[libvirt] [PATCH 0/3 v4] use qemu's dump-guest-meory when vm uses host device

Currently, we use migrate to dump guest's memory. There is one restriction in migrate command: the device's status should be stored in qemu because the device's status should be passed to target machine. If we passthrough a host device to guest, the device's status is stored in the real device. So migrate command will fail. We usually use dump when guest is panicked. So there is no need to store device's status in the vmcore. qemu will have a new monitor command dump-guest-memory to dump guest memory, but it doesn't support async now(it will support later when the common async API is implemented). So I use dump-guest-memory only when the guest uses host device in this patchset. Note: the patchset for qemu is still queued. Luiz has acked, but he said he does not wait an ACK from Jan and/or Anthony. Changes from v3 to v4: 1. allow the user to specify the core file's format Changes from v2 to v3: 1. qemu supports the fd that is associated with a pipe, socket, or FIFO. So pass a pipe fd to qemu and O_DIRECT can work now. Change from v1 to v2: 1. remove the implemention for text mode. Wen Congyang (3): qemu: implement qemu's dump-guest-memory qemu: allow the client to choose the vmcore's format virsh: allow the user to specify vmcore's format include/libvirt/libvirt.h.in | 1 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 54 +++++++++++++++++++++++++++++++---------- src/qemu/qemu_monitor.c | 38 +++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 12 +++++++++ src/qemu/qemu_monitor_json.c | 35 +++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++ tools/virsh.c | 3 ++ tools/virsh.pod | 5 +++- 10 files changed, 142 insertions(+), 14 deletions(-)

dump-guest-memory is a new dump mechanism, and it can work when the guest uses host devices. This patch adds a API to use this new monitor command. --- src/qemu/qemu_monitor.c | 38 ++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 12 ++++++++++++ src/qemu/qemu_monitor_json.c | 34 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++++ 4 files changed, 90 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2f66c46..a5d3eec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2018,6 +2018,44 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon) return ret; } +int qemuMonitorDumpToFd(qemuMonitorPtr mon, + unsigned int flags, + int fd, + unsigned long long begin, + unsigned long long length) +{ + int ret; + VIR_DEBUG("mon=%p fd=%d flags=%x begin=%llx length=%llx", + mon, fd, flags, begin, length); + + if (!mon) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + /* dump-guest-memory is supported after qemu-1.0, and we always use json + * if qemu's version is >= 0.15. So if we use text mode, the qemu is + * old, and it does not support dump-guest-memory. + */ + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("dump-guest-memory is not supported in text mode")); + return -1; + } + + if (qemuMonitorSendFileHandle(mon, "dump", fd) < 0) + return -1; + + ret = qemuMonitorJSONDump(mon, flags, "fd:dump", begin, length); + + if (ret < 0) { + if (qemuMonitorCloseFileHandle(mon, "dump") < 0) + VIR_WARN("failed to close dumping handle"); + } + + return ret; +} int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon, int type, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index f3cdcdd..7df52ad 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -379,6 +379,18 @@ int qemuMonitorMigrateToUnix(qemuMonitorPtr mon, int qemuMonitorMigrateCancel(qemuMonitorPtr mon); +typedef enum { + QEMU_MONITOR_DUMP_HAVE_FILTER = 1 << 0, + QEMU_MONITOR_DUMP_PAGING = 1 << 1, + QEMU_MONITOR_DUMP_FLAGS_LAST +} QEMU_MONITOR_DUMP; + +int qemuMonitorDumpToFd(qemuMonitorPtr mon, + unsigned int flags, + int fd, + unsigned long long begin, + unsigned long long length); + int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon, int type, const char *hostname, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index eb58f13..b229a31 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2461,6 +2461,40 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon) return ret; } +int qemuMonitorJSONDump(qemuMonitorPtr mon, + unsigned int flags, + const char *protocol, + unsigned long long begin, + unsigned long long length) +{ + int ret; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + + if (flags & QEMU_MONITOR_DUMP_HAVE_FILTER) + cmd = qemuMonitorJSONMakeCommand("dump-guest-memory", + "b:paging", flags & QEMU_MONITOR_DUMP_PAGING ? 1 : 0, + "s:protocol", protocol, + "U:begin", begin, + "U:length", length, + NULL); + else + cmd = qemuMonitorJSONMakeCommand("dump-guest-memory", + "b:paging", flags & QEMU_MONITOR_DUMP_PAGING ? 1 : 0, + "s:protocol", protocol, + NULL); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon, int type, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index aacbb5f..ccb2624 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -136,6 +136,12 @@ int qemuMonitorJSONMigrate(qemuMonitorPtr mon, int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon); +int qemuMonitorJSONDump(qemuMonitorPtr mon, + unsigned int flags, + const char *protocol, + unsigned long long begin, + unsigned long long length); + int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon, int type, const char *hostname, -- 1.7.1

On 04/20/2012 09:27 AM, Wen Congyang wrote:
dump-guest-memory is a new dump mechanism, and it can work when the guest uses host devices. This patch adds a API to use this new monitor command.
--- src/qemu/qemu_monitor.c | 38 ++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 12 ++++++++++++ src/qemu/qemu_monitor_json.c | 34 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++++ 4 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2f66c46..a5d3eec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2018,6 +2018,44 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon) return ret; }
+int qemuMonitorDumpToFd(qemuMonitorPtr mon, + unsigned int flags, + int fd, + unsigned long long begin, + unsigned long long length) +{ + int ret; + VIR_DEBUG("mon=%p fd=%d flags=%x begin=%llx length=%llx", + mon, fd, flags, begin, length); + + if (!mon) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + /* dump-guest-memory is supported after qemu-1.0, and we always use json + * if qemu's version is >= 0.15. So if we use text mode, the qemu is + * old, and it does not support dump-guest-memory. + */ + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("dump-guest-memory is not supported in text mode")); + return -1; + }
Correct me if I'm wrong, but shouldn't this be rather handled by adding it as a qemu capability? Maybe by checking the qemu version in qemuCapsComputeCmdFlags()? Or probably even better by checking that command in qemuCapsComputeCmdFlags(). That way we can be sure that the command is supported.
+ + if (qemuMonitorSendFileHandle(mon, "dump", fd) < 0) + return -1; + + ret = qemuMonitorJSONDump(mon, flags, "fd:dump", begin, length); + + if (ret < 0) { + if (qemuMonitorCloseFileHandle(mon, "dump") < 0) + VIR_WARN("failed to close dumping handle"); + } + + return ret; +}
int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon, int type, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index f3cdcdd..7df52ad 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -379,6 +379,18 @@ int qemuMonitorMigrateToUnix(qemuMonitorPtr mon,
int qemuMonitorMigrateCancel(qemuMonitorPtr mon);
+typedef enum { + QEMU_MONITOR_DUMP_HAVE_FILTER = 1 << 0, + QEMU_MONITOR_DUMP_PAGING = 1 << 1, + QEMU_MONITOR_DUMP_FLAGS_LAST +} QEMU_MONITOR_DUMP; + +int qemuMonitorDumpToFd(qemuMonitorPtr mon, + unsigned int flags, + int fd, + unsigned long long begin, + unsigned long long length); + int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon, int type, const char *hostname, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index eb58f13..b229a31 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2461,6 +2461,40 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon) return ret; }
+int qemuMonitorJSONDump(qemuMonitorPtr mon, + unsigned int flags, + const char *protocol, + unsigned long long begin, + unsigned long long length) +{ + int ret; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + + if (flags & QEMU_MONITOR_DUMP_HAVE_FILTER) + cmd = qemuMonitorJSONMakeCommand("dump-guest-memory", + "b:paging", flags & QEMU_MONITOR_DUMP_PAGING ? 1 : 0, + "s:protocol", protocol, + "U:begin", begin, + "U:length", length, + NULL); + else + cmd = qemuMonitorJSONMakeCommand("dump-guest-memory", + "b:paging", flags & QEMU_MONITOR_DUMP_PAGING ? 1 : 0, + "s:protocol", protocol, + NULL); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +}
int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon, int type, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index aacbb5f..ccb2624 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -136,6 +136,12 @@ int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon);
+int qemuMonitorJSONDump(qemuMonitorPtr mon, + unsigned int flags, + const char *protocol, + unsigned long long begin, + unsigned long long length); + int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon, int type, const char *hostname,

At 05/23/2012 04:56 PM, Martin Kletzander Wrote:
On 04/20/2012 09:27 AM, Wen Congyang wrote:
dump-guest-memory is a new dump mechanism, and it can work when the guest uses host devices. This patch adds a API to use this new monitor command.
--- src/qemu/qemu_monitor.c | 38 ++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 12 ++++++++++++ src/qemu/qemu_monitor_json.c | 34 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++++ 4 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2f66c46..a5d3eec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2018,6 +2018,44 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon) return ret; }
+int qemuMonitorDumpToFd(qemuMonitorPtr mon, + unsigned int flags, + int fd, + unsigned long long begin, + unsigned long long length) +{ + int ret; + VIR_DEBUG("mon=%p fd=%d flags=%x begin=%llx length=%llx", + mon, fd, flags, begin, length); + + if (!mon) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + /* dump-guest-memory is supported after qemu-1.0, and we always use json + * if qemu's version is >= 0.15. So if we use text mode, the qemu is + * old, and it does not support dump-guest-memory. + */ + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("dump-guest-memory is not supported in text mode")); + return -1; + }
Correct me if I'm wrong, but shouldn't this be rather handled by adding it as a qemu capability? Maybe by checking the qemu version in qemuCapsComputeCmdFlags()? Or probably even better by checking that command in qemuCapsComputeCmdFlags(). That way we can be sure that the command is supported.
If mon->json is false, we use the text mode, so the qemu's version is < 0.15. The dump-guest-memory is supported after qemu-1.0. So we can say that the qemu does not support dump-guest-memory if mon->json is false. Thanks Wen Congyang

On 05/23/2012 11:17 AM, Wen Congyang wrote:
At 05/23/2012 04:56 PM, Martin Kletzander Wrote:
On 04/20/2012 09:27 AM, Wen Congyang wrote:
dump-guest-memory is a new dump mechanism, and it can work when the guest uses host devices. This patch adds a API to use this new monitor command.
--- src/qemu/qemu_monitor.c | 38 ++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 12 ++++++++++++ src/qemu/qemu_monitor_json.c | 34 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++++ 4 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2f66c46..a5d3eec 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2018,6 +2018,44 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon) return ret; }
+int qemuMonitorDumpToFd(qemuMonitorPtr mon, + unsigned int flags, + int fd, + unsigned long long begin, + unsigned long long length) +{ + int ret; + VIR_DEBUG("mon=%p fd=%d flags=%x begin=%llx length=%llx", + mon, fd, flags, begin, length); + + if (!mon) { + qemuReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + /* dump-guest-memory is supported after qemu-1.0, and we always use json + * if qemu's version is >= 0.15. So if we use text mode, the qemu is + * old, and it does not support dump-guest-memory. + */ + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("dump-guest-memory is not supported in text mode")); + return -1; + }
Correct me if I'm wrong, but shouldn't this be rather handled by adding it as a qemu capability? Maybe by checking the qemu version in qemuCapsComputeCmdFlags()? Or probably even better by checking that command in qemuCapsComputeCmdFlags(). That way we can be sure that the command is supported.
If mon->json is false, we use the text mode, so the qemu's version is < 0.15. The dump-guest-memory is supported after qemu-1.0. So we can say that the qemu does not support dump-guest-memory if mon->json is false.
Thanks Wen Congyang
Yes, that's true, but on the other hand we cannot say it supports dump-guest-memory just because we are using JSON. For example for qemu-0.15, we'll use JSON, but the command will not be supported. Regards, Martin

This patch updates qemu driver to allow the client to choose the vmcore's format: memory only or including device state. --- include/libvirt/libvirt.h.in | 1 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 54 +++++++++++++++++++++++++++++++---------- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 97ad99d..5f03043 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -927,6 +927,7 @@ typedef enum { VIR_DUMP_LIVE = (1 << 1), /* live dump */ VIR_DUMP_BYPASS_CACHE = (1 << 2), /* avoid file system cache pollution */ VIR_DUMP_RESET = (1 << 3), /* reset domain after dump finishes */ + VIR_DUMP_MEMORY_ONLY = (1 << 4), /* use dump-guest-memory */ } virDomainCoreDumpFlags; /* Domain migration flags. */ diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4dda2e0..e81f439 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -160,6 +160,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) job->phase = 0; job->mask = DEFAULT_JOB_MASK; job->start = 0; + job->dump_memory_only = false; memset(&job->info, 0, sizeof(job->info)); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index ce52569..098349b 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -104,6 +104,7 @@ struct qemuDomainJobObj { int phase; /* Job phase (mainly for migrations) */ unsigned long long mask; /* Jobs allowed during async job */ unsigned long long start; /* When the async job started */ + bool dump_memory_only; /* use dump-guest-memory to do dump */ virDomainJobInfo info; /* Async job progress data */ }; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c3555ca..779304f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2967,12 +2967,33 @@ cleanup: return ret; } +static int qemuDumpToFd(struct qemud_driver *driver, virDomainObjPtr vm, + int fd, enum qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret = -1; + + if (virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def, + fd) < 0) + return -1; + + priv->job.dump_memory_only = true; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + ret = qemuMonitorDumpToFd(priv->mon, 0, fd, 0, 0); + qemuDomainObjExitMonitorWithDriver(driver, vm); + + return ret; +} + static int doCoreDump(struct qemud_driver *driver, virDomainObjPtr vm, const char *path, enum qemud_save_formats compress, - bool bypass_cache) + unsigned int dump_flags) { int fd = -1; int ret = -1; @@ -2981,7 +3002,7 @@ doCoreDump(struct qemud_driver *driver, unsigned int flags = VIR_FILE_WRAPPER_NON_BLOCKING; /* Create an empty file with appropriate ownership. */ - if (bypass_cache) { + if (dump_flags & VIR_DUMP_BYPASS_CACHE) { flags |= VIR_FILE_WRAPPER_BYPASS_CACHE; directFlag = virFileDirectFdFlag(); if (directFlag < 0) { @@ -3001,14 +3022,20 @@ doCoreDump(struct qemud_driver *driver, if (!(wrapperFd = virFileWrapperFdNew(&fd, path, flags))) goto cleanup; - if (qemuMigrationToFile(driver, vm, fd, 0, path, - qemuCompressProgramName(compress), false, - QEMU_ASYNC_JOB_DUMP) < 0) + if (dump_flags & VIR_DUMP_MEMORY_ONLY) { + ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP); + } else { + ret = qemuMigrationToFile(driver, vm, fd, 0, path, + qemuCompressProgramName(compress), false, + QEMU_ASYNC_JOB_DUMP); + } + + if (ret < 0) goto cleanup; if (VIR_CLOSE(fd) < 0) { virReportSystemError(errno, - _("unable to save file %s"), + _("unable to close file %s"), path); goto cleanup; } @@ -3066,7 +3093,8 @@ static int qemudDomainCoreDump(virDomainPtr dom, virDomainEventPtr event = NULL; virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH | - VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET, -1); + VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET | + VIR_DUMP_MEMORY_ONLY, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -3108,8 +3136,7 @@ static int qemudDomainCoreDump(virDomainPtr dom, } } - ret = doCoreDump(driver, vm, path, getCompressionType(driver), - (flags & VIR_DUMP_BYPASS_CACHE) != 0); + ret = doCoreDump(driver, vm, path, getCompressionType(driver), flags); if (ret < 0) goto endjob; @@ -3270,6 +3297,7 @@ static void processWatchdogEvent(void *data, void *opaque) case VIR_DOMAIN_WATCHDOG_ACTION_DUMP: { char *dumpfile; + unsigned int flags = 0; if (virAsprintf(&dumpfile, "%s/%s-%u", driver->autoDumpPath, @@ -3292,9 +3320,9 @@ static void processWatchdogEvent(void *data, void *opaque) goto endjob; } + flags |= driver->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0; ret = doCoreDump(driver, wdEvent->vm, dumpfile, - getCompressionType(driver), - driver->autoDumpBypassCache); + getCompressionType(driver), flags); if (ret < 0) qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Dump failed")); @@ -9349,7 +9377,7 @@ static int qemuDomainGetJobInfo(virDomainPtr dom, priv = vm->privateData; if (virDomainObjIsActive(vm)) { - if (priv->job.asyncJob) { + if (priv->job.asyncJob && !priv->job.dump_memory_only) { memcpy(info, &priv->job.info, sizeof(*info)); /* Refresh elapsed time again just to ensure it @@ -9407,7 +9435,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) { priv = vm->privateData; - if (!priv->job.asyncJob) { + if (!priv->job.asyncJob || priv->job.dump_memory_only) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("no job is active on the domain")); goto endjob; -- 1.7.1

Add a new parameter --memory-only for 'virsh dump' command. So the user can decide the vmcore's format. --- tools/virsh.c | 3 +++ tools/virsh.pod | 5 ++++- 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 6168a13..c1e8891 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3982,6 +3982,7 @@ static const vshCmdOptDef opts_dump[] = { {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("where to dump the core")}, {"verbose", VSH_OT_BOOL, 0, N_("display the progress of dump")}, + {"memory-only", VSH_OT_BOOL, 0, N_("dump domain's memory only")}, {NULL, 0, 0, NULL} }; @@ -4020,6 +4021,8 @@ doDump(void *opaque) flags |= VIR_DUMP_BYPASS_CACHE; if (vshCommandOptBool(cmd, "reset")) flags |= VIR_DUMP_RESET; + if (vshCommandOptBool(cmd, "memory-only")) + flags |= VIR_DUMP_MEMORY_ONLY; if (virDomainCoreDump(dom, to, flags) < 0) { vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); diff --git a/tools/virsh.pod b/tools/virsh.pod index ca5c853..9378714 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -784,7 +784,7 @@ the I<format> argument must be B<qemu-argv>. For Xen hypervisor, the I<format> argument may be B<xen-xm> or B<xen-sxpr>. =item B<dump> I<domain-id> I<corefilepath> [I<--bypass-cache>] -{ [I<--live>] | [I<--crash>] | [I<--reset>] } [I<--verbose>] +{ [I<--live>] | [I<--crash>] | [I<--reset>] } [I<--verbose>] [I<--memory-only>] Dumps the core of a domain to a file for analysis. If I<--live> is specified, the domain continues to run until the core @@ -795,6 +795,9 @@ If I<--reset> is specified, the domain is reset after successful dump. Note, these three switches are mutually exclusive. If I<--bypass-cache> is specified, the save will avoid the file system cache, although this may slow down the operation. +If I<--memory-only> is specified, the file is elf file, and will only +include domain's memory and cpu common register value. It is very +useful if the domain uses host devices directly. The progress may be monitored using B<domjobinfo> virsh command and canceled with B<domjobabort> command (sent by another virsh instance). Another option -- 1.7.1

Hi, All The qemu's patch has been applied to QMP tree. I think we can start this work now. Thanks Wen Congyang At 04/20/2012 03:20 PM, Wen Congyang Wrote:
Currently, we use migrate to dump guest's memory. There is one restriction in migrate command: the device's status should be stored in qemu because the device's status should be passed to target machine.
If we passthrough a host device to guest, the device's status is stored in the real device. So migrate command will fail.
We usually use dump when guest is panicked. So there is no need to store device's status in the vmcore.
qemu will have a new monitor command dump-guest-memory to dump guest memory, but it doesn't support async now(it will support later when the common async API is implemented).
So I use dump-guest-memory only when the guest uses host device in this patchset.
Note: the patchset for qemu is still queued. Luiz has acked, but he said he does not wait an ACK from Jan and/or Anthony.
Changes from v3 to v4: 1. allow the user to specify the core file's format
Changes from v2 to v3: 1. qemu supports the fd that is associated with a pipe, socket, or FIFO. So pass a pipe fd to qemu and O_DIRECT can work now.
Change from v1 to v2: 1. remove the implemention for text mode.
Wen Congyang (3): qemu: implement qemu's dump-guest-memory qemu: allow the client to choose the vmcore's format virsh: allow the user to specify vmcore's format
include/libvirt/libvirt.h.in | 1 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 54 +++++++++++++++++++++++++++++++---------- src/qemu/qemu_monitor.c | 38 +++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 12 +++++++++ src/qemu/qemu_monitor_json.c | 35 +++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++ tools/virsh.c | 3 ++ tools/virsh.pod | 5 +++- 10 files changed, 142 insertions(+), 14 deletions(-)
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (2)
-
Martin Kletzander
-
Wen Congyang