[Libvirt-cim] [PATCH 1/3] libxutil, xmlgen: Add Controller Support

John Ferlan jferlan at redhat.com
Fri Mar 14 12:56:04 UTC 2014


From: Xu Wang <gesaint at linux.vnet.ibm.com>

Add support to define and save a controller found in the XML. A controller
will have an "OTHER" RASD ResourceType value and make use of the CIM
ResourceSubType property as the XML "type" of controller

Signed-off-by: Xu Wang <gesaint at linux.vnet.ibm.com>
Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 libxkutil/device_parsing.c | 105 ++++++++++++++++++++++++++++++++++++++++++++-
 libxkutil/device_parsing.h |  15 +++++++
 libxkutil/xmlgen.c         |  52 ++++++++++++++++++++++
 src/svpc_types.h           |   4 +-
 4 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index c9ae886..f35df39 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -1,5 +1,5 @@
 /*
- * Copyright IBM Corp. 2007, 2013
+ * Copyright IBM Corp. 2007, 2014
  *
  * Authors:
  *  Dan Smith <danms at us.ibm.com>
@@ -49,6 +49,7 @@
 #define GRAPHICS_XPATH  (xmlChar *)"/domain/devices/graphics | "\
         "/domain/devices/console"
 #define INPUT_XPATH     (xmlChar *)"/domain/devices/input"
+#define CONTROLLER_XPATH (xmlChar *)"/domain/devices/controller"
 
 #define DEFAULT_BRIDGE "xenbr0"
 #define DEFAULT_NETWORK "default"
@@ -306,6 +307,20 @@ static void cleanup_input_device(struct input_device *dev)
         free(dev->bus);
 }
 
+static void cleanup_controller_device(struct controller_device *dev)
+{
+        if (dev == NULL)
+                return;
+
+        free(dev->type);
+        free(dev->model);
+        free(dev->queues);
+        free(dev->ports);
+        free(dev->vectors);
+        cleanup_device_address(&dev->address);
+        cleanup_device_address(&dev->master);
+}
+
 void cleanup_virt_device(struct virt_device *dev)
 {
         if (dev == NULL)
@@ -323,6 +338,8 @@ void cleanup_virt_device(struct virt_device *dev)
                 cleanup_input_device(&dev->dev.input);
         else if (dev->type == CIM_RES_TYPE_CONSOLE)
                 cleanup_console_device(&dev->dev.console);
+        else if (dev->type == CIM_RES_TYPE_CONTROLLER)
+                cleanup_controller_device(&dev->dev.controller);
 
         free(dev->id);
 
@@ -1101,6 +1118,71 @@ static int parse_input_device(xmlNode *node, struct virt_device **vdevs)
         return 0;
 }
 
+static int parse_controller_device(xmlNode *cnode, struct virt_device **vdevs)
+{
+        struct virt_device *vdev = NULL;
+        struct controller_device *cdev = NULL;
+        xmlNode *child = NULL;
+        char *index = NULL;
+        int ret;
+
+        vdev = calloc(1, sizeof(*vdev));
+        if (vdev == NULL)
+                goto err;
+
+        cdev = &(vdev->dev.controller);
+
+        cdev->type = get_attr_value(cnode, "type");
+        if (cdev->type == NULL) {
+                CU_DEBUG("No type");
+                goto err;
+        }
+
+        index = get_attr_value(cnode, "index");
+        if (index != NULL) {
+                sscanf(index, "%" PRIu64, &cdev->index);
+                free(index);
+        } else {
+                CU_DEBUG("No index");
+                goto err;
+        }
+
+        cdev->model = get_attr_value(cnode, "model");
+        cdev->ports = get_attr_value(cnode, "ports");
+        cdev->vectors = get_attr_value(cnode, "vectors");
+
+        for (child = cnode->children; child != NULL; child = child->next) {
+                if (XSTREQ(child->name, "address")) {
+                        parse_device_address(child, &cdev->address);
+                } else if (XSTREQ(child->name, "master")) {
+                        /* Although technically not an address it is similar
+                         * insomuch as it's a paired list of attributes that
+                         * we're just going to save and write out later
+                         */
+                        parse_device_address(child, &cdev->master);
+                } else if (XSTREQ(child->name, "driver")) {
+                        cdev->queues = get_attr_value(child, "queues");
+                }
+        }
+        vdev->type = CIM_RES_TYPE_CONTROLLER;
+
+        ret = asprintf(&vdev->id, "controller:%s:%" PRIu64,
+                       cdev->type, cdev->index);
+        if (ret == -1) {
+                CU_DEBUG("Failed to create controller id string");
+                goto err;
+        }
+
+        *vdevs = vdev;
+
+        return 1;
+ err:
+        cleanup_controller_device(cdev);
+        free(vdev);
+
+        return 0;
+}
+
 static bool resize_devlist(struct virt_device **list, int newsize)
 {
         struct virt_device *_list;
@@ -1224,6 +1306,11 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type)
                 func = &parse_input_device;
                 break;
 
+        case CIM_RES_TYPE_CONTROLLER:
+                xpathstr = CONTROLLER_XPATH;
+                func = &parse_controller_device;
+                break;
+
         default:
                 CU_DEBUG("Unrecognized device type. Returning.");
                 goto err1;
@@ -1343,7 +1430,19 @@ struct virt_device *virt_device_dup(struct virt_device *_dev)
         } else if (dev->type == CIM_RES_TYPE_CONSOLE) {
                 console_device_dup(&dev->dev.console,
                                    &_dev->dev.console);
+        } else if (dev->type == CIM_RES_TYPE_CONTROLLER) {
+                DUP_FIELD(dev, _dev, dev.controller.type);
+                dev->dev.controller.index = _dev->dev.controller.index;
+                DUP_FIELD(dev, _dev, dev.controller.model);
+                DUP_FIELD(dev, _dev, dev.controller.ports);
+                DUP_FIELD(dev, _dev, dev.controller.vectors);
+                DUP_FIELD(dev, _dev, dev.controller.queues);
+                duplicate_device_address(&dev->dev.controller.master,
+                                         &_dev->dev.controller.master);
+                duplicate_device_address(&dev->dev.controller.address,
+                                         &_dev->dev.controller.address);
         }
+
         return dev;
 }
 
@@ -1723,6 +1822,9 @@ int get_dominfo_from_xml(const char *xml, struct domain **dominfo)
         (*dominfo)->dev_vcpu_ct = parse_devices(xml,
                                                 &(*dominfo)->dev_vcpu,
                                                 CIM_RES_TYPE_PROC);
+        (*dominfo)->dev_controller_ct = parse_devices(xml,
+                                                      &(*dominfo)->dev_controller,
+                                                      CIM_RES_TYPE_CONTROLLER);
 
         return ret;
 
@@ -1811,6 +1913,7 @@ void cleanup_dominfo(struct domain **dominfo)
         cleanup_virt_devices(&dom->dev_graphics, dom->dev_graphics_ct);
         cleanup_virt_devices(&dom->dev_input, dom->dev_input_ct);
         cleanup_virt_devices(&dom->dev_console, dom->dev_console_ct);
+        cleanup_virt_devices(&dom->dev_controller, dom->dev_controller_ct);
 
         free(dom);
 
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h
index 92427c1..8072f51 100644
--- a/libxkutil/device_parsing.h
+++ b/libxkutil/device_parsing.h
@@ -161,6 +161,17 @@ struct input_device {
         char *bus;
 };
 
+struct controller_device {
+        char *type;
+        uint64_t index;
+        char *model;
+        char *ports;
+        char *vectors;
+        char *queues;
+        struct device_address address;
+        struct device_address master;
+};
+
 struct virt_device {
         uint16_t type;
         union {
@@ -172,6 +183,7 @@ struct virt_device {
                 struct graphics_device graphics;
                 struct console_device console;
                 struct input_device input;
+                struct controller_device controller;
         } dev;
         char *id;
 };
@@ -247,6 +259,9 @@ struct domain {
 
         struct virt_device *dev_vcpu;
         int dev_vcpu_ct;
+
+        struct virt_device *dev_controller;
+        int dev_controller_ct;
 };
 
 struct virt_device *virt_device_dup(struct virt_device *dev);
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
index 931f0c9..6418974 100644
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -794,6 +794,52 @@ static const char *input_xml(xmlNodePtr root, struct domain *dominfo)
         return NULL;
 }
 
+static const char *controller_xml(xmlNodePtr root, struct domain *dominfo)
+{
+        int i;
+
+        for (i = 0; i < dominfo->dev_controller_ct; i++) {
+                xmlNodePtr ctlr;
+                xmlNodePtr tmp;
+                char *index;
+
+                struct virt_device *_dev = &dominfo->dev_controller[i];
+                if (_dev->type == CIM_RES_TYPE_UNKNOWN)
+                        continue;
+
+                struct controller_device *dev = &_dev->dev.controller;
+
+                ctlr = xmlNewChild(root, NULL, BAD_CAST "controller", NULL);
+                if (ctlr == NULL)
+                        return XML_ERROR;
+
+                /* Required */
+                xmlNewProp(ctlr, BAD_CAST "type", BAD_CAST dev->type);
+                if (asprintf(&index, "%" PRIu64, dev->index) == -1)
+                    return XML_ERROR;
+                xmlNewProp(ctlr, BAD_CAST "index", BAD_CAST index);
+                free(index);
+
+                /* Optional */
+                if (dev->model)
+                    xmlNewProp(ctlr, BAD_CAST "model", BAD_CAST dev->model);
+                if (dev->ports)
+                    xmlNewProp(ctlr, BAD_CAST "ports", BAD_CAST dev->ports);
+                if (dev->vectors)
+                    xmlNewProp(ctlr, BAD_CAST "vectors", BAD_CAST dev->vectors);
+                if (dev->queues) {
+                    tmp = xmlNewChild(ctlr, NULL, BAD_CAST "driver", NULL);
+                    xmlNewProp(tmp, BAD_CAST "queueus", BAD_CAST dev->queues);
+                }
+                if (dev->master.ct > 0)
+                    return device_address_xml(ctlr, &dev->master);
+                if (dev->address.ct > 0)
+                    return device_address_xml(ctlr, &dev->address);
+        }
+
+        return NULL;
+}
+
 static char *system_xml(xmlNodePtr root, struct domain *domain)
 {
         xmlNodePtr tmp;
@@ -1125,6 +1171,11 @@ char *device_to_xml(struct virt_device *_dev)
                 dominfo->dev_input_ct = 1;
                 dominfo->dev_input = dev;
                 break;
+        case CIM_RES_TYPE_CONTROLLER:
+                func = controller_xml;
+                dominfo->dev_controller_ct = 1;
+                dominfo->dev_controller = dev;
+                break;
         default:
                 cleanup_virt_devices(&dev, 1);
                 goto out;
@@ -1163,6 +1214,7 @@ char *system_to_xml(struct domain *dominfo)
                 &console_xml,
                 &graphics_xml,
                 &emu_xml,
+                &controller_xml,
                 NULL
         };
 
diff --git a/src/svpc_types.h b/src/svpc_types.h
index 404e428..7a2b653 100644
--- a/src/svpc_types.h
+++ b/src/svpc_types.h
@@ -36,8 +36,9 @@
 #define CIM_RES_TYPE_IMAGE      32768 
 #define CIM_RES_TYPE_CONSOLE    32769
 #define CIM_RES_TYPE_EMU        32770
+#define CIM_RES_TYPE_CONTROLLER 32771
 
-#define CIM_RES_TYPE_COUNT 7
+#define CIM_RES_TYPE_COUNT 8
 const static int cim_res_types[CIM_RES_TYPE_COUNT] = 
   {CIM_RES_TYPE_NET,
    CIM_RES_TYPE_DISK,
@@ -46,6 +47,7 @@ const static int cim_res_types[CIM_RES_TYPE_COUNT] =
    CIM_RES_TYPE_GRAPHICS,
    CIM_RES_TYPE_INPUT,
    CIM_RES_TYPE_CONSOLE,
+   CIM_RES_TYPE_CONTROLLER,
   };
 
 #define CIM_VSSD_RECOVERY_NONE       2
-- 
1.8.5.3




More information about the Libvirt-cim mailing list