From: Xu Wang <cngesaint(a)gmail.com>
Signed-off-by: Xu Wang <gesaint(a)linux.vnet.ibm.com>
---
libxkutil/device_parsing.c | 273 ++++++++++++++++++++++++++++++++++-----------
libxkutil/device_parsing.h | 1 +
2 files changed, 207 insertions(+), 67 deletions(-)
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index 0a74ff3..8edd2e3 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -287,6 +287,7 @@ static void cleanup_console_device(struct console_device *dev)
dev->source_type = 0;
free(dev->target_type);
memset(&dev->source_dev, 0, sizeof(dev->source_dev));
+ cleanup_others(dev->others);
};
static void console_device_dup(struct console_device *t,
@@ -1648,18 +1649,37 @@ 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_console_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);
@@ -1668,85 +1688,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;
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h
index 0855166..24b7c1d 100644
--- a/libxkutil/device_parsing.h
+++ b/libxkutil/device_parsing.h
@@ -180,6 +180,7 @@ struct console_device {
struct udp_device udp;
} source_dev;
char *target_type;
+ struct others *others;
};
struct input_device {
--
1.8.3.1