From 2b1d5020e2ebf4e415809988b9c6a4079fdc3c12 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Fri, 23 May 2025 12:07:05 +0000 Subject: [PATCH 1/2] import OL libvirt-10.10.0-7.3.0.1.el9_6 --- ...tion-type-into-virDomainGetGuestInfo.patch | 53 ++ ...erface-types-with-backend-type-passt.patch | 106 ++++ ...ree-inhibitor-in-networkStateCleanup.patch | 44 ++ ...pport-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch | 72 +++ ...DomainCheckCPU-with-unknown-host-CPU.patch | 38 -- ...ect-behave-identically-to-passt-user.patch | 111 ++++ ...tDevStreamDisconnectedEvent-reusable.patch | 119 ++++ ...ecial-for-passt-in-a-helper-function.patch | 110 ++++ ...processNetdevStreamDisconnectedEvent.patch | 56 ++ ...NETDEV_VHOST_USER_DISCONNECTED-event.patch | 224 +++++++ ...g-snapshot-for-VM-with-non-file-disk.patch | 75 --- ...t-qemu_agent-Add-qemuAgentGetLoadAvg.patch | 163 ++++++ ...rting-to-external-disk-only-snapshot.patch | 50 -- ...ysusers-file-to-create-libvirt-group.patch | 6 +- ...move-logind-support-for-virNetDaemon.patch | 202 +++++++ ...rivers-over-to-new-virInhibitor-APIs.patch | 549 ++++++++++++++++++ ...re-logind-inhibitor-if-not-requested.patch | 52 ++ ...-fix-off-by-1-in-inhibitor-constants.patch | 46 ++ ...-for-holding-a-system-inhibitor-lock.patch | 375 ++++++++++++ ...pport-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch | 71 +++ SPECS/libvirt.spec | 48 +- 21 files changed, 2400 insertions(+), 170 deletions(-) create mode 100644 SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch create mode 100644 SOURCES/libvirt-conf-parse-interface-source-dev-for-all-interface-types-with-backend-type-passt.patch create mode 100644 SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch create mode 100644 SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch delete mode 100644 SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch create mode 100644 SOURCES/libvirt-qemu-make-passt-vhostuser-reconnect-behave-identically-to-passt-user.patch create mode 100644 SOURCES/libvirt-qemu-make-processNetDevStreamDisconnectedEvent-reusable.patch create mode 100644 SOURCES/libvirt-qemu-put-vhost-user-code-that-s-special-for-passt-in-a-helper-function.patch create mode 100644 SOURCES/libvirt-qemu-remove-nonsensical-sanity-check-in-processNetdevStreamDisconnectedEvent.patch create mode 100644 SOURCES/libvirt-qemu-respond-to-NETDEV_VHOST_USER_DISCONNECTED-event.patch delete mode 100644 SOURCES/libvirt-qemu-snapshot-error-out-early-when-reverting-snapshot-for-VM-with-non-file-disk.patch create mode 100644 SOURCES/libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch delete mode 100644 SOURCES/libvirt-qemu_snapshot-allow-reverting-to-external-disk-only-snapshot.patch create mode 100644 SOURCES/libvirt-rpc-remove-logind-support-for-virNetDaemon.patch create mode 100644 SOURCES/libvirt-src-convert-drivers-over-to-new-virInhibitor-APIs.patch create mode 100644 SOURCES/libvirt-util-don-t-attempt-to-acquire-logind-inhibitor-if-not-requested.patch create mode 100644 SOURCES/libvirt-util-fix-off-by-1-in-inhibitor-constants.patch create mode 100644 SOURCES/libvirt-util-introduce-object-for-holding-a-system-inhibitor-lock.patch create mode 100644 SOURCES/libvirt-virsh-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch diff --git a/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch b/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch new file mode 100644 index 0000000..03bbf21 --- /dev/null +++ b/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch @@ -0,0 +1,53 @@ +From 514588d016d1e105f987d821331a578a34ccdf49 Mon Sep 17 00:00:00 2001 +Message-ID: <514588d016d1e105f987d821331a578a34ccdf49.1745925135.git.jdenemar@redhat.com> +From: Martin Kletzander +Date: Tue, 25 Feb 2025 15:36:03 +0100 +Subject: [PATCH] Add load average information type into virDomainGetGuestInfo + +The public API part. + +Signed-off-by: Martin Kletzander +Reviewed-by: Peter Krempa +(cherry picked from commit c52c449fd40c7263896d5f17129207b815c3a09c) + +https://issues.redhat.com/browse/RHEL-88449 + +Signed-off-by: Martin Kletzander +--- + include/libvirt/libvirt-domain.h | 1 + + src/libvirt-domain.c | 8 ++++++++ + 2 files changed, 9 insertions(+) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index f026ce197c..c04b696f03 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -6425,6 +6425,7 @@ typedef enum { + VIR_DOMAIN_GUEST_INFO_FILESYSTEM = (1 << 4), /* return filesystem information (Since: 5.7.0) */ + VIR_DOMAIN_GUEST_INFO_DISKS = (1 << 5), /* return disks information (Since: 7.0.0) */ + VIR_DOMAIN_GUEST_INFO_INTERFACES = (1 << 6), /* return interfaces information (Since: 7.10.0) */ ++ VIR_DOMAIN_GUEST_INFO_LOAD = (1 << 7), /* return load averages (Since: 11.2.0) */ + } virDomainGuestInfoTypes; + + int virDomainGetGuestInfo(virDomainPtr domain, +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 7c6b93963c..24752a9888 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -13292,6 +13292,14 @@ virDomainSetVcpu(virDomainPtr domain, + * "if..addr..addr" - the IP address of addr + * "if..addr..prefix" - the prefix of IP address of addr + * ++ * VIR_DOMAIN_GUEST_INFO_LOAD: ++ * Returns load (the number of processes in the runqueue or waiting for disk ++ * I/O) as double values: ++ * ++ * "load.1m" - load averaged over 1 minute ++ * "load.5m" - load averaged over 5 minutes ++ * "load.15m" - load averaged over 15 minutes ++ * + * Using 0 for @types returns all information groups supported by the given + * hypervisor. + * +-- +2.49.0 diff --git a/SOURCES/libvirt-conf-parse-interface-source-dev-for-all-interface-types-with-backend-type-passt.patch b/SOURCES/libvirt-conf-parse-interface-source-dev-for-all-interface-types-with-backend-type-passt.patch new file mode 100644 index 0000000..2728161 --- /dev/null +++ b/SOURCES/libvirt-conf-parse-interface-source-dev-for-all-interface-types-with-backend-type-passt.patch @@ -0,0 +1,106 @@ +From a52da24e19808954454be38945953a2a81c078e9 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Laine Stump +Date: Thu, 6 Mar 2025 19:19:12 -0500 +Subject: [PATCH] conf: parse interface/source/@dev for all interface types + (with backend type='passt') + +The original implementation of the passt backend for vhost-user +interfaces erroneously forgot to parse: + + + +for interface type='vhostuser', so it wasn't being added to the passt +commandline, and also wasn't being saved to the domain config. Now we +parse it whenever the type='passt', no matter what the +interface type, and then throw an error during validation if +source/@dev was specified for interface type = 'user|vhostuser' and +backend type != 'passt'. + +Fixes: 1e9054b9c79d721a55f413c2983c5370044f8f60 +Resolves: https://issues.redhat.com/browse/RHEL-82539 +Signed-off-by: Laine Stump +Reviewed-by: Peter Krempa +(cherry picked from commit 4c979edaa545c8425f7a856c06ebc0de939d4b9f) + +https://issues.redhat.com/browse/RHEL-84689 + +Signed-off-by: Jiri Denemark +--- + src/conf/domain_conf.c | 8 +++++--- + src/conf/domain_validate.c | 8 +++++++- + .../qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml | 2 ++ + 3 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 095b9bbaa2..94e26bf82a 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -9900,9 +9900,6 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, + break; + + case VIR_DOMAIN_NET_TYPE_USER: +- def->sourceDev = virXMLPropString(source_node, "dev"); +- break; +- + case VIR_DOMAIN_NET_TYPE_NULL: + case VIR_DOMAIN_NET_TYPE_LAST: + break; +@@ -10017,6 +10014,11 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt, + return NULL; + } + ++ if (def->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) { ++ def->sourceDev = virXMLPropString(source_node, "dev"); ++ } ++ ++ + def->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT; + if (linkstate != NULL) { + if ((def->linkstate = virDomainNetInterfaceLinkStateTypeFromString(linkstate)) <= 0) { +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index 597ae3d938..9cedc8d6d2 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -2160,12 +2160,18 @@ virDomainNetDefValidate(const virDomainNetDef *net) + if (net->type != VIR_DOMAIN_NET_TYPE_USER && + net->type != VIR_DOMAIN_NET_TYPE_VHOSTUSER) { + if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("The 'passt' backend can only be used with interface type='user' or type='vhostuser'")); + return -1; + } + } + ++ if (net->sourceDev && net->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("The 'dev' attribute of the element can only be used with type='user' or type='vhostuser' if the type='passt'")); ++ return -1; ++ } ++ + if (net->nPortForwards > 0) { + size_t p; + +diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml +index a1f9366722..529aff11f8 100644 +--- a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml ++++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.xml +@@ -33,6 +33,7 @@ + + + ++ + + + +@@ -63,6 +64,7 @@ + + + ++ + + +
+-- +2.49.0 diff --git a/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch b/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch new file mode 100644 index 0000000..0a812a8 --- /dev/null +++ b/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch @@ -0,0 +1,44 @@ +From 8e64dac6129cacd8f53813cbc7580209e96e7dc3 Mon Sep 17 00:00:00 2001 +Message-ID: <8e64dac6129cacd8f53813cbc7580209e96e7dc3.1744361503.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Thu, 13 Mar 2025 13:01:19 +0100 +Subject: [PATCH] network: Free inhibitor in networkStateCleanup() + +The shutdown inhibitor is created in networkStateInitialize() but +corresponding call to virInhibitorFree() is missing in +networkStateCleanup() leading to a memleak: + +116 (72 direct, 44 indirect) bytes in 1 blocks are definitely lost in loss record 1,769 of 1,998 + at 0x484CEF3: calloc (vg_replace_malloc.c:1675) + by 0x4F0E7A9: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.8000.5) + by 0x4993B9B: virInhibitorNew (virinhibitor.c:152) + by 0x5279394: networkStateInitialize (bridge_driver.c:654) + by 0x4CC74DC: virStateInitialize (libvirt.c:665) + by 0x15B719: daemonRunStateInit (remote_daemon.c:613) + by 0x49F2B44: virThreadHelper (virthread.c:256) + by 0x5356662: start_thread (in /usr/lib64/libc.so.6) + by 0x53D7DA3: clone (in /usr/lib64/libc.so.6) + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +(cherry picked from commit 8701ba4feb528109da8b72fa48a8ada50a235807) +Resolves: https://issues.redhat.com/browse/RHEL-83076 +--- + src/network/bridge_driver.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index ce793c12ef..adcff6f34f 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -802,6 +802,8 @@ networkStateCleanup(void) + network_driver->lockFD); + } + ++ virInhibitorFree(network_driver->inhibitor); ++ + virObjectUnref(network_driver->config); + virObjectUnref(network_driver->dnsmasqCaps); + +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch b/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch new file mode 100644 index 0000000..ccb387b --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch @@ -0,0 +1,72 @@ +From 816ce9100cbc410706fde26763158640f6d06f44 Mon Sep 17 00:00:00 2001 +Message-ID: <816ce9100cbc410706fde26763158640f6d06f44.1745925135.git.jdenemar@redhat.com> +From: Martin Kletzander +Date: Tue, 25 Feb 2025 15:36:32 +0100 +Subject: [PATCH] qemu: Add support for VIR_DOMAIN_GUEST_INFO_LOAD + +Signed-off-by: Martin Kletzander +Reviewed-by: Peter Krempa +(cherry picked from commit b4cf9c8cba45e65551aa9440dea2c3757a96aa0c) + +https://issues.redhat.com/browse/RHEL-88449 + +Signed-off-by: Martin Kletzander +--- + src/qemu/qemu_driver.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index d65fc542d1..3e194999fe 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -19288,7 +19288,8 @@ static const unsigned int qemuDomainGetGuestInfoSupportedTypes = + VIR_DOMAIN_GUEST_INFO_HOSTNAME | + VIR_DOMAIN_GUEST_INFO_FILESYSTEM | + VIR_DOMAIN_GUEST_INFO_DISKS | +- VIR_DOMAIN_GUEST_INFO_INTERFACES; ++ VIR_DOMAIN_GUEST_INFO_INTERFACES | ++ VIR_DOMAIN_GUEST_INFO_LOAD; + + static int + qemuDomainGetGuestInfoCheckSupport(unsigned int types, +@@ -19575,6 +19576,10 @@ qemuDomainGetGuestInfo(virDomainPtr dom, + qemuAgentDiskInfo **agentdiskinfo = NULL; + virDomainInterfacePtr *ifaces = NULL; + size_t nifaces = 0; ++ double load1m = 0; ++ double load5m = 0; ++ double load15m = 0; ++ bool format_load = false; + size_t i; + + virCheckFlags(0, -1); +@@ -19645,6 +19650,14 @@ qemuDomainGetGuestInfo(virDomainPtr dom, + nifaces = rc; + } + ++ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_LOAD) { ++ rc = qemuAgentGetLoadAvg(agent, &load1m, &load5m, &load15m, report_unsupported); ++ if (rc == -1) ++ goto exitagent; ++ if (rc >= 0) ++ format_load = true; ++ } ++ + qemuDomainObjExitAgent(vm, agent); + virDomainObjEndAgentJob(vm); + +@@ -19671,6 +19684,12 @@ qemuDomainGetGuestInfo(virDomainPtr dom, + virDomainInterfaceFormatParams(ifaces, nifaces, params, nparams, &maxparams); + } + ++ if (format_load) { ++ virTypedParamsAddDouble(params, nparams, &maxparams, "load.1m", load1m); ++ virTypedParamsAddDouble(params, nparams, &maxparams, "load.5m", load5m); ++ virTypedParamsAddDouble(params, nparams, &maxparams, "load.15m", load15m); ++ } ++ + ret = 0; + + cleanup: +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch b/SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch deleted file mode 100644 index 7eb1537..0000000 --- a/SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d874530eaded03d0b90139c9bbd80902b9464e87 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Jiri Denemark -Date: Tue, 18 Feb 2025 11:24:32 +0100 -Subject: [PATCH] qemu: Avoid crash in qemuDomainCheckCPU with unknown host CPU - -When we don't have any information about host CPU (for example when -running on an aarch64 host), the virQEMUCapsGetHostModel would return -NULL. - -Fixes: f928eb5fc80ca0ed7277f2513b63aed36c09d275 -Fixes: https://gitlab.com/libvirt/libvirt/-/issues/747 -Signed-off-by: Jiri Denemark -Tested-by: Jaroslav Suchanek -Reviewed-by: Michal Privoznik -(cherry picked from commit 43eae1b7077104d4e2ed52447407a335c2d093e3) - -https://issues.redhat.com/browse/RHEL-81747 - -Signed-off-by: Jiri Denemark ---- - src/qemu/qemu_domain.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c -index 92035dd281..1ccaff90d9 100644 ---- a/src/qemu/qemu_domain.c -+++ b/src/qemu/qemu_domain.c -@@ -11446,6 +11446,7 @@ qemuDomainCheckCPU(virArch arch, - /* Force compat check if the CPU model is not found in qemuCaps or - * we don't have host CPU data from QEMU */ - if (!cpu->model || -+ !hypervisorCPU || - hypervisorCPU->fallback != VIR_CPU_FALLBACK_FORBID || - virQEMUCapsGetCPUBlockers(qemuCaps, virtType, - cpu->model, &blockers) < 0) --- -2.48.1 diff --git a/SOURCES/libvirt-qemu-make-passt-vhostuser-reconnect-behave-identically-to-passt-user.patch b/SOURCES/libvirt-qemu-make-passt-vhostuser-reconnect-behave-identically-to-passt-user.patch new file mode 100644 index 0000000..81a1bcd --- /dev/null +++ b/SOURCES/libvirt-qemu-make-passt-vhostuser-reconnect-behave-identically-to-passt-user.patch @@ -0,0 +1,111 @@ +From bc0074073da43052e4a786eca70dd5fbbf023903 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Laine Stump +Date: Fri, 4 Apr 2025 19:44:52 -0400 +Subject: [PATCH] qemu: make passt+vhostuser reconnect behave identically to + passt+user + +When "original passt" support was added, we decided that we always +wanted to reconnect (i.e. restart the passt process) if it was somehow +terminated. Generic vhost-user, on the other hand, only turns on +reconnect if specified by the user in the config. But there is no +reason to require the user to specify this if the other end of the +vhost-user socket is a passt process - we know what has happened and +what we want to do; no reason to do the *wrong* thing by default, and +force the user to make an arbitrary decision about what to add to the +config in order to make it do the *right* thing; instead we just +hardcode it to always do the right thing. + +(NB: when the backend is passt, has +always ignored the reconnect setting in when parsing and +formatting, just as it has always ignored the socket path (since that +also is not user configurable for the passt backend) + +Resolves: https://issues.redhat.com/browse/RHEL-80169 + +Signed-off-by: Laine Stump +Tested-by: Stefano Brivio +Reviewed-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 44abaa0128ac0fc8be9de4eebc15c03809bf5867) + +Conflicts: + +tests/qemuxmlconfdata/schema-reorder-domain-subelements.x86_64-latest.args: + This file (created by upstream commit be5332c81d28) was modified + upstream but doesin't exist downstream + +https://issues.redhat.com/browse/RHEL-84782 +Signed-off-by: Laine Stump +--- + src/qemu/qemu_passt.c | 16 +++++++++++++--- + .../net-vhostuser-passt.x86_64-latest.args | 6 +++--- + 2 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c +index bc495eca1e..fcc34de384 100644 +--- a/src/qemu/qemu_passt.c ++++ b/src/qemu/qemu_passt.c +@@ -36,7 +36,7 @@ VIR_LOG_INIT("qemu.passt"); + + + #define PASST "passt" +- ++#define QEMU_PASST_RECONNECT_TIMEOUT 5 + + static char * + qemuPasstCreatePidFilename(virDomainObj *vm, +@@ -106,11 +106,15 @@ qemuPasstAddNetProps(virDomainObj *vm, + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_STREAM_RECONNECT)) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS)) { +- if (virJSONValueObjectAdd(netprops, "u:reconnect-ms", 5000, NULL) < 0) ++ if (virJSONValueObjectAdd(netprops, "u:reconnect-ms", ++ QEMU_PASST_RECONNECT_TIMEOUT * 1000, NULL) < 0) { + return -1; ++ } + } else { +- if (virJSONValueObjectAdd(netprops, "u:reconnect", 5, NULL) < 0) ++ if (virJSONValueObjectAdd(netprops, "u:reconnect", ++ QEMU_PASST_RECONNECT_TIMEOUT, NULL) < 0) { + return -1; ++ } + } + } + +@@ -182,6 +186,12 @@ qemuPasstPrepareVhostUser(virDomainObj *vm, + */ + g_free(net->data.vhostuser->data.nix.path); + net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net); ++ ++ /* reconnect is always enabled, with timeout always at 5 seconds, when ++ * using passt ++ */ ++ net->data.vhostuser->data.nix.reconnect.enabled = VIR_TRISTATE_BOOL_YES; ++ net->data.vhostuser->data.nix.reconnect.timeout = QEMU_PASST_RECONNECT_TIMEOUT; + } + + int +diff --git a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args +index 7c030d7067..afbbe188cf 100644 +--- a/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args ++++ b/tests/qemuxmlconfdata/net-vhostuser-passt.x86_64-latest.args +@@ -28,13 +28,13 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ + -boot strict=on \ + -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \ + -device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-storage","id":"ide0-0-0","bootindex":1}' \ +--chardev socket,id=charnet0,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net0.socket \ ++-chardev socket,id=charnet0,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net0.socket,reconnect-ms=5000 \ + -netdev '{"type":"vhost-user","chardev":"charnet0","id":"hostnet0"}' \ + -device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"00:11:22:33:44:55","bus":"pci.0","addr":"0x2"}' \ +--chardev socket,id=charnet1,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net1.socket \ ++-chardev socket,id=charnet1,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net1.socket,reconnect-ms=5000 \ + -netdev '{"type":"vhost-user","chardev":"charnet1","id":"hostnet1"}' \ + -device '{"driver":"virtio-net-pci","netdev":"hostnet1","id":"net1","mac":"00:11:22:33:44:11","bus":"pci.0","addr":"0x3"}' \ +--chardev socket,id=charnet2,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net2.socket \ ++-chardev socket,id=charnet2,path=/var/run/libvirt/qemu/passt/-1-QEMUGuest1-net2.socket,reconnect-ms=5000 \ + -netdev '{"type":"vhost-user","chardev":"charnet2","id":"hostnet2"}' \ + -device '{"driver":"virtio-net-pci","netdev":"hostnet2","id":"net2","mac":"00:11:22:33:44:11","bus":"pci.0","addr":"0x4"}' \ + -audiodev '{"id":"audio1","driver":"none"}' \ +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-make-processNetDevStreamDisconnectedEvent-reusable.patch b/SOURCES/libvirt-qemu-make-processNetDevStreamDisconnectedEvent-reusable.patch new file mode 100644 index 0000000..f172156 --- /dev/null +++ b/SOURCES/libvirt-qemu-make-processNetDevStreamDisconnectedEvent-reusable.patch @@ -0,0 +1,119 @@ +From 718c4bc80d3af4570d75b590625bd5249aa50a8d Mon Sep 17 00:00:00 2001 +Message-ID: <718c4bc80d3af4570d75b590625bd5249aa50a8d.1744361503.git.jdenemar@redhat.com> +From: Laine Stump +Date: Fri, 4 Apr 2025 16:57:21 -0400 +Subject: [PATCH] qemu: make processNetDevStreamDisconnectedEvent() reusable + +We will be adding a new event whose response will be *exactly* the +same as the response to NETDEV_STREAM_DISCONNECTED. Rather than doing +a copy-paste of the complete function that does the processing, turn +that function into something more generic that takes the name of the +event as an arg (the event name is only used in log messages). + +Signed-off-by: Laine Stump +Tested-by: Stefano Brivio +Reviewed-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 03a6bc7752ec73d7ea222d5386e8f4124fe51c7f) + +Conflicts: + +src/qemu/qemu_driver.c: + In context surrounding a chunk, the arguments to + processNicRxFilterChangedEvent() changed upstream (due to upstream + commit 50981052a5f) + +https://issues.redhat.com/browse/RHEL-84782 +Signed-off-by: Laine Stump +--- + src/qemu/qemu_driver.c | 37 +++++++++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 14 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 53dcd690f0..65e17a870d 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -3618,8 +3618,9 @@ processDeviceDeletedEvent(virQEMUDriver *driver, + + + static void +-processNetdevStreamDisconnectedEvent(virDomainObj *vm, +- const char *netdevId) ++processNetdevDisconnectedEvent(virDomainObj *vm, ++ const char *netdevId, ++ const char *eventName) + { + virDomainDeviceDef dev; + virDomainNetDef *def; +@@ -3634,13 +3635,13 @@ processNetdevStreamDisconnectedEvent(virDomainObj *vm, + */ + + if (!devAlias) { +- VIR_WARN("Received NETDEV_STREAM_DISCONNECTED event for unrecognized netdev %s from domain %p %s", +- netdevId, vm, vm->def->name); ++ VIR_WARN("Received %s event for unrecognized netdev %s from domain %p %s", ++ eventName, netdevId, vm, vm->def->name); + return; + } + +- VIR_DEBUG("Received NETDEV_STREAM_DISCONNECTED event for device %s from domain %p %s", +- devAlias, vm, vm->def->name); ++ VIR_DEBUG("Received %s event for device %s from domain %p %s", ++ eventName, devAlias, vm, vm->def->name); + + if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0) + return; +@@ -3651,28 +3652,28 @@ processNetdevStreamDisconnectedEvent(virDomainObj *vm, + } + + if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0) { +- VIR_WARN("NETDEV_STREAM_DISCONNECTED event received for non-existent device %s in domain %s", +- devAlias, vm->def->name); ++ VIR_WARN("%s event received for non-existent device %s in domain %s", ++ eventName, devAlias, vm->def->name); + goto endjob; + } + if (dev.type != VIR_DOMAIN_DEVICE_NET) { +- VIR_WARN("NETDEV_STREAM_DISCONNECTED event received for non-network device %s in domain %s", +- devAlias, vm->def->name); ++ VIR_WARN("%s event received for non-network device %s in domain %s", ++ eventName, devAlias, vm->def->name); + goto endjob; + } + def = dev.data.net; + + if (def->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) { +- VIR_DEBUG("ignore NETDEV_STREAM_DISCONNECTED event for non-passt network device %s in domain %s", +- def->info.alias, vm->def->name); ++ VIR_DEBUG("ignore %s event for non-passt network device %s in domain %s", ++ eventName, def->info.alias, vm->def->name); + goto endjob; + } + + /* handle the event - restart the passt process with its original + * parameters + */ +- VIR_DEBUG("process NETDEV_STREAM_DISCONNECTED event for network device %s in domain %s", +- def->info.alias, vm->def->name); ++ VIR_DEBUG("process %s event for network device %s in domain %s", ++ eventName, def->info.alias, vm->def->name); + + if (qemuPasstStart(vm, def) < 0) + goto endjob; +@@ -3682,6 +3683,14 @@ processNetdevStreamDisconnectedEvent(virDomainObj *vm, + } + + ++static void ++processNetdevStreamDisconnectedEvent(virDomainObj *vm, ++ const char *netdevId) ++{ ++ processNetdevDisconnectedEvent(vm, netdevId, "NETDEV_STREAM_DISCONNECTED"); ++} ++ ++ + static void + processNicRxFilterChangedEvent(virDomainObj *vm, + const char *devAlias) +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-put-vhost-user-code-that-s-special-for-passt-in-a-helper-function.patch b/SOURCES/libvirt-qemu-put-vhost-user-code-that-s-special-for-passt-in-a-helper-function.patch new file mode 100644 index 0000000..6319411 --- /dev/null +++ b/SOURCES/libvirt-qemu-put-vhost-user-code-that-s-special-for-passt-in-a-helper-function.patch @@ -0,0 +1,110 @@ +From c6e5688293b765885e8b76c35ad47bc316de81aa Mon Sep 17 00:00:00 2001 +Message-ID: +From: Laine Stump +Date: Fri, 4 Apr 2025 19:38:28 -0400 +Subject: [PATCH] qemu: put vhost-user code that's special for passt in a + helper function + +Rather than duplicating these two lines of chr device object setup for +hotplug and domain start, put them in a helper function that's called +from both places. That way when we need to setup *more* stuff specific +to passt+vhostuser, we can just add it in that one place. + +Signed-off-by: Laine Stump +Tested-by: Stefano Brivio +Reviewed-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 95ff77f2896478e039673bb552affec2c5a5e822) + +https://issues.redhat.com/browse/RHEL-84782 +Signed-off-by: Laine Stump +--- + src/qemu/qemu_hotplug.c | 7 +------ + src/qemu/qemu_passt.c | 19 +++++++++++++++++++ + src/qemu/qemu_passt.h | 3 +++ + src/qemu/qemu_process.c | 9 ++------- + 4 files changed, 25 insertions(+), 13 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index c8746f5e22..ff09b58bfe 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -1264,12 +1264,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, + + if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) { + +- /* vhostuser needs socket path in this location, and when +- * backend is passt, the path is derived from other info, +- * not taken from config. +- */ +- g_free(net->data.vhostuser->data.nix.path); +- net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net); ++ qemuPasstPrepareVhostUser(vm, net); + + if (qemuPasstStart(vm, net) < 0) + goto cleanup; +diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c +index b9616d1c63..bc495eca1e 100644 +--- a/src/qemu/qemu_passt.c ++++ b/src/qemu/qemu_passt.c +@@ -165,6 +165,25 @@ qemuPasstSetupCgroup(virDomainObj *vm, + } + + ++void ++qemuPasstPrepareVhostUser(virDomainObj *vm, ++ virDomainNetDef *net) ++{ ++ /* There are some options on the QEMU commandline for a vhost-user ++ * chr device that are normally configurable, but when it is passt ++ * speaking to the vhost-user device those things are ++ * derived/fixed. This function, which is called prior to ++ * generating the QEMU commandline, sets thos derived/fixed things ++ * in the chr device object. ++ */ ++ ++ /* The socket path is not user-configurable for passt - it is ++ * derived from other info ++ */ ++ g_free(net->data.vhostuser->data.nix.path); ++ net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net); ++} ++ + int + qemuPasstStart(virDomainObj *vm, + virDomainNetDef *net) +diff --git a/src/qemu/qemu_passt.h b/src/qemu/qemu_passt.h +index e0b9aaac8d..ea545ccf38 100644 +--- a/src/qemu/qemu_passt.h ++++ b/src/qemu/qemu_passt.h +@@ -37,5 +37,8 @@ int qemuPasstSetupCgroup(virDomainObj *vm, + virDomainNetDef *net, + virCgroup *cgroup); + ++void qemuPasstPrepareVhostUser(virDomainObj *vm, ++ virDomainNetDef *net); ++ + char *qemuPasstCreateSocketPath(virDomainObj *vm, + virDomainNetDef *net); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index f5c277203f..c80d7bb6dc 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -5952,13 +5952,8 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm) + + case VIR_DOMAIN_NET_TYPE_VHOSTUSER: + if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) { +- /* when using the passt backend, the path of the +- * unix socket is always derived from other info +- * *not* manually given in the config, but all the +- * vhostuser code looks for it there. +- */ +- g_free(net->data.vhostuser->data.nix.path); +- net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net); ++ /* some extra setup of internal data for passt vhostuser mode */ ++ qemuPasstPrepareVhostUser(vm, net); + } + break; + +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-remove-nonsensical-sanity-check-in-processNetdevStreamDisconnectedEvent.patch b/SOURCES/libvirt-qemu-remove-nonsensical-sanity-check-in-processNetdevStreamDisconnectedEvent.patch new file mode 100644 index 0000000..368eaf4 --- /dev/null +++ b/SOURCES/libvirt-qemu-remove-nonsensical-sanity-check-in-processNetdevStreamDisconnectedEvent.patch @@ -0,0 +1,56 @@ +From f6d606779aaedc8a6d958a2e97b462df390cb0a5 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Laine Stump +Date: Fri, 4 Apr 2025 16:48:23 -0400 +Subject: [PATCH] qemu: remove nonsensical sanity check in + processNetdevStreamDisconnectedEvent() + +By definition QEMU will never send a NETDEV_STREAM_DISCONNECTED event +if it doesn't support the reconnect option for a stream netdev. And +even if, by some comedy of errors, it did send +NETDEV_STREAM_DISCONNECTED in that case, our response to the event +doesn't request anything at all of QEMU (much less something that +would fail if QEMU didn't understand NETDEV_STREAM_DISCONNECTED) - it +just starts a new passt process to replace the one that has been +terminated, so we don't need to check the QEMU capabilities for +QEMU_CAPS_NETDEV_STREAM_RECONNECT. + +Signed-off-by: Laine Stump +Tested-by: Stefano Brivio +Reviewed-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 51a54dc1c4ecf37d60acee1cb94252e51c5ef627) + +https://issues.redhat.com/browse/RHEL-84782 +Signed-off-by: Laine Stump +--- + src/qemu/qemu_driver.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index f8f3d2c725..53dcd690f0 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -3623,7 +3623,6 @@ processNetdevStreamDisconnectedEvent(virDomainObj *vm, + { + virDomainDeviceDef dev; + virDomainNetDef *def; +- virQEMUCaps *qemuCaps = QEMU_DOMAIN_PRIVATE(vm)->qemuCaps; + const char *devAlias = STRSKIP(netdevId, "host"); + + /* The event sends us the "netdev-id", but we don't store the +@@ -3669,12 +3668,6 @@ processNetdevStreamDisconnectedEvent(virDomainObj *vm, + goto endjob; + } + +- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_STREAM_RECONNECT)) { +- VIR_WARN("ignore NETDEV_STREAM_DISCONNECTED event for passt network device %s in domain %s - QEMU binary does not support reconnect", +- def->info.alias, vm->def->name); +- goto endjob; +- } +- + /* handle the event - restart the passt process with its original + * parameters + */ +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-respond-to-NETDEV_VHOST_USER_DISCONNECTED-event.patch b/SOURCES/libvirt-qemu-respond-to-NETDEV_VHOST_USER_DISCONNECTED-event.patch new file mode 100644 index 0000000..6a1d575 --- /dev/null +++ b/SOURCES/libvirt-qemu-respond-to-NETDEV_VHOST_USER_DISCONNECTED-event.patch @@ -0,0 +1,224 @@ +From 874251dd0b6fdbf3a0be8e494f83001e5f028868 Mon Sep 17 00:00:00 2001 +Message-ID: <874251dd0b6fdbf3a0be8e494f83001e5f028868.1744361503.git.jdenemar@redhat.com> +From: Laine Stump +Date: Fri, 4 Apr 2025 17:16:43 -0400 +Subject: [PATCH] qemu: respond to NETDEV_VHOST_USER_DISCONNECTED event + +This response to this event is identical to NETDEV_STREAM_DISCONNECTED +(start a new passt process to replace the one that just disappeared - +see commitf62ce81b8a5), except that the new passt process will have +"--vhost-user" appended to the commandline. Fortunately that +difference is already handled based on the virDomainNetDef contents, +so we can, in fact, respond to the new event in exactly the same +manner. + +Signed-off-by: Laine Stump +Tested-by: Stefano Brivio +Reviewed-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit dedf1ada95f046310827194eb8794fa18975b9e7) + +Conflicts: + +src/qemu/qemu_driver.c: + In context surrounding a chunk, the arguments to + processNicRxFilterChangedEvent() changed upstream (due to upstream + commit 50981052a5f) + +https://issues.redhat.com/browse/RHEL-84782 +Signed-off-by: Laine Stump +--- + src/qemu/qemu_domain.c | 1 + + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_driver.c | 11 +++++++++++ + src/qemu/qemu_monitor.c | 11 +++++++++++ + src/qemu/qemu_monitor.h | 6 ++++++ + src/qemu/qemu_monitor_json.c | 16 ++++++++++++++++ + src/qemu/qemu_process.c | 18 ++++++++++++++++++ + 7 files changed, 64 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 92035dd281..95cca36fe1 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -10036,6 +10036,7 @@ qemuProcessEventFree(struct qemuProcessEvent *event) + case QEMU_PROCESS_EVENT_WATCHDOG: + case QEMU_PROCESS_EVENT_DEVICE_DELETED: + case QEMU_PROCESS_EVENT_NETDEV_STREAM_DISCONNECTED: ++ case QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED: + case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED: + case QEMU_PROCESS_EVENT_SERIAL_CHANGED: + case QEMU_PROCESS_EVENT_GUEST_CRASHLOADED: +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index e810f79599..79bdc4e8fe 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -465,6 +465,7 @@ typedef enum { + QEMU_PROCESS_EVENT_GUESTPANIC, + QEMU_PROCESS_EVENT_DEVICE_DELETED, + QEMU_PROCESS_EVENT_NETDEV_STREAM_DISCONNECTED, ++ QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED, + QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED, + QEMU_PROCESS_EVENT_SERIAL_CHANGED, + QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE, +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 65e17a870d..d65fc542d1 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -3691,6 +3691,14 @@ processNetdevStreamDisconnectedEvent(virDomainObj *vm, + } + + ++static void ++processNetdevVhostUserDisconnectedEvent(virDomainObj *vm, ++ const char *netdevId) ++{ ++ processNetdevDisconnectedEvent(vm, netdevId, "NETDEV_VHOST_USER_DISCONNECTED"); ++} ++ ++ + static void + processNicRxFilterChangedEvent(virDomainObj *vm, + const char *devAlias) +@@ -4086,6 +4094,9 @@ static void qemuProcessEventHandler(void *data, void *opaque) + case QEMU_PROCESS_EVENT_NETDEV_STREAM_DISCONNECTED: + processNetdevStreamDisconnectedEvent(vm, processEvent->data); + break; ++ case QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED: ++ processNetdevVhostUserDisconnectedEvent(vm, processEvent->data); ++ break; + case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED: + processNicRxFilterChangedEvent(vm, processEvent->data); + break; +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 82aa1cbc5f..ed63b7a29b 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1267,6 +1267,17 @@ qemuMonitorEmitNetdevStreamDisconnected(qemuMonitor *mon, + } + + ++void ++qemuMonitorEmitNetdevVhostUserDisconnected(qemuMonitor *mon, ++ const char *devAlias) ++{ ++ VIR_DEBUG("mon=%p", mon); ++ ++ QEMU_MONITOR_CALLBACK(mon, domainNetdevVhostUserDisconnected, ++ mon->vm, devAlias); ++} ++ ++ + void + qemuMonitorEmitSerialChange(qemuMonitor *mon, + const char *devAlias, +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 672cd6487e..bcb39409ac 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -255,6 +255,9 @@ typedef void (*qemuMonitorDomainDeviceUnplugErrCallback)(qemuMonitor *mon, + typedef void (*qemuMonitorDomainNetdevStreamDisconnectedCallback)(qemuMonitor *mon, + virDomainObj *vm, + const char *devAlias); ++typedef void (*qemuMonitorDomainNetdevVhostUserDisconnectedCallback)(qemuMonitor *mon, ++ virDomainObj *vm, ++ const char *devAlias); + typedef void (*qemuMonitorDomainNicRxFilterChangedCallback)(qemuMonitor *mon, + virDomainObj *vm, + const char *devAlias); +@@ -403,6 +406,7 @@ struct _qemuMonitorCallbacks { + qemuMonitorDomainMemoryDeviceSizeChange domainMemoryDeviceSizeChange; + qemuMonitorDomainDeviceUnplugErrCallback domainDeviceUnplugError; + qemuMonitorDomainNetdevStreamDisconnectedCallback domainNetdevStreamDisconnected; ++ qemuMonitorDomainNetdevVhostUserDisconnectedCallback domainNetdevVhostUserDisconnected; + }; + + qemuMonitor *qemuMonitorOpen(virDomainObj *vm, +@@ -490,6 +494,8 @@ void qemuMonitorEmitDeviceUnplugErr(qemuMonitor *mon, + const char *devAlias); + void qemuMonitorEmitNetdevStreamDisconnected(qemuMonitor *mon, + const char *devAlias); ++void qemuMonitorEmitNetdevVhostUserDisconnected(qemuMonitor *mon, ++ const char *devAlias); + void qemuMonitorEmitNicRxFilterChanged(qemuMonitor *mon, + const char *devAlias); + void qemuMonitorEmitSerialChange(qemuMonitor *mon, +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 6f9f495888..be5d3be7e6 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -85,6 +85,7 @@ static void qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon, virJSONValue *d + static void qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon, virJSONValue *data); + static void qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data); + static void qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *data); ++static void qemuMonitorJSONHandleNetdevVhostUserDisconnected(qemuMonitor *mon, virJSONValue *data); + + typedef struct { + const char *type; +@@ -108,6 +109,7 @@ static qemuEventHandler eventHandlers[] = { + { "MIGRATION", qemuMonitorJSONHandleMigrationStatus, }, + { "MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass, }, + { "NETDEV_STREAM_DISCONNECTED", qemuMonitorJSONHandleNetdevStreamDisconnected, }, ++ { "NETDEV_VHOST_USER_DISCONNECTED", qemuMonitorJSONHandleNetdevVhostUserDisconnected, }, + { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, }, + { "PR_MANAGER_STATUS_CHANGED", qemuMonitorJSONHandlePRManagerStatusChanged, }, + { "RDMA_GID_STATUS_CHANGED", qemuMonitorJSONHandleRdmaGidStatusChanged, }, +@@ -1044,6 +1046,20 @@ qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *da + } + + ++static void ++qemuMonitorJSONHandleNetdevVhostUserDisconnected(qemuMonitor *mon, virJSONValue *data) ++{ ++ const char *name; ++ ++ if (!(name = virJSONValueObjectGetString(data, "netdev-id"))) { ++ VIR_WARN("missing device in NETDEV_VHOST_USER_DISCONNECTED event"); ++ return; ++ } ++ ++ qemuMonitorEmitNetdevVhostUserDisconnected(mon, name); ++} ++ ++ + static void + qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor *mon, virJSONValue *data) + { +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 722e982b9e..f5c277203f 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -1402,6 +1402,23 @@ qemuProcessHandleNetdevStreamDisconnected(qemuMonitor *mon G_GNUC_UNUSED, + } + + ++static void ++qemuProcessHandleNetdevVhostUserDisconnected(qemuMonitor *mon G_GNUC_UNUSED, ++ virDomainObj *vm, ++ const char *devAlias) ++{ ++ virObjectLock(vm); ++ ++ VIR_DEBUG("Device %s Netdev vhost-user Disconnected in domain %p %s", ++ devAlias, vm, vm->def->name); ++ ++ qemuProcessEventSubmit(vm, QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED, ++ 0, 0, g_strdup(devAlias)); ++ ++ virObjectUnlock(vm); ++} ++ ++ + static void + qemuProcessHandleNicRxFilterChanged(qemuMonitor *mon G_GNUC_UNUSED, + virDomainObj *vm, +@@ -1848,6 +1865,7 @@ static qemuMonitorCallbacks monitorCallbacks = { + .domainMemoryDeviceSizeChange = qemuProcessHandleMemoryDeviceSizeChange, + .domainDeviceUnplugError = qemuProcessHandleDeviceUnplugErr, + .domainNetdevStreamDisconnected = qemuProcessHandleNetdevStreamDisconnected, ++ .domainNetdevVhostUserDisconnected = qemuProcessHandleNetdevVhostUserDisconnected, + }; + + static void +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-snapshot-error-out-early-when-reverting-snapshot-for-VM-with-non-file-disk.patch b/SOURCES/libvirt-qemu-snapshot-error-out-early-when-reverting-snapshot-for-VM-with-non-file-disk.patch deleted file mode 100644 index 40c8120..0000000 --- a/SOURCES/libvirt-qemu-snapshot-error-out-early-when-reverting-snapshot-for-VM-with-non-file-disk.patch +++ /dev/null @@ -1,75 +0,0 @@ -From c9c9405687b78713b913c09113697fcadec1cdba Mon Sep 17 00:00:00 2001 -Message-ID: -From: Pavel Hrdina -Date: Wed, 26 Feb 2025 11:04:52 +0100 -Subject: [PATCH] qemu: snapshot: error out early when reverting snapshot for - VM with non-file disk - -Before this patch the code would start the revert process by destroying -the VM and preparing to revert where it would fail with following error: - - error: unsupported configuration: source for disk 'sdb' is not a regular file; refusing to generate external snapshot name - -and leaving user with offline VM even if it was running. - -Make the check before we start the revert process to not destroy VMs. - -Resolves: https://issues.redhat.com/browse/RHEL-30971 -Resolves: https://issues.redhat.com/browse/RHEL-79928 -Signed-off-by: Pavel Hrdina -Reviewed-by: Peter Krempa -(cherry picked from commit 278b8334eb26aa9495f6d37e4f72471cbc8739a6) - -Signed-off-by: Pavel Hrdina ---- - src/qemu/qemu_snapshot.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c -index 3a8510c69e..16d3aaf6e7 100644 ---- a/src/qemu/qemu_snapshot.c -+++ b/src/qemu/qemu_snapshot.c -@@ -2190,6 +2190,8 @@ qemuSnapshotRevertValidate(virDomainObj *vm, - virDomainSnapshotDef *snapdef, - unsigned int flags) - { -+ size_t i; -+ - if (!vm->persistent && - snapdef->state != VIR_DOMAIN_SNAPSHOT_RUNNING && - snapdef->state != VIR_DOMAIN_SNAPSHOT_PAUSED && -@@ -2217,6 +2219,22 @@ qemuSnapshotRevertValidate(virDomainObj *vm, - } - } - -+ /* Reverting to external snapshot creates overlay files for every disk and -+ * it would fail for non-file based disks. -+ * See qemuSnapshotRevertExternalPrepare for more details. */ -+ if (virDomainSnapshotIsExternal(snap)) { -+ for (i = 0; i < snap->def->dom->ndisks; i++) { -+ virDomainDiskDef *disk = snap->def->dom->disks[i]; -+ -+ if (disk->src->type != VIR_STORAGE_TYPE_FILE) { -+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, -+ _("source disk for '%1$s' is not a regular file, reverting to snapshot is not supported"), -+ disk->dst); -+ return -1; -+ } -+ } -+ } -+ - return 0; - } - -@@ -2368,6 +2386,9 @@ qemuSnapshotRevertExternalPrepare(virDomainObj *vm, - if (virDomainMomentDefPostParse(&tmpsnapdef->parent) < 0) - return -1; - -+ /* Force default location to be external in order to create overlay files -+ * for every disk. In qemuSnapshotRevertValidate we make sure that each -+ * disk is regular file otherwise this would fail. */ - if (virDomainSnapshotAlignDisks(tmpsnapdef, domdef, - VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL, - false, true) < 0) { --- -2.48.1 diff --git a/SOURCES/libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch b/SOURCES/libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch new file mode 100644 index 0000000..21d6210 --- /dev/null +++ b/SOURCES/libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch @@ -0,0 +1,163 @@ +From 4e04c0a27ced260053815b2348474ef7226aabb7 Mon Sep 17 00:00:00 2001 +Message-ID: <4e04c0a27ced260053815b2348474ef7226aabb7.1745925135.git.jdenemar@redhat.com> +From: Martin Kletzander +Date: Tue, 25 Feb 2025 15:23:07 +0100 +Subject: [PATCH] qemu_agent: Add qemuAgentGetLoadAvg() + +With qemu guest agent 9.3 we are able to get the load averages with a +new command. + +Signed-off-by: Martin Kletzander +Reviewed-by: Peter Krempa +(cherry picked from commit 1669d91eade46b930ebb44e4b9d398ea8c2064e7) + +https://issues.redhat.com/browse/RHEL-88449 + +Signed-off-by: Martin Kletzander +--- + src/qemu/qemu_agent.c | 46 +++++++++++++++++++++++++++++++++++++ + src/qemu/qemu_agent.h | 6 +++++ + tests/qemuagenttest.c | 53 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 105 insertions(+) + +diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c +index 43fca86f10..16a6eaa998 100644 +--- a/src/qemu/qemu_agent.c ++++ b/src/qemu/qemu_agent.c +@@ -2568,3 +2568,49 @@ int qemuAgentGetDisks(qemuAgent *agent, + g_free(*disks); + return -1; + } ++ ++ ++int ++qemuAgentGetLoadAvg(qemuAgent *agent, ++ double *load1m, ++ double *load5m, ++ double *load15m, ++ bool report_unsupported) ++{ ++ g_autoptr(virJSONValue) cmd = NULL; ++ g_autoptr(virJSONValue) reply = NULL; ++ virJSONValue *data = NULL; ++ int rc; ++ ++ if (!(cmd = qemuAgentMakeCommand("guest-get-load", NULL))) ++ return -1; ++ ++ if ((rc = qemuAgentCommandFull(agent, cmd, &reply, agent->timeout, ++ report_unsupported)) < 0) ++ return rc; ++ ++ if (!(data = virJSONValueObjectGetObject(reply, "return"))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("qemu agent didn't return an array of loads")); ++ return -1; ++ } ++ ++#define GET_NUMBER_PARAM(param_) \ ++ do { \ ++ if (param_ && \ ++ virJSONValueObjectGetNumberDouble(data, #param_, param_) < 0) { \ ++ virReportError(VIR_ERR_INTERNAL_ERROR, \ ++ _("parameter '%1$s' is missing in reply of guest-get-load"), \ ++ #param_); \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++ GET_NUMBER_PARAM(load1m); ++ GET_NUMBER_PARAM(load5m); ++ GET_NUMBER_PARAM(load15m); ++ ++#undef GET_NUMBER_PARAM ++ ++ return 0; ++} +diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h +index f98586e8f8..cd17a98d39 100644 +--- a/src/qemu/qemu_agent.h ++++ b/src/qemu/qemu_agent.h +@@ -195,3 +195,9 @@ int qemuAgentSSHRemoveAuthorizedKeys(qemuAgent *agent, + int qemuAgentGetDisks(qemuAgent *mon, + qemuAgentDiskInfo ***disks, + bool report_unsupported); ++ ++int qemuAgentGetLoadAvg(qemuAgent *agent, ++ double *load1m, ++ double *load5m, ++ double *load15m, ++ bool report_unsupported); +diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c +index 3287880241..566571cf11 100644 +--- a/tests/qemuagenttest.c ++++ b/tests/qemuagenttest.c +@@ -1356,6 +1356,58 @@ testQemuAgentTimezone(const void *data) + virTypedParamsFree(params, nparams); + return ret; + } ++ ++ ++static const char testQemuAgentGetLoadAvgResponse[] = ++ "{" ++ " \"return\": {" ++ " \"load15m\": 0.03564453125," ++ " \"load5m\": 0.064453125," ++ " \"load1m\": 0.00390625" ++ " }" ++ "}"; ++ ++static int ++testQemuAgentGetLoadAvg(const void *data) ++{ ++ virDomainXMLOption *xmlopt = (virDomainXMLOption *)data; ++ g_autoptr(qemuMonitorTest) test = qemuMonitorTestNewAgent(xmlopt); ++ double load1m = 0; ++ double load5m = 0; ++ double load15m = 0; ++ ++ if (!test) ++ return -1; ++ ++ if (qemuMonitorTestAddAgentSyncResponse(test) < 0) ++ return -1; ++ ++ if (qemuMonitorTestAddItem(test, "guest-get-load", ++ testQemuAgentGetLoadAvgResponse) < 0) ++ return -1; ++ ++ if (qemuAgentGetLoadAvg(qemuMonitorTestGetAgent(test), ++ &load1m, &load5m, &load15m, true) < 0) ++ return -1; ++ ++#define VALIDATE_LOAD(value_, expected_) \ ++ do { \ ++ if (value_ != expected_) { \ ++ virReportError(VIR_ERR_INTERNAL_ERROR, \ ++ "Expected " #value_ " '%.11f', got '%.11f'", \ ++ expected_, value_); \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++ VALIDATE_LOAD(load1m, 0.00390625); ++ VALIDATE_LOAD(load5m, 0.064453125); ++ VALIDATE_LOAD(load15m, 0.03564453125); ++ ++ return 0; ++} ++ ++ + static int + mymain(void) + { +@@ -1392,6 +1444,7 @@ mymain(void) + DO_TEST(Timezone); + DO_TEST(SSHKeys); + DO_TEST(GetDisks); ++ DO_TEST(GetLoadAvg); + + DO_TEST(Timeout); /* Timeout should always be called last */ + +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu_snapshot-allow-reverting-to-external-disk-only-snapshot.patch b/SOURCES/libvirt-qemu_snapshot-allow-reverting-to-external-disk-only-snapshot.patch deleted file mode 100644 index 1354549..0000000 --- a/SOURCES/libvirt-qemu_snapshot-allow-reverting-to-external-disk-only-snapshot.patch +++ /dev/null @@ -1,50 +0,0 @@ -From b0282d5149f90b155a38881f92e3263bd23d9878 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Pavel Hrdina -Date: Wed, 31 Jan 2024 17:14:28 +0100 -Subject: [PATCH] qemu_snapshot: allow reverting to external disk only snapshot - -When snapshot is created with disk-only flag it is always external -snapshot without memory state. Historically when there was not support -to revert external snapshots this produced error message. - - error: Failed to revert snapshot s1 - error: internal error: Invalid target domain state 'disk-snapshot'. Refusing snapshot reversion - -Now we can simply consider this as reverting to offline snapshot as the -possible damage to file system is already done at the point of snapshot -creation. - -Resolves: https://issues.redhat.com/browse/RHEL-21549 -Signed-off-by: Pavel Hrdina -Reviewed-by: Peter Krempa -(cherry picked from commit 443ae4adec3a94a575ea2acaa112188e721c7dfe) - -Signed-off-by: Pavel Hrdina ---- - src/qemu/qemu_snapshot.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c -index b1f4ebb995..3a8510c69e 100644 ---- a/src/qemu/qemu_snapshot.c -+++ b/src/qemu/qemu_snapshot.c -@@ -2884,6 +2884,7 @@ qemuSnapshotRevert(virDomainObj *vm, - case VIR_DOMAIN_SNAPSHOT_SHUTDOWN: - case VIR_DOMAIN_SNAPSHOT_SHUTOFF: - case VIR_DOMAIN_SNAPSHOT_CRASHED: -+ case VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT: - ret = qemuSnapshotRevertInactive(vm, snapshot, snap, - driver, cfg, - &inactiveConfig, -@@ -2895,8 +2896,6 @@ qemuSnapshotRevert(virDomainObj *vm, - _("qemu doesn't support reversion of snapshot taken in PMSUSPENDED state")); - goto endjob; - -- case VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT: -- /* Rejected earlier as an external snapshot */ - case VIR_DOMAIN_SNAPSHOT_NOSTATE: - case VIR_DOMAIN_SNAPSHOT_BLOCKED: - case VIR_DOMAIN_SNAPSHOT_LAST: --- -2.48.1 diff --git a/SOURCES/libvirt-remote-add-sysusers-file-to-create-libvirt-group.patch b/SOURCES/libvirt-remote-add-sysusers-file-to-create-libvirt-group.patch index c2c5c4a..4258c9a 100644 --- a/SOURCES/libvirt-remote-add-sysusers-file-to-create-libvirt-group.patch +++ b/SOURCES/libvirt-remote-add-sysusers-file-to-create-libvirt-group.patch @@ -1,5 +1,5 @@ -From 44fc545f45e2e0077fbdc9d45bf8743d115fca35 Mon Sep 17 00:00:00 2001 -Message-ID: <44fc545f45e2e0077fbdc9d45bf8743d115fca35.1741876175.git.jdenemar@redhat.com> +From 4aa0ea0a693e06110333a8f851525d0e5a8fcfed Mon Sep 17 00:00:00 2001 +Message-ID: <4aa0ea0a693e06110333a8f851525d0e5a8fcfed.1741351378.git.jdenemar@redhat.com> From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 29 Jan 2025 15:37:46 +0000 Subject: [PATCH] remote: add sysusers file to create 'libvirt' group @@ -17,7 +17,7 @@ Reviewed-by: Jiri Denemark Signed-off-by: Daniel P. Berrangé (cherry picked from commit 18f0160994af80dfac2dcaf46097922e443b283b) -https://issues.redhat.com/browse/RHEL-81749 +https://issues.redhat.com/browse/RHEL-81740 Signed-off-by: Andrea Bolognani --- diff --git a/SOURCES/libvirt-rpc-remove-logind-support-for-virNetDaemon.patch b/SOURCES/libvirt-rpc-remove-logind-support-for-virNetDaemon.patch new file mode 100644 index 0000000..109c3a0 --- /dev/null +++ b/SOURCES/libvirt-rpc-remove-logind-support-for-virNetDaemon.patch @@ -0,0 +1,202 @@ +From 4c6d50cb9675f59c8ba2e5bc4fc424cb3b8f5527 Mon Sep 17 00:00:00 2001 +Message-ID: <4c6d50cb9675f59c8ba2e5bc4fc424cb3b8f5527.1744361503.git.jdenemar@redhat.com> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Mon, 16 Dec 2024 16:37:52 +0000 +Subject: [PATCH] rpc: remove logind support for virNetDaemon +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virNetDaemon code now only concerns itself with preventing auto +shutdown of the local daemon. Logind is now handled by the new +virInhibitor object, for QEMU, LXC and LibXL. This fixes two notable +bugs + + * Running virtual networks would prevent system shutdown + * Loaded ephemeral secrets would prevent system shutdown + +Fixes 9e3cc0ff5e81ed2056a6a528893fd2cb5609d70b +Fixes 37800af9a400385801da6d73654249fdb51a93d8 +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 8575724aef4f48f3d66cb7beb4c61014992e31eb) +Resolves: https://issues.redhat.com/browse/RHEL-83076 +--- + src/libxl/libxl_driver.c | 2 +- + src/lxc/lxc_driver.c | 2 +- + src/qemu/qemu_driver.c | 2 +- + src/rpc/virnetdaemon.c | 78 ---------------------------------------- + 4 files changed, 3 insertions(+), 81 deletions(-) + +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index ecd6ea9fa8..2a4f31f93c 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -707,7 +707,7 @@ libxlStateInitialize(bool privileged, + goto error; + + libxl_driver->inhibitor = virInhibitorNew( +- VIR_INHIBITOR_WHAT_NONE, ++ VIR_INHIBITOR_WHAT_SHUTDOWN, + _("Libvirt Xen"), + _("Xen virtual machines are running"), + VIR_INHIBITOR_MODE_DELAY, +diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c +index 9ee771c62a..72b950ac8a 100644 +--- a/src/lxc/lxc_driver.c ++++ b/src/lxc/lxc_driver.c +@@ -1488,7 +1488,7 @@ lxcStateInitialize(bool privileged, + goto cleanup; + + lxc_driver->inhibitor = virInhibitorNew( +- VIR_INHIBITOR_WHAT_NONE, ++ VIR_INHIBITOR_WHAT_SHUTDOWN, + _("Libvirt LXC"), + _("LXC containers are running"), + VIR_INHIBITOR_MODE_DELAY, +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 5b911d5221..f8f3d2c725 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -673,7 +673,7 @@ qemuStateInitialize(bool privileged, + } + + qemu_driver->inhibitor = virInhibitorNew( +- VIR_INHIBITOR_WHAT_NONE, ++ VIR_INHIBITOR_WHAT_SHUTDOWN, + _("Libvirt QEMU"), + _("QEMU/KVM virtual machines are running"), + VIR_INHIBITOR_MODE_DELAY, +diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c +index 9795418126..e4c6261536 100644 +--- a/src/rpc/virnetdaemon.c ++++ b/src/rpc/virnetdaemon.c +@@ -31,7 +31,6 @@ + #include "virutil.h" + #include "virfile.h" + #include "virnetserver.h" +-#include "virgdbus.h" + #include "virhash.h" + #include "virprocess.h" + #include "virsystemd.h" +@@ -80,7 +79,6 @@ struct _virNetDaemon { + int autoShutdownTimerID; + bool autoShutdownTimerActive; + size_t autoShutdownInhibitions; +- int autoShutdownInhibitFd; + }; + + +@@ -109,7 +107,6 @@ virNetDaemonDispose(void *obj) + virEventRemoveHandle(dmn->sigwatch); + #endif /* !WIN32 */ + +- VIR_FORCE_CLOSE(dmn->autoShutdownInhibitFd); + g_free(dmn->stateStopThread); + + g_clear_pointer(&dmn->servers, g_hash_table_unref); +@@ -150,7 +147,6 @@ virNetDaemonNew(void) + #endif /* !WIN32 */ + + dmn->privileged = geteuid() == 0; +- dmn->autoShutdownInhibitFd = -1; + + virProcessActivateMaxFiles(); + +@@ -491,66 +487,6 @@ virNetDaemonAutoShutdown(virNetDaemon *dmn, + } + + +-#ifdef G_OS_UNIX +-/* As per: https://www.freedesktop.org/wiki/Software/systemd/inhibit */ +-static void +-virNetDaemonCallInhibit(virNetDaemon *dmn, +- const char *what, +- const char *who, +- const char *why, +- const char *mode) +-{ +- g_autoptr(GVariant) reply = NULL; +- g_autoptr(GUnixFDList) replyFD = NULL; +- g_autoptr(GVariant) message = NULL; +- GDBusConnection *systemBus; +- int fd; +- int rc; +- +- VIR_DEBUG("dmn=%p what=%s who=%s why=%s mode=%s", +- dmn, NULLSTR(what), NULLSTR(who), NULLSTR(why), NULLSTR(mode)); +- +- if (virSystemdHasLogind() < 0) +- return; +- +- if (!(systemBus = virGDBusGetSystemBus())) +- return; +- +- message = g_variant_new("(ssss)", what, who, why, mode); +- +- rc = virGDBusCallMethodWithFD(systemBus, +- &reply, +- G_VARIANT_TYPE("(h)"), +- &replyFD, +- NULL, +- "org.freedesktop.login1", +- "/org/freedesktop/login1", +- "org.freedesktop.login1.Manager", +- "Inhibit", +- message, +- NULL); +- +- if (rc < 0) +- return; +- +- if (g_unix_fd_list_get_length(replyFD) <= 0) +- return; +- +- fd = g_unix_fd_list_get(replyFD, 0, NULL); +- if (fd < 0) +- return; +- +- if (dmn->autoShutdownInhibitions) { +- dmn->autoShutdownInhibitFd = fd; +- VIR_DEBUG("Got inhibit FD %d", fd); +- } else { +- /* We stopped the last VM since we made the inhibit call */ +- VIR_DEBUG("Closing inhibit FD %d", fd); +- VIR_FORCE_CLOSE(fd); +- } +-} +-#endif +- + void + virNetDaemonAddShutdownInhibition(virNetDaemon *dmn) + { +@@ -559,15 +495,6 @@ virNetDaemonAddShutdownInhibition(virNetDaemon *dmn) + dmn->autoShutdownInhibitions++; + + VIR_DEBUG("dmn=%p inhibitions=%zu", dmn, dmn->autoShutdownInhibitions); +- +-#ifdef G_OS_UNIX +- if (dmn->autoShutdownInhibitions == 1) +- virNetDaemonCallInhibit(dmn, +- "shutdown", +- _("Libvirt"), +- _("Virtual machines need to be saved"), +- "delay"); +-#endif + } + + +@@ -579,11 +506,6 @@ virNetDaemonRemoveShutdownInhibition(virNetDaemon *dmn) + dmn->autoShutdownInhibitions--; + + VIR_DEBUG("dmn=%p inhibitions=%zu", dmn, dmn->autoShutdownInhibitions); +- +- if (dmn->autoShutdownInhibitions == 0) { +- VIR_DEBUG("Closing inhibit FD %d", dmn->autoShutdownInhibitFd); +- VIR_FORCE_CLOSE(dmn->autoShutdownInhibitFd); +- } + } + + +-- +2.49.0 diff --git a/SOURCES/libvirt-src-convert-drivers-over-to-new-virInhibitor-APIs.patch b/SOURCES/libvirt-src-convert-drivers-over-to-new-virInhibitor-APIs.patch new file mode 100644 index 0000000..b6b2497 --- /dev/null +++ b/SOURCES/libvirt-src-convert-drivers-over-to-new-virInhibitor-APIs.patch @@ -0,0 +1,549 @@ +From fd7a63d7b6be85cb60b7157de52d28f5c76bdf42 Mon Sep 17 00:00:00 2001 +Message-ID: +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Mon, 16 Dec 2024 16:28:48 +0000 +Subject: [PATCH] src: convert drivers over to new virInhibitor APIs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This initial conversion of the drivers switches them over to use +the virInhibitor APIs in local daemon only mode. Communication to +logind is still handled by the virNetDaemon class logic. + +This mostly just replaces upto 3 fields in the driver state +with a single new virInhibitor object, but otherwise should not +change functionality besides replacing atomics with mutex protected +APIs. + +The exception is the LXC driver which has been trying to inhibit +shutdown shutdown but silently failing to, since nothing ever +remembered to set the 'inhibitCallback' pointer in the driver +state struct. + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 48f0b6dfa12563f0006d2de4b0f85599e20f9449) +Resolves: https://issues.redhat.com/browse/RHEL-83076 +--- + src/libxl/libxl_conf.h | 9 +++---- + src/libxl/libxl_domain.c | 6 ++--- + src/libxl/libxl_driver.c | 15 +++++++---- + src/lxc/lxc_conf.h | 9 +++---- + src/lxc/lxc_driver.c | 13 +++++++-- + src/lxc/lxc_process.c | 9 +++---- + src/network/bridge_driver.c | 20 +++++++------- + src/network/bridge_driver_conf.h | 9 +++---- + src/qemu/qemu_conf.h | 9 +++---- + src/qemu/qemu_driver.c | 12 ++++++--- + src/qemu/qemu_process.c | 9 +++---- + src/secret/secret_driver.c | 46 +++++++++++++------------------- + 12 files changed, 80 insertions(+), 86 deletions(-) + +diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h +index 7087b41079..0edcde079d 100644 +--- a/src/libxl/libxl_conf.h ++++ b/src/libxl/libxl_conf.h +@@ -35,6 +35,7 @@ + #include "virfirmware.h" + #include "libxl_capabilities.h" + #include "libxl_logger.h" ++#include "virinhibitor.h" + + #define LIBXL_DRIVER_EXTERNAL_NAME "Xen" + /* +@@ -117,12 +118,8 @@ struct _libxlDriverPrivate { + /* pid file FD, ensures two copies of the driver can't use the same root */ + int lockFD; + +- /* Atomic inc/dec only */ +- unsigned int nactive; +- +- /* Immutable pointers. Caller must provide locking */ +- virStateInhibitCallback inhibitCallback; +- void *inhibitOpaque; ++ /* Immutable pointer, self-locking APIs */ ++ virInhibitor *inhibitor; + + /* Immutable pointer, self-locking APIs */ + virDomainObjList *domains; +diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c +index 711e22b8df..6805160923 100644 +--- a/src/libxl/libxl_domain.c ++++ b/src/libxl/libxl_domain.c +@@ -873,8 +873,7 @@ libxlDomainCleanup(libxlDriverPrivate *driver, + priv->deathW = NULL; + } + +- if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback) +- driver->inhibitCallback(false, driver->inhibitOpaque); ++ virInhibitorRelease(driver->inhibitor); + + /* Release auto-allocated graphics ports */ + for (i = 0; i < vm->def->ngraphics; i++) { +@@ -1418,8 +1417,7 @@ libxlDomainStart(libxlDriverPrivate *driver, + return -1; + } + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, + restore_fd < 0 ? +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index b670e697c6..ecd6ea9fa8 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -437,8 +437,7 @@ libxlReconnectDomain(virDomainObj *vm, + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNKNOWN); + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + /* Enable domain death events */ + libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW); +@@ -514,6 +513,7 @@ libxlStateCleanup(void) + + virObjectUnref(libxl_driver->domainEventState); + virSysinfoDefFree(libxl_driver->hostsysinfo); ++ virInhibitorFree(libxl_driver->inhibitor); + + if (libxl_driver->lockFD != -1) + virPidFileRelease(libxl_driver->config->stateDir, "driver", libxl_driver->lockFD); +@@ -675,9 +675,6 @@ libxlStateInitialize(bool privileged, + return VIR_DRV_STATE_INIT_ERROR; + } + +- libxl_driver->inhibitCallback = callback; +- libxl_driver->inhibitOpaque = opaque; +- + /* Allocate bitmap for vnc port reservation */ + if (!(libxl_driver->reservedGraphicsPorts = + virPortAllocatorRangeNew(_("VNC"), +@@ -709,6 +706,14 @@ libxlStateInitialize(bool privileged, + if (libxlDriverConfigLoadFile(cfg, driverConf) < 0) + goto error; + ++ libxl_driver->inhibitor = virInhibitorNew( ++ VIR_INHIBITOR_WHAT_NONE, ++ _("Libvirt Xen"), ++ _("Xen virtual machines are running"), ++ VIR_INHIBITOR_MODE_DELAY, ++ callback, ++ opaque); ++ + /* Register the callbacks providing access to libvirt's event loop */ + libxl_osevent_register_hooks(cfg->ctx, &libxl_osevent_callbacks, cfg->ctx); + +diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h +index c0967ac63b..73c60c7ebf 100644 +--- a/src/lxc/lxc_conf.h ++++ b/src/lxc/lxc_conf.h +@@ -30,6 +30,7 @@ + #include "virsysinfo.h" + #include "virclosecallbacks.h" + #include "virhostdev.h" ++#include "virinhibitor.h" + + #define LXC_DRIVER_NAME "LXC" + +@@ -76,12 +77,8 @@ struct _virLXCDriver { + /* Immutable pointer, lockless APIs */ + virSysinfoDef *hostsysinfo; + +- /* Atomic inc/dec only */ +- unsigned int nactive; +- +- /* Immutable pointers. Caller must provide locking */ +- virStateInhibitCallback inhibitCallback; +- void *inhibitOpaque; ++ /* Immutable pointer, self-locking APIs */ ++ virInhibitor *inhibitor; + + /* Immutable pointer, self-locking APIs */ + virDomainObjList *domains; +diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c +index 9609d7d10c..9ee771c62a 100644 +--- a/src/lxc/lxc_driver.c ++++ b/src/lxc/lxc_driver.c +@@ -1433,8 +1433,8 @@ static virDrvStateInitResult + lxcStateInitialize(bool privileged, + const char *root, + bool monolithic G_GNUC_UNUSED, +- virStateInhibitCallback callback G_GNUC_UNUSED, +- void *opaque G_GNUC_UNUSED) ++ virStateInhibitCallback callback, ++ void *opaque) + { + virLXCDriverConfig *cfg = NULL; + bool autostart = true; +@@ -1487,6 +1487,14 @@ lxcStateInitialize(bool privileged, + if (virLXCLoadDriverConfig(cfg, SYSCONFDIR "/libvirt/lxc.conf") < 0) + goto cleanup; + ++ lxc_driver->inhibitor = virInhibitorNew( ++ VIR_INHIBITOR_WHAT_NONE, ++ _("Libvirt LXC"), ++ _("LXC containers are running"), ++ VIR_INHIBITOR_MODE_DELAY, ++ callback, ++ opaque); ++ + if (!(lxc_driver->securityManager = lxcSecurityInit(cfg))) + goto cleanup; + +@@ -1591,6 +1599,7 @@ static int lxcStateCleanup(void) + virObjectUnref(lxc_driver->caps); + virObjectUnref(lxc_driver->securityManager); + virObjectUnref(lxc_driver->xmlopt); ++ virInhibitorFree(lxc_driver->inhibitor); + + if (lxc_driver->lockFD != -1) + virPidFileRelease(lxc_driver->config->stateDir, "driver", lxc_driver->lockFD); +diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c +index cd8bcfc282..c2982244f0 100644 +--- a/src/lxc/lxc_process.c ++++ b/src/lxc/lxc_process.c +@@ -203,8 +203,7 @@ static void virLXCProcessCleanup(virLXCDriver *driver, + vm->pid = 0; + vm->def->id = -1; + +- if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback) +- driver->inhibitCallback(false, driver->inhibitOpaque); ++ virInhibitorRelease(driver->inhibitor); + + virLXCDomainReAttachHostDevices(driver, vm->def); + +@@ -1466,8 +1465,7 @@ int virLXCProcessStart(virLXCDriver * driver, + if (virCommandHandshakeNotify(cmd) < 0) + goto cleanup; + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + /* The first synchronization point is when the controller creates CGroups. */ + if (lxcContainerWaitForContinue(handshakefds[0]) < 0) { +@@ -1665,8 +1663,7 @@ virLXCProcessReconnectDomain(virDomainObj *vm, + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNKNOWN); + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm))) + goto error; +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index e700a614a9..ce793c12ef 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -504,8 +504,7 @@ networkUpdateState(virNetworkObj *obj, + if (virNetworkObjIsActive(obj)) { + virNetworkObjPortForEach(obj, networkUpdatePort, obj); + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + } + + /* Try and read dnsmasq pids of both active and inactive networks, just in +@@ -644,9 +643,6 @@ networkStateInitialize(bool privileged, + goto error; + } + +- network_driver->inhibitCallback = callback; +- network_driver->inhibitOpaque = opaque; +- + network_driver->privileged = privileged; + + if (!(network_driver->xmlopt = networkDnsmasqCreateXMLConf())) +@@ -655,6 +651,14 @@ networkStateInitialize(bool privileged, + if (!(network_driver->config = cfg = virNetworkDriverConfigNew(privileged))) + goto error; + ++ network_driver->inhibitor = virInhibitorNew( ++ VIR_INHIBITOR_WHAT_NONE, ++ _("Libvirt Network"), ++ _("Virtual networks are active"), ++ VIR_INHIBITOR_MODE_DELAY, ++ callback, ++ opaque); ++ + if ((network_driver->lockFD = + virPidFileAcquire(cfg->stateDir, "driver", getpid())) < 0) + goto error; +@@ -2432,8 +2436,7 @@ networkStartNetwork(virNetworkDriverState *driver, + obj, network_driver->xmlopt) < 0) + goto cleanup; + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + virNetworkObjSetActive(obj, true); + VIR_INFO("Network '%s' started up", def->name); +@@ -2509,8 +2512,7 @@ networkShutdownNetwork(virNetworkDriverState *driver, + + virNetworkObjSetActive(obj, false); + +- if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback) +- driver->inhibitCallback(false, driver->inhibitOpaque); ++ virInhibitorRelease(driver->inhibitor); + + virNetworkObjUnsetDefTransient(obj); + return ret; +diff --git a/src/network/bridge_driver_conf.h b/src/network/bridge_driver_conf.h +index 1beed01efb..2a2e2bc16d 100644 +--- a/src/network/bridge_driver_conf.h ++++ b/src/network/bridge_driver_conf.h +@@ -27,6 +27,7 @@ + #include "virnetworkobj.h" + #include "object_event.h" + #include "virfirewall.h" ++#include "virinhibitor.h" + + typedef struct _virNetworkDriverConfig virNetworkDriverConfig; + struct _virNetworkDriverConfig { +@@ -49,12 +50,8 @@ typedef struct _virNetworkDriverState virNetworkDriverState; + struct _virNetworkDriverState { + virMutex lock; + +- /* Atomic inc/dec only */ +- unsigned int nactive; +- +- /* Immutable pointers. Caller must provide locking */ +- virStateInhibitCallback inhibitCallback; +- void *inhibitOpaque; ++ /* Immutable pointer, self-locking APIs */ ++ virInhibitor *inhibitor; + + /* Read-only */ + bool privileged; +diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h +index 23a900193e..42cdb6f883 100644 +--- a/src/qemu/qemu_conf.h ++++ b/src/qemu/qemu_conf.h +@@ -42,6 +42,7 @@ + #include "virfile.h" + #include "virfilecache.h" + #include "virfirmware.h" ++#include "virinhibitor.h" + + #define QEMU_DRIVER_NAME "QEMU" + +@@ -257,16 +258,12 @@ struct _virQEMUDriver { + /* Atomic increment only */ + int lastvmid; + +- /* Atomic inc/dec only */ +- unsigned int nactive; +- + /* Immutable values */ + bool privileged; + char *embeddedRoot; + +- /* Immutable pointers. Caller must provide locking */ +- virStateInhibitCallback inhibitCallback; +- void *inhibitOpaque; ++ /* Immutable pointer, self-locking APIs */ ++ virInhibitor *inhibitor; + + /* Immutable pointer, self-locking APIs */ + virDomainObjList *domains; +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 379f9fb74f..5b911d5221 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -573,9 +573,6 @@ qemuStateInitialize(bool privileged, + return VIR_DRV_STATE_INIT_ERROR; + } + +- qemu_driver->inhibitCallback = callback; +- qemu_driver->inhibitOpaque = opaque; +- + qemu_driver->privileged = privileged; + qemu_driver->hostarch = virArchFromHost(); + if (root != NULL) +@@ -675,6 +672,14 @@ qemuStateInitialize(bool privileged, + goto error; + } + ++ qemu_driver->inhibitor = virInhibitorNew( ++ VIR_INHIBITOR_WHAT_NONE, ++ _("Libvirt QEMU"), ++ _("QEMU/KVM virtual machines are running"), ++ VIR_INHIBITOR_MODE_DELAY, ++ callback, ++ opaque); ++ + if ((qemu_driver->lockFD = + virPidFileAcquire(cfg->stateDir, "driver", getpid())) < 0) + goto error; +@@ -1065,6 +1070,7 @@ qemuStateCleanup(void) + ebtablesContextFree(qemu_driver->ebtables); + virObjectUnref(qemu_driver->domains); + virObjectUnref(qemu_driver->nbdkitCapsCache); ++ virInhibitorFree(qemu_driver->inhibitor); + + if (qemu_driver->lockFD != -1) + virPidFileRelease(qemu_driver->config->stateDir, "driver", qemu_driver->lockFD); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 7285fd5ce9..722e982b9e 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -5853,8 +5853,7 @@ qemuProcessInit(virQEMUDriver *driver, + qemuDomainSetFakeReboot(vm, false); + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP); + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + /* Run an early hook to set-up missing devices */ + if (qemuProcessStartHook(driver, vm, +@@ -8885,8 +8884,7 @@ void qemuProcessStop(virQEMUDriver *driver, + if (priv->eventThread) + g_object_unref(g_steal_pointer(&priv->eventThread)); + +- if (g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback) +- driver->inhibitCallback(false, driver->inhibitOpaque); ++ virInhibitorRelease(driver->inhibitor); + + /* Clear network bandwidth */ + virDomainClearNetBandwidth(vm->def); +@@ -9644,8 +9642,7 @@ qemuProcessReconnect(void *opaque) + goto error; + } + +- if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) +- driver->inhibitCallback(true, driver->inhibitOpaque); ++ virInhibitorHold(driver->inhibitor); + + cleanup: + if (jobStarted) +diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c +index a2d6b879d0..04c3ca49f1 100644 +--- a/src/secret/secret_driver.c ++++ b/src/secret/secret_driver.c +@@ -41,6 +41,7 @@ + #include "viraccessapicheck.h" + #include "secret_event.h" + #include "virutil.h" ++#include "virinhibitor.h" + + #define VIR_FROM_THIS VIR_FROM_SECRET + +@@ -67,9 +68,8 @@ struct _virSecretDriverState { + /* Immutable pointer, self-locking APIs */ + virObjectEventState *secretEventState; + +- /* Immutable pointers. Caller must provide locking */ +- virStateInhibitCallback inhibitCallback; +- void *inhibitOpaque; ++ /* Immutable pointer, self-locking APIs */ ++ virInhibitor *inhibitor; + }; + + static virSecretDriverState *driver; +@@ -90,23 +90,6 @@ secretObjFromSecret(virSecretPtr secret) + } + + +-static bool +-secretNumOfEphemeralSecretsHelper(virConnectPtr conn G_GNUC_UNUSED, +- virSecretDef *def) +-{ +- return def->isephemeral; +-} +- +- +-static int +-secretNumOfEphemeralSecrets(void) +-{ +- return virSecretObjListNumOfSecrets(driver->secrets, +- secretNumOfEphemeralSecretsHelper, +- NULL); +-} +- +- + /* Driver functions */ + + static int +@@ -271,6 +254,10 @@ secretDefineXML(virConnectPtr conn, + objDef->uuid, + objDef->usage_type, + objDef->usage_id); ++ ++ if (objDef->isephemeral) ++ virInhibitorHold(driver->inhibitor); ++ + goto cleanup; + + restore_backup: +@@ -288,8 +275,6 @@ secretDefineXML(virConnectPtr conn, + virSecretDefFree(def); + virSecretObjEndAPI(&obj); + +- if (secretNumOfEphemeralSecrets() > 0) +- driver->inhibitCallback(true, driver->inhibitOpaque); + + virObjectEventStateQueue(driver->secretEventState, event); + +@@ -440,6 +425,9 @@ secretUndefine(virSecretPtr secret) + VIR_SECRET_EVENT_UNDEFINED, + 0); + ++ if (def->isephemeral) ++ virInhibitorRelease(driver->inhibitor); ++ + virSecretObjDeleteData(obj); + + virSecretObjListRemove(driver->secrets, obj); +@@ -450,9 +438,6 @@ secretUndefine(virSecretPtr secret) + cleanup: + virSecretObjEndAPI(&obj); + +- if (secretNumOfEphemeralSecrets() == 0) +- driver->inhibitCallback(false, driver->inhibitOpaque); +- + virObjectEventStateQueue(driver->secretEventState, event); + + return ret; +@@ -469,6 +454,7 @@ secretStateCleanupLocked(void) + VIR_FREE(driver->configDir); + + virObjectUnref(driver->secretEventState); ++ virInhibitorFree(driver->inhibitor); + + if (driver->lockFD != -1) + virPidFileRelease(driver->stateDir, "driver", driver->lockFD); +@@ -502,8 +488,6 @@ secretStateInitialize(bool privileged, + driver->lockFD = -1; + driver->secretEventState = virObjectEventStateNew(); + driver->privileged = privileged; +- driver->inhibitCallback = callback; +- driver->inhibitOpaque = opaque; + + if (root) { + driver->embeddedRoot = g_strdup(root); +@@ -535,6 +519,14 @@ secretStateInitialize(bool privileged, + goto error; + } + ++ driver->inhibitor = virInhibitorNew( ++ VIR_INHIBITOR_WHAT_NONE, ++ _("Libvirt Secret"), ++ _("Ephemeral secrets are loaded"), ++ VIR_INHIBITOR_MODE_DELAY, ++ callback, ++ opaque); ++ + if ((driver->lockFD = + virPidFileAcquire(driver->stateDir, "driver", getpid())) < 0) + goto error; +-- +2.49.0 diff --git a/SOURCES/libvirt-util-don-t-attempt-to-acquire-logind-inhibitor-if-not-requested.patch b/SOURCES/libvirt-util-don-t-attempt-to-acquire-logind-inhibitor-if-not-requested.patch new file mode 100644 index 0000000..d2bfd76 --- /dev/null +++ b/SOURCES/libvirt-util-don-t-attempt-to-acquire-logind-inhibitor-if-not-requested.patch @@ -0,0 +1,52 @@ +From 05aa05e3b17000b2a886dddb2abdb183bd6d4295 Mon Sep 17 00:00:00 2001 +Message-ID: <05aa05e3b17000b2a886dddb2abdb183bd6d4295.1744361503.git.jdenemar@redhat.com> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 8 Jan 2025 17:37:03 +0000 +Subject: [PATCH] util: don't attempt to acquire logind inhibitor if not + requested +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When VIR_INHIBITOR_WHAT_NONE is passed to virInhibitorNew, it is +an indication that daemon shutdown should be inhibited, but no +OS level inhibitors acquired. This is done by the virtnetworkd +daemon, for example, to prevent shutdown while running virtual +machines are present, without blocking / delaying OS shutdown. + +Unfortunately the code forgot to skip the DBus call in this case, +resulting in errors being logged. + +Reviewed-by: Laine Stump +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit caa10431cdd1aa476637ff721f1947c4e0b53da1) +Resolves: https://issues.redhat.com/browse/RHEL-83076 +--- + src/util/virinhibitor.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/util/virinhibitor.c b/src/util/virinhibitor.c +index 647bdc9fbb..a95021de5a 100644 +--- a/src/util/virinhibitor.c ++++ b/src/util/virinhibitor.c +@@ -152,7 +152,7 @@ virInhibitor *virInhibitorNew(virInhibitorWhat what, + virInhibitor *inhibitor = g_new0(virInhibitor, 1); + + inhibitor->fd = -1; +- inhibitor->what = virInhibitorWhatFormat(what); ++ inhibitor->what = what ? virInhibitorWhatFormat(what) : NULL; + inhibitor->who = g_strdup(who); + inhibitor->why = g_strdup(why); + inhibitor->mode = virInhibitorModeTypeToString(mode); +@@ -171,7 +171,8 @@ void virInhibitorHold(virInhibitor *inhibitor) + inhibitor->action(true, inhibitor->actionData); + } + #ifdef G_OS_UNIX +- if (virInhibitorAcquire( ++ if (inhibitor->what && ++ virInhibitorAcquire( + inhibitor->what, inhibitor->who, inhibitor->why, + inhibitor->mode, &inhibitor->fd) < 0) { + VIR_ERROR(_("Failed to acquire inhibitor: %1$s"), +-- +2.49.0 diff --git a/SOURCES/libvirt-util-fix-off-by-1-in-inhibitor-constants.patch b/SOURCES/libvirt-util-fix-off-by-1-in-inhibitor-constants.patch new file mode 100644 index 0000000..20fe7ce --- /dev/null +++ b/SOURCES/libvirt-util-fix-off-by-1-in-inhibitor-constants.patch @@ -0,0 +1,46 @@ +From 10b60d5a7910c243249e296306c7dc9e87e79f71 Mon Sep 17 00:00:00 2001 +Message-ID: <10b60d5a7910c243249e296306c7dc9e87e79f71.1744361503.git.jdenemar@redhat.com> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Tue, 7 Jan 2025 15:21:18 +0000 +Subject: [PATCH] util: fix off-by-1 in inhibitor constants +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The inhibitor constant values were off-by-1, so when converted into +string format, we picked the wrong names + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit fc3a60d9d7b29283a0b2d57bb06d15fb597a5003) +Resolves: https://issues.redhat.com/browse/RHEL-83076 +--- + src/util/virinhibitor.h | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/util/virinhibitor.h b/src/util/virinhibitor.h +index 0a1c445d41..49cf32fbeb 100644 +--- a/src/util/virinhibitor.h ++++ b/src/util/virinhibitor.h +@@ -26,13 +26,13 @@ typedef struct _virInhibitor virInhibitor; + + typedef enum { + VIR_INHIBITOR_WHAT_NONE = 0, +- VIR_INHIBITOR_WHAT_SLEEP = (1 << 1), +- VIR_INHIBITOR_WHAT_SHUTDOWN = (1 << 2), +- VIR_INHIBITOR_WHAT_IDLE = (1 << 3), +- VIR_INHIBITOR_WHAT_POWER_KEY = (1 << 4), +- VIR_INHIBITOR_WHAT_SUSPEND_KEY = (1 << 5), +- VIR_INHIBITOR_WHAT_HIBERNATE_KEY = (1 << 6), +- VIR_INHIBITOR_WHAT_LID_SWITCH = (1 << 7), ++ VIR_INHIBITOR_WHAT_SLEEP = (1 << 0), ++ VIR_INHIBITOR_WHAT_SHUTDOWN = (1 << 1), ++ VIR_INHIBITOR_WHAT_IDLE = (1 << 2), ++ VIR_INHIBITOR_WHAT_POWER_KEY = (1 << 3), ++ VIR_INHIBITOR_WHAT_SUSPEND_KEY = (1 << 4), ++ VIR_INHIBITOR_WHAT_HIBERNATE_KEY = (1 << 5), ++ VIR_INHIBITOR_WHAT_LID_SWITCH = (1 << 6), + } virInhibitorWhat; + + typedef enum { +-- +2.49.0 diff --git a/SOURCES/libvirt-util-introduce-object-for-holding-a-system-inhibitor-lock.patch b/SOURCES/libvirt-util-introduce-object-for-holding-a-system-inhibitor-lock.patch new file mode 100644 index 0000000..ceece4d --- /dev/null +++ b/SOURCES/libvirt-util-introduce-object-for-holding-a-system-inhibitor-lock.patch @@ -0,0 +1,375 @@ +From 9f2c4a2117eec85d5146e7dedd628585bb55df01 Mon Sep 17 00:00:00 2001 +Message-ID: <9f2c4a2117eec85d5146e7dedd628585bb55df01.1744361502.git.jdenemar@redhat.com> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Mon, 16 Dec 2024 15:19:34 +0000 +Subject: [PATCH] util: introduce object for holding a system inhibitor lock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The system inhibitor locks are currently handled by code in the +virNetDaemon class. The driver code invokes a callback provided +by the daemon when it wants to start or end inhibition. + +When the first inhibition is started, the daemon will call out +to logind to apply it system wide. + +This has many flaws + + * A single message is registered with logind regardless of + what driver holds the inhibition + * An inhibition of daemon shutdown can't be acquired + without also inhibiting system shutdown + * Config of the inhibitions cannot be tailored by the + driver + +The new virInhibitor object addresses these: + + * The object directly manages an inhibition with logind + privately to the driver, enabling custom messages to + be set. + * It is possible to acquire an inhibition locally to the + daemon without forwarding it to logind. + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit d2e5aa4f4e1501149c9e3095d38ebc04c9a4ba31) +Resolves: https://issues.redhat.com/browse/RHEL-83076 +--- + po/POTFILES | 1 + + src/libvirt_private.syms | 7 ++ + src/util/meson.build | 1 + + src/util/virinhibitor.c | 214 +++++++++++++++++++++++++++++++++++++++ + src/util/virinhibitor.h | 58 +++++++++++ + 5 files changed, 281 insertions(+) + create mode 100644 src/util/virinhibitor.c + create mode 100644 src/util/virinhibitor.h + +diff --git a/po/POTFILES b/po/POTFILES +index 3514aa3dca..c71e439fe3 100644 +--- a/po/POTFILES ++++ b/po/POTFILES +@@ -293,6 +293,7 @@ src/util/virhostcpu.c + src/util/virhostmem.c + src/util/virhostuptime.c + src/util/viridentity.c ++src/util/virinhibitor.c + src/util/virinitctl.c + src/util/viriscsi.c + src/util/virjson.c +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 7d404fdbf5..727ab52cfe 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2605,6 +2605,13 @@ virIdentitySetUserName; + virIdentitySetX509DName; + + ++# util/virinhibitor.h ++virInhibitorFree; ++virInhibitorHold; ++virInhibitorNew; ++virInhibitorRelease; ++ ++ + # util/virinitctl.h + virInitctlFifos; + virInitctlSetRunLevel; +diff --git a/src/util/meson.build b/src/util/meson.build +index 30f71b0227..69ef49139a 100644 +--- a/src/util/meson.build ++++ b/src/util/meson.build +@@ -45,6 +45,7 @@ util_sources = [ + 'virhostmem.c', + 'virhostuptime.c', + 'viridentity.c', ++ 'virinhibitor.c', + 'virinitctl.c', + 'viriscsi.c', + 'virjson.c', +diff --git a/src/util/virinhibitor.c b/src/util/virinhibitor.c +new file mode 100644 +index 0000000000..647bdc9fbb +--- /dev/null ++++ b/src/util/virinhibitor.c +@@ -0,0 +1,214 @@ ++/* ++ * virinhibitor.c: helper APIs for inhibiting host actions ++ * ++ * Copyright (C) 2024 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#include ++ ++#include "virinhibitor.h" ++#include "virgdbus.h" ++#include "virsystemd.h" ++#include "virfile.h" ++#include "virlog.h" ++#include "virenum.h" ++ ++#define VIR_FROM_THIS VIR_FROM_NONE ++ ++VIR_LOG_INIT("util.inhibitor"); ++ ++struct _virInhibitor { ++ GMutex lock; ++ size_t count; ++ int fd; ++ ++ char *what; ++ char *who; ++ char *why; ++ const char *mode; ++ ++ virInhibitorAction action; ++ void *actionData; ++}; ++ ++VIR_ENUM_DECL(virInhibitorMode); ++ ++VIR_ENUM_IMPL(virInhibitorMode, ++ VIR_INHIBITOR_MODE_LAST, ++ "block", "delay"); ++ ++#ifdef G_OS_UNIX ++/* As per: https://www.freedesktop.org/wiki/Software/systemd/inhibit */ ++static int ++virInhibitorAcquire(const char *what, ++ const char *who, ++ const char *why, ++ const char *mode, ++ int *inhibitorFD) ++{ ++ g_autoptr(GVariant) reply = NULL; ++ g_autoptr(GUnixFDList) replyFD = NULL; ++ g_autoptr(GVariant) message = NULL; ++ GDBusConnection *systemBus; ++ int fd; ++ int rc; ++ ++ VIR_DEBUG("what=%s who=%s why=%s mode=%s", ++ NULLSTR(what), NULLSTR(who), NULLSTR(why), NULLSTR(mode)); ++ ++ if (!(systemBus = virGDBusGetSystemBus())) { ++ VIR_DEBUG("system dbus not available, skipping system inhibitor"); ++ return 0; ++ } ++ ++ if (virSystemdHasLogind() < 0) { ++ VIR_DEBUG("logind not available, skipping system inhibitor"); ++ return 0; ++ } ++ ++ message = g_variant_new("(ssss)", what, who, why, mode); ++ ++ rc = virGDBusCallMethodWithFD(systemBus, ++ &reply, ++ G_VARIANT_TYPE("(h)"), ++ &replyFD, ++ NULL, ++ "org.freedesktop.login1", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ "Inhibit", ++ message, ++ NULL); ++ ++ if (rc < 0) ++ return -1; ++ ++ if (g_unix_fd_list_get_length(replyFD) <= 0) { ++ VIR_DEBUG("Missing inhibitor FD in logind reply"); ++ return -1; ++ } ++ ++ fd = g_unix_fd_list_get(replyFD, 0, NULL); ++ if (fd < 0) { ++ VIR_DEBUG("Unable to get inhibitor FD from logind reply"); ++ return -1; ++ } ++ ++ *inhibitorFD = fd; ++ VIR_DEBUG("Got inhibitor FD %d", fd); ++ return 0; ++} ++#endif ++ ++ ++static char * ++virInhibitorWhatFormat(virInhibitorWhat what) ++{ ++ const char *whatstr[] = { ++ "sleep", ++ "shutdown", ++ "idle", ++ "handle-power-key", ++ "handle-suspend-key", ++ "handle-hibernate-key", ++ "handle-lid-switch", ++ }; ++ GString *str = g_string_new(""); ++ size_t i; ++ ++ for (i = 0; i < G_N_ELEMENTS(whatstr); i++) { ++ if (what & (1 << i)) { ++ if (str->len) ++ g_string_append(str, ":"); ++ g_string_append(str, whatstr[i]); ++ } ++ } ++ ++ return g_string_free(str, FALSE); ++} ++ ++ ++virInhibitor *virInhibitorNew(virInhibitorWhat what, ++ const char *who, ++ const char *why, ++ virInhibitorMode mode, ++ virInhibitorAction action, ++ void *actionData) ++{ ++ virInhibitor *inhibitor = g_new0(virInhibitor, 1); ++ ++ inhibitor->fd = -1; ++ inhibitor->what = virInhibitorWhatFormat(what); ++ inhibitor->who = g_strdup(who); ++ inhibitor->why = g_strdup(why); ++ inhibitor->mode = virInhibitorModeTypeToString(mode); ++ inhibitor->action = action; ++ inhibitor->actionData = actionData; ++ ++ return inhibitor; ++} ++ ++void virInhibitorHold(virInhibitor *inhibitor) ++{ ++ g_mutex_lock(&inhibitor->lock); ++ ++ if (inhibitor->count == 0) { ++ if (inhibitor->action) { ++ inhibitor->action(true, inhibitor->actionData); ++ } ++#ifdef G_OS_UNIX ++ if (virInhibitorAcquire( ++ inhibitor->what, inhibitor->who, inhibitor->why, ++ inhibitor->mode, &inhibitor->fd) < 0) { ++ VIR_ERROR(_("Failed to acquire inhibitor: %1$s"), ++ virGetLastErrorMessage()); ++ virResetLastError(); ++ } ++#else ++ VIR_DEBUG("No inhibitor implementation on non-UNIX platforms"); ++#endif ++ } ++ inhibitor->count++; ++ g_mutex_unlock(&inhibitor->lock); ++} ++ ++ ++void virInhibitorRelease(virInhibitor *inhibitor) ++{ ++ g_mutex_lock(&inhibitor->lock); ++ inhibitor->count--; ++ if (inhibitor->count == 0) { ++ VIR_FORCE_CLOSE(inhibitor->fd); ++ if (inhibitor->action) { ++ inhibitor->action(false, inhibitor->actionData); ++ } ++ } ++ g_mutex_unlock(&inhibitor->lock); ++} ++ ++ ++void virInhibitorFree(virInhibitor *inhibitor) ++{ ++ if (!inhibitor) ++ return; ++ ++ g_free(inhibitor->what); ++ g_free(inhibitor->who); ++ g_free(inhibitor->why); ++ VIR_FORCE_CLOSE(inhibitor->fd); ++ g_free(inhibitor); ++} +diff --git a/src/util/virinhibitor.h b/src/util/virinhibitor.h +new file mode 100644 +index 0000000000..0a1c445d41 +--- /dev/null ++++ b/src/util/virinhibitor.h +@@ -0,0 +1,58 @@ ++/* ++ * virinhibitor.h: helper APIs for inhibiting host actions ++ * ++ * Copyright (C) 2024 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#pragma once ++ ++#include "internal.h" ++ ++typedef struct _virInhibitor virInhibitor; ++ ++typedef enum { ++ VIR_INHIBITOR_WHAT_NONE = 0, ++ VIR_INHIBITOR_WHAT_SLEEP = (1 << 1), ++ VIR_INHIBITOR_WHAT_SHUTDOWN = (1 << 2), ++ VIR_INHIBITOR_WHAT_IDLE = (1 << 3), ++ VIR_INHIBITOR_WHAT_POWER_KEY = (1 << 4), ++ VIR_INHIBITOR_WHAT_SUSPEND_KEY = (1 << 5), ++ VIR_INHIBITOR_WHAT_HIBERNATE_KEY = (1 << 6), ++ VIR_INHIBITOR_WHAT_LID_SWITCH = (1 << 7), ++} virInhibitorWhat; ++ ++typedef enum { ++ VIR_INHIBITOR_MODE_BLOCK, ++ VIR_INHIBITOR_MODE_DELAY, ++ ++ VIR_INHIBITOR_MODE_LAST ++} virInhibitorMode; ++ ++typedef void (*virInhibitorAction)(bool inhibited, ++ void *opaque); ++ ++virInhibitor *virInhibitorNew(virInhibitorWhat what, ++ const char *who, ++ const char *why, ++ virInhibitorMode mode, ++ virInhibitorAction action, ++ void *actionData); ++ ++void virInhibitorHold(virInhibitor *inhibitor); ++void virInhibitorRelease(virInhibitor *inhibitor); ++ ++void virInhibitorFree(virInhibitor *inhibitor); +-- +2.49.0 diff --git a/SOURCES/libvirt-virsh-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch b/SOURCES/libvirt-virsh-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch new file mode 100644 index 0000000..95eaa4e --- /dev/null +++ b/SOURCES/libvirt-virsh-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch @@ -0,0 +1,71 @@ +From f2b3e5bf2ae55e028125e545a1fe9565e2bc86f9 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Martin Kletzander +Date: Tue, 25 Feb 2025 15:22:35 +0100 +Subject: [PATCH] virsh: Add support for VIR_DOMAIN_GUEST_INFO_LOAD + +Resolves: https://issues.redhat.com/browse/RHEL-71883 +Signed-off-by: Martin Kletzander +Reviewed-by: Peter Krempa +(cherry picked from commit 71e75ce09203aa2489803426ae368d1693ee925b) + +https://issues.redhat.com/browse/RHEL-88449 + +Signed-off-by: Martin Kletzander +--- + docs/manpages/virsh.rst | 8 +++++++- + tools/virsh-domain.c | 6 ++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index 2e525d3fac..77798af7d3 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -2912,7 +2912,7 @@ Success is always reported in this case. + + You can limit the types of information that are returned by specifying one or + more flags. Available information types flags are *--user*, *--os*, +-*--timezone*, *--hostname*, *--filesystem*, *--disk* and *--interface*. ++*--timezone*, *--hostname*, *--filesystem*, *--disk*, *--interface* and *--load*. + If an explicitly requested information type is not supported by the guest agent + at that point, the processes will provide an exit code of 1. + +@@ -2991,6 +2991,12 @@ returned: + * ``if..addr..addr`` - the IP address of addr + * ``if..addr..prefix`` - the prefix of IP address of addr + ++*--load* returns: ++* ``load.1m`` - average load in guest for last 1 minute ++* ``load.5m`` - average load in guest for last 5 minutes ++* ``load.15m`` - average load in guest for last 15 minutes ++ ++ + guestvcpus + ---------- + +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index e4923284af..0f30a65fd9 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -13066,6 +13066,10 @@ static const vshCmdOptDef opts_guestinfo[] = { + .type = VSH_OT_BOOL, + .help = N_("report interface information"), + }, ++ {.name = "load", ++ .type = VSH_OT_BOOL, ++ .help = N_("report load averages information"), ++ }, + {.name = NULL} + }; + +@@ -13093,6 +13097,8 @@ cmdGuestInfo(vshControl *ctl, const vshCmd *cmd) + types |= VIR_DOMAIN_GUEST_INFO_DISKS; + if (vshCommandOptBool(cmd, "interface")) + types |= VIR_DOMAIN_GUEST_INFO_INTERFACES; ++ if (vshCommandOptBool(cmd, "load")) ++ types |= VIR_DOMAIN_GUEST_INFO_LOAD; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; +-- +2.49.0 diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 9339e32..9b6f157 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -289,7 +289,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 10.10.0 -Release: 7.1%{?dist}%{?extra_release} +Release: 7.3.0.1%{?dist}%{?extra_release} License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1 URL: https://libvirt.org/ @@ -381,6 +381,22 @@ Patch81: libvirt-docs-improve-type-user-docs-to-higlight-differences-between-SLI Patch82: libvirt-docs-document-using-passt-backend-with-interface-type-vhostuser.patch Patch83: libvirt-utils-Canonicalize-paths-before-comparing-them.patch Patch84: libvirt-remote-add-sysusers-file-to-create-libvirt-group.patch +Patch85: libvirt-util-introduce-object-for-holding-a-system-inhibitor-lock.patch +Patch86: libvirt-src-convert-drivers-over-to-new-virInhibitor-APIs.patch +Patch87: libvirt-rpc-remove-logind-support-for-virNetDaemon.patch +Patch88: libvirt-util-fix-off-by-1-in-inhibitor-constants.patch +Patch89: libvirt-util-don-t-attempt-to-acquire-logind-inhibitor-if-not-requested.patch +Patch90: libvirt-network-Free-inhibitor-in-networkStateCleanup.patch +Patch91: libvirt-conf-parse-interface-source-dev-for-all-interface-types-with-backend-type-passt.patch +Patch92: libvirt-qemu-remove-nonsensical-sanity-check-in-processNetdevStreamDisconnectedEvent.patch +Patch93: libvirt-qemu-make-processNetDevStreamDisconnectedEvent-reusable.patch +Patch94: libvirt-qemu-respond-to-NETDEV_VHOST_USER_DISCONNECTED-event.patch +Patch95: libvirt-qemu-put-vhost-user-code-that-s-special-for-passt-in-a-helper-function.patch +Patch96: libvirt-qemu-make-passt-vhostuser-reconnect-behave-identically-to-passt-user.patch +Patch97: libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch +Patch98: libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch +Patch99: libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch +Patch100: libvirt-virsh-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch Requires: libvirt-daemon = %{version}-%{release} @@ -1402,7 +1418,8 @@ exit 1 %define arg_packager_version -Dpackager_version="%{release}" %define arg_selinux_mount -Dselinux_mount="/sys/fs/selinux" -# place macros above and build commands below this comment +# Set SOURCE_DATE_EPOCH from changelog +%define source_date_epoch_from_changelog 1 export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/libvirt.spec) @@ -2706,8 +2723,31 @@ exit 0 %endif %changelog -* Thu Mar 13 2025 Jiri Denemark - 10.10.0-7.1 -- remote: add sysusers file to create 'libvirt' group (RHEL-81749) +* Fri May 16 2025 EL Errata - 10.10.0-7.3.0.1 +- Set SOURCE_DATE_EPOCH from changelog [Orabug: 32019554] + +* Tue Apr 29 2025 Jiri Denemark - 10.10.0-7.3.el9_6 +- Add load average information type into virDomainGetGuestInfo (RHEL-88449) +- qemu_agent: Add qemuAgentGetLoadAvg() (RHEL-88449) +- qemu: Add support for VIR_DOMAIN_GUEST_INFO_LOAD (RHEL-88449) +- virsh: Add support for VIR_DOMAIN_GUEST_INFO_LOAD (RHEL-88449) + +* Fri Apr 11 2025 Jiri Denemark - 10.10.0-7.2.el9_6 +- util: introduce object for holding a system inhibitor lock (RHEL-83076) +- src: convert drivers over to new virInhibitor APIs (RHEL-83076) +- rpc: remove logind support for virNetDaemon (RHEL-83076) +- util: fix off-by-1 in inhibitor constants (RHEL-83076) +- util: don't attempt to acquire logind inhibitor if not requested (RHEL-83076) +- network: Free inhibitor in networkStateCleanup() (RHEL-83076) +- conf: parse interface/source/@dev for all interface types (with backend type='passt') (RHEL-84689) +- qemu: remove nonsensical sanity check in processNetdevStreamDisconnectedEvent() (RHEL-84782) +- qemu: make processNetDevStreamDisconnectedEvent() reusable (RHEL-84782) +- qemu: respond to NETDEV_VHOST_USER_DISCONNECTED event (RHEL-84782) +- qemu: put vhost-user code that's special for passt in a helper function (RHEL-84782) +- qemu: make passt+vhostuser reconnect behave identically to passt+user (RHEL-84782) + +* Fri Mar 7 2025 Jiri Denemark - 10.10.0-7.1.el9_6 +- remote: add sysusers file to create 'libvirt' group (RHEL-81740) * Mon Feb 17 2025 Jiri Denemark - 10.10.0-7 - qemu_migration: Refactor qemuMigrationSrcRestoreDomainState (RHEL-79168) From 3e1705e817de3d65ebff244897cbd6325e31a647 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Fri, 23 May 2025 13:07:07 +0000 Subject: [PATCH 2/2] Revert OL modifications --- SPECS/libvirt.spec | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 9b6f157..cc3860e 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -289,7 +289,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 10.10.0 -Release: 7.3.0.1%{?dist}%{?extra_release} +Release: 7.3%{?dist}%{?extra_release} License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1 URL: https://libvirt.org/ @@ -1418,8 +1418,7 @@ exit 1 %define arg_packager_version -Dpackager_version="%{release}" %define arg_selinux_mount -Dselinux_mount="/sys/fs/selinux" -# Set SOURCE_DATE_EPOCH from changelog -%define source_date_epoch_from_changelog 1 +# place macros above and build commands below this comment export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/libvirt.spec) @@ -2723,9 +2722,6 @@ exit 0 %endif %changelog -* Fri May 16 2025 EL Errata - 10.10.0-7.3.0.1 -- Set SOURCE_DATE_EPOCH from changelog [Orabug: 32019554] - * Tue Apr 29 2025 Jiri Denemark - 10.10.0-7.3.el9_6 - Add load average information type into virDomainGetGuestInfo (RHEL-88449) - qemu_agent: Add qemuAgentGetLoadAvg() (RHEL-88449)