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 could be considered an existing change command.
Signed-off-by: Fiona Ebner <f.eb...@proxmox.com> --- Tried to go more general at first with a 'job-change' command, but I couldn't figure out a way to avoid mutual inclusion between block-core.json and job.json. blockdev.c | 14 ++++++++++++++ blockjob.c | 20 ++++++++++++++++++++ include/block/blockjob.h | 11 +++++++++++ include/block/blockjob_int.h | 5 +++++ job.c | 1 + qapi/block-core.json | 26 ++++++++++++++++++++++++++ qapi/job.json | 4 +++- 7 files changed, 80 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index d7b5c18f0a..ceb367dcb8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3416,6 +3416,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 659c3cb9de..b933d1c631 100644 --- a/blockjob.c +++ b/blockjob.c @@ -319,6 +319,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"); + } +} + int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n) { IO_CODE(); diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 058b0c824c..d8b80d9625 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -172,6 +172,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. + * @opt: 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 f008446285..055bee5020 100644 --- a/include/block/blockjob_int.h +++ b/include/block/blockjob_int.h @@ -67,6 +67,11 @@ 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. + */ + void (*change)(BlockJob *job, BlockJobChangeOptions *opts, Error **errp); }; /* diff --git a/job.c b/job.c index 72d57f0934..99a2e54b54 100644 --- a/job.c +++ b/job.c @@ -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 7f331eb8ea..714cabd49d 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2964,6 +2964,32 @@ { 'command': 'block-job-finalize', 'data': { 'id': 'str' }, 'allow-preconfig': true } +## +# @BlockJobChangeOptions: +# +# Block job options that can be changed after job creation. +# +# @id: The job identifier +# +# @type: The job type +# +# Since 8.0 +## +{ 'union': 'BlockJobChangeOptions', + 'base': { 'id': 'str', 'type': 'JobType' }, + 'discriminator': 'type', + 'data': {} } + +## +# @block-job-change: +# +# Change the block job's options. +# +# Since: 8.0 +## +{ 'command': 'block-job-change', + 'data': 'BlockJobChangeOptions', 'boxed': true } + ## # @BlockdevDiscardOptions: # diff --git a/qapi/job.json b/qapi/job.json index d5f84e9615..7d9d328d7f 100644 --- a/qapi/job.json +++ b/qapi/job.json @@ -100,11 +100,13 @@ # # @finalize: see @job-finalize # +# @change: see @block-job-change (since 8.0) +# # Since: 2.12 ## { 'enum': 'JobVerb', 'data': ['cancel', 'pause', 'resume', 'set-speed', 'complete', 'dismiss', - 'finalize' ] } + 'finalize', 'change' ] } ## # @JOB_STATUS_CHANGE: -- 2.30.2