[libvirt] [PATCH v5 0/6] [REPOST] introduce new listen types for graphics

There is no change since v4 [1], I've only rebased patches that are still waiting for review and removed the ones that are already pushed. [1] <https://www.redhat.com/archives/libvir-list/2016-May/msg01438.html> Pavel Hrdina (6): graphics: introduce listen type socket and use it for VNC qemu_capabilites: add QEMU_CAPS_SPICE_UNIX spice: add support for listen type socket spice: introduce spice_auto_unix_socket config option spice: introduce listen type none vnc: add support for listen type none docs/formatdomain.html.in | 28 +++ docs/schemas/domaincommon.rng | 15 ++ src/conf/domain_conf.c | 245 ++++++++++++++++++--- src/conf/domain_conf.h | 8 +- src/libvirt_private.syms | 1 + src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 17 +- src/qemu/qemu_capabilities.c | 3 + src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_command.c | 130 ++++++----- src/qemu/qemu_conf.c | 1 + src/qemu/qemu_conf.h | 1 + src/qemu/qemu_domain.c | 28 ++- src/qemu/qemu_hotplug.c | 9 + src/qemu/qemu_migration.c | 47 +++- src/qemu/qemu_parse_command.c | 2 +- src/qemu/qemu_process.c | 46 +++- src/qemu/test_libvirtd_qemu.aug.in | 1 + src/security/virt-aa-helper.c | 15 +- ...ric-graphics-vnc-socket-attr-listen-address.xml | 30 +++ ...hics-vnc-socket-attr-listen-socket-mismatch.xml | 30 +++ ...eric-graphics-vnc-socket-attr-listen-socket.xml | 30 +++ ...ric-graphics-vnc-socket-attr-listen-address.xml | 30 +++ ...eric-graphics-vnc-socket-attr-listen-socket.xml | 30 +++ .../generic-graphics-vnc-socket-listen.xml | 4 +- .../generic-graphics-vnc-socket.xml | 4 +- tests/genericxml2xmltest.c | 4 + .../qemuargv2xml-graphics-vnc-socket.xml | 4 +- tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + ...emuxml2argv-graphics-spice-auto-socket-cfg.args | 20 ++ ...qemuxml2argv-graphics-spice-auto-socket-cfg.xml | 30 +++ .../qemuxml2argv-graphics-spice-auto-socket.args | 20 ++ .../qemuxml2argv-graphics-spice-auto-socket.xml | 30 +++ .../qemuxml2argv-graphics-spice-socket.args | 20 ++ .../qemuxml2argv-graphics-spice-socket.xml | 30 +++ .../qemuxml2argv-graphics-vnc-auto-socket.args | 20 ++ .../qemuxml2argv-graphics-vnc-auto-socket.xml | 30 +++ .../qemuxml2argv-graphics-vnc-none.args | 20 ++ .../qemuxml2argv-graphics-vnc-none.xml | 30 +++ .../qemuxml2argv-graphics-vnc-socket.args | 4 +- .../qemuxml2argv-graphics-vnc-socket.xml | 10 +- .../qemuxml2argv-video-virtio-gpu-spice-gl.args | 2 +- tests/qemuxml2argvtest.c | 14 ++ ...muxml2xmlout-graphics-spice-auto-socket-cfg.xml | 35 +++ .../qemuxml2xmlout-graphics-spice-auto-socket.xml | 35 +++ .../qemuxml2xmlout-graphics-spice-socket.xml | 35 +++ .../qemuxml2xmlout-graphics-vnc-auto-socket.xml | 35 +++ ...graphics-vnc-remove-generated-socket-active.xml | 4 +- .../qemuxml2xmlout-graphics-vnc-socket.xml | 35 +++ .../qemuxml2xmlout-video-virtio-gpu-spice-gl.xml | 4 +- tests/qemuxml2xmltest.c | 8 + 53 files changed, 1096 insertions(+), 145 deletions(-) create mode 100644 tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-address.xml create mode 100644 tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket-mismatch.xml create mode 100644 tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket.xml create mode 100644 tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-address.xml create mode 100644 tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-socket.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket-cfg.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-socket.xml -- 2.8.3

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@redhat.com> --- docs/formatdomain.html.in | 16 +++ docs/schemas/domaincommon.rng | 10 ++ src/conf/domain_conf.c | 152 ++++++++++++++++++--- src/conf/domain_conf.h | 8 +- src/libvirt_private.syms | 1 + src/qemu/qemu.conf | 6 +- src/qemu/qemu_command.c | 58 ++++---- src/qemu/qemu_domain.c | 28 ++-- src/qemu/qemu_hotplug.c | 9 ++ src/qemu/qemu_parse_command.c | 2 +- src/qemu/qemu_process.c | 45 ++++-- src/security/virt-aa-helper.c | 15 +- ...ric-graphics-vnc-socket-attr-listen-address.xml | 30 ++++ ...hics-vnc-socket-attr-listen-socket-mismatch.xml | 30 ++++ ...eric-graphics-vnc-socket-attr-listen-socket.xml | 30 ++++ ...ric-graphics-vnc-socket-attr-listen-address.xml | 30 ++++ ...eric-graphics-vnc-socket-attr-listen-socket.xml | 30 ++++ .../generic-graphics-vnc-socket-listen.xml | 4 +- .../generic-graphics-vnc-socket.xml | 4 +- tests/genericxml2xmltest.c | 4 + .../qemuargv2xml-graphics-vnc-socket.xml | 4 +- .../qemuxml2argv-graphics-vnc-auto-socket.args | 20 +++ .../qemuxml2argv-graphics-vnc-auto-socket.xml | 30 ++++ .../qemuxml2argv-graphics-vnc-socket.args | 4 +- .../qemuxml2argv-graphics-vnc-socket.xml | 10 +- tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-graphics-vnc-auto-socket.xml | 35 +++++ ...graphics-vnc-remove-generated-socket-active.xml | 4 +- .../qemuxml2xmlout-graphics-vnc-socket.xml | 35 +++++ tests/qemuxml2xmltest.c | 2 + 30 files changed, 564 insertions(+), 94 deletions(-) create mode 100644 tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-address.xml create mode 100644 tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket-mismatch.xml create mode 100644 tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket.xml create mode 100644 tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-address.xml create mode 100644 tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-socket.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-socket.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 72bfa35..91f41db 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5349,6 +5349,22 @@ 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.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 903fd7e..60f9f52 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2971,6 +2971,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 fb05bf7..bbbf67c 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 (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; @@ -10663,6 +10664,7 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node, * virDomainGraphicsListenDefParseXML: * @def: listen def pointer to be filled * @node: xml node of <listen/> element + * * @parent: xml node of <graphics/> element * @flags: bit-wise or of VIR_DOMAIN_DEF_PARSE_* * @@ -10674,6 +10676,7 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node, static int virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, xmlNodePtr node, + virDomainGraphicsDefPtr graphics, xmlNodePtr parent, unsigned int flags) { @@ -10681,12 +10684,17 @@ 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; + char *socketCompat = NULL; + const char *graphicsType = virDomainGraphicsTypeToString(graphics->type); int tmp, typeVal; - if (parent) + if (parent) { addressCompat = virXMLPropString(parent, "listen"); + socketCompat = virXMLPropString(parent, "socket"); + } if (!type) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -10701,6 +10709,14 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, } def->type = typeVal; + 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, @@ -10716,6 +10732,21 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, } } + if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) { + if (socket && socketCompat && STRNEQ(socket, socketCompat)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("graphics 'socket' attribute '%s' must match " + "'socket' attribute of first listen element " + "(found '%s')"), socketCompat, socket); + goto error; + } + + if (!socket) { + socket = socketCompat; + socketCompat = NULL; + } + } + if (address && address[0] && (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS || (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK && @@ -10735,6 +10766,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) { @@ -10753,8 +10795,10 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, VIR_FREE(type); VIR_FREE(address); VIR_FREE(network); + VIR_FREE(socket); VIR_FREE(fromConfig); VIR_FREE(addressCompat); + VIR_FREE(socketCompat); return ret; } @@ -10774,12 +10818,6 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def, ctxt->node = node; - if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && - (socketPath = virXMLPropString(node, "socket"))) { - ret = 0; - goto error; - } - /* parse the <listen> subelements for graphics types that support it */ nListens = virXPathNodeSet("./listen", ctxt, &listenNodes); if (nListens < 0) @@ -10794,6 +10832,7 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def, for (i = 0; i < nListens; i++) { if (virDomainGraphicsListenDefParseXML(&def->listens[i], listenNodes[i], + def, i == 0 ? node : NULL, flags) < 0) goto error; @@ -10801,16 +10840,43 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def, def->nListens++; } VIR_FREE(listenNodes); + } + + /* If no <listen/> element was found in XML for backward compatibility + * we should try to parse 'listen' or 'socket' attribute from <graphics/> + * element. */ + if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) + socketPath = virXMLPropString(node, "socket"); + + if (socketPath) { + newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET; + newListen.socket = socketPath; + socketPath = NULL; } else { - /* If no <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 no <listen/> element was found add a new one created by parsing + * <graphics/> element. */ + if (def->nListens == 0) { if (VIR_APPEND_ELEMENT(def->listens, def->nListens, newListen) < 0) goto error; + } else { + virDomainGraphicsListenDefPtr glisten = &def->listens[0]; + + /* If the first <listen/> element is 'address' or 'network' and we found + * 'socket' attribute inside <graphics/> element for backward + * compatibility we need to replace the first listen by + * <listen type='socket' .../> element based on the 'socket' attribite. */ + if ((glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS || + glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) && + newListen.type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) { + virDomainGraphicsListenDefClear(glisten); + *glisten = newListen; + } } ret = 0; @@ -10888,7 +10954,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, @@ -21413,6 +21478,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); @@ -21470,11 +21542,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 || glisten->fromConfig) && + (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) { + virBufferEscapeString(buf, " socket='%s'", glisten->socket); } } else { if (def->data.vnc.port && @@ -21580,9 +21658,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); @@ -23896,6 +23984,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 82e581b..48e9f78 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1410,6 +1410,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; @@ -1426,7 +1427,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 { @@ -1443,8 +1446,6 @@ struct _virDomainGraphicsDef { int websocket; bool autoport; char *keymap; - char *socket; - bool socketAutogenerated; virDomainGraphicsAuthDef auth; int sharePolicy; } vnc; @@ -2720,6 +2721,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 fb5b419..63373e7 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.conf b/src/qemu/qemu.conf index 4fa5e8a..59c839e 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -15,9 +15,9 @@ # unix socket. This prevents unprivileged access from users on the # host machine, though most VNC clients do not support it. # -# This will only be enabled for VNC configurations that do not have -# a hardcoded 'listen' or 'socket' value. This setting takes preference -# over vnc_listen. +# This will only be enabled for VNC configurations that have listen +# type=address but without any address specified. This setting takes +# preference over vnc_listen. # #vnc_auto_unix_socket = 1 diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 102837b..21db884 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7303,8 +7303,7 @@ static int qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, virQEMUCapsPtr qemuCaps, - virDomainGraphicsDefPtr graphics, - const char *domainLibDir) + virDomainGraphicsDefPtr graphics) { virBuffer opt = VIR_BUFFER_INITIALIZER; virDomainGraphicsListenDefPtr glisten = NULL; @@ -7316,21 +7315,20 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, goto error; } - glisten = virDomainGraphicsGetListen(graphics, 0); - - if (graphics->data.vnc.socket || cfg->vncAutoUnixSocket) { - if (!graphics->data.vnc.socket) { - if (virAsprintf(&graphics->data.vnc.socket, - "%s/vnc.sock", domainLibDir) < 0) - goto error; - - graphics->data.vnc.socketAutogenerated = true; - } + 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: virBufferAddLit(&opt, "unix:"); - qemuBufferEscapeComma(&opt, graphics->data.vnc.socket); + qemuBufferEscapeComma(&opt, glisten->socket); + break; - } else { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: if (!graphics->data.vnc.autoport && (graphics->data.vnc.port < 5900 || graphics->data.vnc.port > 65535)) { @@ -7339,7 +7337,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, goto error; } - if (glisten && glisten->address) { + if (glisten->address) { escapeAddr = strchr(glisten->address, ':') != NULL; if (escapeAddr) virBufferAsprintf(&opt, "[%s]", glisten->address); @@ -7348,17 +7346,21 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, } virBufferAsprintf(&opt, ":%d", graphics->data.vnc.port - 5900); - } - if (!graphics->data.vnc.socket && - graphics->data.vnc.websocket) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("VNC WebSockets are not supported " - "with this QEMU binary")); - goto error; + if (graphics->data.vnc.websocket) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VNC WebSockets are not supported " + "with this QEMU binary")); + goto error; + } + virBufferAsprintf(&opt, ",websocket=%d", graphics->data.vnc.websocket); } - virBufferAsprintf(&opt, ",websocket=%d", graphics->data.vnc.websocket); + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; } if (graphics->data.vnc.sharePolicy) { @@ -7629,8 +7631,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, virDomainDefPtr def, virQEMUCapsPtr qemuCaps, - virDomainGraphicsDefPtr graphics, - const char *domainLibDir) + virDomainGraphicsDefPtr graphics) { switch (graphics->type) { case VIR_DOMAIN_GRAPHICS_TYPE_SDL: @@ -7662,8 +7663,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, break; case VIR_DOMAIN_GRAPHICS_TYPE_VNC: - return qemuBuildGraphicsVNCCommandLine(cfg, cmd, qemuCaps, - graphics, domainLibDir); + return qemuBuildGraphicsVNCCommandLine(cfg, cmd, qemuCaps, graphics); case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: return qemuBuildGraphicsSPICECommandLine(cfg, cmd, qemuCaps, graphics); @@ -9343,7 +9343,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, for (i = 0; i < def->ngraphics; ++i) { if (qemuBuildGraphicsCommandLine(cfg, cmd, def, qemuCaps, - def->graphics[i], domainLibDir) < 0) + def->graphics[i]) < 0) goto error; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c21465d..2fe0780 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2085,20 +2085,30 @@ 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); - if (virDomainGraphicsListenAppendAddress(graphics, NULL) < 0) - return -1; + for (j = 0; j < graphics->nListens; ++j) { + virDomainGraphicsListenDefPtr glisten = &graphics->listens[j]; + + /* This will happen only if we parse XML from old libvirts where + * unix socket was available only for VNC graphics. In this + * particular case we should follow the behavior and if we remove + * the auto-generated socket we need to change the listen type to + * address. */ + if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && + 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); + glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS; + } else { + glisten->autogenerated = true; + } } - else - graphics->data.vnc.socketAutogenerated = true; } } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5f34a76..35fd5f5 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2649,6 +2649,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 4fafdf2..927bd79 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 b2669c0..3389174 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3466,9 +3466,6 @@ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver, { unsigned short port; - if (graphics->data.vnc.socket) - return 0; - if (!allocate) { if (graphics->data.vnc.autoport) graphics->data.vnc.port = 5900; @@ -4019,13 +4016,18 @@ qemuProcessGraphicsSetupNetworkAddress(virDomainGraphicsListenDefPtr glisten, static int qemuProcessGraphicsSetupListen(virQEMUDriverConfigPtr cfg, - virDomainGraphicsDefPtr graphics) + virDomainGraphicsDefPtr graphics, + virDomainObjPtr vm) { + qemuDomainObjPrivatePtr priv = vm->privateData; + const char *type = virDomainGraphicsTypeToString(graphics->type); char *listenAddr = NULL; + bool useSocket = false; size_t i; switch (graphics->type) { case VIR_DOMAIN_GRAPHICS_TYPE_VNC: + useSocket = cfg->vncAutoUnixSocket; listenAddr = cfg->vncListen; break; @@ -4045,13 +4047,23 @@ qemuProcessGraphicsSetupListen(virQEMUDriverConfigPtr cfg, switch (glisten->type) { case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: - if (glisten->address || !listenAddr) - continue; - - if (VIR_STRDUP(glisten->address, listenAddr) < 0) - return -1; - - glisten->fromConfig = true; + if (!glisten->address) { + /* If there is no address specified and qemu.conf has + * *_auto_unix_socket set we should use unix socket as + * default instead of tcp listen. */ + if (useSocket) { + memset(glisten, 0, sizeof(virDomainGraphicsListenDef)); + if (virAsprintf(&glisten->socket, "%s/%s.sock", + priv->libDir, type) < 0) + return -1; + glisten->fromConfig = true; + glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET; + } else if (listenAddr) { + if (VIR_STRDUP(glisten->address, listenAddr) < 0) + return -1; + glisten->fromConfig = true; + } + } break; case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: @@ -4063,6 +4075,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; @@ -4107,7 +4128,7 @@ qemuProcessSetupGraphics(virQEMUDriverPtr driver, break; } - if (qemuProcessGraphicsSetupListen(cfg, graphics) < 0) + if (qemuProcessGraphicsSetupListen(cfg, graphics, vm) < 0) goto cleanup; } diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 537e89d..cbe09af 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1002,10 +1002,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/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-address.xml b/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-address.xml new file mode 100644 index 0000000..a32c20b --- /dev/null +++ b/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-address.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' socket='/tmp/vnc.sock'> + <listen type='address' address='0.0.0.0'/> + </graphics> + <video> + <model type='cirrus' vram='16384' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket-mismatch.xml b/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket-mismatch.xml new file mode 100644 index 0000000..980b64c --- /dev/null +++ b/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket-mismatch.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' socket='/tmp/vnc.sock'> + <listen type='socket' socket='/tmp/mismatch.sock'/> + </graphics> + <video> + <model type='cirrus' vram='16384' heads='1'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket.xml b/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-socket.xml new file mode 100644 index 0000000..ea3efca --- /dev/null +++ b/tests/genericxml2xmlindata/generic-graphics-vnc-socket-attr-listen-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' socket='/tmp/vnc.sock'> + <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/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-address.xml b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-address.xml new file mode 100644 index 0000000..f205e13 --- /dev/null +++ b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-address.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' socket='/tmp/vnc.sock'> + <listen type='socket' socket='/tmp/vnc.sock'/> + </graphics> + <video> + <model type='cirrus' vram='16384' heads='1' primary='yes'/> + </video> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-socket.xml b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-socket.xml new file mode 100644 index 0000000..f205e13 --- /dev/null +++ b/tests/genericxml2xmloutdata/generic-graphics-vnc-socket-attr-listen-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' socket='/tmp/vnc.sock'> + <listen type='socket' socket='/tmp/vnc.sock'/> + </graphics> + <video> + <model type='cirrus' vram='16384' heads='1' primary='yes'/> + </video> + <memballoon model='none'/> + </devices> +</domain> 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/genericxml2xmltest.c b/tests/genericxml2xmltest.c index 70ecd2d..a193a33 100644 --- a/tests/genericxml2xmltest.c +++ b/tests/genericxml2xmltest.c @@ -87,6 +87,10 @@ mymain(void) DO_TEST_DIFFERENT("graphics-vnc-listen-attr-only"); DO_TEST_DIFFERENT("graphics-vnc-listen-element-minimal"); DO_TEST_DIFFERENT("graphics-vnc-listen-element-with-address"); + DO_TEST_DIFFERENT("graphics-vnc-socket-attr-listen-address"); + DO_TEST_DIFFERENT("graphics-vnc-socket-attr-listen-socket"); + DO_TEST_FULL("graphics-vnc-socket-attr-listen-socket-mismatch", 0, false, + TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); DO_TEST_FULL("name-slash-parse", 0, false, TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); diff --git a/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml b/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml index edbaab3..efd2601 100644 --- a/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml +++ b/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml @@ -29,7 +29,9 @@ </controller> <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'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.args new file mode 100644 index 0000000..84ce727 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-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-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-socket.xml new file mode 100644 index 0000000..3e455df --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-auto-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-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args index 2464867..abf724c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args @@ -16,7 +16,5 @@ QEMU_AUDIO_DRV=none \ -no-acpi \ -boot c \ -usb \ --drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ --device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ --vnc unix:/tmp/foo.socket \ +-vnc unix:/tmp/vnc.sock \ -vga cirrus diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml index de70bc4..522c3af 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml @@ -14,18 +14,14 @@ <on_crash>destroy</on_crash> <devices> <emulator>/usr/bin/qemu</emulator> - <disk type='block' device='disk'> - <driver name='qemu' type='raw'/> - <source dev='/dev/HostVG/QEMUGuest1'/> - <target dev='hda' bus='ide'/> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </disk> <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' socket='/tmp/foo.socket'/> + <graphics type='vnc'> + <listen type='socket' socket='/tmp/vnc.sock'/> + </graphics> <video> <model type='cirrus' vram='16384' heads='1'/> </video> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 7bf9300..13243b2 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -901,6 +901,8 @@ mymain(void) driver.config->vncAutoUnixSocket = true; DO_TEST("graphics-vnc-auto-socket-cfg", QEMU_CAPS_VNC); driver.config->vncAutoUnixSocket = false; + DO_TEST("graphics-vnc-socket", QEMU_CAPS_VNC); + DO_TEST("graphics-vnc-auto-socket", QEMU_CAPS_VNC); driver.config->vncSASL = 1; VIR_FREE(driver.config->vncSASLdir); diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-socket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-socket.xml new file mode 100644 index 0000000..e14bbd1 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-auto-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-remove-generated-socket-active.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-remove-generated-socket-active.xml index f3ccfdf..1aeffe8 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-remove-generated-socket-active.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-remove-generated-socket-active.xml @@ -29,7 +29,9 @@ <controller type='pci' index='0' model='pci-root'/> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> - <graphics type='vnc' socket='/tmp/lib/domain-99-QEMUGuest1/delete.this.socket'/> + <graphics type='vnc' socket='/tmp/lib/domain-99-QEMUGuest1/delete.this.socket'> + <listen type='socket' socket='/tmp/lib/domain-99-QEMUGuest1/delete.this.socket'/> + </graphics> <video> <model type='cirrus' vram='16384' heads='1' primary='yes'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-socket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-socket.xml new file mode 100644 index 0000000..9a83328 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-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 c85cd60..091fadb 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -434,6 +434,8 @@ mymain(void) cfg->vncAutoUnixSocket = true; DO_TEST("graphics-vnc-auto-socket-cfg"); cfg->vncAutoUnixSocket = false; + DO_TEST("graphics-vnc-socket"); + DO_TEST("graphics-vnc-auto-socket"); DO_TEST("graphics-sdl"); DO_TEST("graphics-sdl-fullscreen"); -- 2.8.3

On Tue, May 24, 2016 at 04:45:53PM +0200, Pavel Hrdina wrote:
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@redhat.com> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 72bfa35..91f41db 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5349,6 +5349,22 @@ 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.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 903fd7e..60f9f52 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2971,6 +2971,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>
Reiterating an old comment on this new version, but I really think "type" should be "unix" rather than "socket" for consistency reasons. Less strong feelings on "socket" VS "path" for the associated attribute name. Christophe

On Wed, May 25, 2016 at 10:32:02AM +0200, Christophe Fergeau wrote:
On Tue, May 24, 2016 at 04:45:53PM +0200, Pavel Hrdina wrote:
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@redhat.com> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 72bfa35..91f41db 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5349,6 +5349,22 @@ 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.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 903fd7e..60f9f52 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2971,6 +2971,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>
Reiterating an old comment on this new version, but I really think "type" should be "unix" rather than "socket" for consistency reasons. Less strong feelings on "socket" VS "path" for the associated attribute name.
Yes, I know about your comment but like I've already replied, I would prefer "socket" for consistency reasons. I would use "unix" if we had a "tcp" instead of "address". All other occurrences in our XML have "tcp", "udp" and "unix" but in case of listens we have "address", "network" and "none" and I think that "socket" fits better than "unix". I'm not arguing that "unix" would be more correct description, but "socket" isn't completely wrong. Pavel

Add a new capability to detect support of unix sockets for spice graphics. Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/qemu_capabilities.c | 3 +++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + 5 files changed, 9 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d32e71f..2261ac7 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -329,6 +329,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "nec-usb-xhci-ports", "virtio-scsi-pci.iothread", "name-guest", + + "spice-unix", /* 225 */ ); @@ -2659,6 +2661,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = { { "chardev", "logfile", QEMU_CAPS_CHARDEV_LOGFILE }, { "name", "debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS }, { "name", "guest", QEMU_CAPS_NAME_GUEST }, + { "spice", "unix", QEMU_CAPS_SPICE_UNIX }, }; static int diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 368996a..7ef7bc6 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -361,6 +361,9 @@ typedef enum { QEMU_CAPS_VIRTIO_SCSI_IOTHREAD, /* virtio-scsi-{pci,ccw}.iothread */ QEMU_CAPS_NAME_GUEST, /* -name guest= */ + /* 225 */ + QEMU_CAPS_SPICE_UNIX, /* -spice unix */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml index e56b7e5..ac78802 100644 --- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml @@ -178,6 +178,7 @@ <flag name='nec-usb-xhci-ports'/> <flag name='virtio-scsi-pci.iothread'/> <flag name='name-guest'/> + <flag name='spice-unix'/> <version>2004000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml index 4df4843..98c5dc4 100644 --- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml @@ -182,6 +182,7 @@ <flag name='nec-usb-xhci-ports'/> <flag name='virtio-scsi-pci.iothread'/> <flag name='name-guest'/> + <flag name='spice-unix'/> <version>2005000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml index 8af0894..a4e758c 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml @@ -188,6 +188,7 @@ <flag name='nec-usb-xhci-ports'/> <flag name='virtio-scsi-pci.iothread'/> <flag name='name-guest'/> + <flag name='spice-unix'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> -- 2.8.3

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1335832 Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- docs/formatdomain.html.in | 2 +- src/conf/domain_conf.c | 31 ++++++++---- src/qemu/qemu_command.c | 56 ++++++++++++++++------ src/qemu/qemu_migration.c | 47 +++++++++++++----- .../qemuxml2argv-graphics-spice-auto-socket.args | 20 ++++++++ .../qemuxml2argv-graphics-spice-auto-socket.xml | 30 ++++++++++++ .../qemuxml2argv-graphics-spice-socket.args | 20 ++++++++ .../qemuxml2argv-graphics-spice-socket.xml | 30 ++++++++++++ tests/qemuxml2argvtest.c | 6 +++ .../qemuxml2xmlout-graphics-spice-auto-socket.xml | 35 ++++++++++++++ .../qemuxml2xmlout-graphics-spice-socket.xml | 35 ++++++++++++++ tests/qemuxml2xmltest.c | 2 + 12 files changed, 277 insertions(+), 37 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-socket.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 91f41db..6bc2910 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5355,7 +5355,7 @@ qemu-kvm -net nic,model=? /dev/null 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>. + Supported by graphics type <code>vnc</code> and <code>spice</code>. </p> <p> For <code>vnc</code> graphics be backward compatible diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bbbf67c..9b51696 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10710,7 +10710,8 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, def->type = typeVal; if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET && - graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) { + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("listen type 'socket' is not available for " "graphics type '%s'"), graphicsType); @@ -21627,18 +21628,28 @@ virDomainGraphicsDefFormat(virBufferPtr buf, break; case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: - if (def->data.spice.port) - virBufferAsprintf(buf, " port='%d'", - def->data.spice.port); + switch (glisten->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + if (def->data.spice.port) + virBufferAsprintf(buf, " port='%d'", + def->data.spice.port); - if (def->data.spice.tlsPort) - virBufferAsprintf(buf, " tlsPort='%d'", - def->data.spice.tlsPort); + if (def->data.spice.tlsPort) + virBufferAsprintf(buf, " tlsPort='%d'", + def->data.spice.tlsPort); - virBufferAsprintf(buf, " autoport='%s'", - def->data.spice.autoport ? "yes" : "no"); + virBufferAsprintf(buf, " autoport='%s'", + def->data.spice.autoport ? "yes" : "no"); - virDomainGraphicsListenDefFormatAddr(buf, glisten, flags); + virDomainGraphicsListenDefFormatAddr(buf, glisten, flags); + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; + } if (def->data.spice.keymap) virBufferEscapeString(buf, " keymap='%s'", diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 21db884..ba58423 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7438,27 +7438,53 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, goto error; } - glisten = virDomainGraphicsGetListen(graphics, 0); - - if (port > 0) { - virBufferAsprintf(&opt, "port=%u,", port); - hasInsecure = true; + if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing listen element")); + goto error; } - if (tlsPort > 0) { - if (!cfg->spiceTLS) { + switch (glisten->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_UNIX)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("spice TLS port set in XML configuration," - " but TLS is disabled in qemu.conf")); + _("unix socket for spice graphics are not supported " + "with this QEMU")); goto error; } - virBufferAsprintf(&opt, "tls-port=%u,", tlsPort); - hasSecure = true; - } - if (port > 0 || tlsPort > 0) { - if (glisten && glisten->address) - virBufferAsprintf(&opt, "addr=%s,", glisten->address); + virBufferAsprintf(&opt, "unix,addr=%s,", glisten->socket); + hasInsecure = true; + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + if (port > 0) { + virBufferAsprintf(&opt, "port=%u,", port); + hasInsecure = true; + } + + if (tlsPort > 0) { + if (!cfg->spiceTLS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("spice TLS port set in XML configuration, " + "but TLS is disabled in qemu.conf")); + goto error; + } + virBufferAsprintf(&opt, "tls-port=%u,", tlsPort); + hasSecure = true; + } + + if (port > 0 || tlsPort > 0) { + if (glisten->address) + virBufferAsprintf(&opt, "addr=%s,", glisten->address); + } + + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; } if (cfg->spiceSASL) { diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 25093ac..c63341d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -315,17 +315,17 @@ qemuDomainExtractTLSSubject(const char *certdir) static qemuMigrationCookieGraphicsPtr qemuMigrationCookieGraphicsSpiceAlloc(virQEMUDriverPtr driver, - virDomainGraphicsDefPtr def) + virDomainGraphicsDefPtr def, + virDomainGraphicsListenDefPtr glisten) { qemuMigrationCookieGraphicsPtr mig = NULL; const char *listenAddr; - virDomainGraphicsListenDefPtr glisten = virDomainGraphicsGetListen(def, 0); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); if (VIR_ALLOC(mig) < 0) goto error; - mig->type = def->type; + mig->type = VIR_DOMAIN_GRAPHICS_TYPE_SPICE; mig->port = def->data.spice.port; if (cfg->spiceTLS) mig->tlsPort = def->data.spice.tlsPort; @@ -452,14 +452,39 @@ qemuMigrationCookieAddGraphics(qemuMigrationCookiePtr mig, } for (i = 0; i < dom->def->ngraphics; i++) { - if (dom->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { - if (!(mig->graphics = - qemuMigrationCookieGraphicsSpiceAlloc(driver, - dom->def->graphics[i]))) - return -1; - mig->flags |= QEMU_MIGRATION_COOKIE_GRAPHICS; - break; - } + if (dom->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virDomainGraphicsListenDefPtr glisten = + virDomainGraphicsGetListen(dom->def->graphics[i], 0); + + if (!glisten) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing listen element")); + return -1; + } + + switch (glisten->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + /* Seamless migration is supported only for listen types + * 'address and 'network'. */ + if (!(mig->graphics = + qemuMigrationCookieGraphicsSpiceAlloc(driver, + dom->def->graphics[i], + glisten))) + return -1; + mig->flags |= QEMU_MIGRATION_COOKIE_GRAPHICS; + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; + } + + /* Seamless migration is supported only for one graphics. */ + if (mig->graphics) + break; + } } return 0; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.args new file mode 100644 index 0000000..61335b0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.args @@ -0,0 +1,20 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/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 \ +-spice unix,addr=/tmp/lib/domain--1-QEMUGuest1/spice.sock \ +-vga cirrus diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket.xml new file mode 100644 index 0000000..acb325a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-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='spice'> + <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-spice-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.args new file mode 100644 index 0000000..26d0671 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.args @@ -0,0 +1,20 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/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 \ +-spice unix,addr=/tmp/spice.sock \ +-vga cirrus diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-socket.xml new file mode 100644 index 0000000..13bbef1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-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='spice'> + <listen type='socket' socket='/tmp/spice.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 13243b2..980ed2c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -966,6 +966,12 @@ mymain(void) QEMU_CAPS_DEVICE_QXL_VGA, QEMU_CAPS_DEVICE_QXL, QEMU_CAPS_SPICE_FILE_XFER_DISABLE); + DO_TEST("graphics-spice-socket", + QEMU_CAPS_SPICE, + QEMU_CAPS_SPICE_UNIX); + DO_TEST("graphics-spice-auto-socket", + QEMU_CAPS_SPICE, + QEMU_CAPS_SPICE_UNIX); DO_TEST("input-usbmouse", NONE); DO_TEST("input-usbtablet", NONE); diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket.xml new file mode 100644 index 0000000..931ec0f --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-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='spice'> + <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-spice-socket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-socket.xml new file mode 100644 index 0000000..dd672ed --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-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='spice'> + <listen type='socket' socket='/tmp/spice.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 091fadb..87fbb0a 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -442,6 +442,8 @@ mymain(void) DO_TEST("graphics-spice"); DO_TEST("graphics-spice-compression"); DO_TEST("graphics-spice-qxl-vga"); + DO_TEST("graphics-spice-socket"); + DO_TEST("graphics-spice-auto-socket"); DO_TEST("nographics-vga"); DO_TEST("input-usbmouse"); DO_TEST("input-usbtablet"); -- 2.8.3

Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 11 +++++++ src/qemu/qemu_conf.c | 1 + src/qemu/qemu_conf.h | 1 + src/qemu/qemu_process.c | 1 + src/qemu/test_libvirtd_qemu.aug.in | 1 + ...emuxml2argv-graphics-spice-auto-socket-cfg.args | 20 +++++++++++++ ...qemuxml2argv-graphics-spice-auto-socket-cfg.xml | 30 +++++++++++++++++++ tests/qemuxml2argvtest.c | 5 ++++ ...muxml2xmlout-graphics-spice-auto-socket-cfg.xml | 35 ++++++++++++++++++++++ tests/qemuxml2xmltest.c | 4 +++ 11 files changed, 110 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket-cfg.xml diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index b6f6dc4..8bc23ba 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -37,6 +37,7 @@ module Libvirtd_qemu = let spice_entry = str_entry "spice_listen" | bool_entry "spice_tls" | str_entry "spice_tls_x509_cert_dir" + | bool_entry "spice_auto_unix_socket" | str_entry "spice_password" | bool_entry "spice_sasl" | str_entry "spice_sasl_dir" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 59c839e..7964273 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -130,6 +130,17 @@ #spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice" +# Enable this option to have SPICE served over an automatically created +# unix socket. This prevents unprivileged access from users on the +# host machine. +# +# This will only be enabled for SPICE configurations that have listen +# type=address but without any address specified. This setting takes +# preference over spice_listen. +# +#spice_auto_unix_socket = 1 + + # The default SPICE password. This parameter is only used if the # per-domain XML config does not already provide a password. To # allow access without passwords, leave this commented out. An diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index e00ddca..d4c34c9 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -588,6 +588,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, GET_VALUE_STR("spice_sasl_dir", cfg->spiceSASLdir); GET_VALUE_STR("spice_listen", cfg->spiceListen); GET_VALUE_STR("spice_password", cfg->spicePassword); + GET_VALUE_BOOL("spice_auto_unix_socket", cfg->spiceAutoUnixSocket); GET_VALUE_ULONG("remote_websocket_port_min", cfg->webSocketPortMin); diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index a714b84..c94bf13 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -123,6 +123,7 @@ struct _virQEMUDriverConfig { char *spiceSASLdir; char *spiceListen; char *spicePassword; + bool spiceAutoUnixSocket; int remotePortMin; int remotePortMax; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 3389174..f74226d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4032,6 +4032,7 @@ qemuProcessGraphicsSetupListen(virQEMUDriverConfigPtr cfg, break; case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + useSocket = cfg->spiceAutoUnixSocket; listenAddr = cfg->spiceListen; break; diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index 8bec743..c4d4f19 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -14,6 +14,7 @@ module Test_libvirtd_qemu = { "spice_listen" = "0.0.0.0" } { "spice_tls" = "1" } { "spice_tls_x509_cert_dir" = "/etc/pki/libvirt-spice" } +{ "spice_auto_unix_socket" = "1" } { "spice_password" = "XYZ12345" } { "spice_sasl" = "1" } { "spice_sasl_dir" = "/some/directory/sasl2" } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.args new file mode 100644 index 0000000..61335b0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.args @@ -0,0 +1,20 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/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 \ +-spice unix,addr=/tmp/lib/domain--1-QEMUGuest1/spice.sock \ +-vga cirrus diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.xml new file mode 100644 index 0000000..f2e3d12 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-auto-socket-cfg.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='spice' autoport='yes'> + <listen type='address'/> + </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 980ed2c..a2920df 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -972,6 +972,11 @@ mymain(void) DO_TEST("graphics-spice-auto-socket", QEMU_CAPS_SPICE, QEMU_CAPS_SPICE_UNIX); + driver.config->spiceAutoUnixSocket = true; + DO_TEST("graphics-spice-auto-socket-cfg", + QEMU_CAPS_SPICE, + QEMU_CAPS_SPICE_UNIX); + driver.config->spiceAutoUnixSocket = false; DO_TEST("input-usbmouse", NONE); DO_TEST("input-usbtablet", NONE); diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket-cfg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket-cfg.xml new file mode 100644 index 0000000..7548184 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-auto-socket-cfg.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='spice' autoport='yes'> + <listen type='address'/> + </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 87fbb0a..49c1d43 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -444,6 +444,10 @@ mymain(void) DO_TEST("graphics-spice-qxl-vga"); DO_TEST("graphics-spice-socket"); DO_TEST("graphics-spice-auto-socket"); + cfg->spiceAutoUnixSocket = true; + DO_TEST("graphics-spice-auto-socket-cfg"); + cfg->spiceAutoUnixSocket = false; + DO_TEST("nographics-vga"); DO_TEST("input-usbmouse"); DO_TEST("input-usbtablet"); -- 2.8.3

This new listen type is currently supported only by spice graphics. It's introduced to make it easier and clearer specify to not listen anywhere in order to start a guest with OpenGL support. The old way to do this was set spice graphics autoport='no' and don't specify any ports. The new way is to use <listen type='none'/>. In order to be able to migrate to old libvirt the migratable XML will be generated without the listen element and with autoport='no'. Also the old configuration will be automatically converted to the this listen type. Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- docs/formatdomain.html.in | 11 ++++ docs/schemas/domaincommon.rng | 5 ++ src/conf/domain_conf.c | 77 ++++++++++++++++++---- src/qemu/qemu_command.c | 13 ++-- .../qemuxml2argv-video-virtio-gpu-spice-gl.args | 2 +- .../qemuxml2xmlout-video-virtio-gpu-spice-gl.xml | 4 +- 6 files changed, 89 insertions(+), 23 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 6bc2910..a5620d9 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5365,6 +5365,17 @@ qemu-kvm -net nic,model=? /dev/null attribute all <code>listen</code> elements are ignored. </p> </dd> + <dt><code>none</code> <span class="since">since 1.3.5</span></dt> + <dd> + <p> + This listen type doesn't have any other attribute. Libvirt supports + passing a file descriptor through our APIs virDomainOpenGraphics() and + virDomainOpenGraphicsFD(). No other listen types are allowed if this + one is used and the graphics device doesn't listen anywhere. You need + to use one of the two APIs to pass a FD to QEMU in order to connect to + this graphics device. Supported only by <code>spice</code>. + </p> + </dd> </dl> <h4><a name="elementsVideo">Video devices</a></h4> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 60f9f52..70d3e3c 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2981,6 +2981,11 @@ </attribute> </optional> </group> + <group> + <attribute name="type"> + <value>none</value> + </attribute> + </group> </choice> </element> </zeroOrMore> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9b51696..cb05153 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3925,6 +3925,33 @@ virDomainDefPostParseTimer(virDomainDefPtr def) } +static void +virDomainDefPostParseGraphics(virDomainDef *def) +{ + size_t i; + + for (i = 0; i < def->ngraphics; i++) { + virDomainGraphicsDefPtr graphics = def->graphics[i]; + + /* If spice graphics is configured without ports and with autoport='no' + * then we start qemu with Spice to not listen anywhere. Let's convert + * this configuration to the new listen type='none' which does the + * same. */ + if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virDomainGraphicsListenDefPtr glisten = &graphics->listens[0]; + + if (glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS && + graphics->data.spice.port == 0 && + graphics->data.spice.tlsPort == 0 && + !graphics->data.spice.autoport) { + VIR_FREE(glisten->address); + glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE; + } + } + } +} + + /* Check if a drive type address $controller:$bus:$target:$unit is already * taken by a disk or not. */ @@ -4404,6 +4431,8 @@ virDomainDefPostParseInternal(virDomainDefPtr def, /* clean up possibly duplicated metadata entries */ virDomainDefMetadataSanitize(def); + virDomainDefPostParseGraphics(def); + return 0; } @@ -10709,13 +10738,28 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, } def->type = typeVal; - if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET && - graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC && - graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("listen type 'socket' is not available for " - "graphics type '%s'"), graphicsType); - goto error; + switch (def->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("listen type 'socket' is not available for " + "graphics type '%s'"), graphicsType); + goto error; + } + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("listen type 'none' is not available for " + "graphics type '%s'"), graphicsType); + goto error; + } + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; } if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) { @@ -21460,10 +21504,8 @@ virDomainGraphicsListenDefFormat(virBufferPtr buf, return; virBufferAddLit(buf, "<listen"); - if (def->type) { - virBufferAsprintf(buf, " type='%s'", - virDomainGraphicsListenTypeToString(def->type)); - } + virBufferAsprintf(buf, " type='%s'", + virDomainGraphicsListenTypeToString(def->type)); if (def->address && (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS || @@ -21646,6 +21688,10 @@ virDomainGraphicsDefFormat(virBufferPtr buf, break; case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + if (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE) + virBufferAddStr(buf, " autoport='no'"); + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: break; @@ -21667,8 +21713,6 @@ 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) { if (def->listens[i].fromConfig) continue; @@ -21681,6 +21725,13 @@ virDomainGraphicsDefFormat(virBufferPtr buf, def->listens[i].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET && !def->listens[i].autogenerated) continue; + + /* The new listen type none is in the migratable XML represented as + * port=0 and autoport=no because old libvirt support this + * configuration for spice. */ + if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE && + def->listens[i].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE) + continue; } if (!children) { virBufferAddLit(buf, ">\n"); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ba58423..80915ba 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7483,6 +7483,11 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, break; case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + /* QEMU requires either port or tls-port to be specified if there is no + * other argument. Use a dummy port=0. */ + virBufferAddLit(&opt, "port=0,"); + hasInsecure = true; + break; case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: break; } @@ -7630,13 +7635,7 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, virBufferTrim(&opt, ",", -1); virCommandAddArg(cmd, "-spice"); - /* If we did not add any SPICE arguments, add a dummy 'port=0' one - * as -spice alone is not allowed on QEMU command line - */ - if (virBufferUse(&opt) == 0) - virCommandAddArg(cmd, "port=0"); - else - virCommandAddArgBuffer(cmd, &opt); + virCommandAddArgBuffer(cmd, &opt); if (graphics->data.spice.keymap) virCommandAddArgList(cmd, "-k", graphics->data.spice.keymap, NULL); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-spice-gl.args b/tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-spice-gl.args index b80ad16..edecca1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-spice-gl.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-spice-gl.args @@ -19,6 +19,6 @@ QEMU_AUDIO_DRV=spice \ -drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,\ id=drive-ide0-0-0,cache=none \ -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ --spice gl=on \ +-spice port=0,gl=on \ -device virtio-vga,id=video0,virgl=on,bus=pci.0,addr=0x2 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-video-virtio-gpu-spice-gl.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-video-virtio-gpu-spice-gl.xml index a6dddab..9fb533a 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-video-virtio-gpu-spice-gl.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-video-virtio-gpu-spice-gl.xml @@ -29,8 +29,8 @@ <controller type='pci' index='0' model='pci-root'/> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> - <graphics type='spice' autoport='no'> - <listen type='address'/> + <graphics type='spice'> + <listen type='none'/> <gl enable='yes'/> </graphics> <video> -- 2.8.3

Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- docs/formatdomain.html.in | 3 ++- src/conf/domain_conf.c | 3 ++- src/qemu/qemu_command.c | 3 +++ .../qemuxml2argv-graphics-vnc-none.args | 20 +++++++++++++++ .../qemuxml2argv-graphics-vnc-none.xml | 30 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a5620d9..fdc5485 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5373,7 +5373,8 @@ qemu-kvm -net nic,model=? /dev/null virDomainOpenGraphicsFD(). No other listen types are allowed if this one is used and the graphics device doesn't listen anywhere. You need to use one of the two APIs to pass a FD to QEMU in order to connect to - this graphics device. Supported only by <code>spice</code>. + this graphics device. Supported only by <code>vnc</code> and + <code>spice</code>. </p> </dd> </dl> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index cb05153..d2d8301 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10749,7 +10749,8 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, } break; case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: - if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + if (graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE && + graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("listen type 'none' is not available for " "graphics type '%s'"), graphicsType); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 80915ba..9efacd9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7359,6 +7359,9 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, break; case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + virBufferAddLit(&opt, "none"); + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: break; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.args new file mode 100644 index 0000000..69d1991 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.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 none \ +-vga cirrus diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.xml new file mode 100644 index 0000000..72a4819 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-none.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='none'/> + </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 a2920df..ff42169 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -903,6 +903,7 @@ mymain(void) driver.config->vncAutoUnixSocket = false; DO_TEST("graphics-vnc-socket", QEMU_CAPS_VNC); DO_TEST("graphics-vnc-auto-socket", QEMU_CAPS_VNC); + DO_TEST("graphics-vnc-none", QEMU_CAPS_VNC); driver.config->vncSASL = 1; VIR_FREE(driver.config->vncSASLdir); -- 2.8.3
participants (2)
-
Christophe Fergeau
-
Pavel Hrdina