Enable building for ppc64le
This commit is contained in:
commit
bc6466474b
@ -0,0 +1,53 @@
|
||||
From 514588d016d1e105f987d821331a578a34ccdf49 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <514588d016d1e105f987d821331a578a34ccdf49.1745925135.git.jdenemar@redhat.com>
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
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 <mkletzan@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit c52c449fd40c7263896d5f17129207b815c3a09c)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-88449
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
---
|
||||
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.<num>.addr.<num1>.addr" - the IP address of addr <num1>
|
||||
* "if.<num>.addr.<num1>.prefix" - the prefix of IP address of addr <num1>
|
||||
*
|
||||
+ * 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
|
@ -0,0 +1,106 @@
|
||||
From a52da24e19808954454be38945953a2a81c078e9 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <a52da24e19808954454be38945953a2a81c078e9.1744361503.git.jdenemar@redhat.com>
|
||||
From: Laine Stump <laine@redhat.com>
|
||||
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:
|
||||
|
||||
<source dev='blah'/>
|
||||
|
||||
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 <backend> 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 <laine@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit 4c979edaa545c8425f7a856c06ebc0de939d4b9f)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-84689
|
||||
|
||||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
---
|
||||
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 <source> element can only be used with <interface> type='user' or type='vhostuser' if the <backend> 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 @@
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<interface type='vhostuser'>
|
||||
<mac address='00:11:22:33:44:55'/>
|
||||
+ <source dev='eth42'/>
|
||||
<ip address='172.17.2.0' family='ipv4' prefix='24'/>
|
||||
<ip address='2001:db8:ac10:fd01::feed' family='ipv6'/>
|
||||
<portForward proto='tcp' address='2001:db8:ac10:fd01::1:10'>
|
||||
@@ -63,6 +64,7 @@
|
||||
</interface>
|
||||
<interface type='vhostuser'>
|
||||
<mac address='00:11:22:33:44:11'/>
|
||||
+ <source dev='eth43'/>
|
||||
<model type='virtio'/>
|
||||
<backend type='passt'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
|
||||
--
|
||||
2.49.0
|
@ -0,0 +1,44 @@
|
||||
From 8e64dac6129cacd8f53813cbc7580209e96e7dc3 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <8e64dac6129cacd8f53813cbc7580209e96e7dc3.1744361503.git.jdenemar@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
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 <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(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
|
@ -0,0 +1,72 @@
|
||||
From 816ce9100cbc410706fde26763158640f6d06f44 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <816ce9100cbc410706fde26763158640f6d06f44.1745925135.git.jdenemar@redhat.com>
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
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 <mkletzan@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit b4cf9c8cba45e65551aa9440dea2c3757a96aa0c)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-88449
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
---
|
||||
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
|
@ -1,38 +0,0 @@
|
||||
From d874530eaded03d0b90139c9bbd80902b9464e87 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <d874530eaded03d0b90139c9bbd80902b9464e87.1741876175.git.jdenemar@redhat.com>
|
||||
From: Jiri Denemark <jdenemar@redhat.com>
|
||||
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 <jdenemar@redhat.com>
|
||||
Tested-by: Jaroslav Suchanek <jsuchane@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit 43eae1b7077104d4e2ed52447407a335c2d093e3)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-81747
|
||||
|
||||
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
---
|
||||
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
|
@ -0,0 +1,111 @@
|
||||
From bc0074073da43052e4a786eca70dd5fbbf023903 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <bc0074073da43052e4a786eca70dd5fbbf023903.1744361503.git.jdenemar@redhat.com>
|
||||
From: Laine Stump <laine@redhat.com>
|
||||
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, <interface type='vhostuser'> has
|
||||
always ignored the reconnect setting in <source> 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 <laine@redhat.com>
|
||||
Tested-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(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 <laine@redhat.com>
|
||||
---
|
||||
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
|
@ -0,0 +1,119 @@
|
||||
From 718c4bc80d3af4570d75b590625bd5249aa50a8d Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <718c4bc80d3af4570d75b590625bd5249aa50a8d.1744361503.git.jdenemar@redhat.com>
|
||||
From: Laine Stump <laine@redhat.com>
|
||||
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 <laine@redhat.com>
|
||||
Tested-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(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 <laine@redhat.com>
|
||||
---
|
||||
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
|
@ -0,0 +1,110 @@
|
||||
From c6e5688293b765885e8b76c35ad47bc316de81aa Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <c6e5688293b765885e8b76c35ad47bc316de81aa.1744361503.git.jdenemar@redhat.com>
|
||||
From: Laine Stump <laine@redhat.com>
|
||||
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 <laine@redhat.com>
|
||||
Tested-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit 95ff77f2896478e039673bb552affec2c5a5e822)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-84782
|
||||
Signed-off-by: Laine Stump <laine@redhat.com>
|
||||
---
|
||||
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
|
@ -0,0 +1,56 @@
|
||||
From f6d606779aaedc8a6d958a2e97b462df390cb0a5 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <f6d606779aaedc8a6d958a2e97b462df390cb0a5.1744361503.git.jdenemar@redhat.com>
|
||||
From: Laine Stump <laine@redhat.com>
|
||||
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 <laine@redhat.com>
|
||||
Tested-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit 51a54dc1c4ecf37d60acee1cb94252e51c5ef627)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-84782
|
||||
Signed-off-by: Laine Stump <laine@redhat.com>
|
||||
---
|
||||
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
|
@ -0,0 +1,224 @@
|
||||
From 874251dd0b6fdbf3a0be8e494f83001e5f028868 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <874251dd0b6fdbf3a0be8e494f83001e5f028868.1744361503.git.jdenemar@redhat.com>
|
||||
From: Laine Stump <laine@redhat.com>
|
||||
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 <laine@redhat.com>
|
||||
Tested-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(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 <laine@redhat.com>
|
||||
---
|
||||
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
|
@ -1,75 +0,0 @@
|
||||
From c9c9405687b78713b913c09113697fcadec1cdba Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <c9c9405687b78713b913c09113697fcadec1cdba.1741876175.git.jdenemar@redhat.com>
|
||||
From: Pavel Hrdina <phrdina@redhat.com>
|
||||
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 <phrdina@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit 278b8334eb26aa9495f6d37e4f72471cbc8739a6)
|
||||
|
||||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
||||
---
|
||||
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
|
163
SOURCES/libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch
Normal file
163
SOURCES/libvirt-qemu_agent-Add-qemuAgentGetLoadAvg.patch
Normal file
@ -0,0 +1,163 @@
|
||||
From 4e04c0a27ced260053815b2348474ef7226aabb7 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <4e04c0a27ced260053815b2348474ef7226aabb7.1745925135.git.jdenemar@redhat.com>
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
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 <mkletzan@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit 1669d91eade46b930ebb44e4b9d398ea8c2064e7)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-88449
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
---
|
||||
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
|
@ -1,50 +0,0 @@
|
||||
From b0282d5149f90b155a38881f92e3263bd23d9878 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <b0282d5149f90b155a38881f92e3263bd23d9878.1741876175.git.jdenemar@redhat.com>
|
||||
From: Pavel Hrdina <phrdina@redhat.com>
|
||||
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 <phrdina@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit 443ae4adec3a94a575ea2acaa112188e721c7dfe)
|
||||
|
||||
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
||||
---
|
||||
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
|
@ -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?= <berrange@redhat.com>
|
||||
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 <jdenemar@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 18f0160994af80dfac2dcaf46097922e443b283b)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-81749
|
||||
https://issues.redhat.com/browse/RHEL-81740
|
||||
|
||||
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
|
||||
---
|
||||
|
202
SOURCES/libvirt-rpc-remove-logind-support-for-virNetDaemon.patch
Normal file
202
SOURCES/libvirt-rpc-remove-logind-support-for-virNetDaemon.patch
Normal file
@ -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?= <berrange@redhat.com>
|
||||
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 <mprivozn@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(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
|
@ -0,0 +1,549 @@
|
||||
From fd7a63d7b6be85cb60b7157de52d28f5c76bdf42 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <fd7a63d7b6be85cb60b7157de52d28f5c76bdf42.1744361503.git.jdenemar@redhat.com>
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
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 <mprivozn@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(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
|
@ -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?= <berrange@redhat.com>
|
||||
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 <laine@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(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
|
@ -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?= <berrange@redhat.com>
|
||||
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é <berrange@redhat.com>
|
||||
(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
|
@ -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?= <berrange@redhat.com>
|
||||
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 <mprivozn@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(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
|
||||
+ * <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#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
|
||||
+ * <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#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
|
@ -0,0 +1,71 @@
|
||||
From f2b3e5bf2ae55e028125e545a1fe9565e2bc86f9 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <f2b3e5bf2ae55e028125e545a1fe9565e2bc86f9.1745925135.git.jdenemar@redhat.com>
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
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 <mkletzan@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
(cherry picked from commit 71e75ce09203aa2489803426ae368d1693ee925b)
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-88449
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
---
|
||||
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.<num>.addr.<num1>.addr`` - the IP address of addr <num1>
|
||||
* ``if.<num>.addr.<num1>.prefix`` - the prefix of IP address of addr <num1>
|
||||
|
||||
+*--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
|
@ -293,7 +293,7 @@
|
||||
Summary: Library providing a simple virtualization API
|
||||
Name: libvirt
|
||||
Version: 10.10.0
|
||||
Release: 7.1%{?dist}%{?extra_release}.alma.1
|
||||
Release: 7.3%{?dist}%{?extra_release}.alma.1
|
||||
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/
|
||||
|
||||
@ -385,6 +385,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}
|
||||
@ -2710,11 +2726,31 @@ exit 0
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue May 13 2025 Eduard Abdullin <eabdullin@almalinux.org> - 10.10.0-7.1.alma.1
|
||||
* Fri May 23 2025 Eduard Abdullin <eabdullin@almalinux.org> - 10.10.0-7.3.alma.1
|
||||
- Enable building for ppc64le
|
||||
|
||||
* Thu Mar 13 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-7.1
|
||||
- remote: add sysusers file to create 'libvirt' group (RHEL-81749)
|
||||
* Tue Apr 29 2025 Jiri Denemark <jdenemar@redhat.com> - 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 <jdenemar@redhat.com> - 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 <jdenemar@redhat.com> - 10.10.0-7.1.el9_6
|
||||
- remote: add sysusers file to create 'libvirt' group (RHEL-81740)
|
||||
|
||||
* Mon Feb 17 2025 Jiri Denemark <jdenemar@redhat.com> - 10.10.0-7
|
||||
- qemu_migration: Refactor qemuMigrationSrcRestoreDomainState (RHEL-79168)
|
||||
|
Loading…
Reference in New Issue
Block a user