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(a)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