diff options
author | Fam Zheng <famz@redhat.com> | 2015-04-03 22:05:18 +0800 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2015-04-28 15:36:09 +0200 |
commit | 751ebd76e654bd1e65da08ecf694325282b4cfcc (patch) | |
tree | e4a1a824f63fc24501480faec35a388c7df22f18 /blockdev.c | |
parent | 199667a8c843d268f0fe80f09041b8c7193f1ba5 (diff) |
blockjob: Allow nested pause
This patch changes block_job_pause to increase the pause counter and
block_job_resume to decrease it.
The counter will allow calling block_job_pause/block_job_resume
unconditionally on a job when we need to suspend the IO temporarily.
From now on, each block_job_resume must be paired with a block_job_pause
to keep the counter balanced.
The user pause from QMP or HMP will only trigger block_job_pause once
until it's resumed, this is achieved by adding a user_paused flag in
BlockJob.
One occurrence of block_job_resume in mirror_complete is replaced with
block_job_enter which does what is necessary.
In block_job_cancel, the cancel flag is good enough to instruct
coroutines to quit loop, so use block_job_enter to replace the unpaired
block_job_resume.
Upon block job IO error, user is notified about the entering to the
pause state, so this pause belongs to user pause, set the flag
accordingly and expect a matching QMP resume.
[Extended doc comments as suggested by Paolo Bonzini
<pbonzini@redhat.com>.
--Stefan]
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1428069921-2957-2-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'blockdev.c')
-rw-r--r-- | blockdev.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/blockdev.c b/blockdev.c index fbb3a79978..9132d69e09 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2699,7 +2699,7 @@ void qmp_block_job_cancel(const char *device, force = false; } - if (job->paused && !force) { + if (job->user_paused && !force) { error_setg(errp, "The block job for device '%s' is currently paused", device); goto out; @@ -2716,10 +2716,11 @@ void qmp_block_job_pause(const char *device, Error **errp) AioContext *aio_context; BlockJob *job = find_block_job(device, &aio_context, errp); - if (!job) { + if (!job || job->user_paused) { return; } + job->user_paused = true; trace_qmp_block_job_pause(job); block_job_pause(job); aio_context_release(aio_context); @@ -2730,10 +2731,11 @@ void qmp_block_job_resume(const char *device, Error **errp) AioContext *aio_context; BlockJob *job = find_block_job(device, &aio_context, errp); - if (!job) { + if (!job || !job->user_paused) { return; } + job->user_paused = false; trace_qmp_block_job_resume(job); block_job_resume(job); aio_context_release(aio_context); |