On 08/25/2015 12:04 PM, nshirokovskiy(a)virtuozzo.com wrote:
From: Nikolay Shirokovskiy <nshirokovskiy(a)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(a)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?
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.
+ 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?
+ 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);