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:
parent
76e1ac04c7
commit
8a154b2c0d
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user