From: Markus Armbruster <armbru@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [PATCH v2 4/6] qemu-option: clean up id vs. list->merge_lists
Date: Mon, 09 Nov 2020 17:56:58 +0100 [thread overview]
Message-ID: <87wnyu4gf9.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <20201109133931.979563-5-pbonzini@redhat.com> (Paolo Bonzini's message of "Mon, 9 Nov 2020 08:39:29 -0500")
Paolo Bonzini <pbonzini@redhat.com> writes:
> Forbid ids if the option is intended to be a singleton, as indicated by
> list->merge_lists.
Well, ->merge_lists need not imply singleton. Perhaps we only ever use
it that way. Careful review is called for.
> This avoids that "./qemu-system-x86_64 -M q35,id=ff"
> uses a "pc" machine type.
Just like any other QemuOptsList, "machine" may have any number of
QemuOpts. The ones with non-null ID happen to be ignored silently.
Known[*] trap for the unwary.
> Instead it errors out. The affected options
> are "qemu-img reopen -o",
reopen_opts in qemu-io-cmds.c
> "qemu-io open -o",
empty_opts in qemu-io.c
> -rtc, -M, -boot, -name,
> -m, -icount, -smp,
qemu_rtc_opts, qemu_machine_opts, qemu_boot_opts, qemu_name_opts,
qemu_mem_opts, qemu_icount_opts, qemu_smp_opts in vl.c
> -spice.
qemu_spice_opts in spice-core.c.
Are these all singletons?
There's also machine_opts in qemu-config.c, but that's only to make
query-command-line-options lie backward-compatibly.
>
> qemu_opts_create's fail_if_exists parameter is now unnecessary:
>
> - it is unused if id is NULL
>
> - opts_parse only passes false if reached from qemu_opts_set_defaults,
> in which case this patch enforces that id must be NULL
>
> - other callers that can pass a non-NULL id always set it to true
>
> Assert that it is true in the only case where "fail_if_exists" matters,
> i.e. "id && !lists->merge_lists". This means that if an id is present,
> duplicates are always forbidden, which was already the status quo.
Sounds like you're specializing the code (which might be good).
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> util/qemu-option.c | 27 ++++++++++++++-------------
> 1 file changed, 14 insertions(+), 13 deletions(-)
>
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index c88e159f18..91f4120ce1 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -619,7 +619,17 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
> {
> QemuOpts *opts = NULL;
>
> - if (id) {
> + if (list->merge_lists) {
> + if (id) {
> + error_setg(errp, QERR_INVALID_PARAMETER, "id");
> + return NULL;
> + }
> + opts = qemu_opts_find(list, NULL);
> + if (opts) {
> + return opts;
> + }
If lists>merge_lists, you no longer check id_wellformed(). Easy enough
to fix: lift the check before this conditional.
> + } else if (id) {
> + assert(fail_if_exists);
> if (!id_wellformed(id)) {
> error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id",
> "an identifier");
> @@ -629,17 +639,8 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
> }
> opts = qemu_opts_find(list, id);
> if (opts != NULL) {
> - if (fail_if_exists && !list->merge_lists) {
> - error_setg(errp, "Duplicate ID '%s' for %s", id, list->name);
> - return NULL;
> - } else {
> - return opts;
> - }
> - }
> - } else if (list->merge_lists) {
> - opts = qemu_opts_find(list, NULL);
> - if (opts) {
> - return opts;
> + error_setg(errp, "Duplicate ID '%s' for %s", id, list->name);
> + return NULL;
> }
> }
> opts = g_malloc0(sizeof(*opts));
Paths through the function before the patch:
id fail_if_exists merge_lists | return
null don't care false | new opts
null don't care true | existing or else new opts
non-null false don't care | existing or else new opts
non-null true true | existing or else new opts
non-null true false | new opts / fail if exist
Too many cases.
After the patch:
id fail_if_exists merge_lists | return
non-null don't care true | fail
null don't care true | existing or else new opts
non-null false false | abort
non-null true false | new opts / fail if exist
null don't care false | new opts
Still too many :)
I'm running out of time for today, and I still need to convince myself
that the changes in behavior are all okay.
> @@ -893,7 +894,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
> * (if unlikely) future misuse:
> */
> assert(!defaults || list->merge_lists);
> - opts = qemu_opts_create(list, id, !defaults, errp);
> + opts = qemu_opts_create(list, id, !list->merge_lists, errp);
> g_free(id);
> if (opts == NULL) {
> return NULL;
[*] Known to the QemuOpts cognoscenti, whose number could be
embarrasingly close to one.
next prev parent reply other threads:[~2020-11-09 16:57 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-09 13:39 [PATCH v2 for-5.2 0/6] Deprecate or forbid crazy QemuOpts cases Paolo Bonzini
2020-11-09 13:39 ` [PATCH v2 1/6] qemu-option: simplify search for end of key Paolo Bonzini
2020-11-09 14:48 ` Markus Armbruster
2020-11-09 13:39 ` [PATCH v2 2/6] qemu-option: pass QemuOptsList to opts_accepts_any Paolo Bonzini
2020-11-09 15:27 ` Markus Armbruster
2020-11-09 13:39 ` [PATCH v2 3/6] qemu-option: restrict qemu_opts_set to merge-lists QemuOpts Paolo Bonzini
2020-11-09 15:55 ` Markus Armbruster
2020-11-09 16:21 ` Paolo Bonzini
2020-11-09 18:52 ` Markus Armbruster
2020-11-09 18:58 ` Paolo Bonzini
2020-11-09 13:39 ` [PATCH v2 4/6] qemu-option: clean up id vs. list->merge_lists Paolo Bonzini
2020-11-09 16:56 ` Markus Armbruster [this message]
2020-11-09 17:17 ` Paolo Bonzini
2020-11-09 18:38 ` Markus Armbruster
2020-11-09 18:59 ` Paolo Bonzini
2020-11-10 8:29 ` Markus Armbruster
2020-11-10 8:39 ` Paolo Bonzini
2020-11-10 9:54 ` Markus Armbruster
2020-11-09 13:39 ` [PATCH v2 5/6] qemu-option: move help handling to get_opt_name_value Paolo Bonzini
2020-11-09 19:40 ` Markus Armbruster
2020-11-09 19:47 ` Paolo Bonzini
2020-11-09 13:39 ` [PATCH v2 6/6] qemu-option: warn for short-form boolean options Paolo Bonzini
2020-11-09 21:19 ` Markus Armbruster
2020-11-09 21:42 ` Paolo Bonzini
2020-11-10 8:32 ` Markus Armbruster
2020-11-09 13:54 ` [PATCH v2 for-5.2 0/6] Deprecate or forbid crazy QemuOpts cases no-reply
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=87wnyu4gf9.fsf@dusky.pond.sub.org \
--to=armbru@redhat.com \
--cc=pbonzini@redhat.com \
--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.