lib/bdev: fix coredump when bdev initialize failed.

If subsystem bdev module initialize failed, it will call
spdk_bdev_init_complete(-1) -> (subsystem bdev)->fini
_spdk_bdev_finish_unregister_bdevs_iter -> spdk_bdev_module_finish_iter

In abovt path, spdk_bdev_module_finish_iter will repeate to call
bdev_module->module_fini function. Some bdevs will call spdk_io_device_unregister
which never call spdk_io_device_register. It will coredump when assert false in
spdk_io_device_unregister dev is null.

To fix this, let's check whether g_bdev_mgr.module_init_complete is equals true
and then call the bdev_module->module_fini.

Change-Id: Ia9a13318720d954e40eb2d666574bcb86e5f49e3
Signed-off-by: Tianyu Yang <yangtianyu2@huawei.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/462382
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Tianyu Yang 2019-07-15 16:17:14 +08:00 committed by Changpeng Liu
parent ac8b488982
commit 96b759297f

View File

@ -1134,6 +1134,16 @@ spdk_bdev_module_finish_iter(void *arg)
{
struct spdk_bdev_module *bdev_module;
/* FIXME: Handling initialization failures is broken now,
* so we won't even try cleaning up after successfully
* initialized modules. if module_init_complete is false,
* just call spdk_bdev_mgr_unregister_cb
*/
if (!g_bdev_mgr.module_init_complete) {
spdk_bdev_mgr_unregister_cb(NULL);
return;
}
/* Start iterating from the last touched module */
if (!g_resume_bdev_module) {
bdev_module = TAILQ_LAST(&g_bdev_mgr.bdev_modules, bdev_module_list);