
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@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