120 lines
3.3 KiB
Diff
120 lines
3.3 KiB
Diff
|
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);
|
||
|
}
|
||
|
|