From nobody Tue Jun 9 21:00:00 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1778735353; cv=none; d=zohomail.com; s=zohoarc; b=PBMyRfTKjfEMU+CTnNR/H7fjjxOzu5JCYqc/JTTJsx+Urtf6st3cpkeu8di8rUlYP0/7+OWrSYlXlh1g1uMN+6fXEiGZGstzwlGPGiS1dTNuvOQ93i5XIC2R8mPQPFoHfn/FFC7ta2TVddFxE1ei3cCK+5CEnDuyKmy0nk9ZXNc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778735353; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=YYSDuVrO0poYgwVtgn0QzJiYbO61/CXaHdSi2MT1xEI=; b=aLDDgY+Gl5tshttQP+MmWbwWMg//rEWog9Etlvg+7P65sL7d9UBrX7kC2vprzcgTgQi8Og5xoyojPsD7/dPe4jUwZY4zDL+1Vk4mymuUer5/x+TMkO8GkohOTemfbqHZdZuJ/qmU8HO6pGHSdP/PLb9xPWPGh8IyWAUi/HjcnzE= ARC-Authentication-Results: i=1; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1778735353835969.2053238135371; Wed, 13 May 2026 22:09:13 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 5897241868; Thu, 14 May 2026 01:09:12 -0400 (EDT) Received: from [172.19.199.9] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 2A90C41A82; Thu, 14 May 2026 01:05:51 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 71EE94185C; Thu, 14 May 2026 01:05:40 -0400 (EDT) Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) (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 9EE6841852 for ; Thu, 14 May 2026 01:05:33 -0400 (EDT) Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-bd2e8931915so476008966b.1 for ; Wed, 13 May 2026 22:05:33 -0700 (PDT) Received: from tulp.my.domain (2001-1c02-1a15-3000-ee82-4536-a8f2-9e22.cable.dynamic.v6.ziggo.nl. [2001:1c02:1a15:3000:ee82:4536:a8f2:9e22]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bd4f4bce1a4sm49550166b.5.2026.05.13.22.05.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2026 22:05:30 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778735132; x=1779339932; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YYSDuVrO0poYgwVtgn0QzJiYbO61/CXaHdSi2MT1xEI=; b=OXzqoAtRuA6aIldKbJ2LY0QA3q3xkEqiLWiLtX5e6JBbQNxKpTqEFvzwh+R5KocFi9 26PXlEO/9XflIsj419ZTQdq5BMVBzwTE5xAHGRxFnx/KYwP0RlWT6sg2Jw4dnrDh0YFp XNKkc55gDa5jBTVK9StHPmNiAB4Mj/tHslm379QeCTaUOokymjKzBEh4Jsei+k9aR3R0 wz+9XgYdvZ5x9NuyhVa9IaQ1YsPRqY9vBrGsDmi+Awr7iBgRb7E4GSyjDa22QH+F6nPM u4vhp//I5DVU4V+xFDKa2rjtwu4//B8wHngIrlPiieOgMTVCGirCp3pnZaib+ctQNdA+ 8wYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778735132; x=1779339932; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=YYSDuVrO0poYgwVtgn0QzJiYbO61/CXaHdSi2MT1xEI=; b=ClrDKZ87x2epNy0c89+jrqqhwuFWImSl1Sge/77slJqNNVG7EqNOxogVVosB7NB8+o FaKNjAqcYhgoiqHIQ7zndHt3GjK7W3dng5uXQOkWJgkTDatOxU8U1VibXn8EqiNBoZEn kSS11hlsRXnRybx4tOjrGHNXpmNFe+MmdmDeuQrmNOIAX/B7EcBbDWYMrImQXEt+XBDg tpNmJxGAMK1mpU3i9ZZtcwaM3H5glyN6U/4yBHeKbZ/g0XjjKjEOEaSTocMYf0FTPqUW KUR9dYk6Ebhi2nzy3xv4RyrJBBfjLC58v80AXW5/Elu5VV3um0tDAGim9jTK3Cq82TL4 VtMw== X-Gm-Message-State: AOJu0Yy833Pq+yp1VvxrmfWiqJuRmvskNbhBDWGDwb6p9VblhlFzD1gl Qugbbt9YOHmgFp3mtQSdpy9svxTrDSY/WaOqfarRkqUI8TvsiPKPojE/Mvh32akC X-Gm-Gg: Acq92OEAyYk2fFHjaK6VQx/I4gvJnITK9kX6XaIjns0G3jC/hu1n0LBIdn4Is1GIgh8 1B2BGc1BybJSuCQms4Lm2Sg7OCFc0zTiDSd3A6H8aFSl6Wzk2sPVjLlZFzWGjhSy1Ej8nz0997W XfwHeQVinQcMVDCVesa9rUC20Tmw9m1crOuVdiMxWLLLizs5K/aeMD2cPuRGK4BQF5+WRh++6YO N7KcCqw3IXBlGygtIegBwnDFvQevMflJrwV7scLn8UgaGC9YdpXhtgUtdOpnsZ6C91sNkrRsBfQ rKzCsxdPt0rtIF+9jl+3SRrs/4u52SWumIJ7FlzNOQHxyH3TvPwhhcSbOhCeFwu4lBTSOQCl3AP 9mVW4DeS3EHIMzUCg2a2eT4G9O8cbKGNk/U1yCRU1zhrU7xpABTBERD1m68yi9xoN4dv50EPitd 4vqHCh46LTQwvb4CKNexbFSPa72OJuAE0ox+Ctc8QWbtU4nbdDBZ/IiD8aeBfhaT79L1jptYdQU 7pH+qVd2kyLhOf7rWw8ZHOOote71uBu2cnAfw== X-Received: by 2002:a17:907:c298:b0:bc6:76d:819e with SMTP id a640c23a62f3a-bd4f337d3dbmr149091266b.1.1778735131388; Wed, 13 May 2026 22:05:31 -0700 (PDT) From: Roman Bogorodskiy To: devel@lists.libvirt.org Subject: [PATCH 1/2] qemu: move qemu_agent.c to hypervisor/ Date: Thu, 14 May 2026 07:02:15 +0200 Message-ID: <20260514050216.56790-2-bogorodskiy@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260514050216.56790-1-bogorodskiy@gmail.com> References: <20260514050216.56790-1-bogorodskiy@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 7VMTJNQYCSPKLTAHVWIVA6MQ4UJBYGQ3 X-Message-ID-Hash: 7VMTJNQYCSPKLTAHVWIVA6MQ4UJBYGQ3 X-MailFrom: bogorodskiy@gmail.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 CC: Roman Bogorodskiy 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 @gmail.com) X-ZM-MESSAGEID: 1778735355699158500 Content-Type: text/plain; charset="utf-8" To prepare for the qemu agent support for the bhyve driver, move the implementation from qemu/ to hypervisor. This way this implementation can be shared across multiple drivers. The move is mostly mechanical except qemuAgentOpen() which now accepts the "timeout" argument for the agent timeout. As the original code used QEMU_DOMAIN_PRIVATE() to access the agent timeout value, this change allows to make the code driver-independent. emuAgentOpenUnix() is wrapped with #ifndef WIN32 so it does not fail on mingw. Signed-off-by: Roman Bogorodskiy Reviewed-by: Michal Privoznik --- po/POTFILES | 2 +- src/hypervisor/meson.build | 1 + src/{qemu =3D> hypervisor}/qemu_agent.c | 20 +++++++++++++---- src/{qemu =3D> hypervisor}/qemu_agent.h | 3 ++- src/libvirt_private.syms | 32 +++++++++++++++++++++++++++ src/qemu/meson.build | 1 - src/qemu/qemu_process.c | 3 ++- tests/qemuagenttest.c | 2 +- tests/qemumonitortestutils.c | 6 +++-- tests/qemumonitortestutils.h | 2 +- 10 files changed, 60 insertions(+), 12 deletions(-) rename src/{qemu =3D> hypervisor}/qemu_agent.c (99%) rename src/{qemu =3D> hypervisor}/qemu_agent.h (98%) diff --git a/po/POTFILES b/po/POTFILES index a5f8705eb8..3d52f23002 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -100,6 +100,7 @@ src/hypervisor/domain_cgroup.c src/hypervisor/domain_driver.c src/hypervisor/domain_logcontext.c src/hypervisor/domain_interface.c +src/hypervisor/qemu_agent.c src/hypervisor/virhostdev.c src/interface/interface_backend_netcf.c src/interface/interface_backend_udev.c @@ -166,7 +167,6 @@ src/nwfilter/nwfilter_tech_driver.c src/openvz/openvz_conf.c src/openvz/openvz_driver.c src/openvz/openvz_util.c -src/qemu/qemu_agent.c src/qemu/qemu_alias.c src/qemu/qemu_backup.c src/qemu/qemu_block.c diff --git a/src/hypervisor/meson.build b/src/hypervisor/meson.build index 91eaefbebc..90055b950e 100644 --- a/src/hypervisor/meson.build +++ b/src/hypervisor/meson.build @@ -2,6 +2,7 @@ hypervisor_sources =3D [ 'domain_cgroup.c', 'domain_driver.c', 'domain_interface.c', + 'qemu_agent.c', 'virclosecallbacks.c', 'virhostdev.c', ] diff --git a/src/qemu/qemu_agent.c b/src/hypervisor/qemu_agent.c similarity index 99% rename from src/qemu/qemu_agent.c rename to src/hypervisor/qemu_agent.c index ee0921eca6..70f0cde5dd 100644 --- a/src/qemu/qemu_agent.c +++ b/src/hypervisor/qemu_agent.c @@ -21,14 +21,15 @@ =20 #include =20 -#include +#ifndef WIN32 +# include +#endif #include #include #include #include =20 #include "qemu_agent.h" -#include "qemu_domain.h" #include "viralloc.h" #include "virlog.h" #include "virerror.h" @@ -146,6 +147,7 @@ static void qemuAgentDispose(void *obj) virResetError(&agent->lastError); } =20 +#ifndef WIN32 static int qemuAgentOpenUnix(const char *socketpath) { @@ -183,6 +185,15 @@ qemuAgentOpenUnix(const char *socketpath) VIR_FORCE_CLOSE(agentfd); return -1; } +#else /* WIN32 */ +static int +qemuAgentOpenUnix(const char *socketpath G_GNUC_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Opening UNIX sockets is not supported on Win32= platform")); + return -1; +} +#endif /* WIN32 */ =20 =20 static int @@ -584,7 +595,8 @@ qemuAgent * qemuAgentOpen(virDomainObj *vm, const virDomainChrSourceDef *config, GMainContext *context, - qemuAgentCallbacks *cb) + qemuAgentCallbacks *cb, + int timeout) { qemuAgent *agent; g_autoptr(GError) gerr =3D NULL; @@ -601,7 +613,7 @@ qemuAgentOpen(virDomainObj *vm, if (!(agent =3D virObjectLockableNew(qemuAgentClass))) return NULL; =20 - agent->timeout =3D QEMU_DOMAIN_PRIVATE(vm)->agentTimeout; + agent->timeout =3D timeout; agent->fd =3D -1; if (virCondInit(&agent->notify) < 0) { virReportSystemError(errno, "%s", diff --git a/src/qemu/qemu_agent.h b/src/hypervisor/qemu_agent.h similarity index 98% rename from src/qemu/qemu_agent.h rename to src/hypervisor/qemu_agent.h index 860f19b6bd..9117d3743c 100644 --- a/src/qemu/qemu_agent.h +++ b/src/hypervisor/qemu_agent.h @@ -38,7 +38,8 @@ struct _qemuAgentCallbacks { qemuAgent *qemuAgentOpen(virDomainObj *vm, const virDomainChrSourceDef *config, GMainContext *context, - qemuAgentCallbacks *cb); + qemuAgentCallbacks *cb, + int timeout); =20 void qemuAgentClose(qemuAgent *mon); =20 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index cf0e71cc6a..3af6cc568a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1705,6 +1705,38 @@ virDomainInterfaceStopDevice; virDomainInterfaceStopDevices; virDomainInterfaceVportRemove; =20 +# hypervisor/qemu_agent.h +qemuAgentArbitraryCommand; +qemuAgentClose; +qemuAgentDiskInfoFree; +qemuAgentFSFreeze; +qemuAgentFSInfoFree; +qemuAgentFSThaw; +qemuAgentFSTrim; +qemuAgentGetDisks; +qemuAgentGetFSInfo; +qemuAgentGetHostname; +qemuAgentGetInterfaces; +qemuAgentGetLoadAvg; +qemuAgentGetOSInfo; +qemuAgentGetTime; +qemuAgentGetTimezone; +qemuAgentGetUsers; +qemuAgentGetVCPUs; +qemuAgentNotifyClose; +qemuAgentNotifyEvent; +qemuAgentOpen; +qemuAgentSetResponseTimeout; +qemuAgentSetTime; +qemuAgentSetUserPassword; +qemuAgentSetVCPUs; +qemuAgentShutdown; +qemuAgentSSHAddAuthorizedKeys; +qemuAgentSSHGetAuthorizedKeys; +qemuAgentSSHRemoveAuthorizedKeys; +qemuAgentSuspend; +qemuAgentUpdateCPUInfo; + # hypervisor/virclosecallbacks.h virCloseCallbacksDomainAdd; virCloseCallbacksDomainAlloc; diff --git a/src/qemu/meson.build b/src/qemu/meson.build index b4fb62f14f..2615a5ceef 100644 --- a/src/qemu/meson.build +++ b/src/qemu/meson.build @@ -1,5 +1,4 @@ qemu_driver_sources =3D [ - 'qemu_agent.c', 'qemu_alias.c', 'qemu_backup.c', 'qemu_block.c', diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index a6d33f6746..83f5ebb19c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -236,7 +236,8 @@ qemuConnectAgent(virQEMUDriver *driver, virDomainObj *v= m) agent =3D qemuAgentOpen(vm, config->source, virEventThreadGetContext(priv->eventThread), - &agentCallbacks); + &agentCallbacks, + QEMU_DOMAIN_PRIVATE(vm)->agentTimeout); =20 if (!virDomainObjIsActive(vm)) { qemuAgentClose(agent); diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index 9c64ed3c5f..74cd317e74 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -23,7 +23,7 @@ #include "testutilsqemu.h" #include "qemumonitortestutils.h" #include "qemu/qemu_conf.h" -#include "qemu/qemu_agent.h" +#include "hypervisor/qemu_agent.h" #include "virerror.h" =20 =20 diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 88a369188e..b6e17fc2ca 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -27,9 +27,10 @@ =20 #include "virthread.h" #define LIBVIRT_QEMU_PROCESSPRIV_H_ALLOW +#include "hypervisor/qemu_agent.h" +#include "qemu/qemu_domain.h" #include "qemu/qemu_processpriv.h" #include "qemu/qemu_monitor.h" -#include "qemu/qemu_agent.h" #include "rpc/virnetsocket.h" #include "viralloc.h" #include "virlog.h" @@ -1201,7 +1202,8 @@ qemuMonitorTestNewAgent(virDomainXMLOption *xmlopt) if (!(test->agent =3D qemuAgentOpen(test->vm, &src, virEventThreadGetContext(test->event= Thread), - &qemuMonitorTestAgentCallbacks))) + &qemuMonitorTestAgentCallbacks, + QEMU_DOMAIN_PRIVATE(test->vm)->agent= Timeout))) goto error; =20 virObjectLock(test->agent); diff --git a/tests/qemumonitortestutils.h b/tests/qemumonitortestutils.h index 6d26526f60..4f136410ee 100644 --- a/tests/qemumonitortestutils.h +++ b/tests/qemumonitortestutils.h @@ -21,7 +21,7 @@ =20 #include "qemu/qemu_conf.h" #include "qemu/qemu_monitor.h" -#include "qemu/qemu_agent.h" +#include "hypervisor/qemu_agent.h" =20 typedef struct _qemuMonitorTest qemuMonitorTest; =20 --=20 2.52.0 From nobody Tue Jun 9 21:00:00 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1778735511; cv=none; d=zohomail.com; s=zohoarc; b=ZRanPLrYI/h7DbH7GBUbCT/KtGsVZseU8C7R2ZtX1dz73Yxc1ep3kyHlqBEGVr+zGLut1ZdscODkUHUGwNR7Kz/IClV4I4OKpUDLJCQSI7VuYq3N48UKJuSf8c8IktvUB61caw+sJS/ZJtg18OK3Dr6FJtMTSFZsYpg0vh8HWEQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778735511; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=5fEBMhFi6k8UPoV2VRLx7tWwsnN3Z5XTIiMP+56bKrQ=; b=hwID1j6HiEzDx/8bMd/RwnhSX0JZYifGBGft/wgMnfJX2jiF5db4STf8HziF0tdKuWDgBa6FRxFmZT2Kh36UHUj7crrqOszKw5/h2EJdQ8NfmHGgJv4ZQShnDYwtkIsbnVIAjxSJP7wJkGK8n806JGmUD/8yrdw9RYnVfFYszhU= ARC-Authentication-Results: i=1; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1778735511025632.0405248787532; Wed, 13 May 2026 22:11:51 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id D41573F282; Thu, 14 May 2026 01:11:49 -0400 (EDT) Received: from [172.19.199.9] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 09F7941ADB; Thu, 14 May 2026 01:05:57 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 119DF418F6; Thu, 14 May 2026 01:05:41 -0400 (EDT) Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) (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 8388D4184F for ; Thu, 14 May 2026 01:05:33 -0400 (EDT) Received: by mail-ej1-x62e.google.com with SMTP id a640c23a62f3a-b9382e59c0eso1226005766b.0 for ; Wed, 13 May 2026 22:05:33 -0700 (PDT) Received: from tulp.my.domain (2001-1c02-1a15-3000-ee82-4536-a8f2-9e22.cable.dynamic.v6.ziggo.nl. [2001:1c02:1a15:3000:ee82:4536:a8f2:9e22]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bd4f4bce1a4sm49550166b.5.2026.05.13.22.05.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2026 22:05:31 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778735132; x=1779339932; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5fEBMhFi6k8UPoV2VRLx7tWwsnN3Z5XTIiMP+56bKrQ=; b=j4dAJ9AqlinMceVnkoBSGV/kZy+pYygNNjsV5zDU46a7gbY32Jm5AMw+mVY0MIjzpQ ODziosqY+Wq1e+H87nkMEZPuHTOswZEXhLKFyCAwfERqe2I4ip5xMBzbqGQSO/xMDdoB bJ/0P6Q1YxFC3zBhEcP/W732qd4FeRIHabpe3dpln0mEPsjiP5meRPa+rHRsQl2RUQ5X 6VqVWuND9IWtz07SjgMjbR1OGh/GAYKiobAzlMqOMU6KqNhOlNn+ZIrI77wSGIZUCWlK BUdgx0IzBRzBgA+qEWvANo3veuSBuFZYtA/YBMsaWS3xlukmWXyBup7YoOVl9uKHdi80 ZnaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778735132; x=1779339932; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5fEBMhFi6k8UPoV2VRLx7tWwsnN3Z5XTIiMP+56bKrQ=; b=eHbKm35p4El79S17dEiE5sCvNeC8HwfK0qax3FCw+zj2NmL++8gteLWXelTB0D07sb 6dNRIdUlEwzG1P1iuCCRvLP1gTY5vGpXY0JoKNo+y1mau0pbrPUhklSLMbKAAg37OrQf sRyXfDgWcuKBajCLhPMu+q699ZFFOG1SR2PzGrQ3kewoNGj+nONA/gZgf7ozndKF03Ol XRqfbpbYvNDtpLELW+w0eNIEtAAVLo14Of11i14RBZX8zY1zbPJsEavzX50DEKkN5ee5 OQ1bWF5GRfJZbnDqsdzS2D4n4WOH47wiC4xl++kGp41LlYPLG5o1bayvNK338fZ4Lhr4 PDlA== X-Gm-Message-State: AOJu0YxeVnA9TLeZd67prkHa22C7a2Ja55un/dt3c1sLFRQBThcoGfbI VkvfgZ5oNtNvJ3hGALQG0gKEGxZhPQuVUb6Z13FAfJoXOTog5eXS7tmbGD4Gi0Zv X-Gm-Gg: Acq92OHJvLgxRhgUKujenDTWlelwyD2H3eNfr16RNa8eWdzR/mG7OskGPUNJj+9WOg6 0/75rkZmzg5MhtuToYuJnob/X5j79wN63MFe1ujzBg1dnq4geFBIcqU/jj1P7yCls/DPch/l74O SMVRL7G8UEGrAL+/F78/pMjxaNly6B6JfzP0ozXb7Syr87jYTHhmHZlbe6iAx5416uGuW6iF/1c VWPIoz2zbsHtdORJ0aACM5QorwaM+G3rqbk2WUlPWMFU6ZGwKmjaTIBc8KjlKlObOOlzQXU5wgB QhmaATjDsJg8qJkk1vfy1Kc1Yf1kBOVRqkoJ/AE9qttSC/GZgzQUvoWGFGwgaZ5kwzVK2DCi6wb Mj3etm7hwPvy547FpYOExrfhTZInP/b2OrpjnEKaQQJmMxclUm/kp3NuOXegvyAUVVqBy4AjSu8 t4tH0uHMigt/R5O9N8BKsQhXxd6kfOVaGmcDLUTc1OsVwHXQP7t+dM+YWdvXvLuu7G+V/3FkEOv I5aeGWaM9MY2stuKTY8a6V3LarCrNZjVETXAw== X-Received: by 2002:a17:907:3e24:b0:bc3:989f:5179 with SMTP id a640c23a62f3a-bd3c12f996cmr440524166b.22.1778735132168; Wed, 13 May 2026 22:05:32 -0700 (PDT) From: Roman Bogorodskiy To: devel@lists.libvirt.org Subject: [PATCH 2/2] bhyve: add agent support Date: Thu, 14 May 2026 07:02:16 +0200 Message-ID: <20260514050216.56790-3-bogorodskiy@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260514050216.56790-1-bogorodskiy@gmail.com> References: <20260514050216.56790-1-bogorodskiy@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 3Q3WMVTO22EME52F76T2KOU32PRK3ERY X-Message-ID-Hash: 3Q3WMVTO22EME52F76T2KOU32PRK3ERY X-MailFrom: bogorodskiy@gmail.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 CC: Roman Bogorodskiy 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 @gmail.com) X-ZM-MESSAGEID: 1778735512648158500 Content-Type: text/plain; charset="utf-8" Implement QEMU Guest Agent support for bhyve. In bhyve it can configured using the virtio-console device. This change covers only two APIs using the agent: - DomainQemuAgentCommand -- the most generic one. - DomainGetHostname -- extended to support not only DHCP lease source, but an agent as well. It shares the qemu agent implementation with the qemu driver. Signed-off-by: Roman Bogorodskiy Reviewed-by: Michal Privoznik --- src/bhyve/bhyve_domain.c | 32 +++++++ src/bhyve/bhyve_domain.h | 14 +++ src/bhyve/bhyve_driver.c | 180 +++++++++++++++++++++++++++++++++++++- src/bhyve/bhyve_process.c | 118 +++++++++++++++++++++++++ src/bhyve/bhyve_process.h | 4 + 5 files changed, 345 insertions(+), 3 deletions(-) diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index 832a9b58d1..6367985efc 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -41,6 +41,7 @@ bhyveDomainObjPrivateAlloc(void *opaque) { bhyveDomainObjPrivate *priv =3D g_new0(bhyveDomainObjPrivate, 1); =20 + priv->agentTimeout =3D 30; priv->driver =3D opaque; =20 return priv; @@ -663,3 +664,34 @@ virXMLNamespace virBhyveDriverDomainXMLNamespace =3D { .uri =3D "http://libvirt.org/schemas/domain/bhyve/1.0", =20 }; + + +int +virBhyveDomainObjStartWorker(virDomainObj *dom) +{ + bhyveDomainObjPrivate *priv =3D dom->privateData; + + if (!priv->eventThread) { + g_autofree char *threadName =3D g_strdup_printf("vm-%s", dom->def-= >name); + if (!(priv->eventThread =3D virEventThreadNew(threadName))) + return -1; + } + + return 0; +} + + +void +virBhyveDomainObjStopWorker(virDomainObj *dom) +{ + bhyveDomainObjPrivate *priv =3D dom->privateData; + virEventThread *eventThread; + + if (!priv->eventThread) + return; + + eventThread =3D g_steal_pointer(&priv->eventThread); + virObjectUnlock(dom); + g_object_unref(eventThread); + virObjectLock(dom); +} diff --git a/src/bhyve/bhyve_domain.h b/src/bhyve/bhyve_domain.h index 5a539bc4c0..888ef2f84b 100644 --- a/src/bhyve/bhyve_domain.h +++ b/src/bhyve/bhyve_domain.h @@ -22,6 +22,8 @@ =20 #include "domain_addr.h" #include "domain_conf.h" +#include "vireventthread.h" +#include "hypervisor/qemu_agent.h" =20 #include "bhyve_monitor.h" =20 @@ -33,10 +35,22 @@ struct _bhyveDomainObjPrivate { bool persistentAddrs; =20 bhyveMonitor *mon; + + qemuAgent *agent; + bool agentError; + int agentTimeout; + + virEventThread *eventThread; }; =20 +#define BHYVE_DOMAIN_PRIVATE(vm) \ + ((bhyveDomainObjPrivate *) (vm)->privateData) + virDomainXMLOption *virBhyveDriverCreateXMLConf(struct _bhyveConn *); =20 extern virDomainXMLPrivateDataCallbacks virBhyveDriverPrivateDataCallbacks; extern virDomainDefParserConfig virBhyveDriverDomainDefParserConfig; extern virXMLNamespace virBhyveDriverDomainXMLNamespace; + +int virBhyveDomainObjStartWorker(virDomainObj *dom); +void virBhyveDomainObjStopWorker(virDomainObj *dom); diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index c8dd1a728a..7103be67a0 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -53,6 +53,7 @@ #include "virstring.h" #include "cpu/cpu.h" #include "viraccessapicheck.h" +#include "viraccessapicheckqemu.h" #include "virhostcpu.h" #include "virhostmem.h" #include "virportallocator.h" @@ -1895,6 +1896,165 @@ bhyveDomainInterfaceAddresses(virDomainPtr domain, } =20 =20 +static qemuAgent * +bhyveDomainObjEnterAgent(virDomainObj *obj) +{ + bhyveDomainObjPrivate *priv =3D obj->privateData; + qemuAgent *agent =3D priv->agent; + + VIR_DEBUG("Entering agent (agent=3D%p vm=3D%p name=3D%s)", + priv->agent, obj, obj->def->name); + + virObjectLock(agent); + virObjectRef(agent); + virObjectUnlock(obj); + + return agent; +} + + +static void +bhyveDomainObjExitAgent(virDomainObj *obj, qemuAgent *agent) +{ + virObjectUnlock(agent); + virObjectUnref(agent); + virObjectLock(obj); + + VIR_DEBUG("Exited agent (agent=3D%p vm=3D%p name=3D%s)", + agent, obj, obj->def->name); +} + + +static bool +bhyveDomainAgentAvailable(virDomainObj *vm, + bool reportError) +{ + bhyveDomainObjPrivate *priv =3D vm->privateData; + + if (virDomainObjGetState(vm, NULL) !=3D VIR_DOMAIN_RUNNING) { + if (reportError) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not running")); + } + return false; + } + + if (!priv->agent) { + if (bhyveFindAgentConfig(vm->def)) { + if (reportError) { + virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s", + _("QEMU guest agent is not connected")); + } + return false; + } else { + if (reportError) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("QEMU guest agent is not configured")); + } + return false; + } + } + return true; +} + + +static int +bhyveDomainEnsureAgent(virDomainObj *vm, + bool reportError) +{ + bhyveDomainObjPrivate *priv =3D vm->privateData; + + if (virDomainObjGetState(vm, NULL) !=3D VIR_DOMAIN_RUNNING) { + if (reportError) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not running")); + } + return -1; + } + + if (priv->agent) + return 0; + + if (!priv->eventThread && + virBhyveDomainObjStartWorker(vm) < 0) + return -1; + + if (bhyveConnectAgent(NULL, vm) < 0) + return -1; + + return 0; +} + + +static int +bhyveDomainGetHostnameAgent(virDomainObj *vm, + char **hostname) +{ + qemuAgent *agent; + int ret =3D -1; + + if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0) + return -1; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + if (bhyveDomainEnsureAgent(vm, true) < 0) + goto endjob; + + agent =3D bhyveDomainObjEnterAgent(vm); + ret =3D qemuAgentGetHostname(agent, hostname, true); + bhyveDomainObjExitAgent(vm, agent); + + endjob: + virDomainObjEndAgentJob(vm); + return ret; +} + + +static char * +bhyveDomainQemuAgentCommand(virDomainPtr domain, + const char *cmd, + int timeout, + unsigned int flags) +{ + virDomainObj *vm; + int ret =3D -1; + char *result =3D NULL; + qemuAgent *agent; + + virCheckFlags(0, NULL); + + if (!(vm =3D bhyveDomObjFromDomain(domain))) + goto cleanup; + + if (virDomainQemuAgentCommandEnsureACL(domain->conn, vm->def) < 0) + goto cleanup; + + if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + if (!bhyveDomainAgentAvailable(vm, true)) + goto endjob; + + agent =3D bhyveDomainObjEnterAgent(vm); + ret =3D qemuAgentArbitraryCommand(agent, cmd, &result, timeout); + bhyveDomainObjExitAgent(vm, agent); + if (ret < 0) + VIR_FREE(result); + + endjob: + virDomainObjEndAgentJob(vm); + + cleanup: + virDomainObjEndAPI(&vm); + return result; +} + + static int bhyveDomainGetHostnameLease(virDomainObj *vm, char **hostname) @@ -1961,7 +2121,15 @@ bhyveDomainGetHostname(virDomainPtr domain, virDomainObj *vm =3D NULL; char *hostname =3D NULL; =20 - virCheckFlags(VIR_DOMAIN_GET_HOSTNAME_LEASE, NULL); + virCheckFlags(VIR_DOMAIN_GET_HOSTNAME_LEASE | + VIR_DOMAIN_GET_HOSTNAME_AGENT, NULL); + + VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_GET_HOSTNAME_LEASE, + VIR_DOMAIN_GET_HOSTNAME_AGENT, + NULL); + + if (!(flags & VIR_DOMAIN_GET_HOSTNAME_AGENT)) + flags |=3D VIR_DOMAIN_GET_HOSTNAME_LEASE; =20 if (!(vm =3D bhyveDomObjFromDomain(domain))) return NULL; @@ -1969,8 +2137,13 @@ bhyveDomainGetHostname(virDomainPtr domain, if (virDomainGetHostnameEnsureACL(domain->conn, vm->def) < 0) goto cleanup; =20 - if (bhyveDomainGetHostnameLease(vm, &hostname) < 0) - goto cleanup; + if (flags & VIR_DOMAIN_GET_HOSTNAME_LEASE) { + if (bhyveDomainGetHostnameLease(vm, &hostname) < 0) + goto cleanup; + } else if (flags & VIR_DOMAIN_GET_HOSTNAME_AGENT) { + if (bhyveDomainGetHostnameAgent(vm, &hostname) < 0) + goto cleanup; + } =20 if (!hostname) { virReportError(VIR_ERR_NO_HOSTNAME, @@ -2052,6 +2225,7 @@ static virHypervisorDriver bhyveHypervisorDriver =3D { .domainGetVcpuPinInfo =3D bhyveDomainGetVcpuPinInfo, /* 12.1.0 */ .domainInterfaceAddresses =3D bhyveDomainInterfaceAddresses, /* 12.3.0= */ .domainGetHostname =3D bhyveDomainGetHostname, /* 12.3.0 */ + .domainQemuAgentCommand =3D bhyveDomainQemuAgentCommand, /* 12.4.0 */ }; =20 =20 diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index 6078d995cd..7652a998e5 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -171,6 +171,118 @@ bhyveSetResourceLimits(struct _bhyveConn *driver, vir= DomainObj *vm) return 0; } =20 +virDomainChrDef * +bhyveFindAgentConfig(virDomainDef *def) +{ + size_t i; + + for (i =3D 0; i < def->nchannels; i++) { + virDomainChrDef *channel =3D def->channels[i]; + + if (channel->targetType !=3D VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VI= RTIO) + continue; + + + if (STREQ_NULLABLE(channel->target.name, "org.qemu.guest_agent.0")= ) { + return channel; + } + } + + return NULL; +} + +static void +bhyveProcessHandleAgentEOF(qemuAgent *agent, + virDomainObj *vm) +{ + bhyveDomainObjPrivate *priv; + + virObjectLock(vm); + VIR_INFO("Received EOF from agent on %p '%s'", vm, vm->def->name); + + priv =3D vm->privateData; + + if (!priv->agent) { + VIR_DEBUG("Agent freed already"); + goto unlock; + } + + qemuAgentClose(agent); + priv->agent =3D NULL; + priv->agentError =3D false; + + virObjectUnlock(vm); + return; + + unlock: + virObjectUnlock(vm); + return; +} + +/* + * This is invoked when there is some kind of error + * parsing data to/from the agent. The VM can continue + * to run, but no further agent commands will be + * allowed + */ +static void +bhyveProcessHandleAgentError(qemuAgent *agent G_GNUC_UNUSED, + virDomainObj *vm) +{ + bhyveDomainObjPrivate *priv; + + virObjectLock(vm); + VIR_INFO("Received error from agent on %p '%s'", vm, vm->def->name); + + priv =3D vm->privateData; + + priv->agentError =3D true; + + virObjectUnlock(vm); +} + +static qemuAgentCallbacks agentCallbacks =3D { + .eofNotify =3D bhyveProcessHandleAgentEOF, + .errorNotify =3D bhyveProcessHandleAgentError, +}; + +int +bhyveConnectAgent(struct _bhyveConn *driver G_GNUC_UNUSED, virDomainObj *v= m) +{ + bhyveDomainObjPrivate *priv =3D vm->privateData; + qemuAgent *agent =3D NULL; + virDomainChrDef *config =3D bhyveFindAgentConfig(vm->def); + + if (!config) + return 0; + + if (priv->agent) + return 0; + + agent =3D qemuAgentOpen(vm, + config->source, + virEventThreadGetContext(priv->eventThread), + &agentCallbacks, + BHYVE_DOMAIN_PRIVATE(vm)->agentTimeout); + + if (!virDomainObjIsActive(vm)) { + qemuAgentClose(agent); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("guest crashed while connecting to the guest agen= t")); + return -1; + } + + priv->agent =3D agent; + if (!priv->agent) { + VIR_WARN("Cannot connect to QEMU guest agent for %s", vm->def->nam= e); + priv->agentError =3D true; + virResetLastError(); + } + + return 0; +} + + static int virBhyveProcessStartImpl(struct _bhyveConn *driver, virDomainObj *vm, @@ -293,6 +405,9 @@ virBhyveProcessStartImpl(struct _bhyveConn *driver, virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); priv->mon =3D bhyveMonitorOpen(vm, driver); =20 + if (virBhyveDomainObjStartWorker(vm) < 0) + goto cleanup; + if (virDomainObjSave(vm, driver->xmlopt, BHYVE_STATE_DIR) < 0) goto cleanup; @@ -714,6 +829,9 @@ virBhyveProcessReconnect(virDomainObj *vm, virDomainNetNotifyActualDevice(conn, vm->def, net); } =20 + if (virBhyveDomainObjStartWorker(vm) < 0) + goto cleanup; + cleanup: if (ret < 0) { /* If VM is reported to be in active state, but we cannot find diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h index 5e0acc810c..bf82f748a6 100644 --- a/src/bhyve/bhyve_process.h +++ b/src/bhyve/bhyve_process.h @@ -56,6 +56,10 @@ int virBhyveGetDomainTotalCpuStats(virDomainObj *vm, =20 void virBhyveProcessReconnectAll(struct _bhyveConn *driver); =20 +int bhyveConnectAgent(struct _bhyveConn *driver, virDomainObj *vm); + +virDomainChrDef *bhyveFindAgentConfig(virDomainDef *def); + typedef enum { VIR_BHYVE_PROCESS_START_AUTODESTROY =3D 1 << 0, } bhyveProcessStartFlags; --=20 2.52.0