@@ -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;
};
/**
@@ -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);
@@ -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);
}
@@ -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);
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 <lersek@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(+)