Exemplo n.º 1
0
static void qnull_visit_test(void)
{
    QObject *obj;
    Visitor *v;
    QNull *null;

    /*
     * Most tests of interactions between QObject and visitors are in
     * test-qmp-*-visitor; but these tests live here because they
     * depend on layering violations to check qnull_ refcnt.
     */

    g_assert(qnull_.base.refcnt == 1);
    obj = QOBJECT(qnull());
    v = qobject_input_visitor_new(obj);
    qobject_decref(obj);
    visit_type_null(v, NULL, &null, &error_abort);
    g_assert(obj == QOBJECT(&qnull_));
    QDECREF(null);
    visit_free(v);

    null = NULL;
    v = qobject_output_visitor_new(&obj);
    visit_type_null(v, NULL, &null, &error_abort);
    visit_complete(v, &obj);
    g_assert(obj == QOBJECT(&qnull_));
    QDECREF(null);
    qobject_decref(obj);
    visit_free(v);

    g_assert(qnull_.base.refcnt == 1);
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/* test generated deallocation on an object whose construction was prematurely
 * terminated due to an error */
static void test_dealloc_partial(void)
{
    static const char text[] = "don't leak me";

    UserDefTwo *ud2 = NULL;
    Error *err = NULL;

    /* create partial object */
    {
        QDict *ud2_dict;
        Visitor *v;

        ud2_dict = qdict_new();
        qdict_put_str(ud2_dict, "string0", text);

        v = qobject_input_visitor_new(QOBJECT(ud2_dict));
        visit_type_UserDefTwo(v, NULL, &ud2, &err);
        visit_free(v);
        qobject_unref(ud2_dict);
    }

    /* verify that visit_type_XXX() cleans up properly on error */
    error_free_or_abort(&err);
    assert(!ud2);

    /* Manually create a partial object, leaving ud2->dict1 at NULL */
    ud2 = g_new0(UserDefTwo, 1);
    ud2->string0 = g_strdup(text);

    /* tear down partial object */
    qapi_free_UserDefTwo(ud2);
}
Exemplo n.º 4
0
static InetSocketAddress *ssh_config(BDRVSSHState *s, QDict *options,
                                     Error **errp)
{
    InetSocketAddress *inet = NULL;
    QDict *addr = NULL;
    QObject *crumpled_addr = NULL;
    Visitor *iv = NULL;
    Error *local_error = NULL;

    qdict_extract_subqdict(options, &addr, "server.");
    if (!qdict_size(addr)) {
        error_setg(errp, "SSH server address missing");
        goto out;
    }

    crumpled_addr = qdict_crumple(addr, errp);
    if (!crumpled_addr) {
        goto out;
    }

    iv = qobject_input_visitor_new(crumpled_addr, true);
    visit_type_InetSocketAddress(iv, NULL, &inet, &local_error);
    if (local_error) {
        error_propagate(errp, local_error);
        goto out;
    }

out:
    QDECREF(addr);
    qobject_decref(crumpled_addr);
    visit_free(iv);
    return inet;
}
Exemplo n.º 5
0
static void visitor_output_teardown(TestOutputVisitorData *data,
                                    const void *unused)
{
    visit_free(data->ov);
    data->ov = NULL;
    qobject_decref(data->obj);
    data->obj = NULL;
}
Exemplo n.º 6
0
static void dealloc_helper(void *native_in, VisitorFunc visit, Error **errp)
{
    Visitor *v = qapi_dealloc_visitor_new();

    visit(v, &native_in, errp);

    visit_free(v);
}
Exemplo n.º 7
0
void object_property_set_qobject(Object *obj, QObject *value,
                                 const char *name, Error **errp)
{
    Visitor *v;
    /* TODO: Should we reject, rather than ignore, excess input? */
    v = qobject_input_visitor_new(value, false);
    object_property_set(obj, v, name, errp);
    visit_free(v);
}
Exemplo n.º 8
0
static void visitor_input_teardown(TestInputVisitorData *data,
                                   const void *unused)
{
    qobject_decref(data->obj);
    data->obj = NULL;

    if (data->qiv) {
        visit_free(data->qiv);
        data->qiv = NULL;
    }
}
Exemplo n.º 9
0
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
{
    Visitor *v;
    QDict *pdict;
    Object *obj = NULL;

    v = opts_visitor_new(opts);
    pdict = qemu_opts_to_qdict(opts, NULL);

    obj = user_creatable_add(pdict, v, errp);
    visit_free(v);
    QDECREF(pdict);
    return obj;
}
Exemplo n.º 10
0
void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *,
                                                     void **, Error **))
{
    Visitor *v;
    void *dst = (void *) src; /* Cast away const */

    if (!src) {
        return NULL;
    }

    v = qapi_clone_visitor_new();
    visit_type(v, NULL, &dst, &error_abort);
    visit_free(v);
    return dst;
}
Exemplo n.º 11
0
QObject *object_property_get_qobject(Object *obj, const char *name,
                                     Error **errp)
{
    QObject *ret = NULL;
    Error *local_err = NULL;
    Visitor *v;

    v = qobject_output_visitor_new(&ret);
    object_property_get(obj, v, name, &local_err);
    if (!local_err) {
        visit_complete(v, &ret);
    }
    error_propagate(errp, local_err);
    visit_free(v);
    return ret;
}
Exemplo n.º 12
0
static QCryptoBlockCreateOptions *
block_crypto_create_opts_init(QCryptoBlockFormat format,
                              QemuOpts *opts,
                              Error **errp)
{
    Visitor *v;
    QCryptoBlockCreateOptions *ret = NULL;
    Error *local_err = NULL;

    ret = g_new0(QCryptoBlockCreateOptions, 1);
    ret->format = format;

    v = opts_visitor_new(opts);

    visit_start_struct(v, NULL, NULL, 0, &local_err);
    if (local_err) {
        goto out;
    }

    switch (format) {
    case Q_CRYPTO_BLOCK_FORMAT_LUKS:
        visit_type_QCryptoBlockCreateOptionsLUKS_members(
            v, &ret->u.luks, &local_err);
        break;

    default:
        error_setg(&local_err, "Unsupported block format %d", format);
        break;
    }
    if (!local_err) {
        visit_check_struct(v, &local_err);
    }

    visit_end_struct(v, NULL);

 out:
    if (local_err) {
        error_propagate(errp, local_err);
        qapi_free_QCryptoBlockCreateOptions(ret);
        ret = NULL;
    }
    visit_free(v);
    return ret;
}
Exemplo n.º 13
0
static QAuthZ *
qauthz_list_file_load(QAuthZListFile *fauthz, Error **errp)
{
    GError *err = NULL;
    gchar *content = NULL;
    gsize len;
    QObject *obj = NULL;
    QDict *pdict;
    Visitor *v = NULL;
    QAuthZ *ret = NULL;

    trace_qauthz_list_file_load(fauthz, fauthz->filename);
    if (!g_file_get_contents(fauthz->filename, &content, &len, &err)) {
        error_setg(errp, "Unable to read '%s': %s",
                   fauthz->filename, err->message);
        goto cleanup;
    }

    obj = qobject_from_json(content, errp);
    if (!obj) {
        goto cleanup;
    }

    pdict = qobject_to(QDict, obj);
    if (!pdict) {
        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "obj", "dict");
        goto cleanup;
    }

    v = qobject_input_visitor_new(obj);

    ret = (QAuthZ *)user_creatable_add_type(TYPE_QAUTHZ_LIST,
                                            NULL, pdict, v, errp);

 cleanup:
    visit_free(v);
    qobject_unref(obj);
    if (err) {
        g_error_free(err);
    }
    g_free(content);
    return ret;
}
Exemplo n.º 14
0
Arquivo: ssh.c Projeto: J-Liu/qemu
static InetSocketAddress *ssh_config(QDict *options, Error **errp)
{
    InetSocketAddress *inet = NULL;
    QDict *addr = NULL;
    QObject *crumpled_addr = NULL;
    Visitor *iv = NULL;
    Error *local_error = NULL;

    qdict_extract_subqdict(options, &addr, "server.");
    if (!qdict_size(addr)) {
        error_setg(errp, "SSH server address missing");
        goto out;
    }

    crumpled_addr = qdict_crumple(addr, errp);
    if (!crumpled_addr) {
        goto out;
    }

    /*
     * FIXME .numeric, .to, .ipv4 or .ipv6 don't work with -drive.
     * .to doesn't matter, it's ignored anyway.
     * That's because when @options come from -blockdev or
     * blockdev_add, members are typed according to the QAPI schema,
     * but when they come from -drive, they're all QString.  The
     * visitor expects the former.
     */
    iv = qobject_input_visitor_new(crumpled_addr);
    visit_type_InetSocketAddress(iv, NULL, &inet, &local_error);
    if (local_error) {
        error_propagate(errp, local_error);
        goto out;
    }

out:
    QDECREF(addr);
    qobject_decref(crumpled_addr);
    visit_free(iv);
    return inet;
}
Exemplo n.º 15
0
Arquivo: rbd.c Projeto: CTU-IIG/qemu
static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts,
                                    Error **errp)
{
    Visitor *v;
    Error *local_err = NULL;

    /* Convert the remaining options into a QAPI object */
    v = qobject_input_visitor_new_flat_confused(options, errp);
    if (!v) {
        return -EINVAL;
    }

    visit_type_BlockdevOptionsRbd(v, NULL, opts, &local_err);
    visit_free(v);

    if (local_err) {
        error_propagate(errp, local_err);
        return -EINVAL;
    }

    return 0;
}
Exemplo n.º 16
0
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
                         Error **errp)
{
    BDRVRBDState *s = bs->opaque;
    BlockdevOptionsRbd *opts = NULL;
    Visitor *v;
    QObject *crumpled = NULL;
    const QDictEntry *e;
    Error *local_err = NULL;
    const char *filename;
    char *keypairs, *secretid;
    int r;

    /* If we are given a filename, parse the filename, with precedence given to
     * filename encoded options */
    filename = qdict_get_try_str(options, "filename");
    if (filename) {
        warn_report("'filename' option specified. "
                    "This is an unsupported option, and may be deprecated "
                    "in the future");
        qemu_rbd_parse_filename(filename, options, &local_err);
        qdict_del(options, "filename");
        if (local_err) {
            error_propagate(errp, local_err);
            return -EINVAL;
        }
    }

    keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs"));
    if (keypairs) {
        qdict_del(options, "=keyvalue-pairs");
    }

    secretid = g_strdup(qdict_get_try_str(options, "password-secret"));
    if (secretid) {
        qdict_del(options, "password-secret");
    }

    /* Convert the remaining options into a QAPI object */
    crumpled = qdict_crumple(options, errp);
    if (crumpled == NULL) {
        r = -EINVAL;
        goto out;
    }

    v = qobject_input_visitor_new_keyval(crumpled);
    visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err);
    visit_free(v);
    qobject_unref(crumpled);

    if (local_err) {
        error_propagate(errp, local_err);
        r = -EINVAL;
        goto out;
    }

    /* Remove the processed options from the QDict (the visitor processes
     * _all_ options in the QDict) */
    while ((e = qdict_first(options))) {
        qdict_del(options, e->key);
    }

    r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts,
                         !(flags & BDRV_O_NOCACHE), keypairs, secretid, errp);
    if (r < 0) {
        goto out;
    }

    s->snap = g_strdup(opts->snapshot);
    s->image_name = g_strdup(opts->image);

    /* rbd_open is always r/w */
    r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap);
    if (r < 0) {
        error_setg_errno(errp, -r, "error reading header from %s",
                         s->image_name);
        goto failed_open;
    }

    /* If we are using an rbd snapshot, we must be r/o, otherwise
     * leave as-is */
    if (s->snap != NULL) {
        if (!bdrv_is_read_only(bs)) {
            error_report("Opening rbd snapshots without an explicit "
                         "read-only=on option is deprecated. Future versions "
                         "will refuse to open the image instead of "
                         "automatically marking the image read-only.");
            r = bdrv_set_read_only(bs, true, &local_err);
            if (r < 0) {
                error_propagate(errp, local_err);
                goto failed_open;
            }
        }
    }

    r = 0;
    goto out;

failed_open:
    rados_ioctx_destroy(s->io_ctx);
    g_free(s->snap);
    g_free(s->image_name);
    rados_shutdown(s->cluster);
out:
    qapi_free_BlockdevOptionsRbd(opts);
    g_free(keypairs);
    g_free(secretid);
    return r;
}
Exemplo n.º 17
0
void acpi_table_add(const QemuOpts *opts, Error **errp)
{
    AcpiTableOptions *hdrs = NULL;
    Error *err = NULL;
    char **pathnames = NULL;
    char **cur;
    size_t bloblen = 0;
    char unsigned *blob = NULL;

    {
        Visitor *v;

        v = opts_visitor_new(opts);
        visit_type_AcpiTableOptions(v, NULL, &hdrs, &err);
        visit_free(v);
    }

    if (err) {
        goto out;
    }
    if (hdrs->has_file == hdrs->has_data) {
        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
        goto out;
    }

    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
    if (pathnames == NULL || pathnames[0] == NULL) {
        error_setg(&err, "'-acpitable' requires at least one pathname");
        goto out;
    }

    /* now read in the data files, reallocating buffer as needed */
    for (cur = pathnames; *cur; ++cur) {
        int fd = open(*cur, O_RDONLY | O_BINARY);

        if (fd < 0) {
            error_setg(&err, "can't open file %s: %s", *cur, strerror(errno));
            goto out;
        }

        for (;;) {
            char unsigned data[8192];
            ssize_t r;

            r = read(fd, data, sizeof data);
            if (r == 0) {
                break;
            } else if (r > 0) {
                blob = g_realloc(blob, bloblen + r);
                memcpy(blob + bloblen, data, r);
                bloblen += r;
            } else if (errno != EINTR) {
                error_setg(&err, "can't read file %s: %s",
                           *cur, strerror(errno));
                close(fd);
                goto out;
            }
        }

        close(fd);
    }

    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);

out:
    g_free(blob);
    g_strfreev(pathnames);
    qapi_free_AcpiTableOptions(hdrs);

    error_propagate(errp, err);
}
Exemplo n.º 18
0
static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
                                Error **errp)
{
    const QDict *qdict = NULL;
    const QDictEntry *e;
    Visitor *visitor;
    ObjectClass *oc;
    S390CPU *cpu;
    Object *obj;

    if (info->props) {
        qdict = qobject_to_qdict(info->props);
        if (!qdict) {
            error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
            return;
        }
    }

    oc = cpu_class_by_name(TYPE_S390_CPU, info->name);
    if (!oc) {
        error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name);
        return;
    }
    if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) {
        error_setg(errp, "The CPU definition '%s' requires KVM", info->name);
        return;
    }
    obj = object_new(object_class_get_name(oc));
    cpu = S390_CPU(obj);

    if (!cpu->model) {
        error_setg(errp, "Details about the host CPU model are not available, "
                         "it cannot be used.");
        object_unref(obj);
        return;
    }

    if (qdict) {
        visitor = qobject_input_visitor_new(info->props);
        visit_start_struct(visitor, NULL, NULL, 0, errp);
        if (*errp) {
            object_unref(obj);
            return;
        }
        for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
            object_property_set(obj, visitor, e->key, errp);
            if (*errp) {
                break;
            }
        }
        if (!*errp) {
            visit_check_struct(visitor, errp);
        }
        visit_end_struct(visitor, NULL);
        visit_free(visitor);
        if (*errp) {
            object_unref(obj);
            return;
        }
    }

    /* copy the model and throw the cpu away */
    memcpy(model, cpu->model, sizeof(*model));
    object_unref(obj);
}