qemu: Fix shutdown regression with buggy qemu

The commit that prevents disk corruption on domain shutdown
(96fc478417) causes regression with QEMU
0.14.* and 0.15.* because of a regression bug in QEMU that was fixed
only recently in QEMU git. The affected versions of QEMU do not quit on
SIGTERM if started with -no-shutdown, which we use to implement fake
reboot. Since -no-shutdown tells QEMU not to quit automatically on guest
shutdown, domains started using the affected QEMU cannot be shutdown
properly and stay in a paused state.

This patch disables fake reboot feature on such QEMU by not using
-no-shutdown, which makes shutdown work as expected. However,
virDomainReboot will not work in this case and it will report "Requested
operation is not valid: Reboot is not supported with this QEMU binary".
This commit is contained in:
Jiri Denemark 2011-09-21 10:25:29 +02:00
parent e531f9a9d8
commit f84aedad09
9 changed files with 87 additions and 13 deletions

View File

@ -136,6 +136,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"pci-ohci",
"usb-redir",
"usb-hub",
"no-shutdown",
);
struct qemu_feature_flags {
@ -1008,6 +1009,13 @@ qemuCapsComputeCmdFlags(const char *help,
qemuCapsSet(flags, QEMU_CAPS_VHOST_NET);
}
/* Do not use -no-shutdown if qemu doesn't support it or SIGTERM handling
* is most likely buggy when used with -no-shutdown (which applies for qemu
* 0.14.* and 0.15.*)
*/
if (strstr(help, "-no-shutdown") && (version < 14000 || version > 15999))
qemuCapsSet(flags, QEMU_CAPS_NO_SHUTDOWN);
/*
* Handling of -incoming arg with varying features
* -incoming tcp (kvm >= 79, qemu >= 0.10.0)

View File

@ -110,6 +110,7 @@ enum qemuCapsFlags {
QEMU_CAPS_PCI_OHCI = 71, /* -device pci-ohci */
QEMU_CAPS_USB_REDIR = 72, /* -device usb-redir */
QEMU_CAPS_USB_HUB = 73, /* -device usb-hub */
QEMU_CAPS_NO_SHUTDOWN = 74, /* usable -no-shutdown */
QEMU_CAPS_LAST, /* this must always be the last item */
};

View File

@ -3574,7 +3574,7 @@ qemuBuildCommandLine(virConnectPtr conn,
* when QEMU stops. If we use no-shutdown, then we can
* watch for this event and do a soft/warm reboot.
*/
if (monitor_json)
if (monitor_json && qemuCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN))
virCommandAddArg(cmd, "-no-shutdown");
if (!(def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)))

View File

@ -1557,6 +1557,12 @@ static int qemuDomainReboot(virDomainPtr dom, unsigned int flags) {
priv = vm->privateData;
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("Reboot is not supported with this QEMU binary"));
goto cleanup;
}
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;

View File

@ -152,7 +152,8 @@ mymain(void)
QEMU_CAPS_KVM,
QEMU_CAPS_DRIVE_FORMAT,
QEMU_CAPS_MEM_PATH,
QEMU_CAPS_TDF);
QEMU_CAPS_TDF,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("kvm-83-rhel56", 9001, 1, 83,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -177,7 +178,8 @@ mymain(void)
QEMU_CAPS_TDF,
QEMU_CAPS_DRIVE_READONLY,
QEMU_CAPS_SMBIOS_TYPE,
QEMU_CAPS_SPICE);
QEMU_CAPS_SPICE,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-0.10.5", 10005, 0, 0,
QEMU_CAPS_KQEMU,
QEMU_CAPS_VNC_COLON,
@ -196,7 +198,8 @@ mymain(void)
QEMU_CAPS_SDL,
QEMU_CAPS_RTC_TD_HACK,
QEMU_CAPS_NO_HPET,
QEMU_CAPS_VGA_NONE);
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-kvm-0.10.5", 10005, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -221,7 +224,8 @@ mymain(void)
QEMU_CAPS_NO_KVM_PIT,
QEMU_CAPS_TDF,
QEMU_CAPS_NESTING,
QEMU_CAPS_VGA_NONE);
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("kvm-86", 10050, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -246,7 +250,8 @@ mymain(void)
QEMU_CAPS_TDF,
QEMU_CAPS_NESTING,
QEMU_CAPS_SMBIOS_TYPE,
QEMU_CAPS_VGA_NONE);
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-kvm-0.11.0-rc2", 10092, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -276,7 +281,8 @@ mymain(void)
QEMU_CAPS_NESTING,
QEMU_CAPS_NAME_PROCESS,
QEMU_CAPS_SMBIOS_TYPE,
QEMU_CAPS_VGA_NONE);
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-0.12.1", 12001, 0, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -306,7 +312,8 @@ mymain(void)
QEMU_CAPS_SMBIOS_TYPE,
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_MIGRATE_QEMU_FD,
QEMU_CAPS_DRIVE_AIO);
QEMU_CAPS_DRIVE_AIO,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-kvm-0.12.1.2-rhel60", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -350,7 +357,8 @@ mymain(void)
QEMU_CAPS_DEVICE_SPICEVMC,
QEMU_CAPS_PIIX3_USB_UHCI,
QEMU_CAPS_PIIX4_USB_UHCI,
QEMU_CAPS_USB_HUB);
QEMU_CAPS_USB_HUB,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-kvm-0.12.3", 12003, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -387,7 +395,8 @@ mymain(void)
QEMU_CAPS_SMBIOS_TYPE,
QEMU_CAPS_VGA_NONE,
QEMU_CAPS_MIGRATE_QEMU_FD,
QEMU_CAPS_DRIVE_AIO);
QEMU_CAPS_DRIVE_AIO,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-kvm-0.13.0", 13000, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -439,7 +448,8 @@ mymain(void)
QEMU_CAPS_PIIX4_USB_UHCI,
QEMU_CAPS_VT82C686B_USB_UHCI,
QEMU_CAPS_PCI_OHCI,
QEMU_CAPS_USB_HUB);
QEMU_CAPS_USB_HUB,
QEMU_CAPS_NO_SHUTDOWN);
DO_TEST("qemu-kvm-0.12.1.2-rhel61", 12001, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@ -487,7 +497,8 @@ mymain(void)
QEMU_CAPS_VIRTIO_IOEVENTFD,
QEMU_CAPS_PIIX3_USB_UHCI,
QEMU_CAPS_PIIX4_USB_UHCI,
QEMU_CAPS_USB_HUB);
QEMU_CAPS_USB_HUB,
QEMU_CAPS_NO_SHUTDOWN);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@ -1,5 +1,5 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,\
id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,\
id=monitor,mode=control -no-shutdown -no-acpi -boot c -hda /dev/hda1 -usb -device \
id=monitor,mode=control -no-acpi -boot c -hda /dev/hda1 -usb -device \
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -0,0 +1,21 @@
LC_ALL=C \
PATH=/bin \
HOME=/home/test \
USER=test \
LOGNAME=test \
/usr/bin/qemu \
-S \
-M pc \
-m 214 \
-smp 1 \
-nographic \
-nodefconfig \
-nodefaults \
-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control \
-no-shutdown \
-no-acpi \
-boot c \
-hda /dev/hda1 \
-usb \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -0,0 +1,24 @@
<domain type='qemu'>
<name>encryptdisk</name>
<uuid>496898a6-e6ff-f7c8-5dc2-3cf410945ee9</uuid>
<memory>219100</memory>
<currentMemory>219100</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/dev/hda1'/>
<target dev='hda'/>
</disk>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -578,6 +578,9 @@ mymain(void)
json = true;
DO_TEST("monitor-json", false, QEMU_CAPS_DEVICE,
QEMU_CAPS_CHARDEV, QEMU_CAPS_MONITOR_JSON, QEMU_CAPS_NODEFCONFIG);
DO_TEST("no-shutdown", false, QEMU_CAPS_DEVICE,
QEMU_CAPS_CHARDEV, QEMU_CAPS_MONITOR_JSON, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_NO_SHUTDOWN);
json = false;
free(driver.stateDir);