[libvirt] [PATCH 14/17] vnc: use listen type=socket instead of socket attribute

Pavel Hrdina phrdina at redhat.com
Thu May 5 16:20:33 UTC 2016


Introduce a new listen type that will be used to tell a graphics device
to listen on unix socket and use it for VNC graphics instead of socket
attribute.  The socket attribute will remain in the XML for backward
compatibility.

Since old libvirt supports 'socket' attribute inside 'graphics' element
for socket path provided by user libvirt will generate migratable XML
without that listen type='socket' but only with 'socket' attribute in
order to be able to migrate back to old libvirt.

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 docs/formatdomain.html.in                          |  16 +++
 docs/schemas/domaincommon.rng                      |  10 ++
 src/conf/domain_conf.c                             | 119 ++++++++++++++++-----
 src/conf/domain_conf.h                             |   8 +-
 src/libvirt_private.syms                           |   1 +
 src/qemu/qemu_command.c                            |  27 +++--
 src/qemu/qemu_domain.c                             |  19 ++--
 src/qemu/qemu_hotplug.c                            |   9 ++
 src/qemu/qemu_parse_command.c                      |   2 +-
 src/qemu/qemu_process.c                            |  33 ++++--
 src/security/virt-aa-helper.c                      |  15 ++-
 .../generic-graphics-vnc-socket-listen.xml         |   4 +-
 .../generic-graphics-vnc-socket.xml                |   4 +-
 .../qemuargv2xml-graphics-vnc-socket.xml           |   4 +-
 ...qemuxml2argv-graphics-vnc-auto-unix-socket.args |  20 ++++
 .../qemuxml2argv-graphics-vnc-auto-unix-socket.xml |  30 ++++++
 .../qemuxml2argv-graphics-vnc-unix-socket.args     |  20 ++++
 .../qemuxml2argv-graphics-vnc-unix-socket.xml      |  30 ++++++
 tests/qemuxml2argvtest.c                           |   2 +
 ...emuxml2xmlout-graphics-vnc-auto-unix-socket.xml |  35 ++++++
 .../qemuxml2xmlout-graphics-vnc-unix-socket.xml    |  35 ++++++
 tests/qemuxml2xmltest.c                            |   2 +
 22 files changed, 387 insertions(+), 58 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-unix-socket.xml
 create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-unix-socket.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0d22922..c5cf107 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5347,6 +5347,22 @@ qemu-kvm -net nic,model=? /dev/null
           <code>address</code>.
         </p>
       </dd>
+      <dt><code>socket</code> <span class="since">since 1.3.5</span></dt>
+      <dd>
+        <p>
+          This listen type tells a graphics server to listen on unix socket.
+          Attribute <code>socket</code> contains a path to unix socket. If this
+          attribute is omitted libvirt will generate this path for you.
+          Supported by graphics type <code>vnc</code>.
+        </p>
+        <p>
+          For <code>vnc</code> graphics be backward compatible
+          the <code>socket</code> attribute of first <code>listen</code> element
+          is duplicated as <code>socket</code> attribute in <code>graphics</code>
+          element. If <code>graphics</code> element contains a <code>socket</code>
+          attribute all <code>listen</code> elements are ignored.
+        </p>
+      </dd>
     </dl>
 
     <h4><a name="elementsVideo">Video devices</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index e7eda77..e3dbcc6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3014,6 +3014,16 @@
               </attribute>
             </optional>
           </group>
+          <group>
+            <attribute name="type">
+              <value>socket</value>
+            </attribute>
+            <optional>
+              <attribute name="socket">
+                <ref name="absFilePath"/>
+              </attribute>
+            </optional>
+          </group>
         </choice>
       </element>
     </zeroOrMore>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2168bac..5075fb5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -561,7 +561,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST,
 VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST,
               "none",
               "address",
-              "network")
+              "network",
+              "socket")
 
 VIR_ENUM_IMPL(virDomainGraphicsAuthConnected,
               VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST,
@@ -1229,6 +1230,7 @@ virDomainGraphicsListenDefClear(virDomainGraphicsListenDefPtr def)
 
     VIR_FREE(def->address);
     VIR_FREE(def->network);
+    VIR_FREE(def->socket);
     return;
 }
 
@@ -1242,7 +1244,6 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
 
     switch ((virDomainGraphicsType)def->type) {
     case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
-        VIR_FREE(def->data.vnc.socket);
         VIR_FREE(def->data.vnc.keymap);
         virDomainGraphicsAuthDefClear(&def->data.vnc.auth);
         break;
@@ -10786,8 +10787,10 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
     char *type = virXMLPropString(node, "type");
     char *address = virXMLPropString(node, "address");
     char *network = virXMLPropString(node, "network");
+    char *socket = virXMLPropString(node, "socket");
     char *fromConfig = virXMLPropString(node, "fromConfig");
     char *addressCompat = NULL;
+    const char *graphicsType = virDomainGraphicsTypeToString(graphics->type);
     int tmp;
 
     if (parent)
@@ -10805,6 +10808,14 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
         goto error;
     }
 
+    if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
+        graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("listen type 'socket' is not available for "
+                         "graphics type '%s'"), graphicsType);
+        goto error;
+    }
+
     if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) {
         if (address && addressCompat && STRNEQ(address, addressCompat)) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -10839,6 +10850,17 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
         network = NULL;
     }
 
+    if (socket && 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 = socket;
+        socket = NULL;
+    }
+
     if (fromConfig &&
         flags & VIR_DOMAIN_DEF_PARSE_STATUS) {
         if (virStrToLong_i(fromConfig, NULL, 10, &tmp) < 0) {
@@ -10882,18 +10904,15 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
 
     ctxt->node = node;
 
-    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
-        (socketPath = virXMLPropString(node, "socket"))) {
-        ret = 0;
-        goto error;
-    }
+    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC)
+        socketPath = virXMLPropString(node, "socket");
 
     /* parse the <listen> subelements for graphics types that support it */
     nListens = virXPathNodeSet("./listen", ctxt, &listenNodes);
     if (nListens < 0)
         goto error;
 
-    if (nListens > 0) {
+    if (nListens > 0 && !socketPath) {
         size_t i;
 
         if (VIR_ALLOC_N(def->listens, nListens) < 0)
@@ -10913,14 +10932,20 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
     } else {
         /* If not <listen/> element was found in XML for backward compatibility
          * we should try to parse 'listen' attribute from <graphics/> element. */
-        newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
-        newListen.address = virXMLPropString(node, "listen");
-        if (STREQ_NULLABLE(newListen.address, ""))
-            VIR_FREE(newListen.address);
+        if (socketPath) {
+            newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
+            newListen.socket = socketPath;
+            socketPath = NULL;
+        } else {
+            newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
+            newListen.address = virXMLPropString(node, "listen");
+            if (STREQ_NULLABLE(newListen.address, ""))
+                VIR_FREE(newListen.address);
 
-        if (virDomainGraphicsListenDefParsePorts(&newListen, node, def,
-                                                 NULL, flags) < 0)
-            goto error;
+            if (virDomainGraphicsListenDefParsePorts(&newListen, node, def,
+                                                     NULL, flags) < 0)
+                goto error;
+        }
 
         if (VIR_APPEND_ELEMENT(def->listens, def->nListens, newListen) < 0)
             goto error;
@@ -10963,7 +10988,6 @@ virDomainGraphicsDefParseXMLVNC(virDomainGraphicsDefPtr def,
         }
     }
 
-    def->data.vnc.socket = virXMLPropString(node, "socket");
     def->data.vnc.keymap = virXMLPropString(node, "keymap");
 
     if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth,
@@ -21438,6 +21462,13 @@ virDomainGraphicsListenDefFormat(virBufferPtr buf,
         }
     }
 
+    if (def->socket &&
+        def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
+        !(def->autogenerated &&
+          (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) {
+        virBufferEscapeString(buf, " socket='%s'", def->socket);
+    }
+
     if (flags & VIR_DOMAIN_DEF_FORMAT_STATUS)
         virBufferAsprintf(buf, " fromConfig='%d'", def->fromConfig);
 
@@ -21467,11 +21498,17 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
 
     switch (def->type) {
     case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
-        if (def->data.vnc.socket) {
-            if (!def->data.vnc.socketAutogenerated ||
-                !(flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE)) {
-                virBufferEscapeString(buf, " socket='%s'",
-                                      def->data.vnc.socket);
+        if (!glisten) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("missing listen element for graphics"));
+            return -1;
+        }
+
+        if (glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
+            if (glisten->socket &&
+                !(glisten->autogenerated &&
+                  (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) {
+                virBufferEscapeString(buf, " socket='%s'", glisten->socket);
             }
         } else if (glisten) {
             if (glisten->port &&
@@ -21579,9 +21616,19 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
     for (i = 0; i < def->nListens; i++) {
         if (def->listens[i].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE)
             continue;
-        if (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE &&
-            def->listens[i].fromConfig)
-            continue;
+        if (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE) {
+            if (def->listens[i].fromConfig)
+                continue;
+
+            /* If the socket is provided by user in the XML we need to skip this
+             * listen type to support migration back to old libvirt since old
+             * libvirt supports specifying socket path inside graphics element
+             * as 'socket' attribute. */
+            if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+                def->listens[i].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
+                !def->listens[i].autogenerated)
+                continue;
+        }
         if (!children) {
             virBufferAddLit(buf, ">\n");
             virBufferAdjustIndent(buf, 2);
@@ -23904,6 +23951,30 @@ virDomainGraphicsListenAppendAddress(virDomainGraphicsDefPtr def,
 }
 
 
+int
+virDomainGraphicsListenAppendSocket(virDomainGraphicsDefPtr def,
+                                    const char *socket)
+{
+    virDomainGraphicsListenDef listen;
+
+    memset(&listen, 0, sizeof(listen));
+
+    listen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
+
+    if (VIR_STRDUP(listen.socket, socket) < 0)
+        goto error;
+
+    if (VIR_APPEND_ELEMENT_COPY(def->listens, def->nListens, listen) < 0)
+        goto error;
+
+    return 0;
+
+ error:
+    VIR_FREE(listen.socket);
+    return -1;
+}
+
+
 /**
  * virDomainNetFind:
  * @def: domain's def
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0895136..6def5be 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1539,6 +1539,7 @@ typedef enum {
     VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 0,
     VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS,
     VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK,
+    VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET,
 
     VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST
 } virDomainGraphicsListenType;
@@ -1555,6 +1556,7 @@ struct _virDomainGraphicsListenDef {
     virDomainGraphicsListenType type;
     char *address;
     char *network;
+    char *socket;
     bool fromConfig;    /* true if the @address is config file originated */
     int port;
     int tlsPort;
@@ -1562,6 +1564,7 @@ struct _virDomainGraphicsListenDef {
     bool autoport;
     bool portReserved;
     bool tlsPortReserved;
+    bool autogenerated;
 };
 
 struct _virDomainGraphicsDef {
@@ -1574,8 +1577,6 @@ struct _virDomainGraphicsDef {
     union {
         struct {
             char *keymap;
-            char *socket;
-            bool socketAutogenerated;
             virDomainGraphicsAuthDef auth;
             int sharePolicy;
         } vnc;
@@ -2840,6 +2841,9 @@ int virDomainGraphicsListenAppendAddress(virDomainGraphicsDefPtr def,
                                          const int websocket,
                                          const bool autoport)
             ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenAppendSocket(virDomainGraphicsDefPtr def,
+                                        const char *socket)
+            ATTRIBUTE_NONNULL(1);
 
 int virDomainNetGetActualType(virDomainNetDefPtr iface);
 const char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c445d9f..d38e98e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -305,6 +305,7 @@ virDomainGraphicsAuthConnectedTypeToString;
 virDomainGraphicsDefFree;
 virDomainGraphicsGetListen;
 virDomainGraphicsListenAppendAddress;
+virDomainGraphicsListenAppendSocket;
 virDomainGraphicsSpiceChannelModeTypeFromString;
 virDomainGraphicsSpiceChannelModeTypeToString;
 virDomainGraphicsSpiceChannelNameTypeFromString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 67f781e..842679f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7333,15 +7333,19 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
         goto error;
     }
 
-    if (graphics->data.vnc.socket) {
-        virBufferAsprintf(&opt, "unix:%s", graphics->data.vnc.socket);
-    } else {
-        if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("missing listen element"));
-            goto error;
-        }
+    if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("missing listen element"));
+        goto error;
+    }
+
+    switch (glisten->type) {
+    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
+        virBufferAsprintf(&opt, "unix:%s", glisten->socket);
+        break;
 
+    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
+    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
         if (!glisten->autoport &&
             (glisten->port < 5900 ||
              glisten->port > 65535)) {
@@ -7377,6 +7381,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
             break;
 
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
             break;
         }
@@ -7402,6 +7407,11 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
             }
             virBufferAsprintf(&opt, ",websocket=%d", glisten->websocket);
         }
+        break;
+
+    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
+        break;
     }
 
     if (graphics->data.vnc.sharePolicy) {
@@ -7538,6 +7548,7 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
             break;
 
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
             break;
         }
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 173f82c..8f4c664 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1945,17 +1945,22 @@ qemuDomainRecheckInternalPaths(virDomainDefPtr def,
                                unsigned int flags)
 {
     size_t i = 0;
+    size_t j = 0;
 
     for (i = 0; i < def->ngraphics; ++i) {
         virDomainGraphicsDefPtr graphics = def->graphics[i];
 
-        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
-            graphics->data.vnc.socket &&
-            STRPREFIX(graphics->data.vnc.socket, cfg->libDir)) {
-            if (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)
-                VIR_FREE(graphics->data.vnc.socket);
-            else
-                graphics->data.vnc.socketAutogenerated = true;
+        for (j = 0; j < graphics->nListens; ++j) {
+            virDomainGraphicsListenDefPtr glisten =  &graphics->listens[j];
+
+            if (glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
+                glisten->socket &&
+                STRPREFIX(glisten->socket, cfg->libDir)) {
+                if (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)
+                    VIR_FREE(glisten->socket);
+                else
+                    glisten->autogenerated = true;
+            }
         }
     }
 }
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1fb08c0..5670c20 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2674,6 +2674,15 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
             }
             break;
 
+        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
+            if (STRNEQ_NULLABLE(newlisten->socket, oldlisten->socket)) {
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                               _("cannot change listen socket setting "
+                                 "on '%s' graphics"), type);
+                goto cleanup;
+            }
+            break;
+
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
             /* nada */
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index 429cc45..a3c73e1 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -509,7 +509,7 @@ qemuParseCommandLineVnc(virDomainDefPtr def,
 
     if (STRPREFIX(val, "unix:")) {
         /* -vnc unix:/some/big/path */
-        if (VIR_STRDUP(vnc->data.vnc.socket, val + 5) < 0)
+        if (virDomainGraphicsListenAppendSocket(vnc, val + 5) < 0)
             goto cleanup;
     } else {
         /*
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8f0cc9e..968e74c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3864,9 +3864,6 @@ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
     unsigned short port;
     size_t i;
 
-    if (graphics->data.vnc.socket)
-        return 0;
-
     for (i = 0; i < graphics->nListens; i++) {
         virDomainGraphicsListenDefPtr glisten = &graphics->listens[i];
 
@@ -3892,6 +3889,7 @@ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
             break;
 
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
             break;
         }
@@ -3990,6 +3988,7 @@ qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
             break;
 
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
             break;
         }
@@ -5210,6 +5209,7 @@ qemuProcessPrepareDomain(virConnectPtr conn,
     for (i = 0; i < vm->def->ngraphics; i++) {
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
         char *listenAddr = NULL;
+        const char *type = virDomainGraphicsTypeToString(graphics->type);
         size_t j;
 
         switch (graphics->type) {
@@ -5222,12 +5222,26 @@ qemuProcessPrepareDomain(virConnectPtr conn,
             for (j = 0; j < graphics->nListens; j++) {
                 virDomainGraphicsListenDefPtr glisten = &graphics->listens[j];
 
-                if (glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS &&
-                    !glisten->address) {
-                    if (VIR_STRDUP(glisten->address, listenAddr) < 0)
-                        goto cleanup;
-
-                    glisten->fromConfig = true;
+                switch (glisten->type) {
+                case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
+                    if (!glisten->address) {
+                        if (VIR_STRDUP(glisten->address, listenAddr) < 0)
+                            goto cleanup;
+                        glisten->fromConfig = true;
+                    }
+                    break;
+                case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
+                    if (!glisten->socket) {
+                        if (virAsprintf(&glisten->socket, "%s/%s.sock",
+                                        priv->libDir, type) < 0)
+                            goto cleanup;
+                        glisten->autogenerated = true;
+                    }
+                    break;
+                case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+                case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
+                case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
+                    break;
                 }
             }
             break;
@@ -6246,6 +6260,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
                 break;
 
             case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
             case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
                 break;
             }
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 7eeb4ef..b144250 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1060,10 +1060,17 @@ get_files(vahControl * ctl)
             goto cleanup;
 
     for (i = 0; i < ctl->def->ngraphics; i++) {
-        if (ctl->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
-            ctl->def->graphics[i]->data.vnc.socket &&
-            vah_add_file(&buf, ctl->def->graphics[i]->data.vnc.socket, "w"))
-            goto cleanup;
+        virDomainGraphicsDefPtr graphics = ctl->def->graphics[i];
+        size_t n;
+
+        for (n = 0; n < graphics->nListens; n++) {
+            virDomainGraphicsListenDef listenObj = graphics->listens[n];
+
+            if (listenObj.type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
+                listenObj.socket &&
+                vah_add_file(&buf, listenObj.socket, "rw"))
+                goto cleanup;
+        }
     }
 
     if (ctl->def->ngraphics == 1 &&
diff --git a/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-listen.xml b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-listen.xml
index d8742c6..cb4e5ac 100644
--- a/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-listen.xml
+++ b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-listen.xml
@@ -19,7 +19,9 @@
     <controller type='pci' index='0' model='pci-root'/>
     <input type='mouse' bus='ps2'/>
     <input type='keyboard' bus='ps2'/>
-    <graphics type='vnc' socket='/tmp/QEMUGuest1-vnc.sock'/>
+    <graphics type='vnc' socket='/tmp/QEMUGuest1-vnc.sock'>
+      <listen type='socket' socket='/tmp/QEMUGuest1-vnc.sock'/>
+    </graphics>
     <video>
       <model type='cirrus' vram='16384' heads='1' primary='yes'/>
     </video>
diff --git a/tests/genericxml2xmloutdata/generic-graphics-vnc-socket.xml b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket.xml
index d8742c6..cb4e5ac 100644
--- a/tests/genericxml2xmloutdata/generic-graphics-vnc-socket.xml
+++ b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket.xml
@@ -19,7 +19,9 @@
     <controller type='pci' index='0' model='pci-root'/>
     <input type='mouse' bus='ps2'/>
     <input type='keyboard' bus='ps2'/>
-    <graphics type='vnc' socket='/tmp/QEMUGuest1-vnc.sock'/>
+    <graphics type='vnc' socket='/tmp/QEMUGuest1-vnc.sock'>
+      <listen type='socket' socket='/tmp/QEMUGuest1-vnc.sock'/>
+    </graphics>
     <video>
       <model type='cirrus' vram='16384' heads='1' primary='yes'/>
     </video>
diff --git a/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml b/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml
index 93daa76..8f2478a 100644
--- a/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml
+++ b/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml
@@ -25,7 +25,9 @@
     <controller type='ide' index='0'/>
     <input type='mouse' bus='ps2'/>
     <input type='keyboard' bus='ps2'/>
-    <graphics type='vnc' socket='/tmp/foo.socket'/>
+    <graphics type='vnc' socket='/tmp/foo.socket'>
+      <listen type='socket' socket='/tmp/foo.socket'/>
+    </graphics>
     <video>
       <model type='cirrus' vram='16384' heads='1' primary='yes'/>
     </video>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.args
new file mode 100644
index 0000000..84ce727
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.args
@@ -0,0 +1,20 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-m 214 \
+-smp 1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-vnc unix:/tmp/lib/domain--1-QEMUGuest1/vnc.sock \
+-vga cirrus
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.xml
new file mode 100644
index 0000000..3e455df
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-unix-socket.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc'>
+      <listen type='socket'/>
+    </graphics>
+    <video>
+      <model type='cirrus' vram='16384' heads='1'/>
+    </video>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.args
new file mode 100644
index 0000000..abf724c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.args
@@ -0,0 +1,20 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-m 214 \
+-smp 1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-vnc unix:/tmp/vnc.sock \
+-vga cirrus
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.xml
new file mode 100644
index 0000000..522c3af
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-unix-socket.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc'>
+      <listen type='socket' socket='/tmp/vnc.sock'/>
+    </graphics>
+    <video>
+      <model type='cirrus' vram='16384' heads='1'/>
+    </video>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index e41444d..d2517ad 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -876,6 +876,8 @@ mymain(void)
     DO_TEST("graphics-vnc-websocket", QEMU_CAPS_VNC, QEMU_CAPS_VNC_WEBSOCKET);
     DO_TEST("graphics-vnc-policy", QEMU_CAPS_VNC, QEMU_CAPS_VNC_SHARE_POLICY);
     DO_TEST("graphics-vnc-no-listen-attr", QEMU_CAPS_VNC);
+    DO_TEST("graphics-vnc-unix-socket", QEMU_CAPS_VNC);
+    DO_TEST("graphics-vnc-auto-unix-socket", QEMU_CAPS_VNC);
 
     driver.config->vncSASL = 1;
     VIR_FREE(driver.config->vncSASLdir);
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-unix-socket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-unix-socket.xml
new file mode 100644
index 0000000..e14bbd1
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-unix-socket.xml
@@ -0,0 +1,35 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc'>
+      <listen type='socket'/>
+    </graphics>
+    <video>
+      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+    </video>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-unix-socket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-unix-socket.xml
new file mode 100644
index 0000000..9a83328
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-unix-socket.xml
@@ -0,0 +1,35 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' socket='/tmp/vnc.sock'>
+      <listen type='socket' socket='/tmp/vnc.sock'/>
+    </graphics>
+    <video>
+      <model type='cirrus' vram='16384' heads='1' primary='yes'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+    </video>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 6821895..fa343d2 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -433,6 +433,8 @@ mymain(void)
     DO_TEST("graphics-vnc-sasl");
     DO_TEST("graphics-vnc-tls");
     DO_TEST("graphics-vnc-no-listen-attr");
+    DO_TEST("graphics-vnc-unix-socket");
+    DO_TEST("graphics-vnc-auto-unix-socket");
     DO_TEST("graphics-sdl");
     DO_TEST("graphics-sdl-fullscreen");
     DO_TEST("graphics-spice");
-- 
2.8.2




More information about the libvir-list mailing list