From: Hogan Wang via <qemu-devel@nongnu.org>
To: <kwolf@redhat.com>, <berrange@redhat.com>, <armbru@redhat.com>,
<marcandre.lureau@redhat.com>, <qemu-devel@nongnu.org>
Cc: <wangxinxin.wang@huawei.com>, <hogan.wang@huawei.com>
Subject: [PATCH v3 3/3] dump: use jobs framework for dump guest memory
Date: Sat, 30 Jul 2022 11:20:08 +0800 [thread overview]
Message-ID: <20220730032008.3185-1-hogan.wang@huawei.com> (raw)
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
reply other threads:[~2022-07-30 3:21 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220730032008.3185-1-hogan.wang@huawei.com \
--to=qemu-devel@nongnu.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=hogan.wang@huawei.com \
--cc=kwolf@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=wangxinxin.wang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).