Commit 6b654ab9 authored by Vitaliy Mysak's avatar Vitaliy Mysak Committed by Darek Stojaczyk
Browse files

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: default avatarVitaliy Mysak <vitaliy.mysak@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/461230


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
parent 0b3fb240
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -940,6 +940,15 @@ spdk_bdev_module_examine_done(struct spdk_bdev_module *module)
/** The last initialized bdev module */
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
spdk_bdev_modules_init(void)
{
@@ -953,6 +962,10 @@ spdk_bdev_modules_init(void)
		}
		rc = module->module_init();
		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;
		}
	}
@@ -961,12 +974,6 @@ spdk_bdev_modules_init(void)
	return 0;
}

static void
spdk_bdev_init_failed(void *cb_arg)
{
	spdk_bdev_init_complete(-1);
}

void
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;
	if (rc != 0) {
		SPDK_ERRLOG("bdev modules init failed\n");
		spdk_thread_send_msg(spdk_get_thread(), spdk_bdev_init_failed, NULL);
		return;
	}