]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Read system UUID from DMI and merge hostnqn generation functions
authorHannes Reinecke <hare@suse.de>
Wed, 24 Mar 2021 07:22:28 +0000 (08:22 +0100)
committerKeith Busch <kbusch@kernel.org>
Wed, 31 Mar 2021 21:47:51 +0000 (15:47 -0600)
Both fabrics.c and the 'gen-hostnqn' command contain functions
to generate a default host NQN. Needless to say, both are different.
_And_ we have the script 'nvme-gen-hostnqn' to read the host nqn
from the system UUID, implement yet another way.

This patch merges all of these functions, and implements a hierarchy
in generating host NQNs:
- Try reading system UUID from /sys/firmware/dmi/entries
- Try reading systemd-generated UUID
- Generate a random UUID

Signed-off-by: Hannes Reinecke <hare@suse.de>
fabrics.c
nvme-topology.c
nvme.c
nvme.h

index 1615901e2ec7121488ac5eae49ebb11385f75385..ea8380a49a23428cc0fa650b5e4c3974a8e4c228 100644 (file)
--- a/fabrics.c
+++ b/fabrics.c
@@ -818,6 +818,18 @@ static char *hostnqn_generate_systemd(void)
 #endif
 }
 
+static char *hostnqn_read_dmi(void)
+{
+       char uuid[16];
+       char *ret = NULL;
+
+       if (uuid_from_dmi(uuid) < 0)
+               return NULL;
+       if (asprintf(&ret, "nqn.2014-08.org.nvmexpress:uuid:%s", uuid) == -1)
+               return NULL;
+       return ret;
+}
+
 /* returns an allocated string or NULL */
 char *hostnqn_read(void)
 {
@@ -827,6 +839,10 @@ char *hostnqn_read(void)
        if (ret)
                return ret;
 
+       ret = hostnqn_read_dmi();
+       if (ret)
+               return ret;
+
        ret = hostnqn_generate_systemd();
        if (ret)
                return ret;
index 63e433d70f0181626e611655b01e485cce5025ef..db0714f7ea7ff46ae0e5e4b71e757d1b4804f995 100644 (file)
@@ -696,3 +696,76 @@ void *mmap_registers(const char *dev)
        return membase;
 }
 
+#define PATH_DMI_ENTRIES       "/sys/firmware/dmi/entries"
+
+int uuid_from_dmi(char *system_uuid)
+{
+       int f;
+       DIR *d;
+       struct dirent *de;
+       char buf[512];
+
+       system_uuid[0] = '\0';
+       d = opendir(PATH_DMI_ENTRIES);
+       if (!d)
+               return -ENXIO;
+       while ((de = readdir(d))) {
+               char filename[PATH_MAX];
+               int len, type;
+
+               if (de->d_name[0] == '.')
+                       continue;
+               sprintf(filename, "%s/%s/type", PATH_DMI_ENTRIES, de->d_name);
+               f = open(filename, O_RDONLY);
+               if (f < 0)
+                       continue;
+               len = read(f, buf, 512);
+               close(f);
+               if (len < 0)
+                       continue;
+               if (sscanf(buf, "%d", &type) != 1)
+                       continue;
+               if (type != 1)
+                       continue;
+               sprintf(filename, "%s/%s/raw", PATH_DMI_ENTRIES, de->d_name);
+               f = open(filename, O_RDONLY);
+               if (f < 0)
+                       continue;
+               len = read(f, buf, 512);
+               close(f);
+               if (len < 0)
+                       continue;
+               /* Sigh. https://en.wikipedia.org/wiki/Overengineering */
+               /* DMTF SMBIOS 3.0 Section 7.2.1 System UUID */
+               sprintf(system_uuid,
+                       "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
+                       "%02x%02x%02x%02x%02x%02x",
+                       (uint8_t)buf[8 + 3], (uint8_t)buf[8 + 2],
+                       (uint8_t)buf[8 + 1], (uint8_t)buf[8 + 0],
+                       (uint8_t)buf[8 + 5], (uint8_t)buf[8 + 4],
+                       (uint8_t)buf[8 + 7], (uint8_t)buf[8 + 6],
+                       (uint8_t)buf[8 + 8], (uint8_t)buf[8 + 9],
+                       (uint8_t)buf[8 + 10], (uint8_t)buf[8 + 11],
+                       (uint8_t)buf[8 + 12], (uint8_t)buf[8 + 13],
+                       (uint8_t)buf[8 + 14], (uint8_t)buf[8 + 15]);
+               break;
+       }
+       closedir(d);
+       return strlen(system_uuid) ? 0 : -ENXIO;
+}
+
+int uuid_from_systemd(char *systemd_uuid)
+{
+#ifdef HAVE_SYSTEMD
+       sd_id128_t id;
+       char *ret;
+
+       if (sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id) < 0)
+               return -ENXIO;
+
+       sprintf(systemd_uuid, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));
+       return 0;
+#else
+       return -ENOTSUP;
+#endif
+}
diff --git a/nvme.c b/nvme.c
index 8751ffd45e26d43626e114fbaded6f33f39c10bf..5e77e3f643f3d3114c11ba8529fb7a082a2951ba 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -5581,25 +5581,32 @@ static int admin_passthru(int argc, char **argv, struct command *cmd, struct plu
        return passthru(argc, argv, NVME_IOCTL_ADMIN_CMD, 1, desc, cmd);
 }
 
-#ifdef LIBUUID
 static int gen_hostnqn_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
 {
-       uuid_t uuid;
+       int ret;
        char uuid_str[37]; /* e.g. 1b4e28ba-2fa1-11d2-883f-0016d3cca427 + \0 */
+#ifdef LIBUUID
+       uuid_t uuid;
+#endif
 
-       uuid_generate_random(uuid);
-       uuid_unparse_lower(uuid, uuid_str);
+       ret = uuid_from_dmi(uuid_str);
+       if (ret < 0)
+               ret = uuid_from_systemd(uuid_str);
+#ifdef LIBUUID
+       if (ret < 0) {
+               uuid_generate_random(uuid);
+               uuid_unparse_lower(uuid, uuid_str);
+               ret = 0;
+       }
+#endif
+       if (ret < 0) {
+               fprintf(stderr, "\"%s\" not supported. Install lib uuid and rebuild.\n",
+                       command->name);
+               return -ENOTSUP;
+       }
        printf("nqn.2014-08.org.nvmexpress:uuid:%s\n", uuid_str);
        return 0;
 }
-#else
-static int gen_hostnqn_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
-{
-       fprintf(stderr, "\"%s\" not supported. Install lib uuid and rebuild.\n",
-               command->name);
-       return -ENOTSUP;
-}
-#endif
 
 static int show_hostnqn_cmd(int argc, char **argv, struct command *command, struct plugin *plugin)
 {
diff --git a/nvme.h b/nvme.h
index 1ffbb1f63b1163903191e0c28735de79a05e5881..9d772857173cb7e63efe489d2d5902cb0a3e8ba3 100644 (file)
--- a/nvme.h
+++ b/nvme.h
@@ -139,6 +139,9 @@ char *nvme_get_ctrl_attr(char *path, const char *attr);
 void *nvme_alloc(size_t len, bool *huge);
 void nvme_free(void *p, bool huge);
 
+int uuid_from_dmi(char *uuid);
+int uuid_from_systemd(char *uuid);
+
 unsigned long long elapsed_utime(struct timeval start_time,
                                        struct timeval end_time);
 #endif /* _NVME_H */