There's no way to cancel the current executing dump process, lead to the virtual machine manager daemon((e.g. libvirtd) cannot restore the dump job after daemon restart.
Use default job id 'dump-guest-memory' to create a job object for dump process. Signed-off-by: Hogan Wang <hogan.w...@huawei.com> --- dump/dump.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/dump/dump.c b/dump/dump.c index 6aa946b9ac..51dc933c7c 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -1528,6 +1528,14 @@ static void get_max_mapnr(DumpState *s) static DumpState dump_state_global = { .status = DUMP_STATUS_NONE }; +typedef struct DumpJob { + Job common; + DumpState *state; + Coroutine *co; + Error **errp; +} DumpJob; + + static void dump_state_prepare(DumpState *s) { /* zero the struct, setting status to active */ @@ -1854,8 +1862,11 @@ static void dump_process(DumpState *s, Error **errp) static void *dump_thread(void *data) { - DumpState *s = (DumpState *)data; - dump_process(s, NULL); + DumpJob *job = (DumpJob *)data; + job_progress_set_remaining(&job->common, 1); + dump_process(job->state, job->errp); + job_progress_update(&job->common, 1); + aio_co_wake(job->co); return NULL; } @@ -1871,6 +1882,37 @@ DumpQueryResult *qmp_query_dump(Error **errp) return result; } +static void dump_sync_job_bh(void *opaque) +{ + dump_thread(opaque); +} + +static int coroutine_fn dump_guest_memory_job_run(Job *job, Error **errp) +{ + DumpJob *s = container_of(job, DumpJob, common); + DumpState *state = &dump_state_global; + + s->errp = errp; + s->co = qemu_coroutine_self(); + + if (state->detached) { + /* detached dump */ + qemu_thread_create(&s->state->dump_thread, "dump_thread", dump_thread, + s, QEMU_THREAD_DETACHED); + } else { + aio_bh_schedule_oneshot(qemu_get_aio_context(), + dump_sync_job_bh, job); + } + qemu_coroutine_yield(); + return qatomic_read(&state->status) == DUMP_STATUS_COMPLETED ? 0 : -1; +} + +static const JobDriver dump_guest_memory_job_driver = { + .instance_size = sizeof(DumpJob), + .job_type = JOB_TYPE_DUMP_GUEST_MEMORY, + .run = dump_guest_memory_job_run, +}; + void qmp_dump_guest_memory(bool paging, const char *file, bool has_job_id, const char *job_id, bool has_detach, bool detach, @@ -1882,6 +1924,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, const char *p; int fd = -1; DumpState *s; + DumpJob *job; bool detach_p = false; if (runstate_check(RUN_STATE_INMIGRATE)) { @@ -1977,6 +2020,10 @@ void qmp_dump_guest_memory(bool paging, const char *file, return; } + if (!has_job_id) { + job_id = "dump-guest-memory"; + } + s = &dump_state_global; dump_state_prepare(s); @@ -1987,15 +2034,16 @@ void qmp_dump_guest_memory(bool paging, const char *file, return; } - if (detach_p) { - /* detached dump */ - s->detached = true; - qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread, - s, QEMU_THREAD_DETACHED); - } else { - /* sync dump */ - dump_process(s, errp); + s->detached = detach_p; + job = job_create(job_id, &dump_guest_memory_job_driver, NULL, + qemu_get_aio_context(), JOB_DEFAULT, + NULL, NULL, errp); + if (!job) { + qatomic_set(&s->status, DUMP_STATUS_FAILED); + return; } + job->state = s; + job_start(&job->common); } DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp) -- 2.33.0