render / rpms / libvirt

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