On Thu, Feb 11, 2021 at 16:37:53 +0100, Peter Krempa wrote:
> Add status XML infrastructure for storing a list of block dirty bitmaps
> which are temporarily used when migrating a VM with
> VIR_MIGRATE_NON_SHARED_DISK for cleanup after a libvirtd restart during
> migration.
> 
> Signed-off-by: Peter Krempa <pkre...@redhat.com>
> ---
>  src/qemu/qemu_domain.c | 90 ++++++++++++++++++++++++++++++++++++++++--
>  src/qemu/qemu_domain.h | 15 +++++++
>  2 files changed, 102 insertions(+), 3 deletions(-)
> 
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 53b4fb5f4f..ed37917670 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -86,6 +86,18 @@ qemuJobAllocPrivate(void)
>  }
> 
> 
> +void
> +qemuDomainJobPrivateMigrateTempBitmapFree(qemuDomainJobPrivateMigrateTempBitmapPtr
>  bmp)
> +{
> +    if (!bmp)
> +        return;
> +
> +    g_free(bmp->nodename);
> +    g_free(bmp->bitmapname);
> +    g_free(bmp);
> +}
> +
> +
>  static void
>  qemuJobFreePrivate(void *opaque)
>  {
> @@ -95,6 +107,9 @@ qemuJobFreePrivate(void *opaque)
>          return;
> 
>      qemuMigrationParamsFree(priv->migParams);
> +    if (priv->migTempBitmaps)
> +        g_slist_free_full(priv->migTempBitmaps,
> +                          (GDestroyNotify) 
> qemuDomainJobPrivateMigrateTempBitmapFree);

I just realized this now although the same pattern is used in previous
patches... Shouldn't g_slist_free_full be able to cope with NULL making
the if () check before it redundant?

>      VIR_FREE(priv);
>  }
> 
> @@ -165,6 +180,28 @@ qemuDomainObjPrivateXMLFormatNBDMigration(virBufferPtr 
> buf,
>      return 0;
>  }
> 
> +
> +static void
> +qemuDomainObjPrivateXMLFormatMigrationBlockDirtyBitmapsTemp(virBufferPtr buf,
> +                                                            GSList *bitmaps)

The naming is pretty inconsistent here, how about

    qemuDomainObjPrivateXMLFormatMigrateTempBitmap(...)?

> +{
> +    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
> +    GSList *next;
> +
> +    for (next = bitmaps; next; next = next->next) {
> +        qemuDomainJobPrivateMigrateTempBitmapPtr t = next->data;
> +        g_auto(virBuffer) bitmapBuf = VIR_BUFFER_INITIALIZER;
> +
> +        virBufferAsprintf(&bitmapBuf, " name='%s'", t->bitmapname);
> +        virBufferAsprintf(&bitmapBuf, " nodename='%s'", t->nodename);
> +
> +        virXMLFormatElement(&childBuf, "bitmap", &bitmapBuf, NULL);
> +    }
> +
> +    virXMLFormatElement(buf, "tempBlockDirtyBitmaps", NULL, &childBuf);
> +}
> +
> +
>  static int
>  qemuDomainFormatJobPrivate(virBufferPtr buf,
>                             qemuDomainJobObjPtr job,
> @@ -172,9 +209,14 @@ qemuDomainFormatJobPrivate(virBufferPtr buf,
>  {
>      qemuDomainJobPrivatePtr priv = job->privateData;
> 
> -    if (job->asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT &&
> -        qemuDomainObjPrivateXMLFormatNBDMigration(buf, vm) < 0)
> -        return -1;
> +    if (job->asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
> +        if (qemuDomainObjPrivateXMLFormatNBDMigration(buf, vm) < 0)
> +            return -1;
> +
> +        if (priv->migTempBitmaps)
> +            qemuDomainObjPrivateXMLFormatMigrationBlockDirtyBitmapsTemp(buf,
> +                                                                        
> priv->migTempBitmaps);

You could just directly call the formatting function as it won't format
anything when priv->migTempBitmaps is an empty list.

> +    }
> 
>      if (priv->migParams)
>          qemuMigrationParamsFormat(buf, priv->migParams);
> @@ -267,6 +309,45 @@ qemuDomainObjPrivateXMLParseJobNBD(virDomainObjPtr vm,
>      return 0;
>  }
> 
> +
> +static int
> +qemuDomainParseJobPrivateXMLMigrationBlockDirtyBitmapsTemp(qemuDomainJobPrivatePtr
>  jobPriv,
> +                                                           
> xmlXPathContextPtr ctxt)

qemuDomainObjPrivateXMLParseMigrateTempBitmap would make the naming a
bit more consistent with other formatting and parsing functions.

> +{
> +    g_autoslist(qemuDomainJobPrivateMigrateTempBitmap) bitmaps = NULL;
> +    g_autofree xmlNodePtr *nodes = NULL;
> +    size_t i;
> +    int n;
> +
> +    if ((n = virXPathNodeSet("./tempBlockDirtyBitmaps/bitmap", ctxt, 
> &nodes)) < 0)
> +        return -1;
> +
> +    if (n == 0)
> +        return 0;
> +
> +    for (i = 0; i < n; i++) {
> +        g_autofree char *bitmapname = virXMLPropString(nodes[i], "name");
> +        g_autofree char *nodename = virXMLPropString(nodes[i], "nodename");
> +        qemuDomainJobPrivateMigrateTempBitmapPtr bmp;
> +
> +        if (!bitmapname || !nodename) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("malformed <tempBlockDirtyBitmaps>"));
> +            return -1;
> +        }

Right, something similar is needed in patch 12/19. Although you could
mention extend the error message here and mention the error happened in
a status XML.

And you could even get away without the temp variables by marking bmp
for autoclean and stealing its content when adding to the list.

> +
> +        bmp = g_new0(qemuDomainJobPrivateMigrateTempBitmap, 1);
> +        bmp->nodename = g_steal_pointer(&nodename);
> +        bmp->bitmapname = g_steal_pointer(&bitmapname);
> +
> +        bitmaps = g_slist_prepend(bitmaps, bmp);
> +    }
> +
> +    jobPriv->migTempBitmaps = g_slist_reverse(g_steal_pointer(&bitmaps));
> +    return 0;
> +}
> +
> +
>  static int
>  qemuDomainParseJobPrivate(xmlXPathContextPtr ctxt,
>                            qemuDomainJobObjPtr job,
> @@ -277,6 +358,9 @@ qemuDomainParseJobPrivate(xmlXPathContextPtr ctxt,
>      if (qemuDomainObjPrivateXMLParseJobNBD(vm, ctxt) < 0)
>          return -1;
> 
> +    if (qemuDomainParseJobPrivateXMLMigrationBlockDirtyBitmapsTemp(priv, 
> ctxt) < 0)
> +        return -1;
> +
>      if (qemuMigrationParamsParse(ctxt, &priv->migParams) < 0)
>          return -1;
> 
...

No matter whether you decide to change the functions names...

Reviewed-by: Jiri Denemark <jdene...@redhat.com>

Reply via email to