147b37
From b3bd3f499bcf2fa9b2d61b5291e0a50bc7e8e595 Mon Sep 17 00:00:00 2001
147b37
Message-Id: <b3bd3f499bcf2fa9b2d61b5291e0a50bc7e8e595@dist-git>
147b37
From: Jiri Denemark <jdenemar@redhat.com>
147b37
Date: Thu, 22 Feb 2018 13:51:36 +0100
147b37
Subject: [PATCH] qemu: Fix updating device with boot order
147b37
MIME-Version: 1.0
147b37
Content-Type: text/plain; charset=UTF-8
147b37
Content-Transfer-Encoding: 8bit
147b37
147b37
Commit v3.7.0-14-gc57f3fd2f8 prevented adding a <boot order='x'/>
147b37
element to an inactive domain with global <boot dev='...'/> element.
147b37
However, as a result of that change updating any device with boot order
147b37
would fail with 'boot order X is already used by another device', where
147b37
"another device" is in fact the device which is being updated.
147b37
147b37
To fix this we have to ignore the device which we're about to update
147b37
when checking for boot order conflicts.
147b37
147b37
https://bugzilla.redhat.com/show_bug.cgi?id=1546971
147b37
147b37
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
147b37
(cherry picked from commit edae027cfe02be4863dcef1e7f0ea0564766e312)
147b37
147b37
https://bugzilla.redhat.com/show_bug.cgi?id=1557922
147b37
147b37
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
147b37
Reviewed-by: Ján Tomko <jtomko@redhat.com>
147b37
---
147b37
 src/conf/domain_conf.c | 29 ++++++++++++++++++++++-------
147b37
 1 file changed, 22 insertions(+), 7 deletions(-)
147b37
147b37
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
147b37
index e9bba70057..f21c776ccd 100644
147b37
--- a/src/conf/domain_conf.c
147b37
+++ b/src/conf/domain_conf.c
147b37
@@ -27166,18 +27166,30 @@ virDomainDeviceIsUSB(virDomainDeviceDefPtr dev)
147b37
     return false;
147b37
 }
147b37
 
147b37
+
147b37
+typedef struct _virDomainCompatibleDeviceData virDomainCompatibleDeviceData;
147b37
+typedef virDomainCompatibleDeviceData *virDomainCompatibleDeviceDataPtr;
147b37
+struct _virDomainCompatibleDeviceData {
147b37
+    virDomainDeviceInfoPtr newInfo;
147b37
+    virDomainDeviceInfoPtr oldInfo;
147b37
+};
147b37
+
147b37
 static int
147b37
 virDomainDeviceInfoCheckBootIndex(virDomainDefPtr def ATTRIBUTE_UNUSED,
147b37
                                   virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
147b37
                                   virDomainDeviceInfoPtr info,
147b37
                                   void *opaque)
147b37
 {
147b37
-    virDomainDeviceInfoPtr newinfo = opaque;
147b37
+    virDomainCompatibleDeviceDataPtr data = opaque;
147b37
 
147b37
-    if (info->bootIndex == newinfo->bootIndex) {
147b37
+    /* Ignore the device we're about to update */
147b37
+    if (data->oldInfo == info)
147b37
+        return 0;
147b37
+
147b37
+    if (info->bootIndex == data->newInfo->bootIndex) {
147b37
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
147b37
                        _("boot order %u is already used by another device"),
147b37
-                       newinfo->bootIndex);
147b37
+                       data->newInfo->bootIndex);
147b37
         return -1;
147b37
     }
147b37
     return 0;
147b37
@@ -27186,9 +27198,12 @@ virDomainDeviceInfoCheckBootIndex(virDomainDefPtr def ATTRIBUTE_UNUSED,
147b37
 int
147b37
 virDomainDefCompatibleDevice(virDomainDefPtr def,
147b37
                              virDomainDeviceDefPtr dev,
147b37
-                             virDomainDeviceDefPtr oldDev ATTRIBUTE_UNUSED)
147b37
+                             virDomainDeviceDefPtr oldDev)
147b37
 {
147b37
-    virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev);
147b37
+    virDomainCompatibleDeviceData data = {
147b37
+        .newInfo = virDomainDeviceGetInfo(dev),
147b37
+        .oldInfo = virDomainDeviceGetInfo(oldDev),
147b37
+    };
147b37
 
147b37
     if (!virDomainDefHasUSB(def) &&
147b37
         def->os.type != VIR_DOMAIN_OSTYPE_EXE &&
147b37
@@ -27199,7 +27214,7 @@ virDomainDefCompatibleDevice(virDomainDefPtr def,
147b37
         return -1;
147b37
     }
147b37
 
147b37
-    if (info && info->bootIndex > 0) {
147b37
+    if (data.newInfo && data.newInfo->bootIndex > 0) {
147b37
         if (def->os.nBootDevs > 0) {
147b37
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
147b37
                            _("per-device boot elements cannot be used"
147b37
@@ -27208,7 +27223,7 @@ virDomainDefCompatibleDevice(virDomainDefPtr def,
147b37
         }
147b37
         if (virDomainDeviceInfoIterate(def,
147b37
                                        virDomainDeviceInfoCheckBootIndex,
147b37
-                                       info) < 0)
147b37
+                                       &data) < 0)
147b37
             return -1;
147b37
     }
147b37
 
147b37
-- 
147b37
2.17.0
147b37