https://bugzilla.redhat.com/show_bug.cgi?id=817700 When pre-creating a disk on the destination, a volume XML is constructed. The XML is then passed to virStorageVolCreateXML() which does the work. But, since there's no <allocation/> in the XML, the disk are fully allocated. This possibly breaks sparse allocation user has on the migration source. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_migration.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d4757e4..7a40548 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -144,6 +144,7 @@ typedef qemuMigrationCookieNBDDisk *qemuMigrationCookieNBDDiskPtr; struct _qemuMigrationCookieNBDDisk { char *target; /* Disk target */ unsigned long long capacity; /* And its capacity */ + unsigned long long allocation; /* And its allocation */ }; typedef struct _qemuMigrationCookieNBD qemuMigrationCookieNBD; @@ -593,6 +594,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig, disk->dst) < 0) goto cleanup; mig->nbd->disks[mig->nbd->ndisks].capacity = entry->capacity; + mig->nbd->disks[mig->nbd->ndisks].allocation = entry->wr_highest_offset; mig->nbd->ndisks++; } @@ -833,8 +835,12 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, for (i = 0; i < mig->nbd->ndisks; i++) { virBufferEscapeString(buf, "<disk target='%s'", mig->nbd->disks[i].target); - virBufferAsprintf(buf, " capacity='%llu'/>\n", + virBufferAsprintf(buf, " capacity='%llu'", mig->nbd->disks[i].capacity); + if (mig->nbd->disks[i].capacity != mig->nbd->disks[i].allocation) + virBufferAsprintf(buf, " allocation='%llu'", + mig->nbd->disks[i].allocation); + virBufferAddLit(buf, "/>\n"); } virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</nbd>\n"); @@ -972,7 +978,7 @@ static qemuMigrationCookieNBDPtr qemuMigrationCookieNBDXMLParse(xmlXPathContextPtr ctxt) { qemuMigrationCookieNBDPtr ret = NULL; - char *port = NULL, *capacity = NULL; + char *port = NULL, *capacity = NULL, *allocation = NULL; size_t i; int n; xmlNodePtr *disks = NULL; @@ -1000,6 +1006,7 @@ qemuMigrationCookieNBDXMLParse(xmlXPathContextPtr ctxt) for (i = 0; i < n; i++) { ctxt->node = disks[i]; VIR_FREE(capacity); + VIR_FREE(allocation); if (!(ret->disks[i].target = virXPathString("string(./@target)", ctxt))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1016,12 +1023,24 @@ qemuMigrationCookieNBDXMLParse(xmlXPathContextPtr ctxt) NULLSTR(capacity)); goto error; } + + allocation = virXPathString("string(./@allocation)", ctxt); + if (allocation) { + if (virStrToLong_ull(allocation, NULL, 10, + &ret->disks[i].allocation) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed disk allocation: '%s'"), + allocation); + goto error; + } + } } } cleanup: VIR_FREE(port); VIR_FREE(capacity); + VIR_FREE(allocation); VIR_FREE(disks); ctxt->node = save_ctxt; return ret; @@ -1541,6 +1560,8 @@ qemuMigrationPrecreateDisk(virConnectPtr conn, virBufferAdjustIndent(&buf, 2); virBufferEscapeString(&buf, "<name>%s</name>\n", volName); virBufferAsprintf(&buf, "<capacity>%llu</capacity>\n", nbd->capacity); + if (nbd->allocation) + virBufferAsprintf(&buf, "<allocation>%llu</allocation>\n", nbd->allocation); virBufferAddLit(&buf, "<target>\n"); virBufferAdjustIndent(&buf, 2); virBufferAsprintf(&buf, "<format type='%s'/>\n", format); @@ -1585,8 +1606,9 @@ qemuMigrationPrecreateStorage(virConnectPtr conn, int indx; const char *diskSrcPath; - VIR_DEBUG("Looking up disk target '%s' (capacity=%llu)", - nbd->disks[i].target, nbd->disks[i].capacity); + VIR_DEBUG("Looking up disk target '%s' (capacity=%llu allocation=%llu)", + nbd->disks[i].target, nbd->disks[i].capacity, + nbd->disks[i].allocation); if ((indx = virDomainDiskIndexByName(vm->def, nbd->disks[i].target, false)) < 0) { -- 2.0.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list