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

John Ferlan jferlan at redhat.com
Fri Mar 14 15:20:50 UTC 2014



On 03/14/2014 08:56 AM, John Ferlan wrote:
> 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;
> +

I really would like some guidance in this area to in order to understand
what other kinds of changes are going to be necessary considering this
particular "break;" causes quite a few cimtest failures. It's as if
there needs to be some other place that has to know about the controller
device.

Perhaps in CIM parlance - some Association that's missing.

John


>          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
> 




More information about the Libvirt-cim mailing list