From 90e178f8bffe1dd013b5d707723609125c46f667 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 3 Aug 2016 16:20:19 +0100 Subject: [PATCH] qemu: allow turning off QEMU guest RAM dump globally We already have the ability to turn off dumping of guest RAM via the domain XML. This is not particularly useful though, as it is under control of the management application. What is needed is a way for the sysadmin to turn off guest RAM defaults globally, regardless of whether the mgmt app provides its own way to set this in the domain XML. So this adds a 'dump_guest_core' option in /etc/libvirt/qemu.conf which defaults to false. ie guest RAM will never be included in the QEMU core dumps by default. This default is different from historical practice, but is considered to be more suitable as a default because a) guest RAM can be huge and so inflicts a DOS on the host I/O subsystem when dumping core for QEMU crashes b) guest RAM can contain alot of sensitive data belonging to the VM owner. This should not generally be copied around inside QEMU core dumps submitted to vendors for debugging c) guest RAM contents are rarely useful in diagnosing QEMU crashes Signed-off-by: Daniel P. Berrange --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 16 +++++++++++++--- src/qemu/qemu_command.c | 18 ++++++++++++------ src/qemu/qemu_conf.c | 3 +++ src/qemu/qemu_conf.h | 1 + src/qemu/test_libvirtd_qemu.aug.in | 1 + tests/qemuxml2argvtest.c | 4 ++++ 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 9ec8250840..e0d8b9dd83 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -76,6 +76,7 @@ module Libvirtd_qemu = | int_entry "max_processes" | int_entry "max_files" | limits_entry "max_core" + | bool_entry "dump_guest_core" | str_entry "stdio_handler" let device_entry = bool_entry "mac_filter" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index b1ece732c9..4bc062341f 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -406,10 +406,10 @@ # RAM size is smaller than the limit set. # # Be warned that the core dump will include a full copy of the -# guest RAM, unless it has been disabled via the guest XML by -# setting: +# guest RAM, if the 'dump_guest_core' setting has been enabled, +# or if the guest XML contains # -# ...guest ram... +# ...guest ram... # # If guest RAM is to be included, ensure the max_core limit # is set to at least the size of the largest expected guest @@ -425,6 +425,16 @@ # #max_core = "unlimited" +# Determine if guest RAM is included in QEMU core dumps. By +# default guest RAM will be excluded if a new enough QEMU is +# present. Setting this to '1' will force guest RAM to always +# be included in QEMU core dumps. +# +# This setting will be ignored if the guest XML has set the +# dumpcore attribute on the element. +# +#dump_guest_core = 1 + # mac_filter enables MAC addressed based filtering on bridge ports. # This currently requires ebtables to be installed. # diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 982c33cd26..ed1ca1fe71 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6930,6 +6930,7 @@ qemuBuildNameCommandLine(virCommandPtr cmd, static int qemuBuildMachineCommandLine(virCommandPtr cmd, + virQEMUDriverConfigPtr cfg, const virDomainDef *def, virQEMUCapsPtr qemuCaps) { @@ -7014,16 +7015,21 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, virTristateSwitchTypeToString(smm)); } - if (def->mem.dump_core) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) { + if (def->mem.dump_core) { + virBufferAsprintf(&buf, ",dump-guest-core=%s", + virTristateSwitchTypeToString(def->mem.dump_core)); + } else { + virBufferAsprintf(&buf, ",dump-guest-core=%s", + cfg->dumpGuestCore ? "on" : "off"); + } + } else { + if (def->mem.dump_core) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("dump-guest-core is not available " "with this QEMU binary")); goto cleanup; } - - virBufferAsprintf(&buf, ",dump-guest-core=%s", - virTristateSwitchTypeToString(def->mem.dump_core)); } if (def->mem.nosharepages) { @@ -9396,7 +9402,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (enableFips) virCommandAddArg(cmd, "-enable-fips"); - if (qemuBuildMachineCommandLine(cmd, def, qemuCaps) < 0) + if (qemuBuildMachineCommandLine(cmd, cfg, def, qemuCaps) < 0) goto error; if (qemuBuildCpuCommandLine(cmd, driver, def, qemuCaps, !!migrateURI) < 0) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b3db22c045..17b73c2c68 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -654,6 +654,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, goto cleanup; } + if (virConfGetValueBool(conf, "dump_guest_core", &cfg->dumpGuestCore) < 0) + goto cleanup; + if (virConfGetValueString(conf, "lock_manager", &cfg->lockManagerName) < 0) goto cleanup; if (virConfGetValueString(conf, "stdio_handler", &stdioHandler) < 0) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index b730202c5e..c73d812da3 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -149,6 +149,7 @@ struct _virQEMUDriverConfig { unsigned int maxProcesses; unsigned int maxFiles; unsigned long long maxCore; + bool dumpGuestCore; unsigned int maxQueuedJobs; diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index 1d3c0b73a6..834c5340a8 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -63,6 +63,7 @@ module Test_libvirtd_qemu = { "max_processes" = "0" } { "max_files" = "0" } { "max_core" = "unlimited" } +{ "dump_guest_core" = "1" } { "mac_filter" = "1" } { "relaxed_acs_check" = "1" } { "allow_disk_format_probing" = "1" } diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 39abe726ef..aaf00c2fb6 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -614,8 +614,12 @@ mymain(void) DO_TEST("machine-aliases2", QEMU_CAPS_KVM); DO_TEST("machine-core-on", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_DUMP_GUEST_CORE); + driver.config->dumpGuestCore = true; DO_TEST("machine-core-off", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_DUMP_GUEST_CORE); + driver.config->dumpGuestCore = false; + DO_TEST("machine-core-cfg-off", QEMU_CAPS_MACHINE_OPT, + QEMU_CAPS_DUMP_GUEST_CORE); DO_TEST_FAILURE("machine-core-on", NONE); DO_TEST_FAILURE("machine-core-on", QEMU_CAPS_MACHINE_OPT); DO_TEST("machine-smm-opt",