File s390-tools-sles15sp2-03-zpcitctl-Exit-on-error-in-sysfs_report_error.patch of Package s390-tools.15659

Subject: [PATCH] [BZ 184174] zpcitctl: Exit on error in sysfs_report_error
From: Jan Hoeppner <hoeppner@linux.ibm.com>

Description:   zpcictl: Initiate recover after reset
Symptom:       If a PCI function is reset using zpcictl --reset, the function
               is in an error state.
Problem:       zpcictl --reset only issues a SCLP reset and leaves the PCI
               function in an error state.
Solution:      Initiate an OS level recovery by calling
               /sys/bus/devices/<dev>/recover after the SCLP reset.
Reproduction:  Call zpcictl --reset <dev>
               Under z/VM check the state of the function with 'vmcp q pcif'
Upstream-ID:   304c3d8086bc2a9230c5404f9c9fec72de08d229
Problem-ID:    184174

Upstream-Description:

              zpcitctl: Exit on error in sysfs_report_error

              This also makes sure that we don't try to write to the
              /sys/bus/pci/device/<dev>/recover attribute if reset failed.

              Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
              Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
              Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>


Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>
---
 zpcictl/zpcictl.c |   55 +++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 38 insertions(+), 17 deletions(-)

--- a/zpcictl/zpcictl.c
+++ b/zpcictl/zpcictl.c
@@ -97,6 +97,35 @@ static void fopen_err(char *path)
 	exit(EXIT_FAILURE);
 }
 
+static void fclose_err(char *path)
+{
+	if (errno == EIO || errno == EOPNOTSUPP)
+		warnx("Unsupported operation: %s: %s", path, strerror(errno));
+	else
+		warnx("Could not close file: %s: %s", path, strerror(errno));
+	free(path);
+	exit(EXIT_FAILURE);
+
+}
+
+static void fread_err(FILE *fp, char *path)
+{
+	warnx("Could not read file: %s: %s", path, strerror(errno));
+	if (fclose(fp))
+		fclose_err(path);
+	free(path);
+	exit(EXIT_FAILURE);
+}
+
+static void fwrite_err(FILE *fp, char *path)
+{
+	warnx("Could not write to file: %s: %s", path, strerror(errno));
+	if (fclose(fp))
+		fclose_err(path);
+	free(path);
+	exit(EXIT_FAILURE);
+}
+
 #define READ_CHUNK_SIZE		512
 
 static char *collect_smart_data(struct zpci_device *pdev)
@@ -152,12 +181,10 @@ static unsigned int sysfs_read_value(str
 	if (!fp)
 		fopen_err(path);
 	if (fscanf(fp, "%x", &val) != 1) {
-		fclose(fp);
-		warnx("Could not read file %s: %s", path, strerror(errno));
-		free(path);
-		exit(EXIT_FAILURE);
+		fread_err(fp, path);
 	}
-	fclose(fp);
+	if (fclose(fp))
+		fclose_err(path);
 	free(path);
 
 	return val;
@@ -174,12 +201,10 @@ static void sysfs_write_value(struct zpc
 	if (!fp)
 		fopen_err(path);
 	if (fprintf(fp, "%x", val) < 0) {
-		fclose(fp);
-		warnx("Could not write to file %s: %s", path, strerror(errno));
-		free(path);
-		exit(EXIT_FAILURE);
+		fwrite_err(fp, path);
 	}
-	fclose(fp);
+	if (fclose(fp))
+		fclose_err(path);
 	free(path);
 }
 
@@ -196,13 +221,9 @@ static void sysfs_report_error(struct zp
 	if (!fp)
 		fopen_err(path);
 	if (fwrite(report, 1, r_size, fp) != r_size)
-		warnx("Could not write to file: %s: %s", path, strerror(errno));
-	if (fclose(fp)) {
-		if (errno == EIO || errno == EOPNOTSUPP)
-			warnx("Unsupported operation: %s: %s", path, strerror(errno));
-		else
-			warnx("Could not close file: %s: %s", path, strerror(errno));
-	}
+		fwrite_err(fp, path);
+	if (fclose(fp))
+		fclose_err(path);
 	free(path);
 }
 
openSUSE Build Service is sponsored by