]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
examples: Add loop discover example
authorKeith Busch <kbusch@kernel.org>
Fri, 7 Feb 2020 00:43:45 +0000 (16:43 -0800)
committerKeith Busch <kbusch@kernel.org>
Fri, 7 Feb 2020 00:43:45 +0000 (16:43 -0800)
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 <kbusch@kernel.org>
.gitignore
examples/Makefile
examples/discover-loop.c [new file with mode: 0644]
examples/display-columnar.c
src/Makefile
src/libnvme.map
src/nvme/fabrics.c
src/nvme/ioctl.c
src/nvme/util.c
src/nvme/util.h

index 2cef1e0bc1af75c4138b995ffb9d2b476de616d5..364c1d0e861d0d680130a42f3e8f2e4f5801bbfd 100644 (file)
@@ -12,6 +12,7 @@ test/test
 examples/display-tree
 examples/display-columnar
 examples/telemetry-listen
+examples/discover-loop
 
 config-host.h
 config-host.mak
index 5c4a082e80aeec32ec449d9a589d7425783f3b3b..0a70e9b812a4aad63fa05c0c05f667ebb8e0fa48 100644 (file)
@@ -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 (file)
index 0000000..6b9d01f
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <libnvme.h>
+
+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;
+}
index b3dbc7ea86d9ca3b1b301a3923094c3d712c8c2c..014c8dc44de34e838918658793a0f79e6c4370b5 100644 (file)
@@ -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 <stdio.h>
 #include <libnvme.h>
index 396e8caf8ea77cdaaed2ddb3fd74e5cff1d57471..6b5847480e18500a71f027b5ac17d96033942632 100644 (file)
@@ -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
index fbb3355b4fa9bde21e54b3d41426a2c390e2ee98..6fb0c9e2c92414fab887bf8fe60fdc92caf7edee 100644 (file)
                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;
index 56e97fcad6232995fdaac279ec518b5fc7a2d488..2e232ddf70671b78b59254d4b3fd9b28baa766e1 100644 (file)
@@ -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,
index ab7b022f010ec44fb07bcf367f2bd472ccd1bd49..a0d22f77163a75541b7d4479487efe8264cfbb84 100644 (file)
@@ -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;
index 9b0c68be7491fc3760dcce909ee8d5bb6336b172..6234ea0e655b768c650d1977488a4422ac706b6b 100644 (file)
@@ -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)
 {
index d608eef20c047a3560de3b2e523b31682777603b..04bd88d4b57a295d19914ab995b3b5e9d5aac7f8 100644 (file)
@@ -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);