[libvirt] [PATCH v3 2/2] qemu: Add VNC WebSocket support

Guannan Ren gren at redhat.com
Tue May 14 07:15:13 UTC 2013


On 05/13/2013 09:10 PM, Martin Kletzander wrote:
> Adding a VNC WebSocket support for QEMU driver.  This functionality is
> in upstream qemu from commit described as v1.3.0-982-g7536ee4, so the
> capability is being recognized based on QEMU version for now.
>
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
>   src/qemu/libvirtd_qemu.aug                         |  2 +
>   src/qemu/qemu.conf                                 |  6 +++
>   src/qemu/qemu_capabilities.c                       |  5 ++
>   src/qemu/qemu_capabilities.h                       |  1 +
>   src/qemu/qemu_command.c                            | 60 +++++++++++++++++++++-
>   src/qemu/qemu_command.h                            |  3 ++
>   src/qemu/qemu_conf.c                               | 32 ++++++++++++
>   src/qemu/qemu_conf.h                               |  6 +++
>   src/qemu/qemu_driver.c                             |  5 ++
>   src/qemu/qemu_process.c                            | 44 ++++++++++++----
>   src/qemu/test_libvirtd_qemu.aug.in                 |  2 +
>   tests/qemuargv2xmltest.c                           |  1 +
>   .../qemuxml2argv-graphics-vnc-websocket.args       |  4 ++
>   .../qemuxml2argv-graphics-vnc-websocket.xml        | 28 ++++++++++
>   tests/qemuxml2argvtest.c                           |  1 +
>   tests/qemuxml2xmltest.c                            |  1 +
>   16 files changed, 189 insertions(+), 12 deletions(-)
>   create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-websocket.args
>   create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-websocket.xml
>
> diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
> index a3dcb30..5344125 100644
> --- a/src/qemu/libvirtd_qemu.aug
> +++ b/src/qemu/libvirtd_qemu.aug
> @@ -41,6 +41,8 @@ module Libvirtd_qemu =
>
>      let remote_display_entry = int_entry "remote_display_port_min"
>                    | int_entry "remote_display_port_max"
> +                 | int_entry "remote_websocket_port_min"
> +                 | int_entry "remote_websocket_port_max"
>
>      let security_entry = str_entry "security_driver"
>                    | bool_entry "security_default_confined"
> diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
> index 0f0a24c..cdf1ec4 100644
> --- a/src/qemu/qemu.conf
> +++ b/src/qemu/qemu.conf
> @@ -153,6 +153,12 @@
>   #remote_display_port_min = 5900
>   #remote_display_port_max = 65535
>
> +# VNC WebSocket port policies, same rules apply as with remote display
> +# ports.  VNC WebSockets use similar display <-> port mappings, with
> +# the exception being that ports starts from 5700 instead of 5900.
> +#
> +#remote_websocket_port_min = 5700
> +#remote_websocket_port_max = 65535
>
>   # The default security driver is SELinux. If SELinux is disabled
>   # on the host, then the security driver will automatically disable
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 74ac43c..18ebe14 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -227,6 +227,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
>                 "scsi-generic",
>
>                 "scsi-generic.bootindex", /* 145 */
> +              "vnc-websocket",
>       );
>
>   struct _virQEMUCaps {
> @@ -2567,6 +2568,10 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
>       if (qemuCaps->version >= 1003000)
>           virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT);
>
> +    /* WebSockets were introduced between 1.3.0 and 1.3.1 */
> +    if (qemuCaps->version >= 1003001)
> +        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET);
> +
>       if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
>           goto cleanup;
>       if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index a9eea4e..4b07b75 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -184,6 +184,7 @@ enum virQEMUCapsFlags {
>       QEMU_CAPS_VFIO_PCI_BOOTINDEX = 143, /* bootindex param for vfio-pci device */
>       QEMU_CAPS_DEVICE_SCSI_GENERIC = 144,  /* -device scsi-generic */
>       QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX = 145,  /* -device scsi-generic.bootindex */
> +    QEMU_CAPS_VNC_WEBSOCKET      = 146, /* -vnc x:y,websocket */
>
>       QEMU_CAPS_LAST,                   /* this must always be the last item */
>   };
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index eddc263..7d80e74 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -6070,6 +6070,17 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
>           }
>       }
>
> +    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);
> +    }
> +

           I think the above block should be moved in
           if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
               if (graphics->data.vnc.websocket)
               ...
          }


>
> @@ -9915,6 +9928,49 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
>                       virDomainGraphicsDefFree(vnc);
>                       goto no_memory;
>                   }
> +
> +                if (*opts == ',') {
> +                    char *orig_opts = strdup(opts + 1);
> +                    if (!orig_opts) {
> +                        virDomainGraphicsDefFree(vnc);
> +                        goto no_memory;
> +                    }
> +                    opts = orig_opts;
> +
> +                    while (opts && *opts) {
> +                        char *nextopt = strchr(opts, ',');
> +                        if (nextopt)
> +                            *(nextopt++) = '\0';
> +
> +                        if (STRPREFIX(opts, "websocket")) {
> +                            char *websocket = opts + strlen("websocket");
> +                            if (*(websocket++) == '=' &&
> +                                *websocket) {
> +                                /* If the websocket continues with
> +                                 * '=<something>', we'll parse it */
> +                                if (virStrToLong_i(websocket,
> +                                                   NULL, 0,
> +                                                   &vnc->data.vnc.websocket) < 0) {
> +                                    virReportError(VIR_ERR_INTERNAL_ERROR,
> +                                                   _("cannot parse VNC "
> +                                                     "WebSocket port '%s'"),
> +                                                   websocket);
> +                                    virDomainGraphicsDefFree(vnc);
> +                                    VIR_FREE(orig_opts);

              missing goto error, but still nice parsing

              The rest is good for me. I use noVNC to connect it, it 
works well.
              Right now, the 'autoport' attribute only manages automatic 
port allocation for 'port'.
              'websocket' doesn't use it, -1 means auto port allocation 
itself.
              If we should change doc to avoid confusing.

              ACK with above fixed.

              Guannan




More information about the libvir-list mailing list