Pass the group name as argument to qemu_opts_parse_noisily() to make it simmetric with qemu_opts_parse().
This change solves the issue of qemu_opts_parse_noisily() crashing on a NULL return from qemu_find_opts(), which can happen when an option is invoked for code in a module that is not loaded. Signed-off-by: Fabiano Rosas <[email protected]> --- block/monitor/block-hmp-cmds.c | 2 +- blockdev.c | 2 +- chardev/char-hmp-cmds.c | 5 +-- include/qemu/option.h | 2 +- plugins/loader.c | 2 +- qemu-img.c | 3 +- semihosting/config.c | 4 +- system/vl.c | 75 ++++++++++++---------------------- tests/unit/test-char.c | 12 ++---- tests/unit/test-seccomp.c | 6 +-- trace/control.c | 3 +- ui/vnc.c | 3 +- util/qemu-option.c | 14 ++++++- 13 files changed, 54 insertions(+), 79 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index cbd64166ec..d94a07314f 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -101,7 +101,7 @@ void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict) return; } - opts = qemu_opts_parse_noisily(qemu_find_opts("drive"), optstr, false); + opts = qemu_opts_parse_noisily("drive", optstr, false); if (!opts) return; diff --git a/blockdev.c b/blockdev.c index 6e86c6262f..21554500dc 100644 --- a/blockdev.c +++ b/blockdev.c @@ -203,7 +203,7 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file, GLOBAL_STATE_CODE(); - opts = qemu_opts_parse_noisily(qemu_find_opts("drive"), optstr, false); + opts = qemu_opts_parse_noisily("drive", optstr, false); if (!opts) { return NULL; } diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c index fb0560054b..938dbd3ba2 100644 --- a/chardev/char-hmp-cmds.c +++ b/chardev/char-hmp-cmds.c @@ -83,7 +83,7 @@ void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict) Error *err = NULL; QemuOpts *opts; - opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true); + opts = qemu_opts_parse_noisily("chardev", args, true); if (opts == NULL) { error_setg(&err, "Parsing chardev args failed"); } else { @@ -100,8 +100,7 @@ void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict) Error *err = NULL; ChardevBackend *backend = NULL; ChardevReturn *ret = NULL; - QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, - true); + QemuOpts *opts = qemu_opts_parse_noisily("chardev", args, true); if (!opts) { error_setg(&err, "Parsing chardev args failed"); goto end; diff --git a/include/qemu/option.h b/include/qemu/option.h index df68da9aa8..2955ed3b2d 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -128,7 +128,7 @@ void qemu_opts_del(QemuOpts *opts); bool qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp); bool qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname, Error **errp); -QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params, +QemuOpts *qemu_opts_parse_noisily(const char *group, const char *params, bool permit_abbrev); QemuOpts *qemu_opts_parse(const char *group, const char *params, bool permit_abbrev, Error **errp); diff --git a/plugins/loader.c b/plugins/loader.c index b10ebe8cc0..1808679c82 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -147,7 +147,7 @@ void qemu_plugin_opt_parse(const char *optstr, QemuPluginList *head) struct qemu_plugin_parse_arg arg; QemuOpts *opts; - opts = qemu_opts_parse_noisily(qemu_find_opts("plugin"), optstr, true); + opts = qemu_opts_parse_noisily("plugin", optstr, true); if (opts == NULL) { exit(1); } diff --git a/qemu-img.c b/qemu-img.c index 4996618a4e..0459faac5f 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -358,8 +358,7 @@ static BlockBackend *img_open(bool image_opts, error_report("--image-opts and --format are mutually exclusive"); return NULL; } - opts = qemu_opts_parse_noisily(qemu_find_opts("source"), - filename, true); + opts = qemu_opts_parse_noisily("source", filename, true); if (!opts) { return NULL; } diff --git a/semihosting/config.c b/semihosting/config.c index 56283b5c3c..c8c865ebae 100644 --- a/semihosting/config.c +++ b/semihosting/config.c @@ -134,8 +134,8 @@ void qemu_semihosting_enable(void) int qemu_semihosting_config_options(const char *optstr) { - QemuOptsList *opt_list = qemu_find_opts("semihosting-config"); - QemuOpts *opts = qemu_opts_parse_noisily(opt_list, optstr, false); + QemuOpts *opts = qemu_opts_parse_noisily("semihosting-config", optstr, + false); semihosting.enabled = true; diff --git a/system/vl.c b/system/vl.c index adda7b0f70..4a6c3e5582 100644 --- a/system/vl.c +++ b/system/vl.c @@ -1870,8 +1870,7 @@ static void object_option_parse(const char *str) v = qobject_input_visitor_new(obj); qobject_unref(obj); } else { - opts = qemu_opts_parse_noisily(qemu_find_opts("object"), - str, true); + opts = qemu_opts_parse_noisily("object", str, true); if (!opts) { exit(1); } @@ -1897,8 +1896,7 @@ static void overcommit_parse(const char *str) QemuOpts *opts; const char *mem_lock_opt; - opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"), - str, false); + opts = qemu_opts_parse_noisily("overcommit", str, false); if (!opts) { exit(1); } @@ -2475,7 +2473,7 @@ static void configure_accelerators(const char *progname) * such as "-machine accel=tcg,,thread=single". */ if (accel_find(*tmp)) { - qemu_opts_parse_noisily(qemu_find_opts("accel"), *tmp, true); + qemu_opts_parse_noisily("accel", *tmp, true); } else { init_failed = true; error_report("invalid accelerator %s", *tmp); @@ -2975,8 +2973,7 @@ void qemu_init(int argc, char **argv) break; } case QEMU_OPTION_drive: - if (!qemu_opts_parse_noisily(qemu_find_opts("drive"), - optarg, false)) { + if (!qemu_opts_parse_noisily("drive", optarg, false)) { exit(1); } break; @@ -3001,8 +2998,7 @@ void qemu_init(int argc, char **argv) replay_add_blocker("-snapshot"); break; case QEMU_OPTION_numa: - if (!qemu_opts_parse_noisily(qemu_find_opts("numa"), - optarg, true)) { + if (!qemu_opts_parse_noisily("numa", optarg, true)) { exit(1); } break; @@ -3061,8 +3057,7 @@ void qemu_init(int argc, char **argv) break; #ifdef CONFIG_LIBISCSI case QEMU_OPTION_iscsi: - if (!qemu_opts_parse_noisily(qemu_find_opts("iscsi"), - optarg, false)) { + if (!qemu_opts_parse_noisily("iscsi", optarg, false)) { exit(1); } break; @@ -3115,8 +3110,7 @@ void qemu_init(int argc, char **argv) exit(0); break; case QEMU_OPTION_m: - if (!qemu_opts_parse_noisily(qemu_find_opts("memory"), - optarg, true)) { + if (!qemu_opts_parse_noisily("memory", optarg, true)) { exit(1); } break; @@ -3244,15 +3238,13 @@ void qemu_init(int argc, char **argv) "See '-object' docs in the QEMU manual for further " "configuration guidance: " "https://www.qemu.org/docs/master/system/invocation.html"); - if (!qemu_opts_parse_noisily(qemu_find_opts("mon"), optarg, - true)) { + if (!qemu_opts_parse_noisily("mon", optarg, true)) { exit(1); } default_monitor = 0; break; case QEMU_OPTION_chardev: - if (!qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optarg, true)) { + if (!qemu_opts_parse_noisily("chardev", optarg, true)) { exit(1); } break; @@ -3356,9 +3348,8 @@ void qemu_init(int argc, char **argv) } break; case QEMU_OPTION_action: - olist = qemu_find_opts("action"); - if (!qemu_opts_parse_noisily(olist, optarg, false)) { - exit(1); + if (!qemu_opts_parse_noisily("action", optarg, false)) { + exit(1); } break; case QEMU_OPTION_watchdog_action: { @@ -3390,24 +3381,21 @@ void qemu_init(int argc, char **argv) object_register_sugar_prop("ide-device", "win2k-install-hack", "true", true); break; case QEMU_OPTION_acpitable: - opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"), - optarg, true); + opts = qemu_opts_parse_noisily("acpi", optarg, true); if (!opts) { exit(1); } acpi_table_add(opts, &error_fatal); break; case QEMU_OPTION_smbios: - opts = qemu_opts_parse_noisily(qemu_find_opts("smbios"), - optarg, false); + opts = qemu_opts_parse_noisily("smbios", optarg, false); if (!opts) { exit(1); } smbios_entry_add(opts, &error_fatal); break; case QEMU_OPTION_fwcfg: - if (!qemu_opts_parse_noisily(qemu_find_opts("fw_cfg"), - optarg, true)) { + if (!qemu_opts_parse_noisily("fw_cfg", optarg, true)) { exit(1); } break; @@ -3430,8 +3418,7 @@ void qemu_init(int argc, char **argv) break; } case QEMU_OPTION_accel: - accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"), - optarg, true); + accel_opts = qemu_opts_parse_noisily("accel", optarg, true); optarg = qemu_opt_get(accel_opts, "accel"); if (!optarg || is_help_option(optarg)) { printf("Accelerators supported in QEMU binary:\n"); @@ -3470,8 +3457,7 @@ void qemu_init(int argc, char **argv) assert(opt->opts != NULL); QTAILQ_INSERT_TAIL(&device_opts, opt, next); } else { - if (!qemu_opts_parse_noisily(qemu_find_opts("device"), - optarg, true)) { + if (!qemu_opts_parse_noisily("device", optarg, true)) { exit(1); } } @@ -3487,12 +3473,10 @@ void qemu_init(int argc, char **argv) break; #endif case QEMU_OPTION_no_reboot: - olist = qemu_find_opts("action"); - qemu_opts_parse_noisily(olist, "reboot=shutdown", false); + qemu_opts_parse_noisily("action", "reboot=shutdown", false); break; case QEMU_OPTION_no_shutdown: - olist = qemu_find_opts("action"); - qemu_opts_parse_noisily(olist, "shutdown=pause", false); + qemu_opts_parse_noisily("action", "shutdown=pause", false); break; case QEMU_OPTION_uuid: if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) { @@ -3506,8 +3490,7 @@ void qemu_init(int argc, char **argv) error_report("too many option ROMs"); exit(1); } - opts = qemu_opts_parse_noisily(qemu_find_opts("option-rom"), - optarg, true); + opts = qemu_opts_parse_noisily("option-rom", optarg, true); if (!opts) { exit(1); } @@ -3529,8 +3512,7 @@ void qemu_init(int argc, char **argv) } break; case QEMU_OPTION_name: - opts = qemu_opts_parse_noisily(qemu_find_opts("name"), - optarg, true); + opts = qemu_opts_parse_noisily("name", optarg, true); if (!opts) { exit(1); } @@ -3546,15 +3528,13 @@ void qemu_init(int argc, char **argv) nb_prom_envs++; break; case QEMU_OPTION_rtc: - opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg, - false); + opts = qemu_opts_parse_noisily("rtc", optarg, false); if (!opts) { exit(1); } break; case QEMU_OPTION_icount: - icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"), - optarg, true); + icount_opts = qemu_opts_parse_noisily("icount", optarg, true); if (!icount_opts) { exit(1); } @@ -3603,7 +3583,7 @@ void qemu_init(int argc, char **argv) break; #ifdef CONFIG_SPICE case QEMU_OPTION_spice: - opts = qemu_opts_parse_noisily(qemu_find_opts("spice"), optarg, false); + opts = qemu_opts_parse_noisily("spice", optarg, false); if (!opts) { exit(1); } @@ -3633,8 +3613,7 @@ void qemu_init(int argc, char **argv) break; case QEMU_OPTION_add_fd: #ifndef _WIN32 - opts = qemu_opts_parse_noisily(qemu_find_opts("add-fd"), - optarg, false); + opts = qemu_opts_parse_noisily("add-fd", optarg, false); if (!opts) { exit(1); } @@ -3666,8 +3645,7 @@ void qemu_init(int argc, char **argv) break; } case QEMU_OPTION_msg: - opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg, - false); + opts = qemu_opts_parse_noisily("msg", optarg, false); if (!opts) { exit(1); } @@ -3697,8 +3675,7 @@ void qemu_init(int argc, char **argv) break; case QEMU_OPTION_run_with: { const char *str; - opts = qemu_opts_parse_noisily(qemu_find_opts("run-with"), - optarg, false); + opts = qemu_opts_parse_noisily("run-with", optarg, false); if (!opts) { exit(1); } diff --git a/tests/unit/test-char.c b/tests/unit/test-char.c index b88b557133..bbcdf9a9ce 100644 --- a/tests/unit/test-char.c +++ b/tests/unit/test-char.c @@ -1210,8 +1210,7 @@ static void char_socket_server_test(gconstpointer opaque) config->fd_pass, NULL, true); - opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optstr, true); + opts = qemu_opts_parse_noisily("chardev", optstr, true); g_assert_nonnull(opts); chr = qemu_chr_new_from_opts(opts, NULL, &error_abort); qemu_opts_del(opts); @@ -1352,8 +1351,7 @@ static void char_socket_client_dupid_test(gconstpointer opaque) config->reconnect, false); - opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optstr, true); + opts = qemu_opts_parse_noisily("chardev", optstr, true); g_assert_nonnull(opts); chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort); g_assert_nonnull(chr1); @@ -1412,8 +1410,7 @@ static void char_socket_client_test(gconstpointer opaque) config->reconnect, false); - opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optstr, true); + opts = qemu_opts_parse_noisily("chardev", optstr, true); g_assert_nonnull(opts); chr = qemu_chr_new_from_opts(opts, NULL, &error_abort); qemu_opts_del(opts); @@ -1544,8 +1541,7 @@ static void char_socket_server_two_clients_test(gconstpointer opaque) false, NULL, true); - opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optstr, true); + opts = qemu_opts_parse_noisily("chardev", optstr, true); g_assert_nonnull(opts); chr = qemu_chr_new_from_opts(opts, NULL, &error_abort); qemu_opts_del(opts); diff --git a/tests/unit/test-seccomp.c b/tests/unit/test-seccomp.c index 71d4083439..4438012989 100644 --- a/tests/unit/test-seccomp.c +++ b/tests/unit/test-seccomp.c @@ -31,15 +31,11 @@ static void test_seccomp_helper(const char *args, bool killed, int errnum, int (*doit)(void)) { if (g_test_subprocess()) { - QemuOptsList *olist; QemuOpts *opts; int ret; module_call_init(MODULE_INIT_OPTS); - olist = qemu_find_opts("sandbox"); - g_assert(olist != NULL); - - opts = qemu_opts_parse_noisily(olist, args, true); + opts = qemu_opts_parse_noisily("sandbox", args, true); g_assert(opts != NULL); parse_sandbox(NULL, opts, &error_abort); diff --git a/trace/control.c b/trace/control.c index 49f0a4c5cd..51cecf5827 100644 --- a/trace/control.c +++ b/trace/control.c @@ -288,8 +288,7 @@ bool trace_init_backends(void) void trace_opt_parse(const char *optstr) { - QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("trace"), - optstr, true); + QemuOpts *opts = qemu_opts_parse_noisily("trace", optstr, true); if (!opts) { exit(1); } diff --git a/ui/vnc.c b/ui/vnc.c index 656768f9c9..7ddf660856 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -4324,8 +4324,7 @@ static char *vnc_auto_assign_id(QemuOpts *opts) void vnc_parse(const char *str) { - QemuOptsList *olist = qemu_find_opts("vnc"); - QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str)); + QemuOpts *opts = qemu_opts_parse_noisily("vnc", str, !is_help_option(str)); if (!opts) { exit(1); diff --git a/util/qemu-option.c b/util/qemu-option.c index c762eb20a3..f8494c8842 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -941,6 +941,8 @@ QemuOpts *qemu_opts_parse_list(QemuOptsList *list, const char *params, bool noisily = !errp; QemuOpts *opts = NULL; + assert(list); + if (noisily) { Error *err = NULL; bool help_wanted = !opts_accepts_any(list); @@ -958,16 +960,24 @@ QemuOpts *qemu_opts_parse_list(QemuOptsList *list, const char *params, } /** - * Create a QemuOpts in @list and with options parsed from @params. + * Find the @group and create a QemuOpts with options parsed from @params. * If @permit_abbrev, the first key=value in @params may omit key=, * and is treated as if key was @list->implied_opt_name. * Report errors with error_report_err(). This is inappropriate in * QMP context. Do not use this function there! * Return the new QemuOpts on success, null pointer on error. */ -QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params, +QemuOpts *qemu_opts_parse_noisily(const char *group, const char *params, bool permit_abbrev) { + Error *err = NULL; + QemuOptsList *list = qemu_find_opts_err(group, &err); + + if (!list) { + error_report_err(err); + return NULL; + } + return qemu_opts_parse_list(list, params, permit_abbrev, NULL); } -- 2.53.0
