]> www.infradead.org Git - users/hch/nvme-cli.git/commitdiff
Use a systemd app-specific machine ID for hostnqn
authorAndy Lutomirski <luto@kernel.org>
Thu, 3 Oct 2019 18:47:02 +0000 (11:47 -0700)
committerAndy Lutomirski <luto@kernel.org>
Thu, 3 Oct 2019 18:52:40 +0000 (11:52 -0700)
If /etc/nvme/hostnqn is not present, the fabric commands will ask
systemd for an app-specific machine ID as a fallback.  This should
improve functionality if /etc/nvme/hostnqn is not present and should
allow packagers to avoid creating /etc/nvme/hostnqn.

Heavily based on an earlier patch from Tomasz Torcz.

Signed-off-by: Tomasz Torcz <tomek@pipebreaker.pl>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Documentation/nvme-show-hostnqn.txt [new file with mode: 0644]
Makefile
fabrics.c
fabrics.h
nvme-builtin.h
nvme.c

diff --git a/Documentation/nvme-show-hostnqn.txt b/Documentation/nvme-show-hostnqn.txt
new file mode 100644 (file)
index 0000000..044346c
--- /dev/null
@@ -0,0 +1,29 @@
+nvme-show-hostnqn(1)
+===================
+
+NAME
+----
+nvme-show-hostnqn - Generate a host NVMe Qualified Name
+
+SYNOPSIS
+--------
+[verse]
+'nvme show-hostnqn'
+
+DESCRIPTION
+-----------
+Show the host NQN configured for the system.  If /etc/nvme/hostnqn is
+not present and systemd application-specific machine IDs are available,
+this will show the systemd-generated host NQN for the system.
+
+OPTIONS
+-------
+No options needed
+
+EXAMPLES
+--------
+nvme show-hostnqn
+
+NVME
+----
+Part of the nvme-user suite
index 66632a31406b8494874969840cbf46807bb13cc7..3470493786d8b6372aa657ee37782dd7353bde51 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,7 @@ CFLAGS ?= -O2 -g -Wall -Werror
 override CFLAGS += -std=gnu99 -I.
 override CPPFLAGS += -D_GNU_SOURCE -D__CHECK_ENDIAN__
 LIBUUID = $(shell $(LD) -o /dev/null -luuid >/dev/null 2>&1; echo $$?)
+HAVE_SYSTEMD = $(shell pkg-config --exists systemd  --atleast-version=232; echo $$?)
 NVME = nvme
 INSTALL ?= install
 DESTDIR =
@@ -22,6 +23,11 @@ endif
 
 INC=-Iutil
 
+ifeq ($(HAVE_SYSTEMD),0)
+       override LDFLAGS += -lsystemd
+       override CFLAGS += -DHAVE_SYSTEMD
+endif
+
 RPMBUILD = rpmbuild
 TAR = tar
 RM = rm -f
index 85f537142fec07f5fd38847c683ea9a4271b1e83..8982ae4fce50e3b299bed6f7cb2b591d5c9b5656 100644 (file)
--- a/fabrics.c
+++ b/fabrics.c
 
 #include "common.h"
 
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-id128.h>
+#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b)
+#endif
+
 #define NVMF_HOSTID_SIZE       36
 
 static struct config {
@@ -563,11 +568,11 @@ static void save_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
        close(fd);
 }
 
-static int nvmf_hostnqn_file(void)
+static char *hostnqn_read_file(void)
 {
        FILE *f;
        char hostnqn[NVMF_NQN_SIZE];
-       int ret = false;
+       char *ret = NULL;
 
        f = fopen(PATH_NVMF_HOSTNQN, "r");
        if (f == NULL)
@@ -576,16 +581,54 @@ static int nvmf_hostnqn_file(void)
        if (fgets(hostnqn, sizeof(hostnqn), f) == NULL)
                goto out;
 
-       cfg.hostnqn = strndup(hostnqn, strcspn(hostnqn, "\n"));
-       if (!cfg.hostnqn)
-               goto out;
+       ret = strndup(hostnqn, strcspn(hostnqn, "\n"));
 
-       ret = true;
 out:
        fclose(f);
        return ret;
 }
 
+static char *hostnqn_generate_systemd(void)
+{
+#ifdef HAVE_SYSTEMD
+       sd_id128_t id;
+       char *ret;
+
+       if (sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id) < 0)
+               return NULL;
+
+       if (asprintf(&ret, "nqn.2014-08.org.nvmexpress:uuid:" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id)) == -1)
+               ret = NULL;
+
+       return ret;
+#else
+       return NULL;
+#endif
+}
+
+/* returns an allocated string or NULL */
+char *hostnqn_read(void)
+{
+       char *ret;
+
+       ret = hostnqn_read_file();
+       if (ret)
+               return ret;
+
+       ret = hostnqn_generate_systemd();
+       if (ret)
+               return ret;
+
+       return NULL;
+}
+
+static int nvmf_hostnqn_file(void)
+{
+       cfg.hostnqn = hostnqn_read();
+
+       return cfg.hostnqn != NULL;
+}
+
 static int nvmf_hostid_file(void)
 {
        FILE *f;
index 7c1664b80d5125720f8d1356001f0e5598778a61..b8e53f492b5303a93b656c89081815fd5cedfd55 100644 (file)
--- a/fabrics.h
+++ b/fabrics.h
@@ -3,6 +3,8 @@
 
 #define NVMF_DEF_DISC_TMO      30
 
+extern char *hostnqn_read(void);
+
 extern int discover(const char *desc, int argc, char **argv, bool connect);
 extern int connect(const char *desc, int argc, char **argv);
 extern int disconnect(const char *desc, int argc, char **argv);
index bcb59e3444ca3770cbf42d78d2914ede6f907ea8..bfb907dff9ef9655c4598bfd077d9a66a103b64c 100644 (file)
@@ -70,6 +70,7 @@ COMMAND_LIST(
        ENTRY("disconnect", "Disconnect from NVMeoF subsystem", disconnect_cmd)
        ENTRY("disconnect-all", "Disconnect from all connected NVMeoF subsystems", disconnect_all_cmd)
        ENTRY("gen-hostnqn", "Generate NVMeoF host NQN", gen_hostnqn_cmd)
+       ENTRY("show-hostnqn", "Show NVMeoF host NQN", show_hostnqn_cmd)
        ENTRY("dir-receive", "Submit a Directive Receive command, return results", dir_receive)
        ENTRY("dir-send", "Submit a Directive Send command, return results", dir_send)
        ENTRY("virt-mgmt", "Manage Flexible Resources between Primary and Secondary Controller ", virtual_mgmt)
diff --git a/nvme.c b/nvme.c
index 7bf2a50fb0947cd9223bd92d5b82a90fce0d7ee8..88298f60b12535ab7f43a49804d5757505ad515a 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -5026,6 +5026,21 @@ static int gen_hostnqn_cmd(int argc, char **argv, struct command *command, struc
 }
 #endif
 
+static int show_hostnqn_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
+{
+       char *hostnqn;
+
+       hostnqn = hostnqn_read();
+       if (hostnqn) {
+               fputs(hostnqn, stdout);
+               free(hostnqn);
+               return 0;
+       } else {
+               fprintf(stderr, "hostnqn is not available -- use nvme gen-hostnqn\n");
+               return -ENOENT;
+       }
+}
+
 static int discover_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
 {
        const char *desc = "Send Get Log Page request to Discovery Controller.";