Commit 8fa129b5d8 for qemu.org

commit 8fa129b5d865a69b340628e5fb8ca67fde391b4b
Author: Mark Cave-Ayland <mark.caveayland@nutanix.com>
Date:   Mon Sep 21 12:35:10 2026 +0100

    qom/object.c: introduce object_property_set_alias() function

    This will be used to set the class alias property for a specific object. Note
    that this function is only required for class properties, and will assert at
    runtime if an attempt is made to use it on an object alias property.

    Update the existing property_release_alias() function to reflect the documented
    refcount behaviour.

    Signed-off-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
    Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
    Message-ID: <20260921113559.1299740-5-mark.caveayland@nutanix.com>

diff --git a/include/qom/object.h b/include/qom/object.h
index 73d72619b8..4c0645817a 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -2324,6 +2324,23 @@ object_class_property_add_alias(ObjectClass *klass, const char *name,
                                 const char *target_type,
                                 const char *target_name);

+/**
+ * object_property_set_alias:
+ * @obj: the object upon which to set the alias property
+ * @name: the name of the alias property
+ * @target_obj: the object to forward property access to
+ *
+ * Set an alias property on an object to point to @target_obj.  This is only
+ * required for class properties, and will assert at runtime if used on an
+ * object property.
+ *
+ * This function ensures that @target_obj stays alive as long as @obj exists
+ * by taking a reference if @target_obj is not a child object or an alias on
+ * the same object.
+ */
+void object_property_set_alias(Object *obj, const char *name,
+                               Object *target_obj);
+
 /**
  * object_property_add_const_link:
  * @obj: the object to add a property to
diff --git a/qom/object.c b/qom/object.c
index e4e8dc6886..96498f3d00 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -3126,6 +3126,18 @@ static void property_release_alias(Object *obj, const char *name, void *opaque)
     if (!(prop->flags & OBJ_PROP_ALIAS_CLASS)) {
         g_free(prop->target_name);
         g_free(prop);
+    } else {
+        Object **target_obj = object_alias_get_targetp(obj, prop);
+
+        if (*target_obj) {
+            ObjectProperty *target_prop = object_property_find_err(*target_obj,
+                                                           prop->target_name,
+                                                           &error_abort);
+            if (*target_obj != obj &&
+                !object_property_is_child(target_prop)) {
+                    object_unref(*target_obj);
+            }
+        }
     }
 }

@@ -3212,6 +3224,35 @@ object_class_property_add_alias(ObjectClass *klass, const char *name,
     return op;
 }

+void object_property_set_alias(Object *obj, const char *name,
+                               Object *target_obj)
+{
+    AliasProperty *prop;
+    ObjectProperty *op, *target_prop;
+    Object **target_objp;
+
+    op = object_property_find_err(obj, name, &error_abort);
+    prop = op->opaque;
+    assert(prop->flags & OBJ_PROP_ALIAS_CLASS);
+
+    target_objp = object_alias_get_targetp(obj, prop);
+    if (*target_objp) {
+        target_prop = object_property_find_err(*target_objp, prop->target_name,
+                                               &error_abort);
+        if (*target_objp != obj && !object_property_is_child(target_prop)) {
+            object_unref(*target_objp);
+        }
+    }
+    *target_objp = target_obj;
+    if (*target_objp) {
+        target_prop = object_property_find_err(*target_objp, prop->target_name,
+                                               &error_abort);
+        if (*target_objp != obj && !object_property_is_child(target_prop)) {
+            object_ref(*target_objp);
+        }
+    }
+}
+
 void object_property_set_description(Object *obj, const char *name,
                                      const char *description)
 {