]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
add new virDomainCoreDumpWithFormat API
authorQiao Nuohan <qiaonuohan@cn.fujitsu.com>
Sun, 23 Mar 2014 03:51:12 +0000 (11:51 +0800)
committerEric Blake <eblake@redhat.com>
Mon, 24 Mar 2014 20:14:11 +0000 (14:14 -0600)
--memory-only option is introduced without compression supported. Now qemu
has support for dumping domain's memory in kdump-compressed format. This
patch adds a new virDomainCoreDumpWithFormat API, so that the format in
which qemu dumps domain's memory can be specified.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
include/libvirt/libvirt.h.in
src/driver.h
src/libvirt.c
src/libvirt_public.syms
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs
src/test/test_driver.c

index 82c602b6d189d4219d1cdabc7801bd4f99e66489..91e3e3b9a605a5e3e45c8d9193971f02e7932c1b 100644 (file)
@@ -1180,6 +1180,29 @@ typedef enum {
     VIR_DUMP_MEMORY_ONLY  = (1 << 4), /* use dump-guest-memory */
 } virDomainCoreDumpFlags;
 
+/**
+ * virDomainCoreDumpFormat:
+ *
+ * Values for specifying different formats of domain core dumps.
+ */
+typedef enum {
+    VIR_DOMAIN_CORE_DUMP_FORMAT_RAW,          /* dump guest memory in raw format */
+    VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB,   /* kdump-compressed format, with
+                                               * zlib compression */
+    VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO,    /* kdump-compressed format, with
+                                               * lzo compression */
+    VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY, /* kdump-compressed format, with
+                                               * snappy compression */
+#ifdef VIR_ENUM_SENTINELS
+    VIR_DOMAIN_CORE_DUMP_FORMAT_LAST
+    /*
+     * NB: this enum value will increase over time as new events are
+     * added to the libvirt API. It reflects the last state supported
+     * by this version of the libvirt API.
+     */
+#endif
+} virDomainCoreDumpFormat;
+
 /* Domain migration flags. */
 typedef enum {
     VIR_MIGRATE_LIVE              = (1 << 0), /* live migration */
@@ -1731,6 +1754,14 @@ int                     virDomainCoreDump       (virDomainPtr domain,
                                                  const char *to,
                                                  unsigned int flags);
 
+/*
+ * Domain core dump with format specified
+ */
+int                 virDomainCoreDumpWithFormat (virDomainPtr domain,
+                                                 const char *to,
+                                                 unsigned int dumpformat,
+                                                 unsigned int flags);
+
 /*
  * Screenshot of current domain console
  */
index d728705623896947ac1e78640f39b9f46f39f51c..e66fc7ae5f8ea4b0a2256e468d4b07bf7719cff3 100644 (file)
@@ -306,6 +306,12 @@ typedef int
                         const char *to,
                         unsigned int flags);
 
+typedef int
+(*virDrvDomainCoreDumpWithFormat)(virDomainPtr domain,
+                                  const char *to,
+                                  unsigned int dumpformat,
+                                  unsigned int flags);
+
 typedef char *
 (*virDrvDomainScreenshot)(virDomainPtr domain,
                           virStreamPtr stream,
@@ -1213,6 +1219,7 @@ struct _virDriver {
     virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc;
     virDrvDomainSaveImageDefineXML domainSaveImageDefineXML;
     virDrvDomainCoreDump domainCoreDump;
+    virDrvDomainCoreDumpWithFormat domainCoreDumpWithFormat;
     virDrvDomainScreenshot domainScreenshot;
     virDrvDomainSetVcpus domainSetVcpus;
     virDrvDomainSetVcpusFlags domainSetVcpusFlags;
index c5c3136d0ba2e716394a8cfe2c80ecaae77ad53c..d42da389e57e6b6e42246f590085389c5e113cea 100644 (file)
@@ -2937,6 +2937,8 @@ error:
  * or fail if it cannot do so for the given system; this can allow less
  * pressure on file system cache, but also risks slowing saves to NFS.
  *
+ * For more control over the output format, see virDomainCoreDumpWithFormat().
+ *
  * Returns 0 in case of success and -1 in case of failure.
  */
 int
@@ -2999,6 +3001,105 @@ error:
     return -1;
 }
 
+/**
+ * virDomainCoreDumpWithFormat:
+ * @domain: a domain object
+ * @to: path for the core file
+ * @dumpformat: format of domain memory's dump
+ * @flags: bitwise-OR of virDomainCoreDumpFlags
+ *
+ * This method will dump the core of a domain on a given file for analysis.
+ * Note that for remote Xen Daemon the file path will be interpreted in
+ * the remote host. Hypervisors may require  the user to manually ensure
+ * proper permissions on the file named by @to.
+ *
+ * @dumpformat controls which format the dump will have; use of
+ * VIR_DOMAIN_CORE_DUMP_FORMAT_RAW mirrors what virDomainCoreDump() will
+ * perform.  Not all hypervisors are able to support all formats.
+ *
+ * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
+ * a crashed state after the dump completes.  If @flags includes
+ * VIR_DUMP_LIVE, then make the core dump while continuing to allow
+ * the guest to run; otherwise, the guest is suspended during the dump.
+ * VIR_DUMP_RESET flag forces reset of the quest after dump.
+ * The above three flags are mutually exclusive.
+ *
+ * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt
+ * will attempt to bypass the file system cache while creating the file,
+ * or fail if it cannot do so for the given system; this can allow less
+ * pressure on file system cache, but also risks slowing saves to NFS.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainCoreDumpWithFormat(virDomainPtr domain, const char *to,
+                            unsigned int dumpformat, unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "to=%s, dumpformat=%u, flags=%x",
+                     to, dumpformat, flags);
+
+    virResetLastError();
+
+    virCheckDomainReturn(domain, -1);
+    conn = domain->conn;
+
+    virCheckReadOnlyGoto(conn->flags, error);
+    virCheckNonNullArgGoto(to, error);
+
+    if (dumpformat >= VIR_DOMAIN_CORE_DUMP_FORMAT_LAST) {
+        virReportInvalidArg(flags, _("dumpformat '%d' is not supported"),
+                            dumpformat);
+        goto error;
+    }
+
+    if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) {
+        virReportInvalidArg(flags, "%s",
+                            _("crash and live flags are mutually exclusive"));
+        goto error;
+    }
+
+    if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) {
+        virReportInvalidArg(flags, "%s",
+                            _("crash and reset flags are mutually exclusive"));
+        goto error;
+    }
+
+    if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) {
+        virReportInvalidArg(flags, "%s",
+                            _("live and reset flags are mutually exclusive"));
+        goto error;
+    }
+
+    if (conn->driver->domainCoreDumpWithFormat) {
+        int ret;
+        char *absolute_to;
+
+        /* We must absolutize the file path as the save is done out of process */
+        if (virFileAbsPath(to, &absolute_to) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("could not build absolute core file path"));
+            goto error;
+        }
+
+        ret = conn->driver->domainCoreDumpWithFormat(domain, absolute_to,
+                                                     dumpformat, flags);
+
+        VIR_FREE(absolute_to);
+
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+error:
+    virDispatchError(domain->conn);
+    return -1;
+}
+
 
 /**
  * virDomainScreenshot:
index 6ed6ce61db1ebe8449362919e2e5dc916f2644ac..9ab0c92172ace6794c0c1621f10bcf60c8b6f475 100644 (file)
@@ -645,5 +645,10 @@ LIBVIRT_1.2.1 {
         virConnectNetworkEventDeregisterAny;
 } LIBVIRT_1.1.3;
 
+LIBVIRT_1.2.3 {
+    global:
+        virDomainCoreDumpWithFormat;
+} LIBVIRT_1.2.1;
+
 
 # .... define new API here using predicted next version number ....
index f6d52e20652a8646e2f7f107fc8551ee69f716b9..72545dfb4563816e89bd332cae0c31926202761c 100644 (file)
@@ -7653,6 +7653,7 @@ static virDriver remote_driver = {
     .domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */
     .domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */
     .domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */
+    .domainCoreDumpWithFormat = remoteDomainCoreDumpWithFormat, /* 1.2.3 */
     .domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */
     .domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */
     .domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */
index f1f23594f53b1d4c792b6740a506553cd94ba4b3..6c445cc4314172c5a0351d5b4c0d2fefd5e53178 100644 (file)
@@ -904,6 +904,13 @@ struct remote_domain_core_dump_args {
     unsigned int flags;
 };
 
+struct remote_domain_core_dump_with_format_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string to;
+    unsigned int dumpformat;
+    unsigned int flags;
+};
+
 struct remote_domain_screenshot_args {
     remote_nonnull_domain dom;
     unsigned int screen;
@@ -5262,5 +5269,11 @@ enum remote_procedure {
      * @generate: both
      * @acl: none
      */
-    REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333
+    REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333,
+
+    /**
+     * @generate: both
+     * @acl: domain:core_dump
+     */
+    REMOTE_PROC_DOMAIN_CORE_DUMP_WITH_FORMAT = 334
 };
index 5636d55b8b5adef636d222fe22c3405fe46c83cb..456d0dae0628fe28444c8e6f518994327ac0f215 100644 (file)
@@ -557,6 +557,12 @@ struct remote_domain_core_dump_args {
         remote_nonnull_string      to;
         u_int                      flags;
 };
+struct remote_domain_core_dump_with_format_args {
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      to;
+        u_int                      dumpformat;
+        u_int                      flags;
+};
 struct remote_domain_screenshot_args {
         remote_nonnull_domain      dom;
         u_int                      screen;
@@ -2755,4 +2761,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE = 331,
         REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK = 332,
         REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333,
+        REMOTE_PROC_DOMAIN_CORE_DUMP_WITH_FORMAT = 334,
 };
index d88d3fcd7be551e9b3093c996b7ed8bd891066a5..5694680cdf313eeb194ce0e312da9827db20341a 100644 (file)
@@ -2428,9 +2428,10 @@ testDomainRestore(virConnectPtr conn,
     return testDomainRestoreFlags(conn, path, NULL, 0);
 }
 
-static int testDomainCoreDump(virDomainPtr domain,
-                              const char *to,
-                              unsigned int flags)
+static int testDomainCoreDumpWithFormat(virDomainPtr domain,
+                                        const char *to,
+                                        unsigned int dumpformat,
+                                        unsigned int flags)
 {
     testConnPtr privconn = domain->conn->privateData;
     int fd = -1;
@@ -2468,6 +2469,13 @@ static int testDomainCoreDump(virDomainPtr domain,
         goto cleanup;
     }
 
+    /* we don't support non-raw formats in test driver */
+    if (dumpformat != VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("kdump-compressed format is not supported here"));
+        goto cleanup;
+    }
+
     if (flags & VIR_DUMP_CRASH) {
         testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_CRASHED);
         event = virDomainEventLifecycleNewFromObj(privdom,
@@ -2491,14 +2499,29 @@ cleanup:
     return ret;
 }
 
-static char *testDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
+
+static int
+testDomainCoreDump(virDomainPtr domain,
+                   const char *to,
+                   unsigned int flags)
+{
+    return testDomainCoreDumpWithFormat(domain, to,
+                                        VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, flags);
+}
+
+
+static char *
+testDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED)
+{
     char *ret;
 
     ignore_value(VIR_STRDUP(ret, "linux"));
     return ret;
 }
 
-static unsigned long long testDomainGetMaxMemory(virDomainPtr domain)
+
+static unsigned long long
+testDomainGetMaxMemory(virDomainPtr domain)
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
@@ -7383,6 +7406,7 @@ static virDriver testDriver = {
     .domainRestore = testDomainRestore, /* 0.3.2 */
     .domainRestoreFlags = testDomainRestoreFlags, /* 0.9.4 */
     .domainCoreDump = testDomainCoreDump, /* 0.3.2 */
+    .domainCoreDumpWithFormat = testDomainCoreDumpWithFormat, /* 1.2.3 */
     .domainSetVcpus = testDomainSetVcpus, /* 0.1.4 */
     .domainSetVcpusFlags = testDomainSetVcpusFlags, /* 0.8.5 */
     .domainGetVcpusFlags = testDomainGetVcpusFlags, /* 0.8.5 */