
From: Xu Wang <cngesaint@gmail.com> Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 301 +++++++++++++++++++++++++++++++-------------- libxkutil/device_parsing.h | 1 + 2 files changed, 211 insertions(+), 91 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 940b105..8b39cda 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -148,6 +148,7 @@ static void cleanup_net_device(struct net_device *dev) free(dev->poolid); cleanup_vsi_device(&dev->vsi); cleanup_device_address(&dev->address); + cleanup_others(dev->others); } static void cleanup_emu_device(struct emu_device *dev) @@ -429,30 +430,6 @@ int add_device_address_property(struct device_address *devaddr, return 0; } - -static int parse_device_address(xmlNode *anode, struct device_address *devaddr) -{ - xmlAttr *attr = NULL; - char *name = NULL; - char *value = NULL; - - for (attr = anode->properties; attr != NULL; attr = attr->next) { - name = (char*) attr->name; - value = get_attr_value(anode, name); - if (!add_device_address_property(devaddr, name, value)) - goto err; - free(value); - } - - return 1; - - err: - cleanup_device_address(devaddr); - free(value); - - return 0; -} - /* * Device addresses can have many forms based on the 'type' field, so rather * than try to create a function that could parse each particular option, we @@ -1222,92 +1199,234 @@ static int parse_net_device(xmlNode *inode, struct virt_device **vdevs) { struct virt_device *vdev = NULL; struct net_device *ndev = NULL; - xmlNode *child = NULL; + + CU_DEBUG("Enter parse_net_device()."); vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } ndev = &(vdev->dev.net); - ndev->type = get_attr_value(inode, "type"); - if (ndev->type == NULL) + ndev->others = parse_data_to_others(ndev->others, + inode, + 0, + BAD_CAST "devices"); + if (ndev->others == NULL) { + CU_DEBUG("parse xml data to others failed."); goto err; + } + + /* fetch out <interface> tag from others. It will be removed + * after others management finished. */ + fetch_from_others(&ndev->others, + -1, + "interface", + TYPE_NODE, + -1, + "devices"); + + ndev->type = fetch_from_others(&ndev->others, + -1, + "type", + TYPE_PROP, + -1, + (char *)inode->name); + + if (ndev->type == NULL) { + CU_DEBUG("no type"); + goto err; + } + + if (seek_in_others(&ndev->others, + -1, + "mac", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->mac = fetch_from_others(&ndev->others, + -1, + "address", + TYPE_PROP, + -1, + "mac"); + + if (ndev->mac == NULL) { + CU_DEBUG("no mac address"); + goto err; + } + } + + if (seek_in_others(&ndev->others, + -1, + "source", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->source = fetch_from_others(&ndev->others, + -1, + "bridge", + TYPE_PROP, + -1, + "source"); + + if (ndev->source == NULL) { + ndev->source = fetch_from_others(&ndev->others, + -1, + "network", + TYPE_PROP, + -1, + "source"); - for (child = inode->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "mac")) { - ndev->mac = get_attr_value(child, "address"); - if (ndev->mac == NULL) - goto err; - } else if (XSTREQ(child->name, "source")) { - ndev->source = get_attr_value(child, "bridge"); - if (ndev->source != NULL) - continue; - ndev->source = get_attr_value(child, "network"); if (ndev->source != NULL) { - int ret = asprintf(&ndev->poolid, + int ret = asprintf(&ndev->poolid, "NetworkPool/%s", ndev->source); + if (ret == -1) { - CU_DEBUG("Failed to get network" - " poolid"); + CU_DEBUG("Failed to get network poolid"); + goto err; } - continue; + } else { + ndev->source = fetch_from_others(&ndev->others, + -1, + "dev", + TYPE_PROP, + -1, + "source"); + + ndev->net_mode = fetch_from_others(&ndev->others, + -1, + "mode", + TYPE_PROP, + -1, + "source"); + + if ((ndev->source == NULL) || (ndev->net_mode == NULL)) { + CU_DEBUG("source %s, mode %s", ndev->source, ndev->net_mode); + goto err; + } + } - ndev->source = get_attr_value(child, "dev"); - ndev->net_mode = get_attr_value(child, "mode"); - if ((ndev->source != NULL) && (ndev->net_mode != NULL)) - continue; + } + } + + if (seek_in_others(&ndev->others, + -1, + "target", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->device = fetch_from_others(&ndev->others, + -1, + "dev", + TYPE_PROP, + -1, + "target"); + + if (ndev->device == NULL) { + CU_DEBUG("no dev in target."); goto err; - } else if (XSTREQ(child->name, "target")) { - ndev->device = get_attr_value(child, "dev"); - if (ndev->device == NULL) - goto err; - } else if (XSTREQ(child->name, "model")) { - ndev->model = get_attr_value(child, "type"); - if (ndev->model == NULL) - goto err; - } else if (XSTREQ(child->name, "filterref")) { - ndev->filter_ref = get_attr_value(child, "filter"); - } else if (XSTREQ(child->name, "virtualport")) { - parse_vsi_device(child, ndev); - } else if (XSTREQ(child->name, "address")) { - parse_device_address(child, &ndev->address); + } + } + + if (seek_in_others(&ndev->others, + -1, + "model", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->model = fetch_from_others(&ndev->others, + -1, + "type", + TYPE_PROP, + -1, + "model"); + if (ndev->model == NULL) { + CU_DEBUG("no model type."); + goto err; + } + } + + if (seek_in_others(&ndev->others, + -1, + "filterref", + TYPE_NODE, + -1, + (char *)inode->name)) { + ndev->filter_ref = fetch_from_others(&ndev->others, + -1, + "filter", + TYPE_PROP, + -1, + "filterref"); + } + + if (seek_in_others(&ndev->others, -1, "virtualport", + TYPE_NODE, -1, (char *)inode->name)) { + parse_vsi_device(&ndev->others, ndev); + } + + if (seek_in_others(&ndev->others, + -1, + "address", + TYPE_NODE, + -1, + (char *)inode->name)) { + if (!fetch_device_address_from_others(&ndev->others, + &ndev->address)) { + CU_DEBUG("error fetching device address"); + goto err; + } + } + #if LIBVIR_VERSION_NUMBER >= 9000 - } else if (XSTREQ(child->name, "bandwidth")) { - /* Network QoS bandwidth support */ - xmlNode *grandchild = NULL; - for (grandchild = child->children; - grandchild != NULL; - grandchild = grandchild->next) { - if (XSTREQ(grandchild->name, "inbound")) { - /* Only expose inbound bandwidth */ - char *val; - - val = get_attr_value(grandchild, - "average"); - if (val != NULL) { - sscanf(val, "%" PRIu64, - &ndev->reservation); - free(val); - } else - ndev->reservation = 0; - - val = get_attr_value(grandchild, - "peak"); - if (val != NULL) { - sscanf(val, "%" PRIu64, - &ndev->limit); - free(val); - } else - ndev->limit = 0; - break; - } - } + /* Network QoS bandwidth support */ + /* Only expose inbound bandwidth */ + char *val; + if (seek_in_others(&ndev->others, + -1, + "bandwidth", + TYPE_NODE, + -1, + (char *)inode->name) && + seek_in_others(&ndev->others, + -1, + "inbound", + TYPE_NODE, + -1, + "bandwidth")) { + val = fetch_from_others(&ndev->others, + -1, + "average", + TYPE_PROP, + -1, + "inbound"); + + if (val != NULL) { + sscanf(val, "%" PRIu64, &ndev->reservation); + free(val); + } else { + ndev->reservation = 0; } -#endif + val = fetch_from_others(&ndev->others, + -1, + "peak", + TYPE_PROP, + -1, + "inbound"); + + if (val != NULL) { + sscanf(val, "%" PRIu64, &ndev->limit); + free(val); + } else { + ndev->limit = 0; + } } +#endif if (ndev->source == NULL) CU_DEBUG("No network source defined, leaving blank\n"); diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h index 6e8fe25..4d26fc8 100644 --- a/libxkutil/device_parsing.h +++ b/libxkutil/device_parsing.h @@ -100,6 +100,7 @@ struct net_device { uint64_t limit; struct vsi_device vsi; struct device_address address; + struct others *others; }; struct mem_device { -- 1.8.3.1