[libvirt] [PATCH 2/3 v5] qemu: allow the client to choose the vmcore's format

Wen Congyang wency at cn.fujitsu.com
Tue Jun 12 03:06:33 UTC 2012


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_capabilities.c |    5 +++
 src/qemu/qemu_capabilities.h |    1 +
 src/qemu/qemu_domain.c       |    1 +
 src/qemu/qemu_domain.h       |    1 +
 src/qemu/qemu_driver.c       |   60 ++++++++++++++++++++++++++++++++---------
 6 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index fcb6695..120ed14 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_capabilities.c b/src/qemu/qemu_capabilities.c
index b410648..6eee8cd 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -164,6 +164,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
               "no-user-config",
 
               "hda-micro", /* 95 */
+              "dump-guest-memory",
 
     );
 
@@ -1237,6 +1238,10 @@ qemuCapsComputeCmdFlags(const char *help,
 
     if (version >= 11000)
         qemuCapsSet(flags, QEMU_CAPS_CPU_HOST);
+
+    if (version >= 1001050)
+        qemuCapsSet(flags, QEMU_CAPS_DUMP_GUEST_MEMORY);
+
     return 0;
 }
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 64831e2..640f7f5 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -131,6 +131,7 @@ enum qemuCapsFlags {
     QEMU_CAPS_IDE_CD             = 93, /* -device ide-cd */
     QEMU_CAPS_NO_USER_CONFIG     = 94, /* -no-user-config */
     QEMU_CAPS_HDA_MICRO          = 95, /* -device hda-micro */
+    QEMU_CAPS_DUMP_GUEST_MEMORY  = 96, /* dump-guest-memory command */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3752ddf..91c0645 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 1256c4e..3a5f1f3 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 d3f74d2..b2da838 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2986,12 +2986,39 @@ 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 (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) {
+        qemuReportError(VIR_ERR_NO_SUPPORT, "%s",
+                        _("dump-guest-memory is not supported"));
+        return -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;
@@ -3000,7 +3027,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) {
@@ -3020,14 +3047,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;
     }
@@ -3085,7 +3118,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);
@@ -3127,8 +3161,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;
 
@@ -3289,6 +3322,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,
@@ -3311,9 +3345,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"));
@@ -9402,7 +9436,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
@@ -9460,7 +9494,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




More information about the libvir-list mailing list