]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Pass oldDev to virDomainDefCompatibleDevice on device update
authorJiri Denemark <jdenemar@redhat.com>
Thu, 22 Feb 2018 12:30:27 +0000 (13:30 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Fri, 23 Feb 2018 10:52:44 +0000 (11:52 +0100)
When calling virDomainDefCompatibleDevice to check a new device during
device update, we need to pass the original device which is going to be
updated in addition to the new device. Otherwise, the function can
report false conflicts.

The new argument is currently ignored by virDomainDefCompatibleDevice,
but this will change in the following patch.

https://bugzilla.redhat.com/show_bug.cgi?id=1546971

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/lxc/lxc_driver.c
src/qemu/qemu_driver.c

index f2ddde7a3601a93c0b8a0547209443e49e6053a6..c71c28e8d21daa79181b3a25ac2989310a33f2dc 100644 (file)
@@ -27400,7 +27400,8 @@ virDomainDeviceInfoCheckBootIndex(virDomainDefPtr def ATTRIBUTE_UNUSED,
 
 int
 virDomainDefCompatibleDevice(virDomainDefPtr def,
-                             virDomainDeviceDefPtr dev)
+                             virDomainDeviceDefPtr dev,
+                             virDomainDeviceDefPtr oldDev ATTRIBUTE_UNUSED)
 {
     virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev);
 
index 2350926e5bdc2cb0042080c647f15917ef0399ff..368f16f3fbf9480382f147b3b6c4707a1b92c084 100644 (file)
@@ -3014,7 +3014,8 @@ typedef enum {
 } virDomainDeviceAction;
 
 int virDomainDefCompatibleDevice(virDomainDefPtr def,
-                                 virDomainDeviceDefPtr dev);
+                                 virDomainDeviceDefPtr dev,
+                                 virDomainDeviceDefPtr oldDev);
 
 void virDomainRNGDefFree(virDomainRNGDefPtr def);
 
index 4c6f09a4352fe84638e0c7ce9f7cd0748fdeb50a..fa6fc4643ee2c705e0558def2b71ff4f96fd99d2 100644 (file)
@@ -3578,6 +3578,7 @@ lxcDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
 {
     int ret = -1;
     virDomainNetDefPtr net;
+    virDomainDeviceDef oldDev = { .type = dev->type };
     int idx;
 
     switch (dev->type) {
@@ -3586,8 +3587,11 @@ lxcDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
         if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
             goto cleanup;
 
-        virDomainNetDefFree(vmdef->nets[idx]);
+        oldDev.data.net = vmdef->nets[idx];
+        if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev) < 0)
+            return -1;
 
+        virDomainNetDefFree(vmdef->nets[idx]);
         vmdef->nets[idx] = net;
         dev->data.net = NULL;
         ret = 0;
@@ -4820,7 +4824,7 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
         if (!vmdef)
             goto endjob;
 
-        if (virDomainDefCompatibleDevice(vmdef, dev) < 0)
+        if (virDomainDefCompatibleDevice(vmdef, dev, NULL) < 0)
             goto endjob;
 
         if ((ret = lxcDomainAttachDeviceConfig(vmdef, dev)) < 0)
@@ -4828,7 +4832,7 @@ static int lxcDomainAttachDeviceFlags(virDomainPtr dom,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (virDomainDefCompatibleDevice(vm->def, dev_copy) < 0)
+        if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL) < 0)
             goto endjob;
 
         if ((ret = lxcDomainAttachDeviceLive(dom->conn, driver, vm, dev_copy)) < 0)
@@ -4931,9 +4935,8 @@ static int lxcDomainUpdateDeviceFlags(virDomainPtr dom,
         if (!vmdef)
             goto endjob;
 
-        if (virDomainDefCompatibleDevice(vmdef, dev) < 0)
-            goto endjob;
-
+        /* virDomainDefCompatibleDevice call is delayed until we know the
+         * device we're going to update. */
         if ((ret = lxcDomainUpdateDeviceConfig(vmdef, dev)) < 0)
             goto endjob;
     }
index 14c39b2610dda9a6661730305debeee022647972..313d730c791fe558a90da1e13f023cabc65311ad 100644 (file)
@@ -7844,6 +7844,7 @@ qemuDomainChangeDiskLive(virDomainObjPtr vm,
 {
     virDomainDiskDefPtr disk = dev->data.disk;
     virDomainDiskDefPtr orig_disk = NULL;
+    virDomainDeviceDef oldDev = { .type = dev->type };
     int ret = -1;
 
     if (virDomainDiskTranslateSourcePool(disk) < 0)
@@ -7861,6 +7862,10 @@ qemuDomainChangeDiskLive(virDomainObjPtr vm,
         goto cleanup;
     }
 
+    oldDev.data.disk = orig_disk;
+    if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev) < 0)
+        goto cleanup;
+
     if (!qemuDomainDiskChangeSupported(disk, orig_disk))
         goto cleanup;
 
@@ -7903,19 +7908,36 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
                            bool force)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
+    virDomainDeviceDef oldDev = { .type = dev->type };
     int ret = -1;
+    int idx;
 
     switch ((virDomainDeviceType) dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
         qemuDomainObjCheckDiskTaint(driver, vm, dev->data.disk, NULL);
         ret = qemuDomainChangeDiskLive(vm, dev, driver, force);
         break;
+
     case VIR_DOMAIN_DEVICE_GRAPHICS:
+        if ((idx = qemuDomainFindGraphicsIndex(vm->def, dev->data.graphics) >= 0)) {
+            oldDev.data.graphics = vm->def->graphics[idx];
+            if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev) < 0)
+                return -1;
+        }
+
         ret = qemuDomainChangeGraphics(driver, vm, dev->data.graphics);
         break;
+
     case VIR_DOMAIN_DEVICE_NET:
+        if ((idx = virDomainNetFindIdx(vm->def, dev->data.net)) >= 0) {
+            oldDev.data.net = vm->def->nets[idx];
+            if (virDomainDefCompatibleDevice(vm->def, dev, &oldDev) < 0)
+                return -1;
+        }
+
         ret = qemuDomainChangeNet(driver, vm, dev);
         break;
+
     case VIR_DOMAIN_DEVICE_FS:
     case VIR_DOMAIN_DEVICE_INPUT:
     case VIR_DOMAIN_DEVICE_SOUND:
@@ -8329,6 +8351,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
     virDomainDiskDefPtr newDisk;
     virDomainGraphicsDefPtr newGraphics;
     virDomainNetDefPtr net;
+    virDomainDeviceDef oldDev = { .type = dev->type };
     int pos;
 
     switch ((virDomainDeviceType) dev->type) {
@@ -8340,6 +8363,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
             return -1;
         }
 
+        oldDev.data.disk = vmdef->disks[pos];
+        if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev) < 0)
+            return -1;
+
         virDomainDiskDefFree(vmdef->disks[pos]);
         vmdef->disks[pos] = newDisk;
         dev->data.disk = NULL;
@@ -8355,8 +8382,11 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
             return -1;
         }
 
-        virDomainGraphicsDefFree(vmdef->graphics[pos]);
+        oldDev.data.graphics = vmdef->graphics[pos];
+        if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev) < 0)
+            return -1;
 
+        virDomainGraphicsDefFree(vmdef->graphics[pos]);
         vmdef->graphics[pos] = newGraphics;
         dev->data.graphics = NULL;
         break;
@@ -8366,8 +8396,11 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
         if ((pos = virDomainNetFindIdx(vmdef, net)) < 0)
             return -1;
 
-        virDomainNetDefFree(vmdef->nets[pos]);
+        oldDev.data.net = vmdef->nets[pos];
+        if (virDomainDefCompatibleDevice(vmdef, dev, &oldDev) < 0)
+            return -1;
 
+        virDomainNetDefFree(vmdef->nets[pos]);
         vmdef->nets[pos] = net;
         dev->data.net = NULL;
         break;
@@ -8454,7 +8487,7 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
         if (!vmdef)
             goto cleanup;
 
-        if (virDomainDefCompatibleDevice(vmdef, dev) < 0)
+        if (virDomainDefCompatibleDevice(vmdef, dev, NULL) < 0)
             goto cleanup;
         if ((ret = qemuDomainAttachDeviceConfig(vmdef, dev, caps,
                                                 parse_flags,
@@ -8463,7 +8496,7 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (virDomainDefCompatibleDevice(vm->def, dev_copy) < 0)
+        if (virDomainDefCompatibleDevice(vm->def, dev_copy, NULL) < 0)
             goto cleanup;
 
         if ((ret = qemuDomainAttachDeviceLive(vm, dev_copy, driver)) < 0)
@@ -8603,9 +8636,8 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
         if (!vmdef)
             goto endjob;
 
-        if (virDomainDefCompatibleDevice(vmdef, dev) < 0)
-            goto endjob;
-
+        /* virDomainDefCompatibleDevice call is delayed until we know the
+         * device we're going to update. */
         if ((ret = qemuDomainUpdateDeviceConfig(vmdef, dev, caps,
                                                 parse_flags,
                                                 driver->xmlopt)) < 0)
@@ -8613,9 +8645,8 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (virDomainDefCompatibleDevice(vm->def, dev_copy) < 0)
-            goto endjob;
-
+        /* virDomainDefCompatibleDevice call is delayed until we know the
+         * device we're going to update. */
         if ((ret = qemuDomainUpdateDeviceLive(vm, dev_copy, dom, force)) < 0)
             goto endjob;
         /*