Compare commits

..

520 Commits

Author SHA1 Message Date
Jan Höppner
bea3180836 New release s390-tools-2.23.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-18 15:33:16 +02:00
Steffen Eiden
1ffd767977 pvattest/tools: Add script to display config UID and additional data
Although the previous patch enables pvattest to display the
config UID this script enables the user to extract the config UID of
the SE-guest and the additional data if specified. This allows users of
pvattest v2.22.0 to view the config UID without examining binary blobs.

$ ./pvattest-info attresult.bin
Config UID:
1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a
Additional Data:
1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
1b1b

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
a4e396fdd7 pvattest: Add more information to verbose logging
In verbose mode (-v) `pvattest verify´ now also prints
"Attestation measurement verified", if the verification was successful and the
Config UID of the SE-guest and any additional data if available.

$ pvattest -V verify  [...]
Attestation measurement verified
Config UID:
1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a

Additional Data:
1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b
1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
972d4fe0a5 pvattest: Improve logging
Change the name of `hexdump´ to `pvattest_log_bytes´. Additionally, allow
that function to dump the bytes as a single hexadecimal number.

Change the name of `printf_hexdump´ to `pvattest_hexdump´.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
148460c235 pvattest: Improve error reporting
Map the Ultravisor return code 0x2 to "Invalid UV command" string. This
results in better error messages.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
8c2f6790fe genprotimg: sync man and help with pvattest
Syncronizes the description of shared options of genprotimg and pvattest

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
044272ea25 pvattest: Improve man pages and help
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Matthew Rosato
7d67dc8f1c zdev: add some --type ap examples to manpages
The ap type has some unique input parameters, provide some examples
on how to modify and set the apmask and aqmask via chzdev.  Also
include an example of using lszdev to view the apmask and aqmask.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/140
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Benjamin Block
71461d80bf Makefile: use common Make definition for DRACUTDIR
The dracut installation directory is referenced from `chreipl-fcp-mpath`,
`zdev`, and `zipl`; in each with its own individual definition and
variable name. This makes it unnecessarily hard to change it when
installing from the top level directory of s390-tools and passing
variable overwrites via the command line.

Fix this by defining a common `DRACUTDIR` variable in the shared
`common.mak` file, and referencing this in each tool as base directory.
With this a user can simply pass `DRACUTDIR=/foo/bar/baz` on the
commandline and change the installation for all three tools.

Further, also derive common `DRACUTCONFDIR` and `DRACUTMODDIR` variables
from `DRACUTDIR` in `common.mak`, so that `zdev` and `zipl` don't use
different variable names for the same directory anymore, and all these
are defined together in a common place.

Semantically nothing changes for a default build/installation.

Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Benjamin Block
9eac2788d7 Makefile: use common Make definition for UDEVDIR and UDEVRULESDIR
UDEVDIR is used in both `chreipl-fcp-mpath` and `zdev`, but with a
different meaning. In the former it points to the base udev directory,
not the rules directory; in the later it points to the rules directory.
If someone was to call `make` from the top level directory, and set
UDEVDIR for the whole build/installation, it would either break `zdev`
or `chreipl-fcp-mpath` (depending on what it was set to).

Fix this by pulling the definition of it in the shared `common.mak`
file, and giving it a common meaning. Point UDEVDIR to the base udev
directory, and UDEVRULESDIR to the rules directory below it.

Semantically nothing changes for a default build/installation.

Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
6ff8202fa9 zipl: Add missing check for a nullpointer.
Fixes a bug that leads to a segmentation fault when no parmline is
provided.

Fixes: 11b401b5 ("zipl: move and make check for maximum command line length dynamic")
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
acf30de415 pvattest: remove unnecessary variable
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
a766411306 pvattest: fix dependency checking
Fixes a bug that make still tried to build pvattest even when the
compilation of pvattest was turned off.
This lead to a build bug when one of the dependencies was not met.

Also fixes the check of the OpenSSL version at build time.

Fixes: 3ab06d77 ("pvattest: Create, perform, and verify attestation measurements")
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Steffen Eiden
cbcab61c65 libpv: fix dependency checking
Fixes a bug that make still tried to build libpv even when the
compilation of libpv was turned off.
This lead to a build bug when one of the dependencies was not met.

Also fixes the check of the OpenSSL version at build time.i

Fixes: 38639269 ("libpv: New library for PV tools")
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:28:21 +02:00
Marc Hartmayer
c3d179f06e libpv: Fix condition in pv_BIO_reset()
pv_BIO_reset() wrongfully handled the BIO_reset() rc for non-file-backed BIOs.
This is currently not an issue as the only non-file BIO used cannot fail
at BIO_reset()

Fixes: 3ab06d77fb ("pvattest: Create, perform, and verify attestation measurements")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:27:36 +02:00
Marc Hartmayer
f42250ca9b genprotimg: Fix BIO_reset() returncode handling
The returncode handling for BIO_reset() was wrong when handling with
file based BIOs.

This resulted in a bug that DER formated certificates cannot be read
by genprotimg which is now fixed.

Fixes: d90344a2 (genprotimg: check return value of BIO_reset)
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-08-16 18:23:13 +02:00
Dan Horák
7217903ce4 libvmdump: add default assignment operators
lkcd_dump.cpp: In constructor ‘LKCDDump32::LKCDDump32(Dump*, const RegisterContent32&)’:
lkcd_dump.cpp:191:27: warning: implicitly-declared ‘constexpr RegisterContent32& RegisterContent32::operator=(const RegisterContent32&)’ is deprecated [-Wdeprecated-copy]
  191 |         registerContent = r;
      |                           ^
In file included from lkcd_dump.h:18,
                 from lkcd_dump.cpp:17:
register_content.h:63:9: note: because ‘RegisterContent32’ has user-provided ‘RegisterContent32::RegisterContent32(const RegisterContent32&)’
   63 |         RegisterContent32(const RegisterContent32&);
      |         ^~~~~~~~~~~~~~~~~
lkcd_dump.cpp: In constructor ‘LKCDDump64::LKCDDump64(Dump*, const RegisterContent64&)’:
lkcd_dump.cpp:232:27: warning: implicitly-declared ‘constexpr RegisterContent64& RegisterContent64::operator=(const RegisterContent64&)’ is deprecated [-Wdeprecated-copy]
  232 |         registerContent = r;
      |                           ^
register_content.h:49:9: note: because ‘RegisterContent64’ has user-provided ‘RegisterContent64::RegisterContent64(const RegisterContent64&)’
   49 |         RegisterContent64(const RegisterContent64&);
      |         ^~~~~~~~~~~~~~~~~

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
708abbf380 dasdfmt: fix buffer overread warning
dasdfmt.c: In function ‘dasdfmt_write_labels’:
dasdfmt.c:1110:22: warning: ‘write’ reading 88 bytes from a region of size 4 [-Wstringop-overread]
 1110 |                 rc = write(fd, &vlabel->vollbl, (sizeof(*vlabel)
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1111 |                                                  - sizeof(vlabel->volkey)));
      |                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from dasdfmt.c:23:
../include/lib/vtoc.h:84:14: note: source object ‘vollbl’ of size 4
   84 |         char vollbl[4];         /* volume label                              */
      |              ^~~~~~
In file included from ../include/lib/util_opt.h:16,
                 from dasdfmt.c:20:
/usr/include/unistd.h:378:16: note: in a call to function ‘write’ declared with attribute ‘access (read_only, 2, 3)’
  378 | extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur
      |                ^~~~~

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
28dbec093b iucvterm: fix function declaration
GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
daf02f75b1 dasdview: fix string truncation warning
Replace strncpy() with util_strlcpy() which provides the required
semantic.

In function ‘dasdview_print_format1’,
    inlined from ‘dasdview_view_standard’ at dasdview.c:1952:4,
    inlined from ‘dasdview_view’ at dasdview.c:2165:3,
    inlined from ‘main’ at dasdview.c:2364:3:
dasdview.c:1791:25: warning: ‘strncpy’ output may be truncated copying 16 bytes from a string of length 1023 [-Wstringop-truncation]
 1791 |                         strncpy(asc, (char *)dumpstr + i, 16);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dasdview.c:1792:25: warning: ‘strncpy’ output may be truncated copying 16 bytes from a string of length 1023 [-Wstringop-truncation]
 1792 |                         strncpy(ebc, (char *)dumpstr + i, 16);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘dasdview_print_format2’,
    inlined from ‘dasdview_view_standard’ at dasdview.c:1935:4,
    inlined from ‘dasdview_view’ at dasdview.c:2165:3,
    inlined from ‘main’ at dasdview.c:2364:3:
dasdview.c:1825:25: warning: ‘strncpy’ output may be truncated copying 8 bytes from a string of length 1023 [-Wstringop-truncation]
 1825 |                         strncpy(asc, (char *)dumpstr + i, 8);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dasdview.c:1826:25: warning: ‘strncpy’ output may be truncated copying 8 bytes from a string of length 1023 [-Wstringop-truncation]
 1826 |                         strncpy(ebc, (char *)dumpstr + i, 8);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
[hoeppner@linux.ibm.com: sort include]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
71b0460d11 mon_tools: drop an always-true condition
The d_name member of struct dirent is a statically allocated string,
thus it's always non-NULL.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
ff62f4d425 mon_tools: fix user counting condition
The ut_user (aka ut_name) member of struct utmp is a statically
allocated string, thus always non-NULL.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
53c523ab19 ziomon: silence unaligned pointer value warnings
The build produces a number of warnings like the ones below. The
unaligned pointers are expected, thus silence the warnings by disabling
the compiler diagnostics.

ziomon_dacc.c: In function ‘read_message’:
ziomon_dacc.c:189:44: warning: taking address of packed member of ‘struct message’ may result in an unaligned pointer value [-Waddress-of-packed-member]
  189 |         if ( (rc = read_message_header(fp, &msg->length, &msg->type)) )
      |                                            ^~~~~~~~~~~~

or

In file included from ziomon_mgr.c:36:
blkiomon.h: In function ‘blkiomon_stat_init’:
blkiomon.h:70:21: warning: taking address of packed member of ‘struct blkiomon_stat’ may result in an unaligned pointer value [-Waddress-of-packed-member]
   70 |         minmax_init(&bstat->size_r);
      |                     ^~~~~~~~~~~~~~

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Dan Horák
2285b9527b lib: avoid redefinition of _AC() macro
The kernel already provides the same macro as does the zt_common.h file,
thus check for its availability first.

  CC      zconf/qeth/lsqeth.o
In file included from ../../include/lib/util_base.h:17,
                 from lsqeth.c:30:
../../include/lib/zt_common.h:27: warning: "_AC" redefined
   27 | #define _AC(X, TYPE)    X##TYPE
      |
In file included from /usr/include/linux/ethtool.h:17,
                 from lsqeth.c:12:
/usr/include/linux/const.h:21: note: this is the location of the previous definition
   21 | #define _AC(X,Y)        __AC(X,Y)
      |

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/137
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Balint Reczey
b4648ec4bd dumpconf: Don't run the service in containers
It just fails to start in unprivileged containers

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/85
Signed-off-by: Balint Reczey <balint.reczey@canonical.com>
Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
[hoeppner@linux.ibm.com: expanded from !lxc to !container]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Juergen Christ
c6207db8fc cpacfstats: Typos and Explanation
Correct wrong counter name.
Clarify counting of KMA.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Sven Schnelle
1bd73c68f9 zipl/boot: don't use lt to test value in tape0.S
This instruction is not present on older machines, therefore
use ltr.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Fixes: 1627c6a39f ("zipl: Support command lines longer than 896 bytes in bootloader")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Joern Siglen
47016441f0 dbginfo.sh: get more details on lspci command
The new version of lspci does support an extended verbose mode "-vvv"

Using the the tripple v parameter does also work for the old version
having the same result as the double v called before.

Reported-by: Eberhard Pasch <epasch@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Steffen Maier
eeed384a51 dbginfo.sh: fix accidental ftrace buffer shrinkage/free
https://www.kernel.org/doc/html/latest/trace/ftrace.html?highlight=free_buffer

  free_buffer:

        If a process is performing tracing, and the ring buffer should be
        shrunk "freed" when the process is finished, even if it were to be
        killed by a signal, this file can be used for that purpose. On close
        of this file, the ring buffer will be resized to its minimum size.
        Having a process that is tracing also open this file, when the process
        exits its file descriptor for this file will be closed, and in doing so,
        the ring buffer will be "freed".

        It may also stop tracing if disable_on_free option is set.

$ cat /sys/kernel/debug/tracing/buffer_size_kb
7 (expanded: 1408)
$ cat /sys/kernel/debug/tracing/free_buffer
cat: /sys/kernel/debug/tracing/free_buffer: Invalid argument
$ cat /sys/kernel/debug/tracing/buffer_size_kb
0

Reported-by: Thomas Lambart <Thomas.Lambart2@ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Steffen Eiden
cd5d6a5004 libpv/cert.c: Improve error reporting
The current implementation drops the reason why a download of a CRL
failed. This is changed to the reporting of the error triggered by the
last CRL download attempt.

This mainly helps to check for the download error during CI testing
and prevent connectivity issues to be the reason of a test failure.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:57:17 +02:00
Thomas Richter
e4733002da cpumf/pai: Extract type number from PMU named pai_ext
Use PMU named pai_ext to extract the PMU type number required
for the installation of PAI NNPA counters using perf_event_open()
system call.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:56:44 +02:00
Thomas Richter
15158ee0ca libcpumf: Detect PMU named pai_ext
Add a check to detect Processor Activity Instrumentation (PAI)
Extension 1 facility unit.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:56:44 +02:00
Thomas Richter
dc73c77d73 cpumf/pai: Omit detailed event information when summary flag selected
When the summary flag is selected do not print detailed information
on every single event. Just print the summary information on each
non-zero counter value.

Suggested-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:56:44 +02:00
Thomas Richter
56529261db cpumf/pai: Omit file write progress information
During recording, progress information is displayed on the screen
on how many event have been processed and at which offset these
events have been extracted from the ring buffer.

This information is usually of no interest to the user. Omit this
data and only print them when requested via verbose flag.

Suggested-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-07-21 15:56:44 +02:00
Juergen Christ
fcb1f7efd1 cpacfstats: Add PAI and hotplug support
Add virtual counters pai_user and pai_kernel to detail all Processor Activity
 Instrumentation (PAI) counters in user resp. kernel space.  Once activated,
they will show all counters for the corresponding set.  Add option -n to limit
the display to only non-zero counter values.

Add support for cpu hotplug events based on libudev.  CPU hotplug events are
used to either detach from a vanishing CPU or (re-)attach to a (re-)appearing
CPU.  In that case, a "hotplug detected" virtual counter is set to a non-zero
value to indicate possible loss of counters which happens when CPACF is used
on the CPU before cpacfstatsd could attach to it.  The hotplug indication is
cleared once all counters are deactivated.

Add support for JSON output.  The JSON document is an array of JSON objects
representing the counters and their values.  Every object has a name (property
"counter") and a value (property "value").  For PAI counters, the counters
also have a space (property "space") determining the counter set pai_user or
pai_kernel, and a numeric id (property "counterid") that can be used to filter
the JSON document.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-By: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:07:34 +02:00
Juergen Christ
72b5e8b313 cpacfstats: Handle CPU hotplug
cpacfstatsd now correctly handles offline cpus and dynamically attaches to
cpus once they get online.  If events are enabled when a hotplug event
occurs, cpacfstatsd uses a pseudo-counter to notify user applications about
the occurence of this event and a potential data inaccuracy.

cpacfstats shows if a hotplug event has been detected since at least one
counter was activated.  As soon as all counters are deactivated, the
hotplug detection state is reset.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-By: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:07:31 +02:00
Juergen Christ
225964875c cpacfstats: Use timed operations in daemon.
The cpacfstats daemon is susceptible to dos attacks from malicious clients
that connect but either do not send a query or receive an answer fast
enough.  The latter currently is impossible but might occur once we
introduce further counters.

Solve both problems by exploiting a timed read/write operation in the
daemon and close the connection on timeout.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-By: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:06:35 +02:00
Marc Hartmayer
e580190074 common.mak: remove -rdynamic since it's a linker flag
Remove `-rdynamic` since it's a linker flag. This should not cause any problems
because we differentiate between compilation and linking by default. While at
it, adapt the `print_backtrace` documentation accordingly.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:06:35 +02:00
Thomas Richter
8ef593904d cpumf/pai: Use util_file_read_va function
Use util_file_read_va() function to read out the event number
given the event file. Also use util_strdup() function to save
the event name. This function terminates on Out Of Memory condition.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:06:35 +02:00
Frank Heimes
51b9504720 zkey: use default benchmarked Argon2i with LUKS2.
cryptsetup 2.1.0 requires excessive amount of RAM (1GB) to luksOpen encrypted
drives (LP: #1820049).
LUKS2 introduced support for Argon2i and Argon2id as a Password-Based Key
Derivation Function (PBKDF).
Argon2 is the winner of Password Hashing Competition and is now officially
recommended by RFC 9106.
PBKDF2 is currently used in zkey to mitigate out-of-memory errors when
multiple LUKS2 volumes are opened automatically via /etc/crypttab.

This patch is to use Argon2i (the deflaut algorithm) as key derivation function
for LUKS2 volumes, but with options for low memory and time requirements.
Using the default Argon2i options might still cause out-of-memory errors.

Link: https://bugs.launchpad.net/ubuntu/+source/cryptsetup/+bug/1820049
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/138
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
Acked-by: Ingo Franzki ifranzki@linux.ibm.com
[hoeppner@linux.ibm.com: fix whitespace, line break, and commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:06:34 +02:00
Thomas Richter
e9d0e267c5 cpumf/lscpumf: Replace /sys mount point by util_path_sysfs
Replace hard coded /sys directory by call to util_path_sysfs()
function.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-29 14:06:34 +02:00
Jan Höppner
b028d4c254 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 14:08:53 +02:00
Jan Höppner
a6f844d642 New release s390-tools-2.22.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 14:08:53 +02:00
Marc Hartmayer
7f059bef13 common.mak: fix -Wnewline-eof in check_header_prereq and check_dep
printf "#include <%s>\n int main(void) {return 0;}"  "glib.h" | ( clang -DS390_TOOLS_RELEASE=2.21.0-build-20220609 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -g -fstack-protector-all -W -Wall -Wformat-security -O3 -std=gnu11 -DOPENSSL_API_COMPAT=0x10101000L -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/sysprof-4 -pthread -Wall -Wextra -Wshadow -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes -Wpointer-arith -Wno-error=inline -Wpedantic -Werror -fPIC -I ../include -D_GNU_SOURCE  -o /dev/null -xc - )
<stdin>:2:28: error: no newline at end of file [-Werror,-Wnewline-eof]
 int main(void) {return 0;}
                           ^
1 error generated.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Steffen Eiden
4543d23dcf Makefile: remove trailing whitespace
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Ingo Franzki
12f7dbbb3d zkey: Fix EP11 host library version checking
Extract the minor version and modification level separately.
Previously only the modification level has been extracted, and was
reported as minor version.

Currently no one is checking the minor version or modification level,
so it does not hurt. But maybe in the future one will check, so report
it correctly.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Ingo Franzki
f7c048d0eb zkey_kmip: Setup ext-lib once the APQNs have been configured
During plugin initialization, the external libraries such as the
EP11 or CCA host libraries are set up, if the configuration is
appropriate.

A secure identity key may be generated once the APQNs are configured,
but before the server connection is configured. Trying to re-encipher
the plugin's secure keys to a new HSM master key at that stage fails
with 'ERROR: Invalid ext lib type: 0' because the external libraries
have not been setup yet.

Change the code to setup the libraries once the APQNs have been
configured, and not only after the server connection has been
configured.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Mete Durlu
80e54ac888 hyptop: increase initial update interval
Increase initial update interval from 200ms to 1 seconds to avoid
fluctuations on the initial data output.

Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Steffen Eiden
26148740df pvattest/tools: Add tool for attestation
Adds:
  * extract_hdr_from_image
    a bash script to extract the SE header from an SE image.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Steffen Eiden
3ab06d77fb pvattest: Create, perform, and verify attestation measurements
pvattest is a tool to attest an IBM Secure Execution guest.

In a trusted environment, one can create a request using
`pvattest create`. To get a measurement of an untrusted
IBM Secure Execution guest call 'pvattest perform'.
Again in a trusted environment, call 'pvattest verify'
to verify that the measurement is the expected one.

The tool runs on s390 and x86.
It has the same requirements like libpv and therefore
requires openssl v1.1.1+, glib2.56+, and libcurl.
Additionally, to measure, the linux kernel must provide
the Ultravisor userspace interface `uvdevice` at /dev/uv
and must be executed  on an IBM Secure Execution guest on
hardware with Ultravisor attestation support, like IBM z16 or later.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Steffen Eiden
386392690d libpv: New library for PV tools
libpv is a collection of definitions and functions related to
Protected Virtualization (PV).
The functions cover mainly encryption (e.g. AES-GCM)
and certificates (X509). There are also helping functions for glib2.

Most of the code is extracted+refactored from `genprotimg`, which
will use this library in future.

Requires openssl v1.1.1+, glib2.56+, and libcurl.

libpv is not designed or intended to be dynamically linked or used
outside of this project. Its purpose is to avoid code duplication
as PV tools do very similar things regarding cryptography.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
72df42ea4e zdump: Adapt man page for NGDump dump tool
Document how to use zgetdump with NGDump and NVMe.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
6c0f429805 zdump: Implement DFI interface for NGDump
The NGDump DFI interface enables zgetdump to read and mount dumps created
with NGDump stand-alone dump.

Under the hood, the NGDump DFI delegates the task of reading and
parsing of ELF dump files to the ELF DFI interface dfi_elf.

Usage example 1:
----------------

$ zgetdump -i /dev/nvme0n1p1
General dump info:
  Dump format........: elf
  Version............: 1
  UTS node name......: t83lp49.lnxne.boe
  UTS kernel release.: 5.14.0-20210819.rc6.git0.efb8a921eec7.300.fc34.s390x
  UTS kernel version.: #1 SMP Thu Aug 19 00:22:04 CEST 2021
  System arch........: s390x (64 bit)
  CPU count (online).: 32
  Dump memory range..: 16384 MB

Memory map:
  0000000000000000 - 00000003ffffffff (16384 MB)

Usage example 2:
----------------

$ zgetdump /dev/nvme0n1p1 > dump.elf

Usage example 3:
----------------

$ zgetdump -m /dev/nvme0n1p1 /mnt
$ ls -l /mnt/dump.elf
$ zgetdump -u /mnt

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Tested-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
0466760ec1 zdump: Implement DT interface for NGDump
The NGDump DT interface enables zgetdump to display various meta
information contained within a dump partition prepared for NGDump
stand-alone dump.

Usage example:
--------------

No dump yet made
----------------

$ zgetdump -d /dev/nvme0n1
Dump device info:
  Dump tool.........: Next Generation (NGDump) dump tool
  Version...........: 1
  Architecture......: s390x (64 bit)

Partition info:
  Partition number..: 1

Dump present
------------

$ zgetdump -d /dev/nvme0n1
Dump device info:
  Dump tool.........: Next Generation (NGDump) dump tool
  Version...........: 1
  Architecture......: s390x (64 bit)

Partition info:
  Partition number..: 1
Meta info:
  File..............: dump.elf

Alternative disk path
---------------------

$ zgetdump -d /dev/disk/by-id/nvme-eui.01000000010000005cd2e4c5bc845051
Dump device info:
  Dump tool.........: Next Generation (NGDump) dump tool
  Version...........: 1
  Architecture......: s390x (64 bit)

Partition info:
  Partition number..: 1
Meta info:
  File..............: dump.elf

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Tested-by:  Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
8ddc31ea77 zdump: Implement NGDump helpers
This commit introduces a new module containing various helpers for
NGDump stand-alone dump. The purpose of these helpers is to facilitate
the implementation of DT and DFI interfaces for NGDump, share code
between both, reduce duplication and enable unit testing later on.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
60f862b21c libutil/util_part: return partition containing given block range
Return the partition number which contains the given block range,
before it was tested for exact match between a partition block range
and the one provided by user. The old behavior with exact match
should still work, this change just relaxes the partition matching
algorithm and allows one to find a partition which contains the given
block range.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
a66f6bb075 zipl: Adapt man pages for NVMe stand-alone dump
From user perspective, there is no difference between SCSI stand-alone
dump and NVMe one.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
2b015183aa zipl: Implement NGDump
This commit finalizes the implementation of the new stand-alone dump -
Next Gen Dump (NGDump).

NGDump stand-alone dump is a universal stand-alone dump which works for both
SCSI and NVMe disks. But currently can be used only with NVMe disks
and SCSI stand-alone dump remains the default for SCSI disks.

Currently, this stand-alone dump can be used only on IBM z15 or newer
machine generations because it requires larger amount of HSA memory offered
by firmware only on IBM z15 machines. Whereas SCSI stand-alone dump is able
to work with HSA memory of 32M, the new stand-alone dump requires 512M HSA
memory at the moment.

NGDump stand-alone dump installation is initiated by passing a path to
a NVMe disk partition to zipl via the command-line -d, similar to SCSI
stand-alone dump. zipl will then:
- build a dumper initramfs with either dracut (Fedora/RHEL/SLES) or
  initramfs-tools (Ubuntu/Debian)
- format the given NVMe partition with ext4 file system
- create a bootmap file on the newly created file system using the built
  initramfs and the currently active kernel image
- install a boot loader on the disk the given dump partition belongs to

The operations described above are destructive for the given NVMe dump
partition and the boot record(s) of its disk.

After the installation step, users can configure the dumpconf to IPL
the dumper automatically on panic or trigger a dump manually via HMC
interface.

When activated, the dumper will create a dump ELF file named "dump.elf"
on the given NVMe dump partition by using the makedumpfile tool. The kdump
compressed file format is not supported yet due to zgetdump not being able
to read such a file format. Therefore, the dumper is restricted to write
the dump only in ELF format but only kernel pages which are in use.
This will usually make the dump smaller than the original size of
/proc/vmcore and the whole dump process faster as well.

Example configuration for dumpconf:

ON_PANIC=dump   # or dump_reipl
DUMP_TYPE=nvme
FID=0x00000001
NSID=0x00000001
BOOTPROG=0
BR_LBA=0

$ systemctl enable --now dumpconf

To install the dracut support on Fedora/RHEL/SUSE:

$ make -C zipl/dracut HAVE_DRACUT=1 install

To install the initramfs-tools support on Ubuntu/Debian:

$ make -C zipl/initramfs-tools HAVE_INITRAMFS=1 install

Example of NGDump console output on SLES during dump
----------------------------------------------------

         Starting NGDump...
[    8.932343] ngdump.sh[327]: NGDump started
[    8.934739] ngdump.sh[336]: Checking for memory holes                         : [  0.0 %] /
[    8.967536] ngdump.sh[336]: Checking for memory holes                         : [100.0 %] |
[    9.076976] ngdump.sh[336]: Excluding unnecessary pages                       : [100.0 %] \
[   11.721157] ngdump.sh[336]: Copying data                                      : [  0.0 %] -
[   12.317319] ngdump.sh[336]: Copying data                                      : [ 22.5 %] /           eta: 2s
[   13.273000] ngdump.sh[336]: Copying data                                      : [100.0 %] |           eta: 0s
[   13.273244] ngdump.sh[336]: The kernel version is not supported.
[   13.273263] ngdump.sh[336]: The makedumpfile operation may be incomplete.
[   13.273281] ngdump.sh[336]: The dumpfile is saved to /ngdump/dump.elf.
[   13.273299] ngdump.sh[336]: makedumpfile Completed.

Example of NGDump console output on Ubuntu during dump
-------------------------------------------------------

[    3.240078] zdump: The dump process started for a 64-bit operating system
Loading, please wait...
Starting version 245.4-4ubuntu3.17
Begin: Starting firmware auto-configuration ... done.
Begin: Loading essential drivers ... done.
Begin: Running /scripts/init-premount ...
Begin: NGDump ...
Checking for memory holes                         : [  0.0 %] /
Checking for memory holes                         : [100.0 %] |
Excluding unnecessary pages                       : [100.0 %] \
Copying data                                      : [  0.0 %] -
Copying data                                      : [ 40.7 %] /           eta: 1s
Copying data                                      : [100.0 %] |           eta: 0s
The kernel version is not supported.
The makedumpfile operation may be incomplete.
The dumpfile is saved to /ngdump/dump.elf.
makedumpfile Completed.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Tested-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
b4142a9966 zipl: Implement zipl helper script for NGDump
The purpose of the new zipl helper script is to build a dumper initramfs
for NGDump stand-alone dump. zipl executes the helper script when
preparing a NVMe dump partition for stand-alone dump.

The zipl helper script expects a single parameter - a path to the dump
partition to store a dump on. The helper script terminates with 0 on
success and a positive value otherwise.

The zipl helper script performs the following steps:
- It builds an initramfs image suitable for dumping. To perform this step,
  the script employs the dracut tool on Fedora/RHEL/SLES and
  the initramfs-tools on Ubuntu/Debian.
- It outputs the path to the newly built initramfs image and the currently
  active kernel bzImage on the standard output.
- It prints the kernel command-line to be used by the dumper on
  the standard output.

On success, zipl expects the helper script to return at least three lines
containing:
- initrd=<path to an initramfs image>
- kernel=<path to a kernel bzImage>
- cmdline=<kernel command-line parameters>

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
c1d08e1380 zipl: Add initramfs-tools module for NGDump
The NGDump initramfs-tools module is required to build an initramfs image
to be used with NGDump stand-alone dump. NGDump stand-alone dump does not
use a pre-built initramfs image in contrast to SCSI stand-alone dump.
Instead, an initramfs image is built with initramfs-tools if NGDump
stand-alone dump is installed on a NVMe partition.

The NGDump initramfs-tools module ensures that all necessary tools are
present within the built initramfs and a dump of /proc/vmcore is initiated
to the chosen NVMe partition when the installed dumper is IPLed.

The NGDump intramfs-tools module installs a configuration file and
a dump script into dumper initramfs. This dump script starts at boot
shortly after the initialization of the dump target device. It reads
the aforementioned configuration file that contains the name of a dump
partition to store a dump on. The dump script reads the configuration file,
mounts then the dump target device, creates a copy of /proc/vmcore with
the makedumpfile tool on it, and then shuts down the system.

Ubuntu and Debian are the main Linux distributions targeted by this
initramfs-tools module.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
85c9a49e63 zipl: Add dracut module for NGDump
The NGDump dracut module is required to build an initramfs image to be used
with NGDump stand-alone dump. NGDump stand-alone dump does not
use a pre-built initramfs image in contrast to SCSI stand-alone dump.
Instead, an initramfs image is built with dracut if NGDump stand-alone dump
is installed on a NVMe partition.

The NGDump dracut module ensures that all necessary tools are present
within the built initramfs and a dump of /proc/vmcore is initiated
to the chosen NVMe partition when the installed dumper is IPLed.

The NGDump dracut module installs a new systemd service and a dump script
into dumper initramfs. The systemd init process starts the NGDump service
at boot shortly after the initialization of the dump target device.
The NGDump systemd service, in its turn, starts the dump script provided
by the new dracut module. The dump script mounts then the dump target
device, creates a copy of /proc/vmcore with the makedumpfile tool on it,
and then shuts down the system.

The NGDump dracut module can be used on any Linux distribution which
supports dracut. But the primary targets are:
- Fedora
- RHEL
- SLES

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
4939531fe5 zipl: Add bootmap directory parameter to bootmap_create_file()
This change adds a new parameter to the function bootmap_create_file()
that requires the caller to specify a path to the directory where
a bootmap file will be created. The primary motivation for this change is
to support NVMe stand-alone dump, in that case the job's bootmap directory
is not set.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
84abb27077 zipl: Extract SCSI dump partition check from bootmap_create_device()
The purpose of this change is to simplify the function
bootmap_create_device() and make it more readable. Furthermore,
the dump partition check can be reused for NVMe dump partitions later on.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
6826316350 zipl: Extract SCSI dump size estimation from bootmap_create_device()
The purpose of this change is to simplify the function
bootmap_create_device() and to make it more readable.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
b95a3c24b8 zipl: Extract SCSI superblock writing from bootmap_create_device()
The purpose of this change is to simplify the function
bootmap_create_device() and make it more readable.
Furthermore, make bootmap_create_device() more robust by checking the return
value of disk_write_block_aligned().

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
1f8496aa92 zipl: Extract SCSI dump partition handling from bootmap_create()
The purpose of this change is to simplify the function bootmap_create(),
make it more readable and prepare for new changes that will follow.
The original function bootmap_create() tried to handle two different cases
and, therefore, contained many conditional statements which had a negative
effect on readability.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
9aa59bfc4b zipl: Fix stage2 disk block memory leaks in bootmap_install_stages()
This commit fixes a bug that fails to release stage2 disk blocks in case
the installation of stage1b disk blocks has failed.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Suggested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
fa111404cb zipl: Extract stage2 loader handling from bootmap_create()
The purpose of this change is to simplify the function bootmap_create(),
make it more readable and prepare for new changes that will follow.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
5094354c39 zipl: Implement helper function disk_is_nvme()
The new function disk_is_nvme() is a convenience function that indicates
whether the given path to a device file represents a NVMe disk.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:05 +02:00
Alexander Egorenkov
844058bf4d zipl: Extend disk_get_info() to recognize NVMe disks
Until now, NVMe disks were handled by zipl as SCSI disks. To support
NVMe stand-alone dump, it became necessary to further differentiate between
both types of disks.

There are two cases that must be handled:
1. A non-device-mapper device is a NVMe disk if it is assigned to the blkext
   device driver.
2. A device-mapper disk is a NVMe disk if the ioctl NVME_IOCTL_ID succeeds.
   This case is necessary to properly recognize NVMe disks which are
   DM devices and, therefore, not directly handled by the blkext device
   driver.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
dc49b4fcf0 zdump/scsi: reuse zipl magic string definitions from boot_defs.h
To remove duplication of definitions.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
647e8b5c37 zipl/boot: move zipl magic string definitions to boot_defs.h for reuse
To reduce duplication of definitions and facilitate reuse between zipl
and zgetdump.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
1ae4fd18fe zfcpdump: reuse SCSI struct definitions from boot_defs.h
To remove duplication of definitions.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
561883b1d8 zdump/scsi: reuse SCSI MBR struct definitions from boot_defs.h
To remove duplication of definitions.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
953af2cc67 zipl/boot: move SCSI MBR struct definition to boot_defs.h for reuse
To reduce duplication of definitions and facilitate reuse between zipl
and zgetdump.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
8f37000137 zdump/scsi: reuse boot info struct definitions from boot_defs.h
To remove duplication of definitions.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
ba7bf2f6d3 zipl/boot: move boot info struct definitions to boot_defs.h for reuse
To reduce duplication of definitions and facilitate reuse between zipl
and zgetdump.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
4a8e52a019 zdump/scsi: reuse SCSI superblock struct definitions from boot_defs.h
To remove duplication of definitions.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
446ace09ad zipl/boot: move SCSI superblock struct definitions to boot_defs.h for reuse
To reduce duplication of definitions and facilitate reuse between zipl
and zgetdump.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
012b842652 zdump/scsi: reuse boot component struct definitions from boot_defs.h
To remove duplication of definitions.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Alexander Egorenkov
fed12a71cf zipl/boot: move boot component struct definitions to boot_defs.h for reuse
To reduce duplication of definitions and facilitate reuse between zipl
and zgetdump.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Thomas Richter
5cd9ad13e5 cpumf/lshwc: Use util_file_read_va function
Use util_file_read_va() function to read out the event number
given the event file. Also use util_strdup() function to save
the event name. This function terminates on Out Of Memory condition.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Frank Heimes
f2d5b649e1 README.md: Add 70-chreipl-fcp-mpath.rules to the list of udev rule descriptions
All udev rules that are part of the s390-tools package are listed in the main
README.md with a brief description.
This commit adds information about the newly added rule for chreipl-fcp-mpath,
called '70-chreipl-fcp-mpath.rules'.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/136
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
Acked-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-20 13:14:04 +02:00
Jan Höppner
a957e3efd6 zcryptstats: Fix man page section in title line
The title line of the zcryptstats man page specifies section 1 (user
command) while the tool is a system command.
Change it to section 8 for system command.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/135
Reviewd-by Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Jan Höppner
463189bf60 cpumf: Move man pages to System commands section
lscpumf, lshwc, and pai are system commands but the corresponding man
pages are located in section 1 for user commands.

Move the man pages to section 8 for system commands.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/135
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Jan Höppner
aa2e8e1caa scripts: Move man pages to System commands section
dbginfo.sh, zfcpdbf, and zipl-switch-to-blscfg are system commands but
the corresponding man pages are located in section 1 for user commands.

Move the man pages to section 8 for system commands.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/135
Reviewed-by: Steffen Maier <maier@linux.ibm.com> [zfcpdbf]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Jan Höppner
7bc15537c8 genprotimg: Move man page to section 1 for user commands
genprotimg is a user command and as such installed into /usr/bin. Adapt
the man page accordingly and move it from section 8 (system commnds) to
section 1 (user commands).

Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Frank Heimes
901f082f1a s390-tools: Fix typos that were detected by lintian as 'typo-in-manual-page'
The static analysis tool for Debian packages 'lintian', especially if called
like 'lintian -EvIL +pedantic', checks manual pages for correctness and typos.
This commit fixes typos that were identified by lintian and marked with
'typo-in-manual-page' while s390-tools version 2.20.0 was packaged.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/134
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
Acked-by: Steffen Maier maier@linux.ibm.com [ziomon]
Acked-by: Ingo Franzki ifranzki@linux.ibm.com [zkey]
[hoeppner@linux.ibm.com: fix commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Ingo Franzki
cd2647ab78 libseckey: make secure key provider functions more type save
The provider functions are passed to OpenSSL in the dispatch array
casted to 'void (*)(void)', so they can not be type checked by the
compiler. Add function prototypes using the OpenSSL provided
function typedefs to allow the compiler to check the function
signatures.

No functional change.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Ingo Franzki
48bcfc3366 zkey-kmip: Fix possible use after free
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Ingo Franzki
57f3527799 libkmipclient: Fix -Wmaybe-uninitialized warning with gcc 12
Gcc 12 produces a -Wmaybe-uninitialized warning that the content
of the tmp buffer may be uninitialized. This is a false positive.
Silence the warning by using calloc instead of malloc to ensure
that the allocated buffer is initialized.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Eduard Shishkin
f51dc05f7f zipl/Makefile: create an empty environment file /etc/ziplenv
Create an empty environment file /etc/ziplenv at make install
time if that file doesn't exist

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Eduard Shishkin
3f9ead5731 ipl-tools/man: update a man page with LOADPARM specifications
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Eduard Shishkin
b4e4cd6cd5 zipl/man: update zipl-editenv man page
Add definitions of sites, namespaces and sections.
Document the new options --site (-S) and --effective-site (-E)

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Eduard Shishkin
e97c85bb80 zipl-editenv: added zIPL multienvironment support
. Support multiple namespaces in the installed environment block;
. Add option --site (-S) to specify a particular namespace
  when operating on the installed environment block;
. Add option --effective-site (-E) to specify a particular
  namespace. When using in a combination with the option -l
  (--list), it displays zIPL environment that would take place if
  the specified namespace was activated at boot time;
. Modify set/unset/reset/list operations over the installed
  environment block in the case when the option --site is specified

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Eduard Shishkin
c6443cf977 zipl/boot: added zIPL multienvironment support
. Parse LOADPARM specified by user to find out site-ID;
. Support multiple namespaces in the environment block. Use hash
  function on "extended" strings (i.e. strings with logical
  prefixes) for the key-value store implementation;
. Added logic to activate a particular namespace by site-ID passed
  by user via LOADPARM;
. Modify the logic of evaluation of zIPL environment variables in
  the kernel command line. Use the activated namespace for the
  evaluation

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Eduard Shishkin
6a439e6771 zipl/src: added zIPL multienvironment support
Support multiple namespaces in environment block. Use hash
function on "extended" strings for key-value store.
Support multiple sections in environment file.
Modify the import environment precedure to be "section-aware"

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
2134aff491 zipl/boot: kdump: remove static struct
Makes the code easier to read since it can have less side effects.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
b41ac66f36 zipl: consolidate boot and dump type definitions
Consolidate type definitions in order to avoid duplicated code, getting
better compiler support, and to avoid confusing namings for the same
thing - e.g. `blk_end` vs. `blockcnt` field name used in the old `struct
fba_dump_param` definitions. It also allows us to get rid of two
`uint64_t` casts.

While at it, fix the documentation of `struct eckd_blockptr`.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
9aa368af54 zipl/boot: eckd2/fba: remove two superfluous casts
Remove two superfluous casts.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
2e6cf81c2a zipl/boot: stage3.lds.S: put notes section explicitly at the end
...otherwise `.note.gnu.build-id` will be put at 0x0 (location for s390x
lowcore) if the linker option `--build-id` is used (which is the default
if gcc is used for linking).

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
ae27066c15 zipl/boot: add struct tpi_info to the lowcore struct
Use the `tpi_info` struct definition, similar to the Linux kernel, in
the lowcore struct. This change allows us to use simple assignments
instead of using casts. Additionally, there is the advantage that the
lowcore definition from the s390-tools now looks more similar to the
lowcore definition used by the Linux kernel.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
47fcc71f96 include/s390.h: add STATIC_ASSERTION for size of lowcore
This helps to find possible bugs earlier, e.g. possible bugs in the
changes in the upcoming patches.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
5ac171d224 genprotimg/zipl: boot: Makefile: small refactoring
Move the common `-nostdlib` and `$(NO_PIE_LINKFLAGS) linker options to
the actual linker call. This makes the code easier to maintain.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Marc Hartmayer
67dbf094b2 genprotimg/zipl: boot: Makefile: do not link against shared libraries
It's pretty obvious that we don't want to link against shared libraries
therefore use `-static` for linking.

`ld` call before this change:

  /usr/bin/ld -v -plugin /usr/lib/gcc/s390x-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/s390x-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccLfGZu4.res --build-id --eh-frame-hdr -m elf64_s390 --hash-style=gnu --as-needed -dynamic-linker /lib/ld64.so.1 -z relro -o stage3.exec -L/usr/lib/gcc/s390x-linux-gnu/9 -L/usr/lib/gcc/s390x-linux-gnu/9/../../../../s390x-linux-gnu/lib/../lib -L/usr/lib/gcc/s390x-linux-gnu/9/../../../s390x-linux-gnu -L/usr/lib/gcc/s390x-linux-gnu/9/../../../../lib -L/lib/s390x-linux-gnu -L/lib/../lib -L/usr/lib/s390x-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/s390x-linux-gnu/9/../../../../s390x-linux-gnu/lib -L/usr/lib/gcc/s390x-linux-gnu/9/../../.. -T stage3.lds stage3.o head.o kdump3.o libc.o ebcdic.o ebcdic_conv.o sclp.o sclp_stage3.o kdump.o entry.o

`ld` call after this change:

  /usr/bin/ld -v -plugin /usr/lib/gcc/s390x-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/s390x-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccw0ELAp.res --build-id -m elf64_s390 --hash-style=gnu --as-needed -static -z relro -o stage3.exec -L/usr/lib/gcc/s390x-linux-gnu/9 -L/usr/lib/gcc/s390x-linux-gnu/9/../../../../s390x-linux-gnu/lib/../lib -L/usr/lib/gcc/s390x-linux-gnu/9/../../../s390x-linux-gnu -L/usr/lib/gcc/s390x-linux-gnu/9/../../../../lib -L/lib/s390x-linux-gnu -L/lib/../lib -L/usr/lib/s390x-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/s390x-linux-gnu/9/../../../../s390x-linux-gnu/lib -L/usr/lib/gcc/s390x-linux-gnu/9/../../.. -T stage3.lds stage3.o head.o kdump3.o libc.o ebcdic.o ebcdic_conv.o sclp.o sclp_stage3.o kdump.o entry.o

Fixes: b627b8d8e1 ("Initial s390-tools-2.0.0 import")
Fixes: 3356d6f4fa ("genprotimg: boot: initial bootloader support")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-06-03 18:40:36 +02:00
Dimitri John Ledkov
3669fd4d8a zkey: Add initramfs hook
Add hook script to allow zkey utilities to be used in initramfs.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/42
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Reviewd-by Ingo Franzki <ifranzki@linux.ibm.com>
[hoeppner@linux.ibm.com: removed / in Makefile and updated commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Jan Höppner
b01ef782f0 scripts/dumpconf: Bring installation rules in line with other scripts
Until recently dumpconf might have been installed in two different
locations, /etc/init.d/ and /lib/s390-tools/. As dumpconf is now part of
the helper scripts in the scripts directory, extend the installation
rule and add the %S390_TOOLS_VERSION% wildcard to the script along the
way for correct version output.

The installation rule in the systemd/Makefile is removed, bringing it in
line with cpictl.

Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Jan Höppner
a177ae2439 scripts/dumpconf: Update header of the dumpconf script
Remove the leftovers of the SysV init configuration and replace it with
proper information about the tool. Also add the missing Copyright
statement and remove DUMPCONF_BIN as there is no user.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/132
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Jan Höppner
13fef6dbe0 dumpconf: Move dumpconf tool to scripts directory
Modern distributions use systemd and a corresponding systemd unit file
is provided that handles the dumpconf tool. The tool is also the last
script left in etc/init.d. Move it to scripts and get rid of the init.d
directory altogether.

Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Jan Höppner
508253c666 etc/init.d: Remove SysV related daemon scripts
For cpacfstatsd, cpuplugd, and mon_statd there are still SysV daemon
scripts available. However, modern distributions use systemd and
corresponding systemd unit files are provided and in use for a long time
already.

Remove the daemon scripts for the obsolete SysV init system as they're
not used by modern systems anymore.

Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Matthew Rosato
773d01e674 zdev: Introduce the ap device type
The AP device type initially allows only the setting of type
attributes 'apmask' and 'aqmask'.

Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Matthew Rosato
2da206f5a6 ap_tools: Introduce ap_tools and the ap-check tool
The ap_tools utilities are intended to be used in conjunction with
the mdevctl utility for safely managing and inspecting vfio-ap
mediated devices.  For now, this will consist of the ap-check tool
which will be driven via a call-out from mdevctl to validate a
proposed vfio-ap mediated device change.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Matthew Rosato
bf71e3bb1f libap: Add library for ap / vfio-ap management tools
libap is intended to provide utility functions to be used by
tooling supporting the ap bus and vfio-ap mediated devices.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Matthew Rosato
6f7982dae5 libutil: Introduce util_udev
Move code to read udev files from zdev into a utility library for use by
other tools.

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Matthew Rosato
f64b4087dd libutil: Move some zdev file reading functions into util
In preparation for sharing some zdev udev code with other libraries, move
some file operation code from zdev into util_file.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Matthew Rosato
a739584d6f libutil: add util_exit_code
zdev uses a particular set of exit codes -- In preparation for sharing
some zdev udev code with other libraries, let's also create a libutil
include to specify reusable exit codes.  For now, let's just initialize
it with the codes from zdev we care about.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Thomas Richter
cce5f510c3 cpumf/lscpumf: Add IBM z16 extended counter set definitions
Add IBM z16 extended counter set. For each counter in this set
add the counter number, the short and long description and the
counter number.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Thomas Richter
2515832469 util_arch: Add IBM z16 as known machine
Add IBM z16 as known machine to the architecture definitions.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:27 +02:00
Ingo Franzki
6c5c5f7e55 libseckey: Adapt keymgmt_match() implementation to OpenSSL
OpenSSL commit ee22a3741e3fc27c981e7f7e9bcb8d3342b0c65a changed the
OpenSSL provider's keymgmt_match() function to be not so strict with
the selector bits in regards to matching different key parts.

Adapt the secure key provider's match function accordingly.
This means, that if the public key is selected to be matched, and
the public key matches (together with any also selected parameters),
then the private key is no longer checked, although it may also be
selected to be matched. This is according to how the OpenSSL function
EVP_PKEY_eq() is supposed to behave.

OpenSSL function SSL_CTX_use_PrivateKey() calls the providers match
function to check if the private key specified matches the public key
of the certificate using EVP_PKEY_eq(). EVP_PKEY_eq() includes the
private key into the selector bits here, although the certificate
only contains the public key part.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-17 13:20:26 +02:00
Thomas Richter
736c69379d cpumf/pai: Add support for PAI extension 1 NNPA counters
The Processor Activity Instrumentation facility (PAI) Extension 1
adds support for the counter set for Neural Network Processing Assist
(NNPA) counters.

NNPA counter values are appended as raw data to the data report.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-13 11:42:54 +02:00
Thomas Richter
130880159a libcpumf: Detect PMU pai_nnpa
Add a check to detect Processor Activity Instrumentation (PAI)
Extension 1 facility unit. This covers the counter set for
Neural Network Processing Assist (NNPA) counters.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-13 11:42:54 +02:00
Thomas Richter
d7b1cbad8b cpumf/pai: Add Processor Activity Instrumentation tool
The Processor Activity Instrumentation facility (PAI) uses the
perf_event_open system call to report data and the crypto counter
values. The data can be inspected with the perf tool in a very
generic way using raw data report and a hex dump utility.

The pai tool also uses the perf_event_open system call to record the
data, but uses specialized event attributes for recording detailed
information such as the recording of fork, exit, exec system call
events and context switch events.
Cryptography counter values are appended as raw data attachments.

The pai command can be used for recording and reporting.
Also a list of CPUs can be specified.
The recording ring buffers are created per CPU
and are named paicrypto.XXX where XXX stands for the CPU number.
The numbering scheme has leading zeros, such as 007 for CPU number 7.

For invocation and possible command line options see the man page.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-13 11:42:51 +02:00
Thomas Richter
a58460b5c7 libcpumf: Function to return PMU name
Return the PMU name as found in the sysfs tree given a PMU type number.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-13 11:41:56 +02:00
Thomas Richter
acdce2a7a9 libcpumf: Detect PMU pai_crypto
Add a check to detect Processor Activity Instrumentation (PAI)
facility unit.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-13 11:41:56 +02:00
Sven Schnelle
0981df62c0 cmsfs-fuse: fix enabling of hard_remove option
Since the switch to fuse3 setting the hard_remove option with the
FUSE_LIB_OPT() macro is no longer supported. See libfuse commit
8ee553dac029 ("fuse_new(): don't accept options that don't make sense
for end-users") for details. To fix this, add an appropriate init
function which sets this option.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/131
Fixes: e679a88d88 ("Switch from fuse2 to fuse3")
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Jan Höppner
4e28f6749b Add missing copyright header
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Thomas Richter
5f08033bb8 libcpumf: Fix doxygen comments
Fix the doxygen comments and add a description on the return values.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Marc Hartmayer
8231ec5f38 zipl/boot/Makefile: fix cleanup of linker script dependency files
By default, the Bash file globbing pattern '*' doesn't list files prefixed by a
dot (see https://linux.die.net/man/1/bash). Let's fix this by using the pattern
`.*` instead. While at it, add `--` option to remove possible problems with
leading dashes in filenames.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Marc Hartmayer
9e62005818 genprotimg/boot: disable -Warray-bounds for now
This work around fixes the gcc-12 false positive by disabling `Warray-bounds`:

  CC      genprotimg/boot/stage3a.o
  In file included from stage3a.c:14:
  In function ‘__test_facility’,
      inlined from ‘test_facility’ at ../../include/boot/s390.h:428:9,
      inlined from ‘start’ at stage3a.c:42:7:
  ../../include/boot/s390.h:418:17: error: array subscript 0 is outside array bounds of ‘void[0]’ [-Werror=array-bounds]
    418 |         return (*ptr & (0x80 >> (nr & 7))) != 0;
	|                 ^~~~

Unfortunately, there is currently no better fix available that doesn't result
in larger boot loader code sizes. Given the importancy of the boot loader file
sizes the other fixes aren't acceptable. The Linux kernel shares the
problem (but for performance reasons), take a look at the discussion
https://lore.kernel.org/lkml/yt9dzgkelelc.fsf@linux.ibm.com/ for details.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/130
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Eduard Shishkin
a0dba6bfdb zipl/src: Implement sorting bls entries by versions
This patch implements an additional method of sorting bls entries
by version field and uses it as default one. If sorting by version
fails, then it falls back to the most robust method of sorting by
file names

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Eduard Shishkin
ebc3384b9f zipl/src: make blsdir variable global instead of local
It is used by the next patch.
Specifically, ->filter() and ->sort() callbacks of the scandir(3)
accept only short names of directory entries to be filtered/sorted,
while we need to know absolute names to perform filtering/sorting.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-05-10 13:33:24 +02:00
Jan Höppner
e9bf141264 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-20 13:29:04 +02:00
Jan Höppner
d8b8114e6f New release s390-tools-2.21.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-20 13:29:04 +02:00
Mikhail Zaslonko
c4e4b926b4 zdump/dfi: Fix segfault due to double free
The problem can happen when dfi_s390mv_init_gen() returns with an error
code to dfi_init() in dfi.c.
Double free condition occurs on zg_close() call at the end of the
while loop in dfi_init() if zg_close() has already been called for the
same file handle at the end of open_dump() function in scope of
dfi_s390mv_init_gen() processing.
This global file handle is not closed during init() call for any
other dump formats. Since it is not reopened/reused after open_dump() call
during multi-volume dump initialization, we should not close it at all.

The problem can be reproduced in the following steps:

1) Install multi-volume dump tool

   # zipl -M mvdump.conf
   Dump target: 2 partitions with a total size of 4732 MB.
   Warning: All information on the following partitions will be lost!
      /dev/dasdb2
      /dev/dasdb3
   Do you want to continue creating multi-volume dump partitions (y/n)?y
   Done.

2) Run zgetdump -i using device (not partition) as a parameter without
   taking actual dump.

   # zgetdump -i /dev/dasdb
   free(): double free detected in tcache 2
   Aborted (core dumped)

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-19 18:37:17 +02:00
Niklas Schnelle
6324f62da7 zpcictl: Add option to trigger firmware reset
With "zpcictl --reset DDDD:BB:FF.F" now causing a fully Linux driven
reset where the Linux kernel does an explicit device driver unbind,
disable and re-enable, let's also expose a way to instead have firmware
perform a device reset by issuing an SCLP with SCLP_ERRNOTIFY_RESET.

When firmware is done resetting the device it will then issue an error
notification with PCI Error Code 0x3a indicating successful reset, which
will subsequently cause the new kernel based automatic recovery
mechanism to perform recovery in coordination with the device driver.
This allows resetting devices without unbinding them from their device
driver and thus without losing related block devices or network
interfaces. This may also be used to test the automatic recovery
mechanism.

Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-12 17:18:26 +02:00
Niklas Schnelle
3ade063ea2 zpcictl: Fix race of SCLP reset and Linux recovery
Currently "zpcictl --reset DDDD:BB:FF.F" issues an SCLP call with
SCLP_ERRNOTIFY_AQ_RESET followed by a Linux driven device reset via the
recover sysfs attribute. The latter was introduced with commit
bc0d40c580 ("zpcictl: Initiate recover after reset") because the
firmware driven reset leaves the device in the error state. Now with the
addition of transparent PCI recovery however the situation has changed
as Linux will not leave the device in the error state after the reset
but will instead initiate its automatic recovery flow. With that however
the two mechanisms, automatic PCI recovery and the zpcictl triggered
recovery attribute handler will race against each other.

In practice this is harmless as the automatic recovery is serialized
with the recover attribute and whichever wins the race will do the reset.
The losing side will detect that the original device was removed and
will refrain from causing a double reset.

Letting both mechanisms race against each other is not predictable
behavior though so instead of SCLP_ERRNOTIFY_AQ_RESET issue
a SCLP_ERRNOTIFY_AQ_REPORT_ERROR that will report a device error to the
Support Element but not cause a reset and then predictably reset via the
recover sysfs attribute. If instead a firmware driven reset followed by
the automatic recovery flow is desired the new "--reset-fw" option may
be used.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-12 17:18:26 +02:00
Viktor Mihajlovski
92a3b30323 genprotimg/check_hostkeydoc: allow to disable default issuer check
The default issuer check may fail if the to-be-verified host key
document was issued and signed by an entity not known at the point
in time check_hostkeydoc was released.

In order to allow verification of the chain of trust for an unknown
but otherwise valid issuer, check_hostkeydoc can be called with
the -d command line option.

This commit also enhances the help text by briefly describing the
command line options and fixes a typo.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Viktor Mihajlovski
673ff375d9 genprotimg/check_hostkeydoc: relax default issuer check
While the original default issuer's organizationalUnitName (OU)
was defined as "IBM Z Host Key Signing Service", any OU ending
with "Key Signing Service" is considered legal.

Let's relax the default issuer check by stripping off characters
preceding "Key Signing Service".

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Ingo Franzki
4e2ebe0370 libseckey: Fix re-enciphering of EP11 secure key
The re-enciphering of EP11 asymmetric secure keys does not work.
First, the result of the re-encipher operation of the private key
part must be copied back into the user supplied key token buffer.
Second, the public key part, i.e. the MACed SubjectPublicKeyInfo
(SPKI) structure must also be re-enciphered (i.e. re-MACed), since
the MAC is calculated with the EP11 master key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Marc Hartmayer
78b053326c genprotimg: remove DigiCert root CA pinning
Remove the DigiCert root CA pinning. The root CA used for the chain of trust can
change in the future therefore let's remove this check. If someone wants to
enforce the usage of a specific root CA it can be selected by the genprotimg
command line option `--root-ca $CA`. Make it transparent to the user which root
CA is actually being used by printing the subject name of the root CA to stdout
in verbose mode.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Reviewed-and-tested-by: Nico Boehr <nrb@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Peter Oberparleiter
ab06a5d88a cpictl: Handle excessive kernel version numbers
Some development kernel versions provide an 8-digit date number like
"20220325" in place of the second kernel sublevel, while the data
format used to send this information to the HMC only supports 16 Bit
numbers. As a result, the HMC displays a seemingly random sublevel
number.

Fix this by replacing excessive sublevel numbers with 0 to ensure that
these numbers are handled consistently.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Viktor Mihajlovski
a0a71efde0 fdasd: Fix endless menu loop on EOF
Hitting CTRL-D anywhere will cause fdasd to go into an endless loop
displaying the main menu over and over again. Killing fdasd (e.g.
via CTR-C) is the only way out.
The issue is that read_line() is just ignoring the resulting EOF
condition on stdin. Subsequent invocations of read_line() will return
immediately and thus cause the loop. A simple fix is to reset stdin
after EOF. A caller of read_line() will see the same behavior as for
EOL with no input.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Steffen Maier
b4b2202ff5 dbginfo.sh: collect all places where modprobe.d config files could exist
This can now include /lib/modprobe.d/10-unsupported-modules.conf

Strictly speaking, modprobe would only consider *.conf files inside
those directories, but for consistency with the already existing
collection of /etc/modprobe.d instead of /etc/modprobe.d/*.conf,
do the same for the added missing locations.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Steffen Maier
a26f61c4fe dbginfo.sh: collect config files of systemd-modules-load.service
Recent multipath-tools can depend on this.
a1eabea75e
("multipathd.service: drop ExecStartPre for loading dm-multipath")
92f0893ac1
("multipath-tools: install modules-load.d/multipath.conf")

This can now also include /usr/lib/modules-load.d/s390-pkey.conf
Complements v2.8.0 commit
dffd41943e ("pkey: Support autoloading kernel pkey module").

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-04-06 16:11:19 +02:00
Javier Martinez Canillas
a28b396d9e zipl: make IPL sections defined with BLS to inherit a target field
The target field is required for IPL sections, but the ones populated from
BLS snippets did not have this field. This was only working when using BLS
snippets because IPL sections inherit the target field with "defaultauto".

But that's not the case when using a menu, for example the following zipl
configuration will fail if it's used along with BLS defined IPL sections:
fail when running the zipl tool:

  [defaultboot]
  defaultmenu = menu1

  :menu1
  target = /boot
  1 = linux
  2 = test
  default = 1
  prompt = 1
  timeout = 0

Because "linux" and "test" will be defined using BLS snippets and these
don't have an option to define target fields. Let's make these to always
inherit a target field, either from the [defaultboot] section or a menu
section if there's a defaultmenu defined.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/111
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/113
[hoeppner@linux.ibm.com: Fixed a couple of style issues]
Reported-by: Renaud Métrich <rmetrich@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-18 14:41:43 +01:00
Juergen Christ
0012eaf68e zcryptctl: Fix some typos
Fix typos in usage and error messages.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-18 14:41:21 +01:00
Juergen Christ
c22d282e67 zcryptctl: Add control domain handling
Support control domain handling for custom zcrypt device nodes.

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-18 14:41:21 +01:00
Marc Hartmayer
071522f7d2 editorconfig: py/yaml: use spaces for indentation
Use spaces for the indentation of Python and YAML files.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-18 14:41:21 +01:00
Marc Hartmayer
ae7217806b common.mak: remove LINK and LINKXX
Now that we've concluded that the compiler is used for calling the actual
linker, it doesn't make much sense to select a different compiler for linking.
Even worse, it's prone to error. A naive user might try to compile s390-tools
using clang as follows:

  $ make -C genprotimg CC=clang
  ...
  CC      genprotimg/src/utils/curl.o
  LINK    genprotimg/src/genprotimg
  /usr/bin/ld: genprotimg.o: `stderr@@GLIBC_2.2' non-PLT reloc for symbol defined in shared library and accessed from executable (rebuild file with -fPIC ?)
  /usr/bin/ld: final link failed: bad value
  collect2: error: ld returned 1 exit status

Therefore it makes sense to use the same compiler for linking as well.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Marc Hartmayer
9f6150db34 common.mak: D=1: use -g3 and -ggdb3 compiler options
Level 3 includes extra information, such as macro definitions.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Marc Hartmayer
b39bdfbf6e common.mak: W=1: add multiple compiler warning options
Add multiple compiler warning options if `W=1` is set.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Jan Höppner
71fe58111c s390-tools: Clean up NO_PIE_* flags
Remove NO_PIE_LINKFLAGS and follow the naming convention by using
LDFLAGS for linker flags. Replace all occurrences accordingly.

Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Jan Höppner
5e46632767 zipl: Use the compiler for linking instead of ld
Instead of directly calling ld, it is recommended to call the compiler
to do the linking. Do that and adapt the linker flags accordingly.

This also fixes build issues with newer binutils as -no-pie has never
been a valid option for ld itself.

See:
https://sourceware.org/bugzilla/show_bug.cgi?id=27050
https://bugs.launchpad.net/ubuntu/+source/s390-tools/+bug/1907789

LD has no user anymore and is removed.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/106
Reported-by: Lukas Märdian <lukas.maerdian@canonical.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Steffen Maier
1bd64f5b0f dbginfo.sh: sort list of environment variables for readability
The "detour" with NUL terminated records ensures that sorting
works as expected for environment variables with values containing
one or more lines and thus '\n' as regular record separator.

Reviewed-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Steffen Maier
d311506dc4 dbginfo.sh: add hex FCP LUN to multipath FC addressing
Make use of multipath-tools 0.8.9 commit
("libmultipath: add %L path wildcard for 64-bit hex LUN")
260d7cb411 .
Multipath-tools versions that do not know the format wildcard simply
ignore it and expand to an empty string, so it's backwards compatible.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Steffen Maier
08e4520a4f dbginfo.sh: add multipath info to map paths to FC addressing and prio group
Eases mapping of multipath paths and FCP by-path information
without having to use different tool output and correlate,
such as "multipathd -k'show topo'" and "lszfcp -D".

Possibly the HBA is reported as "[undef]" for zfcp
[without multipath-tools 0.8.9 commit
 ("libmultipath: support host adapter name lookup for s390x ccw bus")
 852a1dfd94 ]
and the FCP LUN needs to be manually converted from the SCSI LUN in h:c:i:l.

While at it, append correlation information for block device name and
major:minor, as well as all information from a standard 'show paths',
which is the path state 3-tuple and next_check,
plus the number of path failures.

Example output:

$ multipathd -k'show paths format "%w|%a|%r|%p|%i|%d|%D|%t|%T|%o|%0|%C"'
uuid                             |host adapter|target WWPN       |pri|hcil     |dev|dev_t|dm_st |chk_st|dev_st |failures|next_check
3600507640081818ab00000000000025e|[undef]     |0x500507680b2581fa|10 |0:0:0:606|sdb|8:16 |active|ready |running|0       |XXXXXX.... 13/20
3600507640081818ab00000000000025e|[undef]     |0x500507680b2581fb|50 |0:0:1:606|sdc|8:32 |active|ready |running|0       |XX........ 4/20
3600507640081818ab00000000000025e|[undef]     |0x500507680b2681fa|10 |1:0:0:606|sdd|8:48 |active|ready |running|0       |XXXX...... 8/20
3600507640081818ab00000000000025e|[undef]     |0x500507680b2681fb|50 |1:0:1:606|sde|8:64 |active|ready |running|0       |XXXXXXX... 15/20

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Harald Freudenberger
46fd42af0c lszcrypt: new option to show the serial numbers of CCA and EP11 cards
The new option -s, long --serial shows the serial numbers of
CCA and EP11 cards.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Harald Freudenberger
a8b0d7ace8 lszcrypt: new options to filter cards/queues only
New options:
  --cardonly
  --queueonly
which filter the output to show only card or queue information.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Harald Freudenberger
a29b3c8997 lszcrypt: new options to show only accel, cca or ep11 cards/queues
New options:
  --accelonly
  --ccaonly
  --ep11only
which restrict the output to only cards/queues with the given mode.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Harald Freudenberger
27dce3317a lszcrypt: add support for checkstop state
Newer kernel show a sysfs attribute chkstop which displays
the checkstop state of a crypto card. This patch enables
support for lszcrypt to display the checkstop state.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:49 +01:00
Harald Freudenberger
4382901daa lszcrypt: show AP bus msg size limit capability
If there is a max_msg_size attribute for the card
the lszcrypt -c option will show this limit as
  AP bus max message size limit xx Kb

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:45 +01:00
Harald Freudenberger
bcbb6fcae6 zcryptstats: add CEX8 support
Add the CEX8 crypto card to the list of known crypto cards.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:45 +01:00
Harald Freudenberger
b16a6d4fe1 lszcrypt: add CEX8S support
Recognize AP type 14 as CEX8S crypto express card.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:11:42 +01:00
Benjamin Block
0d15a07c0a chreipl-fcp-mpath: bundle a pre-cooked version of the man page
On several distributions `pandoc` is not available via the default
repositories, and thus not available in the build environments for the
distribution packages. That means, the man page can't be bundled along
with the packages generated for those distributions.

But since this is a valuable asset for some users, instead of requiring
`pandoc` in order to have a man page be generated during the build, so it
can be installed, bundle a pre-cooked version that corresponds to the
current version of the `README.md` file. This way, the man page can always
be packaged, and is now always installed, even if `ENABLE_DOC` is set to
`0` (the default).

This also means, whenever the `README.md` file is changed, the bundled
man page needs to be regenerated, so it stays in sync. As a safeguard
we also add a checksum of the `README.md` file that is regenerated along
with the man page. This checksum is tested even when `pandoc` is not
available, and the user is notified whenever it runs out of sync (with a
hint as to how to remedy it).

Nothing changes for the compile/installation workflow, if `ENABLE_DOC` is
set to `1`.

Suggested-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-03-09 12:08:24 +01:00
Marc Hartmayer
5394cd363c genprotimg: add PV guest dump support
Sometimes dumping a virtual machine from the outside is the only way to
get the data that is needed. This can be the case if a dumping mechanism
like kdump hasn't been configured or data needs to be fetched at a
specific point. Dumping a protected guest from the outside without help
from FW/HW doesn't yield sufficient data to be useful. Hence we now
introduce Protected Virtualization (PV) dump support.

The PV dump support works by integrating the firmware into the dump
process. New Ultravisor calls are used to initiate the dump process,
dump cpu data, dump memory state and lastly complete the dump process.
The guest's data is fully encrypted and can only be decrypted by the
entity that owns the customer communication key for the dumped guest.
Also dumping needs to be allowed via a flag in the SE header.

This patch adds support for PV guest dumps to genprotimg. To prepare a
PV image in order that the PV guest can later be dumped from the
outside, the user has to provide a customer communication key used for
the dump process and he has to set the corresponding control flag. For
specifying the customer communication key a new command line option
`--comm-key` is added and for enabling/disabling the control flag the
command line options `--enable-dump` and `--disable-dump` are added.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 17:06:33 +01:00
Marc Hartmayer
0906293cd8 genprotimg: --enable-pckmo and --disable-pckmo are mutually exclusive
Declare `--enable-pckmo` and `--disable-pckmo` as mutually exclusive.
Let's define a helper macro for this which allows an easier definition
of mutually exclusive command line flags.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 17:06:33 +01:00
Marc Hartmayer
a9e13a2d69 genprotimg: introduce macro for the control flags and sort them
Introduce a private macro for the calculation of the control flags and
sort the flags by bit value.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 17:06:33 +01:00
Philipp Kern
ee2c6d4160 zipl: Allow optional entries that are left out when files are missing.
Debian carried a patch forever that allowed zipl to run even if not all
menu items had files attached. If a required file is missing for an
entry (e.g. vmlinuz.old or initrd.img.old) and it is marked as
"optional" in the config, the section will be skipped. This allows
zipl to install after bootstrapping, as booting on s390 still relies
on the kernel/initrd symlinks in the root directory.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/2
Signed-off-by: Philipp Kern <pkern@debian.org>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
[sth@linux.ibm.com: adapted patches to latest changes, merged patches]
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Alexander Egorenkov
455ad953a9 zdump: Fix /dev/mem reading
This commit makes zgetdump work with /dev/mem again.
zg_seek() should not attempt to verify the given offset for devices before
issuing lseek() because special devices like /dev/mem report 0 in
stat.sb_size.

$ zgetdump -i /dev/mem
zgetdump: Trying to seek past file end "/dev/mem"

Fixes: 11e78cada5 ("zdump: catch attempts to seek past end of file in zg_seek()")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
02a0d12988 dbginfo.sh: (re)group commands by block/scsi
This change will group the commands executed for block and scsi devices
into a section with a comment.
By grouping, we intend to enhance the handling in our runtime.out file
and help to understand the purpose of command groups.

In addition we did get feedback for promoting some commands to the top.

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
be47b51890 dbginfo.sh: (re)group commands by z device
This change will group the commands executed for Z device subsystem
into a section with a comment.
By grouping, we try to enhance the handling in our runtime.out file and
help to understand the purpose of command groups.

In addition we did get feedback for promoting some commands to the top.
lspci -t was added on request of SMEs during the discussions

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Acked-by: Nicklas Schnelle <Niklas.Schnelle@ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
2677a4182d dbginfo.sh: (re)group commands by system state
This change will group the commands executed for overall state into a
first section with a comment.
By grouping, we intend to enhance the handling in our runtime.out file
and help to understand the purpose of command groups.

In addition we did get feedback for promoting some commands to the top.

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
812df795c3 dbginfo.sh: (re)group commands by topic
This change will group the commands executed for crypto, special SW or
specific for a distro into sections with a comment.
By grouping, we intend to enhance the handling in our runtime.out file
and help to understand the purpose of command groups.

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
a0d6edf03c dbginfo.sh: (re)group commands by long output
This change will group the commands with long output into two
sections with a comment.
By grouping, we intend to enhance the handling in our runtime.out file
and help to understand the purpose of command groups.

We did get feedback for moveing some independent long output files to
the end for speed up the scrolling in the upper parts.
Files which already have a separate output file are bundled in a
separate group at the end.

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
81920f7cfd dbginfo.sh: (re)group commands for network
This change will regroup & reorder the commands executed for network.
By grouping, we intend to enhance the handling in our runtime.out file
and help to understand the purpose of command groups.

In addition we did get feedback for promoting some commands to the top.
"ip -br a" was added on request of SMEs during the discussions

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Acked-by: Sandy Winter <WINTERA@de.ibm.com>
Acked-by: Stefan Raspl <stefan.raspl@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Thomas Richter
40dd63e2ac cpumf/lshwc: Fix missing CPU list invocation
When lshwc is invoked with
 # ./lshwc -a :P
 lshwc: ioctl S390_HWCTR_START: Invalid argument
 #
it returns an error instead of listing all problem state counters
of all online CPUs. The reason is an empty CPU list when it is
omitted and only a counter set is specified. Fix this.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
a8579a0727 dbginfo.sh: replace indents with 8char tab
cleanup of indents according to the guidlines
this patch has no logic changes

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
2ab27bdaf2 dbginfo.sh: update copyright date
adjust second year field on recent updates

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Thomas Richter
03fef264bd cpumf: Remove unneeded defines.h
With the introduction of libcpumf/libcpumf.a library there is no need
for this file anymore. Its defines have been moved to
include/lib/libcpumf.h are obsolete.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Thomas Richter
927a48e607 cpumf/lshwc: Use libcpumf.a library functions
Use new library functions defined in libcpumf/libcpumf.a

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Thomas Richter
fbcb3f384a cpumf/chcpumf-lscpumf: Use libcpumf.a library functions
Use new library functions defined in libcpumf/libcpumf.a

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Thomas Richter
c7fe21b019 libcpumf: Create library libcpumf for CPU Measurement functions
Add a function to detect the existence of the CPU Measurement Sampling
Facility on a system.
Add a function which extracts the CPU Measurement Sampling Facility
characteristics on a system, such as
 - minimum sample speed
 - maximum sample speed
 - current CPU speed
 - basic sample size in bytes
 - diagnostic sample size in bytes

Add a function to detect the existence of the CPU Measurement Sampling
Facility on a system and return the current sampling buffer management
characteristics, such as:
 - minimum supported sampling buffer size
 - maximum supported sampling buffer size

Add a function to detect the existence of the CPU Measurement Counting
Facility on a system.
Add a function which extracts the CPU Measurement Counting Facility
characteristics on a system, such as
 - counter first version number
 - counter second version number
 - counter set authorization level

Add a function the returm the PMU type number of a CPU Measurement
Facility device driver. These numbers may vary between boots.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
50a4740443 dbginfo.sh: replace "which" by builtin command "type" for cmd checks
'which' tool is packaged separately from other core tools and there will
likely be scenarios where this check will fail because 'which' is
unavailable.
The "type" is builtin itself and should solve this problem.
For a built in command, we will not suppress error out -> removing 2>&1.
On this replace - in call_run_command - get cmd_type as variable only once

Reported by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
164d4817ec dbginfo.sh: check existence of dump2tar before executing
a missing dump2tar command did show misleading error messages
now check it and give clear messages

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
abec41f514 dbginfo.sh: alphabetic order of log- and config files
as order itself does not matter for collection of log and config files,
we decided to use alphabetic order for better maintenance

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
fcb503ea3c dbginfo.sh: sync excludes in sysfs data collection
critical paths in dump2tar data collection have been already excluded -
this update will sync the excludes in the fall back, running in case
dump2tar is missing or failing on a system
By this we also sync the filtering to match exact the same pattern.

Reported by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Sa Liu <saliu@de.ibm.com>

Fixes: 12c84469fd ("dbginfo.sh: exclude reading page_idle/bitmap sysfs
attribute")
Fixes: b627b8d8e1 ("Initial s390-tools-2.0.0 import")

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
2eea614bbf dbginfo.sh: unify indents - prettify code
adopt all indents to have the same setting overall - NO logic changes !
tooling: vim used with setting "shiftwidth=8",expandtab,autoindent
  commands "gg=G",":retab"
  some additional line brakes to stay below 100 chars
  and one line added manual before "collect_procfs"

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Joern Siglen
3a13cb43f2 dbginfo.sh: unify console output
use same look over all output

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Peter Oberparleiter
e8fca95592 zdev: Fix off-by one errors in cio_ignore handling
chzdev fails to generate correct cio_ignore udev-rules for a CCW device
with device number 0xffff. Also chzdev aborts due to a segmentation
fault when a CCW device with CSSID 0xff is configured. Both issues are
caused by off-by-one errors while interpreting CCW device ID limits
CSSID_MAX, SSID_MAX and DEVNO_MAX.

Fix these errors by correctly interpreting CCW device ID limits.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-21 12:54:34 +01:00
Jan Höppner
b5604850ab Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-04 12:34:47 +01:00
Jan Höppner
18efac6306 New release s390-tools-2.20.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-04 12:34:47 +01:00
Jan Höppner
18f8db2225 bin/mk-authors: Run only on master branch history
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-04 12:34:47 +01:00
Marc Hartmayer
f1a13749df genprotimg: pv_comp: remove useless function
The endianness handling is already done before, so there is no need for
this function. Let's remove the useless `uint64_to_uint8_buf` function.

Suggested-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-04 09:50:29 +01:00
Matthew Rosato
b5da337d1e zdev: check for errors when removing a devtype setting
Currently, a device type setting being --removed from both the active and
persistent configuration via 'chzdev -t' can result in a scenario where
the setting is not removed from the active configuration (and an error
message is presented) but chzdev still proceeds to remove the setting from
the persistent configuration.
Update this logic so that devtype_remove_settings behaves the same way as
device_remove_settings and only perform the removal when no errors are
encountered.

Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-04 09:50:29 +01:00
Peter Oberparleiter
a67888f36a cpictl: Report extended version information
Extend cpictl to report Linux distribution type and version information,
and another sublevel of Linux kernel version data via the system level
field of the SCLP CPI firmware interface. This data is intended to be
decoded by the IBM Z HMC web-UI to provide users a more detailed view of
Linux software levels installed in LPARs.

For this purpose, the format of the 64-bit system level word is extended
in a compatible way, that is, the meaning of existing fields remains
unchanged while additional data is added to previously unused fields.

The new format is defined as 0xabccddeeeeffgghh, where:
 - a=statistics flags
 - b=distro id
 - c=distro major version
 - d=distro minor version(s)
 - e=kernel sublevel 2
 - f=kernel version
 - g=kernel patchlevel
 - h=kernel sublevel 1

This format will be automatically reported for supported distributions
based on data from /etc/os-release. As before, users can override the
data by specifying a custom system level word in /etc/sysconfig/cpi.

To support manual specification of new data fields, the format of
cpictl's -L command line option and the CPI_SYSTEM_LEVEL environment
variable are extended as follows:

 - 0x<level>

   Specifies the system level as 64 bit hex value

 - [[[flags:]distro_id:distro_version:]kernel_version]

   Specifies the system level as list of optional fields. Any field that
   is omitted is initialized with automatically determined values.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Marc Hartmayer
e1f174ae22 zipl/libc.h: declare start as __noreturn function
Declare `start` as __noreturn function since the function doesn't
return. Use the gcc/clang built-in function `__builtin_unreachable` to
make clear that `lpsw` and `diag308(DIAG390_IPL, NULL)` doesn't
return (see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html and
https://clang.llvm.org/docs/LanguageExtensions.html#builtin-unreachable).

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Marc Hartmayer
7503d88b3b genprotimg/boot: add extended kernel command line support
In the past s390 used a fixed command line length of 896 bytes. This has
changed with newer Linux kernels. There is now a parm area indicating
the maximum command line size. This parm area has always been
initialized to zero, so with old kernels this field would read zero and
we must then assume that only 896 bytes are available.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Marc Hartmayer
43039943cd genprotimg/boot: remove useless volatile keyword
There is no reason to declare the variable @psw on the stack as
volatile.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Marc Hartmayer
b2e02d202a Add EditorConfig configuration
EditorConfig (https://editorconfig.org/) defines a file format for
defining coding styles. The most common editor do either provide native
support or via plugin support for EditorConfig.

This patch adds an EditorConfig configuration for s390-tools.

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Peter Oberparleiter
1faa5d2957 zdev: Fix path resolution for multi-mount point file systems
zdev provides path resolution logic to determine which z-specific
devices contribute to the file system mounted at a specific mount point.
This logic is used by command-line option --by-path, but also to
determine the list of devices needed to enable the root file system.

Path resolution fails when a device provides multiple mount points such
as, for example, when using btrfs subvolumes, or when mounting the same
file system at multiple mount points. The failure is caused by zdev
relying on the MOUNTPOINT attribute of lsblk's output which only
contains a single mount point.

Fix this by making use of lsblk's MOUNTPOINTS attribute that contains
the full list of mount points. Note that MOUNTPOINTS was only introduced
with util-linux v2.37, therefore a fall-back to the old format is
needed.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/129
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
Reported-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Thomas Richter
d62e075450 cpumf/lshwc.c: Fix CPU list parameter setup for device driver
lshwc allows to specify a list of CPUs, for example

   # ./lshwc -a 2-3,66-68:b
   Date,Time,CPU,CPU_CYCLES(0),INSTRUCTIONS(1),L1I_DIR_WRITES(2),....
   2022-01-21,12:51:54,CPU2,68762,20999,283,14157,601,87255
   2022-01-21,12:51:54,CPU3,70514,21179,288,10654,586,90188
   2022-01-21,12:51:54,CPU4,48504,21018,141,7831,438,78494
   2022-01-21,12:51:54,Total,187780,63196,712,32642,1625,255937
   #

However, as seen on the output, the CPU list is incorrect. It shows
CPUs 2, 3 and 4 even when only CPU 2 and 3 was requested. CPUs 66, 67
and 68 have not been online and can not be displayed.

What happens is a wrong parameter conversion for the device driver.
CPUs 66, 67 and 68 are passed to the device driver as CPUs 2 3 and 4
and that data is returned.

Fix this and submit a CPU list with correct bit ordering:

   # ./lshwc -a 2-3,66-68:b
   Date,Time,CPU,CPU_CYCLES(0),INSTRUCTIONS(1),L1I_DIR_WRITES(2),...
   2022-01-21,12:59:18,CPU2,50753,18042,246,10972,494,60345
   2022-01-21,12:59:18,CPU3,54002,20390,232,9219,511,66033
   2022-01-21,12:59:18,Total,104755,38432,478,20191,1005,126378
   #

Reported-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Marc Hartmayer
983233730c zipl: add missing static declarations
Fix Sparse findings like:

 warning: symbol 'hash_table_find' was not declared. Should it be static?

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00
Vineeth Vijayan
ad024c06e1 zdev: modify the lsblk output parser in lszdev
Since version 2.37.x, with the commit 58b510e58 ("libsmartcols: sanitize
variable names on export output"), util-linux changes the output
characters of lsblk, where the ":" is replaced with an "_". Align the
lsblk output parser function in lszdev as per this change.

Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Suggested-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Tested-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Eduard Shishkin
e2843232d5 zipl/src: make gcc 11.2 happy
Add a prophylactic check that @filename is not NULL before its
dereference.

This addresses the following warning (which is a false positive,
since stat(2) is never called with NULL file name):

job.c:514:13: warning: argument 1 null where non-null expected
[-Wnonnull]
514 | if (stat(filename, &stats)) {
| ^~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/features.h:488,
from /usr/include/errno.h:25,
from job.c:13:
job.c: In function 'check_job_ipl_data':
/usr/include/sys/stat.h:227:12: note: in a call to function
'stat' declared 'nonnull'
227 | extern int __REDIRECT_NTH (stat, (const char *__restrict __file,

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/127
Reported-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Viktor Mihajlovski
b79d17d233 cpictl: Suppress messages for unwritable sysfs files
Under certain conditions, e.g. in a KVM guest, a write operation
to /sys/firmware/cpi/set can result in an error message to
stderr while the script returns with a zero exit code, indicating
success.

This can cause confusion if cpictl is called by systemd due to
the existence of a writable /sys/firmware/cpi/. Let's silence
cpictl when writing to the /sys/firmware/cpi/set. This is OK, as
nothing can be inferred from failure or success from the perspective
of the invoking Linux instance.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/120

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
11b401b599 zipl: move and make check for maximum command line length dynamic
The maximum command line length is now dependent on the kernel image
that is loaded. Therefore move the check to check_common_ipl_data().
This function now reads the new kernel image, and check whether the
command line length is in the allowed range.

The command line size limit in zipl is now set to 64k, which is hopefully
enough.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
69c5ee2e52 zipl: no need to check for NULL when calling free()
free() accepts NULL pointers, so no need for an extra check.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
3ee625d74f zipl: add check_common_ipl_data()
There are two places where we check whether the initrd and kernel image
is readably. Add one helper function that checks this. This is also a
preparation for the extended command line handling, so that we have to
add that code in only one location.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
832268ecb0 zipl: add error_text_section()
There are quite a few places that do:

if (section == NULL) {
	error_text("file '%s'", file);
} else {
	error_text("file '%s' in section '%s'", file, section);
}

Add a helper function to deduplicate that.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
5fb6434548 zipl: add get_common_components() and finalize_common_address_data()
Most of get_*_components() and finalize_*_address_data() is the same
for normal ip, tape and dump types, so we can unify that.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
5894e3f700 zipl: add free_common_ipl_data()
Add a small helper function to free the common ipl data to avoid
having the same code duplicated multiple times. Also remove the if()
check before the free as it is allowed to pass NULL pointers to free().

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
e384f06014 zipl: add common ipl data
Each ipl type takes at least a kernel image, parameter line and initrd
parameter. This is duplicated all over the place in the current
implementation. To simplify this, add struct job_common_ipl_data which
will hold this data.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
1627c6a39f zipl: Support command lines longer than 896 bytes in bootloader
This adds support for long command lines. The boot loader stages
will no longer use a fixed limit when copying the command line, but
will use the maximum length from the kernel image that is being loaded.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
bb8f17a7da zipl: fix tape boot
The assembly code in tape0.S loads the kernel from tape to offset 0x4000.
After loading the kernel it loads the parm file and stores it to the
address provided by zipl. zipl doesn't know about the 0x4000 load offset,
so this address is inside of the kernel image and will silently corrupt
the loaded image in memory.

Fix this by copying the kernel to the final destination before loading
the parm files and initrd. We can do this because we can strip the first
0x10000 bytes like the zipl C code does for non-tape IPL.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
8b3d3dd4bd zipl: rename COMMAND_LINE_SIZE to LEGACY_COMMAND_LINE_SIZE
Preparation to support command lines that are longer than 896 bytes.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
a5c04e5746 zipl/boot: rewrite setup_commandline()
No need to use memcpy() and carry the length around all the time.
Switch to using strlcpy() to simplify the code.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
c5ae1a41da zipl/boot: add strlcpy implementation
add strlcpy from libutil to the zipl boot mini libc.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:02 +01:00
Sven Schnelle
970c697983 zipl: move command line processing into its own function
Makes the code easier to read.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland<sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:01 +01:00
Sven Schnelle
cff4b0384f zipl: move secure boot verification into its own function
Makes the code easier to read.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-01-20 09:35:01 +01:00
Dan Horák
724f800dc5 cpictl: fix permissions
The regular 0755 permission should be sufficient for cpictl.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=2024102
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/124
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 21:48:58 +01:00
Graham Inggs
4cdfe91ca9 README.md: refer to fuse3 instead of fuse
Update READMEs to refer to fuse3 instead of fuse.
Also, update minimum versions and FUSE upstream's homepage

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
a44db0f367 zdump, man pages: remove references to 'nonempty' option
In FUSE 3, nonempty is always true, and has been removed.
By default it is false on FUSE 2.

Therefore, remove 'nonempty' option from zdump and references to
the same in man pages.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
03ddcd6267 zdsfs: fix compiler warnings
Compiling against fuse3 shows 'incompatible pointer type' warnings due
to the additional function arguments in the new API.

Therefore, adjust the declarations of zdsfs_getattr() and
zdsfs_readdir() to match.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
5c468a220e hmcdrvfs: fix compiler warnings
Compiling against fuse3 shows 'incompatible pointer type' warnings due
to the additional function arguments in the new API.

Therefore, adjust the declarations of hmcdrv_fuse_getattr(),
hmcdrv_fuse_readdir() and hmcdrv_fuse_init() to match.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
4ba65eaa74 cmsfs-fuse: fix compiler warnings
Compiling against fuse3 shows 'incompatible pointer type' warnings due
to the additional function arguments in the new API.

Therefore, adjust the declarations of cmsfs_getattr(), cmsfs_readdir(),
cmsfs_utimens(), cmsfs_rename() and cmsfs_truncate() to match.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
58cae4fecd zdump: fix compiler warnings
Compiling against fuse3 shows 'incompatible pointer type' warnings due
to the additional function arguments in the new API.

Therefore, adjust the declarations of zfuse_getattr() and
zfuse_readdir() to match.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
9b84de4b0a hsavmcore: fix compiler warnings
Compiling against fuse3 shows 'incompatible pointer type' warnings due
to the additional function arguments in the new API.

Therefore, adjust the declarations of vmcore_fuse_getattr() and
vmcore_fuse_readdir() to match.

GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Signed-off-by: Graham Inggs <ginggs@debian.org>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Graham Inggs
e679a88d88 Switch from fuse2 to fuse3
Fuse 3.0.0 was released in December 2016. The last maintenance release
from the 2.9 branch was in January 2019, and users are encouraged to
transition to the actively developed 3.x branch.
https://github.com/libfuse/libfuse/releases/tag/fuse-2.9.9

Therefore, adapt cmsfs-fuse, hmcdrvfs, hsavmcore, zdsfs and zdump to
the new API, and adapt associated Makefiles to link the new library.

Closes: https://github.com/ibm-s390-linux/s390-tools/issues/116
GitHub-ID: https://github.com/ibm-s390-linux/s390-tools/pull/117
Link: https://bugs.launchpad.net/ubuntu/+source/s390-tools/+bug/1935666
[hoeppner@linux.ibm.com: Add links to commit message]
Signed-off-by: Graham Inggs <ginggs@debian.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Benjamin Block
6acf6ed76d chreipl-fcp-mpath: fix directory dependencies for parallel make install
When `make install` is called with parallel execution enabled (e.g.:
`-j2`), the dependencies for the necessary directories are not correct.
The `install` target depends on `install_dirs`, which creates the
necessary directories, and needs to run before any of the
`chreipl-fcp-mpath-install*` targets that have prerequisites on these
directories; but the `chreipl-fcp-mpath-install*` targets have
indirectly the same "hierarchy level" as `install_dirs`, and no direct
dependency on it.

Simplified it looks like this:
    install: install_dirs chreipl-fcp-mpath-install
    chreipl-fcp-mpath-install: chreipl-fcp-mpath-install-udev-rules ...

This works fine with only one job, as `install_dirs` will be satisfied
first, before recursing into any other branch of the dependency tree.
But if we have more than one job, there is nothing in the rules that
prevents Make from working on both branches - `install_dirs` and
`chreipl-fcp-mpath-install` - at the same time, and so
`chreipl-fcp-mpath-install-udev-rules` might run before `install_dirs`,
and end up with a unsatisfied dependency:
    make[2]: *** No rule to make target '/usr/lib/udev/rules.d', needed by 'chreipl-fcp-mpath-install-udev-rules'.  Stop.

Fix this by adding direct dependencies on `install_dirs` for all the
directory prerequisites of `chreipl-fcp-mpath-install*` targets. This
way Make will need to satisfy `install_dirs` before it can work on any
of the other targets, and so the necessary directories will be created
in the correct order.

Reported-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Marc Hartmayer
e7abf256f6 genprotimg: use NULL and not 0 for a NULL pointer
This fixes the sparse warning:

utils/crypto.c:443:68: warning: Using plain integer as NULL pointer

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
0d407904dd zdump/zg: Convert print macros to functions which can be mocked
This change allows mocking of print macros in unit tests.
Being able to do this in unit tests, enables us to catch output from
zgetdump functions and test it.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
2238eb820f zdump/zg: Save errno in _zg_err_errno()
_zg_err_errno() should save the current errno value before calling any
libc functions because they could change it. Failing to do so, may result
in _zg_err_errno() displaying an incorrect error message.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
81013f0c70 zdump/zg: Convert error and abort macros to functions which can be mocked
This change allows mocking of error/abort macros in unit tests.
Being able to do this in unit tests, enables us to test error conditions w/o
terminating the unit test runner.

The new error functions do not have "noreturn" attribute because
this would make mocking of them in unit tests impossible. We must not
compile these functions as noreturn because we need to return from them
in unit tests and returning from a noreturn function is an undefined
behavior in the C++ standard!

For more details:
- ISO/IEC 14882:2017, Chapter 10.6.8 "Noreturn attribute""
- https://en.cppreference.com/w/cpp/language/attributes/noreturn.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Marc Hartmayer
697c5dc405 zdump: write_dump: use FILE *
Use the more common `FILE *` for writing to the output.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Marc Hartmayer
e9deec4c62 zdump: copy: add support for file output
It is unusual to write the file output from a tool to stdout. Therefore
add a positional argument to the zgetdump convert action where the
output file can be specified. If no positional argument is given the
output is written to stdout as before and therefore there is no change
in the default behavior.

If the file output already exists an error is returned. The reason for
this is to avoid the situation where an existing dump is accidentally
overwritten by the user.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
d60b7770fd zdump/zg.h: Remove extern keyword from function declarations
The keyword extern before a function declaration is not required with
modern C compilers.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
70925f9aff zdump/df_elf: Introduce symbolic names for note names
To reduce code duplication.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
ef88fac874 zdump: Extract common ELF routines from dfo_elf and move to df_elf
The primary goal of this change is to split DFO ELF module into
multiple smaller ones for better unit testability.

The change doesn't introduce any functionality changes, just shuffling code
around.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Alexander Egorenkov
4bd16ba8ea zdump: Extract dfo_mem_chunk interface from DFO
The primary goal is to separate DFO code into multiple smaller modules
and make it unit testable.

This refactoring only moved the code around w/o changing any functionality.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-12-09 16:19:25 +01:00
Steffen Maier
f6a7da141c dbginfo.sh: fix missing syslog for step create_package
Without the fix, readers of syslog / systemd-journal can erroneously
think that dbginfo.sh was incomplete because the last logged step is
"17 of 18".
The fix also makes the missing line appear in dbginfo.log inside the
generated DBGINFO....tgz.
s390-tools v2.17.0 commit b7807d0195 ("dbginfo.sh: Add KVM commands
and rework data collection") turned create_package into a numbered
step.

Snippet of terminal output:

...
17 of 18:  Postprocessing
18 of 18:  Finalizing: Creating archive with collected data
Collected data was saved to:
 >>  /tmp/DBGINFO-....tgz  <<
Please review all collected data before sending to your service organization.

Syslog before:

...
dbginfo.sh[...]: 17 of 18:  Postprocessing
dbginfo.sh[...]: Data collection completed

Syslog after:

...
dbginfo.sh[...]: 17 of 18:  Postprocessing
dbginfo.sh[...]: 18 of 18:  Finalizing: Creating archive with collected data
dbginfo.sh[...]: Data collection completed

Fixes: b7807d0195 ("dbginfo.sh: Add KVM commands and rework data collection")
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Benjamin Block
1bbd34e500 chreipl-fcp-mpath: don't compress the manpage before installing it
Remove the call to `gzip` before installing the manpage during the
`make install` call. What and if compression is done should be handled by
the distribution tooling.

This also removes a dependency for the build process.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Benjamin Block
c2f8988444 chreipl-fcp-mpath: remove shebang from chreipl-fcp-mpath-common.sh.in
`chreipl-fcp-mpath-common.sh.in` is never executed, only used as argument
for `source` in the udev helper scripts, so the shebang is unnecessary, and
might be confusing.

Also, tools like `rpmlint` from the rpm software management will complain
about this; e.g.:
  s390-tools-chreipl-fcp-mpath.s390x: W: non-executable-script /usr/lib/chreipl-fcp-mpath/chreipl-fcp-mpath-common.sh 644 /bin/bash

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Alexander Egorenkov
d2990db15f zdump/df_elf.h: Remove unused header include
df_elf.h doesn't use anything from dfo.h

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Marc Hartmayer
fd3d79335a zdump: dfo_elf: get rid of file local static data
Remove the need to have global file local static data.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Marc Hartmayer
07b3837e68 zdump: dump_chunks_init: replace 0 with off variable
...to make clear why `off` is initialized to 0 and that all calls to
`dfo_chunk_add` occur for the same reason. For consistency reasons adapt
the `off` value calculation as well.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Marc Hartmayer
13a1227a02 zdump: notes_init: rename some parameters
Rename the parameter `ptr` of `notes_init` to something meaningful. Since
it points to the start of the notes segment rename it to `segment_start`.
In addition, improve the documentation for the function.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Marc Hartmayer
52118a8d02 zdump: loads_init: refactor the code
Use `mem_chunk->size` instead of recalculate it. In addition, assign
`p_vaddr` to `p_paddr` to make clear that they must be equal and rename the
parameter `load_offset` to `elf_offset` to make clear that the offset in
the ELF vmcore file is meant. Finally rename `loads_init` to
`load_phdrs_init`.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Marc Hartmayer
ee89b850fe zdump: dfo_elf: notes_init: use PTR_DIFF
Use `PTR_DIFF` since this is exactly what is done here.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Marc Hartmayer
5160f41079 zdump: PTR_(SUB|ADD) cast result to void pointer
This cast makes the macros easier to use without getting compiler warnings.

e.g.

dfo_elf.c: In function 'dfo_elf_init':
dfo_elf.c:343:20: warning: assignment to 'Elf64_Phdr *' from incompatible pointer type 'char *' [-Wincompatible-pointer-types]
  343 |         phdrs_load = PTR_ADD(phdr_notes, sizeof(Elf64_Phdr) * phdrs_notes_count);

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Steffen Eiden
5b0115fdb4 zdump: refractor PTR_DIFF
PTR_SUB already implements subtraction of pointers. Let's reuse it.

Suggested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-17 15:48:22 +01:00
Jan Höppner
ae305b5158 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 17:05:37 +01:00
Jan Höppner
04407d24fc New release s390-tools-2.19.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 17:05:37 +01:00
Jan Höppner
bcb8ea09d1 lshwc: Fix compile error for gcc <8.1
With gcc < 8.1 the following compile error occurs:

lshwc.c:52:37: error: initializer element is not constant
 static unsigned int read_interval = ioctlsleep, cfvn, csvn, authorization;
                                     ^~~~~~~~~~

Even though this gcc bug was fixed in gcc 8.1+, change the constant
definition to a #define to make the tool compile with older compilers as
well.

Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66618
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
88619b6dba chreipl-fcp-mpath: documentation and man page
Add a README.md for chreipl-fcp-mpath and infrastructure to build and
install a man page generated from the README.md. Building and installing
of the man page is only done when supplying the make option `ENABLE_DOC=1`
(per default disabled). The `pandoc` utility is used to build the man page.

The README.md is reused since there is no other tool or command as part of
chreipl-fcp-mpath that needs to be documented in a separate man page.

Also add information about chreipl-fcp-mpath to the main README.md and
CHANGELOG.md.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
e127b89624 chreipl-fcp-mpath: optional dracut config to bundle toolset into initrd
Add a dracut configuration file that might optionally be installed along
with the toolset (per default to: $(USRLIBDIR)/dracut/dracut.conf.d). It
causes the udev rules and helper scripts to be included into an initial
ramdisk, when (re-)built with dracut; along with any dependency.

This is only done when passing `HAVE_DRACUT` set to 1 during the
installation (default is 0), e.g.: make install HAVE_DRACUT=1.

Enabling the toolset during the initial ramdisk phase has the advantage
that paths can be audited earlier in the life cycle of this Linux
runtime, e.g. to record the WWID in the ID-file.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
3591b94c42 chreipl-fcp-mpath: try to change the re-IPL target if the old one went away
In the final step of the udev rules toolset, we either know that the
current event subject is the re-IPL target, a dm-multipath device with
the re-IPL target, or represents the same volume based on its WWID. As
such it is a candidate to replace the current re-IPL target.

The new helper `chreipl-fcp-mpath-try-change-ipl-path` will use the
subject itself - in case it is a single scsi disk -, or the dm-multipath
device, to test whether there is a path in a good state.

"Good state" is based on the zfcp device driver state
(<SDEV>/zfcp_failed, <SDEV>/zfcp_in_recovery), the scsi_transport_fc
port state (<SDEV>/../../fc_remote_ports/rport-*/port_state), and the
scsi device state (<SDEV>/state). A path is only considered if they all
indicate a device in good conditions.

If such a path is found, the helper will try to set it as new re-IPL
target regardless of whether the current re-IPL is still in good shape
or not. This is by design, and done to reduce complexity in further
state checking, and prevention of races with overlapping events in udev
(when executing in parallel workers).

Whenever a new re-IPL target is selected and set in
/sys/firmware/reipl/fcp/{device,wwpn,lun}, the helper will also update
the records in the ID-file - otherwise they might appear as stale, when
they aren't.

This step in the udev rule processing might also result in log messages
written to the syslog (using the utility `logger` from util-linux;
writing to /dev/log).

In case the re-IPL target is changed, a message with level notice is
logged, informing about the new target.

In case no good path is found as part of a dm-multipath device, a
message with level critical is logged, as it might result in a failed
re-IPL if no path is available.

Lastly, when changing the information in /sys/firmware/reipl/fcp/ fails
for whatever reason, a message with level alert is logged, as the
written information might be inconsistent and must be audited/corrected
manually by an operator.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
2a29a28f78 chreipl-fcp-mpath: if event subject is not re-IPL target, test if WWID matches
When the first test, whether the current event subject represents the
re-IPL target failed, we attempt a second test, using the recorded WWID
of a previously successful attempt.

The new helper `chreipl-fcp-mpath-is-ipl-vol` utilizes the information
previously stored in the ID-file (read under lock via `flock`).

The recorded WWID is compared with the one of the event subject; if it
matches we know that it addresses the same volume, and might be used as
alternative re-IPL target.

Additionally we also compare the current re-IPL triplet with the one
recorded in the ID-file. If it doesn't match anymore, we assume the
recorded WWID is stale - e.g., because the operator changed the re-IPL
target manually - and the previous check invalid.

If both the WWID match, and the re-IPL triplet is still the same as
previously recorded, the toolset may continue with the subject, and use
it as replacement for the current re-IPL target.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
cb831aea44 dbginfo.sh: collect config- and debug-data for chreipl-fcp-mpath
When built with `D=1` chreipl-fcp-mpath automatically creates debug data
for the helpers that run during udev event processing. This is the only
way to effectively debug what is happening during event processing in
chreipl-fcp-mpath.

Collect this data under its default path in /run/udev/.

Also collect the chreipl-fcp-mpath statefile which contains WWID, Device
Bus-ID and LUN of the last path that was detected to represent a FCP
re-IPL device.

Suggested-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
04be704083 chreipl-fcp-mpath: record the event subject WWID if it repr. the tgt
When we have identified the current event subject to represent the
re-IPL target, we record its WWID for future identification in a
stateful ID-file (per default: /run/udev/chreiplzfcpmp-ipl-volume-id). In
addition to the WWID, we also record the current re-IPL triplet
(<Dev-Bus-ID>:<WWPN>:<LUN>), so that when that changes - e.g. due to an
operator manually changing the re-IPL target -, we know that the
recorded WWID is stale.

This record may be used in cases when the current re-IPL target is
completely gone from the system, so we can't used it as comparison
object for when events arrive for paths that go to the same volume, but
don't have the same I_T_L nexus. They however have the same WWID. We
may use these (new) paths as replacement for the one that is completely
gone.

The new helper `chreipl-fcp-mpath-record-volume-identifier` uses the
kernel scsi-device attribute `wwid` as source for the WWID (verbatim).

As with reading the re-IPL firmware information, when writing to the
ID-file, a lock is taken via `flock`, to prevent overlapping
writes/reads to the file.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
1bcfcd3253 chreipl-fcp-mpath: test if event subject represents re-IPL target
Now that we know that the system uses s390x IPL and the current re-IPL
target is from FCP, whenever we get a udev event that indicates a path
state changed, we have to figure out whether it affects the path that is
currently set as re-IPL target, or goes to the same volume (so we might
use it as alternative re-IPL path).

Add a new helper `chreipl-fcp-mpath-is-ipl-tgt` for this task.

Based on the information provided in
/sys/firmware/reipl/fcp/{device,wwpn,lun} it figures out whether the
current event subject has the same triplet <Dev-Bus-ID>:<WWPN>:<LUN> (in
T10 SCSI: I_T_L nexus), or whether one of its parts (in case of
dm-multipath) has.

If true, we know for sure, that we deal with an event affecting the
current re-IPL setting, and continue.

When accessing the re-IPL firmware information a lock is taken via the
`flock` utility (from util-linux). This is done so concurrent changes
from the toolset, that are added in a later commit, don't result in
inconsistent reads.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
2dbaf9f991 chreipl-fcp-mpath: test if the system uses s390x IPL and re-IPL is from FCP
Add second filter stage to the udev rules: only continue with the
toolset, if the system uses s390x IPL and if the current re-IPL target
is from FCP.

For the test, whether the next re-IPL target is planned to be done from
FCP, a helper `chreipl-fcp-mpath-is-reipl-zfcp` is added, and the
information in /sys/firmware/reipl/reipl_type is used.

If either one or both of the tests are not true, the udev rules will
exit.

For debugging, the toolset can be built with the Make variable `D` set
to 1 (e.g.: make D=1; make install D=1). This causes the toolset to
write shell traces of the helper to $(DEBUGOUTDIR) (per default:
/run/udev); otherwise no output is generated. `dbginfo.sh` will be
changed to collect this data automatically.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Benjamin Block
2ea20094d0 chreipl-fcp-mpath: toolset skeleton with initial set of udev rules
Add a new tool to s390-tools: chreipl-fcp-mpath. A toolset based on udev
to change the active re-IPL target if the current target goes into an
error-state, due to for example a pulled cable.

Add the base infrastructure consisting of a Makefile and a base set of
udev rules. Integrate the Makefile into s390-tools Make machinery.

The rules filter events base on the event subject type (dm-multipath,
scsi disk), udev action (change, or add), and device mapper action
(path failure, or path reinstated). No further processing is done right
now in case of a match; if neither of these criteria matches, the
rules exit, and the toolset won't be invoked.

Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Joern Siglen
a80c14d72c dbginfo.sh: addtional timeout and omitting a report
running mpio data disks with offline paths might cause dbginfo
to hang up on the command "blockdev --report" -> we remove
it to ensure a non blocking data collection.
In addition we add a second kill step with the same timeout
value to retry stopping a command

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Thomas Huth
10518da618 zipl/boot: Always clear COMMAND_LINE_EXTRA region
Always clear the COMMAND_LINE_EXTRA region, also in case sclp_setup()
fails. If the region is not cleared properly, there might be junk
in there after a reboot, causing confusion for the kernel later.

While we're at it, also switch to COMMAND_LINE_EXTRA_SIZE instead
of COMMAND_LINE_SIZE, since that constant is more appropriate here.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/122
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Marc Hartmayer
e9d1e168b2 zdump: rename ZG_ACTION_STDOUT to ZG_ACTION_COPY
With an upcoming patch the output target can be different to `stdout`.
Therefore, the term `ZG_ACTION_STDOUT` is no longer generic enough. In addition,
rename `do_write` to `do_copy` to match the enum name.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Marc Hartmayer
7567506cca zdump: stdout_write_dump: replace magic value
Replace magic value with something easier to read.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Marc Hartmayer
524017ac06 zdump: stdout_write_dump: if dfo_size() == 0 then don't enter the loop
While at it, decrease the scope of @cnt and @rc.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Marc Hartmayer
15774dbe32 zdump: stdout_write_dump: replace dfo_size() calls
Read the `dfo_size()` value only once and then reuse it.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Marc Hartmayer
f247850ff0 zdump: only mount command uses the optional arguments
Currently, for some commands (e.g. `zgetdump unmount`) unused positional
arguments are silently ignored, for some commands (`zgetdump mount`) they're
not. Therefore let's fix this by always returning an error message and exit code
if too many positional arguments are given.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexandra Winter
800ef7cb13 hsci: Compatibility with old hsci tool
In case the hsci tool was upgraded on a running system, it can happen
that an hsci interface exists, that was created by an older version of
the tool (and thus has no veth pair). Add support to show and delete
such an hsci interface.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexandra Winter
48cf3b3809 hsci: Compatibility with old kernel
Without kernel commits
f7936b7b2663 s390/qeth: Update MACs of LEARNING_SYNC device
4e20e73e631a s390/qeth: Switchdev event handler
60bb1089467d s390/qeth: Register switchdev event handler
HSCI cannot be used with multiple MACs, but the single MAC usecase needs
to be supported even with old kernel. So manually setting the same single
MAC on hsci, HiperSockets and the external interface is still required.
The hsci itself is not a bridgeport, so a static forwarding rule in the
bridge is also required. It seems cleaner to use the initial MAC of the
veth hsci as single static MAC, than the initial MAC of the HiperSockets
interface.

Even with an updated kernel a single static MAC interface, that is not
subject to ageing and re-learning, is beneficial when hsci is used as
a single MAC interface.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexandra Winter
99c8c27302 hsci: Support multiple MAC addresses
The first implementation of HSCI (HiperSockets Converged Interface)
supports only a single static MAC address per HSCI and thus constructs
like MACVTAP or OpenVSwitch cannot be used on top of it.

Kernel commits
f7936b7b2663 s390/qeth: Update MACs of LEARNING_SYNC device
4e20e73e631a s390/qeth: Switchdev event handler
60bb1089467d s390/qeth: Register switchdev event handler
changed the behaviour of a LEARNING_SYNC HiperSockets (HS) device
such that any MAC address that is added or learned on a non-isolated
bridgeport of the HSCI bridge is set on the LEARNING_SYNC HS device and
its isolated siblings.

So no new trigger is required for a HS device with the bridge attribute
LEARNING_SYNC to support multiple MACs on a northbound HSCI interface.
However the first implementation of the hsci tool uses the bridge itself
as northbound HSCI interface. This is not treated as a real bridgeport.
So we add a veth bridgeport as northern link for HSCI.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexandra Winter
a5c3af1361 hsci: Idempotency and cleanup
Instead of checking for ideal starting conditions, try to achieve
the desired outcome and accept conditions that do not prevent it.

This allows the user to get to a defined state, even if the
hsci interface was manipulated by other means than the hsci tool,
e.g. by ip commands or bridge commands

Minor cleanup:
hsci show:
	- display PNET_ID, even if only one hsci port has one
	  (e.g. if External is a bond)
	- only 1 header for mulitple hscis
hsci add:
	- sanitize error messages
	- allow nonsense HSCI of 2 HiperSockets

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
353c23a157 zdump: Include dfi_mem_chunk.h only if required
Don't include dfi_mem_chunk.h in dfi.h because not every module including
dfi.h needs it.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
d371ba0db8 zdump: Cleanup zgetdump.h C header
Separate the definition of a struct from the declaration of a global
variable of the type. To improve readability.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
8308143008 zdump/stdout: Extract stdout.h header from zgetdump.h
Create a separate C header for STDOUT to separate independent things and
make it more readable.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
d8871197ea zdump/opts: Make command-line argument parsing independent of DFO
Set DFO format after the parsing of command-line arguments is done.
The command-line argument parsing should be independent of DFO.
This improves testability of the command-line argument parsing and
separates independent things from each other.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
df338a3bac zdump/opts: Make parsing of command line arguments testable
Make the C module responsible for the parsing of command-line arguments
independent of other global variables. This improves its testability.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
1005e7be7e zdump: Don't use god-like C headers
Get rid of C headers which include everything. This is bad for testing and
maintainability. C files should include only what they need and no more.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
afb14cba7a zdump/zfuse: Extract zfuse.h header from zgetdump.h
Create a separate C header for FUSE to separate independent things and
make it more readable.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 15:12:10 +01:00
Alexander Egorenkov
1e450e6f7b zdump/dt: Move declaration of DT structs to dt.h
Move DT structs to the header where they belong to.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
696a007b62 zdump/dfi: Move declaration of DFI structs to dfi.h
Move DFI structs to the header where they belong to.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
ea5f3f4a1c zdump/dfo: Move declaration of DFO structs to dfo.h
Move DFO structs to the header where they belong to.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
6afd5e97d1 zdump/dfi: Extract dfi_vmcoreinfo.h header from dfi.h
Create a separate C header for DFI VMCOREINFO to separate
independent things and make it more readable.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
b1da8bbbe9 zdump/dfi: Introduce symbolic constants for OLDMEM base and size
Replace magic values with descriptive names to improve readability.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
6ece595532 zdump/dfi_mem_chunk: Validate parameters passed to dfi_mem_phys_read()
To prevent segmentation faults when the function dfi_mem_phys_read() is
given invalid parameters, check that the given memory range falls within
a known physical memory chunk, just like it is done for dfi_mem_virt_read().

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
40d4aa38e9 zdump/dfi_mem_chunk: Rename dfi_mem_read_rc() to dfi_mem_virt_read()
The new name describes the purpose of the function better and
emphasizes its difference with the function dfi_mem_phys_read().

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
c58cfd1ec1 zdump/dfi_mem_chunk: Replace dfi_mem_read() with dfi_mem_read_rc()
Always use the function dfi_mem_read_rc() which verifies that the given
address and size fall within a valid memory chunk. We cannot trust
user's input.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
02086f26d2 zdump/dfi_mem_chunk: Don't expose private function dfi_mem_chunk_virt_add()
The function dfi_mem_chunk_virt_add() is used only internally and should
not be exported to prevent misuse.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:59:57 +01:00
Alexander Egorenkov
7a2666d727 zdump/dfi: Remove redundant extern from function declarations in headers
The keyword extern is redundant for function declarations in C headers.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 14:11:29 +01:00
Alexander Egorenkov
2df532c1fa zdump: Extract dfi_mem_chunk module
To make dfi_mem_chunk API unit testable.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 11:50:58 +01:00
Eduard Shishkin
969a439aaa zipl: check add_envblk predicate when setting stage3_parms
Set stage3_parms.envblk_len to 0, if add_envblk is false.
This fixes segmentation fault when performing job with
not defined zIPL environment (e.g. installing SCSI dump)

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 11:50:58 +01:00
Fedor Loshakov
f8331a4b8e ziomon: correct throughput calculation in ziorep_printers.cpp
During evaluation of the collected ziomon data from the system with following
multipath configuration:

$ multipath -ll
3600507630bffc3200000000000005294 dm-0 IBM,2107900
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 1:0:0:1083457618 sdd 8:48  active ready running
  `- 0:0:0:1083457618 sda 8:0   active ready running
3600507630bffc3200000000000005394 dm-1 IBM,2107900
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 1:0:0:1083457619 sdf 8:80  active ready running
  `- 0:0:0:1083457619 sdb 8:16  active ready running
3600507630bffc3200000000000005494 dm-2 IBM,2107900
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 1:0:0:1083457620 sdg 8:96  active ready running
  `- 0:0:0:1083457620 sdc 8:32  active ready running
3600507630bffc3200000000000005594 dm-3 IBM,2107900
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 1:0:0:1083457621 sdh 8:112 active ready running
  `- 0:0:0:1083457621 sde 8:64  active ready running

there were low throughput values for adapter noticed in ziorep_utilization
virtual adapter report:

$ ziorep_utilization adp_line_speed.log
...
CHP Bus-ID  |qdio util.%|queu|fail|-thp in MB/s-|I/O reqs-|
 ID            max   avg full  erc     rd    wrt   rd  wrt
2021-08-18 12:56:44
 61/0.0.1946  32.8   3.1    0    0   0.0   84.5    21 204K
12:57:04
...

there were also low values for throughput of devices noticed in
ziorep_traffic report. And were no aggregation of throughput for
different aggregation parameters provided:

$ ziorep_traffic adp_line_speed.log -i 0
       WWPN                LUN       |I/O rt MB/s|thrp in MB/s-|...
                                        min   max    avg  stdev ...
2021-08-18 12:58:24
0x500507630b09c320:0x4052409400000000   0.0 219.2  85.7  3.352K ...
0x500507630b09c320:0x4053409400000000   0.0 348.6  84.6  3.330K ...
0x500507630b09c320:0x4054409400000000   0.0 268.6  84.0  3.317K ...
0x500507630b09c320:0x4055409400000000   0.0 354.2  83.7  3.312K ...

$ ziorep_traffic adp_line_speed.log -i 0 -Cu
 Bus-ID |I/O rt MB/s|thrp in MB/s-|...
           min   max    avg  stdev ...
2021-08-18 12:58:24
0.0.1946   0.0 354.2  84.5  3.328K ...

although, iostat tool showed decent throughput values for each scsi disk, which
belongs to investigated zfcp adapter. In this example each scsi disk has
throughput more than 300MB/s, which is much larger, than 84.5MB/s
throughput for the adapter:

$ iostat -x 1
...
Device            r/s     w/s     rkB/s     wkB/s ...
dasda            0.00    0.00      0.00      0.00 ...
dasdb            0.00    0.00      0.00      0.00 ...
sda              0.00 2556.00      0.00 327168.00 ...
sdc              0.00 2554.00      0.00 326912.00 ...
sdb              0.00 2559.00      0.00 327552.00 ...
sdf              0.00 2865.00      0.00 366720.00 ...
sdd              0.00 2843.00      0.00 363904.00 ...
sdg              0.00 2845.00      0.00 364160.00 ...
sde              0.00 2471.00      0.00 315416.00 ...
sdh              0.00 2768.00      0.00 353768.00 ...
dm-0             0.00 5399.00      0.00 691072.00 ...
dm-1             0.00 5424.00      0.00 694272.00 ...
dm-2             0.00 5400.00      0.00 691200.00 ...
dm-3             0.00 5240.00      0.00 669312.00 ...

Use Frameset interval size for calculation of throughput of zfcp adapter
instead of d2c (dispatch to complete) time of request, which is used for I/O
rate calculation. Also use Frameset interval instead of total_latency.sum
(which in fact is a sum of d2c times for each repuest in specifed interval).
Use calc_avg() function for throughput calculation.

With fix applied, virtual adapter report now contains correct value for adpater
throughput for specified interval:

$ ziorep_utilization adp_line_speed.log
...
CHP Bus-ID  |qdio util.%|queu|fail|-thp in MB/s-|I/O reqs-|
 ID            max   avg full  erc     rd    wrt   rd  wrt
2021-08-18 12:56:44
 61/0.0.1946  32.8   3.1    0    0   0.0  1.336K   21 204K
...

With fix applied, traffic report now contains correct values of
throughput for each device and aggregation now works correctly:

$ ziorep_traffic adp_line_speed.log -i 0
       WWPN                LUN       |I/O rt MB/s|thrp in MB/s-|...
                                        min   max    avg  stdev ...
2021-08-18 12:58:24
0x500507630b09c320:0x4052409400000000   0.0 219.2 339.6  3.352K ...
0x500507630b09c320:0x4053409400000000   0.0 348.6 335.4  3.330K ...
0x500507630b09c320:0x4054409400000000   0.0 268.6 333.1  3.317K ...
0x500507630b09c320:0x4055409400000000   0.0 354.2 331.9  3.312K ...

$ ziorep_traffic adp_line_speed.log -i 0 -Cu
 Bus-ID |I/O rt MB/s|thrp in MB/s-|...
           min   max    avg  stdev ...
2021-08-18 12:58:24
0.0.1946   0.0 354.2 1.340K 3.328K ...

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-11-10 11:50:58 +01:00
Jan Höppner
895dc80580 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 17:45:29 +02:00
Jan Höppner
d93645d690 New release s390-tools-2.18.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 17:45:29 +02:00
Jan Höppner
c3bb6307b8 gitignore: Add zdev_id and zipl-editenv
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 15:44:16 +02:00
Steffen Maier
6208c0626a dbginfo.sh: collect udev rules from DPM device auto-configuration
Complements v2.5.0 commit fe68ec513d
("zdev: Add support for handling auto-configuration data").

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Peter Oberparleiter
3949c62f6f zdev: Add auto-config for PCI and crypto devices
PCI and crypto devices defined using the IBM Z Dynamic Partition Manager
(DPM) will start in an offline/unconfigured state that requires manual
intervention before the associated Linux function can be used. This
results for example in PCI networking interfaces being unavailable in a
distribution installer system.

Fix this by providing a udev rule and initial RAM-disk logic that
automatically enables PCI and crypto devices either during boot, or when
they are defined at run-time. This processing can be suppressed by
specifying the "rd.zdev=no-auto" parameter on the kernel command line.

Auto-configuration is limited to Linux running in DPM LPARs because
PCI-functions and crypto devices defined by DPM are always intended for
use by a single LPAR only.

For Linux running in classic-mode LPARs or virtual machines, leaving PCI
and crypto devices in an offline state may be useful to allow defining a
device as available to multiple systems, where only the system that
intends to make use of the device should enable it.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Peter Oberparleiter
8c6c2ef30e zdev: Add udev rule helper tool
Add an internal tool intended to be used by udev rules to determine
zdev and hypervisor related system information in key=value format.

Supported keys are:

  ZDEV_NEST_LEVEL=n
    Virtualization nesting level of running system

  ZDEV_HYPERVISOR_<n>=LPAR|z/VM|KVM/Linux
    Type of hypervisor that provides virtualization at nesting level <n>

  ZDEV_IS_DPM=0|1
    Indicator if top-level LPAR is managed by Dynamic Partition Manager

  ZDEV_NO_AUTO=0|1
    Indicator if auto-configuration is requested

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Joern Siglen
12c84469fd dbginfo.sh: exclude reading page_idle/bitmap sysfs attribute
Due to issues with reading the /sys/kernel/mm/page_idle/bitmap sysfs
attribute that can lead to a system hang, reading this particular
attribute is excluded.

Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1904884
Reviewed-by: Mario Held <mario.held@linux.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Marc Hartmayer
0a8e726d05 zgetdump: return -EINVAL for user space core dumps
zgetdump is for analyzing VM coredumps and not user space coredumps therefore
return an error in case of a user space coredump.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Peter Oberparleiter
533df585fd scripts: Add tool for parsing sclp s390dbf logs
Add new tool named 'sclpdbf'. This script displays the contents of
s390dbf sclp debug logs in human-readable format.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
c4eb2d5fba zipl-editenv: added a manpage for the new zipl-editenv tool
update manpages of zipl(8), zipl.conf(5) w/ zipl environment stuff

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
35029ad010 zipl: add environment editor
Added a tool to operate with zIPL environment, currently
installed in the boot record. All modifying operations result
in atomic update of the installed environment block, bypassing
the file system driver.

Operations currently supported by zIPL environment editor:
. set/unset environment variables,
. print/reset environment

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
296079f70a zipl: move logical-to-physical block mapping logic
from disk.c to a dedicated source file fs-map.c, so that the new
zipl-editenv tool will be also able to use it.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
4f1c73d592 zipl: add environment interpretation by stage3 of boot
Before starting the kernel:

1. parse environment block (if any) and create a hash table
   of all found pairs (NAME, VALUE);
2. scan the command line, which already contains extra-parameters
   (if any), and for each found ${NAME} replace it with VALUE, as
   found in the hash table by NAME.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
1fb859729e zipl: add basic support of environment block by zipl(8)
When installing a boot record for "ipl" and "menu" job, always add
an environment block as a boot component located in bootmap file
at offset alinged on file system block size boundary. When adding,
first try to import environment from a file at location specified
by newly introduced "--environment" zipl option, or by default at
"/etc/ziplenv". If nothing was imported, then add a blank environment
block. Optionally print the content of the environment block.

Store environment block size and address (as of boot component) in
stage3_parms.

Change interface of add_ipl_program(): add 2 additional arguments:
a pointer to bootmap file name and a predicate indicating if we
need to add environment block as a boot component.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
bbeb0f8445 zipl: expand interface of disk_write_block_aligned_base()
Provide helper functions disk_write_block_buffer_align()
and add_component_buffer_align() to align offset of the record
on specified block size boundary and to save the offset, where
the record was made at.

This will be used by a later patch.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Eduard Shishkin
2ae44cb794 zipl: expand interface of disk_get_blocklist_from_file
. expand interface of disk_get_blocklist_from_file() to get
  block pointers for a specific range of data within a file.
. provide a helper function add_component_file_range() to add a
  specific range of data within a file as a boot component.

This will be used by a later patch.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Marc Hartmayer
a0b8033088 zdump: dfi_mem_range_valid: check that unsigned int operation don't wrap
Validate that the addition of the parameters @addr and @len given to
`dfi_mem_range_valid()` does not overflow 64bit unsigned integer type.

This fixes the following segmentation fault:

[#0] 0x2aa000084fc → mem_read(mem=0x2aa00021b68 <l+152>, addr=0xffffffffffffffff, buf=0x3ffffffec64, cnt=0xc)
[#1] 0x2aa00009964 → dfi_mem_read(addr=0xfffffffffffffffa, buf=0x3ffffffec64, cnt=0xc)
[#2] 0x2aa00009c86 → dfi_mem_read_rc(addr=0xfffffffffffffffa, buf=0x3ffffffec64, cnt=0xc)
[#3] 0x2aa0000ba42 → dfi_vmcoreinfo_init()
[#4] 0x2aa0000b496 → dfi_init()
[#5] 0x2aa00005aa6 → do_dump_info()
[#6] 0x2aa00005c82 → main(argc=<optimized out>, argv=0x3fffffff118)

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Marc Hartmayer
9cc74839b0 zgetdump: initalize sigact to 0
This fixes the following Valgrind finding:

==28040== Syscall param rt_sigaction(act->sa_flags) points to uninitialised byte(s)
==28040==    at 0x48C98B0: __libc_sigaction (sigaction.c:58)
==28040==    by 0x10D507: sig_handler_init (zgetdump.c:58)
==28040==    by 0x10D507: main (zgetdump.c:179)
==28040==  Address 0x1ffefffc84 is on thread 1's stack
==28040==  in frame #0, created by __libc_sigaction (sigaction.c:43)

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Marc Hartmayer
b7b7002855 gitignore: Ignore coverage data
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Peter Oberparleiter
55e428a4d7 dump2tar: Fix (null) output on help text
Fix the following incorrect help text line:

 -T, --file-timeout (null)  Stop reading file after SEC seconds

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Alexander Egorenkov
cb09223a56 zdump/dfi_elf: Fix stack buffer overflow in nt_read()
Sanity check ELF notes descriptor size before reading it. This prevents
stack buffer overflows in case a dump contains invalid ELF notes.
Instead of reading a note's descriptor into a temporary buffer on stack,
read it directly into the buffer given to nt_read() but also provide
a maximum length of the given buffer to nt_read() in order to prevent
overflows.

This problem was found with valgrind and AFL fuzzing + ASAN.

AFL +  ASAN findings:

[root@t83lp49 s390-tools]# ./zdump/zgetdump -iVVVVV ~/zgetdump-fuzzing/findings/crashes/id\:000008\,sig\:06\,src\:000007\,op\:arith8\,pos\:67\,val\:+3
TRACE: DFI initialization
DEBUG: DFI trying s390tape
DEBUG: DFI s390tape returned with rc -19
DEBUG: DFI trying devmem
DEBUG: DFI devmem returned with rc -19
DEBUG: DFI trying s390mv_ext
DEBUG: DFI s390mv_ext returned with rc -19
DEBUG: DFI trying s390mv
DEBUG: DFI s390mv returned with rc -19
DEBUG: DFI trying s390_ext
DEBUG: DFI S390 extended initialization
DEBUG: DFI s390_ext returned with rc -19
DEBUG: DFI trying s390
DEBUG: DFI S390 initialization
DEBUG: DFI s390 returned with rc -19
DEBUG: DFI trying lkcd
DEBUG: DFI lkcd returned with rc -19
DEBUG: DFI trying elf
DEBUG: DFI ELF initialization
DEBUG: DFI ELF e_phnum 11
DEBUG: DFI ELF p_type[0] 0x4
DEBUG: DFI ELF n_type 0x0
AddressSanitizer:DEADLYSIGNAL
=================================================================
==208548==ERROR: AddressSanitizer: stack-overflow on address 0x03ffef05d000 (pc 0x0000010051b0 bp 0x03fff107dc40 sp 0x03ffef05dac8 T0)
    #0 0x10051b0  (/root/s390-tools/zdump/zgetdump+0x10051b0)

SUMMARY: AddressSanitizer: stack-overflow (/root/s390-tools/zdump/zgetdump+0x10051b0)
==208548==ABORTING

valgrind findings:

	==56423== Source and destination overlap in memcpy(0x4a86d38, 0x4a875e0, 4096)
	==56423==    at 0x4839F86: memcpy (in /usr/lib/s390x-linux-gnu/valgrind/vgpreload_memcheck-s390x-linux.so)
	==56423==    by 0x114253: memcpy (string_fortified.h:34)
	==56423==    by 0x114253: nt_read (dfi_elf.c:95)
	==56423==    by 0x1145FF: nt_s390_prefix_read (dfi_elf.c:195)
	==56423==    by 0x1145FF: pt_notes_add (dfi_elf.c:259)
	==56423==    by 0x1145FF: dfi_elf_init (dfi_elf.c:326)
	==56423==    by 0x112A57: dfi_init (dfi.c:1212)
	==56423==    by 0x10D663: do_dump_info (zgetdump.c:127)
	==56423==    by 0x10D663: main (zgetdump.c:182)
	==56423==
	==56423== Invalid write of size 8
	==56423==    at 0x4839E28: memcpy (in /usr/lib/s390x-linux-gnu/valgrind/vgpreload_memcheck-s390x-linux.so)
	==56423==    by 0x114253: memcpy (string_fortified.h:34)
	==56423==    by 0x114253: nt_read (dfi_elf.c:95)
	==56423==    by 0x1145FF: nt_s390_prefix_read (dfi_elf.c:195)
	==56423==    by 0x1145FF: pt_notes_add (dfi_elf.c:259)
	==56423==    by 0x1145FF: dfi_elf_init (dfi_elf.c:326)
	==56423==    by 0x112A57: dfi_init (dfi.c:1212)
	==56423==    by 0x10D663: do_dump_info (zgetdump.c:127)
	==56423==    by 0x10D663: main (zgetdump.c:182)
	==56423==  Address 0x4a86ee0 is 0 bytes after a block of size 912 alloc'd
	==56423==    at 0x483675E: calloc (in /usr/lib/s390x-linux-gnu/valgrind/vgpreload_memcheck-s390x-linux.so)
	==56423==    by 0x10E71D: zg_alloc (zg.c:93)
	==56423==    by 0x114793: nt_prstatus_read (dfi_elf.c:123)
	==56423==    by 0x114793: pt_notes_add (dfi_elf.c:234)
	==56423==    by 0x114793: dfi_elf_init (dfi_elf.c:326)
	==56423==    by 0x112A57: dfi_init (dfi.c:1212)
	==56423==    by 0x10D663: do_dump_info (zgetdump.c:127)
	==56423==    by 0x10D663: main (zgetdump.c:182)

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Suggested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reported-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Alexander Egorenkov
28db3523d0 zdump/dfi: Fix illegal memory access in mem_chunk_has_addr()
Verify that the mem chunk_cache pointer is valid before using it.
This prevents potential illegal memory accesses.

This problem was found with AFL fuzzing and ASAN.

./zdump/zgetdump -iVVVVV ~/zgetdump-fuzzing/findings/crashes/id\:000007\,sig\:06\,src\:000007\,op\:flip1\,pos\:37
TRACE: DFI initialization
DEBUG: DFI trying s390tape
DEBUG: DFI s390tape returned with rc -19
DEBUG: DFI trying devmem
DEBUG: DFI devmem returned with rc -19
DEBUG: DFI trying s390mv_ext
DEBUG: DFI s390mv_ext returned with rc -19
DEBUG: DFI trying s390mv
DEBUG: DFI s390mv returned with rc -19
DEBUG: DFI trying s390_ext
DEBUG: DFI S390 extended initialization
DEBUG: DFI s390_ext returned with rc -19
DEBUG: DFI trying s390
DEBUG: DFI S390 initialization
DEBUG: DFI s390 returned with rc -19
DEBUG: DFI trying lkcd
DEBUG: DFI lkcd returned with rc -19
DEBUG: DFI trying elf
DEBUG: DFI ELF initialization
DEBUG: DFI ELF e_phnum 11
DEBUG: DFI ELF p_type[0] 0x6060606
DEBUG: DFI ELF p_type[1] 0x6060606
DEBUG: DFI ELF p_type[2] 0x6060606
DEBUG: DFI ELF p_type[3] 0x6060606
DEBUG: DFI ELF p_type[4] 0x6060606
DEBUG: DFI ELF p_type[5] 0x6060606
DEBUG: DFI ELF p_type[6] 0x6060606
DEBUG: DFI ELF p_type[7] 0x6060606
DEBUG: DFI ELF p_type[8] 0x6060606
DEBUG: DFI ELF p_type[9] 0x6060606
DEBUG: DFI ELF p_type[10] 0x6060606
TRACE: DFI kdump initialization
AddressSanitizer:DEADLYSIGNAL
=================================================================
==206692==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000001016a12 bp 0x03ffcc57eae0 sp 0x03ffcc57eae0 T0)
==206692==The signal is caused by a UNKNOWN memory access.
==206692==Hint: address points to the zero page.
    #0 0x1016a12 in mem_chunk_has_addr /root/s390-tools/zdump/dfi.c:308
    #1 0x1016a12 in mem_chunk_find /root/s390-tools/zdump/dfi.c:318
    #2 0x1016a12 in dfi_mem_chunk_find /root/s390-tools/zdump/dfi.c:513
    #3 0x1016a12 in dfi_mem_range_valid /root/s390-tools/zdump/dfi.c:208
    #4 0x1016a12 in kdump_init /root/s390-tools/zdump/dfi.c:1100
    #5 0x1016a12 in dfi_init /root/s390-tools/zdump/dfi.c:1253
    #6 0x1006d3d in do_dump_info /root/s390-tools/zdump/zgetdump.c:127
    #7 0x1006d3d in main /root/s390-tools/zdump/zgetdump.c:182
    #8 0x3ff9e0abe03 in __libc_start_main (/lib64/libc.so.6+0x2be03)
    #9 0x1007d7d  (/root/s390-tools/zdump/zgetdump+0x1007d7d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/s390-tools/zdump/dfi.c:308 in mem_chunk_has_addr
==206692==ABORTING

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Alexander Egorenkov
f15e32cdb1 zdump/dfi: Fix illegal memory access in dfi_cpu_add_from_lc()
Check that a CPU's lowcore address falls within a valid memory region
before accessing it. This prevents potential illegal memory accesses
in case a dump contains invalid CPU lowcore addresses.

This bug was found with AFL fuzzing and ASAN.

Starting program: /root/s390-tools/zdump/zgetdump -iVVVVV /root/zgetdump-fuzzing/findings/crashes/id:000004,sig:06,src:000005,op:flip32,pos:3055
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
TRACE: DFI initialization
DEBUG: DFI trying s390tape
DEBUG: DFI s390tape returned with rc -19
DEBUG: DFI trying devmem
DEBUG: DFI devmem returned with rc -19
DEBUG: DFI trying s390mv_ext
DEBUG: DFI s390mv_ext returned with rc -19
DEBUG: DFI trying s390mv
DEBUG: DFI s390mv returned with rc -19
DEBUG: DFI trying s390_ext
DEBUG: DFI S390 extended initialization
DEBUG: DFI s390_ext returned with rc -19
DEBUG: DFI trying s390
DEBUG: DFI S390 initialization
 INFO: DFI S390 version 5
DEBUG: DFI S390 mem_size 0x00000000000dbba0
DEBUG: DFI add vol mem chunk start 0x0000000000000000 size 0x00000000000dbba0 volnr 0

[snip]

TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x0000000000000000 size 0x0000000000002000
TRACE: DFI virt mem read addr 0x00000000000000ff size 0x0000000000002000
TRACE: DFI virt mem read addr 0x00000000ffffff00 size 0x0000000000002000

Program received signal SIGSEGV, Segmentation fault.
0x000000000100fbb0 in mem_read (cnt=<optimized out>, buf=0x3ffffffc7d0, addr=4294967040, mem=0x104b218 <l+152>) at dfi.c:339
339                     size = MIN(cnt - copied, mem_chunk->end - addr + 1);
Missing separate debuginfos, use: dnf debuginfo-install fuse-libs-2.9.9-11.fc34.s390x glibc-2.33-20.1.ibm.fc34.s390x libasan-11.0.1-0.3.1.ibm.fc34.s390x libgcc-11.0.1-0.3.1.ibm.fc34.s390x libstdc++-11.0.1-0.3.1.ibm.fc34.s390x zlib-1.2.11-26.fc34.s390x
(gdb) bt

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:59:56 +02:00
Steffen Maier
094057e265 zfcpdbf: fix missing "FCP rsp IU all" fields if PAY record wrapped away
Had a confusing decoded trace record:

Timestamp      : ...
Area           : SCSI
...
Tag            : rsl_err
...
SCSI result    : 0x00000002
SCSI opcode    : 1a...
FCP rsp inf cod: 0x00
FCP rsp IU     : 00000000 00000000 00000a02 000000ff
                 00000012 00000000
                       ^^

and was wondering where that sense data would be or if the
corresponding PAY record "fcp_riu" was lost due to trace area wrapping.
So the fix here adds the following two lines to the same trace record:

FCP rsp IU len : 42
FCP rsp IU all : record not available anymore.

Similarly, the following LUN reset Task Management Function response
was missing the last two lines regarding the full FCP response IU
and its optional part with the FCP response info:

Timestamp      : ...
Area           : SCSI
...
Tag            : lr_okay
...
FCP rsp inf cod: 0x00
FCP rsp IU     : 00000000 00000000 00000100 00000000
                 00000000 00000008
                                ^^
FCP rsp IU len : 32
FCP rsp IU all : record not available anymore.

As of today, depending on the kernel version we have
either fcp_sns or fcp_riu PAY trace records. See Linux kernel v4.14 commit
12c3e5754c80 ("scsi: zfcp: fix payload with full FCP_RSP IU in SCSI trace
records").
Always print non-zero payload length independent of payload type.
Actually this also fixes a regression for wrapped away fcp_sns.
If there is no fcp_sns it either wrapped away or it's a kernel with fcp_riu.
Only print fcp_riu if it contains more content than the preceding
unconditional fixed-size field "FCP rsp IU".

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:58:17 +02:00
Alexander Egorenkov
025a2198a4 zdump/dfi_s390: Fix use of uninitialized stack value in mem_chunks_add_ext()
If the while loop in mem_chunks_add_ext() is never executed, then
the stack variable containing the dump segment header will never be
initialized.

clang's static code analyzer reports the following problem:

$ make CC="clang --analyze" -C zdump

dfi_s390.c:157:6: warning: Branch condition evaluates to a garbage value [core.uninitialized.Branch]
        if (!dump_segm.stop_marker)
            ^~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:14 +02:00
Alexander Egorenkov
2b938b78aa zdump: Introduce multi-level message logging
Use util_log from libutil to output various log messages that can be helpful
during problem analysis.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:14 +02:00
Alexander Egorenkov
de36fc5259 zdump/dfi: Fix format string specifiers in dfi_info_print()
Replace the incorrect %d format specifier with %u one for unsigned integer
types.

This issue was found with AFL fuzzing.

$ ./zdump/zgetdump -i ~/input.bin
General dump info:
  Dump format........: s390
  Version............: -2147483647
  System arch........: s390x (64 bit)
  CPU count (online).: 32768
  Dump memory range..: 1 MB

Memory map:
  0000000000000000 - 00000000000f423f (1 MB)

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:14 +02:00
Alexander Egorenkov
e3e5b6422a zdump/dfi_s390: Fix out-of-bounds array access in df_s390_cpu_info_add()
Verify that a s390 dump header contains a valid CPU count value.

This bug was found with an input file produced by AFL + ASAN.

$ ./zdump/zgetdump -i ~/input.bin
=================================================================
==3928488==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000001043e90 at pc 0x000001025dca bp 0x03ffe96fe128 sp 0x03ffe96fe120
READ of size 4 at 0x000001043e90 thread T0
    #0 0x1025dc9 in df_s390_cpu_info_add /root/s390-tools/zdump/df_s390.c:57
    #1 0x101bb59 in dfi_s390_init_gen /root/s390-tools/zdump/dfi_s390.c:169
    #2 0x101bb59 in dfi_s390_init_gen /root/s390-tools/zdump/dfi_s390.c:156
    #3 0x1015d23 in dfi_init /root/s390-tools/zdump/dfi.c:1216
    #4 0x1006a0d in do_dump_info /root/s390-tools/zdump/zgetdump.c:127
    #5 0x1006a0d in main /root/s390-tools/zdump/zgetdump.c:182
    #6 0x3ffb93abe03 in __libc_start_main (/lib64/libc.so.6+0x2be03)
    #7 0x10077bd  (/root/s390-tools/zdump/zgetdump+0x10077bd)

0x000001043e91 is located 0 bytes to the right of global variable 'l' defined in 'dfi_s390.c:30:3' (0x1042e80) of size 4113
SUMMARY: AddressSanitizer: global-buffer-overflow /root/s390-tools/zdump/df_s390.c:57 in df_s390_cpu_info_add
Shadow bytes around the buggy address:
  0x10000000208780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000000208790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100000002087a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100000002087b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100000002087c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100000002087d0: 00 00[01]f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x100000002087e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100000002087f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000000208800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000000208810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000000208820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==3928488==ABORTING

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:14 +02:00
Joern Siglen
38343be0fa dbginfo.sh: update the order of collection steps
We found situations, where the debug commands from dbginfo.sh
did overwrite some debug files (e.g. OSA s390dbf) - so we change
the collection order

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:14 +02:00
Alexander Egorenkov
957e612720 zdump/dfi_vmcoreinfo: Fix illegal memory access in dfi_vmcoreinfo_init()
Before reading data in dfi_vmcoreinfo_init(), check the validity
of the memory range. Otherwise this can result in a segmentation fault when
zgetdump is given a very small dump, e.g. S390 DASD single-volume dump of
size 0x10 bytes.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:14 +02:00
Jan Höppner
1d2316caef zdump/dfi_vmcoreinfo: Fix potential illegal memory access in os_info_get()
Before reading data in os_info_get(), check the validity of the memory
range. Otherwise this can result in a segmentation fault when zgetdump is
given a very small dump, e.g. S390 DASD single-volume dump of size 0x10
bytes.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:13 +02:00
Alexander Egorenkov
64539853ca zdump/dfi: Fix potential illegal memory access in kdump_init()
Before reading data at addresses 0x10418 and 0x10420 in kdump_init(),
validate the validity of the memory range. Otherwise this can result in
a segmentation fault when zgetdump is given a very small dump, e.g.
S390 DASD single-volume dump of size 0x1000 bytes.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:13 +02:00
Alexander Egorenkov
686c331b69 zdump/dfi_vmcoreinfo: Sanity checks for n_namesz in ELF Notes header
The dfi_vmcoreinfo_init() function might be called on a dump of a non-ELF
format because the DFI goes through all supported dump formats when first
trying to identify of what dump format the given input is. Therefore,
we must be very careful in interpreting read data and ensure that it
makes sense before accessing or using it.

This commit prevents a potential overflow of a stack buffer in
dfi_vmcoreinfo_init() if note.n_namesz is bigger than the stack buffer.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:13 +02:00
Joern Siglen
01551f98d5 dbginfo.sh: code rework
- adding new print function for simpler output customizing
- consolidate some output files
- sync structures and use of checks
- some formatting updates

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:13 +02:00
Alexander Egorenkov
0e2c5907e0 zdump/dfi_s390: Fix memory leaks in mem_chunks_add_ext()
The function mem_chunks_add_ext() allocates but does not release memory
if it encounters unexpected errors during dump segment reading.

Allocate memory passed to dfi_mem_chunk_add() right before calling
the function. This way there is no need for a cleanup anymore.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:13 +02:00
Joern Siglen
68ff79e4c3 dbginfo.sh: cleanup 2.x kernel & adding timeout
- clenaup outdated kernel - we no longer have 2.x kenrel in support
- add timeout on command excution - ensure to not miss all data for a
  single command to hang

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-10-01 14:53:13 +02:00
Ingo Franzki
5b96d86538 zkey-cryptsetup: Support LUKS2 volumes with integrity support enabled
When integrity support is enabled for a LUKS2 volume, then the LUKS2
volume key may include the integrity key concatenated to the secure key
(dependent on the integrity type).

Get the integrity key size from the LUKS2 header (if integrity support
is enabled) and calculate the size of the secure key when performing
operations with the secure key only.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:21:32 +02:00
Alexander Egorenkov
4043137cd7 zdump: Fix handling of PT_LOAD segments with p_filesz < p_memsz in ELF DFI
According to the ELF specification, the file size of a PT_LOAD
memory segment might be less than its memory size. In that case,
the remaining bytes must be filled with zeros. The ELF DFI implementation
didn't handle this case correctly. Such ELF core files might be produced
by the makedumpfile tool.

From elf.5 man page:
------------------------------------------------------
PT_LOAD
       The array element specifies a loadable segment,
       described by p_filesz and p_memsz.  The bytes
       from the file are mapped to the beginning of the
       memory segment.  If the segment's memory size
       p_memsz is larger than the file size p_filesz,
       the "extra" bytes are defined to hold the value
       0 and to follow the segment's initialized area.
       The file size may not be larger than the memory
       size.  Loadable segment entries in the program
       header table appear in ascending order, sorted
       on the p_vaddr member.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:21:32 +02:00
Alexander Egorenkov
735d8f5493 zdump: Fix reading of ELF program headers in ELF DFI
Before attempting to read ELF program headers, the file must be positioned
at the offset of the first program header as specified in the ELF header.

Furthermore, read all ELF program headers with one call to zg_read(). This
has the advantage of not having to restore the file offset every time
after it is changed in pt_notes_add() and other functions which need to
read the same file as well.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:21:32 +02:00
Alexander Egorenkov
28efa7d120 zdump: Disable warnings about unaligned access to packed struct members
This is a false positive because IBM Z architecture supports unaligned
memory accesses.

dfo_s390.c: In function ‘df_s390_dump_init’:
dfo_s390.c:218:29: warning: taking address of packed member of ‘struct df_s390_hdr’ may result in an unaligned pointer value [-Waddress-of-packed-member]
  218 |                 timeval2tod(&dh->tod, dfi_attr_time());
      |                             ^~~~~~~~
dfo_s390.c:219:29: warning: taking address of packed member of ‘struct df_s390_em’ may result in an unaligned pointer value [-Waddress-of-packed-member]
  219 |                 timeval2tod(&em->tod, dfi_attr_time());
      |                             ^~~~~~~~
dfo_s390.c:222:29: warning: taking address of packed member of ‘struct df_s390_em’ may result in an unaligned pointer value [-Waddress-of-packed-member]
  222 |                 timeval2tod(&em->tod, dfi_attr_time_end());
      |                             ^~~~~~~~

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:21:29 +02:00
Eduard Shishkin
ebde75eeda zipl: add an ability to specify components location
When creating a bootmap, look for zipl components (stage3.bin and
zipl helpers) in a directory specified by S390TOOLS_LIBDIR shell
environment variable. If that variable is not set, then look for
them at the default location.

In verbose mode print the name of s390-tools library directory,
where the search was implemented.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Eduard Shishkin
a645ec0fc0 libutil: make TOOLS_LIBDIR and TOOLS_DATADIR configurable
Add generic functions

util_sysdir();
util_sysdir_path()

and their special cases supplied for users:

util_libdir();
util_libdir_path();
util_datadir();
util_datadir_path()

The function util_sysdir() determines the absolute name of a
s390-tools system directory. It could be data, or library directory.

The function util_sysdir_path() determines the absolute name of a
file installed in the s390-tools system directory.

The function util_libdir() determines the absolute name of a
s390-tools library directory. By default that name is defined
by the compile-time macro TOOLS_LIBDIR (/lib/s390-tools).
Users can specify an override by setting environment variable
S390TOOLS_LIBDIR.

The function util_libdir_path() determines the absolute name of a
file installed in the s390-tools library directory.

The function util_datadir() determines the absolute name of a
s390-tools system data directory. By default the name is defined
by the compile-time macro TOOLS_DATADIR (/usr/share/s390-tools/).
Users can specify an override by setting environment variable
S390TOOLS_DATADIR.

The function util_datadir_path() determines the absolute name of a
file installed in the s390-tools data directory.

The ability to override the setting for TOOLS_LIBDIR and
TOOLS_DATADIR is required for implementing tests on tools that are
not installed in their default system path locations.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Vineeth Vijayan
761a185938 zconf/lscss: show device number from pmcw
lscss shows device number as 'None' if the corresponding device in the
subchannel is non-operational or not connected. Instead, show the
device-no derived from the new dev_busid attribute which provides the
value of device_id irrespective of the device availability.

i.e the current lscss shows

Device   Subchan.  DevType CU Type Use  PIM PAM POM  CHPIDs
----------------------------------------------------------------------
0.0.0000 0.0.0000  3390/0c 3990/e9      f0  a0  ff   32333435 00000000
none     0.0.00c7                       f0  a0  5f   32333435 00000000
none     0.0.00c8                       f0  a0  5f   32333435 00000000

here the subchannels 0.0.00c7 and 0.0.00c8 do not have an operational
device on them. Hence the device is shown as none.

With this patch,

Device   Subchan.  DevType CU Type Use  PIM PAM POM  CHPIDs
----------------------------------------------------------------------
0.0.0000 0.0.0000  3390/0c 3990/e9      f0  a0  ff   32333435 00000000
0.0.74c8 0.0.00c7                       f0  a0  5f   32333435 00000000
0.0.74c9 0.0.00c8                       f0  a0  5f   32333435 00000000

The device-no is shown as 0.0.74c8; Where the DevType field still
indicates that the device is not present.

Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Harald Freudenberger
890b15d158 lszcrypt: add support for vfio-ap status field
lszcrypt now evaluates and displays the 'status' in the
'STATUS' column if the vfio provides this sysfs attribute.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Harald Freudenberger
07677668a3 lszcrypt: online is status and now tracked as status
The 'STATUS' field was within the code used as 'online'
record because it showed the online state. But now it
displays some more info like 'deconfig' and maybe even
more in the future. So now the code also uses a 'status'
record for this info.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Harald Freudenberger
fde914fd1c lszcrypt: Improved output for deconfig cards and queues
Slight rework of the lszcrypt code with:
- a queue or card in deconfigured mode is displayed
  as 'deconfig' regardless which driver is bound to
  the device.
- a queue or card in 'deconfig' mode does not show
  any counters any more but displays a '-' instead.
- a queue not bound or bound to something else as
  the 'default' zcrypt dd does not show any counters
  but displays a '-' instead.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Thomas Richter
35c97a07aa vmur/vmur.cpp: Fix error handling on transfer failure
The command

 # vmur punch -r rhcos-live-kernel-s390x -u etpgxku -N kernel.img
 Reader file with spoolid E YO created and transferred to ETPGXKU.
 #

did not indicate an error when executed. However the file was not
transferred and this error message went unnoticed:
RPIMGR032E YOU ARE NOT AUTHORIZED TO CLOSE TO TATAC05.ETPGXKU
HCPCSL007E Invalid userid - ETPGXKU

Fix this by checking the CP return code and print the error message
returned by CP. This is the behavior now:
 # vmur punch -r rhcos-live-kernel-s390x -u etpgxku -N kernel.img
 vmur: CP command failed with rc=7
 RPIMGR032E YOU ARE NOT AUTHORIZED TO CLOSE TO TATAC05.ETPGXKU
 HCPCSL007E Invalid userid - ETPGXKU
 #

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/119
Reported-by: Vance Morris <vmorris@us.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Tested-by: Vance Morris <vmorris@us.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 17:20:52 +02:00
Steffen Maier
45e3f016f4 lszfcp: add linkdown case to host marker of extended output
Complements v2.9.0 commit 4036e80b26 ("lszfcp: add new output marker
for non-good FCP devices (hosts)").

Otherwise "linkdown" shows as "failed" because linkdown happens to be
the one special case that also sets the failed status flag of the
FCP device (host). Linkdown is kind of benign compared to other cases
where the FCP device is in failed status.

Examples:
$ lszfcp -He
0.0.194a host3 linkdown

$ lszfcp -HeV
/sys/devices/css0/0.0.0004/0.0.194a linkdown
/sys/class/fc_host/host3
/sys/class/scsi_host/host3

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 16:55:02 +02:00
Alexander Egorenkov
38b520ab4c zdump/dfi_elf: Don't accept ELF input with zero-sized PT_LOAD segments
The DFI memory chunk manager cannot handle PT_LOAD segments of size 0.
This can lead to a NULL pointer access in mem_chunk_find() in case
zgetdump is given an invalid VMCORE ELF file as input which contains
only zero-sized ELF PT_LOAD segments. Instead of crashing, show an error
message and terminate gracefully.

The TELA test dump_with_zero_sized_segments.sh can reproduce this bug.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 16:55:02 +02:00
Fabrice Fontaine
3b6920271e Makefile: add {CURL,XML2}_CONFIG
Add CURL_CONFIG and XML2_CONFIG to allow the user to configure the
binaries used in check-dep-libkmipclient

This will allow the user to avoid the following build failures raised
since version 2.17.0 and
56fecf1832:

/bin/sh: 1: curl-config: not found
Error: libcurl is not built with the OpenSSL backend
make[2]: *** [Makefile:54: check-dep-libekmfweb] Error 1

Fixes:
 - http://autobuild.buildroot.org/results/cfb46d7547c22f0a23aca2286dc5a1d2c20aadfc

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/121
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 16:55:02 +02:00
Steffen Maier
a3146409da dbginfo.sh: collect zipl boot menu entries from boot loader specification
Zipl.conf is collected via /etc/*.conf in CONFIGFILES but BLS snippets
do not appear in /etc/zipl.conf.

Complements v2.5.0 commit d280e5b1fa ("zipl: Add BootLoaderSpec support")

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 16:55:02 +02:00
Ingo Franzki
76aa8e4a52 Makefile: Fix order of build of libraries for parallel builds
Some libraries depend on other libraries, so split the libraries
into two groups: base libraries that do not depend on any others, and
the remaining libraries, that may depend on the base libraries.

Ensure that the base libraries are built first, before starting to
build the remaining libraries. The tools are only built once the base
libraries and the remaining libraries have been built.

This fixes a possible build problem with libseckey when parallel build
is used. The libseckey library is used by libekmfweb and the zkey KMIP
plugin (zkey-kmip). With parallel build both are built in parallel,
and thus both trigger the build of libseckey. This can lead to the
situation that libseckey is built twice at the same time, which can lead
to build failures (corrupted archive, etc).

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 16:54:59 +02:00
Jan Höppner
f5e6f4a8cb gitignore: Add hsavmcore/check-dep-fuse
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-09-30 16:52:38 +02:00
Alexander Egorenkov
80cb1553a3 hsavmcore: Avoid recompilation of overlay during install step
overlay.o was being recompiled during the install step because
it depended on the target check-dep-fuse which is phony and,
therefore, always outdated. The solution is to create an empty file
for the target check-dep-fuse after its successful completion. This
prevents make from rebuilding overlay.o during installation.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/118
Fixes: 5a7d2a58c8 ("hsavmcore: Fix fuse dependency checking")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Suggested-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:48:45 +02:00
Thomas Richter
706f59b9d9 cpumf/lshwc.c: Fix sparse warning and replace 0 by NULL
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Suggested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:46:39 +02:00
Thomas Richter
02cc902b90 cpumf/lswhc.c: Fix sparse warning and add missing static
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Suggested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:46:39 +02:00
Alexander Egorenkov
ff2fb42868 cpumf/lshwc: Fix compile errors due to use of non-standard __BITS_PER_LONG
Use LONG_BIT provided by C standard in <limits.h>.

Fixes the following compile errors with buildroot:
lshwc.c: In function ‘parse_cpulist’:
lshwc.c:295:15: error: ‘__BITS_PER_LONG’ undeclared (first use in this function)
  295 |    no_a = i % __BITS_PER_LONG;
      |               ^~~~~~~~~~~~~~~

Fixes: 27a562da0a ("cpumf/lshwc: Program to extract complete counter sets")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:46:39 +02:00
Alexander Egorenkov
451bf7fbc6 cpumf/lshwc: Fix compile errors due to use of non-standard 32/64 bit types
Use standard 32- and 64-bit C types.

Fixes the following compile errors with buildroot:
In file included from lshwc.c:41:
lshwc.h:61:2: error: unknown type name ‘__u64’
   61 |  __u64 version;   /* Version of interface */
      |  ^~~~~
lshwc.h:62:2: error: unknown type name ‘__u64’
   62 |  __u64 data_bytes;  /* # of bytes required */
      |  ^~~~~
lshwc.h:63:2: error: unknown type name ‘__u64’
   63 |  __u64 cpumask_len;  /* Length of CPU mask in bytes */
      |  ^~~~~
lshwc.h:64:2: error: unknown type name ‘__u64’
   64 |  __u64 *cpumask;   /* Pointer to CPU mask */
      |  ^~~~~
lshwc.h:65:2: error: unknown type name ‘__u64’
   65 |  __u64 counter_sets;  /* Bit mask of counter set to get */
      |  ^~~~~
lshwc.h:69:2: error: unknown type name ‘__u32’
   69 |  __u32 set;   /* Counter set number */
      |  ^~~~~

Fixes: 27a562da0a ("cpumf/lshwc: Program to extract complete counter sets")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:46:39 +02:00
Ingo Franzki
d2a4a8b0f3 libkmipclient: Fix parsing of hex values for XML and JSON encoding
KMIP values of type BYTE-STRING are represented as hex values when XML
or JSON encoding is used. Do not drop any leading zero bytes, if the
value has them.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:46:39 +02:00
Jan Höppner
fe5753d34d Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-27 11:46:39 +02:00
Jan Höppner
fe187eb3d3 New release s390-tools-2.17.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 15:18:51 +02:00
Jan Höppner
4a8afd4ed6 README.md: Add lshwc description
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 15:18:51 +02:00
Jan Höppner
74e6ebe1df libdasd: Free memory for previously used sysfs path
util_path_sysfs() allocates memory for the created path which must be
freed by the user.

Fixes: 8023a72b11 ("libdasd: Provide function to read ese sysfs attribute")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki
ec83da3a39 zkey-kmip: Add man page for the KMIP plugin
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki
c11b0cdcaa zkey-kmip: List and import keys managed by KMIP
List (find) and import a key that exists in a KMIP server into the zkey
repository. Retrieve the key attributes of a key stored in a KMIP server,
and extract the zkey properties from it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki
4f3cba406e zkey-kmip: Remove keys and optionally set its state in KMIP
When a key is removed from the zkey repository, it is usually not removed
from the KMIP server. Optionally, the state of a KMIP key can be changed
when it is removed by zkey.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:02:13 +02:00
Ingo Franzki
c55ac2c016 zkey-kmip: Set properties of an existing key
Change the attributes of a key at the KMIP server when the properties
of a key are changed in zkey.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 14:01:49 +02:00
Ingo Franzki
4eab80ef44 zkey-kmip: Generate keys in the KMIP server and retrieve them
Allow to generate a new AES key at the KMIP server, and retrieved it.
Keys are always retrieved in wrapped format, wrapped by the public RSA
wrapping key used by the KMIP plugin. The KMIP plugin can then unwrap
the retrieved key with its secure private RSA key, and can then import
the retrieved AES key into the zkey repository as secure key. That way,
the retrieved AES key is never in clear, once it leaves the KMIP server.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
41ddd35bc1 zkey-kmip: Re-encipher identity and wrapping keys on MK change
When the master keys of the configured APQNs are changed, the secure
identity key as well as the secure wrapping key must be re-enciphered.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
bdc44cafb6 zkey-kmip: Generate and register wrapping key
Keys retrieved from a KMIP server are wrapped with an RSA key. The
RSA wrapping key is a secure key generated by the KMIP plugin. The
public RSA key is registered at the KMIP server, and the KMIP server
can then wrap the keys with it. The KMIP plugin can unwrap the retrieved
key with the private RSA key and import it as secure key into the zkey
repository.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
46583b4db6 zkey-kmip: Configure connection to KMIP server
Configure a connection to a KMIP server, establish trust between
server and client, query the KMIP server and verify if it supports
the required KMIP operations. Also, the profile to be used with this
KMIP server is tried to matched. If not specified in the profile,
the KMIP protocol version to be used is discovered.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
a2359dbe5f zkey-kmip: Add support for KMIP server profiles
KMIP server profiles (not to be confused with profiles defined by
the KMIP standard) define how the KMIP plugin talks to the KMIP
server. Profiles can be used to configure certain KMIP usages for
certain KMIP servers.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
52b6e57743 zkey: Allow comments and empty lines in properties files
Lines with '#' as first character are treated as comments, and are
skipped. Empty lines are also skipped.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
b1997c7aac zkey-kmip: Generate CSR or self signed certificate
For the client certificate to authenticate with the KMIP server,
a certificate signing request (CSR) or self signed certificate can be
generated. The generated CSR or certificate is signed with the secure
identity key of the KMIP plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
c56aea0fa9 zkey-kmip: Generate an secure identity key
Authentication with KMIP servers is based on TLS client authentication.
To establish trust between zkey and the KMIP server, a client certificate
must be registered with the KMIP server before a client can communicate
with it.

The signature key of the client's certificate is a secure key created by
zkey. It can either be an RSA or an ECC key, using either CCA or EP11
type crypto adapters configured with the KMIP plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
e24629b977 zkey-kmip: Configure APQNs
The KMIP plugin supports CCA and EP11 APQNs, but only it can only be
configured with one type. Once configured with one type of APQN, it accepts
only APQNs of the same type.

It supports key types matching to the APQn type it is configured with.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
268dcebe23 zkey-kmip: Add new zkey KMS plugin for KMIP
Add support to integrate the external key management systems based
on the KMIP protocol (KMIP: OASIS Key Management Interoperability
Protocol) into zkey by providing a zkey KMS plugin for KMIP. The
plugin communicates with KMIP servers using libkmipclient over a
TLS or HTTPS connection.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
030c0054b1 zkey-ekmfweb: Move some functions used by multiple KMS plugins to common code
Some functions are likely to be used by multiple plugins. Move them
into zkey common code (plugin-utils.c), this module is then linked
into the plugins.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
154914ee7a zkey: Allow KMS plugin to import a key of a specific type
KMS plugins that support multiple key types need to know which
key type to produce with the kms_import_key() function. Extend
the plugin API to allow a plugin to provide a kms_import_key2()
function, that accepts the key type as additional parameter.

Existing plugins do not need to be changed, as the old function
kms_import_key() still exists, and is still used when the plugin
does not provide a kms_import_key2() function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
56fecf1832 libkmipclient: Add KMIP client shared library
libkmipclient is a shared library that provides an KMIP client to
communicate with an KMIP server. KMIP stands for Key Management
Interoperability Protocol, and is an extensible communication protocol
that defines message formats for the manipulation of cryptographic
keys on a key management server.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
081499f355 zkey-ekmfweb: Fix deprecation warnings with OpenSSL 3.0
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
26c34a49b1 libekmfweb: Make use of the new libseckey
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Ingo Franzki
e70cde2c5d libseckey: Add a secure key library
The libseckey is a secure key library to perform secure key operations
with OpenSSL. It provides a framework to create OpenSSL PKEYs with a
secure key attached. Such a PKEY contains the public key parts in clear,
but the private key as secure key blob. Only the private key operations
are actually performed with the secure key, public key operations are
performed in software by OpenSSL. It supports CCA and EP11 secure
keys for RSA and ECC crypto operations.

Because many PKEY method related functions are deprecated since OpenSSL
3.0, two versions of the OpenSSL secure key support are needed. One (using
a PKEY method override) for OpenSSL 1.1.1, and another one (using an own
OpenSSL provider) for OpenSSL 3.0 and later. The desired implementation is
selected automatically at compile time, using OpenSSL version defines. The
interface of both implementations is the same, so a user does not need to
care which one is used.

Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Alexander Egorenkov
fff83fc116 hsavmcore: Let make create list of object files instead of hard-coding it
Use idiomatic make constructs.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:06 +02:00
Alexander Egorenkov
5a7d2a58c8 hsavmcore: Fix fuse dependency checking
all target should not depend on check_dep but only objects which
use fuse header.

This fixes issues with parallel build of hsavmcore.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reported-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:53:04 +02:00
Alexander Egorenkov
89d25559e0 hsavmcore: Disable systemd support during build if systemd header not found
Check for systemd C header and disable systemd support even if HAVE_SYSTEMD
make variable is set to 1.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:49:57 +02:00
Alexander Egorenkov
49901079d4 common.mak: Introduce user-defined function check_header_prereq()
The new user-defined function allows to check for C headers in
make's conditional statements.

Example:

ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
  $(warning "systemd support enabled")
else
  $(warning "systemd support disabled")
endif

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-07 13:49:57 +02:00
Ingo Franzki
317384b5c9 libekmfweb: Ensure that libcurl supports the OpenSSL backend
The callback function used for CURLOPT_SSL_CTX_FUNCTION requires
that OpenSSL is used as SSL backend.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
8db32a8cb9 genprotimg: add --(enable|disable)-pckmo flag
Add the genprotimg flags `--(enable|disable)-pckmo` flag to enable/disable the
support for PCKMO-encrypt-DEA/TDEA/AES/ECC-key functions.

Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
4cf73238fc genprotimg: allow PCKMO functions by default
Allow the PCKMO-encrypt-DEA/TDEA/AES/ECC-key functions to be used in a protected
virtualization guest by default.

Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
27120f2824 genprotimg: rename PV_CFLAG_NO_DECRYPTION to PV_PCF_NO_DECRYPTION
The new name reflects that it's a plaintext control flag. While at it, use a
left shift operation to calculate the value.

Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov
8f32a60c22 zipl: Use util_arch_hsa_maxsize() to compute address limit for kdump
The HSA size, which limits the address space in kdump case, is not constant
and depends on the underlying architecture.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov
0fa2f9acf7 cpumf: Use helpers from util_arch
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov
2ca7db75d3 libutil: Introduce util_arch module
The util_arch module is supposed to provide general information about
the underlying architecture of the machine in use.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Ingo Franzki
02aaff72fa zkey: Use secure_getenv() instead of getenv() for all environment variables
... to avoid vulnerabilities that could occur if set-user-ID or
set-group-ID programs accidentally trusted the environment.

zkey is usually NOT a set-user-ID or set-group-ID program, but its
safer to use secure_getenv() anyway.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
8723dbce04 genprotimg: add OpenSSL 3.0 support
Add OpenSSL 3.0 support while still supporting OpenSSL 1.1.0 and newer. For this
set the OPENSSL_API_COMPAT user defined macro to OpenSSL 1.1.0 (see
https://www.openssl.org/docs/manmaster/man7/OPENSSL_API_COMPAT.html) so we don't
see any deprecation warnings when using OpenSSL 3.0. In addition, add an
compatibility layer for OpenSSL since some OpenSSL API functions were constified
with OpenSSL 3.0.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/112
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
c5d566a4da genprotimg/crypto: use X509_get0_not(After|Before)
Use X509_get0_not(After|Before) since X509_get_notBefore() and
X509_get_notAfter() were deprecated in OpenSSL 1.1.0 (see
https://www.openssl.org/docs/man1.1.0/man3/X509_set1_notBefore.html).

Github-ID: https://github.com/ibm-s390-linux/s390-tools/issues/112
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
d90344a2d5 genprotimg: check return value of BIO_reset
Add missing return value checks for BIO_reset. Unfortunately, the OpenSSL
documentation says:

"BIO_reset() normally returns 1 for success and 0 or -1 for failure. File BIOs
are an exception, they return 0 for success and -1 for failure."

Github-ID: https://github.com/ibm-s390-linux/s390-tools/issues/112
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Marc Hartmayer
71a667fbf0 genprotimg: add missing return values
Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov
d2611b472b gitignore: Ignore all example executables in libutil/
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:06 +02:00
Alexander Egorenkov
34482d67c0 libutil: Refactor and clean up Makefile
Use idiomatic make constructs.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:57:00 +02:00
Alexander Egorenkov
b77523ab4d libutil: Fix typo in doxygen group of util_log
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Jan Höppner
802e5f6607 libutil: Remove /proc/mount related functions
The only user of util_proc_mnt_get_entry() so far was util_path_sysfs().
With the simplified version there is no user left. Remove
util_proc_mnt_get_entry() and related code.

Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Jan Höppner
5e5d49264f libutil: Simplify util_path_sysfs and helper functions
Using util_path_sysfs always leaves 5 bytes of memory unfreed as the
value for the sysfs mount point is stored in a static variable to avoid
multiple queries of /proc/mount.

$ valgrind ./util_path_example sysfs
==3629315== Memcheck, a memory error detector
==3629315== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3629315== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3629315== Command: ./util_path_example sysfs
==3629315==
Path for    cpu: "/sys/devices/system/cpu"
Path for memory: "/sys/devices/system/memory"
==3629315==
==3629315== HEAP SUMMARY:
==3629315==     in use at exit: 5 bytes in 1 blocks
==3629315==   total heap usage: 22 allocs, 21 frees, 18,435 bytes allocated
==3629315==
==3629315== LEAK SUMMARY:
==3629315==    definitely lost: 0 bytes in 0 blocks
==3629315==    indirectly lost: 0 bytes in 0 blocks
==3629315==      possibly lost: 0 bytes in 0 blocks
==3629315==    still reachable: 5 bytes in 1 blocks
==3629315==         suppressed: 0 bytes in 0 blocks
==3629315== Rerun with --leak-check=full to see details of leaked memory
==3629315==
==3629315== For lists of detected and suppressed errors, rerun with: -s
==3629315== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

As per the Kernel rules for accessing sysfs information [1], searching
for the sysfs mount point is a waste of time and systems that don't have
sysfs mounted at /sys are considered broken.

With those things in mind, util_path_sysfs() and especially
sys_mount_point() can be simplified. sys_mount_point() will always
return '/sys' unless the environment variable SYSFS_ROOT is set.

With SYSFS_ROOT still being present, special container setups or test
case scenarios are still possible but might need to be modified if they
previously relied on util_path_sysfs() automatically finding the correct
sysfs mount point.

To make things more secure against malicious strings in SYSFS_ROOT,
secure_getenv() is being used and the ordering of creating the formatted
path string in util_path_sysfs() is changed slightly.

Furthermore, the static variable is removed as no complicated query of
the /proc fs is required anymore. Memory for the sysfs mount point value
is properly freed now at the end of util_path_sysfs().

[1] https://www.kernel.org/doc/html/latest/admin-guide/sysfs-rules.html
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Ingo Franzki
3e818c53b2 zconf/zcrypt: Fix sparse warnings
A compile with sparse (make C=1) shows a couple of warnings:
like:

  chzcrypt.c:36:3: warning: symbol 'l' was not declared.
  Should it be static?

  lszcrypt.c: In function 'show_device':
  lszcrypt.c:556:9: warning: 'card' may be used uninitialized
  [-Wmaybe-uninitialized]

Fix those warnings.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Ingo Franzki
9100d6f40e libutil/util_rec: Declare internal only functions static
A compile with sparse (make C=1) shows the following warnings:

  util_rec.c:211:6: warning: symbol 'rec_print_wide' was not declared.
  Should it be static?
  util_rec.c:383:6: warning: symbol 'rec_print_csv_hdr' was not declared.
  Should it be static?
  util_rec.c:404:6: warning: symbol 'rec_print_csv' was not declared.
  Should it be static?

These functions are only used internally from function util_rec_print_hdr(),
declare them as static.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Ingo Franzki
8bcb93673e libutil/util_opt: Remove unused global variables
A compile with sparse (make C=1) shows the following warnings:

  util_opt.c:42:19: warning: symbol 'util_opt_l' was not declared.
  Should it be static?
  util_prg.c:28:19: warning: symbol 'util_prg_l' was not declared.
  Should it be static?

util_opt_l and util_prg_l are not used anywhere, and also not declared in
any header file. Looks like they are superfluous, remove them.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-07-05 13:55:54 +02:00
Jan Höppner
21fe08ad23 gitignore: Add ctags files
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov
f8d3e5069a hsavmcore: add dracut modules and systemd services for kdump initramfs
* Provide a dracut module and a systemd service for Fedora, RHEL and SLES.
* Provide a systemd service for Ubuntu.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov
9fb2568134 hsavmcore: add man pages for hsavmcore and hsavmcore.conf
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov
a38d82e8f9 hsavmcore: add hsavmcore.conf example
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov
8c9cc6e12a s390-tools: add hsavmcore utility
hsavmcore is designed to make the dump process with kdump more efficient.
With hsavmcore, the HSA memory that contains a part of the production
kernel's memory can be released early in the process. Depending on the size
of the production kernel's memory, writing the dump to persistent storage
can be time consuming and prevent the HSA memory from being reused
by other LPARs.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Ingo Franzki
ce8383e5ac zkey: Fix conversion of CCA DATA keys to CCA CIPHER keys
The CCA Key Translate2 verb needs a pre-built AES CIPHER key token skeleton
with XPRTCPAC set in the output buffer, to produce an AES CIPHER key
that can be exported to CAPCF.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Jan Höppner
9696b4c9b5 gitignore: Add lshwc binary
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Ingo Franzki
466ceb02a1 libekmfweb: Fix certificate extensions compare function
Correctly dereference the extensions passed to the compare function.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov
f6ab7f6cda libutil: Add an example for util_log
Build:
$ make -C libutil/util_log_example

* Every time a -V option is passed, the verbosity level increases and extra
messages are enabled.

Test:
$ ./libutil/util_log_example
 # No output
$ ./libutil/util_log_example -V
ERROR: This is an ERROR message
$ ./libutil/util_log_example -VV
ERROR: This is an ERROR message
 WARN: This is a WARN message
$ ./libutil/util_log_example -VVV
ERROR: This is an ERROR message
 WARN: This is a WARN message
 INFO: This is an INFO message
$ ./libutil/util_log_example -VVVV
ERROR: This is an ERROR message
 WARN: This is a WARN message
 INFO: This is an INFO message
DEBUG: This is a DEBUG message
$ ./libutil/util_log_example -VVVVV
ERROR: This is an ERROR message
 WARN: This is a WARN message
 INFO: This is an INFO message
DEBUG: This is a DEBUG message
TRACE: This is a TRACE message

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Alexander Egorenkov
568caa0501 libutil: Introduce multi-level message logging
The goal of util_log is to provide a facility for a multi-level message
logging on stderr. This allows to selectively enable/disable log messages
via a log level which can be adjusted at runtime.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-06-18 13:20:08 +02:00
Stefan Haberland
2ece47ee1a zdsfs: fix out of bound access in config file parsing
The tmp buffer is one byte too short missing space for the final \0 byte
leading to out of bound access.
Fix by increasing the buffer by one.

Reported-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-21 12:24:27 +02:00
Stefan Haberland
0fafbcf3bb zdsfs: add dataset conversion to manpage
Update zdsfs manpage to include information about dataset conversion.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-21 12:24:27 +02:00
Stefan Haberland
7244785279 zdsfs: transparent codepage conversion
Add transparent codepage conversion feature to zdsfs.
Add options to specify that codepage conversion should be done using
default codepages from 'CP1047' to 'UTF-8' or using user defined codepage
tables.
Also add a new config file allowing the user to specify codepage conversion
options on a per dataset basis.

When a dataset is opened and codepage conversion settings match this
dataset an iconv handle is created and the conversion itself is performed
by the lzds_dshandle_read() function.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-21 12:23:57 +02:00
Stefan Haberland
cdf716a7a9 libzds: add codepage conversion
Add codepage conversion capabilities to libzds.
Whenever a dataset is read and an appropriate iconv handle is set for the
dataset the conversion is automatically performed.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-21 12:21:09 +02:00
Thomas Richter
529ad4000e cpumf/lscpumf.c: Replace function linux_error by err/warn
Replace function linux_error() by err/warn family.
Delete function linux_error() which is not used anymore.
Also fix some checkpatch warnings regarding comparison to zero.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:50:53 +02:00
Thomas Richter
0772c0f01b cpumf/chcpumf: Simplify function read_sfb
Simplify function read_sfb(). Convert it to type void
and return only when no errors occurred.
On error print error message and exit instead of return.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:50:53 +02:00
Thomas Richter
27a562da0a cpumf/lshwc: Program to extract complete counter sets
Program reads complete counter sets from any CPU by opening
device /dev/hwctr which is available with linux version 5.12.
The counter sets and CPUs can be specified on the command line.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:50:48 +02:00
Thomas Richter
cd532cb6cd cpumf/chcpumf: Replace linux_error by err/warn
Replace function linux_error() by err/warn functions.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:45 +02:00
Thomas Richter
80b1306102 cpumf/chcpumf: Replace fprintf to stderr by err/warn
Replace fprintf(stderr,...) by warnx and errx.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:45 +02:00
Stefan Haberland
4b0403a963 zdsfs: improve man page for coordinated read access
Incorporate some ID feedback.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter
1d9e7b614c cpumf/chcpumf: Use util_opt_print_parse_error function
Use function util_opt_print_parse_error() instead of fprintf to stderr.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter
44de579311 cpumf/chcpumf: Simplify comparison against 0
Simplify comparison against 0 or NULL and fix a checkpatch.pl
warning.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Wenjia Zhang
4fb18a1e7b znetconf: avoid conflict with "chzdev -e"
Using "chzdev -e" to configurate a device persistently, the
corresponding udev rule is also created, which will trigger a uevent
that sets the device online as soon as the group device is created.

If 'znetconf -r/R' is first used to remove such a configured device
(which won't remove the corresponding udev rule) and then
'znetconf -a/A' afterwards on the same device, either the error
"Failed to make <device> online" or "Failed to configure layer2=1"
will occur.

For the first error, the udev queue might not have been fully processed
and hence the check whether a device is online may fail due to that
race. Call 'udevadm settle' to ensure a fully processed queue before
checking whether a device is online.

The second error occurs, because configure_ccwgroupdev_option() does
not check whether the device is online. Add the check and set the
device offline if necessary. Also, log any details for debugging
purposes.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter
59206b88d8 cpumf/lscpumf: Use util_opt_print_parse_error function
Use function util_opt_print_parse_error() instead of
fprintf to stdout.

Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Thomas Richter
7a64b88396 cpumf/lscpumf: Use warnx instead of fprintf
Use function warnx() instead of fprintf() to stderr.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Siglen
b7807d0195 dbginfo.sh: Add KVM commands and rework data collection
Add virsh commands for KVM debug data collection and rework the domain
data collection and step numbering. Update the man page accordingly.

[hoeppner@linux.ibm.com: Reword commit message]
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Siglen
2f436d6ee0 CHANGELOG.md: Add dbginfo changes
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Siglen
302cd4ed7e dbginfo.sh: fix typo
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Jan Höppner
69526998f0 libdasd: Check return value for util_file_read_l
The return code of util_file_read_l() isn't checked and therefore
'value' could contain anything in case of an error. Check the return
code and set 'value' to 0 in the error case.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/110
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-05-20 18:49:44 +02:00
Stefan Haberland
a65bc51cf4 udev/dasd: change DASD udev-rule to set none scheduler
Performance evaluation showed that using the mq-deadline scheduler for DASD
devices leads to a significantly higher CPU consumption compared to using
none scheduler while having the same amount of throughput.
Setting none scheduler as default in the dasd udev rule.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Mario Held
eb1fd47a85 dbginfo: Added and removed commands
Added kallsyms and lscpu -ye, added vmcp commands
q memassist, q pcifunction, q vmrelocate and removed q cache

Signed-off-by: Mario Held <mario.held@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Ingo Franzki
c4918fe713 zkey: Fix typos in man pages
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Jan Höppner
d23558f1d1 ttyrun-getty: Avoid conflicts with serial-getty@
Starting ttyrun-getty@ will fail as it conflicts with the serial-getty@
service. Add Conflicts= option to avoid any conflicts.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/105
Suggested-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-03-16 17:18:51 +01:00
Fabrice Fontaine
3d79a542d4 osasnmpd/Makefile: fix cross-compilation
Fix the following build failure by allowing the user to provide
NET_SNMP_CONFIG:

/bin/sh: net-snmp-config: command not found
/home/buildroot/autobuild/run/instance-2/output-1/host/lib/gcc/s390x-buildroot-linux-gnu/9.3.0/../../../../s390x-buildroot-linux-gnu/bin/ld: osasnmpd.o: in function `main':
osasnmpd.c:(.text.startup+0xcc): undefined reference to `snmp_log_perror'

Fixes: http://autobuild.buildroot.org/results/00796f2ebd5fb0e08ac7a05a9ee566f2bc4bd1c3
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/99
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-24 18:34:27 +01:00
Marc Hartmayer
b6bdd7744a genprotimg: use pv_ namespace for our Buffer implementation
Use `pv_` namespace for our Buffer implementation so a symbol clash with other
libraries is less likely.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/109
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-24 18:33:44 +01:00
Ingo Franzki
3f3f063c98 zkey: Fix build error when the compiler flags are overridden
When the compiler flags are overridden, the build of zkey may fail with:

kms.c:44:2: error: #error KMS_PLUGIN_LOCATION must be defined
   44 | #error KMS_PLUGIN_LOCATION must be defined
      |  ^~~~~

The Makefile uses CFLAGS variable for defining the KMS_PLUGIN_LOCATION,
but it should rather use ALL_CFLAGS.

Also use ALL_CPPFLAGS for defining HAVE_LUKS2_SUPPORT.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/108

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-23 16:49:09 +01:00
Jan Höppner
78d63f2333 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-23 16:49:09 +01:00
Jan Höppner
1bb9a9ec5b New release s390-tools-2.16.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 15:46:37 +01:00
Nikita Dubrovskii
4a3957fab5 zipl: fix reading 4k disk's geometry
On 4k SCSI disks zipl stores wrong values to 'scsi_mbr.program_table_pointer',
which makes system unbootable.
This happens in 'zipl/src/disk.c:656':

```
/* Convert file system block to physical */
*physical = mapped * phy_per_fs + subblock;
/* Add partition start */
*physical += info->geo.start;

```

So 'hd_geometry.start' should be adjusted before being used.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1918723
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/107
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Ingo Franzki
e506c94839 zkey-ekmfweb: Fix typos in messages
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Wenjia Zhang
dfd9f52873 hsci: fix packet loss caused by large MTU
For maximum performance the MTU of an HSCI interface was set to the value
of the MTU of its HiperSockets interface. However, the MTU of a
HiperSockets interface can be very large, and when the data packets are
not sent over the HiperSocket but over the corresponding ethernet
interface (which usually has a smaller MTU size) then it can happen that
the large packets are silently dropped. One example would be communication
from an HSCI in one CEC to another HSCI in another CEC via Ethernet.

To solve the problem, the MTU setting in this tool is removed, and the
default MTU value is used. Thus, the minimum value of the MTUs of the both
converged interfaces is used as the MTU of the HSCI interface.

Fixes: 0566a492ae ("s390-tools: add hsci tool")
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Jan Höppner
14ca7c5080 s390-tools: Change GitHub link to new name
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Steffen Maier
4fc1a92a8d zfcpdbf: deal with crash 7.2.9 change in caller name formatting
Since crash 7.2.9 commit
f1f43bf355
in support of kernel v5.9 commit 0990d836cecb
("s390/debug: debug feature version 3"),
the symbolic caller function name is left aligned instead of right
aligned, so now we alternatively have to remove whitespace between
function name and offset.

Otherwise, zfcpdbf output contains wrong warnings about ambiguous payload
records with wrong values for reqid and area, as well as incorrectly
decoded trace records with wrong content values and potential error
messages on not defined record id, and finally a potential list of
occurrences of unknown tags which should empty:

Loading trace records ...(this might take a while)
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:V^D^@fcp_
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:W^D^@fsf_
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:i^B^@san_

...

Timestamp      : ...
Area           : SAN
Subarea        : 00
Level          : 1
Exception      : -
CPU ID         : 0001
Caller         : <zfcp_dbf_san_in_els
Record ID      : 0
Tag            : 6^B^Cfcie
Request ID     : >>>wrong<<<
Destination ID : >>>wrong<<<
SAN record id=0 not defined.
Timestamp      : ...
Area           : SAN
Subarea        : 00
Level          : 1
Exception      : -
CPU ID         : 0002
Caller         : <zfcp_dbf_san_in_els
Record ID      : 0
Tag            : 6^B^Cfcie
Request ID     : >>>wrong<<<
Destination ID : >>>wrong<<<
SAN record id=0 not defined.

...

occurrences of unknown tags:
...

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:46:54 +01:00
Ingo Franzki
d73d7f91ac zkey-ekmfweb: Fix typos in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov
800df6bef8 zipl/boot: fix heap OOM in stage2 of DASD dumper
For the stage2 of zipl's boot loaders only 3 heap pages are available
[0x6000, 0x6000 + 0x3000]. Therefore, stage2 code needs to be very careful
when and for how long it allocates a heap page.

The heap OOM problem in stage2 was hidden until the commit 252be376
("zipl/boot: fix potential heap overflow in stage2"). Before this commit,
stage2 assumed that heap is 4 pages large which is apparently very wrong
but get_zeroed_page() still allowed allocating an extra 4th page by
overriding the memory segment following the heap area of stage2 (stage3
parameter area).

Try to avoid allocating a heap page and keeping it allocated over a long
period of time in the DASD dumpers. Free a heap page as soon as possible
if not required anymore.

And be extra careful with printf() because it always tries to allocate
a free heap page.

Fixes: 252be376 ("zipl/boot: fix potential heap overflow in stage2")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Marc Hartmayer
3c661da4ee genprotimg: boot: make boot loader -march=z900 compatible
Replace the `lgfi` opcode with equivalents as z900 has no support for
it.

While at it, fix a comment in `genprotimg/boot/head.S` and remove a
useless label in `genprotimg/boot/stage3b_reloc.S`.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/86
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Ingo Franzki
bf5ca4367d libekmfweb: Check length of JWK EC public key coordinates
RFC 7517 requires that the x and y coordinates of a ECC JSON Web Key
(JWK) are specified in its full size of a coordinate for the curve used.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Wenjia Zhang
faf26220a7 hsci: fix failed to delete an HSCI connected with VLAN
Deleting an HSCI interface, the connected HiperSockets interface's name
and the connected Ethernet interface's name are extracted from "ip link
show". Currently the extracted names are directly used in "bridge -d link
show dev ifname" for further checking. If "iflink" and "ifindex" of an
interface are not matched, ip commands will print @ifXX appended to the
real interface's name. Thus, it will be failed if the interface's name
with the ending @ifXX is used in "bridge -d link show dev ifname" for
further checking.

To solve the problem, the ending @ifXX must be removed before the
interface name is used further.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Wenjia Zhang
522252d18a hsci: fix wrong return code
In the current code, after the function check_pnetids() and the function
verify_precon() are called, $? from each function is used twice
successively. It is used for the first time in the condition of the IF
statement, while for the second time as return code of the current
function. In bash, $? can be used to get the return code, but only for
the first time directly after the previous function is called.
Afterwards, $? will be reset to "0". Thus, the right return code can not
be get, if $? is used second time.

To solve the problem, using $? for the second time should be avoided.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov
42889edc0c make: add address sanitizer support
Install libasan first, e.g. on Fedora 32:
  dnf install -y libasan libasan-static.

To compile with address sanitizer, pass ASAN=1 to make.
AdressSanitizer helps to catch various memory bugs for which C/C++ is
infamous.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov
13016ebc5a cmsfs-fuse: ASAN fix dec_to_hex() and hex_to_dec()
This fixes the following compiler errors when ASAN is enabled:

  CC      cmsfs-fuse/cmsfs-fuse.o
cmsfs-fuse.c: Assembler messages:
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Ingo Franzki
c4546daf34 zkey-ekmfweb: Avoid sequence number clash when generating keys
When keys are generated concurrently in EKMF Web from multiple clients,
and the key labels use a sequence number tag, then the assignment logic
of the sequence number may cause a duplicate sequence number to be used,
because another key might have already been generated with the same
sequence number, since the next-to-use sequence number has been retrieved
from EKMF Web. This results in a HTTP response code of 409 and a -EEXIST
return code from ekmf_generate_key().

Instead of getting the last used sequence number from EKMFWeb, tell
EKMFWeb to automatically use the next available sequence number when
generating a key. When the sequence number label tag value is 'next'
then EKMFWeb will automatically assign the next available sequence number
to the label tag and increment the sequence number in an atomic way.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov
1e18429f69 zdump: fix invalid memory access on memory chunk's data
If a memory chunk is added to mem_phys as well as mem_virt
in dfi_mem_chunk_add_vol() then an illegal memory access might occur
when accessing mem_chunk->data e.g. in dfi_elf_mem_chunk_read_fn()
because the data block pointed to by the data field is now being referenced
by two memory chunks, one in mem_phys and one in mem_virt. If it happens
that the memory chunk from mem_virt is freed in mem_unmap() then
the memory chunk in mem_phys still points to the common data block
which has been already freed. This leads to all sort of bad behavior
in dfi_elf_mem_chunk_read_fn() and other places where mem_chunk->data
might be accessed.

Fixes the following bug:
zgetdump: Unexpected end of file for "dump.all.elf"

And this was found by AddressSanitizer:

=================================================================
==81170==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000570 at pc 0x00000101ac10 bp 0x03ffd897e250 sp 0x03ffd897e248
READ of size 8 at 0x602000000570 thread T0
    #0 0x101ac0f in dfi_elf_mem_chunk_read_fn s390-tools/zdump/dfi_elf.c:27
    #1 0x100d8a5 in mem_read s390-tools/zdump/dfi.c:339
    #2 0x100d8a5 in dfi_mem_phys_read s390-tools/zdump/dfi.c:616
    #3 0x100d8a5 in mem_chunk_map_read_fn s390-tools/zdump/dfi.c:353
    #4 0x100fd29 in mem_read s390-tools/zdump/dfi.c:339
    #5 0x100fd29 in dfi_mem_read s390-tools/zdump/dfi.c:608
    #6 0x1018e89 in os_info_get s390-tools/zdump/dfi_vmcoreinfo.c:65
    #7 0x1018e89 in dfi_vmcoreinfo_init s390-tools/zdump/dfi_vmcoreinfo.c:86
    #8 0x10175b3 in dfi_init s390-tools/zdump/dfi.c:1215
    #9 0x1006e71 in do_stdout s390-tools/zdump/zgetdump.c:161
    #10 0x1006e71 in main s390-tools/zdump/zgetdump.c:180
    #11 0x3ffb07abb89 in __libc_start_main (/lib64/libc.so.6+0x2bb89)
    #12 0x1007e8d  (s390-tools/zdump/zgetdump+0x1007e8d)

0x602000000570 is located 0 bytes inside of 8-byte region [0x602000000570,0x602000000578)
freed by thread T0 here:
    #0 0x3ffb0bc961b in free (/lib64/libasan.so.6+0xc961b)
    #1 0x100d2d9 in mem_unmap s390-tools/zdump/dfi.c:1050

previously allocated by thread T0 here:
    #0 0x3ffb0bc9aa9 in calloc (/lib64/libasan.so.6+0xc9aa9)
    #1 0x100a271 in zg_alloc s390-tools/zdump/zg.c:93

SUMMARY: AddressSanitizer: heap-use-after-free s390-tools/zdump/dfi_elf.c:27 in dfi_elf_mem_chunk_read_fn
Shadow bytes around the buggy address:
  0x100c0400000050: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000060: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000070: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000080: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000090: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
=>0x100c04000000a0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa[fd]fa
  0x100c04000000b0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x100c04000000c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa 04 fa
  0x100c04000000d0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c04000000e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x100c04000000f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==81170==ABORTING

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov
11e78cada5 zdump: catch attempts to seek past end of file in zg_seek()
Make zg_seek() more robust.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov
0a7df9e030 zdump: improve error handling in pt_load_add()
Verify the given ELF header before adding any memory chunks otherwise
a memory chunk might be added even if the given ELF header is invalid.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Vineeth Vijayan
7dd03eaeec zdev: Add build option to update initial RAM-disk by default
Some Linux distributions always include a copy of all persistent device
configuration data when updating the initial RAM-disk. This makes
chzdev's persistent device configuration changes ineffective because
device configuration directives applied in the RAM-disk take precedence
over those stored in the root filesystem.

This patch introduces a new build-time switch which allows distributions
to specify that whenever there is a persistent device configuration
change, the RAM-disk is updated automatically.

This feature can be enabled by adding 'ZDEV_ALWAYS_UPDATE_INITRD=1' as
a zdev build option. Where, by default ZDEV_ALWAYS_UPDATE_INITRD is 0.

Co-developed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Ingo Franzki
663262c962 zkey: Prevent sporadic error during key verification pattern generation
After a master key change, it can happen that the AF_ALG setkey
operation returns EINVAL, although the key is valid. This is a
temporary situation and the operation will succeed, once the firmware
has completed some internal processing related with the master key
change. Delay 1 second and retry up to 10 times.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Nikita Dubrovskii
bf9482709f fdasd: Use increased retry count for dasd_reread_partition_table
If fdasd is used right after dasdfmt, it may fail with the following
error due to udev still processing events for the device:

```
fdasd error:  IOCTL error: Error while rereading partition table.
```

Call dasd_reread_partition_table() with an increased retry value to
circumvent this issue.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/103
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
[hoeppner@linux.ibm.com: Reword commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Dan Horák
cdf0b5d66f hsci: fix help text
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/102
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Vance Morris
4aafd6962a netboot: Bump busybox version in pxelinux.0 build
`stime` was removed in glibc-2.31.
Busybox fixes this in https://git.busybox.net/busybox/patch/?id=d3539be8f27b8cbfdfee460fe08299158f08bcd9

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/100
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/101
Signed-off-by: Vance Morris <vmorris@us.ibm.com>
Reviewed-by: Viktor Mihajlovski mihajlov@de.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
863e1c3fa4 zkey: Remove warning about sector size support with crypttab
Current distributions should now all support the sector size option
in crypttab entries for plain mode dm-crypt volumes.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
7c47ea8e09 zkey: Add support to store LUKS2 dummy passphrase in key repository
Extend zkey to allow to store a (dummy) LUKS2 passphrase together with a
secure key, for use with LUKS2 volumes. That way, when the repository is
backed up, or archived, also the passphrases of the associated LUKS2
volumes are backed up, or archived, and thus can not be forgotten.
This passphrase is then used in generated commands to format and open
the LUKS2 volumes.

Because of the use of secure keys to encrypt the volumes, the LUKS2
passphrase is of no or less relevance for security. It is therefore OK to
store the passphrase in clear text in the key repository, and also use
them in /etc/crypttab. Therefore, the passphrase could actually be a
trivial passphrase, or a dummy passphrase.

Note: Such a dummy passphrase is NOT considered a secret that needs to
be protected. If for a certain usage the passphrase is of relevance for
security, then the zkey dummy passphrase option must not be used to store
the passphrase.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov
c239d99379 genprotimg: do not fail on inline warnings caused by glib
gcc's -Werror switch also enables -Werror=inline which leads to a compilation
failure due to inline warnings caused by GLIB macros. To fix it, disable
the conversion of inline warnings into errors.

In file included from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/lib/glib-2.0/include/glibconfig.h:9,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/gtypes.h:32,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/galloca.h:32,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib.h:30,
                 from pv/pv_hdr.c:10:
buildroot/qemu-s390x/build/s390-tools-2.15.1/genprotimg/src/utils/buffer.h: In function ‘pv_hdr_new’:
buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/gmacros.h:1028:49: error: inlining failed in call to ‘glib_autoptr_clear_Buffer’: call is unlikely and code size would grow [-Werror=inline]
 1028 | #define _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) glib_autoptr_clear_##TypeName
      |                                                 ^~~~~~~~~~~~~~~~~~~

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov
6c6e3a2b0e zipl/boot: fix potential heap overflow in stage2
Current heap size in stage2 is three pages long [0x6000-0x9000] but
get_zeroed_page() assumes it is one page more which might lead to
a heap overflow which will corrupt data located at 0x9000 (stage3
parameters). Calculate the heap size of a stage at run-time
by using the symbols provided by linker.

Furthermore, validate the given address in free_page() to stop illegal
memory accesses.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov
2dca5d193f zipl/boot: fix memory use after free in stage2
Prevent access to freed memory still pointed to by entry.
entry still points into load_page that has been released with free_page.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
75675ec627 libekmfweb: Make install directory for shared libraries configurable
If LIBDIR is not passed to the make invocation, install shared libraries
to USRLIB64DIR (/usr/lib64/), even though LIBDIR defaults to /lib/. If
LIBDIR is overridden for the make invocation, install shared libraries to
whatever is specified as LIBDIR.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/98

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
18bf2cce06 zkey/zkey-ekmfweb: Install KMS plugins into configurable location
Install KMS plugins into a configurable location. The default KMS plugin
location is '/usr/lib64/zkey/', but one can set ZKEYKMSPLUGINDIR on the make
invocation to change the plugin location, e.g. to '/usr/libexec/zkey/'.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/98

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
8781dd3e7b zkey-ekmfweb: Fix selection of key properties to set or remove
When some of the key properties are skipped due to null_values_only
being true or false, then the resulting EKMF tag list might be built
incorrectly.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
6380e77f28 zkey-ekmfweb: Allow NULL as property value to remove a property
To remove a KMS property function kms_set_key_properties() can be
called with the property value set to NULL. Do not assert for non-NULL
property values.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer
733b86c02a genprotimg: remove -Winline cflag
`-Winline` can cause problems with the cleanup functions defined by
glib. Therefore let's remove the cflag for now.

DEBUG: /usr/include/glib-2.0/glib/gmacros.h:1031:43: error: inlining failed in call to 'glib_autoptr_cleanup_STACK_OF_X509_CRL.isra.0': call is unlikely and \
code size would grow [-Werror=inline]
DEBUG:  1031 | #define _GLIB_AUTOPTR_FUNC_NAME(TypeName) glib_autoptr_cleanup_##TypeName

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer
7827a791c9 genprotimg: add missing return
This should be no problem (if OpenSSL works correctly), because
`crls_download_cb` is only called out of the verification context of
OpenSSL. It's used to look up a CRL and therefore
X509_STORE_CTX_get_current_cert should always return a certificate
since X509_STORE_CTX_get_current_cert returns NULL only if an error
has occurred during the verification (see
https://www.openssl.org/docs/man1.1.0/man3/X509_STORE_CTX_get_current_cert.html).

Fixes: 074de1e14e ("genprotimg: add host-key document verification support")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer
074de1e14e genprotimg: add host-key document verification support
Add host-key document verification support to genprotimg. This ensures
that a host-key document is genuine and provided by IBM. For this the
user must provide the IBM Z signing key, the intermediate CA
certificate (signed by the root CA used) so a chain of trust starting
from the host-key document and ending in the root CA can be
established.

By default, genprotimg tries to download all revocation lists needed
by looking up in the corresponding certificate on how CRL information
can be obtained (see https://tools.ietf.org/html/rfc5280#section-4.2.1.13
for details).

Acked-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Ingo Franzki
07d181e29b zkey: Fix APQN property names
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Marc Hartmayer
895a88b2f8 genprotimg: require argument for 'ramdisk' and 'parmfile' options
A argument is required for the optional options 'ramdisk' and
'parmfile'.

Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Ingo Franzki
f01f8b240c zkey-ekmfweb: Fix typo in message
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Jan Höppner
be2bc610b7 netboot: Add version information to scripts
Add the -v short option for version information to the mk-s390image and
mk-pxelinux-ramfs. Adjust the Makefile accordingly to set the correct
s390-tools version during installation.

Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Marc Hartmayer
c48d45ba92 common.mak: use '--' for rm calls to distinguish between options and files
Use '--' for rm calls to distinguish between options and files. This
fixes, for example, the following error:

make[1]: Entering directory '/root/git/s390-tools/genprotimg/src'
rm -f *.gcda *.gcno *.gcov
rm: invalid option -- '.'
Try 'rm ./-.gcno' to remove the file '-.gcno'.
Try 'rm --help' for more information.
make[1]: *** [../../common.mak:369: clean_gcov] Error 1

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Thomas Richter
886476a207 cpumf/chcpumf.c: Print proper error message on non-root invocation
chcpumf must be executed as root. A non-root user sees this error
message:

[tester@t35lp46 ~]$ chcpumf -m 1000
Error: /sys/module/kernel/parameters/cpum_sfb_size: Permission denied
[tester@t35lp46 ~]$

Enhance the error message and be clear about the root cause:
[tester@t35lp46 ~]$ chcpumf-new  -m 1000
Error: Must run as root
[tester@t35lp46 ~]$

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Thomas Richter
86685f001d cpumf/lscpumf.c: Check for help and version options first
Check command line arguments for help text and version
string first, before doing any action. This ensures this
information is always printed, even when invoked as non-root
user.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/97
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Jan Höppner
d619b492e9 lsdasd: Add FC Endpoint Security information
Provide the status of the FC Endpoint Security information via the long
output of lsdasd for online Base and Alias devices.

New Output:

$ lsdasd -l c600
0.0.c600/dasdd/9412
  status:                               n/f
  type:                                 ECKD
  blksz:                                512
  size:
  blocks:
  extent_size:                          1113
  logical_capacity:                     1113
  space_allocated:                      1113
  use_diag:                             0
  readonly:                             0
  eer_enabled:                          0
  erplog:                               0
  hpf:                                  1
  uid:                                  IBM.750000000KMV11.c600.00
  fc_security:                          Encryption
  paths_installed:                      38 39 3a 3b
  paths_in_use:                         38 39 3a 3b
  paths_non_preferred:
  paths_invalid_cabling:
  paths_cuir_quiesced:
  paths_invalid_hpf_characteristics:
  paths_error_threshold_exceeded:

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 10:50:48 +01:00
Jan Höppner
79e4798061 zdev: Add FC Endpoint Security information for DASD devices
Provide information for the DASD device attribute 'fc_security'.
The help output for this attribute can be queried like this:

chzdev dasd --help-attribute

The lszdev tool can be used to display the current state of the FC
Endpoint Security information:

lszdev dasd -a -c TYPE,ID,ATTR:fc_security,ATTRPATH:fc_security

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 10:50:48 +01:00
Ingo Franzki
cf2311f1f1 zcryptstats: Fix handling of partial results with many domains
When many domains per card are available, then the results of the SCDMD
CHSC call may not fit into the output area, and a partial result is
returned. The further results must be retrieved with another CHSC call.

Fix the code to pass the correct next-domain to the subsequent CHSC call
of a partial response. Otherwise the same set of domains 1 to n are
retrieved again, resulting in an infinite loop, because this will always
produce a partial result.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 08:06:11 +01:00
Colin Walters
7e832da790 systemd/cpi.service: Add RemainAfterExit=yes
Noticed this while looking at the unit file for a different
RHEL CoreOS issue.

See https://github.com/ostreedev/ostree/pull/1697
and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750683

Omitting this can cause the service to run multiple times if
something else ends up depending on it, which I'm guessing
we don't want.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/72
Signed-off-by: Colin Walters <walters@verbum.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Dan Horák
3b402a0630 lscpumf: add z15 Model T02
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/87
Signed-off-by: Dan Horák <dan@danny.cz>
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Dan Horák
3437c9bb90 netboot/mk-s390image: add simple man page
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/94
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Philipp Kern
8898650266 scripts/zipl-switch-to-blscfg.1: Fix some typos
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/90
Signed-off-by: Philipp Kern <pkern@google.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Prashanth Sundararaman
3ae2100d5e systemd/cpi.service: Add sysinit.target dependency to make sure /var is created
Noticed on RHEL CoreOS that the CPI service failed to start with:

"Cannot access lock file: /var/lock/cpictl.lock"

This was a timing issue where /var was not created yet and the symlink
to /run/lock was not present. Add sysinit.target to fix this.
This fix has been tested with RHEL CoreOS.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/82
Signed-off-by: Prashanth Sundararaman <psundara@redhat.com>
Suggested-by: Colin Walters <walters@verbum.org>
Reviewed-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Alexander Egorenkov
93e4249fd3 zkey/ekmfweb: fix linking of libekmfweb
Use -L compiler's parameter instead of the environment variable
LIBRARY_PATH.

Fixes the following problem on buildroot:

buildroot/qemu-s390x/host/bin/s390x-linux-gcc -shared -Wl,--version-script=zkey-ekmfweb.map -Wl,-z,defs,-Bsymbolic -Wl,-soname,zkey-ekmfweb.so.1 zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o ../..//libutil/libutil.a -lekmfweb -ldl -lcrypto -o zkey-ekmfweb.so
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c udev_ccwgroup.c -o udev_ccwgroup.o
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c iscsi.c -o iscsi.o
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c dasd.c -o dasd.o
buildroot/qemu-s390x/host/opt/ext-toolchain/bin/../lib/gcc/s390x-buildroot-linux-gnu/9.3.0/../../../../s390x-buildroot-linux-gnu/bin/ld: cannot find -lekmfweb
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:36: zkey-ekmfweb.so] Error 1
make[3]: *** [Makefile:128: ekmfweb] Error 2
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c zfcp.c -o zfcp.o
make[2]: *** [Makefile:43: zkey] Error 2
make[2]: *** Waiting for unfinished jobs....

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Jan Höppner
8ec4705239 libutil: Compare proc entries to vfstype
Modern systems have systemd manage system mount points like sysfs which
specify 'sysfs' as a keyword for the device as there is no device
associated with this special filesystem. However, any arbitrary string
could be specified here and the determination of the sysfs mount point
would fail in such a case.
To make sure that the mount point of the sysfs is still found when
mounted with a device keyword specified other than 'sysfs', check for
the filesystem type instead, which is more specific.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/91
Suggested-by: Mark Post <mpost@suse.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 12:24:32 +01:00
Jan Höppner
cad450fdf9 dasdfmt: Make error function less error-prone
Add a proper definition to the dasdfmt header file of the error()
function that lets the compiler check the format string against the
provided parameters.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 12:24:32 +01:00
Dan Horák
3a1cda59ce libekmfweb: fix permissions for ekmfweb.h
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/96
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 10:39:46 +01:00
Wenjia Zhang
0566a492ae hsci: Add new tool to control HiperSockets Converged Interfaces
hsci is used to control and show HSCI (HiperSockets Converged Interfaces)
settings. A HiperSockets interface and an external network interface are
converged to an HSCI interface.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 10:16:22 +01:00
Marc Hartmayer
bc7359d2a3 iucvterm: abort if one of the recursive targets is failing
Abort processing as soon as one of the recursive targets is failing.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Marc Hartmayer
db6f272607 genprotimg: fix two memory leaks
==1005844== HEAP SUMMARY:
==1005844==     in use at exit: 18,907 bytes in 14 blocks
==1005844==   total heap usage: 82 allocs, 68 frees, 32,529 bytes allocated
==1005844==
==1005844== 136 (104 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 14
==1005844==    at 0x483885A: calloc (vg_replace_malloc.c:760)
==1005844==    by 0x48C950D: g_malloc0 (gmem.c:132)
==1005844==    by 0x100EC41: pv_args_new (pv_args.c:364)
==1005844==    by 0x100587F: main (genprotimg.c:122)
==1005844==
==1005844== LEAK SUMMARY:
==1005844==    definitely lost: 104 bytes in 1 blocks
==1005844==    indirectly lost: 32 bytes in 1 blocks
==1005844==      possibly lost: 0 bytes in 0 blocks
==1005844==    still reachable: 18,771 bytes in 12 blocks
==1005844==         suppressed: 0 bytes in 0 blocks
==1005844== Reachable blocks (those to which a pointer was found) are not shown.
==1005844== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1005844==
==1005844== For lists of detected and suppressed errors, rerun with: -s
==1005844== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Marc Hartmayer
6db7fbe018 genprotimg: abort if one of the recursive targets is failing
Abort compilation as soon as one of the recursive targets is failing.

Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Sven Schnelle
2f154fa49d cmsfs-fuse: fix pointer block level calculation
Adding one to the pointer per block value results in a wrong
calculation of pointer block levels. When writing a file that
would result in about 454MB size, the code would calculate that
it needs a two level pointer directory but correct would be a three
level pointer directory. This causes an invalid filesystem state:
besides missing all the records of one top level pointer directory
entry, it would also record a higher record number in the FST than
what is present in the pointer blocks.

Note that this bug only hits when the file is about 454MB and the write
is stopped (means the file is closed) - if file writing continues the
problem doesn't happen because at some point in time cmsfs-fuse would
switch to three levels of pointer blocks anyways as the file grows.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Jan Höppner
148d3f9b64 dasdfmt: Fix segfault when an incorrect option is specified
When specifying an incorrect program option, dasdfmt segfaults as the
format string for the corresponding error message has no parameter.
Add the missing parameter to fix this.

Fixes: 732b3dddab ("dasdfmt: Replace ERRMSG_EXIT macro with an error handling function")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Brian C. Lane
702dc96264 netboot: Clear kernel cmdline data before writing new parmfile
If this isn't cleared first it can end up with an unexpected cmdline if
it doesn't completely overwrite the default data.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/95
Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Jan Höppner
313092b202 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Jan Höppner
b098990abe New release s390-tools-2.15.1
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:31:59 +01:00
Stefan Haberland
6802b86414 libutil: determine base device address in case of given partition
util_sys_get_dev_addr() returns the device address for a given blockdevice.
This does not work for partitions but some tools rely on the ability to get
the device address for partitions.

Add code that first determines the base device for a partition.

Fixes: 6014d07cb1 ("dasdview/libdasd/zipl: Use util_sys_get_dev_addr() instead of u2s_getbusid()")
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:29 +01:00
Stefan Haberland
aa8c2945cc zipl: make use of util_sys functions to get base device
Remove the implementation in zipl and use the util_sys one.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:24 +01:00
Stefan Haberland
fa7a4dafa3 libutil: add function to get base device for blockdevice
Some operations are only possible on base devices not on partitions.
Add functions to determine if a given device is a partition or a base
device and to get the base device to a given partition.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:02 +01:00
Jan Höppner
7eb04cdc54 zfcpdump: Fix dump location in README
Commit 724f1fea2c ("Makefile: Rename ZFCPDUMP_PART_* macros") renamed
the zfcpdump image from zfcpdump_part.image to zfcpdump-image. Fix the
image name in the README as well.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/89
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
d55b787d05 zgetdump: Fix device node determination via sysfs
When using zgetdump on a multi-volume device dump, the sysfs path to
determine the device node is incomplete, resulting in the following
error:

$ zgetdump -i /dev/dasdb1
zgetdump: Could not open "/sys/bus/ccw/devices/0.0.9300/dasdb/dev" (No
such file or directory)

A simple fix would be to add the missing "block" part in the sysfs path.
However, the logic still assumes sysfs links like "block:" that have
been deprecated a decade ago and are no longer present on modern
systems anyway.
Therefore, the logic can greatly be improved. Create a separate function
to determine whether a device is online, remove the logic for "block:"
entries, and use libutil functions to reduce the complexity even further.

Fixes: 70a79fab3c ("zgetdump: Avoid using PATH_MAX")
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
da4fdeeb82 dasdfmt: Set prog_name to last component of program name
In the process of switching to glibc defined error functions it becomes
apparent that self-defined error functions that do special things are
not in line with the output of the glibc functions.

To address this, set the prog_name variable to the last component of the
program name (stored in argv[0]) and guarantee a uniform error output.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
9fe491df27 dasdfmt: Improve error message construction
In check_track_format() the base error message is the same for all cases
but has different additional content depending on which mode dasdfmt is
running.

Currently the message is compiled by using different outputs. To make it
a little bit cleaner and for a better error message handling, construct
the message string completely before passing it to the error() function
for output.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
732b3dddab dasdfmt: Replace ERRMSG_EXIT macro with an error handling function
The ERRMSG_EXIT macro is a bit clunky in its usage and a change is
necessary in order to free memory in error cases.

Create a new function error() that takes only a format string and adds
all other relevant information by itself. This function frees memory
before terminating the program with the EXIT_FAILURE exit code.

This simplifies the error handling for pretty much all calls and makes
the code a bit cleaner.

While at it, the defines EXIT_MISUSE and EXIT_BUSY don't provide any
value. Neither are they documented nor are these standardized. Also, a
parent process is mostly interessted in success or failure only anyway.
Replace these by using only EXIT_FAILURE in the error() function.

Also, change multiline output to a combination of warnx and error to
have a uniformed output. So this:

WARNING: Device is formatted with a different blocksize (4096).
Use --mode=full to perform a clean format.

becomes this:

dasdfmt: WARNING: Device is formatted with a different blocksize (4096).
dasdfmt: Use --mode=full to perform a clean format.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
cb76e39cef dasdfmt: Fix bad file descriptor error when running on symlinks
When calling dasdfmt on device node symlinks like
/dev/disk/by-id/ccw-0X9300, dasdfmt fails with "dasdfmt: the ioctl to get
the blocksize of the device failed (Bad file descriptor)"

This is because before the actual formatting process starts, the disk
will be disabled calling the BIODASDDISABLE ioctl, resulting in the
removal of the symlink. Trying to open this file later in the process to
retrieve e.g. blocksize information results in the mentioned error, as
the file doesn't exist any longer.

This incorrect behaviour was introduced with commit 8826028bdc
("dasdfmt: Use libdasd provided ioctl functions") at which the use of a
globally available file descriptor was omitted. Instead, the ioctl
library functions require a device node to be passed as a function
parameter and will open a file descriptor themselves.
So, before that change, the global file descriptor was always valid even
when the file was removed.

In order to fix this without modifying the behaviour of libdasd,
introduce the two global variables dev_node and dev_path. dev_path is
the original device path entered by the user. dev_node on the other hand
is the reliable device node under /dev/block/ using the major and minor
numbers and is determined in get_device_name().
The dev_path is used for message output only and the dev_node variable
is used for the actual disk operations.

As these two variables are global, the device parameters for several
functions are removed to make the code a bit cleaner.

Fixes: 8826028bdc ("dasdfmt: Use libdasd provided ioctl functions")
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
09be935c54 dasdfmt: Make program relevant information global
The global program options (and other actually globally used
information) are currently passed through via function parameter
whenever this information is needed. However, in reality, this
information is used almost everywhere across the program.

Make this information globally available and get rid of all the
unnecessary function parameters for dasdfmt_info_t. This makes the code
a little bit cleaner and more readable. Also, rename the global struct
to a more suitable name.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
65e18bff67 dasdfmt: Remove function dasdfmt_format
dasdfmt_format() does nothing but calling process_tracks() with the same
parameters. Get rid of it, call process_tracks() directly, and avoid
confusion.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
07ab32fa8b dasdfmt: Fix whitespace
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
353403824b libdasd: Fix dasd_get_host_access_count()
Since commit 75e3afb6a0 ("libdasd: Move get_host_access_count() to
libdasd") dasd_get_host_access_count() reports always 0 as the check for
unsuccessful execution of util_sys_get_dev_addr() is incorrect.
Fix the behaviour by turning the check around.

Fixes: 75e3afb6a0 ("libdasd: Move get_host_access_count() to libdasd")
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki
8a58389e2f zkey: Add library versioning for libekmfweb and zkey-ekmfweb
Closes: https://github.com/ibm-s390-tools/s390-tools/issues/93

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Alexander Egorenkov
f2cc871b02 genprotimg/boot: disable SSP
SSP cannot work with boot loaders because it requires libc.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Alexander Egorenkov
4dbdc8dfab zipl/boot: disable SSP
SSP cannot work with boot loaders because it requires libc.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki
60900de5e9 zkey: Skip build of zkey-ekmfweb.so if libekmfweb dependencies are missing
zkey-ekmfweb.so requires libekmfweb.so. If libekmfweb.so can not be built
due to missing build requirements, then zkey-ekmfweb.so can't be built
either.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Sven Schnelle
2bba362e9a lsstp: Improve wording and fix typos in man page
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki
76044be98d zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
Building zkey-ekmfweb.so will also trigger to build libekmfweb.so,
which requires OpenSSL. So, skip zkey-ekmfweb.so if HAVE_OPENSSL=0.

zkey-cryptsetup also has a dependency on OpenSSL, so skip it also
if HAVE_OPENSSL=0

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:29 +01:00
Jan Höppner
885ff0a03f Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
490 changed files with 81543 additions and 10944 deletions

21
.editorconfig Normal file
View File

@@ -0,0 +1,21 @@
# Check https://editorconfig.org for details
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = tab
tab_width = 8
[*.sh]
shell_variant = bash # used by `shfmt`
[*.y{a,}ml]
indent_style = space
indent_size = 2
[*.py]
indent_style = space
indent_size = 4

43
.gitignore vendored
View File

@@ -5,14 +5,25 @@
*.a
*.o.d
# ctags files
tags
TAGS
# Ignore coverage data
*.gcda
*.gcno
#
# Ignore generated executables and other generated files
#
ap_tools/ap-check
cmsfs-fuse/cmsfs-fuse
cpacfstats/cpacfstats
cpacfstats/cpacfstatsd
cpumf/chcpumf
cpumf/lscpumf
cpumf/lshwc
cpumf/pai
cpuplugd/cpuplugd
dasdfmt/dasdfmt
dasdinfo/dasdinfo
@@ -20,6 +31,8 @@ dasdview/dasdview
dump2tar/src/dump2tar
fdasd/fdasd
hmcdrvfs/hmcdrvfs
hsavmcore/check-dep-fuse
hsavmcore/hsavmcore
hyptop/hyptop
ip_watcher/xcec-bridge
ipl_tools/chreipl
@@ -34,25 +47,29 @@ iucvterm/src/iucvconn
iucvterm/src/iucvtty
iucvterm/src/ttyrun
iucvterm/test/test_afiucv
libap/check-dep-lock
libap/check-dep-json
libekmfweb/check-dep-libekmfweb
libekmfweb/detect-openssl-version.dep
libekmfweb/libekmfweb.so
libutil/util_base_example
libutil/util_file_example
libutil/util_libc_example
libutil/util_opt_command_example
libutil/util_opt_example
libutil/util_panic_example
libutil/util_path_example
libutil/util_prg_example
libutil/util_rec_example
libutil/util_scandir_example
libekmfweb/libekmfweb.so.1
libekmfweb/libekmfweb.so.1.0
libkmipclient/check-dep-libkmipclient
libkmipclient/detect-openssl-version.dep
libkmipclient/libkmipclient.so
libkmipclient/libkmipclient.so.1
libkmipclient/libkmipclient.so.1.0
libseckey/check-dep-libseckey
libseckey/detect-openssl-version.dep
libutil/*_example
libvmcp/vmcp_example
libzds/libzds.a
lsstp/lsstp
mon_tools/mon_fsstatd
mon_tools/mon_procd
osasnmpd/osasnmpd
pvattest/src/pvattest
pvattest/tools/exchange_info
qetharp/qetharp
qethqoat/qethqoat
systemd/cpacfstatsd.service
@@ -92,12 +109,18 @@ zipl/boot/*.bin
zipl/boot/*.exec
zipl/boot/data.h
zipl/src/chreipl_helper.device-mapper
zdev/src/zdev_id
zipl/src/zipl
zipl/src/zipl-editenv
zipl/src/zipl_helper.device-mapper
zkey/check-dep-zkey
zkey/check-dep-zkey-cryptsetup
zkey/detect-libcryptsetup.dep
zkey/ekmfweb/libekmfweb.dep
zkey/ekmfweb/zkey-ekmfweb.so
zkey/kmip/libkmipclient.dep
zkey/kmip/zkey-kmip.so
zkey/zkey
zkey/zkey-cryptsetup
zpcictl/zpcictl
**/.detect-openssl.dep.c

View File

@@ -2,20 +2,25 @@ List of all individuals having contributed content to s390-tools
----------------------------------------------------------------
- Alexander Egorenkov
- Alexandra Winter
- Alexey Ishchuk
- Andreas Herrmann
- Andre Wild
- André Wild
- Antoinette Kaschner
- Arnd Bergmann
- Axel Wirbser
- Balint Reczey
- Benjamin Block
- Brian C. Lane
- Carsten Otte
- Christian Borntraeger
- Christian Ehrhardt
- Christof Schmitt
- Claudio Imbrenda
- Clemens von Mann
- Colin Walters
- Dan Horak
- Dan Horák
- Despina Papadopoulou
- Dimitri John Ledkov
- Eberhard Pasch
@@ -25,15 +30,18 @@ List of all individuals having contributed content to s390-tools
- Erwin Vicari
- Eugene Crosser
- Eugene Dvurechenski
- Fabrice Fontaine
- Farhan Ali
- Fedor Loshakov
- Felix Beck
- Frank Blaschka
- Frank Heimes
- Frank Munzert
- Frank Pavlic
- Fritz Elfert
- Gerald Schaefer
- Gerhard Tonn
- Graham Inggs
- Guevenc Guelce
- Hannes Reinecke
- Hans-Joachim Picht
@@ -48,13 +56,14 @@ List of all individuals having contributed content to s390-tools
- Ingo Franzki
- Ingo Tuchscherer
- Jan Glauber
- Jan Hoeppner
- Jan Höppner
- Jan Willeke
- Jason J. Herne
- Javier Martinez Canillas
- Jean-Baptiste Joret
- Jens Remus
- Jochen Roehrig
- Joern Siglen
- Juergen Christ
- Julian Wiedmann
- Karsten Graul
@@ -62,24 +71,29 @@ List of all individuals having contributed content to s390-tools
- Klaus-Dieter Wacker
- Lakhvich Dmitriy
- Marc Hartmayer
- Mario Held
- Mark Dettinger
- Mark Post
- Martin Kammerer
- Martin Peschke
- Martin Petermann
- Martin Schwidefsky
- Matthew Rosato
- Maxim Shchetynin
- Melissa Howland
- Mete Durlu
- Michael Ernst
- Michael Holzheu
- Michael Mueller
- Mijo Safradin
- Mikhail Zaslonko
- Nikita Dubrovskii
- Niklas Schnelle
- Peter Oberparleiter
- Peter Tiedemann
- Philipp Kern
- Philipp Rudo
- Prashanth Sundararaman
- Rafael Fonseca
- Raimund Schroeder
- Ralph Wuerthner
@@ -95,6 +109,7 @@ List of all individuals having contributed content to s390-tools
- Stefan Raspl
- Stefan Reimbold
- Stefan Weinhuber
- Steffen Eiden
- Steffen Maier
- Steffen Thoss
- Susanne Wintenberger
@@ -103,13 +118,17 @@ List of all individuals having contributed content to s390-tools
- Swen Schillig
- Taraka R. Bodireddy
- Thomas Heidrich
- Thomas Huth
- Thomas Richter
- Thomas Spatzier
- Thomas Weber
- Tuan Hoang
- Ursula Braun
- Utz Bacher
- Vance Morris
- Vasily Gorbik
- Viktor Mihajlovski
- Vineeth Vijayan
- Volker Sameske
- Wenjia Zhang
- Wolfgang Taphorn

View File

@@ -1,5 +1,243 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.23.0 (2022-08-18)__
For Linux kernel version: 5.19
Changes of existing tools:
- Makefile: use common Make definition for DRACUTDIR
- Makefile: use common Make definition for UDEVDIR and UDEVRULESDIR
- cpacfstats: Add PAI and hotplug support
- cpumf/pai: Omit file write progress information
- dbginfo.sh: Get more details on lspci command
- dumpconf: Prevent running the service in containers
- libcpumf: Detect PMU named pai_ext
- pvattest: Improve error reporting and logging
- zdev: Add some --type ap examples to manpages
- zkey: Use default benchmarked Argon2i with LUKS2
Bug Fixes:
- dbginfo.sh: Fix accidental ftrace buffer shrinkage/free
- genprotimg: Fix BIO_reset() returncode handling
- libpv: Fix dependency checking
- 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
Add new tools / libraries:
- ap_tools: Introduce ap_tools and the ap-check tool
- cpumf/pai: Add Processor Activity Instrumentation tool
- libpv: New library for PV tools
- pvattest: Add new tool to create, perform, and verify attestation measurements
- zipl/zdump: Add Next Gen Dump (NGDump) support
Changes of existing tools:
- Move man pages to System commands section (lscpumf, lshwc, pai, dbginfo.sh, zfcpdbf, zipl-switch-to-blscfg)
- README.md: Add 70-chreipl-fcp-mpath.rules to the list of udev rule descriptions
- Remove SysV related daemon scripts (cpacfstatsd, cpuplugd, mon_statd)
- genprotimg: Move man page to section 1 for user commands
- hyptop: increase initial update interval
- libseckey: Adapt keymgmt_match() implementation to OpenSSL
- libutil: Add util_exit_code
- libutil: Introduce util_udev
- zdev: Introduce the ap device type
- zipl-editenv: Add zIPL multienvironment support
- zipl: Implement sorting BLS entries by versions
- zkey: Add initramfs hook
Bug Fixes:
- cmsfs-fuse: Fix enabling of hard_remove option
- s390-tools: Fix typos that were detected by lintian as 'typo-in-manual-page'
- zkey-kmip: Fix possible use after free
- zkey: Fix EP11 host library version checking
- zkey_kmip: Setup ext-lib once the APQNs have been configured
* __v2.21.0 (2022-04-20)__
For Linux kernel version: 5.17
Add new tools / libraries:
- libcpumf: Create library libcpumf for CPU Measurement functions
Changes of existing tools:
- chreipl-fcp-mpath: bundle a pre-cooked version of the manpage for build
environments without access to `pandoc`
- dbginfo.sh: Add multipath info to map paths to FC addressing and prio group
- dbginfo.sh: Collect config files of systemd-modules-load.service
- dbginfo.sh: Sort list of environment variables for readability
- dbginfo.sh: Replace "which" by builtin command "type"
- dbginfo.sh: Rework script formatting (indents, order)
- dbginfo.sh: Update sysfs collection (excludes, messages)
- genprotimg: Add Protected Virtualization (PV) dump support
- genprotimg: Remove DigiCert root CA pinning
- lszcrypt: Add CEX8S support
- zcryptctl: Add control domain handling
- zcryptstats: Add CEX8 support
- zipl: Allow optional entries that are left out when files are missing
- zipl: make IPL sections defined with BLS to inherit a target field
- zpcictl: Add option to trigger firmware reset
Bug Fixes:
- cpictl: Handle excessive kernel version numbers
- dbginfo.sh: Collect all places where modprobe.d config files could exist
- fdasd: Fix endless menu loop on EOF
- zdump/dfi: Fix segfault due to double free
- zdump: Fix /dev/mem reading
- zpcictl: Fix race of SCLP reset and Linux recovery
* __v2.20.0 (2022-02-04)__
For Linux kernel version: 5.16
Add new tools / libraries:
- Add EditorConfig configuration
Changes of existing tools:
- s390-tools switches to Fuse 3 as Fuse 2 is deprecated.
Affected tools: cmsfs, hmcdrvfs, hsavmcore, zdsfs, zdump
- chreipl-fcp-mpath: don't compress the manpage before installing it
- cpictl: Report extended version information
- genprotimg: Add extended kernel command line support
- zdev: modify the lsblk output parser in lszdev
- zipl: Add support for longer kernel command lines (now supports up to 64k length)
Bug Fixes:
- cpictl: Suppress messages for unwritable sysfs files
- dbginfo.sh: Fix missing syslog for step create_package
- lshwc: Fix CPU list parameter setup for device driver
- zdev: Check for errors when removing a devtype setting
- zdev: Fix path resolution for multi-mount point file systems
* __v2.19.0 (2021-11-10)__
For Linux kernel version: 5.15
Add new tools / libraries:
- chreipl-fcp-mpath: New toolset that uses multipath information to change
the configured FCP re-IPL path on detecting issues with the current path
Changes of existing tools:
- dbginfo.sh: Add retry timeout and remove possible blocking "blockdev --report"
- dbginfo.sh: Collect config- and debug-data for chreipl-fcp-mpath
- hsci: Add support for multiple MAC addresses
Bug Fixes:
- lshwc: Fix compile error for gcc <8.1
- zdump: Various clean-ups and fixes
- ziomon: Correct throughput calculation in ziorep_printers
- zipl: Fix segmentation fault when setting stage3_parms
* __v2.18.0 (2021-10-01)__
For Linux kernel version: 5.14
Add new tools:
- scripts: Add tool for parsing sclp s390dbf logs
- zdev: Add udev rule helper tool
- zipl-editenv: Add tool to operate with zIPL environment installed in the boot record
Changes of existing tools:
- Makefile: Fix order of build of libraries for parallel builds
- dbginfo.sh: Add collection in area of timedate, coredump and --check option
- dbginfo.sh: Add exception on dump2tar for /sys/kernel/mm/page_idle/bitmap
- dbginfo.sh: Cleanup of outdated sections and general code rework
- dbginfo.sh: Collect zipl boot menu entries from boot loader specification
- lszcrypt: Add support for vfio-ap status field
- lszcrypt: Improved output for deconfig cards and queues
- lszfcp: Add linkdown case to host marker of extended output
- zdev: Add auto-config for PCI and crypto devices
- zdump: Introduce multi-level message logging
- zipl: Add support for environment block interpretation
- zkey-cryptsetup: Support LUKS2 volumes with integrity support enabled
Bug Fixes:
- hsavmcore: Avoid recompilation of overlay during install step
- libkmipclient: Fix parsing of hex values for XML and JSON encoding
- vmur/vmur.cpp: Fix error handling on transfer failure
- zdump: Lots of smaller fixes across the board
* __v2.17.0 (2021-07-07)__
For Linux kernel version: 5.12 / 5.13
Add new tools / libraries:
- hsavmcore: New utility to make the dump process with kdump more efficient
- libkmipclient: Add KMIP client shared library
- libseckey: Add a secure key library
- lshwc: New tool to extract and list complete counter sets
Changes of existing tools:
- genprotimg: Add '--(enable|disable)-pckmo' options
- genprotimg: Add OpenSSL 3.0 support
- genprotimg: Change plaintext control flags defaults so PCKMO functions are allowed
- libutil: Introduce multi-level message logging (util_log)
- libutil: Introduce util_arch module
- udev/dasd: Change DASD udev-rule to set none scheduler
- zdsfs: Add transparent codepage conversion
- zkey: Add support for KMIP-based key management systems
Bug Fixes:
- ttyrun-getty: Avoid conflicts with serial-getty@
- dbginfo: add /proc/kallsyms - refresh zVM, lscpu - fix WORKARCHIVE handling
- dbginfo: add KVM data collection for server and guest - fix lszdev
- genprotimg: Add missing return values in error paths
- zkey: Fix conversion of CCA DATA keys to CCA CIPHER keys
- znetconf: avoid conflict with "chzdev -e"
* __v2.16.0 (2021-02-19)__
For Linux kernel version: 5.10 / 5.11
Add new tool:
- hsci: New tool to manage HSCI (HiperSockets Converged Interfaces)
Changes of existing tools:
- genprotimg: Add host-key document verification support
- genprotimg: boot: Make boot loader -march=z900 compatible
- libekmfweb: Make install directory for shared libraries configurable
- lsdasd: Add FC Endpoint Security information
- make: Add address sanitizer support
- netboot: Add version information to scripts
- netboot: Bump busybox version in pxelinux.0 build
- zdev: Add FC Endpoint Security information for DASD devices
- zdev: Add build option to update initial RAM-disk by default
- zkey-ekmfweb: Avoid sequence number clash when generating keys
- zkey/zkey-ekmfweb: Install KMS plugins into configurable location
- zkey: Add support to store LUKS2 dummy passphrase in key repository
Bug Fixes:
- dasdfmt: Fix segfault when an incorrect option is specified
- genprotimg: Fix several build issues
- genprotimg: Require argument for 'ramdisk' and 'parmfile' options
- zcryptstats: Fix handling of partial results with many domains
- zfcpdbf: Deal with crash 7.2.9 change in caller name formatting
- zipl/boot: Fix memory use after free in stage2
- zipl/boot: Fix potential heap overflow in stage2
- zipl: Fix reading 4k disk's geometry
* __v2.15.1 (2020-10-28)__
For Linux kernel version: 5.9
Changes of existing tools:
- lsstp: Improve wording and fix typos in man page
- zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
- zkey: Add library versioning for libekmfweb and zkey-ekmfweb
- libutil: Add function to determine base device of a partition block device
Bug Fixes:
- dasdfmt: Fix bad file descriptor error when running on symlinks
- libdasd: Fix dasd_get_host_access_count()
- zipl: Fix multivolume dump
- zgetdump: Fix device node determination via sysfs to work with multivolume again
- genprotimg/boot: Fix build by disabling SSP
- zipl/boot: Fix build by disabling SSP
* __v2.15.0 (2020-10-15)__
For Linux kernel version: 5.9

View File

@@ -72,7 +72,7 @@ In the examples below we use this fictive identity:
### Setup GitHub and local git
1. Create a fork of this repository by clicking the `Fork` button on the top
right of the [s390-tools](https://github.com/ibm-s390-tools/s390-tools)
right of the [s390-tools](https://github.com/ibm-s390-linux/s390-tools)
main page
2. Clone your forked repository to your local development system
@@ -84,7 +84,7 @@ In the examples below we use this fictive identity:
s390-tools repository on GitHub
```
$ cd s390-tools
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-tools/s390-tools.git
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-linux/s390-tools.git
```
4. Verify your remotes
@@ -92,8 +92,8 @@ In the examples below we use this fictive identity:
~/s390-tools $ git remote -v
origin https://github.com/random-developer/s390-tools.git (fetch)
origin https://github.com/random-developer/s390-tools.git (push)
upstream https://github.com/ibm-s390-tools/s390-tools.git (fetch)
upstream https://github.com/ibm-s390-tools/s390-tools.git (push)
upstream https://github.com/ibm-s390-linux/s390-tools.git (fetch)
upstream https://github.com/ibm-s390-linux/s390-tools.git (push)
```
You now have two remotes: The "origin" remote points to your fork
and the "upstream" remote to the official s390-tools repository.

View File

@@ -3,15 +3,22 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
# Include common definitions
include common.mak
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp libekmfweb
#
# BASELIBS: Libraries that have no dependency to other libraries in s390-tools
# LIBS: Libraries that can have a dependency to base libraries
# TOOLS: Tools that can have a dependency to base libraries or libraries
#
BASELIB_DIRS = libutil libseckey
LIB_DIRS = libvtoc libzds libdasd libvmdump libccw libvmcp libekmfweb \
libkmipclient libcpumf libap libpv
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
genprotimg lsstp
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
all: $(TOOL_DIRS)
clean: $(TOOL_DIRS)
@@ -25,9 +32,10 @@ MAKECMDGOALS = all
endif
#
# We have to build the libraries before the tools are built. Otherwise
# the tools would trigger parallel "make -C" builds for libraries in
# case of "make -j".
# We have to build the base libraries before the other libraries are built,
# and then build the other libraries before the tools are built. Otherwise the
# other libraries and tools would trigger parallel "make -C" builds for the
# base libraries and the other libraries in case of "make -j".
#
# MAKECMDGOALS contains the list of goals, e.g. "clean all". We use
# "foreach" to generate a ";" separated list of "make -C <target>".
@@ -44,7 +52,12 @@ $(TOOL_DIRS): $(LIB_DIRS)
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
.PHONY: $(TOOL_DIRS)
$(LIB_DIRS):
$(LIB_DIRS): $(BASELIB_DIRS)
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
.PHONY: $(LIB_DIRS)
$(BASELIB_DIRS):
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
.PHONY: $(BASELIB_DIRS)

148
README.md
View File

@@ -33,6 +33,9 @@ Package contents
* genprotimg:
Create a protected virtualization image.
* pvattest:
Create, perform, and verify protected virtualization attestation measurements.
* udev rules:
- 59-dasd.rules: rules for unique DASD device nodes created in /dev/disk/.
- 57-osasnmpd.rules: udev rules for osasnmpd.
@@ -40,6 +43,9 @@ Package contents
- 40-z90crypt.rules: udev rules for z90crypt driver
- 90-cpi.rules: udev rule to update Control-Program-Information when KVM is
used.
- 70-chreipl-fcp-mpath.rules: udev rules to monitor multipath events for
re-IPL path failover and to adjust the re-IPL
device in case needed.
* systemd units:
- cpi.service: Unit to apply CPI settings
@@ -50,10 +56,10 @@ Package contents
- ttyrun-getty@.service: Instance unit to manage ttyrun
* zipl:
Make DASDs or tapes bootable for system IPL or system dump.
Make DASDs, SCSIs, NVMes or tapes bootable for system IPL or system dump.
* zgetdump:
Retrieve system dumps from either tapes or DASDs.
Retrieve system dumps from either tapes, DASDs, SCSIs or NVMes.
* qetharp:
Read and flush the ARP cache on OSA Express network cards.
@@ -109,6 +115,9 @@ Package contents
feature. Those traces are filtered with the zfcpdbf script, i.e. merge
several traces, make it more readable etc.
* sclpdbf:
Display debug data for the sclp kernel component.
* scsi_logging_level:
Create, get or set the logging level for the SCSI logging facility.
@@ -223,7 +232,8 @@ Package contents
* CPU-measurement facilities (CPU-MF) tools:
Use the lscpumf tool to display information about the CPU-measurement
counter and sampling facilities. Use the chcpumf tool to control the
sampling facility support.
sampling facility support. Use lshwc to extract complete counter sets from
the CPU Measurement Facilities.
* cpacfstats:
The cpacfstats tools provide a client/server application set to monitor
@@ -249,6 +259,31 @@ Package contents
Management Foundation - Web Edition, and is used to manage keys in an
enterprise.
* libkmipclient:
A shared library that provides an KMIP client to communicate with an KMIP
server. KMIP stands for Key Management Interoperability Protocol, and is an
extensible communication protocol that defines message formats for the
manipulation of cryptographic keys on a key management server.
* hsci:
Manage HiperSockets Converged Interfaces (HSCI).
* hsavmcore:
hsavmcore is designed to make the dump process with kdump more efficient.
With hsavmcore, the HSA memory that contains a part of the production
kernel's memory can be released early in the process. Depending on the size
of the production kernel's memory, writing the dump to persistent storage
can be time consuming and prevent the HSA memory from being reused
by other LPARs.
* chreipl-fcp-mpath:
Use multipath information to change the configured FCP re-IPL path on
detecting issues with the current path.
* ap-check:
A utility called by mdevctl to assist in managing vfio_ap-passthrough
devices.
For more information refer to the following publications:
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
@@ -267,24 +302,33 @@ build options:
| __LIBRARY__ | __BUILD OPTION__ | __TOOLS__ |
|----------------|:------------------:|:-------------------------------------:|
| fuse | `HAVE_FUSE` | cmsfs-fuse, zdsfs, hmcdrvfs, zgetdump |
| fuse3 | `HAVE_FUSE` | cmsfs-fuse, zdsfs, hmcdrvfs, zgetdump,|
| | | hsavmcore |
| zlib | `HAVE_ZLIB` | zgetdump, dump2tar |
| ncurses | `HAVE_NCURSES` | hyptop |
| pfm | `HAVE_PFM` | cpacfstats |
| net-snmp | `HAVE_SNMP` | osasnmpd |
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb |
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb, |
| | | libkmipclient, pvattest |
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb |
| glib2 | `HAVE_GLIB2` | genprotimg |
| libcurl | `HAVE_LIBCURL` | libekmfweb |
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb, |
| | | libkmipclient |
| glib2 | `HAVE_GLIB2` | genprotimg, pvattest |
| 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:
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|----------------|:----------------:|:-------------------------------:|
| dracut | `HAVE_DRACUT` | zdev |
| initramfs-tools| `HAVE_INITRAMFS` | zdev |
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|------------------|:----------------------------:|:------------------------:|
| dracut | `HAVE_DRACUT` | zdev, chreipl-fcp-mpath, |
| | | zipl |
| initramfs-tools | `HAVE_INITRAMFS` | zdev, zipl |
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
The s390-tools build process uses "pkg-config" if available and hard-coded
compiler and linker options otherwise.
@@ -306,6 +350,16 @@ the different tools are provided:
The runtime requirements are: openssl-libs (>= 1.1.0) and glib2.
* pvattest:
For building pvattest you need OpenSSL version 1.1.1 or newer
installed (openssl-devel.rpm). Also required is glib2.56 or newer
(glib2-devel.rpm) and libcurl.
Tip: you may skip the pvattest build by adding
`HAVE_OPENSSL=0`, `HAVE_LIBCURL=0`, or `HAVE_GLIB2=0`.
The runtime requirements are: openssl-libs (>= 1.1.1) and
glib2.56 or newer.
* osasnmpd:
You need at least the NET-SNMP 5.1.x package (net-snmp-devel.rpm)
installed, before building the osasnmpd subagent.
@@ -324,12 +378,12 @@ the different tools are provided:
* cmsfs-fuse/zdsfs/hmcdrvfs/zgetdump:
The tools cmsfs-fuse, zdsfs, hmcdrvfs, and zgetdump depend on FUSE.
FUSE is provided by installing the fuse and libfuse packages and by a
FUSE is provided by installing the fuse3 and libfuse3 packages and by a
kernel compiled with `CONFIG_FUSE_FS`. For compiling the s390-tools package
the fuse-devel package is required.
The cmsfs-fuse tool requires FUSE version 2.8.1 or newer for full
the fuse3-devel package is required.
The cmsfs-fuse tool requires FUSE version 3.0 or newer for full
functionality.
For further information about FUSE see: http://fuse.sourceforge.net
For further information about FUSE see: https://github.com/libfuse/libfuse
* hyptop:
The ncurses-devel package is required to build hyptop.
@@ -349,14 +403,13 @@ the different tools are provided:
As of s390-tools-1.13.0, the minimum required kernel level is 2.6.38.
* cpacfstats:
For building the cpacfstats tools you need libpfm version 4 or
newer installed (libpfm-devel.rpm). Tip: you may skip the cpacfstats
build by adding `HAVE_PFN=0` to the make invocation. To run the
cpacfstats daemon the kernel needs to have performance
events enabled (check for `CONFIG_PERF_EVENTS=y`) and you need libpfm
version 4 or newer installed. A new group 'cpacfstats' needs to be
created and all users intending to use the tool should be added to
this group.
For building the cpacfstats tools you need libudev installed
(systemd-devel.rpm). Tip: you may skip the cpacfstats build by
adding `HAVE_LIBUDEV=0` to the make invocation. To run the
cpacfstats daemon the kernel needs to have performance events
enabled (check for `CONFIG_PERF_EVENTS=y`). A new group 'cpacfstats'
needs to be created and all users intending to use the tool should
be added to this group.
* zdev:
Depending on the boot loader and initial RAM-disk mechanism used by a
@@ -375,6 +428,17 @@ the different tools are provided:
Distributors with different boot or RAM-disk mechanisms should provide
a custom zdev-root-update helper script.
- `ZDEV_ALWAYS_UPDATE_INITRD=1` upon modification of any persistent device
configuration, chzdev updates the initial RAM-disk by default, without any
additional user interaction.
For some distributions, all the configuration attributes must be copied to
the initial RAM-disk. Because the device configuration directives applied
in the initial RAM-disk takes precedence over those stored in the root file-
system. This copying is done usually by explicitly invoking a command. This
build option makes it user-friendly and does this copying without any manual
intervention.
Some functions of zdev require that the following programs are available:
- modprobe (kmod)
@@ -412,3 +476,37 @@ the different tools are provided:
(libcurl-devel.rpm).
Tip: you may skip the libekmfweb build by adding `HAVE_OPENSSL=0`,
`HAVE_JSONC=0`, or `HAVE_LIBCURL=0` to the make invocation.
* hsavmcore:
For building the hsavmcore tool you need fuse version 3.0 and optionally
systemd which is enabled by default, to disable systemd support,
add `HAVE_SYSTEMD=0` to the make invocation.
Tip: you may skip the hsavmcore build by adding `HAVE_FUSE=0`
to the make invocation.
* libkmipclient:
For building the libkmipclient shared library you need openssl version 1.1.1
or newer installed (openssl-devel.rpm). Also required are json-c version 0.13
or newer (json-c-devel.rpm), libxml2 version 2.9.10 or newer
(libxml2-devel.rpm), and libcurl version 7.59 or newer (libcurl-devel.rpm).
Tip: you may skip the libkmipclient build by adding `HAVE_OPENSSL=0`,
`HAVE_JSONC=0`, `HAVE_LIBXML2=0`, or `HAVE_LIBCURL=0` to the make invocation.
* chreipl-fcp-mpath:
For a complete list and documentation of the requirements, installation and
uninstallation, please see
[chreipl-fcp-mpath/README.md](chreipl-fcp-mpath/README.md).
Summarized: chreipl-fcp-mpath requires GNU Bash, GNU Core Utilities,
util-linux, udev, and multipath-tools. When using `HAVE_DRACUT=1` with the
make invocation, it also requires dracut. When using `ENABLE_DOC=1` with the
make invocation to build a fresh man page (instead of using the pre-cooked
version) and render the README.md as HTML, make further requires pandoc and
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.

47
ap_tools/Makefile Normal file
View File

@@ -0,0 +1,47 @@
include ../common.mak
MDEVCTL_DIR = /etc/mdevctl.d/
MDEVCTL_SCRIPTS = /etc/mdevctl.d/scripts.d/
MDEVCTL_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)
all:
$(SKIP) HAVE_JSONC=0
install:
$(SKIP) HAVE_JSONC=0
else
LDLIBS += -llockfile -ljson-c
all: ap-check
ap-check: ap-check.o $(libs)
install: all
@if [ ! -d $(DESTDIR)$(MDEVCTL_CALLOUTS) ]; then \
mkdir -p $(DESTDIR)$(MDEVCTL_CALLOUTS); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
chmod 755 $(DESTDIR)$(MDEVCTL_DIR); \
chmod 755 $(DESTDIR)$(MDEVCTL_SCRIPTS); \
chmod 755 $(DESTDIR)$(MDEVCTL_CALLOUTS); \
fi; \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ap-check \
$(DESTDIR)$(MDEVCTL_CALLOUTS)
endif
clean:
rm -f *.o *~ ap-check core
.PHONY: all install clean

911
ap_tools/ap-check.c Normal file
View File

@@ -0,0 +1,911 @@
/*
* ap-check - Validate vfio-ap mediated device configuration changes
*
* This tool in intended to be driven via the callout API of the mdevctl
* utility (https://github.com/mdevctl/mdevctl/)
*
* 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 <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "lib/ap.h"
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/util_opt.h"
#include "lib/util_path.h"
#include "ap-check.h"
static const struct mdevctl_action mdevctl_action_table[NUM_MDEVCTL_ACTIONS] = {
{MDEVCTL_ACTION_DEFINE, "define"},
{MDEVCTL_ACTION_LIST, "list"},
{MDEVCTL_ACTION_MODIFY, "modify"},
{MDEVCTL_ACTION_START, "start"},
{MDEVCTL_ACTION_STOP, "stop"},
{MDEVCTL_ACTION_TYPES, "types"},
{MDEVCTL_ACTION_UNDEFINE, "undefine"},
{MDEVCTL_ACTION_ATTRIBUTES, "attributes"}
};
static const struct mdevctl_event mdevctl_event_table[NUM_MDEVCTL_EVENTS] = {
{MDEVCTL_EVENT_PRE, "pre"},
{MDEVCTL_EVENT_POST, "post"},
{MDEVCTL_EVENT_GET, "get"}
};
/*
* Convert mdevctl action string to an enumerated value
*/
static enum mdevctl_action_id validate_action(char *action)
{
int i;
for (i = 0; i < NUM_MDEVCTL_ACTIONS; i++) {
if (strcmp(action, mdevctl_action_table[i].action) == 0)
return mdevctl_action_table[i].id;
}
return MDEVCTL_ACTION_UNKNOWN;
}
/*
* Convert mdevctl event string to an enumerated value
*/
static enum mdevctl_event_id validate_event(char *event)
{
int i;
for (i = 0; i < NUM_MDEVCTL_EVENTS; i++) {
if (strcmp(event, mdevctl_event_table[i].event) == 0)
return mdevctl_event_table[i].id;
}
return MDEVCTL_EVENT_UNKNOWN;
}
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("DEVICE"),
{
.option = { "e", required_argument, NULL, 'e' },
.argument = "EVENT",
.desc = "The type of callout being issued",
},
{
.option = { "a", required_argument, NULL, 'a' },
.argument = "ACTION",
.desc = "The action being performed on the specified device",
},
{
.option = { "s", required_argument, NULL, 's' },
.argument = "STATE",
.desc = "The state of the associated mdevctl command",
},
{
.option = { "u", required_argument, NULL, 'u' },
.argument = "UUID",
.desc = "Universally Unique ID for the mediated device",
},
{
.option = { "p", required_argument, NULL, 'p' },
.argument = "PDEV",
.desc = "Parent device name, e.g. matrix",
},
{
.option = { "t", required_argument, NULL, 't' },
.argument = "TYPE",
.desc = "Mediated device type, e.g. vfio_ap-passthrough",
},
UTIL_OPT_END
};
/*
* Initialize the ap_check anchor struct.
*/
static void ap_check_init(struct ap_check_anchor *anc)
{
anc->uuid = anc->parent = anc->type = NULL;
anc->dev = vfio_ap_device_new();
anc->cleanup_lock = false;
}
/*
* Free memory of ap_check anchor struct.
*/
static void ap_check_cleanup(struct ap_check_anchor *anc)
{
if (anc->uuid)
free(anc->uuid);
if (anc->parent)
free(anc->parent);
if (anc->type)
free(anc->type);
if (anc->dev)
vfio_ap_device_free(anc->dev);
if (anc->cleanup_lock)
ap_release_lock();
}
/*
* Exit ap_check
*/
static void __noreturn ap_check_exit(struct ap_check_anchor *anc, int rc)
{
ap_check_cleanup(anc);
exit(rc);
}
/*
* parses the command line
*/
static void ap_check_parse(struct ap_check_anchor *anc,
int argc, char *argv[])
{
bool action = false, event = false, state = false, bad_opts = false;
int opt;
util_opt_init(opt_vec, NULL);
while (1) {
opt = util_opt_getopt_long(argc, argv);
if (opt == -1)
break;
switch (opt) {
case 'e':
if (event) {
bad_opts = true;
} else {
anc->event = validate_event(optarg);
event = true;
}
break;
case 'a':
if (action) {
bad_opts = true;
} else {
anc->action = validate_action(optarg);
action = true;
}
break;
case 's':
if (state) {
bad_opts = true;
} else {
/* Ignore the state */
state = true;
}
break;
case 'u':
if (anc->uuid)
bad_opts = true;
else
anc->uuid = util_strdup(optarg);
break;
case 'p':
if (anc->parent)
bad_opts = true;
else
anc->parent = util_strdup(optarg);
break;
case 't':
if (anc->type)
bad_opts = true;
else
anc->type = util_strdup(optarg);
break;
default:
fprintf(stderr, "Unknown operand\n");
ap_check_exit(anc, EXIT_FAILURE);
}
}
/* Make sure we got all expected input values */
if (!(action && event && state && anc->uuid && anc->parent &&
anc->type) || bad_opts) {
fprintf(stderr, "Duplicate or missing operand\n");
ap_check_exit(anc, EXIT_FAILURE);
}
/* Check for invalid UUID */
if (!is_valid_uuid(anc->uuid)) {
fprintf(stderr, "Invalid UUID specified\n");
ap_check_exit(anc, EXIT_FAILURE);
}
anc->dev->uuid = util_strdup(anc->uuid);
/* Check for valid type */
if (strcmp(anc->type, VFIO_AP_TYPE) != 0)
ap_check_exit(anc, APC_EXIT_UNKNOWN_TYPE);
/* Check for invalid parent - currently only 'matrix' supported */
if (strcmp(anc->parent, "matrix") != 0) {
fprintf(stderr, "Invalid parent specified\n");
ap_check_exit(anc, EXIT_FAILURE);
}
}
/*
* Call a function for each entry in a directory:
* int callback(const char *abs_path, const char *rel_path, void *data)
* Continues for all entries in the directory regardless of callback return
* code. Will return 0 or, if one or more callbacks failed, the first nonzero
* rc received.
*/
static int path_for_each(const char *path,
int (*callback)(const char *, const char *, void *),
void *data)
{
struct dirent *de;
int rc = 0;
int r = 0;
DIR *dir;
char *p;
dir = opendir(path);
if (!dir)
return -1;
while ((de = readdir(dir))) {
if (strcmp(de->d_name, ".") == 0 ||
strcmp(de->d_name, "..") == 0)
continue;
util_asprintf(&p, "%s/%s", path, de->d_name);
r = callback(p, de->d_name, data);
/* Save first nonzero return code for caller */
if (rc == 0 && r != 0)
rc = r;
free(p);
}
closedir(dir);
return rc;
}
/*
* Report an error message when the specified configuration will conflict
* with an existing device
*/
static void conflict_error(const char *uuid, unsigned int a, unsigned int d,
bool persistent)
{
if (uuid) {
if (persistent) {
fprintf(stderr,
"APQN %u.%u is defined for autostart by %s\n",
a, d, uuid);
} else {
fprintf(stderr, "APQN %u.%u already in use by %s\n",
a, d, uuid);
}
} else {
if (persistent) {
fprintf(stderr, "AQPN %u.%u is not defined for "
"vfio_ap-passthrough use by the persistent "
"ap bus mask settings\n", a, d);
} else {
fprintf(stderr, "AQPN %u.%u is not allowed for "
"vfio_ap-passthrough use by the active ap "
"bus mask settings\n", a, d);
}
}
}
/*
* Compare the list of adapters and domains for two devices, reporting error
* messages for any conflicts that occur. A conflict occurs when both devices
* have the same adapter + domain pair.
* The function below takes advantage of the fact that the lists are known to
* be sorted in numeric order; therefore we can use this information to run
* the lists in parallel rather than always starting from the beginning.
*/
static int find_apqn_conflicts(const char *uuid,
struct util_list *adapters,
struct util_list *domains,
struct util_list *adapters2,
struct util_list *domains2,
bool persistent)
{
struct vfio_ap_node *a, *a2, *d, *d2;
int rc = 0;
/* Checks for conflicts with the device */
a = util_list_start(adapters);
a2 = util_list_start(adapters2);
while ((a != NULL) && (a2 != NULL)) {
if (a->id == a2->id) {
d = util_list_start(domains);
d2 = util_list_start(domains2);
while ((d != NULL) && (d2 != NULL)) {
if (d->id == d2->id) {
/* Report error, look for more */
conflict_error(uuid, a->id, d->id,
persistent);
rc = -1;
d = util_list_next(domains, d);
d2 = util_list_next(domains2, d2);
} else if (d->id > d2->id) {
d2 = util_list_next(domains2, d2);
} else {
d = util_list_next(domains, d);
}
}
a = util_list_next(adapters, a);
a2 = util_list_next(adapters2, a2);
} else if (a->id > a2->id) {
a2 = util_list_next(adapters2, a2);
} else {
a = util_list_next(adapters, a);
}
}
return rc;
}
/*
* If the provided path maps to a valid vfio-ap device configuration,
* determine if its current configuration will conflict with the proposed
* changes.
*/
static int check_other_mdev_cfg_cb(const char *path,
const char *filename,
void *data)
{
struct other_mdev_cb_data *cbdata = data;
struct vfio_ap_device *dev = cbdata->dev;
struct vfio_ap_device *dev2 = NULL;
int rc = 0;
/* Skip anything that isn't an mdev config */
if (!is_valid_uuid(filename))
goto out;
/* Skip if this is the input device */
if (strcasecmp(cbdata->uuid, filename) == 0)
goto out;
/* Read the device config */
dev2 = vfio_ap_device_new();
if (vfio_ap_read_device_config(path, dev2) != 0)
goto out;
/* If wrong device type, skip */
if (strcmp(dev2->type, VFIO_AP_TYPE) != 0)
goto out;
/* If not AUTO device, skip */
if (dev2->manual)
goto out;
/* Perform mdev-to-mdev apqn conflict analysis */
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
dev2->adapters, dev2->domains, true);
out:
if (dev2 != NULL)
vfio_ap_device_free(dev2);
return rc;
}
/*
* Perform conflict analysis against all other vfio-ap persistent
* configurations.
*/
int check_other_mdevs_cfg(struct ap_check_anchor *anc)
{
struct other_mdev_cb_data cb_data;
if (!util_path_is_dir(VFIO_AP_CONFIG_PATH))
return 0;
cb_data.uuid = anc->uuid;
cb_data.dev = anc->dev;
return path_for_each(VFIO_AP_CONFIG_PATH, check_other_mdev_cfg_cb,
&cb_data);
}
/*
* If the provided path maps to a valid device, determine if its current
* configuration will conflict with the proposed changes.
*/
static int check_other_mdev_sysfs_cb(const char *path, const char *filename,
void *data)
{
struct other_mdev_cb_data *cbdata = data;
struct vfio_ap_device *dev = cbdata->dev;
struct vfio_ap_device *dev2;
char *matrix_path;
char buf[80];
int rc = 0;
FILE *f;
if (!is_valid_uuid(filename) || path == NULL ||
strcasecmp(filename, cbdata->uuid) == 0)
return 0;
dev2 = vfio_ap_device_new();
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
f = fopen(matrix_path, "r");
while (fgets(buf, sizeof(buf), f))
vfio_ap_parse_matrix(dev2, buf);
vfio_ap_sort_matrix_results(dev2);
fclose(f);
free(matrix_path);
/* Look for conflicts between target device and this device */
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
dev2->adapters, dev2->domains, false);
vfio_ap_device_free(dev2);
return rc;
}
/* Run conflict analysis against all other active vfio-ap devices */
static int check_other_mdevs_sysfs(struct ap_check_anchor *anc)
{
struct other_mdev_cb_data cb_data;
char *root;
int rc = 0;
cb_data.uuid = anc->uuid;
cb_data.dev = anc->dev;
root = path_get_vfio_ap_mdev("");
if (util_path_is_dir(root))
rc = path_for_each(root, check_other_mdev_sysfs_cb, &cb_data);
free(root);
return rc;
}
/*
* Determine if there are any conflicts between the specified device and
* the active apmask/aqmask settings. This is done by treating the masks
* as a temporary vfio_ap_device with all of the associated APQNs owned by
* the system.
*/
static int check_sysfs_mask_conflicts(struct ap_check_anchor *anc)
{
struct vfio_ap_device *sysdev = vfio_ap_device_new();
char *apmask = util_zalloc(AP_MASK_SIZE);
char *aqmask = util_zalloc(AP_MASK_SIZE);
int rc = 0;
if (ap_read_sysfs_masks(apmask, aqmask, AP_MASK_SIZE) != 0) {
fprintf(stderr, "Error reading system AP settings\n");
rc = -1;
goto out;
}
/* Convert the masks to a device with the associated APQNs */
ap_mask_to_list(apmask, sysdev->adapters);
ap_mask_to_list(aqmask, sysdev->domains);
/* Perform conflict analysis */
rc = find_apqn_conflicts(NULL, anc->dev->adapters,
anc->dev->domains, sysdev->adapters,
sysdev->domains, false);
out:
free(apmask);
free(aqmask);
vfio_ap_device_free(sysdev);
return rc;
}
/*
* Determine if there are any conflicts between the specified device and
* the apmask/aqmask settings stored in udev. This is done by treating
* the masks as a temporary vfio_ap_device with all of the associated
* AQPNs owned by the system.
*/
static int check_cfg_mask_conflicts(struct ap_check_anchor *anc)
{
struct vfio_ap_device *sysdev = vfio_ap_device_new();
char *apmask = util_zalloc(AP_MASK_SIZE);
char *aqmask = util_zalloc(AP_MASK_SIZE);
bool read_ap = false, read_aq = false;
char *path;
int rc = 0;
path = path_get_ap_udev();
if (!ap_read_udev_masks(path, apmask, aqmask, &read_ap, &read_aq)) {
fprintf(stderr, "Error reading system AP settings\n");
rc = -1;
goto out;
}
/* Convert the masks to a device with the associated APQNs */
ap_mask_to_list(apmask, sysdev->adapters);
ap_mask_to_list(aqmask, sysdev->domains);
/* Perform conflict analysis */
rc = find_apqn_conflicts(NULL, anc->dev->adapters,
anc->dev->domains, sysdev->adapters,
sysdev->domains, true);
out:
free(apmask);
free(aqmask);
free(path);
vfio_ap_device_free(sysdev);
return rc;
}
/* Subroutine to handle checking shared between DEFINE and MODIFY actions. */
static int ap_check_changes(struct ap_check_anchor *anc)
{
int rc = 0, rc2;
rc = ap_get_lock_callout();
if (rc) {
fprintf(stderr, "Failed to acquire configuration lock %d\n",
rc);
rc = -1;
goto out;
}
anc->cleanup_lock = true;
if (vfio_ap_read_device_config(NULL, anc->dev) != 0) {
fprintf(stderr, "Failed to read device config\n");
rc = -1;
goto out;
}
if (strcmp(anc->dev->type, anc->type) != 0) {
fprintf(stderr, "Invalid mdev_type: %s\n", anc->dev->type);
rc = -1;
goto out;
}
if (!anc->dev->manual) {
/* Check against all other AUTO config files */
rc = check_other_mdevs_cfg(anc);
/* Check against the system UDEV rule for apmask/aqmask */
rc2 = check_cfg_mask_conflicts(anc);
/* If either hit an error, reflect this */
rc = rc != 0 ? rc : rc2;
}
/* If successful, lock must remain held until post callout */
if (rc == 0)
anc->cleanup_lock = false;
out:
return rc;
}
/*
* Determine if defining the specified device is a valid operation.
* mdevctl can reach us for a DEFINE under the following circumstances:
* 1) the device does not exist
* 2) the device is active but does not have a config file, so this action
* would be to generate a config file based upon the active device.
* DEFINE has no effect on an active device (if one exists) it only creates
* the configuration file. The config file might be empty or may have various
* attributes if being fed by --jsonfile or an active device.
*/
static int ap_check_handle_define(struct ap_check_anchor *anc)
{
char *path = path_get_vfio_ap_mdev_config(anc->uuid);
if (util_path_is_readable(path)) {
fprintf(stderr, "Config already exists\n");
free(path);
return -1;
}
free(path);
return ap_check_changes(anc);
}
/*
* Determine if modifying the specified device is a valid operation.
* mdevctl can reach us for a MODIFY under the following circumstances:
* 1) Modifying a MANUAL device
* 2) Modifying an AUTO device
* In the case of MANUAL, we don't take any action because changes made via
* MODIFY don't take affect on the active mdev until a STOP/START cycle.
* In the case of AUTO, we must compare the contents of the proposed device
* with the contents of stashed AUTO mdev configurations + the system.
*/
static int ap_check_handle_modify(struct ap_check_anchor *anc)
{
char *path = path_get_vfio_ap_mdev_config(anc->uuid);
FILE *fd = fopen(path, "r");
/* Determine if a base config file already exists for UUID */
free(path);
if (fd == NULL) {
fprintf(stderr, "Config doesn't exist\n");
return -1;
}
fclose(fd);
return ap_check_changes(anc);
}
/*
* Determine if starting the specified device is a valid operation.
* mdevctl can reach us for a START under the following circumstances:
* 1) STARTing a MANUAL device
* 1a) Where the MANUAL device is defined (has a config file)
* 1b) Where the MANUAL device is NOT defined (no config file).
* For vfio-ap this case provides an mdev with no adapters/domains.
* 1c) Where the MANUAL device is NOT defined but a full configuration is
* provided via --jsonfile
* 2) STARTing an AUTO device
* 2a) Where the AUTO device is defined (has a config file)
* 2b) Where the AUTO device is NOT defined but a full configuration is
* provided via --jsonfile
* In each case, we must compare the proposed device with the contents of
* active mdevs + the system.
*/
static int ap_check_handle_start(struct ap_check_anchor *anc)
{
int rc = 0, rc2;
/* Can only start a device if vfio_ap is built-in or loaded */
if (!util_path_is_dir(VFIO_AP_PATH)) {
fprintf(stderr, "vfio_ap module is not loaded\n");
ap_check_exit(anc, EXIT_FAILURE);
}
rc = ap_get_lock_callout();
if (rc) {
fprintf(stderr, "Failed to acquire configuration lock %d\n",
rc);
rc = -1;
goto out;
}
anc->cleanup_lock = true;
if (vfio_ap_read_device_config(NULL, anc->dev) != 0) {
fprintf(stderr, "Failed to read device config\n");
rc = -1;
goto out;
}
if (strcmp(anc->dev->type, anc->type) != 0) {
fprintf(stderr, "Invalid mdev_type: %s\n", anc->dev->type);
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 */
rc2 = check_sysfs_mask_conflicts(anc);
/* If either hit an error, reflect this */
rc = rc != 0 ? rc : rc2;
/* If successful, lock must remain held until post callout */
if (rc == 0)
anc->cleanup_lock = false;
out:
return rc;
}
/*
* Acquire the appropriate serialization so that the specified device can be
* STOPped.
*/
static int ap_check_handle_stop(void)
{
int rc;
rc = ap_get_lock_callout();
if (rc) {
fprintf(stderr, "Failed to acquire configuration lock %d\n",
rc);
return -1;
}
/* The lock must remain held until post callout */
return 0;
}
/*
* Determine if UNDEFINEing the specified device is a valid operation.
* mdevctl can reach us for an UNDEFINE under the following circumstances:
* 1) UNDEFINEing an active device
* 2) UNDEFINEing an inactive device
* UNDEFINE has no effect on the active device, it only removes the config
* file.
*/
static int ap_check_handle_undefine(struct ap_check_anchor *anc)
{
char *path = path_get_vfio_ap_mdev_config(anc->uuid);
int rc = 0;
rc = ap_get_lock_callout();
if (rc) {
fprintf(stderr, "Failed to acquire configuration lock %d\n",
rc);
rc = -1;
goto out;
}
anc->cleanup_lock = true;
if (vfio_ap_read_device_config(path, anc->dev) != 0) {
fprintf(stderr, "Failed to read device config\n");
rc = -1;
goto out;
}
if (strcmp(anc->dev->type, anc->type) != 0) {
fprintf(stderr, "Invalid mdev_type: %s\n", anc->dev->type);
rc = -1;
goto out;
}
/* Success: lock must remain held until post callout */
anc->cleanup_lock = false;
out:
free(path);
return rc;
}
/*
* For callouts where the "pre" callout would have acquired the lock, it is
* now safe to remove the lock as all changes have been committed.
*/
static int ap_check_handle_post(void)
{
return ap_release_lock();
}
/* For the specified device, print the attributes to stdout in JSON format */
static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
{
struct vfio_ap_device *dev = anc->dev;
struct vfio_ap_node *node;
bool has_attr = false;
char buf[80];
char *path;
FILE *f;
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
f = fopen(path, "r");
while (fgets(buf, sizeof(buf), f))
vfio_ap_parse_matrix(dev, buf);
vfio_ap_sort_matrix_results(dev);
fclose(f);
free(path);
path = path_get_vfio_ap_attr(anc->uuid, "control_domains");
f = fopen(path, "r");
while (fgets(buf, sizeof(buf), f))
vfio_ap_parse_control(dev, buf);
fclose(f);
free(path);
printf("[{");
if (!util_list_is_empty(dev->adapters)) {
util_list_iterate(dev->adapters, node) {
if (has_attr)
printf("},{");
printf("\"assign_adapter\": \"%u\"", node->id);
has_attr = true;
}
}
if (!util_list_is_empty(dev->domains)) {
util_list_iterate(dev->domains, node) {
if (has_attr)
printf("},{");
printf("\"assign_domain\": \"%u\"", node->id);
has_attr = true;
}
}
if (!util_list_is_empty(dev->controls)) {
util_list_iterate(dev->controls, node) {
if (has_attr)
printf("},{");
printf("\"assign_control_domain\": \"%u\"", node->id);
has_attr = true;
}
}
printf("}]\n");
return 0;
}
/*
* Determine which mdevctl action is being checked and handle accordingly.
*/
static int ap_check_handle_action(struct ap_check_anchor *anc)
{
int rc = 0;
switch (anc->event) {
case MDEVCTL_EVENT_PRE:
switch (anc->action) {
case MDEVCTL_ACTION_DEFINE:
rc = ap_check_handle_define(anc);
break;
case MDEVCTL_ACTION_MODIFY:
rc = ap_check_handle_modify(anc);
break;
case MDEVCTL_ACTION_START:
rc = ap_check_handle_start(anc);
break;
case MDEVCTL_ACTION_STOP:
rc = ap_check_handle_stop();
break;
case MDEVCTL_ACTION_UNDEFINE:
rc = ap_check_handle_undefine(anc);
break;
case MDEVCTL_ACTION_LIST:
case MDEVCTL_ACTION_TYPES:
default:
/* Ignore some actions including unknown ones */
break;
}
break;
case MDEVCTL_EVENT_POST:
switch (anc->action) {
case MDEVCTL_ACTION_DEFINE:
case MDEVCTL_ACTION_MODIFY:
case MDEVCTL_ACTION_START:
case MDEVCTL_ACTION_STOP:
case MDEVCTL_ACTION_UNDEFINE:
ap_check_handle_post();
break;
default:
/* Ignore other post events */
break;
}
break;
case MDEVCTL_EVENT_GET:
switch (anc->action) {
case MDEVCTL_ACTION_ATTRIBUTES:
rc = ap_check_handle_get_attributes(anc);
break;
default:
/* Ignore some actions including unknown ones */
break;
}
break;
default:
/* Ignore any unknown events */
break;
}
return rc;
}
/*
*
*/
int main(int argc, char *argv[])
{
struct ap_check_anchor anchor;
int rc;
ap_check_init(&anchor);
ap_check_parse(&anchor, argc, argv);
rc = ap_check_handle_action(&anchor);
ap_check_exit(&anchor, rc);
}

74
ap_tools/ap-check.h Normal file
View File

@@ -0,0 +1,74 @@
/*
* ap-check - Validate vfio-ap mediated device configuration changes
*
* 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 AP_CHECK_H
#define AP_CHECK_H
#include <stdbool.h>
/*
* List of all of the supported mdevctl actions
*/
enum mdevctl_action_id {
MDEVCTL_ACTION_DEFINE = 0,
MDEVCTL_ACTION_LIST,
MDEVCTL_ACTION_MODIFY,
MDEVCTL_ACTION_START,
MDEVCTL_ACTION_STOP,
MDEVCTL_ACTION_TYPES,
MDEVCTL_ACTION_UNDEFINE,
MDEVCTL_ACTION_ATTRIBUTES,
/* UNKNOWN must always be the last in the list */
MDEVCTL_ACTION_UNKNOWN,
};
#define NUM_MDEVCTL_ACTIONS MDEVCTL_ACTION_UNKNOWN
struct mdevctl_action {
enum mdevctl_action_id id;
const char action[32];
};
enum mdevctl_event_id {
MDEVCTL_EVENT_PRE = 0,
MDEVCTL_EVENT_POST,
MDEVCTL_EVENT_GET,
MDEVCTL_EVENT_UNKNOWN,
};
#define NUM_MDEVCTL_EVENTS MDEVCTL_EVENT_UNKNOWN
struct mdevctl_event {
enum mdevctl_event_id id;
const char event[32];
};
/* ap-check special exit codes */
#define APC_EXIT_UNKNOWN_TYPE 2
struct ap_check_anchor {
enum mdevctl_event_id event;
enum mdevctl_action_id action;
char *uuid;
char *parent;
char *type;
struct vfio_ap_device *dev;
/* Active Masks */
char apmask[80];
char aqmask[80];
/* Persistent Masks */
char p_apmask[80];
char p_aqmask[80];
bool cleanup_lock;
};
struct other_mdev_cb_data {
const char *uuid;
struct vfio_ap_device *dev;
};
#endif /* AP_CHECK_H */

View File

@@ -32,7 +32,7 @@ Usage: $cmd [-t LAST_GIT_TAG]
Add all new authors since last release to the $authors_file file. Without
the -t option the tool uses the last available git tag as last release.
The tool should be called form the s390-tools master branch.
The tool runs on the s390-tools master branch.
OPTIONS
-t, --tag LAST_GIT_TAG Use git tag LAST_GIT_TAG as starting point
@@ -116,7 +116,7 @@ echo "$cmd: Adding new authors since tag: $release_tag_last"
# Print authors list without header
tail -n +4 $authors_file_path
# Add the new authors
git log --format="- %an" $release_tag_last..
git log --format="- %an" $release_tag_last..master
# Then sort everything and remove duplicates
} | sort | uniq > $authors_file_tmp
# Create new AUTHORS file with header ...

View File

@@ -0,0 +1 @@
8e604dab39577678bc9f24bfe5e2ee35354b2f4b1759edd16093157b1ecce9d3 README.md

11
chreipl-fcp-mpath/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
# build artifacts
/chreipl-fcp-mpath-common.sh
/chreipl-fcp-mpath-is-ipl-tgt
/chreipl-fcp-mpath-is-ipl-vol
/chreipl-fcp-mpath-is-reipl-zfcp
/chreipl-fcp-mpath-record-volume-identifier
/chreipl-fcp-mpath-try-change-ipl-path
/dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf
/README.html
/README.pdf
/chreipl-fcp-mpath.md

274
chreipl-fcp-mpath/Makefile Normal file
View File

@@ -0,0 +1,274 @@
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Utilities list in GNU Make Conventions:
# https://www.gnu.org/software/make/manual/make.html#Utilities-in-Makefiles
# Those necessary for sourced Makefiles:
# - ../common.mak
# - chreipl-fcp-mpath.mak
# bash:
# - bash
# GNU coreutils:
# - sha256sum
# If $(ENABLE_DOC) is `1`:
# GNU awk:
# - gawk
override SHELL := /bin/bash
override .SHELLFLAGS := -O globstar -O nullglob -O extglob -c
# Include common s390-tools definitions
include ../common.mak
# Include common chreipl-fcp-mpath definitions
include chreipl-fcp-mpath.mak
# Local setting: .make.config
# You may create a file named like this in the same directory as this
# Makefile, and customize the build this way (e.g. re-define variables
# set in `chreipl-fcp-mpath.mak`, or define a `CHREIPLZFCPMP_POST_INSTALL`
# that is automatically called after each installation)
ifneq ($(wildcard .make.config),)
include $(wildcard .make.config)
endif
#
## Build
#
.PHONY: chreipl-fcp-mpath chreipl-fcp-mpath-clean
chreipl-fcp-mpath:
chreipl-fcp-mpath-clean:
all: chreipl-fcp-mpath
clean: chreipl-fcp-mpath-clean
# common function used in the helper scripts
CHREIPL_FCP_MPATH_COMMON := \
chreipl-fcp-mpath-common.sh
CHREIPL_FCP_MPATH_UDEV_HELPER := \
chreipl-fcp-mpath-is-ipl-tgt \
chreipl-fcp-mpath-is-ipl-vol \
chreipl-fcp-mpath-is-reipl-zfcp \
chreipl-fcp-mpath-record-volume-identifier \
chreipl-fcp-mpath-try-change-ipl-path
$(CHREIPL_FCP_MPATH_UDEV_HELPER) $(CHREIPL_FCP_MPATH_COMMON): $(MAKEFILE_LIST)
$(CHREIPL_FCP_MPATH_UDEV_HELPER) $(CHREIPL_FCP_MPATH_COMMON): % : %.in
$(call chreiplzfcpmp-sed-buildvar-replace,$(<),$(@))
chmod a+x $(@)
$(CHREIPL_FCP_MPATH_UDEV_HELPER): $(CHREIPL_FCP_MPATH_COMMON)
.PHONY: chreipl-fcp-mpath-udev-helper-clean
chreipl-fcp-mpath-udev-helper-clean:
rm -f $(CHREIPL_FCP_MPATH_UDEV_HELPER) $(CHREIPL_FCP_MPATH_COMMON)
udev/rules.d/70-chreipl-fcp-mpath.rules: $(CHREIPL_FCP_MPATH_UDEV_HELPER)
chreipl-fcp-mpath: udev/rules.d/70-chreipl-fcp-mpath.rules
chreipl-fcp-mpath-clean: chreipl-fcp-mpath-udev-helper-clean
dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf: $(MAKEFILE_LIST)
dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf: % : %.in
$(call chreiplzfcpmp-sed-buildvar-replace,$(<),$(@))
.PHONY: chreipl-fcp-mpath-dracut-clean
chreipl-fcp-mpath-dracut-clean:
rm -f dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf
chreipl-fcp-mpath: dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf
chreipl-fcp-mpath-clean: chreipl-fcp-mpath-dracut-clean
ifeq ($(ENABLE_DOC),1)
.PHONY: chreipl-fcp-mpath-doc
chreipl-fcp-mpath-doc: README.html chreipl-fcp-mpath.7
ifeq ($(ENABLE_DOC_PDF),1)
chreipl-fcp-mpath-doc: README.pdf
README.pdf: PANDOCFLAGS += -M title="chreipl-fcp-mpath" -M subtitle="README"
endif
README.html: PANDOCFLAGS += -M title="chreipl-fcp-mpath" -M subtitle="README"
chreiplzfcpmp-doc-man-meta = \
-M title="CHREIPL-FCP-MPATH" \
-V header="Administrator Manual" \
-V section="7" \
-V footer="s390-tools $(S390_TOOLS_RELEASE)"
chreipl-fcp-mpath.7: PANDOCFLAGS += $(chreiplzfcpmp-doc-man-meta)
chreipl-fcp-mpath.7: .chreipl-fcp-mpath.7.cksum
.INTERMEDIATE: chreipl-fcp-mpath.md
chreipl-fcp-mpath.md: README.md
gawk -- '/NOT-IN-MAN \{/,/NOT-IN-MAN \}/ { next } { print }' $(<) > $(@)
.chreipl-fcp-mpath.7.cksum: README.md
sha256sum $(<) > $(@)
.PHONY: chreipl-fcp-mpath-doc-clean
chreipl-fcp-mpath-doc-clean:
rm -f README.html README.pdf chreipl-fcp-mpath.md
chreipl-fcp-mpath: chreipl-fcp-mpath-doc
chreipl-fcp-mpath-clean: chreipl-fcp-mpath-doc-clean
else # $(ENABLE_DOC) != 1
# We bundle a pre-cooked man page with the source-code so that distributions
# don't need `pandoc` in order to be able to ship the man page. As of this
# writing multiple distributions don't have a packaged version of it.
#
# In order to remember to regenerate this pre-cooked version whenever the
# README.md is changed, we also generate a checksum of the README.md, bundle
# that as well, and compare that whenever `make` is called. This way, the
# freshness of the man page can be checked, even if `pandoc` is not available,
# or ENABLE_DOC disabled.
MANPAGE_FRESH := $(shell sha256sum --check .chreipl-fcp-mpath.7.cksum >/dev/null && echo 1 || echo 0)
ifeq ($(MANPAGE_FRESH),0)
$(warning chreipl-fcp-mpath.7 is outdated, please regenerate it by calling `make ENABLE_DOC=1`)
endif
endif # $(ENABLE_DOC) == 1
#
## Install
#
.PHONY: chreipl-fcp-mpath-install
# The content of `CHREIPLZFCPMP_POST_INSTALL` (bash script) is automatically
# called *after* installing chreipl-fcp-mpath during `make install`. If not
# defined (the default), nothing happens. You may define this on the make
# command line, or by creating a `.make.config` and defining the variable in
# there.
chreipl-fcp-mpath-install:
$(CHREIPLZFCPMP_POST_INSTALL)
install: chreipl-fcp-mpath-install
# install udev rules
INSTDIRS += $(UDEVRULESDIR)
$(DESTDIR)$(UDEVRULESDIR): install_dirs
.PHONY: chreipl-fcp-mpath-install-udev-rules
chreipl-fcp-mpath-install-udev-rules: | $(DESTDIR)$(UDEVRULESDIR)
chreipl-fcp-mpath-install-udev-rules: udev/rules.d/70-chreipl-fcp-mpath.rules
$(INSTALL_DATA) -t $(DESTDIR)$(UDEVRULESDIR) \
udev/rules.d/70-chreipl-fcp-mpath.rules
chreipl-fcp-mpath-install: chreipl-fcp-mpath-install-udev-rules
# install udev helper programs
INSTDIRS += $(UDEVDIR)
$(DESTDIR)$(UDEVDIR): install_dirs
.PHONY: chreipl-fcp-mpath-install-udev-helper
chreipl-fcp-mpath-install-udev-helper: | $(DESTDIR)$(UDEVDIR)
chreipl-fcp-mpath-install-udev-helper: $(CHREIPL_FCP_MPATH_UDEV_HELPER)
$(INSTALL_EXEC) -t $(DESTDIR)$(UDEVDIR) $(CHREIPL_FCP_MPATH_UDEV_HELPER)
chreipl-fcp-mpath-install: chreipl-fcp-mpath-install-udev-helper
# install common library files
INSTDIRS += $(CHREIPLZFCPMPDIR)
$(DESTDIR)$(CHREIPLZFCPMPDIR): install_dirs
.PHONY: chreipl-fcp-mpath-install-libfiles
chreipl-fcp-mpath-install-libfiles: | $(DESTDIR)$(CHREIPLZFCPMPDIR)
chreipl-fcp-mpath-install-libfiles: $(CHREIPL_FCP_MPATH_COMMON)
$(INSTALL_DATA) -t $(DESTDIR)$(CHREIPLZFCPMPDIR) \
$(CHREIPL_FCP_MPATH_COMMON)
chreipl-fcp-mpath-install: chreipl-fcp-mpath-install-libfiles
ifeq ($(HAVE_DRACUT),1)
# install dracut config files
INSTDIRS += $(DRACUTCONFDIR)
$(DESTDIR)$(DRACUTCONFDIR): install_dirs
.PHONY: chreipl-fcp-mpath-install-dracut-config
chreipl-fcp-mpath-install-dracut-config: | $(DESTDIR)$(DRACUTCONFDIR)
chreipl-fcp-mpath-install-dracut-config: dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf
$(INSTALL_DATA) -t $(DESTDIR)$(DRACUTCONFDIR) \
dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf
chreipl-fcp-mpath-install: chreipl-fcp-mpath-install-dracut-config
endif
# chreipl-fcp-mpath: install man page
INSTDIRS += $(MANDIR)
$(DESTDIR)$(MANDIR)/man7: install_dirs
.PHONY: chreipl-fcp-mpath-install-man-page
chreipl-fcp-mpath-install-man-page: | $(DESTDIR)$(MANDIR)/man7
chreipl-fcp-mpath-install-man-page: chreipl-fcp-mpath.7
$(INSTALL_DATA) -t $(DESTDIR)$(MANDIR)/man7 \
chreipl-fcp-mpath.7
chreipl-fcp-mpath-install: chreipl-fcp-mpath-install-man-page
#
## Utility
#
# Utilities for the debug feature of chreipl-fcp-mpath-common.sh.
#
# When `chreipl-fcp-mpath` is built with D=1 (default is D=0), each run
# of one of the helper scripts will create a debug log in $(DEBUGOUTDIR)
# (default: /run/udev) which among other things contains the complete shell
# trace of that script run, with some added information that would not be
# inspectable otherwise with just the trace.
#
# There is currently no way of enabling/disabling this at runtime.
#
# chreipl-fcp-mpath-common.sh defines debug log file name as
# "chreiplzfcpmp-${debug_trace_tag}-${SEQNUM:-0}.XXXXXXXXXX" where SEQNUM is a
# udev rule environment variable and each X is replaced with some [[:alnum:]]
# by mktemp. For a definition of `debug_trace_tag`, please see the comments
# in the source.
#
# The following targets can be used for some simple access and filtering of the
# logs during development.
DEBUG_LOG_GLOB = $(DEBUGOUTDIR)/chreiplzfcpmp-[[:digit:]][[:digit:]][[:alpha:]][[:alpha:]][[:alpha:]][[:alpha:]]-+([[:digit:]]).[[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]
# display all debug log files on the system
.PHONY: chreipl-fcp-mpath-debug-logs
chreipl-fcp-mpath-debug-logs:
@ls -1d $(DEBUG_LOG_GLOB)
# display only debug log files of script runs that exited with status 0 (= good)
#
# XXX: `sed -n -e '$p'` is used instead of `tail -n1` to prevent an other
# dependency just for that (both invocations do the same thing).
.PHONY: chreipl-fcp-mpath-debug-logs-filter-good
chreipl-fcp-mpath-debug-logs-filter-good:
@for lg in $(DEBUG_LOG_GLOB); do \
sed -e '/^+ trap_exit$$/,/^+ trap - EXIT$$/d' "$${lg}" \
| sed -n -e '$$p' \
| grep -q -e '^+ exit 0$$' || continue; \
ls -d "$${lg}"; \
done
# display only debug log files of script runs that didn't exit with status 0
# (= bad)
.PHONY: chreipl-fcp-mpath-debug-logs-filter-bad
chreipl-fcp-mpath-debug-logs-filter-bad:
@for lg in $(DEBUG_LOG_GLOB); do \
sed -e '/^+ trap_exit$$/,/^+ trap - EXIT$$/d' "$${lg}" \
| sed -n -e '$$p' \
| grep -q -e '^+ exit 0$$' && continue; \
ls -d "$${lg}"; \
done
.PHONY: chreipl-fcp-mpath-debug-logs-clean
chreipl-fcp-mpath-debug-logs-clean:
rm -f $(DEBUG_LOG_GLOB)

270
chreipl-fcp-mpath/README.md Normal file
View File

@@ -0,0 +1,270 @@
<!-- markdown documentation: https://github.github.com/gfm/ -->
NAME
====
chreipl-fcp-mpath - use multipath information for re-IPL path failover on a
running Linux instance
DESCRIPTION
===========
The IPL process of Linux on Z or LinuxONE from an FCP-attached SCSI volume uses
exactly one path to the volume. If this path is unavailable, the IPL fails.
The **chreipl-fcp-mpath** toolset monitors **udev** events about paths to the
re-IPL volume. If the currently configured re-IPL path becomes unavailable, the
toolset checks for operational paths to the same volume. If available, it
reconfigures the re-IPL settings to use an operational path.
Thus, re-IPL from an FCP-attached SCSI volume can be successful despite path
failures on a running Linux instance if at least one path to the re-IPL volume
remains operational.
**Chreipl-fcp-mpath** requires **udev**, **multipathd** and **dm-multipath**.
Once installed, the toolset runs automatically and autonomously. No user
intervention is possible or required.
Other than installing the toolset, there is no user interface for
**chreipl-fcp-mpath**.
Requirements
------------
The **chreipl-fcp-mpath** tool has the following requirements on the
Linux instance that is being monitored:
- The Linux instance must have started successfully, during IPL.
- The running Linux instance must use **dm-multipath** and **multipathd** for
the configured re-IPL volume - a volume that contains a zipl boot record
and has one of its paths used in the re-IPL configuration.
- **udev** must run.
- The toolset must observe at least one event about the configured re-IPL
path. Examples for such events are: the SCSI disk comes online, or a path
of the corresponding multipath device goes down or comes back online.
- The WWID of the re-IPL volume must not change while the Linux instance is
running.
- When the configured re-IPL path becomes unavailable while the Linux
instance is running, at least one operational path to the re-IPL volume
must be available, or must become available. If no such path is available
when the Linux instance is rebooted, the re-IPL path is not changed.
- The tool assumes that any manually reconfigured re-IPL device is valid and
operational.
The tool treats a newly configured re-IPL device like the initially
configured re-IPL device. In particular, if the newly configured re-IPL
device fulfills the requirements of the tool, re-IPL path failover takes
place if the configured re-IPL path becomes unavailable.
Caution with Manual Changes to the Configured re-IPL Target
-----------------------------------------------------------
**chreipl-fcp-mpath** is designed to accept operator-inititated changes of the
re-IPL device. However, concurrent changes by the operator and tool driven
changes can result in the operator change being overwritten.
To avoid this problem, change the re-IPL device only during steady-state
operations, when no path events happen. Alternatively, make sure that no events
are processed while you change the device. See [EXAMPLES](#examples) for one
way to suspend event processing.
MESSAGES
========
During monitoring and event processing, **chreipl-fcp-mpath** writes messages
to the syslog.
When the configured re-IPL path is changed to a different path to the same
volume (priority *daemon.notice*):
> Changed re-IPL path to: \<device-bus-id\>:\<wwpn\>:\<lun\>.
When a path event indicates that the last available path has become
non-operational (priority *daemon.alert*):
> The re-IPL device cannot be changed because no operational path to the
> re-IPL volume remains. The next re-IPL might fail unless you re-attach or
> enable at least one valid path to the re-IPL volume.
When changing the configured re-IPL device failed because of an error with the
used Linux kernel interface (priority *daemon.crit*):
> Changing the re-IPL device failed. The current re-IPL settings might be
> inconsistent. Check and correct the settings (see the README.md of
> chreipl-fcp-mpath) to make sure that the current re-IPL device is valid.
A failure to change the re-IPL device can indicate an inconsistent setting that
cannot be corrected automatically by **chreipl-fcp-mpath**. As a result, the
next re-IPL might fail or might not use the intended re-IPL device.
You can use the following tools to check and correct the current settings:
- **lsreipl** to confirm that the intended re-IPL device is configured;
- **chreipl** to change the re-IPL device;
- **lszfcp** to inspect the state of available paths to the re-IPL device.
<!-- NOT-IN-MAN { -->
SOFTWARE REQUIREMENTS
=====================
**chreipl-fcp-mpath** integrates into s390-tools's build and install
infrastructure. Use **make** to build it. No explicit dependency management is
in place, but the toolset has some software dependencies besides the
requirements in section [Requirements](#requirements):
- GNU Bash;
- GNU Core Utilities (mktemp, readlink, sync, truncate, sha256sum);
- util-linux (flock, hexdump, logger);
- udev / systemd-udev;
- multipath-tools.
To make use of the optional dracut configuration you need: dracut.
To build a fresh version of the documentation (man page) you need:
- pandoc;
- GNU Core Utilities (date);
- GNU awk;
otherwise the pre-cooked version shipped with the source will be used.
INSTALLATION
============
If your distribution includes a packaged version of **chreipl-fcp-mpath**,
either as a separate package or as part of a **s390-tools** package, install
that package. Otherwise, you can either install it from source as part of
**s390-tools** or separately.
To install **chreipl-fcp-mpath** as part of **s390-tools**, use **make** on the
top-level directory of your **s390-tools** distribution. Installing the entire
distribution might overwrite other already installed tools.
To install the tool separately, change into the **chreipl-fcp-mpath**
directory, and use **make** there.
You need *root* privileges to install the tool into the root file system.
Calling **make** runs the build steps. Calling **make install** runs the build
steps and copies the resulting components to their final destination.
**s390-tools** offers more options and targets to customize the build (see
**make help**).
**chreipl-fcp-mpath** has the following optional build options:
| Option | Values | Default | Effect
| :----- | :----: | :-----: | :-----
| HAVE_DRACUT | 0, 1 | 0 | Install a dracut configuration file that includes **chreipl-fcp-mpath** in the initial ramdisks built with **dracut**.
| ENABLE_DOC | 0, 1 | 0 | Build a fresh version of the man page for **chreipl-fcp-mpath**.
Specify any options as arguments for both the **make** and **make install**
command as shown in the following example:
~ # cd chreipl-fcp-mpath/
~ # make HAVE_DRACUT=1 ENABLE_DOC=1
~ # make HAVE_DRACUT=1 ENABLE_DOC=1 install
After the installation, reload the udev rules database:
~ # udevadm control --reload
*The toolset is now active on your running Linux instance.*
If you use the *HAVE_DRACUT=1* option, also rebuild your
initial ramdisk, to immediately include the toolset instead of
waiting for the next kernel update.
How to rebuild the initial ramdisk and the naming scheme for the
resulting file or files depends on your distribution.
The following example applies to Fedora and to Red Hat Enterprise Linux:
~ # dracut --force /boot/initramfs-"$(uname -r)".img "$(uname -r)"
For SUSE Linux Enterprise Server run for example:
~ # dracut --hostonly --force /boot/initrd-"$(uname -r)" "$(uname -r)"
These commands replace the initial ramdisk for the currently running kernel.
If your distribution uses **zipl** as its boot loader, run **zipl** to refresh
the boot record to find the new initial ramdisk.
~ # zipl
With dracut enabled, **make install** deploys the following files to these
default locations:
/usr/lib/chreipl-fcp-mpath/chreipl-fcp-mpath-common.sh
/usr/lib/dracut/dracut.conf.d/70-chreipl-fcp-mpath.conf
/usr/lib/udev/chreipl-fcp-mpath-is-ipl-tgt
/usr/lib/udev/chreipl-fcp-mpath-is-ipl-vol
/usr/lib/udev/chreipl-fcp-mpath-is-reipl-zfcp
/usr/lib/udev/chreipl-fcp-mpath-record-volume-identifier
/usr/lib/udev/chreipl-fcp-mpath-try-change-ipl-path
/usr/lib/udev/rules.d/70-chreipl-fcp-mpath.rules
/usr/share/man/man7/chreipl-fcp-mpath.7
UNINSTALL
=========
If your distribution includes a separately from **s390-tools** packaged version
of **chreipl-fcp-mpath**, uninstall that package.
For installations without distribution packaging, you cannot uninstall
**chreipl-fcp-mpath** with **make**.
Instead, remove the toolset by deleting the installed files as listed in
[INSTALLATION](#installation)), reload the udev rules database, and rebuild all
modified initial ramdisks as described in [INSTALLATION](#installation)).
<!-- NOT-IN-MAN } -->
EXAMPLES
========
Manual Changes to the Configured re-IPL Device
----------------------------------------------
As outlined in [DESCRIPTION](#description), be cautious when manually changing
the configured re-IPL device. Assure that your reconfiguration actions do not
collide with concurrent automatic event processing by **chreipl-fcp-mpath**.
You can avoid such collisions, by stopping event processing, making your
changes, and then re-enabling event processing. You need *root* privileges for
running the commands in the following example:
~ # udevadm settle
~ # udevadm control --stop-exec-queue
~ # chreipl ...
~ # udevadm control --start-exec-queue
Listing messages with journalctl
--------------------------------
If your Linux instance includes **journalctl**, use the following command to
list all messages that are issued by **chreipl-fcp-mpath**:
~ # journalctl -t chreipl-fcp-mpath
To list only messages that were issued since the last IPL, use this command:
~ # journalctl -t chreipl-fcp-mpath -b
REPORTING BUGS
==============
Use the **Issues** functionality on GitHub to report any bugs in
**chreipl-fcp-mpath**:
[s390-tools Issues](<https://github.com/ibm-s390-linux/s390-tools/issues> "Link to the s390-tools Issues page").
SEE ALSO
========
**chreipl**(8), **dracut**(8), **journalctl**(1), **lsreipl(8)**,
**lszfcp**(8), **multipath**(8), **multipathd**(8), **udev**(7),
**udevadm**(8), **zipl**(8)

View File

@@ -0,0 +1,446 @@
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# GNU coreutils:
# - mktemp
# - readlink
# - sync
# util-linux:
# - flock
# - logger
# Makes use of udev event environment variables:
# SEQNUM
# (1) expand failed globs to an empty string
# (2) extended pattern matching to strip leading/trailing whitespaces
shopt -s nullglob extglob
# (1) don't overwrite existing files using redirects (e.g.: `>`)
set -o noclobber
# make sure any state files created are only writeable by the owning user
umask 027
# create log if DEBUG is enabled (with Make: D=1)
#
# Each script importing this library and expecting a debug log to be created
# must declare a *trace tag* in a variable `debug_trace_tag`. This is used as
# identifier in the log file name. The format is:
#
# [[:digit:]][[:digit:]][[:alpha:]][[:alpha:]][[:alpha:]][[:alpha:]]
# \ /\ /
# --------\ /-------- -------------------\ /-------------------
# \/ \/
# relative position of some unique abbreviation for the script
# execution in the name, excluding any common prefix
# udev rules
if '@DEBUG@' && [ -v debug_trace_tag ] && tlg="$(
mktemp -p '@debugoutdir@' \
"chreiplzfcpmp-${debug_trace_tag}-${SEQNUM:-0}.XXXXXXXXXX" \
2>/dev/null)"
then
readonly tlg
exec >|"${tlg}" 2>&1
set -x
set
else
unset tlg
fi
declare -gr ID_FILE='@chreiplzfcpmp-id-file@'
declare -gr FW_LOCK_FILE='@chreiplzfcpmp-fwlock-file@'
declare -gA TRAP_EXIT_FN=()
declare -gf trap_exit 1>/dev/null
function trap_exit() {
local fn
for fn in "${TRAP_EXIT_FN[@]}"; do
"${fn}"
done
trap - EXIT
}
trap trap_exit EXIT
# Output variables:
# id_file_unlock_exclusive_create() - call to unlock when finished with
# critical section
#
# XXX: `id_file_lock_*` can't be taken recursively
function id_file_lock_exclusive_create() {
declare -g ID_FILE_LOCK=""
# prevent concurrent file creation
#
# First, open the file defined in ${ID_FILE} for writing; this will
# succeed and create the file only if it doesn't exist already. If the
# file already exist, the first open attempt will fail and we fall
# back to opening it only for reading; this will always succeed if the
# file already exists (the reason why the first attempty failed). In
# both cases store the corresponding file descriptor in
# ${ID_FILE_LOCK}.
#
# XXX: This should be race free.
# open() with O_EXCL... is atomic (we set `noclobber` as shell
# option); at least as long as we talk about a local FS.
if ! { exec {ID_FILE_LOCK}>"${ID_FILE}"; } 2>/dev/null; then
{ exec {ID_FILE_LOCK}<"${ID_FILE}"; } 2>/dev/null \
|| return 1
fi
declare -gf id_file_unlock_exclusive_create 1>/dev/null
function id_file_unlock_exclusive_create() {
if [ -v ID_FILE_LOCK ]; then
sync "${ID_FILE}" 2>/dev/null
# release file and implicitly the lock, if taken
exec {ID_FILE_LOCK}>&-
unset ID_FILE_LOCK
fi
unset "TRAP_EXIT_FN[id_file_unlock_exclusive_create]"
}
TRAP_EXIT_FN+=(
[id_file_unlock_exclusive_create]=id_file_unlock_exclusive_create
)
flock --exclusive --timeout 5 "${ID_FILE_LOCK}" || return 2
return 0
}
# Output variables:
# id_file_unlock_exclusive_no_create() - call to unlock when finished with
# critical section
#
# XXX: `id_file_lock_*` can't be taken recursively
function id_file_lock_exclusive_no_create() {
declare -g ID_FILE_LOCK=""
# Open the file defined in ${ID_FILE} for reading, and store the
# corresponding file descriptor in ${ID_FILE_LOCK}.
#
# XXX: return code is used in `chreipl-fcp-mpath-try-change-ipl-path`
{ exec {ID_FILE_LOCK}<"${ID_FILE}"; } 2>/dev/null || return 1
declare -gf id_file_unlock_exclusive_no_create 1>/dev/null
function id_file_unlock_exclusive_no_create() {
if [ -v ID_FILE_LOCK ]; then
sync "${ID_FILE}" 2>/dev/null
# release file and implicitly the lock, if taken
exec {ID_FILE_LOCK}<&-
unset ID_FILE_LOCK
fi
unset "TRAP_EXIT_FN[id_file_unlock_exclusive_no_create]"
}
TRAP_EXIT_FN+=(
[id_file_unlock_exclusive_no_create]=id_file_unlock_exclusive_no_create
)
flock --exclusive --timeout 5 "${ID_FILE_LOCK}" || return 2
return 0
}
# Output variables:
# id_file_unlock_shared_no_create() - call to unlock when finished with
# critical section
#
# XXX: `id_file_lock_*` can't be taken recursively
function id_file_lock_shared_no_create() {
declare -g ID_FILE_LOCK=""
# Open the file defined in ${ID_FILE} for reading, and store the
# corresponding file descriptor in ${ID_FILE_LOCK}.
{ exec {ID_FILE_LOCK}<"${ID_FILE}"; } 2>/dev/null || return 1
declare -gf id_file_unlock_shared_no_create 1>/dev/null
function id_file_unlock_shared_no_create() {
if [ -v ID_FILE_LOCK ]; then
# release file and implicitly the lock, if taken
exec {ID_FILE_LOCK}<&-
unset ID_FILE_LOCK
fi
unset "TRAP_EXIT_FN[id_file_unlock_shared_no_create]"
}
TRAP_EXIT_FN+=(
[id_file_unlock_shared_no_create]=id_file_unlock_shared_no_create
)
flock --shared --timeout 5 "${ID_FILE_LOCK}" || return 2
return 0
}
# Output variables:
# firmware_unlock_exclusive() - call to unlock when finished with critical section
#
# XXX: `firmware_lock_*` can't be taken recursively
function firmware_lock_exclusive() {
declare -g FIRMWARE_LOCK=""
# Open the file defined in ${FW_LOCK_FILE} for reading, and store the
# corresponding file descriptor in ${FIRMWARE_LOCK} (it doesn't matter
# whether this is a normal file or directory). This file descriptor
# will only be used for locking - not for actual I/O.
{ exec {FIRMWARE_LOCK}<"${FW_LOCK_FILE}"; } 2>/dev/null || return 1
declare -gf firmware_unlock_exclusive 1>/dev/null
function firmware_unlock_exclusive() {
if [ -v FIRMWARE_LOCK ]; then
# release file and implicitly the lock, if taken
exec {FIRMWARE_LOCK}<&-
unset FIRMWARE_LOCK
fi
unset "TRAP_EXIT_FN[firmware_unlock_exclusive]"
}
TRAP_EXIT_FN+=([firmware_unlock_exclusive]=firmware_unlock_exclusive)
flock --exclusive --timeout 5 "${FIRMWARE_LOCK}" || return 2
return 0
}
# Output variables:
# firmware_unlock_shared() - call to unlock when finished with critical section
#
# XXX: `firmware_lock_*` can't be taken recursively
function firmware_lock_shared() {
declare -g FIRMWARE_LOCK=""
# Open the file defined in ${FW_LOCK_FILE} for reading, and store the
# corresponding file descriptor in ${FIRMWARE_LOCK} (it doesn't matter
# whether this is a normal file or directory). This file descriptor
# will only be used for locking - not for actual I/O.
{ exec {FIRMWARE_LOCK}<"${FW_LOCK_FILE}"; } 2>/dev/null || return 1
declare -gf firmware_unlock_shared 1>/dev/null
function firmware_unlock_shared() {
if [ -v FIRMWARE_LOCK ]; then
# release file and implicitly the lock, if taken
exec {FIRMWARE_LOCK}<&-
unset FIRMWARE_LOCK
fi
unset "TRAP_EXIT_FN[firmware_unlock_shared]"
}
TRAP_EXIT_FN+=([firmware_unlock_shared]=firmware_unlock_shared)
flock --shared --timeout 5 "${FIRMWARE_LOCK}" || return 2
return 0
}
# Output variables:
# IPL_TYPE
# IPL_BUSID
# IPL_WWPN
# IPL_LUN
function firmware_get_ipl_information() {
declare -g IPL_TYPE="" IPL_BUSID="" IPL_WWPN="" IPL_LUN=""
# Take lock so we don't see any intermediate state from other helpers
# running in parallel
firmware_lock_shared || return 5
{ read -r IPL_TYPE _ < /sys/firmware/reipl/reipl_type; } 2>/dev/null \
|| return 1
{ read -r IPL_BUSID _ < /sys/firmware/reipl/fcp/device; } 2>/dev/null \
|| return 2
{ read -r IPL_WWPN _ < /sys/firmware/reipl/fcp/wwpn; } 2>/dev/null \
|| return 3
{ read -r IPL_LUN _ < /sys/firmware/reipl/fcp/lun; } 2>/dev/null \
|| return 4
firmware_unlock_shared
# show read values in debug log if enabled
if '@DEBUG@'; then
declare -p IPL_TYPE IPL_BUSID IPL_WWPN IPL_LUN 1>&2
fi
return 0
}
# Input:
# 1: absolute canonical path to the scsi device in sysfs, e.g.:
# /sys/devices/css0/0.0.0014/0.0.1700/host1/rport-1:0-0/target1:0:0/1:0:0:1075789848
# Output variables:
# SDEV_LUN
function sdev_get_lun() {
local sdev="${1}" sdev_lun_str
# bash uses `intmax_t` as width for integer variables, and glibc
# defines this either as `long int` on 64 bit systems, or
# `long long int` on other.
local -i sdev_lun=0 fcp_lun=0
sdev_lun_str="${sdev##*:}"
# e.g.: 1075789848
[[ "${sdev_lun_str}" == +([[:digit:]]) ]] || return 1
# "cast" to integer
sdev_lun="${sdev_lun_str}"
# convert the Linux integer LUN format to the hexadecimal 64 bit T10
# LUN representation format used by many s390x interfaces
(( fcp_lun = (((sdev_lun >> 0) & 0xffff) << 48)
| (((sdev_lun >> 16) & 0xffff) << 32)
| (((sdev_lun >> 32) & 0xffff) << 16)
| (((sdev_lun >> 48) & 0xffff) << 0) ))
# the '0x' prefix is part of the length
printf -v SDEV_LUN "%#018llx" "${fcp_lun}"
# show read values in debug log if enabled
if '@DEBUG@'; then
declare -p SDEV_LUN 1>&2
fi
return 0
}
# Input:
# 1: path to the scsi device in sysfs, e.g.:
# /sys/devices/css0/0.0.0014/0.0.1700/host1/rport-1:0-0/target1:0:0/1:0:0:1075789848
# , or a symlink pointing to the scsi device, e.g.:
# /sys/class/block/sds/device
# Output variables:
# SDEV_BUSID
# SDEV_WWPN
# SDEV_LUN
function sdev_get_fcp_addressing() {
local sdev="${1}" fcp_lun rport rport_wwpn zfcp_dev
declare -g SDEV_BUSID="" SDEV_WWPN="" SDEV_LUN=""
sdev="$(readlink -se "${sdev}")" || return 1
# get the LUN for this SDEV
#
# sets ${SDEV_LUN}
sdev_get_lun "${sdev}" || return 2
# get the WWPN of the remote port this SDEV is attached to
printf -v rport "%s" "${sdev}"/../../fc_remote_ports/rport-*:*-*
# e.g.: /sys/devices/css0/0.0.0016/0.0.1740/host0/rport-0:0-1/fc_remote_ports/rport-0:0-1
[ "${rport}" != "" ] || return 3
# XXX: This works even if the rport is currently in a bad
# state, so e.g. when it has just gone down because of a
# cable pull.
{ read -r rport_wwpn _ < "${rport}"/port_name; } 2>/dev/null \
|| return 4
# The Linux kernel doesn't guarantee the same format as in
# /sys/firmware/..., so make sure it is the one we expect.
[[ "${rport_wwpn}" =~ ^0x[[:xdigit:]]{1,16}$ ]] || return 5
# the '0x' prefix is part of the length
printf -v rport_wwpn "%#018llx" "${rport_wwpn}"
# get the Device Bus-ID of the device via which this SDEV is attached
zfcp_dev="$(readlink -se "${sdev}"/../../../..)" || return 6
# e.g.: /sys/devices/css0/0.0.0016/0.0.1740
zfcp_dev="${zfcp_dev##*/}"
# shellcheck disable=2034
SDEV_BUSID="${zfcp_dev}"
# shellcheck disable=2034
SDEV_WWPN="${rport_wwpn}"
return 0
}
# Input:
# 1: path to the scsi device in sysfs
# Output variables:
# SDEV_WWID
function sdev_get_wwid() {
local sdev="${1}"
local -a wwid
declare -g SDEV_WWID=""
# read the volume identifier without stripping any content
#
# XXX: we can read the WWID file, even if the SDEV is currently not
# operational (e.g.: due to the path has gone away), as long as
# the VPD PG 83 is still cached in the kernel; and the page gets
# only released on SDEV device release.
{ readarray -d "" -t wwid < "${sdev}"/wwid; } 2>/dev/null \
|| return 1
if '@DEBUG@'; then declare -p wwid 1>&2; fi
# test whether we read something
#
# This strips all leading spaces from the beginning of the read WWID
# (until the first non-space or NUL character), and checks whether the
# result is empty.
# Hence, we return early if the WWID consists of only whitespace.
#
# XXX: there could be unexpected characters in the returned ID.
# `scsi_id` from the udev helpers sanitizes the strings it reads
# from the devices, so they can be used in environment variables
# without much danger.
# But we don't export anything here, so it should be fine.
[ "${wwid[0]/#*([[:space:]])}" != "" ] || return 2
# shellcheck disable=2034
SDEV_WWID="${wwid[0]}"
return 0
}
# Input:
# 1: path to the scsi device in sysfs
# Return Value:
# == 0: SDEV referenced by `1` in good state
# != 0: otherwise
function sdev_test_path_state() {
local sdev="${1}" state zfcp_failed zfcp_in_recovery rport port_state
sdev="$(readlink -se "${sdev}")" || return 1
{ read -r state _ < "${sdev}"/state; } 2>/dev/null || return 2
{ read -r zfcp_failed _ < "${sdev}"/zfcp_failed; } 2>/dev/null \
|| return 3
{ read -r zfcp_in_recovery _ < "${sdev}"/zfcp_in_recovery; } 2>/dev/null \
|| return 4
printf -v rport "%s" "${sdev}"/../../fc_remote_ports/rport-*:*-*
# e.g.: /sys/devices/css0/0.0.0016/0.0.1740/host0/rport-0:0-1/fc_remote_ports/rport-0:0-1
[ "${rport}" != "" ] || return 5
{ read -r port_state _ < "${rport}"/port_state; } 2>/dev/null \
|| return 6
if '@DEBUG@'; then
declare -p state zfcp_failed zfcp_in_recovery port_state 1>&2
fi
[ "${state}" = "running" ] || return 7
[ "${zfcp_failed}" = "0" ] || return 8
[ "${zfcp_in_recovery}" = "0" ] || return 9
{ [ "${port_state}" = "Online" ] \
|| [ "${port_state}" = "Marginal" ]; } || return 10
return 0
}
# Input:
# *: all input parameters are used as quoted message
function log_note() {
logger -p 'daemon.notice' -t 'chreipl-fcp-mpath' "${*}" &>/dev/null
}
# Input:
# *: all input parameters are used as quoted message
function log_crit() {
logger -p 'daemon.crit' -t 'chreipl-fcp-mpath' "${*}" &>/dev/null
}
# Input:
# *: all input parameters are used as quoted message
function log_alert() {
logger -p 'daemon.alert' -t 'chreipl-fcp-mpath' "${*}" &>/dev/null
}

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Those necessary for sourced library:
# - chreipl-fcp-mpath-common.sh
# Find out whether the device in udev event environment variable ${DEVPATH}
# represents the device we want to re-IPL from. We do this by comparing
# Device-Bus-ID/Target-WWPN/LUN of the individual SDEVs to the parameters set
# in `/sys/firmware/reipl/fcp/`.
#
# Makes use of udev event environment variables:
# DM_UUID
# SUBSYSTEM
# DEVPATH
# shellcheck disable=SC2034
declare -gr debug_trace_tag=05iilt
# shellcheck disable=SC1091
source '@chreiplzfcpmp-lib@' || exit 127
firmware_get_ipl_information || exit 1
if [[ "${DM_UUID}" == mpath-* ]]; then
# Assume Multipath Device Mapper Device;
# e.g.: DEVPATH = /devices/virtual/block/dm-0
declare sdev
# depends on `nullglob` from `chreipl-fcp-mpath-common.sh`
for sdev in /sys/"${DEVPATH}"/slaves/sd*/device; do
sdev_get_fcp_addressing "${sdev}" || continue
[ "${SDEV_LUN}" = "${IPL_LUN}" ] || continue
[ "${SDEV_WWPN}" = "${IPL_WWPN}" ] || continue
[ "${SDEV_BUSID}" = "${IPL_BUSID}" ] || continue
exit 0
done
unset sdev
elif [ "${SUBSYSTEM}" = block ]; then
# Assume SCSI Disk;
# e.g.: DEVPATH = /devices/css0/0.0.0014/0.0.1700/host0/rport-0:0-0/target0:0:0/0:0:0:1074806808/block/sds
sdev_get_fcp_addressing /sys/"${DEVPATH}"/device || exit 2
[ "${SDEV_LUN}" = "${IPL_LUN}" ] || exit 3
[ "${SDEV_WWPN}" = "${IPL_WWPN}" ] || exit 4
[ "${SDEV_BUSID}" = "${IPL_BUSID}" ] || exit 5
exit 0
fi
exit 6

View File

@@ -0,0 +1,86 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Those necessary for sourced library:
# - chreipl-fcp-mpath-common.sh
# Find out whether the device in environment variable ${DEVPATH} represents the
# _volume_ that we IPL'ed from. We do this by comparing its WWID to the one
# recorded in `@chreiplzfcpmp-id-file@`.
#
# Makes use of udev event environment variables:
# DM_UUID
# SUBSYSTEM
# DEVPATH
# shellcheck disable=SC2034
declare -gr debug_trace_tag=11iilv
# shellcheck disable=SC1091
source '@chreiplzfcpmp-lib@' || exit 127
function id_file_read_ipl_information() {
local -a records
declare -g REC_WWID="" REC_BUSID="" REC_WWPN="" REC_LUN=""
# lock file before reading ID, so we don't see any intermediate state
id_file_lock_shared_no_create || return 1
{ readarray -d "" -t -u "${ID_FILE_LOCK}" records; } 2>/dev/null \
|| return 2
if '@DEBUG@'; then declare -p records 1>&2; fi
id_file_unlock_shared_no_create
[ "${#records[@]}" = "4" ] || return 3
# check that none of the array fields contains whitespace only
[ "${records[0]/#*([[:space:]])}" != "" ] || return 4
[ "${records[1]/#*([[:space:]])}" != "" ] || return 5
[ "${records[2]/#*([[:space:]])}" != "" ] || return 6
[ "${records[3]/#*([[:space:]])}" != "" ] || return 7
REC_WWID="${records[0]}"
REC_BUSID="${records[1]}"
REC_WWPN="${records[2]}"
REC_LUN="${records[3]}"
return 0
}
id_file_read_ipl_information || exit 1
if [[ "${DM_UUID}" == mpath-* ]]; then
# Assume Multipath Device Mapper Device;
# e.g.: DEVPATH = /devices/virtual/block/dm-0
declare sdev found=false
for sdev in /sys/"${DEVPATH}"/slaves/sd*/device; do
if sdev_get_wwid "${sdev}"; then
found=true
break
fi
done
unset sdev
"${found}" || exit 2
elif [ "${SUBSYSTEM}" = block ]; then
# Assume SCSI Disk;
# e.g.: DEVPATH = /devices/css0/0.0.0014/0.0.1700/host0/rport-0:0-0/target0:0:0/0:0:0:1074806808/block/sds
sdev_get_wwid /sys/"${DEVPATH}"/device || exit 3
fi
# set by `sdev_get_wwid` and `id_file_read_ipl_information`
[ "${SDEV_WWID}" = "${REC_WWID}" ] || exit 4
firmware_get_ipl_information || exit 5
# set by `firmware_get_ipl_information` and `id_file_read_ipl_information`
[ "${IPL_BUSID}" = "${REC_BUSID}" ] || exit 6
[ "${IPL_WWPN}" = "${REC_WWPN}" ] || exit 7
[ "${IPL_LUN}" = "${REC_LUN}" ] || exit 8
exit 0

View File

@@ -0,0 +1,25 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Those necessary for sourced library:
# - chreipl-fcp-mpath-common.sh
# Find out whether ReIPL is gonna happen from a SCSI volume attached via zFCP
# shellcheck disable=SC2034
declare -gr debug_trace_tag=00iriz
# shellcheck disable=SC1091
source '@chreiplzfcpmp-lib@' || exit 127
declare reipl_type
{ read -r reipl_type _ < /sys/firmware/reipl/reipl_type; } 2>/dev/null || exit 1
if '@DEBUG@'; then declare -p reipl_type 1>&2; fi
[ "${reipl_type}" = "fcp" ] || exit 2
exit 0

View File

@@ -0,0 +1,73 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Those necessary for sourced library:
# - chreipl-fcp-mpath-common.sh
# GNU coreutils:
# - truncate
# util-linux:
# - hexdump
# Record the identification of the volume we want to re-IPL from
#
# Makes use of udev event environment variables:
# DM_UUID
# SUBSYSTEM
# DEVPATH
# shellcheck disable=SC2034
declare -gr debug_trace_tag=10rvid
# shellcheck disable=SC1091
source '@chreiplzfcpmp-lib@' || exit 127
function id_file_record_ipl_information() {
local sdev_wwid="${1}" ipl_busid="${2}" ipl_wwpn="${3}" ipl_lun="${4}"
# lock file before writing ID, so noone sees any intermediate state
id_file_lock_exclusive_create || return 1
# reset ID without removing the file (necessary for the locking to work
# properly, since the FD we use for locking is on this file/inode)
truncate --no-create --size=0 "${ID_FILE}" || return 3
echo -ne "${sdev_wwid}\x00${ipl_busid}\x00${ipl_wwpn}\x00${ipl_lun}\x00" \
>>"${ID_FILE}" || return 4
if '@DEBUG@'; then hexdump -vC "${ID_FILE}" 1>&2; fi
id_file_unlock_exclusive_create
return 0
}
if [[ "${DM_UUID}" == mpath-* ]]; then
# Assume Multipath Device Mapper Device;
# e.g.: DEVPATH = /devices/virtual/block/dm-0
declare sdev
for sdev in /sys/"${DEVPATH}"/slaves/sd*/device; do
if sdev_get_wwid "${sdev}"; then
break
fi
done
unset sdev
elif [ "${SUBSYSTEM}" = block ]; then
# Assume SCSI Disk;
# e.g.: DEVPATH = /devices/css0/0.0.0014/0.0.1700/host0/rport-0:0-0/target0:0:0/0:0:0:1074806808/block/sds
sdev_get_wwid /sys/"${DEVPATH}"/device
fi
# shellcheck disable=SC2153
[ "${SDEV_WWID}" != "" ] || exit 1
firmware_get_ipl_information || exit 2
# shellcheck disable=SC2153
id_file_record_ipl_information \
"${SDEV_WWID}" "${IPL_BUSID}" "${IPL_WWPN}" "${IPL_LUN}" \
|| exit 3
exit 0

View File

@@ -0,0 +1,158 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Those necessary for sourced library:
# - chreipl-fcp-mpath-common.sh
# GNU coreutils:
# - truncate
# util-linux:
# - hexdump
# Try to change the current re-IPL target to a dfferent, operational path to
# the same volume.
#
# Makes use of udev event environment variables:
# DM_UUID
# SUBSYSTEM
# DEVPATH
# CHREIPL_FCP_MPATH_IS_TGT
# shellcheck disable=SC2034
declare -gr debug_trace_tag=15tcip
# shellcheck disable=SC1091
source '@chreiplzfcpmp-lib@' || exit 127
function apply_ipl_information() {
local sdev_wwid="${1}"
local sdev_busid="${2}" sdev_wwpn="${3}" sdev_lun="${4}"
local ipl_type="${5}" ipl_busid="${6}" ipl_wwpn="${7}" ipl_lun="${8}"
local -a records
local try_update_id_file=true
[ "${ipl_type}" = "fcp" ] || return 1
[[ "${sdev_busid}" =~ ^[[:xdigit:]]{1,3}\.[[:xdigit:]]\.[[:xdigit:]]{1,4}$ ]] \
|| return 2
[[ "${sdev_wwpn}" =~ ^0x[[:xdigit:]]{16}$ ]] || return 3
[[ "${sdev_lun}" =~ ^0x[[:xdigit:]]{16}$ ]] || return 4
# After updating the firmware re-IPL information below we also try to
# update the information stored in the ID file (necessary, so it
# contains the correct Device-Bus-ID/WWPN/LUN after the update). For
# the update of the ID file we try to grab an exclusive lock, so there
# are no overlapping reads/writes.
#
# In case we can't get the lock because the ID file is missing, but we
# have a direct TGT match, we may still try to change the re-IPL
# information, but skip the ID file update.
#
# "direct match" means, the event subject is either the SDEV that is
# currently set as re-IPL target, or it is the dm-multipath device that
# currently contains the re-IPL target.
if ! id_file_lock_exclusive_no_create; then
# rc == 1 --> could not read ${ID_FILE}
[ "${PIPESTATUS[0]}" -eq 1 ] || return 5
# if true, we are dealing with a direct TGT match
[ "${CHREIPL_FCP_MPATH_IS_TGT}" = "true" ] || return 6
try_update_id_file=false
fi
# If we have a direct match (see in the comment above), we know
# that we have a path to the current re-IPL volume - no matter of the
# WWID. Otherwise, we got here by comparing the WWID of the event
# subject with the one recorded in the ID file; in this case we try to
# make sure the information is still up-to-date.
if [ "${CHREIPL_FCP_MPATH_IS_TGT}" != "true" ]; then
# last bail to make sure we don't overwrite user choices..
#
# XXX: this will *NOT* prevent the race completely, but at least
# make it less likely
{ readarray -d "" -t -u "${ID_FILE_LOCK}" records; } 2>/dev/null \
|| return 7
if '@DEBUG@'; then declare -p records 1>&2; fi
[ "${#records[@]}" = "4" ] || return 8
[ "${records[0]}" = "${sdev_wwid}" ] || return 9
[ "${records[1]}" = "${ipl_busid}" ] || return 10
[ "${records[2]}" = "${ipl_wwpn}" ] || return 11
[ "${records[3]}" = "${ipl_lun}" ] || return 12
fi
# Take lock so we don't see any intermediate state from other helpers
# running in parallel
firmware_lock_exclusive || return 13
if ! { echo "${sdev_busid}" >| /sys/firmware/reipl/fcp/device \
&& echo "${sdev_wwpn}" >| /sys/firmware/reipl/fcp/wwpn \
&& echo "${sdev_lun}" >| /sys/firmware/reipl/fcp/lun; };
then
log_alert "Changing the re-IPL device failed. The current re-IPL settings might be inconsistent. Check and correct the settings (see the README.md of chreipl-fcp-mpath) to make sure that the current re-IPL device is valid."
return 14
fi
firmware_unlock_exclusive
if [ "${sdev_busid}" != "${ipl_busid}" ] \
|| [ "${sdev_wwpn}" != "${ipl_wwpn}" ] \
|| [ "${sdev_lun}" != "${ipl_lun}" ]; then
log_note "Changed re-IPL path to: ${sdev_busid}:${sdev_wwpn}:${sdev_lun}."
fi
# Try to update the information in the ID file if we have gotten the
# lock for it.
if ${try_update_id_file}; then
# reset ID without removing the file
truncate --no-create --size=0 "${ID_FILE}" || return 15
echo -ne "${sdev_wwid}\x00${sdev_busid}\x00${sdev_wwpn}\x00${sdev_lun}\x00" \
>>"${ID_FILE}" || return 16
id_file_unlock_exclusive_no_create
if '@DEBUG@'; then hexdump -vC "${ID_FILE}" 1>&2; fi
fi
return 0
}
declare -g SDEV=""
if [[ "${DM_UUID}" == mpath-* ]]; then
# Assume Multipath Device Mapper Device;
# e.g.: DEVPATH = /devices/virtual/block/dm-0
for sdev in /sys/"${DEVPATH}"/slaves/sd*/device; do
if sdev_test_path_state "${sdev}"; then
SDEV="${sdev}"
break
fi
done
# No path of the multipath-device that represents the IPL volume is
# online.
if [ "${SDEV}" = "" ]; then
log_crit "The re-IPL device cannot be changed because no operational path to the re-IPL volume remains. The next re-IPL might fail unless you re-attach or enable at least one valid path to the re-IPL volume."
fi
elif [ "${SUBSYSTEM}" = block ]; then
# Assume SCSI Disk;
# e.g.: DEVPATH = /devices/css0/0.0.0014/0.0.1700/host0/rport-0:0-0/target0:0:0/0:0:0:1074806808/block/sds
if sdev_test_path_state /sys/"${DEVPATH}"/device; then
SDEV=/sys/"${DEVPATH}"/device
fi
fi
[ "${SDEV}" != "" ] || exit 0
sdev_get_wwid "${SDEV}" || exit 0
sdev_get_fcp_addressing "${SDEV}" || exit 0
firmware_get_ipl_information || exit 0
# shellcheck disable=SC2153
apply_ipl_information \
"${SDEV_WWID}" "${SDEV_BUSID}" "${SDEV_WWPN}" "${SDEV_LUN}" \
"${IPL_TYPE}" "${IPL_BUSID}" "${IPL_WWPN}" "${IPL_LUN}" || exit 0
exit 0

View File

@@ -0,0 +1,183 @@
.\" Automatically generated by Pandoc 2.16.1
.\"
.TH "CHREIPL-FCP-MPATH" "7" "2022-02-24" "s390-tools 2.20.0-build-20220224" "Administrator Manual"
.hy
.SH NAME
.PP
chreipl-fcp-mpath - use multipath information for re-IPL path failover
on a running Linux instance
.SH DESCRIPTION
.PP
The IPL process of Linux on Z or LinuxONE from an FCP-attached SCSI
volume uses exactly one path to the volume.
If this path is unavailable, the IPL fails.
.PP
The \f[B]chreipl-fcp-mpath\f[R] toolset monitors \f[B]udev\f[R] events
about paths to the re-IPL volume.
If the currently configured re-IPL path becomes unavailable, the toolset
checks for operational paths to the same volume.
If available, it reconfigures the re-IPL settings to use an operational
path.
.PP
Thus, re-IPL from an FCP-attached SCSI volume can be successful despite
path failures on a running Linux instance if at least one path to the
re-IPL volume remains operational.
.PP
\f[B]Chreipl-fcp-mpath\f[R] requires \f[B]udev\f[R],
\f[B]multipathd\f[R] and \f[B]dm-multipath\f[R].
Once installed, the toolset runs automatically and autonomously.
No user intervention is possible or required.
.PP
Other than installing the toolset, there is no user interface for
\f[B]chreipl-fcp-mpath\f[R].
.SS Requirements
.PP
The \f[B]chreipl-fcp-mpath\f[R] tool has the following requirements on
the Linux instance that is being monitored:
.IP \[bu] 2
The Linux instance must have started successfully, during IPL.
.IP \[bu] 2
The running Linux instance must use \f[B]dm-multipath\f[R] and
\f[B]multipathd\f[R] for the configured re-IPL volume - a volume that
contains a zipl boot record and has one of its paths used in the re-IPL
configuration.
.IP \[bu] 2
\f[B]udev\f[R] must run.
.IP \[bu] 2
The toolset must observe at least one event about the configured re-IPL
path.
Examples for such events are: the SCSI disk comes online, or a path of
the corresponding multipath device goes down or comes back online.
.RS 2
.IP \[bu] 2
The WWID of the re-IPL volume must not change while the Linux instance
is running.
.RE
.IP \[bu] 2
When the configured re-IPL path becomes unavailable while the Linux
instance is running, at least one operational path to the re-IPL volume
must be available, or must become available.
If no such path is available when the Linux instance is rebooted, the
re-IPL path is not changed.
.IP \[bu] 2
The tool assumes that any manually reconfigured re-IPL device is valid
and operational.
.RS 2
.PP
The tool treats a newly configured re-IPL device like the initially
configured re-IPL device.
In particular, if the newly configured re-IPL device fulfills the
requirements of the tool, re-IPL path failover takes place if the
configured re-IPL path becomes unavailable.
.RE
.SS Caution with Manual Changes to the Configured re-IPL Target
.PP
\f[B]chreipl-fcp-mpath\f[R] is designed to accept operator-inititated
changes of the re-IPL device.
However, concurrent changes by the operator and tool driven changes can
result in the operator change being overwritten.
.PP
To avoid this problem, change the re-IPL device only during steady-state
operations, when no path events happen.
Alternatively, make sure that no events are processed while you change
the device.
See EXAMPLES for one way to suspend event processing.
.SH MESSAGES
.PP
During monitoring and event processing, \f[B]chreipl-fcp-mpath\f[R]
writes messages to the syslog.
.PP
When the configured re-IPL path is changed to a different path to the
same volume (priority \f[I]daemon.notice\f[R]):
.RS
.PP
Changed re-IPL path to: <device-bus-id>:<wwpn>:<lun>.
.RE
.PP
When a path event indicates that the last available path has become
non-operational (priority \f[I]daemon.alert\f[R]):
.RS
.PP
The re-IPL device cannot be changed because no operational path to the
re-IPL volume remains.
The next re-IPL might fail unless you re-attach or enable at least one
valid path to the re-IPL volume.
.RE
.PP
When changing the configured re-IPL device failed because of an error
with the used Linux kernel interface (priority \f[I]daemon.crit\f[R]):
.RS
.PP
Changing the re-IPL device failed.
The current re-IPL settings might be inconsistent.
Check and correct the settings (see the README.md of chreipl-fcp-mpath)
to make sure that the current re-IPL device is valid.
.RE
.PP
A failure to change the re-IPL device can indicate an inconsistent
setting that cannot be corrected automatically by
\f[B]chreipl-fcp-mpath\f[R].
As a result, the next re-IPL might fail or might not use the intended
re-IPL device.
.PP
You can use the following tools to check and correct the current
settings:
.IP \[bu] 2
\f[B]lsreipl\f[R] to confirm that the intended re-IPL device is
configured;
.IP \[bu] 2
\f[B]chreipl\f[R] to change the re-IPL device;
.IP \[bu] 2
\f[B]lszfcp\f[R] to inspect the state of available paths to the re-IPL
device.
.SH EXAMPLES
.SS Manual Changes to the Configured re-IPL Device
.PP
As outlined in DESCRIPTION, be cautious when manually changing the
configured re-IPL device.
Assure that your reconfiguration actions do not collide with concurrent
automatic event processing by \f[B]chreipl-fcp-mpath\f[R].
You can avoid such collisions, by stopping event processing, making your
changes, and then re-enabling event processing.
You need \f[I]root\f[R] privileges for running the commands in the
following example:
.IP
.nf
\f[C]
\[ti] # udevadm settle
\[ti] # udevadm control --stop-exec-queue
\[ti] # chreipl ...
\[ti] # udevadm control --start-exec-queue
\f[R]
.fi
.SS Listing messages with journalctl
.PP
If your Linux instance includes \f[B]journalctl\f[R], use the following
command to list all messages that are issued by
\f[B]chreipl-fcp-mpath\f[R]:
.IP
.nf
\f[C]
\[ti] # journalctl -t chreipl-fcp-mpath
\f[R]
.fi
.PP
To list only messages that were issued since the last IPL, use this
command:
.IP
.nf
\f[C]
\[ti] # journalctl -t chreipl-fcp-mpath -b
\f[R]
.fi
.SH REPORTING BUGS
.PP
Use the \f[B]Issues\f[R] functionality on GitHub to report any bugs in
\f[B]chreipl-fcp-mpath\f[R]: s390-tools
Issues (https://github.com/ibm-s390-linux/s390-tools/issues).
.SH SEE ALSO
.PP
\f[B]chreipl\f[R](8), \f[B]dracut\f[R](8), \f[B]journalctl\f[R](1),
\f[B]lsreipl(8)\f[R], \f[B]lszfcp\f[R](8), \f[B]multipath\f[R](8),
\f[B]multipathd\f[R](8), \f[B]udev\f[R](7), \f[B]udevadm\f[R](8),
\f[B]zipl\f[R](8)

View File

@@ -0,0 +1,89 @@
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
#
# Uses the following system-utilities (and shell-builtins):
# Utilities list in GNU Make Conventions:
# https://www.gnu.org/software/make/manual/make.html#Utilities-in-Makefiles
# GNU coreutils:
# - mktemp
# If $(ENABLE_DOC) is `1`:
# Pandoc:
# - pandoc
# GNU coreutils:
# - date
#
## Paths and Build Variables
#
# Install the configuration file for dracut, to automatically pull in the
# toolset into the initial ramdisk, when built with it.
HAVE_DRACUT = 0
# Build documentation; requires: Pandoc
ENABLE_DOC = 0
# https://www.gnu.org/software/make/manual/make.html#Directory-Variables
CHREIPLZFCPMPDIR = $(USRLIBDIR)/chreipl-fcp-mpath
UDEVRUNDIR = /run/udev
DEBUGOUTDIR = $(UDEVRUNDIR)
INSTALL_EXEC = $(INSTALL) -g $(GROUP) -o $(OWNER) --preserve-timestamps
INSTALL_DATA = $(INSTALL_EXEC) --mode=0644
# used for data exchange and synchronization across the different helpers
chreiplzfcpmp-id-file = $(UDEVRUNDIR)/chreiplzfcpmp-ipl-volume-id
# file used to implement mutual exclusion when accessing firmware IPL info:
# - this should be something that is (practically) always available, so we
# dont have to worry about fallbacks or error-handling;
# - at the same time, it should not be used by anything else with flock(2) to
# hold a lock for long periods.
chreiplzfcpmp-fwlock-file = /sys/firmware/reipl
.DELETE_ON_ERROR:
# export build-time definitions to the scripts/built-components
define chreiplzfcpmp-sed-buildvar-replace =
tmpout=$$(mktemp -p ./ .make.tmp.XXXXXXXXXXXXXXXX) && { \
$(SED) -E \
-e 's|@DEBUG@|$(if $(filter 1,$(D)),true,false)|g' \
-e 's|@chreiplzfcpmp-id-file@|$(chreiplzfcpmp-id-file)|g' \
-e 's|@chreiplzfcpmp-fwlock-file@|$(chreiplzfcpmp-fwlock-file)|g' \
-e 's|@chreiplzfcpmp-lib@|$(CHREIPLZFCPMPDIR)/chreipl-fcp-mpath-common.sh|g' \
-e 's|@debugoutdir@|$(DEBUGOUTDIR)|g' \
-e 's|@udevdir@|$(UDEVDIR)|g' \
-e 's|@udevrulesdir@|$(UDEVRULESDIR)|g' \
$(1) > $${tmpout} \
&& mv $${tmpout} $(2) \
|| { rm $${tmpout}; false; } \
; }
endef
.PHONY: clean-mk-temp
clean: clean-mk-temp
clean-mk-temp:
rm -f .make.tmp.[[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]
# Definitions for generating documentation when $(ENABLE_DOC) is set to `1`
PANDOCFLAGS = --fail-if-warnings
ALL_PANDOCFLAGS = --preserve-tabs --tab-stop=8 --strip-comments \
--standalone --self-contained \
-M date="$(shell date +'%Y-%m-%d')" \
$(PANDOCFLAGS)
$(eval $(call cmd_define, PANDOC," PANDOC ",pandoc))
%.html : ALL_PANDOCFLAGS += -t html
%.html : %.md
$(PANDOC) $(ALL_PANDOCFLAGS) -f gfm -o $(@) $(<)
%.pdf : ALL_PANDOCFLAGS += -t latex --toc
%.pdf : %.md
$(PANDOC) $(ALL_PANDOCFLAGS) -f gfm -o $(@) $(<)
%.7 : ALL_PANDOCFLAGS += -t man
%.7 : %.md
$(PANDOC) $(ALL_PANDOCFLAGS) -f gfm -o $(@) $(<)

View File

@@ -0,0 +1,16 @@
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
add_dracutmodules+=" bash multipath udev-rules "
install_items+=" @udevrulesdir@/70-chreipl-fcp-mpath.rules "
install_items+=" @chreiplzfcpmp-lib@ "
install_items+=" @udevdir@/chreipl-fcp-mpath-is-ipl-tgt "
install_items+=" @udevdir@/chreipl-fcp-mpath-is-ipl-vol "
install_items+=" @udevdir@/chreipl-fcp-mpath-is-reipl-zfcp "
install_items+=" @udevdir@/chreipl-fcp-mpath-record-volume-identifier "
install_items+=" @udevdir@/chreipl-fcp-mpath-try-change-ipl-path "
install_items+=" flock hexdump logger mktemp readlink sync truncate "

View File

@@ -0,0 +1,101 @@
# SPDX-License-Identifier: MIT
#
# chreipl-fcp-mpath: use multipath information to change FCP IPL target
# (C) Copyright IBM Corp. 2021
# Did the event affect a multipath or scsi disk device?
ACTION=="change", KERNEL=="dm-[0-9]*", SUBSYSTEM=="block", \
ENV{DM_UUID}=="mpath-*", ENV{DM_ACTION}=="PATH_FAILED", \
GOTO="chreipl_fcp_mpath_path_change"
ACTION=="change", KERNEL=="dm-[0-9]*", SUBSYSTEM=="block", \
ENV{DM_UUID}=="mpath-*", ENV{DM_ACTION}=="PATH_REINSTATED", \
GOTO="chreipl_fcp_mpath_path_change"
ACTION=="add", KERNEL=="sd[a-z]*", SUBSYSTEM=="block", \
GOTO="chreipl_fcp_mpath_path_change"
GOTO="chreipl_fcp_mpath_end"
LABEL="chreipl_fcp_mpath_path_change"
# Is this system IPL'ed (IOW, are we on s390x)? And do we ReIPL via zFCP?
#
# udev(7): If no absolute path is given, the program is expected to live
# in /usr/lib/udev; otherwise, the absolute path must be
# specified.
TEST!="/sys/firmware/ipl", GOTO="chreipl_fcp_mpath_end"
PROGRAM!="chreipl-fcp-mpath-is-reipl-zfcp", GOTO="chreipl_fcp_mpath_end"
# Consider the following scenarios.
# Either:
#
# (A) We recognized a new SCSI Disk. This might represent:
# (a) the path we want to ReIPL from;
# (b) an alternative path to the volume we want to ReIPL from;
# (c) a path to some unrelated volume.
#
# Or:
#
# (B) We recognized a PATH_ event for a multipath device. This might represent:
# the path we want to ReIPL from:
# (a) went away;
# (b) came back online;
# an alternative path to the volume we want to ReIPL from:
# (c) went away;
# (d) came back online;
# (e) some unrelated multipath device saw an event.
# Test whether the affected device is, or contains, the current IPL target.
#
# This covers scenarios:
# (A) (a),
# (B) (a)/(b)/(c)/(d)
PROGRAM!="chreipl-fcp-mpath-is-ipl-tgt", \
ENV{CHREIPL_FCP_MPATH_IS_TGT}="false", \
GOTO="chreipl_fcp_mpath_not_direct_match"
ENV{CHREIPL_FCP_MPATH_IS_TGT}="true"
# Record the WWID, Device-Bus-ID, Remote WWPN, and LUN of the ReIPL target
# (see `chreipl-fcp-mpath-is-ipl-vol` for usecases). This information
# might change, depending on whether the machine operator changes the ReIPL
# target to a different volume.
#
# XXX: Because the kernel doesn't generate any events upon changing of
# the ReIPL target, the chreipl-fcp-mpath toolset can't take any
# actions until the next path event for the new target is
# generated. Following that, we assume that when the machine
# operator changes the ReIPL target, the new target is reachable
# and in a good state at this point in time.
PROGRAM!="chreipl-fcp-mpath-record-volume-identifier", \
GOTO="chreipl_fcp_mpath_try_change_ipl_path"
GOTO="chreipl_fcp_mpath_try_change_ipl_path"
# If the even subject is not a direct match (not the sdev that is the current
# ReIPL target, and not a mpath device that contains the current ReIPL target)
LABEL="chreipl_fcp_mpath_not_direct_match"
# While this sdev/mpath device doesn't directly correspond to the path
# currently set as ReIPL target, it might still point to the same volume.
#
# For mpath devices this can happen if the original ReIPL target is completely
# gone from the machine, and so there is no way we can successfully, directly
# compare the ReIPL parameters to the sdevs of the mpath device.
#
# For cases like these we recorded the volume identifier, which we now can
# compare, and so still decide whether we are addressing the correct volume.
#
# This covers scenarios:
# (A) (b)/(c),
# (B) (c)/(d)/(e)
#
# XXX: we recorded WWID, Device-Bus-ID, Remote WWPN, LUN of the ReIPL target at
# the time; if the latter three don't match the current ReIPL setting
# anymore, we have to assume that someone changed the ReIPL target
# manually, and we cannot use the WWID anymore since we can't possibly
# know whether that stayed the same when the change was done.
PROGRAM!="chreipl-fcp-mpath-is-ipl-vol", GOTO="chreipl_fcp_mpath_end"
# We are here because of scenarios:
# (A) (a)/(b),
# (B) (a)/(b)/(c)/(d)
LABEL="chreipl_fcp_mpath_try_change_ipl_path"
RUN{program}+="chreipl-fcp-mpath-try-change-ipl-path"
LABEL="chreipl_fcp_mpath_end"

View File

@@ -16,17 +16,18 @@ check_dep:
$(call check_dep, \
"cmsfs-fuse", \
"fuse.h", \
"fuse-devel or libfuse-dev", \
"HAVE_FUSE=0")
"fuse3-devel or libfuse3-dev", \
"HAVE_FUSE=0", \
"-DFUSE_USE_VERSION=30")
all: check_dep cmsfs-fuse
ifneq ($(shell sh -c 'command -v pkg-config'),)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
else
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
FUSE_LDLIBS = -lfuse
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
FUSE_LDLIBS = -lfuse3
endif
ALL_CFLAGS += -DHAVE_SETXATTR $(FUSE_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) -lm

View File

@@ -80,9 +80,6 @@ Allow access by other users
\fB\-o\fR allow_root
Allow access by root
.TP
\fB\-o\fR nonempty
Allow mounts over non\-empty file/dir
.TP
\fB\-o\fR default_permissions
Enable permission checking by kernel
.TP

View File

@@ -9,7 +9,7 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#define FUSE_USE_VERSION 26
#define FUSE_USE_VERSION 30
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -299,7 +299,7 @@ static unsigned long dec_to_hex(unsigned long long num)
{
unsigned long res;
asm volatile("cvb %0,%1" : "=d" (res) : "m" (num));
asm volatile("cvb %0,%1" : "=d" (res) : "Q" (num));
return res & 0xffffffff;
}
@@ -307,7 +307,7 @@ static unsigned int hex_to_dec(unsigned int num)
{
unsigned long long res;
asm volatile("cvd %1,%0" : "=m" (res) : "d" (num));
asm volatile("cvd %1,%0" : "=Q" (res) : "d" (num));
return res & 0xffffffff;
}
@@ -1516,7 +1516,7 @@ static void walk_dir_block(struct fst_entry *fst, struct walk_file *walk,
decode_edf_name(file, fst->name, fst->type);
if (!file_unlinked(file)) {
cache_fst_addr(walk->addr, file);
walk->filler(walk->buf, file, NULL, 0);
walk->filler(walk->buf, file, NULL, 0, 0);
}
}
}
@@ -1728,8 +1728,11 @@ static off_t get_file_size_logical(struct fst_entry *fst)
return total;
}
static int cmsfs_getattr(const char *path, struct stat *stbuf)
static int cmsfs_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
(void) fi;
int mask = (cmsfs.allow_other) ? 0444 : 0440;
struct fst_entry fst;
@@ -1783,13 +1786,15 @@ static int cmsfs_getattr(const char *path, struct stat *stbuf)
}
static int cmsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{
struct walk_file walk;
struct fst_entry fst;
(void) offset;
(void) fi;
(void) flags;
/*
* Offset is ignored and 0 passed to the filler fn so the whole
@@ -1800,8 +1805,8 @@ static int cmsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, ".", NULL, 0, 0);
filler(buf, "..", NULL, 0, 0);
memset(&walk, 0, sizeof(walk));
/* readdir is possible without open so fi->fh is not set */
@@ -2050,7 +2055,7 @@ static int update_dir_levels(int blocks)
if (blocks < 2)
return 0;
while (blocks / (PTRS_PER_BLOCK + 1)) {
while (blocks / PTRS_PER_BLOCK) {
levels++;
blocks /= PTRS_PER_BLOCK;
}
@@ -2683,13 +2688,16 @@ static int cmsfs_statfs(const char *path, struct statvfs *buf)
return 0;
}
static int cmsfs_utimens(const char *path, const struct timespec ts[2])
static int cmsfs_utimens(const char *path, const struct timespec ts[2],
struct fuse_file_info *fi)
{
struct fst_entry fst;
off_t fst_addr;
struct tm tm;
int rc;
(void) fi;
if (cmsfs.readonly)
return -EACCES;
@@ -2825,7 +2833,8 @@ error:
return rc;
}
static int cmsfs_rename(const char *path, const char *new_path)
static int cmsfs_rename(const char *path, const char *new_path,
unsigned int flags)
{
struct fst_entry fst, fst_new;
off_t fst_addr, fst_addr_new;
@@ -2835,6 +2844,8 @@ static int cmsfs_rename(const char *path, const char *new_path)
struct file *f;
int rc;
(void) flags;
if (cmsfs.readonly)
return -EACCES;
@@ -3103,7 +3114,7 @@ static void update_levels(struct file *f)
return;
}
while (blocks / (per_block + 1)) {
while (blocks / per_block) {
levels++;
blocks /= per_block;
}
@@ -3232,13 +3243,16 @@ static void update_fst(struct file *f, off_t addr)
unhide_null_blocks(f);
}
static int cmsfs_truncate(const char *path, off_t size)
static int cmsfs_truncate(const char *path, off_t size,
struct fuse_file_info *fi)
{
struct fst_entry fst;
off_t fst_addr, len;
struct file *f;
int rc = 0;
(void) fi;
if (cmsfs.readonly)
return -EROFS;
@@ -4478,6 +4492,15 @@ static void destroy_file_object(struct file *f)
free(f);
}
static void *cmsfs_oper_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
{
(void)conn;
/* force immediate file removal */
cfg->hard_remove = 1;
return NULL;
}
static struct file_operations fops_fixed = {
.cache_data = cache_file_fixed,
.write_data = extend_block_fixed,
@@ -4493,6 +4516,7 @@ static struct file_operations fops_variable = {
};
static struct fuse_operations cmsfs_oper = {
.init = cmsfs_oper_init,
.getattr = cmsfs_getattr,
.statfs = cmsfs_statfs,
.readdir = cmsfs_readdir,
@@ -4669,8 +4693,6 @@ int main(int argc, char *argv[])
fuse_opt_add_arg(&args, "-oro");
/* force single threaded mode which requires no locking */
fuse_opt_add_arg(&args, "-s");
/* force immediate file removal */
fuse_opt_add_arg(&args, "-ohard_remove");
if (cmsfs.mode == BINARY_MODE &&
(cmsfs.codepage_from != NULL || cmsfs.codepage_to != NULL))

View File

@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2
RELEASE = 15
RELEASE = 23
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -59,11 +59,8 @@ define cmd_define
endef
$(eval $(call cmd_define, AS," AS ",$(CROSS_COMPILE)as))
$(eval $(call cmd_define, LINK," LINK ",$(CROSS_COMPILE)gcc))
$(eval $(call cmd_define, LD," LD ",$(CROSS_COMPILE)ld))
$(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
$(eval $(call cmd_define, HOSTCC," HOSTCC ",gcc))
$(eval $(call cmd_define, LINKXX," LINKXX ",$(CROSS_COMPILE)g++))
$(eval $(call cmd_define, CXX," CXX ",$(CROSS_COMPILE)g++))
$(eval $(call cmd_define, CPP," CPP ",$(CROSS_COMPILE)gcc -E))
$(eval $(call cmd_define, AR," AR ",$(CROSS_COMPILE)ar))
@@ -84,6 +81,8 @@ CHECKTOOL = $(call echocmd," CHECK ",/$@)$(CHECK_SILENT)
SKIP = echo " SKIP $(call reldir) due to"
INSTALL = install
LINK = $(CC)
LINKXX = $(CXX)
CP = cp
ifneq ("${V}","1")
MAKEFLAGS += --quiet
@@ -92,13 +91,12 @@ ifneq ("${V}","1")
else
echocmd=
endif
DEFAULT_CFLAGS = -g -fstack-protector-all -W -Wall -Wformat-security
ifeq ("${W}","1")
DEFAULT_CFLAGS = -g -rdynamic -fstack-protector-all -W -Wall -Wformat-security -Wextra
else
DEFAULT_CFLAGS = -g -rdynamic -fstack-protector-all -W -Wall -Wformat-security
DEFAULT_CFLAGS += -Wextra -Wshadow -Wundef -Wuninitialized -Wdouble-promotion -Wconversion
endif
ifeq ("${D}","1")
DEFAULT_CFLAGS += -Og
DEFAULT_CFLAGS += -Og -g3 -ggdb3
else
DEFAULT_CFLAGS += -O3
endif
@@ -106,6 +104,25 @@ endif
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
DEFAULT_LDFLAGS = -rdynamic
ifeq ("${ASAN}","1")
DEFAULT_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
DEFAULT_LDFLAGS += -fsanitize=address
endif
#
# Check for header prerequisite
#
# $1: Name of include file to check
# $2: Additional compiler & linker options (optional)
#
# Returns "yes" on success and nothing otherwise
#
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)
endef
#
# Check for build dependency
#
@@ -116,7 +133,7 @@ DEFAULT_LDFLAGS = -rdynamic
# $5: Additional compiler & linker options (optional)
#
check_dep=\
printf "\#include <%s>\n int main(void) {return 0;}" $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 -xc - ) > /dev/null 2>&1; \
if [ $$? != 0 ]; \
then \
printf " REQCHK %s (%s)\n" $1 $2; \
@@ -163,7 +180,8 @@ USRSBINDIR = $(INSTALLDIR)/usr/sbin
USRBINDIR = $(INSTALLDIR)/usr/bin
BINDIR = $(INSTALLDIR)/sbin
LIBDIR = $(INSTALLDIR)/lib
LIB64DIR = $(INSTALLDIR)/lib64
USRLIBDIR = $(INSTALLDIR)/usr/lib
USRLIB64DIR = $(INSTALLDIR)/usr/lib64
SYSCONFDIR = $(INSTALLDIR)/etc
MANDIR = $(INSTALLDIR)/usr/share/man
VARDIR = $(INSTALLDIR)/var
@@ -174,15 +192,28 @@ ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
SYSTEMDSYSTEMUNITDIR =
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
ZKEYKMSPLUGINDIR = $(USRLIB64DIR)/zkey
UDEVDIR = $(USRLIBDIR)/udev
UDEVRULESDIR = $(UDEVDIR)/rules.d
DRACUTDIR = $(USRLIBDIR)/dracut
DRACUTCONFDIR = $(DRACUTDIR)/dracut.conf.d
DRACUTMODDIR = $(DRACUTDIR)/modules.d
ifeq ($(LIBDIR),$(INSTALLDIR)/lib)
SOINSTALLDIR = $(USRLIB64DIR)
else
SOINSTALLDIR = $(LIBDIR)
endif
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) \
$(LIB64DIR) $(USRINCLUDEDIR)
$(USRLIB64DIR) $(USRINCLUDEDIR) $(ZKEYKMSPLUGINDIR) \
$(SOINSTALLDIR) $(USRLIBDIR)
OWNER = $(shell id -un)
GROUP = $(shell id -gn)
export INSTALLDIR BINDIR LIBDIR LIB64DIR MANDIR OWNER GROUP
export INSTALLDIR BINDIR LIBDIR USRLIBDIR USRLIB64DIR MANDIR OWNER GROUP
# Special defines for zfcpdump
ZFCPDUMP_IMAGE = zfcpdump-image
@@ -224,11 +255,9 @@ export AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP INSTALL CFLAGS CXXFLAGS \
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
NO_PIE_CFLAGS := -fno-pie
NO_PIE_LINKFLAGS := -no-pie
NO_PIE_LDFLAGS := -no-pie
else
NO_PIE_CFLAGS :=
NO_PIE_LINKFLAGS :=
NO_PIE_LDFLAGS :=
endif
@@ -264,6 +293,7 @@ help:
@echo ' G=1 Build with gcov to collect code coverage data'
@echo ' V=1 Generate verbose build output'
@echo ' W=1 Build with higher warning level'
@echo ' ASAN=1 Build with address sanitizer'
@echo ''
@echo 'EXAMPLES'
@echo ' # make clean all D=1 W=1 -j'
@@ -342,10 +372,30 @@ $(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
.PHONY: $(rootdir)/libvmcp
$(rootdir)/libcpumf/libcpumf.a: $(rootdir)/libcpumf
$(MAKE) -C $(rootdir)/libcpumf/ libcpumf.a
.PHONY: $(rootdir)/libcpumf
$(rootdir)/libekmfweb/libekmfweb.so: $(rootdir)/libekmfweb
$(MAKE) -C $(rootdir)/libekmfweb/ libekmfweb.so
.PHONY: $(rootdir)/libekmfweb
$(rootdir)/libseckey/libseckey.a: $(rootdir)/libseckey
$(MAKE) -C $(rootdir)/libseckey/ libseckey.a
.PHONY: $(rootdir)/libseckey
$(rootdir)/libkmipclient/libkmipclient.so: $(rootdir)/libkmipclient
$(MAKE) -C $(rootdir)/libkmipclient/ libkmipclient.so
.PHONY: $(rootdir)/libkmipclient
$(rootdir)/libap/libap.a: $(rootdir)/libap
$(MAKE) -C $(rootdir)/libap/ libap.a
.PHONY: $(rootdir)/libap
$(rootdir)/libpv/libpv.a: $(rootdir)/libpv
$(MAKE) -C $(rootdir)/libpv libpv.a
.PHONY: $(rootdir)/libpv
$(rootdir)/zipl/boot/data.o:
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
@@ -366,9 +416,9 @@ install: install_echo install_dirs
clean_echo:
$(call echocmd," CLEAN ")
clean_gcov:
rm -f *.gcda *.gcno *.gcov
rm -f -- *.gcda *.gcno *.gcov
clean_dep:
rm -f .*.o.d
rm -f -- .*.o.d
clean: clean_echo clean_gcov clean_dep
endif

View File

@@ -1,11 +1,28 @@
include ../common.mak
ifeq (${HAVE_LIBUDEV},0)
all:
$(SKIP) HAVE_LIBUDEV=0
install:
$(SKIP) HAVE_LIBUDEV=0
else
check_dep:
$(call check_dep, \
"cpacfstatsd", \
"libudev.h", \
"systemd-devel", \
"HAVE_LIBUDEV=0")
ALL_CPPFLAGS += -DVERSION=$(VERSION)
all: cpacfstats cpacfstatsd
all: check_dep cpacfstats cpacfstatsd
cpacfstatsd: cpacfstatsd.o stats_sock.o perf_crypto.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -ludev -lpthread -o $@
cpacfstats: cpacfstats.o stats_sock.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
@@ -16,6 +33,8 @@ install: all
$(INSTALL) -m 644 cpacfstatsd.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 cpacfstats.1 $(DESTDIR)$(MANDIR)/man1
endif
clean:
rm -f *.o *~ cpacfstatsd cpacfstats

View File

@@ -1,6 +1,6 @@
.\" cpacfstats.1
.\"
.\" Copyright IBM Corp. 2015, 2020
.\" Copyright IBM Corp. 2015, 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.
.\"
@@ -32,7 +32,9 @@ cpacfstats \- enable, disable and display CPACF statistical data
.RB ]
.RB [ \-p | \-\-print
.I counter
.RB [ \-n | \-\-nonzero]
.RB ]
.RB [ \-j | \-\-json ]
.
.SH DESCRIPTION
The cpacfstats client application interacts with the cpacfstatsd daemon and
@@ -44,12 +46,347 @@ All counters are initially disabled and must be switched on to measure
CPACF activities of the system. There is a slight performance penalty with
CPACF counters enabled.
Note: All cryptographic counters are bound to physical CPUs. If you use
dedicated CPUs for your LPAR, you obtain only your CPACF activities. If
your CPUs are shared with other LPARs, their cryptographic activities might
distort the results. CPACF performance counters are available on LPARs
only. For security reasons only members of the group \fIcpacfstats\fR are
allowed to run the cpacfstats client application.
CPACF activity counters come in two flavors: CPU-MF and PAI. CPU-MF
counters are only available on LPARs and have to be authorized. If
they are available, the counters
.B des,
.B aes,
.B sha,
.B rng,
and
.B ecc
are made available. These counters can individually be activated,
reset, printed, or deactivated. PAI counters are a lot more detailed.
The user interface only offers the counters
.B pai_user
and
.B pai_kernel
to count CPACF usage in user-space or kernel-space. When printing
these counters, detailed counters are shown. The detailed names are:
.RS
.IP \(bu
KM DES,
.IP \(bu
KM 2key TDES,
.IP \(bu
KM TDES,
.IP \(bu
KM DES protected key,
.IP \(bu
KM 2key TDES protected key,
.IP \(bu
KM TDES protected key,
.IP \(bu
KM AES 128bit,
.IP \(bu
KM AES 192bit,
.IP \(bu
KM AES 256bit,
.IP \(bu
KM AES 128bit protected key,
.IP \(bu
KM AES 192bit protected key,
.IP \(bu
KM AES 256bit protected key,
.IP \(bu
KM AES-XTS 128bit,
.IP \(bu
KM AES-XTS 256bit,
.IP \(bu
KM AES-XTS 128bit protected key,
.IP \(bu
KM AES-XTS 256bit protected key,
.IP \(bu
KMC DES,
.IP \(bu
KMC 2key TDES,
.IP \(bu
KMC TDES,
.IP \(bu
KMC DES protected key,
.IP \(bu
KMC 2key TDES protected key,
.IP \(bu
KMC TDES protected key,
.IP \(bu
KMC AES 128bit,
.IP \(bu
KMC AES 192bit,
.IP \(bu
KMC AES 256bit,
.IP \(bu
KMC AES 128bit protected key,
.IP \(bu
KMC AES 192bit protected key,
.IP \(bu
KMC AES 256bit protected key,
.IP \(bu
KMC PRNG,
.IP \(bu
KMA AES 128bit,
.IP \(bu
KMA AES 192bit,
.IP \(bu
KMA AES 256bit,
.IP \(bu
KMA AES 128bit protected key,
.IP \(bu
KMA AES 192bit protected key,
.IP \(bu
KMA AES 256bit protected key,
.IP \(bu
KMF DES,
.IP \(bu
KMF 2key TDES,
.IP \(bu
KMF TDES,
.IP \(bu
KMF DES protected key,
.IP \(bu
KMF 2key TDES protected key,
.IP \(bu
KMF TDES protected key,
.IP \(bu
KMF AES 128bit,
.IP \(bu
KMF AES 192bit,
.IP \(bu
KMF AES 256bit,
.IP \(bu
KMF AES 128bit protected key,
.IP \(bu
KMF AES 192bit protected key,
.IP \(bu
KMF AES 256bit protected key,
.IP \(bu
KMCTR DES,
.IP \(bu
KMCTR 2key TDES,
.IP \(bu
KMCTR TDES,
.IP \(bu
KMCTR DES protected key,
.IP \(bu
KMCTR 2key TDES protected key,
.IP \(bu
KMCTR TDES protected key,
.IP \(bu
KMCTR AES 128bit,
.IP \(bu
KMCTR AES 192bit,
.IP \(bu
KMCTR AES 256bit,
.IP \(bu
KMCTR AES 128bit protected key,
.IP \(bu
KMCTR AES 192bit protected key,
.IP \(bu
KMCTR AES 256bit protected key,
.IP \(bu
KMO DES,
.IP \(bu
KMO 2key TDES,
.IP \(bu
KMO TDES,
.IP \(bu
KMO DES protected key,
.IP \(bu
KMO 2key TDES protected key,
.IP \(bu
KMO TDES protected key,
.IP \(bu
KMO AES 128bit,
.IP \(bu
KMO AES 192bit,
.IP \(bu
KMO AES 256bit,
.IP \(bu
KMO AES 128bit protected key,
.IP \(bu
KMO AES 192bit protected key,
.IP \(bu
KMO AES 256bit protected key,
.IP \(bu
KIMD SHA1,
.IP \(bu
KIMD SHA256,
.IP \(bu
KIMD SHA512,
.IP \(bu
KIMD SHA3-224,
.IP \(bu
KIMD SHA3-256,
.IP \(bu
KIMD SHA3-384,
.IP \(bu
KIMD SHA3-512,
.IP \(bu
KIMD SHAKE 128,
.IP \(bu
KIMD SHAKE 256,
.IP \(bu
KIMD GHASH,
.IP \(bu
KLMD SHA1,
.IP \(bu
KLMD SHA256,
.IP \(bu
KLMD SHA512,
.IP \(bu
KLMD SHA3-224,
.IP \(bu
KLMD SHA3-256,
.IP \(bu
KLMD SHA3-384,
.IP \(bu
KLMD SHA3-512,
.IP \(bu
KLMD SHAKE 128,
.IP \(bu
KLMD SHAKE 256,
.IP \(bu
KMAC DES,
.IP \(bu
KMAC 2key TDES,
.IP \(bu
KMAC TDES,
.IP \(bu
KMAC DES protected key,
.IP \(bu
KMAC 2key TDES protected key,
.IP \(bu
KMAC TDES protected key,
.IP \(bu
KMAC AES 128bit,
.IP \(bu
KMAC AES 192bit,
.IP \(bu
KMAC AES 256bit,
.IP \(bu
KMAC AES 128bit protected key,
.IP \(bu
KMAC AES 192bit protected key,
.IP \(bu
KMAC AES 256bit protected key,
.IP \(bu
PCC Last Block CMAC DES,
.IP \(bu
PCC Last Block CMAC 2key TDES,
.IP \(bu
PCC Last Block CMAC TDES,
.IP \(bu
PCC Last Block CMAC DES protected key,
.IP \(bu
PCC Last Block CMAC 2key TDES protected key,
.IP \(bu
PCC Last Block CMAC TDES protected key,
.IP \(bu
PCC Last Block CMAC AES 128bit,
.IP \(bu
PCC Last Block CMAC AES 192bit,
.IP \(bu
PCC Last Block CMAC AES 256bit,
.IP \(bu
PCC Last Block CMAC AES 128bit protected key,
.IP \(bu
PCC Last Block CMAC AES 192bit protected key,
.IP \(bu
PCC Last Block CMAC AES 256bit protected key,
.IP \(bu
PCC XTS Parameter AES 128bit,
.IP \(bu
PCC XTS Parameter AES 256bit,
.IP \(bu
PCC XTS Parameter AES 128bit protected key,
.IP \(bu
PCC XTS Parameter AES 256bit protected key,
.IP \(bu
PCC Scalar Mult P256,
.IP \(bu
PCC Scalar Mult P384,
.IP \(bu
PCC Scalar Mult P521,
.IP \(bu
PCC Scalar Mult Ed25519,
.IP \(bu
PCC Scalar Mult Ed448,
.IP \(bu
PCC Scalar Mult X25519,
.IP \(bu
PCC Scalar Mult X448,
.IP \(bu
PRNO SHA512 DRNG,
.IP \(bu
PRNO TRNG Query Ratio,
.IP \(bu
PRNO TRNG,
.IP \(bu
KDSA ECDSA Verify P256,
.IP \(bu
KDSA ECDSA Verify P384,
.IP \(bu
KDSA ECDSA Verify P521,
.IP \(bu
KDSA ECDSA Sign P256,
.IP \(bu
KDSA ECDSA Sign P384,
.IP \(bu
KDSA ECDSA Sign P521,
.IP \(bu
KDSA ECDSA Sign P256 protected key,
.IP \(bu
KDSA ECDSA Sign P384 protected key,
.IP \(bu
KDSA ECDSA Sign P521 protected key,
.IP \(bu
KDSA EdDSA Verify Ed25519,
.IP \(bu
KDSA EdDSA Verify Ed448,
.IP \(bu
KDSA EdDSA Sign Ed25519,
.IP \(bu
KDSA EdDSA Sign Ed448,
.IP \(bu
KDSA EdDSA Sign Ed25519 protected key,
.IP \(bu
KDSA EdDSA Sign Ed448 protected key,
.IP \(bu
PCKMO DES,
.IP \(bu
PCKMO 2key TDES,
.IP \(bu
PCMKO TDES,
.IP \(bu
PCKMO AES 128bit,
.IP \(bu
PCKMO AES 192bit,
.IP \(bu
PCMKO AES 256bit,
.IP \(bu
PCKMO ECC P256,
.IP \(bu
PCKMO ECC P384,
.IP \(bu
PCKMO ECC P521,
.IP \(bu
PCKMO ECC Ed25519,
.IP \(bu
PCKMO ECC Ed448,
.IP \(bu
Reserved 1, and
.IP \(bu
Reserved 2.
.RE
Note that the counters starting with PCKMO and Reserved are only
available in the pai_kernel set. Also note that the counters are
designed to count successful operations. In the case of KMA this
means only complete GCM operations including final hashing are
counted.
Note: CPU-MF based CPACF performance counters are available on LPARs
only. PAI counters are available on all hypervisors. For security
reasons only members of the group \fIcpacfstats\fR are allowed to run
the cpacfstats client application.
Example usage scenario:
.P
@@ -101,12 +438,34 @@ argument can be one of: \fBdes\fR, \fBaes\fR, \fBsha\fR, \fBprng\fR,
\fBecc\fR, or \fBall\fR. If the counter argument is omitted, all
performance counters are reset to 0.
.TP
\fB\-p\fR or \fB\-\-print\fR [counter]
\fB\-p\fR or \fB\-\-print\fR [\fB\-n\fR or \fB\-\-nonzero\fR] [counter]
Display the value of one or all CPACF performance counters. The
optional counter argument can be one of: \fBdes\fR, \fBaes\fR,
\fBsha\fR, \fBprng\fR, \fBecc\fR, or \fBall\fR. If the counter
argument is omitted or if there is no argument, all performance
counters are displayed.
\fBsha\fR, \fBprng\fR, \fBecc\fR, \fBpai_user\fR, \fBpai_kernel\fR, or
\fBall\fR. If the counter argument is omitted or if there is no
argument, all performance counters are displayed. If the optional
\fB\-n\fR or \fB\-\-nonzero\fR argument is given, then only PAI
counters that have a non-zero value are printed.
.TP
\fB\-j\fR or \fB\-\-json\fR
Display all activated counters in JSON format. The JSON contains an
array of counter objects. Each object contains the property
.B counter
specifying either a CPU-MF counter of one of the detailed PAI counter.
Additional properties include
.B error
an error number if the counter could not be read,
.B value
the counter value if the counter could be read,
.B space
for PAI counters to specify
.B user
or
.B kernel
space counter set, and
.B counterid
for PAI counters to specify the PAI counter number as specified in the
Principles of Operation.
.TP
The default command is --print all.
.

View File

@@ -3,7 +3,7 @@
*
* cpacfstats client implementation
*
* Copyright IBM Corp. 2015, 2020
* Copyright IBM Corp. 2015, 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.
@@ -39,17 +39,187 @@ static const char *const usage =
"\t-d, --disable [counter] Disable one or all counters\n"
"\t-r, --reset [counter] Reset one or all counter values\n"
"\t-p, --print [counter] Print one or all counter values\n"
"\tcounter can be: 'aes' 'des' 'rng' 'sha' 'ecc' or 'all'\n";
"\t-n, --nonzero Print all PAI counters\n"
"\t-j, --json Print all counter values in JSON format\n"
"\tcounter can be: 'aes' 'des' 'rng' 'sha' 'ecc'\n"
"\t 'pai_user' 'pai_kernel' or 'all'\n";
static const char *const counter_str[] = {
[DES_FUNCTIONS] = "des",
[AES_FUNCTIONS] = "aes",
[SHA_FUNCTIONS] = "sha",
[PRNG_FUNCTIONS] = "rng",
[ECC_FUNCTIONS] = "ecc",
[ALL_COUNTER] = "all"
[ECC_FUNCTIONS] = "ecc",
[ALL_COUNTER] = "all",
[PAI_USER] = "pai_user",
[PAI_KERNEL] = "pai_kernel"
};
/* Strings for the pai counter details. Note that this is 0-based
* while PoP is 1-based.
*/
static const char *const pai_str[] = {
[ 0] = "KM DES",
[ 1] = "KM 2key TDES",
[ 2] = "KM TDES",
[ 3] = "KM DES protected key",
[ 4] = "KM 2key TDES protected key",
[ 5] = "KM TDES protected key",
[ 6] = "KM AES 128bit",
[ 7] = "KM AES 192bit",
[ 8] = "KM AES 256bit",
[ 9] = "KM AES 128bit protected key",
[ 10] = "KM AES 192bit protected key",
[ 11] = "KM AES 256bit protected key",
[ 12] = "KM AES-XTS 128bit",
[ 13] = "KM AES-XTS 256bit",
[ 14] = "KM AES-XTS 128bit protected key",
[ 15] = "KM AES-XTS 256bit protected key",
[ 16] = "KMC DES",
[ 17] = "KMC 2key TDES",
[ 18] = "KMC TDES",
[ 19] = "KMC DES protected key",
[ 20] = "KMC 2key TDES protected key",
[ 21] = "KMC TDES protected key",
[ 22] = "KMC AES 128bit",
[ 23] = "KMC AES 192bit",
[ 24] = "KMC AES 256bit",
[ 25] = "KMC AES 128bit protected key",
[ 26] = "KMC AES 192bit protected key",
[ 27] = "KMC AES 256bit protected key",
[ 28] = "KMC PRNG",
[ 29] = "KMA AES 128bit",
[ 30] = "KMA AES 192bit",
[ 31] = "KMA AES 256bit",
[ 32] = "KMA AES 128bit protected key",
[ 33] = "KMA AES 192bit protected key",
[ 34] = "KMA AES 256bit protected key",
[ 35] = "KMF DES",
[ 36] = "KMF 2key TDES",
[ 37] = "KMF TDES",
[ 38] = "KMF DES protected key",
[ 39] = "KMF 2key TDES protected key",
[ 40] = "KMF TDES protected key",
[ 41] = "KMF AES 128bit",
[ 42] = "KMF AES 192bit",
[ 43] = "KMF AES 256bit",
[ 44] = "KMF AES 128bit protected key",
[ 45] = "KMF AES 192bit protected key",
[ 46] = "KMF AES 256bit protected key",
[ 47] = "KMCTR DES",
[ 48] = "KMCTR 2key TDES",
[ 49] = "KMCTR TDES",
[ 50] = "KMCTR DES protected key",
[ 51] = "KMCTR 2key TDES protected key",
[ 52] = "KMCTR TDES protected key",
[ 53] = "KMCTR AES 128bit",
[ 54] = "KMCTR AES 192bit",
[ 55] = "KMCTR AES 256bit",
[ 56] = "KMCTR AES 128bit protected key",
[ 57] = "KMCTR AES 192bit protected key",
[ 58] = "KMCTR AES 256bit protected key",
[ 59] = "KMO DES",
[ 60] = "KMO 2key TDES",
[ 61] = "KMO TDES",
[ 62] = "KMO DES protected key",
[ 63] = "KMO 2key TDES protected key",
[ 64] = "KMO TDES protected key",
[ 65] = "KMO AES 128bit",
[ 66] = "KMO AES 192bit",
[ 67] = "KMO AES 256bit",
[ 68] = "KMO AES 128bit protected key",
[ 69] = "KMO AES 192bit protected key",
[ 70] = "KMO AES 256bit protected key",
[ 71] = "KIMD SHA1",
[ 72] = "KIMD SHA256",
[ 73] = "KIMD SHA512",
[ 74] = "KIMD SHA3-224",
[ 75] = "KIMD SHA3-256",
[ 76] = "KIMD SHA3-384",
[ 77] = "KIMD SHA3-512",
[ 78] = "KIMD SHAKE 128",
[ 79] = "KIMD SHAKE 256",
[ 80] = "KIMD GHASH",
[ 81] = "KLMD SHA1",
[ 82] = "KLMD SHA256",
[ 83] = "KLMD SHA512",
[ 84] = "KLMD SHA3-224",
[ 85] = "KLMD SHA3-256",
[ 86] = "KLMD SHA3-384",
[ 87] = "KLMD SHA3-512",
[ 88] = "KLMD SHAKE 128",
[ 89] = "KLMD SHAKE 256",
[ 90] = "KMAC DES",
[ 91] = "KMAC 2key TDES",
[ 92] = "KMAC TDES",
[ 93] = "KMAC DES protected key",
[ 94] = "KMAC 2key TDES protected key",
[ 95] = "KMAC TDES protected key",
[ 96] = "KMAC AES 128bit",
[ 97] = "KMAC AES 192bit",
[ 98] = "KMAC AES 256bit",
[ 99] = "KMAC AES 128bit protected key",
[100] = "KMAC AES 192bit protected key",
[101] = "KMAC AES 256bit protected key",
[102] = "PCC Last Block CMAC DES",
[103] = "PCC Last Block CMAC 2key TDES",
[104] = "PCC Last Block CMAC TDES",
[105] = "PCC Last Block CMAC DES protected key",
[106] = "PCC Last Block CMAC 2key TDES protected key",
[107] = "PCC Last Block CMAC TDES protected key",
[108] = "PCC Last Block CMAC AES 128bit",
[109] = "PCC Last Block CMAC AES 192bit",
[110] = "PCC Last Block CMAC AES 256bit",
[111] = "PCC Last Block CMAC AES 128bit protected key",
[112] = "PCC Last Block CMAC AES 192bit protected key",
[113] = "PCC Last Block CMAC AES 256bit protected key",
[114] = "PCC XTS Parameter AES 128bit",
[115] = "PCC XTS Parameter AES 256bit",
[116] = "PCC XTS Parameter AES 128bit protected key",
[117] = "PCC XTS Parameter AES 256bit protected key",
[118] = "PCC Scalar Mult P256",
[119] = "PCC Scalar Mult P384",
[120] = "PCC Scalar Mult P521",
[121] = "PCC Scalar Mult Ed25519",
[122] = "PCC Scalar Mult Ed448",
[123] = "PCC Scalar Mult X25519",
[124] = "PCC Scalar Mult X448",
[125] = "PRNO SHA512 DRNG",
[126] = "PRNO TRNG Query Ratio",
[127] = "PRNO TRNG",
[128] = "KDSA ECDSA Verify P256",
[129] = "KDSA ECDSA Verify P384",
[130] = "KDSA ECDSA Verify P521",
[131] = "KDSA ECDSA Sign P256",
[132] = "KDSA ECDSA Sign P384",
[133] = "KDSA ECDSA Sign P521",
[134] = "KDSA ECDSA Sign P256 protected key",
[135] = "KDSA ECDSA Sign P384 protected key",
[136] = "KDSA ECDSA Sign P521 protected key",
[137] = "KDSA EdDSA Verify Ed25519",
[138] = "KDSA EdDSA Verify Ed448",
[139] = "KDSA EdDSA Sign Ed25519",
[140] = "KDSA EdDSA Sign Ed448",
[141] = "KDSA EdDSA Sign Ed25519 protected key",
[142] = "KDSA EdDSA Sign Ed448 protected key",
[143] = "PCKMO DES",
[144] = "PCKMO 2key TDES",
[145] = "PCMKO TDES",
[146] = "PCKMO AES 128bit",
[147] = "PCKMO AES 192bit",
[148] = "PCMKO AES 256bit",
[149] = "PCKMO ECC P256",
[150] = "PCKMO ECC P384",
[151] = "PCKMO ECC P521",
[152] = "PCKMO ECC Ed25519",
[153] = "PCKMO ECC Ed448",
[154] = "Reserved 1",
[155] = "Reserved 2"
};
static int paiprintnonzero;
static int send_query(int s, enum cmd_e cmd, enum ctr_e ctr)
{
@@ -62,7 +232,7 @@ static int send_query(int s, enum cmd_e cmd, enum ctr_e ctr)
m.query.m_ctr = ctr;
m.query.m_cmd = cmd;
return send_msg(s, &m);
return send_msg(s, &m, 0);
}
@@ -71,7 +241,7 @@ static int recv_answer(int s, int *ctr, int *state, uint64_t *value)
struct msg m;
int rc;
rc = recv_msg(s, &m);
rc = recv_msg(s, &m, 0);
if (rc == 0) {
if (m.head.m_ver != VERSION) {
eprint("Received msg with wrong version %d != %d\n",
@@ -92,9 +262,139 @@ static int recv_answer(int s, int *ctr, int *state, uint64_t *value)
}
static void print_answer(int ctr, int state, uint64_t value)
static void printjsonsep(void)
{
if (state < 0)
static const char *jsonsep = "";
fputs(jsonsep, stdout);
jsonsep = ",";
}
static void json_print_virtual_counter_answer(int s, int ctr,
int state, uint64_t value)
{
int paictr = 0, paistate = 0, ec;
uint64_t i, paivalue = 0, maxnum;
const char *space;
switch (ctr) {
case HOTPLUG_DETECTED:
printjsonsep();
printf("{\"counter\":\"hotplug detected\",");
if (state < 0)
printf("\"error\":%d}", state);
else
printf("\"value\":%d}", !!value);
return;
case PAI_USER:
maxnum = NUM_PAI_USER;
space = "user";
break;
case PAI_KERNEL:
maxnum = NUM_PAI_KERNEL;
space = "kernel";
break;
default:
return;
}
/* Here, we have validated the PAI counter retrieved, but not
* yet printed. */
if (state != ENABLED)
return;
if (value > maxnum) {
eprint("Incompatible versions detected!\n");
eprint("Expected %"PRIu64" counter space for %s, but got %"PRIu64"\n",
maxnum, space, value);
exit(EXIT_FAILURE);
}
for (i = 0; i < value; ++i) {
ec = recv_answer(s, &paictr, &paistate, &paivalue);
if (ec < 0 || paistate < 0) {
eprint("Error on receiving answer message from daemon\n");
/* No more data for this virtual event after error. */
return;
}
if (paictr > NUM_PAI_KERNEL) {
eprint("Pai counter number too big: %d\n", paictr);
} else {
printjsonsep();
printf("{\"counter\":\"%s\",\"space\":\"%s\",\"counterid\":%d,",
pai_str[paictr], space, paictr + 1);
if (paistate < 0) {
printf("\"error\":%d}", paistate);
/* Protocol does not send furter counters. */
return;
}
printf("\"value\":%"PRIu64"}", paivalue);
}
}
}
static void print_virtual_counter_answer(int s,
int ctr, int state, uint64_t value)
{
static const char *const states[] = {
[DISABLED] = "disabled",
[ENABLED] = "enabled",
[UNSUPPORTED] = "unsupported"
};
int paictr = 0, paistate = 0, ec;
uint64_t i, paivalue = 0, maxnum;
const char *ctrstr;
switch (ctr) {
case HOTPLUG_DETECTED:
if (state >= 0 && value > 0)
printf(" hotplug detected\n");
return;
case PAI_USER:
maxnum = NUM_PAI_USER;
ctrstr = "pai_user";
break;
case PAI_KERNEL:
maxnum = NUM_PAI_KERNEL;
ctrstr = "pai_kernel";
break;
default:
return;
}
/* Here, we have validated the PAI counter retrieved, but not
* yet printed. */
if (state < 0 || state > UNSUPPORTED) {
printf(" %11s: error state %d\n", ctrstr, state);
/* No details follow if counter in error state. */
return;
}
printf(" %-11s: %s\n", ctrstr, states[state]);
if (state != ENABLED)
return;
if (value > maxnum) {
eprint("Incompatible versions detected!\n");
eprint("Expected %"PRIu64" counters for %s, but got %"PRIu64"\n",
maxnum, ctrstr, value);
exit(EXIT_FAILURE);
}
for (i = 0; i < value; ++i) {
ec = recv_answer(s, &paictr, &paistate, &paivalue);
if (ec < 0 || paistate < 0) {
eprint("Error on receiving answer message from daemon\n");
/* No more data for this virtual event after error. */
return;
}
if (paictr > NUM_PAI_KERNEL)
eprint("Pai counter number too big: %d\n", paictr);
else if (!paiprintnonzero || paivalue > 0)
printf(" %-45s: %"PRIu64"\n", pai_str[paictr], paivalue);
}
}
static void print_answer(int s, int ctr, int state, uint64_t value)
{
if (ctr > ALL_COUNTER)
print_virtual_counter_answer(s, ctr, state, value);
else if (state < 0)
printf(" %s counter: error state %d\n",
counter_str[ctr], state);
else if (state == DISABLED)
@@ -106,6 +406,22 @@ static void print_answer(int ctr, int state, uint64_t value)
}
static void json_print_answer(int s, int ctr, int state, uint64_t value)
{
if (ctr > ALL_COUNTER) {
json_print_virtual_counter_answer(s, ctr, state, value);
} else if (state < 0) {
printjsonsep();
printf("{\"counter\":\"%s\",", counter_str[ctr]);
printf("\"error\":%d}\n", state);
} else if (state == ENABLED) {
printjsonsep();
printf("{\"counter\":\"%s\",", counter_str[ctr]);
printf("\"value\":%"PRIu64"}", value);
}
}
int eprint(const char *format, ...)
{
char buf[1024];
@@ -128,7 +444,7 @@ int main(int argc, char *argv[])
{
enum ctr_e ctr = ALL_COUNTER;
enum cmd_e cmd = PRINT;
int i, j, s, state;
int i, j, s, state, num, json = 0;
uint64_t value;
if (argc > 1) {
@@ -140,98 +456,108 @@ int main(int argc, char *argv[])
{ "disable", 0, NULL, 'd' },
{ "reset", 0, NULL, 'r' },
{ "print", 0, NULL, 'p' },
{ "nonzero", 0, NULL, 'n' },
{ "json", 0, NULL, 'j' },
{ NULL, 0, NULL, 0 } };
while (1) {
opt = getopt_long(argc, argv,
"hvedrp", long_opts, &idx);
"hvedrpnj", long_opts, &idx);
if (opt == -1)
break; /* no more arguments */
switch (opt) {
case 'h':
printf(usage, name);
exit(0);
break;
return 0;
case 'v':
printf("%s: Linux on System z CPACF Crypto Activity Counters Client\n"
"Version %s\n%s\n",
name, RELEASE_STRING, COPYRIGHT);
exit(0);
break;
return 0;
case 'e':
cmd = ENABLE;
json = 0;
break;
case 'd':
cmd = DISABLE;
json = 0;
break;
case 'r':
cmd = RESET;
break;
case 'p':
cmd = PRINT;
json = 0;
break;
case 'n':
paiprintnonzero = 1;
break;
case 'j':
cmd = PRINT;
json = 1;
break;
default:
eprint("Invalid argument, try -h or --help for more information\n");
exit(1);
break;
return EXIT_FAILURE;
}
}
/* there may be an optional counter argument */
if (optind > 0 && optind < argc) {
for (i = 0; i <= ALL_COUNTER; i++)
for (i = 0; i < NUM_COUNTER; i++)
if (strcmp(argv[optind], counter_str[i]) == 0)
break;
if (i > ALL_COUNTER) {
if (i >= NUM_COUNTER) {
eprint("Unknown counter '%s'\n", argv[optind]);
exit(1);
return EXIT_FAILURE;
}
ctr = (enum ctr_e) i;
}
}
if (json)
ctr = ALL_COUNTER;
/* try to open and connect socket to the cpacfstatsd daemon */
s = open_socket(CLIENT);
if (s < 0) {
eprint("Can't connect to daemon\n");
exit(1);
return EXIT_FAILURE;
}
/* send query */
if (send_query(s, cmd, ctr) != 0) {
eprint("Error on sending query message to daemon\n");
close(s);
exit(1);
return EXIT_FAILURE;
}
if (ctr == ALL_COUNTER) {
for (i = 0; i < ALL_COUNTER; i++) {
/* receive answer */
if (recv_answer(s, &j, &state, &value) != 0) {
eprint("Error on receiving answer message from daemon\n");
exit(1);
}
if (state < 0) {
eprint("Received bad status code %d from daemon\n",
state);
close(s);
exit(1);
}
print_answer(j, state, value);
}
/* The -1 is for ALL_COUNTER which is not sent, +1 for
* hotplug state. */
num = NUM_COUNTER - 1 + 1;
} else {
/* +1 for hotplug state */
num = 1 + 1;
}
if (json)
putchar('[');
for (i = 0; i < num; i++) {
/* receive answer */
if (recv_answer(s, &j, &state, &value) != 0) {
eprint("Error on receiving answer message from daemon\n");
close(s);
exit(1);
return EXIT_FAILURE;
}
if (state < 0) {
eprint("Received bad status code %d from daemon\n",
state);
state);
close(s);
exit(1);
return EXIT_FAILURE;
}
print_answer(j, state, value);
if (json)
json_print_answer(s, j, state, value);
else
print_answer(s, j, state, value);
}
if (json)
putchar(']');
/* close connection */
close(s);

View File

@@ -3,7 +3,7 @@
*
* common function prototypes and definitions
*
* Copyright IBM Corp. 2015, 2020
* Copyright IBM Corp. 2015, 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.
@@ -14,13 +14,27 @@
#include "lib/zt_common.h"
#define COPYRIGHT "Copyright IBM Corp. 2015, 2020"
#define COPYRIGHT "Copyright IBM Corp. 2015, 2022"
#define DEFAULT_SEND_TIMEOUT (30 * 1000)
#define DEFAULT_RECV_TIMEOUT (30 * 1000)
/*
* Number of PAI counters for user space. This excludes PCKMO since
* this instruction is privileged.
*/
#define NUM_PAI_USER 143
/* Number of PAI counters for kernel space. Contains all counters. */
#define NUM_PAI_KERNEL 156
int eprint(const char *format, ...);
/*
* Counter names
* ALL_COUNTER must always be the last member of the enum
* ALL_COUNTER specifies the number of physical counters. Virtual
* counters might be added afterwards. NUM_COUNTER is the last
* managed counter (i.e., a counter that can be activated, reset,
* deactivated).
*/
enum ctr_e {
DES_FUNCTIONS = 0,
@@ -28,7 +42,11 @@ enum ctr_e {
SHA_FUNCTIONS,
PRNG_FUNCTIONS,
ECC_FUNCTIONS,
ALL_COUNTER
ALL_COUNTER,
PAI_USER,
PAI_KERNEL,
NUM_COUNTER,
HOTPLUG_DETECTED = 0xffff
};
enum type_e {
@@ -50,7 +68,7 @@ enum state_e {
};
/*
* query send from clent to daemon
* query send from client to daemon
* Consist of:
* enum counter
* enum command
@@ -63,7 +81,7 @@ struct msg_query {
/*
* answer send from daemon to client
* Consist of:
* enum counter
* enum counter or PAI counter number if following PAI_USER or PAI_KERNEL
* status code: < 0 error, 0 disabled, > 0 enabled
* counter value
*/
@@ -99,17 +117,20 @@ struct msg {
} __packed;
int open_socket(int mode);
int send_msg(int sfd, struct msg *m);
int recv_msg(int sfd, struct msg *m);
int send_msg(int sfd, struct msg *m, int timeout);
int recv_msg(int sfd, struct msg *m, int timeout);
/* perf_crypto.c */
int perf_init(void);
void perf_stop(void);
void perf_close(void);
int perf_enable_ctr(enum ctr_e ctr);
int perf_disable_ctr(enum ctr_e ctr);
int perf_reset_ctr(enum ctr_e ctr);
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value);
int perf_read_ctr(enum ctr_e ctr, uint64_t *value);
int perf_ecc_supported(void);
int perf_ctr_state(enum ctr_e ctr);
int perf_read_pai_ctr(unsigned int ctrnum, int user, uint64_t *value);
#endif

View File

@@ -3,7 +3,7 @@
*
* cpacfstatsd daemon implementation
*
* Copyright IBM Corp. 2015, 2017
* Copyright IBM Corp. 2015, 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.
@@ -28,6 +28,7 @@
#include "lib/zt_common.h"
#include "cpacfstats.h"
static volatile int stopsig;
static const char *const name = "cpacfstatsd";
@@ -43,15 +44,12 @@ static const char *const usage =
static int daemonized;
static int ctr_state[ALL_COUNTER];
static int recv_query(int s, enum ctr_e *ctr, enum cmd_e *cmd)
{
struct msg m;
int rc;
rc = recv_msg(s, &m);
rc = recv_msg(s, &m, DEFAULT_RECV_TIMEOUT);
if (rc == 0) {
if (m.head.m_ver != VERSION) {
eprint("Received msg with wrong version %d != %d\n",
@@ -83,38 +81,82 @@ static int send_answer(int s, int ctr, int state, uint64_t value)
m.answer.m_state = state;
m.answer.m_value = value;
return send_msg(s, &m);
return send_msg(s, &m, DEFAULT_SEND_TIMEOUT);
}
/*
* Print according to protocol for PAI:
* - first the state and the number of PAI counters that follow
* - if state is ENABLED:
* - for each PAI counter the value with state ENABLED
* Note that the PAI counters are 0-based, not 1 based as in PoP!
* Sending ends with the first error.
*/
static int do_send_pai(int s, int user)
{
int ctr, state, i, maxctr, rc = 0;
uint64_t value;
if (user) {
ctr = PAI_USER;
maxctr = NUM_PAI_USER;
} else {
ctr = PAI_KERNEL;
maxctr = NUM_PAI_KERNEL;
}
state = perf_ctr_state(ctr);
if (state != ENABLED)
return rc;
for (i = 0; i < maxctr; ++i) {
rc = perf_read_pai_ctr(i, user, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
send_answer(s, i, state, value);
}
return rc;
}
static int do_enable(int s, enum ctr_e ctr)
{
uint64_t value;
uint64_t value = 0;
int i, rc = 0;
int state;
for (i = 0; i < ALL_COUNTER; i++) {
for (i = 0; i < NUM_COUNTER; i++) {
if (i == ALL_COUNTER)
continue;
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i] == DISABLED) {
state = perf_ctr_state(i);
if (state == DISABLED) {
rc = perf_enable_ctr(i);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
ctr_state[i] = ENABLED;
state = ENABLED;
}
if (ctr_state[i] == UNSUPPORTED) {
send_answer(s, i, UNSUPPORTED, 0);
} else {
if (state != UNSUPPORTED) {
rc = perf_read_ctr(i, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
send_answer(s, i, ENABLED, value);
}
send_answer(s, i, state, value);
if (i == PAI_USER)
rc = do_send_pai(s, 1);
if (i == PAI_KERNEL)
rc = do_send_pai(s, 0);
}
}
if (rc == 0) {
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
send_answer(s, HOTPLUG_DETECTED, rc, value);
}
return rc;
}
@@ -122,67 +164,90 @@ static int do_enable(int s, enum ctr_e ctr)
static int do_disable(int s, enum ctr_e ctr)
{
int i, rc = 0;
uint64_t value;
for (i = 0; i < ALL_COUNTER; i++) {
for (i = 0; i < NUM_COUNTER; i++) {
if (i == ALL_COUNTER)
continue;
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i] == ENABLED) {
if (perf_ctr_state(i) == ENABLED) {
rc = perf_disable_ctr(i);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
ctr_state[i] = 0;
}
send_answer(s, i, ctr_state[i], 0);
send_answer(s, i, perf_ctr_state(i), 0);
}
}
if (rc == 0) {
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
send_answer(s, HOTPLUG_DETECTED, rc, value);
}
return rc;
}
static int do_reset(int s, enum ctr_e ctr)
{
int i, rc = 0;
int i, rc = 0, state;
uint64_t value;
for (i = 0; i < ALL_COUNTER; i++) {
for (i = 0; i < NUM_COUNTER; i++) {
if (i == ALL_COUNTER)
continue;
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i] == ENABLED) {
rc = perf_reset_ctr(i);
state = perf_ctr_state(i);
if (state == ENABLED) {
rc = perf_reset_ctr(i, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
send_answer(s, i, ENABLED, 0);
} else {
send_answer(s, i, ctr_state[i], 0);
}
send_answer(s, i, state, value);
if (i == PAI_USER)
rc = do_send_pai(s, 1);
if (i == PAI_KERNEL)
rc = do_send_pai(s, 0);
}
}
if (rc == 0) {
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
send_answer(s, HOTPLUG_DETECTED, rc, value);
}
return rc;
}
static int do_print(int s, enum ctr_e ctr)
{
int i, rc = 0;
uint64_t value;
int i, rc = 0, state;
uint64_t value = 0;
for (i = 0; i < ALL_COUNTER; i++) {
for (i = 0; i < NUM_COUNTER; i++) {
if (i == ALL_COUNTER)
continue;
if (i == (int) ctr || ctr == ALL_COUNTER) {
if (ctr_state[i] == ENABLED) {
state = perf_ctr_state(i);
if (state == ENABLED) {
rc = perf_read_ctr(i, &value);
if (rc != 0) {
send_answer(s, i, rc, 0);
break;
}
send_answer(s, i, ENABLED, value);
} else {
send_answer(s, i, ctr_state[i], 0);
}
send_answer(s, i, state, value);
if (i == PAI_USER)
rc = do_send_pai(s, 1);
if (i == PAI_KERNEL)
rc = do_send_pai(s, 0);
}
}
if (rc == 0) {
rc = perf_read_ctr(HOTPLUG_DETECTED, &value);
send_answer(s, HOTPLUG_DETECTED, rc, value);
}
return rc;
}
@@ -324,18 +389,8 @@ static void remove_pidfile(void)
void signalhandler(int sig)
{
if (sig == SIGTERM)
eprint("Caught signal SIGTERM, terminating...\n");
else if (sig == SIGINT)
eprint("Caught signal SIGINT, terminating...\n");
else
eprint("Caught signal %d, terminating...\n", sig);
remove_sock();
perf_close();
remove_pidfile();
exit(0);
perf_stop();
stopsig = sig;
}
@@ -381,7 +436,7 @@ int main(int argc, char *argv[])
switch (opt) {
case 'h':
printf(usage, name);
exit(0);
return 0;
case 'f':
foreground = 1;
break;
@@ -389,40 +444,37 @@ int main(int argc, char *argv[])
printf("%s: Linux on System z CPACF Crypto Activity Counters Daemon\n"
"Version %s\n%s\n",
name, RELEASE_STRING, COPYRIGHT);
exit(0);
return 0;
default:
printf("%s: Invalid argument, try -h or --help for more information\n",
name);
exit(1);
return EXIT_FAILURE;
}
}
}
if (check_pidfile() != 0) {
eprint("Stalled pid file or daemon allready running, terminating\n");
exit(1);
return EXIT_FAILURE;
}
if (!foreground) {
if (become_daemon() != 0) {
eprint("Couldn't daemonize\n");
exit(1);
return EXIT_FAILURE;
}
}
if (perf_init() != 0) {
eprint("Couldn't initialize perf lib\n");
exit(1);
return EXIT_FAILURE;
}
atexit(perf_close);
if (!perf_ecc_supported())
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
sfd = open_socket(SERVER);
if (sfd < 0) {
eprint("Couldn't initialize server socket\n");
exit(1);
return EXIT_FAILURE;
}
atexit(remove_sock);
@@ -432,17 +484,19 @@ int main(int argc, char *argv[])
if (sigaction(SIGINT, &act, 0) != 0) {
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
errno, strerror(errno));
exit(1);
return EXIT_FAILURE;
}
if (sigaction(SIGTERM, &act, 0) != 0) {
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
errno, strerror(errno));
exit(1);
return EXIT_FAILURE;
}
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
signal(SIGPIPE, SIG_IGN);
eprint("Running\n");
while (1) {
while (!stopsig) {
enum ctr_e ctr;
enum cmd_e cmd;
int s;
@@ -453,7 +507,7 @@ int main(int argc, char *argv[])
continue;
eprint("Accept() failure, errno=%d [%s]\n",
errno, strerror(errno));
exit(1);
return EXIT_FAILURE;
}
rc = recv_query(s, &ctr, &cmd);
@@ -480,5 +534,13 @@ cleanup:
close(s);
}
if (stopsig == SIGTERM)
eprint("Caught signal SIGTERM, terminating...\n");
else if (stopsig == SIGINT)
eprint("Caught signal SIGINT, terminating...\n");
else
eprint("Caught signal %d, terminating...\n", stopsig);
remove_pidfile();
return 0;
}

View File

@@ -3,7 +3,7 @@
*
* low level perf functions
*
* Copyright IBM Corp. 2015, 2020
* Copyright IBM Corp. 2015, 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.
@@ -16,14 +16,21 @@
#include <inttypes.h>
#include <limits.h>
#include <linux/perf_event.h>
#include <pthread.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <unistd.h>
#include <libudev.h>
#include "cpacfstats.h"
#include "../include/lib/zt_common.h"
/* correlation between counter and perf counter string */
static const struct {
@@ -38,25 +45,83 @@ static const struct {
{"cpum_cf", "ECC_FUNCTION_COUNT", ECC_FUNCTIONS}
};
/*
* We need one filedescriptor per CPU per counter.
* So perf_init builds this:
*
* ctr_fds - is an array of pointers to file descriptor arrays.
* Each file descriptor array has space for number of logical CPUs + 1
* filedescriptors (int values). The last element of each file descriptor
* array is always 0, assuming there will never appear a filedescriptor
* with value 0:
*
* ctr_fds:
* ctr_fds[0] -> [file descriptor 0] [fd1] ... [fd cpus-1][0]
* ctr_fds[1] -> [file descriptor 0] [fd1] ... [fd cpus-1][0]
* ...
* ctr_fds[ALL_COUNTER-1] -> [file descriptor 0] [fd1] ... [fd cpus-1][0]
*/
static int *ctr_fds[ALL_COUNTER];
static struct pmf_data {
int pmutype;
int eventid;
} pmf_counter_data[ALL_COUNTER];
static int ecc_supported;
struct percpucounter {
int ctr_fds[ALL_COUNTER];
int pai_user[NUM_PAI_USER];
int pai_kernel[NUM_PAI_KERNEL];
unsigned int cpunum;
struct percpucounter *next;
};
static struct percpucounter *root;
pthread_mutex_t rootmux = PTHREAD_MUTEX_INITIALIZER;
static volatile int hotplugdetected;
static unsigned int enabledcounter;
pthread_t hotplugthread;
#define foreachcpu(PCPU) if (pthread_mutex_lock(&rootmux)) return -1; \
for ((PCPU) = root; (PCPU) != NULL; (PCPU) = (PCPU)->next)
#define endforeachcpu() pthread_mutex_unlock(&rootmux)
static int ctr_state[NUM_COUNTER];
static volatile int stoprequested;
static int paipmutype, paipmueventstart;
static struct percpucounter *allocpercpucounter(unsigned int cpunum)
{
struct percpucounter *ppc;
ppc = malloc(sizeof(struct percpucounter));
if (ppc) {
int i;
for (i = 0; i < ALL_COUNTER; ++i)
ppc->ctr_fds[i] = -1;
for (i = 0; i < NUM_PAI_USER; ++i)
ppc->pai_user[i] = -1;
for (i = 0; i < NUM_PAI_KERNEL; ++i)
ppc->pai_kernel[i] = -1;
ppc->cpunum = cpunum;
ppc->next = NULL;
}
return ppc;
}
static void freepercpucounter(struct percpucounter *pcpu)
{
int i;
for (i = 0; i < ALL_COUNTER; ++i)
(void)close(pcpu->ctr_fds[i]);
for (i = 0; i < NUM_PAI_USER; ++i)
(void)close(pcpu->pai_user[i]);
for (i = 0; i < NUM_PAI_KERNEL; ++i)
(void)close(pcpu->pai_kernel[i]);
free(pcpu);
}
static struct percpucounter *findcpu(unsigned int cpunum, int unlinkflag)
{
struct percpucounter **prev = &root, *walk = root;
while (walk) {
if (walk->cpunum == cpunum) {
if (unlinkflag)
*prev = walk->next;
return walk;
}
prev = &(walk->next);
walk = walk->next;
}
return NULL;
}
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
@@ -85,12 +150,43 @@ static int perf_counter_supported(const char *pmu, const char *counter)
return !access(buf, R_OK);
}
static int perf_event_encode(struct perf_event_attr *attr,
static int cpumf_authorized(void)
{
unsigned vermin, vermax, auth;
int res = 0, found = 0;
size_t linesize = 0;
char *line = NULL;
FILE *f;
f = fopen("/proc/service_levels", "r");
if (f == NULL) {
eprint("Failed to open /proc/service_levels (%d:%s)\n",
errno, strerror(errno));
return 0;
}
while (getline(&line, &linesize, f) >= 0) {
if (sscanf(line,
"CPU-MF: Counter facility: version=%d.%d authorization=%x",
&vermin, &vermax, &auth) == 3) {
if (auth & 0x8)
res = 1;
else
eprint("CPU-MF counters not authorized.\n");
found = 1;
break;
}
}
if (!found)
eprint("CPU-MF counters not available.\n");
free(line);
fclose(f);
return res;
}
static int perf_event_encode(int *pmutype, int *eventid,
const char *pmu, const char *event)
{
FILE *f;
int eventid;
int pmutype;
char buf[PATH_MAX];
if (snprintf(buf, PATH_MAX, "/sys/bus/event_source/devices/%s/events/%s",
@@ -104,7 +200,7 @@ static int perf_event_encode(struct perf_event_attr *attr,
errno, strerror(errno));
return -1;
}
if (fscanf(f, "event=0x%x\n", &eventid) != 1) {
if (fscanf(f, "event=0x%x\n", eventid) != 1) {
fclose(f);
eprint("Event file %s has invalid format\n", buf);
return -1;
@@ -121,21 +217,257 @@ static int perf_event_encode(struct perf_event_attr *attr,
errno, strerror(errno));
return -1;
}
if (fscanf(f, "%d\n", &pmutype) != 1) {
if (fscanf(f, "%d\n", pmutype) != 1) {
fclose(f);
eprint("Type file %s has invalid format\n", buf);
return -1;
}
attr->type = pmutype;
attr->config = eventid;
return 0;
}
static int activatecpu(unsigned int cpu)
{
struct perf_event_attr pfm_event;
struct percpucounter *ppc;
int fd, i, rc = 0;
ppc = allocpercpucounter(cpu);
if (ppc == NULL) {
eprint("Failed to allocate per cpu counter data");
return -1;
}
if (pthread_mutex_lock(&rootmux)) {
freepercpucounter(ppc);
return -1;
}
/* activate CPU-MF */
for (i = 0; i < ALL_COUNTER; ++i) {
if (ctr_state[i] == UNSUPPORTED)
continue;
memset(&pfm_event, 0, sizeof(pfm_event));
pfm_event.size = sizeof(pfm_event);
pfm_event.type = pmf_counter_data[i].pmutype;
pfm_event.config = pmf_counter_data[i].eventid;
/* fetch file descriptor for this perf event
* the counter event should start disabled
*/
pfm_event.disabled = ctr_state[i] == DISABLED;
fd = perf_event_open(
&pfm_event,
-1, /* pid -1 means all processes */
cpu,
-1, /* group filedescriptor */
0); /* flags */
if (fd < 0) {
eprint("Perf_event_open() failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
ctr_state[i] = UNSUPPORTED;
} else {
ppc->ctr_fds[i] = fd;
}
}
/* activate pai_user and pai_kernel */
/* invariant:
(ctr_state[PAI_USER] == UNSUPPORTED) ==
(ctr_state[PAI_KERNEL] == UNSUPPORTED) */
if (ctr_state[PAI_USER] != UNSUPPORTED) {
for (i = 1; i <= NUM_PAI_USER; ++i) {
memset(&pfm_event, 0, sizeof(pfm_event));
pfm_event.size = sizeof(pfm_event);
pfm_event.type = paipmutype;
pfm_event.config = paipmueventstart + i;
pfm_event.exclude_kernel = 1;
pfm_event.exclude_user = 0;
pfm_event.disabled = ctr_state[PAI_USER] == DISABLED;
fd = perf_event_open(&pfm_event, -1, cpu, -1, 0);
if (fd < 0) {
eprint("Perf_event_open() failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
ctr_state[PAI_USER] = UNSUPPORTED;
ctr_state[PAI_KERNEL] = UNSUPPORTED;
goto outevents;
} else {
ppc->pai_user[i - 1] = fd;
}
pfm_event.exclude_kernel = 0;
pfm_event.exclude_user = 1;
pfm_event.disabled = ctr_state[PAI_KERNEL] == DISABLED;
fd = perf_event_open(&pfm_event, -1, cpu, -1, 0);
if (fd < 0) {
eprint("Perf_event_open() failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
ctr_state[PAI_USER] = UNSUPPORTED;
ctr_state[PAI_KERNEL] = UNSUPPORTED;
goto outevents;
} else {
ppc->pai_kernel[i - 1] = fd;
}
}
for (; i <= NUM_PAI_KERNEL; ++i) {
memset(&pfm_event, 0, sizeof(pfm_event));
pfm_event.size = sizeof(pfm_event);
pfm_event.type = paipmutype;
pfm_event.config = paipmueventstart + i;
pfm_event.exclude_kernel = 0;
pfm_event.exclude_user = 1;
pfm_event.disabled = ctr_state[PAI_KERNEL] == DISABLED;
fd = perf_event_open(&pfm_event, -1, cpu, -1, 0);
if (fd < 0) {
eprint("Perf_event_open() failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
ctr_state[PAI_USER] = UNSUPPORTED;
ctr_state[PAI_KERNEL] = UNSUPPORTED;
goto outevents;
} else {
ppc->pai_kernel[i - 1] = fd;
}
}
}
outevents:
ppc->next = root;
root = ppc;
if (enabledcounter)
hotplugdetected = 1;
pthread_mutex_unlock(&rootmux);
return rc;
}
static void deactivatecpu(unsigned int cpunum)
{
struct percpucounter *pcpu;
int i;
if (pthread_mutex_lock(&rootmux))
return;
pcpu = findcpu(cpunum, 1);
if (pcpu != NULL) {
for (i = 0; i < ALL_COUNTER; ++i)
(void)close(pcpu->ctr_fds[i]);
for (i = 0; i < NUM_PAI_USER; ++i)
(void)close(pcpu->pai_user[i]);
for (i = 0; i < NUM_PAI_KERNEL; ++i)
(void)close(pcpu->pai_kernel[i]);
free(pcpu);
if (enabledcounter)
hotplugdetected = 1;
}
pthread_mutex_unlock(&rootmux);
}
static int addallcpus(void)
{
unsigned int start, end;
int scanned, rc = 0;
FILE *fp;
/* comma separated list of intervals */
if ((fp = fopen("/sys/devices/system/cpu/online", "r")) == NULL) {
eprint("Failed to get online cpus (%d:%s)\n",
errno, strerror(errno));
return -1;
}
while (!feof(fp)) {
/* scan all intervals of online cpus */
scanned = fscanf(fp, "%u-%u", &start, &end);
/* take care of singleton intervals */
if (scanned == 1)
end = start;
for (; start <= end; ++start) {
if (activatecpu(start)) {
rc = -1;
goto out;
}
}
/* Skip comma separator */
(void)fgetc(fp);
}
out:
fclose(fp);
return rc;
}
static int perf_load_counter_data(void)
{
int i, res = 0;
for (i = 0; i < ALL_COUNTER; ++i) {
if (ctr_state[i] != UNSUPPORTED)
res |= perf_event_encode(&pmf_counter_data[i].pmutype,
&pmf_counter_data[i].eventid,
pmf_counter_name[i].pmu,
pmf_counter_name[i].pfm_name);
}
if (ctr_state[PAI_USER] != UNSUPPORTED)
res |= perf_event_encode(&paipmutype, &paipmueventstart,
"pai_crypto", "CRYPTO_ALL");
return res;
}
static void *hotplughandler(void *UNUSED(unused))
{
struct udev *hotplug;
struct udev_monitor *monitor;
struct pollfd item;
hotplug = udev_new();
if (!hotplug) {
eprint("Failed to create hotplug device\n");
return NULL;
}
monitor = udev_monitor_new_from_netlink(hotplug, "udev");
udev_monitor_filter_add_match_subsystem_devtype(monitor, "cpu", NULL);
udev_monitor_enable_receiving(monitor);
item.fd = udev_monitor_get_fd(monitor);
item.events = POLLIN;
item.revents = 0;
while (!stoprequested) {
struct udev_device *dev;
const char *path, *action;
unsigned int cpunum;
int rc, on, off;
errno = 0;
rc = poll(&item, 1, -1);
if (rc == -1) {
if (errno == EINTR)
continue;
break;
}
dev = udev_monitor_receive_device(monitor);
if (dev == NULL)
continue;
action = udev_device_get_action(dev);
if (action == NULL)
continue;
off = strcmp(action, "offline") == 0;
on = strcmp(action, "online") == 0;
if (!on && !off)
continue;
path = udev_device_get_devpath(dev);
if (sscanf(path, "/devices/system/cpu/cpu%u", &cpunum) != 1)
continue;
if (on && activatecpu(cpunum))
eprint("Failed to attach to hotplugged CPU %u\n", cpunum);
if (off)
deactivatecpu(cpunum);
}
udev_monitor_unref(monitor);
udev_unref(hotplug);
return NULL;
}
int perf_init(void)
{
int i, cpus, ctr, cpu, *fds;
memset(ctr_fds, 0, sizeof(ctr_fds));
int ecc_supported, i, num;
unsigned long maxfd;
struct rlimit rlim;
FILE *f;
/* initialize performance monitoring library */
if (!perf_supported()) {
@@ -143,99 +475,105 @@ int perf_init(void)
return -1;
}
/* We currently support all cpumf counters plus two virtual
* counters for PAI. */
num = ALL_COUNTER + 2;
/* Check if ECC is supported on current hardware */
ecc_supported = perf_counter_supported("cpum_cf", "ECC_FUNCTION_COUNT");
/* get number of logical processors */
cpus = sysconf(_SC_NPROCESSORS_ONLN);
/* for each counter */
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
/* Skip ECC counters completely if unsupported */
if (ctr == ECC_FUNCTIONS && !ecc_supported)
continue;
/*
* allocate an array of ints to store for each CPU
* one filedescriptor + a terminating 0
*/
fds = (int *) calloc(sizeof(int), cpus+1);
if (!fds) {
eprint("Malloc() of %d byte failed, errno=%d [%s]\n",
(int)(sizeof(int) * (cpus+1)),
errno, strerror(errno));
return -1;
}
ctr_fds[ctr] = fds;
/* search for the counter's corresponding pfm name */
for (i = ALL_COUNTER-1; i >= 0; i--)
if ((int) pmf_counter_name[i].ctr == ctr)
break;
if (i < 0) {
eprint("Pfm ctr name not found for counter %d, please adjust pmf_counter_name[] in %s\n",
ctr, __FILE__);
return -1;
}
for (cpu = 0; cpu < cpus; cpu++) {
struct perf_event_attr pfm_event;
int fd;
memset(&pfm_event, 0, sizeof(pfm_event));
pfm_event.size = sizeof(pfm_event);
if (perf_event_encode(&pfm_event,
pmf_counter_name[i].pmu,
pmf_counter_name[i].pfm_name)) {
eprint("Failed to initialize counter %s for pmu %s\n",
pmf_counter_name[i].pfm_name,
pmf_counter_name[i].pmu);
return -1;
}
/* fetch file descriptor for this perf event
* the counter event should start disabled
*/
pfm_event.disabled = 1;
fd = perf_event_open(
&pfm_event,
-1, /* pid -1 means all processes */
cpu,
-1, /* group filedescriptor */
0); /* flags */
if (fd < 0) {
eprint("Perf_event_open() failed with errno=%d [%s]\n",
errno, strerror(errno));
return -1;
}
fds[cpu] = fd;
}
if (!cpumf_authorized()) {
for (i = 0; i < ALL_COUNTER; ++i)
ctr_state[i] = UNSUPPORTED;
num -= ALL_COUNTER;
} else if (!ecc_supported) {
ctr_state[ECC_FUNCTIONS] = UNSUPPORTED;
--num;
}
return 0;
if (!perf_counter_supported("pai_crypto", "CRYPTO_ALL")) {
ctr_state[PAI_USER] = UNSUPPORTED;
ctr_state[PAI_KERNEL] = UNSUPPORTED;
num -= 2;
}
if (num == 0) {
eprint("No crypto counters supported!\n");
return -1;
}
if (perf_load_counter_data())
return -1;
/* We have to adjust the number of FDs possible since we might
* need more than 1024 (the typical soft limit) */
f = fopen("/proc/sys/fs/nr_open", "r");
if (f == NULL) {
eprint("fopen failed for /proc/sys/fs/nr_open with errno=%d [%s]\n",
errno, strerror(errno));
return -1;
}
if (fscanf(f, "%lu", &maxfd) != 1) {
fclose(f);
eprint("Failed to parse /proc/sys/fs/nr_open\n");
return -1;
}
fclose(f);
rlim.rlim_cur = maxfd;
rlim.rlim_max = maxfd;
if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
eprint("setrlimit failed with errno=%d [%s]\n",
errno, strerror(errno));
return -1;
}
if (pthread_create(&hotplugthread, NULL, hotplughandler, NULL)) {
eprint("Failed to start hotplug handler thread\n");
return -1;
}
return addallcpus();
}
void perf_stop(void)
{
stoprequested = 1;
}
void perf_close(void)
{
int ctr, *fds;
struct percpucounter *walk, *next;
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
close(*fds);
*fds = 0;
}
free(ctr_fds[ctr]);
ctr_fds[ctr] = NULL;
pthread_kill(hotplugthread, SIGINT);
pthread_join(hotplugthread, NULL);
walk = root;
while (walk) {
next = walk->next;
freepercpucounter(walk);
walk = next;
}
}
static int enable_array(int *arr, int size)
{
int i, ec, rc = 0;
for (i = 0; i < size; ++i) {
ec = ioctl(arr[i], PERF_EVENT_IOC_ENABLE, 0);
if (ec < 0) {
eprint("Ioctl(PERF_EVENT_IOC_ENABLE) failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
}
}
return rc;
}
int perf_enable_ctr(enum ctr_e ctr)
{
int *fds, ec, rc = 0;
struct percpucounter *pcpu;
int ec, rc = 0;
if (ctr == ALL_COUNTER) {
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
@@ -243,24 +581,64 @@ int perf_enable_ctr(enum ctr_e ctr)
if (rc != 0)
return rc;
}
} else {
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
ec = ioctl(*fds, PERF_EVENT_IOC_ENABLE, 0);
} else if (ctr < ALL_COUNTER) {
foreachcpu(pcpu) {
ec = ioctl(pcpu->ctr_fds[ctr], PERF_EVENT_IOC_ENABLE, 0);
if (ec < 0) {
eprint("Ioctl(PERF_EVENT_IOC_ENABLE) failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
}
}
ctr_state[ctr] = ENABLED;
++enabledcounter;
endforeachcpu();
} else if (ctr == PAI_USER) {
foreachcpu(pcpu) {
ec = enable_array(pcpu->pai_user, NUM_PAI_USER);
if (ec < 0)
rc = -1;
}
ctr_state[ctr] = ENABLED;
++enabledcounter;
endforeachcpu();
} else if (ctr == PAI_KERNEL) {
foreachcpu(pcpu) {
ec = enable_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
if (ec < 0)
rc = -1;
}
ctr_state[ctr] = ENABLED;
++enabledcounter;
endforeachcpu();
} else {
rc = -1;
}
return rc;
}
static int disable_array(int *arr, int size)
{
int i, ec, rc = 0;
for (i = 0; i < size; ++i) {
ec = ioctl(arr[i], PERF_EVENT_IOC_DISABLE, 0);
if (ec < 0) {
eprint("Ioctl(PERF_EVENT_IOC_DISABLE) failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
}
}
return rc;
}
int perf_disable_ctr(enum ctr_e ctr)
{
int *fds, ec, rc = 0;
struct percpucounter *pcpu;
int ec, rc = 0;
if (ctr == ALL_COUNTER) {
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
@@ -268,70 +646,183 @@ int perf_disable_ctr(enum ctr_e ctr)
if (rc != 0)
return rc;
}
} else {
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
ec = ioctl(*fds, PERF_EVENT_IOC_DISABLE, 0);
} else if (ctr < ALL_COUNTER) {
foreachcpu(pcpu) {
ec = ioctl(pcpu->ctr_fds[ctr], PERF_EVENT_IOC_DISABLE, 0);
if (ec < 0) {
eprint("Ioctl(PERF_EVENT_IOC_DISABLE) failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
}
}
ctr_state[ctr] = DISABLED;
--enabledcounter;
if (enabledcounter == 0)
hotplugdetected = 0;
endforeachcpu();
} else if (ctr == PAI_USER) {
foreachcpu(pcpu) {
ec = disable_array(pcpu->pai_user, NUM_PAI_USER);
if (ec < 0)
rc = -1;
}
ctr_state[ctr] = DISABLED;
--enabledcounter;
if (enabledcounter == 0)
hotplugdetected = 0;
endforeachcpu();
} else if (ctr == PAI_KERNEL) {
foreachcpu(pcpu) {
ec = disable_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
if (ec < 0)
rc = -1;
}
ctr_state[ctr] = DISABLED;
--enabledcounter;
if (enabledcounter == 0)
hotplugdetected = 0;
endforeachcpu();
} else {
rc = -1;
}
return rc;
}
int perf_reset_ctr(enum ctr_e ctr)
static int reset_array(int *arr, int size)
{
int *fds, ec, rc = 0;
int ec, rc = 0, i;
for (i = 0; i < size; ++i) {
ec = ioctl(arr[i], PERF_EVENT_IOC_RESET, 0);
if (ec < 0) {
eprint("Ioctl(PERF_EVENT_IOC_RESET) failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
}
}
return rc;
}
int perf_reset_ctr(enum ctr_e ctr, uint64_t *value)
{
struct percpucounter *pcpu;
int ec, rc = 0;
if (ctr == ALL_COUNTER) {
for (ctr = 0; ctr < ALL_COUNTER; ctr++) {
rc = perf_reset_ctr(ctr);
rc = perf_reset_ctr(ctr, value);
if (rc != 0)
return rc;
}
} else {
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
ec = ioctl(*fds, PERF_EVENT_IOC_RESET, 0);
} else if (ctr < ALL_COUNTER) {
foreachcpu(pcpu) {
ec = ioctl(pcpu->ctr_fds[ctr], PERF_EVENT_IOC_RESET, 0);
if (ec < 0) {
eprint("Ioctl(PERF_EVENT_IOC_RESET) failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
}
}
endforeachcpu();
} else if (ctr == PAI_USER) {
foreachcpu(pcpu) {
ec = reset_array(pcpu->pai_user, NUM_PAI_USER);
if (ec < 0)
rc = -1;
}
endforeachcpu();
} else if (ctr == PAI_KERNEL) {
foreachcpu(pcpu) {
ec = reset_array(pcpu->pai_kernel, NUM_PAI_KERNEL);
if (ec < 0)
rc = -1;
}
endforeachcpu();
} else {
rc = -1;
}
if (rc == 0)
rc = perf_read_ctr(ctr, value);
return rc;
}
int perf_read_ctr(enum ctr_e ctr, uint64_t *value)
{
int *fds, ec, rc = -1;
struct percpucounter *pcpu;
int ec, rc = 0;
uint64_t val;
if (!value)
return -1;
if (ctr == HOTPLUG_DETECTED) {
*value = hotplugdetected;
return 0;
}
if (ctr == PAI_USER) {
*value = NUM_PAI_USER;
return 0;
}
if (ctr == PAI_KERNEL) {
*value = NUM_PAI_KERNEL;
return 0;
}
if (ctr >= ALL_COUNTER)
return -1;
*value = 0;
for (fds = ctr_fds[ctr]; fds && *fds; fds++) {
ec = read(*fds, &val, sizeof(val));
foreachcpu(pcpu) {
ec = read(pcpu->ctr_fds[ctr], &val, sizeof(val));
if (ec != sizeof(val)) {
eprint("Read() on perf file descriptor failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
} else {
*value += val;
rc = 0;
}
}
endforeachcpu();
return rc;
}
int perf_ecc_supported(void)
{
return ecc_supported;
return ctr_state[ECC_FUNCTIONS] != UNSUPPORTED;
}
int perf_ctr_state(enum ctr_e ctr) {
if (ctr < NUM_COUNTER)
return ctr_state[ctr];
return UNSUPPORTED;
}
int perf_read_pai_ctr(unsigned int ctrnum, int user, uint64_t *value)
{
struct percpucounter *pcpu;
unsigned int maxctr;
int *arr, ec, rc = 0;
uint64_t val;
*value = 0;
maxctr = user ? NUM_PAI_USER : NUM_PAI_KERNEL;
if (ctrnum >= maxctr)
return -1;
foreachcpu(pcpu) {
arr = user ? pcpu->pai_user : pcpu->pai_kernel;
ec = read(arr[ctrnum], &val, sizeof(val));
if (ec != sizeof(val)) {
eprint("Read() on perf file descriptor failed with errno=%d [%s]\n",
errno, strerror(errno));
rc = -1;
} else {
*value += val;
}
}
endforeachcpu();
return rc;
}

View File

@@ -3,7 +3,7 @@
*
* basic socket and receive/send functions
*
* Copyright IBM Corp. 2015, 2017
* Copyright IBM Corp. 2015, 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.
@@ -13,6 +13,7 @@
#include <endian.h>
#include <errno.h>
#include <grp.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -148,7 +149,51 @@ static int __read(int fd, void *buf, int buflen)
}
int send_msg(int sfd, struct msg *m)
static int __timedwrite(int fd, const void *buf, int buflen, int timeout)
{
struct pollfd pfd = { .fd = fd, .events = POLLOUT };
int i = 0, n;
while (poll(&pfd, 1, timeout) == 1) {
n = write(fd, buf + i, buflen - i);
if (n < 0) {
if (errno == EINTR)
continue;
else
return n;
} else if (n == 0) {
return i;
}
i += n;
if (buflen == i)
return i;
}
return -1;
}
static int __timedread(int fd, void *buf, int buflen, int timeout)
{
struct pollfd pfd = { .fd = fd, .events = POLLIN };
int i = 0, n;
while (poll(&pfd, 1, timeout) == 1) {
n = read(fd, buf + i, buflen - i);
if (n < 0) {
if (errno == EINTR)
continue;
else
return n;
} else if (n == 0) {
return i;
}
i += n;
if (buflen == i)
return i;
}
return -1;
}
int send_msg(int sfd, struct msg *m, int timeout)
{
int n, len;
@@ -166,7 +211,7 @@ int send_msg(int sfd, struct msg *m)
return -1;
}
n = __write(sfd, m, len);
n = timeout ? __timedwrite(sfd, m, len, timeout) : __write(sfd, m, len);
if (n != len) {
eprint("Write() error: write()=%d expected %d, errno=%d [%s]\n",
n, len, errno, strerror(errno));
@@ -176,12 +221,12 @@ int send_msg(int sfd, struct msg *m)
return 0;
}
int recv_msg(int sfd, struct msg *m)
int recv_msg(int sfd, struct msg *m, int timeout)
{
int n, len;
len = sizeof(m->head);
n = __read(sfd, m, len);
n = timeout ? __timedread(sfd, m, len, timeout) : __read(sfd, m, len);
if (n != len) {
eprint("Recv() error: read()=%d expected %d, errno=%d [%s]\n",
n, len, errno, strerror(errno));
@@ -200,7 +245,8 @@ int recv_msg(int sfd, struct msg *m)
return -1;
}
n = __read(sfd, ((char *)m) + sizeof(m->head), len);
n = timeout ? __timedread(sfd, ((char *)m) + sizeof(m->head), len, timeout) :
__read(sfd, ((char *)m) + sizeof(m->head), len);
if (n != len) {
eprint("Recv() error: recv()=%d expected %d, errno=%d [%s]\n",
n, len, errno, strerror(errno));

View File

@@ -1,14 +1,16 @@
include ../common.mak
BIN_FILES = lscpumf chcpumf
MAN_FILES = lscpumf.1 chcpumf.8
BIN_FILES = lscpumf chcpumf lshwc pai
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8
all: $(BIN_FILES)
libs = $(rootdir)/libutil/libutil.a
libs = $(rootdir)/libcpumf/libcpumf.a $(rootdir)/libutil/libutil.a
lscpumf: lscpumf.o $(libs)
chcpumf: chcpumf.o $(libs)
lshwc: lshwc.o $(libs)
pai: pai.o $(libs)
install: all install-man
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
@@ -21,8 +23,8 @@ clean:
install-man:
for man in $(MAN_FILES); do \
msection=`echo $$man |sed 's/.*\.\([1-9]\)$$/man\1/'` ; \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 -D man/$$man $(DESTDIR)$(MANDIR)/$$msection/$$man ; \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 man/$$man \
$(DESTDIR)$(MANDIR)/man8 ; \
done
.PHONY: all install clean

View File

@@ -1,7 +1,7 @@
/*
* chcpumf - Change CPU Measurement Facility Characteristics
*
* Copyright IBM Corp. 2020
* Copyright IBM Corp. 2020, 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.
@@ -20,9 +20,9 @@
#include "lib/util_prg.h"
#include "lib/util_base.h"
#include "defines.h"
#include "lib/libcpumf.h"
static int verbose;
static unsigned int verbose;
static unsigned long min_sdb, max_sdb;
static struct util_opt opt_vec[] = {
@@ -85,57 +85,31 @@ static long parse_buffersize(char *string)
return bytes;
}
static int read_sfb(unsigned long *min, unsigned long *max)
{
unsigned long cur_min_sdb, cur_max_sdb;
int rc = EXIT_SUCCESS;
FILE *fp;
fp = fopen(PERF_SFB_SIZE, "r");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
rc = EXIT_FAILURE;
} else {
if (*min == 0)
*min = cur_min_sdb;
if (*max == 0)
*max = cur_max_sdb;
}
fclose(fp);
return rc;
}
static int write_sfb(unsigned long min, unsigned long max)
static int write_sfb(unsigned int min, unsigned int max)
{
int rc = EXIT_SUCCESS;
char text[64];
size_t len;
FILE *fp;
fp = fopen(PERF_SFB_SIZE, "w");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
snprintf(text, sizeof text, "%ld,%ld", min, max);
fp = fopen(S390_CPUMSF_BUFFERSZ, "w");
if (!fp)
err(EXIT_FAILURE, S390_CPUMSF_BUFFERSZ);
snprintf(text, sizeof(text), "%u,%u", min, max);
len = strlen(text) + 1;
if (fwrite(text, 1, len, fp) != len) {
linux_error(PERF_SFB_SIZE);
warn(S390_CPUMSF_BUFFERSZ);
rc = EXIT_FAILURE;
}
if (fclose(fp)) {
linux_error(PERF_SFB_SIZE);
warn(S390_CPUMSF_BUFFERSZ);
rc = EXIT_FAILURE;
}
if (verbose && rc != EXIT_FAILURE)
fprintf(stderr, "Sampling buffer sizes:\n"
" Minimum:%7ld sample-data-blocks\n"
" Maximum:%7ld sample-data-blocks\n",
min, max);
warnx("Sampling buffer sizes:\n"
" Minimum:%7d sample-data-blocks\n"
" Maximum:%7d sample-data-blocks\n",
min, max);
return rc;
}
@@ -155,61 +129,50 @@ static int parse_args(int argc, char **argv)
exit(EXIT_SUCCESS);
case 'x':
new = parse_buffersize(optarg);
if (new < 1) {
fprintf(stderr, "The specified number(s)"
" are not valid\n");
exit(EXIT_FAILURE);
}
if (new < 1)
errx(EXIT_FAILURE,
"The specified number(s) are not valid");
max_sdb = new;
action = 1;
break;
case 'm':
new = parse_buffersize(optarg);
if (new < 1) {
fprintf(stderr, "The specified number(s)"
" are not valid\n");
exit(EXIT_FAILURE);
}
if (new < 1)
errx(EXIT_FAILURE,
"The specified number(s) are not valid");
min_sdb = new;
action = 1;
break;
case 'V':
verbose = 1;
break;
case '?':
fprintf(stderr, "One or more options are not valid\n");
fprintf(stderr, "Try 'chcpumf --help' for more"
" information\n");
default:
util_opt_print_parse_error(opt, argv);
exit(EXIT_FAILURE);
}
}
if (!action) {
fprintf(stderr, "You must specify a valid option\n");
exit(EXIT_FAILURE);
}
if (!action)
errx(EXIT_FAILURE, "You must specify a valid option");
return action;
}
int main(int argc, char **argv)
{
int ret = EXIT_FAILURE;
struct stat sbuf;
unsigned long my_min, my_max;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
parse_args(argc, argv);
if (stat(PERF_PATH PERF_SF, &sbuf) != 0) {
fprintf(stderr,
"No CPU-measurement sampling facility detected\n");
return ret;
}
if (read_sfb(&min_sdb, &max_sdb))
return ret;
if (min_sdb >= max_sdb) {
fprintf(stderr, "The specified maximum must be greater "
"than the minimum\n");
return ret;
}
if (geteuid())
errx(EXIT_FAILURE, "Must run as root");
if (!libcpumf_have_sfb())
errx(EXIT_FAILURE,
"No CPU-measurement sampling facility detected");
libcpumf_sfb_info(&my_min, &my_max);
if (!min_sdb)
min_sdb = my_min;
if (!max_sdb)
max_sdb = my_max;
return write_sfb(min_sdb, max_sdb);
}

View File

@@ -1,23 +0,0 @@
/*
* Defines for CPU Measurement Facility Characteristics
*
* Copyright IBM Corp. 2020
*
* 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 DEFINES_H
#define DEFINES_H
#define PERF_SFB_SIZE "/sys/module/kernel/parameters/cpum_sfb_size"
#define PERF_PATH "/sys/bus/event_source/devices/"
#define PERF_SF "cpum_sf"
#define PERF_CF "cpum_cf"
static inline void linux_error(const char *message)
{
fprintf(stderr, "Error: %s: %s\n", message, strerror(errno));
}
#endif

File diff suppressed because it is too large Load Diff

703
cpumf/lshwc.c Normal file
View File

@@ -0,0 +1,703 @@
/* Copyright IBM Corp. 2021
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
/* CPU Measurements counter facility counter sets can be extracted by a
* device driver accessible by opening device /dev/hwctr.
* This program extracts complete counter set using this device.
* Counter sets are per CPU, the interface allows to specify counter sets
* for individual CPUs. The supported flags are executed from left to
* right, the first error encountered stops the execution of the program.
*/
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <linux/limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/user.h>
#include <time.h>
#include <unistd.h>
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/util_base.h"
#include "lib/util_path.h"
#include "lib/util_scandir.h"
#include "lib/util_libc.h"
#include "lib/util_file.h"
#include "lib/libcpumf.h"
#include "lshwc.h"
#define CPUS_ONLINE "/sys/devices/system/cpu/online"
#define CPUS_POSSIBLE "/sys/devices/system/cpu/possible"
#define CPUS_KERNELMAX "/sys/devices/system/cpu/kernel_max"
#define MAXCTRS 512
#define IOCTLSLEEP 60U
static unsigned int read_interval = IOCTLSLEEP;
static int cfvn, csvn, authorization;
static unsigned long loop_count = 1;
static unsigned char *ioctlbuffer;
static bool allcpu;
static unsigned int max_possible_cpus; /* No of possible CPUs */
static struct ctrname { /* List of defined counters */
char *name; /* Counter name */
bool hitcnt; /* Counter number read from ioctl() */
unsigned long total; /* Total counter value */
unsigned long *ccv; /* Per CPU counter value */
} ctrname[MAXCTRS];
static bool read_counternames(void)
{
struct dirent **namelist = NULL;
int i, ctr = 0, count = 0;
char *path, *ctrpath;
path = util_path_sysfs("/bus/event_source/devices/cpum_cf/events/");
count = util_scandir(&namelist, alphasort, path, "[^.]");
if (count <= 0) {
warnx("Cannot open %s", path);
free(path);
return false;
}
for (i = 0; i < count && ctr >= 0; i++) {
util_asprintf(&ctrpath, "%s/%s", path, namelist[i]->d_name);
if (util_file_read_va(ctrpath, "event=%x", &ctr) == 1)
ctrname[ctr].name = util_strdup(namelist[i]->d_name);
else
warnx("Cannot parse %s", ctrpath);
free(ctrpath);
}
util_scandir_free(namelist, count);
free(path);
return ctr < 0 ? false : true;
}
static void free_counternames(void)
{
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
free(ctrname[i].name);
free(ctrname[i].ccv);
}
}
static struct check_result {
bool cpu_pos; /* CPU Number possible */
bool cpu_req; /* CPU Number requested */
bool cpu_hit; /* CPU Number received */
unsigned char sets_req; /* Counters sets requested */
unsigned char sets_hit; /* Counters sets received */
} *check;
static bool check_set(unsigned long a, unsigned long b, unsigned long sets)
{
if (a > b)
return false;
for (; a <= b; ++a) {
if (a >= max_possible_cpus || !check[a].cpu_pos)
return false;
check[a].cpu_req = true;
check[a].sets_req = sets;
}
return true;
}
/*
* Functions to parse command line parameters
* Convert a number from ascii to int.
*/
static unsigned long getnumber(char *word, char stopchar)
{
unsigned long no;
char *endp;
no = strtoul(word, &endp, 0);
if (*endp != stopchar)
errx(EXIT_FAILURE, "Invalid parameter %s", word);
return no;
}
/* Read file to get all online CPUs */
static bool get_cpus(char *file, char *buf, size_t bufsz)
{
char fmt[16];
FILE *slp;
int rc;
slp = fopen(file, "r");
if (!slp) {
warnx("Cannot open %s", file);
return false;
}
snprintf(fmt, sizeof(fmt), "%%%zus", bufsz - 1);
rc = fscanf(slp, fmt, buf);
fclose(slp);
if (rc != 1)
warnx("Cannot parse %s", file);
return rc == 1 ? true : false;
}
/* Parse counter set specification */
static unsigned long parse_ctrset(char *cp)
{
unsigned long x = 0;
for (; *cp; ++cp) {
switch (tolower(*cp)) {
case 'b':
x |= S390_HWCTR_BASIC;
break;
case 'c':
x |= S390_HWCTR_CRYPTO;
break;
case 'e':
x |= S390_HWCTR_EXT;
break;
case 'm':
x |= S390_HWCTR_MT_DIAG;
break;
case 'p':
case 'u':
x |= S390_HWCTR_USER;
break;
case 'a':
x |= S390_HWCTR_ALL;
break;
default:
errx(EXIT_FAILURE,
"Invalid counter set specification '%c'", *cp);
}
}
return x;
}
static char *show_ctrset(unsigned long set)
{
static char text[16];
int i = 0;
if (set & S390_HWCTR_BASIC)
text[i++] = 'B';
if (set & S390_HWCTR_CRYPTO)
text[i++] = 'C';
if (set & S390_HWCTR_EXT)
text[i++] = 'E';
if (set & S390_HWCTR_MT_DIAG)
text[i++] = 'M';
if (set & S390_HWCTR_USER)
text[i++] = 'U';
text[i] = '\0';
return text;
}
/* Parse CPU list and counter sets */
static void parse_cpulist(char *parm, struct s390_hwctr_start *start)
{
uint64_t *words = start->cpumask;
unsigned int i, no_a, no_b;
cpu_set_t cpulist;
int rc;
CPU_ZERO(&cpulist);
start->data_bytes = 0;
start->counter_sets = S390_HWCTR_ALL; /* Default all counter sets */
if (parm) { /* CPU list with optional counter set */
char *cp = strchr(parm, ':');
if (cp) { /* Handle counter set */
*cp = '\0';
start->counter_sets = parse_ctrset(++cp);
}
if (strlen(parm) > 0) /* Handle CPU list */
rc = libcpumf_cpuset(parm, &cpulist);
else
rc = libcpumf_cpuset_fn(S390_CPUS_ONLINE, &cpulist);
if (rc)
errx(EXIT_FAILURE, "Cannot use CPU list %s", parm);
} else { /* No CPU list and no counter sets */
rc = libcpumf_cpuset_fn(S390_CPUS_ONLINE, &cpulist);
if (rc)
err(EXIT_FAILURE, "Cannot read file " S390_CPUS_ONLINE);
}
/* Check with authorized counter sets */
if ((start->counter_sets & authorization) != start->counter_sets) {
unsigned int noton = ~(start->counter_sets & authorization);
start->counter_sets &= authorization;
if (!start->counter_sets)
errx(EXIT_FAILURE, "No counter sets are authorized");
warnx("One or more counter sets are not authorized: %s",
show_ctrset(noton));
}
for (rc = 0; rc < CPU_SETSIZE; ++rc)
if (CPU_ISSET(rc, &cpulist))
if (!check_set(rc, rc, start->counter_sets))
errx(EXIT_FAILURE, "Invalid CPU %d", rc);
/* Convert the CPU list to a bitmask for kernel cpumask_t */
for (i = 0, no_b = 0; i < max_possible_cpus; ++i) {
if (check[i].cpu_req) {
no_a = i % LONG_BIT;
no_b = i / LONG_BIT;
words[no_b] |= 1ULL << no_a;
}
}
/* no_b is highest used index */
start->cpumask_len = (no_b + 1) * CHAR_BIT;
start->version = S390_HWCTR_START_VERSION;
}
static bool check_setpossible(void)
{
char *cp, *parm, *tokens[16]; /* Used to parse command line params */
unsigned long i, no_a, no_b;
char cpubuf[1024];
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
return false;
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
check = calloc(max_possible_cpus, sizeof(*check));
if (!check)
err(EXIT_FAILURE, "Maximum CPUs %u", max_possible_cpus);
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
free(check);
return false;
}
parm = cpubuf;
for (i = 0; i < ARRAY_SIZE(tokens) && (tokens[i] = strtok(parm, ","));
++i, parm = NULL) {
cp = strchr(tokens[i], '-');
if (cp) { /* Range */
no_a = getnumber(tokens[i], *cp);
no_b = getnumber(++cp, '\0');
} else {
no_b = getnumber(tokens[i], '\0');
no_a = no_b;
}
for (; no_a <= no_b; ++no_a)
check[no_a].cpu_pos = true;
}
return true;
}
static void show_header(void)
{
static bool header;
bool comma = false;
if (header)
return; /* Printed already */
printf("Date,Time,CPU,"); /* Print counter name and number */
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
continue;
if (comma)
putchar(',');
printf("%s(%ld)", ctrname[i].name ?: "Counter", i);
comma = true;
}
putchar('\n');
header = true;
}
static void line(char *header)
{
bool comma;
show_header();
if (allcpu) {
for (unsigned int h = 0; h < max_possible_cpus; ++h) {
char txt[16];
if (!check[h].cpu_hit)
continue;
comma = false;
snprintf(txt, sizeof(txt), "CPU%d,", h);
printf("%s%s", header, txt);
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
continue;
if (comma)
putchar(',');
printf("%ld", ctrname[i].ccv[h]);
comma = true;
}
putchar('\n');
}
}
/* Print total count of all CPUs */
printf("%sTotal,", header);
comma = false;
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
continue;
if (comma)
putchar(',');
printf("%ld", ctrname[i].total);
comma = true;
}
putchar('\n');
}
static void show(void)
{
time_t now = time(NULL);
struct tm *now_tm;
char now_text[32];
now_tm = localtime(&now);
strftime(now_text, sizeof(now_text), "%F,%T,", now_tm);
line(now_text);
}
/* Return Counter set size numbers (in counters) */
static unsigned int ctrset_size(int set)
{
switch (set) {
case S390_HWCTR_BASIC:
return 6;
case S390_HWCTR_USER:
return (cfvn == 1) ? 6 : 2;
case S390_HWCTR_CRYPTO:
return (csvn <= 5) ? 16 : 20;
case S390_HWCTR_EXT:
switch (csvn) {
case 1: return 32;
case 2: return 48;
case 3:
case 4:
case 5: return 128;
}
return 160;
case S390_HWCTR_MT_DIAG:
switch (csvn) {
case 1:
case 2:
case 3: return 0;
}
return 48;
}
return 0;
}
/* Return counter set offset numbers */
static int ctrset_offset(int set)
{
switch (set) {
case S390_HWCTR_BASIC:
return 0;
case S390_HWCTR_USER:
return 32;
case S390_HWCTR_CRYPTO:
return 64;
case S390_HWCTR_EXT:
return 128;
case S390_HWCTR_MT_DIAG:
return 448;
}
return 0;
}
static bool set_and_size_ok(struct s390_hwctr_setdata *p)
{
switch (p->set) {
case S390_HWCTR_BASIC:
case S390_HWCTR_USER:
case S390_HWCTR_CRYPTO:
case S390_HWCTR_EXT:
case S390_HWCTR_MT_DIAG:
return p->no_cnts == ctrset_size(p->set);
}
return false;
}
static bool add_countervalue(size_t idx, unsigned int cpu, unsigned long value)
{
if (idx >= ARRAY_SIZE(ctrname)) {
warnx("Invalid counter number %zu", idx);
return false;
}
if (cpu >= max_possible_cpus) {
warnx("Invalid CPU number %d", cpu);
return false;
}
if (!ctrname[idx].ccv) /* Unknown counter */
ctrname[idx].ccv = calloc(max_possible_cpus,
sizeof(unsigned long));
if (ctrname[idx].ccv)
ctrname[idx].ccv[cpu] += value;
ctrname[idx].total += value;
ctrname[idx].hitcnt = true;
return true;
}
static int test_read(struct s390_hwctr_read *read)
{
void *base = &read->data;
size_t offset = 0;
/* Clear previous hit counters */
for (unsigned int i = 0; i < max_possible_cpus; ++i) {
check[i].sets_hit = 0;
check[i].cpu_hit = false;
}
/* Iterate over all CPUs */
for (unsigned int i = 0; i < read->no_cpus; ++i) {
struct s390_hwctr_cpudata *cp = base + offset;
check[cp->cpu_nr].cpu_hit = true;
check[cp->cpu_nr].sets_hit = 0;
offset += sizeof(cp->cpu_nr) + sizeof(cp->no_sets);
/* Iterate over all counter sets */
for (unsigned int j = 0; j < cp->no_sets; ++j) {
struct s390_hwctr_setdata *sp = base + offset;
check[cp->cpu_nr].sets_hit |= sp->set;
offset += sizeof(sp->set) + sizeof(sp->no_cnts);
if (!set_and_size_ok(sp)) {
warnx("CPU %d inconsistent set %d size %d",
cp->cpu_nr, sp->set, sp->no_cnts);
return -1;
}
/* Iterate over all counters in each set */
for (unsigned int k = 0; k < sp->no_cnts; ++k) {
uint64_t value;
void *addr = base + offset;
size_t idx = ctrset_offset(sp->set) + k;
memcpy(&value, addr, sizeof(value));
offset += sizeof(value);
if (!add_countervalue(idx, cp->cpu_nr, value))
return -1;
}
}
}
show();
return 0;
}
static int do_open(void)
{
int fd = open(S390_HWCTR_DEVICE, O_RDWR);
if (fd < 0)
warn(S390_HWCTR_DEVICE);
return fd;
}
static int do_stop(int ioctlfd)
{
int rc = ioctl(ioctlfd, S390_HWCTR_STOP, 0);
if (rc < 0)
warn("ioctl S390_HWCTR_STOP");
return rc;
}
static int do_start(int ioctlfd, struct s390_hwctr_start *start)
{
int rc = ioctl(ioctlfd, S390_HWCTR_START, start);
if (rc < 0)
warn("ioctl S390_HWCTR_START");
return rc;
}
static int do_read(int ioctlfd)
{
size_t ioctlbuffer_len = PAGE_SIZE * max_possible_cpus +
sizeof(struct s390_hwctr_read);
struct s390_hwctr_read *read;
int rc;
if (!ioctlbuffer) {
ioctlbuffer = malloc(ioctlbuffer_len);
if (!ioctlbuffer) {
warn("ioctl S390_HWCTR_START");
return -ENOMEM;
}
}
read = (struct s390_hwctr_read *)ioctlbuffer;
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
if (!rc)
rc = test_read(read);
else
warn("ioctl S390_HWCTR_READ");
return rc;
}
static void do_sleep(void)
{
struct timespec req = {
.tv_sec = read_interval,
.tv_nsec = 0
};
nanosleep(&req, NULL);
}
/* Execute commands and report first error */
static int do_it(char *s)
{
struct s390_hwctr_start start;
int ioctlfd;
int rc;
memset(&start, 0, sizeof(start));
rc = max_possible_cpus / sizeof(uint64_t);
start.cpumask = alloca(max_possible_cpus / sizeof(uint64_t));
memset(start.cpumask, 0, rc);
parse_cpulist(s, &start);
errno = 0;
ioctlfd = do_open();
if (ioctlfd < 0)
return EXIT_FAILURE;
rc = do_start(ioctlfd, &start);
if (rc < 0) {
close(ioctlfd);
return EXIT_FAILURE;
}
for (unsigned long i = 0; !rc && i < loop_count; ++i) {
rc = do_read(ioctlfd);
if (rc) {
close(ioctlfd);
return EXIT_FAILURE;
}
if (read_interval && i + 1 < loop_count)
do_sleep();
}
rc = do_stop(ioctlfd);
close(ioctlfd);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Displays all CPUs in output"
},
{
.option = { "loop", required_argument, NULL, 'l' },
.argument = "NUMBER",
.desc = "Specifies loop count for next read"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "NUMBER",
.desc = "Specifies interval between read operations (seconds)"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "Read CPU Measurement facility counter sets",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2021,
.pub_last = 2021,
},
UTIL_PRG_COPYRIGHT_END
}
};
/* Check for hardware support and exit if not available */
static void have_support(void)
{
struct stat statbuf;
if (stat(S390_HWCTR_DEVICE, &statbuf) == -1)
errx(EXIT_FAILURE,
"No support for CPU Measurement Counter set facility");
}
int main(int argc, char **argv)
{
char *slash;
int ch;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
switch (ch) {
default:
util_opt_print_parse_error(ch, argv);
return EXIT_FAILURE;
case 'h':
util_prg_print_help();
util_opt_print_help();
return EXIT_SUCCESS;
case 'v':
util_prg_print_version();
return EXIT_SUCCESS;
case 'l':
errno = 0;
loop_count = strtoul(optarg, &slash, 0);
if (errno || *slash)
errx(EXIT_FAILURE, "Invalid argument for -%c",
ch);
break;
case 'i':
errno = 0;
read_interval = (unsigned int)strtoul(optarg, &slash, 0);
if (errno || *slash)
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
break;
case 'a':
allcpu = true;
break;
}
}
have_support();
if (!libcpumf_cpumcf_info(&cfvn, &csvn, &authorization))
return EXIT_FAILURE;
if (!check_setpossible())
return EXIT_FAILURE;
if (!read_counternames()) {
free(check);
return EXIT_FAILURE;
}
if (optind >= argc) {
ch = do_it(NULL);
} else {
while (optind < argc) {
ch = do_it(argv[optind++]);
if (ch)
break;
}
}
free_counternames();
free(check);
return ch;
}

93
cpumf/lshwc.h Normal file
View File

@@ -0,0 +1,93 @@
/* Copyright IBM Corp. 2021
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
/*
* CPU Measurement counter facility application for device driver.
*
* Ioctl system call definitions.
*/
#ifndef LSHWC_H
#define LSHWC_H
#include <stdint.h>
#include <sys/ioctl.h>
enum {
S390_HWCTR_BASIC = 0x2, /* BASIC counter set */
S390_HWCTR_USER = 0x4, /* Problem-State Counter Set */
S390_HWCTR_CRYPTO = 0x8, /* Crypto-Activity Counter Set */
S390_HWCTR_EXT = 0x1, /* Extended Counter Set */
S390_HWCTR_MT_DIAG = 0x20, /* MT-diagnostic Counter Set */
S390_HWCTR_ALL = S390_HWCTR_BASIC | S390_HWCTR_USER |
S390_HWCTR_CRYPTO | S390_HWCTR_EXT |
S390_HWCTR_MT_DIAG
};
/* The ioctl(..., S390_HWCTR_READ, ...) is the only subcommand which returns
* data. It requires member data_bytes to be positive and indicates the
* maximum amount of data available to store counter set data. The other
* ioctl() subcommands do not use this member and it should be set to zero.
*
* The cpuset data is flattened using the following scheme, stored in member
* data:
*
* 0x0 0x8 0xc 0x10 0x14 0x18 0x20 0x28 0xU-1
* +---------+-----+---------+-----+---------+-----+-----+------+------+
* | no_cpus | cpu | no_sets | set | no_cnts | cv1 | cv2 | .... | cv_n |
* +---------+-----+---------+-----+---------+-----+-----+------+------+
*
* 0xU 0xU+4 0xU+8 0xU+10 0xV-1
* +-----+---------+-----+-----+------+------+
* | set | no_cnts | cv1 | cv2 | .... | cv_n |
* +-----+---------+-----+-----+------+------+
*
* 0xV 0xV+4 0xV+8 0xV+c
* +-----+---------+-----+---------+-----+-----+------+------+
* | cpu | no_sets | set | no_cnts | cv1 | cv2 | .... | cv_n |
* +-----+---------+-----+---------+-----+-----+------+------+
*
* U and V denote arbitrary hexadezimal addresses.
* In fact the first int represents the number of CPUs data was extracted
* from. This is followed by CPU number and number of counter sets extracted.
* Both are two integer values. This is followed by the set number and number
* of counters extracted. Both are two integer values. This is followed by
* the counter values, each element is eight bytes in size.
*/
struct s390_hwctr_start { /* Set CPUs to operate on */
uint64_t version; /* Version of interface */
uint64_t data_bytes; /* # of bytes required */
uint64_t cpumask_len; /* Length of CPU mask in bytes */
uint64_t *cpumask; /* Pointer to CPU mask */
uint64_t counter_sets; /* Bit mask of counter set to get */
};
struct s390_hwctr_setdata { /* Counter set data */
uint32_t set; /* Counter set number */
uint32_t no_cnts; /* # of counters stored in cv[] */
uint64_t cv[0]; /* Counter values (variable length) */
};
struct s390_hwctr_cpudata { /* Counter set data per CPU */
uint32_t cpu_nr; /* Counter set number */
uint32_t no_sets; /* # of counters sets in data[] */
struct s390_hwctr_setdata data[0];
};
struct s390_hwctr_read { /* Structure to get all ctr sets */
uint64_t no_cpus; /* Total # of CPUs data taken from */
struct s390_hwctr_cpudata data[0];
};
#define S390_HWCTR_MAGIC 'C' /* Random magic # for ioctls */
#define S390_HWCTR_START _IOWR(S390_HWCTR_MAGIC, 1, struct s390_hwctr_start)
#define S390_HWCTR_STOP _IO(S390_HWCTR_MAGIC, 2)
#define S390_HWCTR_READ _IOWR(S390_HWCTR_MAGIC, 3, struct s390_hwctr_read)
#define S390_HWCTR_START_VERSION 1 /* Version # s390_hwctr_start */
#define S390_HWCTR_DEVICE "/dev/hwctr" /* Device name */
#endif

View File

@@ -1,11 +1,11 @@
\" lscpumf.1
\" lscpumf.8
.\"
.\"
.\" Copyright IBM Corp. 2014, 2020
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\" ----------------------------------------------------------------------
.TH lscpumf "1" "May 2020" "s390-tools" "CPU-MF management programs"
.TH lscpumf "8" "May 2022" "s390-tools" "CPU-MF management programs"
.
.ds c \fBlscpumf\fP
.

134
cpumf/man/lshwc.8 Normal file
View File

@@ -0,0 +1,134 @@
.\" lshwc.8
.\"
.\"
.\" Copyright IBM Corp. 2021
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\" ----------------------------------------------------------------------
.ds c \fBlshwc\fP
.
.TH \*c "8" "May 2022" "s390-tools" "CPU-MF management programs"
.
.SH NAME
\*c \- extract CPU Measurement Facilities counter sets
.
.SH SYNOPSIS
\*c
.RB [ \-a ]
.RB [ \-l
.IR count ]
.RB [ \-i
.IR interval ]
\fR[\fIcpulist\fR][:\fIsets\fR]\fP
.br
\*c
.BR \-h | \-\-help
.br
\*c
.BR \-v | \-\-version
.
.
.SH DESCRIPTION
The \*c command extracts complete counter sets from the CPU
Measurement Facilities for Linux on Z.
Counter sets can be specified and extracted for individual CPUs.
The output is a comma-separated values file.
Each line starts with a timestamp and the CPU number,
followed by the extracted counter values.
.
.SH OPTIONS
.TP
.BR \-h ", " \-\-help
Displays help information, then exits.
.
.TP
.BR \-v ", " \-\-version
Displays version information, then exits.
.
.TP
.BR \-a ", " \-\-allcpu
Displays counter values from each CPU.
The default is a total summary line of all counters from all CPUs.
.
.TP
.BR \-i ", " \-\-interval \fI\ seconds\fP
Specifies a time interval, in seconds,
that the command waits between read operations.
The default is 60 seconds.
.
.TP
.BR \-l ", " \-\-loop \fI\ count\fP
Performs the specified number of read operations.
.
.TP
\fR[\fIcpulist\fR][:\fIsets\fR]\fP
A comma-separated list of CPUs.
Each CPU can optionally be followed by characters that specify the counter set.
See below for details.
.
.SS "CPU List and counter-set specification"
In the comma-separated list of CPUs,
each element is a CPU or a range of CPUs.
By default, \*c lists all CPUs.
.P
The CPU list can be followed by an optional list
of characters that specify the counter sets to be extracted,
preceded by a colon.
The characters can be upper or lower case.
By default, all counter sets are used.
.IP b
Include the basic counter set.
.IP c
Include the crypto counter set.
.IP e
Include the extended counter set.
.IP m
Include the MT_Diagnostic counter set.
.IP p|u
Include the problem counter set.
.IP a
Include all known counter sets (default).
.SH "Concurrency with perf tool"
The \*c tool and the linux
.B perf
tool use the same hardware and cannot be used concurrently.
Both tools print an error message and abort when they
detect this situation.
.SH "EXAMPLES"
The first example enables the basic and problem counter sets on CPU 0 and 1.
Two read operations are performed and a summary line is printed for each
read operation.
.sp 1
.nf
.ft CW
# lshwc -l2 0-1:BP
Date,Time,CPU,CPU_CYCLES(0),INSTRUCTIONS(1),L1I_DIR_WRITES(2),L1I_PENALTY_CYCLES(3),L1D_DIR_WRITES(4),
L1D_PENALTY_CYCLES(5),PROBLEM_STATE_CPU_CYCLES(32),PROBLEM_STATE_INSTRUCTIONS(33)
2021-04-01,11:50:32,Total,125422,39421,304,13953,454,
97489,0,0
2021-04-01,11:51:32,Total,68074231,16386850,194028,21382384,317227,
104503489,777383,14198
.ft
.fi
.sp 1
This example shows the counter values of the problem state counter set
per CPU. CPU 0 and CPU 1 is selected.
.nf
.ft CW
.sp 1
# lshwc -l3 -a 0-1:P
Date,Time,CPU,PROBLEM_STATE_CPU_CYCLES(32),PROBLEM_STATE_INSTRUCTIONS(33)
2021-04-01,11:54:47,CPU0,0,0
2021-04-01,11:54:47,CPU1,0,0
2021-04-01,11:54:47,Total,0,0
2021-04-01,11:55:47,CPU0,818775,14198
2021-04-01,11:55:47,CPU1,125689,1306
2021-04-01,11:55:47,Total,944464,15504
2021-04-01,11:56:47,CPU0,3207071426,1489122591
2021-04-01,11:56:47,CPU1,3225092021,1489278312
2021-04-01,11:56:47,Total,6432163447,2978400903
.ft
.fi
.SH "SEE ALSO"
.BR lscpumf (8)
.BR chcpumf (8)

268
cpumf/man/pai.8 Normal file
View File

@@ -0,0 +1,268 @@
.\" pai.8
.\"
.\"
.\" 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.
.\" ----------------------------------------------------------------------
.ds c \fBpai\fP
.
.TH \*c "8" "May 2022" "s390-tools" "PAI Management Programs"
.
.SH NAME
\*c \- record and report Processor Activity Instrumentation (PAI) counters
.
.SH SYNOPSIS
\*c
.RB [ \-V ][ \-m | \-\-mapsize
.IR size ]
.RB [ \-i | \-\-interval
.IR ms ]
.BR \-c | \-\-crypto [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
.br
\*c
.RB [ \-V ][ \-m | \-\-mapsize
.IR size ]
.RB [ \-i | \-\-interval
.IR ms ]
.BR \-n | \-\-nnpa [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
.br
\*c
.RB [ \-V ][ \-H | \-\-humantime ][ \-S | \-\-summary "] " \-r | \-\-report " [" \fIfiles\fP ]
.br
\*c
.BR \-h | \-\-help
.br
\*c
.BR \-v | \-\-version
.
.
.SH DESCRIPTION
\*c
counters tally calls for specific CPU instructions.
The \*c command records PAI counters in a ring buffer.
\*c can record counter data for all CPUs or for selected CPUs.
The main command options are
.B \-c
for recording cryptographic CPU instructions,
.B \-n
for recording NNPA CPU instructions
and
.B \-r
for reporting.
If all three options are omitted, option
.B \-r
is assumed and a message is printed.
Recording stores data, by CPU, in files
.I paicrypto.<XXX>,
for option
.B \-c
or
.I painnpa.<XXX>,
for option
.B \-n
where <XXX> specifies the CPU number with leading
zeros.
The files are created in the working directory,
existing files are overwritten.
Reporting evaluates files that are created by recording.
.SH OPTIONS
.TP
.BR \-c ", " \-\-crypto "\fR[\fIcpulist\fR][:\fIdata\fR]"
Records data for all (default) or a specified list of CPUs.
The CPU list is a comma-separated list of CPU numbers and ranges.
In a range, a hyphen separates the first CPU number
from the last CPU number.
By default \*c lists all CPUs.
.RS
The optional data specification
follows the colon
and determines additional collection of data.
The specification consists of alphabetic
characters that can be upper or lower case:
.IP c|C
Include task rename system calls
.B exec
and
.BR prctl .
.IP f|F
Include task creation and deletion system calls
.B fork
and
.BR exit .
.IP s|S
Include context switch records created by the kernel scheduler.
.IP k|K
Include only PAI cryptographic counters changed during system call
execution.
.IP u|U
Include only PAI cryptographic counters changed during user space
execution.
.RE
.
.TP
.BR \-n ", " \-\-nnpa "\fR[\fIcpulist\fR][:\fIdata\fR]"
Records data for all (default) or a specified list of CPUs.
The CPU list is a comma-separated list of CPU numbers and ranges.
In a range, a hyphen separates the first CPU number
from the last CPU number.
By default \*c lists all CPUs.
.RS
The optional data specification
follows the colon
and determines additional collection of data.
The specification consists of alphabetic
characters that can be upper or lower case:
.IP c|C
Include task rename system calls
.B exec
and
.BR prctl .
.IP f|F
Include task creation and deletion system calls
.B fork
and
.BR exit .
.IP s|S
Include context switch records created by the kernel scheduler.
.RE
.
.TP
.BR \-r ", " \-\-report
Generates a report from the specified files.
Files is a list of blank-separated file names.
If no files are specified,
uses all files named
.I paicrypto.<X>,
in the working directory, where
.I <X>
is a CPU number that
identifies the CPU for which the data was recorded.
.
.TP
.BR \-h ", " \-\-help
Displays help information, then exits.
.
.TP
.BR \-v ", " \-\-version
Displays version information, then exits.
.
.TP
.BR \-V ", " \-\-verbose
Displays the following information during reporting:
the file name and the hexadecimal offset for each sample header.
Displays the following information during recording:
the read position in the ring buffer,
the file name, and the hexadecimal offset for each sample header.
.
.TP
.BR \-H ", " \-\-humantime
Changes the time stamp format for sample entries from a hexadecimal
number to a human readable <seconds>.<nanoseconds> format.
The time stamp specifies the elapsed time since Linux was booted.
.
.TP
.BR \-S ", " \-\-summary
Prints a summary of counter names and
counter numbers with non-zero values.
The summary is the last line in the command output.
It shows the sum of the counter values of all processed files.
.
.TP
.BR \-i ", " \-\-interval "\ ms"
Specifies the waiting time,
in milliseconds,
between ring buffer read operations during recording.
The default is 1000 milliseconds.
Argument
.B loops
is an integer that specifies the number of
read operations during recording. The default is 1.
.
.TP
.BR \-m ", " \-\-mapsize "\ size"
Specifies the size of the ring buffer
that holds the collected data.
The value specifies the number of 4 KB pages
to be allocated and must be a power of 2.
The default size is 512 pages.
The ring buffer is created with the
.IR mmap (2)
system call.
.
.SH ARGUMENT
The command line options determine how command line
arguments are interpreted.
For option
.B \-c
to start recording, the argument specifies
the number of read operations.
If omitted, the default is one.
For option
.B \-r
to start reporting, the argument specifies
the file names to be read.
If omitted all files in the current directory
with file name
.I paicryto.<X>
are read.
.SH "Concurrency with perf tool"
The following concurrency restrictions apply
for \*c and the
.B perf
tool.
Both tools use the
.IR perf_event_open ()
system call and use the same device driver.
The device driver supports limited concurrency:
.IP Counting:
Counting pai events can run in parallel.
.IP Sampling:
Only one sampling event pai_crypto/CRYPTO_ALL can be active at any one time.
If a sampling event is active, no pai counting event can be active.
Both tools stop with an error message if they detect a collision
reported by the device driver.
.SH "EXAMPLES"
This example collects cryptographic counter on CPU 0.
The program runs for 10 seconds
(10 intervals of 1000 milliseconds).
.sp 1
.nf
.ft CW
# \*c -c0 10
.ft R
.fi
.sp 1
This example displays the data
that is collected in the first example.
Each data line shows the time stamp in jiffies,
followed by the CPU number,
the event number,
process and thread identifier (pid/tid) separated by slash (/),
and a comma-separated list of counter number, colon (:),
and the counter value n hexadecimal notation.
.sp 1
.nf
.ft CW
# \*c -r
0x62a668f2fa 0 event 4096 sample pid 4956/4956 9:0xa7,73:0x8,74:0x18
0x6319c75653 0 event 4096 sample pid 4972/4972 32:0x1
0x6319e2ddee 0 event 4096 sample pid 4972/4972 32:0x1
0x631d3e44f5 0 event 4096 sample pid 4972/4972 32:0x2
0x631d4cfc2e 0 event 4096 sample pid 4972/4972 32:0x3
0x631d529fdd 0 event 4096 sample pid 4972/4972 32:0x2
0x631d84cfa0 0 event 4096 sample pid 4972/4972 73:0x1
0x636e9826bc 0 event 4096 sample pid 4984/4984 9:0xa7,73:0x8,74:0x18
0x636f81a137 0 event 4096 sample pid 4984/4984 9:0x2,74:0x7
0x6378026e54 0 event 4096 sample pid 4984/4984 73:0x2
0x637bcdc8da 0 event 4096 sample pid 4984/4984 73:0x2
0x637bd426cd 0 event 4096 sample pid 4984/4984 73:0x6
0x637c503384 0 event 4096 sample pid 4984/4984 73:0x2
0x64991d83ba 0 event 4096 sample pid 5026/5026 9:0xb0,73:0x8,74:0x18
#
.ft R
.fi
.sp 1
.SH "SEE ALSO"
perf(1)

1125
cpumf/pai.c Normal file

File diff suppressed because it is too large Load Diff

105
cpumf/pai.h Normal file
View File

@@ -0,0 +1,105 @@
/*
* pai - Extract CPU Processor Activity Instrumentation (PAI) facility data.
*
* 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 PAI_H
#define PAI_H
#define S390_EVT_PAI_CRYPTO 0x1000
enum { /* Event attribute specifications */
S390_EVTATTR_CTX_SWITCH = 1,
S390_EVTATTR_COMM = 2,
S390_EVTATTR_FORK = 4,
S390_EVTATTR_USERSPACE = 8,
S390_EVTATTR_KERNELSPACE = 16
};
struct pai_event {
struct util_list_node node; /* List node */
struct perf_event_attr attr; /* Perf_event_open(2) attr */
int fd; /* Perf event file descriptor */
void *map_addr; /* Sampling data mapping address */
size_t map_size; /* Sampling size mapping size */
char file_name[16]; /* File name of sampled data */
int file_fd; /* Map data output file descriptor */
int cpu; /* Perf_event_open(2) CPU */
unsigned long flags; /* Perf_event_open(2) flags */
};
struct pai_event_out { /* Output for CRYPTO_ALL event */
__u32 type; /* Header type, see PERF_RECORD_xxx */
__u16 misc; /* Header misc, value depends on type */
__u64 time; /* Time stamp valid for all entries */
__u32 cpu; /* CPU number valid for all entries */
union {
/* Fields from PERF_RECORD_FORK|EXIT */
struct {
__u32 pid, ppid;
__u32 tid, ptid;
__u64 time;
} s_fork;
/* Fields from PERF_RECORD_COMM */
struct {
__u32 pid, tid;
__u8 cmd[16];
} s_comm;
/* Fields from PERF_RECORD_SWITCH_CPU_WIDE */
struct {
__u32 next_prev_pid, next_prev_tid;
} s_cs;
/* Fields from PERF_RECORD_LOST_SAMPLES */
struct {
__u64 lost;
} s_lost;
/* Relevant fields from PERF_RECORD_SAMPLE, time and cpu
* are stored above
*/
struct {
__u64 ip;
__u64 period;
__u32 pid, tid;
} s_sample;
/* Fields from PERF_RECORD_[UN]THROTTLE */
struct {
__u64 time;
__u64 id;
__u64 stream_id;
} s_throttle;
} u;
/* Information on last context switch out */
struct cs_switch {
unsigned char valid;
__u32 topid, totid;
__u32 frompid, fromtid;
} cs_switch;
void *raw; /* Pointer to key/value array for crypto counters */
};
struct data_pos { /* Perf event mapped ring buffer */
__u64 data_head; /* Head in the data section */
__u64 data_tail; /* User-space written tail */
__u64 data_offset; /* Where the buffer starts */
__u64 data_size; /* Data buffer size */
};
struct event_name { /* Event list for number to name xlate */
char *name; /* Event name */
__u64 config; /* Event config value */
__u64 total; /* Total counter value */
};
struct pmu_events { /* Event list for PMU number to name xlate */
struct util_list_node node; /* List node */
char *name; /* PMU name */
int type; /* PMU type */
int lstlen; /* # of entries in lst */
unsigned long base; /* Base event number */
struct event_name *lst; /* List of event names */
};
#endif /* PAI_H */

File diff suppressed because it is too large Load Diff

View File

@@ -41,6 +41,10 @@ static const char mode_str[3][10] = {
"Full", "Quick", "Expand"
};
/* Report error, free memory, and exit */
static void error(const char *format, ...)
__attribute__((__noreturn__, __format__(__printf__, 1, 2)));
#define DASD_PARTN_BITS 2
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
@@ -65,47 +69,24 @@ static const char mode_str[3][10] = {
"is in invalid format\n",prog_name);}
typedef struct bootstrap1 {
u_int32_t key;
u_int32_t data[6];
u_int32_t key;
u_int32_t data[6];
} __attribute__ ((packed)) bootstrap1_t;
typedef struct bootstrap2 {
u_int32_t key;
u_int32_t data[36];
u_int32_t key;
u_int32_t data[36];
} __attribute__ ((packed)) bootstrap2_t;
typedef struct dasdfmt_info {
dasd_information2_t dasd_info;
int verbosity;
int testmode;
int withoutprompt;
int print_progressbar;
int print_hashmarks, hashstep;
int print_percentage;
int force;
int writenolabel;
int labelspec;
int cdl_format;
int blksize_specified;
int reqsize_specified;
int keep_volser;
int force_host;
int layout_specified;
int check;
int mode_specified;
int ese;
int no_discard;
} dasdfmt_info_t;
/*
C9D7D3F1 000A0000 0000000F 03000000 00000001 00000000 00000000
*/
static bootstrap1_t ipl1 = {
0xC9D7D3F1, {
0x000A0000, 0x0000000F, 0x03000000,
0x00000001, 0x00000000, 0x00000000
}
0xC9D7D3F1, {
0x000A0000, 0x0000000F, 0x03000000,
0x00000001, 0x00000000, 0x00000000
}
};
/*
@@ -116,21 +97,20 @@ C9D7D3F2 07003AB8 40000006 31003ABE 40000005 08003AA0 00000000 06000000
00000000 00000000 00000000 00000000 00000000
*/
static bootstrap2_t ipl2 = {
0xC9D7D3F2, {
0x07003AB8, 0x40000006, 0x31003ABE,
0x40000005, 0x08003AA0, 0x00000000,
0x06000000, 0x20000000, 0x00000000,
0x00000000, 0x00000400, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000
}
0xC9D7D3F2, {
0x07003AB8, 0x40000006, 0x31003ABE,
0x40000005, 0x08003AA0, 0x00000000,
0x06000000, 0x20000000, 0x00000000,
0x00000000, 0x00000400, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000
}
};
#endif /* DASDFMT_H */

View File

@@ -47,7 +47,7 @@ Print DASD uid without z/VM minidisk token
z/VM may provide an additional token that can be used to distinguish
between different minidisks (see --extended-uid option). To remain
compatibile with systems that were installed on older Linux or z/VM
compatible with systems that were installed on older Linux or z/VM
levels, the -u option will print the uid excluding any z/VM-provided
minidisk token.

View File

@@ -29,6 +29,7 @@
#include "lib/dasd_sys.h"
#include "lib/libzds.h"
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/util_opt.h"
#include "lib/util_prg.h"
#include "lib/util_sys.h"
@@ -1788,10 +1789,8 @@ dasdview_print_format1(unsigned int size, unsigned char *dumpstr)
for (i = 0; i < size; i++) {
if ((i / 16) * 16 == i) {
printf("\n| ");
strncpy(asc, (char *)dumpstr + i, 16);
strncpy(ebc, (char *)dumpstr + i, 16);
asc[16] = '\0';
ebc[16] = '\0';
util_strlcpy(asc, (char *)dumpstr + i, 16);
util_strlcpy(ebc, (char *)dumpstr + i, 16);
}
printf("%02X", dumpstr[i]);
if (((i + 1) / 4) * 4 == i + 1)
@@ -1822,8 +1821,8 @@ dasdview_print_format2(unsigned int size, unsigned char *dumpstr,
begin + (unsigned long long)i,
begin + (unsigned long long)i);
strncpy(asc, (char *)dumpstr + i, 8);
strncpy(ebc, (char *)dumpstr + i, 8);
util_strlcpy(asc, (char *)dumpstr + i, 8);
util_strlcpy(ebc, (char *)dumpstr + i, 8);
}
printf("%02X", dumpstr[i]);
if (((i + 1) / 4) * 4 == i + 1)

View File

@@ -110,6 +110,7 @@ static struct util_opt dump2tar_opts[] = {
{
.option = { "file-timeout", required_argument, NULL, 'T' },
.desc = "Stop reading file after SEC seconds",
.argument = "SEC",
},
{
.option = { "file-max-size", required_argument, NULL, 'M' },

25
etc/hsavmcore.conf Normal file
View File

@@ -0,0 +1,25 @@
# Example configuration for hsavmcore
# See hsavmcore.conf(8) for documentation
# 0 - ERROR
# 1 - WARN
# 2 - INFO
# 3 - DEBUG
# 4 - TRACE
#verbose = 0
#workdir = /var/crash
#mount_debugfs = 0
#use_hsa_mem = 0
#hsa_size = -1
#release_hsa = 1
#bind_mount_vmcore = 1
#swap = /dev/disk/by-uuid/3cf6630b-4c4d-49ac-a0ae-0f5484cb5721
#swap = /swap.img
#fuse_debug = 0

View File

@@ -1,89 +0,0 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: cpacfstatsd
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: Start the cpacfstatsd daemon for Linux on System z
# Description: CPACF statistics collection daemon process for Linux on System z
### END INIT INFO
DAEMON=cpacfstatsd
DAEMON_PATH=/usr/sbin/cpacfstatsd
RUN_PID_FILE=/run/cpacfstatsd.pid
RETVAL=0
OPTIONS=""
# source function library
. /lib/lsb/init-functions
start()
{
if [ ! -f $RUN_PID_FILE ]; then
echo -n $"Starting $DAEMON:"
$DAEMON_PATH $OPTIONS
if [ $? == "0" ]; then
log_success_msg
else
log_failure_msg
fi
echo
else
echo "$DAEMON (pid $(cat $RUN_PID_FILE)) is already running..."
echo
fi
}
stop()
{
echo -n $"Stopping $DAEMON:"
if [ -f $RUN_PID_FILE ]; then
killproc $DAEMON_PATH -TERM
log_success_msg
rm -f $RUN_PID_FILE
else
log_failure_msg
fi
echo
}
restart() {
stop
sleep 1
start
}
status()
{
if [ ! -f $RUN_PID_FILE ]; then
echo "$DAEMON is not running."
echo
else
echo "$DAEMON (pid $(cat $RUN_PID_FILE)) is running."
echo
fi
}
# How are we called?
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
*)
echo "Usage: $DAEMON {start|stop|status|restart}"
RETVAL=1
esac
exit $RETVAL

View File

@@ -1,116 +0,0 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: cpuplugd
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: Start the cpu hotplug daemon for Linux on System z
# Description: Starts the cpuplugd. It uses the configuration
# file /etc/cpuplugd.conf
### END INIT INFO
# chkconfig: 235 01 99
DAEMON=cpuplugd
DAEMON_PATH=/usr/sbin/cpuplugd
CONFIG_FILE=/etc/cpuplugd.conf
RUN_PID_FILE=/run/cpuplugd.pid
RETVAL=0
OPTIONS="-c $CONFIG_FILE"
# source function library
. /lib/lsb/init-functions
start()
{
if [ ! -f $RUN_PID_FILE ]; then
echo -n $"Starting $DAEMON:"
$DAEMON_PATH $OPTIONS
if [ $? == "0" ]; then
log_success_msg
else
log_failure_msg
fi
echo
else
echo "$DAEMON (pid $(cat $RUN_PID_FILE)) is already running..."
echo
fi
}
stop()
{
echo -n $"Stopping $DAEMON:"
if [ -f $RUN_PID_FILE ]; then
killproc $DAEMON_PATH -TERM
log_success_msg
rm -f $RUN_PID_FILE
else
log_failure_msg
fi
echo
}
restart() {
stop
#
# We have to wait 2-3 seconds here. When the daemon is stopped it takes
# the time we sleep to reactivate cpus. If we restart to fast and
# cpuplugd wasn't able to restore some settings we may get a undesired
# online cpu count after cpuplugd shutdown
#
sleep 4
start
}
status()
{
if [ ! -f $RUN_PID_FILE ]; then
echo "$DAEMON is not running."
echo
else
echo "$DAEMON (pid $(cat $RUN_PID_FILE), options: $OPTIONS) is running."
echo
fi
}
reload()
{
echo -n $"Reloading $DAEMON: "
if [ -f $RUN_PID_FILE ]; then
killproc $DAEMON_PATH -HUP
log_success_msg
else
log_failure_msg
fi
RETVAL=$?
echo
}
# How are we called?
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
reload|force-reload)
reload
;;
*)
echo "Usage: $DAEMON {start|stop|status|restart|reload}"
RETVAL=1
esac
exit $RETVAL

View File

@@ -1,161 +0,0 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: mon_statd
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: Configure the mon_fsstatd and mon_procd daemons.
# Description: Configures the mon_fsstatd and mon_procd daemons. It uses the
# configuration file /etc/sysconfig/mon_statd.
### END INIT INFO
# chkconfig: 235 01 99
DAEMON=mon_statd
FSSTATD=mon_fsstatd
PROCD=mon_procd
FSSTATD_PATH=/usr/sbin/$FSSTATD
PROCD_PATH=/usr/sbin/$PROCD
CONFIG_FILE=/etc/sysconfig/$DAEMON
FSSTATD_PID_FILE=/run/$FSSTATD.pid
PROCD_PID_FILE=/run/$PROCD.pid
# source function library
. /lib/lsb/init-functions
# Source config file
if [ -f $CONFIG_FILE ]; then
. $CONFIG_FILE
fi
UDEVSETTLE=/usr/bin/udevadm
if [ ! -e $UDEVSETTLE ]
then
UDEVSETTLE=/sbin/udevsettle
UDEVSETTLE_CALL="$UDEVSETTLE --timeout=10"
else
UDEVSETTLE_CALL="$UDEVSETTLE settle --timeout=10"
fi
load_kernel_module()
{
if [ ! -e /dev/monwriter ]; then
echo "Loading monwriter module..."
modprobe monwriter 2>&1
if [ $? -ne 0 ]; then
exit 1
fi
if [ -e $UDEVSETTLE ]
then
$UDEVSETTLE_CALL
fi
fi
}
start_daemon()
{
local daemon_name=$1
local daemon_interval=$2
local daemon_pid_file=$3
local daemon_path=$4
if [ ! -f $daemon_pid_file ]; then
load_kernel_module
echo -n "Starting $daemon_name:"
$daemon_path -i $daemon_interval
if [ $? -eq 0 ]; then
log_success_msg
else
log_failure_msg
fi
else
echo "$daemon_name (pid $(cat $daemon_pid_file)) is already running..."
fi
}
start()
{
if [ "$FSSTAT" = "yes" ]; then
start_daemon $FSSTATD $FSSTAT_INTERVAL $FSSTATD_PID_FILE \
$FSSTATD_PATH
fi
if [ "$PROC" = "yes" ]; then
start_daemon $PROCD $PROC_INTERVAL $PROCD_PID_FILE \
$PROCD_PATH
fi
}
stop_daemon()
{
local daemon_name=$1
local daemon_pid_file=$2
local daemon_path=$3
echo -n "Stopping $daemon_name:"
if [ -f $daemon_pid_file ]; then
killproc $daemon_path -TERM
log_success_msg
rm -f $daemon_pid_file
else
log_failure_msg
fi
}
stop()
{
if [ "$FSSTAT" = "yes" ]; then
stop_daemon $FSSTATD $FSSTATD_PID_FILE $FSSTATD_PATH
fi
if [ "$PROC" = "yes" ]; then
stop_daemon $PROCD $PROCD_PID_FILE $PROCD_PATH
fi
}
restart() {
stop
start
}
status_daemon()
{
local daemon_name=$1
local daemon_pid_file=$2
local daemon_interval=$3
if [ ! -f $daemon_pid_file ]; then
echo "$daemon_name is not running."
else
echo "$daemon_name (pid $(cat $daemon_pid_file), interval: $daemon_interval) is running."
fi
}
status()
{
status_daemon $FSSTATD $FSSTATD_PID_FILE $FSSTAT_INTERVAL
status_daemon $PROCD $PROCD_PID_FILE $PROC_INTERVAL
}
# How are we called?
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart|reload|force-reload)
restart
;;
*)
echo "Usage: $DAEMON {start|stop|status|restart|reload}"
exit 1
esac
exit 0

View File

@@ -26,10 +26,10 @@ KERNEL=="dasd*[0-9]", ENV{ID_XUID}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env
LABEL="dasd_symlinks_end"
# on device add set request queue scheduler to deadline
# on device add set request queue scheduler to none
SUBSYSTEM!="block", GOTO="sched_end"
ACTION!="change", GOTO="sched_end"
KERNEL=="dasd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="deadline"
KERNEL=="dasd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="none"
LABEL="sched_end"

View File

@@ -408,8 +408,10 @@ static int read_line(void)
{
bzero(line_buffer, LINE_LENGTH);
line_ptr = line_buffer;
if (!fgets(line_buffer, LINE_LENGTH, stdin))
if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
clearerr(stdin);
return 0;
}
while (*line_ptr && !isgraph(*line_ptr))
line_ptr++;
@@ -1232,7 +1234,7 @@ static void fdasd_reread_partition_table(fdasd_anchor_t *anc)
if (!anc->silent)
printf("rereading partition table...\n");
if (dasd_reread_partition_table(options.device, 1) != 0) {
if (dasd_reread_partition_table(options.device, 5) != 0) {
fdasd_error(anc, unable_to_ioctl, "Error while rereading "
"partition table.\nPlease reboot!");
}

View File

@@ -21,7 +21,7 @@ clean: clean-recursive
$(RECURSIVE_TARGETS):
@target=`echo $@ |sed s/-recursive//`; \
for d in $(SUBDIRS); do \
$(MAKE) -C $$d $$target; \
$(MAKE) -C $$d $$target || exit 1; \
done
.PHONY: all install clean $(RECURSIVE_TARGETS)

View File

@@ -12,10 +12,11 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
-DENABLE_SCLP_ASCII=1 \
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
-fno-delete-null-pointer-checks \
-fno-delete-null-pointer-checks -fno-stack-protector \
-fexec-charset=IBM1047 -m64 -mpacked-stack \
-mstack-size=4096 -mstack-guard=128 -msoft-float \
-Wall -Wformat-security -Wextra -Werror
-Wall -Wformat-security -Wextra -Werror \
-Wno-array-bounds
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
@@ -74,11 +75,11 @@ stage3b_reloc.elf:
%.elf: %.o
case $* in \
stage3a) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3a.lds";; \
stage3b) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-T,stage3b.lds";; \
stage3b_reloc) SFLAGS="$(NO_PIE_LINKFLAGS) -nostdlib -Wl,-estage3b_reloc_start,-Ttext,0";; \
stage3a) SFLAGS="-Wl,-T,stage3a.lds";; \
stage3b) SFLAGS="-Wl,-T,stage3b.lds";; \
stage3b_reloc) SFLAGS="-Wl,-estage3b_reloc_start,-Ttext,0";; \
esac; \
$(LINK) $$SFLAGS -m64 $(filter %.o, $^) -o $@
$(LINK) $$SFLAGS $(NO_PIE_LDFLAGS) -m64 -static -nostdlib $(filter %.o, $^) -o $@
@chmod a-x $@
%.bin: %.elf

View File

@@ -1,5 +1,5 @@
/*
* Entry code for stage 3a boot loader
* Entry code for stage 3a and stage 3b boot loader
*
* Copyright IBM Corp. 2020
*
@@ -24,6 +24,8 @@ _start:
sam64
/* Initialize stack */
lgfi %r15, STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
basr %r13, 0
.Lbase: llgf %r15, .Lstack - .Lbase(%r13)
brasl %r14, initialize
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
.previous

View File

@@ -21,6 +21,8 @@ _init:
* kernel command line and the address and size of the
* ramdisk. Simply ignore this by starting at 0x11000.
*/
lgfi %r1, STAGE3A_ENTRY
basr %r13, 0
.Lbase: llgf %r1, .Lstage3a_entry - .Lbase(%r13)
br %r1
.Lstage3a_entry: .long STAGE3A_ENTRY
.previous

View File

@@ -28,13 +28,23 @@ static inline void __noreturn load_psw(struct psw_t psw)
;
}
static unsigned long get_kernel_cmdline_size(void)
{
unsigned long size = *(volatile unsigned long *)MAX_COMMAND_LINE_SIZE;
if (size != 0)
return size;
return LEGACY_COMMAND_LINE_SIZE;
}
void __noreturn start(void)
{
volatile struct stage3b_args *args = &loader_parms;
volatile struct memblob *kernel = &args->kernel;
volatile struct memblob *cmdline = &args->cmdline;
volatile struct memblob *initrd = &args->initrd;
volatile struct psw_t psw = args->psw;
struct psw_t psw = args->psw;
/* set up ASCII and line-mode */
sclp_setup(SCLP_LINE_ASCII_INIT);
@@ -42,14 +52,14 @@ void __noreturn start(void)
if (kernel->size < IMAGE_LOAD_ADDRESS)
panic(EINTERNAL, "Invalid kernel\n");
if (cmdline->size > COMMAND_LINE_SIZE)
panic(EINTERNAL, "Command line is too large\n");
/* move the kernel and cut the kernel header */
memmove((void *)IMAGE_LOAD_ADDRESS,
(void *)(kernel->src + IMAGE_LOAD_ADDRESS),
kernel->size - IMAGE_LOAD_ADDRESS);
if (cmdline->size > get_kernel_cmdline_size())
panic(EINTERNAL, "Command line is too large\n");
/* move the kernel cmdline */
memmove((void *)COMMAND_LINE,
(void *)cmdline->src,

View File

@@ -31,12 +31,12 @@ stage3b_reloc_start:
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
sam64
.copy_stage3b:
/* Location of stage3b in memory */
larl %r8, stage3b_start
/* Destination for stage3b */
lgfi %r9, STAGE3B_LOAD_ADDRESS
basr %r13, 0
.Lbase: llgf %r9, .Lstage3b_load_address - .Lbase(%r13)
/* Size of stage3b */
lghi %r11, stage3b_end - stage3b_start
@@ -45,8 +45,10 @@ stage3b_reloc_start:
MEMCPY %r9, %r8, %r11
/* Branch to STAGE3B_ENTRY */
lgfi %r9, STAGE3B_ENTRY
llgf %r9, .Lstage3b_entry - .Lbase(%r13)
br %r9
.Lstage3b_load_address: .long STAGE3B_LOAD_ADDRESS
.Lstage3b_entry: .long STAGE3B_ENTRY
stage3b_start:
.incbin "stage3b.bin"
stage3b_end:

View File

@@ -4,8 +4,8 @@ include ../../common.mak
all:
install:
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 -c genprotimg.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
$(INSTALL) -m 644 -c genprotimg.1 $(DESTDIR)$(MANDIR)/man1
clean:

148
genprotimg/man/genprotimg.1 Normal file
View File

@@ -0,0 +1,148 @@
.\" Copyright 2020 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.
.\"
.TH GENPROTIMG 1 "May 2022" "s390-tools"
.SH NAME
genprotimg \- Create a protected virtualization image
.SH SYNOPSIS
.SY
.B genprotimg
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
\fB\-C\fR \fICERTIFICATE\fR...
\fB\-i\fR \fIVMLINUZ\fR
[\fB\-r\fR \fIRAMDISK\fR]
[\fB\-p\fR \fIPARMFILE\fR]
\fB\-o\fR \fIOUTFILE\fR
[\fIOPTION\fR]...
.YS
.SH DESCRIPTION
.PP
Use \fBgenprotimg\fR to generate a single bootable image file with
encrypted and integrity-protected parts. The command requires a kernel
image, a host-key document, certificates for the host-key document
verification, and an output file name. Optionally, specify an initial
RAM filesystem, and a file containing the kernel parameters. If the
command should be run offline, use the \fB\-\-offline\fR option and
specify the certificate revocation lists (CRLs) by using the
\fB\-\-crl\fR option. Should special circumstances require it, you can
optionally specify your own keys for the encryption by using the
experimental options. For all certificates, CRLs, and host-key
documents, both the PEM and DER input formats are supported. In the
resulting image file, a plain text boot loader, the encrypted
components for kernel, initial RAM disk, kernel parameters, and the
encrypted and integrity-protected header are concatenated. The header
contains metadata necessary for running the guest in protected mode.
.PP
Use this image file as a kernel image for zipl or for a direct kernel
boot using QEMU.
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Prints usage information, then exits.
.TP
\fB\-\-help-experimental\fR
Prints experimental usage information, then exits.
.TP
\fB\-\-help-all\fR
Prints all usage information, then exits.
.TP
\fB\-V\fR, \fB\-\-verbose\fR
Provides more detailed output.
.TP
\fB\-k\fR, \fB\-\-host-key-document\fR=\fI\,HOST_KEY_DOCUMENT\/\fR
Specifies a host-key document. At least one is required. Specify this
option multiple times to enable the image to run on more than one
host.
.TP
\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR
Specifies the certificate that is used to establish a chain of trust
for the verification of the host-key documents. Specify this option
twice to specify the IBM Z signing key and the intermediate CA
certificate (signed by the root CA).
Required. Ignored if \fB--no-verify\fP is specified.
.TP
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
Specifies the output file. Required.
.TP
\fB\-i\fR, \fB\-\-image\fR=\fI\,VMLINUZ\/\fR
Specifies the Linux kernel image file. Required.
.TP
\fB\-r\fR, \fB\-\-ramdisk\fR=\fI\,RAMDISK\/\fR
Specifies the RAM disk image. Optional.
.TP
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
.TP
\fB\-\-crl\fR=\fI\,FILE\/\fR
Specifies the revocation list that is used to check whether a
certificate of the chain of trust is revoked. Specify this option
multiple times to use multiple CRLs. Optional.
.TP
\fB\-\-offline\fR
Specifies offline mode, in which no attempt is made to download
CRLs. Optional.
.TP
\fB\-\-root\-ca\fR=\fI\,FILE\/\fR
Specifies the root CA certificate for the verification. If omitted,
the system wide root CAs installed on the system is used. Use
this only if you trust the specified certificate. Optional.
.TP
\fB\-\-no-verify\fR
Does not require the host-key documents to be valid.
Do not use for a production image unless you verified
the host-key document before. Optional.
.TP
\fB\-\-comm\-key\fR=\fI\,FILE\/\fR
Specifies the encryption key you want to use for the PV guest dump. Use a
secure, random, plaintext AES-256 GCM key. Optional.
.TP
\fB\-\-enable\-dump\fR
Enable PV guest dumps. Requires the \fB\-\-comm-key\fR option. Optional.
.TP
\fB\-\-disable\-dump\fR
Disable PV guest dumps. This is the default. Optional.
.TP
\fB\-\-enable\-pckmo\fR
Enable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption
functions. This is the default. Optional.
.TP
\fB\-\-disable\-pckmo\fR
Disable the support for the DEA, TDEA, AES, and ECC PCKMO key encryption
functions. Optional.
.TP
\fB\-v\fR, \fB\-\-version\fR
Prints version information, then exits.
.SH EXAMPLES
These are examples to generate a protected virtualization image in
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR, the
initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
\fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR, the
IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the
host-key document in \fI\,host_key.crt\/\fR. An AES-256 GCM key is stored in
\fI\,comm-key\/\fR, which is used for the PV guest dump support in the second
example.
Generate a protected virtualization image:
.PP
.B genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt\fR \-o \fI\,/boot/vmlinuz.pv\/\fR
Generate a protected virtualization image with PV guest dump support:
.PP
.B genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt\fR \-o \fI\,/boot/vmlinuz.pv\/\fR \-\-enable\-dump \-\-comm\-key \fI\,comm-key\fR
.SH NOTES
.IP "1." 4
An ELF file cannot be used as a Linux kernel image.
.IP "2." 4
Remember to re-run \fBzipl\fR after updating a protected
virtualization image.
.SH SEE ALSO
\&\fBzipl\fR\|(5), \fBqemu\fR\|(1)

View File

@@ -1,97 +0,0 @@
.\" Copyright 2020 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.
.\"
.TH GENPROTIMG 8 "March 2020" "s390-tools"
.SH NAME
genprotimg \- Create a protected virtualization image
.SH SYNOPSIS
.SY
.B genprotimg
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
\fB\-i\fR \fIVMLINUZ\fR
[\fB\-r\fR \fIRAMDISK\fR]
[\fB\-p\fR \fIPARMFILE\fR]
\fB\-o\fR \fIOUTFILE\fR
[\fIOPTION\fR]...
.YS
.SH DESCRIPTION
.PP
Use \fBgenprotimg\fR to generate a single bootable image file with
encrypted and integrity-protected parts. The command requires a kernel
image, a host-key document, and an output file name. Optionally,
specify an initial RAM filesystem, and a file containing the kernel
parameters. Should special circumstances require it, you can
optionally specify your own keys for the encryption by using the
experimental options. In the resulting image file, a plain text boot
loader, the encrypted components for kernel, initial RAM disk, kernel
parameters, and the encrypted and integrity-protected header are
concatenated. The header contains metadata necessary for running the
guest in protected mode.
.PP
Use this image file as a kernel image for zipl or for a direct kernel
boot using QEMU.
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
Prints usage information, then exits.
.TP
\fB\-\-help-experimental\fR
Prints experimental usage information, then exits.
.TP
\fB\-\-help-all\fR
Prints all usage information, then exits.
.TP
\fB\-V\fR, \fB\-\-verbose\fR
Provides more detailed output.
.TP
\fB\-k\fR, \fB\-\-host-key-document\fR=\fI\,HOST_KEY_DOCUMENT\/\fR
Specifies a host-key document. At least one is required. Specify this
option multiple times to enable the image to run on more than one
host.
.TP
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
Specifies the output file. Required.
.TP
\fB\-i\fR, \fB\-\-image\fR=\fI\,VMLINUZ\/\fR
Specifies the Linux kernel image file. Required.
.TP
\fB\-r\fR, \fB\-\-ramdisk\fR=\fI\,RAMDISK\/\fR
Specifies the RAM disk image. Optional.
.TP
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
.TP
\fB\-\-no-verify\fR
Do not require the host-key documents to be valid. For testing
purposes, do not use for a production image. Optional.
.TP
\fB\-v\fR, \fB\-\-version\fR
Prints version information, then exits.
.SH EXAMPLE
.PP
Generate a protected virtualization image in
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR:
.PP
.Vb 1
.EX
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR
.EE
.Ve
.PP
.SH NOTES
.IP "1." 4
An ELF file cannot be used as a Linux kernel image.
.IP "2." 4
Remember to re-run \fBzipl\fR after updating a protected
virtualization image.
.SH SEE ALSO
\&\fBzipl\fR\|(5), \fBqemu\fR\|(1)

View File

@@ -23,6 +23,7 @@ BODY_FILE=$(mktemp)
ISSUER_DN_FILE=$(mktemp)
SUBJECT_DN_FILE=$(mktemp)
DEF_ISSUER_DN_FILE=$(mktemp)
CANONICAL_ISSUER_DN_FILE=$(mktemp)
CRL_SERIAL_FILE=$(mktemp)
# Cleanup on exit
@@ -30,7 +31,7 @@ cleanup()
{
rm -f $ISSUER_PUBKEY_FILE $SIGNATURE_FILE $BODY_FILE \
$ISSUER_DN_FILE $SUBJECT_DN_FILE $DEF_ISSUER_DN_FILE \
$CRL_SERIAL_FILE
$CANONICAL_ISSUER_DN_FILE $CRL_SERIAL_FILE
}
trap cleanup EXIT
@@ -47,13 +48,21 @@ set -e
usage()
{
cat <<-EOF
Usage: `basename $1` host-key-doc signing-key-cert [-c CA-cert] [-r CRL]
Usage: `basename $1` [-d] [-c CA-cert] [-r CRL] host-key-doc signing-key-cert
Verify an IBM Secure Execution host key document against
a signing key.
Options:
-d disable default issuer check of host-key-doc
-c CA-cert trusted CA certificate
-r CRL list of revoked host-key-docs
Note that in order to have the full trust chain verified
it is necessary to provide the issueing CA's certificate.
it is necessary to provide the issuing CA's certificate.
The default issuer check may be disabled if a non-default
signing key certificate needs to be verified against the
CA certificate.
EOF
}
@@ -121,20 +130,34 @@ default_issuer()
commonName = International Business Machines Corporation
countryName = US
localityName = Poughkeepsie
organizationalUnitName = IBM Z Host Key Signing Service
organizationalUnitName = Key Signing Service
organizationName = International Business Machines Corporation
stateOrProvinceName = New York
EOF
}
verify_issuer_files()
# As organizationalUnitName can have an arbitrary prefix but must
# end with "Key Signing Service" let's normalize the OU name by
# stripping off the prefix
verify_default_issuer()
{
default_issuer > $DEF_ISSUER_DN_FILE
if ! diff $ISSUER_DN_FILE $DEF_ISSUER_DN_FILE
sed "s/\(^[ ]*organizationalUnitName[ ]*=[ ]*\).*\(Key Signing Service$\)/\1\2/" \
$ISSUER_DN_FILE > $CANONICAL_ISSUER_DN_FILE
if ! diff $CANONICAL_ISSUER_DN_FILE $DEF_ISSUER_DN_FILE
then
echo Incorrect default issuer >&2 && exit 1
fi
}
verify_issuer_files()
{
if [ $1 -eq 1 ]
then
verify_default_issuer
fi
if diff $ISSUER_DN_FILE $SUBJECT_DN_FILE
then
@@ -196,14 +219,16 @@ check_file()
# check args
CRL_FILE=
CA_FILE=
CHECK_DEFAULT_ISSUER=1
args=$(getopt -qu "r:c:h" $*)
args=$(getopt -qu "dr:c:h" $*)
if [ $? = 0 ]
then
set -- $args
while [ $1 != "" ]
do
case $1 in
-d) CHECK_DEFAULT_ISSUER=0; shift;;
-r) CRL_FILE=$2; shift 2;;
-c) CA_FILE=$2; shift 2;;
-h) usage $0; exit 0;;
@@ -244,7 +269,7 @@ exit 1
# Verify the issuer
canonical_dn x509 $HKD_FILE issuer $ISSUER_DN_FILE
canonical_dn x509 $HKSK_FILE subject $SUBJECT_DN_FILE
verify_issuer_files
verify_issuer_files $CHECK_DEFAULT_ISSUER
# Verify dates
verify_dates $(cert_time $HKD_FILE startdate) $(cert_time $HKD_FILE enddate)
@@ -261,7 +286,7 @@ then
echo -n "CRL "
canonical_dn crl $CRL_FILE issuer $ISSUER_DN_FILE
canonical_dn x509 $HKSK_FILE subject $SUBJECT_DN_FILE
verify_issuer_files
verify_issuer_files $CHECK_DEFAULT_ISSUER
verify_dates $(crl_time $CRL_FILE lastupdate) $(crl_time $CRL_FILE nextupdate) 'CRL'

View File

@@ -15,24 +15,25 @@ INCLUDE_PARMS = $(addprefix -I,$(INCLUDE_PATHS))
WARNINGS := -Wall -Wextra -Wshadow \
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Werror \
-Wpointer-arith -Werror -Wno-error=inline \
$(NULL)
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
pv/pv_opt_item.c \
pv/pv_opt_item.c utils/curl.c \
$(NULL)
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \
-DOPENSSL_API_COMPAT=0x10100000L \
$(WARNINGS) \
$(NULL)
ALL_CPPFLAGS += $(INCLUDE_PARMS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
ifneq ($(shell sh -c 'command -v pkg-config'),)
@@ -40,21 +41,27 @@ GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
else
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
GLIB2_LIBS := -lglib-2.0
LIBCRYPTO_CFLAGS :=
LIBCRYPTO_LIBS := -lcrypto
LIBCURL_CFLAGS :=
LIBCURL_LIBS := -lcurl
endif
BUILD_TARGETS := skip-$(bin_PROGRAM)
INSTALL_TARGETS := skip-$(bin_PROGRAM)
ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_GLIB2},0)
ifneq (${HAVE_LIBCURL},0)
BUILD_TARGETS := $(bin_PROGRAM)
INSTALL_TARGETS := install-$(bin_PROGRAM)
endif
endif
endif
all: $(BUILD_TARGETS)
@@ -98,4 +105,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM)
"openssl-devel / libssl-dev version >= 1.1.0", \
"HAVE_OPENSSL=0", \
"-I.")
$(call check_dep, \
"$(bin_PROGRAM)", \
"curl/curl.h", \
"libcurl-devel", \
"HAVE_LIBCURL=0")
touch $@

View File

@@ -1,3 +1,10 @@
/*
* Copyright IBM Corp. 2020, 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 COMMON_H
#define COMMON_H

View File

@@ -18,6 +18,8 @@
#include "common.h"
#include "pv/pv_args.h"
#include "pv/pv_image.h"
#include "utils/crypto.h"
#include "utils/curl.h"
enum {
LOG_LEVEL_CRITICAL = 0,
@@ -117,6 +119,8 @@ static void remove_signal_handler(const gint *signals, const gsize signals_n)
signal(signals[i], SIG_DFL);
}
static void __attribute__((constructor)) __init(void);
static void __attribute__((destructor)) __cleanup(void);
gint main(gint argc, gchar *argv[])
{
g_autoptr(PvArgs) args = pv_args_new();
@@ -177,5 +181,20 @@ error:
rmdir_recursive(tmp_dir, NULL);
remove_signal_handler(signals, G_N_ELEMENTS(signals));
g_free(tmp_dir);
g_clear_pointer(&img, pv_img_free);
g_clear_pointer(&args, pv_args_free);
exit(ret);
}
static void __init(void)
{
pv_crypto_init();
if (curl_init() != 0)
g_abort();
}
static void __cleanup(void)
{
curl_cleanup();
pv_crypto_cleanup();
}

View File

@@ -14,6 +14,21 @@
#include "lib/zt_common.h"
/* IBM signing key subject */
#define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation"
#define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US"
#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie"
#define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service"
#define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation"
#define PV_IBM_Z_SUBJECT_STATE "New York"
#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6
/* Minimum security level for the keys/certificates used to establish a chain of
* trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html
* for details).
*/
#define PV_CERTS_SECURITY_LEVEL 2
union ecdh_pub_key {
struct {
uint8_t x[80];

View File

@@ -24,8 +24,15 @@
#define PV_MAGIC_NUMBER 0x49424d5365634578ULL
#define PV_VERSION_1 0x00000100U
/* prevent Ultravisor decryption during unpack operation */
#define PV_CFLAG_NO_DECRYPTION 0x10000000ULL
/* Internal helper macro */
#define __PV_BIT(nr) (1ULL << (63 - (nr)))
/* Plaintext control flags */
#define PV_PCF_ALLOW_DUMPING __PV_BIT(34) /* dumping of the configuration is allowed */
#define PV_PCF_NO_DECRYPTION __PV_BIT(35) /* prevent Ultravisor decryption during unpack operation */
#define PV_PCF_PCKMO_DEA_TDEA __PV_BIT(56) /* PCKMO encrypt-DEA/TDEA-key functions allowed */
#define PV_PCF_PCKMO_AES __PV_BIT(57) /* PCKMO encrypt-AES-key functions allowed */
#define PV_PCF_PCKM_ECC __PV_BIT(58) /* PCKMO encrypt-ECC-key functions allowed */
/* maxima for the PV version 1 */
#define PV_V1_IPIB_MAX_SIZE PAGE_SIZE

View File

@@ -18,7 +18,9 @@
static gchar summary[] =
"Use genprotimg to create a protected virtualization kernel image file,\n"
"which can be loaded using zipl or QEMU.";
"which can be loaded using zipl or QEMU. For all certificates, revocation\n"
"lists, and host-key documents, both the PEM and DER input formats are\n"
"supported.";
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
{
@@ -62,6 +64,17 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
{
PvComponentType KERNEL = PV_COMP_TYPE_KERNEL;
/* Check for mutually exclusive arguments */
if (args->pcf && !(args->allow_pckmo == PV_NOT_SET &&
args->allow_dump == PV_NOT_SET)) {
g_set_error(
err, PV_PARSE_ERROR, PV_PARSE_ERROR_SYNTAX,
_("The '--x-pcf' option cannot be used with the '--(enable|disable)-pckmo' or"
" '--(enable|disable)-dump' flags.\nUse 'genprotimg --help' for more information"));
return -1;
}
/* Check for unused arguments */
if (args->unused_values->len > 0) {
g_autofree gchar *unused = NULL;
@@ -79,6 +92,14 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
return -1;
}
/* Check for mandatory arguments */
if (args->allow_dump == PV_TRUE && !args->cust_comm_key_path) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Option '--allow-dump' requires the '--comm-key' option.\nUse 'genprotimg "
"--help' for more information"));
return -1;
}
if (!args->output_path) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Option '--output' is required.\nUse 'genprotimg --help' for more information"));
@@ -97,9 +118,14 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
return -1;
}
if (!args->no_verify) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Use the option '--no-verify' as the verification support is not available yet."));
if (!args->no_verify &&
(!args->untrusted_cert_paths ||
g_strv_length(args->untrusted_cert_paths) == 0)) {
g_set_error(
err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Either specify the IBM Z signing key and intermediate CA certificate\n"
"by using the '--cert' option, or use the '--no-verify' flag to disable the\n"
"host-key document verification completely (at your own risk)."));
return -1;
}
@@ -141,12 +167,14 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value,
{
gchar **args_option = NULL;
if (g_str_equal(option, "--comm-key"))
args_option = &args->cust_comm_key_path;
if (g_str_equal(option, "--root-ca"))
args_option = &args->root_ca_path;
if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
args_option = &args->output_path;
if (g_str_equal(option, "--x-comp-key"))
args_option = &args->xts_key_path;
if (g_str_equal(option, "--x-comm-key"))
args_option = &args->cust_comm_key_path;
if (g_str_equal(option, "--x-header-key"))
args_option = &args->cust_root_key_path;
if (g_str_equal(option, "--x-pcf"))
@@ -188,8 +216,51 @@ static gboolean cb_remaining_values(const gchar *option G_GNUC_UNUSED,
return TRUE;
}
#define MUT_EXCL_BOOL_FLAG_CB_NAME(FLAG, VALUE) (cb_##FLAG##_##VALUE)
#define DEFINE_MUT_EXCL_BOOL_FLAG_CB(FLAG, VALUE) \
static gboolean MUT_EXCL_BOOL_FLAG_CB_NAME(FLAG, VALUE)( \
const gchar *option G_GNUC_UNUSED, const gchar *value G_GNUC_UNUSED, \
PvArgs *args, GError **err) \
{ \
if (!(args->allow_##FLAG == PV_NOT_SET || \
args->allow_##FLAG == VALUE)) { \
g_set_error(err, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, \
"'--enable-" #FLAG "' and '--disable-" #FLAG \
"' are mutually exclusive"); \
return FALSE; \
} \
args->allow_##FLAG = VALUE; \
return TRUE; \
}
#define DEFINE_MUT_EXCL_BOOL_FLAG_CBS(FLAG) \
DEFINE_MUT_EXCL_BOOL_FLAG_CB(FLAG, PV_TRUE) \
DEFINE_MUT_EXCL_BOOL_FLAG_CB(FLAG, PV_FALSE)
#define MUT_EXCL_BOOL_FLAG(FLAG, ENABLE_DESC, DISABLE_DESC) \
{ \
.long_name = "enable-" #FLAG, \
.short_name = 0, \
.flags = G_OPTION_FLAG_NO_ARG, \
.arg = G_OPTION_ARG_CALLBACK, \
.arg_data = MUT_EXCL_BOOL_FLAG_CB_NAME(FLAG, PV_TRUE), \
.description = ENABLE_DESC, \
}, \
{ \
.long_name = "disable-" #FLAG, \
.short_name = 0, \
.flags = G_OPTION_FLAG_NO_ARG, \
.arg = G_OPTION_ARG_CALLBACK, \
.arg_data = MUT_EXCL_BOOL_FLAG_CB_NAME(FLAG, PV_FALSE), \
.description = DISABLE_DESC, \
}
#define INDENT " "
/* Define the callbacks for mutually exclusive command line flags */
DEFINE_MUT_EXCL_BOOL_FLAG_CBS(dump)
DEFINE_MUT_EXCL_BOOL_FLAG_CBS(pckmo)
gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
GError **err)
{
@@ -209,7 +280,20 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_data = &args->host_keys,
.description =
_("FILE specifies a host-key document. At least\n" INDENT
"one is required."),
"one is required Specify this option multiple times\n" INDENT
"to enable the image to run on more than one host."),
.arg_description = _("FILE") },
{ .long_name = "cert",
.short_name = 'C',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->untrusted_cert_paths,
.description = _(
"FILE contains a certificate that is used to\n" INDENT
"establish a chain of trust for the verification\n" INDENT
"of the host-key documents. The IBM Z signing\n" INDENT
"key and intermediate CA certificate (signed\n" INDENT
"by the root CA) are required."),
.arg_description = _("FILE") },
{ .long_name = "output",
.short_name = 'o',
@@ -227,7 +311,7 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_description = _("IMAGE") },
{ .long_name = "ramdisk",
.short_name = 'r',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT
@@ -235,12 +319,59 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_description = _("RAMDISK") },
{ .long_name = "parmfile",
.short_name = 'p',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
"(optional)."),
.arg_description = _("PARMFILE") },
MUT_EXCL_BOOL_FLAG(
dump,
_("Enable PV guest dumps (optional). This option\n" INDENT
"requires the '--comm-key' option."),
_("Disable PV guest dumps (default) (optional).")),
MUT_EXCL_BOOL_FLAG(
pckmo,
_("Enable the support for the DEA, TDEA, AES, and\n" INDENT
"ECC PCKMO key encryption functions (default)\n" INDENT
"(optional)."),
_("Disable the support for the DEA, TDEA, AES, and\n" INDENT
"ECC PCKMO key encryption functions (optional).")),
{ .long_name = "comm-key",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"FILE contains the key with which you encrypt\n" INDENT
"the PV guest dump (optional). Required by\n" INDENT
"the '--enable-dump' option."),
.arg_description = _("FILE") },
{ .long_name = "crl",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->crl_paths,
.description = _(
"FILE contains a certificate revocation list\n" INDENT
"(optional)."),
.arg_description = _("FILE") },
{ .long_name = "offline",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &args->offline,
.description = _("Don't download CRLs (optional)."),
.arg_description = NULL },
{ .long_name = "root-ca",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Set FILE as the trusted root CA and don't use the\n" INDENT
"root CAs that are installed on the system (optional)."),
.arg_description = _("FILE") },
{ .long_name = "no-verify",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
@@ -274,15 +405,6 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
};
GOptionEntry x_entries[] = {
{ .long_name = "x-comm-key",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Use FILE as the customer communication key.\n" INDENT
"Optional; default: auto-generated."),
.arg_description = _("FILE") },
{ .long_name = "x-comp-key",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
@@ -311,7 +433,8 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.description =
_("Specify the plaintext control flags\n" INDENT
"as a hexadecimal value.\n" INDENT
"Optional; default: '0x0'."),
"Optional; mutually exclusive with\n" INDENT
"'--(enable|disable)-pckmo'; default: '0xe0'."),
.arg_description = _("VALUE") },
{ .long_name = "x-psw",
.short_name = 0,
@@ -364,6 +487,8 @@ PvArgs *pv_args_new(void)
g_autoptr(PvArgs) args = g_new0(PvArgs, 1);
args->unused_values = g_ptr_array_new_with_free_func(g_free);
args->allow_dump = PV_NOT_SET;
args->allow_pckmo = PV_NOT_SET;
return g_steal_pointer(&args);
}
@@ -378,6 +503,9 @@ void pv_args_free(PvArgs *args)
g_free(args->cust_root_key_path);
g_free(args->cust_comm_key_path);
g_free(args->gcm_iv_path);
g_free(args->root_ca_path);
g_strfreev(args->crl_paths);
g_strfreev(args->untrusted_cert_paths);
g_strfreev(args->host_keys);
g_free(args->xts_key_path);
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);

View File

@@ -22,11 +22,20 @@ typedef struct pv_arg {
PvArg *pv_arg_new(PvComponentType type, const gchar *path);
void pv_arg_free(PvArg *arg);
typedef enum pv_tristate {
PV_NOT_SET = 0,
PV_TRUE,
PV_FALSE,
} PvTristate;
typedef struct {
gint log_level;
gint no_verify;
gboolean offline;
gchar *pcf;
gchar *scf;
PvTristate allow_dump;
PvTristate allow_pckmo;
gchar *psw_addr; /* PSW address which will be used for the start of
* the actual component (e.g. Linux kernel)
*/
@@ -34,6 +43,11 @@ typedef struct {
gchar *cust_comm_key_path;
gchar *gcm_iv_path;
gchar **host_keys;
gchar *root_ca_path; /* Trusted root CA used for the verification of the
* chain of trust (if specified).
*/
gchar **untrusted_cert_paths;
gchar **crl_paths;
gchar *xts_key_path;
GSList *comps;
gchar *output_path;

View File

@@ -73,12 +73,12 @@ PvComponent *pv_component_new_file(PvComponentType type, const gchar *path,
return pv_component_new(type, size, DATA_FILE, (void **)&file, err);
}
PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf,
PvComponent *pv_component_new_buf(PvComponentType type, const PvBuffer *buf,
GError **err)
{
g_assert(buf);
g_autoptr(Buffer) dup_buf = buffer_dup(buf, FALSE);
g_autoptr(PvBuffer) dup_buf = pv_buffer_dup(buf, FALSE);
return pv_component_new(type, buf->size, DATA_BUFFER, (void **)&dup_buf,
err);
}
@@ -90,7 +90,7 @@ void pv_component_free(PvComponent *component)
switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER:
buffer_clear(&component->buf);
pv_buffer_clear(&component->buf);
break;
case DATA_FILE:
comp_file_free(component->file);
@@ -162,21 +162,21 @@ gint pv_component_align_and_encrypt(PvComponent *component, const gchar *tmp_pat
switch ((PvComponentDataType)component->d_type) {
case DATA_BUFFER: {
g_autoptr(Buffer) enc_buf = NULL;
g_autoptr(PvBuffer) enc_buf = NULL;
if (!(IS_PAGE_ALIGNED(pv_component_size(component)))) {
g_autoptr(Buffer) new = NULL;
g_autoptr(PvBuffer) new = NULL;
/* create a page aligned copy */
new = buffer_dup(component->buf, TRUE);
buffer_clear(&component->buf);
new = pv_buffer_dup(component->buf, TRUE);
pv_buffer_clear(&component->buf);
component->buf = g_steal_pointer(&new);
}
enc_buf = encrypt_buf(parms, component->buf, err);
if (!enc_buf)
return -1;
buffer_clear(&component->buf);
pv_buffer_clear(&component->buf);
component->buf = g_steal_pointer(&enc_buf);
return 0;
}
@@ -220,10 +220,10 @@ gint pv_component_align(PvComponent *component, const gchar *tmp_path,
switch (component->d_type) {
case DATA_BUFFER: {
g_autoptr(Buffer) buf = NULL;
g_autoptr(PvBuffer) buf = NULL;
buf = buffer_dup(component->buf, TRUE);
buffer_clear(&component->buf);
buf = pv_buffer_dup(component->buf, TRUE);
pv_buffer_clear(&component->buf);
component->buf = g_steal_pointer(&buf);
return 0;
} break;
@@ -248,19 +248,6 @@ gint pv_component_align(PvComponent *component, const gchar *tmp_path,
g_assert_not_reached();
}
/* Convert uint64_t address to byte array */
static void uint64_to_uint8_buf(uint8_t dst[8], uint64_t addr)
{
uint8_t *p = (uint8_t *)&addr;
g_assert(dst);
for (gint i = 0; i < 8; i++) {
/* cppcheck-suppress objectIndex */
dst[i] = p[i];
}
}
int64_t pv_component_update_ald(const PvComponent *comp, EVP_MD_CTX *ctx,
GError **err)
{
@@ -273,11 +260,8 @@ int64_t pv_component_update_ald(const PvComponent *comp, EVP_MD_CTX *ctx,
do {
uint64_t cur_be = GUINT64_TO_BE(cur);
uint8_t addr_buf[8];
uint64_to_uint8_buf(addr_buf, cur_be);
if (EVP_DigestUpdate(ctx, addr_buf, sizeof(addr_buf)) != 1) {
if (EVP_DigestUpdate(ctx, &cur_be, sizeof(cur_be)) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("EVP_DigestUpdate failed"));
@@ -301,7 +285,7 @@ int64_t pv_component_update_pld(const PvComponent *comp, EVP_MD_CTX *ctx,
switch (comp->d_type) {
case DATA_BUFFER: {
const Buffer *buf = comp->buf;
const PvBuffer *buf = comp->buf;
g_assert(buf->size <= INT64_MAX);
g_assert(buf->size == size);
@@ -383,6 +367,7 @@ int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_bin2bn failed"));
return -1;
}
for (uint64_t cur = 0; cur < size; cur += PAGE_SIZE) {
@@ -395,6 +380,7 @@ int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_bn2binpad failed"));
return -1;
}
if (EVP_DigestUpdate(ctx, tmp, sizeof(tmp)) != 1) {
@@ -409,6 +395,7 @@ int64_t pv_component_update_tld(const PvComponent *comp, EVP_MD_CTX *ctx,
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("BN_add_word failed"));
return -1;
}
nep++;
@@ -425,7 +412,7 @@ gint pv_component_write(const PvComponent *component, FILE *f, GError **err)
switch (component->d_type) {
case DATA_BUFFER: {
const Buffer *buf = component->buf;
const PvBuffer *buf = component->buf;
if (seek_and_write_buffer(f, buf, offset, err) < 0)
return -1;

View File

@@ -41,7 +41,7 @@ typedef struct {
gint d_type; /* PvComponentDataType */
union {
struct comp_file *file;
Buffer *buf;
PvBuffer *buf;
void *data;
};
uint64_t src_addr;
@@ -51,7 +51,7 @@ typedef struct {
PvComponent *pv_component_new_file(PvComponentType type, const gchar *path,
GError **err);
PvComponent *pv_component_new_buf(PvComponentType type, const Buffer *buf,
PvComponent *pv_component_new_buf(PvComponentType type, const PvBuffer *buf,
GError **err);
void pv_component_free(PvComponent *component);
gint pv_component_type(const PvComponent *component);

View File

@@ -210,13 +210,13 @@ GSList *pv_img_comps_get_comps(const PvImgComps *comps)
return comps->comps;
}
gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest,
Buffer **ald_digest, Buffer **tld_digest,
gint pv_img_comps_finalize(PvImgComps *comps, PvBuffer **pld_digest,
PvBuffer **ald_digest, PvBuffer **tld_digest,
uint64_t *nep, GError **err)
{
g_autoptr(Buffer) tmp_pld_digest = NULL;
g_autoptr(Buffer) tmp_ald_digest = NULL;
g_autoptr(Buffer) tmp_tld_digest = NULL;
g_autoptr(PvBuffer) tmp_pld_digest = NULL;
g_autoptr(PvBuffer) tmp_ald_digest = NULL;
g_autoptr(PvBuffer) tmp_tld_digest = NULL;
comps->finalized = TRUE;
for (GSList *iterator = comps->comps; iterator; iterator = iterator->next) {

View File

@@ -32,8 +32,8 @@ gint pv_img_comps_add_component(PvImgComps *comps, PvComponent **comp,
GError **err);
PvComponent *pv_img_comps_get_nth_comp(PvImgComps *comps, guint n);
gint pv_img_comps_set_offset(PvImgComps *comps, gsize offset, GError **err);
gint pv_img_comps_finalize(PvImgComps *comps, Buffer **pld_digest,
Buffer **ald_digest, Buffer **tld_digest,
gint pv_img_comps_finalize(PvImgComps *comps, PvBuffer **pld_digest,
PvBuffer **ald_digest, PvBuffer **tld_digest,
uint64_t *nep, GError **err);
void pv_img_comps_free(PvImgComps *comps);

View File

@@ -28,6 +28,8 @@ typedef enum {
PV_ERROR_IPIB_SIZE,
PV_ERROR_PV_HDR_SIZE,
PV_ERROR_INTERNAL,
PV_ERROR_CURL_INIT_FAILED,
PV_ERROR_DOWNLOAD_FAILED,
} PvErrors;
typedef enum {
@@ -57,6 +59,31 @@ typedef enum {
PV_CRYPTO_ERROR_RANDOMIZATION,
PV_CRYPTO_ERROR_INVALID_PARM,
PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD,
PV_CRYPTO_ERROR_EXPIRED,
PV_CRYPTO_ERROR_NOT_VALID_YET,
PV_CRYPTO_ERROR_LOAD_CRL,
PV_CRYPTO_ERROR_NO_PUBLIC_KEY,
PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM,
PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH,
PV_CRYPTO_ERROR_INVALID_URI,
PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED,
PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID,
PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID,
PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH,
PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH,
PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE,
PV_CRYPTO_ERROR_NO_CRL,
PV_CRYPTO_ERROR_LOAD_ROOT_CA,
PV_CRYPTO_ERROR_LOAD_DEFAULT_CA,
PV_CRYPTO_ERROR_MALFORMED_ROOT_CA,
PV_CRYPTO_ERROR_WRONG_CA_USED,
PV_CRYPTO_ERROR_SKID_AKID_MISMATCH,
PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND,
PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL,
PV_CRYPTO_ERROR_NO_CRLDP,
PV_CRYPTO_ERROR_CERT_REVOKED,
} PvCryptoErrors;
#endif

View File

@@ -41,7 +41,7 @@ uint32_t pv_hdr_size(const PvHdr *hdr)
gboolean pv_hdr_uses_encryption(const PvHdr *hdr)
{
return !(GUINT64_FROM_BE(hdr->head.pcf) & PV_CFLAG_NO_DECRYPTION);
return !(GUINT64_FROM_BE(hdr->head.pcf) & PV_PCF_NO_DECRYPTION);
}
uint64_t pv_hdr_enc_size(const PvHdr *hdr)
@@ -76,17 +76,17 @@ uint64_t pv_hdr_get_nks(const PvHdr *hdr)
}
/* In-place modification of ``buf`` */
static gint pv_hdr_encrypt(const PvHdr *hdr, const PvImage *img, Buffer *buf,
static gint pv_hdr_encrypt(const PvHdr *hdr, const PvImage *img, PvBuffer *buf,
GError **err)
{
uint32_t hdr_len = pv_hdr_size(hdr);
uint32_t aad_len = pv_hdr_aad_size(hdr);
guint tag_len = pv_hdr_tag_size(hdr);
uint32_t enc_len = pv_hdr_enc_size_casted(hdr);
const Buffer aad_part = { .data = buf->data, .size = aad_len };
Buffer enc_part = { .data = (uint8_t *)buf->data + aad_len,
const PvBuffer aad_part = { .data = buf->data, .size = aad_len };
PvBuffer enc_part = { .data = (uint8_t *)buf->data + aad_len,
.size = enc_len };
Buffer tag_part = { .data = (uint8_t *)buf->data + hdr_len - tag_len,
PvBuffer tag_part = { .data = (uint8_t *)buf->data + hdr_len - tag_len,
.size = tag_len };
struct cipher_parms parms;
int64_t c_len;
@@ -119,9 +119,9 @@ static gint pv_hdr_aad_init(PvHdr *hdr, const PvImage *img, GError **err)
g_autofree union ecdh_pub_key *cust_pub_key = NULL;
struct pv_hdr_key_slot *hdr_slot = hdr->slots;
struct pv_hdr_head *head = &hdr->head;
g_autoptr(Buffer) pld = NULL;
g_autoptr(Buffer) ald = NULL;
g_autoptr(Buffer) tld = NULL;
g_autoptr(PvBuffer) pld = NULL;
g_autoptr(PvBuffer) ald = NULL;
g_autoptr(PvBuffer) tld = NULL;
uint64_t nep = 0;
g_assert(sizeof(head->iv) == img->gcm_iv->size);
@@ -250,7 +250,7 @@ PvHdr *pv_hdr_new(const PvImage *img, GError **err)
return g_steal_pointer(&ret);
}
static void pv_hdr_memcpy(const PvHdr *hdr, const Buffer *dst)
static void pv_hdr_memcpy(const PvHdr *hdr, const PvBuffer *dst)
{
uint64_t nks = pv_hdr_get_nks(hdr);
uint8_t *data;
@@ -270,13 +270,13 @@ static void pv_hdr_memcpy(const PvHdr *hdr, const Buffer *dst)
}
}
Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err)
PvBuffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err)
{
uint32_t hdr_size = pv_hdr_size(hdr);
g_autoptr(Buffer) ret = NULL;
g_autoptr(PvBuffer) ret = NULL;
ret = buffer_alloc(hdr_size);
ret = pv_buffer_alloc(hdr_size);
pv_hdr_memcpy(hdr, ret);
if (mode == PV_ENCRYPT) {

View File

@@ -23,8 +23,8 @@
PvHdr *pv_hdr_new(const PvImage *img, GError **err);
void pv_hdr_free(PvHdr *hdr);
G_GNUC_UNUSED gboolean pv_hdr_uses_encryption(const PvHdr *hdr);
Buffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err);
PvBuffer *pv_hdr_serialize(const PvHdr *hdr, const PvImage *img,
enum PvCryptoMode mode, GError **err);
uint32_t pv_hdr_size(const PvHdr *hdr);
uint32_t pv_hdr_aad_size(const PvHdr *hdr);
uint64_t pv_hdr_enc_size(const PvHdr *hdr);

View File

@@ -10,6 +10,7 @@
#include <errno.h>
#include <glib.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -55,12 +56,12 @@ static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
GError **err)
{
struct cipher_parms parms = { 0 };
g_autoptr(Buffer) tweak = NULL;
g_autoptr(PvBuffer) tweak = NULL;
prepare_func func = NULL;
void *opaque = NULL;
gint rc;
if (img->pcf & PV_CFLAG_NO_DECRYPTION) {
if (img->pcf & PV_PCF_NO_DECRYPTION) {
/* we only need to align the components */
func = pv_component_align;
opaque = NULL;
@@ -75,7 +76,7 @@ static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
EVP_CIPHER_iv_length(cipher));
g_assert(img->xts_key->size <= UINT_MAX);
tweak = buffer_alloc(sizeof(comp->tweak.data));
tweak = pv_buffer_alloc(sizeof(comp->tweak.data));
memcpy(tweak->data, comp->tweak.data, tweak->size);
func = pv_component_align_and_encrypt;
parms.cipher = cipher;
@@ -92,11 +93,11 @@ static gint pv_img_prepare_component(const PvImage *img, PvComponent *comp,
return 0;
}
static Buffer *pv_img_read_key(const gchar *path, guint key_size,
GError **err)
static PvBuffer *pv_img_read_key(const gchar *path, guint key_size,
GError **err)
{
g_autoptr(Buffer) tmp_ret = NULL;
Buffer *ret = NULL;
g_autoptr(PvBuffer) tmp_ret = NULL;
PvBuffer *ret = NULL;
gsize bytes_read;
FILE *f = NULL;
gsize size;
@@ -115,7 +116,7 @@ static Buffer *pv_img_read_key(const gchar *path, guint key_size,
if (!f)
return NULL;
tmp_ret = buffer_alloc(size);
tmp_ret = pv_buffer_alloc(size);
if (file_read(f, tmp_ret->data, 1, tmp_ret->size, &bytes_read, err) < 0)
goto err;
@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err)
return generate_ec_key(nid, err);
}
static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
X509_STORE *store, gint nid,
static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid,
GError **err)
{
g_autoslist(EVP_PKEY) ret = NULL;
g_assert(host_cert_paths);
for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL;
iterator++) {
for (GSList *iterator = host_keys_with_path; iterator;
iterator = iterator->next) {
x509_with_path *cert_with_path = iterator->data;
g_autoptr(EVP_PKEY) host_key = NULL;
const gchar *path = *iterator;
X509 *cert = cert_with_path->cert;
g_assert(path);
host_key = read_ec_pubkey_cert(store, nid, path, err);
host_key = read_ec_pubkey_cert(cert, nid, err);
if (!host_key)
return NULL;
@@ -163,8 +160,8 @@ static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
return g_steal_pointer(&ret);
}
static Buffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path,
GError **err)
static PvBuffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path,
GError **err)
{
gint key_len = EVP_CIPHER_key_length(cipher);
@@ -176,8 +173,8 @@ static Buffer *pv_img_get_key(const EVP_CIPHER *cipher, const gchar *path,
return generate_aes_key((guint)key_len, err);
}
static Buffer *pv_img_get_iv(const EVP_CIPHER *cipher, const gchar *path,
GError **err)
static PvBuffer *pv_img_get_iv(const EVP_CIPHER *cipher, const gchar *path,
GError **err)
{
gint iv_len = EVP_CIPHER_iv_length(cipher);
@@ -232,7 +229,9 @@ static gint pv_img_set_psw_addr(PvImage *img, const gchar *psw_addr_s,
}
static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
const gchar *scf_s, GError **err)
const gchar *scf_s,
PvTristate allow_dump,
PvTristate allow_pckmo, GError **err)
{
uint64_t flags;
@@ -250,13 +249,180 @@ static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
img->scf = flags;
}
if (allow_dump == PV_TRUE)
img->pcf |= PV_PCF_ALLOW_DUMPING;
else if (allow_dump == PV_FALSE)
img->pcf &= ~PV_PCF_ALLOW_DUMPING;
if (allow_pckmo == PV_TRUE)
img->pcf |= PV_PCF_PCKM_ECC | PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA;
else if (allow_pckmo == PV_FALSE)
img->pcf &= ~(PV_PCF_PCKM_ECC | PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA);
return 0;
}
static gint pv_img_hostkey_verify(GSList *host_key_certs,
const gchar *root_ca_path,
const gchar *const *crl_paths,
const gchar *const *untrusted_cert_paths,
gboolean offline, GError **err)
{
g_autoslist(x509_with_path) untrusted_certs_with_path = NULL;
g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL;
g_autoptr(STACK_OF_X509) untrusted_certs = NULL;
g_autoslist(x509_pair) ibm_z_pairs = NULL;
g_autoptr(X509_STORE) trusted = NULL;
gint ibm_signing_certs_count;
/* Load trusted root CAs of the system if and only if @root_ca_path is
* NULL, otherwise use the root CA specified by @root_ca_path.
*/
trusted = store_setup(root_ca_path, crl_paths, err);
if (!trusted)
goto error;
if (!offline) {
g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL;
/* Set up the download routine for the lookup of CRLs. */
store_setup_crl_download(trusted);
/* Try to download the CRLs of the IBM Z signing certificates
* specified in the host-key documents. Ignore download errors
* as it's still possible that a CRL is specified via command
* line.
*/
downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs);
/* Add the downloaded CRLs to the store so they can be used for
* the verification later.
*/
for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) {
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
if (X509_STORE_add_crl(trusted, crl) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("failed to load CRL"));
goto error;
}
}
}
/* Load all untrusted certificates (e.g. IBM Z signing key and
* intermediate CA) that are required to establish a chain of trust
* starting from the host-key document up to the root CA (if not
* otherwise specified that can be one of the system wide installed
* root CAs, e.g. DigiCert).
*/
untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err);
if (!untrusted_certs_with_path)
goto error;
/* Convert to STACK_OF(X509) */
untrusted_certs = get_x509_stack(untrusted_certs_with_path);
/* Find all IBM Z signing keys and remove them from the chain as we
* have to verify that they're valid. The last step of the chain of
* trust verification must be done manually, as the IBM Z signing keys
* are not marked as (intermediate) CA and therefore the standard
* `X509_verify_cert` function of OpenSSL cannot be used to verify the
* actual host-key documents.
*/
ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs);
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
if (ibm_signing_certs_count < 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
_("please specify at least one IBM Z signing key"));
goto error;
} else if (ibm_signing_certs_count > 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
_("please specify only one IBM Z signing key"));
goto error;
}
if (store_set_verify_param(trusted, err) < 0)
goto error;
/* Verify that the IBM Z signing keys are trustable.
* For this we must check:
*
* 1. Can a chain of trust be established ending in a root CA
* 2. Is the correct root CA used? It has either to be a system CA
* or the root CA specified via command line.
*/
for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) {
X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i);
g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL;
g_autoptr(X509_STORE_CTX) ctx = NULL;
x509_pair *pair = NULL;
g_assert(ibm_signing_cert);
/* Create the verification context and set the trusted
* and chain parameters.
*/
ctx = create_store_ctx(trusted, untrusted_certs, err);
if (!ctx)
goto error;
/* Verify the IBM Z signing key */
if (verify_cert(ibm_signing_cert, ctx, err) < 0)
goto error;
/* If there is a chain of trust using either the provided root
* CA on the command line or a system wide trusted root CA.
*/
if (check_chain_parameters(X509_STORE_CTX_get0_chain(ctx),
err) < 0)
goto error;
ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err);
if (!ibm_signing_crls) {
g_prefix_error(err, _("IBM Z signing key: "));
goto error;
}
/* Increment reference counter of @ibm_signing_cert as the
* certificate will now also be owned by @ibm_z_pairs.
*/
if (X509_up_ref(ibm_signing_cert) != 1)
g_abort();
pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls);
ibm_z_pairs = g_slist_append(ibm_z_pairs, pair);
g_assert(!ibm_signing_cert);
g_assert(!ibm_signing_crls);
}
/* Verify host-key documents by using the IBM Z signing
* certificates and the corresponding certificate revocation
* lists.
*/
for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) {
x509_with_path *host_key_with_path = iterator->data;
const gchar *host_key_path = host_key_with_path->path;
X509 *host_key = host_key_with_path->cert;
gint flags = X509_V_FLAG_CRL_CHECK;
if (verify_host_key(host_key, ibm_z_pairs, flags,
PV_CERTS_SECURITY_LEVEL, err) < 0) {
g_prefix_error(err, "'%s': ", host_key_path);
goto error;
}
}
return 0;
error:
g_prefix_error(err, _("Failed to verify host-key document: "));
return -1;
}
/* read in the keys or auto-generate them */
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
{
g_autoptr(X509_STORE) store = NULL;
g_autoslist(x509_with_path) host_key_certs = NULL;
g_assert(img->xts_cipher);
g_assert(img->cust_comm_cipher);
@@ -285,8 +451,25 @@ static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
if (!img->cust_pub_priv_key)
return -1;
/* Load all host-key documents specified on the command line */
host_key_certs = load_certificates((const gchar **)args->host_keys,
err);
if (!host_key_certs)
return -1;
if (!args->no_verify &&
pv_img_hostkey_verify(host_key_certs, args->root_ca_path,
(const gchar * const *)args->crl_paths,
(const gchar * const *)args->untrusted_cert_paths,
args->offline, err) < 0) {
return -1;
}
/* Loads the public keys stored in the host-key documents and verify
* that the correct elliptic curve is used.
*/
img->host_pub_keys =
pv_img_get_host_keys(args->host_keys, store, img->nid, err);
pv_img_get_host_keys(host_key_certs, img->nid, err);
if (!img->host_pub_keys)
return -1;
@@ -309,23 +492,23 @@ static void pv_hdr_key_slot_free(PvHdrKeySlot *slot)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvHdrKeySlot, pv_hdr_key_slot_free)
static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher,
const Buffer *cust_root_key,
const PvBuffer *cust_root_key,
EVP_PKEY *cust_key, EVP_PKEY *host_key,
GError **err)
{
g_autoptr(PvHdrKeySlot) ret = g_new0(PvHdrKeySlot, 1);
g_autofree union ecdh_pub_key *pub = NULL;
g_autoptr(Buffer) exchange_key = NULL;
g_autoptr(Buffer) digest_key = NULL;
g_autoptr(Buffer) iv = NULL;
Buffer pub_buf;
g_autoptr(PvBuffer) exchange_key = NULL;
g_autoptr(PvBuffer) digest_key = NULL;
g_autoptr(PvBuffer) iv = NULL;
PvBuffer pub_buf;
/* No AAD data is used */
Buffer aad = { .data = NULL, .size = 0 };
PvBuffer aad = { .data = NULL, .size = 0 };
/* Set the output buffers for the encrypted data and the
* generated GCM tag
*/
Buffer enc = { .data = ret->wrapped_key, .size = sizeof(ret->wrapped_key) };
Buffer tag = { .data = ret->tag, .size = sizeof(ret->tag) };
PvBuffer enc = { .data = ret->wrapped_key, .size = sizeof(ret->wrapped_key) };
PvBuffer tag = { .data = ret->tag, .size = sizeof(ret->tag) };
struct cipher_parms parms;
int64_t c_len = 0;
@@ -354,7 +537,7 @@ static PvHdrKeySlot *pv_hdr_key_slot_new(const EVP_CIPHER *gcm_cipher,
g_assert(exchange_key->size == (guint)EVP_CIPHER_key_length(gcm_cipher));
/* create zero IV */
iv = buffer_alloc((guint)EVP_CIPHER_iv_length(gcm_cipher));
iv = pv_buffer_alloc((guint)EVP_CIPHER_iv_length(gcm_cipher));
parms.iv_or_tweak = iv;
parms.key = exchange_key;
parms.cipher = gcm_cipher;
@@ -406,10 +589,14 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
if (args->no_verify)
g_warning(_("host-key document verification is disabled. Your workload is not secured."));
if (args->root_ca_path)
g_warning(_("The root CA is selected through the command line. Ensure that this root CA is trusted."));
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
if (!ret->comps)
return NULL;
ret->pcf = PV_PCF_PCKMO_AES | PV_PCF_PCKMO_DEA_TDEA | PV_PCF_PCKM_ECC;
ret->cust_comm_cipher = EVP_aes_256_gcm();
ret->gcm_cipher = EVP_aes_256_gcm();
ret->initial_psw.addr = DEFAULT_INITIAL_PSW_ADDR;
@@ -423,7 +610,9 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
return NULL;
/* set the control flags: PCF and SCF */
if (pv_img_set_control_flags(ret, args->pcf, args->scf, err) < 0)
if (pv_img_set_control_flags(ret, args->pcf, args->scf,
args->allow_dump, args->allow_pckmo,
err) < 0)
return NULL;
/* read in the keys */
@@ -458,13 +647,13 @@ void pv_img_free(PvImage *img)
g_slist_free_full(img->key_slots, (GDestroyNotify)pv_hdr_key_slot_free);
g_slist_free_full(img->host_pub_keys, (GDestroyNotify)EVP_PKEY_free);
EVP_PKEY_free(img->cust_pub_priv_key);
buffer_clear(&img->stage3a);
pv_buffer_clear(&img->stage3a);
pv_img_comps_free(img->comps);
g_free(img->tmp_dir);
buffer_free(img->xts_key);
buffer_free(img->cust_root_key);
buffer_free(img->gcm_iv);
buffer_free(img->cust_comm_key);
pv_buffer_free(img->xts_key);
pv_buffer_free(img->cust_root_key);
pv_buffer_free(img->gcm_iv);
pv_buffer_free(img->cust_comm_key);
g_free(img);
}
@@ -505,13 +694,13 @@ gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err)
return 0;
}
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald,
Buffer **tld, uint64_t *nep, GError **err)
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, PvBuffer **pld, PvBuffer **ald,
PvBuffer **tld, uint64_t *nep, GError **err)
{
return pv_img_comps_finalize(img->comps, pld, ald, tld, nep, err);
}
static gint pv_img_build_stage3b(PvImage *img, Buffer *stage3b, GError **err)
static gint pv_img_build_stage3b(PvImage *img, PvBuffer *stage3b, GError **err)
{
g_autofree struct stage3b_args *args = NULL;
@@ -529,7 +718,7 @@ static gint pv_img_build_stage3b(PvImage *img, Buffer *stage3b, GError **err)
gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err)
{
g_autoptr(PvComponent) comp = NULL;
g_autoptr(Buffer) stage3b = NULL;
g_autoptr(PvBuffer) stage3b = NULL;
stage3b = stage3b_getblob(path, err);
if (!stage3b)
@@ -646,7 +835,7 @@ static gint get_stage3a_data_size(const PvImage *img, gsize *data_size,
gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err)
{
g_autoptr(Buffer) stage3a = NULL;
g_autoptr(PvBuffer) stage3a = NULL;
gsize bin_size, data_size = 0;
if (get_stage3a_data_size(img, &data_size, err) < 0)
@@ -666,8 +855,8 @@ gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err)
}
/* Creates the PV IPIB and sets the stage3a arguments */
static gint pv_img_build_stage3a(Buffer *stage3a, gsize stage3a_bin_size,
GSList *comps, const Buffer *hdr, GError **err)
static gint pv_img_build_stage3a(PvBuffer *stage3a, gsize stage3a_bin_size,
GSList *comps, const PvBuffer *hdr, GError **err)
{
g_autofree struct ipl_parameter_block *ipib = NULL;
@@ -687,9 +876,9 @@ static gint pv_img_build_stage3a(Buffer *stage3a, gsize stage3a_bin_size,
}
/* Creates the actual PV header (serialized and AES-GCM encrypted) */
static Buffer *pv_img_create_pv_hdr(PvImage *img, GError **err)
static PvBuffer *pv_img_create_pv_hdr(PvImage *img, GError **err)
{
g_autoptr(Buffer) hdr_buf = NULL;
g_autoptr(PvBuffer) hdr_buf = NULL;
g_autoptr(PvHdr) hdr = NULL;
hdr = pv_hdr_new(img, err);
@@ -708,7 +897,7 @@ static Buffer *pv_img_create_pv_hdr(PvImage *img, GError **err)
*/
gint pv_img_finalize(PvImage *pv, const gchar *stage3b_path, GError **err)
{
g_autoptr(Buffer) hdr = NULL;
g_autoptr(PvBuffer) hdr = NULL;
/* load stage3b template into memory and add it to the list of
* components. This must be done before calling

View File

@@ -25,7 +25,7 @@
typedef struct {
gchar *tmp_dir; /* directory used for temporary files */
Buffer *stage3a; /* stage3a containing IPIB and PV header */
PvBuffer *stage3a; /* stage3a containing IPIB and PV header */
gsize stage3a_bin_size; /* size of stage3a.bin */
struct psw_t stage3a_psw; /* (short) PSW that is written to
* location 0 of the created image
@@ -35,15 +35,15 @@ typedef struct {
GSList *host_pub_keys; /* public host keys */
gint nid; /* Elliptic Curve used for the key derivation */
/* keys and cipher used for the AES-GCM encryption */
Buffer *cust_root_key;
Buffer *gcm_iv;
PvBuffer *cust_root_key;
PvBuffer *gcm_iv;
const EVP_CIPHER *gcm_cipher;
/* Information for the IPIB and PV header */
uint64_t pcf;
uint64_t scf;
Buffer *cust_comm_key;
PvBuffer *cust_comm_key;
const EVP_CIPHER *cust_comm_cipher;
Buffer *xts_key;
PvBuffer *xts_key;
const EVP_CIPHER *xts_cipher;
GSList *key_slots;
GSList *optional_items;
@@ -54,8 +54,8 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err);
void pv_img_free(PvImage *img);
gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err);
gint pv_img_finalize(PvImage *img, const gchar *stage3b_path, GError **err);
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, Buffer **pld, Buffer **ald,
Buffer **tld, uint64_t *nep, GError **err);
gint pv_img_calc_pld_ald_tld_nep(const PvImage *img, PvBuffer **pld, PvBuffer **ald,
PvBuffer **tld, uint64_t *nep, GError **err);
gint pv_img_load_and_set_stage3a(PvImage *img, const gchar *path, GError **err);
const PvComponent *pv_img_get_stage3b_comp(const PvImage *img, GError **err);
gint pv_img_add_stage3b_comp(PvImage *img, const gchar *path, GError **err);

View File

@@ -35,7 +35,7 @@ uint64_t pv_ipib_get_size(uint32_t num_comp)
}
static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps,
const Buffer *hdr)
const PvBuffer *hdr)
{
g_assert(sizeof(struct ipl_pl_hdr) <= UINT32_MAX);
g_assert(sizeof(struct ipl_pb0_pv_comp) <= UINT32_MAX);
@@ -100,7 +100,7 @@ static gint pv_ipib_init(IplParameterBlock *ipib, GSList *comps,
return 0;
}
IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err)
IplParameterBlock *pv_ipib_new(GSList *comps, const PvBuffer *hdr, GError **err)
{
uint64_t ipib_size = pv_ipib_get_size(g_slist_length(comps));
g_autoptr(IplParameterBlock) ret = NULL;

View File

@@ -19,7 +19,7 @@
typedef struct ipl_parameter_block IplParameterBlock;
uint64_t pv_ipib_get_size(uint32_t num_comp);
IplParameterBlock *pv_ipib_new(GSList *comps, const Buffer *hdr, GError **err);
IplParameterBlock *pv_ipib_new(GSList *comps, const PvBuffer *hdr, GError **err);
void pv_ipib_free(IplParameterBlock *ipib);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(IplParameterBlock, pv_ipib_free)

View File

@@ -24,12 +24,12 @@
((struct stage3a_args *)((uint64_t)data_ptr + loader_size - \
sizeof(struct stage3a_args)))
static Buffer *loader_getblob(const gchar *filename, gsize *loader_size,
gsize args_size, gsize data_size,
gboolean data_aligned, GError **err)
static PvBuffer *loader_getblob(const gchar *filename, gsize *loader_size,
gsize args_size, gsize data_size,
gboolean data_aligned, GError **err)
{
g_autoptr(GMappedFile) mapped_file = NULL;
g_autoptr(Buffer) ret = NULL;
g_autoptr(PvBuffer) ret = NULL;
gsize size, tmp_loader_size;
gchar *loader_data;
@@ -60,7 +60,7 @@ static Buffer *loader_getblob(const gchar *filename, gsize *loader_size,
size = (data_aligned ? PAGE_ALIGN(tmp_loader_size) : tmp_loader_size) +
data_size;
ret = buffer_alloc(size);
ret = pv_buffer_alloc(size);
/* copy the loader "template" */
memcpy(ret->data, loader_data, tmp_loader_size);
@@ -71,8 +71,8 @@ static Buffer *loader_getblob(const gchar *filename, gsize *loader_size,
return g_steal_pointer(&ret);
}
Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err)
PvBuffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err)
{
return loader_getblob(filename, loader_size,
sizeof(struct stage3a_args), data_size, TRUE,
@@ -83,8 +83,8 @@ Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
/* Set the right offsets and sizes in the stage3a template + add
* the IPIB block with the PV header
*/
static gint stage3a_set_data(Buffer *loader, gsize loader_size,
const Buffer *hdr, struct ipl_parameter_block *ipib,
static gint stage3a_set_data(PvBuffer *loader, gsize loader_size,
const PvBuffer *hdr, struct ipl_parameter_block *ipib,
GError **err)
{
uint32_t ipib_size = GUINT32_FROM_BE(ipib->hdr.len);
@@ -126,15 +126,15 @@ static gint stage3a_set_data(Buffer *loader, gsize loader_size,
return 0;
}
gint build_stage3a(Buffer *loader, gsize loader_size, const Buffer *hdr,
gint build_stage3a(PvBuffer *loader, gsize loader_size, const PvBuffer *hdr,
struct ipl_parameter_block *ipib, GError **err)
{
return stage3a_set_data(loader, loader_size, hdr, ipib, err);
}
Buffer *stage3b_getblob(const gchar *filename, GError **err)
PvBuffer *stage3b_getblob(const gchar *filename, GError **err)
{
g_autoptr(Buffer) ret = NULL;
g_autoptr(PvBuffer) ret = NULL;
gsize rb_size;
ret = loader_getblob(filename, &rb_size, sizeof(struct stage3b_args), 0,
@@ -146,7 +146,7 @@ Buffer *stage3b_getblob(const gchar *filename, GError **err)
return g_steal_pointer(&ret);
}
void build_stage3b(Buffer *stage3b, const struct stage3b_args *args)
void build_stage3b(PvBuffer *stage3b, const struct stage3b_args *args)
{
g_assert(stage3b->size > sizeof(*args));

View File

@@ -19,12 +19,12 @@
#include "boot/stage3b.h"
#include "utils/buffer.h"
Buffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err);
gint build_stage3a(Buffer *dc, gsize dc_size, const Buffer *hdr,
PvBuffer *stage3a_getblob(const gchar *filename, gsize *loader_size,
gsize data_size, GError **err);
gint build_stage3a(PvBuffer *dc, gsize dc_size, const PvBuffer *hdr,
struct ipl_parameter_block *ipib, GError **err);
Buffer *stage3b_getblob(const gchar *filename, GError **err);
void build_stage3b(Buffer *stage3b, const struct stage3b_args *args);
PvBuffer *stage3b_getblob(const gchar *filename, GError **err);
void build_stage3b(PvBuffer *stage3b, const struct stage3b_args *args);
void memblob_init(struct memblob *arg, uint64_t src, uint64_t size);
#endif

View File

@@ -17,18 +17,18 @@
#include "common.h"
#include "file_utils.h"
Buffer *buffer_alloc(gsize size)
PvBuffer *pv_buffer_alloc(gsize size)
{
Buffer *ret = g_new0(Buffer, 1);
PvBuffer *ret = g_new0(PvBuffer, 1);
ret->data = g_malloc0(size);
ret->size = size;
return ret;
}
Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned)
PvBuffer *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned)
{
Buffer *ret;
PvBuffer *ret;
gsize size;
if (!buf)
@@ -38,19 +38,19 @@ Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned)
if (page_aligned)
size = PAGE_ALIGN(size);
ret = buffer_alloc(size);
ret = pv_buffer_alloc(size);
/* content will be 0-right-padded */
memcpy(ret->data, buf->data, buf->size);
return ret;
}
gint buffer_write(const Buffer *buf, FILE *file, GError **err)
gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err)
{
return file_write(file, buf->data, buf->size, 1, NULL, err);
}
void buffer_free(Buffer *buf)
void pv_buffer_free(PvBuffer *buf)
{
if (!buf)
return;
@@ -59,11 +59,11 @@ void buffer_free(Buffer *buf)
g_free(buf);
}
void buffer_clear(Buffer **buf)
void pv_buffer_clear(PvBuffer **buf)
{
if (!buf || !*buf)
return;
buffer_free(*buf);
pv_buffer_free(*buf);
*buf = NULL;
}

View File

@@ -15,17 +15,17 @@
#include "common.h"
typedef struct Buffer {
typedef struct PvBuffer {
void *data;
gsize size; /* in bytes */
} Buffer;
} PvBuffer;
Buffer *buffer_alloc(gsize size);
void buffer_free(Buffer *buf);
void buffer_clear(Buffer **buf);
gint buffer_write(const Buffer *buf, FILE *file, GError **err);
Buffer *buffer_dup(const Buffer *buf, gboolean page_aligned);
PvBuffer *pv_buffer_alloc(gsize size);
void pv_buffer_free(PvBuffer *buf);
void pv_buffer_clear(PvBuffer **buf);
gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err);
PvBuffer *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(Buffer, buffer_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(PvBuffer, pv_buffer_free)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -11,14 +11,18 @@
#define PV_UTILS_CRYPTO_H
#include <glib.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/evp.h>
#include <openssl/ossl_typ.h>
#include <openssl/rand.h>
#include <openssl/safestack.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <stdint.h>
#include "common.h"
@@ -33,6 +37,9 @@
#define AES_256_XTS_TWEAK_SIZE 16
#define AES_256_XTS_KEY_SIZE 64
#define CRL_DOWNLOAD_TIMEOUT_MS 3000
#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */
enum PvCryptoMode {
PV_ENCRYPT,
PV_DECRYPT,
@@ -40,7 +47,34 @@ enum PvCryptoMode {
typedef GSList HostKeyList;
/* play nice with g_autoptr */
typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT;
typedef STACK_OF(X509) STACK_OF_X509;
typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL;
void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack);
void STACK_OF_X509_free(STACK_OF_X509 *stack);
void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack);
typedef struct {
X509 *cert;
const gchar *path;
} x509_with_path;
x509_with_path *x509_with_path_new(X509 *cert, const gchar *path);
void x509_with_path_free(x509_with_path *cert);
typedef struct {
X509 *cert;
STACK_OF_X509_CRL *crls;
} x509_pair;
x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls);
void x509_pair_free(x509_pair *pair);
/* Register auto cleanup functions */
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free)
union cmp_index {
struct {
@@ -75,30 +117,57 @@ union tweak {
struct cipher_parms {
const EVP_CIPHER *cipher;
const Buffer *key;
const Buffer *iv_or_tweak;
const PvBuffer *key;
const PvBuffer *iv_or_tweak;
};
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path,
GError **err);
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
Buffer *generate_aes_key(guint size, GError **err);
Buffer *generate_aes_iv(guint size, GError **err);
int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert,
gint verify_flags, GError **err);
void pv_crypto_init(void);
void pv_crypto_cleanup(void);
gint verify_host_key(X509 *host_key, GSList *issuer_pairs,
gint verify_flags, int level, GError **err);
X509 *load_cert_from_file(const char *path, GError **err);
X509_CRL *load_crl_from_file(const gchar *path, GError **err);
GSList *load_certificates(const gchar *const *cert_paths, GError **err);
STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list);
X509_STORE *store_setup(const gchar *root_ca_path,
const gchar * const *crl_paths,
GError **err);
int store_set_verify_param(X509_STORE *store, GError **err);
X509_CRL *load_crl_by_cert(X509 *cert, GError **err);
STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path);
gint check_chain_parameters(const STACK_OF_X509 *chain, GError **err);
X509_NAME *c2b_name(const X509_NAME *name);
STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs);
STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert,
GError **err);
X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain,
GError **err);
gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err);
X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err);
void store_setup_crl_download(X509_STORE *st);
EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err);
PvBuffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
PvBuffer *generate_aes_key(guint size, GError **err);
PvBuffer *generate_aes_iv(guint size, GError **err);
EVP_PKEY *generate_ec_key(gint nid, GError **err);
gint generate_tweak(union tweak *tweak, uint16_t i, GError **err);
union ecdh_pub_key *evp_pkey_to_ecdh_pub_key(EVP_PKEY *key, GError **err);
EVP_MD_CTX *digest_ctx_new(const EVP_MD *md, GError **err);
Buffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err);
Buffer *sha256_buffer(const Buffer *buf, GError **err);
int64_t gcm_encrypt(const Buffer *in, const Buffer *aad,
const struct cipher_parms *parms, Buffer *out,
Buffer *tag, GError **err);
PvBuffer *digest_ctx_finalize(EVP_MD_CTX *ctx, GError **err);
PvBuffer *sha256_buffer(const PvBuffer *buf, GError **err);
int64_t gcm_encrypt(const PvBuffer *in, const PvBuffer *aad,
const struct cipher_parms *parms, PvBuffer *out,
PvBuffer *tag, GError **err);
gint encrypt_file(const struct cipher_parms *parms, const gchar *in_path,
const gchar *path_out, gsize *in_size, gsize *out_size,
GError **err);
Buffer *encrypt_buf(const struct cipher_parms *parms, const Buffer *in,
GError **err);
G_GNUC_UNUSED Buffer *decrypt_buf(const struct cipher_parms *parms,
const Buffer *in, GError **err);
PvBuffer *encrypt_buf(const struct cipher_parms *parms, const PvBuffer *in,
GError **err);
G_GNUC_UNUSED PvBuffer *decrypt_buf(const struct cipher_parms *parms,
const PvBuffer *in, GError **err);
#endif

121
genprotimg/src/utils/curl.c Normal file
View File

@@ -0,0 +1,121 @@
/*
* Libcurl utils
*
* Copyright IBM Corp. 2020
*
* 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 <stdio.h>
#include <glib.h>
#include <glib/gtypes.h>
#include <curl/curl.h>
#include "lib/zt_common.h"
#include "pv/pv_error.h"
#include "curl.h"
struct UserData {
GByteArray *buffer;
guint max_size;
};
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
g_assert(userdata);
struct UserData *data = (struct UserData *)userdata;
GByteArray *buffer = data->buffer;
guint64 actual_size;
size_t err;
g_assert(buffer);
if (!g_uint64_checked_mul(&actual_size, size, nmemb))
g_abort();
/* Signal an error condition by returning a amount that differs
* from the amount passed to the callback. This results in a
* CURLE_WRITE_ERROR.
*/
err = actual_size + 1;
if (actual_size > G_MAXUINT)
return err;
data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size);
if (data->buffer->len > data->max_size)
return err;
return actual_size;
}
gint curl_init(void)
{
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
return -1;
return 0;
}
void curl_cleanup(void)
{
curl_global_cleanup();
}
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
GError **err)
{
g_autoptr(GByteArray) ret = NULL;
g_autoptr(CURL) handle = NULL;
g_autofree gchar *agent = NULL;
struct UserData userdata;
CURLcode rc;
/* set up curl session */
handle = curl_easy_init();
if (!handle)
g_abort();
/* follow redirection */
rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l);
if (rc != CURLE_OK)
goto curl_err;
agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING);
rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
if (rc != CURLE_OK)
goto curl_err;
ret = g_byte_array_new();
userdata.buffer = ret;
userdata.max_size = max_size;
rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_URL, url);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_perform(handle);
if (rc != CURLE_OK) {
g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED,
_("download failed: %s"), curl_easy_strerror(rc));
return NULL;
}
return g_steal_pointer(&ret);
curl_err:
g_set_error(err, PV_ERROR,
PV_ERROR_CURL_INIT_FAILED,
_("cURL initialization failed: %s"),
curl_easy_strerror(rc));
return NULL;
}

View File

@@ -0,0 +1,25 @@
/*
* Libcurl utils
*
* Copyright IBM Corp. 2020
*
* 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 PV_UTILS_LIBCURL_H
#define PV_UTILS_LIBCURL_H
#include <glib.h>
#include <curl/curl.h>
#include "common.h"
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup)
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
GError **err);
gint curl_init(void);
void curl_cleanup(void);
#endif /* PV_UTILS_LIBCURL_H */

View File

@@ -171,13 +171,13 @@ err:
return ret;
}
gint seek_and_write_buffer(FILE *o, const Buffer *buf, uint64_t offset,
gint seek_and_write_buffer(FILE *o, const PvBuffer *buf, uint64_t offset,
GError **err)
{
if (file_seek(o, offset, err) < 0)
return -1;
if (buffer_write(buf, o, err) < 0)
if (pv_buffer_write(buf, o, err) < 0)
return -1;
return 0;

View File

@@ -26,7 +26,7 @@ gint file_write(FILE *out, const void *ptr, gsize size, gsize count,
gsize *count_written, GError **err);
gint pad_file_right(const gchar *path_out, const gchar *path_in,
gsize *size_out, guint padding, GError **err);
gint seek_and_write_buffer(FILE *out, const Buffer *buf, uint64_t offset,
gint seek_and_write_buffer(FILE *out, const PvBuffer *buf, uint64_t offset,
GError **err);
gint seek_and_write_file(FILE *o, const CompFile *ifile, uint64_t offset,
GError **err);

View File

@@ -0,0 +1,33 @@
/*
* OpenSSL compatibility utils
*
* Copyright IBM Corp. 2021
*
* 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 PV_UTILS_OPENSSL_COMPAT_H
#define PV_UTILS_OPENSSL_COMPAT_H
#include <openssl/opensslv.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#if OPENSSL_VERSION_NUMBER < 0x30000000L
#define Pv_X509_STORE_CTX_get_current_cert(ctx) \
X509_STORE_CTX_get_current_cert((X509_STORE_CTX *)(ctx))
#define Pv_X509_STORE_CTX_get1_crls(ctx, nm) \
X509_STORE_CTX_get1_crls((X509_STORE_CTX *)(ctx), (X509_NAME *)(nm))
#define Pv_X509_STORE_set_lookup_crls(st, cb) \
X509_STORE_set_lookup_crls(st, (X509_STORE_CTX_lookup_crls_fn)(cb))
#else
#define Pv_X509_STORE_CTX_get_current_cert(ctx) \
X509_STORE_CTX_get_current_cert(ctx)
#define Pv_X509_STORE_CTX_get1_crls(ctx, nm) \
X509_STORE_CTX_get1_crls(ctx, nm)
#define Pv_X509_STORE_set_lookup_crls(st, cb) \
X509_STORE_set_lookup_crls(st, cb)
#endif
#endif

View File

@@ -16,17 +16,17 @@ check_dep:
$(call check_dep, \
"hmcdrvfs", \
"fuse.h", \
"fuse-devel or libfuse-dev", \
"fuse3-devel or libfuse3-dev", \
"HAVE_FUSE=0")
ifneq ($(shell sh -c 'command -v pkg-config'),)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
else
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
FUSE_LDLIBS = -lfuse
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
FUSE_LDLIBS = -lfuse3
endif
ALL_CFLAGS += -DFUSE_USE_VERSION=26 -D_LARGEFILE_SOURCE $(FUSE_CFLAGS)
ALL_CFLAGS += -DFUSE_USE_VERSION=30 -D_LARGEFILE_SOURCE $(FUSE_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
OBJECTS = hmcdrvfs.o

View File

@@ -111,9 +111,6 @@ allow access by other users
.B -o allow_root
allow access by root
.TP
.B -o nonempty
allow mounts over non-empty file/dir
.TP
.B -o default_permissions
enable permission checking by kernel
.TP

View File

@@ -990,7 +990,7 @@ static int hmcdrv_cache_dir(const char *dir, fuse_fill_dir_t filler, void *buf)
hmcdrv_cache_refresh(path, &st, symlink);
if ((filler != NULL) &&
(filler(buf, fname, &st, 0) != 0))
(filler(buf, fname, &st, 0, 0) != 0))
filler = NULL; /* stop filling */
#ifdef DEBUG
strftime(symlink, sizeof(symlink),
@@ -1109,7 +1109,8 @@ static struct hmcdrv_fuse_file *hmcdrv_file_get(const char *path)
*
* Note: The most important function which FUSE calls (very often).
*/
static int hmcdrv_fuse_getattr(const char *path, struct stat *stbuf)
static int hmcdrv_fuse_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *UNUSED(fi))
{
struct hmcdrv_fuse_file *fp;
int rc = 0;
@@ -1175,12 +1176,13 @@ static int hmcdrv_fuse_opendir(const char *UNUSED(path),
*/
static int hmcdrv_fuse_readdir(const char *path, void *buf,
fuse_fill_dir_t filler, off_t UNUSED(offset),
struct fuse_file_info *UNUSED(fi))
struct fuse_file_info *UNUSED(fi),
enum fuse_readdir_flags UNUSED(flags))
{
int ret;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, ".", NULL, 0, 0);
filler(buf, "..", NULL, 0, 0);
pthread_mutex_lock(&hmcdrv_ctx.mutex);
ret = hmcdrv_cache_dir(path, filler, buf);
@@ -1232,7 +1234,8 @@ static int hmcdrv_fuse_read(const char *path, char *buf, size_t size,
* Return: value to be passed in the private_data field of fuse_context to
* all file operations and as a parameter to the destroy() method
*/
static void *hmcdrv_fuse_init(struct fuse_conn_info *UNUSED(conn))
static void *hmcdrv_fuse_init(struct fuse_conn_info *UNUSED(conn),
struct fuse_config *UNUSED(cfg))
{
pthread_mutexattr_t attr;

Some files were not shown because too many files have changed in this diff Show More