All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 3/3] dump: use jobs framework for dump guest memory
@ 2022-07-30  3:20 Hogan Wang via
  0 siblings, 0 replies; only message in thread
From: Hogan Wang via @ 2022-07-30  3:20 UTC (permalink / raw)
  To: kwolf, berrange, armbru, marcandre.lureau, qemu-devel
  Cc: wangxinxin.wang, hogan.wang

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.

When caller pass the 'job-id' argument, create a job for dump process.
And then caller can use job-cancel QMP command to cancel the detached
dump process, use job-dismiss QMP command to release job object.

Examples:
Start dump job:
{"execute": "dump-guest-memory", "arguments": { "job-id": "dump-guest-memory",
                                                "protocol": "file:/tmp/vm.dump",
                                                "paging": false,
                                                "format": "elf",
                                                "detach": true
                                              }}

Cancel dump job:
{"execute": "job-cancel", "arguments": { "id": "dump-guest-memory" }}

Dismiss dump job:
{"execute": "job-dismiss", "arguments": { "id": "dump-guest-memory" }}

Signed-off-by: Hogan Wang <hogan.wang@huawei.com>
---
 dump/dump.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/dump/dump.c b/dump/dump.c
index cec9be30b4..3f4ed8e7a7 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -98,6 +98,7 @@ static int dump_cleanup(DumpState *s)
 {
     guest_phys_blocks_free(&s->guest_phys_blocks);
     memory_mapping_list_free(&s->list);
+    s->job = NULL;
     close(s->fd);
     g_free(s->guest_note);
     s->guest_note = NULL;
@@ -1542,6 +1543,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 */
@@ -1894,6 +1903,64 @@ DumpQueryResult *qmp_query_dump(Error **errp)
     return result;
 }
 
+static void *dump_job_thread(void *opaque)
+{
+    DumpJob *job = (DumpJob *)opaque;
+    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;
+}
+
+static void dump_sync_job_bh(void *opaque)
+{
+    dump_job_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_job_thread, job, 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,
+};
+
+static void dump_job_start(DumpState *state, const char *job_id,
+                           bool detach, Error **errp)
+{
+    DumpJob *job;
+
+    job = job_create(job_id, &dump_guest_memory_job_driver, NULL,
+                     qemu_get_aio_context(), JOB_MANUAL_DISMISS,
+                     NULL, NULL, errp);
+    if (!job) {
+        return;
+    }
+    state->detached = detach;
+    state->job = &job->common;
+    job->state = state;
+    job_start(&job->common);
+}
+
 void qmp_dump_guest_memory(bool paging, const char *file,
                            bool has_job_id, const char *job_id,
                            bool has_detach, bool detach,
@@ -2010,6 +2077,15 @@ void qmp_dump_guest_memory(bool paging, const char *file,
         return;
     }
 
+    if (has_job_id) {
+        dump_job_start(s, job_id, detach_p, errp);
+        if (*errp) {
+            qatomic_set(&s->status, DUMP_STATUS_FAILED);
+            dump_cleanup(s);
+        }
+        return;
+    }
+
     if (detach_p) {
         /* detached dump */
         s->detached = true;
-- 
2.33.0



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-30  3:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-30  3:20 [PATCH v3 3/3] dump: use jobs framework for dump guest memory Hogan Wang via

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.