
Signed-off-by: Xu Wang <gesaint@linux.vnet.ibm.com> --- libxkutil/device_parsing.c | 273 +++++++++++++++++++++++++++++++++----------- 1 files changed, 206 insertions(+), 67 deletions(-) diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c index 0323fb5..b8fcc7b 100644 --- a/libxkutil/device_parsing.c +++ b/libxkutil/device_parsing.c @@ -1522,18 +1522,38 @@ static int parse_console_device(xmlNode *node, struct virt_device **vdevs) char *source_type_str = NULL; char *target_port_ID = NULL; char *udp_source_mode = NULL; + int id; - xmlNode *child = NULL; + CU_DEBUG("Enter parse_graphics_device()."); vdev = calloc(1, sizeof(*vdev)); - if (vdev == NULL) + if (vdev == NULL) { + CU_DEBUG("calloc failed."); goto err; + } cdev = &(vdev->dev.console); - source_type_str = get_attr_value(node, "type"); - if (source_type_str == NULL) + cdev->others = parse_data_to_others(cdev->others, + node, + 0, + BAD_CAST "devices"); + if (cdev->others == NULL) { + CU_DEBUG("parse data to others failed."); + goto err; + } + + source_type_str = fetch_from_others(&cdev->others, + -1, + "type", + TYPE_PROP, + -1, + (char *)node->name); + + if (source_type_str == NULL) { + CU_DEBUG("no type"); goto err; + } CU_DEBUG("console device type = %s", source_type_str ? : "NULL"); cdev->source_type = chardev_source_type_StrToID(source_type_str); @@ -1542,85 +1562,204 @@ static int parse_console_device(xmlNode *node, struct virt_device **vdevs) CU_DEBUG("console device type ID = %d", cdev->source_type); - for (child = node->children; child != NULL; child = child->next) { - if (XSTREQ(child->name, "target")) { - cdev->target_type = get_attr_value(child, "type"); - CU_DEBUG("Console device target type = '%s'", - cdev->target_type ? : "NULL"); - target_port_ID = get_attr_value(child, "port"); - if (target_port_ID == NULL) - goto err; - } + if (seek_in_others(&cdev->others, + -1, + "target", + TYPE_NODE, + -1, + (char *)node->name)) { + cdev->target_type = fetch_from_others(&cdev->others, + -1, + "type", + TYPE_PROP, + -1, + "target"); + CU_DEBUG("Console device target type = '%s'", + cdev->target_type ? : "NULL"); - if (XSTREQ(child->name, "source")) { - switch (cdev->source_type) - { - case CIM_CHARDEV_SOURCE_TYPE_PTY: - cdev->source_dev.pty.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_DEV: - cdev->source_dev.dev.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_FILE: - cdev->source_dev.file.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_PIPE: - cdev->source_dev.pipe.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK: - cdev->source_dev.unixsock.mode = - get_attr_value(child, "mode"); - cdev->source_dev.unixsock.path = - get_attr_value(child, "path"); - break; - case CIM_CHARDEV_SOURCE_TYPE_UDP: - udp_source_mode = get_attr_value(child, "mode"); + target_port_ID = fetch_from_others(&cdev->others, + -1, + "port", + TYPE_PROP, + -1, + "target"); + if (target_port_ID == NULL) + goto err; + } + + if (seek_in_others(&cdev->others, + 0, + "source", + TYPE_NODE, + -1, + (char *)node->name)) { + switch (cdev->source_type) + { + case CIM_CHARDEV_SOURCE_TYPE_PTY: + cdev->source_dev.pty.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_DEV: + cdev->source_dev.dev.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_FILE: + cdev->source_dev.file.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_PIPE: + cdev->source_dev.pipe.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK: + cdev->source_dev.unixsock.mode = + fetch_from_others(&cdev->others, + -1, + "mode", + TYPE_PROP, + -1, + "source"); + cdev->source_dev.unixsock.path = + fetch_from_others(&cdev->others, + -1, + "path", + TYPE_PROP, + -1, + "source"); + break; + case CIM_CHARDEV_SOURCE_TYPE_UDP: + /* Something different from other cases. It has two + * <source> tags with mode="bind" and "connect" value. + * Hence here id MUST NOT be ignored. + */ + + /* Just fetch out another <source> tag but we need to do + * nothing with it. + */ + fetch_from_others(&cdev->others, + 1, + "source", + TYPE_NODE, + -1, + "console"); + + for (id = 0; id < 2; id++) { + udp_source_mode = + fetch_from_others(&cdev->others, + -1, + "mode", + TYPE_PROP, + id, + "source"); if (udp_source_mode == NULL) goto err; + if (STREQC(udp_source_mode, "bind")) { cdev->source_dev.udp.bind_host = - get_attr_value(child, "host"); + fetch_from_others(&cdev->others, + -1, + "host", + TYPE_PROP, + id, + "source"); cdev->source_dev.udp.bind_service = - get_attr_value(child, "service"); + fetch_from_others(&cdev->others, + -1, + "service", + TYPE_PROP, + id, + "source"); } else if (STREQC(udp_source_mode, "connect")) { cdev->source_dev.udp.connect_host = - get_attr_value(child, "host"); + fetch_from_others(&cdev->others, + -1, + "host", + TYPE_PROP, + id, + "source"); cdev->source_dev.udp.connect_service = - get_attr_value(child, "service"); + fetch_from_others(&cdev->others, + -1, + "service", + TYPE_PROP, + id, + "source"); } else { CU_DEBUG("unknown udp mode: %s", udp_source_mode ? : "NULL"); goto err; } - break; - case CIM_CHARDEV_SOURCE_TYPE_TCP: - cdev->source_dev.tcp.mode = - get_attr_value(child, "mode"); - cdev->source_dev.tcp.host = - get_attr_value(child, "host"); - cdev->source_dev.tcp.service = - get_attr_value(child, "service"); - break; - - default: - /* Nothing to do for : - CIM_CHARDEV_SOURCE_TYPE_STDIO - CIM_CHARDEV_SOURCE_TYPE_NULL - CIM_CHARDEV_SOURCE_TYPE_VC - CIM_CHARDEV_SOURCE_TYPE_SPICEVMC - */ - break; } + break; + case CIM_CHARDEV_SOURCE_TYPE_TCP: + cdev->source_dev.tcp.mode = + fetch_from_others(&cdev->others, + -1, + "mode", + TYPE_PROP, + -1, + "source"); + cdev->source_dev.tcp.host = + fetch_from_others(&cdev->others, + -1, + "host", + TYPE_PROP, + -1, + "source"); + cdev->source_dev.tcp.service = + fetch_from_others(&cdev->others, + -1, + "service", + TYPE_PROP, + -1, + "source"); + break; + + default: + /* Nothing to do for : + CIM_CHARDEV_SOURCE_TYPE_STDIO + CIM_CHARDEV_SOURCE_TYPE_NULL + CIM_CHARDEV_SOURCE_TYPE_VC + CIM_CHARDEV_SOURCE_TYPE_SPICEVMC + */ + break; } - if ((cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_TCP) - && XSTREQ(child->name, "protocol")) { - cdev->source_dev.tcp.protocol = - get_attr_value(child, "type"); - } + } + + if ((cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_TCP) + && seek_in_others(&cdev->others, + -1, + "protocol", + TYPE_NODE, + -1, + (char *)node->name)) { + cdev->source_dev.tcp.protocol = + fetch_from_others(&cdev->others, + -1, + "type", + TYPE_PROP, + -1, + "protocol"); } vdev->type = CIM_RES_TYPE_CONSOLE; -- 1.7.1