Compare commits

...

75 Commits

Author SHA1 Message Date
Jan Höppner
d6925a30da New release s390-tools-2.7.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Ingo Franzki
fe4cc7c479 zkey: add generated files to .gitignore
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Ingo Franzki
fa3cabc8af zkey: Makefile: Don't rebuild .o.d files on 'make install'
The .o.d make targets in common.mak do not expect that
header files are generated by a make target. When a new header
file is generated, the .o.d targets will be rebuilt on the
next make invocation, because that new header file is then
detected, and is then treated as a new dependency of all .o.d
targets.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Jan Höppner
5a9b56f814 lscss: Fix email address
The linux.vnet.ibm.com addresses will be become disfunct by eoy.

Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-31 11:44:17 +01:00
Julian Wiedmann
20145b6d06 qethqoat: add OSA-Express7S support
Add the missing identifiers to report the card name and link speed.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 13:42:12 +02:00
Ingo Franzki
9561a0b983 zkey: Enhance error message on key store open
Print a meaningful reason when the keystore can not be
accessed, e.g. because the user is not allowed to access
the keystore directory.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Philipp Rudo
97fa88299f zfcpdump: Remove unneeded include <zlib.h>
Dump compression was a feature of the file system dumper which was removed
several years ago. This include is a leftover. Remove it.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Jan Höppner
aaaebb2030 zpcictl: Change wording of man-page and help output
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Karsten Graul
ff2a403bd2 osasnmpd: remove unused code, improve readability
Remove unused code because query_OSA_EXP does actually never return -1.
So make its return value unsigned and remove all checks for negative
return values.

Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Karsten Graul
66ed1727f9 osasnmpd: start without real OSA devices
Osasnmpd would start without any devices, but refuses to start when all
devices are no real OSA devices.
Start osasnmpd in this case because it re-scans via update_mib_info
whenever the interface data changes.

Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-25 11:00:52 +02:00
Ingo Franzki
c33cc5a619 zkey: Makefile: Avoid relink of modules during 'make install'
Because targets check-dep-zkey and check-dep-zkey-cryptsetup
do not produce any file, any targets that have a pre-req on those
targets are rebuilt during 'make install'.

Also correct .PHONY targets.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/46
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-22 14:02:35 +02:00
Karsten Graul
cd46297d7c s390-tools/utils: handle util_scandir errors correctly
The util_scandir_* functions may return 0 or -1, in which case no vector
is allocated in libutil/util_scandir.c. util_ptr_vec_free, called by
util_scandir_free or directly from lschp.c and lsscm.c, does always
call free for the vector which might be not initialized.

Fix this by always initializing the vector with NULL in __scandir and
add some api hardening by checking the vector and count in
util_ptr_vec_free before iterating over the vector.
And update the comment for util_scandir to indicate that -1 may be
returned in error cases plus that the vector is initialized with NULL.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/43
Reported-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:32:53 +02:00
Dimitri John Ledkov
07b11982e3 zdev: Trigger generic_ccw devices on any kernel module loads.
Generic CCW device can use any driver, and the value of the driver is
not known ahead of time. To avoid the race between loading and binding
a kernel module, and devices added - retrigger generic-ccw devices on
any kernel module load.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/37
Link: https://bugs.launchpad.net/ubuntu-z-systems/+bug/1794308
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/45

Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:32:40 +02:00
Dimitri John Ledkov
35348c302b zdev/initramfs: add s390-tools- prefix to hook, due to conflicts.
Unfortunately zdev hook already exists in Ubuntu, from an unrelated
project. ZFS uses zdev/zpool names, and ships a zdev hook to do ZFS
specific initialisation. It is available on s390x and thus results in
file-conflict upon installing both. Thus renaming this zdev hook to
s390-tools-zdev.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/41
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:31:54 +02:00
Dimitri John Ledkov
35312d0c47 cpacfstatsd.service: only run on LPARs.
Add ConditionVirtualization=no to the service file such that it is
only started on LPARs. This service cannot run on z/VM nor KVM, and
fails resulting in a degraded boot.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/38
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-19 15:31:40 +02:00
Jan Höppner
342c6a3707 zpcictl: Make device node for NVMe optional
At the moment, if we specify the slot address of an NVMe device but
can't find the corresponding device node, the execution is terminated.

This is a bit harsh as the device node is rather optional and only
necessary to collect S.M.A.R.T. data. We should still be able to issue
the error reporting, even if we couldn't determine the device node.

Therefore, make sure the device node for NVMe devices is optional by
changing various error messages to warnings.
Change sysfs_get_slot_addr() to have a return value and work with that
accordingly.
Also make sure, that execution is terminated when a valid device node
was specified but no matching slot address was determined. The slot
address is necessary to issue the error reporting commands.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Jan Höppner
e2a8d85916 zpcictl: Read device link to obtain device address
The address sysfs attribute might not be present on some older kernel
levels. Read the device link instead using readlink() to obtain the
address.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Jan Höppner
8f0496b26a zpcictl: Use fopen() instead of open() for writes
Be consistent with the rest of the code and use fopen() rather than
open().

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Jan Höppner
d03be73536 zpcictl: Rephrase man page entries and tool output
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Michael Holzheu
a87268d62e util_path_example: Fix usage message
Document that for the "sysfs" invocation the mount point is optional.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Michael Holzheu
9cc06a0529 util_proc: Fix typos in description of util_proc_mnt_get_entry()
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Michael Holzheu
3b1ccce515 util_proc: Fix return code handling for util_proc_mnt_get_entry()
Correctly return -1 if the requested file system is not mounted.

Reported-by: Peter Morjan <peter.morjan@de.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Hans Wippel
ffe91d1b30 zdev: fix qeth BridgePort and VNICC conflict checking
This patch fixes false positives when attributes are checked for
conflicts between BridgePort and VNICC.

Signed-off-by: Hans Wippel <hwippel@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-10-11 14:41:32 +02:00
Hendrik Brueckner
f35c5d01fd zpcictl: include sys/sysmacros.h to avoid minor/major glibc warnings
The minor()/major() function definitions are moved to sys/sysmacros.h
and will be removed from sys/types.h.  To correct below warning, simply
include sys/sysmacros.h.

  zpcictl.c: In function ‘sysfs_get_slot_addr’:
  zpcictl.c:184:13: warning: In the GNU C Library, "major" is defined
   by <sys/sysmacros.h>. For historical compatibility, it is
   currently defined by <sys/types.h> as well, but we plan to
   remove this soon. To use "major", include <sys/sysmacros.h>
   directly. If you did not intend to use a system-defined macro
   "major", you should undefine it after including <sys/types.h>.
    major = major(dev_stat.st_rdev);
               ^~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
2018-10-02 09:55:27 +02:00
Jan Höppner
b23c35c390 zcryptctl: Add binary to .gitignore
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:54 +02:00
Jan Höppner
177cf8cfeb zpcictl: Introduce new tool zpcictl
zpcictl is used to manage PCI devices on z Systems. In this first
version it is mainly used to handle erroneous PCI devices by changing
their state and make those changes known to the SE. Log data, such as
S.M.A.R.T. data for NVMe devices, is sent alongside those state changes.

The state change is issued by sending data via the PCI 'report_error'
sysfs attribute. It's a binary attribute which will cause the host to
send an Adapter Notification Event.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:44 +02:00
Harald Freudenberger
f05f7d656b zcryptctl: new tool zcryptctl for multiple zcrypt node management
With the latest kernel comes an extension for the zcrypt
device driver to support multiple zcrypt device nodes.

Here is the userspace part of this which adds a new
application zcryptctl for user friendly management of
this feature.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:31 +02:00
Dan Horák
0bf4f1b957 zkey: Be explicit about linking the tools
I've met cases when the make's default rule for linking was used instead
omitting the ALL_LDFLAGS variable. The linking rule from common.mak is
defined for linking *.o files only, here we have libutil.a too.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:28 +02:00
Dan Horák
cd38119888 zkey: Be consistent when referring to libutil.a
Link: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:21 +02:00
Dan Horák
cadef5c0ff zkey: Drop redundant include
Link: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:15 +02:00
Dan Horák
02e1c783f6 Makefile: drop LOADLIBES variable
Remove deprecated LOADLIBES variable from the Makefile rules, LDLIBS
serves the same purpose these days.

Link: https://github.com/ibm-s390-tools/s390-tools/pull/35
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-29 12:41:08 +02:00
Eric Sandeen
07e30951f8 zipl: use FIEMAP mapping ioctl if it exists
zipl currently uses the FIBMAP ioctl to map blocks for the bootloader;
on XFS, if FIBMAP is requested on a reflinked file, it will fail -
and FIBMAP returns 0 in this case, which is indistinguishable from a
hole.  This causes boot to fail because the file is not mapped.

We can use the FIEMAP ioctl instead, which is able to map reflinked
files.  While FIEMAP is able to map entire extents at once, here we
simply use it to obtain the mapping block-by-block so that it fits
in with the current FIBMAP calls.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/34
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/36
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Tested-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:28:18 +02:00
Harald Freudenberger
0a0b4c3826 lszcrypt: support for alternate zcrypt device drivers
With kernel 4.19 there comes an extension to the existing
AP bus which supports alternate zcrypt drivers. For details
about this see kernel patch "s390/zcrypt: AP bus support for
alternate driver(s)". So now lszcrypt displays the driver
name in verbose mode. As some of the information displayed
by lszcrypt was based on sysfs attributes, which are only
available when the default zcrypt driver is bound to the
device, this also needed some rework. If a sysfs attribute
is not available because of an alternate driver binding
(or no driver) a question mark is printed into the field.

Together with this a slight rework of the displayed information
has been done. The two columns for pending requests and pending
replies has been merged to one pending column and the column
sizes have been adjusted.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:26:29 +02:00
Peter Oberparleiter
eade995185 zdsfs: Direct --help and --version output to stdout
zdsfs writes output for --help and --version to stderr. This is
likely because zdsfs calls into a FUSE function for additional
usage output that also writes to stderr (prior to FUSE 3.0.0).

To be consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for zdsfs generated output, and by
redirecting stderr to stdout before calling the FUSE function.

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
0eba8d11df tape390_display: Direct --help output to stdout
tape390_display writes output for --help to stderr. To be consistent
with other s390-tools and GNU coding guide lines, fix this by using
stdout for tool-generated usage help.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
257490366b util_prg_example: Add --help and --version options
Add missing long options for --help and --version in util_prg_example.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
5ef1320a7b iucvconn/iucvtty: Direct --help output to stdout
Both iucvconn and iucvtty write output for --help to stderr. To be
consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for tool-generated usage help.

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
f2f572fa70 hmcdrvfs: Direct --help and --version output to stdout
hmcdrvfs writes output for --help and --version to stderr. This is
likely because hmcdrvfs calls into a FUSE function for additional
usage output that also writes to stderr (prior to FUSE 3.0.0).

To be consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for hmcdrvfs generated output, and by
redirecting stderr to stdout before calling the FUSE function.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
e655f0cd7b cmsfs-fuse: Direct --help and --version output to stdout
cmsfs-fuse writes output for --help and --version to stderr. This is
likely because cmsfs-fuse calls into a FUSE function for additional
usage output that also writes to stderr (prior to FUSE 3.0.0).

To be consistent with other s390-tools and GNU coding guide lines,
fix this by using stdout for cmsfs-fuse generated output, and by
redirecting stderr to stdout before calling the FUSE function.

Also remove an inactive call to add FUSE version output on --version to
be consistent with other FUSE-based s390-tools.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-17 14:23:47 +02:00
Peter Oberparleiter
68b46eea7a zipl: Add missing build dependency
Building zipl from outside the zipl/ sub-directory fails due to a
missing dependency:

  # cd s390-tools
  # make -C zipl/src/ zipl
  boot.c:18:10: fatal error: ../boot/data.h: No such file or directory
   #include "../boot/data.h"

This is because boot/data.h needs to be generated before src/boot.c can
be compiled. Fix this by adding the missing dependency to the zipl
Makefile.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Ingo Franzki
9894e391ef zkey: Man page correction
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
5982fd98bf CHANGELOG: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
d5291eed1c lstape: fix SCSI HBA CCW device bus-ID e.g. for virtio-scsi-ccw
Get the SCSI HBA device bus-ID in general for HBAs on the CCW bus.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
34260f1736 lstape: fix SCSI output description in man page
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
b9b3d2d230 lstape: fix description of --type and <devbusid> filter for channel tapes
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
4cf8f5f46c lstape: fix to prevent error messages if there are non-zfcp SCSI devices
Assume "N/A" for non-zfcp SCSI devices, such as iSCSI or virtio-scsi-ccw,
to not erroneously access absent zfcp-specific sysfs attributes.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
eba744a25e lsluns: fix to prevent error messages if there are non-zfcp SCSI devices
Simply skip non-zfcp SCSI devices, such as iSCSI or virtio-scsi-ccw,
to not erroneously access absent zfcp-specific sysfs attributes.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
80e0c41b89 lstape: fix output without SCSI generic (sg)
The default bash setting have nullglob disabled so if
$SCSI_DEV/scsi_generic*
aka
/sys/bus/scsi/devices/*:*:*:*/scsi_generic*
does not match anything, it leaves the glob pattern unmodified and
SG_DEV=$(basename $SG_DEV/*)
results in the literal:
*
If $SG_INQ exists, it invoked sg_inq with more than the one allowed
positional argument for a SCSI generic device node:
sg_inq /dev/*
Causing error messages and the usage of sg_inq to land in $TAPE_SERIAL.

To not have to rely on the nullglob setting, explicitly check for the
existence of $SCSI_DEV/scsi_generic before evaluating
SG_DEV=$(basename $SG_DEV/*).

Also handle availability of sg_inq but absence of scsi_generic
individually to provide the user with a hint if only sg is missing.

Suggested-by: Eric Farman <farman@linux.vnet.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Cc: Eric Farman <farman@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
cdc787db1b lstape: fix to prefer sysfs to find lin_tape device name for SCSI device
This should be more stable than parsing the IBM lin_tape proc-fs output.
If sysfs is not available or provides no match, fall back to proc-fs.

An alternative to "ls -1d ... | head -n1" would have been to use
"shopt -s extglob; ls -d $SCSI_DEV/lin_tape/$DEV_NAME+([0-9])"
but I did not want to have to rely on extglob potentially influencing
other old code of lstape.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Steffen Maier
ef4dc7a45b lstape: fix output with SCSI lin_tape and multiple paths to same tape/changer
https://www.ibm.com/developerworks/linux/linux390/s390-tools-1.8.0.html
before the first upstream commit b627b8d8e1 ("Initial s390-tools-2.0.0
import") introduced SCSI tape/changer output for lstape. It used the SCSI
device serial number as lookup key to find a match in IBM lin_tape device
driver proc-fs output for a given SCSI device name. Since multiple paths
to the same tape/changer have the same serial number, multiple matches can
occur and distort the output:

% lstape
...
SCSI tape devices (found 12):
...
Generic Device        Target       Vendor   Model            Type     State
sg0     IBMtape0      3            0:0:0:0  IBM              ULT3580-TD6 tapedrv
running
sg1     IBMchanger0   1            2        3                0:0:0:1  IBM
3573-TL changer       running
...

There are unexpected additional Device suffix numbers for each additional
path of the same tape/changer (independent of actual path failover
enablement in lin_tape). The multiple matches above cause excess arguments
to printf. Explaining the resulting output, the bash man page says:
"The format is reused as necessary to consume all of the arguments."
This also causes a wrong number of found devices.

Current lin_tape (v3.0.31) uses the printf format string
"%-8d%-12s%-25s%-16s%-16s%-10s" for fixed column proc-fs output.
This causes the following example input to lstape:

==> /proc/scsi/IBMchanger <==
lin_tape version: 3.0.31
lin_tape major number: 251
Attached Changer Devices:
Number  model       SN                       HBA             SCSI            FO Path
0       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 0:0:0:1         Primary
1       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 0:0:1:1         Alternate
2       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 1:0:1:1         Alternate
3       3573-TL     00L4U78W6497_LL0         Virtio SCSI HBA 1:0:0:1         Alternate

==> /proc/scsi/IBMtape <==
lin_tape version: 3.0.31
lin_tape major number: 251
Attached Tape Devices:
Number  model       SN                       HBA             SCSI            FO Path
0       ULT3580-TD6 10WT037733               Virtio SCSI HBA 0:0:0:0         Primary
1       ULT3580-TD6 10WT037701               Virtio SCSI HBA 0:0:1:0         Primary
2       ULT3580-TD6 10WT037701               Virtio SCSI HBA 1:0:1:0         Alternate
3       ULT3580-TD6 10WT037733               Virtio SCSI HBA 1:0:0:0         Alternate

If that was reliable and stable, we could use fixed column parsing:
			IBM_IDX=$(
				awk 'BEGIN {
					FIELDWIDTHS="8 12 25 16 16 10"
				}
				gensub(" ","","g",$5) == "'$SCSI_ID'"{
					print gensub(" ","","g",$1)
				}' /proc/scsi/$DEV_NAME
			)
However, we can hardly guarantee a field value always fits into the left-
adjusted columns (printf won't cap to field width!). Also, the fixed column
format changed between lin_tape v3.0.20 and v3.0.18 from
"%-8d%-12s%-18s%-16s%-16s%-10s" with less width for the 'SN' field.
The column format also changed between v2.2.0 and v1.37.0 from
"%-8d%-12s%-18s%-32s%-10s" where the 'SCSI' field did not even exist.
Likely that was the reason for the original Serial lookup in lstape.

As can be seen in the example, at least the HBA device driver string can
contain whitespace and breaks the field numbers with tokenized parsing.
We want to match column 5 (SCSI) but above we would match against the
string 'SCSI' as part of "Virtio SCSI HBA" instead of e.g. '0:0:0:0'.

The following works currently knowing that the last two columns do not
contain white space. But it can also fail if the value of field
'HBA' does not fit into the left-adjusted columns so there is no white
space between columns 'HBA' and 'SCSI' making them collapse:
awk '$(NF-1) == "'$SCSI_ID'" { print $1 }' /proc/scsi/$DEV_NAME

Grep for the SCSI device name as word (to skip names with same substring,
such as 0:0:1:1 also matching 0:0:1:10) and cut the first field 'Number'.
If there is no SCSI column at all (and no SCSI LLDD or other column with a
name accidentally matching an existing SCSI device name), we get no match
and better bail out with the initialized "N/A" for the lstape column
"Device". If the SCSI column exists, the SCSI device names are unique and
we always get at most one match.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
cb3e949772 zfcpdump: Fix incompatible cast compile warning
When zfcpdump is built you get a compile warning

zfcpdump.c: In function ‘init_sig’:
zfcpdump.c:307:24: warning: cast between incompatible function types from ‘void (* (*)(int,  siginfo_t *, void *))(int)’ {aka ‘void (* (*)(int,  struct <anonymous> *, void *))(int)’} to ‘void (*)(int)’ [-Wcast-function-type]
  g.sigact.sa_handler = (__sighandler_t)dump_sig_handler;

Furthermore the man pages for sigaction says

$man 2 sigaction
[...]
       If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead
       of sa_handler) specifies the signal-handling function for signum.
       This function receives three arguments, as described below.
[...]

Because SA_SIGINFO is set, using sa_handler at all is wrong in this case.

Fix this by giving dump_sig_handler the correct return type and assign it
to sa_sigaction.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
f02de298c1 zfcpdump: Remove module load
The zfcpdump kernel is built without module support. Furthermore the initrd
doesn't contain modprobe. So trying to load modules using modprobe in
zfcpdump userspace doesn't really make sense.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
eb0dc13c88 zfcpdump: Add install script for zfcpdump
Since version 198 (Feb 2013) systemd contains kernel-install, a script
managing kernel installs. This script allows execution of drop-in scripts
for customization. Add such a drop-in script to s390-tools to handle the
installation of zfcpdump kernels.

It's main purpose is to manage a link to the latest installed zfcpudump
kernel at ZFCPDUMP_IMAGE, where zipl expects to find the image to install
for a SCSI dumper.

The script supports two installation modes. One recommended by the
BootLoaderSpecs [1] to /boot/<machine-id>/<kernel-version> directories and
one directly to /boot. In the second case files are renamed during
installation to <original-name>-<kernel-version> to guarantee unique names.

Because the zfcpdump kernel is so special make the script stand-alone and
prevent any other script from being executed (exit 77) when a zfcpdump is
installed. Especially avoid functionality like creating an initrd (already
provided by s390-tools) or creating a boot entry (the zfcpdump kernel
should not be used for any other purpose than dumping).

The script requires systemd >= 203.

[1] https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
d08bd23c1e zipl: Move macro definition to Makefile
In the zipl Makefile macros are defined with the sole purpose to define
other macros in zipl.h. Remove this unnecessary indirection.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
724f1fea2c Makefile: Rename ZFCPDUMP_PART_* macros
The file system dumper no longer exists. So there is no need in keeping
'PART' to distinguish between the file system and the partition dumper.
Adjust the macro name to the usage in zipl by removing 'PART'.

While at it also adjust the file names the macros stand for.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
dcc63e6dfc zipl: Rename FSDUMP_PART_* macros
The macro names are a mixture of the original file system dumper (FSDUMP)
and its extension to cut the file system and write directly to a partition
(PART). The original dumper no longer exists and today the feature is
called zfcpdump. Prevent confusion by renaming the macros to fit todays
usage.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Philipp Rudo
576034e94a zfcpdump: Remove unused macros
There are no more users for these macros. Remove them.

Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Jan Höppner
3ec49ba7bd Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-09-04 14:09:24 +02:00
Jan Höppner
60c687238d New release s390-tools-2.6.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 12:41:17 +02:00
Sebastian Ott
57b992ffa1 lscss: document behavior of subchannels bound to alternate drivers
Provide information on how subchannels bound to vfio_ccw are displayed.

Reported-by: Cornelia Huck <cohuck@redhat.com>
Link: https://github.com/ibm-s390-tools/s390-tools/issues/32
Fixes: #32
Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 12:41:17 +02:00
Ingo Franzki
1f07a41d5a zkey: Add volume-type property to support LUKS2 volumes
Allow to specify a volume-type for a key. This applies to all
associated volumes. The volume type can be either 'plain' or
'luks2'. New keys created will default to 'luks2', but existing
keys that do not have a volume-type property default to 'plain'
for compatibility reasons.

The volume type 'luks2' is only available when the define
HAVE_LUKS2_SUPPORT is set in the makefile. This is set only
when libcryptsetup version 2.0.3 or newer is available
at build time. If the define is not set, the volume-type
option is not available to the user, and the volume-type of
a key defaults to 'plain'.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 12:41:12 +02:00
Ingo Franzki
512b47c004 zkey: Add key verification pattern property
Store a verification pattern in the properties file along
with the secure key. The verification pattern allows to identify
the inner key even when the secure key is no longer valid.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Ingo Franzki
818ffbc4b0 zkey: Add build dependency for libcryptsetup and json-c
The zkey-cryptsetup tool has a build dependency to
libcryptsetup version 2.0.3 or later, and json-c.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Ingo Franzki
5e65df7375 zkey: Add man page for zkey-cryptsetup
Add documentation for the new zkey-cryptsetup tool

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Ingo Franzki
4eb80d14a0 zkey: Add zkey-cryptsetup tool
The zkey-cryptsetup tool is used to validate and re-encipher
secure AES volume keys of volumes encrypted with LUKS2 and
the paes cipher.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Viktor Mihajlovski
7247a61e0b netboot: add BOOTIF support
The IPAPPEND option in the pxelinux config file can be used
to pass information about the boot interface to the booted
Linux kernel.

The support for this option was missing and could lead to
installation failures, e.g. using kickstart.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Viktor Mihajlovski
c856f28e11 netboot: Send client architecture and handle path prefix
Client architecture aware DHCP configurations may send a
bootfile for the wrong architecture, if the DHCP request
doesn't include the client architecture identifier 0x001f.

Further, the DHCP reply may include the pxepathprefix option,
which points to the base directory to use for TFT requests.
If the value is not honored by the client, the wrong
configuration file, kernel, etc. could be loaded.

Both issues are fixed by this commit.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Viktor Mihajlovski
ca30cfd341 netboot: Include compressed kernel modules in initramfs
Compressed kernel modules (filename *.ko.xz) would not be included
since the script was looking for files with .ko suffix only.

This can result in a pxelinux.0 image that can't access the
network, which is not good for a network boot loader...

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-08-10 10:42:18 +02:00
Gerald Schaefer
58ecf1f363 mon_procd: fix parsing of /proc/<pid>/stat
The output of /proc/<pid>/stat will show the process name in parentheses.
The parsing code in read_stat() tries to filter out the parentheses, which
will go wrong when the process name itself also contains parentheses, e.g.
in an output like this: "2421 ((sd-pam)) S 2420 2420 2420 ..."

In this case, the first closing parentheses will be taken as end marker,
and the sscanf() on the remaining string will silently fail, leaving its
values in uninitialized state and producing wrong data.

Fix this by using strrchr() instead of strchr() to find the last closing
parentheses. Also add return value checking for sscanf() and initialize the
values to 0.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-07-04 13:10:20 +02:00
Sa Liu
d36ff82999 dbginfo: Add VM command query time. Corrected error messages.
Signed-off-by: Sa Liu <saliu@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-07-04 13:09:58 +02:00
Dimitri John Ledkov
d4398aea89 zdev: Adjust zdev modprobe path to be compatible with split-usr systems.
mk-pxelinux-ramfs, mod_fsstatd|procd.service, zfcpdump all use
/sbin/modprobe path. Adjust zdev to use that path as well. This works
universally on both usr-merge systems (e.g. Debian/Ubuntu with
usrmerge package installed), and split-usr systems alike
(Debian/Ubuntu current stable releases default).

Closes: #31
Link: https://bugs.launchpad.net/ubuntu/+source/s390-tools/+bug/1777600
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-06-22 17:25:06 +02:00
Ingo Franzki
672548ce30 zkey: Fix generate and import leaving key in an inconsistent state
When a volume or APQN association is made while generating or
importing a key, and a duplicate association is detected, then
this may leave the key in an inconsistent state.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-06-22 17:25:06 +02:00
Ingo Franzki
344965bd29 zkey: Fix APQN validation routine
When a zkey generate or change command is used to associate one
or multiple APQNs the command succeeds, but no key is generated
and no APQNs are associated, because the return code returned by
_keystore_apqn_check() is wrong.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-06-22 17:25:06 +02:00
Ingo Franzki
d6a96f07c1 zkey: Fix memory leak
The APQN check routine as well as the properties helper functions
do not free all memory that they allocated.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-06-22 17:25:06 +02:00
Jan Höppner
6a99d95d4f Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2018-06-22 17:25:06 +02:00
71 changed files with 6147 additions and 521 deletions

9
.gitignore vendored
View File

@@ -68,6 +68,7 @@ zconf/qeth/lsqeth
zconf/scm/lsscm
zconf/zcrypt/chzcrypt
zconf/zcrypt/lszcrypt
zconf/zcrypt/zcryptctl
zdev/src/chzdev
zdev/src/chzdev_usage.c
zdev/src/lszdev
@@ -76,7 +77,8 @@ zdsfs/zdsfs
zdump/zgetdump
zfcpdump/cpioinit
zfcpdump/zfcpdump_part
zfcpdump/zfcpdump_part.rd
zfcpdump/zfcpdump-initrd
zfcpdump/10-zfcpdump.install
ziomon/ziomon_mgr
ziomon/ziomon_util
ziomon/ziomon_zfcpdd
@@ -89,3 +91,8 @@ zipl/src/chreipl_helper.device-mapper
zipl/src/zipl
zipl/src/zipl_helper.device-mapper
zkey/zkey
zkey/zkey-cryptsetup
zkey/check-dep-zkey
zkey/check-dep-zkey-cryptsetup
zkey/detect-libcryptsetup.dep
zpcictl/zpcictl

View File

@@ -16,8 +16,10 @@ List of all individuals having contributed content to s390-tools
- Clemens von Mann
- Dan Horak
- Despina Papadopoulou
- Dimitri John Ledkov
- Eberhard Pasch
- Einar Lueck
- Eric Sandeen
- Erwin Vicari
- Eugene Crosser
- Eugene Dvurechenski

View File

@@ -1,5 +1,44 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.7.0 (2018-10-31)__
For Linux kernel version: 4.19
Add new tool:
- zcryptctl: Add zcryptctl for multiple zcrypt node management
- zpcictl: Add zpcictl for reporting defective PCI devices
Changes of existing tools:
- qethqoat: Add OSA-Express7S support
- lszcrypt: Add support for alternative zcrypt device drivers
- zfcpdump: Add install script for zfcpdump
- zipl: Make zipl work with XFS by using the FIEMAP mapping ioctl
Bug Fixes:
- lstape: Fix output with SCSI lin_tape and multiple paths to same unit
- lstape: Fix output without SCSI generic (sg)
- lsluns: Fix to prevent error messages if there are non-zfcp SCSI devices
- lstape: Fix to prevent error messages if there are non-zfcp SCSI devices
- lstape: Fix description of --type and <devbusid> filter for channel tapes
- lstape: Fix SCSI output description in man page
- lstape: Fix SCSI HBA CCW device bus-ID e.g. for virtio-scsi-ccw
- Direct --help and --version output to stdout for several tools
- osasnmpd: Start without real OSA devices
* __v2.6.0 (2018-08-10)__
For Linux kernel version: 4.18
Add new tool:
- zkey: Add zkey-cryptsetup tool
Changes of existing tools:
- netboot: add BOOTIF support
Bug Fixes:
- mon_procd: fix parsing of /proc/<pid>/stat
- netboot: Include compressed kernel modules in initramfs
- netboot: Send client architecture and handle path prefix
* __v2.5.0 (2018-06-08)__
For Linux kernel version: 4.17

View File

@@ -8,7 +8,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
all: $(TOOL_DIRS)

View File

@@ -265,6 +265,8 @@ build options:
| net-snmp | `HAVE_SNMP` | osasnmpd |
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
| openssl | `HAVE_OPENSSL` | zkey |
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup |
This table lists additional build or install options:
@@ -371,9 +373,12 @@ the different tools are provided:
* zkey:
For building the zkey tools you need openssl version 0.9.7 or newer installed
(openssl-devel.rpm). Tip: you may skip the zkey build by adding
`HAVE_OPENSSL=0` to the make invocation.
(openssl-devel.rpm). Also required are cryptsetup version 2.0.3 or newer
(cryptsetup-devel.rpm), and json-c version 0.12 or newer (json-c-devel.rpm).
Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0`, and you may
may skip the zkey-cryptsetup build by adding `HAVE_CRYPTSETUP2=0`, or
`HAVE_JSONC=0` to the make invocation.
A new group 'zkeyadm' needs to be created and all users intending to use the
tool must be added to this group. The owner of the default key repository
tool must be added to this group. The owner of the default key repository
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
for this group.
for this group.

View File

@@ -76,7 +76,7 @@ static const struct fuse_opt cmsfs_opts[] = {
static void usage(const char *progname)
{
fprintf(stderr,
fprintf(stdout,
"Usage: %s DEVICE MOUNTPOINT [OPTIONS]\n"
"\n"
"Use the cmsfs-fuse command to read and write files stored on a z/VM CMS disk.\n"
@@ -4498,14 +4498,23 @@ static int cmsfs_process_args(void *data, const char *arg, int key,
return 1;
case KEY_HELP:
usage(outargs->argv[0]);
/*
* Usage output needs to go to stdout to be consistent with
* coding guidelines. FUSE versions before 3.0.0 print help
* output to stderr. Redirect stderr to stdout here to enforce
* consistent behavior.
*/
fflush(stderr);
dup2(STDOUT_FILENO, STDERR_FILENO);
fuse_opt_add_arg(outargs, "-ho");
cmsfs_fuse_main(outargs, &cmsfs_oper);
exit(0);
case KEY_VERSION:
fprintf(stderr, COMP "FUSE file system for CMS disks "
fprintf(stdout, COMP "FUSE file system for CMS disks "
"program version %s\n", RELEASE_STRING);
fprintf(stderr, "Copyright IBM Corp. 2010, 2017\n");
fuse_opt_add_arg(outargs, "--version");
fprintf(stdout, "Copyright IBM Corp. 2010, 2017\n");
exit(0);
default:

View File

@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION = 2
RELEASE = 5
RELEASE = 7
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -182,9 +182,10 @@ GROUP = $(shell id -gn)
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
# Special defines for zfcpdump
ZFCPDUMP_PART_IMAGE = zfcpdump_part.image
ZFCPDUMP_PART_RD = zfcpdump_part.rd
export ZFCPDUMP_DIR ZFCPDUMP_PART_IMAGE ZFCPDUMP_PART_RD
ZFCPDUMP_IMAGE = zfcpdump-image
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)
@@ -239,7 +240,7 @@ endif
$(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
%: %.o
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
%.a:
$(AR) rcs $@ $^

View File

@@ -7,7 +7,7 @@ LDLIBS += -lm
OBJECTS = daemon.o cpu.o info.o terms.o config.o main.o getopt.o mem.o
cpuplugd: $(OBJECTS)
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
clean:
rm -f cpuplugd $(OBJECTS)

View File

@@ -1338,7 +1338,7 @@ static int hmcdrv_fuse_main(struct fuse_args *args)
*/
static void hmcdrv_fuse_usage(const char *progname)
{
fprintf(stderr,
fprintf(stdout,
"Usage: %s MOUNTPOINT [OPTIONS]\n\n"
"Use the %s command to read files from a HMC drive DVD.\n"
"\n"
@@ -1450,7 +1450,7 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
return 1;
case HMCDRV_FUSE_OPTKEY_VERSION:
fprintf(stderr, HMCDRV_FUSE_LOGHEAD
fprintf(stdout, HMCDRV_FUSE_LOGHEAD
"HMC drive DVD file system, version %s\n"
"Copyright IBM Corp. 2015, 2017\n",
HMCDRV_FUSE_RELEASE);
@@ -1458,6 +1458,16 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
case HMCDRV_FUSE_OPTKEY_HELP:
hmcdrv_fuse_usage(outargs->argv[0]);
/*
* Usage output needs to go to stdout to be consistent with
* coding guidelines. FUSE versions before 3.0.0 print help
* output to stderr. Redirect stderr to stdout here to enforce
* consistent behavior.
*/
fflush(stderr);
dup2(STDOUT_FILENO, STDERR_FILENO);
fuse_opt_add_arg(outargs, "-ho");
hmcdrv_fuse_main(outargs);
exit(EXIT_SUCCESS);

View File

@@ -42,6 +42,9 @@ static inline void util_ptr_vec_free(void **ptr_vec, int count)
{
int i;
if (!ptr_vec || count < 0)
return;
for (i = 0; i < count; i++)
free(ptr_vec[i]);
free(ptr_vec);

View File

@@ -6,7 +6,7 @@ objects = main.o ccw.o fcp.o system.o shutdown.o \
cmd_lsshut.o cmd_chshut.o cmd_lsreipl.o cmd_chreipl.o proc.o
chreipl: $(objects)
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
lsreipl:
ln -sf chreipl lsreipl

View File

@@ -75,9 +75,11 @@ static const struct tool_info iucv_tool[2] = {
static void __noreturn usage_exit(const struct tool_info *prg, int is_error,
const char *msg)
{
FILE *file = is_error ? stderr : stdout;
if (msg != NULL)
fprintf(stderr, _("%s: %s\n"), prg->name, msg);
fprintf(stderr, _(prg->usage), prg->name, prg->name);
fprintf(file, _("%s: %s\n"), prg->name, msg);
fprintf(file, _(prg->usage), prg->name, prg->name);
exit(is_error ? 1 : 0); /* rc=1 .. invalid args */
}

View File

@@ -90,7 +90,7 @@ static void test_util_path_is_xxx(void)
}
/*
* Usage: util_path_example [sysfs mount point] | "is_xxx"
* Usage: util_path_example sysfs [MOUNT_POINT] | is_xxx
*/
int main(int argc, char *argv[])
{
@@ -111,6 +111,6 @@ int main(int argc, char *argv[])
}
return EXIT_SUCCESS;
out_fail:
errx(EXIT_FAILURE, "Usage: %s sysfs <path> | is_xxx", argv[0]);
errx(EXIT_FAILURE, "Usage: %s sysfs [MOUNT_POINT] | is_xxx", argv[0]);
}
//! [code]

View File

@@ -34,6 +34,12 @@ const struct util_prg prg = {
}
};
static const struct option opt_list[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ NULL, no_argument, NULL, 0 },
};
/*
* Demonstrate the util_prg_print() functions
*/
@@ -49,7 +55,7 @@ int main(int argc, char *argv[])
util_prg_init(&prg);
while ((opt = getopt(argc, argv, "vhe")) != -1) {
while ((opt = getopt_long(argc, argv, "vhe", opt_list, NULL)) != -1) {
switch (opt) {
case 'v':
util_prg_print_version();

View File

@@ -442,9 +442,9 @@ util_proc_dev_get_entry(dev_t device, int blockdev,
/*
* Provide one record form a /proc/mounts like file
* Provide one record from a /proc/mounts like file
*
* The parameter file_name distinguishes the file form procfs which
* The parameter file_name distinguishes the file from procfs which
* is read, the parameter spec is the selector for the record.
*/
int util_proc_mnt_get_entry(const char *file_name, const char *spec,
@@ -456,7 +456,6 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
rc = get_file_buffer(&file, file_name);
if (rc)
return rc;
rc = -1;
while (!eof(&file)) {
rc = scan_mnt_entry(&file, entry);
if (rc)
@@ -467,6 +466,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
}
util_proc_mnt_free_entry(entry);
}
rc = -1;
out_free:
free_file_buffer(&file);
return rc;

View File

@@ -59,6 +59,7 @@ static int __scandir(struct dirent ***de_vec, const char *path,
int count = 0;
DIR *dirp;
*de_vec = NULL;
dirp = opendir(path);
if (!dirp)
return -1;
@@ -134,13 +135,13 @@ int util_scandir_hexsort(const struct dirent **de1, const struct dirent **de2)
* directory entries. The entries as well as the pointer array itself are
* allocated by the function and has to be released by the user via free.
*
* @param[out] de_vec Vector of matched directory entries
* @param[out] de_vec Vector of matched directory entries, or NULL
* @param[in] compar_fn Callback function for sorting the entry list
* @param[in] path Path to the directory to scan
* @param[in] fmt Format string, describes the search pattern as POSIX regex
* @param[in] ... Values for format string
*
* @returns Number of returned directory entries
* @returns Number of returned directory entries, or -1 on error
*/
int util_scandir(struct dirent ***de_vec,
int compar_fn(const struct dirent **first,

View File

@@ -594,17 +594,18 @@ static void cal_task_pcpu(struct task_t *task, const unsigned long long tics)
*/
static int read_stat(struct task_t *task)
{
int ppid, tty, proc;
unsigned long flags, pri, nice;
unsigned long long maj_flt, utime, stime, cutime, cstime;
unsigned long long maj_flt = 0, utime = 0, stime = 0, cutime = 0,
cstime = 0;
unsigned long flags = 0, pri = 0, nice = 0;
char *cmd_start, *cmd_end, *cmdlenp, *cmdp;
int ppid = 0, tty = 0, proc = 0, rc;
snprintf(fname, sizeof(fname), "/proc/%u/stat", task->pid);
if (read_file(fname, buf, sizeof(buf) - 1) == -1)
return 0;
cmd_start = strchr(buf, '(') + 1;
cmd_end = strchr(cmd_start, ')');
cmd_end = strrchr(cmd_start, ')');
name_lens.cmd_len = cmd_end - cmd_start;
cmdlenp = mon_record + sizeof(struct monwrite_hdr);
cmdlenp += sizeof(struct procd_hdr);
@@ -625,7 +626,7 @@ static int read_stat(struct task_t *task)
memcpy(cmdlenp, &name_lens.cmd_len, sizeof(__u16));
cmd_end += 2;
sscanf(cmd_end,
rc = sscanf(cmd_end,
"%c %d %*d %*d %d %*d "
"%lu %*s %*s %Lu %*s "
"%Lu %Lu %Lu %Lu "
@@ -642,6 +643,8 @@ static int read_stat(struct task_t *task)
&utime, &stime, &cutime, &cstime,
&pri, &nice,
&proc);
if (rc != 12)
syslog(LOG_ERR, "bad data in %s \n", fname);
task->ppid = (__u32)ppid;
task->tty = (__u16)tty;
task->flags = (__u32)flags;

View File

@@ -134,8 +134,8 @@ echo "$cmd: Copying virtio modules"
mkdir -p $builddir/$netdir
mkdir -p $builddir/$blkdir
set +e
cp $netdir/virtio_net.ko $builddir/$netdir 2> /dev/null
cp $blkdir/virtio_blk.ko $builddir/$blkdir 2> /dev/null
cp $netdir/virtio_net.ko* $builddir/$netdir 2> /dev/null
cp $blkdir/virtio_blk.ko* $builddir/$blkdir 2> /dev/null
set -e
# Busybox (+ dependencies)
@@ -170,7 +170,7 @@ cat <<'EOF' > $builddir/init
/bin/mount -t tmpfs none /run
/sbin/modprobe virtio_net
/sbin/udhcpc -O pxeconffile -O pxepathprefix &
/sbin/udhcpc -O pxeconffile -O pxepathprefix -x 93:001F &
/sbin/pxeboot.script
EOF
@@ -237,6 +237,7 @@ case "$1" in
echo " router: $router"
echo " domain: $domain $dns"
echo " tftp: $siaddr"
echo " pxepathprefix: $pxepathprefix"
# flush routes
/sbin/ip route flush table all
# setup if link
@@ -272,6 +273,7 @@ case "$1" in
echo "siaddr=$siaddr" > $PXECONF
echo "interface=$interface" >> $PXECONF
echo "ip=$ip" >> $PXECONF
echo "pxepathprefix=$pxepathprefix" >> $PXECONF
fi
;;
@@ -354,7 +356,7 @@ then
for c in $CONFIGS
do
echo "fetching config pxelinux.cfg/$c from $siaddr"
if /usr/bin/tftp -g -l /tmp/config -r pxelinux.cfg/$c $siaddr
if /usr/bin/tftp -g -l /tmp/config -r ${pxepathprefix}pxelinux.cfg/$c $siaddr
then
break
fi
@@ -371,6 +373,7 @@ fi
kernel=$(/bin/grep -i "^[[:space:]]*kernel" /tmp/config | sed "s/^[[:space:]]*kernel[[:space:]]*//I")
initrd=$(/bin/grep -i "^[[:space:]]*initrd" /tmp/config | sed "s/^[[:space:]]*initrd[[:space:]]*//I")
append=$(/bin/grep -i "^[[:space:]]*append" /tmp/config | sed "s/^[[:space:]]*append[[:space:]]*//I")
ipappend=$(/bin/grep -i "^[[:space:]]*ipappend" /tmp/config | sed "s/^[[:space:]]*ipappend[[:space:]]*//I")
if [ -z "$kernel" ]
then
@@ -378,13 +381,13 @@ then
exit
else
echo fetch kernel $kernel from $siaddr
/usr/bin/tftp -g -l /tmp/kernel -r $kernel $siaddr
/usr/bin/tftp -g -l /tmp/kernel -r $pxepathprefix$kernel $siaddr
fi
if [ -n "$initrd" ]
then
echo fetch initrd $initrd from $siaddr
/usr/bin/tftp -g -l /tmp/initrd -r $initrd $siaddr
/usr/bin/tftp -g -l /tmp/initrd -r $pxepathprefix$initrd $siaddr
INITRD="--initrd=/tmp/initrd"
else
INITRD=""
@@ -394,6 +397,9 @@ if [ -z "$append" ]; then
echo "Kexec load: kexec -l /tmp/kernel $INITRD"
kexec -l /tmp/kernel $INITRD
else
if [ "$ipappend" = "2" ]; then
$append="$append BOOTIF=01-$ifaddr"
fi
echo "Kexec load: kexec -l /tmp/kernel $INITRD --append=\"$append\""
kexec -l /tmp/kernel $INITRD --append="$append"
fi

View File

@@ -85,20 +85,12 @@ void init_ibmOSAMib(void) {
/* query OSA-E device driver for OSA-E devices and mark them in IF-MIB interface list */
osaexp_num = query_OSA_EXP ( &if_list, ifNumber );
if ( osaexp_num < 0 )
if ( osaexp_num == 0 )
{
fprintf( stderr, "init_ibmOSAMib(): "
"OSA-E device driver query interface ioctl() failed\n"
"check agent log file for more details\n"
"Cannot start subagent...exiting...\n");
exit(1);
}
else if ( osaexp_num == 0 )
{
fprintf( stderr, "init_ibmOSAMib(): bad or no OSA-E devices reported\n"
"check agent log file for more details\n"
"Cannot start subagent...exiting...\n");
exit(1);
get_time( time_buf );
snmp_log( LOG_ERR, "%s init_ibmOSAMib(): none of the %d interfaces is a real "
"OSA-E device - starting subagent anyway\n", time_buf, ifNumber);
return;
}
/* end if */

View File

@@ -1204,18 +1204,7 @@ void update_mib_info ()
* and mark them in IF-MIB interface list
* */
osaexp_num = query_OSA_EXP( &tmp_list, if_num );
if ( osaexp_num < 0 )
{
get_time( time_buf );
fprintf( stderr, "%s update_mib_info(): "
"OSA-E device driver query interface ioctl() "
"failed\nupdate_mib_info(): going to stop osasnmpd daemon\n"
"update_mib_info(): check subagent logfile for more details\n"
"update_mib_info(): sending termination signal to osasnmpd...\n",
time_buf );
exit(-1);
}
else if ( osaexp_num == 0 )
if ( osaexp_num == 0 )
{
get_time( time_buf );
snmp_log( LOG_ERR, "%s update_mib_info(): "
@@ -1698,9 +1687,8 @@ int query_IF_MIB ( IF_LIST** ifList )
* IN int if_Number: number of network interfaces
* returns: int num - number of OSA Express devices found on this
* system (>=0)
* -1 -an error occurred , no valid info avail
*********************************************************************/
int query_OSA_EXP ( IF_LIST** ifList, int if_Number )
unsigned int query_OSA_EXP ( IF_LIST** ifList, int if_Number )
{
int j, num = 0;
char time_buf[TIME_BUF_SIZE]; /* date/time buffer */

View File

@@ -91,7 +91,7 @@ void update_mib_info ( );
int query_IF_MIB( IF_LIST** );
/* retrieves OSA Express interface information from kernel */
int query_OSA_EXP ( IF_LIST** ,int );
unsigned int query_OSA_EXP ( IF_LIST** ,int );
/* get time of day */
int get_time( char* );

View File

@@ -208,6 +208,9 @@ static void print_physical(struct qeth_qoat_physical *phdr)
case OAT_OSA_GEN_OSAE6S:
osagen = "OSA-Express6S";
break;
case OAT_OSA_GEN_OSAE7S:
osagen = "OSA-Express7S";
break;
default:
sprintf(tmp, "unknown (0x%x)", phdr->osa_gen);
osagen = tmp;
@@ -239,6 +242,9 @@ static void print_physical(struct qeth_qoat_physical *phdr)
case OAT_PORT_SPEED_10gbs_full:
speed = "10 Gb/s / full duplex";
break;
case OAT_PORT_SPEED_25gbs_full:
speed = "25 Gb/s / full duplex";
break;
case OAT_PORT_SPEED_UNKNOWN:
speed = "unknown / unknown";
break;

View File

@@ -58,6 +58,7 @@ struct qeth_qoat_physical {
#define OAT_OSA_GEN_OSAE4S 0x02
#define OAT_OSA_GEN_OSAE5S 0x03
#define OAT_OSA_GEN_OSAE6S 0x04
#define OAT_OSA_GEN_OSAE7S 0x05
__u8 osa_gen;
#define OAT_PORT_SPEED_UNKNOWN 0x00
#define OAT_PORT_SPEED_10mbs_half 0x01
@@ -68,6 +69,7 @@ struct qeth_qoat_physical {
#define OAT_PORT_SPEED_1000mbs_full 0x06
#define OAT_PORT_SPEED_NA 0x07
#define OAT_PORT_SPEED_10gbs_full 0x08
#define OAT_PORT_SPEED_25gbs_full 0x0A
__u8 port_speed;
#define OAT_PORT_MEDIA_COPPER 0x01
#define OAT_PORT_MEDIA_MULTI_MODE 0x02

View File

@@ -2,7 +2,7 @@
#
# dbginfo.sh - Tool to collect runtime, configuration, and trace information
#
# Copyright IBM Corp. 2002, 2017
# Copyright IBM Corp. 2002, 2018
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
@@ -21,7 +21,7 @@ readonly SCRIPTNAME="${0##*/}"
print_version() {
cat <<EOF
${SCRIPTNAME}: Debug information script version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2002, 2017
Copyright IBM Corp. 2002, 2018
EOF
}
@@ -480,6 +480,7 @@ VM_CMDS="q userid\
:q cpus\
:q srm\
:q vtod\
:q time full\
:q timezone\
:q loaddev\
:q v osa\
@@ -1016,25 +1017,31 @@ environment_setup()
# create gzip-ped tar file
create_package()
{
local rc_tar
pr_stdout "Finalizing: Creating archive with collected data"
cd "${WORKDIR_BASE}"
if ! tar -czf "${WORKARCHIVE}" "${WORKDIR_CURRENT}"; then
pr_stdout " "
pr_stdout "${SCRIPTNAME}: Error: Collection of data failed!"
pr_stdout " The creation of \"${WORKARCHIVE}\" was not successful."
pr_stdout " Please check the directory \"${WORKDIR_BASE}\""
pr_stdout " to provide enough free available space."
tar -czf "${WORKARCHIVE}" "${WORKDIR_CURRENT}"
rc_tar=$?
if [ $rc_tar -eq 0 ]; then
chmod 0600 "${WORKARCHIVE}"
pr_stdout " "
pr_stdout "Collected data was saved to:"
pr_stdout " >> ${WORKARCHIVE} <<"
pr_stdout " "
pr_stdout "Review the collected data before sending to your service organization. "
pr_stdout " "
elif [ $rc_tar -eq 127 ]; then
pr_stdout " "
pr_stdout "${SCRIPTNAME}: Error: tar command is not available!"
pr_stdout " Please install the corresponding package!"
else
chmod 0600 "${WORKARCHIVE}"
pr_stdout " "
pr_stdout "Collected data was saved to:"
pr_stdout " >> ${WORKARCHIVE} <<"
pr_stdout " "
pr_stdout "${SCRIPTNAME}: Error: Collection of data failed!"
pr_stdout " The creation of \"${WORKARCHIVE}\" was not successful."
pr_stdout " Please check the directory \"${WORKDIR_BASE}\""
pr_stdout " to provide enough free available space."
fi
pr_stdout " "
pr_stdout "Review the collected data before sending to your service organization. "
pr_stdout " "
}

View File

@@ -10,6 +10,7 @@
[Unit]
Description=CPACF statistics collection daemon process for Linux on System z
Documentation=man:cpacfstatsd(8)
ConditionVirtualization=no
[Service]
Type=forking

View File

@@ -174,7 +174,7 @@ int main(int argc, char *argv[]) {
) {
switch(c) {
case 'h':
fprintf(stderr, "%s", help_text);
fprintf(stdout, "%s", help_text);
exit(0);
case 'b':
ds.cntrl.blink = 1;

View File

@@ -9,7 +9,7 @@ libs = $(rootdir)/libvmdump/libvmdump.a
objects = vmconvert.o
vmconvert: $(objects) $(libs)
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) $(DESTDIR)$(MANDIR)/man1

View File

@@ -11,7 +11,7 @@ libs = $(rootdir)/libvmdump/libvmdump.a \
objects = vmur.o
vmur: $(objects) $(libs)
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(USRSBINDIR) $(DESTDIR)$(MANDIR)/man8

View File

@@ -111,10 +111,14 @@ In rare situations a device might temporarily not be accessible to
the subchannel. Then "none" is displayed as the device identifier and the
other device attributes are empty.
For subchannels bound to an alternate driver (most notably vfio_ccw) the
device identifier may also be displayed as "none". In this case use the
\fB--vfio\fR option to show VFIO specific subchannel information.
.SH AUTHOR
.nf
This man-page was written by Stefan Bader <shbader@de.ibm.com>.
New options added by Sebastian Ott <sebott@linux.vnet.ibm.com>.
New options added by Sebastian Ott <sebott@linux.ibm.com>.
.SH "SEE ALSO"
.BR chccwdev (8)
.fi

View File

@@ -2,7 +2,7 @@
#
# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
#
# Copyright IBM Corp. 2008, 2017
# Copyright IBM Corp. 2008, 2018
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
@@ -152,6 +152,11 @@ sub get_lun_hash
my %lun_hash;
foreach my $device (</$sg_dir/sg*>) {
# skip non-zfcp SCSI devices and avoid file access error messages
next unless -r "$device/device/fcp_lun";
next unless -r "$device/device/wwpn";
next unless -r "$device/device/hba_id";
my $l = `cat $device/device/fcp_lun`;
my $p = `cat $device/device/wwpn`;
my $a = `cat $device/device/hba_id`;
@@ -170,9 +175,8 @@ sub get_lun_hash
sub lsluns_usage {
print <<EOD;
Usage:
This tool is designed for environments where all SCSI devices are attached
through the zfcp device driver. Expect error messages in mixed environments
such as with iSCSI.
This tool is designed for environments with SCSI devices attached
through the zfcp device driver.
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
@@ -220,7 +224,7 @@ EOD
sub lsluns_version {
print "$PROGRAM_NAME: version %S390_TOOLS_VERSION%\n";
print "Copyright IBM Corp. 2008, 2017\n";
print "Copyright IBM Corp. 2008, 2018\n";
}
sub lsluns_invalid_usage {

View File

@@ -28,9 +28,8 @@ zfcp-attached LUNs
.SH DESCRIPTION
.PP
This tool is designed for environments where all SCSI devices are attached
through the zfcp device driver. Expect error messages in mixed environments
such as with iSCSI.
This tool is designed for environments with SCSI devices attached
through the zfcp device driver.
.B lsluns
lists all logical unit numbers (LUNs) discovered in the

View File

@@ -2,7 +2,7 @@
#
# lstape - Tool to show information about tape devices
#
# Copyright IBM Corp. 2003, 2017
# Copyright IBM Corp. 2003, 2018
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
@@ -48,6 +48,9 @@ function PrintUsage() {
: -v|--version
: Display the version of the tools package and
: the lstape command.
:
:$(basename $0) without the --ccw-only option causes extra SAN traffic
:for each SCSI tape or changer device by invoking the sg_inq command.
EOD
}
@@ -55,7 +58,7 @@ function PrintVersion()
{
cat <<-EOD
$CMD: version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2003, 2017
Copyright IBM Corp. 2003, 2018
EOD
}
@@ -220,6 +223,24 @@ function SysfsCreateListCCW() {
' | sort
}
# handle SCSI device not necessarily zfcp-attached, e.g. virtio-scsi-ccw
function SCSISearchCCWBusid()
{
local SCSI_DEV=$1
local SDEVCAN=$(readlink -e $SCSI_DEV)
while [ -n "$SDEVCAN" ]; do
# ascend to parent: strip last path part
SDEVCAN=${SDEVCAN%/*}
[ -h $SDEVCAN/subsystem ] || continue
local SUBSYSTEM=$(readlink -e $SDEVCAN/subsystem)
if [ "${SUBSYSTEM##*/}" = "ccw" ]; then
echo ${SDEVCAN##*/}
return
fi
done
echo "N/A"
}
function SysfsCreateListSCSI()
{
for SCSI_DEV in $1/bus/scsi/devices/*:*:*:*; do
@@ -249,11 +270,16 @@ function SysfsCreateListSCSI()
if [ -h $SG_DEV ]; then
# deprecated sysfs layout
SG_DEV=$(echo $SG_DEV | awk -F: '{print $NF}')
else
elif [ -d $SCSI_DEV/scsi_generic ]; then
SG_DEV=$(basename $SG_DEV/*)
else
SG_DEV=""
fi
if [ "$SG_INQ" != "" ]; then
if [ -z "$SG_DEV" ]; then
SG_DEV="N/A"
TAPE_SERIAL="NO/SG"
elif [ "$SG_INQ" != "" ]; then
TAPE_SERIAL=$(
sg_inq /dev/$SG_DEV |
awk '/serial/{print $NF}'
@@ -291,17 +317,31 @@ function SysfsCreateListSCSI()
if [ "$CHG_IDX" != "" ]; then
TAPE_DEV=$CHG_IDX
fi
elif [ -r /proc/scsi/$DEV_NAME ]; then
if [ "$TAPE_SERIAL" != "NO/INQ" ]; then
elif [ "$(echo "$SCSI_LIST"|grep lin_tape)" != "" ]; then
# bash glob sorts so IBMtape0 comes before IBMtape0n
local IBM_PATH=$(
ls -1d $SCSI_DEV/lin_tape/$DEV_NAME[0-9]* |
head -n 1)
if [ -d "$IBM_PATH" ]; then
IBM_IDX=${IBM_PATH##*/}
else
# deprecated sysfs layout
IBM_IDX=$(
awk '$3 == "'$TAPE_SERIAL'"{
print $1
}' /proc/scsi/$DEV_NAME
echo "$SCSI_LIST" |
awk -F: '/lin_tape\:'"$DEV_NAME"'[0-9]+$/{print $NF}'
)
fi
if [ "$IBM_IDX" != "" ]; then
TAPE_DEV=$IBM_IDX
fi
elif [ -r /proc/scsi/$DEV_NAME ]; then
IBM_IDX=$(
grep -wF "$SCSI_ID" /proc/scsi/$DEV_NAME |
cut -d ' ' -f 1
)
if [ "$IBM_IDX" != "" ]; then
TAPE_DEV=$DEV_NAME$IBM_IDX
fi
fi
fi
printf "$SCSIFORMAT" \
@@ -313,9 +353,16 @@ function SysfsCreateListSCSI()
$STATE
if $VERBOSE; then
if [ -r $SCSI_DEV/hba_id ]; then
HBA_ID=$(cat $SCSI_DEV/hba_id)
else
HBA_ID=$(SCSISearchCCWBusid $SCSI_DEV)
fi
WWPN="N/A"
[ -r $SCSI_DEV/wwpn ] && WWPN=$(cat $SCSI_DEV/wwpn)
printf "$SCSIVFORMAT" \
$(cat $SCSI_DEV/hba_id) \
$(cat $SCSI_DEV/wwpn) \
"$HBA_ID" \
"$WWPN" \
$TAPE_SERIAL
fi
done

View File

@@ -1,8 +1,8 @@
.\" Copyright 2017 IBM Corp.
.\" Copyright 2017, 2018 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 LSTAPE 8 "Jul 2007" "s390-tools"
.TH LSTAPE 8 "Jun 2018" "s390-tools"
.SH NAME
lstape \- list tape devices.
@@ -20,6 +20,8 @@ lstape \- list tape devices.
.br
.RB [ -t
.IR <device-type> [, <device-type> ] "" ...]
.br
.RI [ <device-bus-ID> ...]
.SH DESCRIPTION
The lstape command lists all available tape devices on the current host. For
@@ -27,19 +29,8 @@ channel attached tape devices this output is the same as the contents of
/proc/tapedevices (which is obsolete) but also includes offline devices. By
default all tape devices are displayed.
Since SCSI tape devices are accessed differently to channel attached tape
devices they are only visible if they are known to the SCSI layer. There
are at least two possible drivers that can claim a SCSI tape device and the
lstape command tries to find out which one this is. For the generic tape
and changer driver the device names start with "st" or "sch", while for the
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
the correct driver could not be obtained.
This happens for example if there is no sg_inq command installed which is
required to read the drive's serial number which in turn is used to find out
the device number of the IBM tape driver.
The serial number of a SCSI tape can be displayed with the --verbose option. If
there is no sg_inq command available "NO/INQ" is shown as the tape's serial.
The lstape command without the --ccw-only option causes extra SAN traffic
for each SCSI tape or changer device by invoking the sg_inq command.
.SH OPTIONS
.TP 8
@@ -75,12 +66,64 @@ on the output of SCSI devices.
.TP
.BR -t | --type " \fI<device-type>\fR"
Limit output to given device types (currently only applies to channel attached
Limit output to given device types, for example 3490
(currently only applies to channel-attached
tape devices).
.TP
\fB<device-type>\fR =
Device type of devices that should be displayed (e.g. 3490).
.I <device-bus-ID>
Limits the output to information about the specified tape device or
devices only. For CCW-attached devices only.
.SH OUTPUT FIELDS FOR SCSI TAPE/CHANGER DEVICES
.TP
.B Generic
SCSI generic device file for the tape drive, for example /dev/sg0.
"N/A" if the SCSI generic (sg) kernel functionality is not available.
.TP
.B Device
Main character device node file for accessing the tape drive or medium changer.
SCSI tape devices are only visible if they are known to the SCSI layer. There
are at least two possible drivers that can claim a SCSI tape device. The
lstape command tries to determine the device driver. For the generic tape
and changer driver the device names start with "st" or "sch", while for the
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
the device driver could not be determined.
.TP
.B Target
Linux SCSI device name in H:C:T:L format.
.TP
.B Vendor
The vendor field from the SCSI device.
.TP
.B Model
The model field from the SCSI device.
.TP
.B Type
"tapedrv" for a tape drive or "changer" for a medium changer.
.TP
.B State
The state of the SCSI device object in the kernel.
Any state other than "running" can indicate problems.
.PP
For SCSI devices, the --verbose option additionally displays:
.TP
.B HBA
The device bus-ID of the FCP device
or of the virtio-scsi-ccw virtual HBA
through which the tape drive is attached.
"N/A" if the device does not have a sysfs ancestor with subsystem ccw.
.TP
.B WWPN
The WWPN (worldwide port name) of the tape drive in the SAN.
"N/A" if device is not attached through zfcp.
.TP
.B Serial
The serial number.
"NO/INQ" if there is no sg_inq command available.
"NO/SG" if no SCSI generic (sg) kernel support is available.
.SH EXAMPLES
\fBlstape\fR
@@ -92,3 +135,8 @@ List all tape devices that are available
.RS
Show all 3490 CCW devices that are online.
.RE
\fBlstape --scsi-only --verbose\fR
.RS
Show all SCSI tape or changer devices with maximum information.
.RE

View File

@@ -1,21 +1,24 @@
include ../../common.mak
all: chzcrypt lszcrypt
all: chzcrypt lszcrypt zcryptctl
libs = $(rootdir)/libutil/libutil.a
chzcrypt: chzcrypt.o misc.o $(libs)
lszcrypt: lszcrypt.o misc.o $(libs)
zcryptctl: zcryptctl.o misc.o $(libs)
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 chzcrypt $(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lszcrypt $(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zcryptctl $(DESTDIR)$(BINDIR)
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 -c chzcrypt.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 -c lszcrypt.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 -c zcryptctl.8 $(DESTDIR)$(MANDIR)/man8
clean:
rm -f *.o chzcrypt lszcrypt
rm -f *.o chzcrypt lszcrypt zcryptctl
.PHONY: all install clean

View File

@@ -54,8 +54,8 @@ status.
.B -V, --verbose
The verbose level for cryptographic device information.
With this verbose level additional information like hardware card type,
hardware queue depth, pending request queue count, outstanding
request queue count, and installed function facilities are displayed.
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

View File

@@ -1,7 +1,7 @@
/**
* lszcrypt - Display zcrypt devices and configuration settings
*
* Copyright IBM Corp. 2008, 2017
* Copyright IBM Corp. 2008, 2018
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -56,6 +56,25 @@ struct lszcrypt_l *lszcrypt_l = &l;
#define MASK_CLASS_STATELESS 0x00400000
#define CLASS_STATELESS "restricted function set"
/*
* facility bits
*/
#define MAX_FAC_BITS 9
static struct fac_bits_s {
int mask;
char c;
} fac_bits[MAX_FAC_BITS] = {
{ 0x80000000, 'S' },
{ 0x40000000, 'M' },
{ 0x20000000, 'C' },
{ 0x10000000, 'D' },
{ 0x08000000, 'A' },
{ 0x04000000, 'X' },
{ 0x02000000, 'N' },
{ 0x00800000, 'F' },
{ 0x00400000, 'R' },
};
/*
* Program configuration
*/
@@ -66,7 +85,7 @@ const struct util_prg prg = {
{
.owner = "IBM Corp.",
.pub_first = 2008,
.pub_last = 2017,
.pub_last = 2018,
},
UTIL_PRG_COPYRIGHT_END
}
@@ -255,7 +274,8 @@ static void show_capability(const char *id_str)
/* Skip devices, which are not supported by zcrypt layer */
if (!util_path_is_readable("%s/type", dev) ||
!util_path_is_readable("%s/online", dev)) {
printf("Detailed capability information for %s (hardware type %ld) is not available.\n", card, hwtype);
printf("Detailed capability information for %s (hardware type %ld) is not available.\n",
card, hwtype);
return;
}
cbuf[0] = '\0';
@@ -299,11 +319,13 @@ static void show_capability(const char *id_str)
} else if (func_val & MASK_EP11) {
printf("%s", CAP_EP11);
} else {
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
printf("Detailed capability information for %s (hardware type %ld) is not available.",
card, hwtype);
}
break;
default:
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
printf("Detailed capability information for %s (hardware type %ld) is not available.",
card, hwtype);
break;
}
printf("\n");
@@ -315,17 +337,22 @@ static void show_capability(const char *id_str)
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
const char *sub_dev)
{
unsigned long facility;
char buf[256];
unsigned long facility;
util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
util_rec_set(rec, "type", buf);
util_file_read_line(buf, sizeof(buf), "%s/%s/online", grp_dev, sub_dev);
if (strcmp(buf, "0") == 0)
util_rec_set(rec, "online", "offline");
if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
util_rec_set(rec, "type", "-");
else
util_rec_set(rec, "online", "online");
util_rec_set(rec, "type", buf);
if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
grp_dev, sub_dev))
util_rec_set(rec, "online", "-");
else
if (strcmp(buf, "0") == 0)
util_rec_set(rec, "online", "offline");
else
util_rec_set(rec, "online", "online");
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
if (facility & MASK_COPRO)
@@ -339,7 +366,7 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
util_file_read_line(buf, sizeof(buf), "%s/%s/request_count",
grp_dev, sub_dev);
util_rec_set(rec, "request_count", buf);
util_rec_set(rec, "requests", buf);
}
/*
@@ -348,20 +375,19 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
const char *sub_dev)
{
int i;
unsigned long facility;
char buf[256];
long depth;
char buf[256], afile[PATH_MAX];
long depth, pending1, pending2;
if (l.verbose == 0)
return;
util_file_read_line(buf, sizeof(buf), "%s/%s/pendingq_count",
grp_dev, sub_dev);
util_rec_set(rec, "pendingq_count", buf);
util_file_read_line(buf, sizeof(buf), "%s/%s/requestq_count",
grp_dev, sub_dev);
util_rec_set(rec, "requestq_count", buf);
util_file_read_l(&pending1, 10, "%s/%s/pendingq_count",
grp_dev, sub_dev);
util_file_read_l(&pending2, 10, "%s/%s/requestq_count",
grp_dev, sub_dev);
util_rec_set(rec, "pending", "%ld", pending1 + pending2);
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
util_rec_set(rec, "hwtype", buf);
@@ -370,7 +396,18 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
util_rec_set(rec, "depth", "%02d", depth + 1);
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
util_rec_set(rec, "facility", "0x%08x", facility);
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);
snprintf(afile, sizeof(afile), "%s/%s/driver", grp_dev, sub_dev);
afile[sizeof(afile) - 1] = '\0';
memset(buf, 0, sizeof(buf));
if (readlink(afile, buf, sizeof(buf)) > 0)
util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
else
util_rec_set(rec, "driver", "-no-driver-");
}
/*
@@ -382,9 +419,13 @@ static void show_subdevice(struct util_rec *rec, const char *grp_dev,
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);
/* Skip devices, which are not supported by zcrypt layer */
if (!util_path_is_readable("%s/type", grp_dev) ||
!util_path_is_readable("%s/%s/online", grp_dev, sub_dev))
/*
* If not verbose mode, skip devices which are not supported
* by the zcrypt layer.
*/
if (l.verbose == 0 &&
(!util_path_is_readable("%s/type", grp_dev) ||
!util_path_is_readable("%s/%s/online", grp_dev, sub_dev)))
return;
util_rec_set(rec, "card", sub_dev);
@@ -414,11 +455,13 @@ static void show_subdevices(struct util_rec *rec, const char *grp_dev)
*/
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
{
unsigned long facility;
char buf[256];
unsigned long facility;
util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
util_rec_set(rec, "type", buf);
if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
util_rec_set(rec, "type", "-");
else
util_rec_set(rec, "type", buf);
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
if (facility & MASK_COPRO)
@@ -430,14 +473,16 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
else
util_rec_set(rec, "mode", "Unknown");
util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev);
if (strcmp(buf, "0") == 0)
util_rec_set(rec, "online", "offline");
if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
util_rec_set(rec, "online", "-");
else
util_rec_set(rec, "online", "online");
if (strcmp(buf, "0") == 0)
util_rec_set(rec, "online", "offline");
else
util_rec_set(rec, "online", "online");
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
util_rec_set(rec, "request_count", buf);
util_rec_set(rec, "requests", buf);
}
/*
@@ -445,18 +490,17 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
*/
static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
{
int i;
unsigned long facility;
char buf[256];
long depth;
char buf[256], afile[PATH_MAX];
long depth, pending1, pending2;
if (l.verbose == 0)
return;
util_file_read_line(buf, sizeof(buf), "%s/pendingq_count", grp_dev);
util_rec_set(rec, "pendingq_count", buf);
util_file_read_line(buf, sizeof(buf), "%s/requestq_count", grp_dev);
util_rec_set(rec, "requestq_count", buf);
util_file_read_l(&pending1, 10, "%s/pendingq_count", grp_dev);
util_file_read_l(&pending2, 10, "%s/requestq_count", grp_dev);
util_rec_set(rec, "pending", "%ld", pending1 + pending2);
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
util_rec_set(rec, "hwtype", buf);
@@ -465,7 +509,18 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
util_rec_set(rec, "depth", "%02d", depth + 1);
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
util_rec_set(rec, "facility", "0x%08x", facility);
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);
snprintf(afile, sizeof(afile), "%s/driver", grp_dev);
afile[sizeof(afile) - 1] = '\0';
memset(buf, 0, sizeof(buf));
if (readlink(afile, buf, sizeof(buf)) > 0)
util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
else
util_rec_set(rec, "driver", "-no-driver-");
}
/*
@@ -481,9 +536,14 @@ static void show_device(struct util_rec *rec, const char *device)
grp_dev = util_path_sysfs("devices/ap/%s", device);
if (!util_path_is_dir(grp_dev))
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
/* Skip devices, which are not supported by zcrypt layer */
if (!util_path_is_readable("%s/type", grp_dev) ||
!util_path_is_readable("%s/online", grp_dev)) {
/*
* If not verbose mode, skip devices which are not supported
* by the zcrypt layer.
*/
if (l.verbose == 0 &&
(!util_path_is_readable("%s/type", grp_dev) ||
!util_path_is_readable("%s/online", grp_dev))) {
goto out_free;
}
util_rec_set(rec, "card", card);
@@ -506,8 +566,7 @@ static void define_rec_default(struct util_rec *rec)
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
util_rec_def(rec, "request_count", UTIL_REC_ALIGN_RIGHT, 11,
"REQUEST_CNT");
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
}
/*
@@ -517,13 +576,11 @@ static void define_rec_verbose(struct util_rec *rec)
{
if (l.verbose == 0)
return;
util_rec_def(rec, "pendingq_count", UTIL_REC_ALIGN_RIGHT, 12,
"PENDINGQ_CNT");
util_rec_def(rec, "requestq_count", UTIL_REC_ALIGN_RIGHT, 12,
"REQUESTQ_CNT");
util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 7, "HW_TYPE");
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 7, "Q_DEPTH");
util_rec_def(rec, "pending", UTIL_REC_ALIGN_RIGHT, 8, "PENDING");
util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 6, "HWTYPE");
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");
}
/*

147
zconf/zcrypt/zcryptctl.8 Normal file
View File

@@ -0,0 +1,147 @@
.\" zcryptctl.8
.\"
.\" Copyright 2018 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.
.\"
.\" use
.\" groff -man -Tutf8 zcryptctl.8
.\" or
.\" nroff -man zcryptctl.8
.\" to process this source
.\"
.TH ZCRYPTCTL 8 "AUG 2018" "s390-tools"
.SH NAME
zcryptctl \- display information and administrate zcrypt multiple device nodes
.SH SYNOPSIS
.TP 8
.B zcryptctl list
.TP
.B zcryptctl create
.R [
.I node-name
.R ]
.TP
.B zcryptctl destroy
.I node-name
.TP
.B zcryptctl addap
.R |
.B delap
.I node-name adapter-nr
.TP
.B zcryptctl adddom
.R |
.B deldom
.I node-name domain-nr
.TP
.B zcryptctl addioctl
.R |
.B delioctl
.I node-name ioctl-term
.TP
.B zcryptctl config
.I config-file
.TP
.B zcryptctl listconfig
.SH DESCRIPTION
The
.B zcryptctl
command displays information and maintains the multi device node
extension for the zcrypt device driver.
.P
With the multi device node extension you can create and configure
additional zcrypt device nodes which can be used as alternate device
nodes to access the crypto hardware provided by the zcrypt device
driver. Each zcrypt device node can be restricted in terms of crypto
cards, domains, and available ioctls. Such a device node can be used
as a base for container solutions like Docker to control and restrict
the access to crypto resources.
.SH COMMANDS
.TP 8
.B zcryptctl list
Show all the additional device nodes that are currently active.
.TP
.B zcryptctl create
.R [
.I node-name
.R ]
Create a new zcrypt device node. The \fInode-name\fP might be given
and needs to be unique and not in use. If there is no node name
provided, the zcrypt device driver will create a new one with pattern
zcrypt_\fIx\fP, with \fIx\fP being the next free number. Up to 256
additional device nodes can be created. The newly created additional
device node appears in /dev and has read and write permissions enabled
only for root. By default all adapters, domains and ioctls are
initially disabled on this new device node.
.TP
.B zcryptctl destroy
.I node-name
Destroy an additional zcrypt device node. The device node is only
marked for disposal and destroyed when it is no longer used.
.TP
.B zcryptctl addap
.R |
.B delap
.I node-name adapter-nr
Update the filter for the specified zcrypt device node and add or
delete a crypto adapter to be accessible via this node. The symbol
\fBALL\fP can be used to enable or disable all adapters.
.TP
.B zcryptctl adddom
.R |
.B deldom
.I node-name domain-nr
Update the filter for the specified zcrypt device node and add or
delete a domain to be accessible through this node. The symbol
\fBALL\fP can be used to enable or disable all domains.
.TP
.B zcryptctl addioctl
.R |
.B delioctl
.I node-name ioctl-term
Update the filter for the specified zcrypt device node and add or
delete an ioctl. The ioctl might be specified as symbolic string (one
of \fBICARSAMODEXPO\fP, \fBICARSACRT\fP, \fBZSECSENDCPRB\fP,
\fBZSENDEP11CPRB\fP, \fBZCRYPT_DEVICE_STATUS\fP,
\fBZCRYPT_STATUS_MASK\fP, \fBZCRYPT_QDEPTH_MASK\fP,
\fBZCRYPT_PERDEV_REQCNT\fP) or numeric value in the range 0-255 and
the symbol \fBALL\fP can be used to include all ioctls.
.TP
.B zcryptctl config
.I config-file
Process a config file. The given configuration file is read line by
line and the settings are applied. Syntax is simple:
.RS
.IP "node=<node-name>"
.IP "aps=<list of ap numbers separated by space, tab or ','>"
.IP "doms=<list of domain numbers separated by space, tab or ','>"
.IP "ioctls=<list of ioctl as numeric or symbolic number separated by space, tab or ','>"
.LP
Empty lines are ignored and the '#' marks the rest of the
line as comment.
.LP
The \fBnode=\fP line creates a new zcrypt device node, the \fBaps=\fP,
\fBdoms=\fP and \fBioctls=\fP lines customize the previously created
node. The symbol \fBALL\fP is also recognized for aps, doms, and
ioctls.
.LP
Each action must fit into one line, spreading over multiple lines is
not supported. But you can use more than one \fBaps=\fP, \fBdoms=\fP
and \fBioctls=\fP lines to customize the very same node.
.LP
Processing stops when a line cannot be parsed or the current action
fails. In this case the exit status is non zero but the successful
actions until the failure occurs are not rolled back.
.RE
.TP
.B zcryptctl listconfig
List the current configuration in a form suitable for input to the
\fBzcryptctl config\fP command.
.LP
.SH EXIT STATUS
On successful completion of the command the exit status is 0. A non
zero return code (and some kind of failure message) is emitted if the
processing could not complete successful.
.SH SEE ALSO
\fBlszcrypt\fR(8)

1030
zconf/zcrypt/zcryptctl.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -62,10 +62,12 @@ struct ccw_devinfo {
* ccw_subtype_data - CCW subtype specific information
* @ccwdrv: The name of the CCW device driver for this subtype
* @mod: The name of the main kernel module for this subtype
* @any_driver: If set, the exact driver for this subtype are not known
*/
struct ccw_subtype_data {
const char *ccwdrv;
const char *mod;
bool any_driver;
};
extern struct attrib ccw_attr_online;

View File

@@ -20,7 +20,7 @@
#define UDEV_SUFFIX ".rules"
#define PATH_MODPROBE_CONF "/etc/modprobe.d"
#define PATH_MODPROBE "/usr/sbin/modprobe"
#define PATH_MODPROBE "/sbin/modprobe"
#define PATH_CCW_BUS "/sys/bus/ccw"
#define PATH_CCWGROUP_BUS "/sys/bus/ccwgroup"
#define PATH_UDEV_RULES "/etc/udev/rules.d"

View File

@@ -17,6 +17,6 @@ INITTOP := $(INITRAMFSDIR)/scripts/init-top
ifeq ($(HAVE_INITRAMFS),1)
install:
$(INSTALL) -m 755 -d $(DESTDIR)/$(HOOKDIR) $(DESTDIR)/$(INITTOP)
$(INSTALL) -m 755 hooks/zdev $(DESTDIR)/$(HOOKDIR)
$(INSTALL) -m 755 scripts/init-top/zdev $(DESTDIR)/$(INITTOP)
$(INSTALL) -m 755 hooks/s390-tools-zdev $(DESTDIR)/$(HOOKDIR)
$(INSTALL) -m 755 scripts/init-top/s390-tools-zdev $(DESTDIR)/$(INITTOP)
endif

View File

@@ -5,7 +5,7 @@
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
# hooks/zdev
# hooks/s390-tools-zdev
# This hook script adds files required to apply firmware-provided I/O
# configuration data during boot.
#

View File

@@ -5,7 +5,7 @@
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
# scripts/init-top/zdev
# scripts/init-top/s390-tools-zdev
# Parse the kernel command line for rd.zdev kernel parameters. These
# parameters are evaluated and used to configure z Systems specific devices.
#

View File

@@ -29,6 +29,7 @@
static struct ccw_subtype_data generic_ccw_data = {
.ccwdrv = NULL,
.mod = NULL,
.any_driver = true,
};
/* Check if there is a non-generic subtype in the CCW namespace that uses the

View File

@@ -1171,6 +1171,37 @@ static exit_code_t check_ineffective_settings(struct setting_list *list,
return rc;
}
/* Check if a possibly conflicting setting is active in the configuration */
static bool conflict_setting_active(struct setting *s)
{
enum qeth_attr_group_type t;
t = get_attr_group_type(s);
if (t != group_bridge && t != group_vnicc) {
/* Check BridgePort and VNICC attributes only */
return false;
}
if (s->specified) {
/* Specified on the command line: We are strict here and do not
* allow to specify VNICC and BridgePort attributes in the same
* command to avoid issues when attributes are enabled/disabled
* in the wrong order. Example: disable VNICC and enable
* BridgePort in the same command would result in an error
* because BridgePort attributes are set first.
*/
return true;
}
if (attrib_match_default(s->attrib, s->value)) {
/* Not active if set to default value */
return false;
}
if (s->actual_value && strncmp(s->actual_value, "n/a", 3) == 0) {
/* Not active if in n/a state (conflicting attribute set) */
return false;
}
return true;
}
/* Check if there are conflicting attribute settings */
static exit_code_t check_conflicting_settings(struct setting_list *list)
{
@@ -1182,6 +1213,8 @@ static exit_code_t check_conflicting_settings(struct setting_list *list)
util_list_iterate(&list->list, s) {
if (s->removed)
continue;
if (!conflict_setting_active(s))
continue;
t = get_attr_group_type(s);
if (t == group_bridge && (!bridge || !bridge->specified))
bridge = s;

View File

@@ -140,7 +140,7 @@ exit_code_t udev_ccw_write_device(struct device *dev, bool autoconf)
{
struct subtype *st = dev->subtype;
struct ccw_subtype_data *data = st->data;
const char *type = st->name, *drv = data->ccwdrv, *id = dev->id;
const char *type = st->name, *drv = data->any_driver ? "*" : data->ccwdrv, *id = dev->id;
struct device_state *state = autoconf ? &dev->autoconf :
&dev->persistent;
char *path, *cfg_label = NULL, *end_label = NULL;

View File

@@ -774,7 +774,7 @@ static const struct fuse_opt zdsfs_opts[] = {
static void usage(const char *progname)
{
fprintf(stderr,
fprintf(stdout,
"Usage: %s <devices> <mountpoint> [<options>]\n"
"\n"
"Use the zdsfs command to provide read access to data sets stored on one or\n"
@@ -976,14 +976,24 @@ static int zdsfs_process_args(void *UNUSED(data), const char *arg, int key,
return 0;
case KEY_HELP:
usage(outargs->argv[0]);
/*
* Usage output needs to go to stdout to be consistent with
* coding guidelines. FUSE versions before 3.0.0 print help
* output to stderr. Redirect stderr to stdout here to enforce
* consistent behavior.
*/
fflush(stderr);
dup2(STDOUT_FILENO, STDERR_FILENO);
fuse_opt_add_arg(outargs, "-ho");
/* call fuse_main to let library print fuse options */
fuse_main(outargs->argc, outargs->argv, &rdf_oper, NULL);
exit(0);
case KEY_VERSION:
fprintf(stderr, COMP "FUSE file system for z/OS data set access"
fprintf(stdout, COMP "FUSE file system for z/OS data set access"
", program version %s\n", RELEASE_STRING);
fprintf(stderr, "Copyright IBM Corp. 2013, 2017\n");
fprintf(stdout, "Copyright IBM Corp. 2013, 2017\n");
exit(0);
default:
fprintf(stderr, "Unknown argument key %x\n", key);

114
zfcpdump/10-zfcpdump.install.in Executable file
View File

@@ -0,0 +1,114 @@
#!/bin/bash
#
# 10-zfcpdump.install - Installation script to handle zfcpdump kernels
#
# Copyright IBM Corp. 2018
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
#
# This script supports two modes:
#
# 1) Installing the images to /boot/<machine-id>/<kernel-version>
# subdirectories, i.e. BOOT_DIR_ABS, as recommended by the BLS.
# In this case file names are taken over from the original files.
#
# 2) Installing the images directly to /boot. In this case the files are
# renamed to <original-name>-<kernel-version>.
#
# The existence of BOOT_DIR_ABS is taken as trigger to switch between both
# modes.
#
# The KERNEL_VERSION is assumed to contain '@flavor@' to identify the image
# as a zfcpdump kernel.
COMMAND="$1"
KERNEL_VERSION="$2"
BOOT_DIR_ABS="$3"
KERNEL_IMAGE="$4"
# Location zipl looks for the zfcpdump kernel
ZFCPDUMP_IMAGE='@zfcpdump_image@'
# Only handle zfcpdump kernels
echo "$KERNEL_VERSION" | grep -q '@flavor@' || exit 0
case "$COMMAND" in
add)
KERNEL_DIR="$(dirname $KERNEL_IMAGE)"
KERNEL_NAME="$(basename $KERNEL_IMAGE)"
for f in \
"$KERNEL_IMAGE" \
"$KERNEL_DIR"/System.map \
"$KERNEL_DIR"/config \
"$KERNEL_DIR"/zImage.stub
do
test -e "$f" || continue
test -d "$BOOT_DIR_ABS" \
&& DEST="$BOOT_DIR_ABS/$(basename $f)" \
|| DEST="/boot/$(basename $f)-$KERNEL_VERSION"
cp -aT "$f" "$DEST"
test $(command -v restorecon) && restorecon -R "$DEST"
done
# hmac file need special treatment
f="$KERNEL_DIR/.$KERNEL_NAME.hmac"
if [ -e "$f" ]; then
test -d "$BOOT_DIR_ABS" \
&& DEST="$BOOT_DIR_ABS/$(basename $f)" \
|| DEST="/boot/.$KERNEL_NAME-$KERNEL_VERSION.hmac"
cp -aT "$f" "$DEST"
test $(command -v restorecon) && restorecon -R "$DEST"
fi
# Set link so zipl finds the kernel
test -d "$BOOT_DIR_ABS" \
&& TARGET="$BOOT_DIR_ABS/$KERNEL_NAME" \
|| TARGET="/boot/$KERNEL_NAME-$KERNEL_VERSION"
ln -sf "$TARGET" "$ZFCPDUMP_IMAGE"
;;
remove)
# On removal
# $KERNEL_IMAGE is empty -> $KERNEL_NAME is empty -> rebuild it
KERNEL_NAME="$(basename $(readlink $ZFCPDUMP_IMAGE))"
if [ -d "$BOOT_DIR_ABS" ]; then
INSTALL_DIR="$(dirname $BOOT_DIR_ABS)"
else
INSTALL_DIR="/boot/"
KERNEL_NAME="$(echo $KERNEL_NAME \
| sed -e "s#\(.*\)-$KERNEL_VERSION#\1#")"
fi
for f in $(find "$INSTALL_DIR" -name "*$KERNEL_VERSION*"); do
rm -rf "$f"
done
# Update link to latest remaining zfcpdump kernel.
if [ $(readlink "$ZFCPDUMP_IMAGE" | grep "$KERNEL_VERSION") ]
then
NEXT_IMAGE=$( \
find "$INSTALL_DIR" -type f \
| grep '@flavor@' \
| grep "$KERNEL_NAME" \
| grep -v "hmac" \
| sort -V \
| tail -n1 )
test $NEXT_IMAGE \
&& ln -sf "$NEXT_IMAGE" "$ZFCPDUMP_IMAGE" \
|| rm -f "$ZFCPDUMP_IMAGE"
fi
;;
*)
;;
esac
# Prevent execution of all other scripts.
# The zfcpdump kernel is stripped down to the bare minimum needed for
# dumping. It is not supposed to be used for any other purpose.
exit 77

View File

@@ -1,6 +1,7 @@
include ../common.mak
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
INSTALL_SCRIPTS = 10-zfcpdump.install
ifeq (${HAVE_LIBC_STATIC},0)
@@ -20,7 +21,7 @@ check_dep:
"HAVE_LIBC_STATIC=0", \
"-static")
all: check_dep $(ZFCPDUMP_PART_RD)
all: check_dep $(ZFCPDUMP_INITRD) scripts
cpioinit: cpioinit.c
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
@@ -29,17 +30,26 @@ zfcpdump_part: zfcpdump.o zfcpdump_part.o
$(LINK) $(ALL_LDFLAGS) $^ -static -o $@
$(STRIP) -s $@
$(ZFCPDUMP_PART_RD): cpioinit zfcpdump_part
$(ZFCPDUMP_INITRD): cpioinit zfcpdump_part
$(CPIOINIT) zfcpdump_part > $@.tmp
$(GZIP) -f $@.tmp
$(MV) $@.tmp.gz $(ZFCPDUMP_PART_RD)
$(MV) $@.tmp.gz $(ZFCPDUMP_INITRD)
scripts: $(INSTALL_SCRIPTS)
chmod +x $(INSTALL_SCRIPTS)
install: all
$(INSTALL) -m 611 $(ZFCPDUMP_PART_RD) $(DESTDIR)$(ZFCPDUMP_DIR)
$(INSTALL) -m 611 $(ZFCPDUMP_INITRD) $(DESTDIR)$(ZFCPDUMP_DIR)
%: %.in
zfcpdump_image=$(ZFCPDUMP_DIR)/$(ZFCPDUMP_IMAGE); \
$(SED) -e "s#@zfcpdump_image@#$$zfcpdump_image#g" \
-e "s#@flavor@#$(ZFCPDUMP_FLAVOR)#g" \
< $< > $@
endif
clean:
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_PART_RD)
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_INITRD) \
$(INSTALL_SCRIPTS)
.PHONY: all clean install check_dep
.PHONY: all clean install check_dep scripts

View File

@@ -29,9 +29,6 @@
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#ifdef GZIP_SUPPORT
#include <zlib.h>
#endif
#include "lib/zt_common.h"
#include "zfcpdump.h"
@@ -288,12 +285,10 @@ no_reipl:
/*
* Signal handler for zfcp_dumper
*/
static __sighandler_t dump_sig_handler(int sig, siginfo_t *UNUSED(sip),
void *UNUSED(p))
static void dump_sig_handler(int sig, siginfo_t *UNUSED(sip), void *UNUSED(p))
{
PRINT_ERR("Got signal: %i\n", sig);
terminate(1);
return NULL;
}
/*
@@ -304,7 +299,7 @@ static __sighandler_t dump_sig_handler(int sig, siginfo_t *UNUSED(sip),
static int init_sig(void)
{
g.sigact.sa_flags = (SA_NODEFER | SA_SIGINFO | SA_RESETHAND);
g.sigact.sa_handler = (__sighandler_t)dump_sig_handler;
g.sigact.sa_sigaction = dump_sig_handler;
if (sigemptyset(&g.sigact.sa_mask) < 0)
return -1;
if (sigaction(SIGINT, &g.sigact, NULL) < 0)
@@ -359,41 +354,10 @@ void show_progress(unsigned long done)
time_next = tv.tv_sec + 10;
}
/*
* Load a kernel module
*/
static void modprobe(const char *module)
{
pid_t pid;
pid = fork();
if (pid < 0) {
PRINT_PERR("fork failed\n");
return;
} else if (pid == 0) {
execl("/bin/modprobe", "modprobe", module, "-q", NULL);
execl("/sbin/modprobe", "modprobe", module, "-q", NULL);
exit(1);
} else {
waitpid(pid, NULL, 0);
}
}
/*
* Load all required kernel modules
*/
static void load_modules(const char *module_list[])
{
int i;
for (i = 0; module_list[i]; i++)
modprobe(module_list[i]);
}
/*
* Initialize zfcpdump
*/
int zfcpdump_init(const char *module_list[])
int zfcpdump_init(void)
{
char start_time_str[128], linux_version[256];
@@ -436,7 +400,6 @@ int zfcpdump_init(const char *module_list[])
PRINT_ERR("Could not parse parmline\n");
return -1;
}
load_modules(module_list);
if (enable_zfcp_device()) {
PRINT_ERR("Could not enable dump device\n");
return -1;

View File

@@ -103,7 +103,7 @@ struct mem_chunk {
*/
void release_hsa(void);
__u64 get_hsa_size(void);
int zfcpdump_init(const char *module_list[]);
int zfcpdump_init(void);
void print_newline(void);
void show_progress(unsigned long done);
int terminate(int rc);

View File

@@ -103,7 +103,6 @@ struct scsi_mbr {
/*
* Globals
*/
static const char *module_list[] = {"zfcp", "sd_mod", "zcore_mod", NULL};
static struct scsi_dump_sb dump_sb;
static struct scsi_mbr mbr;
@@ -440,7 +439,7 @@ int main(int UNUSED(argc), char *UNUSED(argv[]))
{
int rc;
if (zfcpdump_init(module_list))
if (zfcpdump_init())
return terminate(1);
PRINT("Dump parameters:\n");
PRINT(" devno....: %s\n", g.dump_devno);

View File

@@ -12,33 +12,33 @@ ziomon_mgr_main.o: ziomon_mgr.c
ziomon_mgr: LDLIBS += -lm
ziomon_mgr: ziomon_dacc.o ziomon_util.o ziomon_mgr_main.o ziomon_tools.o \
ziomon_zfcpdd.o ziomon_msg_tools.o
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ziomon_util_main.o: ziomon_util.c ziomon_util.h
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
ziomon_util: LDLIBS += -lm
ziomon_util: ziomon_util_main.o ziomon_tools.o
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ziomon_zfcpdd_main.o: ziomon_zfcpdd.c ziomon_zfcpdd.h
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
ziomon_zfcpdd: LDLIBS += -lm -lrt -lpthread
ziomon_zfcpdd: ziomon_zfcpdd_main.o ziomon_tools.o
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ziorep_traffic: ziorep_traffic.o ziorep_framer.o ziorep_frameset.o \
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
ziorep_filters.o
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ziorep_utilization: ziorep_utilization.o ziorep_framer.o ziorep_frameset.o \
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
ziorep_filters.o
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install: all
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \

View File

@@ -48,13 +48,6 @@
#define MENU_DEFAULT_PROMPT 0
#define MENU_DEFAULT_TIMEOUT 0
#define FSDUMP_IMAGE STRINGIFY(ZFCPDUMP_DIR) "/" STRINGIFY(ZFCPDUMP_FS_IMAGE)
#define FSDUMP_RAMDISK STRINGIFY(ZFCPDUMP_DIR) "/" STRINGIFY(ZFCPDUMP_FS_RD)
#define FSDUMP_PART_IMAGE STRINGIFY(ZFCPDUMP_DIR) "/" \
STRINGIFY(ZFCPDUMP_PART_IMAGE)
#define FSDUMP_PART_RAMDISK STRINGIFY(ZFCPDUMP_DIR) "/" \
STRINGIFY(ZFCPDUMP_PART_RD)
#define MAX_DUMP_VOLUMES 32
/* Internal component load address type */

View File

@@ -2,11 +2,8 @@
include ../../common.mak
ALL_CPPFLAGS += -I../include -I../boot \
-DZFCPDUMP_DIR=$(ZFCPDUMP_DIR) \
-DZFCPDUMP_FS_IMAGE=$(ZFCPDUMP_FS_IMAGE) \
-DZFCPDUMP_FS_RD=$(ZFCPDUMP_FS_RD) \
-DZFCPDUMP_PART_IMAGE=$(ZFCPDUMP_PART_IMAGE) \
-DZFCPDUMP_PART_RD=$(ZFCPDUMP_PART_RD) \
-DZFCPDUMP_IMAGE="STRINGIFY($(ZFCPDUMP_DIR)/$(ZFCPDUMP_IMAGE))" \
-DZFCPDUMP_INITRD="STRINGIFY($(ZFCPDUMP_DIR)/$(ZFCPDUMP_INITRD))" \
-D_FILE_OFFSET_BITS=64 $(NO_PIE_CFLAGS)
ALL_LDFLAGS += -Wl,-z,noexecstack $(NO_PIE_LDFLAGS)
@@ -44,6 +41,8 @@ clean:
# Additional manual dependencies
.boot.o.d boot.o: ../boot/data.h
../boot/data.h:
make -C ../boot data.h

View File

@@ -21,6 +21,8 @@
#include <sys/sysmacros.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <linux/fs.h>
#include <linux/fiemap.h>
#include "lib/util_proc.h"
@@ -550,8 +552,12 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
{
struct statfs buf;
blocknum_t phy_per_fs;
int mapped;
blocknum_t mapped;
int block;
int subblock;
int fiemap_size;
int map_offset;
struct fiemap *fiemap;
/* No file system: partition or raw disk */
if (info->fs_block_size == -1) {
@@ -576,12 +582,55 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
}
/* Get mapping in file system blocks */
phy_per_fs = info->fs_block_size / info->phy_block_size;
mapped = logical / phy_per_fs;
subblock = logical % phy_per_fs;
if (ioctl(fd, FIBMAP, &mapped)) {
error_reason("Could not get file mapping");
/* First try FIEMAP, more complicated to set up */
fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent);
fiemap = misc_malloc(fiemap_size);
if (!fiemap)
return -1;
memset(fiemap, 0, fiemap_size);
fiemap->fm_extent_count = 1;
fiemap->fm_flags = FIEMAP_FLAG_SYNC;
/* fm_start, fm_length in bytes; logical is in physical block units */
fiemap->fm_start = logical * info->phy_block_size;
fiemap->fm_length = info->phy_block_size;
if (ioctl(fd, FS_IOC_FIEMAP, (unsigned long)fiemap)) {
/* FIEMAP failed, fall back to FIBMAP */
block = logical / phy_per_fs;
if (ioctl(fd, FIBMAP, &block)) {
error_reason("Could not get file mapping");
free(fiemap);
return -1;
}
mapped = block;
} else {
if (fiemap->fm_mapped_extents) {
if (fiemap->fm_extents[0].fe_flags &
FIEMAP_EXTENT_ENCODED) {
error_reason("File mapping is encoded");
free(fiemap);
return -1;
}
/*
* returned extent may start prior to our request
*/
map_offset = fiemap->fm_start -
fiemap->fm_extents[0].fe_logical;
mapped = fiemap->fm_extents[0].fe_physical +
map_offset;
/* set mapped to fs block units */
mapped = mapped / info->fs_block_size;
} else {
mapped = 0;
}
}
free(fiemap);
if (mapped == 0) {
/* This is a hole in the file */
*physical = 0;

View File

@@ -874,22 +874,22 @@ check_job_dump_images(struct job_dump_data* dump, char* name)
{
int rc;
/* Add data needed to convert fs dump job to IPL job */
rc = misc_check_readable_file(FSDUMP_PART_IMAGE);
rc = misc_check_readable_file(ZFCPDUMP_IMAGE);
if (rc) {
error_text("Need external file '%s' for partition dump",
FSDUMP_PART_IMAGE);
ZFCPDUMP_IMAGE);
return rc;
}
dump->image = misc_strdup(FSDUMP_PART_IMAGE);
dump->image = misc_strdup(ZFCPDUMP_IMAGE);
if (dump->image == NULL)
return -1;
dump->image_addr = DEFAULT_IMAGE_ADDRESS;
/* Ramdisk is no longer required with new initramfs dump system */
if (misc_check_readable_file(FSDUMP_PART_RAMDISK))
if (misc_check_readable_file(ZFCPDUMP_INITRD))
dump->ramdisk = NULL;
else {
dump->ramdisk = misc_strdup(FSDUMP_PART_RAMDISK);
dump->ramdisk = misc_strdup(ZFCPDUMP_INITRD);
if (dump->ramdisk == NULL)
return -1;
dump->ramdisk_addr = UNSPECIFIED_ADDRESS;

View File

@@ -1,47 +1,103 @@
include ../common.mak
ifeq (${HAVE_OPENSSL},0)
all:
$(SKIP) HAVE_OPENSSL=0
install:
$(SKIP) HAVE_OPENSSL=0
ifneq (${HAVE_OPENSSL},0)
BUILD_TARGETS += zkey
INSTALL_TARGETS += install-zkey
else
BUILD_TARGETS += zkey-skip
INSTALL_TARGETS += zkey-skip
endif
check_dep:
ifneq (${HAVE_CRYPTSETUP2},0)
ifneq (${HAVE_JSONC},0)
BUILD_TARGETS += zkey-cryptsetup
INSTALL_TARGETS += install-zkey-cryptsetup
CPPFLAGS += -DHAVE_LUKS2_SUPPORT
else
BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
endif
else
BUILD_TARGETS += zkey-cryptsetup-skip-cryptsetup2
INSTALL_TARGETS += zkey-cryptsetup-skip-cryptsetup2
endif
libs = $(rootdir)/libutil/libutil.a
detect-libcryptsetup.dep:
echo "#include <libcryptsetup.h>" > detect-libcryptsetup.dep
echo "#ifndef CRYPT_LUKS2" >> detect-libcryptsetup.dep
echo " #error libcryptsetup version 2.0.3 is required" >> detect-libcryptsetup.dep
echo "#endif" >> detect-libcryptsetup.dep
echo "int i = CRYPT_SLOT_UNBOUND;" >> detect-libcryptsetup.dep
check-dep-zkey:
$(call check_dep, \
"zkey", \
"openssl/evp.h", \
"openssl-devel", \
"HAVE_OPENSSL=0")
touch check-dep-zkey
CPPFLAGS += -I../include
LDLIBS += -ldl -lcrypto
check-dep-zkey-cryptsetup: detect-libcryptsetup.dep
$(call check_dep, \
"zkey-cryptsetup", \
"detect-libcryptsetup.dep", \
"cryptsetup-devel version 2.0.3", \
"HAVE_CRYPTSETUP2=0", \
"-I.")
$(call check_dep, \
"zkey-cryptsetup", \
"json-c/json.h", \
"json-c-devel", \
"HAVE_JSONC=0")
touch check-dep-zkey-cryptsetup
all: check_dep zkey
zkey-skip:
echo " SKIP zkey due to HAVE_OPENSSL=0"
libs = $(rootdir)/libutil/libutil.a
zkey-cryptsetup-skip-cryptsetup2:
echo " SKIP zkey-cryptsetup due to HAVE_CRYPTSETUP2=0"
zkey-cryptsetup-skip-jsonc:
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
all: $(BUILD_TARGETS)
zkey.o: zkey.c pkey.h misc.h
pkey.o: pkey.c pkey.h
properties.o: properties.c properties.h
properties.o: check-dep-zkey properties.c properties.h
keystore.o: keystore.c keystore.h properties.h
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h misc.h
zkey: LDLIBS = -ldl -lcrypto
zkey: zkey.o pkey.o properties.o keystore.o $(libs)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install: all
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c
zkey-cryptsetup: zkey-cryptsetup.o pkey.o $(libs)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install-common:
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
install-zkey:
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
endif
install-zkey-cryptsetup:
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
$(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
install: all install-common $(INSTALL_TARGETS)
clean:
rm -f *.o zkey
rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.dep \
check-dep-zkey check-dep-zkey-cryptsetup
.PHONY: all install clean
.PHONY: all install clean zkey-skip zkey-cryptsetup-skip-cryptsetup2 \
zkey-cryptsetup-skip-jsonc install-common install-zkey \
install-zkey-cryptsetup

File diff suppressed because it is too large Load Diff

View File

@@ -30,16 +30,17 @@ int keystore_generate_key(struct keystore *keystore, const char *name,
const char *description, const char *volumes,
const char *apqns, size_t sector_size,
size_t keybits, bool xts, const char *clear_key_file,
int pkey_fd);
const char *volume_type, int pkey_fd);
int keystore_import_key(struct keystore *keystore, const char *name,
const char *description, const char *volumes,
const char *apqns, size_t sector_size,
const char *import_file);
const char *import_file, const char *volume_type);
int keystore_change_key(struct keystore *keystore, const char *name,
const char *description, const char *volumes,
const char *apqns, long int sector_size);
const char *apqns, long int sector_size,
const char *volume_type);
int keystore_rename_key(struct keystore *keystore, const char *name,
const char *newname);
@@ -63,12 +64,14 @@ int keystore_remove_key(struct keystore *keystore, const char *name,
bool quiet);
int keystore_list_keys(struct keystore *keystore, const char *name_filter,
const char *volume_filter, const char *apqn_filter);
const char *volume_filter, const char *apqn_filter,
const char *volume_type);
int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
bool execute);
bool execute, const char *volume_type);
int keystore_crypttab(struct keystore *keystore, const char *volume_filter);
int keystore_crypttab(struct keystore *keystore, const char *volume_filter,
const char *volume_type);
void keystore_free(struct keystore *keystore);

View File

@@ -11,11 +11,13 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/if_alg.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
@@ -25,6 +27,12 @@
#include "pkey.h"
#ifndef AF_ALG
#define AF_ALG 38
#endif
#ifndef SOL_ALG
#define SOL_ALG 279
#endif
#define pr_verbose(verbose, fmt...) do { \
if (verbose) \
@@ -34,6 +42,8 @@
#define DOUBLE_KEYSIZE_FOR_XTS(keysize, xts) ((xts) ? 2 * (keysize) : (keysize))
#define HALF_KEYSIZE_FOR_XTS(keysize, xts) ((xts) ? (keysize) / 2 : (keysize))
#define MAX_CIPHER_LEN 32
/*
* Definitions for the CCA library
*/
@@ -367,6 +377,8 @@ int generate_secure_key_random(int pkey_fd, const char *keyfile,
if (rc < 0) {
rc = -errno;
warnx("Failed to generate a secure key: %s", strerror(errno));
warnx("Make sure that all available CCA crypto adapters are "
"setup with the same master key");
goto out;
}
@@ -378,6 +390,8 @@ int generate_secure_key_random(int pkey_fd, const char *keyfile,
rc = -errno;
warnx("Failed to generate a secure key: %s",
strerror(errno));
warnx("Make sure that all available CCA crypto "
"adapters are setup with the same master key");
goto out;
}
@@ -465,6 +479,8 @@ int generate_secure_key_clear(int pkey_fd, const char *keyfile,
rc = -errno;
warnx("Failed to generate a secure key from a "
"clear key: %s", strerror(errno));
warnx("Make sure that all available CCA crypto adapters are "
"setup with the same master key");
goto out;
}
@@ -479,6 +495,8 @@ int generate_secure_key_clear(int pkey_fd, const char *keyfile,
rc = -errno;
warnx("Failed to generate a secure key from "
"a clear key: %s", strerror(errno));
warnx("Make sure that all available CCA crypto "
"adapters are setup with the same master key");
goto out;
}
@@ -746,3 +764,143 @@ int validate_secure_key(int pkey_fd,
return 0;
}
/**
* Generate a key verification pattern of a secure key by encrypting the all
* zero message with the secure key using the AF_ALG interface
*
* @param[in] key the secure key token
* @param[in] key_size the size of the secure key
* @param[in] vp buffer where the verification pattern is returned
* @param[in] vp_len the size of the buffer
* @param[in] verbose if true, verbose messages are printed
*
* @returns 0 on success, a negative errno in case of an error
*/
int generate_key_verification_pattern(const char *key, size_t key_size,
char *vp, size_t vp_len, bool verbose)
{
int tfmfd = -1, opfd = -1, rc = 0;
char null_msg[ENC_ZERO_LEN];
char enc_zero[ENC_ZERO_LEN];
struct af_alg_iv *alg_iv;
struct cmsghdr *header;
uint32_t *type;
ssize_t len;
size_t i;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "skcipher",
};
struct iovec iov = {
.iov_base = (void *)null_msg,
.iov_len = sizeof(null_msg),
};
int iv_msg_size = CMSG_SPACE(sizeof(*alg_iv) + PAES_BLOCK_SIZE);
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
struct msghdr msg = {
.msg_control = buffer,
.msg_controllen = sizeof(buffer),
.msg_iov = &iov,
.msg_iovlen = 1,
};
if (vp_len < VERIFICATION_PATTERN_LEN) {
rc = -EMSGSIZE;
goto out;
}
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(paes)",
key_size > SECURE_KEY_SIZE ? "xts" : "cbc");
tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (tfmfd < 0) {
rc = -errno;
pr_verbose(verbose, "Failed to open an AF_ALG socket");
goto out;
}
if (bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
rc = -errno;
pr_verbose(verbose, "Failed to bind the AF_ALG socket, "
"salg_name='%s' ", sa.salg_name);
goto out;
}
if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, key,
key_size) < 0) {
rc = -errno;
pr_verbose(verbose, "Failed to set the key");
goto out;
}
opfd = accept(tfmfd, NULL, 0);
if (opfd < 0) {
rc = -errno;
pr_verbose(verbose, "Failed to accept on the AF_ALG socket");
goto out;
}
memset(null_msg, 0, sizeof(null_msg));
memset(buffer, 0, sizeof(buffer));
header = CMSG_FIRSTHDR(&msg);
if (header == NULL) {
pr_verbose(verbose, "Failed to obtain control message header");
rc = -EINVAL;
goto out;
}
header->cmsg_level = SOL_ALG;
header->cmsg_type = ALG_SET_OP;
header->cmsg_len = CMSG_LEN(sizeof(*type));
type = (void *)CMSG_DATA(header);
*type = ALG_OP_ENCRYPT;
header = CMSG_NXTHDR(&msg, header);
if (header == NULL) {
pr_verbose(verbose, "Failed to obtain control message "
"header");
rc = -EINVAL;
goto out;
}
header->cmsg_level = SOL_ALG;
header->cmsg_type = ALG_SET_IV;
header->cmsg_len = iv_msg_size;
alg_iv = (void *)CMSG_DATA(header);
alg_iv->ivlen = PAES_BLOCK_SIZE;
memcpy(alg_iv->iv, null_msg, PAES_BLOCK_SIZE);
len = sendmsg(opfd, &msg, 0);
if (len != ENC_ZERO_LEN) {
pr_verbose(verbose, "Failed to send to the AF_ALG socket");
rc = -errno;
goto out;
}
len = read(opfd, enc_zero, sizeof(enc_zero));
if (len != ENC_ZERO_LEN) {
pr_verbose(verbose, "Failed to receive from the AF_ALG socket");
rc = -errno;
goto out;
}
memset(vp, 0, vp_len);
for (i = 0; i < sizeof(enc_zero); i++)
sprintf(&vp[i * 2], "%02x", enc_zero[i]);
pr_verbose(verbose, "Key verification pattern: %s", vp);
out:
if (opfd != -1)
close(opfd);
if (tfmfd != -1)
close(tfmfd);
if (rc != 0)
pr_verbose(verbose, "Failed to generate the key verification "
"pattern: %s", strerror(-rc));
return rc;
}

View File

@@ -93,6 +93,10 @@ typedef void (*t_CSNBKTC)(long *return_code,
unsigned char *rule_array,
unsigned char *key_identifier);
#define PAES_BLOCK_SIZE 16
#define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE)
#define VERIFICATION_PATTERN_LEN (2 * ENC_ZERO_LEN + 1)
int load_cca_library(void **lib_csulcca, t_CSNBKTC *dll_CSNBKTC, bool verbose);
int open_pkey_device(bool verbose);
@@ -122,4 +126,7 @@ int key_token_change(t_CSNBKTC dll_CSNBKTC,
u8 *secure_key, unsigned int secure_key_size,
char *method, bool verbose);
int generate_key_verification_pattern(const char *key, size_t key_size,
char *vp, size_t vp_len, bool verbose);
#endif

View File

@@ -149,6 +149,7 @@ void properties_free(struct properties *properties)
free(property->name);
free(property->value);
util_list_remove(&properties->list, property);
free(property);
}
free(properties);
@@ -259,6 +260,7 @@ int properties_remove(struct properties *properties, const char *name)
free(property->name);
free(property->value);
util_list_remove(&properties->list, property);
free(property);
return 0;
}
@@ -614,10 +616,13 @@ char *str_list_remove(const char *str_list, const char *str)
*/
void str_list_free_string_array(char **strings)
{
char **list = strings;
util_assert(strings != NULL, "Internal error: strings is NULL");
while (*strings != NULL) {
free((void *)*strings);
strings++;
}
free(list);
}

403
zkey/zkey-cryptsetup.1 Normal file
View File

@@ -0,0 +1,403 @@
.\" Copyright IBM Corp. 2018
.\" 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 ZKEY\-CRYPTSETUP 1 "May 2018" "s390-tools"
.SH NAME
zkey\-cryptsetup \- Manage secure AES volume keys of volumes encrypted with
\fBLUKS2\fP and the \fBpaes\fP cipher
.
.
.SH SYNOPSIS
.B zkey\-cryptsetup
.I command
.I device
.RI [ OPTIONS ]
.
.PP
.B zkey\-cryptsetup
.RI [ command ]
.BR \-\-help | \-h
.br
.B zkey\-cryptsetup
.BR \-\-version | \-v
.
.
.
.SH DESCRIPTION
Use \fBzkey\-cryptsetup\fP to validate and re-encipher secure AES
volume keys of volumes encrypted with \fBLUKS2\fP and the \fBpaes\fP cipher.
These secure AES volume keys are enciphered with a master key of an IBM
cryptographic adapter in CCA coprocessor mode.
.PP
To encrypt a volume using \fBLUKS2\fP and the \fBpaes\fP cipher, generate a
secure AES key using \fBzkey\fP: \fB'zkey generate luks.key --xts'\fP.
Then format the device with \fBcryptsetup\fP using the just generated secure
AES key from file luks.key: \fB'cryptsetup luksFormat <device> --type luks2
--cipher paes-xts-plain64 --master-key-file luks.key --key-size 1024'\fP. For
more details about \fBzkey\fP or \fBcryptsetup\fP see the
corresponding man pages.
.
.
.
.SH COMMANDS
.
.
.SS "Validate secure AES volume keys"
.
.B zkey\-cryptsetup
.BR validate | val
.I device
.RB [ \-\-key\-file | \-d
.IR file-name ]
.RB [ \-\-keyfile\-offset | \-o
.IR bytes ]
.RB [ \-\-keyfile\-size | \-l
.IR bytes ]
.RB [ \-\-tries | \-T
.IR number ]
.RB [ \-\-verbose | \-V ]
.RB [ \-\-debug | \-D ]
.PP
Use the
.B validate
command to validate a secure AES volume key of a volume encrypted with
\fBLUKS2\fP and the \fBpaes\fP cipher.
It checks if the LUKS2 header of the volume contains a valid secure key.
It also displays the attributes of the secure key, such as key size, whether
it is a secure key that can be used for the XTS cipher mode, and the master key
register (CURRENT or OLD) with which the secure key is enciphered.
For further information about master key registers, see the
\fBreencipher\fP command.
.PP
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
required. You are prompted for the passphrase, unless option
.B \-\-key\-file
is specified. Option
.B \-\-tries
specifies how often a passphrase can be re-entered. When option
.B \-\-key\-file
is specified, the passphrase is read from the specified file. You can specify
options
.B \-\-keyfile\-offset
and
.B \-\-keyfile\-size
to control which part of the key file is used as passphrase. These options
behave in the same way as with \fBcryptsetup\fP.
.
.SS "Re-encipher secure AES volume keys"
.
.PP
.B zkey\-cryptsetup
.BR reencipher | re
.I device
.RB [ \-\-staged | \-s ]
.RB [ \-\-in\-place | \-i ]
.RB [ \-\-complete | \-c ]
.RB [ \-\-key\-file | \-d
.IR file-name ]
.RB [ \-\-keyfile\-offset | \-o
.IR bytes ]
.RB [ \-\-keyfile\-size | \-l
.IR bytes ]
.RB [ \-\-tries | \-T
.IR number ]
.RB [ \-\-verbose | \-V ]
.RB [ \-\-debug | \-D ]
.PP
Use the
.B reencipher
command to re-encipher a secure AES volume key of a volume encrypted with
\fBLUKS2\fP and the \fBpaes\fP cipher. A secure AES volume key must be
re-enciphered when the master key of the cryptographic adapter in CCA
coprocessor mode changes.
.PP
The cryptographic adapter in CCA coprocessor mode has three different registers
to store master keys:
.RS 2
.IP "\(bu" 2
The \fBCURRENT\fP register contains the current master key.
.
.IP "\(bu" 2
The \fBOLD\fP register contains the previously used master key.
Secure keys enciphered with the master key contained in the \fBOLD\fP
register can still be used until the master key is changed again.
.
.IP "\(bu" 2
The \fBNEW\fP register contains the new master key to be set.
The master key in the \fBNEW\fP register cannot be used until it is made
the current master key. You can pro-actively re-encipher a secure key with the
\fBNEW\fP master key before this key is made the \fBCURRENT\fP key.
.RE
.PP
\fBzkey\-cryptsetup\fP automatically detects whether the secure volume key
is currently enciphered with the master key in the \fBOLD\fP register or with
the master key in the \fBCURRENT\fP register. If currently enciphered with the
master key in the \fBOLD\fP register, it is re-enciphered with the master key
in the \fBCURRENT\fP register. If it is currently enciphered with the master
key in the \fBCURRENT\fP register, it is re-enciphered with the master key in
the \fBNEW\fP register. If for this case the \fBNEW\fP register does not
contain a valid master key, then the re-encipher operation fails.
.PP
Re-enciphering a secure volume key of a volume encrypted with
\fBLUKS2\fP and the \fBpaes\fP cipher can be performed \fBin-place\fP, or in
\fBstaged\fP mode.
.PP
\fB"In-place"\fP immediately replaces the secure volume key in the LUKS2
header of the encrypted volume with the re-enciphered secure volume key.
Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed in-place per
default. You can use option \fB--in-place\fP to force an in-place
re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case. Be aware that
an encrypted volume with a secure volume key that was re-enciphered in-place
from \fBCURRENT\fP to \fBNEW\fP is no longer usable, until the new CCA master
key has been made the current one.
.PP
\fBStaged\fP mode means that the re-enciphered secure volume key is stored in a
separate (unbound) key slot in the LUKS2 header of the encrypted volume. Thus
all key slots containing the current secure volume key are still valid at this
point. Once the new CCA master key has been set (made active), you must rerun
the reencipher command with option \fB--complete\fP to complete the staged
re-enciphering. When completing the staged re-enciphering, the (unbound) key
slot containing the re-enciphered secure volume key becomes the active
key slot and, optionally, all key slots containing the old secure volume key
are removed.
Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is performed in staged mode per
default. You can use option \fB--staged\fP to force a staged re-enciphering for
the \fBOLD\fP to \fBCURRENT\fP case.
.PP
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
required. You are prompted for the passphrase, unless option
.B \-\-key\-file
is specified. Option
.B \-\-tries
specifies how often a passphrase can be re-entered. When option
.B \-\-key\-file
is specified, the passphrase is read from the specified file. You can specify
options
.B \-\-keyfile\-offset
and
.B \-\-keyfile\-size
to control which part of the key file is used as passphrase. These options
behave in the same way as with \fBcryptsetup\fP.
.PP
.B Note:
The \fBreencipher\fP command requires the CCA host library (libcsulcca.so)
to be installed.
.
.
.
.SS "Set a verification pattern of the secure AES volume key"
.
.B zkey\-cryptsetup
.BR setvp | setv
.I device
.RB [ \-\-key\-file | \-d
.IR file-name ]
.RB [ \-\-keyfile\-offset | \-o
.IR bytes ]
.RB [ \-\-keyfile\-size | \-l
.IR bytes ]
.RB [ \-\-tries | \-T
.IR number ]
.RB [ \-\-verbose | \-V ]
.RB [ \-\-debug | \-D ]
.PP
Use the
.B setvp
command to set a verification pattern of the secure AES volume key of a volume
encrypted with \fBLUKS2\fP and the \fBpaes\fP cipher. The verification pattern
identifies the effective key used to encrypt the volume's data.
The verification pattern is stored in a token named
\fBpaes-verification-pattern\fP in the LUKS2 header.
.PP
.B Note:
Set the verification pattern right after formatting the volume using
\fB'cryptsetup luksFormat'\fP.
.PP
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
required. You are prompted for the passphrase, unless option
.B \-\-key\-file
is specified. Option
.B \-\-tries
specifies how often a passphrase can be re-entered. When option
.B \-\-key\-file
is specified, the passphrase is read from the specified file. You can specify
options
.B \-\-keyfile\-offset
and
.B \-\-keyfile\-size
to control which part of the key file is used as passphrase. These options
behave in the same way as with \fBcryptsetup\fP.
.
.
.
.SS "Set a new secure AES volume key for a volume"
.
.B zkey\-cryptsetup
.BR setkey | setk
.I device
.BR \-\-master\-key\-file | \-m
.IR file-name
.RB [ \-\-key\-file | \-d
.IR file-name ]
.RB [ \-\-keyfile\-offset | \-o
.IR bytes ]
.RB [ \-\-keyfile\-size | \-l
.IR bytes ]
.RB [ \-\-tries | \-T
.IR number ]
.RB [ \-\-verbose | \-V ]
.RB [ \-\-debug | \-D ]
.PP
Use the
.B setkey
command to set a new secure AES volume key for a volume encrypted with
\fBLUKS2\fP and the \fBpaes\fP cipher. Use this command to recover from an
invalid secure AES volume key contained in the LUKS2 header.
A secure AES volume key contained in the LUKS2 header can become invalid when
the CCA master key is changed without re-enciphering the secure volume key.
.PP
You can recover the secure volume key only if you have a copy of the secure key
in a file, and this copy was re-enciphered when the CCA master key has been
changed. Thus, the copy of the secure key must be currently enciphered with the
CCA master key in the CURRENT or OLD master key register.
Specify the secure key file with option
.B \-\-master\-key\-file
to set this secure key as the new volume key.
.PP
In case the LUKS2 header of the volume contains a verification pattern token,
it is used to ensure that the new volume key contains the same effective key.
If no verification pattern token is available, then you are prompted to confirm
that the specified secure key is the correct one.
.B ATTENTION:
If you set a wrong secure key you will loose all the data on the encrypted
volume!
.PP
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
required. You are prompted for the passphrase, unless option
.B \-\-key\-file
is specified. Option
.B \-\-tries
specifies how often a passphrase can be re-entered. When option
.B \-\-key\-file
is specified, the passphrase is read from the specified file. You can specify
options
.B \-\-keyfile\-offset
and
.B \-\-keyfile\-size
to control which part of the key file is used as passphrase. These options
behave in the same way the same as with \fBcryptsetup\fP.
.
.
.
.
.SH OPTIONS
.
.SS "Options for the reencipher command"
.TP
.BR \-i ", " \-\-in-place
Forces an in-place re-enciphering of a secure volume key in the LUKS2
header. This option immediately replaces the secure volume key in the LUKS2
header of the encrypted volume with the re-enciphered secure volume key.
Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed in-place per
default.
.TP
.BR \-s ", " \-\-staged
Forces that the re-enciphering of a secure volume key in the LUKS2
header is performed in staged mode. Staged mode means that the re-enciphered
secure volume key is stored in a separate (unbound) key slot in the LUKS2
header of the encrypted volume. Thus all key slots containing the current
secure volume key are still valid at this point. Once the new CCA master key
has been set (made active), you must rerun the reencipher command with option
\fB--complete\fP to complete the staged re-enciphering. Re-enciphering from
\fBCURRENT\fP to \fBNEW\fP is performed in staged mode per default.
.TP
.BR \-p ", " \-\-complete
Completes a staged re-enciphering. Use this option after the new CCA master key
has been set (made active). When completing the staged re-enciphering, the
(unbound) key slot containing the re-enciphered secure volume key becomes
the active key slot and, optionally, all key slots containing the old secure
volume key are removed.
.
.
.
.SS "Options for the setkey command"
.TP
.BR \-m ", " \-\-master\-key\-file\~\fIfile\-name\fP
Specifies the name of a file containing the secure AES key that is set as the
new volume key.
.
.
.
.SS "Options for supplying the passphrase"
.TP
.BR \-d ", " \-\-key\-file\~\fIfile\-name\fP
Reads the passphrase from the specified file. If this option is omitted,
or if the file\-name is \fI-\fP (a dash), then you are prompted to enter the
passphrase interactively.
.TP
.BR \-o ", " \-\-keyfile\-offset\~\fIbytes\fP
Specifies the number of bytes to skip before starting to read in the file
specified with option \fB\-\-key\-file\fP. If omitted, the file is read
from the beginning. When option \fB\-\-key\-file\fP is not specified, this
option is ignored.
.TP
.BR \-l ", " \-\-keyfile\-size\~\fIbytes\fP
Specifies the number of bytes to be read from the beginning of the file
specified with option \fB\-\-key\-file\fP. If omitted, the file is read
until the end. When \fB\-\-keyfile\-offset\fP is also specified, reading starts
at the offset. When option \fB\-\-key\-file\fP is not specified, this option is
ignored.
.TP
.BR \-T ", " \-\-tries\~\fInumber\fP
Specifies how often the interactive input of the passphrase can be re-entered.
The default is 3 times. When option \fB\-\-key\-file\fP is specified, this
option is ignored, and the passphrase is read only once from the file.
.
.
.
.SS "General options"
.TP
.BR \-V ", " \-\-verbose
Displays additional information messages during processing.
.TP
.BR \-D ", " \-\-debug
Displays additional debugging messages during processing. This option also
implies \fB\-\-verbose\fP.
.TP
.BR \-h ", " \-\-help
Displays help text and exits.
.TP
.BR \-v ", " \-\-version
Displays version information and exits.
.
.
.
.SH EXAMPLES
.TP
.B zkey-cryptsetup reencipher /dev/dasdd1
Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1.
.TP
.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-staged
Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1 in
staged mode.
.TP
.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-complete
Completes re-enciphers the secure volume key of the encrypted
volume /dev/dasdd1.
.TP
.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-in\-place
Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1 in
in-place mode.
.TP
.B zkey-cryptsetup validate /dev/dasdd1
Validates the secure volume key of the encrypted volume /dev/dasdd1 and
displays its attributes.
.TP
.B zkey-cryptsetup setvp /dev/dasdd1
Sets the verification pattern of the secure volume key of the encrypted
volume /dev/dasdd1.
.TP
.B zkey-cryptsetup setkey /dev/dasdd1 --master-key-file seckey.key
Sets the secure key contained in file seckey.key as the new volume key
for the encrypted volume /dev/dasdd1.

2270
zkey/zkey-cryptsetup.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -75,30 +75,32 @@ key repository.
.BR generate | gen
.I secure\-key\-file
.RB [ \-\-keybits | \-k
.IB size ]
.IR size ]
.RB [ \-\-xts | \-x ]
.RB [ \-\-clearkey | \-c
.IB clear\-key\-file ]
.IR clear\-key\-file ]
.RB [ \-\-verbose | \-V ]
.
.PP
.B zkey
.BR generate | gen
.B \-\-name | \-N
.IB key-name
.IR key-name
.RB [ \-\-description | \-d
.IB description ]
.IR description ]
.RB [ \-\-volumes | \-l
.IB volume1:dmname1[,volume2:dmname2[,...]] ]
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
.RB [ \-\-apqns | \-a
.IB card1.domain1[,card2.domain2[,...]] ]
.IR card1.domain1[,card2.domain2[,...]] ]
.RB [ \-\-sector-size | \-S
.IB bytes ]
.IR bytes ]
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-keybits | \-k
.IB size ]
.IR size ]
.RB [ \-\-xts | \-x ]
.RB [ \-\-clearkey | \-c
.IB clear\-key\-file ]
.IR clear\-key\-file ]
.RB [ \-\-verbose | \-V ]
.PP
Use the
@@ -115,16 +117,16 @@ The generated secure key can either be stored in a file in the file system,
or in the secure key repository. To store the generated secure key in a
file, specify the file name with option \fIsecure\-key\-file\fP. To store the
secure key in the secure key repository, specify the name of the key using the
.B --name
.B \-\-name
option. When storing the secure key in a key repository,
additional information can be associated with a secure key using the
.B --description
.B \-\-description
,
.B --volumes
.B \-\-volumes
,
.B --apqns
.B \-\-apqns
, or the
.B --sector-size
.B \-\-sector-size
options.
.
.SS "Validating secure AES keys"
@@ -138,7 +140,7 @@ options.
.B zkey
.BR validate | val
.RB [ \-\-name | \-N
.IB key-name ]
.IR key-name ]
.RB [ \-\-verbose | \-V ]
.PP
Use the
@@ -156,10 +158,10 @@ secure key repository. To validate a secure key contained in a file, specify
the file name with option \fIsecure\-key\-file\fP. To validate secure keys
contained in the secure key repository, specify the name of the key
or a pattern containing wildcards using the
.B --name
.B \-\-name
option. When wildcards are used you must quote the value.
If neither option \fIsecure\-key\-file\fP nor option
.B --name
.B \-\-name
are specified, then all secure keys contained in the key repository
are validated.
.
@@ -171,15 +173,15 @@ are validated.
.RB [ \-\-to\-new | \-n ]
.RB [ \-\-from\-old | \-o ]
.RB [ \-\-output | \-f
.IB output\-file ]
.IR output\-file ]
.RB [ \-\-verbose | \-V ]
.PP
.B zkey
.BR reencipher | re
.RB [ \-\-name | \-N
.IB key-name ]
.IR key-name ]
.RB [ \-\-apqns | \-a
.IB card1.domain1[,card2.domain2[,...]] ]
.IR card1.domain1[,card2.domain2[,...]] ]
.RB [ \-\-to\-new | \-n ]
.RB [ \-\-from\-old | \-o ]
.RB [ \-\-in-place | \-i ]
@@ -190,7 +192,7 @@ are validated.
Use the
.B reencipher
command to re-encipher an existing secure key with a new master key.
A secure key bust be re-enciphered when the master key of the CCA
A secure key must be re-enciphered when the master key of the CCA
cryptographic adapter changes.
.PP
The CCA cryptographic adapter has three different registers to store
@@ -243,18 +245,18 @@ secure key repository. To re-encipher a secure key contained in a file,
specify the file name with option \fIsecure\-key\-file\fP. To re-encipher
secure keys contained in the secure key repository, specify the name of the key
or a pattern containing wildcards using the
.B --name
.B \-\-name
option. When wildcards are used you must quote the value.
You can also specify the
.B --apqns
.B \-\-apqns
option to re-encipher those secure
keys which are associated with the specified cryptographic adapters (APQNs).
You can use wildcards for the APQN specification.
When wildcards are used you must quote the value.
If both option
.B --name
.B \-\-name
and option
.B --apqns
.B \-\-apqns
are specified then all secure keys
contained in the key repository that match both patterns are re-enciphered.
If all both options are omitted, then all secure keys contained in the key
@@ -265,7 +267,7 @@ performed \fBin-place\fP, or in \fBstaged\fP mode.
.PP
\fB"In-place"\fP immediately replaces the secure key in the repository with
the re-enciphered secure key. Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is
performed in-place per default. You can use option \fB--in-place\fP to force an
performed in-place per default. You can use option \fB\-\-in-place\fP to force an
in-place re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case. Be aware that
a secure key that was re-enciphered in-place from \fBCURRENT\fP to \fBNEW\fP
is no longer valid, until the new CCA master key has been made the current one.
@@ -273,9 +275,9 @@ is no longer valid, until the new CCA master key has been made the current one.
\fBStaged\fP mode means that the re-enciphered secure key is stored in a
separate file in the secure key repository. Thus the current secure key is still
valid at this point. Once the new CCA master key has been set (made active), you
must rerun the reencipher command with option \fB--complete\fP to complete the
must rerun the reencipher command with option \fB\-\-complete\fP to complete the
staged re-enciphering. Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is
performed in staged mode per default. You can use option \fB--staged\fP to force
performed in staged mode per default. You can use option \fB\-\-staged\fP to force
a staged re-enciphering for the \fBOLD\fP to \fBCURRENT\fP case.
.PP
.B Note:
@@ -288,15 +290,17 @@ to be installed.
.BR import | im
.I secure\-key\-file
.B \-\-name | \-N
.IB key-name
.IR key-name
.RB [ \-\-description | \-d
.IB description ]
.IR description ]
.RB [ \-\-volumes | \-l
.IB volume1:dmname1[,volume2:dmname2[,...]] ]
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
.RB [ \-\-apqns | \-a
.IB card1.domain1[,card2.domain2[,...]] ]
.IR card1.domain1[,card2.domain2[,...]] ]
.RB [ \-\-sector-size | \-S
.IB bytes ]
.IR bytes ]
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-verbose | \-V ]
.
.PP
@@ -305,13 +309,13 @@ Use the
command to import an existing secure key contained in a file into the the
secure key repository. When importing a secure key in a key repository,
additional information can be associated with a secure key using the
.B --description
.B \-\-description
,
.B --volumes
.B \-\-volumes
,
.B --apqns
.B \-\-apqns
, or the
.B --sector-size
.B \-\-sector-size
options.
.
.SS "Export AES secure keys from the secure key repository"
@@ -320,7 +324,7 @@ options.
.BR export | ex
.I secure\-key\-file
.B \-\-name | \-N
.IB key-name
.IR key-name
.RB [ \-\-verbose | \-V ]
.
.PP
@@ -329,9 +333,8 @@ Use the
command to export an existing secure key contained in the secure key repository
to a file in the file system. Specify the name of the key that is to be exported
using the
.B --name
.B \-\-name
option. You cannot use wildcards.
When wildcards are used you must quote the value.
The exported secure key also remains in the secure key repository.
.
.SS "List AES secure keys contained in the secure key repository"
@@ -339,20 +342,22 @@ The exported secure key also remains in the secure key repository.
.B zkey
.BR list | li
.RB [ \-\-name | \-N
.IB key-name ]
.IR key-name ]
.RB [ \-\-volumes | \-l
.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
.RB [ \-\-apqns | \-a
.IB card1.domain1[,card2.domain2[,...]] ]
.IR card1.domain1[,card2.domain2[,...]] ]
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B list
command to display a list of secure keys contained in the secure key repository.
You can filter the displayed list by key name, associated volumes, and
associated cryptographic adapters (APQNs). You can use wildcards for the key
name, associated APQNs, and associated volumes. The device-mapper name of an
You can filter the displayed list by key name, associated volumes, associated
cryptographic adapters (APQNs), and volume type. You can use wildcards for the
key name, associated APQNs, and associated volumes. The device-mapper name of an
associated volume can be omitted; if it is specified then only those keys are
listed that are associated with the specified volume and device-mapper name.
.PP
@@ -361,15 +366,15 @@ The
command displays the attributes of the secure keys, such as key sizes,
whether it is a secure key that can be used for the XTS cipher mode, the textual
description, associated cryptographic adapters (APQNs) and volumes, the
sector size, and timestamps for key creation, last modification and last
re-encipherment.
sector size, the key verification pattern, and timestamps for key creation, last
modification and last re-encipherment.
.
.SS "Remove existing AES secure keys from the secure key repository"
.
.B zkey
.BR remove | rem
.B \-\-name | \-N
.IB key-name
.IR key-name
.RB [ \-\-force | \-F ]
.RB [ \-\-verbose | \-V ]
.
@@ -378,60 +383,64 @@ Use the
.B remove
command to remove an existing secure key from the secure key repository.
Specify the name of the key that is to be removed using the
.B --name
.B \-\-name
option. You cannot use wildcards. The remove command prompts for
a confirmation, unless you specify the
.B --force
.B \-\-force
option.
.PP
.B Note:
When removing a secure key that is associated with one or multiple volumes,
and the key's volume type is \fBplain\fP,
a message informs you about the associated volumes. When the secure key is
removed, these volumes can no longer be used, unless you have a backup of the
secure key.
secure key. For keys with volume type \fBluks2\fP no such message is issued,
because the secure key is contained in the LUKS2 header.
.
.SS "Change existing AES secure keys contained the secure key repository"
.
.B zkey
.BR change | ch
.B \-\-name | \-N
.IB key-name
.IR key-name
.RB [ \-\-description | \-d
.IB description ]
.IR description ]
.RB [ \-\-volumes | \-l
.IB [+|-]volume1:dmname1[,volume2:dmname2[,...]] ]
.IR [+|-]volume1:dmname1[,volume2:dmname2[,...]] ]
.RB [ \-\-apqns | \-a
.IB [+|-]card1.domain1[,card2.domain2[,...]] ]
.IR [+|-]card1.domain1[,card2.domain2[,...]] ]
.RB [ \-\-sector-size | \-S
.IB bytes ]
.IR bytes ]
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B change
command to change the description, the associated volumes, the associated
cryptographic adapters (APQNs), and the sector size of a secure key contained
in the secure key repository. Specify the name of the key that is to be changed
using the
.B --name
cryptographic adapters (APQNs), the sector size, and the volume type of a secure
key contained in the secure key repository. Specify the name of the key that is
to be changed using the
.B \-\-name
option. You cannot use wildcards.
.PP
You can set (replace), add, or
remove volume and cryptographic adapters (APQN) associations. To set
(replace) an association, specify the association with the
.B --volumes
.B \-\-volumes
or the
.B --apqns
.B \-\-apqns
options. To add an association,
specify the new association prefixed with a \fI+\fP with the
.B --volumes
.B \-\-volumes
or the
.B --apqns
.B \-\-apqns
options. To remove an association,
specify the association to remove prefixed with a \fI-\fP with the
.B --volumes
.B \-\-volumes
or the
.B --apqns
.B \-\-apqns
options. You cannot mix \fI+\fP and
\fI-\fP in one specification. You can either add or remove (or set) the
associations with one command.
@@ -447,9 +456,9 @@ command.
.B zkey
.BR rename | ren
.B \-\-name | \-N
.IB key-name
.IR key-name
.B \-\-new-name | \-w
.IB new-key-name
.IR new-key-name
.RB [ \-\-verbose | \-V ]
.
.PP
@@ -457,21 +466,30 @@ Use the
.B rename
command to rename an existing secure key in the secure key repository.
Specify the name of the key that is to be renamed using the
.B --name
.B \-\-name
option and the new name using the
.B --new-name
.B \-\-new-name
option. You cannot use wildcards.
.
.B Note:
When renaming a secure key that is associated with one or multiple volumes and
the key's volume type is \fBplain\fP, a message informs you about the
associated volumes. When the secure key is renamed, these volumes can no
longer be used, unless you change the name of the secure key in the 'cryptsetup
plainOpen' commands and in the '/etc/crypttab' entries.
For keys with volume type \fBluks2\fP no such message is issued, because the
secure key is contained in the LUKS2 header.
.
.SS "Copy (duplicate) existing AES secure keys in the secure key repository"
.
.B zkey
.B copy | co
.RB \-\-name | \-N
.IB key-name
.IR key-name
.B \-\-new-key-name | \-w
.IB new-name
.IR new-name
.RB [ \-\-volumes | \-l
.IB volume1:dmname1[,volume2:dmname2[,...]] ]
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
.RB [ \-\-verbose | \-V ]
.
.PP
@@ -479,15 +497,15 @@ Use the
.B copy
command to copy (duplicate) an existing secure key in the secure key repository.
Specify the name of the key that is to be copied using the
.B --name
.B \-\-name
option and the name of the copied key using the
.B --new-name
.B \-\-new-name
option. You cannot use wildcards.
.PP
.B Note:
When copying a secure key, the volume associations are not copied, because
a specific volume can only be associated with a single secure key. Specify the
.B --volumes
.B \-\-volumes
option to associate different
volumes with the copied secure key, or use the \fBchange\fP command to associate
volumes afterwards.
@@ -497,45 +515,56 @@ volumes afterwards.
.B zkey
.BR crypttab | cryptt
.RB [ \-\-volumes | \-l
.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B crypttab
command to generate crypttab entries using the \fBplain\fP dm-crypt mode
for volumes that are associated with secure keys contained in the secure key
repository. Specify the
.B --volumes
command to generate crypttab entries using the \fBplain\fP or \fBLUKS2\fP
dm-crypt mode for volumes that are associated with secure keys contained in the
secure key repository. Specify the
.B \-\-volumes
option to limit the list
of volumes where crypttab entries are generated for. You can use wildcards.
When wildcards are used you must quote the value.
The device-mapper name of an associated volume can be omitted; if it is
specified then only those volumes with the specified volume and device-mapper
name are selected.
Specify the
.B \-\-volume-type
option to generate crypttab entries for the specified volume type only.
.
.SS "Generate cryptsetup commands for volumes associated with secure AES keys"
.
.B zkey
.BR cryptsetup | crypts
.RB [ \-\-volumes | \-l
.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
.RB [ \-\-volume-type | \-t
.IR type ]
.RB [ \-\-run | \-r ]
.RB [ \-\-verbose | \-V ]
.
.PP
Use the
.B cryptsetup
command to generate \fBcryptsetup plainOpen\fP commands for volumes that are
associated with secure keys contained in the secure key repository. Specify the
.B --volumes
command to generate \fBcryptsetup plainOpen\fP or \fBcryptsetup luksFormat\fP
commands for volumes that are associated with secure keys contained in the
secure key repository. Specify the
.B \-\-volumes
option to limit the list
of volumes where cryptsetup commands are generated for. You can use wildcards.
When wildcards are used you must quote the value.
The device-mapper name of an associated volume can be omitted; if it is
specified then only those volumes with the specified volume and device-mapper
name are selected. Specify the
.B --run
.B \-\-volume-type
option to generate cryptsetup commands for the specified volume type only.
Specify the
.B \-\-run
option to run the generated cryptsetup commands.
.
.
@@ -589,8 +618,17 @@ This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
and in the range 512 - 4096 bytes. If omitted, the system default sector size
is used.
and in the range of 512 to 4096 bytes. If omitted, the system default sector
size is used.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume-type\~\fItype\fP
Specifies the volume type of the associated volumes used with dm-crypt. Possible
values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is used.
This option is only available if
.B zkey
has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled,
the default volume type is \fBplain\fP.
This option is only used for secure keys contained in the secure key repository.
.
.
@@ -650,7 +688,7 @@ repository is performed in staged mode. Staged mode means that the re-enciphered
secure key is stored in a separate file in the secure key repository. Thus the
current secure key is still valid at this point. Once the new CCA master key has
been set (made active), you must rerun the reencipher command with option
\fB--complete\fP to complete the staged re-enciphering.
\fB\-\-complete\fP to complete the staged re-enciphering.
Re-enciphering from CURRENT to NEW is performed in staged mode per default.
This option is only used for secure keys contained in the secure key repository.
.TP
@@ -690,8 +728,17 @@ This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
and in the range 512 - 4096 bytes. If omitted, the system default sector size
is used.
and in the range of 512 to 4096 bytes. If omitted, the system default sector
size is used.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume-type\~\fItype\fP
Specifies the volume type of the associated volumes used with dm-crypt. Possible
values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is used.
This option is only available if
.B zkey
has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled,
the default volume type is \fBplain\fP.
This option is only used for secure keys contained in the secure key repository.
.
.
@@ -734,6 +781,15 @@ APQNs. Each APQN association specifies a card and domain number separated
by a period (like lszcrypt displays it). You can use wildcards in the APQN
specification.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume-type\~\fItype\fP
Specifies the volume type of the associated volumes used with dm-crypt. Possible
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
type are listed.
This option is only available if
.B zkey
has been compiled with LUKS2 support enabled.
This option is only used for secure keys contained in the secure key repository.
.
.
.
@@ -791,9 +847,16 @@ This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
and in the range 512 - 4096 bytes. If omitted, the system default sector size
is used. Specify \fI0\fP to un-set the sector size so that the system default
is used.
and in the range of 512 to 4096 bytes. Specify \fI0\fP to set the sector size
to the system default.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume-type\~\fItype\fP
Specifies the volume type of the associated volumes used with dm-crypt. Possible
values are \fBplain\fP and \fBluks2\fP.
This option is only available if
.B zkey
has been compiled with LUKS2 support enabled.
This option is only used for secure keys contained in the secure key repository.
.
.
@@ -845,6 +908,15 @@ specified volume and device-mapper name. You can use wildcards to specify
the volumes and device-mapper names.
When wildcards are used you must quote the value.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-t ", " \-\-volume-type\~\fItype\fP
Specifies the volume type of the associated volumes used with dm-crypt. Possible
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
type are selected to generate crypttab entries for.
This option is only available if
.B zkey
has been compiled with LUKS2 support enabled.
This option is only used for secure keys contained in the secure key repository.
.
.
.
@@ -861,10 +933,18 @@ the volumes and device-mapper names.
When wildcards are used you must quote the value.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-r ", " \-\-run\fP
Runs the generated cryptsetup commands. When an execution of a cryptsetup
command fails, no further cryptsetup commands are executed, and zkey ends
with an error.
.BR \-t ", " \-\-volume-type\~\fItype\fP
Specifies the volume type of the associated volumes used with dm-crypt. Possible
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
type are selected to generate cryptsetup commands for.
This option is only available if
.B zkey
has been compiled with LUKS2 support enabled.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-r ", " \-\-run
Runs the generated cryptsetup commands. When one of the cryptsetup command fail,
no further cryptsetup commands are run, and zkey ends with an error.
This option is only used for secure keys contained in the secure key repository.
.
.
@@ -895,15 +975,20 @@ in file 'seckey.bin'.
Generates a secure AES key from the clear key in file 'clearkey.bin' and
stores it in file 'seckey.bin'.
.TP
.B zkey generate --name seckey
.B zkey generate \-\-name seckey
Generates a random 256-bit secure AES key and stores it in the secure key
repository under the name 'seckey'.
repository using the name 'seckey'.
.TP
.B zkey generate --name seckey --volumes /dev/dasdc1:encvol --apqns 03.004c
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-apqns 03.004c
Generates a random 256-bit secure AES key and stores it in the secure key
repository under the name 'seckey' and associates it with block
repository using the name 'seckey' and associates it with block
device '/dev/dasdc1' and device-mapper name 'encvol', and APQN '03.004c'.
.TP
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-volume-type luks2
Generates a random 256-bit secure AES key and stores it in the secure key
repository using the name 'seckey' and associates it with block
device '/dev/dasdc1' and device-mapper name 'encvol', and a volume type of luks2.
.TP
.B zkey reencipher seckey.bin \-\-from\-old
Re-enciphers the secure key in file 'seckey.bin' which is currently enciphered
with the master key in the OLD register with the master key in the CURRENT
@@ -915,17 +1000,17 @@ Re-enciphers the secure key in file 'seckey.bin' which is currently enciphered
with the master key in the CURRENT register with the master key in the NEW
register, and saves the re-enciphered secure key to file 'seckey2.bin'.
.TP
.B zkey reencipher --name seckey
.B zkey reencipher \-\-name seckey
Re-enciphers the secure key 'seckey' in the secure key repository.
.TP
.B zkey reencipher --apqns 03.004c
.B zkey reencipher \-\-apqns 03.004c
Re-enciphers all secure keys contained in the secure key repository that are
associated with APQN '03.004c'.
.TP
.B zkey validate seckey.bin
Validates the secure key in file 'seckey.bin' and displays its attributes.
.TP
.B zkey validate --name seckey
.B zkey validate \-\-name seckey
Validates the secure key 'seckey' in the secure key repository and displays its
attributes.
.TP
@@ -933,25 +1018,28 @@ attributes.
Lists all secure keys in the secure key repository and displays its
attributes.
.TP
.B zkey list --name '*key'
.B zkey list \-\-name '*key'
Lists all secure keys in the secure key repository with names ending with 'key'
and displays its attributes.
.TP
.B zkey change --name seckey --volumes +/dev/dasdc2:encvol2
.B zkey change \-\-name seckey \-\-volumes +/dev/dasdc2:encvol2
Changes the secure key 'seckey' in the secure key repository and adds
volume '/dev/dasdc2' with device-mapper name 'encvol2' to the list of associated
volumes of this secure key.
.TP
.B zkey change --name seckey --apqns -03.004c
.B zkey change \-\-name seckey \-\-apqns -03.004c
Changes the secure key 'seckey' in the secure key repository and removes
APQN '03.004c' from the list of associated APQNs of this secure key.
.TP
.B zkey crypttab --volumes '/dev/dasdc*'
.B zkey crypttab \-\-volumes '/dev/dasdc*'
Generates crypttab entries for all volumes that match the pattern '/dev/dasdc*'.
.TP
.B zkey cryptsetup --volumes '*:enc_dasd'
.B zkey cryptsetup \-\-volumes '*:enc_dasd'
Generates cryptsetup commands for the volumes that uses the device-mapper
name 'enc_dasd'.
.TP
.B zkey cryptsetup \-\-volume-type luks2
Generates cryptsetup commands for all volumes of type luks2.
.
.SH ENVIRONMENT
.TP

View File

@@ -68,6 +68,7 @@ static struct zkey_globals {
char *volumes;
char *apqns;
long int sector_size;
char *volume_type;
char *newname;
bool run;
bool force;
@@ -180,6 +181,16 @@ static struct util_opt opt_vec[] = {
"used",
.command = COMMAND_GENERATE,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. When this option is omitted, "
"the default is 'luks2'",
.command = COMMAND_GENERATE,
},
#endif
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -211,19 +222,23 @@ static struct util_opt opt_vec[] = {
},
{
.option = {"complete", 0, NULL, 'p'},
.desc = "Completes a pending re-enciphering of a secure AES "
"key that was re-enciphered with the master key in the "
"NEW register",
.desc = "Completes a staged re-enciphering. Use this option "
"after the new CCA master key has been set (made "
"active)",
.command = COMMAND_REENCIPHER,
},
{
.option = {"in-place", 0, NULL, 'i'},
.desc = "Forces an in-place re-enchipering of a secure AES key",
.desc = "Forces an in-place re-enchipering of a secure AES "
"key. Re-enciphering from OLD to CURRENT is performed "
"in-place per default",
.command = COMMAND_REENCIPHER,
},
{
.option = {"staged", 0, NULL, 's'},
.desc = "Forces a staged re-enchipering of a secure AES key",
.desc = "Forces that the re-enciphering of a secure AES key is "
"performed in staged mode. Re-enciphering from CURRENT "
"to NEW is performed in staged mode per default",
.command = COMMAND_REENCIPHER,
},
{
@@ -310,6 +325,16 @@ static struct util_opt opt_vec[] = {
"used",
.command = COMMAND_IMPORT,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. When this option is omitted, "
"the default is 'luks2'",
.command = COMMAND_IMPORT,
},
#endif
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -358,6 +383,16 @@ static struct util_opt opt_vec[] = {
"associated with specific crypto cards",
.command = COMMAND_LIST,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to list all "
"keys with the specified volumes type.",
.command = COMMAND_LIST,
},
#endif
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -422,11 +457,19 @@ static struct util_opt opt_vec[] = {
.option = { "sector-size", required_argument, NULL, 'S'},
.argument = "0|512|4096",
.desc = "The sector size used with dm-crypt. It must be power "
"of two and in range 512 - 4096 bytes. If this option "
"is omitted, the system default sector size (512) is "
"used",
"of two and in range 512 - 4096 bytes. Specify 0 to "
"use the system default sector size (512)",
.command = COMMAND_CHANGE,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'",
.command = COMMAND_CHANGE,
},
#endif
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -494,6 +537,17 @@ static struct util_opt opt_vec[] = {
"volume and the device-mapper name matches",
.command = COMMAND_CRYPTTAB,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to select "
"the keys by its volume type for which a crypttab "
"entry is to be generated",
.command = COMMAND_CRYPTTAB,
},
#endif
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -512,6 +566,17 @@ static struct util_opt opt_vec[] = {
"both, the volume and the device-mapper name matches",
.command = COMMAND_CRYPTSETUP,
},
#ifdef HAVE_LUKS2_SUPPORT
{
.option = { "volume-type", required_argument, NULL, 't'},
.argument = "type",
.desc = "The type of the associated volume(s). Possible values "
"are 'plain' and 'luks2'. Use this option to select "
"the keys by its volume type for which a crypttab "
"entry is to be generated",
.command = COMMAND_CRYPTSETUP,
},
#endif
{
.option = {"run", 0, NULL, 'r'},
.desc = "Runs the generated cryptsetup command",
@@ -819,7 +884,7 @@ static int command_generate_repository(void)
rc = keystore_generate_key(g.keystore, g.name, g.description, g.volumes,
g.apqns, g.sector_size, g.keybits, g.xts,
g.clearkeyfile, g.pkey_fd);
g.clearkeyfile, g.volume_type, g.pkey_fd);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1057,6 +1122,7 @@ static int command_reencipher(void)
*/
static int command_validate_file(void)
{
char vp[VERIFICATION_PATTERN_LEN];
size_t secure_key_size;
size_t clear_key_size;
u8 *secure_key;
@@ -1089,14 +1155,30 @@ static int command_validate_file(void)
goto out;
}
rc = generate_key_verification_pattern((char *)secure_key,
secure_key_size, vp, sizeof(vp),
g.verbose);
if (rc != 0) {
warnx("Failed to generate the verification pattern: %s",
strerror(-rc));
warnx("Make sure that kernel module 'paes_s390' is loaded and "
"that the 'paes' cipher is available");
rc = EXIT_FAILURE;
goto out;
}
printf("Validation of secure key in file '%s':\n", g.pos_arg);
printf(" Status: Valid\n");
printf(" Secure key size: %lu bytes\n", secure_key_size);
printf(" Clear key size: %lu bits\n", clear_key_size);
printf(" XTS type key: %s\n",
printf(" Status: Valid\n");
printf(" Secure key size: %lu bytes\n", secure_key_size);
printf(" Clear key size: %lu bits\n", clear_key_size);
printf(" XTS type key: %s\n",
secure_key_size > SECURE_KEY_SIZE ? "Yes" : "No");
printf(" Encrypted with: %s CCA master key\n",
printf(" Enciphered with: %s CCA master key\n",
is_old_mk ? "OLD" : "CURRENT");
printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2,
vp);
printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2,
&vp[VERIFICATION_PATTERN_LEN / 2]);
out:
free(secure_key);
@@ -1150,7 +1232,8 @@ static int command_import(void)
g.sector_size = 0;
rc = keystore_import_key(g.keystore, g.name, g.description, g.volumes,
g.apqns, g.sector_size, g.pos_arg);
g.apqns, g.sector_size, g.pos_arg,
g.volume_type);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1183,7 +1266,8 @@ static int command_list(void)
{
int rc;
rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns);
rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns,
g.volume_type);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1222,7 +1306,7 @@ static int command_change(void)
}
rc = keystore_change_key(g.keystore, g.name, g.description, g.volumes,
g.apqns, g.sector_size);
g.apqns, g.sector_size, g.volume_type);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1282,7 +1366,7 @@ static int command_crypttab(void)
{
int rc;
rc = keystore_crypttab(g.keystore, g.volumes);
rc = keystore_crypttab(g.keystore, g.volumes, g.volume_type);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1296,7 +1380,7 @@ static int command_cryptsetup(void)
{
int rc;
rc = keystore_cryptsetup(g.keystore, g.volumes, g.run);
rc = keystore_cryptsetup(g.keystore, g.volumes, g.run, g.volume_type);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
@@ -1473,6 +1557,11 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
break;
#ifdef HAVE_LUKS2_SUPPORT
case 't':
g.volume_type = optarg;
break;
#endif
case 'w':
g.newname = optarg;
break;

18
zpcictl/Makefile Normal file
View File

@@ -0,0 +1,18 @@
include ../common.mak
all: zpcictl
libs = $(rootdir)/libutil/libutil.a
zpcictl: zpcictl.o $(libs)
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zpcictl $(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 zpcictl.8 \
$(DESTDIR)$(MANDIR)/man8
clean:
rm -f *.o *~ zpcictl core
.PHONY: all install clean

75
zpcictl/zpcictl.8 Normal file
View File

@@ -0,0 +1,75 @@
.\" Copyright IBM Corp. 2018
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.\" Macro for inserting an option description prologue.
.\" .OD <long> [<short>] [args]
.de OD
. ds args "
. if !'\\$3'' .as args \fI\\$3\fP
. if !'\\$4'' .as args \\$4
. if !'\\$5'' .as args \fI\\$5\fP
. if !'\\$6'' .as args \\$6
. if !'\\$7'' .as args \fI\\$7\fP
. PD 0
. if !'\\$2'' .IP "\fB\-\\$2\fP \\*[args]" 4
. if !'\\$1'' .IP "\fB\-\-\\$1\fP \\*[args]" 4
. PD
..
.
.TH zpcictl 8 "Oct 2018" s390-tools zpcictl
.
.SH NAME
zpcictl - Manage PCI devices on IBM Z
.
.
.SH SYNOPSIS
.B "zpcictl"
.I "OPTIONS"
.I "DEVICE"
.
.
.SH DESCRIPTION
Use
.B zpcictl
to manage PCI devices on the IBM Z platform. In particular,
use this command to report defective PCI devices to the service element.
.B Note:
For NVMe devices additional data (such as S.M.A.R.T. data) is collected and sent
with any error handling action. For this extendend data collection, the
smartmontools must be installed.
.PP
.
.
.SH DEVICE
A PCI slot address (e.g. 0000:00:00.0) or the main device node of an NVMe
device (e.g.
.I /dev/nvme0
).
.
.
.SH OPTIONS
.SS Error Handling Options
.OD reset "" "DEVICE"
Reset and re-initialize the PCI device.
.PP
.
.OD deconfigure "" "DEVICE"
Deconfigure the PCI device and prepare for any repair action. This action
changes the status of the PCI device from configured to reserved.
.PP
.
.OD report-error "" "DEVICE"
Report any device error for the PCI device.
The device is marked as defective but no further action is taken.
.PP
.
.SS General Options
.OD help "h" ""
Print usage information, then exit.
.PP
.
.OD version "v" ""
Print version information, then exit.
.PP

402
zpcictl/zpcictl.c Normal file
View File

@@ -0,0 +1,402 @@
/*
* zpcictl - Manage PCI devices on z Systems
*
* Copyright IBM Corp. 2018
*
* 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 <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <time.h>
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/util_opt.h"
#include "lib/util_path.h"
#include "lib/util_prg.h"
#include "lib/util_proc.h"
#include "lib/util_rec.h"
#include "lib/util_scandir.h"
#include "zpcictl.h"
#define SMARTCTL_CMDLINE "smartctl -x %s 2>/dev/null"
static const struct util_prg prg = {
.desc = "Use zpcictl to manage PCI devices on IBM Z\n"
"DEVICE is the slot ID or node of the device "
"(e.g. 0000:00:00.0 or /dev/nvme0)",
.args = "DEVICE",
.copyright_vec = {
{
.owner = "IBM Corp.",
.pub_first = 2018,
.pub_last = 2018,
},
UTIL_PRG_COPYRIGHT_END
}
};
/* Defines for options with no short command */
#define OPT_RESET 128
#define OPT_DECONF 129
#define OPT_REPORT_ERR 130
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("ERROR HANDLING OPTIONS"),
{
.option = { "reset", no_argument, NULL, OPT_RESET },
.desc = "Reset the device",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "deconfigure", no_argument, NULL, OPT_DECONF },
.desc = "Deconfigure the device to prepare for any repair action",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "report-error", no_argument, NULL, OPT_REPORT_ERR },
.desc = "Report a device error to the service element (SE)",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("GENERAL OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static int is_char_dev(const char *dev)
{
struct stat s;
if (stat(dev, &s))
return 0;
return S_ISCHR(s.st_mode);
}
static int is_blk_dev(const char *dev)
{
struct stat s;
if (stat(dev, &s))
return 0;
return S_ISBLK(s.st_mode);
}
static void fopen_err(char *path)
{
warnx("Could not open file %s: %s", path, strerror(errno));
free(path);
exit(EXIT_FAILURE);
}
#define READ_CHUNK_SIZE 512
static char *collect_smart_data(struct zpci_device *pdev)
{
char *buffer = NULL;
size_t count = 0;
char *cmd;
FILE *fd;
if (!pdev->device)
return NULL;
util_asprintf(&cmd, SMARTCTL_CMDLINE, pdev->device);
fd = popen(cmd, "r");
if (!fd)
goto out;
while (!feof(fd)) {
buffer = realloc(buffer, count + READ_CHUNK_SIZE);
if (!buffer) {
warnx("Could not collect S.M.A.R.T. data");
goto out;
}
count += fread(&buffer[count], 1, READ_CHUNK_SIZE, fd);
if (ferror(fd)) {
free(buffer);
buffer = NULL;
goto out;
}
}
buffer = realloc(buffer, count);
if (!buffer && count > 0)
warnx("Could not collect S.M.A.R.T. data");
if (buffer)
buffer[count] = '\0';
out:
pclose(fd);
free(cmd);
return buffer;
}
static unsigned int sysfs_read_value(struct zpci_device *pdev, const char *attr)
{
unsigned int val;
char *path;
FILE *fp;
path = util_path_sysfs("bus/pci/devices/%s/%s", pdev->slot, attr);
fp = fopen(path, "r");
if (!fp)
fopen_err(path);
fscanf(fp, "%x", &val);
fclose(fp);
free(path);
return val;
}
static void sysfs_write_data(struct zpci_report_error *report, char *slot)
{
size_t r_size;
char *path;
FILE *fp;
r_size = sizeof(*report);
path = util_path_sysfs("bus/pci/devices/%s/report_error", slot);
fp = fopen(path, "w");
if (!fp)
fopen_err(path);
if (fwrite(report, 1, r_size, fp) != r_size)
warnx("Could not write to file: %s: %s", path, strerror(errno));
if (fclose(fp))
warnx("Could not close file: %s: %s", path, strerror(errno));
free(path);
}
/* lstat() doesn't work for sysfs files, so we have to work with a fixed size */
#define READLINK_SIZE 256
static int sysfs_get_slot_addr(const char *dev, char *slot)
{
char device[READLINK_SIZE], *result;
unsigned int major, minor;
struct stat dev_stat;
ssize_t len;
char *path;
if (stat(dev, &dev_stat) != 0) {
warnx("Could not get stat information for %s: %s",
dev, strerror(errno));
return 0;
}
major = major(dev_stat.st_rdev);
minor = minor(dev_stat.st_rdev);
path = util_path_sysfs("dev/char/%u:%u/device", major, minor);
len = readlink(path, device, READLINK_SIZE - 1);
free(path);
if (len != -1) {
device[len] = '\0';
} else {
warnx("Could not read device link for %s", dev);
return 0;
}
result = strrchr(device, '/');
if (result)
result++;
else
result = device;
strcpy(slot, result);
return 1;
}
static void get_device_node(struct zpci_device *pdev)
{
struct dirent **de_vec;
char *path, *dev;
char slot[13];
int count, i;
path = util_path_sysfs("bus/pci/devices/%s/nvme", pdev->slot);
count = util_scandir(&de_vec, alphasort, path, "nvme*");
if (count == -1) {
warnx("Could not read directory %s: %s", path, strerror(errno));
free(path);
return;
}
for (i = 0; i < count; i++) {
util_asprintf(&dev, "/dev/%s", de_vec[i]->d_name);
if (!sysfs_get_slot_addr(dev, slot))
continue;
if (strcmp(slot, pdev->slot) == 0) {
pdev->device = dev;
break;
}
}
util_scandir_free(de_vec, count);
free(path);
}
static int device_exists(char *dev)
{
char *path;
int rc = 0;
path = util_path_sysfs("bus/pci/devices/%s", dev);
if (util_path_exists(path) || util_path_exists(dev))
rc = 1;
free(path);
return rc;
}
static void get_device_info(struct zpci_device *pdev, char *dev)
{
if (!device_exists(dev))
errx(EXIT_FAILURE, "Could not find device %s", dev);
if (is_blk_dev(dev))
errx(EXIT_FAILURE, "Unsupported device type %s", dev);
if (is_char_dev(dev)) {
if (!sysfs_get_slot_addr(dev, pdev->slot))
errx(EXIT_FAILURE,
"Could not determine slot address for %s", dev);
pdev->device = dev;
} else {
strcpy(pdev->slot, dev);
}
pdev->class = sysfs_read_value(pdev, "class");
pdev->fid = sysfs_read_value(pdev, "function_id");
pdev->pchid = sysfs_read_value(pdev, "pchid");
/*
* In case a slot address was specified, the device node for NVMe
* devices is still needed. Otherwise it won't be possible to collect
* S.M.A.R.T. data at a later point.
*/
if (!pdev->device && pdev->class == PCI_CLASS_NVME)
get_device_node(pdev);
}
/*
* Issue an SCLP Adapter Error Notification event with a specific action
* qualifier.
*
* Collect additional information when possible (e.g. S.M.A.R.T. data for NVMe
* devices).
*/
static void sclp_issue_action(struct zpci_device *pdev, int action)
{
struct zpci_report_error report = {
.header = { 0 },
.data = { 0 }
};
char *sdata = NULL;
report.header.version = 1;
report.header.action = action;
report.header.length = sizeof(report.data);
report.data.timestamp = (__u64)time(NULL);
report.data.err_log_id = 0x4713;
if (pdev->class == PCI_CLASS_NVME)
sdata = collect_smart_data(pdev);
if (sdata) {
strncpy(report.data.log_data, sdata, sizeof(report.data.log_data));
free(sdata);
}
sysfs_write_data(&report, pdev->slot);
}
/*
* Reset the PCI device and initiate a re-initialization.
*/
static void sclp_reset_device(struct zpci_device *pdev)
{
sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_RESET);
}
/*
* De-Configure/repair PCI device. Moves the device from configured
* to reserved state.
*/
static void sclp_deconfigure(struct zpci_device *pdev)
{
sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_DECONF);
}
/*
* Report an error to the SE.
*/
static void sclp_report_error(struct zpci_device *pdev)
{
sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_REPORT_ERR);
}
static void parse_cmdline(int argc, char *argv[], struct options *opts)
{
int cmd;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
do {
cmd = util_opt_getopt_long(argc, argv);
switch (cmd) {
case OPT_RESET:
opts->reset = 1;
break;
case OPT_DECONF:
opts->deconfigure = 1;
break;
case OPT_REPORT_ERR:
opts->report = 1;
break;
case 'h':
util_prg_print_help();
util_opt_print_help();
exit(EXIT_SUCCESS);
case 'v':
util_prg_print_version();
exit(EXIT_SUCCESS);
case -1:
/* End of options string */
if (argc == 1) {
errx(EXIT_FAILURE,
"Use '%s --help' for more information",
argv[0]);
}
break;
}
} while (cmd != -1);
}
int main(int argc, char *argv[])
{
struct zpci_device pdev = { 0 };
struct options opts = { 0 };
parse_cmdline(argc, argv, &opts);
if (optind >= argc)
errx(EXIT_FAILURE, "No device specified");
get_device_info(&pdev, argv[optind]);
if (opts.reset)
sclp_reset_device(&pdev);
else if (opts.deconfigure)
sclp_deconfigure(&pdev);
else if (opts.report)
sclp_report_error(&pdev);
return 0;
}

60
zpcictl/zpcictl.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* zpcictl - Manage PCI devices on z Systems
*
* Copyright IBM Corp. 2018
*
* 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 ZPCICTL_H
#define ZPCICTL_H
#include <linux/types.h>
#include "lib/zt_common.h"
#define SCLP_ERRNOTIFY_AQ_RESET 0
#define SCLP_ERRNOTIFY_AQ_DECONF 1
#define SCLP_ERRNOTIFY_AQ_REPORT_ERR 2
#define PCI_CLASS_UNCLASSIFIED 0x000000U
#define PCI_CLASS_NVME 0x010802U
#define PCI_CLASS_NETWORK 0x020000U
struct options {
unsigned int reset;
unsigned int deconfigure;
unsigned int report;
};
struct zpci_device {
u16 fid;
u16 pchid;
u32 class;
char slot[13];
char *device;
};
struct zpci_report_error_header {
__u8 version; /* Interface version byte */
__u8 action; /* Action qualifier byte
* 0: Adapter Reset Request
* 1: Deconfigure and repair action requested
* 2: Informational Report
*/
__u16 length; /* Length of Subsequent Data (up to 4K SCLP header) */
__u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */
};
struct zpci_report_error_data {
__u64 timestamp;
__u64 err_log_id;
char log_data[4054]; /* We cannot exceed a total of 4074 bytes (header + data) */
};
struct zpci_report_error {
struct zpci_report_error_header header;
struct zpci_report_error_data data;
} __packed;
#endif /* ZPCICTL_H */