From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076015889435.80480329847967; Wed, 13 Feb 2019 08:40:15 -0800 (PST) Received: from localhost ([127.0.0.1]:59837 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxa0-0003kj-Li for importer@patchew.org; Wed, 13 Feb 2019 11:40:12 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39192) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG5-000450-Q4 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005Js-44 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48156) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-000597-F7 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6275BC04959D; Wed, 13 Feb 2019 16:19:17 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id B4EB960856; Wed, 13 Feb 2019 16:19:16 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:49 +0100 Message-Id: <20190213161913.22107-2-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Feb 2019 16:19:17 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 01/25] chardev: fix mess in OPENED/CLOSED events when muxed X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Artem Pisarenko When chardev is multiplexed (mux=3Don) there are a lot of cases where CHR_EVENT_OPENED/CHR_EVENT_CLOSED events pairing (expected from frontend side) is broken. There are either generation of multiple repeated or extra CHR_EVENT_OPENED events, or CHR_EVENT_CLOSED just isn't generated at all. This is mostly because 'qemu_chr_fe_set_handlers()' function makes its own (and often wrong) implicit decision on updated frontend state and invokes 'fd_event' callback with 'CHR_EVENT_OPENED'. And even worse, it doesn't do symmetric action in opposite direction, as someone may expect (i.e. it doesn't invoke previously set 'fd_event' with 'CHR_EVENT_CLOSED'). Muxed chardev uses trick by calling this function again to replace callback handlers with its own ones, but it doesn't account for such side effect. Fix that using extended version of this function with added argument for disabling side effect and keep original function for compatibility with lots of frontends already using this interface and being "tolerant" to its side effects. One more source of event duplication is just line of code in char-mux.c, which does far more than comment above says (obvious fix). Signed-off-by: Artem Pisarenko Reviewed-by: Marc-Andr=C3=A9 Lureau Message-Id: <7dde6abbd21682857f8294644013173c0b9949b3.1541507990.git.artem.= k.pisarenko@gmail.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/chardev/char-fe.h | 18 +++++++++++++++++- chardev/char-fe.c | 33 ++++++++++++++++++++++++--------- chardev/char-mux.c | 16 ++++++++-------- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h index 46c997d352..c1b7fd9a95 100644 --- a/include/chardev/char-fe.h +++ b/include/chardev/char-fe.h @@ -67,7 +67,7 @@ bool qemu_chr_fe_backend_connected(CharBackend *be); bool qemu_chr_fe_backend_open(CharBackend *be); =20 /** - * qemu_chr_fe_set_handlers: + * qemu_chr_fe_set_handlers_full: * @b: a CharBackend * @fd_can_read: callback to get the amount of data the frontend may * receive @@ -79,12 +79,28 @@ bool qemu_chr_fe_backend_open(CharBackend *be); * @context: a main loop context or NULL for the default * @set_open: whether to call qemu_chr_fe_set_open() implicitely when * any of the handler is non-NULL + * @sync_state: whether to issue event callback with updated state * * Set the front end char handlers. The front end takes the focus if * any of the handler is non-NULL. * * Without associated Chardev, nothing is changed. */ +void qemu_chr_fe_set_handlers_full(CharBackend *b, + IOCanReadHandler *fd_can_read, + IOReadHandler *fd_read, + IOEventHandler *fd_event, + BackendChangeHandler *be_change, + void *opaque, + GMainContext *context, + bool set_open, + bool sync_state); + +/** + * qemu_chr_fe_set_handlers: + * + * Version of qemu_chr_fe_set_handlers_full() with sync_state =3D true. + */ void qemu_chr_fe_set_handlers(CharBackend *b, IOCanReadHandler *fd_can_read, IOReadHandler *fd_read, diff --git a/chardev/char-fe.c b/chardev/char-fe.c index a8931f7afd..b7bcbd59c0 100644 --- a/chardev/char-fe.c +++ b/chardev/char-fe.c @@ -246,14 +246,15 @@ void qemu_chr_fe_deinit(CharBackend *b, bool del) } } =20 -void qemu_chr_fe_set_handlers(CharBackend *b, - IOCanReadHandler *fd_can_read, - IOReadHandler *fd_read, - IOEventHandler *fd_event, - BackendChangeHandler *be_change, - void *opaque, - GMainContext *context, - bool set_open) +void qemu_chr_fe_set_handlers_full(CharBackend *b, + IOCanReadHandler *fd_can_read, + IOReadHandler *fd_read, + IOEventHandler *fd_event, + BackendChangeHandler *be_change, + void *opaque, + GMainContext *context, + bool set_open, + bool sync_state) { Chardev *s; int fe_open; @@ -285,7 +286,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b, qemu_chr_fe_take_focus(b); /* We're connecting to an already opened device, so let's make sur= e we also get the open event */ - if (s->be_open) { + if (sync_state && s->be_open) { qemu_chr_be_event(s, CHR_EVENT_OPENED); } } @@ -295,6 +296,20 @@ void qemu_chr_fe_set_handlers(CharBackend *b, } } =20 +void qemu_chr_fe_set_handlers(CharBackend *b, + IOCanReadHandler *fd_can_read, + IOReadHandler *fd_read, + IOEventHandler *fd_event, + BackendChangeHandler *be_change, + void *opaque, + GMainContext *context, + bool set_open) +{ + qemu_chr_fe_set_handlers_full(b, fd_can_read, fd_read, fd_event, be_ch= ange, + opaque, context, set_open, + true); +} + void qemu_chr_fe_take_focus(CharBackend *b) { if (!b->chr) { diff --git a/chardev/char-mux.c b/chardev/char-mux.c index 6055e76293..1199d32674 100644 --- a/chardev/char-mux.c +++ b/chardev/char-mux.c @@ -283,13 +283,13 @@ void mux_chr_set_handlers(Chardev *chr, GMainContext = *context) MuxChardev *d =3D MUX_CHARDEV(chr); =20 /* Fix up the real driver with mux routines */ - qemu_chr_fe_set_handlers(&d->chr, - mux_chr_can_read, - mux_chr_read, - mux_chr_event, - NULL, - chr, - context, true); + qemu_chr_fe_set_handlers_full(&d->chr, + mux_chr_can_read, + mux_chr_read, + mux_chr_event, + NULL, + chr, + context, true, false); } =20 void mux_set_focus(Chardev *chr, int focus) @@ -367,7 +367,7 @@ static int open_muxes(Chardev *chr) * mark mux as OPENED so any new FEs will immediately receive * OPENED event */ - qemu_chr_be_event(chr, CHR_EVENT_OPENED); + chr->be_open =3D 1; =20 return 0; } --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550075471496727.0269810588283; Wed, 13 Feb 2019 08:31:11 -0800 (PST) Received: from localhost ([127.0.0.1]:59706 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxRB-0005GS-FL for importer@patchew.org; Wed, 13 Feb 2019 11:31:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39140) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG4-00043Q-4S for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005Jg-0Z for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37430) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-00059q-F4 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 86B6A81E06; Wed, 13 Feb 2019 16:19:19 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id E90BA600C0; Wed, 13 Feb 2019 16:19:18 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:50 +0100 Message-Id: <20190213161913.22107-3-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 13 Feb 2019 16:19:19 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 02/25] tests/test-char: add muxed chardev testing for open/close X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Artem Pisarenko Validate that frontend callbacks for CHR_EVENT_OPENED/CHR_EVENT_CLOSED events are being issued when expected and in strictly pairing order. Signed-off-by: Artem Pisarenko Reviewed-by: Marc-Andr=C3=A9 Lureau Message-Id: Signed-off-by: Marc-Andr=C3=A9 Lureau --- tests/test-char.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/tests/test-char.c b/tests/test-char.c index 19c3efad72..018e2eed93 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -16,6 +16,9 @@ static bool quit; =20 typedef struct FeHandler { int read_count; + bool is_open; + int openclose_count; + bool openclose_mismatch; int last_event; char read_buf[128]; } FeHandler; @@ -49,10 +52,24 @@ static void fe_read(void *opaque, const uint8_t *buf, i= nt size) static void fe_event(void *opaque, int event) { FeHandler *h =3D opaque; + bool new_open_state; =20 h->last_event =3D event; - if (event !=3D CHR_EVENT_BREAK) { + switch (event) { + case CHR_EVENT_BREAK: + break; + case CHR_EVENT_OPENED: + case CHR_EVENT_CLOSED: + h->openclose_count++; + new_open_state =3D (event =3D=3D CHR_EVENT_OPENED); + if (h->is_open =3D=3D new_open_state) { + h->openclose_mismatch =3D true; + } + h->is_open =3D new_open_state; + /* no break */ + default: quit =3D true; + break; } } =20 @@ -161,7 +178,7 @@ static void char_mux_test(void) QemuOpts *opts; Chardev *chr, *base; char *data; - FeHandler h1 =3D { 0, }, h2 =3D { 0, }; + FeHandler h1 =3D { 0, false, 0, false, }, h2 =3D { 0, false, 0, false,= }; CharBackend chr_be1, chr_be2; =20 opts =3D qemu_opts_create(qemu_find_opts("chardev"), "mux-label", @@ -233,6 +250,65 @@ static void char_mux_test(void) g_assert_cmpint(h1.last_event, =3D=3D, CHR_EVENT_BREAK); g_assert_cmpint(h2.last_event, =3D=3D, CHR_EVENT_MUX_OUT); =20 + /* open/close state and corresponding events */ + g_assert_true(qemu_chr_fe_backend_open(&chr_be1)); + g_assert_true(qemu_chr_fe_backend_open(&chr_be2)); + g_assert_true(h1.is_open); + g_assert_false(h1.openclose_mismatch); + g_assert_true(h2.is_open); + g_assert_false(h2.openclose_mismatch); + + h1.openclose_count =3D h2.openclose_count =3D 0; + + qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL, + NULL, NULL, false); + qemu_chr_fe_set_handlers(&chr_be2, NULL, NULL, NULL, NULL, + NULL, NULL, false); + g_assert_cmpint(h1.openclose_count, =3D=3D, 0); + g_assert_cmpint(h2.openclose_count, =3D=3D, 0); + + h1.is_open =3D h2.is_open =3D false; + qemu_chr_fe_set_handlers(&chr_be1, + NULL, + NULL, + fe_event, + NULL, + &h1, + NULL, false); + qemu_chr_fe_set_handlers(&chr_be2, + NULL, + NULL, + fe_event, + NULL, + &h2, + NULL, false); + g_assert_cmpint(h1.openclose_count, =3D=3D, 1); + g_assert_false(h1.openclose_mismatch); + g_assert_cmpint(h2.openclose_count, =3D=3D, 1); + g_assert_false(h2.openclose_mismatch); + + qemu_chr_be_event(base, CHR_EVENT_CLOSED); + qemu_chr_be_event(base, CHR_EVENT_OPENED); + g_assert_cmpint(h1.openclose_count, =3D=3D, 3); + g_assert_false(h1.openclose_mismatch); + g_assert_cmpint(h2.openclose_count, =3D=3D, 3); + g_assert_false(h2.openclose_mismatch); + + qemu_chr_fe_set_handlers(&chr_be2, + fe_can_read, + fe_read, + fe_event, + NULL, + &h2, + NULL, false); + qemu_chr_fe_set_handlers(&chr_be1, + fe_can_read, + fe_read, + fe_event, + NULL, + &h1, + NULL, false); + /* remove first handler */ qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL, NULL, NULL, true); --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 155007584471729.836513739121642; Wed, 13 Feb 2019 08:37:24 -0800 (PST) Received: from localhost ([127.0.0.1]:59798 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxXC-0001Mg-KN for importer@patchew.org; Wed, 13 Feb 2019 11:37:18 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39214) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG6-00045e-Fv for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005K5-4a for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:38 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57042) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-0005B7-F6 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BB03BC06A81A; Wed, 13 Feb 2019 16:19:21 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2418260BE2; Wed, 13 Feb 2019 16:19:20 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:51 +0100 Message-Id: <20190213161913.22107-4-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 13 Feb 2019 16:19:21 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 03/25] io: store reference to thread information in the QIOTask struct X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 Currently the struct QIOTaskThreadData is only needed by the worker thread, but a subsequent patch will need to access it from another context. Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-2-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- io/task.c | 64 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/io/task.c b/io/task.c index 2886a2c1bc..396866b10f 100644 --- a/io/task.c +++ b/io/task.c @@ -24,6 +24,14 @@ #include "qemu/thread.h" #include "trace.h" =20 +struct QIOTaskThreadData { + QIOTaskWorker worker; + gpointer opaque; + GDestroyNotify destroy; + GMainContext *context; +}; + + struct QIOTask { Object *source; QIOTaskFunc func; @@ -32,6 +40,7 @@ struct QIOTask { Error *err; gpointer result; GDestroyNotify destroyResult; + struct QIOTaskThreadData *thread; }; =20 =20 @@ -57,6 +66,18 @@ QIOTask *qio_task_new(Object *source, =20 static void qio_task_free(QIOTask *task) { + if (task->thread) { + if (task->thread->destroy) { + task->thread->destroy(task->thread->opaque); + } + + if (task->thread->context) { + g_main_context_unref(task->thread->context); + } + + g_free(task->thread); + } + if (task->destroy) { task->destroy(task->opaque); } @@ -72,31 +93,12 @@ static void qio_task_free(QIOTask *task) } =20 =20 -struct QIOTaskThreadData { - QIOTask *task; - QIOTaskWorker worker; - gpointer opaque; - GDestroyNotify destroy; - GMainContext *context; -}; - - static gboolean qio_task_thread_result(gpointer opaque) { - struct QIOTaskThreadData *data =3D opaque; + QIOTask *task =3D opaque; =20 - trace_qio_task_thread_result(data->task); - qio_task_complete(data->task); - - if (data->destroy) { - data->destroy(data->opaque); - } - - if (data->context) { - g_main_context_unref(data->context); - } - - g_free(data); + trace_qio_task_thread_result(task); + qio_task_complete(task); =20 return FALSE; } @@ -104,22 +106,23 @@ static gboolean qio_task_thread_result(gpointer opaqu= e) =20 static gpointer qio_task_thread_worker(gpointer opaque) { - struct QIOTaskThreadData *data =3D opaque; + QIOTask *task =3D opaque; GSource *idle; =20 - trace_qio_task_thread_run(data->task); - data->worker(data->task, data->opaque); + trace_qio_task_thread_run(task); + + task->thread->worker(task, task->thread->opaque); =20 /* We're running in the background thread, and must only * ever report the task results in the main event loop * thread. So we schedule an idle callback to report * the worker results */ - trace_qio_task_thread_exit(data->task); + trace_qio_task_thread_exit(task); =20 idle =3D g_idle_source_new(); - g_source_set_callback(idle, qio_task_thread_result, data, NULL); - g_source_attach(idle, data->context); + g_source_set_callback(idle, qio_task_thread_result, task, NULL); + g_source_attach(idle, task->thread->context); =20 return NULL; } @@ -138,17 +141,18 @@ void qio_task_run_in_thread(QIOTask *task, g_main_context_ref(context); } =20 - data->task =3D task; data->worker =3D worker; data->opaque =3D opaque; data->destroy =3D destroy; data->context =3D context; =20 + task->thread =3D data; + trace_qio_task_thread_start(task, worker, opaque); qemu_thread_create(&thread, "io-task-worker", qio_task_thread_worker, - data, + task, QEMU_THREAD_DETACHED); } =20 --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076030996572.5163049435503; Wed, 13 Feb 2019 08:40:30 -0800 (PST) Received: from localhost ([127.0.0.1]:59839 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxaF-0003wC-Qm for importer@patchew.org; Wed, 13 Feb 2019 11:40:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39187) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG5-00044v-Nv for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005Jz-4T for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39752) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-0005C4-F5 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 19F2B89C34; Wed, 13 Feb 2019 16:19:24 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6B69519C7B; Wed, 13 Feb 2019 16:19:23 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:52 +0100 Message-Id: <20190213161913.22107-5-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 13 Feb 2019 16:19:24 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 04/25] io: add qio_task_wait_thread to join with a background thread X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 Add the ability for a caller to wait for completion of the background thread to synchronously dispatch its result, without needing to wait for the main loop to run the idle callback. This method needs very careful usage to avoid a dangerous race condition with the free'ing of the task. The completion callback is normally invoked from an idle callback registered with the main loop context. The qio_task_wait_thread method must only be called if the completion callback has not yet run. The only safe way to achieve this is to run the qio_task_wait_thread method from the thread that executes the main loop. It is generally a bad idea to use this method since it will block execution of the main loop, however, the design of the character devices and its usage from vhostuser already requires blocking execution. Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-3-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/io/task.h | 29 ++++++++++++++++++++++++++++- io/task.c | 41 +++++++++++++++++++++++++++++++++++++---- io/trace-events | 2 ++ 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/include/io/task.h b/include/io/task.h index 9e09b95b2e..57d8ba835e 100644 --- a/include/io/task.h +++ b/include/io/task.h @@ -232,7 +232,8 @@ QIOTask *qio_task_new(Object *source, * * Run a task in a background thread. When @worker * returns it will call qio_task_complete() in - * the event thread context that provided. + * the thread that is running the main loop associated + * with @context. */ void qio_task_run_in_thread(QIOTask *task, QIOTaskWorker worker, @@ -240,6 +241,32 @@ void qio_task_run_in_thread(QIOTask *task, GDestroyNotify destroy, GMainContext *context); =20 + +/** + * qio_task_wait_thread: + * @task: the task struct + * + * Wait for completion of a task that was previously + * invoked using qio_task_run_in_thread. This MUST + * ONLY be invoked if the task has not already + * completed, since after the completion callback + * is invoked, @task will have been freed. + * + * To avoid racing with execution of the completion + * callback provided with qio_task_new, this method + * MUST ONLY be invoked from the thread that is + * running the main loop associated with @context + * parameter to qio_task_run_in_thread. + * + * When the thread has completed, the completion + * callback provided to qio_task_new will be invoked. + * When that callback returns @task will be freed, + * so @task must not be referenced after this + * method completes. + */ +void qio_task_wait_thread(QIOTask *task); + + /** * qio_task_complete: * @task: the task struct diff --git a/io/task.c b/io/task.c index 396866b10f..64c4c7126a 100644 --- a/io/task.c +++ b/io/task.c @@ -29,6 +29,7 @@ struct QIOTaskThreadData { gpointer opaque; GDestroyNotify destroy; GMainContext *context; + GSource *completion; }; =20 =20 @@ -40,6 +41,8 @@ struct QIOTask { Error *err; gpointer result; GDestroyNotify destroyResult; + QemuMutex thread_lock; + QemuCond thread_cond; struct QIOTaskThreadData *thread; }; =20 @@ -58,6 +61,8 @@ QIOTask *qio_task_new(Object *source, task->func =3D func; task->opaque =3D opaque; task->destroy =3D destroy; + qemu_mutex_init(&task->thread_lock); + qemu_cond_init(&task->thread_cond); =20 trace_qio_task_new(task, source, func, opaque); =20 @@ -66,6 +71,7 @@ QIOTask *qio_task_new(Object *source, =20 static void qio_task_free(QIOTask *task) { + qemu_mutex_lock(&task->thread_lock); if (task->thread) { if (task->thread->destroy) { task->thread->destroy(task->thread->opaque); @@ -89,6 +95,10 @@ static void qio_task_free(QIOTask *task) } object_unref(task->source); =20 + qemu_mutex_unlock(&task->thread_lock); + qemu_mutex_destroy(&task->thread_lock); + qemu_cond_destroy(&task->thread_cond); + g_free(task); } =20 @@ -107,7 +117,6 @@ static gboolean qio_task_thread_result(gpointer opaque) static gpointer qio_task_thread_worker(gpointer opaque) { QIOTask *task =3D opaque; - GSource *idle; =20 trace_qio_task_thread_run(task); =20 @@ -120,9 +129,17 @@ static gpointer qio_task_thread_worker(gpointer opaque) */ trace_qio_task_thread_exit(task); =20 - idle =3D g_idle_source_new(); - g_source_set_callback(idle, qio_task_thread_result, task, NULL); - g_source_attach(idle, task->thread->context); + qemu_mutex_lock(&task->thread_lock); + + task->thread->completion =3D g_idle_source_new(); + g_source_set_callback(task->thread->completion, + qio_task_thread_result, task, NULL); + g_source_attach(task->thread->completion, + task->thread->context); + trace_qio_task_thread_source_attach(task, task->thread->completion); + + qemu_cond_signal(&task->thread_cond); + qemu_mutex_unlock(&task->thread_lock); =20 return NULL; } @@ -157,6 +174,22 @@ void qio_task_run_in_thread(QIOTask *task, } =20 =20 +void qio_task_wait_thread(QIOTask *task) +{ + qemu_mutex_lock(&task->thread_lock); + g_assert(task->thread !=3D NULL); + while (task->thread->completion =3D=3D NULL) { + qemu_cond_wait(&task->thread_cond, &task->thread_lock); + } + + trace_qio_task_thread_source_cancel(task, task->thread->completion); + g_source_destroy(task->thread->completion); + qemu_mutex_unlock(&task->thread_lock); + + qio_task_thread_result(task); +} + + void qio_task_complete(QIOTask *task) { task->func(task, task->opaque); diff --git a/io/trace-events b/io/trace-events index f70bad7cbe..07a7bbec6a 100644 --- a/io/trace-events +++ b/io/trace-events @@ -7,6 +7,8 @@ qio_task_thread_start(void *task, void *worker, void *opaqu= e) "Task thread start qio_task_thread_run(void *task) "Task thread run task=3D%p" qio_task_thread_exit(void *task) "Task thread exit task=3D%p" qio_task_thread_result(void *task) "Task thread result task=3D%p" +qio_task_thread_source_attach(void *task, void *source) "Task thread sourc= e attach task=3D%p source=3D%p" +qio_task_thread_source_cancel(void *task, void *source) "Task thread sourc= e cancel task=3D%p source=3D%p" =20 # io/channel-socket.c qio_channel_socket_new(void *ioc) "Socket new ioc=3D%p" --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076085074555.9768937829099; Wed, 13 Feb 2019 08:41:25 -0800 (PST) Received: from localhost ([127.0.0.1]:59876 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxb8-0004mq-0N for importer@patchew.org; Wed, 13 Feb 2019 11:41:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39186) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG5-00044t-O2 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005K8-2c for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48300) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-0005Cq-F3 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3ACA9C04B31A; Wed, 13 Feb 2019 16:19:26 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A36D19C7B; Wed, 13 Feb 2019 16:19:25 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:53 +0100 Message-Id: <20190213161913.22107-6-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Feb 2019 16:19:26 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 05/25] chardev: fix validation of options for QMP created chardevs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The TLS creds option is not valid with certain address types. The user config was only checked for errors when parsing legacy QemuOpts, thus the user could pass unsupported values via QMP. Pull all code for validating options out into a new method qmp_chardev_validate_socket, that is called from the main qmp_chardev_open_socket method. This adds a missing check for rejecting TLS creds with the vsock address type. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-4-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 92 +++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index eaa8e8b68f..e85250b624 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -987,6 +987,65 @@ static gboolean socket_reconnect_timeout(gpointer opaq= ue) return false; } =20 + +static bool qmp_chardev_validate_socket(ChardevSocket *sock, + SocketAddress *addr, + Error **errp) +{ + /* Validate any options which have a dependency on address type */ + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_FD: + if (sock->has_reconnect) { + error_setg(errp, + "'reconnect' option is incompatible with " + "'fd' address type"); + return false; + } + if (sock->has_tls_creds && + !(sock->has_server && sock->server)) { + error_setg(errp, + "'tls_creds' option is incompatible with " + "'fd' address type as client"); + return false; + } + break; + + case SOCKET_ADDRESS_TYPE_UNIX: + if (sock->has_tls_creds) { + error_setg(errp, + "'tls_creds' option is incompatible with " + "'unix' address type"); + return false; + } + break; + + case SOCKET_ADDRESS_TYPE_INET: + break; + + case SOCKET_ADDRESS_TYPE_VSOCK: + if (sock->has_tls_creds) { + error_setg(errp, + "'tls_creds' option is incompatible with " + "'vsock' address type"); + return false; + } + + default: + break; + } + + /* Validate any options which have a dependancy on client vs server */ + if (!(sock->has_server && sock->server)) { + if (sock->has_websocket && sock->websocket) { + error_setg(errp, "%s", "Websocket client is not implemented"); + return false; + } + } + + return true; +} + + static void qmp_chardev_open_socket(Chardev *chr, ChardevBackend *backend, bool *be_opened, @@ -1004,11 +1063,6 @@ static void qmp_chardev_open_socket(Chardev *chr, QIOChannelSocket *sioc =3D NULL; SocketAddress *addr; =20 - if (!is_listen && is_websock) { - error_setg(errp, "%s", "Websocket client is not implemented"); - goto error; - } - s->is_listen =3D is_listen; s->is_telnet =3D is_telnet; s->is_tn3270 =3D is_tn3270; @@ -1049,10 +1103,10 @@ static void qmp_chardev_open_socket(Chardev *chr, =20 s->addr =3D addr =3D socket_address_flatten(sock->addr); =20 - if (sock->has_reconnect && addr->type =3D=3D SOCKET_ADDRESS_TYPE_FD) { - error_setg(errp, "'reconnect' option is incompatible with 'fd'"); + if (!qmp_chardev_validate_socket(sock, addr, errp)) { goto error; } + qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE); /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */ if (addr->type =3D=3D SOCKET_ADDRESS_TYPE_UNIX) { @@ -1140,27 +1194,12 @@ static void qemu_chr_parse_socket(QemuOpts *opts, C= hardevBackend *backend, return; } =20 - backend->type =3D CHARDEV_BACKEND_KIND_SOCKET; - if (path) { - if (tls_creds) { - error_setg(errp, "TLS can only be used over TCP socket"); - return; - } - } else if (host) { - if (!port) { - error_setg(errp, "chardev: socket: no port given"); - return; - } - } else if (fd) { - /* We don't know what host to validate against when in client mode= */ - if (tls_creds && !is_listen) { - error_setg(errp, "TLS can not be used with pre-opened client F= D"); - return; - } - } else { - g_assert_not_reached(); + if (host && !port) { + error_setg(errp, "chardev: socket: no port given"); + return; } =20 + backend->type =3D CHARDEV_BACKEND_KIND_SOCKET; sock =3D backend->u.socket.data =3D g_new0(ChardevSocket, 1); qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); =20 @@ -1178,6 +1217,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, Cha= rdevBackend *backend, sock->wait =3D is_waitconnect; sock->has_reconnect =3D qemu_opt_find(opts, "reconnect"); sock->reconnect =3D reconnect; + sock->has_tls_creds =3D tls_creds; sock->tls_creds =3D g_strdup(tls_creds); =20 addr =3D g_new0(SocketAddressLegacy, 1); --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076257197448.7283778585447; Wed, 13 Feb 2019 08:44:17 -0800 (PST) Received: from localhost ([127.0.0.1]:59903 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxdr-0007Gk-4d for importer@patchew.org; Wed, 13 Feb 2019 11:44:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39306) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGB-00049I-M7 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005Jw-4l for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:41 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55586) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-0005Dm-HY for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 40D2689AEC; Wed, 13 Feb 2019 16:19:28 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id B195B60BE2; Wed, 13 Feb 2019 16:19:27 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:54 +0100 Message-Id: <20190213161913.22107-7-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 13 Feb 2019 16:19:28 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 06/25] chardev: forbid 'reconnect' option with server sockets X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The 'reconnect' option is used to give the sleep time, in seconds, before a client socket attempts to re-establish a connection to the server. It does not make sense to set this for server sockets, as they will always accept a new client connection immediately after the previous one went away. Reviewed-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Thomas Huth Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-5-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index e85250b624..743b7b11cd 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1035,7 +1035,14 @@ static bool qmp_chardev_validate_socket(ChardevSocke= t *sock, } =20 /* Validate any options which have a dependancy on client vs server */ - if (!(sock->has_server && sock->server)) { + if (!sock->has_server || sock->server) { + if (sock->has_reconnect) { + error_setg(errp, + "'reconnect' option is incompatible with " + "socket in server listen mode"); + return false; + } + } else { if (sock->has_websocket && sock->websocket) { error_setg(errp, "%s", "Websocket client is not implemented"); return false; --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076247177713.690807421714; Wed, 13 Feb 2019 08:44:07 -0800 (PST) Received: from localhost ([127.0.0.1]:59901 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxdk-0007A2-44 for importer@patchew.org; Wed, 13 Feb 2019 11:44:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG4-00043i-Ef for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005JN-0O for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47734) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-0005FM-EB for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:33 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6ABE459447; Wed, 13 Feb 2019 16:19:30 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id C9A8D5C21F; Wed, 13 Feb 2019 16:19:29 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:55 +0100 Message-Id: <20190213161913.22107-8-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 13 Feb 2019 16:19:30 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 07/25] chardev: forbid 'wait' option with client sockets X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The 'wait'/'nowait' parameter is used to tell server sockets whether to block until a client is accepted during initialization. Client chardevs have always silently ignored this option. Various tests were mistakenly passing this option for their client chardevs. Reviewed-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Thomas Huth Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-6-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 12 +++++++++++- tests/ivshmem-test.c | 2 +- tests/libqtest.c | 4 ++-- tests/test-filter-redirector.c | 4 ++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 743b7b11cd..728342dc9f 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1047,6 +1047,12 @@ static bool qmp_chardev_validate_socket(ChardevSocke= t *sock, error_setg(errp, "%s", "Websocket client is not implemented"); return false; } + if (sock->has_wait) { + error_setg(errp, "%s", + "'wait' option is incompatible with " + "socket in client connect mode"); + return false; + } } =20 return true; @@ -1220,7 +1226,11 @@ static void qemu_chr_parse_socket(QemuOpts *opts, Ch= ardevBackend *backend, sock->tn3270 =3D is_tn3270; sock->has_websocket =3D true; sock->websocket =3D is_websock; - sock->has_wait =3D true; + /* + * We have different default to QMP for 'wait' when 'server' + * is set, hence we can't just check for existence of 'wait' + */ + sock->has_wait =3D qemu_opt_find(opts, "wait") || is_listen; sock->wait =3D is_waitconnect; sock->has_reconnect =3D qemu_opt_find(opts, "reconnect"); sock->reconnect =3D reconnect; diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c index 4911b69317..942ddc9192 100644 --- a/tests/ivshmem-test.c +++ b/tests/ivshmem-test.c @@ -295,7 +295,7 @@ static void setup_vm_with_server(IVState *s, int nvecto= rs) { char *cmd; =20 - cmd =3D g_strdup_printf("-chardev socket,id=3Dchr0,path=3D%s,nowait " + cmd =3D g_strdup_printf("-chardev socket,id=3Dchr0,path=3D%s " "-device ivshmem-doorbell,chardev=3Dchr0,vectors= =3D%d", tmpserver, nvectors); =20 diff --git a/tests/libqtest.c b/tests/libqtest.c index 6fb30855fa..c49b85482d 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -232,9 +232,9 @@ QTestState *qtest_init_without_qmp_handshake(const char= *extra_args) qtest_add_abrt_handler(kill_qemu_hook_func, s); =20 command =3D g_strdup_printf("exec %s " - "-qtest unix:%s,nowait " + "-qtest unix:%s " "-qtest-log %s " - "-chardev socket,path=3D%s,nowait,id=3Dchar0= " + "-chardev socket,path=3D%s,id=3Dchar0 " "-mon chardev=3Dchar0,mode=3Dcontrol " "-machine accel=3Dqtest " "-display none " diff --git a/tests/test-filter-redirector.c b/tests/test-filter-redirector.c index 9ca9feabf8..6dc21dd4fb 100644 --- a/tests/test-filter-redirector.c +++ b/tests/test-filter-redirector.c @@ -96,7 +96,7 @@ static void test_redirector_tx(void) "-device %s,netdev=3Dqtest-bn0,id=3Dqtest-e0 " "-chardev socket,id=3Dredirector0,path=3D%s,server,nowait " "-chardev socket,id=3Dredirector1,path=3D%s,server,nowait " - "-chardev socket,id=3Dredirector2,path=3D%s,nowait " + "-chardev socket,id=3Dredirector2,path=3D%s " "-object filter-redirector,id=3Dqtest-f0,netdev=3Dqtest-bn0," "queue=3Dtx,outdev=3Dredirector0 " "-object filter-redirector,id=3Dqtest-f1,netdev=3Dqtest-bn0," @@ -166,7 +166,7 @@ static void test_redirector_rx(void) "-device %s,netdev=3Dqtest-bn0,id=3Dqtest-e0 " "-chardev socket,id=3Dredirector0,path=3D%s,server,nowait " "-chardev socket,id=3Dredirector1,path=3D%s,server,nowait " - "-chardev socket,id=3Dredirector2,path=3D%s,nowait " + "-chardev socket,id=3Dredirector2,path=3D%s " "-object filter-redirector,id=3Dqtest-f0,netdev=3Dqtest-bn0," "queue=3Drx,indev=3Dredirector0 " "-object filter-redirector,id=3Dqtest-f1,netdev=3Dqtest-bn0," --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155007567536775.69278103831039; Wed, 13 Feb 2019 08:34:35 -0800 (PST) Received: from localhost ([127.0.0.1]:59731 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxUW-0007Vr-Ae for importer@patchew.org; Wed, 13 Feb 2019 11:34:32 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39194) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG5-000451-QB for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG2-0005Ky-8z for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53084) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG1-0005Hg-TQ for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:34 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8FAAB3D956; Wed, 13 Feb 2019 16:19:32 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 084FE60BE2; Wed, 13 Feb 2019 16:19:31 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:56 +0100 Message-Id: <20190213161913.22107-9-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 13 Feb 2019 16:19:32 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 08/25] chardev: remove many local variables in qemu_chr_parse_socket X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 Now that all validation is separated off into a separate method, we can directly populate the ChardevSocket struct from the QemuOpts values, avoiding many local variables. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-7-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 728342dc9f..8a6e203da7 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1186,18 +1186,10 @@ error: static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, Error **errp) { - bool is_listen =3D qemu_opt_get_bool(opts, "server", false); - bool is_waitconnect =3D is_listen && qemu_opt_get_bool(opts, "wait", t= rue); - bool is_telnet =3D qemu_opt_get_bool(opts, "telnet", false); - bool is_tn3270 =3D qemu_opt_get_bool(opts, "tn3270", false); - bool is_websock =3D qemu_opt_get_bool(opts, "websocket", false); - bool do_nodelay =3D !qemu_opt_get_bool(opts, "delay", true); - int64_t reconnect =3D qemu_opt_get_number(opts, "reconnect", 0); const char *path =3D qemu_opt_get(opts, "path"); const char *host =3D qemu_opt_get(opts, "host"); const char *port =3D qemu_opt_get(opts, "port"); const char *fd =3D qemu_opt_get(opts, "fd"); - const char *tls_creds =3D qemu_opt_get(opts, "tls-creds"); SocketAddressLegacy *addr; ChardevSocket *sock; =20 @@ -1216,26 +1208,30 @@ static void qemu_chr_parse_socket(QemuOpts *opts, C= hardevBackend *backend, sock =3D backend->u.socket.data =3D g_new0(ChardevSocket, 1); qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); =20 - sock->has_nodelay =3D true; - sock->nodelay =3D do_nodelay; + sock->has_nodelay =3D qemu_opt_get(opts, "delay"); + sock->nodelay =3D !qemu_opt_get_bool(opts, "delay", true); + /* + * We have different default to QMP for 'server', hence + * we can't just check for existence of 'server' + */ sock->has_server =3D true; - sock->server =3D is_listen; - sock->has_telnet =3D true; - sock->telnet =3D is_telnet; - sock->has_tn3270 =3D true; - sock->tn3270 =3D is_tn3270; - sock->has_websocket =3D true; - sock->websocket =3D is_websock; + sock->server =3D qemu_opt_get_bool(opts, "server", false); + sock->has_telnet =3D qemu_opt_get(opts, "telnet"); + sock->telnet =3D qemu_opt_get_bool(opts, "telnet", false); + sock->has_tn3270 =3D qemu_opt_get(opts, "tn3270"); + sock->tn3270 =3D qemu_opt_get_bool(opts, "tn3270", false); + sock->has_websocket =3D qemu_opt_get(opts, "websocket"); + sock->websocket =3D qemu_opt_get_bool(opts, "websocket", false); /* * We have different default to QMP for 'wait' when 'server' * is set, hence we can't just check for existence of 'wait' */ - sock->has_wait =3D qemu_opt_find(opts, "wait") || is_listen; - sock->wait =3D is_waitconnect; + sock->has_wait =3D qemu_opt_find(opts, "wait") || sock->server; + sock->wait =3D qemu_opt_get_bool(opts, "wait", true); sock->has_reconnect =3D qemu_opt_find(opts, "reconnect"); - sock->reconnect =3D reconnect; - sock->has_tls_creds =3D tls_creds; - sock->tls_creds =3D g_strdup(tls_creds); + sock->reconnect =3D qemu_opt_get_number(opts, "reconnect", 0); + sock->has_tls_creds =3D qemu_opt_get(opts, "tls-creds"); + sock->tls_creds =3D g_strdup(qemu_opt_get(opts, "tls-creds")); =20 addr =3D g_new0(SocketAddressLegacy, 1); if (path) { --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550075862281612.8819491262917; Wed, 13 Feb 2019 08:37:42 -0800 (PST) Received: from localhost ([127.0.0.1]:59802 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxXU-0001cc-97 for importer@patchew.org; Wed, 13 Feb 2019 11:37:36 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxG6-00045q-Im for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG4-0005OY-2M for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:38 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57446) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG3-0005MY-OV for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:35 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AD5CFC06A801; Wed, 13 Feb 2019 16:19:34 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 329AF5C21F; Wed, 13 Feb 2019 16:19:33 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:57 +0100 Message-Id: <20190213161913.22107-10-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 13 Feb 2019 16:19:34 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 09/25] chardev: ensure qemu_chr_parse_compat reports missing driver error X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 If no valid char driver was identified the qemu_chr_parse_compat method was silent, leaving callers no clue what failed. Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-8-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char.c | 2 ++ tests/test-char.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/chardev/char.c b/chardev/char.c index ccba36bafb..b99f3692f7 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -490,6 +490,8 @@ QemuOpts *qemu_chr_parse_compat(const char *label, cons= t char *filename, return opts; } =20 + error_report("'%s' is not a valid char driver", filename); + fail: qemu_opts_del(opts); return NULL; diff --git a/tests/test-char.c b/tests/test-char.c index 018e2eed93..45203f5d7a 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -932,9 +932,10 @@ static void char_null_test(void) static void char_invalid_test(void) { Chardev *chr; - + g_setenv("QTEST_SILENT_ERRORS", "1", 1); chr =3D qemu_chr_new("label-invalid", "invalid"); g_assert_null(chr); + g_unsetenv("QTEST_SILENT_ERRORS"); } =20 static int chardev_change(void *opaque) --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076427244153.5826414130063; Wed, 13 Feb 2019 08:47:07 -0800 (PST) Received: from localhost ([127.0.0.1]:59962 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxgb-0001Jv-9U for importer@patchew.org; Wed, 13 Feb 2019 11:47:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39304) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGB-00049G-M0 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxG6-0005S7-Qz for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:41 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57482) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxG6-0005Pc-6X for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:38 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DEA25C05D405; Wed, 13 Feb 2019 16:19:36 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 459FD5D9C6; Wed, 13 Feb 2019 16:19:36 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:58 +0100 Message-Id: <20190213161913.22107-11-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 13 Feb 2019 16:19:36 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 10/25] chardev: remove unused 'sioc' variable & cleanup paths X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The 'sioc' variable in qmp_chardev_open_socket was unused since commit 3e7d4d20d3a528b1ed10b1dc3d83119bfb0c5f24 Author: Peter Xu Date: Tue Mar 6 13:33:17 2018 +0800 chardev: use chardev's gcontext for async connect Reviewed-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Thomas Huth Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-9-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 8a6e203da7..8a5e5c2fe7 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1073,7 +1073,6 @@ static void qmp_chardev_open_socket(Chardev *chr, bool is_waitconnect =3D sock->has_wait ? sock->wait : false; bool is_websock =3D sock->has_websocket ? sock->websocket : false; int64_t reconnect =3D sock->has_reconnect ? sock->reconnect : 0; - QIOChannelSocket *sioc =3D NULL; SocketAddress *addr; =20 s->is_listen =3D is_listen; @@ -1088,7 +1087,7 @@ static void qmp_chardev_open_socket(Chardev *chr, if (!creds) { error_setg(errp, "No TLS credentials with id '%s'", sock->tls_creds); - goto error; + return; } s->tls_creds =3D (QCryptoTLSCreds *) object_dynamic_cast(creds, @@ -1096,20 +1095,20 @@ static void qmp_chardev_open_socket(Chardev *chr, if (!s->tls_creds) { error_setg(errp, "Object with id '%s' is not TLS credentials", sock->tls_creds); - goto error; + return; } object_ref(OBJECT(s->tls_creds)); if (is_listen) { if (s->tls_creds->endpoint !=3D QCRYPTO_TLS_CREDS_ENDPOINT_SER= VER) { error_setg(errp, "%s", "Expected TLS credentials for server endpoint"); - goto error; + return; } } else { if (s->tls_creds->endpoint !=3D QCRYPTO_TLS_CREDS_ENDPOINT_CLI= ENT) { error_setg(errp, "%s", "Expected TLS credentials for client endpoint"); - goto error; + return; } } } @@ -1117,7 +1116,7 @@ static void qmp_chardev_open_socket(Chardev *chr, s->addr =3D addr =3D socket_address_flatten(sock->addr); =20 if (!qmp_chardev_validate_socket(sock, addr, errp)) { - goto error; + return; } =20 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE); @@ -1153,7 +1152,7 @@ static void qmp_chardev_open_socket(Chardev *chr, if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0= ) { object_unref(OBJECT(s->listener)); s->listener =3D NULL; - goto error; + return; } =20 qapi_free_SocketAddress(s->addr); @@ -1171,16 +1170,9 @@ static void qmp_chardev_open_socket(Chardev *chr, chr->gcontext); } } else if (qemu_chr_wait_connected(chr, errp) < 0) { - goto error; + return; } } - - return; - -error: - if (sioc) { - object_unref(OBJECT(sioc)); - } } =20 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076616858115.692995173329; Wed, 13 Feb 2019 08:50:16 -0800 (PST) Received: from localhost ([127.0.0.1]:59998 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxja-0003e5-GI for importer@patchew.org; Wed, 13 Feb 2019 11:50:06 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39337) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGD-0004BU-N7 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGB-0005XB-QV for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:45 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48522) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGA-0005Su-Ps for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:43 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 13A75C047B7A; Wed, 13 Feb 2019 16:19:39 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7530819C7B; Wed, 13 Feb 2019 16:19:38 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:18:59 +0100 Message-Id: <20190213161913.22107-12-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Feb 2019 16:19:39 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 11/25] chardev: split tcp_chr_wait_connected into two methods X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The tcp_chr_wait_connected method can deal with either server or client chardevs, but some callers only care about one of these possibilities. The tcp_chr_wait_connected method will also need some refactoring to reliably deal with its primary goal of allowing a device frontend to wait for an established connection, which will interfere with other callers. Split it into two methods, one responsible for server initiated connections, the other responsible for client initiated connections. In doing this split the tcp_char_connect_async() method is renamed to become consistent with naming of the new methods. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-10-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 59 +++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 8a5e5c2fe7..222adbbad3 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -886,30 +886,47 @@ static void tcp_chr_accept(QIONetListener *listener, tcp_chr_new_client(chr, cioc); } =20 -static int tcp_chr_wait_connected(Chardev *chr, Error **errp) + +static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp) +{ + SocketChardev *s =3D SOCKET_CHARDEV(chr); + QIOChannelSocket *sioc =3D qio_channel_socket_new(); + tcp_chr_set_client_ioc_name(chr, sioc); + if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { + object_unref(OBJECT(sioc)); + return -1; + } + tcp_chr_new_client(chr, sioc); + object_unref(OBJECT(sioc)); + return 0; +} + + +static void tcp_chr_accept_server_sync(Chardev *chr) { SocketChardev *s =3D SOCKET_CHARDEV(chr); QIOChannelSocket *sioc; + info_report("QEMU waiting for connection on: %s", + chr->filename); + sioc =3D qio_net_listener_wait_client(s->listener); + tcp_chr_set_client_ioc_name(chr, sioc); + tcp_chr_new_client(chr, sioc); + object_unref(OBJECT(sioc)); +} + =20 +static int tcp_chr_wait_connected(Chardev *chr, Error **errp) +{ + SocketChardev *s =3D SOCKET_CHARDEV(chr); /* It can't wait on s->connected, since it is set asynchronously * in TLS and telnet cases, only wait for an accepted socket */ while (!s->ioc) { if (s->is_listen) { - info_report("QEMU waiting for connection on: %s", - chr->filename); - sioc =3D qio_net_listener_wait_client(s->listener); - tcp_chr_set_client_ioc_name(chr, sioc); - tcp_chr_new_client(chr, sioc); - object_unref(OBJECT(sioc)); + tcp_chr_accept_server_sync(chr); } else { - sioc =3D qio_channel_socket_new(); - tcp_chr_set_client_ioc_name(chr, sioc); - if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { - object_unref(OBJECT(sioc)); + if (tcp_chr_connect_client_sync(chr, errp) < 0) { return -1; } - tcp_chr_new_client(chr, sioc); - object_unref(OBJECT(sioc)); } } =20 @@ -958,7 +975,7 @@ cleanup: object_unref(OBJECT(sioc)); } =20 -static void tcp_chr_connect_async(Chardev *chr) +static void tcp_chr_connect_client_async(Chardev *chr) { SocketChardev *s =3D SOCKET_CHARDEV(chr); QIOChannelSocket *sioc; @@ -982,7 +999,7 @@ static gboolean socket_reconnect_timeout(gpointer opaqu= e) return false; } =20 - tcp_chr_connect_async(chr); + tcp_chr_connect_client_async(chr); =20 return false; } @@ -1139,7 +1156,7 @@ static void qmp_chardev_open_socket(Chardev *chr, } =20 if (s->reconnect_time) { - tcp_chr_connect_async(chr); + tcp_chr_connect_client_async(chr); } else { if (s->is_listen) { char *name; @@ -1159,17 +1176,15 @@ static void qmp_chardev_open_socket(Chardev *chr, s->addr =3D socket_local_address(s->listener->sioc[0]->fd, err= p); update_disconnected_filename(s); =20 - if (is_waitconnect && - qemu_chr_wait_connected(chr, errp) < 0) { - return; - } - if (!s->ioc) { + if (is_waitconnect) { + tcp_chr_accept_server_sync(chr); + } else { qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept, chr, NULL, chr->gcontext); } - } else if (qemu_chr_wait_connected(chr, errp) < 0) { + } else if (tcp_chr_connect_client_sync(chr, errp) < 0) { return; } } --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076784395128.61350839842476; Wed, 13 Feb 2019 08:53:04 -0800 (PST) Received: from localhost ([127.0.0.1]:60059 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxmP-00067V-Aw for importer@patchew.org; Wed, 13 Feb 2019 11:53:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39359) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGF-0004Dn-MT for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGD-0005a0-Oc for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:47 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50890) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGB-0005V0-Pc for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:45 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3F772A78B; Wed, 13 Feb 2019 16:19:41 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9ADBD61084; Wed, 13 Feb 2019 16:19:40 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:00 +0100 Message-Id: <20190213161913.22107-13-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 13 Feb 2019 16:19:41 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 12/25] chardev: split up qmp_chardev_open_socket connection code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 In qmp_chardev_open_socket the code for connecting client chardevs is split across two conditionals far apart with some server chardev code in the middle. Split up the method so that code for client connection setup is separate from code for server connection setup. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-11-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 96 +++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 222adbbad3..90dafef7d4 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1005,6 +1005,61 @@ static gboolean socket_reconnect_timeout(gpointer op= aque) } =20 =20 +static int qmp_chardev_open_socket_server(Chardev *chr, + bool is_telnet, + bool is_waitconnect, + Error **errp) +{ + SocketChardev *s =3D SOCKET_CHARDEV(chr); + char *name; + if (is_telnet) { + s->do_telnetopt =3D 1; + } + s->listener =3D qio_net_listener_new(); + + name =3D g_strdup_printf("chardev-tcp-listener-%s", chr->label); + qio_net_listener_set_name(s->listener, name); + g_free(name); + + if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) { + object_unref(OBJECT(s->listener)); + s->listener =3D NULL; + return -1; + } + + qapi_free_SocketAddress(s->addr); + s->addr =3D socket_local_address(s->listener->sioc[0]->fd, errp); + update_disconnected_filename(s); + + if (is_waitconnect) { + tcp_chr_accept_server_sync(chr); + } else { + qio_net_listener_set_client_func_full(s->listener, + tcp_chr_accept, + chr, NULL, + chr->gcontext); + } + + return 0; +} + + +static int qmp_chardev_open_socket_client(Chardev *chr, + int64_t reconnect, + Error **errp) +{ + SocketChardev *s =3D SOCKET_CHARDEV(chr); + + if (reconnect > 0) { + s->reconnect_time =3D reconnect; + tcp_chr_connect_client_async(chr); + return 0; + } else { + return tcp_chr_connect_client_sync(chr, errp); + } +} + + static bool qmp_chardev_validate_socket(ChardevSocket *sock, SocketAddress *addr, Error **errp) @@ -1147,44 +1202,13 @@ static void qmp_chardev_open_socket(Chardev *chr, =20 update_disconnected_filename(s); =20 - if (is_listen) { - if (is_telnet || is_tn3270) { - s->do_telnetopt =3D 1; + if (s->is_listen) { + if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270, + is_waitconnect, errp) < 0) { + return; } - } else if (reconnect > 0) { - s->reconnect_time =3D reconnect; - } - - if (s->reconnect_time) { - tcp_chr_connect_client_async(chr); } else { - if (s->is_listen) { - char *name; - s->listener =3D qio_net_listener_new(); - - name =3D g_strdup_printf("chardev-tcp-listener-%s", chr->label= ); - qio_net_listener_set_name(s->listener, name); - g_free(name); - - if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0= ) { - object_unref(OBJECT(s->listener)); - s->listener =3D NULL; - return; - } - - qapi_free_SocketAddress(s->addr); - s->addr =3D socket_local_address(s->listener->sioc[0]->fd, err= p); - update_disconnected_filename(s); - - if (is_waitconnect) { - tcp_chr_accept_server_sync(chr); - } else { - qio_net_listener_set_client_func_full(s->listener, - tcp_chr_accept, - chr, NULL, - chr->gcontext); - } - } else if (tcp_chr_connect_client_sync(chr, errp) < 0) { + if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) { return; } } --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 15500771143941004.4512407237476; Wed, 13 Feb 2019 08:58:34 -0800 (PST) Received: from localhost ([127.0.0.1]:60166 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxrg-0002Nr-Ac for importer@patchew.org; Wed, 13 Feb 2019 11:58:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39379) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGH-0004GM-OF for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGF-0005bx-MO for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:49 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38020) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGD-0005WV-Lr for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:45 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 602B281F25; Wed, 13 Feb 2019 16:19:43 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id C267160856; Wed, 13 Feb 2019 16:19:42 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:01 +0100 Message-Id: <20190213161913.22107-14-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 13 Feb 2019 16:19:43 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 13/25] chardev: use a state machine for socket connection state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The socket connection state is indicated via the 'bool connected' field in the SocketChardev struct. This variable is somewhat misleading though, as it is only set to true once the connection has completed all required handshakes (eg for TLS, telnet or websockets). IOW there is a period of time in which the socket is connected, but the "connected" flag is still false. The socket chardev really has three states that it can be in, disconnected, connecting and connected and those should be tracked explicitly. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-12-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 63 +++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 90dafef7d4..d6de5d2305 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -46,6 +46,12 @@ typedef struct { size_t buflen; } TCPChardevTelnetInit; =20 +typedef enum { + TCP_CHARDEV_STATE_DISCONNECTED, + TCP_CHARDEV_STATE_CONNECTING, + TCP_CHARDEV_STATE_CONNECTED, +} TCPChardevState; + typedef struct { Chardev parent; QIOChannel *ioc; /* Client I/O channel */ @@ -53,7 +59,7 @@ typedef struct { QIONetListener *listener; GSource *hup_source; QCryptoTLSCreds *tls_creds; - int connected; + TCPChardevState state; int max_size; int do_telnetopt; int do_nodelay; @@ -82,6 +88,21 @@ typedef struct { static gboolean socket_reconnect_timeout(gpointer opaque); static void tcp_chr_telnet_init(Chardev *chr); =20 +static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state) +{ + switch (state) { + case TCP_CHARDEV_STATE_DISCONNECTED: + break; + case TCP_CHARDEV_STATE_CONNECTING: + assert(s->state =3D=3D TCP_CHARDEV_STATE_DISCONNECTED); + break; + case TCP_CHARDEV_STATE_CONNECTED: + assert(s->state =3D=3D TCP_CHARDEV_STATE_CONNECTING); + break; + } + s->state =3D state; +} + static void tcp_chr_reconn_timer_cancel(SocketChardev *s) { if (s->reconnect_timer) { @@ -96,7 +117,7 @@ static void qemu_chr_socket_restart_timer(Chardev *chr) SocketChardev *s =3D SOCKET_CHARDEV(chr); char *name; =20 - assert(s->connected =3D=3D 0); + assert(s->state =3D=3D TCP_CHARDEV_STATE_DISCONNECTED); name =3D g_strdup_printf("chardev-socket-reconnect-%s", chr->label); s->reconnect_timer =3D qemu_chr_timeout_add_ms(chr, s->reconnect_time * 1000, @@ -131,7 +152,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *b= uf, int len) { SocketChardev *s =3D SOCKET_CHARDEV(chr); =20 - if (s->connected) { + if (s->state =3D=3D TCP_CHARDEV_STATE_CONNECTED) { int ret =3D io_channel_send_full(s->ioc, buf, len, s->write_msgfds, s->write_msgfds_num); @@ -164,7 +185,7 @@ static int tcp_chr_read_poll(void *opaque) { Chardev *chr =3D CHARDEV(opaque); SocketChardev *s =3D SOCKET_CHARDEV(opaque); - if (!s->connected) { + if (s->state !=3D TCP_CHARDEV_STATE_CONNECTED) { return 0; } s->max_size =3D qemu_chr_be_can_write(chr); @@ -277,7 +298,7 @@ static int tcp_set_msgfds(Chardev *chr, int *fds, int n= um) s->write_msgfds =3D NULL; s->write_msgfds_num =3D 0; =20 - if (!s->connected || + if ((s->state !=3D TCP_CHARDEV_STATE_CONNECTED) || !qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { return -1; @@ -389,7 +410,7 @@ static void tcp_chr_free_connection(Chardev *chr) s->ioc =3D NULL; g_free(chr->filename); chr->filename =3D NULL; - s->connected =3D 0; + tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); } =20 static const char *qemu_chr_socket_protocol(SocketChardev *s) @@ -442,12 +463,12 @@ static void update_disconnected_filename(SocketCharde= v *s) =20 /* NB may be called even if tcp_chr_connect has not been * reached, due to TLS or telnet initialization failure, - * so can *not* assume s->connected =3D=3D true + * so can *not* assume s->state =3D=3D TCP_CHARDEV_STATE_CONNECTED */ static void tcp_chr_disconnect(Chardev *chr) { SocketChardev *s =3D SOCKET_CHARDEV(chr); - bool emit_close =3D s->connected; + bool emit_close =3D s->state =3D=3D TCP_CHARDEV_STATE_CONNECTED; =20 tcp_chr_free_connection(chr); =20 @@ -471,7 +492,8 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondi= tion cond, void *opaque) uint8_t buf[CHR_READ_BUF_LEN]; int len, size; =20 - if (!s->connected || s->max_size <=3D 0) { + if ((s->state !=3D TCP_CHARDEV_STATE_CONNECTED) || + s->max_size <=3D 0) { return TRUE; } len =3D sizeof(buf); @@ -508,7 +530,7 @@ static int tcp_chr_sync_read(Chardev *chr, const uint8_= t *buf, int len) SocketChardev *s =3D SOCKET_CHARDEV(chr); int size; =20 - if (!s->connected) { + if (s->state !=3D TCP_CHARDEV_STATE_CONNECTED) { return 0; } =20 @@ -564,7 +586,7 @@ static void update_ioc_handlers(SocketChardev *s) { Chardev *chr =3D CHARDEV(s); =20 - if (!s->connected) { + if (s->state !=3D TCP_CHARDEV_STATE_CONNECTED) { return; } =20 @@ -589,7 +611,7 @@ static void tcp_chr_connect(void *opaque) g_free(chr->filename); chr->filename =3D qemu_chr_compute_filename(s); =20 - s->connected =3D 1; + tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED); update_ioc_handlers(s); qemu_chr_be_event(chr, CHR_EVENT_OPENED); } @@ -828,7 +850,7 @@ static int tcp_chr_new_client(Chardev *chr, QIOChannelS= ocket *sioc) { SocketChardev *s =3D SOCKET_CHARDEV(chr); =20 - if (s->ioc !=3D NULL) { + if (s->state !=3D TCP_CHARDEV_STATE_CONNECTING) { return -1; } =20 @@ -865,11 +887,17 @@ static int tcp_chr_add_client(Chardev *chr, int fd) { int ret; QIOChannelSocket *sioc; + SocketChardev *s =3D SOCKET_CHARDEV(chr); + + if (s->state !=3D TCP_CHARDEV_STATE_DISCONNECTED) { + return -1; + } =20 sioc =3D qio_channel_socket_new_fd(fd, NULL); if (!sioc) { return -1; } + tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_set_client_ioc_name(chr, sioc); ret =3D tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); @@ -881,7 +909,9 @@ static void tcp_chr_accept(QIONetListener *listener, void *opaque) { Chardev *chr =3D CHARDEV(opaque); + SocketChardev *s =3D SOCKET_CHARDEV(chr); =20 + tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_set_client_ioc_name(chr, cioc); tcp_chr_new_client(chr, cioc); } @@ -891,8 +921,10 @@ static int tcp_chr_connect_client_sync(Chardev *chr, E= rror **errp) { SocketChardev *s =3D SOCKET_CHARDEV(chr); QIOChannelSocket *sioc =3D qio_channel_socket_new(); + tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_set_client_ioc_name(chr, sioc); if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { + tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); object_unref(OBJECT(sioc)); return -1; } @@ -908,6 +940,7 @@ static void tcp_chr_accept_server_sync(Chardev *chr) QIOChannelSocket *sioc; info_report("QEMU waiting for connection on: %s", chr->filename); + tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); sioc =3D qio_net_listener_wait_client(s->listener); tcp_chr_set_client_ioc_name(chr, sioc); tcp_chr_new_client(chr, sioc); @@ -963,6 +996,7 @@ static void qemu_chr_socket_connected(QIOTask *task, vo= id *opaque) Error *err =3D NULL; =20 if (qio_task_propagate_error(task, &err)) { + tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); check_report_connect_error(chr, err); error_free(err); goto cleanup; @@ -980,6 +1014,7 @@ static void tcp_chr_connect_client_async(Chardev *chr) SocketChardev *s =3D SOCKET_CHARDEV(chr); QIOChannelSocket *sioc; =20 + tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); sioc =3D qio_channel_socket_new(); tcp_chr_set_client_ioc_name(chr, sioc); qio_channel_socket_connect_async(sioc, s->addr, @@ -1307,7 +1342,7 @@ char_socket_get_connected(Object *obj, Error **errp) { SocketChardev *s =3D SOCKET_CHARDEV(obj); =20 - return s->connected; + return s->state =3D=3D TCP_CHARDEV_STATE_CONNECTED; } =20 static void char_socket_class_init(ObjectClass *oc, void *data) --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076949950864.8940227642604; Wed, 13 Feb 2019 08:55:49 -0800 (PST) Received: from localhost ([127.0.0.1]:60134 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxp1-00008J-CZ for importer@patchew.org; Wed, 13 Feb 2019 11:55:43 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39380) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGH-0004GN-Oc for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGF-0005cF-RB for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:49 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53338) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGF-0005a9-LD for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:47 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AF37A3697F; Wed, 13 Feb 2019 16:19:45 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id E87AC19C7B; Wed, 13 Feb 2019 16:19:44 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:02 +0100 Message-Id: <20190213161913.22107-15-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 13 Feb 2019 16:19:45 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 14/25] chardev: honour the reconnect setting in tcp_chr_wait_connected X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 If establishing a client connection fails, the tcp_chr_wait_connected method should sleep for the reconnect timeout and then retry the attempt. This ensures the callers don't immediately abort with an error when the initial connection fails. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-13-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index d6de5d2305..7db20ff0a0 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -957,8 +957,15 @@ static int tcp_chr_wait_connected(Chardev *chr, Error = **errp) if (s->is_listen) { tcp_chr_accept_server_sync(chr); } else { - if (tcp_chr_connect_client_sync(chr, errp) < 0) { - return -1; + Error *err =3D NULL; + if (tcp_chr_connect_client_sync(chr, &err) < 0) { + if (s->reconnect_time) { + error_free(err); + g_usleep(s->reconnect_time * 1000ULL * 1000ULL); + } else { + error_propagate(errp, err); + return -1; + } } } } --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076181736943.280163494834; Wed, 13 Feb 2019 08:43:01 -0800 (PST) Received: from localhost ([127.0.0.1]:59895 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxcg-0006CH-LV for importer@patchew.org; Wed, 13 Feb 2019 11:42:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39405) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGL-0004KJ-Es for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGJ-0005e9-FW for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:53 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32770) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGH-0005cN-NS for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:51 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B8F7288306; Wed, 13 Feb 2019 16:19:47 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3481719C7B; Wed, 13 Feb 2019 16:19:47 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:03 +0100 Message-Id: <20190213161913.22107-16-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 13 Feb 2019 16:19:47 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 15/25] chardev: disallow TLS/telnet/websocket with tcp_chr_wait_connected X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 In the previous commit commit 1dc8a6695c731abb7461c637b2512c3670d82be4 Author: Marc-Andr=C3=A9 Lureau Date: Tue Aug 16 12:33:32 2016 +0400 char: fix waiting for TLS and telnet connection the tcp_chr_wait_connected() method was changed to check for a non-NULL 's->ioc' as a sign that there is already a connection present, as opposed to checking the "connected" flag to supposedly fix handling of TLS/telnet connections. The original code would repeatedly call tcp_chr_wait_connected creating many connections as 'connected' would never become true. The changed code would still repeatedly call tcp_chr_wait_connected busy waiting because s->ioc is set but the chardev will never see CHR_EVENT_OPENED. IOW, the code is still broken with TLS/telnet, but in a different way. Checking for a non-NULL 's->ioc' does not mean that a CHR_EVENT_OPENED will be ready for a TLS/telnet connection. These protocols (and the websocket protocol) all require the main loop to be running in order to complete the protocol handshake before emitting CHR_EVENT_OPENED. The tcp_chr_wait_connected() method is only used during early startup before a main loop is running, so TLS/telnet/websock connections can never complete initialization. Making this work would require changing tcp_chr_wait_connected to run a main loop. This is quite complex since we must not allow GSource's that other parts of QEMU have registered to run yet. The current callers of tcp_chr_wait_connected do not require use of the TLS/telnet/websocket protocols, so the simplest option is to just forbid this combination completely for now. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-14-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 7db20ff0a0..86c1f502d6 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -951,8 +951,20 @@ static void tcp_chr_accept_server_sync(Chardev *chr) static int tcp_chr_wait_connected(Chardev *chr, Error **errp) { SocketChardev *s =3D SOCKET_CHARDEV(chr); - /* It can't wait on s->connected, since it is set asynchronously - * in TLS and telnet cases, only wait for an accepted socket */ + const char *opts[] =3D { "telnet", "tn3270", "websock", "tls-creds" }; + bool optset[] =3D { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_= creds }; + size_t i; + + QEMU_BUILD_BUG_ON(G_N_ELEMENTS(opts) !=3D G_N_ELEMENTS(optset)); + for (i =3D 0; i < G_N_ELEMENTS(opts); i++) { + if (optset[i]) { + error_setg(errp, + "'%s' option is incompatible with waiting for " + "connection completion", opts[i]); + return -1; + } + } + while (!s->ioc) { if (s->is_listen) { tcp_chr_accept_server_sync(chr); --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550077279934379.83971763574084; Wed, 13 Feb 2019 09:01:19 -0800 (PST) Received: from localhost ([127.0.0.1]:60233 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxuN-0004jv-NG for importer@patchew.org; Wed, 13 Feb 2019 12:01:15 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39417) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGN-0004MU-Cv for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGL-0005fs-FS for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:55 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51148) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGJ-0005dj-E4 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:52 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0EC04461D2; Wed, 13 Feb 2019 16:19:50 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4D04919C7B; Wed, 13 Feb 2019 16:19:49 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:04 +0100 Message-Id: <20190213161913.22107-17-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 13 Feb 2019 16:19:50 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 16/25] chardev: fix race with client connections in tcp_chr_wait_connected X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 When the 'reconnect' option is given for a client connection, the qmp_chardev_open_socket_client method will run an asynchronous connection attempt. The QIOChannel socket executes this is a single use background thread, so the connection will succeed immediately (assuming the server is listening). The chardev, however, won't get the result from this background thread until the main loop starts running and processes idle callbacks. Thus when tcp_chr_wait_connected is run s->ioc will be NULL, but the state will be TCP_CHARDEV_STATE_CONNECTING, and there may already be an established connection that will be associated with the chardev by the pending idle callback. tcp_chr_wait_connected doesn't check the state, only s->ioc, so attempts to establish another connection synchronously. If the server allows multiple connections this is unhelpful but not a fatal problem as the duplicate connection will get ignored by the tcp_chr_new_client method when it sees the state is already connected. If the server only supports a single connection, however, the tcp_chr_wait_connected method will hang forever because the server will not accept its synchronous connection attempt until the first connection is closed. To deal with this tcp_chr_wait_connected needs to synchronize with the completion of the background connection task. To do this it needs to create the QIOTask directly and use the qio_task_wait_thread method. This will cancel the pending idle callback and directly dispatch the task completion callback, allowing the connection to be associated with the chardev. If the background connection failed, it can still attempt a new synchronous connection. Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-15-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-socket.c | 90 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 86c1f502d6..4fcdd8aedd 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -80,6 +80,8 @@ typedef struct { GSource *reconnect_timer; int64_t reconnect_time; bool connect_err_reported; + + QIOTask *connect_task; } SocketChardev; =20 #define SOCKET_CHARDEV(obj) \ @@ -118,6 +120,7 @@ static void qemu_chr_socket_restart_timer(Chardev *chr) char *name; =20 assert(s->state =3D=3D TCP_CHARDEV_STATE_DISCONNECTED); + assert(!s->reconnect_timer); name =3D g_strdup_printf("chardev-socket-reconnect-%s", chr->label); s->reconnect_timer =3D qemu_chr_timeout_add_ms(chr, s->reconnect_time * 1000, @@ -965,7 +968,56 @@ static int tcp_chr_wait_connected(Chardev *chr, Error = **errp) } } =20 - while (!s->ioc) { + tcp_chr_reconn_timer_cancel(s); + + /* + * We expect states to be as follows: + * + * - server + * - wait -> CONNECTED + * - nowait -> DISCONNECTED + * - client + * - reconnect =3D=3D 0 -> CONNECTED + * - reconnect !=3D 0 -> CONNECTING + * + */ + if (s->state =3D=3D TCP_CHARDEV_STATE_CONNECTING) { + if (!s->connect_task) { + error_setg(errp, + "Unexpected 'connecting' state without connect task= " + "while waiting for connection completion"); + return -1; + } + /* + * tcp_chr_wait_connected should only ever be run from the + * main loop thread associated with chr->gcontext, otherwise + * qio_task_wait_thread has a dangerous race condition with + * free'ing of the s->connect_task object. + * + * Acquiring the main context doesn't 100% prove we're in + * the main loop thread, but it does at least guarantee + * that the main loop won't be executed by another thread + * avoiding the race condition with the task idle callback. + */ + g_main_context_acquire(chr->gcontext); + qio_task_wait_thread(s->connect_task); + g_main_context_release(chr->gcontext); + + /* + * The completion callback (qemu_chr_socket_connected) for + * s->connect_task should have set this to NULL by the time + * qio_task_wait_thread has returned. + */ + assert(!s->connect_task); + + /* + * NB we are *not* guaranteed to have "s->state =3D=3D ..CONNECTED" + * at this point as this first connect may be failed, so + * allow the next loop to run regardless. + */ + } + + while (s->state !=3D TCP_CHARDEV_STATE_CONNECTED) { if (s->is_listen) { tcp_chr_accept_server_sync(chr); } else { @@ -1014,6 +1066,8 @@ static void qemu_chr_socket_connected(QIOTask *task, = void *opaque) SocketChardev *s =3D SOCKET_CHARDEV(chr); Error *err =3D NULL; =20 + s->connect_task =3D NULL; + if (qio_task_propagate_error(task, &err)) { tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); check_report_connect_error(chr, err); @@ -1028,6 +1082,20 @@ cleanup: object_unref(OBJECT(sioc)); } =20 + +static void tcp_chr_connect_client_task(QIOTask *task, + gpointer opaque) +{ + QIOChannelSocket *ioc =3D QIO_CHANNEL_SOCKET(qio_task_get_source(task)= ); + SocketAddress *addr =3D opaque; + Error *err =3D NULL; + + qio_channel_socket_connect_sync(ioc, addr, &err); + + qio_task_set_error(task, err); +} + + static void tcp_chr_connect_client_async(Chardev *chr) { SocketChardev *s =3D SOCKET_CHARDEV(chr); @@ -1036,9 +1104,23 @@ static void tcp_chr_connect_client_async(Chardev *ch= r) tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); sioc =3D qio_channel_socket_new(); tcp_chr_set_client_ioc_name(chr, sioc); - qio_channel_socket_connect_async(sioc, s->addr, - qemu_chr_socket_connected, - chr, NULL, chr->gcontext); + /* + * Normally code would use the qio_channel_socket_connect_async + * method which uses a QIOTask + qio_task_set_error internally + * to avoid blocking. The tcp_chr_wait_connected method, however, + * needs a way to synchronize with completion of the background + * connect task which can't be done with the QIOChannelSocket + * async APIs. Thus we must use QIOTask directly to implement + * the non-blocking concept locally. + */ + s->connect_task =3D qio_task_new(OBJECT(sioc), + qemu_chr_socket_connected, + chr, NULL); + qio_task_run_in_thread(s->connect_task, + tcp_chr_connect_client_task, + s->addr, + NULL, + chr->gcontext); } =20 static gboolean socket_reconnect_timeout(gpointer opaque) --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076346974902.7737863909667; Wed, 13 Feb 2019 08:45:46 -0800 (PST) Received: from localhost ([127.0.0.1]:59933 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxfI-0000Et-OT for importer@patchew.org; Wed, 13 Feb 2019 11:45:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39447) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGP-0004Of-PR for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGN-0005gz-Ep for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:57 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48264) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGL-0005fV-Dt for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:55 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5912561E73; Wed, 13 Feb 2019 16:19:52 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7F37B1974C; Wed, 13 Feb 2019 16:19:51 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:05 +0100 Message-Id: <20190213161913.22107-18-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 13 Feb 2019 16:19:52 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 17/25] tests: expand coverage of socket chardev test X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 The current socket chardev tests try to exercise the chardev socket driver in both server and client mode at the same time. The chardev API is not very well designed to handle both ends of the connection being in the same process so this approach makes the test case quite unpleasant to deal with. This splits the tests into distinct cases, one to test server socket chardevs and one to test client socket chardevs. In each case the peer is run in a background thread using the simpler QIOChannelSocket APIs. The main test case code can now be written in a way that mirrors the typical usage from within QEMU. In doing this recfactoring it is possible to greatly expand the test coverage for the socket chardevs to test all combinations except for a server operating in blocking wait mode. Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-16-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- tests/test-char.c | 640 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 475 insertions(+), 165 deletions(-) diff --git a/tests/test-char.c b/tests/test-char.c index 45203f5d7a..82579e6aa5 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -11,6 +11,9 @@ #include "qapi/qapi-commands-char.h" #include "qapi/qmp/qdict.h" #include "qom/qom-qobject.h" +#include "io/channel-socket.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/qapi-visit-sockets.h" =20 static bool quit; =20 @@ -333,168 +336,6 @@ static void char_mux_test(void) qemu_chr_fe_deinit(&chr_be2, true); } =20 -typedef struct SocketIdleData { - GMainLoop *loop; - Chardev *chr; - bool conn_expected; - CharBackend *be; - CharBackend *client_be; -} SocketIdleData; - -static gboolean char_socket_test_idle(gpointer user_data) -{ - SocketIdleData *data =3D user_data; - - if (object_property_get_bool(OBJECT(data->chr), "connected", NULL) - =3D=3D data->conn_expected) { - quit =3D true; - return FALSE; - } - - return TRUE; -} - -static void socket_read(void *opaque, const uint8_t *buf, int size) -{ - SocketIdleData *data =3D opaque; - - g_assert_cmpint(size, =3D=3D, 1); - g_assert_cmpint(*buf, =3D=3D, 'Z'); - - size =3D qemu_chr_fe_write(data->be, (const uint8_t *)"hello", 5); - g_assert_cmpint(size, =3D=3D, 5); -} - -static int socket_can_read(void *opaque) -{ - return 10; -} - -static void socket_read_hello(void *opaque, const uint8_t *buf, int size) -{ - g_assert_cmpint(size, =3D=3D, 5); - g_assert(strncmp((char *)buf, "hello", 5) =3D=3D 0); - - quit =3D true; -} - -static int socket_can_read_hello(void *opaque) -{ - return 10; -} - -static void char_socket_test_common(Chardev *chr, bool reconnect) -{ - Chardev *chr_client; - QObject *addr; - QDict *qdict; - const char *port; - SocketIdleData d =3D { .chr =3D chr }; - CharBackend be; - CharBackend client_be; - char *tmp; - - d.be =3D &be; - d.client_be =3D &be; - - g_assert_nonnull(chr); - g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_ab= ort)); - - addr =3D object_property_get_qobject(OBJECT(chr), "addr", &error_abort= ); - qdict =3D qobject_to(QDict, addr); - port =3D qdict_get_str(qdict, "port"); - tmp =3D g_strdup_printf("tcp:127.0.0.1:%s%s", port, - reconnect ? ",reconnect=3D1" : ""); - qobject_unref(qdict); - - qemu_chr_fe_init(&be, chr, &error_abort); - qemu_chr_fe_set_handlers(&be, socket_can_read, socket_read, - NULL, NULL, &d, NULL, true); - - chr_client =3D qemu_chr_new("client", tmp); - qemu_chr_fe_init(&client_be, chr_client, &error_abort); - qemu_chr_fe_set_handlers(&client_be, socket_can_read_hello, - socket_read_hello, - NULL, NULL, &d, NULL, true); - g_free(tmp); - - d.conn_expected =3D true; - guint id =3D g_idle_add(char_socket_test_idle, &d); - g_source_set_name_by_id(id, "test-idle"); - g_assert_cmpint(id, >, 0); - main_loop(); - - d.chr =3D chr_client; - id =3D g_idle_add(char_socket_test_idle, &d); - g_source_set_name_by_id(id, "test-idle"); - g_assert_cmpint(id, >, 0); - main_loop(); - - g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abo= rt)); - g_assert(object_property_get_bool(OBJECT(chr_client), - "connected", &error_abort)); - - qemu_chr_write_all(chr_client, (const uint8_t *)"Z", 1); - main_loop(); - - object_unparent(OBJECT(chr_client)); - - d.chr =3D chr; - d.conn_expected =3D false; - g_idle_add(char_socket_test_idle, &d); - main_loop(); - - object_unparent(OBJECT(chr)); -} - - -static void char_socket_basic_test(void) -{ - Chardev *chr =3D qemu_chr_new("server", "tcp:127.0.0.1:0,server,nowait= "); - - char_socket_test_common(chr, false); -} - - -static void char_socket_reconnect_test(void) -{ - Chardev *chr =3D qemu_chr_new("server", "tcp:127.0.0.1:0,server,nowait= "); - - char_socket_test_common(chr, true); -} - - -static void char_socket_fdpass_test(void) -{ - Chardev *chr; - char *optstr; - QemuOpts *opts; - int fd; - SocketAddress *addr =3D g_new0(SocketAddress, 1); - - addr->type =3D SOCKET_ADDRESS_TYPE_INET; - addr->u.inet.host =3D g_strdup("127.0.0.1"); - addr->u.inet.port =3D g_strdup("0"); - - fd =3D socket_listen(addr, &error_abort); - g_assert(fd >=3D 0); - - qapi_free_SocketAddress(addr); - - optstr =3D g_strdup_printf("socket,id=3Dcdev,fd=3D%d,server,nowait", f= d); - - opts =3D qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optstr, true); - g_free(optstr); - g_assert_nonnull(opts); - - chr =3D qemu_chr_new_from_opts(opts, &error_abort); - - qemu_opts_del(opts); - - char_socket_test_common(chr, false); -} - =20 static void websock_server_read(void *opaque, const uint8_t *buf, int size) { @@ -686,6 +527,28 @@ static void char_pipe_test(void) } #endif =20 +typedef struct SocketIdleData { + GMainLoop *loop; + Chardev *chr; + bool conn_expected; + CharBackend *be; + CharBackend *client_be; +} SocketIdleData; + + +static void socket_read_hello(void *opaque, const uint8_t *buf, int size) +{ + g_assert_cmpint(size, =3D=3D, 5); + g_assert(strncmp((char *)buf, "hello", 5) =3D=3D 0); + + quit =3D true; +} + +static int socket_can_read_hello(void *opaque) +{ + return 10; +} + static int make_udp_socket(int *port) { struct sockaddr_in addr =3D { 0, }; @@ -756,6 +619,391 @@ static void char_udp_test(void) char_udp_test_internal(NULL, 0); } =20 + +typedef struct { + int event; + bool got_pong; +} CharSocketTestData; + + +#define SOCKET_PING "Hello" +#define SOCKET_PONG "World" + + +static void +char_socket_event(void *opaque, int event) +{ + CharSocketTestData *data =3D opaque; + data->event =3D event; +} + + +static void +char_socket_read(void *opaque, const uint8_t *buf, int size) +{ + CharSocketTestData *data =3D opaque; + g_assert_cmpint(size, =3D=3D, sizeof(SOCKET_PONG)); + g_assert(memcmp(buf, SOCKET_PONG, size) =3D=3D 0); + data->got_pong =3D true; +} + + +static int +char_socket_can_read(void *opaque) +{ + return sizeof(SOCKET_PONG); +} + + +static char * +char_socket_addr_to_opt_str(SocketAddress *addr, bool fd_pass, + const char *reconnect, bool is_listen) +{ + if (fd_pass) { + QIOChannelSocket *ioc =3D qio_channel_socket_new(); + int fd; + char *optstr; + g_assert(!reconnect); + if (is_listen) { + qio_channel_socket_listen_sync(ioc, addr, &error_abort); + } else { + qio_channel_socket_connect_sync(ioc, addr, &error_abort); + } + fd =3D ioc->fd; + ioc->fd =3D -1; + optstr =3D g_strdup_printf("socket,id=3Dcdev0,fd=3D%d%s", + fd, is_listen ? ",server,nowait" : ""); + object_unref(OBJECT(ioc)); + return optstr; + } else { + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + return g_strdup_printf("socket,id=3Dcdev0,host=3D%s,port=3D%s%= s%s", + addr->u.inet.host, + addr->u.inet.port, + reconnect ? reconnect : "", + is_listen ? ",server,nowait" : ""); + + case SOCKET_ADDRESS_TYPE_UNIX: + return g_strdup_printf("socket,id=3Dcdev0,path=3D%s%s%s", + addr->u.q_unix.path, + reconnect ? reconnect : "", + is_listen ? ",server,nowait" : ""); + + default: + g_assert_not_reached(); + } + } +} + + +static void +char_socket_ping_pong(QIOChannel *ioc) +{ + char greeting[sizeof(SOCKET_PING)]; + const char *response =3D SOCKET_PONG; + + qio_channel_read_all(ioc, greeting, sizeof(greeting), &error_abort); + + g_assert(memcmp(greeting, SOCKET_PING, sizeof(greeting)) =3D=3D 0); + + qio_channel_write_all(ioc, response, sizeof(SOCKET_PONG), &error_abort= ); + + object_unref(OBJECT(ioc)); +} + + +static gpointer +char_socket_server_client_thread(gpointer data) +{ + SocketAddress *addr =3D data; + QIOChannelSocket *ioc =3D qio_channel_socket_new(); + + qio_channel_socket_connect_sync(ioc, addr, &error_abort); + + char_socket_ping_pong(QIO_CHANNEL(ioc)); + + return NULL; +} + + +typedef struct { + SocketAddress *addr; + bool wait_connected; + bool fd_pass; +} CharSocketServerTestConfig; + + +static void char_socket_server_test(gconstpointer opaque) +{ + const CharSocketServerTestConfig *config =3D opaque; + Chardev *chr; + CharBackend be =3D {0}; + CharSocketTestData data =3D {0}; + QObject *qaddr; + SocketAddress *addr; + Visitor *v; + QemuThread thread; + int ret; + bool reconnected; + char *optstr; + QemuOpts *opts; + + g_setenv("QTEST_SILENT_ERRORS", "1", 1); + /* + * We rely on config->addr containing "nowait", otherwise + * qemu_chr_new() will block until a client connects. We + * can't spawn our client thread though, because until + * qemu_chr_new() returns we don't know what TCP port was + * allocated by the OS + */ + optstr =3D char_socket_addr_to_opt_str(config->addr, + config->fd_pass, + NULL, + true); + opts =3D qemu_opts_parse_noisily(qemu_find_opts("chardev"), + optstr, true); + g_assert_nonnull(opts); + chr =3D qemu_chr_new_from_opts(opts, &error_abort); + qemu_opts_del(opts); + g_assert_nonnull(chr); + g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_ab= ort)); + + qaddr =3D object_property_get_qobject(OBJECT(chr), "addr", &error_abor= t); + g_assert_nonnull(qaddr); + + v =3D qobject_input_visitor_new(qaddr); + visit_type_SocketAddress(v, "addr", &addr, &error_abort); + visit_free(v); + qobject_unref(qaddr); + + qemu_chr_fe_init(&be, chr, &error_abort); + + reconnect: + data.event =3D -1; + qemu_chr_fe_set_handlers(&be, NULL, NULL, + char_socket_event, NULL, + &data, NULL, true); + g_assert(data.event =3D=3D -1); + + /* + * Kick off a thread to act as the "remote" client + * which just plays ping-pong with us + */ + qemu_thread_create(&thread, "client", + char_socket_server_client_thread, + addr, QEMU_THREAD_JOINABLE); + g_assert(data.event =3D=3D -1); + + if (config->wait_connected) { + /* Synchronously accept a connection */ + qemu_chr_wait_connected(chr, &error_abort); + } else { + /* + * Asynchronously accept a connection when the evnt + * loop reports the listener socket as readable + */ + while (data.event =3D=3D -1) { + main_loop_wait(false); + } + } + g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abo= rt)); + g_assert(data.event =3D=3D CHR_EVENT_OPENED); + data.event =3D -1; + + /* Send a greeting to the client */ + ret =3D qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING, + sizeof(SOCKET_PING)); + g_assert_cmpint(ret, =3D=3D, sizeof(SOCKET_PING)); + g_assert(data.event =3D=3D -1); + + /* Setup a callback to receive the reply to our greeting */ + qemu_chr_fe_set_handlers(&be, char_socket_can_read, + char_socket_read, + char_socket_event, NULL, + &data, NULL, true); + g_assert(data.event =3D=3D CHR_EVENT_OPENED); + data.event =3D -1; + + /* Wait for the client to go away */ + while (data.event =3D=3D -1) { + main_loop_wait(false); + } + g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_ab= ort)); + g_assert(data.event =3D=3D CHR_EVENT_CLOSED); + g_assert(data.got_pong); + + qemu_thread_join(&thread); + + if (!reconnected) { + reconnected =3D true; + goto reconnect; + } + + qapi_free_SocketAddress(addr); + object_unparent(OBJECT(chr)); + g_free(optstr); + g_unsetenv("QTEST_SILENT_ERRORS"); +} + + +static gpointer +char_socket_client_server_thread(gpointer data) +{ + QIOChannelSocket *ioc =3D data; + QIOChannelSocket *cioc; + + cioc =3D qio_channel_socket_accept(ioc, &error_abort); + g_assert_nonnull(cioc); + + char_socket_ping_pong(QIO_CHANNEL(cioc)); + + return NULL; +} + + +typedef struct { + SocketAddress *addr; + const char *reconnect; + bool wait_connected; + bool fd_pass; +} CharSocketClientTestConfig; + + +static void char_socket_client_test(gconstpointer opaque) +{ + const CharSocketClientTestConfig *config =3D opaque; + QIOChannelSocket *ioc; + char *optstr; + Chardev *chr; + CharBackend be =3D {0}; + CharSocketTestData data =3D {0}; + SocketAddress *addr; + QemuThread thread; + int ret; + bool reconnected =3D false; + QemuOpts *opts; + + /* + * Setup a listener socket and determine get its address + * so we know the TCP port for the client later + */ + ioc =3D qio_channel_socket_new(); + g_assert_nonnull(ioc); + qio_channel_socket_listen_sync(ioc, config->addr, &error_abort); + addr =3D qio_channel_socket_get_local_address(ioc, &error_abort); + g_assert_nonnull(addr); + + /* + * Kick off a thread to act as the "remote" client + * which just plays ping-pong with us + */ + qemu_thread_create(&thread, "client", + char_socket_client_server_thread, + ioc, QEMU_THREAD_JOINABLE); + + /* + * Populate the chardev address based on what the server + * is actually listening on + */ + optstr =3D char_socket_addr_to_opt_str(addr, + config->fd_pass, + config->reconnect, + false); + + opts =3D qemu_opts_parse_noisily(qemu_find_opts("chardev"), + optstr, true); + g_assert_nonnull(opts); + chr =3D qemu_chr_new_from_opts(opts, &error_abort); + qemu_opts_del(opts); + g_assert_nonnull(chr); + + if (config->reconnect) { + /* + * If reconnect is set, the connection will be + * established in a background thread and we won't + * see the "connected" status updated until we + * run the main event loop, or call qemu_chr_wait_connected + */ + g_assert(!object_property_get_bool(OBJECT(chr), "connected", + &error_abort)); + } else { + g_assert(object_property_get_bool(OBJECT(chr), "connected", + &error_abort)); + } + + qemu_chr_fe_init(&be, chr, &error_abort); + + reconnect: + data.event =3D -1; + qemu_chr_fe_set_handlers(&be, NULL, NULL, + char_socket_event, NULL, + &data, NULL, true); + if (config->reconnect) { + g_assert(data.event =3D=3D -1); + } else { + g_assert(data.event =3D=3D CHR_EVENT_OPENED); + } + + if (config->wait_connected) { + /* + * Synchronously wait for the connection to complete + * This should be a no-op if reconnect is not set. + */ + qemu_chr_wait_connected(chr, &error_abort); + } else { + /* + * Asynchronously wait for the connection to be reported + * as complete when the background thread reports its + * status. + * The loop will short-circuit if reconnect was set + */ + while (data.event =3D=3D -1) { + main_loop_wait(false); + } + } + g_assert(data.event =3D=3D CHR_EVENT_OPENED); + data.event =3D -1; + g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abo= rt)); + + /* Send a greeting to the server */ + ret =3D qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING, + sizeof(SOCKET_PING)); + g_assert_cmpint(ret, =3D=3D, sizeof(SOCKET_PING)); + g_assert(data.event =3D=3D -1); + + /* Setup a callback to receive the reply to our greeting */ + qemu_chr_fe_set_handlers(&be, char_socket_can_read, + char_socket_read, + char_socket_event, NULL, + &data, NULL, true); + g_assert(data.event =3D=3D CHR_EVENT_OPENED); + data.event =3D -1; + + /* Wait for the server to go away */ + while (data.event =3D=3D -1) { + main_loop_wait(false); + } + g_assert(data.event =3D=3D CHR_EVENT_CLOSED); + g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_ab= ort)); + g_assert(data.got_pong); + qemu_thread_join(&thread); + + if (config->reconnect && !reconnected) { + reconnected =3D true; + qemu_thread_create(&thread, "client", + char_socket_client_server_thread, + ioc, QEMU_THREAD_JOINABLE); + goto reconnect; + } + + object_unref(OBJECT(ioc)); + object_unparent(OBJECT(chr)); + qapi_free_SocketAddress(addr); + g_free(optstr); +} + + #ifdef HAVE_CHARDEV_SERIAL static void char_serial_test(void) { @@ -1035,9 +1283,71 @@ int main(int argc, char **argv) #ifndef _WIN32 g_test_add_func("/char/file-fifo", char_file_fifo_test); #endif - g_test_add_func("/char/socket/basic", char_socket_basic_test); - g_test_add_func("/char/socket/reconnect", char_socket_reconnect_test); - g_test_add_func("/char/socket/fdpass", char_socket_fdpass_test); + + SocketAddress tcpaddr =3D { + .type =3D SOCKET_ADDRESS_TYPE_INET, + .u.inet.host =3D (char *)"127.0.0.1", + .u.inet.port =3D (char *)"0", + }; +#ifndef WIN32 + SocketAddress unixaddr =3D { + .type =3D SOCKET_ADDRESS_TYPE_UNIX, + .u.q_unix.path =3D (char *)"test-char.sock", + }; +#endif + +#define SOCKET_SERVER_TEST(name, addr) \ + CharSocketServerTestConfig server1 ## name =3D \ + { addr, false, false }; \ + CharSocketServerTestConfig server2 ## name =3D \ + { addr, true, false }; \ + CharSocketServerTestConfig server3 ## name =3D \ + { addr, false, true }; \ + CharSocketServerTestConfig server4 ## name =3D \ + { addr, true, true }; \ + g_test_add_data_func("/char/socket/server/mainloop/" # name, \ + &server1 ##name, char_socket_server_test); \ + g_test_add_data_func("/char/socket/server/wait-conn/" # name, \ + &server2 ##name, char_socket_server_test); \ + g_test_add_data_func("/char/socket/server/mainloop-fdpass/" # name, \ + &server3 ##name, char_socket_server_test); \ + g_test_add_data_func("/char/socket/server/wait-conn-fdpass/" # name, \ + &server4 ##name, char_socket_server_test) + +#define SOCKET_CLIENT_TEST(name, addr) \ + CharSocketClientTestConfig client1 ## name =3D \ + { addr, NULL, false, false }; \ + CharSocketClientTestConfig client2 ## name =3D \ + { addr, NULL, true, false }; \ + CharSocketClientTestConfig client3 ## name =3D \ + { addr, ",reconnect=3D1", false }; \ + CharSocketClientTestConfig client4 ## name =3D \ + { addr, ",reconnect=3D1", true }; \ + CharSocketClientTestConfig client5 ## name =3D \ + { addr, NULL, false, true }; \ + CharSocketClientTestConfig client6 ## name =3D \ + { addr, NULL, true, true }; \ + g_test_add_data_func("/char/socket/client/mainloop/" # name, \ + &client1 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn/" # name, \ + &client2 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/mainloop-reconnect/" # name,= \ + &client3 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn-reconnect/" # name= , \ + &client4 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/mainloop-fdpass/" # name, \ + &client5 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \ + &client6 ##name, char_socket_client_test) + + SOCKET_SERVER_TEST(tcp, &tcpaddr); + SOCKET_CLIENT_TEST(tcp, &tcpaddr); +#ifndef WIN32 + SOCKET_SERVER_TEST(unix, &unixaddr); + SOCKET_CLIENT_TEST(unix, &unixaddr); +#endif + + g_test_add_func("/char/udp", char_udp_test); #ifdef HAVE_CHARDEV_SERIAL g_test_add_func("/char/serial", char_serial_test); --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076434548196.88956208527577; Wed, 13 Feb 2019 08:47:14 -0800 (PST) Received: from localhost ([127.0.0.1]:59965 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxgi-0001QW-Dp for importer@patchew.org; Wed, 13 Feb 2019 11:47:08 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39445) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGP-0004Oe-Le for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGO-0005ho-TK for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:57 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48856) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGN-0005gW-DY for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:56 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7B17FC047B7A; Wed, 13 Feb 2019 16:19:54 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id E5A545D6AA; Wed, 13 Feb 2019 16:19:53 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:06 +0100 Message-Id: <20190213161913.22107-19-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Feb 2019 16:19:54 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 18/25] chardev: ensure termios is fully initialized X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Daniel P. Berrang=C3=A9 valgrind on the test-char.c code reports that 'struct termios' contains uninitialized memory. Signed-off-by: Daniel P. Berrang=C3=A9 Message-Id: <20190211182442.8542-17-berrange@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/char-serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chardev/char-serial.c b/chardev/char-serial.c index 3299b46853..a8bae31b8d 100644 --- a/chardev/char-serial.c +++ b/chardev/char-serial.c @@ -57,7 +57,7 @@ static void qmp_chardev_open_serial(Chardev *chr, static void tty_serial_init(int fd, int speed, int parity, int data_bits, int stop_bits) { - struct termios tty; + struct termios tty =3D {0}; speed_t spd; =20 #if 0 --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076722173781.2706532144413; Wed, 13 Feb 2019 08:52:02 -0800 (PST) Received: from localhost ([127.0.0.1]:60052 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxlM-0005II-Va for importer@patchew.org; Wed, 13 Feb 2019 11:51:57 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39481) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGS-0004So-MX for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGQ-0005jD-1a for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51326) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGP-0005ia-N1 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:57 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E39FB13A40; Wed, 13 Feb 2019 16:19:56 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0834E60BE2; Wed, 13 Feb 2019 16:19:55 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:07 +0100 Message-Id: <20190213161913.22107-20-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 13 Feb 2019 16:19:56 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 19/25] char: allow specifying a GMainContext at opening time X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Paolo Bonzini This will be needed by vhost-user-test, when each test switches to its own GMainLoop and GMainContext. Otherwise, for a reconnecting socket the initial connection will happen on the default GMainContext, and no one will be listening on it. Signed-off-by: Paolo Bonzini Reviewed-by: Daniel P. Berrang=C3=A9 Message-Id: <20190202110834.24880-1-pbonzini@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/chardev/char.h | 16 ++++++++++++---- chardev/char.c | 32 +++++++++++++++++++------------- gdbstub.c | 4 ++-- hmp.c | 2 +- hw/arm/omap2.c | 2 +- hw/bt/hci-csr.c | 2 +- hw/char/omap_uart.c | 4 ++-- hw/char/xen_console.c | 3 ++- hw/isa/isa-superio.c | 4 ++-- hw/mips/boston.c | 2 +- hw/mips/mips_malta.c | 2 +- hw/usb/dev-serial.c | 2 +- net/slirp.c | 2 +- qtest.c | 2 +- tests/test-char.c | 38 +++++++++++++++++++------------------- tests/vhost-user-test.c | 2 +- vl.c | 8 ++++---- 17 files changed, 71 insertions(+), 56 deletions(-) diff --git a/include/chardev/char.h b/include/chardev/char.h index 014566c3de..c0b57f7685 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -73,6 +73,7 @@ struct Chardev { /** * qemu_chr_new_from_opts: * @opts: see qemu-config.c for a list of valid options + * @context: the #GMainContext to be used at initialization time * * Create a new character backend from a QemuOpts list. * @@ -81,6 +82,7 @@ struct Chardev { * or left untouched in case of help option */ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, + GMainContext *context, Error **errp); =20 /** @@ -106,25 +108,29 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, * qemu_chr_new: * @label: the name of the backend * @filename: the URI + * @context: the #GMainContext to be used at initialization time * * Create a new character backend from a URI. * Do not implicitly initialize a monitor if the chardev is muxed. * * Returns: a new character backend */ -Chardev *qemu_chr_new(const char *label, const char *filename); +Chardev *qemu_chr_new(const char *label, const char *filename, + GMainContext *context); =20 /** * qemu_chr_new_mux_mon: * @label: the name of the backend * @filename: the URI + * @context: the #GMainContext to be used at initialization time * * Create a new character backend from a URI. * Implicitly initialize a monitor if the chardev is muxed. * * Returns: a new character backend */ -Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename); +Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename, + GMainContext *context); =20 /** * qemu_chr_change: @@ -146,6 +152,7 @@ void qemu_chr_cleanup(void); * @label: the name of the backend * @filename: the URI * @permit_mux_mon: if chardev is muxed, initialize a monitor + * @context: the #GMainContext to be used at initialization time * * Create a new character backend from a URI. * Character device communications are not written @@ -154,7 +161,7 @@ void qemu_chr_cleanup(void); * Returns: a new character backend */ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename, - bool permit_mux_mon); + bool permit_mux_mon, GMainContext *context); =20 /** * qemu_chr_be_can_write: @@ -272,7 +279,8 @@ typedef struct ChardevClass { } ChardevClass; =20 Chardev *qemu_chardev_new(const char *id, const char *typename, - ChardevBackend *backend, Error **errp); + ChardevBackend *backend, GMainContext *context, + Error **errp); =20 extern int term_escape_char; =20 diff --git a/chardev/char.c b/chardev/char.c index b99f3692f7..f6d61fa5f8 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -636,7 +636,8 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Err= or **errp) return backend; } =20 -Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error **errp) +Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context, + Error **errp) { const ChardevClass *cc; Chardev *chr =3D NULL; @@ -676,7 +677,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error *= *errp) =20 chr =3D qemu_chardev_new(bid ? bid : id, object_class_get_name(OBJECT_CLASS(cc)), - backend, errp); + backend, context, errp); =20 if (chr =3D=3D NULL) { goto out; @@ -689,7 +690,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error *= *errp) backend->type =3D CHARDEV_BACKEND_KIND_MUX; backend->u.mux.data =3D g_new0(ChardevMux, 1); backend->u.mux.data->chardev =3D g_strdup(bid); - mux =3D qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, errp); + mux =3D qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, context, e= rrp); if (mux =3D=3D NULL) { object_unparent(OBJECT(chr)); chr =3D NULL; @@ -705,7 +706,7 @@ out: } =20 Chardev *qemu_chr_new_noreplay(const char *label, const char *filename, - bool permit_mux_mon) + bool permit_mux_mon, GMainContext *context) { const char *p; Chardev *chr; @@ -720,7 +721,7 @@ Chardev *qemu_chr_new_noreplay(const char *label, const= char *filename, if (!opts) return NULL; =20 - chr =3D qemu_chr_new_from_opts(opts, &err); + chr =3D qemu_chr_new_from_opts(opts, context, &err); if (!chr) { error_report_err(err); goto out; @@ -738,10 +739,11 @@ out: =20 static Chardev *qemu_chr_new_permit_mux_mon(const char *label, const char *filename, - bool permit_mux_mon) + bool permit_mux_mon, + GMainContext *context) { Chardev *chr; - chr =3D qemu_chr_new_noreplay(label, filename, permit_mux_mon); + chr =3D qemu_chr_new_noreplay(label, filename, permit_mux_mon, context= ); if (chr) { if (replay_mode !=3D REPLAY_MODE_NONE) { qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY); @@ -755,14 +757,16 @@ static Chardev *qemu_chr_new_permit_mux_mon(const cha= r *label, return chr; } =20 -Chardev *qemu_chr_new(const char *label, const char *filename) +Chardev *qemu_chr_new(const char *label, const char *filename, + GMainContext *context) { - return qemu_chr_new_permit_mux_mon(label, filename, false); + return qemu_chr_new_permit_mux_mon(label, filename, false, context); } =20 -Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename) +Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename, + GMainContext *context) { - return qemu_chr_new_permit_mux_mon(label, filename, true); + return qemu_chr_new_permit_mux_mon(label, filename, true, context); } =20 static int qmp_query_chardev_foreach(Object *obj, void *data) @@ -937,6 +941,7 @@ void qemu_chr_set_feature(Chardev *chr, =20 Chardev *qemu_chardev_new(const char *id, const char *typename, ChardevBackend *backend, + GMainContext *gcontext, Error **errp) { Object *obj; @@ -949,6 +954,7 @@ Chardev *qemu_chardev_new(const char *id, const char *t= ypename, obj =3D object_new(typename); chr =3D CHARDEV(obj); chr->label =3D g_strdup(id); + chr->gcontext =3D gcontext; =20 qemu_char_open(chr, backend, &be_opened, &local_err); if (local_err) { @@ -993,7 +999,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevB= ackend *backend, } =20 chr =3D qemu_chardev_new(id, object_class_get_name(OBJECT_CLASS(cc)), - backend, errp); + backend, NULL, errp); if (!chr) { return NULL; } @@ -1051,7 +1057,7 @@ ChardevReturn *qmp_chardev_change(const char *id, Cha= rdevBackend *backend, } =20 chr_new =3D qemu_chardev_new(NULL, object_class_get_name(OBJECT_CLASS(= cc)), - backend, errp); + backend, chr->gcontext, errp); if (!chr_new) { return NULL; } diff --git a/gdbstub.c b/gdbstub.c index a4be63f6eb..ff19579452 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2531,7 +2531,7 @@ int gdbserver_start(const char *device) * FIXME: it's a bit weird to allow using a mux chardev here * and implicitly setup a monitor. We may want to break this. */ - chr =3D qemu_chr_new_noreplay("gdb", device, true); + chr =3D qemu_chr_new_noreplay("gdb", device, true, NULL); if (!chr) return -1; } @@ -2545,7 +2545,7 @@ int gdbserver_start(const char *device) =20 /* Initialize a monitor terminal for gdb */ mon_chr =3D qemu_chardev_new(NULL, TYPE_CHARDEV_GDB, - NULL, &error_abort); + NULL, NULL, &error_abort); monitor_init(mon_chr, 0); } else { qemu_chr_fe_deinit(&s->chr, true); diff --git a/hmp.c b/hmp.c index b2a2b1f84e..c18caacfd7 100644 --- a/hmp.c +++ b/hmp.c @@ -2395,7 +2395,7 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict) if (opts =3D=3D NULL) { error_setg(&err, "Parsing chardev args failed"); } else { - qemu_chr_new_from_opts(opts, &err); + qemu_chr_new_from_opts(opts, NULL, &err); qemu_opts_del(opts); } hmp_handle_error(mon, &err); diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index 3c7d1364a9..94dffb2f57 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -799,7 +799,7 @@ static struct omap_sti_s *omap_sti_init(struct omap_tar= get_agent_s *ta, s->irq =3D irq; omap_sti_reset(s); =20 - qemu_chr_fe_init(&s->chr, chr ?: qemu_chr_new("null", "null"), + qemu_chr_fe_init(&s->chr, chr ?: qemu_chr_new("null", "null", NULL), &error_abort); =20 memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti", diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c index 0341ded50c..fa6660a113 100644 --- a/hw/bt/hci-csr.c +++ b/hw/bt/hci-csr.c @@ -501,7 +501,7 @@ static const TypeInfo char_hci_type_info =3D { Chardev *uart_hci_init(void) { return qemu_chardev_new(NULL, TYPE_CHARDEV_HCI, - NULL, &error_abort); + NULL, NULL, &error_abort); } =20 static void register_types(void) diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c index 6fd1b9cf6b..b3bb1cfcec 100644 --- a/hw/char/omap_uart.c +++ b/hw/char/omap_uart.c @@ -63,7 +63,7 @@ struct omap_uart_s *omap_uart_init(hwaddr base, s->irq =3D irq; s->serial =3D serial_mm_init(get_system_memory(), base, 2, irq, omap_clk_getrate(fclk)/16, - chr ?: qemu_chr_new(label, "null"), + chr ?: qemu_chr_new(label, "null", NULL), DEVICE_NATIVE_ENDIAN); return s; } @@ -183,6 +183,6 @@ void omap_uart_attach(struct omap_uart_s *s, Chardev *c= hr) /* TODO: Should reuse or destroy current s->serial */ s->serial =3D serial_mm_init(get_system_memory(), s->base, 2, s->irq, omap_clk_getrate(s->fclk) / 16, - chr ?: qemu_chr_new("null", "null"), + chr ?: qemu_chr_new("null", "null", NULL), DEVICE_NATIVE_ENDIAN); } diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index dc6ff0e5b3..91f34ef06c 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -211,7 +211,8 @@ static int con_init(struct XenLegacyDevice *xendev) * FIXME: sure we want to support implicit * muxed monitors here? */ - qemu_chr_new_mux_mon(label, output), &error_abort= ); + qemu_chr_new_mux_mon(label, output, NULL), + &error_abort); } =20 xenstore_store_pv_console_info(con->xendev.dev, diff --git a/hw/isa/isa-superio.c b/hw/isa/isa-superio.c index 8bc2f69eaa..d54463bf03 100644 --- a/hw/isa/isa-superio.c +++ b/hw/isa/isa-superio.c @@ -44,7 +44,7 @@ static void isa_superio_realize(DeviceState *dev, Error *= *errp) chr =3D parallel_hds[i]; if (chr =3D=3D NULL) { name =3D g_strdup_printf("discarding-parallel%d", i); - chr =3D qemu_chr_new(name, "null"); + chr =3D qemu_chr_new(name, "null", NULL); } else { name =3D g_strdup_printf("parallel%d", i); } @@ -84,7 +84,7 @@ static void isa_superio_realize(DeviceState *dev, Error *= *errp) chr =3D serial_hd(i); if (chr =3D=3D NULL) { name =3D g_strdup_printf("discarding-serial%d", i); - chr =3D qemu_chr_new(name, "null"); + chr =3D qemu_chr_new(name, "null", NULL); } else { name =3D g_strdup_printf("serial%d", i); } diff --git a/hw/mips/boston.c b/hw/mips/boston.c index 6c9c20a93e..e5bab3cadc 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -512,7 +512,7 @@ static void boston_mach_init(MachineState *machine) memory_region_init_io(lcd, NULL, &boston_lcd_ops, s, "boston-lcd", 0x8= ); memory_region_add_subregion_overlap(sys_mem, 0x17fff000, lcd, 0); =20 - chr =3D qemu_chr_new("lcd", "vc:320x240"); + chr =3D qemu_chr_new("lcd", "vc:320x240", NULL); qemu_chr_fe_init(&s->lcd_display, chr, NULL); qemu_chr_fe_set_handlers(&s->lcd_display, NULL, NULL, boston_lcd_event, NULL, s, NULL, true); diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 74667766c2..7a403ef1ce 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -568,7 +568,7 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *ad= dress_space, memory_region_add_subregion(address_space, base, &s->iomem_lo); memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi); =20 - chr =3D qemu_chr_new("fpga", "vc:320x200"); + chr =3D qemu_chr_new("fpga", "vc:320x200", NULL); qemu_chr_fe_init(&s->display, chr, NULL); qemu_chr_fe_set_handlers(&s->display, NULL, NULL, malta_fgpa_display_event, NULL, s, NULL, true= ); diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 98d1ca3c91..03c3bcd240 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -514,7 +514,7 @@ static USBDevice *usb_braille_init(USBBus *bus, const c= har *unused) USBDevice *dev; Chardev *cdrv; =20 - cdrv =3D qemu_chr_new("braille", "braille"); + cdrv =3D qemu_chr_new("braille", "braille", NULL); if (!cdrv) return NULL; =20 diff --git a/net/slirp.c b/net/slirp.c index 7a16d8d615..4ec989b592 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -927,7 +927,7 @@ static int slirp_guestfwd(SlirpState *s, const char *co= nfig_str, Error **errp) * FIXME: sure we want to support implicit * muxed monitors here? */ - Chardev *chr =3D qemu_chr_new_mux_mon(buf, p); + Chardev *chr =3D qemu_chr_new_mux_mon(buf, p, NULL); =20 if (!chr) { error_setg(errp, "Could not open guest forwarding device '%s'", diff --git a/qtest.c b/qtest.c index 60988c8aa2..527141785f 100644 --- a/qtest.c +++ b/qtest.c @@ -763,7 +763,7 @@ void qtest_init(const char *qtest_chrdev, const char *q= test_log, Error **errp) { Chardev *chr; =20 - chr =3D qemu_chr_new("qtest", qtest_chrdev); + chr =3D qemu_chr_new("qtest", qtest_chrdev, NULL); =20 if (chr =3D=3D NULL) { error_setg(errp, "Failed to initialize device for qtest: \"%s\"", diff --git a/tests/test-char.c b/tests/test-char.c index 82579e6aa5..63b4d3289d 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -86,7 +86,7 @@ static void char_console_test_subprocess(void) 1, &error_abort); qemu_opt_set(opts, "backend", "console", &error_abort); =20 - chr =3D qemu_chr_new_from_opts(opts, NULL); + chr =3D qemu_chr_new_from_opts(opts, NULL, NULL); g_assert_nonnull(chr); =20 qemu_chr_write_all(chr, (const uint8_t *)"CONSOLE", 7); @@ -108,7 +108,7 @@ static void char_stdio_test_subprocess(void) CharBackend be; int ret; =20 - chr =3D qemu_chr_new("label", "stdio"); + chr =3D qemu_chr_new("label", "stdio", NULL); g_assert_nonnull(chr); =20 qemu_chr_fe_init(&be, chr, &error_abort); @@ -139,7 +139,7 @@ static void char_ringbuf_test(void) qemu_opt_set(opts, "backend", "ringbuf", &error_abort); =20 qemu_opt_set(opts, "size", "5", &error_abort); - chr =3D qemu_chr_new_from_opts(opts, NULL); + chr =3D qemu_chr_new_from_opts(opts, NULL, NULL); g_assert_null(chr); qemu_opts_del(opts); =20 @@ -147,7 +147,7 @@ static void char_ringbuf_test(void) 1, &error_abort); qemu_opt_set(opts, "backend", "ringbuf", &error_abort); qemu_opt_set(opts, "size", "2", &error_abort); - chr =3D qemu_chr_new_from_opts(opts, &error_abort); + chr =3D qemu_chr_new_from_opts(opts, NULL, &error_abort); g_assert_nonnull(chr); qemu_opts_del(opts); =20 @@ -170,7 +170,7 @@ static void char_ringbuf_test(void) 1, &error_abort); qemu_opt_set(opts, "backend", "memory", &error_abort); qemu_opt_set(opts, "size", "2", &error_abort); - chr =3D qemu_chr_new_from_opts(opts, NULL); + chr =3D qemu_chr_new_from_opts(opts, NULL, NULL); g_assert_nonnull(chr); object_unparent(OBJECT(chr)); qemu_opts_del(opts); @@ -189,7 +189,7 @@ static void char_mux_test(void) qemu_opt_set(opts, "backend", "ringbuf", &error_abort); qemu_opt_set(opts, "size", "128", &error_abort); qemu_opt_set(opts, "mux", "on", &error_abort); - chr =3D qemu_chr_new_from_opts(opts, &error_abort); + chr =3D qemu_chr_new_from_opts(opts, NULL, &error_abort); g_assert_nonnull(chr); qemu_opts_del(opts); =20 @@ -412,7 +412,7 @@ static void char_websock_test(void) CharBackend client_be; Chardev *chr_client; Chardev *chr =3D qemu_chr_new("server", - "websocket:127.0.0.1:0,server,nowait"); + "websocket:127.0.0.1:0,server,nowait", NUL= L); const char handshake[] =3D "GET / HTTP/1.1\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" @@ -436,7 +436,7 @@ static void char_websock_test(void) qemu_chr_fe_set_handlers(&be, websock_server_can_read, websock_server_= read, NULL, NULL, chr, NULL, true); =20 - chr_client =3D qemu_chr_new("client", tmp); + chr_client =3D qemu_chr_new("client", tmp, NULL); qemu_chr_fe_init(&client_be, chr_client, &error_abort); qemu_chr_fe_set_handlers(&client_be, websock_client_can_read, websock_client_read, @@ -482,7 +482,7 @@ static void char_pipe_test(void) } =20 tmp =3D g_strdup_printf("pipe:%s", pipe); - chr =3D qemu_chr_new("pipe", tmp); + chr =3D qemu_chr_new("pipe", tmp, NULL); g_assert_nonnull(chr); g_free(tmp); =20 @@ -586,7 +586,7 @@ static void char_udp_test_internal(Chardev *reuse_chr, = int sock) int port; sock =3D make_udp_socket(&port); tmp =3D g_strdup_printf("udp:127.0.0.1:%d", port); - chr =3D qemu_chr_new("client", tmp); + chr =3D qemu_chr_new("client", tmp, NULL); g_assert_nonnull(chr); =20 be =3D g_alloca(sizeof(CharBackend)); @@ -764,7 +764,7 @@ static void char_socket_server_test(gconstpointer opaqu= e) opts =3D qemu_opts_parse_noisily(qemu_find_opts("chardev"), optstr, true); g_assert_nonnull(opts); - chr =3D qemu_chr_new_from_opts(opts, &error_abort); + chr =3D qemu_chr_new_from_opts(opts, NULL, &error_abort); qemu_opts_del(opts); g_assert_nonnull(chr); g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_ab= ort)); @@ -914,7 +914,7 @@ static void char_socket_client_test(gconstpointer opaqu= e) opts =3D qemu_opts_parse_noisily(qemu_find_opts("chardev"), optstr, true); g_assert_nonnull(opts); - chr =3D qemu_chr_new_from_opts(opts, &error_abort); + chr =3D qemu_chr_new_from_opts(opts, NULL, &error_abort); qemu_opts_del(opts); g_assert_nonnull(chr); =20 @@ -1015,14 +1015,14 @@ static void char_serial_test(void) qemu_opt_set(opts, "backend", "serial", &error_abort); qemu_opt_set(opts, "path", "/dev/null", &error_abort); =20 - chr =3D qemu_chr_new_from_opts(opts, NULL); + chr =3D qemu_chr_new_from_opts(opts, NULL, NULL); g_assert_nonnull(chr); /* TODO: add more tests with a pty */ object_unparent(OBJECT(chr)); =20 /* test tty alias */ qemu_opt_set(opts, "backend", "tty", &error_abort); - chr =3D qemu_chr_new_from_opts(opts, NULL); + chr =3D qemu_chr_new_from_opts(opts, NULL, NULL); g_assert_nonnull(chr); object_unparent(OBJECT(chr)); =20 @@ -1055,7 +1055,7 @@ static void char_file_fifo_test(void) g_assert_cmpint(ret, =3D=3D, 8); =20 chr =3D qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend, - &error_abort); + NULL, &error_abort); =20 qemu_chr_fe_init(&be, chr, &error_abort); qemu_chr_fe_set_handlers(&be, @@ -1109,7 +1109,7 @@ static void char_file_test_internal(Chardev *ext_chr,= const char *filepath) out =3D g_build_filename(tmp_path, "out", NULL); file.out =3D out; chr =3D qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, - &error_abort); + NULL, &error_abort); } ret =3D qemu_chr_write_all(chr, (uint8_t *)"hello!", 6); g_assert_cmpint(ret, =3D=3D, 6); @@ -1144,7 +1144,7 @@ static void char_null_test(void) chr =3D qemu_chr_find("label-null"); g_assert_null(chr); =20 - chr =3D qemu_chr_new("label-null", "null"); + chr =3D qemu_chr_new("label-null", "null", NULL); chr =3D qemu_chr_find("label-null"); g_assert_nonnull(chr); =20 @@ -1181,7 +1181,7 @@ static void char_invalid_test(void) { Chardev *chr; g_setenv("QTEST_SILENT_ERRORS", "1", 1); - chr =3D qemu_chr_new("label-invalid", "invalid"); + chr =3D qemu_chr_new("label-invalid", "invalid", NULL); g_assert_null(chr); g_unsetenv("QTEST_SILENT_ERRORS"); } @@ -1215,7 +1215,7 @@ static void char_hotswap_test(void) =20 chr_args =3D g_strdup_printf("udp:127.0.0.1:%d", port); =20 - chr =3D qemu_chr_new("chardev", chr_args); + chr =3D qemu_chr_new("chardev", chr_args, NULL); qemu_chr_fe_init(&be, chr, &error_abort); =20 /* check that chardev operates correctly */ diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 7d5f234646..d961bd09d1 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -519,7 +519,7 @@ static void test_server_create_chr(TestServer *server, = const gchar *opt) Chardev *chr; =20 chr_path =3D g_strdup_printf("unix:%s%s", server->socket_path, opt); - chr =3D qemu_chr_new(server->chr_name, chr_path); + chr =3D qemu_chr_new(server->chr_name, chr_path, NULL); g_free(chr_path); =20 g_assert_nonnull(chr); diff --git a/vl.c b/vl.c index 9e4dba7f92..ea794ec117 100644 --- a/vl.c +++ b/vl.c @@ -2302,7 +2302,7 @@ static int chardev_init_func(void *opaque, QemuOpts *= opts, Error **errp) { Error *local_err =3D NULL; =20 - if (!qemu_chr_new_from_opts(opts, &local_err)) { + if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) { if (local_err) { error_propagate(errp, local_err); return -1; @@ -2440,7 +2440,7 @@ static int serial_parse(const char *devname) snprintf(label, sizeof(label), "serial%d", index); serial_hds =3D g_renew(Chardev *, serial_hds, index + 1); =20 - serial_hds[index] =3D qemu_chr_new_mux_mon(label, devname); + serial_hds[index] =3D qemu_chr_new_mux_mon(label, devname, NULL); if (!serial_hds[index]) { error_report("could not connect serial device" " to character backend '%s'", devname); @@ -2476,7 +2476,7 @@ static int parallel_parse(const char *devname) exit(1); } snprintf(label, sizeof(label), "parallel%d", index); - parallel_hds[index] =3D qemu_chr_new_mux_mon(label, devname); + parallel_hds[index] =3D qemu_chr_new_mux_mon(label, devname, NULL); if (!parallel_hds[index]) { error_report("could not connect parallel device" " to character backend '%s'", devname); @@ -2490,7 +2490,7 @@ static int debugcon_parse(const char *devname) { QemuOpts *opts; =20 - if (!qemu_chr_new_mux_mon("debugcon", devname)) { + if (!qemu_chr_new_mux_mon("debugcon", devname, NULL)) { error_report("invalid character backend '%s'", devname); exit(1); } --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076542935421.1121055927466; Wed, 13 Feb 2019 08:49:02 -0800 (PST) Received: from localhost ([127.0.0.1]:59986 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxiS-0002j0-SF for importer@patchew.org; Wed, 13 Feb 2019 11:48:56 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39483) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGS-0004Sw-Qo for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGS-0005kb-0E for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57926) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGR-0005k3-Qb for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:19:59 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D790C04B2D7; Wed, 13 Feb 2019 16:19:59 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7E34260856; Wed, 13 Feb 2019 16:19:58 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:08 +0100 Message-Id: <20190213161913.22107-21-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 13 Feb 2019 16:19:59 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 20/25] chardev/wctablet: Fix a typo X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Philippe Mathieu-Daud=C3=A9 The correct name is Wacom. Fix the typo which is present since 378af96155d. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Philippe Mathieu-Daud=C3=A9 Message-Id: <20190213123446.1768-1-philmd@redhat.com> Signed-off-by: Marc-Andr=C3=A9 Lureau --- chardev/wctablet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chardev/wctablet.c b/chardev/wctablet.c index 969d014574..35dbd29a33 100644 --- a/chardev/wctablet.c +++ b/chardev/wctablet.c @@ -177,7 +177,7 @@ static void wctablet_input_sync(DeviceState *dev) } =20 static QemuInputHandler wctablet_handler =3D { - .name =3D "QEMU Wacome Pen Tablet", + .name =3D "QEMU Wacom Pen Tablet", .mask =3D INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS, .event =3D wctablet_input_event, .sync =3D wctablet_input_sync, --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550077479748787.8126939317679; Wed, 13 Feb 2019 09:04:39 -0800 (PST) Received: from localhost ([127.0.0.1]:60320 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxxb-00075T-Ms for importer@patchew.org; Wed, 13 Feb 2019 12:04:35 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39525) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGX-0004XV-Lt for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGU-0005lr-7F for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48528) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGU-0005lb-0T for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:02 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 33584E6A64; Wed, 13 Feb 2019 16:20:01 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 98B9910018FB; Wed, 13 Feb 2019 16:20:00 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:09 +0100 Message-Id: <20190213161913.22107-22-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 13 Feb 2019 16:20:01 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 21/25] char: update the mux handlers in class callback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Instead of handling mux chardev in a special way in qemu_chr_fe_set_handlers(), we may use the chr_update_read_handler class callback instead. Signed-off-by: Marc-Andr=C3=A9 Lureau Message-Id: <20190206174328.9736-2-marcandre.lureau@redhat.com> Reviewed-by: Paolo Bonzini --- include/chardev/char-mux.h | 1 - chardev/char-fe.c | 4 ---- chardev/char-mux.c | 5 +++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/include/chardev/char-mux.h b/include/chardev/char-mux.h index 1e13187767..572cefd517 100644 --- a/include/chardev/char-mux.h +++ b/include/chardev/char-mux.h @@ -55,7 +55,6 @@ typedef struct MuxChardev { #define CHARDEV_IS_MUX(chr) \ object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_MUX) =20 -void mux_chr_set_handlers(Chardev *chr, GMainContext *context); void mux_set_focus(Chardev *chr, int focus); void mux_chr_send_all_event(Chardev *chr, int event); =20 diff --git a/chardev/char-fe.c b/chardev/char-fe.c index b7bcbd59c0..f3530a90e6 100644 --- a/chardev/char-fe.c +++ b/chardev/char-fe.c @@ -290,10 +290,6 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b, qemu_chr_be_event(s, CHR_EVENT_OPENED); } } - - if (CHARDEV_IS_MUX(s)) { - mux_chr_set_handlers(s, context); - } } =20 void qemu_chr_fe_set_handlers(CharBackend *b, diff --git a/chardev/char-mux.c b/chardev/char-mux.c index 1199d32674..23aa82125d 100644 --- a/chardev/char-mux.c +++ b/chardev/char-mux.c @@ -278,7 +278,7 @@ static void char_mux_finalize(Object *obj) qemu_chr_fe_deinit(&d->chr, false); } =20 -void mux_chr_set_handlers(Chardev *chr, GMainContext *context) +static void mux_chr_update_read_handlers(Chardev *chr) { MuxChardev *d =3D MUX_CHARDEV(chr); =20 @@ -289,7 +289,7 @@ void mux_chr_set_handlers(Chardev *chr, GMainContext *c= ontext) mux_chr_event, NULL, chr, - context, true, false); + chr->gcontext, true, false); } =20 void mux_set_focus(Chardev *chr, int focus) @@ -383,6 +383,7 @@ static void char_mux_class_init(ObjectClass *oc, void *= data) cc->chr_add_watch =3D mux_chr_add_watch; cc->chr_be_event =3D mux_chr_be_event; cc->chr_machine_done =3D open_muxes; + cc->chr_update_read_handler =3D mux_chr_update_read_handlers; } =20 static const TypeInfo char_mux_type_info =3D { --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076137968170.85144610119426; Wed, 13 Feb 2019 08:42:17 -0800 (PST) Received: from localhost ([127.0.0.1]:59886 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxbw-0005VZ-0Q for importer@patchew.org; Wed, 13 Feb 2019 11:42:12 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39515) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGX-0004XC-7n for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGW-0005n9-Ap for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48942) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGW-0005mp-4A for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:04 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 58F12C049E20; Wed, 13 Feb 2019 16:20:03 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id C55A9600C5; Wed, 13 Feb 2019 16:20:02 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:10 +0100 Message-Id: <20190213161913.22107-23-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Feb 2019 16:20:03 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 22/25] terminal3270: do not use backend timer sources X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" terminal3270 uses the front-end side of the chardev. It shouldn't create sources from backend side context (with backend functions). send_timing_mark_cb calls qemu_chr_fe_write_all() which should be thread safe. This partially reverts changes from commit 2c716ba1506769c9be2caa02f0f6d6e7c00f4304. Signed-off-by: Marc-Andr=C3=A9 Lureau Message-Id: <20190206174328.9736-4-marcandre.lureau@redhat.com> Acked-by: Cornelia Huck Reviewed-by: Paolo Bonzini --- hw/char/terminal3270.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c index e9c45e55b1..35b079d5c4 100644 --- a/hw/char/terminal3270.c +++ b/hw/char/terminal3270.c @@ -31,7 +31,7 @@ typedef struct Terminal3270 { uint8_t outv[OUTPUT_BUFFER_SIZE]; int in_len; bool handshake_done; - GSource *timer_src; + guint timer_tag; } Terminal3270; =20 #define TYPE_TERMINAL_3270 "x-terminal3270" @@ -47,10 +47,9 @@ static int terminal_can_read(void *opaque) =20 static void terminal_timer_cancel(Terminal3270 *t) { - if (t->timer_src) { - g_source_destroy(t->timer_src); - g_source_unref(t->timer_src); - t->timer_src =3D NULL; + if (t->timer_tag) { + g_source_remove(t->timer_tag); + t->timer_tag =3D 0; } } =20 @@ -100,8 +99,7 @@ static void terminal_read(void *opaque, const uint8_t *b= uf, int size) assert(size <=3D (INPUT_BUFFER_SIZE - t->in_len)); =20 terminal_timer_cancel(t); - t->timer_src =3D qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000, - send_timing_mark_cb, t); + t->timer_tag =3D g_timeout_add_seconds(600, send_timing_mark_cb, t); memcpy(&t->inv[t->in_len], buf, size); t->in_len +=3D size; if (t->in_len < 2) { @@ -160,8 +158,7 @@ static void chr_event(void *opaque, int event) * char-socket.c. Once qemu receives the terminal-type of the * client, mark handshake done and trigger everything rolling agai= n. */ - t->timer_src =3D qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000, - send_timing_mark_cb, t); + t->timer_tag =3D g_timeout_add_seconds(600, send_timing_mark_cb, t= ); break; case CHR_EVENT_CLOSED: sch->curr_status.scsw.dstat =3D SCSW_DSTAT_DEVICE_END; --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155007768064038.99499832963363; Wed, 13 Feb 2019 09:08:00 -0800 (PST) Received: from localhost ([127.0.0.1]:60422 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gty0t-0001J0-FY for importer@patchew.org; Wed, 13 Feb 2019 12:07:59 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39556) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGZ-0004Ys-7n for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGY-0005oT-Dt for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:07 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44623) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGY-0005o2-8M for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:06 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 709957A19B; Wed, 13 Feb 2019 16:20:05 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id DCADA60857; Wed, 13 Feb 2019 16:20:04 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:11 +0100 Message-Id: <20190213161913.22107-24-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 13 Feb 2019 16:20:05 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 23/25] chardev: add a note about frontend sources and context switch X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Marc-Andr=C3=A9 Lureau Message-Id: <20190206174328.9736-5-marcandre.lureau@redhat.com> Reviewed-by: Paolo Bonzini --- include/chardev/char-fe.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h index c1b7fd9a95..aa1b864ccd 100644 --- a/include/chardev/char-fe.h +++ b/include/chardev/char-fe.h @@ -184,6 +184,9 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fm= t, ...) * is active; return the #GSource's tag. If it is disconnected, * or without associated Chardev, return 0. * + * Note that you are responsible to update the front-end sources if + * you are switching the main context with qemu_chr_fe_set_handlers(). + * * Returns: the source tag */ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond, --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076300329640.6545375021582; Wed, 13 Feb 2019 08:45:00 -0800 (PST) Received: from localhost ([127.0.0.1]:59910 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxeS-0007sq-F7 for importer@patchew.org; Wed, 13 Feb 2019 11:44:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39586) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGc-0004aC-1p for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGa-0005pp-GF for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:09 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48986) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGa-0005pQ-AI for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:08 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8585EC047B7A; Wed, 13 Feb 2019 16:20:07 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id F39125D9D1; Wed, 13 Feb 2019 16:20:06 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:12 +0100 Message-Id: <20190213161913.22107-25-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Feb 2019 16:20:07 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 24/25] char-pty: remove the check for connection on write X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This doesn't help much compared to the 1 second poll PTY timer. I can't think of a use case where this would help. However, we can simplify the code around chr_write(): the write lock is no longer needed for other char-pty callbacks (see following patch). Signed-off-by: Marc-Andr=C3=A9 Lureau Message-Id: <20190206174328.9736-6-marcandre.lureau@redhat.com> Reviewed-by: Paolo Bonzini --- chardev/char-pty.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/chardev/char-pty.c b/chardev/char-pty.c index f681d637c1..f8772c9e15 100644 --- a/chardev/char-pty.c +++ b/chardev/char-pty.c @@ -130,11 +130,7 @@ static int char_pty_chr_write(Chardev *chr, const uint= 8_t *buf, int len) PtyChardev *s =3D PTY_CHARDEV(chr); =20 if (!s->connected) { - /* guest sends data, check for (re-)connect */ - pty_chr_update_read_handler_locked(chr); - if (!s->connected) { - return len; - } + return len; } return io_channel_send(s->ioc, buf, len); } --=20 2.21.0.rc0.1.g036caf7885 From nobody Thu May 16 16:39:09 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1550076626279763.1316643800321; Wed, 13 Feb 2019 08:50:26 -0800 (PST) Received: from localhost ([127.0.0.1]:60000 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxjm-0003lJ-5k for importer@patchew.org; Wed, 13 Feb 2019 11:50:18 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39631) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtxGe-0004ei-3q for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtxGc-0005tk-RV for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:48658) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gtxGc-0005s0-HV for qemu-devel@nongnu.org; Wed, 13 Feb 2019 11:20:10 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B859E2DDA5; Wed, 13 Feb 2019 16:20:09 +0000 (UTC) Received: from localhost (ovpn-112-60.ams2.redhat.com [10.36.112.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1860310018FB; Wed, 13 Feb 2019 16:20:08 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Wed, 13 Feb 2019 17:19:13 +0100 Message-Id: <20190213161913.22107-26-marcandre.lureau@redhat.com> In-Reply-To: <20190213161913.22107-1-marcandre.lureau@redhat.com> References: <20190213161913.22107-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 13 Feb 2019 16:20:09 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 25/25] char-pty: remove write_lock usage X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The lock usage was described with its introduction in commit 9005b2a7589540a3733b3abdcfbccfe7746cd1a1. It was necessary because PTY write() shares more state than GIOChannel with other operations. This made char-pty a bit different from other chardev, that only lock around the write operation. This was apparent in commit 7b3621f47a990c5099c6385728347f69a8d0e55c, which introduced an idle source to avoid the lock. By removing the PTY chardev state sharing on write() with previous patch, we can remove the lock and the idle source. Signed-off-by: Marc-Andr=C3=A9 Lureau Message-Id: <20190206174328.9736-7-marcandre.lureau@redhat.com> Reviewed-by: Paolo Bonzini --- chardev/char-pty.c | 50 +++------------------------------------------- 1 file changed, 3 insertions(+), 47 deletions(-) diff --git a/chardev/char-pty.c b/chardev/char-pty.c index f8772c9e15..b034332edd 100644 --- a/chardev/char-pty.c +++ b/chardev/char-pty.c @@ -36,15 +36,12 @@ typedef struct { QIOChannel *ioc; int read_bytes; =20 - /* Protected by the Chardev chr_write_lock. */ int connected; GSource *timer_src; - GSource *open_source; } PtyChardev; =20 #define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY) =20 -static void pty_chr_update_read_handler_locked(Chardev *chr); static void pty_chr_state(Chardev *chr, int connected); =20 static void pty_chr_timer_cancel(PtyChardev *s) @@ -56,32 +53,19 @@ static void pty_chr_timer_cancel(PtyChardev *s) } } =20 -static void pty_chr_open_src_cancel(PtyChardev *s) -{ - if (s->open_source) { - g_source_destroy(s->open_source); - g_source_unref(s->open_source); - s->open_source =3D NULL; - } -} - static gboolean pty_chr_timer(gpointer opaque) { struct Chardev *chr =3D CHARDEV(opaque); PtyChardev *s =3D PTY_CHARDEV(opaque); =20 - qemu_mutex_lock(&chr->chr_write_lock); pty_chr_timer_cancel(s); - pty_chr_open_src_cancel(s); if (!s->connected) { /* Next poll ... */ - pty_chr_update_read_handler_locked(chr); + qemu_chr_be_update_read_handlers(chr, chr->gcontext); } - qemu_mutex_unlock(&chr->chr_write_lock); return FALSE; } =20 -/* Called with chr_write_lock held. */ static void pty_chr_rearm_timer(Chardev *chr, int ms) { PtyChardev *s =3D PTY_CHARDEV(chr); @@ -94,8 +78,7 @@ static void pty_chr_rearm_timer(Chardev *chr, int ms) g_free(name); } =20 -/* Called with chr_write_lock held. */ -static void pty_chr_update_read_handler_locked(Chardev *chr) +static void pty_chr_update_read_handler(Chardev *chr) { PtyChardev *s =3D PTY_CHARDEV(chr); GPollFD pfd; @@ -117,14 +100,6 @@ static void pty_chr_update_read_handler_locked(Chardev= *chr) } } =20 -static void pty_chr_update_read_handler(Chardev *chr) -{ - qemu_mutex_lock(&chr->chr_write_lock); - pty_chr_update_read_handler_locked(chr); - qemu_mutex_unlock(&chr->chr_write_lock); -} - -/* Called with chr_write_lock held. */ static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len) { PtyChardev *s =3D PTY_CHARDEV(chr); @@ -179,23 +154,11 @@ static gboolean pty_chr_read(QIOChannel *chan, GIOCon= dition cond, void *opaque) return TRUE; } =20 -static gboolean qemu_chr_be_generic_open_func(gpointer opaque) -{ - Chardev *chr =3D CHARDEV(opaque); - PtyChardev *s =3D PTY_CHARDEV(opaque); - - s->open_source =3D NULL; - qemu_chr_be_event(chr, CHR_EVENT_OPENED); - return FALSE; -} - -/* Called with chr_write_lock held. */ static void pty_chr_state(Chardev *chr, int connected) { PtyChardev *s =3D PTY_CHARDEV(chr); =20 if (!connected) { - pty_chr_open_src_cancel(s); remove_fd_in_watch(chr); s->connected =3D 0; /* (re-)connect poll interval for idle guests: once per second. @@ -205,13 +168,8 @@ static void pty_chr_state(Chardev *chr, int connected) } else { pty_chr_timer_cancel(s); if (!s->connected) { - g_assert(s->open_source =3D=3D NULL); - s->open_source =3D g_idle_source_new(); s->connected =3D 1; - g_source_set_callback(s->open_source, - qemu_chr_be_generic_open_func, - chr, NULL); - g_source_attach(s->open_source, chr->gcontext); + qemu_chr_be_event(chr, CHR_EVENT_OPENED); } if (!chr->gsource) { chr->gsource =3D io_add_watch_poll(chr, s->ioc, @@ -227,11 +185,9 @@ static void char_pty_finalize(Object *obj) Chardev *chr =3D CHARDEV(obj); PtyChardev *s =3D PTY_CHARDEV(obj); =20 - qemu_mutex_lock(&chr->chr_write_lock); pty_chr_state(chr, 0); object_unref(OBJECT(s->ioc)); pty_chr_timer_cancel(s); - qemu_mutex_unlock(&chr->chr_write_lock); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } =20 --=20 2.21.0.rc0.1.g036caf7885