Blame SOURCES/libvirt-cim-0.6.3-4f74864c.patch

c55d09
From 4f74864c72ffbb05c8b02ab9d12c581e22da359f Mon Sep 17 00:00:00 2001
c55d09
From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
c55d09
Date: Mon, 14 Oct 2013 17:29:41 +0200
c55d09
Subject: [PATCH 26/60] libxkutil: Support for device addresses
c55d09
c55d09
New data type for device addresses based on the generic
c55d09
"address" element of the libvirt domain XML.
c55d09
Contains XML parsing and generation code for device addresses.
c55d09
c55d09
Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
c55d09
Signed-off-by: John Ferlan <jferlan@redhat.com>
c55d09
---
c55d09
 libxkutil/device_parsing.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
c55d09
 libxkutil/device_parsing.h |  11 +++++
c55d09
 libxkutil/xmlgen.c         |  28 +++++++++++
c55d09
 3 files changed, 152 insertions(+)
c55d09
c55d09
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
c55d09
index aecca4c..97419d2 100644
c55d09
--- a/libxkutil/device_parsing.c
c55d09
+++ b/libxkutil/device_parsing.c
c55d09
@@ -63,6 +63,22 @@
c55d09
 /* Device parse function */
c55d09
 typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **);
c55d09
 
c55d09
+static void cleanup_device_address(struct device_address *addr)
c55d09
+{
c55d09
+        int i;
c55d09
+        if (addr == NULL)
c55d09
+                return;
c55d09
+
c55d09
+        for (i = 0; i < addr->ct; i++) {
c55d09
+                free(addr->key[i]);
c55d09
+                free(addr->value[i]);
c55d09
+        }
c55d09
+
c55d09
+        free(addr->key);
c55d09
+        free(addr->value);
c55d09
+        addr->ct = 0;
c55d09
+}
c55d09
+
c55d09
 static void cleanup_disk_device(struct disk_device *dev)
c55d09
 {
c55d09
         if (dev == NULL)
c55d09
@@ -77,6 +93,7 @@ static void cleanup_disk_device(struct disk_device *dev)
c55d09
         free(dev->virtual_dev);
c55d09
         free(dev->bus_type);
c55d09
         free(dev->access_mode);
c55d09
+        cleanup_device_address(&dev->address);
c55d09
 }
c55d09
 
c55d09
 static void cleanup_vsi_device(struct vsi_device *dev)
c55d09
@@ -107,6 +124,7 @@ static void cleanup_net_device(struct net_device *dev)
c55d09
         free(dev->filter_ref);
c55d09
         free(dev->poolid);
c55d09
         cleanup_vsi_device(&dev->vsi);
c55d09
+        cleanup_device_address(&dev->address);
c55d09
 }
c55d09
 
c55d09
 static void cleanup_emu_device(struct emu_device *dev)
c55d09
@@ -351,6 +369,67 @@ char *get_node_content(xmlNode *node)
c55d09
         return buf;
c55d09
 }
c55d09
 
c55d09
+int add_device_address_property(struct device_address *devaddr,
c55d09
+                                const char *key,
c55d09
+                                const char *value)
c55d09
+{
c55d09
+        char *k = NULL;
c55d09
+        char *v = NULL;
c55d09
+        char **list = NULL;
c55d09
+
c55d09
+        if (key != NULL && value != NULL) {
c55d09
+                k = strdup(key);
c55d09
+                v = strdup(value);
c55d09
+                if (k == NULL || v == NULL)
c55d09
+                        goto err;
c55d09
+
c55d09
+                list = realloc(devaddr->key, sizeof(char*) * (devaddr->ct+1));
c55d09
+                if (list == NULL)
c55d09
+                        goto err;
c55d09
+                devaddr->key = list;
c55d09
+
c55d09
+                list = realloc(devaddr->value, sizeof(char*) * (devaddr->ct+1));
c55d09
+                if (list == NULL)
c55d09
+                        goto err;
c55d09
+                devaddr->value = list;
c55d09
+
c55d09
+                devaddr->key[devaddr->ct] = k;
c55d09
+                devaddr->value[devaddr->ct] = v;
c55d09
+                devaddr->ct += 1;
c55d09
+                return 1;
c55d09
+        }
c55d09
+
c55d09
+ err:
c55d09
+        free(k);
c55d09
+        free(v);
c55d09
+        free(list);
c55d09
+        return 0;
c55d09
+}
c55d09
+
c55d09
+
c55d09
+static int parse_device_address(xmlNode *anode, struct device_address *devaddr)
c55d09
+{
c55d09
+        xmlAttr *attr = NULL;
c55d09
+        char *name = NULL;
c55d09
+        char *value = NULL;
c55d09
+
c55d09
+        for (attr = anode->properties; attr != NULL; attr = attr->next) {
c55d09
+                name = (char*) attr->name;
c55d09
+                value = get_attr_value(anode, name);
c55d09
+                if (!add_device_address_property(devaddr, name, value))
c55d09
+                        goto err;
c55d09
+                free(value);
c55d09
+        }
c55d09
+
c55d09
+        return 1;
c55d09
+
c55d09
+ err:
c55d09
+        cleanup_device_address(devaddr);
c55d09
+        free(value);
c55d09
+
c55d09
+        return 0;
c55d09
+}
c55d09
+
c55d09
 static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs)
c55d09
 {
c55d09
         struct virt_device *vdev = NULL;
c55d09
@@ -386,6 +465,8 @@ static int parse_fs_device(xmlNode *dnode, struct virt_device **vdevs)
c55d09
                         }
c55d09
                 } else if (XSTREQ(child->name, "driver")) {
c55d09
                        ddev->driver_type = get_attr_value(child, "type");
c55d09
+                } else if (XSTREQ(child->name, "address")) {
c55d09
+                        parse_device_address(child, &ddev->address);
c55d09
                 }
c55d09
         }
c55d09
 
c55d09
@@ -459,6 +540,8 @@ static int parse_block_device(xmlNode *dnode, struct virt_device **vdevs)
c55d09
                         ddev->readonly = true;
c55d09
                 } else if (XSTREQ(child->name, "shareable")) {
c55d09
                         ddev->shareable = true;
c55d09
+                } else if (XSTREQ(child->name, "address")) {
c55d09
+                        parse_device_address(child, &ddev->address);
c55d09
                 }
c55d09
         }
c55d09
 
c55d09
@@ -598,6 +681,8 @@ static int parse_net_device(xmlNode *inode, struct virt_device **vdevs)
c55d09
                         ndev->filter_ref = get_attr_value(child, "filter");
c55d09
                 } else if (XSTREQ(child->name, "virtualport")) {
c55d09
                         parse_vsi_device(child, ndev);
c55d09
+                } else if (XSTREQ(child->name, "address")) {
c55d09
+                        parse_device_address(child, &ndev->address);
c55d09
 #if LIBVIR_VERSION_NUMBER >= 9000
c55d09
                 } else if (XSTREQ(child->name, "bandwidth")) {
c55d09
                         /* Network QoS bandwidth support */
c55d09
@@ -1167,6 +1252,32 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type)
c55d09
         return count;
c55d09
 }
c55d09
 
c55d09
+static void duplicate_device_address(struct device_address *to, const struct device_address *from)
c55d09
+{
c55d09
+        int i;
c55d09
+
c55d09
+        if (from == NULL || to == NULL || from->ct == 0)
c55d09
+                return;
c55d09
+
c55d09
+        to->ct = from->ct;
c55d09
+        to->key = calloc(from->ct, sizeof(char*));
c55d09
+        to->value = calloc(from->ct, sizeof(char*));
c55d09
+        if (to->key == NULL || to->value == NULL)
c55d09
+                goto err;
c55d09
+
c55d09
+        for (i = 0; i < from->ct; i++) {
c55d09
+                to->key[i] = strdup(from->key[i]);
c55d09
+                to->value[i] = strdup(from->value[i]);
c55d09
+                if (to->key[i] == NULL || to->value[i] == NULL)
c55d09
+                        goto err;
c55d09
+        }
c55d09
+
c55d09
+        return;
c55d09
+
c55d09
+ err:
c55d09
+        cleanup_device_address(to);
c55d09
+}
c55d09
+
c55d09
 struct virt_device *virt_device_dup(struct virt_device *_dev)
c55d09
 {
c55d09
         struct virt_device *dev;
c55d09
@@ -1196,6 +1307,7 @@ struct virt_device *virt_device_dup(struct virt_device *_dev)
c55d09
                 DUP_FIELD(dev, _dev, dev.net.vsi.profile_id);
c55d09
                 dev->dev.net.reservation = _dev->dev.net.reservation;
c55d09
                 dev->dev.net.limit = _dev->dev.net.limit;
c55d09
+                duplicate_device_address(&dev->dev.net.address, &_dev->dev.net.address);
c55d09
         } else if (dev->type == CIM_RES_TYPE_DISK) {
c55d09
                 DUP_FIELD(dev, _dev, dev.disk.type);
c55d09
                 DUP_FIELD(dev, _dev, dev.disk.device);
c55d09
@@ -1209,6 +1321,7 @@ struct virt_device *virt_device_dup(struct virt_device *_dev)
c55d09
                 dev->dev.disk.disk_type = _dev->dev.disk.disk_type;
c55d09
                 dev->dev.disk.readonly = _dev->dev.disk.readonly;
c55d09
                 dev->dev.disk.shareable = _dev->dev.disk.shareable;
c55d09
+                duplicate_device_address(&dev->dev.disk.address, &_dev->dev.disk.address);
c55d09
         } else if (dev->type == CIM_RES_TYPE_MEM) {
c55d09
                 dev->dev.mem.size = _dev->dev.mem.size;
c55d09
                 dev->dev.mem.maxsize = _dev->dev.mem.maxsize;
c55d09
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h
c55d09
index 2803d6a..531703d 100644
c55d09
--- a/libxkutil/device_parsing.h
c55d09
+++ b/libxkutil/device_parsing.h
c55d09
@@ -33,6 +33,12 @@
c55d09
 
c55d09
 #include "../src/svpc_types.h"
c55d09
 
c55d09
+struct device_address {
c55d09
+        uint32_t ct;
c55d09
+        char **key;
c55d09
+        char **value;
c55d09
+};
c55d09
+
c55d09
 struct vsi_device {
c55d09
         char *vsi_type;
c55d09
         char *manager_id;
c55d09
@@ -56,6 +62,7 @@ struct disk_device {
c55d09
         char *bus_type;
c55d09
         char *cache;
c55d09
         char *access_mode; /* access modes for DISK_FS (filesystem) type */
c55d09
+        struct device_address address;
c55d09
 };
c55d09
 
c55d09
 struct net_device {
c55d09
@@ -70,6 +77,7 @@ struct net_device {
c55d09
         uint64_t reservation;
c55d09
         uint64_t limit;
c55d09
         struct vsi_device vsi;
c55d09
+        struct device_address address;
c55d09
 };
c55d09
 
c55d09
 struct mem_device {
c55d09
@@ -257,6 +265,9 @@ int get_devices(virDomainPtr dom, struct virt_device **list, int type,
c55d09
 void cleanup_virt_device(struct virt_device *dev);
c55d09
 void cleanup_virt_devices(struct virt_device **devs, int count);
c55d09
 
c55d09
+int add_device_address_property(struct device_address *devaddr,
c55d09
+                                const char *key, const char *value);
c55d09
+
c55d09
 char *get_node_content(xmlNode *node);
c55d09
 char *get_attr_value(xmlNode *node, char *attrname);
c55d09
 
c55d09
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
c55d09
index 7e8801d..40e2905 100644
c55d09
--- a/libxkutil/xmlgen.c
c55d09
+++ b/libxkutil/xmlgen.c
c55d09
@@ -178,6 +178,26 @@ static const char *console_xml(xmlNodePtr root, struct domain *dominfo)
c55d09
                                    BAD_CAST cdev->target_type);
c55d09
                 }
c55d09
         }
c55d09
+
c55d09
+        return NULL;
c55d09
+}
c55d09
+
c55d09
+static char *device_address_xml(xmlNodePtr root, struct device_address *addr)
c55d09
+{
c55d09
+        int i;
c55d09
+        xmlNodePtr address;
c55d09
+
c55d09
+        if (addr == NULL || addr->ct == 0)
c55d09
+                return NULL;
c55d09
+
c55d09
+        address = xmlNewChild(root, NULL, BAD_CAST "address", NULL);
c55d09
+        if (address == NULL)
c55d09
+                return XML_ERROR;
c55d09
+
c55d09
+        for (i = 0; i < addr->ct; i++) {
c55d09
+                xmlNewProp(address, BAD_CAST addr->key[i] , BAD_CAST addr->value[i]);
c55d09
+        }
c55d09
+
c55d09
         return NULL;
c55d09
 }
c55d09
 
c55d09
@@ -225,6 +245,9 @@ static char *disk_block_xml(xmlNodePtr root, struct disk_device *dev)
c55d09
         if (dev->shareable)
c55d09
                 xmlNewChild(disk, NULL, BAD_CAST "shareable", NULL);
c55d09
 
c55d09
+        if (dev->address.ct > 0)
c55d09
+                return device_address_xml(disk, &dev->address);
c55d09
+
c55d09
         return NULL;
c55d09
 }
c55d09
 
c55d09
@@ -279,6 +302,8 @@ static const char *disk_file_xml(xmlNodePtr root, struct disk_device *dev)
c55d09
         if (dev->shareable)
c55d09
                 xmlNewChild(disk, NULL, BAD_CAST "shareable", NULL);
c55d09
 
c55d09
+        if (dev->address.ct > 0)
c55d09
+                return device_address_xml(disk, &dev->address);
c55d09
 
c55d09
         return NULL;
c55d09
 }
c55d09
@@ -520,6 +545,9 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo)
c55d09
                 }
c55d09
 #endif
c55d09
 
c55d09
+                if (dev->dev.net.address.ct > 0)
c55d09
+                        msg = device_address_xml(nic, &dev->dev.net.address);
c55d09
+
c55d09
                 if (STREQ(dev->dev.net.type, "network")) {
c55d09
                         msg = set_net_source(nic, net, "network");
c55d09
                 } else if (STREQ(dev->dev.net.type, "bridge")) {
c55d09
-- 
c55d09
2.1.0
c55d09