Commit 72215395 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

util: Add qemu_opts_to_qdict_filtered()



This allows, given a QemuOpts for a QemuOptsList that was merged from
multiple QemuOptsList, to only consider those options that exist in one
specific list. Block drivers need this to separate format-layer create
options from protocol-level options.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
parent e4b5dad8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
                            int permit_abbrev);
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
                               Error **errp);
QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict,
                                   QemuOptsList *list, bool del);
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);

+37 −5
Original line number Diff line number Diff line
@@ -1007,14 +1007,23 @@ void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
}

/*
 * Convert from QemuOpts to QDict.
 * The QDict values are of type QString.
 * Convert from QemuOpts to QDict. The QDict values are of type QString.
 *
 * If @list is given, only add those options to the QDict that are contained in
 * the list. If @del is true, any options added to the QDict are removed from
 * the QemuOpts, otherwise they remain there.
 *
 * If two options in @opts have the same name, they are processed in order
 * so that the last one wins (consistent with the reverse iteration in
 * qemu_opt_find()), but all of them are deleted if @del is true.
 *
 * TODO We'll want to use types appropriate for opt->desc->type, but
 * this is enough for now.
 */
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict,
                                   QemuOptsList *list, bool del)
{
    QemuOpt *opt;
    QemuOpt *opt, *next;

    if (!qdict) {
        qdict = qdict_new();
@@ -1022,12 +1031,35 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
    if (opts->id) {
        qdict_put_str(qdict, "id", opts->id);
    }
    QTAILQ_FOREACH(opt, &opts->head, next) {
    QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next) {
        if (list) {
            QemuOptDesc *desc;
            bool found = false;
            for (desc = list->desc; desc->name; desc++) {
                if (!strcmp(desc->name, opt->name)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                continue;
            }
        }
        qdict_put_str(qdict, opt->name, opt->str);
        if (del) {
            qemu_opt_del(opt);
        }
    }
    return qdict;
}

/* Copy all options in a QemuOpts to the given QDict. See
 * qemu_opts_to_qdict_filtered() for details. */
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
{
    return qemu_opts_to_qdict_filtered(opts, qdict, NULL, false);
}

/* Validate parsed opts against descriptions where no
 * descriptions were provided in the QemuOptsList.
 */