[PATCH 01/12] conf: Introduce helper to find duplicate device address

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When adding devices to the definition it's useful to check whether the
devices don't reside on a conflicting address. This patch adds a helper
that iterates all device info and comapres the addresses with the given
info.
---
 src/conf/domain_conf.c   | 98 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |  4 ++
 src/libvirt_private.syms |  1 +
 3 files changed, 103 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4251b13..94289cf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2715,6 +2715,90 @@ virDomainDeviceInfoNeedsFormat(virDomainDeviceInfoPtr info, unsigned int flags)
     return false;
 }

+static bool
+virDomainDeviceInfoAddressIsEqual(const virDomainDeviceInfo *a,
+                                  const virDomainDeviceInfo *b)
+{
+
+    if (a->type != b->type)
+        return false;
+
+    switch ((virDomainDeviceAddressType) a->type) {
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
+    /* address types below don't have any specific data */
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
+        /* the 'multi' field shouldn't be checked */
+        if (a->addr.pci.domain != b->addr.pci.domain ||
+            a->addr.pci.bus != b->addr.pci.bus ||
+            a->addr.pci.slot != b->addr.pci.slot ||
+            a->addr.pci.function != b->addr.pci.function)
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
+        if (memcmp(&a->addr.drive, &b->addr.drive, sizeof(a->addr.drive)))
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL:
+        if (memcmp(&a->addr.vioserial, &b->addr.vioserial, sizeof(a->addr.vioserial)))
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
+        if (memcmp(&a->addr.ccid, &b->addr.ccid, sizeof(a->addr.ccid)))
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB:
+        if (memcmp(&a->addr.usb, &b->addr.usb, sizeof(a->addr.usb)))
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
+        if (memcmp(&a->addr.spaprvio, &b->addr.spaprvio, sizeof(a->addr.spaprvio)))
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
+        /* the 'assigned' field denotes that the address was generated */
+        if (a->addr.ccw.cssid != b->addr.ccw.cssid ||
+            a->addr.ccw.ssid != b->addr.ccw.ssid ||
+            a->addr.ccw.devno != b->addr.ccw.devno)
+            return false;
+        break;
+
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
+        if (memcmp(&a->addr.isa, &b->addr.isa, sizeof(a->addr.isa)))
+            return false;
+        break;
+    }
+
+    return true;
+}
+
+
+static int
+virDomainDeviceInfoFindByAddressIterator(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                         virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                                         virDomainDeviceInfoPtr info,
+                                         void *opaque)
+{
+    virDomainDeviceInfoPtr needle = opaque;
+
+    /* break iteration if the info was found */
+    if (virDomainDeviceInfoAddressIsEqual(info, needle))
+        return -1;
+
+    return 0;
+}
+
+
 int
 virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst,
                         virDomainDeviceInfoPtr src)
@@ -2967,6 +3051,20 @@ virDomainDeviceInfoIterate(virDomainDefPtr def,
 }


+bool
+virDomainDeviceInfoHasAddress(virDomainDefPtr def,
+                              virDomainDeviceInfoPtr info)
+{
+    if (virDomainDeviceInfoIterateInternal(def,
+                                           virDomainDeviceInfoFindByAddressIterator,
+                                           true,
+                                           info) < 0)
+        return true;
+
+    return false;
+}
+
+
 static int
 virDomainDefRejectDuplicateControllers(virDomainDefPtr def)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 93f2314..d073a99 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2382,6 +2382,10 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
                                virDomainDeviceInfoCallback cb,
                                void *opaque);

+bool virDomainDeviceInfoHasAddress(virDomainDefPtr def,
+                                   virDomainDeviceInfoPtr info)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+
 void virDomainDefFree(virDomainDefPtr vm);

 virDomainChrDefPtr virDomainChrDefNew(void);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 376c69b..619bf79 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -215,6 +215,7 @@ virDomainDeviceDefParse;
 virDomainDeviceFindControllerModel;
 virDomainDeviceGetInfo;
 virDomainDeviceInfoCopy;
+virDomainDeviceInfoHasAddress;
 virDomainDeviceInfoIterate;
 virDomainDeviceTypeToString;
 virDomainDiskBusTypeToString;
-- 
2.2.2

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]