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 <pkre...@redhat.com>
Signed-off-by: Daniel P. Berrangé <berra...@redhat.com>
---
 src/hypervisor/domain_driver.c | 48 ++++++++++++++++++++++++++++++++++
 src/hypervisor/domain_driver.h |  6 +++++
 src/libvirt_private.syms       |  1 +
 src/qemu/qemu_driver.c         | 47 ++++-----------------------------
 4 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c
index b7499a376f..0ca482275f 100644
--- a/src/hypervisor/domain_driver.c
+++ b/src/hypervisor/domain_driver.c
@@ -712,3 +712,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);
+    }
+}
diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h
index f81d436c2c..f36db5c6f0 100644
--- a/src/hypervisor/domain_driver.h
+++ b/src/hypervisor/domain_driver.h
@@ -90,3 +90,9 @@ typedef struct _virDomainDriverAutoStartConfig {
 
 void virDomainDriverAutoStart(virDomainObjList *domains,
                               virDomainDriverAutoStartConfig *cfg);
+
+typedef struct _virDomainDriverAutoShutdownConfig {
+    const char *uri;
+} virDomainDriverAutoShutdownConfig;
+
+void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e63939e2b5..e6fec0a151 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1649,6 +1649,7 @@ virDomainCgroupSetupVcpuBW;
 
 # hypervisor/domain_driver.h
 virDomainDriverAddIOThreadCheck;
+virDomainDriverAutoShutdown;
 virDomainDriverAutoStart;
 virDomainDriverDelIOThreadCheck;
 virDomainDriverGenerateMachineName;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2364b4d312..14b128d268 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -944,51 +944,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;
 }
 
 
-- 
2.48.1

Reply via email to