From nobody Sat Sep 6 14:41:19 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=1756906763; cv=none; d=zohomail.com; s=zohoarc; b=XbnDzCgwwenDpnQPVZ5bdlvKJIMmEumwmGctxiMEUaHHqDCEVWcHN9L8z+DmuxDjfAOLPdOTnE79WUArqoAbZqDRJXwQdrx18TSdoe3PF/nSghFqaJOubxIwsiVlOUtz1qtBZlry7IMYC+5blR1njlKZS1/EP91AcHmRpp203TI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906763; 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=vTD8jN8GgnHxP7miFMJzCoDR8mpWlWdzUIe3poEf6UQ=; b=jAuiE3pongq0G1Adge9YUS4nRuVlq/oUNVRCBsDRUKo0HWJL2SqHfET5lSuXi5nU4yfDklY8TNRVZYhQs2dWIJ/VSaDBcJYs7shuEjaccHe7ezwDgjLmMAwzxbX4MGrRa15JGoriJNqvaUP2mOEXu/yimPc8U9spmkrbV/LzgpM= 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 175690676381715.134520245885028; Wed, 3 Sep 2025 06:39:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utngE-0005N9-0T; Wed, 03 Sep 2025 09:37:42 -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 1utnfu-00059R-Q9 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:23 -0400 Received: from forwardcorp1a.mail.yandex.net ([178.154.239.72]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfp-0004tH-Qf for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:22 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id EFC90C0197; Wed, 03 Sep 2025 16:37:13 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-S0T2KLBN; Wed, 03 Sep 2025 16:37:13 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906633; bh=vTD8jN8GgnHxP7miFMJzCoDR8mpWlWdzUIe3poEf6UQ=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=PEqWXXBV6BmEKO1CTYhh61qfBngaROTC+QHAwReNsM75Gp/JeJdgSiK9+ZxE44Vlt ANIbSdfhSbZG/28oFtkbZRiQoSqJJi/41i/sEgy18Aw/wQ06anV6vir2EwgLJknugy RCY1Wb6rNL8NCp56vQF2sCEJxpd9wlPpNCXoesUw= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 1/8] net/tap: add some trace points Date: Wed, 3 Sep 2025 16:36:58 +0300 Message-ID: <20250903133706.1177633-2-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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.72; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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: 1756906765670124100 Content-Type: text/plain; charset="utf-8" Add trace points to simplify debugging migration. Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- net/tap.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ net/trace-events | 7 ++++++ 2 files changed, 65 insertions(+) diff --git a/net/tap.c b/net/tap.c index 2530627a9a..224fb37310 100644 --- a/net/tap.c +++ b/net/tap.c @@ -43,6 +43,7 @@ #include "qemu/main-loop.h" #include "qemu/sockets.h" #include "hw/virtio/vhost.h" +#include "trace.h" =20 #include "net/tap.h" =20 @@ -148,6 +149,9 @@ static ssize_t tap_receive_iov(NetClientState *nc, cons= t struct iovec *iov, g_autofree struct iovec *iov_copy =3D NULL; struct virtio_net_hdr hdr =3D { }; =20 + trace_tap_receive_iov(s->using_vnet_hdr, s->host_vnet_hdr_len, iovcnt, + iov->iov_len); + if (s->host_vnet_hdr_len && !s->using_vnet_hdr) { iov_copy =3D g_new(struct iovec, iovcnt + 1); iov_copy[0].iov_base =3D &hdr; @@ -183,6 +187,49 @@ static void tap_send_completed(NetClientState *nc, ssi= ze_t len) tap_read_poll(s, true); } =20 +static char *tap_dump_packet(const uint8_t *buf, int size) +{ + int i, j; + char hex_line[80]; /* Enough space for hex pairs + spaces */ + char ascii_line[17]; /* 16 + 1 for null terminator */ + GString *dump_str =3D g_string_new(NULL); + + g_string_append_printf(dump_str, "Packet dump (%d bytes):\n", size); + + for (i =3D 0; i < size; i +=3D 16) { + memset(hex_line, 0, sizeof(hex_line)); + memset(ascii_line, 0, sizeof(ascii_line)); + + /* Build hex line in groups of 2 bytes (4 hex chars) */ + int hex_pos =3D 0; + for (j =3D 0; j < 16 && (i + j) < size; j +=3D 2) { + if (i + j + 1 < size) { + /* Two bytes available */ + hex_pos +=3D snprintf(hex_line + hex_pos, + sizeof(hex_line) - hex_pos, + "%02x%02x ", buf[i + j], buf[i + j + 1= ]); + } else { + /* Only one byte left */ + hex_pos +=3D snprintf(hex_line + hex_pos, + sizeof(hex_line) - hex_pos, + "%02x ", buf[i + j]); + } + } + + /* Build ASCII line */ + for (j =3D 0; j < 16 && (i + j) < size; j++) { + uint8_t byte =3D buf[i + j]; + ascii_line[j] =3D (byte >=3D 32 && byte <=3D 126) ? byte : '.'; + } + + /* Add the line in tcpdump-like format */ + g_string_append_printf(dump_str, "\t0x%04x: %-40s %s\n", + i, hex_line, ascii_line); + } + + return g_string_free(dump_str, false); +} + static void tap_send(void *opaque) { TAPState *s =3D opaque; @@ -199,6 +246,13 @@ static void tap_send(void *opaque) break; } =20 + if (trace_event_get_state_backends(TRACE_TAP_PACKET_DUMP)) { + g_autofree char *dump =3D tap_dump_packet(s->buf, size); + trace_tap_packet_dump(dump); + } + + trace_tap_send_packet(s->using_vnet_hdr, s->host_vnet_hdr_len, siz= e); + if (s->host_vnet_hdr_len && size <=3D s->host_vnet_hdr_len) { /* Invalid packet */ break; @@ -980,6 +1034,8 @@ int tap_enable(NetClientState *nc) TAPState *s =3D DO_UPCAST(TAPState, nc, nc); int ret; =20 + trace_tap_enable(); + if (s->enabled) { return 0; } else { @@ -997,6 +1053,8 @@ int tap_disable(NetClientState *nc) TAPState *s =3D DO_UPCAST(TAPState, nc, nc); int ret; =20 + trace_tap_disable(); + if (s->enabled =3D=3D 0) { return 0; } else { diff --git a/net/trace-events b/net/trace-events index cda960f42b..b51427f539 100644 --- a/net/trace-events +++ b/net/trace-events @@ -29,3 +29,10 @@ vhost_vdpa_set_address_space_id(void *v, unsigned vq_gro= up, unsigned asid_num) " vhost_vdpa_net_load_cmd(void *s, uint8_t class, uint8_t cmd, int data_num,= int data_size) "vdpa state: %p class: %u cmd: %u sg_num: %d size: %d" vhost_vdpa_net_load_cmd_retval(void *s, uint8_t class, uint8_t cmd, int r)= "vdpa state: %p class: %u cmd: %u retval: %d" vhost_vdpa_net_load_mq(void *s, int ncurqps) "vdpa state: %p current_qpair= s: %d" + +# tap.c +tap_receive_iov(bool using_vnet_hdr, uint32_t host_vnet_hdr_len, int iovcn= t, size_t iov_len) "using_vnet_hdr:%d host_vnet_hdr_len:%u iovcnt:%d iov_le= n:%zu" +tap_send_packet(bool using_vnet_hdr, uint32_t host_vnet_hdr_len, int size)= "using_vnet_hdr:%d host_vnet_hdr_len:%u size:%d" +tap_enable(void) "tap enabled" +tap_disable(void) "tap disabled" +tap_packet_dump(const char *dump_str) "%s" --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906742; cv=none; d=zohomail.com; s=zohoarc; b=Prc4YklUXkegmSInahcBfso9TAHhlPUW7R3sWKSKbYTjKIGFN9sBdbDycbHrk8Qcxi+9ejXwD6Tfgcn5x23MskKk6evGNYeRJfVk4KH3eAlcCZho/c+u0z+SgVeZ068KeuYnvF3mzOnXj7nizb6+3Hn0Qrp4F9FyxqMiiO/uwVw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906742; 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=3kTD8LHMLe7WQJ1Cy0sH9HJeNgscWdXUbDRna1jwCKA=; b=dF+D8Ui6+gOvsdXbpQ69iDB0E+VitWSN4s+QC0o32M+4PTewdm9qAdjya40K5G/wy41OfybfG5zRuCKvpN7XtnUY18C4dLHnV23zy7jhE5yt1B36ZLzJVMeNn3J3NapUjor4+pHxsA+pvd5nHYKSzV1as03s0fTmUWZ7gOFmctw= 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 1756906742235260.3246835007071; Wed, 3 Sep 2025 06:39:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utng3-0005Ef-HD; Wed, 03 Sep 2025 09:37:31 -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 1utnfu-00059L-Jl for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:23 -0400 Received: from forwardcorp1a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfp-0004tQ-Sc for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:22 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id BDC2BC019B; Wed, 03 Sep 2025 16:37:14 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-AX9ikqZl; Wed, 03 Sep 2025 16:37:14 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906634; bh=3kTD8LHMLe7WQJ1Cy0sH9HJeNgscWdXUbDRna1jwCKA=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=mrCFFCjLEkTQno36xFOUtOIJD+TuS0ZvEe2IxMaW5Y7ByNbZwD0JZKWiC5Iu6mzFX GIixc1POq6nrpWqUNL4iSYB4pW0erE7YmB0NaCWinjS1960s92azqcWcA1eCFNjyYl 6HP4MS9fgLKzznYI2YinOZ/jh4CcSPP+aF2mcFhk= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 2/8] net/tap: keep exit notifier only when downscript set Date: Wed, 3 Sep 2025 16:36:59 +0300 Message-ID: <20250903133706.1177633-3-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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=2a02:6b8:c0e:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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_DNSWL_NONE=-0.0001, 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: 1756906745255124100 Content-Type: text/plain; charset="utf-8" The notifier is used only to call the downscript. Avoid extra notifier for other cases. Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- net/tap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/net/tap.c b/net/tap.c index 224fb37310..7dc8af1e57 100644 --- a/net/tap.c +++ b/net/tap.c @@ -384,8 +384,10 @@ static void tap_cleanup(NetClientState *nc) =20 qemu_purge_queued_packets(nc); =20 - tap_exit_notify(&s->exit, NULL); - qemu_remove_exit_notifier(&s->exit); + if (s->exit.notify) { + tap_exit_notify(&s->exit, NULL); + qemu_remove_exit_notifier(&s->exit); + } =20 tap_read_poll(s, false); tap_write_poll(s, false); @@ -775,9 +777,7 @@ static int net_tap_fd_init_common(const Netdev *netdev,= NetClientState *peer, } tap_read_poll(s, true); s->vhost_net =3D NULL; - - s->exit.notify =3D tap_exit_notify; - qemu_add_exit_notifier(&s->exit); + s->exit.notify =3D NULL; =20 if (netdev->type =3D=3D NET_CLIENT_DRIVER_BRIDGE) { const NetdevBridgeOptions *bridge =3D &netdev->u.bridge; @@ -805,6 +805,8 @@ static int net_tap_fd_init_common(const Netdev *netdev,= NetClientState *peer, snprintf(s->down_script, sizeof(s->down_script), "%s", downscr= ipt); snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname); + s->exit.notify =3D tap_exit_notify; + qemu_add_exit_notifier(&s->exit); } } =20 --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906733; cv=none; d=zohomail.com; s=zohoarc; b=k8sL+hHi+Jnins/KLXXlPvSDbWbyS6l6wlYY4CTC13YUyjQtYwOv/86broQHdskk8IJUAVaAQuRF3ILfMVsNVTIFh6u4vYvnqMqj929DtWooMhS0kfT3VDuD6EpL2N/cDpTm/x8XqQP1+1f2/+q6J8oEArhZGRHBhIlDyflraFs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906733; 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=o3d7PuXgCNqOyrQ19Zdb3HH/QsFbltz5ybQynB3AbEY=; b=fG9W4UplNjXf3FqUCsh4oTtqYbtcKXqT9ZyFSrjlBSmeBdMIlRL5VnFrFxWZYPNlYBeLNlYew2UQxaDxvzT4xIVCvn5ZAkLlFCfc6CqD/ch+CB8C2pdAUCsLCbjHAR028aAgy2C/Y6rRF15PQVBEMMZQOyZuSPs5YJz8cJbTfLY= 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 1756906733716593.5754969114915; Wed, 3 Sep 2025 06:38:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utng5-0005Fz-K8; Wed, 03 Sep 2025 09:37:33 -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 1utnfu-00059U-Qh for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:23 -0400 Received: from forwardcorp1a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfp-0004vt-Se for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:22 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id 73E6FC01A0; Wed, 03 Sep 2025 16:37:15 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-nQmFWkf9; Wed, 03 Sep 2025 16:37:14 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906634; bh=o3d7PuXgCNqOyrQ19Zdb3HH/QsFbltz5ybQynB3AbEY=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=qwshluS2t76eQLe75r/D85uB+rJLThFpnEEd8PWL0Ara3kcKGLycBCspjxFzgoyZl v2Iy8sfxj56hkxSrXwmRkwtyR1DKU+VJj4auENG8gbaSrXL4UTIrx3ZfIPPy3hubeV NfcsWKG6awT882bywzYiU2Ni7I+dbj/6+Ijx2e3w= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 3/8] net/tap: refactor net_tap_setup_vhost() Date: Wed, 3 Sep 2025 16:37:00 +0300 Message-ID: <20250903133706.1177633-4-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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=2a02:6b8:c0e:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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_DNSWL_NONE=-0.0001, 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: 1756906735538124100 Content-Type: text/plain; charset="utf-8" 1. Move function higher. (we anyway want to split it into two functions, and change the code a lot, so take an opportunity to get rid of extra declaration). 2. Split into _set_options() and _init_vhost(): we'll need it later to implement TAP local migration feature. 3. Split requires to store options somewhere, and to be able to call _init_vhost() later (from migriation _load() in later commit), store options in the TAPState. 4. So, take an opportunity to zero-initialize options: - be safe (avoid uninitialized options) - don't care to initialize half of the options to zero by hand 5. Also, don't worry too much about poll_us: absent option should be zero-initialized anyway. Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- net/tap.c | 123 +++++++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 57 deletions(-) diff --git a/net/tap.c b/net/tap.c index 7dc8af1e57..a9d955ac5f 100644 --- a/net/tap.c +++ b/net/tap.c @@ -78,6 +78,7 @@ typedef struct TAPState { bool has_ufo; bool has_uso; bool enabled; + VhostNetOptions *vhost_options; VHostNetState *vhost_net; unsigned host_vnet_hdr_len; Notifier exit; @@ -95,8 +96,6 @@ static int net_tap_fd_init_common(const Netdev *netdev, N= etClientState *peer, const char *downscript, const char *vhostfdname, int vnet_hdr, int fd, Error **errp); -static int net_tap_setup_vhost(TAPState *s, const NetdevTapOptions *tap, - const char *vhostfdname, Error **errp); =20 static void tap_update_fd_handler(TAPState *s) { @@ -382,6 +381,8 @@ static void tap_cleanup(NetClientState *nc) s->vhost_net =3D NULL; } =20 + g_free(s->vhost_options); + qemu_purge_queued_packets(nc); =20 if (s->exit.notify) { @@ -745,6 +746,63 @@ static int net_tap_open_one(const Netdev *netdev, =20 #define MAX_TAP_QUEUES 1024 =20 +static int net_tap_set_vhost_options(TAPState *s, const NetdevTapOptions *= tap, + const char *vhostfdname, Error **errp) +{ + int vhostfd; + bool vhost_on =3D tap->has_vhost ? tap->vhost : + vhostfdname || (tap->has_vhostforce && tap->vhostforce); + + if (!vhost_on) { + return 0; + } + + if (vhostfdname) { + vhostfd =3D monitor_fd_param(monitor_cur(), vhostfdname, errp); + if (vhostfd =3D=3D -1) { + return -1; + } + } else { + vhostfd =3D open("/dev/vhost-net", O_RDWR); + if (vhostfd < 0) { + error_setg_errno(errp, errno, + "tap: open vhost char device failed"); + return -1; + } + } + + if (!qemu_set_blocking(vhostfd, false, errp)) { + return -1; + } + + s->vhost_options =3D g_new(VhostNetOptions, 1); + *s->vhost_options =3D (VhostNetOptions) { + .backend_type =3D VHOST_BACKEND_TYPE_KERNEL, + .net_backend =3D &s->nc, + .busyloop_timeout =3D tap->poll_us, + .opaque =3D (void *)(uintptr_t)vhostfd, + .nvqs =3D 2, + .feature_bits =3D kernel_feature_bits, + }; + + return 0; +} + +static int net_tap_init_vhost(TAPState *s, Error **errp) { + if (!s->vhost_options) { + return 0; + } + + s->vhost_net =3D vhost_net_init(s->vhost_options); + if (!s->vhost_net) { + error_setg(errp, + "vhost-net requested but could not be initialized"); + return -1; + } + + return 0; +} + static int net_tap_fd_init_common(const Netdev *netdev, NetClientState *pe= er, const char *model, const char *name, const char *ifname, const char *script, @@ -810,7 +868,12 @@ static int net_tap_fd_init_common(const Netdev *netdev= , NetClientState *peer, } } =20 - ret =3D net_tap_setup_vhost(s, tap, vhostfdname, errp); + ret =3D net_tap_set_vhost_options(s, tap, vhostfdname, errp); + if (ret < 0) { + goto failed; + } + + ret =3D net_tap_init_vhost(s, errp); if (ret < 0) { goto failed; } @@ -822,60 +885,6 @@ failed: return -1; } =20 -static int net_tap_setup_vhost(TAPState *s, const NetdevTapOptions *tap, - const char *vhostfdname, Error **errp) -{ - if (tap->has_vhost ? tap->vhost : - vhostfdname || (tap->has_vhostforce && tap->vhostforce)) { - VhostNetOptions options; - int vhostfd; - - options.backend_type =3D VHOST_BACKEND_TYPE_KERNEL; - options.net_backend =3D &s->nc; - if (tap->has_poll_us) { - options.busyloop_timeout =3D tap->poll_us; - } else { - options.busyloop_timeout =3D 0; - } - - if (vhostfdname) { - vhostfd =3D monitor_fd_param(monitor_cur(), vhostfdname, errp); - if (vhostfd =3D=3D -1) { - return -1; - } - if (!qemu_set_blocking(vhostfd, false, errp)) { - return -1; - } - } else { - vhostfd =3D open("/dev/vhost-net", O_RDWR); - if (vhostfd < 0) { - error_setg_errno(errp, errno, - "tap: open vhost char device failed"); - return -1; - } - if (!qemu_set_blocking(vhostfd, false, errp)) { - return -1; - } - } - options.opaque =3D (void *)(uintptr_t)vhostfd; - options.nvqs =3D 2; - options.feature_bits =3D kernel_feature_bits; - options.get_acked_features =3D NULL; - options.save_acked_features =3D NULL; - options.max_tx_queue_size =3D 0; - options.is_vhost_user =3D false; - - s->vhost_net =3D vhost_net_init(&options); - if (!s->vhost_net) { - error_setg(errp, - "vhost-net requested but could not be initialized"); - return -1; - } - } - - return 0; -} - static int net_tap_from_monitor_fd(const Netdev *netdev, NetClientState *p= eer, const char *name, const char *vhostfdna= me, int *pvnet_hdr, const char *fdname, --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906696; cv=none; d=zohomail.com; s=zohoarc; b=BkDshzvP1iGEjn5WswidzbYO0aWQfQKf7ezv6yKlYPsnpx1nwu/d6jc27E68Sq4JF8e8rMxxamHKsvYeO9xnI90a1wYXiqdixdlKk1Wtph7FfrxfRoFbW2grO9B8vIFxyHLlLa18DCas9RstIhEFULGDZzBzTQRgmSTSFcaE1fU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906696; 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=ZIuITB1rd17BNdWGYUy9N1rTVr/YhJCJKjPp4gE6akA=; b=htNUBV5dY6dnAk9M2SVktb+cqGjP2ZviMHJVL/PsSUfeWVucpWZheb7dUoEtLhoZ3Wn7an2VohP74LdIlENVgj0Wk56LvNvPWb3ac6OrqYhRpAQ2jeTOpKzOLJFug85R6c0Fjw4LCBjJRWjVI00F0cDQNjnV+OPBg8RL86bqCiA= 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 1756906696325227.37377631952086; Wed, 3 Sep 2025 06:38:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utng6-0005Gw-0T; Wed, 03 Sep 2025 09:37:34 -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 1utnfu-00059S-QA for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:23 -0400 Received: from forwardcorp1a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfp-0004w7-QZ for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:22 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id 1D5C2C01A4; Wed, 03 Sep 2025 16:37:16 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-Fv3Tkeen; Wed, 03 Sep 2025 16:37:15 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906635; bh=ZIuITB1rd17BNdWGYUy9N1rTVr/YhJCJKjPp4gE6akA=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=na+wOSr64PlakhG5ElD/DgnHtD8yV5pfJdNHEm/CT9VaezRP8lqSV/XV0scoVGXPn T/JyoUGjmih+Ul/bFRtJf70k3q+IpIK8t+q7BvSzpDPyZKMJEct7E+vNx67Y3Qq0Cc 3kIR5RzjG9ubGURRfI3c0MQnIP03MPEpn062RE8I= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 4/8] qapi: add interface for local TAP migration Date: Wed, 3 Sep 2025 16:37:01 +0300 Message-ID: <20250903133706.1177633-5-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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=2a02:6b8:c0e:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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_DNSWL_NONE=-0.0001, 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: 1756906700485124100 Content-Type: text/plain; charset="utf-8" To migrate TAP device (including open fds) locally, user should: 1. enable local-tap migration capability both on source and target 2. use additional local-incoming=3Dtrue option for tap on target Why capability is not enough? We need an option to modify early initialization of TAP, to avoid opening new fds. The capability may not be set at the moment of netdev initialization. Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- migration/options.c | 7 +++++++ migration/options.h | 1 + qapi/migration.json | 9 ++++++++- qapi/net.json | 12 +++++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/migration/options.c b/migration/options.c index 4e923a2e07..6f5af52a5c 100644 --- a/migration/options.c +++ b/migration/options.c @@ -262,6 +262,13 @@ bool migrate_mapped_ram(void) return s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM]; } =20 +bool migrate_local_tap(void) +{ + MigrationState *s =3D migrate_get_current(); + + return s->capabilities[MIGRATION_CAPABILITY_LOCAL_TAP]; +} + bool migrate_ignore_shared(void) { MigrationState *s =3D migrate_get_current(); diff --git a/migration/options.h b/migration/options.h index 82d839709e..08c0606072 100644 --- a/migration/options.h +++ b/migration/options.h @@ -30,6 +30,7 @@ bool migrate_colo(void); bool migrate_dirty_bitmaps(void); bool migrate_events(void); bool migrate_mapped_ram(void); +bool migrate_local_tap(void); bool migrate_ignore_shared(void); bool migrate_late_block_activate(void); bool migrate_multifd(void); diff --git a/qapi/migration.json b/qapi/migration.json index 2387c21e9c..992a5b1e2b 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -517,6 +517,12 @@ # each RAM page. Requires a migration URI that supports seeking, # such as a file. (since 9.0) # +# @local-tap: Migrate TAPs locally, keeping backend alive. Open file +# descriptors and TAP-related state are migrated. Only may be +# used when migration channel is unix socket. For target device +# also @local-incoming option must be specified (since 10.2) +# (since 10.2) +# # Features: # # @unstable: Members @x-colo and @x-ignore-shared are experimental. @@ -536,7 +542,8 @@ { 'name': 'x-ignore-shared', 'features': [ 'unstable' ] }, 'validate-uuid', 'background-snapshot', 'zero-copy-send', 'postcopy-preempt', 'switchover-ack', - 'dirty-limit', 'mapped-ram'] } + 'dirty-limit', 'mapped-ram', + { 'name': 'local-tap', 'features': [ 'unstable' ] } ] } =20 ## # @MigrationCapabilityStatus: diff --git a/qapi/net.json b/qapi/net.json index 78bcc9871e..8f53549d58 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -353,6 +353,15 @@ # @poll-us: maximum number of microseconds that could be spent on busy # polling for tap (since 2.7) # +# @local-incoming: Do load open file descriptor for that TAP +# on incoming migration. May be used only if QEMU is started +# for incoming migration. Will work only together with local-tap +# migration capability enabled (default: false) (Since: 10.2) +# +# Features: +# +# @unstable: Member @local-incoming is experimental +# # Since: 1.2 ## { 'struct': 'NetdevTapOptions', @@ -371,7 +380,8 @@ '*vhostfds': 'str', '*vhostforce': 'bool', '*queues': 'uint32', - '*poll-us': 'uint32'} } + '*poll-us': 'uint32', + '*local-incoming': { 'type': 'bool', 'features': [ 'unstable' ] } } } =20 ## # @NetdevSocketOptions: --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906764; cv=none; d=zohomail.com; s=zohoarc; b=DGonl25eGeeZ+xjfuv6WR3KolImm1ZlR8qlYWqsCMbtKEiPfw7AjGv5Ql27kUXAfs2WAVMdcZrjfkT8F7PwiU15R1+Jg8rbSV81TJ/M6NSDWpgY7HbisGjJy67U31hV/GEXvCdXCuIbLfs9KhAZadKZtC5nKinxOx2/HP5Bjm8c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906764; 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=3KYcrL9COF6I/pEql3juewALPYmRgt15qbCAujjYteQ=; b=AzVyVdJUgQ0qBfigjN9YuGCQIsantntxO4obLuC2WbVS0fL4uZrvK5axsostLryqfSWLDl1oAJOCfhV+JTcqV7j+NJ1dPTOAMfzXVlpDPuGVkUpNbi7iNbQJ/3BXUXYVdwgjr5RwuqoWhKj9cGmI7h9RboorBiheoctUoxYk2gU= 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 1756906764041446.578203935676; Wed, 3 Sep 2025 06:39:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utng6-0005H2-6l; Wed, 03 Sep 2025 09:37:35 -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 1utnft-000584-4P for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:21 -0400 Received: from forwardcorp1a.mail.yandex.net ([178.154.239.72]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfq-0004wC-5C for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:20 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id BFF5CC01A7; Wed, 03 Sep 2025 16:37:16 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-H5C7rK5S; Wed, 03 Sep 2025 16:37:16 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906636; bh=3KYcrL9COF6I/pEql3juewALPYmRgt15qbCAujjYteQ=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=rih6eT3xn7hslh1z/c5HYOIruhoTgvBOzNn0ZPYLVBq15idHB7Qph2faLJ+C4tRaS Hi2r4+QyW09Wp4xaIWAOkENDeJgw1/ZcxG4BULJOIaHgjtppmtLb4yIP9C36DRwZD7 4a8Z8ZEaxVUhei6/C6jIt5dYSJEvsSBhSdtlq2RI= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 5/8] net/tap: implement interfaces for local migration Date: Wed, 3 Sep 2025 16:37:02 +0300 Message-ID: <20250903133706.1177633-6-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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.72; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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: 1756906765596124100 Content-Type: text/plain; charset="utf-8" Handle local-incoming option: Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- include/net/tap.h | 4 ++ net/tap.c | 136 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 119 insertions(+), 21 deletions(-) diff --git a/include/net/tap.h b/include/net/tap.h index 6f34f13eae..3ef2e2dbae 100644 --- a/include/net/tap.h +++ b/include/net/tap.h @@ -30,7 +30,11 @@ =20 int tap_enable(NetClientState *nc); int tap_disable(NetClientState *nc); +bool tap_local_incoming(NetClientState *nc); =20 int tap_get_fd(NetClientState *nc); =20 +int tap_load(NetClientState *nc, QEMUFile *f); +int tap_save(NetClientState *nc, QEMUFile *f); + #endif /* QEMU_NET_TAP_H */ diff --git a/net/tap.c b/net/tap.c index a9d955ac5f..499db756ea 100644 --- a/net/tap.c +++ b/net/tap.c @@ -35,6 +35,8 @@ #include "net/eth.h" #include "net/net.h" #include "clients.h" +#include "migration/migration.h" +#include "migration/qemu-file.h" #include "monitor/monitor.h" #include "system/system.h" #include "qapi/error.h" @@ -82,6 +84,7 @@ typedef struct TAPState { VHostNetState *vhost_net; unsigned host_vnet_hdr_len; Notifier exit; + bool local_incoming; } TAPState; =20 static void launch_script(const char *setup_script, const char *ifname, @@ -803,6 +806,40 @@ static int net_tap_init_vhost(TAPState *s, Error **err= p) { return 0; } =20 +int tap_save(NetClientState *nc, QEMUFile *f) +{ + TAPState *s =3D DO_UPCAST(TAPState, nc, nc); + + qemu_file_put_fd(f, s->fd); + qemu_put_byte(f, s->using_vnet_hdr); + qemu_put_byte(f, s->has_ufo); + qemu_put_byte(f, s->has_uso); + qemu_put_byte(f, s->enabled); + qemu_put_be32(f, s->host_vnet_hdr_len); + + return 0; +} + +int tap_load(NetClientState *nc, QEMUFile *f) +{ + TAPState *s =3D DO_UPCAST(TAPState, nc, nc); + + s->fd =3D qemu_file_get_fd(f); + if (s->fd < 0) { + return -1; + } + + s->using_vnet_hdr =3D qemu_get_byte(f); + s->has_ufo =3D qemu_get_byte(f); + s->has_uso =3D qemu_get_byte(f); + s->enabled =3D qemu_get_byte(f); + qemu_get_be32s(f, &s->host_vnet_hdr_len); + + tap_read_poll(s, true); + + return net_tap_init_vhost(s, NULL); +} + static int net_tap_fd_init_common(const Netdev *netdev, NetClientState *pe= er, const char *model, const char *name, const char *ifname, const char *script, @@ -810,30 +847,40 @@ static int net_tap_fd_init_common(const Netdev *netde= v, NetClientState *peer, const char *vhostfdname, int vnet_hdr, int fd, Error **errp) { - const NetdevTapOptions *tap; + const NetdevTapOptions *tap =3D NULL; int ret; NetClientState *nc; TAPState *s; + bool local_incoming =3D false; + + if (netdev->type =3D=3D NET_CLIENT_DRIVER_TAP) { + tap =3D &netdev->u.tap; + local_incoming =3D tap->local_incoming; + } =20 nc =3D qemu_new_net_client(&net_tap_info, peer, model, name); =20 s =3D DO_UPCAST(TAPState, nc, nc); - - s->fd =3D fd; - s->host_vnet_hdr_len =3D vnet_hdr ? sizeof(struct virtio_net_hdr) : 0; - s->using_vnet_hdr =3D false; - s->has_ufo =3D tap_probe_has_ufo(s->fd); - s->has_uso =3D tap_probe_has_uso(s->fd); - s->enabled =3D true; - tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0); - /* - * Make sure host header length is set correctly in tap: - * it might have been modified by another instance of qemu. - */ - if (vnet_hdr) { - tap_fd_set_vnet_hdr_len(s->fd, s->host_vnet_hdr_len); + s->local_incoming =3D local_incoming; + + if (!local_incoming) { + s->fd =3D fd; + s->host_vnet_hdr_len =3D vnet_hdr ? sizeof(struct virtio_net_hdr) = : 0; + s->using_vnet_hdr =3D false; + s->has_ufo =3D tap_probe_has_ufo(s->fd); + s->has_uso =3D tap_probe_has_uso(s->fd); + s->enabled =3D true; + tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0); + /* + * Make sure host header length is set correctly in tap: + * it might have been modified by another instance of qemu. + */ + if (vnet_hdr) { + tap_fd_set_vnet_hdr_len(s->fd, s->host_vnet_hdr_len); + } + tap_read_poll(s, true); } - tap_read_poll(s, true); + s->vhost_net =3D NULL; s->exit.notify =3D NULL; =20 @@ -845,9 +892,8 @@ static int net_tap_fd_init_common(const Netdev *netdev,= NetClientState *peer, } =20 assert(netdev->type =3D=3D NET_CLIENT_DRIVER_TAP); - tap =3D &netdev->u.tap; =20 - if (tap_set_sndbuf(s->fd, tap, errp) < 0) { + if (!local_incoming && tap_set_sndbuf(s->fd, tap, errp) < 0) { goto failed; } =20 @@ -873,9 +919,11 @@ static int net_tap_fd_init_common(const Netdev *netdev= , NetClientState *peer, goto failed; } =20 - ret =3D net_tap_init_vhost(s, errp); - if (ret < 0) { - goto failed; + if (!local_incoming) { + ret =3D net_tap_init_vhost(s, errp); + if (ret < 0) { + goto failed; + } } =20 return 0; @@ -942,6 +990,38 @@ static int net_tap_open(const Netdev *netdev, return 0; } =20 +static int net_init_local_incoming(const Netdev *netdev, + const char *name, + NetClientState *peer, + Error **errp) +{ + const NetdevTapOptions *tap =3D &netdev->u.tap; + const char *downscript =3D tap->downscript; + int queues =3D tap->has_queues ? tap->queues : 1; + g_autofree char *default_downscript =3D NULL; + int i, ret; + + assert(netdev->type =3D=3D NET_CLIENT_DRIVER_TAP); + assert(!tap->script); + + if (!downscript) { + downscript =3D default_downscript =3D + get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIP= T); + } + + for (i =3D 0; i < queues; i++) { + ret =3D net_tap_fd_init_common(netdev, peer, "tap", name, + tap->ifname ?: "", + "no", downscript, + tap->vhostfd, -1, -1, errp); + if (ret < 0) { + return -1; + } + } + + return 0; +} + static int net_init_tap_fds(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp) { @@ -1030,6 +1110,13 @@ int net_init_tap(const Netdev *netdev, const char *n= ame, } =20 return net_init_bridge(netdev, name, peer, errp); + } else if (tap->local_incoming) { + if (tap->script) { + error_setg(errp, "script=3D is invalid with local-incoming"); + return -1; + } + + return net_init_local_incoming(netdev, name, peer, errp); } =20 if (tap->vhostfds) { @@ -1078,3 +1165,10 @@ int tap_disable(NetClientState *nc) return ret; } } + +bool tap_local_incoming(NetClientState *nc) +{ + TAPState *s =3D DO_UPCAST(TAPState, nc, nc); + + return s->local_incoming && runstate_check(RUN_STATE_INMIGRATE); +} --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906709; cv=none; d=zohomail.com; s=zohoarc; b=eDyyYqCe8n90wnFfjb+HNeCs5y2nY4dAXCks6wjzj2/bkcztFpCF9H5kwvhJXaG3jXdVTVl6u2Nl9X/4w1W6DmYemNRcWYiAvnak4qQVyPl4FjLDAdarshrQC+5n7S5TGSE/C/58Ph3NJ7TCrtBQgwADtz/YMTCiChAnUejPvX8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906709; 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=GftTvKuCJ/20RJKBye2/TezLhjc0gyXvfMSFYxlvOO8=; b=K4cL0Gbu5co5cnCxt+dfepXAKc5vBj1LlnLz4qJJRc1ijI/C6S7c9tldDc8K0X1az+gN6IAl7EU0BNFDiiW719zBmviGWEiBy6llBS0z3aeEQDBaZJl7mRrm+T84eB/n0PTjTxhQNY2gIYLv183V9b+y5JFj2hosI9xeiIk/5EU= 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 1756906709097890.829689796582; Wed, 3 Sep 2025 06:38:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utngC-0005Hd-0u; Wed, 03 Sep 2025 09:37:41 -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 1utnfu-00059V-Qi for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:23 -0400 Received: from forwardcorp1a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfq-0004wY-PL for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:22 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id 71616C01A8; Wed, 03 Sep 2025 16:37:17 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-J7CkUe3K; Wed, 03 Sep 2025 16:37:16 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906636; bh=GftTvKuCJ/20RJKBye2/TezLhjc0gyXvfMSFYxlvOO8=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=y2zSpmtroCmqBEGOq0B5Fqc9nSNMvW+h/AkFw4Ry1kvlo4wrOul9+cpZxLT2KVY7z yBxJxHBX2vStSHYOgUMBhuv51u1Wm+3R1oTo6iFLWyGlF/KnDI5WAC2rRu9HH+Aqzq q0iHM3+i5a+PPChe15hNsT2WnYk1nwLblTCT6uTY= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 6/8] virtio-net: support local tap migration Date: Wed, 3 Sep 2025 16:37:03 +0300 Message-ID: <20250903133706.1177633-7-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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=2a02:6b8:c0e:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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_DNSWL_NONE=-0.0001, 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: 1756906711350116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- hw/net/virtio-net.c | 100 ++++++++++++++++++++++++++++++++- include/hw/virtio/virtio-net.h | 2 + 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 6b5b5dace3..874e349fee 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -38,6 +38,8 @@ #include "qapi/qapi-events-migration.h" #include "hw/virtio/virtio-access.h" #include "migration/misc.h" +#include "migration/migration.h" +#include "migration/options.h" #include "standard-headers/linux/ethtool.h" #include "system/system.h" #include "system/replay.h" @@ -2999,7 +3001,13 @@ static void virtio_net_set_multiqueue(VirtIONet *n, = int multiqueue) n->multiqueue =3D multiqueue; virtio_net_change_num_queues(n, max * 2 + 1); =20 - virtio_net_set_queue_pairs(n); + /* + * Called from set_features(0) on reset, when on target we + * doesn't have fds yet + */ + if (!n->tap_wait_incoming) { + virtio_net_set_queue_pairs(n); + } } =20 static int virtio_net_pre_load_queues(VirtIODevice *vdev, uint32_t n) @@ -3009,6 +3017,19 @@ static int virtio_net_pre_load_queues(VirtIODevice *= vdev, uint32_t n) return 0; } =20 +static int virtio_net_pre_save_device(void *opaque) +{ + VirtIONet *n =3D opaque; + int i, r; + + for (i =3D 0; i < n->curr_queue_pairs; i++) { + r =3D peer_detach(n, i); + assert(!r); + } + + return 0; +} + static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t featu= res, Error **errp) { @@ -3028,6 +3049,11 @@ static uint64_t virtio_net_get_features(VirtIODevice= *vdev, uint64_t features, =20 virtio_add_feature(&features, VIRTIO_NET_F_MAC); =20 + if (n->tap_wait_incoming) { + /* Excessive feature set is OK for early initialization */ + return features; + } + if (!peer_has_vnet_hdr(n)) { virtio_clear_feature(&features, VIRTIO_NET_F_CSUM); virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4); @@ -3494,11 +3520,69 @@ static const VMStateDescription vhost_user_net_back= end_state =3D { } }; =20 +static int virtio_net_tap_save(QEMUFile *f, void *pv, size_t size, + const VMStateField *field, + JSONWriter *vmdesc) +{ + VirtIONet *n =3D pv; + int i; + + for (i =3D 0; i < n->max_queue_pairs; i++) { + NetClientState *nc =3D qemu_get_subqueue(n->nic, i); + assert(nc->peer->info->type =3D=3D NET_CLIENT_DRIVER_TAP); + + tap_save(nc->peer, f); + } + + return 0; +} + +static int virtio_net_tap_load(QEMUFile *f, void *pv, size_t size, + const VMStateField *field) +{ + VirtIONet *n =3D pv; + VirtIODevice *vdev =3D VIRTIO_DEVICE(n); + VirtioDeviceClass *vdc =3D VIRTIO_DEVICE_GET_CLASS(vdev); + Error *local_err =3D NULL; + int i; + + for (i =3D 0; i < n->max_queue_pairs; i++) { + NetClientState *nc =3D qemu_get_subqueue(n->nic, i); + assert(nc->peer->info->type =3D=3D NET_CLIENT_DRIVER_TAP); + + tap_load(nc->peer, f); + } + + peer_test_vnet_hdr(n); + n->tap_wait_incoming =3D false; + + vdev->host_features =3D vdc->get_features(vdev, vdev->host_features, + &local_err); + if (local_err) { + error_report_err(local_err); + return -EINVAL; + } + + return 0; +} + +static bool virtio_net_is_tap_local(void *opaque, int version_id) +{ + VirtIONet *n =3D opaque; + NetClientState *nc; + + nc =3D qemu_get_queue(n->nic); + + return migrate_local_tap() && nc->peer && + nc->peer->info->type =3D=3D NET_CLIENT_DRIVER_TAP; +} + static const VMStateDescription vmstate_virtio_net_device =3D { .name =3D "virtio-net-device", .version_id =3D VIRTIO_NET_VM_VERSION, .minimum_version_id =3D VIRTIO_NET_VM_VERSION, .post_load =3D virtio_net_post_load_device, + .pre_save =3D virtio_net_pre_save_device, .fields =3D (const VMStateField[]) { VMSTATE_UINT8_ARRAY(mac, VirtIONet, ETH_ALEN), VMSTATE_STRUCT_POINTER(vqs, VirtIONet, @@ -3525,6 +3609,15 @@ static const VMStateDescription vmstate_virtio_net_d= evice =3D { * but based on the uint. */ VMSTATE_BUFFER_POINTER_UNSAFE(vlans, VirtIONet, 0, MAX_VLAN >> 3), + { + .name =3D "tap", + .info =3D &(const VMStateInfo) { + .name =3D "virtio-net vhost-user backend state", + .get =3D virtio_net_tap_load, + .put =3D virtio_net_tap_save, + }, + .field_exists =3D virtio_net_is_tap_local, + }, VMSTATE_WITH_TMP(VirtIONet, struct VirtIONetMigTmp, vmstate_virtio_net_has_vnet), VMSTATE_UINT8(mac_table.multi_overflow, VirtIONet), @@ -3954,6 +4047,11 @@ static void virtio_net_device_realize(DeviceState *d= ev, Error **errp) vhost_net_set_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg, 0, ETH_ALEN, VHOST_SET_CONFIG_TYPE_FRONTEN= D); } + + if (nc->peer && nc->peer->info->type =3D=3D NET_CLIENT_DRIVER_TAP) { + n->tap_wait_incoming =3D tap_local_incoming(nc->peer); + } + QTAILQ_INIT(&n->rsc_chains); n->qdev =3D dev; =20 diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 73fdefc0dc..04ae0e4c06 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -231,6 +231,8 @@ struct VirtIONet { struct EBPFRSSContext ebpf_rss; uint32_t nr_ebpf_rss_fds; char **ebpf_rss_fds; + + bool tap_wait_incoming; }; =20 size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev, --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906711; cv=none; d=zohomail.com; s=zohoarc; b=RqQ0JdzVDtElFgTG+aC6TOXf3DP88YgiVTrYvH/dhTK083wk3iLZZ/NR4I7DCR2UBnfnTzq/izQhINgxnaLVlhTYfRY2eLXDAtTmkfmM6MfpQGNCHKxjb322HQMw1csgb/ZEJlU1hR4do0ulpm0WFPXUTMvmbc5KC2Ya8rH99h0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906711; h=Content-Type: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=xzcdYCb73x3t/fdZEEKsSgOBm4tobZHvOXDAvGXSlv0=; b=aQNSKGvyVOtP4FfeU1EjCGwUcsVGD1PoySWJCH6WutL20JDsdaHXfqYY1yTr+6S5/8rUqYpq2nIWZQR04GybhkdCF8QZYk6DKjGEXimXRU+V7VzEEzU5Cc5okq12yGqFGZyrD8/3GkUlMTLgY9wAiK1jn/bNbWWQPYFzZDsNwrQ= 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 1756906710565600.3930567489606; Wed, 3 Sep 2025 06:38:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utngF-0005Rf-D6; Wed, 03 Sep 2025 09:37:43 -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 1utnfw-0005Bl-3e for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:25 -0400 Received: from forwardcorp1a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfr-0004x8-Cw for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:23 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id 11156C01AA; Wed, 03 Sep 2025 16:37:18 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-7JCLZnDD; Wed, 03 Sep 2025 16:37:17 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906637; bh=xzcdYCb73x3t/fdZEEKsSgOBm4tobZHvOXDAvGXSlv0=; h=Cc:Message-ID:References:Date:In-Reply-To:Subject:To:From; b=oe3WJG+ZmPzwZaZe0Tv0Ng300s0HzCGw8XCVGxrMlvJXl2HnOiD4sTPqW5Lwd3DAI mtH4bn2eB1wty4t3z8MkyX5JafQp19maAvKIhCv+mtB7WIDdKx6ZaA53uJTMhA2tVg cvGufUviIH1eEmKiYMlSEtO8LLh5wLfinEsfco1g= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 7/8] test/functional: exec_command_and_wait_for_pattern: add vm arg Date: Wed, 3 Sep 2025 16:37:04 +0300 Message-ID: <20250903133706.1177633-8-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=2a02:6b8:c0e:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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_DNSWL_NONE=-0.0001, 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: 1756906713268116600 Allow to specify non default vm for the command. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Thomas Huth Tested-by: Lei Yang --- tests/functional/qemu_test/cmd.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test= /cmd.py index dc5f422b77..28b36a3a54 100644 --- a/tests/functional/qemu_test/cmd.py +++ b/tests/functional/qemu_test/cmd.py @@ -172,7 +172,8 @@ def exec_command(test, command): _console_interaction(test, None, None, command + '\r') =20 def exec_command_and_wait_for_pattern(test, command, - success_message, failure_message=3DN= one): + success_message, failure_message=3DN= one, + vm=3DNone): """ Send a command to a console (appending CRLF characters), then wait for success_message to appear on the console, while logging the. @@ -184,9 +185,11 @@ def exec_command_and_wait_for_pattern(test, command, :param command: the command to send :param success_message: if this message appears, test succeeds :param failure_message: if this message appears, test fails + :param vm: the VM to use (defaults to test.vm if None) """ assert success_message - _console_interaction(test, success_message, failure_message, command += '\r') + _console_interaction(test, success_message, failure_message, command += '\r', + vm=3Dvm) =20 def get_qemu_img(test): test.log.debug('Looking for and selecting a qemu-img binary') --=20 2.48.1 From nobody Sat Sep 6 14:41:19 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=1756906770; cv=none; d=zohomail.com; s=zohoarc; b=KzaGt23TNOAJJkkoB/GRz3eoqAY3fNPHtqVl2s/+REbjTrOHYl9V/jIRMU1uxP9pcivOzAtjje859ThqnbUnpu+5mA04o0wO7ukec884p/Rra1e5ge237f21ge0Dhe1rXpdaI5XGrgCSawPe6dbIvQpeRawMTIxepU0jBZdTO+A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756906770; 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=jI2xXG4ZnB8h51vVyKGOkOZl6WAFYyvCTxq8YUSWu3Y=; b=D5cJzbrjxuOTEpQtOiK3lFQDtkVgUO7+lzGnliuUyUwm8vumcjlR6ex9RW+A5NXCrrCeYDpPjviN9s5+7se0IdQJxJckiMPKDWxTO6CGKHO1XZDvbYft5JOuU8uwMoPFK6J6p8lgFQobdFFl+56ISTnSbZXZONVw8ixSlBoOxY0= 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 1756906770502581.1557941248317; Wed, 3 Sep 2025 06:39:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utngG-0005Tk-3y; Wed, 03 Sep 2025 09:37:44 -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 1utnfw-0005CP-TW for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:25 -0400 Received: from forwardcorp1a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1utnfs-0004xV-CL for qemu-devel@nongnu.org; Wed, 03 Sep 2025 09:37:24 -0400 Received: from mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net [IPv6:2a02:6b8:c2d:7394:0:640:5a8a:0]) by forwardcorp1a.mail.yandex.net (Yandex) with ESMTPS id 08906C01AC; Wed, 03 Sep 2025 16:37:19 +0300 (MSK) Received: from vsementsov-lin.. (unknown [2a02:6bf:8080:b8f::1:11]) by mail-nwsmtp-smtp-corp-main-83.vla.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id BbgRSa3GomI0-NLFZSUOw; Wed, 03 Sep 2025 16:37:18 +0300 Precedence: bulk X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1756906638; bh=jI2xXG4ZnB8h51vVyKGOkOZl6WAFYyvCTxq8YUSWu3Y=; h=Message-ID:Date:In-Reply-To:Cc:Subject:References:To:From; b=UG4dbjjEzHTILe6eSdC2BLv1thKaPJ6VDwR1HktUudRXQIaUFK6XYcdaz0BqOXgj3 JPRUqn28/wfTcvUL38+rn84DsnJBcDh0FxuFBVg2RyP2vFLElslhCmtX74hjA8rvT9 AaOUuG0aIeJzp7OhimDmABwTSEd3St+iCbzRRuik= Authentication-Results: mail-nwsmtp-smtp-corp-main-83.vla.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, steven.sistare@oracle.com, yc-core@yandex-team.ru, peterx@redhat.com, mst@redhat.com, farosas@suse.de, eblake@redhat.com, armbru@redhat.com, thuth@redhat.com, philmd@linaro.org, berrange@redhat.com Subject: [PATCH v2 8/8] tests/functional: add test_x86_64_tap_fd_migration Date: Wed, 3 Sep 2025 16:37:05 +0300 Message-ID: <20250903133706.1177633-9-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250903133706.1177633-1-vsementsov@yandex-team.ru> References: <20250903133706.1177633-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=2a02:6b8:c0e:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1a.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_DNSWL_NONE=-0.0001, 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: 1756906772033116600 Content-Type: text/plain; charset="utf-8" Add test for a new feature of local TAP migration with fd passing through unix socket. Signed-off-by: Vladimir Sementsov-Ogievskiy Tested-by: Lei Yang --- .../test_x86_64_tap_fd_migration.py | 347 ++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 tests/functional/test_x86_64_tap_fd_migration.py diff --git a/tests/functional/test_x86_64_tap_fd_migration.py b/tests/funct= ional/test_x86_64_tap_fd_migration.py new file mode 100644 index 0000000000..f6d18fe39f --- /dev/null +++ b/tests/functional/test_x86_64_tap_fd_migration.py @@ -0,0 +1,347 @@ +#!/usr/bin/env python3 +# +# Functional test that tests TAP local migration +# with fd passing +# +# Copyright (c) Yandex +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import time +import subprocess +import signal +from typing import Tuple + +from qemu_test import ( + LinuxKernelTest, + Asset, + exec_command_and_wait_for_pattern, +) + +GUEST_IP =3D "10.0.1.2" +GUEST_IP_MASK =3D f"{GUEST_IP}/24" +GUEST_MAC =3D "d6:0d:75:f8:0f:b7" +HOST_IP =3D "10.0.1.1" +HOST_IP_MASK =3D f"{HOST_IP}/24" +TAP_ID =3D "tap0" +TAP_MAC =3D "e6:1d:44:b5:03:5d" + + +def run(cmd: str, check: bool =3D True) -> None: + subprocess.run(cmd, check=3Dcheck, shell=3DTrue) + + +def fetch(cmd: str, check: bool =3D True) -> str: + return subprocess.run( + cmd, check=3Dcheck, shell=3DTrue, stdout=3Dsubprocess.PIPE, text= =3DTrue + ).stdout + + +def del_tap() -> None: + run(f"ip tuntap del {TAP_ID} mode tap multi_queue", check=3DFalse) + + +def init_tap() -> None: + run(f"ip tuntap add dev {TAP_ID} mode tap multi_queue") + run(f"ip link set dev {TAP_ID} address {TAP_MAC}") + run(f"ip addr add {HOST_IP_MASK} dev {TAP_ID}") + run(f"ip link set {TAP_ID} up") + + +def parse_ping_line(line: str) -> float: + # suspect lines like + # [1748524876.590509] 64 bytes from 94.245.155.3 \ + # (94.245.155.3): icmp_seq=3D1 ttl=3D250 time=3D101 ms + spl =3D line.split() + return float(spl[0][1:-1]) + + +def parse_ping_output(out) -> Tuple[bool, float, float]: + lines =3D [x for x in out.split("\n") if x.startswith("[")] + + try: + first_no_ans =3D next( + (ind for ind in range(len(lines)) if lines[ind][20:26] =3D=3D = "no ans") + ) + except StopIteration: + return False, parse_ping_line(lines[0]), parse_ping_line(lines[-1]) + + last_no_ans =3D next( + (ind for ind in range(len(lines) - 1, -1, -1) if lines[ind][20:26]= =3D=3D "no ans") + ) + + return ( + True, + parse_ping_line(lines[first_no_ans]), + parse_ping_line(lines[last_no_ans]), + ) + + +def wait_migration_finish(source_vm, target_vm): + migr_events =3D ( + ("MIGRATION", {"data": {"status": "completed"}}), + ("MIGRATION", {"data": {"status": "failed"}}), + ) + + source_e =3D source_vm.events_wait(migr_events)["data"] + target_e =3D target_vm.events_wait(migr_events)["data"] + + source_s =3D source_vm.cmd("query-status")["status"] + target_s =3D target_vm.cmd("query-status")["status"] + + assert ( + source_e["status"] =3D=3D "completed" + and target_e["status"] =3D=3D "completed" + and source_s =3D=3D "postmigrate" + and target_s =3D=3D "paused" + ), f"""Migration failed: + SRC status: {source_s} + SRC event: {source_e} + TGT status: {target_s} + TGT event:{target_e}""" + + +class VhostUserBlkFdMigration(LinuxKernelTest): + + ASSET_KERNEL =3D Asset( + ( + "https://archives.fedoraproject.org/pub/archive/fedora/linux/r= eleases" + "/31/Server/x86_64/os/images/pxeboot/vmlinuz" + ), + "d4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129", + ) + + ASSET_INITRD =3D Asset( + ( + "https://archives.fedoraproject.org/pub/archive/fedora/linux/r= eleases" + "/31/Server/x86_64/os/images/pxeboot/initrd.img" + ), + "277cd6c7adf77c7e63d73bbb2cded8ef9e2d3a2f100000e92ff1f8396513cd8b", + ) + + ASSET_ALPINE_ISO =3D Asset( + ( + "https://dl-cdn.alpinelinux.org/" + "alpine/v3.22/releases/x86_64/alpine-standard-3.22.1-x86_64.is= o" + ), + "96d1b44ea1b8a5a884f193526d92edb4676054e9fa903ad2f016441a0fe13089", + ) + + def setUp(self): + super().setUp() + + init_tap() + + self.outer_ping_proc =3D None + + def tearDown(self): + del_tap() + + if self.outer_ping_proc: + self.stop_outer_ping() + + super().tearDown() + + def start_outer_ping(self) -> None: + assert self.outer_ping_proc is None + self.outer_ping_log =3D open("/tmp/ping.log", "w") + self.outer_ping_proc =3D subprocess.Popen( + ["ping", "-i", "0", "-O", "-D", GUEST_IP], + text=3DTrue, + stdout=3Dself.outer_ping_log, + ) + + def stop_outer_ping(self) -> str: + assert self.outer_ping_proc + self.outer_ping_proc.send_signal(signal.SIGINT) + + self.outer_ping_proc.communicate(timeout=3D5) + self.outer_ping_proc =3D None + self.outer_ping_log.close() + + # We need the start, the end and several lines around "no answer" + cmd =3D "cat /tmp/ping.log | grep -A 4 -B 4 'PING\\|packets\\|no a= ns'" + return fetch(cmd) + + def stop_ping_and_check(self, stop_time, resume_time): + ping_res =3D self.stop_outer_ping() + + discon, a, b =3D parse_ping_output(ping_res) + + if not discon: + text =3D f"STOP: {stop_time}, RESUME: {resume_time}," f"PING: = {a} - {b}" + if a > stop_time or b < resume_time: + self.fail(f"PING failed: {text}") + self.log.info(f"PING: no packets lost: {text}") + return + + text =3D ( + f"STOP: {stop_time}, RESUME: {resume_time}," f"PING: disconnec= t: {a} - {b}" + ) + self.log.info(text) + eps =3D 0.01 + if a < stop_time - eps or b > resume_time + eps: + self.fail(text) + + def one_ping_from_guest(self, vm) -> None: + exec_command_and_wait_for_pattern( + self, + f"ping -c 1 -W 1 {HOST_IP}", + "1 packets transmitted, 1 packets received", + "1 packets transmitted, 0 packets received", + vm=3Dvm, + ) + self.wait_for_console_pattern("# ", vm=3Dvm) + + def one_ping_from_host(self) -> None: + run(f"ping -c 1 -W 1 {GUEST_IP}") + + def setup_shared_memory(self): + shm_path =3D f"/dev/shm/qemu_test_{os.getpid()}" + + try: + with open(shm_path, "wb") as f: + f.write(b"\0" * (1024 * 1024 * 1024)) # 1GB + except Exception as e: + self.fail(f"Failed to create shared memory file: {e}") + + return shm_path + + def prepare_and_launch_vm(self, shm_path, vhost, incoming=3DFalse, vm= =3DNone): + if not vm: + vm =3D self.vm + + vm.set_console() + vm.add_args("-accel", "kvm") + vm.add_args("-device", "pcie-pci-bridge,id=3Dpci.1,bus=3Dpcie.0") + vm.add_args("-m", "1G") + + vm.add_args( + "-object", + f"memory-backend-file,id=3Dram0,size=3D1G,mem-path=3D{shm_path= },share=3Don", + ) + vm.add_args("-machine", "memory-backend=3Dram0") + + vm.add_args( + "-drive", f"file=3D{self.ASSET_ALPINE_ISO.fetch()},media=3Dcdr= om,format=3Draw" + ) + + vm.add_args("-S") + + if incoming: + vm.add_args("-incoming", "defer") + + vm_s =3D "target" if incoming else "source" + self.log.info(f"Launching {vm_s} VM") + vm.launch() + + self.set_migration_capabilities(vm) + self.add_virtio_net(vm, vhost, incoming) + + def add_virtio_net(self, vm, vhost: bool, incoming: bool =3D False): + netdev_params =3D { + "id": "netdev.1", + "vhost": vhost, + "type": "tap", + "ifname": "tap0", + "downscript": "no", + "queues": 4, + } + + if incoming: + netdev_params["local-incoming"] =3D True + else: + netdev_params["script"] =3D "no" + + vm.cmd("netdev_add", netdev_params) + + vm.cmd( + "device_add", + driver=3D"virtio-net-pci", + romfile=3D"", + id=3D"vnet.1", + netdev=3D"netdev.1", + mq=3DTrue, + vectors=3D18, + bus=3D"pci.1", + mac=3DGUEST_MAC, + disable_legacy=3D"off", + ) + + def set_migration_capabilities(self, vm): + capabilities =3D [ + {"capability": "events", "state": True}, + {"capability": "x-ignore-shared", "state": True}, + {"capability": "local-tap", "state": True}, + ] + vm.cmd("migrate-set-capabilities", {"capabilities": capabilities}) + + def setup_guest_network(self) -> None: + exec_command_and_wait_for_pattern(self, "ip addr", "# ") + exec_command_and_wait_for_pattern( + self, + f"ip addr add {GUEST_IP_MASK} dev eth0 && ip link set eth0 up = && echo OK", + "OK", + ) + self.wait_for_console_pattern("# ") + + def do_test_tap_fd_migration(self, vhost): + self.require_accelerator("kvm") + self.set_machine("q35") + + socket_dir =3D self.socket_dir() + migration_socket =3D os.path.join(socket_dir.name, "migration.sock= ") + + shm_path =3D self.setup_shared_memory() + + self.prepare_and_launch_vm(shm_path, vhost) + self.vm.cmd("cont") + self.wait_for_console_pattern("login:") + exec_command_and_wait_for_pattern(self, "root", "# ") + + self.setup_guest_network() + + self.one_ping_from_guest(self.vm) + self.one_ping_from_host() + self.start_outer_ping() + + # Get some successful pings before migration + time.sleep(0.5) + + target_vm =3D self.get_vm(name=3D"target") + self.prepare_and_launch_vm(shm_path, vhost, incoming=3DTrue, vm=3D= target_vm) + + target_vm.cmd("migrate-incoming", {"uri": f"unix:{migration_socket= }"}) + + self.log.info("Starting migration") + freeze_start =3D time.time() + self.vm.cmd("migrate", {"uri": f"unix:{migration_socket}"}) + + self.log.info("Waiting for migration completion") + wait_migration_finish(self.vm, target_vm) + + target_vm.cmd("cont") + freeze_end =3D time.time() + + self.vm.shutdown() + + self.log.info("Verifying PING on target VM after migration") + self.one_ping_from_guest(target_vm) + self.one_ping_from_host() + + # And a bit more pings after source shutdown + time.sleep(0.3) + self.stop_ping_and_check(freeze_start, freeze_end) + + target_vm.shutdown() + + def test_tap_fd_migration(self): + self.do_test_tap_fd_migration(False) + + def test_tap_fd_migration_vhost(self): + self.do_test_tap_fd_migration(True) + + +if __name__ =3D=3D "__main__": + LinuxKernelTest.main() --=20 2.48.1