Esempio n. 1
0
File: rbd.c Progetto: nikunjad/qemu
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
                         Error **errp)
{
    BDRVRBDState *s = bs->opaque;
    const char *pool, *snap, *conf, *user, *image_name, *keypairs;
    const char *secretid, *filename;
    QemuOpts *opts;
    Error *local_err = NULL;
    char *mon_host = NULL;
    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);
        if (local_err) {
            r = -EINVAL;
            error_propagate(errp, local_err);
            goto exit;
        }
    }

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        r = -EINVAL;
        goto failed_opts;
    }

    mon_host = qemu_rbd_mon_host(options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        r = -EINVAL;
        goto failed_opts;
    }

    secretid = qemu_opt_get(opts, "password-secret");

    pool           = qemu_opt_get(opts, "pool");
    conf           = qemu_opt_get(opts, "conf");
    snap           = qemu_opt_get(opts, "snapshot");
    user           = qemu_opt_get(opts, "user");
    image_name     = qemu_opt_get(opts, "image");
    keypairs       = qemu_opt_get(opts, "=keyvalue-pairs");

    if (!pool || !image_name) {
        error_setg(errp, "Parameters 'pool' and 'image' are required");
        r = -EINVAL;
        goto failed_opts;
    }

    r = rados_create(&s->cluster, user);
    if (r < 0) {
        error_setg_errno(errp, -r, "error initializing");
        goto failed_opts;
    }

    s->snap = g_strdup(snap);
    s->image_name = g_strdup(image_name);

    /* try default location when conf=NULL, but ignore failure */
    r = rados_conf_read_file(s->cluster, conf);
    if (conf && r < 0) {
        error_setg_errno(errp, -r, "error reading conf file %s", conf);
        goto failed_shutdown;
    }

    r = qemu_rbd_set_keypairs(s->cluster, keypairs, errp);
    if (r < 0) {
        goto failed_shutdown;
    }

    if (mon_host) {
        r = rados_conf_set(s->cluster, "mon_host", mon_host);
        if (r < 0) {
            goto failed_shutdown;
        }
    }

    if (qemu_rbd_set_auth(s->cluster, secretid, errp) < 0) {
        r = -EIO;
        goto failed_shutdown;
    }

    /*
     * Fallback to more conservative semantics if setting cache
     * options fails. Ignore errors from setting rbd_cache because the
     * only possible error is that the option does not exist, and
     * librbd defaults to no caching. If write through caching cannot
     * be set up, fall back to no caching.
     */
    if (flags & BDRV_O_NOCACHE) {
        rados_conf_set(s->cluster, "rbd_cache", "false");
    } else {
        rados_conf_set(s->cluster, "rbd_cache", "true");
    }

    r = rados_connect(s->cluster);
    if (r < 0) {
        error_setg_errno(errp, -r, "error connecting");
        goto failed_shutdown;
    }

    r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
    if (r < 0) {
        error_setg_errno(errp, -r, "error opening pool %s", pool);
        goto failed_shutdown;
    }

    /* 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;
            }
        }
    }

    qemu_opts_del(opts);
    return 0;

failed_open:
    rados_ioctx_destroy(s->io_ctx);
failed_shutdown:
    rados_shutdown(s->cluster);
    g_free(s->snap);
    g_free(s->image_name);
failed_opts:
    qemu_opts_del(opts);
    g_free(mon_host);
exit:
    return r;
}
Esempio n. 2
0
File: rbd.c Progetto: nikunjad/qemu
static int coroutine_fn qemu_rbd_co_create_opts(const char *filename,
                                                QemuOpts *opts,
                                                Error **errp)
{
    Error *local_err = NULL;
    int64_t bytes = 0;
    int64_t objsize;
    int obj_order = 0;
    const char *pool, *image_name, *conf, *user, *keypairs;
    const char *secretid;
    rados_t cluster;
    rados_ioctx_t io_ctx;
    QDict *options = NULL;
    int ret = 0;

    secretid = qemu_opt_get(opts, "password-secret");

    /* Read out options */
    bytes = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
                     BDRV_SECTOR_SIZE);
    objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
    if (objsize) {
        if ((objsize - 1) & objsize) {    /* not a power of 2? */
            error_setg(errp, "obj size needs to be power of 2");
            ret = -EINVAL;
            goto exit;
        }
        if (objsize < 4096) {
            error_setg(errp, "obj size too small");
            ret = -EINVAL;
            goto exit;
        }
        obj_order = ctz32(objsize);
    }

    options = qdict_new();
    qemu_rbd_parse_filename(filename, options, &local_err);
    if (local_err) {
        ret = -EINVAL;
        error_propagate(errp, local_err);
        goto exit;
    }

    /*
     * Caution: while qdict_get_try_str() is fine, getting non-string
     * types would require more care.  When @options come from -blockdev
     * or blockdev_add, its members are typed according to the QAPI
     * schema, but when they come from -drive, they're all QString.
     */
    pool       = qdict_get_try_str(options, "pool");
    conf       = qdict_get_try_str(options, "conf");
    user       = qdict_get_try_str(options, "user");
    image_name = qdict_get_try_str(options, "image");
    keypairs   = qdict_get_try_str(options, "=keyvalue-pairs");

    ret = rados_create(&cluster, user);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error initializing");
        goto exit;
    }

    /* try default location when conf=NULL, but ignore failure */
    ret = rados_conf_read_file(cluster, conf);
    if (conf && ret < 0) {
        error_setg_errno(errp, -ret, "error reading conf file %s", conf);
        ret = -EIO;
        goto shutdown;
    }

    ret = qemu_rbd_set_keypairs(cluster, keypairs, errp);
    if (ret < 0) {
        ret = -EIO;
        goto shutdown;
    }

    if (qemu_rbd_set_auth(cluster, secretid, errp) < 0) {
        ret = -EIO;
        goto shutdown;
    }

    ret = rados_connect(cluster);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error connecting");
        goto shutdown;
    }

    ret = rados_ioctx_create(cluster, pool, &io_ctx);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error opening pool %s", pool);
        goto shutdown;
    }

    ret = rbd_create(io_ctx, image_name, bytes, &obj_order);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error rbd create");
    }

    rados_ioctx_destroy(io_ctx);

shutdown:
    rados_shutdown(cluster);

exit:
    QDECREF(options);
    return ret;
}
Esempio n. 3
0
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
                         Error **errp)
{
    BDRVRBDState *s = bs->opaque;
    const char *pool, *snap, *conf, *clientname, *name, *keypairs;
    const char *secretid;
    QemuOpts *opts;
    Error *local_err = NULL;
    char *mon_host = NULL;
    int r;

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        r = -EINVAL;
        goto failed_opts;
    }

    mon_host = qemu_rbd_mon_host(options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        r = -EINVAL;
        goto failed_opts;
    }

    secretid = qemu_opt_get(opts, "password-secret");

    pool           = qemu_opt_get(opts, "pool");
    conf           = qemu_opt_get(opts, "conf");
    snap           = qemu_opt_get(opts, "snapshot");
    clientname     = qemu_opt_get(opts, "user");
    name           = qemu_opt_get(opts, "image");
    keypairs       = qemu_opt_get(opts, "=keyvalue-pairs");

    if (!pool || !name) {
        error_setg(errp, "Parameters 'pool' and 'image' are required");
        r = -EINVAL;
        goto failed_opts;
    }

    r = rados_create(&s->cluster, clientname);
    if (r < 0) {
        error_setg_errno(errp, -r, "error initializing");
        goto failed_opts;
    }

    s->snap = g_strdup(snap);
    s->name = g_strdup(name);

    /* try default location when conf=NULL, but ignore failure */
    r = rados_conf_read_file(s->cluster, conf);
    if (conf && r < 0) {
        error_setg_errno(errp, -r, "error reading conf file %s", conf);
        goto failed_shutdown;
    }

    r = qemu_rbd_set_keypairs(s->cluster, keypairs, errp);
    if (r < 0) {
        goto failed_shutdown;
    }

    if (mon_host) {
        r = rados_conf_set(s->cluster, "mon_host", mon_host);
        if (r < 0) {
            goto failed_shutdown;
        }
    }

    if (qemu_rbd_set_auth(s->cluster, secretid, errp) < 0) {
        r = -EIO;
        goto failed_shutdown;
    }

    /*
     * Fallback to more conservative semantics if setting cache
     * options fails. Ignore errors from setting rbd_cache because the
     * only possible error is that the option does not exist, and
     * librbd defaults to no caching. If write through caching cannot
     * be set up, fall back to no caching.
     */
    if (flags & BDRV_O_NOCACHE) {
        rados_conf_set(s->cluster, "rbd_cache", "false");
    } else {
        rados_conf_set(s->cluster, "rbd_cache", "true");
    }

    r = rados_connect(s->cluster);
    if (r < 0) {
        error_setg_errno(errp, -r, "error connecting");
        goto failed_shutdown;
    }

    r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
    if (r < 0) {
        error_setg_errno(errp, -r, "error opening pool %s", pool);
        goto failed_shutdown;
    }

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

    bs->read_only = (s->snap != NULL);

    qemu_opts_del(opts);
    return 0;

failed_open:
    rados_ioctx_destroy(s->io_ctx);
failed_shutdown:
    rados_shutdown(s->cluster);
    g_free(s->snap);
    g_free(s->name);
failed_opts:
    qemu_opts_del(opts);
    g_free(mon_host);
    return r;
}
Esempio n. 4
0
File: rbd.c Progetto: CTU-IIG/qemu
static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
                            BlockdevOptionsRbd *opts, bool cache,
                            const char *keypairs, const char *secretid,
                            Error **errp)
{
    char *mon_host = NULL;
    Error *local_err = NULL;
    int r;

    if (secretid) {
        if (opts->key_secret) {
            error_setg(errp,
                       "Legacy 'password-secret' clashes with 'key-secret'");
            return -EINVAL;
        }
        opts->key_secret = g_strdup(secretid);
        opts->has_key_secret = true;
    }

    mon_host = qemu_rbd_mon_host(opts, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        r = -EINVAL;
        goto failed_opts;
    }

    r = rados_create(cluster, opts->user);
    if (r < 0) {
        error_setg_errno(errp, -r, "error initializing");
        goto failed_opts;
    }

    /* try default location when conf=NULL, but ignore failure */
    r = rados_conf_read_file(*cluster, opts->conf);
    if (opts->has_conf && r < 0) {
        error_setg_errno(errp, -r, "error reading conf file %s", opts->conf);
        goto failed_shutdown;
    }

    r = qemu_rbd_set_keypairs(*cluster, keypairs, errp);
    if (r < 0) {
        goto failed_shutdown;
    }

    if (mon_host) {
        r = rados_conf_set(*cluster, "mon_host", mon_host);
        if (r < 0) {
            goto failed_shutdown;
        }
    }

    r = qemu_rbd_set_auth(*cluster, opts, errp);
    if (r < 0) {
        goto failed_shutdown;
    }

    /*
     * Fallback to more conservative semantics if setting cache
     * options fails. Ignore errors from setting rbd_cache because the
     * only possible error is that the option does not exist, and
     * librbd defaults to no caching. If write through caching cannot
     * be set up, fall back to no caching.
     */
    if (cache) {
        rados_conf_set(*cluster, "rbd_cache", "true");
    } else {
        rados_conf_set(*cluster, "rbd_cache", "false");
    }

    r = rados_connect(*cluster);
    if (r < 0) {
        error_setg_errno(errp, -r, "error connecting");
        goto failed_shutdown;
    }

    r = rados_ioctx_create(*cluster, opts->pool, io_ctx);
    if (r < 0) {
        error_setg_errno(errp, -r, "error opening pool %s", opts->pool);
        goto failed_shutdown;
    }

    return 0;

failed_shutdown:
    rados_shutdown(*cluster);
failed_opts:
    g_free(mon_host);
    return r;
}
Esempio n. 5
0
static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
{
    Error *local_err = NULL;
    int64_t bytes = 0;
    int64_t objsize;
    int obj_order = 0;
    const char *pool, *name, *conf, *clientname, *keypairs;
    const char *secretid;
    rados_t cluster;
    rados_ioctx_t io_ctx;
    QDict *options = NULL;
    int ret = 0;

    secretid = qemu_opt_get(opts, "password-secret");

    /* Read out options */
    bytes = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
                     BDRV_SECTOR_SIZE);
    objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
    if (objsize) {
        if ((objsize - 1) & objsize) {    /* not a power of 2? */
            error_setg(errp, "obj size needs to be power of 2");
            ret = -EINVAL;
            goto exit;
        }
        if (objsize < 4096) {
            error_setg(errp, "obj size too small");
            ret = -EINVAL;
            goto exit;
        }
        obj_order = ctz32(objsize);
    }

    options = qdict_new();
    qemu_rbd_parse_filename(filename, options, &local_err);
    if (local_err) {
        ret = -EINVAL;
        error_propagate(errp, local_err);
        goto exit;
    }

    pool       = qdict_get_try_str(options, "pool");
    conf       = qdict_get_try_str(options, "conf");
    clientname = qdict_get_try_str(options, "user");
    name       = qdict_get_try_str(options, "image");
    keypairs   = qdict_get_try_str(options, "=keyvalue-pairs");

    ret = rados_create(&cluster, clientname);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error initializing");
        goto exit;
    }

    /* try default location when conf=NULL, but ignore failure */
    ret = rados_conf_read_file(cluster, conf);
    if (conf && ret < 0) {
        error_setg_errno(errp, -ret, "error reading conf file %s", conf);
        ret = -EIO;
        goto shutdown;
    }

    ret = qemu_rbd_set_keypairs(cluster, keypairs, errp);
    if (ret < 0) {
        ret = -EIO;
        goto shutdown;
    }

    if (qemu_rbd_set_auth(cluster, secretid, errp) < 0) {
        ret = -EIO;
        goto shutdown;
    }

    ret = rados_connect(cluster);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error connecting");
        goto shutdown;
    }

    ret = rados_ioctx_create(cluster, pool, &io_ctx);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error opening pool %s", pool);
        goto shutdown;
    }

    ret = rbd_create(io_ctx, name, bytes, &obj_order);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "error rbd create");
    }

    rados_ioctx_destroy(io_ctx);

shutdown:
    rados_shutdown(cluster);

exit:
    QDECREF(options);
    return ret;
}