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