Skip to content

Commit

Permalink
The below patches introduces support for nvme disk and few improvemen…
Browse files Browse the repository at this point in the history
…ts in efivar-37 package.

Patches has been taken from debian source efivar 37-6
https://sources.debian.org/patches/efivar/37-6/

Details of the patches mentioned below

1. remove-arrows.patch
https://sources.debian.org/patches/efivar/37-6/remove-arrows.patch
Upstream commit
Get rid of the arrows in our debug messages.
rhboot/efivar@e39fb5b

2. Always-initialize-any-variable-we-use-with-sscanf-s-.patch
https://sources.debian.org/patches/efivar/37-6/Always-initialize-any-variable-we-use-with-sscanf-s-.patch/
Upstream commit
Always initialize any variable we use with sscanf's %n
rhboot/efivar@5dc12cc

3. 0001-Fix-the-error-path-in-set_disk_and_part_name.patch
https://sources.debian.org/patches/efivar/37-6/0001-Fix-the-error-path-in-set_disk_and_part_name.patch/
Upstream commit:
Fix the error path in set_disk_and_part_name()
rhboot/efivar@22bc086

4. 0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch
https://sources.debian.org/patches/efivar/37-6/0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch
Upstream commit:
sysfs parsers: make all the /sys/block link parsers work the same way
rhboot/efivar@4718694

5. 0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch
https://sources.debian.org/patches/efivar/37-6/0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch/
Upstream commit
Try even harder to find disk device symlinks in sysfs.
rhboot/efivar@c9c1424

6. 0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch
 https://sources.debian.org/patches/efivar/37-6/0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch
Upstream commit
Handle /sys/devices/virtual/{nvme-fabrics,nvme-subsystem} devices
rhboot/efivar@c41da0b

7. 0005-Fix-variable-sz-uninitialized-error.patch
https://sources.debian.org/patches/efivar/37-6/0005-Fix-variable-sz-uninitialized-error.patch
Upstream commit
Fix variable 'sz' uninitialized error
rhboot/efivar@9dc04c2

8. 0006-Fix-parsing-for-nvme-subsystem-devices.patch
https://sources.debian.org/patches/efivar/37-6/0006-Fix-parsing-for-nvme-subsystem-devices.patch
Upstream commit:
Fix parsing for nvme-subsystem devices
rhboot/efivar@4e12f99

Signed-off-by: Ashwin H <[email protected]>
Signed-off-by: Shantanu Shrivastava <[email protected]>
  • Loading branch information
ashwin-h authored and mshych committed Mar 14, 2023
1 parent 4238ae5 commit 26b2e4c
Show file tree
Hide file tree
Showing 9 changed files with 1,254 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
From 22bc0866e941cbfe57de6522db51e9cf2c6b3ff1 Mon Sep 17 00:00:00 2001
From: Peter Jones <[email protected]>
Date: Wed, 2 Oct 2019 17:01:00 -0400
Subject: [PATCH] Fix the error path in set_disk_and_part_name()

Signed-off-by: Peter Jones <[email protected]>

[ dannf: Context adjustments due to upstream whitespace cleanup;
Included to simplify the application of
0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch ]

Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718
Bug: https://github.com/rhboot/efivar/issues/157
Origin: upstream, https://github.com/rhboot/efivar/commit/22bc0866e941cbfe57de6522db51e9cf2c6b3ff1
Last-Updated: 2020-09-30

Index: efivar-37/src/linux.c
===================================================================
--- efivar-37.orig/src/linux.c
+++ efivar-37/src/linux.c
@@ -1,6 +1,6 @@
/*
* libefiboot - library for the manipulation of EFI boot variables
- * Copyright 2012-2015 Red Hat, Inc.
+ * Copyright 2012-2019 Red Hat, Inc.
* Copyright (C) 2001 Dell Computer Corporation <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -169,6 +169,8 @@ set_disk_name(struct device *dev, const
int HIDDEN
set_disk_and_part_name(struct device *dev)
{
+ int rc = -1;
+
/*
* results are like such:
* maj:min -> ../../devices/pci$PCI_STUFF/$BLOCKDEV_STUFF/block/$DISK/$PART
@@ -200,6 +202,7 @@ set_disk_and_part_name(struct device *de
set_disk_name(dev, "%s", penultimate);
set_part_name(dev, "%s", ultimate);
debug("disk:%s part:%s", penultimate, ultimate);
+ rc = 0;
} else if (ultimate && approximate && !strcmp(approximate, "nvme")) {
/*
* 259:0 -> ../../devices/pci0000:00/0000:00:1d.0/0000:05:00.0/nvme/nvme0/nvme0n1
@@ -207,6 +210,7 @@ set_disk_and_part_name(struct device *de
set_disk_name(dev, "%s", ultimate);
set_part_name(dev, "%sp%d", ultimate, dev->part);
debug("disk:%s part:%sp%d", ultimate, ultimate, dev->part);
+ rc = 0;
} else if (ultimate && penultimate && !strcmp(penultimate, "block")) {
/*
* 253:0 -> ../../devices/virtual/block/dm-0 (... I guess)
@@ -220,15 +224,19 @@ set_disk_and_part_name(struct device *de
set_disk_name(dev, "%s", ultimate);
set_part_name(dev, "%s%d", ultimate, dev->part);
debug("disk:%s part:%s%d", ultimate, ultimate, dev->part);
+ rc = 0;
} else if (ultimate && approximate && !strcmp(approximate, "mtd")) {
/*
* 31:0 -> ../../devices/platform/1e000000.palmbus/1e000b00.spi/spi_master/spi32766/spi32766.0/mtd/mtd0/mtdblock0
*/
set_disk_name(dev, "%s", ultimate);
debug("disk:%s", ultimate);
+ rc = 0;
}

- return 0;
+ if (rc < 0)
+ efi_error("Could not parse disk name:\"%s\"", dev->link);
+ return rc;
}

static struct dev_probe *dev_probes[] = {
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
From 4718694094647b981b74453445d000b0296b6544 Mon Sep 17 00:00:00 2001
From: Peter Jones <[email protected]>
Date: Tue, 15 Oct 2019 16:53:27 -0400
Subject: [PATCH] sysfs parsers: make all the /sys/block link parsers work the
same way

Apparently I wrote some of these one way and some the other, and the one
special case where everything was "current+sz" instead of some form of
"current += pos; sz += pos; ...; return sz;" or the subtraction version.

Make them all the same, where possible.

Signed-off-by: Peter Jones <[email protected]>

[ dannf: Restrict to just linux-nvme.c;
Context adjustments due to upstream whitespace cleanup;
drop call to dbgmk() call - it didn't exist in v37;
included to simplify application of later patches in series ]

Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718
Bug: https://github.com/rhboot/efivar/issues/157
Origin: upstream, https://github.com/rhboot/efivar/commit/4718694094647b981b74453445d000b0296b6544
Last-Updated: 2020-09-30

Index: efivar-37/src/linux-nvme.c
===================================================================
--- efivar-37.orig/src/linux-nvme.c
+++ efivar-37/src/linux-nvme.c
@@ -24,6 +24,7 @@
#include <fcntl.h>
#include <inttypes.h>
#include <stdint.h>
+#include <sys/param.h>
#include <unistd.h>

#include "efiboot.h"
@@ -48,25 +49,28 @@
*/

static ssize_t
-parse_nvme(struct device *dev, const char *current, const char *root UNUSED)
+parse_nvme(struct device *dev, const char *path, const char *root UNUSED)
{
+ const char *current = path;
int rc;
int32_t tosser0, tosser1, tosser2, ctrl_id, ns_id, partition;
uint8_t *filebuf = NULL;
- int pos0 = 0, pos1 = 0;
+ int pos0 = -1, pos1 = -1, pos2 = -1;

debug("entry");

debug("searching for nvme/nvme0/nvme0n1 or nvme/nvme0/nvme0n1/nvme0n1p1");
- rc = sscanf(current, "nvme/nvme%d/nvme%dn%d%n/nvme%dn%dp%d%n",
- &tosser0, &ctrl_id, &ns_id, &pos0,
- &tosser1, &tosser2, &partition, &pos1);
- debug("current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
+ rc = sscanf(current, "%nnvme/nvme%d/nvme%dn%d%n/nvme%dn%dp%d%n",
+ &pos0, &tosser0, &ctrl_id, &ns_id,
+ &pos1, &tosser1, &tosser2, &partition, &pos2);
+ debug("current:\"%s\" rc:%d pos0:%d pos1:%d pos2:%d\n", current, rc, pos0, pos1, pos2);
/*
* If it isn't of that form, it's not one of our nvme devices.
*/
if (rc != 3 && rc != 6)
return 0;
+ if (rc == 3)
+ pos2 = pos1;

dev->nvme_info.ctrl_id = ctrl_id;
dev->nvme_info.ns_id = ns_id;
@@ -77,8 +81,9 @@ parse_nvme(struct device *dev, const cha
if (dev->part == -1)
dev->part = partition;

- pos0 = pos1;
+ pos1 = pos2;
}
+ current += pos1;

/*
* now fish the eui out of sysfs is there is one...
@@ -110,7 +115,8 @@ parse_nvme(struct device *dev, const cha
memcpy(dev->nvme_info.eui, eui, sizeof(eui));
}

- return pos0;
+ debug("current:'%s' sz:%zd", current, current - path);
+ return current - path;
}

static ssize_t
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
From c9c1424d0e09bf33b747d37c43177c63367b1290 Mon Sep 17 00:00:00 2001
From: Peter Jones <[email protected]>
Date: Fri, 11 Oct 2019 14:20:54 -0400
Subject: [PATCH] Try even harder to find disk device symlinks in sysfs.

Today's realization is that the thing encoded into the structure of
sysfs is, in the best case, the dependency graph of the makefile targets
to build a device driver.

In the case of nvme-fabric, or really wherever the kernel has
class_create() and device_create() in the same function, there's an
extra level of indirection.

Anyway, in this patch we stop pretending sysfs isn't completely absurd,
and just try adding "/device" in the middle of the driver symlink path,
until we actually either get ENOENT on the device symlink or find a
device symlink that actually has a driver symlink under it.

Signed-off-by: Peter Jones <[email protected]>

[ dannf: Context adjustments due to upstream whitespace cleanup;
Adjust to omit efi_error_pop() call that didn't exist in v37;
included to simplify application of later patches in series ]

Bug-Ubuntu: https://bugs.launchpad.net/bugs/1891718
Bug: https://github.com/rhboot/efivar/issues/157
Origin: upstream, https://github.com/rhboot/efivar/commit/c9c1424d0e09bf33b747d37c43177c63367b1290
Last-Updated: 2020-09-30

Index: efivar-37/src/linux-nvme.c
===================================================================
--- efivar-37.orig/src/linux-nvme.c
+++ efivar-37/src/linux-nvme.c
@@ -88,13 +88,12 @@ parse_nvme(struct device *dev, const cha
/*
* now fish the eui out of sysfs is there is one...
*/
- rc = read_sysfs_file(&filebuf,
- "class/block/nvme%dn%d/eui",
- ctrl_id, ns_id);
- if ((rc < 0 && errno == ENOENT) || filebuf == NULL) {
- rc = read_sysfs_file(&filebuf,
- "class/block/nvme%dn%d/device/eui",
- ctrl_id, ns_id);
+ char *euipath = NULL;
+ rc = read_sysfs_file(&filebuf, "class/block/nvme%dn%d/eui", ctrl_id, ns_id);
+ if (rc < 0 && (errno == ENOENT || errno == ENOTDIR)) {
+ rc = find_device_file(&euipath, "eui", "class/block/nvme%dn%d", ctrl_id, ns_id);
+ if (rc >= 0 && euipath != NULL)
+ rc = read_sysfs_file(&filebuf, "%s", euipath);
}
if (rc >= 0 && filebuf != NULL) {
uint8_t eui[8];
Index: efivar-37/src/linux.c
===================================================================
--- efivar-37.orig/src/linux.c
+++ efivar-37/src/linux.c
@@ -410,24 +410,32 @@ struct device HIDDEN
goto err;
}

- if (dev->device[0] != 0) {
- rc = sysfs_readlink(&tmpbuf, "block/%s/device/driver", dev->disk_name);
+ /*
+ * So, on a normal disk, you get something like:
+ * /sys/block/sda/device -> ../../0:0:0:0
+ * /sys/block/sda/device/driver -> ../../../../../../../bus/scsi/drivers/sd
+ *
+ * On a directly attached nvme device you get:
+ * /sys/block/nvme0n1/device -> ../../nvme0
+ * /sys/block/nvme0n1/device/device -> ../../../0000:6e:00.0
+ * /sys/block/nvme0n1/device/device/driver -> ../../../../bus/pci/drivers/nvme
+ *
+ * On a fabric-attached nvme device, you get something like:
+ * /sys/block/nvme0n1/device -> ../../nvme0
+ * /sys/block/nvme0n1/device/device -> ../../ctl
+ * /sys/block/nvme0n1/device/device/device -> ../../../../../0000:6e:00.0
+ * /sys/block/nvme0n1/device/device/device/driver -> ../../../../../../bus/pci/drivers/nvme-fabrics
+ *
+ * ... I think? I don't have one in front of me.
+ */
+
+ char *filepath = NULL;
+ rc = find_device_file(&filepath, "driver", "block/%s", dev->disk_name);
+ if (rc >= 0) {
+ rc = sysfs_readlink(&tmpbuf, "%s", filepath);
if (rc < 0 || !tmpbuf) {
- if (errno == ENOENT) {
- /*
- * nvme, for example, will have nvme0n1/device point
- * at nvme0, and we need to look for device/driver
- * there.
- */
- rc = sysfs_readlink(&tmpbuf,
- "block/%s/device/device/driver",
- dev->disk_name);
- }
- if (rc < 0 || !tmpbuf) {
- efi_error("readlink of /sys/block/%s/device/driver failed",
- dev->disk_name);
- goto err;
- }
+ efi_error("readlink of /sys/%s failed", filepath);
+ goto err;
}

linkbuf = pathseg(tmpbuf, -1);
@@ -438,7 +446,7 @@ struct device HIDDEN

dev->driver = strdup(linkbuf);
} else {
- dev->driver = strdup("");
+ dev->driver = strdup("");
}

if (!dev->driver) {
Index: efivar-37/src/linux.h
===================================================================
--- efivar-37.orig/src/linux.h
+++ efivar-37/src/linux.h
@@ -1,6 +1,6 @@
/*
* libefiboot - library for the manipulation of EFI boot variables
- * Copyright 2012-2015 Red Hat, Inc.
+ * Copyright 2012-2019 Red Hat, Inc.
* Copyright (C) 2001 Dell Computer Corporation <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -196,6 +196,22 @@ extern ssize_t HIDDEN make_mac_path(uint
bufsize_; \
})

+#define sysfs_access(mode, fmt, args...) \
+ ({ \
+ int rc_; \
+ char *pn_; \
+ \
+ rc_ = asprintfa(&pn_, "/sys/" fmt, ## args); \
+ if (rc_ >= 0) { \
+ rc_ = access(pn_, mode); \
+ if (rc_ < 0) \
+ efi_error("could not access %s", pn_); \
+ } else { \
+ efi_error("could not allocate memory"); \
+ } \
+ rc_; \
+ })
+
#define sysfs_readlink(linkbuf, fmt, args...) \
({ \
char *_lb = alloca(PATH_MAX+1); \
@@ -251,6 +267,57 @@ extern ssize_t HIDDEN make_mac_path(uint
dir_; \
})

+/*
+ * Iterate a /sys/block directory looking for device/foo, device/device/foo,
+ * etc. I'm not proud of this method.
+ */
+#define find_device_file(result, name, fmt, args...) \
+ ({ \
+ int rc_ = 0; \
+ debug("searching for %s from in %s", name, dev->disk_name); \
+ for (unsigned int try_ = 0; true; try_++) { \
+ char slashdev_[sizeof("device") \
+ + try_ * strlen("/device")]; \
+ \
+ char *nul_ = stpcpy(slashdev_, "device"); \
+ for (unsigned int i_ = 0; i_ < try_; i_++) \
+ nul_ = stpcpy(nul_, "/device"); \
+ \
+ debug("trying /sys/" fmt "/%s/%s", \
+ ## args, slashdev_, name); \
+ \
+ rc_ = sysfs_access(F_OK, fmt "/%s", ## args, slashdev_);\
+ if (rc_ < 0) { \
+ if (errno == ENOENT) { \
+ break; \
+ } \
+ efi_error("cannot access /sys/"fmt"/%s: %m", \
+ ## args, slashdev_); \
+ goto find_device_link_err_; \
+ } \
+ \
+ rc_ = sysfs_access(F_OK, fmt "/%s/%s", \
+ ## args, slashdev_, name); \
+ if (rc_ < 0) { \
+ if (errno == ENOENT) { \
+ break; \
+ } \
+ efi_error("cannot access /sys/"fmt"/%s/%s: %m", \
+ ## args, slashdev_, name); \
+ goto find_device_link_err_; \
+ } \
+ \
+ rc_ = asprintfa(result, fmt "/%s/%s", \
+ ## args, slashdev_, name); \
+ if (rc_ < 0) { \
+ efi_error("cannot allocate memory: %m"); \
+ goto find_device_link_err_; \
+ } \
+ } \
+find_device_link_err_: \
+ rc_; \
+ })
+
#define DEV_PROVIDES_ROOT 1
#define DEV_PROVIDES_HD 2
#define DEV_ABBREV_ONLY 4
Loading

0 comments on commit 26b2e4c

Please sign in to comment.