On 25.08.2015 18:42, Dmitry Guryanov wrote: > On 08/25/2015 12:04 PM, nshirokovskiy@xxxxxxxxxxxxx wrote: >> From: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> >> >> This patch makes basic vz migration possible. For example by virsh: >> virsh -c vz:///system migrate --direct $NAME $STUB vz+ssh://$DST/system >> >> $STUB could be anything as it is required virsh argument but it is not >> used in direct migration. >> >> Vz migration is implemented as direct migration. The reason is that vz sdk do >> all the job. Prepare phase function is used to pass session uuid from >> destination to source so we don't introduce new rpc call. >> >> Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> >> --- >> src/libvirt-domain.c | 3 +- >> src/vz/vz_driver.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++ >> src/vz/vz_sdk.c | 33 +++++++++ >> src/vz/vz_sdk.h | 2 + >> 4 files changed, 230 insertions(+), 1 deletions(-) >> >> diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c >> index cbf08fc..8577edd 100644 >> --- a/src/libvirt-domain.c >> +++ b/src/libvirt-domain.c >> @@ -3425,7 +3425,8 @@ virDomainMigrateDirect(virDomainPtr domain, >> NULLSTR(xmlin), flags, NULLSTR(dname), NULLSTR(uri), >> bandwidth); >> - if (!domain->conn->driver->domainMigratePerform) { >> + if (!domain->conn->driver->domainMigratePerform && >> + !domain->conn->driver->domainMigratePerform3) { >> virReportUnsupportedError(); >> return -1; >> } > > Could you, please, send this change in a separate patch, because it's a sort of bugfix to common libvirt code and not related to our migration? ok > >> diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c >> index 8fa7957..f82fff8 100644 >> --- a/src/vz/vz_driver.c >> +++ b/src/vz/vz_driver.c >> @@ -1343,6 +1343,196 @@ vzDomainMemoryStats(virDomainPtr domain, >> return ret; >> } >> +static char* >> +vzFormatCookie(const unsigned char *session_uuid) >> +{ >> + char uuidstr[VIR_UUID_STRING_BUFLEN]; >> + virBuffer buf = VIR_BUFFER_INITIALIZER; >> + >> + virBufferAddLit(&buf, "<vz-migration1>\n"); >> + virUUIDFormat(session_uuid, uuidstr); >> + virBufferAsprintf(&buf, "<session_uuid>%s</session_uuid>\n", uuidstr); >> + virBufferAddLit(&buf, "</vz-migration1>\n"); > > ..... >> + >> +static virURIPtr >> +vzMakeVzUri(const char *connuri_str) >> +{ >> + virURIPtr connuri = NULL; >> + virURIPtr vzuri = NULL; >> + int ret = -1; >> + >> + if (!(connuri = virURIParse(connuri_str))) >> + goto cleanup; >> + >> + if (VIR_ALLOC(vzuri) < 0) >> + goto cleanup; >> + memset(vzuri, 0, sizeof(*vzuri)); >> + >> + if (VIR_STRDUP(vzuri->server, connuri->server) < 0) >> + goto cleanup; >> + vzuri->port = connuri->port; >> + ret = 0; >> + > > This is generally not correct, since you are passing the port of libvirt's connection to vz connection, it works if you don't specify port in URI, port is 0 in this case, and libprlsdk accepts it. I'm not agree. This function is called with hypervisor specific uri where port is hypervisor and not libvirtd port. > >> + cleanup: >> + >> + virURIFree(connuri); >> + if (ret < 0) { >> + virURIFree(vzuri); >> + vzuri = NULL; >> + } >> + >> + return vzuri; >> +} >> + >> +#define VZ_MIGRATION_FLAGS (0) >> + >> +#define VZ_MIGRATION_PARAMETERS (NULL) >> + >> +static int >> +vzDomainMigratePerform3(virDomainPtr domain, >> + const char *xmlin ATTRIBUTE_UNUSED, >> + const char *cookiein ATTRIBUTE_UNUSED, >> + int cookieinlen ATTRIBUTE_UNUSED, >> + char **cookieout ATTRIBUTE_UNUSED, >> + int *cookieoutlen ATTRIBUTE_UNUSED, >> + const char *dconnuri ATTRIBUTE_UNUSED, >> + const char *uri, >> + unsigned long flags, >> + const char *dname ATTRIBUTE_UNUSED, >> + unsigned long bandwidth ATTRIBUTE_UNUSED) >> +{ >> + int ret = -1; >> + virDomainObjPtr dom = NULL; >> + virConnectPtr dconn = NULL; >> + virURIPtr vzuri = NULL; >> + unsigned char session_uuid[VIR_UUID_BUFLEN]; >> + vzConnPtr privconn = domain->conn->privateData; >> + char *cookie = NULL; >> + int cookielen = 0; >> + >> + virCheckFlags(VZ_MIGRATION_FLAGS, -1); >> + >> + if (!(vzuri = vzMakeVzUri(uri))) >> + goto cleanup; >> + >> + if (!(dom = vzDomObjFromDomain(domain))) >> + goto cleanup; >> + >> + dconn = virConnectOpen(uri); >> + if (dconn == NULL) { >> + virReportError(VIR_ERR_OPERATION_FAILED, >> + _("Failed to connect to remote libvirt URI %s: %s"), >> + uri, virGetLastErrorMessage()); >> + goto cleanup; >> + } >> + >> + /* NULL and zero elements are unused */ >> + /* domxml is passed as "" or otherwise we will fail at rpc call */ >> + if (virDomainMigratePrepare3(dconn, NULL, 0, &cookie, &cookielen, NULL, NULL, 0, NULL, 0, "") < 0) > Could you split this line? ok > >> + goto cleanup; >> + >> + if (vzParseCookie(cookie, session_uuid) < 0) >> + goto cleanup; >> + >> + if (prlsdkMigrate(dom, vzuri, session_uuid) < 0) >> + goto cleanup; >> + >> + virDomainObjListRemove(privconn->domains, dom); >> + dom = NULL; >> + >> + ret = 0; >> + >> + cleanup: >> + if (dom) >> + virObjectUnlock(dom); >> + virObjectUnref(dconn); >> + virURIFree(vzuri); >> + VIR_FREE(cookie); >> + >> + return ret; >> +} >> + >> static virHypervisorDriver vzDriver = { >> .name = "vz", >> .connectOpen = vzConnectOpen, /* 0.10.0 */ >> @@ -1396,6 +1586,9 @@ static virHypervisorDriver vzDriver = { >> .domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */ >> .domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ >> .domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */ >> + .connectSupportsFeature = vzConnectSupportsFeature, /* 1.2.19 */ >> + .domainMigratePrepare3 = vzDomainMigratePrepare3, /* 1.2.19 */ >> + .domainMigratePerform3 = vzDomainMigratePerform3, /* 1.2.19 */ >> }; >> static virConnectDriver vzConnectDriver = { >> diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c >> index f7253de..783438d 100644 >> --- a/src/vz/vz_sdk.c >> +++ b/src/vz/vz_sdk.c >> @@ -4054,3 +4054,36 @@ prlsdkGetMemoryStats(virDomainObjPtr dom, >> return ret; >> } >> + >> +/* high security is default choice for 2 reasons: >> + 1. as this is the highest set security we can't get >> + reject from server with high security settings >> + 2. this is on par with security level of driver >> + connection to dispatcher */ >> + >> +#define PRLSDK_MIGRATION_FLAGS (PSL_HIGH_SECURITY) >> + >> +int prlsdkMigrate(virDomainObjPtr dom, virURIPtr uri, >> + const unsigned char *session_uuid) >> +{ >> + int ret = -1; >> + vzDomObjPtr privdom = dom->privateData; >> + PRL_HANDLE job = PRL_INVALID_HANDLE; >> + char uuidstr[VIR_UUID_STRING_BUFLEN + 2]; >> + >> + prlsdkUUIDFormat(session_uuid, uuidstr); >> + job = PrlVm_MigrateEx(privdom->sdkdom, uri->server, uri->port, uuidstr, >> + "", /* use default dir for migrated instance bundle */ >> + PRLSDK_MIGRATION_FLAGS, >> + 0, /* reserved flags */ >> + PRL_TRUE /* don't ask for confirmations */ >> + ); >> + >> + if (PRL_FAILED(waitJob(job))) >> + goto cleanup; >> + >> + ret = 0; >> + >> + cleanup: >> + return ret; >> +} >> diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h >> index ebe4591..d3f0caf 100644 >> --- a/src/vz/vz_sdk.h >> +++ b/src/vz/vz_sdk.h >> @@ -76,3 +76,5 @@ int >> prlsdkGetVcpuStats(virDomainObjPtr dom, int idx, unsigned long long *time); >> int >> prlsdkGetMemoryStats(virDomainObjPtr dom, virDomainMemoryStatPtr stats, unsigned int nr_stats); >> +int >> +prlsdkMigrate(virDomainObjPtr dom, virURIPtr uri, const char unsigned *session_uuid); > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list