diff -Nru s390-tools-2.23.0/ap_tools/ap-check.c s390-tools-2.25.0/ap_tools/ap-check.c --- s390-tools-2.23.0/ap_tools/ap-check.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/ap_tools/ap-check.c 2022-12-08 13:40:15.000000000 +0100 @@ -133,7 +133,7 @@ if (anc->dev) vfio_ap_device_free(anc->dev); if (anc->cleanup_lock) - ap_release_lock(); + ap_release_lock_callout(); } /* @@ -685,6 +685,14 @@ goto out; } + /* Ensure device with control domains also has usage domains */ + if (util_list_is_empty(anc->dev->domains) && + !util_list_is_empty(anc->dev->controls)) { + fprintf(stderr, "At least one usage domain must be specified\n"); + rc = -1; + goto out; + } + /* Check against all other active vfio-ap devices */ rc = check_other_mdevs_sysfs(anc); /* Check against the system sysfs values for apmask/aqmask */ @@ -767,7 +775,7 @@ */ static int ap_check_handle_post(void) { - return ap_release_lock(); + return ap_release_lock_callout(); } /* For the specified device, print the attributes to stdout in JSON format */ diff -Nru s390-tools-2.23.0/ap_tools/ap-check.sh s390-tools-2.25.0/ap_tools/ap-check.sh --- s390-tools-2.23.0/ap_tools/ap-check.sh 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/ap_tools/ap-check.sh 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,15 @@ +#!/bin/sh +# +# ap-check.sh - Wrapper script for 'ap-check' binary +# +# mdevctl has deprecated the /etc/mdevctl.d/scripts.d/callouts/ location in +# newer releases. This wrapper ensures that mdevctl 1.2.0 and older can +# still access 'ap-check' for now, and will be removed at a later time. +# +# Copyright 2022 IBM Corp. +# +# s390-tools is free software; you can redistribute it and/or modify +# it under the terms of the MIT license. See LICENSE for details. +# + +[ -e /usr/lib/mdevctl/scripts.d/callouts/ap-check ] && /usr/lib/mdevctl/scripts.d/callouts/ap-check "$@" diff -Nru s390-tools-2.23.0/ap_tools/Makefile s390-tools-2.25.0/ap_tools/Makefile --- s390-tools-2.23.0/ap_tools/Makefile 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/ap_tools/Makefile 2022-12-08 13:40:15.000000000 +0100 @@ -1,27 +1,23 @@ include ../common.mak -MDEVCTL_DIR = /etc/mdevctl.d/ -MDEVCTL_SCRIPTS = /etc/mdevctl.d/scripts.d/ -MDEVCTL_CALLOUTS = /etc/mdevctl.d/scripts.d/callouts/ +MDEVCTL_DIR = /usr/lib/mdevctl/ +MDEVCTL_SCRIPTS = /usr/lib/mdevctl/scripts.d/ +MDEVCTL_CALLOUTS = /usr/lib/mdevctl/scripts.d/callouts/ +MDEVCTL_DEP_DIR = /etc/mdevctl.d/ +MDEVCTL_DEP_SCRIPTS = /etc/mdevctl.d/scripts.d/ +MDEVCTL_DEP_CALLOUTS = /etc/mdevctl.d/scripts.d/callouts/ libs = $(rootdir)/libap/libap.a \ $(rootdir)/libutil/libutil.a -ifeq (${HAVE_LOCKFILE},0) -all: - $(SKIP) HAVE_LOCKFILE=0 - -install: - $(SKIP) HAVE_LOCKFILE=0 - -else ifeq (${HAVE_JSONC},0) +ifeq (${HAVE_JSONC},0) all: $(SKIP) HAVE_JSONC=0 install: $(SKIP) HAVE_JSONC=0 else -LDLIBS += -llockfile -ljson-c +LDLIBS += -ljson-c all: ap-check @@ -39,6 +35,17 @@ fi; \ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ap-check \ $(DESTDIR)$(MDEVCTL_CALLOUTS) + @if [ ! -d $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS) ]; then \ + mkdir -p $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \ + chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_DIR); \ + chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \ + chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \ + chmod 755 $(DESTDIR)$(MDEVCTL_DEP_DIR); \ + chmod 755 $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \ + chmod 755 $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \ + fi; \ + $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ap-check.sh \ + $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS) endif clean: diff -Nru s390-tools-2.23.0/AUTHORS.md s390-tools-2.25.0/AUTHORS.md --- s390-tools-2.23.0/AUTHORS.md 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/AUTHORS.md 2022-12-08 13:40:15.000000000 +0100 @@ -21,6 +21,7 @@ - Colin Walters - Dan Horak - Dan HorĂ¡k +- Daniel S. Haischt - Despina Papadopoulou - Dimitri John Ledkov - Eberhard Pasch diff -Nru s390-tools-2.23.0/CHANGELOG.md s390-tools-2.25.0/CHANGELOG.md --- s390-tools-2.23.0/CHANGELOG.md 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/CHANGELOG.md 2022-12-08 13:40:15.000000000 +0100 @@ -1,6 +1,43 @@ Release history for s390-tools (MIT version) -------------------------------------------- +* __v2.25.0 (2022-12-08)__ + + For Linux kernel version: 6.1 + + Changes of existing tools: + - ap_tools: Use new mdevctl installation location + - lsdasd/tunedasd/zdev: Add support to handle copy pair relations presented by the DASD driver + - zdev: Add --shell command line switch to generate output suitable for shell environments + - zipl: Add List-Directed IPL from ECKD DASD to support secure boot + + Bug Fixes: + - ipl_tools: Fix chreipl node for NVMes with CONFIG_NVME_MULTIPATH + - libdasd: Fix bug that prevented positive ioctl return codes + +* __v2.24.0 (2022-11-09)__ + + For Linux kernel version: 6.0 + + Add new tools / libraries: + - Provide config files for checkpatch, codespell, and clang-format + + Changes of existing tools: + - dbginfo.sh: Collect log from various distro tools (YaST, DNF, Anaconda) + - dbginfo.sh: add Kubernetes data collection + - libutil: Introduce util_lockfile + - zdev: Add site-aware device configuration + - zdump: Add support to read Protected Virtualization dumps + - zipl/boot: Add secure boot trailer + + Bug Fixes: + - ap_tools/ap-check: Reject start for control domains without usage + - cpumf/lshwc: Fix incremented counter output + - cpumf/pai: Fix core dump when summary flag set + - dbginfo.sh: Ensure compatibility with /bin/dash shell + - dbginfo.sh: Save dbginfo.sh version to dbginfo.log + - zipl/src/zipl_helper.device-mapper: Fix bug in error path + * __v2.23.0 (2022-08-18)__ For Linux kernel version: 5.19 @@ -24,7 +61,6 @@ - pvattest: Fix dependency checking - zipl: Fix segmentation fault when no parmline is provided - * __v2.22.0 (2022-06-20)__ For Linux kernel version: 5.18 diff -Nru s390-tools-2.23.0/.checkpatch.conf s390-tools-2.25.0/.checkpatch.conf --- s390-tools-2.23.0/.checkpatch.conf 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/.checkpatch.conf 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,12 @@ +--max-line-length=100 +--strict + +# Not Linux therefore don't expect a Linux tree +--no-tree + +# Ignore the following +--ignore PREFER_KERNEL_TYPES +--ignore EXECUTE_PERMISSIONS +--ignore FILE_PATH_CHANGES +--ignore NEW_TYPEDEFS +--ignore SPDX_LICENSE_TAG diff -Nru s390-tools-2.23.0/.clang-format s390-tools-2.25.0/.clang-format --- s390-tools-2.23.0/.clang-format 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/.clang-format 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,134 @@ +# Must be compatible with clang-format 14 +--- +AccessModifierOffset: "-4" +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: AcrossComments +AlignConsecutiveMacros: AcrossComments +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BitFieldColonSpacing: Both +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: BeforeComma +BreakConstructorInitializersBeforeComma: false +BreakStringLiterals: false +ColumnLimit: "100" +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: "8" +ContinuationIndentWidth: "8" +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +# git grep -h '^#define [^[:space:]]*\(for_each\|iterate\)[^[:space:]]*(' \ +# | sed "s,^#define \([^[:space:]]*\(for_each\|iterate\)[^[:space:]]*\)(.*$, - '\1'," \ +# | LC_ALL=C sort -u +ForEachMacros: + - "dfi_cpu_iterate" + - "dfi_mem_chunk_iterate" + - "dfo_chunk_iterate" + - "for_each_rb_entry" + - "ns_range_for_each" + - "sd_cpu_item_enable_iterate" + - "sd_cpu_item_iterate" + - "sd_cpu_iterate" + - "sd_cpu_type_iterate" + - "sd_sys_item_enable_iterate" + - "sd_sys_item_iterate" + - "sd_sys_iterate" + - "table_col_iterate" + - "table_iterate_mark_keys" + - "util_list_iterate" + - "util_list_iterate_safe" + - "util_opt_iterate" + - "util_rec_iterate" +IncludeBlocks: Preserve +# Leave imports as is +IncludeCategories: + - Regex: .* + Priority: 1 +IndentCaseLabels: false +IndentGotoLabels: false +IndentPPDirectives: None +IndentWidth: "8" +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: "" +MacroBlockEnd: "" +MaxEmptyLinesToKeep: "1" +NamespaceIndentation: Inner +PackConstructorInitializers: CurrentLine +PenaltyBreakAssignment: "10" +PenaltyBreakBeforeFirstCallParameter: "30" +PenaltyBreakComment: "10" +PenaltyBreakFirstLessLess: "0" +PenaltyBreakString: "10" +PenaltyExcessCharacter: "100" +PenaltyReturnTypeOnItsOwnLine: "60" +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatementsExceptForEachMacros +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: "1" +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +StatementMacros: + - "STATIC_ASSERT" +TabWidth: "8" +TypenameMacros: + - "STACK_OF" +UseTab: Always +WhitespaceSensitiveMacros: + - "STRINGIFY" diff -Nru s390-tools-2.23.0/.codespellrc s390-tools-2.25.0/.codespellrc --- s390-tools-2.23.0/.codespellrc 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/.codespellrc 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,5 @@ +[codespell] +ignore-words-list = parm,parms +skip = '' +count = '' +quiet-level = 3 diff -Nru s390-tools-2.23.0/CODINGSTYLE.md s390-tools-2.25.0/CODINGSTYLE.md --- s390-tools-2.23.0/CODINGSTYLE.md 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/CODINGSTYLE.md 2022-12-08 13:40:15.000000000 +0100 @@ -4,8 +4,10 @@ For s390-tools the preferred language is C. We provide libraries, e.g. [`libutil`](libutil) that should be used by all tools if possible. -The coding style is based on the Linux [kernel guidelines]. Therefore, use -the [checkpatch] tool for verification before you submit a patch. +The coding style is based on the Linux [kernel guidelines]. Therefore, use the +[checkpatch] tool for verification before you submit a patch. s390-tools +provides a CheckPatch configuration for this - see +[`.checkpatch.conf`](.checkpatch.conf). [kernel guidelines]: https://www.kernel.org/doc/html/latest/process/coding-style.html [checkpatch]: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl @@ -17,6 +19,39 @@ might not follow all recommendations. Note that when changing existing code, consistency could have priority over applying rules. +Automatic Code Formatting +------------------------- + +> **NOTE:** clang-format is a helpful tool but please don't use it blindly! + +s390-tools provides a ClangFormat (https://clang.llvm.org/docs/ClangFormat.html) +configuration file - see [`.clang-format`](.clang-format). It can be used to +format your C/C++ code automatically. + +Clang-format can format a single file or multiple files at once. For example, to +format `main.c` in place, run the following command in a terminal: + +```bash +clang-format -i main.c +``` + +In order to format only your current staged changes use the clang-format git +plugin: + +```bash +git clang-format --staged +``` + +See also `git clang-format -h`. + +Automatic Editor Configuration +------------------------------ + +s390-tools provides a EditorConfig (https://editorconfig.org/) configuration +file - see [`.editorconfig`](.editorconfig). EditorConfig defines coding style +rules (such as indentation size, use of tabs, etc.) and is supported by most +common editors natively or via plugins. + Standard abbreviations ---------------------- diff -Nru s390-tools-2.23.0/common.mak s390-tools-2.25.0/common.mak --- s390-tools-2.23.0/common.mak 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/common.mak 2022-12-08 13:40:15.000000000 +0100 @@ -5,7 +5,7 @@ # The variable "DISTRELEASE" should be overwritten in rpm spec files with: # "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}" VERSION = 2 -RELEASE = 23 +RELEASE = 25 PATCHLEVEL = 0 DISTRELEASE = build-$(shell date +%Y%m%d) S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE) @@ -60,8 +60,10 @@ $(eval $(call cmd_define, AS," AS ",$(CROSS_COMPILE)as)) $(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc)) +$(eval $(call cmd_define, LINK," LINK ",$(CC))) $(eval $(call cmd_define, HOSTCC," HOSTCC ",gcc)) $(eval $(call cmd_define, CXX," CXX ",$(CROSS_COMPILE)g++)) +$(eval $(call cmd_define, LINKXX," LINKXX ",$(CXX))) $(eval $(call cmd_define, CPP," CPP ",$(CROSS_COMPILE)gcc -E)) $(eval $(call cmd_define, AR," AR ",$(CROSS_COMPILE)ar)) $(eval $(call cmd_define, NM," NM ",$(CROSS_COMPILE)nm)) @@ -81,8 +83,6 @@ SKIP = echo " SKIP $(call reldir) due to" INSTALL = install -LINK = $(CC) -LINKXX = $(CXX) CP = cp ifneq ("${V}","1") MAKEFLAGS += --quiet @@ -120,7 +120,7 @@ define check_header_prereq $(shell printf "#include <%s>\n int main(void) {return 0;}\n" $1 | \ ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) \ - $2 -o /dev/null -xc - ) >/dev/null 2>&1 && echo -n yes) + $2 -o /dev/null -x c - ) >/dev/null 2>&1 && echo -n yes) endef # @@ -133,7 +133,7 @@ # $5: Additional compiler & linker options (optional) # check_dep=\ -printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -xc - ) > /dev/null 2>&1; \ +printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -x c - ) > /dev/null 2>&1; \ if [ $$? != 0 ]; \ then \ printf " REQCHK %s (%s)\n" $1 $2; \ diff -Nru s390-tools-2.23.0/cpumf/lshwc.c s390-tools-2.25.0/cpumf/lshwc.c --- s390-tools-2.23.0/cpumf/lshwc.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/cpumf/lshwc.c 2022-12-08 13:40:15.000000000 +0100 @@ -356,6 +356,8 @@ putchar(','); printf("%ld", ctrname[i].total); comma = true; + ctrname[i].total = 0; + ctrname[i].hitcnt = false; } putchar('\n'); } @@ -446,7 +448,7 @@ ctrname[idx].ccv = calloc(max_possible_cpus, sizeof(unsigned long)); if (ctrname[idx].ccv) - ctrname[idx].ccv[cpu] += value; + ctrname[idx].ccv[cpu] = value; ctrname[idx].total += value; ctrname[idx].hitcnt = true; return true; @@ -458,10 +460,8 @@ size_t offset = 0; /* Clear previous hit counters */ - for (unsigned int i = 0; i < max_possible_cpus; ++i) { - check[i].sets_hit = 0; + for (unsigned int i = 0; i < max_possible_cpus; ++i) check[i].cpu_hit = false; - } /* Iterate over all CPUs */ for (unsigned int i = 0; i < read->no_cpus; ++i) { diff -Nru s390-tools-2.23.0/cpumf/pai.c s390-tools-2.25.0/cpumf/pai.c --- s390-tools-2.23.0/cpumf/pai.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/cpumf/pai.c 2022-12-08 13:40:15.000000000 +0100 @@ -426,7 +426,7 @@ static void evt_show(__u64 evtnum, const char *evtsel, struct pai_event_out *ev) { if (summary) { - if (ev->type == PERF_RECORD_SAMPLE) + if (ev->type == PERF_RECORD_SAMPLE && ev->raw) evtraw_show(evtnum, ev->raw); return; } diff -Nru s390-tools-2.23.0/debian/changelog s390-tools-2.25.0/debian/changelog --- s390-tools-2.23.0/debian/changelog 2022-08-17 10:55:47.000000000 +0200 +++ s390-tools-2.25.0/debian/changelog 2023-01-26 12:22:05.000000000 +0100 @@ -1,3 +1,13 @@ +s390-tools (2.25.0-0ubuntu1) lunar; urgency=medium + + * New upstream release, requested in LP: #2006451 + * Remove d/p/lp1986991-fix-binary-in-etc.patch and the corresponding lines + in debian/rules and debian/s390-tools.install, since a fix for this is + now upstream included with commit 4b5937f + "ap_tools/ap-check: use new mdevctl install location". + + -- Frank Heimes Thu, 26 Jan 2023 12:22:05 +0100 + s390-tools (2.23.0-0ubuntu1) kinetic; urgency=medium * New upstream release, that solves LP: #1986991, but also the following: diff -Nru s390-tools-2.23.0/debian/patches/lp1986991-fix-binary-in-etc.patch s390-tools-2.25.0/debian/patches/lp1986991-fix-binary-in-etc.patch --- s390-tools-2.23.0/debian/patches/lp1986991-fix-binary-in-etc.patch 2022-08-17 10:55:47.000000000 +0200 +++ s390-tools-2.25.0/debian/patches/lp1986991-fix-binary-in-etc.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,29 +0,0 @@ -Description: wrapper script for ap-check to avoid binary-in-etc lintian error - Per default the 'ap-check' ELF binary is installed to - /etc/mdevctl.d/scripts.d/callouts/. But the Filesystem Hierarchy Standard - forbids this, see: - https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html#etcHostspecificSystemConfiguration - Refer to Section 3.7. - Hence based on this, lintian reports this as 'binary-in-etc' error. - To solve this, the binary is moved from /etc/mdevctl.d/scripts.d/callouts/ - to /usr/lib/s390-tools/ and wrapped by a shell script with the same name - 'ap-check' located in /etc/mdevctl.d/scripts.d/callouts/. - Please notice that this requires to move the 'ap-check' binary within the - build tree to /usr/lib/s390-tools/ - where other binaries files already - reside - which is done in debian/rules. In addition the two files (binary - and script) need to be picked up by the package in the correct folders, - which is done in debian/s390-tools.install. -Author: Frank Heimes -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1986670 -Forwarded: https://github.com/ibm-s390-linux/s390-tools/issues/143 -Reviewed-by: Frank Heimes -Last-Update: 2022-08-18 ---- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- /dev/null -+++ b/etc/mdevctl.d/scripts.d/callouts/ap-check -@@ -0,0 +1,4 @@ -+#!/bin/sh -+# wrapper script for 'ap-check' binary, to avoid lintian error 'binary-in-etc' -+ -+[ -e /usr/lib/s390-tools/ap-check ] && /usr/lib/s390-tools/ap-check "$@" diff -Nru s390-tools-2.23.0/debian/patches/series s390-tools-2.25.0/debian/patches/series --- s390-tools-2.23.0/debian/patches/series 2022-08-17 10:55:47.000000000 +0200 +++ s390-tools-2.25.0/debian/patches/series 2023-01-26 12:22:05.000000000 +0100 @@ -1,4 +1,3 @@ install-iucvterm.patch bashism.patch sg3-utils.patch -lp1986991-fix-binary-in-etc.patch diff -Nru s390-tools-2.23.0/debian/rules s390-tools-2.25.0/debian/rules --- s390-tools-2.23.0/debian/rules 2022-08-17 10:55:47.000000000 +0200 +++ s390-tools-2.25.0/debian/rules 2023-01-26 12:22:05.000000000 +0100 @@ -29,7 +29,6 @@ dh_install -ps390-tools-chreipl-fcp-mpath dh_install $(if $(SIGN_SIPL),-Xstage3.bin) -Xcpuplugd -Xosasnmpd -Xprocd -Xfsstatd -X60-readahead.rules -Xzkey -Xchreipl-fcp-mpath $(if $(SIGN_SIPL),echo 'signing:Depends=s390-tools-signed (= $(DEB_VERSION))') >> debian/s390-tools.substvars - find . -iname "ap-check.sh" override_dh_fixperms: dh_fixperms @@ -45,7 +44,6 @@ override_dh_auto_install: HAVE_INITRAMFS=1 HAVE_DRACUT=1 dh_auto_install -- $(options) - mkdir -p ./debian/tmp/usr/lib/s390-tools/ && mv ./debian/tmp/etc/mdevctl.d/scripts.d/callouts/ap-check ./debian/tmp/usr/lib/s390-tools/ signing=debian/s390-tools-$(DEB_VERSION)-signing/ signingv=$(signing)/$(DEB_VERSION) diff -Nru s390-tools-2.23.0/debian/s390-tools.install s390-tools-2.25.0/debian/s390-tools.install --- s390-tools-2.23.0/debian/s390-tools.install 2022-08-17 10:55:47.000000000 +0200 +++ s390-tools-2.25.0/debian/s390-tools.install 2023-01-26 12:22:05.000000000 +0100 @@ -52,8 +52,8 @@ pvattest/tools/pvattest-info /usr/share/s390-tools/pvattest/ # ap_tools -debian/tmp/usr/lib/s390-tools/ap-check /usr/lib/s390-tools/ -./etc/mdevctl.d/scripts.d/callouts/ap-check /etc/mdevctl.d/scripts.d/callouts/ +debian/tmp/usr/lib/mdevctl/scripts.d/callouts/ap-check /usr/lib/mdevctl/scripts.d/callouts/ +etc/mdevctl.d/scripts.d/callouts/ap-check.sh # readmes genprotimg/README.md /usr/share/s390-tools/genprotimg/ diff -Nru s390-tools-2.23.0/genprotimg/src/common.h s390-tools-2.25.0/genprotimg/src/common.h --- s390-tools-2.23.0/genprotimg/src/common.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/genprotimg/src/common.h 2022-12-08 13:40:15.000000000 +0100 @@ -10,7 +10,7 @@ #define GETTEXT_PACKAGE "genprotimg" #include -#include +#include #include "boot/linux_layout.h" #include "boot/s390.h" diff -Nru s390-tools-2.23.0/.gitignore s390-tools-2.25.0/.gitignore --- s390-tools-2.23.0/.gitignore 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/.gitignore 2022-12-08 13:40:15.000000000 +0100 @@ -95,6 +95,9 @@ zdev/src/lszdev zdev/src/lszdev_usage.c zdsfs/zdsfs +zdump/.check_dep_fuse +zdump/.check_dep_zgetdump +zdump/.detect_openssl.dep.c zdump/zgetdump zfcpdump/10-zfcpdump.install zfcpdump/cpioinit diff -Nru s390-tools-2.23.0/include/boot/boot_defs.h s390-tools-2.25.0/include/boot/boot_defs.h --- s390-tools-2.23.0/include/boot/boot_defs.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/boot/boot_defs.h 2022-12-08 13:40:15.000000000 +0100 @@ -58,10 +58,40 @@ } __packed; /* + * Format of a boot record on ECKD DASD for List-Directed IPL + */ +struct eckd_boot_record { + uint8_t magic[4]; + uint32_t version_id; + uint8_t unused[8]; + uint8_t program_table_pointer[16]; + uint8_t reserved[478]; + uint16_t os_id; +} __packed; + +/* * Layout of block pointer for cylinder/head/sector devices * e.g. ECKD */ -struct eckd_blockptr { + +enum blkptr_format_id { + /* + * this is the old format which serves only CCW-type IPL, + * and doesn't fit List-Directed IPL. Still supported for + * compatibility reasons. + */ + LEGACY_BLKPTR_FORMAT_ID, + /* + * this is the "new" format which serves only List-Directed IPL, + * but is also suitable for CCW-type IPL. + */ + BLKPTR_FORMAT_ID +}; + +/* + * Block pointers format identified as LEGACY_BLKPTR_FORMAT_ID. + */ +struct eckd_blockptr_legacy { uint16_t cyl; uint16_t head; uint8_t sec; @@ -70,10 +100,22 @@ uint8_t reserved[8]; } __packed; +/* + * Block pointers format identified as BLKPTR_FORMAT_ID. + */ +struct eckd_blockptr { + uint32_t cyl; + uint8_t head; + uint8_t sec; + uint8_t reserved1[4]; + uint16_t blockct; + uint8_t reserved2[4]; +} __packed; + typedef enum { - COMPONENT_EXECUTE = 0x01, - COMPONENT_LOAD = 0x02, - COMPONENT_SIGNATURE = 0x03 + COMPONENT_TYPE_EXECUTE = 0x01, + COMPONENT_TYPE_LOAD = 0x02, + COMPONENT_TYPE_SIGNATURE = 0x03 } component_type; typedef enum { @@ -117,7 +159,8 @@ uint64_t csum_offset; uint64_t csum_size; uint64_t csum; -} __packed; +}; +STATIC_ASSERT(sizeof(struct scsi_dump_sb) == 72); #define SCSI_DUMP_SB_MAGIC 0x5a46435044554d50ULL /* ZFCPDUMP */ /* To avoid a csum entry of 0 a seed is used */ @@ -153,6 +196,7 @@ struct boot_info_bp_ipl { union { + struct eckd_blockptr_legacy eckd_legacy; struct eckd_blockptr eckd; struct linear_blockptr lin; } bm_ptr; diff -Nru s390-tools-2.23.0/include/lib/ap.h s390-tools-2.25.0/include/lib/ap.h --- s390-tools-2.23.0/include/lib/ap.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/lib/ap.h 2022-12-08 13:40:15.000000000 +0100 @@ -90,5 +90,6 @@ int ap_get_lock(void); int ap_get_lock_callout(void); int ap_release_lock(void); +int ap_release_lock_callout(void); #endif /* LIB_AP_H */ diff -Nru s390-tools-2.23.0/include/lib/dasd_base.h s390-tools-2.25.0/include/lib/dasd_base.h --- s390-tools-2.23.0/include/lib/dasd_base.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/lib/dasd_base.h 2022-12-08 13:40:15.000000000 +0100 @@ -20,8 +20,8 @@ #include #include -/* A bus id of a DASD is 8 characters long. E.g. 0.0.4711 */ -#define DASD_BUS_ID_SIZE 9 +/* the definition of a BUSID in the DASD driver is 20 */ +#define DASD_BUS_ID_SIZE 20 typedef struct dasd_information2_t { unsigned int devno; /* S/390 devno */ @@ -187,6 +187,68 @@ #define DASD_FMT_ERR_RECORD_ID 4 #define DASD_FMT_ERR_KEY_LENGTH 5 +/* + * struct profile_info_t + * holds the profiling information + */ +typedef struct dasd_profile_info_t { + unsigned int dasd_io_reqs; /* # of requests processed at all */ + unsigned int dasd_io_sects; /* # of sectors processed at all */ + unsigned int dasd_io_secs[32]; /* request's sizes */ + unsigned int dasd_io_times[32]; /* requests's times */ + unsigned int dasd_io_timps[32]; /* requests's times per sector */ + unsigned int dasd_io_time1[32]; /* time from build to start */ + unsigned int dasd_io_time2[32]; /* time from start to irq */ + unsigned int dasd_io_time2ps[32]; /* time from start to irq */ + unsigned int dasd_io_time3[32]; /* time from irq to end */ + unsigned int dasd_io_nr_req[32]; /* # of requests in chanq */ +} dasd_profile_info_t; + +/* + * struct attrib_data_t + * represents the operation (cache) bits for the device. + * Used in DE to influence caching of the DASD. + */ +typedef struct attrib_data_t { + unsigned char operation : 3; /* cache operation mode */ + unsigned char reserved : 5; + unsigned short nr_cyl; /* no of cyliners for read ahaed */ + unsigned char reserved2[29]; /* for future use */ +} __attribute__((packed)) attrib_data_t; + +/* definition of operation (cache) bits within attributes of DE */ +#define DASD_NORMAL_CACHE 0x0 +#define DASD_BYPASS_CACHE 0x1 +#define DASD_INHIBIT_LOAD 0x2 +#define DASD_SEQ_ACCESS 0x3 +#define DASD_SEQ_PRESTAGE 0x4 +#define DASD_REC_ACCESS 0x5 + +/* + * Data returned by Sense Path Group ID (SNID) + */ +struct dasd_snid_data { + struct { + __u8 group : 2; + __u8 reserve : 2; + __u8 mode : 1; + __u8 res : 3; + } __attribute__((packed)) path_state; + __u8 pgid[11]; +} __attribute__((packed)); + +struct dasd_snid_ioctl_data { + struct dasd_snid_data data; + __u8 path_mask; +} __attribute__((packed)); + +struct dasd_copypair_swap_data { + char primary[DASD_BUS_ID_SIZE]; /* BUSID of primary */ + char secondary[DASD_BUS_ID_SIZE]; /* BUSID of secondary */ + /* Reserved for future updates. */ + char reserved[64]; +}; + #ifndef __linux__ /* definition from hdreg.h */ struct hd_geometry { @@ -207,27 +269,29 @@ #define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2) /* Release the device for the current LPAR */ #define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3) +/* Unconditional reserve the device for the current LPAR */ +#define BIODASDSLCK _IO(DASD_IOCTL_LETTER, 4) +/* reset profiling information of a device */ +#define BIODASDPRRST _IO(DASD_IOCTL_LETTER, 5) +/* retrieve profiling information of a device */ +#define BIODASDPRRD _IOR(DASD_IOCTL_LETTER, 2, dasd_profile_info_t) /* Get information on a dasd device (enhanced) */ #define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t) +/* Get Attributes (cache operations) */ +#define BIODASDGATTR _IOR(DASD_IOCTL_LETTER, 5, attrib_data_t) /* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */ #define BIODASDFMT _IOW(DASD_IOCTL_LETTER, 1, format_data_t) +/* Set Attributes (cache operations) */ +#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER, 2, attrib_data_t) /* Release Allocated Space */ #define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t) +/* Swap copy pair */ +#define BIODASDPPRCSWAP _IOW(DASD_IOCTL_LETTER, 4, struct dasd_copypair_swap_data) +/* Get Sense Path Group ID (SNID) data */ +#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data) /* Check device format according to format_data_t */ #define BIODASDCHECKFMT _IOWR(DASD_IOCTL_LETTER, 2, format_check_t) -/******************************************************************************** - * SECTION: Further IOCTL Definitions (see fs.h and hdreq.h) - *******************************************************************************/ -/* get read-only status (0 = read_write) */ -#define BLKROGET _IO(0x12, 94) -/* re-read partition table */ -#define BLKRRPART _IO(0x12, 95) -/* get block device sector size */ -#define BLKSSZGET _IO(0x12, 104) -/* return device size in bytes (u64 *arg) */ -#define BLKGETSIZE64 _IOR(0x12, 114, size_t) - #ifndef __linux__ /* from */ #define HDIO_GETGEO 0x0301 #endif @@ -245,5 +309,12 @@ int dasd_reread_partition_table(const char *device, int ntries); int dasd_disk_reserve(const char *device); int dasd_disk_release(const char *device); +int dasd_slock(const char *device); +int dasd_get_cache(const char *device, attrib_data_t *attrib_data); +int dasd_set_cache(const char *device, attrib_data_t *attrib_data); +int dasd_query_reserve(const char *device); +int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info); +int dasd_reset_profile(const char *device); +int dasd_copy_swap(const char *device, struct dasd_copypair_swap_data *data); #endif /* LIB_DASD_BASE_H */ diff -Nru s390-tools-2.23.0/include/lib/util_lockfile.h s390-tools-2.25.0/include/lib/util_lockfile.h --- s390-tools-2.23.0/include/lib/util_lockfile.h 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/include/lib/util_lockfile.h 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,26 @@ +/** + * @defgroup util_lockfile_h util_lockfile: File locking utility + * @{ + * @brief Create file-based locks + * + * Copyright IBM Corp. 2022 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ +#ifndef LIB_UTIL_LOCKFILE_H +#define LIB_UTIL_LOCKFILE_H + +#define UTIL_LOCKFILE_OK 0 /* Lock acquired/released successfully */ +#define UTIL_LOCKFILE_LOCK_FAIL 1 /* Lock already held, ran out of retries */ +#define UTIL_LOCKFILE_RELEASE_NONE 2 /* Lock not held */ +#define UTIL_LOCKFILE_RELEASE_FAIL 3 /* Lock not held by specified pid */ +#define UTIL_LOCKFILE_ERR 4 /* Other, unexpected error conditions */ + +int util_lockfile_lock(char *lockfile, int retries); +int util_lockfile_parent_lock(char *lockfile, int retries); + +int util_lockfile_release(char *lockfile); +int util_lockfile_parent_release(char *lockfile); + +#endif /** LIB_UTIL_LOCKFILE_H @} */ diff -Nru s390-tools-2.23.0/include/lib/vtoc.h s390-tools-2.25.0/include/lib/vtoc.h --- s390-tools-2.23.0/include/lib/vtoc.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/lib/vtoc.h 2022-12-08 13:40:15.000000000 +0100 @@ -97,6 +97,24 @@ unsigned long long formatted_blocks; /* valid when ldl_version >= f2 */ } __attribute__ ((packed)) volume_label_t; +/** + * This represents a volume label specific for OS/390 compatible disk layout + */ +struct vol_label_cdl { + char volkey[4]; + char vollbl[4]; + char opaq[70]; + cchhb_t br; /* boot record address */ + char stdv[1]; /* standard version ID */ +} __attribute__ ((packed)); + +static inline int is_vol1(char *this) +{ + char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00} /* "VOL1" in EBCDIC */; + + return !strncmp(this, vol1, 4); +} + typedef struct extent { u_int8_t typeind; /* extent type indicator */ diff -Nru s390-tools-2.23.0/include/lib/zt_common.h s390-tools-2.25.0/include/lib/zt_common.h --- s390-tools-2.23.0/include/lib/zt_common.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/lib/zt_common.h 2022-12-08 13:40:15.000000000 +0100 @@ -32,6 +32,10 @@ #ifndef __ASSEMBLER__ +#ifndef sizeof_field +#define sizeof_field(type, field) (sizeof((type *)0)->field) +#endif + #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) @@ -50,6 +54,10 @@ #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#ifndef ROUNDUP +# define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +#endif + #define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE) #define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR) #define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR) @@ -62,6 +70,7 @@ #define __may_alias __attribute__((may_alias)) #define __section(x) __attribute__((__section__(#x))) #define __noinline __attribute__((__noinline__)) +#define __big_endian /* The Linux kernel (in stddef.h) and glibc (sys/cdefs.h) define * __always_inline. Therefore undefine it first to allow the headers * to be included first. diff -Nru s390-tools-2.23.0/include/libpv/cert.h s390-tools-2.25.0/include/libpv/cert.h --- s390-tools-2.23.0/include/libpv/cert.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/libpv/cert.h 2022-12-08 13:40:15.000000000 +0100 @@ -68,6 +68,7 @@ PV_CERT_ERROR_MALFORMED_ROOT_CA, PV_CERT_ERROR_NO_CRL, PV_CERT_ERROR_NO_CRLDP, + PV_CERT_ERROR_NO_IBM_Z_SIGNING_KEY, PV_CERT_ERROR_NO_ISSUER_IBM_Z_FOUND, PV_CERT_ERROR_NO_PUBLIC_KEY, PV_CERT_ERROR_READ_CERTIFICATE, diff -Nru s390-tools-2.23.0/include/libpv/common.h s390-tools-2.25.0/include/libpv/common.h --- s390-tools-2.23.0/include/libpv/common.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/libpv/common.h 2022-12-08 13:40:15.000000000 +0100 @@ -15,7 +15,7 @@ */ #include "libpv/glib-helper.h" -#include +#include #include "libpv/openssl-compat.h" #include "libpv/macros.h" diff -Nru s390-tools-2.23.0/include/libpv/crypto.h s390-tools-2.25.0/include/libpv/crypto.h --- s390-tools-2.23.0/include/libpv/crypto.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/libpv/crypto.h 2022-12-08 13:40:15.000000000 +0100 @@ -42,11 +42,14 @@ PV_DECRYPT, }; -/** pv_get_openssl_error: +/** pv_get_openssl_errors: * - * Returns: (transfer full): String representing the error. + * Returns the last OpenSSL error messages. + * Caller is responsible to free the returned value. + * + * Returns: String representing the error. */ -const char *pv_get_openssl_error(void); +char *pv_get_openssl_errors(void); /** * pv_BIO_reset: @@ -181,7 +184,6 @@ PV_CRYPTO_ERROR_KEYGENERATION, PV_CRYPTO_ERROR_RANDOMIZATION, PV_CRYPTO_ERROR_READ_FILE, - PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, PV_CRYPTO_ERROR_NO_MATCH_TAG, } PvCryptoErrors; diff -Nru s390-tools-2.23.0/include/libpv/glib-helper.h s390-tools-2.25.0/include/libpv/glib-helper.h --- s390-tools-2.23.0/include/libpv/glib-helper.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/libpv/glib-helper.h 2022-12-08 13:40:15.000000000 +0100 @@ -102,9 +102,12 @@ /** pv_gbytes_memcpy: * - * memcpy with size check. + * memcpy with size check. In case @dst_size is smaller than the size of @src + * the error value %NULL is returned and @copied and @dst are left unchanged. + * + * If @dst and @src data overlap, the behavior is undefined. */ -void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src); +void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src, size_t *copied); #define PV_GLIB_HELPER_ERROR g_quark_from_static_string("pv-glib-helper_error-quark") typedef enum { diff -Nru s390-tools-2.23.0/include/libpv/macros.h s390-tools-2.25.0/include/libpv/macros.h --- s390-tools-2.23.0/include/libpv/macros.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/libpv/macros.h 2022-12-08 13:40:15.000000000 +0100 @@ -10,7 +10,12 @@ #ifndef LIBPV_MACROS_H #define LIBPV_MACROS_H +#include + #define PV_NONNULL(...) #define DO_PRAGMA(x) _Pragma(#x) +/* Most significant bit */ +#define PV_MSB(idx) ((uint64_t)1 << (63 - (idx))) + #endif /* LIBPV_MACROS_H */ diff -Nru s390-tools-2.23.0/include/libpv/se-hdr.h s390-tools-2.25.0/include/libpv/se-hdr.h --- s390-tools-2.23.0/include/libpv/se-hdr.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/include/libpv/se-hdr.h 2022-12-08 13:40:15.000000000 +0100 @@ -15,6 +15,7 @@ #include "boot/s390.h" #include "libpv/crypto.h" +#include "libpv/macros.h" /* Magic number which is used to identify the file containing the PV * header @@ -22,20 +23,17 @@ #define PV_MAGIC_NUMBER 0x49424d5365634578ULL #define PV_VERSION_1 0x00000100U -/* Internal helper macro */ -#define __PV_BIT(nr) (1ULL << (63 - (nr))) - /* Plaintext control flags */ /* dumping of the configuration is allowed */ -#define PV_PCF_ALLOW_DUMPING __PV_BIT(34) +#define PV_PCF_ALLOW_DUMPING PV_MSB(34) /* prevent Ultravisor decryption during unpack operation */ -#define PV_PCF_NO_DECRYPTION __PV_BIT(35) +#define PV_PCF_NO_DECRYPTION PV_MSB(35) /* PCKMO encrypt-DEA/TDEA-key functions allowed */ -#define PV_PCF_PCKMO_DEA_TDEA __PV_BIT(56) +#define PV_PCF_PCKMO_DEA_TDEA PV_MSB(56) /* PCKMO encrypt-AES-key functions allowed */ -#define PV_PCF_PCKMO_AES __PV_BIT(57) +#define PV_PCF_PCKMO_AES PV_MSB(57) /* PCKMO encrypt-ECC-key functions allowed */ -#define PV_PCF_PCKM_ECC __PV_BIT(58) +#define PV_PCF_PCKM_ECC PV_MSB(58) /* maxima for the PV version 1 */ #define PV_V1_IPIB_MAX_SIZE PAGE_SIZE diff -Nru s390-tools-2.23.0/ipl_tools/ipl_tools.h s390-tools-2.25.0/ipl_tools/ipl_tools.h --- s390-tools-2.23.0/ipl_tools/ipl_tools.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/ipl_tools/ipl_tools.h 2022-12-08 13:40:15.000000000 +0100 @@ -75,6 +75,7 @@ * NVME */ #define FID_MAX_LEN 11 /* 8 characters + 0x + null */ +#define NVME_DEV_MAX_LEN 15 /* "nvme" + u32 in decimal + null */ #define NVME_PATH_MAX (PATH_MAX + NAME_MAX + 1) extern void nvme_fid_get(const char *device, char *fid); diff -Nru s390-tools-2.23.0/ipl_tools/nvme.c s390-tools-2.25.0/ipl_tools/nvme.c --- s390-tools-2.23.0/ipl_tools/nvme.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/ipl_tools/nvme.c 2022-12-08 13:40:15.000000000 +0100 @@ -18,15 +18,31 @@ #include "lib/util_file.h" #include "ipl_tools.h" +static void nvme_dev_from_bdev(char *dev_name) +{ + char *delim = strrchr(dev_name, 'n'); + + if (delim) + *delim = 0; +} + /* * Return the fid of a device */ void nvme_fid_get(const char *device, char *fid) { char path[PATH_MAX], buf[FID_MAX_LEN]; + char nvme_dev[NVME_DEV_MAX_LEN]; + + /* + * An NVMe may present multiple namespaces and thus block devices, even + * before partitioning, so we need the nvme part of the block + * device name to get to the PCI function ID. + */ + util_strlcpy(nvme_dev, device, sizeof(nvme_dev)); + nvme_dev_from_bdev(nvme_dev); - snprintf(path, PATH_MAX, "/sys/block/%s/device/device/function_id", - device); + snprintf(path, PATH_MAX, "/sys/class/nvme/%s/device/function_id", nvme_dev); if (util_file_read_line(buf, FID_MAX_LEN, path)) ERR_EXIT_ERRNO("Could not read from \"%s\"", path); diff -Nru s390-tools-2.23.0/libap/ap.c s390-tools-2.25.0/libap/ap.c --- s390-tools-2.23.0/libap/ap.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libap/ap.c 2022-12-08 13:40:15.000000000 +0100 @@ -22,13 +22,10 @@ #include #endif /* HAVE_JSONC */ -#ifdef HAVE_LOCKFILE -#include -#endif /* HAVE_LOCKFILE */ - #include "lib/ap.h" #include "lib/util_file.h" #include "lib/util_libc.h" +#include "lib/util_lockfile.h" #include "lib/util_panic.h" #include "lib/util_path.h" #include "lib/util_udev.h" @@ -701,33 +698,28 @@ } } -#ifdef HAVE_LOCKFILE -static int ap_lockfile_create(int flags) -{ - return lockfile_create(AP_LOCKFILE, AP_LOCK_RETRIES, flags); -} - /** - * Acquire the ap config lock using this process PID (L_PID) + * Acquire the ap config lock using this Process ID + * + * @retval 0 Lock acquired on behalf of this process * - * @retval 0 Lock successfully acquired on behalf of L_PID * @retval != 0 Error, lock was not obtained */ int ap_get_lock(void) { - return ap_lockfile_create(L_PID); + return util_lockfile_lock(AP_LOCKFILE, AP_LOCK_RETRIES); } /** - * Acquire the ap config lock using the parent process PID (L_PPID) -- intended - * for use by the mdevctl callout ap-check utility + * Acquire the ap config lock using the Parent Process ID -- intended for use + * by the mdevctl callout ap-check utility * - * @retval 0 Lock successfully acquired on behalf of L_PPID + * @retval 0 Lock acquired on behalf of parent process * @retval != 0 Error, lock was not obtained */ int ap_get_lock_callout(void) { - return ap_lockfile_create(L_PPID); + return util_lockfile_parent_lock(AP_LOCKFILE, AP_LOCK_RETRIES); } /** @@ -738,23 +730,10 @@ */ int ap_release_lock(void) { - return lockfile_remove(AP_LOCKFILE); -} -#else -/* If no liblockfile, actions are performed without acquiring the file lock */ -int ap_get_lock(void) -{ - return 0; + return util_lockfile_release(AP_LOCKFILE); } -int ap_get_lock_callout(void) +int ap_release_lock_callout(void) { - return 0; + return util_lockfile_parent_release(AP_LOCKFILE); } - -int ap_release_lock(void) -{ - return 0; -} - -#endif /* HAVE_LOCKFILE */ diff -Nru s390-tools-2.23.0/libap/Makefile s390-tools-2.25.0/libap/Makefile --- s390-tools-2.23.0/libap/Makefile 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libap/Makefile 2022-12-08 13:40:15.000000000 +0100 @@ -2,17 +2,6 @@ lib = libap.a -check-dep-lock: - touch check-dep-lock -ifneq (${HAVE_LOCKFILE},0) - $(call check_dep, \ - "libap", \ - "lockfile.h", \ - "liblockfile-devel", \ - "HAVE_LOCKFILE=0") -ALL_CPPFLAGS += -DHAVE_LOCKFILE -endif - check-dep-json: touch check-dep-json ifneq (${HAVE_JSONC},0) @@ -29,7 +18,7 @@ $(lib): $(objects) -$(objects): check-dep-lock check-dep-json +$(objects): check-dep-json install: all diff -Nru s390-tools-2.23.0/libdasd/dasd_ioctl.c s390-tools-2.25.0/libdasd/dasd_ioctl.c --- s390-tools-2.23.0/libdasd/dasd_ioctl.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libdasd/dasd_ioctl.c 2022-12-08 13:40:15.000000000 +0100 @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include "lib/dasd_base.h" @@ -27,11 +29,13 @@ #define RUN_IOCTL(fd, req, argp) \ do { \ - if (ioctl(fd, req, argp) != 0) { \ - int err = errno; \ - if (err != EBADF) \ + int rc = ioctl(fd, req, argp); \ + if (rc != 0) { \ + if (rc == -1) \ + rc = errno; \ + if (rc != EBADF) \ dasd_close_device(fd); \ - return err; \ + return rc; \ } \ } while (0) @@ -320,4 +324,160 @@ dasd_close_device(fd); return 0; +} + +/* + * Unconditionally reserve DASD disk + * + * An existing reserve lock is lifted (steal lock) and the device + * is reserved. + * + * @param[in] device node device node's name + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_slock(const char *device) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDSLCK, NULL); + dasd_close_device(fd); + + return 0; +} + +/* + * Get the caching algorithm used for the channel programs of this device. + * + * @param[in] device node device node's name + * @param[out] attrib_data pointer to dasd attrib data with: + * 'cache' is the caching mode + * 'no_cyl' the number of cylinders to be cached. + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_get_cache(const char *device, attrib_data_t *attrib_data) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDGATTR, attrib_data); + dasd_close_device(fd); + + return 0; +} + +/* + * Set the caching algorithm used for the channel programs of this device. + * + * @param[in] device node device node's name + * @param[in] attrib_data pointer to dasd attrib data with: + * 'cache' is the caching mode + * 'no_cyl' the number of cylinders to be cached. + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_set_cache(const char *device, attrib_data_t *attrib_data) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDSATTR, attrib_data); + dasd_close_device(fd); + + return 0; +} + +/* + * Get reserve status of device. + * + * @param[in] device node device node's name + * + * @retval errno in case of failure + * @retval 0 unreserved + * @retval 1 implicit reserved + * @retval 2 other reservation + * @retval 3 reserved + */ +int dasd_query_reserve(const char *device) +{ + struct dasd_snid_ioctl_data snid = { 0 }; + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDSNID, &snid); + dasd_close_device(fd); + + return snid.data.path_state.reserve; +} + +/* + * Get and print the profiling info of the device. + * + * @param[in] device node device node's name + * @param[in] dasd_profile_info pointer to dasd profile info + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDPRRD, dasd_profile_info); + dasd_close_device(fd); + + return 0; +} + +/* + * Reset the profiling counters of the device. + * + * @param[in] device node device node's name + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_reset_profile(const char *device) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDPRRST, NULL); + dasd_close_device(fd); + + return 0; +} + +/* + * Initiate the swap of a copy pairs primary,secondary relation. + * The old secondary will become the new primary and vice versa. + * + * @param[in] device node device node's name + * @param[in] copy_pair data pointer to dasd copypair data with: + * 'primary' old primary, becoming secondary + * 'secondary' old secondary, becoming primary. + * + * @retval errno in case of failure + * @retval 0 in case of success + * @retval 1 swap data invalid + * @retval 2 no active device found + * @retval 3 wrong primary specified + * @retval 4 secondary device not found + * @retval 5 swap already running + */ +int dasd_copy_swap(const char *device, struct dasd_copypair_swap_data *data) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDPPRCSWAP, data); + dasd_close_device(fd); + + return 0; } diff -Nru s390-tools-2.23.0/libpv/cert.c s390-tools-2.25.0/libpv/cert.c --- s390-tools-2.23.0/libpv/cert.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libpv/cert.c 2022-12-08 13:40:15.000000000 +0100 @@ -290,7 +290,9 @@ long len; if (X509_NAME_print_ex(key_bio, name, 0, XN_FLAG_RFC2253) == -1) { - g_warning(_("Cannot receive X509-NAME from CRL: %s"), pv_get_openssl_error()); + g_autofree char *openssl_err_msg = pv_get_openssl_errors(); + + g_warning(_("Cannot receive X509-NAME from CRL: %s"), openssl_err_msg); return NULL; } @@ -790,7 +792,7 @@ return 0; error: - g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL, _("X509 store initialization failed")); return -1; } @@ -1375,14 +1377,14 @@ ca_x509_subject = X509_get_subject_name(ca); if (!ca_x509_subject) { - g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL, _("subject of the root CA cannot be retrieved")); return -1; } ca_subject = pv_X509_NAME_oneline(ca_x509_subject); if (!ca_subject) { - g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL, _("subject name of the root CA cannot be retrieved")); return -1; } @@ -1476,11 +1478,11 @@ ibm_signing_certs = pv_remove_ibm_signing_certs(certs); ibm_signing_certs_count = sk_X509_num(ibm_signing_certs); if (ibm_signing_certs_count < 1) { - g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_NO_IBM_Z_SIGNING_KEY, _("Specify at least one IBM Z signing key")); return NULL; } else if (ibm_signing_certs_count > 1) { - g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY, + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_NO_IBM_Z_SIGNING_KEY, _("Specify only one IBM Z signing key")); return NULL; } @@ -1511,7 +1513,7 @@ X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i); if (X509_STORE_add_crl(trusted, crl) != 1) { - g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + g_set_error(error, PV_CERT_ERROR, PV_CERT_ERROR_INTERNAL, _("failed to load CRL")); return FALSE; } diff -Nru s390-tools-2.23.0/libpv/crypto.c s390-tools-2.25.0/libpv/crypto.c --- s390-tools-2.23.0/libpv/crypto.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libpv/crypto.c 2022-12-08 13:40:15.000000000 +0100 @@ -19,18 +19,18 @@ #include "libpv/glib-helper.h" #include "libpv/hash.h" -const char *pv_get_openssl_error(void) +char *pv_get_openssl_errors(void) { - const char *ret; - BIO *bio; + char *ret; char *buf; + BIO *bio; long len; bio = BIO_new(BIO_s_mem()); ERR_print_errors(bio); len = BIO_get_mem_data(bio, &buf); - if (len < 0) - ret = "Cannot receive OpenSSL error message."; + if (len <= 0 || !buf) + ret = g_strdup("Cannot receive OpenSSL error message."); else ret = g_strndup(buf, (size_t)len); BIO_free(bio); @@ -276,7 +276,7 @@ } GBytes *pv_hkdf_extract_and_expand(size_t derived_key_len, GBytes *key, GBytes *salt, GBytes *info, - const EVP_MD *md, G_GNUC_UNUSED GError **error) + const EVP_MD *md, GError **error) { const unsigned char *salt_data, *key_data, *info_data; g_autoptr(EVP_PKEY_CTX) ctx = NULL; @@ -354,7 +354,6 @@ if (EVP_PKEY_derive(ctx, derived_key, &derived_key_len) != 1) { g_set_error(error, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_HKDF_FAIL, "FAILED to derive key via HKDF"); - printf("%s\n", pv_get_openssl_error()); return NULL; } diff -Nru s390-tools-2.23.0/libpv/glib-helper.c s390-tools-2.25.0/libpv/glib-helper.c --- s390-tools-2.23.0/libpv/glib-helper.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libpv/glib-helper.c 2022-12-08 13:40:15.000000000 +0100 @@ -168,12 +168,14 @@ return pv_sec_gbytes_new_take(g_steal_pointer(&data), data_size); } -void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src) +void *pv_gbytes_memcpy(void *dst, size_t dst_size, GBytes *src, size_t *copied) { size_t src_size; const void *src_data = g_bytes_get_data(src, &src_size); if (dst_size < src_size) return NULL; + if (copied) + *copied = src_size; return memcpy(dst, src_data, src_size); } diff -Nru s390-tools-2.23.0/libpv/hash.c s390-tools-2.25.0/libpv/hash.c --- s390-tools-2.23.0/libpv/hash.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libpv/hash.c 2022-12-08 13:40:15.000000000 +0100 @@ -97,8 +97,10 @@ key_data = g_bytes_get_data(key, &key_size); if (HMAC_Init_ex(ctx, key_data, (int)key_size, md, NULL) != 1) { + g_autofree char *openssl_err_msg = pv_get_openssl_errors(); + g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL, - "unable to create HMAC context: %s", pv_get_openssl_error()); + "unable to create HMAC context: %s", openssl_err_msg); return NULL; } return g_steal_pointer(&ctx); @@ -110,8 +112,10 @@ return 0; if (HMAC_Update(ctx, buf, size) != 1) { + g_autofree char *openssl_err_msg = pv_get_openssl_errors(); + g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL, - "unable to add data to HMAC context: %s", pv_get_openssl_error()); + "unable to add data to HMAC context: %s", openssl_err_msg); return -1; } return 0; @@ -139,8 +143,10 @@ hmac = g_malloc0((unsigned int)md_size); if (HMAC_Final(ctx, hmac, &hmac_size) != 1) { + g_autofree char *openssl_err_msg = pv_get_openssl_errors(); + g_set_error(error, PV_HASH_ERROR, PV_HASH_ERROR_INTERNAL, - "unable to calculate HMAC: %s", pv_get_openssl_error()); + "unable to calculate HMAC: %s", openssl_err_msg); return NULL; } return g_bytes_new_take(g_steal_pointer(&hmac), hmac_size); diff -Nru s390-tools-2.23.0/libutil/util_arch.c s390-tools-2.25.0/libutil/util_arch.c --- s390-tools-2.23.0/libutil/util_arch.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libutil/util_arch.c 2022-12-08 13:40:15.000000000 +0100 @@ -107,13 +107,12 @@ */ unsigned long util_arch_hsa_maxsize(void) { - unsigned long size = HSA_SIZE_32M; - int type; - - type = util_arch_machine_type(); - if (type != UTIL_ARCH_MACHINE_TYPE_UNKNOWN && - type >= UTIL_ARCH_MACHINE_TYPE_Z15) - size = HSA_SIZE_512M; - - return size; + switch (util_arch_machine_type()) { + case UTIL_ARCH_MACHINE_TYPE_Z15: + case UTIL_ARCH_MACHINE_TYPE_Z15_T02: + case UTIL_ARCH_MACHINE_TYPE_Z16: + return HSA_SIZE_512M; + default: + return HSA_SIZE_32M; + } } diff -Nru s390-tools-2.23.0/libutil/util_lockfile.c s390-tools-2.25.0/libutil/util_lockfile.c --- s390-tools-2.23.0/libutil/util_lockfile.c 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/libutil/util_lockfile.c 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,301 @@ +/* + * util - Utility function library + * + * Created file-based locks + * + * Copyright IBM Corp. 2022 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib/util_libc.h" +#include "lib/util_lockfile.h" +#include "lib/util_panic.h" + +#define WAITPID 120 /* Time to wait for pid to be written */ +#define WAITINC 5 /* Additional time to wait each retry */ +#define MAXWAIT 60 /* Maximum wait between retries */ +#define BUFSIZE 40 /* Buffer must be large enough to fit pid string */ + +/** + * Check if there is a process that exists with the specified identifier. + * + * @param[in] pid Process Identifier to check + * + * @retval true Process exists or we lack privelege to check + * @retval false Process does not exist + */ +static bool pid_exists(int pid) +{ + int rc; + + /* Use sig 0 to determine if the owner is still alive */ + rc = kill(pid, 0); + if (rc != 0) { + switch (errno) { + case EPERM: + /* Privilege issue, just assume PID exists */ + break; + case ESRCH: + /* PID does not exist, this lock is stale */ + return false; + default: + util_assert(false, "Unexpected return from kill: %d\n", rc); + break; + } + } + + return true; +} + +/** + * Check for an existing lock that is deemed stale (either the associated PID + * is gone or no PID has been written to the file in a reasonable timeframe). + * In the case a stale lock is found, remove it. + * + * @param[in] lockfile Path to the lock file + * + * @retval 0 Either no lock or stale lock was found and removed + * @retval 1 Lock is held by another PID and is not stale + */ +static int handle_stale_lock(char *lockfile) +{ + int fd, rc, pid, len; + struct stat info; + char buf[BUFSIZE]; + time_t curr; + + fd = open(lockfile, O_RDONLY); + + if (fd >= 0) { + /* Lock exists, see who owns it */ + len = read(fd, buf, sizeof(buf)); + if (len > 0) { + buf[len] = 0; /* Ensure null terminated string */ + pid = atoi(buf); + if (!pid_exists(pid)) { + /* Stale lock detected unlink and retry now */ + close(fd); + unlink(lockfile); + return 0; + } else if (pid != 0) { + /* Lock is held by an active pid, delay */ + close(fd); + return 1; + } + /* + * If we reach this point, the PID was 0 which is + * unexpected. Proceed under the assumption that the + * proper PID hasn't been written yet. + */ + } + /* + * PID hasn't been written yet? Either a bad lock or a very + * new one. + */ + time(&curr); + rc = fstat(fd, &info); + close(fd); + if (rc != 0) { + /* Can't read file anymore, retry now */ + return 0; + } + if (curr > info.st_mtime + WAITPID) { + /* + * PID should be in the file within 2 minutes, + * something went wrong. Treat as stale. + */ + unlink(lockfile); + return 0; + } + /* Otherwise, assume file was newly created and delay */ + return 1; + } + + /* Couldn't open, try again immediately */ + return 0; +} + +/** + * Attempt to create a lockfile at the specified path. + * + * @param[in] lockfile Path to the lock file + * @param[in] retries Number of times to retry if lock fails initially + * @param[in] pid PID to use for lock ownership + * + * @retval 0 Lock created with PID as owner + * @retval !=0 Lock was not created + */ +static int do_lockfile_lock(char *lockfile, unsigned int retries, int pid) +{ + int fd, plen, len, rc = 0, snooze = 0; + unsigned int tries = retries + 1; + char buf[BUFSIZE]; + char *tpath; + + if (!lockfile) + return UTIL_LOCKFILE_ERR; + + plen = snprintf(buf, sizeof(buf), "%d\n", pid); + if (plen < 0 || (plen > ((int)sizeof(buf) - 1))) + return UTIL_LOCKFILE_ERR; + + /* Allocate temporary lock file with a sufficiently unique path */ + len = util_asprintf(&tpath, "%s%05d%02x", lockfile, getpid(), + (unsigned int)time(NULL) & 255); + if (len < 0) + return UTIL_LOCKFILE_ERR; + + /* Open the temporary lockfile, write the specified pid */ + fd = open(tpath, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0644); + if (fd < 0) { + rc = UTIL_LOCKFILE_ERR; + goto out; + } + + len = write(fd, buf, plen); + if (close(fd) != 0) { + rc = UTIL_LOCKFILE_ERR; + goto cleanup; + } + if (len != plen) { + /* Failed to write the temp lockfile, bail out */ + rc = UTIL_LOCKFILE_ERR; + goto cleanup; + } + + /* Link the temprorary file to the real path */ + do { + rc = link(tpath, lockfile); + if (rc == 0) { + /* Lock successfully acquired */ + rc = UTIL_LOCKFILE_OK; + goto cleanup; + } + /* Lock already held - check for stale lock */ + rc = handle_stale_lock(lockfile); + /* Only wait if the lock was not stale */ + if (rc != 0) { + tries--; + if (tries > 0) { + snooze += WAITINC; + snooze = (snooze > MAXWAIT) ? MAXWAIT : snooze; + sleep(snooze); + } + } + } while (tries > 0); + + /* Exhausted specified number of retries, exit on failure */ + rc = UTIL_LOCKFILE_LOCK_FAIL; + +cleanup: + unlink(tpath); + free(tpath); +out: + return rc; +} + +/** + * Attempt to release a lockfile at the specified path. + * + * @param[in] lockfile Path to the lock file + * @param[in] pid PID that should own the lock + * + * @retval 0 Lock released + * @retval !=0 Lock was not released or did not exist + */ +static int do_lockfile_release(char *lockfile, int pid) +{ + int fd, len, lpid; + char buf[BUFSIZE]; + + if (!lockfile) + return UTIL_LOCKFILE_ERR; + + /* Open lockfile, read the owning pid if it exists */ + fd = open(lockfile, O_RDONLY); + if (fd < 0) + return UTIL_LOCKFILE_RELEASE_NONE; + len = read(fd, buf, sizeof(buf)); + close(fd); + if (len <= 0) + return UTIL_LOCKFILE_RELEASE_FAIL; + buf[len] = 0; + lpid = atoi(buf); + + /* Only release the lock if its held by the right pid */ + if (pid != lpid) + return UTIL_LOCKFILE_RELEASE_FAIL; + + unlink(lockfile); + + return 0; +} + +/** + * Attempt to create a lockfile owned by this process at the specified path. + * + * @param[in] lockfile Path to the lock file + * @param[in] retries Number of times to retry if lock fails initially + * + * @retval 0 Lock created + * @retval !=0 Lock was not created + */ +int util_lockfile_lock(char *lockfile, int retries) +{ + return do_lockfile_lock(lockfile, retries, getpid()); +} + +/** + * Attempt to create a lockfile owned by the parent of this process at the + * specified path. + * + * @param[in] lockfile Path to the lock file + * @param[in] retries Number of times to retry if lock fails initially + * + * @retval 0 Lock created + * @retval !=0 Lock was not created + */ +int util_lockfile_parent_lock(char *lockfile, int retries) +{ + return do_lockfile_lock(lockfile, retries, getppid()); +} + +/** + * Attempt to release a lockfile owned by this process at the specified path. + * + * @param[in] lockfile Path to the lock file + * + * @retval 0 Lock released + * @retval !=0 Lock was not released or did not exist + */ +int util_lockfile_release(char *lockfile) +{ + return do_lockfile_release(lockfile, getpid()); +} + +/** + * Attempt to release a lockfile owned by the parent of this process at the + * specified path. + * + * @param[in] lockfile Path to the lock file + * + * @retval 0 Lock released + * @retval !=0 Lock was not released or did not exist + */ +int util_lockfile_parent_release(char *lockfile) +{ + return do_lockfile_release(lockfile, getppid()); +} diff -Nru s390-tools-2.23.0/libutil/util_lockfile_example.c s390-tools-2.25.0/libutil/util_lockfile_example.c --- s390-tools-2.23.0/libutil/util_lockfile_example.c 1970-01-01 01:00:00.000000000 +0100 +++ s390-tools-2.25.0/libutil/util_lockfile_example.c 2022-12-08 13:40:15.000000000 +0100 @@ -0,0 +1,232 @@ +/** + * util_lockfile_example - Example program for util_lockfile + * + * Copyright IBM Corp. 2022 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +//! [code] +#include +#include +#include "lib/util_opt.h" +#include "lib/util_prg.h" +#include "lib/util_lockfile.h" + +static const struct util_prg prg = { + .desc = "Example for util_lockfile.", + .copyright_vec = { { + .owner = "IBM Corp.", + .pub_first = 2022, + .pub_last = 2022, + }, + UTIL_PRG_COPYRIGHT_END } +}; + +static struct util_opt opt_vec[] = { + UTIL_OPT_SECTION("OPTIONS"), + { + .option = { "file", required_argument, NULL, 'f' }, + .argument = "PATH", + .desc = "Use the specified path for a lockfile.", + }, + { + .option = { "lock", required_argument, NULL, 'l' }, + .argument = "RETRIES", + .desc = "Acquire the specified file lock using the parent " + "process id of this process. If not immediately " + "successful, retry for the specified number of times", + }, + { + .option = { "release", 0, NULL, 'r' }, + .desc = "Release the specified lock file using the parent " + "process id", + }, + { + .option = { "lock-and-release", required_argument, NULL, 'L' }, + .argument = "RETRIES", + .desc = "Acquire the specified file lock using this process " + "id, then release it. If not immediately successful, " + "retry for the specified number of times.", + }, + UTIL_OPT_HELP, + UTIL_OPT_VERSION, + UTIL_OPT_END +}; + +enum prg_action { + ACTION_NONE = 0, + ACTION_LOCK, + ACTION_RELEASE, + ACTION_LOCK_AND_RELEASE, +}; + +static void print_single_action_error(void) +{ + warnx("Only a single action (--lock, --lock-parent, --release, " + "--release-parent) is allowed"); +} + +int main(int argc, char *argv[]) +{ + enum prg_action action_id = ACTION_NONE; + int opt, rc, retries = 0; + char *endp, *path = NULL; + + util_prg_init(&prg); + util_opt_init(opt_vec, NULL); + + while (1) { + opt = util_opt_getopt_long(argc, argv); + if (opt == -1) + break; + switch (opt) { + case 'f': + path = optarg; + break; + case 'L': + if (action_id != ACTION_NONE) { + print_single_action_error(); + return EXIT_FAILURE; + } + retries = strtol(optarg, &endp, 0); + if (*optarg == '\0' || *endp != '\0' || retries < 0) { + warnx("Invalid retry value for " + "--lock-and-release: '%s'", + optarg); + util_prg_print_parse_error(); + return EXIT_FAILURE; + } + action_id = ACTION_LOCK_AND_RELEASE; + break; + case 'l': + if (action_id != ACTION_NONE) { + print_single_action_error(); + return EXIT_FAILURE; + } + retries = strtol(optarg, &endp, 0); + if (*optarg == '\0' || *endp != '\0' || retries < 0) { + warnx("Invalid retry value for " + "--parent-lock: '%s'", + optarg); + util_prg_print_parse_error(); + return EXIT_FAILURE; + } + action_id = ACTION_LOCK; + break; + case 'r': + if (action_id != ACTION_NONE) { + print_single_action_error(); + return EXIT_FAILURE; + } + action_id = ACTION_RELEASE; + break; + case 'h': + util_prg_print_help(); + util_opt_print_help(); + exit(EXIT_SUCCESS); + case 'v': + util_prg_print_version(); + exit(EXIT_SUCCESS); + default: + util_opt_print_parse_error(opt, argv); + return EXIT_FAILURE; + } + } + + if (!path) { + warnx("--file is required, see --help for more information"); + return EXIT_FAILURE; + } + + if (action_id == ACTION_NONE) { + warnx("One of the following actions must be specified: " + "--lock, --release, --lock-and-release"); + return EXIT_FAILURE; + } + + /* Determine which util_lockfile function to call */ + switch (action_id) { + case ACTION_LOCK: + rc = util_lockfile_parent_lock(path, retries); + switch (rc) { + case UTIL_LOCKFILE_OK: + printf("lock acquired successfully\n"); + break; + case UTIL_LOCKFILE_LOCK_FAIL: + warnx("lock was not acquired; already held"); + return EXIT_FAILURE; + case UTIL_LOCKFILE_ERR: + warnx("lock was not acquired; file error"); + return EXIT_FAILURE; + default: + warnx("Unknown util_lockfile rc %d", rc); + return EXIT_FAILURE; + } + break; + case ACTION_RELEASE: + rc = util_lockfile_parent_release(path); + switch (rc) { + case UTIL_LOCKFILE_OK: + printf("lock released successfully\n"); + break; + case UTIL_LOCKFILE_RELEASE_NONE: + warnx("lock file did not exist"); + return EXIT_FAILURE; + case UTIL_LOCKFILE_RELEASE_FAIL: + warnx("lock was not held by the specified pid"); + return EXIT_FAILURE; + case UTIL_LOCKFILE_ERR: + warnx("lock was not released; file error"); + return EXIT_FAILURE; + default: + warnx("Unknown util_lockfile rc %d", rc); + return EXIT_FAILURE; + } + break; + case ACTION_LOCK_AND_RELEASE: + rc = util_lockfile_lock(path, retries); + switch (rc) { + case UTIL_LOCKFILE_OK: + printf("lock acquired successfully, holding for 2 seconds\n"); + break; + case UTIL_LOCKFILE_LOCK_FAIL: + warnx("lock was not acquired; already held"); + return EXIT_FAILURE; + case UTIL_LOCKFILE_ERR: + warnx("lock was not acquired; file error"); + return EXIT_FAILURE; + default: + warnx("Unknown util_lockfile rc %d", rc); + return EXIT_FAILURE; + } + /* Briefly sleep while holding the lock */ + sleep(2); + rc = util_lockfile_release(path); + switch (rc) { + case UTIL_LOCKFILE_OK: + printf("lock released successfully\n"); + break; + case UTIL_LOCKFILE_RELEASE_NONE: + warnx("lock file did not exist"); + return EXIT_FAILURE; + case UTIL_LOCKFILE_RELEASE_FAIL: + warnx("lock was not held by the specified pid"); + return EXIT_FAILURE; + case UTIL_LOCKFILE_ERR: + warnx("lock was not released; file error"); + return EXIT_FAILURE; + default: + warnx("Unknown util_lockfile rc %d", rc); + return EXIT_FAILURE; + } + break; + default: + warnx("Unknown util_lockfile action"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} +//! [code] diff -Nru s390-tools-2.23.0/libzds/libzds.c s390-tools-2.25.0/libzds/libzds.c --- s390-tools-2.23.0/libzds/libzds.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/libzds/libzds.c 2022-12-08 13:40:15.000000000 +0100 @@ -1419,7 +1419,6 @@ volume_label_t *vlabel = NULL; char *trackdata = NULL; - char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00}; /* "VOL1" in EBCDIC */ errorlog_clear(dasd->log); @@ -1431,8 +1430,7 @@ goto cleanup; } /* verify that we have a proper VOL1 label */ - if (strncmp(vlabel->volkey, vol1, 4) || - strncmp(vlabel->vollbl, vol1, 4)) { + if (!is_vol1(vlabel->volkey) || !is_vol1(vlabel->vollbl)) { rc = EINVAL; errorlog_add_message( &dasd->log, NULL, rc, diff -Nru s390-tools-2.23.0/mon_tools/Makefile s390-tools-2.25.0/mon_tools/Makefile --- s390-tools-2.23.0/mon_tools/Makefile 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/mon_tools/Makefile 2022-12-08 13:40:15.000000000 +0100 @@ -1,5 +1,7 @@ include ../common.mak +ALL_CFLAGS += -Wno-address-of-packed-member + all: mon_fsstatd mon_procd mon_fsstatd: mon_fsstatd.o diff -Nru s390-tools-2.23.0/pvattest/man/pvattest-create.1 s390-tools-2.25.0/pvattest/man/pvattest-create.1 --- s390-tools-2.23.0/pvattest/man/pvattest-create.1 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/man/pvattest-create.1 2022-12-08 13:40:15.000000000 +0100 @@ -24,7 +24,7 @@ .B \fB-k\fP, \fB--host-key-document\fP=\fBFILE\fP Specify one or more host key documents. At least one is required. -Specify this option multiple times to enable the image to run on more than one host. +Specify this option multiple times to create an attestation request control block that is usable on multiple hosts. .TP .B \fB-C\fP, \fB--cert\fP=\fBFILE\fP diff -Nru s390-tools-2.23.0/pvattest/src/arcb.c s390-tools-2.25.0/pvattest/src/arcb.c --- s390-tools-2.23.0/pvattest/src/arcb.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/src/arcb.c 2022-12-08 13:40:15.000000000 +0100 @@ -171,9 +171,9 @@ g_assert(g_bytes_get_size(phkh) == sizeof(key_slot->phkh)); key_slot = g_malloc0(sizeof(*key_slot)); - pv_gbytes_memcpy(key_slot->warpk, sizeof(key_slot->warpk), warpk); - pv_gbytes_memcpy(key_slot->kst, sizeof(key_slot->warpk), tag); - pv_gbytes_memcpy(key_slot->phkh, sizeof(key_slot->warpk), phkh); + pv_gbytes_memcpy(key_slot->warpk, sizeof(key_slot->warpk), warpk, NULL); + pv_gbytes_memcpy(key_slot->kst, sizeof(key_slot->warpk), tag, NULL); + pv_gbytes_memcpy(key_slot->phkh, sizeof(key_slot->warpk), phkh, NULL); arcb->host_key_slots = g_slist_prepend(arcb->host_key_slots, g_steal_pointer(&key_slot)); return 0; @@ -246,7 +246,7 @@ /* copy plain data to contiguous memory */ hdr.arl = GUINT32_TO_BE((uint32_t)att_req_len); - pv_gbytes_memcpy(hdr.iv, ARCB_V1_IV_SIZE, arcb->iv); + pv_gbytes_memcpy(hdr.iv, ARCB_V1_IV_SIZE, arcb->iv, NULL); hdr.nks = (uint8_t)nks; hdr.sea = GUINT32_TO_BE((uint32_t)sea); ecdh_cpk = pv_evp_pkey_to_ecdh_pub_key(arcb->evp_cust_pub_key, error); diff -Nru s390-tools-2.23.0/pvattest/src/arcb.h s390-tools-2.25.0/pvattest/src/arcb.h --- s390-tools-2.23.0/pvattest/src/arcb.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/src/arcb.h 2022-12-08 13:40:15.000000000 +0100 @@ -15,6 +15,7 @@ #include "lib/zt_common.h" #include "libpv/crypto.h" +#include "libpv/macros.h" #include "types.h" @@ -28,18 +29,17 @@ #define ARCB_V1_IV_SIZE 12 #define ARCB_V1_PHKH_SIZE 32 -#define BIT(bit) ((uint64_t)1 << (63 - (bit))) /* Optional nonce in ARCB */ -#define ARCB_V1_PAF_NONCE BIT(1) +#define ARCB_V1_PAF_NONCE PV_MSB(1) /* Public host key hash used to unseal SE header added to additional data to be measured */ -#define ARCB_V1_PAF_AAD_PHKH_HEADER BIT(2) +#define ARCB_V1_PAF_AAD_PHKH_HEADER PV_MSB(2) /* Public host key hash used to unseal this attestation added to additional data to be measured */ -#define ARCB_V1_PAF_AAD_PHKH_ATTEST BIT(3) +#define ARCB_V1_PAF_AAD_PHKH_ATTEST PV_MSB(3) /* Temporary backup-host-key use allowed */ -#define ARCB_V1_PAF_TMP_BACKUP_ALLOWED BIT(62) +#define ARCB_V1_PAF_TMP_BACKUP_ALLOWED PV_MSB(62) /* Global not-host-specific key allowed */ -#define ARCB_V1_PAF_GLOBAL_NHS_KEY_ALLOWED BIT(63) +#define ARCB_V1_PAF_GLOBAL_NHS_KEY_ALLOWED PV_MSB(63) #define ARCB_V1_PAF_ALL \ (ARCB_V1_PAF_NONCE | ARCB_V1_PAF_AAD_PHKH_HEADER | ARCB_V1_PAF_AAD_PHKH_ATTEST | \ diff -Nru s390-tools-2.23.0/pvattest/src/attestation.c s390-tools-2.25.0/pvattest/src/attestation.c --- s390-tools-2.23.0/pvattest/src/attestation.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/src/attestation.c 2022-12-08 13:40:15.000000000 +0100 @@ -130,7 +130,7 @@ pv_wrapped_g_assert(config_uid); g_assert(g_bytes_get_size(config_uid) == ATT_CONFIG_UID_SIZE); - pv_gbytes_memcpy(meas_ctx->config_uid, ATT_CONFIG_UID_SIZE, config_uid); + pv_gbytes_memcpy(meas_ctx->config_uid, ATT_CONFIG_UID_SIZE, config_uid, NULL); } gboolean att_verify_measurement(const GBytes *calculated_measurement, diff -Nru s390-tools-2.23.0/pvattest/src/common.h s390-tools-2.25.0/pvattest/src/common.h --- s390-tools-2.23.0/pvattest/src/common.h 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/src/common.h 2022-12-08 13:40:15.000000000 +0100 @@ -11,7 +11,7 @@ /* Must be included before any other header */ #include "config.h" -#include +#include #include #include "libpv/glib-helper.h" diff -Nru s390-tools-2.23.0/pvattest/src/exchange_format.c s390-tools-2.25.0/pvattest/src/exchange_format.c --- s390-tools-2.23.0/pvattest/src/exchange_format.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/src/exchange_format.c 2022-12-08 13:40:15.000000000 +0100 @@ -191,7 +191,7 @@ } ctx->req_meas_size = GUINT32_FROM_BE(hdr_v1->measurement.size); ctx->req_add_size = GUINT32_FROM_BE(hdr_v1->additional_data.size); - ctx->version = GUINT32_TO_BE(hdr->version); + ctx->version = GUINT32_FROM_BE(hdr->version); return g_steal_pointer(&ctx); } diff -Nru s390-tools-2.23.0/pvattest/src/uvio.c s390-tools-2.25.0/pvattest/src/uvio.c --- s390-tools-2.23.0/pvattest/src/uvio.c 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/src/uvio.c 2022-12-08 13:40:15.000000000 +0100 @@ -9,6 +9,7 @@ */ /* Must be included before any other header */ #include "config.h" +#include "lib/zt_common.h" #ifdef PVATTEST_COMPILE_PERFORM #include @@ -42,26 +43,29 @@ uvio_attest = g_malloc0(sizeof(*uvio_attest)); uvio_attest->arcb_addr = PTR_TO_U64(g_steal_pointer(&arcb)); g_assert_cmpuint(arcb_size, <, UINT32_MAX); - uvio_attest->arcb_len = GUINT32_TO_BE((uint32_t)arcb_size); + uvio_attest->arcb_len = (uint32_t)arcb_size; /* transferred the local ownership of the arcb from this function to uvio_attest; nullify pointer */ g_steal_pointer(&serialized_arcb); if (user_data) { - if (g_bytes_get_size(user_data) > sizeof(uvio_attest->user_data)) { + size_t copied_data_size; + + if (pv_gbytes_memcpy(uvio_attest->user_data, sizeof(uvio_attest->user_data), + user_data, &copied_data_size) == NULL) { g_set_error(error, ATT_ERROR, ATT_ERR_INVALID_USER_DATA, - _("User data larger than %li bytes"), - sizeof(uvio_attest->user_data)); + _("User data %li bytes is larger than %li bytes"), + g_bytes_get_size(user_data), sizeof(uvio_attest->user_data)); return NULL; } - uvio_attest->user_data_len = GUINT16_TO_BE((uint16_t)g_bytes_get_size(user_data)); - pv_gbytes_memcpy(uvio_attest->user_data, uvio_attest->user_data_len, user_data); + STATIC_ASSERT(sizeof(uvio_attest->user_data) <= UINT16_MAX); + uvio_attest->user_data_len = (uint16_t)copied_data_size; } - uvio_attest->meas_len = GUINT32_TO_BE(measurement_size); - uvio_attest->meas_addr = PTR_TO_U64(g_malloc0(uvio_attest->meas_len)); + uvio_attest->meas_addr = PTR_TO_U64(g_malloc0(measurement_size)); + uvio_attest->meas_len = measurement_size; - uvio_attest->add_data_len = GUINT32_TO_BE(add_data_size); - uvio_attest->add_data_addr = PTR_TO_U64(g_malloc0(uvio_attest->add_data_len)); + uvio_attest->add_data_addr = PTR_TO_U64(g_malloc0(add_data_size)); + uvio_attest->add_data_len = add_data_size; return g_steal_pointer(&uvio_attest); } @@ -83,7 +87,7 @@ if (attest->meas_addr == (__u64)0) return NULL; - return g_bytes_new(U64_TO_PTR(attest->meas_addr), GUINT32_FROM_BE(attest->meas_len)); + return g_bytes_new(U64_TO_PTR(attest->meas_addr), attest->meas_len); } GBytes *uvio_get_additional_data(const uvio_attest_t *attest) @@ -92,8 +96,7 @@ if (attest->add_data_addr == (__u64)0) return NULL; - return g_bytes_new(U64_TO_PTR(attest->add_data_addr), - GUINT32_FROM_BE(attest->add_data_len)); + return g_bytes_new(U64_TO_PTR(attest->add_data_addr), attest->add_data_len); } GBytes *uvio_get_config_uid(const uvio_attest_t *attest) @@ -127,7 +130,7 @@ g_set_error(error, UVIO_ERROR, UVIO_ERR_UV_NOT_OK, _("Ultravisor call returned '%#x' (%s)"), uv_ioctl->uv_rc, uvio_uv_rc_to_str(uv_ioctl->uv_rc)); - return GUINT16_FROM_BE(uv_ioctl->uv_rc); + return uv_ioctl->uv_rc; } uint16_t uvio_ioctl_attest(const int uv_fd, uvio_attest_t *attest, GError **error) diff -Nru s390-tools-2.23.0/pvattest/tools/pvattest-info s390-tools-2.25.0/pvattest/tools/pvattest-info --- s390-tools-2.23.0/pvattest/tools/pvattest-info 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/tools/pvattest-info 2022-12-08 13:40:15.000000000 +0100 @@ -14,6 +14,8 @@ set -o nounset set -e +XDUMP='od -A x -t x2z -v' + usage() { cat <<-EOF Usage: $(basename "$0") FILE @@ -33,16 +35,16 @@ exit 1 fi - xxd -l 16 "${input}" | grep -q pvattest || + ${XDUMP} --read-bytes 16 -- "${input}" 2>/dev/null | grep -q pvattest || { echo "ERROR: ${input} does not contain a pvattest binary output." >&2 && exit 1; } - size=$(xxd -s 12 -l 4 "${input}" | awk 'NR==1 {print "0x" $2 $3}') + size=$(${XDUMP} --skip-bytes 12 --read-bytes 4 -- "${input}" 2>/dev/null | awk 'NR==1 {print "0x" $2 $3}') if [ $((size)) -lt 64 ]; then echo "ERROR: ${input} does not contain a pvattest binary output." >&2 exit 1 fi - version=$(xxd -s 8 -l 4 "$input") + version=$(${XDUMP} --skip-bytes 8 --read-bytes 4 -- "$input" 2>/dev/null) echo "$version" | grep -q "0000 0100" || { echo -n "WARNING: unknown hdr version " >&2 && echo "$version" | awk '{print "0x" $2 $3}'>&2 ; } @@ -55,24 +57,28 @@ local size local off - size=$(xxd -s $((file_off)) -l 4 "${input}" | awk 'NR==1 {print "0x" $2 $3}') - off=$(xxd -s $((file_off + 4)) -l 4 "${input}" | awk 'NR==1 {print "0x" $2 $3}') + size=$(${XDUMP} --skip-bytes $((file_off)) --read-bytes 4 -- "${input}" 2>/dev/null | + awk 'NR==1 {print "0x" $2 $3}') + off=$(${XDUMP} --skip-bytes $((file_off + 4)) --read-bytes 4 -- "${input}" 2>/dev/null | + awk 'NR==1 {print "0x" $2 $3}') if [[ $size != "0x00000000" ]] || [[ $off != "0x00000000" ]]; then echo "${text}:" - xxd -s $((off)) -l $((size)) -p "${input}" + od -A n -w$((size)) -t x8 --skip-bytes $((off)) --read-bytes $((size)) -- "${input}" 2>/dev/null |\ + sed -e 's/\s//g' fi } function require_command() { local cmd="$1" - command -v "$cmd" >/dev/null 2>&1 || { echo >&2 "ERROR: $cmd required but not installed."; exit 1; } + command -v "$cmd" >/dev/null 2>&1 || \ + { echo >&2 "ERROR: $cmd required but not installed."; exit 1; } } -require_command xxd require_command awk require_command wc +require_command od if [ $# -eq 0 ]; then echo "ERROR: Input not set. Use '$(basename "$0") [FILE]' to specify the Input file" >&2 diff -Nru s390-tools-2.23.0/pvattest/tools/pvextract-hdr s390-tools-2.25.0/pvattest/tools/pvextract-hdr --- s390-tools-2.23.0/pvattest/tools/pvextract-hdr 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/pvattest/tools/pvextract-hdr 2022-12-08 13:40:15.000000000 +0100 @@ -14,7 +14,9 @@ set -o nounset set -e -def_output="sehdr.bin" +XDUMP='od -A x -t x2z -v' + +def_output='sehdr.bin' def_skip=0x14 def_len=0x4 @@ -37,11 +39,22 @@ function check_hdr_ver() { local hdr_start="$1" local input="$2" - xxd -s $((hdr_start + 8)) -l 4 "$input" | grep -q "000 0100" || + ${XDUMP} --skip-bytes $((hdr_start + 8)) --read-bytes 4 -- "$input" 2>/dev/null | grep -q "000 0100" || { echo -n "WARNING: unknown hdr version " && - xxd -s $((hdr_start + 8)) -l 4 "$input" | awk '{print "0x" $2 $3}'; } + ${XDUMP} --skip-bytes $((hdr_start + 8)) --read_bytes 4 -- "$input" 2>/dev/null | awk '{print "0x" $2 $3}'; } } +function require_command() { + local cmd="$1" + + command -v "$cmd" >/dev/null 2>&1 || \ + { echo >&2 "ERROR: $cmd required but not installed."; exit 1; } +} + +require_command od +require_command awk +require_command grep + output=${def_output} parsed_skip=${def_skip} parsed_len=${def_len} @@ -77,13 +90,15 @@ fi check_file "$input" -hdr_start=$(xxd -s $((skip)) -l $((len)) "${input}" | grep IBMSecEx || { echo ERROR: "${input} does not contain an SE header." >&2 && exit 1; }) +hdr_start=$(${XDUMP} --skip-bytes $((skip)) --read-bytes $((len)) -- "${input}" 2>/dev/null | grep IBMSecEx || + { echo ERROR: "${input} does not contain an SE header." >&2 && exit 1; }) hdr_start=$(echo "${hdr_start}" | awk '{print "0x" $1}' | cut -c 1-10) echo "SE header found at offset ${hdr_start}" check_hdr_ver "$hdr_start" "$input" -size=$(xxd -s $((hdr_start + 12)) -l 4 "${input}" | awk 'NR==1 {print "0x" $2 $3}') +size=$(${XDUMP} --skip-bytes $((hdr_start + 12)) --read-bytes 4 -- "${input}" 2>/dev/null | + awk 'NR==1 {print "0x" $2 $3}') dd if="${input}" of="${output}" bs=1 count=$((size)) skip=$((hdr_start)) status=none echo "SE header written to '${output}' ($((size)) bytes)" diff -Nru s390-tools-2.23.0/README.md s390-tools-2.25.0/README.md --- s390-tools-2.23.0/README.md 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/README.md 2022-12-08 13:40:15.000000000 +0100 @@ -60,6 +60,7 @@ * zgetdump: Retrieve system dumps from either tapes, DASDs, SCSIs or NVMes. + Decrypt Protected Virtualization (PV) dumps from IBM Secure Execution guests. * qetharp: Read and flush the ARP cache on OSA Express network cards. @@ -309,16 +310,15 @@ | net-snmp | `HAVE_SNMP` | osasnmpd | | glibc-static | `HAVE_LIBC_STATIC` | zfcpdump | | openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb, | -| | | libkmipclient, pvattest | +| | | libkmipclient, pvattest, zgetdump | | cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup | | json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb, | | | | libkmipclient | -| glib2 | `HAVE_GLIB2` | genprotimg, pvattest | +| glib2 | `HAVE_GLIB2` | genprotimg, pvattest, zgetdump | | libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb, libkmipclient,| | | | pvattest | | libxml2 | `HAVE_LIBXML2` | libkmipclient | | systemd | `HAVE_SYSTEMD` | hsavmcore | -| liblockfile | `HAVE_LOCKFILE` | ap-check | | libudev | `HAVE_LIBUDEV` | cpacfstatsd | This table lists additional build or install options: @@ -376,6 +376,13 @@ - Packages: blktrace, multipath-tools, sg3-utils - Tools: rsync, tar, lsscsi +* zgetdump + For building zgetdump you need OpenSSL version 1.1.0 or newer + installed (openssl-devel.rpm). Also required is glib2 + (glib2-devel.rpm) and zlib (zlib-devel.rpm). + Tip: you may skip the zgetdump build by adding + `HAVE_OPENSSL=0`, `HAVE_GLIB2=0`, or `HAVE_ZLIB=0`. + * cmsfs-fuse/zdsfs/hmcdrvfs/zgetdump: The tools cmsfs-fuse, zdsfs, hmcdrvfs, and zgetdump depend on FUSE. FUSE is provided by installing the fuse3 and libfuse3 packages and by a @@ -505,8 +512,7 @@ GNU awk for the build process. * ap-check: - For building the ap-check mdevctl callout utility you need liblockfile - version 1.14 or newer installed (liblockfile-devel.rpm). Also required is - json-c version 0.13 or newer (json-c-devel.rpm). - Tip: you may skip ap-check build by adding `HAVE_LOCKFILE=0` or `HAVE_JSONC=0` - to the make invocation. + For building the ap-check mdevctl callout utility you need json-c version + 0.13 or newer (json-c-devel.rpm). + Tip: you may skip ap-check build by adding `HAVE_JSONC=0` to the make + invocation. diff -Nru s390-tools-2.23.0/scripts/dbginfo.sh s390-tools-2.25.0/scripts/dbginfo.sh --- s390-tools-2.23.0/scripts/dbginfo.sh 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/scripts/dbginfo.sh 2022-12-08 13:40:15.000000000 +0100 @@ -17,7 +17,8 @@ readonly SCRIPTNAME="${0##*/}" # general name of this script # readonly DATETIME="$(date +%Y-%m-%d-%H-%M-%S 2>/dev/null)" -readonly DOCKER=$(if type -t docker >/dev/null; then echo "YES"; else echo "NO"; fi) +readonly DOCKER=$(if type docker >/dev/null 2>&1; then echo "YES"; else echo "NO"; fi) +readonly DUMP2TAR_OK=$(if type dump2tar >/dev/null 2>&1; then echo "YES"; else echo "NO"; fi) readonly HW="$(uname -i 2>/dev/null)" # retrieve and split kernel version readonly KERNEL_BASE="$(uname -r 2>/dev/null)" @@ -25,7 +26,9 @@ readonly KERNEL_MAJOR_REVISION=$(echo ${KERNEL_BASE} | cut -d'.' -f2 ) readonly KERNEL_MINOR_REVISION=$(echo ${KERNEL_BASE} | cut -d'.' -f3 | sed 's/[^0-9].*//g') readonly KERNEL_INFO=${KERNEL_VERSION}.${KERNEL_MAJOR_REVISION}.${KERNEL_MINOR_REVISION} -readonly KVM=$(if type -t virsh >/dev/null; then echo "YES"; else echo "NO"; fi) +readonly KUBERNETES=$(if type kubectl >/dev/null 2>&1; then echo "YES"; else echo "NO"; fi) +readonly KUBERNETES_LOG_LINES=50 +readonly KVM=$(if type virsh >/dev/null 2>&1; then echo "YES"; else echo "NO"; fi) # The file to indicate that another instance of the script is already running readonly LOCKFILE="/tmp/${SCRIPTNAME}.lock" # check limits for logfiles like /var/log/messages @@ -43,14 +46,20 @@ sed 's/.*version[[:space:]]*\=[[:space:]]*\([[:alnum:]]*\).*/\1/g')" if test "x${PROCESSORVERSION}" = "xFF" || test "x${PROCESSORVERSION}" = "xff"; then RUNTIME_ENVIRONMENT=$(grep -E "VM00.*Control Program.*" /proc/sysinfo | \ - sed 's/.*:[[:space:]]*\([[:graph:]]*\).*/\1/g') + sed 's/.*:[[:space:]]*\([[:graph:]]*\).*/\1/g') else RUNTIME_ENVIRONMENT="LPAR" fi readonly SYSTEMHOSTNAME="$(hostname -s 2>/dev/null)" # hostname of system being analysed readonly TERMINAL="$(tty 2>/dev/null)" -# The processor version for the first processor and resulting vitrtualization RUNTIME -readonly TOS=15 # timeout seconds for command execution +# timeout seconds TOS / kill timeout TOKS +readonly TOS=15 +readonly TOKS=30 +readonly TIMEOUT=$(if type timeout >/dev/null 2>&1; then echo "YES"; else echo "NO"; fi) +readonly TIMEOUT_OK=$(if test "x${TIMEOUT}" = "xYES"; then + if test $(timeout -k ${TOKS} ${TOS} uname 2>/dev/null) = $(uname); then + echo "YES"; else echo "WRONG_VERSION"; fi + else echo "NO"; fi) readonly ZDEV_CONF=$(lszdev --configured 2>/dev/null | wc -l) readonly ZDEV_OFF=$(lszdev --offline 2>/dev/null | wc -l) readonly ZDEV_ONL=$(lszdev --online 2>/dev/null | wc -l) @@ -79,7 +88,7 @@ a Linux on IBM Z installation for debugging purposes. It also traces information about z/VM if the Linux runs under z/VM. -KVM or DOCKER data ist collected on a host serving this. +Virtualization platform data is collected on a host serving this. Default location for data collection and final tar file is "/tmp/". The collected information is written to a TAR archive named @@ -96,7 +105,7 @@ stores the temporary data and the final archive. -h|--help print this help -v|--version print version information - -c|--check online quick check (no data collection) + -c|--check online base system information (no data collection) Please report bugs to: linux390@de.ibm.com @@ -150,7 +159,7 @@ Kernel version = ${KERNEL_INFO} OS version / distro = ${OS_NAME} KVM host = ${KVM} -DOCKER host = ${DOCKER} +container host Kubernetes: ${KUBERNETES} - docker: ${DOCKER} Current user = $(whoami) (must be root for data collection) Date and time = $(date) @@ -162,6 +171,9 @@ Working directory = $(ls -d ${paramWORKDIR_BASE} 2>&1 && df -k ${paramWORKDIR_BASE}) $(ls -ltr ${paramWORKDIR_BASE}/DBGINFO*tgz 2>/dev/null | tail -2) $(ls ${LOCKFILE} 2>/dev/null && echo " Warning: dbginfo running since: $(cat ${LOCKFILE})") +Tool/command dependency check successful: + timeout = ${TIMEOUT_OK} + dump2tar = ${DUMP2TAR_OK} This is a console output only - no data was saved using option -c ! @@ -213,7 +225,8 @@ # finally verification to run as root if test "$(/usr/bin/id -u 2>/dev/null)" -ne 0; then - echo "${SCRIPTNAME}: Error: You must be user root to run \"${SCRIPTNAME}\"!" + echo "${SCRIPTNAME}: Error: You must be user root to run data collection \"${SCRIPTNAME}\"!" + echo "${SCRIPTNAME}: Hint: for base system information you may run \"${SCRIPTNAME} -c\"" exit 1 fi @@ -249,6 +262,7 @@ readonly OUTPUT_FILE_TC="${WORKPATH}network.out" readonly OUTPUT_FILE_VMCMD="${WORKPATH}zvm_runtime.out" # Base file names for different output files - no extension ! +readonly OUTPUT_FILE_KUBERNETES="${WORKPATH}kubernetes" readonly OUTPUT_FILE_OSAOAT="${WORKPATH}network" readonly OUTPUT_FILE_SYSFS="${WORKPATH}sysfs" @@ -268,7 +282,7 @@ collect_bridge\ collect_ovs\ collect_kvm\ - collect_docker\ + collect_container\ collect_nvme\ collect_logfiles\ post_processing\ @@ -329,14 +343,18 @@ ######################################## LOGFILES="\ + /root/anaconda-ks.cfg\ + /root/original-ks.cfg\ /run/containerd/events.log\ /run/docker/libcontainerd/containerd/events.log\ /run/udev/chreiplzfcpmp-[0-9][0-9][a-z][a-z][a-z][a-z]-*\ + /var/log/anaconda\ /var/log/anaconda.*\ /var/log/audit\ /var/log/boot*\ /var/log/cron*\ /var/log/dmesg*\ + /var/log/dnf.*\ /var/log/dracut.log*\ /var/log/IBMtape.trace\ /var/log/IBMtape.errorlog\ @@ -346,9 +364,12 @@ /var/log/messages*\ /var/log/openvswitch/ovs-vswitchd.log\ /var/log/openvswitch/ovsdb-server.log\ + /var/log/pbl.log\ /var/log/sa\ /var/log/syslog*\ /var/log/yum.log\ + /var/log/YaST2\ + /var/log/zypp*\ " ######################################## @@ -368,6 +389,7 @@ /etc/crypttab\ /etc/default\ /etc/depmod.d\ + /etc/dnf/dnf.conf\ /etc/docker\ /etc/dracut.conf.d\ /etc/exports\ @@ -468,6 +490,7 @@ :dmsetup table --target multipath\ :dmsetup status\ :multipathd -k'show config'\ + :multipathd -k'show config local'\ :multipathd -k'show maps'\ :multipathd -k'show topo'\ :multipathd -k'show paths'\ @@ -558,6 +581,18 @@ " ######################################## +KUBERNETES_CMDS="kubectl version\ + :oc version # get also OCP version if installed\ + :kubectl top pod\ + :kubectl top node\ + :kubectl describe pod -A\ + :kubectl describe node -A\ + :kubectl describe endpoints\ + :ls -l /var/log/containers # list of logs is sufficent\ + :kubectl cluster-info dump >>${OUTPUT_FILE_KUBERNETES}.dmp\ + " + +######################################## VM_CMDS="q userid\ :q users\ :q privclass\ @@ -676,18 +711,18 @@ local vm_userid local module_loaded=1 local ifs_orig="${IFS}" - local cp_buffer_size=2 - local rc_buffer_size=2 + local cp_buffer_size + local rc_buffer_check if echo "${RUNTIME_ENVIRONMENT}" | grep -qi "z/VM" >/dev/null 2>&1; then pr_collect_output "z/VM" - if type -t vmcp >/dev/null; then + if type vmcp >/dev/null; then cp_command="vmcp" if ! lsmod 2>/dev/null | grep -q vmcp && modinfo vmcp >/dev/null 2>&1; then modprobe vmcp && module_loaded=0 && sleep 2 fi - elif type -t hcp >/dev/null; then + elif type hcp >/dev/null; then cp_command="hcp" if ! lsmod 2>/dev/null | grep -q cpint; then modprobe cpint && module_loaded=0 && sleep 2 @@ -703,11 +738,14 @@ IFS=: for vm_command in ${vm_cmds}; do IFS="${ifs_orig}" - while test ${rc_buffer_size} -eq 2 && test ${cp_buffer_size} -lt 1024; do + # initialize buffer values for automatic resizing + cp_buffer_size=2 + rc_buffer_check=2 + while test ${rc_buffer_check} -eq 2 && test ${cp_buffer_size} -lt 1024; do cp_buffer_size=$(( cp_buffer_size * 2 )) eval ${cp_command} -b ${cp_buffer_size}k "${vm_command}" \ >/dev/null 2>&1 - rc_buffer_size=$? + rc_buffer_check=$? done call_run_command "${cp_command} -b ${cp_buffer_size}k ${vm_command}" \ "${OUTPUT_FILE_VMCMD}" @@ -781,7 +819,7 @@ # files known to block on read (-x). Stop reading a file that takes # more than 5 seconds (-T 5) such as an active ftrace buffer. # error messages are not written to the log - if type -t dump2tar >/dev/null; then + if test "x${DUMP2TAR_OK}" = "xYES"; then dump2tar /sys -z -o "${OUTPUT_FILE_SYSFS}.tgz" \ -x '*/tracing/trace_pipe*' \ -x '*/page_idle/bitmap*' \ @@ -859,7 +897,7 @@ network_devices=$(lsqeth 2>/dev/null | grep "Device name" \ | sed 's/D.*:[[:space:]]*\([^[:space:]]*\)[[:space:]]\+/\1/g') - if type -t qethqoat >/dev/null; then + if type qethqoat >/dev/null; then if test -n "${network_devices}"; then pr_collect_output "osa oat" for network_device in ${network_devices}; do @@ -882,7 +920,7 @@ local network_device network_devices=$(ls /sys/class/net 2>/dev/null) - if type -t ethtool >/dev/null; then + if type ethtool >/dev/null; then if test -n "${network_devices}"; then pr_collect_output "ethtool" for network_device in ${network_devices}; do @@ -923,7 +961,7 @@ local network_device network_devices=$(ls /sys/class/net 2>/dev/null) - if type -t tc >/dev/null; then + if type tc >/dev/null; then if test -n "${network_devices}"; then pr_collect_output "Trafic Control" for network_device in ${network_devices}; do @@ -944,7 +982,7 @@ local network_device network_devices=$(ls /sys/class/net 2>/dev/null) - if type -t bridge >/dev/null; then + if type bridge >/dev/null; then if test -n "${network_devices}"; then pr_collect_output "bridge" for network_device in ${network_devices}; do @@ -976,7 +1014,7 @@ :ovs-vsctl -t 5 show\ :ovsdb-client dump\ " - if type -t ovs-vsctl >/dev/null; then + if type ovs-vsctl >/dev/null; then pr_collect_output "OpenVSwitch" IFS=: for ovscmd in ${ovscmds}; do @@ -1001,14 +1039,21 @@ } ######################################## -collect_docker() { +collect_container() { local container_list local network_list local item - # check if docker command exists + # check if container environment exists + if test "x${DOCKER}" = "xYES" || test "x${KUBERNETES}" = "xYES"; then + pr_collect_output "container host" + else + pr_skip "container host: not found" + fi + + # for docker command exists if [ "x${DOCKER}" = "xYES" ]; then - pr_collect_output "docker" + pr_syslog_stdout " docker ..." container_list=$(docker ps -qa) network_list=$(docker network ls -q) ifs_orig="${IFS}" @@ -1030,8 +1075,25 @@ "${OUTPUT_FILE_DOCKER}" done fi - else - pr_skip "docker: not available" + fi + + # for kubectl command exists + if [ "x${KUBERNETES}" = "xYES" ]; then + pr_syslog_stdout " Kubernetes ..." + container_list=$(kubectl top pod | grep -v "MEMORY(bytes)" | cut -d' ' -f1) + + ifs_orig="${IFS}" + IFS=: + for item in ${KUBERNETES_CMDS}; do + IFS=${ifs_orig} call_run_command "${item}" "${OUTPUT_FILE_KUBERNETES}.out" + done + IFS="${ifs_orig}" + if test -n "${container_list}"; then + for item in ${container_list}; do + call_run_command "kubectl logs --tail=${KUBERNETES_LOG_LINES} ${item}"\ + "${OUTPUT_FILE_KUBERNETES}.log" + done + fi fi } @@ -1039,7 +1101,7 @@ collect_nvme() { local device - if type -t nvme >/dev/null; then + if type nvme >/dev/null; then pr_collect_output "NVME storage" call_run_command "nvme list" "${OUTPUT_FILE_NVME}" for device in /dev/nvme[0-9]*; do @@ -1080,7 +1142,7 @@ call_run_command "virsh domstats ${domain}" "${OUTPUT_FILE_KVM}" done else - echo "no KVM doamins found" | tee -a ${OUTPUT_FILE_KVM} + echo "no KVM domains found" | tee -a ${OUTPUT_FILE_KVM} fi else pr_skip "KVM: no virsh command" @@ -1130,6 +1192,10 @@ rm -f "${file_name}" fi done + + echo "log work directory state after post processing:" + echo "du summary: $(du -ks ${WORKPATH})" + df -k ${WORKPATH} } ######################################## @@ -1139,23 +1205,23 @@ local rc=0 local cmd="${1}" local logfile="${2}" - # extract the raw_command and set cmd_type - local raw_cmd=$(echo "${cmd}" | sed -ne 's/^\([^[:space:]]*\).*$/\1/p') - local cmd_type=$(type -t ${raw_cmd}) - # timeout_ok - like a boolean - is not empty if command exists - local timeout_ok=$(type -t timeout) + # extract the raw_command and set cmd_type, as some shell might split into + # several lines restrict the cmd echo to the first line only + local raw_cmd=$(echo "${cmd}" | head -1 | sed -ne 's/^\([^[:space:]]*\).*$/\1/p') + local cmd_type=$(type ${raw_cmd} | cut -d' ' -sf4,5) echo "#######################################################" >> "${logfile}" echo "${USER}@${SYSTEMHOSTNAME:-localhost}> ${cmd}" >> "${logfile}" # check calling command type - if [ "X${cmd_type}" = "Xbuiltin" ]; then + if [ "X${cmd_type}" = "Xshell builtin" ]; then # command is a builtin (no use of timeout possible) eval "${cmd}" >> ${logfile} 2>&1 rc=$? - elif [ "X${cmd_type}" != "X" ]; then - if [ "X${timeout_ok}" = "Xfile" ]; then - eval timeout -k ${TOS} ${TOS} "${cmd}" >> ${logfile} 2>&1 + elif [ "X${cmd_type}" != "Xnot found" ]; then + if [ "x${TIMEOUT_OK}" = "xYES" ]; then + eval timeout -k ${TOKS} ${TOS} "${cmd}" >> ${logfile} 2>&1 + rc=$? else # fall back - call all existing commands without timeout @@ -1347,6 +1413,9 @@ # saving stdout/stderr and redirecting stdout/stderr into log file exec 8>&1 9>&2 >"${LOGFILE}" 2>&1 +# run print_version again to be logged in dbginfo.log +print_version + # trap on SIGHUP=1 SIGINT=2 SIGTERM=15 trap emergency_exit SIGHUP SIGINT SIGTERM diff -Nru s390-tools-2.23.0/scripts/dbginfo.sh.8 s390-tools-2.25.0/scripts/dbginfo.sh.8 --- s390-tools-2.23.0/scripts/dbginfo.sh.8 2022-08-18 15:33:16.000000000 +0200 +++ s390-tools-2.25.0/scripts/dbginfo.sh.8 2022-12-08 13:40:15.000000000 +0100 @@ -1,4 +1,4 @@ -.TH DBGINFO.SH 8 "May 2022" "s390-tools" +.TH DBGINFO.SH 8 "Sep 2022" "s390-tools" .SH NAME dbginfo.sh \- collect runtime, configuration and trace information @@ -8,13 +8,13 @@ .br \fBdbginfo.sh\fP [OPTIONS] .br -\fBdbginfo.sh\fP {\-h|\-v} +\fBdbginfo.sh\fP {\-h|\-c|\-v} .SH DESCRIPTION This script collects runtime, configuration and trace information that can be used to debug a Linux on IBM Z instance. For Linux on z/VM, the script also traces information about the z/VM system. -KVM or DOCKER data ist collected on a host serving this. +Virtualization platform data is collected on a host serving this. The debug information is written to a file //DBGINFO\-\-