Hi On Tue, Mar 10, 2026 at 6:27 PM Fiona Ebner <[email protected]> wrote: > > In QEMU 10.1, commit 5d56bff11e ("ui/vdagent: add migration support") > added migration support for the vdagent chardev and commit 42000e0013 > ("ui/vdagent: remove migration blocker") removed the migration > blocker. No compat for older machine versions was added, so migration > with pre-10.1 machine version, from a 10.1 binary to a pre-10.1 binary > will result in a failure when loading the VM state in the target > instance: > > > Unknown savevm section or instance 'vdagent' 0. Make sure that your > > current VM setup matches your saved VM setup, including any > > hotplugged devices > > Add a compat flag to block migration when the machine version is less > than 10.1 to avoid this. > > Cc: [email protected] > Fixes: 42000e0013 ("ui/vdagent: remove migration blocker") > Signed-off-by: Fiona Ebner <[email protected]>
Ah yes, I didn't think about that case! Reviewed-by: Marc-André Lureau <[email protected]> > --- > > Changes in v2: > * rebase on current master, adapting to commit 8c84f31ace > ("chardev: .chr_open(): add boolean return value") > > hw/core/machine.c | 1 + > ui/vdagent.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+) > > diff --git a/hw/core/machine.c b/hw/core/machine.c > index a14ad05b9a..6cf0e2f404 100644 > --- a/hw/core/machine.c > +++ b/hw/core/machine.c > @@ -57,6 +57,7 @@ GlobalProperty hw_compat_10_0[] = { > { "vfio-pci", "x-migration-load-config-after-iter", "off" }, > { "ramfb", "use-legacy-x86-rom", "true"}, > { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" }, > + { "chardev-qemu-vdagent", "x-migration-blocked", "true" }, > }; > const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0); > > diff --git a/ui/vdagent.c b/ui/vdagent.c > index 5a5e4bf681..bb0c4aa14c 100644 > --- a/ui/vdagent.c > +++ b/ui/vdagent.c > @@ -6,6 +6,8 @@ > #include "qemu/option.h" > #include "qemu/units.h" > #include "hw/core/qdev.h" > +#include "hw/core/qdev-properties.h" > +#include "migration/blocker.h" > #include "ui/clipboard.h" > #include "ui/console.h" > #include "ui/input.h" > @@ -24,6 +26,10 @@ > struct VDAgentChardev { > Chardev parent; > > + /* needed for machine versions < 10.1 when migration was not supported */ > + Error *migration_blocker; > + bool migration_blocked; > + > /* config */ > bool mouse; > bool clipboard; > @@ -657,6 +663,12 @@ static bool vdagent_chr_open(Chardev *chr, > ChardevBackend *backend, > return false; > #endif > > + if (vd->migration_blocked) { > + if (migrate_add_blocker(&vd->migration_blocker, errp) != 0) { > + return false; > + } > + } > + > vd->mouse = VDAGENT_MOUSE_DEFAULT; > if (cfg->has_mouse) { > vd->mouse = cfg->mouse; > @@ -901,6 +913,19 @@ static void vdagent_chr_parse(QemuOpts *opts, > ChardevBackend *backend, > > /* ------------------------------------------------------------------ */ > > +static bool get_migration_blocked(Object *o, Error **errp) > +{ > + VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(o); > + return vd->migration_blocked; > +} > + > +static void set_migration_blocked(Object *o, bool migration_blocked, > + Error **errp) > +{ > + VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(o); > + vd->migration_blocked = migration_blocked; > +} > + > static void vdagent_chr_class_init(ObjectClass *oc, const void *data) > { > ChardevClass *cc = CHARDEV_CLASS(oc); > @@ -910,6 +935,10 @@ static void vdagent_chr_class_init(ObjectClass *oc, > const void *data) > cc->chr_write = vdagent_chr_write; > cc->chr_set_fe_open = vdagent_chr_set_fe_open; > cc->chr_accept_input = vdagent_chr_accept_input; > + > + object_class_property_add_bool(oc, "x-migration-blocked", > + get_migration_blocked, > + set_migration_blocked); > } > > static int post_load(void *opaque, int version_id) > @@ -1064,10 +1093,26 @@ static void vdagent_chr_instance_init(Object *obj) > vmstate_register_any(NULL, &vmstate_vdagent, vd); > } > > +static void vdagent_post_init(Object *obj) > +{ > + VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(obj); > + > + object_apply_compat_props(obj); > + > + if (vd->migration_blocked) { > + error_setg(&vd->migration_blocker, > + "The vdagent chardev doesn't support migration with > machine" > + " version less than 10.1"); > + } > +} > + > static void vdagent_chr_fini(Object *obj) > { > VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(obj); > > + if (vd->migration_blocked) { > + migrate_del_blocker(&vd->migration_blocker); > + } > vdagent_disconnect(vd); > if (vd->mouse_hs) { > qemu_input_handler_unregister(vd->mouse_hs); > @@ -1080,6 +1125,7 @@ static const TypeInfo vdagent_chr_type_info = { > .parent = TYPE_CHARDEV, > .instance_size = sizeof(VDAgentChardev), > .instance_init = vdagent_chr_instance_init, > + .instance_post_init = vdagent_post_init, > .instance_finalize = vdagent_chr_fini, > .class_init = vdagent_chr_class_init, > }; > -- > 2.47.3 > > > -- Marc-André Lureau
