Only supported with completion-mode 'grouped', since it relies on a JobTxn to exist. This means that for now it is only available for {drive,blockdev}-backup transactions.
Since only one job will be running at a time, bandwidth-limits can be applied effectively. It can also prevent overloading a host's IO capabilities in general. Signed-off-by: Stefan Reiter <s.rei...@proxmox.com> --- blockdev.c | 25 ++++++++++++++++++++++--- qapi/transaction.json | 6 +++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/blockdev.c b/blockdev.c index 3848a9c8ab..3691e5e791 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1826,7 +1826,10 @@ static void drive_backup_commit(BlkActionState *common) aio_context_acquire(aio_context); assert(state->job); - job_start(&state->job->job); + + if (!common->txn_props->sequential) { + job_start(&state->job->job); + } aio_context_release(aio_context); } @@ -1927,7 +1930,9 @@ static void blockdev_backup_commit(BlkActionState *common) aio_context_acquire(aio_context); assert(state->job); - job_start(&state->job->job); + if (!common->txn_props->sequential) { + job_start(&state->job->job); + } aio_context_release(aio_context); } @@ -2303,6 +2308,11 @@ static TransactionProperties *get_transaction_properties( props->completion_mode = ACTION_COMPLETION_MODE_INDIVIDUAL; } + if (!props->has_sequential) { + props->has_sequential = true; + props->sequential = false; + } + return props; } @@ -2328,7 +2338,11 @@ void qmp_transaction(TransactionActionList *dev_list, */ props = get_transaction_properties(props); if (props->completion_mode != ACTION_COMPLETION_MODE_INDIVIDUAL) { - block_job_txn = job_txn_new(); + block_job_txn = props->sequential ? job_txn_new_seq() : job_txn_new(); + } else if (props->sequential) { + error_setg(errp, "Sequential transaction mode is not supported with " + "completion-mode = individual"); + return; } /* drain all i/o before any operations */ @@ -2367,6 +2381,11 @@ void qmp_transaction(TransactionActionList *dev_list, } } + /* jobs in sequential txns don't start themselves on commit */ + if (block_job_txn && props->sequential) { + job_txn_start_seq(block_job_txn); + } + /* success */ goto exit; diff --git a/qapi/transaction.json b/qapi/transaction.json index 15ddebdbc3..4808383088 100644 --- a/qapi/transaction.json +++ b/qapi/transaction.json @@ -84,11 +84,15 @@ # Actions will complete or fail as a group. # See @ActionCompletionMode for details. # +# @sequential: Run the jobs in the transaction one after the other, instead +# of all at once. Not supported for completion-mode 'individual'. +# # Since: 2.5 ## { 'struct': 'TransactionProperties', 'data': { - '*completion-mode': 'ActionCompletionMode' + '*completion-mode': 'ActionCompletionMode', + '*sequential': 'bool' } } -- 2.20.1