[libvirt] [PATCH RFC 1/2] support compression when --memory-only option is specified

--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@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
participants (1)
-
Qiao Nuohan