diff mbox

[1/2] save registration order of machine types

Message ID 1411385195-13495-2-git-send-email-lersek@redhat.com
State New
Headers show

Commit Message

Laszlo Ersek Sept. 22, 2014, 11:26 a.m. UTC
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(+)
diff mbox

Patch

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);