From nobody Fri Nov 14 18:24:05 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1761844995; cv=none; d=zohomail.com; s=zohoarc; b=g9+AYYtq97SvbXptbAVQRw0Mh29sg1HqgK5iOeMVzY6olhxsWr905aMvIRZjns4Sx44MFkNI8dgTi+0xPPItDDZOciQX8T/M+LFexJYJ+5s3fxf43O+jiHoSE0OI/ipv/Ono5ladIjy07ygETZyvtKPlwH0imU1eLy93/sozjEM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1761844995; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4mc/qBRLhfYXRJW391uyW9nJdD23QGaduedXq3nj154=; b=Bg0+q+F7AYnX/cRjq6BzbDRlq8uPGkhYh2BiIRwFsXQLOEtoPr3ToHj3S7E7fxf4jd8JUmQIchwP5/Y5BPab/94uml9RI5OlvlkW4voFrPpnkaj9esoxnf0fivvT2DtDH3OFaiIpO+dElKqrHZ3OJ3SUO1O75uRc0YA1btTTGsU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1761844995941606.4792311364544; Thu, 30 Oct 2025 10:23:15 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vEWJc-0001Ce-Oo; Thu, 30 Oct 2025 13:20:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vEWJS-000180-UU for qemu-devel@nongnu.org; Thu, 30 Oct 2025 13:19:51 -0400 Received: from forwardcorp1d.mail.yandex.net ([178.154.239.200]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vEWJ9-0008Mx-9N for qemu-devel@nongnu.org; Thu, 30 Oct 2025 13:19:48 -0400 Received: from mail-nwsmtp-smtp-corp-main-66.iva.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-66.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1a8f:0:640:2fa2:0]) by forwardcorp1d.mail.yandex.net (Yandex) with ESMTPS id 2FEED8094A; Thu, 30 Oct 2025 20:19:25 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:861::1:2b]) by mail-nwsmtp-smtp-corp-main-66.iva.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id GJjc0O0FA0U0-fLAA5S6I; Thu, 30 Oct 2025 20:19:24 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1761844764; bh=4mc/qBRLhfYXRJW391uyW9nJdD23QGaduedXq3nj154=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=gifW8X1uO3BMUUllENMu6cpL+PuoQ2iLARh5T0L6cild5mcv0BLxlFH5wg/YF6B+c 8/r3HTM4EkWHsPn8I4qyTi6Y73JNTITLXlBI9sSrzTJtAZkQaIMEdfoEdjxvKOBZ4o Rar+rFBSHK938UtIBWCIQDbmlPIgeVdAuK+DYKxw= Authentication-Results: mail-nwsmtp-smtp-corp-main-66.iva.yp-c.yandex.net; dkim=pass header.i=@yandex-team.ru From: Vladimir Sementsov-Ogievskiy To: jasowang@redhat.com Cc: qemu-devel@nongnu.org, vsementsov@yandex-team.ru, leiyang@redhat.com, davydov-max@yandex-team.ru, yc-core@yandex-team.ru, pbonzini@redhat.com, berrange@redhat.com, eduardo@habkost.net, peterx@redhat.com Subject: [PATCH v9 9/9] net/tap: postpone tap setup to net_backend_connect() call Date: Thu, 30 Oct 2025 20:19:14 +0300 Message-ID: <20251030171915.726441-10-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20251030171915.726441-1-vsementsov@yandex-team.ru> References: <20251030171915.726441-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=178.154.239.200; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1d.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1761844997986158500 Content-Type: text/plain; charset="utf-8" As described in previous commit, to support backend-transfer migration for virtio-net/tap, we need to postpone the decision to open the device or to wait for incoming fds up to pre-incoming point (when we actually can decide). This commit only postpones TAP-open case of initialization. We don't try to postpone the all cases of initialization, as it will require a lot more work of refactoring the code. So we postpone only the simple case, for which we are going to support fd-incoming migration: 1. No fds / fd parameters: obviously, if user give fd/fds the should be used, no incoming backend-transfer migration is possible. 2. No helper: just for simplicity. It probably possible to allow it (and just ignore in case of backend-transfer migration), to allow user use same cmdline on target QEMU.. But that questionable, and postponable. 3. No sciprt/downscript. It's not simple to support downscript: we should pass the responsiblity to call it on target QEMU with migration.. And back to source QEMU on migration failure. It feasible, but may be implemented later on demand. 3. Concrete ifname: to not try to share it between queues, when we only can setup queues as separate entities. Supporting undecided ifname will require to create some extra netdev state, connecting all the taps, to be able to iterate through them. No part of backend-transfer migration is here, we only prepare the code for future implementation of it. Signed-off-by: Vladimir Sementsov-Ogievskiy --- net/tap.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/net/tap.c b/net/tap.c index c50430ba49..ad1d458521 100644 --- a/net/tap.c +++ b/net/tap.c @@ -90,6 +90,12 @@ typedef struct TAPState { int sndbuf; int vhostfd; uint32_t vhost_busyloop_timeout; + + /* for postponed setup */ + bool vnet_hdr_required; + int vnet_hdr; + bool mq_required; + char *ifname; } TAPState; =20 static bool net_tap_setup(TAPState *s, int fd, int vnet_hdr, Error **errp); @@ -99,6 +105,7 @@ static void launch_script(const char *setup_script, cons= t char *ifname, =20 static void tap_send(void *opaque); static void tap_writable(void *opaque); +static bool tap_backend_connect(NetClientState *nc, Error **errp); =20 static char *tap_parse_script(const char *script_arg, const char *default_= path) { @@ -368,6 +375,8 @@ static void tap_cleanup(NetClientState *nc) close(s->vhostfd); s->vhostfd =3D -1; } + + g_free(s->ifname); } =20 static void tap_poll(NetClientState *nc, bool enable) @@ -424,6 +433,7 @@ static NetClientInfo net_tap_info =3D { .set_vnet_be =3D tap_set_vnet_be, .set_steering_ebpf =3D tap_set_steering_ebpf, .get_vhost_net =3D tap_get_vhost_net, + .backend_connect =3D tap_backend_connect, }; =20 static TAPState *net_tap_new(NetClientState *peer, const char *model, @@ -847,6 +857,102 @@ static int get_fds(char *str, char *fds[], int max) return i; } =20 +static bool tap_wait_incoming(NetClientState *nc) +{ + TAPState *s =3D DO_UPCAST(TAPState, nc, nc); + + return s->fd =3D=3D -1; +} + +static bool tap_backend_connect(NetClientState *nc, Error **errp) +{ + TAPState *s =3D DO_UPCAST(TAPState, nc, nc); + char ifname[TAP_IFNAME_SZ]; + int vnet_hdr =3D s->vnet_hdr; + int fd; + + if (!tap_wait_incoming(nc)) { + /* Already connected */ + return true; + } + + pstrcpy(ifname, sizeof(ifname), s->ifname); + fd =3D net_tap_open(&vnet_hdr, s->vnet_hdr_required, NULL, + ifname, sizeof(ifname), + s->mq_required, errp); + if (fd < 0) { + goto fail; + } + + if (!net_tap_setup(s, fd, vnet_hdr, errp)) { + goto fail; + } + + return true; + +fail: + qemu_del_net_client(&s->nc); + return false; +} + +static bool check_no_script(const char *script_arg) +{ + return script_arg && + (script_arg[0] =3D=3D '\0' || strcmp(script_arg, "no") =3D=3D 0); +} + +/* + * Returns: + * -1 - failed, errp set. The whole tap creation process is faild. + * 0 - success, tap initialized, connect is postponed + * 1 - no critical error, but postponed connect is not supported, + * caller should continue usual initialization + */ +static int tap_postpone_init(const NetdevTapOptions *tap, + const char *name, NetClientState *peer, + Error **errp) +{ + int queues =3D tap->has_queues ? tap->queues : 1; + + if (tap->fd || tap->fds || tap->helper || tap->vhostfds) { + return 1; + } + + if (!tap->ifname || tap->ifname[0] =3D=3D '\0' || + strstr(tap->ifname, "%d") !=3D NULL) { + /* + * It's hard to postpone logic of parsing template or + * absent ifname + */ + return 1; + } + + /* + * It's not simple to support downscript for backend transfer migratio= n, + * so for simplicity, let's not support postponed connect in case of + * any scripts given. + */ + if (!check_no_script(tap->script) || !check_no_script(tap->downscript)= ) { + return 1; + } + + for (int i =3D 0; i < queues; i++) { + TAPState *s =3D net_tap_new(peer, "tap", name, tap, NULL, errp); + if (!s) { + return -1; + } + + s->vnet_hdr_required =3D tap->has_vnet_hdr && tap->vnet_hdr; + s->vnet_hdr =3D tap->has_vnet_hdr ? tap->vnet_hdr : 1; + s->mq_required =3D queues > 1; + s->ifname =3D g_strdup(tap->ifname); + qemu_set_info_str(&s->nc, "ifname=3D%s,script=3Dno,downscript=3Dno= ", + tap->ifname); + } + + return 0; +} + int net_init_tap(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp) { @@ -875,6 +981,11 @@ int net_init_tap(const Netdev *netdev, const char *nam= e, return -1; } =20 + ret =3D tap_postpone_init(tap, name, peer, errp); + if (ret <=3D 0) { + return ret; + } + if (tap->fd) { if (tap->ifname || tap->script || tap->downscript || tap->has_vnet_hdr || tap->helper || tap->has_queues || --=20 2.48.1