[libvirt] [PATCH v6 04/10] graphics: introduce new listen type 'socket'

Pavel Hrdina phrdina at redhat.com
Wed Jun 8 15:25:42 UTC 2016


Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 docs/formatdomain.html.in     |  8 ++++++
 docs/schemas/domaincommon.rng | 10 ++++++++
 src/conf/domain_conf.c        | 60 +++++++++++++++++++++++++++++++++++++++++--
 src/conf/domain_conf.h        |  6 +++++
 src/libvirt_private.syms      |  1 +
 src/qemu/qemu_hotplug.c       |  9 +++++++
 src/qemu/qemu_process.c       |  9 +++++++
 src/security/virt-aa-helper.c | 15 ++++++++---
 8 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e737e39..5dd0e78 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5360,6 +5360,14 @@ qemu-kvm -net nic,model=? /dev/null
           of the first forward dev will be used.
         </p>
       </dd>
+      <dt><code>socket</code> <span class="since">since 1.3.6 (QEMU only)</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.
+        </p>
+      </dd>
     </dl>
 
     <h4><a name="elementsVideo">Video devices</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d14c1c5..f0640cc 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2976,6 +2976,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 133c2a3..0adf885 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;
 }
 
@@ -10895,6 +10897,7 @@ virDomainGraphicsAuthDefParseXML(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_*
@@ -10906,6 +10909,7 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
  */
 static int
 virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
+                                   virDomainGraphicsDefPtr graphics,
                                    xmlNodePtr node,
                                    xmlNodePtr parent,
                                    unsigned int flags)
@@ -10914,8 +10918,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, typeVal;
 
     if (parent)
@@ -10934,6 +10940,13 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
     }
     def->type = typeVal;
 
+    if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
+        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,
@@ -10968,6 +10981,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) {
@@ -10986,6 +11010,7 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
     VIR_FREE(type);
     VIR_FREE(address);
     VIR_FREE(network);
+    VIR_FREE(socket);
     VIR_FREE(fromConfig);
     VIR_FREE(addressCompat);
     return ret;
@@ -11025,7 +11050,7 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
             goto error;
 
         for (i = 0; i < nListens; i++) {
-            if (virDomainGraphicsListenDefParseXML(&def->listens[i],
+            if (virDomainGraphicsListenDefParseXML(&def->listens[i], def,
                                                    listenNodes[i],
                                                    i == 0 ? node : NULL,
                                                    flags) < 0)
@@ -21707,6 +21732,13 @@ virDomainGraphicsListenDefFormat(virBufferPtr buf,
         virBufferEscapeString(buf, " network='%s'", def->network);
     }
 
+    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);
 
@@ -24208,6 +24240,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 d1fc4b7..05dbfc2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1418,6 +1418,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;
@@ -1434,7 +1435,9 @@ struct _virDomainGraphicsListenDef {
     virDomainGraphicsListenType type;
     char *address;
     char *network;
+    char *socket;
     bool fromConfig;    /* true if the @address is config file originated */
+    bool autoGenerated;
 };
 
 struct _virDomainGraphicsDef {
@@ -2751,6 +2754,9 @@ virDomainGraphicsGetListen(virDomainGraphicsDefPtr def, size_t i);
 int virDomainGraphicsListenAppendAddress(virDomainGraphicsDefPtr def,
                                          const char *address)
             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 27ad7ff..d3e761a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -307,6 +307,7 @@ virDomainGraphicsAuthConnectedTypeToString;
 virDomainGraphicsDefFree;
 virDomainGraphicsGetListen;
 virDomainGraphicsListenAppendAddress;
+virDomainGraphicsListenAppendSocket;
 virDomainGraphicsSpiceChannelModeTypeFromString;
 virDomainGraphicsSpiceChannelModeTypeToString;
 virDomainGraphicsSpiceChannelNameTypeFromString;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6ce0a84..64f34ac 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2620,6 +2620,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_process.c b/src/qemu/qemu_process.c
index 71ac08c..5e66c31 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4080,6 +4080,15 @@ qemuProcessGraphicsSetupListen(virQEMUDriverConfigPtr cfg,
                 return -1;
             break;
 
+        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
+            if (!glisten->socket) {
+                if (virAsprintf(&glisten->socket, "%s/%s.sock",
+                                priv->libDir, type) < 0)
+                    return -1;
+                glisten->autoGenerated = true;
+            }
+            break;
+
         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
         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 6b0685c..9eafaee 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1007,10 +1007,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 &&
-- 
2.8.3




More information about the libvir-list mailing list