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

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