From patchwork Fri Feb 5 20:45:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joao Martins X-Patchwork-Id: 8239251 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5B8DEBEEE5 for ; Fri, 5 Feb 2016 20:47:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2629C203A0 for ; Fri, 5 Feb 2016 20:47:50 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD96B2039D for ; Fri, 5 Feb 2016 20:47:48 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aRnFW-0002lm-RF; Fri, 05 Feb 2016 20:45:02 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aRnFV-0002lg-4Z for xen-devel@lists.xen.org; Fri, 05 Feb 2016 20:45:01 +0000 Received: from [193.109.254.147] by server-14.bemta-14.messagelabs.com id 87/65-07165-CC905B65; Fri, 05 Feb 2016 20:45:00 +0000 X-Env-Sender: joao.m.martins@oracle.com X-Msg-Ref: server-4.tower-27.messagelabs.com!1454705098!20925974!1 X-Originating-IP: [141.146.126.69] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTQxLjE0Ni4xMjYuNjkgPT4gMjc3MjE4\n X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 62682 invoked from network); 5 Feb 2016 20:44:59 -0000 Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by server-4.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 5 Feb 2016 20:44:59 -0000 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u15Kiuix006305 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 5 Feb 2016 20:44:57 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u15Kiu8N006139 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 5 Feb 2016 20:44:56 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id u15KitLt014136; Fri, 5 Feb 2016 20:44:55 GMT Received: from localhost.localdomain (/77.54.175.82) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 05 Feb 2016 12:44:55 -0800 From: Joao Martins To: libvir-list@redhat.com Date: Fri, 5 Feb 2016 20:45:02 +0000 Message-Id: <1454705103-25456-1-git-send-email-joao.m.martins@oracle.com> X-Mailer: git-send-email 2.1.4 X-Source-IP: userv0022.oracle.com [156.151.31.74] Cc: Joao Martins , Jim Fehlig , xen-devel@lists.xen.org Subject: [Xen-devel] [PATCH v4 1/2] libxl: add p2p migration X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce support for VIR_MIGRATE_PEER2PEER in libvirt migration. Most of the changes occur at the source and no modifications at the receiver. In P2P mode there is only the Perform phase so we must handle the connection with the destination and actually perform the migration. libxlDomainPerformP2P implements the connection to the destination and libxlDoMigrateP2P implements the actual migration logic with virConnectPtr. In this function we take care of doing all phases of migration in the destination similar to virDomainMigrateVersion3Full. We appropriately save the last error reported in each of the phases to provide proper reporting. We don't yet support VIR_MIGRATE_TUNNELED and we always use V3 with extensible params, thus it also makes the implementation simpler. It is worth noting that the receiver didn't have any changes, and since it's still the v3 sequence thus it is possible to migrate from a P2P to non-P2P host. Signed-off-by: Joao Martins --- Note: v4 series requires the patch ("remote: set VIR_TYPED_PARAM_STRING_OKAY on migration") [0] to make migration work again, but it's not reviewed yet. [https://www.redhat.com/archives/libvir-list/2016-February/msg00317.html] Changes since v3: - Put keep alive support into a separate patch and do it with proper configuration. - Fixed spelling errors on commit message. Changes since v2: - Remove Connect Close callback Changes since v1: - Move Begin step to libxlDoMigrateP2P to have all 4 steps together. - Remove if before VIR_FREE(dom_xml) --- src/libxl/libxl_driver.c | 13 ++- src/libxl/libxl_migration.c | 197 ++++++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_migration.h | 11 +++ 3 files changed, 218 insertions(+), 3 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 2a6c2de..9e3f568 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -5011,6 +5011,7 @@ libxlConnectSupportsFeature(virConnectPtr conn, int feature) switch (feature) { case VIR_DRV_FEATURE_TYPED_PARAM_STRING: case VIR_DRV_FEATURE_MIGRATION_PARAMS: + case VIR_DRV_FEATURE_MIGRATION_P2P: return 1; default: return 0; @@ -5336,9 +5337,15 @@ libxlDomainMigratePerform3Params(virDomainPtr dom, if (virDomainMigratePerform3ParamsEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - if (libxlDomainMigrationPerform(driver, vm, dom_xml, dconnuri, - uri, dname, flags) < 0) - goto cleanup; + if (flags & VIR_MIGRATE_PEER2PEER) { + if (libxlDomainMigrationPerformP2P(driver, vm, dom->conn, dom_xml, + dconnuri, uri, dname, flags) < 0) + goto cleanup; + } else { + if (libxlDomainMigrationPerform(driver, vm, dom_xml, dconnuri, + uri, dname, flags) < 0) + goto cleanup; + } ret = 0; diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c index 641bd4e..5993abc 100644 --- a/src/libxl/libxl_migration.c +++ b/src/libxl/libxl_migration.c @@ -42,6 +42,7 @@ #include "libxl_conf.h" #include "libxl_migration.h" #include "locking/domain_lock.h" +#include "virtypedparam.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -456,6 +457,202 @@ libxlDomainMigrationPrepare(virConnectPtr dconn, return ret; } +/* This function is a simplification of virDomainMigrateVersion3Full + * excluding tunnel support and restricting it to migration v3 + * with params since it was the first to be introduced in libxl. + */ +static int +libxlDoMigrateP2P(libxlDriverPrivatePtr driver, + virDomainObjPtr vm, + virConnectPtr sconn, + const char *xmlin, + virConnectPtr dconn, + const char *dconnuri ATTRIBUTE_UNUSED, + const char *dname, + const char *uri, + unsigned int flags) +{ + virDomainPtr ddomain = NULL; + virTypedParameterPtr params = NULL; + int nparams = 0; + int maxparams = 0; + char *uri_out = NULL; + char *dom_xml = NULL; + unsigned long destflags; + bool cancelled = true; + virErrorPtr orig_err = NULL; + int ret = -1; + + dom_xml = libxlDomainMigrationBegin(sconn, vm, xmlin); + if (!dom_xml) + goto cleanup; + + if (virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_MIGRATE_PARAM_DEST_XML, dom_xml) < 0) + goto cleanup; + + if (dname && + virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_MIGRATE_PARAM_DEST_NAME, dname) < 0) + goto cleanup; + + if (uri && + virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_MIGRATE_PARAM_URI, uri) < 0) + goto cleanup; + + /* We don't require the destination to have P2P support + * as it looks to be normal migration from the receiver perpective. + */ + destflags = flags & ~(VIR_MIGRATE_PEER2PEER); + + VIR_DEBUG("Prepare3"); + virObjectUnlock(vm); + ret = dconn->driver->domainMigratePrepare3Params + (dconn, params, nparams, NULL, 0, NULL, NULL, &uri_out, destflags); + virObjectLock(vm); + + if (ret == -1) + goto cleanup; + + if (uri_out) { + if (virTypedParamsReplaceString(¶ms, &nparams, + VIR_MIGRATE_PARAM_URI, uri_out) < 0) { + orig_err = virSaveLastError(); + goto finish; + } + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("domainMigratePrepare3 did not set uri")); + goto finish; + } + + VIR_DEBUG("Perform3 uri=%s", NULLSTR(uri_out)); + ret = libxlDomainMigrationPerform(driver, vm, NULL, NULL, + uri_out, NULL, flags); + + if (ret < 0) + orig_err = virSaveLastError(); + + cancelled = (ret < 0); + + finish: + VIR_DEBUG("Finish3 ret=%d", ret); + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0 && + virTypedParamsReplaceString(¶ms, &nparams, + VIR_MIGRATE_PARAM_DEST_NAME, + vm->def->name) < 0) { + ddomain = NULL; + } else { + virObjectUnlock(vm); + ddomain = dconn->driver->domainMigrateFinish3Params + (dconn, params, nparams, NULL, 0, NULL, NULL, + destflags, cancelled); + virObjectLock(vm); + } + + cancelled = (ddomain == NULL); + + /* If Finish3Params set an error, and we don't have an earlier + * one we need to preserve it in case confirm3 overwrites + */ + if (!orig_err) + orig_err = virSaveLastError(); + + VIR_DEBUG("Confirm3 cancelled=%d vm=%p", cancelled, vm); + ret = libxlDomainMigrationConfirm(driver, vm, flags, cancelled); + + if (ret < 0) + VIR_WARN("Guest %s probably left in 'paused' state on source", + vm->def->name); + + cleanup: + if (ddomain) { + virObjectUnref(ddomain); + ret = 0; + } else { + ret = -1; + } + + if (orig_err) { + virSetError(orig_err); + virFreeError(orig_err); + } + + VIR_FREE(dom_xml); + VIR_FREE(uri_out); + virTypedParamsFree(params, nparams); + return ret; +} + +static int virConnectCredType[] = { + VIR_CRED_AUTHNAME, + VIR_CRED_PASSPHRASE, +}; + +static virConnectAuth virConnectAuthConfig = { + .credtype = virConnectCredType, + .ncredtype = ARRAY_CARDINALITY(virConnectCredType), +}; + +/* On P2P mode there is only the Perform3 phase and we need to handle + * the connection with the destination libvirtd and perform the migration. + * Here we first tackle the first part of it, and libxlDoMigrationP2P handles + * the migration process with an established virConnectPtr to the destination. + */ +int +libxlDomainMigrationPerformP2P(libxlDriverPrivatePtr driver, + virDomainObjPtr vm, + virConnectPtr sconn, + const char *xmlin, + const char *dconnuri, + const char *uri_str ATTRIBUTE_UNUSED, + const char *dname, + unsigned int flags) +{ + int ret = -1; + bool useParams; + virConnectPtr dconn = NULL; + virErrorPtr orig_err = NULL; + + virObjectUnlock(vm); + dconn = virConnectOpenAuth(dconnuri, &virConnectAuthConfig, 0); + virObjectLock(vm); + + if (dconn == NULL) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Failed to connect to remote libvirt URI %s: %s"), + dconnuri, virGetLastErrorMessage()); + return ret; + } + + virObjectUnlock(vm); + useParams = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn, + VIR_DRV_FEATURE_MIGRATION_PARAMS); + virObjectLock(vm); + + if (!useParams) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("Destination libvirt does not support migration with extensible parameters")); + goto cleanup; + } + + ret = libxlDoMigrateP2P(driver, vm, sconn, xmlin, dconn, dconnuri, + dname, uri_str, flags); + + cleanup: + orig_err = virSaveLastError(); + virObjectUnlock(vm); + virObjectUnref(dconn); + virObjectLock(vm); + if (orig_err) { + virSetError(orig_err); + virFreeError(orig_err); + } + return ret; +} + int libxlDomainMigrationPerform(libxlDriverPrivatePtr driver, virDomainObjPtr vm, diff --git a/src/libxl/libxl_migration.h b/src/libxl/libxl_migration.h index 20b45d8..0f83bb4 100644 --- a/src/libxl/libxl_migration.h +++ b/src/libxl/libxl_migration.h @@ -28,6 +28,7 @@ # define LIBXL_MIGRATION_FLAGS \ (VIR_MIGRATE_LIVE | \ + VIR_MIGRATE_PEER2PEER | \ VIR_MIGRATE_UNDEFINE_SOURCE | \ VIR_MIGRATE_PAUSED) @@ -56,6 +57,16 @@ libxlDomainMigrationPrepare(virConnectPtr dconn, unsigned int flags); int +libxlDomainMigrationPerformP2P(libxlDriverPrivatePtr driver, + virDomainObjPtr vm, + virConnectPtr sconn, + const char *dom_xml, + const char *dconnuri, + const char *uri_str, + const char *dname, + unsigned int flags); + +int libxlDomainMigrationPerform(libxlDriverPrivatePtr driver, virDomainObjPtr vm, const char *dom_xml,