
On Thu, Feb 11, 2021 at 16:37:51 +0100, Peter Krempa wrote:
In cases where we are copying the storage we need to ensure that also bitmaps are copied properly. This patch adds migration cookie XML infrastructure which will allow the migration sides reach consensus on which bitmaps to migrate.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration_cookie.c | 134 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_cookie.h | 34 ++++++++ 2 files changed, 168 insertions(+)
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index 6f2b1b2f57..94ba9c83d0 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c ... @@ -758,6 +795,48 @@ qemuMigrationCookieNBDXMLFormat(qemuMigrationCookieNBDPtr nbd, }
+static void +qemuMigrationCookieBlockDirtyBitmapsFormat(virBufferPtr buf, + GSList *bitmaps) +{ + g_auto(virBuffer) disksBuf = VIR_BUFFER_INIT_CHILD(buf); + GSList *nextdisk; + + for (nextdisk = bitmaps; nextdisk; nextdisk = nextdisk->next) { + qemuMigrationBlockDirtyBitmapsDiskPtr disk = nextdisk->data; + g_auto(virBuffer) diskAttrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) diskChildBuf = VIR_BUFFER_INIT_CHILD(&disksBuf); + bool hasBitmaps = false; + GSList *nextbitmap; + + if (disk->skip || !disk->bitmaps) + continue; + + for (nextbitmap = disk->bitmaps; nextbitmap; nextbitmap = nextbitmap->next) { + qemuMigrationBlockDirtyBitmapsDiskBitmapPtr bitmap = nextbitmap->data; + + if (bitmap->skip) + continue; + + virBufferAsprintf(&diskChildBuf, + "<bitmap name='%s' alias='%s'/>\n", + bitmap->bitmapname, bitmap->alias); + + hasBitmaps = true; + } + + if (!hasBitmaps) + continue;
You could drop hasBitmaps and call virBufferUse instead, but not a big deal.
+ + virBufferAsprintf(&diskAttrBuf, " target='%s'", disk->target); + virXMLFormatElement(&disksBuf, "disk", &diskAttrBuf, &diskChildBuf); + } + + + virXMLFormatElement(buf, "blockDirtyBitmaps", NULL, &disksBuf); +} + + int qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, virQEMUCapsPtr qemuCaps, @@ -829,6 +908,9 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, if (mig->flags & QEMU_MIGRATION_COOKIE_CAPS) qemuMigrationCookieCapsXMLFormat(buf, mig->caps);
+ if (mig->flags & QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS) + qemuMigrationCookieBlockDirtyBitmapsFormat(buf, mig->blockDirtyBitmaps); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</qemu-migration>\n"); return 0; @@ -1132,6 +1214,53 @@ qemuMigrationCookieXMLParseMandatoryFeatures(xmlXPathContextPtr ctxt, }
+static int +qemuMigrationCookieBlockDirtyBitmapsParse(xmlXPathContextPtr ctxt, + qemuMigrationCookiePtr mig) +{ + g_autoslist(qemuMigrationBlockDirtyBitmapsDisk) disks = NULL; + g_autofree xmlNodePtr *disknodes = NULL; + int ndisknodes; + size_t i; + VIR_XPATH_NODE_AUTORESTORE(ctxt) + + if ((ndisknodes = virXPathNodeSet("./blockDirtyBitmaps/disk", ctxt, &disknodes)) < 0) + return -1; + + for (i = 0; i < ndisknodes; i++) { + GSList *bitmaps = NULL; + qemuMigrationBlockDirtyBitmapsDiskPtr disk; + g_autofree xmlNodePtr *bitmapnodes = NULL; + int nbitmapnodes; + size_t j; + + ctxt->node = disknodes[i]; + + if ((nbitmapnodes = virXPathNodeSet("./bitmap", ctxt, &bitmapnodes)) < 0) + return -1; + + for (j = 0; j < nbitmapnodes; j++) { + qemuMigrationBlockDirtyBitmapsDiskBitmapPtr bitmap; + + bitmap = g_new0(qemuMigrationBlockDirtyBitmapsDiskBitmap, 1); + bitmap->bitmapname = virXMLPropString(bitmapnodes[j], "name"); + bitmap->alias = virXMLPropString(bitmapnodes[j], "alias");
So what if the attributes do not exist? And virXMLPropString does not abort on OOM. You should check for the result being non-NULL here.
+ bitmaps = g_slist_prepend(bitmaps, bitmap); + } + + disk = g_new0(qemuMigrationBlockDirtyBitmapsDisk, 1); + disk->target = virXMLPropString(disknodes[i], "target");
And here as well.
+ disk->bitmaps = g_slist_reverse(bitmaps); + + disks = g_slist_prepend(disks, disk); + } + + mig->blockDirtyBitmaps = g_slist_reverse(g_steal_pointer(&disks)); + + return 0; +} + + static int qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, virQEMUDriverPtr driver, ...
With the checks for virXMLPropString result added Reviewed-by: Jiri Denemark <jdenemar@redhat.com>