bdev/rbd:Add uuid to bdev_rbd_create to support multipath when rbd used as ns of nvmf target

This patch is to solve the issue that two nvmf target connect the same rbd image and used for multipath.
The scenario is host wants to access the same rbd image via two gateways, host and gateways are working as nvmf ini and tgt, and two gateways connect with the rbd image, io can switch to another gateway once one is broken. The targets of multipath must have the same uuid, so this patch add a new argument for bdev_rbd_create, like malloc dev.

Signed-off-by: tanlong <948985618@qq.com>
Change-Id: I593fedb6c5d94f625f1b331fdc40e2db488f7fb7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9935
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
tanlong 2021-10-19 04:56:18 -04:00 committed by Jim Harris
parent 76e1ac04c7
commit 8a154b2c0d
6 changed files with 40 additions and 7 deletions

View File

@ -3569,6 +3569,7 @@ rbd_name | Required | string | Image name
block_size | Required | number | Block size
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
If no config is specified, Ceph configuration files must exist with
all relevant settings for accessing the pool. If a config map is
@ -3601,7 +3602,8 @@ Example request with `key` from `/etc/ceph/ceph.client.admin.keyring`:
"mon_host": "192.168.7.1:6789,192.168.7.2:6789",
"key": "AQDwf8db7zR1GRAA5k7NKXjS5S5V4mntwUDnGQ==",
}
"block_size": 4096
"block_size": 4096,
"uuid": "76210ea4-7920-40a0-a07b-8992a7443c76"
},
"jsonrpc": "2.0",
"method": "bdev_rbd_create",

View File

@ -852,6 +852,7 @@ static void
bdev_rbd_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w)
{
struct bdev_rbd *rbd = bdev->ctxt;
char uuid_str[SPDK_UUID_STRING_LEN];
spdk_json_write_object_begin(w);
@ -877,6 +878,9 @@ bdev_rbd_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w
spdk_json_write_object_end(w);
}
spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid);
spdk_json_write_named_string(w, "uuid", uuid_str);
spdk_json_write_object_end(w);
spdk_json_write_object_end(w);
@ -1128,7 +1132,8 @@ bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
const char *const *config,
const char *rbd_name,
uint32_t block_size,
const char *cluster_name)
const char *cluster_name,
const struct spdk_uuid *uuid)
{
struct bdev_rbd *rbd;
int ret;
@ -1189,6 +1194,12 @@ bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *user_id,
return ret;
}
if (uuid) {
rbd->disk.uuid = *uuid;
} else {
spdk_uuid_generate(&rbd->disk.uuid);
}
if (name) {
rbd->disk.name = strdup(name);
} else {

View File

@ -54,7 +54,7 @@ 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 char *rbd_name, uint32_t block_size, const char *cluster_name, const struct spdk_uuid *uuid);
/**
* Delete rbd bdev.
*

View File

@ -33,6 +33,7 @@
#include "bdev_rbd.h"
#include "spdk/util.h"
#include "spdk/uuid.h"
#include "spdk/string.h"
#include "spdk/log.h"
@ -44,6 +45,7 @@ struct rpc_create_rbd {
uint32_t block_size;
char **config;
char *cluster_name;
char *uuid;
};
static void
@ -55,6 +57,7 @@ free_rpc_create_rbd(struct rpc_create_rbd *req)
free(req->rbd_name);
bdev_rbd_free_config(req->config);
free(req->cluster_name);
free(req->uuid);
}
static int
@ -106,7 +109,8 @@ static const struct spdk_json_object_decoder rpc_create_rbd_decoders[] = {
{"rbd_name", offsetof(struct rpc_create_rbd, rbd_name), spdk_json_decode_string},
{"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}
{"cluster_name", offsetof(struct rpc_create_rbd, cluster_name), spdk_json_decode_string, true},
{"uuid", offsetof(struct rpc_create_rbd, uuid), spdk_json_decode_string, true}
};
static void
@ -117,6 +121,8 @@ rpc_bdev_rbd_create(struct spdk_jsonrpc_request *request,
struct spdk_json_write_ctx *w;
struct spdk_bdev *bdev;
int rc = 0;
struct spdk_uuid *uuid = NULL;
struct spdk_uuid decoded_uuid;
if (spdk_json_decode_object(params, rpc_create_rbd_decoders,
SPDK_COUNTOF(rpc_create_rbd_decoders),
@ -127,10 +133,19 @@ rpc_bdev_rbd_create(struct spdk_jsonrpc_request *request,
goto cleanup;
}
if (req.uuid) {
if (spdk_uuid_parse(&decoded_uuid, req.uuid)) {
spdk_jsonrpc_send_error_response(request, -EINVAL,
"Failed to parse bdev UUID");
goto cleanup;
}
uuid = &decoded_uuid;
}
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.block_size, req.cluster_name, uuid);
if (rc) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup;

View File

@ -700,7 +700,8 @@ if __name__ == "__main__":
pool_name=args.pool_name,
rbd_name=args.rbd_name,
block_size=args.block_size,
cluster_name=args.cluster_name))
cluster_name=args.cluster_name,
uuid=args.uuid))
p = subparsers.add_parser('bdev_rbd_create', aliases=['construct_rbd_bdev'],
help='Add a bdev with ceph rbd backend')
@ -712,6 +713,7 @@ if __name__ == "__main__":
p.add_argument('rbd_name', help='rbd image name')
p.add_argument('block_size', help='rbd block size', type=int)
p.add_argument('-c', '--cluster-name', help="cluster name to identify the Rados cluster", required=False)
p.add_argument('-u', '--uuid', help="UUID of the bdev")
p.set_defaults(func=bdev_rbd_create)
def bdev_rbd_delete(args):

View File

@ -733,7 +733,7 @@ def bdev_rbd_get_clusters_info(client, name):
@deprecated_alias('construct_rbd_bdev')
def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user=None, config=None, cluster_name=None):
def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user=None, config=None, cluster_name=None, uuid=None):
"""Create a Ceph RBD block device.
Args:
@ -744,6 +744,7 @@ def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user=Non
user: Ceph user name (optional)
config: map of config keys to values (optional)
cluster_name: Name to identify Rados cluster (optional)
uuid: UUID of block device (optional)
Returns:
Name of created block device.
@ -762,6 +763,8 @@ def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user=Non
params['config'] = config
if cluster_name is not None:
params['cluster_name'] = cluster_name
if uuid is not None:
params['uuid'] = uuid
return client.call('bdev_rbd_create', params)