Commit 151e37cf authored by Wojciech Malikowski's avatar Wojciech Malikowski Committed by Tomasz Zawadzki
Browse files

bdev/ftl: Examine config support



Bdev FTL is dependent on base bdev and cache
bdev. Allow for examine config if dependent
bdevs are not ready during bdev FTL creation.

Change-Id: I917994d7015f3b74a29ccd066f0c6989ad3c1c4e
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471375


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent e2e62546
Loading
Loading
Loading
Loading
+107 −0
Original line number Diff line number Diff line
@@ -90,8 +90,11 @@ struct ftl_deferred_init {
	LIST_ENTRY(ftl_deferred_init)	entry;
};

static LIST_HEAD(, ftl_deferred_init)	g_deferred_init = LIST_HEAD_INITIALIZER(g_deferred_init);

static int bdev_ftl_initialize(void);
static void bdev_ftl_finish(void);
static void bdev_ftl_examine(struct spdk_bdev *bdev);

static int
bdev_ftl_get_ctx_size(void)
@@ -103,6 +106,7 @@ static struct spdk_bdev_module g_ftl_if = {
	.name		= "ftl",
	.module_init	= bdev_ftl_initialize,
	.module_fini	= bdev_ftl_finish,
	.examine_disk	= bdev_ftl_examine,
	.get_ctx_size	= bdev_ftl_get_ctx_size,
};

@@ -527,6 +531,58 @@ error_dev:
	init_cb(NULL, init_arg, rc);
}

static void
bdev_ftl_defer_free(struct ftl_deferred_init *init)
{
	free((char *)init->opts.name);
	free((char *)init->opts.base_bdev);
	free((char *)init->opts.cache_bdev);
	free(init);
}

static int
bdev_ftl_defer_init(const struct ftl_bdev_init_opts *opts)
{
	struct ftl_deferred_init *init;

	init = calloc(1, sizeof(*init));
	if (!init) {
		return -ENOMEM;
	}

	init->opts.mode = opts->mode;
	init->opts.uuid = opts->uuid;
	init->opts.ftl_conf = opts->ftl_conf;

	init->opts.name = strdup(opts->name);
	if (!init->opts.name) {
		SPDK_ERRLOG("Could not allocate bdev name\n");
		goto error;
	}

	init->opts.base_bdev = strdup(opts->base_bdev);
	if (!init->opts.base_bdev) {
		SPDK_ERRLOG("Could not allocate base bdev name\n");
		goto error;
	}

	if (opts->cache_bdev) {
		init->opts.cache_bdev = strdup(opts->cache_bdev);
		if (!init->opts.cache_bdev) {
			SPDK_ERRLOG("Could not allocate cache bdev name\n");
			goto error;
		}
	}

	LIST_INSERT_HEAD(&g_deferred_init, init, entry);

	return 0;

error:
	bdev_ftl_defer_free(init);
	return -ENOMEM;
}

static int
bdev_ftl_init_dependent_bdev(struct ftl_bdev *ftl_bdev, const char *bdev_name,
			     struct spdk_bdev_desc **bdev_desc)
@@ -574,6 +630,15 @@ bdev_ftl_create_bdev(const struct ftl_bdev_init_opts *bdev_opts,
		goto error_bdev;
	}

	if (spdk_bdev_get_by_name(bdev_opts->base_bdev) == NULL ||
	    (bdev_opts->cache_bdev && spdk_bdev_get_by_name(bdev_opts->cache_bdev) == NULL)) {
		rc = bdev_ftl_defer_init(bdev_opts);
		if (rc == 0) {
			rc = -ENODEV;
		}
		goto error_name;
	}

	rc = bdev_ftl_init_dependent_bdev(ftl_bdev, bdev_opts->base_bdev,
					  &ftl_bdev->base_bdev_desc);
	if (rc) {
@@ -654,4 +719,46 @@ bdev_ftl_finish(void)
{
}

static void
bdev_ftl_create_defered_cb(const struct ftl_bdev_info *info, void *ctx, int status)
{
	struct ftl_deferred_init *opts = ctx;

	if (status) {
		SPDK_ERRLOG("Failed to initialize FTL bdev '%s'\n", opts->opts.name);
	}

	bdev_ftl_defer_free(opts);

	spdk_bdev_module_examine_done(&g_ftl_if);
}

static void
bdev_ftl_examine(struct spdk_bdev *bdev)
{
	struct ftl_deferred_init *opts;

	LIST_FOREACH(opts, &g_deferred_init, entry) {
		if (spdk_bdev_get_by_name(opts->opts.base_bdev) == NULL) {
			continue;
		}

		if (opts->opts.cache_bdev && spdk_bdev_get_by_name(opts->opts.base_bdev) == NULL) {
			continue;
		}

		LIST_REMOVE(opts, entry);

		/* spdk_bdev_module_examine_done will be called by bdev_ftl_create_defered_cb */
		if (bdev_ftl_create_bdev(&opts->opts, bdev_ftl_create_defered_cb, opts)) {
			SPDK_ERRLOG("Failed to initialize FTL bdev '%s'\n", opts->opts.name);
			bdev_ftl_defer_free(opts);
			break;
		}
		return;
	}

	spdk_bdev_module_examine_done(&g_ftl_if);
}

SPDK_LOG_REGISTER_COMPONENT("bdev_ftl", SPDK_LOG_BDEV_FTL)
+10 −3
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ spdk_rpc_bdev_ftl_create(struct spdk_jsonrpc_request *request,
{
	struct rpc_bdev_ftl_create req = {};
	struct ftl_bdev_init_opts opts = {};
	struct spdk_json_write_ctx *w;
	int rc;

	spdk_ftl_conf_init_defaults(&req.ftl_conf);
@@ -187,9 +188,15 @@ spdk_rpc_bdev_ftl_create(struct spdk_jsonrpc_request *request,

	rc = bdev_ftl_create_bdev(&opts, _spdk_rpc_bdev_ftl_create_cb, request);
	if (rc) {
		if (rc == -ENODEV) {
			w = spdk_jsonrpc_begin_result(request);
			spdk_json_write_string_fmt(w, "FTL bdev: %s creation deferred", req.name);
			spdk_jsonrpc_end_result(request, w);
		} else {
			spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
							     "Failed to create FTL bdev: %s",
							     spdk_strerror(-rc));
		}
		goto invalid;
	}

+5 −2
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@ $rootdir/app/spdk_tgt/spdk_tgt & svcpid=$!
waitforlisten $svcpid

# Create new bdev from json configuration
$rootdir/scripts/gen_ftl.sh -j -a $device -n nvme0 | $rpc_py load_subsystem_config
$rootdir/scripts/gen_ftl.sh -n ftl0 -d nvme0n1 | $rpc_py load_subsystem_config
$rpc_py bdev_nvme_attach_controller -b nvme0 -a $device -t pcie
$rpc_py bdev_ocssd_create -c nvme0 -b nvme0n1 -n 1

uuid=$($rpc_py bdev_get_bdevs | jq -r '.[0].uuid')
waitforbdev ftl0
uuid=$($rpc_py bdev_get_bdevs | jq -r ".[] | select(.name==\"ftl0\").uuid")

$rpc_py bdev_ftl_delete -b nvme0