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