hw/core/machine.c | 1 + ui/vdagent.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+)
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: qemu-stable@nongnu.org
Fixes: 42000e0013 ("ui/vdagent: remove migration blocker")
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
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 6411e68856..9a5241ce17 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -55,6 +55,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 142a3691ac..15ecabb402 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"
@@ -32,6 +34,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;
@@ -677,6 +683,12 @@ static void vdagent_chr_open(Chardev *chr,
return;
#endif
+ if (vd->migration_blocked) {
+ if (migrate_add_blocker(&vd->migration_blocker, errp) != 0) {
+ return;
+ }
+ }
+
vd->mouse = VDAGENT_MOUSE_DEFAULT;
if (cfg->has_mouse) {
vd->mouse = cfg->mouse;
@@ -920,6 +932,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);
@@ -929,6 +954,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)
@@ -1083,10 +1112,26 @@ static void vdagent_chr_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);
@@ -1099,6 +1144,7 @@ static const TypeInfo vdagent_chr_type_info = {
.parent = TYPE_CHARDEV,
.instance_size = sizeof(VDAgentChardev),
.instance_init = vdagent_chr_init,
+ .instance_post_init = vdagent_post_init,
.instance_finalize = vdagent_chr_fini,
.class_init = vdagent_chr_class_init,
};
--
2.47.3
Hi Fiona
On Mon, Jan 12, 2026 at 2:51 PM Fiona Ebner <f.ebner@proxmox.com> 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:
>
>
But you can migrate a pre-10.1 machine with the new binary.
> > 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.
>
>
I am not sure this is the right way to handle this. There is already this
error when migrating to an older qemu, I am not sure we have to block
earlier and prevent the above case.
> Cc: qemu-stable@nongnu.org
> Fixes: 42000e0013 ("ui/vdagent: remove migration blocker")
> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
> ---
> 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 6411e68856..9a5241ce17 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -55,6 +55,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" },
>
Is there a precedent where such compat property was added to block
migration?
> };
> 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 142a3691ac..15ecabb402 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"
> @@ -32,6 +34,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;
> @@ -677,6 +683,12 @@ static void vdagent_chr_open(Chardev *chr,
> return;
> #endif
>
> + if (vd->migration_blocked) {
> + if (migrate_add_blocker(&vd->migration_blocker, errp) != 0) {
> + return;
> + }
> + }
> +
> vd->mouse = VDAGENT_MOUSE_DEFAULT;
> if (cfg->has_mouse) {
> vd->mouse = cfg->mouse;
> @@ -920,6 +932,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);
> @@ -929,6 +954,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)
> @@ -1083,10 +1112,26 @@ static void vdagent_chr_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);
> @@ -1099,6 +1144,7 @@ static const TypeInfo vdagent_chr_type_info = {
> .parent = TYPE_CHARDEV,
> .instance_size = sizeof(VDAgentChardev),
> .instance_init = vdagent_chr_init,
> + .instance_post_init = vdagent_post_init,
> .instance_finalize = vdagent_chr_fini,
> .class_init = vdagent_chr_class_init,
> };
> --
> 2.47.3
>
>
>
Hi Marc-André,
Am 13.01.26 um 8:39 AM schrieb Marc-André Lureau:
> Hi Fiona
>
> On Mon, Jan 12, 2026 at 2:51 PM Fiona Ebner <f.ebner@proxmox.com
> <mailto:f.ebner@proxmox.com>> 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:
>
>
> But you can migrate a pre-10.1 machine with the new binary.
True, but I think it violates what a machine version is supposed to
encapsulate. If a QEMU binary supports a given machine version, it
should be able to load migration streams originating from other, newer
QEMU binaries when the same machine version and commandline is used, or?
>
>
> > 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.
>
>
> I am not sure this is the right way to handle this. There is already
> this error when migrating to an older qemu, I am not sure we have to
> block earlier and prevent the above case.
I would consider this an internal/unexpected error. I feel like it
should not occur if the VM was started with the exact same commandline
on source and target, but currently, it can. It happens at the very end
of migration when the source is already in post-migrate state, which is
not nice for users/management layer.
>
>
>
> Cc: qemu-stable@nongnu.org <mailto:qemu-stable@nongnu.org>
> Fixes: 42000e0013 ("ui/vdagent: remove migration blocker")
> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com
> <mailto:f.ebner@proxmox.com>>
> ---
> 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 6411e68856..9a5241ce17 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -55,6 +55,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" },
>
>
> Is there a precedent where such compat property was added to block
> migration?
There are several ones where migration is turned off for a device or
certain properties, e.g.
{ "ramfb", "x-migrate", "off" } for 8.1
{ "pl011", "migrate-clk", "off" } for 5.1
which is not quite the same, but I'd still argue:
I guess those properties were not migrated, so compatibility means still
not migrating those for older machine version. For the vdagent chardev,
the previous behavior was blocking migration, so compatibility means
still blocking migration for older machine versions. Or does that not
make sense?
Best Regards,
Fiona
On Tue, Jan 13, 2026 at 12:20:12PM +0100, Fiona Ebner wrote:
> Hi Marc-André,
>
> Am 13.01.26 um 8:39 AM schrieb Marc-André Lureau:
> > Hi Fiona
> >
> > On Mon, Jan 12, 2026 at 2:51 PM Fiona Ebner <f.ebner@proxmox.com
> > <mailto:f.ebner@proxmox.com>> 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:
> >
> >
> > But you can migrate a pre-10.1 machine with the new binary.
>
> True, but I think it violates what a machine version is supposed to
> encapsulate. If a QEMU binary supports a given machine version, it
> should be able to load migration streams originating from other, newer
> QEMU binaries when the same machine version and commandline is used, or?
I guess it gets fuzzy because the general concept of machine types
is
"what previously worked must still work in future, given an
identical machine config".
Marc-andre's patch took something which was previously broken, and
made it work, for both new and pre-existing machine types, but only
if both sides used the new QEMU binary. This is somewhat unusual,
but probably not without precedent wrt other places where we have
removed historical blockers.
In this case, the patch is proposing to extend the above concept to
include "what was previously broken must remain broken", wrt pre-
existing machine types.
I have some sympathy for the latter proposal, because the way that
failures loading vmstate present themselves is very user hostile.
At least with migration you'll see the error after migration
completes, which is still "in the moment". If you're using a
save/restore workflow, as you might only discover this config
is not restorable on your desired older QEMU weeks or months
later.
IOW using an old machine type and the user config sometimes be
migratable and sometimes not migratable is poor user experiance
IMHO.
>
> >
> >
> > > 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.
> >
> >
> > I am not sure this is the right way to handle this. There is already
> > this error when migrating to an older qemu, I am not sure we have to
> > block earlier and prevent the above case.
>
> I would consider this an internal/unexpected error. I feel like it
> should not occur if the VM was started with the exact same commandline
> on source and target, but currently, it can. It happens at the very end
> of migration when the source is already in post-migrate state, which is
> not nice for users/management layer.
>
> >
> >
> >
> > Cc: qemu-stable@nongnu.org <mailto:qemu-stable@nongnu.org>
> > Fixes: 42000e0013 ("ui/vdagent: remove migration blocker")
> > Signed-off-by: Fiona Ebner <f.ebner@proxmox.com
> > <mailto:f.ebner@proxmox.com>>
> > ---
> > 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 6411e68856..9a5241ce17 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -55,6 +55,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" },
> >
> >
> > Is there a precedent where such compat property was added to block
> > migration?
>
> There are several ones where migration is turned off for a device or
> certain properties, e.g.
> { "ramfb", "x-migrate", "off" } for 8.1
> { "pl011", "migrate-clk", "off" } for 5.1
> which is not quite the same, but I'd still argue:
>
> I guess those properties were not migrated, so compatibility means still
> not migrating those for older machine version. For the vdagent chardev,
> the previous behavior was blocking migration, so compatibility means
> still blocking migration for older machine versions. Or does that not
> make sense?
>
> Best Regards,
> Fiona
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
Hi
On Tue, Jan 13, 2026 at 3:21 PM Fiona Ebner <f.ebner@proxmox.com> wrote:
>
> Hi Marc-André,
>
> Am 13.01.26 um 8:39 AM schrieb Marc-André Lureau:
> > Hi Fiona
> >
> > On Mon, Jan 12, 2026 at 2:51 PM Fiona Ebner <f.ebner@proxmox.com
> > <mailto:f.ebner@proxmox.com>> 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:
> >
> >
> > But you can migrate a pre-10.1 machine with the new binary.
>
> True, but I think it violates what a machine version is supposed to
> encapsulate. If a QEMU binary supports a given machine version, it
> should be able to load migration streams originating from other, newer
> QEMU binaries when the same machine version and commandline is used, or?
>
> >
> >
> > > 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.
> >
> >
> > I am not sure this is the right way to handle this. There is already
> > this error when migrating to an older qemu, I am not sure we have to
> > block earlier and prevent the above case.
>
> I would consider this an internal/unexpected error. I feel like it
> should not occur if the VM was started with the exact same commandline
> on source and target, but currently, it can. It happens at the very end
> of migration when the source is already in post-migrate state, which is
> not nice for users/management layer.
>
> >
> >
> >
> > Cc: qemu-stable@nongnu.org <mailto:qemu-stable@nongnu.org>
> > Fixes: 42000e0013 ("ui/vdagent: remove migration blocker")
> > Signed-off-by: Fiona Ebner <f.ebner@proxmox.com
> > <mailto:f.ebner@proxmox.com>>
> > ---
> > 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 6411e68856..9a5241ce17 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -55,6 +55,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" },
> >
> >
> > Is there a precedent where such compat property was added to block
> > migration?
>
> There are several ones where migration is turned off for a device or
> certain properties, e.g.
> { "ramfb", "x-migrate", "off" } for 8.1
> { "pl011", "migrate-clk", "off" } for 5.1
> which is not quite the same, but I'd still argue:
>
> I guess those properties were not migrated, so compatibility means still
> not migrating those for older machine version. For the vdagent chardev,
> the previous behavior was blocking migration, so compatibility means
> still blocking migration for older machine versions. Or does that not
> make sense?
Makes sense, I actually wrote that ramfb x-migrate and nobody
complained about that behaviour:
commit a1e88d2d2b89ad6371036aa07f7e96947786c873
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date: Mon Oct 9 10:32:46 2023 +0400
ramfb-standalone: add migration support
Add a "ramfb-dev" section whenever "x-migrate" is turned on. Turn it off
by default on machines <= 8.1 for compatibility reasons.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
So let's take the same approach for qemu-vdagent
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
--
Marc-André Lureau
© 2016 - 2026 Red Hat, Inc.