OSDN Git Service

nvdimm: Use the namespace guid, not just the device guid
authorPeter Jones <pjones@redhat.com>
Fri, 8 Jun 2018 17:44:37 +0000 (13:44 -0400)
committerPeter Jones <pmjones@gmail.com>
Fri, 8 Jun 2018 19:11:37 +0000 (15:11 -0400)
This makes long-form device paths for nvdimm be:

NVDIMM(pmem-namespace-guid)/NVDIMM(pmem-label-guid)/HD(...)/File(...)

It also conditionally removes our UUID swizzling, because nobody can
figure out what the correct encoding is, and only byteswaps if
LIBEFIBOOT_SWIZZLE_PMEM_UUID is set (to any value) in the environment.

Signed-off-by: Peter Jones <pjones@redhat.com>
src/linux-pmem.c
src/linux.h

index 503a591..045650b 100644 (file)
@@ -76,6 +76,7 @@ parse_pmem(struct device *dev, const char *current)
         uint8_t system, sysbus, acpi_id;
         uint16_t pnp_id;
         int ndbus, region, btt_region_id, btt_id, rc, pos;
+        char *namespace = NULL;
 
         debug(DEBUG, "entry");
 
@@ -111,18 +112,47 @@ parse_pmem(struct device *dev, const char *current)
          * but the UUID we really do need to have.
          */
         rc = read_sysfs_file(&filebuf,
-                             "class/block/%s/device/uuid", dev->disk_name);
+                             "class/block/%s/device/namespace", dev->disk_name);
         if ((rc < 0 && errno == ENOENT) || filebuf == NULL)
                 return -1;
 
-        rc = efi_str_to_guid((char *)filebuf, &dev->nvdimm_label);
+        rc = sscanf((char *)filebuf, "%ms[^\n]\n", &namespace);
+        if (rc != 1 || namespace == NULL)
+                return -1;
+
+        filebuf = NULL;
+        debug(DEBUG, "nvdimm namespace is \"%s\"", namespace);
+        rc = read_sysfs_file(&filebuf, "bus/nd/devices/%s/uuid", namespace);
+        free(namespace);
+        if (rc < 0 || filebuf == NULL)
+                return -1;
+
+        rc = efi_str_to_guid((char *)filebuf,
+                             &dev->nvdimm_info.namespace_label);
+        if (rc < 0)
+                return -1;
+
+        filebuf = NULL;
+        rc = read_sysfs_file(&filebuf, "class/block/%s/device/uuid",
+                             dev->disk_name);
+        if (rc < 0 || filebuf == NULL)
+                return -1;
+
+        rc = efi_str_to_guid((char *)filebuf,
+                             &dev->nvdimm_info.nvdimm_label);
         if (rc < 0)
                 return -1;
 
-        /* UUIDs are stored opposite Endian from GUIDs, so our normal GUID
-         * parser is giving us the wrong thing; swizzle those bytes around.
+        /*
+         * Right now it's not clear what encoding NVDIMM($uuid) gets in the
+         * binary format, so this will be in the mixed endian format EFI GUIDs
+         * are in (33221100-1100-1100-0011-223344556677) unless you set this
+         * variable.
          */
-        swizzle_guid_to_uuid(&dev->nvdimm_label);
+        if (getenv("LIBEFIBOOT_SWIZZLE_PMEM_UUID") != NULL) {
+                swizzle_guid_to_uuid(&dev->nvdimm_info.namespace_label);
+                swizzle_guid_to_uuid(&dev->nvdimm_info.nvdimm_label);
+        }
 
         dev->interface_type = nd_pmem;
 
@@ -133,14 +163,21 @@ static ssize_t
 dp_create_pmem(struct device *dev,
                uint8_t *buf, ssize_t size, ssize_t off)
 {
-        ssize_t sz;
+        ssize_t sz, sz1;
 
         debug(DEBUG, "entry");
 
         sz = efidp_make_nvdimm(buf + off, size ? size - off : 0,
-                               &dev->nvdimm_label);
-
-        return sz;
+                               &dev->nvdimm_info.namespace_label);
+        if (sz < 0)
+                return sz;
+        off += sz;
+        sz1 = efidp_make_nvdimm(buf + off, size ? size - off : 0,
+                                &dev->nvdimm_info.nvdimm_label);
+        if (sz1 < 0)
+                return sz1;
+
+        return sz + sz1;
 }
 
 enum interface_type pmem_iftypes[] = { nd_pmem, unknown };
index 71f766f..2f9eb0f 100644 (file)
@@ -82,6 +82,11 @@ struct nvme_info {
         uint8_t eui[8];
 };
 
+struct nvdimm_info {
+        efi_guid_t namespace_label;
+        efi_guid_t nvdimm_label;
+};
+
 enum interface_type {
         unknown,
         isa, pci, network,
@@ -126,7 +131,7 @@ struct device {
                                 struct sata_info sata_info;
                                 struct ata_info ata_info;
                                 struct nvme_info nvme_info;
-                                efi_guid_t nvdimm_label;
+                                struct nvdimm_info nvdimm_info;
                         };
                 };
                 char *ifname;