diff options
author | Fiona Ebner <f.ebner@proxmox.com> | 2023-10-31 14:54:22 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2023-10-31 18:20:25 +0100 |
commit | 61a3a5a76a993b74c85f92585b10250d12323c38 (patch) | |
tree | ed7dc7d2c25fcf9bd75940d6db789f91fd491002 | |
parent | 073458da5619c8914a91440ef243d1e2b888c1b7 (diff) |
blockjob: introduce block-job-change QMP command
which will allow changing job-type-specific options after job
creation.
In the JobVerbTable, the same allow bits as for set-speed are used,
because set-speed can be considered an existing change command.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-ID: <20231031135431.393137-2-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | blockdev.c | 14 | ||||
-rw-r--r-- | blockjob.c | 20 | ||||
-rw-r--r-- | include/block/blockjob.h | 11 | ||||
-rw-r--r-- | include/block/blockjob_int.h | 7 | ||||
-rw-r--r-- | job.c | 1 | ||||
-rw-r--r-- | qapi/block-core.json | 26 | ||||
-rw-r--r-- | qapi/job.json | 4 |
7 files changed, 82 insertions, 1 deletions
diff --git a/blockdev.c b/blockdev.c index 877e3a26d4..1517dc6210 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3392,6 +3392,20 @@ void qmp_block_job_dismiss(const char *id, Error **errp) job_dismiss_locked(&job, errp); } +void qmp_block_job_change(BlockJobChangeOptions *opts, Error **errp) +{ + BlockJob *job; + + JOB_LOCK_GUARD(); + job = find_block_job_locked(opts->id, errp); + + if (!job) { + return; + } + + block_job_change_locked(job, opts, errp); +} + void qmp_change_backing_file(const char *device, const char *image_node_name, const char *backing_file, diff --git a/blockjob.c b/blockjob.c index 953dc1b6dc..f0505ad232 100644 --- a/blockjob.c +++ b/blockjob.c @@ -330,6 +330,26 @@ static bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp) return block_job_set_speed_locked(job, speed, errp); } +void block_job_change_locked(BlockJob *job, BlockJobChangeOptions *opts, + Error **errp) +{ + const BlockJobDriver *drv = block_job_driver(job); + + GLOBAL_STATE_CODE(); + + if (job_apply_verb_locked(&job->job, JOB_VERB_CHANGE, errp)) { + return; + } + + if (drv->change) { + job_unlock(); + drv->change(job, opts, errp); + job_lock(); + } else { + error_setg(errp, "Job type does not support change"); + } +} + void block_job_ratelimit_processed_bytes(BlockJob *job, uint64_t n) { IO_CODE(); diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 058b0c824c..95854f1477 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -173,6 +173,17 @@ bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs); bool block_job_set_speed_locked(BlockJob *job, int64_t speed, Error **errp); /** + * block_job_change_locked: + * @job: The job to change. + * @opts: The new options. + * @errp: Error object. + * + * Change the job according to opts. + */ +void block_job_change_locked(BlockJob *job, BlockJobChangeOptions *opts, + Error **errp); + +/** * block_job_query_locked: * @job: The job to get information about. * diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h index 104824040c..a4656d4cb5 100644 --- a/include/block/blockjob_int.h +++ b/include/block/blockjob_int.h @@ -67,6 +67,13 @@ struct BlockJobDriver { void (*attached_aio_context)(BlockJob *job, AioContext *new_context); void (*set_speed)(BlockJob *job, int64_t speed); + + /* + * Change the @job's options according to @opts. + * + * Note that this can already be called before the job coroutine is running. + */ + void (*change)(BlockJob *job, BlockJobChangeOptions *opts, Error **errp); }; /* @@ -80,6 +80,7 @@ bool JobVerbTable[JOB_VERB__MAX][JOB_STATUS__MAX] = { [JOB_VERB_COMPLETE] = {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}, [JOB_VERB_FINALIZE] = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, [JOB_VERB_DISMISS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + [JOB_VERB_CHANGE] = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, }; /* Transactional group of jobs */ diff --git a/qapi/block-core.json b/qapi/block-core.json index 89751d81f2..c6f31a9399 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3045,6 +3045,32 @@ 'allow-preconfig': true } ## +# @BlockJobChangeOptions: +# +# Block job options that can be changed after job creation. +# +# @id: The job identifier +# +# @type: The job type +# +# Since 8.2 +## +{ 'union': 'BlockJobChangeOptions', + 'base': { 'id': 'str', 'type': 'JobType' }, + 'discriminator': 'type', + 'data': {} } + +## +# @block-job-change: +# +# Change the block job's options. +# +# Since: 8.2 +## +{ 'command': 'block-job-change', + 'data': 'BlockJobChangeOptions', 'boxed': true } + +## # @BlockdevDiscardOptions: # # Determines how to handle discard requests. diff --git a/qapi/job.json b/qapi/job.json index 7f0ba090de..b3957207a4 100644 --- a/qapi/job.json +++ b/qapi/job.json @@ -105,11 +105,13 @@ # # @finalize: see @job-finalize # +# @change: see @block-job-change (since 8.2) +# # Since: 2.12 ## { 'enum': 'JobVerb', 'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete', 'dismiss', - 'finalize' ] } + 'finalize', 'change' ] } ## # @JOB_STATUS_CHANGE: |