[libvirt] [PATCH] support compressed crashdump of guests

Now, virsh dump doesn't support compresses dump. This patch adds GZIP and LZOP option to virsh dump and support it at qemu coredump. (AFAIK, LZOP is available on RHEL6.) When I did 4G guest dump, (Raw) 3844669750 (Gzip) 1029846577 (LZOP) 1416263880 (faster than gzip in general) This will be a help for a host where crash-dump is used and several guests works on it. help message is modified as this. NAME dump - dump the core of a domain to a file for analysis SYNOPSIS dump [--live] [--crash] [--gzip] [--lzop] <domain> <file> DESCRIPTION Core dump a domain. OPTIONS --live perform a live core dump if supported --crash crash the domain after core dump --gzip gzip dump(only one compression allowed --lzop lzop dump(only one compression allowed [--domain] <string> domain name, id or uuid [--file] <string> where to dump the core Tested on Fedora-13+x86-64. Note: for better compression, we may have to skip pages filled by zero or freed pages. But it seems it's qemu's works. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> --- include/libvirt/libvirt.h.in | 2 ++ src/qemu/qemu_driver.c | 23 +++++++++++++++++++---- tools/virsh.c | 10 +++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) Index: libvirt-0.8.4/src/qemu/qemu_driver.c =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_driver.c +++ libvirt-0.8.4/src/qemu/qemu_driver.c @@ -5710,7 +5710,7 @@ cleanup: static int qemudDomainCoreDump(virDomainPtr dom, const char *path, - int flags ATTRIBUTE_UNUSED) { + int flags) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; int resume = 0, paused = 0; @@ -5720,6 +5720,14 @@ static int qemudDomainCoreDump(virDomain "cat", NULL, }; + const char *zargs[] = { + "gzip", + NULL, + }; + const char *lzargs[] = { + "lzop", + NULL, + }; qemuDomainObjPrivatePtr priv; qemuDriverLock(driver); @@ -5787,9 +5795,16 @@ static int qemudDomainCoreDump(virDomain } qemuDomainObjEnterMonitorWithDriver(driver, vm); - ret = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, 0); + if (flags & VIR_DUMP_GZIP) + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, zargs, path, 0); + else if (flags & VIR_DUMP_LZOP) + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, lzargs, path, 0); + else + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, args, path, 0); + qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) goto endjob; Index: libvirt-0.8.4/tools/virsh.c =================================================================== --- libvirt-0.8.4.orig/tools/virsh.c +++ libvirt-0.8.4/tools/virsh.c @@ -1751,6 +1751,8 @@ static const vshCmdInfo info_dump[] = { static const vshCmdOptDef opts_dump[] = { {"live", VSH_OT_BOOL, 0, N_("perform a live core dump if supported")}, {"crash", VSH_OT_BOOL, 0, N_("crash the domain after core dump")}, + {"gzip", VSH_OT_BOOL, 0, N_("gzip dump(only one compression allowed")}, + {"lzop", VSH_OT_BOOL, 0, N_("lzop dump(only one compression allowed")}, {"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")}, {NULL, 0, 0, NULL} @@ -1778,7 +1780,13 @@ cmdDump(vshControl *ctl, const vshCmd *c flags |= VIR_DUMP_LIVE; if (vshCommandOptBool (cmd, "crash")) flags |= VIR_DUMP_CRASH; - + if (vshCommandOptBool (cmd, "gzip")) + flags |= VIR_DUMP_GZIP; + if (vshCommandOptBool (cmd, "lzop")) + flags |= VIR_DUMP_LZOP; + if ((flags & (VIR_DUMP_GZIP | VIR_DUMP_LZOP)) + == (VIR_DUMP_GZIP | VIR_DUMP_LZOP)) + return FALSE; if (virDomainCoreDump(dom, to, flags) == 0) { vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to); } else { Index: libvirt-0.8.4/include/libvirt/libvirt.h.in =================================================================== --- libvirt-0.8.4.orig/include/libvirt/libvirt.h.in +++ libvirt-0.8.4/include/libvirt/libvirt.h.in @@ -402,6 +402,8 @@ typedef virDomainMemoryStatStruct *virDo typedef enum { VIR_DUMP_CRASH = (1 << 0), /* crash after dump */ VIR_DUMP_LIVE = (1 << 1), /* live dump */ + VIR_DUMP_GZIP = (1 << 2), /* gzip dump file */ + VIR_DUMP_LZOP = (1 << 3), /* lzop dump file */ } virDomainCoreDumpFlags; /* Domain migration flags. */

On Thu, Oct 21, 2010 at 12:02:11PM +0900, KAMEZAWA Hiroyuki wrote:
Now, virsh dump doesn't support compresses dump. This patch adds GZIP and LZOP option to virsh dump and support it at qemu coredump. (AFAIK, LZOP is available on RHEL6.)
When I did 4G guest dump, (Raw) 3844669750 (Gzip) 1029846577 (LZOP) 1416263880 (faster than gzip in general)
This will be a help for a host where crash-dump is used and several guests works on it.
help message is modified as this. NAME dump - dump the core of a domain to a file for analysis
SYNOPSIS dump [--live] [--crash] [--gzip] [--lzop] <domain> <file>
DESCRIPTION Core dump a domain.
OPTIONS --live perform a live core dump if supported --crash crash the domain after core dump --gzip gzip dump(only one compression allowed --lzop lzop dump(only one compression allowed [--domain] <string> domain name, id or uuid [--file] <string> where to dump the core
Tested on Fedora-13+x86-64.
Note: for better compression, we may have to skip pages filled by zero or freed pages. But it seems it's qemu's works.
The patch looks relatively simple and clean, I still have one comemnt below though. It also seems to me that any use of the dump need a follow up decompression before it can be fed to debug tools (gdb ...) as I don't think they handle compressed dumps natively. The other comment on principle about this patch is that for saving compression we use a qemu.conf option, maybe we should instead use a new option there for core compression, or simply reuse the same option for both (core being just a special kind of save). You will also note that save_image_format takes more options than lzop or gzip. If doing so one doesn't need to change virsh too. It's a trade off. If using the configuration option you need to plan in advance the fact you will be dumping compressed core, if you expose it at the API level itself, you can activate it anytime, and that may be more useful for example when interacting with a customer facing an issue needing debug. So both ways are acceptable to me.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> --- include/libvirt/libvirt.h.in | 2 ++ src/qemu/qemu_driver.c | 23 +++++++++++++++++++---- tools/virsh.c | 10 +++++++++- 3 files changed, 30 insertions(+), 5 deletions(-)
Index: libvirt-0.8.4/src/qemu/qemu_driver.c =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_driver.c +++ libvirt-0.8.4/src/qemu/qemu_driver.c @@ -5710,7 +5710,7 @@ cleanup:
static int qemudDomainCoreDump(virDomainPtr dom, const char *path, - int flags ATTRIBUTE_UNUSED) { + int flags) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; int resume = 0, paused = 0; @@ -5720,6 +5720,14 @@ static int qemudDomainCoreDump(virDomain "cat", NULL, }; + const char *zargs[] = { + "gzip", + NULL, + }; + const char *lzargs[] = { + "lzop", + NULL, + }; qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver); @@ -5787,9 +5795,16 @@ static int qemudDomainCoreDump(virDomain }
qemuDomainObjEnterMonitorWithDriver(driver, vm); - ret = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, 0); + if (flags & VIR_DUMP_GZIP) + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, zargs, path, 0); + else if (flags & VIR_DUMP_LZOP) + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, lzargs, path, 0); + else + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, args, path, 0); +
I'm wondering what happens if the compression command is not present, if the current error message we get back from qemu is clear enough then fine, but otherwise we may have to check for the presence of the compressor program.
qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) goto endjob; Index: libvirt-0.8.4/tools/virsh.c =================================================================== --- libvirt-0.8.4.orig/tools/virsh.c +++ libvirt-0.8.4/tools/virsh.c @@ -1751,6 +1751,8 @@ static const vshCmdInfo info_dump[] = { static const vshCmdOptDef opts_dump[] = { {"live", VSH_OT_BOOL, 0, N_("perform a live core dump if supported")}, {"crash", VSH_OT_BOOL, 0, N_("crash the domain after core dump")}, + {"gzip", VSH_OT_BOOL, 0, N_("gzip dump(only one compression allowed")}, + {"lzop", VSH_OT_BOOL, 0, N_("lzop dump(only one compression allowed")},
what about bzip2 and xz, the first one is probably way too slow, but we accept it for saves.
{"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")}, {NULL, 0, 0, NULL} @@ -1778,7 +1780,13 @@ cmdDump(vshControl *ctl, const vshCmd *c flags |= VIR_DUMP_LIVE; if (vshCommandOptBool (cmd, "crash")) flags |= VIR_DUMP_CRASH; - + if (vshCommandOptBool (cmd, "gzip")) + flags |= VIR_DUMP_GZIP; + if (vshCommandOptBool (cmd, "lzop")) + flags |= VIR_DUMP_LZOP; + if ((flags & (VIR_DUMP_GZIP | VIR_DUMP_LZOP)) + == (VIR_DUMP_GZIP | VIR_DUMP_LZOP)) + return FALSE;
I think an error message need to be provided stating that both options are mutually exclusive. Otherwise that looks fine to me, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Thu, 21 Oct 2010 10:35:10 +0200 Daniel Veillard <veillard@redhat.com> wrote:
On Thu, Oct 21, 2010 at 12:02:11PM +0900, KAMEZAWA Hiroyuki wrote:
Now, virsh dump doesn't support compresses dump. This patch adds GZIP and LZOP option to virsh dump and support it at qemu coredump. (AFAIK, LZOP is available on RHEL6.)
When I did 4G guest dump, (Raw) 3844669750 (Gzip) 1029846577 (LZOP) 1416263880 (faster than gzip in general)
This will be a help for a host where crash-dump is used and several guests works on it.
help message is modified as this. NAME dump - dump the core of a domain to a file for analysis
SYNOPSIS dump [--live] [--crash] [--gzip] [--lzop] <domain> <file>
DESCRIPTION Core dump a domain.
OPTIONS --live perform a live core dump if supported --crash crash the domain after core dump --gzip gzip dump(only one compression allowed --lzop lzop dump(only one compression allowed [--domain] <string> domain name, id or uuid [--file] <string> where to dump the core
Tested on Fedora-13+x86-64.
Note: for better compression, we may have to skip pages filled by zero or freed pages. But it seems it's qemu's works.
Thank you for review.
The patch looks relatively simple and clean, I still have one comemnt below though. It also seems to me that any use of the dump need a follow up decompression before it can be fed to debug tools (gdb ...) as I don't think they handle compressed dumps natively.
Yes. But at support-job, coredump must be transfered to support-team enviroment in many case. In that case, dump image tend to be compressed.
The other comment on principle about this patch is that for saving compression we use a qemu.conf option, maybe we should instead use a new option there for core compression, or simply reuse the same option for both (core being just a special kind of save). You will also note that save_image_format takes more options than lzop or gzip. If doing so one doesn't need to change virsh too.
Ah, okay, this one ? http://www.mail-archive.com/libvir-list@redhat.com/msg15564.html Doesn't this affect behaviors other than dump ?
It's a trade off. If using the configuration option you need to plan in advance the fact you will be dumping compressed core, if you expose it at the API level itself, you can activate it anytime, and that may be more useful for example when interacting with a customer facing an issue needing debug. So both ways are acceptable to me.
Sure.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> --- include/libvirt/libvirt.h.in | 2 ++ src/qemu/qemu_driver.c | 23 +++++++++++++++++++---- tools/virsh.c | 10 +++++++++- 3 files changed, 30 insertions(+), 5 deletions(-)
Index: libvirt-0.8.4/src/qemu/qemu_driver.c =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_driver.c +++ libvirt-0.8.4/src/qemu/qemu_driver.c @@ -5710,7 +5710,7 @@ cleanup:
static int qemudDomainCoreDump(virDomainPtr dom, const char *path, - int flags ATTRIBUTE_UNUSED) { + int flags) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; int resume = 0, paused = 0; @@ -5720,6 +5720,14 @@ static int qemudDomainCoreDump(virDomain "cat", NULL, }; + const char *zargs[] = { + "gzip", + NULL, + }; + const char *lzargs[] = { + "lzop", + NULL, + }; qemuDomainObjPrivatePtr priv;
qemuDriverLock(driver); @@ -5787,9 +5795,16 @@ static int qemudDomainCoreDump(virDomain }
qemuDomainObjEnterMonitorWithDriver(driver, vm); - ret = qemuMonitorMigrateToFile(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - args, path, 0); + if (flags & VIR_DUMP_GZIP) + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, zargs, path, 0); + else if (flags & VIR_DUMP_LZOP) + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, lzargs, path, 0); + else + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, args, path, 0); +
I'm wondering what happens if the compression command is not present, if the current error message we get back from qemu is clear enough then fine, but otherwise we may have to check for the presence of the compressor program.
Ok, I will add check code. But hmm, calling system() for checking command exists is ok ? Or some good function do we have ?
qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) goto endjob; Index: libvirt-0.8.4/tools/virsh.c =================================================================== --- libvirt-0.8.4.orig/tools/virsh.c +++ libvirt-0.8.4/tools/virsh.c @@ -1751,6 +1751,8 @@ static const vshCmdInfo info_dump[] = { static const vshCmdOptDef opts_dump[] = { {"live", VSH_OT_BOOL, 0, N_("perform a live core dump if supported")}, {"crash", VSH_OT_BOOL, 0, N_("crash the domain after core dump")}, + {"gzip", VSH_OT_BOOL, 0, N_("gzip dump(only one compression allowed")}, + {"lzop", VSH_OT_BOOL, 0, N_("lzop dump(only one compression allowed")},
what about bzip2 and xz, the first one is probably way too slow, but we accept it for saves.
will add bzip2 and xz. (but maybe very slow.)
{"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")}, {NULL, 0, 0, NULL} @@ -1778,7 +1780,13 @@ cmdDump(vshControl *ctl, const vshCmd *c flags |= VIR_DUMP_LIVE; if (vshCommandOptBool (cmd, "crash")) flags |= VIR_DUMP_CRASH; - + if (vshCommandOptBool (cmd, "gzip")) + flags |= VIR_DUMP_GZIP; + if (vshCommandOptBool (cmd, "lzop")) + flags |= VIR_DUMP_LZOP; + if ((flags & (VIR_DUMP_GZIP | VIR_DUMP_LZOP)) + == (VIR_DUMP_GZIP | VIR_DUMP_LZOP)) + return FALSE;
I think an error message need to be provided stating that both options are mutually exclusive.
I'll add one. Thank you. -Kame

On Thu, Oct 21, 2010 at 10:35:10AM +0200, Daniel Veillard wrote:
On Thu, Oct 21, 2010 at 12:02:11PM +0900, KAMEZAWA Hiroyuki wrote:
Now, virsh dump doesn't support compresses dump. This patch adds GZIP and LZOP option to virsh dump and support it at qemu coredump. (AFAIK, LZOP is available on RHEL6.)
When I did 4G guest dump, (Raw) 3844669750 (Gzip) 1029846577 (LZOP) 1416263880 (faster than gzip in general)
This will be a help for a host where crash-dump is used and several guests works on it.
help message is modified as this. NAME dump - dump the core of a domain to a file for analysis
SYNOPSIS dump [--live] [--crash] [--gzip] [--lzop] <domain> <file>
DESCRIPTION Core dump a domain.
OPTIONS --live perform a live core dump if supported --crash crash the domain after core dump --gzip gzip dump(only one compression allowed --lzop lzop dump(only one compression allowed [--domain] <string> domain name, id or uuid [--file] <string> where to dump the core
Tested on Fedora-13+x86-64.
Note: for better compression, we may have to skip pages filled by zero or freed pages. But it seems it's qemu's works.
The patch looks relatively simple and clean, I still have one comemnt below though. It also seems to me that any use of the dump need a follow up decompression before it can be fed to debug tools (gdb ...) as I don't think they handle compressed dumps natively.
The other comment on principle about this patch is that for saving compression we use a qemu.conf option, maybe we should instead use a new option there for core compression, or simply reuse the same option for both (core being just a special kind of save). You will also note that save_image_format takes more options than lzop or gzip. If doing so one doesn't need to change virsh too.
It's a trade off. If using the configuration option you need to plan in advance the fact you will be dumping compressed core, if you expose it at the API level itself, you can activate it anytime, and that may be more useful for example when interacting with a customer facing an issue needing debug. So both ways are acceptable to me.
IMHO, we should follow the same style for save/restore and core dump. As you say save/restore setup compression in qemu.conf & we should do the same for core dump, allowing all the same formats. Compression is the kind of thing you just want enabled all the time. I don't see anyone who is going to pick & choose different compression algorithms per API call, so exposing all the compression methods is just using up a significant portion of the flag space for little real world gain. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Thu, 21 Oct 2010 10:26:42 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
On Thu, Oct 21, 2010 at 10:35:10AM +0200, Daniel Veillard wrote:
On Thu, Oct 21, 2010 at 12:02:11PM +0900, KAMEZAWA Hiroyuki wrote:
Now, virsh dump doesn't support compresses dump. This patch adds GZIP and LZOP option to virsh dump and support it at qemu coredump. (AFAIK, LZOP is available on RHEL6.)
When I did 4G guest dump, (Raw) 3844669750 (Gzip) 1029846577 (LZOP) 1416263880 (faster than gzip in general)
This will be a help for a host where crash-dump is used and several guests works on it.
help message is modified as this. NAME dump - dump the core of a domain to a file for analysis
SYNOPSIS dump [--live] [--crash] [--gzip] [--lzop] <domain> <file>
DESCRIPTION Core dump a domain.
OPTIONS --live perform a live core dump if supported --crash crash the domain after core dump --gzip gzip dump(only one compression allowed --lzop lzop dump(only one compression allowed [--domain] <string> domain name, id or uuid [--file] <string> where to dump the core
Tested on Fedora-13+x86-64.
Note: for better compression, we may have to skip pages filled by zero or freed pages. But it seems it's qemu's works.
The patch looks relatively simple and clean, I still have one comemnt below though. It also seems to me that any use of the dump need a follow up decompression before it can be fed to debug tools (gdb ...) as I don't think they handle compressed dumps natively.
The other comment on principle about this patch is that for saving compression we use a qemu.conf option, maybe we should instead use a new option there for core compression, or simply reuse the same option for both (core being just a special kind of save). You will also note that save_image_format takes more options than lzop or gzip. If doing so one doesn't need to change virsh too.
It's a trade off. If using the configuration option you need to plan in advance the fact you will be dumping compressed core, if you expose it at the API level itself, you can activate it anytime, and that may be more useful for example when interacting with a customer facing an issue needing debug. So both ways are acceptable to me.
IMHO, we should follow the same style for save/restore and core dump. As you say save/restore setup compression in qemu.conf & we should do the same for core dump, allowing all the same formats. Compression is the kind of thing you just want enabled all the time. I don't see anyone who is going to pick & choose different compression algorithms per API call, so exposing all the compression methods is just using up a significant portion of the flag space for little real world gain.
IMHO, hibernation(save vm) and coredump has big difference in usage. Hibernation is a planned one and the system schedules disk space for it. Coredump is not a planned one and the system has some special area for coredump. (At least, most of crashdump user has specail disk space for crashdump.) Usage is not the same and purpose is, either. 1. Assume a case: hibernation use gzip and coredump use "raw" Hibernation can be slow because it's scheduled one. Coredump must be fast because the user has to bring the guest up ASAP. 2. Assume a case: hibernation use raw and coredump uses lzop. A user want to hibernation quickly. But at coredump, the user uses cluster-fail-over and coredump itself is not need to be fast but disk-space for crashdump seems to be small. There are real gain, I think. But ok, if "flag" space is important, I'd like to only support lzop. Is it ok ? Thanks, -Kame

On Fri, 22 Oct 2010 12:48:38 +0900 KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:
On Thu, 21 Oct 2010 10:26:42 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
On Thu, Oct 21, 2010 at 10:35:10AM +0200, Daniel Veillard wrote:
On Thu, Oct 21, 2010 at 12:02:11PM +0900, KAMEZAWA Hiroyuki wrote:
Now, virsh dump doesn't support compresses dump. This patch adds GZIP and LZOP option to virsh dump and support it at qemu coredump. (AFAIK, LZOP is available on RHEL6.)
When I did 4G guest dump, (Raw) 3844669750 (Gzip) 1029846577 (LZOP) 1416263880 (faster than gzip in general)
This will be a help for a host where crash-dump is used and several guests works on it.
help message is modified as this. NAME dump - dump the core of a domain to a file for analysis
SYNOPSIS dump [--live] [--crash] [--gzip] [--lzop] <domain> <file>
DESCRIPTION Core dump a domain.
OPTIONS --live perform a live core dump if supported --crash crash the domain after core dump --gzip gzip dump(only one compression allowed --lzop lzop dump(only one compression allowed [--domain] <string> domain name, id or uuid [--file] <string> where to dump the core
Tested on Fedora-13+x86-64.
Note: for better compression, we may have to skip pages filled by zero or freed pages. But it seems it's qemu's works.
The patch looks relatively simple and clean, I still have one comemnt below though. It also seems to me that any use of the dump need a follow up decompression before it can be fed to debug tools (gdb ...) as I don't think they handle compressed dumps natively.
The other comment on principle about this patch is that for saving compression we use a qemu.conf option, maybe we should instead use a new option there for core compression, or simply reuse the same option for both (core being just a special kind of save). You will also note that save_image_format takes more options than lzop or gzip. If doing so one doesn't need to change virsh too.
It's a trade off. If using the configuration option you need to plan in advance the fact you will be dumping compressed core, if you expose it at the API level itself, you can activate it anytime, and that may be more useful for example when interacting with a customer facing an issue needing debug. So both ways are acceptable to me.
IMHO, we should follow the same style for save/restore and core dump. As you say save/restore setup compression in qemu.conf & we should do the same for core dump, allowing all the same formats. Compression is the kind of thing you just want enabled all the time. I don't see anyone who is going to pick & choose different compression algorithms per API call, so exposing all the compression methods is just using up a significant portion of the flag space for little real world gain.
IMHO, hibernation(save vm) and coredump has big difference in usage. Hibernation is a planned one and the system schedules disk space for it. Coredump is not a planned one and the system has some special area for coredump. (At least, most of crashdump user has specail disk space for crashdump.) Usage is not the same and purpose is, either.
I discussed my team and decied to start from save_image_format qemu.conf. Or I'll add dump_image_format configuration in qemu.conf Thanks, -Kame

Thank you for advices for v1. This version adss dump_image_format config for qemu.conf. 1/2 adds dump_image_format, 2/2 adds the check for availability of compression program for save_image_format and dump_image_format. == Add dump_image_format[] to qemu.conf and support compressed dump at virsh dump. coredump compression is important for saving disk space in an environment where multiple guest run. (In general, "disk space for dump" is specially allocated and will be a dead space in the system. It's used only at emergency. So, it's better to have both of save_image_format and dump_image_format. "save" is done in scheduled manner with enough calculated disk space for it.) This code reuses some of save_image_format[] and supports the same format with virsh save. --- src/qemu/qemu.conf | 4 ++++ src/qemu/qemu_conf.c | 11 +++++++++++ src/qemu/qemu_conf.h | 1 + src/qemu/qemu_driver.c | 30 +++++++++++++++++++++++++----- 4 files changed, 41 insertions(+), 5 deletions(-) Index: libvirt-0.8.4/src/qemu/qemu_conf.c =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_conf.c +++ libvirt-0.8.4/src/qemu/qemu_conf.c @@ -324,6 +324,17 @@ int qemudLoadDriverConfig(struct qemud_d } } + p = virConfGetValue (conf, "dump_image_format"); + CHECK_TYPE ("dump_image_format", VIR_CONF_STRING); + if (p && p->str) { + VIR_FREE(driver->dumpImageFormat); + if (!(driver->dumpImageFormat = strdup(p->str))) { + virReportOOMError(); + virConfFree(conf); + return -1; + } + } + p = virConfGetValue (conf, "hugetlbfs_mount"); CHECK_TYPE ("hugetlbfs_mount", VIR_CONF_STRING); if (p && p->str) { Index: libvirt-0.8.4/src/qemu/qemu_conf.h =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_conf.h +++ libvirt-0.8.4/src/qemu/qemu_conf.h @@ -159,6 +159,7 @@ struct qemud_driver { virSecurityDriverPtr securitySecondaryDriver; char *saveImageFormat; + char *dumpImageFormat; pciDeviceList *activePciHostdevs; Index: libvirt-0.8.4/src/qemu/qemu.conf =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu.conf +++ libvirt-0.8.4/src/qemu/qemu.conf @@ -144,7 +144,11 @@ # saving a domain in order to save disk space; the list above is in descending # order by performance and ascending order by compression ratio. # +# save_image_format is used when you use 'virsh save' at scheduled saving. +# dump_image_format is used when you use 'virsh dump' at emergency crashdump. +# # save_image_format = "raw" +# dump_image_format = "raw" # If provided by the host and a hugetlbfs mount point is configured, # a guest may request huge page backing. When this mount point is Index: libvirt-0.8.4/src/qemu/qemu_driver.c =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_driver.c +++ libvirt-0.8.4/src/qemu/qemu_driver.c @@ -5716,11 +5716,15 @@ static int qemudDomainCoreDump(virDomain int resume = 0, paused = 0; int ret = -1, fd = -1; virDomainEventPtr event = NULL; - const char *args[] = { - "cat", - NULL, - }; + int compress; qemuDomainObjPrivatePtr priv; + /* + * We reuse "save" flag for "dump" here. Then, we can support the same + * format in "save" and "dump". + */ + compress = QEMUD_SAVE_FORMAT_RAW; + if (driver->dumpImageFormat) + compress = qemudSaveCompressionTypeFromString(driver->dumpImageFormat); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -5787,9 +5791,25 @@ static int qemudDomainCoreDump(virDomain } qemuDomainObjEnterMonitorWithDriver(driver, vm); - ret = qemuMonitorMigrateToFile(priv->mon, + if (compress == QEMUD_SAVE_FORMAT_RAW) { + const char *args[] = { + "cat", + NULL, + }; + ret = qemuMonitorMigrateToFile(priv->mon, QEMU_MONITOR_MIGRATE_BACKGROUND, args, path, 0); + } else { + const char *prog = qemudSaveCompressionTypeToString(compress); + const char *args[] = { + prog, + "-c", + NULL, + }; + ret = qemuMonitorMigrateToFile(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + args, path, 0); + } qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) goto endjob;

At compression, external programs are used but it is not checked whether the program is available or not. Check it at parsing qemu.conf and find problems in early stage. --- src/qemu/qemu_conf.c | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) Index: libvirt-0.8.4/src/qemu/qemu_conf.c =================================================================== --- libvirt-0.8.4.orig/src/qemu/qemu_conf.c +++ libvirt-0.8.4/src/qemu/qemu_conf.c @@ -316,22 +316,54 @@ int qemudLoadDriverConfig(struct qemud_d p = virConfGetValue (conf, "save_image_format"); CHECK_TYPE ("save_image_format", VIR_CONF_STRING); if (p && p->str) { - VIR_FREE(driver->saveImageFormat); - if (!(driver->saveImageFormat = strdup(p->str))) { - virReportOOMError(); - virConfFree(conf); - return -1; - } + int find = 1; + if (strcmp(p->str, "raw")) { + char *c; + c = virFindFileInPath(p->str); + if (!c) + find = 0; + else + VIR_FREE(c); + } + VIR_FREE(driver->saveImageFormat); + if (find) { + if (!(driver->saveImageFormat = strdup(p->str))) { + virReportOOMError(); + virConfFree(conf); + return -1; + } + } else { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "save_image_format cannot find program %s", p->str); + virConfFree(conf); + return -1; + } } p = virConfGetValue (conf, "dump_image_format"); CHECK_TYPE ("dump_image_format", VIR_CONF_STRING); if (p && p->str) { + int find = 1; + if (strcmp(p->str, "raw")) { + char *c; + c = virFindFileInPath(p->str); + if (!c) + find = 0; + else + VIR_FREE(c); + } VIR_FREE(driver->dumpImageFormat); - if (!(driver->dumpImageFormat = strdup(p->str))) { + if (find) { + if (!(driver->dumpImageFormat = strdup(p->str))) { virReportOOMError(); virConfFree(conf); return -1; + } + } else { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "dump_image_format cannot find program %s", p->str); + virConfFree(conf); + return -1; } }
participants (3)
-
Daniel P. Berrange
-
Daniel Veillard
-
KAMEZAWA Hiroyuki