The commit that prevents disk corruption on domain shutdown
(
96fc4784177ecb70357518fa863442455e45ad0e) 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".
"pci-ohci",
"usb-redir",
"usb-hub",
+ "no-shutdown",
);
struct qemu_feature_flags {
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)
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 */
};
* 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)))
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;
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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;
}
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
--- /dev/null
+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
--- /dev/null
+<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>
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);