[Libvirt-cim] [PATCH] (#2) Override devices in reference configuration, where the ID is the same

Dan Smith danms at us.ibm.com
Mon Aug 18 18:39:31 UTC 2008


# HG changeset patch
# User Dan Smith <danms at us.ibm.com>
# Date 1219084718 25200
# Node ID 80e6ea1a1a296d424e15b3771d6753c3f8bbc5d1
# Parent  f40ac4d174324f9ee4c76a4a8832704d3439e7dd
(#2) Override devices in reference configuration, where the ID is the same

Currently, we depend on libvirt to return an error if the client's
combination of ReferenceConfig and ResourceSettings results in a duplicate
device.  That error is non-obvious in origin.  Since two devices that would
result in the same InstanceID cannot be properly represented by the providers
anyway, this patch adds some logic to properly override such a conflicting
device.

To do this, I had to make sure we set the ID in rasd_to_vdev, which wasn't
previously required.  The actual insertion of the device into the appropriate
type list is done by a helper function which checks for (and overrides if
appropriate) a duplicate before tacking the new instance on the end of the
list.

Changes:
We were already making the required space for the additional devices,
but I didn't correctly specify the new size then calling add_device_nodup()
function, resulting in a false failure.

Side note: the classify_resources() function is really getting out of hand
and could use some refactoring.

Signed-off-by: Dan Smith <danms at us.ibm.com>

diff -r f40ac4d17432 -r 80e6ea1a1a29 src/Virt_VirtualSystemManagementService.c
--- a/src/Virt_VirtualSystemManagementService.c	Fri Aug 15 09:30:30 2008 -0700
+++ b/src/Virt_VirtualSystemManagementService.c	Mon Aug 18 11:38:38 2008 -0700
@@ -411,6 +411,9 @@
         free(dev->dev.net.mac);
         dev->dev.net.mac = strdup(val);
 
+        free(dev->id);
+        dev->id = strdup(dev->dev.net.mac);
+
         op = CMGetObjectPath(inst, NULL);
         if (op == NULL) {
                 CU_DEBUG("Unable to get instance path");
@@ -449,6 +452,9 @@
         dev->dev.disk.source = strdup(val);
         dev->dev.disk.disk_type = disk_type_from_file(val);
 
+        free(dev->id);
+        dev->id = strdup(dev->dev.disk.virtual_dev);
+
         return NULL;
 }
 
@@ -469,6 +475,9 @@
         free(dev->dev.disk.source);
         dev->dev.disk.source = strdup(val);
         dev->dev.disk.disk_type = DISK_FS;
+
+        free(dev->id);
+        dev->id = strdup(dev->dev.disk.virtual_dev);
 
         return NULL;
 }
@@ -621,6 +630,33 @@
         return true;
 }
 
+static char *add_device_nodup(struct virt_device *dev,
+                              struct virt_device *list,
+                              int max,
+                              int *index)
+{
+        int i;
+
+        for (i = 0; i < *index; i++) {
+                struct virt_device *ptr = &list[i];
+
+                if (STREQC(ptr->id, dev->id)) {
+                        CU_DEBUG("Overriding device %s from refconf", ptr->id);
+                        cleanup_virt_device(ptr);
+                        memcpy(ptr, dev, sizeof(*ptr));
+                        return NULL;
+                }
+        }
+
+        if (*index == max)
+                return "Internal error: no more device slots";
+
+        memcpy(&list[*index], dev, sizeof(list[*index]));
+        *index += 1;
+
+        return NULL;
+}
+
 static const char *classify_resources(CMPIArray *resources,
                                       const char *ns,
                                       struct domain *domain)
@@ -678,15 +714,33 @@
                                            &domain->dev_mem[0],
                                            ns);
                 } else if (type == CIM_RES_TYPE_DISK) {
+                        struct virt_device dev;
+                        int dcount = count + domain->dev_disk_ct;
+
+                        memset(&dev, 0, sizeof(dev));
                         msg = rasd_to_vdev(inst,
                                            domain,
-                                           &domain->dev_disk[domain->dev_disk_ct++],
+                                           &dev,
                                            ns);
+                        if (msg == NULL)
+                                msg = add_device_nodup(&dev,
+                                                       domain->dev_disk,
+                                                       dcount,
+                                                       &domain->dev_disk_ct);
                 } else if (type == CIM_RES_TYPE_NET) {
+                        struct virt_device dev;
+                        int ncount = count + domain->dev_net_ct;
+
+                        memset(&dev, 0, sizeof(dev));
                         msg = rasd_to_vdev(inst,
                                            domain,
-                                           &domain->dev_net[domain->dev_net_ct++],
+                                           &dev,
                                            ns);
+                        if (msg == NULL)
+                                msg = add_device_nodup(&dev,
+                                                       domain->dev_net,
+                                                       ncount,
+                                                       &domain->dev_net_ct);
                 }
                 if (msg != NULL)
                         return msg;




More information about the Libvirt-cim mailing list