[libvirt] [PATCH 04/68] qemu: New file for all APIs related to migration parameters

Jiri Denemark jdenemar at redhat.com
Wed Apr 4 14:40:53 UTC 2018


In the end, this will allow us to have most of the logic around
migration parameters done in one place.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 po/POTFILES.in                   |   1 +
 src/qemu/Makefile.inc.am         |   2 +
 src/qemu/qemu_driver.c           |   1 +
 src/qemu/qemu_migration.c        | 421 +---------------------------
 src/qemu/qemu_migration.h        |  24 +-
 src/qemu/qemu_migration_params.c | 454 +++++++++++++++++++++++++++++++
 src/qemu/qemu_migration_params.h |  82 ++++++
 src/qemu/qemu_process.c          |   1 +
 8 files changed, 550 insertions(+), 436 deletions(-)
 create mode 100644 src/qemu/qemu_migration_params.c
 create mode 100644 src/qemu/qemu_migration_params.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index d84859a4e3..0b62126a19 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -136,6 +136,7 @@ src/qemu/qemu_hotplug.c
 src/qemu/qemu_interface.c
 src/qemu/qemu_migration.c
 src/qemu/qemu_migration_cookie.c
+src/qemu/qemu_migration_params.c
 src/qemu/qemu_monitor.c
 src/qemu/qemu_monitor_json.c
 src/qemu/qemu_monitor_text.c
diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
index 8ef290a6c1..25706ba4bc 100644
--- a/src/qemu/Makefile.inc.am
+++ b/src/qemu/Makefile.inc.am
@@ -33,6 +33,8 @@ QEMU_DRIVER_SOURCES = \
 	qemu/qemu_migration.h \
 	qemu/qemu_migration_cookie.c \
 	qemu/qemu_migration_cookie.h \
+        qemu/qemu_migration_params.c \
+        qemu/qemu_migration_params.h \
 	qemu/qemu_monitor.c \
 	qemu/qemu_monitor.h \
 	qemu/qemu_monitor_text.c \
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f7ad211077..519bd767c1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -57,6 +57,7 @@
 #include "qemu_monitor.h"
 #include "qemu_process.h"
 #include "qemu_migration.h"
+#include "qemu_migration_params.h"
 #include "qemu_blockjob.h"
 #include "qemu_security.h"
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index f88ac02f2f..4bdaa67ea1 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -29,6 +29,7 @@
 
 #include "qemu_migration.h"
 #include "qemu_migration_cookie.h"
+#include "qemu_migration_params.h"
 #include "qemu_monitor.h"
 #include "qemu_domain.h"
 #include "qemu_process.h"
@@ -81,8 +82,6 @@ VIR_ENUM_IMPL(qemuMigrationCompressMethod, QEMU_MIGRATION_COMPRESS_LAST,
               "mt",
 );
 
-#define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate"
-
 static int
 qemuMigrationJobStart(virQEMUDriverPtr driver,
                       virDomainObjPtr vm,
@@ -115,156 +114,6 @@ qemuMigrationJobFinish(virQEMUDriverPtr driver,
                        virDomainObjPtr obj)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
-/* qemuMigrationParamsCheckTLSCreds
- * @driver: pointer to qemu driver
- * @vm: domain object
- * @asyncJob: migration job to join
- *
- * Query the migration parameters looking for the 'tls-creds' parameter.
- * If found, then we can support setting or clearing the parameters and thus
- * can support TLS for migration.
- *
- * Returns 0 if we were able to successfully fetch the params and
- * additionally if the tls-creds parameter exists, saves it in the
- * private domain structure. Returns -1 on failure.
- */
-static int
-qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver,
-                                 virDomainObjPtr vm,
-                                 qemuDomainAsyncJob asyncJob)
-{
-    int ret = -1;
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-    qemuMonitorMigrationParams migParams = { 0 };
-
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
-        return -1;
-
-    if (qemuMonitorGetMigrationParams(priv->mon, &migParams) < 0)
-        goto cleanup;
-
-    /* NB: Could steal NULL pointer too! Let caller decide what to do. */
-    VIR_STEAL_PTR(priv->migTLSAlias, migParams.tlsCreds);
-
-    ret = 0;
-
- cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
-        ret = -1;
-
-    qemuMigrationParamsClear(&migParams);
-
-    return ret;
-}
-
-
-/* qemuMigrationParamsCheckSetupTLS
- * @driver: pointer to qemu driver
- * @vm: domain object
- * @cfg: configuration pointer
- * @asyncJob: migration job to join
- *
- * Check if TLS is possible and set up the environment. Assumes the caller
- * desires to use TLS (e.g. caller found VIR_MIGRATE_TLS flag).
- *
- * Ensure the qemu.conf has been properly configured to add an entry for
- * "migrate_tls_x509_cert_dir". Also check if the "tls-creds" parameter
- * was present from a query of migration parameters
- *
- * Returns 0 on success, -1 on error/failure
- */
-static int
-qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver,
-                                 virQEMUDriverConfigPtr cfg,
-                                 virDomainObjPtr vm,
-                                 qemuDomainAsyncJob asyncJob)
-{
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-
-    if (!cfg->migrateTLSx509certdir) {
-        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                       _("host migration TLS directory not configured"));
-        return -1;
-    }
-
-    if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0)
-        return -1;
-
-    if (!priv->migTLSAlias) {
-        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-                       _("TLS migration is not supported with this "
-                         "QEMU binary"));
-        return -1;
-    }
-
-    /* If there's a secret, then grab/store it now using the connection */
-    if (cfg->migrateTLSx509secretUUID &&
-        !(priv->migSecinfo =
-          qemuDomainSecretInfoTLSNew(priv, QEMU_MIGRATION_TLS_ALIAS_BASE,
-                                     cfg->migrateTLSx509secretUUID)))
-        return -1;
-
-    return 0;
-}
-
-
-/* qemuMigrationParamsAddTLSObjects
- * @driver: pointer to qemu driver
- * @vm: domain object
- * @cfg: configuration pointer
- * @tlsListen: server or client
- * @asyncJob: Migration job to join
- * @tlsAlias: alias to be generated for TLS object
- * @secAlias: alias to be generated for a secinfo object
- * @migParams: migration parameters to set
- *
- * Create the TLS objects for the migration and set the migParams value
- *
- * Returns 0 on success, -1 on failure
- */
-static int
-qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver,
-                                 virDomainObjPtr vm,
-                                 virQEMUDriverConfigPtr cfg,
-                                 bool tlsListen,
-                                 qemuDomainAsyncJob asyncJob,
-                                 char **tlsAlias,
-                                 char **secAlias,
-                                 qemuMonitorMigrationParamsPtr migParams)
-{
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-    virJSONValuePtr tlsProps = NULL;
-    virJSONValuePtr secProps = NULL;
-
-    if (qemuDomainGetTLSObjects(priv->qemuCaps, priv->migSecinfo,
-                                cfg->migrateTLSx509certdir, tlsListen,
-                                cfg->migrateTLSx509verify,
-                                QEMU_MIGRATION_TLS_ALIAS_BASE,
-                                &tlsProps, tlsAlias, &secProps, secAlias) < 0)
-        goto error;
-
-    /* Ensure the domain doesn't already have the TLS objects defined...
-     * This should prevent any issues just in case some cleanup wasn't
-     * properly completed (both src and dst use the same alias) or
-     * some other error path between now and perform . */
-    qemuDomainDelTLSObjects(driver, vm, asyncJob, *secAlias, *tlsAlias);
-
-    if (qemuDomainAddTLSObjects(driver, vm, asyncJob, *secAlias, &secProps,
-                                *tlsAlias, &tlsProps) < 0)
-        goto error;
-
-    if (VIR_STRDUP(migParams->tlsCreds, *tlsAlias) < 0)
-        goto error;
-
-    return 0;
-
- error:
-    virJSONValueFree(tlsProps);
-    virJSONValueFree(secProps);
-    return -1;
-}
-
-
 static void
 qemuMigrationSrcStoreDomainState(virDomainObjPtr vm)
 {
@@ -1325,7 +1174,7 @@ qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver,
 }
 
 
-static int
+int
 qemuMigrationOptionSet(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
                        qemuMonitorMigrationCaps capability,
@@ -2366,238 +2215,6 @@ qemuMigrationDstPrepare(virDomainObjPtr vm,
     return inc;
 }
 
-static int
-qemuMigrationParamsSetCompression(virQEMUDriverPtr driver,
-                                  virDomainObjPtr vm,
-                                  qemuDomainAsyncJob job,
-                                  qemuMigrationCompressionPtr compression,
-                                  qemuMonitorMigrationParamsPtr migParams)
-{
-    int ret = -1;
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-
-    if (qemuMigrationOptionSet(driver, vm,
-                               QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
-                               compression->methods &
-                               (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE),
-                               job) < 0)
-        return -1;
-
-    if (qemuMigrationOptionSet(driver, vm,
-                               QEMU_MONITOR_MIGRATION_CAPS_COMPRESS,
-                               compression->methods &
-                               (1ULL << QEMU_MIGRATION_COMPRESS_MT),
-                               job) < 0)
-        return -1;
-
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
-        return -1;
-
-    migParams->compressLevel_set = compression->level_set;
-    migParams->compressLevel = compression->level;
-
-    migParams->compressThreads_set = compression->threads_set;
-    migParams->compressThreads = compression->threads;
-
-    migParams->decompressThreads_set = compression->dthreads_set;
-    migParams->decompressThreads = compression->dthreads;
-
-    if (compression->xbzrle_cache_set &&
-        qemuMonitorSetMigrationCacheSize(priv->mon,
-                                         compression->xbzrle_cache) < 0)
-        goto cleanup;
-
-    ret = 0;
-
- cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
-        ret = -1;
-
-    return ret;
-}
-
-
-void
-qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams)
-{
-    if (!migParams)
-        return;
-
-    VIR_FREE(migParams->tlsCreds);
-    VIR_FREE(migParams->tlsHostname);
-}
-
-
-void
-qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams)
-{
-    if (!*migParams)
-        return;
-
-    qemuMigrationParamsClear(*migParams);
-    VIR_FREE(*migParams);
-}
-
-
-/* qemuMigrationParamsSetEmptyTLS
- * @driver: pointer to qemu driver
- * @vm: domain object
- * @asyncJob: migration job to join
- * @migParams: Pointer to a migration parameters block
- *
- * If we support setting the tls-creds, then set both tls-creds and
- * tls-hostname to the empty string ("") which indicates to not use
- * TLS on this migration.
- *
- * Returns 0 on success, -1 on failure
- */
-static int
-qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver,
-                               virDomainObjPtr vm,
-                               qemuDomainAsyncJob asyncJob,
-                               qemuMonitorMigrationParamsPtr migParams)
-{
-   qemuDomainObjPrivatePtr priv = vm->privateData;
-
-   if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0)
-       return -1;
-
-   if (!priv->migTLSAlias)
-       return 0;
-
-   if (VIR_STRDUP(migParams->tlsCreds, "") < 0 ||
-       VIR_STRDUP(migParams->tlsHostname, "") < 0)
-       return -1;
-
-    return 0;
-}
-
-
-qemuMonitorMigrationParamsPtr
-qemuMigrationParamsFromFlags(virTypedParameterPtr params,
-                             int nparams,
-                             unsigned long flags)
-{
-    qemuMonitorMigrationParamsPtr migParams;
-
-    if (VIR_ALLOC(migParams) < 0)
-        return NULL;
-
-    if (!params)
-        return migParams;
-
-#define GET(PARAM, VAR) \
-    do { \
-        int rc; \
-        if ((rc = virTypedParamsGetInt(params, nparams, \
-                                       VIR_MIGRATE_PARAM_ ## PARAM, \
-                                       &migParams->VAR)) < 0) \
-            goto error; \
- \
-        if (rc == 1) \
-            migParams->VAR ## _set = true; \
-    } while (0)
-
-    GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial);
-    GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement);
-
-#undef GET
-
-    if ((migParams->cpuThrottleInitial_set ||
-         migParams->cpuThrottleIncrement_set) &&
-        !(flags & VIR_MIGRATE_AUTO_CONVERGE)) {
-        virReportError(VIR_ERR_INVALID_ARG, "%s",
-                       _("Turn auto convergence on to tune it"));
-        goto error;
-    }
-
-    return migParams;
-
- error:
-    qemuMigrationParamsFree(&migParams);
-    return NULL;
-}
-
-
-static int
-qemuMigrationParamsSet(virQEMUDriverPtr driver,
-                       virDomainObjPtr vm,
-                       qemuDomainAsyncJob job,
-                       qemuMonitorMigrationParamsPtr migParams)
-{
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-    int ret = -1;
-
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
-        return -1;
-
-    if (qemuMonitorSetMigrationParams(priv->mon, migParams) < 0)
-        goto cleanup;
-
-    ret = 0;
-
- cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
-        ret = -1;
-
-    return ret;
-}
-
-
-/* qemuMigrationParamsResetTLS
- * @driver: pointer to qemu driver
- * @vm: domain object
- * @asyncJob: migration job to join
- *
- * Deconstruct all the setup possibly done for TLS - delete the TLS and
- * security objects, free the secinfo, and reset the migration params to "".
- *
- * Returns 0 on success, -1 on failure
- */
-static int
-qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
-                            virDomainObjPtr vm,
-                            qemuDomainAsyncJob asyncJob)
-{
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-    char *tlsAlias = NULL;
-    char *secAlias = NULL;
-    qemuMonitorMigrationParams migParams = { 0 };
-    int ret = -1;
-
-    if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0)
-        return -1;
-
-    /* If the tls-creds doesn't exist or if they're set to "" then there's
-     * nothing to do since we never set anything up */
-    if (!priv->migTLSAlias || !*priv->migTLSAlias)
-        return 0;
-
-    /* NB: If either or both fail to allocate memory we can still proceed
-     *     since the next time we migrate another deletion attempt will be
-     *     made after successfully generating the aliases. */
-    tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE);
-    secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false);
-
-    qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias);
-    qemuDomainSecretInfoFree(&priv->migSecinfo);
-
-    if (VIR_STRDUP(migParams.tlsCreds, "") < 0 ||
-        VIR_STRDUP(migParams.tlsHostname, "") < 0 ||
-        qemuMigrationParamsSet(driver, vm, asyncJob, &migParams) < 0)
-        goto cleanup;
-
-    ret = 0;
-
- cleanup:
-    VIR_FREE(tlsAlias);
-    VIR_FREE(secAlias);
-    qemuMigrationParamsClear(&migParams);
-
-    return ret;
-}
-
-
 static int
 qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
                            virConnectPtr dconn,
@@ -6077,40 +5694,6 @@ qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression,
 }
 
 
-/*
- * qemuMigrationParamsReset:
- *
- * Reset all migration parameters so that the next job which internally uses
- * migration (save, managedsave, snapshots, dump) will not try to use them.
- */
-void
-qemuMigrationParamsReset(virQEMUDriverPtr driver,
-                         virDomainObjPtr vm,
-                         qemuDomainAsyncJob job)
-{
-    qemuMonitorMigrationCaps cap;
-    virErrorPtr err = virSaveLastError();
-
-    if (!virDomainObjIsActive(vm))
-        goto cleanup;
-
-    if (qemuMigrationParamsResetTLS(driver, vm, job) < 0)
-        goto cleanup;
-
-    for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) {
-        if (qemuMigrationCapsGet(vm, cap) &&
-            qemuMigrationOptionSet(driver, vm, cap, false, job) < 0)
-            goto cleanup;
-    }
-
- cleanup:
-    if (err) {
-        virSetError(err);
-        virFreeError(err);
-    }
-}
-
-
 int
 qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index b9f7369784..7342517ca6 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -34,7 +34,6 @@
  *
  * Exceptions:
  *
- *  - qemuMigrationParamsXXX - runs on source or dest host
  *  - qemuMigrationOptionXXX - runs on source or dest host
  *  - qemuMigrationJobXXX - runs on source or dest host
  *  - qemuMigrationCapsXXX - runs on source or dest host
@@ -137,17 +136,6 @@ qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression,
                                 int *maxparams,
                                 unsigned long *flags);
 
-void
-qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams);
-
-void
-qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams);
-
-qemuMonitorMigrationParamsPtr
-qemuMigrationParamsFromFlags(virTypedParameterPtr params,
-                             int nparams,
-                             unsigned long flags);
-
 int
 qemuMigrationSrcSetOffline(virQEMUDriverPtr driver,
                            virDomainObjPtr vm);
@@ -298,11 +286,6 @@ void
 qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver,
                             virDomainObjPtr vm);
 
-void
-qemuMigrationParamsReset(virQEMUDriverPtr driver,
-                         virDomainObjPtr vm,
-                         qemuDomainAsyncJob job);
-
 int
 qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
@@ -318,4 +301,11 @@ bool
 qemuMigrationCapsGet(virDomainObjPtr vm,
                      qemuMonitorMigrationCaps cap);
 
+int
+qemuMigrationOptionSet(virQEMUDriverPtr driver,
+                       virDomainObjPtr vm,
+                       qemuMonitorMigrationCaps capability,
+                       bool state,
+                       qemuDomainAsyncJob job);
+
 #endif /* __QEMU_MIGRATION_H__ */
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
new file mode 100644
index 0000000000..72ecafd057
--- /dev/null
+++ b/src/qemu/qemu_migration_params.c
@@ -0,0 +1,454 @@
+/*
+ * qemu_migration_params.c: QEMU migration parameters handling
+ *
+ * Copyright (C) 2006-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+
+#include "virlog.h"
+#include "virerror.h"
+#include "viralloc.h"
+#include "virstring.h"
+
+#include "qemu_alias.h"
+#include "qemu_hotplug.h"
+#include "qemu_migration.h"
+#include "qemu_migration_params.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+VIR_LOG_INIT("qemu.qemu_migration_params");
+
+#define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate"
+
+
+void
+qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams)
+{
+    if (!migParams)
+        return;
+
+    VIR_FREE(migParams->tlsCreds);
+    VIR_FREE(migParams->tlsHostname);
+}
+
+
+void
+qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams)
+{
+    if (!*migParams)
+        return;
+
+    qemuMigrationParamsClear(*migParams);
+    VIR_FREE(*migParams);
+}
+
+
+qemuMonitorMigrationParamsPtr
+qemuMigrationParamsFromFlags(virTypedParameterPtr params,
+                             int nparams,
+                             unsigned long flags)
+{
+    qemuMonitorMigrationParamsPtr migParams;
+
+    if (VIR_ALLOC(migParams) < 0)
+        return NULL;
+
+    if (!params)
+        return migParams;
+
+#define GET(PARAM, VAR) \
+    do { \
+        int rc; \
+        if ((rc = virTypedParamsGetInt(params, nparams, \
+                                       VIR_MIGRATE_PARAM_ ## PARAM, \
+                                       &migParams->VAR)) < 0) \
+            goto error; \
+ \
+        if (rc == 1) \
+            migParams->VAR ## _set = true; \
+    } while (0)
+
+    GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial);
+    GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement);
+
+#undef GET
+
+    if ((migParams->cpuThrottleInitial_set ||
+         migParams->cpuThrottleIncrement_set) &&
+        !(flags & VIR_MIGRATE_AUTO_CONVERGE)) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("Turn auto convergence on to tune it"));
+        goto error;
+    }
+
+    return migParams;
+
+ error:
+    qemuMigrationParamsFree(&migParams);
+    return NULL;
+}
+
+
+int
+qemuMigrationParamsSet(virQEMUDriverPtr driver,
+                       virDomainObjPtr vm,
+                       int asyncJob,
+                       qemuMonitorMigrationParamsPtr migParams)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ret = -1;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    if (qemuMonitorSetMigrationParams(priv->mon, migParams) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        ret = -1;
+
+    return ret;
+}
+
+
+/* qemuMigrationParamsCheckTLSCreds
+ * @driver: pointer to qemu driver
+ * @vm: domain object
+ * @asyncJob: migration job to join
+ *
+ * Query the migration parameters looking for the 'tls-creds' parameter.
+ * If found, then we can support setting or clearing the parameters and thus
+ * can support TLS for migration.
+ *
+ * Returns 0 if we were able to successfully fetch the params and
+ * additionally if the tls-creds parameter exists, saves it in the
+ * private domain structure. Returns -1 on failure.
+ */
+static int
+qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver,
+                                 virDomainObjPtr vm,
+                                 int asyncJob)
+{
+    int ret = -1;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorMigrationParams migParams = { 0 };
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    if (qemuMonitorGetMigrationParams(priv->mon, &migParams) < 0)
+        goto cleanup;
+
+    /* NB: Could steal NULL pointer too! Let caller decide what to do. */
+    VIR_STEAL_PTR(priv->migTLSAlias, migParams.tlsCreds);
+
+    ret = 0;
+
+ cleanup:
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        ret = -1;
+
+    qemuMigrationParamsClear(&migParams);
+
+    return ret;
+}
+
+
+/* qemuMigrationParamsCheckSetupTLS
+ * @driver: pointer to qemu driver
+ * @vm: domain object
+ * @cfg: configuration pointer
+ * @asyncJob: migration job to join
+ *
+ * Check if TLS is possible and set up the environment. Assumes the caller
+ * desires to use TLS (e.g. caller found VIR_MIGRATE_TLS flag).
+ *
+ * Ensure the qemu.conf has been properly configured to add an entry for
+ * "migrate_tls_x509_cert_dir". Also check if the "tls-creds" parameter
+ * was present from a query of migration parameters
+ *
+ * Returns 0 on success, -1 on error/failure
+ */
+int
+qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver,
+                                 virQEMUDriverConfigPtr cfg,
+                                 virDomainObjPtr vm,
+                                 int asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (!cfg->migrateTLSx509certdir) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("host migration TLS directory not configured"));
+        return -1;
+    }
+
+    if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0)
+        return -1;
+
+    if (!priv->migTLSAlias) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("TLS migration is not supported with this "
+                         "QEMU binary"));
+        return -1;
+    }
+
+    /* If there's a secret, then grab/store it now using the connection */
+    if (cfg->migrateTLSx509secretUUID &&
+        !(priv->migSecinfo =
+          qemuDomainSecretInfoTLSNew(priv, QEMU_MIGRATION_TLS_ALIAS_BASE,
+                                     cfg->migrateTLSx509secretUUID)))
+        return -1;
+
+    return 0;
+}
+
+
+/* qemuMigrationParamsAddTLSObjects
+ * @driver: pointer to qemu driver
+ * @vm: domain object
+ * @cfg: configuration pointer
+ * @tlsListen: server or client
+ * @asyncJob: Migration job to join
+ * @tlsAlias: alias to be generated for TLS object
+ * @secAlias: alias to be generated for a secinfo object
+ * @migParams: migration parameters to set
+ *
+ * Create the TLS objects for the migration and set the migParams value
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver,
+                                 virDomainObjPtr vm,
+                                 virQEMUDriverConfigPtr cfg,
+                                 bool tlsListen,
+                                 int asyncJob,
+                                 char **tlsAlias,
+                                 char **secAlias,
+                                 qemuMonitorMigrationParamsPtr migParams)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virJSONValuePtr tlsProps = NULL;
+    virJSONValuePtr secProps = NULL;
+
+    if (qemuDomainGetTLSObjects(priv->qemuCaps, priv->migSecinfo,
+                                cfg->migrateTLSx509certdir, tlsListen,
+                                cfg->migrateTLSx509verify,
+                                QEMU_MIGRATION_TLS_ALIAS_BASE,
+                                &tlsProps, tlsAlias, &secProps, secAlias) < 0)
+        goto error;
+
+    /* Ensure the domain doesn't already have the TLS objects defined...
+     * This should prevent any issues just in case some cleanup wasn't
+     * properly completed (both src and dst use the same alias) or
+     * some other error path between now and perform . */
+    qemuDomainDelTLSObjects(driver, vm, asyncJob, *secAlias, *tlsAlias);
+
+    if (qemuDomainAddTLSObjects(driver, vm, asyncJob, *secAlias, &secProps,
+                                *tlsAlias, &tlsProps) < 0)
+        goto error;
+
+    if (VIR_STRDUP(migParams->tlsCreds, *tlsAlias) < 0)
+        goto error;
+
+    return 0;
+
+ error:
+    virJSONValueFree(tlsProps);
+    virJSONValueFree(secProps);
+    return -1;
+}
+
+
+/* qemuMigrationParamsSetEmptyTLS
+ * @driver: pointer to qemu driver
+ * @vm: domain object
+ * @asyncJob: migration job to join
+ * @migParams: Pointer to a migration parameters block
+ *
+ * If we support setting the tls-creds, then set both tls-creds and
+ * tls-hostname to the empty string ("") which indicates to not use
+ * TLS on this migration.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               int asyncJob,
+                               qemuMonitorMigrationParamsPtr migParams)
+{
+   qemuDomainObjPrivatePtr priv = vm->privateData;
+
+   if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0)
+       return -1;
+
+   if (!priv->migTLSAlias)
+       return 0;
+
+   if (VIR_STRDUP(migParams->tlsCreds, "") < 0 ||
+       VIR_STRDUP(migParams->tlsHostname, "") < 0)
+       return -1;
+
+    return 0;
+}
+
+
+int
+qemuMigrationParamsSetCompression(virQEMUDriverPtr driver,
+                                  virDomainObjPtr vm,
+                                  int asyncJob,
+                                  qemuMigrationCompressionPtr compression,
+                                  qemuMonitorMigrationParamsPtr migParams)
+{
+    int ret = -1;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (qemuMigrationOptionSet(driver, vm,
+                               QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
+                               compression->methods &
+                               (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE),
+                               asyncJob) < 0)
+        return -1;
+
+    if (qemuMigrationOptionSet(driver, vm,
+                               QEMU_MONITOR_MIGRATION_CAPS_COMPRESS,
+                               compression->methods &
+                               (1ULL << QEMU_MIGRATION_COMPRESS_MT),
+                               asyncJob) < 0)
+        return -1;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    migParams->compressLevel_set = compression->level_set;
+    migParams->compressLevel = compression->level;
+
+    migParams->compressThreads_set = compression->threads_set;
+    migParams->compressThreads = compression->threads;
+
+    migParams->decompressThreads_set = compression->dthreads_set;
+    migParams->decompressThreads = compression->dthreads;
+
+    if (compression->xbzrle_cache_set &&
+        qemuMonitorSetMigrationCacheSize(priv->mon,
+                                         compression->xbzrle_cache) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        ret = -1;
+
+    return ret;
+}
+
+
+/* qemuMigrationParamsResetTLS
+ * @driver: pointer to qemu driver
+ * @vm: domain object
+ * @asyncJob: migration job to join
+ *
+ * Deconstruct all the setup possibly done for TLS - delete the TLS and
+ * security objects, free the secinfo, and reset the migration params to "".
+ *
+ * Returns 0 on success, -1 on failure
+ */
+static int
+qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            int asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    char *tlsAlias = NULL;
+    char *secAlias = NULL;
+    qemuMonitorMigrationParams migParams = { 0 };
+    int ret = -1;
+
+    if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0)
+        return -1;
+
+    /* If the tls-creds doesn't exist or if they're set to "" then there's
+     * nothing to do since we never set anything up */
+    if (!priv->migTLSAlias || !*priv->migTLSAlias)
+        return 0;
+
+    /* NB: If either or both fail to allocate memory we can still proceed
+     *     since the next time we migrate another deletion attempt will be
+     *     made after successfully generating the aliases. */
+    tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE);
+    secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false);
+
+    qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias);
+    qemuDomainSecretInfoFree(&priv->migSecinfo);
+
+    if (VIR_STRDUP(migParams.tlsCreds, "") < 0 ||
+        VIR_STRDUP(migParams.tlsHostname, "") < 0 ||
+        qemuMigrationParamsSet(driver, vm, asyncJob, &migParams) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(tlsAlias);
+    VIR_FREE(secAlias);
+    qemuMigrationParamsClear(&migParams);
+
+    return ret;
+}
+
+
+/*
+ * qemuMigrationParamsReset:
+ *
+ * Reset all migration parameters so that the next job which internally uses
+ * migration (save, managedsave, snapshots, dump) will not try to use them.
+ */
+void
+qemuMigrationParamsReset(virQEMUDriverPtr driver,
+                         virDomainObjPtr vm,
+                         int asyncJob)
+{
+    qemuMonitorMigrationCaps cap;
+    virErrorPtr err = virSaveLastError();
+
+    if (!virDomainObjIsActive(vm))
+        goto cleanup;
+
+    if (qemuMigrationParamsResetTLS(driver, vm, asyncJob) < 0)
+        goto cleanup;
+
+    for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) {
+        if (qemuMigrationCapsGet(vm, cap) &&
+            qemuMigrationOptionSet(driver, vm, cap, false, asyncJob) < 0)
+            goto cleanup;
+    }
+
+ cleanup:
+    if (err) {
+        virSetError(err);
+        virFreeError(err);
+    }
+}
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
new file mode 100644
index 0000000000..33b3c27e51
--- /dev/null
+++ b/src/qemu/qemu_migration_params.h
@@ -0,0 +1,82 @@
+/*
+ * qemu_migration_params.h: QEMU migration parameters handling
+ *
+ * Copyright (C) 2006-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __QEMU_MIGRATION_PARAMS_H__
+# define __QEMU_MIGRATION_PARAMS_H__
+
+# include "internal.h"
+
+# include "qemu_monitor.h"
+# include "qemu_conf.h"
+
+
+qemuMonitorMigrationParamsPtr
+qemuMigrationParamsFromFlags(virTypedParameterPtr params,
+                             int nparams,
+                             unsigned long flags);
+
+void
+qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams);
+
+void
+qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams);
+
+int
+qemuMigrationParamsSet(virQEMUDriverPtr driver,
+                       virDomainObjPtr vm,
+                       int asyncJob,
+                       qemuMonitorMigrationParamsPtr migParams);
+
+int
+qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver,
+                                 virQEMUDriverConfigPtr cfg,
+                                 virDomainObjPtr vm,
+                                 int asyncJob);
+
+int
+qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver,
+                                 virDomainObjPtr vm,
+                                 virQEMUDriverConfigPtr cfg,
+                                 bool tlsListen,
+                                 int asyncJob,
+                                 char **tlsAlias,
+                                 char **secAlias,
+                                 qemuMonitorMigrationParamsPtr migParams);
+
+int
+qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               int asyncJob,
+                               qemuMonitorMigrationParamsPtr migParams);
+
+int
+qemuMigrationParamsSetCompression(virQEMUDriverPtr driver,
+                                  virDomainObjPtr vm,
+                                  int asyncJob,
+                                  qemuMigrationCompressionPtr compression,
+                                  qemuMonitorMigrationParamsPtr migParams);
+
+void
+qemuMigrationParamsReset(virQEMUDriverPtr driver,
+                         virDomainObjPtr vm,
+                         int asyncJob);
+
+#endif /* __QEMU_MIGRATION_PARAMS_H__ */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index df2db53a97..3a7f8ed105 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -45,6 +45,7 @@
 #include "qemu_hostdev.h"
 #include "qemu_hotplug.h"
 #include "qemu_migration.h"
+#include "qemu_migration_params.h"
 #include "qemu_interface.h"
 #include "qemu_security.h"
 
-- 
2.17.0




More information about the libvir-list mailing list