From 0404c306cb9892c18eecceab375cf9978738b9e0 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 25 Oct 2016 16:19:53 -0700 Subject: [PATCH] bdev: make construct RPCs return the bdev names When creating a bdev via the RPC interface, there was no way to know what name it was assigned (other than predicting it based on the numbering scheme). Change all of the relevant RPC interfaces to return an array of bdev names so they can be used to construct LUNs/subsystems dynamically in scripts. Change-Id: I8e03349bdc81afd3d69247396a20df5fcf050f40 Signed-off-by: Daniel Verkamp --- lib/bdev/aio/blockdev_aio.c | 10 +++++----- lib/bdev/aio/blockdev_aio.h | 2 +- lib/bdev/aio/blockdev_aio_rpc.c | 8 ++++++-- lib/bdev/malloc/blockdev_malloc.c | 10 +++++----- lib/bdev/malloc/blockdev_malloc.h | 4 ++-- lib/bdev/malloc/blockdev_malloc_rpc.c | 8 ++++++-- lib/bdev/nvme/blockdev_nvme.c | 16 ++++++++++++++-- lib/bdev/nvme/blockdev_nvme.h | 8 ++++++++ lib/bdev/nvme/blockdev_nvme_rpc.c | 8 ++++++-- lib/bdev/rbd/blockdev_rbd.c | 19 +++++++++---------- lib/bdev/rbd/blockdev_rbd.h | 7 +++++-- lib/bdev/rbd/blockdev_rbd_rpc.c | 8 ++++++-- scripts/rpc.py | 16 ++++++++++++---- test/iscsi_tgt/rpc_config/rpc_config.py | 9 +++------ 14 files changed, 88 insertions(+), 45 deletions(-) diff --git a/lib/bdev/aio/blockdev_aio.c b/lib/bdev/aio/blockdev_aio.c index 6b416142d..d360435bd 100644 --- a/lib/bdev/aio/blockdev_aio.c +++ b/lib/bdev/aio/blockdev_aio.c @@ -339,7 +339,7 @@ static void aio_free_disk(struct file_disk *fdisk) free(fdisk); } -struct file_disk * +struct spdk_bdev * create_aio_disk(char *fname) { struct file_disk *fdisk; @@ -375,7 +375,7 @@ create_aio_disk(char *fname) spdk_io_device_register(&fdisk->disk, blockdev_aio_create_cb, blockdev_aio_destroy_cb, sizeof(struct blockdev_aio_io_channel)); spdk_bdev_register(&fdisk->disk); - return fdisk; + return &fdisk->disk; error_return: blockdev_aio_close(fdisk); @@ -385,7 +385,7 @@ error_return: static int blockdev_aio_initialize(void) { - struct file_disk *fdisk; + struct spdk_bdev *bdev; int i; const char *val = NULL; char *file; @@ -410,9 +410,9 @@ static int blockdev_aio_initialize(void) return -1; } - fdisk = create_aio_disk(file); + bdev = create_aio_disk(file); - if (fdisk == NULL && !skip_missing) { + if (bdev == NULL && !skip_missing) { return -1; } } diff --git a/lib/bdev/aio/blockdev_aio.h b/lib/bdev/aio/blockdev_aio.h index 911584703..9da7f0c0f 100644 --- a/lib/bdev/aio/blockdev_aio.h +++ b/lib/bdev/aio/blockdev_aio.h @@ -69,6 +69,6 @@ struct file_disk { TAILQ_HEAD(, blockdev_aio_task) sync_completion_list; }; -struct file_disk *create_aio_disk(char *fname); +struct spdk_bdev *create_aio_disk(char *fname); #endif // SPDK_BLOCKDEV_AIO_H diff --git a/lib/bdev/aio/blockdev_aio_rpc.c b/lib/bdev/aio/blockdev_aio_rpc.c index 400e0b9d6..ba9112218 100644 --- a/lib/bdev/aio/blockdev_aio_rpc.c +++ b/lib/bdev/aio/blockdev_aio_rpc.c @@ -56,6 +56,7 @@ spdk_rpc_construct_aio_bdev(struct spdk_jsonrpc_server_conn *conn, { struct rpc_construct_aio req = {}; struct spdk_json_write_ctx *w; + struct spdk_bdev *bdev; if (spdk_json_decode_object(params, rpc_construct_aio_decoders, sizeof(rpc_construct_aio_decoders) / sizeof(*rpc_construct_aio_decoders), @@ -64,7 +65,8 @@ spdk_rpc_construct_aio_bdev(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - if (create_aio_disk(req.fname) == NULL) { + bdev = create_aio_disk(req.fname); + if (bdev == NULL) { goto invalid; } @@ -75,7 +77,9 @@ spdk_rpc_construct_aio_bdev(struct spdk_jsonrpc_server_conn *conn, } w = spdk_jsonrpc_begin_result(conn, id); - spdk_json_write_bool(w, true); + spdk_json_write_array_begin(w); + spdk_json_write_string(w, bdev->name); + spdk_json_write_array_end(w); spdk_jsonrpc_end_result(conn, w); return; diff --git a/lib/bdev/malloc/blockdev_malloc.c b/lib/bdev/malloc/blockdev_malloc.c index 23a5b062a..50441dae5 100644 --- a/lib/bdev/malloc/blockdev_malloc.c +++ b/lib/bdev/malloc/blockdev_malloc.c @@ -364,7 +364,7 @@ static const struct spdk_bdev_fn_table malloc_fn_table = { .get_io_channel = blockdev_malloc_get_io_channel, }; -struct malloc_disk *create_malloc_disk(uint64_t num_blocks, uint32_t block_size) +struct spdk_bdev *create_malloc_disk(uint64_t num_blocks, uint32_t block_size) { struct malloc_disk *mdisk; @@ -415,7 +415,7 @@ struct malloc_disk *create_malloc_disk(uint64_t num_blocks, uint32_t block_size) mdisk->next = g_malloc_disk_head; g_malloc_disk_head = mdisk; - return mdisk; + return &mdisk->disk; } static void free_malloc_disk(struct malloc_disk *mdisk) @@ -429,7 +429,7 @@ static int blockdev_malloc_initialize(void) struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Malloc"); int NumberOfLuns, LunSizeInMB, BlockSize, i; uint64_t size; - struct malloc_disk *mdisk; + struct spdk_bdev *bdev; if (sp != NULL) { NumberOfLuns = spdk_conf_section_get_intval(sp, "NumberOfLuns"); @@ -445,8 +445,8 @@ static int blockdev_malloc_initialize(void) } size = (uint64_t)LunSizeInMB * 1024 * 1024; for (i = 0; i < NumberOfLuns; i++) { - mdisk = create_malloc_disk(size / BlockSize, BlockSize); - if (mdisk == NULL) { + bdev = create_malloc_disk(size / BlockSize, BlockSize); + if (bdev == NULL) { SPDK_ERRLOG("Could not create malloc disk\n"); return EINVAL; } diff --git a/lib/bdev/malloc/blockdev_malloc.h b/lib/bdev/malloc/blockdev_malloc.h index ec207a1b5..f680129a2 100644 --- a/lib/bdev/malloc/blockdev_malloc.h +++ b/lib/bdev/malloc/blockdev_malloc.h @@ -36,8 +36,8 @@ #include -struct malloc_disk; +#include "spdk/bdev.h" -struct malloc_disk *create_malloc_disk(uint64_t num_blocks, uint32_t block_size); +struct spdk_bdev *create_malloc_disk(uint64_t num_blocks, uint32_t block_size); #endif /* SPDK_BLOCKDEV_MALLOC_H */ diff --git a/lib/bdev/malloc/blockdev_malloc_rpc.c b/lib/bdev/malloc/blockdev_malloc_rpc.c index 59a9a9799..77c62e295 100644 --- a/lib/bdev/malloc/blockdev_malloc_rpc.c +++ b/lib/bdev/malloc/blockdev_malloc_rpc.c @@ -52,6 +52,7 @@ spdk_rpc_construct_malloc_bdev(struct spdk_jsonrpc_server_conn *conn, { struct rpc_construct_malloc req = {}; struct spdk_json_write_ctx *w; + struct spdk_bdev *bdev; if (spdk_json_decode_object(params, rpc_construct_malloc_decoders, sizeof(rpc_construct_malloc_decoders) / sizeof(*rpc_construct_malloc_decoders), @@ -60,7 +61,8 @@ spdk_rpc_construct_malloc_bdev(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - if (create_malloc_disk(req.num_blocks, req.block_size) == NULL) { + bdev = create_malloc_disk(req.num_blocks, req.block_size); + if (bdev == NULL) { goto invalid; } @@ -69,7 +71,9 @@ spdk_rpc_construct_malloc_bdev(struct spdk_jsonrpc_server_conn *conn, } w = spdk_jsonrpc_begin_result(conn, id); - spdk_json_write_bool(w, true); + spdk_json_write_array_begin(w); + spdk_json_write_string(w, bdev->name); + spdk_json_write_array_end(w); spdk_jsonrpc_end_result(conn, w); return; diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index 503040106..17ad87b87 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -102,8 +102,6 @@ enum data_direction { BDEV_DISK_WRITE = 1 }; -#define NVME_MAX_BLOCKDEVS_PER_CONTROLLER 256 -#define NVME_MAX_BLOCKDEVS (NVME_MAX_BLOCKDEVS_PER_CONTROLLER * NVME_MAX_CONTROLLERS) static struct nvme_blockdev g_blockdev[NVME_MAX_BLOCKDEVS]; static int blockdev_index_max = 0; static int nvme_luns_per_ns = 1; @@ -430,13 +428,27 @@ blockdev_nvme_exist(struct nvme_probe_ctx *ctx) int spdk_bdev_nvme_create(struct nvme_probe_ctx *ctx) { + int prev_index_max, i; + if (blockdev_nvme_exist(ctx)) { return -1; } + prev_index_max = blockdev_index_max; + if (spdk_nvme_probe(ctx, probe_cb, attach_cb, NULL)) { return -1; } + + /* + * Report the new bdevs that were created in this call. + * There can be more than one bdev per NVMe controller since one bdev is created per namespace. + */ + ctx->num_created_bdevs = 0; + for (i = prev_index_max; i < blockdev_index_max; i++) { + ctx->created_bdevs[ctx->num_created_bdevs++] = &g_blockdev[i].disk; + } + return 0; } diff --git a/lib/bdev/nvme/blockdev_nvme.h b/lib/bdev/nvme/blockdev_nvme.h index 8f7a1e56e..048ed964e 100644 --- a/lib/bdev/nvme/blockdev_nvme.h +++ b/lib/bdev/nvme/blockdev_nvme.h @@ -35,14 +35,22 @@ #define SPDK_BLOCKDEV_NVME_H #include + +#include "spdk/bdev.h" #include "spdk/env.h" #define NVME_MAX_CONTROLLERS 16 +#define NVME_MAX_BLOCKDEVS_PER_CONTROLLER 256 +#define NVME_MAX_BLOCKDEVS (NVME_MAX_BLOCKDEVS_PER_CONTROLLER * NVME_MAX_CONTROLLERS) struct nvme_probe_ctx { int controllers_remaining; int num_whitelist_controllers; struct spdk_pci_addr whitelist[NVME_MAX_CONTROLLERS]; + + /* Filled by spdk_bdev_nvme_create() with the bdevs that were added */ + int num_created_bdevs; + struct spdk_bdev *created_bdevs[NVME_MAX_BLOCKDEVS]; }; int diff --git a/lib/bdev/nvme/blockdev_nvme_rpc.c b/lib/bdev/nvme/blockdev_nvme_rpc.c index 139505b94..8e68388d0 100644 --- a/lib/bdev/nvme/blockdev_nvme_rpc.c +++ b/lib/bdev/nvme/blockdev_nvme_rpc.c @@ -58,7 +58,7 @@ spdk_rpc_construct_nvme_bdev(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_write_ctx *w; struct nvme_probe_ctx ctx = {}; unsigned int domain, bus, dev, func; - int rc; + int rc, i; if (spdk_json_decode_object(params, rpc_construct_nvme_decoders, sizeof(rpc_construct_nvme_decoders) / sizeof(*rpc_construct_nvme_decoders), @@ -91,7 +91,11 @@ spdk_rpc_construct_nvme_bdev(struct spdk_jsonrpc_server_conn *conn, } w = spdk_jsonrpc_begin_result(conn, id); - spdk_json_write_bool(w, true); + spdk_json_write_array_begin(w); + for (i = 0; i < ctx.num_created_bdevs; i++) { + spdk_json_write_string(w, ctx.created_bdevs[i]->name); + } + spdk_json_write_array_end(w); spdk_jsonrpc_end_result(conn, w); return; diff --git a/lib/bdev/rbd/blockdev_rbd.c b/lib/bdev/rbd/blockdev_rbd.c index e2431cc3b..663f84f95 100644 --- a/lib/bdev/rbd/blockdev_rbd.c +++ b/lib/bdev/rbd/blockdev_rbd.c @@ -557,7 +557,7 @@ blockdev_rbd_pool_info_init(const char *rbd_pool_name) return pool_info; } -int +struct spdk_bdev * spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block_size) { struct blockdev_rbd_pool_info *pool_info; @@ -565,20 +565,20 @@ spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block int ret; if ((pool_name == NULL) || (rbd_name == NULL)) { - return -1; + return NULL; } pool_info = blockdev_rbd_pool_info_init(pool_name); if (pool_info == NULL) { SPDK_ERRLOG("failed to create blockdev_rbd_pool_info\n"); - return -1; + return NULL; } rbd = calloc(1, sizeof(struct blockdev_rbd)); if (rbd == NULL) { SPDK_ERRLOG("Failed to allocate blockdev_rbd struct\n"); blockdev_rbd_free_pool_info(pool_info); - return -1; + return NULL; } rbd->pool_info = pool_info; @@ -586,7 +586,7 @@ spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block if (!rbd->rbd_name) { blockdev_rbd_free_pool_info(pool_info); blockdev_rbd_free(rbd); - return -1; + return NULL; } ret = blockdev_rbd_init(pool_info->name, rbd_name, &rbd->info); @@ -594,7 +594,7 @@ spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block blockdev_rbd_free_pool_info(pool_info); blockdev_rbd_free(rbd); SPDK_ERRLOG("Failed to init rbd device\n"); - return -1; + return NULL; } snprintf(rbd->disk.name, SPDK_BDEV_MAX_NAME_LENGTH, "Ceph%d", @@ -615,13 +615,13 @@ spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block blockdev_rbd_destroy_cb, sizeof(struct blockdev_rbd_io_channel)); spdk_bdev_register(&rbd->disk); - return 0; + return &rbd->disk; } static int blockdev_rbd_library_init(void) { - int i, ret; + int i; const char *val; const char *pool_name; const char *rbd_name; @@ -668,8 +668,7 @@ blockdev_rbd_library_init(void) } } - ret = spdk_bdev_rbd_create(pool_name, rbd_name, block_size); - if (ret) { + if (spdk_bdev_rbd_create(pool_name, rbd_name, block_size) == NULL) { goto cleanup; } } diff --git a/lib/bdev/rbd/blockdev_rbd.h b/lib/bdev/rbd/blockdev_rbd.h index 8ea17ae0e..900177deb 100644 --- a/lib/bdev/rbd/blockdev_rbd.h +++ b/lib/bdev/rbd/blockdev_rbd.h @@ -36,6 +36,9 @@ #include -int -spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block_size); +#include "spdk/bdev.h" + +struct spdk_bdev *spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, + uint32_t block_size); + #endif // SPDK_BLOCKDEV_RBD_H diff --git a/lib/bdev/rbd/blockdev_rbd_rpc.c b/lib/bdev/rbd/blockdev_rbd_rpc.c index a120e777d..80a98f656 100644 --- a/lib/bdev/rbd/blockdev_rbd_rpc.c +++ b/lib/bdev/rbd/blockdev_rbd_rpc.c @@ -61,6 +61,7 @@ spdk_rpc_construct_rbd_bdev(struct spdk_jsonrpc_server_conn *conn, { struct rpc_construct_rbd req = {}; struct spdk_json_write_ctx *w; + struct spdk_bdev *bdev; if (spdk_json_decode_object(params, rpc_construct_rbd_decoders, sizeof(rpc_construct_rbd_decoders) / sizeof(*rpc_construct_rbd_decoders), @@ -69,7 +70,8 @@ spdk_rpc_construct_rbd_bdev(struct spdk_jsonrpc_server_conn *conn, goto invalid; } - if (spdk_bdev_rbd_create(req.pool_name, req.rbd_name, req.size)) { + bdev = spdk_bdev_rbd_create(req.pool_name, req.rbd_name, req.size); + if (bdev == NULL) { goto invalid; } @@ -80,7 +82,9 @@ spdk_rpc_construct_rbd_bdev(struct spdk_jsonrpc_server_conn *conn, } w = spdk_jsonrpc_begin_result(conn, id); - spdk_json_write_bool(w, true); + spdk_json_write_array_begin(w); + spdk_json_write_string(w, bdev->name); + spdk_json_write_array_end(w); spdk_jsonrpc_end_result(conn, w); return; diff --git a/scripts/rpc.py b/scripts/rpc.py index ceadc872a..306c68793 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -4,11 +4,19 @@ import argparse import json import socket +try: + from shlex import quote +except ImportError: + from pipes import quote + SPDK_JSONRPC_PORT_BASE = 5260 def print_dict(d): print json.dumps(d, indent=2) +def print_array(a): + print " ".join((quote(v) for v in a)) + parser = argparse.ArgumentParser(description='SPDK RPC command line interface') parser.add_argument('-s', dest='server_ip', help='RPC server IP address', default='127.0.0.1') parser.add_argument('-p', dest='instance_id', help='RPC server instance ID', default=0, type=int) @@ -146,7 +154,7 @@ p.set_defaults(func=construct_target_node) def construct_malloc_bdev(args): num_blocks = (args.total_size * 1024 * 1024) / args.block_size params = {'num_blocks': num_blocks, 'block_size': args.block_size} - jsonrpc_call('construct_malloc_bdev', params) + print_array(jsonrpc_call('construct_malloc_bdev', params)) p = subparsers.add_parser('construct_malloc_bdev', help='Add a bdev with malloc backend') p.add_argument('total_size', help='Size of malloc bdev in MB (int > 0)', type=int) @@ -156,7 +164,7 @@ p.set_defaults(func=construct_malloc_bdev) def construct_aio_bdev(args): params = {'fname': args.fname} - jsonrpc_call('construct_aio_bdev', params) + print_array(jsonrpc_call('construct_aio_bdev', params)) p = subparsers.add_parser('construct_aio_bdev', help='Add a bdev with aio backend') p.add_argument('fname', help='Path to device or file (ex: /dev/sda)') @@ -164,7 +172,7 @@ p.set_defaults(func=construct_aio_bdev) def construct_nvme_bdev(args): params = {'pci_address': args.pci_address} - jsonrpc_call('construct_nvme_bdev', params) + print_array(jsonrpc_call('construct_nvme_bdev', params)) p = subparsers.add_parser('construct_nvme_bdev', help='Add bdev with nvme backend') p.add_argument('pci_address', help='PCI address domain:bus:device.function') p.set_defaults(func=construct_nvme_bdev) @@ -175,7 +183,7 @@ def construct_rbd_bdev(args): 'rbd_name': args.rbd_name, 'size': args.size, } - jsonrpc_call('construct_rbd_bdev', params) + print_array(jsonrpc_call('construct_rbd_bdev', params)) p = subparsers.add_parser('construct_rbd_bdev', help='Add a bdev with ceph rbd backend') p.add_argument('pool_name', help='rbd pool name') diff --git a/test/iscsi_tgt/rpc_config/rpc_config.py b/test/iscsi_tgt/rpc_config/rpc_config.py index 1991aa9af..d7549b390 100755 --- a/test/iscsi_tgt/rpc_config/rpc_config.py +++ b/test/iscsi_tgt/rpc_config/rpc_config.py @@ -400,14 +400,11 @@ def verify_add_nvme_bdev_rpc_methods(rpc_py): addrs = re.findall('^([0-9]{2}:[0-9]{2}.[0-9]) "Non-Volatile memory controller \[0108\]".*-p02', output, re.MULTILINE) for addr in addrs: ctrlr_address = "0000:{}".format(addr) - output = rpc.construct_nvme_bdev(ctrlr_address) - if output.strip() == '': - print "add nvme device passed first time" - test_pass = 1 - verify(test_pass == 1, 1, "add nvme device passed first time") + rpc.construct_nvme_bdev(ctrlr_address) + print "add nvme device passed first time" test_pass = 0 try: - output = rpc.construct_nvme_bdev(ctrlr_address) + rpc.construct_nvme_bdev(ctrlr_address) except Exception as e: print "add nvme device passed second time" test_pass = 1