Commit cd93e001 authored by Gil Bregman's avatar Gil Bregman Committed by Tomasz Zawadzki
Browse files

bdev/rbd: Implement read-only rbd bdevs.



Change-Id: I5f6b2a342e25e2c0c2197dbd16b7376a30d8b174
Signed-off-by: default avatarGil Bregman <gbregman@il.ibm.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/26101


Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
Reviewed-by: default avatarChangpeng Liu <changpeliu@tencent.com>
parent b98fa9f9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5463,6 +5463,7 @@ for SPDK to get up to your projections.
 config       | Optional   | string map | Explicit librados configuration
 cluster_name | Optional   | string     | Rados cluster object name created in this module.
 uuid         | Optional   | string     | UUID of new bdev
 read_only    | Optional   | boolean    | set rbd bdev as read-only

#### Response

+15 −5
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct bdev_rbd {
	struct spdk_bdev_io *reset_bdev_io;

	uint64_t rbd_watch_handle;
	bool rbd_read_only;
};

struct bdev_rbd_io_channel {
@@ -426,7 +427,12 @@ bdev_rbd_init_context(void *arg)
	}

	assert(io_ctx != NULL);
	if (rbd->rbd_read_only) {
		SPDK_DEBUGLOG(bdev_rbd, "Will open RBD image %s/%s as read-only\n", rbd->pool_name, rbd->rbd_name);
		rc = rbd_open_read_only(*io_ctx, rbd->rbd_name, &rbd->image, NULL);
	} else {
		rc = rbd_open(*io_ctx, rbd->rbd_name, &rbd->image, NULL);
	}
	if (rc < 0) {
		SPDK_ERRLOG("Failed to open specified rbd device\n");
		return NULL;
@@ -794,18 +800,20 @@ bdev_rbd_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io
static bool
bdev_rbd_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
{
	struct bdev_rbd *rbd = (struct bdev_rbd *)ctx;

	switch (io_type) {
	case SPDK_BDEV_IO_TYPE_READ:
	case SPDK_BDEV_IO_TYPE_WRITE:
	case SPDK_BDEV_IO_TYPE_UNMAP:
	case SPDK_BDEV_IO_TYPE_FLUSH:
	case SPDK_BDEV_IO_TYPE_RESET:
		return true;
	case SPDK_BDEV_IO_TYPE_WRITE:
	case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
#ifdef LIBRBD_SUPPORTS_COMPARE_AND_WRITE_IOVEC
	case SPDK_BDEV_IO_TYPE_COMPARE_AND_WRITE:
#endif
		return true;

		return !rbd->rbd_read_only;
	default:
		return false;
	}
@@ -1282,7 +1290,8 @@ bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
		const char *rbd_name,
		uint32_t block_size,
		const char *cluster_name,
		const struct spdk_uuid *uuid)
		const struct spdk_uuid *uuid,
		bool read_only)
{
	struct bdev_rbd *rbd;
	int ret;
@@ -1329,6 +1338,7 @@ bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
		return -ENOMEM;
	}

	rbd->rbd_read_only = read_only;
	ret = bdev_rbd_init(rbd);
	if (ret < 0) {
		bdev_rbd_free(rbd);
+2 −1
Original line number Diff line number Diff line
@@ -28,7 +28,8 @@ typedef void (*spdk_delete_rbd_complete)(void *cb_arg, int bdeverrno);
int bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
		    const char *pool_name,
		    const char *const *config,
		    const char *rbd_name, uint32_t block_size, const char *cluster_name, const struct spdk_uuid *uuid);
		    const char *rbd_name, uint32_t block_size, const char *cluster_name,
		    const struct spdk_uuid *uuid, bool read_only);
/**
 * Delete rbd bdev.
 *
+4 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ struct rpc_create_rbd {
	char **config;
	char *cluster_name;
	struct spdk_uuid uuid;
	bool read_only;
};

static void
@@ -81,7 +82,8 @@ static const struct spdk_json_object_decoder rpc_create_rbd_decoders[] = {
	{"block_size", offsetof(struct rpc_create_rbd, block_size), spdk_json_decode_uint32},
	{"config", offsetof(struct rpc_create_rbd, config), bdev_rbd_decode_config, true},
	{"cluster_name", offsetof(struct rpc_create_rbd, cluster_name), spdk_json_decode_string, true},
	{"uuid", offsetof(struct rpc_create_rbd, uuid), spdk_json_decode_uuid, true}
	{"uuid", offsetof(struct rpc_create_rbd, uuid), spdk_json_decode_uuid, true},
	{"read_only", offsetof(struct rpc_create_rbd, read_only), spdk_json_decode_bool, true}
};

static void
@@ -105,7 +107,7 @@ rpc_bdev_rbd_create(struct spdk_jsonrpc_request *request,
	rc = bdev_rbd_create(&bdev, req.name, req.user_id, req.pool_name,
			     (const char *const *)req.config,
			     req.rbd_name,
			     req.block_size, req.cluster_name, &req.uuid);
			     req.block_size, req.cluster_name, &req.uuid, req.read_only);
	if (rc) {
		spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
		goto cleanup;
+5 −1
Original line number Diff line number Diff line
@@ -1057,7 +1057,8 @@ def bdev_rbd_get_clusters_info(client, name=None):
    return client.call('bdev_rbd_get_clusters_info', params)


def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user_id=None, config=None, cluster_name=None, uuid=None):
def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user_id=None, config=None, cluster_name=None,
                    uuid=None, read_only=None):
    """Create a Ceph RBD block device.
    Args:
        pool_name: Ceph RBD pool name
@@ -1068,6 +1069,7 @@ def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user_id=
        config: map of config keys to values (optional)
        cluster_name: Name to identify Rados cluster (optional)
        uuid: UUID of block device (optional)
        read_only: set block device to read-only (optional)
    Returns:
        Name of created block device.
    """
@@ -1087,6 +1089,8 @@ def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user_id=
        print("WARNING:bdev_rbd_create should be used with specifying -c to have a cluster name after bdev_rbd_register_cluster.")
    if uuid is not None:
        params['uuid'] = uuid
    if read_only is not None:
        params['read_only'] = read_only
    return client.call('bdev_rbd_create', params)


Loading