[libvirt] [PATCH v2] qemu: don't use deprecated -no-kvm-pit-reinjection

Since qemu-kvm 1.1 [1] (since 1.3. in upstream QEMU [2]) '-no-kvm-pit-reinjection' has been deprecated. Use -device kvm-pit,lost_tick_policy=discard instead. https://bugzilla.redhat.com/show_bug.cgi?id=978719 [1] http://git.kernel.org/cgit/virt/kvm/qemu-kvm.git/commit/?id=4e4fa39 [2] http://git.qemu.org/?p=qemu.git;a=commitdiff;h=c21fb4f --- src/qemu/qemu_capabilities.c | 5 ++-- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 8 ++++-- .../qemuxml2argv-kvm-pit-delay.args | 4 +++ .../qemuxml2argv-kvm-pit-delay.xml | 29 ++++++++++++++++++++++ .../qemuxml2argv-kvm-pit-device.args | 5 ++++ .../qemuxml2argv-kvm-pit-device.xml | 29 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 4 +++ 8 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.xml diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index baaaefe..31bd19c 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -233,6 +233,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "mlock", "vnc-share-policy", /* 150 */ + "kvm-pit", ); struct _virQEMUCaps { @@ -1381,6 +1382,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE }, { "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI }, { "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC }, + { "kvm-pit", QEMU_CAPS_DEVICE_KVM_PIT }, }; static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { @@ -2446,13 +2448,12 @@ virQEMUCapsInitArchQMPBasic(virQEMUCapsPtr qemuCaps, /* * Currently only x86_64 and i686 support PCI-multibus, - * -no-acpi and -no-kvm-pit-reinjection. + * -no-acpi */ if (qemuCaps->arch == VIR_ARCH_X86_64 || qemuCaps->arch == VIR_ARCH_I686) { virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS); virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI); - virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT); } ret = 0; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 7088747..9c21811 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -189,6 +189,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_DRIVE_DISCARD = 148, /* -drive discard=off(ignore)|on(unmap) */ QEMU_CAPS_MLOCK = 149, /* -realtime mlock=on|off */ QEMU_CAPS_VNC_SHARE_POLICY = 150, /* set display sharing policy */ + QEMU_CAPS_DEVICE_KVM_PIT = 151, /* -device kvm-pit */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0e517f2..0b640c0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6994,11 +6994,15 @@ qemuBuildCommandLine(virConnectPtr conn, case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY: /* delay is the default if we don't have kernel (-no-kvm-pit), otherwise, the default is catchup. */ - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT)) + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_KVM_PIT)) + virCommandAddArgList(cmd, "-device", + "kvm-pit,lost_tick_policy=discard", NULL); + else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT)) virCommandAddArg(cmd, "-no-kvm-pit-reinjection"); break; case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP: - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT)) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT) || + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_KVM_PIT)) { /* do nothing - this is default for kvm-pit */ } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDF)) { /* -tdf switches to 'catchup' with userspace pit. */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.args b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.args new file mode 100644 index 0000000..326c582 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \ +-M pc -m 214 -smp 2 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-kvm-pit-reinjection -no-acpi -boot c -usb -hda /dev/HostVG/QEMUGuest1 \ +-net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.xml new file mode 100644 index 0000000..7835a1b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-delay.xml @@ -0,0 +1,29 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</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='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.args b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.args new file mode 100644 index 0000000..cb7c951 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \ +-M pc -m 214 -smp 2 -nographic \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-device kvm-pit,lost_tick_policy=discard -no-acpi -boot c -usb \ +-hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.xml new file mode 100644 index 0000000..7835a1b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-pit-device.xml @@ -0,0 +1,29 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</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='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 7d7332f..e6aa793 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1018,6 +1018,10 @@ mymain(void) DO_TEST_PARSE_ERROR("pci-bridge-negative-index-invalid", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST("kvm-pit-device", QEMU_CAPS_DEVICE_KVM_PIT); + DO_TEST("kvm-pit-delay", QEMU_CAPS_NO_KVM_PIT); + DO_TEST("kvm-pit-device", QEMU_CAPS_NO_KVM_PIT, QEMU_CAPS_DEVICE_KVM_PIT); + virObjectUnref(driver.config); virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); -- 1.8.1.5

On 07/12/2013 08:54 AM, Ján Tomko wrote:
Since qemu-kvm 1.1 [1] (since 1.3. in upstream QEMU [2]) '-no-kvm-pit-reinjection' has been deprecated. Use -device kvm-pit,lost_tick_policy=discard instead.
https://bugzilla.redhat.com/show_bug.cgi?id=978719
[1] http://git.kernel.org/cgit/virt/kvm/qemu-kvm.git/commit/?id=4e4fa39 [2] http://git.qemu.org/?p=qemu.git;a=commitdiff;h=c21fb4f ---
@@ -2446,13 +2448,12 @@ virQEMUCapsInitArchQMPBasic(virQEMUCapsPtr qemuCaps,
/* * Currently only x86_64 and i686 support PCI-multibus, - * -no-acpi and -no-kvm-pit-reinjection. + * -no-acpi */ if (qemuCaps->arch == VIR_ARCH_X86_64 || qemuCaps->arch == VIR_ARCH_I686) { virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS); virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI); - virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
This part seems dubious, like it might break upgrades. If an older libvirt says that qemu has a feature, and a VM is running, then when you upgrade libvirtd and the feature is no longer provided by qemu, then libvirtd may silently drop the domain definition because it can't find a qemu binary that supports the same features as were required by the older libvirtd. It shouldn't hurt to leave this cap bit set, even if the rest of this patch is about avoiding the need to rely on this cap bit. Otherwise, the patch looks okay to me. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Fri, Jul 12, 2013 at 09:47:57AM -0600, Eric Blake wrote:
On 07/12/2013 08:54 AM, Ján Tomko wrote:
Since qemu-kvm 1.1 [1] (since 1.3. in upstream QEMU [2]) '-no-kvm-pit-reinjection' has been deprecated. Use -device kvm-pit,lost_tick_policy=discard instead.
https://bugzilla.redhat.com/show_bug.cgi?id=978719
[1] http://git.kernel.org/cgit/virt/kvm/qemu-kvm.git/commit/?id=4e4fa39 [2] http://git.qemu.org/?p=qemu.git;a=commitdiff;h=c21fb4f ---
@@ -2446,13 +2448,12 @@ virQEMUCapsInitArchQMPBasic(virQEMUCapsPtr qemuCaps,
/* * Currently only x86_64 and i686 support PCI-multibus, - * -no-acpi and -no-kvm-pit-reinjection. + * -no-acpi */ if (qemuCaps->arch == VIR_ARCH_X86_64 || qemuCaps->arch == VIR_ARCH_I686) { virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS); virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI); - virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
This part seems dubious, like it might break upgrades. If an older libvirt says that qemu has a feature, and a VM is running, then when you upgrade libvirtd and the feature is no longer provided by qemu, then libvirtd may silently drop the domain definition because it can't find a qemu binary that supports the same features as were required by the older libvirtd. It shouldn't hurt to leave this cap bit set, even if the rest of this patch is about avoiding the need to rely on this cap bit.
That shouldn't happen I think. For any runing guest, we have recorded the original capabilities in the domain status XML file. So any caps we detect against QEMU binaries upon restart will only impact newly started guests. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 07/12/2013 09:53 AM, Daniel P. Berrange wrote:
if (qemuCaps->arch == VIR_ARCH_X86_64 || qemuCaps->arch == VIR_ARCH_I686) { virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS); virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI); - virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
This part seems dubious, like it might break upgrades. If an older libvirt says that qemu has a feature, and a VM is running, then when you upgrade libvirtd and the feature is no longer provided by qemu, then libvirtd may silently drop the domain definition because it can't find a qemu binary that supports the same features as were required by the older libvirtd. It shouldn't hurt to leave this cap bit set, even if the rest of this patch is about avoiding the need to rely on this cap bit.
That shouldn't happen I think. For any runing guest, we have recorded the original capabilities in the domain status XML file. So any caps we detect against QEMU binaries upon restart will only impact newly started guests.
I seem to recall difficulties in the past, such as when developing on a RHEL machine, where the upstream and the downstream list of cap bits are different, and where restarting upstream libvirtd had problems with domains already started by downstream libvirtd. I'd feel better if this were explicitly tested (easy enough to do - build libvirtd without this patch, start a domain, rebuild libvirtd with the patch, restart libvirtd, and see if virsh can still control the domain). -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 07/12/2013 10:00 AM, Eric Blake wrote:
That shouldn't happen I think. For any runing guest, we have recorded the original capabilities in the domain status XML file. So any caps we detect against QEMU binaries upon restart will only impact newly started guests.
I seem to recall difficulties in the past, such as when developing on a RHEL machine, where the upstream and the downstream list of cap bits are different, and where restarting upstream libvirtd had problems with domains already started by downstream libvirtd. I'd feel better if this were explicitly tested (easy enough to do - build libvirtd without this patch, start a domain, rebuild libvirtd with the patch, restart libvirtd, and see if virsh can still control the domain).
Or maybe the difficulty I'm recalling is the case of _unknown_ cap bits. You may be right that a known, but differently-set bit, behaves nicer than parsing the XML with a bit that is completely unknown. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Ján Tomko