From nobody Tue Dec 16 07:07:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1520982060319589.4088772722241; Tue, 13 Mar 2018 16:01:00 -0700 (PDT) Received: from localhost ([::1]:43349 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evsug-0008NY-8t for importer@patchew.org; Tue, 13 Mar 2018 19:00:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57895) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evshn-0005UI-Rf for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:47:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evshm-0002xw-Rc for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:47:39 -0400 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:54932) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evshm-0002wU-Ie for qemu-devel@nongnu.org; Tue, 13 Mar 2018 18:47:38 -0400 Received: by mail-wm0-x242.google.com with SMTP id h76so869748wme.4 for ; Tue, 13 Mar 2018 15:47:38 -0700 (PDT) Received: from donizetti.lan (94-36-191-219.adsl-ull.clienti.tiscali.it. [94.36.191.219]) by smtp.gmail.com with ESMTPSA id x107sm1557951wrb.97.2018.03.13.15.47.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Mar 2018 15:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/f9WYDaLS5E3ea3YgWTOcg8sJkeE7JjKA4gZEIu1iBo=; b=Kf4FDjNpHiCiJh4OEpk9ISUAOx/QUGOf14hBAnUpvGav409KBJsWEODQ2Inmsbiohc U6oR/paqwT23igdvylVMyzMeADlZj5kKMpfRy6a4KZrQiTJK3OKd9EY8cDh9fWqr5AI1 sWbfBAefChe/C2QMx2TW10cE2+2ocjrT2aH59tb0i8iYz69gyM8hlAug/mtIy083CIoZ 5raS7A6kFui7y3rBrXMc8X2CwRayafs9MAOf/4CTZlVbVCMqIcjYwhX3j3L3WmUiBdyP FTL91NXdQ6Z7PSa9jtukjHWNbXyAwvMR16frkteMeclG0gRzSig78+K7YY9EcRWQiEKc ZmdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=/f9WYDaLS5E3ea3YgWTOcg8sJkeE7JjKA4gZEIu1iBo=; b=YQr2wh6sJpOodCroxJ4zLXA19oxsu5AVyeRw/cpsNq43MXE8aPFojw0OYKi0mgcQiW geBJqcO8fQMb0uX/TOm2lh7fYi9W29m9tzixYgE7cEWOpGyeK8yc51HsnePtR66aRNwQ AszIduhM1b/q2VBVM7NhchL+3b2iINW9eSDhMdSNr1/Quca4DLTDcyTH5swy/hkkZbTQ s/GjHtKJ+JKwWL8LrXT7TzjXr/N9ncoEZdbWJRKyTp1uGu48/4rZQWqdQo+59xnNIYeh um5bV4gM37GZC2ZRfQJWpSyhsjHElybhiu11eujXoyHLG1bL+OCbymy104/+4+gpwzKP nuwQ== X-Gm-Message-State: AElRT7HFOwcDD6Ea039NNdyJZD+MrDhuJCHz1O201fCaS8JLWejPBkMJ N26NPGAgHwJ8kjp0R/PnpH8M0N0h X-Google-Smtp-Source: AG47ELtE6hTKKx3hznHPiJU9lMj8mbrKTvrhztGBw0MEdajuu2mmBenZTSIwUs9yLLCLWltaY72asA== X-Received: by 10.28.235.4 with SMTP id j4mr2166254wmh.52.1520981257139; Tue, 13 Mar 2018 15:47:37 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 13 Mar 2018 23:46:23 +0100 Message-Id: <20180313224719.4954-14-pbonzini@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180313224719.4954-1-pbonzini@redhat.com> References: <20180313224719.4954-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [PULL 13/69] chardev: allow telnet gsource to switch gcontext 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 Xu Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 From: Peter Xu It was originally created by qio_channel_add_watch() so it's always assigning the task to main context. Now we use the new API called qio_channel_add_watch_source() so that we get the GSource handle rather than the tag ID. Meanwhile, caching the gsource and TCPChardevTelnetInit (which holds the handshake data) in SocketChardev.telnet_source so that we can also do dynamic context switch when update read handlers. Signed-off-by: Peter Xu Message-Id: <20180306053320.15401-5-peterx@redhat.com> Acked-by: Stefan Hajnoczi Reviewed-by: Daniel P. Berrang=C3=A9 Signed-off-by: Paolo Bonzini --- chardev/char-socket.c | 67 +++++++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 2475e1d52f..82c7d7a323 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -40,6 +40,11 @@ =20 #define TCP_MAX_FDS 16 =20 +typedef struct { + char buf[21]; + size_t buflen; +} TCPChardevTelnetInit; + typedef struct { Chardev parent; QIOChannel *ioc; /* Client I/O channel */ @@ -60,6 +65,8 @@ typedef struct { bool is_listen; bool is_telnet; bool is_tn3270; + GSource *telnet_source; + TCPChardevTelnetInit *telnet_init; =20 GSource *reconnect_timer; int64_t reconnect_time; @@ -70,6 +77,7 @@ typedef struct { OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET) =20 static gboolean socket_reconnect_timeout(gpointer opaque); +static void tcp_chr_telnet_init(Chardev *chr); =20 static void tcp_chr_reconn_timer_cancel(SocketChardev *s) { @@ -556,6 +564,15 @@ static void tcp_chr_connect(void *opaque) qemu_chr_be_event(chr, CHR_EVENT_OPENED); } =20 +static void tcp_chr_telnet_destroy(SocketChardev *s) +{ + if (s->telnet_source) { + g_source_destroy(s->telnet_source); + g_source_unref(s->telnet_source); + s->telnet_source =3D NULL; + } +} + static void tcp_chr_update_read_handler(Chardev *chr) { SocketChardev *s =3D SOCKET_CHARDEV(chr); @@ -570,6 +587,10 @@ static void tcp_chr_update_read_handler(Chardev *chr) chr, NULL, chr->gcontext); } =20 + if (s->telnet_source) { + tcp_chr_telnet_init(CHARDEV(s)); + } + if (!s->connected) { return; } @@ -583,32 +604,30 @@ static void tcp_chr_update_read_handler(Chardev *chr) } } =20 -typedef struct { - Chardev *chr; - char buf[21]; - size_t buflen; -} TCPChardevTelnetInit; - static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc, GIOCondition cond G_GNUC_UNUSED, gpointer user_data) { - TCPChardevTelnetInit *init =3D user_data; + SocketChardev *s =3D user_data; + Chardev *chr =3D CHARDEV(s); + TCPChardevTelnetInit *init =3D s->telnet_init; ssize_t ret; =20 + assert(init); + ret =3D qio_channel_write(ioc, init->buf, init->buflen, NULL); if (ret < 0) { if (ret =3D=3D QIO_CHANNEL_ERR_BLOCK) { ret =3D 0; } else { - tcp_chr_disconnect(init->chr); + tcp_chr_disconnect(chr); goto end; } } init->buflen -=3D ret; =20 if (init->buflen =3D=3D 0) { - tcp_chr_connect(init->chr); + tcp_chr_connect(chr); goto end; } =20 @@ -617,16 +636,30 @@ static gboolean tcp_chr_telnet_init_io(QIOChannel *io= c, return G_SOURCE_CONTINUE; =20 end: - g_free(init); + g_free(s->telnet_init); + s->telnet_init =3D NULL; + g_source_unref(s->telnet_source); + s->telnet_source =3D NULL; return G_SOURCE_REMOVE; } =20 static void tcp_chr_telnet_init(Chardev *chr) { SocketChardev *s =3D SOCKET_CHARDEV(chr); - TCPChardevTelnetInit *init =3D g_new0(TCPChardevTelnetInit, 1); + TCPChardevTelnetInit *init; size_t n =3D 0; =20 + /* Destroy existing task */ + tcp_chr_telnet_destroy(s); + + if (s->telnet_init) { + /* We are possibly during a handshake already */ + goto cont; + } + + s->telnet_init =3D g_new0(TCPChardevTelnetInit, 1); + init =3D s->telnet_init; + #define IACSET(x, a, b, c) \ do { \ x[n++] =3D a; \ @@ -634,7 +667,6 @@ static void tcp_chr_telnet_init(Chardev *chr) x[n++] =3D c; \ } while (0) =20 - init->chr =3D chr; if (!s->is_tn3270) { init->buflen =3D 12; /* Prep the telnet negotion to put telnet in binary, @@ -657,10 +689,11 @@ static void tcp_chr_telnet_init(Chardev *chr) =20 #undef IACSET =20 - qio_channel_add_watch( - s->ioc, G_IO_OUT, - tcp_chr_telnet_init_io, - init, NULL); +cont: + s->telnet_source =3D qio_channel_add_watch_source(s->ioc, G_IO_OUT, + tcp_chr_telnet_init_io, + s, NULL, + chr->gcontext); } =20 =20 @@ -835,6 +868,8 @@ static void char_socket_finalize(Object *obj) tcp_chr_free_connection(chr); tcp_chr_reconn_timer_cancel(s); qapi_free_SocketAddress(s->addr); + tcp_chr_telnet_destroy(s); + g_free(s->telnet_init); if (s->listener) { qio_net_listener_set_client_func_full(s->listener, NULL, NULL, NULL, chr->gcontext); --=20 2.14.3