
On 12/01/14 15:57, Michal Privoznik wrote:
Up 'til now, users need to precreate non-shared storage on migration themselves. This is not very friendly requirement and we should do something about it. In this patch, the migration cookie is extended, so that <nbd/> section does not only contain NBD port, but info on disks being migrated. This patch sends a list of pairs of:
<disk target; disk size>
to the destination. The actual storage allocation is left for next commit.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_migration.c | 163 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 143 insertions(+), 20 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f19e68c..26df9c7 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c
@@ -525,20 +543,69 @@ qemuMigrationCookieAddNetwork(qemuMigrationCookiePtr mig,
static int qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig, - virQEMUDriverPtr driver ATTRIBUTE_UNUSED, + virQEMUDriverPtr driver, virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv = vm->privateData; + virHashTablePtr stats = NULL; + size_t i; + int ret = -1;
/* It is not a bug if there already is a NBD data */ if (!mig->nbd && VIR_ALLOC(mig->nbd) < 0) return -1;
+ if (vm->def->ndisks && + VIR_ALLOC_N(mig->nbd->disks, vm->def->ndisks) < 0) + return -1; + mig->nbd->ndisks = 0; + + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDefPtr disk = vm->def->disks[i]; + qemuBlockStats *entry; + + /* skip shared, RO and source-less disks */ + if (disk->src->shared || disk->src->readonly || + !virDomainDiskGetSource(disk))
Either report the size for all disks and decide on the destination whether they are eligible to be copied or restrict this to files only. I personally vote for option 1.
+ continue; + + if (!stats) { + if (!(stats = virHashCreate(10, virHashValueFree))) + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); + if (qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats) < 0) { + qemuDomainObjExitMonitor(driver, vm); + goto cleanup; + } + qemuDomainObjExitMonitor(driver, vm); + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("domain exited meanwhile")); + goto cleanup; + } + } + + if (!disk->info.alias || + !(entry = virHashLookup(stats, disk->info.alias))) + continue; + + if (VIR_STRDUP(mig->nbd->disks[mig->nbd->ndisks].target, + disk->dst) < 0) + goto cleanup; + mig->nbd->disks[mig->nbd->ndisks].capacity = entry->capacity; + mig->nbd->ndisks++; + } + mig->nbd->port = priv->nbdPort; mig->flags |= QEMU_MIGRATION_COOKIE_NBD;
- return 0; + ret = 0; + cleanup: + virHashFree(stats); + return ret; }
@@ -763,7 +830,18 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, virBufferAddLit(buf, "<nbd"); if (mig->nbd->port) virBufferAsprintf(buf, " port='%d'", mig->nbd->port); - virBufferAddLit(buf, "/>\n"); + if (mig->nbd->ndisks) { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + for (i = 0; i < mig->nbd->ndisks; i++) + virBufferAsprintf(buf, "<disk target='%s' capacity='%llu'/>\n", + mig->nbd->disks[i].target,
formatting of @target should probably use virBufferEscape.
+ mig->nbd->disks[i].capacity); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</nbd>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } }
if (mig->flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo)
ACK Peter