From nobody Fri Apr 26 17:24:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) client-ip=209.132.183.37; envelope-from=libvir-list-bounces@redhat.com; helo=mx5-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mx.zohomail.com with SMTPS id 148715749584556.088581701477096; Wed, 15 Feb 2017 03:18:15 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1FBElXb043195; Wed, 15 Feb 2017 06:14:47 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1FBEbq6010862 for ; Wed, 15 Feb 2017 06:14:37 -0500 Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1FBEaBn001420 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 15 Feb 2017 06:14:37 -0500 Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2B4EB6AAC7 for ; Wed, 15 Feb 2017 11:14:36 +0000 (UTC) Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v1FBEX6G016935 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 15 Feb 2017 11:14:34 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id v1FBEW0d028565 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 15 Feb 2017 11:14:33 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id v1FBEWdn017418; Wed, 15 Feb 2017 11:14:32 GMT Received: from paddy.lan (/89.114.92.174) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 15 Feb 2017 03:14:31 -0800 From: Joao Martins To: Libvirt Development List Date: Wed, 15 Feb 2017 11:17:37 +0000 Message-Id: <1487157458-4339-2-git-send-email-joao.m.martins@oracle.com> In-Reply-To: <1487157458-4339-1-git-send-email-joao.m.martins@oracle.com> References: <1487157458-4339-1-git-send-email-joao.m.martins@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 200 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 15 Feb 2017 11:14:36 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 15 Feb 2017 11:14:36 +0000 (UTC) for IP:'156.151.31.81' DOMAIN:'userp1040.oracle.com' HELO:'userp1040.oracle.com' FROM:'joao.m.martins@oracle.com' RCPT:'' X-RedHat-Spam-Score: -105.2 (BAYES_50, DCC_REPUT_00_12, RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H2, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY, USER_IN_WHITELIST) 156.151.31.81 userp1040.oracle.com 156.151.31.81 userp1040.oracle.com X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-loop: libvir-list@redhat.com Cc: Joao Martins Subject: [libvirt] [PATCH v3 1/2] libxl: refactor libxlDomainMigrationPrepare X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The newly introduced function libxlDomainMigrationPrepareAny will be shared between P2P and tunnelled variations. Signed-off-by: Joao Martins --- src/libxl/libxl_migration.c | 92 +++++++++++++++++++++++++++--------------= ---- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c index a471d2a..7beabd2 100644 --- a/src/libxl/libxl_migration.c +++ b/src/libxl/libxl_migration.c @@ -483,41 +483,26 @@ libxlDomainMigrationPrepareDef(libxlDriverPrivatePtr = driver, return def; } =20 -int -libxlDomainMigrationPrepare(virConnectPtr dconn, - virDomainDefPtr *def, - const char *uri_in, - char **uri_out, - const char *cookiein, - int cookieinlen, - unsigned int flags) +static int +libxlDomainMigrationPrepareAny(virConnectPtr dconn, + virDomainDefPtr *def, + const char *cookiein, + int cookieinlen, + libxlMigrationCookiePtr *mig, + char **xmlout, + bool *taint_hook) { libxlDriverPrivatePtr driver =3D dconn->privateData; libxlDriverConfigPtr cfg =3D libxlDriverConfigGet(driver); - libxlMigrationCookiePtr mig =3D NULL; - virDomainObjPtr vm =3D NULL; - char *hostname =3D NULL; - char *xmlout =3D NULL; - unsigned short port; - char portstr[100]; - virURIPtr uri =3D NULL; - virNetSocketPtr *socks =3D NULL; - size_t nsocks =3D 0; - int nsocks_listen =3D 0; - libxlMigrationDstArgs *args =3D NULL; - bool taint_hook =3D false; - libxlDomainObjPrivatePtr priv =3D NULL; - size_t i; - int ret =3D -1; =20 - if (libxlMigrationEatCookie(cookiein, cookieinlen, &mig) < 0) - goto error; + if (libxlMigrationEatCookie(cookiein, cookieinlen, mig) < 0) + return -1; =20 - if (mig->xenMigStreamVer > LIBXL_SAVE_VERSION) { + if ((*mig)->xenMigStreamVer > LIBXL_SAVE_VERSION) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("Xen migration stream version '%d' is not support= ed on this host"), - mig->xenMigStreamVer); - goto error; + (*mig)->xenMigStreamVer); + return -1; } =20 /* Let migration hook filter domain XML */ @@ -528,29 +513,29 @@ libxlDomainMigrationPrepare(virConnectPtr dconn, if (!(xml =3D virDomainDefFormat(*def, cfg->caps, VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_MIGRATABLE))) - goto error; + return -1; =20 hookret =3D virHookCall(VIR_HOOK_DRIVER_LIBXL, (*def)->name, VIR_HOOK_LIBXL_OP_MIGRATE, VIR_HOOK_SUBOP_BE= GIN, - NULL, xml, &xmlout); + NULL, xml, xmlout); VIR_FREE(xml); =20 if (hookret < 0) { - goto error; + return -1; } else if (hookret =3D=3D 0) { - if (virStringIsEmpty(xmlout)) { + if (virStringIsEmpty(*xmlout)) { VIR_DEBUG("Migrate hook filter returned nothing; using the" " original XML"); } else { virDomainDefPtr newdef; =20 - VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout); - newdef =3D virDomainDefParseString(xmlout, cfg->caps, driv= er->xmlopt, + VIR_DEBUG("Using hook-filtered domain XML: %s", *xmlout); + newdef =3D virDomainDefParseString(*xmlout, cfg->caps, dri= ver->xmlopt, NULL, VIR_DOMAIN_DEF_PARSE_INAC= TIVE | VIR_DOMAIN_DEF_PARSE_SKIP= _VALIDATE); if (!newdef) - goto error; + return -1; =20 /* TODO At some stage we will want to have some check of w= hat the user * did in the hook. */ @@ -560,17 +545,52 @@ libxlDomainMigrationPrepare(virConnectPtr dconn, /* We should taint the domain here. However, @vm and there= fore * privateData too are still NULL, so just notice the fact= and * taint it later. */ - taint_hook =3D true; + *taint_hook =3D true; } } } =20 + return 0; +} + +int +libxlDomainMigrationPrepare(virConnectPtr dconn, + virDomainDefPtr *def, + const char *uri_in, + char **uri_out, + const char *cookiein, + int cookieinlen, + unsigned int flags) +{ + libxlDriverPrivatePtr driver =3D dconn->privateData; + libxlDriverConfigPtr cfg =3D libxlDriverConfigGet(driver); + libxlMigrationCookiePtr mig =3D NULL; + virDomainObjPtr vm =3D NULL; + char *hostname =3D NULL; + char *xmlout =3D NULL; + unsigned short port; + char portstr[100]; + virURIPtr uri =3D NULL; + virNetSocketPtr *socks =3D NULL; + size_t nsocks =3D 0; + int nsocks_listen =3D 0; + libxlMigrationDstArgs *args =3D NULL; + bool taint_hook =3D false; + libxlDomainObjPrivatePtr priv =3D NULL; + size_t i; + int ret =3D -1; + + if (libxlDomainMigrationPrepareAny(dconn, def, cookiein, cookieinlen, + &mig, &xmlout, &taint_hook) < 0) + goto error; + if (!(vm =3D virDomainObjListAdd(driver->domains, *def, driver->xmlopt, VIR_DOMAIN_OBJ_LIST_ADD_LIVE | VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, NULL))) goto error; + *def =3D NULL; priv =3D vm->privateData; =20 --=20 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 17:24:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) client-ip=209.132.183.24; envelope-from=libvir-list-bounces@redhat.com; helo=mx3-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mx.zohomail.com with SMTPS id 1487157510784646.8939325097161; Wed, 15 Feb 2017 03:18:30 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1FBEglC007563; Wed, 15 Feb 2017 06:14:42 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1FBEfEP010872 for ; Wed, 15 Feb 2017 06:14:41 -0500 Received: by smtp.corp.redhat.com (Postfix) id 6FD0C660DC; Wed, 15 Feb 2017 11:14:41 +0000 (UTC) Received: from mx1.redhat.com (ext-mx01.extmail.prod.ext.phx2.redhat.com [10.5.110.25]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 696EB653F8 for ; Wed, 15 Feb 2017 11:14:41 +0000 (UTC) Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D5D5088E60 for ; Wed, 15 Feb 2017 11:14:39 +0000 (UTC) Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v1FBEbf5028113 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 15 Feb 2017 11:14:38 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id v1FBEbYR029436 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 15 Feb 2017 11:14:37 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id v1FBEYLd025544; Wed, 15 Feb 2017 11:14:35 GMT Received: from paddy.lan (/89.114.92.174) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 15 Feb 2017 03:14:34 -0800 From: Joao Martins To: Libvirt Development List Date: Wed, 15 Feb 2017 11:17:38 +0000 Message-Id: <1487157458-4339-3-git-send-email-joao.m.martins@oracle.com> In-Reply-To: <1487157458-4339-1-git-send-email-joao.m.martins@oracle.com> References: <1487157458-4339-1-git-send-email-joao.m.martins@oracle.com> X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 200 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 15 Feb 2017 11:14:40 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 15 Feb 2017 11:14:40 +0000 (UTC) for IP:'141.146.126.69' DOMAIN:'aserp1040.oracle.com' HELO:'aserp1040.oracle.com' FROM:'joao.m.martins@oracle.com' RCPT:'' X-RedHat-Spam-Score: -104.9 (BAYES_50, DCC_REPUT_13_19, RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H2, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY, USER_IN_WHITELIST) 141.146.126.69 aserp1040.oracle.com 141.146.126.69 aserp1040.oracle.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.25 X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-loop: libvir-list@redhat.com Cc: Joao Martins , Bob Liu Subject: [libvirt] [PATCH v3 2/2] libxl: add tunnelled migration support X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Bob Liu Tunnelled migration doesn't require any extra network connections beside the libvirt daemon. It's capable of strong encryption and the default option of openstack-nova. This patch adds the tunnelled migration(Tunnel3params) support to libxl. On the source side, the data flow is: * libxlDoMigrateSend() -> pipe libxlTunnel3MigrationFunc() polls pipe * out and then write to dest stream. While on the destination side: * Stream -> pipe -> 'recvfd of libxlDomainStartRestore' The usage is the same as p2p migration, execpt adding one extra '--tunnelled' to the libvirt p2p migration command. Signed-off-by: Bob Liu Signed-off-by: Joao Martins --- v3: * virStream{Send,Finish} and VIR_ALLOC_N already report errors, hence removing the virReportError calls from its error paths. * Revert top-level migration APIs to initial v1 approach. v2: ( Comments from Jim ) * Adjust common preparetunnel function reflecting v1 suggestions - Using common top-level Prepare function by adding is_tunnel variable - Using libxl_migration PrepareAny added in patch 1 - virHook support in PrepareTunnel3 * Move virThreadPtr from libxlTunnelMigrationThread into libxlTunnelControl * Rename function local variable from tmThreadPtr to arg * Remove redundant assignment "tmThreadPtr =3D &tc->tmThread;" always bein= g not null. * Adjust debug message to "poll returned 0" as opposed to "poll got timeout" as the latter might not always be the case. --- src/libxl/libxl_driver.c | 58 +++++++++- src/libxl/libxl_migration.c | 275 ++++++++++++++++++++++++++++++++++++++++= +--- src/libxl/libxl_migration.h | 9 ++ 3 files changed, 325 insertions(+), 17 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 74cb05a..e5b8f48 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -5934,6 +5934,61 @@ libxlDomainMigrateBegin3Params(virDomainPtr domain, } =20 static int +libxlDomainMigratePrepareTunnel3Params(virConnectPtr dconn, + virStreamPtr st, + virTypedParameterPtr params, + int nparams, + const char *cookiein, + int cookieinlen, + char **cookieout ATTRIBUTE_UNUSED, + int *cookieoutlen ATTRIBUTE_UNUSED, + unsigned int flags) +{ + libxlDriverPrivatePtr driver =3D dconn->privateData; + virDomainDefPtr def =3D NULL; + const char *dom_xml =3D NULL; + const char *dname =3D NULL; + const char *uri_in =3D NULL; + +#ifdef LIBXL_HAVE_NO_SUSPEND_RESUME + virReportUnsupportedError(); + return -1; +#endif + + virCheckFlags(LIBXL_MIGRATION_FLAGS, -1); + if (virTypedParamsValidate(params, nparams, LIBXL_MIGRATION_PARAMETERS= ) < 0) + goto error; + + if (virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_XML, + &dom_xml) < 0 || + virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_DEST_NAME, + &dname) < 0 || + virTypedParamsGetString(params, nparams, + VIR_MIGRATE_PARAM_URI, + &uri_in) < 0) + + goto error; + + if (!(def =3D libxlDomainMigrationPrepareDef(driver, dom_xml, dname))) + goto error; + + if (virDomainMigratePrepareTunnel3ParamsEnsureACL(dconn, def) < 0) + goto error; + + if (libxlDomainMigrationPrepareTunnel3(dconn, st, &def, cookiein, + cookieinlen, flags) < 0) + goto error; + + return 0; + + error: + virDomainDefFree(def); + return -1; +} + +static int libxlDomainMigratePrepare3Params(virConnectPtr dconn, virTypedParameterPtr params, int nparams, @@ -6033,7 +6088,7 @@ libxlDomainMigratePerform3Params(virDomainPtr dom, if (virDomainMigratePerform3ParamsEnsureACL(dom->conn, vm->def) < 0) goto cleanup; =20 - if (flags & VIR_MIGRATE_PEER2PEER) { + if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { if (libxlDomainMigrationPerformP2P(driver, vm, dom->conn, dom_xml, dconnuri, uri, dname, flags) < = 0) goto cleanup; @@ -6518,6 +6573,7 @@ static virHypervisorDriver libxlHypervisorDriver =3D { .nodeDeviceReset =3D libxlNodeDeviceReset, /* 1.2.3 */ .domainMigrateBegin3Params =3D libxlDomainMigrateBegin3Params, /* 1.2.= 6 */ .domainMigratePrepare3Params =3D libxlDomainMigratePrepare3Params, /* = 1.2.6 */ + .domainMigratePrepareTunnel3Params =3D libxlDomainMigratePrepareTunnel= 3Params, /* 3.1.0 */ .domainMigratePerform3Params =3D libxlDomainMigratePerform3Params, /* = 1.2.6 */ .domainMigrateFinish3Params =3D libxlDomainMigrateFinish3Params, /* 1.= 2.6 */ .domainMigrateConfirm3Params =3D libxlDomainMigrateConfirm3Params, /* = 1.2.6 */ diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c index 7beabd2..6bd8983 100644 --- a/src/libxl/libxl_migration.c +++ b/src/libxl/libxl_migration.c @@ -44,6 +44,7 @@ #include "libxl_migration.h" #include "locking/domain_lock.h" #include "virtypedparam.h" +#include "fdstream.h" =20 #define VIR_FROM_THIS VIR_FROM_LIBXL =20 @@ -554,6 +555,95 @@ libxlDomainMigrationPrepareAny(virConnectPtr dconn, } =20 int +libxlDomainMigrationPrepareTunnel3(virConnectPtr dconn, + virStreamPtr st, + virDomainDefPtr *def, + const char *cookiein, + int cookieinlen, + unsigned int flags) +{ + libxlMigrationCookiePtr mig =3D NULL; + libxlDriverPrivatePtr driver =3D dconn->privateData; + virDomainObjPtr vm =3D NULL; + libxlMigrationDstArgs *args =3D NULL; + virThread thread; + bool taint_hook =3D false; + libxlDomainObjPrivatePtr priv =3D NULL; + char *xmlout =3D NULL; + int dataFD[2] =3D { -1, -1 }; + int ret =3D -1; + + if (libxlDomainMigrationPrepareAny(dconn, def, cookiein, cookieinlen, + &mig, &xmlout, &taint_hook) < 0) + goto error; + + if (!(vm =3D virDomainObjListAdd(driver->domains, *def, + driver->xmlopt, + VIR_DOMAIN_OBJ_LIST_ADD_LIVE | + VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, + NULL))) + goto error; + + *def =3D NULL; + priv =3D vm->privateData; + + if (taint_hook) { + /* Domain XML has been altered by a hook script. */ + priv->hookRun =3D true; + } + + /* + * The data flow of tunnel3 migration in the dest side: + * stream -> pipe -> recvfd of libxlDomainStartRestore + */ + if (pipe(dataFD) < 0) + goto error; + + /* Stream data will be written to pipeIn */ + if (virFDStreamOpen(st, dataFD[1]) < 0) + goto error; + dataFD[1] =3D -1; /* 'st' owns the FD now & will close it */ + + if (libxlMigrationDstArgsInitialize() < 0) + goto error; + + if (!(args =3D virObjectNew(libxlMigrationDstArgsClass))) + goto error; + + args->conn =3D dconn; + args->vm =3D vm; + args->flags =3D flags; + args->migcookie =3D mig; + /* Receive from pipeOut */ + args->recvfd =3D dataFD[0]; + args->nsocks =3D 0; + if (virThreadCreate(&thread, false, libxlDoMigrateReceive, args) < 0) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("Failed to create thread for receiving migration = data")); + goto error; + } + + ret =3D 0; + goto done; + + error: + VIR_FORCE_CLOSE(dataFD[1]); + VIR_FORCE_CLOSE(dataFD[0]); + virObjectUnref(args); + /* Remove virDomainObj from domain list */ + if (vm) { + virDomainObjListRemove(driver->domains, vm); + vm =3D NULL; + } + + done: + if (vm) + virObjectUnlock(vm); + + return ret; +} + +int libxlDomainMigrationPrepare(virConnectPtr dconn, virDomainDefPtr *def, const char *uri_in, @@ -734,9 +824,143 @@ libxlDomainMigrationPrepare(virConnectPtr dconn, return ret; } =20 -/* 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. +typedef struct _libxlTunnelMigrationThread libxlTunnelMigrationThread; +struct _libxlTunnelMigrationThread { + virStreamPtr st; + int srcFD; +}; +#define TUNNEL_SEND_BUF_SIZE 65536 + +/* + * The data flow of tunnel3 migration in the src side: + * libxlDoMigrateSend() -> pipe + * libxlTunnel3MigrationFunc() polls pipe out and then write to dest strea= m. + */ +static void libxlTunnel3MigrationFunc(void *arg) +{ + libxlTunnelMigrationThread *data =3D (libxlTunnelMigrationThread *)arg; + char *buffer =3D NULL; + struct pollfd fds[1]; + int timeout =3D -1; + + if (VIR_ALLOC_N(buffer, TUNNEL_SEND_BUF_SIZE) < 0) + return; + + fds[0].fd =3D data->srcFD; + for (;;) { + int ret; + + fds[0].events =3D POLLIN; + fds[0].revents =3D 0; + ret =3D poll(fds, ARRAY_CARDINALITY(fds), timeout); + if (ret < 0) { + if (errno =3D=3D EAGAIN || errno =3D=3D EINTR) + continue; + virReportError(errno, "%s", + _("poll failed in libxlTunnel3MigrationFunc")); + goto cleanup; + } + + if (ret =3D=3D 0) { + VIR_DEBUG("poll returned 0"); + break; + } + + if (fds[0].revents & (POLLIN | POLLERR | POLLHUP)) { + int nbytes; + + nbytes =3D read(data->srcFD, buffer, TUNNEL_SEND_BUF_SIZE); + if (nbytes > 0) { + /* Write to dest stream */ + if (virStreamSend(data->st, buffer, nbytes) < 0) { + virStreamAbort(data->st); + goto cleanup; + } + } else if (nbytes < 0) { + virReportError(errno, "%s", + _("tunnelled migration failed to read from = xen side")); + virStreamAbort(data->st); + goto cleanup; + } else { + /* EOF; transferred all data */ + break; + } + } + } + + ignore_value(virStreamFinish(data->st)); + + cleanup: + VIR_FREE(buffer); + + return; +} + +struct libxlTunnelControl { + libxlTunnelMigrationThread tmThread; + virThread thread; + int dataFD[2]; +}; + +static int +libxlMigrationStartTunnel(libxlDriverPrivatePtr driver, + virDomainObjPtr vm, + unsigned long flags, + virStreamPtr st, + struct libxlTunnelControl *tc) +{ + libxlTunnelMigrationThread *arg =3D NULL; + int ret =3D -1; + + if (VIR_ALLOC(tc) < 0) + goto out; + + tc->dataFD[0] =3D -1; + tc->dataFD[1] =3D -1; + if (pipe(tc->dataFD) < 0) { + virReportError(errno, "%s", _("Unable to make pipes")); + goto out; + } + + arg =3D &tc->tmThread; + /* Read from pipe */ + arg->srcFD =3D tc->dataFD[0]; + /* Write to dest stream */ + arg->st =3D st; + if (virThreadCreate(&tc->thread, true, + libxlTunnel3MigrationFunc, arg) < 0) { + virReportError(errno, "%s", + _("Unable to create tunnel migration thread")); + goto out; + } + + virObjectUnlock(vm); + /* Send data to pipe */ + ret =3D libxlDoMigrateSend(driver, vm, flags, tc->dataFD[1]); + virObjectLock(vm); + + out: + /* libxlMigrationStopTunnel will be called in libxlDoMigrateP2P to free + * all resources for us. */ + return ret; +} + +static void libxlMigrationStopTunnel(struct libxlTunnelControl *tc) +{ + if (!tc) + return; + + virThreadCancel(&tc->thread); + virThreadJoin(&tc->thread); + + VIR_FORCE_CLOSE(tc->dataFD[0]); + VIR_FORCE_CLOSE(tc->dataFD[1]); + VIR_FREE(tc); +} + +/* This function is a simplification of virDomainMigrateVersion3Full and + * restricting it to migration v3 with params since it was the first to be + * introduced in libxl. */ static int libxlDoMigrateP2P(libxlDriverPrivatePtr driver, @@ -761,6 +985,9 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr driver, bool cancelled =3D true; virErrorPtr orig_err =3D NULL; int ret =3D -1; + /* For tunnel migration */ + virStreamPtr st =3D NULL; + struct libxlTunnelControl *tc =3D NULL; =20 dom_xml =3D libxlDomainMigrationBegin(sconn, vm, xmlin, &cookieout, &cookieoutlen); @@ -788,29 +1015,40 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr driver, =20 VIR_DEBUG("Prepare3"); virObjectUnlock(vm); - ret =3D dconn->driver->domainMigratePrepare3Params - (dconn, params, nparams, cookieout, cookieoutlen, NULL, NULL, &uri= _out, destflags); + if (flags & VIR_MIGRATE_TUNNELLED) { + if (!(st =3D virStreamNew(dconn, 0))) + goto cleanup; + ret =3D dconn->driver->domainMigratePrepareTunnel3Params + (dconn, st, params, nparams, cookieout, cookieoutlen, NULL, NU= LL, destflags); + } else { + ret =3D dconn->driver->domainMigratePrepare3Params + (dconn, params, nparams, cookieout, cookieoutlen, NULL, NULL, = &uri_out, destflags); + } virObjectLock(vm); =20 if (ret =3D=3D -1) goto cleanup; =20 - if (uri_out) { - if (virTypedParamsReplaceString(¶ms, &nparams, - VIR_MIGRATE_PARAM_URI, uri_out) < = 0) { - orig_err =3D virSaveLastError(); + if (!(flags & VIR_MIGRATE_TUNNELLED)) { + if (uri_out) { + if (virTypedParamsReplaceString(¶ms, &nparams, + VIR_MIGRATE_PARAM_URI, uri_out= ) < 0) { + orig_err =3D virSaveLastError(); + goto finish; + } + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("domainMigratePrepare3 did not set uri")); goto finish; } - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("domainMigratePrepare3 did not set uri")); - goto finish; } =20 VIR_DEBUG("Perform3 uri=3D%s", NULLSTR(uri_out)); - ret =3D libxlDomainMigrationPerform(driver, vm, NULL, NULL, - uri_out, NULL, flags); - + if (flags & VIR_MIGRATE_TUNNELLED) + ret =3D libxlMigrationStartTunnel(driver, vm, flags, st, tc); + else + ret =3D libxlDomainMigrationPerform(driver, vm, NULL, NULL, + uri_out, NULL, flags); if (ret < 0) orig_err =3D virSaveLastError(); =20 @@ -848,6 +1086,11 @@ libxlDoMigrateP2P(libxlDriverPrivatePtr driver, vm->def->name); =20 cleanup: + if (flags & VIR_MIGRATE_TUNNELLED) { + libxlMigrationStopTunnel(tc); + virObjectUnref(st); + } + if (ddomain) { virObjectUnref(ddomain); ret =3D 0; diff --git a/src/libxl/libxl_migration.h b/src/libxl/libxl_migration.h index 8a074a0..fcea558 100644 --- a/src/libxl/libxl_migration.h +++ b/src/libxl/libxl_migration.h @@ -29,6 +29,7 @@ # define LIBXL_MIGRATION_FLAGS \ (VIR_MIGRATE_LIVE | \ VIR_MIGRATE_PEER2PEER | \ + VIR_MIGRATE_TUNNELLED | \ VIR_MIGRATE_PERSIST_DEST | \ VIR_MIGRATE_UNDEFINE_SOURCE | \ VIR_MIGRATE_PAUSED) @@ -53,6 +54,14 @@ libxlDomainMigrationPrepareDef(libxlDriverPrivatePtr dri= ver, const char *dname); =20 int +libxlDomainMigrationPrepareTunnel3(virConnectPtr dconn, + virStreamPtr st, + virDomainDefPtr *def, + const char *cookiein, + int cookieinlen, + unsigned int flags); + +int libxlDomainMigrationPrepare(virConnectPtr dconn, virDomainDefPtr *def, const char *uri_in, --=20 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list