From: Keith Busch Date: Fri, 7 Feb 2020 00:43:45 +0000 (-0800) Subject: examples: Add loop discover example X-Git-Tag: v1.0-rc0~194 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=339364742b85f2d1944cff9bad53f64f7674a54e;p=users%2Fsagi%2Flibnvme.git examples: Add loop discover example A basic fabrics example discoverying loop nvme fabric targets. Apply fixes and updates to lib code as needed from testing. Signed-off-by: Keith Busch --- diff --git a/.gitignore b/.gitignore index 2cef1e0b..364c1d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ test/test examples/display-tree examples/display-columnar examples/telemetry-listen +examples/discover-loop config-host.h config-host.mak diff --git a/examples/Makefile b/examples/Makefile index 5c4a082e..0a70e9b8 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -lsystemd include ../Makefile.quiet @@ -7,11 +7,11 @@ ifneq ($(MAKECMDGOALS),clean) include ../config-host.mak endif -all_targets += telemetry-listen display-tree display-columnar +all_targets += telemetry-listen display-tree display-columnar discover-loop all: $(all_targets) -test_srcs := telemetry-listen.c display-tree.c display-columnar.c +test_srcs := telemetry-listen.c display-tree.c display-columnar.c discover-loop.c test_objs := $(patsubst %.c,%.ol,$(test_srcs)) diff --git a/examples/discover-loop.c b/examples/discover-loop.c new file mode 100644 index 00000000..6b9d01ff --- /dev/null +++ b/examples/discover-loop.c @@ -0,0 +1,72 @@ +/** + * discover-loop: Use fabrics commands to discover any loop targets and print + * those records. You must have at least one configured nvme loop target on the + * system (no existing connection required). The output will look more + * interesting with more targets. + */ +#include +#include +#include +#include +#include + +static void print_discover_log(struct nvmf_discovery_log *log) +{ + int i, numrec = le64_to_cpu(log->numrec); + + printf(".\n"); + printf("|-- genctr:%llx\n", log->genctr); + printf("|-- numrec:%x\n", numrec); + printf("`-- recfmt:%x\n", log->recfmt); + + for (i = 0; i < numrec; i++) { + struct nvmf_disc_log_entry *e = &log->entries[i]; + + printf(" %c-- Entry:%d\n", (i < numrec - 1) ? '|' : '`', i); + printf(" %c |-- trtype:%x\n", (i < numrec - 1) ? '|' : ' ', e->trtype); + printf(" %c |-- adrfam:%x\n", (i < numrec - 1) ? '|' : ' ', e->adrfam); + printf(" %c |-- subtype:%x\n", (i < numrec - 1) ? '|' : ' ', e->subtype); + printf(" %c |-- treq:%x\n", (i < numrec - 1) ? '|' : ' ', e->treq); + printf(" %c |-- portid:%x\n", (i < numrec - 1) ? '|' : ' ', e->portid); + printf(" %c |-- cntlid:%x\n", (i < numrec - 1) ? '|' : ' ', e->cntlid); + printf(" %c |-- asqsz:%x\n", (i < numrec - 1) ? '|' : ' ', e->asqsz); + printf(" %c |-- trsvcid:%s\n", (i < numrec - 1) ? '|' : ' ', e->trsvcid); + printf(" %c |-- subnqn:%s\n", (i < numrec - 1) ? '|' : ' ', e->subnqn); + printf(" %c `-- traddr:%s\n", (i < numrec - 1) ? '|' : ' ', e->traddr); + } +} + +int main() +{ + struct nvmf_discovery_log *log = NULL; + nvme_ctrl_t c; + char *hnqn; + int ret; + + struct nvme_fabrics_config cfg = { + .nqn = NVME_DISC_SUBSYS_NAME, + .transport = "loop", + .tos = -1, + }; + + hnqn = nvmf_hostnqn_from_file(), + cfg.hostnqn = hnqn; + + c = nvmf_add_ctrl(&cfg); + if (!c) { + fprintf(stderr, "no controller found\n"); + return errno; + } + + ret = nvmf_get_discovery_log(c, &log, 4); + nvme_ctrl_disconnect(c); + nvme_free_ctrl(c); + + if (ret) + fprintf(stderr, "nvmf-discover-log:%x\n", ret); + else + print_discover_log(log); + + free(hnqn); + return 0; +} diff --git a/examples/display-columnar.c b/examples/display-columnar.c index b3dbc7ea..014c8dc4 100644 --- a/examples/display-columnar.c +++ b/examples/display-columnar.c @@ -1,6 +1,6 @@ /** - * display-tree: Scans the nvme topology, prints as an ascii tree with some - * selected attributes for each component. + * display-columnar: Scans the nvme topology, prints each record type in a + * column format for easy visual scanning. */ #include #include diff --git a/src/Makefile b/src/Makefile index 396e8caf..6b584748 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,7 +10,7 @@ CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) -LINK_FLAGS= -L /usr/lib64 +LINK_FLAGS= -L /usr/lib64 -lsystemd LINK_FLAGS+=$(LDFLAGS) ENABLE_SHARED ?= 1 SED ?= sed diff --git a/src/libnvme.map b/src/libnvme.map index fbb3355b..6fb0c9e2 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -216,6 +216,7 @@ nvme_setup_ctrl_list; nvme_dsm_range; nvme_get_log_page; + __nvme_get_log_page; nvme_get_ana_log_len; nvme_namespace_attach_ctrls; nvme_namespace_detach_ctrls; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 56e97fca..2e232ddf 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -154,8 +154,6 @@ int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg) return ret; ret = __nvmf_add_ctrl(argstr); - printf("ctrl:%s ret:%d\n", argstr, ret); - free(argstr); return ret; } @@ -229,7 +227,23 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, errno = EINVAL; return NULL; } - cfg.transport = nvmf_trtype_str(e->trtype); + + switch (e->trtype) { + case NVMF_TRTYPE_RDMA: + cfg.transport = "rdma"; + break; + case NVMF_TRTYPE_FC: + cfg.transport = "fc"; + break; + case NVMF_TRTYPE_TCP: + cfg.transport = "tcp"; + break; + case NVMF_TRTYPE_LOOP: + cfg.transport = "loop"; + break; + default: + break; + } cfg.nqn = e->subnqn; if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) @@ -248,7 +262,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) { - return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, len, log); + return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, 512, len, log); } int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index ab7b022f..a0d22f77 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -18,10 +18,9 @@ static int nvme_verify_chr(int fd) static struct stat nvme_stat; int err = fstat(fd, &nvme_stat); - if (err < 0) { - perror("fstat"); + if (err < 0) return errno; - } + if (!S_ISCHR(nvme_stat.st_mode)) { errno = ENOTBLK; return -1; diff --git a/src/nvme/util.c b/src/nvme/util.c index 9b0c68be..6234ea0e 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -231,10 +231,10 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, return err; } -int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data) +int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data) { - __u64 offset = 0, xfer_len = data_len; + __u64 offset = 0, xfer; void *ptr = data; int ret; @@ -243,23 +243,29 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * avoids having to check the MDTS value of the controller. */ do { - xfer_len = data_len - offset; - if (xfer_len > 4096) - xfer_len = 4096; + xfer = data_len - offset; + if (xfer > xfer_len) + xfer = xfer_len; ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - xfer_len, ptr); + xfer, ptr); if (ret) return ret; - offset += xfer_len; - ptr += xfer_len; + offset += xfer; + ptr += xfer; } while (offset < data_len); return 0; } +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data) +{ + return __nvme_get_log_page(fd, nsid, log_id, rae, 4086, data_len, data); +} + int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, void **buf, __u32 *log_size) { diff --git a/src/nvme/util.h b/src/nvme/util.h index d608eef2..04bd88d4 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -72,8 +72,29 @@ void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges); +/** + * __nvme_get_log_page() - + * @fd: + * @nsid: + * @log_id: + * @rae: + * @xfer_len: Max partial log transfer size to request while splitting + * @data_len: + * @data: + */ +int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data); + /** * nvme_get_log_page() - + * @fd: + * @nsid: + * @log_id: + * @rae: + * @data_len: + * @data: + * + * Calls __nvme_get_log_page() with a default 4k transfer length. */ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data);