[libvirt] [PATCH v6 05/10] vnc: add support for listen type 'socket'

Ján Tomko jtomko at redhat.com
Thu Jun 9 11:18:22 UTC 2016


On Wed, Jun 08, 2016 at 05:25:43PM +0200, Pavel Hrdina wrote:
> VNC graphics already supports sockets but only via 'socket' attribute.
> This patch coverts that attribute into listen type 'socket'.
> 
> For backward compatibility we need to handle listen type 'socket' and 'socket'
> attribute properly to support old XMLs and new XMLs.  If both are provided they
> have to match, if only one of them is provided we need to be able to parse that
> configuration too.
> 
> To not break migration back to old libvirt if the socket is provided by user we
> need to generate migratable XML without the listen element and use only 'socket'
> attribute.
> 
> Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
> ---
>  docs/formatdomain.html.in                          |   8 ++
>  src/conf/domain_conf.c                             | 103 +++++++++++++++++----
>  src/conf/domain_conf.h                             |   2 -
>  src/qemu/qemu_command.c                            |  22 ++++-
>  src/qemu/qemu_domain.c                             |  28 ++++--
>  src/qemu/qemu_parse_command.c                      |   2 +-
>  src/qemu/qemu_process.c                            |  10 +-
>  ...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 +
>  25 files changed, 426 insertions(+), 57 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
> 

> +    /* 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. */

*attribute

> +        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;

> @@ -21906,9 +21955,23 @@ 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 the listen is based on config options from qemu.conf we need
> +             * to skip it.  It's up to user to properly configure both host for

*hosts

> +             * migration. */
> +            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.  Auto-generated socket is a new feature
> +             * thus we can generate it in the migrateble XML. */
> +            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);
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 05dbfc2..3792562 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1454,8 +1454,6 @@ struct _virDomainGraphicsDef {
>              int websocket;
>              bool autoport;
>              char *keymap;
> -            char *socket;

This is also referenced in vz_sdk.c:

    if (gr->data.vnc.socket) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("vz driver doesn't support "
                         "VNC graphics over unix sockets."));
        return -1;
    }

But since the new code copies the socket to listens[0] and a later check
rejects non-address based listens, it can be safely dropped.

> -            bool socketFromConfig;
>              virDomainGraphicsAuthDef auth;
>              int sharePolicy;
>          } vnc;
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 6a086eb..1d25655 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -7224,13 +7224,20 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
>          goto error;
>      }
>  
> -    glisten = virDomainGraphicsGetListen(graphics, 0);
> +    if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("missing listen element"));
> +        goto error;
> +    }
>  
> -    if (graphics->data.vnc.socket) {
> +    switch (glisten->type) {

switch ((virDomainGraphicsListenType) 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)) {

> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 5e66c31..3eb1403 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -3469,9 +3469,6 @@ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
>  {
>      unsigned short port;
>  
> -    if (graphics->data.vnc.socket)
> -        return 0;
> -

This check should be adjusted to look for TYPE_SOCKET in listens[0],
we do not need a TCP port in that case.

>      if (!allocate) {
>          if (graphics->data.vnc.autoport)
>              graphics->data.vnc.port = 5900;

ACK

Jan




More information about the libvir-list mailing list