Compare commits

...

83 Commits

Author SHA1 Message Date
Steffen Eiden
7770b7a2c0 New release s390-tools-2.28.0
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 13:15:19 +02:00
Steffen Eiden
2ef6f64b1d Makefile: fix build for non-390 architectures
The last commit accidentally deleted the TOOLS_DIR for non-s390x
architectures.

Fixes: de013d2f ("Makefile: add genprotimg to non-s390x architectures target list")
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 11:32:26 +02:00
Marc Hartmayer
de013d2f04 Makefile: add genprotimg to non-s390x architectures target list
`genprotimg` can be useful on non-s390x architectures such as x86 or
arm. Therefore add `genprotimg` to the non-s390x target list.

How to build genprotimg on a non-s390x system (s390x cross-compiler
required)

$ # Build and install /usr/bin/genprotimg
$ make -C genprotimg
$ make install -C genprotimg
$ # Build and install the genprotimg bootloaders
$ make -C genprotimg/boot HOST_ARCH=s390x CROSS_COMPILE=s390x-linux-gnu-
$ make install -C genprotimg/boot HOST_ARCH=s390x CROSS_COMPILE=s390x-linux-gnu-

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:24:52 +02:00
Marc Hartmayer
ed94cf9839 genprotimg/boot: compile the bootloaders only if HOST_ARCH is s390x
The genprotimg bootloaders are s390x specific, so only build them if the
`HOST_ARCH' is set to s390x.

On x86 one can cross-compile and install the bootloaders as follows:

$ make -C genprotimg/boot HOST_ARCH=s390x CROSS_COMPILE=s390x-linux-gnu-
$ make -C genprotimg/boot install HOST_ARCH=s390x CROSS_COMPILE=s390x-linux-gnu-

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:22:04 +02:00
Marc Hartmayer
2fec7688b0 genprotimg: move bootloader installation responsibility to boot/Makefile
It's cleaner if the bootloader installation code is located in the
boot/Makefile, rather than the top Makefile.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:22:04 +02:00
Matthew Rosato
3c1834f0fc ap_tools/ap-check: handle missing 'matrix' and 'control_domains' attrs
Under typical circumstances these sysfs attributes should be available
however if the device happens to be in the process of being removed
without the protection of the ap config file lock, this scenario can
be encountered.  In this case, ignore the device and assume it is in
the process of being removed.

Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:22:04 +02:00
Matthew Rosato
f6e78d3ecd ap_tools/ap-check: hold ap config file lock over get attributes
Since this callout reads sysfs values for the specified mdev, the
ap config file lock should be held to prevent other tools from
making changes to the ap configuration at the same time.

Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:22:04 +02:00
Steffen Eiden
dad7fce7a1 zipl/boot: move load_wait_psw() location
`load_wait_psw` is defined in include/boot/s390.h but is implemented in
zipl/boot/libc.c. This results in a dangling definition for s390.h users
other than zipl, due to the missing implementation. Since the function
is only relevant for zipl, move the definition to the corresponding
header file zipl/boot/libc.h

Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:21:58 +02:00
Steffen Eiden
8058921f58 Reorganize boot-loader header files
include/boot/s390.h relies on s390 specific kernel headers. However,
some tools used this header for non-s390 code (outside of boot-loaders).
To solve this the PSW and PAGE_SIZE definitions are now in separate
header files. All includes for s390.h which are not in boot-loader code
are replaced with one of psw.h or page.h.

This fixes the compilation failure on ppc64le due to conflicting types
for `__vector128`.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/151
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:21:48 +02:00
Marc Hartmayer
bb8e0e1047 common.mak: test_linker_flag: use LINK and not CC variable
The check is for linker flags, and the $(LINK) variable is used for
linking, not $(CC).

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:21:48 +02:00
Marc Hartmayer
5dcac6d2e3 common.mak: use a minimal assembly snippet to check for linker flags
Use a minimal assembly snippet to check for linker flags. This has the
advantage that it will work even if only the cross-toolchain is
installed, but not, for example, stdlib.

Using the C snippet, the check runs in a similar error like this:

  /usr/bin/s390x-linux-gnu-ld: cannot find crt1.o: No such file or directory
  /usr/bin/s390x-linux-gnu-ld: cannot find crti.o: No such file or directory
  /usr/bin/s390x-linux-gnu-ld: cannot find -lc: No such file or directory
  /usr/bin/s390x-linux-gnu-ld: cannot find crtn.o: No such file or directory

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-07-11 08:21:48 +02:00
Peter Oberparleiter
552772d2a9 zdev: fix unexpected warning due to non-existent interface
Using option --by-interface with a non-existent network interface name
results in an unexpected duplicate warning message:

  $ lszdev --by-interface xx
  Could not open directory /sys/class/net/xx: No such file or directory
  Could not open directory /sys/class/net/xx: No such file or directory
  lszdev: Could not determine device that provides xx (xx)

Fix this by checking for the existence of the associated /sys/class/net
directory before initiating the associated directory traversal.

Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:04 +02:00
Peter Oberparleiter
42611a787d zdev: use consistent exit code for nonexistent device nodes
zdev's --by-node option returns exit code 15 (EXIT_RUNTIME_ERROR) when
the specified device node cannot be found. This is inconsistent with
other selection options --by-path and --by-interface which both return
the more appropriate exit code 3 (EXIT_DEVICE_NOT_FOUND).

Fix this by changing --by-node to also return exit code 3 in case the
specified device node does not exist.

Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:03 +02:00
Sven Schnelle
743788d02f zipl/dump: fix ngdump dracut helper script
While changing the helper script to create the ngdump filesystem,
some lines were left in the script which now cause the zipl
installation to fail:

Run /lib/s390-tools/zipl_helper.prepare-ngdump /dev/disk/by-path/ccw-0.0.6a56-part1 0
Couldn't find disk by PARTUUID.
Error: Script could not determine dump parameters

Remove the superfluous lines to fix this.

Fixes: 41108c98aa ("zipl: move mkfs to ngdump prepare script")
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:03 +02:00
Marc Hartmayer
6028300366 cpacfstatsd: don't fail if no crypto counters are supported
Do not fail to start the daemon if no crypto counters are supported, as
there is still a use case for the daemon to run, as the user can then
use the 'cpacfstats' tool to evaluate that no counter stats are
available. Previously, the user had to check the syslogs for the reason
why the daemon was not running and the cpacfstats command failed.

Before this change:

$ cpacfstats
cpacfstats: Can't access domain socket file '/run/cpacfstatsd_socket', errno=2 [No such file or directory]
cpacfstats: Maybe cpacfstatsd daemon is not running ???
cpacfstats: Can't connect to daemon

After this change:

$ cpacfstats
 des counter: unsupported
 aes counter: unsupported
 sha counter: unsupported
 rng counter: unsupported
 ecc counter: unsupported
 pai_user   : unsupported
 pai_kernel : unsupported

Also, it's no good practice to let systemd services fail, because
otherwise the system state will be shown as 'degraded':

$ systemctl status
* a46lp59
    State: degraded
     Jobs: 0 queued
   Failed: 1 units

$ systemctl list-units --failed
  UNIT                LOAD   ACTIVE SUB    DESCRIPTION
* cpacfstatsd.service loaded failed failed CPACF statistics collection daemon process for Linux on System z

Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:03 +02:00
Marc Hartmayer
70cb25766b cpacfstatsd: manpage: CPU hotplug is recognized by the daemon
Since commit 72b5e8b313 ("cpacfstats: Handle CPU hotplug") CPU
hotplugs are recognized by the daemon.

Fixes: 72b5e8b313 ("cpacfstats: Handle CPU hotplug")
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:03 +02:00
Marc Hartmayer
36eede8f31 cpacfstats: whitespace cleanups and typo fix
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:03 +02:00
Eduard Shishkin
ec0dcdb685 zipl/job.c: Print additional information on error paths
Print the name of the section which specifes non-existing image
and/or ramdisk files.

It allows to quickly identify problems after using non-atomic tools
manipulating with bootloader settings.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:03 +02:00
Vineeth Vijayan
2a1a821bb3 zdev: add missing label in the udev-rules
The udev-rules generated with the current version of chzdev command
is missing the configuration label, incase of auto configuration,
resulting in an ineffective configuration logic.
Add the missing configuration start label for autoconfig.

Fixes: 2e89722ef0 ("zdev: make site specific udev-rule for ccw")
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>
2023-07-04 15:41:02 +02:00
Vineeth Vijayan
09c01e580a zdev: use rename-file to avoid any symlinks created
During the boot, the ZDEV_SITE_ID is derived with the help
of loadparm and will be saved in ZDEV_SITE_ID_FILE, which
will be the used by the udev-rules.

ZDEV_SITE_ID_FILE creation can have a surface of symlink attack
as we are directly using the fopen and fprintf on it. To avoid
this, make sure that we are writing the ZDEV_SITE_ID to a temporary
file, which will then be renamed to ZDEV_SITE_ID_FILE, which will
remove all the existing symlinks associated with the target file.

Reported-by: Marc Hartmayer <mhartmay@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>
2023-07-04 15:41:02 +02:00
Vineeth Vijayan
27902c9106 zdev: add proper value input for the ZDEV_SITE_ID key
udev does not allow an empty value for keys when importing output
from an external program. Providing an empty value for any key
invokes a warning during the parsing. Currently, ZDEV_SITE_ID for
fallback sites are not assigned any value. Add an empty double
quotes as the value in case of failover sites.

This modification is tested on udevadm version 253 on fedora38.

Also verify that the ZDEV_SITE_ID is properly written, if not log
the error.

Fixes: c8ad5f57d0 ("zdev: modify zdev_id to read the site_id from loadparm")
Reported-by: Alexander Egorenkov <egorenar@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>
2023-07-04 15:41:02 +02:00
Thomas Richter
a8d328bba2 cpumf/lshwc: replace memory alloction functions by library counterparts
Replace memory allocation functions malloc() and calloc()
by counterparts provided in libutil.a library. Also remove error
handling when no memory could be allocated as those functions do
not 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>
2023-07-04 15:41:02 +02:00
Eduard Shishkin
917d611883 zipl: add/move some definitions to header files
Make the listed changes which are needed to re-use some definitions
by the new zipl-debug(8) tool introduced by the next patch in the
series:

. Add definitions to boot_defs.h:
   . a named union disk_bloclkptr (instead of the anonymous one);
   . a named structure disk_program_table;
. Remove a 'typedef union disk_blockptr_t' from boot/stage2.h
  (cleanup), use the named union in boot_defs.h instead;
. Move the definition of scsi_layout types and the function
  get_scsi_layout() from install.c to install.h;
. Move definition of PROGRAM_TABLE_BLOCK_SIZE from bootmap.c to
  bootmap.h

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>
2023-07-04 15:41:02 +02:00
Marc Hartmayer
94e0b644a7 cpacfstatsd: use a PIPE to notify the parent that the initialization is done
Use a PIPE to notify the parent that the initialization is complete and
all external communication channels are established. See
https://www.freedesktop.org/software/systemd/man/daemon.html for
details.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:02 +02:00
Marc Hartmayer
10f8565e32 cpacfstatsd: replace goto cleanups
There are only two users of the `cleanup` label, so let's replace the
goto statements with the label code. This makes the code easier to read.
Especially since another label will be introduced in the next commit.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:01 +02:00
Marc Hartmayer
22bce41dd7 cpacfstatsd: white-space cleanup and typo fixes
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:41:01 +02:00
Harald Freudenberger
e35e73d2a3 chzcrypt: Support for SE bind, unbind and associate
This patch adds support for Secure Execution with AP pass-through
support for chzcrypt.

chzcrypt details:
* new command: --se-associate <secret-id> <queue device>
* new command: --se-bind <queue device>
* new command: --se-unbind <queue device>

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:40:56 +02:00
Harald Freudenberger
f821f31a51 lszcrypt: Support for SE AP pass-through support
This patch adds support for Secure Execution with AP pass-through
support for lszcrypt.

lszcrypt details:
* extension to -b: list AP bus features
* extension to -c: now also valid for queue devices, shows
		   bind and assoicate state in SE environment;
		   shows MK states (only for current MKs).
* extension to -V: new column SESTAT within an SE guest, shows text
		   for the BS bits within an SE environment:
		   "usable", "bond", "avail", "unuse".

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-07-04 15:40:47 +02:00
Stefan Haberland
493af760ed zdev: add support for autoquiesce related sysfs attributes
Autoquiesce is a mechanism that tells Linux to stop issuing I/Os to a
specific DASD after certain events.

Add support for configuring related DASD device attributes
that govern the following aspects of autoquiesce:

aq_mask - Configure which events lead to autoquiesce.
aq_requeue - Configure if autoquiesce will requeue all I/O to blocklayer.
aq_timeouts - Configure the number of timeouts before autoquiesce.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 16:55:55 +02:00
Steffen Eiden
3287bb9613 Prepare for next release
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 14:42:12 +02:00
Steffen Eiden
76606802d0 New release s390-tools-2.27.0
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 14:42:12 +02:00
Marc Hartmayer
e99b32cacb common.mak: make *clean targets mutually exclusive
The 'clean' build targets can be specified alongside other targets,
which causes an immediate removal of build artifacts. Make 'clean'
targets mutually exclusive to avoid this issue and display an error if
'clean' is used in combination with other targets.

Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:53 +02:00
Jan Höppner
87a6154de9 Makefile: limit build targets for non-s390x architecture
A subset of s390 tools can be useful on non-s390x architectures such as
x86 or arm. Limit the build targets for these architectures with
'pvattest' and 'libpv' as the first candidates.

A cross compilation on x86 for s390x will still build the entire package
provided that the HOST_ARCH variable is set properly:

$ make HOST_ARCH=s390x CROSS_COMPILE=s390x-linux-gnu-

Cross compilation on s390x for x86 will limit the build targets as
described:

$ make HOST_ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu-

Co-developed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:53 +02:00
Marc Hartmayer
ed4c68e867 common.mak: improve cross compilation support
Introduce `BUILD_ARCH` and `(CC|LINK|...|OBJDUMP)_FOR_BUILD` variables
in order to properly support the build of tools that generate code or
data during the build process. Replace existing variables `HOSTCC` with
`CC_FOR_BUILD` and `HOSTCFLAGS` `CFLAGS_FOR_BUILD`. The Makefile
variables for the `HOST_ARCH` are unchanged.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:53 +02:00
Marc Hartmayer
e2b68b4d9b common.mak: make sure all command variables are getting exported
Export the Makefile variables HOSTCC, LINKXX, PANDOC, and PKG_CONFIG so
they can be used in sub-make calls, too.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:53 +02:00
Marc Hartmayer
686fca1863 Move HOST_ARCH declaration to common.mak
In addition, add the ability that a Makefile that includes `common.mak`
can specify the `HOST_ARCH`. Usage example:

$S390_TOOLS/mytool/Makefile:
``` Makefile
HOST_ARCH := s390x
include ../common.mak
```

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:53 +02:00
Marc Hartmayer
0c1a5069d9 Rename ARCH to HOST_ARCH
Use a common naming convention for the variable [1][2][3]. In an
upcoming patch the Makefile variable `BUILD_ARCH` will be introduced.

[1] https://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html
[2] https://docs.yoctoproject.org/ref-manual/variables.html#term-HOST_ARCH
[3] https://mesonbuild.com/Cross-compilation.html#cross-compilation

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:53 +02:00
Marc Hartmayer
de88b1c71b common.mak: introduce PKG_CONFIG
Introduce `PKG_CONFIG` Makefile variable. This helps for
cross-compilation.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:51 +02:00
Marc Hartmayer
4bba1058c6 Declare pkg-config as required
`pkg-config` is a well established tool and all of our required
libraries do provide .pc files. Therefore let's declare `pkg-config` as
required and use it. In addition, remove now useless code.

Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:31:20 +02:00
Jan Höppner
49937f40a1 zipl: Disable array-bounds warning
Since GCC12 several warnings like the following are produced in
zipl/boot compile targets:

CC      zipl/boot/stage2.o
stage2.c: In function ‘start’:
stage2.c:99:24: warning: array subscript 0 is outside array bounds of ‘struct stage2_descr[0]’ [-Warray-bounds]
   99 |         stage2_descr = *(struct stage2_descr*)STAGE2_DESC;

This is the same issue as reported for the Kernel [1][2]. There is
currently no sane fix available, therefore simply disable the warning
for the zipl/boot/ targets.

[1] https://lore.kernel.org/lkml/yt9dzgkelelc.fsf@linux.ibm.com/
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:29:57 +02:00
Jan Höppner
d55818a797 dasdfmt: Fall back to full format if space release fails
In certain storage setups the Release Allocated Space (RAS) command to
free up space on the storage server previously allocated for an ESE DASD
might not work. At the moment dasdfmt will error out if RAS is failing.
This however is not ideal for the default case when a user is expecting
dasdfmt to simply format the disk.

One workaround would be to specify --no-discard to disable RAS
completely. However, a sane default handling that tries to work every
time is more reasonable.

Change the default handling as follows: If an ESE is detected default to
QUICK mode and try RAS. If RAS fails, fall back to the FULL format mode
and display a warning accordingly.

If -M (--mode) QUICK is specified explicitly dasdfmt will still error
out on a failing RAS. A combination with --no-discard will still allow
for a QUICK format on an ESE DASD in that case, if desired.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-30 13:29:57 +02:00
Steffen Eiden
96897ee32e pvattest/tools: fix endianness in tools
`od` in contrast to `xxd` uses the system endianness for displying the
hexdump by default which leads to invalid results on little endian
systems.
Use the `--endian=big` option to fix the endianness problem.

Fixes: 3cc0b4cd ("pvattest/tools: remove xxd dependency from scripts")
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Marc Hartmayer
5522aaedf4 iucvterm/bin/chiucvallow: explicitly use bash
The script uses bashisms (e.g. `local` keyword) therefore make sure that
bash is used by setting the shebang line to `#!/bin/bash`.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Joern Siglen
f3b7f4b14b dbginfo.sh: fix icastats for all users
icastats is accounted by user and does cover root only today
adding the --all will collect stats for all users

Reported-by: Ingo Franzki <ifranzki@de.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@de.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Sven Schnelle
01f74c75f5 zipl/dump: add dasd device to ngdump parmline
For dasd devices, we need to enable the device before we can use it.
Add the required dasd device to the kernel commandline when installing
ngdump to a dasd device.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Sven Schnelle
24bcc3141d zipl: add support for ldipl dump from ECKD DASD
Add the required code to install ngdump on DASDs.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Sven Schnelle
41108c98aa zipl: move mkfs to ngdump prepare script
The current code first assembles the ngdump init ramdisk, and creates
the filesystem on the dump disk afterwards. ngdump uses uuids to mount
the dump device. Because the filesystem uuid is changing with the final
mkfs, ngdump has to use the partuuid of the device. This does work for
nvme, but not for dasds. Another problem is that dryrun likely wouldn't
work if there's no partition table on the dump device. To fix these
issues, move the mkfs to the ngdump helper script so we can use the
filesystem uuid. When --dryrun is specified the script passes /dev/null
as ngdump device to make mkinitramfs happy. As the initramdisk is never
used in this case, this shouldn't be a problem.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Sven Schnelle
f5aa1d4406 zipl: add ldipl-dump option
CCW and LD-IPL records cannot be used at the same time for dumps because
CCW dump uses the standalone dumper, while LD-IPL uses ngdump. The first
one writes data to the raw disk without any filesystem, while the second
one uses an ext filesystem. Therefore we need a way to tell zipl which
kind of dumper it should install, as both cannot be installed at the
same time. The device given is the same for both types, so we cannot use
this to decide which type to install. Therefore add a '--ldipl-dump' option
so the user can decide which type of dump to use.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Sven Schnelle
ee4f503ec0 zipl: pass job to is_ngdump_enabled()
No functional change, only preparation for the next patches.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:04 +02:00
Sven Schnelle
7095da9f9d dumpconf: add options for ldipl ECKD devices
Add the following options to dumpconf so that LDIPL ECKD devices
can be configured for dumping:

br_chr: (optional) location of boot record
device: ccw device
bootprog: boot program selector

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Eduard Shishkin
7c656faa36 zipl: remove last table / number of tables logic
In order to allow installing only a list-directed ipl entry, remove
the last-table/number-of-tables logic which always required a legacy
program table. With the new code there's no longer a loop in
prepare_bootloader() which requires a certain start index or order
of tables.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Sven Schnelle
10515380e8 zipl: add print_details flag to struct install_set
Instead of depending on array index, add an explicit print_details
flag to struct install_set.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Sven Schnelle
7301883e69 zipl: add skip_prepare flag to struct install_set
Instead of depending on array index to decide whether we
did already the preparation work for installing the bootloader,
add an explicit skip_prepare flag to struct install_set.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Sven Schnelle
555f3782d4 zipl: rename PROGRAM_TABLE_* to {LEGACY}_BLKPTR_FORMAT_ID
In preparation of decoupling the program table position from
the block pointer format, rename:

PROGRAM_TABLE_0 to LEGACY_BLKPTR_FORMAT_ID
PRAGRAM_TABLE_1 to BLKPTR_FORMAT_ID

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Sven Schnelle
7ecad86938 zipl: split up install_bootloader()
To make the code easier to maintain and prepare for ECKD LD-IPL,
split up install_bootloader() into two functions: One which is used
for IPL, and one for dump partitions.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Sven Schnelle
e496e9862c zipl: show whether we're installed LD ipl or dump
Let the user know whether we're going to install a
list-directed IPL or dump.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Sven Schnelle
c8e989840f zipl: add disk_is_eckd_ldl()
Add a small helper to check whether a given disk is ECKD
containing a Linux disk label.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Jan Höppner
908067bdf9 common.mak: Fix slow build
The relative subdirectory path of a build target is determined via a
separate shell command that issues 'cd' and 'pwd'. Spawning a separate
shell is very costly and can lead to extremely slow builds in some
circumstances.

Replace the shell command with the make built-in command 'realpath' to
accomplish the same result more efficiently.

Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:21:03 +02:00
Marc Hartmayer
2c7e61a6c7 zipl: check_common_ipl_data: fix memory leak of @buffer
Related Valgrind output:
  ==1073934== 241,722,000 bytes in 30 blocks are definitely lost in loss record 2 of 2
  ==1073934==    at 0x484417C: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-s390x-linux.so)
  ==1073934==    by 0x1006B8D: misc_malloc (misc.c:33)
  ==1073934==    by 0x1006B8D: misc_read_file (misc.c:150)
  ==1073934==    by 0x100DACD: check_common_ipl_data (job.c:774)
  ==1073934==    by 0x100FE2F: check_job_ipl_data (job.c:827)
  ==1073934==    by 0x100FE2F: check_job_menu_data (job.c:999)
  ==1073934==    by 0x100FE2F: check_job_data (job.c:1139)
  ==1073934==    by 0x100FE2F: job_get (job.c:2011)
  ==1073934==    by 0x1006335: main (zipl.c:141)

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:18:08 +02:00
Joern Siglen
ae824745a0 dbginfo.sh: add nstat command in network section
include the statistics about the network and SNMP

Reported-by: Nils Hoppmann <NIHO@de.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:18:08 +02:00
Mete Durlu
2b2c111af4 hyptop: Show thread util by default
Since SMT is being used by default on z systems, hyptop should show
thread utilization by default on both system and system list window.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:18:08 +02:00
Marc Hartmayer
1bfa78896f libpv|pvattest: do not link against openssl
Neither libpv nor pvattest uses libssl functionality directly, so let's
remove it from the pkg-config calls.

$ pkg-config --libs openssl
-lssl -lcrypto

$ pkg-config --libs libcrypto
-lcrypto

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:18:04 +02:00
Marc Hartmayer
e928c6f83c .gitignore: ignore clangd cache
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:13:35 +02:00
Marc Hartmayer
0e86da9d66 zipl: extract_signature: fix memory leak of @signature
Fix memory leak @signature in case of an unsupported signature type.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:13:35 +02:00
Marc Hartmayer
21dbbcfa56 zipl: scan_upldate_bls_path: fix memory leak of @img_value
Valgrind finding:
  ==1083976== 19 bytes in 1 blocks are definitely lost in loss record 1 of 1
  ==1083976==    at 0x484417C: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-s390x-linux.so)
  ==1083976==    by 0x48F3C97: __vasprintf_internal (vasprintf.c:71)
  ==1083976==    by 0x1006861: vasprintf (stdio2.h:218)
  ==1083976==    by 0x1006861: misc_asprintf (misc.c:49)
  ==1083976==    by 0x100C7E1: scan_update_bls_path (scan.c:1874)
  ==1083976==    by 0x100FF4B: get_job_from_config_file (job.c:1901)
  ==1083976==    by 0x100FF4B: job_get (job.c:1997)
  ==1083976==    by 0x1006335: main (zipl.c:141)

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:13:35 +02:00
Marc Hartmayer
0a512bf904 common.mak: use single quotes in order to avoid globbing
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-05-26 12:13:35 +02:00
Marc Hartmayer
e6be1c1b79 zipl/boot: constify data in section stage2_head
Declare `magic`, `tape_head`, and `stage2_head` as const.

Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-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>
2023-03-31 18:23:46 +02:00
Marc Hartmayer
a4eb03dfe1 zipl: set kernel parmline only if it was specified
Before commit 5fb6434548 ("zipl: add get_common_components() and
finalize_common_address_data()") the default kernel parmline was only
overwritten if a parmline was specified. After the commit it was always
overwritten, even if no parmline was specified. Let's change this
behavior back by adding a NULL-pointer check. For dump types this change
changes the behavior before commit 5fb6434548 ("zipl: add
get_common_components() and finalize_common_address_data()").

Fixes: 5fb6434548 ("zipl: add get_common_components() and finalize_common_address_data()")
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
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>
2023-03-31 18:23:46 +02:00
Marc Hartmayer
fc1167fd34 common.mak: avoid a lot of warnings if make --warn is used
Fix the following warnings by using proper default values:

../common.mak:1: warning: undefined variable 'COMMON_INCLUDED'
../common.mak:87: warning: undefined variable 'V'
../common.mak:95: warning: undefined variable 'W'
../common.mak:98: warning: undefined variable 'D'
../common.mak:107: warning: undefined variable 'ASAN'
../common.mak:249: warning: undefined variable 'OPT_FLAGS'
../common.mak:262: warning: undefined variable 'G'
../common.mak:280: warning: undefined variable 'C'
../common.mak:349: warning: undefined variable 'MAKECMDGOALS'
../common.mak:105: warning: undefined variable 'ENABLE_WERROR'

This has two main advantages:
1. Explicit default values
2. `make --warn` shows less false positives

Reviewed-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>
2023-03-17 10:56:11 +01:00
Marc Hartmayer
561559277d zkey: Makefiles: add newline at end of file
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-17 10:56:11 +01:00
Thomas Richter
68a3ccd45e cpumf/lshwc: Update man page and remove concurrency statement
Linux kernel commits
a029a4eab39 ("s390/cpumf: Allow concurrent access for CPU Measurement Counter Facility")
453380318ed ("s390/cpumf: Allow multiple processes to access /dev/hwc")
removed this restriction. Both commits are included in linux 5.16.

Therefore remove the restriction in 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>
2023-03-17 10:56:11 +01:00
Ingo Franzki
fcfd4a6158 libseckey: Fix error checking when building ECDSA signatures
OpenSSL function i2d_ECDSA_SIG() returns a negative value in case of
an error, so check the returned length for <= zero to detect an error.

Reported-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-17 10:56:11 +01:00
Ingo Franzki
e621d2dfa2 libseckey: Use OSSL_FUNC_keymgmt_im/export_types_ex functions
The provider functions OSSL_FUNC_keymgmt_import_types() and
OSSL_FUNC_keymgmt_export_types() do not get the provider context passed.
However, the implementation of these functions in the secure key provider
need the provider context to pass the call to the default provider
and append some of its own types to the result.

Up to now, the provider context was obtained using a global variable
holding the secure key provider handle. This may not be save if multiple
instances of the provider exist.

Just recently OpenSSL added support for an extended form of these
functions, namely OSSL_FUNC_keymgmt_import_types_ex() and
OSSL_FUNC_keymgmt_export_types_ex(), that get the provider context passed
as argument. Make use of these new functions, if compiled against an
OpenSSL version that supports them. For older OpenSSL versions still use
the global variable as before.

See OpenSSL commit 5e3b84505e

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-17 10:56:11 +01:00
Fedor Loshakov
a92ee5ba8d ziomon/ziorep_config: fix for SCSI devices of type disk without block dev
If system configuration contains zfcp-attached SCSI devices of Peripheral
Device Type disk, but without block device, e.g. because the storage reports
Peripheral Qualifier 1 in INQUIRY, ziorep_config tool issue the
following type of errors during generation of .config file from .cfg
file:

$ ziorep_config -I -i test.cfg
Unpacking configuration ...Done.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 36.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 36.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 54.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 135.
...

Such errors can also be seen during printing of adapter, device and map
reports:

$ ziorep_config -ADM -i test.cfg
Unpacking configuration ...Done.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 36.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 36.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 54.
Use of uninitialized value in subroutine entry at /usr/sbin/ziorep_config line 135.
...

This is because ziorep_config reads block device parameters from
non-existent block device subdirectory. And therefore ziorep_config
leaves block device major:minor number column empty in .config file
instead of filling it with 0:0 preset value afterwards.

As a consequence, ziorep_traffic tool, which is using .config file to
get information about devices, reports the following error:

$ ziorep_traffic test
Extracting config data...done
ziorep_traffic: Could not parse line 1 - configuration file broken?

To fix this, skip reading the block device parameters for such
devices, and use the preset values that have been set before
instead.

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Suggested-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-17 10:56:11 +01:00
Fedor Loshakov
46c291835f ziomon/ziorep_config: fix missing SG major:minor for disk block devices
The value of "generic/dev" exists and can be retrieved directly under
the SCSI device directory, not under the disk block device subdirectory,
where the global variable $c_src points to after
$c_src = $devices{$hctl}{dev}; command.

So move the sg_mm retrieval before the block device parameters
retrieval.

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Suggested-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-17 10:56:11 +01:00
Benjamin Block
4941fc15c0 zfcpdbf: test-compile the script during the build using perl -c
For a slightly easier development loop add a pseudo compilation of the
zfcpdbf Perl script. This will run the Perl interpreter in syntax-check
mode:

  -c   causes Perl to check the syntax of the program and then exit
       without executing it.  Actually, it will execute any "BEGIN",
       "UNITCHECK", or "CHECK" blocks and any "use" statements: these are
       considered as occurring outside the execution of your program.
       "INIT" and "END" blocks, however, will be skipped.

Additionally add the `-w` switch when the Make variable `W` is `1`. This
will print additional warnings about dubious constructs (according to
Perl).

So this pseudo compilation only happens whenever the script is changed
during development create a file `.zfcpdbf.ct` as a result so we can
describe the relationship and dependency in Make. This file can be ignored
otherwise.

Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-17 10:56:11 +01:00
Joern Siglen
48d7c6e6d1 dbginfo.sh: rework opencryptoki data collection
changes in opencryptoki setup do require some modifications:
- "pkcsconf -mlist" does no longer work in a combined format
- config files have changed
- ep11info was not yet collected

Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-03 09:58:40 +01:00
Steffen Maier
73c46a3056 zdev/dracut: fix kdump by only activating required devices
This prevents out-of-memory (OOM) situations in the kdump crashkernel
environment.

Please note that the new dracut module 95zdev-kdump and the new library
zdev-lib.sh need to be packaged into the same (core) (sub)package as
95zdev.

This patch introduces a new dracut module "zdev-kdump", which is used
instead of module "zdev" when building a kdump initrd:

1. Ignore all persistently configured block devices and disable zfcp auto
LUN scanning => minimize the number of SCSI devices enabled during kdump.

2. Do not rely on chzdev's persistent configuration => work with systems
that do not use chzdev for persistent device configuration.

The detection of kdump is based on strict hostonly mode and on $IN_KDUMP.
See also
https://src.fedoraproject.org/rpms/kexec-tools commit
4eedcae5e154 ("dracut-module-setup.sh: don't include multipath-hostonly")
and https://github.com/dracutdevs/dracut commits
35e86ac117ac ("Merge 90-multipath-hostonly and 90-multipath")
a695250ec7db ("Introduce tri-state hostonly mode")
and
https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/mkdumprd#_17
https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/dracut-module-setup.sh#_23.
The detection of kdump is also based on kdump_needed() in
https://github.com/openSUSE/kdump/blob/master/dracut/module-setup.sh.

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-03 09:58:40 +01:00
Steffen Maier
f2c82bf2b5 zdev/dracut: fix hardcoded '/' as required mount or device
With the introduction of zdev for device configuration in v1.33.0,
it used a hardcoded "/" to refer to the root-fs.

Dracut has its own mechanism to find the root file system and to walk its
device dependencies.
Mkdumprd also has its own mechanism to interpret the kdump target
and invokes dracut so that dracut only considers arguments from mkdumprd
without any root-fs dracut would default to [--no-hostonly-default-device].

Use the dracut mechanism to walk device dependencies and individually
have chzdev treat each leaf-node in the dependency tree.
See also https://github.com/dracutdevs/dracut commit
83e0dc7a3dca ("Add for_each_host_dev_and_slaves for device only checking").
This enables the use of dracut options such as --add-device or
--mount used in turn by mkdumprd.

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-03 09:58:20 +01:00
Steffen Eiden
d3a3b26d16 Make -Werror optional
Enforcing `-Werror` can cause problems when compiling with newer
compilers that have additional warnings on by default.

By default `-Werror` is turned off and can be turned on via
`ENABLE_WERROR=1`.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/148
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-03 09:53:46 +01:00
Holger Dengler
c142bb0625 lszcrypt: use separate index for inner sub-device loop
The function show_devices_argv() iterates over all remaining
arguments. Each argument may specify a single device or a list of
sub-devices. Use a separate index for the inner sub-device loop. This
fixes a bug, that not all or wrong arguments are processed.

Also terminate the outer arguments loop based on the number of
remaining arguments.

Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-03 09:50:53 +01:00
Holger Dengler
ec04a1846e lszcrypt: use type-filter option also for sub-devices
The tools lszcrypt provides filter options for card types. Use these
options not only for devices (cards), but also for sub-devices
(domains).

Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-03-03 09:50:53 +01:00
Jan Höppner
0324fac616 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-14 14:05:17 +01:00
103 changed files with 1908 additions and 735 deletions

3
.gitignore vendored
View File

@@ -9,6 +9,9 @@
tags
TAGS
# clangd cache (https://clangd.llvm.org/design/indexing#backgroundindex)
.cache/
# Ignore coverage data
*.gcda
*.gcno

View File

@@ -1,6 +1,56 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.28.0 (2023-07-11)__
For Linux kernel version: 6.4
Changes of existing tools:
- chzcrypt: Support for SE AP pass-through support
- genprotimg: Add support for non-s390x architectures
- lszcrypt: Support for SE AP pass-through support
- zdev: Add support for autoquiesce related sysfs attributes
Bug Fixes:
- ap_tools/ap-check: Handle missing 'matrix' and 'control_domains' attrs
- ap_tools/ap-check: Hold ap config file lock over get attributes
- s390-tools: Fix build for ppc64le
- zdev: Add missing label in the udev-rules
- zdev: Add proper value input for the ZDEV_SITE_ID key
- zdev: Use rename-file to avoid any symlinks created
- zipl/dump: fix ngdump dracut helper script
* __v2.27.0 (2023-05-30)__
For Linux kernel version: 6.3
Changes of existing tools:
- s390-tools cross-compile and non-s390x support:
- `pkg-config` is now mandatory for the build process
- Add `PKG_CONFIG` Makefile variable to select pkg-config program;
default `pkg-config` or `$(CROSS_COMPILE)pkg-config` if
`CROSS_COMPILE` is set
- Rename Makefile variable `ARCH` to `HOST_ARCH`. `HOST_ARCH` is the
architecture that will run the produced (executable) objects
- Add the Makefile variable `BUILD_ARCH`. `BUILD_ARCH` is the
architecture of the build system. For each Makefile variable like
`CC`, `LINK`, `CPP`, ... there is a suffixed version of it - e.g.
`CC_FOR_BUILD`. This is useful for cross compiling, and this naming
convention is very similar to the Meson convention (see
https://mesonbuild.com/Reference-tables.html#environment-variables-per-machine).
- Limit build targets for non-s390x architectures (pvattest)
- dasdfmt: Fall back to full format if space release fails
- dbginfo.sh: Add nstat for network and SNMP stats
- dbginfo.sh: Rework crypto data collection
- hyptop: Show thread util by default
- zipl: Add support for list-directed IPL dump from ECKD DASD
Bug Fixes:
- lszcrypt: Fix argument parsing
- zdev/dracut: Fix out-of-memory (OOM) situations in the kdump crashkernel environment
- ziomon/ziorep_config: Fix for SCSI devices of type disk without block dev
- pvextract-hdr: Fix parsing issues on little-endian systems
* __v2.26.0 (2023-02-14)__
For Linux kernel version: 6.2

View File

@@ -1,5 +1,3 @@
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
# Include common definitions
include common.mak
@@ -8,6 +6,7 @@ include common.mak
# LIBS: Libraries that can have a dependency to base libraries
# TOOLS: Tools that can have a dependency to base libraries or libraries
#
ifeq ($(HOST_ARCH),s390x)
BASELIB_DIRS = libutil libseckey
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
libkmipclient libcpumf libap libpv
@@ -17,6 +16,11 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest
else
BASELIB_DIRS =
LIB_DIRS = libpv
TOOL_DIRS = genprotimg pvattest
endif
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
@@ -49,15 +53,15 @@ endif
$(TOOL_DIRS): $(LIB_DIRS)
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
.PHONY: $(TOOL_DIRS)
$(LIB_DIRS): $(BASELIB_DIRS)
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
.PHONY: $(LIB_DIRS)
$(BASELIB_DIRS):
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
.PHONY: $(BASELIB_DIRS)

View File

@@ -325,8 +325,8 @@ This table lists additional build or install options:
| 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.
The s390-tools build process uses "pkg-config" and therefore it must be
available.
Build and runtime requirements for specific tools
-------------------------------------------------

View File

@@ -434,14 +434,23 @@ static int check_other_mdev_sysfs_cb(const char *path, const char *filename,
strcasecmp(filename, cbdata->uuid) == 0)
return 0;
dev2 = vfio_ap_device_new();
/*
* Read the 'matrix' attribute to get the list of queues for the active
* device. If the sysfs attribute is unreadable, assume the device is
* being destroyed and skip it.
*/
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
f = fopen(matrix_path, "r");
free(matrix_path);
if (!f)
return 0;
dev2 = vfio_ap_device_new();
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,
@@ -787,21 +796,39 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
char buf[80];
char *path;
FILE *f;
int rc;
rc = ap_get_lock_callout();
if (rc) {
fprintf(stderr, "Failed to acquire configuration lock %d\n", rc);
return -1;
}
anc->cleanup_lock = true;
/*
* Read the 'matrix' and 'control_domains' attributes to get the
* current attributes of the active device. If either of these sysfs
* attributes is unreadable, assume the device is being destroyed
* and return nothing.
*/
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
f = fopen(path, "r");
free(path);
if (!f)
return 0;
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");
free(path);
if (!f)
return 0;
while (fgets(buf, sizeof(buf), f))
vfio_ap_parse_control(dev, buf);
fclose(f);
free(path);
printf("[{");

View File

@@ -74,7 +74,7 @@ ALL_PANDOCFLAGS = --preserve-tabs --tab-stop=8 --strip-comments \
-M date="$(shell date +'%Y-%m-%d')" \
$(PANDOCFLAGS)
$(eval $(call cmd_define, PANDOC," PANDOC ",pandoc))
$(eval $(call cmd_define_and_export, PANDOC," PANDOC ",pandoc))
%.html : ALL_PANDOCFLAGS += -t html
%.html : %.md

View File

@@ -22,13 +22,8 @@ check_dep:
all: check_dep cmsfs-fuse
ifneq ($(shell sh -c 'command -v pkg-config'),)
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/fuse3
FUSE_LDLIBS = -lfuse3
endif
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
ALL_CFLAGS += -DHAVE_SETXATTR $(FUSE_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) -lm

View File

@@ -1,25 +1,47 @@
ifndef $(COMMON_INCLUDED)
COMMON_INCLUDED = true
COMMON_INCLUDED ?= false
V ?= 0
W ?= 0
G ?= 0
C ?= 0
D ?= 0
ASAN ?= 0
ENABLE_WERROR ?= 0
OPT_FLAGS ?=
MAKECMDGOALS ?=
ifeq ($(COMMON_INCLUDED),false)
COMMON_INCLUDED := true
# 'BUILD_ARCH' is the architecture of the machine where the build takes place
BUILD_ARCH := $(shell uname -m | sed -e 's/i.86/i386/' -e 's/sun4u/sparc64/' -e 's/arm.*/arm/' -e 's/sa110/arm/')
# 'HOST_ARCH' is the architecture of the machine that will run the compiled output
HOST_ARCH ?= $(BUILD_ARCH)
# The `*clean` targets are mutually exclusive to all other targets
ifneq ($(filter %clean,$(MAKECMDGOALS)),)
ifneq ($(MAKECMDGOALS),$(filter %clean,$(MAKECMDGOALS)))
$(error The *clean targets are mutually exclusive to all other targets)
endif
endif
# Global definitions
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2
RELEASE = 26
RELEASE = 28
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
export S390_TOOLS_RELEASE
reldir = $(subst $(shell cd -P $(dir $(filter %common.mak,$(MAKEFILE_LIST))); \
pwd)/,,$(CURDIR))
reldir = $(subst $(realpath $(dir $(filter %common.mak,$(MAKEFILE_LIST))))/,,$(CURDIR))
rootdir= $(dir $(filter %common.mak,$(MAKEFILE_LIST)))
export S390_TEST_LIB_PATH=$(rootdir)/s390-tools-testsuite/lib
#
# For cross compiles specify CROSS_COMPILE= on the commandline:
# For cross compiles specify HOST_ARCH= and CROSS_COMPILE= on the commandline:
#
# $ make CROSS_COMPILE="s390x-5.1.0-"
# $ make HOST_ARCH=s390x CROSS_COMPILE="s390x-linux-gnu-"
#
CROSS_COMPILE =
@@ -29,8 +51,10 @@ CROSS_COMPILE =
#
# $ make CC=gcc-4.8
#
# The "cmd_define" macro wraps the command definition so that the commands
# can be user supplied and are still pretty-printed for the build process.
# The "cmd_define_and_export" macro wraps the command definition so that
# the commands can be user supplied and are still pretty-printed for the
# build process. In addition, the command variable gets exported so it
# can be used by sub-makes.
#
# The macro is called with the following parameters:
#
@@ -40,13 +64,14 @@ CROSS_COMPILE =
#
# The Example below...
#
# $(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
# $(eval $(call cmd_define_and_export, CC," CC ",$(CROSS_COMPILE)gcc))
#
# ... produces the following code:
#
# CC = $(CROSS_COMPILE)gcc
# CC_SILENT := $(CC)
# override CC = $(call echocmd," CC ",/$@)$(CC_SILENT)
# export CC
#
# The "strip" make function is used for the first parameter to allow blanks,
# which improves readability.
@@ -58,23 +83,47 @@ define cmd_define
override $(strip $(1)) = $$(call echocmd,$(2),/$$@)$$($(strip $(1))_SILENT)
endef
$(eval $(call cmd_define, AS," AS ",$(CROSS_COMPILE)as))
$(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
$(eval $(call cmd_define, LINK," LINK ",$(CC)))
$(eval $(call cmd_define, HOSTCC," HOSTCC ",gcc))
$(eval $(call cmd_define, CXX," CXX ",$(CROSS_COMPILE)g++))
$(eval $(call cmd_define, LINKXX," LINKXX ",$(CXX)))
$(eval $(call cmd_define, CPP," CPP ",$(CROSS_COMPILE)gcc -E))
$(eval $(call cmd_define, AR," AR ",$(CROSS_COMPILE)ar))
$(eval $(call cmd_define, NM," NM ",$(CROSS_COMPILE)nm))
$(eval $(call cmd_define, STRIP," STRIP ",$(CROSS_COMPILE)strip))
$(eval $(call cmd_define,OBJCOPY," OBJCOPY ",$(CROSS_COMPILE)objcopy))
$(eval $(call cmd_define,OBJDUMP," OBJDUMP ",$(CROSS_COMPILE)objdump))
define cmd_define_and_export
$(call cmd_define,$(1),$(2),$(3))
export $(strip $(1))
endef
define define_toolchain_variables
$(eval $(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as))
$(eval $(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc))
$(eval $(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1))))
$(eval $(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++))
$(eval $(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1))))
$(eval $(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E))
$(eval $(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar))
$(eval $(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm))
$(eval $(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip))
$(eval $(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy))
$(eval $(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump))
$(eval PKG_CONFIG$(1) = pkg-config)
$(eval export PKG_CONFIG$(1))
endef
# If the host architecture is not the same as the build architecture
# 'CROSS_COMPILE=...' is always required (except for the '*clean' targets).
ifneq ($(HOST_ARCH),$(BUILD_ARCH))
ifeq ($(CROSS_COMPILE),)
# `make clean` and similar must always work!
ifeq ($(filter %clean,$(MAKECMDGOALS)),)
$(error Please specify CROSS_COMPILE=... and try it again!)
endif
endif
endif
$(call define_toolchain_variables,_FOR_BUILD,)
$(call define_toolchain_variables,,$(CROSS_COMPILE))
$(eval $(call cmd_define,RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
$(eval $(call cmd_define, CAT," CAT ",cat))
$(eval $(call cmd_define, SED," SED ",sed))
$(eval $(call cmd_define, GZIP," GZIP ",gzip))
$(eval $(call cmd_define, MV," MV ",mv))
$(eval $(call cmd_define, PERLC," PERLC ",perl -c))
CHECK = sparse
CHECK_SILENT := $(CHECK)
@@ -101,6 +150,10 @@ else
DEFAULT_CFLAGS += -O3
endif
ifeq ("${ENABLE_WERROR}", "1")
DEFAULT_CFLAGS += -Werror
endif
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
DEFAULT_LDFLAGS = -rdynamic
@@ -109,6 +162,11 @@ ifeq ("${ASAN}","1")
DEFAULT_LDFLAGS += -fsanitize=address
endif
DEFAULT_PERLCFLAGS =
ifeq ("${W}","1")
DEFAULT_PERLCFLAGS += -w
endif
#
# Check for header prerequisite
#
@@ -153,8 +211,8 @@ fi
# Returns the linker option if available and nothing otherwise
#
define test_linker_flag
$(shell printf "int main(void) {return 0;}\n" | \
( $(CC) "-Wl,$1" -o /dev/null -x c - ) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
$(shell printf ".globl _start\n_start:\nnop\n" | \
( $(LINK) "-Wl,$1" -o /dev/null -nostdlib -x assembler -) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
endef
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
@@ -235,10 +293,10 @@ ZFCPDUMP_INITRD = zfcpdump-initrd
ZFCPDUMP_FLAVOR = zfcpdump
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
LDFLAGS ?= $(DEFAULT_LDFLAGS)
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
CFLAGS_FOR_BUILD ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
LDFLAGS ?= $(DEFAULT_LDFLAGS)
ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
@@ -256,6 +314,8 @@ ALL_CXXFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
ALL_PERLCFLAGS = $(DEFAULT_PERLCFLAGS)
# make G=1
# Compile tools so that gcov can be used to collect code coverage data.
# See the gcov man page for details.
@@ -264,7 +324,7 @@ ALL_CFLAGS := $(filter-out -O%,$(ALL_CFLAGS)) --coverage
ALL_CXXFLAGS := $(filter-out -O%,$(ALL_CXXFLAGS)) --coverage
ALL_LDFLAGS += --coverage
endif
export AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP INSTALL CFLAGS CXXFLAGS \
export INSTALL CFLAGS CXXFLAGS \
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
@@ -302,12 +362,13 @@ help:
@echo ' clean Delete all generated files'
@echo ''
@echo 'OPTIONS'
@echo ' D=1 Build with debugging option "-Og"'
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
@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 ' D=1 Build with debugging option "-Og"'
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
@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 ' ENABLE_WERROR=1 Build with -Werror'
@echo ''
@echo 'EXAMPLES'
@echo ' # make clean all D=1 W=1 -j'

View File

@@ -323,7 +323,7 @@ static void json_print_virtual_counter_answer(int s, int ctr,
pai_str[paictr], space, paictr + 1);
if (paistate < 0) {
printf("\"error\":%d}", paistate);
/* Protocol does not send furter counters. */
/* Protocol does not send further counters. */
return;
}
printf("\"value\":%"PRIu64"}", paivalue);
@@ -420,7 +420,7 @@ static void json_print_answer(int s, int ctr, int state, uint64_t value)
printf("\"value\":%"PRIu64"}", value);
}
}
int eprint(const char *format, ...)
{

View File

@@ -45,9 +45,8 @@ counter set authorization control" checkbox.
- The daemon requires root privileges to interact with the performance
ioctls of the kernel.
CPU hotplug is not recognized by the daemon. When adding or removing a CPU,
restart the daemon to ensure correct summing of the per-CPU performance
counters.
CPU hotplug is recognized by the daemon. When adding or removing a CPU,
the daemon ensures correct summing of the per-CPU performance counters.
The starting daemon first checks for any stale pid file
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the

View File

@@ -97,7 +97,7 @@ 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;
@@ -252,20 +252,26 @@ static int do_print(int s, enum ctr_e ctr)
}
static int become_daemon(void)
static int become_daemon(int *startup_pipe)
{
int child_initialized = 0, fd;
int pipefds[2];
FILE *f;
int fd;
/* syslog */
openlog("cpacfstatsd", 0, LOG_DAEMON);
if (pipe(pipefds) != 0) {
eprint("pipe() failed, errno=%d [%s]\n", errno, strerror(errno));
return -1;
}
/*
* fork and terminate parent
* Reasons:
* - opens new command line prompt
* - the child process is guaranteed not to be the process group leader
* nessecarry for setsid.
* necessary for setsid.
*/
switch (fork()) {
@@ -276,9 +282,23 @@ static int become_daemon(void)
case 0: /* child */
break;
default: /* parent */
(void)close(pipefds[1]);
if (read(pipefds[0], &child_initialized, sizeof(child_initialized)) !=
sizeof(child_initialized)) {
eprint("Couldn't read from PIPE, errno=%d [%s]\n", errno, strerror(errno));
(void)close(pipefds[0]);
_exit(EXIT_FAILURE);
}
(void)close(pipefds[0]);
if (!child_initialized)
_exit(EXIT_FAILURE);
_exit(0);
}
/* Executed within the child context only */
(void)close(pipefds[0]);
*startup_pipe = pipefds[1];
if (chdir("/") != 0) {
eprint("Chdir('/') failed, errno=%d [%s]\n",
errno, strerror(errno));
@@ -418,7 +438,7 @@ int eprint(const char *format, ...)
int main(int argc, char *argv[])
{
int rc, sfd, foreground = 0;
int rc, sfd, foreground = 0, startup_pipe = -1, initialized = 0;
struct sigaction act;
if (argc > 1) {
@@ -454,27 +474,27 @@ int main(int argc, char *argv[])
}
if (check_pidfile() != 0) {
eprint("Stalled pid file or daemon allready running, terminating\n");
eprint("Stalled pid file or daemon already running, terminating\n");
return EXIT_FAILURE;
}
if (!foreground) {
if (become_daemon() != 0) {
if (become_daemon(&startup_pipe) != 0) {
eprint("Couldn't daemonize\n");
return EXIT_FAILURE;
goto error;
}
}
if (perf_init() != 0) {
eprint("Couldn't initialize perf lib\n");
return EXIT_FAILURE;
goto error;
}
atexit(perf_close);
sfd = open_socket(SERVER);
if (sfd < 0) {
eprint("Couldn't initialize server socket\n");
return EXIT_FAILURE;
goto error;
}
atexit(remove_sock);
@@ -484,17 +504,27 @@ 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));
return EXIT_FAILURE;
goto error;
}
if (sigaction(SIGTERM, &act, 0) != 0) {
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
errno, strerror(errno));
return EXIT_FAILURE;
goto error;
}
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
signal(SIGPIPE, SIG_IGN);
eprint("Running\n");
initialized = 1;
/* `startup_pipe` has been initialized, so we know we are
* running in daemon mode. Let's write to the pipe so that the
* parent knows that the initialization is complete.
*/
if (startup_pipe != -1 &&
write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
goto error;
(void)close(startup_pipe);
startup_pipe = -1;
while (!stopsig) {
enum ctr_e ctr;
@@ -507,13 +537,14 @@ int main(int argc, char *argv[])
continue;
eprint("Accept() failure, errno=%d [%s]\n",
errno, strerror(errno));
return EXIT_FAILURE;
goto error;
}
rc = recv_query(s, &ctr, &cmd);
if (rc != 0) {
eprint("Recv_query() failed, ignoring\n");
goto cleanup;
close(s);
continue;
}
if (cmd == ENABLE)
@@ -527,11 +558,9 @@ int main(int argc, char *argv[])
else {
eprint("Received unknown command %d, ignoring\n",
(int) cmd);
goto cleanup;
close(s);
continue;
}
cleanup:
close(s);
}
if (stopsig == SIGTERM)
@@ -543,4 +572,14 @@ cleanup:
remove_pidfile();
return 0;
error:
if (startup_pipe != -1) {
/* Notify the parent process that there was an error */
if (write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
eprint("Couldn't write to PIPE, errno=%d [%s]\n", errno, strerror(errno));
(void)close(startup_pipe);
}
return EXIT_FAILURE;
}

View File

@@ -371,7 +371,7 @@ static int addallcpus(void)
errno, strerror(errno));
return -1;
}
while (!feof(fp)) {
/* scan all intervals of online cpus */
scanned = fscanf(fp, "%u-%u", &start, &end);
@@ -414,7 +414,7 @@ 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");
@@ -496,10 +496,8 @@ int perf_init(void)
num -= 2;
}
if (num == 0) {
if (num == 0)
eprint("No crypto counters supported!\n");
return -1;
}
if (perf_load_counter_data())
return -1;

View File

@@ -276,9 +276,7 @@ static bool check_setpossible(void)
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);
check = util_zalloc(max_possible_cpus * sizeof(*check));
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
free(check);
return false;
@@ -533,13 +531,8 @@ static int do_read(int ioctlfd)
struct s390_hwctr_read *read;
int rc;
if (!ioctlbuffer) {
ioctlbuffer = malloc(ioctlbuffer_len);
if (!ioctlbuffer) {
warn("ioctl S390_HWCTR_START");
return -ENOMEM;
}
}
if (!ioctlbuffer)
ioctlbuffer = util_malloc(ioctlbuffer_len);
read = (struct s390_hwctr_read *)ioctlbuffer;
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
if (!rc)

View File

@@ -88,12 +88,6 @@ Include the MT_Diagnostic counter set.
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

View File

@@ -118,12 +118,17 @@ Specify the \fImode\fR to be used to format the device. Valid modes are:
.IP full
Format the entire disk with the specified blocksize. (default)
.IP quick
Format the first two tracks and write label and partition information. Only use
this option if you are sure that the target DASD already contains a regular
Format the first two tracks and write label and partition information. Use this
option only if you are sure that the target DASD already contains a regular
format with the specified blocksize. A blocksize can optionally be specified
using \fB-b\fR (\fB--blocksize\fR).
.br
For thin-provisioned DASD ESE volumes this is the default mode.
For thin-provisioned DASD ESE volumes, quick is the default mode. A full space
release then precedes the formatting step. If this space release fails, dasdfmt
falls back to a full-format mode. Formatting stops if the space release fails
and quick mode was specified explicitly using \fB-M\fR. Specify the
\fB--no-discard\fR option to omit the space release.
.IP expand
Format all unformatted tracks at the end of the target DASD. This mode assumes
that tracks at the beginning of the DASD volume have already been correctly

View File

@@ -1230,7 +1230,7 @@ static void dasdfmt_find_start(unsigned int cylinders, unsigned int heads,
format_params->start_unit = first;
}
static void dasdfmt_release_space(void)
static int dasdfmt_release_space(void)
{
format_data_t r = {
.start_unit = 0,
@@ -1240,12 +1240,21 @@ static void dasdfmt_release_space(void)
int err = 0;
if (!g.ese || g.no_discard)
return;
return 0;
printf("Releasing space for the entire device...\n");
err = dasd_release_space(g.dev_node, &r);
if (err)
/*
* Warn or Error on failing RAS depending on QUICK mode set explicitly or automatically
*/
if (err && !g.mode_specified) {
warnx("Could not release space. Falling back to full format.");
return 1;
} else if (err && g.mode_specified) {
error("Could not release space: %s", strerror(err));
}
return 0;
}
static void dasdfmt_prepare_and_format(unsigned int cylinders, unsigned int heads,
@@ -1445,8 +1454,12 @@ static void do_format_dasd(volume_label_t *vlabel, format_data_t *p,
dasdfmt_prepare_and_format(cylinders, heads, p);
break;
case QUICK:
dasdfmt_release_space();
dasdfmt_quick_format(cylinders, heads, p);
if (dasdfmt_release_space()) {
p->stop_unit = (cylinders * heads) - 1;
dasdfmt_prepare_and_format(cylinders, heads, p);
} else {
dasdfmt_quick_format(cylinders, heads, p);
}
break;
case EXPAND:
dasdfmt_expand_format(cylinders, heads, p);

View File

@@ -16,13 +16,8 @@ check_dep:
BUILDTARGET = check_dep
ifneq ($(shell sh -c 'command -v pkg-config'),)
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
else
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
CURL_LDLIBS = -lcurl
endif # shell
CURL_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
CURL_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
endif # HAVE_CURL

View File

@@ -12,8 +12,6 @@ all: all-recursive
install: all install-recursive
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3a.bin "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3b_reloc.bin "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
clean: clean-recursive

View File

@@ -1,8 +1,12 @@
# Common definitions
include ../../common.mak
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
ifeq ($(HOST_ARCH),s390x)
ZIPL_DIR := $(rootdir)/zipl
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
PKGDATADIR := $(DESTDIR)$(TOOLS_DATADIR)/genprotimg
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
@@ -15,11 +19,9 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
-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 \
-Wno-array-bounds
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
ZIPL_SRCS_ASM := entry.S
@@ -27,9 +29,6 @@ ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o)
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
all: $(FILES)
# Prevent make from using some default rules...
%: %.S
@@ -80,6 +79,26 @@ stage3b.elf: head.o $(ZIPL_OBJS)
$(OBJCOPY) -O binary $< $@
@chmod a-x $@
install: stage3a.bin stage3b_reloc.bin
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3a.bin "$(PKGDATADIR)"
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3b_reloc.bin "$(PKGDATADIR)"
else
# Don't generate the dependency files (see `common.mak` for the
# `-include $(dependencies_c)` statement).
.PHONY: $(dependencies_c)
$(FILES):
echo " SKIP $@ due to HOST_ARCH != s390x"
install:
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
endif
.DEFAULT_GOAL := all
all: $(FILES)
clean:
rm -f *.o *.elf *.bin *.map .*.d *.lds

View File

@@ -11,7 +11,6 @@
#include "stage3a.h"
#include "lib/zt_common.h"
#include "boot/s390.h"
#include "boot/ipl.h"
#include "sclp.h"
#include "error.h"

View File

@@ -11,7 +11,7 @@
#include "stage3b.h"
#include "lib/zt_common.h"
#include "boot/s390.h"
#include "boot/psw.h"
#include "boot/linux_layout.h"
#include "boot/loaders_layout.h"
#include "sclp.h"

View File

@@ -21,7 +21,7 @@
#include <stdint.h>
#include "boot/s390.h"
#include "boot/psw.h"
/* Must not have any padding included */
struct memblob {

View File

@@ -17,7 +17,7 @@ WARNINGS := -Wall -Wextra -Wshadow \
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Werror -Wno-error=inline \
-Wpointer-arith -Wno-error=inline \
$(NULL)
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
@@ -36,21 +36,12 @@ ALL_CPPFLAGS += $(INCLUDE_PARMS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
ifneq ($(shell sh -c 'command -v pkg-config'),)
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
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)
BUILD_TARGETS := skip-$(bin_PROGRAM)
INSTALL_TARGETS := skip-$(bin_PROGRAM)

View File

@@ -13,7 +13,6 @@
#include <glib/gi18n.h>
#include "boot/linux_layout.h"
#include "boot/s390.h"
#include "lib/zt_common.h"
static const gchar tool_name[] = "genprotimg";

View File

@@ -12,7 +12,7 @@
#include <openssl/sha.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "lib/zt_common.h"
#include "utils/crypto.h"

View File

@@ -15,7 +15,6 @@
#include <stdio.h>
#include <string.h>
#include "boot/s390.h"
#include "common.h"
#include "utils/align.h"
#include "utils/buffer.h"

View File

@@ -12,7 +12,7 @@
#include <openssl/evp.h>
#include <stdint.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "boot/stage3b.h"
#include "common.h"
#include "utils/align.h"

View File

@@ -14,7 +14,7 @@
#include <openssl/evp.h>
#include <stdint.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "boot/stage3b.h"
#include "utils/buffer.h"

View File

@@ -14,7 +14,7 @@
#include <stdint.h>
#include <string.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "include/pv_crypto_def.h"
#include "utils/buffer.h"
#include "utils/crypto.h"

View File

@@ -13,7 +13,6 @@
#include <glib.h>
#include <stdint.h>
#include "boot/s390.h"
#include "include/pv_hdr_def.h"
#include "utils/crypto.h"
#include "utils/buffer.h"

View File

@@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "boot/stage3a.h"
#include "common.h"
#include "include/pv_crypto_def.h"

View File

@@ -15,7 +15,7 @@
#include <openssl/evp.h>
#include <stdint.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "utils/buffer.h"
#include "pv_args.h"

View File

@@ -13,7 +13,6 @@
#include <stdio.h>
#include "boot/ipl.h"
#include "boot/s390.h"
#include "common.h"
#include "include/pv_hdr_def.h"
#include "lib/zt_common.h"

View File

@@ -15,7 +15,6 @@
#include <stdint.h>
#include "boot/ipl.h"
#include "boot/s390.h"
#include "boot/stage3b.h"
#include "utils/buffer.h"

View File

@@ -10,8 +10,8 @@
#ifndef PV_UTILS_ALIGN_H
#define PV_UTILS_ALIGN_H
#include "boot/s390.h"
#include "lib/zt_common.h"
#include "boot/page.h"
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))

View File

@@ -24,7 +24,7 @@
#include <stdint.h>
#include <string.h>
#include "boot/s390.h"
#include "boot/page.h"
#include "common.h"
#include "include/pv_crypto_def.h"
#include "pv/pv_error.h"

View File

@@ -19,13 +19,8 @@ check_dep:
"fuse3-devel or libfuse3-dev", \
"HAVE_FUSE=0")
ifneq ($(shell sh -c 'command -v pkg-config'),)
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/fuse3
FUSE_LDLIBS = -lfuse3
endif
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
ALL_CFLAGS += -DFUSE_USE_VERSION=30 -D_LARGEFILE_SOURCE $(FUSE_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm

View File

@@ -22,26 +22,16 @@ else # HAVE_FUSE
#
# FUSE
#
ifneq ($(shell sh -c 'command -v pkg-config'),)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
else
FUSE_CFLAGS = -I/usr/include/fuse3
FUSE_LDLIBS = -lfuse3
endif
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
#
# systemd
#
ifneq (${HAVE_SYSTEMD},0)
ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
ifneq ($(shell sh -c 'command -v pkg-config'),)
SYSTEMD_CFLAGS = $(shell pkg-config --silence-errors --cflags libsystemd)
SYSTEMD_LDLIBS = $(shell pkg-config --silence-errors --libs libsystemd)
else
SYSTEMD_CFLAGS =
SYSTEMD_LDLIBS = -lsystemd
endif
SYSTEMD_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libsystemd)
SYSTEMD_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libsystemd)
ALL_CPPFLAGS += -DHAVE_SYSTEMD
else
$(warning "systemd support disabled")

View File

@@ -311,6 +311,7 @@ static struct sd_sys_item *l_sys_item_vec[] = {
static struct sd_sys_item *l_sys_item_enable_vec[] = {
&sd_sys_item_core_cnt,
&sd_sys_item_core_diff,
&sd_sys_item_thread_diff,
&sd_sys_item_mgm_diff,
&sd_sys_item_core,
&sd_sys_item_mgm,
@@ -339,6 +340,7 @@ static struct sd_cpu_item *l_cpu_item_vec[] = {
static struct sd_cpu_item *l_cpu_item_enable_vec[] = {
&sd_cpu_item_type,
&sd_cpu_item_core_diff,
&sd_cpu_item_thread_diff,
&sd_cpu_item_mgm_diff,
NULL,
};

View File

@@ -85,7 +85,8 @@ enum blkptr_format_id {
* this is the "new" format which serves only List-Directed IPL,
* but is also suitable for CCW-type IPL.
*/
BLKPTR_FORMAT_ID
BLKPTR_FORMAT_ID,
NR_BLKPTR_FORMATS
};
/*
@@ -194,15 +195,25 @@ struct boot_info_bp_dump {
uint8_t unused[16];
} __packed;
/* This represents on-disk pointer to a block on disk */
union disk_blockptr {
struct eckd_blockptr_legacy eckd_legacy;
struct eckd_blockptr eckd;
struct linear_blockptr linear;
};
struct boot_info_bp_ipl {
union {
struct eckd_blockptr_legacy eckd_legacy;
struct eckd_blockptr eckd;
struct linear_blockptr lin;
} bm_ptr;
union disk_blockptr bm_ptr;
uint8_t unused[16];
} __packed;
struct disk_program_table {
uint32_t magic;
uint32_t version;
uint64_t unused;
union disk_blockptr component_table[0];
} __packed;
struct boot_info {
char magic[4];
uint8_t version;

View File

@@ -11,7 +11,7 @@
#define IPL_H
#include "lib/zt_common.h"
#include "s390.h"
#include "page.h"
#define IPL_FLAG_SECURE 0x40

15
include/boot/page.h Normal file
View File

@@ -0,0 +1,15 @@
/*
* Page related definitions and functions.
*
* Copyright IBM Corp. 2023
*
* 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 BOOT_PAGE_H
#define BOOT_PAGE_H
#include "lib/zt_common.h"
#define PAGE_SIZE _AC(4096, UL)
#endif

31
include/boot/psw.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* Program Status Word related definitions and functions.
*
* Copyright IBM Corp. 2023
*
* 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 BOOT_PSW_H
#define BOOT_PSW_H
#include "lib/zt_common.h"
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
#define PSW_LOAD _AC(0x0008000080000000, UL)
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
#ifndef __ASSEMBLER__
#include <stdint.h>
struct psw_t {
uint64_t mask;
uint64_t addr;
} __aligned(8);
#endif
#endif

View File

@@ -1,7 +1,8 @@
/*
* s390 related definitions and functions.
* Should only be used for code targeting s390 (bootloader code)
*
* Copyright IBM Corp. 2013, 2020
* Copyright IBM Corp. 2013, 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -12,29 +13,22 @@
#include "lib/zt_common.h"
#include "boot/sigp.h"
#include "boot/psw.h"
#include "boot/page.h"
#define __LC_IPLDEV 0x0c6c
#define __LC_OS_INFO 0x0e18
#define LOWCORE_SIZE _AC(0x2000, UL)
#define PAGE_SIZE _AC(4096, UL)
/* Minimum size of a stack frame in bytes */
#define STACK_FRAME_OVERHEAD _AC(160, U)
/* Facilities */
#define UNPACK_FACILITY _AC(161, U)
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
#define PSW_LOAD _AC(0x0008000080000000, UL)
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
#ifndef __ASSEMBLER__
#include <stdint.h>
/*
* Helper macro for exception table entries
@@ -46,18 +40,6 @@
".long (" #_target ")\n" \
".previous\n"
struct psw_t {
uint64_t mask;
uint64_t addr;
} __aligned(8);
struct psw32_t {
uint32_t mask;
uint32_t addr;
} __aligned(8);
void load_wait_psw(uint64_t, struct psw_t *);
struct subchannel_id {
uint32_t cssid:8;
uint32_t:4;

View File

@@ -13,7 +13,7 @@
#include <openssl/sha.h>
#include "boot/s390.h"
#include "boot/psw.h"
#include "libpv/crypto.h"
#include "libpv/macros.h"

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# z/VM IUCV HVC device driver -- Edit z/VM user ID filter
#

View File

@@ -5,21 +5,12 @@ include ../common.mak
LIB := libpv.a
ifneq ($(shell sh -c 'command -v pkg-config'),)
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 openssl)
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto openssl)
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 -lssl
LIBCURL_CFLAGS := -I/usr/include/s390x-linux-gnu
LIBCURL_LIBS := -lcurl
endif
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)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
WARNINGS := -Wall -Wextra -Wshadow \
@@ -28,7 +19,6 @@ WARNINGS := -Wall -Wextra -Wshadow \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Wno-error=inline \
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
-Werror \
$(NULL)
ALL_CFLAGS += -std=gnu11 \

View File

@@ -174,6 +174,20 @@ static OSSL_FUNC_keymgmt_settable_params_fn
sk_prov_keymgmt_rsa_pss_settable_params;
static OSSL_FUNC_keymgmt_settable_params_fn
sk_prov_keymgmt_ec_settable_params;
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
static OSSL_FUNC_keymgmt_export_types_ex_fn
sk_prov_keymgmt_rsa_export_types_ex;
static OSSL_FUNC_keymgmt_export_types_ex_fn
sk_prov_keymgmt_rsa_pss_export_types_ex;
static OSSL_FUNC_keymgmt_export_types_ex_fn
sk_prov_keymgmt_ec_export_types_ex;
static OSSL_FUNC_keymgmt_import_types_ex_fn
sk_prov_keymgmt_rsa_import_types_ex;
static OSSL_FUNC_keymgmt_import_types_ex_fn
sk_prov_keymgmt_rsa_pss_import_types_ex;
static OSSL_FUNC_keymgmt_import_types_ex_fn
sk_prov_keymgmt_ec_import_types_ex;
#else
static OSSL_FUNC_keymgmt_export_types_fn
sk_prov_keymgmt_rsa_export_types;
static OSSL_FUNC_keymgmt_export_types_fn
@@ -185,6 +199,7 @@ static OSSL_FUNC_keymgmt_import_types_fn
static OSSL_FUNC_keymgmt_import_types_fn
sk_prov_keymgmt_rsa_pss_import_types;
static OSSL_FUNC_keymgmt_import_types_fn sk_prov_keymgmt_ec_import_types;
#endif
static OSSL_FUNC_keyexch_newctx_fn sk_prov_keyexch_ec_newctx;
static OSSL_FUNC_keyexch_dupctx_fn sk_prov_keyexch_ec_dupctx;
@@ -2947,14 +2962,14 @@ static const OSSL_PARAM sk_prov_imexport_types[] = {
OSSL_PARAM_END
};
static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
int pkey_type)
static const OSSL_PARAM *sk_prov_keymgmt_export_types(
struct sk_prov_ctx *provctx,
int selection,
int pkey_type)
{
OSSL_FUNC_keymgmt_export_types_fn *default_export_types_fn;
const OSSL_PARAM *default_parms = NULL, *params;
struct sk_prov_ctx *provctx;
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
if (provctx == NULL)
return NULL;
@@ -2982,14 +2997,14 @@ static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
sk_prov_imexport_types);
}
static const OSSL_PARAM *sk_prov_keymgmt_import_types(int selection,
int pkey_type)
static const OSSL_PARAM *sk_prov_keymgmt_import_types(
struct sk_prov_ctx *provctx,
int selection,
int pkey_type)
{
OSSL_FUNC_keymgmt_import_types_fn *default_import_types_fn;
const OSSL_PARAM *default_parms = NULL, *params;
struct sk_prov_ctx *provctx;
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
if (provctx == NULL)
return NULL;
@@ -3337,15 +3352,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_settable_params(void *vprovctx)
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA);
}
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types_ex(void *vprovctx,
int selection)
{
struct sk_prov_ctx *provctx = vprovctx;
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
}
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types_ex(void *vprovctx,
int selection)
{
struct sk_prov_ctx *provctx = vprovctx;
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
}
#else
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types(int selection)
{
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA);
struct sk_prov_ctx *provctx =
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
}
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types(int selection)
{
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA);
struct sk_prov_ctx *provctx =
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
}
#endif
static void *sk_prov_keymgmt_rsa_gen_init(void *vprovctx, int selection,
const OSSL_PARAM params[])
@@ -3407,15 +3446,43 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_settable_params(void *vprovctx)
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA_PSS);
}
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types_ex(void *vprovctx,
int selection)
{
struct sk_prov_ctx *provctx = vprovctx;
return sk_prov_keymgmt_export_types(provctx, selection,
EVP_PKEY_RSA_PSS);
}
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types_ex(void *vprovctx,
int selection)
{
struct sk_prov_ctx *provctx = vprovctx;
return sk_prov_keymgmt_import_types(provctx, selection,
EVP_PKEY_RSA_PSS);
}
#else
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types(int selection)
{
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA_PSS);
struct sk_prov_ctx *provctx =
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
return sk_prov_keymgmt_export_types(provctx, selection,
EVP_PKEY_RSA_PSS);
}
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types(int selection)
{
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA_PSS);
struct sk_prov_ctx *provctx =
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
return sk_prov_keymgmt_import_types(provctx, selection,
EVP_PKEY_RSA_PSS);
}
#endif
static void *sk_prov_keymgmt_rsa_pss_gen_init(void *vprovctx, int selection,
const OSSL_PARAM params[])
@@ -3490,15 +3557,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_ec_settable_params(void *vprovctx)
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_EC);
}
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types_ex(void *vprovctx,
int selection)
{
struct sk_prov_ctx *provctx = vprovctx;
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
}
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types_ex(void *vprovctx,
int selection)
{
struct sk_prov_ctx *provctx = vprovctx;
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
}
#else
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types(int selection)
{
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_EC);
struct sk_prov_ctx *provctx =
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
}
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types(int selection)
{
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_EC);
struct sk_prov_ctx *provctx =
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
}
#endif
static void *sk_prov_keymgmt_ec_gen_init(void *vprovctx, int selection,
const OSSL_PARAM params[])
@@ -4648,11 +4739,21 @@ static const OSSL_DISPATCH sk_prov_rsa_keymgmt_functions[] = {
/* Import and export routines */
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
(void (*)(void))sk_prov_keymgmt_rsa_export_types_ex },
#else
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
(void (*)(void))sk_prov_keymgmt_rsa_export_types },
#endif
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
(void (*)(void))sk_prov_keymgmt_rsa_import_types_ex },
#else
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
(void (*)(void))sk_prov_keymgmt_rsa_import_types },
#endif
/* No copy function, OpenSSL will use export/import to copy instead */
{ 0, NULL }
@@ -4697,11 +4798,21 @@ static const OSSL_DISPATCH sk_prov_rsapss_keymgmt_functions[] = {
/* Import and export routines */
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types_ex },
#else
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types },
#endif
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types_ex },
#else
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types },
#endif
/* No copy function, OpenSSL will use export/import to copy instead */
{ 0, NULL }
@@ -4746,11 +4857,21 @@ static const OSSL_DISPATCH sk_prov_ec_keymgmt_functions[] = {
/* Import and export routines */
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
(void (*)(void))sk_prov_keymgmt_ec_export_types_ex },
#else
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
(void (*)(void))sk_prov_keymgmt_ec_export_types },
#endif
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
(void (*)(void))sk_prov_keymgmt_ec_import_types_ex },
#else
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
(void (*)(void))sk_prov_keymgmt_ec_import_types },
#endif
/* No copy function, OpenSSL will use export/import to copy instead */
{ 0, NULL }

View File

@@ -776,6 +776,10 @@ int SK_UTIL_build_ecdsa_signature(const unsigned char *raw_sig,
bn_s = NULL;
der_len = i2d_ECDSA_SIG(ec_sig, NULL);
if (der_len <= 0) {
rc = -EIO;
goto out;
}
if (sig == NULL) {
*sig_len = der_len;
@@ -788,13 +792,14 @@ int SK_UTIL_build_ecdsa_signature(const unsigned char *raw_sig,
memset(sig, 0, *sig_len);
der = sig;
*sig_len = i2d_ECDSA_SIG(ec_sig, &der);
if (*sig_len == 0) {
der_len = i2d_ECDSA_SIG(ec_sig, &der);
if (der_len <= 0) {
rc = -EIO;
goto out;
}
*sig_len = der_len;
out:
if (ec_sig != NULL)
ECDSA_SIG_free(ec_sig);

View File

@@ -17,7 +17,6 @@ WARNINGS := -Wall -Wextra -Wshadow \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Wno-error=inline \
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
-Werror \
$(NULL)
PVATTEST_SRCS := $(wildcard *.c) \
@@ -29,21 +28,12 @@ $(BIN_PROGRAM)_SRCS := \
$(BIN_PROGRAM)_OBJS := $($(BIN_PROGRAM)_SRCS:.c=.o)
ifneq ($(shell sh -c 'command -v pkg-config'),)
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 openssl)
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto openssl)
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 -lssl
LIBCURL_CFLAGS := -I/usr/include/s390x-linux-gnu
LIBCURL_LIBS := -lcurl
endif
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)
ALL_CFLAGS += -std=gnu11 \
-DPKGDATADIR=$(PKGDATADIR) \

View File

@@ -14,7 +14,7 @@ set -o pipefail
set -o nounset
set -e
XDUMP='od -A x -t x2z -v'
XDUMP='od -A x -t x2z -v --endian=big'
usage() {
cat <<-EOF

View File

@@ -14,7 +14,7 @@ set -o pipefail
set -o nounset
set -e
XDUMP='od -A x -t x2z -v'
XDUMP='od -A x -t x2z -v --endian=big'
def_output='sehdr.bin'
def_skip=0x14

1
scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/.zfcpdbf.ct

View File

@@ -36,4 +36,21 @@ install:
clean:
.zfcpdbf.ct: zfcpdbf
$(PERLC) $(ALL_PERLCFLAGS) zfcpdbf 2>$(@); \
if [ "$${?}" -ne 0 ]; then \
cat "$(@)" >&2 && rm "$(@)"; \
elif [ "$$(cat '$(@)' | wc -l)" -gt 1 ]; then \
cat "$(@)" >&2; \
elif [ " $(V)" = " 1" ]; then \
cat "$(@)"; \
fi
.PHONY: .zfcpdbf.ct-clean
.zfcpdbf.ct-clean:
rm -f .zfcpdbf.ct
all: .zfcpdbf.ct
clean: .zfcpdbf.ct-clean
.PHONY: all install clean

View File

@@ -409,6 +409,7 @@ CONFIGFILES="\
/etc/multipath\
/etc/network\
/etc/networks\
/etc/opencryptoki/*.conf\
/etc/pam.d\
/etc/profile\
/etc/profile.d\
@@ -513,13 +514,20 @@ CMDS="${CMDS}\
# crypto specific commands
CMDS="${CMDS}\
:cat /var/lib/opencryptoki/pk_config_data\
:ep11info -D\
:ep11info -H\
:ep11info -M\
:icainfo\
:icastats\
:icastats --all\
:ivp.e # IBM CCA package install check\
:ls -al /usr/lib64/opencryptoki/stdll\
:lszcrypt -VV\
:pkcsconf -mlist\
:pkcsconf -i\
:pkcsconf -s\
:pkcsconf -l\
:pkcsconf -t\
:pkcsconf -m\
:systemctl status pkcsslotd\
"
# product / distro specific commands
@@ -567,6 +575,7 @@ NETWORK_CMDS="ip -br a\
:netstat -pantu\
:netstat -s\
:nm-tool\
:nstat -az\
:openssl engine\
:route -n\
"

View File

@@ -301,6 +301,9 @@ setup_reipl()
fi
case "$REIPL_TYPE" in
eckd)
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
;;
ccw)
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
;;
@@ -332,6 +335,9 @@ setup_reipl()
setup_dump()
{
case "$DUMP_TYPE" in
eckd)
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
;;
ccw)
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
;;
@@ -408,6 +414,16 @@ print_ccw_device()
pr_info "device..: $DEVICE"
}
print_eckd_device()
{
DEVICE=$(cat $1/eckd/device) || RETVAL=1
pr_info "device..: $DEVICE"
BR_CHR=$(cat $1/eckd/br_chr) || RETVAL=1
pr_info "br_chr..: $BR_CHR"
BOOTPROG=$(cat $1/eckd/bootprog) || RETVAL=1
pr_info "bootprog: $BOOTPROG"
}
print_nvme_device()
{
FID=$(cat $1/nvme/fid) || RETVAL=1
@@ -433,6 +449,11 @@ status_dump()
none)
pr_info "type....: no dump device configured"
;;
eckd)
pr_info "type....: eckd"
print_eckd_device $DUMP_CONFIG_DIR
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/eckd/device)
;;
ccw)
pr_info "type....: ccw"
print_ccw_device $DUMP_CONFIG_DIR
@@ -458,6 +479,9 @@ status_reipl()
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
pr_info "type....: $REIPL_TYPE"
case "$REIPL_TYPE" in
eckd)
print_eckd_device $REIPL_CONFIG_DIR
;;
ccw)
print_ccw_device $REIPL_CONFIG_DIR
;;

View File

@@ -59,7 +59,7 @@ endif
$(SUB_DIRS):
$(foreach goal,$(MAKECMDGOALS), \
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
.PHONY: $(SUB_DIRS)
.PHONY: all install clean install-scripts install-manpages install-usrsbin-scripts

View File

@@ -1,10 +1,16 @@
.\" chzcrypt.8
.\"
.\" Copyright 2020 IBM Corp.
.\" Copyright 2020, 2023 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 CHZCRYPT 8 "OCT 2020" "s390-tools"
.\" use
.\" groff -man -Tutf8 chzcrypt.8
.\" or
.\" nroff -man chzcrypt.8
.\" to process this source
.\"
.TH CHZCRYPT 8 "MAY 2023" "s390-tools"
.SH NAME
chzcrypt \- modify zcrypt configuration
.SH SYNOPSIS
@@ -46,8 +52,8 @@ chzcrypt \- modify zcrypt configuration
.SH DESCRIPTION
The
.B chzcrypt
command is used to configure cryptographic devices managed by zcrypt and
modify zcrypt's AP bus attributes.
command is used to configure cryptographic devices managed by zcrypt
and modify zcrypt's AP bus attributes.
Attributes may vary depending on the kernel
version.
@@ -70,19 +76,6 @@ Set the given cryptographic card device(s) config on ('configured').
.B --config-off
Set the given cryptographic card device(s) config off ('deconfigured').
.TP 8
.B <device id>
Specifies a cryptographic device which will be set either online or
offline or configured on or off. For online and offline the device can
either be a card device or a queue device. A queue device can only get
switched online when the providing card is online.
.br
For config on/off the device needs to be a card device. A card or
queue device cannot get switched online if the card is in deconfigured
state.
.br
Please note that the card device and queue device representation are both
in hexadecimal notation.
.TP 8
.B -p, --poll-thread-enable
Enable zcrypt's poll thread.
.TP 8
@@ -94,15 +87,28 @@ Set configuration timer for re-scanning the AP bus to
.I <timeout>
seconds.
.TP 8
.B --se-associate <association-index> <queue-device>
Associate the given queue device with the given association
index. This command is only valid within an Secure Execution guest
with AP pass-through support enabled.
.TP 8
.B --se-bind <queue-device>
Bind the given queue device. This command is only valid within an
Secure Execution guest with AP pass-through support enabled.
.TP 8
.B --se-unbind <queue-device>
Unbind the given queue device. This command is only valid within an
Secure Execution guest with AP pass-through support enabled.
.TP 8
.BI "-t, --poll-timeout" " <poll_timeout>"
Set poll timer to run poll tasklet all
.I <poll_timeout>
nanoseconds.
.TP 8
.BI "-q, --default-domain" " <domain>"
Set the new default domain of the AP bus to <domain>.
The number of available domains can be retrieved with the lszcrypt
command ('-d' option).
Set the new default domain of the AP bus to <domain>. The number of
available domains can be retrieved with the lszcrypt command ('-d'
option).
.TP 8
.B -V, --verbose
Print verbose messages.
@@ -112,6 +118,22 @@ Print help text and exit.
.TP 8
.B -v, --version
Print version information and exit.
.TP 8
.B <device id>
Specifies a cryptographic device which will be set either online or
offline or configured on or off. For online and offline the device can
either be a card device or a queue device. A queue device can only get
switched online when the providing card is online.
.br
For config on/off the device needs to be a card device. A card or
queue device cannot get switched online if the card is in deconfigured
state.
.br
Please note that the card device and queue device representation are
both in hexadecimal notation.
.TP 8
.B <queue-device>
An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.
.SH EXAMPLES
.TP
.B chzcrypt -e 0 1 12
@@ -131,8 +153,8 @@ Set all available crypto cards to config on, be verbose.
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
.TP
.B chzcrypt -c 60 -n
Will set configuration timer for re-scanning the AP bus to 60 seconds and
disable zcrypt's poll thread.
Will set configuration timer for re-scanning the AP bus to 60 seconds
and disable zcrypt's poll thread.
.TP
.B chzcrypt -q 67
Will set the default domain to 67.
@@ -144,5 +166,11 @@ chzcrypt exits with an appropriate message. Even more config on/off
may require support from a hypervisor like KVM or zVM and may fail if
the Linux kernel is unable to perform the SCLP command. Check syslog
on failure.
.TP
Bind, associate and unbind command on an queue device are only
available and valid within an Secure Execution environment with AP
pass-through enabled and a Linux kernel providing the low level sysfs
API. If these conditions are not fulfilled, the command will fail with
an appropriate error messages.
.SH SEE ALSO
\fBlszcrypt\fR(8)

View File

@@ -1,7 +1,7 @@
/*
* chzcrypt - Tool to modify zcrypt configuration
*
* Copyright IBM Corp. 2008, 2020
* Copyright IBM Corp. 2008, 2023
*
* 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,12 @@
#include "misc.h"
/* max seconds the se-association command will wait for completion */
#define MAX_ASSOC_POLL_TIME_IN_S 30
/* max seconds the se-unbind command will wait for unbind complete */
#define MAX_UNBIND_POLL_TIME_IN_S 30
/*
* Private data
*/
@@ -45,7 +51,7 @@ static const struct util_prg prg = {
{
.owner = "IBM Corp.",
.pub_first = 2008,
.pub_last = 2020,
.pub_last = 2023,
},
UTIL_PRG_COPYRIGHT_END
}
@@ -57,6 +63,9 @@ static const struct util_prg prg = {
#define OPT_CONFIG_ON 0x80
#define OPT_CONFIG_OFF 0x81
#define OPT_SE_ASSOC 0x82
#define OPT_SE_BIND 0x83
#define OPT_SE_UNBIND 0x84
static struct util_opt opt_vec[] = {
{
@@ -116,6 +125,22 @@ static struct util_opt opt_vec[] = {
.option = { "verbose", no_argument, NULL, 'V'},
.desc = "Print verbose messages",
},
{
.option = { "se-associate", required_argument, NULL, OPT_SE_ASSOC},
.argument = "assoc_idx",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "SE guest with AP support only: Associate the given queue device",
},
{
.option = { "se-bind", no_argument, NULL, OPT_SE_BIND},
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "SE guest with AP support only: Bind the given queue device",
},
{
.option = { "se-unbind", no_argument, NULL, OPT_SE_UNBIND},
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "SE guest with AP support only: Unbind the given queue device",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
@@ -336,6 +361,186 @@ next:
}
}
static void se_assoc(const char *assoc_idx, const char *dev)
{
int i, idx, rc, ap, dom, loop;
char *dev_path, *attr;
char buf[256];
if (!ap_bus_has_SB_support())
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
dev);
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
ap, ap, dom);
if (!util_path_is_dir(dev_path))
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
dev);
if (sscanf(assoc_idx, "%i", &idx) != 1)
errx(EXIT_FAILURE, "Error - Can't parse association index '%s' as number.",
assoc_idx);
if (idx < 0 || idx > 0xFFFF)
errx(EXIT_FAILURE, "Error - Association index needs to be in range [0...%d].",
0xffff);
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_associate",
ap, ap, dom);
if (!util_path_is_writable(attr))
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
attr, strerror(errno));
/* read se_associate attribute and check for 'unassociated' */
rc = util_file_read_line(buf, sizeof(buf), attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
attr, strerror(errno));
if (strcmp(buf, "unassociated"))
errx(EXIT_FAILURE,
"Error - Queue device %s is NOT in 'unassociated' state (state '%s' found).",
dev, buf);
/* write assocition index to the se_associate attribute */
rc = util_file_write_l(idx, 10, attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
attr, strerror(errno));
/* loop up to MAX_ASSOC_POLL_TIME_IN_S seconds for completion */
for (loop = 0; loop < 2 * MAX_ASSOC_POLL_TIME_IN_S; usleep(500000), loop++) {
rc = util_file_read_line(buf, sizeof(buf), attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
attr, strerror(errno));
if (!strncmp(buf, "associated", strlen("associated")))
break;
if (!strcmp(buf, "unassociated"))
errx(EXIT_FAILURE,
"Error - Failure associating queue device %s (state '%s' found).",
dev, buf);
}
if (loop >= 2 * MAX_ASSOC_POLL_TIME_IN_S)
errx(EXIT_FAILURE,
"Error - Failure associating queue device %s (timeout after %d s).",
dev, MAX_ASSOC_POLL_TIME_IN_S);
if (sscanf(buf, "associated %d", &i) != 1 || idx != i)
errx(EXIT_FAILURE,
"Error - Failure associating queue device %s (state '%s' found).",
dev, buf);
verbose("Queue device %s successful associated with index %d.\n",
dev, idx);
free(dev_path);
free(attr);
}
static void se_bind(const char *dev)
{
char *dev_path, *attr;
int rc, ap, dom;
char buf[256];
if (!ap_bus_has_SB_support())
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
dev);
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
ap, ap, dom);
if (!util_path_is_dir(dev_path))
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
dev);
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
ap, ap, dom);
if (!util_path_is_writable(attr))
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
attr, strerror(errno));
/* read se_bind attribute and check for 'unboud' */
rc = util_file_read_line(buf, sizeof(buf), attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
attr, strerror(errno));
if (strcmp(buf, "unbound"))
errx(EXIT_FAILURE,
"Error - Queue device %s is NOT in 'unbound' state (state '%s' found).",
dev, buf);
/* write se_bind attribute, check for 'bound' afterwards */
rc = util_file_write_l(1, 10, attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
attr, strerror(errno));
rc = util_file_read_line(buf, sizeof(buf), attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
attr, strerror(errno));
if (strcmp(buf, "bound"))
errx(EXIT_FAILURE, "Error - Failure binding queue device %s (state '%s' found).",
dev, buf);
verbose("Queue device %s successful bound.\n", dev);
free(dev_path);
free(attr);
}
static void se_unbind(const char *dev)
{
int rc, ap, dom, loop;
char *dev_path, *attr;
char buf[256];
if (!ap_bus_has_SB_support())
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
dev);
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
ap, ap, dom);
if (!util_path_is_dir(dev_path))
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
dev);
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
ap, ap, dom);
if (!util_path_is_writable(attr))
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
attr, strerror(errno));
/* write se_bind attribute */
rc = util_file_write_l(0, 10, attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
attr, strerror(errno));
/* loop up to MAX_UNBIND_POLL_TIME_IN_S seconds for completion */
for (loop = 0; loop < 2 * MAX_UNBIND_POLL_TIME_IN_S; usleep(500000), loop++) {
rc = util_file_read_line(buf, sizeof(buf), attr);
if (rc)
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
attr, strerror(errno));
if (!strcmp(buf, "unbound"))
break;
}
if (loop >= 2 * MAX_UNBIND_POLL_TIME_IN_S)
errx(EXIT_FAILURE,
"Error - Failure unbinding queue device %s (timeout after %d s).",
dev, MAX_UNBIND_POLL_TIME_IN_S);
verbose("Queue device %s successful unbound.\n", dev);
free(dev_path);
free(attr);
}
/*
* Print invalid commandline error message and then exit with error code
*/
@@ -389,10 +594,10 @@ static void print_adapter_id_help(void)
printf("DEVICE_IDS\n");
printf(" List of cryptographic device ids separated by blanks which will be set\n");
printf(" online/offline. Must be used in conjunction with the enable or disable option.\n");
printf(" DEVICE_ID could either be card device id ('<card-id>') or queue device id\n");
printf(" '<card-id>.<domain-id>').\n");
printf(" \n");
printf(" '<card-id>.<domain-id>').\n\n");
printf("QUEUE_DEVICE:\n");
printf(" An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.\n\n");
printf("EXAMPLE:\n");
printf(" Disable the cryptographic device with card id '02' (inclusive all queues).\n");
printf(" #>chzcrypt -d 02\n");
@@ -407,13 +612,14 @@ static void print_adapter_id_help(void)
*/
int main(int argc, char *argv[])
{
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
const char *config_time = NULL, *poll_timeout = NULL;
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
const char *queue_device = NULL, *assoc_idx = NULL;
int c, i, j, action = 0;
char *path, *dev_list;
bool all = false, actionset = false;
bool all = false;
size_t len;
int c, i, j;
for (i=0; i < argc; i++)
for (j=2; j < (int) strlen(argv[i]); j++)
@@ -428,12 +634,12 @@ int main(int argc, char *argv[])
break;
switch (c) {
case 'e':
actionset = true;
action = c;
online = "1";
online_text = "online";
break;
case 'd':
actionset = true;
action = c;
online = "0";
online_text = "offline";
break;
@@ -441,23 +647,23 @@ int main(int argc, char *argv[])
all = true;
break;
case 'p':
actionset = true;
action = c;
poll_thread = "1";
break;
case 'n':
actionset = true;
action = c;
poll_thread = "0";
break;
case 'c':
actionset = true;
action = c;
config_time = optarg;
break;
case 't':
actionset = true;
action = c;
poll_timeout = optarg;
break;
case 'q':
actionset = true;
action = c;
default_domain = optarg;
break;
case 'V':
@@ -472,21 +678,31 @@ int main(int argc, char *argv[])
util_prg_print_version();
return EXIT_SUCCESS;
case OPT_CONFIG_ON:
actionset = true;
action = c;
config = "1";
config_text = "config on";
break;
case OPT_CONFIG_OFF:
actionset = true;
action = c;
config = "0";
config_text = "config off";
break;
case OPT_SE_ASSOC:
action = c;
assoc_idx = optarg;
break;
case OPT_SE_BIND:
action = c;
break;
case OPT_SE_UNBIND:
action = c;
break;
default:
util_opt_print_parse_error(c, argv);
return EXIT_FAILURE;
}
}
if (!actionset)
if (!action)
invalid_cmdline_exit("Error - missing argument.\n");
path = util_path_sysfs("bus/ap");
if (!util_path_is_dir(path))
@@ -508,6 +724,32 @@ int main(int argc, char *argv[])
default_domain_set(default_domain);
return EXIT_SUCCESS;
}
if (action == OPT_SE_ASSOC) {
if (optind >= argc)
errx(EXIT_FAILURE,
"Error - The --se-associate needs a queue device given.");
queue_device = argv[optind];
se_assoc(assoc_idx, queue_device);
return EXIT_SUCCESS;
}
if (action == OPT_SE_BIND) {
if (optind >= argc)
errx(EXIT_FAILURE,
"Error - The --se-bind needs a queue device given.");
queue_device = argv[optind];
se_bind(queue_device);
return EXIT_SUCCESS;
}
if (action == OPT_SE_UNBIND) {
if (optind >= argc)
errx(EXIT_FAILURE,
"Error - The --se-unbind needs a queue device given.");
queue_device = argv[optind];
se_unbind(queue_device);
return EXIT_SUCCESS;
}
if (all)
dev_list_all(&dev_list, &len);
else

View File

@@ -1,6 +1,6 @@
.\" lszcrypt.8
.\"
.\" Copyright IBM Corp. 2019, 2022
.\" Copyright IBM Corp. 2019, 2023
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
@@ -10,7 +10,7 @@
.\" nroff -man lszcrypt.8
.\" to process this source
.\"
.TH LSZCRYPT 8 "FEB 2022" "s390-tools"
.TH LSZCRYPT 8 "MAY 2023" "s390-tools"
.SH NAME
lszcrypt \- display zcrypt device and configuration information
.SH SYNOPSIS
@@ -24,7 +24,7 @@ lszcrypt \- display zcrypt device and configuration information
.TP
.B lszcrypt
.B -c
<card-id>
<device-id>
.TP
.B lszcrypt -b
.TP
@@ -41,43 +41,60 @@ lszcrypt \- display zcrypt device and configuration information
.SH DESCRIPTION
The
.B lszcrypt
command is used to display information about cryptographic devices managed by
zcrypt and the AP bus attributes of zcrypt. Displayed information depends on the
kernel version.
command is used to display information about cryptographic devices
managed by zcrypt and the AP bus attributes of zcrypt. Displayed
information depends on the kernel version.
.B lszcrypt
requires that sysfs is mounted.
.P
The following information can be displayed for each cryptographic
device: card ID, domain ID, card type (symbolic), mode, online status,
hardware card type (numeric), installed function facilities, card capability,
hardware queue depth, request count, number of requests in hardware queue, and
the number of outstanding requests.
The following AP bus attributes can be displayed: AP domain, Max AP domain,
configuration timer, poll thread status, poll timeout, and AP interrupt
status.
hardware card type (numeric), installed function facilities, card
capability, hardware queue depth, request count, number of requests in
hardware queue, and the number of outstanding requests. The following
AP bus attributes can be displayed: AP domain, Max AP domain,
configuration timer, poll thread status, poll timeout, and AP
interrupt status.
.SH OPTIONS
.TP 8
.B -V, --verbose
The verbose level for cryptographic device information.
With this verbose level additional information like hardware card type,
hardware queue depth, pending requests count, installed function
facilities and driver binding is displayed.
The verbose level for cryptographic device information. With this
verbose level additional information like hardware card type, hardware
queue depth, pending requests count, installed function facilities and
driver binding is displayed.
.TP 8
.B <device-id>
Specifies a cryptographic device to display. A cryptographic device can be
either a card device or a queue device. If no devices are specified information
about all available devices is displayed.
Specifies a cryptographic device to display. A cryptographic device
can be either a card device or a queue device. If no devices are
specified information about all available devices is displayed.
Please note that the card device representation and the queue device
are both in hexadecimal notation.
.TP 8
.B -b, --bus
Displays the AP bus attributes and exits.
There is also a list of AP bus features shown here:
.RS
.IP "o" 3
APSC - Extended TAPQ (Test AP Queue) support.
.IP "o"
APXA - Support for more than 16 domains per card.
.IP "o"
QACT - QACT support for toleration of new unknown crypto cards.
.IP "o"
RC8A - Firmware reports 0x8A instead of 0x42 on some error conditions.
.IP "o"
APSB - AP bus has Secure Execution AP pass-through support.
.RE
.TP 8
.B -c, --capability <card-id>
Shows the capabilities of a cryptographic card device of hardware type 6 or
higher. The card device id value may be given as decimal or hex value (with
a leading 0x). The capabilities of a cryptographic card device depend on
the card type and the installed function facilities. A cryptographic card
.B -c, --capability <device-id>
Shows the capabilities of a cryptographic card or queue device of
hardware type 6 or higher. A card device id value may be given as
decimal or hex value (with a leading 0x), a queue device needs to be
given as xy.abcd (as it is displayed by lszcrypt).
The capabilities of a cryptographic card device depend on the card
type and the installed function facilities. A cryptographic card
device can provide one or more of the following capabilities:
.RS
.IP "o" 3
@@ -94,14 +111,25 @@ Long RNG
.RS 8
The CCA Secure Key capability may be limited by a hypervisor
layer. The remarks 'full function set' or 'restricted function set' may
reflect this. For details about these limitations please check the
layer. The remarks 'full function set' or 'restricted function set'
may reflect this. For details about these limitations please check the
hypervisor documentation.
.RE
.RS 8
The capabilities of a cryptographic queue device may vary depending
on some state or environment. However if a queue device is given here,
and the runtime environment is a KVM guest in Secure Execution mode
with AP pass-through support, then the AP queue bind state and AP
queue association state is shown here. Furthermore the state(s) and
mkvp(s) (Master Key Verification Pattern) of the current master WK
(Wrapping Key - EP11 mode) or current master AES, APKA and ASYM (CCA
mode) are shown here.
.RE
.TP 8
.B -d, --domains
Shows the usage and control domains of the cryptographic devices.
The displayed domains of the cryptographic device depends on the initial
Shows the usage and control domains of the cryptographic devices. The
displayed domains of the cryptographic device depends on the initial
cryptographic configuration.
.RS
.IP "o" 3
@@ -140,18 +168,20 @@ Here is an explanation of the columns displayed. Please note that some
of the columns show up in verbose mode only.
.TP
.B CARD.DOM
The crypto card number in hexadecimal for a crypto card line or
the crypto card number and the domain id both in hex separated by a single
The crypto card number in hexadecimal for a crypto card line or the
crypto card number and the domain id both in hex separated by a single
dot for a queue line.
.TP
.B TYPE and HWTYPE
The HWTYPE is a numeric value showing which type of hardware the zcrypt
device driver presumes that this crypto card is. The currently known values
are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7 and 14=CEX8.
The HWTYPE is a numeric value showing which type of hardware the
zcrypt device driver presumes that this crypto card is. The currently
known values are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7
and 14=CEX8.
.br
The TYPE is a human readable value showing the hardware type and the basic
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
The TYPE is a human readable value showing the hardware type and the
basic function type (A=Accelerator, C=CCA Coprocessor, P=EP11
Coprocessor). So for example CEX6P means a CEX6 card in EP11
Coprocessor mode.
.TP
.B MODE
A crypto card can be configured to run into one of 3 modes:
@@ -170,13 +200,13 @@ online/offline state is kept by the zcrypt device driver and can be
switched on or off with the help of the chzcrypt application.
.br
A crypto card can also be 'configured' or 'deconfigured'. This state
may be adjusted on the HMC or SE. The chzcrypt application can also
trigger this state with the --config-on and --config-off options.
may be adjusted on the HMC. The chzcrypt application can also trigger
this state with the --config-on and --config-off options.
.br
lszcrypt shows 'online' when a card or queue is available for
cryptographic operations. 'offline' is displayed when a card or queue
is switched to (software) offline. If a card is 'deconfigured' via
HMC, SE or chzcrypt the field shows 'deconfig'.
HMC or chzcrypt the field shows 'deconfig'.
.br
A crypto card may also reach a 'checkstopped' state. lszcrypt shows
this as 'chkstop'.
@@ -184,21 +214,22 @@ this as 'chkstop'.
If a queue is not bound to a device driver there is no detailed
information available and thus the status shows only '-'.
.br
If a queue is bound to the vfio-ap device driver it is up to this driver
to give some status information and what exactly this means. So lszcrypt
shows the text retrieved from the underlying sysfs attribute here.
If a queue is bound to the vfio-ap device driver it is up to this
driver to give some status information and what exactly this means. So
lszcrypt shows the text retrieved from the underlying sysfs attribute
here.
.TP
.B REQUESTS
This is the counter value of successful processed requests on card or queue
level. Successful here means the request was processed without any failure
in the whole processing chain.
This is the counter value of successful processed requests on card or
queue level. Successful here means the request was processed without
any failure in the whole processing chain.
.TP
.B PENDING
The underlying firmware and hardware layer usually provide some queuing
space for requests. When this queue is already filled up, the zcrypt device
driver maintains a software queue of pending requests. The sum of these
both values is displayed here and shows the amount of requests waiting for
processing on card or queue level.
The underlying firmware and hardware layer usually provide some
queuing space for requests. When this queue is already filled up, the
zcrypt device driver maintains a software queue of pending
requests. The sum of these both values is displayed here and shows the
amount of requests waiting for processing on card or queue level.
.TP
.B FUNCTIONS
This column shows firmware and hardware function details:
@@ -224,48 +255,64 @@ F - Full function support (opposed to restricted function support, see below).
.br
R - Restricted function support. The F and R flag both reflect if a
hypervisor is somehow restricting this crypto resource in a virtual
environment. Dependent on the hypervisor configuration the crypto requests
may be filtered by the hypervisor to allow only a subset of functions
within the virtual runtime environment. For example a shared CCA
Coprocessor may be restricted by the hypervisor to allow only clear key
operations within the guests.
environment. Dependent on the hypervisor configuration the crypto
requests may be filtered by the hypervisor to allow only a subset of
functions within the virtual runtime environment. For example a shared
CCA Coprocessor may be restricted by the hypervisor to allow only
clear key operations within the guests.
.TP
.B DRIVER
.br
Shows which card or queue device driver currently handles this crypto
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX8
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
for use by kvm hypervisor for kvm guests and not accessible to host
applications). It is also valid to have no driver handling a queue which is
shown as a -no-driver- entry.
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue
reserved for use by KVM hypervisor for KVM guests and not accessible
to host applications). It is also valid to have no driver handling a
queue which is shown as a -no-driver- entry.
.TP
.B SESTAT
.br
Shows the state of the BS bits associated with every AP queue within a
Secure Execution guest when AP Pass-through support is available:
.br
usable - AP queue is usable for crypto load.
.br
bound - AP queue is bound but not yet associated.
.br
unbound - AP queue is unbound and needs to get bound to this Secure
Execution guest.
.br
illicit - AP queue is not available for this Secure Execution guest.
.SH NOTES
Use only one of the mode filtering options --accelonly, --ccaonly, --ep11only.
Same with card/queue filtering: Use only one of --cardonly, --queueonly.
However, one of the mode filtering options and one of the card/queue filtering
can be combined.
Use only one of the mode filtering options --accelonly, --ccaonly,
--ep11only. Same with card/queue filtering: Use only one of
--cardonly, --queueonly. However, one of the mode filtering options
and one of the card/queue filtering can be combined.
.SH EXAMPLES
.TP
.B lszcrypt
Displays the card/domain ID, card type (short name), mode (long name), online
status and request count of all available cryptographic devices.
Displays the card/domain ID, card type (short name), mode (long name),
online status and request count of all available cryptographic
devices.
.TP
.B lszcrypt 1 3 5
Displays the card/domain ID, card type, mode, online status and request count
for cryptographic devices 1, 3, and 5.
Displays the card/domain ID, card type, mode, online status and
request count for cryptographic devices 1, 3, and 5.
.TP
.B lszcrypt -V 3 7 11
Displays the card/domain ID, card type, mode, online status, request count,
number of requests in the hardware queue, number of outstanding requests and
installed function facilities for cryptographic devices 3, 7 and 17 (0x11).
Displays the card/domain ID, card type, mode, online status, request
count, number of requests in the hardware queue, number of outstanding
requests and installed function facilities for cryptographic devices
3, 7 and 17 (0x11).
.TP
.B lszcrypt 10.0038
Displays information of the cryptographic device '10.0038' respectively card
id 16 (0x10) with domain 56 (0x38).
Displays information of the cryptographic device '10.0038'
respectively card id 16 (0x10) with domain 56 (0x38).
.TP
.B lszcrypt .0038
Displays information of all available queue devices (potentially multiple
adapters) with domain 56 (0x38).
Displays information of all available queue devices (potentially
multiple adapters) with domain 56 (0x38).
.TP
.B lszcrypt -b
Displays AP bus information.

View File

@@ -1,7 +1,7 @@
/**
* lszcrypt - Display zcrypt devices and configuration settings
*
* Copyright IBM Corp. 2008, 2022
* Copyright IBM Corp. 2008, 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -55,7 +55,7 @@ static struct lszcrypt_l {
#define MASK_COPRO 0x10000000
#define MASK_ACCEL 0x08000000
#define MASK_EP11 0x04000000
#define MASK_HSL 0x01000000
#define MASK_HSL 0x01000000
/*
* Classification
@@ -85,6 +85,8 @@ static struct fac_bits_s {
{ 0x00400000, 'R' }, /* bit 9, restricted function set */
};
#define EXTRACT_BS_BITS(f) (((f) & 0x0000c000UL) >> 14)
/*
* Program configuration
*/
@@ -95,7 +97,7 @@ static const struct util_prg prg = {
{
.owner = "IBM Corp.",
.pub_first = 2008,
.pub_last = 2020,
.pub_last = 2023,
},
UTIL_PRG_COPYRIGHT_END
}
@@ -169,8 +171,9 @@ static struct util_opt opt_vec[] = {
static void show_bus(void)
{
long domain, max_domain, config_time, value;
unsigned long long poll_timeout;
const char *poll_thread, *ap_interrupts;
unsigned long long poll_timeout;
char features[256];
char *ap;
/* check if ap driver is available */
@@ -178,6 +181,10 @@ static void show_bus(void)
if (!util_path_is_dir(ap))
errx(EXIT_FAILURE, "Crypto device driver not available.");
if (util_path_is_readable("%s/features", ap))
util_file_read_line(features, sizeof(features), "%s/features", ap);
else
features[0] = '\0';
util_file_read_l(&domain, 10, "%s/ap_domain", ap);
util_file_read_l(&max_domain, 10, "%s/ap_max_domain_id", ap);
util_file_read_l(&config_time, 10, "%s/config_time", ap);
@@ -192,6 +199,8 @@ static void show_bus(void)
ap_interrupts = "enabled";
else
ap_interrupts = "disabled";
if (features[0])
printf("features: %s\n", features);
printf("ap_domain=0x%lx\n", domain);
printf("ap_max_domain_id=0x%lx\n", max_domain);
if (util_path_is_reg_file("%s/ap_interrupts", ap))
@@ -374,23 +383,15 @@ next:
}
/*
* Show capability
* Show card capability
*/
static void show_capability(const char *id_str)
static void show_card_capability(int id)
{
unsigned long func_val;
long hwtype, id, max_msg_size;
char *p, *ap, *dev, card[16], cbuf[256];
long hwtype, max_msg_size;
char *dev, card[16], cbuf[256];
/* check if ap driver is available */
ap = util_path_sysfs("bus/ap");
if (!util_path_is_dir(ap))
errx(EXIT_FAILURE, "Crypto device driver not available.");
id = strtol(id_str, &p, 0);
if (id < 0 || id > 255 || p == id_str || *p != '\0')
errx(EXIT_FAILURE, "Error - '%s' is an invalid cryptographic device id.", id_str);
snprintf(card, sizeof(card), "card%02lx", id);
snprintf(card, sizeof(card), "card%02x", id);
dev = util_path_sysfs("devices/ap/%s", card);
if (!util_path_is_dir(dev))
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", card);
@@ -464,6 +465,78 @@ static void show_capability(const char *id_str)
card, hwtype);
break;
}
free(dev);
}
/*
* Show queue capability
*/
static void show_queue_capability(int id, int dom)
{
char *dev, card[16], queue[16], buf[256];
snprintf(card, sizeof(card), "card%02x", id);
snprintf(queue, sizeof(queue), "%02x.%04x", id, dom);
dev = util_path_sysfs("devices/ap/%s/%s", card, queue);
if (!util_path_is_dir(dev))
errx(EXIT_FAILURE, "Error - cryptographic queue device %02x.%04x does not exist.",
id, dom);
printf("queue %02x.%04x capabilities:\n", id, dom);
if (util_path_is_reg_file("%s/se_bind", dev)) {
util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev);
printf("SE bind state: %s\n", buf);
}
if (util_path_is_reg_file("%s/se_associate", dev)) {
util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev);
printf("SE association state: %s\n", buf);
}
if (util_path_is_reg_file("%s/mkvps", dev)) {
char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue);
FILE *f = fopen(mkvps, "r");
if (!f)
errx(EXIT_FAILURE, "Error - failed to open sysfs file %s.",
mkvps);
while (fgets(buf, sizeof(buf), f)) {
if (strstr(buf, "WK CUR") ||
strstr(buf, "AES CUR") ||
strstr(buf, "APKA CUR") ||
strstr(buf, "ASYM CUR"))
printf("MK %s", buf); /* no newline here */
}
fclose(f);
free(mkvps);
}
free(dev);
}
/*
* Show capability
*/
static void show_capability(const char *id_str)
{
char *p, *ap;
int id, dom;
/* check if ap driver is available */
ap = util_path_sysfs("bus/ap");
if (!util_path_is_dir(ap))
errx(EXIT_FAILURE, "Crypto device driver not available.");
if (sscanf(id_str, "%x.%x", &id, &dom) == 2) {
show_queue_capability(id, dom);
} else {
id = strtol(id_str, &p, 0);
if (id < 0 || id > 255 || p == id_str || *p != '\0')
errx(EXIT_FAILURE,
"Error - '%s' is an invalid cryptographic device id.",
id_str);
show_card_capability(id);
}
}
/*
@@ -601,11 +674,33 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
util_file_read_l(&depth, 10, "%s/depth", grp_dev);
util_rec_set(rec, "depth", "%02d", depth + 1);
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev))
util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev);
else
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
for (i = 0; i < MAX_FAC_BITS; i++)
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
buf[i] = '\0';
util_rec_set(rec, "facility", buf);
if (ap_bus_has_SB_support()) {
switch (EXTRACT_BS_BITS(facility)) {
case 0:
util_rec_set(rec, "sestat", "usable");
break;
case 1:
util_rec_set(rec, "sestat", "bound");
break;
case 2:
util_rec_set(rec, "sestat", "unbound");
break;
case 3:
util_rec_set(rec, "sestat", "illicit");
break;
default:
util_rec_set(rec, "sestat", "-");
}
}
}
/*
@@ -614,6 +709,8 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
static void show_subdevice(struct util_rec *rec, const char *grp_dev,
const char *sub_dev)
{
char type[16], t = '\0';
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
@@ -630,6 +727,14 @@ static void show_subdevice(struct util_rec *rec, const char *grp_dev,
return;
util_rec_set(rec, "card", sub_dev);
if (util_file_read_line(type, sizeof(type), "%s/type", grp_dev) == 0)
t = type[strlen(type) - 1];
if ((t == 'A' && !l.showaccel) ||
(t == 'C' && !l.showcca) ||
(t == 'P' && !l.showep11))
return;
read_subdev_rec_default(rec, grp_dev, sub_dev);
read_subdev_rec_verbose(rec, grp_dev, sub_dev);
@@ -740,6 +845,9 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
i = read_driver(grp_dev, NULL, buf, sizeof(buf));
util_rec_set(rec, "driver", i > 0 ? buf : "-no-driver-");
if (ap_bus_has_SB_support())
util_rec_set(rec, "sestat", "-");
}
/*
@@ -808,6 +916,8 @@ static void define_rec_verbose(struct util_rec *rec)
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
if (ap_bus_has_SB_support())
util_rec_def(rec, "sestat", UTIL_REC_ALIGN_LEFT, 11, "SESTAT");
}
/*
@@ -843,12 +953,12 @@ static void show_devices_all(void)
/*
* Show devices specified on commandline
*/
static void show_devices_argv(char *argv[])
static void show_devices_argv(int argc, char **argv)
{
int id, dom, argidx, devidx, n, dev_cnt, sub_cnt;
struct util_rec *rec = util_rec_new_wide("-");
struct dirent **dev_vec, **subdev_vec;
char *ap, *grp_dev, *path, *card, *sub_dev;
int id, dom, i, n, dev_cnt, sub_cnt;
struct dirent **dev_vec, **subdev_vec;
/* check if ap driver is available */
ap = util_path_sysfs("bus/ap");
@@ -860,10 +970,10 @@ static void show_devices_argv(char *argv[])
define_rec_verbose(rec);
util_rec_print_hdr(rec);
for (i = 0; argv[i] != NULL; i++) {
for (argidx = 0; argidx < argc; argidx++) {
id = -1;
dom = -1;
if (sscanf(argv[i], "%x.%x", &id, &dom) >= 1) {
if (sscanf(argv[argidx], "%x.%x", &id, &dom) >= 1) {
/* at least the id field was valid */
if (id >= 0 && dom >= 0) { /* single subdevice */
util_asprintf(&sub_dev, "%02x.%04x", id, dom);
@@ -879,7 +989,7 @@ static void show_devices_argv(char *argv[])
}
continue;
}
if (sscanf(argv[i]+1, "%x", &dom) == 1) {
if (sscanf(argv[argidx] + 1, "%x", &dom) == 1) {
/* list specific domains of all adapters */
path = util_path_sysfs("devices/ap/");
dev_cnt = util_scandir(&dev_vec, alphasort, path,
@@ -887,9 +997,9 @@ static void show_devices_argv(char *argv[])
if (dev_cnt < 1)
errx(EXIT_FAILURE, "No crypto card devices found.");
free(path);
for (i = 0; i < dev_cnt; i++) {
for (devidx = 0; devidx < dev_cnt; devidx++) {
path = util_path_sysfs("devices/ap/%s",
dev_vec[i]->d_name);
dev_vec[devidx]->d_name);
sub_cnt = util_scandir(&subdev_vec, alphasort,
path,
"[0-9a-fA-F]+.%04x",
@@ -1013,6 +1123,6 @@ int main(int argc, char **argv)
if (optind == argc)
show_devices_all();
else
show_devices_argv(&argv[optind]);
show_devices_argv((argc - optind), &argv[optind]);
return EXIT_SUCCESS;
}

View File

@@ -1,16 +1,20 @@
/*
* Misc - Local helper functions
*
* Copyright IBM Corp. 2016, 2017
* Copyright IBM Corp. 2016, 2023
*
* 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 <regex.h>
#include <string.h>
#include <sys/types.h>
#include "lib/util_base.h"
#include "lib/util_file.h"
#include "lib/util_panic.h"
#include "lib/util_path.h"
#include "misc.h"
/**
@@ -35,3 +39,35 @@ bool misc_regex_match(const char *str, const char *regex)
regfree(&preg);
return rc == 0 ? true : false;
}
/**
* Test if AP bus has SB support available.
*
* @returns true Yes, SB support is available
* false No
*/
bool ap_bus_has_SB_support(void)
{
static int sb_support = -1;
if (sb_support < 0) {
char *ap, buf[256];
ap = util_path_sysfs("bus/ap");
if (!util_path_is_dir(ap)) {
sb_support = 0;
} else {
if (!util_path_is_readable("%s/features", ap)) {
sb_support = 0;
} else {
util_file_read_line(buf, sizeof(buf),
"%s/features", ap);
if (strstr(buf, "APSB"))
sb_support = 1;
}
}
free(ap);
}
return sb_support > 0 ? true : false;
}

View File

@@ -1,7 +1,7 @@
/*
* misc - Local helper functions
*
* Copyright IBM Corp. 2016, 2017
* Copyright IBM Corp. 2016, 2023
*
* 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,5 +13,6 @@
#include <stdbool.h>
bool misc_regex_match(const char *str, const char *regex);
bool ap_bus_has_SB_support(void);
#endif /* MISC_H */

View File

@@ -0,0 +1,99 @@
#!/bin/bash
#
# Copyright IBM Corp. 2023
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
#
# 95zdev-kdump/module_setup.sh
# This module installs configuration files (udev rules and modprobe.conf
# files) required to enable the kdump target on s390.
#
# called by dracut
check() {
local _arch=${DRACUT_ARCH:-$(uname -m)}
# Ensure that we're running on s390
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1
source "$moddir/../95zdev/zdev-lib.sh"
# Ensure this module is only included when building kdump initrd
is_kdump || return 1
# Ensure that required tools are available
require_binaries chzdev || return 1
return 0
}
# called by dracut
depends() {
return 0
}
# called by dracut
installkernel() {
# Add modules for all device types supported by chzdev (required for
# auto-configuration)
instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
dasd_diag_mod zfcp
}
# called by dracut
install() {
local _tempfile
# Obtain kdump target device configuration
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
# work with systems that are not based on chzdev persistent config
local _configuration="--active"
# disable zfcp auto LUN scan to prevent OOM situations on systems with
# many zFCP LUNs
inst_dir /etc/modprobe.d
chzdev zfcp --type "allow_lun_scan=0" --persistent \
--base "/etc=$initdir/etc" --yes --quiet --no-root-update \
--force >/dev/null
# drop /etc/zfcp.conf from dracut module 95zfcp
echo "rd.zfcp.conf=0" > "$initdir/etc/cmdline.d/00-no-zfcp-conf.conf"
# => only activate individual zfcp paths found as required below
function check_zdev() {
local _dev=$1
local _devsysfs _bdevpath
_devsysfs=$(
cd -P /sys/dev/block/"$_dev" && echo "$PWD"
)
_bdevpath=/dev/${_devsysfs##*/}
# do not export device type information potentially unknown on import
chzdev --export - "$_configuration" --by-node "$_bdevpath" --quiet \
2>/dev/null >> "$_tempfile"
}
for_each_host_dev_and_slaves_all check_zdev
sed -i -e 's/^\[active /\[persistent /' "$_tempfile"
# Apply via --import to prevent other devices from being configured
chzdev --import "$_tempfile" --persistent --base "/etc=$initdir/etc" \
--yes --quiet --no-root-update --force >/dev/null
rm -f "$_tempfile"
# these are purely generated udev rules so we have to glob expand
# within $initdir and strip the $initdir prefix for mark_hostonly
local -a _array
local _nullglob=$(shopt -p nullglob)
shopt -u nullglob
readarray -t _array < \
<(ls -1 $initdir/etc/udev/rules.d/41-*.rules 2> /dev/null)
[[ ${#_array[@]} -gt 0 ]] && mark_hostonly "${_array[@]#$initdir}"
readarray -t _array < \
<(ls -1 $initdir/etc/modprobe.d/s390x-*.conf 2> /dev/null)
[[ ${#_array[@]} -gt 0 ]] && mark_hostonly "${_array[@]#$initdir}"
$_nullglob
return 0
}

View File

@@ -19,6 +19,12 @@ check() {
# Ensure that we're running on s390
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1
source "$moddir/zdev-lib.sh"
# Leave kdump device configuration to module zdev-kdump to
# ensure a minimal device footprint
is_kdump && return 1
# Ensure that required tools are available
require_binaries chzdev lszdev /lib/s390-tools/zdev_id || return 1
@@ -50,8 +56,18 @@ install() {
# Obtain early + root device configuration
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
chzdev --export "$_tempfile" --persistent --by-path / --quiet \
--type 2>/dev/null
function check_zdev() {
local _dev=$1
local _devsysfs _bdevpath
_devsysfs=$(
cd -P /sys/dev/block/"$_dev" && echo "$PWD"
)
_bdevpath=/dev/${_devsysfs##*/}
chzdev --export - --persistent --by-node "$_bdevpath" --quiet \
--type 2>/dev/null >> "$_tempfile"
}
for_each_host_dev_and_slaves_all check_zdev
chzdev --export - --persistent --by-attrib "zdev:early=1" --quiet \
--type 2>/dev/null >> "$_tempfile"

View File

@@ -0,0 +1,24 @@
#
# Copyright IBM Corp. 2023
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
#
# 95zdev/zdev-lib.sh
# Common shell library functionality for 95zdev and 95zdev-kdump.
#
is_kdump() {
# https://src.fedoraproject.org/rpms/kexec-tools/c/4eedcae5e1540690a3761857fe2e692774c44960
# https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/mkdumprd
# https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/dracut-module-setup.sh
if [[ $hostonly && "$hostonly_mode" == "strict" && -n "$IN_KDUMP" ]]; then
return 0
fi
# https://github.com/openSUSE/kdump/blob/master/dracut/module-setup.sh
if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules " == *\ kdump\ * ]]; then
return 0
fi
return 1
}

View File

@@ -2,6 +2,7 @@
include ../../common.mak
ZDEVDIR := 95zdev
ZDEVKDUMPDIR := 95zdev-kdump
# HAVE_DRACUT
#
@@ -19,5 +20,9 @@ install:
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(ZDEVDIR)
$(INSTALL) -m 755 $(ZDEVDIR)/module-setup.sh \
$(ZDEVDIR)/parse-zdev.sh \
$(ZDEVDIR)/zdev-lib.sh \
$(DESTDIR)$(DRACUTMODDIR)/$(ZDEVDIR)/
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(ZDEVKDUMPDIR)
$(INSTALL) -m 755 $(ZDEVKDUMPDIR)/module-setup.sh \
$(DESTDIR)$(DRACUTMODDIR)/$(ZDEVKDUMPDIR)/
endif

View File

@@ -344,6 +344,68 @@ static struct attrib dasd_attr_fc_security = {
.readonly = 1,
};
static struct attrib dasd_attr_aq_mask = {
.name = "aq_mask",
.title = "Specify autoquiesce triggers",
.desc =
"Use the aq_mask attribute to automatically quiesce a device and block\n"
"new I/O after certain events.\n"
"\n"
"The value is a bitmask in decimal or hexadecimal format where each set bit\n"
"indicates that the associated event shown in the table below triggers an\n"
"autoquiesce.\n"
" Bit 0 is not used.\n"
" 1 - 0x02 - A terminal I/O error occurred\n"
" 2 - 0x04 - No active channel paths remain for the device\n"
" 3 - 0x08 - A state change interrupt occurred\n"
" 4 - 0x10 - The device is PPRC suspended\n"
" 5 - 0x20 - No space is left on an ESE device\n"
" 6 - 0x40 The number of timeouts specified in aq_timeouts is reached\n"
" 7 - 0x80 - I/O was not started because of an error in the start function\n"
"\n"
"For example bits 1,3 and 5 set (0010 1010) lead to an integer value of 42\n"
"or 0x2A.\n"
"An integer value of 0 turns off the autoquiesce function.\n",
.order_cmp = ccw_online_only_order_cmp,
.check = ccw_online_only_check,
.defval = "0",
/*
* Currently only 8 bits are defined and the max value is 255.
* This needs to be adjusted if more bits are defined.
*/
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 255)),
};
static struct attrib dasd_attr_aq_requeue = {
.name = "aq_requeue",
.title = "Control I/O requeing during autoquiesce",
.desc =
"Use the aq_requeue attribute to control whether outstanding I/O\n"
"operations to the blocklayer should be automatically requeued after\n"
"an autoquiesce event.\n"
"Valid values are 1 for requeuing, or 0 for no requeueing.\n"
"Requeing the I/O requests to the blocklayer might benefit I/O\n"
"in case of a copy_pair swap operation.\n",
.order_cmp = ccw_online_only_order_cmp,
.check = ccw_online_only_check,
.defval = "0",
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
};
static struct attrib dasd_attr_aq_timeouts = {
.name = "aq_timeouts",
.title = "Specify timeout retry threshold",
.desc =
"Specify the number of sequential timeout events for an I/O operation\n"
"before an autoquiesce is triggered on a device.\n"
"This requires that the corresponding trigger bit 6 is set\n"
"in the aq_mask attribute.\n",
.order_cmp = ccw_online_only_order_cmp,
.check = ccw_online_only_check,
.defval = "32768",
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 32768)),
};
/*
* DASD subtype methods.
*/
@@ -725,6 +787,9 @@ struct subtype dasd_subtype_eckd = {
&dasd_attr_safe_offline,
&dasd_attr_fc_security,
&dasd_attr_copy_pair,
&dasd_attr_aq_mask,
&dasd_attr_aq_requeue,
&dasd_attr_aq_timeouts,
&internal_attr_early,
),
.unknown_dev_attribs = 1,

View File

@@ -11,6 +11,8 @@
#include <stdbool.h>
#include <string.h>
#include "lib/util_path.h"
#include "devnode.h"
#include "misc.h"
#include "net.h"
@@ -55,7 +57,8 @@ static bool add_devnodes_from_link(struct util_list *list,
cb_data.prefix_len = strlen(prefix);
cb_data.result = false;
path = path_get_sys_class("net", devnode->name);
path_for_each(path, add_linked_cb, &cb_data);
if (util_path_exists(path))
path_for_each(path, add_linked_cb, &cb_data);
free(path);
return cb_data.result;

View File

@@ -603,7 +603,7 @@ exit_code_t select_by_node(struct select_opts *select,
devnode = devnode_from_node(path, err);
if (!devnode)
return EXIT_RUNTIME_ERROR;
return EXIT_DEVICE_NOT_FOUND;
rc = select_by_devnode(select, selected, config, scope, only_dt,
only_st, devnode, path, err);

View File

@@ -295,6 +295,7 @@ static exit_code_t udev_ccw_write_device_legacy(struct device *dev, bool autocon
}
fprintf(fd, "GOTO=\"%s\"\n", end_label);
fprintf(fd, "\n");
fprintf(fd, "LABEL=\"%s\"\n", cfg_label);
write_attr_to_file(fd, state, id);

View File

@@ -213,16 +213,41 @@ out:
static void write_zdev_site_id(int site_id)
{
FILE *fd;
int tmpfd, rc;
const char zdev_id_file[] = ZDEV_SITE_ID_FILE;
char zdev_id_tmpfile[] = ZDEV_SITE_ID_FILE "-XXXXXX";
fd = fopen(ZDEV_SITE_ID_FILE, "w");
tmpfd = mkstemp(zdev_id_tmpfile);
if (tmpfd == -1)
goto err;
/* Open the temp file to use with fprintf */
fd = fdopen(tmpfd, "w");
if (!fd)
err(1, "Could not write to zdev_site_id file");
if (site_id == SITE_FALLBACK)
fprintf(fd, "ZDEV_SITE_ID=\n");
else
fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
goto err;
fclose(fd);
if (site_id == SITE_FALLBACK)
rc = fprintf(fd, "ZDEV_SITE_ID=\"\"\n");
else
rc = fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
if (rc < 0) {
fclose(fd);
goto err;
}
if (fclose(fd))
goto err;
/* Rename the temporary file to ZDEV_SITE_ID_FILE*/
if (rename(zdev_id_tmpfile, zdev_id_file) == -1) {
remove(zdev_id_tmpfile);
goto err;
}
return;
err:
err(1, "Could not write to zdev_site_id file");
}
/* Read the loadparm and extract the current site_id.
@@ -265,7 +290,7 @@ static void process_loadparm(const char *filename)
out:
write_zdev_site_id(site_id);
if (site_id == SITE_FALLBACK)
printf("ZDEV_SITE_ID=\n");
printf("ZDEV_SITE_ID=\"\"\n");
else
printf("ZDEV_SITE_ID=%d\n", site_id);
}

View File

@@ -39,17 +39,10 @@ check_dep:
"curl-devel or libcurl-dev", \
"HAVE_CURL=0")
ifneq ($(shell sh -c 'command -v pkg-config'),)
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
else
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
FUSE_LDLIBS = -lfuse3
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
CURL_LDLIBS = -lcurl
endif
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
CURL_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
CURL_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
ALL_CPPFLAGS += -DSYSFS
ALL_CFLAGS += -DHAVE_SETXATTR -pthread $(FUSE_CFLAGS) $(CURL_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) $(CURL_LDLIBS) -lpthread -lrt -lm

View File

@@ -79,17 +79,10 @@ OBJECTS = zgetdump.o opts.o zg.o zg_error.o zg_print.o \
ngdump.o dt_ngdump.o dfi_ngdump.o dfi_vmdump.o \
pv_utils.o
ifneq ($(shell sh -c 'command -v pkg-config'),)
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)
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
endif
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)
LIBPV = $(rootdir)/libpv/libpv.a
LIBPV_CFLAGS := -DOPENSSL_API_COMPAT=0x10100000L \
@@ -101,12 +94,9 @@ LIBPV_LIBS := $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
ifeq ("$(HAVE_FUSE)","0")
FUSE_CFLAGS = -DHAVE_FUSE=0 -D_FILE_OFFSET_BITS=64
FUSE_LDLIBS =
else ifneq ($(shell sh -c 'command -v pkg-config'),)
FUSE_CFLAGS = -DHAVE_FUSE=1 $(shell pkg-config --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
else
FUSE_CFLAGS = -DHAVE_FUSE=1 -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
FUSE_LDLIBS = -lfuse3
FUSE_CFLAGS = -DHAVE_FUSE=1 $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
endif
LDLIBS += -lz $(FUSE_LDLIBS) $(LIBPV_LIBS)
ALL_CFLAGS += $(FUSE_CFLAGS) $(LIBPV_CFLAGS)

View File

@@ -27,7 +27,7 @@ check_dep:
all: check_dep $(ZFCPDUMP_INITRD) scripts
cpioinit: cpioinit.c
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -o $@ $^
zfcpdump_part: zfcpdump.o zfcpdump_part.o
$(LINK) $(ALL_LDFLAGS) $^ -static -o $@

View File

@@ -123,11 +123,12 @@ sub get_device_data
} else {
$devices{$hctl}{dev} = glob_last("block\:sd*");
}
$devices{$hctl}{sg_mm} = get_line("generic", "dev");
next if !defined $devices{$hctl}{dev};
$c_src = $devices{$hctl}{dev};
$devices{$hctl}{dev} =~ s/.*(sd[a-z0-9]+)\Z/$1/
unless(!$devices{$hctl}{dev});
$devices{$hctl}{mm} = get_line("dev");
$devices{$hctl}{sg_mm} = get_line("generic", "dev");
$devices{$hctl}{mp_dev} = glob_last("holders", "dm*");
$devices{$hctl}{mp_dev} =~ s/.*\/(.+)\Z/$1/
unless (!$devices{$hctl}{mp_dev});

View File

@@ -10,7 +10,7 @@ ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g $(INCLUDE_PARMS) \
-fno-delete-null-pointer-checks -fno-stack-protector \
-fexec-charset=IBM1047 -m64 -mpacked-stack \
-mstack-size=4096 -mstack-guard=128 -msoft-float \
-W -Wall -Wformat-security -fno-sanitize=all
-W -Wall -Wformat-security -fno-sanitize=all -Wno-array-bounds
ALL_LDFLAGS += -fno-sanitize=all
FILES = fba0.bin fba1b.bin fba2.bin \

View File

@@ -29,10 +29,10 @@ int is_zero_block(void *data)
return blockptr->cyl || blockptr->head || blockptr->sec;
}
void * load_direct(disk_blockptr_t *data, struct subchannel_id subchannel_id,
void *load_addr)
void *load_direct(union disk_blockptr *data, struct subchannel_id subchannel_id,
void *load_addr)
{
struct eckd_blockptr_legacy *blockptr = &data->eckd;
struct eckd_blockptr_legacy *blockptr = &data->eckd_legacy;
struct ccw1 *ccws;
unsigned long record_size;
struct seek_arg seek_addr;

View File

@@ -21,7 +21,7 @@
/*
* Magic number at start of dump record
*/
uint64_t __section(.stage2.head) magic = 0x584d554c54363401ULL; /* XMULT64, version 1 */
const uint64_t __section(.stage2.head) magic = 0x584d554c54363401ULL; /* XMULT64, version 1 */
/*
* Parameter format for ECKD MV dumper (13 bytes):

View File

@@ -19,7 +19,7 @@
/*
* Magic number at start of dump record
*/
uint64_t __section(.stage2.head) magic = 0x5845434b44363401ULL; /* "XECKD64", version 1 */
const uint64_t __section(.stage2.head) magic = 0x5845434b44363401ULL; /* "XECKD64", version 1 */
/*
* Get device characteristics from zipl parameter block

View File

@@ -25,7 +25,7 @@ int is_zero_block(void *data) {
return blockptr->blockno;
}
void *load_direct(disk_blockptr_t *data, struct subchannel_id subchannel_id,
void *load_direct(union disk_blockptr *data, struct subchannel_id subchannel_id,
void *load_addr)
{
struct linear_blockptr *blockptr = &data->linear;

View File

@@ -23,7 +23,7 @@
/*
* Magic number at start of dump record
*/
uint64_t __section(.stage2.head) magic = 0x5844464241363401ULL; /* XDFBA64, version 1 */
const uint64_t __section(.stage2.head) magic = 0x5844464241363401ULL; /* XDFBA64, version 1 */
/*
* FBA dump device partition specification

View File

@@ -15,6 +15,7 @@
#include <stddef.h>
#include "lib/zt_common.h"
#include "boot/psw.h"
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
@@ -65,6 +66,7 @@ void __noreturn start(void);
void pgm_check_handler(void);
void pgm_check_handler_fn(void);
void panic_notify(unsigned long reason);
void load_wait_psw(uint64_t, struct psw_t *);
#define panic(reason, ...) \
do { \

View File

@@ -18,7 +18,7 @@
#include "boot/loaders_layout.h"
#include "stage2.h"
static int is_null_descriptor(disk_blockptr_t *address)
static int is_null_descriptor(union disk_blockptr *address)
{
unsigned long long *value = (unsigned long long *)address;
@@ -28,13 +28,12 @@ static int is_null_descriptor(disk_blockptr_t *address)
static void *load_blocklist(struct component_entry *descriptor_address,
struct subchannel_id subchannel_id, void *load_address)
{
disk_blockptr_t *indirect_blocks, *indirect_blockspace,
*start_addr;
union disk_blockptr *indirect_blocks, *indirect_blockspace, *start_addr;
unsigned long length;
long long nr_descr;
/* start address to load first indirect blocks */
start_addr = (disk_blockptr_t *)&descriptor_address->data;
start_addr = (union disk_blockptr *)&descriptor_address->data;
/* get a free page to store indirect blocks in */
indirect_blockspace = (void *)get_zeroed_page();
@@ -90,7 +89,7 @@ void __noreturn start(void)
struct subchannel_id subchannel_id;
void *load_address;
struct component_entry *entry;
disk_blockptr_t *blockptr;
union disk_blockptr *blockptr;
uint64_t load_psw;
void *load_page;
int config_nr;
@@ -106,14 +105,14 @@ void __noreturn start(void)
set_device(subchannel_id, ENABLED);
load_page = (void *)get_zeroed_page();
load_address = (disk_blockptr_t *) load_page;
load_address = (union disk_blockptr *) load_page;
/* load blockpointer list to load address */
load_direct((disk_blockptr_t *)&stage2_descr, subchannel_id,
load_direct((union disk_blockptr *)&stage2_descr, subchannel_id,
load_address);
blockptr = (disk_blockptr_t *)(load_address +
sizeof(disk_blockptr_t));
blockptr = (union disk_blockptr *)(load_address +
sizeof(union disk_blockptr));
load_direct(&blockptr[config_nr], subchannel_id, load_address);
@@ -148,4 +147,4 @@ void panic_notify(unsigned long UNUSED(reason))
{
}
uint64_t __section(.stage2.head) stage2_head;
const uint64_t __section(.stage2.head) stage2_head;

View File

@@ -26,16 +26,12 @@
#include "cio.h"
#include "error.h"
typedef union {
struct eckd_blockptr_legacy eckd;
struct linear_blockptr linear;
} disk_blockptr_t;
struct stage2_descr {
uint8_t reserved[16];
} __packed __aligned(8);
void *load_direct(disk_blockptr_t *, struct subchannel_id , void *);
void *load_direct(union disk_blockptr *data, struct subchannel_id sid,
void *load_addr);
int extract_length(void *);
int is_zero_block(void *);
void kdump_stage2(unsigned long);

View File

@@ -37,7 +37,7 @@ struct tape_head {
uint64_t ccw2;
} __packed;
struct tape_head __section(.stage2.head) tape_head = {
const struct tape_head __section(.stage2.head) tape_head = {
.psw = PSW_LOAD | STAGE2_ENTRY, /* Start code at 0x2018 */
.ccw1 = 0x0700000060000001ULL, /* Rewind ccw */
.ccw2 = 0x0200200020003000ULL, /* CCW to load dump tool to 0x2000 */

View File

@@ -16,18 +16,20 @@ DRACUT_OMIT_MODULES=(
systemd-timedated systemd-timesyncd
systemd-networkd systemd-network-manager systemd-coredump)
[ $# -gt 0 ] || { echo "Usage: $0 <dump partition device>" >&2; exit 1; }
function create_dumpfs()
{
[ "$dryrun" -eq 1 ] && { echo "/dev/null"; return 0; }
mkfs -F "$device" >/dev/null || { echo "Couldn't create filesystem on $1." >&2; return 1; }
local disk_path=/dev/disk/by-uuid/$(blkid -o value -s UUID "$device")
for i in $(seq 0 30)
do
[ -e "$disk_path" ] && break;
sleep 1
done
#
# Retrieve partition UUID
#
# We use PARTUUID because zipl re-formats the given partition after
# calling us, therefore, a UUID will change.
#
device=$(readlink -f $1)
disk_path=/dev/disk/by-partuuid/$(blkid -o value -s PARTUUID "$device")
[ -e "$disk_path" ] || { echo "Couldn't find disk by PARTUUID." >&2; exit 1; }
[ -e "$disk_path" ] || { echo "Filesystem device link missing." >&2; return 1; }
echo "$disk_path"
}
function get_kernel_version()
{
@@ -69,6 +71,27 @@ function create_initrd()
--kver "$kver" -f "$initrd" 2>&1
}
[ $# -gt 1 ] || { echo "Usage: $0 <dump partition device> <dryrun>" >&2; exit 1; }
dasd=
device=$(readlink -f $1)
dryrun=$2
type=$(lsblk -dno type "$device")
[ "$type" != "part" ] && { echo "$device with type $type is not a partition." >&2; exit 1; }
case "${device##*/}" in
dasd*)
dasd=$(dasdview -i "$1"|sed -n 's/busid\s*:\s*\([0-9a-fA-F.]\)/dasd=\1/p')
;;
nvme*)
;;
*)
echo "Unsupported device $device." >&2
exit 1
;;
esac
disk_path=$(create_dumpfs $device)
kernel_version=$(get_kernel_version)
kernel=$(get_kernel_image "$kernel_version")
[ -e "$kernel" ] || { echo "Couldn't find kernel image." >&2; exit 1; }
@@ -88,6 +111,6 @@ create_initrd "$disk_path" "$kernel_version" "$initrd"
echo "kernel=$kernel"
echo "initrd=$initrd"
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1"
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1 $dasd"
exit 0

View File

@@ -21,6 +21,7 @@
#define BOOTMAP_HEADER_VERSION 1
#define PROGRAM_TABLE_BLOCK_SIZE 512
#define SIGNATURE_MAGIC "~Module signature appended~\n"
#define PKCS7_FORMAT 0x01

View File

@@ -38,7 +38,7 @@ struct disk_blockptr_linear {
int blockct;
};
/* Pointer to a block on disk */
/* This represents in-memory pointer to a block on disk */
typedef union {
struct disk_blockptr_chs chs;
struct disk_blockptr_linear linear;
@@ -95,13 +95,14 @@ int disk_get_info(const char* device, struct job_target_data* target,
struct disk_info** info);
int disk_is_tape(const char* device);
int disk_is_scsi(const char* device, struct job_target_data* target);
int disk_is_eckd_ldl(const char* device, struct job_target_data* target);
int disk_is_nvme(const char* device, struct job_target_data* target);
int disk_get_info_from_file(const char* filename,
struct job_target_data* target,
struct disk_info** info);
void disk_free_info(struct disk_info* info);
char* disk_get_type_name(disk_type_t type);
char *disk_get_ipl_type(disk_type_t type);
char *disk_get_ipl_type(disk_type_t type, int is_dump);
int disk_is_large_volume(struct disk_info* info);
int disk_cyl_from_blocknum(blocknum_t blocknum, struct disk_info* info);
int disk_head_from_blocknum(blocknum_t blocknum, struct disk_info* info);

View File

@@ -8,7 +8,7 @@
* it under the terms of the MIT license. See LICENSE for details.
*
*/
#include "boot/s390.h" /* for PAGE_SIZE */
#include "boot/page.h"
#define ZIPL_ENVBLK_SIGNATURE "# zIPL Environment Block\n"
#define ENVBLK_DEFAULT_IMPORT_SOURCE "/etc/ziplenv"

View File

@@ -17,15 +17,7 @@
#include "zipl.h"
#include "boot/boot_defs.h"
/*
* For compatibility reasons zIPL can build multiple "similar"
* program tables, which differ only in block pointers format
*/
enum program_table_id {
PROGRAM_TABLE_0,
PROGRAM_TABLE_1,
NR_PROGRAM_TABLES
};
#define NR_PROGRAM_TABLES NR_BLKPTR_FORMATS
enum program_component_id {
COMPONENT_ID_HEAP_AREA,
@@ -43,6 +35,14 @@ enum program_component_id {
NR_PROGRAM_COMPONENTS
};
/* Types of SCSI disk layouts */
enum scsi_layout {
scsi_layout_pcbios,
scsi_layout_sun,
scsi_layout_sgi,
scsi_layout_unknown
};
struct component_loc {
address_t addr;
size_t size;
@@ -69,7 +69,6 @@ struct program_table {
struct install_set {
struct program_table tables[NR_PROGRAM_TABLES];
struct program_component *components[NR_PROGRAM_COMPONENTS];
int nr_tables; /* number of "similar" program tables to be installed */
int nr_menu_entries;
int fd;
char *device;
@@ -77,12 +76,27 @@ struct install_set {
char *dump_mount_point;
unsigned int dump_tmp_dir_created:1;
unsigned int dump_mounted:1;
unsigned int skip_prepare:1;
unsigned int print_details:1;
struct disk_info *info;
disk_blockptr_t scsi_dump_sb_blockptr;
};
extern struct component_footer component_footers[NR_PROGRAM_COMPONENTS];
/* Determine SCSI disk layout from the specified BOOTBLOCK. */
static inline enum scsi_layout get_scsi_layout(unsigned char *bootblock)
{
if ((bootblock[510] == 0x55) && (bootblock[511] == 0xaa))
return scsi_layout_pcbios;
else if ((bootblock[508] == 0xda) && (bootblock[509] == 0xbe))
return scsi_layout_sun;
else if ((bootblock[0] == 0x0b) && (bootblock[1] == 0xe5) &&
(bootblock[2] == 0xa9) && (bootblock[3] == 0x41))
return scsi_layout_sgi;
return scsi_layout_unknown;
}
static inline component_type component_type_by_id(enum program_component_id id)
{
return component_footers[id].type;

View File

@@ -128,6 +128,7 @@ struct job_data {
int dry_run;
int command_line;
int is_secure;
int is_ldipl_dump;
};
@@ -136,6 +137,6 @@ void job_free(struct job_data* job);
int type_from_target(char *target, disk_type_t *type);
int check_job_dump_images(struct job_dump_data* dump, char* name);
int check_job_images_ngdump(struct job_dump_data* dump, char* name);
bool is_ngdump_enabled(const char* device, struct job_target_data* target);
bool is_ngdump_enabled(struct job_data *job);
#endif /* not JOB_H */

View File

@@ -6,18 +6,20 @@
# it under the terms of the MIT license. See LICENSE for details.
#
[ $# -gt 0 ] || { echo "Usage: $0 <dump partition device>" >&2; exit 1; }
function create_dumpfs()
{
[ "$dryrun" -eq 1 ] && { echo "/dev/null"; return 0; }
mkfs -F "$device" >/dev/null || { echo "Couldn't create filesystem on $1." >&2; return 1; }
local disk_path=/dev/disk/by-uuid/$(blkid -o value -s UUID "$device")
for i in $(seq 0 30)
do
[ -e "$disk_path" ] && break;
sleep 1
done
#
# Retrieve partition UUID
#
# We use PARTUUID because zipl re-formats the given partition after
# calling us, therefore, a UUID will change.
#
device=$(readlink -f $1)
disk_path=/dev/disk/by-partuuid/$(blkid -o value -s PARTUUID "$device")
[ -e "$disk_path" ] || { echo "Couldn't find disk by PARTUUID." >&2; exit 1; }
[ -e "$disk_path" ] || { echo "Filesystem device link missing." >&2; return 1; }
echo "$disk_path"
}
function get_kernel_version()
{
@@ -49,6 +51,28 @@ function create_initrd()
NGDUMP=y NGDUMP_DEVICE="$disk" mkinitramfs -o "$initrd" "$kver" 2>&1
}
[ $# -gt 1 ] || { echo "Usage: $0 <dump partition device> <dryrun>" >&2; exit 1; }
device=$(readlink -f $1)
dryrun=$2
dasd=
type=$(lsblk -dno type "$device")
[ "$type" != "part" ] && { echo "$device with type $type is not a partition." >&2; exit 1; }
case "${device##*/}" in
dasd*)
dasd=$(dasdview -i "$1"|sed -n 's/busid\s*:\s*\([0-9a-fA-F.]\)/dasd=\1/p')
;;
nvme*)
;;
*)
echo "Unsupported device $device." >&2
exit 1
;;
esac
disk_path=$(create_dumpfs $device)
kernel_version=$(get_kernel_version)
kernel=$(get_kernel_image "$kernel_version")
[ -e "$kernel" ] || { echo "Couldn't find kernel image." >&2; exit 1; }
@@ -68,6 +92,6 @@ create_initrd "$disk_path" "$kernel_version" "$initrd"
echo "kernel=$kernel"
echo "initrd=$initrd"
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1"
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1 $dasd"
exit 0

View File

@@ -281,6 +281,10 @@ or configuration section on the command line at the same time.
.BR "\-D" " or " "\-\-dumptofs"
This option has been removed, use --dumpto instead.
.TP
.BR "\-\-ldipl-dump"
Install a List-directed dump record instead of a CCW-type dump.
.TP
.BR "\-M <DUMPLIST[,SIZE]>" " or " "--mvdump=<DUMPLIST[,SIZE]>"
Install a multi-volume dump record on each device associated with one of the

View File

@@ -25,7 +25,6 @@
#include "lib/util_libc.h"
#include "lib/util_part.h"
#include "lib/util_path.h"
#include "boot/s390.h"
#include "stage3.h"
#include "boot.h"
@@ -119,8 +118,6 @@ void bootmap_store_blockptr(void *buffer, disk_blockptr_t *ptr,
}
}
#define PROGRAM_TABLE_BLOCK_SIZE 512
/* Calculate the maximum number of entries in the program table. INFO
* specifies the type of disk. */
static int
@@ -321,7 +318,7 @@ static int add_component_file_range(struct install_set *bis,
size_t size;
int rc;
if (program_table_id)
if (bis->skip_prepare)
/* skip the preparation work */
goto write_segment_table;
if (add_files) {
@@ -402,7 +399,7 @@ static int add_component_buffer_align(struct install_set *bis, void *buffer,
disk_blockptr_t segment;
int rc;
if (program_table_id)
if (bis->skip_prepare)
/* skip the preparation work */
goto write_segment_table;
/* Write buffer */
@@ -511,9 +508,6 @@ extract_signature(const char *filename, void **ret_signature,
memcpy(signature, buffer + size - signature_size - sizeof(*file_sig),
signature_size);
*ret_signature = signature;
sig_head->length = signature_size;
switch (file_sig->id_type) {
case PKEY_ID_PKCS7:
sig_head->format = PKCS7_FORMAT;
@@ -522,8 +516,12 @@ extract_signature(const char *filename, void **ret_signature,
error_text("Unsupported signature type %02x",
file_sig->id_type);
signature_size = 0;
free(signature);
goto out;
}
sig_head->length = signature_size;
*ret_signature = signature;
/* return size of signature and corresponding header */
signature_size += sizeof(*file_sig);
out:
@@ -542,13 +540,6 @@ check_remaining_filesize(size_t filesize, size_t signature_size,
}
}
static int is_last_table(struct install_set *bis, int table_id)
{
assert(bis->nr_tables > 0 && bis->nr_tables <= NR_PROGRAM_TABLES);
return table_id == bis->nr_tables - 1;
}
static int add_ipl_program(struct install_set *bis, char *filename,
bool add_envblk, struct job_envblk_data *envblk,
struct job_ipl_data *ipl, disk_blockptr_t *program,
@@ -556,7 +547,6 @@ static int add_ipl_program(struct install_set *bis, char *filename,
struct job_target_data *target, int is_secure,
int menu_idx, int program_table_id)
{
int last_table = is_last_table(bis, program_table_id);
struct signature_header sig_head;
size_t ramdisk_size, image_size;
size_t stage3_params_size;
@@ -588,7 +578,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
stats.st_size = 0;
if (ipl->common.ramdisk != NULL) {
/* Add ramdisk */
if (verbose && last_table)
if (verbose && bis->print_details)
printf(" initial ramdisk...: %s\n", ipl->common.ramdisk);
/* Get ramdisk file size */
if (stat(ipl->common.ramdisk, &stats)) {
@@ -646,7 +636,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
if (signature_size &&
(is_secure == SECURE_BOOT_ENABLED ||
(is_secure == SECURE_BOOT_AUTO && secure_boot_supported))) {
if (verbose && last_table)
if (verbose && bis->print_details)
printf(" signature for.....: %s\n", ZIPL_STAGE3_PATH);
rc = add_component_buffer(bis, signature, sig_head.length,
@@ -716,14 +706,14 @@ static int add_ipl_program(struct install_set *bis, char *filename,
offset += sizeof(struct component_entry);
/* Add kernel image */
if (verbose && last_table)
if (verbose && bis->print_details)
printf(" kernel image......: %s\n", ipl->common.image);
signature_size = extract_signature(ipl->common.image, &signature, &sig_head);
if (signature_size &&
(is_secure == SECURE_BOOT_ENABLED ||
(is_secure == SECURE_BOOT_AUTO && secure_boot_supported))) {
if (verbose && last_table)
if (verbose && bis->print_details)
printf(" signature for.....: %s\n", ipl->common.image);
rc = add_component_buffer(bis, signature, sig_head.length,
@@ -766,7 +756,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
/* Add kernel parmline */
if (ipl->common.parmline != NULL) {
if (verbose && last_table)
if (verbose && bis->print_details)
printf(" kernel parmline...: '%s'\n", ipl->common.parmline);
rc = add_component_buffer(bis, ipl->common.parmline,
strlen(ipl->common.parmline) + 1,
@@ -790,7 +780,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
(is_secure == SECURE_BOOT_ENABLED ||
(is_secure == SECURE_BOOT_AUTO &&
secure_boot_supported))) {
if (verbose && last_table) {
if (verbose && bis->print_details) {
printf(" signature for.....: %s\n",
ipl->common.ramdisk);
}
@@ -883,7 +873,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
}
offset += sizeof(struct component_entry);
}
if (verbose && last_table)
if (verbose && bis->print_details)
print_components(bis, menu_idx);
/* Terminate component table */
create_component_entry(VOID_ADD(table, offset), NULL,
@@ -906,7 +896,6 @@ static int add_segment_program(struct install_set *bis,
struct job_target_data *target,
int program_table_id)
{
int last_table = is_last_table(bis, program_table_id);
void *table;
int offset;
int rc;
@@ -920,7 +909,7 @@ static int add_segment_program(struct install_set *bis,
create_component_header(VOID_ADD(table, offset), type);
offset += sizeof(struct component_header);
/* Add segment file */
if (verbose && last_table)
if (verbose && bis->print_details)
printf(" segment file......: %s\n", segment->segment);
rc = add_component_file(bis, segment->segment, segment->segment_addr, 0,
@@ -935,7 +924,7 @@ static int add_segment_program(struct install_set *bis,
}
offset += sizeof(struct component_entry);
/* Print component addresses */
if (verbose && last_table)
if (verbose && bis->print_details)
print_components(bis, 0 /* menu_idx */);
/* Terminate component table */
create_component_entry(VOID_ADD(table, offset), NULL,
@@ -955,7 +944,8 @@ static int add_segment_program(struct install_set *bis,
static int
check_dump_device_late(char *partition, struct disk_info *target_info,
struct job_target_data *target)
struct job_target_data *target,
struct job_data *job)
{
struct disk_info* info;
int rc;
@@ -967,8 +957,10 @@ check_dump_device_late(char *partition, struct disk_info *target_info,
partition);
return rc;
}
if ((info->type != disk_type_scsi) || (info->partnum == 0)) {
error_reason("Device '%s' is not a SCSI partition",
if ((job->is_ldipl_dump && info->type != disk_type_eckd_cdl) ||
(!job->is_ldipl_dump && info->type != disk_type_scsi) ||
info->partnum == 0) {
error_reason("Device '%s' is not a SCSI or DASD partition",
partition);
disk_free_info(info);
return -1;
@@ -983,12 +975,13 @@ check_dump_device_late(char *partition, struct disk_info *target_info,
return 0;
}
static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
static int add_dump_program(struct install_set *bis, struct job_data *job,
disk_blockptr_t *program, int verbose,
component_header_type type,
struct job_target_data *target,
int program_table_id)
{
struct job_dump_data *dump = &job->data.dump;
struct job_target_data *target = &job->target;
struct job_ipl_data ipl;
int rc;
@@ -997,7 +990,7 @@ static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
ipl.common = dump->common;
/* Get file system dump parmline */
rc = check_dump_device_late(dump->device, bis->info, target);
rc = check_dump_device_late(dump->device, bis->info, target, job);
if (rc)
return rc;
ipl.common.parmline = dump->common.parmline;
@@ -1011,11 +1004,11 @@ static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
/**
* Build a program table from job data and set pointer to program table
* block upon success
* PROGRAM_TABLE_ID: offset of the program table in the array (@bis->tables)
*/
static int build_program_table(struct job_data *job,
struct install_set *bis, int program_table_id)
{
int last_table = is_last_table(bis, program_table_id);
int entries, component_header;
disk_blockptr_t *table;
int is_secure;
@@ -1033,7 +1026,7 @@ static int build_program_table(struct job_data *job,
/* Add programs */
switch (job->id) {
case job_ipl:
if (last_table) {
if (bis->print_details) {
if (job->command_line)
printf("Adding IPL section\n");
else
@@ -1052,7 +1045,7 @@ static int build_program_table(struct job_data *job,
program_table_id);
break;
case job_segment:
if (last_table) {
if (bis->print_details) {
if (job->command_line)
printf("Adding segment load section\n");
else
@@ -1066,33 +1059,33 @@ static int build_program_table(struct job_data *job,
break;
case job_dump_partition:
/* Only useful for a partition dump that uses a dump kernel*/
if (last_table) {
if (bis->print_details) {
if (job->command_line)
printf("Adding dump section\n");
else
printf("Adding dump section '%s' (default)\n",
job->name);
}
rc = add_dump_program(bis, &job->data.dump, &table[0],
rc = add_dump_program(bis, job, &table[0],
verbose || job->command_line,
COMPONENT_HEADER_DUMP, &job->target,
COMPONENT_HEADER_DUMP,
program_table_id);
break;
case job_menu:
if (last_table)
if (bis->print_details)
printf("Building menu '%s'\n", job->name);
rc = 0;
for (i=0; i < job->data.menu.num; i++) {
switch (job->data.menu.entry[i].id) {
case job_ipl:
if (last_table &&
if (bis->print_details &&
job->data.menu.entry[i].data.ipl.common.ignore) {
printf("Skipping #%d: IPL section '%s' (missing files)\n",
job->data.menu.entry[i].pos,
job->data.menu.entry[i].name);
break;
}
if (last_table)
if (bis->print_details)
printf("Adding #%d: IPL section '%s'%s",
job->data.menu.entry[i].pos,
job->data.menu.entry[i].name,
@@ -1102,12 +1095,12 @@ static int build_program_table(struct job_data *job,
if (job->data.menu.entry[i].data.ipl.is_kdump) {
component_header =
COMPONENT_HEADER_DUMP;
if (last_table)
if (bis->print_details)
printf(" (kdump)\n");
} else {
component_header =
COMPONENT_HEADER_IPL;
if (last_table)
if (bis->print_details)
printf("\n");
}
if (job->is_secure != SECURE_BOOT_UNDEFINED)
@@ -1150,7 +1143,7 @@ static int build_program_table(struct job_data *job,
rc = -1;
break;
}
if (job->envblk.buf && verbose && last_table)
if (job->envblk.buf && verbose && bis->print_details)
envblk_print(job->envblk.buf, job->envblk.size);
if (rc == 0) {
@@ -1199,7 +1192,7 @@ static int install_stages_dasd_fba(int fd, char *filename,
void *stage2_data;
switch (program_table_id) {
case PROGRAM_TABLE_0:
case LEGACY_BLKPTR_FORMAT_ID:
/*
* This program table is used for CCW-type IPL (see comments
* for install_bootloader()).
@@ -1220,7 +1213,7 @@ static int install_stages_dasd_fba(int fd, char *filename,
return -1;
free(stage2_list);
break;
case PROGRAM_TABLE_1:
case BLKPTR_FORMAT_ID:
/*
* This program table is not used when booting from DASD FBA
* (see comments for install_bootloader()
@@ -1248,7 +1241,7 @@ static int install_stages_eckd_dasd(int fd, char *filename,
void *stage2b_data;
switch (program_table_id) {
case PROGRAM_TABLE_0:
case LEGACY_BLKPTR_FORMAT_ID:
/*
* This program table is used for CCW-type IPL.
* Add stage2 loader
@@ -1269,7 +1262,7 @@ static int install_stages_eckd_dasd(int fd, char *filename,
return -1;
free(stage2b_list);
break;
case PROGRAM_TABLE_1:
case BLKPTR_FORMAT_ID:
/*
* This program table is used for List-Directed IPL,
* which doesn't invoke stage2 loader.
@@ -1397,11 +1390,17 @@ static int disk_is_appropriate(const struct job_data *job,
error_reason("Secure boot forced for improper disk type");
return 0;
}
if (job->id == job_dump_partition &&
job->is_ldipl_dump &&
info->type != disk_type_eckd_cdl) {
error_reason("List-directed dump not support on DASD with LDL format");
return 0;
}
return 1;
}
static int
check_dump_device(const struct job_data *job, const struct disk_info *info,
check_dump_device(struct job_data *job, const struct disk_info *info,
const char *device)
{
int rc, part_ext;
@@ -1415,6 +1414,9 @@ check_dump_device(const struct job_data *job, const struct disk_info *info,
if (!disk_is_appropriate(job, info))
return -1;
if (is_ngdump_enabled(job))
return 0;
rc = util_part_search(device, info->geo.start,
info->phy_blocks, info->phy_block_size, &part_ext);
if (rc <= 0 || part_ext) {
@@ -1430,30 +1432,15 @@ check_dump_device(const struct job_data *job, const struct disk_info *info,
return 0;
}
/**
* Set actual number of "similar" program tables to be installed
*/
static void set_nr_tables(struct job_data *job, struct install_set *bis)
{
assert(bis->nr_tables == 0);
if (bis->info->type == disk_type_eckd_cdl &&
(job->id == job_ipl || job->id == job_menu))
bis->nr_tables = NR_PROGRAM_TABLES;
else
bis->nr_tables = 1;
}
/**
* Prepare resources to build a program table
*/
static int prepare_build_program_table_device(struct job_data *job,
struct install_set *bis,
int program_table_id)
struct install_set *bis)
{
ulong unused_size;
if (program_table_id)
if (bis->skip_prepare)
/* skip the preparation work */
return 0;
/* Get full path of bootmap file */
@@ -1522,19 +1509,26 @@ static int prepare_build_program_table_device(struct job_data *job,
bis->filename);
return -1;
}
set_nr_tables(job, bis);
return 0;
}
static int bootmap_create_device(struct job_data *job, struct install_set *bis,
int program_table_id)
/**
* Called when making a dump on a raw SCSI partition
*/
static int prepare_bootloader_device(struct job_data *job,
struct install_set *bis)
{
if (prepare_build_program_table_device(job, bis, program_table_id))
if (prepare_build_program_table_device(job, bis))
return -1;
if (build_program_table(job, bis, program_table_id))
/*
* build a single program table at offset 1,
* see comment before install_bootloader() for details
*/
bis->print_details = 1;
if (build_program_table(job, bis, BLKPTR_FORMAT_ID))
return -1;
/* Install stage 2 loader to bootmap if necessary */
if (bootmap_install_stages(job, bis, program_table_id)) {
if (bootmap_install_stages(job, bis, BLKPTR_FORMAT_ID)) {
error_text("Could not install loader stages to bootmap");
return -1;
}
@@ -1546,10 +1540,9 @@ static int bootmap_create_device(struct job_data *job, struct install_set *bis,
*/
static int prepare_build_program_table_file(struct job_data *job,
char *bootmap_dir,
struct install_set *bis,
int program_table_id)
struct install_set *bis)
{
if (program_table_id)
if (bis->skip_prepare)
/* skip the preparation work */
return 0;
/* Create temporary bootmap file */
@@ -1602,7 +1595,6 @@ static int prepare_build_program_table_file(struct job_data *job,
error_text("Could not write to file '%s'", bis->filename);
return -1;
}
set_nr_tables(job, bis);
return 0;
}
@@ -1627,11 +1619,13 @@ static int finalize_create_file(char *bootmap_dir, struct install_set *bis)
return 0;
}
static int bootmap_create_file(struct job_data *job, char *bootmap_dir,
struct install_set *bis, int program_table_id)
/*
* PROGRAM_TABLE_ID: offset of the program table in the array (@bis->tables)
*/
static int bootmap_create_file(struct job_data *job, struct install_set *bis,
char *bootmap_dir, int program_table_id)
{
if (prepare_build_program_table_file(job, bootmap_dir, bis,
program_table_id))
if (prepare_build_program_table_file(job, bootmap_dir, bis))
return -1;
if (build_program_table(job, bis, program_table_id))
return -1;
@@ -1641,8 +1635,6 @@ static int bootmap_create_file(struct job_data *job, char *bootmap_dir,
bis->filename);
return -1;
}
if (!dry_run && is_last_table(bis, program_table_id))
return finalize_create_file(bootmap_dir, bis);
return 0;
}
@@ -1680,14 +1672,12 @@ ngdump_create_meta(const char *path)
return 0;
}
static int bootmap_create_device_ngdump(struct job_data *job,
struct install_set *bis,
int program_table_id)
static int prepare_bootloader_ngdump(struct job_data *job,
struct install_set *bis)
{
struct disk_info *info;
int rc;
char *bootmap_dir;
assert(program_table_id == 0);
/* Retrieve target device information */
if (disk_get_info(job->data.dump.device, &job->target, &info))
return -1;
@@ -1712,22 +1702,6 @@ static int bootmap_create_device_ngdump(struct job_data *job,
return -1;
}
bis->dump_tmp_dir_created = 1;
if (!dry_run) {
char *cmd = NULL;
util_asprintf(&cmd, "mkfs.%s -qF %s >/dev/null",
NGDUMP_FSTYPE, job->data.dump.device);
if (verbose)
printf("Formatting partition '%s'\n",
job->data.dump.device);
rc = system(cmd);
free(cmd);
if (rc) {
error_reason(strerror(errno));
error_text("Could not format partition '%s':",
job->data.dump.device);
return -1;
}
}
/*
* Mount partition where bootmap file and also a dump file will
* be stored.
@@ -1740,29 +1714,47 @@ static int bootmap_create_device_ngdump(struct job_data *job,
return -1;
}
bis->dump_mounted = 1;
if (bootmap_create_file(job, bis->dump_mount_point,
bis, program_table_id))
bootmap_dir = bis->dump_mount_point;
/*
* Build a single program table for List-Directed IPL
* See comments before install_bootloader() for details
*/
bis->print_details = 1;
if (bootmap_create_file(job, bis, bootmap_dir, BLKPTR_FORMAT_ID))
return -1;
if (ngdump_create_meta(bis->dump_mount_point))
if (!dry_run && finalize_create_file(bootmap_dir, bis))
return -1;
return 0;
return ngdump_create_meta(bootmap_dir);
}
static int
bootmap_create(struct job_data *job, struct install_set *bis,
int program_table_id)
/**
* Build one or two program tables for CCW-type and(or) for List-Direceted IPL
* at respective offsets in the array BIS->tables. See the comment before
* install_bootloader() for details
*/
static int prepare_bootloader_ipl(struct job_data *job, struct install_set *bis)
{
if (job->id == job_dump_partition) {
if (is_ngdump_enabled(job->data.dump.device, &job->target))
return bootmap_create_device_ngdump(job, bis,
program_table_id);
else
return bootmap_create_device(job, bis,
program_table_id);
} else
return bootmap_create_file(job, job->target.bootmap_dir,
bis, program_table_id);
char *bootmap_dir = job->target.bootmap_dir;
/*
* Build a program table for List-Directed IPL from
* SCSI or ECKD DASD
*/
bis->print_details = 1;
if (bootmap_create_file(job, bis, bootmap_dir, BLKPTR_FORMAT_ID))
return -1;
if (bis->info->type == disk_type_scsi)
/* only one table to be installed per device */
return dry_run ? 0 : finalize_create_file(bootmap_dir, bis);
/*
* Build one more program table for CCW-type IPL from
* ECKD DASD
*/
bis->skip_prepare = 1;
bis->print_details = 0;
if (bootmap_create_file(job, bis, bootmap_dir, LEGACY_BLKPTR_FORMAT_ID))
return -1;
return dry_run ? 0 : finalize_create_file(bootmap_dir, bis);
}
/**
@@ -1796,20 +1788,19 @@ static int init_bis(struct job_data *job, struct install_set *bis)
*/
int prepare_bootloader(struct job_data *job, struct install_set *bis)
{
int i;
int rc;
secure_boot_supported = check_secure_boot_support();
rc = init_bis(job, bis);
if (rc)
return rc;
for (i = 0;; i++) {
rc = bootmap_create(job, bis, i);
if (rc || is_last_table(bis, i))
break;
if (init_bis(job, bis))
return -1;
if (job->id == job_dump_partition) {
if (is_ngdump_enabled(job))
return prepare_bootloader_ngdump(job, bis);
else
return prepare_bootloader_device(job, bis);
} else {
return prepare_bootloader_ipl(job, bis);
}
return rc;
return -1;
}
/**

View File

@@ -509,6 +509,19 @@ disk_is_scsi(const char* device, struct job_target_data* target)
return rc;
}
int disk_is_eckd_ldl(const char *device, struct job_target_data *target)
{
struct disk_info *info;
int rc = 0;
if (disk_get_info(device, target, &info) == -1)
return 0;
if (info->type == disk_type_eckd_ldl)
rc = 1;
disk_free_info(info);
return rc;
}
int
disk_is_nvme(const char* device, struct job_target_data* target)
{
@@ -828,7 +841,7 @@ disk_get_type_name(disk_type_t type)
}
/* Return IPL types supported for a given disk TYPE */
char *disk_get_ipl_type(disk_type_t type)
char *disk_get_ipl_type(disk_type_t type, int is_dump)
{
switch (type) {
case disk_type_scsi:
@@ -837,7 +850,7 @@ char *disk_get_ipl_type(disk_type_t type)
case disk_type_eckd_ldl:
return "CCW-";
case disk_type_eckd_cdl:
return "CCW- and LD-";
return is_dump ? "LD-" : "CCW- and LD-";
default:
return "";
}

View File

@@ -45,32 +45,9 @@ static inline unsigned long blk_cnt(int size, struct disk_info *info)
return (size + info->phy_block_size - 1) / info->phy_block_size;
}
/* Types of SCSI disk layouts */
enum scsi_layout {
scsi_layout_pcbios,
scsi_layout_sun,
scsi_layout_sgi,
scsi_layout_unknown
};
/* From linux/fs.h */
#define BLKFLSBUF _IO(0x12, 97)
/* Determine SCSI disk layout from the specified BOOTBLOCK. */
static enum scsi_layout
get_scsi_layout(unsigned char* bootblock)
{
if ((bootblock[510] == 0x55) && (bootblock[511] == 0xaa))
return scsi_layout_pcbios;
else if ((bootblock[508] == 0xda) && (bootblock[509] == 0xbe))
return scsi_layout_sun;
else if ((bootblock[0] == 0x0b) && (bootblock[1] == 0xe5) &&
(bootblock[2] == 0xa9) && (bootblock[3] == 0x41))
return scsi_layout_sgi;
return scsi_layout_unknown;
}
static int
overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic);
@@ -112,7 +89,7 @@ update_scsi_mbr(void* bootblock, disk_blockptr_t* table,
mbr->version_id = DISK_LAYOUT_ID;
bootmap_store_blockptr(&mbr->program_table_pointer, table, info,
0 /* this argument is ignored for scsi */);
if (scsi_dump_sb_blockptr->linear.block != 0) {
if (scsi_dump_sb_blockptr && scsi_dump_sb_blockptr->linear.block != 0) {
/* Write dump boot_info */
param.block = scsi_dump_sb_blockptr->linear.block *
scsi_dump_sb_blockptr->linear.size;
@@ -318,35 +295,113 @@ static int install_eckd_cdl_ld(int fd, disk_blockptr_t *br,
return 0;
}
/**
* Install program tables for CCW-type and(or) List-Directed IPL
* See the comment before install_bootloader() for details.
*
* TABLES: array of the program tables to be installed
*/
int install_bootloader_ipl(struct program_table *tables,
struct disk_info *info,
int fd)
{
struct program_table *pt = &tables[LEGACY_BLKPTR_FORMAT_ID];
int rc = -1;
switch (info->type) {
case disk_type_scsi:
/* List-Directed IPL */
pt = &tables[BLKPTR_FORMAT_ID];
rc = install_scsi(fd, &pt->table, info, NULL);
break;
case disk_type_fba:
rc = install_fba_ccw(fd,
&pt->table,
pt->stage1b_list,
pt->stage1b_count, info);
break;
case disk_type_eckd_ldl:
rc = install_eckd_ldl_ccw(fd,
&pt->table,
pt->stage1b_list,
pt->stage1b_count, info);
break;
case disk_type_eckd_cdl:
rc = install_eckd_cdl_ccw(fd,
&pt->table,
pt->stage1b_list,
pt->stage1b_count, info);
if (rc)
break;
/* install one more table for List-Directed IPL */
pt = &tables[BLKPTR_FORMAT_ID];
rc = install_eckd_cdl_ld(fd, pt->stage1b_list, info);
break;
case disk_type_diag:
error_reason("Inappropriarte device type (%d) for IPL",
info->type);
break;
}
return rc;
}
/**
* Install a program table for List-Directed dump
* See the comment before install_bootloader() for details
*/
static int install_bootloader_dump(struct program_table *tables,
struct disk_info *info,
disk_blockptr_t *scsi_dump_sb_blockptr,
int ngdump_enabled,
int fd)
{
struct program_table *pt = &tables[BLKPTR_FORMAT_ID];
int rc = -1;
switch (info->type) {
case disk_type_scsi:
rc = install_scsi(fd, &pt->table, info, scsi_dump_sb_blockptr);
if (rc == 0 && !ngdump_enabled)
rc = overwrite_partition_start(fd, info, 0);
break;
case disk_type_eckd_cdl:
rc = install_eckd_cdl_ld(fd, pt->stage1b_list, info);
break;
default:
error_reason("Inappropriarte device type (%d) for List-Directed dump",
info->type);
break;
}
return rc;
}
/**
* Install a "compatible" boot record referring one, or two "similar"
* program tables.
*
* The picture below shows which program table is used for IPL
* of specified type from disk of specified type.
* E.g. program table "0" is used for CCW-type IPL from ECKD DASD,
* LD-IPL from DASD FBA is unsupported (respectively, only one program
* table "0" is used), etc.
*
* CCW-IPL LD-IPL
*
* SCSI X 0
* DASD FBA 0 X
* ECKD DASD LDL 0 X
* ECKD DASD CDL 0 1
* For compatibility reasons zIPL installs multiple "similar"
* program tables which differ only in block pointers format.
* Each such table is identified by an offset in the array BIS->tables
* of in-memory program table representations built by prepare_bootloader().
* The common rule is that tables built for CCW-type IPL are placed
* at offset 0, and tables built for List-Directed IPL are placed at
* offset 1. The same works for dumps.
*/
int install_bootloader(struct job_data *job, struct install_set *bis)
{
disk_blockptr_t *scsi_dump_sb_blockptr = &bis->scsi_dump_sb_blockptr;
struct program_table *pt0 = &bis->tables[PROGRAM_TABLE_0];
struct program_table *pt1 = &bis->tables[PROGRAM_TABLE_1];
struct disk_info *info = bis->info;
char *device = bis->device;
int fd, rc;
if (!info)
return 0;
/* Inform user about what we're up to */
printf("Preparing boot device for %sIPL: ",
disk_get_ipl_type(info->type));
printf("Preparing boot device for %s%s: ",
disk_get_ipl_type(info->type,
job->id == job_dump_partition),
job->id == job_dump_partition ? "dump" : "IPL");
if (info->name) {
printf("%s", info->name);
if (info->devno >= 0)
@@ -379,39 +434,13 @@ int install_bootloader(struct job_data *job, struct install_set *bis)
* for CCW-type IPL and (or) for List-Directed IPL (see the
* picture in comments above)
*/
rc = -1;
switch (info->type) {
case disk_type_scsi:
rc = install_scsi(fd, &pt0->table, info,
scsi_dump_sb_blockptr);
if (rc == 0 && job->id == job_dump_partition &&
!is_ngdump_enabled(device, &job->target))
rc = overwrite_partition_start(fd, info, 0);
break;
case disk_type_fba:
rc = install_fba_ccw(fd,
&pt0->table,
pt0->stage1b_list,
pt0->stage1b_count, info);
break;
case disk_type_eckd_ldl:
rc = install_eckd_ldl_ccw(fd,
&pt0->table,
pt0->stage1b_list,
pt0->stage1b_count, info);
break;
case disk_type_eckd_cdl:
rc = install_eckd_cdl_ccw(fd,
&pt0->table,
pt0->stage1b_list,
pt0->stage1b_count, info);
if (rc)
break;
rc = install_eckd_cdl_ld(fd, pt1->stage1b_list, info);
break;
case disk_type_diag:
/* Should not happen */
break;
if (job->id == job_dump_partition) {
rc = install_bootloader_dump(bis->tables, info,
scsi_dump_sb_blockptr,
is_ngdump_enabled(job),
fd);
} else {
rc = install_bootloader_ipl(bis->tables, info, fd);
}
if (fsync(fd))

View File

@@ -63,6 +63,7 @@ static struct option options[] = {
{ "dry-run", no_argument, NULL, '0'},
{ "force", no_argument, NULL, 'f'},
{ "kdump", required_argument, NULL, 'k'},
{ "ldipl-dump", no_argument, NULL, 0xb0},
{ "secure", required_argument, NULL, 'S'},
{ NULL, 0, NULL, 0 }
};
@@ -93,6 +94,7 @@ struct command_line {
int dry_run;
int force;
int is_secure;
int is_ldipl_dump;
enum scan_section_type type;
};
@@ -284,6 +286,9 @@ get_command_line(int argc, char* argv[], struct command_line* line)
case 'f':
cmdline.force = 1;
break;
case 0xb0:
cmdline.is_ldipl_dump = 1;
break;
case 1:
/* Non-option is interpreted as section name */
if (cmdline.section != NULL) {
@@ -561,11 +566,13 @@ get_common_components(struct job_common_ipl_data *common,
MAXIMUM_PHYSICAL_BLOCKSIZE);
if (rc)
goto error;
rc = set_cl_element(&cl[num++], "parmline", NULL, &common->parm_addr,
MAXIMUM_PARMLINE_SIZE, 0,
MAXIMUM_PHYSICAL_BLOCKSIZE);
if (rc)
goto error;
if (common->parmline) {
rc = set_cl_element(&cl[num++], "parmline", NULL, &common->parm_addr,
MAXIMUM_PARMLINE_SIZE, 0,
MAXIMUM_PHYSICAL_BLOCKSIZE);
if (rc)
goto error;
}
if (common->ramdisk) {
rc = set_cl_element(&cl[num++], "initial ramdisk",
common->ramdisk, &common->ramdisk_addr,
@@ -781,10 +788,13 @@ check_common_ipl_data(struct job_common_ipl_data *common, const char *section,
rc = 0;
goto skip_image;
}
fprintf(stderr, "Section '%s': Could not read image file '%s'\n",
section, common->image);
return rc;
}
if (size < MAX_COMMAND_LINE_SIZE + sizeof(uint64_t)) {
error_text_section("Image file", section, common->image);
free(buffer);
return -1;
}
@@ -797,8 +807,11 @@ check_common_ipl_data(struct job_common_ipl_data *common, const char *section,
error_text("The length of the parameters line "
"(%d bytes) exceeds the allowed maximum "
"(%d bytes) in section '%s'", len, max_parm_size, section);
free(buffer);
return -1;
}
free(buffer);
buffer = NULL;
}
skip_image:
if (common->ramdisk != NULL) {
@@ -811,6 +824,8 @@ skip_image:
common->ignore = true;
rc = 0;
} else {
fprintf(stderr, "Section '%s': Missing ramdisk file '%s'\n",
section, common->ramdisk);
return rc;
}
}
@@ -908,7 +923,7 @@ check_job_images_ngdump(struct job_dump_data* dump, char *name)
FILE *fp;
int rc;
misc_asprintf(&ppn_cmd, "%s %s", helper, dump->device);
misc_asprintf(&ppn_cmd, "%s %s %d", helper, dump->device, dry_run);
printf("Run %s\n", ppn_cmd);
fp = popen(ppn_cmd, "r");
@@ -1972,6 +1987,7 @@ job_get(int argc, char* argv[], struct job_data** data)
job->data.mvdump.force = cmdline.force;
job->dry_run = cmdline.dry_run;
job->is_secure = SECURE_BOOT_UNDEFINED;
job->is_ldipl_dump = cmdline.is_ldipl_dump;
if (job->verbose)
printf("Looking for components in '%s'\n", util_libdir());
@@ -2014,7 +2030,9 @@ job_get(int argc, char* argv[], struct job_data** data)
}
bool
is_ngdump_enabled(const char* device, struct job_target_data* target)
is_ngdump_enabled(struct job_data *job)
{
return disk_is_nvme(device, target);
if (job->is_ldipl_dump)
return true;
return disk_is_nvme(job->data.dump.device, &job->target);
}

View File

@@ -1873,8 +1873,10 @@ void scan_update_bls_path(struct scan_token *scan)
if (misc_check_readable_file(file)) {
misc_asprintf(&img_value, "%s%s",
target_value, file);
if (misc_check_readable_file(img_value))
if (misc_check_readable_file(img_value)) {
free(img_value);
continue;
}
/*
* when file has stripped the load address part,

View File

@@ -72,6 +72,7 @@ static const char* usage_text[] = {
" stand-alone dump tool",
"-d, --dumpto DUMPDEV[,SIZE] Install a system dump record on tape device",
" or disk partition DUMPDEV",
" --ldipl-dump Install a List-directed dump",
"-M, --mvdump DEVLIST[,SIZE] Install a multi-volume dump record on each",
" disk partition listed in file DEVLIST",
"-f, --force Disable sanity check while producing a",
@@ -171,8 +172,9 @@ main(int argc, char* argv[])
/* Do it */
switch (job->id) {
case job_dump_partition:
if (disk_is_tape(job->data.dump.device) ||
!disk_is_scsi(job->data.dump.device, &job->target)) {
if (!is_ngdump_enabled(job) &&
(disk_is_tape(job->data.dump.device) ||
!disk_is_scsi(job->data.dump.device, &job->target))) {
rc = install_dump(job->data.dump.device, &job->target,
job->data.dump.mem);
break;
@@ -184,10 +186,16 @@ main(int argc, char* argv[])
rc = -1;
break;
}
if (is_ngdump_enabled(job->data.dump.device, &job->target))
if (is_ngdump_enabled(job)) {
if (disk_is_eckd_ldl(job->data.dump.device, &job->target)) {
error_reason("List-directed dump on ECKD with LDL not supported");
rc = -1;
break;
}
rc = check_job_images_ngdump(&job->data.dump, job->name);
else
} else {
rc = check_job_dump_images(&job->data.dump, job->name);
}
if (rc != 0)
break;
/* Fall through. */

Some files were not shown because too many files have changed in this diff Show More