[PATCH v2 07/21] qom/object: introduce user interaction flags for properties

Zhao Liu posted 21 patches 14 hours ago
Maintainers: Pierrick Bouvier <pierrick.bouvier@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Eduardo Habkost <eduardo@habkost.net>, "Michael S. Tsirkin" <mst@redhat.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Richard Henderson <richard.henderson@linaro.org>, Zhao Liu <zhao1.liu@intel.com>
[PATCH v2 07/21] qom/object: introduce user interaction flags for properties
Posted by Zhao Liu 14 hours ago
Introduce three new flags to `ObjectPropertyFlags` to better manage
property interactions with external users (CLI, QMP, HMP):

1. OBJ_PROP_FLAG_USER_SET:
   Marks a property as having been modified by an external user.

   This flag is designed to be "sticky": once set, it persists even if
   the property value is subsequently overwritten by internal logic.
   It allows the QEMU system to distinguish user intent.

   The advantage of this design is that it is not needed to manually
   clear the USER_SET flag on every internal write. This simplifies the
   logic and decouples flag management from the current property setting
   path (object_property_set()).

   This is chosen over a strict "current origin" approach (where
   internal writes would clear the flag) for a practical reason: QEMU
   code often modifies underlying struct fields (which are defined as
   properties) directly, bypassing the property API entirely. This makes
   it impossible to "accurately" track whether the *current* value truly
   comes from the user. Therefore, a sticky "user touched this" flag is
   the only meaningful and robust solution.

2. OBJ_PROP_FLAG_DEPRECATED:
   Marks a property as deprecated.

3. OBJ_PROP_FLAG_INTERNAL:
   Marks a property as internal-only, disallowing external user access.

Additionally, update object_property_set_flags() to implement the
enforcement logic. When a property is flagged with
OBJ_PROP_FLAG_USER_SET:
 - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
   warning.
 - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
   and stop the operation.

Suggested-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 24 ++++++++++++++++++++++++
 qom/object.c         | 15 +++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 856b12e7289c..1b77429aa28b 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -109,6 +109,30 @@ typedef enum {
      * will automatically add a getter and a setter to this property.
      */
     OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
+    /*
+     * The property was explicitly set by an external user.
+     *
+     * This flag is set whenever the property is modified via external interfaces
+     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
+     * property has been modified by the user.
+     *
+     * Once set, this flag persists even if the property value is subsequently
+     * overwritten by internal logic. It is NOT automatically cleared and must
+     * be explicitly cleared using object_property_clear_flags().
+     */
+    OBJ_PROP_FLAG_USER_SET = BIT(2),
+    /*
+     * The property is deprecated and will be removed in the future version.
+     *
+     * Any setting to this property by the user will raise a deprecation warning.
+     */
+    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
+    /*
+     * The property is internal only and cannot be set by the user.
+     *
+     * Any setting to this property by the user will raise an error.
+     */
+    OBJ_PROP_FLAG_INTERNAL = BIT(4),
 } ObjectPropertyFlags;
 
 struct ObjectProperty
diff --git a/qom/object.c b/qom/object.c
index 49ef99a299b6..75a1fe7ea1d3 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1242,6 +1242,21 @@ bool object_property_set_flags(Object *obj, const char *name,
         return false;
     }
 
+    if ((flags & OBJ_PROP_FLAG_USER_SET)) {
+        if (prop->flags & OBJ_PROP_FLAG_DEPRECATED) {
+            warn_report("Property '%s.%s' has been deprecated. "
+                        "Please do not use it.",
+                        object_get_typename(obj), name);
+        }
+
+        if (prop->flags & OBJ_PROP_FLAG_INTERNAL) {
+            error_setg(errp, "Property '%s.%s' is internal only. "
+                       "It can't be set by external user",
+                       object_get_typename(obj), name);
+            return false;
+        }
+    }
+
     prop->flags |= flags;
     return true;
 }
-- 
2.34.1
Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
Posted by BALATON Zoltan 3 hours ago
On Tue, 10 Feb 2026, Zhao Liu wrote:
> Introduce three new flags to `ObjectPropertyFlags` to better manage
> property interactions with external users (CLI, QMP, HMP):
>
> 1. OBJ_PROP_FLAG_USER_SET:
>   Marks a property as having been modified by an external user.
>
>   This flag is designed to be "sticky": once set, it persists even if
>   the property value is subsequently overwritten by internal logic.
>   It allows the QEMU system to distinguish user intent.
>
>   The advantage of this design is that it is not needed to manually
>   clear the USER_SET flag on every internal write. This simplifies the
>   logic and decouples flag management from the current property setting
>   path (object_property_set()).
>
>   This is chosen over a strict "current origin" approach (where
>   internal writes would clear the flag) for a practical reason: QEMU
>   code often modifies underlying struct fields (which are defined as
>   properties) directly, bypassing the property API entirely. This makes
>   it impossible to "accurately" track whether the *current* value truly
>   comes from the user. Therefore, a sticky "user touched this" flag is
>   the only meaningful and robust solution.
>
> 2. OBJ_PROP_FLAG_DEPRECATED:
>   Marks a property as deprecated.
>
> 3. OBJ_PROP_FLAG_INTERNAL:
>   Marks a property as internal-only, disallowing external user access.
>
> Additionally, update object_property_set_flags() to implement the
> enforcement logic. When a property is flagged with
> OBJ_PROP_FLAG_USER_SET:
> - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
>   warning.
> - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
>   and stop the operation.
>
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
> include/qom/object.h | 24 ++++++++++++++++++++++++
> qom/object.c         | 15 +++++++++++++++
> 2 files changed, 39 insertions(+)
>
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 856b12e7289c..1b77429aa28b 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -109,6 +109,30 @@ typedef enum {
>      * will automatically add a getter and a setter to this property.
>      */
>     OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> +    /*
> +     * The property was explicitly set by an external user.
> +     *
> +     * This flag is set whenever the property is modified via external interfaces
> +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> +     * property has been modified by the user.
> +     *
> +     * Once set, this flag persists even if the property value is subsequently
> +     * overwritten by internal logic. It is NOT automatically cleared and must
> +     * be explicitly cleared using object_property_clear_flags().
> +     */
> +    OBJ_PROP_FLAG_USER_SET = BIT(2),

As this isn't strictly for user set maybe jusr call it 
OBJ_PROP_FLAG_EXTERNAL? (Can be set by external management application or 
global compat prop in later patches so user set is not quite right name,)
Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
Posted by Daniel P. Berrangé 8 hours ago
On Tue, Feb 10, 2026 at 11:23:34AM +0800, Zhao Liu wrote:
> Introduce three new flags to `ObjectPropertyFlags` to better manage
> property interactions with external users (CLI, QMP, HMP):
> 
> 1. OBJ_PROP_FLAG_USER_SET:
>    Marks a property as having been modified by an external user.
> 
>    This flag is designed to be "sticky": once set, it persists even if
>    the property value is subsequently overwritten by internal logic.
>    It allows the QEMU system to distinguish user intent.
> 
>    The advantage of this design is that it is not needed to manually
>    clear the USER_SET flag on every internal write. This simplifies the
>    logic and decouples flag management from the current property setting
>    path (object_property_set()).
> 
>    This is chosen over a strict "current origin" approach (where
>    internal writes would clear the flag) for a practical reason: QEMU
>    code often modifies underlying struct fields (which are defined as
>    properties) directly, bypassing the property API entirely. This makes
>    it impossible to "accurately" track whether the *current* value truly
>    comes from the user. Therefore, a sticky "user touched this" flag is
>    the only meaningful and robust solution.
> 
> 2. OBJ_PROP_FLAG_DEPRECATED:
>    Marks a property as deprecated.
> 
> 3. OBJ_PROP_FLAG_INTERNAL:
>    Marks a property as internal-only, disallowing external user access.
> 
> Additionally, update object_property_set_flags() to implement the
> enforcement logic. When a property is flagged with
> OBJ_PROP_FLAG_USER_SET:
>  - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
>    warning.
>  - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
>    and stop the operation.
> 
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
>  include/qom/object.h | 24 ++++++++++++++++++++++++
>  qom/object.c         | 15 +++++++++++++++
>  2 files changed, 39 insertions(+)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 856b12e7289c..1b77429aa28b 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -109,6 +109,30 @@ typedef enum {
>       * will automatically add a getter and a setter to this property.
>       */
>      OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> +    /*
> +     * The property was explicitly set by an external user.
> +     *
> +     * This flag is set whenever the property is modified via external interfaces
> +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> +     * property has been modified by the user.
> +     *
> +     * Once set, this flag persists even if the property value is subsequently
> +     * overwritten by internal logic. It is NOT automatically cleared and must
> +     * be explicitly cleared using object_property_clear_flags().
> +     */
> +    OBJ_PROP_FLAG_USER_SET = BIT(2),
> +    /*
> +     * The property is deprecated and will be removed in the future version.
> +     *
> +     * Any setting to this property by the user will raise a deprecation warning.
> +     */
> +    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
> +    /*
> +     * The property is internal only and cannot be set by the user.
> +     *
> +     * Any setting to this property by the user will raise an error.
> +     */
> +    OBJ_PROP_FLAG_INTERNAL = BIT(4),
>  } ObjectPropertyFlags;

I don't think this single enum design is very desirable, as it is mixing up
pieces of information with three distinct lifetimes / scopes.

The OBJ_PROP_FLAD_{READ,WRITE,READWRITE} values are scoped to the execution
of the property adder methods.

The OBJ_PROP_FLAG_{DEPRECATED,INTERNAL} values are scoped to the lifetime
of the class.

The OBJ_PROP_FLAG_USER_SET value is scoped to the lifetime of the instance.

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 :|
Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
Posted by Daniel P. Berrangé 7 hours ago
On Tue, Feb 10, 2026 at 09:49:40AM +0000, Daniel P. Berrangé wrote:
> On Tue, Feb 10, 2026 at 11:23:34AM +0800, Zhao Liu wrote:
> > Introduce three new flags to `ObjectPropertyFlags` to better manage
> > property interactions with external users (CLI, QMP, HMP):
> > 
> > 1. OBJ_PROP_FLAG_USER_SET:
> >    Marks a property as having been modified by an external user.
> > 
> >    This flag is designed to be "sticky": once set, it persists even if
> >    the property value is subsequently overwritten by internal logic.
> >    It allows the QEMU system to distinguish user intent.
> > 
> >    The advantage of this design is that it is not needed to manually
> >    clear the USER_SET flag on every internal write. This simplifies the
> >    logic and decouples flag management from the current property setting
> >    path (object_property_set()).
> > 
> >    This is chosen over a strict "current origin" approach (where
> >    internal writes would clear the flag) for a practical reason: QEMU
> >    code often modifies underlying struct fields (which are defined as
> >    properties) directly, bypassing the property API entirely. This makes
> >    it impossible to "accurately" track whether the *current* value truly
> >    comes from the user. Therefore, a sticky "user touched this" flag is
> >    the only meaningful and robust solution.
> > 
> > 2. OBJ_PROP_FLAG_DEPRECATED:
> >    Marks a property as deprecated.
> > 
> > 3. OBJ_PROP_FLAG_INTERNAL:
> >    Marks a property as internal-only, disallowing external user access.
> > 
> > Additionally, update object_property_set_flags() to implement the
> > enforcement logic. When a property is flagged with
> > OBJ_PROP_FLAG_USER_SET:
> >  - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
> >    warning.
> >  - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
> >    and stop the operation.
> > 
> > Suggested-by: Igor Mammedov <imammedo@redhat.com>
> > Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> > ---
> >  include/qom/object.h | 24 ++++++++++++++++++++++++
> >  qom/object.c         | 15 +++++++++++++++
> >  2 files changed, 39 insertions(+)
> > 
> > diff --git a/include/qom/object.h b/include/qom/object.h
> > index 856b12e7289c..1b77429aa28b 100644
> > --- a/include/qom/object.h
> > +++ b/include/qom/object.h
> > @@ -109,6 +109,30 @@ typedef enum {
> >       * will automatically add a getter and a setter to this property.
> >       */
> >      OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> > +    /*
> > +     * The property was explicitly set by an external user.
> > +     *
> > +     * This flag is set whenever the property is modified via external interfaces
> > +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> > +     * property has been modified by the user.
> > +     *
> > +     * Once set, this flag persists even if the property value is subsequently
> > +     * overwritten by internal logic. It is NOT automatically cleared and must
> > +     * be explicitly cleared using object_property_clear_flags().
> > +     */
> > +    OBJ_PROP_FLAG_USER_SET = BIT(2),
> > +    /*
> > +     * The property is deprecated and will be removed in the future version.
> > +     *
> > +     * Any setting to this property by the user will raise a deprecation warning.
> > +     */
> > +    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
> > +    /*
> > +     * The property is internal only and cannot be set by the user.
> > +     *
> > +     * Any setting to this property by the user will raise an error.
> > +     */
> > +    OBJ_PROP_FLAG_INTERNAL = BIT(4),
> >  } ObjectPropertyFlags;
> 
> I don't think this single enum design is very desirable, as it is mixing up
> pieces of information with three distinct lifetimes / scopes.
> 
> The OBJ_PROP_FLAD_{READ,WRITE,READWRITE} values are scoped to the execution
> of the property adder methods.
> 
> The OBJ_PROP_FLAG_{DEPRECATED,INTERNAL} values are scoped to the lifetime
> of the class.
> 
> The OBJ_PROP_FLAG_USER_SET value is scoped to the lifetime of the instance.

In fact, with my comment on the later patch, OBJ_PROP_FLAG_DEPRECATED should
not be modelled as a boolean flag at all.  We need to record a const char*
deprecation_note internally, so that warn_report can provide useful info
to the user. We can turn that into a "bool deprecated" flag in the QAPI
command response for querying properties.


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 :|