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 <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-10-25 16:19:53 -07:00
parent 93de96b412
commit 0404c306cb
14 changed files with 88 additions and 45 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -36,8 +36,8 @@
#include <stdint.h>
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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -35,14 +35,22 @@
#define SPDK_BLOCKDEV_NVME_H
#include <stdint.h>
#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

View File

@ -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;

View File

@ -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;
}
}

View File

@ -36,6 +36,9 @@
#include <stdint.h>
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

View File

@ -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;

View File

@ -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')

View File

@ -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