With every board-created device, memory region, IRQ, and singleton
now given an explicit QOM parent, the /machine/unattached container
serves no legitimate purpose. Remove it and turn the
device_set_realized() fallback into a hard error, so that any
future orphan is caught at realize time rather than silently
adopted into an anonymous bucket.
hw/core/qdev.c error out on !obj->parent instead of adopting
hw/core/qdev-user.c drop the fake unattached container
system/vl.c drop "unattached" from machine container list
hw/i386/pc.c search /machine recursively for the FDC instead
of the (unattached, peripheral, peripheral-anon)
container triple
tests/unit/ parent test devices explicitly under /machine
After this commit, `info qom-tree` no longer shows
/machine/unattached on any target/machine combination, and
`git grep '"unattached"'` returns zero hits.
Assisted-by: Kiro
Signed-off-by: Alexander Graf <[email protected]>
---
hw/core/qdev-user.c | 6 +-----
hw/core/qdev.c | 20 ++++----------------
hw/i386/pc.c | 11 +----------
include/hw/core/qdev.h | 2 +-
system/vl.c | 1 -
tests/unit/test-qdev-global-props.c | 17 +++++++----------
tests/unit/test-qdev.c | 12 ++++--------
7 files changed, 18 insertions(+), 51 deletions(-)
diff --git a/hw/core/qdev-user.c b/hw/core/qdev-user.c
index 051f8fbd02..592a8369a3 100644
--- a/hw/core/qdev-user.c
+++ b/hw/core/qdev-user.c
@@ -11,9 +11,5 @@
void qdev_create_fake_machine(void)
{
- Object *fake_machine_obj;
-
- fake_machine_obj = object_property_add_new_container(object_get_root(),
- "machine");
- object_property_add_new_container(fake_machine_obj, "unattached");
+ object_property_add_new_container(object_get_root(), "machine");
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 44a44862fd..7d7d08733d 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -485,8 +485,6 @@ static void device_set_realized(Object *obj, bool value,
Error **errp)
BusState *bus;
NamedClockList *ncl;
Error *local_err = NULL;
- bool unattached_parent = false;
- static int unattached_count;
if (dev->hotplugged && !dc->hotpluggable) {
error_setg(errp, "Device '%s' does not support hotplugging",
@@ -500,12 +498,10 @@ static void device_set_realized(Object *obj, bool value,
Error **errp)
}
if (!obj->parent) {
- gchar *name = g_strdup_printf("device[%d]", unattached_count++);
-
- object_property_add_child(machine_get_container("unattached"),
- name, obj);
- unattached_parent = true;
- g_free(name);
+ error_setg(errp, "device type '%s' has no QOM parent; "
+ "use qdev_new() with a parent",
+ object_get_typename(obj));
+ return;
}
hotplug_ctrl = qdev_get_hotplug_handler(dev);
@@ -633,14 +629,6 @@ post_realize_fail:
fail:
error_propagate(errp, local_err);
- if (unattached_parent) {
- /*
- * Beware, this doesn't just revert
- * object_property_add_child(), it also runs bus_remove()!
- */
- object_unparent(OBJECT(dev));
- unattached_count--;
- }
}
static bool device_get_hotpluggable(Object *obj, Error **errp)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 398371ff6f..bab8ee453f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -368,24 +368,15 @@ static int check_fdc(Object *obj, void *opaque)
return 0;
}
-static const char * const fdc_container_path[] = {
- "unattached", "peripheral", "peripheral-anon"
-};
-
/*
* Locate the FDC at IO address 0x3f0, in order to configure the CMOS registers
* and ACPI objects.
*/
static ISADevice *pc_find_fdc0(void)
{
- int i;
- Object *container;
CheckFdcState state = { 0 };
- for (i = 0; i < ARRAY_SIZE(fdc_container_path); i++) {
- container = machine_get_container(fdc_container_path[i]);
- object_child_foreach(container, check_fdc, &state);
- }
+ object_child_foreach_recursive(qdev_get_machine(), check_fdc, &state);
if (state.multiple) {
warn_report("multiple floppy disk controllers with "
diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index 9220e9e3b1..eded1b715d 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -462,7 +462,7 @@ static inline bool qdev_is_realized(DeviceState *dev)
* initialization.
* @dev must not be plugged into a bus already.
* If @bus, plug @dev into @bus. This takes a reference to @dev.
- * If @dev has no QOM parent, make one up, taking another reference.
+ * @dev must already have a QOM parent (see qdev_new()).
*
* If you created @dev via object_new() directly (holding a floating
* reference), you probably want to use qdev_realize_and_unref() instead.
diff --git a/system/vl.c b/system/vl.c
index b4434839df..e51399d389 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2192,7 +2192,6 @@ static void parse_memory_options(void)
static void qemu_create_machine_containers(Object *machine)
{
static const char *const containers[] = {
- "unattached",
"peripheral",
"peripheral-anon",
};
diff --git a/tests/unit/test-qdev-global-props.c
b/tests/unit/test-qdev-global-props.c
index 8ea362cbb9..a941774b9d 100644
--- a/tests/unit/test-qdev-global-props.c
+++ b/tests/unit/test-qdev-global-props.c
@@ -78,25 +78,22 @@ static const TypeInfo subclass_type = {
* inherit the global states of the parent process) will try to create qdev
* and realize the device.
*
- * Realization of such anonymous qdev (with no parent object) requires both
- * the machine object and its "unattached" container to be at least present.
+ * Realization requires that the device already has a QOM parent.
*/
static void test_init_machine(void)
{
/* This is a fake machine - it doesn't need to be a machine object */
- Object *machine = object_property_add_new_container(
+ object_property_add_new_container(
object_get_root(), "machine");
- /* This container must exist for anonymous qdevs to realize() */
- object_property_add_new_container(machine, "unattached");
-}
+ }
/* Test simple static property setting to default value */
static void test_static_prop_subprocess(void)
{
MyType *mt;
- mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+ mt = STATIC_TYPE(object_new_child(qdev_get_machine(), "dev[*]",
TYPE_STATIC_PROPS));
qdev_realize(DEVICE(mt), NULL, &error_fatal);
g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
@@ -131,7 +128,7 @@ static void test_static_globalprop_subprocess(void)
register_global_properties(props);
- mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+ mt = STATIC_TYPE(object_new_child(qdev_get_machine(), "dev[*]",
TYPE_STATIC_PROPS));
qdev_realize(DEVICE(mt), NULL, &error_fatal);
g_assert_cmpuint(mt->prop1, ==, 200);
@@ -249,7 +246,7 @@ static void test_dynamic_globalprop_subprocess(void)
register_global_properties(props);
- mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
+ mt = DYNAMIC_TYPE(object_new_child(qdev_get_machine(), "dev[*]",
TYPE_DYNAMIC_PROPS));
qdev_realize(DEVICE(mt), NULL, &error_fatal);
g_assert_cmpuint(mt->prop1, ==, 101);
@@ -295,7 +292,7 @@ static void test_subclass_global_props(void)
register_global_properties(props);
- mt = STATIC_TYPE(object_new(TYPE_SUBCLASS));
+ mt = STATIC_TYPE(object_new_child(qdev_get_machine(), "dev[*]",
TYPE_SUBCLASS));
qdev_realize(DEVICE(mt), NULL, &error_fatal);
g_assert_cmpuint(mt->prop1, ==, 102);
diff --git a/tests/unit/test-qdev.c b/tests/unit/test-qdev.c
index 20eae38e03..eafffb7175 100644
--- a/tests/unit/test-qdev.c
+++ b/tests/unit/test-qdev.c
@@ -44,24 +44,21 @@ static const TypeInfo my_dev_type_info = {
/*
* Initialize a fake machine, being prepared for future tests.
*
- * Realization of anonymous qdev (with no parent object) requires both
- * the machine object and its "unattached" container to be at least present.
+ * Realization requires that the device already has a QOM parent.
*/
static void test_init_machine(void)
{
/* This is a fake machine - it doesn't need to be a machine object */
- Object *machine = object_property_add_new_container(
+ object_property_add_new_container(
object_get_root(), "machine");
- /* This container must exist for anonymous qdevs to realize() */
- object_property_add_new_container(machine, "unattached");
-}
+ }
static void test_qdev_free_properties(void)
{
MyDev *mt;
- mt = STATIC_TYPE(object_new(TYPE_MY_DEV));
+ mt = STATIC_TYPE(object_new_child(qdev_get_machine(), "dev[*]",
TYPE_MY_DEV));
object_set_props(OBJECT(mt), &error_fatal,
"string", "something",
"array-u32", "12,13",
@@ -75,7 +72,6 @@ static void test_qdev_free_properties(void)
g_assert_cmpuint(mt->prop_array_u32[1], ==, 13);
object_unparent(OBJECT(mt));
- object_unref(mt);
}
--
2.47.1