[PATCH V2 18/20] qemu: Add support for parallel save and restore

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for parallel save and restore by mapping libvirt's
"parallel-connections" parameter to QEMU's "multifd-channels"
migration parameter.

Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx>
---
 src/qemu/qemu_driver.c           | 32 +++++++++++++++++++++-----------
 src/qemu/qemu_migration_params.c | 31 +++++++++++++++++++++++++++++--
 src/qemu/qemu_migration_params.h |  5 ++++-
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 803c7be3f7..4d8f5f08c3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2611,6 +2611,8 @@ qemuDomainSaveInternal(virQEMUDriver *driver,
                        int format,
                        virCommand *compressor,
                        const char *xmlin,
+                       virTypedParameterPtr params,
+                       int nparams,
                        unsigned int flags)
 {
     g_autofree char *xml = NULL;
@@ -2700,7 +2702,8 @@ qemuDomainSaveInternal(virQEMUDriver *driver,
         goto endjob;
     xml = NULL;
 
-    if (!(saveParams = qemuMigrationParamsForSave(format == QEMU_SAVE_FORMAT_SPARSE,
+    if (!(saveParams = qemuMigrationParamsForSave(params, nparams,
+                                                  format == QEMU_SAVE_FORMAT_SPARSE,
                                                   flags)))
         goto endjob;
 
@@ -2787,7 +2790,7 @@ qemuDomainManagedSaveHelper(virQEMUDriver *driver,
     VIR_INFO("Saving state of domain '%s' to '%s'", vm->def->name, path);
 
     if (qemuDomainSaveInternal(driver, vm, path, format,
-                               compressor, dxml, flags) < 0)
+                               compressor, dxml, NULL, 0, flags) < 0)
         return -1;
 
     vm->hasManagedSave = true;
@@ -2826,7 +2829,7 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml,
         goto cleanup;
 
     ret = qemuDomainSaveInternal(driver, vm, path, format,
-                                 compressor, dxml, flags);
+                                 compressor, dxml, NULL, 0, flags);
 
  cleanup:
     virDomainObjEndAPI(&vm);
@@ -2856,13 +2859,16 @@ qemuDomainSaveParams(virDomainPtr dom,
 
     virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
                   VIR_DOMAIN_SAVE_RUNNING |
-                  VIR_DOMAIN_SAVE_PAUSED, -1);
+                  VIR_DOMAIN_SAVE_PAUSED |
+                  VIR_DOMAIN_SAVE_PARALLEL, -1);
 
     if (virTypedParamsValidate(params, nparams,
                                VIR_DOMAIN_SAVE_PARAM_FILE,
                                VIR_TYPED_PARAM_STRING,
                                VIR_DOMAIN_SAVE_PARAM_DXML,
                                VIR_TYPED_PARAM_STRING,
+                               VIR_DOMAIN_SAVE_PARAM_PARALLEL_CHANNELS,
+                               VIR_TYPED_PARAM_INT,
                                NULL) < 0)
         return -1;
 
@@ -2894,7 +2900,7 @@ qemuDomainSaveParams(virDomainPtr dom,
         goto cleanup;
 
     ret = qemuDomainSaveInternal(driver, vm, to, format,
-                                 compressor, dxml, flags);
+                                 compressor, dxml, params, nparams, flags);
 
  cleanup:
     virDomainObjEndAPI(&vm);
@@ -5769,6 +5775,8 @@ static int
 qemuDomainRestoreInternal(virConnectPtr conn,
                           const char *path,
                           const char *dxml,
+                          virTypedParameterPtr params,
+                          int nparams,
                           unsigned int flags,
                           int (*ensureACL)(virConnectPtr, virDomainDef *))
 {
@@ -5790,7 +5798,8 @@ qemuDomainRestoreInternal(virConnectPtr conn,
     virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
                   VIR_DOMAIN_SAVE_RUNNING |
                   VIR_DOMAIN_SAVE_PAUSED |
-                  VIR_DOMAIN_SAVE_RESET_NVRAM, -1);
+                  VIR_DOMAIN_SAVE_RESET_NVRAM |
+                  VIR_DOMAIN_SAVE_PARALLEL, -1);
 
     if (flags & VIR_DOMAIN_SAVE_RESET_NVRAM)
         reset_nvram = true;
@@ -5799,7 +5808,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
         goto cleanup;
 
     sparse = data->header.format == QEMU_SAVE_FORMAT_SPARSE;
-    if (!(restoreParams = qemuMigrationParamsForSave(sparse, flags)))
+    if (!(restoreParams = qemuMigrationParamsForSave(params, nparams, sparse, flags)))
         goto cleanup;
 
     fd = qemuSaveImageOpen(driver, path,
@@ -5881,7 +5890,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
                        const char *dxml,
                        unsigned int flags)
 {
-    return qemuDomainRestoreInternal(conn, path, dxml, flags,
+    return qemuDomainRestoreInternal(conn, path, dxml, NULL, 0, flags,
                                      virDomainRestoreFlagsEnsureACL);
 }
 
@@ -5889,7 +5898,7 @@ static int
 qemuDomainRestore(virConnectPtr conn,
                   const char *path)
 {
-    return qemuDomainRestoreInternal(conn, path, NULL, 0,
+    return qemuDomainRestoreInternal(conn, path, NULL, NULL, 0, 0,
                                      virDomainRestoreEnsureACL);
 }
 
@@ -5905,6 +5914,7 @@ qemuDomainRestoreParams(virConnectPtr conn,
     if (virTypedParamsValidate(params, nparams,
                                VIR_DOMAIN_SAVE_PARAM_FILE, VIR_TYPED_PARAM_STRING,
                                VIR_DOMAIN_SAVE_PARAM_DXML, VIR_TYPED_PARAM_STRING,
+                               VIR_DOMAIN_SAVE_PARAM_PARALLEL_CHANNELS, VIR_TYPED_PARAM_INT,
                                NULL) < 0)
         return -1;
 
@@ -5921,7 +5931,7 @@ qemuDomainRestoreParams(virConnectPtr conn,
         return -1;
     }
 
-    ret = qemuDomainRestoreInternal(conn, path, dxml, flags,
+    ret = qemuDomainRestoreInternal(conn, path, dxml, params, nparams, flags,
                                     virDomainRestoreParamsEnsureACL);
     return ret;
 }
@@ -6125,7 +6135,7 @@ qemuDomainObjRestore(virConnectPtr conn,
     }
 
     sparse = data->header.format == QEMU_SAVE_FORMAT_SPARSE;
-    if (!(restoreParams = qemuMigrationParamsForSave(sparse,
+    if (!(restoreParams = qemuMigrationParamsForSave(NULL, 0, sparse,
                                                      bypass_cache ? VIR_DOMAIN_SAVE_BYPASS_CACHE : 0)))
         return -1;
 
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 79b47333f9..420bf2fdbe 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -788,10 +788,19 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params,
 
 
 qemuMigrationParams *
-qemuMigrationParamsForSave(bool sparse, unsigned int flags)
+qemuMigrationParamsForSave(virTypedParameterPtr params,
+                           int nparams,
+                           bool sparse,
+                           unsigned int flags)
 {
     g_autoptr(qemuMigrationParams) saveParams = NULL;
 
+    if (flags & VIR_DOMAIN_SAVE_PARALLEL && !sparse) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Parallel save is only supported with the 'sparse' save image format"));
+        return NULL;
+    }
+
     if (!(saveParams = qemuMigrationParamsNew()))
         return NULL;
 
@@ -800,7 +809,25 @@ qemuMigrationParamsForSave(bool sparse, unsigned int flags)
             return NULL;
         if (virBitmapSetBit(saveParams->caps, QEMU_MIGRATION_CAP_MULTIFD) < 0)
             return NULL;
-        saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].value.i = 1;
+
+        if (flags & VIR_DOMAIN_SAVE_PARALLEL) {
+            int nchannels;
+
+            if (params && virTypedParamsGetInt(params, nparams,
+                                               VIR_DOMAIN_SAVE_PARAM_PARALLEL_CHANNELS,
+                                               &nchannels) < 0)
+                return NULL;
+
+            if (nchannels < 1) {
+                virReportError(VIR_ERR_INVALID_ARG, "%s",
+                               _("number of parallel save channels cannot be less than 1"));
+                return NULL;
+            }
+
+            saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].value.i = nchannels;
+        } else {
+            saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].value.i = 1;
+        }
         saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].set = true;
 
         if (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) {
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index b326aa5bc1..b6998d67a2 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -88,7 +88,10 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params,
                              qemuMigrationParty party);
 
 qemuMigrationParams *
-qemuMigrationParamsForSave(bool sparse, unsigned int flags);
+qemuMigrationParamsForSave(virTypedParameterPtr params,
+                           int nparams,
+                           bool sparse,
+                           unsigned int flags);
 
 int
 qemuMigrationParamsDump(qemuMigrationParams *migParams,
-- 
2.43.0



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux