diff --git a/debian/changelog b/debian/changelog index f570024..62d56e9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,21 @@ +s390-tools (2.14.0-1ubuntu1.1) groovy; urgency=medium + + * debian/patches/s390-tools-sru-lp1903984-groovy.patch + zcryptstats: Fix handling of partial results with many domains + Thanks to Ingo Franzki (LP: #1903984) + * debian/patches/s390-tools-sru-lp1898935-groovy.patch: + chcpumf installed with s390-tools version 2.14.0 + no longer provides version or help information + backport, actually cherry-pick, from s390-tools v2.15.1 to v2.14 + Thanks to Thomas Richter (LP: #1898935) + * debian/patches/s390-tools-sru-lp1908371-groovy.patch: + zipl command isn't working correctly in combination with the -M + (respectively --mvdump) option. + cherry-picking 4 commits from s390-tools v2.15.1 to v2.14 + Thanks to Stefan Haberland and Sven Schnelle (LP: #1908371) + + -- Frank Heimes Tue, 19 Jan 2021 19:23:32 +0100 + s390-tools (2.14.0-1ubuntu1) groovy; urgency=medium * Merge from Debian, remaining changes: diff --git a/debian/patches/s390-tools-sru-lp1898935-groovy.patch b/debian/patches/s390-tools-sru-lp1898935-groovy.patch new file mode 100644 index 0000000..3999dc7 --- /dev/null +++ b/debian/patches/s390-tools-sru-lp1898935-groovy.patch @@ -0,0 +1,72 @@ +Description: chcpumf installed with s390-tools version 2.14.0 no longer provides version or help information + With s390-tools version 2.14.0 installed with Ubuntu 20.10 the -v and -h + options to chcpumf no longer report the version or display help information. + Rather the message "No CPU-measurement sampling facility detected" is + displayed. This behavior diverges from previous versions and is not consistent + with other binaries provided by the s390-tools package. + This regression was introduced with 2.14 and got fixed in 2.15.1. + - cpumf/chcpumf.c: Fix version and help printout when CPUMF not installed +Author: Thomas Richter +Origin: https://github.com/ibm-s390-tools/s390-tools/commit/ea10995f4d62e6f6adbbc9ec16dd84bb6386618b +Bug-IBM: IBM Bugzilla 188540 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1898935 +Forwarded: not-needed +Applied-Upstream: >= v2.15.1 +Reviewed-by: Frank Heimes +Last-Update: 2020-12-21 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/cpumf/chcpumf.c ++++ b/cpumf/chcpumf.c +@@ -60,10 +60,6 @@ + } + }; + +-/* Parse tool parameters. Fill in global variables keep_case, buffersize and +- * command according to parameters. Return VMCP_OK on success, VMCP_OPT +- * in case of parameter errors. In case of --help or --version, print +- * respective text to stdout and exit. */ + static long parse_buffersize(char *string) + { + char *suffix; +@@ -91,6 +87,7 @@ + + static int read_sfb(unsigned long *min, unsigned long *max) + { ++ unsigned long cur_min_sdb, cur_max_sdb; + int rc = EXIT_SUCCESS; + FILE *fp; + +@@ -99,9 +96,14 @@ + linux_error(PERF_SFB_SIZE); + return EXIT_FAILURE; + } +- if (fscanf(fp, "%ld,%ld", min, max) != 2) { ++ if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) { + fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE); + rc = EXIT_FAILURE; ++ } else { ++ if (*min == 0) ++ *min = cur_min_sdb; ++ if (*max == 0) ++ *max = cur_max_sdb; + } + fclose(fp); + return rc; +@@ -196,6 +198,7 @@ + util_prg_init(&prg); + util_opt_init(opt_vec, NULL); + ++ parse_args(argc, argv); + if (stat(PERF_PATH PERF_SF, &sbuf) != 0) { + fprintf(stderr, + "No CPU-measurement sampling facility detected\n"); +@@ -203,8 +206,6 @@ + } + if (read_sfb(&min_sdb, &max_sdb)) + return ret; +- /* Overwrite min_sdb and/or max_sdb */ +- parse_args(argc, argv); + if (min_sdb >= max_sdb) { + fprintf(stderr, "The specified maximum must be greater " + "than the minimum\n"); diff --git a/debian/patches/s390-tools-sru-lp1903984-groovy.patch b/debian/patches/s390-tools-sru-lp1903984-groovy.patch new file mode 100644 index 0000000..fc4952f --- /dev/null +++ b/debian/patches/s390-tools-sru-lp1903984-groovy.patch @@ -0,0 +1,49 @@ +Description: zcryptstats fails + The zcryptstats tool reports data for only the last two domain IDs. + Further, it hangs if one collect data for a complete crypto card, + and then one has to kill the ssh session to get back. + Patch/commit is: + cf2311f cf2311f1f1de17435b49ba8c8697be91705ba031 + "zcryptstats: Fix handling of partial results with many domains" + - zconf/zcrypt/zcryptstats.c: code fix to pass the correct next-domain + to the subsequent CHSC call of a partial response +Author: Ingo Franzki +Origin: https://github.com/ibm-s390-tools/s390-tools/commit/cf2311f1f1de17435b49ba8c8697be91705ba031 +Bug-IBM: IBM Bugzilla 189183 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1903984 +Forwarded: not-needed +Applied-Upstream: upstream accepted with > v2.15.1 +Reviewed-by: Frank Heimes +Last-Update: 2021-01-19 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/zconf/zcrypt/zcryptstats.c ++++ b/zconf/zcrypt/zcryptstats.c +@@ -1178,8 +1178,14 @@ + scdmd_area.request.header.code = 0x102d; + scdmd_area.request.header.length = + sizeof(struct chsc_scdmd_request); +- scdmd_area.request.first_drid.ap_index = card; +- scdmd_area.request.first_drid.domain_index = g.min_domain; ++ if (scdmd_area.response.p) { ++ scdmd_area.request.first_drid = ++ scdmd_area.response.crid; ++ } else { ++ scdmd_area.request.first_drid.ap_index = card; ++ scdmd_area.request.first_drid.domain_index = ++ g.min_domain; ++ } + scdmd_area.request.last_drid.ap_index = card; + scdmd_area.request.last_drid.domain_index = g.max_domain; + scdmd_area.request.s = 1; +@@ -1217,10 +1223,6 @@ + rc = process_apqn_measurement_data(&scdmd_area); + if (rc != 0) + break; +- +- if (scdmd_area.response.p) +- scdmd_area.request.first_drid = +- scdmd_area.response.crid; + } while (scdmd_area.response.p); + + return rc; diff --git a/debian/patches/s390-tools-sru-lp1908371-groovy.patch b/debian/patches/s390-tools-sru-lp1908371-groovy.patch new file mode 100644 index 0000000..7ba3725 --- /dev/null +++ b/debian/patches/s390-tools-sru-lp1908371-groovy.patch @@ -0,0 +1,402 @@ +Description: The zipl command doesn't work correctly in combination with the -M + (respectively --mvdump) option. There is an error with the preparation of + multi-volume dumps, since the bus-ID for the first disk partition that is + listed in file dump_conf (DEVLIST) isn't found. + - include/lib/util_sys.h: declaration of new util_sys_* functions + - include/lib/util_file.h: declaration of two new util_file_read_* functions + - libutil/util_sys.c: implementation of new util_sys_* functions; + getting minor and major device number now based on base device + and prechecking if base device available util_file_read_* functions + - libutil/util_file.c: implementation of two new + - zipl/src/disk.c: removing blkext_* function set and changing code to + use the new util_sys_* functions +Author: Stefan Haberland , Sven Schnelle +Origin: https://github.com/ibm-s390-tools/s390-tools/commit/fa7a4dafa3d89b2e8787de102e4362e895d44b05 + https://github.com/ibm-s390-tools/s390-tools/commit/aa8c2945cc7b047c626e75817c6a3e3924413023 + https://github.com/ibm-s390-tools/s390-tools/commit/6802b86414b48c4f118da09c7bf7ee142a459fa0 + https://github.com/ibm-s390-tools/s390-tools/commit/37348ef662a7052dae798e500ca8c9b769fff3e6 +Bug-IBM: IBM Bugzilla 187221 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1908371 +Forwarded: not-needed +Applied-Upstream: >= v2.15.1 +Reviewed-by: Frank Heimes +Last-Update: 2020-12-22 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/include/lib/util_file.h ++++ b/include/lib/util_file.h +@@ -12,8 +12,10 @@ + #define LIB_UTIL_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/include/lib/util_sys.h ++++ b/include/lib/util_sys.h +@@ -12,6 +12,11 @@ + #ifndef LIB_UTIL_SYS_H + #define LIB_UTIL_SYS_H + ++#include ++ + int util_sys_get_dev_addr(const char *dev, char *addr); ++bool util_sys_dev_is_partition(dev_t dev); ++int util_sys_get_partnum(dev_t dev); ++int util_sys_get_base_dev(dev_t dev, dev_t *base_dev); + + #endif /** LIB_UTIL_SYS_H @} */ +--- a/libutil/util_file.c ++++ b/libutil/util_file.c +@@ -282,6 +282,44 @@ + } + + /** ++ * 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 @@ + 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; + } +--- a/libutil/util_sys.c ++++ b/libutil/util_sys.c +@@ -11,17 +11,114 @@ + + #include + #include ++#include + #include ++#include + #include + #include + #include + #include + ++#include "lib/util_file.h" ++#include "lib/util_libc.h" + #include "lib/util_path.h" + #include "lib/util_sys.h" + + /* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */ + #define READLINK_SIZE 256 ++#define PAGE_SIZE 4096 ++ ++/** ++ * Return the partition number of a given partition. ++ * ++ * @param[in] dev Device node of interest ++ * ++ * @retval int Partition number of the device ++ * @retval -1 Error when trying to read the partition number. ++ */ ++int util_sys_get_partnum(dev_t dev) ++{ ++ int partnum = -1; ++ char *path; ++ ++ path = util_path_sysfs("dev/block/%u:%u/partition", ++ major(dev), minor(dev)); ++ if (util_file_read_i(&partnum, 10, path)) { ++ warnx("Could not read from path '%s'", path); ++ goto out; ++ } ++ if (partnum <= 0) { ++ warnx("Bad partition number in '%s'", path); ++ partnum = -1; ++ goto out; ++ } ++ ++out: ++ free(path); ++ return partnum; ++} ++ ++/** ++ * Determine if the given device is a partition. ++ * ++ * @param[in] dev Device node of interest ++ * ++ * @retval true Device is partition ++ * @retval false Device is not a partition ++ */ ++bool util_sys_dev_is_partition(dev_t dev) ++{ ++ bool is_part; ++ char *path; ++ ++ path = util_path_sysfs("dev/block/%u:%u/partition", ++ major(dev), minor(dev)); ++ is_part = util_path_exists(path); ++ free(path); ++ ++ return is_part; ++} ++ ++/** ++ * Determine base device ++ * ++ * This function determines the base device \p base_dev of a given ++ * device \p dev. If \p dev is a base device, \p base_dev becomes \p dev. ++ * ++ * @param[in] dev Device node of interest ++ * @param[out] base_dev Identified base device ++ * ++ * @retval 0 Success ++ * @retval -1 Error while reading device information or ++ * constructed path ++ */ ++int util_sys_get_base_dev(dev_t dev, dev_t *base_dev) ++{ ++ int base_major, base_minor; ++ char buf[PAGE_SIZE]; ++ char *path; ++ ++ /* check if the device already is a base device */ ++ if (!util_sys_dev_is_partition(dev)) { ++ *base_dev = makedev(major(dev), minor(dev)); ++ return 0; ++ } ++ path = util_path_sysfs("dev/block/%d:%d/../dev", ++ major(dev), minor(dev)); ++ if (util_file_read_line(buf, sizeof(buf), path)) { ++ warnx("Could not read from path '%s'", path); ++ free(path); ++ return -1; ++ } ++ free(path); ++ if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) { ++ warn("Could not parse major:minor from string '%s'", buf); ++ return -1; ++ } ++ *base_dev = makedev(base_major, base_minor); ++ ++ return 0; ++} + + /** + * Identify device address +@@ -44,13 +141,17 @@ + unsigned int maj, min; + struct stat s; + ssize_t len; ++ dev_t base; + char *path; + + if (stat(dev, &s) != 0) + return -1; + +- maj = major(s.st_rdev); +- min = minor(s.st_rdev); ++ if (util_sys_get_base_dev(s.st_rdev, &base)) ++ return -1; ++ ++ maj = major(base); ++ min = minor(base); + + if (S_ISBLK(s.st_mode)) + path = util_path_sysfs("dev/block/%u:%u/device", maj, min); +--- a/zipl/src/disk.c ++++ b/zipl/src/disk.c +@@ -25,6 +25,7 @@ + #include + + #include "lib/util_proc.h" ++#include "lib/util_sys.h" + + #include "disk.h" + #include "error.h" +@@ -89,88 +90,6 @@ + return 0; + } + +-static int blkext_get_partnum(dev_t dev) +-{ +- char path[PATH_MAX], *buf; +- int dev_major, dev_minor, partnum = -1; +- +- dev_major = major(dev); +- dev_minor = minor(dev); +- snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition", +- dev_major, dev_minor); +- +- if (misc_read_special_file(path, &buf, NULL, 1)) { +- error_text("Could not read from path '%s'", path); +- return -1; +- } +- +- partnum = atoi(buf); +- free(buf); +- if (partnum < 0) { +- error_text("Bad partition number in '%s'", path); +- return -1; +- } +- +- return partnum; +-} +- +-static int blkext_is_base_device(dev_t dev) +-{ +- int dev_major, dev_minor; +- char path[PATH_MAX]; +- struct stat stats; +- +- dev_major = major(dev); +- dev_minor = minor(dev); +- +- snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition", +- dev_major, dev_minor); +- return (stat(path, &stats)); +-} +- +-static int blkext_get_base_dev(dev_t dev, dev_t *base_dev) +-{ +- int base_major, base_minor; +- char dev_path[PATH_MAX], base_path[PATH_MAX]; +- char *temp_path, *buf; +- +- misc_asprintf(&temp_path, "/sys/dev/block/%d:%d", major(dev), minor(dev)); +- if (!realpath(temp_path, dev_path)) { +- error_reason(strerror(errno)); +- error_text("Could not resolve link %s", temp_path); +- free(temp_path); +- return -1; +- } +- free(temp_path); +- +- misc_asprintf(&temp_path, "%s/..", dev_path); +- if (!realpath(temp_path, base_path)) { +- error_reason(strerror(errno)); +- error_text("Could not resolve path %s", temp_path); +- free(temp_path); +- return -1; +- } +- free(temp_path); +- +- misc_asprintf(&temp_path, "%s/dev", base_path); +- if (misc_read_special_file(temp_path, &buf, NULL, 1)) { +- error_text("Could not read from path '%s'", temp_path); +- free(temp_path); +- return -1; +- } +- free(temp_path); +- +- if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) { +- error_text("Could not parse major:minor from string '%s'", buf); +- free(buf); +- return -1; +- } +- +- free(buf); +- *base_dev = makedev(base_major, base_minor); +- return 0; +-} +- + /* Return non-zero for ECKD type. */ + int + disk_is_eckd(disk_type_t type) +@@ -492,15 +411,15 @@ + data->devno = -1; + data->type = disk_type_scsi; + +- if (blkext_is_base_device(stats.st_rdev)) { +- data->device = stats.st_rdev; +- data->partnum = 0; +- } else { +- if (blkext_get_base_dev(stats.st_rdev, &data->device)) ++ if (util_sys_dev_is_partition(stats.st_rdev)) { ++ if (util_sys_get_base_dev(stats.st_rdev, &data->device)) + goto out_close; +- data->partnum = blkext_get_partnum(stats.st_rdev); ++ data->partnum = util_sys_get_partnum(stats.st_rdev); + if (data->partnum == -1) + goto out_close; ++ } else { ++ data->device = stats.st_rdev; ++ data->partnum = 0; + } + } else { + /* Driver name is unknown */ diff --git a/debian/patches/series b/debian/patches/series index 74ab653..6d4ff86 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -6,3 +6,6 @@ sg3-utils.patch 0001-zkey-add-initramfs-hook.patch 0001-zkey-on-Ubuntu-use-default-benchmarked-Argon2i-with-.patch 0001-dumpconf-Don-t-run-the-service-in-LXC.patch +s390-tools-sru-lp1903984-groovy.patch +s390-tools-sru-lp1898935-groovy.patch +s390-tools-sru-lp1908371-groovy.patch