[libvirt] [PATCH 2/3] qemu: properly handle '=' in the VNC socket path

Pavel Hrdina phrdina at redhat.com
Fri Jul 21 18:11:30 UTC 2017


If a domain name contains a '=' and the unix socket path is
auto-generated or socket path provided by user contains '=' QEMU
is unable to properly parse the command line.  In order to make it
work we need to use the new command line syntax for VNC or we will
fail to start/define such domain.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1352529

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/qemu/qemu_command.c                            |  5 ++-
 src/qemu/qemu_process.c                            | 51 ++++++++++++++++++++--
 .../qemuxml2argvdata/qemuxml2argv-name-escape.args |  2 +-
 tests/qemuxml2argvtest.c                           |  1 +
 4 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0ce5aa5906..a0394a00ae 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7802,7 +7802,10 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
 
     switch (glisten->type) {
     case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
-        virBufferAddLit(&opt, "unix:");
+        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_MULTI_SERVERS))
+            virBufferAddLit(&opt, "vnc=unix:");
+        else
+            virBufferAddLit(&opt, "unix:");
         virQEMUBuildBufferEscapeComma(&opt, glisten->socket);
         break;
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 525521aaf0..4e93420955 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4146,6 +4146,34 @@ qemuProcessGraphicsSetupNetworkAddress(virDomainGraphicsListenDefPtr glisten,
     return 0;
 }
 
+static int
+qemuProcessVncValidateUnixSocket(const char *socket,
+                                 virQEMUCapsPtr qemuCaps)
+{
+    if (!socket)
+        return 0;
+
+    /* The way how QEMU process options disallow using '=' in the unix socket
+     * path.  The reason is that the first option doesn't have to use its name
+     * and -vnc has it's first option without name.  However when the parser
+     * finds first '=' in the option it always split it into key=value pair
+     * which blocks having '=' in the socket path.  Since QEMU 2.3.0 it's possible
+     * to use "vnc" as a key for the first option so we can use a unix socket
+     * path with '='. */
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_MULTI_SERVERS))
+        return 0;
+
+    if (strchr(socket, '=')) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("QEMU does not support having '=' in the "
+                         "VNC socket path '%s'."), socket);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 
 static int
 qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
@@ -4192,6 +4220,9 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
                     if (virAsprintf(&glisten->socket, "%s/%s.sock",
                                     priv->libDir, type) < 0)
                         goto cleanup;
+                    if (qemuProcessVncValidateUnixSocket(glisten->socket,
+                                                         priv->qemuCaps) < 0)
+                        goto cleanup;
                     glisten->fromConfig = true;
                     glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
                 } else if (listenAddr) {
@@ -4216,6 +4247,9 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
                 if (virAsprintf(&glisten->socket, "%s/%s.sock",
                                 priv->libDir, type) < 0)
                     goto cleanup;
+                if (qemuProcessVncValidateUnixSocket(glisten->socket,
+                                                     priv->qemuCaps) < 0)
+                    goto cleanup;
                 glisten->autoGenerated = true;
             }
             break;
@@ -4440,9 +4474,10 @@ qemuProcessStartWarnShmem(virDomainObjPtr vm)
 
 
 static int
-qemuProcessStartValidateGraphics(virDomainObjPtr vm)
+qemuProcessStartValidateGraphics(virDomainObjPtr vm,
+                                 virQEMUCapsPtr qemuCaps)
 {
-    size_t i;
+    size_t i, j;
 
     for (i = 0; i < vm->def->ngraphics; i++) {
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
@@ -4464,6 +4499,16 @@ qemuProcessStartValidateGraphics(virDomainObjPtr vm)
         case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
             break;
         }
+
+        if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+            for (j = 0; j < graphics->nListens; j++) {
+                virDomainGraphicsListenDefPtr glisten = &graphics->listens[j];
+                if (glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
+                    qemuProcessVncValidateUnixSocket(glisten->socket, qemuCaps) < 0) {
+                    return -1;
+                }
+            }
+        }
     }
 
     return 0;
@@ -4633,7 +4678,7 @@ qemuProcessStartValidate(virQEMUDriverPtr driver,
     if (qemuProcessStartValidateXML(driver, vm, qemuCaps, caps, flags) < 0)
         return -1;
 
-    if (qemuProcessStartValidateGraphics(vm) < 0)
+    if (qemuProcessStartValidateGraphics(vm, qemuCaps) < 0)
         return -1;
 
     if (qemuProcessStartValidateVideo(vm, qemuCaps) < 0)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
index d94ab76312..dd0fc8dd05 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-name-escape.args
@@ -20,7 +20,7 @@ bar=2/monitor.sock,server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--vnc unix:/tmp/lib/domain--1-foo=1,,bar=2/vnc.sock \
+-vnc vnc=unix:/tmp/lib/domain--1-foo=1,,bar=2/vnc.sock \
 -spice unix,addr=/tmp/lib/domain--1-foo=1,,bar=2/spice.sock \
 -vga cirrus \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 25cfedd9f8..7dc7e52d86 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2655,6 +2655,7 @@ mymain(void)
             QEMU_CAPS_NAME_DEBUG_THREADS,
             QEMU_CAPS_OBJECT_SECRET,
             QEMU_CAPS_VNC,
+            QEMU_CAPS_VNC_MULTI_SERVERS,
             QEMU_CAPS_NAME_GUEST,
             QEMU_CAPS_DEVICE_CIRRUS_VGA,
             QEMU_CAPS_SPICE,
-- 
2.13.3




More information about the libvir-list mailing list