[libvirt] [PATCH v3 2/5] vz: add migration backbone code
Nikolay Shirokovskiy
nshirokovskiy at parallels.com
Wed Aug 26 06:44:03 UTC 2015
On 25.08.2015 18:42, Dmitry Guryanov wrote:
> On 08/25/2015 12:04 PM, nshirokovskiy at virtuozzo.com wrote:
>> From: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
>>
>> 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 at virtuozzo.com>
>> ---
>> 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);
>
More information about the libvir-list
mailing list