[libvirt] [PATCH 0/2] vmcoreinfo feature

From: Marc-André Lureau <marcandre.lureau@redhat.com> Hi, Starting with QEMU 2.11, the guest can save kernel debug details when this feature is enabled and the kernel supports it. It is useful to process kernel dump with KASLR enabled, and also provides various kernel details to crash tools. rfc->v1: - rebased - update commit message to give some internal fw_cfg details - add news patch Marc-André Lureau (2): qemu: add vmcoreinfo support news: add vmcoreinfo feature details docs/formatdomain.html.in | 4 +++ docs/news.xml | 11 +++++++ docs/schemas/domaincommon.rng | 9 +++++ src/conf/domain_conf.c | 3 ++ src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 26 +++++++++++++++ .../qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args | 25 ++++++++++++++ tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml | 28 ++++++++++++++++ tests/qemuxml2argvtest.c | 1 + .../qemuxml2xmlout-vmcoreinfo.xml | 38 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 13 files changed, 150 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-vmcoreinfo.xml -- 2.15.0.125.g8f49766d64

From: Marc-André Lureau <marcandre.lureau@redhat.com> Starting from qemu 2.11, the `-device vmcoreinfo` will create a fw_cfg entry for a guest to store dump details, necessary to process kernel dump with KASLR enabled and providing additional kernel details. In essence, it is similar to -fw_cfg name=etc/vmcoreinfo,file=X but in this case it is not backed by a file, but collected by QEMU itself. Since the device is a singleton and shouldn't use additional hardware resources, it is presented as a <feature> element in the libvirt domain XML. The device is arm/x86 only for now (targets that support fw_cfg+dma). Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1395248 Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> --- docs/formatdomain.html.in | 4 +++ docs/schemas/domaincommon.rng | 9 +++++ src/conf/domain_conf.c | 3 ++ src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 26 +++++++++++++++ .../qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args | 25 ++++++++++++++ tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml | 28 ++++++++++++++++ tests/qemuxml2argvtest.c | 1 + .../qemuxml2xmlout-vmcoreinfo.xml | 38 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 12 files changed, 139 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-vmcoreinfo.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 8dbea6af7..4bc88cfc5 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1951,6 +1951,10 @@ the attribute is not defined, the hypervisor default will be used. <span class="since">Since 3.10.0</span> (QEMU/KVM only) </dd> + <dt><code>vmcoreinfo</code></dt> + <dd>Enable QEMU vmcoreinfo device to let the guest kernel save debug + details. <span class="since">Since 3.10.0</span> (QEMU only) + </dd> </dl> <h3><a id="elementsTime">Time keeping</a></h3> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 82fdfd5f7..f1808065b 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4739,6 +4739,9 @@ <optional> <ref name="hpt"/> </optional> + <optional> + <ref name="vmcoreinfo"/> + </optional> </interleave> </element> </optional> @@ -4939,6 +4942,12 @@ </element> </define> + <define name="vmcoreinfo"> + <element name="vmcoreinfo"> + <empty/> + </element> + </define> + <define name="address"> <element name="address"> <choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0e4f76f06..5e3c07703 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -151,6 +151,7 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "smm", "ioapic", "hpt", + "vmcoreinfo", ); VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST, @@ -18719,6 +18720,7 @@ virDomainDefParseXML(xmlDocPtr xml, case VIR_DOMAIN_FEATURE_VIRIDIAN: case VIR_DOMAIN_FEATURE_PRIVNET: case VIR_DOMAIN_FEATURE_HYPERV: + case VIR_DOMAIN_FEATURE_VMCOREINFO: case VIR_DOMAIN_FEATURE_KVM: def->features[val] = VIR_TRISTATE_SWITCH_ON; break; @@ -26089,6 +26091,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, case VIR_DOMAIN_FEATURE_ACPI: case VIR_DOMAIN_FEATURE_PAE: case VIR_DOMAIN_FEATURE_VIRIDIAN: + case VIR_DOMAIN_FEATURE_VMCOREINFO: case VIR_DOMAIN_FEATURE_PRIVNET: switch ((virTristateSwitch) def->features[i]) { case VIR_TRISTATE_SWITCH_ABSENT: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3ac24ab32..cb8701dd2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1724,6 +1724,7 @@ typedef enum { VIR_DOMAIN_FEATURE_SMM, VIR_DOMAIN_FEATURE_IOAPIC, VIR_DOMAIN_FEATURE_HPT, + VIR_DOMAIN_FEATURE_VMCOREINFO, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 1badadbc2..dcf5ddc5e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -444,6 +444,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "vxhs", "virtio-blk.num-queues", "machine.pseries.resize-hpt", + "vmcoreinfo", ); @@ -1671,6 +1672,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "pcie-root-port", QEMU_CAPS_DEVICE_PCIE_ROOT_PORT }, { "qemu-xhci", QEMU_CAPS_DEVICE_QEMU_XHCI }, { "spapr-pci-host-bridge", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE }, + { "vmcoreinfo", QEMU_CAPS_DEVICE_VMCOREINFO }, }; static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBalloon[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f0e2e9016..17daa67a5 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -430,6 +430,7 @@ typedef enum { QEMU_CAPS_VXHS, /* -drive file.driver=vxhs via query-qmp-schema */ QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES, /* virtio-blk-*.num-queues */ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT, /* -machine pseries,resize-hpt */ + QEMU_CAPS_DEVICE_VMCOREINFO, /* -device vmcoreinfo */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 56729e498..1ee957680 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9710,6 +9710,29 @@ qemuBuildTPMCommandLine(virCommandPtr cmd, } +static int +qemuBuildVMCoreInfoCommandLine(virCommandPtr cmd, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + virTristateSwitch vmci = def->features[VIR_DOMAIN_FEATURE_VMCOREINFO]; + + if (vmci != VIR_TRISTATE_SWITCH_ON) { + return 0; + } + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMCOREINFO)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vmcoreinfo is not available " + "with this QEMU binary")); + return -1; + } + + virCommandAddArgList(cmd, "-device", "vmcoreinfo", NULL); + return 0; +} + + static int qemuBuildPanicCommandLine(virCommandPtr cmd, const virDomainDef *def, @@ -10129,6 +10152,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildNVRAMCommandLine(cmd, def, qemuCaps) < 0) goto error; + if (qemuBuildVMCoreInfoCommandLine(cmd, def, qemuCaps) < 0) + goto error; + if (snapshot) virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args b/tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args new file mode 100644 index 000000000..772e5a071 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.args @@ -0,0 +1,25 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-device vmcoreinfo diff --git a/tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml b/tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml new file mode 100644 index 000000000..f8e586531 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-vmcoreinfo.xml @@ -0,0 +1,28 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <vmcoreinfo/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 1bedc6874..b3e71aa1b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2822,6 +2822,7 @@ mymain(void) DO_TEST_PARSE_ERROR("cpu-cache-emulate-l2", QEMU_CAPS_KVM); DO_TEST_PARSE_ERROR("cpu-cache-passthrough3", QEMU_CAPS_KVM); DO_TEST_PARSE_ERROR("cpu-cache-passthrough-l3", QEMU_CAPS_KVM); + DO_TEST("vmcoreinfo", QEMU_CAPS_DEVICE_VMCOREINFO); DO_TEST("user-aliases", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_CIRRUS_VGA, QEMU_CAPS_OBJECT_MEMORY_FILE, QEMU_CAPS_PIIX_DISABLE_S3, diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-vmcoreinfo.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-vmcoreinfo.xml new file mode 100644 index 000000000..a3922d630 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-vmcoreinfo.xml @@ -0,0 +1,38 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <vmcoreinfo/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i686</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 1afd0d271..99d831c32 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1265,6 +1265,7 @@ mymain(void) DO_TEST("cpu-check-default-none2", NONE); DO_TEST("cpu-check-default-partial", NONE); DO_TEST("cpu-check-default-partial2", NONE); + DO_TEST("vmcoreinfo", NONE); DO_TEST("smartcard-host", NONE); DO_TEST("smartcard-host-certificates", NONE); -- 2.15.0.125.g8f49766d64

From: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> --- docs/news.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index efde4c8b7..5eb0b79d6 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -65,6 +65,17 @@ hypervisor defaults and negotiation between the guest and the host. </description> </change> + <change> + <summary> + qemu: Add vmcoreinfo feature + </summary> + <description> + Starting with QEMU 2.11, the guest can save kernel debug + details when this feature is enabled and the kernel supports + it. It is useful to process kernel dump with KASLR enabled, + and also provides various kernel details to crash tools. + </description> + </change> </section> <section title="Improvements"> <change> -- 2.15.0.125.g8f49766d64

On Thu, Nov 16, 2017 at 05:49:37PM +0100, marcandre.lureau@redhat.com wrote:
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Hi,
Starting with QEMU 2.11, the guest can save kernel debug details when this feature is enabled and the kernel supports it. It is useful to process kernel dump with KASLR enabled, and also provides various kernel details to crash tools.
rfc->v1: - rebased - update commit message to give some internal fw_cfg details - add news patch
Thanks, ACK. There was still one issue that wouldn't go through make syntax-check, but I fixed it and pushed the series.
participants (2)
-
marcandre.lureau@redhat.com
-
Martin Kletzander