bdev: make (v)bdev init in async manner

Change-Id: I93684a004e2ae276734edbb4767b5ba1bac3dd48
Signed-off-by: Ziye Yang <optimistyzy@gmail.com>
Reviewed-on: https://review.gerrithub.io/362111
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Ziye Yang 2017-05-26 12:58:04 +08:00 committed by Jim Harris
parent 6e0d1dcdfa
commit 9104fe73ce
9 changed files with 136 additions and 76 deletions

View File

@ -87,10 +87,11 @@ struct spdk_bdev_module_if {
/** /**
* Initialization function for the module. Called by the spdk * Initialization function for the module. Called by the spdk
* application during startup. * application during startup.
* User must call spdk_bdev_module_init_next() with return code inside this func.
* *
* Modules are required to define this function. * Modules are required to define this function.
*/ */
int (*module_init)(void); void (*module_init)(void);
/** /**
* Finish function for the module. Called by the spdk application * Finish function for the module. Called by the spdk application
@ -381,6 +382,8 @@ void spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io,
void spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module); void spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module);
void spdk_vbdev_module_list_add(struct spdk_bdev_module_if *vbdev_module); void spdk_vbdev_module_list_add(struct spdk_bdev_module_if *vbdev_module);
void spdk_bdev_module_init_next(int rc);
void spdk_vbdev_module_init_next(int rc);
static inline struct spdk_bdev_io * static inline struct spdk_bdev_io *
spdk_bdev_io_from_ctx(void *ctx) spdk_bdev_io_from_ctx(void *ctx)

View File

@ -43,7 +43,7 @@
#include "spdk_internal/log.h" #include "spdk_internal/log.h"
static int blockdev_aio_initialize(void); static void blockdev_aio_initialize(void);
static void aio_free_disk(struct file_disk *fdisk); static void aio_free_disk(struct file_disk *fdisk);
static int static int
@ -377,7 +377,8 @@ error_return:
return NULL; return NULL;
} }
static int blockdev_aio_initialize(void) static void
blockdev_aio_initialize(void)
{ {
size_t i; size_t i;
struct spdk_conf_section *sp; struct spdk_conf_section *sp;
@ -385,7 +386,7 @@ static int blockdev_aio_initialize(void)
sp = spdk_conf_find_section(NULL, "AIO"); sp = spdk_conf_find_section(NULL, "AIO");
if (!sp) { if (!sp) {
return 0; goto end;
} }
i = 0; i = 0;
@ -415,7 +416,8 @@ static int blockdev_aio_initialize(void)
i++; i++;
} }
return 0; end:
spdk_bdev_module_init_next(0);
} }
SPDK_LOG_REGISTER_TRACE_FLAG("aio", SPDK_TRACE_AIO) SPDK_LOG_REGISTER_TRACE_FLAG("aio", SPDK_TRACE_AIO)

View File

@ -76,6 +76,9 @@ static struct spdk_bdev_mgr g_bdev_mgr = {
.bdevs = TAILQ_HEAD_INITIALIZER(g_bdev_mgr.bdevs), .bdevs = TAILQ_HEAD_INITIALIZER(g_bdev_mgr.bdevs),
}; };
static struct spdk_bdev_module_if *g_next_bdev_module;
static struct spdk_bdev_module_if *g_next_vbdev_module;
struct spdk_bdev_mgmt_channel { struct spdk_bdev_mgmt_channel {
}; };
@ -258,11 +261,56 @@ spdk_bdev_mgmt_channel_destroy(void *io_device, void *ctx_buf)
{ {
} }
void
spdk_bdev_module_init_next(int rc)
{
if (rc) {
assert(g_next_bdev_module != NULL);
SPDK_ERRLOG("Failed to init bdev module: %s\n", g_next_bdev_module->module_name);
spdk_subsystem_init_next(rc);
return;
}
if (!g_next_bdev_module) {
g_next_bdev_module = TAILQ_FIRST(&g_bdev_mgr.bdev_modules);
} else {
g_next_bdev_module = TAILQ_NEXT(g_next_bdev_module, tailq);
}
if (g_next_bdev_module) {
g_next_bdev_module->module_init();
} else {
spdk_vbdev_module_init_next(0);
}
}
void
spdk_vbdev_module_init_next(int rc)
{
if (rc) {
assert(g_next_vbdev_module != NULL);
SPDK_ERRLOG("Failed to init vbdev module: %s\n", g_next_vbdev_module->module_name);
spdk_subsystem_init_next(rc);
return;
}
if (!g_next_vbdev_module) {
g_next_vbdev_module = TAILQ_FIRST(&g_bdev_mgr.vbdev_modules);
} else {
g_next_vbdev_module = TAILQ_NEXT(g_next_vbdev_module, tailq);
}
if (g_next_vbdev_module) {
g_next_vbdev_module->module_init();
} else {
spdk_subsystem_init_next(0);
}
}
static void static void
spdk_bdev_initialize(void) spdk_bdev_initialize(void)
{ {
int i, cache_size; int i, cache_size;
struct spdk_bdev_module_if *bdev_module;
int rc = 0; int rc = 0;
g_bdev_mgr.bdev_io_pool = spdk_mempool_create("blockdev_io", g_bdev_mgr.bdev_io_pool = spdk_mempool_create("blockdev_io",
@ -309,22 +357,6 @@ spdk_bdev_initialize(void)
if (!g_bdev_mgr.buf_large_pool) { if (!g_bdev_mgr.buf_large_pool) {
SPDK_ERRLOG("create rbuf large pool failed\n"); SPDK_ERRLOG("create rbuf large pool failed\n");
rc = -1; rc = -1;
goto end;
}
TAILQ_FOREACH(bdev_module, &g_bdev_mgr.bdev_modules, tailq) {
rc = bdev_module->module_init();
if (rc) {
rc = -1;
goto end;
}
}
TAILQ_FOREACH(bdev_module, &g_bdev_mgr.vbdev_modules, tailq) {
rc = bdev_module->module_init();
if (rc) {
rc = -1;
goto end;
}
} }
spdk_io_device_register(&g_bdev_mgr, spdk_bdev_mgmt_channel_create, spdk_io_device_register(&g_bdev_mgr, spdk_bdev_mgmt_channel_create,
@ -332,7 +364,7 @@ spdk_bdev_initialize(void)
sizeof(struct spdk_bdev_mgmt_channel)); sizeof(struct spdk_bdev_mgmt_channel));
end: end:
spdk_subsystem_init_next(rc); spdk_bdev_module_init_next(rc);
} }
static int static int

View File

@ -221,17 +221,17 @@ cleanup:
return rc; return rc;
} }
static int static void
vbdev_error_init(void) vbdev_error_init(void)
{ {
struct spdk_conf_section *sp; struct spdk_conf_section *sp;
const char *base_bdev_name; const char *base_bdev_name;
int i; int i, rc = 0;
struct spdk_bdev *base_bdev; struct spdk_bdev *base_bdev;
sp = spdk_conf_find_section(NULL, "BdevError"); sp = spdk_conf_find_section(NULL, "BdevError");
if (sp == NULL) { if (sp == NULL) {
return 0; goto end;
} }
for (i = 0; ; i++) { for (i = 0; ; i++) {
@ -242,20 +242,25 @@ vbdev_error_init(void)
base_bdev_name = spdk_conf_section_get_nmval(sp, "BdevError", i, 0); base_bdev_name = spdk_conf_section_get_nmval(sp, "BdevError", i, 0);
if (!base_bdev_name) { if (!base_bdev_name) {
SPDK_ERRLOG("ErrorInjection configuration missing blockdev name\n"); SPDK_ERRLOG("ErrorInjection configuration missing blockdev name\n");
return -1; rc = -1;
goto end;
} }
base_bdev = spdk_bdev_get_by_name(base_bdev_name); base_bdev = spdk_bdev_get_by_name(base_bdev_name);
if (!base_bdev) { if (!base_bdev) {
SPDK_ERRLOG("Could not find ErrorInjection bdev %s\n", base_bdev_name); SPDK_ERRLOG("Could not find ErrorInjection bdev %s\n", base_bdev_name);
return -1; rc = -1;
goto end;
} }
if (spdk_vbdev_error_create(base_bdev)) { if (spdk_vbdev_error_create(base_bdev)) {
return -1; rc = -1;
goto end;
} }
} }
return 0;
end:
spdk_vbdev_module_init_next(rc);
} }
static void static void

View File

@ -88,7 +88,7 @@ static struct malloc_disk *g_malloc_disk_head = NULL;
int malloc_disk_count = 0; int malloc_disk_count = 0;
static int blockdev_malloc_initialize(void); static void blockdev_malloc_initialize(void);
static void blockdev_malloc_finish(void); static void blockdev_malloc_finish(void);
static void blockdev_malloc_get_spdk_running_config(FILE *fp); static void blockdev_malloc_get_spdk_running_config(FILE *fp);
@ -421,10 +421,10 @@ static void free_malloc_disk(struct malloc_disk *mdisk)
spdk_dma_free(mdisk); spdk_dma_free(mdisk);
} }
static int blockdev_malloc_initialize(void) static void blockdev_malloc_initialize(void)
{ {
struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Malloc"); struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Malloc");
int NumberOfLuns, LunSizeInMB, BlockSize, i; int NumberOfLuns, LunSizeInMB, BlockSize, i, rc = 0;
uint64_t size; uint64_t size;
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
@ -434,7 +434,8 @@ static int blockdev_malloc_initialize(void)
BlockSize = spdk_conf_section_get_intval(sp, "BlockSize"); BlockSize = spdk_conf_section_get_intval(sp, "BlockSize");
if ((NumberOfLuns < 1) || (LunSizeInMB < 1)) { if ((NumberOfLuns < 1) || (LunSizeInMB < 1)) {
SPDK_ERRLOG("Malloc section present, but no devices specified\n"); SPDK_ERRLOG("Malloc section present, but no devices specified\n");
return EINVAL; rc = EINVAL;
goto end;
} }
if (BlockSize < 1) { if (BlockSize < 1) {
/* Default is 512 bytes */ /* Default is 512 bytes */
@ -445,11 +446,14 @@ static int blockdev_malloc_initialize(void)
bdev = create_malloc_disk(size / BlockSize, BlockSize); bdev = create_malloc_disk(size / BlockSize, BlockSize);
if (bdev == NULL) { if (bdev == NULL) {
SPDK_ERRLOG("Could not create malloc disk\n"); SPDK_ERRLOG("Could not create malloc disk\n");
return EINVAL; rc = EINVAL;
goto end;
} }
} }
} }
return 0;
end:
spdk_bdev_module_init_next(rc);
} }
static void blockdev_malloc_finish(void) static void blockdev_malloc_finish(void)

View File

@ -170,12 +170,12 @@ null_bdev_destroy_cb(void *io_device, void *ctx_buf)
{ {
} }
static int static void
blockdev_null_initialize(void) blockdev_null_initialize(void)
{ {
struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Null"); struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "Null");
uint64_t size_in_mb, num_blocks; uint64_t size_in_mb, num_blocks;
int block_size, i; int block_size, i, rc = 0;
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
const char *name, *val; const char *name, *val;
@ -195,7 +195,7 @@ blockdev_null_initialize(void)
spdk_io_device_register(&g_null_bdev_head, null_bdev_create_cb, null_bdev_destroy_cb, 0); spdk_io_device_register(&g_null_bdev_head, null_bdev_create_cb, null_bdev_destroy_cb, 0);
if (sp == NULL) { if (sp == NULL) {
return 0; goto end;
} }
i = 0; i = 0;
@ -241,12 +241,15 @@ blockdev_null_initialize(void)
bdev = create_null_bdev(name, num_blocks, block_size); bdev = create_null_bdev(name, num_blocks, block_size);
if (bdev == NULL) { if (bdev == NULL) {
SPDK_ERRLOG("Could not create null bdev\n"); SPDK_ERRLOG("Could not create null bdev\n");
return EINVAL; rc = EINVAL;
goto end;
} }
i++; i++;
} }
return 0;
end:
spdk_bdev_module_init_next(rc);
} }
static void static void

View File

@ -125,7 +125,7 @@ static TAILQ_HEAD(, nvme_ctrlr) g_nvme_ctrlrs = TAILQ_HEAD_INITIALIZER(g_nvme_ct
static TAILQ_HEAD(, nvme_bdev) g_nvme_bdevs = TAILQ_HEAD_INITIALIZER(g_nvme_bdevs); static TAILQ_HEAD(, nvme_bdev) g_nvme_bdevs = TAILQ_HEAD_INITIALIZER(g_nvme_bdevs);
static void nvme_ctrlr_create_bdevs(struct nvme_ctrlr *nvme_ctrlr); static void nvme_ctrlr_create_bdevs(struct nvme_ctrlr *nvme_ctrlr);
static int bdev_nvme_library_init(void); static void bdev_nvme_library_init(void);
static void bdev_nvme_library_fini(void); static void bdev_nvme_library_fini(void);
static int bdev_nvme_queue_cmd(struct nvme_bdev *bdev, struct spdk_nvme_qpair *qpair, static int bdev_nvme_queue_cmd(struct nvme_bdev *bdev, struct spdk_nvme_qpair *qpair,
struct nvme_bdev_io *bio, struct nvme_bdev_io *bio,
@ -754,25 +754,26 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
return 0; return 0;
} }
static int static void
bdev_nvme_library_init(void) bdev_nvme_library_init(void)
{ {
struct spdk_conf_section *sp; struct spdk_conf_section *sp;
const char *val; const char *val;
int rc; int rc = 0;
size_t i; size_t i;
struct nvme_probe_ctx *probe_ctx; struct nvme_probe_ctx *probe_ctx = NULL;
int retry_count; int retry_count;
sp = spdk_conf_find_section(NULL, "Nvme"); sp = spdk_conf_find_section(NULL, "Nvme");
if (sp == NULL) { if (sp == NULL) {
return 0; goto end;
} }
probe_ctx = calloc(1, sizeof(*probe_ctx)); probe_ctx = calloc(1, sizeof(*probe_ctx));
if (probe_ctx == NULL) { if (probe_ctx == NULL) {
SPDK_ERRLOG("Failed to allocate probe_ctx\n"); SPDK_ERRLOG("Failed to allocate probe_ctx\n");
return -1; rc = -1;
goto end;
} }
if ((retry_count = spdk_conf_section_get_intval(sp, "RetryCount")) < 0) { if ((retry_count = spdk_conf_section_get_intval(sp, "RetryCount")) < 0) {
@ -795,15 +796,15 @@ bdev_nvme_library_init(void)
rc = spdk_nvme_transport_id_parse(&probe_ctx->trids[i], val); rc = spdk_nvme_transport_id_parse(&probe_ctx->trids[i], val);
if (rc < 0) { if (rc < 0) {
SPDK_ERRLOG("Unable to parse TransportID: %s\n", val); SPDK_ERRLOG("Unable to parse TransportID: %s\n", val);
free(probe_ctx); rc = -1;
return -1; goto end;
} }
val = spdk_conf_section_get_nmval(sp, "TransportID", i, 1); val = spdk_conf_section_get_nmval(sp, "TransportID", i, 1);
if (val == NULL) { if (val == NULL) {
SPDK_ERRLOG("No name provided for TransportID\n"); SPDK_ERRLOG("No name provided for TransportID\n");
free(probe_ctx); rc = -1;
return -1; goto end;
} }
probe_ctx->names[i] = val; probe_ctx->names[i] = val;
@ -863,8 +864,8 @@ bdev_nvme_library_init(void)
} }
if (spdk_nvme_probe(NULL, probe_ctx, probe_cb, attach_cb, NULL)) { if (spdk_nvme_probe(NULL, probe_ctx, probe_cb, attach_cb, NULL)) {
free(probe_ctx); rc = -1;
return -1; goto end;
} }
if (g_nvme_hotplug_enabled) { if (g_nvme_hotplug_enabled) {
@ -872,8 +873,9 @@ bdev_nvme_library_init(void)
g_nvme_hotplug_poll_core, g_nvme_hotplug_poll_timeout_us); g_nvme_hotplug_poll_core, g_nvme_hotplug_poll_timeout_us);
} }
end:
free(probe_ctx); free(probe_ctx);
return 0; spdk_bdev_module_init_next(rc);
} }
static void static void

View File

@ -199,7 +199,7 @@ blockdev_rbd_start_aio(rbd_image_t image, struct blockdev_rbd_io *cmd,
return 0; return 0;
} }
static int blockdev_rbd_library_init(void); static void blockdev_rbd_library_init(void);
static void blockdev_rbd_library_fini(void); static void blockdev_rbd_library_fini(void);
static int static int
@ -543,10 +543,10 @@ spdk_bdev_rbd_create(const char *pool_name, const char *rbd_name, uint32_t block
return &rbd->disk; return &rbd->disk;
} }
static int static void
blockdev_rbd_library_init(void) blockdev_rbd_library_init(void)
{ {
int i; int i, rc = 0;
const char *val; const char *val;
const char *pool_name; const char *pool_name;
const char *rbd_name; const char *rbd_name;
@ -558,7 +558,7 @@ blockdev_rbd_library_init(void)
/* /*
* Ceph section not found. Do not initialize any rbd LUNS. * Ceph section not found. Do not initialize any rbd LUNS.
*/ */
return 0; goto end;
} }
/* Init rbd block devices */ /* Init rbd block devices */
@ -571,13 +571,15 @@ blockdev_rbd_library_init(void)
pool_name = spdk_conf_section_get_nmval(sp, "Ceph", i, 0); pool_name = spdk_conf_section_get_nmval(sp, "Ceph", i, 0);
if (pool_name == NULL) { if (pool_name == NULL) {
SPDK_ERRLOG("Ceph%d: rbd pool name needs to be provided\n", i); SPDK_ERRLOG("Ceph%d: rbd pool name needs to be provided\n", i);
goto cleanup; rc = -1;
goto end;
} }
rbd_name = spdk_conf_section_get_nmval(sp, "Ceph", i, 1); rbd_name = spdk_conf_section_get_nmval(sp, "Ceph", i, 1);
if (rbd_name == NULL) { if (rbd_name == NULL) {
SPDK_ERRLOG("Ceph%d: format error\n", i); SPDK_ERRLOG("Ceph%d: format error\n", i);
goto cleanup; rc = -1;
goto end;
} }
val = spdk_conf_section_get_nmval(sp, "Ceph", i, 2); val = spdk_conf_section_get_nmval(sp, "Ceph", i, 2);
@ -589,17 +591,17 @@ blockdev_rbd_library_init(void)
if (block_size & 0x1ff) { if (block_size & 0x1ff) {
SPDK_ERRLOG("current block_size = %d, it should be multiple of 512\n", SPDK_ERRLOG("current block_size = %d, it should be multiple of 512\n",
block_size); block_size);
goto cleanup; rc = -1;
goto end;
} }
} }
if (spdk_bdev_rbd_create(pool_name, rbd_name, block_size) == NULL) { if (spdk_bdev_rbd_create(pool_name, rbd_name, block_size) == NULL) {
goto cleanup; rc = -1;
goto end;
} }
} }
return 0; end:
cleanup: spdk_bdev_module_init_next(rc);
blockdev_rbd_library_fini();
return -1;
} }

View File

@ -331,19 +331,19 @@ cleanup:
return rc; return rc;
} }
static int static void
vbdev_split_init(void) vbdev_split_init(void)
{ {
struct spdk_conf_section *sp; struct spdk_conf_section *sp;
const char *base_bdev_name; const char *base_bdev_name;
const char *split_count_str; const char *split_count_str;
const char *split_size_str; const char *split_size_str;
int i, split_count, split_size; int i, split_count, split_size, rc = 0;
struct spdk_bdev *base_bdev; struct spdk_bdev *base_bdev;
sp = spdk_conf_find_section(NULL, "Split"); sp = spdk_conf_find_section(NULL, "Split");
if (sp == NULL) { if (sp == NULL) {
return 0; goto end;
} }
for (i = 0; ; i++) { for (i = 0; ; i++) {
@ -354,25 +354,29 @@ vbdev_split_init(void)
base_bdev_name = spdk_conf_section_get_nmval(sp, "Split", i, 0); base_bdev_name = spdk_conf_section_get_nmval(sp, "Split", i, 0);
if (!base_bdev_name) { if (!base_bdev_name) {
SPDK_ERRLOG("Split configuration missing blockdev name\n"); SPDK_ERRLOG("Split configuration missing blockdev name\n");
return -1; rc = -1;
goto end;
} }
base_bdev = spdk_bdev_get_by_name(base_bdev_name); base_bdev = spdk_bdev_get_by_name(base_bdev_name);
if (!base_bdev) { if (!base_bdev) {
SPDK_ERRLOG("Could not find Split bdev %s\n", base_bdev_name); SPDK_ERRLOG("Could not find Split bdev %s\n", base_bdev_name);
return -1; rc = -1;
goto end;
} }
split_count_str = spdk_conf_section_get_nmval(sp, "Split", i, 1); split_count_str = spdk_conf_section_get_nmval(sp, "Split", i, 1);
if (!split_count_str) { if (!split_count_str) {
SPDK_ERRLOG("Split configuration missing split count\n"); SPDK_ERRLOG("Split configuration missing split count\n");
return -1; rc = -1;
goto end;
} }
split_count = atoi(split_count_str); split_count = atoi(split_count_str);
if (split_count < 1) { if (split_count < 1) {
SPDK_ERRLOG("Invalid Split count %d\n", split_count); SPDK_ERRLOG("Invalid Split count %d\n", split_count);
return -1; rc = -1;
goto end;
} }
/* Optional split size in MB */ /* Optional split size in MB */
@ -382,16 +386,19 @@ vbdev_split_init(void)
split_size = atoi(split_size_str); split_size = atoi(split_size_str);
if (split_size <= 0) { if (split_size <= 0) {
SPDK_ERRLOG("Invalid Split size %d\n", split_size); SPDK_ERRLOG("Invalid Split size %d\n", split_size);
return -1; rc = -1;
goto end;
} }
} }
if (vbdev_split_create(base_bdev, split_count, split_size)) { if (vbdev_split_create(base_bdev, split_count, split_size)) {
return -1; rc = -1;
goto end;
} }
} }
return 0; end:
spdk_vbdev_module_init_next(rc);
} }
static void static void