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: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471375
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
Wojciech Malikowski 2019-10-15 08:14:49 -04:00 committed by Tomasz Zawadzki
parent e2e6254651
commit 151e37cfaa
3 changed files with 122 additions and 5 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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