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.wang@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);
This is a change of behaviour, the command is no longer "sync" after this change, as it returns immediately (even though further IO will be blocked until the dump is completed). Maybe only create a job for commands with a job-id and detached?
}
DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
--
2.33.0