--memory-only option is introduced without compression supported. Therefore,
this is a freature regression of virsh dump. This patch is used to add
"--compress" and "[--compression-format] <string>" to the
command
"virsh dump --memory-only" and send dump-guest-memory command to qemu with dump
format specified to one of elf, kdump-zlib, kdump-lzo and kdump-snappy.
Signed-off-by: Qiao Nuohan <qiaonuohan(a)cn.fujitsu.com>
---
include/libvirt/libvirt.h.in | 18 +++++++++++++-----
src/libvirt.c | 15 +++++++++++++++
src/qemu/qemu_driver.c | 21 +++++++++++++++++----
src/qemu/qemu_monitor.c | 6 +++---
src/qemu/qemu_monitor.h | 3 ++-
src/qemu/qemu_monitor_json.c | 4 +++-
src/qemu/qemu_monitor_json.h | 3 ++-
tests/qemumonitorjsontest.c | 2 +-
tools/virsh-domain.c | 29 +++++++++++++++++++++++++++++
9 files changed, 85 insertions(+), 16 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a448411..cb8989e 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1165,11 +1165,19 @@ typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
/* Domain core dump flags. */
typedef enum {
- VIR_DUMP_CRASH = (1 << 0), /* crash after dump */
- 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 */
+ VIR_DUMP_CRASH = (1 << 0), /* crash after dump */
+ 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 */
+ VIR_DUMP_COMPRESS = (1 << 5), /* dump guest memory in
+ kdump-compressed format */
+ VIR_DUMP_COMPRESS_ZLIB = (1 << 6), /* kdump-compressed format, with
+ zlib-compressed */
+ VIR_DUMP_COMPRESS_LZO = (1 << 7), /* kdump-compressed format, with
+ lzo-compressed */
+ VIR_DUMP_COMPRESS_SNAPPY = (1 << 8), /* kdump-compressed format, with
+ snappy-compressed */
} virDomainCoreDumpFlags;
/* Domain migration flags. */
diff --git a/src/libvirt.c b/src/libvirt.c
index 666526e..318296e 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -2969,6 +2969,21 @@ virDomainCoreDump(virDomainPtr domain, const char *to,
unsigned int flags)
goto error;
}
+ if ((flags & VIR_DUMP_COMPRESS) && !(flags & VIR_DUMP_MEMORY_ONLY))
{
+ virReportInvalidArg(flags, "%s",
+ _("compress flag cannot be set without memory-only
"
+ "flag"));
+ goto error;
+ }
+
+ if ((flags & (VIR_DUMP_COMPRESS_ZLIB | VIR_DUMP_COMPRESS_LZO |
+ VIR_DUMP_COMPRESS_SNAPPY)) && !(flags & VIR_DUMP_COMPRESS))
{
+ virReportInvalidArg(flags, "%s",
+ _("compression-format cannot be set without "
+ "compress flag"));
+ goto error;
+ }
+
if (conn->driver->domainCoreDump) {
int ret;
char *absolute_to;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index df4f5b5..c4e1aef 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3380,7 +3380,8 @@ cleanup:
}
static int qemuDumpToFd(virQEMUDriverPtr driver, virDomainObjPtr vm,
- int fd, enum qemuDomainAsyncJob asyncJob)
+ int fd, enum qemuDomainAsyncJob asyncJob,
+ const char* dump_format)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
@@ -3400,7 +3401,7 @@ static int qemuDumpToFd(virQEMUDriverPtr driver,
virDomainObjPtr vm,
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
- ret = qemuMonitorDumpToFd(priv->mon, fd);
+ ret = qemuMonitorDumpToFd(priv->mon, fd, dump_format);
qemuDomainObjExitMonitor(driver, vm);
return ret;
@@ -3418,6 +3419,7 @@ doCoreDump(virQEMUDriverPtr driver,
virFileWrapperFdPtr wrapperFd = NULL;
int directFlag = 0;
unsigned int flags = VIR_FILE_WRAPPER_NON_BLOCKING;
+ const char *dump_format;
/* Create an empty file with appropriate ownership. */
if (dump_flags & VIR_DUMP_BYPASS_CACHE) {
@@ -3441,7 +3443,16 @@ doCoreDump(virQEMUDriverPtr driver,
goto cleanup;
if (dump_flags & VIR_DUMP_MEMORY_ONLY) {
- ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP);
+ if (dump_flags & VIR_DUMP_COMPRESS_ZLIB)
+ dump_format = "kdump-zlib";
+ else if (dump_flags & VIR_DUMP_COMPRESS_LZO)
+ dump_format = "kdump-lzo";
+ else if (dump_flags & VIR_DUMP_COMPRESS_SNAPPY)
+ dump_format = "kdump-snappy";
+ else
+ dump_format = "elf";
+ ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP,
+ dump_format);
} else {
ret = qemuMigrationToFile(driver, vm, fd, 0, path,
qemuCompressProgramName(compress), false,
@@ -3517,7 +3528,9 @@ static int qemuDomainCoreDump(virDomainPtr dom,
virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET |
- VIR_DUMP_MEMORY_ONLY, -1);
+ VIR_DUMP_MEMORY_ONLY | VIR_DUMP_COMPRESS |
+ VIR_DUMP_COMPRESS_ZLIB | VIR_DUMP_COMPRESS_LZO |
+ VIR_DUMP_COMPRESS_SNAPPY, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a968901..c2c4a1e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2338,10 +2338,10 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon)
}
int
-qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd)
+qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd, const char *dump_format)
{
int ret;
- VIR_DEBUG("mon=%p fd=%d", mon, fd);
+ VIR_DEBUG("mon=%p fd=%d dump_format=%s", mon, fd, dump_format);
if (!mon) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -2361,7 +2361,7 @@ qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd)
if (qemuMonitorSendFileHandle(mon, "dump", fd) < 0)
return -1;
- ret = qemuMonitorJSONDump(mon, "fd:dump");
+ ret = qemuMonitorJSONDump(mon, "fd:dump", dump_format);
if (ret < 0) {
if (qemuMonitorCloseFileHandle(mon, "dump") < 0)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index eabf000..f2e5763 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -495,7 +495,8 @@ int qemuMonitorMigrateToUnix(qemuMonitorPtr mon,
int qemuMonitorMigrateCancel(qemuMonitorPtr mon);
int qemuMonitorDumpToFd(qemuMonitorPtr mon,
- int fd);
+ int fd,
+ const char *dump_format);
int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon,
int type,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index ec3b958..a16ef44 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2636,7 +2636,8 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon)
int
qemuMonitorJSONDump(qemuMonitorPtr mon,
- const char *protocol)
+ const char *protocol,
+ const char *dump_format)
{
int ret;
virJSONValuePtr cmd = NULL;
@@ -2645,6 +2646,7 @@ qemuMonitorJSONDump(qemuMonitorPtr mon,
cmd = qemuMonitorJSONMakeCommand("dump-guest-memory",
"b:paging", false,
"s:protocol", protocol,
+ "s:format", dump_format,
NULL);
if (!cmd)
return -1;
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index a93c51e..7691356 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -148,7 +148,8 @@ int qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitorPtr mon,
int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon);
int qemuMonitorJSONDump(qemuMonitorPtr mon,
- const char *protocol);
+ const char *protocol,
+ const char *dump_format);
int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon,
int type,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 2152e4a..256655a 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -1154,7 +1154,7 @@ GEN_TEST_FUNC(qemuMonitorJSONSetMigrationDowntime, 1)
GEN_TEST_FUNC(qemuMonitorJSONMigrate, QEMU_MONITOR_MIGRATE_BACKGROUND |
QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
QEMU_MONITOR_MIGRATE_NON_SHARED_INC, "tcp:localhost:12345")
-GEN_TEST_FUNC(qemuMonitorJSONDump, "dummy_protocol")
+GEN_TEST_FUNC(qemuMonitorJSONDump, "dummy_protocol",
"dummy_dump_format")
GEN_TEST_FUNC(qemuMonitorJSONGraphicsRelocate, VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
"localhost", 12345, 12346, NULL)
GEN_TEST_FUNC(qemuMonitorJSONAddNetdev, "some_dummy_netdevstr")
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index b4ca4c3..652c7ec 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -4519,6 +4519,14 @@ static const vshCmdOptDef opts_dump[] = {
.type = VSH_OT_BOOL,
.help = N_("dump domain's memory only")
},
+ {.name = "compress",
+ .type = VSH_OT_BOOL,
+ .help = N_("dump domain's memory in kdump-compressed format")
+ },
+ {.name = "compression-format",
+ .type = VSH_OT_DATA,
+ .help = N_("specify the compression format of kdump-compressed format")
+ },
{.name = NULL}
};
@@ -4533,6 +4541,7 @@ doDump(void *opaque)
sigset_t sigmask, oldsigmask;
const char *name = NULL;
const char *to = NULL;
+ const char *compression_format = NULL;
unsigned int flags = 0;
sigemptyset(&sigmask);
@@ -4556,6 +4565,26 @@ doDump(void *opaque)
flags |= VIR_DUMP_RESET;
if (vshCommandOptBool(cmd, "memory-only"))
flags |= VIR_DUMP_MEMORY_ONLY;
+ if (vshCommandOptBool(cmd, "compress"))
+ flags |= VIR_DUMP_COMPRESS;
+
+ if (vshCommandOptString(cmd, "compression-format",
&compression_format)) {
+ if (STREQ(compression_format, "zlib"))
+ flags |= VIR_DUMP_COMPRESS_ZLIB;
+ else if (STREQ(compression_format, "lzo"))
+ flags |= VIR_DUMP_COMPRESS_LZO;
+ else if (STREQ(compression_format, "snappy"))
+ flags |= VIR_DUMP_COMPRESS_SNAPPY;
+ else {
+ vshError(ctl, _("compression format %s is not supported, "
+ "expecting 'zlib', 'lzo' or
'snappy'."),
+ compression_format);
+ goto out;
+ }
+ } else {
+ if (flags & VIR_DUMP_COMPRESS)
+ flags |= VIR_DUMP_COMPRESS_ZLIB;
+ }
if (virDomainCoreDump(dom, to, flags) < 0) {
vshError(ctl, _("Failed to core dump domain %s to %s"), name, to);
--
1.8.3.1