lib/nvmf: custom admin handler config

This commit disables the custom identify handler by default.
The user has to explictly enable this handler via the set_nvmf_config
RPC or conf file.

Change-Id: I767816ba7639ebe78683993408ce6db02c7620fe
Signed-off-by: Michael Haeuptle <michael.haeuptle@hpe.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479603
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Michael Haeuptle 2020-01-07 23:01:43 +00:00 committed by Tomasz Zawadzki
parent e93902a03d
commit c9874b91a7
8 changed files with 58 additions and 6 deletions

View File

@ -33,9 +33,8 @@ in `spdk_internal/nvmf.h` expose this functionality. There is an example custom
for the NVMe IDENTIFY CTRLR in `lib/nvmf/custom_cmd_hdlr.c`. This handler gets the SN, MN, FR, IEEE, FGUID
attributes from the first NVMe drive in the NVMF subsystem and returns it to the NVMF initiator (sn and mn attributes
specified during NVMF subsystem creation RPC will be overwritten).
This handler is enabled by default and can be disabled by adding
`spdk_nvmf_set_custom_admin_cmd_hdlr(SPDK_NVME_OPC_IDENTIFY, NULL);` to a target application.
This handler can be enabled via the `nvmf_set_config` RPC.
Note: In a future version of SPDK, this handler will be enabled by default.
### sock

View File

@ -4313,6 +4313,13 @@ have been initialized.
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
acceptor_poll_rate | Optional | number | Polling interval of the acceptor for incoming connections (microseconds)
admin_cmd_passthru | Optional | object | Admin command passthru configuration
### admin_cmd_passthru {#spdk_nvmf_admin_passthru_conf}
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
identify_ctrlr | Required | bool | If true, enables custom identify handler that reports some identify attributes from the underlying NVMe drive
### Example

View File

@ -136,6 +136,9 @@ spdk_nvmf_read_config_file_tgt_conf(struct spdk_conf_section *sp,
"we will use RoundRobin as the default scheduler\n");
}
conf->admin_passthru.identify_ctrlr = spdk_conf_section_get_boolval(sp,
"AdminCmdPassthruIdentifyCtrlr", false);
return rc;
}
@ -168,6 +171,7 @@ spdk_nvmf_parse_tgt_conf(void)
conf->acceptor_poll_rate = ACCEPT_TIMEOUT_US;
conf->conn_sched = DEFAULT_CONN_SCHED;
conf->admin_passthru.identify_ctrlr = false;
sp = spdk_conf_find_section(NULL, "Nvmf");
if (sp != NULL) {

View File

@ -51,9 +51,14 @@ enum spdk_nvmf_connect_sched {
CONNECT_SCHED_TRANSPORT_OPTIMAL_GROUP,
};
struct spdk_nvmf_admin_passthru_conf {
bool identify_ctrlr;
};
struct spdk_nvmf_tgt_conf {
uint32_t acceptor_poll_rate;
enum spdk_nvmf_connect_sched conn_sched;
struct spdk_nvmf_admin_passthru_conf admin_passthru;
};
extern struct spdk_nvmf_tgt_conf *g_spdk_nvmf_tgt_conf;

View File

@ -92,9 +92,28 @@ static int decode_conn_sched(const struct spdk_json_val *val, void *out)
return 0;
}
static const struct spdk_json_object_decoder admin_passthru_decoder[] = {
{"identify_ctrlr", offsetof(struct spdk_nvmf_admin_passthru_conf, identify_ctrlr), spdk_json_decode_bool}
};
static int decode_admin_passthru(const struct spdk_json_val *val, void *out)
{
struct spdk_nvmf_admin_passthru_conf *req = (struct spdk_nvmf_admin_passthru_conf *)out;
if (spdk_json_decode_object(val, admin_passthru_decoder,
SPDK_COUNTOF(admin_passthru_decoder),
req)) {
SPDK_ERRLOG("spdk_json_decode_object failed\n");
return -1;
}
return 0;
}
static const struct spdk_json_object_decoder nvmf_rpc_subsystem_tgt_conf_decoder[] = {
{"acceptor_poll_rate", offsetof(struct spdk_nvmf_tgt_conf, acceptor_poll_rate), spdk_json_decode_uint32, true},
{"conn_sched", offsetof(struct spdk_nvmf_tgt_conf, conn_sched), decode_conn_sched, true},
{"admin_cmd_passthru", offsetof(struct spdk_nvmf_tgt_conf, admin_passthru), decode_admin_passthru, true}
};
static void
@ -121,6 +140,7 @@ spdk_rpc_nvmf_set_config(struct spdk_jsonrpc_request *request,
conf->acceptor_poll_rate = ACCEPT_TIMEOUT_US;
conf->conn_sched = DEFAULT_CONN_SCHED;
conf->admin_passthru.identify_ctrlr = false;
if (params != NULL) {
if (spdk_json_decode_object(params, nvmf_rpc_subsystem_tgt_conf_decoder,

View File

@ -438,7 +438,6 @@ nvmf_tgt_advance_state(void)
switch (g_tgt_state) {
case NVMF_TGT_INIT_NONE: {
spdk_nvmf_set_custom_admin_cmd_hdlr(SPDK_NVME_OPC_IDENTIFY, spdk_nvmf_custom_identify_hdlr);
g_tgt_state = NVMF_TGT_INIT_PARSE_CONFIG;
break;
}
@ -449,6 +448,11 @@ nvmf_tgt_advance_state(void)
spdk_thread_send_msg(spdk_get_thread(), nvmf_tgt_parse_conf_start, NULL);
break;
case NVMF_TGT_INIT_CREATE_POLL_GROUPS:
/* Config parsed */
if (g_spdk_nvmf_tgt_conf->admin_passthru.identify_ctrlr) {
SPDK_NOTICELOG("Custom identify ctrlr handler enabled\n");
spdk_nvmf_set_custom_admin_cmd_hdlr(SPDK_NVME_OPC_IDENTIFY, spdk_nvmf_custom_identify_hdlr);
}
/* Send a message to each thread and create a poll group */
spdk_for_each_thread(nvmf_tgt_create_poll_group,
NULL,
@ -542,6 +546,10 @@ spdk_nvmf_subsystem_write_config_json(struct spdk_json_write_ctx *w)
spdk_json_write_named_uint32(w, "acceptor_poll_rate", g_spdk_nvmf_tgt_conf->acceptor_poll_rate);
spdk_json_write_named_string(w, "conn_sched",
get_conn_sched_string(g_spdk_nvmf_tgt_conf->conn_sched));
spdk_json_write_named_object_begin(w, "admin_cmd_passthru");
spdk_json_write_named_bool(w, "identify_ctrlr",
g_spdk_nvmf_tgt_conf->admin_passthru.identify_ctrlr);
spdk_json_write_object_end(w);
spdk_json_write_object_end(w);
spdk_json_write_object_end(w);

View File

@ -1651,7 +1651,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
def nvmf_set_config(args):
rpc.nvmf.nvmf_set_config(args.client,
acceptor_poll_rate=args.acceptor_poll_rate,
conn_sched=args.conn_sched)
conn_sched=args.conn_sched,
passthru_identify_ctrlr=args.passthru_identify_ctrlr)
p = subparsers.add_parser('nvmf_set_config', aliases=['set_nvmf_target_config'],
help='Set NVMf target config')
@ -1660,6 +1661,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
on the cores in a round robin manner (Default). 'hostip' - Schedule all the incoming connections from a
specific host IP on to the same core. Connections from different IP will be assigned to cores in a round
robin manner. 'transport' - Schedule the connection according to the transport characteristics.""")
p.add_argument('-i', '--passthru-identify-ctrlr', help="""Passthrough fields like serial number and model number
when the controller has a single namespace that is an NVMe bdev""", action='store_true')
p.set_defaults(func=nvmf_set_config)
def nvmf_create_transport(args):

View File

@ -21,7 +21,8 @@ def nvmf_set_max_subsystems(client,
@deprecated_alias('set_nvmf_target_config')
def nvmf_set_config(client,
acceptor_poll_rate=None,
conn_sched=None):
conn_sched=None,
passthru_identify_ctrlr=None):
"""Set NVMe-oF target subsystem configuration.
Args:
@ -37,6 +38,11 @@ def nvmf_set_config(client,
params['acceptor_poll_rate'] = acceptor_poll_rate
if conn_sched:
params['conn_sched'] = conn_sched
if passthru_identify_ctrlr:
admin_cmd_passthru = {}
admin_cmd_passthru['identify_ctrlr'] = passthru_identify_ctrlr
params['admin_cmd_passthru'] = admin_cmd_passthru
return client.call('nvmf_set_config', params)