diff --git a/libvirt-cgroup-Plumb-the-daemonDomainShutdown-parameter-of-virSystemdCreateMachine-to-drivers.patch b/libvirt-cgroup-Plumb-the-daemonDomainShutdown-parameter-of-virSystemdCreateMachine-to-drivers.patch new file mode 100644 index 0000000..4a31b99 --- /dev/null +++ b/libvirt-cgroup-Plumb-the-daemonDomainShutdown-parameter-of-virSystemdCreateMachine-to-drivers.patch @@ -0,0 +1,176 @@ +From 5ef229b0035c34fd9b67183d6f0a2b810cc47907 Mon Sep 17 00:00:00 2001 +Message-ID: <5ef229b0035c34fd9b67183d6f0a2b810cc47907.1752837271.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 27 Jun 2025 14:47:10 +0200 +Subject: [PATCH] cgroup: Plumb the 'daemonDomainShutdown' parameter of + 'virSystemdCreateMachine' to drivers + +Plumb the new argument across the cgroup helpers up to the domain driver +code. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit fe57a6deaa8ab83ffdb8ed73104196e4b1421893) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/ch/ch_process.c | 2 ++ + src/hypervisor/domain_cgroup.c | 4 ++++ + src/hypervisor/domain_cgroup.h | 1 + + src/lxc/lxc_cgroup.c | 1 + + src/qemu/qemu_cgroup.c | 1 + + src/util/vircgroup.c | 6 +++++- + src/util/vircgroup.h | 1 + + 7 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c +index 95c808cb41..cc84823fdc 100644 +--- a/src/ch/ch_process.c ++++ b/src/ch/ch_process.c +@@ -973,6 +973,7 @@ virCHProcessStart(virCHDriver *driver, + cfg->cgroupControllers, + 0, /*maxThreadsPerProc*/ + priv->driver->privileged, ++ false, + priv->machineName) < 0) + goto cleanup; + +@@ -1147,6 +1148,7 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from + cfg->cgroupControllers, + 0, /*maxThreadsPerProc*/ + priv->driver->privileged, ++ false, + priv->machineName) < 0) + goto cleanup; + +diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c +index fecc0f7966..8787165f48 100644 +--- a/src/hypervisor/domain_cgroup.c ++++ b/src/hypervisor/domain_cgroup.c +@@ -351,6 +351,7 @@ virDomainCgroupInitCgroup(const char *prefix, + int cgroupControllers, + unsigned int maxThreadsPerProc, + bool privileged, ++ bool daemonDomainShutdown, + char *machineName) + { + if (!privileged) +@@ -384,6 +385,7 @@ virDomainCgroupInitCgroup(const char *prefix, + vm->def->resource->partition, + cgroupControllers, + maxThreadsPerProc, ++ daemonDomainShutdown, + cgroup) < 0) { + if (virCgroupNewIgnoreError()) + return 0; +@@ -513,6 +515,7 @@ virDomainCgroupSetupCgroup(const char *prefix, + int cgroupControllers, + unsigned int maxThreadsPerProc, + bool privileged, ++ bool daemonDomainShutdown, + char *machineName) + { + if (vm->pid == 0) { +@@ -529,6 +532,7 @@ virDomainCgroupSetupCgroup(const char *prefix, + cgroupControllers, + maxThreadsPerProc, + privileged, ++ daemonDomainShutdown, + machineName) < 0) + return -1; + +diff --git a/src/hypervisor/domain_cgroup.h b/src/hypervisor/domain_cgroup.h +index 6e5c98004e..7769572a2c 100644 +--- a/src/hypervisor/domain_cgroup.h ++++ b/src/hypervisor/domain_cgroup.h +@@ -71,6 +71,7 @@ virDomainCgroupSetupCgroup(const char *prefix, + int cgroupControllers, + unsigned int maxThreadsPerProc, + bool privileged, ++ bool daemonDomainShutdown, + char *machineName); + void + virDomainCgroupEmulatorAllNodesDataFree(virCgroupEmulatorAllNodesData *data); +diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c +index 7c889667ba..f566a5468e 100644 +--- a/src/lxc/lxc_cgroup.c ++++ b/src/lxc/lxc_cgroup.c +@@ -400,6 +400,7 @@ virCgroup *virLXCCgroupCreate(virDomainDef *def, + def->resource->partition, + -1, + 0, ++ false, + &cgroup) < 0) + return NULL; + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 48af467bf9..04d6370011 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -919,6 +919,7 @@ qemuSetupCgroup(virDomainObj *vm, + cfg->cgroupControllers, + cfg->maxThreadsPerProc, + priv->driver->privileged, ++ false, + priv->machineName) < 0) + + return -1; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index fc5dca4858..532a7e5690 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1274,6 +1274,7 @@ virCgroupNewMachineSystemd(const char *name, + const char *partition, + int controllers, + unsigned int maxthreads, ++ bool daemonDomainShutdown, + virCgroup **group) + { + int rv; +@@ -1294,7 +1295,7 @@ virCgroupNewMachineSystemd(const char *name, + nicindexes, + partition, + maxthreads, +- false)) < 0) ++ daemonDomainShutdown)) < 0) + return rv; + + if (controllers != -1) +@@ -1407,6 +1408,7 @@ virCgroupNewMachine(const char *name, + const char *partition, + int controllers, + unsigned int maxthreads, ++ bool daemonDomainShutdown, + virCgroup **group) + { + int rv; +@@ -1424,6 +1426,7 @@ virCgroupNewMachine(const char *name, + partition, + controllers, + maxthreads, ++ daemonDomainShutdown, + group)) == 0) + return 0; + +@@ -3144,6 +3147,7 @@ virCgroupNewMachine(const char *name G_GNUC_UNUSED, + const char *partition G_GNUC_UNUSED, + int controllers G_GNUC_UNUSED, + unsigned int maxthreads G_GNUC_UNUSED, ++ bool daemonDomainShutdown G_GNUC_UNUSED, + virCgroup **group G_GNUC_UNUSED) + { + virReportSystemError(ENXIO, "%s", +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index adf3850b22..2a7aa3306c 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -101,6 +101,7 @@ int virCgroupNewMachine(const char *name, + const char *partition, + int controllers, + unsigned int maxthreads, ++ bool daemonDomainShutdown, + virCgroup **group) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) + ATTRIBUTE_NONNULL(3); +-- +2.50.1 diff --git a/libvirt-cgroup-Unexport-virDomainCgroupInitCgroup.patch b/libvirt-cgroup-Unexport-virDomainCgroupInitCgroup.patch new file mode 100644 index 0000000..9be80de --- /dev/null +++ b/libvirt-cgroup-Unexport-virDomainCgroupInitCgroup.patch @@ -0,0 +1,68 @@ +From c7889487359bff14c6d4b236055acfee68da66ae Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Thu, 26 Jun 2025 18:24:06 +0200 +Subject: [PATCH] cgroup: Unexport 'virDomainCgroupInitCgroup' + +The function is called just from one place within the module where it's +defined. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 3e0859566a164f640e75889d08241844b5e61bf8) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/hypervisor/domain_cgroup.c | 2 +- + src/hypervisor/domain_cgroup.h | 10 ---------- + src/libvirt_private.syms | 1 - + 3 files changed, 1 insertion(+), 12 deletions(-) + +diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c +index fda495faf5..fecc0f7966 100644 +--- a/src/hypervisor/domain_cgroup.c ++++ b/src/hypervisor/domain_cgroup.c +@@ -342,7 +342,7 @@ virDomainCgroupSetupCpuCgroup(virDomainObj *vm, + } + + +-int ++static int + virDomainCgroupInitCgroup(const char *prefix, + virDomainObj *vm, + size_t nnicindexes, +diff --git a/src/hypervisor/domain_cgroup.h b/src/hypervisor/domain_cgroup.h +index f8d261a080..6e5c98004e 100644 +--- a/src/hypervisor/domain_cgroup.h ++++ b/src/hypervisor/domain_cgroup.h +@@ -52,16 +52,6 @@ virDomainCgroupSetupCpusetCgroup(virCgroup *cgroup); + int + virDomainCgroupSetupCpuCgroup(virDomainObj *vm, + virCgroup *cgroup); +-int +-virDomainCgroupInitCgroup(const char *prefix, +- virDomainObj *vm, +- size_t nnicindexes, +- int *nicindexes, +- virCgroup **cgroup, +- int cgroupControllers, +- unsigned int maxThreadsPerProc, +- bool privileged, +- char *machineName); + void + virDomainCgroupRestoreCgroupState(virDomainObj *vm, + virCgroup *cgroup); +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index a8ebf9efd8..8f1489ecc8 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1641,7 +1641,6 @@ virSetConnectStorage; + virDomainCgroupConnectCgroup; + virDomainCgroupEmulatorAllNodesAllow; + virDomainCgroupEmulatorAllNodesRestore; +-virDomainCgroupInitCgroup; + virDomainCgroupRemoveCgroup; + virDomainCgroupSetMemoryLimitParameters; + virDomainCgroupSetupBlkio; +-- +2.50.1 diff --git a/libvirt-hypervisor-Split-out-individual-steps-out-of-virDomainDriverAutoShutdown.patch b/libvirt-hypervisor-Split-out-individual-steps-out-of-virDomainDriverAutoShutdown.patch new file mode 100644 index 0000000..04f8f50 --- /dev/null +++ b/libvirt-hypervisor-Split-out-individual-steps-out-of-virDomainDriverAutoShutdown.patch @@ -0,0 +1,325 @@ +From bbb7dceccc95c5329fed28d71b35264a0cdf2b3c Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Tue, 1 Jul 2025 16:11:12 +0200 +Subject: [PATCH] hypervisor: Split out individual steps out of + virDomainDriverAutoShutdown + +'virDomainDriverAutoShutdown' grew into an unwieldy function. Extract +the code for each of the save/shutdown/poweroff steps into helpers and +call them. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit e13e9b46f62d4d9f0aad33983fda39c5f3f7e645) + +https://issues.redhat.com/browse/RHEL-95196 +--- + src/hypervisor/domain_driver.c | 285 +++++++++++++++++++-------------- + 1 file changed, 161 insertions(+), 124 deletions(-) + +diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c +index 353b8875ec..cce6c64d1b 100644 +--- a/src/hypervisor/domain_driver.c ++++ b/src/hypervisor/domain_driver.c +@@ -738,6 +738,164 @@ virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg) + } + + ++static void ++virDomainDriverAutoShutdownDoSave(virDomainPtr *domains, ++ bool *transient, ++ size_t numDomains, ++ virDomainDriverAutoShutdownConfig *cfg) ++{ ++ g_autofree unsigned int *flags = g_new0(unsigned int, numDomains); ++ size_t i; ++ ++ if (cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) ++ return; ++ ++ for (i = 0; i < numDomains; i++) { ++ int state; ++ ++ if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || ++ (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ continue; ++ ++ virSystemdNotifyStatus("Suspending '%s' (%zu of %zu)", ++ virDomainGetName(domains[i]), i + 1, numDomains); ++ VIR_INFO("Suspending '%s'", virDomainGetName(domains[i])); ++ ++ /* ++ * Pause all VMs to make them stop dirtying pages, ++ * so save is quicker. We remember if any VMs were ++ * paused so we can restore that on resume. ++ */ ++ flags[i] = VIR_DOMAIN_SAVE_RUNNING; ++ if (virDomainGetState(domains[i], &state, NULL, 0) == 0) { ++ if (state == VIR_DOMAIN_PAUSED) ++ flags[i] = VIR_DOMAIN_SAVE_PAUSED; ++ } ++ if (cfg->saveBypassCache) ++ flags[i] |= VIR_DOMAIN_SAVE_BYPASS_CACHE; ++ ++ if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) ++ virDomainSuspend(domains[i]); ++ } ++ ++ for (i = 0; i < numDomains; i++) { ++ virSystemdNotifyStatus("Saving '%s' (%zu of %zu)", ++ virDomainGetName(domains[i]), i + 1, numDomains); ++ VIR_INFO("Saving '%s'", virDomainGetName(domains[i])); ++ ++ if (virDomainManagedSave(domains[i], flags[i]) < 0) { ++ VIR_WARN("auto-shutdown: unable to perform managed save of '%s': %s", ++ domains[i]->name, ++ virGetLastErrorMessage()); ++ if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) ++ virDomainResume(domains[i]); ++ continue; ++ } ++ virObjectUnref(domains[i]); ++ domains[i] = NULL; ++ } ++} ++ ++ ++static void ++virDomainDriverAutoShutdownDoShutdown(virDomainPtr *domains, ++ bool *transient, ++ size_t numDomains, ++ virDomainDriverAutoShutdownConfig *cfg) ++{ ++ GTimer *timer = NULL; ++ size_t i; ++ ++ if (cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) ++ return; ++ ++ for (i = 0; i < numDomains; i++) { ++ if (domains[i] == NULL) ++ continue; ++ ++ if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || ++ (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ continue; ++ ++ virSystemdNotifyStatus("Shutting down '%s' (%zu of %zu)", ++ virDomainGetName(domains[i]), i + 1, numDomains); ++ VIR_INFO("Shutting down '%s'", virDomainGetName(domains[i])); ++ ++ if (virDomainShutdown(domains[i]) < 0) { ++ VIR_WARN("auto-shutdown: unable to request graceful shutdown of '%s': %s", ++ domains[i]->name, ++ virGetLastErrorMessage()); ++ break; ++ } ++ } ++ ++ timer = g_timer_new(); ++ virSystemdNotifyStatus("Waiting %u secs for VM shutdown completion", ++ cfg->waitShutdownSecs); ++ VIR_INFO("Waiting %u secs for VM shutdown completion", cfg->waitShutdownSecs); ++ while (1) { ++ bool anyRunning = false; ++ for (i = 0; i < numDomains; i++) { ++ if (!domains[i]) ++ continue; ++ ++ if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || ++ (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ continue; ++ ++ if (virDomainIsActive(domains[i]) == 1) { ++ anyRunning = true; ++ } else { ++ virObjectUnref(domains[i]); ++ domains[i] = NULL; ++ } ++ } ++ ++ if (!anyRunning) ++ break; ++ if (g_timer_elapsed(timer, NULL) > cfg->waitShutdownSecs) ++ break; ++ g_usleep(1000*500); ++ } ++ g_timer_destroy(timer); ++} ++ ++ ++static void ++virDomainDriverAutoShutdownDoPoweroff(virDomainPtr *domains, ++ bool *transient, ++ size_t numDomains, ++ virDomainDriverAutoShutdownConfig *cfg) ++{ ++ size_t i; ++ ++ if (cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) ++ return; ++ ++ for (i = 0; i < numDomains; i++) { ++ if (domains[i] == NULL) ++ continue; ++ ++ if ((transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || ++ (!transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ continue; ++ ++ virSystemdNotifyStatus("Destroying '%s' (%zu of %zu)", ++ virDomainGetName(domains[i]), i + 1, numDomains); ++ VIR_INFO("Destroying '%s'", virDomainGetName(domains[i])); ++ /* ++ * NB might fail if we gave up on waiting for ++ * virDomainShutdown, but it then completed anyway, ++ * hence we're not checking for failure ++ */ ++ virDomainDestroy(domains[i]); ++ ++ virObjectUnref(domains[i]); ++ domains[i] = NULL; ++ } ++} ++ ++ + void + virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) + { +@@ -816,130 +974,9 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) + } + } + +- if (cfg->trySave != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { +- g_autofree unsigned int *flags = g_new0(unsigned int, numDomains); +- for (i = 0; i < numDomains; i++) { +- int state; +- +- if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) +- continue; +- +- virSystemdNotifyStatus("Suspending '%s' (%zu of %d)", +- virDomainGetName(domains[i]), i + 1, numDomains); +- VIR_INFO("Suspending '%s'", virDomainGetName(domains[i])); +- +- /* +- * Pause all VMs to make them stop dirtying pages, +- * so save is quicker. We remember if any VMs were +- * paused so we can restore that on resume. +- */ +- flags[i] = VIR_DOMAIN_SAVE_RUNNING; +- if (virDomainGetState(domains[i], &state, NULL, 0) == 0) { +- if (state == VIR_DOMAIN_PAUSED) +- flags[i] = VIR_DOMAIN_SAVE_PAUSED; +- } +- if (cfg->saveBypassCache) +- flags[i] |= VIR_DOMAIN_SAVE_BYPASS_CACHE; +- +- if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) +- virDomainSuspend(domains[i]); +- } +- +- for (i = 0; i < numDomains; i++) { +- virSystemdNotifyStatus("Saving '%s' (%zu of %d)", +- virDomainGetName(domains[i]), i + 1, numDomains); +- VIR_INFO("Saving '%s'", virDomainGetName(domains[i])); +- +- if (virDomainManagedSave(domains[i], flags[i]) < 0) { +- VIR_WARN("auto-shutdown: unable to perform managed save of '%s': %s", +- domains[i]->name, +- virGetLastErrorMessage()); +- if (flags[i] & VIR_DOMAIN_SAVE_RUNNING) +- virDomainResume(domains[i]); +- continue; +- } +- virObjectUnref(domains[i]); +- domains[i] = NULL; +- } +- } +- +- if (cfg->tryShutdown != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { +- GTimer *timer = NULL; +- for (i = 0; i < numDomains; i++) { +- if (domains[i] == NULL) +- continue; +- +- if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) +- continue; +- +- virSystemdNotifyStatus("Shutting down '%s' (%zu of %d)", +- virDomainGetName(domains[i]), i + 1, numDomains); +- VIR_INFO("Shutting down '%s'", virDomainGetName(domains[i])); +- +- if (virDomainShutdown(domains[i]) < 0) { +- VIR_WARN("auto-shutdown: unable to request graceful shutdown of '%s': %s", +- domains[i]->name, +- virGetLastErrorMessage()); +- break; +- } +- } +- +- timer = g_timer_new(); +- virSystemdNotifyStatus("Waiting %u secs for VM shutdown completion", +- cfg->waitShutdownSecs); +- VIR_INFO("Waiting %u secs for VM shutdown completion", cfg->waitShutdownSecs); +- while (1) { +- bool anyRunning = false; +- for (i = 0; i < numDomains; i++) { +- if (!domains[i]) +- continue; +- +- if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) +- continue; +- +- if (virDomainIsActive(domains[i]) == 1) { +- anyRunning = true; +- } else { +- virObjectUnref(domains[i]); +- domains[i] = NULL; +- } +- } +- +- if (!anyRunning) +- break; +- if (g_timer_elapsed(timer, NULL) > cfg->waitShutdownSecs) +- break; +- g_usleep(1000*500); +- } +- g_timer_destroy(timer); +- } +- +- if (cfg->poweroff != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) { +- for (i = 0; i < numDomains; i++) { +- if (domains[i] == NULL) +- continue; +- +- if ((transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) +- continue; +- +- virSystemdNotifyStatus("Destroying '%s' (%zu of %d)", +- virDomainGetName(domains[i]), i + 1, numDomains); +- VIR_INFO("Destroying '%s'", virDomainGetName(domains[i])); +- /* +- * NB might fail if we gave up on waiting for +- * virDomainShutdown, but it then completed anyway, +- * hence we're not checking for failure +- */ +- virDomainDestroy(domains[i]); +- +- virObjectUnref(domains[i]); +- domains[i] = NULL; +- } +- } ++ virDomainDriverAutoShutdownDoSave(domains, transient, numDomains, cfg); ++ virDomainDriverAutoShutdownDoShutdown(domains, transient, numDomains, cfg); ++ virDomainDriverAutoShutdownDoPoweroff(domains, transient, numDomains, cfg); + + virSystemdNotifyStatus("Processed %d domains", numDomains); + VIR_INFO("Processed %d domains", numDomains); +-- +2.50.1 diff --git a/libvirt-hypervisor-domain-Extract-logic-for-auto-shutdown-to-virDomainDriverAutoShutdownActive.patch b/libvirt-hypervisor-domain-Extract-logic-for-auto-shutdown-to-virDomainDriverAutoShutdownActive.patch new file mode 100644 index 0000000..c8e0eb1 --- /dev/null +++ b/libvirt-hypervisor-domain-Extract-logic-for-auto-shutdown-to-virDomainDriverAutoShutdownActive.patch @@ -0,0 +1,77 @@ +From 8ebd4e7c38291929f8a6c481b768a4d8355ea19c Mon Sep 17 00:00:00 2001 +Message-ID: <8ebd4e7c38291929f8a6c481b768a4d8355ea19c.1752837271.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 27 Jun 2025 15:22:22 +0200 +Subject: [PATCH] hypervisor: domain: Extract logic for auto shutdown to + virDomainDriverAutoShutdownActive + +Extract the checker that determines whether the daemon auto shutdown +functionality is active to a separate helper +'virDomainDriverAutoShutdownActive'. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit bb51963bb173b28dacb6a1374712b1344e9a61c2) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/hypervisor/domain_driver.c | 13 ++++++++++--- + src/hypervisor/domain_driver.h | 1 + + src/libvirt_private.syms | 1 + + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c +index 62bbe176ae..353b8875ec 100644 +--- a/src/hypervisor/domain_driver.c ++++ b/src/hypervisor/domain_driver.c +@@ -729,6 +729,15 @@ virDomainDriverAutoStart(virDomainObjList *domains, + } + + ++bool ++virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg) ++{ ++ return cfg->trySave != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE || ++ cfg->tryShutdown != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE || ++ cfg->poweroff != VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; ++} ++ ++ + void + virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) + { +@@ -773,9 +782,7 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) + } + + /* Short-circuit if all actions are disabled */ +- if (cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE && +- cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE && +- cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) ++ if (!virDomainDriverAutoShutdownActive(cfg)) + return; + + if (!(conn = virConnectOpen(cfg->uri))) +diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h +index d90466b942..af1c4eaed6 100644 +--- a/src/hypervisor/domain_driver.h ++++ b/src/hypervisor/domain_driver.h +@@ -116,4 +116,5 @@ typedef struct _virDomainDriverAutoShutdownConfig { + bool autoRestore; + } virDomainDriverAutoShutdownConfig; + ++bool virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg); + void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg); +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 8f1489ecc8..1b9be478e4 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1658,6 +1658,7 @@ virDomainCgroupSetupVcpuBW; + # hypervisor/domain_driver.h + virDomainDriverAddIOThreadCheck; + virDomainDriverAutoShutdown; ++virDomainDriverAutoShutdownActive; + virDomainDriverAutoShutdownScopeTypeFromString; + virDomainDriverAutoShutdownScopeTypeToString; + virDomainDriverAutoStart; +-- +2.50.1 diff --git a/libvirt-kbase-tlscerts-Drop-encryption_key-feature-request.patch b/libvirt-kbase-tlscerts-Drop-encryption_key-feature-request.patch new file mode 100644 index 0000000..7b2785f --- /dev/null +++ b/libvirt-kbase-tlscerts-Drop-encryption_key-feature-request.patch @@ -0,0 +1,44 @@ +From c50a7108b0090fdce43c7f9d0cef9c905c989cc5 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Tue, 1 Jul 2025 13:46:59 +0200 +Subject: [PATCH] kbase: tlscerts: Drop 'encryption_key' feature request +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As TLS 1.3 performs key exchange separately from the algorithm used to +verify authenticity, the certificates for libvirt's use of TLS don't +need to require the 'encryption_key' feature any more. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 3da460236968be1c67a38a01711d46cb257a7125) + +https://issues.redhat.com/browse/RHEL-100711 +--- + docs/kbase/tlscerts.rst | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/docs/kbase/tlscerts.rst b/docs/kbase/tlscerts.rst +index e4aa5bb3c9..215d454998 100644 +--- a/docs/kbase/tlscerts.rst ++++ b/docs/kbase/tlscerts.rst +@@ -204,7 +204,6 @@ define the server as follows: + ip_address = 2001:cafe::74 + ip_address = fe20::24 + tls_www_server +- encryption_key + signing_key + + The 'cn' field should refer to the fully qualified public hostname of the +@@ -298,7 +297,6 @@ briefly cover the steps. + organization = Libvirt Project + cn = client1 + tls_www_client +- encryption_key + signing_key + + and sign by doing: +-- +2.50.1 diff --git a/libvirt-qemu-Fix-auto-shutdown-of-qemu-VMs-by-the-qemu-driver.patch b/libvirt-qemu-Fix-auto-shutdown-of-qemu-VMs-by-the-qemu-driver.patch new file mode 100644 index 0000000..4fe9362 --- /dev/null +++ b/libvirt-qemu-Fix-auto-shutdown-of-qemu-VMs-by-the-qemu-driver.patch @@ -0,0 +1,93 @@ +From 79f9281a8d3dcd15b2332e2e4f599617d47b5fd0 Mon Sep 17 00:00:00 2001 +Message-ID: <79f9281a8d3dcd15b2332e2e4f599617d47b5fd0.1752837271.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 27 Jun 2025 16:10:03 +0200 +Subject: [PATCH] qemu: Fix auto-shutdown of qemu VMs by the qemu driver + +When auto-shutdown via the qemu driver is requested (rather than via +libvirt guests) we need to start the VMs in a way that they will be kept +around for libvirt to terminate them. This involves inverting the +dependancy relationship for the machined unit file. + +Since the setup is done at startup of the VM, add a disclaimer to +qemu.conf that switching between the two modes with VMs running will not +work properly. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 82963fdcb67742fad3066d31f2bd9b14c8153574) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/qemu/qemu.conf.in | 15 ++++++++++++++- + src/qemu/qemu_cgroup.c | 8 +++++++- + 2 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in +index 221bfa8095..6358a45ae2 100644 +--- a/src/qemu/qemu.conf.in ++++ b/src/qemu/qemu.conf.in +@@ -663,7 +663,10 @@ + # implemented for transient VMs. + # + # If 'libvirt-guests.service' is enabled, then this must be +-# set to 'none' for system daemons to avoid dueling actions ++# set to 'none' for system daemons to avoid dueling actions. ++# Warning: Switching between 'libvirt-guests.service' and this option ++# causes VMs running at that point to misbehave on host shutdown unless ++# they are restarted, or saved and restored. + #auto_shutdown_try_save = "persistent" + + # As above, but with a graceful shutdown action instead of +@@ -675,6 +678,9 @@ + # + # If 'libvirt-guests.service' is enabled, then this must be + # set to 'none' for system daemons to avoid dueling actions ++# Warning: Switching between 'libvirt-guests.service' and this option ++# causes VMs running at that point to misbehave on host shutdown unless ++# they are restarted, or saved and restored. + #auto_shutdown_try_shutdown = "all" + + # As above, but with a forced poweroff instead of managed +@@ -687,6 +693,13 @@ + # + # If 'libvirt-guests.service' is enabled, then this must be + # set to 'none' for system daemons to avoid dueling actions ++# ++# Warning: Switching between 'libvirt-guests.service' and this option ++# causes VMs running at that point to misbehave on host shutdown unless ++# they are restarted, or saved and restored. ++# ++# When using any 'auto_shutdown_try_save', 'auto_shutdown_try_shutdown' this ++# feature should to be enabled as well to ensure proper cleanup of the VMs. + #auto_shutdown_poweroff = "all" + + # How may seconds to wait for running VMs to gracefully shutdown +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 04d6370011..25e42ebfc6 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -910,6 +910,12 @@ qemuSetupCgroup(virDomainObj *vm, + { + qemuDomainObjPrivate *priv = vm->privateData; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); ++ /* When users wants to auto-shutdown the VMs via the qemu daemon itself ++ * we need to instruct machined to create dependencies for the units ++ * in such way that the VMs will not be killed before the auto shutdown ++ * code is reached. ++ */ ++ bool daemonAutoShutdown = virDomainDriverAutoShutdownActive(&cfg->autoShutdown); + + if (virDomainCgroupSetupCgroup("qemu", + vm, +@@ -919,7 +925,7 @@ qemuSetupCgroup(virDomainObj *vm, + cfg->cgroupControllers, + cfg->maxThreadsPerProc, + priv->driver->privileged, +- false, ++ daemonAutoShutdown, + priv->machineName) < 0) + + return -1; +-- +2.50.1 diff --git a/libvirt-qemu-conf-Store-autoShutdown-config-in-virDomainDriverAutoShutdownConfig.patch b/libvirt-qemu-conf-Store-autoShutdown-config-in-virDomainDriverAutoShutdownConfig.patch new file mode 100644 index 0000000..12d456d --- /dev/null +++ b/libvirt-qemu-conf-Store-autoShutdown-config-in-virDomainDriverAutoShutdownConfig.patch @@ -0,0 +1,137 @@ +From 44d1e39ed66596dfb8d2d4046aa5b0aa91d6dc88 Mon Sep 17 00:00:00 2001 +Message-ID: <44d1e39ed66596dfb8d2d4046aa5b0aa91d6dc88.1752837271.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Fri, 27 Jun 2025 15:13:35 +0200 +Subject: [PATCH] qemu: conf: Store 'autoShutdown' config in + virDomainDriverAutoShutdownConfig + +Rather than having a bunch of extra variables save the configuration of +the daemon auto shutdown in virDomainDriverAutoShutdownConfig which is +also used when initiating the shutdown. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit c8adb8537b947f76a0be85e9c28de85e351d6b51) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/qemu/qemu_conf.c | 30 +++++++++++++++--------------- + src/qemu/qemu_conf.h | 7 +------ + src/qemu/qemu_driver.c | 12 +++--------- + 3 files changed, 19 insertions(+), 30 deletions(-) + +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index 9bf12fc179..482e19b502 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -320,15 +320,15 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, + * + * XXX, or query if libvirt-guests.service is enabled perhaps ? + */ +- cfg->autoShutdownTrySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; +- cfg->autoShutdownTryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; +- cfg->autoShutdownPoweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; ++ cfg->autoShutdown.trySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; ++ cfg->autoShutdown.tryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; ++ cfg->autoShutdown.poweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE; + } else { +- cfg->autoShutdownTrySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT; +- cfg->autoShutdownTryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL; +- cfg->autoShutdownPoweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL; ++ cfg->autoShutdown.trySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT; ++ cfg->autoShutdown.tryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL; ++ cfg->autoShutdown.poweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL; + } +- cfg->autoShutdownRestore = true; ++ cfg->autoShutdown.autoRestore = true; + + return g_steal_pointer(&cfg); + } +@@ -719,11 +719,11 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *cfg, + autoShutdownTrySave); + return -1; + } +- cfg->autoShutdownTrySave = autoShutdownVal; ++ cfg->autoShutdown.trySave = autoShutdownVal; + } + +- if (cfg->autoShutdownTrySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || +- cfg->autoShutdownTrySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT) { ++ if (cfg->autoShutdown.trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || ++ cfg->autoShutdown.trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("managed save cannot be requested for transient domains")); + return -1; +@@ -740,7 +740,7 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *cfg, + autoShutdownTryShutdown); + return -1; + } +- cfg->autoShutdownTryShutdown = autoShutdownVal; ++ cfg->autoShutdown.tryShutdown = autoShutdownVal; + } + + if (virConfGetValueString(conf, "auto_shutdown_poweroff", &autoShutdownPoweroff) < 0) +@@ -754,16 +754,16 @@ virQEMUDriverConfigLoadSaveEntry(virQEMUDriverConfig *cfg, + autoShutdownPoweroff); + return -1; + } +- cfg->autoShutdownPoweroff = autoShutdownVal; ++ cfg->autoShutdown.poweroff = autoShutdownVal; + } + + if (virConfGetValueUInt(conf, "auto_shutdown_wait", +- &cfg->autoShutdownWait) < 0) ++ &cfg->autoShutdown.waitShutdownSecs) < 0) + return -1; +- if (virConfGetValueBool(conf, "auto_shutdown_restore", &cfg->autoShutdownRestore) < 0) ++ if (virConfGetValueBool(conf, "auto_shutdown_restore", &cfg->autoShutdown.autoRestore) < 0) + return -1; + if (virConfGetValueBool(conf, "auto_save_bypass_cache", +- &cfg->autoSaveBypassCache) < 0) ++ &cfg->autoShutdown.saveBypassCache) < 0) + return -1; + + return 0; +diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h +index 1ce9dbe4a8..ff376aed4d 100644 +--- a/src/qemu/qemu_conf.h ++++ b/src/qemu/qemu_conf.h +@@ -208,12 +208,7 @@ struct _virQEMUDriverConfig { + bool autoDumpBypassCache; + bool autoStartBypassCache; + unsigned int autoStartDelayMS; +- virDomainDriverAutoShutdownScope autoShutdownTrySave; +- virDomainDriverAutoShutdownScope autoShutdownTryShutdown; +- virDomainDriverAutoShutdownScope autoShutdownPoweroff; +- unsigned int autoShutdownWait; +- bool autoShutdownRestore; +- bool autoSaveBypassCache; ++ virDomainDriverAutoShutdownConfig autoShutdown; + + char *lockManagerName; + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 9b583ad7aa..4dbd5ec2fc 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -964,15 +964,9 @@ static int + qemuStateStop(void) + { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(qemu_driver); +- virDomainDriverAutoShutdownConfig ascfg = { +- .uri = cfg->uri, +- .trySave = cfg->autoShutdownTrySave, +- .tryShutdown = cfg->autoShutdownTryShutdown, +- .poweroff = cfg->autoShutdownPoweroff, +- .waitShutdownSecs = cfg->autoShutdownWait, +- .saveBypassCache = cfg->autoSaveBypassCache, +- .autoRestore = cfg->autoShutdownRestore, +- }; ++ virDomainDriverAutoShutdownConfig ascfg = cfg->autoShutdown; ++ ++ ascfg.uri = cfg->uri; + + virDomainDriverAutoShutdown(&ascfg); + +-- +2.50.1 diff --git a/libvirt-qemu_tpm-Do-not-use-persistent-definition-during-pre-start-checks.patch b/libvirt-qemu_tpm-Do-not-use-persistent-definition-during-pre-start-checks.patch new file mode 100644 index 0000000..c12f838 --- /dev/null +++ b/libvirt-qemu_tpm-Do-not-use-persistent-definition-during-pre-start-checks.patch @@ -0,0 +1,43 @@ +From 49a0c4d4d371eb030090e0172144bce00b6e1044 Mon Sep 17 00:00:00 2001 +Message-ID: <49a0c4d4d371eb030090e0172144bce00b6e1044.1753438163.git.jdenemar@redhat.com> +From: Martin Kletzander +Date: Fri, 18 Jul 2025 14:47:58 +0200 +Subject: [PATCH] qemu_tpm: Do not use persistent definition during pre-start + checks + +Commit 3451987fca7c used the persistent TPM Definition in both calls to +qemuTPMVirCommandSwtpmAddTPMState() but in one of the two cases it +might've been NULL and what's more, it is not the right definition which +should've been used. Change that to @tpm which is the current +definition. The other call does not have access to the current +definition and is only called during updating the profile. But for the +sake of fewer future mistakes, keep the other one as is because there is +no issue with calling it that way and adding logic that just skips the +extra check on NULL could mistake someone in the future. + +Signed-off-by: Martin Kletzander +Reviewed-by: Pavel Hrdina +(cherry picked from commit 3a39cfacc36b26be559ab6217fce2a44a2b15159) + +Resolves: https://issues.redhat.com/browse/RHEL-80155 + +Signed-off-by: Martin Kletzander +--- + src/qemu/qemu_tpm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index cdbd6e3993..2e5ec823b2 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -852,7 +852,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + virCommandAddArgFormat(cmd, "type=unixio,path=%s,mode=0600", + tpm->data.emulator.source->data.nix.path); + +- qemuTPMVirCommandSwtpmAddTPMState(cmd, &tpm->data.emulator, persistentTPMDef, cfg); ++ qemuTPMVirCommandSwtpmAddTPMState(cmd, &tpm->data.emulator, tpm, cfg); + + virCommandAddArg(cmd, "--log"); + if (tpm->data.emulator.debug != 0) +-- +2.50.1 diff --git a/libvirt-qemu_tpm-Extract-per-TPM-functionality-from-qemuTPMDomainHasSharedStorage.patch b/libvirt-qemu_tpm-Extract-per-TPM-functionality-from-qemuTPMDomainHasSharedStorage.patch new file mode 100644 index 0000000..93d0d55 --- /dev/null +++ b/libvirt-qemu_tpm-Extract-per-TPM-functionality-from-qemuTPMDomainHasSharedStorage.patch @@ -0,0 +1,108 @@ +From 6361cb03d2bada54287e20b979e26e3b3a7c793d Mon Sep 17 00:00:00 2001 +Message-ID: <6361cb03d2bada54287e20b979e26e3b3a7c793d.1752837271.git.jdenemar@redhat.com> +From: Martin Kletzander +Date: Thu, 17 Jul 2025 11:54:22 +0200 +Subject: [PATCH] qemu_tpm: Extract per-TPM functionality from + qemuTPMDomainHasSharedStorage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This way we can do the check for a particular TPM also elsewhere in the +code, especially in places where we're dealing with only one TPM. The +semantics is changed a little bit in a way that the function will check +all the TPMs as opposed to stopping on the first one which is of the +emulator type, but since a domain can currently only have one of these +it was not an issue. + +Signed-off-by: Martin Kletzander +Reviewed-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit 6c6b6b2b4133f3d6be643416cc3756d940d22ddc) + +Resolves: https://issues.redhat.com/browse/RHEL-80155 + +Signed-off-by: Martin Kletzander +--- + src/qemu/qemu_tpm.c | 59 ++++++++++++++++++++++++++------------------- + 1 file changed, 34 insertions(+), 25 deletions(-) + +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index 8c104ab1b3..855d732e60 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -205,6 +205,40 @@ qemuTPMEmulatorCreateStorage(virDomainTPMDef *tpm, + } + + ++static bool ++qemuTPMHasSharedStorage(const virQEMUDriverConfig *cfg, ++ const virDomainTPMDef *tpm) ++{ ++ switch (tpm->type) { ++ case VIR_DOMAIN_TPM_TYPE_EMULATOR: ++ return virFileIsSharedFS(tpm->data.emulator.source_path, ++ cfg->sharedFilesystems) == 1; ++ case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: ++ case VIR_DOMAIN_TPM_TYPE_EXTERNAL: ++ case VIR_DOMAIN_TPM_TYPE_LAST: ++ break; ++ } ++ ++ return false; ++} ++ ++ ++bool ++qemuTPMDomainHasSharedStorage(virQEMUDriver *driver, ++ virDomainDef *def) ++{ ++ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); ++ size_t i; ++ ++ for (i = 0; i < def->ntpms; i++) { ++ if (qemuTPMHasSharedStorage(cfg, def->tpms[i])) ++ return true; ++ } ++ ++ return false; ++} ++ ++ + /** + * qemuTPMEmulatorDeleteStorage: + * @tpm: TPM definition +@@ -1218,31 +1252,6 @@ qemuTPMEmulatorStart(virQEMUDriver *driver, + } + + +-bool +-qemuTPMDomainHasSharedStorage(virQEMUDriver *driver, +- virDomainDef *def) +-{ +- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); +- size_t i; +- +- for (i = 0; i < def->ntpms; i++) { +- virDomainTPMDef *tpm = def->tpms[i]; +- +- switch (tpm->type) { +- case VIR_DOMAIN_TPM_TYPE_EMULATOR: +- return virFileIsSharedFS(tpm->data.emulator.source_path, +- cfg->sharedFilesystems) == 1; +- case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: +- case VIR_DOMAIN_TPM_TYPE_EXTERNAL: +- case VIR_DOMAIN_TPM_TYPE_LAST: +- break; +- } +- } +- +- return false; +-} +- +- + bool + qemuTPMCanMigrateSharedStorage(virDomainDef *def) + { +-- +2.50.1 diff --git a/libvirt-qemu_tpm-Only-warn-about-missing-locking-feature-on-shared-filesystems.patch b/libvirt-qemu_tpm-Only-warn-about-missing-locking-feature-on-shared-filesystems.patch new file mode 100644 index 0000000..88bd625 --- /dev/null +++ b/libvirt-qemu_tpm-Only-warn-about-missing-locking-feature-on-shared-filesystems.patch @@ -0,0 +1,67 @@ +From 0a38abe57db307e11f28710fd33b10b7dd2988b2 Mon Sep 17 00:00:00 2001 +Message-ID: <0a38abe57db307e11f28710fd33b10b7dd2988b2.1752837271.git.jdenemar@redhat.com> +From: Martin Kletzander +Date: Thu, 17 Jul 2025 11:58:32 +0200 +Subject: [PATCH] qemu_tpm: Only warn about missing locking feature on shared + filesystems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The warning pollutes the logs and might give a bad impression on someone +reading them even though the locking is not always needed. This way we +at least limit the logging in unnecessary cases. + +Resolves: https://issues.redhat.com/browse/RHEL-80155 +Signed-off-by: Martin Kletzander +Reviewed-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit 3451987fca7c89a1aa9c5b0701471b6bc23dda3d) +Signed-off-by: Martin Kletzander +--- + src/qemu/qemu_tpm.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index 855d732e60..cdbd6e3993 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -660,12 +660,16 @@ qemuTPMVirCommandSwtpmAddEncryption(virCommand *cmd, + + static void + qemuTPMVirCommandSwtpmAddTPMState(virCommand *cmd, +- const virDomainTPMEmulatorDef *emulator) ++ const virDomainTPMEmulatorDef *emulator, ++ const virDomainTPMDef *tpmDef, ++ const virQEMUDriverConfig *cfg) + { + const char *lock = ",lock"; + + if (!virTPMSwtpmCapsGet(VIR_TPM_SWTPM_FEATURE_TPMSTATE_OPT_LOCK)) { +- VIR_WARN("This swtpm version doesn't support explicit locking"); ++ if (qemuTPMHasSharedStorage(cfg, tpmDef)) ++ VIR_WARN("This swtpm version doesn't support explicit locking"); ++ + lock = ""; + } + +@@ -721,7 +725,7 @@ qemuTPMEmulatorUpdateProfileName(virDomainTPMEmulatorDef *emulator, + + virCommandAddArgList(cmd, "socket", "--print-info", "0x20", "--tpm2", NULL); + +- qemuTPMVirCommandSwtpmAddTPMState(cmd, emulator); ++ qemuTPMVirCommandSwtpmAddTPMState(cmd, emulator, persistentTPMDef, cfg); + + if (qemuTPMVirCommandSwtpmAddEncryption(cmd, emulator, swtpm) < 0) + return -1; +@@ -848,7 +852,7 @@ qemuTPMEmulatorBuildCommand(virDomainTPMDef *tpm, + virCommandAddArgFormat(cmd, "type=unixio,path=%s,mode=0600", + tpm->data.emulator.source->data.nix.path); + +- qemuTPMVirCommandSwtpmAddTPMState(cmd, &tpm->data.emulator); ++ qemuTPMVirCommandSwtpmAddTPMState(cmd, &tpm->data.emulator, persistentTPMDef, cfg); + + virCommandAddArg(cmd, "--log"); + if (tpm->data.emulator.debug != 0) +-- +2.50.1 diff --git a/libvirt-qemu_tpm-Rename-qemuTPMHasSharedStorage-qemuTPMDomainHasSharedStorage.patch b/libvirt-qemu_tpm-Rename-qemuTPMHasSharedStorage-qemuTPMDomainHasSharedStorage.patch new file mode 100644 index 0000000..13687f6 --- /dev/null +++ b/libvirt-qemu_tpm-Rename-qemuTPMHasSharedStorage-qemuTPMDomainHasSharedStorage.patch @@ -0,0 +1,92 @@ +From d8c8f0d4f82ddbb3f3a59b11b9bd1373e8d82c3d Mon Sep 17 00:00:00 2001 +Message-ID: +From: Martin Kletzander +Date: Thu, 17 Jul 2025 11:51:39 +0200 +Subject: [PATCH] qemu_tpm: Rename qemuTPMHasSharedStorage -> + qemuTPMDomainHasSharedStorage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function deals with the whole domain and the part that handles one +TPM will be useful elsewhere and hence extracted later. This rename +makes it possible for the new function to use the original name of this +renamed one. + +Signed-off-by: Martin Kletzander +Reviewed-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit 05c5aabb475595249ed1eeca1b6f65b21edc0041) + +Resolves: https://issues.redhat.com/browse/RHEL-80155 + +Signed-off-by: Martin Kletzander +--- + src/qemu/qemu_migration.c | 2 +- + src/qemu/qemu_tpm.c | 8 ++++---- + src/qemu/qemu_tpm.h | 4 ++-- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 2400750ee4..090ac8ae1e 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -1721,7 +1721,7 @@ qemuMigrationSrcIsAllowed(virDomainObj *vm, + } + } + +- if (qemuTPMHasSharedStorage(driver, vm->def) && ++ if (qemuTPMDomainHasSharedStorage(driver, vm->def) && + !qemuTPMCanMigrateSharedStorage(vm->def)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("the running swtpm does not support migration with shared storage")); +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index b2f76e6b8b..8c104ab1b3 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -1150,7 +1150,7 @@ qemuTPMEmulatorStart(virQEMUDriver *driver, + virCommandSetPidFile(cmd, pidfile); + virCommandSetErrorFD(cmd, &errfd); + +- if (incomingMigration && qemuTPMHasSharedStorage(driver, vm->def)) { ++ if (incomingMigration && qemuTPMDomainHasSharedStorage(driver, vm->def)) { + /* If the TPM is being migrated over shared storage, we can't + * lock all files before labeling them: the source swtpm + * process is still holding on to the lock file, and it will +@@ -1219,8 +1219,8 @@ qemuTPMEmulatorStart(virQEMUDriver *driver, + + + bool +-qemuTPMHasSharedStorage(virQEMUDriver *driver, +- virDomainDef *def) ++qemuTPMDomainHasSharedStorage(virQEMUDriver *driver, ++ virDomainDef *def) + { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + size_t i; +@@ -1346,7 +1346,7 @@ qemuExtTPMStop(virQEMUDriver *driver, + return; + + qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName); +- if (migration && qemuTPMHasSharedStorage(driver, vm->def)) ++ if (migration && qemuTPMDomainHasSharedStorage(driver, vm->def)) + restoreTPMStateLabel = false; + + if (qemuSecurityRestoreTPMLabels(driver, vm, restoreTPMStateLabel, false) < 0) +diff --git a/src/qemu/qemu_tpm.h b/src/qemu/qemu_tpm.h +index f0f16392a1..2d633fe36b 100644 +--- a/src/qemu/qemu_tpm.h ++++ b/src/qemu/qemu_tpm.h +@@ -61,8 +61,8 @@ int qemuExtTPMSetupCgroup(virQEMUDriver *driver, + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + G_GNUC_WARN_UNUSED_RESULT; + +-bool qemuTPMHasSharedStorage(virQEMUDriver *driver, +- virDomainDef *def) ++bool qemuTPMDomainHasSharedStorage(virQEMUDriver *driver, ++ virDomainDef *def) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) + G_GNUC_WARN_UNUSED_RESULT; + +-- +2.50.1 diff --git a/libvirt-tests-virnettls-test-Drop-use-of-GNUTLS_KEY_KEY_ENCIPHERMENT.patch b/libvirt-tests-virnettls-test-Drop-use-of-GNUTLS_KEY_KEY_ENCIPHERMENT.patch new file mode 100644 index 0000000..e8dcaae --- /dev/null +++ b/libvirt-tests-virnettls-test-Drop-use-of-GNUTLS_KEY_KEY_ENCIPHERMENT.patch @@ -0,0 +1,239 @@ +From a926ee49aeab039d02bffd27034b1410f37f323b Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Tue, 1 Jul 2025 13:48:00 +0200 +Subject: [PATCH] tests: virnettls*test: Drop use of + GNUTLS_KEY_KEY_ENCIPHERMENT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's not needed with TLS 1.3 any more. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit e67952b0e612c9ad3c3eec8bb692589602953ee8) + +https://issues.redhat.com/browse/RHEL-100711 +--- + tests/virnettlscontexttest.c | 36 ++++++++++++++++++------------------ + tests/virnettlssessiontest.c | 14 +++++++------- + 2 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c +index 2311524db8..48bdefdd76 100644 +--- a/tests/virnettlscontexttest.c ++++ b/tests/virnettlscontexttest.c +@@ -156,13 +156,13 @@ mymain(void) + TLS_CERT_REQ(servercertreq, cacertreq, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + TLS_CERT_REQ(clientcertreq, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 0, 0); + +@@ -182,7 +182,7 @@ mymain(void) + TLS_CERT_REQ(servercert1req, cacert1req, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + +@@ -196,7 +196,7 @@ mymain(void) + TLS_CERT_REQ(servercert2req, cacert2req, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + +@@ -210,7 +210,7 @@ mymain(void) + TLS_CERT_REQ(servercert3req, cacert3req, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + +@@ -230,7 +230,7 @@ mymain(void) + TLS_CERT_REQ(servercert4req, cacert4req, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + /* no-basic */ +@@ -243,7 +243,7 @@ mymain(void) + TLS_CERT_REQ(servercert5req, cacert5req, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + /* Key usage:dig-sig:critical */ +@@ -256,7 +256,7 @@ mymain(void) + TLS_CERT_REQ(servercert6req, cacert6req, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + +@@ -284,7 +284,7 @@ mymain(void) + TLS_CERT_REQ(servercert8req, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_KEY_CERT_SIGN, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_CERT_SIGN, + false, false, NULL, NULL, + 0, 0); + /* usage:cert-sign:not-critical */ +@@ -372,7 +372,7 @@ mymain(void) + TLS_CERT_REQ(clientcert2req, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_KEY_CERT_SIGN, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_CERT_SIGN, + false, false, NULL, NULL, + 0, 0); + /* usage:cert-sign:not-critical */ +@@ -459,19 +459,19 @@ mymain(void) + TLS_CERT_REQ(servercertexpreq, cacertexpreq, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + TLS_CERT_REQ(servercertexp1req, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, -1); + TLS_CERT_REQ(clientcertexp1req, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 0, -1); + +@@ -491,19 +491,19 @@ mymain(void) + TLS_CERT_REQ(servercertnewreq, cacertnewreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + TLS_CERT_REQ(servercertnew1req, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 1, 2); + TLS_CERT_REQ(clientcertnew1req, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 1, 2); + +@@ -538,13 +538,13 @@ mymain(void) + TLS_CERT_REQ(servercertlevel3areq, cacertlevel2areq, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, + "UK", "libvirt client level 2b", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 0, 0); + +diff --git a/tests/virnettlssessiontest.c b/tests/virnettlssessiontest.c +index 285cde57d8..459e17c52c 100644 +--- a/tests/virnettlssessiontest.c ++++ b/tests/virnettlssessiontest.c +@@ -314,20 +314,20 @@ mymain(void) + TLS_CERT_REQ(servercertreq, cacertreq, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + TLS_CERT_REQ(clientcertreq, cacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 0, 0); + + TLS_CERT_REQ(clientcertaltreq, altcacertreq, + "UK", "libvirt", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 0, 0); + +@@ -342,14 +342,14 @@ mymain(void) + TLS_CERT_REQ(servercertalt1req, cacertreq, + "UK", "libvirt.org", "www.libvirt.org", "libvirt.org", "192.168.122.1", "fec0::dead:beaf", + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + /* This intentionally doesn't replicate */ + TLS_CERT_REQ(servercertalt2req, cacertreq, + "UK", "libvirt.org", "www.libvirt.org", "wiki.libvirt.org", "192.168.122.1", "fec0::dead:beaf", + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + +@@ -433,13 +433,13 @@ mymain(void) + TLS_CERT_REQ(servercertlevel3areq, cacertlevel2areq, + "UK", "libvirt.org", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, + 0, 0); + TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, + "UK", "libvirt client level 2b", NULL, NULL, NULL, NULL, + true, true, false, +- true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, ++ true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, + true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, + 0, 0); + +-- +2.50.1 diff --git a/libvirt-tls-Don-t-require-keyEncipherment-to-be-enabled-altoghther.patch b/libvirt-tls-Don-t-require-keyEncipherment-to-be-enabled-altoghther.patch new file mode 100644 index 0000000..e8a004b --- /dev/null +++ b/libvirt-tls-Don-t-require-keyEncipherment-to-be-enabled-altoghther.patch @@ -0,0 +1,85 @@ +From 5e7f9ff3044baee5c4528dd68b4e74c852abcf04 Mon Sep 17 00:00:00 2001 +Message-ID: <5e7f9ff3044baee5c4528dd68b4e74c852abcf04.1752837271.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 30 Jun 2025 19:19:42 +0200 +Subject: [PATCH] tls: Don't require 'keyEncipherment' to be enabled altoghther +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Key encipherment is required only for RSA key exchange algorithm. With +TLS 1.3 this is not even used as RSA is used only for authentication. + +Since we can't really check when it's required ahead of time drop the +check completely. GnuTLS will moan if it will not be able to use RSA +key exchange. + +In commit 11867b0224a2 I tried to relax the check for some eliptic +curve algorithm that explicitly forbid it. Based on the above the proper +solution is to completely remove it. + +Resolves: https://issues.redhat.com/browse/RHEL-100711 +Fixes: 11867b0224a2b8dc34755ff0ace446b6842df1c1 +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 8cecd3249e5fa5478a7c53567971b4d969274ea3) + +https://issues.redhat.com/browse/RHEL-100711 +--- + src/rpc/virnettlscert.c | 34 ++++------------------------------ + 1 file changed, 4 insertions(+), 30 deletions(-) + +diff --git a/src/rpc/virnettlscert.c b/src/rpc/virnettlscert.c +index f197995633..6a723c1ed4 100644 +--- a/src/rpc/virnettlscert.c ++++ b/src/rpc/virnettlscert.c +@@ -128,8 +128,10 @@ static int virNetTLSCertCheckKeyUsage(gnutls_x509_crt_t cert, + VIR_DEBUG("Cert %s key usage status %d usage %d critical %u", certFile, status, usage, critical); + if (status < 0) { + if (status == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { +- usage = isCA ? GNUTLS_KEY_KEY_CERT_SIGN : +- GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_KEY_ENCIPHERMENT; ++ if (isCA) ++ usage = GNUTLS_KEY_KEY_CERT_SIGN; ++ else ++ usage = GNUTLS_KEY_DIGITAL_SIGNATURE; + } else { + virReportError(VIR_ERR_SYSTEM_ERROR, + _("Unable to query certificate %1$s key usage %2$s"), +@@ -162,34 +164,6 @@ static int virNetTLSCertCheckKeyUsage(gnutls_x509_crt_t cert, + certFile); + } + } +- if (!(usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) { +- int alg = gnutls_x509_crt_get_pk_algorithm(cert, NULL); +- +- /* Per RFC8813 [1] which amends RFC5580 [2] ECDSA, ECDH, and ECMQV +- * algorithms must not have 'keyEncipherment' present. +- * +- * [1] https://datatracker.ietf.org/doc/rfc8813/ +- * [2] https://datatracker.ietf.org/doc/rfc5480 +- */ +- +- switch (alg) { +- case GNUTLS_PK_ECDSA: +- case GNUTLS_PK_ECDH_X25519: +- case GNUTLS_PK_ECDH_X448: +- break; +- +- default: +- if (critical) { +- virReportError(VIR_ERR_SYSTEM_ERROR, +- _("Certificate %1$s usage does not permit key encipherment"), +- certFile); +- return -1; +- } else { +- VIR_WARN("Certificate %s usage does not permit key encipherment", +- certFile); +- } +- } +- } + } + + return 0; +-- +2.50.1 diff --git a/libvirt-virDomainDriverAutoShutdown-Refactor-selection-logic-for-VMs.patch b/libvirt-virDomainDriverAutoShutdown-Refactor-selection-logic-for-VMs.patch new file mode 100644 index 0000000..fccd697 --- /dev/null +++ b/libvirt-virDomainDriverAutoShutdown-Refactor-selection-logic-for-VMs.patch @@ -0,0 +1,332 @@ +From 518d76ea990261580c502657e4bf7b9dea22b21e Mon Sep 17 00:00:00 2001 +Message-ID: <518d76ea990261580c502657e4bf7b9dea22b21e.1752837271.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Tue, 1 Jul 2025 17:19:46 +0200 +Subject: [PATCH] virDomainDriverAutoShutdown: Refactor selection logic for VMs + +Decide separately and record what shutdown modes are to be applied on +given VM object rather than spreading out the logic through the code. + +This centralization simplifies the conditions in the worker functions +and also: + - provides easy way to check if the auto-shutdown code will be acting + on domain object (will be used to fix attempt to auto-restore of + VMs which were not selected to be acted on + - will simplify further work where the desired shutdown action will be + picked per-VM + +This refactor also fixes a bug where if restoring of the state is +applied also on VMs that are not selected for action based on current +logic. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 1c2295fbafab12cb3f943aab8bd015e167cad533) + +https://issues.redhat.com/browse/RHEL-95196 +--- + src/hypervisor/domain_driver.c | 178 +++++++++++++++++++-------------- + 1 file changed, 101 insertions(+), 77 deletions(-) + +diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c +index d8ccee40d5..88fb87023a 100644 +--- a/src/hypervisor/domain_driver.c ++++ b/src/hypervisor/domain_driver.c +@@ -738,25 +738,32 @@ virDomainDriverAutoShutdownActive(virDomainDriverAutoShutdownConfig *cfg) + } + + ++enum { ++ VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SAVE = 1 << 1, ++ VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SHUTDOWN = 1 << 2, ++ VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_POWEROFF = 1 << 3, ++ VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_RESTORE = 1 << 4, ++} virDomainDriverAutoShutdownModeFlag; ++ ++ + static void + virDomainDriverAutoShutdownDoSave(virDomainPtr *domains, +- bool *transient, ++ unsigned int *modes, + size_t numDomains, + virDomainDriverAutoShutdownConfig *cfg) + { + g_autofree unsigned int *flags = g_new0(unsigned int, numDomains); ++ bool hasSave = false; + size_t i; + +- if (cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) +- return; +- + for (i = 0; i < numDomains; i++) { + int state; + +- if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ if (!(modes[i] & VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SAVE)) + continue; + ++ hasSave = true; ++ + virSystemdNotifyStatus("Suspending '%s' (%zu of %zu)", + virDomainGetName(domains[i]), i + 1, numDomains); + VIR_INFO("Suspending '%s'", virDomainGetName(domains[i])); +@@ -778,9 +785,11 @@ virDomainDriverAutoShutdownDoSave(virDomainPtr *domains, + virDomainSuspend(domains[i]); + } + ++ if (!hasSave) ++ return; ++ + for (i = 0; i < numDomains; i++) { +- if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ if (!(modes[i] & VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SAVE)) + continue; + + virSystemdNotifyStatus("Saving '%s' (%zu of %zu)", +@@ -795,31 +804,27 @@ virDomainDriverAutoShutdownDoSave(virDomainPtr *domains, + virDomainResume(domains[i]); + continue; + } +- virObjectUnref(domains[i]); +- domains[i] = NULL; ++ ++ modes[i] = 0; + } + } + + + static void + virDomainDriverAutoShutdownDoShutdown(virDomainPtr *domains, +- bool *transient, ++ unsigned int *modes, + size_t numDomains, + virDomainDriverAutoShutdownConfig *cfg) + { + GTimer *timer = NULL; ++ bool hasShutdown = false; + size_t i; + +- if (cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) +- return; +- + for (i = 0; i < numDomains; i++) { +- if (domains[i] == NULL) ++ if (!(modes[i] & VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SHUTDOWN)) + continue; + +- if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) +- continue; ++ hasShutdown = true; + + virSystemdNotifyStatus("Shutting down '%s' (%zu of %zu)", + virDomainGetName(domains[i]), i + 1, numDomains); +@@ -833,25 +838,24 @@ virDomainDriverAutoShutdownDoShutdown(virDomainPtr *domains, + } + } + ++ if (!hasShutdown) ++ return; ++ + timer = g_timer_new(); + virSystemdNotifyStatus("Waiting %u secs for VM shutdown completion", + cfg->waitShutdownSecs); + VIR_INFO("Waiting %u secs for VM shutdown completion", cfg->waitShutdownSecs); ++ + while (1) { + bool anyRunning = false; + for (i = 0; i < numDomains; i++) { +- if (!domains[i]) +- continue; +- +- if ((transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ if (!(modes[i] & VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SHUTDOWN)) + continue; + + if (virDomainIsActive(domains[i]) == 1) { + anyRunning = true; + } else { +- virObjectUnref(domains[i]); +- domains[i] = NULL; ++ modes[i] = 0; + } + } + +@@ -867,21 +871,13 @@ virDomainDriverAutoShutdownDoShutdown(virDomainPtr *domains, + + static void + virDomainDriverAutoShutdownDoPoweroff(virDomainPtr *domains, +- bool *transient, +- size_t numDomains, +- virDomainDriverAutoShutdownConfig *cfg) ++ unsigned int *modes, ++ size_t numDomains) + { + size_t i; + +- if (cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE) +- return; +- + for (i = 0; i < numDomains; i++) { +- if (domains[i] == NULL) +- continue; +- +- if ((transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || +- (!transient[i] && cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ if (!(modes[i] & VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_POWEROFF)) + continue; + + virSystemdNotifyStatus("Destroying '%s' (%zu of %zu)", +@@ -894,11 +890,49 @@ virDomainDriverAutoShutdownDoPoweroff(virDomainPtr *domains, + */ + virDomainDestroy(domains[i]); + +- virObjectUnref(domains[i]); +- domains[i] = NULL; ++ modes[i] = 0; + } + } + ++static unsigned int ++virDomainDriverAutoShutdownGetMode(virDomainPtr domain, ++ virDomainDriverAutoShutdownConfig *cfg) ++{ ++ unsigned int mode = 0; ++ ++ if (virDomainIsPersistent(domain) != 0) { ++ if (cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || ++ cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ++ mode |= VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SAVE; ++ ++ if (cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || ++ cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ++ mode |= VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SHUTDOWN; ++ ++ if (cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || ++ cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) ++ mode |= VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_POWEROFF; ++ ++ /* Don't restore VMs which weren't selected for auto-shutdown */ ++ if (mode != 0 && cfg->autoRestore) ++ mode |= VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_RESTORE; ++ } else { ++ if (cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || ++ cfg->tryShutdown == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT) ++ mode |= VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_SHUTDOWN; ++ ++ if (cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL || ++ cfg->poweroff == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT) ++ mode |= VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_POWEROFF; ++ ++ if (cfg->autoRestore) ++ VIR_DEBUG("Cannot auto-restore transient VM '%s'", ++ virDomainGetName(domain)); ++ } ++ ++ return mode; ++} ++ + + void + virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) +@@ -907,7 +941,7 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) + int numDomains = 0; + size_t i; + virDomainPtr *domains = NULL; +- g_autofree bool *transient = NULL; ++ g_autofree unsigned int *modes = NULL; + + VIR_DEBUG("Run autoshutdown uri=%s trySave=%s tryShutdown=%s poweroff=%s waitShutdownSecs=%u saveBypassCache=%d autoRestore=%d", + cfg->uri, +@@ -948,58 +982,48 @@ virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg) + return; + + if (!(conn = virConnectOpen(cfg->uri))) +- goto cleanup; ++ return; + + if ((numDomains = virConnectListAllDomains(conn, + &domains, + VIR_CONNECT_LIST_DOMAINS_ACTIVE)) < 0) +- goto cleanup; ++ return; + + VIR_DEBUG("Auto shutdown with %d running domains", numDomains); + +- transient = g_new0(bool, numDomains); +- for (i = 0; i < numDomains; i++) { +- if (virDomainIsPersistent(domains[i]) == 0) +- transient[i] = true; ++ modes = g_new0(unsigned int, numDomains); + +- if (cfg->autoRestore) { +- if (transient[i]) { +- VIR_DEBUG("Cannot auto-restore transient VM %s", +- virDomainGetName(domains[i])); +- } else { +- VIR_DEBUG("Mark %s for autostart on next boot", +- virDomainGetName(domains[i])); +- if (virDomainSetAutostartOnce(domains[i], 1) < 0) { +- VIR_WARN("Unable to mark domain '%s' for auto restore: %s", +- virDomainGetName(domains[i]), +- virGetLastErrorMessage()); +- } ++ for (i = 0; i < numDomains; i++) { ++ modes[i] = virDomainDriverAutoShutdownGetMode(domains[i], cfg); ++ ++ if (modes[i] == 0) { ++ /* VM wasn't selected for any of the shutdown modes. There's not ++ * much we can do about that as the host is powering off, logging ++ * at least lets admins know */ ++ VIR_WARN("auto-shutdown: domain '%s' not successfully shut off by any action", ++ domains[i]->name); ++ } ++ ++ if (modes[i] & VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_MODE_RESTORE) { ++ VIR_DEBUG("Mark '%s' for autostart on next boot", ++ virDomainGetName(domains[i])); ++ if (virDomainSetAutostartOnce(domains[i], 1) < 0) { ++ VIR_WARN("Unable to mark domain '%s' for auto restore: %s", ++ virDomainGetName(domains[i]), ++ virGetLastErrorMessage()); + } + } + } + +- virDomainDriverAutoShutdownDoSave(domains, transient, numDomains, cfg); +- virDomainDriverAutoShutdownDoShutdown(domains, transient, numDomains, cfg); +- virDomainDriverAutoShutdownDoPoweroff(domains, transient, numDomains, cfg); ++ virDomainDriverAutoShutdownDoSave(domains, modes, numDomains, cfg); ++ virDomainDriverAutoShutdownDoShutdown(domains, modes, numDomains, cfg); ++ virDomainDriverAutoShutdownDoPoweroff(domains, modes, numDomains); + + virSystemdNotifyStatus("Processed %d domains", numDomains); + VIR_INFO("Processed %d domains", numDomains); + +- cleanup: +- if (domains) { +- /* Anything non-NULL in this list indicates none of +- * the configured ations were successful in processing +- * the domain. There's not much we can do about that +- * as the host is powering off, logging at least lets +- * admins know +- */ +- for (i = 0; i < numDomains; i++) { +- if (domains[i] == NULL) +- continue; +- VIR_WARN("auto-shutdown: domain '%s' not successfully shut off by any action", +- domains[i]->name); +- virObjectUnref(domains[i]); +- } +- VIR_FREE(domains); +- } ++ for (i = 0; i < numDomains; i++) ++ virObjectUnref(domains[i]); ++ ++ VIR_FREE(domains); + } +-- +2.50.1 diff --git a/libvirt-virDomainDriverAutoShutdownDoSave-Don-t-attempt-to-save-transient-VMs.patch b/libvirt-virDomainDriverAutoShutdownDoSave-Don-t-attempt-to-save-transient-VMs.patch new file mode 100644 index 0000000..3e51016 --- /dev/null +++ b/libvirt-virDomainDriverAutoShutdownDoSave-Don-t-attempt-to-save-transient-VMs.patch @@ -0,0 +1,41 @@ +From ec623715d2716db078a0248925506d4d75d7fd57 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Thu, 3 Jul 2025 14:18:46 +0200 +Subject: [PATCH] virDomainDriverAutoShutdownDoSave: Don't attempt to save + transient VMs + +Commit 84bb136c31e added code that intended to skip the save of +transient domains but did so only in the setup part where we pause the +VMS. The second loop that actually attempts to save the VM was not +modified so we'd still try saving them: + + Jul 03 14:15:13 andariel virtqemud[247210]: auto-shutdown: unable to perform managed save of 'cd3': Requested operation is not valid: cannot do managed save for transient domain + +Fixes: 84bb136c31e +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit e1f84ca87e20c64999d3e6e1daccbd86dda743ef) + +https://issues.redhat.com/browse/RHEL-95196 +--- + src/hypervisor/domain_driver.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c +index cce6c64d1b..d8ccee40d5 100644 +--- a/src/hypervisor/domain_driver.c ++++ b/src/hypervisor/domain_driver.c +@@ -779,6 +779,10 @@ virDomainDriverAutoShutdownDoSave(virDomainPtr *domains, + } + + for (i = 0; i < numDomains; i++) { ++ if ((transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT) || ++ (!transient[i] && cfg->trySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT)) ++ continue; ++ + virSystemdNotifyStatus("Saving '%s' (%zu of %zu)", + virDomainGetName(domains[i]), i + 1, numDomains); + VIR_INFO("Saving '%s'", virDomainGetName(domains[i])); +-- +2.50.1 diff --git a/libvirt-virSystemdCreateMachine-Add-flag-to-invert-machined-unit-dependencies.patch b/libvirt-virSystemdCreateMachine-Add-flag-to-invert-machined-unit-dependencies.patch new file mode 100644 index 0000000..945229f --- /dev/null +++ b/libvirt-virSystemdCreateMachine-Add-flag-to-invert-machined-unit-dependencies.patch @@ -0,0 +1,178 @@ +From aa234d4ed710432af8aac8fbe79d5cf80ae2b1f6 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Thu, 26 Jun 2025 17:35:17 +0200 +Subject: [PATCH] virSystemdCreateMachine: Add flag to invert machined unit + dependencies + +The existing dependency order of the 'machined' unit file for the domain +we're starting ("After libvirtd/virtqemud"->thus shuts down *before* the +daemon) is intended to work with 'libvirt-guests.service' which requires +the daemon to be around to shut down the VMs. + +If we want to use the integrated auto shutdown done by the daemon itself +we need to be able to instruct the domains (thus the corresponding +machined units to shut down *after* virtqemud/libvirt. + +This means that we need to be able to invert the ordering relationship +to "Before". + +This patch adds a parameter to virSystemdCreateMachine so that when +starting the VM we'll be able to tell the daemon to use the proper +relationship. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 9b12b7e85914dd3d0874dfcd0f6abc0925e3325f) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/util/vircgroup.c | 3 ++- + src/util/virsystemd.c | 27 +++++++++++++++++++++------ + src/util/virsystemd.h | 3 ++- + tests/virsystemdtest.c | 15 +++++++++------ + 4 files changed, 34 insertions(+), 14 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 1daa95e178..fc5dca4858 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1293,7 +1293,8 @@ virCgroupNewMachineSystemd(const char *name, + nnicindexes, + nicindexes, + partition, +- maxthreads)) < 0) ++ maxthreads, ++ false)) < 0) + return rv; + + if (controllers != -1) +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 4f8424ae32..bd174c683e 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -358,6 +358,8 @@ virSystemdGetMachineUnitByPID(pid_t pid) + * @nicindexes: list of network interface indexes + * @partition: name of the slice to place the machine in + * @maxthreads: maximum number of threads the VM process can use ++ * @daemonDomainShutdown: shutdown of domains on host shutdown is done by the ++ * daemon instead of the libvirt-guests script + * + * Returns 0 on success, -1 on fatal error, or -2 if systemd-machine is not available + */ +@@ -370,7 +372,8 @@ int virSystemdCreateMachine(const char *name, + size_t nnicindexes, + int *nicindexes, + const char *partition, +- unsigned int maxthreads) ++ unsigned int maxthreads, ++ bool daemonDomainShutdown) + { + int rc; + GDBusConnection *conn; +@@ -462,11 +465,23 @@ int virSystemdCreateMachine(const char *name, + uuid, 16, sizeof(unsigned char)); + gnicindexes = g_variant_new_fixed_array(G_VARIANT_TYPE("i"), + nicindexes, nnicindexes, sizeof(int)); +- gprops = g_variant_new_parsed("[('Slice', <%s>)," +- " ('After', <['libvirtd.service', %s]>)," +- " ('Before', <['virt-guest-shutdown.target']>)]", +- slicename, +- servicename); ++ ++ if (daemonDomainShutdown) { ++ /* When domains are shut down by the daemon rather than the ++ * "libvirt-guests" script we need ensure that their unit ++ * is ordered so that it's shutdown after the libvirt daemon itself */ ++ gprops = g_variant_new_parsed("[('Slice', <%s>)," ++ " ('Before', <['libvirtd.service', %s]>)]", ++ slicename, ++ servicename); ++ } else { ++ gprops = g_variant_new_parsed("[('Slice', <%s>)," ++ " ('After', <['libvirtd.service', %s]>)," ++ " ('Before', <['virt-guest-shutdown.target']>)]", ++ slicename, ++ servicename); ++ } ++ + message = g_variant_new("(s@ayssus@ai@a(sv))", + name, + guuid, +diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h +index 98460dbc3a..620d9a9645 100644 +--- a/src/util/virsystemd.h ++++ b/src/util/virsystemd.h +@@ -40,7 +40,8 @@ int virSystemdCreateMachine(const char *name, + size_t nnicindexes, + int *nicindexes, + const char *partition, +- unsigned int maxthreads); ++ unsigned int maxthreads, ++ bool daemonDomainShutdown); + + int virSystemdTerminateMachine(const char *name); + +diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c +index 004b0549ce..24c118a409 100644 +--- a/tests/virsystemdtest.c ++++ b/tests/virsystemdtest.c +@@ -170,7 +170,8 @@ static int testCreateContainer(const void *opaque G_GNUC_UNUSED) + 123, + true, + 0, NULL, +- "highpriority.slice", 0) < 0) { ++ "highpriority.slice", 0, ++ false) < 0) { + fprintf(stderr, "%s", "Failed to create LXC machine\n"); + return -1; + } +@@ -203,7 +204,9 @@ static int testCreateMachine(const void *opaque G_GNUC_UNUSED) + 123, + false, + 0, NULL, +- NULL, 0) < 0) { ++ NULL, ++ 0, ++ true) < 0) { + fprintf(stderr, "%s", "Failed to create KVM machine\n"); + return -1; + } +@@ -240,7 +243,7 @@ static int testCreateNoSystemd(const void *opaque G_GNUC_UNUSED) + 123, + false, + 0, NULL, +- NULL, 0)) == 0) { ++ NULL, 0, false)) == 0) { + g_unsetenv("FAIL_NO_SERVICE"); + fprintf(stderr, "%s", "Unexpected create machine success\n"); + return -1; +@@ -274,7 +277,7 @@ static int testCreateSystemdNotRunning(const void *opaque G_GNUC_UNUSED) + 123, + false, + 0, NULL, +- NULL, 0)) == 0) { ++ NULL, 0, false)) == 0) { + g_unsetenv("FAIL_NOT_REGISTERED"); + fprintf(stderr, "%s", "Unexpected create machine success\n"); + return -1; +@@ -308,7 +311,7 @@ static int testCreateBadSystemd(const void *opaque G_GNUC_UNUSED) + 123, + false, + 0, NULL, +- NULL, 0)) == 0) { ++ NULL, 0, false)) == 0) { + g_unsetenv("FAIL_BAD_SERVICE"); + fprintf(stderr, "%s", "Unexpected create machine success\n"); + return -1; +@@ -343,7 +346,7 @@ static int testCreateNetwork(const void *opaque G_GNUC_UNUSED) + 123, + true, + nnicindexes, nicindexes, +- "highpriority.slice", 2) < 0) { ++ "highpriority.slice", 2, false) < 0) { + fprintf(stderr, "%s", "Failed to create LXC machine\n"); + return -1; + } +-- +2.50.1 diff --git a/libvirt-virSystemdCreateMachine-Document-maxthreds.patch b/libvirt-virSystemdCreateMachine-Document-maxthreds.patch new file mode 100644 index 0000000..18e3dce --- /dev/null +++ b/libvirt-virSystemdCreateMachine-Document-maxthreds.patch @@ -0,0 +1,32 @@ +From a979205ad19aafc0cea99f66debff32704882fa4 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Thu, 26 Jun 2025 17:20:21 +0200 +Subject: [PATCH] virSystemdCreateMachine: Document @maxthreds + +The parameter overrides the maximum number of threads for the machine. + +Fixes: d5572f62e32 +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 0df20b69c8c235946a307ee9b031002d69137852) + +https://issues.redhat.com/browse/RHEL-95361 +--- + src/util/virsystemd.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 92d2890360..4f8424ae32 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -357,6 +357,7 @@ virSystemdGetMachineUnitByPID(pid_t pid) + * @nnicindexes: number of network interface indexes in list + * @nicindexes: list of network interface indexes + * @partition: name of the slice to place the machine in ++ * @maxthreads: maximum number of threads the VM process can use + * + * Returns 0 on success, -1 on fatal error, or -2 if systemd-machine is not available + */ +-- +2.50.1 diff --git a/libvirt.spec b/libvirt.spec index 00b4cb6..0a025ab 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -293,7 +293,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 11.5.0 -Release: 1%{?dist}%{?extra_release}.alma.1 +Release: 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/ @@ -301,6 +301,24 @@ URL: https://libvirt.org/ %define mainturl stable_updates/ %endif Source: https://download.libvirt.org/%{?mainturl}libvirt-%{version}.tar.xz +Patch1: libvirt-virSystemdCreateMachine-Document-maxthreds.patch +Patch2: libvirt-cgroup-Unexport-virDomainCgroupInitCgroup.patch +Patch3: libvirt-qemu-conf-Store-autoShutdown-config-in-virDomainDriverAutoShutdownConfig.patch +Patch4: libvirt-hypervisor-domain-Extract-logic-for-auto-shutdown-to-virDomainDriverAutoShutdownActive.patch +Patch5: libvirt-virSystemdCreateMachine-Add-flag-to-invert-machined-unit-dependencies.patch +Patch6: libvirt-cgroup-Plumb-the-daemonDomainShutdown-parameter-of-virSystemdCreateMachine-to-drivers.patch +Patch7: libvirt-qemu-Fix-auto-shutdown-of-qemu-VMs-by-the-qemu-driver.patch +Patch8: libvirt-hypervisor-Split-out-individual-steps-out-of-virDomainDriverAutoShutdown.patch +Patch9: libvirt-virDomainDriverAutoShutdownDoSave-Don-t-attempt-to-save-transient-VMs.patch +Patch10: libvirt-virDomainDriverAutoShutdown-Refactor-selection-logic-for-VMs.patch +Patch11: libvirt-tls-Don-t-require-keyEncipherment-to-be-enabled-altoghther.patch +Patch12: libvirt-kbase-tlscerts-Drop-encryption_key-feature-request.patch +Patch13: libvirt-tests-virnettls-test-Drop-use-of-GNUTLS_KEY_KEY_ENCIPHERMENT.patch +Patch14: libvirt-qemu_tpm-Rename-qemuTPMHasSharedStorage-qemuTPMDomainHasSharedStorage.patch +Patch15: libvirt-qemu_tpm-Extract-per-TPM-functionality-from-qemuTPMDomainHasSharedStorage.patch +Patch16: libvirt-qemu_tpm-Only-warn-about-missing-locking-feature-on-shared-filesystems.patch +Patch17: libvirt-qemu_tpm-Do-not-use-persistent-definition-during-pre-start-checks.patch + Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1163,6 +1181,9 @@ MinGW Windows libvirt virtualization library. %prep %autosetup -S git_am -N +%autopatch + + %build %if 0%{?fedora} >= %{min_fedora} || 0%{?rhel} >= %{min_rhel} %define supported_platform 1 @@ -2692,9 +2713,30 @@ exit 0 %endif %changelog -* Thu Jul 03 2025 Eduard Abdullin - 11.5.0-1.alma.1 +* Tue Jul 29 2025 Eduard Abdullin - 11.5.0-3.alma.1 - Enable building for ppc64le +* Fri Jul 25 2025 Jiri Denemark - 11.5.0-3 +- qemu_tpm: Do not use persistent definition during pre-start checks (RHEL-80155) + +* Fri Jul 18 2025 Jiri Denemark - 11.5.0-2 +- virSystemdCreateMachine: Document @maxthreds (RHEL-95361) +- cgroup: Unexport 'virDomainCgroupInitCgroup' (RHEL-95361) +- qemu: conf: Store 'autoShutdown' config in virDomainDriverAutoShutdownConfig (RHEL-95361) +- hypervisor: domain: Extract logic for auto shutdown to virDomainDriverAutoShutdownActive (RHEL-95361) +- virSystemdCreateMachine: Add flag to invert machined unit dependencies (RHEL-95361) +- cgroup: Plumb the 'daemonDomainShutdown' parameter of 'virSystemdCreateMachine' to drivers (RHEL-95361) +- qemu: Fix auto-shutdown of qemu VMs by the qemu driver (RHEL-95361) +- hypervisor: Split out individual steps out of virDomainDriverAutoShutdown (RHEL-95196) +- virDomainDriverAutoShutdownDoSave: Don't attempt to save transient VMs (RHEL-95196) +- virDomainDriverAutoShutdown: Refactor selection logic for VMs (RHEL-95196) +- tls: Don't require 'keyEncipherment' to be enabled altoghther (RHEL-100711) +- kbase: tlscerts: Drop 'encryption_key' feature request (RHEL-100711) +- tests: virnettls*test: Drop use of GNUTLS_KEY_KEY_ENCIPHERMENT (RHEL-100711) +- qemu_tpm: Rename qemuTPMHasSharedStorage -> qemuTPMDomainHasSharedStorage (RHEL-80155) +- qemu_tpm: Extract per-TPM functionality from qemuTPMDomainHasSharedStorage (RHEL-80155) +- qemu_tpm: Only warn about missing locking feature on shared filesystems (RHEL-80155) + * Tue Jul 1 2025 Jiri Denemark - 11.5.0-1 - Rebased to libvirt-11.5.0 (RHEL-71662) - The rebase also fixes the following bugs: