bdev/nvme: use asynchronous API to probe user specified controller
NVMe controller can be attached via asynchronous API now, we added the RPC 'construct_nvme_bdev' with asynchronous probe support so that the initialization can be processed later. Change-Id: Ic60fdde6af9c4ba9a07b874852cfba044acb06c Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Change-Id: Ic60fdde6af9c4ba9a07b874852cfba044acb06c8 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/445054 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: wuzhouhui <wuzhouhui@kingsoft.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
parent
4fb2260117
commit
8129ede1c8
@ -1183,6 +1183,55 @@ bdev_nvme_create_and_get_bdev_names(struct spdk_nvme_ctrlr *ctrlr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nvme_async_probe_ctx {
|
||||
struct spdk_nvme_probe_ctx *probe_ctx;
|
||||
const char *base_name;
|
||||
const char **names;
|
||||
size_t *count;
|
||||
uint32_t prchk_flags;
|
||||
struct spdk_poller *poller;
|
||||
struct spdk_nvme_transport_id trid;
|
||||
struct spdk_nvme_ctrlr_opts opts;
|
||||
spdk_bdev_create_nvme_fn cb_fn;
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
static void
|
||||
connect_attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
|
||||
struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
|
||||
{
|
||||
struct spdk_nvme_ctrlr_opts *user_opts = cb_ctx;
|
||||
struct nvme_async_probe_ctx *ctx;
|
||||
int rc;
|
||||
|
||||
ctx = SPDK_CONTAINEROF(user_opts, struct nvme_async_probe_ctx, opts);
|
||||
rc = bdev_nvme_create_and_get_bdev_names(ctrlr,
|
||||
ctx->base_name,
|
||||
ctx->names, ctx->count,
|
||||
&ctx->trid,
|
||||
ctx->prchk_flags);
|
||||
|
||||
if (ctx->cb_fn) {
|
||||
ctx->cb_fn(ctx->cb_ctx, rc);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bdev_nvme_async_poll(void *arg)
|
||||
{
|
||||
struct nvme_async_probe_ctx *ctx = arg;
|
||||
int done;
|
||||
|
||||
done = spdk_nvme_probe_poll_async(ctx->probe_ctx);
|
||||
/* retry again */
|
||||
if (done == -EAGAIN) {
|
||||
return 1;
|
||||
}
|
||||
spdk_poller_unregister(&ctx->poller);
|
||||
free(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
struct spdk_nvme_host_id *hostid,
|
||||
@ -1190,13 +1239,11 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
const char **names, size_t *count,
|
||||
const char *hostnqn,
|
||||
uint32_t prchk_flags,
|
||||
spdk_bdev_nvme_fn cb_fn,
|
||||
spdk_bdev_create_nvme_fn cb_fn,
|
||||
void *cb_ctx)
|
||||
{
|
||||
int rc;
|
||||
struct spdk_nvme_ctrlr_opts opts;
|
||||
struct spdk_nvme_ctrlr *ctrlr;
|
||||
struct nvme_probe_skip_entry *entry, *tmp;
|
||||
struct nvme_async_probe_ctx *ctx;
|
||||
|
||||
if (nvme_bdev_ctrlr_get(trid) != NULL) {
|
||||
SPDK_ERRLOG("A controller with the provided trid (traddr: %s) already exists.\n", trid->traddr);
|
||||
@ -1218,33 +1265,41 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
}
|
||||
}
|
||||
|
||||
spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts));
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
ctx->base_name = base_name;
|
||||
ctx->names = names;
|
||||
ctx->count = count;
|
||||
ctx->cb_fn = cb_fn;
|
||||
ctx->cb_ctx = cb_ctx;
|
||||
ctx->prchk_flags = prchk_flags;
|
||||
ctx->trid = *trid;
|
||||
|
||||
spdk_nvme_ctrlr_get_default_ctrlr_opts(&ctx->opts, sizeof(ctx->opts));
|
||||
|
||||
if (hostnqn) {
|
||||
snprintf(opts.hostnqn, sizeof(opts.hostnqn), "%s", hostnqn);
|
||||
snprintf(ctx->opts.hostnqn, sizeof(ctx->opts.hostnqn), "%s", hostnqn);
|
||||
}
|
||||
|
||||
if (hostid->hostaddr[0] != '\0') {
|
||||
snprintf(opts.src_addr, sizeof(opts.src_addr), "%s", hostid->hostaddr);
|
||||
snprintf(ctx->opts.src_addr, sizeof(ctx->opts.src_addr), "%s", hostid->hostaddr);
|
||||
}
|
||||
|
||||
if (hostid->hostsvcid[0] != '\0') {
|
||||
snprintf(opts.src_svcid, sizeof(opts.src_svcid), "%s", hostid->hostsvcid);
|
||||
snprintf(ctx->opts.src_svcid, sizeof(ctx->opts.src_svcid), "%s", hostid->hostsvcid);
|
||||
}
|
||||
|
||||
ctrlr = spdk_nvme_connect(trid, &opts, sizeof(opts));
|
||||
if (!ctrlr) {
|
||||
SPDK_ERRLOG("Failed to create new device\n");
|
||||
ctx->probe_ctx = spdk_nvme_connect_async(trid, &ctx->opts, connect_attach_cb);
|
||||
if (ctx->probe_ctx == NULL) {
|
||||
SPDK_ERRLOG("No controller was found with provided trid (traddr: %s)\n", trid->traddr);
|
||||
free(ctx);
|
||||
return -1;
|
||||
}
|
||||
ctx->poller = spdk_poller_register(bdev_nvme_async_poll, ctx, 1000);
|
||||
|
||||
rc = bdev_nvme_create_and_get_bdev_names(ctrlr, base_name, names,
|
||||
count, trid, prchk_flags);
|
||||
if (rc == 0 && cb_fn) {
|
||||
cb_fn(cb_ctx);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -54,7 +54,7 @@ struct spdk_bdev_nvme_opts {
|
||||
uint64_t nvme_ioq_poll_period_us;
|
||||
};
|
||||
|
||||
typedef void (*spdk_bdev_nvme_fn)(void *ctx);
|
||||
typedef void (*spdk_bdev_create_nvme_fn)(void *ctx, int rc);
|
||||
struct spdk_nvme_qpair *spdk_bdev_nvme_get_io_qpair(struct spdk_io_channel *ctrlr_io_ch);
|
||||
void spdk_bdev_nvme_get_opts(struct spdk_bdev_nvme_opts *opts);
|
||||
int spdk_bdev_nvme_set_opts(const struct spdk_bdev_nvme_opts *opts);
|
||||
@ -66,7 +66,7 @@ int spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
const char **names, size_t *count,
|
||||
const char *hostnqn,
|
||||
uint32_t prchk_flags,
|
||||
spdk_bdev_nvme_fn cb_fn,
|
||||
spdk_bdev_create_nvme_fn cb_fn,
|
||||
void *cb_ctx);
|
||||
struct spdk_nvme_ctrlr *spdk_bdev_nvme_get_ctrlr(struct spdk_bdev *bdev);
|
||||
|
||||
|
@ -213,7 +213,7 @@ struct rpc_create_nvme_bdev_ctx {
|
||||
};
|
||||
|
||||
static void
|
||||
spdk_rpc_construct_nvme_bdev_done(void *cb_ctx)
|
||||
spdk_rpc_construct_nvme_bdev_done(void *cb_ctx, int rc)
|
||||
{
|
||||
struct rpc_create_nvme_bdev_ctx *ctx = cb_ctx;
|
||||
struct spdk_jsonrpc_request *request = ctx->request;
|
||||
@ -225,7 +225,7 @@ spdk_rpc_construct_nvme_bdev_done(void *cb_ctx)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ctx->count == 0) {
|
||||
if (rc < 0) {
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
|
||||
goto exit;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user