Signed-off-by: Shi Lei <shi_...@massclouds.com>
---
 src/conf/domain_conf.c | 207 ++++++++++++++++++++++++-----------------
 1 file changed, 121 insertions(+), 86 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0802c45..d1602ab 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14119,55 +14119,19 @@ virDomainTimerDefParseXML(xmlNodePtr node,
 }
 
 
-/**
- * virDomainGraphicsListenDefParseXML:
- * @def: listen def pointer to be filled
- * @graphics: graphics def pointer
- * @node: xml node of <listen/> element
- * @parent: xml node of <graphics/> element
- * @flags: bit-wise or of VIR_DOMAIN_DEF_PARSE_*
- *
- * Parses current <listen/> element from @node to @def.  For backward
- * compatibility the @parent element should contain node of <graphics/> element
- * for the first <listen/> element in order to validate attributes from both
- * elements.
- */
 static int
-virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
-                                   virDomainGraphicsDefPtr graphics,
-                                   xmlNodePtr node,
-                                   xmlNodePtr parent,
-                                   unsigned int flags)
+virDomainGraphicsListenDefParseXMLHook(xmlNodePtr node G_GNUC_UNUSED,
+                                       virDomainGraphicsListenDefPtr def,
+                                       const char *instname G_GNUC_UNUSED,
+                                       void *parent,
+                                       void *opaque,
+                                       const char *type G_GNUC_UNUSED,
+                                       const char *fromConfig,
+                                       const char *autoGenerated)
 {
-    int ret = -1;
+    unsigned int flags = *((unsigned int *) opaque);
+    virDomainGraphicsDefPtr graphics = (virDomainGraphicsDefPtr) parent;
     const char *graphicsType = virDomainGraphicsTypeToString(graphics->type);
-    int tmp, typeVal;
-    g_autofree char *type = virXMLPropString(node, "type");
-    g_autofree char *address = virXMLPropString(node, "address");
-    g_autofree char *network = virXMLPropString(node, "network");
-    g_autofree char *socketPath = virXMLPropString(node, "socket");
-    g_autofree char *fromConfig = virXMLPropString(node, "fromConfig");
-    g_autofree char *autoGenerated = virXMLPropString(node, "autoGenerated");
-    g_autofree char *addressCompat = NULL;
-    g_autofree char *socketCompat = NULL;
-
-    if (parent) {
-        addressCompat = virXMLPropString(parent, "listen");
-        socketCompat = virXMLPropString(parent, "socket");
-    }
-
-    if (!type) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("graphics listen type must be specified"));
-        goto error;
-    }
-
-    if ((typeVal = virDomainGraphicsListenTypeFromString(type)) < 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("unknown graphics listen type '%s'"), type);
-        goto error;
-    }
-    def->type = typeVal;
 
     switch (def->type) {
     case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
@@ -14194,61 +14158,94 @@ 
virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
         break;
     }
 
-    if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) {
-        if (address && addressCompat && STRNEQ(address, addressCompat)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("graphics 'listen' attribute '%s' must match "
-                             "'address' attribute of first listen element "
-                             "(found '%s')"), addressCompat, address);
-            goto error;
-        }
-
-        if (!address)
-            address = g_steal_pointer(&addressCompat);
-    }
-
-    if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
-        if (socketPath && socketCompat && STRNEQ(socketPath, socketCompat)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("graphics 'socket' attribute '%s' must match "
-                             "'socket' attribute of first listen element "
-                             "(found '%s')"), socketCompat, socketPath);
+    if (def->address && def->address[0]) {
+        if (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS &&
+            (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK ||
+             (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)))
             goto error;
-        }
-
-        if (!socketPath)
-            socketPath = g_steal_pointer(&socketCompat);
-    }
-
-    if (address && address[0] &&
-        (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS ||
-         (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK &&
-          !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)))) {
-        def->address = g_steal_pointer(&address);
     }
 
-    if (network && network[0]) {
+    if (def->network && def->network[0]) {
         if (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) {
             virReportError(VIR_ERR_XML_ERROR, "%s",
                            _("'network' attribute is valid only for listen "
                              "type 'network'"));
             goto error;
         }
-        def->network = g_steal_pointer(&network);
     }
 
-    if (socketPath && socketPath[0]) {
+    if (def->socket && def->socket[0]) {
         if (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
             virReportError(VIR_ERR_XML_ERROR, "%s",
                            _("'socket' attribute is valid only for listen "
                              "type 'socket'"));
             goto error;
         }
-        def->socket = g_steal_pointer(&socketPath);
     }
 
-    if (fromConfig &&
-        flags & VIR_DOMAIN_DEF_PARSE_STATUS) {
+    if (fromConfig && !(flags & VIR_DOMAIN_DEF_PARSE_STATUS))
+        def->fromConfig = 0;
+
+    if (autoGenerated && !(flags & VIR_DOMAIN_DEF_PARSE_STATUS))
+        def->autoGenerated = false;
+
+    return 0;
+
+ error:
+    return -1;
+}
+
+
+/**
+ * virDomainGraphicsListenDefParseXML:
+ * @def: listen def pointer to be filled
+ * @graphics: graphics def pointer
+ * @node: xml node of <listen/> element
+ * @flags: bit-wise or of VIR_DOMAIN_DEF_PARSE_*
+ *
+ * Parses current <listen/> element from @node to @def.  For backward
+ * compatibility the @parent element should contain node of <graphics/> element
+ * for the first <listen/> element in order to validate attributes from both
+ * elements.
+ */
+static int
+virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
+                                   virDomainGraphicsDefPtr graphics,
+                                   xmlNodePtr node,
+                                   unsigned int flags)
+{
+    int ret = -1;
+    int tmp, typeVal;
+    g_autofree char *type = virXMLPropString(node, "type");
+    g_autofree char *address = virXMLPropString(node, "address");
+    g_autofree char *network = virXMLPropString(node, "network");
+    g_autofree char *socketPath = virXMLPropString(node, "socket");
+    g_autofree char *fromConfig = virXMLPropString(node, "fromConfig");
+    g_autofree char *autoGenerated = virXMLPropString(node, "autoGenerated");
+
+    if (!type) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("graphics listen type must be specified"));
+        goto error;
+    }
+
+    if ((typeVal = virDomainGraphicsListenTypeFromString(type)) < 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown graphics listen type '%s'"), type);
+        goto error;
+    }
+    def->type = typeVal;
+
+    if (address && address[0])
+        def->address = g_steal_pointer(&address);
+
+    if (network && network[0])
+        def->network = g_steal_pointer(&network);
+
+    if (socketPath && socketPath[0])
+        def->socket = g_steal_pointer(&socketPath);
+
+    if (fromConfig) {
         if (virStrToLong_i(fromConfig, NULL, 10, &tmp) < 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("Invalid fromConfig value: %s"),
@@ -14258,8 +14255,7 @@ 
virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
         def->fromConfig = tmp != 0;
     }
 
-    if (autoGenerated &&
-        flags & VIR_DOMAIN_DEF_PARSE_STATUS) {
+    if (autoGenerated) {
         if (virStringParseYesNo(autoGenerated, &def->autoGenerated) < 0) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("Invalid autoGenerated value: %s"),
@@ -14268,6 +14264,11 @@ 
virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
         }
     }
 
+    if (virDomainGraphicsListenDefParseXMLHook(node, def, NULL,
+                                               graphics, &flags, type,
+                                               fromConfig, autoGenerated) < 0)
+        goto error;
+
     ret = 0;
  error:
     if (ret < 0)
@@ -14303,12 +14304,46 @@ 
virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
             goto cleanup;
 
         for (i = 0; i < nListens; i++) {
-            if (virDomainGraphicsListenDefParseXML(&def->listens[i], def,
+            virDomainGraphicsListenDefPtr listen = &def->listens[i];
+            if (virDomainGraphicsListenDefParseXML(listen, def,
                                                    listenNodes[i],
-                                                   i == 0 ? node : NULL,
                                                    flags) < 0)
                 goto cleanup;
 
+            if (i == 0) {
+                g_autofree char *addressCompat = NULL;
+                g_autofree char *socketCompat = NULL;
+
+                addressCompat = virXMLPropString(node, "listen");
+                socketCompat = virXMLPropString(node, "socket");
+
+                if (listen->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) {
+                    if (listen->address && addressCompat && 
STRNEQ(listen->address, addressCompat)) {
+                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                       _("graphics 'listen' attribute '%s' 
must match "
+                                         "'address' attribute of first listen 
element "
+                                         "(found '%s')"), addressCompat, 
listen->address);
+                        goto cleanup;
+                    }
+
+                    if (!listen->address)
+                        listen->address = g_steal_pointer(&addressCompat);
+                }
+
+                if (listen->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
+                    if (listen->socket && socketCompat && 
STRNEQ(listen->socket, socketCompat)) {
+                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                       _("graphics 'socket' attribute '%s' 
must match "
+                                         "'socket' attribute of first listen 
element "
+                                         "(found '%s')"), socketCompat, 
listen->socket);
+                        goto cleanup;
+                    }
+
+                    if (!listen->socket)
+                        listen->socket = g_steal_pointer(&socketCompat);
+                }
+            }
+
             def->nListens++;
         }
     }
-- 
2.25.1


Reply via email to