QEMU provides machine compat properties so that old machine types can
define device properties, which will be compatible with old QEMU binaris.

This is the core of how QEMU manages VM ABI across migrations between
different versions of QEMUs.

It used to almost only work for qdev, which was almost enough.  There were
already outliers showed up:

  - do_configure_accelerator()
  - host_memory_backend_post_init()
  - sev_guest_instance_init()

They all invoke object_apply_compat_props() explicitly, because they want
to benefit from the machine compat properties too, just like normal qdevs.
However they're not qdev, hence they need explicit code to support it.

MigrationState object is another example that wants to use similar feature
of qdev.  That was previously done by making TYPE_MIGRATION inherit
TYPE_DEVICE.  See comments for migration_type.  That's working but weird,
e.g. people may question what "-device migration" means..

Nowadays, there're more demands of that, e.g., what if we want to allow
compat properties to be applied to device backends ([1,2])?

Maybe it's time to think about extending the compat properties to a root
class so that more objects can inherit.

This patch introduces object-compat, which is almost object except that it
also allows apply machine compat properties on top.  Then any object that
is not qdev but wants to benefit from machine compat properties can opt-in.

[1] https://lore.kernel.org/r/[email protected]
[2] 
https://lore.kernel.org/r/[email protected]

Signed-off-by: Peter Xu <[email protected]>
---
 include/qom/object.h |  1 +
 qom/object.c         | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 26df6137b9..e5b3116ad5 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -26,6 +26,7 @@ typedef struct InterfaceClass InterfaceClass;
 typedef struct InterfaceInfo InterfaceInfo;
 
 #define TYPE_OBJECT "object"
+#define TYPE_OBJECT_COMPAT "object-compat"
 #define TYPE_CONTAINER "container"
 
 typedef struct ObjectProperty ObjectProperty;
diff --git a/qom/object.c b/qom/object.c
index 4f32c1aba7..581c041b08 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -2893,6 +2893,11 @@ void object_class_property_set_description(ObjectClass 
*klass,
     op->description = g_strdup(description);
 }
 
+static void object_compat_post_init(Object *obj)
+{
+    object_apply_compat_props(obj);
+}
+
 static void object_class_init(ObjectClass *klass, const void *data)
 {
     object_class_property_add_str(klass, "type", object_get_type,
@@ -2914,8 +2919,17 @@ static void register_types(void)
         .abstract = true,
     };
 
+    static const TypeInfo object_compat_info = {
+        .parent = TYPE_OBJECT,
+        .name = TYPE_OBJECT_COMPAT,
+        .instance_size = sizeof(Object),
+        .instance_post_init = object_compat_post_init,
+        .abstract = true,
+    };
+
     type_interface = type_register_internal(&interface_info);
     type_register_internal(&object_info);
+    type_register_internal(&object_compat_info);
 }
 
 type_init(register_types)
-- 
2.50.1


Reply via email to