All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, imammedo@redhat.com, armbru@redhat.com,
	qemu-block@nongnu.org
Subject: [PATCH 22/28] qemu: use keyval for -object parsing
Date: Wed,  2 Dec 2020 04:02:59 -0500	[thread overview]
Message-ID: <20201202090305.4129317-23-pbonzini@redhat.com> (raw)
In-Reply-To: <20201202090305.4129317-1-pbonzini@redhat.com>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qom/object_interfaces.h | 65 +---------------------------
 qom/object_interfaces.c         | 75 ---------------------------------
 softmmu/vl.c                    | 75 +++++++++++++++++++++------------
 3 files changed, 48 insertions(+), 167 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index ed0d7d663b..1caa4fca57 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -104,51 +104,6 @@ Object *user_creatable_add_type(const char *type, const char *id,
  */
 bool user_creatable_add_dict(const QDict *qdict, bool keyval, Error **errp);
 
-/**
- * user_creatable_add_opts:
- * @opts: the object definition
- * @errp: if an error occurs, a pointer to an area to store the error
- *
- * Create an instance of the user creatable object whose type
- * is defined in @opts by the 'qom-type' option, placing it
- * in the object composition tree with name provided by the
- * 'id' field. The remaining options in @opts are used to
- * initialize the object properties.
- *
- * Returns: the newly created object or NULL on error
- */
-Object *user_creatable_add_opts(QemuOpts *opts, Error **errp);
-
-
-/**
- * user_creatable_add_opts_predicate:
- * @type: the QOM type to be added
- *
- * A callback function to determine whether an object
- * of type @type should be created. Instances of this
- * callback should be passed to user_creatable_add_opts_foreach
- */
-typedef bool (*user_creatable_add_opts_predicate)(const char *type);
-
-/**
- * user_creatable_add_opts_foreach:
- * @opaque: a user_creatable_add_opts_predicate callback or NULL
- * @opts: options to create
- * @errp: unused
- *
- * An iterator callback to be used in conjunction with
- * the qemu_opts_foreach() method for creating a list of
- * objects from a set of QemuOpts
- *
- * The @opaque parameter can be passed a user_creatable_add_opts_predicate
- * callback to filter which types of object are created during iteration.
- * When it fails, report the error.
- *
- * Returns: 0 on success, -1 when an error was reported.
- */
-int user_creatable_add_opts_foreach(void *opaque,
-                                    QemuOpts *opts, Error **errp);
-
 /**
  * user_creatable_print_types:
  *
@@ -156,30 +111,12 @@ int user_creatable_add_opts_foreach(void *opaque,
  */
 void user_creatable_print_types(void);
 
-/**
- * user_creatable_print_help:
- * @type: the QOM type to be added
- * @opts: options to create
- *
- * Prints help if requested in @type or @opts. Note that if @type is neither
- * "help"/"?" nor a valid user creatable type, no help will be printed
- * regardless of @opts.
- *
- * Returns: true if a help option was found and help was printed, false
- * otherwise.
- */
-bool user_creatable_print_help(const char *type, QemuOpts *opts);
-
 /**
  * user_creatable_print_help_from_qdict:
  * @args: options to create
  *
  * Prints help considering the other options given in @args (if "qom-type" is
- * given and valid, print properties for the type, otherwise print valid types)
- *
- * In contrast to user_creatable_print_help(), this function can't return that
- * no help was requested. It should only be called if we know that help is
- * requested and it will always print some help.
+ * given and valid, print properties for the type, otherwise print valid types).
  */
 void user_creatable_print_help_from_qdict(const QDict *args);
 
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 80814ae7b5..107c378c27 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -141,60 +141,6 @@ out:
     return !!obj;
 }
 
-Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
-{
-    Visitor *v;
-    QDict *pdict;
-    Object *obj;
-    const char *id = qemu_opts_id(opts);
-    char *type = qemu_opt_get_del(opts, "qom-type");
-
-    if (!type) {
-        error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
-        return NULL;
-    }
-    if (!id) {
-        error_setg(errp, QERR_MISSING_PARAMETER, "id");
-        qemu_opt_set(opts, "qom-type", type, &error_abort);
-        g_free(type);
-        return NULL;
-    }
-
-    qemu_opts_set_id(opts, NULL);
-    pdict = qemu_opts_to_qdict(opts, NULL);
-
-    v = opts_visitor_new(opts);
-    obj = user_creatable_add_type(type, id, pdict, v, errp);
-    visit_free(v);
-
-    qemu_opts_set_id(opts, (char *) id);
-    qemu_opt_set(opts, "qom-type", type, &error_abort);
-    g_free(type);
-    qobject_unref(pdict);
-    return obj;
-}
-
-
-int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
-{
-    bool (*type_opt_predicate)(const char *, QemuOpts *) = opaque;
-    Object *obj = NULL;
-    const char *type;
-
-    type = qemu_opt_get(opts, "qom-type");
-    if (type && type_opt_predicate &&
-        !type_opt_predicate(type, opts)) {
-        return 0;
-    }
-
-    obj = user_creatable_add_opts(opts, errp);
-    if (!obj) {
-        return -1;
-    }
-    object_unref(obj);
-    return 0;
-}
-
 char *object_property_help(const char *name, const char *type,
                            QObject *defval, const char *description)
 {
@@ -269,20 +215,6 @@ static bool user_creatable_print_type_properites(const char *type)
     return true;
 }
 
-bool user_creatable_print_help(const char *type, QemuOpts *opts)
-{
-    if (is_help_option(type)) {
-        user_creatable_print_types();
-        return true;
-    }
-
-    if (qemu_opt_has_help_opt(opts)) {
-        return user_creatable_print_type_properites(type);
-    }
-
-    return false;
-}
-
 void user_creatable_print_help_from_qdict(const QDict *args)
 {
     const char *type = qdict_get_try_str(args, "qom-type");
@@ -309,13 +241,6 @@ bool user_creatable_del(const char *id, Error **errp)
         return false;
     }
 
-    /*
-     * if object was defined on the command-line, remove its corresponding
-     * option group entry
-     */
-    qemu_opts_del(qemu_opts_find(qemu_find_opts_err("object", &error_abort),
-                                 id));
-
     object_unparent(obj);
     return true;
 }
diff --git a/softmmu/vl.c b/softmmu/vl.c
index de3e22c9eb..f083881f21 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -134,6 +134,7 @@ static const char *cpu_option;
 static const char *mem_path;
 static const char *incoming;
 static const char *loadvm;
+static GSList *object_opts_list = NULL;
 static ram_addr_t maxram_size;
 static uint64_t ram_slots;
 static int display_remote;
@@ -306,15 +307,6 @@ static QemuOptsList qemu_add_fd_opts = {
     },
 };
 
-static QemuOptsList qemu_object_opts = {
-    .name = "object",
-    .implied_opt_name = "qom-type",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
-    .desc = {
-        { }
-    },
-};
-
 static QemuOptsList qemu_tpmdev_opts = {
     .name = "tpmdev",
     .implied_opt_name = "type",
@@ -1675,12 +1667,8 @@ static int machine_set_property(void *opaque,
  * cannot be created here, as it depends on the chardev
  * already existing.
  */
-static bool object_create_early(const char *type, QemuOpts *opts)
+static bool object_create_early(const char *type)
 {
-    if (user_creatable_print_help(type, opts)) {
-        exit(0);
-    }
-
     /*
      * Objects should not be made "delayed" without a reason.  If you
      * add one, state the reason in a comment!
@@ -1773,6 +1761,22 @@ static void qemu_apply_machine_options(void)
     }
 }
 
+static void user_creatable_add_dict_foreach(void *data, void *opaque)
+{
+    bool (*type_opt_predicate)(const char *) = opaque;
+    const QDict *dict = data;
+    const char *type = qdict_get_try_str(dict, "qom-type");
+
+    if (!type) {
+        error_report("Parameter 'qom-type' is missing");
+    }
+    if (type_opt_predicate && !type_opt_predicate(type)) {
+        return;
+    }
+
+    user_creatable_add_dict(dict, true, &error_fatal);
+}
+
 static void qemu_create_early_backends(void)
 {
     MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
@@ -1799,9 +1803,9 @@ static void qemu_create_early_backends(void)
         exit(1);
     }
 
-    qemu_opts_foreach(qemu_find_opts("object"),
-                      user_creatable_add_opts_foreach,
-                      object_create_early, &error_fatal);
+    g_slist_foreach(object_opts_list,
+                    user_creatable_add_dict_foreach,
+                    object_create_early);
 
     /* spice needs the timers to be initialized by this point */
     /* spice must initialize before audio as it changes the default auiodev */
@@ -1830,9 +1834,9 @@ static void qemu_create_early_backends(void)
  * The remainder of object creation happens after the
  * creation of chardev, fsdev, net clients and device data types.
  */
-static bool object_create_late(const char *type, QemuOpts *opts)
+static bool object_create_late(const char *type)
 {
-    return !object_create_early(type, opts);
+    return !object_create_early(type);
 }
 
 static void qemu_create_late_backends(void)
@@ -1843,9 +1847,9 @@ static void qemu_create_late_backends(void)
 
     net_init_clients(&error_fatal);
 
-    qemu_opts_foreach(qemu_find_opts("object"),
-                      user_creatable_add_opts_foreach,
-                      object_create_late, &error_fatal);
+    g_slist_foreach(object_opts_list,
+                    user_creatable_add_dict_foreach,
+                    object_create_late);
 
     if (tpm_init() < 0) {
         exit(1);
@@ -2052,6 +2056,9 @@ 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")) {
+        return false;
+    }
     return true;
 }
 
@@ -2061,6 +2068,9 @@ static bool is_qemuopts_group(const char *group)
  */
 static GSList **qemu_config_list(const char *group)
 {
+    if (g_str_equal(group, "object")) {
+        return &object_opts_list;
+    }
     return NULL;
 }
 
@@ -2643,7 +2653,6 @@ void qemu_init(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_smp_opts);
     qemu_add_opts(&qemu_boot_opts);
     qemu_add_opts(&qemu_add_fd_opts);
-    qemu_add_opts(&qemu_object_opts);
     qemu_add_opts(&qemu_tpmdev_opts);
     qemu_add_opts(&qemu_realtime_opts);
     qemu_add_opts(&qemu_overcommit_opts);
@@ -3427,12 +3436,18 @@ void qemu_init(int argc, char **argv, char **envp)
 #endif
                 break;
             case QEMU_OPTION_object:
-                opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
-                                               optarg, true);
-                if (!opts) {
-                    exit(1);
+                {
+                    QDict *args;
+                    bool help;
+
+                    args = keyval_parse(optarg, "qom-type", &help, &error_fatal);
+                    if (help) {
+                        user_creatable_print_help_from_qdict(args);
+                        exit(EXIT_SUCCESS);
+                    }
+                    qemu_record_config_group("object", args, &error_abort);
+                    break;
                 }
-                break;
             case QEMU_OPTION_realtime:
                 warn_report("'-realtime mlock=...' is deprecated, please use "
                              "'-overcommit mem-lock=...' instead");
@@ -3490,6 +3505,10 @@ void qemu_init(int argc, char **argv, char **envp)
             }
         }
     }
+
+    /* Cleanup after option parsing loop.  */
+    object_opts_list = g_slist_reverse(object_opts_list);
+
     /*
      * Clear error location left behind by the loop.
      * Best done right after the loop.  Do not insert code here!
-- 
2.26.2




  parent reply	other threads:[~2020-12-02 10:22 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-02  9:02 [PATCH 00/28] qemu-option, keyval, vl: switch -object/-M/-accel to keyval parsing Paolo Bonzini
2020-12-02  9:02 ` [PATCH 01/28] qemu-option: simplify search for end of key Paolo Bonzini
2020-12-02  9:02 ` [PATCH 02/28] qemu-option: pass QemuOptsList to opts_accepts_any Paolo Bonzini
2020-12-02  9:02 ` [PATCH 03/28] qemu-option: clean up id vs. list->merge_lists Paolo Bonzini
2020-12-02  9:02 ` [PATCH 04/28] qemu-option: move help handling to get_opt_name_value Paolo Bonzini
2020-12-02  9:02 ` [PATCH 05/28] qemu-option: warn for short-form boolean options Paolo Bonzini
2020-12-02  9:02 ` [PATCH 06/28] keyval: accept escaped commas in implied option Paolo Bonzini
2020-12-02  9:02 ` [PATCH 07/28] keyval: simplify keyval_parse_one Paolo Bonzini
2020-12-02  9:02 ` [PATCH 08/28] tests: convert check-qom-proplist to keyval Paolo Bonzini
2020-12-02  9:02 ` [PATCH 09/28] keyval: introduce keyval_parse_into Paolo Bonzini
2020-12-02  9:02 ` [PATCH 10/28] hmp: replace "O" parser with keyval Paolo Bonzini
2020-12-02  9:02 ` [PATCH 11/28] qom: use qemu_printf to print help for user-creatable objects Paolo Bonzini
2020-12-02  9:02 ` [PATCH 12/28] hmp: special case help options for object_add Paolo Bonzini
2020-12-02  9:02 ` [PATCH 13/28] remove -writeconfig Paolo Bonzini
2020-12-02  9:02 ` [PATCH 14/28] qemu-config: add error propagation to qemu_config_parse Paolo Bonzini
2020-12-02  9:02 ` [PATCH 15/28] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict Paolo Bonzini
2020-12-02  9:02 ` [PATCH 16/28] qemu-config: parse configuration files to a QDict Paolo Bonzini
2020-12-02  9:02 ` [PATCH 17/28] vl: plumb keyval-based options into -set and -readconfig Paolo Bonzini
2020-12-02  9:02 ` [PATCH 18/28] qom: do not modify QDict argument in user_creatable_add_dict Paolo Bonzini
2020-12-02  9:02 ` [PATCH 19/28] qemu-io: use keyval for -object parsing Paolo Bonzini
2020-12-02  9:02 ` [PATCH 20/28] qemu-nbd: " Paolo Bonzini
2020-12-02  9:02 ` [PATCH 21/28] qemu-img: " Paolo Bonzini
2020-12-02  9:02 ` Paolo Bonzini [this message]
2020-12-02  9:03 ` [PATCH 23/28] storage-daemon: do not register the "object" group with QemuOpts Paolo Bonzini
2020-12-02  9:03 ` [PATCH 24/28] qom: export more functions for use with non-UserCreatable objects Paolo Bonzini
2020-12-02  9:03 ` [PATCH 25/28] vl: rename local variable in configure_accelerators Paolo Bonzini
2020-12-02  9:03 ` [PATCH 26/28] vl: switch -M parsing to keyval Paolo Bonzini
2020-12-02  9:03 ` [PATCH 27/28] qemu-option: remove now-dead code Paolo Bonzini
2020-12-02  9:03 ` [PATCH 28/28] vl: switch -accel parsing to keyval Paolo Bonzini
2021-01-17 16:48 ` [PATCH 00/28] qemu-option, keyval, vl: switch -object/-M/-accel to keyval parsing Paolo Bonzini
2021-01-18 10:29   ` Kevin Wolf
2021-01-18 12:47     ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201202090305.4129317-23-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=armbru@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.