bdev/nvme: make construct nvme device RPC can be executed asynchronously
This is the first step which adds the callback for construct NVMe controller RPC, the next patch will add the asynchronous probe support. Change-Id: Ib681d78b544c62f6f1ef66e298cd91f71c34cbc7 Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/447030 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: wuzhouhui <wuzhouhui@kingsoft.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
8ca0fbcec0
commit
e208be6f1d
@ -1180,8 +1180,11 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
const char *base_name,
|
||||
const char **names, size_t *count,
|
||||
const char *hostnqn,
|
||||
uint32_t prchk_flags)
|
||||
uint32_t prchk_flags,
|
||||
spdk_bdev_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;
|
||||
@ -1226,8 +1229,13 @@ spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return bdev_nvme_create_and_get_bdev_names(ctrlr, base_name, names,
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -53,6 +53,7 @@ struct spdk_bdev_nvme_opts {
|
||||
uint64_t nvme_adminq_poll_period_us;
|
||||
};
|
||||
|
||||
typedef void (*spdk_bdev_nvme_fn)(void *ctx);
|
||||
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);
|
||||
@ -63,7 +64,9 @@ int spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
|
||||
const char *base_name,
|
||||
const char **names, size_t *count,
|
||||
const char *hostnqn,
|
||||
uint32_t prchk_flags);
|
||||
uint32_t prchk_flags,
|
||||
spdk_bdev_nvme_fn cb_fn,
|
||||
void *cb_ctx);
|
||||
struct spdk_nvme_ctrlr *spdk_bdev_nvme_get_ctrlr(struct spdk_bdev *bdev);
|
||||
|
||||
/**
|
||||
|
@ -204,98 +204,124 @@ static const struct spdk_json_object_decoder rpc_construct_nvme_decoders[] = {
|
||||
|
||||
#define NVME_MAX_BDEVS_PER_RPC 128
|
||||
|
||||
struct rpc_create_nvme_bdev_ctx {
|
||||
struct rpc_construct_nvme req;
|
||||
size_t count;
|
||||
const char *names[NVME_MAX_BDEVS_PER_RPC];
|
||||
struct spdk_jsonrpc_request *request;
|
||||
};
|
||||
|
||||
static void
|
||||
spdk_rpc_construct_nvme_bdev_done(void *cb_ctx)
|
||||
{
|
||||
struct rpc_create_nvme_bdev_ctx *ctx = cb_ctx;
|
||||
struct spdk_jsonrpc_request *request = ctx->request;
|
||||
struct spdk_json_write_ctx *w;
|
||||
size_t i;
|
||||
|
||||
w = spdk_jsonrpc_begin_result(request);
|
||||
if (w == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ctx->count == 0) {
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
spdk_json_write_array_begin(w);
|
||||
for (i = 0; i < ctx->count; i++) {
|
||||
spdk_json_write_string(w, ctx->names[i]);
|
||||
}
|
||||
spdk_json_write_array_end(w);
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
|
||||
exit:
|
||||
free_rpc_construct_nvme(&ctx->req);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_rpc_construct_nvme_bdev(struct spdk_jsonrpc_request *request,
|
||||
const struct spdk_json_val *params)
|
||||
{
|
||||
struct rpc_construct_nvme req = {};
|
||||
struct spdk_json_write_ctx *w;
|
||||
struct rpc_create_nvme_bdev_ctx *ctx;
|
||||
struct spdk_nvme_transport_id trid = {};
|
||||
struct spdk_nvme_host_id hostid = {};
|
||||
const char *names[NVME_MAX_BDEVS_PER_RPC];
|
||||
size_t count;
|
||||
size_t i;
|
||||
uint32_t prchk_flags = 0;
|
||||
int rc;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, spdk_strerror(ENOMEM));
|
||||
return;
|
||||
}
|
||||
|
||||
if (spdk_json_decode_object(params, rpc_construct_nvme_decoders,
|
||||
SPDK_COUNTOF(rpc_construct_nvme_decoders),
|
||||
&req)) {
|
||||
&ctx->req)) {
|
||||
SPDK_ERRLOG("spdk_json_decode_object failed\n");
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
/* Parse trtype */
|
||||
rc = spdk_nvme_transport_id_parse_trtype(&trid.trtype, req.trtype);
|
||||
rc = spdk_nvme_transport_id_parse_trtype(&trid.trtype, ctx->req.trtype);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Failed to parse trtype: %s\n", req.trtype);
|
||||
SPDK_ERRLOG("Failed to parse trtype: %s\n", ctx->req.trtype);
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
/* Parse traddr */
|
||||
snprintf(trid.traddr, sizeof(trid.traddr), "%s", req.traddr);
|
||||
snprintf(trid.traddr, sizeof(trid.traddr), "%s", ctx->req.traddr);
|
||||
|
||||
/* Parse adrfam */
|
||||
if (req.adrfam) {
|
||||
rc = spdk_nvme_transport_id_parse_adrfam(&trid.adrfam, req.adrfam);
|
||||
if (ctx->req.adrfam) {
|
||||
rc = spdk_nvme_transport_id_parse_adrfam(&trid.adrfam, ctx->req.adrfam);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("Failed to parse adrfam: %s\n", req.adrfam);
|
||||
SPDK_ERRLOG("Failed to parse adrfam: %s\n", ctx->req.adrfam);
|
||||
goto invalid;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse trsvcid */
|
||||
if (req.trsvcid) {
|
||||
snprintf(trid.trsvcid, sizeof(trid.trsvcid), "%s", req.trsvcid);
|
||||
if (ctx->req.trsvcid) {
|
||||
snprintf(trid.trsvcid, sizeof(trid.trsvcid), "%s", ctx->req.trsvcid);
|
||||
}
|
||||
|
||||
/* Parse subnqn */
|
||||
if (req.subnqn) {
|
||||
snprintf(trid.subnqn, sizeof(trid.subnqn), "%s", req.subnqn);
|
||||
if (ctx->req.subnqn) {
|
||||
snprintf(trid.subnqn, sizeof(trid.subnqn), "%s", ctx->req.subnqn);
|
||||
}
|
||||
|
||||
if (req.hostaddr) {
|
||||
snprintf(hostid.hostaddr, sizeof(hostid.hostaddr), "%s", req.hostaddr);
|
||||
if (ctx->req.hostaddr) {
|
||||
snprintf(hostid.hostaddr, sizeof(hostid.hostaddr), "%s", ctx->req.hostaddr);
|
||||
}
|
||||
|
||||
if (req.hostsvcid) {
|
||||
snprintf(hostid.hostsvcid, sizeof(hostid.hostsvcid), "%s", req.hostsvcid);
|
||||
if (ctx->req.hostsvcid) {
|
||||
snprintf(hostid.hostsvcid, sizeof(hostid.hostsvcid), "%s", ctx->req.hostsvcid);
|
||||
}
|
||||
|
||||
if (req.prchk_reftag) {
|
||||
if (ctx->req.prchk_reftag) {
|
||||
prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_REFTAG;
|
||||
}
|
||||
|
||||
if (req.prchk_guard) {
|
||||
if (ctx->req.prchk_guard) {
|
||||
prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_GUARD;
|
||||
}
|
||||
|
||||
count = NVME_MAX_BDEVS_PER_RPC;
|
||||
if (spdk_bdev_nvme_create(&trid, &hostid, req.name, names, &count, req.hostnqn,
|
||||
prchk_flags)) {
|
||||
ctx->request = request;
|
||||
ctx->count = NVME_MAX_BDEVS_PER_RPC;
|
||||
if (spdk_bdev_nvme_create(&trid, &hostid, ctx->req.name, ctx->names, &ctx->count, ctx->req.hostnqn,
|
||||
prchk_flags, spdk_rpc_construct_nvme_bdev_done, ctx)) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
w = spdk_jsonrpc_begin_result(request);
|
||||
if (w == NULL) {
|
||||
free_rpc_construct_nvme(&req);
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_json_write_array_begin(w);
|
||||
for (i = 0; i < count; i++) {
|
||||
spdk_json_write_string(w, names[i]);
|
||||
}
|
||||
spdk_json_write_array_end(w);
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
|
||||
free_rpc_construct_nvme(&req);
|
||||
|
||||
return;
|
||||
|
||||
invalid:
|
||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
|
||||
free_rpc_construct_nvme(&req);
|
||||
free_rpc_construct_nvme(&ctx->req);
|
||||
free(ctx);
|
||||
}
|
||||
SPDK_RPC_REGISTER("construct_nvme_bdev", spdk_rpc_construct_nvme_bdev, SPDK_RPC_RUNTIME)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user