Commit 8a87f3d7 authored by Max Reitz's avatar Max Reitz Committed by Kevin Wolf
Browse files

quorum: Simplify quorum_open()



Although it may not look like it, this patch simplifies quorum_open().
qdict_array_split() is now able to return QLists with different objects
than only QDicts, therefore it will now do all the work and
quorum_open() does not have to handle reference strings by itself.

This allows mixing full option dicts and reference strings for
specifying the child block devices of quorum; furthermore, it improves
handling of malformed specifications.

Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarBenoit Canet <benoit@irqsave.net>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent c7fc5bc2
Loading
Loading
Loading
Loading
+39 −27
Original line number Diff line number Diff line
@@ -720,7 +720,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
    QDict *sub = NULL;
    QList *list = NULL;
    const QListEntry *lentry;
    const QDictEntry *dentry;
    int i;
    int ret = 0;

@@ -728,10 +727,15 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
    qdict_extract_subqdict(options, &sub, "children.");
    qdict_array_split(sub, &list);

    /* count how many different children are present and validate
     * qdict_size(sub) address the open by reference case
     */
    s->num_children = !qlist_size(list) ? qdict_size(sub) : qlist_size(list);
    if (qdict_size(sub)) {
        error_setg(&local_err, "Invalid option children.%s",
                   qdict_first(sub)->key);
        ret = -EINVAL;
        goto exit;
    }

    /* count how many different children are present */
    s->num_children = qlist_size(list);
    if (s->num_children < 2) {
        error_setg(&local_err,
                   "Number of provided children must be greater than 1");
@@ -767,31 +771,39 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
    s->bs = g_new0(BlockDriverState *, s->num_children);
    opened = g_new0(bool, s->num_children);

    /* Open by file name or options dict (command line or QMP) */
    if (s->num_children == qlist_size(list)) {
    for (i = 0, lentry = qlist_first(list); lentry;
         lentry = qlist_next(lentry), i++) {
            QDict *d = qobject_to_qdict(lentry->value);
        QDict *d;
        QString *string;

        switch (qobject_type(lentry->value))
        {
            /* List of options */
            case QTYPE_QDICT:
                d = qobject_to_qdict(lentry->value);
                QINCREF(d);
            ret = bdrv_open(&s->bs[i], NULL, NULL, d, flags, NULL, &local_err);
            if (ret < 0) {
                goto close_exit;
            }
            opened[i] = true;
        }
    /* Open by QMP references */
    } else {
        for (i = 0, dentry = qdict_first(sub); dentry;
             dentry = qdict_next(sub, dentry), i++) {
            QString *string = qobject_to_qstring(dentry->value);
                ret = bdrv_open(&s->bs[i], NULL, NULL, d, flags, NULL,
                                &local_err);
                break;

            /* QMP reference */
            case QTYPE_QSTRING:
                string = qobject_to_qstring(lentry->value);
                ret = bdrv_open(&s->bs[i], NULL, qstring_get_str(string), NULL,
                                flags, NULL, &local_err);
                break;

            default:
                error_setg(&local_err, "Specification of child block device %i "
                           "is invalid", i);
                ret = -EINVAL;
        }

        if (ret < 0) {
            goto close_exit;
        }
        opened[i] = true;
    }
    }

    g_free(opened);
    goto exit;