From nobody Sun Dec 14 12:14:58 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1764754678645893.3027193597043; Wed, 3 Dec 2025 01:37:58 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vQjHi-0000Hz-2p; Wed, 03 Dec 2025 04:36:30 -0500 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 1vQjHg-0000GP-GP; Wed, 03 Dec 2025 04:36:28 -0500 Received: from isrv.corpit.ru ([212.248.84.144]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vQjHe-00074s-K6; Wed, 03 Dec 2025 04:36:28 -0500 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id 94A7D1708B2; Wed, 03 Dec 2025 12:35:54 +0300 (MSK) Received: from think4mjt.tls.msk.ru (mjtthink.wg.tls.msk.ru [192.168.177.146]) by tsrv.corpit.ru (Postfix) with ESMTP id 7F0EF32B5A9; Wed, 03 Dec 2025 12:36:12 +0300 (MSK) From: Michael Tokarev To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Lucas Kornicki , Fiona Ebner , Michael Tokarev Subject: [Stable-10.1.3 83/96] ui/vdagent: fix windows agent regression Date: Wed, 3 Dec 2025 12:35:16 +0300 Message-ID: <20251203093612.2370716-7-mjt@tls.msk.ru> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: 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=212.248.84.144; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_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 Precedence: list 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-ZM-MESSAGEID: 1764754680120019200 From: Marc-Andr=C3=A9 Lureau Since commit f626116f ("ui/vdagent: factor out clipboard peer registration"), the QEMU clipboard serial is reset whenever the vdagent chardev receives the guest caps. This triggers a CHR_EVENT_CLOSED which is handled by virtio_serial_close() to notify the guest. The "reconnection logic" is there to reset the agent when a client (dbus, spice etc) reconnects, or the agent is restarted. It is required to sync the clipboard serials and to prevent races or loops due to clipboard managers on both ends (but this is not implemented by windows vdagent). The Unix agent has been reconnecting without resending caps, thus working with this approach. However, the Windows agent does not seem to have a way to handle VIRTIO_CONSOLE_PORT_OPEN=3D0 event and do not receive further data... Let's not trigger this disconnection/reset logic if the agent does not support VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL. Fixes: f626116f ("ui/vdagent: factor out clipboard peer registration") Signed-off-by: Marc-Andr=C3=A9 Lureau Reported-by: Lucas Kornicki Tested-by: Fiona Ebner Reviewed-by: Fiona Ebner Tested-by: Lucas Kornicki (cherry picked from commit 4be62d311791bf9d318f5139439d170ad5112279) Signed-off-by: Michael Tokarev diff --git a/ui/vdagent.c b/ui/vdagent.c index c0746fe5b1..a7c959e8ab 100644 --- a/ui/vdagent.c +++ b/ui/vdagent.c @@ -316,6 +316,15 @@ static bool have_selection(VDAgentChardev *vd) return vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION); } =20 +static bool have_clipboard_serial(VDAgentChardev *vd) +{ +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) + return vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL); +#else + return false; +#endif +} + static uint32_t type_qemu_to_vdagent(enum QemuClipboardType type) { switch (type) { @@ -345,8 +354,7 @@ static void vdagent_send_clipboard_grab(VDAgentChardev = *vd, return; } =20 -#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) - if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) { + if (have_clipboard_serial(vd)) { if (!info->has_serial) { /* client should win */ info->serial =3D vd->last_serial[info->selection]++; @@ -356,7 +364,6 @@ static void vdagent_send_clipboard_grab(VDAgentChardev = *vd, data++; msg->size +=3D sizeof(uint32_t); } -#endif =20 for (q =3D 0; q < QEMU_CLIPBOARD_TYPE__COUNT; q++) { type =3D type_qemu_to_vdagent(q); @@ -464,6 +471,9 @@ static void vdagent_clipboard_reset_serial(VDAgentChard= ev *vd) { Chardev *chr =3D CHARDEV(vd); =20 + if (!have_clipboard_serial(vd)) { + return; + } /* reopen the agent connection to reset the serial state */ qemu_chr_be_event(chr, CHR_EVENT_CLOSED); /* OPENED again after the guest disconnected, see set_fe_open */ @@ -518,8 +528,7 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev = *vd, uint8_t s, uint32_t =20 trace_vdagent_cb_grab_selection(GET_NAME(sel_name, s)); info =3D qemu_clipboard_info_new(&vd->cbpeer, s); -#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) - if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) { + if (have_clipboard_serial(vd)) { if (size < sizeof(uint32_t)) { /* this shouldn't happen! */ return; @@ -537,7 +546,6 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev = *vd, uint8_t s, uint32_t data +=3D sizeof(uint32_t); size -=3D sizeof(uint32_t); } -#endif if (size > sizeof(uint32_t) * 10) { /* * spice has 6 types as of 2021. Limiting to 10 entries --=20 2.47.3