* [Qemu-devel] [PATCH v2 01/10] vnc: remove vnc_display global
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-11 1:58 ` Gonglei
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 02/10] vnc: remove unused DisplayState parameter, add id instead Gerd Hoffmann
` (8 subsequent siblings)
9 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori
Replace with a vnc_displays list, so we can have multiple vnc server
instances. Add vnc_server_find function to lookup a display by id.
With no id supplied return the first vnc server, for backward
compatibility reasons.
It is not possible (yet) to actually create mutiple vnc server
instances.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc.c | 63 +++++++++++++++++++++++++++++++++++++++++----------------------
ui/vnc.h | 2 ++
2 files changed, 43 insertions(+), 22 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 5707015..a6549c8 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -46,7 +46,8 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
#include "vnc_keysym.h"
#include "d3des.h"
-static VncDisplay *vnc_display; /* needed for info vnc */
+static QTAILQ_HEAD(, VncDisplay) vnc_displays =
+ QTAILQ_HEAD_INITIALIZER(vnc_displays);
static int vnc_cursor_define(VncState *vs);
static void vnc_release_modifiers(VncState *vs);
@@ -226,10 +227,10 @@ static const char *vnc_auth_name(VncDisplay *vd) {
return "unknown";
}
-static VncServerInfo *vnc_server_info_get(void)
+static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
{
VncServerInfo *info;
- VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vnc_display->lsock);
+ VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock);
if (!bi) {
return NULL;
}
@@ -237,7 +238,7 @@ static VncServerInfo *vnc_server_info_get(void)
info = g_malloc(sizeof(*info));
info->base = bi;
info->has_auth = true;
- info->auth = g_strdup(vnc_auth_name(vnc_display));
+ info->auth = g_strdup(vnc_auth_name(vd));
return info;
}
@@ -282,7 +283,7 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
}
g_assert(vs->info->base);
- si = vnc_server_info_get();
+ si = vnc_server_info_get(vs->vd);
if (!si) {
return;
}
@@ -345,11 +346,27 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
return info;
}
+static VncDisplay *vnc_display_find(const char *id)
+{
+ VncDisplay *vd;
+
+ if (id == NULL) {
+ return QTAILQ_FIRST(&vnc_displays);
+ }
+ QTAILQ_FOREACH(vd, &vnc_displays, next) {
+ if (strcmp(id, vd->id) == 0) {
+ return vd;
+ }
+ }
+ return NULL;
+}
+
VncInfo *qmp_query_vnc(Error **errp)
{
VncInfo *info = g_malloc0(sizeof(*info));
+ VncDisplay *vd = vnc_display_find(NULL);
- if (vnc_display == NULL || vnc_display->display == NULL) {
+ if (vd == NULL || vd->display == NULL) {
info->enabled = false;
} else {
VncClientInfoList *cur_item = NULL;
@@ -364,7 +381,7 @@ VncInfo *qmp_query_vnc(Error **errp)
/* for compatibility with the original command */
info->has_clients = true;
- QTAILQ_FOREACH(client, &vnc_display->clients, next) {
+ QTAILQ_FOREACH(client, &vd->clients, next) {
VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
cinfo->value = qmp_query_vnc_client(client);
@@ -377,11 +394,11 @@ VncInfo *qmp_query_vnc(Error **errp)
}
}
- if (vnc_display->lsock == -1) {
+ if (vd->lsock == -1) {
return info;
}
- if (getsockname(vnc_display->lsock, (struct sockaddr *)&sa,
+ if (getsockname(vd->lsock, (struct sockaddr *)&sa,
&salen) == -1) {
error_set(errp, QERR_UNDEFINED_ERROR);
goto out_error;
@@ -405,7 +422,7 @@ VncInfo *qmp_query_vnc(Error **errp)
info->family = inet_netfamily(sa.ss_family);
info->has_auth = true;
- info->auth = g_strdup(vnc_auth_name(vnc_display));
+ info->auth = g_strdup(vnc_auth_name(vd));
}
return info;
@@ -853,7 +870,7 @@ static int vnc_cursor_define(VncState *vs)
static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
QEMUCursor *c)
{
- VncDisplay *vd = vnc_display;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs;
cursor_put(vd->cursor);
@@ -2818,6 +2835,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
int i;
vs->csock = csock;
+ vs->vd = vd;
if (skipauth) {
vs->auth = VNC_AUTH_NONE;
@@ -2862,8 +2880,6 @@ static void vnc_connect(VncDisplay *vd, int csock,
vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
- vs->vd = vd;
-
#ifdef CONFIG_VNC_WS
if (!vs->websocket)
#endif
@@ -2955,7 +2971,7 @@ void vnc_display_init(DisplayState *ds)
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
- vnc_display = vs;
+ QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
vs->lsock = -1;
#ifdef CONFIG_VNC_WS
@@ -2985,7 +3001,7 @@ void vnc_display_init(DisplayState *ds)
static void vnc_display_close(DisplayState *ds)
{
- VncDisplay *vs = vnc_display;
+ VncDisplay *vs = vnc_display_find(NULL);
if (!vs)
return;
@@ -3014,7 +3030,7 @@ static void vnc_display_close(DisplayState *ds)
int vnc_display_password(DisplayState *ds, const char *password)
{
- VncDisplay *vs = vnc_display;
+ VncDisplay *vs = vnc_display_find(NULL);
if (!vs) {
return -EINVAL;
@@ -3033,7 +3049,7 @@ int vnc_display_password(DisplayState *ds, const char *password)
int vnc_display_pw_expire(DisplayState *ds, time_t expires)
{
- VncDisplay *vs = vnc_display;
+ VncDisplay *vs = vnc_display_find(NULL);
if (!vs) {
return -EINVAL;
@@ -3045,14 +3061,14 @@ int vnc_display_pw_expire(DisplayState *ds, time_t expires)
char *vnc_display_local_addr(DisplayState *ds)
{
- VncDisplay *vs = vnc_display;
-
+ VncDisplay *vs = vnc_display_find(NULL);
+
return vnc_socket_local_addr("%s:%s", vs->lsock);
}
void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
{
- VncDisplay *vs = vnc_display;
+ VncDisplay *vs = vnc_display_find(NULL);
const char *options;
int password = 0;
int reverse = 0;
@@ -3068,7 +3084,7 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
#endif
int lock_key_sync = 1;
- if (!vnc_display) {
+ if (!vs) {
error_setg(errp, "VNC display not active");
return;
}
@@ -3367,7 +3383,10 @@ fail:
void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
{
- VncDisplay *vs = vnc_display;
+ VncDisplay *vs = vnc_display_find(NULL);
+ if (!vs) {
+ return;
+ }
vnc_connect(vs, csock, skipauth, false);
}
diff --git a/ui/vnc.h b/ui/vnc.h
index 334de9d..6fe8278 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -171,6 +171,8 @@ struct VncDisplay
struct VncSurface guest; /* guest visible surface (aka ds->surface) */
pixman_image_t *server; /* vnc server surface */
+ const char *id;
+ QTAILQ_ENTRY(VncDisplay) next;
char *display;
char *password;
time_t expires;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 01/10] vnc: remove vnc_display global
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 01/10] vnc: remove vnc_display global Gerd Hoffmann
@ 2014-12-11 1:58 ` Gonglei
0 siblings, 0 replies; 29+ messages in thread
From: Gonglei @ 2014-12-11 1:58 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel, Anthony Liguori
On 2014/12/10 17:37, Gerd Hoffmann wrote:
> Replace with a vnc_displays list, so we can have multiple vnc server
> instances. Add vnc_server_find function to lookup a display by id.
> With no id supplied return the first vnc server, for backward
> compatibility reasons.
>
> It is not possible (yet) to actually create mutiple vnc server
s/mutiple/multiple/
> instances.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> ui/vnc.c | 63 +++++++++++++++++++++++++++++++++++++++++----------------------
> ui/vnc.h | 2 ++
> 2 files changed, 43 insertions(+), 22 deletions(-)
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 02/10] vnc: remove unused DisplayState parameter, add id instead.
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 01/10] vnc: remove vnc_display global Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-11 1:59 ` Gonglei
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 03/10] vnc: add display id to acl names Gerd Hoffmann
` (7 subsequent siblings)
9 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Gerd Hoffmann, Anthony Liguori
DisplayState isn't used anywhere, drop it. Add the vnc server ID as
parameter instead, so it is possible to specify the server instance.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 16 ++++++++--------
ui/vnc.c | 29 ++++++++++++++---------------
vl.c | 7 ++++---
3 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index 22ef8ca..5ff2e27 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -327,19 +327,19 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
void cocoa_display_init(DisplayState *ds, int full_screen);
/* vnc.c */
-void vnc_display_init(DisplayState *ds);
-void vnc_display_open(DisplayState *ds, const char *display, Error **errp);
-void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth);
-char *vnc_display_local_addr(DisplayState *ds);
+void vnc_display_init(const char *id);
+void vnc_display_open(const char *id, const char *display, Error **errp);
+void vnc_display_add_client(const char *id, int csock, bool skipauth);
+char *vnc_display_local_addr(const char *id);
#ifdef CONFIG_VNC
-int vnc_display_password(DisplayState *ds, const char *password);
-int vnc_display_pw_expire(DisplayState *ds, time_t expires);
+int vnc_display_password(const char *id, const char *password);
+int vnc_display_pw_expire(const char *id, time_t expires);
#else
-static inline int vnc_display_password(DisplayState *ds, const char *password)
+static inline int vnc_display_password(const char *id, const char *password)
{
return -ENODEV;
}
-static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
+static inline int vnc_display_pw_expire(const char *id, time_t expires)
{
return -ENODEV;
};
diff --git a/ui/vnc.c b/ui/vnc.c
index a6549c8..fce4861 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2967,10 +2967,11 @@ static const DisplayChangeListenerOps dcl_ops = {
.dpy_cursor_define = vnc_dpy_cursor_define,
};
-void vnc_display_init(DisplayState *ds)
+void vnc_display_init(const char *id)
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
+ vs->id = strdup(id);
QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
vs->lsock = -1;
@@ -2999,10 +3000,8 @@ void vnc_display_init(DisplayState *ds)
}
-static void vnc_display_close(DisplayState *ds)
+static void vnc_display_close(VncDisplay *vs)
{
- VncDisplay *vs = vnc_display_find(NULL);
-
if (!vs)
return;
g_free(vs->display);
@@ -3028,9 +3027,9 @@ static void vnc_display_close(DisplayState *ds)
#endif
}
-int vnc_display_password(DisplayState *ds, const char *password)
+int vnc_display_password(const char *id, const char *password)
{
- VncDisplay *vs = vnc_display_find(NULL);
+ VncDisplay *vs = vnc_display_find(id);
if (!vs) {
return -EINVAL;
@@ -3047,9 +3046,9 @@ int vnc_display_password(DisplayState *ds, const char *password)
return 0;
}
-int vnc_display_pw_expire(DisplayState *ds, time_t expires)
+int vnc_display_pw_expire(const char *id, time_t expires)
{
- VncDisplay *vs = vnc_display_find(NULL);
+ VncDisplay *vs = vnc_display_find(id);
if (!vs) {
return -EINVAL;
@@ -3059,16 +3058,16 @@ int vnc_display_pw_expire(DisplayState *ds, time_t expires)
return 0;
}
-char *vnc_display_local_addr(DisplayState *ds)
+char *vnc_display_local_addr(const char *id)
{
- VncDisplay *vs = vnc_display_find(NULL);
+ VncDisplay *vs = vnc_display_find(id);
return vnc_socket_local_addr("%s:%s", vs->lsock);
}
-void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
+void vnc_display_open(const char *id, const char *display, Error **errp)
{
- VncDisplay *vs = vnc_display_find(NULL);
+ VncDisplay *vs = vnc_display_find(id);
const char *options;
int password = 0;
int reverse = 0;
@@ -3088,7 +3087,7 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
error_setg(errp, "VNC display not active");
return;
}
- vnc_display_close(ds);
+ vnc_display_close(vs);
if (strcmp(display, "none") == 0)
return;
@@ -3381,9 +3380,9 @@ fail:
#endif /* CONFIG_VNC_WS */
}
-void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
+void vnc_display_add_client(const char *id, int csock, bool skipauth)
{
- VncDisplay *vs = vnc_display_find(NULL);
+ VncDisplay *vs = vnc_display_find(id);
if (!vs) {
return;
diff --git a/vl.c b/vl.c
index eb89d62..08b73ee 100644
--- a/vl.c
+++ b/vl.c
@@ -4323,8 +4323,9 @@ int main(int argc, char **argv, char **envp)
/* init remote displays */
if (vnc_display) {
Error *local_err = NULL;
- vnc_display_init(ds);
- vnc_display_open(ds, vnc_display, &local_err);
+ const char *id = "default";
+ vnc_display_init(id);
+ vnc_display_open(id, vnc_display, &local_err);
if (local_err != NULL) {
error_report("Failed to start VNC server on `%s': %s",
vnc_display, error_get_pretty(local_err));
@@ -4333,7 +4334,7 @@ int main(int argc, char **argv, char **envp)
}
if (show_vnc_port) {
- printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
+ printf("VNC server running on `%s'\n", vnc_display_local_addr(id));
}
}
#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 02/10] vnc: remove unused DisplayState parameter, add id instead.
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 02/10] vnc: remove unused DisplayState parameter, add id instead Gerd Hoffmann
@ 2014-12-11 1:59 ` Gonglei
0 siblings, 0 replies; 29+ messages in thread
From: Gonglei @ 2014-12-11 1:59 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Paolo Bonzini, qemu-devel, Anthony Liguori
On 2014/12/10 17:37, Gerd Hoffmann wrote:
> DisplayState isn't used anywhere, drop it. Add the vnc server ID as
> parameter instead, so it is possible to specify the server instance.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> include/ui/console.h | 16 ++++++++--------
> ui/vnc.c | 29 ++++++++++++++---------------
> vl.c | 7 ++++---
> 3 files changed, 26 insertions(+), 26 deletions(-)
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 03/10] vnc: add display id to acl names
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 01/10] vnc: remove vnc_display global Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 02/10] vnc: remove unused DisplayState parameter, add id instead Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-11 2:09 ` Gonglei
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 04/10] vnc: switch to QemuOpts, allow multiple servers Gerd Hoffmann
` (6 subsequent siblings)
9 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori
In case the display id is "default" (which is the one you get if you
don't explicitly assign one) we keep the old name scheme, without
display, for backward compatibility reasons.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index fce4861..1b86365 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3206,18 +3206,36 @@ void vnc_display_open(const char *id, const char *display, Error **errp)
#ifdef CONFIG_VNC_TLS
if (acl && x509 && vs->tls.x509verify) {
- if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
+ char *aclname;
+
+ if (strcmp(vs->id, "default") == 0) {
+ aclname = g_strdup("vnc.x509dname");
+ } else {
+ aclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
+ }
+ vs->tls.acl = qemu_acl_init(aclname);
+ if (!vs->tls.acl) {
fprintf(stderr, "Failed to create x509 dname ACL\n");
exit(1);
}
+ g_free(aclname);
}
#endif
#ifdef CONFIG_VNC_SASL
if (acl && sasl) {
- if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
+ char *aclname;
+
+ if (strcmp(vs->id, "default") == 0) {
+ aclname = g_strdup("vnc.username");
+ } else {
+ aclname = g_strdup_printf("vnc.%s.username", vs->id);
+ }
+ vs->sasl.acl = qemu_acl_init(aclname);
+ if (!vs->sasl.acl) {
fprintf(stderr, "Failed to create username ACL\n");
exit(1);
}
+ g_free(aclname);
}
#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 04/10] vnc: switch to QemuOpts, allow multiple servers
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (2 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 03/10] vnc: add display id to acl names Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-11 2:59 ` Gonglei
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 05/10] vnc: allow binding servers to qemu consoles Gerd Hoffmann
` (5 subsequent siblings)
9 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Gerd Hoffmann, Anthony Liguori, Luiz Capitulino
This patch switches vnc over to QemuOpts, and it (more or less
as side effect) allows multiple vnc server instances.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 4 +-
qmp.c | 15 ++-
ui/vnc.c | 271 ++++++++++++++++++++++++++++++++-------------------
vl.c | 42 +++-----
4 files changed, 200 insertions(+), 132 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index 5ff2e27..887ed91 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -328,12 +328,14 @@ void cocoa_display_init(DisplayState *ds, int full_screen);
/* vnc.c */
void vnc_display_init(const char *id);
-void vnc_display_open(const char *id, const char *display, Error **errp);
+void vnc_display_open(const char *id, Error **errp);
void vnc_display_add_client(const char *id, int csock, bool skipauth);
char *vnc_display_local_addr(const char *id);
#ifdef CONFIG_VNC
int vnc_display_password(const char *id, const char *password);
int vnc_display_pw_expire(const char *id, time_t expires);
+QemuOpts *vnc_parse_func(const char *str);
+int vnc_init_func(QemuOpts *opts, void *opaque);
#else
static inline int vnc_display_password(const char *id, const char *password)
{
diff --git a/qmp.c b/qmp.c
index 0b4f131..3fda973 100644
--- a/qmp.c
+++ b/qmp.c
@@ -368,7 +368,20 @@ void qmp_change_vnc_password(const char *password, Error **errp)
static void qmp_change_vnc_listen(const char *target, Error **errp)
{
- vnc_display_open(NULL, target, errp);
+ QemuOptsList *olist = qemu_find_opts("vnc");
+ QemuOpts *opts;
+
+ if (strstr(target, "id=")) {
+ error_setg(errp, "id not supported");
+ return;
+ }
+
+ opts = qemu_opts_find(olist, "default");
+ if (opts) {
+ qemu_opts_del(opts);
+ }
+ opts = vnc_parse_func(target);
+ vnc_init_func(opts, NULL);
}
static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
diff --git a/ui/vnc.c b/ui/vnc.c
index 1b86365..cf8bed8 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -31,6 +31,7 @@
#include "qemu/sockets.h"
#include "qemu/timer.h"
#include "qemu/acl.h"
+#include "qemu/config-file.h"
#include "qapi/qmp/types.h"
#include "qmp-commands.h"
#include "qemu/osdep.h"
@@ -2969,7 +2970,12 @@ static const DisplayChangeListenerOps dcl_ops = {
void vnc_display_init(const char *id)
{
- VncDisplay *vs = g_malloc0(sizeof(*vs));
+ VncDisplay *vs;
+
+ if (vnc_display_find(id) != NULL) {
+ return;
+ }
+ vs = g_malloc0(sizeof(*vs));
vs->id = strdup(id);
QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
@@ -3065,14 +3071,65 @@ char *vnc_display_local_addr(const char *id)
return vnc_socket_local_addr("%s:%s", vs->lsock);
}
-void vnc_display_open(const char *id, const char *display, Error **errp)
+static QemuOptsList qemu_vnc_opts = {
+ .name = "vnc",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
+ .implied_opt_name = "vnc",
+ .desc = {
+ {
+ .name = "vnc",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "websocket",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "x509",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "share",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "password",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "reverse",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "lock-key-sync",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "sasl",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "tls",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "x509verify",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "acl",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "lossy",
+ .type = QEMU_OPT_BOOL,
+ },{
+ .name = "non-adaptive",
+ .type = QEMU_OPT_BOOL,
+ },
+ { /* end of list */ }
+ },
+};
+
+void vnc_display_open(const char *id, Error **errp)
{
VncDisplay *vs = vnc_display_find(id);
- const char *options;
+ QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
+ const char *display, *websocket, *share;
int password = 0;
int reverse = 0;
#ifdef CONFIG_VNC_TLS
int tls = 0, x509 = 0;
+ const char *path;
#endif
#ifdef CONFIG_VNC_SASL
int sasl = 0;
@@ -3088,115 +3145,86 @@ void vnc_display_open(const char *id, const char *display, Error **errp)
return;
}
vnc_display_close(vs);
- if (strcmp(display, "none") == 0)
- return;
+ if (!opts) {
+ return;
+ }
+ display = qemu_opt_get(opts, "vnc");
+ if (!display || strcmp(display, "none") == 0) {
+ return;
+ }
vs->display = g_strdup(display);
- vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
-
- options = display;
- while ((options = strchr(options, ','))) {
- options++;
- if (strncmp(options, "password", 8) == 0) {
- if (fips_get_state()) {
- error_setg(errp,
- "VNC password auth disabled due to FIPS mode, "
- "consider using the VeNCrypt or SASL authentication "
- "methods as an alternative");
- goto fail;
- }
- password = 1; /* Require password auth */
- } else if (strncmp(options, "reverse", 7) == 0) {
- reverse = 1;
- } else if (strncmp(options, "no-lock-key-sync", 16) == 0) {
- lock_key_sync = 0;
+
+ password = qemu_opt_get_bool(opts, "password", false);
+ if (password && fips_get_state()) {
+ error_setg(errp,
+ "VNC password auth disabled due to FIPS mode, "
+ "consider using the VeNCrypt or SASL authentication "
+ "methods as an alternative");
+ goto fail;
+ }
+
+ reverse = qemu_opt_get_bool(opts, "reverse", false);
+ lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
#ifdef CONFIG_VNC_SASL
- } else if (strncmp(options, "sasl", 4) == 0) {
- sasl = 1; /* Require SASL auth */
+ sasl = qemu_opt_get_bool(opts, "sasl", false);
#endif
-#ifdef CONFIG_VNC_WS
- } else if (strncmp(options, "websocket", 9) == 0) {
- char *start, *end;
- vs->websocket = 1;
-
- /* Check for 'websocket=<port>' */
- start = strchr(options, '=');
- end = strchr(options, ',');
- if (start && (!end || (start < end))) {
- int len = end ? end-(start+1) : strlen(start+1);
- if (len < 6) {
- /* extract the host specification from display */
- char *host = NULL, *port = NULL, *host_end = NULL;
- port = g_strndup(start + 1, len);
-
- /* ipv6 hosts have colons */
- end = strchr(display, ',');
- host_end = g_strrstr_len(display, end - display, ":");
-
- if (host_end) {
- host = g_strndup(display, host_end - display + 1);
- } else {
- host = g_strndup(":", 1);
- }
- vs->ws_display = g_strconcat(host, port, NULL);
- g_free(host);
- g_free(port);
- }
- }
-#endif /* CONFIG_VNC_WS */
#ifdef CONFIG_VNC_TLS
- } else if (strncmp(options, "tls", 3) == 0) {
- tls = 1; /* Require TLS */
- } else if (strncmp(options, "x509", 4) == 0) {
- char *start, *end;
- x509 = 1; /* Require x509 certificates */
- if (strncmp(options, "x509verify", 10) == 0)
- vs->tls.x509verify = 1; /* ...and verify client certs */
-
- /* Now check for 'x509=/some/path' postfix
- * and use that to setup x509 certificate/key paths */
- start = strchr(options, '=');
- end = strchr(options, ',');
- if (start && (!end || (start < end))) {
- int len = end ? end-(start+1) : strlen(start+1);
- char *path = g_strndup(start + 1, len);
-
- VNC_DEBUG("Trying certificate path '%s'\n", path);
- if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
- error_setg(errp, "Failed to find x509 certificates/keys in %s", path);
- g_free(path);
- goto fail;
- }
- g_free(path);
- } else {
- error_setg(errp, "No certificate path provided");
- goto fail;
- }
+ tls = qemu_opt_get_bool(opts, "tls", false);
+ path = qemu_opt_get(opts, "x509");
+ if (path) {
+ x509 = 1;
+ vs->tls.x509verify = qemu_opt_get_bool(opts, "x509verify", false);
+ if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
+ error_setg(errp, "Failed to find x509 certificates/keys in %s",
+ path);
+ goto fail;
+ }
+ }
#endif
#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
- } else if (strncmp(options, "acl", 3) == 0) {
- acl = 1;
-#endif
- } else if (strncmp(options, "lossy", 5) == 0) {
-#ifdef CONFIG_VNC_JPEG
- vs->lossy = true;
+ acl = qemu_opt_get_bool(opts, "acl", false);
#endif
- } else if (strncmp(options, "non-adaptive", 12) == 0) {
- vs->non_adaptive = true;
- } else if (strncmp(options, "share=", 6) == 0) {
- if (strncmp(options+6, "ignore", 6) == 0) {
- vs->share_policy = VNC_SHARE_POLICY_IGNORE;
- } else if (strncmp(options+6, "allow-exclusive", 15) == 0) {
- vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
- } else if (strncmp(options+6, "force-shared", 12) == 0) {
- vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
- } else {
- error_setg(errp, "unknown vnc share= option");
- goto fail;
- }
+
+ share = qemu_opt_get(opts, "share");
+ if (share) {
+ if (strcmp(share, "ignore") == 0) {
+ vs->share_policy = VNC_SHARE_POLICY_IGNORE;
+ } else if (strcmp(share, "allow-exclusive") == 0) {
+ vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
+ } else if (strcmp(share, "force-shared") == 0) {
+ vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
+ } else {
+ error_setg(errp, "unknown vnc share= option");
+ goto fail;
+ }
+ } else {
+ vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
+ }
+
+ #ifdef CONFIG_VNC_WS
+ websocket = qemu_opt_get(opts, "websocket");
+ if (websocket) {
+ /* extract the host specification from display */
+ char *host = NULL, *host_end = NULL;
+ vs->websocket = 1;
+
+ /* ipv6 hosts have colons */
+ host_end = strrchr(display, ':');
+ if (host_end) {
+ host = g_strndup(display, host_end - display + 1);
+ } else {
+ host = g_strdup(":");
}
+ vs->ws_display = g_strconcat(host, websocket, NULL);
+ g_free(host);
}
+#endif /* CONFIG_VNC_WS */
+#ifdef CONFIG_VNC_JPEG
+ vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
+#endif
+ vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
/* adaptive updates are only used with tight encoding and
* if lossy updates are enabled so we can disable all the
* calculations otherwise */
@@ -3407,3 +3435,44 @@ void vnc_display_add_client(const char *id, int csock, bool skipauth)
}
vnc_connect(vs, csock, skipauth, false);
}
+
+QemuOpts *vnc_parse_func(const char *str)
+{
+ return qemu_opts_parse(qemu_find_opts("vnc"), str, 1);
+}
+
+int vnc_init_func(QemuOpts *opts, void *opaque)
+{
+ Error *local_err = NULL;
+ QemuOptsList *olist = qemu_find_opts("vnc");
+ char *id = (char *)qemu_opts_id(opts);
+
+ if (!id) {
+ /* auto-assign id if not present */
+ int i = 2;
+ id = g_strdup("default");
+ while (qemu_opts_find(olist, id)) {
+ g_free(id);
+ id = g_strdup_printf("vnc%d", i++);
+ }
+ qemu_opts_set_id(opts, id);
+ }
+ fprintf(stderr, "%s: id \"%s\"\n", __func__, id);
+
+ vnc_display_init(id);
+ vnc_display_open(id, &local_err);
+ if (local_err != NULL) {
+ error_report("Failed to start VNC server on `%s': %s",
+ qemu_opt_get(opts, "display"),
+ error_get_pretty(local_err));
+ error_free(local_err);
+ exit(1);
+ }
+ return 0;
+}
+
+static void vnc_register_config(void)
+{
+ qemu_add_opts(&qemu_vnc_opts);
+}
+machine_init(vnc_register_config);
diff --git a/vl.c b/vl.c
index 08b73ee..0bf00cf 100644
--- a/vl.c
+++ b/vl.c
@@ -158,9 +158,6 @@ int smp_cpus = 1;
int max_cpus = 0;
int smp_cores = 1;
int smp_threads = 1;
-#ifdef CONFIG_VNC
-const char *vnc_display;
-#endif
int acpi_enabled = 1;
int no_hpet = 0;
int fd_bootchk = 1;
@@ -2087,16 +2084,12 @@ static DisplayType select_display(const char *p)
#endif
} else if (strstart(p, "vnc", &opts)) {
#ifdef CONFIG_VNC
- display_remote++;
-
- if (*opts) {
- const char *nextopt;
-
- if (strstart(opts, "=", &nextopt)) {
- vnc_display = nextopt;
+ if (*opts == '=') {
+ display_remote++;
+ if (vnc_parse_func(opts+1) == NULL) {
+ exit(1);
}
- }
- if (!vnc_display) {
+ } else {
fprintf(stderr, "VNC requires a display argument vnc=<display>\n");
exit(1);
}
@@ -3563,7 +3556,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_vnc:
#ifdef CONFIG_VNC
display_remote++;
- vnc_display = optarg;
+ if (vnc_parse_func(optarg) == NULL) {
+ exit(1);
+ }
#else
fprintf(stderr, "VNC support is disabled\n");
exit(1);
@@ -4016,7 +4011,7 @@ int main(int argc, char **argv, char **envp)
#elif defined(CONFIG_SDL) || defined(CONFIG_COCOA)
display_type = DT_SDL;
#elif defined(CONFIG_VNC)
- vnc_display = "localhost:0,to=99";
+ vnc_parse_func("localhost:0,to=99,id=default");
show_vnc_port = 1;
#else
display_type = DT_NONE;
@@ -4321,21 +4316,10 @@ int main(int argc, char **argv, char **envp)
#ifdef CONFIG_VNC
/* init remote displays */
- if (vnc_display) {
- Error *local_err = NULL;
- const char *id = "default";
- vnc_display_init(id);
- vnc_display_open(id, vnc_display, &local_err);
- if (local_err != NULL) {
- error_report("Failed to start VNC server on `%s': %s",
- vnc_display, error_get_pretty(local_err));
- error_free(local_err);
- exit(1);
- }
-
- if (show_vnc_port) {
- printf("VNC server running on `%s'\n", vnc_display_local_addr(id));
- }
+ qemu_opts_foreach(qemu_find_opts("vnc"), vnc_init_func, NULL, 0);
+ if (show_vnc_port) {
+ printf("VNC server running on `%s'\n",
+ vnc_display_local_addr("default"));
}
#endif
#ifdef CONFIG_SPICE
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 04/10] vnc: switch to QemuOpts, allow multiple servers
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 04/10] vnc: switch to QemuOpts, allow multiple servers Gerd Hoffmann
@ 2014-12-11 2:59 ` Gonglei
2014-12-11 8:48 ` Gerd Hoffmann
0 siblings, 1 reply; 29+ messages in thread
From: Gonglei @ 2014-12-11 2:59 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Paolo Bonzini, qemu-devel, Anthony Liguori, Luiz Capitulino
On 2014/12/10 17:37, Gerd Hoffmann wrote:
> This patch switches vnc over to QemuOpts, and it (more or less
> as side effect) allows multiple vnc server instances.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> include/ui/console.h | 4 +-
> qmp.c | 15 ++-
> ui/vnc.c | 271 ++++++++++++++++++++++++++++++++-------------------
> vl.c | 42 +++-----
> 4 files changed, 200 insertions(+), 132 deletions(-)
>
> diff --git a/include/ui/console.h b/include/ui/console.h
> index 5ff2e27..887ed91 100644
> --- a/include/ui/console.h
> +++ b/include/ui/console.h
> @@ -328,12 +328,14 @@ void cocoa_display_init(DisplayState *ds, int full_screen);
>
> /* vnc.c */
> void vnc_display_init(const char *id);
> -void vnc_display_open(const char *id, const char *display, Error **errp);
> +void vnc_display_open(const char *id, Error **errp);
> void vnc_display_add_client(const char *id, int csock, bool skipauth);
> char *vnc_display_local_addr(const char *id);
> #ifdef CONFIG_VNC
> int vnc_display_password(const char *id, const char *password);
> int vnc_display_pw_expire(const char *id, time_t expires);
> +QemuOpts *vnc_parse_func(const char *str);
> +int vnc_init_func(QemuOpts *opts, void *opaque);
> #else
> static inline int vnc_display_password(const char *id, const char *password)
> {
> diff --git a/qmp.c b/qmp.c
> index 0b4f131..3fda973 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -368,7 +368,20 @@ void qmp_change_vnc_password(const char *password, Error **errp)
>
> static void qmp_change_vnc_listen(const char *target, Error **errp)
> {
> - vnc_display_open(NULL, target, errp);
> + QemuOptsList *olist = qemu_find_opts("vnc");
> + QemuOpts *opts;
> +
> + if (strstr(target, "id=")) {
> + error_setg(errp, "id not supported");
> + return;
> + }
> +
> + opts = qemu_opts_find(olist, "default");
> + if (opts) {
> + qemu_opts_del(opts);
> + }
> + opts = vnc_parse_func(target);
> + vnc_init_func(opts, NULL);
> }
>
> static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 1b86365..cf8bed8 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -31,6 +31,7 @@
> #include "qemu/sockets.h"
> #include "qemu/timer.h"
> #include "qemu/acl.h"
> +#include "qemu/config-file.h"
> #include "qapi/qmp/types.h"
> #include "qmp-commands.h"
> #include "qemu/osdep.h"
> @@ -2969,7 +2970,12 @@ static const DisplayChangeListenerOps dcl_ops = {
>
> void vnc_display_init(const char *id)
> {
> - VncDisplay *vs = g_malloc0(sizeof(*vs));
> + VncDisplay *vs;
> +
> + if (vnc_display_find(id) != NULL) {
> + return;
> + }
> + vs = g_malloc0(sizeof(*vs));
>
> vs->id = strdup(id);
> QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
> @@ -3065,14 +3071,65 @@ char *vnc_display_local_addr(const char *id)
> return vnc_socket_local_addr("%s:%s", vs->lsock);
> }
>
> -void vnc_display_open(const char *id, const char *display, Error **errp)
> +static QemuOptsList qemu_vnc_opts = {
> + .name = "vnc",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
> + .implied_opt_name = "vnc",
> + .desc = {
> + {
> + .name = "vnc",
> + .type = QEMU_OPT_STRING,
> + },{
> + .name = "websocket",
> + .type = QEMU_OPT_STRING,
> + },{
> + .name = "x509",
> + .type = QEMU_OPT_STRING,
> + },{
> + .name = "share",
> + .type = QEMU_OPT_STRING,
> + },{
> + .name = "password",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "reverse",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "lock-key-sync",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "sasl",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "tls",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "x509verify",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "acl",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "lossy",
> + .type = QEMU_OPT_BOOL,
> + },{
> + .name = "non-adaptive",
> + .type = QEMU_OPT_BOOL,
> + },
> + { /* end of list */ }
> + },
> +};
> +
> +void vnc_display_open(const char *id, Error **errp)
> {
> VncDisplay *vs = vnc_display_find(id);
> - const char *options;
> + QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
> + const char *display, *websocket, *share;
> int password = 0;
> int reverse = 0;
> #ifdef CONFIG_VNC_TLS
> int tls = 0, x509 = 0;
> + const char *path;
> #endif
> #ifdef CONFIG_VNC_SASL
> int sasl = 0;
> @@ -3088,115 +3145,86 @@ void vnc_display_open(const char *id, const char *display, Error **errp)
> return;
> }
> vnc_display_close(vs);
> - if (strcmp(display, "none") == 0)
> - return;
>
> + if (!opts) {
> + return;
> + }
> + display = qemu_opt_get(opts, "vnc");
> + if (!display || strcmp(display, "none") == 0) {
> + return;
> + }
> vs->display = g_strdup(display);
> - vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
> -
> - options = display;
> - while ((options = strchr(options, ','))) {
> - options++;
> - if (strncmp(options, "password", 8) == 0) {
> - if (fips_get_state()) {
> - error_setg(errp,
> - "VNC password auth disabled due to FIPS mode, "
> - "consider using the VeNCrypt or SASL authentication "
> - "methods as an alternative");
> - goto fail;
> - }
> - password = 1; /* Require password auth */
> - } else if (strncmp(options, "reverse", 7) == 0) {
> - reverse = 1;
> - } else if (strncmp(options, "no-lock-key-sync", 16) == 0) {
> - lock_key_sync = 0;
> +
> + password = qemu_opt_get_bool(opts, "password", false);
> + if (password && fips_get_state()) {
> + error_setg(errp,
> + "VNC password auth disabled due to FIPS mode, "
> + "consider using the VeNCrypt or SASL authentication "
> + "methods as an alternative");
> + goto fail;
> + }
> +
> + reverse = qemu_opt_get_bool(opts, "reverse", false);
> + lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
> #ifdef CONFIG_VNC_SASL
> - } else if (strncmp(options, "sasl", 4) == 0) {
> - sasl = 1; /* Require SASL auth */
> + sasl = qemu_opt_get_bool(opts, "sasl", false);
> #endif
> -#ifdef CONFIG_VNC_WS
> - } else if (strncmp(options, "websocket", 9) == 0) {
> - char *start, *end;
> - vs->websocket = 1;
> -
> - /* Check for 'websocket=<port>' */
> - start = strchr(options, '=');
> - end = strchr(options, ',');
> - if (start && (!end || (start < end))) {
> - int len = end ? end-(start+1) : strlen(start+1);
> - if (len < 6) {
> - /* extract the host specification from display */
> - char *host = NULL, *port = NULL, *host_end = NULL;
> - port = g_strndup(start + 1, len);
> -
> - /* ipv6 hosts have colons */
> - end = strchr(display, ',');
> - host_end = g_strrstr_len(display, end - display, ":");
> -
> - if (host_end) {
> - host = g_strndup(display, host_end - display + 1);
> - } else {
> - host = g_strndup(":", 1);
> - }
> - vs->ws_display = g_strconcat(host, port, NULL);
> - g_free(host);
> - g_free(port);
> - }
> - }
> -#endif /* CONFIG_VNC_WS */
> #ifdef CONFIG_VNC_TLS
> - } else if (strncmp(options, "tls", 3) == 0) {
> - tls = 1; /* Require TLS */
> - } else if (strncmp(options, "x509", 4) == 0) {
> - char *start, *end;
> - x509 = 1; /* Require x509 certificates */
> - if (strncmp(options, "x509verify", 10) == 0)
> - vs->tls.x509verify = 1; /* ...and verify client certs */
> -
> - /* Now check for 'x509=/some/path' postfix
> - * and use that to setup x509 certificate/key paths */
> - start = strchr(options, '=');
> - end = strchr(options, ',');
> - if (start && (!end || (start < end))) {
> - int len = end ? end-(start+1) : strlen(start+1);
> - char *path = g_strndup(start + 1, len);
> -
> - VNC_DEBUG("Trying certificate path '%s'\n", path);
> - if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
> - error_setg(errp, "Failed to find x509 certificates/keys in %s", path);
> - g_free(path);
> - goto fail;
> - }
> - g_free(path);
> - } else {
> - error_setg(errp, "No certificate path provided");
> - goto fail;
> - }
> + tls = qemu_opt_get_bool(opts, "tls", false);
> + path = qemu_opt_get(opts, "x509");
> + if (path) {
> + x509 = 1;
> + vs->tls.x509verify = qemu_opt_get_bool(opts, "x509verify", false);
> + if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
> + error_setg(errp, "Failed to find x509 certificates/keys in %s",
> + path);
> + goto fail;
> + }
> + }
> #endif
> #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
> - } else if (strncmp(options, "acl", 3) == 0) {
> - acl = 1;
> -#endif
> - } else if (strncmp(options, "lossy", 5) == 0) {
> -#ifdef CONFIG_VNC_JPEG
> - vs->lossy = true;
> + acl = qemu_opt_get_bool(opts, "acl", false);
> #endif
> - } else if (strncmp(options, "non-adaptive", 12) == 0) {
> - vs->non_adaptive = true;
> - } else if (strncmp(options, "share=", 6) == 0) {
> - if (strncmp(options+6, "ignore", 6) == 0) {
> - vs->share_policy = VNC_SHARE_POLICY_IGNORE;
> - } else if (strncmp(options+6, "allow-exclusive", 15) == 0) {
> - vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
> - } else if (strncmp(options+6, "force-shared", 12) == 0) {
> - vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
> - } else {
> - error_setg(errp, "unknown vnc share= option");
> - goto fail;
> - }
> +
> + share = qemu_opt_get(opts, "share");
> + if (share) {
> + if (strcmp(share, "ignore") == 0) {
> + vs->share_policy = VNC_SHARE_POLICY_IGNORE;
> + } else if (strcmp(share, "allow-exclusive") == 0) {
> + vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
> + } else if (strcmp(share, "force-shared") == 0) {
> + vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
> + } else {
> + error_setg(errp, "unknown vnc share= option");
> + goto fail;
> + }
> + } else {
> + vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
> + }
> +
> + #ifdef CONFIG_VNC_WS
> + websocket = qemu_opt_get(opts, "websocket");
> + if (websocket) {
> + /* extract the host specification from display */
> + char *host = NULL, *host_end = NULL;
> + vs->websocket = 1;
> +
> + /* ipv6 hosts have colons */
> + host_end = strrchr(display, ':');
> + if (host_end) {
> + host = g_strndup(display, host_end - display + 1);
> + } else {
> + host = g_strdup(":");
> }
> + vs->ws_display = g_strconcat(host, websocket, NULL);
> + g_free(host);
> }
> +#endif /* CONFIG_VNC_WS */
>
> +#ifdef CONFIG_VNC_JPEG
> + vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
> +#endif
> + vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
> /* adaptive updates are only used with tight encoding and
> * if lossy updates are enabled so we can disable all the
> * calculations otherwise */
> @@ -3407,3 +3435,44 @@ void vnc_display_add_client(const char *id, int csock, bool skipauth)
> }
> vnc_connect(vs, csock, skipauth, false);
> }
> +
> +QemuOpts *vnc_parse_func(const char *str)
> +{
> + return qemu_opts_parse(qemu_find_opts("vnc"), str, 1);
> +}
> +
> +int vnc_init_func(QemuOpts *opts, void *opaque)
> +{
> + Error *local_err = NULL;
> + QemuOptsList *olist = qemu_find_opts("vnc");
> + char *id = (char *)qemu_opts_id(opts);
> +
> + if (!id) {
> + /* auto-assign id if not present */
> + int i = 2;
> + id = g_strdup("default");
> + while (qemu_opts_find(olist, id)) {
> + g_free(id);
> + id = g_strdup_printf("vnc%d", i++);
> + }
> + qemu_opts_set_id(opts, id);
> + }
> + fprintf(stderr, "%s: id \"%s\"\n", __func__, id);
A debug message, isn't it?
> +
> + vnc_display_init(id);
> + vnc_display_open(id, &local_err);
> + if (local_err != NULL) {
> + error_report("Failed to start VNC server on `%s': %s",
> + qemu_opt_get(opts, "display"),
> + error_get_pretty(local_err));
> + error_free(local_err);
> + exit(1);
Now, this function is called by main() and qmp_change_vnc_listen() ,
That's ok for main() exit if encounter any errors, but don't adapt to qmp
command IMHO.
Regards,
-Gonglei
> + }
> + return 0;
> +}
> +
> +static void vnc_register_config(void)
> +{
> + qemu_add_opts(&qemu_vnc_opts);
> +}
> +machine_init(vnc_register_config);
> diff --git a/vl.c b/vl.c
> index 08b73ee..0bf00cf 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -158,9 +158,6 @@ int smp_cpus = 1;
> int max_cpus = 0;
> int smp_cores = 1;
> int smp_threads = 1;
> -#ifdef CONFIG_VNC
> -const char *vnc_display;
> -#endif
> int acpi_enabled = 1;
> int no_hpet = 0;
> int fd_bootchk = 1;
> @@ -2087,16 +2084,12 @@ static DisplayType select_display(const char *p)
> #endif
> } else if (strstart(p, "vnc", &opts)) {
> #ifdef CONFIG_VNC
> - display_remote++;
> -
> - if (*opts) {
> - const char *nextopt;
> -
> - if (strstart(opts, "=", &nextopt)) {
> - vnc_display = nextopt;
> + if (*opts == '=') {
> + display_remote++;
> + if (vnc_parse_func(opts+1) == NULL) {
> + exit(1);
> }
> - }
> - if (!vnc_display) {
> + } else {
> fprintf(stderr, "VNC requires a display argument vnc=<display>\n");
> exit(1);
> }
> @@ -3563,7 +3556,9 @@ int main(int argc, char **argv, char **envp)
> case QEMU_OPTION_vnc:
> #ifdef CONFIG_VNC
> display_remote++;
> - vnc_display = optarg;
> + if (vnc_parse_func(optarg) == NULL) {
> + exit(1);
> + }
> #else
> fprintf(stderr, "VNC support is disabled\n");
> exit(1);
> @@ -4016,7 +4011,7 @@ int main(int argc, char **argv, char **envp)
> #elif defined(CONFIG_SDL) || defined(CONFIG_COCOA)
> display_type = DT_SDL;
> #elif defined(CONFIG_VNC)
> - vnc_display = "localhost:0,to=99";
> + vnc_parse_func("localhost:0,to=99,id=default");
> show_vnc_port = 1;
> #else
> display_type = DT_NONE;
> @@ -4321,21 +4316,10 @@ int main(int argc, char **argv, char **envp)
>
> #ifdef CONFIG_VNC
> /* init remote displays */
> - if (vnc_display) {
> - Error *local_err = NULL;
> - const char *id = "default";
> - vnc_display_init(id);
> - vnc_display_open(id, vnc_display, &local_err);
> - if (local_err != NULL) {
> - error_report("Failed to start VNC server on `%s': %s",
> - vnc_display, error_get_pretty(local_err));
> - error_free(local_err);
> - exit(1);
> - }
> -
> - if (show_vnc_port) {
> - printf("VNC server running on `%s'\n", vnc_display_local_addr(id));
> - }
> + qemu_opts_foreach(qemu_find_opts("vnc"), vnc_init_func, NULL, 0);
> + if (show_vnc_port) {
> + printf("VNC server running on `%s'\n",
> + vnc_display_local_addr("default"));
> }
> #endif
> #ifdef CONFIG_SPICE
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 04/10] vnc: switch to QemuOpts, allow multiple servers
2014-12-11 2:59 ` Gonglei
@ 2014-12-11 8:48 ` Gerd Hoffmann
0 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-11 8:48 UTC (permalink / raw)
To: Gonglei; +Cc: Paolo Bonzini, qemu-devel, Anthony Liguori, Luiz Capitulino
Hi,
> > + fprintf(stderr, "%s: id \"%s\"\n", __func__, id);
>
> A debug message, isn't it?
Yes, dropped.
> > +
> > + vnc_display_init(id);
> > + vnc_display_open(id, &local_err);
> > + if (local_err != NULL) {
> > + error_report("Failed to start VNC server on `%s': %s",
> > + qemu_opt_get(opts, "display"),
> > + error_get_pretty(local_err));
> > + error_free(local_err);
> > + exit(1);
>
> Now, this function is called by main() and qmp_change_vnc_listen() ,
> That's ok for main() exit if encounter any errors, but don't adapt to qmp
> command IMHO.
Correct. Fixed qmp up to call vnc_display_open directly.
cheers,
Gerd
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 05/10] vnc: allow binding servers to qemu consoles
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (3 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 04/10] vnc: switch to QemuOpts, allow multiple servers Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 06/10] vnc: update docs/multiseat.txt Gerd Hoffmann
` (4 subsequent siblings)
9 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori
This patch adds a display= parameter to the vnc options. This allows to
bind a vnc server instance to a specific display, allowing to create a
multiseat setup with a vnc server for each seat.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 43 insertions(+), 7 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index cf8bed8..210a115 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -27,6 +27,7 @@
#include "vnc.h"
#include "vnc-jobs.h"
#include "trace.h"
+#include "hw/qdev.h"
#include "sysemu/sysemu.h"
#include "qemu/sockets.h"
#include "qemu/timer.h"
@@ -1665,7 +1666,8 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
vs->modifiers_state[keycode] = 0;
break;
case 0x02 ... 0x0a: /* '1' to '9' keys */
- if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
+ if (vs->vd->dcl.con == NULL &&
+ down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
/* Reset the modifiers sent to the current console */
reset_keys(vs);
console_select(keycode - 0x02);
@@ -2073,8 +2075,8 @@ static void set_pixel_format(VncState *vs,
set_pixel_conversion(vs);
- graphic_hw_invalidate(NULL);
- graphic_hw_update(NULL);
+ graphic_hw_invalidate(vs->vd->dcl.con);
+ graphic_hw_update(vs->vd->dcl.con);
}
static void pixel_format_message (VncState *vs) {
@@ -2801,7 +2803,7 @@ static void vnc_refresh(DisplayChangeListener *dcl)
return;
}
- graphic_hw_update(NULL);
+ graphic_hw_update(vd->dcl.con);
if (vnc_trylock_display(vd)) {
update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
@@ -2907,7 +2909,7 @@ void vnc_init_state(VncState *vs)
QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
- graphic_hw_update(NULL);
+ graphic_hw_update(vd->dcl.con);
vnc_write(vs, "RFB 003.008\n", 12);
vnc_flush(vs);
@@ -2930,7 +2932,7 @@ static void vnc_listen_read(void *opaque, bool websocket)
int csock;
/* Catch-up */
- graphic_hw_update(NULL);
+ graphic_hw_update(vs->dcl.con);
#ifdef CONFIG_VNC_WS
if (websocket) {
csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
@@ -3089,6 +3091,12 @@ static QemuOptsList qemu_vnc_opts = {
.name = "share",
.type = QEMU_OPT_STRING,
},{
+ .name = "display",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "head",
+ .type = QEMU_OPT_NUMBER,
+ },{
.name = "password",
.type = QEMU_OPT_BOOL,
},{
@@ -3124,7 +3132,8 @@ void vnc_display_open(const char *id, Error **errp)
{
VncDisplay *vs = vnc_display_find(id);
QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
- const char *display, *websocket, *share;
+ const char *display, *websocket, *share, *device_id;
+ QemuConsole *con;
int password = 0;
int reverse = 0;
#ifdef CONFIG_VNC_TLS
@@ -3353,6 +3362,33 @@ void vnc_display_open(const char *id, Error **errp)
#endif
vs->lock_key_sync = lock_key_sync;
+ device_id = qemu_opt_get(opts, "display");
+ if (device_id) {
+ DeviceState *dev;
+ int head = qemu_opt_get_number(opts, "head", 0);
+
+ dev = qdev_find_recursive(sysbus_get_default(), device_id);
+ if (dev == NULL) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device_id);
+ goto fail;
+ }
+
+ con = qemu_console_lookup_by_device(dev, head);
+ if (con == NULL) {
+ error_setg(errp, "Device %s is not bound to a QemuConsole",
+ device_id);
+ goto fail;
+ }
+ } else {
+ con = NULL;
+ }
+
+ if (con != vs->dcl.con) {
+ unregister_displaychangelistener(&vs->dcl);
+ vs->dcl.con = con;
+ register_displaychangelistener(&vs->dcl);
+ }
+
if (reverse) {
/* connect to viewer */
int csock;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 06/10] vnc: update docs/multiseat.txt
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (4 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 05/10] vnc: allow binding servers to qemu consoles Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 07/10] vnc: track & limit connections Gerd Hoffmann
` (3 subsequent siblings)
9 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
vnc joins the party ;)
Also some s/head/seat/ to clarify.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
docs/multiseat.txt | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/docs/multiseat.txt b/docs/multiseat.txt
index 67151e0..b963665 100644
--- a/docs/multiseat.txt
+++ b/docs/multiseat.txt
@@ -7,7 +7,7 @@ host side
First you must compile qemu with a user interface supporting
multihead/multiseat and input event routing. Right now this
-list includes sdl2 and gtk (both 2+3):
+list includes sdl2, gtk (both 2+3) and vnc:
./configure --enable-sdl --with-sdlabi=2.0
@@ -16,16 +16,16 @@ or
./configure --enable-gtk
-Next put together the qemu command line:
+Next put together the qemu command line (sdk/gtk):
qemu -enable-kvm -usb $memory $disk $whatever \
-display [ sdl | gtk ] \
-vga std \
-device usb-tablet
-That is it for the first head, which will use the standard vga, the
+That is it for the first seat, which will use the standard vga, the
standard ps/2 keyboard (implicitly there) and the usb-tablet. Now the
-additional switches for the second head:
+additional switches for the second seat:
-device pci-bridge,addr=12.0,chassis_nr=2,id=head.2 \
-device secondary-vga,bus=head.2,addr=02.0,id=video.2 \
@@ -47,6 +47,16 @@ in a separate tab. You can either simply switch tabs to switch heads,
or use the "View / Detach tab" menu item to move one of the displays
to its own window so you can see both display devices side-by-side.
+For vnc some additional configuration on the command line is needed.
+We'll create two vnc server instances, and bind the second one to the
+second seat, simliar to input devices:
+
+ -display vnc=:1,id=primary \
+ -display vnc=:2,id=secondary,display=video.2
+
+Connecting to vnc display :1 gives you access to the first seat, and
+likewise connecting to vnc display :2 shows the second seat.
+
Note on spice: Spice handles multihead just fine. But it can't do
multiseat. For tablet events the event source is sent to the spice
agent. But qemu can't figure it, so it can't do input routing.
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 07/10] vnc: track & limit connections
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (5 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 06/10] vnc: update docs/multiseat.txt Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 08/10] vnc: factor out qmp_query_client_list Gerd Hoffmann
` (2 subsequent siblings)
9 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori, Dr. David Alan Gilbert
Also track the number of connections in "connecting" and "shared" state
(in addition to the "exclusive" state). Apply a configurable limit to
these connections.
The logic to apply the limit to connections in "shared" state is pretty
simple: When the limit is reached no new connections are allowed.
The logic to apply the limit to connections in "connecting" state (this
is the state you are in *before* successful authentication) is
slightly different: A new connect kicks out the oldest client which is
still in "connecting" state. This avoids a easy DoS by unauthenticated
users by simply opening connections until the limit is reached.
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
ui/vnc.h | 3 +++
2 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 210a115..8d189e7 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -68,12 +68,34 @@ static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
vs->csock, mn[vs->share_mode], mn[mode]);
#endif
- if (vs->share_mode == VNC_SHARE_MODE_EXCLUSIVE) {
+ switch (vs->share_mode) {
+ case VNC_SHARE_MODE_CONNECTING:
+ vs->vd->num_connecting--;
+ break;
+ case VNC_SHARE_MODE_SHARED:
+ vs->vd->num_shared--;
+ break;
+ case VNC_SHARE_MODE_EXCLUSIVE:
vs->vd->num_exclusive--;
+ break;
+ default:
+ break;
}
+
vs->share_mode = mode;
- if (vs->share_mode == VNC_SHARE_MODE_EXCLUSIVE) {
+
+ switch (vs->share_mode) {
+ case VNC_SHARE_MODE_CONNECTING:
+ vs->vd->num_connecting++;
+ break;
+ case VNC_SHARE_MODE_SHARED:
+ vs->vd->num_shared++;
+ break;
+ case VNC_SHARE_MODE_EXCLUSIVE:
vs->vd->num_exclusive++;
+ break;
+ default:
+ break;
}
}
@@ -2337,6 +2359,11 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
}
vnc_set_share_mode(vs, mode);
+ if (vs->vd->num_shared > vs->vd->connections_limit) {
+ vnc_disconnect_start(vs);
+ return 0;
+ }
+
vs->client_width = pixman_image_get_width(vs->vd->server);
vs->client_height = pixman_image_get_height(vs->vd->server);
vnc_write_u16(vs, vs->client_width);
@@ -2889,6 +2916,15 @@ static void vnc_connect(VncDisplay *vd, int csock,
{
vnc_init_state(vs);
}
+
+ if (vd->num_connecting > vd->connections_limit) {
+ QTAILQ_FOREACH(vs, &vd->clients, next) {
+ if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
+ vnc_disconnect_start(vs);
+ return;
+ }
+ }
+ }
}
void vnc_init_state(VncState *vs)
@@ -2907,7 +2943,7 @@ void vnc_init_state(VncState *vs)
qemu_mutex_init(&vs->output_mutex);
vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
- QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
+ QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
graphic_hw_update(vd->dcl.con);
@@ -3097,6 +3133,9 @@ static QemuOptsList qemu_vnc_opts = {
.name = "head",
.type = QEMU_OPT_NUMBER,
},{
+ .name = "connections",
+ .type = QEMU_OPT_NUMBER,
+ },{
.name = "password",
.type = QEMU_OPT_BOOL,
},{
@@ -3210,6 +3249,7 @@ void vnc_display_open(const char *id, Error **errp)
} else {
vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
}
+ vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
#ifdef CONFIG_VNC_WS
websocket = qemu_opt_get(opts, "websocket");
diff --git a/ui/vnc.h b/ui/vnc.h
index 6fe8278..5e2b1a5 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -150,7 +150,10 @@ typedef enum VncSharePolicy {
struct VncDisplay
{
QTAILQ_HEAD(, VncState) clients;
+ int num_connecting;
+ int num_shared;
int num_exclusive;
+ int connections_limit;
VncSharePolicy share_policy;
int lsock;
#ifdef CONFIG_VNC_WS
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 08/10] vnc: factor out qmp_query_client_list
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (6 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 07/10] vnc: track & limit connections Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command Gerd Hoffmann
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 10/10] monitor: add vnc websockets Gerd Hoffmann
9 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori
so we can reuse it for the new vnc query command.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index 8d189e7..d04802c 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -385,6 +385,20 @@ static VncDisplay *vnc_display_find(const char *id)
return NULL;
}
+static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
+{
+ VncClientInfoList *cinfo, *prev = NULL;
+ VncState *client;
+
+ QTAILQ_FOREACH(client, &vd->clients, next) {
+ cinfo = g_new0(VncClientInfoList, 1);
+ cinfo->value = qmp_query_vnc_client(client);
+ cinfo->next = prev;
+ prev = cinfo;
+ }
+ return prev;
+}
+
VncInfo *qmp_query_vnc(Error **errp)
{
VncInfo *info = g_malloc0(sizeof(*info));
@@ -393,30 +407,16 @@ VncInfo *qmp_query_vnc(Error **errp)
if (vd == NULL || vd->display == NULL) {
info->enabled = false;
} else {
- VncClientInfoList *cur_item = NULL;
struct sockaddr_storage sa;
socklen_t salen = sizeof(sa);
char host[NI_MAXHOST];
char serv[NI_MAXSERV];
- VncState *client;
info->enabled = true;
/* for compatibility with the original command */
info->has_clients = true;
-
- QTAILQ_FOREACH(client, &vd->clients, next) {
- VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
- cinfo->value = qmp_query_vnc_client(client);
-
- /* XXX: waiting for the qapi to support GSList */
- if (!cur_item) {
- info->clients = cur_item = cinfo;
- } else {
- cur_item->next = cinfo;
- cur_item = cinfo;
- }
- }
+ info->clients = qmp_query_client_list(vd);
if (vd->lsock == -1) {
return info;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (7 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 08/10] vnc: factor out qmp_query_client_list Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-10 16:52 ` Eric Blake
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 10/10] monitor: add vnc websockets Gerd Hoffmann
9 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel
Cc: Markus Armbruster, Gerd Hoffmann, Anthony Liguori,
Luiz Capitulino
Add new query vnc qmp command, for the lack of better ideas just name it
"query-vnc2". Changes over query-vnc:
* It returns a list of vnc servers, so multiple vnc server instances
are covered.
* Each vnc server returns a list of server sockets. Followup patch
will use that to also report websockets. In case we add support for
multiple server sockets server sockets (to better support ipv4+ipv6
dualstack) we can add them to the list too.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qapi-schema.json | 50 +++++++++++++++++++++++++++++++++++++++++++
qmp-commands.hx | 5 +++++
ui/vnc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+)
diff --git a/qapi-schema.json b/qapi-schema.json
index 9ffdcf8..677a762 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -751,6 +751,45 @@
'*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
##
+# @VncInfo2:
+#
+# Information about a vnc server
+#
+# @id: vnc server name.
+#
+# @server: A list of @VncBasincInfo describing all listening sockets.
+# The list can be empty (in case the vnc server is disabled).
+# It also may have multiple entries: normal + websocket,
+# possibly also ipv4 + ipv6 in the future.
+#
+# @clients: A list of @VncClientInfo of all currently connected clients.
+# The list can be empty, for obvious reasons.
+#
+# @auth: The current authentication type used by the server
+# 'none' if no authentication is being used
+# 'vnc' if VNC authentication is being used
+# 'vencrypt+plain' if VEncrypt is used with plain text authentication
+# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
+# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
+# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
+# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
+# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
+# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
+# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
+# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
+#
+# @display: #optional The display device the vnc server is linked to.
+#
+# Since: 2.3
+##
+{ 'type': 'VncInfo2',
+ 'data': { 'id' : 'str',
+ 'server' : ['VncBasicInfo'],
+ 'clients' : ['VncClientInfo'],
+ 'auth' : 'str',
+ '*display' : 'str' } }
+
+##
# @query-vnc:
#
# Returns information about the current VNC server
@@ -762,6 +801,17 @@
{ 'command': 'query-vnc', 'returns': 'VncInfo' }
##
+# @query-vnc2:
+#
+# Returns a list of vnc servers. The list can be empty.
+#
+# Returns: @VncInfo
+#
+# Since: 2.3
+##
+{ 'command': 'query-vnc2', 'returns': ['VncInfo2'] }
+
+##
# @SpiceBasicInfo
#
# The basic information for SPICE network connection
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 718dd92..704522e 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2825,6 +2825,11 @@ EQMP
.args_type = "",
.mhandler.cmd_new = qmp_marshal_input_query_vnc,
},
+ {
+ .name = "query-vnc2",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_vnc2,
+ },
SQMP
query-spice
diff --git a/ui/vnc.c b/ui/vnc.c
index d04802c..0574631 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -456,6 +456,70 @@ out_error:
return NULL;
}
+static VncBasicInfoList *qmp_query_server_entry(int socket,
+ VncBasicInfoList *prev)
+{
+ VncBasicInfoList *list;
+ VncBasicInfo *info;
+ struct sockaddr_storage sa;
+ socklen_t salen = sizeof(sa);
+ char host[NI_MAXHOST];
+ char serv[NI_MAXSERV];
+
+ if (getsockname(socket, (struct sockaddr *)&sa, &salen) < 0 ||
+ getnameinfo((struct sockaddr *)&sa, salen,
+ host, sizeof(host), serv, sizeof(serv),
+ NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
+ return prev;
+ }
+
+ info = g_new0(VncBasicInfo, 1);
+ info->host = g_strdup(host);
+ info->service = g_strdup(serv);
+ info->family = inet_netfamily(sa.ss_family);
+
+ list = g_new0(VncBasicInfoList, 1);
+ list->value = info;
+ list->next = prev;
+ return list;
+}
+
+VncInfo2List *qmp_query_vnc2(Error **errp)
+{
+ VncInfo2List *item, *prev = NULL;
+ VncInfo2 *info;
+ VncDisplay *vd;
+ DeviceState *dev;
+
+ QTAILQ_FOREACH(vd, &vnc_displays, next) {
+ info = g_new0(VncInfo2, 1);
+ info->id = g_strdup(vd->id);
+ info->auth = g_strdup(vnc_auth_name(vd));
+ info->clients = qmp_query_client_list(vd);
+ if (vd->dcl.con) {
+ dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
+ "device", NULL));
+ info->has_display = true;
+ info->display = g_strdup(dev->id);
+ }
+ if (vd->lsock != -1) {
+ info->server = qmp_query_server_entry(vd->lsock,
+ info->server);
+ }
+#ifdef CONFIG_VNC_WS
+ if (vd->lwebsock != -1) {
+ /* TODO */
+ }
+#endif
+
+ item = g_new0(VncInfo2List, 1);
+ item->value = info;
+ item->next = prev;
+ prev = item;
+ }
+ return prev;
+}
+
/* TODO
1) Get the queue working for IO.
2) there is some weirdness when using the -S option (the screen is grey
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command Gerd Hoffmann
@ 2014-12-10 16:52 ` Eric Blake
2014-12-11 9:07 ` Gerd Hoffmann
2014-12-11 9:40 ` Daniel P. Berrange
0 siblings, 2 replies; 29+ messages in thread
From: Eric Blake @ 2014-12-10 16:52 UTC (permalink / raw)
To: Gerd Hoffmann, qemu-devel
Cc: Markus Armbruster, Anthony Liguori, Luiz Capitulino
[-- Attachment #1: Type: text/plain, Size: 2847 bytes --]
On 12/10/2014 02:37 AM, Gerd Hoffmann wrote:
> Add new query vnc qmp command, for the lack of better ideas just name it
> "query-vnc2". Changes over query-vnc:
>
> * It returns a list of vnc servers, so multiple vnc server instances
> are covered.
> * Each vnc server returns a list of server sockets. Followup patch
> will use that to also report websockets. In case we add support for
> multiple server sockets server sockets (to better support ipv4+ipv6
> dualstack) we can add them to the list too.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> +# @VncInfo2:
> +#
> +# Information about a vnc server
> +#
> +# @id: vnc server name.
> +#
> +# @server: A list of @VncBasincInfo describing all listening sockets.
> +# The list can be empty (in case the vnc server is disabled).
> +# It also may have multiple entries: normal + websocket,
> +# possibly also ipv4 + ipv6 in the future.
> +#
> +# @clients: A list of @VncClientInfo of all currently connected clients.
> +# The list can be empty, for obvious reasons.
Seems okay.
> +#
> +# @auth: The current authentication type used by the server
> +# 'none' if no authentication is being used
> +# 'vnc' if VNC authentication is being used
> +# 'vencrypt+plain' if VEncrypt is used with plain text authentication
> +# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
> +# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
> +# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
> +# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
> +# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
> +# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
> +# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
> +# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
This feels like an open-coded string that should instead be an array of
enum values. That is,
{ 'enum': 'VncAuth', 'data', [ 'none', 'vnc', 'vencrypt', 'plain',
'tls', 'x509' ] }
... 'auth': ['VcnAuth']
might be friendlier to applications (having to post-parse the '+' is not
friendly).
> +#
> +# @display: #optional The display device the vnc server is linked to.
> +#
> +# Since: 2.3
> +##
> +{ 'type': 'VncInfo2',
> + 'data': { 'id' : 'str',
> + 'server' : ['VncBasicInfo'],
> + 'clients' : ['VncClientInfo'],
> + 'auth' : 'str',
> + '*display' : 'str' } }
Looks reasonable, other than my concern about 'auth'.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-10 16:52 ` Eric Blake
@ 2014-12-11 9:07 ` Gerd Hoffmann
2014-12-11 9:43 ` Daniel P. Berrange
2014-12-11 9:40 ` Daniel P. Berrange
1 sibling, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-11 9:07 UTC (permalink / raw)
To: Eric Blake
Cc: Markus Armbruster, qemu-devel, Anthony Liguori, Luiz Capitulino
Hi,
> > +# @auth: The current authentication type used by the server
> > +# 'none' if no authentication is being used
> > +# 'vnc' if VNC authentication is being used
> > +# 'vencrypt+plain' if VEncrypt is used with plain text authentication
> > +# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
> > +# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
> > +# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
> > +# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
> > +# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
> > +# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
> > +# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
> > +# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
>
> This feels like an open-coded string that should instead be an array of
> enum values.
This is just copyed over from the old query-vnc command.
We can try to do that in a cleaner way for query-vnc2. That implies
libvirt needs to be able to handle both formats though.
Adding danbp who did most vnc auth stuff for comments.
> That is,
>
> { 'enum': 'VncAuth', 'data', [ 'none', 'vnc', 'vencrypt', 'plain',
> 'tls', 'x509' ] }
> ... 'auth': ['VcnAuth']
Looked at the source, figured the list grew meanwhile.
Do we need 'none' here? When we have a list anyway we can have an empty
list instead.
cheers,
Gerd
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-11 9:07 ` Gerd Hoffmann
@ 2014-12-11 9:43 ` Daniel P. Berrange
0 siblings, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2014-12-11 9:43 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Markus Armbruster, qemu-devel, Anthony Liguori, Luiz Capitulino
On Thu, Dec 11, 2014 at 10:07:24AM +0100, Gerd Hoffmann wrote:
> Hi,
>
> > > +# @auth: The current authentication type used by the server
> > > +# 'none' if no authentication is being used
> > > +# 'vnc' if VNC authentication is being used
> > > +# 'vencrypt+plain' if VEncrypt is used with plain text authentication
> > > +# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
> > > +# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
> > > +# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
> > > +# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
> > > +# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
> > > +# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
> > > +# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
> > > +# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
> >
> > This feels like an open-coded string that should instead be an array of
> > enum values.
>
> This is just copyed over from the old query-vnc command.
>
> We can try to do that in a cleaner way for query-vnc2. That implies
> libvirt needs to be able to handle both formats though.
It isn't a big deal if the format changes. Libvirt doesn't use the
auth value for any functional purpose. It just passes the string
auth scheme name to the event callback that fires whenever a user
completes authentication. So if the fields were split, libvirt
would just concatenate them again.
>
> > That is,
> >
> > { 'enum': 'VncAuth', 'data', [ 'none', 'vnc', 'vencrypt', 'plain',
> > 'tls', 'x509' ] }
>
> > ... 'auth': ['VcnAuth']
>
> Looked at the source, figured the list grew meanwhile.
>
> Do we need 'none' here? When we have a list anyway we can have an empty
> list instead.
Yes, I think "none" should be explicit, because you'll need it in
combination with vencrypt too - eg vencrypt-tls-none where you can
infer it from an empty list.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-10 16:52 ` Eric Blake
2014-12-11 9:07 ` Gerd Hoffmann
@ 2014-12-11 9:40 ` Daniel P. Berrange
2014-12-11 11:33 ` Gerd Hoffmann
1 sibling, 1 reply; 29+ messages in thread
From: Daniel P. Berrange @ 2014-12-11 9:40 UTC (permalink / raw)
To: Eric Blake
Cc: Markus Armbruster, Luiz Capitulino, Gerd Hoffmann,
Anthony Liguori, qemu-devel
On Wed, Dec 10, 2014 at 09:52:05AM -0700, Eric Blake wrote:
> On 12/10/2014 02:37 AM, Gerd Hoffmann wrote:
> > Add new query vnc qmp command, for the lack of better ideas just name it
> > "query-vnc2". Changes over query-vnc:
> >
> > * It returns a list of vnc servers, so multiple vnc server instances
> > are covered.
> > * Each vnc server returns a list of server sockets. Followup patch
> > will use that to also report websockets. In case we add support for
> > multiple server sockets server sockets (to better support ipv4+ipv6
> > dualstack) we can add them to the list too.
> >
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> > ---
>
> > +# @VncInfo2:
> > +#
> > +# Information about a vnc server
> > +#
> > +# @id: vnc server name.
> > +#
> > +# @server: A list of @VncBasincInfo describing all listening sockets.
> > +# The list can be empty (in case the vnc server is disabled).
> > +# It also may have multiple entries: normal + websocket,
> > +# possibly also ipv4 + ipv6 in the future.
> > +#
> > +# @clients: A list of @VncClientInfo of all currently connected clients.
> > +# The list can be empty, for obvious reasons.
>
> Seems okay.
>
> > +#
> > +# @auth: The current authentication type used by the server
> > +# 'none' if no authentication is being used
> > +# 'vnc' if VNC authentication is being used
> > +# 'vencrypt+plain' if VEncrypt is used with plain text authentication
> > +# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
> > +# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
> > +# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
> > +# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
> > +# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
> > +# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
> > +# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
> > +# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
>
> This feels like an open-coded string that should instead be an array of
> enum values. That is,
>
> { 'enum': 'VncAuth', 'data', [ 'none', 'vnc', 'vencrypt', 'plain',
> 'tls', 'x509' ] }
> ... 'auth': ['VcnAuth']
>
> might be friendlier to applications (having to post-parse the '+' is not
> friendly).
That's not a correct interpretation of the auth values - tls and x509 are
not separate auth codes. VNC has one set of primary auth codes really
none, vnc, vencrypt
If using the vencrypt option there are a number of sub-auth codes
tls-none, tls-vnc, tls-plain, tls-sasl x509-none, x509-vnc, x509-plain, x509-sasl
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-11 9:40 ` Daniel P. Berrange
@ 2014-12-11 11:33 ` Gerd Hoffmann
2014-12-11 11:47 ` Daniel P. Berrange
0 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-11 11:33 UTC (permalink / raw)
To: Daniel P. Berrange
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
Hi,
> That's not a correct interpretation of the auth values - tls and x509 are
> not separate auth codes. VNC has one set of primary auth codes really
>
> none, vnc, vencrypt
Well, the source code also has (see vnc_auth_name in ui/vnc.c):
ra2, ra2ne, tight, ultra, tls, sasl
> If using the vencrypt option there are a number of sub-auth codes
>
> tls-none, tls-vnc, tls-plain, tls-sasl x509-none, x509-vnc, x509-plain, x509-sasl
So better add a 'vencrypt-subauth' enum with this list?
cheers,
Gerd
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-11 11:33 ` Gerd Hoffmann
@ 2014-12-11 11:47 ` Daniel P. Berrange
2014-12-15 9:16 ` Gerd Hoffmann
0 siblings, 1 reply; 29+ messages in thread
From: Daniel P. Berrange @ 2014-12-11 11:47 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
On Thu, Dec 11, 2014 at 12:33:35PM +0100, Gerd Hoffmann wrote:
> Hi,
>
> > That's not a correct interpretation of the auth values - tls and x509 are
> > not separate auth codes. VNC has one set of primary auth codes really
> >
> > none, vnc, vencrypt
>
> Well, the source code also has (see vnc_auth_name in ui/vnc.c):
>
> ra2, ra2ne, tight, ultra, tls, sasl
True, though most of those aren't actually implemented (only SASL is)
> > If using the vencrypt option there are a number of sub-auth codes
> >
> > tls-none, tls-vnc, tls-plain, tls-sasl x509-none, x509-vnc, x509-plain, x509-sasl
>
> So better add a 'vencrypt-subauth' enum with this list?
Yeah probably a good idea
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-11 11:47 ` Daniel P. Berrange
@ 2014-12-15 9:16 ` Gerd Hoffmann
2014-12-15 9:26 ` Daniel P. Berrange
2014-12-15 16:22 ` Eric Blake
0 siblings, 2 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-15 9:16 UTC (permalink / raw)
To: Daniel P. Berrange
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 196 bytes --]
Hi,
> >
> > So better add a 'vencrypt-subauth' enum with this list?
>
> Yeah probably a good idea
How does this look like (incremental fixup attached, docs to be
updated) ?
cheers,
Gerd
[-- Attachment #2: 0001-query-vnc2-auth-fixup.patch --]
[-- Type: text/x-patch, Size: 4313 bytes --]
>From c2de144be939412f8923d20e22983e16ab418404 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 15 Dec 2014 10:14:10 +0100
Subject: [PATCH] query-vnc2: auth fixup
---
qapi-schema.json | 20 ++++++++++++----
ui/vnc.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 5bba0c2..8ef2510 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -785,12 +785,22 @@
#
# Since: 2.3
##
+{ 'enum': 'VncPriAuth',
+ 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
+ 'tls', 'vencrypt', 'sasl' ] }
+{ 'enum': 'VncVencryptSubAuth',
+ 'data': [ 'plain',
+ 'tls-none', 'x509-none',
+ 'tls-vnc', 'x509-vnc',
+ 'tls-plain', 'x509-plain',
+ 'tls-sasl', 'x509-sasl' ] }
{ 'type': 'VncInfo2',
- 'data': { 'id' : 'str',
- 'server' : ['VncBasicInfo'],
- 'clients' : ['VncClientInfo'],
- 'auth' : 'str',
- '*display' : 'str' } }
+ 'data': { 'id' : 'str',
+ 'server' : ['VncBasicInfo'],
+ 'clients' : ['VncClientInfo'],
+ 'auth' : 'VncPriAuth',
+ '*vencrypt' : 'VncVencryptSubAuth',
+ '*display' : 'str' } }
##
# @query-vnc:
diff --git a/ui/vnc.c b/ui/vnc.c
index 1e7eb4d..fb8068f 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -489,6 +489,75 @@ static VncBasicInfoList *qmp_query_server_entry(int socket,
return list;
}
+static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
+{
+ switch (vd->auth) {
+ case VNC_AUTH_VNC:
+ info->auth = VNC_PRI_AUTH_VNC;
+ break;
+ case VNC_AUTH_RA2:
+ info->auth = VNC_PRI_AUTH_RA2;
+ break;
+ case VNC_AUTH_RA2NE:
+ info->auth = VNC_PRI_AUTH_RA2NE;
+ break;
+ case VNC_AUTH_TIGHT:
+ info->auth = VNC_PRI_AUTH_TIGHT;
+ break;
+ case VNC_AUTH_ULTRA:
+ info->auth = VNC_PRI_AUTH_ULTRA;
+ break;
+ case VNC_AUTH_TLS:
+ info->auth = VNC_PRI_AUTH_TLS;
+ break;
+ case VNC_AUTH_VENCRYPT:
+ info->auth = VNC_PRI_AUTH_VENCRYPT;
+#ifdef CONFIG_VNC_TLS
+ info->has_vencrypt = true;
+ switch (vd->subauth) {
+ case VNC_AUTH_VENCRYPT_PLAIN:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSNONE:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSVNC:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSPLAIN:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
+ break;
+ case VNC_AUTH_VENCRYPT_X509NONE:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
+ break;
+ case VNC_AUTH_VENCRYPT_X509VNC:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
+ break;
+ case VNC_AUTH_VENCRYPT_X509PLAIN:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSSASL:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
+ break;
+ case VNC_AUTH_VENCRYPT_X509SASL:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
+ break;
+ default:
+ info->has_vencrypt = false;
+ break;
+ }
+#endif
+ break;
+ case VNC_AUTH_SASL:
+ info->auth = VNC_PRI_AUTH_SASL;
+ break;
+ case VNC_AUTH_NONE:
+ default:
+ info->auth = VNC_PRI_AUTH_NONE;
+ break;
+ }
+}
+
VncInfo2List *qmp_query_vnc2(Error **errp)
{
VncInfo2List *item, *prev = NULL;
@@ -499,8 +568,8 @@ VncInfo2List *qmp_query_vnc2(Error **errp)
QTAILQ_FOREACH(vd, &vnc_displays, next) {
info = g_new0(VncInfo2, 1);
info->id = g_strdup(vd->id);
- info->auth = g_strdup(vnc_auth_name(vd));
info->clients = qmp_query_client_list(vd);
+ qmp_query_auth(vd, info);
if (vd->dcl.con) {
dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
"device", NULL));
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-15 9:16 ` Gerd Hoffmann
@ 2014-12-15 9:26 ` Daniel P. Berrange
2014-12-15 16:22 ` Eric Blake
1 sibling, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2014-12-15 9:26 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
On Mon, Dec 15, 2014 at 10:16:39AM +0100, Gerd Hoffmann wrote:
> Hi,
>
> > >
> > > So better add a 'vencrypt-subauth' enum with this list?
> >
> > Yeah probably a good idea
>
> How does this look like (incremental fixup attached, docs to be
> updated) ?
Looks fine to me.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-15 9:16 ` Gerd Hoffmann
2014-12-15 9:26 ` Daniel P. Berrange
@ 2014-12-15 16:22 ` Eric Blake
2014-12-16 10:18 ` Gerd Hoffmann
1 sibling, 1 reply; 29+ messages in thread
From: Eric Blake @ 2014-12-15 16:22 UTC (permalink / raw)
To: Gerd Hoffmann, Daniel P. Berrange
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 1478 bytes --]
On 12/15/2014 02:16 AM, Gerd Hoffmann wrote:
> Hi,
>
>>> > >
>>> > > So better add a 'vencrypt-subauth' enum with this list?
>> >
>> > Yeah probably a good idea
> How does this look like (incremental fixup attached, docs to be
> updated) ?
>
> +++ b/qapi-schema.json
> @@ -785,12 +785,22 @@
> #
> # Since: 2.3
> ##
> +{ 'enum': 'VncPriAuth',
> + 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
> + 'tls', 'vencrypt', 'sasl' ] }
> +{ 'enum': 'VncVencryptSubAuth',
> + 'data': [ 'plain',
> + 'tls-none', 'x509-none',
> + 'tls-vnc', 'x509-vnc',
> + 'tls-plain', 'x509-plain',
> + 'tls-sasl', 'x509-sasl' ] }
Might be worth separate docs for the enums (we've done it elsewhere).
> { 'type': 'VncInfo2',
> - 'data': { 'id' : 'str',
> - 'server' : ['VncBasicInfo'],
> - 'clients' : ['VncClientInfo'],
> - 'auth' : 'str',
> - '*display' : 'str' } }
> + 'data': { 'id' : 'str',
> + 'server' : ['VncBasicInfo'],
> + 'clients' : ['VncClientInfo'],
> + 'auth' : 'VncPriAuth',
> + '*vencrypt' : 'VncVencryptSubAuth',
> + '*display' : 'str' } }
And don't forget docs for 'vencrypt'. But the interface looks fine to me.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-15 16:22 ` Eric Blake
@ 2014-12-16 10:18 ` Gerd Hoffmann
2014-12-16 16:13 ` Eric Blake
0 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-16 10:18 UTC (permalink / raw)
To: Eric Blake
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 364 bytes --]
Hi,
> > How does this look like (incremental fixup attached, docs to be
> > updated) ?
> Might be worth separate docs for the enums (we've done it elsewhere).
Sure, as mentioned above docs where not done yet ...
> But the interface looks fine to me.
... as I wanted to check this first ;)
So, here is the new version with updated docs ;)
cheers,
Gerd
[-- Attachment #2: 0001-query-vnc2-auth-fixup.patch --]
[-- Type: text/x-patch, Size: 5816 bytes --]
>From 1fcfdb821b7dbbafe1a2ee81f8b74f2ab83b6075 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 15 Dec 2014 10:14:10 +0100
Subject: [PATCH] query-vnc2: auth fixup
---
qapi-schema.json | 50 ++++++++++++++++++++++++++-------------
ui/vnc.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 104 insertions(+), 17 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 5bba0c2..b48c5ca 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -754,6 +754,31 @@
'*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
##
+# @VncPriAuth:
+#
+# vnc primary authentication method.
+#
+# Since: 2.3
+##
+{ 'enum': 'VncPriAuth',
+ 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
+ 'tls', 'vencrypt', 'sasl' ] }
+
+##
+# @VncVencryptSubAuth:
+#
+# vnc sub authentication method with vencrypt.
+#
+# Since: 2.3
+##
+{ 'enum': 'VncVencryptSubAuth',
+ 'data': [ 'plain',
+ 'tls-none', 'x509-none',
+ 'tls-vnc', 'x509-vnc',
+ 'tls-plain', 'x509-plain',
+ 'tls-sasl', 'x509-sasl' ] }
+
+##
# @VncInfo2:
#
# Information about a vnc server
@@ -769,28 +794,21 @@
# The list can be empty, for obvious reasons.
#
# @auth: The current authentication type used by the server
-# 'none' if no authentication is being used
-# 'vnc' if VNC authentication is being used
-# 'vencrypt+plain' if VEncrypt is used with plain text authentication
-# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
-# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
-# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
-# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
-# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
-# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
-# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
-# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
+#
+# @vencrypt: #optional The vencrypt sub authentication type used by the server,
+# only specified in case auth == vencrypt.
#
# @display: #optional The display device the vnc server is linked to.
#
# Since: 2.3
##
{ 'type': 'VncInfo2',
- 'data': { 'id' : 'str',
- 'server' : ['VncBasicInfo'],
- 'clients' : ['VncClientInfo'],
- 'auth' : 'str',
- '*display' : 'str' } }
+ 'data': { 'id' : 'str',
+ 'server' : ['VncBasicInfo'],
+ 'clients' : ['VncClientInfo'],
+ 'auth' : 'VncPriAuth',
+ '*vencrypt' : 'VncVencryptSubAuth',
+ '*display' : 'str' } }
##
# @query-vnc:
diff --git a/ui/vnc.c b/ui/vnc.c
index 1e7eb4d..fb8068f 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -489,6 +489,75 @@ static VncBasicInfoList *qmp_query_server_entry(int socket,
return list;
}
+static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
+{
+ switch (vd->auth) {
+ case VNC_AUTH_VNC:
+ info->auth = VNC_PRI_AUTH_VNC;
+ break;
+ case VNC_AUTH_RA2:
+ info->auth = VNC_PRI_AUTH_RA2;
+ break;
+ case VNC_AUTH_RA2NE:
+ info->auth = VNC_PRI_AUTH_RA2NE;
+ break;
+ case VNC_AUTH_TIGHT:
+ info->auth = VNC_PRI_AUTH_TIGHT;
+ break;
+ case VNC_AUTH_ULTRA:
+ info->auth = VNC_PRI_AUTH_ULTRA;
+ break;
+ case VNC_AUTH_TLS:
+ info->auth = VNC_PRI_AUTH_TLS;
+ break;
+ case VNC_AUTH_VENCRYPT:
+ info->auth = VNC_PRI_AUTH_VENCRYPT;
+#ifdef CONFIG_VNC_TLS
+ info->has_vencrypt = true;
+ switch (vd->subauth) {
+ case VNC_AUTH_VENCRYPT_PLAIN:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSNONE:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSVNC:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSPLAIN:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
+ break;
+ case VNC_AUTH_VENCRYPT_X509NONE:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
+ break;
+ case VNC_AUTH_VENCRYPT_X509VNC:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
+ break;
+ case VNC_AUTH_VENCRYPT_X509PLAIN:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
+ break;
+ case VNC_AUTH_VENCRYPT_TLSSASL:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
+ break;
+ case VNC_AUTH_VENCRYPT_X509SASL:
+ info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
+ break;
+ default:
+ info->has_vencrypt = false;
+ break;
+ }
+#endif
+ break;
+ case VNC_AUTH_SASL:
+ info->auth = VNC_PRI_AUTH_SASL;
+ break;
+ case VNC_AUTH_NONE:
+ default:
+ info->auth = VNC_PRI_AUTH_NONE;
+ break;
+ }
+}
+
VncInfo2List *qmp_query_vnc2(Error **errp)
{
VncInfo2List *item, *prev = NULL;
@@ -499,8 +568,8 @@ VncInfo2List *qmp_query_vnc2(Error **errp)
QTAILQ_FOREACH(vd, &vnc_displays, next) {
info = g_new0(VncInfo2, 1);
info->id = g_strdup(vd->id);
- info->auth = g_strdup(vnc_auth_name(vd));
info->clients = qmp_query_client_list(vd);
+ qmp_query_auth(vd, info);
if (vd->dcl.con) {
dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
"device", NULL));
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command
2014-12-16 10:18 ` Gerd Hoffmann
@ 2014-12-16 16:13 ` Eric Blake
0 siblings, 0 replies; 29+ messages in thread
From: Eric Blake @ 2014-12-16 16:13 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Luiz Capitulino, qemu-devel, Anthony Liguori, Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 580 bytes --]
On 12/16/2014 03:18 AM, Gerd Hoffmann wrote:
> Hi,
>
>>> How does this look like (incremental fixup attached, docs to be
>>> updated) ?
>
>> Might be worth separate docs for the enums (we've done it elsewhere).
>
> Sure, as mentioned above docs where not done yet ...
>
>
>> But the interface looks fine to me.
>
> ... as I wanted to check this first ;)
>
> So, here is the new version with updated docs ;)
Looks okay to me on first glance.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH v2 10/10] monitor: add vnc websockets
2014-12-10 9:37 [Qemu-devel] [PATCH v2 00/10] vnc: add support for multiple vnc displays Gerd Hoffmann
` (8 preceding siblings ...)
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 09/10] monitor: add query-vnc2 command Gerd Hoffmann
@ 2014-12-10 9:37 ` Gerd Hoffmann
2014-12-10 16:54 ` Eric Blake
9 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-10 9:37 UTC (permalink / raw)
To: qemu-devel
Cc: Markus Armbruster, Gerd Hoffmann, Anthony Liguori,
Luiz Capitulino
Add websockets bool to VncBasicInfo, report websocket server sockets,
flag websocket client connections.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
qapi-schema.json | 5 ++++-
ui/vnc.c | 14 ++++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 677a762..a945693 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -672,12 +672,15 @@
#
# @family: address family
#
+# @websocket: #optional true in case the socket is a websocket (since 2.2).
+#
# Since: 2.1
##
{ 'type': 'VncBasicInfo',
'data': { 'host': 'str',
'service': 'str',
- 'family': 'NetworkAddressFamily' } }
+ 'family': 'NetworkAddressFamily',
+ '*websocket': 'bool' } }
##
# @VncServerInfo
diff --git a/ui/vnc.c b/ui/vnc.c
index 0574631..f3beb4b 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -353,6 +353,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
info->base->host = g_strdup(host);
info->base->service = g_strdup(serv);
info->base->family = inet_netfamily(sa.ss_family);
+ if (client->websocket) {
+ info->base->has_websocket = true;
+ info->base->websocket = true;
+ }
#ifdef CONFIG_VNC_TLS
if (client->tls.session && client->tls.dname) {
@@ -457,6 +461,7 @@ out_error:
}
static VncBasicInfoList *qmp_query_server_entry(int socket,
+ bool websocket,
VncBasicInfoList *prev)
{
VncBasicInfoList *list;
@@ -477,6 +482,10 @@ static VncBasicInfoList *qmp_query_server_entry(int socket,
info->host = g_strdup(host);
info->service = g_strdup(serv);
info->family = inet_netfamily(sa.ss_family);
+ if (websocket) {
+ info->has_websocket = true;
+ info->websocket = true;
+ }
list = g_new0(VncBasicInfoList, 1);
list->value = info;
@@ -503,12 +512,13 @@ VncInfo2List *qmp_query_vnc2(Error **errp)
info->display = g_strdup(dev->id);
}
if (vd->lsock != -1) {
- info->server = qmp_query_server_entry(vd->lsock,
+ info->server = qmp_query_server_entry(vd->lsock, false,
info->server);
}
#ifdef CONFIG_VNC_WS
if (vd->lwebsock != -1) {
- /* TODO */
+ info->server = qmp_query_server_entry(vd->lwebsock, true,
+ info->server);
}
#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 10/10] monitor: add vnc websockets
2014-12-10 9:37 ` [Qemu-devel] [PATCH v2 10/10] monitor: add vnc websockets Gerd Hoffmann
@ 2014-12-10 16:54 ` Eric Blake
2014-12-11 9:08 ` Gerd Hoffmann
0 siblings, 1 reply; 29+ messages in thread
From: Eric Blake @ 2014-12-10 16:54 UTC (permalink / raw)
To: Gerd Hoffmann, qemu-devel
Cc: Markus Armbruster, Anthony Liguori, Luiz Capitulino
[-- Attachment #1: Type: text/plain, Size: 1350 bytes --]
On 12/10/2014 02:37 AM, Gerd Hoffmann wrote:
> Add websockets bool to VncBasicInfo, report websocket server sockets,
> flag websocket client connections.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> qapi-schema.json | 5 ++++-
> ui/vnc.c | 14 ++++++++++++--
> 2 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 677a762..a945693 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -672,12 +672,15 @@
> #
> # @family: address family
> #
> +# @websocket: #optional true in case the socket is a websocket (since 2.2).
s/2.2/2.3/
> +#
> # Since: 2.1
> ##
> { 'type': 'VncBasicInfo',
> 'data': { 'host': 'str',
> 'service': 'str',
> - 'family': 'NetworkAddressFamily' } }
> + 'family': 'NetworkAddressFamily',
> + '*websocket': 'bool' } }
Is it optional because you omit it when false? Why not just always
output the bool, so that clients know they are talking to a new-enough
qemu that knows about websockets (and this is explicitly not one), vs.
having to guess that the omission of the bool implies that it is not
rather than being an older qemu.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH v2 10/10] monitor: add vnc websockets
2014-12-10 16:54 ` Eric Blake
@ 2014-12-11 9:08 ` Gerd Hoffmann
0 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2014-12-11 9:08 UTC (permalink / raw)
To: Eric Blake
Cc: Markus Armbruster, qemu-devel, Anthony Liguori, Luiz Capitulino
> > +# @websocket: #optional true in case the socket is a websocket (since 2.2).
>
> s/2.2/2.3/
Fixed.
> Is it optional because you omit it when false? Why not just always
> output the bool, so that clients know they are talking to a new-enough
> qemu that knows about websockets (and this is explicitly not one), vs.
> having to guess that the omission of the bool implies that it is not
> rather than being an older qemu.
Makes sense, dropped optional. Also simplifies the code a bit ;)
cheers,
Gerd
^ permalink raw reply [flat|nested] 29+ messages in thread