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


Reply via email to