SHA256
1
0
forked from pool/s390-tools
s390-tools/s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch

125 lines
4.1 KiB
Diff

Subject: zpcictl: Make device node for NVMe optional
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
Summary: zpcictl: Add tool to manage PCI devices
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
platform. Initial functions include generating firmware
error logs, resetting PCI devices, and preparing a device
for further repair actions.
Upstream-ID: 342c6a3707315514f0f886fabb532f6c8b59b694
Problem-ID: RAS1703
Upstream-Description:
zpcictl: Make device node for NVMe optional
At the moment, if we specify the slot address of an NVMe device but
can't find the corresponding device node, the execution is terminated.
This is a bit harsh as the device node is rather optional and only
necessary to collect S.M.A.R.T. data. We should still be able to issue
the error reporting, even if we couldn't determine the device node.
Therefore, make sure the device node for NVMe devices is optional by
changing various error messages to warnings.
Change sysfs_get_slot_addr() to have a return value and work with that
accordingly.
Also make sure, that execution is terminated when a valid device node
was specified but no matching slot address was determined. The slot
address is necessary to issue the error reporting commands.
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
---
zpcictl/zpcictl.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
--- a/zpcictl/zpcictl.c
+++ b/zpcictl/zpcictl.c
@@ -104,6 +104,9 @@ static char *collect_smart_data(struct z
char *cmd;
FILE *fd;
+ if (!pdev->device)
+ return NULL;
+
util_asprintf(&cmd, SMARTCTL_CMDLINE, pdev->device);
fd = popen(cmd, "r");
if (!fd)
@@ -175,7 +178,7 @@ static void sysfs_write_data(struct zpci
/* lstat() doesn't work for sysfs files, so we have to work with a fixed size */
#define READLINK_SIZE 256
-static void sysfs_get_slot_addr(const char *dev, char *slot)
+static int sysfs_get_slot_addr(const char *dev, char *slot)
{
char device[READLINK_SIZE], *result;
unsigned int major, minor;
@@ -184,8 +187,9 @@ static void sysfs_get_slot_addr(const ch
char *path;
if (stat(dev, &dev_stat) != 0) {
- errx(EXIT_FAILURE, "Could not get stat information for %s: %s",
- dev, strerror(errno));
+ warnx("Could not get stat information for %s: %s",
+ dev, strerror(errno));
+ return 0;
}
major = major(dev_stat.st_rdev);
minor = minor(dev_stat.st_rdev);
@@ -193,18 +197,21 @@ static void sysfs_get_slot_addr(const ch
path = util_path_sysfs("dev/char/%u:%u/device", major, minor);
len = readlink(path, device, READLINK_SIZE - 1);
free(path);
- if (len != -1)
+ if (len != -1) {
device[len] = '\0';
- else
- errx(EXIT_FAILURE, "Could not read device link for %s", dev);
+ } else {
+ warnx("Could not read device link for %s", dev);
+ return 0;
+ }
result = strrchr(device, '/');
if (result)
result++;
else
result = device;
-
strcpy(slot, result);
+
+ return 1;
}
static void get_device_node(struct zpci_device *pdev)
@@ -219,12 +226,13 @@ static void get_device_node(struct zpci_
if (count == -1) {
warnx("Could not read directory %s: %s", path, strerror(errno));
free(path);
- exit(EXIT_FAILURE);
+ return;
}
for (i = 0; i < count; i++) {
util_asprintf(&dev, "/dev/%s", de_vec[i]->d_name);
- sysfs_get_slot_addr(dev, slot);
+ if (!sysfs_get_slot_addr(dev, slot))
+ continue;
if (strcmp(slot, pdev->slot) == 0) {
pdev->device = dev;
break;
@@ -255,7 +263,9 @@ static void get_device_info(struct zpci_
if (is_blk_dev(dev))
errx(EXIT_FAILURE, "Unsupported device type %s", dev);
if (is_char_dev(dev)) {
- sysfs_get_slot_addr(dev, pdev->slot);
+ if (!sysfs_get_slot_addr(dev, pdev->slot))
+ errx(EXIT_FAILURE,
+ "Could not determine slot address for %s", dev);
pdev->device = dev;
} else {
strcpy(pdev->slot, dev);