From nobody Sat May 30 15:31:02 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; arc=fail (Bad Signature); dmarc=pass(p=none dis=none) header.from=nutanix.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1779198857827783.1657447763056; Tue, 19 May 2026 06:54:17 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id E348141959; Tue, 19 May 2026 09:54:16 -0400 (EDT) Received: from [172.19.199.5] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id C44BA41AF7; Tue, 19 May 2026 09:50:39 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id E935541AA8; Tue, 19 May 2026 09:50:29 -0400 (EDT) Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id E07D641ABA for ; Tue, 19 May 2026 09:49:54 -0400 (EDT) Received: from pps.filterd (m0127844.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64JDKbxN2754741 for ; Tue, 19 May 2026 06:22:05 -0700 Received: from sn4pr0501cu005.outbound.protection.outlook.com (mail-southcentralusazon11021125.outbound.protection.outlook.com [40.93.194.125]) by mx0b-002c1b01.pphosted.com (PPS) with ESMTPS id 4e6r3xprsn-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT) for ; Tue, 19 May 2026 06:22:04 -0700 (PDT) Received: from DM5PR02MB3831.namprd02.prod.outlook.com (2603:10b6:4:b4::21) by CH3PR02MB9556.namprd02.prod.outlook.com (2603:10b6:610:121::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.25.21; Tue, 19 May 2026 13:22:03 +0000 Received: from DM5PR02MB3831.namprd02.prod.outlook.com ([fe80::b0ba:9ac1:4aed:805d]) by DM5PR02MB3831.namprd02.prod.outlook.com ([fe80::b0ba:9ac1:4aed:805d%6]) with mapi id 15.21.0025.022; Tue, 19 May 2026 13:22:01 +0000 X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; h= content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= proofpoint20171006; bh=3y9EovjX2JKbyqGbALo8vTNFAd6ZHt4czLk+6F6/v wo=; b=tYlifa7/P8KwGTowcgbrg/y82a/67a9Lt6cmm+WnP6sHZOy3/EJ2nxVRy C/JLbEHtUjwpdDKensCs39W8q5OrIj5egphv2rEjcQnYEt56rnDRhEz5VW28ZJdt 0CH2POsIqjaHWkguvI/OcrqtEnpKBi6/frkUoEZ9uwix60BkVYZj3z9S3x3XyqNm Rrui4lcqbdVBF/uqQE3GKBmI2YrzVZNafNn7joqco+6oWIev+ewkAjFxD68qzokf 78jpJLsWka5cqpiO4GQQdOOg6NlcgQd0eiqRAvDsZyviktmlxwiadeu/D7MAPUZC F7/ueagmBiT6Lhmy1linb2Ikn7zbQ== ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=J3HEnKuuW3rq01VnHFJZt+tRSrs9Sn0uJ42QOsa85MKk+6R/dGIeb/mJeK0VNOBmzKjiKMiK4ddJsYPEQlSCzqOdJjC4WG0Oea07NrLT/Jj3d8ZZh+gyjDPEmllW9fV82P1pClO22YlznI8PFMJtXnbsLW795+Z8yijfjn7FrwP3h7bri2G0KMNo+kBhw5eBk3HDHqpyX5vcWdZQ6IU8HCEte/NVULIlzrfxjKE/o7NIrNOUtVbRrrlGotEUaYyBvfaXgNJoecuSlORtQDnnWi3kUDg8nI+xa76q16tddr9DUebNhFDeylEMoQpOuIRQyxqNO/tluhCvLdmLUl/OvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3y9EovjX2JKbyqGbALo8vTNFAd6ZHt4czLk+6F6/vwo=; b=cMHrUV0Yx8KrnJ9G2tYuvr39+SF8sa0iOHkkvzqBfADE9szfvhC+sCB6uaHVaog2k9enZdncr49nwb1ERqJwI1/jYVkgQCx9odJ9j8voIMBPrA0Mw/fAU2l2bL71nd9BHEaQvtSUDYES8wfTJNRuGE4ofH3np+mqd2NBZwy9ePTLDx6ky3rmACw87x96EkzAC3G2S9LNn1Yfs/fWDgtksQUxgiDkPJvxT3bqDqOyUfD0msOpBXY7qHBxiICr4eKOpJ4N0zZ0Wu0IgEy+HBjGrrM1BVmExccOpqABrjyT6YIAYEx+fqgG3wKjmVbbYKhyjSzLH/oma61qd72sez8ErQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nutanix.com; dmarc=pass action=none header.from=nutanix.com; dkim=pass header.d=nutanix.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3y9EovjX2JKbyqGbALo8vTNFAd6ZHt4czLk+6F6/vwo=; b=XqP8bIbCF0walCq0i6RTgBb03mtsRZ+0S46pHcDyjCjMlEKo/KzHonf8MKZ9+JIAqwIClC+70plBEGNgL/9TbyDE4z2CcZzFXMNjCknDls+YcnS7KKxSuhghJVzh06XUgzWp3oINfIQMl9EY59CFr+am9F9+mUFubI9QBln75XJjksIeM4/uLk2VVTYqkdAsuGAGcNCLiK2qpYRDUQdSAZTcpHRxH9VHZTbH97hj5ohXaK0WY5VPqObPYk9qs7aRMuvqmvtzbvDSJBfmNh6woAaedU1GadgLUxvMa+Ay9j5lgkLqoAmz60aMoxQiv16wWNB1qrPIke2U1RyOKsxyGg== From: Lucas Kornicki To: devel@lists.libvirt.org Subject: [PATCH 1/2] conf,remote: add channel lifecycle domain event Date: Tue, 19 May 2026 15:11:35 +0200 Message-ID: <20260519131916.2241422-2-lucas.kornicki@nutanix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260519131916.2241422-1-lucas.kornicki@nutanix.com> References: <20260519131916.2241422-1-lucas.kornicki@nutanix.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR5P281CA0027.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f1::7) To DM5PR02MB3831.namprd02.prod.outlook.com (2603:10b6:4:b4::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM5PR02MB3831:EE_|CH3PR02MB9556:EE_ X-MS-Office365-Filtering-Correlation-Id: e2c7e53b-d2b5-407c-46ea-08deb5a99c26 x-proofpoint-crosstenant: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|376014|1800799024|56012099003|18002099003|3023799003|22082099003; X-Microsoft-Antispam-Message-Info: vqLXBLiF0FMvK+58lB/cpaadMCA5gK21Et2X3lHLKifkHit4I/5+zZ4Bxf6UJxT2FpEXti6ZmxqvFqguPyxDEpNfAsO6Z4CaSFoCZx9SPHUwigVyQK0PcI2bTplXMedhvyTmphZqOQfRvQ1pEMKqzRSNSTrnIHqccV29kJ6NCWilFDmILGR6+B4w73S3GMMS886PC7OaEZPKlxJ2QN0mngO3hHc1HNdzRDxZthx+AGBQnrFyljB1QtlTiBJ+FeCf4f3w8C9HYeu23h9IFkcjZ4h+qfBgq/ajETfxBRKXFwfp+gK0fwGNIo+L/ElmoaQi+BI3nAAQVBWZciIZhTuuqBUHuh/MOaHctCLjwJbnXRPBeg95gTrhBA/kQJ2XyOVEcTirFt7vJ4ynDdVnwKtC/HiAr4OTLIZUaaNHJ2GKK5t0ceG5H5Gt2FfW55noXJumL5B89NJVqhrbmlyVbfCq8C1WlIH9+VVVlVRDZTBa73GHxC/O5vKiCFgluTISw9RLXoEyoxsW1pGB5Q0F04xb5bPg00nchHocQfZzQ7cx1HwT+zxG4Fxdd5P9pESVsj6r7V5jzWPLoqbz75To/pujfSgWQurMRW1hcy/vrAExo7YnejFx8xYfwg3/8ec/MvX3DMKUaSpOzYEpiI9T/tl+0fKRYTh1RjgA4u34sUB+MbC9ZGv4RX7X97XZtNZF2OOv X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM5PR02MB3831.namprd02.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(56012099003)(18002099003)(3023799003)(22082099003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?gZXMIY4PmSMytEo0qPhgqvFaqT5LghYAWvTlHAogkK5VV6CWiIPbh6+3eJbc?= =?us-ascii?Q?DeI46dUko3AvfvefhyAg+nHksOQGWkfQd2Y9V0NP591ggPzG6fd7c4VWI4Tq?= =?us-ascii?Q?S86TBDvAlbEC6rMafnvC3shALFR0YnwRfNu2QAzN7QkJi/18sEUHcYfXlHi1?= =?us-ascii?Q?lCtUrO9dYhZrQWZgZiEaZzW0fk/laTQ/ZgDtiIQQCzRCIGpwxC0IftajibW3?= =?us-ascii?Q?h5IpjbF/6yCB1R8QlSSFyzoJgy2mTQcGXpBPCDSUqiuaPbcLm4SPXPtsJTMW?= =?us-ascii?Q?kRbjuds54SIbDUxybFkcn74DyrmFRzTpbAB7v374L4z/1/h4JAIyN+g6psAo?= =?us-ascii?Q?L+LDbxOzeJMCTSL15aHDRifc6ukteTb4qDNAmHpeieIeKS+2WdY+j4K6vVdT?= =?us-ascii?Q?Wnoa/O3cqL9CfiLwqbMh9cnk584/bHbS2O9oyeP5AFI/vmYdRJmvMWHpwTHm?= =?us-ascii?Q?zpjrdXr3AaJkWBsIq5VYB0f2co46ji3fhyMElSYe0I/XjIQFKhIyXRXXLKiV?= =?us-ascii?Q?ftpWj8TSX8RXoXSaxSKW6YAYSrafhAZIyG1ZUnm4FfV94cAGQ9OyNFiD57QN?= =?us-ascii?Q?1eT16Gs9/sHhmamj0h3p4ig6UHHebpYQ1AEa3pbCmQiD3PZJo/ce3NiCDFgk?= =?us-ascii?Q?uEjDab1xpK36CioYzZ7N9htbriu0LP95tp2Jc0GWwlp/MWt7MMXuVjS8PoKO?= =?us-ascii?Q?ftYPfKO9RaYJ0xbfiYg+Ig8FtYI+W8BtSMOq9VSj9z44smAzZs370JIo20nG?= =?us-ascii?Q?MQ/1iHdIoxpKyhQFInnBub2p5ZmYRg6g3Ih//7kSMnGmHPvjjl67TsAawHEo?= =?us-ascii?Q?7JKZDqfB59VEdIdX84/HTebHlZIhXWtcznK3u8Dxlp4CWikT96R4GTp6R1Ge?= =?us-ascii?Q?UmHCKLLHN5rxr8pLWxay3Xt0Mlxv49osYyGB/SyoBMvVCeJW9OTv+FW7zd97?= =?us-ascii?Q?35jUnLEtpU26ddasAFo6EonOQgfATVHvLnfMKTWIFsiryMfQKlRV4xx0aloo?= =?us-ascii?Q?i746r1JR+cqUm8uQ6w9nhLBjbbq7eYYD5iM4+WFn3bP0qYmfdR2ZeY80rw8G?= =?us-ascii?Q?W34lCnEApjIBcGFyuL+SzNVLkkiIUMSP26mOAxYLPHG6XEFE3e65QWZarSrV?= =?us-ascii?Q?YCrYLnXWk69Vz12upg8FqxCltk7B/gK/QAQn+PZnRDQwuGMKbHoQ2IQ4QDHD?= =?us-ascii?Q?LWnQK/ImIYavNDi4A/DnAX90BhWvjyMFVhNYhm7t3LRRhlf25OUhQJWwWiD9?= =?us-ascii?Q?8RgXfeTaI5kDwxE5AiVH4y/uJFvVUakoduqF41rEIQ2HMsCRtRf2ZNv+r0S8?= =?us-ascii?Q?5JMjxsOk2Feq0sC6mZ/T1/epcVnFQgf5ON7JS9rL0rWS/smPKKQ8dOi6kgqG?= =?us-ascii?Q?jzoxtYpSFjVaaoBpJ1bYSau2fe4M2DWKqbvE3CCk3d97plVbc7XTP2mVvAel?= =?us-ascii?Q?Tk+1ee1pzWkr3s52tYhoBdAXg9ovo+GzbyKBL46FeuKTMMOLQ/UZ0QlaN6Yz?= =?us-ascii?Q?fkineE9lDUrL5LgSJxoS2ZXZ+lISXAu+dAldPEKyWmueUxMWdre3SIEQN5Xj?= =?us-ascii?Q?XrB05m16APPVH+o7ooiiTK0LB40P65SVwQ/mJGlIyblmEGouOpgUOp2ubETy?= =?us-ascii?Q?N8eO/1yBMmGSgIw+FKZX+dINvWDmvZ7KfEA+nxaHAVP+KjvSs4b967ydhjvp?= =?us-ascii?Q?4aV45gDS6T2QPBh8N5lZIxlztGVLdVB3lnrsTcK4Pig1fn1XXazGTlfUIK1B?= =?us-ascii?Q?1DJaoKMaLCNMobYJEK5coVi3rJgXk0M=3D?= X-Exchange-RoutingPolicyChecked: vumVvEsRjA2ac9KtJ+hSmPuFNE+CvRDnMlY6zQwky6hyLRrL2GpJmfZZPAjQi7AMJwQrKFJaRT4NQ5I9YFf3hbyg7CRBUWvRxOFLnTgthqrJxWvQE+iah5I3tRMrqjyJ1Gw9O2HYUB4npLyZCsScHTsKrYlteMNKwhjz0nf4bXByo6WZ8bszb/jmQhaxFmXyGit+1GLTkdx7B66crWAl9YQSdDoMUi/dezb9DqnQrVcyiWKJ3tWx+hqtvkyjE3GOHiYTICQ5pA8Za//72y5jOC8DXut4sY9JTGeMxeFEYJY7gN6EntAvypBJf7C2bBPlmNGoE74ULCrPtgGKDgaFiw== X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: e2c7e53b-d2b5-407c-46ea-08deb5a99c26 X-MS-Exchange-CrossTenant-AuthSource: DM5PR02MB3831.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 May 2026 13:22:01.1446 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: nS4HEwrJ4dm6jDa9S/saTHKxCLgYgvPLxuC2LLwHRkgv8I1LPgCYCyAaCWf8JqfnXIH2ocZJSMpw8lCevhgS6DACVQtIGeYnxtE+bWeHzYo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR02MB9556 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTE5MDEzMiBTYWx0ZWRfX0mYsWDyf1Jaw xH2LvhwEyf/vnhMIKe9mTFydWHdLPD8dTefBdbsCMxOeaI48a1g0SK26W7VYGmJAlybrNs7jg+M jcuPWbMJqG3k4OHAfWeQPTQ9SXhqrczKHcGiEydEpD2Bf3etknpKZUn3QsKJnKMw9m5F9qxFXaT f9MCZUQnQdMJuv67gANe+yHz1aqyojPT9f0w2jk6+pq2znUMm6kObs/0U8/bmDFQ4GuYdCf3AaE sfxDBp6yZ+zT5yppUz9nd/Gn8HAogUETzSzHBT+KX3c4kKbf0ncYyC2ZDHdZuRqKKOth6IhcAhB 2TF3/zPij3cpfqq/V7wgsiE8csaO3nAu1xJMybzJxMSMpBv6cQD3I9wNjKsTd0SEBLCilpnfJwg lavO7iP0k9guysSGha0JIVTy5XHFoqbgnJPeyHJ6UkzeueNBb+NJTSZg5mLMpIHPJ91ztG4Bg9m 7WOAxpHKq8rW8SAHPzg== X-Proofpoint-GUID: VL0mxO1OYAm3o0TcRVlQqv_OUCdFI2du X-Proofpoint-ORIG-GUID: VL0mxO1OYAm3o0TcRVlQqv_OUCdFI2du X-Authority-Analysis: v=2.4 cv=Wsgb99fv c=1 sm=1 tr=0 ts=6a0c63fd cx=c_pps a=zgxwnwFdFZm2O07vxbsARg==:117 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=lCpzRmAYbLLaTzLvsPZ7Mbvzbb8=:19 a=xqWC_Br6kY4A:10 a=NGcC8JguVDcA:10 a=0kUYKlekyDsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VofLwUrZ8Iiv6rRUPXIb:22 a=0LlEyIVc8U2lsR7dKhuH:22 a=64Cc0HZtAAAA:8 a=pJHdOpIVuuRciE8XwL4A:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-19_03,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Reason: safe Message-ID-Hash: 7IAFMSLILJO3RXX6H3MTR5HBCIZB3DSS X-Message-ID-Hash: 7IAFMSLILJO3RXX6H3MTR5HBCIZB3DSS X-MailFrom: lucas.kornicki@nutanix.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @nutanix.com) X-ZM-MESSAGEID: 1779198860421154100 Content-Type: text/plain; charset="utf-8" Add support for a new domain event which can be used to track the state of any virtio channel. Previously one could only monitor the "org.qemu.guest_agent.0" channel which had a dedicated agent lifecycle event. The channel lifecycle event will be emitted alongside the agent specific one. Signed-off-by: Lucas Kornicki Reviewed-by: Michal Privoznik --- examples/c/misc/event-test.c | 57 +++++++++++++++++ include/libvirt/libvirt-domain.h | 65 +++++++++++++++++++ src/conf/domain_event.c | 97 +++++++++++++++++++++++++++++ src/conf/domain_event.h | 12 ++++ src/libvirt_private.syms | 2 + src/remote/remote_daemon_dispatch.c | 34 ++++++++++ src/remote/remote_driver.c | 34 ++++++++++ src/remote/remote_protocol.x | 16 ++++- src/remote_protocol-structs | 8 +++ tools/virsh-domain-event.c | 35 +++++++++++ 10 files changed, 359 insertions(+), 1 deletion(-) diff --git a/examples/c/misc/event-test.c b/examples/c/misc/event-test.c index f9e65c55f0..601f5eafcf 100644 --- a/examples/c/misc/event-test.c +++ b/examples/c/misc/event-test.c @@ -353,6 +353,45 @@ guestAgentLifecycleEventReasonToString(int event) return "unknown"; } =20 + +static const char * +guestChannelLifecycleEventStateToString(int event) +{ + switch ((virConnectDomainEventChannelLifecycleState) event) { + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_DISCONNECTED: + return "Disconnected"; + + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_CONNECTED: + return "Connected"; + + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_LAST: + break; + } + + return "unknown"; +} + + +static const char * +guestChannelLifecycleEventReasonToString(int event) +{ + switch ((virConnectDomainEventChannelLifecycleReason) event) { + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_UNKNOWN: + return "Unknown"; + + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_DOMAIN_STARTED: + return "Domain started"; + + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_CHANNEL: + return "Channel event"; + + case VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_LAST: + break; + } + + return "unknown"; +} + static const char * storagePoolEventToString(int event) { @@ -869,6 +908,23 @@ myDomainEventAgentLifecycleCallback(virConnectPtr conn= G_GNUC_UNUSED, } =20 =20 +static int +myDomainEventChannelLifecycleCallback(virConnectPtr conn G_GNUC_UNUSED, + virDomainPtr dom, + const char *channelName, + int state, + int reason, + void *opaque G_GNUC_UNUSED) +{ + printf("%s EVENT: Domain %s(%d) guest channel(%s) state changed: %s re= ason: %s\n", + __func__, virDomainGetName(dom), virDomainGetID(dom), channelNa= me, + guestChannelLifecycleEventStateToString(state), + guestChannelLifecycleEventReasonToString(reason)); + + return 0; +} + + static int myDomainEventDeviceAddedCallback(virConnectPtr conn G_GNUC_UNUSED, virDomainPtr dom, @@ -1195,6 +1251,7 @@ struct domainEventData domainEvents[] =3D { DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_MEMORY_DEVICE_SIZE_CHANGE, myDomainEv= entMemoryDeviceSizeChangeCallback), DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE, myDomainEventNICMACCh= angeCallback), DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_VCPU_REMOVED, myDomainEventVcpuRemove= dCallback), + DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE, myDomainEventChann= elLifecycleCallback), }; =20 struct storagePoolEventData { diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index 1066a0b3f1..abc3be0252 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -7673,6 +7673,70 @@ typedef void (*virConnectDomainEventNICMACChangeCall= back)(virConnectPtr conn, const char *newM= AC, void *opaque); =20 + +/** + * virConnectDomainEventChannelLifecycleState: + * + * Since: 12.4.0 + */ +typedef enum { + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_CONNECTED =3D 1, /* c= hannel connected (Since: 12.4.0) */ + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_DISCONNECTED =3D 2, /= * channel disconnected (Since: 12.4.0) */ + +# ifdef VIR_ENUM_SENTINELS + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_LAST /* (Since: 12.4.= 0) */ +# endif +} virConnectDomainEventChannelLifecycleState; + +/** + * virConnectDomainEventChannelLifecycleReason: + * + * The reason values are intentionally numerically aligned with + * virConnectDomainEventAgentLifecycleReason so that the qemu driver + * can pass the same int through both events. + * + * Since: 12.4.0 + */ +typedef enum { + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_UNKNOWN =3D 0, /* un= known state change reason (Since: 12.4.0) */ + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_DOMAIN_STARTED =3D 1= , /* state changed due to domain start (Since: 12.4.0) */ + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_CHANNEL =3D 2, /* ch= annel state changed (Since: 12.4.0) */ + +# ifdef VIR_ENUM_SENTINELS + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_LAST /* (Since: 12.4= .0) */ +# endif +} virConnectDomainEventChannelLifecycleReason; + +/** + * virConnectDomainEventChannelLifecycleCallback: + * @conn: connection object + * @dom: domain on which the event occurred + * @channelName: the name of the channel on which the event occurred + * @state: new state of the guest channel, one of virConnectDomainEventCha= nnelLifecycleState + * @reason: reason for state change, one of virConnectDomainEventChannelLi= fecycleReason + * @opaque: application specified data + * + * This callback occurs when libvirt detects a change in the state of a gu= est + * virtio-serial channel. Unlike VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE which= is + * tied to the QEMU guest agent channel ("org.qemu.guest_agent.0"), this e= vent + * is emitted for every virtio-serial channel attached to the domain, + * including the guest agent channel. + * + * The hypervisor must support virtio-serial port state notifications for = the + * event to be delivered. + * + * The callback signature to use when registering for an event of type + * VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE with virConnectDomainEventRegiste= rAny() + * + * Since: 12.4.0 + */ +typedef void (*virConnectDomainEventChannelLifecycleCallback)(virConnectPt= r conn, + virDomainPtr= dom, + const char *= channelName, + int state, + int reason, + void *opaque= ); + /** * VIR_DOMAIN_EVENT_CALLBACK: * @@ -7723,6 +7787,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_MEMORY_DEVICE_SIZE_CHANGE =3D 26, /* virConnectDom= ainEventMemoryDeviceSizeChangeCallback (Since: 7.9.0) */ VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE =3D 27, /* virConnectDomainEventNIC= MACChangeCallback (Since: 11.2.0) */ VIR_DOMAIN_EVENT_ID_VCPU_REMOVED =3D 28, /* virConnectDomainEventVcpuR= emovedCallback (Since: 12.4.0) */ + VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE =3D 29, /* virConnectDomainEvent= ChannelLifecycleCallback (Since: 12.4.0) */ =20 # ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_ID_LAST diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index f09c6a9816..e44dae7922 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -59,6 +59,7 @@ static virClass *virDomainEventBlockThresholdClass; static virClass *virDomainEventMemoryFailureClass; static virClass *virDomainEventMemoryDeviceSizeChangeClass; static virClass *virDomainEventNICMACChangeClass; +static virClass *virDomainEventChannelLifecycleClass; =20 static void virDomainEventDispose(void *obj); static void virDomainEventLifecycleDispose(void *obj); @@ -85,6 +86,7 @@ static void virDomainEventBlockThresholdDispose(void *obj= ); static void virDomainEventMemoryFailureDispose(void *obj); static void virDomainEventMemoryDeviceSizeChangeDispose(void *obj); static void virDomainEventNICMACChangeDispose(void *obj); +static void virDomainEventChannelLifecycleDispose(void *obj); =20 static void virDomainEventDispatchDefaultFunc(virConnectPtr conn, @@ -305,6 +307,23 @@ struct _virDomainEventNICMACChange { }; typedef struct _virDomainEventNICMACChange virDomainEventNICMACChange; =20 +struct _virDomainEventChannelLifecycle { + virDomainEvent parent; + + char *channelName; + int state; + int reason; +}; +typedef struct _virDomainEventChannelLifecycle virDomainEventChannelLifecy= cle; + +/* Make sure the AGENT and CHANNEL lifecycle enums stay in sync with each = other. */ +G_STATIC_ASSERT((int)VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAI= N_STARTED =3D=3D + (int)VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_DOM= AIN_STARTED); +G_STATIC_ASSERT((int)VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANN= EL =3D=3D + (int)VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_CHA= NNEL); +G_STATIC_ASSERT((int)VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST = =3D=3D + (int)VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_LAS= T); + static int virDomainEventsOnceInit(void) { @@ -358,6 +377,8 @@ virDomainEventsOnceInit(void) return -1; if (!VIR_CLASS_NEW(virDomainEventNICMACChange, virDomainEventClass)) return -1; + if (!VIR_CLASS_NEW(virDomainEventChannelLifecycle, virDomainEventClass= )) + return -1; return 0; } =20 @@ -600,6 +621,14 @@ virDomainEventNICMACChangeDispose(void *obj) g_free(event->newMAC); } =20 +static void +virDomainEventChannelLifecycleDispose(void *obj) +{ + virDomainEventChannelLifecycle *event =3D obj; + + g_free(event->channelName); +} + static void * virDomainEventNew(virClass *klass, int eventID, @@ -1867,6 +1896,61 @@ virDomainEventNICMACChangeNewFromDom(virDomainPtr do= m, =20 } =20 + +static virObjectEvent * +virDomainEventChannelLifecycleNew(int id, + const char *name, + const unsigned char *uuid, + const char *channelName, + int state, + int reason) +{ + virDomainEventChannelLifecycle *ev; + + if (virDomainEventsInitialize() < 0) + return NULL; + + if (!(ev =3D virDomainEventNew(virDomainEventChannelLifecycleClass, + VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE, + id, name, uuid))) + return NULL; + + ev->channelName =3D g_strdup(channelName); + ev->state =3D state; + ev->reason =3D reason; + + return (virObjectEvent *)ev; +} + + +virObjectEvent * +virDomainEventChannelLifecycleNewFromObj(virDomainObj *obj, + const char *channelName, + int state, + int reason) +{ + return virDomainEventChannelLifecycleNew(obj->def->id, + obj->def->name, + obj->def->uuid, + channelName, + state, + reason); +} + +virObjectEvent * +virDomainEventChannelLifecycleNewFromDom(virDomainPtr dom, + const char *channelName, + int state, + int reason) +{ + return virDomainEventChannelLifecycleNew(dom->id, + dom->name, + dom->uuid, + channelName, + state, + reason); +} + static void virDomainEventDispatchDefaultFunc(virConnectPtr conn, virObjectEvent *event, @@ -2200,6 +2284,19 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, goto cleanup; } =20 + case VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE: + { + virDomainEventChannelLifecycle *channelLifecycleEvent; + + channelLifecycleEvent =3D (virDomainEventChannelLifecycle *)ev= ent; + ((virConnectDomainEventChannelLifecycleCallback)cb)(conn, dom, + channelLif= ecycleEvent->channelName, + channelLif= ecycleEvent->state, + channelLif= ecycleEvent->reason, + cbopaque); + goto cleanup; + } + case VIR_DOMAIN_EVENT_ID_LAST: break; } diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h index 930b66b13a..4678bec385 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -295,6 +295,18 @@ virDomainEventNICMACChangeNewFromDom(virDomainPtr dom, const char *oldMAC, const char *newMAC); =20 +virObjectEvent * +virDomainEventChannelLifecycleNewFromObj(virDomainObj *obj, + const char *channelName, + int state, + int reason); + +virObjectEvent * +virDomainEventChannelLifecycleNewFromDom(virDomainPtr dom, + const char *channelName, + int state, + int reason); + int virDomainEventStateRegister(virConnectPtr conn, virObjectEventState *state, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7232b7c663..a76da45fb9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -761,6 +761,8 @@ virDomainEventBlockJobNewFromDom; virDomainEventBlockJobNewFromObj; virDomainEventBlockThresholdNewFromDom; virDomainEventBlockThresholdNewFromObj; +virDomainEventChannelLifecycleNewFromDom; +virDomainEventChannelLifecycleNewFromObj; virDomainEventControlErrorNewFromDom; virDomainEventControlErrorNewFromObj; virDomainEventDeviceAddedNewFromDom; diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index 55a1bd2af8..329853b6da 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -1379,6 +1379,39 @@ remoteRelayDomainEventNICMACChange(virConnectPtr con= n, } =20 =20 +static int +remoteRelayDomainEventChannelLifecycle(virConnectPtr conn, + virDomainPtr dom, + const char *channelName, + int state, + int reason, + void *opaque) +{ + daemonClientEventCallback *callback =3D opaque; + remote_domain_event_callback_channel_lifecycle_msg data =3D { 0 }; + + if (callback->callbackID < 0 || + !remoteRelayDomainEventCheckACL(callback->client, conn, dom)) + return -1; + + VIR_DEBUG("Relaying domain channel lifecycle event %s %d, callback %d,= " + "name %s, state %d, reason %d", + dom->name, dom->id, callback->callbackID, channelName, state= , reason); + + data.callbackID =3D callback->callbackID; + make_nonnull_domain(&data.dom, dom); + data.channelName =3D g_strdup(channelName); + data.state =3D state; + data.reason =3D reason; + + remoteDispatchObjectEventSend(callback->client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CHANNE= L_LIFECYCLE, + (xdrproc_t)xdr_remote_domain_event_callb= ack_channel_lifecycle_msg, + &data); + return 0; +} + + static virConnectDomainEventGenericCallback domainEventCallbacks[] =3D { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -1409,6 +1442,7 @@ static virConnectDomainEventGenericCallback domainEve= ntCallbacks[] =3D { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMemoryDeviceSizeChange= ), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventNICMACChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventVcpuRemoved), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventChannelLifecycle), }; =20 G_STATIC_ASSERT(G_N_ELEMENTS(domainEventCallbacks) =3D=3D VIR_DOMAIN_EVENT= _ID_LAST); diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index e83b0abcbe..873e3d173c 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -441,6 +441,11 @@ remoteDomainBuildEventNICMACChange(virNetClientProgram= *prog, virNetClient *client, void *evdata, void *opaque); =20 +static void +remoteDomainBuildEventCallbackChannelLifecycle(virNetClientProgram *prog, + virNetClient *client, + void *evdata, void *opaque); + static virNetClientProgramEvent remoteEvents[] =3D { { REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE, remoteDomainBuildEventLifecycle, @@ -667,6 +672,10 @@ static virNetClientProgramEvent remoteEvents[] =3D { remoteDomainBuildEventVcpuRemoved, sizeof(remote_domain_event_vcpu_removed_msg), (xdrproc_t)xdr_remote_domain_event_vcpu_removed_msg }, + { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CHANNEL_LIFECYCLE, + remoteDomainBuildEventCallbackChannelLifecycle, + sizeof(remote_domain_event_callback_channel_lifecycle_msg), + (xdrproc_t)xdr_remote_domain_event_callback_channel_lifecycle_msg }, }; =20 static void @@ -5192,6 +5201,31 @@ remoteDomainBuildEventNICMACChange(virNetClientProgr= am *prog G_GNUC_UNUSED, } =20 =20 +static void +remoteDomainBuildEventCallbackChannelLifecycle(virNetClientProgram *prog G= _GNUC_UNUSED, + virNetClient *client G_GNUC= _UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn =3D opaque; + remote_domain_event_callback_channel_lifecycle_msg *msg =3D evdata; + struct private_data *priv =3D conn->privateData; + virDomainPtr dom; + virObjectEvent *event =3D NULL; + + if (!(dom =3D get_nonnull_domain(conn, msg->dom))) + return; + + event =3D virDomainEventChannelLifecycleNewFromDom(dom, + msg->channelName, + msg->state, + msg->reason); + + virObjectUnref(dom); + + virObjectEventStateQueueRemote(priv->eventState, event, msg->callbackI= D); +} + + static int remoteStreamSend(virStreamPtr st, const char *data, diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 23699e99a6..4adba82f6d 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -4015,6 +4015,14 @@ struct remote_domain_event_nic_mac_change_msg { remote_nonnull_string newMAC; }; =20 +struct remote_domain_event_callback_channel_lifecycle_msg { + int callbackID; + remote_nonnull_domain dom; + remote_nonnull_string channelName; + int state; + int reason; +}; + /*----- Protocol. -----*/ =20 /* Define the program number, protocol version and procedure numbers here.= */ @@ -7132,5 +7140,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED =3D 454 + REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED =3D 454, + + /** + * @generate: both + * @acl: none + */ + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CHANNEL_LIFECYCLE =3D 455 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 4c24245d2b..dd297bffff 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3342,6 +3342,13 @@ struct remote_domain_event_nic_mac_change_msg { remote_nonnull_string oldMAC; remote_nonnull_string newMAC; }; +struct remote_domain_event_callback_channel_lifecycle_msg { + int callbackID; + remote_nonnull_domain dom; + remote_nonnull_string channelName; + int state; + int reason; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN =3D 1, REMOTE_PROC_CONNECT_CLOSE =3D 2, @@ -3797,4 +3804,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_DEL_THROTTLE_GROUP =3D 452, REMOTE_PROC_DOMAIN_EVENT_NIC_MAC_CHANGE =3D 453, REMOTE_PROC_DOMAIN_EVENT_VCPU_REMOVED =3D 454, + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CHANNEL_LIFECYCLE =3D 455, }; diff --git a/tools/virsh-domain-event.c b/tools/virsh-domain-event.c index 4a9a831b45..a541b155f4 100644 --- a/tools/virsh-domain-event.c +++ b/tools/virsh-domain-event.c @@ -655,6 +655,39 @@ virshEventAgentLifecyclePrint(virConnectPtr conn G_GNU= C_UNUSED, virshEventPrint(opaque, &buf); } =20 +VIR_ENUM_DECL(virshEventChannelLifecycleState); +VIR_ENUM_IMPL(virshEventChannelLifecycleState, + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_LAST, + N_("unknown"), + N_("connected"), + N_("disconnected")); + +VIR_ENUM_DECL(virshEventChannelLifecycleReason); +VIR_ENUM_IMPL(virshEventChannelLifecycleReason, + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_LAST, + N_("unknown"), + N_("domain started"), + N_("channel event")); + +static void +virshEventChannelLifecyclePrint(virConnectPtr conn G_GNUC_UNUSED, + virDomainPtr dom, + const char *channelName, + int state, + int reason, + void *opaque) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&buf, + _("event 'channel-lifecycle' for domain '%1$s': chan= nel name: '%2$s' state: '%3$s' reason: '%4$s'\n"), + virDomainGetName(dom), + channelName, + UNKNOWNSTR(virshEventChannelLifecycleStateTypeToStri= ng(state)), + UNKNOWNSTR(virshEventChannelLifecycleReasonTypeToStr= ing(reason))); + virshEventPrint(opaque, &buf); +} + static void virshEventMigrationIterationPrint(virConnectPtr conn G_GNUC_UNUSED, virDomainPtr dom, @@ -889,6 +922,8 @@ virshDomainEventCallback virshDomainEventCallbacks[] = =3D { VIR_DOMAIN_EVENT_CALLBACK(virshEventNICMACChangePrint), }, { "vcpu-removed", VIR_DOMAIN_EVENT_CALLBACK(virshEventVcpuRemovedPrint), }, + { "channel-lifecycle", + VIR_DOMAIN_EVENT_CALLBACK(virshEventChannelLifecyclePrint), }, }; G_STATIC_ASSERT(VIR_DOMAIN_EVENT_ID_LAST =3D=3D G_N_ELEMENTS(virshDomainEv= entCallbacks)); =20 --=20 2.43.0 From nobody Sat May 30 15:31:02 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; arc=fail (Bad Signature); dmarc=pass(p=none dis=none) header.from=nutanix.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1779198677081714.4238278545229; Tue, 19 May 2026 06:51:17 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id DC8C941A09; Tue, 19 May 2026 09:51:15 -0400 (EDT) Received: from [172.19.199.5] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id DC1924196B; Tue, 19 May 2026 09:49:56 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 81932418EC; Tue, 19 May 2026 09:49:46 -0400 (EDT) Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 2B7643F83F for ; Tue, 19 May 2026 09:49:44 -0400 (EDT) Received: from pps.filterd (m0127842.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64JD2EhI1003204 for ; Tue, 19 May 2026 06:22:09 -0700 Received: from sn4pr0501cu005.outbound.protection.outlook.com (mail-southcentralusazon11021131.outbound.protection.outlook.com [40.93.194.131]) by mx0b-002c1b01.pphosted.com (PPS) with ESMTPS id 4e7sekcujr-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT) for ; Tue, 19 May 2026 06:22:09 -0700 (PDT) Received: from DM5PR02MB3831.namprd02.prod.outlook.com (2603:10b6:4:b4::21) by CH3PR02MB9556.namprd02.prod.outlook.com (2603:10b6:610:121::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.25.21; Tue, 19 May 2026 13:22:08 +0000 Received: from DM5PR02MB3831.namprd02.prod.outlook.com ([fe80::b0ba:9ac1:4aed:805d]) by DM5PR02MB3831.namprd02.prod.outlook.com ([fe80::b0ba:9ac1:4aed:805d%6]) with mapi id 15.21.0025.022; Tue, 19 May 2026 13:22:08 +0000 X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 1659 seconds by postgrey-1.37 at lists.libvirt.org; Tue, 19 May 2026 09:49:44 EDT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; h= content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s= proofpoint20171006; bh=mK7vGzEBUjiALBcEbGNhK4N3h0aHSyx9ZdfKvB759 Mw=; b=Y6vs6EYZWh5Dtp8lLoLcYeaXUKhYJ23xdAo0WMaqGPZE3wvV6drDS9Z80 oH8preZNV9hrW3mGBnZAhsVlS91bNNGVC1Nnp2EyYDqCCT0c4KWJ8EIVID5R5VUh zx1IOZr8+B40mMgMTEYQ9qVJax3pVFZ5aw03s5rxZT/4Ga3Z9NRlKqUS1su5ag1T MhvIEC8A2dkuC9oX2/ZvWcB24ihmXPp3feLgQUtHa7MdDHMTAPV04Ke0NUcs0pjU 9bHZHOC7aMW4lshFCC/lXhYkuvWuC9uNEaNI8pseGjScYjIDyxo1XMXCK/FkAWXN HG9PINGMzE7c2h/x13ooZZHswYRHg== ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OeQ7CENsjp4LkKzlHRCbTTtt1xIfEtSho0qEz3P+SQtxn/eckmxXIzWGjYg3+uJG3fxqGiTxeIYMpIifU76fgem8IPABp1f/P8HIkV3DmAgtdBqi8eSA2aFtyoa+dRq45/DmPXmIUBY/AlHZUM+pu02BHlR1sWinSnrJaCkvyyfS9VFw8Ga4GCLCw5KcOmLu0H0s7REYuZG5qVBJF1gN4hCEGZdpr/2sExqpa4XcFCO7+YkXZOYMGiCfG6sc3K/rd8E0TOBL+x3EhGVtOWQzo3tqiTPfBKN3u4qfXRIlkQzKski/iuVxZYcQAw4zX+ZHV29+VEFOLgQAF3/LK7IFmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mK7vGzEBUjiALBcEbGNhK4N3h0aHSyx9ZdfKvB759Mw=; b=FEJ6AhTR+hPbj92MYjwogL5zTM4a0F/asZ5On0K4+KycuFXSClfePJG1mwAOErMd2wkh947M1UzU6adzHNt+VYuXTIdWcpWg3wSLdFQNoUGwMdlJ3SJi7Hkn4P4zcFTi07Q1cvih06ZsZ5s/4+VvRtPMa9ZYIRV5J0DA+e5YU4wewcYE2LYCM1x6zsM1KdrtvJ3ZO+bFafeuH0mnFSZ07ftUVz8onAC7bVBSZ5s0eQJYLB0bE/MJgB438wsLMJqZKtu2iLtKBOU2V9Bicw9j/FxXzffjrV2QpjwAdgH89+fnYfNZmkzgODzAn7Qg2/cGzArSI7OIsL74VqoQvMaavw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nutanix.com; dmarc=pass action=none header.from=nutanix.com; dkim=pass header.d=nutanix.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mK7vGzEBUjiALBcEbGNhK4N3h0aHSyx9ZdfKvB759Mw=; b=AoOErrAXh8FWUmHGry2XlmvMIeFMlken40Z6VHGuCGNSCXkZaaMcyn9v9UgPyaaclp2wHPXzMQFqNARdolYzOKySIxITeICGccpLqd4bCH34x19+FbnnvpQkfEI2pbfdbUAUsd6MLBTBd8sjxAPmn2ZiEspv+/DqhE3qnoqFriQ88HhJsS2T7nEFEkeNMEnh2uQga4gSmzRK5qAUfZwjg4aOrG88zoWfn6EUdAMmnX2U+CneOUCK/2fQjSsbgNVByEBHG2OOct3FqP1yj/DeTInzrDS4Cvg0fKmvfewJkHze5FibNhdV6Jx+3csTTzG4clstsTELjVFNcaXJv2nONg== From: Lucas Kornicki To: devel@lists.libvirt.org Subject: [PATCH 2/2] qemu: emit channel lifecycle event Date: Tue, 19 May 2026 15:11:36 +0200 Message-ID: <20260519131916.2241422-3-lucas.kornicki@nutanix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260519131916.2241422-1-lucas.kornicki@nutanix.com> References: <20260519131916.2241422-1-lucas.kornicki@nutanix.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: FR3P281CA0151.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a2::12) To DM5PR02MB3831.namprd02.prod.outlook.com (2603:10b6:4:b4::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM5PR02MB3831:EE_|CH3PR02MB9556:EE_ X-MS-Office365-Filtering-Correlation-Id: e55f3933-a688-433d-18ec-08deb5a9a065 x-proofpoint-crosstenant: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|376014|1800799024|56012099003|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: tZXbPomgePwVI5RluiiZSyn7dYd/M7chG5Xshzy9RWyeFVaBHgf8ZIgHdOJtv247rvhtsvEgqJ5mX59NQ4ahducZan0KUmRxs8puHJ3bcDajwOgxnnGZQJBawXlxJbLJ4/J+gNicgoxffkFUEhBI9+6E1V8vZXIgdcQeqYSk3C2Norf2kDUVmKM8Z2zomi7xfJqcU9vNJHpmYcw2VFUENNAR4jt62UZ5+Ts6U7OCfYLmS6FAVxsaKNUpC9mbpjAkDg3Fv0ehkSbMzneFaPemjbnxHX4NAUSU2Z5GQNOwX29rD34B8lOqpJPv/YRN+gt1Oa+0vJmglUg7c7ynFjS5sFJcKMQOv8uLAL1czbtd1sVJhzpk2Fds8os12cLHwzE2S4qhG7NyryyAOo9X4vo0WVkhzBXptSuYdgXdmgG4DvFk8X3aK+0aYitQ5+mMC0xOX0On205MjCT1HbM0qKIaLIPBdi8dxJcrEyxGR5+5STk7s3xiaBkucH6f2u+UIVgL+aMyhbayALkkrN53N1in/drVEQl02SPv7n7EzmAHjWyVAkAypl/mV/GM8Dda5S0vkee9hsOXxlNDcdHPoHot1p0qpBE6ljOdr/yXwFTdXyjoVPSDbDEcgcmmAxWBzSqVlorM+NkTTxMyb4amIEGrwlrjDMrsJVLsk4yyAQdH7Rdyn2stD/0Yp0qZoFVYK/OF X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM5PR02MB3831.namprd02.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(56012099003)(18002099003)(22082099003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?YmbRTi8mcnEEzSJBZl30boIrlUVf6Us+zcNXIwlD+Z6uV0XYy8jbAuCgtNY3?= =?us-ascii?Q?bu3hC2UGLb6BNFFRxlWoFDvgkkYQV1CFc3Uok83napYxfW5yiJMEjQ2QPXb4?= =?us-ascii?Q?TK7vqNo5cqw1bI+DJhhZeMJeymDyl813Wrhh9k2lKshKvpN5J/paWV9lHn+l?= =?us-ascii?Q?aupCFoToO7AuiLxaDP6m/MgS6l2Wv7r42pc+zgcWI4zMdDLX1tm6/967YV8S?= =?us-ascii?Q?/bL8scIYy85RlLHR5jxVOe5Km0lfXTYl0TBEBUs0W44hRUWCEcZ+pTQm5rlY?= =?us-ascii?Q?otZCi9/kX6tY6/B5v8rmZ6S5phQ+ijhToCpySr2HthP+4DHyDZBJKTWkmLij?= =?us-ascii?Q?WNx4EITYPYZkib9GqygY6z167dWz0uhYYF/l4QM5R9CslEzkO31wXaS/a5py?= =?us-ascii?Q?R8biIGAm//6J3pP+b1I15HpMGeW23P8sMX9HeVOQOezuv32PB7w2aat/HoHT?= =?us-ascii?Q?dUjcIiNt6wSrYS+upFWJfUVWCbeyFitNamcDwkvgCnfFzeVkoIYd5OjLw3p1?= =?us-ascii?Q?OgtoEDRvr9Gonwyd4eh7HuYYNRNyF8Y3GcOMu+c+2GQ16hlFDO8EHWa36Xh0?= =?us-ascii?Q?f/A7gPHbIbFcYyaO/N3cFRCa8W0d7T5pr9vowdIAgcdedKEskh1tNXcUHuV9?= =?us-ascii?Q?vCok5MUTQQCLvF/+PepqAwN4KkujjirigYcSiJ0K2iCO06ZKSJ7QhESFOdEb?= =?us-ascii?Q?/ezvsZOuponojVKuMXEPIPfVhVnLNFzc3Ar4xySw16znve3c3sTsZxog6aXJ?= =?us-ascii?Q?6ujNpc8q6NigWyIwbX8DzEPy46FLrfrpAeHrwVlWV95M/oaI1gkxVR8shk9v?= =?us-ascii?Q?r3k2o0YLEuF02KnhZPRKSeAs0riu/smTg2jrsfzfjMENeckKIALlwnObDLs+?= =?us-ascii?Q?jW4+2JpjSpMunLH6VxmSYQ9g62Mtb37lTgO2VfezRPfieND31Wxmv/q4Dpvf?= =?us-ascii?Q?dLVsQ8MwIMVq3nEGVw7MCGGWJNHsuD1KBJMVbg+Ty+yKKcUgJFH+7oNvpMG6?= =?us-ascii?Q?iInxdHr0qR65BfaSnm8F+yE6OhcVtrBmzMhB+dEt/4yJKY2zpEnPBc8PEBOf?= =?us-ascii?Q?Vfyoj35k+S+mkxDz6NcWeyt+xZ+0Rl68qCr84h2kTZKAbhJX4RU0/nYAYzWT?= =?us-ascii?Q?P4IfWN/qXOsmghzwMiyPIB5p8OKBIQ83R2hQqUsenZiU0f9bOvpSUCStV5Xw?= =?us-ascii?Q?I2Ei1Grs+sxJdXaZ4+KsWSNs1sHnjv0c1CEfr7139ZvSSxZCxOuogPzHujH8?= =?us-ascii?Q?UYSorpXH5w6H5OeL9DiDc6sh07obQYm2V/E4JW7D23EK2SWloh+65vxJxe6y?= =?us-ascii?Q?qo3IxTrznWDwNdsGcmW4IBM6t4bQBDBR64ZBbNBCPWOZUWyakF0VPlyHGUNX?= =?us-ascii?Q?UqpnWgnF/7pqXFt1phy1o+69tP4f08oTqpwD+wvEJ0A2mwQia0eeUmvMcQgo?= =?us-ascii?Q?Rp8RQprmL1VIU/oan24x5DTCgZkjx5sDOXKgvFM5aRjjlb9dPRZABRU9Oo6c?= =?us-ascii?Q?e3GLhs4aOIOmXuhOG87kBTvcbwZn91rsN6DG7u+MmPcgynARpzI1OJ3qpF1D?= =?us-ascii?Q?07AL/mRYeWv5uuVwP7HnPPVF5cg7x+IaGeJ5ZnzCR+7ZwKLGc1YYnfY7A/89?= =?us-ascii?Q?B2oP9C3oh8jdxMNyUnkXwI1cptXEFnK5SLjvOiCfQCQZrr0kCNEEBiyuyPb4?= =?us-ascii?Q?4PwPWHuI9bJ7jxiqyPlrmLfIsMtsyHcG+wbMXza0UbNgy22TdAvhSztcg6i2?= =?us-ascii?Q?W3ujxLLXdIT1DEat8atvMVdfOl1qNY4=3D?= X-Exchange-RoutingPolicyChecked: WaythCBRMIMPKscUHQTzk5LGODjkQByYN0aRCaYIUQnGZG6/zZUUv4l+IKVcFk/+wdGRqoVeX+wCF8jH+gx9sQlfiSxhla8/hwdpNlZ/MwwIO3fusiIU0mTzCtm7WXcB+OF+YpZpUzuTwEEtsLPQrvE/plUneTYC1ICH3udhWKIQMZbAf4GM92P/UdtF7QQh6GOFemgbsy0JQTJlSygFpNJcjvc1ZGR70XDaRLL6OaebcvkxEy5HkV4ZGBO1OwmANDsu/HT25y5Y+viracHVYbBT8kv4qXlRtrCQSZyTWkz29R0DYCG8elJBUexTuP63cMLOnFeSvXeRPPAAIrb52w== X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: e55f3933-a688-433d-18ec-08deb5a9a065 X-MS-Exchange-CrossTenant-AuthSource: DM5PR02MB3831.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 May 2026 13:22:08.0467 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: AGrDPfg1orfFjheSSSDU81CGeHI/8jUE3z18C39ChjnwCkTimbeFTUBrmT4uwCYHrm1UxJBHmRuBqE76RfBoc7hlx74AzIRbkm9W7Q1ne4Y= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR02MB9556 X-Proofpoint-ORIG-GUID: 8DIHeSVVadUIP-Jbdm4x-6O-HpIbTE5g X-Proofpoint-GUID: 8DIHeSVVadUIP-Jbdm4x-6O-HpIbTE5g X-Authority-Analysis: v=2.4 cv=NqnhtcdJ c=1 sm=1 tr=0 ts=6a0c6401 cx=c_pps a=p09nrIMaU8oQorgrX9pGYA==:117 a=6eWqkTHjU83fiwn7nKZWdM+Sl24=:19 a=z/mQ4Ysz8XfWz/Q5cLBRGdckG28=:19 a=lCpzRmAYbLLaTzLvsPZ7Mbvzbb8=:19 a=xqWC_Br6kY4A:10 a=NGcC8JguVDcA:10 a=0kUYKlekyDsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=VofLwUrZ8Iiv6rRUPXIb:22 a=VUi8bpU7OL1Oj2-RSIOF:22 a=64Cc0HZtAAAA:8 a=-FXZqOT6UGyiCX_LLnUA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTE5MDEzMiBTYWx0ZWRfX5s3AIm0I5sPX HeCdAH7sG/i8J72a3Ts+lTKkiSSkQSlpWQPW44h/pHtwjs5TZz9qdp7dRXicJig6LMuqVHnW9gD LJQXjl0QPKOTZ1HiBC6XpTIzprikfoJXKX9xx3Ry5CWqgTRryDEo4Jt2NPcv1Zo0e1xjTFb7yNN KAVrVMqbdRpFsSmo8VKzTtuvaoI5C+pyQBo4r9ktpYD/2JXhg6A0DspYMEbLZJIZ1uuZAU+sC18 vcv9noOm8Usi+C1eLB276+bImF/+yo5BjmCMw7xoGx7fv1vOQBkO3SlOLpmFxd7G2Orm1n+3yh0 qcUWiclqLYAd+Ayvurwc/d+Wppiykn9S4e5R84xGqz7jJ+4WrI5BeLBcCG5P/nVK0GGC3tQzX/T aMud4VlLaymXjOoB8+UOh8P1oWbv5i0h+ih100qP76c4DU5lk8a24nzq7olpjkckfvRO+QSbhqV qZutD5oEn4iTnoXe/Og== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-19_03,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Reason: safe Message-ID-Hash: KVSVECP3RSD3HBTPYYHKMGJH7BVDQFI2 X-Message-ID-Hash: KVSVECP3RSD3HBTPYYHKMGJH7BVDQFI2 X-MailFrom: lucas.kornicki@nutanix.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @nutanix.com) X-ZM-MESSAGEID: 1779198679084158500 Content-Type: text/plain; charset="utf-8" Emit the channel lifecycle event on VSERPORT_CHANGE and when refreshing virtio state. On "org.qemu.guest_agent.0" channel state change both agent and channel lifecycle events are emitted in that order. Signed-off-by: Lucas Kornicki Reviewed-by: Michal Privoznik --- src/qemu/qemu_driver.c | 8 ++++++++ src/qemu/qemu_process.c | 28 ++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index eda1f42054..d260c1cc74 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3906,6 +3906,14 @@ processSerialChangedEvent(virQEMUDriver *driver, virObjectEventStateQueue(driver->domainEventState, event); } =20 + /* we deliberately allow for goto endjob to skip generic event emission + * to ensure identical semantics for "org.qemu.guest_agent.0" */ + event =3D virDomainEventChannelLifecycleNewFromObj(vm, + dev.data.chr->target.= name, + newstate, + VIR_CONNECT_DOMAIN_EV= ENT_CHANNEL_LIFECYCLE_REASON_CHANNEL); + virObjectEventStateQueue(driver->domainEventState, event); + endjob: virDomainObjEndJob(vm); } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 83f5ebb19c..38c1fa05ce 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2253,7 +2253,7 @@ qemuProcessRefreshChannelVirtioState(virQEMUDriver *d= river, size_t i; int agentReason =3D VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CH= ANNEL; qemuMonitorChardevInfo *entry; - virObjectEvent *event =3D NULL; + virObjectEvent *events[2]; g_autofree char *id =3D NULL; =20 if (booted) @@ -2271,11 +2271,27 @@ qemuProcessRefreshChannelVirtioState(virQEMUDriver = *driver, !entry->state) continue; =20 - if (entry->state !=3D VIR_DOMAIN_CHR_DEVICE_STATE_DEFAULT && - STREQ_NULLABLE(chr->target.name, "org.qemu.guest_agent.0")= && - (event =3D virDomainEventAgentLifecycleNewFromObj(vm, entr= y->state, - agentReaso= n))) - virObjectEventStateQueue(driver->domainEventState, event); + if (entry->state !=3D VIR_DOMAIN_CHR_DEVICE_STATE_DEFAULT) { + events[0] =3D virDomainEventChannelLifecycleNewFromObj(vm, + chr->= target.name, + entry= ->state, + agent= Reason); + if (STREQ_NULLABLE(chr->target.name, "org.qemu.guest_agent= .0")) { + events[1] =3D virDomainEventAgentLifecycleNewFromObj(v= m, + ent= ry->state, + age= ntReason); + } else { + events[1] =3D NULL; + } + + /* emit agent then channel when emitting both events */ + if (events[0] && events[1]) { + virObjectEventStateQueue(driver->domainEventState, eve= nts[1]); + virObjectEventStateQueue(driver->domainEventState, eve= nts[0]); + } else if (events[0]) { + virObjectEventStateQueue(driver->domainEventState, eve= nts[0]); + } + } =20 chr->state =3D entry->state; } --=20 2.43.0