mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
144 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bb9a9ec5b | |||
| 4a3957fab5 | |||
| e506c94839 | |||
| dfd9f52873 | |||
| 14ca7c5080 | |||
| 4fc1a92a8d | |||
| d73d7f91ac | |||
| 800df6bef8 | |||
| 3c661da4ee | |||
| bf5ca4367d | |||
| faf26220a7 | |||
| 522252d18a | |||
| 42889edc0c | |||
| 13016ebc5a | |||
| c4546daf34 | |||
| 1e18429f69 | |||
| 11e78cada5 | |||
| 0a7df9e030 | |||
| 7dd03eaeec | |||
| 663262c962 | |||
| bf9482709f | |||
| cdf0b5d66f | |||
| 4aafd6962a | |||
| 863e1c3fa4 | |||
| 7c47ea8e09 | |||
| c239d99379 | |||
| 6c6e3a2b0e | |||
| 2dca5d193f | |||
| 75675ec627 | |||
| 18bf2cce06 | |||
| 8781dd3e7b | |||
| 6380e77f28 | |||
| 733b86c02a | |||
| 7827a791c9 | |||
| 074de1e14e | |||
| 07d181e29b | |||
| 895a88b2f8 | |||
| f01f8b240c | |||
| be2bc610b7 | |||
| c48d45ba92 | |||
| 886476a207 | |||
| 86685f001d | |||
| d619b492e9 | |||
| 79e4798061 | |||
| cf2311f1f1 | |||
| 7e832da790 | |||
| 3b402a0630 | |||
| 3437c9bb90 | |||
| 8898650266 | |||
| 3ae2100d5e | |||
| 93e4249fd3 | |||
| 8ec4705239 | |||
| cad450fdf9 | |||
| 3a1cda59ce | |||
| 0566a492ae | |||
| bc7359d2a3 | |||
| db6f272607 | |||
| 6db7fbe018 | |||
| 2f154fa49d | |||
| 148d3f9b64 | |||
| 702dc96264 | |||
| 313092b202 | |||
| b098990abe | |||
| 6802b86414 | |||
| aa8c2945cc | |||
| fa7a4dafa3 | |||
| 7eb04cdc54 | |||
| d55b787d05 | |||
| da4fdeeb82 | |||
| 9fe491df27 | |||
| 732b3dddab | |||
| cb76e39cef | |||
| 09be935c54 | |||
| 65e18bff67 | |||
| 07ab32fa8b | |||
| 353403824b | |||
| 8a58389e2f | |||
| f2cc871b02 | |||
| 4dbdc8dfab | |||
| 60900de5e9 | |||
| 2bba362e9a | |||
| 76044be98d | |||
| 885ff0a03f | |||
| 25968033bb | |||
| 1e746990c0 | |||
| 3002e7f754 | |||
| ea10995f4d | |||
| 8b31319ddf | |||
| 1df4d66387 | |||
| 37348ef662 | |||
| 644432ba23 | |||
| 6eddae9a8a | |||
| d19f0915c3 | |||
| 0ecf18b66d | |||
| 26c544998e | |||
| edaa72d68a | |||
| 041e3ad996 | |||
| 301eece09b | |||
| 36bd05c4ba | |||
| 8aa3f064af | |||
| 48a7da096d | |||
| 094f52d604 | |||
| 0626dc7a72 | |||
| 0180054d07 | |||
| 800fe15d21 | |||
| c570f51f5f | |||
| 57b70a0fe0 | |||
| cc0d030ce9 | |||
| 9dce6793ab | |||
| d8054d1a1a | |||
| 5a9c381225 | |||
| 3c6890317a | |||
| 1c42b9e3e4 | |||
| beb6a1d6fd | |||
| 40e4b71159 | |||
| 8c0f2491a3 | |||
| e44ae22989 | |||
| 3be8be4ac7 | |||
| 544c88ca39 | |||
| c7afb5baec | |||
| cc9b202a9b | |||
| 9f99706c26 | |||
| 8137128a96 | |||
| 1cdfb4946e | |||
| 5fb30f1e6f | |||
| d8089e69fa | |||
| cbf7f02d69 | |||
| 91b1692b16 | |||
| cd8a733c82 | |||
| bcce1e8d18 | |||
| f832428109 | |||
| 1d7bb283fd | |||
| a2f14fcfd7 | |||
| bb6a47db55 | |||
| 35dd59d04c | |||
| 3fa511cfb9 | |||
| c6c4df9697 | |||
| 1b0ab844b4 | |||
| 92fc94f152 | |||
| f25aaf32b8 | |||
| 13f8709ec2 | |||
| 6a860a01c3 | |||
| 131a910ac5 | |||
| 7007937456 |
+14
-6
@@ -34,6 +34,11 @@ iucvterm/src/iucvconn
|
|||||||
iucvterm/src/iucvtty
|
iucvterm/src/iucvtty
|
||||||
iucvterm/src/ttyrun
|
iucvterm/src/ttyrun
|
||||||
iucvterm/test/test_afiucv
|
iucvterm/test/test_afiucv
|
||||||
|
libekmfweb/check-dep-libekmfweb
|
||||||
|
libekmfweb/detect-openssl-version.dep
|
||||||
|
libekmfweb/libekmfweb.so
|
||||||
|
libekmfweb/libekmfweb.so.1
|
||||||
|
libekmfweb/libekmfweb.so.1.0
|
||||||
libutil/util_base_example
|
libutil/util_base_example
|
||||||
libutil/util_file_example
|
libutil/util_file_example
|
||||||
libutil/util_libc_example
|
libutil/util_libc_example
|
||||||
@@ -44,8 +49,9 @@ libutil/util_path_example
|
|||||||
libutil/util_prg_example
|
libutil/util_prg_example
|
||||||
libutil/util_rec_example
|
libutil/util_rec_example
|
||||||
libutil/util_scandir_example
|
libutil/util_scandir_example
|
||||||
libzds/libzds.a
|
|
||||||
libvmcp/vmcp_example
|
libvmcp/vmcp_example
|
||||||
|
libzds/libzds.a
|
||||||
|
lsstp/lsstp
|
||||||
mon_tools/mon_fsstatd
|
mon_tools/mon_fsstatd
|
||||||
mon_tools/mon_procd
|
mon_tools/mon_procd
|
||||||
osasnmpd/osasnmpd
|
osasnmpd/osasnmpd
|
||||||
@@ -75,10 +81,10 @@ zdev/src/lszdev
|
|||||||
zdev/src/lszdev_usage.c
|
zdev/src/lszdev_usage.c
|
||||||
zdsfs/zdsfs
|
zdsfs/zdsfs
|
||||||
zdump/zgetdump
|
zdump/zgetdump
|
||||||
zfcpdump/cpioinit
|
|
||||||
zfcpdump/zfcpdump_part
|
|
||||||
zfcpdump/zfcpdump-initrd
|
|
||||||
zfcpdump/10-zfcpdump.install
|
zfcpdump/10-zfcpdump.install
|
||||||
|
zfcpdump/cpioinit
|
||||||
|
zfcpdump/zfcpdump-initrd
|
||||||
|
zfcpdump/zfcpdump_part
|
||||||
ziomon/ziomon_mgr
|
ziomon/ziomon_mgr
|
||||||
ziomon/ziomon_util
|
ziomon/ziomon_util
|
||||||
ziomon/ziomon_zfcpdd
|
ziomon/ziomon_zfcpdd
|
||||||
@@ -90,9 +96,11 @@ zipl/boot/data.h
|
|||||||
zipl/src/chreipl_helper.device-mapper
|
zipl/src/chreipl_helper.device-mapper
|
||||||
zipl/src/zipl
|
zipl/src/zipl
|
||||||
zipl/src/zipl_helper.device-mapper
|
zipl/src/zipl_helper.device-mapper
|
||||||
zkey/zkey
|
|
||||||
zkey/zkey-cryptsetup
|
|
||||||
zkey/check-dep-zkey
|
zkey/check-dep-zkey
|
||||||
zkey/check-dep-zkey-cryptsetup
|
zkey/check-dep-zkey-cryptsetup
|
||||||
zkey/detect-libcryptsetup.dep
|
zkey/detect-libcryptsetup.dep
|
||||||
|
zkey/ekmfweb/libekmfweb.dep
|
||||||
|
zkey/ekmfweb/zkey-ekmfweb.so
|
||||||
|
zkey/zkey
|
||||||
|
zkey/zkey-cryptsetup
|
||||||
zpcictl/zpcictl
|
zpcictl/zpcictl
|
||||||
|
|||||||
@@ -9,16 +9,19 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Arnd Bergmann
|
- Arnd Bergmann
|
||||||
- Axel Wirbser
|
- Axel Wirbser
|
||||||
- Benjamin Block
|
- Benjamin Block
|
||||||
|
- Brian C. Lane
|
||||||
- Carsten Otte
|
- Carsten Otte
|
||||||
- Christian Borntraeger
|
- Christian Borntraeger
|
||||||
- Christian Ehrhardt
|
- Christian Ehrhardt
|
||||||
- Christof Schmitt
|
- Christof Schmitt
|
||||||
- Claudio Imbrenda
|
- Claudio Imbrenda
|
||||||
- Clemens von Mann
|
- Clemens von Mann
|
||||||
|
- Colin Walters
|
||||||
- Dan Horak
|
- Dan Horak
|
||||||
- Despina Papadopoulou
|
- Despina Papadopoulou
|
||||||
- Dimitri John Ledkov
|
- Dimitri John Ledkov
|
||||||
- Eberhard Pasch
|
- Eberhard Pasch
|
||||||
|
- Eduard Shishkin
|
||||||
- Einar Lueck
|
- Einar Lueck
|
||||||
- Eric Sandeen
|
- Eric Sandeen
|
||||||
- Erwin Vicari
|
- Erwin Vicari
|
||||||
@@ -74,11 +77,13 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Michael Mueller
|
- Michael Mueller
|
||||||
- Mijo Safradin
|
- Mijo Safradin
|
||||||
- Mikhail Zaslonko
|
- Mikhail Zaslonko
|
||||||
|
- Nikita Dubrovskii
|
||||||
- Niklas Schnelle
|
- Niklas Schnelle
|
||||||
- Peter Oberparleiter
|
- Peter Oberparleiter
|
||||||
- Peter Tiedemann
|
- Peter Tiedemann
|
||||||
- Philipp Kern
|
- Philipp Kern
|
||||||
- Philipp Rudo
|
- Philipp Rudo
|
||||||
|
- Prashanth Sundararaman
|
||||||
- Rafael Fonseca
|
- Rafael Fonseca
|
||||||
- Raimund Schroeder
|
- Raimund Schroeder
|
||||||
- Ralph Wuerthner
|
- Ralph Wuerthner
|
||||||
@@ -97,6 +102,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Steffen Maier
|
- Steffen Maier
|
||||||
- Steffen Thoss
|
- Steffen Thoss
|
||||||
- Susanne Wintenberger
|
- Susanne Wintenberger
|
||||||
|
- Sven Schnelle
|
||||||
- Sven Schuetz
|
- Sven Schuetz
|
||||||
- Swen Schillig
|
- Swen Schillig
|
||||||
- Taraka R. Bodireddy
|
- Taraka R. Bodireddy
|
||||||
@@ -107,7 +113,10 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Tuan Hoang
|
- Tuan Hoang
|
||||||
- Ursula Braun
|
- Ursula Braun
|
||||||
- Utz Bacher
|
- Utz Bacher
|
||||||
|
- Vance Morris
|
||||||
- Vasily Gorbik
|
- Vasily Gorbik
|
||||||
- Viktor Mihajlovski
|
- Viktor Mihajlovski
|
||||||
|
- Vineeth Vijayan
|
||||||
- Volker Sameske
|
- Volker Sameske
|
||||||
|
- Wenjia Zhang
|
||||||
- Wolfgang Taphorn
|
- Wolfgang Taphorn
|
||||||
|
|||||||
@@ -1,5 +1,79 @@
|
|||||||
Release history for s390-tools (MIT version)
|
Release history for s390-tools (MIT version)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
* __v2.16.0 (2021-02-19)__
|
||||||
|
|
||||||
|
For Linux kernel version: 5.10 / 5.11
|
||||||
|
|
||||||
|
Add new tool:
|
||||||
|
- hsci: New tool to manage HSCI (HiperSockets Converged Interfaces)
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- genprotimg: Add host-key document verification support
|
||||||
|
- genprotimg: boot: Make boot loader -march=z900 compatible
|
||||||
|
- libekmfweb: Make install directory for shared libraries configurable
|
||||||
|
- lsdasd: Add FC Endpoint Security information
|
||||||
|
- make: Add address sanitizer support
|
||||||
|
- netboot: Add version information to scripts
|
||||||
|
- netboot: Bump busybox version in pxelinux.0 build
|
||||||
|
- zdev: Add FC Endpoint Security information for DASD devices
|
||||||
|
- zdev: Add build option to update initial RAM-disk by default
|
||||||
|
- zkey-ekmfweb: Avoid sequence number clash when generating keys
|
||||||
|
- zkey/zkey-ekmfweb: Install KMS plugins into configurable location
|
||||||
|
- zkey: Add support to store LUKS2 dummy passphrase in key repository
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- dasdfmt: Fix segfault when an incorrect option is specified
|
||||||
|
- genprotimg: Fix several build issues
|
||||||
|
- genprotimg: Require argument for 'ramdisk' and 'parmfile' options
|
||||||
|
- zcryptstats: Fix handling of partial results with many domains
|
||||||
|
- zfcpdbf: Deal with crash 7.2.9 change in caller name formatting
|
||||||
|
- zipl/boot: Fix memory use after free in stage2
|
||||||
|
- zipl/boot: Fix potential heap overflow in stage2
|
||||||
|
- zipl: Fix reading 4k disk's geometry
|
||||||
|
|
||||||
|
* __v2.15.1 (2020-10-28)__
|
||||||
|
|
||||||
|
For Linux kernel version: 5.9
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- lsstp: Improve wording and fix typos in man page
|
||||||
|
- zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
|
||||||
|
- zkey: Add library versioning for libekmfweb and zkey-ekmfweb
|
||||||
|
- libutil: Add function to determine base device of a partition block device
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- dasdfmt: Fix bad file descriptor error when running on symlinks
|
||||||
|
- libdasd: Fix dasd_get_host_access_count()
|
||||||
|
- zipl: Fix multivolume dump
|
||||||
|
- zgetdump: Fix device node determination via sysfs to work with multivolume again
|
||||||
|
- genprotimg/boot: Fix build by disabling SSP
|
||||||
|
- zipl/boot: Fix build by disabling SSP
|
||||||
|
|
||||||
|
* __v2.15.0 (2020-10-15)__
|
||||||
|
|
||||||
|
For Linux kernel version: 5.9
|
||||||
|
|
||||||
|
Add new tool:
|
||||||
|
- lsstp: A small utility to display the Server Time Protocol (STP) information present in sysfs
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- dumpconf: support NVMe dump/reipl device
|
||||||
|
- ipl_tools: support clear attribute for nvme re-IPL
|
||||||
|
- zcrypt: Support new config state with lszcrypt and chzcrypt
|
||||||
|
- zkey: Add support for key management system plugins
|
||||||
|
including the KMS commands:
|
||||||
|
bind, unbind, info, configure, rencipher, list, import, refresh
|
||||||
|
- zkey: Add EKMFWeb support to remotely generate secure keys
|
||||||
|
- libekmfweb: Add new EKMFWeb client library
|
||||||
|
- libutil: Add util_file_read_va()
|
||||||
|
- libutil: Add util_file_read_i()/util_file_read_ui()
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- cpumf: Fix version and help printout when CPUMF is not installed
|
||||||
|
- ziomon/ziorep_printers: fix virtual adapter CSV output
|
||||||
|
- zipl: Fix Error when title is not the first field in BLS file
|
||||||
|
|
||||||
|
|
||||||
* __v2.14.0 (2020-08-21)__
|
* __v2.14.0 (2020-08-21)__
|
||||||
|
|
||||||
For Linux kernel version: 5.7 / 5.8
|
For Linux kernel version: 5.7 / 5.8
|
||||||
|
|||||||
+4
-4
@@ -72,7 +72,7 @@ In the examples below we use this fictive identity:
|
|||||||
### Setup GitHub and local git
|
### Setup GitHub and local git
|
||||||
|
|
||||||
1. Create a fork of this repository by clicking the `Fork` button on the top
|
1. Create a fork of this repository by clicking the `Fork` button on the top
|
||||||
right of the [s390-tools](https://github.com/ibm-s390-tools/s390-tools)
|
right of the [s390-tools](https://github.com/ibm-s390-linux/s390-tools)
|
||||||
main page
|
main page
|
||||||
|
|
||||||
2. Clone your forked repository to your local development system
|
2. Clone your forked repository to your local development system
|
||||||
@@ -84,7 +84,7 @@ In the examples below we use this fictive identity:
|
|||||||
s390-tools repository on GitHub
|
s390-tools repository on GitHub
|
||||||
```
|
```
|
||||||
$ cd s390-tools
|
$ cd s390-tools
|
||||||
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-tools/s390-tools.git
|
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-linux/s390-tools.git
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Verify your remotes
|
4. Verify your remotes
|
||||||
@@ -92,8 +92,8 @@ In the examples below we use this fictive identity:
|
|||||||
~/s390-tools $ git remote -v
|
~/s390-tools $ git remote -v
|
||||||
origin https://github.com/random-developer/s390-tools.git (fetch)
|
origin https://github.com/random-developer/s390-tools.git (fetch)
|
||||||
origin https://github.com/random-developer/s390-tools.git (push)
|
origin https://github.com/random-developer/s390-tools.git (push)
|
||||||
upstream https://github.com/ibm-s390-tools/s390-tools.git (fetch)
|
upstream https://github.com/ibm-s390-linux/s390-tools.git (fetch)
|
||||||
upstream https://github.com/ibm-s390-tools/s390-tools.git (push)
|
upstream https://github.com/ibm-s390-linux/s390-tools.git (push)
|
||||||
```
|
```
|
||||||
You now have two remotes: The "origin" remote points to your fork
|
You now have two remotes: The "origin" remote points to your fork
|
||||||
and the "upstream" remote to the official s390-tools repository.
|
and the "upstream" remote to the official s390-tools repository.
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
|
|||||||
# Include common definitions
|
# Include common definitions
|
||||||
include common.mak
|
include common.mak
|
||||||
|
|
||||||
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp
|
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp libekmfweb
|
||||||
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||||
genprotimg
|
genprotimg lsstp hsci
|
||||||
|
|
||||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,15 @@ Package contents
|
|||||||
Provides simple tools to create a binary that can be used to implement
|
Provides simple tools to create a binary that can be used to implement
|
||||||
simple network boot setups following the PXELINUX conventions.
|
simple network boot setups following the PXELINUX conventions.
|
||||||
|
|
||||||
|
* libekmfweb:
|
||||||
|
A shared library that provides functions to communicate with an EKMF Web
|
||||||
|
server via REST calls over HTTPS. EKMF Web stands for IBM Enterprise Key
|
||||||
|
Management Foundation - Web Edition, and is used to manage keys in an
|
||||||
|
enterprise.
|
||||||
|
|
||||||
|
* hsci:
|
||||||
|
Manage HiperSockets Converged Interfaces (HSCI).
|
||||||
|
|
||||||
For more information refer to the following publications:
|
For more information refer to the following publications:
|
||||||
|
|
||||||
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
|
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
|
||||||
@@ -267,17 +276,19 @@ build options:
|
|||||||
| pfm | `HAVE_PFM` | cpacfstats |
|
| pfm | `HAVE_PFM` | cpacfstats |
|
||||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||||
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
||||||
| openssl | `HAVE_OPENSSL` | genprotimg,zkey |
|
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb |
|
||||||
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
||||||
| json-c | `HAVE_JSONC` | zkey-cryptsetup |
|
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb |
|
||||||
| glib2 | `HAVE_GLIB2` | genprotimg |
|
| glib2 | `HAVE_GLIB2` | genprotimg |
|
||||||
|
| libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb |
|
||||||
|
|
||||||
This table lists additional build or install options:
|
This table lists additional build or install options:
|
||||||
|
|
||||||
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|
||||||
|----------------|:----------------:|:-------------------------------:|
|
|------------------|:----------------------------:|:--------------:|
|
||||||
| dracut | `HAVE_DRACUT` | zdev |
|
| dracut | `HAVE_DRACUT` | zdev |
|
||||||
| initramfs-tools| `HAVE_INITRAMFS` | zdev |
|
| initramfs-tools | `HAVE_INITRAMFS` | zdev |
|
||||||
|
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
|
||||||
|
|
||||||
The s390-tools build process uses "pkg-config" if available and hard-coded
|
The s390-tools build process uses "pkg-config" if available and hard-coded
|
||||||
compiler and linker options otherwise.
|
compiler and linker options otherwise.
|
||||||
@@ -368,6 +379,17 @@ the different tools are provided:
|
|||||||
Distributors with different boot or RAM-disk mechanisms should provide
|
Distributors with different boot or RAM-disk mechanisms should provide
|
||||||
a custom zdev-root-update helper script.
|
a custom zdev-root-update helper script.
|
||||||
|
|
||||||
|
- `ZDEV_ALWAYS_UPDATE_INITRD=1` upon modification of any persistent device
|
||||||
|
configuration, chzdev updates the initial RAM-disk by default, without any
|
||||||
|
additional user interaction.
|
||||||
|
|
||||||
|
For some distributions, all the configuration attributes must be copied to
|
||||||
|
the initial RAM-disk. Because the device configuration directives applied
|
||||||
|
in the initial RAM-disk takes precedence over those stored in the root file-
|
||||||
|
system. This copying is done usually by explicitly invoking a command. This
|
||||||
|
build option makes it user-friendly and does this copying without any manual
|
||||||
|
intervention.
|
||||||
|
|
||||||
Some functions of zdev require that the following programs are available:
|
Some functions of zdev require that the following programs are available:
|
||||||
|
|
||||||
- modprobe (kmod)
|
- modprobe (kmod)
|
||||||
@@ -397,3 +419,11 @@ the different tools are provided:
|
|||||||
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
|
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
|
||||||
for this group.
|
for this group.
|
||||||
|
|
||||||
|
* libekmfweb:
|
||||||
|
For building the libekmfweb shared library you need openssl version 1.1.1 or
|
||||||
|
newer installed (openssl-devel.rpm). Also required are json-c version 0.13 or
|
||||||
|
newer (json-c-devel.rpm), and libcurl version 7.59 or newer
|
||||||
|
(libcurl-devel.rpm).
|
||||||
|
Tip: you may skip the libekmfweb build by adding `HAVE_OPENSSL=0`,
|
||||||
|
`HAVE_JSONC=0`, or `HAVE_LIBCURL=0` to the make invocation.
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ static unsigned long dec_to_hex(unsigned long long num)
|
|||||||
{
|
{
|
||||||
unsigned long res;
|
unsigned long res;
|
||||||
|
|
||||||
asm volatile("cvb %0,%1" : "=d" (res) : "m" (num));
|
asm volatile("cvb %0,%1" : "=d" (res) : "Q" (num));
|
||||||
return res & 0xffffffff;
|
return res & 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ static unsigned int hex_to_dec(unsigned int num)
|
|||||||
{
|
{
|
||||||
unsigned long long res;
|
unsigned long long res;
|
||||||
|
|
||||||
asm volatile("cvd %1,%0" : "=m" (res) : "d" (num));
|
asm volatile("cvd %1,%0" : "=Q" (res) : "d" (num));
|
||||||
return res & 0xffffffff;
|
return res & 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2050,7 +2050,7 @@ static int update_dir_levels(int blocks)
|
|||||||
if (blocks < 2)
|
if (blocks < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (blocks / (PTRS_PER_BLOCK + 1)) {
|
while (blocks / PTRS_PER_BLOCK) {
|
||||||
levels++;
|
levels++;
|
||||||
blocks /= PTRS_PER_BLOCK;
|
blocks /= PTRS_PER_BLOCK;
|
||||||
}
|
}
|
||||||
@@ -3103,7 +3103,7 @@ static void update_levels(struct file *f)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (blocks / (per_block + 1)) {
|
while (blocks / per_block) {
|
||||||
levels++;
|
levels++;
|
||||||
blocks /= per_block;
|
blocks /= per_block;
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-5
@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
|
|||||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
RELEASE = 14
|
RELEASE = 16
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 0
|
||||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
@@ -106,6 +106,11 @@ endif
|
|||||||
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
||||||
DEFAULT_LDFLAGS = -rdynamic
|
DEFAULT_LDFLAGS = -rdynamic
|
||||||
|
|
||||||
|
ifeq ("${ASAN}","1")
|
||||||
|
DEFAULT_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||||
|
DEFAULT_LDFLAGS += -fsanitize=address
|
||||||
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for build dependency
|
# Check for build dependency
|
||||||
#
|
#
|
||||||
@@ -163,6 +168,7 @@ USRSBINDIR = $(INSTALLDIR)/usr/sbin
|
|||||||
USRBINDIR = $(INSTALLDIR)/usr/bin
|
USRBINDIR = $(INSTALLDIR)/usr/bin
|
||||||
BINDIR = $(INSTALLDIR)/sbin
|
BINDIR = $(INSTALLDIR)/sbin
|
||||||
LIBDIR = $(INSTALLDIR)/lib
|
LIBDIR = $(INSTALLDIR)/lib
|
||||||
|
USRLIB64DIR = $(INSTALLDIR)/usr/lib64
|
||||||
SYSCONFDIR = $(INSTALLDIR)/etc
|
SYSCONFDIR = $(INSTALLDIR)/etc
|
||||||
MANDIR = $(INSTALLDIR)/usr/share/man
|
MANDIR = $(INSTALLDIR)/usr/share/man
|
||||||
VARDIR = $(INSTALLDIR)/var
|
VARDIR = $(INSTALLDIR)/var
|
||||||
@@ -172,14 +178,24 @@ ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
|
|||||||
# Systemd support files are installed only if a directory is specified
|
# Systemd support files are installed only if a directory is specified
|
||||||
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
|
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
|
||||||
SYSTEMDSYSTEMUNITDIR =
|
SYSTEMDSYSTEMUNITDIR =
|
||||||
|
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
|
||||||
|
ZKEYKMSPLUGINDIR = $(USRLIB64DIR)/zkey
|
||||||
|
|
||||||
|
ifeq ($(LIBDIR),$(INSTALLDIR)/lib)
|
||||||
|
SOINSTALLDIR = $(USRLIB64DIR)
|
||||||
|
else
|
||||||
|
SOINSTALLDIR = $(LIBDIR)
|
||||||
|
endif
|
||||||
|
|
||||||
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
|
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
|
||||||
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
|
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
|
||||||
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
|
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
|
||||||
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR)
|
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) \
|
||||||
|
$(USRLIB64DIR) $(USRINCLUDEDIR) $(ZKEYKMSPLUGINDIR) \
|
||||||
|
$(SOINSTALLDIR)
|
||||||
OWNER = $(shell id -un)
|
OWNER = $(shell id -un)
|
||||||
GROUP = $(shell id -gn)
|
GROUP = $(shell id -gn)
|
||||||
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
|
export INSTALLDIR BINDIR LIBDIR USRLIB64DIR MANDIR OWNER GROUP
|
||||||
|
|
||||||
# Special defines for zfcpdump
|
# Special defines for zfcpdump
|
||||||
ZFCPDUMP_IMAGE = zfcpdump-image
|
ZFCPDUMP_IMAGE = zfcpdump-image
|
||||||
@@ -261,6 +277,7 @@ help:
|
|||||||
@echo ' G=1 Build with gcov to collect code coverage data'
|
@echo ' G=1 Build with gcov to collect code coverage data'
|
||||||
@echo ' V=1 Generate verbose build output'
|
@echo ' V=1 Generate verbose build output'
|
||||||
@echo ' W=1 Build with higher warning level'
|
@echo ' W=1 Build with higher warning level'
|
||||||
|
@echo ' ASAN=1 Build with address sanitizer'
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo 'EXAMPLES'
|
@echo 'EXAMPLES'
|
||||||
@echo ' # make clean all D=1 W=1 -j'
|
@echo ' # make clean all D=1 W=1 -j'
|
||||||
@@ -339,6 +356,10 @@ $(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
|
|||||||
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
|
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
|
||||||
.PHONY: $(rootdir)/libvmcp
|
.PHONY: $(rootdir)/libvmcp
|
||||||
|
|
||||||
|
$(rootdir)/libekmfweb/libekmfweb.so: $(rootdir)/libekmfweb
|
||||||
|
$(MAKE) -C $(rootdir)/libekmfweb/ libekmfweb.so
|
||||||
|
.PHONY: $(rootdir)/libekmfweb
|
||||||
|
|
||||||
$(rootdir)/zipl/boot/data.o:
|
$(rootdir)/zipl/boot/data.o:
|
||||||
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
|
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
|
||||||
|
|
||||||
@@ -359,9 +380,9 @@ install: install_echo install_dirs
|
|||||||
clean_echo:
|
clean_echo:
|
||||||
$(call echocmd," CLEAN ")
|
$(call echocmd," CLEAN ")
|
||||||
clean_gcov:
|
clean_gcov:
|
||||||
rm -f *.gcda *.gcno *.gcov
|
rm -f -- *.gcda *.gcno *.gcov
|
||||||
clean_dep:
|
clean_dep:
|
||||||
rm -f .*.o.d
|
rm -f -- .*.o.d
|
||||||
|
|
||||||
clean: clean_echo clean_gcov clean_dep
|
clean: clean_echo clean_gcov clean_dep
|
||||||
endif
|
endif
|
||||||
|
|||||||
+14
-8
@@ -60,10 +60,6 @@ static const struct util_prg prg = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Parse tool parameters. Fill in global variables keep_case, buffersize and
|
|
||||||
* command according to parameters. Return VMCP_OK on success, VMCP_OPT
|
|
||||||
* in case of parameter errors. In case of --help or --version, print
|
|
||||||
* respective text to stdout and exit. */
|
|
||||||
static long parse_buffersize(char *string)
|
static long parse_buffersize(char *string)
|
||||||
{
|
{
|
||||||
char *suffix;
|
char *suffix;
|
||||||
@@ -91,17 +87,28 @@ static long parse_buffersize(char *string)
|
|||||||
|
|
||||||
static int read_sfb(unsigned long *min, unsigned long *max)
|
static int read_sfb(unsigned long *min, unsigned long *max)
|
||||||
{
|
{
|
||||||
|
unsigned long cur_min_sdb, cur_max_sdb;
|
||||||
int rc = EXIT_SUCCESS;
|
int rc = EXIT_SUCCESS;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
|
if (geteuid()) {
|
||||||
|
fprintf(stderr, "Error: Must run as root\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
fp = fopen(PERF_SFB_SIZE, "r");
|
fp = fopen(PERF_SFB_SIZE, "r");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
linux_error(PERF_SFB_SIZE);
|
linux_error(PERF_SFB_SIZE);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (fscanf(fp, "%ld,%ld", min, max) != 2) {
|
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
|
||||||
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
|
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE
|
||||||
|
"\n");
|
||||||
rc = EXIT_FAILURE;
|
rc = EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
if (*min == 0)
|
||||||
|
*min = cur_min_sdb;
|
||||||
|
if (*max == 0)
|
||||||
|
*max = cur_max_sdb;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -196,6 +203,7 @@ int main(int argc, char **argv)
|
|||||||
util_prg_init(&prg);
|
util_prg_init(&prg);
|
||||||
util_opt_init(opt_vec, NULL);
|
util_opt_init(opt_vec, NULL);
|
||||||
|
|
||||||
|
parse_args(argc, argv);
|
||||||
if (stat(PERF_PATH PERF_SF, &sbuf) != 0) {
|
if (stat(PERF_PATH PERF_SF, &sbuf) != 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"No CPU-measurement sampling facility detected\n");
|
"No CPU-measurement sampling facility detected\n");
|
||||||
@@ -203,8 +211,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (read_sfb(&min_sdb, &max_sdb))
|
if (read_sfb(&min_sdb, &max_sdb))
|
||||||
return ret;
|
return ret;
|
||||||
/* Overwrite min_sdb and/or max_sdb */
|
|
||||||
parse_args(argc, argv);
|
|
||||||
if (min_sdb >= max_sdb) {
|
if (min_sdb >= max_sdb) {
|
||||||
fprintf(stderr, "The specified maximum must be greater "
|
fprintf(stderr, "The specified maximum must be greater "
|
||||||
"than the minimum\n");
|
"than the minimum\n");
|
||||||
|
|||||||
+6
-4
@@ -2572,6 +2572,7 @@ static const char *machine_name(void)
|
|||||||
case 3906: return "IBM z14";
|
case 3906: return "IBM z14";
|
||||||
case 3907: return "IBM z14 ZR1";
|
case 3907: return "IBM z14 ZR1";
|
||||||
case 8561: return "IBM z15";
|
case 8561: return "IBM z15";
|
||||||
|
case 8562: return "IBM z15 Model T02";
|
||||||
}
|
}
|
||||||
return "Unknown hardware model";
|
return "Unknown hardware model";
|
||||||
}
|
}
|
||||||
@@ -3094,11 +3095,11 @@ int main(int argc, char **argv)
|
|||||||
util_prg_init(&prg);
|
util_prg_init(&prg);
|
||||||
util_opt_init(opt_vec, NULL);
|
util_opt_init(opt_vec, NULL);
|
||||||
|
|
||||||
ret = read_info();
|
ret = parse_args(argc, argv);
|
||||||
if (ret == EXIT_FAILURE)
|
if (read_info() == EXIT_FAILURE)
|
||||||
return ret;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
switch ((ret = parse_args(argc, argv))) {
|
switch (ret) {
|
||||||
case ACTION_CNT:
|
case ACTION_CNT:
|
||||||
case ACTION_CNTALL:
|
case ACTION_CNTALL:
|
||||||
all = ret == ACTION_CNTALL;
|
all = ret == ACTION_CNTALL;
|
||||||
@@ -3114,6 +3115,7 @@ int main(int argc, char **argv)
|
|||||||
case ACTION_NONE:
|
case ACTION_NONE:
|
||||||
case ACTION_INFO:
|
case ACTION_INFO:
|
||||||
show_info(&cpumf, ret == ACTION_INFO);
|
show_info(&cpumf, ret == ACTION_INFO);
|
||||||
|
ret = EXIT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
+5
-3
@@ -19,9 +19,11 @@ lscpumf \- display information about CPU-measurement facilities
|
|||||||
.RB [ \-i | \-\-info ]
|
.RB [ \-i | \-\-info ]
|
||||||
.br
|
.br
|
||||||
.B lscpumf
|
.B lscpumf
|
||||||
.RB [ \-c | \-\-list\-counters ] [ \-n ]
|
.RB \-c | \-\-list\-counters | \-C | \-\-list\-all\-counters
|
||||||
.RB [ \-C | \-\-list\-all\-counters ] [ \-n ]
|
.RB [ \-n ]
|
||||||
.RB [ \-s | \-\-list\-sampling\-events ]
|
.br
|
||||||
|
.B lscpumf
|
||||||
|
.RB \-s | \-\-list\-sampling\-events
|
||||||
.br
|
.br
|
||||||
.B lscpumf
|
.B lscpumf
|
||||||
.BR \-h | \-\-help
|
.BR \-h | \-\-help
|
||||||
|
|||||||
+359
-391
File diff suppressed because it is too large
Load Diff
+26
-46
@@ -41,6 +41,10 @@ static const char mode_str[3][10] = {
|
|||||||
"Full", "Quick", "Expand"
|
"Full", "Quick", "Expand"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Report error, free memory, and exit */
|
||||||
|
static void error(const char *format, ...)
|
||||||
|
__attribute__((__noreturn__, __format__(__printf__, 1, 2)));
|
||||||
|
|
||||||
#define DASD_PARTN_BITS 2
|
#define DASD_PARTN_BITS 2
|
||||||
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
|
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
|
||||||
|
|
||||||
@@ -65,47 +69,24 @@ static const char mode_str[3][10] = {
|
|||||||
"is in invalid format\n",prog_name);}
|
"is in invalid format\n",prog_name);}
|
||||||
|
|
||||||
typedef struct bootstrap1 {
|
typedef struct bootstrap1 {
|
||||||
u_int32_t key;
|
u_int32_t key;
|
||||||
u_int32_t data[6];
|
u_int32_t data[6];
|
||||||
} __attribute__ ((packed)) bootstrap1_t;
|
} __attribute__ ((packed)) bootstrap1_t;
|
||||||
|
|
||||||
typedef struct bootstrap2 {
|
typedef struct bootstrap2 {
|
||||||
u_int32_t key;
|
u_int32_t key;
|
||||||
u_int32_t data[36];
|
u_int32_t data[36];
|
||||||
} __attribute__ ((packed)) bootstrap2_t;
|
} __attribute__ ((packed)) bootstrap2_t;
|
||||||
|
|
||||||
typedef struct dasdfmt_info {
|
|
||||||
dasd_information2_t dasd_info;
|
|
||||||
int verbosity;
|
|
||||||
int testmode;
|
|
||||||
int withoutprompt;
|
|
||||||
int print_progressbar;
|
|
||||||
int print_hashmarks, hashstep;
|
|
||||||
int print_percentage;
|
|
||||||
int force;
|
|
||||||
int writenolabel;
|
|
||||||
int labelspec;
|
|
||||||
int cdl_format;
|
|
||||||
int blksize_specified;
|
|
||||||
int reqsize_specified;
|
|
||||||
int keep_volser;
|
|
||||||
int force_host;
|
|
||||||
int layout_specified;
|
|
||||||
int check;
|
|
||||||
int mode_specified;
|
|
||||||
int ese;
|
|
||||||
int no_discard;
|
|
||||||
} dasdfmt_info_t;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
C9D7D3F1 000A0000 0000000F 03000000 00000001 00000000 00000000
|
C9D7D3F1 000A0000 0000000F 03000000 00000001 00000000 00000000
|
||||||
*/
|
*/
|
||||||
static bootstrap1_t ipl1 = {
|
static bootstrap1_t ipl1 = {
|
||||||
0xC9D7D3F1, {
|
0xC9D7D3F1, {
|
||||||
0x000A0000, 0x0000000F, 0x03000000,
|
0x000A0000, 0x0000000F, 0x03000000,
|
||||||
0x00000001, 0x00000000, 0x00000000
|
0x00000001, 0x00000000, 0x00000000
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -116,21 +97,20 @@ C9D7D3F2 07003AB8 40000006 31003ABE 40000005 08003AA0 00000000 06000000
|
|||||||
00000000 00000000 00000000 00000000 00000000
|
00000000 00000000 00000000 00000000 00000000
|
||||||
*/
|
*/
|
||||||
static bootstrap2_t ipl2 = {
|
static bootstrap2_t ipl2 = {
|
||||||
0xC9D7D3F2, {
|
0xC9D7D3F2, {
|
||||||
0x07003AB8, 0x40000006, 0x31003ABE,
|
0x07003AB8, 0x40000006, 0x31003ABE,
|
||||||
0x40000005, 0x08003AA0, 0x00000000,
|
0x40000005, 0x08003AA0, 0x00000000,
|
||||||
0x06000000, 0x20000000, 0x00000000,
|
0x06000000, 0x20000000, 0x00000000,
|
||||||
0x00000000, 0x00000400, 0x00000000,
|
0x00000000, 0x00000400, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000,
|
0x00000000, 0x00000000, 0x00000000,
|
||||||
0x00000000, 0x00000000, 0x00000000
|
0x00000000, 0x00000000, 0x00000000
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DASDFMT_H */
|
#endif /* DASDFMT_H */
|
||||||
|
|
||||||
|
|||||||
+145
-61
@@ -225,7 +225,7 @@ function CheckDeviceString() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_device()
|
setup_ccw_device()
|
||||||
{
|
{
|
||||||
DEV="$(CheckDeviceString $DEVICE)"
|
DEV="$(CheckDeviceString $DEVICE)"
|
||||||
if [ "$DEV" != "" ]; then
|
if [ "$DEV" != "" ]; then
|
||||||
@@ -235,27 +235,37 @@ setup_device()
|
|||||||
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
|
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
if [ $2 == "fcp" ]; then
|
}
|
||||||
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
|
|
||||||
if [ $RETVAL -eq 1 ]; then
|
setup_fcp_device()
|
||||||
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
|
{
|
||||||
return
|
DEV="$(CheckDeviceString $DEVICE)"
|
||||||
fi
|
if [ "$DEV" != "" ]; then
|
||||||
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
|
echo $DEV > $1/$2/device
|
||||||
if [ $RETVAL -eq 1 ]; then
|
else
|
||||||
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
|
RETVAL=1
|
||||||
return
|
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
|
||||||
fi
|
return
|
||||||
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1
|
fi
|
||||||
if [ $RETVAL -eq 1 ]; then
|
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
|
||||||
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
|
if [ $RETVAL -eq 1 ]; then
|
||||||
return
|
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
|
||||||
fi
|
return
|
||||||
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1
|
fi
|
||||||
if [ $RETVAL -eq 1 ]; then
|
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
|
||||||
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
if [ $RETVAL -eq 1 ]; then
|
||||||
return
|
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
|
||||||
fi
|
return
|
||||||
|
fi
|
||||||
|
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +274,30 @@ setup_nss_device()
|
|||||||
echo $NSS_NAME > $1/nss/name || RETVAL=1
|
echo $NSS_NAME > $1/nss/name || RETVAL=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_nvme_device()
|
||||||
|
{
|
||||||
|
echo $FID > $1/nvme/fid 2>/dev/null || RETVAL=1
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
pr_error "ERROR: Invalid FID '$FID'." $ERRMSG
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo $NSID > $1/nvme/nsid 2>/dev/null || RETVAL=1
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
pr_error "ERROR: Invalid NSID '$NSID'." $ERRMSG
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo $BOOTPROG > $1/nvme/bootprog 2>/dev/null || RETVAL=1
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo $BR_LBA > $1/nvme/br_lba 2>/dev/null || RETVAL=1
|
||||||
|
if [ $RETVAL -eq 1 ]; then
|
||||||
|
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
setup_reipl()
|
setup_reipl()
|
||||||
{
|
{
|
||||||
if [ "$REIPL_TYPE" == "" ]; then
|
if [ "$REIPL_TYPE" == "" ]; then
|
||||||
@@ -271,15 +305,25 @@ setup_reipl()
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$REIPL_TYPE" == "ccw" ] || [ "$REIPL_TYPE" == "fcp" ]; then
|
case "$REIPL_TYPE" in
|
||||||
setup_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
ccw)
|
||||||
elif [ "$REIPL_TYPE" == "nss" ]; then
|
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||||
setup_nss_device $REIPL_CONFIG_DIR
|
;;
|
||||||
else
|
fcp)
|
||||||
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG
|
setup_fcp_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||||
RETVAL=1
|
;;
|
||||||
return
|
nvme)
|
||||||
fi
|
setup_nvme_device $REIPL_CONFIG_DIR
|
||||||
|
;;
|
||||||
|
nss)
|
||||||
|
setup_nss_device $REIPL_CONFIG_DIR
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG
|
||||||
|
RETVAL=1
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
echo $REIPL_TYPE > $REIPL_CONFIG_DIR/reipl_type || RETVAL=1
|
echo $REIPL_TYPE > $REIPL_CONFIG_DIR/reipl_type || RETVAL=1
|
||||||
|
|
||||||
@@ -292,13 +336,24 @@ setup_reipl()
|
|||||||
|
|
||||||
setup_dump()
|
setup_dump()
|
||||||
{
|
{
|
||||||
if [ "$DUMP_TYPE" == "ccw" ] || [ "$DUMP_TYPE" == "fcp" ]; then
|
case "$DUMP_TYPE" in
|
||||||
setup_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
ccw)
|
||||||
elif [ "$DUMP_TYPE" != "none" ]; then
|
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||||
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG
|
;;
|
||||||
RETVAL=1
|
fcp)
|
||||||
return
|
setup_fcp_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||||
fi
|
;;
|
||||||
|
nvme)
|
||||||
|
setup_nvme_device $DUMP_CONFIG_DIR
|
||||||
|
;;
|
||||||
|
none)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG
|
||||||
|
RETVAL=1
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
echo $DUMP_TYPE > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
|
echo $DUMP_TYPE > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
|
||||||
|
|
||||||
@@ -358,6 +413,18 @@ print_ccw_device()
|
|||||||
pr_info "device..: $DEVICE"
|
pr_info "device..: $DEVICE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_nvme_device()
|
||||||
|
{
|
||||||
|
FID=$(cat $1/nvme/fid) || RETVAL=1
|
||||||
|
pr_info "fid.....: $FID"
|
||||||
|
NSID=$(cat $1/nvme/nsid) || RETVAL=1
|
||||||
|
pr_info "nsid....: $NSID"
|
||||||
|
BOOTPROG=$(cat $1/nvme/bootprog) || RETVAL=1
|
||||||
|
pr_info "bootprog: $BOOTPROG"
|
||||||
|
BR_LBA=$(cat $1/nvme/br_lba) || RETVAL=1
|
||||||
|
pr_info "br_lba..: $BR_LBA"
|
||||||
|
}
|
||||||
|
|
||||||
print_nss_name()
|
print_nss_name()
|
||||||
{
|
{
|
||||||
NAME=$(cat $1/nss/device) || RETVAL=1
|
NAME=$(cat $1/nss/device) || RETVAL=1
|
||||||
@@ -367,35 +434,52 @@ print_nss_name()
|
|||||||
status_dump()
|
status_dump()
|
||||||
{
|
{
|
||||||
CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1
|
CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1
|
||||||
if [ "$CONF_DUMP_TYPE" == "none" ]; then
|
case "$CONF_DUMP_TYPE" in
|
||||||
pr_info "type....: no dump device configured"
|
none)
|
||||||
elif [ "$CONF_DUMP_TYPE" == "ccw" ]; then
|
pr_info "type....: no dump device configured"
|
||||||
pr_info "type....: ccw"
|
;;
|
||||||
print_ccw_device $DUMP_CONFIG_DIR
|
ccw)
|
||||||
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
|
pr_info "type....: ccw"
|
||||||
elif [ "$CONF_DUMP_TYPE" == "fcp" ]; then
|
print_ccw_device $DUMP_CONFIG_DIR
|
||||||
pr_info "type....: fcp"
|
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
|
||||||
print_fcp_device $DUMP_CONFIG_DIR
|
;;
|
||||||
else
|
fcp)
|
||||||
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!"
|
pr_info "type....: fcp"
|
||||||
pr_error " Please check if you have the latest dumpconf package!"
|
print_fcp_device $DUMP_CONFIG_DIR
|
||||||
fi
|
;;
|
||||||
|
nvme)
|
||||||
|
pr_info "type....: nvme"
|
||||||
|
print_nvme_device $DUMP_CONFIG_DIR
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!"
|
||||||
|
pr_error " Please check if you have the latest dumpconf package!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
status_reipl()
|
status_reipl()
|
||||||
{
|
{
|
||||||
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
|
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
|
||||||
pr_info "type....: $REIPL_TYPE"
|
pr_info "type....: $REIPL_TYPE"
|
||||||
if [ "$REIPL_TYPE" == "ccw" ]; then
|
case "$REIPL_TYPE" in
|
||||||
print_ccw_device $REIPL_CONFIG_DIR
|
ccw)
|
||||||
elif [ "$REIPL_TYPE" == "fcp" ]; then
|
print_ccw_device $REIPL_CONFIG_DIR
|
||||||
print_fcp_device $REIPL_CONFIG_DIR
|
;;
|
||||||
elif [ "$REIPL_TYPE" == "nss" ]; then
|
fcp)
|
||||||
print_nss_name $REIPL_CONFIG_DIR
|
print_fcp_device $REIPL_CONFIG_DIR
|
||||||
else
|
;;
|
||||||
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!"
|
nvme)
|
||||||
pr_error " Please check if you have the latest dumpconf package!"
|
print_nvme_device $REIPL_CONFIG_DIR
|
||||||
fi
|
;;
|
||||||
|
nss)
|
||||||
|
print_nss_name $REIPL_CONFIG_DIR
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!"
|
||||||
|
pr_error " Please check if you have the latest dumpconf package!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
status_dump_reipl()
|
status_dump_reipl()
|
||||||
|
|||||||
@@ -39,6 +39,16 @@
|
|||||||
# BOOTPROG=0
|
# BOOTPROG=0
|
||||||
# BR_LBA=0
|
# BR_LBA=0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dump on nvme device (NVMe Disk)
|
||||||
|
#
|
||||||
|
# ON_PANIC=dump
|
||||||
|
# DUMP_TYPE=nvme
|
||||||
|
# FID=0x00000300
|
||||||
|
# NSID=0x00000001
|
||||||
|
# BOOTPROG=3
|
||||||
|
# BR_LBA=0
|
||||||
|
|
||||||
#
|
#
|
||||||
# Use VMDUMP
|
# Use VMDUMP
|
||||||
#
|
#
|
||||||
|
|||||||
+1
-1
@@ -1232,7 +1232,7 @@ static void fdasd_reread_partition_table(fdasd_anchor_t *anc)
|
|||||||
if (!anc->silent)
|
if (!anc->silent)
|
||||||
printf("rereading partition table...\n");
|
printf("rereading partition table...\n");
|
||||||
|
|
||||||
if (dasd_reread_partition_table(options.device, 1) != 0) {
|
if (dasd_reread_partition_table(options.device, 5) != 0) {
|
||||||
fdasd_error(anc, unable_to_ioctl, "Error while rereading "
|
fdasd_error(anc, unable_to_ioctl, "Error while rereading "
|
||||||
"partition table.\nPlease reboot!");
|
"partition table.\nPlease reboot!");
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ clean: clean-recursive
|
|||||||
$(RECURSIVE_TARGETS):
|
$(RECURSIVE_TARGETS):
|
||||||
@target=`echo $@ |sed s/-recursive//`; \
|
@target=`echo $@ |sed s/-recursive//`; \
|
||||||
for d in $(SUBDIRS); do \
|
for d in $(SUBDIRS); do \
|
||||||
$(MAKE) -C $$d $$target; \
|
$(MAKE) -C $$d $$target || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
.PHONY: all install clean $(RECURSIVE_TARGETS)
|
.PHONY: all install clean $(RECURSIVE_TARGETS)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
|
|||||||
-DENABLE_SCLP_ASCII=1 \
|
-DENABLE_SCLP_ASCII=1 \
|
||||||
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||||
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
|
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
|
||||||
-fno-delete-null-pointer-checks \
|
-fno-delete-null-pointer-checks -fno-stack-protector \
|
||||||
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
||||||
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
||||||
-Wall -Wformat-security -Wextra -Werror
|
-Wall -Wformat-security -Wextra -Werror
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Entry code for stage 3a boot loader
|
* Entry code for stage 3a and stage 3b boot loader
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2020
|
* Copyright IBM Corp. 2020
|
||||||
*
|
*
|
||||||
@@ -24,6 +24,8 @@ _start:
|
|||||||
sam64
|
sam64
|
||||||
|
|
||||||
/* Initialize stack */
|
/* Initialize stack */
|
||||||
lgfi %r15, STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
|
basr %r13, 0
|
||||||
|
.Lbase: llgf %r15, .Lstack - .Lbase(%r13)
|
||||||
brasl %r14, initialize
|
brasl %r14, initialize
|
||||||
|
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
|
||||||
.previous
|
.previous
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ _init:
|
|||||||
* kernel command line and the address and size of the
|
* kernel command line and the address and size of the
|
||||||
* ramdisk. Simply ignore this by starting at 0x11000.
|
* ramdisk. Simply ignore this by starting at 0x11000.
|
||||||
*/
|
*/
|
||||||
lgfi %r1, STAGE3A_ENTRY
|
basr %r13, 0
|
||||||
|
.Lbase: llgf %r1, .Lstage3a_entry - .Lbase(%r13)
|
||||||
br %r1
|
br %r1
|
||||||
|
.Lstage3a_entry: .long STAGE3A_ENTRY
|
||||||
.previous
|
.previous
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ stage3b_reloc_start:
|
|||||||
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
|
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
|
||||||
sam64
|
sam64
|
||||||
|
|
||||||
.copy_stage3b:
|
|
||||||
/* Location of stage3b in memory */
|
/* Location of stage3b in memory */
|
||||||
larl %r8, stage3b_start
|
larl %r8, stage3b_start
|
||||||
|
|
||||||
/* Destination for stage3b */
|
/* Destination for stage3b */
|
||||||
lgfi %r9, STAGE3B_LOAD_ADDRESS
|
basr %r13, 0
|
||||||
|
.Lbase: llgf %r9, .Lstage3b_load_address - .Lbase(%r13)
|
||||||
|
|
||||||
/* Size of stage3b */
|
/* Size of stage3b */
|
||||||
lghi %r11, stage3b_end - stage3b_start
|
lghi %r11, stage3b_end - stage3b_start
|
||||||
@@ -45,8 +45,10 @@ stage3b_reloc_start:
|
|||||||
MEMCPY %r9, %r8, %r11
|
MEMCPY %r9, %r8, %r11
|
||||||
|
|
||||||
/* Branch to STAGE3B_ENTRY */
|
/* Branch to STAGE3B_ENTRY */
|
||||||
lgfi %r9, STAGE3B_ENTRY
|
llgf %r9, .Lstage3b_entry - .Lbase(%r13)
|
||||||
br %r9
|
br %r9
|
||||||
|
.Lstage3b_load_address: .long STAGE3B_LOAD_ADDRESS
|
||||||
|
.Lstage3b_entry: .long STAGE3B_ENTRY
|
||||||
stage3b_start:
|
stage3b_start:
|
||||||
.incbin "stage3b.bin"
|
.incbin "stage3b.bin"
|
||||||
stage3b_end:
|
stage3b_end:
|
||||||
|
|||||||
+38
-11
@@ -2,7 +2,7 @@
|
|||||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
.TH GENPROTIMG 8 "March 2020" "s390-tools"
|
.TH GENPROTIMG 8 "November 2020" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
genprotimg \- Create a protected virtualization image
|
genprotimg \- Create a protected virtualization image
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ genprotimg \- Create a protected virtualization image
|
|||||||
.SY
|
.SY
|
||||||
.B genprotimg
|
.B genprotimg
|
||||||
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
|
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
|
||||||
|
\fB\-C\fR \fICERTIFICATE\fR...
|
||||||
\fB\-i\fR \fIVMLINUZ\fR
|
\fB\-i\fR \fIVMLINUZ\fR
|
||||||
[\fB\-r\fR \fIRAMDISK\fR]
|
[\fB\-r\fR \fIRAMDISK\fR]
|
||||||
[\fB\-p\fR \fIPARMFILE\fR]
|
[\fB\-p\fR \fIPARMFILE\fR]
|
||||||
@@ -21,15 +22,19 @@ genprotimg \- Create a protected virtualization image
|
|||||||
.PP
|
.PP
|
||||||
Use \fBgenprotimg\fR to generate a single bootable image file with
|
Use \fBgenprotimg\fR to generate a single bootable image file with
|
||||||
encrypted and integrity-protected parts. The command requires a kernel
|
encrypted and integrity-protected parts. The command requires a kernel
|
||||||
image, a host-key document, and an output file name. Optionally,
|
image, a host-key document, certificates for the host-key document
|
||||||
specify an initial RAM filesystem, and a file containing the kernel
|
verification, and an output file name. Optionally, specify an initial
|
||||||
parameters. Should special circumstances require it, you can
|
RAM filesystem, and a file containing the kernel parameters. If the
|
||||||
|
command should be run offline, use the \fB\-\-offline\fR option and
|
||||||
|
specify the certificate revocation lists (CRLs) by using the
|
||||||
|
\fB\-\-crl\fR option. Should special circumstances require it, you can
|
||||||
optionally specify your own keys for the encryption by using the
|
optionally specify your own keys for the encryption by using the
|
||||||
experimental options. In the resulting image file, a plain text boot
|
experimental options. For all certificates, CRLs, and host-key
|
||||||
loader, the encrypted components for kernel, initial RAM disk, kernel
|
documents, both the PEM and DER input formats are supported. In the
|
||||||
parameters, and the encrypted and integrity-protected header are
|
resulting image file, a plain text boot loader, the encrypted
|
||||||
concatenated. The header contains metadata necessary for running the
|
components for kernel, initial RAM disk, kernel parameters, and the
|
||||||
guest in protected mode.
|
encrypted and integrity-protected header are concatenated. The header
|
||||||
|
contains metadata necessary for running the guest in protected mode.
|
||||||
.PP
|
.PP
|
||||||
Use this image file as a kernel image for zipl or for a direct kernel
|
Use this image file as a kernel image for zipl or for a direct kernel
|
||||||
boot using QEMU.
|
boot using QEMU.
|
||||||
@@ -53,6 +58,12 @@ Specifies a host-key document. At least one is required. Specify this
|
|||||||
option multiple times to enable the image to run on more than one
|
option multiple times to enable the image to run on more than one
|
||||||
host.
|
host.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR
|
||||||
|
Specifies the certificate that is used to establish a chain of trust
|
||||||
|
for the verification of the host-key documents. Specify this option
|
||||||
|
twice to specify the IBM Z signing key and the intermediate CA
|
||||||
|
certificate (signed by the root CA). Required.
|
||||||
|
.TP
|
||||||
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
|
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
|
||||||
Specifies the output file. Required.
|
Specifies the output file. Required.
|
||||||
.TP
|
.TP
|
||||||
@@ -65,6 +76,20 @@ Specifies the RAM disk image. Optional.
|
|||||||
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
|
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
|
||||||
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
|
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-crl\fR=\fI\,FILE\/\fR
|
||||||
|
Specifies the revocation list that is used to check whether a
|
||||||
|
certificate of the chain of trust is revoked. Specify this option
|
||||||
|
multiple times to use multiple CRLs. Optional.
|
||||||
|
.TP
|
||||||
|
\fB\-\-offline\fR
|
||||||
|
Specifies offline mode, in which no attempt is made to download
|
||||||
|
CRLs. Optional.
|
||||||
|
.TP
|
||||||
|
\fB\-\-root\-ca\fR=\fI\,FILE\/\fR
|
||||||
|
Specifies the root CA certificate for the verification. If omitted,
|
||||||
|
the DigiCert root CA certificate installed on the system is used. Use
|
||||||
|
this only if you trust the specified certificate. Optional.
|
||||||
|
.TP
|
||||||
\fB\-\-no-verify\fR
|
\fB\-\-no-verify\fR
|
||||||
Do not require the host-key documents to be valid. For testing
|
Do not require the host-key documents to be valid. For testing
|
||||||
purposes, do not use for a production image. Optional.
|
purposes, do not use for a production image. Optional.
|
||||||
@@ -77,11 +102,13 @@ Prints version information, then exits.
|
|||||||
Generate a protected virtualization image in
|
Generate a protected virtualization image in
|
||||||
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
|
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
|
||||||
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
|
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
|
||||||
\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR:
|
\fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR,
|
||||||
|
the IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the
|
||||||
|
host-key document in \fI\,host_key.crt\/\fR:
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
.EX
|
.EX
|
||||||
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR
|
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt \-o \fI\,/boot/vmlinuz.pv\/\fR
|
||||||
.EE
|
.EE
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
|
|||||||
+16
-5
@@ -15,24 +15,24 @@ INCLUDE_PARMS = $(addprefix -I,$(INCLUDE_PATHS))
|
|||||||
|
|
||||||
WARNINGS := -Wall -Wextra -Wshadow \
|
WARNINGS := -Wall -Wextra -Wshadow \
|
||||||
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
|
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
|
||||||
-Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \
|
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
|
||||||
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
||||||
-Wpointer-arith -Werror \
|
-Wpointer-arith -Werror -Wno-error=inline \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
|
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
|
||||||
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
|
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
|
||||||
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
|
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
|
||||||
pv/pv_opt_item.c \
|
pv/pv_opt_item.c utils/curl.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
|
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
|
||||||
|
|
||||||
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
|
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
|
||||||
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \
|
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \
|
||||||
$(WARNINGS) \
|
$(WARNINGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
ALL_CPPFLAGS += $(INCLUDE_PARMS)
|
ALL_CPPFLAGS += $(INCLUDE_PARMS)
|
||||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
|
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||||
@@ -40,21 +40,27 @@ GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
|||||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
||||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
|
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
|
||||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
|
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
|
||||||
|
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
||||||
|
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
||||||
else
|
else
|
||||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||||
GLIB2_LIBS := -lglib-2.0
|
GLIB2_LIBS := -lglib-2.0
|
||||||
LIBCRYPTO_CFLAGS :=
|
LIBCRYPTO_CFLAGS :=
|
||||||
LIBCRYPTO_LIBS := -lcrypto
|
LIBCRYPTO_LIBS := -lcrypto
|
||||||
|
LIBCURL_CFLAGS :=
|
||||||
|
LIBCURL_LIBS := -lcurl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
BUILD_TARGETS := skip-$(bin_PROGRAM)
|
BUILD_TARGETS := skip-$(bin_PROGRAM)
|
||||||
INSTALL_TARGETS := skip-$(bin_PROGRAM)
|
INSTALL_TARGETS := skip-$(bin_PROGRAM)
|
||||||
ifneq (${HAVE_OPENSSL},0)
|
ifneq (${HAVE_OPENSSL},0)
|
||||||
ifneq (${HAVE_GLIB2},0)
|
ifneq (${HAVE_GLIB2},0)
|
||||||
|
ifneq (${HAVE_LIBCURL},0)
|
||||||
BUILD_TARGETS := $(bin_PROGRAM)
|
BUILD_TARGETS := $(bin_PROGRAM)
|
||||||
INSTALL_TARGETS := install-$(bin_PROGRAM)
|
INSTALL_TARGETS := install-$(bin_PROGRAM)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
all: $(BUILD_TARGETS)
|
all: $(BUILD_TARGETS)
|
||||||
|
|
||||||
@@ -98,4 +104,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM)
|
|||||||
"openssl-devel / libssl-dev version >= 1.1.0", \
|
"openssl-devel / libssl-dev version >= 1.1.0", \
|
||||||
"HAVE_OPENSSL=0", \
|
"HAVE_OPENSSL=0", \
|
||||||
"-I.")
|
"-I.")
|
||||||
|
$(call check_dep, \
|
||||||
|
"$(bin_PROGRAM)", \
|
||||||
|
"curl/curl.h", \
|
||||||
|
"libcurl-devel", \
|
||||||
|
"HAVE_LIBCURL=0")
|
||||||
touch $@
|
touch $@
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "pv/pv_args.h"
|
#include "pv/pv_args.h"
|
||||||
#include "pv/pv_image.h"
|
#include "pv/pv_image.h"
|
||||||
|
#include "utils/crypto.h"
|
||||||
|
#include "utils/curl.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LOG_LEVEL_CRITICAL = 0,
|
LOG_LEVEL_CRITICAL = 0,
|
||||||
@@ -117,6 +119,8 @@ static void remove_signal_handler(const gint *signals, const gsize signals_n)
|
|||||||
signal(signals[i], SIG_DFL);
|
signal(signals[i], SIG_DFL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __attribute__((constructor)) __init(void);
|
||||||
|
static void __attribute__((destructor)) __cleanup(void);
|
||||||
gint main(gint argc, gchar *argv[])
|
gint main(gint argc, gchar *argv[])
|
||||||
{
|
{
|
||||||
g_autoptr(PvArgs) args = pv_args_new();
|
g_autoptr(PvArgs) args = pv_args_new();
|
||||||
@@ -177,5 +181,20 @@ error:
|
|||||||
rmdir_recursive(tmp_dir, NULL);
|
rmdir_recursive(tmp_dir, NULL);
|
||||||
remove_signal_handler(signals, G_N_ELEMENTS(signals));
|
remove_signal_handler(signals, G_N_ELEMENTS(signals));
|
||||||
g_free(tmp_dir);
|
g_free(tmp_dir);
|
||||||
|
g_clear_pointer(&img, pv_img_free);
|
||||||
|
g_clear_pointer(&args, pv_args_free);
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init(void)
|
||||||
|
{
|
||||||
|
pv_crypto_init();
|
||||||
|
if (curl_init() != 0)
|
||||||
|
g_abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __cleanup(void)
|
||||||
|
{
|
||||||
|
curl_cleanup();
|
||||||
|
pv_crypto_cleanup();
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,24 @@
|
|||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
|
/* IBM signing key subject */
|
||||||
|
#define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation"
|
||||||
|
#define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US"
|
||||||
|
#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie"
|
||||||
|
#define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service"
|
||||||
|
#define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation"
|
||||||
|
#define PV_IBM_Z_SUBJECT_STATE "New York"
|
||||||
|
#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6
|
||||||
|
|
||||||
|
/* Minimum security level for the keys/certificates used to establish a chain of
|
||||||
|
* trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html
|
||||||
|
* for details).
|
||||||
|
*/
|
||||||
|
#define PV_CERTS_SECURITY_LEVEL 2
|
||||||
|
|
||||||
|
/* SKID for DigiCert Assured ID Root CA */
|
||||||
|
#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F"
|
||||||
|
|
||||||
union ecdh_pub_key {
|
union ecdh_pub_key {
|
||||||
struct {
|
struct {
|
||||||
uint8_t x[80];
|
uint8_t x[80];
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
static gchar summary[] =
|
static gchar summary[] =
|
||||||
"Use genprotimg to create a protected virtualization kernel image file,\n"
|
"Use genprotimg to create a protected virtualization kernel image file,\n"
|
||||||
"which can be loaded using zipl or QEMU.";
|
"which can be loaded using zipl or QEMU. For all certificates, revocation\n"
|
||||||
|
"lists, and host-key documents, both the PEM and DER input formats are\n"
|
||||||
|
"supported.";
|
||||||
|
|
||||||
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
|
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
|
||||||
{
|
{
|
||||||
@@ -97,9 +99,14 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args->no_verify) {
|
if (!args->no_verify &&
|
||||||
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
|
(!args->untrusted_cert_paths ||
|
||||||
_("Use the option '--no-verify' as the verification support is not available yet."));
|
g_strv_length(args->untrusted_cert_paths) == 0)) {
|
||||||
|
g_set_error(
|
||||||
|
err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
|
||||||
|
_("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n"
|
||||||
|
"by using the '--cert' option, or use the '--no-verify' flag to disable the\n"
|
||||||
|
"host-key document verification completely (at your own risk)."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +148,8 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value,
|
|||||||
{
|
{
|
||||||
gchar **args_option = NULL;
|
gchar **args_option = NULL;
|
||||||
|
|
||||||
|
if (g_str_equal(option, "--root-ca"))
|
||||||
|
args_option = &args->root_ca_path;
|
||||||
if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
|
if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
|
||||||
args_option = &args->output_path;
|
args_option = &args->output_path;
|
||||||
if (g_str_equal(option, "--x-comp-key"))
|
if (g_str_equal(option, "--x-comp-key"))
|
||||||
@@ -211,6 +220,18 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
|||||||
_("FILE specifies a host-key document. At least\n" INDENT
|
_("FILE specifies a host-key document. At least\n" INDENT
|
||||||
"one is required."),
|
"one is required."),
|
||||||
.arg_description = _("FILE") },
|
.arg_description = _("FILE") },
|
||||||
|
{ .long_name = "cert",
|
||||||
|
.short_name = 'C',
|
||||||
|
.flags = G_OPTION_FLAG_NONE,
|
||||||
|
.arg = G_OPTION_ARG_FILENAME_ARRAY,
|
||||||
|
.arg_data = &args->untrusted_cert_paths,
|
||||||
|
.description = _(
|
||||||
|
"FILE contains a certificate that is used to\n" INDENT
|
||||||
|
"establish a chain of trust for the verification\n" INDENT
|
||||||
|
"of the host-key documents. The IBM Z signing\n" INDENT
|
||||||
|
"key and intermediate CA certificate (signed\n" INDENT
|
||||||
|
"by the root CA) are required."),
|
||||||
|
.arg_description = _("FILE") },
|
||||||
{ .long_name = "output",
|
{ .long_name = "output",
|
||||||
.short_name = 'o',
|
.short_name = 'o',
|
||||||
.flags = G_OPTION_FLAG_FILENAME,
|
.flags = G_OPTION_FLAG_FILENAME,
|
||||||
@@ -227,7 +248,7 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
|||||||
.arg_description = _("IMAGE") },
|
.arg_description = _("IMAGE") },
|
||||||
{ .long_name = "ramdisk",
|
{ .long_name = "ramdisk",
|
||||||
.short_name = 'r',
|
.short_name = 'r',
|
||||||
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
|
.flags = G_OPTION_FLAG_FILENAME,
|
||||||
.arg = G_OPTION_ARG_CALLBACK,
|
.arg = G_OPTION_ARG_CALLBACK,
|
||||||
.arg_data = cb_add_component,
|
.arg_data = cb_add_component,
|
||||||
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT
|
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT
|
||||||
@@ -235,12 +256,37 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
|||||||
.arg_description = _("RAMDISK") },
|
.arg_description = _("RAMDISK") },
|
||||||
{ .long_name = "parmfile",
|
{ .long_name = "parmfile",
|
||||||
.short_name = 'p',
|
.short_name = 'p',
|
||||||
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
|
.flags = G_OPTION_FLAG_FILENAME,
|
||||||
.arg = G_OPTION_ARG_CALLBACK,
|
.arg = G_OPTION_ARG_CALLBACK,
|
||||||
.arg_data = cb_add_component,
|
.arg_data = cb_add_component,
|
||||||
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
|
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
|
||||||
"(optional)."),
|
"(optional)."),
|
||||||
.arg_description = _("PARMFILE") },
|
.arg_description = _("PARMFILE") },
|
||||||
|
{ .long_name = "crl",
|
||||||
|
.short_name = 0,
|
||||||
|
.flags = G_OPTION_FLAG_NONE,
|
||||||
|
.arg = G_OPTION_ARG_FILENAME_ARRAY,
|
||||||
|
.arg_data = &args->crl_paths,
|
||||||
|
.description = _(
|
||||||
|
"FILE contains a certificate revocation list\n" INDENT
|
||||||
|
"(optional)."),
|
||||||
|
.arg_description = _("FILE") },
|
||||||
|
{ .long_name = "offline",
|
||||||
|
.short_name = 0,
|
||||||
|
.flags = G_OPTION_FLAG_NONE,
|
||||||
|
.arg = G_OPTION_ARG_NONE,
|
||||||
|
.arg_data = &args->offline,
|
||||||
|
.description = _("Don't download CRLs (optional)."),
|
||||||
|
.arg_description = NULL },
|
||||||
|
{ .long_name = "root-ca",
|
||||||
|
.short_name = 0,
|
||||||
|
.flags = G_OPTION_FLAG_FILENAME,
|
||||||
|
.arg = G_OPTION_ARG_CALLBACK,
|
||||||
|
.arg_data = cb_set_string_option,
|
||||||
|
.description = _(
|
||||||
|
"Set FILE as the trusted root CA and don't use the\n" INDENT
|
||||||
|
"root CAs that are installed on the system (optional)."),
|
||||||
|
.arg_description = _("FILE") },
|
||||||
{ .long_name = "no-verify",
|
{ .long_name = "no-verify",
|
||||||
.short_name = 0,
|
.short_name = 0,
|
||||||
.flags = G_OPTION_FLAG_NONE,
|
.flags = G_OPTION_FLAG_NONE,
|
||||||
@@ -378,6 +424,9 @@ void pv_args_free(PvArgs *args)
|
|||||||
g_free(args->cust_root_key_path);
|
g_free(args->cust_root_key_path);
|
||||||
g_free(args->cust_comm_key_path);
|
g_free(args->cust_comm_key_path);
|
||||||
g_free(args->gcm_iv_path);
|
g_free(args->gcm_iv_path);
|
||||||
|
g_free(args->root_ca_path);
|
||||||
|
g_strfreev(args->crl_paths);
|
||||||
|
g_strfreev(args->untrusted_cert_paths);
|
||||||
g_strfreev(args->host_keys);
|
g_strfreev(args->host_keys);
|
||||||
g_free(args->xts_key_path);
|
g_free(args->xts_key_path);
|
||||||
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);
|
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ void pv_arg_free(PvArg *arg);
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
gint log_level;
|
gint log_level;
|
||||||
gint no_verify;
|
gint no_verify;
|
||||||
|
gboolean offline;
|
||||||
gchar *pcf;
|
gchar *pcf;
|
||||||
gchar *scf;
|
gchar *scf;
|
||||||
gchar *psw_addr; /* PSW address which will be used for the start of
|
gchar *psw_addr; /* PSW address which will be used for the start of
|
||||||
@@ -34,6 +35,11 @@ typedef struct {
|
|||||||
gchar *cust_comm_key_path;
|
gchar *cust_comm_key_path;
|
||||||
gchar *gcm_iv_path;
|
gchar *gcm_iv_path;
|
||||||
gchar **host_keys;
|
gchar **host_keys;
|
||||||
|
gchar *root_ca_path; /* Trusted root CA used for the verification of the
|
||||||
|
* chain of trust (if specified).
|
||||||
|
*/
|
||||||
|
gchar **untrusted_cert_paths;
|
||||||
|
gchar **crl_paths;
|
||||||
gchar *xts_key_path;
|
gchar *xts_key_path;
|
||||||
GSList *comps;
|
GSList *comps;
|
||||||
gchar *output_path;
|
gchar *output_path;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ typedef enum {
|
|||||||
PV_ERROR_IPIB_SIZE,
|
PV_ERROR_IPIB_SIZE,
|
||||||
PV_ERROR_PV_HDR_SIZE,
|
PV_ERROR_PV_HDR_SIZE,
|
||||||
PV_ERROR_INTERNAL,
|
PV_ERROR_INTERNAL,
|
||||||
|
PV_ERROR_CURL_INIT_FAILED,
|
||||||
|
PV_ERROR_DOWNLOAD_FAILED,
|
||||||
} PvErrors;
|
} PvErrors;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -57,6 +59,31 @@ typedef enum {
|
|||||||
PV_CRYPTO_ERROR_RANDOMIZATION,
|
PV_CRYPTO_ERROR_RANDOMIZATION,
|
||||||
PV_CRYPTO_ERROR_INVALID_PARM,
|
PV_CRYPTO_ERROR_INVALID_PARM,
|
||||||
PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
|
PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
|
||||||
|
PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD,
|
||||||
|
PV_CRYPTO_ERROR_EXPIRED,
|
||||||
|
PV_CRYPTO_ERROR_NOT_VALID_YET,
|
||||||
|
PV_CRYPTO_ERROR_LOAD_CRL,
|
||||||
|
PV_CRYPTO_ERROR_NO_PUBLIC_KEY,
|
||||||
|
PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM,
|
||||||
|
PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH,
|
||||||
|
PV_CRYPTO_ERROR_INVALID_URI,
|
||||||
|
PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED,
|
||||||
|
PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID,
|
||||||
|
PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID,
|
||||||
|
PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH,
|
||||||
|
PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH,
|
||||||
|
PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||||
|
PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE,
|
||||||
|
PV_CRYPTO_ERROR_NO_CRL,
|
||||||
|
PV_CRYPTO_ERROR_LOAD_ROOT_CA,
|
||||||
|
PV_CRYPTO_ERROR_LOAD_DEFAULT_CA,
|
||||||
|
PV_CRYPTO_ERROR_MALFORMED_ROOT_CA,
|
||||||
|
PV_CRYPTO_ERROR_WRONG_CA_USED,
|
||||||
|
PV_CRYPTO_ERROR_SKID_AKID_MISMATCH,
|
||||||
|
PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND,
|
||||||
|
PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL,
|
||||||
|
PV_CRYPTO_ERROR_NO_CRLDP,
|
||||||
|
PV_CRYPTO_ERROR_CERT_REVOKED,
|
||||||
} PvCryptoErrors;
|
} PvCryptoErrors;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+191
-12
@@ -10,6 +10,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err)
|
|||||||
return generate_ec_key(nid, err);
|
return generate_ec_key(nid, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
|
static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid,
|
||||||
X509_STORE *store, gint nid,
|
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
g_autoslist(EVP_PKEY) ret = NULL;
|
g_autoslist(EVP_PKEY) ret = NULL;
|
||||||
|
|
||||||
g_assert(host_cert_paths);
|
for (GSList *iterator = host_keys_with_path; iterator;
|
||||||
|
iterator = iterator->next) {
|
||||||
for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL;
|
x509_with_path *cert_with_path = iterator->data;
|
||||||
iterator++) {
|
|
||||||
g_autoptr(EVP_PKEY) host_key = NULL;
|
g_autoptr(EVP_PKEY) host_key = NULL;
|
||||||
const gchar *path = *iterator;
|
X509 *cert = cert_with_path->cert;
|
||||||
|
|
||||||
g_assert(path);
|
host_key = read_ec_pubkey_cert(cert, nid, err);
|
||||||
|
|
||||||
host_key = read_ec_pubkey_cert(store, nid, path, err);
|
|
||||||
if (!host_key)
|
if (!host_key)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -253,10 +250,172 @@ static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint pv_img_hostkey_verify(GSList *host_key_certs,
|
||||||
|
const gchar *root_ca_path,
|
||||||
|
const gchar *const *crl_paths,
|
||||||
|
const gchar *const *untrusted_cert_paths,
|
||||||
|
gboolean offline, GError **err)
|
||||||
|
{
|
||||||
|
g_autoslist(x509_with_path) untrusted_certs_with_path = NULL;
|
||||||
|
g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL;
|
||||||
|
g_autoptr(STACK_OF_X509) untrusted_certs = NULL;
|
||||||
|
g_autoslist(x509_pair) ibm_z_pairs = NULL;
|
||||||
|
g_autoptr(X509_STORE) trusted = NULL;
|
||||||
|
gint ibm_signing_certs_count;
|
||||||
|
|
||||||
|
/* Load trusted root CAs of the system if and only if @root_ca_path is
|
||||||
|
* NULL, otherwise use the root CA specified by @root_ca_path.
|
||||||
|
*/
|
||||||
|
trusted = store_setup(root_ca_path, crl_paths, err);
|
||||||
|
if (!trusted)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!offline) {
|
||||||
|
g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL;
|
||||||
|
|
||||||
|
/* Set up the download routine for the lookup of CRLs. */
|
||||||
|
store_setup_crl_download(trusted);
|
||||||
|
|
||||||
|
/* Try to download the CRLs of the IBM Z signing certificates
|
||||||
|
* specified in the host-key documents. Ignore download errors
|
||||||
|
* as it's still possible that a CRL is specified via command
|
||||||
|
* line.
|
||||||
|
*/
|
||||||
|
downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs);
|
||||||
|
|
||||||
|
/* Add the downloaded CRLs to the store so they can be used for
|
||||||
|
* the verification later.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) {
|
||||||
|
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
|
||||||
|
|
||||||
|
if (X509_STORE_add_crl(trusted, crl) != 1) {
|
||||||
|
g_set_error(err, PV_CRYPTO_ERROR,
|
||||||
|
PV_CRYPTO_ERROR_INTERNAL,
|
||||||
|
_("failed to load CRL"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load all untrusted certificates (e.g. IBM Z signing key and
|
||||||
|
* DigiCert intermediate CA) that are required to establish a chain of
|
||||||
|
* trust starting from the host-key document up to the root CA (if not
|
||||||
|
* otherwise specified that's the DigiCert Assured ID Root CA).
|
||||||
|
*/
|
||||||
|
untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err);
|
||||||
|
if (!untrusted_certs_with_path)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Convert to STACK_OF(X509) */
|
||||||
|
untrusted_certs = get_x509_stack(untrusted_certs_with_path);
|
||||||
|
|
||||||
|
/* Find all IBM Z signing keys and remove them from the chain as we
|
||||||
|
* have to verify that they're valid. The last step of the chain of
|
||||||
|
* trust verification must be done manually, as the IBM Z signing keys
|
||||||
|
* are not marked as (intermediate) CA and therefore the standard
|
||||||
|
* `X509_verify_cert` function of OpenSSL cannot be used to verify the
|
||||||
|
* actual host-key documents.
|
||||||
|
*/
|
||||||
|
ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs);
|
||||||
|
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
|
||||||
|
if (ibm_signing_certs_count < 1) {
|
||||||
|
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||||
|
_("please specify at least one IBM Z signing key"));
|
||||||
|
goto error;
|
||||||
|
} else if (ibm_signing_certs_count > 1) {
|
||||||
|
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||||
|
_("please specify only one IBM Z signing key"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store_set_verify_param(trusted, err) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Verify that the IBM Z signing keys are trustable.
|
||||||
|
* For this we must check:
|
||||||
|
*
|
||||||
|
* 1. Can a chain of trust be established ending in a root CA
|
||||||
|
* 2. Is the correct root CA ued? It has either to be the
|
||||||
|
* 'DigiCert Assured ID Root CA' or the root CA specified via
|
||||||
|
* command line.
|
||||||
|
*/
|
||||||
|
for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) {
|
||||||
|
X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i);
|
||||||
|
g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL;
|
||||||
|
g_autoptr(X509_STORE_CTX) ctx = NULL;
|
||||||
|
x509_pair *pair = NULL;
|
||||||
|
|
||||||
|
g_assert(ibm_signing_cert);
|
||||||
|
|
||||||
|
/* Create the verification context and set the trusted
|
||||||
|
* and chain parameters.
|
||||||
|
*/
|
||||||
|
ctx = create_store_ctx(trusted, untrusted_certs, err);
|
||||||
|
if (!ctx)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Verify the IBM Z signing key */
|
||||||
|
if (verify_cert(ibm_signing_cert, ctx, err) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Verify the build chain of trust chain. If the user passes a
|
||||||
|
* trusted root CA on the command line then the check for the
|
||||||
|
* Subject Key Identifier (SKID) is skipped, otherwise let's
|
||||||
|
* check if the SKID meets our expectation.
|
||||||
|
*/
|
||||||
|
if (!root_ca_path &&
|
||||||
|
check_chain_parameters(X509_STORE_CTX_get0_chain(ctx),
|
||||||
|
get_digicert_assured_id_root_ca_skid(),
|
||||||
|
err) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err);
|
||||||
|
if (!ibm_signing_crls) {
|
||||||
|
g_prefix_error(err, _("IBM Z signing key: "));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment reference counter of @ibm_signing_cert as the
|
||||||
|
* certificate will now also be owned by @ibm_z_pairs.
|
||||||
|
*/
|
||||||
|
if (X509_up_ref(ibm_signing_cert) != 1)
|
||||||
|
g_abort();
|
||||||
|
|
||||||
|
pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls);
|
||||||
|
ibm_z_pairs = g_slist_append(ibm_z_pairs, pair);
|
||||||
|
g_assert(!ibm_signing_cert);
|
||||||
|
g_assert(!ibm_signing_crls);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify host-key documents by using the IBM Z signing
|
||||||
|
* certificates and the corresponding certificate revocation
|
||||||
|
* lists.
|
||||||
|
*/
|
||||||
|
for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) {
|
||||||
|
x509_with_path *host_key_with_path = iterator->data;
|
||||||
|
const gchar *host_key_path = host_key_with_path->path;
|
||||||
|
X509 *host_key = host_key_with_path->cert;
|
||||||
|
gint flags = X509_V_FLAG_CRL_CHECK;
|
||||||
|
|
||||||
|
if (verify_host_key(host_key, ibm_z_pairs, flags,
|
||||||
|
PV_CERTS_SECURITY_LEVEL, err) < 0) {
|
||||||
|
g_prefix_error(err, "'%s': ", host_key_path);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
g_prefix_error(err, _("Failed to verify host-key document: "));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* read in the keys or auto-generate them */
|
/* read in the keys or auto-generate them */
|
||||||
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
|
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
|
||||||
{
|
{
|
||||||
g_autoptr(X509_STORE) store = NULL;
|
g_autoslist(x509_with_path) host_key_certs = NULL;
|
||||||
|
|
||||||
g_assert(img->xts_cipher);
|
g_assert(img->xts_cipher);
|
||||||
g_assert(img->cust_comm_cipher);
|
g_assert(img->cust_comm_cipher);
|
||||||
@@ -285,8 +444,25 @@ static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
|
|||||||
if (!img->cust_pub_priv_key)
|
if (!img->cust_pub_priv_key)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Load all host-key documents specified on the command line */
|
||||||
|
host_key_certs = load_certificates((const gchar **)args->host_keys,
|
||||||
|
err);
|
||||||
|
if (!host_key_certs)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!args->no_verify &&
|
||||||
|
pv_img_hostkey_verify(host_key_certs, args->root_ca_path,
|
||||||
|
(const gchar * const *)args->crl_paths,
|
||||||
|
(const gchar * const *)args->untrusted_cert_paths,
|
||||||
|
args->offline, err) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loads the public keys stored in the host-key documents and verify
|
||||||
|
* that the correct elliptic curve is used.
|
||||||
|
*/
|
||||||
img->host_pub_keys =
|
img->host_pub_keys =
|
||||||
pv_img_get_host_keys(args->host_keys, store, img->nid, err);
|
pv_img_get_host_keys(host_key_certs, img->nid, err);
|
||||||
if (!img->host_pub_keys)
|
if (!img->host_pub_keys)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -406,6 +582,9 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
|
|||||||
if (args->no_verify)
|
if (args->no_verify)
|
||||||
g_warning(_("host-key document verification is disabled. Your workload is not secured."));
|
g_warning(_("host-key document verification is disabled. Your workload is not secured."));
|
||||||
|
|
||||||
|
if (args->root_ca_path)
|
||||||
|
g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted."));
|
||||||
|
|
||||||
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
|
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
|
||||||
if (!ret->comps)
|
if (!ret->comps)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
+1345
-38
File diff suppressed because it is too large
Load Diff
@@ -11,14 +11,18 @@
|
|||||||
#define PV_UTILS_CRYPTO_H
|
#define PV_UTILS_CRYPTO_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <openssl/asn1.h>
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
#include <openssl/ecdh.h>
|
#include <openssl/ecdh.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/ossl_typ.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/safestack.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@@ -33,6 +37,9 @@
|
|||||||
#define AES_256_XTS_TWEAK_SIZE 16
|
#define AES_256_XTS_TWEAK_SIZE 16
|
||||||
#define AES_256_XTS_KEY_SIZE 64
|
#define AES_256_XTS_KEY_SIZE 64
|
||||||
|
|
||||||
|
#define CRL_DOWNLOAD_TIMEOUT_MS 3000
|
||||||
|
#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */
|
||||||
|
|
||||||
enum PvCryptoMode {
|
enum PvCryptoMode {
|
||||||
PV_ENCRYPT,
|
PV_ENCRYPT,
|
||||||
PV_DECRYPT,
|
PV_DECRYPT,
|
||||||
@@ -40,7 +47,34 @@ enum PvCryptoMode {
|
|||||||
|
|
||||||
typedef GSList HostKeyList;
|
typedef GSList HostKeyList;
|
||||||
|
|
||||||
|
/* play nice with g_autoptr */
|
||||||
|
typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT;
|
||||||
|
typedef STACK_OF(X509) STACK_OF_X509;
|
||||||
|
typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL;
|
||||||
|
|
||||||
|
void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack);
|
||||||
|
void STACK_OF_X509_free(STACK_OF_X509 *stack);
|
||||||
|
void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
X509 *cert;
|
||||||
|
const gchar *path;
|
||||||
|
} x509_with_path;
|
||||||
|
|
||||||
|
x509_with_path *x509_with_path_new(X509 *cert, const gchar *path);
|
||||||
|
void x509_with_path_free(x509_with_path *cert);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
X509 *cert;
|
||||||
|
STACK_OF_X509_CRL *crls;
|
||||||
|
} x509_pair;
|
||||||
|
|
||||||
|
x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls);
|
||||||
|
void x509_pair_free(x509_pair *pair);
|
||||||
|
|
||||||
/* Register auto cleanup functions */
|
/* Register auto cleanup functions */
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
|
||||||
@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
|
|||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free);
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free);
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free);
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
|
||||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free)
|
||||||
|
|
||||||
union cmp_index {
|
union cmp_index {
|
||||||
struct {
|
struct {
|
||||||
@@ -79,8 +121,37 @@ struct cipher_parms {
|
|||||||
const Buffer *iv_or_tweak;
|
const Buffer *iv_or_tweak;
|
||||||
};
|
};
|
||||||
|
|
||||||
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path,
|
int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert,
|
||||||
GError **err);
|
gint verify_flags, GError **err);
|
||||||
|
void pv_crypto_init(void);
|
||||||
|
void pv_crypto_cleanup(void);
|
||||||
|
const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void);
|
||||||
|
gint verify_host_key(X509 *host_key, GSList *issuer_pairs,
|
||||||
|
gint verify_flags, int level, GError **err);
|
||||||
|
X509 *load_cert_from_file(const char *path, GError **err);
|
||||||
|
X509_CRL *load_crl_from_file(const gchar *path, GError **err);
|
||||||
|
GSList *load_certificates(const gchar *const *cert_paths, GError **err);
|
||||||
|
STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list);
|
||||||
|
X509_STORE *store_setup(const gchar *root_ca_path,
|
||||||
|
const gchar * const *crl_paths,
|
||||||
|
GError **err);
|
||||||
|
int store_set_verify_param(X509_STORE *store, GError **err);
|
||||||
|
X509_CRL *load_crl_by_cert(X509 *cert, GError **err);
|
||||||
|
STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path);
|
||||||
|
gint check_chain_parameters(const STACK_OF_X509 *chain,
|
||||||
|
const ASN1_OCTET_STRING *skid, GError **err);
|
||||||
|
X509_NAME *c2b_name(const X509_NAME *name);
|
||||||
|
|
||||||
|
STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs);
|
||||||
|
STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert,
|
||||||
|
GError **err);
|
||||||
|
X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain,
|
||||||
|
GError **err);
|
||||||
|
gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err);
|
||||||
|
X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err);
|
||||||
|
void store_setup_crl_download(X509_STORE *st);
|
||||||
|
EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err);
|
||||||
|
|
||||||
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
|
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
|
||||||
Buffer *generate_aes_key(guint size, GError **err);
|
Buffer *generate_aes_key(guint size, GError **err);
|
||||||
Buffer *generate_aes_iv(guint size, GError **err);
|
Buffer *generate_aes_iv(guint size, GError **err);
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Libcurl utils
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2020
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gtypes.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "lib/zt_common.h"
|
||||||
|
#include "pv/pv_error.h"
|
||||||
|
|
||||||
|
#include "curl.h"
|
||||||
|
|
||||||
|
struct UserData {
|
||||||
|
GByteArray *buffer;
|
||||||
|
guint max_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||||
|
{
|
||||||
|
g_assert(userdata);
|
||||||
|
struct UserData *data = (struct UserData *)userdata;
|
||||||
|
GByteArray *buffer = data->buffer;
|
||||||
|
guint64 actual_size;
|
||||||
|
size_t err;
|
||||||
|
|
||||||
|
g_assert(buffer);
|
||||||
|
|
||||||
|
if (!g_uint64_checked_mul(&actual_size, size, nmemb))
|
||||||
|
g_abort();
|
||||||
|
|
||||||
|
/* Signal an error condition by returning a amount that differs
|
||||||
|
* from the amount passed to the callback. This results in a
|
||||||
|
* CURLE_WRITE_ERROR.
|
||||||
|
*/
|
||||||
|
err = actual_size + 1;
|
||||||
|
|
||||||
|
if (actual_size > G_MAXUINT)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size);
|
||||||
|
if (data->buffer->len > data->max_size)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return actual_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint curl_init(void)
|
||||||
|
{
|
||||||
|
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void curl_cleanup(void)
|
||||||
|
{
|
||||||
|
curl_global_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
|
||||||
|
GError **err)
|
||||||
|
{
|
||||||
|
g_autoptr(GByteArray) ret = NULL;
|
||||||
|
g_autoptr(CURL) handle = NULL;
|
||||||
|
g_autofree gchar *agent = NULL;
|
||||||
|
struct UserData userdata;
|
||||||
|
CURLcode rc;
|
||||||
|
|
||||||
|
/* set up curl session */
|
||||||
|
handle = curl_easy_init();
|
||||||
|
if (!handle)
|
||||||
|
g_abort();
|
||||||
|
|
||||||
|
/* follow redirection */
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING);
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
ret = g_byte_array_new();
|
||||||
|
userdata.buffer = ret;
|
||||||
|
userdata.max_size = max_size;
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
rc = curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||||
|
if (rc != CURLE_OK)
|
||||||
|
goto curl_err;
|
||||||
|
|
||||||
|
rc = curl_easy_perform(handle);
|
||||||
|
if (rc != CURLE_OK) {
|
||||||
|
g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED,
|
||||||
|
_("download failed: %s"), curl_easy_strerror(rc));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_steal_pointer(&ret);
|
||||||
|
curl_err:
|
||||||
|
g_set_error(err, PV_ERROR,
|
||||||
|
PV_ERROR_CURL_INIT_FAILED,
|
||||||
|
_("cURL initialization failed: %s"),
|
||||||
|
curl_easy_strerror(rc));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Libcurl utils
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2020
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PV_UTILS_LIBCURL_H
|
||||||
|
#define PV_UTILS_LIBCURL_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup)
|
||||||
|
|
||||||
|
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
|
||||||
|
GError **err);
|
||||||
|
gint curl_init(void);
|
||||||
|
void curl_cleanup(void);
|
||||||
|
|
||||||
|
#endif /* PV_UTILS_LIBCURL_H */
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
include ../common.mak
|
||||||
|
|
||||||
|
all:
|
||||||
|
|
||||||
|
install: hsci
|
||||||
|
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||||
|
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
|
||||||
|
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
|
||||||
|
chmod 755 $(DESTDIR)$(BINDIR)/hsci; \
|
||||||
|
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \
|
||||||
|
$(DESTDIR)$(MANDIR)/man8
|
||||||
|
|
||||||
|
clean:
|
||||||
|
|
||||||
|
.PHONY: all install clean
|
||||||
@@ -0,0 +1,436 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# hsci - Tool to manage HiperSockets Converged Interfaces (HSCI)
|
||||||
|
#
|
||||||
|
# Copyright IBM Corp. 2020
|
||||||
|
#
|
||||||
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
#
|
||||||
|
|
||||||
|
hsdev=""
|
||||||
|
ndev=""
|
||||||
|
hsci=""
|
||||||
|
hsdev_mac=""
|
||||||
|
hsif_pnetid=""
|
||||||
|
netif_pnetid=""
|
||||||
|
hsci_pnetid=""
|
||||||
|
|
||||||
|
function usage {
|
||||||
|
cat <<-EOD
|
||||||
|
Usage: hsci COMMAND [OPTION]
|
||||||
|
|
||||||
|
This tool is designed to control and show HSCI (HiperSockets Converged
|
||||||
|
Interfaces) settings. A HiperSockets interface and an external network
|
||||||
|
interface are converged into an HSCI interface.
|
||||||
|
|
||||||
|
COMMANDS
|
||||||
|
add HIPERSOCKETS_DEV NET_DEV Adds an HSCI interface
|
||||||
|
del HSCI_NAME Deletes an HSCI interface
|
||||||
|
show Lists the configured HSCI interfaces
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-v, --version Prints the version number of the hsci tool and exits
|
||||||
|
-h, --help Displays the help information for the command
|
||||||
|
EOD
|
||||||
|
}
|
||||||
|
|
||||||
|
function prereqs_check {
|
||||||
|
if ! [ -x "$(command -v ip)" ]; then
|
||||||
|
echo "Error: No iproute2 installed on this system" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_pnetids {
|
||||||
|
# get PNETID of the HS
|
||||||
|
local hsif_pnetids=""
|
||||||
|
local netif_pnetids=""
|
||||||
|
|
||||||
|
if [ -e /sys/class/net/$hsdev/device/util_string ]; then
|
||||||
|
hsif_pnetids="$(cat /sys/class/net/$hsdev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||||
|
else
|
||||||
|
if [ -e /sys/class/net/$hsdev/device/chpid ]; then
|
||||||
|
chpid="$(cat /sys/class/net/$hsdev/device/chpid | tr [:upper:] [:lower:])"
|
||||||
|
hsif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$hsif_pnetids" != "" ]; then
|
||||||
|
port_hsif="$(cat /sys/class/net/$hsdev/dev_port)"
|
||||||
|
(( idx=16*$port_hsif+1 ))
|
||||||
|
(( end=$idx+15 ))
|
||||||
|
hsif_pnetid="$(echo "$hsif_pnetids" | cut -c $idx-$end | tr -d ' ')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get PNETID of the NET_DEV
|
||||||
|
if [ -e /sys/class/net/$ndev/device/util_string ]; then
|
||||||
|
netif_pnetids="$(cat /sys/class/net/$ndev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||||
|
else
|
||||||
|
if [ -e /sys/class/net/$ndev/device/chpid ]; then
|
||||||
|
chpid="$(cat /sys/class/net/$ndev/device/chpid | tr [:upper:] [:lower:])"
|
||||||
|
netif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$netif_pnetids" != "" ]; then
|
||||||
|
port_netif="$(cat /sys/class/net/$ndev/dev_port)"
|
||||||
|
(( idx=16*$port_netif+1 ))
|
||||||
|
(( end=$idx+15 ))
|
||||||
|
netif_pnetid="$(echo "$netif_pnetids" | cut -c $idx-$end | tr -d ' ')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Check PNETIDs
|
||||||
|
if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" != "$hsif_pnetid" ]; then
|
||||||
|
echo "Error: $hsdev and $ndev have different PNETIDs! They are $hsif_pnetid and $netif_pnetid respectively" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" == "$hsif_pnetid" ]; then
|
||||||
|
hsci_pnetid=$hsif_pnetid
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_precon {
|
||||||
|
echo "Verifying net dev $ndev and HiperSockets dev $hsdev"
|
||||||
|
|
||||||
|
if [ ! -e /sys/class/net/$hsdev ]; then
|
||||||
|
echo "Error: $hsdev does not exist" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$(cat /sys/class/net/$hsdev/device/card_type)" != "HiperSockets" ]; then
|
||||||
|
echo "Error: $hsdev is not a HiperSockets device" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$(cat /sys/class/net/$hsdev/device/layer2)" != "1" ]; then
|
||||||
|
echo "Error: $hsdev is not in layer 2 mode" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ ! -e /sys/class/net/$hsdev/device/vnicc/bridge_invisible ]; then
|
||||||
|
echo "Error: Missing vnic-characteristics support" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$(cat /sys/class/net/$hsdev/device/vnicc/bridge_invisible)" == "n/a" ]; then
|
||||||
|
echo "Error: $hsdev does not support vnicc" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ $(ip link show $hsdev | grep UP | wc -l) -eq 0 ]; then
|
||||||
|
echo "Error: $hsdev is not in state UP" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ $(bridge -d link show dev $hsdev self | grep learning_sync | wc -l) -eq 0 ]; then
|
||||||
|
echo "Error: $hsdev does not support attribute learning_sync" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ $(ip link show $hsdev | grep master | wc -l) -ne 0 ]; then
|
||||||
|
echo "Error: $hsdev is already a bridge port" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Pre-verify net_dev
|
||||||
|
if [ ! -e /sys/class/net/$ndev ]; then
|
||||||
|
echo "Error: $ndev does not exist" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$(cat /sys/class/net/$ndev/device/card_type)" == "HiperSockets" ]; then
|
||||||
|
echo "Error: $ndev is also a HiperSockets device" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ $(ip link show $ndev | grep UP | wc -l) -eq 0 ]; then
|
||||||
|
echo "Error: $ndev is not in state UP" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ $(ip link show $ndev | grep master | wc -l) -ne 0 ]; then
|
||||||
|
echo "Error: $ndev is already a bridge port" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Check PNETIDs
|
||||||
|
check_pnetids
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean_up {
|
||||||
|
bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1
|
||||||
|
echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible >/dev/null 2>&1
|
||||||
|
bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1
|
||||||
|
ip link del $hsci >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
## add a new HSCI interface
|
||||||
|
##############################################################################
|
||||||
|
function add_hsci {
|
||||||
|
|
||||||
|
if [ $# != 2 ]; then
|
||||||
|
echo "hsci: Invalid parameters" >&2
|
||||||
|
echo "Use 'hsci --help' for more information" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
hsdev=$1
|
||||||
|
ndev=$2
|
||||||
|
|
||||||
|
#### Verify preconditions
|
||||||
|
verify_precon
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
hsci_postfix="$(readlink /sys/class/net/$hsdev/device/cdev0 | tail -c5)"
|
||||||
|
hsci=hsci$hsci_postfix
|
||||||
|
|
||||||
|
echo "Adding $hsci with a HiperSockets dev $hsdev and an external dev $ndev"
|
||||||
|
|
||||||
|
#### Create bridge
|
||||||
|
ip link add name $hsci type bridge stp_state 0 >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Could not create a bridge" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#### Prepare hsdev
|
||||||
|
# Set VNICC of hsdev to invisible
|
||||||
|
#(mandatory for co-existence with HS-OSA bridges!)
|
||||||
|
echo 1 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible
|
||||||
|
|
||||||
|
#### Create bridge ports
|
||||||
|
ip link set dev $ndev master $hsci >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Could not set master for $ndev" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
ip link set dev $hsdev master $hsci >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Could not set master for $hsdev" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# no forwarding between ndev and hsdev -> isolated on
|
||||||
|
# ndev is default for outgoing unknown targets -> flood on
|
||||||
|
# no need to learn external LAN targets into fdb -> learning off
|
||||||
|
bridge link set dev $ndev isolated on learning off flood on mcast_flood on >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to set bridge attributes on $ndev" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# no forwarding between ndev and hsdev -> isolated on
|
||||||
|
# fdb will be populated by dev-to-bridge-notification, no need to learn
|
||||||
|
# -> learning off
|
||||||
|
# only send to hsdev, if listed in fdb -> flood off
|
||||||
|
# don't send MC/BC on hsdev -> mcast_flood off
|
||||||
|
bridge link set dev $hsdev isolated on learning off flood off mcast_flood off >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to set bridge attributes on $hsdev" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# NOTE: Although not required, BCs will be sent out on hsdev.
|
||||||
|
# NOTE: We need to receive BCs on hsdev, as z/OS HSCI does ARP requests on HS.
|
||||||
|
|
||||||
|
hsdev_mac="$(cat /sys/class/net/$hsdev/address)"
|
||||||
|
echo "Set $hsdev MAC $hsdev_mac on $ndev and $hsci"
|
||||||
|
|
||||||
|
# set HS MAC on OSA as secondary MAC
|
||||||
|
bridge fdb add $hsdev_mac dev $ndev >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to set HS MAC on OSA as secondary MAC" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set HS MAC (common MAC) on HSCI as primary MAC
|
||||||
|
ip link set address $hsdev_mac dev $hsci >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to set HiperSockets MAC (common MAC) on HSCI as primary MAC" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip link set dev $hsci up >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to set $hsci up" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Turn on device for bridge notification
|
||||||
|
bridge link set dev $hsdev learning_sync on self >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to turn on device for bridge notification" >&2
|
||||||
|
clean_up
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "Successfully added HSCI interface $hsci"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
## Delete HSCI
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
function del_hsci {
|
||||||
|
if [ $# != 1 ]; then
|
||||||
|
echo "hsci: invalid parameters" >&2
|
||||||
|
echo "Use 'hsci --help' for more information" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
hsci=$1
|
||||||
|
if [ $(ip link show dev $hsci | wc -l) -eq 0 ]; then
|
||||||
|
echo "Error: $hsci does not exit" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ $(ip link show | grep "master $hsci" | wc -l) -eq 0 ]; then
|
||||||
|
echo "Error: $hsci is not an active HSCI interface" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
bports="$(ip link show | grep "master $hsci" | awk '{print $2}')"
|
||||||
|
for bport in $bports; do
|
||||||
|
bport=${bport%:}
|
||||||
|
if [[ $bport == *@* ]]; then
|
||||||
|
bport=${bport%@*}
|
||||||
|
fi
|
||||||
|
if [ $(bridge -d link show dev $bport | grep "learning_sync on" | wc -l) -ne 0 ]; then
|
||||||
|
hsdev=$bport
|
||||||
|
else
|
||||||
|
ndev=$bport
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$hsdev" == "" ]; then
|
||||||
|
echo "Error: $hsci has no active HiperSockets port" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "Deleting HSCI interface $hsci with the HiperSockets $hsdev and the external $ndev"
|
||||||
|
|
||||||
|
bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to turn off learning_sync on $hsdev" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible
|
||||||
|
|
||||||
|
hsdev_mac="$(cat /sys/class/net/$hsdev/address)"
|
||||||
|
echo "Deleting $hsev MAC $hsdev_mac on $ndev"
|
||||||
|
bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to delete $hsev MAC $hsdev_mac on $ndev" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip link del $hsci >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to delete $hsci" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "Successfully deleted device $hsci"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
## Show HSCI
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
function list_active {
|
||||||
|
hsdev=$1
|
||||||
|
local ext=""
|
||||||
|
|
||||||
|
hsci="$(ip link show dev $hsdev | awk '{for(x=1;x<NF;x++) if($x~/master/) print $(x+1)}')"
|
||||||
|
ext="$(ip link show | grep "master $hsci" | grep --invert-match $hsdev | awk '{print $2}')"
|
||||||
|
# remove trailing ':'
|
||||||
|
ndev="${ext%:}"
|
||||||
|
|
||||||
|
check_pnetids
|
||||||
|
|
||||||
|
printf '%-8s %-16s %-15s %-15s\n' "$hsci" "$hsci_pnetid" "$hsdev" "$ndev"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_header {
|
||||||
|
if [ $header -eq 0 ]; then
|
||||||
|
echo "HSCI PNET_ID HiperSockets External "
|
||||||
|
echo "------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function list_one {
|
||||||
|
local hsnetdev=$1
|
||||||
|
|
||||||
|
if [ $(bridge -d link show dev $hsnetdev | grep "learning_sync on" | wc -l) -ne 0 ]; then
|
||||||
|
print_header
|
||||||
|
list_active $hsnetdev
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_hsci {
|
||||||
|
if [ $# != 0 ]; then
|
||||||
|
echo "hsci: invalid parameters" >&2
|
||||||
|
echo "Use 'hsci --help' for more information" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
header=0
|
||||||
|
|
||||||
|
for hs_net_dev in $(ls -1 /sys/class/net/); do
|
||||||
|
list_one $hs_net_dev
|
||||||
|
done
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#==============================================================================
|
||||||
|
|
||||||
|
function print_version()
|
||||||
|
{
|
||||||
|
echo "hsci utility: version %S390_TOOLS_VERSION%"
|
||||||
|
echo "Copyright IBM Corp. 2020"
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##### Main
|
||||||
|
##############################################################################
|
||||||
|
prereqs_check
|
||||||
|
|
||||||
|
args="$(getopt -u -o hv -l help,version -- $*)"
|
||||||
|
[ $? -ne 0 ] && exit 2
|
||||||
|
set -- $args
|
||||||
|
while true; do
|
||||||
|
case $1 in
|
||||||
|
-v | --version)
|
||||||
|
print_version
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
;;
|
||||||
|
add) shift
|
||||||
|
add_hsci "$@"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
del) shift
|
||||||
|
del_hsci "$@"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
show) shift
|
||||||
|
show_hsci "$@"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
*) echo "hsci: Please specify a valid command or option" >&2
|
||||||
|
echo "Use 'hsci --help' for more information" >&2
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
.\" Copyright IBM Corp. 2020
|
||||||
|
|
||||||
|
.TH HSCI 8 "November 2020" "s390-tools" "Linux Programmer's Manual"
|
||||||
|
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
.B hsci
|
||||||
|
\- control and show HSCI settings.
|
||||||
|
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B hsci add
|
||||||
|
.I HSDEV
|
||||||
|
.I NETDEV
|
||||||
|
.br
|
||||||
|
.B hsci del
|
||||||
|
.I HSCINAME
|
||||||
|
.br
|
||||||
|
.B hsci show
|
||||||
|
.br
|
||||||
|
.B hsci [\-hv]
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.BI hsci
|
||||||
|
is used to control and show HSCI (HiperSockets Converged Interfaces) settings. A HiperSockets interface and an external network interface are converged into an HSCI interface.
|
||||||
|
|
||||||
|
.SH COMMANDS
|
||||||
|
.TP
|
||||||
|
.B add \fIHSDEV\fR \fINETDEV\fR
|
||||||
|
.RS .4i
|
||||||
|
.PP
|
||||||
|
Adds an HSCI interface
|
||||||
|
.PP
|
||||||
|
.I HSDEV
|
||||||
|
is the interface name of the HiperSockets device to be converged into the HSCI interface.
|
||||||
|
.PP
|
||||||
|
.I NETDEV
|
||||||
|
is the interface name of the external network device to be converged into the HSCI interface.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B del \fIHSCINAME\fR
|
||||||
|
.RS .4i
|
||||||
|
.PP
|
||||||
|
Deletes an HSCI interface
|
||||||
|
.PP
|
||||||
|
.I HSCINAME
|
||||||
|
is the name of the HSCI interface for the HiperSockets device and the external network device.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B show
|
||||||
|
.RS .4i
|
||||||
|
.PP
|
||||||
|
Lists the configured HSCI interfaces.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BR \-v ", " \-\-version
|
||||||
|
Prints the version number of hsci and exits.
|
||||||
|
.TP
|
||||||
|
.BR \-h ", " \-\-help
|
||||||
|
Displays the help information for the command.
|
||||||
|
|
||||||
|
.SH EXIT CODES
|
||||||
|
.TP
|
||||||
|
.BR "0"
|
||||||
|
The hsci command ran successfully.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "1"
|
||||||
|
An error occurred.
|
||||||
|
|
||||||
|
.SH EXAMPLE
|
||||||
|
.BR "hsci show"
|
||||||
|
.TP
|
||||||
|
.RB
|
||||||
|
Lists the configured HSCI interfaces:
|
||||||
|
.RS 1.2i
|
||||||
|
|
||||||
|
HSCI PNET_ID HiperSockets External
|
||||||
|
.br
|
||||||
|
-----------------------------------------
|
||||||
|
.br
|
||||||
|
hsci8410 NET1 enc8410 encb040
|
||||||
|
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.nf
|
||||||
|
ip(8), bridge(8)
|
||||||
|
.fi
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
.nf
|
||||||
|
Written by Alexandra Winter <wintera@linux.ibm.com>
|
||||||
|
Wenjia Zhang <wenjia@linux.ibm.com>
|
||||||
|
.fi
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,10 @@
|
|||||||
#define LIB_UTIL_FILE_H
|
#define LIB_UTIL_FILE_H
|
||||||
|
|
||||||
int util_file_read_line(char *str, size_t size, const char *fmt, ...);
|
int util_file_read_line(char *str, size_t size, const char *fmt, ...);
|
||||||
|
int util_file_read_i(int *val, int base, const char *fmt, ...);
|
||||||
int util_file_read_l(long *val, int base, const char *fmt, ...);
|
int util_file_read_l(long *val, int base, const char *fmt, ...);
|
||||||
int util_file_read_ll(long long *val, int base, const char *fmt, ...);
|
int util_file_read_ll(long long *val, int base, const char *fmt, ...);
|
||||||
|
int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...);
|
||||||
int util_file_read_ul(unsigned long *val, int base, const char *fmt, ...);
|
int util_file_read_ul(unsigned long *val, int base, const char *fmt, ...);
|
||||||
int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...);
|
int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...);
|
||||||
|
|
||||||
@@ -23,4 +25,5 @@ int util_file_write_ll(long long val, int base, const char *fmt, ...);
|
|||||||
int util_file_write_ul(unsigned long val, int base, const char *fmt, ...);
|
int util_file_write_ul(unsigned long val, int base, const char *fmt, ...);
|
||||||
int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...);
|
int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...);
|
||||||
|
|
||||||
|
int util_file_read_va(const char *path, const char *fmt, ...);
|
||||||
#endif /** LIB_UTIL_FILE_H @} */
|
#endif /** LIB_UTIL_FILE_H @} */
|
||||||
|
|||||||
@@ -12,6 +12,11 @@
|
|||||||
#ifndef LIB_UTIL_SYS_H
|
#ifndef LIB_UTIL_SYS_H
|
||||||
#define LIB_UTIL_SYS_H
|
#define LIB_UTIL_SYS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
int util_sys_get_dev_addr(const char *dev, char *addr);
|
int util_sys_get_dev_addr(const char *dev, char *addr);
|
||||||
|
bool util_sys_dev_is_partition(dev_t dev);
|
||||||
|
int util_sys_get_partnum(dev_t dev);
|
||||||
|
int util_sys_get_base_dev(dev_t dev, dev_t *base_dev);
|
||||||
|
|
||||||
#endif /** LIB_UTIL_SYS_H @} */
|
#endif /** LIB_UTIL_SYS_H @} */
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ static const char *const usage_chreipl =
|
|||||||
" -s --nsid <NAMESPACE_ID> Namespace ID of NVME IPL device (decimal, default 1)\n"
|
" -s --nsid <NAMESPACE_ID> Namespace ID of NVME IPL device (decimal, default 1)\n"
|
||||||
" -b, --bootprog <BPROG> Bootprog specification\n"
|
" -b, --bootprog <BPROG> Bootprog specification\n"
|
||||||
" -L, --loadparm <PARM> Loadparm specification\n"
|
" -L, --loadparm <PARM> Loadparm specification\n"
|
||||||
|
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options for nss target:\n"
|
"Options for nss target:\n"
|
||||||
" -n, --name <NAME> Identifier of the NSS\n"
|
" -n, --name <NAME> Identifier of the NSS\n"
|
||||||
@@ -794,6 +795,11 @@ static void chreipl_nvme(void)
|
|||||||
strlen(l.bootparms), BOOTPARMS_FCP_MAX);
|
strlen(l.bootparms), BOOTPARMS_FCP_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (l.reipl_clear >= 0) {
|
||||||
|
check_exists("reipl/nvme/clear", "NVME re-IPL clear attribute");
|
||||||
|
write_str(l.reipl_clear ? "1" : "0", "reipl/nvme/clear");
|
||||||
|
}
|
||||||
|
|
||||||
write_str_optional(l.loadparm, "reipl/nvme/loadparm", l.loadparm_set,
|
write_str_optional(l.loadparm, "reipl/nvme/loadparm", l.loadparm_set,
|
||||||
"loadparm");
|
"loadparm");
|
||||||
write_str_optional(l.bootparms, "reipl/nvme/scp_data", l.bootparms_set,
|
write_str_optional(l.bootparms, "reipl/nvme/scp_data", l.bootparms_set,
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ void print_nvme(int show_ipl, int dump)
|
|||||||
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
|
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
|
||||||
"/sys/firmware/reipl/nvme/loadparm";
|
"/sys/firmware/reipl/nvme/loadparm";
|
||||||
char loadparm[9], loadparm_path[PATH_MAX];
|
char loadparm[9], loadparm_path[PATH_MAX];
|
||||||
|
char *path_reipl_clear = "/sys/firmware/reipl/nvme/clear";
|
||||||
|
|
||||||
if (dump)
|
if (dump)
|
||||||
printf("%-12s nvme_dump\n", get_ipl_banner(show_ipl));
|
printf("%-12s nvme_dump\n", get_ipl_banner(show_ipl));
|
||||||
@@ -111,6 +112,8 @@ void print_nvme(int show_ipl, int dump)
|
|||||||
}
|
}
|
||||||
if (access(path_bootparms, R_OK) == 0)
|
if (access(path_bootparms, R_OK) == 0)
|
||||||
print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data");
|
print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data");
|
||||||
|
if (!show_ipl && access(path_reipl_clear, R_OK) == 0)
|
||||||
|
print_fw_str("clear: %s\n", dir, "clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_ccw(int show_ipl)
|
void print_ccw(int show_ipl)
|
||||||
|
|||||||
@@ -238,6 +238,13 @@ configuration that is defined by the
|
|||||||
boot menu. Instead it can be used to control higher level boot loaders
|
boot menu. Instead it can be used to control higher level boot loaders
|
||||||
like GRUB. For more details refer to distribution specific documentation.
|
like GRUB. For more details refer to distribution specific documentation.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-c" " or " "\-\-clear"
|
||||||
|
Specify whether memory should be cleared on re-IPL. Possible values are 0 to
|
||||||
|
disable and 1 to enable memory clearing on re-IPL.
|
||||||
|
Memory clearing is supported if the "clear" attribute is present in
|
||||||
|
/sys/firmware/reipl/nvme/.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fBExamples:\fP
|
\fBExamples:\fP
|
||||||
.br
|
.br
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ clean: clean-recursive
|
|||||||
$(RECURSIVE_TARGETS):
|
$(RECURSIVE_TARGETS):
|
||||||
@target=`echo $@ |sed s/-recursive//`; \
|
@target=`echo $@ |sed s/-recursive//`; \
|
||||||
for d in $(SUBDIRS); do \
|
for d in $(SUBDIRS); do \
|
||||||
(cd $$d && $(MAKE) $$target) \
|
(cd $$d && $(MAKE) $$target) || exit 1; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -214,7 +214,7 @@ int dasd_get_host_access_count(char *device)
|
|||||||
char *path;
|
char *path;
|
||||||
long value;
|
long value;
|
||||||
|
|
||||||
if (!util_sys_get_dev_addr(device, busid))
|
if (util_sys_get_dev_addr(device, busid) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
path = util_path_sysfs("bus/ccw/devices/%s/host_access_count", busid);
|
path = util_path_sysfs("bus/ccw/devices/%s/host_access_count", busid);
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
include ../common.mak
|
||||||
|
|
||||||
|
VERSION = 1.0
|
||||||
|
VERM = $(shell echo $(VERSION) | cut -d '.' -f 1)
|
||||||
|
|
||||||
|
ifneq (${HAVE_OPENSSL},0)
|
||||||
|
ifneq (${HAVE_JSONC},0)
|
||||||
|
ifneq (${HAVE_LIBCURL},0)
|
||||||
|
BUILD_TARGETS += libekmfweb.so.$(VERSION)
|
||||||
|
INSTALL_TARGETS += install-libekmfweb.so.$(VERSION)
|
||||||
|
else
|
||||||
|
BUILD_TARGETS += skip-libekmfweb-curl
|
||||||
|
INSTALL_TARGETS += skip-libekmfweb-curl
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
BUILD_TARGETS += skip-libekmfweb-jsonc
|
||||||
|
INSTALL_TARGETS += skip-libekmfweb-jsonc
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
BUILD_TARGETS += skip-libekmfweb-openssl
|
||||||
|
INSTALL_TARGETS += skip-libekmfweb-openssl
|
||||||
|
endif
|
||||||
|
|
||||||
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
|
detect-openssl-version.dep:
|
||||||
|
echo "#include <openssl/opensslv.h>" > detect-openssl-version.dep
|
||||||
|
echo "#include <openssl/evp.h>" >> detect-openssl-version.dep
|
||||||
|
echo "#if OPENSSL_VERSION_NUMBER < 0x10101000L" >> detect-openssl-version.dep
|
||||||
|
echo " #error openssl version 1.1.1 is required" >> detect-openssl-version.dep
|
||||||
|
echo "#endif" >> detect-openssl-version.dep
|
||||||
|
echo "static void __attribute__((unused)) test(void) {" >> detect-openssl-version.dep
|
||||||
|
echo " EVP_PKEY_meth_remove(NULL);" >> detect-openssl-version.dep
|
||||||
|
echo "}" >> detect-openssl-version.dep
|
||||||
|
|
||||||
|
check-dep-libekmfweb: detect-openssl-version.dep
|
||||||
|
$(call check_dep, \
|
||||||
|
"libekmfweb", \
|
||||||
|
"detect-openssl-version.dep", \
|
||||||
|
"openssl-devel version >= 1.1.1", \
|
||||||
|
"HAVE_OPENSSL=0", \
|
||||||
|
-I. -lcrypto)
|
||||||
|
$(call check_dep, \
|
||||||
|
"libekmfweb", \
|
||||||
|
"json-c/json.h", \
|
||||||
|
"json-c-devel", \
|
||||||
|
"HAVE_JSONC=0")
|
||||||
|
$(call check_dep, \
|
||||||
|
"libekmfweb", \
|
||||||
|
"curl/curl.h", \
|
||||||
|
"libcurl-devel", \
|
||||||
|
"HAVE_LIBCURL=0")
|
||||||
|
touch check-dep-libekmfweb
|
||||||
|
|
||||||
|
skip-libekmfweb-openssl:
|
||||||
|
echo " SKIP libekmfweb due to HAVE_OPENSSL=0"
|
||||||
|
|
||||||
|
skip-libekmfweb-jsonc:
|
||||||
|
echo " SKIP libekmfweb due to HAVE_JSONC=0"
|
||||||
|
|
||||||
|
skip-libekmfweb-curl:
|
||||||
|
echo " SKIP libekmfweb due to HAVE_LIBCURL=0"
|
||||||
|
|
||||||
|
all: $(BUILD_TARGETS)
|
||||||
|
|
||||||
|
ekmfweb.o: check-dep-libekmfweb ekmfweb.c utilities.h cca.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||||
|
utilities.o: check-dep-libekmfweb utilities.c utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||||
|
cca.o: check-dep-libekmfweb cca.c cca.h utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||||
|
|
||||||
|
libekmfweb.so.$(VERSION): ALL_CFLAGS += -fPIC
|
||||||
|
libekmfweb.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl -lcurl -ldl
|
||||||
|
libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb.map \
|
||||||
|
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
|
||||||
|
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o
|
||||||
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
|
||||||
|
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so
|
||||||
|
|
||||||
|
install-libekmfweb.so.$(VERSION): libekmfweb.so.$(VERSION)
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION)
|
||||||
|
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERM)
|
||||||
|
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so
|
||||||
|
$(INSTALL) -d -m 770 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||||
|
|
||||||
|
install: all $(INSTALL_TARGETS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o libekmfweb.so* check-dep-libekmfweb detect-openssl-version.dep
|
||||||
|
|
||||||
|
.PHONY: all install clean skip-libekmfweb-openssl skip-libekmfweb-jsonc \
|
||||||
|
skip-libekmfweb-curl install-libekmfweb.so.$(VERSION)
|
||||||
+1805
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* libekmfweb - EKMFWeb client library
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2020
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CCA_H
|
||||||
|
#define CCA_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
#include "ekmfweb/ekmfweb.h"
|
||||||
|
|
||||||
|
/* CCA PKA Key Generate function */
|
||||||
|
typedef void (*CSNDPKG_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *regeneration_data_length,
|
||||||
|
unsigned char *regeneration_data,
|
||||||
|
long *skeleton_key_token_length,
|
||||||
|
unsigned char *skeleton_key_token,
|
||||||
|
unsigned char *transport_key_identifier,
|
||||||
|
long *generated_key_identifier_length,
|
||||||
|
unsigned char *generated_key_identifier);
|
||||||
|
|
||||||
|
/* CCA PKA Key Token Build function */
|
||||||
|
typedef void (*CSNDPKB_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *key_values_structure_length,
|
||||||
|
unsigned char *key_values_structure,
|
||||||
|
long *key_name_ln,
|
||||||
|
unsigned char *key_name,
|
||||||
|
long *reserved_1_length,
|
||||||
|
unsigned char *reserved_1,
|
||||||
|
long *reserved_2_length,
|
||||||
|
unsigned char *reserved_2,
|
||||||
|
long *reserved_3_length,
|
||||||
|
unsigned char *reserved_3,
|
||||||
|
long *reserved_4_length,
|
||||||
|
unsigned char *reserved_4,
|
||||||
|
long *reserved_5_length,
|
||||||
|
unsigned char *reserved_5,
|
||||||
|
long *token_length, unsigned char *token);
|
||||||
|
|
||||||
|
/* CCA PKA Key Token Change function */
|
||||||
|
typedef void (*CSNDKTC_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *key_identifier_length,
|
||||||
|
unsigned char *key_identifier);
|
||||||
|
|
||||||
|
/* CCA Digital Signature Generate function */
|
||||||
|
typedef void (*CSNDDSG_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *PKA_private_key_identifier_length,
|
||||||
|
unsigned char *PKA_private_key_identifier,
|
||||||
|
long *hash_length,
|
||||||
|
unsigned char *hash,
|
||||||
|
long *signature_field_length,
|
||||||
|
long *signature_bit_length,
|
||||||
|
unsigned char *signature_field);
|
||||||
|
|
||||||
|
/* CCA Key Token Build2 function */
|
||||||
|
typedef void (*CSNBKTB2_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *clear_key_bit_length,
|
||||||
|
unsigned char *clear_key_value,
|
||||||
|
long *key_name_length,
|
||||||
|
unsigned char *key_name,
|
||||||
|
long *user_associated_data_length,
|
||||||
|
unsigned char *user_associated_data,
|
||||||
|
long *token_data_length,
|
||||||
|
unsigned char *token_data,
|
||||||
|
long *verb_data_length,
|
||||||
|
unsigned char *verb_data,
|
||||||
|
long *target_key_token_length,
|
||||||
|
unsigned char *target_key_token);
|
||||||
|
|
||||||
|
/* CCA EC Diffie-Hellman function */
|
||||||
|
typedef void (*CSNDEDH_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *private_key_identifier_length,
|
||||||
|
unsigned char *private_key_identifier,
|
||||||
|
long *private_KEK_key_identifier_length,
|
||||||
|
unsigned char *private_KEK_key_identifier,
|
||||||
|
long *public_key_identifier_length,
|
||||||
|
unsigned char *public_key_identifier,
|
||||||
|
long *chaining_vector_length,
|
||||||
|
unsigned char *chaining_vector,
|
||||||
|
long *party_info_length,
|
||||||
|
unsigned char *party_info,
|
||||||
|
long *key_bit_length,
|
||||||
|
long *reserved_1_length,
|
||||||
|
unsigned char *reserved_1,
|
||||||
|
long *reserved_2_length,
|
||||||
|
unsigned char *reserved_2,
|
||||||
|
long *reserved_3_length,
|
||||||
|
unsigned char *reserved_3,
|
||||||
|
long *reserved_4_length,
|
||||||
|
unsigned char *reserved_4,
|
||||||
|
long *reserved_5_length,
|
||||||
|
unsigned char *reserved_5,
|
||||||
|
long *output_KEK_key_identifier_length,
|
||||||
|
unsigned char *output_KEK_key_identifier,
|
||||||
|
long *output_key_identifier_length,
|
||||||
|
unsigned char *output_key_identifier);
|
||||||
|
|
||||||
|
/* CCA Symmetric Key Import2 function */
|
||||||
|
typedef void (*CSNDSYI2_t)(long *return_code,
|
||||||
|
long *reason_code,
|
||||||
|
long *exit_data_length,
|
||||||
|
unsigned char *exit_data,
|
||||||
|
long *rule_array_count,
|
||||||
|
unsigned char *rule_array,
|
||||||
|
long *enciphered_key_length,
|
||||||
|
unsigned char *enciphered_key,
|
||||||
|
long *transport_key_identifier_length,
|
||||||
|
unsigned char *transport_key_identifier,
|
||||||
|
long *key_name_length,
|
||||||
|
unsigned char *key_name,
|
||||||
|
long *target_key_identifier_length,
|
||||||
|
unsigned char *target_key_identifier);
|
||||||
|
|
||||||
|
struct cca_lib {
|
||||||
|
CSNDPKB_t dll_CSNDPKB;
|
||||||
|
CSNDPKG_t dll_CSNDPKG;
|
||||||
|
CSNDKTC_t dll_CSNDKTC;
|
||||||
|
CSNDDSG_t dll_CSNDDSG;
|
||||||
|
CSNBKTB2_t dll_CSNBKTB2;
|
||||||
|
CSNDEDH_t dll_CSNDEDH;
|
||||||
|
CSNDSYI2_t dll_CSNDSYI2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CCA_MAX_PKA_KEY_TOKEN_SIZE 3500
|
||||||
|
#define CCA_MAX_SYM_KEY_TOKEN_SIZE 725
|
||||||
|
|
||||||
|
int cca_generate_ecc_key_pair(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
int curve_nid, unsigned char *key_token,
|
||||||
|
size_t *key_token_length, bool verbose);
|
||||||
|
|
||||||
|
int cca_generate_rsa_key_pair(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
size_t modulus_bits, unsigned int pub_exp,
|
||||||
|
unsigned char *key_token,
|
||||||
|
size_t *key_token_length, bool verbose);
|
||||||
|
|
||||||
|
int cca_get_key_type(const unsigned char *key_token, size_t key_token_length,
|
||||||
|
int *pkey_type);
|
||||||
|
|
||||||
|
int cca_reencipher_key(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
const unsigned char *key_token, size_t key_token_length,
|
||||||
|
bool to_new, bool verbose);
|
||||||
|
|
||||||
|
int cca_get_ecc_pub_key_as_pkey(const unsigned char *key_token,
|
||||||
|
size_t key_token_length,
|
||||||
|
EVP_PKEY **pkey, bool verbose);
|
||||||
|
|
||||||
|
int cca_get_ecc_pub_key_as_json_web_key(const unsigned char *key_token,
|
||||||
|
size_t key_token_length,
|
||||||
|
json_object **jwk, bool verbose);
|
||||||
|
|
||||||
|
int cca_get_rsa_pub_key_as_pkey(const unsigned char *key_token,
|
||||||
|
size_t key_token_length,
|
||||||
|
int pkey_type, EVP_PKEY **pkey, bool verbose);
|
||||||
|
|
||||||
|
int cca_import_key_from_json_web_key(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
json_object *jwk, unsigned char *key_token,
|
||||||
|
size_t *key_token_length, bool verbose);
|
||||||
|
|
||||||
|
enum cca_kdf {
|
||||||
|
CCA_KDF_ANS_X9_63_CCA = 1, /* CCA DERIVE01 method */
|
||||||
|
CCA_KDF_ANS_X9_63_SHA224 = 2, /* CCA DERIVE02 method with SHA-224 */
|
||||||
|
CCA_KDF_ANS_X9_63_SHA256 = 3, /* CCA DERIVE02 method with SHA-256 */
|
||||||
|
CCA_KDF_ANS_X9_63_SHA384 = 4, /* CCA DERIVE02 method with SHA-284 */
|
||||||
|
CCA_KDF_ANS_X9_63_SHA512 = 5, /* CCA DERIVE02 method with SHA-512 */
|
||||||
|
};
|
||||||
|
|
||||||
|
int cca_ec_dh_derive_importer(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
const unsigned char *priv_ecc_key_token,
|
||||||
|
size_t priv_ecc_key_token_length,
|
||||||
|
const unsigned char *pub_ecc_key_token,
|
||||||
|
size_t pub_ecc_key_token_length,
|
||||||
|
const unsigned char *party_info,
|
||||||
|
size_t party_info_length,
|
||||||
|
enum cca_kdf kdf,
|
||||||
|
unsigned char *derived_key_token,
|
||||||
|
size_t *derived_key_token_length,
|
||||||
|
bool verbose);
|
||||||
|
|
||||||
|
int cca_import_external_key(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
const unsigned char *external_key_token,
|
||||||
|
size_t external_key_token_length,
|
||||||
|
const unsigned char *importer_key_token,
|
||||||
|
size_t importer_key_token_length,
|
||||||
|
unsigned char *imported_key_token,
|
||||||
|
size_t *imported_key_token_length,
|
||||||
|
bool verbose);
|
||||||
|
|
||||||
|
int cca_rsa_sign(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
const unsigned char *key_token, size_t key_token_length,
|
||||||
|
unsigned char *sig, size_t *siglen,
|
||||||
|
const unsigned char *tbs, size_t tbslen,
|
||||||
|
int padding_type, int digest_nid, bool verbose);
|
||||||
|
|
||||||
|
int cca_rsa_pss_sign(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
const unsigned char *key_token, size_t key_token_length,
|
||||||
|
unsigned char *sig, size_t *siglen,
|
||||||
|
const unsigned char *tbs, size_t tbslen,
|
||||||
|
int digest_nid, int mgf_digest_nid, int saltlen,
|
||||||
|
bool verbose);
|
||||||
|
|
||||||
|
int cca_ecdsa_sign(const struct ekmf_cca_lib *cca_lib,
|
||||||
|
const unsigned char *key_token, size_t key_token_length,
|
||||||
|
unsigned char *sig, size_t *siglen,
|
||||||
|
const unsigned char *tbs, size_t tbslen, int digest_nid,
|
||||||
|
bool verbose);
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
|||||||
|
LIBEKMFWEB_1.0 {
|
||||||
|
global:
|
||||||
|
ekmf_get_server_cert_chain;
|
||||||
|
ekmf_print_certificates;
|
||||||
|
ekmf_check_login_token;
|
||||||
|
ekmf_login;
|
||||||
|
ekmf_generate_identity_key;
|
||||||
|
ekmf_reencipher_identity_key;
|
||||||
|
ekmf_generate_csr;
|
||||||
|
ekmf_generate_ss_cert;
|
||||||
|
ekmf_get_public_key;
|
||||||
|
ekmf_get_settings;
|
||||||
|
ekmf_check_feature;
|
||||||
|
ekmf_retrieve_key;
|
||||||
|
ekmf_list_templates;
|
||||||
|
ekmf_get_template;
|
||||||
|
ekmf_get_last_seq_no;
|
||||||
|
ekmf_clone_template_info;
|
||||||
|
ekmf_free_template_info;
|
||||||
|
ekmf_list_keys;
|
||||||
|
ekmf_get_key_info;
|
||||||
|
ekmf_set_key_state;
|
||||||
|
ekmf_set_key_tags;
|
||||||
|
ekmf_delete_key_tags;
|
||||||
|
ekmf_clone_key_info;
|
||||||
|
ekmf_free_key_info;
|
||||||
|
ekmf_generate_key;
|
||||||
|
ekmf_curl_destroy;
|
||||||
|
local: *;
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* libekmfweb - EKMFWeb client library
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2020
|
||||||
|
*
|
||||||
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTILITIES_H
|
||||||
|
#define UTILITIES_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/obj_mac.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "ekmfweb/ekmfweb.h"
|
||||||
|
|
||||||
|
int decode_base64url(unsigned char *output, size_t *outlen,
|
||||||
|
const char *input, size_t inlen);
|
||||||
|
|
||||||
|
int encode_base64url(char *output, size_t *outlen,
|
||||||
|
const unsigned char *input, size_t inlen);
|
||||||
|
|
||||||
|
int parse_json_web_token(const char *token, json_object **header_obj,
|
||||||
|
json_object **payload_obj, unsigned char **signature,
|
||||||
|
size_t *signature_len);
|
||||||
|
|
||||||
|
int create_json_web_signature(const char *algorithm, bool b64, const char *kid,
|
||||||
|
const unsigned char *payload, size_t payload_len,
|
||||||
|
bool detached_payload, EVP_MD_CTX *md_ctx,
|
||||||
|
char **jws);
|
||||||
|
|
||||||
|
int verify_json_web_signature(const char *jws, const unsigned char *payload,
|
||||||
|
size_t payload_len, EVP_PKEY *pkey);
|
||||||
|
|
||||||
|
json_object *get_json_timestamp(void);
|
||||||
|
|
||||||
|
int json_build_tag_def_list(json_object *array,
|
||||||
|
struct ekmf_tag_def_list *tag_def_list,
|
||||||
|
bool copy);
|
||||||
|
int clone_tag_def_list(const struct ekmf_tag_def_list *src,
|
||||||
|
struct ekmf_tag_def_list *dest);
|
||||||
|
void free_tag_def_list(struct ekmf_tag_def_list *tag_def_list, bool free_tags);
|
||||||
|
|
||||||
|
int json_build_template_info(json_object *obj,
|
||||||
|
struct ekmf_template_info *template,
|
||||||
|
bool copy);
|
||||||
|
int clone_template_info(const struct ekmf_template_info *src,
|
||||||
|
struct ekmf_template_info *dest);
|
||||||
|
void free_template_info(struct ekmf_template_info *template);
|
||||||
|
|
||||||
|
int json_build_tag_list(json_object *array, struct ekmf_tag_list *tag_list,
|
||||||
|
bool copy);
|
||||||
|
int build_json_tag_list(const struct ekmf_tag_list *tag_list,
|
||||||
|
json_object **tags_obj);
|
||||||
|
int clone_tag_list(const struct ekmf_tag_list *src,
|
||||||
|
struct ekmf_tag_list *dest);
|
||||||
|
void free_tag_list(struct ekmf_tag_list *tag_list, bool free_tags);
|
||||||
|
|
||||||
|
int json_build_export_control(json_object *export_control,
|
||||||
|
struct ekmf_export_control *export_info,
|
||||||
|
bool copy);
|
||||||
|
int clone_export_control(const struct ekmf_export_control *src,
|
||||||
|
struct ekmf_export_control *dest);
|
||||||
|
void free_export_control(struct ekmf_export_control *export_control,
|
||||||
|
bool free_keys);
|
||||||
|
|
||||||
|
int json_build_key_info(json_object *obj, json_object *custom_tags,
|
||||||
|
json_object *export_control,
|
||||||
|
struct ekmf_key_info *key, bool copy);
|
||||||
|
int clone_key_info(const struct ekmf_key_info *src,
|
||||||
|
struct ekmf_key_info *dest);
|
||||||
|
void free_key_info(struct ekmf_key_info *key);
|
||||||
|
|
||||||
|
char *get_http_header_value(const struct curl_slist *headers, const char *name);
|
||||||
|
|
||||||
|
size_t ecc_get_curve_prime_bits(int curve_nid);
|
||||||
|
size_t ecc_get_curve_prime_length(int curve_nid);
|
||||||
|
const char *ecc_get_curve_id(int curve_nid);
|
||||||
|
bool ecc_is_prime_curve(int curve_nid);
|
||||||
|
bool ecc_is_brainpool_curve(int curve_nid);
|
||||||
|
int ecc_get_curve_by_id(const char *curve_id);
|
||||||
|
int ecc_get_prime_curve_by_prime_bits(size_t prime_bits);
|
||||||
|
int ecc_get_brainpool_curve_by_prime_bits(size_t prime_bits);
|
||||||
|
|
||||||
|
int ecc_calculate_y_coordinate(int nid, size_t prime_len,
|
||||||
|
const unsigned char *x, int y_bit,
|
||||||
|
unsigned char *y);
|
||||||
|
|
||||||
|
int ecc_pub_key_as_pkey(int nid, size_t prime_len, const unsigned char *x,
|
||||||
|
const unsigned char *y, EVP_PKEY **pkey);
|
||||||
|
|
||||||
|
int rsa_pub_key_as_pkey(const unsigned char *modulus, size_t modulus_length,
|
||||||
|
const unsigned char *pub_exp, size_t pub_exp_length,
|
||||||
|
int pkey_type, EVP_PKEY **pkey);
|
||||||
|
|
||||||
|
int json_web_key_as_pkey(json_object *jwk, int pkey_type, EVP_PKEY **pkey);
|
||||||
|
|
||||||
|
int write_key_blob(const char *filename, unsigned char *key_blob,
|
||||||
|
size_t key_blob_len);
|
||||||
|
|
||||||
|
int read_key_blob(const char *filename, unsigned char *key_blob,
|
||||||
|
size_t *key_blob_len);
|
||||||
|
|
||||||
|
int read_x509_certificate(const char *pem_filename, X509 **cert);
|
||||||
|
|
||||||
|
int write_x509_certificate(const char *pem_filename, X509 *cert);
|
||||||
|
|
||||||
|
int write_x509_request(const char *pem_filename, X509_REQ *req, bool new_hdr);
|
||||||
|
|
||||||
|
int read_public_key(const char *pem_filename, EVP_PKEY **pkey);
|
||||||
|
|
||||||
|
int write_public_key(const char *pem_filename, EVP_PKEY *pkey);
|
||||||
|
|
||||||
|
typedef int (*rsa_sign_t)(const unsigned char *key_blob, size_t key_blob_length,
|
||||||
|
unsigned char *sig, size_t *siglen,
|
||||||
|
const unsigned char *tbs, size_t tbslen,
|
||||||
|
int padding_type, int md_nid,
|
||||||
|
void *private);
|
||||||
|
typedef int (*rsa_pss_sign_t)(const unsigned char *key_blob,
|
||||||
|
size_t key_blob_length, unsigned char *sig,
|
||||||
|
size_t *siglen, const unsigned char *tbs,
|
||||||
|
size_t tbslen, int md_nid, int mfgmd_nid,
|
||||||
|
int saltlen, void *private);
|
||||||
|
typedef int (*ecdsa_sign_t)(const unsigned char *key_blob,
|
||||||
|
size_t key_blob_length, unsigned char *sig,
|
||||||
|
size_t *siglen, const unsigned char *tbs,
|
||||||
|
size_t tbslen, int md_nid, void *private);
|
||||||
|
|
||||||
|
struct sk_pkey_sign_func {
|
||||||
|
rsa_sign_t rsa_sign;
|
||||||
|
rsa_pss_sign_t rsa_pss_sign;
|
||||||
|
ecdsa_sign_t ecdsa_sign;
|
||||||
|
};
|
||||||
|
|
||||||
|
int setup_secure_key_pkey_method(int pkey_id);
|
||||||
|
int cleanup_secure_key_pkey_method(int pkey_id);
|
||||||
|
int setup_secure_key_pkey_context(EVP_PKEY_CTX *pkey_ctx,
|
||||||
|
const unsigned char *key_blob,
|
||||||
|
size_t key_blob_len,
|
||||||
|
struct sk_pkey_sign_func *sign_funcs,
|
||||||
|
void *private);
|
||||||
|
|
||||||
|
int setup_rsa_pss_pkey_context(EVP_PKEY_CTX *pkey_ctx,
|
||||||
|
struct ekmf_rsa_pss_params *rsa_pss_params);
|
||||||
|
|
||||||
|
int build_subject_name(X509_NAME **name, const char *rdns[], size_t num_rdns,
|
||||||
|
bool utf8);
|
||||||
|
|
||||||
|
int build_certificate_extensions(X509 *cert, X509_REQ *req,
|
||||||
|
const char *exts[], size_t num_exts,
|
||||||
|
const STACK_OF(X509_EXTENSION) *addl_exts);
|
||||||
|
|
||||||
|
int generate_x509_serial_number(X509 *cert, size_t sn_bit_size);
|
||||||
|
|
||||||
|
const char *json_get_string(json_object *obj, const char *name);
|
||||||
|
|
||||||
|
int json_object_get_base64url(json_object *obj, const char *name,
|
||||||
|
unsigned char *data, size_t *data_len);
|
||||||
|
|
||||||
|
json_object *json_object_new_base64url(const unsigned char *data, size_t len);
|
||||||
|
|
||||||
|
#ifndef JSON_C_OBJECT_ADD_KEY_IS_NEW
|
||||||
|
#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1 << 1)
|
||||||
|
#define IMPLEMENT_LOCAL_JSON_OBJECT_OBJECT_ADD
|
||||||
|
|
||||||
|
int json_object_object_add_ex(struct json_object *obj, const char *const key,
|
||||||
|
struct json_object *const val,
|
||||||
|
const unsigned int opts);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -43,6 +43,7 @@ util_prg_example: util_prg_example.o $(lib)
|
|||||||
util_rec_example: util_rec_example.o $(lib)
|
util_rec_example: util_rec_example.o $(lib)
|
||||||
|
|
||||||
$(lib): $(objects)
|
$(lib): $(objects)
|
||||||
|
$(lib): ALL_CFLAGS += -fPIC
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
|
||||||
|
|||||||
@@ -281,6 +281,44 @@ int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a file and convert it to signed int according to given base
|
||||||
|
*
|
||||||
|
* @param[out] val Buffer for value
|
||||||
|
* @param[in] base Base for conversion, either 8, 10, or 16
|
||||||
|
* @param[in] fmt Format string for generation of the path name
|
||||||
|
* @param[in] ... Parameters for format string
|
||||||
|
*
|
||||||
|
* @retval 0 Integer has been read correctly
|
||||||
|
* @retval -1 Error while reading file
|
||||||
|
*/
|
||||||
|
int util_file_read_i(int *val, int base, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX], buf[512];
|
||||||
|
va_list ap;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
/* Construct the file name */
|
||||||
|
UTIL_VSPRINTF(path, fmt, ap);
|
||||||
|
|
||||||
|
if (file_gets(buf, sizeof(buf), path))
|
||||||
|
return -1;
|
||||||
|
switch (base) {
|
||||||
|
case 8:
|
||||||
|
count = sscanf(buf, "%do", val);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
count = sscanf(buf, "%dd", val);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
count = sscanf(buf, "%dx", val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
util_panic("Invalid base: %d\n", base);
|
||||||
|
}
|
||||||
|
return (count == 1) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a file and convert it to signed long according to given base
|
* Read a file and convert it to signed long according to given base
|
||||||
*
|
*
|
||||||
@@ -357,6 +395,44 @@ int util_file_read_ll(long long *val, int base, const char *fmt, ...)
|
|||||||
return (count == 1) ? 0 : -1;
|
return (count == 1) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a file and convert it to unsigned int according to given base
|
||||||
|
*
|
||||||
|
* @param[out] val Buffer for value
|
||||||
|
* @param[in] base Base for conversion, either 8, 10, or 16
|
||||||
|
* @param[in] fmt Format string for generation of the path name
|
||||||
|
* @param[in] ... Parameters for format string
|
||||||
|
*
|
||||||
|
* @retval 0 Integer has been read correctly
|
||||||
|
* @retval -1 Error while reading file
|
||||||
|
*/
|
||||||
|
int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX], buf[512];
|
||||||
|
va_list ap;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
/* Construct the file name */
|
||||||
|
UTIL_VSPRINTF(path, fmt, ap);
|
||||||
|
|
||||||
|
if (file_gets(buf, sizeof(buf), path))
|
||||||
|
return -1;
|
||||||
|
switch (base) {
|
||||||
|
case 8:
|
||||||
|
count = sscanf(buf, "%uo", val);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
count = sscanf(buf, "%uu", val);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
count = sscanf(buf, "%ux", val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
util_panic("Invalid base: %d\n", base);
|
||||||
|
}
|
||||||
|
return (count == 1) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a file and convert it to unsigned long according to given base
|
* Read a file and convert it to unsigned long according to given base
|
||||||
*
|
*
|
||||||
@@ -432,3 +508,31 @@ int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
return (count == 1) ? 0 : -1;
|
return (count == 1) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a file and convert it according to format string
|
||||||
|
*
|
||||||
|
* @param[in] path File name to read
|
||||||
|
* @param[in] fmt Format string for parsing the content
|
||||||
|
* @param[out] ... Parameters for format string
|
||||||
|
*
|
||||||
|
* @retval != -1 Number of values parsed correctly
|
||||||
|
* @retval -1 Error while reading file
|
||||||
|
*/
|
||||||
|
|
||||||
|
int util_file_read_va(const char *path, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (file_gets(buf, sizeof(buf), path))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = vsscanf(buf, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (ret == EOF)
|
||||||
|
return -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -460,7 +460,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
|||||||
rc = scan_mnt_entry(&file, entry);
|
rc = scan_mnt_entry(&file, entry);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
if (!strcmp(entry->spec, spec)) {
|
if (!strcmp(entry->vfstype, spec)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|||||||
+103
-2
@@ -11,17 +11,114 @@
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_file.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_path.h"
|
#include "lib/util_path.h"
|
||||||
#include "lib/util_sys.h"
|
#include "lib/util_sys.h"
|
||||||
|
|
||||||
/* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */
|
/* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */
|
||||||
#define READLINK_SIZE 256
|
#define READLINK_SIZE 256
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the partition number of a given partition.
|
||||||
|
*
|
||||||
|
* @param[in] dev Device node of interest
|
||||||
|
*
|
||||||
|
* @retval int Partition number of the device
|
||||||
|
* @retval -1 Error when trying to read the partition number.
|
||||||
|
*/
|
||||||
|
int util_sys_get_partnum(dev_t dev)
|
||||||
|
{
|
||||||
|
int partnum = -1;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = util_path_sysfs("dev/block/%u:%u/partition",
|
||||||
|
major(dev), minor(dev));
|
||||||
|
if (util_file_read_i(&partnum, 10, path)) {
|
||||||
|
warnx("Could not read from path '%s'", path);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (partnum <= 0) {
|
||||||
|
warnx("Bad partition number in '%s'", path);
|
||||||
|
partnum = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(path);
|
||||||
|
return partnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given device is a partition.
|
||||||
|
*
|
||||||
|
* @param[in] dev Device node of interest
|
||||||
|
*
|
||||||
|
* @retval true Device is partition
|
||||||
|
* @retval false Device is not a partition
|
||||||
|
*/
|
||||||
|
bool util_sys_dev_is_partition(dev_t dev)
|
||||||
|
{
|
||||||
|
bool is_part;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = util_path_sysfs("dev/block/%u:%u/partition",
|
||||||
|
major(dev), minor(dev));
|
||||||
|
is_part = util_path_exists(path);
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return is_part;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine base device
|
||||||
|
*
|
||||||
|
* This function determines the base device \p base_dev of a given
|
||||||
|
* device \p dev. If \p dev is a base device, \p base_dev becomes \p dev.
|
||||||
|
*
|
||||||
|
* @param[in] dev Device node of interest
|
||||||
|
* @param[out] base_dev Identified base device
|
||||||
|
*
|
||||||
|
* @retval 0 Success
|
||||||
|
* @retval -1 Error while reading device information or
|
||||||
|
* constructed path
|
||||||
|
*/
|
||||||
|
int util_sys_get_base_dev(dev_t dev, dev_t *base_dev)
|
||||||
|
{
|
||||||
|
int base_major, base_minor;
|
||||||
|
char buf[PAGE_SIZE];
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
/* check if the device already is a base device */
|
||||||
|
if (!util_sys_dev_is_partition(dev)) {
|
||||||
|
*base_dev = makedev(major(dev), minor(dev));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
path = util_path_sysfs("dev/block/%d:%d/../dev",
|
||||||
|
major(dev), minor(dev));
|
||||||
|
if (util_file_read_line(buf, sizeof(buf), path)) {
|
||||||
|
warnx("Could not read from path '%s'", path);
|
||||||
|
free(path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
|
||||||
|
warn("Could not parse major:minor from string '%s'", buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*base_dev = makedev(base_major, base_minor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identify device address
|
* Identify device address
|
||||||
@@ -44,13 +141,17 @@ int util_sys_get_dev_addr(const char *dev, char *addr)
|
|||||||
unsigned int maj, min;
|
unsigned int maj, min;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
dev_t base;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
if (stat(dev, &s) != 0)
|
if (stat(dev, &s) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
maj = major(s.st_rdev);
|
if (util_sys_get_base_dev(s.st_rdev, &base))
|
||||||
min = minor(s.st_rdev);
|
return -1;
|
||||||
|
|
||||||
|
maj = major(base);
|
||||||
|
min = minor(base);
|
||||||
|
|
||||||
if (S_ISBLK(s.st_mode))
|
if (S_ISBLK(s.st_mode))
|
||||||
path = util_path_sysfs("dev/block/%u:%u/device", maj, min);
|
path = util_path_sysfs("dev/block/%u:%u/device", maj, min);
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
include ../common.mak
|
||||||
|
|
||||||
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
all: lsstp
|
||||||
|
|
||||||
|
lsstp: lsstp.o $(libs)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) \
|
||||||
|
$(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lsstp $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 lsstp.8 \
|
||||||
|
$(DESTDIR)$(MANDIR)/man8
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ lsstp core
|
||||||
|
|
||||||
|
.PHONY: all install clean
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
.\" Copyright 2020 IBM Corp.
|
||||||
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
.\"
|
||||||
|
.TH LSSTP 8 "Jul 2020" "s390-tools" "Linux Administrator's Manual"
|
||||||
|
.SH NAME
|
||||||
|
.B "lsstp "
|
||||||
|
\- Show STP configuration information
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BI "lsstp "
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B lsstp
|
||||||
|
displays information about the current Server Time Protocol (STP) configuration
|
||||||
|
like coordinated time network (CTN) ID, timing state and leap seconds.
|
||||||
|
.SH OUTPUT
|
||||||
|
.TP
|
||||||
|
.B STP online
|
||||||
|
Indication of the online state
|
||||||
|
.TP
|
||||||
|
.B CTN ID
|
||||||
|
The ID of the coordinated time network. If it can be decoded as EBCDIC it is shown as an EBCDIC string, otherwise a hexadecimal representation is shown.
|
||||||
|
.TP
|
||||||
|
.B CTN Type
|
||||||
|
The type of timing network.
|
||||||
|
.IP
|
||||||
|
.B No CTN
|
||||||
|
STP is not configured for attachment to a CTN.
|
||||||
|
.IP
|
||||||
|
.B STP-only
|
||||||
|
STP is configured and attached to a CTN with only STP nodes.
|
||||||
|
.IP
|
||||||
|
.B Mixed
|
||||||
|
STP is configured and attached to a CTN with both STP and external time reference (ETR) nodes.
|
||||||
|
.TP
|
||||||
|
.B Stratum
|
||||||
|
The number of servers in the timing path between the local STP clock and the selected primary time server.
|
||||||
|
.TP
|
||||||
|
.B Timing mode
|
||||||
|
.IP
|
||||||
|
.B Local
|
||||||
|
The Time-of-day (TOD) clock is stepped by the local hardware oscillator and is not steered by the STP facility.
|
||||||
|
.IP
|
||||||
|
.B ETR
|
||||||
|
The TOD clock is synchronized with an attached 9037 Sysplex Timer.
|
||||||
|
.IP
|
||||||
|
.B STP
|
||||||
|
The TOD clock is steered by the STP facility to maintain synchronization with a Coordinated Server Time (CST).
|
||||||
|
.IP
|
||||||
|
.B Uninitialized
|
||||||
|
The TOD clock is not initialized. The STP facility is allowed to perform a step adjustment to the TOD clock for synchronization.
|
||||||
|
.TP
|
||||||
|
.B Timing state
|
||||||
|
The synchronization state of the STP facility. Can be unsynchronized, synchronized or stopped.
|
||||||
|
.TP
|
||||||
|
.B DST offset
|
||||||
|
The daylight savings time offset relative to UTC in minutes.
|
||||||
|
.TP
|
||||||
|
.B Timezone offset
|
||||||
|
The offset of the local time relative to UTC in minutes.
|
||||||
|
.TP
|
||||||
|
.B Time offset
|
||||||
|
The total time offset at the server. This field is only valid in mixed CTN configurations.
|
||||||
|
.TP
|
||||||
|
.B Active leap seconds
|
||||||
|
The number of leap seconds that are currently in effect at the STP facility.
|
||||||
|
.TP
|
||||||
|
.B Leap second <insertion|deletion> at
|
||||||
|
If a leap second insertion or deletion is scheduled in the STP facility, this field shows the day and time of the scheduled change.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI "-v|--version"
|
||||||
|
Print version number.
|
||||||
|
.TP
|
||||||
|
.BI "-h|--help"
|
||||||
|
Print usage text.
|
||||||
|
|
||||||
|
.SH AUTHORS
|
||||||
|
Sven Schnelle <svens@linux.ibm.com>
|
||||||
+218
@@ -0,0 +1,218 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <iconv.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "lib/util_opt.h"
|
||||||
|
#include "lib/util_file.h"
|
||||||
|
#include "lib/util_prg.h"
|
||||||
|
#include "lib/util_path.h"
|
||||||
|
|
||||||
|
static const struct util_prg prg = {
|
||||||
|
.desc = "Display STP system information",
|
||||||
|
.args = "",
|
||||||
|
.copyright_vec = {
|
||||||
|
{
|
||||||
|
.owner = "IBM Corp.",
|
||||||
|
.pub_first = 2020,
|
||||||
|
},
|
||||||
|
UTIL_PRG_COPYRIGHT_END
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct util_opt opt_vec[] = {
|
||||||
|
UTIL_OPT_HELP,
|
||||||
|
UTIL_OPT_VERSION,
|
||||||
|
UTIL_OPT_END
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stp_parms {
|
||||||
|
uint64_t ctn_id;
|
||||||
|
unsigned int online;
|
||||||
|
unsigned int leap_seconds;
|
||||||
|
int leap_seconds_diff;
|
||||||
|
unsigned int leap_seconds_utc;
|
||||||
|
unsigned int stratum;
|
||||||
|
unsigned int ctn_type;
|
||||||
|
unsigned int timing_mode;
|
||||||
|
unsigned int timing_state;
|
||||||
|
int dst_offset;
|
||||||
|
int time_offset;
|
||||||
|
int time_zone_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int convert_ctn_id(char *in, char *out)
|
||||||
|
{
|
||||||
|
iconv_t ic;
|
||||||
|
size_t inlen = sizeof(unsigned long long);
|
||||||
|
size_t outlen = sizeof(unsigned long long);
|
||||||
|
|
||||||
|
ic = iconv_open("ISO-8859-1", "EBCDIC-US");
|
||||||
|
if (ic == (iconv_t)-1) {
|
||||||
|
warn("Could not initialize EBCDIC to ISO-8859-1 conversion table");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconv(ic, &in, &inlen, (char **)&out, &outlen) == (size_t)-1) {
|
||||||
|
warn("Code page translation EBCDIC to ISO-8859-1 failed");
|
||||||
|
iconv_close(ic);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
iconv_close(ic);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *ctn_type_str(int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
return "No CTN defined";
|
||||||
|
case 1:
|
||||||
|
return "STP-only";
|
||||||
|
case 2:
|
||||||
|
return "mixed";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *tmd_to_str(int mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
return "Local";
|
||||||
|
case 1:
|
||||||
|
return "ETR";
|
||||||
|
case 2:
|
||||||
|
return "STP";
|
||||||
|
case 15:
|
||||||
|
return "Uninitialized";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *tst_to_str(int mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
return "Unsynchronized";
|
||||||
|
case 1:
|
||||||
|
return "Synchronized";
|
||||||
|
case 2:
|
||||||
|
return "Physical clock stopped";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *yesno_str(int val)
|
||||||
|
{
|
||||||
|
return val ? "yes" : "no";
|
||||||
|
}
|
||||||
|
|
||||||
|
#define read_sysfs_attr(attr, parm, func, base) \
|
||||||
|
do { \
|
||||||
|
path = util_path_sysfs("devices/system/stp/%s", attr); \
|
||||||
|
ret = func(parm, base, path); \
|
||||||
|
if (ret) { \
|
||||||
|
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); \
|
||||||
|
free(path); \
|
||||||
|
exit(EXIT_FAILURE); \
|
||||||
|
} \
|
||||||
|
free(path); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct stp_parms parm = { 0 };
|
||||||
|
char ctn_id[32] = { 0 };
|
||||||
|
char *path;
|
||||||
|
int ret, c;
|
||||||
|
|
||||||
|
util_prg_init(&prg);
|
||||||
|
util_opt_init(opt_vec, NULL);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = util_opt_getopt_long(argc, argv);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'v':
|
||||||
|
util_prg_print_version();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
case 'h':
|
||||||
|
util_prg_print_help();
|
||||||
|
util_opt_print_help();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Try 'lsstp --help' for more information.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read_sysfs_attr("online", &parm.online, util_file_read_ui, 10);
|
||||||
|
if (!parm.online) {
|
||||||
|
printf("STP disabled\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_sysfs_attr("ctn_id", &parm.ctn_id, util_file_read_ul, 16);
|
||||||
|
read_sysfs_attr("ctn_type", &parm.ctn_type, util_file_read_ui, 10);
|
||||||
|
read_sysfs_attr("stratum", &parm.stratum, util_file_read_ui, 10);
|
||||||
|
read_sysfs_attr("leap_seconds", &parm.leap_seconds, util_file_read_ui, 10);
|
||||||
|
read_sysfs_attr("timing_mode", &parm.timing_mode, util_file_read_ui, 10);
|
||||||
|
read_sysfs_attr("timing_state", &parm.timing_state, util_file_read_ui, 10);
|
||||||
|
read_sysfs_attr("dst_offset", &parm.dst_offset, util_file_read_i, 10);
|
||||||
|
read_sysfs_attr("time_offset", &parm.time_offset, util_file_read_i, 10);
|
||||||
|
read_sysfs_attr("time_zone_offset", &parm.time_zone_offset, util_file_read_i, 10);
|
||||||
|
|
||||||
|
if (convert_ctn_id((char *)&parm.ctn_id, ctn_id))
|
||||||
|
snprintf(ctn_id, sizeof(ctn_id)-1, "%016" PRIx64, parm.ctn_id);
|
||||||
|
|
||||||
|
printf("STP online: %s\n"
|
||||||
|
"CTN ID: %s\n"
|
||||||
|
"CTN type: %s\n"
|
||||||
|
"Stratum: %d\n"
|
||||||
|
"Timing mode: %s\n"
|
||||||
|
"Timing state: %s\n"
|
||||||
|
"DST offset: %d\n"
|
||||||
|
"Timezone offset: %d\n"
|
||||||
|
"Time offset: %d\n"
|
||||||
|
"Active leap seconds: %d\n",
|
||||||
|
yesno_str(parm.online),
|
||||||
|
ctn_id,
|
||||||
|
ctn_type_str(parm.ctn_type),
|
||||||
|
parm.stratum,
|
||||||
|
tmd_to_str(parm.timing_mode),
|
||||||
|
tst_to_str(parm.timing_state),
|
||||||
|
parm.dst_offset,
|
||||||
|
parm.time_zone_offset,
|
||||||
|
parm.time_offset,
|
||||||
|
parm.leap_seconds);
|
||||||
|
|
||||||
|
printf("Scheduled leap second: ");
|
||||||
|
|
||||||
|
path = util_path_sysfs("devices/system/stp/leap_seconds_scheduled");
|
||||||
|
if (util_file_read_va(path, "%d,%d", &parm.leap_seconds_utc,
|
||||||
|
&parm.leap_seconds_diff) == 2 &&
|
||||||
|
parm.leap_seconds_diff && parm.leap_seconds_utc) {
|
||||||
|
time_t lsoup = parm.leap_seconds_utc;
|
||||||
|
|
||||||
|
printf("%s at: %s UTC",
|
||||||
|
parm.leap_seconds_diff > 0 ? "insertion" : "deletion",
|
||||||
|
ctime(&lsoup));
|
||||||
|
} else {
|
||||||
|
printf("-\n");
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
return 0;
|
||||||
|
out:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
+28
-1
@@ -45,7 +45,7 @@ vmcmd: Trigger CP command according to the 'VMCMD_X' configuration in
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB - DUMP_TYPE:\fR
|
\fB - DUMP_TYPE:\fR
|
||||||
Type of dump device. Possible values are 'ccw' and 'fcp'.
|
Type of dump device. Possible values are 'ccw', 'fcp' and 'nvme'.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB - DEVICE:\fR
|
\fB - DEVICE:\fR
|
||||||
@@ -59,6 +59,14 @@ WWPN for SCSI dump device.
|
|||||||
\fB - LUN\fR
|
\fB - LUN\fR
|
||||||
LUN for SCSI dump device.
|
LUN for SCSI dump device.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB - FID\fR
|
||||||
|
Function ID for NVMe dump device.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB - NSID\fR
|
||||||
|
Namespace ID for NVMe dump device.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB - BOOTPROG:\fR
|
\fB - BOOTPROG:\fR
|
||||||
Boot program selector.
|
Boot program selector.
|
||||||
@@ -159,6 +167,25 @@ BOOTPROG=0
|
|||||||
BR_LBA=0
|
BR_LBA=0
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
#
|
||||||
|
.br
|
||||||
|
# Example configuration for an NVMe dump device (NVMe Disk)
|
||||||
|
.br
|
||||||
|
#
|
||||||
|
.br
|
||||||
|
ON_PANIC=dump
|
||||||
|
.br
|
||||||
|
DUMP_TYPE=nvme
|
||||||
|
.br
|
||||||
|
FID=0x0300
|
||||||
|
.br
|
||||||
|
NSID=0x0001
|
||||||
|
.br
|
||||||
|
BOOTPROG=0
|
||||||
|
.br
|
||||||
|
BR_LBA=0
|
||||||
|
.br
|
||||||
|
|
||||||
#
|
#
|
||||||
.br
|
.br
|
||||||
# Example configuration for CP commands
|
# Example configuration for CP commands
|
||||||
|
|||||||
+18
-6
@@ -2,15 +2,27 @@
|
|||||||
|
|
||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
|
SCRIPTS = mk-s390image mk-pxelinux-ramfs
|
||||||
NETBOOT_SAMPLEDIR=$(TOOLS_DATADIR)/netboot
|
NETBOOT_SAMPLEDIR=$(TOOLS_DATADIR)/netboot
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
||||||
install: all
|
install: install-scripts
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 \
|
||||||
$(INSTALL) -m 755 mk-s390image mk-pxelinux-ramfs \
|
Dockerfile Makefile.pxelinux.0 README.md mk-s390image.1 \
|
||||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
|
||||||
$(INSTALL) -m 644 Dockerfile Makefile.pxelinux.0 README.md \
|
|
||||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||||
|
|
||||||
.PHONY: all install clean
|
install-scripts: $(SCRIPTS)
|
||||||
|
@if [ ! -d $(DESTDIR)$(NETBOOT_SAMPLEDIR) ]; then \
|
||||||
|
mkdir -p $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||||
|
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||||
|
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||||
|
fi; \
|
||||||
|
for i in $^; do \
|
||||||
|
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||||
|
< $$i >$(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||||
|
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||||
|
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||||
|
done
|
||||||
|
|
||||||
|
.PHONY: all install clean install-scripts
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ ifeq ($(KERNEL_IMAGE),)
|
|||||||
$(error Could not find a kernel image under /boot)
|
$(error Could not find a kernel image under /boot)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
BUSYBOX=busybox-1.27.1
|
BUSYBOX=busybox-1.32.0
|
||||||
BBINSTALL=$(BUSYBOX)/_install
|
BBINSTALL=$(BUSYBOX)/_install
|
||||||
|
|
||||||
all: $(KERNEL_IMAGE) pxelinux.initramfs
|
all: $(KERNEL_IMAGE) pxelinux.initramfs
|
||||||
|
|||||||
@@ -54,9 +54,18 @@ OPTIONS
|
|||||||
-b Search installed busybox in directory BUSYBOX_DIR
|
-b Search installed busybox in directory BUSYBOX_DIR
|
||||||
-k Use KERNEL_VERSION instead of currently running kernel
|
-k Use KERNEL_VERSION instead of currently running kernel
|
||||||
-h Print this help, then exit
|
-h Print this help, then exit
|
||||||
|
-v Print version information, then exit
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printversion()
|
||||||
|
{
|
||||||
|
cat <<-EOD
|
||||||
|
$cmd: version %S390_TOOLS_VERSION%
|
||||||
|
Copyright IBM Corp. 2017
|
||||||
|
EOD
|
||||||
|
}
|
||||||
|
|
||||||
# Get shared objects for binary
|
# Get shared objects for binary
|
||||||
sharedobjs()
|
sharedobjs()
|
||||||
{
|
{
|
||||||
@@ -64,7 +73,7 @@ sharedobjs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check args
|
# Check args
|
||||||
args=$(getopt b:k:h $*)
|
args=$(getopt b:k:hv $*)
|
||||||
if [ $? = 0 ]
|
if [ $? = 0 ]
|
||||||
then
|
then
|
||||||
set -- $args
|
set -- $args
|
||||||
@@ -74,6 +83,7 @@ then
|
|||||||
-b) busyboxdir=$2; shift 2;;
|
-b) busyboxdir=$2; shift 2;;
|
||||||
-k) kernelversion=$2; shift 2;;
|
-k) kernelversion=$2; shift 2;;
|
||||||
-h) usage; exit 0;;
|
-h) usage; exit 0;;
|
||||||
|
-v) printversion; exit 0;;
|
||||||
--) shift; break;;
|
--) shift; break;;
|
||||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
+14
-1
@@ -60,9 +60,18 @@ OPTIONS
|
|||||||
-p Use PARMFILE with kernel parameters in the image
|
-p Use PARMFILE with kernel parameters in the image
|
||||||
-r Include RAMDISK in the image
|
-r Include RAMDISK in the image
|
||||||
-h Print this help, then exit
|
-h Print this help, then exit
|
||||||
|
-v Print version information, then exit
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printversion()
|
||||||
|
{
|
||||||
|
cat <<-EOD
|
||||||
|
$cmd: version %S390_TOOLS_VERSION%
|
||||||
|
Copyright IBM Corp. 2017
|
||||||
|
EOD
|
||||||
|
}
|
||||||
|
|
||||||
# Convert decimal number to big endian doubleword
|
# Convert decimal number to big endian doubleword
|
||||||
dec2be64()
|
dec2be64()
|
||||||
{
|
{
|
||||||
@@ -129,6 +138,9 @@ dobuild()
|
|||||||
parmfile_size=$(du -b $parmfile | cut -f1)
|
parmfile_size=$(du -b $parmfile | cut -f1)
|
||||||
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
|
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
|
||||||
then
|
then
|
||||||
|
# Clear any previous parameters
|
||||||
|
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count=$MAX_PARMFILE_SIZE \
|
||||||
|
if=/dev/zero of=$image conv=notrunc status=none
|
||||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
|
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
|
||||||
of=$image conv=notrunc status=none
|
of=$image conv=notrunc status=none
|
||||||
else
|
else
|
||||||
@@ -142,7 +154,7 @@ dobuild()
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check args and build
|
# check args and build
|
||||||
args=$(getopt "r:p:h" $*)
|
args=$(getopt "r:p:hv" $*)
|
||||||
if [ $? = 0 ]
|
if [ $? = 0 ]
|
||||||
then
|
then
|
||||||
set -- $args
|
set -- $args
|
||||||
@@ -152,6 +164,7 @@ then
|
|||||||
-r) ramdisk=$2; shift 2;;
|
-r) ramdisk=$2; shift 2;;
|
||||||
-p) parmfile=$2; shift 2;;
|
-p) parmfile=$2; shift 2;;
|
||||||
-h) usage; exit 0;;
|
-h) usage; exit 0;;
|
||||||
|
-v) printversion; exit 0;;
|
||||||
--) shift; break;;
|
--) shift; break;;
|
||||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
.TH MK-S390IMAGE "1" "November 2020" "s390-tools" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
mk-s390image \- tool for creating bootable image
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B mk-s390image
|
||||||
|
\fI\,KERNEL BOOT_IMAGE \/\fR[\fI\,-r RAMDISK\/\fR] [\fI\,-p PARMFILE\/\fR]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
|
||||||
|
KVM firmware image using a stripped Linux kernel file KERNEL.
|
||||||
|
.PP
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\fB\-p\fR Use PARMFILE with kernel parameters in the image
|
||||||
|
.TP
|
||||||
|
\fB\-r\fR Include RAMDISK in the image
|
||||||
|
.TP
|
||||||
|
\fB\-h\fR Print usage message, then exit
|
||||||
@@ -227,6 +227,16 @@ sub get_common
|
|||||||
# function name or hexadecimal caller address.
|
# function name or hexadecimal caller address.
|
||||||
#
|
#
|
||||||
$line =~ s/<\s+/</;
|
$line =~ s/<\s+/</;
|
||||||
|
#
|
||||||
|
# Since crash 7.2.9 commit
|
||||||
|
# https://github.com/crash-utility/crash/commit/f1f43bf355df2564543c39f5d7e13b15c67eb13d
|
||||||
|
# in support of kernel v5.9 commit 0990d836cecb
|
||||||
|
# ("s390/debug: debug feature version 3"),
|
||||||
|
# the symbolic caller function name is left aligned instead of right
|
||||||
|
# aligned, so now we alternatively have to remove whitespace between
|
||||||
|
# function name and offset.
|
||||||
|
#
|
||||||
|
$line =~ s/<([^+> ]+)[ \t]+/<\1/;
|
||||||
@common = split(/\s+/, $line);
|
@common = split(/\s+/, $line);
|
||||||
#
|
#
|
||||||
# Process symbolic kernel module name, if necessary.
|
# Process symbolic kernel module name, if necessary.
|
||||||
@@ -388,6 +398,17 @@ sub get_foreign_records
|
|||||||
# caller address.
|
# caller address.
|
||||||
#
|
#
|
||||||
$line =~ s/<\s+/</;
|
$line =~ s/<\s+/</;
|
||||||
|
#
|
||||||
|
# Since crash 7.2.9 commit
|
||||||
|
# https://github.com/crash-utility/crash/commit/f1f43bf355df2564543c39f5d7e13b15c67eb13d
|
||||||
|
# in support of kernel v5.9 commit 0990d836cecb
|
||||||
|
# ("s390/debug: debug feature version 3"),
|
||||||
|
# the symbolic caller function name is left aligned
|
||||||
|
# instead of right aligned, so now we alternatively
|
||||||
|
# have to remove whitespace between function name and
|
||||||
|
# offset.
|
||||||
|
#
|
||||||
|
$line =~ s/<([^+> ]+)[ \t]+/<\1/;
|
||||||
my @raw_rec = split(/\s+/,($line =~ /[|]/) ?
|
my @raw_rec = split(/\s+/,($line =~ /[|]/) ?
|
||||||
substr($line, 0, index($line, '|')):
|
substr($line, 0, index($line, '|')):
|
||||||
$line);
|
$line);
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ zipl-switch-to-blscfg \- Switch zipl to use BootLoaderSpec configuration
|
|||||||
\fBzipl-switch-to-blscfg\fP {\-h|\-v}
|
\fBzipl-switch-to-blscfg\fP {\-h|\-v}
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This script switches the zipl boot-loader configuration to use BootLoaderSpec files
|
This script switches the zipl boot-loader configuration to use BootLoaderSpec
|
||||||
to define IPL sections. For each Linux kernel defined in the zipl.conf config file,
|
files to define IPL sections. For each Linux kernel defined in the zipl.conf
|
||||||
a BLS fragment is generated in the BLS directory specified. Also, the zipl.conf is
|
config file, a BLS fragment is generated in the BLS directory specified. Also,
|
||||||
modified it only contains global configurations, all IPL sections comes from BLS.
|
zipl.conf is modified to only contain global configuration. All IPL sections
|
||||||
|
come from BLS files.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
@@ -30,7 +31,8 @@ The suffix used for backup files, defaults to .bak.
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-bls-directory <DIRECTORY>\fP
|
\fB\-\-bls-directory <DIRECTORY>\fP
|
||||||
The DIRECTORY where the BLS fragments will be generated. The directory is created if it doesn't exists, by default /boot/loader/entries is used.
|
The DIRECTORY where the BLS fragments will be stored. The directory is
|
||||||
|
created if it does not exist. By default /boot/loader/entries is used.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-config-file <FILE>\fP
|
\fB\-\-config-file <FILE>\fP
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
Description=Apply Control Program Identification (CPI)
|
Description=Apply Control Program Identification (CPI)
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
Conflicts=shutdown.target
|
Conflicts=shutdown.target
|
||||||
After=local-fs.target
|
After=sysinit.target
|
||||||
ConditionPathIsReadWrite=/sys/firmware/cpi
|
ConditionPathIsReadWrite=/sys/firmware/cpi
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
#
|
#
|
||||||
# Specify a file with the environment variables using the EnvironmentFile=
|
# Specify a file with the environment variables using the EnvironmentFile=
|
||||||
# service property.
|
# service property.
|
||||||
|
|||||||
+5
-2
@@ -387,6 +387,7 @@ function extended()
|
|||||||
read EXTSZ 2> /dev/null < $DEVPATH/extent_pool/extent_size
|
read EXTSZ 2> /dev/null < $DEVPATH/extent_pool/extent_size
|
||||||
read CAPACITY 2> /dev/null < $DEVPATH/capacity/logical_capacity
|
read CAPACITY 2> /dev/null < $DEVPATH/capacity/logical_capacity
|
||||||
read ALLOCATED 2> /dev/null < $DEVPATH/capacity/space_allocated
|
read ALLOCATED 2> /dev/null < $DEVPATH/capacity/space_allocated
|
||||||
|
read FC_SEC 2> /dev/null < $DEVPATH/fc_security
|
||||||
|
|
||||||
# convert to hexadecimal values
|
# convert to hexadecimal values
|
||||||
PIM=0x$PIM
|
PIM=0x$PIM
|
||||||
@@ -521,7 +522,7 @@ function extended()
|
|||||||
elif [[ "$ALIAS" == 1 ]]; then
|
elif [[ "$ALIAS" == 1 ]]; then
|
||||||
if [[ "$BASEONLY" == "false" ]]; then
|
if [[ "$BASEONLY" == "false" ]]; then
|
||||||
ACTIVE="alias"
|
ACTIVE="alias"
|
||||||
printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
||||||
"$SORTKEYLEN" "$SORTKEY" \
|
"$SORTKEYLEN" "$SORTKEY" \
|
||||||
"$BUSID" \
|
"$BUSID" \
|
||||||
"$ACTIVE" \
|
"$ACTIVE" \
|
||||||
@@ -532,6 +533,7 @@ function extended()
|
|||||||
"$ERP" \
|
"$ERP" \
|
||||||
"$HPF" \
|
"$HPF" \
|
||||||
"$DEV_UID" \
|
"$DEV_UID" \
|
||||||
|
"$FC_SEC" \
|
||||||
"${INSTALLED_PATHS[@]}" \
|
"${INSTALLED_PATHS[@]}" \
|
||||||
"${USED_PATHS[@]}" \
|
"${USED_PATHS[@]}" \
|
||||||
"${NP_PATHS[@]}" \
|
"${NP_PATHS[@]}" \
|
||||||
@@ -563,7 +565,7 @@ function extended()
|
|||||||
DISCIPLINE="${DISCIPLINE} (ESE)"
|
DISCIPLINE="${DISCIPLINE} (ESE)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
||||||
"$SORTKEYLEN" "$SORTKEY" \
|
"$SORTKEYLEN" "$SORTKEY" \
|
||||||
"$BUSID" \
|
"$BUSID" \
|
||||||
"$BLOCKNAME" \
|
"$BLOCKNAME" \
|
||||||
@@ -584,6 +586,7 @@ function extended()
|
|||||||
"$ERP" \
|
"$ERP" \
|
||||||
"$HPF" \
|
"$HPF" \
|
||||||
"$DEV_UID" \
|
"$DEV_UID" \
|
||||||
|
"$FC_SEC" \
|
||||||
"${INSTALLED_PATHS[@]}" \
|
"${INSTALLED_PATHS[@]}" \
|
||||||
"${USED_PATHS[@]}" \
|
"${USED_PATHS[@]}" \
|
||||||
"${NP_PATHS[@]}" \
|
"${NP_PATHS[@]}" \
|
||||||
|
|||||||
+41
-6
@@ -1,8 +1,10 @@
|
|||||||
.\" Copyright 2019 IBM Corp.
|
.\" chzcrypt.8
|
||||||
|
.\"
|
||||||
|
.\" Copyright 2020 IBM Corp.
|
||||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
.TH CHZCRYPT 8 "AUG 2019" "s390-tools"
|
.TH CHZCRYPT 8 "OCT 2020" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
chzcrypt \- modify zcrypt configuration
|
chzcrypt \- modify zcrypt configuration
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -16,6 +18,14 @@ chzcrypt \- modify zcrypt configuration
|
|||||||
[...] )
|
[...] )
|
||||||
.TP
|
.TP
|
||||||
.B chzcrypt
|
.B chzcrypt
|
||||||
|
.B --config-on
|
||||||
|
.RB "|"
|
||||||
|
.B --config-off
|
||||||
|
.RB "( " -a " | "
|
||||||
|
.I <device id>
|
||||||
|
[...] )
|
||||||
|
.TP
|
||||||
|
.B chzcrypt
|
||||||
.RB "[ " -p " | " -n " ] [ " -t
|
.RB "[ " -p " | " -n " ] [ " -t
|
||||||
.I <timeout>
|
.I <timeout>
|
||||||
]
|
]
|
||||||
@@ -54,11 +64,22 @@ Set the given cryptographic device(s) offline.
|
|||||||
.B -a, --all
|
.B -a, --all
|
||||||
Set all available cryptographic device(s) online or offline.
|
Set all available cryptographic device(s) online or offline.
|
||||||
.TP 8
|
.TP 8
|
||||||
|
.B --config-on
|
||||||
|
Set the given cryptographic card device(s) config on ('configured').
|
||||||
|
.TP 8
|
||||||
|
.B --config-off
|
||||||
|
Set the given cryptographic card device(s) config off ('deconfigured').
|
||||||
|
.TP 8
|
||||||
.B <device id>
|
.B <device id>
|
||||||
Specifies a cryptographic device which will be set either online or offline.
|
Specifies a cryptographic device which will be set either online or
|
||||||
The device can either be a card device or a queue device.
|
offline or configured on or off. For online and offline the device can
|
||||||
A queue device can only get switched online when the providing card is online.
|
either be a card device or a queue device. A queue device can only get
|
||||||
|
switched online when the providing card is online.
|
||||||
|
.br
|
||||||
|
For config on/off the device needs to be a card device. A card or
|
||||||
|
queue device cannot get switched online if the card is in deconfigured
|
||||||
|
state.
|
||||||
|
.br
|
||||||
Please note that the card device and queue device representation are both
|
Please note that the card device and queue device representation are both
|
||||||
in hexadecimal notation.
|
in hexadecimal notation.
|
||||||
.TP 8
|
.TP 8
|
||||||
@@ -103,11 +124,25 @@ Will set the cryptographic device '10.0038' respectively card id 16
|
|||||||
.B chzcrypt -d -a
|
.B chzcrypt -d -a
|
||||||
Will set all available cryptographic devices offline.
|
Will set all available cryptographic devices offline.
|
||||||
.TP
|
.TP
|
||||||
|
.B chzcrypt --config-on -a -V
|
||||||
|
Set all available crypto cards to config on, be verbose.
|
||||||
|
.TP
|
||||||
|
.B chzcrypt -V --config-off card01 card03
|
||||||
|
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
|
||||||
|
.TP
|
||||||
.B chzcrypt -c 60 -n
|
.B chzcrypt -c 60 -n
|
||||||
Will set configuration timer for re-scanning the AP bus to 60 seconds and
|
Will set configuration timer for re-scanning the AP bus to 60 seconds and
|
||||||
disable zcrypt's poll thread.
|
disable zcrypt's poll thread.
|
||||||
.TP
|
.TP
|
||||||
.B chzcrypt -q 67
|
.B chzcrypt -q 67
|
||||||
Will set the default domain to 67.
|
Will set the default domain to 67.
|
||||||
|
.SH NOTES
|
||||||
|
Support for crypto cards to get switched config on or off requires a
|
||||||
|
Linux kernel supporting this. If the required sysfs attribute file
|
||||||
|
does not exist, it is assumed there is an older kernel running and
|
||||||
|
chzcrypt exits with an appropriate message. Even more config on/off
|
||||||
|
may require support from a hypervisor like KVM or zVM and may fail if
|
||||||
|
the Linux kernel is unable to perform the SCLP command. Check syslog
|
||||||
|
on failure.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
\fBlszcrypt\fR(8)
|
\fBlszcrypt\fR(8)
|
||||||
|
|||||||
+149
-43
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* chzcrypt - Tool to modify zcrypt configuration
|
* chzcrypt - Tool to modify zcrypt configuration
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2008, 2019
|
* Copyright IBM Corp. 2008, 2020
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -47,7 +47,7 @@ const struct util_prg prg = {
|
|||||||
{
|
{
|
||||||
.owner = "IBM Corp.",
|
.owner = "IBM Corp.",
|
||||||
.pub_first = 2008,
|
.pub_first = 2008,
|
||||||
.pub_last = 2019,
|
.pub_last = 2020,
|
||||||
},
|
},
|
||||||
UTIL_PRG_COPYRIGHT_END
|
UTIL_PRG_COPYRIGHT_END
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,10 @@ const struct util_prg prg = {
|
|||||||
/*
|
/*
|
||||||
* Configuration of command line options
|
* Configuration of command line options
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define OPT_CONFIG_ON 0x80
|
||||||
|
#define OPT_CONFIG_OFF 0x81
|
||||||
|
|
||||||
static struct util_opt opt_vec[] = {
|
static struct util_opt opt_vec[] = {
|
||||||
{
|
{
|
||||||
.option = { "enable", no_argument, NULL, 'e'},
|
.option = { "enable", no_argument, NULL, 'e'},
|
||||||
@@ -73,6 +77,18 @@ static struct util_opt opt_vec[] = {
|
|||||||
"online/offline, must be used in conjunction "
|
"online/offline, must be used in conjunction "
|
||||||
"with the enable or disable option",
|
"with the enable or disable option",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.option = { "config-on", no_argument, NULL, OPT_CONFIG_ON},
|
||||||
|
.argument = "DEVICE_IDS",
|
||||||
|
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||||
|
.desc = "Set the given cryptographic card device(s) configured"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.option = { "config-off", no_argument, NULL, OPT_CONFIG_OFF},
|
||||||
|
.argument = "DEVICE_IDS",
|
||||||
|
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||||
|
.desc = "Set the given cryptographic card device(s) deconfigured"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.option = { "poll-thread-enable", no_argument, NULL, 'p'},
|
.option = { "poll-thread-enable", no_argument, NULL, 'p'},
|
||||||
.desc = "Enable zcrypt's poll thread",
|
.desc = "Enable zcrypt's poll thread",
|
||||||
@@ -212,6 +228,116 @@ static void default_domain_set(const char *default_domain_str)
|
|||||||
free(attr);
|
free(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_online(const char *online, const char *online_text,
|
||||||
|
char *dev_list, size_t len)
|
||||||
|
{
|
||||||
|
long value;
|
||||||
|
int id, dom;
|
||||||
|
char *dev, *dev_path;
|
||||||
|
char device[256], online_read[32];
|
||||||
|
|
||||||
|
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
||||||
|
if (strncmp(dev, "card", 4) == 0) {
|
||||||
|
/* dev == "card2" */
|
||||||
|
if (sscanf(dev, "card%02x", &id) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||||
|
sprintf(device, "card%02x", id);
|
||||||
|
} else if (strncmp(dev, "0x", 2) == 0) {
|
||||||
|
/* dev == "0x.." */
|
||||||
|
if (sscanf(dev, "0x%02x", &id) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||||
|
sprintf(device, "card%02x", id);
|
||||||
|
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
||||||
|
/* dev == "2" */
|
||||||
|
if (sscanf(dev, "%02x", &id) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||||
|
sprintf(device, "card%02x", id);
|
||||||
|
} else {
|
||||||
|
/* Form: 01.0003 ? */
|
||||||
|
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - cryptographic device %s malformed.", dev);
|
||||||
|
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
|
||||||
|
}
|
||||||
|
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
||||||
|
if (!util_path_is_dir(dev_path))
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - cryptographic device %s does not exist.", device);
|
||||||
|
if (!util_path_is_writable("%s/online", dev_path))
|
||||||
|
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n"
|
||||||
|
" Wrong permissions or wrong tools version.", dev_path);
|
||||||
|
if (*online == '1' && util_path_is_readable("%s/config", dev_path)) {
|
||||||
|
util_file_read_l(&value, 10, "%s/config", dev_path);
|
||||||
|
if (value <= 0) {
|
||||||
|
warnx("Warning - device %s is deconfigured,"
|
||||||
|
" can't set to online.\n", dev);
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
||||||
|
util_file_write_s(online, "%s/online", dev_path);
|
||||||
|
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
||||||
|
if (strcmp(online, online_read) != 0)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||||
|
device, online_text);
|
||||||
|
next:
|
||||||
|
free(dev_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_config(const char *config, const char *config_text,
|
||||||
|
char *dev_list, size_t len)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char *dev, *dev_path;
|
||||||
|
char device[256], config_read[32];
|
||||||
|
|
||||||
|
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
||||||
|
if (strncmp(dev, "card", 4) == 0) {
|
||||||
|
/* dev == "card2" */
|
||||||
|
if (sscanf(dev, "card%02x", &id) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||||
|
sprintf(device, "card%02x", id);
|
||||||
|
} else if (strncmp(dev, "0x", 2) == 0) {
|
||||||
|
/* dev == "0x.." */
|
||||||
|
if (sscanf(dev, "0x%02x", &id) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||||
|
sprintf(device, "card%02x", id);
|
||||||
|
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
||||||
|
/* dev == "2" */
|
||||||
|
if (sscanf(dev, "%02x", &id) != 1)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||||
|
sprintf(device, "card%02x", id);
|
||||||
|
} else {
|
||||||
|
errx(EXIT_FAILURE, "Error - invalid device %s\n"
|
||||||
|
" Config on/off is only valid for card devices.", dev);
|
||||||
|
}
|
||||||
|
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
||||||
|
if (!util_path_is_dir(dev_path))
|
||||||
|
errx(EXIT_FAILURE,
|
||||||
|
"Error - cryptographic device %s does not exist.", device);
|
||||||
|
if (!util_path_is_readable("%s/config", dev_path))
|
||||||
|
errx(EXIT_FAILURE, "Error - can't read %s/config.\n"
|
||||||
|
"File may not exist due to an older zcrypt device driver.", dev_path);
|
||||||
|
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
|
||||||
|
if (strcmp(config, config_read) == 0) {
|
||||||
|
warnx("Warning - device %s is already %s.", device, config_text);
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
if (!util_path_is_writable("%s/config", dev_path))
|
||||||
|
errx(EXIT_FAILURE, "Error - can't write to %s/config.\n"
|
||||||
|
"Wrong permissions or wrong tools version.", dev_path);
|
||||||
|
verbose("Setting cryptographic device %s %s\n", device, config_text);
|
||||||
|
util_file_write_s(config, "%s/config", dev_path);
|
||||||
|
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
|
||||||
|
if (strcmp(config, config_read) != 0)
|
||||||
|
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||||
|
device, config_text);
|
||||||
|
next:
|
||||||
|
free(dev_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print invalid commandline error message and then exit with error code
|
* Print invalid commandline error message and then exit with error code
|
||||||
*/
|
*/
|
||||||
@@ -276,7 +402,6 @@ void print_adapter_id_help(void)
|
|||||||
printf(" Enable the cryptographic devices with card id '03' and domain id '0005'.\n");
|
printf(" Enable the cryptographic devices with card id '03' and domain id '0005'.\n");
|
||||||
printf(" #>chzcrypt -e 03.0005\n");
|
printf(" #>chzcrypt -e 03.0005\n");
|
||||||
printf(" \n");
|
printf(" \n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -284,19 +409,19 @@ void print_adapter_id_help(void)
|
|||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const char *online, *online_text = NULL, *poll_thread, *config_time;
|
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
|
||||||
const char *poll_timeout, *default_domain;
|
const char *config_time = NULL, *poll_timeout = NULL;
|
||||||
char *path, *dev_path, *dev, *dev_list, device[256], online_read[32];
|
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
||||||
|
char *path, *dev_list;
|
||||||
bool all = false, actionset = false;
|
bool all = false, actionset = false;
|
||||||
size_t len;
|
size_t len;
|
||||||
int id, dom, c, i, j;
|
int c, i, j;
|
||||||
|
|
||||||
for (i=0; i < argc; i++)
|
for (i=0; i < argc; i++)
|
||||||
for (j=2; j < (int) strlen(argv[i]); j++)
|
for (j=2; j < (int) strlen(argv[i]); j++)
|
||||||
if (argv[i][j] == '_')
|
if (argv[i][j] == '_')
|
||||||
argv[i][j] = '-';
|
argv[i][j] = '-';
|
||||||
|
|
||||||
online = poll_thread = config_time = poll_timeout = default_domain = NULL;
|
|
||||||
util_prg_init(&prg);
|
util_prg_init(&prg);
|
||||||
util_opt_init(opt_vec, NULL);
|
util_opt_init(opt_vec, NULL);
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -348,6 +473,16 @@ int main(int argc, char *argv[])
|
|||||||
case 'v':
|
case 'v':
|
||||||
util_prg_print_version();
|
util_prg_print_version();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
case OPT_CONFIG_ON:
|
||||||
|
actionset = true;
|
||||||
|
config = "1";
|
||||||
|
config_text = "config on";
|
||||||
|
break;
|
||||||
|
case OPT_CONFIG_OFF:
|
||||||
|
actionset = true;
|
||||||
|
config = "0";
|
||||||
|
config_text = "config off";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
util_opt_print_parse_error(c, argv);
|
util_opt_print_parse_error(c, argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@@ -380,42 +515,13 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
dev_list_argv(&dev_list, &len, &argv[optind]);
|
dev_list_argv(&dev_list, &len, &argv[optind]);
|
||||||
|
|
||||||
if (online && len == 0)
|
if ((online || config) && len == 0)
|
||||||
errx(EXIT_FAILURE, "Error - missing cryptographic device id(s).");
|
errx(EXIT_FAILURE, "Error - missing cryptographic device id(s).");
|
||||||
|
|
||||||
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
if (online)
|
||||||
if (strncmp(dev, "card", 4) == 0) {
|
set_online(online, online_text, dev_list, len);
|
||||||
/* dev == "card2" */
|
else if (config)
|
||||||
sscanf(dev, "card%02x", &id);
|
set_config(config, config_text, dev_list, len);
|
||||||
sprintf(device, "card%02x", id);
|
|
||||||
} else if (strncmp(dev, "0x", 2) == 0) {
|
|
||||||
/* dev == "0x.." */
|
|
||||||
sscanf(dev, "0x%02x", &id);
|
|
||||||
sprintf(device, "card%02x", id);
|
|
||||||
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
|
||||||
/* dev == "2" */
|
|
||||||
sscanf(dev, "%02x", &id);
|
|
||||||
sprintf(device, "card%02x", id);
|
|
||||||
} else {
|
|
||||||
/* Form: 01.0003 ? */
|
|
||||||
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
|
|
||||||
errx(EXIT_FAILURE, "Error - cryptographic device %s malformed.", dev);
|
|
||||||
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
|
|
||||||
}
|
|
||||||
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
|
||||||
if (!util_path_is_dir(dev_path))
|
|
||||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
|
||||||
if (!util_path_is_writable("%s/online", dev_path))
|
|
||||||
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n Wrong permissions"
|
|
||||||
" or wrong tools version.", dev_path);
|
|
||||||
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
|
||||||
util_file_write_s(online, "%s/online", dev_path);
|
|
||||||
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
|
||||||
if (strcmp(online, online_read) != 0)
|
|
||||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
|
||||||
device, online_text);
|
|
||||||
free(dev_path);
|
|
||||||
}
|
|
||||||
free(dev_list);
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-4
@@ -10,7 +10,7 @@
|
|||||||
.\" nroff -man lszcrypt.8
|
.\" nroff -man lszcrypt.8
|
||||||
.\" to process this source
|
.\" to process this source
|
||||||
.\"
|
.\"
|
||||||
.TH LSZCRYPT 8 "AUG 2019" "s390-tools"
|
.TH LSZCRYPT 8 "OCT 2020" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
lszcrypt \- display zcrypt device and configuration information
|
lszcrypt \- display zcrypt device and configuration information
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -111,9 +111,9 @@ Displays help text and exits.
|
|||||||
.TP 8
|
.TP 8
|
||||||
.B -v, --version
|
.B -v, --version
|
||||||
Displays version information and exits.
|
Displays version information and exits.
|
||||||
.SH VERBOSE LISTING DETAILS
|
.SH LISTING DETAILS
|
||||||
Some of the columns showing up in verbose listing mode may need some
|
Here is an explanation of the columns displayed. Please note that some
|
||||||
explanation:
|
of the columns show up in verbose mode only.
|
||||||
.TP
|
.TP
|
||||||
.B TYPE and HWTYPE
|
.B TYPE and HWTYPE
|
||||||
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
||||||
@@ -124,6 +124,31 @@ The TYPE is a human readable value showing the hardware type and the basic
|
|||||||
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
||||||
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
||||||
.TP
|
.TP
|
||||||
|
.B MODE
|
||||||
|
A crypto card can be configured to run into one of 3 modes:
|
||||||
|
.br
|
||||||
|
Accelerator - Acceleration of clear key RSA (CRT and ME) cryptographic
|
||||||
|
operations.
|
||||||
|
.br
|
||||||
|
CCA Coprocessor - Support CCA secure key cryptographic operations.
|
||||||
|
.br
|
||||||
|
EP11 Coprocessor - Support EP11 secure key cryptographic operations.
|
||||||
|
.TP
|
||||||
|
.B STATUS
|
||||||
|
A crypto card and/or a crypto queue may be switched offline to
|
||||||
|
prohibit it's use. There are two levels of offline state. A software
|
||||||
|
online/offline state is kept by the zcrypt device driver and can be
|
||||||
|
switched on or off with the help of the chzcrypt application.
|
||||||
|
.br
|
||||||
|
A crypto card can also be 'configured' or 'deconfigured'. This state
|
||||||
|
may be adjusted on the HMC or SE. The chzcrypt application can also
|
||||||
|
trigger this state with the --config-on and --config-off options.
|
||||||
|
.br
|
||||||
|
lszcrypt shows 'online' when a card or queue is available for
|
||||||
|
cryptograhic operations. 'offline' is displayed when a card or queue
|
||||||
|
is switched to (software) offline. If a card is 'deconfigured' via
|
||||||
|
HMC, SE or chzcrypt the field shows 'deconfig'.
|
||||||
|
.TP
|
||||||
.B REQUESTS
|
.B REQUESTS
|
||||||
This is the counter value of successful processed requests on card or queue
|
This is the counter value of successful processed requests on card or queue
|
||||||
level. Successful here means the request was processed without any failure
|
level. Successful here means the request was processed without any failure
|
||||||
|
|||||||
+37
-16
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* lszcrypt - Display zcrypt devices and configuration settings
|
* lszcrypt - Display zcrypt devices and configuration settings
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2008, 2019
|
* Copyright IBM Corp. 2008, 2020
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -86,7 +86,7 @@ const struct util_prg prg = {
|
|||||||
{
|
{
|
||||||
.owner = "IBM Corp.",
|
.owner = "IBM Corp.",
|
||||||
.pub_first = 2008,
|
.pub_first = 2008,
|
||||||
.pub_last = 2019,
|
.pub_last = 2020,
|
||||||
},
|
},
|
||||||
UTIL_PRG_COPYRIGHT_END
|
UTIL_PRG_COPYRIGHT_END
|
||||||
}
|
}
|
||||||
@@ -339,6 +339,7 @@ static void show_capability(const char *id_str)
|
|||||||
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||||
const char *sub_dev)
|
const char *sub_dev)
|
||||||
{
|
{
|
||||||
|
long value;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
unsigned long facility;
|
unsigned long facility;
|
||||||
|
|
||||||
@@ -347,14 +348,25 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
|||||||
else
|
else
|
||||||
util_rec_set(rec, "type", buf);
|
util_rec_set(rec, "type", buf);
|
||||||
|
|
||||||
if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
|
if (util_path_is_readable("%s/%s/online", grp_dev, sub_dev)) {
|
||||||
grp_dev, sub_dev))
|
util_file_read_l(&value, 10, "%s/%s/online", grp_dev, sub_dev);
|
||||||
util_rec_set(rec, "online", "-");
|
if (value > 0)
|
||||||
else
|
|
||||||
if (strcmp(buf, "0") == 0)
|
|
||||||
util_rec_set(rec, "online", "offline");
|
|
||||||
else
|
|
||||||
util_rec_set(rec, "online", "online");
|
util_rec_set(rec, "online", "online");
|
||||||
|
else {
|
||||||
|
/* device is offline, check config (if available) */
|
||||||
|
if (util_path_is_readable("%s/%s/config", grp_dev, sub_dev)) {
|
||||||
|
util_file_read_l(&value, 10, "%s/%s/config", grp_dev, sub_dev);
|
||||||
|
if (value > 0)
|
||||||
|
util_rec_set(rec, "online", "offline");
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "online", "deconfig");
|
||||||
|
} else
|
||||||
|
util_rec_set(rec, "online", "offline");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* no online attribute */
|
||||||
|
util_rec_set(rec, "online", "-");
|
||||||
|
}
|
||||||
|
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||||
if (facility & MASK_COPRO)
|
if (facility & MASK_COPRO)
|
||||||
@@ -457,6 +469,7 @@ 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)
|
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||||
{
|
{
|
||||||
|
long value;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
unsigned long facility;
|
unsigned long facility;
|
||||||
|
|
||||||
@@ -475,13 +488,21 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
|||||||
else
|
else
|
||||||
util_rec_set(rec, "mode", "Unknown");
|
util_rec_set(rec, "mode", "Unknown");
|
||||||
|
|
||||||
if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
|
if (util_path_is_readable("%s/online", grp_dev)) {
|
||||||
util_rec_set(rec, "online", "-");
|
util_file_read_l(&value, 10, "%s/online", grp_dev);
|
||||||
else
|
if (value > 0)
|
||||||
if (strcmp(buf, "0") == 0)
|
|
||||||
util_rec_set(rec, "online", "offline");
|
|
||||||
else
|
|
||||||
util_rec_set(rec, "online", "online");
|
util_rec_set(rec, "online", "online");
|
||||||
|
else {
|
||||||
|
if (util_path_is_readable("%s/config", grp_dev)) {
|
||||||
|
util_file_read_l(&value, 10, "%s/config", grp_dev);
|
||||||
|
if (value > 0)
|
||||||
|
util_rec_set(rec, "online", "offline");
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "online", "deconfig");
|
||||||
|
} else
|
||||||
|
util_rec_set(rec, "online", "offline");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
||||||
util_rec_set(rec, "requests", buf);
|
util_rec_set(rec, "requests", buf);
|
||||||
@@ -567,7 +588,7 @@ static void define_rec_default(struct util_rec *rec)
|
|||||||
util_rec_def(rec, "card", UTIL_REC_ALIGN_LEFT, 11, "CARD.DOMAIN");
|
util_rec_def(rec, "card", UTIL_REC_ALIGN_LEFT, 11, "CARD.DOMAIN");
|
||||||
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
|
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, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
|
||||||
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
|
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 8, "STATUS");
|
||||||
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
|
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1178,8 +1178,14 @@ static int get_apqn_measurement_data(uint8_t card)
|
|||||||
scdmd_area.request.header.code = 0x102d;
|
scdmd_area.request.header.code = 0x102d;
|
||||||
scdmd_area.request.header.length =
|
scdmd_area.request.header.length =
|
||||||
sizeof(struct chsc_scdmd_request);
|
sizeof(struct chsc_scdmd_request);
|
||||||
scdmd_area.request.first_drid.ap_index = card;
|
if (scdmd_area.response.p) {
|
||||||
scdmd_area.request.first_drid.domain_index = g.min_domain;
|
scdmd_area.request.first_drid =
|
||||||
|
scdmd_area.response.crid;
|
||||||
|
} else {
|
||||||
|
scdmd_area.request.first_drid.ap_index = card;
|
||||||
|
scdmd_area.request.first_drid.domain_index =
|
||||||
|
g.min_domain;
|
||||||
|
}
|
||||||
scdmd_area.request.last_drid.ap_index = card;
|
scdmd_area.request.last_drid.ap_index = card;
|
||||||
scdmd_area.request.last_drid.domain_index = g.max_domain;
|
scdmd_area.request.last_drid.domain_index = g.max_domain;
|
||||||
scdmd_area.request.s = 1;
|
scdmd_area.request.s = 1;
|
||||||
@@ -1217,10 +1223,6 @@ static int get_apqn_measurement_data(uint8_t card)
|
|||||||
rc = process_apqn_measurement_data(&scdmd_area);
|
rc = process_apqn_measurement_data(&scdmd_area);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (scdmd_area.response.p)
|
|
||||||
scdmd_area.request.first_drid =
|
|
||||||
scdmd_area.response.crid;
|
|
||||||
} while (scdmd_area.response.p);
|
} while (scdmd_area.response.p);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
+1
-1
@@ -12,6 +12,6 @@
|
|||||||
|
|
||||||
#include "exit_code.h"
|
#include "exit_code.h"
|
||||||
|
|
||||||
exit_code_t root_check(void);
|
exit_code_t initrd_check(bool all_pers);
|
||||||
|
|
||||||
#endif /* ROOT_H */
|
#endif /* ROOT_H */
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ include ../../common.mak
|
|||||||
ALL_CPPFLAGS += -I ../include -std=gnu99 -Wno-unused-parameter \
|
ALL_CPPFLAGS += -I ../include -std=gnu99 -Wno-unused-parameter \
|
||||||
-Wno-missing-field-initializers
|
-Wno-missing-field-initializers
|
||||||
|
|
||||||
|
# Adding ZDEV_ALWAYS_UPDATE_INITRD=1 option will update the initial RAM-disk
|
||||||
|
# without the user interaction upon the modification of a persistent device
|
||||||
|
# configuration.
|
||||||
|
|
||||||
|
ifeq ($(ZDEV_ALWAYS_UPDATE_INITRD),1)
|
||||||
|
ALL_CPPFLAGS += -DZDEV_ALWAYS_UPDATE_INITRD=true
|
||||||
|
else
|
||||||
|
ALL_CPPFLAGS += -DZDEV_ALWAYS_UPDATE_INITRD=false
|
||||||
|
endif
|
||||||
|
|
||||||
# Core
|
# Core
|
||||||
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
|
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
|
||||||
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||||
|
|||||||
+1
-1
@@ -3027,7 +3027,7 @@ int main(int argc, char *argv[])
|
|||||||
!dryrun) {
|
!dryrun) {
|
||||||
/* If the root device/device type or early devices have been
|
/* If the root device/device type or early devices have been
|
||||||
* modified, additional work might be necessary. */
|
* modified, additional work might be necessary. */
|
||||||
rc = root_check();
|
rc = initrd_check(ZDEV_ALWAYS_UPDATE_INITRD);
|
||||||
if (rc && !drc)
|
if (rc && !drc)
|
||||||
drc = rc;
|
drc = rc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,6 +313,22 @@ static struct attrib dasd_attr_safe_offline = {
|
|||||||
.writeonly = 1,
|
.writeonly = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct attrib dasd_attr_fc_security = {
|
||||||
|
.name = "fc_security",
|
||||||
|
.title = "Show FC Endpoint Security state of DASD device",
|
||||||
|
.desc =
|
||||||
|
"This read-only attribute shows the Fibre Channel Endpoint Security\n"
|
||||||
|
"status of the connection to the DASD device:\n"
|
||||||
|
" Unsupported : The DASD device does not support Fibre Channel\n"
|
||||||
|
" Endpoint Security\n"
|
||||||
|
" Inconsistent : The operational channel paths of the DASD device\n"
|
||||||
|
" report inconsistent Fibre Channel Endpoint\n"
|
||||||
|
" Security status\n"
|
||||||
|
" Authentication: The connection has been authenticated\n"
|
||||||
|
" Encryption : The connection is encrypted\n",
|
||||||
|
.readonly = 1,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DASD subtype methods.
|
* DASD subtype methods.
|
||||||
*/
|
*/
|
||||||
@@ -617,6 +633,7 @@ struct subtype dasd_subtype_eckd = {
|
|||||||
&dasd_attr_reservation_policy,
|
&dasd_attr_reservation_policy,
|
||||||
&dasd_attr_last_known_reservation_state,
|
&dasd_attr_last_known_reservation_state,
|
||||||
&dasd_attr_safe_offline,
|
&dasd_attr_safe_offline,
|
||||||
|
&dasd_attr_fc_security,
|
||||||
&internal_attr_early,
|
&internal_attr_early,
|
||||||
),
|
),
|
||||||
.unknown_dev_attribs = 1,
|
.unknown_dev_attribs = 1,
|
||||||
|
|||||||
+67
-9
@@ -58,11 +58,50 @@ static void add_early_removed(struct util_list *selected)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_pers_removed(struct util_list *strlist)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
struct devtype *dt;
|
||||||
|
struct subtype *st;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
for (i = 0; devtypes[i]; i++) {
|
||||||
|
dt = devtypes[i];
|
||||||
|
for (j = 0; dt->subtypes[j]; j++) {
|
||||||
|
st = dt->subtypes[j];
|
||||||
|
util_list_iterate(&st->devices->hash.list, dev) {
|
||||||
|
if (dev->persistent.deconfigured) {
|
||||||
|
strlist_add(strlist, "%s %s",
|
||||||
|
dev->subtype->devname, dev->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_zdev_early_0(struct selected_dev_node *sel)
|
||||||
|
{
|
||||||
|
struct setting *s;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
|
dev = device_list_find(sel->st->devices, sel->id, NULL);
|
||||||
|
if (!dev)
|
||||||
|
return false;
|
||||||
|
s = setting_list_find(dev->persistent.settings,
|
||||||
|
internal_attr_early.name);
|
||||||
|
if (!s)
|
||||||
|
return false;
|
||||||
|
if (s->specified && strcmp(s->value, "0") == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine if initial RAM-disk needs updating. If so, run the corresponding
|
/* Determine if initial RAM-disk needs updating. If so, run the corresponding
|
||||||
* scripts if available. */
|
* scripts if available. */
|
||||||
exit_code_t root_check(void)
|
exit_code_t initrd_check(bool all_pers)
|
||||||
{
|
{
|
||||||
struct util_list *selected, *params, *mod = NULL;
|
struct util_list *selected, *params, *mod = strlist_new();
|
||||||
struct selected_dev_node *sel;
|
struct selected_dev_node *sel;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
char *params_str;
|
char *params_str;
|
||||||
@@ -76,6 +115,20 @@ exit_code_t root_check(void)
|
|||||||
/* Get list of devices that provide the root device or require
|
/* Get list of devices that provide the root device or require
|
||||||
* early configuration. */
|
* early configuration. */
|
||||||
selected = selected_dev_list_new();
|
selected = selected_dev_list_new();
|
||||||
|
|
||||||
|
if (all_pers) {
|
||||||
|
/* Add all persistently configured devices. */
|
||||||
|
select = select_opts_new();
|
||||||
|
select->configured = 1;
|
||||||
|
select_devices(select, selected, 1, 0, 0, config_persistent,
|
||||||
|
scope_mandatory, err_ignore);
|
||||||
|
select_opts_free(select);
|
||||||
|
|
||||||
|
/* Ensure that removed devices are considered. */
|
||||||
|
add_pers_removed(mod);
|
||||||
|
goto check_mod;
|
||||||
|
}
|
||||||
|
|
||||||
/* First add devices that had zdev:early removed or changed to 0.
|
/* First add devices that had zdev:early removed or changed to 0.
|
||||||
* The subsequent call to select_devices() will filter out any
|
* The subsequent call to select_devices() will filter out any
|
||||||
* duplicates. */
|
* duplicates. */
|
||||||
@@ -95,8 +148,8 @@ exit_code_t root_check(void)
|
|||||||
err_ignore);
|
err_ignore);
|
||||||
select_opts_free(select);
|
select_opts_free(select);
|
||||||
|
|
||||||
|
check_mod:
|
||||||
/* Determine if any of the devices or device types has been modified. */
|
/* Determine if any of the devices or device types has been modified. */
|
||||||
mod = strlist_new();
|
|
||||||
util_list_iterate(selected, sel) {
|
util_list_iterate(selected, sel) {
|
||||||
dt = sel->st->devtype;
|
dt = sel->st->devtype;
|
||||||
|
|
||||||
@@ -127,17 +180,22 @@ exit_code_t root_check(void)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ask for confirmation. */
|
if (!all_pers) {
|
||||||
if (!confirm("Update initial RAM-disk now?")) {
|
/* Ask for confirmation. */
|
||||||
rc = EXIT_ABORTED;
|
if (!confirm("Update initial RAM-disk now?")) {
|
||||||
goto out;
|
rc = EXIT_ABORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build the command line. */
|
/* Build the command line. */
|
||||||
params = strlist_new();
|
params = strlist_new();
|
||||||
util_list_iterate(selected, sel) {
|
util_list_iterate(selected, sel) {
|
||||||
strlist_add(params, "%s", sel->st->name);
|
/* From the selected list, remove the devices with zdev:early=0 */
|
||||||
strlist_add(params, "%s", sel->id);
|
if (!is_zdev_early_0(sel)) {
|
||||||
|
strlist_add(params, "%s", sel->st->name);
|
||||||
|
strlist_add(params, "%s", sel->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
params_str = strlist_flatten(params, " ");
|
params_str = strlist_flatten(params, " ");
|
||||||
strlist_free(params);
|
strlist_free(params);
|
||||||
|
|||||||
+1
-1
@@ -407,7 +407,7 @@ void dfi_mem_chunk_add_vol(u64 start, u64 size, void *data,
|
|||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
mem_chunk_create(&l.mem_phys, start, size, data, read_fn, free_fn);
|
mem_chunk_create(&l.mem_phys, start, size, data, read_fn, free_fn);
|
||||||
mem_chunk_create(&l.mem_virt, start, size, data, read_fn, free_fn);
|
mem_chunk_create(&l.mem_virt, start, size, data, read_fn, NULL);
|
||||||
l.mem_virt.chunk_cache->volnr = volnr;
|
l.mem_virt.chunk_cache->volnr = volnr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -42,6 +42,8 @@ static int pt_load_add(Elf64_Phdr *phdr)
|
|||||||
STDERR("Dump file \"%s\" is a user space core dump\n",
|
STDERR("Dump file \"%s\" is a user space core dump\n",
|
||||||
g.opts.device);
|
g.opts.device);
|
||||||
}
|
}
|
||||||
|
if (phdr->p_offset + phdr->p_filesz > zg_size(g.fh))
|
||||||
|
return -EINVAL;
|
||||||
if (phdr->p_filesz == 0) {
|
if (phdr->p_filesz == 0) {
|
||||||
/* Add zero memory chunk */
|
/* Add zero memory chunk */
|
||||||
dfi_mem_chunk_add(phdr->p_paddr, phdr->p_memsz, NULL,
|
dfi_mem_chunk_add(phdr->p_paddr, phdr->p_memsz, NULL,
|
||||||
@@ -52,8 +54,6 @@ static int pt_load_add(Elf64_Phdr *phdr)
|
|||||||
dfi_mem_chunk_add(phdr->p_paddr, phdr->p_memsz, off_ptr,
|
dfi_mem_chunk_add(phdr->p_paddr, phdr->p_memsz, off_ptr,
|
||||||
dfi_elf_mem_chunk_read_fn, zg_free);
|
dfi_elf_mem_chunk_read_fn, zg_free);
|
||||||
}
|
}
|
||||||
if (phdr->p_offset + phdr->p_filesz > zg_size(g.fh))
|
|
||||||
return -EINVAL;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-45
@@ -21,6 +21,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_file.h"
|
||||||
#include "lib/util_path.h"
|
#include "lib/util_path.h"
|
||||||
|
|
||||||
#include "zgetdump.h"
|
#include "zgetdump.h"
|
||||||
@@ -98,6 +99,24 @@ static void em_init(struct vol *vol)
|
|||||||
l.dump_incomplete = 1;
|
l.dump_incomplete = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether a device with a given busid is online
|
||||||
|
*/
|
||||||
|
static unsigned int dev_is_online(const char *busid)
|
||||||
|
{
|
||||||
|
unsigned int online;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = util_path_sysfs("%s/%s/online", SYSFS_BUSDIR, busid);
|
||||||
|
if (util_file_read_ui(&online, 10, path) != 0) {
|
||||||
|
warnx("Could not open \"%s\" (%s)", path, strerror(errno));
|
||||||
|
free(path);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return online;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check sysfs, whether a device specified by its bus ID is defined and online.
|
* Check sysfs, whether a device specified by its bus ID is defined and online.
|
||||||
@@ -106,67 +125,40 @@ static void em_init(struct vol *vol)
|
|||||||
static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
|
static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
|
||||||
{
|
{
|
||||||
struct dirent *direntp;
|
struct dirent *direntp;
|
||||||
int fh, minor, major;
|
int minor, major;
|
||||||
char buf[10];
|
char buf[10];
|
||||||
DIR *fh_dir;
|
DIR *fh_dir;
|
||||||
char *sysfs;
|
char *sysfs;
|
||||||
|
|
||||||
sysfs = util_path_sysfs("%s/%s", SYSFS_BUSDIR, bus_id);
|
sysfs = util_path_sysfs("%s/%s", SYSFS_BUSDIR, bus_id);
|
||||||
fh_dir = opendir(sysfs);
|
if (!util_path_is_dir(sysfs)) {
|
||||||
free(sysfs);
|
free(sysfs);
|
||||||
if (!fh_dir)
|
|
||||||
return DEV_UNDEFINED;
|
return DEV_UNDEFINED;
|
||||||
|
|
||||||
sysfs = util_path_sysfs("%s/%s/online", SYSFS_BUSDIR, bus_id);
|
|
||||||
fh = open(sysfs, O_RDONLY);
|
|
||||||
if (fh == -1) {
|
|
||||||
warnx("Could not open \"%s\" (%s)", sysfs, strerror(errno));
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
free(sysfs);
|
free(sysfs);
|
||||||
if (read(fh, buf, 1) == -1)
|
|
||||||
ERR_EXIT_ERRNO("Could not read online attribute");
|
|
||||||
close(fh);
|
|
||||||
|
|
||||||
if (buf[0] != '1')
|
if (!dev_is_online(bus_id))
|
||||||
return DEV_OFFLINE;
|
return DEV_OFFLINE;
|
||||||
|
|
||||||
while ((direntp = readdir(fh_dir)))
|
sysfs = util_path_sysfs("%s/%s/block", SYSFS_BUSDIR, bus_id);
|
||||||
if (strncmp(direntp->d_name, "block:", 6) == 0)
|
fh_dir = opendir(sysfs);
|
||||||
break;
|
if (!fh_dir) {
|
||||||
closedir(fh_dir);
|
warnx("Could not open \"%s\" (%s) ", sysfs, strerror(errno));
|
||||||
|
|
||||||
if (direntp == NULL) {
|
|
||||||
sysfs = util_path_sysfs("%s/%s/block", SYSFS_BUSDIR, bus_id);
|
|
||||||
fh_dir = opendir(sysfs);
|
|
||||||
if (!fh_dir) {
|
|
||||||
warnx("Could not open \"%s\" (%s) ",
|
|
||||||
sysfs, strerror(errno));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
while ((direntp = readdir(fh_dir)))
|
|
||||||
if (strncmp(direntp->d_name, "dasd", 4) == 0)
|
|
||||||
break;
|
|
||||||
closedir(fh_dir);
|
|
||||||
if (direntp == NULL) {
|
|
||||||
warnx("Problem with contents of \"%s\"", sysfs);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
free(sysfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
sysfs = util_path_sysfs("%s/%s/%s/dev",
|
|
||||||
SYSFS_BUSDIR, bus_id, direntp->d_name);
|
|
||||||
fh = open(sysfs, O_RDONLY);
|
|
||||||
if (fh == -1) {
|
|
||||||
warnx("Could not open \"%s\" (%s)", sysfs, strerror(errno));
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (read(fh, buf, sizeof(buf)) == -1) {
|
while ((direntp = readdir(fh_dir)))
|
||||||
|
if (strncmp(direntp->d_name, "dasd", 4) == 0)
|
||||||
|
break;
|
||||||
|
if (direntp == NULL) {
|
||||||
|
warnx("Problem with contents of \"%s\"", sysfs);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (util_file_read_line(buf, sizeof(buf), "%s/%s/dev", sysfs, direntp->d_name)) {
|
||||||
warnx("Could not read dev file (%s)", strerror(errno));
|
warnx("Could not read dev file (%s)", strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
close(fh);
|
closedir(fh_dir);
|
||||||
|
|
||||||
if (sscanf(buf, "%i:%i", &major, &minor) != 2) {
|
if (sscanf(buf, "%i:%i", &major, &minor) != 2) {
|
||||||
warnx("Malformed content of \"%s\": %s", sysfs, buf);
|
warnx("Malformed content of \"%s\": %s", sysfs, buf);
|
||||||
goto err;
|
goto err;
|
||||||
@@ -178,6 +170,8 @@ static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
|
|||||||
return DEV_ONLINE;
|
return DEV_ONLINE;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
if (fh_dir)
|
||||||
|
closedir(fh_dir);
|
||||||
free(sysfs);
|
free(sysfs);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,6 +280,9 @@ off_t zg_seek(struct zg_fh *zg_fh, off_t off, enum zg_check check)
|
|||||||
{
|
{
|
||||||
off_t rc;
|
off_t rc;
|
||||||
|
|
||||||
|
if (off >= zg_fh->sb.st_size)
|
||||||
|
ERR_EXIT("Trying to seek past file end \"%s\"", zg_fh->path);
|
||||||
|
|
||||||
rc = lseek(zg_fh->fh, off, SEEK_SET);
|
rc = lseek(zg_fh->fh, off, SEEK_SET);
|
||||||
if (rc == -1 && check != ZG_CHECK_NONE)
|
if (rc == -1 && check != ZG_CHECK_NONE)
|
||||||
ERR_EXIT_ERRNO("Could not seek \"%s\"", zg_fh->path);
|
ERR_EXIT_ERRNO("Could not seek \"%s\"", zg_fh->path);
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ include ../common.mak
|
|||||||
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
|
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
|
||||||
INSTALL_SCRIPTS = 10-zfcpdump.install
|
INSTALL_SCRIPTS = 10-zfcpdump.install
|
||||||
|
|
||||||
|
ALL_CFLAGS += -fno-sanitize=all
|
||||||
|
ALL_LDFLAGS += -fno-sanitize=all
|
||||||
|
|
||||||
ifeq (${HAVE_LIBC_STATIC},0)
|
ifeq (${HAVE_LIBC_STATIC},0)
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ configuration.
|
|||||||
* Issue "make bzImage" to build the zfcpdump kernel image.
|
* Issue "make bzImage" to build the zfcpdump kernel image.
|
||||||
|
|
||||||
In a Linux distribution the zfcpdump enabled kernel image must be copied to
|
In a Linux distribution the zfcpdump enabled kernel image must be copied to
|
||||||
/lib/s390-tools/zfcpdump/zfcpdump_part.image, where the s390 zipl tool is
|
/lib/s390-tools/zfcpdump/zfcpdump-image, where the s390 zipl tool is
|
||||||
looking for the dump kernel when preparing a SCSI dump disk.
|
looking for the dump kernel when preparing a SCSI dump disk.
|
||||||
|
|
||||||
Create and install initrd
|
Create and install initrd
|
||||||
|
|||||||
@@ -420,7 +420,7 @@ void VirtAdapterPrinter::print_virt_adpt(FILE *fp, __u32 devno,
|
|||||||
int *rc)
|
int *rc)
|
||||||
{
|
{
|
||||||
if (m_csv)
|
if (m_csv)
|
||||||
fprintf(fp, "%x,%x.%x.%04x,",
|
fprintf(fp, "%x,%x.%x.%04x",
|
||||||
m_cfg->get_chpid_by_devno(devno, rc),
|
m_cfg->get_chpid_by_devno(devno, rc),
|
||||||
ZIOREP_BUSID_UNPACKED(devno));
|
ZIOREP_BUSID_UNPACKED(devno));
|
||||||
else
|
else
|
||||||
@@ -517,7 +517,7 @@ void VirtAdapterPrinter::print_num_requests(FILE *fp, const struct blkiomon_stat
|
|||||||
void VirtAdapterPrinter::print_topline(FILE *fp)
|
void VirtAdapterPrinter::print_topline(FILE *fp)
|
||||||
{
|
{
|
||||||
if (m_csv)
|
if (m_csv)
|
||||||
fprintf(fp, "timestamp,aggregated,CHPID,Bus-ID,qdio utilization max %%,qdio utilization avg %%,queue full,fail erc,throughput read / MS/s,throughput write / MS/s,I/O requests read,I/O requqests write\n");
|
fprintf(fp, "timestamp,aggregated,CHPID,Bus-ID,qdio utilization max %%,qdio utilization avg %%,queue full,fail erc,throughput read / MS/s,throughput write / MS/s,I/O requests read,I/O requests write\n");
|
||||||
else {
|
else {
|
||||||
fprintf(fp, "CHP Bus-ID |qdio util.%%|queu|fail|-thp in MB/s-|I/O reqs-|\n");
|
fprintf(fp, "CHP Bus-ID |qdio util.%%|queu|fail|-thp in MB/s-|I/O reqs-|\n");
|
||||||
fprintf(fp, " ID max avg full erc rd wrt rd wrt\n");
|
fprintf(fp, " ID max avg full erc rd wrt rd wrt\n");
|
||||||
|
|||||||
+3
-2
@@ -7,10 +7,11 @@ INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
|||||||
ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g $(INCLUDE_PARMS) \
|
ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g $(INCLUDE_PARMS) \
|
||||||
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||||
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
|
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
|
||||||
-fno-delete-null-pointer-checks \
|
-fno-delete-null-pointer-checks -fno-stack-protector \
|
||||||
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
||||||
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
||||||
-W -Wall -Wformat-security
|
-W -Wall -Wformat-security -fno-sanitize=all
|
||||||
|
ALL_LDFLAGS += -fno-sanitize=all
|
||||||
|
|
||||||
FILES = fba0.bin fba1b.bin fba2.bin \
|
FILES = fba0.bin fba1b.bin fba2.bin \
|
||||||
eckd0_ldl.bin eckd0_cdl.bin \
|
eckd0_ldl.bin eckd0_cdl.bin \
|
||||||
|
|||||||
@@ -449,13 +449,14 @@ void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count)
|
|||||||
* block number
|
* block number
|
||||||
*/
|
*/
|
||||||
unsigned long write_dump_segment(unsigned long blk,
|
unsigned long write_dump_segment(unsigned long blk,
|
||||||
struct df_s390_dump_segm_hdr *segm,
|
struct df_s390_dump_segm_hdr *segm)
|
||||||
unsigned long zero_page)
|
|
||||||
{
|
{
|
||||||
unsigned long addr, start_blk, blk_count;
|
unsigned long addr, start_blk, blk_count, zero_page;
|
||||||
|
|
||||||
/* Write the dump segment header itself (1 page) */
|
/* Write the dump segment header itself (1 page) */
|
||||||
|
zero_page = get_zeroed_page();
|
||||||
writeblock(blk, (unsigned long)segm, m2b(PAGE_SIZE), zero_page);
|
writeblock(blk, (unsigned long)segm, m2b(PAGE_SIZE), zero_page);
|
||||||
|
free_page(zero_page);
|
||||||
blk += m2b(PAGE_SIZE);
|
blk += m2b(PAGE_SIZE);
|
||||||
/* Write the dump segment */
|
/* Write the dump segment */
|
||||||
addr = segm->start;
|
addr = segm->start;
|
||||||
@@ -464,7 +465,9 @@ unsigned long write_dump_segment(unsigned long blk,
|
|||||||
/* Remaining blocks to write */
|
/* Remaining blocks to write */
|
||||||
blk_count = m2b(segm->len) - (blk - start_blk);
|
blk_count = m2b(segm->len) - (blk - start_blk);
|
||||||
blk_count = MIN(blk_count, eckd_blk_max);
|
blk_count = MIN(blk_count, eckd_blk_max);
|
||||||
|
zero_page = get_zeroed_page();
|
||||||
writeblock(blk, addr, blk_count, zero_page);
|
writeblock(blk, addr, blk_count, zero_page);
|
||||||
|
free_page(zero_page);
|
||||||
progress_print(addr);
|
progress_print(addr);
|
||||||
blk += blk_count;
|
blk += blk_count;
|
||||||
addr += b2m(blk_count);
|
addr += b2m(blk_count);
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_count,
|
|||||||
unsigned long zero_page);
|
unsigned long zero_page);
|
||||||
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
|
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
|
||||||
unsigned long write_dump_segment(unsigned long blk,
|
unsigned long write_dump_segment(unsigned long blk,
|
||||||
struct df_s390_dump_segm_hdr *segm,
|
struct df_s390_dump_segm_hdr *segm);
|
||||||
unsigned long zero_page);
|
|
||||||
|
|
||||||
#endif /* ECKD2DUMP_H */
|
#endif /* ECKD2DUMP_H */
|
||||||
|
|||||||
+16
-11
@@ -192,10 +192,13 @@ void dt_device_enable(void)
|
|||||||
* Check for the volume timestamp and validate the dump signature
|
* Check for the volume timestamp and validate the dump signature
|
||||||
* before writing a dump.
|
* before writing a dump.
|
||||||
*/
|
*/
|
||||||
static void check_volume(unsigned long page)
|
static void check_volume(void)
|
||||||
{
|
{
|
||||||
struct mvdump_parm_table *mvdump_table_new;
|
struct mvdump_parm_table *mvdump_table_new;
|
||||||
struct df_s390_hdr *hdr_new;
|
struct df_s390_hdr *hdr_new;
|
||||||
|
unsigned long page;
|
||||||
|
|
||||||
|
page = get_zeroed_page();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether parameter table on dump device has a valid
|
* Check whether parameter table on dump device has a valid
|
||||||
@@ -222,6 +225,8 @@ static void check_volume(unsigned long page)
|
|||||||
if (dump_hdr->magic != hdr_new->mvdump_sign)
|
if (dump_hdr->magic != hdr_new->mvdump_sign)
|
||||||
panic(ENOSIGN, "Wrong signature");
|
panic(ENOSIGN, "Wrong signature");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -229,10 +234,10 @@ static void check_volume(unsigned long page)
|
|||||||
* address to write for the next volume or memory size if the dump ended
|
* address to write for the next volume or memory size if the dump ended
|
||||||
* on this volume
|
* on this volume
|
||||||
*/
|
*/
|
||||||
static unsigned long write_volume(unsigned long addr, unsigned long page,
|
static unsigned long write_volume(unsigned long addr,
|
||||||
struct df_s390_dump_segm_hdr *dump_segm)
|
struct df_s390_dump_segm_hdr *dump_segm)
|
||||||
{
|
{
|
||||||
unsigned long free_space, blk;
|
unsigned long free_space, blk, page;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write dump header
|
* Write dump header
|
||||||
@@ -245,7 +250,7 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
|
|||||||
* header and the end marker)
|
* header and the end marker)
|
||||||
*/
|
*/
|
||||||
free_space = b2m(device.blk_end - blk + 1) - b2m(2);
|
free_space = b2m(device.blk_end - blk + 1) - b2m(2);
|
||||||
memset((void *) page, 0, PAGE_SIZE);
|
|
||||||
/*
|
/*
|
||||||
* Write dump data
|
* Write dump data
|
||||||
*/
|
*/
|
||||||
@@ -257,7 +262,7 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
|
|||||||
addr = find_dump_segment(addr, dump_hdr->mem_size,
|
addr = find_dump_segment(addr, dump_hdr->mem_size,
|
||||||
ROUND_DOWN(free_space, MIB),
|
ROUND_DOWN(free_space, MIB),
|
||||||
dump_segm);
|
dump_segm);
|
||||||
blk = write_dump_segment(blk, dump_segm, page);
|
blk = write_dump_segment(blk, dump_segm);
|
||||||
/* Update free space left on vol */
|
/* Update free space left on vol */
|
||||||
free_space -= dump_segm->len;
|
free_space -= dump_segm->len;
|
||||||
/* Reserve one block for the next segment header */
|
/* Reserve one block for the next segment header */
|
||||||
@@ -267,8 +272,10 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
|
|||||||
/* Check if no more dump segments follow */
|
/* Check if no more dump segments follow */
|
||||||
if (dump_segm->stop_marker) {
|
if (dump_segm->stop_marker) {
|
||||||
/* Write end marker */
|
/* Write end marker */
|
||||||
|
page = get_zeroed_page();
|
||||||
df_s390_em_page_init(page);
|
df_s390_em_page_init(page);
|
||||||
writeblock(blk, page, 1, 0);
|
writeblock(blk, page, 1, 0);
|
||||||
|
free_page(page);
|
||||||
return dump_hdr->mem_size;
|
return dump_hdr->mem_size;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -286,19 +293,18 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
|
|||||||
void dt_dump_mem(void)
|
void dt_dump_mem(void)
|
||||||
{
|
{
|
||||||
struct df_s390_dump_segm_hdr *dump_segm;
|
struct df_s390_dump_segm_hdr *dump_segm;
|
||||||
unsigned long addr, page;
|
unsigned long addr;
|
||||||
|
|
||||||
dump_hdr->mvdump_sign = DF_S390_MAGIC_EXT;
|
dump_hdr->mvdump_sign = DF_S390_MAGIC_EXT;
|
||||||
dump_hdr->mvdump = 1;
|
dump_hdr->mvdump = 1;
|
||||||
addr = 0;
|
addr = 0;
|
||||||
total_dump_size = 0;
|
total_dump_size = 0;
|
||||||
page = get_zeroed_page();
|
|
||||||
dump_segm = (void *)get_zeroed_page();
|
dump_segm = (void *)get_zeroed_page();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("Dumping to: 0.%x.%04x", device.sid.ssid, device.devno);
|
printf("Dumping to: 0.%x.%04x", device.sid.ssid, device.devno);
|
||||||
check_volume(page);
|
check_volume();
|
||||||
addr = write_volume(addr, page, dump_segm);
|
addr = write_volume(addr, dump_segm);
|
||||||
if (addr == dump_hdr->mem_size)
|
if (addr == dump_hdr->mem_size)
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
@@ -312,7 +318,6 @@ void dt_dump_mem(void)
|
|||||||
set_device(device.sid, DISABLED);
|
set_device(device.sid, DISABLED);
|
||||||
dt_device_enable();
|
dt_device_enable();
|
||||||
}
|
}
|
||||||
progress_print(addr);
|
|
||||||
free_page(page);
|
|
||||||
free_page(__pa(dump_segm));
|
free_page(__pa(dump_segm));
|
||||||
|
progress_print(addr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ void dt_dump_mem(void)
|
|||||||
struct df_s390_dump_segm_hdr *dump_segm;
|
struct df_s390_dump_segm_hdr *dump_segm;
|
||||||
|
|
||||||
blk = device.blk_start;
|
blk = device.blk_start;
|
||||||
page = get_zeroed_page();
|
|
||||||
dump_segm = (void *)get_zeroed_page();
|
dump_segm = (void *)get_zeroed_page();
|
||||||
|
|
||||||
/* Write dump header */
|
/* Write dump header */
|
||||||
@@ -79,18 +78,19 @@ void dt_dump_mem(void)
|
|||||||
end = dump_hdr->mem_size;
|
end = dump_hdr->mem_size;
|
||||||
while (addr < end) {
|
while (addr < end) {
|
||||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||||
blk = write_dump_segment(blk, dump_segm, page);
|
blk = write_dump_segment(blk, dump_segm);
|
||||||
total_dump_size += dump_segm->len;
|
total_dump_size += dump_segm->len;
|
||||||
if (dump_segm->stop_marker) {
|
if (dump_segm->stop_marker) {
|
||||||
addr = end;
|
addr = end;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free_page(__pa(dump_segm));
|
||||||
progress_print(addr);
|
progress_print(addr);
|
||||||
|
|
||||||
/* Write end marker */
|
/* Write end marker */
|
||||||
|
page = get_zeroed_page();
|
||||||
df_s390_em_page_init(page);
|
df_s390_em_page_init(page);
|
||||||
writeblock(blk, page, 1, 0);
|
writeblock(blk, page, 1, 0);
|
||||||
free_page(page);
|
free_page(page);
|
||||||
free_page(__pa(dump_segm));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,13 +141,14 @@ static void writeblock_fba(unsigned long blk, unsigned long addr,
|
|||||||
* block number
|
* block number
|
||||||
*/
|
*/
|
||||||
unsigned long write_dump_segment_fba(unsigned long blk,
|
unsigned long write_dump_segment_fba(unsigned long blk,
|
||||||
struct df_s390_dump_segm_hdr *dump_segm,
|
struct df_s390_dump_segm_hdr *dump_segm)
|
||||||
unsigned long zero_page)
|
|
||||||
{
|
{
|
||||||
unsigned long addr, start_blk, blk_count;
|
unsigned long addr, start_blk, blk_count, zero_page;
|
||||||
|
|
||||||
/* Write the dump segment header itself (1 page) */
|
/* Write the dump segment header itself (1 page) */
|
||||||
|
zero_page = get_zeroed_page();
|
||||||
writeblock_fba(blk, __pa(dump_segm), BLK_PER_PAGE, zero_page);
|
writeblock_fba(blk, __pa(dump_segm), BLK_PER_PAGE, zero_page);
|
||||||
|
free_page(zero_page);
|
||||||
blk += BLK_PER_PAGE;
|
blk += BLK_PER_PAGE;
|
||||||
/* Write the dump segment */
|
/* Write the dump segment */
|
||||||
addr = dump_segm->start;
|
addr = dump_segm->start;
|
||||||
@@ -156,7 +157,9 @@ unsigned long write_dump_segment_fba(unsigned long blk,
|
|||||||
/* Remaining blocks to write */
|
/* Remaining blocks to write */
|
||||||
blk_count = m2b(dump_segm->len) - (blk - start_blk);
|
blk_count = m2b(dump_segm->len) - (blk - start_blk);
|
||||||
blk_count = MIN(blk_count, BLK_PWRT);
|
blk_count = MIN(blk_count, BLK_PWRT);
|
||||||
|
zero_page = get_zeroed_page();
|
||||||
writeblock_fba(blk, addr, blk_count, zero_page);
|
writeblock_fba(blk, addr, blk_count, zero_page);
|
||||||
|
free_page(zero_page);
|
||||||
progress_print(addr);
|
progress_print(addr);
|
||||||
blk += blk_count;
|
blk += blk_count;
|
||||||
addr += b2m(blk_count);
|
addr += b2m(blk_count);
|
||||||
@@ -198,7 +201,6 @@ void dt_dump_mem(void)
|
|||||||
|
|
||||||
ccw_program_init();
|
ccw_program_init();
|
||||||
blk = device.blk_start;
|
blk = device.blk_start;
|
||||||
page = get_zeroed_page();
|
|
||||||
dump_segm = (void *)get_zeroed_page();
|
dump_segm = (void *)get_zeroed_page();
|
||||||
|
|
||||||
/* Write dump header */
|
/* Write dump header */
|
||||||
@@ -211,18 +213,19 @@ void dt_dump_mem(void)
|
|||||||
end = dump_hdr->mem_size;
|
end = dump_hdr->mem_size;
|
||||||
while (addr < end) {
|
while (addr < end) {
|
||||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||||
blk = write_dump_segment_fba(blk, dump_segm, page);
|
blk = write_dump_segment_fba(blk, dump_segm);
|
||||||
total_dump_size += dump_segm->len;
|
total_dump_size += dump_segm->len;
|
||||||
if (dump_segm->stop_marker) {
|
if (dump_segm->stop_marker) {
|
||||||
addr = end;
|
addr = end;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free_page(__pa(dump_segm));
|
||||||
progress_print(addr);
|
progress_print(addr);
|
||||||
|
|
||||||
/* Write end marker */
|
/* Write end marker */
|
||||||
|
page = get_zeroed_page();
|
||||||
df_s390_em_page_init(page);
|
df_s390_em_page_init(page);
|
||||||
writeblock_fba(blk, page, 1, 0);
|
writeblock_fba(blk, page, 1, 0);
|
||||||
free_page(page);
|
free_page(page);
|
||||||
free_page(__pa(dump_segm));
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -32,9 +32,10 @@ struct ex_table_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define MEM_ALLOC_START ((unsigned long) __heap_start)
|
#define MEM_ALLOC_START ((unsigned long) __heap_start)
|
||||||
#define MEM_ALLOC_CNT 4
|
#define MEM_ALLOC_END ((unsigned long) __heap_stop)
|
||||||
|
#define MEM_ALLOC_MAX 4
|
||||||
|
|
||||||
static uint8_t mem_page_alloc_vec[MEM_ALLOC_CNT];
|
static uint8_t mem_page_alloc_vec[MEM_ALLOC_MAX];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize memory with value
|
* Initialize memory with value
|
||||||
@@ -417,10 +418,11 @@ void printf(const char *fmt, ...)
|
|||||||
*/
|
*/
|
||||||
unsigned long get_zeroed_page(void)
|
unsigned long get_zeroed_page(void)
|
||||||
{
|
{
|
||||||
|
const int page_count = MIN(MEM_ALLOC_MAX, (int)((MEM_ALLOC_END - MEM_ALLOC_START) / PAGE_SIZE));
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MEM_ALLOC_CNT; i++) {
|
for (i = 0; i < page_count; i++) {
|
||||||
if (mem_page_alloc_vec[i] != 0)
|
if (mem_page_alloc_vec[i] != 0)
|
||||||
continue;
|
continue;
|
||||||
addr = MEM_ALLOC_START + i * PAGE_SIZE;
|
addr = MEM_ALLOC_START + i * PAGE_SIZE;
|
||||||
@@ -436,6 +438,9 @@ unsigned long get_zeroed_page(void)
|
|||||||
*/
|
*/
|
||||||
void free_page(unsigned long addr)
|
void free_page(unsigned long addr)
|
||||||
{
|
{
|
||||||
|
if (addr < MEM_ALLOC_START || addr >= MEM_ALLOC_END)
|
||||||
|
libc_stop(EINTERNAL);
|
||||||
|
|
||||||
mem_page_alloc_vec[(addr - MEM_ALLOC_START) / PAGE_SIZE] = 0;
|
mem_page_alloc_vec[(addr - MEM_ALLOC_START) / PAGE_SIZE] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -90,6 +90,7 @@ void start(void)
|
|||||||
void *load_address;
|
void *load_address;
|
||||||
struct component_entry *entry;
|
struct component_entry *entry;
|
||||||
disk_blockptr_t *blockptr;
|
disk_blockptr_t *blockptr;
|
||||||
|
uint64_t load_psw;
|
||||||
void *load_page;
|
void *load_page;
|
||||||
int config_nr;
|
int config_nr;
|
||||||
|
|
||||||
@@ -133,11 +134,13 @@ void start(void)
|
|||||||
if (entry->type != COMPONENT_EXECUTE)
|
if (entry->type != COMPONENT_EXECUTE)
|
||||||
panic(EWRONGTYPE, "");
|
panic(EWRONGTYPE, "");
|
||||||
|
|
||||||
|
load_psw = entry->address.load_psw;
|
||||||
|
|
||||||
free_page((unsigned long)load_page);
|
free_page((unsigned long)load_page);
|
||||||
io_irq_disable();
|
io_irq_disable();
|
||||||
set_device(subchannel_id, DISABLED);
|
set_device(subchannel_id, DISABLED);
|
||||||
|
|
||||||
execute(entry->address.load_psw);
|
execute(load_psw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void panic_notify(unsigned long UNUSED(reason))
|
void panic_notify(unsigned long UNUSED(reason))
|
||||||
|
|||||||
+10
-88
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/fiemap.h>
|
#include <linux/fiemap.h>
|
||||||
|
|
||||||
#include "lib/util_proc.h"
|
#include "lib/util_proc.h"
|
||||||
|
#include "lib/util_sys.h"
|
||||||
|
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -89,88 +90,6 @@ disk_determine_dasd_type(struct disk_info *data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int blkext_get_partnum(dev_t dev)
|
|
||||||
{
|
|
||||||
char path[PATH_MAX], *buf;
|
|
||||||
int dev_major, dev_minor, partnum = -1;
|
|
||||||
|
|
||||||
dev_major = major(dev);
|
|
||||||
dev_minor = minor(dev);
|
|
||||||
snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
|
|
||||||
dev_major, dev_minor);
|
|
||||||
|
|
||||||
if (misc_read_special_file(path, &buf, NULL, 1)) {
|
|
||||||
error_text("Could not read from path '%s'", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
partnum = atoi(buf);
|
|
||||||
free(buf);
|
|
||||||
if (partnum < 0) {
|
|
||||||
error_text("Bad partition number in '%s'", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return partnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int blkext_is_base_device(dev_t dev)
|
|
||||||
{
|
|
||||||
int dev_major, dev_minor;
|
|
||||||
char path[PATH_MAX];
|
|
||||||
struct stat stats;
|
|
||||||
|
|
||||||
dev_major = major(dev);
|
|
||||||
dev_minor = minor(dev);
|
|
||||||
|
|
||||||
snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
|
|
||||||
dev_major, dev_minor);
|
|
||||||
return (stat(path, &stats));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int blkext_get_base_dev(dev_t dev, dev_t *base_dev)
|
|
||||||
{
|
|
||||||
int base_major, base_minor;
|
|
||||||
char dev_path[PATH_MAX], base_path[PATH_MAX];
|
|
||||||
char *temp_path, *buf;
|
|
||||||
|
|
||||||
misc_asprintf(&temp_path, "/sys/dev/block/%d:%d", major(dev), minor(dev));
|
|
||||||
if (!realpath(temp_path, dev_path)) {
|
|
||||||
error_reason(strerror(errno));
|
|
||||||
error_text("Could not resolve link %s", temp_path);
|
|
||||||
free(temp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
free(temp_path);
|
|
||||||
|
|
||||||
misc_asprintf(&temp_path, "%s/..", dev_path);
|
|
||||||
if (!realpath(temp_path, base_path)) {
|
|
||||||
error_reason(strerror(errno));
|
|
||||||
error_text("Could not resolve path %s", temp_path);
|
|
||||||
free(temp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
free(temp_path);
|
|
||||||
|
|
||||||
misc_asprintf(&temp_path, "%s/dev", base_path);
|
|
||||||
if (misc_read_special_file(temp_path, &buf, NULL, 1)) {
|
|
||||||
error_text("Could not read from path '%s'", temp_path);
|
|
||||||
free(temp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
free(temp_path);
|
|
||||||
|
|
||||||
if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
|
|
||||||
error_text("Could not parse major:minor from string '%s'", buf);
|
|
||||||
free(buf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buf);
|
|
||||||
*base_dev = makedev(base_major, base_minor);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return non-zero for ECKD type. */
|
/* Return non-zero for ECKD type. */
|
||||||
int
|
int
|
||||||
disk_is_eckd(disk_type_t type)
|
disk_is_eckd(disk_type_t type)
|
||||||
@@ -492,15 +411,15 @@ disk_get_info(const char* device, struct job_target_data* target,
|
|||||||
data->devno = -1;
|
data->devno = -1;
|
||||||
data->type = disk_type_scsi;
|
data->type = disk_type_scsi;
|
||||||
|
|
||||||
if (blkext_is_base_device(stats.st_rdev)) {
|
if (util_sys_dev_is_partition(stats.st_rdev)) {
|
||||||
data->device = stats.st_rdev;
|
if (util_sys_get_base_dev(stats.st_rdev, &data->device))
|
||||||
data->partnum = 0;
|
|
||||||
} else {
|
|
||||||
if (blkext_get_base_dev(stats.st_rdev, &data->device))
|
|
||||||
goto out_close;
|
goto out_close;
|
||||||
data->partnum = blkext_get_partnum(stats.st_rdev);
|
data->partnum = util_sys_get_partnum(stats.st_rdev);
|
||||||
if (data->partnum == -1)
|
if (data->partnum == -1)
|
||||||
goto out_close;
|
goto out_close;
|
||||||
|
} else {
|
||||||
|
data->device = stats.st_rdev;
|
||||||
|
data->partnum = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Driver name is unknown */
|
/* Driver name is unknown */
|
||||||
@@ -525,6 +444,9 @@ type_determined:
|
|||||||
}
|
}
|
||||||
/* Convert device size to size in physical blocks */
|
/* Convert device size to size in physical blocks */
|
||||||
data->phy_blocks = devsize / (data->phy_block_size / 512);
|
data->phy_blocks = devsize / (data->phy_block_size / 512);
|
||||||
|
/* Adjust start on SCSI according to block_size. device-mapper devices are skipped */
|
||||||
|
if (data->type == disk_type_scsi && target->targetbase == NULL)
|
||||||
|
data->geo.start = data->geo.start / (data->phy_block_size / 512);
|
||||||
if (data->partnum != 0)
|
if (data->partnum != 0)
|
||||||
data->partition = stats.st_rdev;
|
data->partition = stats.st_rdev;
|
||||||
/* Try to get device name */
|
/* Try to get device name */
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
@@ -730,6 +732,67 @@ scan_bls_field(struct misc_file_buffer *file, struct scan_token* scan,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find a line with keyword "title" and move it to the top
|
||||||
|
*/
|
||||||
|
static int sort_bls_fields(struct misc_file_buffer *file, char *filename)
|
||||||
|
{
|
||||||
|
bool is_title = false;
|
||||||
|
size_t title_len = 0;
|
||||||
|
int nr_titles = 0;
|
||||||
|
size_t title_off;
|
||||||
|
char *title;
|
||||||
|
int current;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while (file->length - file->pos > 4 /* for "title" */) {
|
||||||
|
if (strncmp("title", &file->buffer[file->pos], 5) == 0) {
|
||||||
|
is_title = true;
|
||||||
|
nr_titles++;
|
||||||
|
title_off = file->pos;
|
||||||
|
}
|
||||||
|
for (len = 0;; file->pos++, len++) {
|
||||||
|
current = misc_get_char(file, 0);
|
||||||
|
if (current == '\n' || current == EOF)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (is_title == true)
|
||||||
|
title_len = len;
|
||||||
|
if (current == EOF)
|
||||||
|
break;
|
||||||
|
file->pos++;
|
||||||
|
}
|
||||||
|
file->pos = 0;
|
||||||
|
|
||||||
|
if (nr_titles == 0) {
|
||||||
|
error_reason("no title in %s", filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (nr_titles > 1) {
|
||||||
|
error_reason("more than one title in %s", filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (title_off == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
title = misc_malloc(title_len);
|
||||||
|
if (!title)
|
||||||
|
return -1;
|
||||||
|
/*
|
||||||
|
* copy the title field w/o trailing '\n' to the temporary buffer
|
||||||
|
*/
|
||||||
|
memcpy(title, &file->buffer[title_off], title_len);
|
||||||
|
/*
|
||||||
|
* shift preceded memory region w/o trailing '\n' to the right
|
||||||
|
*/
|
||||||
|
assert(file->buffer[title_off - 1] == '\n');
|
||||||
|
memmove(&file->buffer[title_len + 1], &file->buffer[0], title_off - 1);
|
||||||
|
file->buffer[title_len] = '\n';
|
||||||
|
memcpy(&file->buffer[0], title, title_len);
|
||||||
|
|
||||||
|
free(title);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
|
scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
|
||||||
@@ -780,6 +843,10 @@ scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
rc = sort_bls_fields(&file, filename);
|
||||||
|
if (rc)
|
||||||
|
goto err;
|
||||||
|
|
||||||
while ((size_t)file.pos < file.length) {
|
while ((size_t)file.pos < file.length) {
|
||||||
current = misc_get_char(&file, 0);
|
current = misc_get_char(&file, 0);
|
||||||
switch (current) {
|
switch (current) {
|
||||||
|
|||||||
+38
-9
@@ -3,6 +3,11 @@ include ../common.mak
|
|||||||
ifneq (${HAVE_OPENSSL},0)
|
ifneq (${HAVE_OPENSSL},0)
|
||||||
BUILD_TARGETS += zkey
|
BUILD_TARGETS += zkey
|
||||||
INSTALL_TARGETS += install-zkey
|
INSTALL_TARGETS += install-zkey
|
||||||
|
ifneq (${HAVE_JSONC},0)
|
||||||
|
ifneq (${HAVE_LIBCURL},0)
|
||||||
|
SUB_DIRS += ekmfweb
|
||||||
|
endif
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
BUILD_TARGETS += zkey-skip
|
BUILD_TARGETS += zkey-skip
|
||||||
INSTALL_TARGETS += zkey-skip
|
INSTALL_TARGETS += zkey-skip
|
||||||
@@ -10,9 +15,14 @@ endif
|
|||||||
|
|
||||||
ifneq (${HAVE_CRYPTSETUP2},0)
|
ifneq (${HAVE_CRYPTSETUP2},0)
|
||||||
ifneq (${HAVE_JSONC},0)
|
ifneq (${HAVE_JSONC},0)
|
||||||
BUILD_TARGETS += zkey-cryptsetup
|
ifneq (${HAVE_OPENSSL},0)
|
||||||
INSTALL_TARGETS += install-zkey-cryptsetup
|
BUILD_TARGETS += zkey-cryptsetup
|
||||||
CPPFLAGS += -DHAVE_LUKS2_SUPPORT
|
INSTALL_TARGETS += install-zkey-cryptsetup
|
||||||
|
CPPFLAGS += -DHAVE_LUKS2_SUPPORT
|
||||||
|
else
|
||||||
|
BUILD_TARGETS += zkey-cryptsetup-skip-openssl
|
||||||
|
INSTALL_TARGETS += zkey-cryptsetup-skip-openssl
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
|
BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
|
||||||
INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
|
INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
|
||||||
@@ -24,6 +34,8 @@ endif
|
|||||||
|
|
||||||
libs = $(rootdir)/libutil/libutil.a
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
|
CFLAGS += -DKMS_PLUGIN_LOCATION=\"$(ZKEYKMSPLUGINDIR)\"
|
||||||
|
|
||||||
detect-libcryptsetup.dep:
|
detect-libcryptsetup.dep:
|
||||||
echo "#include <libcryptsetup.h>" > detect-libcryptsetup.dep
|
echo "#include <libcryptsetup.h>" > detect-libcryptsetup.dep
|
||||||
echo "#ifndef CRYPT_LUKS2" >> detect-libcryptsetup.dep
|
echo "#ifndef CRYPT_LUKS2" >> detect-libcryptsetup.dep
|
||||||
@@ -62,7 +74,10 @@ zkey-cryptsetup-skip-cryptsetup2:
|
|||||||
zkey-cryptsetup-skip-jsonc:
|
zkey-cryptsetup-skip-jsonc:
|
||||||
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
|
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
|
||||||
|
|
||||||
all: $(BUILD_TARGETS)
|
zkey-cryptsetup-skip-openssl:
|
||||||
|
echo " SKIP zkey-cryptsetup due to HAVE_OPENSSL=0"
|
||||||
|
|
||||||
|
all: $(BUILD_TARGETS) $(SUB_DIRS)
|
||||||
|
|
||||||
zkey.o: zkey.c pkey.h cca.h ep11.h misc.h
|
zkey.o: zkey.c pkey.h cca.h ep11.h misc.h
|
||||||
pkey.o: pkey.c pkey.h cca.h ep11.h utils.h
|
pkey.o: pkey.c pkey.h cca.h ep11.h utils.h
|
||||||
@@ -73,9 +88,10 @@ properties.o: check-dep-zkey properties.c properties.h
|
|||||||
keystore.o: keystore.c keystore.h properties.h pkey.h cca.h ep11.h utils.h
|
keystore.o: keystore.c keystore.h properties.h pkey.h cca.h ep11.h utils.h
|
||||||
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h \
|
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h \
|
||||||
ep11.h misc.h utils.h
|
ep11.h misc.h utils.h
|
||||||
|
kms.o: kms.c kms.h kms-plugin.h utils.h pkey.h
|
||||||
|
|
||||||
zkey: LDLIBS = -ldl -lcrypto
|
zkey: LDLIBS = -ldl -lcrypto
|
||||||
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o $(libs)
|
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o kms.o $(libs)
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c -lcrypto
|
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c -lcrypto
|
||||||
@@ -86,22 +102,35 @@ install-common:
|
|||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
|
||||||
install-zkey:
|
install-zkey: zkey
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||||
|
$(INSTALL) -m 644 -c kms-plugins.conf $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||||
|
|
||||||
install-zkey-cryptsetup:
|
install-zkey-cryptsetup: zkey-cryptsetup
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
||||||
$(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
|
||||||
install: all install-common $(INSTALL_TARGETS)
|
install: all install-common $(INSTALL_TARGETS) $(SUB_DIRS)
|
||||||
|
|
||||||
clean:
|
clean: $(SUB_DIRS)
|
||||||
rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.dep \
|
rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.dep \
|
||||||
check-dep-zkey check-dep-zkey-cryptsetup
|
check-dep-zkey check-dep-zkey-cryptsetup
|
||||||
|
|
||||||
|
#
|
||||||
|
# For simple "make" we explicitly set the MAKECMDGOALS to "all".
|
||||||
|
#
|
||||||
|
ifeq ($(MAKECMDGOALS),)
|
||||||
|
MAKECMDGOALS = all
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(SUB_DIRS):
|
||||||
|
$(foreach goal,$(MAKECMDGOALS), \
|
||||||
|
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||||
|
.PHONY: $(SUB_DIRS)
|
||||||
|
|
||||||
.PHONY: all install clean zkey-skip zkey-cryptsetup-skip-cryptsetup2 \
|
.PHONY: all install clean zkey-skip zkey-cryptsetup-skip-cryptsetup2 \
|
||||||
zkey-cryptsetup-skip-jsonc install-common install-zkey \
|
zkey-cryptsetup-skip-jsonc install-common install-zkey \
|
||||||
install-zkey-cryptsetup
|
install-zkey-cryptsetup
|
||||||
|
|||||||
+6
-5
@@ -554,7 +554,8 @@ static int get_cca_adapter_version(struct cca_lib *cca,
|
|||||||
* because the zcrypt kernel module is on an older level. -ENODEV is
|
* because the zcrypt kernel module is on an older level. -ENODEV is
|
||||||
* returned if the APQN is not available.
|
* returned if the APQN is not available.
|
||||||
*/
|
*/
|
||||||
int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose)
|
int select_cca_adapter(struct cca_lib *cca, unsigned int card,
|
||||||
|
unsigned int domain, bool verbose)
|
||||||
{
|
{
|
||||||
unsigned int adapters, adapter;
|
unsigned int adapters, adapter;
|
||||||
char adapter_serialnr[9];
|
char adapter_serialnr[9];
|
||||||
@@ -633,12 +634,12 @@ struct find_mkvp_info {
|
|||||||
u8 mkvp[MKVP_LENGTH];
|
u8 mkvp[MKVP_LENGTH];
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
bool found;
|
bool found;
|
||||||
int card;
|
unsigned int card;
|
||||||
int domain;
|
unsigned int domain;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int find_mkvp(int card, int domain, void *handler_data)
|
static int find_mkvp(unsigned int card, unsigned int domain, void *handler_data)
|
||||||
{
|
{
|
||||||
struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data;
|
struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data;
|
||||||
struct mk_info mk_info;
|
struct mk_info mk_info;
|
||||||
@@ -711,7 +712,7 @@ int select_cca_adapter_by_mkvp(struct cca_lib *cca, u8 *mkvp, const char *apqns,
|
|||||||
|
|
||||||
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the CCA host "
|
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the CCA host "
|
||||||
"library", printable_mkvp(CARD_TYPE_CCA, mkvp),
|
"library", printable_mkvp(CARD_TYPE_CCA, mkvp),
|
||||||
apqns == 0 ? "ANY" : apqns);
|
apqns == NULL ? "ANY" : apqns);
|
||||||
|
|
||||||
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
|
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
|
||||||
info.flags = flags;
|
info.flags = flags;
|
||||||
|
|||||||
+2
-1
@@ -123,7 +123,8 @@ int key_token_change(struct cca_lib *cca,
|
|||||||
u8 *secure_key, unsigned int secure_key_size,
|
u8 *secure_key, unsigned int secure_key_size,
|
||||||
char *method, bool verbose);
|
char *method, bool verbose);
|
||||||
|
|
||||||
int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose);
|
int select_cca_adapter(struct cca_lib *cca, unsigned int card,
|
||||||
|
unsigned int domain, bool verbose);
|
||||||
|
|
||||||
#define FLAG_SEL_CCA_MATCH_CUR_MKVP 0x01
|
#define FLAG_SEL_CCA_MATCH_CUR_MKVP 0x01
|
||||||
#define FLAG_SEL_CCA_MATCH_OLD_MKVP 0x02
|
#define FLAG_SEL_CCA_MATCH_OLD_MKVP 0x02
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
include ../../common.mak
|
||||||
|
|
||||||
|
VERSION = 1.0
|
||||||
|
VERM = $(shell echo $(VERSION) | cut -d '.' -f 1)
|
||||||
|
|
||||||
|
all: zkey-ekmfweb.so
|
||||||
|
|
||||||
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
|
zkey-ekmfweb.o: zkey-ekmfweb.c zkey-ekmfweb.h ../kms-plugin.h \
|
||||||
|
../cca.h ../utils.h ../pkey.h ../properties.h \
|
||||||
|
$(rootdir)include/ekmfweb/ekmfweb.h libekmfweb.dep
|
||||||
|
|
||||||
|
properties.o: ../properties.c ../properties.h
|
||||||
|
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||||
|
|
||||||
|
pkey.o: ../pkey.c ../pkey.h ../cca.h ../ep11.h ../utils.h
|
||||||
|
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||||
|
|
||||||
|
cca.o: ../cca.c ../cca.h ../pkey.h ../ep11.h ../utils.h
|
||||||
|
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||||
|
|
||||||
|
ep11.o: ../ep11.c ../ep11.h ../pkey.h ../cca.h ../utils.h
|
||||||
|
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||||
|
|
||||||
|
utils.o: ../utils.c ../utils.h ../pkey.h ../cca.h ../ep11.h
|
||||||
|
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||||
|
|
||||||
|
zkey-ekmfweb.so: ALL_CFLAGS += -fPIC
|
||||||
|
zkey-ekmfweb.so: LDLIBS = -L$(rootdir)/libekmfweb -lekmfweb -ldl -lcrypto
|
||||||
|
zkey-ekmfweb.so: ALL_LDFLAGS += -shared -Wl,--version-script=zkey-ekmfweb.map \
|
||||||
|
-Wl,-z,defs,-Bsymbolic -Wl,-soname,zkey-ekmfweb.so.$(VERM)
|
||||||
|
zkey-ekmfweb.so: zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o $(libs)
|
||||||
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
|
install-libekmfweb.dep:
|
||||||
|
$(MAKE) -C $(rootdir)/libekmfweb/ TOPDIR=$(TOPDIR) ARCH=$(ARCH) install
|
||||||
|
touch install-libekmfweb.dep
|
||||||
|
|
||||||
|
libekmfweb.dep:
|
||||||
|
$(MAKE) -C $(rootdir)/libekmfweb/ TOPDIR=$(TOPDIR) ARCH=$(ARCH) all
|
||||||
|
touch libekmfweb.dep
|
||||||
|
|
||||||
|
install: all install-libekmfweb.dep zkey-ekmfweb.so
|
||||||
|
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
$(INSTALL) -m 644 -c zkey-ekmfweb.1 $(DESTDIR)$(MANDIR)/man1
|
||||||
|
$(INSTALL) -d -m 755 $(DESTDIR)$(ZKEYKMSPLUGINDIR)
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T zkey-ekmfweb.so $(DESTDIR)$(ZKEYKMSPLUGINDIR)/zkey-ekmfweb.so
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o zkey-ekmfweb.so install-libekmfweb.dep libekmfweb.dep
|
||||||
|
|
||||||
|
.PHONY: all install clean
|
||||||
@@ -0,0 +1,497 @@
|
|||||||
|
.\" Copyright IBM Corp. 2020
|
||||||
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
.\"
|
||||||
|
.TH ZKEY\-EKMFWEB 1 "July 2020" "s390-tools"
|
||||||
|
.SH NAME
|
||||||
|
zkey\-ekmfweb \- Key management system plugin for EKMF Web (IBM Enterprise Key
|
||||||
|
Management Foundation \- Web Edition)
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The \fBzkey\-ekmfweb.so\fP library is a key management system plugin for
|
||||||
|
\fBzkey\fP and provides an interface to \fBEKMF Web\fP (IBM Enterprise Key
|
||||||
|
Management Foundation \- Web Edition). It allows to integrate the external key
|
||||||
|
management system EKMF Web into zkey.
|
||||||
|
.PP
|
||||||
|
Secure AES keys can be generated in EKMF Web and are then imported into the zkey
|
||||||
|
secure key repository. The keys can be used to encrypt volumes, the same way
|
||||||
|
as with secure AES keys generated by zkey locally.
|
||||||
|
.PP
|
||||||
|
EKMF Web supports secure keys of type \fBCCA\-AESCIPHER\fP, and requires one or
|
||||||
|
multiple \fBIBM cryptographic adapters in CCA coprocessor mode\fP of version 6
|
||||||
|
or later, e.g. a CEX6C.
|
||||||
|
.
|
||||||
|
.SS "Bind the zkey secure key repository to EKMF Web"
|
||||||
|
.
|
||||||
|
To use EKMF Web with zkey, the zkey secure key repository must first be bound to
|
||||||
|
the EKMF Web key management system plugin.
|
||||||
|
.PP
|
||||||
|
Use the \fBzkey kms plugins\fP command to list available key management system
|
||||||
|
plugins. The EKMF Web plugin appears as plugin \fBEKMFWeb\fP in the list of
|
||||||
|
available plugins. If it does not appear, check if it is configured properly in
|
||||||
|
configuration file \fB/etc/zkey/kms\-plugins.conf\fP. Refer to the \fBzkey\fP
|
||||||
|
man page for details about this configuration file.
|
||||||
|
.PP
|
||||||
|
Use the \fBzkey kms bind EKMFWeb\fP command to bind the EKMF Web key management
|
||||||
|
system plugin to the zkey repository. You must then configure the EKMF Web
|
||||||
|
plugin with command \fBzkey kms configure\fP before it can be used.
|
||||||
|
.
|
||||||
|
.SS "Display information about the EKMF Web key management system plugin"
|
||||||
|
.
|
||||||
|
Use the \fBzkey kms info\fP command to display information about the EKMF Web
|
||||||
|
key management system plugin and its configuration. If any of the settings are
|
||||||
|
displayed as \fB'(configuration required)'\fP, then you must configure these
|
||||||
|
settings before you can use the EKMF Web plugin. Use the \fBzkey kms
|
||||||
|
configure\fP to do so.
|
||||||
|
.
|
||||||
|
.SS "Configure the EKMF Web key management system plugin"
|
||||||
|
.
|
||||||
|
Use the \fBzkey kms configure\fP command to configure or re\-configure the
|
||||||
|
EKMF Web plugin. Use command \fBzkey kms configure \-\-help\fP to display the
|
||||||
|
possible command line options to perform the configuration.
|
||||||
|
.PP
|
||||||
|
Configuring the EKMF Web plugin may be a multi-step task. You can supply all
|
||||||
|
configuration options at once or use the \fBzkey kms configure\fP command
|
||||||
|
several times supplying only one or a few configuration options each time.
|
||||||
|
.PP
|
||||||
|
The following settings must be configured:
|
||||||
|
.RS 2
|
||||||
|
.IP "\(bu" 2
|
||||||
|
The \fBAPQNs\fP associated with the EKMF Web key management system plugin. These
|
||||||
|
APQNs are used by the EKMF Web plugin to generate internally used secure keys
|
||||||
|
(i.e. the identity key), as well as to import secure AES keys from EKMF Web into
|
||||||
|
the zkey repository, enciphered with the current CCA master key. Secure keys
|
||||||
|
imported from EKMF Web will automatically be associated with the APQNs
|
||||||
|
associated with the EKMF Web plugin. Use the \fB\-\-apqns\fP option to specify
|
||||||
|
the APQNs to associate with the EKMF Web plugin.
|
||||||
|
.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
The \fBconnection to the EKMF Web server\fP. The EKMF Web plugin communicates
|
||||||
|
with EKMF Web via RESTful web services over HTTPS (Hypertext Transfer Protocol
|
||||||
|
Secure). Use option \fB\-\-ekmfweb\-url\fP to specify the URL of the EKMF Web
|
||||||
|
server. The URL should start with \fB'https://'\fP, and may contain a port
|
||||||
|
number separated by a colon. If no port number is specified, 443 is used for
|
||||||
|
HTTPS. Additional TLS (Transport Layer Security) specific options can be
|
||||||
|
specified to control the behavior of the TLS protocol and the validation of the
|
||||||
|
EKMF Web server's certificate. Use command \fBzkey kms configure \-\-help\fP to
|
||||||
|
display the possible command line options.
|
||||||
|
.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
The \fBEKMF Web settings\fP, such as the EKMF Web server's public key and the
|
||||||
|
key templates used by EKMF Web to generate keys. These settings are
|
||||||
|
automatically retrieved from EKMF Web, once the connection to the EKMF Web
|
||||||
|
server has been configured. Use option \fB\-\-refresh\-settings\fP to refresh
|
||||||
|
the settings, when they have changed in EKMF Web.
|
||||||
|
.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
The secure \fBidentity key\fP used to identify the zkey client with EKMF Web,
|
||||||
|
and to cryptographically sign requests sent to EKMF Web. The identity key
|
||||||
|
is a secure key, and is automatically generated once the connection to the
|
||||||
|
EKMF Web server has been configured. Use option \fB\-\-gen\-identity\-key\fP to
|
||||||
|
re-generate the identity key, if needed. You must re-generate a
|
||||||
|
registration certificate with the newly generated identity key and re-register
|
||||||
|
this zkey client with the EKMF Web server.
|
||||||
|
.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
The \fBregistration certificate\fP to register the zkey client with EKMF Web.
|
||||||
|
The registration certificate is an X.509 certificate generated with the secure
|
||||||
|
identity key. Use option \fB\-\-gen\-csr\fP to generate a \fBcertificate signing
|
||||||
|
request\fP (CSR) with the identity key. You pass this CSR to a certificate
|
||||||
|
authority (CA) to have it issue a CA signed certificate for the EKMF Web
|
||||||
|
plugin. Alternatively, use option \fB\-\-gen\-self\-signed\-cert\fP to generate
|
||||||
|
a \fBself signed certificate\fP with the identity key for the EKMF Web plugin.
|
||||||
|
Use options \fB\-\-cert\-subject\fP and \fB\-\-cert\-extensions\fP to specify
|
||||||
|
the certificate subject name and extensions (if any). To renew an existing
|
||||||
|
certificate, use option \fB\-\-renew\-cert\fP. The subject name and extensions
|
||||||
|
are then read from the certificate that is to be renewed.
|
||||||
|
.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
\fBRegister\fP the zkey client with EKMF Web. Use option \fB\-\-register\fP to
|
||||||
|
register the zkey client using the \fBregistration certificate\fP from the
|
||||||
|
previous step. An identity key is generated in EKMF Web using the public
|
||||||
|
key from the certificate. You may also need to use option
|
||||||
|
\fB\-\-label\-tags\fP to specify the label tags for creating the identity key
|
||||||
|
in EKMF Web. Use command \fBzkey kms info\fP to find out which label tags the
|
||||||
|
identity key template uses.
|
||||||
|
.RE
|
||||||
|
.
|
||||||
|
.SS "Re-encipher the secure identity key"
|
||||||
|
.
|
||||||
|
Use the \fBzkey kms reencipher\fP command to re-encipher the secure identity
|
||||||
|
key of the EKMF Web plugin with a new master key.
|
||||||
|
The secure identity key must be re-enciphered when the \fBAPKA master key\fP
|
||||||
|
of the CCA cryptographic adapter changes.
|
||||||
|
.PP
|
||||||
|
See the man page of \fBzkey\fP for a description of the the \fBzkey kms
|
||||||
|
reencipher\fP command.
|
||||||
|
.PP
|
||||||
|
\fBNote:\fP The \fBzkey kms reencipher\fP command does \fBnot\fP re-encipher
|
||||||
|
secure keys that have been generated by or have been imported from EKMF Web and
|
||||||
|
are now stored in the secure key repository. Use the regular \fBzkey
|
||||||
|
reencipher\fP command to re-encipher those secure keys.
|
||||||
|
.
|
||||||
|
.SS "Generating secure AES keys with EKMF Web"
|
||||||
|
.
|
||||||
|
Use the \fBzkey generate\fP command to generate secure AES keys in EKMF Web and
|
||||||
|
import the newly generated key into the secure key repository. When the zkey
|
||||||
|
repository is bound to the EKMF Web plugin, then the \fBzkey generate\fP command
|
||||||
|
always generates the keys in EKMF Web, except when the \fB\-\-local\fP
|
||||||
|
option is specified.
|
||||||
|
.PP
|
||||||
|
Keys generated in EKMF Web are always of type \fBCCA\-AESCIPHER\fP. The
|
||||||
|
cryptographic size of the keys depend on the underlying EKMF Web template.
|
||||||
|
Use \fBzkey kms info\fP to display the names of the key templates configured.
|
||||||
|
If option \fB\-\-key\-bits\fP is specified, it must match the key size in the
|
||||||
|
template.
|
||||||
|
.PP
|
||||||
|
You may need to use option \fB\-\-label\-tags\fP to specify the label tags
|
||||||
|
for creating keys in EKMF Web. Use command \fBzkey kms info\fP to find out
|
||||||
|
which label tags the configured key template uses.
|
||||||
|
.PP
|
||||||
|
Keys generated with EKMF Web are bound to EKMF Web, and also inherit the APQN
|
||||||
|
association from the EKMF Web plugin. You cannot associate different APQNs to
|
||||||
|
a key that is bound to EKMF Web. Other additional information can be associated
|
||||||
|
with a secure key as usual, using the \fB\-\-description\fP, \fB\-\-volumes\fP,
|
||||||
|
\fB\-\-volume\-type\fP, or the \fB\-\-sector\-size\fP options. This associated
|
||||||
|
information is also stored in EKMF Web with the key.
|
||||||
|
.
|
||||||
|
.SS "Remove secure keys bound to EKMF Web from the key repository"
|
||||||
|
.
|
||||||
|
Use the \fBzkey remove\fP command to remove an existing secure key from the
|
||||||
|
secure key repository. If the key is bound to EKMF Web, then you can also
|
||||||
|
change the state of the key in EKMF Web, while removing it. Use option
|
||||||
|
\fB\-\-state\fP to specify the new state of the key in EKMF Web. If no state is
|
||||||
|
specified, the key remains unchanged in EKMF Web, but is removed from the local
|
||||||
|
secure key repository only.
|
||||||
|
.
|
||||||
|
.SS "Change secure keys bound to EKMF Web"
|
||||||
|
.
|
||||||
|
Use the \fBzkey change\fP command to change the description, the associated
|
||||||
|
volumes, the sector size, and the volume type of a secure key contained in the
|
||||||
|
secure key repository. If the key is bound to EKMF Web, then the changed
|
||||||
|
information is also updated for the key in EKMF Web.
|
||||||
|
.PP
|
||||||
|
You cannot change the associated cryptographic adapters (APQNs) of a key that
|
||||||
|
is bound to EKMF Web, because it inherits the APQN association from the EKMF
|
||||||
|
Web plugin. To change the APQNs associated with the EKMF Web plugin, use the
|
||||||
|
\fBzkey kms configure\fP command with the \fB--apqns\fP option. This also
|
||||||
|
changes the APQN associations of all secure keys in the secure key repository,
|
||||||
|
that are bound to the EKMF Web plugin.
|
||||||
|
.
|
||||||
|
.SS "Rename secure keys bound to EKMF Web"
|
||||||
|
.
|
||||||
|
Use the \fBzkey rename\fP command to rename an existing secure key in the
|
||||||
|
secure key repository. If the key is bound to EKMF Web, then the new name
|
||||||
|
is also updated for the key in EKMF Web. Note that the key label as it
|
||||||
|
is known in EKMF Web cannot be changed. Only the associated zkey name is
|
||||||
|
updated.
|
||||||
|
.
|
||||||
|
.SS "List secure keys managed by EKMF Web"
|
||||||
|
.
|
||||||
|
Use the \fBzkey kms list\fP command to display eligible secure keys managed by
|
||||||
|
EKMF Web. You can filter the displayed list by key label, key name, associated
|
||||||
|
volumes, and volume type. Refer to the man page of \fBzkey\fP for the details
|
||||||
|
on these filter options.
|
||||||
|
.PP
|
||||||
|
Use option \fB\-\-states\fP to filter the list by the key state in EKMF Web.
|
||||||
|
You can specify multiple states, separated by comma. If this option is omitted,
|
||||||
|
then only keys in \fBACTIVE\fP state are displayed.
|
||||||
|
.PP
|
||||||
|
By default, only keys are displayed, which this zkey client is allowed to use.
|
||||||
|
Only keys where the export control options include the identity key of this zkey
|
||||||
|
client as allowed exporting key can be used by this zkey client.
|
||||||
|
Specify option \fB\-\-all\fP to also list keys that this zkey client is
|
||||||
|
not allowed to use. The EKMF Web operator can change the export control options
|
||||||
|
of a key to allow a certain zkey identity key to export the key.
|
||||||
|
.
|
||||||
|
.SS "Import secure keys managed by EKMF Web into the repository"
|
||||||
|
.
|
||||||
|
Use the \fBzkey kms import\fP command to import secure keys managed by EKMF Web
|
||||||
|
into the secure key repository. You can filter the list of keys to be imported
|
||||||
|
by key label, key name, associated volumes, and volume type. Refer to the man
|
||||||
|
page of \fBzkey\fP for the details on these filter options.
|
||||||
|
.PP
|
||||||
|
Only keys are imported, which this zkey client is allowed to use. Only keys
|
||||||
|
where the export control options include the identity key of this zkey
|
||||||
|
client as allowed exporting key can be used by this zkey client. The EKMF Web
|
||||||
|
operator can change the export control options of a key, to allow a certain
|
||||||
|
zkey identity key to export the key.
|
||||||
|
.
|
||||||
|
.SS "Refresh secure keys bound to EKMF Web"
|
||||||
|
.
|
||||||
|
Use the \fBzkey kms refresh\fP command to refresh secure keys that are bound to
|
||||||
|
EKMF Web. You can filter the list of keys to be refreshed by name, associated
|
||||||
|
volumes, volume type, and key type. Refreshing a key updates the secure key by
|
||||||
|
re-importing it from EKMF Web. Use option \fB\-\-refresh\-properties\fP to also
|
||||||
|
update the associated information, such as the textual description, associated
|
||||||
|
volumes, volume type, and sector size, with the information stored with the key
|
||||||
|
in EKMF Web. Refer to the man page of \fBzkey\fP for the details on the \fBzkey
|
||||||
|
kms refresh\fP command.
|
||||||
|
.PP
|
||||||
|
The \fBzkey kms refresh\fP command can also help if the secure keys have not
|
||||||
|
been re-enciphered properly after a CCA master key change, and thus became
|
||||||
|
invalid. By refreshing the keys using the \fBzkey kms refresh\fP command, the
|
||||||
|
secure key is re-imported under the current CCA master key. So this command
|
||||||
|
could also be used as an alternative to the \fBzkey reencipher\fP command for
|
||||||
|
keys that are bound to EKMF Web.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH OPTIONS
|
||||||
|
This section describes the EKMF Web plugin specific options of the \fBzkey\fP
|
||||||
|
commands. Refer to the \fBzkey\fP man page for the remaining, non EKMF Web
|
||||||
|
plugin specific options.
|
||||||
|
.
|
||||||
|
.SS "Options for the zkey kms configure command"
|
||||||
|
.TP
|
||||||
|
.BR \-u ", " \-\-ekmfweb\-url\~\fIurl\fP
|
||||||
|
Specifies the URL of the EKMF Web server. The URL should start with
|
||||||
|
\fBhttps://\fP, and may contain a port number separated by a colon. If no
|
||||||
|
port number is specified, 443 is used for HTTPS.
|
||||||
|
.TP
|
||||||
|
.BR \-b ", " \-\-tls\-ca\-bundle\~\fIca\-bundle\fP
|
||||||
|
Specifies the CA bundle PEM file or directory containing the CA certificates
|
||||||
|
used to verify the EKMF Web server certificate during TLS handshake. If this
|
||||||
|
specifies a directory path, then this directory must have been prepared
|
||||||
|
with OpenSSL's \fBc_rehash\fP utility. Default are the system CA certificates.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-client\-cert\~\fIpem\-file\fP
|
||||||
|
Specifies the PEM file containing the client's TLS certificate for use with
|
||||||
|
TLS client authentication.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-client\-key\~\fIpem\-file\fP
|
||||||
|
Specifies the PEM file containing the client's private key for use with TLS
|
||||||
|
client authentication.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-client\-key\-passphrase\~\fIpassphrase\fP
|
||||||
|
If the PEM file is passphrase protected, this option specifies the passphrase
|
||||||
|
to unlock the PEM file that is specified with option \fB\-\-tls\-client\-key\fP.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-pin\-server\-pubkey
|
||||||
|
Pin the EKMF Web server's public key to verify on every connection that the
|
||||||
|
public key of the EKMF Web server's certificate is the same that was used when
|
||||||
|
the connection to the EKMF Web server was configured. This option can only be
|
||||||
|
used with CA signed EKMF Web server certificates.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-trust\-server\-cert
|
||||||
|
Trust the EKMF Web server's certificate even if it is a self signed
|
||||||
|
certificate, or could not be verified due to other reasons. This option can be
|
||||||
|
used instead of option \fB\-\-tls\-pin\-server\-pubkey\fP with self signed
|
||||||
|
EKMF Web server certificates.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-dont\-verify\-server\-cert
|
||||||
|
Do not verify the authenticity of the EKMF Web server's certificate. For self
|
||||||
|
signed EKMF Web server certificates, this is the default. Use option
|
||||||
|
\fB\-\-tls\-pin\-server\-cert\fP to ensure the self signed certificate's
|
||||||
|
authenticity explicitly. CA signed EKMF Web server certificates are verified by
|
||||||
|
default. This option disables the verification.
|
||||||
|
.TP
|
||||||
|
.BR \-\-tls\-verify\-hostname
|
||||||
|
Verify that the EKMF Web server certificate's \fBCommon Name\fP field or a
|
||||||
|
\fBSubject Alternate Name\fP field matches the host name used to connect to the
|
||||||
|
EKMF Web server.
|
||||||
|
.TP
|
||||||
|
.BR \-R ", " \-\-refresh\-settings
|
||||||
|
Refresh the EKMF Web server settings. This is automatically performed when the
|
||||||
|
connection to the EKMF Web server is (re-)configured. Use this option when the
|
||||||
|
settings of the already configured EKMF Web server have changed.
|
||||||
|
.TP
|
||||||
|
.BR \-i ", " \-\-gen\-identity\-key
|
||||||
|
Generate an identity key for the EKMF Web plugin. An identity key is
|
||||||
|
automatically generated when the EKMF Web server connection has been configured.
|
||||||
|
Use this option to generate a new identity key. You need to re-generate a
|
||||||
|
registration certificate with the newly generated identity key, and re-register
|
||||||
|
this zkey client with the EKMF Web server.
|
||||||
|
.TP
|
||||||
|
.BR \-c ", " \-\-gen\-csr\~\fIcsr\-pem\-file\fP
|
||||||
|
Generate a certificate signing request (CSR) with the identity key and store it
|
||||||
|
into the specified PEM file. You pass this CSR to a certificate authority (CA)
|
||||||
|
to have it issue a CA signed certificate for the EKMF Web plugin. You need to
|
||||||
|
register the certificate with EKMF Web before you can access EKMF Web.
|
||||||
|
.TP
|
||||||
|
.BR \-C ", " \-\-gen\-self\-signed\-cert\~\fIcert\-pem\-file\fP
|
||||||
|
Generate a self signed certificate with the identity key and store it into the
|
||||||
|
specified PEM file. You need to register the certificate with EKMF Web before
|
||||||
|
you can access EKMF Web.
|
||||||
|
.TP
|
||||||
|
.BR \-s ", " \-\-cert\-subject\~\fIsubject\-rdns\fP
|
||||||
|
Specifies the subject name for generating a certificate signing request (CSR)
|
||||||
|
or self signed certificate, in the form
|
||||||
|
\fB<type>=<value>(;<type>=<value>)*[;]\fP with types recognized by OpenSSL.
|
||||||
|
.TP
|
||||||
|
.BR \-e ", " \-\-cert\-extensions\~\fIextensions\fP
|
||||||
|
Specifies the certificate extensions for generating a certificate signing
|
||||||
|
request (CSR) or self signed certificate, in the form
|
||||||
|
\fB<name>=[critical,]<value(s)>(;<name>=[critical,]<value(s)>)*[;]\fP
|
||||||
|
with extension names and values recognized by OpenSSL.
|
||||||
|
.TP
|
||||||
|
.BR \-N ", " \-\-renew\-cert\~\fIcert\-pem\-file\fP
|
||||||
|
Specifies an existing PEM file containing the certificate to be renewed. The
|
||||||
|
certificate's subject name and extensions are used to generate the certificate
|
||||||
|
signing request (CSR) or renewed self signed certificate.
|
||||||
|
.TP
|
||||||
|
.BR \-n ", " \-\-csr\-new\-header
|
||||||
|
Adds the word \fBNEW\fP to the PEM file header and footer lines on the
|
||||||
|
certificate signing request. Some software and some CAs need this.
|
||||||
|
.TP
|
||||||
|
.BR \-d ", " \-\-cert\-validity\-days\~\fIdays\fP
|
||||||
|
Specifies the number of days to certify the self signed certificate. The
|
||||||
|
default is 30 days.
|
||||||
|
.TP
|
||||||
|
.BR \-D ", " \-\-cert\-digest\~\fIdigest\fP
|
||||||
|
Specifies the digest algorithm to use when generating a certificate signing
|
||||||
|
request or self signed certificate. The default is determined by OpenSSL.
|
||||||
|
.TP
|
||||||
|
.BR \-r ", " \-\-register\~\fIcert\-file\fP
|
||||||
|
Register the zkey client with EKMF Web by generating an identity key in EKMF
|
||||||
|
Web using the certificate from the specified file. Supported certificate files
|
||||||
|
formats are \fB.pem\fP, \fB.crt\fP, \fB.cert\fP, \fB.cer\fP, and \fB.der\fP
|
||||||
|
(i.e. either base64 or DER encoded). If you want to register a self signed
|
||||||
|
certificate that you are about to generate using option
|
||||||
|
\fB\-\-gen\-self\-signed\-cert\fP, then specify the same certificate file
|
||||||
|
name here, and the generated certificate is registered right away.
|
||||||
|
.TP
|
||||||
|
.BR \-T ", " \-\-label\-tags\~\fIlabel\-tags\fP
|
||||||
|
Specifies the label tags for generating the identity key in EKMF Web when
|
||||||
|
registering the zkey client, in the form
|
||||||
|
\fB<tag>=<value>(,<tag>=<value>)*[,]\fP with tags as defined by the key
|
||||||
|
template. Use the \fBzkey kms info\fP command to display the key templates used
|
||||||
|
by zkey. For registration, the template for identity keys is used.
|
||||||
|
.
|
||||||
|
.SS "Options for the zkey generate command"
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-T ", " \-\-label\-tags\~\fIlabel\-tags\fP
|
||||||
|
Specifies the label tags for generating a secure key in EKMF Web, in the form
|
||||||
|
\fB<tag>=<value>(,<tag>=<value>)*[,]\fP with tags as defined by the key
|
||||||
|
template. Use the \fBzkey kms info\fP command to display the key templates used
|
||||||
|
by zkey. For XTS type keys the two templates for \fBXTS-Key1\fP and
|
||||||
|
\fBXTS-Key2\fP are used. For non-XTS type keys, the template for \fBNon-XTS\fP
|
||||||
|
keys is used.
|
||||||
|
.
|
||||||
|
.SS "Options for the zkey remove command"
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-s ", " \-\-state\~\fIstate\fP
|
||||||
|
Specifies the state to which to change the key in EKMF Web, after removing
|
||||||
|
the secure key from the local secure key repository. Possible states are
|
||||||
|
\fBDEACTIVATED\fP, \fBCOMPROMISED\fP, \fBDESTROYED\fP, and
|
||||||
|
\fBDESTROYED\-COMPROMISED\fP. If this option is not specified, the state of the
|
||||||
|
key in EKMF Web is not changed, but the key is removed from the local secure
|
||||||
|
key repository only.
|
||||||
|
.
|
||||||
|
.SS "Options for the zkey kms list command"
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-s ", " \-\-states\~\fIstates\fP
|
||||||
|
Specifies the states of the keys that are to be listed. Multiple states can be
|
||||||
|
separated by comma. Possible states are \fBPRE\-ACTIVATION\fP, \fBACTIVE\fP,
|
||||||
|
\fBDEACTIVATED\fP, \fBCOMPROMISED\fP, \fBDESTROYED\fP, and
|
||||||
|
\fBDESTROYED\-COMPROMISED\fP. If this option is not specified, only keys in
|
||||||
|
state \fBACTIVE\fP are listed.
|
||||||
|
.TP
|
||||||
|
.BR \-a ", " \-\-all
|
||||||
|
List all keys that can be used for volume encryption. If this option is not
|
||||||
|
specified, then only volume encryption keys that are allowed to be exported by
|
||||||
|
EKMF Web using the identity key of this zkey client are listed.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.TP
|
||||||
|
.B zkey kms plugins
|
||||||
|
Lists available key manamgement system plugins.
|
||||||
|
.TP
|
||||||
|
.B zkey kms bind EKMFWeb
|
||||||
|
Binds the EKMF Web plugin to the current secure key repository.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-apqns 03.004c
|
||||||
|
Configures the APQN '03.004c' to be associated with the EKMF Web plugin.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-ekmfweb\-url https://my.ekmfweb.server
|
||||||
|
Configures the connection to the EKMF Web server on 'my.ekmfweb.server'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-ekmfweb\-url https://my.ekmfweb.server \-\-tls\-pin\-server\-pubkey \-\-tls\-verify\-hostname
|
||||||
|
Configures the connection to the EKMF Web server on 'my.ekmfweb.server' and
|
||||||
|
pins the server's public key from the server's TSL certificate as well as
|
||||||
|
enables verification of the host name to match the server's Common Name in the
|
||||||
|
certificate.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-gen\-csr csr.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq
|
||||||
|
Generates a certificate signing request with the identity key and the specified
|
||||||
|
subject name and stores it in file 'csr.pem'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-gen\-csr csr.pem \-\-renew\-cert cert.pem
|
||||||
|
Generates a certificate signing request with the identity key to renew the
|
||||||
|
existing certificate in file cert.pem and stores it in file 'csr.pem'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-gen\-self\-signed\-cert cert.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq \-\-cert\-validity\-days 50
|
||||||
|
Generates a self signed certificate with the identity key and the specified
|
||||||
|
subject name and a validity of 50 days, and stores it in file 'cert.pem'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-gen\-self\-signed\-cert cert.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq \-\-cert\-extensions \(dqkeyUsage=critical,digitalSignature,keyAgreement\(dq
|
||||||
|
Generates a self signed certificate with the identity key and the specified
|
||||||
|
subject name and a certificate extension to limit the key usage, and stores it
|
||||||
|
in file 'cert.pem'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-register cert.pem
|
||||||
|
Registers the zkey client with EKMF Web using the certificate in file 'cert.pem'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms configure \-\-register cert.pem \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
|
||||||
|
Registers the zkey client with EKMF Web using the certificate in file 'cert.pem'
|
||||||
|
and the label tags 'ENV=TEST' and 'APP=LINUX' for the identity key.
|
||||||
|
.TP
|
||||||
|
.B zkey kms info
|
||||||
|
Displays information about the EKMF Web plugin and its configuration.
|
||||||
|
.TP
|
||||||
|
.B zkey kms reencipher --staged
|
||||||
|
Re-enciphers the EKMF Plugin's identity key with a new CCA master key in staged
|
||||||
|
mode
|
||||||
|
.TP
|
||||||
|
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
|
||||||
|
Generates a secure AES key in EKMF Web using the label tags 'ENV=TEST' and
|
||||||
|
'APP=LINUX' 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'.
|
||||||
|
.TP
|
||||||
|
.B zkey generate \-\-name seckey \-\-xts \-\-volumes /dev/dasdc1:encvol \-\-volume-type luks2 \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
|
||||||
|
Generates a secure AES key for the XTS cipher mode in EKMF Web using the label
|
||||||
|
tags 'ENV=TEST' and 'APP=LINUX' 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 remove \-\-name seckey \-\-state DEACTIVATED
|
||||||
|
Removes secure key 'seckey' from the repository and sets the state of the key
|
||||||
|
to 'DEACTIVATED' in EKMF Web.
|
||||||
|
.TP
|
||||||
|
.B zkey kms list
|
||||||
|
Displays eligible secure keys managed by EKMF Web which this zkey client is
|
||||||
|
allowed to use and are in state 'ACTIVE'
|
||||||
|
.TP
|
||||||
|
.B zkey kms list \-\-states ACTIVE,DEACTIVATED
|
||||||
|
Displays eligible secure keys managed by EKMF Web which this zkey client is
|
||||||
|
allowed to use and are in state 'ACTIVE' or 'DEACTIVATED'
|
||||||
|
.TP
|
||||||
|
.B zkey kms list \-\-all
|
||||||
|
Displays eligible secure keys managed by EKMF Web, regardless if this zkey
|
||||||
|
client is allowed to use it or not.
|
||||||
|
.TP
|
||||||
|
.B zkey kms list \-\-label \(dq*LUKS2*\(dq
|
||||||
|
Displays eligible secure keys managed by EKMF Web where the label name in EKMF
|
||||||
|
Web contains the word 'LUKS2'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms import \-\-name seckey
|
||||||
|
Imports the secure key managed by EKMF Web with a zkey name of 'seckey'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms import \-\-volume\-type LUKS2
|
||||||
|
Imports secure keys managed by EKMF Web that are associated with volumes of
|
||||||
|
volume type LUKS2.
|
||||||
|
.TP
|
||||||
|
.B zkey kms refresh \-\-name \(dqsec*\(dq
|
||||||
|
Refreshes secure keys from EKMF Web where the name starts with 'sec'.
|
||||||
|
.TP
|
||||||
|
.B zkey kms refresh \-\-name seckey \-\-refresh\-properties
|
||||||
|
Refreshes the secure key with the name 'seckey' from EKMF Web and also refreshs
|
||||||
|
the key properties.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user