
On 03/14/2014 08:56 AM, John Ferlan wrote:
From: Xu Wang <gesaint@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@linux.vnet.ibm.com> Signed-off-by: John Ferlan <jferlan@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@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