]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
hypervisor: move support for auto-shutdown out of QEMU driver
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 17 Dec 2024 10:04:35 +0000 (10:04 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 20 Mar 2025 14:55:17 +0000 (14:55 +0000)
This is a move of the code that currently exists in the QEMU
driver, into the common layer that can be used by multiple
drivers.

The code currently supports performing managed save of all
running guests, ignoring any failures.

Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/hypervisor/domain_driver.c
src/hypervisor/domain_driver.h
src/libvirt_private.syms
src/qemu/qemu_driver.c

index 29ba358477e060d14456adb73ad509ff59869f53..5dfa211faef2ae358be423839c543917d1e0308d 100644 (file)
@@ -713,3 +713,51 @@ virDomainDriverAutoStart(virDomainObjList *domains,
 
     virDomainObjListForEach(domains, false, virDomainDriverAutoStartOne, &state);
 }
+
+
+void
+virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg)
+{
+    g_autoptr(virConnect) conn = NULL;
+    int numDomains = 0;
+    size_t i;
+    int state;
+    virDomainPtr *domains = NULL;
+    g_autofree unsigned int *flags = NULL;
+
+    if (!(conn = virConnectOpen(cfg->uri)))
+        goto cleanup;
+
+    if ((numDomains = virConnectListAllDomains(conn,
+                                               &domains,
+                                               VIR_CONNECT_LIST_DOMAINS_ACTIVE)) < 0)
+        goto cleanup;
+
+    flags = g_new0(unsigned int, numDomains);
+
+    /* First we pause all VMs to make them stop dirtying
+       pages, etc. We remember if any VMs were paused so
+       we can restore that on resume. */
+    for (i = 0; i < numDomains; i++) {
+        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;
+        }
+        virDomainSuspend(domains[i]);
+    }
+
+    /* Then we save the VMs to disk */
+    for (i = 0; i < numDomains; i++)
+        if (virDomainManagedSave(domains[i], flags[i]) < 0)
+            VIR_WARN("Unable to perform managed save of '%s': %s",
+                     virDomainGetName(domains[i]),
+                     virGetLastErrorMessage());
+
+ cleanup:
+    if (domains) {
+        for (i = 0; i < numDomains; i++)
+            virObjectUnref(domains[i]);
+        VIR_FREE(domains);
+    }
+}
index f81d436c2cf6e635444878e20c115855535d86a8..f36db5c6f06bf7d207f5e5681850a65e2335fab3 100644 (file)
@@ -90,3 +90,9 @@ typedef struct _virDomainDriverAutoStartConfig {
 
 void virDomainDriverAutoStart(virDomainObjList *domains,
                               virDomainDriverAutoStartConfig *cfg);
+
+typedef struct _virDomainDriverAutoShutdownConfig {
+    const char *uri;
+} virDomainDriverAutoShutdownConfig;
+
+void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg);
index f4ec26eba3596b87ee2c5762fa09d2d804f8c3b9..4b888c63f1999739d84c8d7209fb718004b309d4 100644 (file)
@@ -1649,6 +1649,7 @@ virDomainCgroupSetupVcpuBW;
 
 # hypervisor/domain_driver.h
 virDomainDriverAddIOThreadCheck;
+virDomainDriverAutoShutdown;
 virDomainDriverAutoStart;
 virDomainDriverDelIOThreadCheck;
 virDomainDriverGenerateMachineName;
index d87d38c4b9afbf57efac2e1f2b8a38785d8696de..5f0f4561849e0b1a4106377dd08b47bfcefd58ac 100644 (file)
@@ -963,51 +963,14 @@ qemuStateReload(void)
 static int
 qemuStateStop(void)
 {
-    int ret = -1;
-    g_autoptr(virConnect) conn = NULL;
-    int numDomains = 0;
-    size_t i;
-    int state;
-    virDomainPtr *domains = NULL;
-    g_autofree unsigned int *flags = NULL;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(qemu_driver);
+    virDomainDriverAutoShutdownConfig ascfg = {
+        .uri = cfg->uri,
+    };
 
-    if (!(conn = virConnectOpen(cfg->uri)))
-        goto cleanup;
-
-    if ((numDomains = virConnectListAllDomains(conn,
-                                               &domains,
-                                               VIR_CONNECT_LIST_DOMAINS_ACTIVE)) < 0)
-        goto cleanup;
-
-    flags = g_new0(unsigned int, numDomains);
-
-    /* First we pause all VMs to make them stop dirtying
-       pages, etc. We remember if any VMs were paused so
-       we can restore that on resume. */
-    for (i = 0; i < numDomains; i++) {
-        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;
-        }
-        virDomainSuspend(domains[i]);
-    }
-
-    ret = 0;
-    /* Then we save the VMs to disk */
-    for (i = 0; i < numDomains; i++)
-        if (virDomainManagedSave(domains[i], flags[i]) < 0)
-            ret = -1;
-
- cleanup:
-    if (domains) {
-        for (i = 0; i < numDomains; i++)
-            virObjectUnref(domains[i]);
-        VIR_FREE(domains);
-    }
+    virDomainDriverAutoShutdown(&ascfg);
 
-    return ret;
+    return 0;
 }