On 21.05.2015 13:07, Pavel Boldin wrote:
Implement a `migrate_disks' parameters for the QEMU driver. This
multi-
value parameter can be used to explicitly specify what block devices
are to be migrated using the NBD server. Tunnelled migration using NBD
is to be done.
Signed-off-by: Pavel Boldin <pboldin(a)mirantis.com>
---
include/libvirt/libvirt-domain.h | 9 ++
src/qemu/qemu_driver.c | 66 ++++++++++-----
src/qemu/qemu_migration.c | 174 +++++++++++++++++++++++++--------------
src/qemu/qemu_migration.h | 23 ++++--
4 files changed, 183 insertions(+), 89 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 0f465b9..6b48923 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -748,6 +748,15 @@ typedef enum {
*/
# define VIR_MIGRATE_PARAM_LISTEN_ADDRESS "listen_address"
+/**
+ * VIR_MIGRATE_PARAM_MIGRATE_DISKS:
+ *
+ * virDomainMigrate* params multiple field: The multiple values that list
+ * the block devices to be migrated. At the moment this is only supported
+ * by the QEMU driver but not for the tunnelled migration.
+ */
+# define VIR_MIGRATE_PARAM_MIGRATE_DISKS "migrate_disks"
+
/* Domain migration. */
virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn,
unsigned long flags, const char *dname,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2668011..77b7d9d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12472,7 +12472,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
ret = qemuMigrationPrepareDirect(driver, dconn,
NULL, 0, NULL, NULL, /* No cookies */
uri_in, uri_out,
- &def, origname, NULL, flags);
+ &def, origname, NULL, flags, NULL);
cleanup:
VIR_FREE(origname);
@@ -12525,7 +12525,7 @@ qemuDomainMigratePerform(virDomainPtr dom,
* Consume any cookie we were able to decode though
*/
ret = qemuMigrationPerform(driver, dom->conn, vm,
- NULL, dconnuri, uri, NULL, NULL,
+ NULL, dconnuri, uri, NULL, NULL, NULL,
cookie, cookielen,
NULL, NULL, /* No output cookies in v2 */
flags, dname, resource, false);
@@ -12602,7 +12602,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
}
return qemuMigrationBegin(domain->conn, vm, xmlin, dname,
- cookieout, cookieoutlen, flags);
+ cookieout, cookieoutlen, flags, NULL);
}
static char *
@@ -12615,11 +12615,13 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain,
{
const char *xmlin = NULL;
const char *dname = NULL;
+ const char **migrate_disks = NULL;
+ char *ret = NULL;
virDomainObjPtr vm;
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
- return NULL;
+ goto cleanup;
if (virTypedParamsGetString(params, nparams,
VIR_MIGRATE_PARAM_DEST_XML,
@@ -12627,18 +12629,26 @@ qemuDomainMigrateBegin3Params(virDomainPtr domain,
virTypedParamsGetString(params, nparams,
VIR_MIGRATE_PARAM_DEST_NAME,
&dname) < 0)
- return NULL;
+ goto cleanup;
+
+ migrate_disks = virTypedParamsPickStrings(params, nparams,
+ VIR_MIGRATE_PARAM_MIGRATE_DISKS,
+ NULL);
Since this function looks slightly different now, this patch needs to be
changed too. Mostly, where @migrate_disks is parsed, new variable (say
@nmigrate_disks) describing the array length needs to be passed too.
if (!(vm = qemuDomObjFromDomain(domain)))
- return NULL;
+ goto cleanup;
if (virDomainMigrateBegin3ParamsEnsureACL(domain->conn, vm->def) < 0) {
virDomainObjEndAPI(&vm);
- return NULL;
+ goto cleanup;
}
- return qemuMigrationBegin(domain->conn, vm, xmlin, dname,
- cookieout, cookieoutlen, flags);
+ ret = qemuMigrationBegin(domain->conn, vm, xmlin, dname,
+ cookieout, cookieoutlen, flags, migrate_disks);
+
+ cleanup:
+ VIR_FREE(migrate_disks);
+ return ret;
}
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 8fe1cfb..708d1aa 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1579,12 +1579,32 @@ qemuMigrationPrecreateDisk(virConnectPtr conn,
return ret;
}
+static int
This should return bool rather than int.
+qemuMigrateDisk(virDomainDiskDefPtr const disk, const char
**migrate_disks)
+{
+ size_t i;
+ /* Check if the disk alias is in the list */
+ if (disk->info.alias && migrate_disks) {
+ for (i = 0; migrate_disks[i]; i++) {
+ if (STREQ(disk->info.alias, migrate_disks[i]))
+ return 1;
+ }
+ return 0;
+ }
+
+ /* Default is to migrate only non-shared non-readonly disks
+ * with source */
+ return !disk->src->shared && !disk->src->readonly &&
+ virDomainDiskGetSource(disk);
+}
+
@@ -4577,6 +4614,11 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
listenAddress) < 0)
goto cleanup;
+ if (migrate_disks &&
+ virTypedParamsAddStringList(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_MIGRATE_DISKS,
+ migrate_disks) < 0)
+ goto cleanup;
Since @migrate_disks is no longer a NULL terminated array (but hey, we
have @nmigrate_disks) this must be turned into a for() loop.
}
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
Otherwise looking good.
Michal