]> xenbits.xensource.com Git - libvirt.git/commitdiff
graphics: introduce new listen type 'socket'
authorPavel Hrdina <phrdina@redhat.com>
Wed, 8 Jun 2016 08:35:37 +0000 (10:35 +0200)
committerPavel Hrdina <phrdina@redhat.com>
Thu, 9 Jun 2016 12:24:00 +0000 (14:24 +0200)
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_hotplug.c
src/qemu/qemu_process.c
src/security/virt-aa-helper.c

index e737e39d384f711629cde4f6f08465095a0a7ba1..5dd0e78b2f13496cdd0624de7f620fac4b4dabf5 100644 (file)
@@ -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>
index d14c1c5ecffdc4943f02954c672b2f36ecca2b19..f0640cce10217216c8813531da296fbe540cc2c5 100644 (file)
               </attribute>
             </optional>
           </group>
+          <group>
+            <attribute name="type">
+              <value>socket</value>
+            </attribute>
+            <optional>
+              <attribute name="socket">
+                <ref name="absFilePath"/>
+              </attribute>
+            </optional>
+          </group>
         </choice>
       </element>
     </zeroOrMore>
index 133c2a3ea9f6adfcb394fd8663654698fc7e3809..0adf885584799ee536738ecb653c51e703becf3f 100644 (file)
@@ -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
index d1fc4b75670a5f99babdf4b0ecd74d847d077b0a..05dbfc2943df1854863a72b855cc824ce1aeb36f 100644 (file)
@@ -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);
index 9737ddb8a7d81f5607dc796ff4c93d8be782b6da..42f664c6378d226b25c2937e1a71f6f47b140306 100644 (file)
@@ -307,6 +307,7 @@ virDomainGraphicsAuthConnectedTypeToString;
 virDomainGraphicsDefFree;
 virDomainGraphicsGetListen;
 virDomainGraphicsListenAppendAddress;
+virDomainGraphicsListenAppendSocket;
 virDomainGraphicsSpiceChannelModeTypeFromString;
 virDomainGraphicsSpiceChannelModeTypeToString;
 virDomainGraphicsSpiceChannelNameTypeFromString;
index 6fbeb3225315af9379e733b4e542767706878827..58156c6a432350337dfc09b1513e71f933a71b77 100644 (file)
@@ -2624,6 +2624,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 */
index 1c1a1bff80f785e66d51e2909e170553fc76fd2e..89d963dbce8915019b341d1b383fb2332f59509b 100644 (file)
@@ -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;
index 6b0685c93b4e366d198b77e6ffc9b5f09ca77c45..b6cde42c8e7da8b4a78eb1c3a5896ae33ee2fc53 100644 (file)
@@ -1007,10 +1007,22 @@ 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"))
+        virDomainGraphicsDefPtr graphics = ctl->def->graphics[i];
+        size_t n;
+
+        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+            graphics->data.vnc.socket &&
+            vah_add_file(&buf, graphics->data.vnc.socket, "w"))
             goto cleanup;
+
+        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 &&