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


Reply via email to