diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index d1137cf01..b1125053e 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -915,7 +915,7 @@ raid_bdev_init(void) */ int raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs, - enum raid_level level, struct raid_bdev **raid_bdev_out) + enum raid_level level, struct raid_bdev **raid_bdev_out, const struct spdk_uuid *uuid) { struct raid_bdev *raid_bdev; struct spdk_bdev *raid_bdev_gen; @@ -1020,6 +1020,10 @@ raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs, raid_bdev_gen->module = &g_raid_if; raid_bdev_gen->write_cache = 0; + if (uuid) { + spdk_uuid_copy(&raid_bdev_gen->uuid, uuid); + } + TAILQ_INSERT_TAIL(&g_raid_bdev_list, raid_bdev, global_link); *raid_bdev_out = raid_bdev; diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index a140bb7d8..8e55e1e98 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -7,6 +7,7 @@ #define SPDK_BDEV_RAID_INTERNAL_H #include "spdk/bdev_module.h" +#include "spdk/uuid.h" enum raid_level { INVALID_RAID_LEVEL = -1, @@ -167,7 +168,7 @@ extern struct raid_all_tailq g_raid_bdev_list; typedef void (*raid_bdev_destruct_cb)(void *cb_ctx, int rc); int raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs, - enum raid_level level, struct raid_bdev **raid_bdev_out); + enum raid_level level, struct raid_bdev **raid_bdev_out, const struct spdk_uuid *uuid); void raid_bdev_delete(struct raid_bdev *raid_bdev, raid_bdev_destruct_cb cb_fn, void *cb_ctx); int raid_bdev_add_base_device(struct raid_bdev *raid_bdev, const char *name, uint8_t slot); struct raid_bdev *raid_bdev_find_by_name(const char *name); diff --git a/module/bdev/raid/bdev_raid_rpc.c b/module/bdev/raid/bdev_raid_rpc.c index 7def735e4..bc1fb9af2 100644 --- a/module/bdev/raid/bdev_raid_rpc.c +++ b/module/bdev/raid/bdev_raid_rpc.c @@ -127,6 +127,9 @@ struct rpc_bdev_raid_create { /* Base bdevs information */ struct rpc_bdev_raid_create_base_bdevs base_bdevs; + + /* UUID for this raid bdev */ + char *uuid; }; /* @@ -143,6 +146,7 @@ free_rpc_bdev_raid_create(struct rpc_bdev_raid_create *req) size_t i; free(req->name); + free(req->uuid); for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) { free(req->base_bdevs.base_bdevs[i]); } @@ -191,6 +195,7 @@ static const struct spdk_json_object_decoder rpc_bdev_raid_create_decoders[] = { {"strip_size_kb", offsetof(struct rpc_bdev_raid_create, strip_size_kb), spdk_json_decode_uint32, true}, {"raid_level", offsetof(struct rpc_bdev_raid_create, level), decode_raid_level}, {"base_bdevs", offsetof(struct rpc_bdev_raid_create, base_bdevs), decode_base_bdevs}, + {"uuid", offsetof(struct rpc_bdev_raid_create, uuid), spdk_json_decode_string, true}, }; /* @@ -211,6 +216,8 @@ rpc_bdev_raid_create(struct spdk_jsonrpc_request *request, struct raid_bdev *raid_bdev; int rc; size_t i; + struct spdk_uuid *uuid = NULL; + struct spdk_uuid decoded_uuid; if (spdk_json_decode_object(params, rpc_bdev_raid_create_decoders, SPDK_COUNTOF(rpc_bdev_raid_create_decoders), @@ -220,8 +227,17 @@ rpc_bdev_raid_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, SPDK_JSONRPC_ERROR_INVALID_PARAMS, + "Failed to parse bdev UUID"); + goto cleanup; + } + uuid = &decoded_uuid; + } + rc = raid_bdev_create(req.name, req.strip_size_kb, req.base_bdevs.num_base_bdevs, - req.level, &raid_bdev); + req.level, &raid_bdev, uuid); if (rc != 0) { spdk_jsonrpc_send_error_response_fmt(request, rc, "Failed to create RAID bdev %s: %s", diff --git a/python/spdk/rpc/bdev.py b/python/spdk/rpc/bdev.py index 9bfbd201d..571634c06 100644 --- a/python/spdk/rpc/bdev.py +++ b/python/spdk/rpc/bdev.py @@ -387,7 +387,7 @@ def bdev_raid_get_bdevs(client, category): return client.call('bdev_raid_get_bdevs', params) -def bdev_raid_create(client, name, raid_level, base_bdevs, strip_size=None, strip_size_kb=None): +def bdev_raid_create(client, name, raid_level, base_bdevs, strip_size=None, strip_size_kb=None, uuid=None): """Create raid bdev. Either strip size arg will work but one is required. Args: @@ -396,6 +396,7 @@ def bdev_raid_create(client, name, raid_level, base_bdevs, strip_size=None, stri strip_size_kb: strip size of raid bdev in KB, supported values like 8, 16, 32, 64, 128, 256, etc raid_level: raid level of raid bdev, supported values 0 base_bdevs: Space separated names of Nvme bdevs in double quotes, like "Nvme0n1 Nvme1n1 Nvme2n1" + uuid: UUID for this raid bdev (optional) Returns: None @@ -408,6 +409,9 @@ def bdev_raid_create(client, name, raid_level, base_bdevs, strip_size=None, stri if strip_size_kb: params['strip_size_kb'] = strip_size_kb + if uuid: + params['uuid'] = uuid + return client.call('bdev_raid_create', params) diff --git a/scripts/rpc.py b/scripts/rpc.py index 3fcb02552..44d2750c9 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2056,12 +2056,14 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse name=args.name, strip_size_kb=args.strip_size_kb, raid_level=args.raid_level, - base_bdevs=base_bdevs) + base_bdevs=base_bdevs, + uuid=args.uuid) p = subparsers.add_parser('bdev_raid_create', help='Create new raid bdev') p.add_argument('-n', '--name', help='raid bdev name', required=True) p.add_argument('-z', '--strip-size-kb', help='strip size in KB', type=int) p.add_argument('-r', '--raid-level', help='raid level, raid0, raid1 and a special level concat are supported', required=True) p.add_argument('-b', '--base-bdevs', help='base bdevs name, whitespace separated list in quotes', required=True) + p.add_argument('--uuid', help='UUID for this raid bdev', required=False) p.set_defaults(func=bdev_raid_create) def bdev_raid_delete(args):