You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
14 KiB
400 lines
14 KiB
From 48b28b6aec23b82c0239aee60af2a470c06dde1a Mon Sep 17 00:00:00 2001 |
|
From: Xu Wang <gesaint@linux.vnet.ibm.com> |
|
Date: Mon, 17 Mar 2014 19:21:23 -0400 |
|
Subject: [PATCH 51/60] Parse/Store controller XML tags |
|
|
|
Parse and store the <controller> XML tags. The generated DeviceID will |
|
be a combination of "controller" + XML device "name" + XML Index "value". |
|
This should be unique enough now and generates "controller:pci:0" or |
|
"controller:usb:0" DeviceID's. |
|
|
|
In the future, if support is added for the "<master>" XML child a new |
|
mechanism will need to be put in place since one of those controllers is |
|
designed to have the same name and index - what changes is the function |
|
for the device. |
|
|
|
Signed-off-by: John Ferlan <jferlan@redhat.com> |
|
--- |
|
libxkutil/device_parsing.c | 119 ++++++++++++++++++++++++++++++++++++++++++++- |
|
libxkutil/xmlgen.c | 74 +++++++++++++++++++++++++++- |
|
2 files changed, 191 insertions(+), 2 deletions(-) |
|
|
|
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c |
|
index d2d3859..f863cc5 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" |
|
@@ -69,6 +70,7 @@ static void cleanup_device_address(struct device_address *addr) |
|
if (addr == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Cleanup %d addresses", addr->ct); |
|
for (i = 0; i < addr->ct; i++) { |
|
free(addr->key[i]); |
|
free(addr->value[i]); |
|
@@ -84,6 +86,7 @@ static void cleanup_disk_device(struct disk_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean Disk type %s", dev->type); |
|
free(dev->type); |
|
free(dev->device); |
|
free(dev->driver); |
|
@@ -103,6 +106,7 @@ static void cleanup_vsi_device(struct vsi_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean VSI type %s", dev->vsi_type); |
|
free(dev->vsi_type); |
|
free(dev->manager_id); |
|
free(dev->type_id); |
|
@@ -117,6 +121,7 @@ static void cleanup_net_device(struct net_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean net type %s", dev->type); |
|
free(dev->type); |
|
free(dev->mac); |
|
free(dev->source); |
|
@@ -134,6 +139,7 @@ static void cleanup_emu_device(struct emu_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean emu %s", dev->path); |
|
free(dev->path); |
|
} |
|
|
|
@@ -157,6 +163,7 @@ static void cleanup_graphics_device(struct graphics_device *dev) |
|
if (dev == NULL || dev->type == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean graphics type %s", dev->type); |
|
if (STREQC(dev->type, "sdl")) |
|
cleanup_sdl_device(dev); |
|
else |
|
@@ -170,6 +177,7 @@ static void cleanup_path_device(struct path_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean path device %s", dev->path); |
|
free(dev->path); |
|
|
|
} |
|
@@ -179,6 +187,7 @@ static void cleanup_unixsock_device(struct unixsock_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean unixsock device"); |
|
free(dev->path); |
|
free(dev->mode); |
|
|
|
@@ -189,6 +198,7 @@ static void cleanup_tcp_device(struct tcp_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean tcp device"); |
|
free(dev->mode); |
|
free(dev->protocol); |
|
free(dev->host); |
|
@@ -201,6 +211,7 @@ static void cleanup_udp_device(struct udp_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean udb bind device"); |
|
free(dev->bind_host); |
|
free(dev->bind_service); |
|
free(dev->connect_host); |
|
@@ -212,6 +223,7 @@ static void cleanup_console_device(struct console_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean console source_type %d", dev->source_type); |
|
switch (dev->source_type) |
|
{ |
|
case CIM_CHARDEV_SOURCE_TYPE_PTY: |
|
@@ -304,10 +316,24 @@ static void cleanup_input_device(struct input_device *dev) |
|
if (dev == NULL) |
|
return; |
|
|
|
+ CU_DEBUG("Clean input device %s", dev->type); |
|
free(dev->type); |
|
free(dev->bus); |
|
} |
|
|
|
+static void cleanup_controller_device(struct controller_device *dev) |
|
+{ |
|
+ if (dev == NULL) |
|
+ return; |
|
+ |
|
+ CU_DEBUG("Clean controller device %d", dev->type); |
|
+ free(dev->model); |
|
+ free(dev->queues); |
|
+ free(dev->ports); |
|
+ free(dev->vectors); |
|
+ cleanup_device_address(&dev->address); |
|
+} |
|
+ |
|
void cleanup_virt_device(struct virt_device *dev) |
|
{ |
|
if (dev == NULL) |
|
@@ -325,6 +351,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); |
|
|
|
@@ -339,6 +367,7 @@ void cleanup_virt_devices(struct virt_device **_devs, int count) |
|
for (i = 0; i < count; i++) |
|
cleanup_virt_device(&devs[i]); |
|
|
|
+ CU_DEBUG("All devices cleaned"); |
|
free(devs); |
|
*_devs = NULL; |
|
} |
|
@@ -1107,6 +1136,75 @@ 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; |
|
+ char *type_str = NULL; |
|
+ xmlNode *child = NULL; |
|
+ char *index = NULL; |
|
+ int ret; |
|
+ |
|
+ vdev = calloc(1, sizeof(*vdev)); |
|
+ if (vdev == NULL) |
|
+ goto err; |
|
+ |
|
+ cdev = &(vdev->dev.controller); |
|
+ |
|
+ type_str = get_attr_value(cnode, "type"); |
|
+ if (type_str == NULL) { |
|
+ CU_DEBUG("No type"); |
|
+ goto err; |
|
+ } |
|
+ CU_DEBUG("controller device type = %s", type_str); |
|
+ cdev->type = controller_protocol_type_StrToID(type_str); |
|
+ if (cdev->type == CIM_CONTROLLER_PROTOCOL_TYPE_UNKNOWN) { |
|
+ CU_DEBUG("Unknown controller protocol type (%d)", cdev->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, "driver")) { |
|
+ cdev->queues = get_attr_value(child, "queues"); |
|
+ } |
|
+ } |
|
+ vdev->type = CIM_RES_TYPE_CONTROLLER; |
|
+ |
|
+ ret = asprintf(&vdev->id, "controller:%s:%" PRIu64, |
|
+ type_str, cdev->index); |
|
+ if (ret == -1) { |
|
+ CU_DEBUG("Failed to create controller id string"); |
|
+ goto err; |
|
+ } |
|
+ CU_DEBUG("Controller id is %s", vdev->id); |
|
+ free(type_str); |
|
+ |
|
+ *vdevs = vdev; |
|
+ |
|
+ return 1; |
|
+ err: |
|
+ free(type_str); |
|
+ cleanup_controller_device(cdev); |
|
+ free(vdev); |
|
+ |
|
+ return 0; |
|
+} |
|
+ |
|
static bool resize_devlist(struct virt_device **list, int newsize) |
|
{ |
|
struct virt_device *_list; |
|
@@ -1230,6 +1328,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; |
|
@@ -1351,7 +1454,17 @@ 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) { |
|
+ dev->dev.controller.type = _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.address, |
|
+ &_dev->dev.controller.address); |
|
} |
|
+ |
|
return dev; |
|
} |
|
|
|
@@ -1731,6 +1844,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; |
|
|
|
@@ -1819,6 +1935,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/xmlgen.c b/libxkutil/xmlgen.c |
|
index 18c4765..3174ca9 100644 |
|
--- a/libxkutil/xmlgen.c |
|
+++ b/libxkutil/xmlgen.c |
|
@@ -1,5 +1,5 @@ |
|
/* |
|
- * Copyright IBM Corp. 2007, 2013 |
|
+ * Copyright IBM Corp. 2007-2014 |
|
* |
|
* Authors: |
|
* Dan Smith <danms@us.ibm.com> |
|
@@ -798,6 +798,72 @@ static const char *input_xml(xmlNodePtr root, struct domain *dominfo) |
|
return NULL; |
|
} |
|
|
|
+static const char *controller_xml(xmlNodePtr root, struct domain *dominfo) |
|
+{ |
|
+ int i; |
|
+ const char *msg = NULL; |
|
+ |
|
+ CU_DEBUG("Found %d controllers", dominfo->dev_controller_ct); |
|
+ for (i = 0; i < dominfo->dev_controller_ct; i++) { |
|
+ xmlNodePtr ctlr; |
|
+ xmlNodePtr tmp; |
|
+ char *type_str; |
|
+ |
|
+ struct virt_device *_dev = &dominfo->dev_controller[i]; |
|
+ if (_dev->type == CIM_RES_TYPE_UNKNOWN) |
|
+ continue; |
|
+ |
|
+ struct controller_device *cdev = &_dev->dev.controller; |
|
+ |
|
+ ctlr = xmlNewChild(root, NULL, BAD_CAST "controller", NULL); |
|
+ if (ctlr == NULL) |
|
+ return XML_ERROR; |
|
+ |
|
+ |
|
+ type_str = controller_protocol_type_IDToStr(cdev->type); |
|
+ if (type_str == NULL) |
|
+ return XML_ERROR; |
|
+ |
|
+ CU_DEBUG("Type=%s Index=%" PRIu64, type_str, cdev->index); |
|
+ xmlNewProp(ctlr, BAD_CAST "type", |
|
+ BAD_CAST type_str); |
|
+ |
|
+ /* If index is missing, let libvirt generate it */ |
|
+ if (cdev->index != CONTROLLER_INDEX_NOT_SET) { |
|
+ char *index; |
|
+ if (asprintf(&index, "%" PRIu64, cdev->index) == -1) |
|
+ return XML_ERROR; |
|
+ xmlNewProp(ctlr, BAD_CAST "index", BAD_CAST index); |
|
+ free(index); |
|
+ } |
|
+ |
|
+ /* Optional */ |
|
+ if (cdev->model) |
|
+ xmlNewProp(ctlr, BAD_CAST "model", |
|
+ BAD_CAST cdev->model); |
|
+ if (cdev->ports) |
|
+ xmlNewProp(ctlr, BAD_CAST "ports", |
|
+ BAD_CAST cdev->ports); |
|
+ if (cdev->vectors) |
|
+ xmlNewProp(ctlr, BAD_CAST "vectors", |
|
+ BAD_CAST cdev->vectors); |
|
+ if (cdev->queues) { |
|
+ tmp = xmlNewChild(ctlr, NULL, BAD_CAST "driver", NULL); |
|
+ xmlNewProp(tmp, BAD_CAST "queueus", |
|
+ BAD_CAST cdev->queues); |
|
+ } |
|
+ if (cdev->address.ct > 0) { |
|
+ msg = device_address_xml(ctlr, &cdev->address); |
|
+ if (msg != NULL) { |
|
+ CU_DEBUG("Failed to set the address"); |
|
+ return msg; |
|
+ } |
|
+ } |
|
+ } |
|
+ |
|
+ return NULL; |
|
+} |
|
+ |
|
static char *system_xml(xmlNodePtr root, struct domain *domain) |
|
{ |
|
xmlNodePtr tmp; |
|
@@ -1129,6 +1195,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; |
|
@@ -1167,6 +1238,7 @@ char *system_to_xml(struct domain *dominfo) |
|
&console_xml, |
|
&graphics_xml, |
|
&emu_xml, |
|
+ &controller_xml, |
|
NULL |
|
}; |
|
|
|
-- |
|
2.1.0
|
|
|