edecca
From b56deb73400af9518bdc86802b8ac8da0670d806 Mon Sep 17 00:00:00 2001
edecca
Message-Id: <b56deb73400af9518bdc86802b8ac8da0670d806@dist-git>
edecca
From: Laine Stump <laine@laine.org>
edecca
Date: Thu, 10 Jan 2019 09:44:45 -0500
edecca
Subject: [PATCH] conf: correct false boot order error during domain parse
edecca
edecca
virDomainDefCollectBootOrder() is called for every item on the list
edecca
for each type of device. One of the checks it makes is to gather the
edecca
order attributes from the <boot> element of all devices, and assure
edecca
that no two devices have been given the same order.
edecca
edecca
Since (internally to libvirt, *not* in the domain XML) an 
edecca
type='hostdev'> is on both the list of hostdev devices and the list of
edecca
network devices, it will be counted twice, and the code that checks
edecca
for multiple devices with the same boot order will give a false
edecca
positive.
edecca
edecca
To remedy this, we make sure to return early for hostdev devices that
edecca
have a parent.type != NONE.
edecca
edecca
This was introduced in commit 5b75a4, which was first in libvirt-4.4.0.
edecca
edecca
Resolves: https://bugzilla.redhat.com/1630393 (RHEL8)
edecca
Resolves: https://bugzilla.redhat.com/1601318 (RHEL7)
edecca
edecca
Change from upstream: upstream has eliminated QEMU_CAPS_BOOTINDEX and
edecca
QEMU_CAPS_PCI_BOOTINDEX so they're no longer necessary in test cases.
edecca
edecca
Signed-off-by: Laine Stump <laine@laine.org>
edecca
(cherry picked from commit 7ea7342996d74591e00bcbf14b1eb3995f77a199)
edecca
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
edecca
---
edecca
 src/conf/domain_conf.c                        |  8 ++++
edecca
 .../net-hostdev-bootorder.args                | 27 ++++++++++++
edecca
 .../net-hostdev-bootorder.xml                 | 36 ++++++++++++++++
edecca
 tests/qemuxml2argvtest.c                      |  3 ++
edecca
 .../net-hostdev-bootorder.xml                 | 42 +++++++++++++++++++
edecca
 tests/qemuxml2xmltest.c                       |  1 +
edecca
 6 files changed, 117 insertions(+)
edecca
 create mode 100644 tests/qemuxml2argvdata/net-hostdev-bootorder.args
edecca
 create mode 100644 tests/qemuxml2argvdata/net-hostdev-bootorder.xml
edecca
 create mode 100644 tests/qemuxml2xmloutdata/net-hostdev-bootorder.xml
edecca
edecca
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
edecca
index 660e1523fe..d431441f62 100644
edecca
--- a/src/conf/domain_conf.c
edecca
+++ b/src/conf/domain_conf.c
edecca
@@ -5076,6 +5076,14 @@ virDomainDefCollectBootOrder(virDomainDefPtr def ATTRIBUTE_UNUSED,
edecca
     if (info->bootIndex == 0)
edecca
         return 0;
edecca
 
edecca
+    if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
edecca
+        dev->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE) {
edecca
+        /* This hostdev is a child of a higher level device
edecca
+         * (e.g. interface), and thus already being counted on the
edecca
+         * list for the other device type.
edecca
+         */
edecca
+        return 0;
edecca
+    }
edecca
     if (virAsprintf(&order, "%u", info->bootIndex) < 0)
edecca
         goto cleanup;
edecca
 
edecca
diff --git a/tests/qemuxml2argvdata/net-hostdev-bootorder.args b/tests/qemuxml2argvdata/net-hostdev-bootorder.args
edecca
new file mode 100644
edecca
index 0000000000..e632d9b195
edecca
--- /dev/null
edecca
+++ b/tests/qemuxml2argvdata/net-hostdev-bootorder.args
edecca
@@ -0,0 +1,27 @@
edecca
+LC_ALL=C \
edecca
+PATH=/bin \
edecca
+HOME=/home/test \
edecca
+USER=test \
edecca
+LOGNAME=test \
edecca
+QEMU_AUDIO_DRV=none \
edecca
+/usr/bin/qemu-system-i686 \
edecca
+-name QEMUGuest1 \
edecca
+-S \
edecca
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
edecca
+-m 214 \
edecca
+-smp 1,sockets=1,cores=1,threads=1 \
edecca
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
edecca
+-display none \
edecca
+-no-user-config \
edecca
+-nodefaults \
edecca
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
edecca
+server,nowait \
edecca
+-mon chardev=charmonitor,id=monitor,mode=control \
edecca
+-rtc base=utc \
edecca
+-no-shutdown \
edecca
+-no-acpi \
edecca
+-usb \
edecca
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
edecca
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,\
edecca
+bootindex=2 \
edecca
+-device pci-assign,host=03:07.1,id=hostdev0,bootindex=1,bus=pci.0,addr=0x3
edecca
diff --git a/tests/qemuxml2argvdata/net-hostdev-bootorder.xml b/tests/qemuxml2argvdata/net-hostdev-bootorder.xml
edecca
new file mode 100644
edecca
index 0000000000..cd9f32b2f3
edecca
--- /dev/null
edecca
+++ b/tests/qemuxml2argvdata/net-hostdev-bootorder.xml
edecca
@@ -0,0 +1,36 @@
edecca
+<domain type='qemu'>
edecca
+  <name>QEMUGuest1</name>
edecca
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
edecca
+  <memory unit='KiB'>219136</memory>
edecca
+  <currentMemory unit='KiB'>219136</currentMemory>
edecca
+  <vcpu placement='static'>1</vcpu>
edecca
+  <os>
edecca
+    <type arch='i686' machine='pc'>hvm</type>
edecca
+  </os>
edecca
+  <clock offset='utc'/>
edecca
+  <on_poweroff>destroy</on_poweroff>
edecca
+  <on_reboot>restart</on_reboot>
edecca
+  <on_crash>destroy</on_crash>
edecca
+  <devices>
edecca
+    <emulator>/usr/bin/qemu-system-i686</emulator>
edecca
+    <disk type='block' device='disk'>
edecca
+      <source dev='/dev/HostVG/QEMUGuest1'/>
edecca
+      <target dev='hda' bus='ide'/>
edecca
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
edecca
+      <boot order='2'/>
edecca
+    </disk>
edecca
+    <controller type='usb' index='0'/>
edecca
+    <controller type='ide' index='0'/>
edecca
+    <controller type='pci' index='0' model='pci-root'/>
edecca
+    <interface type='hostdev' managed='yes'>
edecca
+      <mac address='00:11:22:33:44:55'/>
edecca
+      <source>
edecca
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
edecca
+      </source>
edecca
+      <boot order='1'/>
edecca
+    </interface>
edecca
+    <input type='mouse' bus='ps2'/>
edecca
+    <input type='keyboard' bus='ps2'/>
edecca
+    <memballoon model='none'/>
edecca
+  </devices>
edecca
+</domain>
edecca
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
edecca
index bd4aa1266d..690a39054e 100644
edecca
--- a/tests/qemuxml2argvtest.c
edecca
+++ b/tests/qemuxml2argvtest.c
edecca
@@ -1324,6 +1324,9 @@ mymain(void)
edecca
     DO_TEST("net-mcast", NONE);
edecca
     DO_TEST("net-udp", NONE);
edecca
     DO_TEST("net-hostdev", NONE);
edecca
+    DO_TEST("net-hostdev-bootorder",
edecca
+            QEMU_CAPS_BOOTINDEX,
edecca
+            QEMU_CAPS_PCI_BOOTINDEX);
edecca
     DO_TEST("net-hostdev-multidomain", NONE);
edecca
     DO_TEST("net-hostdev-vfio",
edecca
             QEMU_CAPS_DEVICE_VFIO_PCI);
edecca
diff --git a/tests/qemuxml2xmloutdata/net-hostdev-bootorder.xml b/tests/qemuxml2xmloutdata/net-hostdev-bootorder.xml
edecca
new file mode 100644
edecca
index 0000000000..d9ecf40cf0
edecca
--- /dev/null
edecca
+++ b/tests/qemuxml2xmloutdata/net-hostdev-bootorder.xml
edecca
@@ -0,0 +1,42 @@
edecca
+<domain type='qemu'>
edecca
+  <name>QEMUGuest1</name>
edecca
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
edecca
+  <memory unit='KiB'>219136</memory>
edecca
+  <currentMemory unit='KiB'>219136</currentMemory>
edecca
+  <vcpu placement='static'>1</vcpu>
edecca
+  <os>
edecca
+    <type arch='i686' machine='pc'>hvm</type>
edecca
+  </os>
edecca
+  <clock offset='utc'/>
edecca
+  <on_poweroff>destroy</on_poweroff>
edecca
+  <on_reboot>restart</on_reboot>
edecca
+  <on_crash>destroy</on_crash>
edecca
+  <devices>
edecca
+    <emulator>/usr/bin/qemu-system-i686</emulator>
edecca
+    <disk type='block' device='disk'>
edecca
+      <driver name='qemu' type='raw'/>
edecca
+      <source dev='/dev/HostVG/QEMUGuest1'/>
edecca
+      <target dev='hda' bus='ide'/>
edecca
+      <boot order='2'/>
edecca
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
edecca
+    </disk>
edecca
+    <controller type='usb' index='0'>
edecca
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
edecca
+    </controller>
edecca
+    <controller type='ide' index='0'>
edecca
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
edecca
+    </controller>
edecca
+    <controller type='pci' index='0' model='pci-root'/>
edecca
+    <interface type='hostdev' managed='yes'>
edecca
+      <mac address='00:11:22:33:44:55'/>
edecca
+      <source>
edecca
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
edecca
+      </source>
edecca
+      <boot order='1'/>
edecca
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
edecca
+    </interface>
edecca
+    <input type='mouse' bus='ps2'/>
edecca
+    <input type='keyboard' bus='ps2'/>
edecca
+    <memballoon model='none'/>
edecca
+  </devices>
edecca
+</domain>
edecca
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
edecca
index db088fff6b..dbac863239 100644
edecca
--- a/tests/qemuxml2xmltest.c
edecca
+++ b/tests/qemuxml2xmltest.c
edecca
@@ -454,6 +454,7 @@ mymain(void)
edecca
     DO_TEST("net-virtio-network-portgroup", NONE);
edecca
     DO_TEST("net-virtio-rxtxqueuesize", NONE);
edecca
     DO_TEST("net-hostdev", NONE);
edecca
+    DO_TEST("net-hostdev-bootorder", NONE);
edecca
     DO_TEST("net-hostdev-vfio", NONE);
edecca
     DO_TEST("net-midonet", NONE);
edecca
     DO_TEST("net-openvswitch", NONE);
edecca
-- 
edecca
2.20.1
edecca