From 48c10dbfaf00777170e209db20f7d07e47f7a983 Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 3 Oct 2019 11:47:02 -0700 Subject: [PATCH] Use a systemd app-specific machine ID for hostnqn 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 Signed-off-by: Andy Lutomirski --- Documentation/nvme-show-hostnqn.txt | 29 +++++++++++++++ Makefile | 6 ++++ fabrics.c | 55 +++++++++++++++++++++++++---- fabrics.h | 2 ++ nvme-builtin.h | 1 + nvme.c | 15 ++++++++ 6 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 Documentation/nvme-show-hostnqn.txt diff --git a/Documentation/nvme-show-hostnqn.txt b/Documentation/nvme-show-hostnqn.txt new file mode 100644 index 0000000..044346c --- /dev/null +++ b/Documentation/nvme-show-hostnqn.txt @@ -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 diff --git a/Makefile b/Makefile index 66632a3..3470493 100644 --- 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 diff --git a/fabrics.c b/fabrics.c index 85f5371..8982ae4 100644 --- a/fabrics.c +++ b/fabrics.c @@ -43,6 +43,11 @@ #include "common.h" +#ifdef HAVE_SYSTEMD +#include +#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; diff --git a/fabrics.h b/fabrics.h index 7c1664b..b8e53f4 100644 --- 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); diff --git a/nvme-builtin.h b/nvme-builtin.h index bcb59e3..bfb907d 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -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 7bf2a50..88298f6 100644 --- 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."; -- 2.50.1