File s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch of Package s390-tools.15658

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);
openSUSE Build Service is sponsored by