[Libvirt-cim] [PATCH V2 11/48] Fix xml parsing algorithm for parse_console_device()

Xu Wang cngesaint at gmail.com
Mon Oct 28 02:45:40 UTC 2013


Signed-off-by: Xu Wang <gesaint at 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




More information about the Libvirt-cim mailing list