mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 10:34:58 -06:00
job: Move .complete callback to Job
This moves the .complete callback that tells a READY job to complete from BlockJobDriver to JobDriver. The wrapper function job_complete() doesn't require anything block job specific any more and can be moved to Job. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
b69f777dd9
commit
3453d97243
9 changed files with 43 additions and 48 deletions
|
@ -905,16 +905,16 @@ immediate_exit:
|
||||||
job_defer_to_main_loop(&s->common.job, mirror_exit, data);
|
job_defer_to_main_loop(&s->common.job, mirror_exit, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mirror_complete(BlockJob *job, Error **errp)
|
static void mirror_complete(Job *job, Error **errp)
|
||||||
{
|
{
|
||||||
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
|
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
||||||
BlockDriverState *target;
|
BlockDriverState *target;
|
||||||
|
|
||||||
target = blk_bs(s->target);
|
target = blk_bs(s->target);
|
||||||
|
|
||||||
if (!s->synced) {
|
if (!s->synced) {
|
||||||
error_setg(errp, "The active block job '%s' cannot be completed",
|
error_setg(errp, "The active block job '%s' cannot be completed",
|
||||||
job->job.id);
|
job->id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,8 +995,8 @@ static const BlockJobDriver mirror_job_driver = {
|
||||||
.drain = block_job_drain,
|
.drain = block_job_drain,
|
||||||
.start = mirror_run,
|
.start = mirror_run,
|
||||||
.pause = mirror_pause,
|
.pause = mirror_pause,
|
||||||
|
.complete = mirror_complete,
|
||||||
},
|
},
|
||||||
.complete = mirror_complete,
|
|
||||||
.attached_aio_context = mirror_attached_aio_context,
|
.attached_aio_context = mirror_attached_aio_context,
|
||||||
.drain = mirror_drain,
|
.drain = mirror_drain,
|
||||||
};
|
};
|
||||||
|
@ -1010,8 +1010,8 @@ static const BlockJobDriver commit_active_job_driver = {
|
||||||
.drain = block_job_drain,
|
.drain = block_job_drain,
|
||||||
.start = mirror_run,
|
.start = mirror_run,
|
||||||
.pause = mirror_pause,
|
.pause = mirror_pause,
|
||||||
|
.complete = mirror_complete,
|
||||||
},
|
},
|
||||||
.complete = mirror_complete,
|
|
||||||
.attached_aio_context = mirror_attached_aio_context,
|
.attached_aio_context = mirror_attached_aio_context,
|
||||||
.drain = mirror_drain,
|
.drain = mirror_drain,
|
||||||
};
|
};
|
||||||
|
|
|
@ -3894,7 +3894,7 @@ void qmp_block_job_complete(const char *device, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_qmp_block_job_complete(job);
|
trace_qmp_block_job_complete(job);
|
||||||
block_job_complete(job, errp);
|
job_complete(&job->job, errp);
|
||||||
aio_context_release(aio_context);
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
blockjob.c
23
blockjob.c
|
@ -481,24 +481,6 @@ int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
|
||||||
return ratelimit_calculate_delay(&job->limit, n);
|
return ratelimit_calculate_delay(&job->limit, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void block_job_complete(BlockJob *job, Error **errp)
|
|
||||||
{
|
|
||||||
/* Should not be reachable via external interface for internal jobs */
|
|
||||||
assert(job->job.id);
|
|
||||||
if (job_apply_verb(&job->job, JOB_VERB_COMPLETE, errp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (job->job.pause_count || job_is_cancelled(&job->job) ||
|
|
||||||
!job->driver->complete)
|
|
||||||
{
|
|
||||||
error_setg(errp, "The active block job '%s' cannot be completed",
|
|
||||||
job->job.id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
job->driver->complete(job, errp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void block_job_finalize(BlockJob *job, Error **errp)
|
void block_job_finalize(BlockJob *job, Error **errp)
|
||||||
{
|
{
|
||||||
assert(job && job->job.id);
|
assert(job && job->job.id);
|
||||||
|
@ -571,6 +553,11 @@ void block_job_cancel_sync_all(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void block_job_complete(BlockJob *job, Error **errp)
|
||||||
|
{
|
||||||
|
job_complete(&job->job, errp);
|
||||||
|
}
|
||||||
|
|
||||||
int block_job_complete_sync(BlockJob *job, Error **errp)
|
int block_job_complete_sync(BlockJob *job, Error **errp)
|
||||||
{
|
{
|
||||||
return block_job_finish_sync(job, &block_job_complete, errp);
|
return block_job_finish_sync(job, &block_job_complete, errp);
|
||||||
|
|
|
@ -153,16 +153,6 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp);
|
||||||
*/
|
*/
|
||||||
void block_job_cancel(BlockJob *job, bool force);
|
void block_job_cancel(BlockJob *job, bool force);
|
||||||
|
|
||||||
/**
|
|
||||||
* block_job_complete:
|
|
||||||
* @job: The job to be completed.
|
|
||||||
* @errp: Error object.
|
|
||||||
*
|
|
||||||
* Asynchronously complete the specified job.
|
|
||||||
*/
|
|
||||||
void block_job_complete(BlockJob *job, Error **errp);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* block_job_finalize:
|
* block_job_finalize:
|
||||||
* @job: The job to fully commit and finish.
|
* @job: The job to fully commit and finish.
|
||||||
|
|
|
@ -38,12 +38,6 @@ struct BlockJobDriver {
|
||||||
/** Generic JobDriver callbacks and settings */
|
/** Generic JobDriver callbacks and settings */
|
||||||
JobDriver job_driver;
|
JobDriver job_driver;
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional callback for job types whose completion must be triggered
|
|
||||||
* manually.
|
|
||||||
*/
|
|
||||||
void (*complete)(BlockJob *job, Error **errp);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the callback is not NULL, prepare will be invoked when all the jobs
|
* If the callback is not NULL, prepare will be invoked when all the jobs
|
||||||
* belonging to the same transaction complete; or upon this job's completion
|
* belonging to the same transaction complete; or upon this job's completion
|
||||||
|
|
|
@ -167,6 +167,12 @@ struct JobDriver {
|
||||||
*/
|
*/
|
||||||
void (*user_resume)(Job *job);
|
void (*user_resume)(Job *job);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional callback for job types whose completion must be triggered
|
||||||
|
* manually.
|
||||||
|
*/
|
||||||
|
void (*complete)(Job *job, Error **errp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the callback is not NULL, it will be invoked when the job has to be
|
* If the callback is not NULL, it will be invoked when the job has to be
|
||||||
* synchronously cancelled or completed; it should drain any activities
|
* synchronously cancelled or completed; it should drain any activities
|
||||||
|
@ -363,6 +369,8 @@ int job_apply_verb(Job *job, JobVerb verb, Error **errp);
|
||||||
/** The @job could not be started, free it. */
|
/** The @job could not be started, free it. */
|
||||||
void job_early_fail(Job *job);
|
void job_early_fail(Job *job);
|
||||||
|
|
||||||
|
/** Asynchronously complete the specified @job. */
|
||||||
|
void job_complete(Job *job, Error **errp);;
|
||||||
|
|
||||||
typedef void JobDeferToMainLoopFn(Job *job, void *opaque);
|
typedef void JobDeferToMainLoopFn(Job *job, void *opaque);
|
||||||
|
|
||||||
|
|
16
job.c
16
job.c
|
@ -556,6 +556,22 @@ int job_finalize_single(Job *job)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void job_complete(Job *job, Error **errp)
|
||||||
|
{
|
||||||
|
/* Should not be reachable via external interface for internal jobs */
|
||||||
|
assert(job->id);
|
||||||
|
if (job_apply_verb(job, JOB_VERB_COMPLETE, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (job->pause_count || job_is_cancelled(job) || !job->driver->complete) {
|
||||||
|
error_setg(errp, "The active block job '%s' cannot be completed",
|
||||||
|
job->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
job->driver->complete(job, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Job *job;
|
Job *job;
|
||||||
|
|
|
@ -514,9 +514,9 @@ static void coroutine_fn test_job_start(void *opaque)
|
||||||
job_defer_to_main_loop(&s->common.job, test_job_completed, NULL);
|
job_defer_to_main_loop(&s->common.job, test_job_completed, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_job_complete(BlockJob *job, Error **errp)
|
static void test_job_complete(Job *job, Error **errp)
|
||||||
{
|
{
|
||||||
TestBlockJob *s = container_of(job, TestBlockJob, common);
|
TestBlockJob *s = container_of(job, TestBlockJob, common.job);
|
||||||
s->should_complete = true;
|
s->should_complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,8 +527,8 @@ BlockJobDriver test_job_driver = {
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
.drain = block_job_drain,
|
||||||
.start = test_job_start,
|
.start = test_job_start,
|
||||||
|
.complete = test_job_complete,
|
||||||
},
|
},
|
||||||
.complete = test_job_complete,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void test_blockjob_common(enum drain_type drain_type)
|
static void test_blockjob_common(enum drain_type drain_type)
|
||||||
|
|
|
@ -171,9 +171,9 @@ static void cancel_job_completed(Job *job, void *opaque)
|
||||||
block_job_completed(bjob, 0);
|
block_job_completed(bjob, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cancel_job_complete(BlockJob *job, Error **errp)
|
static void cancel_job_complete(Job *job, Error **errp)
|
||||||
{
|
{
|
||||||
CancelJob *s = container_of(job, CancelJob, common);
|
CancelJob *s = container_of(job, CancelJob, common.job);
|
||||||
s->should_complete = true;
|
s->should_complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,8 +204,8 @@ static const BlockJobDriver test_cancel_driver = {
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
.drain = block_job_drain,
|
||||||
.start = cancel_job_start,
|
.start = cancel_job_start,
|
||||||
|
.complete = cancel_job_complete,
|
||||||
},
|
},
|
||||||
.complete = cancel_job_complete,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static CancelJob *create_common(BlockJob **pjob)
|
static CancelJob *create_common(BlockJob **pjob)
|
||||||
|
@ -333,7 +333,7 @@ static void test_cancel_pending(void)
|
||||||
block_job_enter(job);
|
block_job_enter(job);
|
||||||
assert(job->job.status == JOB_STATUS_READY);
|
assert(job->job.status == JOB_STATUS_READY);
|
||||||
|
|
||||||
block_job_complete(job, &error_abort);
|
job_complete(&job->job, &error_abort);
|
||||||
block_job_enter(job);
|
block_job_enter(job);
|
||||||
while (!s->completed) {
|
while (!s->completed) {
|
||||||
aio_poll(qemu_get_aio_context(), true);
|
aio_poll(qemu_get_aio_context(), true);
|
||||||
|
@ -357,7 +357,7 @@ static void test_cancel_concluded(void)
|
||||||
block_job_enter(job);
|
block_job_enter(job);
|
||||||
assert(job->job.status == JOB_STATUS_READY);
|
assert(job->job.status == JOB_STATUS_READY);
|
||||||
|
|
||||||
block_job_complete(job, &error_abort);
|
job_complete(&job->job, &error_abort);
|
||||||
block_job_enter(job);
|
block_job_enter(job);
|
||||||
while (!s->completed) {
|
while (!s->completed) {
|
||||||
aio_poll(qemu_get_aio_context(), true);
|
aio_poll(qemu_get_aio_context(), true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue