bdev: prevent early spdk_bdev_init_complete()
In case some module has `async_init = true` and some other module that comes after it fails to initialize, then callback from asynchronously initialized module may call `spdk_bdev_init_complete()` first, then failed module will call `spdk_bdev_init_complete()` later. This currently results in NULL dereference because first call to `spdk_bdev_init_complete()` sets `g_init_cb_fn = NULL`. This change prevents first call to `spdk_bdev_init_complete()` by saying that failed module is not finished with initialization. This patch fixes #847 Change-Id: Ib6b231d5ea27896ad88d7f11b8732921077b3d4d Signed-off-by: Vitaliy Mysak <vitaliy.mysak@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/461230 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
parent
0b3fb2403e
commit
6b654ab900
@ -940,6 +940,15 @@ spdk_bdev_module_examine_done(struct spdk_bdev_module *module)
|
|||||||
/** The last initialized bdev module */
|
/** The last initialized bdev module */
|
||||||
static struct spdk_bdev_module *g_resume_bdev_module = NULL;
|
static struct spdk_bdev_module *g_resume_bdev_module = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
spdk_bdev_init_failed(void *cb_arg)
|
||||||
|
{
|
||||||
|
struct spdk_bdev_module *module = cb_arg;
|
||||||
|
|
||||||
|
module->internal.action_in_progress--;
|
||||||
|
spdk_bdev_init_complete(-1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
spdk_bdev_modules_init(void)
|
spdk_bdev_modules_init(void)
|
||||||
{
|
{
|
||||||
@ -953,6 +962,10 @@ spdk_bdev_modules_init(void)
|
|||||||
}
|
}
|
||||||
rc = module->module_init();
|
rc = module->module_init();
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
/* Bump action_in_progress to prevent other modules from completion of modules_init
|
||||||
|
* Send message to defer application shutdown until resources are cleaned up */
|
||||||
|
module->internal.action_in_progress = 1;
|
||||||
|
spdk_thread_send_msg(spdk_get_thread(), spdk_bdev_init_failed, module);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -961,12 +974,6 @@ spdk_bdev_modules_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
spdk_bdev_init_failed(void *cb_arg)
|
|
||||||
{
|
|
||||||
spdk_bdev_init_complete(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
spdk_bdev_initialize(spdk_bdev_init_cb cb_fn, void *cb_arg)
|
spdk_bdev_initialize(spdk_bdev_init_cb cb_fn, void *cb_arg)
|
||||||
{
|
{
|
||||||
@ -1078,7 +1085,6 @@ spdk_bdev_initialize(spdk_bdev_init_cb cb_fn, void *cb_arg)
|
|||||||
g_bdev_mgr.module_init_complete = true;
|
g_bdev_mgr.module_init_complete = true;
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SPDK_ERRLOG("bdev modules init failed\n");
|
SPDK_ERRLOG("bdev modules init failed\n");
|
||||||
spdk_thread_send_msg(spdk_get_thread(), spdk_bdev_init_failed, NULL);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user