[libvirt] [PATCH v2 06/12] graphics: introduce listen type=socket and use it for VNC

Marc-André Lureau marcandre.lureau at gmail.com
Wed May 11 18:13:37 UTC 2016


 Hi

On Wed, May 11, 2016 at 5:08 PM, Pavel Hrdina <phrdina at redhat.com> 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 at redhat.com>
> ---
>  docs/formatdomain.html.in                          |  16 +++
>  docs/schemas/domaincommon.rng                      |  10 ++
>  src/conf/domain_conf.c                             | 119 ++++++++++++++++-----
>  src/conf/domain_conf.h                             |   8 +-
>  src/libvirt_private.syms                           |   1 +
>  src/qemu/qemu_command.c                            |  45 ++++----
>  src/qemu/qemu_domain.c                             |  19 ++--
>  src/qemu/qemu_hotplug.c                            |   9 ++
>  src/qemu/qemu_parse_command.c                      |   2 +-
>  src/qemu/qemu_process.c                            |  47 ++++++--
>  src/security/virt-aa-helper.c                      |  15 ++-
>  .../generic-graphics-vnc-socket-listen.xml         |   4 +-
>  .../generic-graphics-vnc-socket.xml                |   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 ++++++
>  .../qemuxml2xmlout-graphics-vnc-autosocket.xml     |   4 +-
>  .../qemuxml2xmlout-graphics-vnc-socket.xml         |  35 ++++++
>  tests/qemuxml2xmltest.c                            |   2 +
>  23 files changed, 361 insertions(+), 84 deletions(-)
>  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 b0847b7..f67076d 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -5359,6 +5359,22 @@ qemu-kvm -net nic,model=? /dev/null
>            <code>address</code>.
>          </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 e7eda77..e3dbcc6 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -3014,6 +3014,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 990cab0..fd071e1 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;
> @@ -10786,8 +10787,10 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
>      char *type = virXMLPropString(node, "type");
>      char *address = virXMLPropString(node, "address");
>      char *network = virXMLPropString(node, "network");
> +    char *socket = virXMLPropString(node, "socket");

Missing corresponding VIR_FREE(socket) under error:

>      char *fromConfig = virXMLPropString(node, "fromConfig");
>      char *addressCompat = NULL;
> +    const char *graphicsType = virDomainGraphicsTypeToString(graphics->type);
>      int tmp, typeVal;
>
>      if (parent)
> @@ -10806,6 +10809,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,
> @@ -10840,6 +10851,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) {
> @@ -10883,18 +10905,15 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
>
>      ctxt->node = node;
>
> -    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
> -        (socketPath = virXMLPropString(node, "socket"))) {
> -        ret = 0;
> -        goto error;
> -    }
> +    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC)
> +        socketPath = virXMLPropString(node, "socket");
>
>      /* parse the <listen> subelements for graphics types that support it */
>      nListens = virXPathNodeSet("./listen", ctxt, &listenNodes);
>      if (nListens < 0)
>          goto error;
>
> -    if (nListens > 0) {
> +    if (nListens > 0 && !socketPath) {
>          size_t i;
>
>          if (VIR_ALLOC_N(def->listens, nListens) < 0)
> @@ -10914,14 +10933,20 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
>      } 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 (socketPath) {
> +            newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
> +            newListen.socket = socketPath;
> +            socketPath = NULL;
> +        } else {
> +            newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
> +            newListen.address = virXMLPropString(node, "listen");
> +            if (STREQ_NULLABLE(newListen.address, ""))
> +                VIR_FREE(newListen.address);
>
> -        if (virDomainGraphicsListenDefParsePorts(&newListen, node, def,
> -                                                 NULL, flags) < 0)
> -            goto error;
> +            if (virDomainGraphicsListenDefParsePorts(&newListen, node, def,
> +                                                     NULL, flags) < 0)
> +                goto error;
> +        }
>
>          if (VIR_APPEND_ELEMENT(def->listens, def->nListens, newListen) < 0)
>              goto error;
> @@ -10964,7 +10989,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,
> @@ -21443,6 +21467,13 @@ virDomainGraphicsListenDefFormat(virBufferPtr buf,
>          }
>      }
>
> +    if (def->socket &&
> +        def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
> +        !(def->autogenerated &&
> +          (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) {

I am not familiar with the FORMAT_MIGRATABLE flag

> +        virBufferEscapeString(buf, " socket='%s'", def->socket);
> +    }
> +
>      if (flags & VIR_DOMAIN_DEF_FORMAT_STATUS)
>          virBufferAsprintf(buf, " fromConfig='%d'", def->fromConfig);
>
> @@ -21472,11 +21503,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 (glisten) {
>              if (glisten->port &&
> @@ -21584,9 +21621,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);
> @@ -23909,6 +23956,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 3247177..0eba888 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1539,6 +1539,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;
> @@ -1555,6 +1556,7 @@ struct _virDomainGraphicsListenDef {
>      virDomainGraphicsListenType type;
>      char *address;
>      char *network;
> +    char *socket;
>      bool fromConfig;    /* true if the @address is config file originated */
>      int port;
>      int tlsPort;
> @@ -1562,6 +1564,7 @@ struct _virDomainGraphicsListenDef {
>      bool autoport;
>      bool portReserved;
>      bool tlsPortReserved;
> +    bool autogenerated;
>  };
>
>  struct _virDomainGraphicsDef {
> @@ -1574,8 +1577,6 @@ struct _virDomainGraphicsDef {
>      union {
>          struct {
>              char *keymap;
> -            char *socket;
> -            bool socketAutogenerated;
>              virDomainGraphicsAuthDef auth;
>              int sharePolicy;
>          } vnc;
> @@ -2840,6 +2841,9 @@ int virDomainGraphicsListenAppendAddress(virDomainGraphicsDefPtr def,
>                                           const int websocket,
>                                           const bool autoport)
>              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 a980a32..4b8b2de 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_command.c b/src/qemu/qemu_command.c
> index 16fa068..13df7cb 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -7373,8 +7373,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;
> @@ -7389,24 +7388,19 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
>          goto error;
>      }
>
> -    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;
> -        }
> -
> -        virBufferAsprintf(&opt, "unix:%s", graphics->data.vnc.socket);
> +    if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("missing listen element"));
> +        goto error;
> +    }
>
> -    } else {
> -        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:
> +        virBufferAsprintf(&opt, "unix:%s", glisten->socket);
> +        break;
>
> +    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
> +    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
>          if (!glisten->autoport &&
>              (glisten->port < 5900 ||
>               glisten->port > 65535)) {
> @@ -7442,6 +7436,7 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
>              break;
>
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
>              break;
>          }
> @@ -7467,6 +7462,11 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
>              }
>              virBufferAsprintf(&opt, ",websocket=%d", glisten->websocket);
>          }
> +        break;
> +
> +    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
> +        break;
>      }
>
>      if (graphics->data.vnc.sharePolicy) {
> @@ -7603,6 +7603,7 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
>              break;
>
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
>              break;
>          }
> @@ -7781,8 +7782,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:
> @@ -7814,8 +7814,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);
> @@ -9543,7 +9542,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 3da0079..0068c33 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -1993,17 +1993,22 @@ 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);
> -            else
> -                graphics->data.vnc.socketAutogenerated = true;
> +        for (j = 0; j < graphics->nListens; ++j) {
> +            virDomainGraphicsListenDefPtr glisten =  &graphics->listens[j];
> +
> +            if (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);
> +                else
> +                    glisten->autogenerated = true;
> +            }
>          }
>      }
>  }
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 06033df..53cf8e1 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -2675,6 +2675,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 429cc45..a3c73e1 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 9f96545..3d78455 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -3864,9 +3864,6 @@ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
>      unsigned short port;
>      size_t i;
>
> -    if (graphics->data.vnc.socket)
> -        return 0;
> -
>      for (i = 0; i < graphics->nListens; i++) {
>          virDomainGraphicsListenDefPtr glisten = &graphics->listens[i];
>
> @@ -3892,6 +3889,7 @@ qemuProcessVNCAllocatePorts(virQEMUDriverPtr driver,
>              break;
>
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
>              break;
>          }
> @@ -3990,6 +3988,7 @@ qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
>              break;
>
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
>          case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
>              break;
>          }
> @@ -4424,6 +4423,7 @@ qemuProcessSetupGraphics(virQEMUDriverPtr driver,
>                           unsigned int flags)
>  {
>      virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
>      bool allocate = !(flags & VIR_QEMU_PROCESS_START_PRETEND);
>      size_t i, j;
>      int ret = -1;
> @@ -4433,6 +4433,7 @@ qemuProcessSetupGraphics(virQEMUDriverPtr driver,
>
>      for (i = 0; i < vm->def->ngraphics; ++i) {
>          virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
> +        const char *type = virDomainGraphicsTypeToString(graphics->type);
>          char *listenAddr = NULL;
>
>          switch (graphics->type) {
> @@ -4460,12 +4461,39 @@ qemuProcessSetupGraphics(virQEMUDriverPtr driver,
>          for (j = 0; j < graphics->nListens; j++) {
>              virDomainGraphicsListenDefPtr glisten = &graphics->listens[j];
>
> -            if (glisten->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS &&
> -                !glisten->address && listenAddr) {
> -                if (VIR_STRDUP(glisten->address, listenAddr) < 0)
> -                    goto cleanup;
> -
> -                glisten->fromConfig = true;
> +            switch (glisten->type) {
> +            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
> +                if (!glisten->address) {
> +                    /* If there is no address specified and qemu.conf has
> +                     * vnc_auto_unix_socket set we should use unix socket as
> +                     * default instead of tcp listen. */
> +                    if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
> +                        cfg->vncAutoUnixSocket) {
> +                        memset(glisten, 0, sizeof(virDomainGraphicsListenDef));

Why not calling virDomainGraphicsListenDefClear() ?

> +                        if (virAsprintf(&glisten->socket, "%s/%s.sock",
> +                                        priv->libDir, type) < 0)
> +                            goto cleanup;
> +                        glisten->fromConfig = true;
> +                        glisten->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
> +                    } else if (listenAddr) {
> +                        if (VIR_STRDUP(glisten->address, listenAddr) < 0)
> +                            goto cleanup;
> +                        glisten->fromConfig = true;
> +                    }
> +                }
> +                break;
> +            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
> +                if (!glisten->socket) {
> +                    if (virAsprintf(&glisten->socket, "%s/%s.sock",
> +                                    priv->libDir, type) < 0)
> +                        goto cleanup;
> +                    glisten->autogenerated = true;
> +                }
> +                break;
> +            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
> +            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
> +                break;
>              }
>          }
>      }
> @@ -6232,6 +6260,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
>                  break;
>
>              case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
> +            case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
>              case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
>                  break;
>              }
> diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
> index 7eeb4ef..b144250 100644
> --- a/src/security/virt-aa-helper.c
> +++ b/src/security/virt-aa-helper.c
> @@ -1060,10 +1060,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/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/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml b/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml
> index 93daa76..8f2478a 100644
> --- a/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml
> +++ b/tests/qemuargv2xmldata/qemuargv2xml-graphics-vnc-socket.xml
> @@ -25,7 +25,9 @@
>      <controller type='ide' index='0'/>
>      <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'/>
>      </video>
> 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 d1cfbec..43deebd 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -876,6 +876,8 @@ mymain(void)
>      DO_TEST("graphics-vnc-websocket", QEMU_CAPS_VNC, QEMU_CAPS_VNC_WEBSOCKET);
>      DO_TEST("graphics-vnc-policy", QEMU_CAPS_VNC, QEMU_CAPS_VNC_SHARE_POLICY);
>      DO_TEST("graphics-vnc-no-listen-attr", QEMU_CAPS_VNC);
> +    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-autosocket.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-autosocket.xml
> index 7450566..5013b18 100644
> --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-autosocket.xml
> +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-vnc-autosocket.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'/>
> +    <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'/>
> 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 5a43fa9..b67d687 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -434,6 +434,8 @@ mymain(void)
>      DO_TEST("graphics-vnc-sasl");
>      DO_TEST("graphics-vnc-tls");
>      DO_TEST("graphics-vnc-no-listen-attr");
> +    DO_TEST("graphics-vnc-socket");
> +    DO_TEST("graphics-vnc-auto-socket");
>      DO_TEST("graphics-sdl");
>      DO_TEST("graphics-sdl-fullscreen");
>      DO_TEST("graphics-spice");
> --
> 2.8.2
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

Other than that, looks good to me.


-- 
Marc-André Lureau




More information about the libvir-list mailing list