File s390-tools-sles15sp2-01-libutil-add-util_file_read_i-util_file_read_ui.patch of Package s390-tools.19608
Subject: [PATCH] [BZ 189020] libutil: add util_file_read_i()/util_file_read_ui()
From: Jan Hoeppner <hoeppner@linux.ibm.com>
Description: zgetdump: Fix device node determination via sysfs
Symptom: When using zgetdump on a multi-volume device dump, the sysfs
path to determine the device node is incomplete, resulting in
the following error:
$ zgetdump -i /dev/dasdb1
zgetdump: Could not open
"/sys/bus/ccw/devices/0.0.9300/dasdb/dev"
(No such file or directory)
Problem: The sysfs path to determine the device node is incomplete.
Solution: A simple fix would be to add the missing "block" part in the
sysfs path. However, the logic still assumes sysfs links like
"block:" that have been deprecated a decade ago and are no
longer present on modern systems anyway.
Therefore, the logic can greatly be improved. Create a separate
function to determine whether a device is online, remove the
logic for "block:" entries, and use libutil functions to reduce
the complexity even further.
Reproduction: Set up a multi-volume dump using zipl -M (See man page and
corresponding Dump Tool Documentation for more details).
Then simply run:
$ zgetdump -i /dev/dasdb1
on the multi-volume setup.
Upstream-ID: 37348ef662a7052dae798e500ca8c9b769fff3e6
Problem-ID: 189020
Upstream-Description:
libutil: add util_file_read_i()/util_file_read_ui()
These functions parse a sysfs file and return either an
unsigned integer or signed integer.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Acked-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>
---
include/lib/util_file.h | 2 +
libutil/util_file.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+)
--- a/include/lib/util_file.h
+++ b/include/lib/util_file.h
@@ -12,8 +12,10 @@
#define LIB_UITL_FILE_H
int util_file_read_line(char *str, size_t size, const char *fmt, ...);
+int util_file_read_i(int *val, int base, const char *fmt, ...);
int util_file_read_l(long *val, int base, const char *fmt, ...);
int util_file_read_ll(long long *val, int base, const char *fmt, ...);
+int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...);
int util_file_read_ul(unsigned long *val, int base, const char *fmt, ...);
int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...);
--- a/libutil/util_file.c
+++ b/libutil/util_file.c
@@ -282,6 +282,44 @@ int util_file_write_ull(unsigned long lo
}
/**
+ * Read a file and convert it to signed int according to given base
+ *
+ * @param[out] val Buffer for value
+ * @param[in] base Base for conversion, either 8, 10, or 16
+ * @param[in] fmt Format string for generation of the path name
+ * @param[in] ... Parameters for format string
+ *
+ * @retval 0 Integer has been read correctly
+ * @retval -1 Error while reading file
+ */
+int util_file_read_i(int *val, int base, const char *fmt, ...)
+{
+ char path[PATH_MAX], buf[512];
+ va_list ap;
+ int count;
+
+ /* Construct the file name */
+ UTIL_VSPRINTF(path, fmt, ap);
+
+ if (file_gets(buf, sizeof(buf), path))
+ return -1;
+ switch (base) {
+ case 8:
+ count = sscanf(buf, "%do", val);
+ break;
+ case 10:
+ count = sscanf(buf, "%dd", val);
+ break;
+ case 16:
+ count = sscanf(buf, "%dx", val);
+ break;
+ default:
+ util_panic("Invalid base: %d\n", base);
+ }
+ return (count == 1) ? 0 : -1;
+}
+
+/**
* Read a file and convert it to signed long according to given base
*
* @param[out] val Buffer for value
@@ -353,6 +391,44 @@ int util_file_read_ll(long long *val, in
break;
default:
util_panic("Invalid base: %d\n", base);
+ }
+ return (count == 1) ? 0 : -1;
+}
+
+/**
+ * Read a file and convert it to unsigned int according to given base
+ *
+ * @param[out] val Buffer for value
+ * @param[in] base Base for conversion, either 8, 10, or 16
+ * @param[in] fmt Format string for generation of the path name
+ * @param[in] ... Parameters for format string
+ *
+ * @retval 0 Integer has been read correctly
+ * @retval -1 Error while reading file
+ */
+int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...)
+{
+ char path[PATH_MAX], buf[512];
+ va_list ap;
+ int count;
+
+ /* Construct the file name */
+ UTIL_VSPRINTF(path, fmt, ap);
+
+ if (file_gets(buf, sizeof(buf), path))
+ return -1;
+ switch (base) {
+ case 8:
+ count = sscanf(buf, "%uo", val);
+ break;
+ case 10:
+ count = sscanf(buf, "%uu", val);
+ break;
+ case 16:
+ count = sscanf(buf, "%ux", val);
+ break;
+ default:
+ util_panic("Invalid base: %d\n", base);
}
return (count == 1) ? 0 : -1;
}