[libvirt] [PATCH 5/6] vz: support misc migration options

nshirokovskiy at virtuozzo.com nshirokovskiy at virtuozzo.com
Mon Jul 13 12:28:55 UTC 2015

From: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>

Migration API has a lot of options. This patch intention is to provide
support for those options that can be trivially supported and give
estimation for other options support in this commit message.

I. Supported.

1. VIR_MIGRATE_COMPRESSED. Means 'use compression when migration domain
memory'. It is supported but quite uncommon way: vz migration demands that this
option should be set. This is due to vz is hardcoded to moving VMs memory using
compression. So anyone who wants to migrate vz domain should set this option
thus declaring it knows it uses compression.

Why bother? May be just support this option and ignore if it is not set or
don't support at all as we can't change behaviour in this aspect.  Well I
believe that this option is, first, inherent to hypervisor implementation as
we have a task of moving domain memory to different place and, second, we have
a tradeoff here between cpu and network resources and some managment should
choose the stratery via this option. If we choose ignoring or unsupporting
implementation than this option has a too vague meaning. Let's go into more

First if we ignore situation where option is not set than we put user into
fallacy that vz hypervisor don't use compression and thus have lower cpu
usage. Second approach is to not support the option. The main reason not to
follow this way is that 'not supported and not set' is indistinguishable from
'supported and not set' and thus again fool the user.

2. VIR_MIGRATE_LIVE. Means 'reduce domain downtime by suspending it as lately
as possible' which technically means 'migrate as much domain memory as possible
before suspending'. Supported in same manner as VIR_MIGRATE_COMPRESSED as both
vz VMs and CTs are always migrated via live scheme.

One may be fooled by vz sdk flags of migration api: PVMT_HOT_MIGRATION(aka
live) and PVMT_WARM_MIGRATION(aka normal). Current implementation ignore these
flags and always use live migration.

together. Vz domain are alwasy persistent so we have to support demand option
this is done just by unsupporting it).

4. VIR_MIGRATE_PAUSED. Means 'don't resume domain on destination'. This is
trivially supported as we have a corresponding option in vz migration.

All that said the minimal command to migrate vz domain looks next:

migrate $DOMAIN $DESTINATION --live --persistent --compressed.

Not good. Say if you want to just migrate a domain without further
details you will get error messages until you add these options to
command line. I think there is a lack of notion 'default' behaviour
in all these aspects. If we have it we could just issue:


For vz this would give default compression for example, for qemu - default
no-compression. Then we could have flags --compressed and -no-compressed
and for vz the latter would give unsupported error.

II. Unsupported.

1. VIR_MIGRATE_UNSAFE. Vz disks are always have 'cache=none' set (this
is not reflected in current version of vz driver and will be fixed
soon). So we need not to support this option.

2. VIR_MIGRATE_CHANGE_PROTECTION. Unsupported as we have no appopriate
support from vz sdk. Although we have locks they are advisory and
cant help us.

3. VIR_MIGRATE_TUNNELLED. Means 'use libvirtd to libvirtd connection
to pass hypervisor migration traffic'. Unsupported as not among
vz hypervisor usecases. Moreover this feature only has meaning
for peer2peer migration that is not implemented in this patch set.

4. Direct migration. Which is exposed via *toURI* interface with
VIR_MIGRATE_PEER2PEER flag unset. Means 'migrate without using
libvirtd on the other side'. To support it we should add authN
means to vz driver as mentioned in 'backbone patch' which looks

Without further discussion. They are just not usecases of vz hypevisor.

III. Unimplemented.

1. VIR_MIGRATE_OFFLINE. Means 'migrate only XML definition of a domain'.
Actually the same vz sdk call supports offline migration but nevertheless we
don't get it for free for vz domain because in case of offline migration only
steps 'begin' and 'prepare' are performed while we can't issue vz migration
command ealier than 'perform' step as we need authN cookie. So we need
extra work to be done which goes to different patchset.

2. VIR_MIGRATE_PEER2PEER. Means 'whole migration managment should
be done by the daemon of the source side'. QEMU does this but
at the cost of heavily(at my estimate) duplicate client side migration
managment code. We can do these too for vz or even better - refactor
and than support. So it goes to different patchset.

IV. Undecided and thus unsupported.

6. VIR_MIGRATE_NON_SHARED_DISK. The meaning of this option is not clear to me.
Look, if qemu domain has a non-shared disk than it will refuse to migrate. But
after you specify this option it will refuse too. You need to create image file
for the disk on the destination side. Only after that you can migrate.
Unexpectedly existence of this file is enough to migrate without option too. In
this case you will get a domain on the destination with disk image unrelated to
source one and this is in case of live migration! Looks like a bug. Ok, imagine
this is fixed so that migration of non-shared disk is only possible with
actual coping disk to destination. What we get from this option? We get
that you have to specify this option if you want to migrate a domain with
non-shared disk like some forcing option. May be it is a good approach
but it is incompatible with vz. Vz don't demand any user awareness of
migration of non-shared disks. And this case incompatibility can not
be easily resolved as for 'compressed' option as this option depends on
classifying of shared/non-shared for disks which is done inside vz.
vz: implement misc migration options

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
 src/vz/vz_driver.c |   42 +++++++++++++++++++++++++++++++++++++++---
 src/vz/vz_sdk.c    |    8 ++++++--
 src/vz/vz_sdk.h    |    3 ++-
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 9fefac1..5a0b3f8 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -1359,17 +1359,53 @@ vzConnectSupportsFeature(virConnectPtr conn ATTRIBUTE_UNUSED, int feature)
+#define VZ_MIGRATION_FLAGS          \
+    (VIR_MIGRATE_LIVE |             \
+int vzCheckFlags(int flags)
+    if (!(flags & VIR_MIGRATE_LIVE)) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                            _("flags VIR_MIGRATE_LIVE must be set"
+                              " for vz migration"));
+        return -1;
+    }
+    if (!(flags & VIR_MIGRATE_COMPRESSED)) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                            _("flags VIR_MIGRATE_COMPRESSED must be set"
+                              " for vz migration"));
+        return -1;
+    }
+    if (!(flags & VIR_MIGRATE_PERSIST_DEST)) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                            _("flags VIR_MIGRATE_PERSIST_DEST must be set"
+                              " for vz migration"));
+        return -1;
+    }
+    virCheckFlags(VZ_MIGRATION_FLAGS, -1);
+    return 0;
 static char *
 vzDomainMigrateBegin3Params(virDomainPtr domain,
                             virTypedParameterPtr params,
                             int nparams,
                             char **cookieout ATTRIBUTE_UNUSED,
                             int *cookieoutlen ATTRIBUTE_UNUSED,
-                            unsigned int fflags ATTRIBUTE_UNUSED)
+                            unsigned int flags)
     virDomainObjPtr dom = NULL;
     char *xml = NULL;
+    if (vzCheckFlags(flags) < 0)
+        goto cleanup;
     if (virTypedParamsValidate(params, nparams, VZ_MIGRATION_PARAMETERS) < 0)
         goto cleanup;
@@ -1604,7 +1640,7 @@ vzDomainMigratePerform3Params(virDomainPtr domain,
                               int cookieinlen ATTRIBUTE_UNUSED,
                               char **cookieout,
                               int *cookieoutlen,
-                              unsigned int fflags ATTRIBUTE_UNUSED)
+                              unsigned int fflags)
     int ret = -1;
     virDomainObjPtr dom = NULL;
@@ -1634,7 +1670,7 @@ vzDomainMigratePerform3Params(virDomainPtr domain,
     if (vzParseCookie1(cookiein, session_uuid) < 0)
         goto cleanup;
-    if (prlsdkMigrate(dom, uri, session_uuid, dname) < 0)
+    if (prlsdkMigrate(dom, uri, session_uuid, dname, fflags) < 0)
         goto cleanup;
     if (!(*cookieout = vzFormatCookie2(dom->def->uuid)))
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index f1fa6da..7646796 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -4067,24 +4067,28 @@ prlsdkGetMemoryStats(virDomainObjPtr dom,
 int prlsdkMigrate(virDomainObjPtr dom, const char* uri_str,
-                  const unsigned char *session_uuid, const char *dname)
+                  const unsigned char *session_uuid, const char *dname, unsigned int flags)
     int ret = -1;
     vzDomObjPtr privdom = dom->privateData;
     virURIPtr uri = NULL;
     char uuidstr[VIR_UUID_STRING_BUFLEN + 2];
     uri = virURIParse(uri_str);
     /* no special error logs as uri should be checked on prepare step */
     if (uri == NULL)
         goto cleanup;
+    if (flags & VIR_MIGRATE_PAUSED)
+        vzflags |= PVMT_DONT_RESUME_VM;
     prlsdkUUIDFormat(session_uuid, uuidstr);
     job = PrlVm_MigrateWithRenameEx(privdom->sdkdom, uri->server, uri->port, uuidstr,
                           dname == NULL ? "" : dname,
                           "", /* use default dir for migrated instance bundle */
-                          PRLSDK_MIGRATION_FLAGS,
+                          vzflags,
                           0, /* reserved flags */
                           PRL_TRUE /* don't ask for confirmations */
diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h
index 971f913..02bd7f5 100644
--- a/src/vz/vz_sdk.h
+++ b/src/vz/vz_sdk.h
@@ -80,4 +80,5 @@ int
 prlsdkMigrate(virDomainObjPtr dom,
               const char* uri_str,
               const unsigned char *session_uuid,
-              const char* dname);
+              const char* dname,
+              unsigned int flags);

More information about the libvir-list mailing list