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

Re: [PULL 36/40] vl: switch -M parsing to keyval



On Tue, Jul 6, 2021 at 6:43 AM Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote:
>
> Switch from QemuOpts to keyval.  This enables the introduction
> of non-scalar machine properties, and JSON syntax in the future.
>
> For JSON syntax to be supported right now, we would have to
> consider what would happen if string-based dictionaries (produced by
> -M key=val) were to be merged with strongly-typed dictionaries
> (produced by -M {'key': 123}).
>
> The simplest way out is to never enter the situation, and only allow one
> -M option when JSON syntax is in use.  However, we want options such as
> -smp to become syntactic sugar for -M, and this is a problem; as soon
> as -smp becomes a shortcut for -M, QEMU would forbid using -M '{....}'
> together with -smp.  Therefore, allowing JSON syntax right now for -M
> would be a forward-compatibility nightmare and it would be impossible
> anyway to introduce -M incrementally in tools.
>
> Instead, support for JSON syntax is delayed until after the main
> options are converted to QOM compound properties.  These include -boot,
> -acpitable, -smbios, -m, -semihosting-config, -rtc and -fw_cfg.  Once JSON
> syntax is introduced, these options will _also_ be forbidden together
> with -M '{...}'.
>
> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
> ---
>  softmmu/vl.c | 315 ++++++++++++++++++++++++---------------------------
>  1 file changed, 146 insertions(+), 169 deletions(-)

Xen's osstest bisector found this commit breaks starting a Xen vm:
https://lore.kernel.org/xen-devel/E1m1HlC-0005Ra-Ff@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/

qemu fails to start with:
Unexpected error in object_property_find_err() at
../qemu-xen-dir-remote/qom/object.c:1299:
qemu-system-i386: Property 'xenfv-3.1-machine.accel' not found

The Xen machines have `default_machine_opts =
"accel=xen,suppress-vmdesc=on"` which may be the problem?

Regards,
Jason


> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 7dd2d72d0b..f848abd31a 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -145,6 +145,8 @@ static const char *cpu_option;
>  static const char *mem_path;
>  static const char *incoming;
>  static const char *loadvm;
> +static const char *accelerators;
> +static QDict *machine_opts_dict;
>  static QTAILQ_HEAD(, ObjectOption) object_opts = 
> QTAILQ_HEAD_INITIALIZER(object_opts);
>  static ram_addr_t maxram_size;
>  static uint64_t ram_slots;
> @@ -235,21 +237,6 @@ static QemuOptsList qemu_option_rom_opts = {
>      },
>  };
>
> -static QemuOptsList qemu_machine_opts = {
> -    .name = "machine",
> -    .implied_opt_name = "type",
> -    .merge_lists = true,
> -    .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
> -    .desc = {
> -        /*
> -         * no elements => accept any
> -         * sanity checking will happen later
> -         * when setting machine properties
> -         */
> -        { }
> -    },
> -};
> -
>  static QemuOptsList qemu_accel_opts = {
>      .name = "accel",
>      .implied_opt_name = "accel",
> @@ -498,16 +485,6 @@ static QemuOptsList qemu_action_opts = {
>      },
>  };
>
> -/**
> - * Get machine options
> - *
> - * Returns: machine options (never null).
> - */
> -static QemuOpts *qemu_get_machine_opts(void)
> -{
> -    return qemu_find_opts_singleton("machine");
> -}
> -
>  const char *qemu_get_vm_name(void)
>  {
>      return qemu_name;
> @@ -815,33 +792,6 @@ static MachineClass *find_default_machine(GSList 
> *machines)
>      return default_machineclass;
>  }
>
> -static int machine_help_func(QemuOpts *opts, MachineState *machine)
> -{
> -    ObjectProperty *prop;
> -    ObjectPropertyIterator iter;
> -
> -    if (!qemu_opt_has_help_opt(opts)) {
> -        return 0;
> -    }
> -
> -    object_property_iter_init(&iter, OBJECT(machine));
> -    while ((prop = object_property_iter_next(&iter))) {
> -        if (!prop->set) {
> -            continue;
> -        }
> -
> -        printf("%s.%s=%s", MACHINE_GET_CLASS(machine)->name,
> -               prop->name, prop->type);
> -        if (prop->description) {
> -            printf(" (%s)\n", prop->description);
> -        } else {
> -            printf("\n");
> -        }
> -    }
> -
> -    return 1;
> -}
> -
>  static void version(void)
>  {
>      printf("QEMU emulator version " QEMU_FULL_VERSION "\n"
> @@ -1554,33 +1504,31 @@ static gint machine_class_cmp(gconstpointer a, 
> gconstpointer b)
>                    object_class_get_name(OBJECT_CLASS(mc1)));
>  }
>
> -static MachineClass *machine_parse(const char *name, GSList *machines)
> +static void machine_help_func(const QDict *qdict)
>  {
> -    MachineClass *mc;
> -    GSList *el;
> +    GSList *machines, *el;
> +    const char *type = qdict_get_try_str(qdict, "type");
>
> -    if (is_help_option(name)) {
> -        printf("Supported machines are:\n");
> -        machines = g_slist_sort(machines, machine_class_cmp);
> -        for (el = machines; el; el = el->next) {
> -            MachineClass *mc = el->data;
> -            if (mc->alias) {
> -                printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, 
> mc->name);
> -            }
> -            printf("%-20s %s%s%s\n", mc->name, mc->desc,
> -                   mc->is_default ? " (default)" : "",
> -                   mc->deprecation_reason ? " (deprecated)" : "");
> +    machines = object_class_get_list(TYPE_MACHINE, false);
> +    if (type) {
> +        ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, 
> machines));
> +        if (machine_class) {
> +            
> type_print_class_properties(object_class_get_name(machine_class));
> +            return;
>          }
> -        exit(0);
>      }
>
> -    mc = find_machine(name, machines);
> -    if (!mc) {
> -        error_report("unsupported machine type");
> -        error_printf("Use -machine help to list supported machines\n");
> -        exit(1);
> +    printf("Supported machines are:\n");
> +    machines = g_slist_sort(machines, machine_class_cmp);
> +    for (el = machines; el; el = el->next) {
> +        MachineClass *mc = el->data;
> +        if (mc->alias) {
> +            printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, 
> mc->name);
> +        }
> +        printf("%-20s %s%s%s\n", mc->name, mc->desc,
> +               mc->is_default ? " (default)" : "",
> +               mc->deprecation_reason ? " (deprecated)" : "");
>      }
> -    return mc;
>  }
>
>  static const char *pid_file;
> @@ -1633,32 +1581,31 @@ static const QEMUOption *lookup_opt(int argc, char 
> **argv,
>      return popt;
>  }
>
> -static MachineClass *select_machine(void)
> +static MachineClass *select_machine(QDict *qdict, Error **errp)
>  {
> +    const char *optarg = qdict_get_try_str(qdict, "type");
>      GSList *machines = object_class_get_list(TYPE_MACHINE, false);
> -    MachineClass *machine_class = find_default_machine(machines);
> -    const char *optarg;
> -    QemuOpts *opts;
> -    Location loc;
> +    MachineClass *machine_class;
> +    Error *local_err = NULL;
>
> -    loc_push_none(&loc);
> -
> -    opts = qemu_get_machine_opts();
> -    qemu_opts_loc_restore(opts);
> -
> -    optarg = qemu_opt_get(opts, "type");
>      if (optarg) {
> -        machine_class = machine_parse(optarg, machines);
> +        machine_class = find_machine(optarg, machines);
> +        qdict_del(qdict, "type");
> +        if (!machine_class) {
> +            error_setg(&local_err, "unsupported machine type");
> +        }
> +    } else {
> +        machine_class = find_default_machine(machines);
> +        if (!machine_class) {
> +            error_setg(&local_err, "No machine specified, and there is no 
> default");
> +        }
>      }
>
> -    if (!machine_class) {
> -        error_report("No machine specified, and there is no default");
> -        error_printf("Use -machine help to list supported machines\n");
> -        exit(1);
> -    }
> -
> -    loc_pop(&loc);
>      g_slist_free(machines);
> +    if (local_err) {
> +        error_append_hint(&local_err, "Use -machine help to list supported 
> machines\n");
> +        error_propagate(errp, local_err);
> +    }
>      return machine_class;
>  }
>
> @@ -1677,42 +1624,70 @@ static int object_parse_property_opt(Object *obj,
>      return 0;
>  }
>
> -static int machine_set_property(void *opaque,
> -                                const char *name, const char *value,
> -                                Error **errp)
> +/* *Non*recursively replace underscores with dashes in QDict keys.  */
> +static void keyval_dashify(QDict *qdict, Error **errp)
>  {
> -    g_autofree char *qom_name = g_strdup(name);
> +    const QDictEntry *ent, *next;
>      char *p;
>
> -    for (p = qom_name; *p; p++) {
> -        if (*p == '_') {
> -            *p = '-';
> +    for (ent = qdict_first(qdict); ent; ent = next) {
> +        g_autofree char *new_key = NULL;
> +
> +        next = qdict_next(qdict, ent);
> +        if (!strchr(ent->key, '_')) {
> +            continue;
>          }
> +        new_key = g_strdup(ent->key);
> +        for (p = new_key; *p; p++) {
> +            if (*p == '_') {
> +                *p = '-';
> +            }
> +        }
> +        if (qdict_haskey(qdict, new_key)) {
> +            error_setg(errp, "Conflict between '%s' and '%s'", ent->key, 
> new_key);
> +            return;
> +        }
> +        qobject_ref(ent->value);
> +        qdict_put_obj(qdict, new_key, ent->value);
> +        qdict_del(qdict, ent->key);
>      }
> +}
> +
> +static void qemu_apply_legacy_machine_options(QDict *qdict)
> +{
> +    const char *value;
> +
> +    keyval_dashify(qdict, &error_fatal);
>
>      /* Legacy options do not correspond to MachineState properties.  */
> -    if (g_str_equal(qom_name, "accel")) {
> -        return 0;
> -    }
> -    if (g_str_equal(qom_name, "igd-passthru")) {
> -        object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value,
> -                                   false);
> -        return 0;
> -    }
> -    if (g_str_equal(qom_name, "kvm-shadow-mem")) {
> -        object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value,
> -                                   false);
> -        return 0;
> -    }
> -    if (g_str_equal(qom_name, "kernel-irqchip")) {
> -        object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value,
> -                                   false);
> -        object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), qom_name, value,
> -                                   false);
> -        return 0;
> +    value = qdict_get_try_str(qdict, "accel");
> +    if (value) {
> +        accelerators = g_strdup(value);
> +        qdict_del(qdict, "accel");
>      }
>
> -    return object_parse_property_opt(opaque, name, value, "type", errp);
> +    value = qdict_get_try_str(qdict, "igd-passthru");
> +    if (value) {
> +        object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), "igd-passthru", 
> value,
> +                                   false);
> +        qdict_del(qdict, "igd-passthru");
> +    }
> +
> +    value = qdict_get_try_str(qdict, "kvm-shadow-mem");
> +    if (value) {
> +        object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), 
> "kvm-shadow-mem", value,
> +                                   false);
> +        qdict_del(qdict, "kvm-shadow-mem");
> +    }
> +
> +    value = qdict_get_try_str(qdict, "kernel-irqchip");
> +    if (value) {
> +        object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), 
> "kernel-irqchip", value,
> +                                   false);
> +        object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), 
> "kernel-irqchip", value,
> +                                   false);
> +        qdict_del(qdict, "kernel-irqchip");
> +    }
>  }
>
>  static void object_option_foreach_add(bool (*type_opt_predicate)(const char 
> *))
> @@ -1827,16 +1802,14 @@ static bool object_create_early(const char *type)
>      return true;
>  }
>
> -static void qemu_apply_machine_options(void)
> +static void qemu_apply_machine_options(QDict *qdict)
>  {
>      MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
> -    QemuOpts *machine_opts = qemu_get_machine_opts();
>      const char *boot_order = NULL;
>      const char *boot_once = NULL;
>      QemuOpts *opts;
>
> -    qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
> -                     &error_fatal);
> +    object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, 
> &error_fatal);
>      current_machine->ram_size = ram_size;
>      current_machine->maxram_size = maxram_size;
>      current_machine->ram_slots = ram_slots;
> @@ -1865,10 +1838,8 @@ static void qemu_apply_machine_options(void)
>      current_machine->boot_once = boot_once;
>
>      if (semihosting_enabled() && !semihosting_get_argc()) {
> -        const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
> -        const char *kernel_cmdline = qemu_opt_get(machine_opts, "append") ?: 
> "";
>          /* fall back to the -kernel/-append */
> -        semihosting_arg_fallback(kernel_filename, kernel_cmdline);
> +        semihosting_arg_fallback(current_machine->kernel_filename, 
> current_machine->kernel_cmdline);
>      }
>  }
>
> @@ -1924,8 +1895,7 @@ static void qemu_create_early_backends(void)
>
>      /*
>       * Note: we need to create audio and block backends before
> -     * machine_set_property(), so machine properties can refer to
> -     * them.
> +     * setting machine properties, so they can be referred to.
>       */
>      configure_blockdev(&bdo_queue, machine_class, snapshot);
>      audio_init_audiodevs();
> @@ -2091,16 +2061,14 @@ static void set_memory_options(MachineClass *mc)
>      loc_pop(&loc);
>  }
>
> -static void qemu_create_machine(MachineClass *machine_class)
> +static void qemu_create_machine(QDict *qdict)
>  {
> +    MachineClass *machine_class = select_machine(qdict, &error_fatal);
>      object_set_machine_compat_props(machine_class->compat_props);
>
>      set_memory_options(machine_class);
>
>      current_machine = 
> MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
> -    if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
> -        exit(0);
> -    }
>      object_property_add_child(object_get_root(), "machine",
>                                OBJECT(current_machine));
>      object_property_add_child(container_get(OBJECT(current_machine),
> @@ -2131,8 +2099,12 @@ static void qemu_create_machine(MachineClass 
> *machine_class)
>       * specified either by the configuration file or by the command line.
>       */
>      if (machine_class->default_machine_opts) {
> -        qemu_opts_set_defaults(qemu_find_opts("machine"),
> -                               machine_class->default_machine_opts, 0);
> +        QDict *default_opts =
> +            keyval_parse(machine_class->default_machine_opts, NULL, NULL,
> +                         &error_abort);
> +        object_set_properties_from_keyval(OBJECT(current_machine), 
> default_opts,
> +                                          false, &error_abort);
> +        qobject_unref(default_opts);
>      }
>  }
>
> @@ -2154,7 +2126,8 @@ static int global_init_func(void *opaque, QemuOpts 
> *opts, Error **errp)
>   */
>  static bool is_qemuopts_group(const char *group)
>  {
> -    if (g_str_equal(group, "object")) {
> +    if (g_str_equal(group, "object") ||
> +        g_str_equal(group, "machine")) {
>          return false;
>      }
>      return true;
> @@ -2167,6 +2140,13 @@ static void qemu_record_config_group(const char 
> *group, QDict *dict,
>          Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
>          object_option_add_visitor(v);
>          visit_free(v);
> +    } else if (g_str_equal(group, "machine")) {
> +        /*
> +         * Cannot merge string-valued and type-safe dictionaries, so JSON
> +         * is not accepted yet for -M.
> +         */
> +        assert(!from_json);
> +        keyval_merge(machine_opts_dict, dict, errp);
>      } else {
>          abort();
>      }
> @@ -2297,13 +2277,11 @@ static int do_configure_accelerator(void *opaque, 
> QemuOpts *opts, Error **errp)
>
>  static void configure_accelerators(const char *progname)
>  {
> -    const char *accelerators;
>      bool init_failed = false;
>
>      qemu_opts_foreach(qemu_find_opts("icount"),
>                        do_configure_icount, NULL, &error_fatal);
>
> -    accelerators = qemu_opt_get(qemu_get_machine_opts(), "accel");
>      if (QTAILQ_EMPTY(&qemu_accel_opts.head)) {
>          char **accel_list, **tmp;
>
> @@ -2391,12 +2369,11 @@ static void create_default_memdev(MachineState *ms, 
> const char *path)
>                              &error_fatal);
>  }
>
> -static void qemu_validate_options(void)
> +static void qemu_validate_options(const QDict *machine_opts)
>  {
> -    QemuOpts *machine_opts = qemu_get_machine_opts();
> -    const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
> -    const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
> -    const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
> +    const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel");
> +    const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd");
> +    const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append");
>
>      if (kernel_filename == NULL) {
>           if (kernel_cmdline != NULL) {
> @@ -2736,7 +2713,6 @@ void qemu_init(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_trace_opts);
>      qemu_plugin_add_opts();
>      qemu_add_opts(&qemu_option_rom_opts);
> -    qemu_add_opts(&qemu_machine_opts);
>      qemu_add_opts(&qemu_accel_opts);
>      qemu_add_opts(&qemu_mem_opts);
>      qemu_add_opts(&qemu_smp_opts);
> @@ -2777,6 +2753,7 @@ void qemu_init(int argc, char **argv, char **envp)
>          }
>      }
>
> +    machine_opts_dict = qdict_new();
>      if (userconfig) {
>          qemu_read_default_config_file(&error_fatal);
>      }
> @@ -2866,8 +2843,7 @@ void qemu_init(int argc, char **argv, char **envp)
>                  parse_display(optarg);
>                  break;
>              case QEMU_OPTION_nographic:
> -                olist = qemu_find_opts("machine");
> -                qemu_opts_parse_noisily(olist, "graphics=off", false);
> +                qdict_put_str(machine_opts_dict, "graphics", "off");
>                  nographic = true;
>                  dpy.type = DISPLAY_TYPE_NONE;
>                  break;
> @@ -2891,16 +2867,16 @@ void qemu_init(int argc, char **argv, char **envp)
>                  }
>                  break;
>              case QEMU_OPTION_kernel:
> -                qemu_opts_set(qemu_find_opts("machine"), "kernel", optarg, 
> &error_abort);
> +                qdict_put_str(machine_opts_dict, "kernel", optarg);
>                  break;
>              case QEMU_OPTION_initrd:
> -                qemu_opts_set(qemu_find_opts("machine"), "initrd", optarg, 
> &error_abort);
> +                qdict_put_str(machine_opts_dict, "initrd", optarg);
>                  break;
>              case QEMU_OPTION_append:
> -                qemu_opts_set(qemu_find_opts("machine"), "append", optarg, 
> &error_abort);
> +                qdict_put_str(machine_opts_dict, "append", optarg);
>                  break;
>              case QEMU_OPTION_dtb:
> -                qemu_opts_set(qemu_find_opts("machine"), "dtb", optarg, 
> &error_abort);
> +                qdict_put_str(machine_opts_dict, "dtb", optarg);
>                  break;
>              case QEMU_OPTION_cdrom:
>                  drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
> @@ -3010,7 +2986,7 @@ void qemu_init(int argc, char **argv, char **envp)
>                  }
>                  break;
>              case QEMU_OPTION_bios:
> -                qemu_opts_set(qemu_find_opts("machine"), "firmware", optarg, 
> &error_abort);
> +                qdict_put_str(machine_opts_dict, "firmware", optarg);
>                  break;
>              case QEMU_OPTION_singlestep:
>                  singlestep = 1;
> @@ -3281,17 +3257,20 @@ void qemu_init(int argc, char **argv, char **envp)
>                  preconfig_requested = true;
>                  break;
>              case QEMU_OPTION_enable_kvm:
> -                olist = qemu_find_opts("machine");
> -                qemu_opts_parse_noisily(olist, "accel=kvm", false);
> +                qdict_put_str(machine_opts_dict, "accel", "kvm");
>                  break;
>              case QEMU_OPTION_M:
>              case QEMU_OPTION_machine:
> -                olist = qemu_find_opts("machine");
> -                opts = qemu_opts_parse_noisily(olist, optarg, true);
> -                if (!opts) {
> -                    exit(1);
> +                {
> +                    bool help;
> +
> +                    keyval_parse_into(machine_opts_dict, optarg, "type", 
> &help, &error_fatal);
> +                    if (help) {
> +                        machine_help_func(machine_opts_dict);
> +                        exit(EXIT_SUCCESS);
> +                    }
> +                    break;
>                  }
> -                break;
>              case QEMU_OPTION_accel:
>                  accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
>                                                       optarg, true);
> @@ -3318,12 +3297,10 @@ void qemu_init(int argc, char **argv, char **envp)
>                  }
>                  break;
>              case QEMU_OPTION_usb:
> -                olist = qemu_find_opts("machine");
> -                qemu_opts_parse_noisily(olist, "usb=on", false);
> +                qdict_put_str(machine_opts_dict, "usb", "on");
>                  break;
>              case QEMU_OPTION_usbdevice:
> -                olist = qemu_find_opts("machine");
> -                qemu_opts_parse_noisily(olist, "usb=on", false);
> +                qdict_put_str(machine_opts_dict, "usb", "on");
>                  add_device_config(DEV_USB, optarg);
>                  break;
>              case QEMU_OPTION_device:
> @@ -3342,12 +3319,10 @@ void qemu_init(int argc, char **argv, char **envp)
>                  vnc_parse(optarg);
>                  break;
>              case QEMU_OPTION_no_acpi:
> -                olist = qemu_find_opts("machine");
> -                qemu_opts_parse_noisily(olist, "acpi=off", false);
> +                qdict_put_str(machine_opts_dict, "acpi", "off");
>                  break;
>              case QEMU_OPTION_no_hpet:
> -                olist = qemu_find_opts("machine");
> -                qemu_opts_parse_noisily(olist, "hpet=off", false);
> +                qdict_put_str(machine_opts_dict, "hpet", "off");
>                  break;
>              case QEMU_OPTION_no_reboot:
>                  olist = qemu_find_opts("action");
> @@ -3600,7 +3575,7 @@ void qemu_init(int argc, char **argv, char **envp)
>       */
>      loc_set_none();
>
> -    qemu_validate_options();
> +    qemu_validate_options(machine_opts_dict);
>      qemu_process_sugar_options();
>
>      /*
> @@ -3633,7 +3608,7 @@ void qemu_init(int argc, char **argv, char **envp)
>
>      configure_rtc(qemu_find_opts_singleton("rtc"));
>
> -    qemu_create_machine(select_machine());
> +    qemu_create_machine(machine_opts_dict);
>
>      suspend_mux_open();
>
> @@ -3641,12 +3616,14 @@ void qemu_init(int argc, char **argv, char **envp)
>      qemu_create_default_devices();
>      qemu_create_early_backends();
>
> -    qemu_apply_machine_options();
> +    qemu_apply_legacy_machine_options(machine_opts_dict);
> +    qemu_apply_machine_options(machine_opts_dict);
> +    qobject_unref(machine_opts_dict);
>      phase_advance(PHASE_MACHINE_CREATED);
>
>      /*
>       * Note: uses machine properties such as kernel-irqchip, must run
> -     * after machine_set_property().
> +     * after qemu_apply_machine_options.
>       */
>      configure_accelerators(argv[0]);
>      phase_advance(PHASE_ACCEL_CREATED);
> --
> 2.31.1
>
>
>



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.