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:
parent
93de96b412
commit
0404c306cb
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user