mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7770b7a2c0 | ||
|
|
2ef6f64b1d | ||
|
|
de013d2f04 | ||
|
|
ed94cf9839 | ||
|
|
2fec7688b0 | ||
|
|
3c1834f0fc | ||
|
|
f6e78d3ecd | ||
|
|
dad7fce7a1 | ||
|
|
8058921f58 | ||
|
|
bb8e0e1047 | ||
|
|
5dcac6d2e3 | ||
|
|
552772d2a9 | ||
|
|
42611a787d | ||
|
|
743788d02f | ||
|
|
6028300366 | ||
|
|
70cb25766b | ||
|
|
36eede8f31 | ||
|
|
ec0dcdb685 | ||
|
|
2a1a821bb3 | ||
|
|
09c01e580a | ||
|
|
27902c9106 | ||
|
|
a8d328bba2 | ||
|
|
917d611883 | ||
|
|
94e0b644a7 | ||
|
|
10f8565e32 | ||
|
|
22bce41dd7 | ||
|
|
e35e73d2a3 | ||
|
|
f821f31a51 | ||
|
|
493af760ed | ||
|
|
3287bb9613 | ||
|
|
76606802d0 | ||
|
|
e99b32cacb | ||
|
|
87a6154de9 | ||
|
|
ed4c68e867 | ||
|
|
e2b68b4d9b | ||
|
|
686fca1863 | ||
|
|
0c1a5069d9 | ||
|
|
de88b1c71b | ||
|
|
4bba1058c6 | ||
|
|
49937f40a1 | ||
|
|
d55818a797 | ||
|
|
96897ee32e | ||
|
|
5522aaedf4 | ||
|
|
f3b7f4b14b | ||
|
|
01f74c75f5 | ||
|
|
24bcc3141d | ||
|
|
41108c98aa | ||
|
|
f5aa1d4406 | ||
|
|
ee4f503ec0 | ||
|
|
7095da9f9d | ||
|
|
7c656faa36 | ||
|
|
10515380e8 | ||
|
|
7301883e69 | ||
|
|
555f3782d4 | ||
|
|
7ecad86938 | ||
|
|
e496e9862c | ||
|
|
c8e989840f | ||
|
|
908067bdf9 | ||
|
|
2c7e61a6c7 | ||
|
|
ae824745a0 | ||
|
|
2b2c111af4 | ||
|
|
1bfa78896f | ||
|
|
e928c6f83c | ||
|
|
0e86da9d66 | ||
|
|
21dbbcfa56 | ||
|
|
0a512bf904 | ||
|
|
e6be1c1b79 | ||
|
|
a4eb03dfe1 | ||
|
|
fc1167fd34 | ||
|
|
561559277d | ||
|
|
68a3ccd45e | ||
|
|
fcfd4a6158 | ||
|
|
e621d2dfa2 | ||
|
|
a92ee5ba8d | ||
|
|
46c291835f | ||
|
|
4941fc15c0 | ||
|
|
48d7c6e6d1 | ||
|
|
73c46a3056 | ||
|
|
f2c82bf2b5 | ||
|
|
d3a3b26d16 | ||
|
|
c142bb0625 | ||
|
|
ec04a1846e | ||
|
|
0324fac616 | ||
|
|
4014087876 | ||
|
|
8a878a0d61 | ||
|
|
2b511aa2b9 | ||
|
|
6d8243d1b1 | ||
|
|
7ecaeb1a3d | ||
|
|
9ada8332d8 | ||
|
|
ca25f71a6e | ||
|
|
67790d3787 | ||
|
|
d301668811 | ||
|
|
6097ee3f9d | ||
|
|
43967feb2c | ||
|
|
8f4535f5eb | ||
|
|
dfe8a4f803 | ||
|
|
fe0d42e295 | ||
|
|
baf7e9aa2e | ||
|
|
60d03262d8 | ||
|
|
4bed503aa7 | ||
|
|
4518bf7d73 | ||
|
|
3d168fac14 | ||
|
|
746a703079 | ||
|
|
4aa5534f1d | ||
|
|
7c24855ba1 | ||
|
|
6222c38495 | ||
|
|
8709a47f6f | ||
|
|
1fb05038cd | ||
|
|
4f5d33988d | ||
|
|
75513ee975 | ||
|
|
b8fff9b750 | ||
|
|
d5f853c460 | ||
|
|
067dd5c7ef | ||
|
|
af1d05c4a4 | ||
|
|
c5ec01420f | ||
|
|
f25984e716 | ||
|
|
7babd82e6f | ||
|
|
d030874050 | ||
|
|
394a6dd5ea | ||
|
|
db6eb7d554 | ||
|
|
032304d503 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -9,6 +9,9 @@
|
||||
tags
|
||||
TAGS
|
||||
|
||||
# clangd cache (https://clangd.llvm.org/design/indexing#backgroundindex)
|
||||
.cache/
|
||||
|
||||
# Ignore coverage data
|
||||
*.gcda
|
||||
*.gcno
|
||||
@@ -78,7 +81,6 @@ systemd/ttyrun-getty@.service
|
||||
tape390/tape390_crypt
|
||||
tape390/tape390_display
|
||||
tunedasd/src/tunedasd
|
||||
vmconvert/vmconvert
|
||||
vmcp/vmcp
|
||||
vmur/vmur
|
||||
zconf/chp/chchp
|
||||
@@ -110,6 +112,7 @@ ziomon/ziorep_traffic
|
||||
ziomon/ziorep_utilization
|
||||
zipl/boot/*.bin
|
||||
zipl/boot/*.exec
|
||||
zipl/boot/.loaders
|
||||
zipl/boot/data.h
|
||||
zipl/src/chreipl_helper.device-mapper
|
||||
zdev/src/zdev_id
|
||||
|
||||
@@ -90,6 +90,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Mikhail Zaslonko
|
||||
- Nikita Dubrovskii
|
||||
- Niklas Schnelle
|
||||
- Nikolay Gueorguiev
|
||||
- Peter Oberparleiter
|
||||
- Peter Tiedemann
|
||||
- Philipp Kern
|
||||
|
||||
69
CHANGELOG.md
69
CHANGELOG.md
@@ -1,6 +1,75 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.28.0 (2023-07-11)__
|
||||
|
||||
For Linux kernel version: 6.4
|
||||
|
||||
Changes of existing tools:
|
||||
- chzcrypt: Support for SE AP pass-through support
|
||||
- genprotimg: Add support for non-s390x architectures
|
||||
- lszcrypt: Support for SE AP pass-through support
|
||||
- zdev: Add support for autoquiesce related sysfs attributes
|
||||
|
||||
Bug Fixes:
|
||||
- ap_tools/ap-check: Handle missing 'matrix' and 'control_domains' attrs
|
||||
- ap_tools/ap-check: Hold ap config file lock over get attributes
|
||||
- s390-tools: Fix build for ppc64le
|
||||
- zdev: Add missing label in the udev-rules
|
||||
- zdev: Add proper value input for the ZDEV_SITE_ID key
|
||||
- zdev: Use rename-file to avoid any symlinks created
|
||||
- zipl/dump: fix ngdump dracut helper script
|
||||
|
||||
* __v2.27.0 (2023-05-30)__
|
||||
|
||||
For Linux kernel version: 6.3
|
||||
|
||||
Changes of existing tools:
|
||||
- s390-tools cross-compile and non-s390x support:
|
||||
- `pkg-config` is now mandatory for the build process
|
||||
- Add `PKG_CONFIG` Makefile variable to select pkg-config program;
|
||||
default `pkg-config` or `$(CROSS_COMPILE)pkg-config` if
|
||||
`CROSS_COMPILE` is set
|
||||
- Rename Makefile variable `ARCH` to `HOST_ARCH`. `HOST_ARCH` is the
|
||||
architecture that will run the produced (executable) objects
|
||||
- Add the Makefile variable `BUILD_ARCH`. `BUILD_ARCH` is the
|
||||
architecture of the build system. For each Makefile variable like
|
||||
`CC`, `LINK`, `CPP`, ... there is a suffixed version of it - e.g.
|
||||
`CC_FOR_BUILD`. This is useful for cross compiling, and this naming
|
||||
convention is very similar to the Meson convention (see
|
||||
https://mesonbuild.com/Reference-tables.html#environment-variables-per-machine).
|
||||
- Limit build targets for non-s390x architectures (pvattest)
|
||||
- dasdfmt: Fall back to full format if space release fails
|
||||
- dbginfo.sh: Add nstat for network and SNMP stats
|
||||
- dbginfo.sh: Rework crypto data collection
|
||||
- hyptop: Show thread util by default
|
||||
- zipl: Add support for list-directed IPL dump from ECKD DASD
|
||||
|
||||
Bug Fixes:
|
||||
- lszcrypt: Fix argument parsing
|
||||
- zdev/dracut: Fix out-of-memory (OOM) situations in the kdump crashkernel environment
|
||||
- ziomon/ziorep_config: Fix for SCSI devices of type disk without block dev
|
||||
- pvextract-hdr: Fix parsing issues on little-endian systems
|
||||
|
||||
* __v2.26.0 (2023-02-14)__
|
||||
|
||||
For Linux kernel version: 6.2
|
||||
|
||||
Remove tools / libraries:
|
||||
- Remove vmconvert and libvmdump in favor of vmdump file support in zdump
|
||||
|
||||
Changes of existing tools:
|
||||
- ipl_tools: Add support for list-directed IPL from ECKD DASD
|
||||
- lszcrypt: Display hardware filtering support capability
|
||||
- vmur: Remove option -c for dump file conversion (See zdump changes)
|
||||
- zdev: Add zfcp ber_stop parameter handling
|
||||
- zdump: Add vmdump dfi for vmdump format to elf format
|
||||
- zkey: Support EP11 host library version
|
||||
|
||||
Bug Fixes:
|
||||
- zipl: Move dump parmline processing and verification
|
||||
- zipl/genprotimg: Various build improvements
|
||||
|
||||
* __v2.25.0 (2022-12-08)__
|
||||
|
||||
For Linux kernel version: 6.1
|
||||
|
||||
18
Makefile
18
Makefile
@@ -1,5 +1,3 @@
|
||||
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
|
||||
|
||||
# Include common definitions
|
||||
include common.mak
|
||||
|
||||
@@ -8,15 +6,21 @@ include common.mak
|
||||
# LIBS: Libraries that can have a dependency to base libraries
|
||||
# TOOLS: Tools that can have a dependency to base libraries or libraries
|
||||
#
|
||||
ifeq ($(HOST_ARCH),s390x)
|
||||
BASELIB_DIRS = libutil libseckey
|
||||
LIB_DIRS = libvtoc libzds libdasd libvmdump libccw libvmcp libekmfweb \
|
||||
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
|
||||
libkmipclient libcpumf libap libpv
|
||||
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest
|
||||
else
|
||||
BASELIB_DIRS =
|
||||
LIB_DIRS = libpv
|
||||
TOOL_DIRS = genprotimg pvattest
|
||||
endif
|
||||
|
||||
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
@@ -49,15 +53,15 @@ endif
|
||||
|
||||
$(TOOL_DIRS): $(LIB_DIRS)
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(TOOL_DIRS)
|
||||
|
||||
$(LIB_DIRS): $(BASELIB_DIRS)
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(LIB_DIRS)
|
||||
|
||||
$(BASELIB_DIRS):
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(BASELIB_DIRS)
|
||||
|
||||
@@ -98,11 +98,6 @@ Package contents
|
||||
* tunedasd:
|
||||
Adjust tunable parameters on DASD devices.
|
||||
|
||||
* vmconvert:
|
||||
Convert system dumps created by the z/VM VMDUMP command into dumps with
|
||||
LKCD format. These LKCD dumps can then be analyzed with the dump analysis
|
||||
tool lcrash.
|
||||
|
||||
* vmcp:
|
||||
Send commands from Linux as a z/VM guest to the z/VM control program (CP).
|
||||
Call vmcp with the CP command as an argument. The response of z/VM is
|
||||
@@ -330,8 +325,8 @@ This table lists additional build or install options:
|
||||
| initramfs-tools | `HAVE_INITRAMFS` | zdev, zipl |
|
||||
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
|
||||
|
||||
The s390-tools build process uses "pkg-config" if available and hard-coded
|
||||
compiler and linker options otherwise.
|
||||
The s390-tools build process uses "pkg-config" and therefore it must be
|
||||
available.
|
||||
|
||||
Build and runtime requirements for specific tools
|
||||
-------------------------------------------------
|
||||
|
||||
@@ -26,9 +26,9 @@ ap-check: ap-check.o $(libs)
|
||||
install: all
|
||||
@if [ ! -d $(DESTDIR)$(MDEVCTL_CALLOUTS) ]; then \
|
||||
mkdir -p $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||
chmod 755 $(DESTDIR)$(MDEVCTL_DIR); \
|
||||
chmod 755 $(DESTDIR)$(MDEVCTL_SCRIPTS); \
|
||||
chmod 755 $(DESTDIR)$(MDEVCTL_CALLOUTS); \
|
||||
@@ -37,9 +37,9 @@ install: all
|
||||
$(DESTDIR)$(MDEVCTL_CALLOUTS)
|
||||
@if [ ! -d $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS) ]; then \
|
||||
mkdir -p $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_DIR); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_DIR); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_DIR); \
|
||||
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
|
||||
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
|
||||
|
||||
@@ -434,14 +434,23 @@ static int check_other_mdev_sysfs_cb(const char *path, const char *filename,
|
||||
strcasecmp(filename, cbdata->uuid) == 0)
|
||||
return 0;
|
||||
|
||||
dev2 = vfio_ap_device_new();
|
||||
/*
|
||||
* Read the 'matrix' attribute to get the list of queues for the active
|
||||
* device. If the sysfs attribute is unreadable, assume the device is
|
||||
* being destroyed and skip it.
|
||||
*/
|
||||
matrix_path = path_get_vfio_ap_attr(filename, "matrix");
|
||||
f = fopen(matrix_path, "r");
|
||||
free(matrix_path);
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
dev2 = vfio_ap_device_new();
|
||||
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
vfio_ap_parse_matrix(dev2, buf);
|
||||
vfio_ap_sort_matrix_results(dev2);
|
||||
fclose(f);
|
||||
free(matrix_path);
|
||||
|
||||
/* Look for conflicts between target device and this device */
|
||||
rc = find_apqn_conflicts(filename, dev->adapters, dev->domains,
|
||||
@@ -787,21 +796,39 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
|
||||
char buf[80];
|
||||
char *path;
|
||||
FILE *f;
|
||||
int rc;
|
||||
|
||||
rc = ap_get_lock_callout();
|
||||
if (rc) {
|
||||
fprintf(stderr, "Failed to acquire configuration lock %d\n", rc);
|
||||
return -1;
|
||||
}
|
||||
anc->cleanup_lock = true;
|
||||
|
||||
/*
|
||||
* Read the 'matrix' and 'control_domains' attributes to get the
|
||||
* current attributes of the active device. If either of these sysfs
|
||||
* attributes is unreadable, assume the device is being destroyed
|
||||
* and return nothing.
|
||||
*/
|
||||
path = path_get_vfio_ap_attr(anc->uuid, "matrix");
|
||||
f = fopen(path, "r");
|
||||
free(path);
|
||||
if (!f)
|
||||
return 0;
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
vfio_ap_parse_matrix(dev, buf);
|
||||
vfio_ap_sort_matrix_results(dev);
|
||||
fclose(f);
|
||||
free(path);
|
||||
|
||||
path = path_get_vfio_ap_attr(anc->uuid, "control_domains");
|
||||
f = fopen(path, "r");
|
||||
free(path);
|
||||
if (!f)
|
||||
return 0;
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
vfio_ap_parse_control(dev, buf);
|
||||
fclose(f);
|
||||
free(path);
|
||||
|
||||
printf("[{");
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ ALL_PANDOCFLAGS = --preserve-tabs --tab-stop=8 --strip-comments \
|
||||
-M date="$(shell date +'%Y-%m-%d')" \
|
||||
$(PANDOCFLAGS)
|
||||
|
||||
$(eval $(call cmd_define, PANDOC," PANDOC ",pandoc))
|
||||
$(eval $(call cmd_define_and_export, PANDOC," PANDOC ",pandoc))
|
||||
|
||||
%.html : ALL_PANDOCFLAGS += -t html
|
||||
%.html : %.md
|
||||
|
||||
@@ -22,13 +22,8 @@ check_dep:
|
||||
|
||||
all: check_dep cmsfs-fuse
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
||||
else
|
||||
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
|
||||
FUSE_LDLIBS = -lfuse3
|
||||
endif
|
||||
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||
ALL_CFLAGS += -DHAVE_SETXATTR $(FUSE_CFLAGS)
|
||||
LDLIBS += $(FUSE_LDLIBS) -lm
|
||||
|
||||
|
||||
152
common.mak
152
common.mak
@@ -1,25 +1,47 @@
|
||||
ifndef $(COMMON_INCLUDED)
|
||||
COMMON_INCLUDED = true
|
||||
COMMON_INCLUDED ?= false
|
||||
V ?= 0
|
||||
W ?= 0
|
||||
G ?= 0
|
||||
C ?= 0
|
||||
D ?= 0
|
||||
ASAN ?= 0
|
||||
ENABLE_WERROR ?= 0
|
||||
OPT_FLAGS ?=
|
||||
MAKECMDGOALS ?=
|
||||
|
||||
ifeq ($(COMMON_INCLUDED),false)
|
||||
COMMON_INCLUDED := true
|
||||
|
||||
# 'BUILD_ARCH' is the architecture of the machine where the build takes place
|
||||
BUILD_ARCH := $(shell uname -m | sed -e 's/i.86/i386/' -e 's/sun4u/sparc64/' -e 's/arm.*/arm/' -e 's/sa110/arm/')
|
||||
# 'HOST_ARCH' is the architecture of the machine that will run the compiled output
|
||||
HOST_ARCH ?= $(BUILD_ARCH)
|
||||
|
||||
# The `*clean` targets are mutually exclusive to all other targets
|
||||
ifneq ($(filter %clean,$(MAKECMDGOALS)),)
|
||||
ifneq ($(MAKECMDGOALS),$(filter %clean,$(MAKECMDGOALS)))
|
||||
$(error The *clean targets are mutually exclusive to all other targets)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Global definitions
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION = 2
|
||||
RELEASE = 25
|
||||
RELEASE = 28
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
export S390_TOOLS_RELEASE
|
||||
|
||||
reldir = $(subst $(shell cd -P $(dir $(filter %common.mak,$(MAKEFILE_LIST))); \
|
||||
pwd)/,,$(CURDIR))
|
||||
reldir = $(subst $(realpath $(dir $(filter %common.mak,$(MAKEFILE_LIST))))/,,$(CURDIR))
|
||||
rootdir= $(dir $(filter %common.mak,$(MAKEFILE_LIST)))
|
||||
export S390_TEST_LIB_PATH=$(rootdir)/s390-tools-testsuite/lib
|
||||
|
||||
#
|
||||
# For cross compiles specify CROSS_COMPILE= on the commandline:
|
||||
# For cross compiles specify HOST_ARCH= and CROSS_COMPILE= on the commandline:
|
||||
#
|
||||
# $ make CROSS_COMPILE="s390x-5.1.0-"
|
||||
# $ make HOST_ARCH=s390x CROSS_COMPILE="s390x-linux-gnu-"
|
||||
#
|
||||
|
||||
CROSS_COMPILE =
|
||||
@@ -29,8 +51,10 @@ CROSS_COMPILE =
|
||||
#
|
||||
# $ make CC=gcc-4.8
|
||||
#
|
||||
# The "cmd_define" macro wraps the command definition so that the commands
|
||||
# can be user supplied and are still pretty-printed for the build process.
|
||||
# The "cmd_define_and_export" macro wraps the command definition so that
|
||||
# the commands can be user supplied and are still pretty-printed for the
|
||||
# build process. In addition, the command variable gets exported so it
|
||||
# can be used by sub-makes.
|
||||
#
|
||||
# The macro is called with the following parameters:
|
||||
#
|
||||
@@ -40,13 +64,14 @@ CROSS_COMPILE =
|
||||
#
|
||||
# The Example below...
|
||||
#
|
||||
# $(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||
# $(eval $(call cmd_define_and_export, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||
#
|
||||
# ... produces the following code:
|
||||
#
|
||||
# CC = $(CROSS_COMPILE)gcc
|
||||
# CC_SILENT := $(CC)
|
||||
# override CC = $(call echocmd," CC ",/$@)$(CC_SILENT)
|
||||
# export CC
|
||||
#
|
||||
# The "strip" make function is used for the first parameter to allow blanks,
|
||||
# which improves readability.
|
||||
@@ -58,23 +83,47 @@ define cmd_define
|
||||
override $(strip $(1)) = $$(call echocmd,$(2),/$$@)$$($(strip $(1))_SILENT)
|
||||
endef
|
||||
|
||||
$(eval $(call cmd_define, AS," AS ",$(CROSS_COMPILE)as))
|
||||
$(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||
$(eval $(call cmd_define, LINK," LINK ",$(CC)))
|
||||
$(eval $(call cmd_define, HOSTCC," HOSTCC ",gcc))
|
||||
$(eval $(call cmd_define, CXX," CXX ",$(CROSS_COMPILE)g++))
|
||||
$(eval $(call cmd_define, LINKXX," LINKXX ",$(CXX)))
|
||||
$(eval $(call cmd_define, CPP," CPP ",$(CROSS_COMPILE)gcc -E))
|
||||
$(eval $(call cmd_define, AR," AR ",$(CROSS_COMPILE)ar))
|
||||
$(eval $(call cmd_define, NM," NM ",$(CROSS_COMPILE)nm))
|
||||
$(eval $(call cmd_define, STRIP," STRIP ",$(CROSS_COMPILE)strip))
|
||||
$(eval $(call cmd_define,OBJCOPY," OBJCOPY ",$(CROSS_COMPILE)objcopy))
|
||||
$(eval $(call cmd_define,OBJDUMP," OBJDUMP ",$(CROSS_COMPILE)objdump))
|
||||
define cmd_define_and_export
|
||||
$(call cmd_define,$(1),$(2),$(3))
|
||||
export $(strip $(1))
|
||||
endef
|
||||
|
||||
define define_toolchain_variables
|
||||
$(eval $(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as))
|
||||
$(eval $(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc))
|
||||
$(eval $(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1))))
|
||||
$(eval $(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++))
|
||||
$(eval $(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1))))
|
||||
$(eval $(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E))
|
||||
$(eval $(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar))
|
||||
$(eval $(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm))
|
||||
$(eval $(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip))
|
||||
$(eval $(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy))
|
||||
$(eval $(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump))
|
||||
$(eval PKG_CONFIG$(1) = pkg-config)
|
||||
$(eval export PKG_CONFIG$(1))
|
||||
endef
|
||||
|
||||
# If the host architecture is not the same as the build architecture
|
||||
# 'CROSS_COMPILE=...' is always required (except for the '*clean' targets).
|
||||
ifneq ($(HOST_ARCH),$(BUILD_ARCH))
|
||||
ifeq ($(CROSS_COMPILE),)
|
||||
# `make clean` and similar must always work!
|
||||
ifeq ($(filter %clean,$(MAKECMDGOALS)),)
|
||||
$(error Please specify CROSS_COMPILE=... and try it again!)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
$(call define_toolchain_variables,_FOR_BUILD,)
|
||||
$(call define_toolchain_variables,,$(CROSS_COMPILE))
|
||||
|
||||
$(eval $(call cmd_define,RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
||||
$(eval $(call cmd_define, CAT," CAT ",cat))
|
||||
$(eval $(call cmd_define, SED," SED ",sed))
|
||||
$(eval $(call cmd_define, GZIP," GZIP ",gzip))
|
||||
$(eval $(call cmd_define, MV," MV ",mv))
|
||||
$(eval $(call cmd_define, PERLC," PERLC ",perl -c))
|
||||
|
||||
CHECK = sparse
|
||||
CHECK_SILENT := $(CHECK)
|
||||
@@ -101,6 +150,10 @@ else
|
||||
DEFAULT_CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifeq ("${ENABLE_WERROR}", "1")
|
||||
DEFAULT_CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
||||
DEFAULT_LDFLAGS = -rdynamic
|
||||
|
||||
@@ -109,6 +162,11 @@ ifeq ("${ASAN}","1")
|
||||
DEFAULT_LDFLAGS += -fsanitize=address
|
||||
endif
|
||||
|
||||
DEFAULT_PERLCFLAGS =
|
||||
ifeq ("${W}","1")
|
||||
DEFAULT_PERLCFLAGS += -w
|
||||
endif
|
||||
|
||||
#
|
||||
# Check for header prerequisite
|
||||
#
|
||||
@@ -145,6 +203,20 @@ then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
#
|
||||
# Test for linker option
|
||||
#
|
||||
# $1: Linker option
|
||||
#
|
||||
# Returns the linker option if available and nothing otherwise
|
||||
#
|
||||
define test_linker_flag
|
||||
$(shell printf ".globl _start\n_start:\nnop\n" | \
|
||||
( $(LINK) "-Wl,$1" -o /dev/null -nostdlib -x assembler -) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
|
||||
endef
|
||||
|
||||
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
|
||||
|
||||
#
|
||||
# Support alternate install root
|
||||
#
|
||||
@@ -221,10 +293,10 @@ ZFCPDUMP_INITRD = zfcpdump-initrd
|
||||
ZFCPDUMP_FLAVOR = zfcpdump
|
||||
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
|
||||
|
||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
|
||||
LDFLAGS ?= $(DEFAULT_LDFLAGS)
|
||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
CFLAGS_FOR_BUILD ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
|
||||
LDFLAGS ?= $(DEFAULT_LDFLAGS)
|
||||
|
||||
ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||
@@ -242,6 +314,8 @@ ALL_CXXFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
|
||||
ALL_LDFLAGS = $(LDFLAGS)
|
||||
|
||||
ALL_PERLCFLAGS = $(DEFAULT_PERLCFLAGS)
|
||||
|
||||
# make G=1
|
||||
# Compile tools so that gcov can be used to collect code coverage data.
|
||||
# See the gcov man page for details.
|
||||
@@ -250,7 +324,7 @@ ALL_CFLAGS := $(filter-out -O%,$(ALL_CFLAGS)) --coverage
|
||||
ALL_CXXFLAGS := $(filter-out -O%,$(ALL_CXXFLAGS)) --coverage
|
||||
ALL_LDFLAGS += --coverage
|
||||
endif
|
||||
export AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP INSTALL CFLAGS CXXFLAGS \
|
||||
export INSTALL CFLAGS CXXFLAGS \
|
||||
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
|
||||
|
||||
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||
@@ -261,7 +335,7 @@ else
|
||||
NO_PIE_LDFLAGS :=
|
||||
endif
|
||||
|
||||
# Overwrite implicite makefile rules for having nice compile output
|
||||
# Overwrite implicit makefile rules for having nice compile output
|
||||
%.o: %.c
|
||||
ifeq ("${C}","1")
|
||||
$(CHECKTOOL) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@
|
||||
@@ -288,12 +362,13 @@ help:
|
||||
@echo ' clean Delete all generated files'
|
||||
@echo ''
|
||||
@echo 'OPTIONS'
|
||||
@echo ' D=1 Build with debugging option "-Og"'
|
||||
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
|
||||
@echo ' G=1 Build with gcov to collect code coverage data'
|
||||
@echo ' V=1 Generate verbose build output'
|
||||
@echo ' W=1 Build with higher warning level'
|
||||
@echo ' ASAN=1 Build with address sanitizer'
|
||||
@echo ' D=1 Build with debugging option "-Og"'
|
||||
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
|
||||
@echo ' G=1 Build with gcov to collect code coverage data'
|
||||
@echo ' V=1 Generate verbose build output'
|
||||
@echo ' W=1 Build with higher warning level'
|
||||
@echo ' ASAN=1 Build with address sanitizer'
|
||||
@echo ' ENABLE_WERROR=1 Build with -Werror'
|
||||
@echo ''
|
||||
@echo 'EXAMPLES'
|
||||
@echo ' # make clean all D=1 W=1 -j'
|
||||
@@ -364,10 +439,6 @@ $(rootdir)/libzds/libzds.a: $(rootdir)/libzds
|
||||
$(MAKE) -C $(rootdir)/libzds/ libzds.a
|
||||
.PHONY: $(rootdir)/libzds
|
||||
|
||||
$(rootdir)/libvmdump/libvmdump.a: $(rootdir)/libvmdump
|
||||
$(MAKE) -C $(rootdir)/libvmdump/ libvmdump.a
|
||||
.PHONY: $(rootdir)/libvmdump
|
||||
|
||||
$(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
|
||||
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
|
||||
.PHONY: $(rootdir)/libvmcp
|
||||
@@ -396,8 +467,8 @@ $(rootdir)/libpv/libpv.a: $(rootdir)/libpv
|
||||
$(MAKE) -C $(rootdir)/libpv libpv.a
|
||||
.PHONY: $(rootdir)/libpv
|
||||
|
||||
$(rootdir)/zipl/boot/data.o:
|
||||
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
|
||||
$(rootdir)/zipl/boot/.loaders:
|
||||
$(MAKE) -C $(rootdir)/zipl/boot/ .loaders
|
||||
|
||||
install_dirs:
|
||||
for dir in $(INSTDIRS); do \
|
||||
@@ -422,4 +493,3 @@ clean_dep:
|
||||
|
||||
clean: clean_echo clean_gcov clean_dep
|
||||
endif
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ static void json_print_virtual_counter_answer(int s, int ctr,
|
||||
pai_str[paictr], space, paictr + 1);
|
||||
if (paistate < 0) {
|
||||
printf("\"error\":%d}", paistate);
|
||||
/* Protocol does not send furter counters. */
|
||||
/* Protocol does not send further counters. */
|
||||
return;
|
||||
}
|
||||
printf("\"value\":%"PRIu64"}", paivalue);
|
||||
@@ -420,7 +420,7 @@ static void json_print_answer(int s, int ctr, int state, uint64_t value)
|
||||
printf("\"value\":%"PRIu64"}", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int eprint(const char *format, ...)
|
||||
{
|
||||
|
||||
@@ -45,9 +45,8 @@ counter set authorization control" checkbox.
|
||||
- The daemon requires root privileges to interact with the performance
|
||||
ioctls of the kernel.
|
||||
|
||||
CPU hotplug is not recognized by the daemon. When adding or removing a CPU,
|
||||
restart the daemon to ensure correct summing of the per-CPU performance
|
||||
counters.
|
||||
CPU hotplug is recognized by the daemon. When adding or removing a CPU,
|
||||
the daemon ensures correct summing of the per-CPU performance counters.
|
||||
|
||||
The starting daemon first checks for any stale pid file
|
||||
\%/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
||||
|
||||
@@ -97,7 +97,7 @@ static int do_send_pai(int s, int user)
|
||||
{
|
||||
int ctr, state, i, maxctr, rc = 0;
|
||||
uint64_t value;
|
||||
|
||||
|
||||
if (user) {
|
||||
ctr = PAI_USER;
|
||||
maxctr = NUM_PAI_USER;
|
||||
@@ -252,20 +252,26 @@ static int do_print(int s, enum ctr_e ctr)
|
||||
}
|
||||
|
||||
|
||||
static int become_daemon(void)
|
||||
static int become_daemon(int *startup_pipe)
|
||||
{
|
||||
int child_initialized = 0, fd;
|
||||
int pipefds[2];
|
||||
FILE *f;
|
||||
int fd;
|
||||
|
||||
/* syslog */
|
||||
openlog("cpacfstatsd", 0, LOG_DAEMON);
|
||||
|
||||
if (pipe(pipefds) != 0) {
|
||||
eprint("pipe() failed, errno=%d [%s]\n", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* fork and terminate parent
|
||||
* Reasons:
|
||||
* - opens new command line prompt
|
||||
* - the child process is guaranteed not to be the process group leader
|
||||
* nessecarry for setsid.
|
||||
* necessary for setsid.
|
||||
*/
|
||||
|
||||
switch (fork()) {
|
||||
@@ -276,9 +282,23 @@ static int become_daemon(void)
|
||||
case 0: /* child */
|
||||
break;
|
||||
default: /* parent */
|
||||
(void)close(pipefds[1]);
|
||||
if (read(pipefds[0], &child_initialized, sizeof(child_initialized)) !=
|
||||
sizeof(child_initialized)) {
|
||||
eprint("Couldn't read from PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||
(void)close(pipefds[0]);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
(void)close(pipefds[0]);
|
||||
if (!child_initialized)
|
||||
_exit(EXIT_FAILURE);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/* Executed within the child context only */
|
||||
(void)close(pipefds[0]);
|
||||
*startup_pipe = pipefds[1];
|
||||
|
||||
if (chdir("/") != 0) {
|
||||
eprint("Chdir('/') failed, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
@@ -418,7 +438,7 @@ int eprint(const char *format, ...)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, sfd, foreground = 0;
|
||||
int rc, sfd, foreground = 0, startup_pipe = -1, initialized = 0;
|
||||
struct sigaction act;
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -454,27 +474,27 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (check_pidfile() != 0) {
|
||||
eprint("Stalled pid file or daemon allready running, terminating\n");
|
||||
eprint("Stalled pid file or daemon already running, terminating\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!foreground) {
|
||||
if (become_daemon() != 0) {
|
||||
if (become_daemon(&startup_pipe) != 0) {
|
||||
eprint("Couldn't daemonize\n");
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (perf_init() != 0) {
|
||||
eprint("Couldn't initialize perf lib\n");
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
atexit(perf_close);
|
||||
|
||||
sfd = open_socket(SERVER);
|
||||
if (sfd < 0) {
|
||||
eprint("Couldn't initialize server socket\n");
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
atexit(remove_sock);
|
||||
|
||||
@@ -484,17 +504,27 @@ int main(int argc, char *argv[])
|
||||
if (sigaction(SIGINT, &act, 0) != 0) {
|
||||
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
if (sigaction(SIGTERM, &act, 0) != 0) {
|
||||
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
eprint("Running\n");
|
||||
initialized = 1;
|
||||
/* `startup_pipe` has been initialized, so we know we are
|
||||
* running in daemon mode. Let's write to the pipe so that the
|
||||
* parent knows that the initialization is complete.
|
||||
*/
|
||||
if (startup_pipe != -1 &&
|
||||
write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||
goto error;
|
||||
(void)close(startup_pipe);
|
||||
startup_pipe = -1;
|
||||
|
||||
while (!stopsig) {
|
||||
enum ctr_e ctr;
|
||||
@@ -507,13 +537,14 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
eprint("Accept() failure, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = recv_query(s, &ctr, &cmd);
|
||||
if (rc != 0) {
|
||||
eprint("Recv_query() failed, ignoring\n");
|
||||
goto cleanup;
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmd == ENABLE)
|
||||
@@ -527,11 +558,9 @@ int main(int argc, char *argv[])
|
||||
else {
|
||||
eprint("Received unknown command %d, ignoring\n",
|
||||
(int) cmd);
|
||||
goto cleanup;
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
close(s);
|
||||
}
|
||||
|
||||
if (stopsig == SIGTERM)
|
||||
@@ -543,4 +572,14 @@ cleanup:
|
||||
remove_pidfile();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (startup_pipe != -1) {
|
||||
/* Notify the parent process that there was an error */
|
||||
if (write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||
eprint("Couldn't write to PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||
(void)close(startup_pipe);
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ static int addallcpus(void)
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
while (!feof(fp)) {
|
||||
/* scan all intervals of online cpus */
|
||||
scanned = fscanf(fp, "%u-%u", &start, &end);
|
||||
@@ -414,7 +414,7 @@ static void *hotplughandler(void *UNUSED(unused))
|
||||
struct udev *hotplug;
|
||||
struct udev_monitor *monitor;
|
||||
struct pollfd item;
|
||||
|
||||
|
||||
hotplug = udev_new();
|
||||
if (!hotplug) {
|
||||
eprint("Failed to create hotplug device\n");
|
||||
@@ -496,10 +496,8 @@ int perf_init(void)
|
||||
num -= 2;
|
||||
}
|
||||
|
||||
if (num == 0) {
|
||||
if (num == 0)
|
||||
eprint("No crypto counters supported!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (perf_load_counter_data())
|
||||
return -1;
|
||||
|
||||
@@ -276,9 +276,7 @@ static bool check_setpossible(void)
|
||||
if (!get_cpus(CPUS_KERNELMAX, cpubuf, sizeof(cpubuf)))
|
||||
return false;
|
||||
max_possible_cpus = getnumber(cpubuf, '\0') + 1;
|
||||
check = calloc(max_possible_cpus, sizeof(*check));
|
||||
if (!check)
|
||||
err(EXIT_FAILURE, "Maximum CPUs %u", max_possible_cpus);
|
||||
check = util_zalloc(max_possible_cpus * sizeof(*check));
|
||||
if (!get_cpus(CPUS_POSSIBLE, cpubuf, sizeof(cpubuf))) {
|
||||
free(check);
|
||||
return false;
|
||||
@@ -533,13 +531,8 @@ static int do_read(int ioctlfd)
|
||||
struct s390_hwctr_read *read;
|
||||
int rc;
|
||||
|
||||
if (!ioctlbuffer) {
|
||||
ioctlbuffer = malloc(ioctlbuffer_len);
|
||||
if (!ioctlbuffer) {
|
||||
warn("ioctl S390_HWCTR_START");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (!ioctlbuffer)
|
||||
ioctlbuffer = util_malloc(ioctlbuffer_len);
|
||||
read = (struct s390_hwctr_read *)ioctlbuffer;
|
||||
rc = ioctl(ioctlfd, S390_HWCTR_READ, read);
|
||||
if (!rc)
|
||||
|
||||
@@ -88,12 +88,6 @@ Include the MT_Diagnostic counter set.
|
||||
Include the problem counter set.
|
||||
.IP a
|
||||
Include all known counter sets (default).
|
||||
.SH "Concurrency with perf tool"
|
||||
The \*c tool and the linux
|
||||
.B perf
|
||||
tool use the same hardware and cannot be used concurrently.
|
||||
Both tools print an error message and abort when they
|
||||
detect this situation.
|
||||
.SH "EXAMPLES"
|
||||
The first example enables the basic and problem counter sets on CPU 0 and 1.
|
||||
Two read operations are performed and a summary line is printed for each
|
||||
|
||||
@@ -118,12 +118,17 @@ Specify the \fImode\fR to be used to format the device. Valid modes are:
|
||||
.IP full
|
||||
Format the entire disk with the specified blocksize. (default)
|
||||
.IP quick
|
||||
Format the first two tracks and write label and partition information. Only use
|
||||
this option if you are sure that the target DASD already contains a regular
|
||||
Format the first two tracks and write label and partition information. Use this
|
||||
option only if you are sure that the target DASD already contains a regular
|
||||
format with the specified blocksize. A blocksize can optionally be specified
|
||||
using \fB-b\fR (\fB--blocksize\fR).
|
||||
.br
|
||||
For thin-provisioned DASD ESE volumes this is the default mode.
|
||||
For thin-provisioned DASD ESE volumes, quick is the default mode. A full space
|
||||
release then precedes the formatting step. If this space release fails, dasdfmt
|
||||
falls back to a full-format mode. Formatting stops if the space release fails
|
||||
and quick mode was specified explicitly using \fB-M\fR. Specify the
|
||||
\fB--no-discard\fR option to omit the space release.
|
||||
|
||||
.IP expand
|
||||
Format all unformatted tracks at the end of the target DASD. This mode assumes
|
||||
that tracks at the beginning of the DASD volume have already been correctly
|
||||
|
||||
@@ -1230,7 +1230,7 @@ static void dasdfmt_find_start(unsigned int cylinders, unsigned int heads,
|
||||
format_params->start_unit = first;
|
||||
}
|
||||
|
||||
static void dasdfmt_release_space(void)
|
||||
static int dasdfmt_release_space(void)
|
||||
{
|
||||
format_data_t r = {
|
||||
.start_unit = 0,
|
||||
@@ -1240,12 +1240,21 @@ static void dasdfmt_release_space(void)
|
||||
int err = 0;
|
||||
|
||||
if (!g.ese || g.no_discard)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
printf("Releasing space for the entire device...\n");
|
||||
err = dasd_release_space(g.dev_node, &r);
|
||||
if (err)
|
||||
/*
|
||||
* Warn or Error on failing RAS depending on QUICK mode set explicitly or automatically
|
||||
*/
|
||||
if (err && !g.mode_specified) {
|
||||
warnx("Could not release space. Falling back to full format.");
|
||||
return 1;
|
||||
} else if (err && g.mode_specified) {
|
||||
error("Could not release space: %s", strerror(err));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dasdfmt_prepare_and_format(unsigned int cylinders, unsigned int heads,
|
||||
@@ -1445,8 +1454,12 @@ static void do_format_dasd(volume_label_t *vlabel, format_data_t *p,
|
||||
dasdfmt_prepare_and_format(cylinders, heads, p);
|
||||
break;
|
||||
case QUICK:
|
||||
dasdfmt_release_space();
|
||||
dasdfmt_quick_format(cylinders, heads, p);
|
||||
if (dasdfmt_release_space()) {
|
||||
p->stop_unit = (cylinders * heads) - 1;
|
||||
dasdfmt_prepare_and_format(cylinders, heads, p);
|
||||
} else {
|
||||
dasdfmt_quick_format(cylinders, heads, p);
|
||||
}
|
||||
break;
|
||||
case EXPAND:
|
||||
dasdfmt_expand_format(cylinders, heads, p);
|
||||
|
||||
@@ -16,13 +16,8 @@ check_dep:
|
||||
|
||||
BUILDTARGET = check_dep
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
|
||||
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
|
||||
else
|
||||
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
|
||||
CURL_LDLIBS = -lcurl
|
||||
endif # shell
|
||||
CURL_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||
CURL_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||
|
||||
endif # HAVE_CURL
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ all: all-recursive
|
||||
|
||||
install: all install-recursive
|
||||
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3a.bin "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 boot/stage3b_reloc.bin "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 samples/check_hostkeydoc "$(PKGDATADIR)"
|
||||
|
||||
clean: clean-recursive
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# Common definitions
|
||||
include ../../common.mak
|
||||
|
||||
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
||||
|
||||
ifeq ($(HOST_ARCH),s390x)
|
||||
ZIPL_DIR := $(rootdir)/zipl
|
||||
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
|
||||
PKGDATADIR := $(DESTDIR)$(TOOLS_DATADIR)/genprotimg
|
||||
|
||||
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
|
||||
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
||||
@@ -15,11 +19,9 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
|
||||
-fno-delete-null-pointer-checks -fno-stack-protector \
|
||||
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
||||
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
||||
-Wall -Wformat-security -Wextra -Werror \
|
||||
-Wall -Wformat-security -Wextra \
|
||||
-Wno-array-bounds
|
||||
|
||||
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
||||
|
||||
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
|
||||
ZIPL_SRCS_ASM := entry.S
|
||||
|
||||
@@ -27,9 +29,6 @@ ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o)
|
||||
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
|
||||
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
|
||||
|
||||
|
||||
all: $(FILES)
|
||||
|
||||
# Prevent make from using some default rules...
|
||||
%: %.S
|
||||
|
||||
@@ -69,29 +68,37 @@ endif
|
||||
|
||||
stage3b_reloc.o: stage3b.bin
|
||||
|
||||
stage3a.elf: head.o stage3a_init.o stage3a.o stage3a.lds $(ZIPL_OBJS)
|
||||
stage3b.elf: head.o stage3b.o stage3b.lds $(ZIPL_OBJS)
|
||||
stage3b_reloc.elf:
|
||||
stage3a.elf: head.o stage3a_init.o $(ZIPL_OBJS)
|
||||
stage3b.elf: head.o $(ZIPL_OBJS)
|
||||
|
||||
%.elf: %.o
|
||||
case $* in \
|
||||
stage3a) SFLAGS="-Wl,-T,stage3a.lds";; \
|
||||
stage3b) SFLAGS="-Wl,-T,stage3b.lds";; \
|
||||
stage3b_reloc) SFLAGS="-Wl,-estage3b_reloc_start,-Ttext,0";; \
|
||||
esac; \
|
||||
$(LINK) $$SFLAGS $(NO_PIE_LDFLAGS) -m64 -static -nostdlib $(filter %.o, $^) -o $@
|
||||
%.elf: %.lds %.o
|
||||
$(LINK) $(NO_PIE_LDFLAGS) $(NO_WARN_RWX_SEGMENTS_LDFLAGS) -Wl,-T,$< -Wl,--build-id=none -m64 -static -nostdlib $(filter %.o, $^) -o $@
|
||||
@chmod a-x $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary \
|
||||
--only-section=.text* \
|
||||
--only-section=.ex_table* \
|
||||
--only-section=.fixup* \
|
||||
--only-section=.data* \
|
||||
--only-section=.rodata* \
|
||||
$< $@
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
install: stage3a.bin stage3b_reloc.bin
|
||||
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3a.bin "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3b_reloc.bin "$(PKGDATADIR)"
|
||||
|
||||
else
|
||||
# Don't generate the dependency files (see `common.mak` for the
|
||||
# `-include $(dependencies_c)` statement).
|
||||
.PHONY: $(dependencies_c)
|
||||
|
||||
$(FILES):
|
||||
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||
|
||||
install:
|
||||
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||
endif
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
all: $(FILES)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.elf *.bin *.map .*.d *.lds
|
||||
|
||||
|
||||
@@ -29,3 +29,8 @@ _start:
|
||||
brasl %r14, initialize
|
||||
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
|
||||
.previous
|
||||
|
||||
/* The code doesn't require an executable stack */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "stage3a.h"
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/s390.h"
|
||||
#include "boot/ipl.h"
|
||||
#include "sclp.h"
|
||||
#include "error.h"
|
||||
|
||||
@@ -23,8 +23,6 @@ ENTRY(_init)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x0;
|
||||
|
||||
. = HEAP_ADDRESS;
|
||||
__heap_start = .;
|
||||
.heap : {
|
||||
@@ -46,7 +44,7 @@ SECTIONS
|
||||
. = STAGE3A_INIT_ENTRY;
|
||||
__text_init_start = .;
|
||||
.text : {
|
||||
stage3a_init.o(.text.init)
|
||||
*(.text.init)
|
||||
__text_init_stop = ABSOLUTE(.);
|
||||
/* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY',
|
||||
* otherwise the text data could be overwritten by the original zipl stage3
|
||||
@@ -56,8 +54,8 @@ SECTIONS
|
||||
. = 0x1000;
|
||||
ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY,
|
||||
"Text section doesn't conform to the described memory layout");
|
||||
head.o(.text.start)
|
||||
*(.text)
|
||||
*(.text.start)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
.ex_table ALIGN(16) : {
|
||||
@@ -74,7 +72,7 @@ SECTIONS
|
||||
|
||||
.rodata ALIGN(16) : {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
.data ALIGN(16) : {
|
||||
@@ -90,14 +88,10 @@ SECTIONS
|
||||
ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout");
|
||||
}
|
||||
|
||||
/* List this explicitly as otherwise .note.gnu.build-id will be
|
||||
* put at 0x0 */
|
||||
.notes : {
|
||||
*(.note.*)
|
||||
}
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,3 +26,8 @@ _init:
|
||||
br %r1
|
||||
.Lstage3a_entry: .long STAGE3A_ENTRY
|
||||
.previous
|
||||
|
||||
/* The code doesn't require an executable stack */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "stage3b.h"
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "boot/linux_layout.h"
|
||||
#include "boot/loaders_layout.h"
|
||||
#include "sclp.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
|
||||
/* Must not have any padding included */
|
||||
struct memblob {
|
||||
|
||||
@@ -21,8 +21,6 @@ ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x0;
|
||||
|
||||
. = HEAP_ADDRESS;
|
||||
__heap_start = .;
|
||||
.heap : {
|
||||
@@ -34,8 +32,8 @@ SECTIONS
|
||||
|
||||
. = STAGE3B_ENTRY;
|
||||
.text : {
|
||||
head.o(.text.start)
|
||||
*(.text)
|
||||
*(.text.start)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
.ex_table ALIGN(16) : {
|
||||
@@ -52,7 +50,7 @@ SECTIONS
|
||||
|
||||
.rodata ALIGN(16) : {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
.data ALIGN(16) : {
|
||||
@@ -74,14 +72,12 @@ SECTIONS
|
||||
}
|
||||
__stack_end = .;
|
||||
|
||||
/* List this explicitly as otherwise .note.gnu.build-id will be
|
||||
* put at 0x0 */
|
||||
.notes : {
|
||||
*(.note.*)
|
||||
}
|
||||
ASSERT(. <= IMAGE_ENTRY, "stage3b size must be smaller than 0x10000 bytes")
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
.org 0x0
|
||||
.section .text.start
|
||||
.globl stage3b_reloc_start
|
||||
stage3b_reloc_start:
|
||||
.globl _start
|
||||
_start:
|
||||
/* Might be called after a diag308 so better set
|
||||
* architecture and addressing mode
|
||||
*/
|
||||
@@ -53,3 +53,8 @@ stage3b_start:
|
||||
.incbin "stage3b.bin"
|
||||
stage3b_end:
|
||||
.previous
|
||||
|
||||
/* The code doesn't require an executable stack */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
19
genprotimg/boot/stage3b_reloc.lds.S
Normal file
19
genprotimg/boot/stage3b_reloc.lds.S
Normal file
@@ -0,0 +1,19 @@
|
||||
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
||||
OUTPUT_ARCH(s390:64-bit)
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*(.text.start)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ WARNINGS := -Wall -Wextra -Wshadow \
|
||||
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
|
||||
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
|
||||
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
||||
-Wpointer-arith -Werror -Wno-error=inline \
|
||||
-Wpointer-arith -Wno-error=inline \
|
||||
$(NULL)
|
||||
|
||||
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
|
||||
@@ -36,21 +36,12 @@ ALL_CPPFLAGS += $(INCLUDE_PARMS)
|
||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
||||
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
|
||||
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
||||
else
|
||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||
GLIB2_LIBS := -lglib-2.0
|
||||
LIBCRYPTO_CFLAGS :=
|
||||
LIBCRYPTO_LIBS := -lcrypto
|
||||
LIBCURL_CFLAGS :=
|
||||
LIBCURL_LIBS := -lcurl
|
||||
endif
|
||||
GLIB2_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||
LIBCURL_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||
|
||||
BUILD_TARGETS := skip-$(bin_PROGRAM)
|
||||
INSTALL_TARGETS := skip-$(bin_PROGRAM)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "boot/linux_layout.h"
|
||||
#include "boot/s390.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
static const gchar tool_name[] = "genprotimg";
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "lib/zt_common.h"
|
||||
#include "utils/crypto.h"
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "common.h"
|
||||
#include "utils/align.h"
|
||||
#include "utils/buffer.h"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "boot/stage3b.h"
|
||||
#include "common.h"
|
||||
#include "utils/align.h"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "boot/stage3b.h"
|
||||
#include "utils/buffer.h"
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "include/pv_crypto_def.h"
|
||||
#include "utils/buffer.h"
|
||||
#include "utils/crypto.h"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <glib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "include/pv_hdr_def.h"
|
||||
#include "utils/crypto.h"
|
||||
#include "utils/buffer.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "boot/stage3a.h"
|
||||
#include "common.h"
|
||||
#include "include/pv_crypto_def.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "utils/buffer.h"
|
||||
|
||||
#include "pv_args.h"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "boot/ipl.h"
|
||||
#include "boot/s390.h"
|
||||
#include "common.h"
|
||||
#include "include/pv_hdr_def.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/ipl.h"
|
||||
#include "boot/s390.h"
|
||||
#include "boot/stage3b.h"
|
||||
#include "utils/buffer.h"
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#ifndef PV_UTILS_ALIGN_H
|
||||
#define PV_UTILS_ALIGN_H
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/page.h"
|
||||
|
||||
#define IS_ALIGNED(addr, size) (!(addr & (size - 1)))
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/page.h"
|
||||
#include "common.h"
|
||||
#include "include/pv_crypto_def.h"
|
||||
#include "pv/pv_error.h"
|
||||
|
||||
@@ -19,13 +19,8 @@ check_dep:
|
||||
"fuse3-devel or libfuse3-dev", \
|
||||
"HAVE_FUSE=0")
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
||||
else
|
||||
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
|
||||
FUSE_LDLIBS = -lfuse3
|
||||
endif
|
||||
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||
ALL_CFLAGS += -DFUSE_USE_VERSION=30 -D_LARGEFILE_SOURCE $(FUSE_CFLAGS)
|
||||
LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
|
||||
|
||||
@@ -52,7 +47,7 @@ install-scripts: lshmc
|
||||
cat $$i | \
|
||||
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
>$(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
done
|
||||
|
||||
|
||||
@@ -22,26 +22,16 @@ else # HAVE_FUSE
|
||||
#
|
||||
# FUSE
|
||||
#
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
||||
else
|
||||
FUSE_CFLAGS = -I/usr/include/fuse3
|
||||
FUSE_LDLIBS = -lfuse3
|
||||
endif
|
||||
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||
|
||||
#
|
||||
# systemd
|
||||
#
|
||||
ifneq (${HAVE_SYSTEMD},0)
|
||||
ifeq ($(call check_header_prereq,"systemd/sd-daemon.h"),yes)
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
SYSTEMD_CFLAGS = $(shell pkg-config --silence-errors --cflags libsystemd)
|
||||
SYSTEMD_LDLIBS = $(shell pkg-config --silence-errors --libs libsystemd)
|
||||
else
|
||||
SYSTEMD_CFLAGS =
|
||||
SYSTEMD_LDLIBS = -lsystemd
|
||||
endif
|
||||
SYSTEMD_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libsystemd)
|
||||
SYSTEMD_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libsystemd)
|
||||
ALL_CPPFLAGS += -DHAVE_SYSTEMD
|
||||
else
|
||||
$(warning "systemd support disabled")
|
||||
|
||||
@@ -5,7 +5,7 @@ all:
|
||||
install: hsci
|
||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
|
||||
chown $(OWNER).$(GROUP) $(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 \
|
||||
|
||||
@@ -311,6 +311,7 @@ static struct sd_sys_item *l_sys_item_vec[] = {
|
||||
static struct sd_sys_item *l_sys_item_enable_vec[] = {
|
||||
&sd_sys_item_core_cnt,
|
||||
&sd_sys_item_core_diff,
|
||||
&sd_sys_item_thread_diff,
|
||||
&sd_sys_item_mgm_diff,
|
||||
&sd_sys_item_core,
|
||||
&sd_sys_item_mgm,
|
||||
@@ -339,6 +340,7 @@ static struct sd_cpu_item *l_cpu_item_vec[] = {
|
||||
static struct sd_cpu_item *l_cpu_item_enable_vec[] = {
|
||||
&sd_cpu_item_type,
|
||||
&sd_cpu_item_core_diff,
|
||||
&sd_cpu_item_thread_diff,
|
||||
&sd_cpu_item_mgm_diff,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -85,7 +85,8 @@ enum blkptr_format_id {
|
||||
* this is the "new" format which serves only List-Directed IPL,
|
||||
* but is also suitable for CCW-type IPL.
|
||||
*/
|
||||
BLKPTR_FORMAT_ID
|
||||
BLKPTR_FORMAT_ID,
|
||||
NR_BLKPTR_FORMATS
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -194,15 +195,25 @@ struct boot_info_bp_dump {
|
||||
uint8_t unused[16];
|
||||
} __packed;
|
||||
|
||||
/* This represents on-disk pointer to a block on disk */
|
||||
union disk_blockptr {
|
||||
struct eckd_blockptr_legacy eckd_legacy;
|
||||
struct eckd_blockptr eckd;
|
||||
struct linear_blockptr linear;
|
||||
};
|
||||
|
||||
struct boot_info_bp_ipl {
|
||||
union {
|
||||
struct eckd_blockptr_legacy eckd_legacy;
|
||||
struct eckd_blockptr eckd;
|
||||
struct linear_blockptr lin;
|
||||
} bm_ptr;
|
||||
union disk_blockptr bm_ptr;
|
||||
uint8_t unused[16];
|
||||
} __packed;
|
||||
|
||||
struct disk_program_table {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint64_t unused;
|
||||
union disk_blockptr component_table[0];
|
||||
} __packed;
|
||||
|
||||
struct boot_info {
|
||||
char magic[4];
|
||||
uint8_t version;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define IPL_H
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "s390.h"
|
||||
#include "page.h"
|
||||
|
||||
#define IPL_FLAG_SECURE 0x40
|
||||
|
||||
|
||||
@@ -14,12 +14,18 @@
|
||||
#include "lib/zt_common.h"
|
||||
#include "linux_layout.h"
|
||||
|
||||
#define STAGE0_LOAD_ADDRESS _AC(0x0, UL)
|
||||
|
||||
#define STAGE1_LOAD_ADDRESS _AC(0x18, UL)
|
||||
#define STAGE1B_LOAD_ADDRESS _AC(0xe000, UL)
|
||||
|
||||
#define STAGE2_DESC _AC(0x78, UL)
|
||||
#define STAGE2_ENTRY _AC(0x2018, UL)
|
||||
#define STAGE2_HEAP_ADDRESS _AC(0x6000, UL)
|
||||
#define STAGE2_HEAP_SIZE _AC(0x3000, UL)
|
||||
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
|
||||
#define STAGE2_STACK_SIZE _AC(0x1c00, UL)
|
||||
#define STAGE2_MAX_SIZE _AC(0x3000, UL)
|
||||
|
||||
#define STAGE3_ENTRY _AC(0xa000, UL)
|
||||
|
||||
|
||||
15
include/boot/page.h
Normal file
15
include/boot/page.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Page related definitions and functions.
|
||||
*
|
||||
* Copyright IBM Corp. 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef BOOT_PAGE_H
|
||||
#define BOOT_PAGE_H
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define PAGE_SIZE _AC(4096, UL)
|
||||
#endif
|
||||
31
include/boot/psw.h
Normal file
31
include/boot/psw.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Program Status Word related definitions and functions.
|
||||
*
|
||||
* Copyright IBM Corp. 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef BOOT_PSW_H
|
||||
#define BOOT_PSW_H
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
|
||||
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
|
||||
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
|
||||
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
|
||||
#define PSW_LOAD _AC(0x0008000080000000, UL)
|
||||
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
|
||||
struct psw_t {
|
||||
uint64_t mask;
|
||||
uint64_t addr;
|
||||
} __aligned(8);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* s390 related definitions and functions.
|
||||
* Should only be used for code targeting s390 (bootloader code)
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2020
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -12,29 +13,22 @@
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/sigp.h"
|
||||
#include "boot/psw.h"
|
||||
#include "boot/page.h"
|
||||
|
||||
#define __LC_IPLDEV 0x0c6c
|
||||
#define __LC_OS_INFO 0x0e18
|
||||
|
||||
#define LOWCORE_SIZE _AC(0x2000, UL)
|
||||
|
||||
#define PAGE_SIZE _AC(4096, UL)
|
||||
|
||||
/* Minimum size of a stack frame in bytes */
|
||||
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
||||
|
||||
/* Facilities */
|
||||
#define UNPACK_FACILITY _AC(161, U)
|
||||
|
||||
#define PSW32_ADDR_MASK _AC(0x000000007fffffff, UL)
|
||||
#define PSW_MASK_BA _AC(0x0000000080000000, UL)
|
||||
#define PSW_MASK_EA _AC(0x0000000100000000, UL)
|
||||
#define PSW_MASK_BIT_12 _AC(0x0008000000000000, UL)
|
||||
#define PSW_LOAD _AC(0x0008000080000000, UL)
|
||||
#define PSW_DISABLED_WAIT _AC(0x000a000000000000, UL)
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Helper macro for exception table entries
|
||||
@@ -46,18 +40,6 @@
|
||||
".long (" #_target ")\n" \
|
||||
".previous\n"
|
||||
|
||||
struct psw_t {
|
||||
uint64_t mask;
|
||||
uint64_t addr;
|
||||
} __aligned(8);
|
||||
|
||||
struct psw32_t {
|
||||
uint32_t mask;
|
||||
uint32_t addr;
|
||||
} __aligned(8);
|
||||
|
||||
void load_wait_psw(uint64_t, struct psw_t *);
|
||||
|
||||
struct subchannel_id {
|
||||
uint32_t cssid:8;
|
||||
uint32_t:4;
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56
|
||||
#endif
|
||||
|
||||
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56
|
||||
|
||||
#ifdef __G_LIB_H__
|
||||
#error "glib.h must be included via libpv/glib-helper.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "libpv/crypto.h"
|
||||
#include "libpv/macros.h"
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ clean:
|
||||
install: ip_watcher.pl xcec-bridge start_hsnc.sh
|
||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
< start_hsnc.sh >$(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||
chmod 755 $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ip_watcher.pl \
|
||||
$(DESTDIR)$(USRSBINDIR)
|
||||
|
||||
@@ -23,12 +23,15 @@
|
||||
#define BOOTPARMS_CCW_MAX 64
|
||||
#define BOOTPARMS_FCP_MAX 3452
|
||||
|
||||
#define OPT_BRCHR 0x80
|
||||
|
||||
enum target_type {
|
||||
TT_CCW,
|
||||
TT_FCP,
|
||||
TT_NSS,
|
||||
TT_NODE,
|
||||
TT_NVME,
|
||||
TT_ECKD,
|
||||
};
|
||||
|
||||
enum reipl_type {
|
||||
@@ -36,12 +39,14 @@ enum reipl_type {
|
||||
REIPL_CCW,
|
||||
REIPL_NSS,
|
||||
REIPL_NVME,
|
||||
REIPL_ECKD,
|
||||
};
|
||||
|
||||
static const char *const usage_chreipl =
|
||||
"Usage: %s [TARGET] [ARGS] [OPTIONS]\n"
|
||||
"\n"
|
||||
" chreipl [ccw] [-d] <DEVICE> [OPTIONS]\n"
|
||||
" chreipl [eckd] [-d] <DEVICE> [OPTIONS]\n"
|
||||
" chreipl [fcp] [-d] <DEVICE> [-w] <WWPN> [-l] <LUN> [OPTIONS]\n"
|
||||
" chreipl nvme [-i] <FID> [-s] <NSID> [OPTIONS]\n"
|
||||
" chreipl [node] <NODE|DIR> [OPTIONS]\n"
|
||||
@@ -50,6 +55,7 @@ static const char *const usage_chreipl =
|
||||
"\n"
|
||||
"The following re-IPL targets are supported:\n"
|
||||
" ccw IPL from CCW device\n"
|
||||
" eckd IPL from ECKD device\n"
|
||||
" fcp IPL from FCP device\n"
|
||||
" nvme IPL from NVME device\n"
|
||||
" nss IPL from NSS\n"
|
||||
@@ -66,6 +72,13 @@ static const char *const usage_chreipl =
|
||||
" -L, --loadparm <PARM> Loadparm specification\n"
|
||||
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
||||
"\n"
|
||||
"Options for eckd target:\n"
|
||||
" -d, --device <DEVICE> Device number of the ECKD IPL device\n"
|
||||
" -b, --bootprog <BPROG> Bootprog specification\n"
|
||||
" --brchr <C,H,R> Boot record location in Cylinder,Head,Record format\n"
|
||||
" -L, --loadparm <PARM> Loadparm specification\n"
|
||||
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
||||
"\n"
|
||||
"Options for fcp target:\n"
|
||||
" -d, --device <DEVICE> Device number of the adapter of the FCP IPL device\n"
|
||||
" -l --lun <LUN> Logical unit number of the FCP IPL device\n"
|
||||
@@ -114,6 +127,8 @@ static struct locals {
|
||||
int target_type_auto_mode;
|
||||
enum reipl_type reipl_type; /* CCW, FCP, NVME, NSS */
|
||||
int reipl_clear;
|
||||
char *brchr;
|
||||
int brchr_set;
|
||||
} l;
|
||||
|
||||
static void __noreturn print_usage_chreipl_exit(void)
|
||||
@@ -329,6 +344,19 @@ static void parse_ccw_args(char *nargv[], int nargc)
|
||||
set_device(nargv[0]);
|
||||
}
|
||||
|
||||
static void parse_eckd_args(char *nargv[], int nargc)
|
||||
{
|
||||
/*
|
||||
* we might be called like this:
|
||||
* chreipl eckd 4711
|
||||
*/
|
||||
if (l.busid_set)
|
||||
ERR_EXIT("Use either options or positional parameters");
|
||||
if (nargc > 1)
|
||||
ERR_EXIT("Too many arguments specified for \"eckd\" re-IPL type");
|
||||
set_device(nargv[0]);
|
||||
}
|
||||
|
||||
static void parse_nss_args(char *nargv[], int nargc)
|
||||
{
|
||||
/*
|
||||
@@ -369,6 +397,8 @@ static int set_reipl_type(const char *dev_name)
|
||||
l.reipl_type = REIPL_FCP;
|
||||
else if (strncmp(dev_name, "nvme", strlen("nvme")) == 0)
|
||||
l.reipl_type = REIPL_NVME;
|
||||
else if (strncmp(dev_name, "eckd", strlen("eckd")) == 0)
|
||||
l.reipl_type = REIPL_ECKD;
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -493,12 +523,15 @@ static void parse_pos_args(char *nargv[], int nargc)
|
||||
case TT_NODE:
|
||||
parse_node_args(nargv, nargc);
|
||||
break;
|
||||
case TT_ECKD:
|
||||
parse_eckd_args(nargv, nargc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_fcp_opts(void)
|
||||
{
|
||||
if (l.nss_name_set)
|
||||
if (l.nss_name_set || l.brchr_set)
|
||||
ERR_EXIT("Invalid option for \"fcp\" target specified");
|
||||
if (!(l.busid_set && l.wwpn_set && l.lun_set))
|
||||
ERR_EXIT("The \"fcp\" target requires device, WWPN, "
|
||||
@@ -507,7 +540,8 @@ static void check_fcp_opts(void)
|
||||
|
||||
static void check_nvme_opts(void)
|
||||
{
|
||||
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set)
|
||||
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set ||
|
||||
l.brchr_set)
|
||||
ERR_EXIT("Invalid option for \"nvme\" target specified");
|
||||
if (!(l.fid_set && l.nsid_set))
|
||||
ERR_EXIT("The \"nvme\" target requires FID, and optional NSID");
|
||||
@@ -515,16 +549,25 @@ static void check_nvme_opts(void)
|
||||
|
||||
static void check_ccw_opts(void)
|
||||
{
|
||||
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set)
|
||||
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set ||
|
||||
l.brchr_set)
|
||||
ERR_EXIT("Invalid option for \"ccw\" target specified");
|
||||
if (!l.busid_set)
|
||||
ERR_EXIT("The \"ccw\" target requires device");
|
||||
}
|
||||
|
||||
static void check_eckd_opts(void)
|
||||
{
|
||||
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.fid_set)
|
||||
ERR_EXIT("Invalid option for \"eckd\" target specified");
|
||||
if (!(l.busid_set))
|
||||
ERR_EXIT("The \"eckd\" target requires device");
|
||||
}
|
||||
|
||||
static void check_nss_opts(void)
|
||||
{
|
||||
if (l.bootprog_set || l.loadparm_set || l.busid_set || l.wwpn_set ||
|
||||
l.lun_set)
|
||||
l.lun_set || l.brchr_set)
|
||||
ERR_EXIT("Invalid option for \"nss\" target specified");
|
||||
if (!l.nss_name_set)
|
||||
ERR_EXIT("The \"nss\" target requires NSS name");
|
||||
@@ -563,6 +606,12 @@ static void set_reipl_clear(const char *arg)
|
||||
ERR_EXIT("re-IPL clear argument must be either 1 or 0");
|
||||
}
|
||||
|
||||
static void set_brchr(const char *arg)
|
||||
{
|
||||
l.brchr = strdup(arg);
|
||||
l.brchr_set = 1;
|
||||
}
|
||||
|
||||
static void parse_chreipl_options(int argc, char *argv[])
|
||||
{
|
||||
int opt, idx;
|
||||
@@ -580,6 +629,7 @@ static void parse_chreipl_options(int argc, char *argv[])
|
||||
{ "force", no_argument, NULL, 'f' },
|
||||
{ "version", no_argument, NULL, 'v' },
|
||||
{ "clear", required_argument, NULL, 'c' },
|
||||
{ "brchr", required_argument, NULL, OPT_BRCHR },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
static const char optstr[] = "hd:vw:l:fL:b:n:p:c:i:s:";
|
||||
@@ -592,6 +642,8 @@ static void parse_chreipl_options(int argc, char *argv[])
|
||||
set_target_type(TT_FCP, 0);
|
||||
else if (strcmp(argv[1], "ccw") == 0)
|
||||
set_target_type(TT_CCW, 0);
|
||||
else if (strcmp(argv[1], "eckd") == 0)
|
||||
set_target_type(TT_ECKD, 0);
|
||||
else if (strcmp(argv[1], "nss") == 0)
|
||||
set_target_type(TT_NSS, 0);
|
||||
else if (strcmp(argv[1], "nvme") == 0)
|
||||
@@ -640,6 +692,9 @@ static void parse_chreipl_options(int argc, char *argv[])
|
||||
case 'c':
|
||||
set_reipl_clear(optarg);
|
||||
break;
|
||||
case OPT_BRCHR:
|
||||
set_brchr(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
print_version_exit();
|
||||
default:
|
||||
@@ -737,6 +792,34 @@ static void chreipl_ccw(void)
|
||||
print_ccw(0);
|
||||
}
|
||||
|
||||
static void chreipl_eckd(void)
|
||||
{
|
||||
check_eckd_opts();
|
||||
|
||||
if (!ccw_is_device(l.busid) && !l.force_set) {
|
||||
if (is_ignored(l.busid))
|
||||
ERR_EXIT("Device is on cio_ignore list, try \"cio_ignore -r %s\"?",
|
||||
l.busid);
|
||||
ERR_EXIT("Could not find DASD ECKD device \"%s\"", l.busid);
|
||||
}
|
||||
|
||||
if (l.reipl_clear >= 0) {
|
||||
check_exists("reipl/eckd/clear", "ECKD re-IPL clear attribute");
|
||||
write_str(l.reipl_clear ? "1" : "0", "reipl/eckd/clear");
|
||||
}
|
||||
|
||||
if (!l.brchr_set)
|
||||
l.brchr = "auto";
|
||||
write_str(l.brchr, "reipl/eckd/br_chr");
|
||||
if (!l.bootprog_set)
|
||||
sprintf(l.bootprog, "0");
|
||||
write_str(l.bootprog, "reipl/eckd/bootprog");
|
||||
write_str(l.busid, "reipl/eckd/device");
|
||||
write_str_optional(l.loadparm, "reipl/eckd/loadparm", l.loadparm_set, "loadparm");
|
||||
write_str("eckd", "reipl/reipl_type");
|
||||
print_eckd(0, "eckd");
|
||||
}
|
||||
|
||||
static void chreipl_fcp(void)
|
||||
{
|
||||
check_fcp_opts();
|
||||
@@ -850,6 +933,11 @@ static void chreipl_node(void)
|
||||
l.busid_set = 1;
|
||||
chreipl_ccw();
|
||||
break;
|
||||
case REIPL_ECKD:
|
||||
ccw_busid_get(l.dev, l.busid);
|
||||
l.busid_set = 1;
|
||||
chreipl_eckd();
|
||||
break;
|
||||
case REIPL_FCP:
|
||||
fcp_wwpn_get(l.dev, l.wwpn);
|
||||
l.wwpn_set = 1;
|
||||
@@ -878,6 +966,9 @@ void cmd_chreipl(int argc, char *argv[])
|
||||
case TT_CCW:
|
||||
chreipl_ccw();
|
||||
break;
|
||||
case TT_ECKD:
|
||||
chreipl_eckd();
|
||||
break;
|
||||
case TT_FCP:
|
||||
chreipl_fcp();
|
||||
break;
|
||||
|
||||
@@ -141,6 +141,30 @@ void print_ccw(int show_ipl)
|
||||
print_fw_str("clear: %s\n", dir, "clear");
|
||||
}
|
||||
|
||||
void print_eckd(int show_ipl, const char *name)
|
||||
{
|
||||
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
|
||||
"/sys/firmware/reipl/eckd/loadparm";
|
||||
char *dir = show_ipl ? "ipl" : "reipl/eckd";
|
||||
char loadparm[9], loadparm_path[PATH_MAX];
|
||||
|
||||
printf("%-12s %s\n", get_ipl_banner(show_ipl), name);
|
||||
|
||||
print_fw_str("Device: %s\n", dir, "device");
|
||||
print_fw_str("bootprog: %s\n", dir, "bootprog");
|
||||
print_fw_str("br_chr: %s\n", dir, "br_chr");
|
||||
print_fw_str("Bootparm: \"%s\"\n", dir, "scp_data");
|
||||
if (access(path_loadparm, R_OK) == 0) {
|
||||
sprintf(loadparm_path, "%s/%s", dir, "loadparm");
|
||||
read_fw_str(loadparm, loadparm_path, sizeof(loadparm));
|
||||
if (strcmp(loadparm, " ") == 0)
|
||||
loadparm[0] = 0;
|
||||
printf("Loadparm: \"%s\"\n", loadparm);
|
||||
}
|
||||
if (!show_ipl)
|
||||
print_fw_str("clear: %s\n", dir, "clear");
|
||||
}
|
||||
|
||||
static void parse_lsreipl_options(int argc, char *argv[])
|
||||
{
|
||||
int opt, idx;
|
||||
@@ -193,6 +217,9 @@ void cmd_lsreipl(int argc, char *argv[])
|
||||
print_nvme(l.ipl_set, 1);
|
||||
else if (strcmp(reipl_type_str, "ccw") == 0)
|
||||
print_ccw(l.ipl_set);
|
||||
else if (strcmp(reipl_type_str, "eckd") == 0 ||
|
||||
strcmp(reipl_type_str, "eckd_dump") == 0)
|
||||
print_eckd(l.ipl_set, reipl_type_str);
|
||||
else if (strcmp(reipl_type_str, "nss") == 0)
|
||||
print_nss(l.ipl_set);
|
||||
else
|
||||
|
||||
@@ -45,6 +45,7 @@ extern void print_ccw(int show_ipl);
|
||||
extern void print_fcp(int show_ipl, int dump);
|
||||
extern void print_nvme(int show_ipl, int dump);
|
||||
extern void print_nss(int show_ipl);
|
||||
extern void print_eckd(int show_ipl, const char *name);
|
||||
|
||||
/*
|
||||
* Helper
|
||||
|
||||
@@ -36,6 +36,9 @@ The first argument specifies the re-IPL target:
|
||||
.RB "- " ccw :
|
||||
Specify a DASD CCW device for reboot
|
||||
.TP
|
||||
.RB "- " eckd :
|
||||
Specify a DASD ECKD device for reboot
|
||||
.TP
|
||||
.RB "- " fcp :
|
||||
Specify a FCP device for reboot
|
||||
.TP
|
||||
@@ -175,6 +178,63 @@ in the installed zIPL environment block for evaluation of zIPL environment
|
||||
variables in the kernel command line:
|
||||
|
||||
\fB# chreipl ccw -d 0.0.7e78 -L 1S2\fP
|
||||
|
||||
.SH eckd
|
||||
Use the eckd re-IPL target for DASD devices that are accessed by the hardware
|
||||
using channel command word (CCW) channels. In contrast to the ccw re-IPL target,
|
||||
the eckd target uses a list-directed bootloader that supports secure boot.
|
||||
.TP
|
||||
.BR "\-d" " or " "\-\-device"
|
||||
Specifies the device bus-ID of the DASD. If the bus-ID starts with "0.0." this
|
||||
prefix can be omitted and the four digit short notation can be used (e.g. 5000 is
|
||||
the same as 0.0.5000).
|
||||
|
||||
.TP
|
||||
.BR "\-b" " or " "\-\-bootprog"
|
||||
Specifies an entry in the ECKD boot configuration by defining the IPL boot
|
||||
program selector. If omitted, '0' is used.
|
||||
|
||||
.TP
|
||||
.BR "\-\-brchr"
|
||||
Specifies the block on the DASD where the boot record is located. If omitted,
|
||||
0 is used. The specification comprises comma-separated values for cylinder, head,
|
||||
and record: "--brchr C,H,R". Alternatively, specifying "0" or "auto" makes the
|
||||
bootloader determine the boot record location from the volume label.
|
||||
|
||||
.TP
|
||||
.BR "\-L" " or " "\-\-loadparm"
|
||||
The loadparm for the eckd re-IPL target is not used to control the ECKD boot
|
||||
configuration that is defined by the
|
||||
.BR zipl (8)
|
||||
boot menu. Instead it can be used to control higher level boot loaders
|
||||
like GRUB. For more details refer to distribution specific documentation.
|
||||
|
||||
.TP
|
||||
.BR "\-c" " or " "\-\-clear"
|
||||
Controls whether memory is 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/eckd/.
|
||||
|
||||
.PP
|
||||
\fBExamples:\fP
|
||||
.br
|
||||
|
||||
1. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and boot
|
||||
program selector 0:
|
||||
|
||||
\fB# chreipl eckd 0.0.7e78\fP
|
||||
|
||||
2. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and boot
|
||||
program selector 2:
|
||||
|
||||
\fB# chreipl eckd -d 0.0.7e78 -b 2\fP
|
||||
|
||||
3. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and tell
|
||||
the bootloader that the bootrecord is located in Cylinder 3, Head 0, Record 1:
|
||||
|
||||
\fB# chreipl eckd -d 0.0.7e78 --brchr 3,0,1\fP
|
||||
|
||||
.SH fcp
|
||||
Use the fcp re-IPL target for SCSI disks that are accessed by the hardware
|
||||
using Fibre Channel Protocol (FCP) channels.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
#
|
||||
# z/VM IUCV HVC device driver -- Edit z/VM user ID filter
|
||||
#
|
||||
|
||||
@@ -5,21 +5,12 @@ include ../common.mak
|
||||
|
||||
LIB := libpv.a
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto openssl)
|
||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto openssl)
|
||||
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
||||
else
|
||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||
GLIB2_LIBS := -lglib-2.0
|
||||
LIBCRYPTO_CFLAGS :=
|
||||
LIBCRYPTO_LIBS := -lcrypto -lssl
|
||||
LIBCURL_CFLAGS := -I/usr/include/s390x-linux-gnu
|
||||
LIBCURL_LIBS := -lcurl
|
||||
endif
|
||||
GLIB2_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||
LIBCURL_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
||||
|
||||
WARNINGS := -Wall -Wextra -Wshadow \
|
||||
@@ -28,7 +19,6 @@ WARNINGS := -Wall -Wextra -Wshadow \
|
||||
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
||||
-Wpointer-arith -Wno-error=inline \
|
||||
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
|
||||
-Werror \
|
||||
$(NULL)
|
||||
|
||||
ALL_CFLAGS += -std=gnu11 \
|
||||
|
||||
@@ -174,6 +174,20 @@ static OSSL_FUNC_keymgmt_settable_params_fn
|
||||
sk_prov_keymgmt_rsa_pss_settable_params;
|
||||
static OSSL_FUNC_keymgmt_settable_params_fn
|
||||
sk_prov_keymgmt_ec_settable_params;
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static OSSL_FUNC_keymgmt_export_types_ex_fn
|
||||
sk_prov_keymgmt_rsa_export_types_ex;
|
||||
static OSSL_FUNC_keymgmt_export_types_ex_fn
|
||||
sk_prov_keymgmt_rsa_pss_export_types_ex;
|
||||
static OSSL_FUNC_keymgmt_export_types_ex_fn
|
||||
sk_prov_keymgmt_ec_export_types_ex;
|
||||
static OSSL_FUNC_keymgmt_import_types_ex_fn
|
||||
sk_prov_keymgmt_rsa_import_types_ex;
|
||||
static OSSL_FUNC_keymgmt_import_types_ex_fn
|
||||
sk_prov_keymgmt_rsa_pss_import_types_ex;
|
||||
static OSSL_FUNC_keymgmt_import_types_ex_fn
|
||||
sk_prov_keymgmt_ec_import_types_ex;
|
||||
#else
|
||||
static OSSL_FUNC_keymgmt_export_types_fn
|
||||
sk_prov_keymgmt_rsa_export_types;
|
||||
static OSSL_FUNC_keymgmt_export_types_fn
|
||||
@@ -185,6 +199,7 @@ static OSSL_FUNC_keymgmt_import_types_fn
|
||||
static OSSL_FUNC_keymgmt_import_types_fn
|
||||
sk_prov_keymgmt_rsa_pss_import_types;
|
||||
static OSSL_FUNC_keymgmt_import_types_fn sk_prov_keymgmt_ec_import_types;
|
||||
#endif
|
||||
|
||||
static OSSL_FUNC_keyexch_newctx_fn sk_prov_keyexch_ec_newctx;
|
||||
static OSSL_FUNC_keyexch_dupctx_fn sk_prov_keyexch_ec_dupctx;
|
||||
@@ -552,6 +567,33 @@ static const OSSL_PARAM *sk_prov_cached_params_build(
|
||||
return provctx->cached_parms[index];
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
static bool sk_prov_check_uint_param(const OSSL_PARAM params[],
|
||||
const char *param_name,
|
||||
const struct sk_prov_key *key,
|
||||
int key_type,
|
||||
unsigned int expected_value)
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
unsigned int value;
|
||||
|
||||
if (key == NULL)
|
||||
return true;
|
||||
if (key->type != key_type)
|
||||
return true;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, param_name);
|
||||
if (p == NULL)
|
||||
return true;
|
||||
|
||||
if (OSSL_PARAM_get_uint(p, &value) != 1)
|
||||
return true;
|
||||
|
||||
return value == expected_value;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
static struct sk_prov_op_ctx *sk_prov_op_newctx(struct sk_prov_ctx *provctx,
|
||||
const char *propq,
|
||||
int type)
|
||||
@@ -850,6 +892,20 @@ static int sk_prov_asym_op_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
for (p = params; p != NULL && p->key != NULL; p++)
|
||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||
|
||||
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||
/* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION is for RSA decrypt only */
|
||||
if (!sk_prov_check_uint_param(params,
|
||||
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||
ctx->key, EVP_PKEY_RSA, 0) ||
|
||||
!sk_prov_check_uint_param(params,
|
||||
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||
ctx->key, EVP_PKEY_RSA_PSS, 0)) {
|
||||
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||
"Implicit rejection is not supported");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
default_set_params_fn = (OSSL_FUNC_asym_cipher_set_ctx_params_fn *)
|
||||
sk_prov_get_default_asym_func(ctx->provctx,
|
||||
ctx->type,
|
||||
@@ -1125,6 +1181,14 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
|
||||
struct sk_prov_op_ctx *ctx = vctx;
|
||||
struct sk_prov_key *key = vkey;
|
||||
const OSSL_PARAM *p;
|
||||
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||
unsigned int implicit_rejection = 0;
|
||||
OSSL_PARAM set_params[] = {
|
||||
OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||
&implicit_rejection),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
#endif
|
||||
|
||||
if (ctx == NULL || key == NULL)
|
||||
return 0;
|
||||
@@ -1133,6 +1197,20 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
|
||||
for (p = params; p != NULL && p->key != NULL; p++)
|
||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||
|
||||
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||
/* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION is for RSA decrypt only */
|
||||
if (!sk_prov_check_uint_param(params,
|
||||
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||
key, EVP_PKEY_RSA, 0) ||
|
||||
!sk_prov_check_uint_param(params,
|
||||
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
|
||||
key, EVP_PKEY_RSA_PSS, 0)) {
|
||||
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||
"Implicit rejection is not supported");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
default_decrypt_init_fn = (OSSL_FUNC_asym_cipher_decrypt_init_fn *)
|
||||
sk_prov_get_default_asym_func(ctx->provctx,
|
||||
ctx->type,
|
||||
@@ -1155,6 +1233,26 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
|
||||
if ((key->type == EVP_PKEY_RSA || key->type == EVP_PKEY_RSA_PSS) &&
|
||||
key->secure_key != NULL) {
|
||||
/*
|
||||
* By default, implicit rejection is enabled for the default
|
||||
* provider. We currently do not support implicit rejection with
|
||||
* secure keys, so disable implicit rejection in the default
|
||||
* provider operation context to report its status correctly
|
||||
* with get-params.
|
||||
*/
|
||||
implicit_rejection = 0;
|
||||
if (!sk_prov_asym_op_set_ctx_params(ctx, set_params)) {
|
||||
sk_debug_op_ctx(ctx,
|
||||
"ERROR: sk_prov_asym_op_set_ctx_params "
|
||||
"failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1361,6 +1459,16 @@ static int sk_prov_sign_op_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
for (p = params; p != NULL && p->key != NULL; p++)
|
||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||
|
||||
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
|
||||
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
|
||||
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
|
||||
ctx->key, EVP_PKEY_EC, 0)) {
|
||||
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||
"Deterministic signature is not supported");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
default_set_params_fn = (OSSL_FUNC_signature_set_ctx_params_fn *)
|
||||
sk_prov_get_default_sign_func(ctx->provctx,
|
||||
ctx->type, OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS);
|
||||
@@ -1701,6 +1809,11 @@ static int sk_prov_sign_op_get_pss_saltlen(struct sk_prov_op_ctx *ctx,
|
||||
salt_len = max_saltlen;
|
||||
else if (strcmp(saltlen, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
|
||||
salt_len = max_saltlen;
|
||||
#ifdef OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX
|
||||
else if (strcmp(saltlen,
|
||||
OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
|
||||
salt_len = MIN(max_saltlen, EVP_MD_size(mgf_md));
|
||||
#endif
|
||||
else
|
||||
salt_len = atoi(saltlen);
|
||||
|
||||
@@ -1729,6 +1842,16 @@ static int sk_prov_sign_op_sign_init(void *vctx, void *vkey,
|
||||
for (p = params; p != NULL && p->key != NULL; p++)
|
||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||
|
||||
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
|
||||
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
|
||||
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
|
||||
key, EVP_PKEY_EC, 0)) {
|
||||
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||
"Deterministic signature is not supported");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
default_sign_init_fn = (OSSL_FUNC_signature_sign_init_fn *)
|
||||
sk_prov_get_default_sign_func(ctx->provctx,
|
||||
ctx->type,
|
||||
@@ -1955,6 +2078,16 @@ static int sk_prov_sign_op_digest_sign_init(struct sk_prov_op_ctx *ctx,
|
||||
for (p = params; p != NULL && p->key != NULL; p++)
|
||||
sk_debug_op_ctx(ctx, "param: %s", p->key);
|
||||
|
||||
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
|
||||
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
|
||||
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
|
||||
key, EVP_PKEY_EC, 0)) {
|
||||
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
|
||||
"Deterministic signature is not supported");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
default_digest_sign_init_fn =
|
||||
(OSSL_FUNC_signature_digest_sign_init_fn *)
|
||||
sk_prov_get_default_sign_func(ctx->provctx,
|
||||
@@ -2829,14 +2962,14 @@ static const OSSL_PARAM sk_prov_imexport_types[] = {
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
|
||||
int pkey_type)
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_export_types(
|
||||
struct sk_prov_ctx *provctx,
|
||||
int selection,
|
||||
int pkey_type)
|
||||
{
|
||||
OSSL_FUNC_keymgmt_export_types_fn *default_export_types_fn;
|
||||
const OSSL_PARAM *default_parms = NULL, *params;
|
||||
struct sk_prov_ctx *provctx;
|
||||
|
||||
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
if (provctx == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -2864,14 +2997,14 @@ static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
|
||||
sk_prov_imexport_types);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_import_types(int selection,
|
||||
int pkey_type)
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_import_types(
|
||||
struct sk_prov_ctx *provctx,
|
||||
int selection,
|
||||
int pkey_type)
|
||||
{
|
||||
OSSL_FUNC_keymgmt_import_types_fn *default_import_types_fn;
|
||||
const OSSL_PARAM *default_parms = NULL, *params;
|
||||
struct sk_prov_ctx *provctx;
|
||||
|
||||
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
if (provctx == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -3219,15 +3352,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_settable_params(void *vprovctx)
|
||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA);
|
||||
}
|
||||
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
#else
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *sk_prov_keymgmt_rsa_gen_init(void *vprovctx, int selection,
|
||||
const OSSL_PARAM params[])
|
||||
@@ -3289,15 +3446,43 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_settable_params(void *vprovctx)
|
||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
#else
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA_PSS);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA_PSS);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *sk_prov_keymgmt_rsa_pss_gen_init(void *vprovctx, int selection,
|
||||
const OSSL_PARAM params[])
|
||||
@@ -3372,15 +3557,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_ec_settable_params(void *vprovctx)
|
||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_EC);
|
||||
}
|
||||
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
#else
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_EC);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_EC);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *sk_prov_keymgmt_ec_gen_init(void *vprovctx, int selection,
|
||||
const OSSL_PARAM params[])
|
||||
@@ -4530,11 +4739,21 @@ static const OSSL_DISPATCH sk_prov_rsa_keymgmt_functions[] = {
|
||||
|
||||
/* Import and export routines */
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_export_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_export_types },
|
||||
#endif
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_import_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_import_types },
|
||||
#endif
|
||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||
|
||||
{ 0, NULL }
|
||||
@@ -4579,11 +4798,21 @@ static const OSSL_DISPATCH sk_prov_rsapss_keymgmt_functions[] = {
|
||||
|
||||
/* Import and export routines */
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types },
|
||||
#endif
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types },
|
||||
#endif
|
||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||
|
||||
{ 0, NULL }
|
||||
@@ -4628,11 +4857,21 @@ static const OSSL_DISPATCH sk_prov_ec_keymgmt_functions[] = {
|
||||
|
||||
/* Import and export routines */
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_export_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_export_types },
|
||||
#endif
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_import_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_import_types },
|
||||
#endif
|
||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||
|
||||
{ 0, NULL }
|
||||
|
||||
@@ -776,6 +776,10 @@ int SK_UTIL_build_ecdsa_signature(const unsigned char *raw_sig,
|
||||
bn_s = NULL;
|
||||
|
||||
der_len = i2d_ECDSA_SIG(ec_sig, NULL);
|
||||
if (der_len <= 0) {
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sig == NULL) {
|
||||
*sig_len = der_len;
|
||||
@@ -788,13 +792,14 @@ int SK_UTIL_build_ecdsa_signature(const unsigned char *raw_sig,
|
||||
|
||||
memset(sig, 0, *sig_len);
|
||||
der = sig;
|
||||
*sig_len = i2d_ECDSA_SIG(ec_sig, &der);
|
||||
|
||||
if (*sig_len == 0) {
|
||||
der_len = i2d_ECDSA_SIG(ec_sig, &der);
|
||||
if (der_len <= 0) {
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*sig_len = der_len;
|
||||
|
||||
out:
|
||||
if (ec_sig != NULL)
|
||||
ECDSA_SIG_free(ec_sig);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
include ../common.mak
|
||||
|
||||
lib = libvmdump.a
|
||||
|
||||
all: $(lib)
|
||||
|
||||
objects = register_content.o dump.o lkcd_dump.o register_content.o \
|
||||
vmdump_convert.o vm_dump.o
|
||||
|
||||
$(lib): $(objects)
|
||||
|
||||
install: all
|
||||
|
||||
clean:
|
||||
rm -f *.o $(lib)
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Dump base class
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 "dump.h"
|
||||
|
||||
int debug = 0;
|
||||
|
||||
void s390TodToTimeval(uint64_t todval, struct timeval *xtime)
|
||||
{
|
||||
/* adjust todclock to 1970 */
|
||||
todval -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
|
||||
|
||||
todval >>= 12;
|
||||
xtime->tv_sec = todval / 1000000;
|
||||
xtime->tv_usec = todval % 1000000;
|
||||
}
|
||||
|
||||
Dump::Dump(const char *filename, const char *mode)
|
||||
{
|
||||
fh = fopen(filename, mode);
|
||||
if(!fh){
|
||||
throw(DumpErrnoException("Open dump file failed!"));
|
||||
}
|
||||
}
|
||||
|
||||
Dump::~Dump(void)
|
||||
{
|
||||
if(fh){
|
||||
fclose(fh);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressBar::initProgress(void)
|
||||
{
|
||||
progressPercentage = -1;
|
||||
}
|
||||
|
||||
void ProgressBar::displayProgress(uint64_t value, uint64_t maxValue)
|
||||
{
|
||||
char progress_bar[51];
|
||||
int j;
|
||||
|
||||
if (progressPercentage == (int) (value * 100 / maxValue))
|
||||
fprintf(stderr, "%6lld of %6lld |\r",
|
||||
(long long) value, (long long) maxValue);
|
||||
else { /* percent value has changed */
|
||||
progressPercentage = (value * 100 / maxValue);
|
||||
for (j = 0; j < progressPercentage / 2; j++)
|
||||
progress_bar[j] = '#';
|
||||
for (j = progressPercentage / 2; j < 50; j++)
|
||||
progress_bar[j] = '-';
|
||||
progress_bar[50] = 0;
|
||||
fprintf(stderr, "%6lld of %6lld |%s| %3d%% \r",
|
||||
(long long) value, (long long) maxValue,
|
||||
progress_bar, progressPercentage);
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Dump base class
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 DUMP_H
|
||||
#define DUMP_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
extern int debug;
|
||||
|
||||
class DumpException
|
||||
{
|
||||
public:
|
||||
DumpException(void) {
|
||||
msg[0] = 0;
|
||||
errorCode = 0;
|
||||
}
|
||||
DumpException(const char *m) {
|
||||
sprintf(msg, "%s", m);
|
||||
errorCode = 0;
|
||||
}
|
||||
|
||||
const char *what(void) const { return msg; }
|
||||
int code(void) const { return errorCode; }
|
||||
protected:
|
||||
char msg[2048];
|
||||
int errorCode;
|
||||
};
|
||||
|
||||
class DumpErrnoException : public DumpException
|
||||
{
|
||||
public:
|
||||
DumpErrnoException(const char *m) {
|
||||
sprintf(msg, "%s (%s)", m, strerror(errno));
|
||||
errorCode = errno;
|
||||
}
|
||||
};
|
||||
|
||||
class Dump
|
||||
{
|
||||
public:
|
||||
Dump(const char *filename, const char *mode);
|
||||
Dump(void) : fh(0) {}
|
||||
virtual ~Dump(void);
|
||||
typedef enum {DT_VM32, DT_VM64, DT_VM64_BIG, DT_LKCD32, DT_LKCD64,
|
||||
DT_UNKNOWN} DumpType;
|
||||
|
||||
virtual void readMem(char *buf, int size) = 0;
|
||||
virtual int seekMem(uint64_t offset) = 0;
|
||||
virtual uint64_t getMemSize(void) const = 0;
|
||||
virtual struct timeval getDumpTime(void) const = 0;
|
||||
protected:
|
||||
FILE *fh;
|
||||
};
|
||||
|
||||
class ProgressBar
|
||||
{
|
||||
public:
|
||||
ProgressBar(void) { progressPercentage = -1; }
|
||||
void initProgress(void);
|
||||
void displayProgress(uint64_t value, uint64_t maxValue);
|
||||
private:
|
||||
int progressPercentage;
|
||||
};
|
||||
|
||||
void s390TodToTimeval(uint64_t todval, struct timeval *xtime);
|
||||
int vm_convert(const char *inputFileName, const char *outputFileName,
|
||||
const char *progName);
|
||||
|
||||
static inline void dump_read(void *ptr, size_t size, size_t nmemb,
|
||||
FILE *stream)
|
||||
{
|
||||
if (fread(ptr, size, nmemb, stream) != nmemb)
|
||||
throw(DumpErrnoException("fread failed"));
|
||||
}
|
||||
|
||||
static inline void dump_seek(FILE *stream, long offset, int whence)
|
||||
{
|
||||
if (fseek(stream, offset, whence) == -1)
|
||||
throw(DumpErrnoException("fseek failed"));
|
||||
}
|
||||
|
||||
#endif /* DUMP_H */
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* LKCD dump classes: LKCDDump, LKCDDump32, LKCDDump64
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "lkcd_dump.h"
|
||||
|
||||
LKCDDump::LKCDDump(Dump* dump, const char* arch) {
|
||||
referenceDump = dump;
|
||||
dumpHeader.magic_number = DUMP_MAGIC_NUMBER;
|
||||
dumpHeader.version = DUMP_VERSION_NUMBER;
|
||||
dumpHeader.header_size = sizeof(struct _lkcd_dump_header);
|
||||
dumpHeader.time.tv_sec = dump->getDumpTime().tv_sec;
|
||||
dumpHeader.time.tv_usec = dump->getDumpTime().tv_usec;
|
||||
strcpy(dumpHeader.utsname_machine, arch);
|
||||
dumpHeader.memory_size = dump->getMemSize();
|
||||
dumpHeader.memory_start = 0;
|
||||
dumpHeader.memory_end = dump->getMemSize();
|
||||
dumpHeader.num_dump_pages = dump->getMemSize()/0x1000;
|
||||
dumpHeader.page_size = 0x1000;
|
||||
dumpHeader.dump_compress = DUMP_COMPRESS_GZIP;
|
||||
dumpHeader.dump_level = DUMP_LEVEL_ALL;
|
||||
|
||||
dumpHeaderAsm.magic_number = DUMP_ASM_MAGIC_NUMBER;
|
||||
dumpHeaderAsm.version = 1;
|
||||
dumpHeaderAsm.header_size = sizeof(dumpHeaderAsm);
|
||||
}
|
||||
|
||||
int LKCDDump::compressGZIP(const char *old, uint32_t old_size, char *n,
|
||||
uint32_t new_size)
|
||||
{
|
||||
unsigned long len = old_size;
|
||||
int rc;
|
||||
|
||||
rc = compress((Bytef*)n, &len, (const Bytef*)old, new_size);
|
||||
switch(rc) {
|
||||
case Z_OK:
|
||||
rc = len;
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
/* In this case the compressed output is bigger than */
|
||||
/* the uncompressed */
|
||||
rc = GZIP_NOT_COMPRESSED;
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
throw(DumpException("gzip call failed: out of memory"));
|
||||
case Z_DATA_ERROR:
|
||||
throw(DumpException("gzip call failed: input data " \
|
||||
"corrupted!"));
|
||||
default:
|
||||
throw(DumpException("gzip call failed: unknown error"));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void LKCDDump::writeDump(const char* fileName)
|
||||
{
|
||||
char dump_header_buf[DUMP_HEADER_SIZE] = {};
|
||||
char dump_page_buf[DUMP_BUFFER_SIZE];
|
||||
char dpcpage[DUMP_PAGE_SIZE];
|
||||
uint32_t dp_size,dp_flags;
|
||||
ProgressBar progressBar;
|
||||
char buf[DUMP_PAGE_SIZE];
|
||||
struct _dump_page dp;
|
||||
uint64_t mem_loc = 0;
|
||||
ssize_t buf_loc = 0;
|
||||
int size, fd;
|
||||
|
||||
if (fileName == NULL) {
|
||||
fd = STDOUT_FILENO;
|
||||
} else {
|
||||
fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR);
|
||||
if (fd == -1) {
|
||||
char msg[1024];
|
||||
sprintf(msg, "Open of dump '%s' failed.", fileName);
|
||||
throw(DumpErrnoException(msg));
|
||||
}
|
||||
}
|
||||
|
||||
/* write dump header */
|
||||
|
||||
memcpy(dump_header_buf, &dumpHeader, sizeof(dumpHeader));
|
||||
memcpy(&dump_header_buf[sizeof(dumpHeader)], &dumpHeaderAsm,
|
||||
sizeof(dumpHeaderAsm));
|
||||
if (write(fd, dump_header_buf, sizeof(dump_header_buf)) !=
|
||||
sizeof(dump_header_buf)) {
|
||||
throw(DumpErrnoException("write failed"));
|
||||
}
|
||||
|
||||
/* write memory */
|
||||
|
||||
referenceDump->seekMem(0);
|
||||
|
||||
while (mem_loc < dumpHeader.memory_size) {
|
||||
referenceDump->readMem(buf, DUMP_PAGE_SIZE);
|
||||
copyRegsToPage(mem_loc,buf);
|
||||
|
||||
memset(dpcpage, 0, DUMP_PAGE_SIZE);
|
||||
/*
|
||||
* Get the new compressed page size
|
||||
*/
|
||||
size = compressGZIP((char *)buf, DUMP_PAGE_SIZE,
|
||||
(char *)dpcpage, DUMP_PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* If compression failed or compressed was ineffective,
|
||||
* we write an uncompressed page
|
||||
*/
|
||||
if (size == GZIP_NOT_COMPRESSED) {
|
||||
dp_flags = DUMP_DH_RAW;
|
||||
dp_size = DUMP_PAGE_SIZE;
|
||||
} else {
|
||||
dp_flags = DUMP_DH_COMPRESSED;
|
||||
dp_size = size;
|
||||
}
|
||||
dp.address = mem_loc;
|
||||
dp.size = dp_size;
|
||||
dp.flags = dp_flags;
|
||||
memcpy((void *)(dump_page_buf + buf_loc),
|
||||
(const void *)&dp, sizeof(dp));
|
||||
buf_loc += sizeof(dp);
|
||||
/*
|
||||
* Copy the page of memory
|
||||
*/
|
||||
if (dp_flags & DUMP_DH_COMPRESSED) {
|
||||
/* Copy the compressed page */
|
||||
memcpy((void *)(dump_page_buf + buf_loc),
|
||||
(const void *)dpcpage, dp_size);
|
||||
} else {
|
||||
/* Copy directly from memory */
|
||||
memcpy((void *)(dump_page_buf + buf_loc),
|
||||
(const void *)buf, dp_size);
|
||||
}
|
||||
buf_loc += dp_size;
|
||||
if(write(fd, dump_page_buf, buf_loc) != buf_loc){
|
||||
throw(DumpErrnoException("write failed"));
|
||||
}
|
||||
buf_loc = 0;
|
||||
mem_loc += DUMP_PAGE_SIZE;
|
||||
progressBar.displayProgress(mem_loc/(1024*1024),
|
||||
dumpHeader.memory_size/(1024*1024));
|
||||
}
|
||||
|
||||
/*
|
||||
* Write end marker
|
||||
*/
|
||||
dp.address = 0x0;
|
||||
dp.size = 0x0;
|
||||
dp.flags = DUMP_DH_END;
|
||||
if(write(fd, &dp, sizeof(dp)) != sizeof(dp)){
|
||||
throw(DumpErrnoException("write failed"));
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
if (fd != STDOUT_FILENO)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
struct timeval LKCDDump::getDumpTime(void) const
|
||||
{
|
||||
struct timeval rc;
|
||||
|
||||
rc.tv_sec = dumpHeader.time.tv_sec;
|
||||
rc.tv_usec = dumpHeader.time.tv_usec;
|
||||
return rc;
|
||||
}
|
||||
|
||||
LKCDDump32::LKCDDump32(Dump* dump, const RegisterContent32& r)
|
||||
: LKCDDump(dump,"s390")
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
dumpHeaderAsm.real_cpu_cnt = (uint32_t) r.getNumCpus();
|
||||
for (i = 0; i < dumpHeaderAsm.real_cpu_cnt; i++) {
|
||||
if (!r.regSets[i].prefix)
|
||||
continue;
|
||||
dumpHeaderAsm.lc_vec[i] = r.regSets[i].prefix;
|
||||
dumpHeaderAsm.cpu_cnt++;
|
||||
}
|
||||
registerContent = r;
|
||||
}
|
||||
|
||||
void LKCDDump32::copyRegsToPage(uint64_t offset, char *buf)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
|
||||
if(offset == registerContent.regSets[cpu].prefix){
|
||||
memcpy(buf+0xd8,®isterContent.regSets[cpu].cpuTimer,
|
||||
sizeof(registerContent.regSets[cpu].cpuTimer));
|
||||
memcpy(buf+0xe0,®isterContent.regSets[cpu].clkCmp,
|
||||
sizeof(registerContent.regSets[cpu].clkCmp));
|
||||
memcpy(buf+0x100,®isterContent.regSets[cpu].psw,
|
||||
sizeof(registerContent.regSets[cpu].psw));
|
||||
memcpy(buf+0x108,®isterContent.regSets[cpu].prefix,
|
||||
sizeof(registerContent.regSets[cpu].prefix));
|
||||
memcpy(buf+0x120,®isterContent.regSets[cpu].acrs,
|
||||
sizeof(registerContent.regSets[cpu].acrs));
|
||||
memcpy(buf+0x160,®isterContent.regSets[cpu].fprs,
|
||||
sizeof(registerContent.regSets[cpu].fprs));
|
||||
memcpy(buf+0x180,®isterContent.regSets[cpu].gprs,
|
||||
sizeof(registerContent.regSets[cpu].gprs));
|
||||
memcpy(buf+0x1c0,®isterContent.regSets[cpu].crs,
|
||||
sizeof(registerContent.regSets[cpu].crs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LKCDDump64::LKCDDump64(Dump* dump, const RegisterContent64& r)
|
||||
: LKCDDump(dump,"s390x")
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
dumpHeaderAsm.real_cpu_cnt = (uint32_t) r.getNumCpus();
|
||||
for (i = 0; i < dumpHeaderAsm.real_cpu_cnt; i++) {
|
||||
if (!r.regSets[i].prefix)
|
||||
continue;
|
||||
dumpHeaderAsm.lc_vec[i] = r.regSets[i].prefix;
|
||||
dumpHeaderAsm.cpu_cnt++;
|
||||
}
|
||||
registerContent = r;
|
||||
}
|
||||
|
||||
void LKCDDump64::copyRegsToPage(uint64_t offset, char *buf)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
|
||||
if(offset == (registerContent.regSets[cpu].prefix + 0x1000)){
|
||||
memcpy(buf+0x328,®isterContent.regSets[cpu].cpuTimer,
|
||||
sizeof(registerContent.regSets[cpu].cpuTimer));
|
||||
memcpy(buf+0x330,®isterContent.regSets[cpu].clkCmp,
|
||||
sizeof(registerContent.regSets[cpu].clkCmp));
|
||||
memcpy(buf+0x300,®isterContent.regSets[cpu].psw,
|
||||
sizeof(registerContent.regSets[cpu].psw));
|
||||
memcpy(buf+0x318,®isterContent.regSets[cpu].prefix,
|
||||
sizeof(registerContent.regSets[cpu].prefix));
|
||||
memcpy(buf+0x340,®isterContent.regSets[cpu].acrs,
|
||||
sizeof(registerContent.regSets[cpu].acrs));
|
||||
memcpy(buf+0x200,®isterContent.regSets[cpu].fprs,
|
||||
sizeof(registerContent.regSets[cpu].fprs));
|
||||
memcpy(buf+0x280,®isterContent.regSets[cpu].gprs,
|
||||
sizeof(registerContent.regSets[cpu].gprs));
|
||||
memcpy(buf+0x380,®isterContent.regSets[cpu].crs,
|
||||
sizeof(registerContent.regSets[cpu].crs));
|
||||
memcpy(buf+0x31c,®isterContent.regSets[cpu].fpCr,
|
||||
sizeof(registerContent.regSets[cpu].fpCr));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* LKCD dump classes: LKCDDump, LKCDDump32, LKCDDump64
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 LKCD_DUMP_H
|
||||
#define LKCD_DUMP_H
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "dump.h"
|
||||
#include "register_content.h"
|
||||
|
||||
#define UTS_LEN 65
|
||||
#define DUMP_BUFFER_SIZE 0x2000 /* Size of dump buffer */
|
||||
|
||||
/* Standard header definitions */
|
||||
#define DUMP_HEADER_SIZE 0x10000
|
||||
#define DUMP_MAGIC_NUMBER 0xa8190173618f23edULL /* Dump magic number */
|
||||
#define DUMP_ASM_MAGIC_NUMBER 0x733339302d64756dULL /* asm magic number */
|
||||
#define DUMP_VERSION_NUMBER 0x8 /* Dump version number */
|
||||
#define DUMP_PANIC_LEN 0x100 /* Dump panic string length */
|
||||
|
||||
/* Dump levels - type specific stuff added later */
|
||||
#define DUMP_LEVEL_ALL 0x10 /* Dump all memory RAM and firmware */
|
||||
|
||||
/* Dump compression options */
|
||||
#define DUMP_COMPRESS_GZIP 0x2 /* Use GZIP compression */
|
||||
|
||||
/* Dump header flags */
|
||||
#define DUMP_DH_RAW 0x1 /* Raw page (no compression) */
|
||||
#define DUMP_DH_COMPRESSED 0x2 /* Page is compressed */
|
||||
#define DUMP_DH_END 0x4 /* End marker on a full dump */
|
||||
|
||||
/* Dump page defines */
|
||||
#define DUMP_PAGE_SHIFT 12ULL
|
||||
#define DUMP_PAGE_SIZE (1ULL << DUMP_PAGE_SHIFT)
|
||||
|
||||
#define GZIP_NOT_COMPRESSED -1
|
||||
|
||||
class LKCDDump : public Dump
|
||||
{
|
||||
public:
|
||||
LKCDDump(Dump*, const char *);
|
||||
virtual ~LKCDDump(void) {}
|
||||
inline virtual void readMem(char *UNUSED(buf), int UNUSED(size))
|
||||
{
|
||||
throw(DumpException("LKCDDump::readMem() not implemented!"));
|
||||
}
|
||||
inline int seekMem(uint64_t UNUSED(offset))
|
||||
{
|
||||
throw(DumpException("LKCDDump::seekMem() not implemented!"));
|
||||
}
|
||||
inline virtual uint64_t getMemSize() const
|
||||
{
|
||||
return dumpHeader.memory_size;
|
||||
}
|
||||
virtual struct timeval getDumpTime(void) const;
|
||||
virtual void writeDump(const char *fileName);
|
||||
virtual void copyRegsToPage(uint64_t offset, char *buf) = 0;
|
||||
protected:
|
||||
struct _lkcd_dump_header {
|
||||
uint64_t magic_number; /* dump magic number,unique to verify */
|
||||
/* dump */
|
||||
uint32_t version; /* version number of this dump */
|
||||
uint32_t header_size; /* size of this header */
|
||||
uint32_t dump_level; /* level of this dump */
|
||||
uint32_t page_size; /* page size (e.g. 4K, 8K, 16K, etc.) */
|
||||
uint64_t memory_size; /* size of entire physical memory */
|
||||
uint64_t memory_start; /* start of physical memory */
|
||||
uint64_t memory_end; /* end of physical memory */
|
||||
/* the number of dump pages in this dump specifically */
|
||||
uint32_t num_dump_pages;
|
||||
char panic_string[DUMP_PANIC_LEN];
|
||||
|
||||
/* timeval depends on machine, two long values */
|
||||
struct {uint64_t tv_sec;
|
||||
uint64_t tv_usec;
|
||||
} time; /* the time of the system crash */
|
||||
|
||||
/* the NEW utsname (uname) information -- in character form */
|
||||
/* we do this so we don't have to include utsname.h */
|
||||
/* plus it helps us be more architecture independent */
|
||||
char utsname_sysname[UTS_LEN];
|
||||
char utsname_nodename[UTS_LEN];
|
||||
char utsname_release[UTS_LEN];
|
||||
char utsname_version[UTS_LEN];
|
||||
char utsname_machine[UTS_LEN];
|
||||
char utsname_domainname[UTS_LEN];
|
||||
|
||||
uint64_t current_task;
|
||||
uint32_t dump_compress; /* compression type used in this dump */
|
||||
uint32_t dump_flags; /* any additional flags */
|
||||
uint32_t dump_device; /* any additional flags */
|
||||
uint64_t s390_asm_magic;
|
||||
uint16_t cpu_cnt;
|
||||
uint32_t lowcore_ptr[512];
|
||||
} __packed;
|
||||
|
||||
struct _lkcd_dump_header_asm {
|
||||
uint64_t magic_number;
|
||||
uint32_t version;
|
||||
uint32_t header_size;
|
||||
uint16_t cpu_cnt;
|
||||
uint16_t real_cpu_cnt;
|
||||
uint32_t lc_vec[512];
|
||||
} __packed;
|
||||
|
||||
struct _dump_page {
|
||||
uint64_t address; /* the address of this dump page */
|
||||
uint32_t size; /* the size of this dump page */
|
||||
uint32_t flags; /* flags (DUMP_COMPRESSED, DUMP_RAW */
|
||||
/* or DUMP_END) */
|
||||
} __packed;
|
||||
|
||||
struct _lkcd_dump_header dumpHeader;
|
||||
struct _lkcd_dump_header_asm dumpHeaderAsm;
|
||||
|
||||
private:
|
||||
int compressGZIP(const char *old, uint32_t old_size, char *n,
|
||||
uint32_t new_size);
|
||||
Dump *referenceDump;
|
||||
};
|
||||
|
||||
class LKCDDump32 : public LKCDDump
|
||||
{
|
||||
public:
|
||||
LKCDDump32(Dump *dump, const RegisterContent32 &rc);
|
||||
virtual void copyRegsToPage(uint64_t offset, char *buf);
|
||||
private:
|
||||
RegisterContent32 registerContent;
|
||||
};
|
||||
|
||||
class LKCDDump64 : public LKCDDump
|
||||
{
|
||||
public:
|
||||
LKCDDump64(Dump *dump, const RegisterContent64 &rc);
|
||||
virtual void copyRegsToPage(uint64_t offset, char *buf);
|
||||
private:
|
||||
RegisterContent64 registerContent;
|
||||
};
|
||||
|
||||
#endif /* LKCD_DUMP_H */
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Register content classes
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "register_content.h"
|
||||
#include "dump.h"
|
||||
|
||||
RegisterContent32::RegisterContent32(void)
|
||||
: regSets(), nrCpus(0)
|
||||
{
|
||||
}
|
||||
|
||||
RegisterContent32::RegisterContent32(const RegisterContent32& r)
|
||||
{
|
||||
nrCpus = r.nrCpus;
|
||||
memcpy(®Sets,&r.regSets,sizeof(regSets));
|
||||
}
|
||||
|
||||
void RegisterContent32::addRegisterSet(const RegisterSet32& rs)
|
||||
{
|
||||
if(nrCpus < MAX_CPUS){
|
||||
regSets[nrCpus++] = rs;
|
||||
} else {
|
||||
throw(DumpException("RegisterContent32::addRegisterSet - " \
|
||||
"No more register sets available"));
|
||||
}
|
||||
}
|
||||
|
||||
RegisterSet32 RegisterContent32::getRegisterSet(int cpu){
|
||||
if(cpu <= nrCpus){
|
||||
return regSets[cpu];
|
||||
} else {
|
||||
throw(DumpException("RegisterContent32::getRegisterSet - " \
|
||||
"No register set for cpu"));
|
||||
}
|
||||
}
|
||||
|
||||
RegisterContent64::RegisterContent64(void)
|
||||
: regSets(), nrCpus(0)
|
||||
{
|
||||
}
|
||||
|
||||
RegisterContent64::RegisterContent64(const RegisterContent64& r)
|
||||
{
|
||||
nrCpus = r.nrCpus;
|
||||
memcpy(®Sets,&r.regSets,sizeof(regSets));
|
||||
}
|
||||
|
||||
void RegisterContent64::addRegisterSet(const RegisterSet64& rs)
|
||||
{
|
||||
if(nrCpus < MAX_CPUS){
|
||||
regSets[nrCpus++] = rs;
|
||||
} else {
|
||||
throw(DumpException("RegisterContent64::addRegisterSet - " \
|
||||
"No more register sets available"));
|
||||
}
|
||||
}
|
||||
|
||||
RegisterSet64 RegisterContent64::getRegisterSet(int cpu)
|
||||
{
|
||||
if(cpu <= nrCpus){
|
||||
return regSets[cpu];
|
||||
} else {
|
||||
throw(DumpException("RegisterContent64::getRegisterSet - " \
|
||||
"No register set for cpu"));
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Register content classes
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 REGISTER_CONTENT_H
|
||||
#define REGISTER_CONTENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_CPUS 512
|
||||
|
||||
class RegisterSet64
|
||||
{
|
||||
public:
|
||||
uint64_t gprs[16];
|
||||
uint64_t crs[16];
|
||||
uint32_t acrs[16];
|
||||
uint64_t fprs[16];
|
||||
uint32_t fpCr;
|
||||
uint64_t psw[2];
|
||||
uint32_t prefix;
|
||||
uint64_t cpuTimer;
|
||||
uint64_t clkCmp;
|
||||
};
|
||||
|
||||
class RegisterSet32
|
||||
{
|
||||
public:
|
||||
uint32_t gprs[16];
|
||||
uint32_t crs[16];
|
||||
uint32_t acrs[16];
|
||||
uint64_t fprs[4];
|
||||
uint32_t psw[2];
|
||||
uint32_t prefix;
|
||||
uint64_t cpuTimer;
|
||||
uint64_t clkCmp;
|
||||
};
|
||||
|
||||
class RegisterContent64{
|
||||
public:
|
||||
RegisterContent64(void);
|
||||
RegisterContent64(const RegisterContent64&);
|
||||
RegisterSet64 getRegisterSet(int cpu);
|
||||
void addRegisterSet(const RegisterSet64&);
|
||||
inline int getNumCpus(void) const { return nrCpus; }
|
||||
RegisterContent64& operator=(const RegisterContent64&) = default;
|
||||
|
||||
RegisterSet64 regSets[MAX_CPUS];
|
||||
private:
|
||||
int nrCpus;
|
||||
|
||||
};
|
||||
|
||||
class RegisterContent32{
|
||||
public:
|
||||
RegisterContent32(void);
|
||||
RegisterContent32(const RegisterContent32&);
|
||||
RegisterSet32 getRegisterSet(int cpu);
|
||||
void addRegisterSet(const RegisterSet32&);
|
||||
inline int getNumCpus(void) const { return nrCpus; }
|
||||
RegisterContent32& operator=(const RegisterContent32&) = default;
|
||||
|
||||
RegisterSet32 regSets[MAX_CPUS];
|
||||
private:
|
||||
int nrCpus;
|
||||
};
|
||||
|
||||
#endif /* REGISTER_CONTENT_H */
|
||||
@@ -1,624 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Register content classes:
|
||||
* VMDump, VMDumpClassic, VMDump64, VMDump64Big, VMDump32
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "vm_dump.h"
|
||||
|
||||
Dump::DumpType VMDump::getDumpType(const char* inputFileName)
|
||||
{
|
||||
uint8_t fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
|
||||
struct _fir_basic fir;
|
||||
struct _fmbk fmbk;
|
||||
struct _adsr adsr;
|
||||
char msg[200];
|
||||
FILE* fh;
|
||||
|
||||
fh = fopen(inputFileName,"r");
|
||||
if (!fh) {
|
||||
sprintf(msg,"Could not open '%s'",inputFileName);
|
||||
throw DumpErrnoException(msg);
|
||||
}
|
||||
|
||||
/* Record 1: adsr */
|
||||
dump_read(&adsr, sizeof(adsr), 1, fh);
|
||||
|
||||
/* Record 2: fmbk */
|
||||
dump_seek(fh, 0x1000, SEEK_SET);
|
||||
if (fread(&fmbk, sizeof(fmbk), 1, fh) != 1) {
|
||||
if(ferror(fh)) {
|
||||
sprintf(msg,"Could not read header of vmdump '%s'",
|
||||
inputFileName);
|
||||
fclose(fh);
|
||||
throw DumpErrnoException(msg);
|
||||
} else{
|
||||
sprintf(msg,"Input file '%s' is not a vmdump",
|
||||
inputFileName);
|
||||
fclose(fh);
|
||||
throw DumpException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if this is a vmdump */
|
||||
if (memcmp(fmbk.id, fmbk_id, 8) != 0 ||
|
||||
adsr.dump_type != 0xe5d4c4e4d4d74040ULL) {
|
||||
fclose(fh);
|
||||
sprintf(msg, "Input file '%s' is not a vmdump", inputFileName);
|
||||
throw DumpException(msg);
|
||||
}
|
||||
|
||||
/* Record 3-7: fir */
|
||||
dump_seek(fh, (fmbk.rec_nr_fir - 1) * 0x1000, SEEK_SET);
|
||||
if(fread(&fir, sizeof(fir), 1, fh) != 1) {
|
||||
if (ferror(fh)) {
|
||||
sprintf(msg,"Could not read header of vmdump '%s'",
|
||||
inputFileName);
|
||||
fclose(fh);
|
||||
throw DumpErrnoException(msg);
|
||||
}
|
||||
else{
|
||||
sprintf(msg, "Could not read header of vmdump '%s'",
|
||||
inputFileName);
|
||||
fclose(fh);
|
||||
throw DumpException(msg);
|
||||
}
|
||||
}
|
||||
fclose(fh);
|
||||
if (fir.fir_format == 0) {
|
||||
return DT_VM32;
|
||||
} else if (fir.fir_format == 0x02) {/*XXX && (fir.dump_format == 0x1))*/
|
||||
return DT_VM64_BIG;
|
||||
} else if (fir.fir_format == 0x82) {
|
||||
return DT_VM64;
|
||||
} else {
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
|
||||
{
|
||||
uint8_t fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
|
||||
|
||||
ebcdicAsciiConv = iconv_open("ISO-8859-1", "EBCDIC-US");
|
||||
|
||||
/* Record 1: adsrRecord */
|
||||
|
||||
dump_seek(fh,0,SEEK_SET);
|
||||
dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
|
||||
|
||||
if(debug) {
|
||||
char buf_asc[1024];
|
||||
char buf[1024];
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "off=%d\n", adsrRecord.sec5_offset);
|
||||
dump_seek(fh, adsrRecord.sec5_offset, SEEK_SET);
|
||||
dump_read(buf, adsrRecord.sec5_len, 1, fh);
|
||||
ebcAsc(buf, buf_asc, adsrRecord.sec5_len);
|
||||
for (i=0; i < adsrRecord.sec5_len; i++) {
|
||||
if ((buf_asc[i]==0) || iscntrl(buf_asc[i]))
|
||||
buf_asc[i]=' ';
|
||||
}
|
||||
buf_asc[adsrRecord.sec5_len] = 0;
|
||||
printf("symptom string1: %s\n",buf_asc);
|
||||
}
|
||||
|
||||
/* Record 2: fmbk */
|
||||
|
||||
dump_seek(fh,0x1000,SEEK_SET);
|
||||
dump_read(&fmbkRecord,sizeof(fmbkRecord),1,fh);
|
||||
|
||||
/* Check if this is a vmdump */
|
||||
if(memcmp(fmbkRecord.id, fmbk_id, 8) != 0) {
|
||||
throw DumpException("Input file is not a vmdump");
|
||||
}
|
||||
|
||||
/* Record 3-7: fir records read by subclasses */
|
||||
|
||||
/* Record 8: albk */
|
||||
|
||||
dump_seek(fh,(fmbkRecord.rec_nr_access-1)*0x1000 ,SEEK_SET);
|
||||
dump_read(&albkRecord,sizeof(albkRecord),1,fh);
|
||||
}
|
||||
|
||||
struct timeval VMDump::getDumpTime(void) const
|
||||
{
|
||||
struct timeval rc;
|
||||
|
||||
s390TodToTimeval(adsrRecord.tod,&rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void VMDump::printDebug(void)
|
||||
{
|
||||
struct timeval time;
|
||||
char fmbk_id[8];
|
||||
char albk_id[8];
|
||||
|
||||
s390TodToTimeval(adsrRecord.tod, &time);
|
||||
|
||||
/* adsr */
|
||||
|
||||
printf("time : %s\n", ctime(&time.tv_sec));
|
||||
printf("stat1 : %x\n", adsrRecord.record_status_flag1);
|
||||
printf("stat2 : %x\n", adsrRecord.record_status_flag2);
|
||||
printf("sec 2 len: %i\n", adsrRecord.sec2_len);
|
||||
printf("sec 2.1 len: %i/%i\n", adsrRecord.sec2_1_len,
|
||||
adsrRecord.sec2_1_offset);
|
||||
printf("sec 3 len: %i/%i\n", adsrRecord.sec3_len,
|
||||
adsrRecord.sec3_offset);
|
||||
printf("sec 4 len: %i/%i\n", adsrRecord.sec4_len,
|
||||
adsrRecord.sec4_offset);
|
||||
printf("sec 5 len: %i/%i\n", adsrRecord.sec5_len,
|
||||
adsrRecord.sec5_offset);
|
||||
printf("sec 6 len: %i/%i\n", adsrRecord.sec6_len,
|
||||
adsrRecord.sec6_offset);
|
||||
|
||||
/* fmbk */
|
||||
|
||||
ebcAsc(fmbkRecord.id, fmbk_id, sizeof(fmbkRecord.id));
|
||||
fmbk_id[7] = 0;
|
||||
printf("id : %s\n", fmbk_id);
|
||||
printf("fir rec nr: %i\n", fmbkRecord.rec_nr_fir);
|
||||
printf("vec rec nr: %i\n", fmbkRecord.rec_nr_vector);
|
||||
printf("access rec nr: %i\n", fmbkRecord.rec_nr_access);
|
||||
|
||||
|
||||
/* albk */
|
||||
|
||||
ebcAsc(albkRecord.id, albk_id, sizeof(albkRecord.id));
|
||||
albk_id[7]=0;
|
||||
printf("ALBK id : %s\n",albk_id);
|
||||
}
|
||||
|
||||
void VMDump::printInfo(void)
|
||||
{
|
||||
struct timeval time;
|
||||
|
||||
s390TodToTimeval(adsrRecord.tod,&time);
|
||||
fprintf(stderr, " date........: %s",ctime(&time.tv_sec));
|
||||
}
|
||||
|
||||
int VMDump::seekMem(uint64_t offset)
|
||||
{
|
||||
if (offset != 0) {
|
||||
return -1;
|
||||
}
|
||||
pageOffset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VMDump::readMem(char* buf, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pageOffset == 0)
|
||||
dump_seek(fh, memoryStartRecord, SEEK_SET);
|
||||
|
||||
if (size % 0x1000 != 0) {
|
||||
throw(DumpException("internal error: VMDump::readMem() " \
|
||||
"can only handle sizes which are multiples of page size"));
|
||||
}
|
||||
|
||||
for(i = 0; i < size; i += 0x1000) {
|
||||
if(testPage(pageOffset)) {
|
||||
dump_read(buf + i, 0x1000, 1, fh);
|
||||
} else {
|
||||
memset(buf + i, 0, 0x1000);
|
||||
}
|
||||
pageOffset += 1;
|
||||
}
|
||||
}
|
||||
|
||||
VMDump::~VMDump(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* VMDumpClassic: traditional 32/64 bit vmdump (before z/VM 5.2) */
|
||||
/*****************************************************************************/
|
||||
|
||||
VMDumpClassic::VMDumpClassic(const char *fileName) : VMDump(fileName)
|
||||
{
|
||||
int storageKeyPages,bitMapPages;
|
||||
|
||||
pageOffset = 0;
|
||||
|
||||
/* Record 9: asibk */
|
||||
|
||||
dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
|
||||
dump_read(&asibkRecord,sizeof(asibkRecord),1,fh);
|
||||
|
||||
/* Record 10: bitmaps */
|
||||
|
||||
dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
|
||||
bitmap = new char[asibkRecord.storage_size_2GB / (0x1000 * 8)];
|
||||
dump_read(bitmap,asibkRecord.storage_size_2GB / (0x1000*8),1,fh);
|
||||
|
||||
bitMapPages=asibkRecord.storage_size_2GB / (0x1000 * 8);
|
||||
if (bitMapPages % 0x1000 != 0)
|
||||
bitMapPages = bitMapPages/0x1000 + 1;
|
||||
else
|
||||
bitMapPages = bitMapPages/0x1000;
|
||||
|
||||
storageKeyPages=asibkRecord.storage_size_2GB / 0x1000;
|
||||
if(storageKeyPages % 0x1000 != 0) {
|
||||
storageKeyPages = storageKeyPages/0x1000 + 1;
|
||||
} else {
|
||||
storageKeyPages = storageKeyPages/0x1000;
|
||||
}
|
||||
|
||||
/* Skip storage keys */
|
||||
|
||||
memoryStartRecord = (fmbkRecord.rec_nr_access + 1) *0x1000 /* 0x9000 */
|
||||
+ (bitMapPages + storageKeyPages)*0x1000;
|
||||
if(debug) {
|
||||
printf("Mem Offset: %llx\n", (long long) memoryStartRecord);
|
||||
}
|
||||
}
|
||||
|
||||
void VMDumpClassic::printInfo(void)
|
||||
{
|
||||
VMDump::printInfo();
|
||||
fprintf(stderr, " storage.....: %i MB\n",
|
||||
asibkRecord.storage_size_2GB/(1024*1024));
|
||||
}
|
||||
|
||||
VMDumpClassic::~VMDumpClassic(void)
|
||||
{
|
||||
delete bitmap;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* VMDump32: 32 bit vmdump */
|
||||
/*****************************************************************************/
|
||||
|
||||
VMDump32::VMDump32(const char* filename) : VMDumpClassic(filename)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!fh) {
|
||||
return;
|
||||
}
|
||||
|
||||
dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
|
||||
dump_read(&fir32Record,sizeof(fir32Record),1,fh);
|
||||
|
||||
fir32OtherRecords = new _fir_other_32[fir32Record.online_cpus];
|
||||
for(i=0; i < fir32Record.online_cpus; i++) {
|
||||
/* fir other */
|
||||
dump_read(&fir32OtherRecords[i],sizeof(fir32OtherRecords[i]),1,
|
||||
fh);
|
||||
}
|
||||
if(debug)
|
||||
printDebug();
|
||||
}
|
||||
|
||||
RegisterContent32 VMDump32::getRegisterContent(void)
|
||||
{
|
||||
RegisterContent32 rc;
|
||||
RegisterSet32 rs;
|
||||
int cpu;
|
||||
|
||||
/* First CPU */
|
||||
|
||||
memcpy(&rs.gprs, &fir32Record.gprs, sizeof(rs.gprs));
|
||||
memcpy(&rs.crs, &fir32Record.crs, sizeof(rs.crs));
|
||||
memcpy(&rs.acrs, &fir32Record.acrs, sizeof(rs.acrs));
|
||||
memcpy(&rs.psw, &fir32Record.psw, sizeof(rs.psw));
|
||||
memcpy(&rs.prefix, &fir32Record.prefix, sizeof(rs.prefix));
|
||||
memcpy(&rs.fprs, &fir32Record.fprs, sizeof(rs.fprs));
|
||||
memcpy(&rs.cpuTimer, &fir32Record.cpu_timer, sizeof(rs.cpuTimer));
|
||||
memcpy(&rs.clkCmp, &fir32Record.clock_cmp, sizeof(rs.clkCmp));
|
||||
|
||||
rc.addRegisterSet(rs);
|
||||
|
||||
/* Other online cpus */
|
||||
|
||||
for(cpu = 0; cpu < fir32Record.online_cpus; cpu++) {
|
||||
memcpy(&rs.gprs, &fir32OtherRecords[cpu].gprs, sizeof(rs.gprs));
|
||||
memcpy(&rs.crs, &fir32OtherRecords[cpu].crs, sizeof(rs.crs));
|
||||
memcpy(&rs.acrs, &fir32OtherRecords[cpu].acrs, sizeof(rs.acrs));
|
||||
/* No psw for ESA vmdumps */
|
||||
rs.psw[0] = 0xdeadbeef;
|
||||
rs.psw[1] = 0xdeadbeef;
|
||||
memcpy(&rs.prefix, &fir32OtherRecords[cpu].prefix,
|
||||
sizeof(rs.prefix));
|
||||
memcpy(&rs.fprs, &fir32OtherRecords[cpu].fprs, sizeof(rs.fprs));
|
||||
memcpy(&rs.cpuTimer, &fir32OtherRecords[cpu].cpu_timer,
|
||||
sizeof(rs.cpuTimer));
|
||||
memcpy(&rs.clkCmp, &fir32OtherRecords[cpu].clock_cmp,
|
||||
sizeof(rs.clkCmp));
|
||||
rc.addRegisterSet(rs);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void VMDump32::printDebug(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
VMDump::printDebug();
|
||||
printf("prefix: %x\n", fir32Record.prefix);
|
||||
printf("cpus: %x\n", fir32Record.online_cpus);
|
||||
printf("psw: %08x %08x\n", fir32Record.psw[0], fir32Record.psw[1]);
|
||||
|
||||
for (i=0; i < fir32Record.online_cpus; i++) {
|
||||
/* fir other */
|
||||
printf("prefix (%i): %x\n", i, fir32OtherRecords[i].prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VMDump32::printInfo(void)
|
||||
{
|
||||
fprintf(stderr, "vmdump information:\n");
|
||||
fprintf(stderr, " architecture: 32 bit\n");
|
||||
VMDumpClassic::printInfo();
|
||||
fprintf(stderr, " cpus........: %x\n", fir32Record.online_cpus + 1);
|
||||
}
|
||||
|
||||
|
||||
VMDump32::~VMDump32(void)
|
||||
{
|
||||
delete fir32OtherRecords;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* VMDump64: 64 bit vmdump for old vmdump format (z/VM < 5.2) */
|
||||
/*****************************************************************************/
|
||||
|
||||
VMDump64::VMDump64(const char* filename) : VMDumpClassic(filename)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!fh) {
|
||||
return;
|
||||
}
|
||||
|
||||
dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
|
||||
dump_read(&fir64Record,sizeof(fir64Record),1,fh);
|
||||
|
||||
fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
|
||||
for (i=0; i < fir64Record.online_cpus; i++) {
|
||||
/* fir other */
|
||||
dump_read(&fir64OtherRecords[i], sizeof(fir64OtherRecords[i]),
|
||||
1, fh);
|
||||
}
|
||||
if(debug)
|
||||
printDebug();
|
||||
}
|
||||
|
||||
void VMDump64::printDebug(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
VMDump::printDebug();
|
||||
printf("prefix: %x\n", fir64Record.prefix);
|
||||
printf("cpus: %x\n", fir64Record.online_cpus);
|
||||
printf("psw: %016llx %016llx\n", (long long)fir64Record.psw[0],
|
||||
(long long)fir64Record.psw[1]);
|
||||
|
||||
for (i=0; i < fir64Record.online_cpus; i++) {
|
||||
/* fir other */
|
||||
printf("prefix (%i): %x\n", i, fir64OtherRecords[i].prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void VMDump64::printInfo(void)
|
||||
{
|
||||
fprintf(stderr, "vmdump information:\n");
|
||||
fprintf(stderr, " architecture: 64 bit\n");
|
||||
VMDumpClassic::printInfo();
|
||||
fprintf(stderr, " cpus........: %x\n",fir64Record.online_cpus + 1);
|
||||
}
|
||||
|
||||
|
||||
RegisterContent64 VMDump64::getRegisterContent(void)
|
||||
{
|
||||
RegisterContent64 rc;
|
||||
RegisterSet64 rs;
|
||||
int cpu;
|
||||
|
||||
/* First CPU */
|
||||
|
||||
memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
|
||||
memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
|
||||
memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
|
||||
memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
|
||||
memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
|
||||
memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
|
||||
memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
|
||||
memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
|
||||
memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
|
||||
|
||||
rc.addRegisterSet(rs);
|
||||
|
||||
/* other online cpus */
|
||||
|
||||
for (cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
|
||||
memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
|
||||
memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
|
||||
memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
|
||||
memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
|
||||
memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
|
||||
sizeof(rs.prefix));
|
||||
memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
|
||||
memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
|
||||
sizeof(rs.cpuTimer));
|
||||
memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
|
||||
sizeof(rs.clkCmp));
|
||||
memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
|
||||
sizeof(rs.fpCr));
|
||||
rc.addRegisterSet(rs);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
VMDump64::~VMDump64(void)
|
||||
{
|
||||
delete fir64OtherRecords;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* VMDump64Big: 64 bit vmdump with new big storage dump format */
|
||||
/*****************************************************************************/
|
||||
|
||||
VMDump64Big::VMDump64Big(const char* filename) : VMDump(filename)
|
||||
{
|
||||
uint64_t pageNum, nrDumpedPages;
|
||||
int i, j;
|
||||
|
||||
if(!fh) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Record 9: asibk */
|
||||
|
||||
dump_seek(fh, fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
|
||||
dump_read(&asibkRecordNew, sizeof(asibkRecordNew), 1, fh);
|
||||
|
||||
/* Record 10: bitmaps: */
|
||||
/* Read all bitmap pages and setup bitmap array */
|
||||
|
||||
pageNum = 0;
|
||||
nrDumpedPages = asibkRecordNew.storage_size_def_store / 0x1000;
|
||||
memoryStartRecord = (fmbkRecord.rec_nr_access + 1) * 0x1000;
|
||||
bitmap = new char[asibkRecordNew.storage_size_def_store/(0x1000 * 8)];
|
||||
if(!bitmap) {
|
||||
throw(DumpErrnoException("out of memory"));
|
||||
}
|
||||
memset(bitmap,0,asibkRecordNew.storage_size_def_store/(0x1000 * 8));
|
||||
|
||||
dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
|
||||
|
||||
do {
|
||||
char bmIndexPage[0x1000];
|
||||
|
||||
dump_read(bmIndexPage, sizeof(bmIndexPage), 1, fh);
|
||||
memoryStartRecord += 0x1000;
|
||||
for (i=0; i < 0x1000; i++) {
|
||||
if(testBitmapPage(bmIndexPage, i)) {
|
||||
char bmPage[0x1000];
|
||||
|
||||
dump_read(bmPage,sizeof(bmPage),1,fh);
|
||||
memoryStartRecord += 0x1000;
|
||||
for(j = 0; j < 0x1000; j++) {
|
||||
if(testBitmapKeyPage(bmPage, j)) {
|
||||
setPageBit(pageNum);
|
||||
}
|
||||
pageNum++;
|
||||
if(pageNum == nrDumpedPages) {
|
||||
goto all_bitmaps_read;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pageNum += 0x1000; /* Empty pages */
|
||||
}
|
||||
}
|
||||
} while (pageNum < nrDumpedPages);
|
||||
|
||||
all_bitmaps_read:
|
||||
|
||||
if(debug)
|
||||
printf("Mem Offset: %llx\n", (long long)memoryStartRecord);
|
||||
|
||||
dump_seek(fh, (fmbkRecord.rec_nr_fir-1)* 0x1000, SEEK_SET);
|
||||
dump_read(&fir64Record, sizeof(fir64Record), 1, fh);
|
||||
|
||||
fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
|
||||
for (i=0; i < fir64Record.online_cpus; i++) {
|
||||
/* fir other */
|
||||
dump_read(&fir64OtherRecords[i], sizeof(fir64OtherRecords[i]),
|
||||
1, fh);
|
||||
}
|
||||
if(debug)
|
||||
printDebug();
|
||||
}
|
||||
|
||||
void VMDump64Big::printDebug(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
VMDump::printDebug();
|
||||
printf("prefix: %x\n", fir64Record.prefix);
|
||||
printf("cpus: %x\n", fir64Record.online_cpus);
|
||||
printf("psw: %016llx %016llx\n", (long long)fir64Record.psw[0],
|
||||
(long long)fir64Record.psw[1]);
|
||||
|
||||
for (i=0; i < fir64Record.online_cpus; i++) {
|
||||
/* fir other */
|
||||
printf("prefix (%i): %x\n", i, fir64OtherRecords[i].prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void VMDump64Big::printInfo(void)
|
||||
{
|
||||
fprintf(stderr, "vmdump information:\n");
|
||||
fprintf(stderr, " architecture: 64 bit (big)\n");
|
||||
fprintf(stderr, " storage.....: %lli MB\n",
|
||||
(long long)asibkRecordNew.storage_size_def_store / (1024*1024));
|
||||
VMDump::printInfo();
|
||||
fprintf(stderr, " cpus........: %x\n", fir64Record.online_cpus + 1);
|
||||
}
|
||||
|
||||
|
||||
RegisterContent64 VMDump64Big::getRegisterContent(void)
|
||||
{
|
||||
RegisterContent64 rc;
|
||||
RegisterSet64 rs;
|
||||
int cpu;
|
||||
|
||||
/* First CPU */
|
||||
|
||||
memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
|
||||
memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
|
||||
memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
|
||||
memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
|
||||
memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
|
||||
memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
|
||||
memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
|
||||
memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
|
||||
memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
|
||||
|
||||
rc.addRegisterSet(rs);
|
||||
|
||||
/* other online cpus */
|
||||
|
||||
for(cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
|
||||
memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
|
||||
memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
|
||||
memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
|
||||
memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
|
||||
memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
|
||||
sizeof(rs.prefix));
|
||||
memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
|
||||
memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
|
||||
sizeof(rs.cpuTimer));
|
||||
memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
|
||||
sizeof(rs.clkCmp));
|
||||
memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
|
||||
sizeof(rs.fpCr));
|
||||
rc.addRegisterSet(rs);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
VMDump64Big::~VMDump64Big(void)
|
||||
{
|
||||
delete bitmap;
|
||||
delete fir64OtherRecords;
|
||||
}
|
||||
@@ -1,484 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Register content classes:
|
||||
* VMDump, VMDumpClassic, VMDump64, VMDump64Big, VMDump32
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
/*===========================*
|
||||
* The format of an vmdump: *
|
||||
*===========================*
|
||||
*---------------------------*
|
||||
* Symptom Record *
|
||||
* (ADSR COPY) Record 1 *
|
||||
*---------------------------*
|
||||
* Dump File Map Record *
|
||||
* (HCPDFMBK COPY) Record 2 *
|
||||
*---------------------------*
|
||||
* Dump File Info Record *
|
||||
* (HCPDFIR COPY) Records 3-7*
|
||||
*---------------------------*
|
||||
* Vector Registers *
|
||||
* (optional) *
|
||||
*---------------------------*
|
||||
* Access Lists (HCPDALBK) *
|
||||
*---------------------------*
|
||||
* Address Space A *
|
||||
* Information and Map *
|
||||
* Record (HCPASIBK) *
|
||||
*---------------------------*
|
||||
* Address Space A *
|
||||
* Bit Maps *
|
||||
*---------------------------*
|
||||
* Address Space A *
|
||||
* Key Maps *
|
||||
*---------------------------*
|
||||
* Address Space A *
|
||||
* Guest Storage *
|
||||
*---------------------------*
|
||||
* Additional Address Spaces *
|
||||
* ASIBK *
|
||||
* Bit Maps *
|
||||
* Key Maps *
|
||||
* Guest Storage *
|
||||
* *NOTE* These probably *
|
||||
* aren't in a Linux guest. *
|
||||
*---------------------------*
|
||||
*/
|
||||
|
||||
#ifndef VMDUMP_H
|
||||
#define VMDUMP_H
|
||||
|
||||
#include <iconv.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "dump.h"
|
||||
#include "register_content.h"
|
||||
|
||||
class VMDump : public Dump
|
||||
{
|
||||
public:
|
||||
VMDump(const char *filename);
|
||||
virtual ~VMDump(void);
|
||||
virtual void readMem(char *buf, int size);
|
||||
virtual int seekMem(uint64_t offset);
|
||||
virtual struct timeval getDumpTime(void) const;
|
||||
|
||||
void printDebug(void);
|
||||
void printInfo(void);
|
||||
|
||||
static DumpType getDumpType(const char *);
|
||||
inline int testPage(uint64_t bit) const
|
||||
{
|
||||
return (bitmap[bit/8] & (1 << (7-(bit % 8))));
|
||||
}
|
||||
inline void setPageBit(uint64_t bit) const
|
||||
{
|
||||
bitmap[bit/8] |= (1 << (7-(bit % 8)));
|
||||
}
|
||||
protected:
|
||||
/* Types */
|
||||
struct _adsr {
|
||||
/* Section 1*/
|
||||
uint16_t sr;
|
||||
uint32_t cpu_model;
|
||||
char cpu_serial[6];
|
||||
uint32_t time_zone_conversion_factor;
|
||||
uint64_t tod;
|
||||
char time_stamp_str[4];
|
||||
char date_str[6];
|
||||
char node_name[8];
|
||||
char product_id[4];
|
||||
char feature_level[8];
|
||||
uint8_t record_status_flag1;
|
||||
uint8_t record_status_flag2;
|
||||
uint64_t dump_type;
|
||||
|
||||
/* Section 2*/
|
||||
char arch_level[2];
|
||||
uint16_t sec2_len;
|
||||
uint16_t sec2_1_len;
|
||||
uint16_t sec2_1_offset;
|
||||
uint16_t sec3_len;
|
||||
uint16_t sec3_offset;
|
||||
uint16_t sec4_len;
|
||||
uint16_t sec4_offset;
|
||||
uint16_t sec5_len;
|
||||
uint16_t sec5_offset;
|
||||
uint16_t sec6_len;
|
||||
uint16_t sec6_offset;
|
||||
} __packed;
|
||||
|
||||
struct _fmbk {
|
||||
char id[8];
|
||||
uint32_t rec_nr_fir;
|
||||
uint32_t rec_nr_vector;
|
||||
uint32_t rec_nr_access;
|
||||
uint32_t num_acc_recs;
|
||||
uint32_t num_addr_spaces;
|
||||
uint32_t rec_nr_asibk;
|
||||
} __packed;
|
||||
|
||||
struct _fir_basic {
|
||||
char filler1[15];
|
||||
uint8_t dump_format;/* 0x1 for big storage dump, 0x2 for cp */
|
||||
/* hard abend, 0x3 for cp soft abend */
|
||||
char filler2[171];
|
||||
uint8_t fir_format; /* 0x2 for big esame, 0x82 for esame, */
|
||||
/* 0x00 for esa */
|
||||
} __packed;
|
||||
|
||||
struct _albk {
|
||||
char id[8];
|
||||
} __packed;
|
||||
|
||||
/* Methods */
|
||||
inline void ebcAsc(char *in, char *out, size_t size) const
|
||||
{
|
||||
size_t size_out = size;
|
||||
size_t size_in = size;
|
||||
size_t rc;
|
||||
|
||||
rc = iconv(ebcdicAsciiConv, &in, &size_in, &out, &size_out);
|
||||
if (rc == (size_t) -1)
|
||||
throw(DumpException("Code page translation EBCDIC-ASCII failed"));
|
||||
}
|
||||
|
||||
/* Members */
|
||||
struct _adsr adsrRecord;
|
||||
struct _fmbk fmbkRecord;
|
||||
struct _albk albkRecord;
|
||||
uint64_t memoryStartRecord;
|
||||
char *bitmap;
|
||||
uint64_t pageOffset;
|
||||
private:
|
||||
iconv_t ebcdicAsciiConv;
|
||||
};
|
||||
|
||||
class VMDumpClassic : public VMDump
|
||||
{
|
||||
public:
|
||||
VMDumpClassic(const char *filename);
|
||||
virtual ~VMDumpClassic(void);
|
||||
void printInfo(void);
|
||||
inline virtual uint64_t getMemSize(void) const
|
||||
{
|
||||
return (uint64_t)asibkRecord.storage_size_2GB;
|
||||
}
|
||||
protected:
|
||||
/* Types */
|
||||
struct _asibk {
|
||||
char id[8];
|
||||
char as_token[8];
|
||||
char spaceid[33];
|
||||
char reserved1[3];
|
||||
uint32_t storage_size_2GB;
|
||||
uint32_t dcss_bitmap_first_rec;
|
||||
uint32_t byte_past_highest_defined_byte;
|
||||
uint64_t format_of_as;
|
||||
char dump_id[100];
|
||||
uint32_t nr_of_recs_of_first_bit_map;
|
||||
} __packed;
|
||||
|
||||
|
||||
/* Members */
|
||||
struct _asibk asibkRecord;
|
||||
|
||||
};
|
||||
|
||||
#define MAX_BKEY_PAGES 2
|
||||
|
||||
class VMDump64Big : public VMDump
|
||||
{
|
||||
public:
|
||||
VMDump64Big(const char *filename);
|
||||
virtual ~VMDump64Big(void);
|
||||
RegisterContent64 getRegisterContent(void);
|
||||
|
||||
void printDebug(void);
|
||||
void printInfo(void);
|
||||
|
||||
inline virtual uint64_t getMemSize(void) const
|
||||
{
|
||||
return (uint64_t)asibkRecordNew.storage_size_def_store;
|
||||
}
|
||||
private:
|
||||
inline int testBitmapPage(char *page, uint64_t bit) const
|
||||
{
|
||||
return (page[bit/8] & (1 << (7-(bit % 8))));
|
||||
}
|
||||
|
||||
inline int testBitmapKeyPage(char *page, uint64_t bit) const
|
||||
{
|
||||
return (page[bit] & 0x01);
|
||||
}
|
||||
|
||||
/* types */
|
||||
struct _asibk_64_new {
|
||||
char id[8];
|
||||
char as_token[8];
|
||||
char spaceid[33];
|
||||
char reserved1[2];
|
||||
uint8_t asibk_format;
|
||||
char filler1[12];
|
||||
uint64_t storage_size_with_dcss;
|
||||
uint64_t storage_size_def_store;
|
||||
char filler2[136];
|
||||
uint64_t online_storage_table[8]; /* for "def store config" */
|
||||
uint64_t fence1;
|
||||
uint64_t requested_range_table[8];
|
||||
uint64_t fence2;
|
||||
uint32_t record_number_of_first_bit_map; /* XXX */
|
||||
} __packed;
|
||||
|
||||
struct _fir_64 {
|
||||
char id[8];
|
||||
uint64_t reserved1;
|
||||
uint64_t gprs[16];
|
||||
uint32_t prefix;
|
||||
char reserved2[5];
|
||||
uint64_t tod;
|
||||
char reserved3[8];
|
||||
uint64_t cpu_timer;
|
||||
char reserved4[7];
|
||||
uint8_t flag;
|
||||
uint8_t type;
|
||||
uint8_t complete;
|
||||
uint8_t fir_format; /* 0x82 for esame - 0x00 for esa */
|
||||
uint8_t cont_flags;
|
||||
uint8_t crypto_domain_index_reg;
|
||||
uint8_t virt_cpu_info;
|
||||
uint8_t arch_mode_id;
|
||||
uint64_t psw[2];
|
||||
uint64_t crs[16];
|
||||
uint64_t fprs[16];
|
||||
uint8_t reserved5;
|
||||
uint64_t clock_cmp;
|
||||
char reserved6[3];
|
||||
uint32_t tod_programmable_reg;
|
||||
uint32_t reserved_for_dvf[20];
|
||||
uint32_t acrs[16];
|
||||
uint32_t storage_size_2GB;
|
||||
uint32_t reserved7;
|
||||
uint32_t hcpsys_addr;
|
||||
uint32_t reserved8;
|
||||
uint64_t storage_size;
|
||||
uint32_t snap_area_map_blk;
|
||||
uint32_t reserved9;
|
||||
char loc_mem[256];
|
||||
uint16_t online_cpus;
|
||||
uint16_t cpu_addr;
|
||||
uint16_t section_size_vector;
|
||||
uint16_t reserved10;
|
||||
char asit_primary[8];
|
||||
char space_id_primary[33];
|
||||
char reserved12[3];
|
||||
uint16_t crypto_domain_index_mask;
|
||||
uint16_t reserved11;
|
||||
uint32_t fp_cntrl_reg;
|
||||
uint32_t reserved13;
|
||||
uint64_t reserved14[16];
|
||||
} __packed;
|
||||
|
||||
struct _fir_other_64 {
|
||||
uint16_t cpu_addr;
|
||||
uint16_t vector_sec_size;
|
||||
uint8_t crypto_index_reg;
|
||||
uint8_t virt_cpu_info;
|
||||
uint16_t crypto_index_mask;
|
||||
uint32_t reserved1[2];
|
||||
uint64_t fprs[16];
|
||||
uint64_t gprs[16];
|
||||
uint64_t psw[2];
|
||||
uint32_t reserved2[2];
|
||||
uint32_t prefix;
|
||||
uint32_t fp_cntrl_reg;
|
||||
uint32_t reserved3;
|
||||
uint32_t tod;
|
||||
uint64_t cpu_timer;
|
||||
uint64_t clock_cmp;
|
||||
uint32_t reserved4[2];
|
||||
uint32_t acrs[16];
|
||||
uint64_t crs[16];
|
||||
uint64_t mc_interrupt_code;
|
||||
uint32_t reserved5;
|
||||
uint32_t external_damage_code;
|
||||
uint64_t mc_failing_storage_addr;
|
||||
} __packed;
|
||||
|
||||
/* Members */
|
||||
struct _asibk_64_new asibkRecordNew;
|
||||
struct _fir_64 fir64Record;
|
||||
struct _fir_other_64 *fir64OtherRecords;
|
||||
};
|
||||
|
||||
class VMDump64 : public VMDumpClassic
|
||||
{
|
||||
public:
|
||||
VMDump64(const char *filename);
|
||||
virtual ~VMDump64(void);
|
||||
RegisterContent64 getRegisterContent(void);
|
||||
|
||||
void printDebug(void);
|
||||
void printInfo(void);
|
||||
private:
|
||||
/* Types */
|
||||
struct _fir_64 {
|
||||
char id[8];
|
||||
uint64_t reserved1;
|
||||
uint64_t gprs[16];
|
||||
uint32_t prefix;
|
||||
char reserved2[5];
|
||||
uint64_t tod;
|
||||
char reserved3[8];
|
||||
uint64_t cpu_timer;
|
||||
char reserved4[7];
|
||||
uint8_t flag;
|
||||
uint8_t type;
|
||||
uint8_t complete;
|
||||
uint8_t fir_format; /* 0x82 for esame - 0x00 for esa */
|
||||
uint8_t cont_flags;
|
||||
uint8_t crypto_domain_index_reg;
|
||||
uint8_t virt_cpu_info;
|
||||
uint8_t arch_mode_id;
|
||||
uint64_t psw[2];
|
||||
uint64_t crs[16];
|
||||
uint64_t fprs[16];
|
||||
uint8_t reserved5;
|
||||
uint64_t clock_cmp;
|
||||
char reserved6[3];
|
||||
uint32_t tod_programmable_reg;
|
||||
uint32_t reserved_for_dvf[20];
|
||||
uint32_t acrs[16];
|
||||
uint32_t storage_size_2GB;
|
||||
uint32_t reserved7;
|
||||
uint32_t hcpsys_addr;
|
||||
uint32_t reserved8;
|
||||
uint64_t storage_size;
|
||||
uint32_t snap_area_map_blk;
|
||||
uint32_t reserved9;
|
||||
char loc_mem[256];
|
||||
uint16_t online_cpus;
|
||||
uint16_t cpu_addr;
|
||||
uint16_t section_size_vector;
|
||||
uint16_t reserved10;
|
||||
char asit_primary[8];
|
||||
char space_id_primary[33];
|
||||
char reserved12[3];
|
||||
uint16_t crypto_domain_index_mask;
|
||||
uint16_t reserved11;
|
||||
uint32_t fp_cntrl_reg;
|
||||
uint32_t reserved13;
|
||||
uint64_t reserved14[16];
|
||||
} __packed;
|
||||
|
||||
struct _fir_other_64 {
|
||||
uint16_t cpu_addr;
|
||||
uint16_t vector_sec_size;
|
||||
uint8_t crypto_index_reg;
|
||||
uint8_t virt_cpu_info;
|
||||
uint16_t crypto_index_mask;
|
||||
uint32_t reserved1[2];
|
||||
uint64_t fprs[16];
|
||||
uint64_t gprs[16];
|
||||
uint64_t psw[2];
|
||||
uint32_t reserved2[2];
|
||||
uint32_t prefix;
|
||||
uint32_t fp_cntrl_reg;
|
||||
uint32_t reserved3;
|
||||
uint32_t tod;
|
||||
uint64_t cpu_timer;
|
||||
uint64_t clock_cmp;
|
||||
uint32_t reserved4[2];
|
||||
uint32_t acrs[16];
|
||||
uint64_t crs[16];
|
||||
uint64_t mc_interrupt_code;
|
||||
uint32_t reserved5;
|
||||
uint32_t external_damage_code;
|
||||
uint64_t mc_failing_storage_addr;
|
||||
} __packed;
|
||||
|
||||
/* Members */
|
||||
struct _fir_64 fir64Record;
|
||||
struct _fir_other_64 *fir64OtherRecords;
|
||||
};
|
||||
|
||||
class VMDump32 : public VMDumpClassic
|
||||
{
|
||||
public:
|
||||
VMDump32(const char *filename);
|
||||
virtual ~VMDump32(void);
|
||||
RegisterContent32 getRegisterContent(void);
|
||||
void printDebug(void);
|
||||
void printInfo(void);
|
||||
private:
|
||||
/* Types */
|
||||
struct _fir_32 {
|
||||
uint32_t gprs[16];
|
||||
uint32_t crs[16];
|
||||
uint64_t fprs[4];
|
||||
uint64_t tod;
|
||||
uint64_t cpu_timer;
|
||||
uint64_t clock_cmp;
|
||||
uint8_t flag;
|
||||
uint8_t type;
|
||||
uint8_t complete;
|
||||
uint8_t fir_format;
|
||||
uint32_t storage_size_2GB;
|
||||
char loc_mem[256];
|
||||
uint32_t prefix;
|
||||
uint16_t online_cpus;
|
||||
uint8_t cont_flags;
|
||||
uint8_t crypto_domain_index_reg;
|
||||
uint8_t virt_cpu_info;
|
||||
uint8_t arch_mode_id;
|
||||
uint16_t crypto_domain_index_mask;
|
||||
uint32_t reserved1;
|
||||
uint32_t snap_area_map_blk;
|
||||
uint64_t reserved2;
|
||||
uint32_t hcpsys_addr;
|
||||
uint32_t reserved3[20];
|
||||
uint32_t psw[2];
|
||||
uint16_t cpu_addr;
|
||||
uint16_t section_size_vector;
|
||||
uint32_t acrs[16];
|
||||
char asit_primary[8];
|
||||
char space_id_primary[33];
|
||||
char reserved4[131];
|
||||
} __packed;
|
||||
|
||||
struct _fir_other_32 {
|
||||
uint16_t cpu_addr;
|
||||
uint16_t vector_sec_size;
|
||||
uint32_t prefix;
|
||||
uint8_t crypto_index_reg;
|
||||
uint8_t virt_cpu_info;
|
||||
uint16_t crypto_index_mask;
|
||||
uint32_t reserved1;
|
||||
uint64_t cpu_timer;
|
||||
uint64_t clock_cmp;
|
||||
uint64_t mc_interrupt_code;
|
||||
uint64_t reserved2;
|
||||
uint32_t mc_failing_storage_addr;
|
||||
uint32_t machine_dependent_region_code;
|
||||
uint32_t lixed_logout_area[4];
|
||||
char reserved3[16];
|
||||
uint32_t acrs[16];
|
||||
uint64_t fprs[4];
|
||||
uint32_t gprs[16];
|
||||
uint32_t crs[16];
|
||||
} __packed;
|
||||
|
||||
/* Members */
|
||||
struct _fir_32 fir32Record;
|
||||
struct _fir_other_32 *fir32OtherRecords;
|
||||
};
|
||||
|
||||
#endif /* VMDUMP_H */
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* vmdump - z/VM dump conversion library
|
||||
*
|
||||
* Dump convert function: Converts VMDUMP to LKCD dump
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 "lkcd_dump.h"
|
||||
#include "vm_dump.h"
|
||||
|
||||
int vmdump_convert(const char* inputFileName, const char* outputFileName,
|
||||
const char* progName)
|
||||
{
|
||||
/* Do the conversion */
|
||||
try {
|
||||
switch(VMDump::getDumpType(inputFileName)){
|
||||
case Dump::DT_VM64_BIG:
|
||||
{
|
||||
LKCDDump64* lkcddump;
|
||||
VMDump64Big* vmdump;
|
||||
|
||||
vmdump = new VMDump64Big(inputFileName);
|
||||
vmdump->printInfo();
|
||||
lkcddump = new LKCDDump64(vmdump,
|
||||
vmdump->getRegisterContent());
|
||||
lkcddump->writeDump(outputFileName);
|
||||
delete vmdump;
|
||||
delete lkcddump;
|
||||
break;
|
||||
}
|
||||
case Dump::DT_VM64:
|
||||
{
|
||||
LKCDDump64* lkcddump;
|
||||
VMDump64* vmdump;
|
||||
|
||||
vmdump = new VMDump64(inputFileName);
|
||||
vmdump->printInfo();
|
||||
lkcddump = new LKCDDump64(vmdump,
|
||||
vmdump->getRegisterContent());
|
||||
lkcddump->writeDump(outputFileName);
|
||||
delete vmdump;
|
||||
delete lkcddump;
|
||||
break;
|
||||
}
|
||||
case Dump::DT_VM32:
|
||||
{
|
||||
LKCDDump32* lkcddump;
|
||||
VMDump32* vmdump;
|
||||
|
||||
vmdump = new VMDump32(inputFileName);
|
||||
vmdump->printInfo();
|
||||
lkcddump = new LKCDDump32(vmdump,
|
||||
vmdump->getRegisterContent());
|
||||
lkcddump->writeDump(outputFileName);
|
||||
delete vmdump;
|
||||
delete lkcddump;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw DumpException("This is not a vmdump");
|
||||
}
|
||||
} catch (DumpException ex) {
|
||||
printf("%s: %s\n", progName, ex.what());
|
||||
fflush(stdout);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -15,13 +15,13 @@ install: install-scripts
|
||||
install-scripts: $(SCRIPTS)
|
||||
@if [ ! -d $(DESTDIR)$(NETBOOT_SAMPLEDIR) ]; then \
|
||||
mkdir -p $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||
chown $(OWNER).$(GROUP) $(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; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||
done
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ WARNINGS := -Wall -Wextra -Wshadow \
|
||||
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
|
||||
-Wpointer-arith -Wno-error=inline \
|
||||
-Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \
|
||||
-Werror \
|
||||
$(NULL)
|
||||
|
||||
PVATTEST_SRCS := $(wildcard *.c) \
|
||||
@@ -29,21 +28,12 @@ $(BIN_PROGRAM)_SRCS := \
|
||||
|
||||
$(BIN_PROGRAM)_OBJS := $($(BIN_PROGRAM)_SRCS:.c=.o)
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto openssl)
|
||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto openssl)
|
||||
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
||||
else
|
||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||
GLIB2_LIBS := -lglib-2.0
|
||||
LIBCRYPTO_CFLAGS :=
|
||||
LIBCRYPTO_LIBS := -lcrypto -lssl
|
||||
LIBCURL_CFLAGS := -I/usr/include/s390x-linux-gnu
|
||||
LIBCURL_LIBS := -lcurl
|
||||
endif
|
||||
GLIB2_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||
LIBCURL_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||
|
||||
ALL_CFLAGS += -std=gnu11 \
|
||||
-DPKGDATADIR=$(PKGDATADIR) \
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
/* Must be included before any other header */
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libpv/glib-helper.h"
|
||||
#include <glib/gi18n.h>
|
||||
#include "libpv/macros.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ set -o pipefail
|
||||
set -o nounset
|
||||
set -e
|
||||
|
||||
XDUMP='od -A x -t x2z -v'
|
||||
XDUMP='od -A x -t x2z -v --endian=big'
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
|
||||
@@ -14,7 +14,7 @@ set -o pipefail
|
||||
set -o nounset
|
||||
set -e
|
||||
|
||||
XDUMP='od -A x -t x2z -v'
|
||||
XDUMP='od -A x -t x2z -v --endian=big'
|
||||
|
||||
def_output='sehdr.bin'
|
||||
def_skip=0x14
|
||||
|
||||
@@ -5,7 +5,7 @@ all:
|
||||
install: qethconf
|
||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
< qethconf >$(DESTDIR)$(BINDIR)/qethconf; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/qethconf; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/qethconf; \
|
||||
chmod 755 $(DESTDIR)$(BINDIR)/qethconf; \
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 qethconf.8 \
|
||||
|
||||
1
scripts/.gitignore
vendored
Normal file
1
scripts/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/.zfcpdbf.ct
|
||||
@@ -36,4 +36,21 @@ install:
|
||||
|
||||
clean:
|
||||
|
||||
.zfcpdbf.ct: zfcpdbf
|
||||
$(PERLC) $(ALL_PERLCFLAGS) zfcpdbf 2>$(@); \
|
||||
if [ "$${?}" -ne 0 ]; then \
|
||||
cat "$(@)" >&2 && rm "$(@)"; \
|
||||
elif [ "$$(cat '$(@)' | wc -l)" -gt 1 ]; then \
|
||||
cat "$(@)" >&2; \
|
||||
elif [ " $(V)" = " 1" ]; then \
|
||||
cat "$(@)"; \
|
||||
fi
|
||||
|
||||
.PHONY: .zfcpdbf.ct-clean
|
||||
.zfcpdbf.ct-clean:
|
||||
rm -f .zfcpdbf.ct
|
||||
|
||||
all: .zfcpdbf.ct
|
||||
clean: .zfcpdbf.ct-clean
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# dbginfo.sh - Tool to collect runtime, configuration, and trace information
|
||||
#
|
||||
# Copyright IBM Corp. 2002, 2022
|
||||
# Copyright IBM Corp. 2002, 2023
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -71,7 +71,7 @@ paramWORKDIR_BASE="/tmp" # initial default path
|
||||
print_version() {
|
||||
cat <<EOF
|
||||
${SCRIPTNAME}: Debug information script version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2002, 2022
|
||||
Copyright IBM Corp. 2002, 2023
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -409,6 +409,7 @@ CONFIGFILES="\
|
||||
/etc/multipath\
|
||||
/etc/network\
|
||||
/etc/networks\
|
||||
/etc/opencryptoki/*.conf\
|
||||
/etc/pam.d\
|
||||
/etc/profile\
|
||||
/etc/profile.d\
|
||||
@@ -513,18 +514,26 @@ CMDS="${CMDS}\
|
||||
|
||||
# crypto specific commands
|
||||
CMDS="${CMDS}\
|
||||
:cat /var/lib/opencryptoki/pk_config_data\
|
||||
:ep11info -D\
|
||||
:ep11info -H\
|
||||
:ep11info -M\
|
||||
:icainfo\
|
||||
:icastats\
|
||||
:icastats --all\
|
||||
:ivp.e # IBM CCA package install check\
|
||||
:ls -al /usr/lib64/opencryptoki/stdll\
|
||||
:lszcrypt -VV\
|
||||
:pkcsconf -mlist\
|
||||
:pkcsconf -i\
|
||||
:pkcsconf -s\
|
||||
:pkcsconf -l\
|
||||
:pkcsconf -t\
|
||||
:pkcsconf -m\
|
||||
:systemctl status pkcsslotd\
|
||||
"
|
||||
|
||||
# product / distro specific commands
|
||||
CMDS="${CMDS}\
|
||||
:java -version\
|
||||
:qemu-ga -V\
|
||||
:SPident # SLES service package\
|
||||
"
|
||||
|
||||
@@ -566,6 +575,7 @@ NETWORK_CMDS="ip -br a\
|
||||
:netstat -pantu\
|
||||
:netstat -s\
|
||||
:nm-tool\
|
||||
:nstat -az\
|
||||
:openssl engine\
|
||||
:route -n\
|
||||
"
|
||||
@@ -655,10 +665,10 @@ VM_CMDS="q userid\
|
||||
:q quickdsp VMUSERID\
|
||||
:q pcifunction\
|
||||
:q vmrelocate\
|
||||
:q syscontrol\
|
||||
:ind load\
|
||||
:ind sp\
|
||||
:ind user\
|
||||
:qemu-ga -V\
|
||||
"
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -301,6 +301,9 @@ setup_reipl()
|
||||
fi
|
||||
|
||||
case "$REIPL_TYPE" in
|
||||
eckd)
|
||||
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||
;;
|
||||
ccw)
|
||||
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||
;;
|
||||
@@ -332,6 +335,9 @@ setup_reipl()
|
||||
setup_dump()
|
||||
{
|
||||
case "$DUMP_TYPE" in
|
||||
eckd)
|
||||
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||
;;
|
||||
ccw)
|
||||
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||
;;
|
||||
@@ -408,6 +414,16 @@ print_ccw_device()
|
||||
pr_info "device..: $DEVICE"
|
||||
}
|
||||
|
||||
print_eckd_device()
|
||||
{
|
||||
DEVICE=$(cat $1/eckd/device) || RETVAL=1
|
||||
pr_info "device..: $DEVICE"
|
||||
BR_CHR=$(cat $1/eckd/br_chr) || RETVAL=1
|
||||
pr_info "br_chr..: $BR_CHR"
|
||||
BOOTPROG=$(cat $1/eckd/bootprog) || RETVAL=1
|
||||
pr_info "bootprog: $BOOTPROG"
|
||||
}
|
||||
|
||||
print_nvme_device()
|
||||
{
|
||||
FID=$(cat $1/nvme/fid) || RETVAL=1
|
||||
@@ -433,6 +449,11 @@ status_dump()
|
||||
none)
|
||||
pr_info "type....: no dump device configured"
|
||||
;;
|
||||
eckd)
|
||||
pr_info "type....: eckd"
|
||||
print_eckd_device $DUMP_CONFIG_DIR
|
||||
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/eckd/device)
|
||||
;;
|
||||
ccw)
|
||||
pr_info "type....: ccw"
|
||||
print_ccw_device $DUMP_CONFIG_DIR
|
||||
@@ -458,6 +479,9 @@ status_reipl()
|
||||
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
|
||||
pr_info "type....: $REIPL_TYPE"
|
||||
case "$REIPL_TYPE" in
|
||||
eckd)
|
||||
print_eckd_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
ccw)
|
||||
print_ccw_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
include ../common.mak
|
||||
|
||||
ALL_CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
LDLIBS += -lz
|
||||
|
||||
all: vmconvert
|
||||
|
||||
libs = $(rootdir)/libvmdump/libvmdump.a
|
||||
objects = vmconvert.o
|
||||
|
||||
vmconvert: $(objects) $(libs)
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 vmconvert \
|
||||
$(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 vmconvert.1 \
|
||||
$(DESTDIR)\$(MANDIR)/man1
|
||||
|
||||
clean:
|
||||
rm -f *.o vmconvert
|
||||
|
||||
.PHONY: all install clean
|
||||
@@ -1,36 +0,0 @@
|
||||
.\" Copyright 2017 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 VMCONVERT 1 "Apr 2006" "s390-tools"
|
||||
.SH NAME
|
||||
vmconvert \- convert VMDUMPs into lkcd dumps
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B vmconvert
|
||||
-f \fIVMDUMPFILE\fR [-o \fIOUTPUTFILE\fR] [-h] [-v]
|
||||
|
||||
.B vmconvert
|
||||
\fIVMDUMPFILE\fR [\fIOUTPUTFILE\fR]
|
||||
.SH DESCRIPTION
|
||||
.B vmconvert
|
||||
is a tool to convert VMDUMPs into lkcd dumps, which can be analyzed by Linux
|
||||
dumpanalysis tools (e.g. lcrash or crash).
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR "\-h" " or " "\-\-help"
|
||||
Print usage information, then exit.
|
||||
|
||||
.TP
|
||||
.BR "\-v" " or " "\-\-version"
|
||||
Print version information, then exit.
|
||||
|
||||
.TP
|
||||
.BR "\-f VMDUMPFILE" " or " "\-\-file=VMDUMPFILE"
|
||||
Use the specified VMDUMPFILE as input file.
|
||||
|
||||
.TP
|
||||
.BR "\-o OUTPUTFILE" " or " "\-\-output=OUTPUTFILE"
|
||||
Use the specified OUTPUTFILE as filename for the lkcd dump. The default
|
||||
filename is 'dump.lkcd'
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* vmconvert - Convert z/VM VMDUMPs into Linux lkcd dumps
|
||||
*
|
||||
* Main program
|
||||
*
|
||||
* Copyright IBM Corp. 2004, 2017
|
||||
*
|
||||
* 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 <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/vmdump.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
static struct option longopts[] = {
|
||||
{"file",required_argument,0,'f'},
|
||||
{"help",no_argument,0,'h'},
|
||||
{"version",no_argument,0,'v'},
|
||||
{"output",required_argument,0,'o'},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
#define OPTSTRING "f:o:vh"
|
||||
extern char *optarg;
|
||||
|
||||
/* Version info */
|
||||
static const char version_text[] = "vmconvert: vmdump converter tool version "\
|
||||
RELEASE_STRING;
|
||||
|
||||
/* Copyright notice */
|
||||
static const char copyright_notice[] = "Copyright IBM Corp. 2004, 2017";
|
||||
|
||||
/* Usage information */
|
||||
static const char usage_text[] = \
|
||||
"Usage: vmconvert -f VMDUMPFILE [-o OUTPUTFILE]\n" \
|
||||
" vmconvert VMDUMPFILE [OUTPUTFILE]\n" \
|
||||
"\n" \
|
||||
"Convert a vmdump into a lkcd (linux kernel crash dumps) dump.\n" \
|
||||
"\n" \
|
||||
"-h, --help Print this help, then exit.\n" \
|
||||
"-v, --version Print version information, then exit.\n" \
|
||||
"-f, --file VMDUMPFILE The vmdump file VMDUMPFILE, which should be\n"\
|
||||
" converted.\n" \
|
||||
"-o, --output OUTPUTFILE The converted lkcd dump file OUTPUTFILE.\n"\
|
||||
" The default file name is 'dump.lkcd'.\n";
|
||||
|
||||
/* Globals */
|
||||
char inputFileName[1024];
|
||||
char outputFileName[1024] = "dump.lkcd";
|
||||
|
||||
void
|
||||
parseOpts(int argc, char* argv[])
|
||||
{
|
||||
int inputFileSet = 0;
|
||||
int outputFileSet = 0;
|
||||
int c, longIndex;
|
||||
while((c = getopt_long(argc, argv, OPTSTRING, longopts,
|
||||
&longIndex)) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
strcpy(inputFileName, optarg);
|
||||
inputFileSet = 1;
|
||||
break;
|
||||
case 'o':
|
||||
strcpy(outputFileName, optarg);
|
||||
outputFileSet = 1;
|
||||
break;
|
||||
case 'h':
|
||||
printf("%s", usage_text);
|
||||
exit(0);
|
||||
case 'v':
|
||||
printf("%s\n", version_text);
|
||||
printf("%s\n", copyright_notice);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "Try 'vmconvert --help' for"
|
||||
" more information.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* check for positional parameters */
|
||||
if (optind < argc) {
|
||||
int count = 0;
|
||||
while (optind < argc){
|
||||
if(!inputFileSet && count==0){
|
||||
strcpy(inputFileName, argv[optind]);
|
||||
inputFileSet = 1;
|
||||
} else if(!outputFileSet && count==1){
|
||||
strcpy(outputFileName, argv[optind]);
|
||||
outputFileSet = 1;
|
||||
} else if(count == 2){
|
||||
printf("%s", usage_text);
|
||||
exit(0);
|
||||
}
|
||||
count++;
|
||||
optind++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!inputFileSet){
|
||||
printf("%s: input file required - use '-f' option!\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
struct stat s;
|
||||
int rc;
|
||||
|
||||
parseOpts(argc,argv);
|
||||
|
||||
/* Check if output file already exists */
|
||||
if(stat(outputFileName,&s) == 0){
|
||||
char answer[100];
|
||||
printf("%s: overwrite file '%s'? ",argv[0],outputFileName);
|
||||
if(scanf("%s",answer) != 1)
|
||||
exit(1);
|
||||
if((strcmp(answer,"y") != 0) && (strcmp(answer,"yes") != 0))
|
||||
exit(0);
|
||||
}
|
||||
rc = vmdump_convert(inputFileName, outputFileName, argv[0]);
|
||||
if (!rc)
|
||||
printf("'%s' has been written successfully.\n", outputFileName);
|
||||
return rc;
|
||||
}
|
||||
@@ -5,13 +5,12 @@ LDLIBS += -lz
|
||||
|
||||
all: vmur
|
||||
|
||||
libs = $(rootdir)/libvmdump/libvmdump.a \
|
||||
$(rootdir)/libvmcp/libvmcp.a $(rootdir)/libutil/libutil.a
|
||||
libs = $(rootdir)/libvmcp/libvmcp.a $(rootdir)/libutil/libutil.a
|
||||
|
||||
objects = vmur.o
|
||||
|
||||
vmur: $(objects) $(libs)
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRSBINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
25
vmur/vmur.8
25
vmur/vmur.8
@@ -50,7 +50,7 @@ Position a file at the top of a spool file queue
|
||||
The \*v program requires the vmcp kernel module as prerequisite.
|
||||
For the receive, punch, and print commands the vmur kernel module is also
|
||||
required, and the corresponding z/VM virtual unit record devices
|
||||
(in most cases 000c as reader, 000d as punch, and 000e as printer)
|
||||
(in most cases 000c as reader, 000d as punch, and 000e as printer)
|
||||
must be set online.
|
||||
See
|
||||
.BR chccwdev (8)
|
||||
@@ -77,7 +77,7 @@ respective command context.
|
||||
.IP "" 0
|
||||
Synopsis:
|
||||
.IP "" 2
|
||||
receive [-fH] [-d dev_node] [-C class] [-t | -b sep.pad | -c]
|
||||
receive [-fH] [-d dev_node] [-C class] [-t | -b sep.pad]
|
||||
spoolid
|
||||
[-O | outfile]
|
||||
.PP
|
||||
@@ -124,7 +124,7 @@ If omitted, /dev/vmrdr-0.0.000c is assumed.
|
||||
.IP "" 0
|
||||
\fB-t or --text\fR
|
||||
.IP "" 2
|
||||
Specifies that a text file requiring EBCDIC-to-ASCII conversion is to be
|
||||
Specifies that a text file requiring EBCDIC-to-ASCII conversion is to be
|
||||
received. Character sets IBM037 and ISO-8859-1 are used for the conversion.
|
||||
An ASCII line feed character (0x0a) is inserted for each 80-byte input
|
||||
record read from the z/VM reader. Trailing EBCDIC blanks (0x40) in the
|
||||
@@ -150,8 +150,14 @@ using the appropriate character sets, for example:
|
||||
.IP "" 0
|
||||
\fB-c or --convert\fR
|
||||
.IP "" 2
|
||||
Specifies to convert the VMDUMP spool file into a
|
||||
format appropriate for further analysis with crash or lcrash.
|
||||
Dump file conversion has been removed from
|
||||
.BR vmur (8)
|
||||
and -c is no longer a valid option.
|
||||
An error message is displayed and the program terminates.
|
||||
Use
|
||||
.BR zgetdump (8)
|
||||
to convert VMDUMP files to a format
|
||||
appropriate for further analysis with crash.
|
||||
.SP
|
||||
.IP "" 0
|
||||
\fB-O or --stdout\fR
|
||||
@@ -299,7 +305,7 @@ residual of the record is filled up with the specified padding byte.
|
||||
If a line exceeds the record length, an error is printed.
|
||||
.br
|
||||
.BR iconv (1)
|
||||
output can be piped to punch or print, for example:
|
||||
output can be piped to punch or print, for example:
|
||||
.IP "" 2
|
||||
# iconv xyz -f ISO-8859-1 -t EBCDIC-US | vmur pun -b 0x25,0x40 -N abc
|
||||
.SP
|
||||
@@ -403,7 +409,7 @@ The following command argument is supported by \fBlist\fR:
|
||||
\fBspoolid\fR
|
||||
.IP "" 2
|
||||
Identifies the z/VM spool file to be listed.
|
||||
If omitted, all spool files on the specified queue are listed
|
||||
If omitted, all spool files on the specified queue are listed
|
||||
.PD
|
||||
.IP "" 0
|
||||
.SP
|
||||
@@ -530,7 +536,7 @@ In the example below, the spool ID is 398:
|
||||
.in +0.25in
|
||||
.nf
|
||||
# vmcp sp cons clo \(rs* rdr
|
||||
RDR FILE 0398 SENT FROM LINUX025 CON WAS 0398 RECS 1872
|
||||
RDR FILE 0398 SENT FROM LINUX025 CON WAS 0398 RECS 1872
|
||||
.fi
|
||||
.in -0.25in
|
||||
.ft
|
||||
@@ -605,6 +611,7 @@ Prepare re-IPL from the z/VM reader and reboot:
|
||||
.SH "SEE ALSO"
|
||||
.BR chccwdev (8),
|
||||
.BR vmcp (8),
|
||||
.BR iconv (1)
|
||||
.BR iconv (1),
|
||||
.BR zgetdump (8)
|
||||
|
||||
.I "Linux on System z - Device Drivers, Features, and Commands"
|
||||
|
||||
@@ -77,7 +77,6 @@ struct vmur {
|
||||
int force_specified;
|
||||
int stdout_specified;
|
||||
int hold_specified;
|
||||
int convert_specified;
|
||||
enum ur_action action;
|
||||
int devno;
|
||||
int ur_reclen;
|
||||
@@ -183,8 +182,6 @@ static char HELP_TEXT[] =
|
||||
"-t, --text Indicates text data causing EBCDIC to ASCII\n"
|
||||
" conversion.\n"
|
||||
"-b, --blocked Use blocked mode.\n"
|
||||
"-c, --convert Specifies to convert VMDUMP file into a format\n"
|
||||
" appropriate for further analysis with (l)crash.\n"
|
||||
"-O, --stdout Write spool file to stdout.\n"
|
||||
"-f, --force Overwrite files without prompt.\n"
|
||||
"-H, --hold Hold spool file in reader after receive.\n"
|
||||
@@ -814,7 +811,10 @@ static void parse_opts_receive(struct vmur *info, int argc, char *argv[])
|
||||
++info->hold_specified;
|
||||
break;
|
||||
case 'c':
|
||||
++info->convert_specified;
|
||||
fprintf(stderr, "%s: Option '-c' is no longer valid. "
|
||||
"Use zgetdump for dump file conversion.\n",
|
||||
prog_name);
|
||||
std_usage_exit();
|
||||
break;
|
||||
case 'C':
|
||||
set_spool_class(info, optarg, 1);
|
||||
@@ -834,14 +834,12 @@ static void parse_opts_receive(struct vmur *info, int argc, char *argv[])
|
||||
CHECK_SPEC_MAX(info->force_specified, 1, "force");
|
||||
CHECK_SPEC_MAX(info->hold_specified, 1, "hold");
|
||||
CHECK_SPEC_MAX(info->stdout_specified, 1, "stdout");
|
||||
CHECK_SPEC_MAX(info->convert_specified, 1, "convert");
|
||||
CHECK_SPEC_MAX(info->spool_class_specified, 1, "class");
|
||||
|
||||
if (info->stdout_specified && info->file_name_specified)
|
||||
ERR_EXIT("File name not allowed, when --stdout specified!\n");
|
||||
if (info->blocked_specified + info->text_specified +
|
||||
info->convert_specified > 1)
|
||||
ERR_EXIT("Conflicting options: -b, -t and -c are mutually "
|
||||
if (info->blocked_specified + info->text_specified)
|
||||
ERR_EXIT("Conflicting options: -b and -t are mutually "
|
||||
"exclusive.\n");
|
||||
if (!info->spool_class_specified)
|
||||
set_spool_class(info, "*", 1);
|
||||
@@ -1749,25 +1747,6 @@ static void ur_receive(struct vmur *info)
|
||||
}
|
||||
|
||||
type = get_spoolfile_fmt(info, &sfdata[0]);
|
||||
if (info->convert_specified) {
|
||||
if (type != TYPE_VMDUMP) {
|
||||
ERR("Reader file %s does not have VMDUMP format, "
|
||||
"conversion not possible.\n", info->spoolid);
|
||||
goto fail;
|
||||
} else {
|
||||
close(fhi);
|
||||
if (info->stdout_specified)
|
||||
rc = vmdump_convert(info->devnode, NULL,
|
||||
prog_name);
|
||||
else
|
||||
rc = vmdump_convert(info->devnode,
|
||||
info->file_name, prog_name);
|
||||
if (rc)
|
||||
goto fail;
|
||||
else
|
||||
goto vm_convert_done;
|
||||
}
|
||||
}
|
||||
if (type == TYPE_VMDUMP)
|
||||
ERR("INFO: Reader file %s has VMDUMP format.\n", info->spoolid);
|
||||
if (type == TYPE_NETDATA)
|
||||
@@ -1819,7 +1798,6 @@ static void ur_receive(struct vmur *info)
|
||||
if (fho != STDOUT_FILENO)
|
||||
close(fho);
|
||||
close(fhi);
|
||||
vm_convert_done:
|
||||
if (info->hold_specified)
|
||||
close_reader(info, "HOLD");
|
||||
else
|
||||
@@ -25,7 +25,7 @@ install-scripts: $(SCRIPTS)
|
||||
cat $$i | \
|
||||
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
>$(DESTDIR)$(BINDIR)/$$i; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/$$i; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(BINDIR)/$$i; \
|
||||
done
|
||||
|
||||
@@ -34,15 +34,15 @@ install-usrsbin-scripts: $(USRSBIN_SCRIPTS)
|
||||
cat $$i | \
|
||||
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
>$(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(USRSBINDIR)/$$i; \
|
||||
done
|
||||
|
||||
install-manpages: $(MANPAGES)
|
||||
@if [ ! -d $(DESTDIR)$(MANDIR) ]; then \
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MANDIR); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(MANDIR)/man8; \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MANDIR); \
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(MANDIR)/man8; \
|
||||
chmod 755 $(DESTDIR)$(MANDIR); \
|
||||
chmod 755 $(DESTDIR)$(MANDIR)/man8; \
|
||||
fi; \
|
||||
@@ -59,7 +59,7 @@ endif
|
||||
|
||||
$(SUB_DIRS):
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(SUB_DIRS)
|
||||
|
||||
.PHONY: all install clean install-scripts install-manpages install-usrsbin-scripts
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
.\" chzcrypt.8
|
||||
.\"
|
||||
.\" Copyright 2020 IBM Corp.
|
||||
.\" Copyright 2020, 2023 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH CHZCRYPT 8 "OCT 2020" "s390-tools"
|
||||
.\" use
|
||||
.\" groff -man -Tutf8 chzcrypt.8
|
||||
.\" or
|
||||
.\" nroff -man chzcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
.TH CHZCRYPT 8 "MAY 2023" "s390-tools"
|
||||
.SH NAME
|
||||
chzcrypt \- modify zcrypt configuration
|
||||
.SH SYNOPSIS
|
||||
@@ -46,8 +52,8 @@ chzcrypt \- modify zcrypt configuration
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B chzcrypt
|
||||
command is used to configure cryptographic devices managed by zcrypt and
|
||||
modify zcrypt's AP bus attributes.
|
||||
command is used to configure cryptographic devices managed by zcrypt
|
||||
and modify zcrypt's AP bus attributes.
|
||||
|
||||
Attributes may vary depending on the kernel
|
||||
version.
|
||||
@@ -70,19 +76,6 @@ Set the given cryptographic card device(s) config on ('configured').
|
||||
.B --config-off
|
||||
Set the given cryptographic card device(s) config off ('deconfigured').
|
||||
.TP 8
|
||||
.B <device id>
|
||||
Specifies a cryptographic device which will be set either online or
|
||||
offline or configured on or off. For online and offline the device can
|
||||
either be a card device or a queue device. A queue device can only get
|
||||
switched online when the providing card is online.
|
||||
.br
|
||||
For config on/off the device needs to be a card device. A card or
|
||||
queue device cannot get switched online if the card is in deconfigured
|
||||
state.
|
||||
.br
|
||||
Please note that the card device and queue device representation are both
|
||||
in hexadecimal notation.
|
||||
.TP 8
|
||||
.B -p, --poll-thread-enable
|
||||
Enable zcrypt's poll thread.
|
||||
.TP 8
|
||||
@@ -94,15 +87,28 @@ Set configuration timer for re-scanning the AP bus to
|
||||
.I <timeout>
|
||||
seconds.
|
||||
.TP 8
|
||||
.B --se-associate <association-index> <queue-device>
|
||||
Associate the given queue device with the given association
|
||||
index. This command is only valid within an Secure Execution guest
|
||||
with AP pass-through support enabled.
|
||||
.TP 8
|
||||
.B --se-bind <queue-device>
|
||||
Bind the given queue device. This command is only valid within an
|
||||
Secure Execution guest with AP pass-through support enabled.
|
||||
.TP 8
|
||||
.B --se-unbind <queue-device>
|
||||
Unbind the given queue device. This command is only valid within an
|
||||
Secure Execution guest with AP pass-through support enabled.
|
||||
.TP 8
|
||||
.BI "-t, --poll-timeout" " <poll_timeout>"
|
||||
Set poll timer to run poll tasklet all
|
||||
.I <poll_timeout>
|
||||
nanoseconds.
|
||||
.TP 8
|
||||
.BI "-q, --default-domain" " <domain>"
|
||||
Set the new default domain of the AP bus to <domain>.
|
||||
The number of available domains can be retrieved with the lszcrypt
|
||||
command ('-d' option).
|
||||
Set the new default domain of the AP bus to <domain>. The number of
|
||||
available domains can be retrieved with the lszcrypt command ('-d'
|
||||
option).
|
||||
.TP 8
|
||||
.B -V, --verbose
|
||||
Print verbose messages.
|
||||
@@ -112,6 +118,22 @@ Print help text and exit.
|
||||
.TP 8
|
||||
.B -v, --version
|
||||
Print version information and exit.
|
||||
.TP 8
|
||||
.B <device id>
|
||||
Specifies a cryptographic device which will be set either online or
|
||||
offline or configured on or off. For online and offline the device can
|
||||
either be a card device or a queue device. A queue device can only get
|
||||
switched online when the providing card is online.
|
||||
.br
|
||||
For config on/off the device needs to be a card device. A card or
|
||||
queue device cannot get switched online if the card is in deconfigured
|
||||
state.
|
||||
.br
|
||||
Please note that the card device and queue device representation are
|
||||
both in hexadecimal notation.
|
||||
.TP 8
|
||||
.B <queue-device>
|
||||
An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B chzcrypt -e 0 1 12
|
||||
@@ -131,8 +153,8 @@ Set all available crypto cards to config on, be verbose.
|
||||
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
|
||||
.TP
|
||||
.B chzcrypt -c 60 -n
|
||||
Will set configuration timer for re-scanning the AP bus to 60 seconds and
|
||||
disable zcrypt's poll thread.
|
||||
Will set configuration timer for re-scanning the AP bus to 60 seconds
|
||||
and disable zcrypt's poll thread.
|
||||
.TP
|
||||
.B chzcrypt -q 67
|
||||
Will set the default domain to 67.
|
||||
@@ -144,5 +166,11 @@ chzcrypt exits with an appropriate message. Even more config on/off
|
||||
may require support from a hypervisor like KVM or zVM and may fail if
|
||||
the Linux kernel is unable to perform the SCLP command. Check syslog
|
||||
on failure.
|
||||
.TP
|
||||
Bind, associate and unbind command on an queue device are only
|
||||
available and valid within an Secure Execution environment with AP
|
||||
pass-through enabled and a Linux kernel providing the low level sysfs
|
||||
API. If these conditions are not fulfilled, the command will fail with
|
||||
an appropriate error messages.
|
||||
.SH SEE ALSO
|
||||
\fBlszcrypt\fR(8)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* chzcrypt - Tool to modify zcrypt configuration
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2020
|
||||
* Copyright IBM Corp. 2008, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -28,6 +28,12 @@
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
/* max seconds the se-association command will wait for completion */
|
||||
#define MAX_ASSOC_POLL_TIME_IN_S 30
|
||||
|
||||
/* max seconds the se-unbind command will wait for unbind complete */
|
||||
#define MAX_UNBIND_POLL_TIME_IN_S 30
|
||||
|
||||
/*
|
||||
* Private data
|
||||
*/
|
||||
@@ -45,7 +51,7 @@ static const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
.pub_last = 2020,
|
||||
.pub_last = 2023,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -57,6 +63,9 @@ static const struct util_prg prg = {
|
||||
|
||||
#define OPT_CONFIG_ON 0x80
|
||||
#define OPT_CONFIG_OFF 0x81
|
||||
#define OPT_SE_ASSOC 0x82
|
||||
#define OPT_SE_BIND 0x83
|
||||
#define OPT_SE_UNBIND 0x84
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
{
|
||||
@@ -116,6 +125,22 @@ static struct util_opt opt_vec[] = {
|
||||
.option = { "verbose", no_argument, NULL, 'V'},
|
||||
.desc = "Print verbose messages",
|
||||
},
|
||||
{
|
||||
.option = { "se-associate", required_argument, NULL, OPT_SE_ASSOC},
|
||||
.argument = "assoc_idx",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "SE guest with AP support only: Associate the given queue device",
|
||||
},
|
||||
{
|
||||
.option = { "se-bind", no_argument, NULL, OPT_SE_BIND},
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "SE guest with AP support only: Bind the given queue device",
|
||||
},
|
||||
{
|
||||
.option = { "se-unbind", no_argument, NULL, OPT_SE_UNBIND},
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "SE guest with AP support only: Unbind the given queue device",
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
@@ -336,6 +361,186 @@ next:
|
||||
}
|
||||
}
|
||||
|
||||
static void se_assoc(const char *assoc_idx, const char *dev)
|
||||
{
|
||||
int i, idx, rc, ap, dom, loop;
|
||||
char *dev_path, *attr;
|
||||
char buf[256];
|
||||
|
||||
if (!ap_bus_has_SB_support())
|
||||
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
||||
|
||||
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
||||
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
||||
dev);
|
||||
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
||||
ap, ap, dom);
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
||||
dev);
|
||||
|
||||
if (sscanf(assoc_idx, "%i", &idx) != 1)
|
||||
errx(EXIT_FAILURE, "Error - Can't parse association index '%s' as number.",
|
||||
assoc_idx);
|
||||
if (idx < 0 || idx > 0xFFFF)
|
||||
errx(EXIT_FAILURE, "Error - Association index needs to be in range [0...%d].",
|
||||
0xffff);
|
||||
|
||||
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_associate",
|
||||
ap, ap, dom);
|
||||
if (!util_path_is_writable(attr))
|
||||
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
|
||||
/* read se_associate attribute and check for 'unassociated' */
|
||||
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
if (strcmp(buf, "unassociated"))
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Queue device %s is NOT in 'unassociated' state (state '%s' found).",
|
||||
dev, buf);
|
||||
|
||||
/* write assocition index to the se_associate attribute */
|
||||
rc = util_file_write_l(idx, 10, attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
|
||||
/* loop up to MAX_ASSOC_POLL_TIME_IN_S seconds for completion */
|
||||
for (loop = 0; loop < 2 * MAX_ASSOC_POLL_TIME_IN_S; usleep(500000), loop++) {
|
||||
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
if (!strncmp(buf, "associated", strlen("associated")))
|
||||
break;
|
||||
if (!strcmp(buf, "unassociated"))
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Failure associating queue device %s (state '%s' found).",
|
||||
dev, buf);
|
||||
}
|
||||
if (loop >= 2 * MAX_ASSOC_POLL_TIME_IN_S)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Failure associating queue device %s (timeout after %d s).",
|
||||
dev, MAX_ASSOC_POLL_TIME_IN_S);
|
||||
|
||||
if (sscanf(buf, "associated %d", &i) != 1 || idx != i)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Failure associating queue device %s (state '%s' found).",
|
||||
dev, buf);
|
||||
|
||||
verbose("Queue device %s successful associated with index %d.\n",
|
||||
dev, idx);
|
||||
|
||||
free(dev_path);
|
||||
free(attr);
|
||||
}
|
||||
|
||||
static void se_bind(const char *dev)
|
||||
{
|
||||
char *dev_path, *attr;
|
||||
int rc, ap, dom;
|
||||
char buf[256];
|
||||
|
||||
if (!ap_bus_has_SB_support())
|
||||
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
||||
|
||||
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
||||
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
||||
dev);
|
||||
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
||||
ap, ap, dom);
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
||||
dev);
|
||||
|
||||
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
|
||||
ap, ap, dom);
|
||||
if (!util_path_is_writable(attr))
|
||||
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
|
||||
/* read se_bind attribute and check for 'unboud' */
|
||||
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
if (strcmp(buf, "unbound"))
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Queue device %s is NOT in 'unbound' state (state '%s' found).",
|
||||
dev, buf);
|
||||
|
||||
/* write se_bind attribute, check for 'bound' afterwards */
|
||||
rc = util_file_write_l(1, 10, attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
if (strcmp(buf, "bound"))
|
||||
errx(EXIT_FAILURE, "Error - Failure binding queue device %s (state '%s' found).",
|
||||
dev, buf);
|
||||
|
||||
verbose("Queue device %s successful bound.\n", dev);
|
||||
|
||||
free(dev_path);
|
||||
free(attr);
|
||||
}
|
||||
|
||||
static void se_unbind(const char *dev)
|
||||
{
|
||||
int rc, ap, dom, loop;
|
||||
char *dev_path, *attr;
|
||||
char buf[256];
|
||||
|
||||
if (!ap_bus_has_SB_support())
|
||||
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
||||
|
||||
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
||||
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
||||
dev);
|
||||
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
||||
ap, ap, dom);
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
||||
dev);
|
||||
|
||||
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
|
||||
ap, ap, dom);
|
||||
if (!util_path_is_writable(attr))
|
||||
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
|
||||
/* write se_bind attribute */
|
||||
rc = util_file_write_l(0, 10, attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
|
||||
/* loop up to MAX_UNBIND_POLL_TIME_IN_S seconds for completion */
|
||||
for (loop = 0; loop < 2 * MAX_UNBIND_POLL_TIME_IN_S; usleep(500000), loop++) {
|
||||
rc = util_file_read_line(buf, sizeof(buf), attr);
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
||||
attr, strerror(errno));
|
||||
if (!strcmp(buf, "unbound"))
|
||||
break;
|
||||
}
|
||||
if (loop >= 2 * MAX_UNBIND_POLL_TIME_IN_S)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Failure unbinding queue device %s (timeout after %d s).",
|
||||
dev, MAX_UNBIND_POLL_TIME_IN_S);
|
||||
|
||||
verbose("Queue device %s successful unbound.\n", dev);
|
||||
|
||||
free(dev_path);
|
||||
free(attr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print invalid commandline error message and then exit with error code
|
||||
*/
|
||||
@@ -389,10 +594,10 @@ static void print_adapter_id_help(void)
|
||||
printf("DEVICE_IDS\n");
|
||||
printf(" List of cryptographic device ids separated by blanks which will be set\n");
|
||||
printf(" online/offline. Must be used in conjunction with the enable or disable option.\n");
|
||||
|
||||
printf(" DEVICE_ID could either be card device id ('<card-id>') or queue device id\n");
|
||||
printf(" '<card-id>.<domain-id>').\n");
|
||||
printf(" \n");
|
||||
printf(" '<card-id>.<domain-id>').\n\n");
|
||||
printf("QUEUE_DEVICE:\n");
|
||||
printf(" An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.\n\n");
|
||||
printf("EXAMPLE:\n");
|
||||
printf(" Disable the cryptographic device with card id '02' (inclusive all queues).\n");
|
||||
printf(" #>chzcrypt -d 02\n");
|
||||
@@ -407,13 +612,14 @@ static void print_adapter_id_help(void)
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
||||
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
|
||||
const char *config_time = NULL, *poll_timeout = NULL;
|
||||
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
||||
const char *queue_device = NULL, *assoc_idx = NULL;
|
||||
int c, i, j, action = 0;
|
||||
char *path, *dev_list;
|
||||
bool all = false, actionset = false;
|
||||
bool all = false;
|
||||
size_t len;
|
||||
int c, i, j;
|
||||
|
||||
for (i=0; i < argc; i++)
|
||||
for (j=2; j < (int) strlen(argv[i]); j++)
|
||||
@@ -428,12 +634,12 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
switch (c) {
|
||||
case 'e':
|
||||
actionset = true;
|
||||
action = c;
|
||||
online = "1";
|
||||
online_text = "online";
|
||||
break;
|
||||
case 'd':
|
||||
actionset = true;
|
||||
action = c;
|
||||
online = "0";
|
||||
online_text = "offline";
|
||||
break;
|
||||
@@ -441,23 +647,23 @@ int main(int argc, char *argv[])
|
||||
all = true;
|
||||
break;
|
||||
case 'p':
|
||||
actionset = true;
|
||||
action = c;
|
||||
poll_thread = "1";
|
||||
break;
|
||||
case 'n':
|
||||
actionset = true;
|
||||
action = c;
|
||||
poll_thread = "0";
|
||||
break;
|
||||
case 'c':
|
||||
actionset = true;
|
||||
action = c;
|
||||
config_time = optarg;
|
||||
break;
|
||||
case 't':
|
||||
actionset = true;
|
||||
action = c;
|
||||
poll_timeout = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
actionset = true;
|
||||
action = c;
|
||||
default_domain = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
@@ -472,21 +678,31 @@ int main(int argc, char *argv[])
|
||||
util_prg_print_version();
|
||||
return EXIT_SUCCESS;
|
||||
case OPT_CONFIG_ON:
|
||||
actionset = true;
|
||||
action = c;
|
||||
config = "1";
|
||||
config_text = "config on";
|
||||
break;
|
||||
case OPT_CONFIG_OFF:
|
||||
actionset = true;
|
||||
action = c;
|
||||
config = "0";
|
||||
config_text = "config off";
|
||||
break;
|
||||
case OPT_SE_ASSOC:
|
||||
action = c;
|
||||
assoc_idx = optarg;
|
||||
break;
|
||||
case OPT_SE_BIND:
|
||||
action = c;
|
||||
break;
|
||||
case OPT_SE_UNBIND:
|
||||
action = c;
|
||||
break;
|
||||
default:
|
||||
util_opt_print_parse_error(c, argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (!actionset)
|
||||
if (!action)
|
||||
invalid_cmdline_exit("Error - missing argument.\n");
|
||||
path = util_path_sysfs("bus/ap");
|
||||
if (!util_path_is_dir(path))
|
||||
@@ -508,6 +724,32 @@ int main(int argc, char *argv[])
|
||||
default_domain_set(default_domain);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (action == OPT_SE_ASSOC) {
|
||||
if (optind >= argc)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - The --se-associate needs a queue device given.");
|
||||
queue_device = argv[optind];
|
||||
se_assoc(assoc_idx, queue_device);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (action == OPT_SE_BIND) {
|
||||
if (optind >= argc)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - The --se-bind needs a queue device given.");
|
||||
queue_device = argv[optind];
|
||||
se_bind(queue_device);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (action == OPT_SE_UNBIND) {
|
||||
if (optind >= argc)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - The --se-unbind needs a queue device given.");
|
||||
queue_device = argv[optind];
|
||||
se_unbind(queue_device);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (all)
|
||||
dev_list_all(&dev_list, &len);
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" lszcrypt.8
|
||||
.\"
|
||||
.\" Copyright IBM Corp. 2019, 2022
|
||||
.\" Copyright IBM Corp. 2019, 2023
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
@@ -10,7 +10,7 @@
|
||||
.\" nroff -man lszcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
.TH LSZCRYPT 8 "FEB 2022" "s390-tools"
|
||||
.TH LSZCRYPT 8 "MAY 2023" "s390-tools"
|
||||
.SH NAME
|
||||
lszcrypt \- display zcrypt device and configuration information
|
||||
.SH SYNOPSIS
|
||||
@@ -24,7 +24,7 @@ lszcrypt \- display zcrypt device and configuration information
|
||||
.TP
|
||||
.B lszcrypt
|
||||
.B -c
|
||||
<card-id>
|
||||
<device-id>
|
||||
.TP
|
||||
.B lszcrypt -b
|
||||
.TP
|
||||
@@ -41,43 +41,60 @@ lszcrypt \- display zcrypt device and configuration information
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B lszcrypt
|
||||
command is used to display information about cryptographic devices managed by
|
||||
zcrypt and the AP bus attributes of zcrypt. Displayed information depends on the
|
||||
kernel version.
|
||||
command is used to display information about cryptographic devices
|
||||
managed by zcrypt and the AP bus attributes of zcrypt. Displayed
|
||||
information depends on the kernel version.
|
||||
.B lszcrypt
|
||||
requires that sysfs is mounted.
|
||||
.P
|
||||
The following information can be displayed for each cryptographic
|
||||
device: card ID, domain ID, card type (symbolic), mode, online status,
|
||||
hardware card type (numeric), installed function facilities, card capability,
|
||||
hardware queue depth, request count, number of requests in hardware queue, and
|
||||
the number of outstanding requests.
|
||||
The following AP bus attributes can be displayed: AP domain, Max AP domain,
|
||||
configuration timer, poll thread status, poll timeout, and AP interrupt
|
||||
status.
|
||||
hardware card type (numeric), installed function facilities, card
|
||||
capability, hardware queue depth, request count, number of requests in
|
||||
hardware queue, and the number of outstanding requests. The following
|
||||
AP bus attributes can be displayed: AP domain, Max AP domain,
|
||||
configuration timer, poll thread status, poll timeout, and AP
|
||||
interrupt status.
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
.B -V, --verbose
|
||||
The verbose level for cryptographic device information.
|
||||
With this verbose level additional information like hardware card type,
|
||||
hardware queue depth, pending requests count, installed function
|
||||
facilities and driver binding is displayed.
|
||||
The verbose level for cryptographic device information. With this
|
||||
verbose level additional information like hardware card type, hardware
|
||||
queue depth, pending requests count, installed function facilities and
|
||||
driver binding is displayed.
|
||||
.TP 8
|
||||
.B <device-id>
|
||||
Specifies a cryptographic device to display. A cryptographic device can be
|
||||
either a card device or a queue device. If no devices are specified information
|
||||
about all available devices is displayed.
|
||||
Specifies a cryptographic device to display. A cryptographic device
|
||||
can be either a card device or a queue device. If no devices are
|
||||
specified information about all available devices is displayed.
|
||||
Please note that the card device representation and the queue device
|
||||
are both in hexadecimal notation.
|
||||
.TP 8
|
||||
.B -b, --bus
|
||||
Displays the AP bus attributes and exits.
|
||||
|
||||
There is also a list of AP bus features shown here:
|
||||
.RS
|
||||
.IP "o" 3
|
||||
APSC - Extended TAPQ (Test AP Queue) support.
|
||||
.IP "o"
|
||||
APXA - Support for more than 16 domains per card.
|
||||
.IP "o"
|
||||
QACT - QACT support for toleration of new unknown crypto cards.
|
||||
.IP "o"
|
||||
RC8A - Firmware reports 0x8A instead of 0x42 on some error conditions.
|
||||
.IP "o"
|
||||
APSB - AP bus has Secure Execution AP pass-through support.
|
||||
.RE
|
||||
.TP 8
|
||||
.B -c, --capability <card-id>
|
||||
Shows the capabilities of a cryptographic card device of hardware type 6 or
|
||||
higher. The card device id value may be given as decimal or hex value (with
|
||||
a leading 0x). The capabilities of a cryptographic card device depend on
|
||||
the card type and the installed function facilities. A cryptographic card
|
||||
.B -c, --capability <device-id>
|
||||
Shows the capabilities of a cryptographic card or queue device of
|
||||
hardware type 6 or higher. A card device id value may be given as
|
||||
decimal or hex value (with a leading 0x), a queue device needs to be
|
||||
given as xy.abcd (as it is displayed by lszcrypt).
|
||||
|
||||
The capabilities of a cryptographic card device depend on the card
|
||||
type and the installed function facilities. A cryptographic card
|
||||
device can provide one or more of the following capabilities:
|
||||
.RS
|
||||
.IP "o" 3
|
||||
@@ -94,14 +111,25 @@ Long RNG
|
||||
|
||||
.RS 8
|
||||
The CCA Secure Key capability may be limited by a hypervisor
|
||||
layer. The remarks 'full function set' or 'restricted function set' may
|
||||
reflect this. For details about these limitations please check the
|
||||
layer. The remarks 'full function set' or 'restricted function set'
|
||||
may reflect this. For details about these limitations please check the
|
||||
hypervisor documentation.
|
||||
.RE
|
||||
|
||||
.RS 8
|
||||
The capabilities of a cryptographic queue device may vary depending
|
||||
on some state or environment. However if a queue device is given here,
|
||||
and the runtime environment is a KVM guest in Secure Execution mode
|
||||
with AP pass-through support, then the AP queue bind state and AP
|
||||
queue association state is shown here. Furthermore the state(s) and
|
||||
mkvp(s) (Master Key Verification Pattern) of the current master WK
|
||||
(Wrapping Key - EP11 mode) or current master AES, APKA and ASYM (CCA
|
||||
mode) are shown here.
|
||||
.RE
|
||||
.TP 8
|
||||
.B -d, --domains
|
||||
Shows the usage and control domains of the cryptographic devices.
|
||||
The displayed domains of the cryptographic device depends on the initial
|
||||
Shows the usage and control domains of the cryptographic devices. The
|
||||
displayed domains of the cryptographic device depends on the initial
|
||||
cryptographic configuration.
|
||||
.RS
|
||||
.IP "o" 3
|
||||
@@ -140,18 +168,20 @@ Here is an explanation of the columns displayed. Please note that some
|
||||
of the columns show up in verbose mode only.
|
||||
.TP
|
||||
.B CARD.DOM
|
||||
The crypto card number in hexadecimal for a crypto card line or
|
||||
the crypto card number and the domain id both in hex separated by a single
|
||||
The crypto card number in hexadecimal for a crypto card line or the
|
||||
crypto card number and the domain id both in hex separated by a single
|
||||
dot for a queue line.
|
||||
.TP
|
||||
.B TYPE and HWTYPE
|
||||
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
||||
device driver presumes that this crypto card is. The currently known values
|
||||
are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7 and 14=CEX8.
|
||||
The HWTYPE is a numeric value showing which type of hardware the
|
||||
zcrypt device driver presumes that this crypto card is. The currently
|
||||
known values are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5, 12=CEX6, 13=CEX7
|
||||
and 14=CEX8.
|
||||
.br
|
||||
The TYPE is a human readable value showing the hardware type and the basic
|
||||
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
||||
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
||||
The TYPE is a human readable value showing the hardware type and the
|
||||
basic function type (A=Accelerator, C=CCA Coprocessor, P=EP11
|
||||
Coprocessor). So for example CEX6P means a CEX6 card in EP11
|
||||
Coprocessor mode.
|
||||
.TP
|
||||
.B MODE
|
||||
A crypto card can be configured to run into one of 3 modes:
|
||||
@@ -170,13 +200,13 @@ online/offline state is kept by the zcrypt device driver and can be
|
||||
switched on or off with the help of the chzcrypt application.
|
||||
.br
|
||||
A crypto card can also be 'configured' or 'deconfigured'. This state
|
||||
may be adjusted on the HMC or SE. The chzcrypt application can also
|
||||
trigger this state with the --config-on and --config-off options.
|
||||
may be adjusted on the HMC. The chzcrypt application can also trigger
|
||||
this state with the --config-on and --config-off options.
|
||||
.br
|
||||
lszcrypt shows 'online' when a card or queue is available for
|
||||
cryptographic operations. 'offline' is displayed when a card or queue
|
||||
is switched to (software) offline. If a card is 'deconfigured' via
|
||||
HMC, SE or chzcrypt the field shows 'deconfig'.
|
||||
HMC or chzcrypt the field shows 'deconfig'.
|
||||
.br
|
||||
A crypto card may also reach a 'checkstopped' state. lszcrypt shows
|
||||
this as 'chkstop'.
|
||||
@@ -184,21 +214,22 @@ this as 'chkstop'.
|
||||
If a queue is not bound to a device driver there is no detailed
|
||||
information available and thus the status shows only '-'.
|
||||
.br
|
||||
If a queue is bound to the vfio-ap device driver it is up to this driver
|
||||
to give some status information and what exactly this means. So lszcrypt
|
||||
shows the text retrieved from the underlying sysfs attribute here.
|
||||
If a queue is bound to the vfio-ap device driver it is up to this
|
||||
driver to give some status information and what exactly this means. So
|
||||
lszcrypt shows the text retrieved from the underlying sysfs attribute
|
||||
here.
|
||||
.TP
|
||||
.B REQUESTS
|
||||
This is the counter value of successful processed requests on card or queue
|
||||
level. Successful here means the request was processed without any failure
|
||||
in the whole processing chain.
|
||||
This is the counter value of successful processed requests on card or
|
||||
queue level. Successful here means the request was processed without
|
||||
any failure in the whole processing chain.
|
||||
.TP
|
||||
.B PENDING
|
||||
The underlying firmware and hardware layer usually provide some queuing
|
||||
space for requests. When this queue is already filled up, the zcrypt device
|
||||
driver maintains a software queue of pending requests. The sum of these
|
||||
both values is displayed here and shows the amount of requests waiting for
|
||||
processing on card or queue level.
|
||||
The underlying firmware and hardware layer usually provide some
|
||||
queuing space for requests. When this queue is already filled up, the
|
||||
zcrypt device driver maintains a software queue of pending
|
||||
requests. The sum of these both values is displayed here and shows the
|
||||
amount of requests waiting for processing on card or queue level.
|
||||
.TP
|
||||
.B FUNCTIONS
|
||||
This column shows firmware and hardware function details:
|
||||
@@ -218,52 +249,70 @@ X - Card/queue is providing EP11 functions (this is the EP11 Coprocessor mode).
|
||||
.br
|
||||
N - APXA available (ability to address more than 16 crypto cards and domains).
|
||||
.br
|
||||
H - Hardware support for stateless filtering available.
|
||||
.br
|
||||
F - Full function support (opposed to restricted function support, see below).
|
||||
.br
|
||||
R - Restricted function support. The F and R flag both reflect if a
|
||||
hypervisor is somehow restricting this crypto resource in a virtual
|
||||
environment. Dependent on the hypervisor configuration the crypto requests
|
||||
may be filtered by the hypervisor to allow only a subset of functions
|
||||
within the virtual runtime environment. For example a shared CCA
|
||||
Coprocessor may be restricted by the hypervisor to allow only clear key
|
||||
operations within the guests.
|
||||
environment. Dependent on the hypervisor configuration the crypto
|
||||
requests may be filtered by the hypervisor to allow only a subset of
|
||||
functions within the virtual runtime environment. For example a shared
|
||||
CCA Coprocessor may be restricted by the hypervisor to allow only
|
||||
clear key operations within the guests.
|
||||
.TP
|
||||
.B DRIVER
|
||||
.br
|
||||
Shows which card or queue device driver currently handles this crypto
|
||||
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX8
|
||||
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
||||
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
|
||||
for use by kvm hypervisor for kvm guests and not accessible to host
|
||||
applications). It is also valid to have no driver handling a queue which is
|
||||
shown as a -no-driver- entry.
|
||||
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue
|
||||
reserved for use by KVM hypervisor for KVM guests and not accessible
|
||||
to host applications). It is also valid to have no driver handling a
|
||||
queue which is shown as a -no-driver- entry.
|
||||
.TP
|
||||
.B SESTAT
|
||||
.br
|
||||
Shows the state of the BS bits associated with every AP queue within a
|
||||
Secure Execution guest when AP Pass-through support is available:
|
||||
.br
|
||||
usable - AP queue is usable for crypto load.
|
||||
.br
|
||||
bound - AP queue is bound but not yet associated.
|
||||
.br
|
||||
unbound - AP queue is unbound and needs to get bound to this Secure
|
||||
Execution guest.
|
||||
.br
|
||||
illicit - AP queue is not available for this Secure Execution guest.
|
||||
.SH NOTES
|
||||
Use only one of the mode filtering options --accelonly, --ccaonly, --ep11only.
|
||||
Same with card/queue filtering: Use only one of --cardonly, --queueonly.
|
||||
However, one of the mode filtering options and one of the card/queue filtering
|
||||
can be combined.
|
||||
Use only one of the mode filtering options --accelonly, --ccaonly,
|
||||
--ep11only. Same with card/queue filtering: Use only one of
|
||||
--cardonly, --queueonly. However, one of the mode filtering options
|
||||
and one of the card/queue filtering can be combined.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B lszcrypt
|
||||
Displays the card/domain ID, card type (short name), mode (long name), online
|
||||
status and request count of all available cryptographic devices.
|
||||
Displays the card/domain ID, card type (short name), mode (long name),
|
||||
online status and request count of all available cryptographic
|
||||
devices.
|
||||
.TP
|
||||
.B lszcrypt 1 3 5
|
||||
Displays the card/domain ID, card type, mode, online status and request count
|
||||
for cryptographic devices 1, 3, and 5.
|
||||
Displays the card/domain ID, card type, mode, online status and
|
||||
request count for cryptographic devices 1, 3, and 5.
|
||||
.TP
|
||||
.B lszcrypt -V 3 7 11
|
||||
Displays the card/domain ID, card type, mode, online status, request count,
|
||||
number of requests in the hardware queue, number of outstanding requests and
|
||||
installed function facilities for cryptographic devices 3, 7 and 17 (0x11).
|
||||
Displays the card/domain ID, card type, mode, online status, request
|
||||
count, number of requests in the hardware queue, number of outstanding
|
||||
requests and installed function facilities for cryptographic devices
|
||||
3, 7 and 17 (0x11).
|
||||
.TP
|
||||
.B lszcrypt 10.0038
|
||||
Displays information of the cryptographic device '10.0038' respectively card
|
||||
id 16 (0x10) with domain 56 (0x38).
|
||||
Displays information of the cryptographic device '10.0038'
|
||||
respectively card id 16 (0x10) with domain 56 (0x38).
|
||||
.TP
|
||||
.B lszcrypt .0038
|
||||
Displays information of all available queue devices (potentially multiple
|
||||
adapters) with domain 56 (0x38).
|
||||
Displays information of all available queue devices (potentially
|
||||
multiple adapters) with domain 56 (0x38).
|
||||
.TP
|
||||
.B lszcrypt -b
|
||||
Displays AP bus information.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* lszcrypt - Display zcrypt devices and configuration settings
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2022
|
||||
* Copyright IBM Corp. 2008, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -45,15 +45,17 @@ static struct lszcrypt_l {
|
||||
#define CAP_RNG "Long RNG"
|
||||
#define CAP_EP11 "EP11 Secure Key"
|
||||
#define CAP_APMMS "AP bus max message size limit %ld Kb"
|
||||
#define CAP_HSL "Hardware support for stateless filtering"
|
||||
|
||||
/*
|
||||
* Card types
|
||||
* Card types and other feature masks
|
||||
*/
|
||||
#define MASK_APSC 0x80000000
|
||||
#define MASK_RSA4K 0x60000000
|
||||
#define MASK_COPRO 0x10000000
|
||||
#define MASK_ACCEL 0x08000000
|
||||
#define MASK_EP11 0x04000000
|
||||
#define MASK_HSL 0x01000000
|
||||
|
||||
/*
|
||||
* Classification
|
||||
@@ -66,22 +68,25 @@ static struct lszcrypt_l {
|
||||
/*
|
||||
* facility bits
|
||||
*/
|
||||
#define MAX_FAC_BITS 9
|
||||
#define MAX_FAC_BITS 10
|
||||
static struct fac_bits_s {
|
||||
int mask;
|
||||
char c;
|
||||
} fac_bits[MAX_FAC_BITS] = {
|
||||
{ 0x80000000, 'S' },
|
||||
{ 0x40000000, 'M' },
|
||||
{ 0x20000000, 'C' },
|
||||
{ 0x10000000, 'D' },
|
||||
{ 0x08000000, 'A' },
|
||||
{ 0x04000000, 'X' },
|
||||
{ 0x02000000, 'N' },
|
||||
{ 0x00800000, 'F' },
|
||||
{ 0x00400000, 'R' },
|
||||
{ 0x80000000, 'S' }, /* bit 0 */
|
||||
{ 0x40000000, 'M' }, /* bit 1 */
|
||||
{ 0x20000000, 'C' }, /* bit 2 */
|
||||
{ 0x10000000, 'D' }, /* bit 3, cca mode */
|
||||
{ 0x08000000, 'A' }, /* bit 4, accel mode */
|
||||
{ 0x04000000, 'X' }, /* bit 5, ep11 mode */
|
||||
{ 0x02000000, 'N' }, /* bit 6, apxa */
|
||||
{ 0x01000000, 'H' }, /* bit 7, stateless filtering by hardware */
|
||||
{ 0x00800000, 'F' }, /* bit 8, full function set */
|
||||
{ 0x00400000, 'R' }, /* bit 9, restricted function set */
|
||||
};
|
||||
|
||||
#define EXTRACT_BS_BITS(f) (((f) & 0x0000c000UL) >> 14)
|
||||
|
||||
/*
|
||||
* Program configuration
|
||||
*/
|
||||
@@ -92,7 +97,7 @@ static const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
.pub_last = 2020,
|
||||
.pub_last = 2023,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -166,8 +171,9 @@ static struct util_opt opt_vec[] = {
|
||||
static void show_bus(void)
|
||||
{
|
||||
long domain, max_domain, config_time, value;
|
||||
unsigned long long poll_timeout;
|
||||
const char *poll_thread, *ap_interrupts;
|
||||
unsigned long long poll_timeout;
|
||||
char features[256];
|
||||
char *ap;
|
||||
|
||||
/* check if ap driver is available */
|
||||
@@ -175,6 +181,10 @@ static void show_bus(void)
|
||||
if (!util_path_is_dir(ap))
|
||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||
|
||||
if (util_path_is_readable("%s/features", ap))
|
||||
util_file_read_line(features, sizeof(features), "%s/features", ap);
|
||||
else
|
||||
features[0] = '\0';
|
||||
util_file_read_l(&domain, 10, "%s/ap_domain", ap);
|
||||
util_file_read_l(&max_domain, 10, "%s/ap_max_domain_id", ap);
|
||||
util_file_read_l(&config_time, 10, "%s/config_time", ap);
|
||||
@@ -189,6 +199,8 @@ static void show_bus(void)
|
||||
ap_interrupts = "enabled";
|
||||
else
|
||||
ap_interrupts = "disabled";
|
||||
if (features[0])
|
||||
printf("features: %s\n", features);
|
||||
printf("ap_domain=0x%lx\n", domain);
|
||||
printf("ap_max_domain_id=0x%lx\n", max_domain);
|
||||
if (util_path_is_reg_file("%s/ap_interrupts", ap))
|
||||
@@ -371,23 +383,15 @@ next:
|
||||
}
|
||||
|
||||
/*
|
||||
* Show capability
|
||||
* Show card capability
|
||||
*/
|
||||
static void show_capability(const char *id_str)
|
||||
static void show_card_capability(int id)
|
||||
{
|
||||
unsigned long func_val;
|
||||
long hwtype, id, max_msg_size;
|
||||
char *p, *ap, *dev, card[16], cbuf[256];
|
||||
long hwtype, max_msg_size;
|
||||
char *dev, card[16], cbuf[256];
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
if (!util_path_is_dir(ap))
|
||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||
|
||||
id = strtol(id_str, &p, 0);
|
||||
if (id < 0 || id > 255 || p == id_str || *p != '\0')
|
||||
errx(EXIT_FAILURE, "Error - '%s' is an invalid cryptographic device id.", id_str);
|
||||
snprintf(card, sizeof(card), "card%02lx", id);
|
||||
snprintf(card, sizeof(card), "card%02x", id);
|
||||
dev = util_path_sysfs("devices/ap/%s", card);
|
||||
if (!util_path_is_dir(dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", card);
|
||||
@@ -444,6 +448,8 @@ static void show_capability(const char *id_str)
|
||||
printf("%s (%s)\n", CAP_CCA, cbuf);
|
||||
else
|
||||
printf("%s\n", CAP_CCA);
|
||||
if (func_val & MASK_HSL)
|
||||
printf("%s\n", CAP_HSL);
|
||||
printf("%s\n", CAP_RNG);
|
||||
} else if (func_val & MASK_EP11) {
|
||||
printf("%s\n", CAP_EP11);
|
||||
@@ -459,6 +465,78 @@ static void show_capability(const char *id_str)
|
||||
card, hwtype);
|
||||
break;
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show queue capability
|
||||
*/
|
||||
static void show_queue_capability(int id, int dom)
|
||||
{
|
||||
char *dev, card[16], queue[16], buf[256];
|
||||
|
||||
snprintf(card, sizeof(card), "card%02x", id);
|
||||
snprintf(queue, sizeof(queue), "%02x.%04x", id, dom);
|
||||
dev = util_path_sysfs("devices/ap/%s/%s", card, queue);
|
||||
if (!util_path_is_dir(dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic queue device %02x.%04x does not exist.",
|
||||
id, dom);
|
||||
|
||||
printf("queue %02x.%04x capabilities:\n", id, dom);
|
||||
|
||||
if (util_path_is_reg_file("%s/se_bind", dev)) {
|
||||
util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev);
|
||||
printf("SE bind state: %s\n", buf);
|
||||
}
|
||||
if (util_path_is_reg_file("%s/se_associate", dev)) {
|
||||
util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev);
|
||||
printf("SE association state: %s\n", buf);
|
||||
}
|
||||
if (util_path_is_reg_file("%s/mkvps", dev)) {
|
||||
char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue);
|
||||
FILE *f = fopen(mkvps, "r");
|
||||
|
||||
if (!f)
|
||||
errx(EXIT_FAILURE, "Error - failed to open sysfs file %s.",
|
||||
mkvps);
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
if (strstr(buf, "WK CUR") ||
|
||||
strstr(buf, "AES CUR") ||
|
||||
strstr(buf, "APKA CUR") ||
|
||||
strstr(buf, "ASYM CUR"))
|
||||
printf("MK %s", buf); /* no newline here */
|
||||
}
|
||||
fclose(f);
|
||||
free(mkvps);
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show capability
|
||||
*/
|
||||
static void show_capability(const char *id_str)
|
||||
{
|
||||
char *p, *ap;
|
||||
int id, dom;
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
if (!util_path_is_dir(ap))
|
||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||
|
||||
if (sscanf(id_str, "%x.%x", &id, &dom) == 2) {
|
||||
show_queue_capability(id, dom);
|
||||
} else {
|
||||
id = strtol(id_str, &p, 0);
|
||||
if (id < 0 || id > 255 || p == id_str || *p != '\0')
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - '%s' is an invalid cryptographic device id.",
|
||||
id_str);
|
||||
show_card_capability(id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -596,11 +674,33 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
util_file_read_l(&depth, 10, "%s/depth", grp_dev);
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev))
|
||||
util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev);
|
||||
else
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
buf[i] = '\0';
|
||||
util_rec_set(rec, "facility", buf);
|
||||
|
||||
if (ap_bus_has_SB_support()) {
|
||||
switch (EXTRACT_BS_BITS(facility)) {
|
||||
case 0:
|
||||
util_rec_set(rec, "sestat", "usable");
|
||||
break;
|
||||
case 1:
|
||||
util_rec_set(rec, "sestat", "bound");
|
||||
break;
|
||||
case 2:
|
||||
util_rec_set(rec, "sestat", "unbound");
|
||||
break;
|
||||
case 3:
|
||||
util_rec_set(rec, "sestat", "illicit");
|
||||
break;
|
||||
default:
|
||||
util_rec_set(rec, "sestat", "-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -609,6 +709,8 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
static void show_subdevice(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
char type[16], t = '\0';
|
||||
|
||||
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
|
||||
|
||||
@@ -625,6 +727,14 @@ static void show_subdevice(struct util_rec *rec, const char *grp_dev,
|
||||
return;
|
||||
|
||||
util_rec_set(rec, "card", sub_dev);
|
||||
if (util_file_read_line(type, sizeof(type), "%s/type", grp_dev) == 0)
|
||||
t = type[strlen(type) - 1];
|
||||
|
||||
if ((t == 'A' && !l.showaccel) ||
|
||||
(t == 'C' && !l.showcca) ||
|
||||
(t == 'P' && !l.showep11))
|
||||
return;
|
||||
|
||||
read_subdev_rec_default(rec, grp_dev, sub_dev);
|
||||
read_subdev_rec_verbose(rec, grp_dev, sub_dev);
|
||||
|
||||
@@ -735,6 +845,9 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
|
||||
i = read_driver(grp_dev, NULL, buf, sizeof(buf));
|
||||
util_rec_set(rec, "driver", i > 0 ? buf : "-no-driver-");
|
||||
|
||||
if (ap_bus_has_SB_support())
|
||||
util_rec_set(rec, "sestat", "-");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -803,6 +916,8 @@ static void define_rec_verbose(struct util_rec *rec)
|
||||
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
||||
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
||||
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
||||
if (ap_bus_has_SB_support())
|
||||
util_rec_def(rec, "sestat", UTIL_REC_ALIGN_LEFT, 11, "SESTAT");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -838,12 +953,12 @@ static void show_devices_all(void)
|
||||
/*
|
||||
* Show devices specified on commandline
|
||||
*/
|
||||
static void show_devices_argv(char *argv[])
|
||||
static void show_devices_argv(int argc, char **argv)
|
||||
{
|
||||
int id, dom, argidx, devidx, n, dev_cnt, sub_cnt;
|
||||
struct util_rec *rec = util_rec_new_wide("-");
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
char *ap, *grp_dev, *path, *card, *sub_dev;
|
||||
int id, dom, i, n, dev_cnt, sub_cnt;
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
@@ -855,10 +970,10 @@ static void show_devices_argv(char *argv[])
|
||||
define_rec_verbose(rec);
|
||||
|
||||
util_rec_print_hdr(rec);
|
||||
for (i = 0; argv[i] != NULL; i++) {
|
||||
for (argidx = 0; argidx < argc; argidx++) {
|
||||
id = -1;
|
||||
dom = -1;
|
||||
if (sscanf(argv[i], "%x.%x", &id, &dom) >= 1) {
|
||||
if (sscanf(argv[argidx], "%x.%x", &id, &dom) >= 1) {
|
||||
/* at least the id field was valid */
|
||||
if (id >= 0 && dom >= 0) { /* single subdevice */
|
||||
util_asprintf(&sub_dev, "%02x.%04x", id, dom);
|
||||
@@ -874,7 +989,7 @@ static void show_devices_argv(char *argv[])
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i]+1, "%x", &dom) == 1) {
|
||||
if (sscanf(argv[argidx] + 1, "%x", &dom) == 1) {
|
||||
/* list specific domains of all adapters */
|
||||
path = util_path_sysfs("devices/ap/");
|
||||
dev_cnt = util_scandir(&dev_vec, alphasort, path,
|
||||
@@ -882,9 +997,9 @@ static void show_devices_argv(char *argv[])
|
||||
if (dev_cnt < 1)
|
||||
errx(EXIT_FAILURE, "No crypto card devices found.");
|
||||
free(path);
|
||||
for (i = 0; i < dev_cnt; i++) {
|
||||
for (devidx = 0; devidx < dev_cnt; devidx++) {
|
||||
path = util_path_sysfs("devices/ap/%s",
|
||||
dev_vec[i]->d_name);
|
||||
dev_vec[devidx]->d_name);
|
||||
sub_cnt = util_scandir(&subdev_vec, alphasort,
|
||||
path,
|
||||
"[0-9a-fA-F]+.%04x",
|
||||
@@ -1008,6 +1123,6 @@ int main(int argc, char **argv)
|
||||
if (optind == argc)
|
||||
show_devices_all();
|
||||
else
|
||||
show_devices_argv(&argv[optind]);
|
||||
show_devices_argv((argc - optind), &argv[optind]);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
/*
|
||||
* Misc - Local helper functions
|
||||
*
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
* Copyright IBM Corp. 2016, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <regex.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_panic.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "misc.h"
|
||||
|
||||
/**
|
||||
@@ -35,3 +39,35 @@ bool misc_regex_match(const char *str, const char *regex)
|
||||
regfree(&preg);
|
||||
return rc == 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if AP bus has SB support available.
|
||||
*
|
||||
* @returns true Yes, SB support is available
|
||||
* false No
|
||||
*/
|
||||
bool ap_bus_has_SB_support(void)
|
||||
{
|
||||
static int sb_support = -1;
|
||||
|
||||
if (sb_support < 0) {
|
||||
char *ap, buf[256];
|
||||
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
if (!util_path_is_dir(ap)) {
|
||||
sb_support = 0;
|
||||
} else {
|
||||
if (!util_path_is_readable("%s/features", ap)) {
|
||||
sb_support = 0;
|
||||
} else {
|
||||
util_file_read_line(buf, sizeof(buf),
|
||||
"%s/features", ap);
|
||||
if (strstr(buf, "APSB"))
|
||||
sb_support = 1;
|
||||
}
|
||||
}
|
||||
free(ap);
|
||||
}
|
||||
|
||||
return sb_support > 0 ? true : false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* misc - Local helper functions
|
||||
*
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
* Copyright IBM Corp. 2016, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -13,5 +13,6 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
bool misc_regex_match(const char *str, const char *regex);
|
||||
bool ap_bus_has_SB_support(void);
|
||||
|
||||
#endif /* MISC_H */
|
||||
|
||||
99
zdev/dracut/95zdev-kdump/module-setup.sh
Executable file
99
zdev/dracut/95zdev-kdump/module-setup.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. 2023
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
#
|
||||
# 95zdev-kdump/module_setup.sh
|
||||
# This module installs configuration files (udev rules and modprobe.conf
|
||||
# files) required to enable the kdump target on s390.
|
||||
#
|
||||
|
||||
# called by dracut
|
||||
check() {
|
||||
local _arch=${DRACUT_ARCH:-$(uname -m)}
|
||||
|
||||
# Ensure that we're running on s390
|
||||
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1
|
||||
|
||||
source "$moddir/../95zdev/zdev-lib.sh"
|
||||
|
||||
# Ensure this module is only included when building kdump initrd
|
||||
is_kdump || return 1
|
||||
|
||||
# Ensure that required tools are available
|
||||
require_binaries chzdev || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# called by dracut
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# called by dracut
|
||||
installkernel() {
|
||||
# Add modules for all device types supported by chzdev (required for
|
||||
# auto-configuration)
|
||||
instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
|
||||
dasd_diag_mod zfcp
|
||||
}
|
||||
|
||||
# called by dracut
|
||||
install() {
|
||||
local _tempfile
|
||||
|
||||
# Obtain kdump target device configuration
|
||||
|
||||
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
|
||||
# work with systems that are not based on chzdev persistent config
|
||||
local _configuration="--active"
|
||||
# disable zfcp auto LUN scan to prevent OOM situations on systems with
|
||||
# many zFCP LUNs
|
||||
inst_dir /etc/modprobe.d
|
||||
chzdev zfcp --type "allow_lun_scan=0" --persistent \
|
||||
--base "/etc=$initdir/etc" --yes --quiet --no-root-update \
|
||||
--force >/dev/null
|
||||
# drop /etc/zfcp.conf from dracut module 95zfcp
|
||||
echo "rd.zfcp.conf=0" > "$initdir/etc/cmdline.d/00-no-zfcp-conf.conf"
|
||||
# => only activate individual zfcp paths found as required below
|
||||
|
||||
function check_zdev() {
|
||||
local _dev=$1
|
||||
local _devsysfs _bdevpath
|
||||
_devsysfs=$(
|
||||
cd -P /sys/dev/block/"$_dev" && echo "$PWD"
|
||||
)
|
||||
_bdevpath=/dev/${_devsysfs##*/}
|
||||
# do not export device type information potentially unknown on import
|
||||
chzdev --export - "$_configuration" --by-node "$_bdevpath" --quiet \
|
||||
2>/dev/null >> "$_tempfile"
|
||||
}
|
||||
for_each_host_dev_and_slaves_all check_zdev
|
||||
sed -i -e 's/^\[active /\[persistent /' "$_tempfile"
|
||||
|
||||
# Apply via --import to prevent other devices from being configured
|
||||
chzdev --import "$_tempfile" --persistent --base "/etc=$initdir/etc" \
|
||||
--yes --quiet --no-root-update --force >/dev/null
|
||||
|
||||
rm -f "$_tempfile"
|
||||
|
||||
# these are purely generated udev rules so we have to glob expand
|
||||
# within $initdir and strip the $initdir prefix for mark_hostonly
|
||||
local -a _array
|
||||
local _nullglob=$(shopt -p nullglob)
|
||||
shopt -u nullglob
|
||||
readarray -t _array < \
|
||||
<(ls -1 $initdir/etc/udev/rules.d/41-*.rules 2> /dev/null)
|
||||
[[ ${#_array[@]} -gt 0 ]] && mark_hostonly "${_array[@]#$initdir}"
|
||||
readarray -t _array < \
|
||||
<(ls -1 $initdir/etc/modprobe.d/s390x-*.conf 2> /dev/null)
|
||||
[[ ${#_array[@]} -gt 0 ]] && mark_hostonly "${_array[@]#$initdir}"
|
||||
$_nullglob
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -19,6 +19,12 @@ check() {
|
||||
# Ensure that we're running on s390
|
||||
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1
|
||||
|
||||
source "$moddir/zdev-lib.sh"
|
||||
|
||||
# Leave kdump device configuration to module zdev-kdump to
|
||||
# ensure a minimal device footprint
|
||||
is_kdump && return 1
|
||||
|
||||
# Ensure that required tools are available
|
||||
require_binaries chzdev lszdev /lib/s390-tools/zdev_id || return 1
|
||||
|
||||
@@ -50,8 +56,18 @@ install() {
|
||||
|
||||
# Obtain early + root device configuration
|
||||
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
chzdev --export "$_tempfile" --persistent --by-path / --quiet \
|
||||
--type 2>/dev/null
|
||||
function check_zdev() {
|
||||
local _dev=$1
|
||||
local _devsysfs _bdevpath
|
||||
_devsysfs=$(
|
||||
cd -P /sys/dev/block/"$_dev" && echo "$PWD"
|
||||
)
|
||||
_bdevpath=/dev/${_devsysfs##*/}
|
||||
chzdev --export - --persistent --by-node "$_bdevpath" --quiet \
|
||||
--type 2>/dev/null >> "$_tempfile"
|
||||
}
|
||||
for_each_host_dev_and_slaves_all check_zdev
|
||||
|
||||
chzdev --export - --persistent --by-attrib "zdev:early=1" --quiet \
|
||||
--type 2>/dev/null >> "$_tempfile"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user