From 88428b7a93347efc51be015cc12cb71fab3976a3 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Fri, 30 Jan 2015 10:14:34 +0800 Subject: [PATCH 1/7] vnc: fix qemu crash when not configure vnc option Add missing vnc options: to, ipv4, ipv6 and fix qemu crash. Reproducer: $ x86_64-softmmu/qemu-system-x86_64 qemu-system-x86_64: Invalid parameter 'to' Segmentation fault (core dumped) BTW the patch fix the below bug: https://bugs.launchpad.net/qemu/+bug/1414222 Signed-off-by: Gonglei Reviewed-by: Don Slutz Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ui/vnc.c b/ui/vnc.c index 02552ee27b..90e8a882e3 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3271,6 +3271,15 @@ static QemuOptsList qemu_vnc_opts = { },{ .name = "connections", .type = QEMU_OPT_NUMBER, + },{ + .name = "to", + .type = QEMU_OPT_NUMBER, + },{ + .name = "ipv4", + .type = QEMU_OPT_BOOL, + },{ + .name = "ipv6", + .type = QEMU_OPT_BOOL, },{ .name = "password", .type = QEMU_OPT_BOOL, From e2a11d9d5a7d8b8450cd644e73b829dcf4686528 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Fri, 30 Jan 2015 10:14:35 +0800 Subject: [PATCH 2/7] vnc: correct missing property about vnc_display Missing three property for vnc socket connection, revalue display variable with correct way. Signed-off-by: Gonglei Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 90e8a882e3..6a82d7f6b7 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3316,10 +3316,15 @@ 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, *share, *device_id; + const char *share, *device_id; QemuConsole *con; int password = 0; int reverse = 0; + const char *vnc; + const char *has_to; + char *display, *to = NULL; + bool has_ipv4 = false; + bool has_ipv6 = false; #ifdef CONFIG_VNC_WS const char *websocket; #endif @@ -3345,10 +3350,21 @@ void vnc_display_open(const char *id, Error **errp) if (!opts) { return; } - display = qemu_opt_get(opts, "vnc"); - if (!display || strcmp(display, "none") == 0) { + vnc = qemu_opt_get(opts, "vnc"); + if (!vnc || strcmp(vnc, "none") == 0) { return; } + + has_to = qemu_opt_get(opts, "to"); + if (has_to) { + to = g_strdup_printf(",to=%s", has_to); + } + has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false); + has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false); + display = g_strdup_printf("%s%s%s%s", vnc, + has_to ? to : "", + has_ipv4 ? ",ipv4" : "", + has_ipv6 ? ",ipv6" : ""); vs->display = g_strdup(display); password = qemu_opt_get_bool(opts, "password", false); @@ -3628,6 +3644,8 @@ void vnc_display_open(const char *id, Error **errp) } #endif /* CONFIG_VNC_WS */ } + g_free(to); + g_free(display); g_free(vs->display); vs->display = dpy; qemu_set_fd_handler2(vs->lsock, NULL, @@ -3642,6 +3660,8 @@ void vnc_display_open(const char *id, Error **errp) return; fail: + g_free(to); + g_free(display); g_free(vs->display); vs->display = NULL; #ifdef CONFIG_VNC_WS From a2c72de09619ed4d2f4498a65027114f9c035f7f Mon Sep 17 00:00:00 2001 From: Gonglei Date: Fri, 30 Jan 2015 10:14:36 +0800 Subject: [PATCH 3/7] vnc: using bool type instead of int for QEMU_OPT_BOOL Signed-off-by: Gonglei Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 6a82d7f6b7..e7c35aa6b6 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3318,8 +3318,8 @@ void vnc_display_open(const char *id, Error **errp) QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id); const char *share, *device_id; QemuConsole *con; - int password = 0; - int reverse = 0; + bool password = false; + bool reverse = false; const char *vnc; const char *has_to; char *display, *to = NULL; @@ -3329,11 +3329,11 @@ void vnc_display_open(const char *id, Error **errp) const char *websocket; #endif #ifdef CONFIG_VNC_TLS - int tls = 0, x509 = 0; + bool tls = false, x509 = false; const char *path; #endif #ifdef CONFIG_VNC_SASL - int sasl = 0; + bool sasl = false; int saslErr; #endif #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL) @@ -3385,7 +3385,7 @@ void vnc_display_open(const char *id, Error **errp) tls = qemu_opt_get_bool(opts, "tls", false); path = qemu_opt_get(opts, "x509"); if (path) { - x509 = 1; + x509 = true; 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", From 2779672fa3f0680e63ecfd3ee2d6ff360ce948a2 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Thu, 5 Feb 2015 17:43:34 +0800 Subject: [PATCH 4/7] vnc: introduce an wrapper for auto assign vnc id Signed-off-by: Gonglei Signed-off-by: Gerd Hoffmann --- include/ui/console.h | 1 + ui/vnc.c | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 8a4d671fbc..5c19c3c098 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -335,6 +335,7 @@ void vnc_display_init(const char *id); 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); +void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts); #ifdef CONFIG_VNC int vnc_display_password(const char *id, const char *password); int vnc_display_pw_expire(const char *id, time_t expires); diff --git a/ui/vnc.c b/ui/vnc.c index e7c35aa6b6..faa218f84b 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3685,6 +3685,19 @@ QemuOpts *vnc_parse_func(const char *str) return qemu_opts_parse(qemu_find_opts("vnc"), str, 1); } +void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts) +{ + int i = 2; + char *id; + + 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); +} + int vnc_init_func(QemuOpts *opts, void *opaque) { Error *local_err = NULL; @@ -3693,13 +3706,8 @@ int vnc_init_func(QemuOpts *opts, void *opaque) 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); + vnc_auto_assign_id(olist, opts); + id = (char *)qemu_opts_id(opts); } vnc_display_init(id); From f7801c5ce42250bf1e84d21bceb1802cfe4485e8 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Thu, 5 Feb 2015 17:43:35 +0800 Subject: [PATCH 5/7] vnc: auto assian an id when calling change vnc qmp interface Only in this way, change vnc qmp interface can take effect, because qemu_opts_find(&qemu_vnc_opts, id) will return NULL in vnc_display_open(), It can't connect successfully vnc server forever. Signed-off-by: Gonglei Signed-off-by: Gerd Hoffmann --- qmp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qmp.c b/qmp.c index 6b2c4bef3b..d701cff5ac 100644 --- a/qmp.c +++ b/qmp.c @@ -387,6 +387,11 @@ static void qmp_change_vnc_listen(const char *target, Error **errp) qemu_opts_del(opts); } opts = vnc_parse_func(target); + if (!opts) { + return; + } + + vnc_auto_assign_id(olist, opts); vnc_display_open("default", errp); } From 0e7d6f608339029404efd025ae9b8965ffe60087 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 2 Feb 2015 16:25:34 +0100 Subject: [PATCH 6/7] ui/vnc: optimize full scanline updates in case we send and update for a complete scanline increment the y offset to avoid running to find_next_bit for that lines twice. Signed-off-by: Peter Lieven Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/vnc.c b/ui/vnc.c index faa218f84b..14289fd951 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1111,6 +1111,12 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync) n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y, (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h); } + if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) { + y += h; + if (y == height) { + break; + } + } } vnc_job_push(job); From 9e0ff75e5158c7dbb65ee447382bbdf4cafbef8b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 11 Feb 2015 17:33:33 +0100 Subject: [PATCH 7/7] vnc: fix coverity warning vnc_display_local_addr will not be called with an invalid display id. Add assert() to silence coverity warning about a null pointer dereference. Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/vnc.c b/ui/vnc.c index 14289fd951..10a272450b 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3248,6 +3248,7 @@ char *vnc_display_local_addr(const char *id) { VncDisplay *vs = vnc_display_find(id); + assert(vs); return vnc_socket_local_addr("%s:%s", vs->lsock); }