All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Alexander Mikhalitsyn <alexander@mihalicyn.com>
Cc: qemu-devel@nongnu.org, "Jesper Devantier" <foss@defmacro.it>,
	"Kevin Wolf" <kwolf@redhat.com>,
	"Fabiano Rosas" <farosas@suse.de>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Hanna Reitz" <hreitz@redhat.com>,
	qemu-block@nongnu.org, "Stéphane Graber" <stgraber@stgraber.org>,
	"Keith Busch" <kbusch@kernel.org>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Fam Zheng" <fam@euphon.net>, "Klaus Jensen" <its@irrelevant.dk>,
	"Zhao Liu" <zhao1.liu@intel.com>,
	"Alexander Mikhalitsyn" <aleksandr.mikhalitsyn@futurfusion.io>
Subject: Re: [PATCH v4 1/8] migration/vmstate: introduce vmstate_{load,save}_field helpers
Date: Fri, 13 Mar 2026 12:27:52 -0400	[thread overview]
Message-ID: <abQ7CLuJsWRLwoe5@x1.local> (raw)
In-Reply-To: <20260313141221.359503-2-alexander@mihalicyn.com>

On Fri, Mar 13, 2026 at 03:12:14PM +0100, Alexander Mikhalitsyn wrote:
> From: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
> 
> Let's introduce vmstate_{load,save}_field() helpers, they will
> be used in next patches to support fully-dynamic arrays with NULLs.
> 
> Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>

Feel free to rebase to Vladimir's series here, Fabiano already queued it:

https://lore.kernel.org/all/20260304212303.667141-11-vsementsov@yandex-team.ru/#t

These codes weren't touched that frequent, it's interesting to see such
coinsidence happens. :)

> ---
>  include/migration/vmstate.h |  4 ++
>  migration/vmstate.c         | 84 +++++++++++++++++++++++--------------
>  2 files changed, 56 insertions(+), 32 deletions(-)
> 
> diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
> index 62c2abd0c49..5d7dfe70643 100644
> --- a/include/migration/vmstate.h
> +++ b/include/migration/vmstate.h
> @@ -1240,8 +1240,12 @@ extern const VMStateInfo vmstate_info_qlist;
>          .flags = VMS_END, \
>      }
>  
> +int vmstate_load_field(QEMUFile *f, void *pv, size_t size,
> +                       const VMStateField *field, Error **errp);
>  int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
>                         void *opaque, int version_id, Error **errp);
> +int vmstate_save_field(QEMUFile *f, void *pv, size_t size,
> +                       const VMStateField *field, JSONWriter *vmdesc, Error **errp);
>  int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
>                         void *opaque, JSONWriter *vmdesc, Error **errp);
>  int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
> diff --git a/migration/vmstate.c b/migration/vmstate.c
> index 4d28364f7ba..8d192bcaa27 100644
> --- a/migration/vmstate.c
> +++ b/migration/vmstate.c
> @@ -131,6 +131,32 @@ static void vmstate_handle_alloc(void *ptr, const VMStateField *field,
>      }
>  }
>  
> +int vmstate_load_field(QEMUFile *f, void *pv, size_t size,
> +                       const VMStateField *field, Error **errp)
> +{
> +    int ret = 0;
> +
> +    if (field->flags & VMS_STRUCT) {
> +        ret = vmstate_load_state(f, field->vmsd, pv,
> +                                 field->vmsd->version_id,
> +                                 errp);
> +    } else if (field->flags & VMS_VSTRUCT) {
> +        ret = vmstate_load_state(f, field->vmsd, pv,
> +                                 field->struct_version_id,
> +                                 errp);
> +    } else {
> +        ret = field->info->get(f, pv, size, field);
> +        if (ret < 0) {
> +            error_setg(errp,
> +                       "Failed to load element of type %s for %s: "
> +                       "%d", field->info->name,
> +                       field->name, ret);
> +        }
> +    }
> +
> +    return ret;
> +}
> +
>  int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
>                         void *opaque, int version_id, Error **errp)
>  {
> @@ -203,24 +229,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
>                      inner_field = field;
>                  }
>  
> -                if (inner_field->flags & VMS_STRUCT) {
> -                    ret = vmstate_load_state(f, inner_field->vmsd, curr_elem,
> -                                             inner_field->vmsd->version_id,
> -                                             errp);
> -                } else if (inner_field->flags & VMS_VSTRUCT) {
> -                    ret = vmstate_load_state(f, inner_field->vmsd, curr_elem,
> -                                             inner_field->struct_version_id,
> -                                             errp);
> -                } else {
> -                    ret = inner_field->info->get(f, curr_elem, size,
> -                                                 inner_field);
> -                    if (ret < 0) {
> -                        error_setg(errp,
> -                                   "Failed to load element of type %s for %s: "
> -                                   "%d", inner_field->info->name,
> -                                   inner_field->name, ret);
> -                    }
> -                }
> +                ret = vmstate_load_field(f, curr_elem, size, inner_field, errp);
>  
>                  /* If we used a fake temp field.. free it now */
>                  if (inner_field != field) {
> @@ -427,6 +436,29 @@ int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
>      return vmstate_save_state_v(f, vmsd, opaque, vmdesc_id, vmsd->version_id, errp);
>  }
>  
> +int vmstate_save_field(QEMUFile *f, void *pv, size_t size,
> +                       const VMStateField *field, JSONWriter *vmdesc, Error **errp)
> +{
> +    int ret = 0;
> +
> +    if (field->flags & VMS_STRUCT) {
> +        ret = vmstate_save_state(f, field->vmsd, pv, vmdesc, errp);
> +    } else if (field->flags & VMS_VSTRUCT) {
> +        ret = vmstate_save_state_v(f, field->vmsd, pv, vmdesc,
> +                                   field->struct_version_id, errp);
> +    } else {
> +        ret = field->info->put(f, pv, size, field, vmdesc);
> +        if (ret < 0) {
> +            error_setg(errp,
> +                       "Failed to save element of type %s for %s: "
> +                       "%d", field->info->name,
> +                       field->name, ret);
> +        }
> +    }
> +
> +    return ret;
> +}
> +
>  int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
>                           void *opaque, JSONWriter *vmdesc, int version_id, Error **errp)
>  {
> @@ -528,19 +560,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
>                  vmsd_desc_field_start(vmsd, vmdesc_loop, inner_field,
>                                        i, max_elems);
>  
> -                if (inner_field->flags & VMS_STRUCT) {
> -                    ret = vmstate_save_state(f, inner_field->vmsd,
> -                                             curr_elem, vmdesc_loop, errp);
> -                } else if (inner_field->flags & VMS_VSTRUCT) {
> -                    ret = vmstate_save_state_v(f, inner_field->vmsd,
> -                                               curr_elem, vmdesc_loop,
> -                                               inner_field->struct_version_id,
> -                                               errp);
> -                } else {
> -                    ret = inner_field->info->put(f, curr_elem, size,
> -                                                 inner_field, vmdesc_loop);
> -                }
> -
> +                ret = vmstate_save_field(f, curr_elem, size, inner_field, vmdesc_loop, errp);
>                  written_bytes = qemu_file_transferred(f) - old_offset;
>                  vmsd_desc_field_end(vmsd, vmdesc_loop, inner_field,
>                                      written_bytes);
> @@ -551,7 +571,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
>                  }
>  
>                  if (ret) {
> -                    error_setg(errp, "Save of field %s/%s failed",
> +                    error_prepend(errp, "Save of field %s/%s failed: ",
>                                  vmsd->name, field->name);
>                      if (vmsd->post_save) {
>                          vmsd->post_save(opaque);
> -- 
> 2.47.3
> 

-- 
Peter Xu



  reply	other threads:[~2026-03-13 16:28 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-13 14:12 [PATCH v4 0/8] hw/nvme: add basic live migration support Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 1/8] migration/vmstate: introduce vmstate_{load, save}_field helpers Alexander Mikhalitsyn via qemu development
2026-03-13 16:27   ` Peter Xu [this message]
2026-03-16 11:09     ` Alexander Mikhalitsyn via qemu development
2026-03-16 14:57       ` Fabiano Rosas
2026-03-16 15:11         ` Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 2/8] migration: add VMSTATE_VARRAY_OF_POINTER_TO_STRUCT_UINT{8, 32}_ALLOC Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 3/8] tests/unit/test-vmstate: add tests for VMS_ARRAY_OF_POINTER_ALLOW_NULL Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 4/8] tests/functional/migration: add VM launch/configure hooks Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 5/8] hw/nvme: add migration blockers for non-supported cases Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 6/8] hw/nvme: split nvme_init_sq/nvme_init_cq into helpers Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 7/8] hw/nvme: add basic live migration support Alexander Mikhalitsyn
2026-03-13 14:12 ` [PATCH v4 8/8] tests/functional/x86_64: add migration test for NVMe device Alexander Mikhalitsyn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=abQ7CLuJsWRLwoe5@x1.local \
    --to=peterx@redhat.com \
    --cc=aleksandr.mikhalitsyn@futurfusion.io \
    --cc=alexander@mihalicyn.com \
    --cc=fam@euphon.net \
    --cc=farosas@suse.de \
    --cc=foss@defmacro.it \
    --cc=hreitz@redhat.com \
    --cc=its@irrelevant.dk \
    --cc=kbusch@kernel.org \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=stgraber@stgraber.org \
    --cc=zhao1.liu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.