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@xxxxxxxxxxxx> --- include/libvirt/libvirt-domain.h | 9 ++ src/qemu/qemu_driver.c | 63 +++++++++---- src/qemu/qemu_migration.c | 198 ++++++++++++++++++++++++--------------- src/qemu/qemu_migration.h | 23 +++-- 4 files changed, 192 insertions(+), 101 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 3695b26..2f53df6 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,25 @@ 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); 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; } @@ -12682,7 +12691,8 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri_in, uri_out, - &def, origname, NULL, flags); + &def, origname, NULL, flags, + NULL); cleanup: VIR_FREE(origname); @@ -12708,6 +12718,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, const char *dname = NULL; const char *uri_in = NULL; const char *listenAddress = cfg->migrationAddress; + const char **migrate_disks = NULL; char *origname = NULL; int ret = -1; @@ -12729,6 +12740,9 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, &listenAddress) < 0) goto cleanup; + migrate_disks = virTypedParamsPickStrings(params, nparams, + VIR_MIGRATE_PARAM_MIGRATE_DISKS); + if (flags & VIR_MIGRATE_TUNNELLED) { /* this is a logical error; we never should have gotten here with * VIR_MIGRATE_TUNNELLED set @@ -12749,9 +12763,11 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri_in, uri_out, - &def, origname, listenAddress, flags); + &def, origname, listenAddress, flags, + migrate_disks); cleanup: + VIR_FREE(migrate_disks); VIR_FREE(origname); virDomainDefFree(def); virObjectUnref(cfg); @@ -12882,7 +12898,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, } return qemuMigrationPerform(driver, dom->conn, vm, xmlin, - dconnuri, uri, NULL, NULL, + dconnuri, uri, NULL, NULL, NULL, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, true); @@ -12906,7 +12922,9 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, const char *uri = NULL; const char *graphicsuri = NULL; const char *listenAddress = NULL; + const char **migrate_disks = NULL; unsigned long long bandwidth = 0; + int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0) @@ -12930,20 +12948,27 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, virTypedParamsGetString(params, nparams, VIR_MIGRATE_PARAM_LISTEN_ADDRESS, &listenAddress) < 0) - return -1; + goto cleanup; + + migrate_disks = virTypedParamsPickStrings(params, nparams, + VIR_MIGRATE_PARAM_MIGRATE_DISKS); if (!(vm = qemuDomObjFromDomain(dom))) - return -1; + goto cleanup; if (virDomainMigratePerform3ParamsEnsureACL(dom->conn, vm->def) < 0) { virDomainObjEndAPI(&vm); - return -1; + goto cleanup; } - return qemuMigrationPerform(driver, dom->conn, vm, dom_xml, - dconnuri, uri, graphicsuri, listenAddress, - cookiein, cookieinlen, cookieout, cookieoutlen, - flags, dname, bandwidth, true); + ret = qemuMigrationPerform(driver, dom->conn, vm, dom_xml, + dconnuri, uri, graphicsuri, listenAddress, + migrate_disks, + cookiein, cookieinlen, cookieout, cookieoutlen, + flags, dname, bandwidth, true); + cleanup: + VIR_FREE(migrate_disks); + return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index eb70f29..60c09d8 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1571,12 +1571,32 @@ qemuMigrationPrecreateDisk(virConnectPtr conn, return ret; } +static 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); +} + static int qemuMigrationPrecreateStorage(virConnectPtr conn, virQEMUDriverPtr driver ATTRIBUTE_UNUSED, virDomainObjPtr vm, - qemuMigrationCookieNBDPtr nbd) + qemuMigrationCookieNBDPtr nbd, + const char **migrate_disks) { int ret = -1; size_t i = 0; @@ -1603,9 +1623,9 @@ qemuMigrationPrecreateStorage(virConnectPtr conn, disk = vm->def->disks[indx]; diskSrcPath = virDomainDiskGetSource(disk); - if (disk->src->shared || disk->src->readonly || + /* Skip disks we don't want to migrate and already existing disks. */ + if (!qemuMigrateDisk(disk, migrate_disks) || (diskSrcPath && virFileExists(diskSrcPath))) { - /* Skip shared, read-only and already existing disks. */ continue; } @@ -1636,7 +1656,8 @@ qemuMigrationPrecreateStorage(virConnectPtr conn, static int qemuMigrationStartNBDServer(virQEMUDriverPtr driver, virDomainObjPtr vm, - const char *listenAddr) + const char *listenAddr, + const char **migrate_disks) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -1647,9 +1668,8 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver, for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk = vm->def->disks[i]; - /* skip shared, RO and source-less disks */ - if (disk->src->shared || disk->src->readonly || - !virDomainDiskGetSource(disk)) + /* check whether disk should be migrated */ + if (!qemuMigrateDisk(disk, migrate_disks)) continue; VIR_FREE(diskAlias); @@ -1728,7 +1748,8 @@ qemuMigrationStopNBDServer(virQEMUDriverPtr driver, */ static int qemuMigrationCheckDriveMirror(virQEMUDriverPtr driver, - virDomainObjPtr vm) + virDomainObjPtr vm, + const char **migrate_disks) { size_t i; int ret = 1; @@ -1736,9 +1757,8 @@ qemuMigrationCheckDriveMirror(virQEMUDriverPtr driver, for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk = vm->def->disks[i]; - /* skip shared, RO and source-less disks */ - if (disk->src->shared || disk->src->readonly || - !virDomainDiskGetSource(disk)) + /* check whether disk should be migrated */ + if (!qemuMigrateDisk(disk, migrate_disks)) continue; /* skip disks that didn't start mirroring */ @@ -1864,9 +1884,10 @@ qemuMigrationCancelDriveMirror(virQEMUDriverPtr driver, for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk = vm->def->disks[i]; - /* skip shared, RO and source-less disks */ - if (disk->src->shared || disk->src->readonly || - !virDomainDiskGetSource(disk)) + /* check whether disk should be migrated */ + /* TODO: pass migrate_disks here or loookup list of + * disks under migration using some kind of qemu monitor command */ + if (!qemuMigrateDisk(disk, NULL)) continue; /* skip disks that didn't start mirroring */ @@ -1907,7 +1928,8 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver, qemuMigrationCookiePtr mig, const char *host, unsigned long speed, - unsigned int *migrate_flags) + unsigned int *migrate_flags, + const char **migrate_disks) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -1937,9 +1959,8 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver, virDomainDiskDefPtr disk = vm->def->disks[i]; int mon_ret; - /* skip shared, RO and source-less disks */ - if (disk->src->shared || disk->src->readonly || - !virDomainDiskGetSource(disk)) + /* check whether disk should be migrated */ + if (!qemuMigrateDisk(disk, migrate_disks)) continue; VIR_FREE(diskAlias); @@ -1972,9 +1993,8 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver, for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk = vm->def->disks[i]; - /* skip shared, RO and source-less disks */ - if (disk->src->shared || disk->src->readonly || - !virDomainDiskGetSource(disk)) + /* check whether disk should be migrated */ + if (!qemuMigrateDisk(disk, migrate_disks)) continue; while (disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_READY) { @@ -1993,7 +2013,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver, 500ull, NULL) < 0) goto cleanup; - if (qemuMigrationCheckDriveMirror(driver, vm) < 0) + if (qemuMigrationCheckDriveMirror(driver, vm, migrate_disks) < 0) goto cleanup; } } @@ -2115,7 +2135,7 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm, } static bool -qemuMigrationIsSafe(virDomainDefPtr def) +qemuMigrationIsSafe(virDomainDefPtr def, const char **migrate_disks) { size_t i; @@ -2125,9 +2145,7 @@ qemuMigrationIsSafe(virDomainDefPtr def) /* Our code elsewhere guarantees shared disks are either readonly (in * which case cache mode doesn't matter) or used with cache=none */ - if (src && - !disk->src->shared && - !disk->src->readonly && + if (qemuMigrateDisk(disk, migrate_disks) && disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) { int rc; @@ -2698,7 +2716,8 @@ static char const char *dname, char **cookieout, int *cookieoutlen, - unsigned long flags) + unsigned long flags, + const char **migrate_disks) { char *rv = NULL; qemuMigrationCookiePtr mig = NULL; @@ -2709,9 +2728,10 @@ static char bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR); VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s," - " cookieout=%p, cookieoutlen=%p, flags=%lx", + " cookieout=%p, cookieoutlen=%p, flags=%lx," + " migrate_disks=%p", driver, vm, NULLSTR(xmlin), NULLSTR(dname), - cookieout, cookieoutlen, flags); + cookieout, cookieoutlen, flags, migrate_disks); if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; @@ -2726,7 +2746,8 @@ static char if (!qemuMigrationIsAllowed(driver, vm, NULL, true, abort_on_error)) goto cleanup; - if (!(flags & VIR_MIGRATE_UNSAFE) && !qemuMigrationIsSafe(vm->def)) + if (!(flags & VIR_MIGRATE_UNSAFE) && + !qemuMigrationIsSafe(vm->def, migrate_disks)) goto cleanup; if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC) && @@ -2797,7 +2818,8 @@ qemuMigrationBegin(virConnectPtr conn, const char *dname, char **cookieout, int *cookieoutlen, - unsigned long flags) + unsigned long flags, + const char **migrate_disks) { virQEMUDriverPtr driver = conn->privateData; char *xml = NULL; @@ -2830,7 +2852,7 @@ qemuMigrationBegin(virConnectPtr conn, if (!(xml = qemuMigrationBeginPhase(driver, vm, xmlin, dname, cookieout, cookieoutlen, - flags))) + flags, migrate_disks))) goto endjob; if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { @@ -2898,7 +2920,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, unsigned short port, bool autoPort, const char *listenAddress, - unsigned long flags) + unsigned long flags, + const char **migrate_disks) { virDomainObjPtr vm = NULL; virObjectEventPtr event = NULL; @@ -3093,7 +3116,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, goto cleanup; } - if (qemuMigrationPrecreateStorage(dconn, driver, vm, mig->nbd) < 0) + if (qemuMigrationPrecreateStorage(dconn, driver, vm, mig->nbd, + migrate_disks) < 0) goto cleanup; if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) @@ -3167,7 +3191,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, if (mig->nbd && flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC) && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_SERVER)) { - if (qemuMigrationStartNBDServer(driver, vm, listenAddress) < 0) { + if (qemuMigrationStartNBDServer(driver, vm, listenAddress, + migrate_disks) < 0) { /* error already reported */ goto endjob; } @@ -3266,7 +3291,7 @@ qemuMigrationPrepareTunnel(virQEMUDriverPtr driver, ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, - st, NULL, 0, false, NULL, flags); + st, NULL, 0, false, NULL, flags, NULL); return ret; } @@ -3306,7 +3331,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, virDomainDefPtr *def, const char *origname, const char *listenAddress, - unsigned long flags) + unsigned long flags, + const char **migrate_disks) { unsigned short port = 0; bool autoPort = true; @@ -3318,10 +3344,12 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, " "cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, " - "def=%p, origname=%s, listenAddress=%s, flags=%lx", + "def=%p, origname=%s, listenAddress=%s, flags=%lx, " + "migrate_disks=%p", driver, dconn, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, NULLSTR(uri_in), uri_out, - *def, origname, NULLSTR(listenAddress), flags); + *def, origname, NULLSTR(listenAddress), flags, + migrate_disks); *uri_out = NULL; @@ -3425,7 +3453,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, NULL, uri ? uri->scheme : "tcp", - port, autoPort, listenAddress, flags); + port, autoPort, listenAddress, flags, + migrate_disks); cleanup: virURIFree(uri); VIR_FREE(hostname); @@ -3897,7 +3926,8 @@ qemuMigrationRun(virQEMUDriverPtr driver, unsigned long resource, qemuMigrationSpecPtr spec, virConnectPtr dconn, - const char *graphicsuri) + const char *graphicsuri, + const char **migrate_disks) { int ret = -1; unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; @@ -3913,11 +3943,12 @@ qemuMigrationRun(virQEMUDriverPtr driver, VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, " "cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, " - "spec=%p (dest=%d, fwd=%d), dconn=%p, graphicsuri=%s", + "spec=%p (dest=%d, fwd=%d), dconn=%p, graphicsuri=%s, " + "migrate_disks=%p", driver, vm, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, flags, resource, spec, spec->destType, spec->fwdType, dconn, - NULLSTR(graphicsuri)); + NULLSTR(graphicsuri), migrate_disks); if (flags & VIR_MIGRATE_NON_SHARED_DISK) { migrate_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_DISK; @@ -3953,7 +3984,8 @@ qemuMigrationRun(virQEMUDriverPtr driver, if (qemuMigrationDriveMirror(driver, vm, mig, spec->dest.host.name, migrate_speed, - &migrate_flags) < 0) { + &migrate_flags, + migrate_disks) < 0) { goto cleanup; } } else { @@ -4090,7 +4122,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, /* Confirm state of drive mirrors */ if (mig->nbd) { - if (qemuMigrationCheckDriveMirror(driver, vm) != 1) { + if (qemuMigrationCheckDriveMirror(driver, vm, migrate_disks) != 1) { ret = -1; goto cancel; } @@ -4187,7 +4219,8 @@ static int doNativeMigrate(virQEMUDriverPtr driver, unsigned long flags, unsigned long resource, virConnectPtr dconn, - const char *graphicsuri) + const char *graphicsuri, + const char **migrate_disks) { qemuDomainObjPrivatePtr priv = vm->privateData; virURIPtr uribits = NULL; @@ -4196,10 +4229,10 @@ static int doNativeMigrate(virQEMUDriverPtr driver, VIR_DEBUG("driver=%p, vm=%p, uri=%s, cookiein=%s, cookieinlen=%d, " "cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, " - "graphicsuri=%s", + "graphicsuri=%s, migrate_disks=%p", driver, vm, uri, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, flags, resource, - NULLSTR(graphicsuri)); + NULLSTR(graphicsuri), migrate_disks); if (!(uribits = qemuMigrationParseURI(uri, NULL))) return -1; @@ -4238,7 +4271,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, - graphicsuri); + graphicsuri, migrate_disks); if (spec.destType == MIGRATION_DEST_FD) VIR_FORCE_CLOSE(spec.dest.fd.qemu); @@ -4260,7 +4293,8 @@ static int doTunnelMigrate(virQEMUDriverPtr driver, unsigned long flags, unsigned long resource, virConnectPtr dconn, - const char *graphicsuri) + const char *graphicsuri, + const char **migrate_disks) { qemuDomainObjPrivatePtr priv = vm->privateData; virNetSocketPtr sock = NULL; @@ -4270,10 +4304,10 @@ static int doTunnelMigrate(virQEMUDriverPtr driver, VIR_DEBUG("driver=%p, vm=%p, st=%p, cookiein=%s, cookieinlen=%d, " "cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, " - "graphicsuri=%s", + "graphicsuri=%s, migrate_disks=%p", driver, vm, st, NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, flags, resource, - NULLSTR(graphicsuri)); + NULLSTR(graphicsuri), migrate_disks); if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX) && @@ -4326,7 +4360,7 @@ static int doTunnelMigrate(virQEMUDriverPtr driver, ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, - graphicsuri); + graphicsuri, migrate_disks); cleanup: if (spec.destType == MIGRATION_DEST_FD) { @@ -4436,12 +4470,12 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver, if (flags & VIR_MIGRATE_TUNNELLED) ret = doTunnelMigrate(driver, vm, st, NULL, 0, NULL, NULL, - flags, resource, dconn, NULL); + flags, resource, dconn, NULL, NULL); else ret = doNativeMigrate(driver, vm, uri_out, cookie, cookielen, NULL, NULL, /* No out cookie with v2 migration */ - flags, resource, dconn, NULL); + flags, resource, dconn, NULL, NULL); /* Perform failed. Make sure Finish doesn't overwrite the error */ if (ret < 0) @@ -4503,6 +4537,7 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, const char *uri, const char *graphicsuri, const char *listenAddress, + const char **migrate_disks, unsigned long long bandwidth, bool useParams, unsigned long flags) @@ -4525,10 +4560,11 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, dconnuri=%s, vm=%p, xmlin=%s, " "dname=%s, uri=%s, graphicsuri=%s, listenAddress=%s, " - "bandwidth=%llu, useParams=%d, flags=%lx", + "migrate_disks=%p, bandwidth=%llu, useParams=%d, flags=%lx", driver, sconn, dconn, NULLSTR(dconnuri), vm, NULLSTR(xmlin), NULLSTR(dname), NULLSTR(uri), NULLSTR(graphicsuri), - NULLSTR(listenAddress), bandwidth, useParams, flags); + NULLSTR(listenAddress), migrate_disks, bandwidth, useParams, + flags); /* Unlike the virDomainMigrateVersion3 counterpart, we don't need * to worry about auto-setting the VIR_MIGRATE_CHANGE_PROTECTION @@ -4536,7 +4572,8 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, * a single job. */ dom_xml = qemuMigrationBeginPhase(driver, vm, xmlin, dname, - &cookieout, &cookieoutlen, flags); + &cookieout, &cookieoutlen, flags, + migrate_disks); if (!dom_xml) goto cleanup; @@ -4571,6 +4608,11 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, VIR_MIGRATE_PARAM_LISTEN_ADDRESS, listenAddress) < 0) goto cleanup; + if (migrate_disks && + virTypedParamsPackStrings(¶ms, &nparams, &maxparams, + VIR_MIGRATE_PARAM_MIGRATE_DISKS, + migrate_disks) < 0) + goto cleanup; } if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) @@ -4655,12 +4697,14 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver, ret = doTunnelMigrate(driver, vm, st, cookiein, cookieinlen, &cookieout, &cookieoutlen, - flags, bandwidth, dconn, graphicsuri); + flags, bandwidth, dconn, graphicsuri, + migrate_disks); } else { ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen, &cookieout, &cookieoutlen, - flags, bandwidth, dconn, graphicsuri); + flags, bandwidth, dconn, graphicsuri, + migrate_disks); } /* Perform failed. Make sure Finish doesn't overwrite the error */ @@ -4794,6 +4838,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, const char *uri, const char *graphicsuri, const char *listenAddress, + const char **migrate_disks, unsigned long flags, const char *dname, unsigned long resource, @@ -4807,12 +4852,12 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); bool useParams; - VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, " - "uri=%s, graphicsuri=%s, listenAddress=%s, flags=%lx, " - "dname=%s, resource=%lu", + VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, uri=%s, " + "graphicsuri=%s, listenAddress=%s, migrate_disks=%p, " + "flags=%lx, dname=%s, resource=%lu", driver, sconn, vm, NULLSTR(xmlin), NULLSTR(dconnuri), NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress), - flags, NULLSTR(dname), resource); + migrate_disks, flags, NULLSTR(dname), resource); /* the order of operations is important here; we make sure the * destination side is completely setup before we touch the source @@ -4857,7 +4902,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, /* Only xmlin, dname, uri, and bandwidth parameters can be used with * old-style APIs. */ - if (!useParams && graphicsuri) { + if (!useParams && (graphicsuri || migrate_disks)) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("Migration APIs with extensible parameters are not " "supported but extended parameters were passed")); @@ -4888,7 +4933,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver, if (*v3proto) { ret = doPeer2PeerMigrate3(driver, sconn, dconn, dconnuri, vm, xmlin, dname, uri, graphicsuri, listenAddress, - resource, useParams, flags); + migrate_disks, resource, useParams, flags); } else { ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm, dconnuri, flags, dname, resource); @@ -4922,6 +4967,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, const char *uri, const char *graphicsuri, const char *listenAddress, + const char **migrate_disks, const char *cookiein, int cookieinlen, char **cookieout, @@ -4949,7 +4995,8 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, if (!qemuMigrationIsAllowed(driver, vm, NULL, true, abort_on_error)) goto endjob; - if (!(flags & VIR_MIGRATE_UNSAFE) && !qemuMigrationIsSafe(vm->def)) + if (!(flags & VIR_MIGRATE_UNSAFE) && + !qemuMigrationIsSafe(vm->def, migrate_disks)) goto endjob; qemuMigrationStoreDomainState(vm); @@ -4957,12 +5004,13 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver, if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { ret = doPeer2PeerMigrate(driver, conn, vm, xmlin, dconnuri, uri, graphicsuri, listenAddress, + migrate_disks, flags, dname, resource, &v3proto); } else { qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2); ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen, cookieout, cookieoutlen, - flags, resource, NULL, NULL); + flags, resource, NULL, NULL, NULL); } if (ret < 0) goto endjob; @@ -5021,6 +5069,7 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver, virDomainObjPtr vm, const char *uri, const char *graphicsuri, + const char **migrate_disks, const char *cookiein, int cookieinlen, char **cookieout, @@ -5045,7 +5094,7 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver, ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen, cookieout, cookieoutlen, - flags, resource, NULL, graphicsuri); + flags, resource, NULL, graphicsuri, migrate_disks); if (ret < 0) { if (qemuMigrationRestoreDomainState(conn, vm)) { @@ -5086,6 +5135,7 @@ qemuMigrationPerform(virQEMUDriverPtr driver, const char *uri, const char *graphicsuri, const char *listenAddress, + const char **migrate_disks, const char *cookiein, int cookieinlen, char **cookieout, @@ -5096,13 +5146,13 @@ qemuMigrationPerform(virQEMUDriverPtr driver, bool v3proto) { VIR_DEBUG("driver=%p, conn=%p, vm=%p, xmlin=%s, dconnuri=%s, " - "uri=%s, graphicsuri=%s, listenAddress=%s" + "uri=%s, graphicsuri=%s, listenAddress=%s, migrate_disks=%p, " "cookiein=%s, cookieinlen=%d, cookieout=%p, cookieoutlen=%p, " "flags=%lx, dname=%s, resource=%lu, v3proto=%d", driver, conn, vm, NULLSTR(xmlin), NULLSTR(dconnuri), NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress), - NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen, - flags, NULLSTR(dname), resource, v3proto); + migrate_disks, NULLSTR(cookiein), cookieinlen, cookieout, + cookieoutlen, flags, NULLSTR(dname), resource, v3proto); if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { if (cookieinlen) { @@ -5113,6 +5163,7 @@ qemuMigrationPerform(virQEMUDriverPtr driver, return qemuMigrationPerformJob(driver, conn, vm, xmlin, dconnuri, uri, graphicsuri, listenAddress, + migrate_disks, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, v3proto); @@ -5125,13 +5176,14 @@ qemuMigrationPerform(virQEMUDriverPtr driver, if (v3proto) { return qemuMigrationPerformPhase(driver, conn, vm, uri, - graphicsuri, + graphicsuri, migrate_disks, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource); } else { return qemuMigrationPerformJob(driver, conn, vm, xmlin, dconnuri, uri, graphicsuri, listenAddress, + migrate_disks, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, v3proto); diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 1726455..42d64e9 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -44,13 +44,15 @@ VIR_MIGRATE_RDMA_PIN_ALL) /* All supported migration parameters and their types. */ -# define QEMU_MIGRATION_PARAMETERS \ - VIR_MIGRATE_PARAM_URI, VIR_TYPED_PARAM_STRING, \ - VIR_MIGRATE_PARAM_DEST_NAME, VIR_TYPED_PARAM_STRING, \ - VIR_MIGRATE_PARAM_DEST_XML, VIR_TYPED_PARAM_STRING, \ - VIR_MIGRATE_PARAM_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, \ - VIR_MIGRATE_PARAM_GRAPHICS_URI, VIR_TYPED_PARAM_STRING, \ - VIR_MIGRATE_PARAM_LISTEN_ADDRESS, VIR_TYPED_PARAM_STRING, \ +# define QEMU_MIGRATION_PARAMETERS \ + VIR_MIGRATE_PARAM_URI, VIR_TYPED_PARAM_STRING, \ + VIR_MIGRATE_PARAM_DEST_NAME, VIR_TYPED_PARAM_STRING, \ + VIR_MIGRATE_PARAM_DEST_XML, VIR_TYPED_PARAM_STRING, \ + VIR_MIGRATE_PARAM_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, \ + VIR_MIGRATE_PARAM_GRAPHICS_URI, VIR_TYPED_PARAM_STRING, \ + VIR_MIGRATE_PARAM_LISTEN_ADDRESS, VIR_TYPED_PARAM_STRING, \ + VIR_MIGRATE_PARAM_MIGRATE_DISKS, VIR_TYPED_PARAM_STRING | \ + VIR_TYPED_PARAM_MULTIPLE, \ NULL @@ -99,7 +101,8 @@ char *qemuMigrationBegin(virConnectPtr conn, const char *dname, char **cookieout, int *cookieoutlen, - unsigned long flags); + unsigned long flags, + const char **migrate_disks); virDomainDefPtr qemuMigrationPrepareDef(virQEMUDriverPtr driver, const char *dom_xml, @@ -128,7 +131,8 @@ int qemuMigrationPrepareDirect(virQEMUDriverPtr driver, virDomainDefPtr *def, const char *origname, const char *listenAddress, - unsigned long flags); + unsigned long flags, + const char **migrate_disks); int qemuMigrationPerform(virQEMUDriverPtr driver, virConnectPtr conn, @@ -138,6 +142,7 @@ int qemuMigrationPerform(virQEMUDriverPtr driver, const char *uri, const char *graphicsuri, const char *listenAddress, + const char **migrate_disks, const char *cookiein, int cookieinlen, char **cookieout, -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list