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