diff --git a/examples/nvme/identify/identify.c b/examples/nvme/identify/identify.c index 88229586b..50d70262b 100644 --- a/examples/nvme/identify/identify.c +++ b/examples/nvme/identify/identify.c @@ -1,8 +1,8 @@ /*- * BSD LICENSE * - * Copyright (c) Intel Corporation. - * All rights reserved. + * Copyright (c) Intel Corporation. All rights reserved. + * Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -104,6 +104,7 @@ static int g_main_core = 0; static char g_core_mask[16] = "0x1"; static struct spdk_nvme_transport_id g_trid; +static char g_hostnqn[SPDK_NVMF_NQN_MAX_LEN + 1]; static int g_controllers_found = 0; @@ -1911,6 +1912,7 @@ usage(const char *program_name) printf(" traddr Transport address (e.g. 192.168.100.8)\n"); printf(" trsvcid Transport service identifier (e.g. 4420)\n"); printf(" subnqn Subsystem NQN (default: %s)\n", SPDK_NVMF_DISCOVERY_NQN); + printf(" hostnqn Host NQN\n"); printf(" Example: -r 'trtype:RDMA adrfam:IPv4 traddr:192.168.100.8 trsvcid:4420'\n"); spdk_log_usage(stdout, "-L"); @@ -1929,6 +1931,7 @@ static int parse_args(int argc, char **argv) { int op, rc; + char *hostnqn; spdk_nvme_trid_populate_transport(&g_trid, SPDK_NVME_TRANSPORT_PCIE); snprintf(g_trid.subnqn, sizeof(g_trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN); @@ -1965,6 +1968,22 @@ parse_args(int argc, char **argv) fprintf(stderr, "Error parsing transport address\n"); return 1; } + + hostnqn = strcasestr(optarg, "hostnqn:"); + if (hostnqn) { + size_t len; + + hostnqn += strlen("hostnqn:"); + + len = strcspn(hostnqn, " \t\n"); + if (len > (sizeof(g_hostnqn) - 1)) { + fprintf(stderr, "Host NQN is too long\n"); + return 1; + } + + memcpy(g_hostnqn, hostnqn, len); + g_hostnqn[len] = '\0'; + } break; case 'x': g_hex_dump = true; @@ -1999,6 +2018,7 @@ static bool probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, struct spdk_nvme_ctrlr_opts *opts) { + memcpy(opts->hostnqn, g_hostnqn, sizeof(opts->hostnqn)); return true; } @@ -2045,7 +2065,11 @@ int main(int argc, char **argv) /* A specific trid is required. */ if (strlen(g_trid.traddr) != 0) { - ctrlr = spdk_nvme_connect(&g_trid, NULL, 0); + struct spdk_nvme_ctrlr_opts opts; + + spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts)); + memcpy(opts.hostnqn, g_hostnqn, sizeof(opts.hostnqn)); + ctrlr = spdk_nvme_connect(&g_trid, &opts, sizeof(opts)); if (!ctrlr) { fprintf(stderr, "spdk_nvme_connect() failed\n"); return 1; diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index 7a4cbaef9..96deedec9 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -4,7 +4,7 @@ * Copyright (c) Intel Corporation. * All rights reserved. * - * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. + * Copyright (c) 2019-2020 Mellanox Technologies LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -266,6 +266,7 @@ static uint32_t g_allowed_pci_addr_num; struct trid_entry { struct spdk_nvme_transport_id trid; uint16_t nsid; + char hostnqn[SPDK_NVMF_NQN_MAX_LEN + 1]; TAILQ_ENTRY(trid_entry) tailq; }; @@ -1411,6 +1412,7 @@ static void usage(char *program_name) printf("\t traddr Transport address (e.g. 0000:04:00.0 for PCIe or 192.168.100.8 for RDMA)\n"); printf("\t trsvcid Transport service identifier (e.g. 4420)\n"); printf("\t subnqn Subsystem NQN (default: %s)\n", SPDK_NVMF_DISCOVERY_NQN); + printf("\t hostnqn Host NQN\n"); printf("\t Example: -r 'trtype:PCIe traddr:0000:04:00.0' for PCIe or\n"); printf("\t -r 'trtype:RDMA adrfam:IPv4 traddr:192.168.100.8 trsvcid:4420' for NVMeoF\n"); printf("\t[-e metadata configuration]\n"); @@ -1677,6 +1679,7 @@ add_trid(const char *trid_str) struct trid_entry *trid_entry; struct spdk_nvme_transport_id *trid; char *ns; + char *hostnqn; trid_entry = calloc(1, sizeof(*trid_entry)); if (trid_entry == NULL) { @@ -1724,6 +1727,23 @@ add_trid(const char *trid_str) trid_entry->nsid = (uint16_t)nsid; } + hostnqn = strcasestr(trid_str, "hostnqn:"); + if (hostnqn) { + size_t len; + + hostnqn += strlen("hostnqn:"); + + len = strcspn(hostnqn, " \t\n"); + if (len > (sizeof(trid_entry->hostnqn) - 1)) { + fprintf(stderr, "Host NQN is too long\n"); + free(trid_entry); + return 1; + } + + memcpy(trid_entry->hostnqn, hostnqn, len); + trid_entry->hostnqn[len] = '\0'; + } + TAILQ_INSERT_TAIL(&g_trid_list, trid_entry, tailq); return 0; } @@ -2128,6 +2148,8 @@ static bool probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, struct spdk_nvme_ctrlr_opts *opts) { + struct trid_entry *trid_entry = cb_ctx; + if (trid->trtype == SPDK_NVME_TRANSPORT_PCIE) { if (g_disable_sq_cmb) { opts->use_cmb_sqs = false; @@ -2147,6 +2169,7 @@ probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, opts->header_digest = g_header_digest; opts->data_digest = g_data_digest; opts->keep_alive_timeout_ms = g_keep_alive_timeout_in_ms; + memcpy(opts->hostnqn, trid_entry->hostnqn, sizeof(opts->hostnqn)); return true; } diff --git a/lib/nvme/nvme.c b/lib/nvme/nvme.c index 32f60e2a3..9f227bb37 100644 --- a/lib/nvme/nvme.c +++ b/lib/nvme/nvme.c @@ -1318,6 +1318,8 @@ spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *st continue; } else if (strcasecmp(key, "hostsvcid") == 0) { continue; + } else if (strcasecmp(key, "hostnqn") == 0) { + continue; } else if (strcasecmp(key, "ns") == 0) { /* * Special case. The namespace id parameter may