Commit 261747f1 ("vl: Use MachineClass instead of global QEMUMachine list") broke the ordering of the machine types in the user-visible output of
qemu-system-XXXX -M \? This occurred because registration was rebased from a manually maintained linked list to GLib hash tables: qemu_register_machine() type_register() type_register_internal() type_table_add() g_hash_table_insert() and because the listing was rebased accordingly, from the traversal of the list to the traversal of the hash table (rendered as an ad-hoc list): machine_parse() object_class_get_list(TYPE_MACHINE) object_class_foreach() g_hash_table_foreach() The current order is a "random" one, for practical purposes, which is annoying for users. The first idea to restore ordering is to sort the ad-hoc list in machine_parse() by "MachineClass.name". Such a name-based ordering would have to be reverse, so that more recent versioned machine types appear higher on the list than older versioned machine types (eg. with qemu-system-x86_64). However, such a reverse sort wreaks havoc between non-versioned machine types (such as those of qemu-system-aarch64). The behavior prior to commit 261747f1 was that: (1) when a given function called qemu_register_machine() several times in sequence, such as in: machine_init(some_machine_init) some_machine_init() qemu_register_machine(...) qemu_register_machine(...) qemu_register_machine(...) then those registration calls influenced the relative order of those machine types directly, and (2) the ordering between functions passed to machine_init() was unspecified. We can restore this behavior by capturing the serial number of the qemu_register_machine() invocation in the MachineClass that it registers. RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1145042 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- include/hw/boards.h | 2 ++ include/sysemu/sysemu.h | 2 ++ hw/i386/pc.c | 2 ++ vl.c | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/include/hw/boards.h b/include/hw/boards.h index dfb6718..0665ca7 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -41,6 +41,7 @@ struct QEMUMachine { const char *default_boot_order; GlobalProperty *compat_props; const char *hw_version; + unsigned registration_order; }; void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, @@ -102,6 +103,7 @@ struct MachineClass { HotplugHandler *(*get_hotplug_handler)(MachineState *machine, DeviceState *dev); + unsigned registration_order; }; /** diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d8539fd..5958b6b 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -24,6 +24,8 @@ int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" #define UUID_NONE "00000000-0000-0000-0000-000000000000" +extern unsigned machtype_registration_order; + bool runstate_check(RunState state); void runstate_set(RunState new_state); int runstate_is_running(void); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 2c2e9dc..95ccce3 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1537,6 +1537,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data) mc->default_boot_order = qm->default_boot_order; mc->compat_props = qm->compat_props; mc->hw_version = qm->hw_version; + mc->registration_order = qm->registration_order; } void qemu_register_pc_machine(QEMUMachine *m) @@ -1549,6 +1550,7 @@ void qemu_register_pc_machine(QEMUMachine *m) .class_data = (void *)m, }; + m->registration_order = machtype_registration_order++; type_register(&ti); g_free(name); } diff --git a/vl.c b/vl.c index dc792fe..b62d9b2 100644 --- a/vl.c +++ b/vl.c @@ -1596,8 +1596,11 @@ static void machine_class_init(ObjectClass *oc, void *data) mc->default_boot_order = qm->default_boot_order; mc->compat_props = qm->compat_props; mc->hw_version = qm->hw_version; + mc->registration_order = qm->registration_order; } +unsigned machtype_registration_order; + int qemu_register_machine(QEMUMachine *m) { char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL); @@ -1608,6 +1611,7 @@ int qemu_register_machine(QEMUMachine *m) .class_data = (void *)m, }; + m->registration_order = machtype_registration_order++; type_register(&ti); g_free(name); -- 1.8.3.1