qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/1] qom: fix setting of array properties


From: Daniel P . Berrangé
Subject: [PATCH 1/1] qom: fix setting of array properties
Date: Mon, 4 Sep 2023 17:25:44 +0100

DEFINE_PROP_ARRAY() creates a property 'len-$ARRAY-PROP-NAME'
which, when set, will create a sequence of '$ARRAY-PROP-NAME[N]'
properties.

This only works if the 'len-$ARRAY-PROP-NAME' property is
set first, and the array elements afterwards. Historically
this required the user to set correct ordering and QemuOpts
traversal would preserve that ordering. With QemuOpts now
converted to QDict, iteration ordering is undefined. Thus
to keep array properties working, we iterate over the QDict
twice.

Doing this in QOM is a bit of a layering violation since
DEFINE_PROP_ARRAY is part of QDev, but it is the simplest
option to preserve backwards compatibility, without ripple
effects across any other part of QEMU.

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1090
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 qom/object_interfaces.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 7d31589b04..6aaaf42ffc 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -51,7 +51,37 @@ static void object_set_properties_from_qdict(Object *obj, 
const QDict *qdict,
     if (!visit_start_struct(v, NULL, NULL, 0, errp)) {
         return;
     }
+
+    /* Layering violation here...
+     *
+     * DEFINE_PROP_ARRAY() creates a property 'len-$ARRAY-PROP-NAME'
+     * which, when set, will create a sequence of '$ARRAY-PROP-NAME[N]'
+     * properties.
+     *
+     * This only works if the 'len-$ARRAY-PROP-NAME' property is
+     * set first, and the array elements afterwards. Historically
+     * this required the user to get correct ordering and QemuOpts
+     * traversal would preserve that ordering. With QemuOpts now
+     * converted to QDict, iteration ordering is undefined. Thus
+     * to keep array properties working, we iterate over the QDict
+     * twice.
+     */
+
+    /* First the props that control array property length */
     for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+        if (!g_str_has_prefix(e->key, "len-")) {
+            continue;
+        }
+        if (!object_property_set(obj, e->key, v, errp)) {
+            goto out;
+        }
+    }
+
+    /* Then any other normal properties */
+    for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+        if (g_str_has_prefix(e->key, "len-")) {
+            continue;
+        }
         if (!object_property_set(obj, e->key, v, errp)) {
             goto out;
         }
-- 
2.41.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]