mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
83 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 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,6 +9,9 @@
|
||||
tags
|
||||
TAGS
|
||||
|
||||
# clangd cache (https://clangd.llvm.org/design/indexing#backgroundindex)
|
||||
.cache/
|
||||
|
||||
# Ignore coverage data
|
||||
*.gcda
|
||||
*.gcno
|
||||
|
||||
50
CHANGELOG.md
50
CHANGELOG.md
@@ -1,6 +1,56 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.28.0 (2023-07-11)__
|
||||
|
||||
For Linux kernel version: 6.4
|
||||
|
||||
Changes of existing tools:
|
||||
- chzcrypt: Support for SE AP pass-through support
|
||||
- genprotimg: Add support for non-s390x architectures
|
||||
- lszcrypt: Support for SE AP pass-through support
|
||||
- zdev: Add support for autoquiesce related sysfs attributes
|
||||
|
||||
Bug Fixes:
|
||||
- ap_tools/ap-check: Handle missing 'matrix' and 'control_domains' attrs
|
||||
- ap_tools/ap-check: Hold ap config file lock over get attributes
|
||||
- s390-tools: Fix build for ppc64le
|
||||
- zdev: Add missing label in the udev-rules
|
||||
- zdev: Add proper value input for the ZDEV_SITE_ID key
|
||||
- zdev: Use rename-file to avoid any symlinks created
|
||||
- zipl/dump: fix ngdump dracut helper script
|
||||
|
||||
* __v2.27.0 (2023-05-30)__
|
||||
|
||||
For Linux kernel version: 6.3
|
||||
|
||||
Changes of existing tools:
|
||||
- s390-tools cross-compile and non-s390x support:
|
||||
- `pkg-config` is now mandatory for the build process
|
||||
- Add `PKG_CONFIG` Makefile variable to select pkg-config program;
|
||||
default `pkg-config` or `$(CROSS_COMPILE)pkg-config` if
|
||||
`CROSS_COMPILE` is set
|
||||
- Rename Makefile variable `ARCH` to `HOST_ARCH`. `HOST_ARCH` is the
|
||||
architecture that will run the produced (executable) objects
|
||||
- Add the Makefile variable `BUILD_ARCH`. `BUILD_ARCH` is the
|
||||
architecture of the build system. For each Makefile variable like
|
||||
`CC`, `LINK`, `CPP`, ... there is a suffixed version of it - e.g.
|
||||
`CC_FOR_BUILD`. This is useful for cross compiling, and this naming
|
||||
convention is very similar to the Meson convention (see
|
||||
https://mesonbuild.com/Reference-tables.html#environment-variables-per-machine).
|
||||
- Limit build targets for non-s390x architectures (pvattest)
|
||||
- dasdfmt: Fall back to full format if space release fails
|
||||
- dbginfo.sh: Add nstat for network and SNMP stats
|
||||
- dbginfo.sh: Rework crypto data collection
|
||||
- hyptop: Show thread util by default
|
||||
- zipl: Add support for list-directed IPL dump from ECKD DASD
|
||||
|
||||
Bug Fixes:
|
||||
- lszcrypt: Fix argument parsing
|
||||
- zdev/dracut: Fix out-of-memory (OOM) situations in the kdump crashkernel environment
|
||||
- ziomon/ziorep_config: Fix for SCSI devices of type disk without block dev
|
||||
- pvextract-hdr: Fix parsing issues on little-endian systems
|
||||
|
||||
* __v2.26.0 (2023-02-14)__
|
||||
|
||||
For Linux kernel version: 6.2
|
||||
|
||||
14
Makefile
14
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,6 +6,7 @@ include common.mak
|
||||
# LIBS: Libraries that can have a dependency to base libraries
|
||||
# TOOLS: Tools that can have a dependency to base libraries or libraries
|
||||
#
|
||||
ifeq ($(HOST_ARCH),s390x)
|
||||
BASELIB_DIRS = libutil libseckey
|
||||
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
|
||||
libkmipclient libcpumf libap libpv
|
||||
@@ -17,6 +16,11 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest
|
||||
else
|
||||
BASELIB_DIRS =
|
||||
LIB_DIRS = libpv
|
||||
TOOL_DIRS = genprotimg pvattest
|
||||
endif
|
||||
|
||||
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
@@ -49,15 +53,15 @@ endif
|
||||
|
||||
$(TOOL_DIRS): $(LIB_DIRS)
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(TOOL_DIRS)
|
||||
|
||||
$(LIB_DIRS): $(BASELIB_DIRS)
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(LIB_DIRS)
|
||||
|
||||
$(BASELIB_DIRS):
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) HOST_ARCH=$(HOST_ARCH) $(goal) ;)
|
||||
.PHONY: $(BASELIB_DIRS)
|
||||
|
||||
@@ -325,8 +325,8 @@ This table lists additional build or install options:
|
||||
| initramfs-tools | `HAVE_INITRAMFS` | zdev, zipl |
|
||||
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
|
||||
|
||||
The s390-tools build process uses "pkg-config" if available and hard-coded
|
||||
compiler and linker options otherwise.
|
||||
The s390-tools build process uses "pkg-config" and therefore it must be
|
||||
available.
|
||||
|
||||
Build and runtime requirements for specific tools
|
||||
-------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
131
common.mak
131
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 = 26
|
||||
RELEASE = 28
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
export S390_TOOLS_RELEASE
|
||||
|
||||
reldir = $(subst $(shell cd -P $(dir $(filter %common.mak,$(MAKEFILE_LIST))); \
|
||||
pwd)/,,$(CURDIR))
|
||||
reldir = $(subst $(realpath $(dir $(filter %common.mak,$(MAKEFILE_LIST))))/,,$(CURDIR))
|
||||
rootdir= $(dir $(filter %common.mak,$(MAKEFILE_LIST)))
|
||||
export S390_TEST_LIB_PATH=$(rootdir)/s390-tools-testsuite/lib
|
||||
|
||||
#
|
||||
# For cross compiles specify CROSS_COMPILE= on the commandline:
|
||||
# For cross compiles specify HOST_ARCH= and CROSS_COMPILE= on the commandline:
|
||||
#
|
||||
# $ make CROSS_COMPILE="s390x-5.1.0-"
|
||||
# $ make HOST_ARCH=s390x CROSS_COMPILE="s390x-linux-gnu-"
|
||||
#
|
||||
|
||||
CROSS_COMPILE =
|
||||
@@ -29,8 +51,10 @@ CROSS_COMPILE =
|
||||
#
|
||||
# $ make CC=gcc-4.8
|
||||
#
|
||||
# The "cmd_define" macro wraps the command definition so that the commands
|
||||
# can be user supplied and are still pretty-printed for the build process.
|
||||
# The "cmd_define_and_export" macro wraps the command definition so that
|
||||
# the commands can be user supplied and are still pretty-printed for the
|
||||
# build process. In addition, the command variable gets exported so it
|
||||
# can be used by sub-makes.
|
||||
#
|
||||
# The macro is called with the following parameters:
|
||||
#
|
||||
@@ -40,13 +64,14 @@ CROSS_COMPILE =
|
||||
#
|
||||
# The Example below...
|
||||
#
|
||||
# $(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||
# $(eval $(call cmd_define_and_export, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||
#
|
||||
# ... produces the following code:
|
||||
#
|
||||
# CC = $(CROSS_COMPILE)gcc
|
||||
# CC_SILENT := $(CC)
|
||||
# override CC = $(call echocmd," CC ",/$@)$(CC_SILENT)
|
||||
# export CC
|
||||
#
|
||||
# The "strip" make function is used for the first parameter to allow blanks,
|
||||
# which improves readability.
|
||||
@@ -58,23 +83,47 @@ define cmd_define
|
||||
override $(strip $(1)) = $$(call echocmd,$(2),/$$@)$$($(strip $(1))_SILENT)
|
||||
endef
|
||||
|
||||
$(eval $(call cmd_define, AS," AS ",$(CROSS_COMPILE)as))
|
||||
$(eval $(call cmd_define, CC," CC ",$(CROSS_COMPILE)gcc))
|
||||
$(eval $(call cmd_define, LINK," LINK ",$(CC)))
|
||||
$(eval $(call cmd_define, HOSTCC," HOSTCC ",gcc))
|
||||
$(eval $(call cmd_define, CXX," CXX ",$(CROSS_COMPILE)g++))
|
||||
$(eval $(call cmd_define, LINKXX," LINKXX ",$(CXX)))
|
||||
$(eval $(call cmd_define, CPP," CPP ",$(CROSS_COMPILE)gcc -E))
|
||||
$(eval $(call cmd_define, AR," AR ",$(CROSS_COMPILE)ar))
|
||||
$(eval $(call cmd_define, NM," NM ",$(CROSS_COMPILE)nm))
|
||||
$(eval $(call cmd_define, STRIP," STRIP ",$(CROSS_COMPILE)strip))
|
||||
$(eval $(call cmd_define,OBJCOPY," OBJCOPY ",$(CROSS_COMPILE)objcopy))
|
||||
$(eval $(call cmd_define,OBJDUMP," OBJDUMP ",$(CROSS_COMPILE)objdump))
|
||||
define cmd_define_and_export
|
||||
$(call cmd_define,$(1),$(2),$(3))
|
||||
export $(strip $(1))
|
||||
endef
|
||||
|
||||
define define_toolchain_variables
|
||||
$(eval $(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as))
|
||||
$(eval $(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc))
|
||||
$(eval $(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1))))
|
||||
$(eval $(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++))
|
||||
$(eval $(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1))))
|
||||
$(eval $(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E))
|
||||
$(eval $(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar))
|
||||
$(eval $(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm))
|
||||
$(eval $(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip))
|
||||
$(eval $(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy))
|
||||
$(eval $(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump))
|
||||
$(eval PKG_CONFIG$(1) = pkg-config)
|
||||
$(eval export PKG_CONFIG$(1))
|
||||
endef
|
||||
|
||||
# If the host architecture is not the same as the build architecture
|
||||
# 'CROSS_COMPILE=...' is always required (except for the '*clean' targets).
|
||||
ifneq ($(HOST_ARCH),$(BUILD_ARCH))
|
||||
ifeq ($(CROSS_COMPILE),)
|
||||
# `make clean` and similar must always work!
|
||||
ifeq ($(filter %clean,$(MAKECMDGOALS)),)
|
||||
$(error Please specify CROSS_COMPILE=... and try it again!)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
$(call define_toolchain_variables,_FOR_BUILD,)
|
||||
$(call define_toolchain_variables,,$(CROSS_COMPILE))
|
||||
|
||||
$(eval $(call cmd_define,RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
||||
$(eval $(call cmd_define, CAT," CAT ",cat))
|
||||
$(eval $(call cmd_define, SED," SED ",sed))
|
||||
$(eval $(call cmd_define, GZIP," GZIP ",gzip))
|
||||
$(eval $(call cmd_define, MV," MV ",mv))
|
||||
$(eval $(call cmd_define, PERLC," PERLC ",perl -c))
|
||||
|
||||
CHECK = sparse
|
||||
CHECK_SILENT := $(CHECK)
|
||||
@@ -101,6 +150,10 @@ else
|
||||
DEFAULT_CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifeq ("${ENABLE_WERROR}", "1")
|
||||
DEFAULT_CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
||||
DEFAULT_LDFLAGS = -rdynamic
|
||||
|
||||
@@ -109,6 +162,11 @@ ifeq ("${ASAN}","1")
|
||||
DEFAULT_LDFLAGS += -fsanitize=address
|
||||
endif
|
||||
|
||||
DEFAULT_PERLCFLAGS =
|
||||
ifeq ("${W}","1")
|
||||
DEFAULT_PERLCFLAGS += -w
|
||||
endif
|
||||
|
||||
#
|
||||
# Check for header prerequisite
|
||||
#
|
||||
@@ -153,8 +211,8 @@ fi
|
||||
# Returns the linker option if available and nothing otherwise
|
||||
#
|
||||
define test_linker_flag
|
||||
$(shell printf "int main(void) {return 0;}\n" | \
|
||||
( $(CC) "-Wl,$1" -o /dev/null -x c - ) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
|
||||
$(shell printf ".globl _start\n_start:\nnop\n" | \
|
||||
( $(LINK) "-Wl,$1" -o /dev/null -nostdlib -x assembler -) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
|
||||
endef
|
||||
|
||||
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
|
||||
@@ -235,10 +293,10 @@ ZFCPDUMP_INITRD = zfcpdump-initrd
|
||||
ZFCPDUMP_FLAVOR = zfcpdump
|
||||
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
|
||||
|
||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
|
||||
LDFLAGS ?= $(DEFAULT_LDFLAGS)
|
||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
CFLAGS_FOR_BUILD ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
CPPFLAGS ?= $(DEFAULT_CPPFLAGS)
|
||||
LDFLAGS ?= $(DEFAULT_LDFLAGS)
|
||||
|
||||
ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||
@@ -256,6 +314,8 @@ ALL_CXXFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
|
||||
ALL_LDFLAGS = $(LDFLAGS)
|
||||
|
||||
ALL_PERLCFLAGS = $(DEFAULT_PERLCFLAGS)
|
||||
|
||||
# make G=1
|
||||
# Compile tools so that gcov can be used to collect code coverage data.
|
||||
# See the gcov man page for details.
|
||||
@@ -264,7 +324,7 @@ ALL_CFLAGS := $(filter-out -O%,$(ALL_CFLAGS)) --coverage
|
||||
ALL_CXXFLAGS := $(filter-out -O%,$(ALL_CXXFLAGS)) --coverage
|
||||
ALL_LDFLAGS += --coverage
|
||||
endif
|
||||
export AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP INSTALL CFLAGS CXXFLAGS \
|
||||
export INSTALL CFLAGS CXXFLAGS \
|
||||
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
|
||||
|
||||
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||
@@ -302,12 +362,13 @@ help:
|
||||
@echo ' clean Delete all generated files'
|
||||
@echo ''
|
||||
@echo 'OPTIONS'
|
||||
@echo ' D=1 Build with debugging option "-Og"'
|
||||
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
|
||||
@echo ' G=1 Build with gcov to collect code coverage data'
|
||||
@echo ' V=1 Generate verbose build output'
|
||||
@echo ' W=1 Build with higher warning level'
|
||||
@echo ' ASAN=1 Build with address sanitizer'
|
||||
@echo ' D=1 Build with debugging option "-Og"'
|
||||
@echo ' C=1 Build with check tool defined with "CHECK=" (default=sparse)'
|
||||
@echo ' G=1 Build with gcov to collect code coverage data'
|
||||
@echo ' V=1 Generate verbose build output'
|
||||
@echo ' W=1 Build with higher warning level'
|
||||
@echo ' ASAN=1 Build with address sanitizer'
|
||||
@echo ' ENABLE_WERROR=1 Build with -Werror'
|
||||
@echo ''
|
||||
@echo 'EXAMPLES'
|
||||
@echo ' # make clean all D=1 W=1 -j'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -80,6 +79,26 @@ stage3b.elf: head.o $(ZIPL_OBJS)
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
install: stage3a.bin stage3b_reloc.bin
|
||||
$(INSTALL) -d -m 755 "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3a.bin "$(PKGDATADIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3b_reloc.bin "$(PKGDATADIR)"
|
||||
|
||||
else
|
||||
# Don't generate the dependency files (see `common.mak` for the
|
||||
# `-include $(dependencies_c)` statement).
|
||||
.PHONY: $(dependencies_c)
|
||||
|
||||
$(FILES):
|
||||
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||
|
||||
install:
|
||||
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||
endif
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
all: $(FILES)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.elf *.bin *.map .*.d *.lds
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/psw.h"
|
||||
#include "libpv/crypto.h"
|
||||
#include "libpv/macros.h"
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -2947,14 +2962,14 @@ static const OSSL_PARAM sk_prov_imexport_types[] = {
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
|
||||
int pkey_type)
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_export_types(
|
||||
struct sk_prov_ctx *provctx,
|
||||
int selection,
|
||||
int pkey_type)
|
||||
{
|
||||
OSSL_FUNC_keymgmt_export_types_fn *default_export_types_fn;
|
||||
const OSSL_PARAM *default_parms = NULL, *params;
|
||||
struct sk_prov_ctx *provctx;
|
||||
|
||||
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
if (provctx == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -2982,14 +2997,14 @@ static const OSSL_PARAM *sk_prov_keymgmt_export_types(int selection,
|
||||
sk_prov_imexport_types);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_import_types(int selection,
|
||||
int pkey_type)
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_import_types(
|
||||
struct sk_prov_ctx *provctx,
|
||||
int selection,
|
||||
int pkey_type)
|
||||
{
|
||||
OSSL_FUNC_keymgmt_import_types_fn *default_import_types_fn;
|
||||
const OSSL_PARAM *default_parms = NULL, *params;
|
||||
struct sk_prov_ctx *provctx;
|
||||
|
||||
provctx = OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
if (provctx == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -3337,15 +3352,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_settable_params(void *vprovctx)
|
||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA);
|
||||
}
|
||||
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
#else
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_export_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_import_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_RSA);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *sk_prov_keymgmt_rsa_gen_init(void *vprovctx, int selection,
|
||||
const OSSL_PARAM params[])
|
||||
@@ -3407,15 +3446,43 @@ static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_settable_params(void *vprovctx)
|
||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
#else
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_export_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_RSA_PSS);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_rsa_pss_import_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_RSA_PSS);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection,
|
||||
EVP_PKEY_RSA_PSS);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *sk_prov_keymgmt_rsa_pss_gen_init(void *vprovctx, int selection,
|
||||
const OSSL_PARAM params[])
|
||||
@@ -3490,15 +3557,39 @@ static const OSSL_PARAM *sk_prov_keymgmt_ec_settable_params(void *vprovctx)
|
||||
return sk_prov_keymgmt_settable_params(provctx, EVP_PKEY_EC);
|
||||
}
|
||||
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types_ex(void *vprovctx,
|
||||
int selection)
|
||||
{
|
||||
struct sk_prov_ctx *provctx = vprovctx;
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
#else
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_export_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_export_types(selection, EVP_PKEY_EC);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_export_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *sk_prov_keymgmt_ec_import_types(int selection)
|
||||
{
|
||||
return sk_prov_keymgmt_import_types(selection, EVP_PKEY_EC);
|
||||
struct sk_prov_ctx *provctx =
|
||||
OSSL_PROVIDER_get0_provider_ctx(sk_prov_securekey_provider);
|
||||
|
||||
return sk_prov_keymgmt_import_types(provctx, selection, EVP_PKEY_EC);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *sk_prov_keymgmt_ec_gen_init(void *vprovctx, int selection,
|
||||
const OSSL_PARAM params[])
|
||||
@@ -4648,11 +4739,21 @@ static const OSSL_DISPATCH sk_prov_rsa_keymgmt_functions[] = {
|
||||
|
||||
/* Import and export routines */
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_export_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_export_types },
|
||||
#endif
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_import_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_import_types },
|
||||
#endif
|
||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||
|
||||
{ 0, NULL }
|
||||
@@ -4697,11 +4798,21 @@ static const OSSL_DISPATCH sk_prov_rsapss_keymgmt_functions[] = {
|
||||
|
||||
/* Import and export routines */
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_export_types },
|
||||
#endif
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_rsa_pss_import_types },
|
||||
#endif
|
||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||
|
||||
{ 0, NULL }
|
||||
@@ -4746,11 +4857,21 @@ static const OSSL_DISPATCH sk_prov_ec_keymgmt_functions[] = {
|
||||
|
||||
/* Import and export routines */
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))sk_prov_keymgmt_export },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_export_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_export_types },
|
||||
#endif
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sk_prov_keymgmt_import },
|
||||
#ifdef OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_import_types_ex },
|
||||
#else
|
||||
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
|
||||
(void (*)(void))sk_prov_keymgmt_ec_import_types },
|
||||
#endif
|
||||
/* No copy function, OpenSSL will use export/import to copy instead */
|
||||
|
||||
{ 0, NULL }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
@@ -409,6 +409,7 @@ CONFIGFILES="\
|
||||
/etc/multipath\
|
||||
/etc/network\
|
||||
/etc/networks\
|
||||
/etc/opencryptoki/*.conf\
|
||||
/etc/pam.d\
|
||||
/etc/profile\
|
||||
/etc/profile.d\
|
||||
@@ -513,13 +514,20 @@ CMDS="${CMDS}\
|
||||
|
||||
# crypto specific commands
|
||||
CMDS="${CMDS}\
|
||||
:cat /var/lib/opencryptoki/pk_config_data\
|
||||
:ep11info -D\
|
||||
:ep11info -H\
|
||||
:ep11info -M\
|
||||
:icainfo\
|
||||
:icastats\
|
||||
:icastats --all\
|
||||
:ivp.e # IBM CCA package install check\
|
||||
:ls -al /usr/lib64/opencryptoki/stdll\
|
||||
:lszcrypt -VV\
|
||||
:pkcsconf -mlist\
|
||||
:pkcsconf -i\
|
||||
:pkcsconf -s\
|
||||
:pkcsconf -l\
|
||||
:pkcsconf -t\
|
||||
:pkcsconf -m\
|
||||
:systemctl status pkcsslotd\
|
||||
"
|
||||
|
||||
# product / distro specific commands
|
||||
@@ -567,6 +575,7 @@ NETWORK_CMDS="ip -br a\
|
||||
:netstat -pantu\
|
||||
:netstat -s\
|
||||
:nm-tool\
|
||||
:nstat -az\
|
||||
:openssl engine\
|
||||
:route -n\
|
||||
"
|
||||
|
||||
@@ -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
|
||||
;;
|
||||
|
||||
@@ -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:
|
||||
@@ -224,48 +255,64 @@ F - Full function support (opposed to restricted function support, see below).
|
||||
.br
|
||||
R - Restricted function support. The F and R flag both reflect if a
|
||||
hypervisor is somehow restricting this crypto resource in a virtual
|
||||
environment. Dependent on the hypervisor configuration the crypto requests
|
||||
may be filtered by the hypervisor to allow only a subset of functions
|
||||
within the virtual runtime environment. For example a shared CCA
|
||||
Coprocessor may be restricted by the hypervisor to allow only clear key
|
||||
operations within the guests.
|
||||
environment. Dependent on the hypervisor configuration the crypto
|
||||
requests may be filtered by the hypervisor to allow only a subset of
|
||||
functions within the virtual runtime environment. For example a shared
|
||||
CCA Coprocessor may be restricted by the hypervisor to allow only
|
||||
clear key operations within the guests.
|
||||
.TP
|
||||
.B DRIVER
|
||||
.br
|
||||
Shows which card or queue device driver currently handles this crypto
|
||||
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX8
|
||||
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
||||
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
|
||||
for use by kvm hypervisor for kvm guests and not accessible to host
|
||||
applications). It is also valid to have no driver handling a queue which is
|
||||
shown as a -no-driver- entry.
|
||||
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue
|
||||
reserved for use by KVM hypervisor for KVM guests and not accessible
|
||||
to host applications). It is also valid to have no driver handling a
|
||||
queue which is shown as a -no-driver- entry.
|
||||
.TP
|
||||
.B SESTAT
|
||||
.br
|
||||
Shows the state of the BS bits associated with every AP queue within a
|
||||
Secure Execution guest when AP Pass-through support is available:
|
||||
.br
|
||||
usable - AP queue is usable for crypto load.
|
||||
.br
|
||||
bound - AP queue is bound but not yet associated.
|
||||
.br
|
||||
unbound - AP queue is unbound and needs to get bound to this Secure
|
||||
Execution guest.
|
||||
.br
|
||||
illicit - AP queue is not available for this Secure Execution guest.
|
||||
.SH NOTES
|
||||
Use only one of the mode filtering options --accelonly, --ccaonly, --ep11only.
|
||||
Same with card/queue filtering: Use only one of --cardonly, --queueonly.
|
||||
However, one of the mode filtering options and one of the card/queue filtering
|
||||
can be combined.
|
||||
Use only one of the mode filtering options --accelonly, --ccaonly,
|
||||
--ep11only. Same with card/queue filtering: Use only one of
|
||||
--cardonly, --queueonly. However, one of the mode filtering options
|
||||
and one of the card/queue filtering can be combined.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B lszcrypt
|
||||
Displays the card/domain ID, card type (short name), mode (long name), online
|
||||
status and request count of all available cryptographic devices.
|
||||
Displays the card/domain ID, card type (short name), mode (long name),
|
||||
online status and request count of all available cryptographic
|
||||
devices.
|
||||
.TP
|
||||
.B lszcrypt 1 3 5
|
||||
Displays the card/domain ID, card type, mode, online status and request count
|
||||
for cryptographic devices 1, 3, and 5.
|
||||
Displays the card/domain ID, card type, mode, online status and
|
||||
request count for cryptographic devices 1, 3, and 5.
|
||||
.TP
|
||||
.B lszcrypt -V 3 7 11
|
||||
Displays the card/domain ID, card type, mode, online status, request count,
|
||||
number of requests in the hardware queue, number of outstanding requests and
|
||||
installed function facilities for cryptographic devices 3, 7 and 17 (0x11).
|
||||
Displays the card/domain ID, card type, mode, online status, request
|
||||
count, number of requests in the hardware queue, number of outstanding
|
||||
requests and installed function facilities for cryptographic devices
|
||||
3, 7 and 17 (0x11).
|
||||
.TP
|
||||
.B lszcrypt 10.0038
|
||||
Displays information of the cryptographic device '10.0038' respectively card
|
||||
id 16 (0x10) with domain 56 (0x38).
|
||||
Displays information of the cryptographic device '10.0038'
|
||||
respectively card id 16 (0x10) with domain 56 (0x38).
|
||||
.TP
|
||||
.B lszcrypt .0038
|
||||
Displays information of all available queue devices (potentially multiple
|
||||
adapters) with domain 56 (0x38).
|
||||
Displays information of all available queue devices (potentially
|
||||
multiple adapters) with domain 56 (0x38).
|
||||
.TP
|
||||
.B lszcrypt -b
|
||||
Displays AP bus information.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* lszcrypt - Display zcrypt devices and configuration settings
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2022
|
||||
* Copyright IBM Corp. 2008, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -55,7 +55,7 @@ static struct lszcrypt_l {
|
||||
#define MASK_COPRO 0x10000000
|
||||
#define MASK_ACCEL 0x08000000
|
||||
#define MASK_EP11 0x04000000
|
||||
#define MASK_HSL 0x01000000
|
||||
#define MASK_HSL 0x01000000
|
||||
|
||||
/*
|
||||
* Classification
|
||||
@@ -85,6 +85,8 @@ static struct fac_bits_s {
|
||||
{ 0x00400000, 'R' }, /* bit 9, restricted function set */
|
||||
};
|
||||
|
||||
#define EXTRACT_BS_BITS(f) (((f) & 0x0000c000UL) >> 14)
|
||||
|
||||
/*
|
||||
* Program configuration
|
||||
*/
|
||||
@@ -95,7 +97,7 @@ static const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
.pub_last = 2020,
|
||||
.pub_last = 2023,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -169,8 +171,9 @@ static struct util_opt opt_vec[] = {
|
||||
static void show_bus(void)
|
||||
{
|
||||
long domain, max_domain, config_time, value;
|
||||
unsigned long long poll_timeout;
|
||||
const char *poll_thread, *ap_interrupts;
|
||||
unsigned long long poll_timeout;
|
||||
char features[256];
|
||||
char *ap;
|
||||
|
||||
/* check if ap driver is available */
|
||||
@@ -178,6 +181,10 @@ static void show_bus(void)
|
||||
if (!util_path_is_dir(ap))
|
||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||
|
||||
if (util_path_is_readable("%s/features", ap))
|
||||
util_file_read_line(features, sizeof(features), "%s/features", ap);
|
||||
else
|
||||
features[0] = '\0';
|
||||
util_file_read_l(&domain, 10, "%s/ap_domain", ap);
|
||||
util_file_read_l(&max_domain, 10, "%s/ap_max_domain_id", ap);
|
||||
util_file_read_l(&config_time, 10, "%s/config_time", ap);
|
||||
@@ -192,6 +199,8 @@ static void show_bus(void)
|
||||
ap_interrupts = "enabled";
|
||||
else
|
||||
ap_interrupts = "disabled";
|
||||
if (features[0])
|
||||
printf("features: %s\n", features);
|
||||
printf("ap_domain=0x%lx\n", domain);
|
||||
printf("ap_max_domain_id=0x%lx\n", max_domain);
|
||||
if (util_path_is_reg_file("%s/ap_interrupts", ap))
|
||||
@@ -374,23 +383,15 @@ next:
|
||||
}
|
||||
|
||||
/*
|
||||
* Show capability
|
||||
* Show card capability
|
||||
*/
|
||||
static void show_capability(const char *id_str)
|
||||
static void show_card_capability(int id)
|
||||
{
|
||||
unsigned long func_val;
|
||||
long hwtype, id, max_msg_size;
|
||||
char *p, *ap, *dev, card[16], cbuf[256];
|
||||
long hwtype, max_msg_size;
|
||||
char *dev, card[16], cbuf[256];
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
if (!util_path_is_dir(ap))
|
||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||
|
||||
id = strtol(id_str, &p, 0);
|
||||
if (id < 0 || id > 255 || p == id_str || *p != '\0')
|
||||
errx(EXIT_FAILURE, "Error - '%s' is an invalid cryptographic device id.", id_str);
|
||||
snprintf(card, sizeof(card), "card%02lx", id);
|
||||
snprintf(card, sizeof(card), "card%02x", id);
|
||||
dev = util_path_sysfs("devices/ap/%s", card);
|
||||
if (!util_path_is_dir(dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", card);
|
||||
@@ -464,6 +465,78 @@ static void show_capability(const char *id_str)
|
||||
card, hwtype);
|
||||
break;
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show queue capability
|
||||
*/
|
||||
static void show_queue_capability(int id, int dom)
|
||||
{
|
||||
char *dev, card[16], queue[16], buf[256];
|
||||
|
||||
snprintf(card, sizeof(card), "card%02x", id);
|
||||
snprintf(queue, sizeof(queue), "%02x.%04x", id, dom);
|
||||
dev = util_path_sysfs("devices/ap/%s/%s", card, queue);
|
||||
if (!util_path_is_dir(dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic queue device %02x.%04x does not exist.",
|
||||
id, dom);
|
||||
|
||||
printf("queue %02x.%04x capabilities:\n", id, dom);
|
||||
|
||||
if (util_path_is_reg_file("%s/se_bind", dev)) {
|
||||
util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev);
|
||||
printf("SE bind state: %s\n", buf);
|
||||
}
|
||||
if (util_path_is_reg_file("%s/se_associate", dev)) {
|
||||
util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev);
|
||||
printf("SE association state: %s\n", buf);
|
||||
}
|
||||
if (util_path_is_reg_file("%s/mkvps", dev)) {
|
||||
char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue);
|
||||
FILE *f = fopen(mkvps, "r");
|
||||
|
||||
if (!f)
|
||||
errx(EXIT_FAILURE, "Error - failed to open sysfs file %s.",
|
||||
mkvps);
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
if (strstr(buf, "WK CUR") ||
|
||||
strstr(buf, "AES CUR") ||
|
||||
strstr(buf, "APKA CUR") ||
|
||||
strstr(buf, "ASYM CUR"))
|
||||
printf("MK %s", buf); /* no newline here */
|
||||
}
|
||||
fclose(f);
|
||||
free(mkvps);
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show capability
|
||||
*/
|
||||
static void show_capability(const char *id_str)
|
||||
{
|
||||
char *p, *ap;
|
||||
int id, dom;
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
if (!util_path_is_dir(ap))
|
||||
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
||||
|
||||
if (sscanf(id_str, "%x.%x", &id, &dom) == 2) {
|
||||
show_queue_capability(id, dom);
|
||||
} else {
|
||||
id = strtol(id_str, &p, 0);
|
||||
if (id < 0 || id > 255 || p == id_str || *p != '\0')
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - '%s' is an invalid cryptographic device id.",
|
||||
id_str);
|
||||
show_card_capability(id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -601,11 +674,33 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
util_file_read_l(&depth, 10, "%s/depth", grp_dev);
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev))
|
||||
util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev);
|
||||
else
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
buf[i] = '\0';
|
||||
util_rec_set(rec, "facility", buf);
|
||||
|
||||
if (ap_bus_has_SB_support()) {
|
||||
switch (EXTRACT_BS_BITS(facility)) {
|
||||
case 0:
|
||||
util_rec_set(rec, "sestat", "usable");
|
||||
break;
|
||||
case 1:
|
||||
util_rec_set(rec, "sestat", "bound");
|
||||
break;
|
||||
case 2:
|
||||
util_rec_set(rec, "sestat", "unbound");
|
||||
break;
|
||||
case 3:
|
||||
util_rec_set(rec, "sestat", "illicit");
|
||||
break;
|
||||
default:
|
||||
util_rec_set(rec, "sestat", "-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -614,6 +709,8 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
static void show_subdevice(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
char type[16], t = '\0';
|
||||
|
||||
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
|
||||
|
||||
@@ -630,6 +727,14 @@ static void show_subdevice(struct util_rec *rec, const char *grp_dev,
|
||||
return;
|
||||
|
||||
util_rec_set(rec, "card", sub_dev);
|
||||
if (util_file_read_line(type, sizeof(type), "%s/type", grp_dev) == 0)
|
||||
t = type[strlen(type) - 1];
|
||||
|
||||
if ((t == 'A' && !l.showaccel) ||
|
||||
(t == 'C' && !l.showcca) ||
|
||||
(t == 'P' && !l.showep11))
|
||||
return;
|
||||
|
||||
read_subdev_rec_default(rec, grp_dev, sub_dev);
|
||||
read_subdev_rec_verbose(rec, grp_dev, sub_dev);
|
||||
|
||||
@@ -740,6 +845,9 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
|
||||
i = read_driver(grp_dev, NULL, buf, sizeof(buf));
|
||||
util_rec_set(rec, "driver", i > 0 ? buf : "-no-driver-");
|
||||
|
||||
if (ap_bus_has_SB_support())
|
||||
util_rec_set(rec, "sestat", "-");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -808,6 +916,8 @@ static void define_rec_verbose(struct util_rec *rec)
|
||||
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
||||
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
||||
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
||||
if (ap_bus_has_SB_support())
|
||||
util_rec_def(rec, "sestat", UTIL_REC_ALIGN_LEFT, 11, "SESTAT");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -843,12 +953,12 @@ static void show_devices_all(void)
|
||||
/*
|
||||
* Show devices specified on commandline
|
||||
*/
|
||||
static void show_devices_argv(char *argv[])
|
||||
static void show_devices_argv(int argc, char **argv)
|
||||
{
|
||||
int id, dom, argidx, devidx, n, dev_cnt, sub_cnt;
|
||||
struct util_rec *rec = util_rec_new_wide("-");
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
char *ap, *grp_dev, *path, *card, *sub_dev;
|
||||
int id, dom, i, n, dev_cnt, sub_cnt;
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
@@ -860,10 +970,10 @@ static void show_devices_argv(char *argv[])
|
||||
define_rec_verbose(rec);
|
||||
|
||||
util_rec_print_hdr(rec);
|
||||
for (i = 0; argv[i] != NULL; i++) {
|
||||
for (argidx = 0; argidx < argc; argidx++) {
|
||||
id = -1;
|
||||
dom = -1;
|
||||
if (sscanf(argv[i], "%x.%x", &id, &dom) >= 1) {
|
||||
if (sscanf(argv[argidx], "%x.%x", &id, &dom) >= 1) {
|
||||
/* at least the id field was valid */
|
||||
if (id >= 0 && dom >= 0) { /* single subdevice */
|
||||
util_asprintf(&sub_dev, "%02x.%04x", id, dom);
|
||||
@@ -879,7 +989,7 @@ static void show_devices_argv(char *argv[])
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i]+1, "%x", &dom) == 1) {
|
||||
if (sscanf(argv[argidx] + 1, "%x", &dom) == 1) {
|
||||
/* list specific domains of all adapters */
|
||||
path = util_path_sysfs("devices/ap/");
|
||||
dev_cnt = util_scandir(&dev_vec, alphasort, path,
|
||||
@@ -887,9 +997,9 @@ static void show_devices_argv(char *argv[])
|
||||
if (dev_cnt < 1)
|
||||
errx(EXIT_FAILURE, "No crypto card devices found.");
|
||||
free(path);
|
||||
for (i = 0; i < dev_cnt; i++) {
|
||||
for (devidx = 0; devidx < dev_cnt; devidx++) {
|
||||
path = util_path_sysfs("devices/ap/%s",
|
||||
dev_vec[i]->d_name);
|
||||
dev_vec[devidx]->d_name);
|
||||
sub_cnt = util_scandir(&subdev_vec, alphasort,
|
||||
path,
|
||||
"[0-9a-fA-F]+.%04x",
|
||||
@@ -1013,6 +1123,6 @@ int main(int argc, char **argv)
|
||||
if (optind == argc)
|
||||
show_devices_all();
|
||||
else
|
||||
show_devices_argv(&argv[optind]);
|
||||
show_devices_argv((argc - optind), &argv[optind]);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
24
zdev/dracut/95zdev/zdev-lib.sh
Normal file
24
zdev/dracut/95zdev/zdev-lib.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright IBM Corp. 2023
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
#
|
||||
# 95zdev/zdev-lib.sh
|
||||
# Common shell library functionality for 95zdev and 95zdev-kdump.
|
||||
#
|
||||
|
||||
is_kdump() {
|
||||
# https://src.fedoraproject.org/rpms/kexec-tools/c/4eedcae5e1540690a3761857fe2e692774c44960
|
||||
# https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/mkdumprd
|
||||
# https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/dracut-module-setup.sh
|
||||
if [[ $hostonly && "$hostonly_mode" == "strict" && -n "$IN_KDUMP" ]]; then
|
||||
return 0
|
||||
fi
|
||||
# https://github.com/openSUSE/kdump/blob/master/dracut/module-setup.sh
|
||||
if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules " == *\ kdump\ * ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
include ../../common.mak
|
||||
|
||||
ZDEVDIR := 95zdev
|
||||
ZDEVKDUMPDIR := 95zdev-kdump
|
||||
|
||||
# HAVE_DRACUT
|
||||
#
|
||||
@@ -19,5 +20,9 @@ install:
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(ZDEVDIR)
|
||||
$(INSTALL) -m 755 $(ZDEVDIR)/module-setup.sh \
|
||||
$(ZDEVDIR)/parse-zdev.sh \
|
||||
$(ZDEVDIR)/zdev-lib.sh \
|
||||
$(DESTDIR)$(DRACUTMODDIR)/$(ZDEVDIR)/
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(ZDEVKDUMPDIR)
|
||||
$(INSTALL) -m 755 $(ZDEVKDUMPDIR)/module-setup.sh \
|
||||
$(DESTDIR)$(DRACUTMODDIR)/$(ZDEVKDUMPDIR)/
|
||||
endif
|
||||
|
||||
@@ -344,6 +344,68 @@ static struct attrib dasd_attr_fc_security = {
|
||||
.readonly = 1,
|
||||
};
|
||||
|
||||
static struct attrib dasd_attr_aq_mask = {
|
||||
.name = "aq_mask",
|
||||
.title = "Specify autoquiesce triggers",
|
||||
.desc =
|
||||
"Use the aq_mask attribute to automatically quiesce a device and block\n"
|
||||
"new I/O after certain events.\n"
|
||||
"\n"
|
||||
"The value is a bitmask in decimal or hexadecimal format where each set bit\n"
|
||||
"indicates that the associated event shown in the table below triggers an\n"
|
||||
"autoquiesce.\n"
|
||||
" Bit 0 is not used.\n"
|
||||
" 1 - 0x02 - A terminal I/O error occurred\n"
|
||||
" 2 - 0x04 - No active channel paths remain for the device\n"
|
||||
" 3 - 0x08 - A state change interrupt occurred\n"
|
||||
" 4 - 0x10 - The device is PPRC suspended\n"
|
||||
" 5 - 0x20 - No space is left on an ESE device\n"
|
||||
" 6 - 0x40 – The number of timeouts specified in aq_timeouts is reached\n"
|
||||
" 7 - 0x80 - I/O was not started because of an error in the start function\n"
|
||||
"\n"
|
||||
"For example bits 1,3 and 5 set (0010 1010) lead to an integer value of 42\n"
|
||||
"or 0x2A.\n"
|
||||
"An integer value of 0 turns off the autoquiesce function.\n",
|
||||
.order_cmp = ccw_online_only_order_cmp,
|
||||
.check = ccw_online_only_check,
|
||||
.defval = "0",
|
||||
/*
|
||||
* Currently only 8 bits are defined and the max value is 255.
|
||||
* This needs to be adjusted if more bits are defined.
|
||||
*/
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 255)),
|
||||
};
|
||||
|
||||
static struct attrib dasd_attr_aq_requeue = {
|
||||
.name = "aq_requeue",
|
||||
.title = "Control I/O requeing during autoquiesce",
|
||||
.desc =
|
||||
"Use the aq_requeue attribute to control whether outstanding I/O\n"
|
||||
"operations to the blocklayer should be automatically requeued after\n"
|
||||
"an autoquiesce event.\n"
|
||||
"Valid values are 1 for requeuing, or 0 for no requeueing.\n"
|
||||
"Requeing the I/O requests to the blocklayer might benefit I/O\n"
|
||||
"in case of a copy_pair swap operation.\n",
|
||||
.order_cmp = ccw_online_only_order_cmp,
|
||||
.check = ccw_online_only_check,
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
};
|
||||
|
||||
static struct attrib dasd_attr_aq_timeouts = {
|
||||
.name = "aq_timeouts",
|
||||
.title = "Specify timeout retry threshold",
|
||||
.desc =
|
||||
"Specify the number of sequential timeout events for an I/O operation\n"
|
||||
"before an autoquiesce is triggered on a device.\n"
|
||||
"This requires that the corresponding trigger bit 6 is set\n"
|
||||
"in the aq_mask attribute.\n",
|
||||
.order_cmp = ccw_online_only_order_cmp,
|
||||
.check = ccw_online_only_check,
|
||||
.defval = "32768",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 32768)),
|
||||
};
|
||||
|
||||
/*
|
||||
* DASD subtype methods.
|
||||
*/
|
||||
@@ -725,6 +787,9 @@ struct subtype dasd_subtype_eckd = {
|
||||
&dasd_attr_safe_offline,
|
||||
&dasd_attr_fc_security,
|
||||
&dasd_attr_copy_pair,
|
||||
&dasd_attr_aq_mask,
|
||||
&dasd_attr_aq_requeue,
|
||||
&dasd_attr_aq_timeouts,
|
||||
&internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "devnode.h"
|
||||
#include "misc.h"
|
||||
#include "net.h"
|
||||
@@ -55,7 +57,8 @@ static bool add_devnodes_from_link(struct util_list *list,
|
||||
cb_data.prefix_len = strlen(prefix);
|
||||
cb_data.result = false;
|
||||
path = path_get_sys_class("net", devnode->name);
|
||||
path_for_each(path, add_linked_cb, &cb_data);
|
||||
if (util_path_exists(path))
|
||||
path_for_each(path, add_linked_cb, &cb_data);
|
||||
free(path);
|
||||
|
||||
return cb_data.result;
|
||||
|
||||
@@ -603,7 +603,7 @@ exit_code_t select_by_node(struct select_opts *select,
|
||||
|
||||
devnode = devnode_from_node(path, err);
|
||||
if (!devnode)
|
||||
return EXIT_RUNTIME_ERROR;
|
||||
return EXIT_DEVICE_NOT_FOUND;
|
||||
|
||||
rc = select_by_devnode(select, selected, config, scope, only_dt,
|
||||
only_st, devnode, path, err);
|
||||
|
||||
@@ -295,6 +295,7 @@ static exit_code_t udev_ccw_write_device_legacy(struct device *dev, bool autocon
|
||||
}
|
||||
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
||||
fprintf(fd, "\n");
|
||||
fprintf(fd, "LABEL=\"%s\"\n", cfg_label);
|
||||
|
||||
write_attr_to_file(fd, state, id);
|
||||
|
||||
|
||||
@@ -213,16 +213,41 @@ out:
|
||||
static void write_zdev_site_id(int site_id)
|
||||
{
|
||||
FILE *fd;
|
||||
int tmpfd, rc;
|
||||
const char zdev_id_file[] = ZDEV_SITE_ID_FILE;
|
||||
char zdev_id_tmpfile[] = ZDEV_SITE_ID_FILE "-XXXXXX";
|
||||
|
||||
fd = fopen(ZDEV_SITE_ID_FILE, "w");
|
||||
tmpfd = mkstemp(zdev_id_tmpfile);
|
||||
if (tmpfd == -1)
|
||||
goto err;
|
||||
|
||||
/* Open the temp file to use with fprintf */
|
||||
fd = fdopen(tmpfd, "w");
|
||||
if (!fd)
|
||||
err(1, "Could not write to zdev_site_id file");
|
||||
if (site_id == SITE_FALLBACK)
|
||||
fprintf(fd, "ZDEV_SITE_ID=\n");
|
||||
else
|
||||
fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
|
||||
goto err;
|
||||
|
||||
fclose(fd);
|
||||
if (site_id == SITE_FALLBACK)
|
||||
rc = fprintf(fd, "ZDEV_SITE_ID=\"\"\n");
|
||||
else
|
||||
rc = fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
|
||||
|
||||
if (rc < 0) {
|
||||
fclose(fd);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (fclose(fd))
|
||||
goto err;
|
||||
|
||||
/* Rename the temporary file to ZDEV_SITE_ID_FILE*/
|
||||
if (rename(zdev_id_tmpfile, zdev_id_file) == -1) {
|
||||
remove(zdev_id_tmpfile);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return;
|
||||
err:
|
||||
err(1, "Could not write to zdev_site_id file");
|
||||
}
|
||||
|
||||
/* Read the loadparm and extract the current site_id.
|
||||
@@ -265,7 +290,7 @@ static void process_loadparm(const char *filename)
|
||||
out:
|
||||
write_zdev_site_id(site_id);
|
||||
if (site_id == SITE_FALLBACK)
|
||||
printf("ZDEV_SITE_ID=\n");
|
||||
printf("ZDEV_SITE_ID=\"\"\n");
|
||||
else
|
||||
printf("ZDEV_SITE_ID=%d\n", site_id);
|
||||
}
|
||||
|
||||
@@ -39,17 +39,10 @@ check_dep:
|
||||
"curl-devel or libcurl-dev", \
|
||||
"HAVE_CURL=0")
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
FUSE_CFLAGS = $(shell pkg-config --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
||||
CURL_CFLAGS = $(shell pkg-config --silence-errors --cflags libcurl)
|
||||
CURL_LDLIBS = $(shell pkg-config --silence-errors --libs libcurl)
|
||||
else
|
||||
FUSE_CFLAGS = -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
|
||||
FUSE_LDLIBS = -lfuse3
|
||||
CURL_CFLAGS = -I/usr/include/s390x-linux-gnu/curl
|
||||
CURL_LDLIBS = -lcurl
|
||||
endif
|
||||
FUSE_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||
CURL_CFLAGS = $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
|
||||
CURL_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
|
||||
ALL_CPPFLAGS += -DSYSFS
|
||||
ALL_CFLAGS += -DHAVE_SETXATTR -pthread $(FUSE_CFLAGS) $(CURL_CFLAGS)
|
||||
LDLIBS += $(FUSE_LDLIBS) $(CURL_LDLIBS) -lpthread -lrt -lm
|
||||
|
||||
@@ -79,17 +79,10 @@ OBJECTS = zgetdump.o opts.o zg.o zg_error.o zg_print.o \
|
||||
ngdump.o dt_ngdump.o dfi_ngdump.o dfi_vmdump.o \
|
||||
pv_utils.o
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
|
||||
else
|
||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||
GLIB2_LIBS := -lglib-2.0
|
||||
LIBCRYPTO_CFLAGS :=
|
||||
LIBCRYPTO_LIBS := -lcrypto
|
||||
endif
|
||||
GLIB2_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||
|
||||
LIBPV = $(rootdir)/libpv/libpv.a
|
||||
LIBPV_CFLAGS := -DOPENSSL_API_COMPAT=0x10100000L \
|
||||
@@ -101,12 +94,9 @@ LIBPV_LIBS := $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
|
||||
ifeq ("$(HAVE_FUSE)","0")
|
||||
FUSE_CFLAGS = -DHAVE_FUSE=0 -D_FILE_OFFSET_BITS=64
|
||||
FUSE_LDLIBS =
|
||||
else ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
FUSE_CFLAGS = -DHAVE_FUSE=1 $(shell pkg-config --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell pkg-config --silence-errors --libs fuse3)
|
||||
else
|
||||
FUSE_CFLAGS = -DHAVE_FUSE=1 -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse3
|
||||
FUSE_LDLIBS = -lfuse3
|
||||
FUSE_CFLAGS = -DHAVE_FUSE=1 $(shell $(PKG_CONFIG) --silence-errors --cflags fuse3)
|
||||
FUSE_LDLIBS = $(shell $(PKG_CONFIG) --silence-errors --libs fuse3)
|
||||
endif
|
||||
LDLIBS += -lz $(FUSE_LDLIBS) $(LIBPV_LIBS)
|
||||
ALL_CFLAGS += $(FUSE_CFLAGS) $(LIBPV_CFLAGS)
|
||||
|
||||
@@ -27,7 +27,7 @@ check_dep:
|
||||
all: check_dep $(ZFCPDUMP_INITRD) scripts
|
||||
|
||||
cpioinit: cpioinit.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
|
||||
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -o $@ $^
|
||||
|
||||
zfcpdump_part: zfcpdump.o zfcpdump_part.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ -static -o $@
|
||||
|
||||
@@ -123,11 +123,12 @@ sub get_device_data
|
||||
} else {
|
||||
$devices{$hctl}{dev} = glob_last("block\:sd*");
|
||||
}
|
||||
$devices{$hctl}{sg_mm} = get_line("generic", "dev");
|
||||
next if !defined $devices{$hctl}{dev};
|
||||
$c_src = $devices{$hctl}{dev};
|
||||
$devices{$hctl}{dev} =~ s/.*(sd[a-z0-9]+)\Z/$1/
|
||||
unless(!$devices{$hctl}{dev});
|
||||
$devices{$hctl}{mm} = get_line("dev");
|
||||
$devices{$hctl}{sg_mm} = get_line("generic", "dev");
|
||||
$devices{$hctl}{mp_dev} = glob_last("holders", "dm*");
|
||||
$devices{$hctl}{mp_dev} =~ s/.*\/(.+)\Z/$1/
|
||||
unless (!$devices{$hctl}{mp_dev});
|
||||
|
||||
@@ -10,7 +10,7 @@ ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g $(INCLUDE_PARMS) \
|
||||
-fno-delete-null-pointer-checks -fno-stack-protector \
|
||||
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
||||
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
||||
-W -Wall -Wformat-security -fno-sanitize=all
|
||||
-W -Wall -Wformat-security -fno-sanitize=all -Wno-array-bounds
|
||||
ALL_LDFLAGS += -fno-sanitize=all
|
||||
|
||||
FILES = fba0.bin fba1b.bin fba2.bin \
|
||||
|
||||
@@ -29,10 +29,10 @@ int is_zero_block(void *data)
|
||||
return blockptr->cyl || blockptr->head || blockptr->sec;
|
||||
}
|
||||
|
||||
void * load_direct(disk_blockptr_t *data, struct subchannel_id subchannel_id,
|
||||
void *load_addr)
|
||||
void *load_direct(union disk_blockptr *data, struct subchannel_id subchannel_id,
|
||||
void *load_addr)
|
||||
{
|
||||
struct eckd_blockptr_legacy *blockptr = &data->eckd;
|
||||
struct eckd_blockptr_legacy *blockptr = &data->eckd_legacy;
|
||||
struct ccw1 *ccws;
|
||||
unsigned long record_size;
|
||||
struct seek_arg seek_addr;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/*
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
uint64_t __section(.stage2.head) magic = 0x584d554c54363401ULL; /* XMULT64, version 1 */
|
||||
const uint64_t __section(.stage2.head) magic = 0x584d554c54363401ULL; /* XMULT64, version 1 */
|
||||
|
||||
/*
|
||||
* Parameter format for ECKD MV dumper (13 bytes):
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/*
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
uint64_t __section(.stage2.head) magic = 0x5845434b44363401ULL; /* "XECKD64", version 1 */
|
||||
const uint64_t __section(.stage2.head) magic = 0x5845434b44363401ULL; /* "XECKD64", version 1 */
|
||||
|
||||
/*
|
||||
* Get device characteristics from zipl parameter block
|
||||
|
||||
@@ -25,7 +25,7 @@ int is_zero_block(void *data) {
|
||||
return blockptr->blockno;
|
||||
}
|
||||
|
||||
void *load_direct(disk_blockptr_t *data, struct subchannel_id subchannel_id,
|
||||
void *load_direct(union disk_blockptr *data, struct subchannel_id subchannel_id,
|
||||
void *load_addr)
|
||||
{
|
||||
struct linear_blockptr *blockptr = &data->linear;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/*
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
uint64_t __section(.stage2.head) magic = 0x5844464241363401ULL; /* XDFBA64, version 1 */
|
||||
const uint64_t __section(.stage2.head) magic = 0x5844464241363401ULL; /* XDFBA64, version 1 */
|
||||
|
||||
/*
|
||||
* FBA dump device partition specification
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/psw.h"
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
@@ -65,6 +66,7 @@ void __noreturn start(void);
|
||||
void pgm_check_handler(void);
|
||||
void pgm_check_handler_fn(void);
|
||||
void panic_notify(unsigned long reason);
|
||||
void load_wait_psw(uint64_t, struct psw_t *);
|
||||
|
||||
#define panic(reason, ...) \
|
||||
do { \
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "boot/loaders_layout.h"
|
||||
#include "stage2.h"
|
||||
|
||||
static int is_null_descriptor(disk_blockptr_t *address)
|
||||
static int is_null_descriptor(union disk_blockptr *address)
|
||||
{
|
||||
unsigned long long *value = (unsigned long long *)address;
|
||||
|
||||
@@ -28,13 +28,12 @@ static int is_null_descriptor(disk_blockptr_t *address)
|
||||
static void *load_blocklist(struct component_entry *descriptor_address,
|
||||
struct subchannel_id subchannel_id, void *load_address)
|
||||
{
|
||||
disk_blockptr_t *indirect_blocks, *indirect_blockspace,
|
||||
*start_addr;
|
||||
union disk_blockptr *indirect_blocks, *indirect_blockspace, *start_addr;
|
||||
unsigned long length;
|
||||
long long nr_descr;
|
||||
|
||||
/* start address to load first indirect blocks */
|
||||
start_addr = (disk_blockptr_t *)&descriptor_address->data;
|
||||
start_addr = (union disk_blockptr *)&descriptor_address->data;
|
||||
/* get a free page to store indirect blocks in */
|
||||
indirect_blockspace = (void *)get_zeroed_page();
|
||||
|
||||
@@ -90,7 +89,7 @@ void __noreturn start(void)
|
||||
struct subchannel_id subchannel_id;
|
||||
void *load_address;
|
||||
struct component_entry *entry;
|
||||
disk_blockptr_t *blockptr;
|
||||
union disk_blockptr *blockptr;
|
||||
uint64_t load_psw;
|
||||
void *load_page;
|
||||
int config_nr;
|
||||
@@ -106,14 +105,14 @@ void __noreturn start(void)
|
||||
set_device(subchannel_id, ENABLED);
|
||||
|
||||
load_page = (void *)get_zeroed_page();
|
||||
load_address = (disk_blockptr_t *) load_page;
|
||||
load_address = (union disk_blockptr *) load_page;
|
||||
|
||||
/* load blockpointer list to load address */
|
||||
load_direct((disk_blockptr_t *)&stage2_descr, subchannel_id,
|
||||
load_direct((union disk_blockptr *)&stage2_descr, subchannel_id,
|
||||
load_address);
|
||||
|
||||
blockptr = (disk_blockptr_t *)(load_address +
|
||||
sizeof(disk_blockptr_t));
|
||||
blockptr = (union disk_blockptr *)(load_address +
|
||||
sizeof(union disk_blockptr));
|
||||
|
||||
load_direct(&blockptr[config_nr], subchannel_id, load_address);
|
||||
|
||||
@@ -148,4 +147,4 @@ void panic_notify(unsigned long UNUSED(reason))
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t __section(.stage2.head) stage2_head;
|
||||
const uint64_t __section(.stage2.head) stage2_head;
|
||||
|
||||
@@ -26,16 +26,12 @@
|
||||
#include "cio.h"
|
||||
#include "error.h"
|
||||
|
||||
typedef union {
|
||||
struct eckd_blockptr_legacy eckd;
|
||||
struct linear_blockptr linear;
|
||||
} disk_blockptr_t;
|
||||
|
||||
struct stage2_descr {
|
||||
uint8_t reserved[16];
|
||||
} __packed __aligned(8);
|
||||
|
||||
void *load_direct(disk_blockptr_t *, struct subchannel_id , void *);
|
||||
void *load_direct(union disk_blockptr *data, struct subchannel_id sid,
|
||||
void *load_addr);
|
||||
int extract_length(void *);
|
||||
int is_zero_block(void *);
|
||||
void kdump_stage2(unsigned long);
|
||||
|
||||
@@ -37,7 +37,7 @@ struct tape_head {
|
||||
uint64_t ccw2;
|
||||
} __packed;
|
||||
|
||||
struct tape_head __section(.stage2.head) tape_head = {
|
||||
const struct tape_head __section(.stage2.head) tape_head = {
|
||||
.psw = PSW_LOAD | STAGE2_ENTRY, /* Start code at 0x2018 */
|
||||
.ccw1 = 0x0700000060000001ULL, /* Rewind ccw */
|
||||
.ccw2 = 0x0200200020003000ULL, /* CCW to load dump tool to 0x2000 */
|
||||
|
||||
@@ -16,18 +16,20 @@ DRACUT_OMIT_MODULES=(
|
||||
systemd-timedated systemd-timesyncd
|
||||
systemd-networkd systemd-network-manager systemd-coredump)
|
||||
|
||||
[ $# -gt 0 ] || { echo "Usage: $0 <dump partition device>" >&2; exit 1; }
|
||||
function create_dumpfs()
|
||||
{
|
||||
[ "$dryrun" -eq 1 ] && { echo "/dev/null"; return 0; }
|
||||
mkfs -F "$device" >/dev/null || { echo "Couldn't create filesystem on $1." >&2; return 1; }
|
||||
local disk_path=/dev/disk/by-uuid/$(blkid -o value -s UUID "$device")
|
||||
for i in $(seq 0 30)
|
||||
do
|
||||
[ -e "$disk_path" ] && break;
|
||||
sleep 1
|
||||
done
|
||||
|
||||
#
|
||||
# Retrieve partition UUID
|
||||
#
|
||||
# We use PARTUUID because zipl re-formats the given partition after
|
||||
# calling us, therefore, a UUID will change.
|
||||
#
|
||||
device=$(readlink -f $1)
|
||||
disk_path=/dev/disk/by-partuuid/$(blkid -o value -s PARTUUID "$device")
|
||||
|
||||
[ -e "$disk_path" ] || { echo "Couldn't find disk by PARTUUID." >&2; exit 1; }
|
||||
[ -e "$disk_path" ] || { echo "Filesystem device link missing." >&2; return 1; }
|
||||
echo "$disk_path"
|
||||
}
|
||||
|
||||
function get_kernel_version()
|
||||
{
|
||||
@@ -69,6 +71,27 @@ function create_initrd()
|
||||
--kver "$kver" -f "$initrd" 2>&1
|
||||
}
|
||||
|
||||
[ $# -gt 1 ] || { echo "Usage: $0 <dump partition device> <dryrun>" >&2; exit 1; }
|
||||
|
||||
dasd=
|
||||
device=$(readlink -f $1)
|
||||
dryrun=$2
|
||||
type=$(lsblk -dno type "$device")
|
||||
[ "$type" != "part" ] && { echo "$device with type $type is not a partition." >&2; exit 1; }
|
||||
|
||||
case "${device##*/}" in
|
||||
dasd*)
|
||||
dasd=$(dasdview -i "$1"|sed -n 's/busid\s*:\s*\([0-9a-fA-F.]\)/dasd=\1/p')
|
||||
;;
|
||||
nvme*)
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported device $device." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
disk_path=$(create_dumpfs $device)
|
||||
kernel_version=$(get_kernel_version)
|
||||
kernel=$(get_kernel_image "$kernel_version")
|
||||
[ -e "$kernel" ] || { echo "Couldn't find kernel image." >&2; exit 1; }
|
||||
@@ -88,6 +111,6 @@ create_initrd "$disk_path" "$kernel_version" "$initrd"
|
||||
|
||||
echo "kernel=$kernel"
|
||||
echo "initrd=$initrd"
|
||||
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1"
|
||||
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1 $dasd"
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#define BOOTMAP_HEADER_VERSION 1
|
||||
|
||||
#define PROGRAM_TABLE_BLOCK_SIZE 512
|
||||
#define SIGNATURE_MAGIC "~Module signature appended~\n"
|
||||
#define PKCS7_FORMAT 0x01
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ struct disk_blockptr_linear {
|
||||
int blockct;
|
||||
};
|
||||
|
||||
/* Pointer to a block on disk */
|
||||
/* This represents in-memory pointer to a block on disk */
|
||||
typedef union {
|
||||
struct disk_blockptr_chs chs;
|
||||
struct disk_blockptr_linear linear;
|
||||
@@ -95,13 +95,14 @@ int disk_get_info(const char* device, struct job_target_data* target,
|
||||
struct disk_info** info);
|
||||
int disk_is_tape(const char* device);
|
||||
int disk_is_scsi(const char* device, struct job_target_data* target);
|
||||
int disk_is_eckd_ldl(const char* device, struct job_target_data* target);
|
||||
int disk_is_nvme(const char* device, struct job_target_data* target);
|
||||
int disk_get_info_from_file(const char* filename,
|
||||
struct job_target_data* target,
|
||||
struct disk_info** info);
|
||||
void disk_free_info(struct disk_info* info);
|
||||
char* disk_get_type_name(disk_type_t type);
|
||||
char *disk_get_ipl_type(disk_type_t type);
|
||||
char *disk_get_ipl_type(disk_type_t type, int is_dump);
|
||||
int disk_is_large_volume(struct disk_info* info);
|
||||
int disk_cyl_from_blocknum(blocknum_t blocknum, struct disk_info* info);
|
||||
int disk_head_from_blocknum(blocknum_t blocknum, struct disk_info* info);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*
|
||||
*/
|
||||
#include "boot/s390.h" /* for PAGE_SIZE */
|
||||
#include "boot/page.h"
|
||||
|
||||
#define ZIPL_ENVBLK_SIGNATURE "# zIPL Environment Block\n"
|
||||
#define ENVBLK_DEFAULT_IMPORT_SOURCE "/etc/ziplenv"
|
||||
|
||||
@@ -17,15 +17,7 @@
|
||||
#include "zipl.h"
|
||||
#include "boot/boot_defs.h"
|
||||
|
||||
/*
|
||||
* For compatibility reasons zIPL can build multiple "similar"
|
||||
* program tables, which differ only in block pointers format
|
||||
*/
|
||||
enum program_table_id {
|
||||
PROGRAM_TABLE_0,
|
||||
PROGRAM_TABLE_1,
|
||||
NR_PROGRAM_TABLES
|
||||
};
|
||||
#define NR_PROGRAM_TABLES NR_BLKPTR_FORMATS
|
||||
|
||||
enum program_component_id {
|
||||
COMPONENT_ID_HEAP_AREA,
|
||||
@@ -43,6 +35,14 @@ enum program_component_id {
|
||||
NR_PROGRAM_COMPONENTS
|
||||
};
|
||||
|
||||
/* Types of SCSI disk layouts */
|
||||
enum scsi_layout {
|
||||
scsi_layout_pcbios,
|
||||
scsi_layout_sun,
|
||||
scsi_layout_sgi,
|
||||
scsi_layout_unknown
|
||||
};
|
||||
|
||||
struct component_loc {
|
||||
address_t addr;
|
||||
size_t size;
|
||||
@@ -69,7 +69,6 @@ struct program_table {
|
||||
struct install_set {
|
||||
struct program_table tables[NR_PROGRAM_TABLES];
|
||||
struct program_component *components[NR_PROGRAM_COMPONENTS];
|
||||
int nr_tables; /* number of "similar" program tables to be installed */
|
||||
int nr_menu_entries;
|
||||
int fd;
|
||||
char *device;
|
||||
@@ -77,12 +76,27 @@ struct install_set {
|
||||
char *dump_mount_point;
|
||||
unsigned int dump_tmp_dir_created:1;
|
||||
unsigned int dump_mounted:1;
|
||||
unsigned int skip_prepare:1;
|
||||
unsigned int print_details:1;
|
||||
struct disk_info *info;
|
||||
disk_blockptr_t scsi_dump_sb_blockptr;
|
||||
};
|
||||
|
||||
extern struct component_footer component_footers[NR_PROGRAM_COMPONENTS];
|
||||
|
||||
/* Determine SCSI disk layout from the specified BOOTBLOCK. */
|
||||
static inline enum scsi_layout get_scsi_layout(unsigned char *bootblock)
|
||||
{
|
||||
if ((bootblock[510] == 0x55) && (bootblock[511] == 0xaa))
|
||||
return scsi_layout_pcbios;
|
||||
else if ((bootblock[508] == 0xda) && (bootblock[509] == 0xbe))
|
||||
return scsi_layout_sun;
|
||||
else if ((bootblock[0] == 0x0b) && (bootblock[1] == 0xe5) &&
|
||||
(bootblock[2] == 0xa9) && (bootblock[3] == 0x41))
|
||||
return scsi_layout_sgi;
|
||||
return scsi_layout_unknown;
|
||||
}
|
||||
|
||||
static inline component_type component_type_by_id(enum program_component_id id)
|
||||
{
|
||||
return component_footers[id].type;
|
||||
|
||||
@@ -128,6 +128,7 @@ struct job_data {
|
||||
int dry_run;
|
||||
int command_line;
|
||||
int is_secure;
|
||||
int is_ldipl_dump;
|
||||
};
|
||||
|
||||
|
||||
@@ -136,6 +137,6 @@ void job_free(struct job_data* job);
|
||||
int type_from_target(char *target, disk_type_t *type);
|
||||
int check_job_dump_images(struct job_dump_data* dump, char* name);
|
||||
int check_job_images_ngdump(struct job_dump_data* dump, char* name);
|
||||
bool is_ngdump_enabled(const char* device, struct job_target_data* target);
|
||||
bool is_ngdump_enabled(struct job_data *job);
|
||||
|
||||
#endif /* not JOB_H */
|
||||
|
||||
@@ -6,18 +6,20 @@
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
|
||||
[ $# -gt 0 ] || { echo "Usage: $0 <dump partition device>" >&2; exit 1; }
|
||||
function create_dumpfs()
|
||||
{
|
||||
[ "$dryrun" -eq 1 ] && { echo "/dev/null"; return 0; }
|
||||
mkfs -F "$device" >/dev/null || { echo "Couldn't create filesystem on $1." >&2; return 1; }
|
||||
local disk_path=/dev/disk/by-uuid/$(blkid -o value -s UUID "$device")
|
||||
for i in $(seq 0 30)
|
||||
do
|
||||
[ -e "$disk_path" ] && break;
|
||||
sleep 1
|
||||
done
|
||||
|
||||
#
|
||||
# Retrieve partition UUID
|
||||
#
|
||||
# We use PARTUUID because zipl re-formats the given partition after
|
||||
# calling us, therefore, a UUID will change.
|
||||
#
|
||||
device=$(readlink -f $1)
|
||||
disk_path=/dev/disk/by-partuuid/$(blkid -o value -s PARTUUID "$device")
|
||||
|
||||
[ -e "$disk_path" ] || { echo "Couldn't find disk by PARTUUID." >&2; exit 1; }
|
||||
[ -e "$disk_path" ] || { echo "Filesystem device link missing." >&2; return 1; }
|
||||
echo "$disk_path"
|
||||
}
|
||||
|
||||
function get_kernel_version()
|
||||
{
|
||||
@@ -49,6 +51,28 @@ function create_initrd()
|
||||
NGDUMP=y NGDUMP_DEVICE="$disk" mkinitramfs -o "$initrd" "$kver" 2>&1
|
||||
}
|
||||
|
||||
[ $# -gt 1 ] || { echo "Usage: $0 <dump partition device> <dryrun>" >&2; exit 1; }
|
||||
|
||||
device=$(readlink -f $1)
|
||||
dryrun=$2
|
||||
dasd=
|
||||
|
||||
type=$(lsblk -dno type "$device")
|
||||
[ "$type" != "part" ] && { echo "$device with type $type is not a partition." >&2; exit 1; }
|
||||
|
||||
case "${device##*/}" in
|
||||
dasd*)
|
||||
dasd=$(dasdview -i "$1"|sed -n 's/busid\s*:\s*\([0-9a-fA-F.]\)/dasd=\1/p')
|
||||
;;
|
||||
nvme*)
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported device $device." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
disk_path=$(create_dumpfs $device)
|
||||
kernel_version=$(get_kernel_version)
|
||||
kernel=$(get_kernel_image "$kernel_version")
|
||||
[ -e "$kernel" ] || { echo "Couldn't find kernel image." >&2; exit 1; }
|
||||
@@ -68,6 +92,6 @@ create_initrd "$disk_path" "$kernel_version" "$initrd"
|
||||
|
||||
echo "kernel=$kernel"
|
||||
echo "initrd=$initrd"
|
||||
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1"
|
||||
echo "cmdline=reset_devices cgroup_disable=memory nokaslr numa=off irqpoll nr_cpus=1 $dasd"
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -281,6 +281,10 @@ or configuration section on the command line at the same time.
|
||||
.BR "\-D" " or " "\-\-dumptofs"
|
||||
This option has been removed, use --dumpto instead.
|
||||
|
||||
.TP
|
||||
.BR "\-\-ldipl-dump"
|
||||
Install a List-directed dump record instead of a CCW-type dump.
|
||||
|
||||
.TP
|
||||
.BR "\-M <DUMPLIST[,SIZE]>" " or " "--mvdump=<DUMPLIST[,SIZE]>"
|
||||
Install a multi-volume dump record on each device associated with one of the
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_part.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "boot/s390.h"
|
||||
#include "stage3.h"
|
||||
|
||||
#include "boot.h"
|
||||
@@ -119,8 +118,6 @@ void bootmap_store_blockptr(void *buffer, disk_blockptr_t *ptr,
|
||||
}
|
||||
}
|
||||
|
||||
#define PROGRAM_TABLE_BLOCK_SIZE 512
|
||||
|
||||
/* Calculate the maximum number of entries in the program table. INFO
|
||||
* specifies the type of disk. */
|
||||
static int
|
||||
@@ -321,7 +318,7 @@ static int add_component_file_range(struct install_set *bis,
|
||||
size_t size;
|
||||
int rc;
|
||||
|
||||
if (program_table_id)
|
||||
if (bis->skip_prepare)
|
||||
/* skip the preparation work */
|
||||
goto write_segment_table;
|
||||
if (add_files) {
|
||||
@@ -402,7 +399,7 @@ static int add_component_buffer_align(struct install_set *bis, void *buffer,
|
||||
disk_blockptr_t segment;
|
||||
int rc;
|
||||
|
||||
if (program_table_id)
|
||||
if (bis->skip_prepare)
|
||||
/* skip the preparation work */
|
||||
goto write_segment_table;
|
||||
/* Write buffer */
|
||||
@@ -511,9 +508,6 @@ extract_signature(const char *filename, void **ret_signature,
|
||||
memcpy(signature, buffer + size - signature_size - sizeof(*file_sig),
|
||||
signature_size);
|
||||
|
||||
*ret_signature = signature;
|
||||
sig_head->length = signature_size;
|
||||
|
||||
switch (file_sig->id_type) {
|
||||
case PKEY_ID_PKCS7:
|
||||
sig_head->format = PKCS7_FORMAT;
|
||||
@@ -522,8 +516,12 @@ extract_signature(const char *filename, void **ret_signature,
|
||||
error_text("Unsupported signature type %02x",
|
||||
file_sig->id_type);
|
||||
signature_size = 0;
|
||||
free(signature);
|
||||
goto out;
|
||||
}
|
||||
|
||||
sig_head->length = signature_size;
|
||||
*ret_signature = signature;
|
||||
/* return size of signature and corresponding header */
|
||||
signature_size += sizeof(*file_sig);
|
||||
out:
|
||||
@@ -542,13 +540,6 @@ check_remaining_filesize(size_t filesize, size_t signature_size,
|
||||
}
|
||||
}
|
||||
|
||||
static int is_last_table(struct install_set *bis, int table_id)
|
||||
{
|
||||
assert(bis->nr_tables > 0 && bis->nr_tables <= NR_PROGRAM_TABLES);
|
||||
|
||||
return table_id == bis->nr_tables - 1;
|
||||
}
|
||||
|
||||
static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
bool add_envblk, struct job_envblk_data *envblk,
|
||||
struct job_ipl_data *ipl, disk_blockptr_t *program,
|
||||
@@ -556,7 +547,6 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
struct job_target_data *target, int is_secure,
|
||||
int menu_idx, int program_table_id)
|
||||
{
|
||||
int last_table = is_last_table(bis, program_table_id);
|
||||
struct signature_header sig_head;
|
||||
size_t ramdisk_size, image_size;
|
||||
size_t stage3_params_size;
|
||||
@@ -588,7 +578,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
stats.st_size = 0;
|
||||
if (ipl->common.ramdisk != NULL) {
|
||||
/* Add ramdisk */
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
printf(" initial ramdisk...: %s\n", ipl->common.ramdisk);
|
||||
/* Get ramdisk file size */
|
||||
if (stat(ipl->common.ramdisk, &stats)) {
|
||||
@@ -646,7 +636,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
if (signature_size &&
|
||||
(is_secure == SECURE_BOOT_ENABLED ||
|
||||
(is_secure == SECURE_BOOT_AUTO && secure_boot_supported))) {
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
printf(" signature for.....: %s\n", ZIPL_STAGE3_PATH);
|
||||
|
||||
rc = add_component_buffer(bis, signature, sig_head.length,
|
||||
@@ -716,14 +706,14 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
offset += sizeof(struct component_entry);
|
||||
|
||||
/* Add kernel image */
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
printf(" kernel image......: %s\n", ipl->common.image);
|
||||
|
||||
signature_size = extract_signature(ipl->common.image, &signature, &sig_head);
|
||||
if (signature_size &&
|
||||
(is_secure == SECURE_BOOT_ENABLED ||
|
||||
(is_secure == SECURE_BOOT_AUTO && secure_boot_supported))) {
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
printf(" signature for.....: %s\n", ipl->common.image);
|
||||
|
||||
rc = add_component_buffer(bis, signature, sig_head.length,
|
||||
@@ -766,7 +756,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
|
||||
/* Add kernel parmline */
|
||||
if (ipl->common.parmline != NULL) {
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
printf(" kernel parmline...: '%s'\n", ipl->common.parmline);
|
||||
rc = add_component_buffer(bis, ipl->common.parmline,
|
||||
strlen(ipl->common.parmline) + 1,
|
||||
@@ -790,7 +780,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
(is_secure == SECURE_BOOT_ENABLED ||
|
||||
(is_secure == SECURE_BOOT_AUTO &&
|
||||
secure_boot_supported))) {
|
||||
if (verbose && last_table) {
|
||||
if (verbose && bis->print_details) {
|
||||
printf(" signature for.....: %s\n",
|
||||
ipl->common.ramdisk);
|
||||
}
|
||||
@@ -883,7 +873,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
}
|
||||
offset += sizeof(struct component_entry);
|
||||
}
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
print_components(bis, menu_idx);
|
||||
/* Terminate component table */
|
||||
create_component_entry(VOID_ADD(table, offset), NULL,
|
||||
@@ -906,7 +896,6 @@ static int add_segment_program(struct install_set *bis,
|
||||
struct job_target_data *target,
|
||||
int program_table_id)
|
||||
{
|
||||
int last_table = is_last_table(bis, program_table_id);
|
||||
void *table;
|
||||
int offset;
|
||||
int rc;
|
||||
@@ -920,7 +909,7 @@ static int add_segment_program(struct install_set *bis,
|
||||
create_component_header(VOID_ADD(table, offset), type);
|
||||
offset += sizeof(struct component_header);
|
||||
/* Add segment file */
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
printf(" segment file......: %s\n", segment->segment);
|
||||
|
||||
rc = add_component_file(bis, segment->segment, segment->segment_addr, 0,
|
||||
@@ -935,7 +924,7 @@ static int add_segment_program(struct install_set *bis,
|
||||
}
|
||||
offset += sizeof(struct component_entry);
|
||||
/* Print component addresses */
|
||||
if (verbose && last_table)
|
||||
if (verbose && bis->print_details)
|
||||
print_components(bis, 0 /* menu_idx */);
|
||||
/* Terminate component table */
|
||||
create_component_entry(VOID_ADD(table, offset), NULL,
|
||||
@@ -955,7 +944,8 @@ static int add_segment_program(struct install_set *bis,
|
||||
|
||||
static int
|
||||
check_dump_device_late(char *partition, struct disk_info *target_info,
|
||||
struct job_target_data *target)
|
||||
struct job_target_data *target,
|
||||
struct job_data *job)
|
||||
{
|
||||
struct disk_info* info;
|
||||
int rc;
|
||||
@@ -967,8 +957,10 @@ check_dump_device_late(char *partition, struct disk_info *target_info,
|
||||
partition);
|
||||
return rc;
|
||||
}
|
||||
if ((info->type != disk_type_scsi) || (info->partnum == 0)) {
|
||||
error_reason("Device '%s' is not a SCSI partition",
|
||||
if ((job->is_ldipl_dump && info->type != disk_type_eckd_cdl) ||
|
||||
(!job->is_ldipl_dump && info->type != disk_type_scsi) ||
|
||||
info->partnum == 0) {
|
||||
error_reason("Device '%s' is not a SCSI or DASD partition",
|
||||
partition);
|
||||
disk_free_info(info);
|
||||
return -1;
|
||||
@@ -983,12 +975,13 @@ check_dump_device_late(char *partition, struct disk_info *target_info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
|
||||
static int add_dump_program(struct install_set *bis, struct job_data *job,
|
||||
disk_blockptr_t *program, int verbose,
|
||||
component_header_type type,
|
||||
struct job_target_data *target,
|
||||
int program_table_id)
|
||||
{
|
||||
struct job_dump_data *dump = &job->data.dump;
|
||||
struct job_target_data *target = &job->target;
|
||||
struct job_ipl_data ipl;
|
||||
int rc;
|
||||
|
||||
@@ -997,7 +990,7 @@ static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
|
||||
ipl.common = dump->common;
|
||||
|
||||
/* Get file system dump parmline */
|
||||
rc = check_dump_device_late(dump->device, bis->info, target);
|
||||
rc = check_dump_device_late(dump->device, bis->info, target, job);
|
||||
if (rc)
|
||||
return rc;
|
||||
ipl.common.parmline = dump->common.parmline;
|
||||
@@ -1011,11 +1004,11 @@ static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
|
||||
/**
|
||||
* Build a program table from job data and set pointer to program table
|
||||
* block upon success
|
||||
* PROGRAM_TABLE_ID: offset of the program table in the array (@bis->tables)
|
||||
*/
|
||||
static int build_program_table(struct job_data *job,
|
||||
struct install_set *bis, int program_table_id)
|
||||
{
|
||||
int last_table = is_last_table(bis, program_table_id);
|
||||
int entries, component_header;
|
||||
disk_blockptr_t *table;
|
||||
int is_secure;
|
||||
@@ -1033,7 +1026,7 @@ static int build_program_table(struct job_data *job,
|
||||
/* Add programs */
|
||||
switch (job->id) {
|
||||
case job_ipl:
|
||||
if (last_table) {
|
||||
if (bis->print_details) {
|
||||
if (job->command_line)
|
||||
printf("Adding IPL section\n");
|
||||
else
|
||||
@@ -1052,7 +1045,7 @@ static int build_program_table(struct job_data *job,
|
||||
program_table_id);
|
||||
break;
|
||||
case job_segment:
|
||||
if (last_table) {
|
||||
if (bis->print_details) {
|
||||
if (job->command_line)
|
||||
printf("Adding segment load section\n");
|
||||
else
|
||||
@@ -1066,33 +1059,33 @@ static int build_program_table(struct job_data *job,
|
||||
break;
|
||||
case job_dump_partition:
|
||||
/* Only useful for a partition dump that uses a dump kernel*/
|
||||
if (last_table) {
|
||||
if (bis->print_details) {
|
||||
if (job->command_line)
|
||||
printf("Adding dump section\n");
|
||||
else
|
||||
printf("Adding dump section '%s' (default)\n",
|
||||
job->name);
|
||||
}
|
||||
rc = add_dump_program(bis, &job->data.dump, &table[0],
|
||||
rc = add_dump_program(bis, job, &table[0],
|
||||
verbose || job->command_line,
|
||||
COMPONENT_HEADER_DUMP, &job->target,
|
||||
COMPONENT_HEADER_DUMP,
|
||||
program_table_id);
|
||||
break;
|
||||
case job_menu:
|
||||
if (last_table)
|
||||
if (bis->print_details)
|
||||
printf("Building menu '%s'\n", job->name);
|
||||
rc = 0;
|
||||
for (i=0; i < job->data.menu.num; i++) {
|
||||
switch (job->data.menu.entry[i].id) {
|
||||
case job_ipl:
|
||||
if (last_table &&
|
||||
if (bis->print_details &&
|
||||
job->data.menu.entry[i].data.ipl.common.ignore) {
|
||||
printf("Skipping #%d: IPL section '%s' (missing files)\n",
|
||||
job->data.menu.entry[i].pos,
|
||||
job->data.menu.entry[i].name);
|
||||
break;
|
||||
}
|
||||
if (last_table)
|
||||
if (bis->print_details)
|
||||
printf("Adding #%d: IPL section '%s'%s",
|
||||
job->data.menu.entry[i].pos,
|
||||
job->data.menu.entry[i].name,
|
||||
@@ -1102,12 +1095,12 @@ static int build_program_table(struct job_data *job,
|
||||
if (job->data.menu.entry[i].data.ipl.is_kdump) {
|
||||
component_header =
|
||||
COMPONENT_HEADER_DUMP;
|
||||
if (last_table)
|
||||
if (bis->print_details)
|
||||
printf(" (kdump)\n");
|
||||
} else {
|
||||
component_header =
|
||||
COMPONENT_HEADER_IPL;
|
||||
if (last_table)
|
||||
if (bis->print_details)
|
||||
printf("\n");
|
||||
}
|
||||
if (job->is_secure != SECURE_BOOT_UNDEFINED)
|
||||
@@ -1150,7 +1143,7 @@ static int build_program_table(struct job_data *job,
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
if (job->envblk.buf && verbose && last_table)
|
||||
if (job->envblk.buf && verbose && bis->print_details)
|
||||
envblk_print(job->envblk.buf, job->envblk.size);
|
||||
|
||||
if (rc == 0) {
|
||||
@@ -1199,7 +1192,7 @@ static int install_stages_dasd_fba(int fd, char *filename,
|
||||
void *stage2_data;
|
||||
|
||||
switch (program_table_id) {
|
||||
case PROGRAM_TABLE_0:
|
||||
case LEGACY_BLKPTR_FORMAT_ID:
|
||||
/*
|
||||
* This program table is used for CCW-type IPL (see comments
|
||||
* for install_bootloader()).
|
||||
@@ -1220,7 +1213,7 @@ static int install_stages_dasd_fba(int fd, char *filename,
|
||||
return -1;
|
||||
free(stage2_list);
|
||||
break;
|
||||
case PROGRAM_TABLE_1:
|
||||
case BLKPTR_FORMAT_ID:
|
||||
/*
|
||||
* This program table is not used when booting from DASD FBA
|
||||
* (see comments for install_bootloader()
|
||||
@@ -1248,7 +1241,7 @@ static int install_stages_eckd_dasd(int fd, char *filename,
|
||||
void *stage2b_data;
|
||||
|
||||
switch (program_table_id) {
|
||||
case PROGRAM_TABLE_0:
|
||||
case LEGACY_BLKPTR_FORMAT_ID:
|
||||
/*
|
||||
* This program table is used for CCW-type IPL.
|
||||
* Add stage2 loader
|
||||
@@ -1269,7 +1262,7 @@ static int install_stages_eckd_dasd(int fd, char *filename,
|
||||
return -1;
|
||||
free(stage2b_list);
|
||||
break;
|
||||
case PROGRAM_TABLE_1:
|
||||
case BLKPTR_FORMAT_ID:
|
||||
/*
|
||||
* This program table is used for List-Directed IPL,
|
||||
* which doesn't invoke stage2 loader.
|
||||
@@ -1397,11 +1390,17 @@ static int disk_is_appropriate(const struct job_data *job,
|
||||
error_reason("Secure boot forced for improper disk type");
|
||||
return 0;
|
||||
}
|
||||
if (job->id == job_dump_partition &&
|
||||
job->is_ldipl_dump &&
|
||||
info->type != disk_type_eckd_cdl) {
|
||||
error_reason("List-directed dump not support on DASD with LDL format");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
check_dump_device(const struct job_data *job, const struct disk_info *info,
|
||||
check_dump_device(struct job_data *job, const struct disk_info *info,
|
||||
const char *device)
|
||||
{
|
||||
int rc, part_ext;
|
||||
@@ -1415,6 +1414,9 @@ check_dump_device(const struct job_data *job, const struct disk_info *info,
|
||||
if (!disk_is_appropriate(job, info))
|
||||
return -1;
|
||||
|
||||
if (is_ngdump_enabled(job))
|
||||
return 0;
|
||||
|
||||
rc = util_part_search(device, info->geo.start,
|
||||
info->phy_blocks, info->phy_block_size, &part_ext);
|
||||
if (rc <= 0 || part_ext) {
|
||||
@@ -1430,30 +1432,15 @@ check_dump_device(const struct job_data *job, const struct disk_info *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set actual number of "similar" program tables to be installed
|
||||
*/
|
||||
static void set_nr_tables(struct job_data *job, struct install_set *bis)
|
||||
{
|
||||
assert(bis->nr_tables == 0);
|
||||
|
||||
if (bis->info->type == disk_type_eckd_cdl &&
|
||||
(job->id == job_ipl || job->id == job_menu))
|
||||
bis->nr_tables = NR_PROGRAM_TABLES;
|
||||
else
|
||||
bis->nr_tables = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare resources to build a program table
|
||||
*/
|
||||
static int prepare_build_program_table_device(struct job_data *job,
|
||||
struct install_set *bis,
|
||||
int program_table_id)
|
||||
struct install_set *bis)
|
||||
{
|
||||
ulong unused_size;
|
||||
|
||||
if (program_table_id)
|
||||
if (bis->skip_prepare)
|
||||
/* skip the preparation work */
|
||||
return 0;
|
||||
/* Get full path of bootmap file */
|
||||
@@ -1522,19 +1509,26 @@ static int prepare_build_program_table_device(struct job_data *job,
|
||||
bis->filename);
|
||||
return -1;
|
||||
}
|
||||
set_nr_tables(job, bis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bootmap_create_device(struct job_data *job, struct install_set *bis,
|
||||
int program_table_id)
|
||||
/**
|
||||
* Called when making a dump on a raw SCSI partition
|
||||
*/
|
||||
static int prepare_bootloader_device(struct job_data *job,
|
||||
struct install_set *bis)
|
||||
{
|
||||
if (prepare_build_program_table_device(job, bis, program_table_id))
|
||||
if (prepare_build_program_table_device(job, bis))
|
||||
return -1;
|
||||
if (build_program_table(job, bis, program_table_id))
|
||||
/*
|
||||
* build a single program table at offset 1,
|
||||
* see comment before install_bootloader() for details
|
||||
*/
|
||||
bis->print_details = 1;
|
||||
if (build_program_table(job, bis, BLKPTR_FORMAT_ID))
|
||||
return -1;
|
||||
/* Install stage 2 loader to bootmap if necessary */
|
||||
if (bootmap_install_stages(job, bis, program_table_id)) {
|
||||
if (bootmap_install_stages(job, bis, BLKPTR_FORMAT_ID)) {
|
||||
error_text("Could not install loader stages to bootmap");
|
||||
return -1;
|
||||
}
|
||||
@@ -1546,10 +1540,9 @@ static int bootmap_create_device(struct job_data *job, struct install_set *bis,
|
||||
*/
|
||||
static int prepare_build_program_table_file(struct job_data *job,
|
||||
char *bootmap_dir,
|
||||
struct install_set *bis,
|
||||
int program_table_id)
|
||||
struct install_set *bis)
|
||||
{
|
||||
if (program_table_id)
|
||||
if (bis->skip_prepare)
|
||||
/* skip the preparation work */
|
||||
return 0;
|
||||
/* Create temporary bootmap file */
|
||||
@@ -1602,7 +1595,6 @@ static int prepare_build_program_table_file(struct job_data *job,
|
||||
error_text("Could not write to file '%s'", bis->filename);
|
||||
return -1;
|
||||
}
|
||||
set_nr_tables(job, bis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1627,11 +1619,13 @@ static int finalize_create_file(char *bootmap_dir, struct install_set *bis)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bootmap_create_file(struct job_data *job, char *bootmap_dir,
|
||||
struct install_set *bis, int program_table_id)
|
||||
/*
|
||||
* PROGRAM_TABLE_ID: offset of the program table in the array (@bis->tables)
|
||||
*/
|
||||
static int bootmap_create_file(struct job_data *job, struct install_set *bis,
|
||||
char *bootmap_dir, int program_table_id)
|
||||
{
|
||||
if (prepare_build_program_table_file(job, bootmap_dir, bis,
|
||||
program_table_id))
|
||||
if (prepare_build_program_table_file(job, bootmap_dir, bis))
|
||||
return -1;
|
||||
if (build_program_table(job, bis, program_table_id))
|
||||
return -1;
|
||||
@@ -1641,8 +1635,6 @@ static int bootmap_create_file(struct job_data *job, char *bootmap_dir,
|
||||
bis->filename);
|
||||
return -1;
|
||||
}
|
||||
if (!dry_run && is_last_table(bis, program_table_id))
|
||||
return finalize_create_file(bootmap_dir, bis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1680,14 +1672,12 @@ ngdump_create_meta(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bootmap_create_device_ngdump(struct job_data *job,
|
||||
struct install_set *bis,
|
||||
int program_table_id)
|
||||
static int prepare_bootloader_ngdump(struct job_data *job,
|
||||
struct install_set *bis)
|
||||
{
|
||||
struct disk_info *info;
|
||||
int rc;
|
||||
char *bootmap_dir;
|
||||
|
||||
assert(program_table_id == 0);
|
||||
/* Retrieve target device information */
|
||||
if (disk_get_info(job->data.dump.device, &job->target, &info))
|
||||
return -1;
|
||||
@@ -1712,22 +1702,6 @@ static int bootmap_create_device_ngdump(struct job_data *job,
|
||||
return -1;
|
||||
}
|
||||
bis->dump_tmp_dir_created = 1;
|
||||
if (!dry_run) {
|
||||
char *cmd = NULL;
|
||||
util_asprintf(&cmd, "mkfs.%s -qF %s >/dev/null",
|
||||
NGDUMP_FSTYPE, job->data.dump.device);
|
||||
if (verbose)
|
||||
printf("Formatting partition '%s'\n",
|
||||
job->data.dump.device);
|
||||
rc = system(cmd);
|
||||
free(cmd);
|
||||
if (rc) {
|
||||
error_reason(strerror(errno));
|
||||
error_text("Could not format partition '%s':",
|
||||
job->data.dump.device);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Mount partition where bootmap file and also a dump file will
|
||||
* be stored.
|
||||
@@ -1740,29 +1714,47 @@ static int bootmap_create_device_ngdump(struct job_data *job,
|
||||
return -1;
|
||||
}
|
||||
bis->dump_mounted = 1;
|
||||
if (bootmap_create_file(job, bis->dump_mount_point,
|
||||
bis, program_table_id))
|
||||
bootmap_dir = bis->dump_mount_point;
|
||||
/*
|
||||
* Build a single program table for List-Directed IPL
|
||||
* See comments before install_bootloader() for details
|
||||
*/
|
||||
bis->print_details = 1;
|
||||
if (bootmap_create_file(job, bis, bootmap_dir, BLKPTR_FORMAT_ID))
|
||||
return -1;
|
||||
if (ngdump_create_meta(bis->dump_mount_point))
|
||||
if (!dry_run && finalize_create_file(bootmap_dir, bis))
|
||||
return -1;
|
||||
return 0;
|
||||
return ngdump_create_meta(bootmap_dir);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bootmap_create(struct job_data *job, struct install_set *bis,
|
||||
int program_table_id)
|
||||
/**
|
||||
* Build one or two program tables for CCW-type and(or) for List-Direceted IPL
|
||||
* at respective offsets in the array BIS->tables. See the comment before
|
||||
* install_bootloader() for details
|
||||
*/
|
||||
static int prepare_bootloader_ipl(struct job_data *job, struct install_set *bis)
|
||||
{
|
||||
if (job->id == job_dump_partition) {
|
||||
if (is_ngdump_enabled(job->data.dump.device, &job->target))
|
||||
return bootmap_create_device_ngdump(job, bis,
|
||||
program_table_id);
|
||||
else
|
||||
return bootmap_create_device(job, bis,
|
||||
program_table_id);
|
||||
} else
|
||||
return bootmap_create_file(job, job->target.bootmap_dir,
|
||||
bis, program_table_id);
|
||||
char *bootmap_dir = job->target.bootmap_dir;
|
||||
|
||||
/*
|
||||
* Build a program table for List-Directed IPL from
|
||||
* SCSI or ECKD DASD
|
||||
*/
|
||||
bis->print_details = 1;
|
||||
if (bootmap_create_file(job, bis, bootmap_dir, BLKPTR_FORMAT_ID))
|
||||
return -1;
|
||||
if (bis->info->type == disk_type_scsi)
|
||||
/* only one table to be installed per device */
|
||||
return dry_run ? 0 : finalize_create_file(bootmap_dir, bis);
|
||||
/*
|
||||
* Build one more program table for CCW-type IPL from
|
||||
* ECKD DASD
|
||||
*/
|
||||
bis->skip_prepare = 1;
|
||||
bis->print_details = 0;
|
||||
if (bootmap_create_file(job, bis, bootmap_dir, LEGACY_BLKPTR_FORMAT_ID))
|
||||
return -1;
|
||||
return dry_run ? 0 : finalize_create_file(bootmap_dir, bis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1796,20 +1788,19 @@ static int init_bis(struct job_data *job, struct install_set *bis)
|
||||
*/
|
||||
int prepare_bootloader(struct job_data *job, struct install_set *bis)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
secure_boot_supported = check_secure_boot_support();
|
||||
|
||||
rc = init_bis(job, bis);
|
||||
if (rc)
|
||||
return rc;
|
||||
for (i = 0;; i++) {
|
||||
rc = bootmap_create(job, bis, i);
|
||||
if (rc || is_last_table(bis, i))
|
||||
break;
|
||||
if (init_bis(job, bis))
|
||||
return -1;
|
||||
if (job->id == job_dump_partition) {
|
||||
if (is_ngdump_enabled(job))
|
||||
return prepare_bootloader_ngdump(job, bis);
|
||||
else
|
||||
return prepare_bootloader_device(job, bis);
|
||||
} else {
|
||||
return prepare_bootloader_ipl(job, bis);
|
||||
}
|
||||
return rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -509,6 +509,19 @@ disk_is_scsi(const char* device, struct job_target_data* target)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int disk_is_eckd_ldl(const char *device, struct job_target_data *target)
|
||||
{
|
||||
struct disk_info *info;
|
||||
int rc = 0;
|
||||
|
||||
if (disk_get_info(device, target, &info) == -1)
|
||||
return 0;
|
||||
if (info->type == disk_type_eckd_ldl)
|
||||
rc = 1;
|
||||
disk_free_info(info);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
disk_is_nvme(const char* device, struct job_target_data* target)
|
||||
{
|
||||
@@ -828,7 +841,7 @@ disk_get_type_name(disk_type_t type)
|
||||
}
|
||||
|
||||
/* Return IPL types supported for a given disk TYPE */
|
||||
char *disk_get_ipl_type(disk_type_t type)
|
||||
char *disk_get_ipl_type(disk_type_t type, int is_dump)
|
||||
{
|
||||
switch (type) {
|
||||
case disk_type_scsi:
|
||||
@@ -837,7 +850,7 @@ char *disk_get_ipl_type(disk_type_t type)
|
||||
case disk_type_eckd_ldl:
|
||||
return "CCW-";
|
||||
case disk_type_eckd_cdl:
|
||||
return "CCW- and LD-";
|
||||
return is_dump ? "LD-" : "CCW- and LD-";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -45,32 +45,9 @@ static inline unsigned long blk_cnt(int size, struct disk_info *info)
|
||||
return (size + info->phy_block_size - 1) / info->phy_block_size;
|
||||
}
|
||||
|
||||
/* Types of SCSI disk layouts */
|
||||
enum scsi_layout {
|
||||
scsi_layout_pcbios,
|
||||
scsi_layout_sun,
|
||||
scsi_layout_sgi,
|
||||
scsi_layout_unknown
|
||||
};
|
||||
|
||||
/* From linux/fs.h */
|
||||
#define BLKFLSBUF _IO(0x12, 97)
|
||||
|
||||
|
||||
/* Determine SCSI disk layout from the specified BOOTBLOCK. */
|
||||
static enum scsi_layout
|
||||
get_scsi_layout(unsigned char* bootblock)
|
||||
{
|
||||
if ((bootblock[510] == 0x55) && (bootblock[511] == 0xaa))
|
||||
return scsi_layout_pcbios;
|
||||
else if ((bootblock[508] == 0xda) && (bootblock[509] == 0xbe))
|
||||
return scsi_layout_sun;
|
||||
else if ((bootblock[0] == 0x0b) && (bootblock[1] == 0xe5) &&
|
||||
(bootblock[2] == 0xa9) && (bootblock[3] == 0x41))
|
||||
return scsi_layout_sgi;
|
||||
return scsi_layout_unknown;
|
||||
}
|
||||
|
||||
static int
|
||||
overwrite_partition_start(int fd, struct disk_info* info, int mv_dump_magic);
|
||||
|
||||
@@ -112,7 +89,7 @@ update_scsi_mbr(void* bootblock, disk_blockptr_t* table,
|
||||
mbr->version_id = DISK_LAYOUT_ID;
|
||||
bootmap_store_blockptr(&mbr->program_table_pointer, table, info,
|
||||
0 /* this argument is ignored for scsi */);
|
||||
if (scsi_dump_sb_blockptr->linear.block != 0) {
|
||||
if (scsi_dump_sb_blockptr && scsi_dump_sb_blockptr->linear.block != 0) {
|
||||
/* Write dump boot_info */
|
||||
param.block = scsi_dump_sb_blockptr->linear.block *
|
||||
scsi_dump_sb_blockptr->linear.size;
|
||||
@@ -318,35 +295,113 @@ static int install_eckd_cdl_ld(int fd, disk_blockptr_t *br,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install program tables for CCW-type and(or) List-Directed IPL
|
||||
* See the comment before install_bootloader() for details.
|
||||
*
|
||||
* TABLES: array of the program tables to be installed
|
||||
*/
|
||||
int install_bootloader_ipl(struct program_table *tables,
|
||||
struct disk_info *info,
|
||||
int fd)
|
||||
{
|
||||
struct program_table *pt = &tables[LEGACY_BLKPTR_FORMAT_ID];
|
||||
|
||||
int rc = -1;
|
||||
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
/* List-Directed IPL */
|
||||
pt = &tables[BLKPTR_FORMAT_ID];
|
||||
rc = install_scsi(fd, &pt->table, info, NULL);
|
||||
break;
|
||||
case disk_type_fba:
|
||||
rc = install_fba_ccw(fd,
|
||||
&pt->table,
|
||||
pt->stage1b_list,
|
||||
pt->stage1b_count, info);
|
||||
break;
|
||||
case disk_type_eckd_ldl:
|
||||
rc = install_eckd_ldl_ccw(fd,
|
||||
&pt->table,
|
||||
pt->stage1b_list,
|
||||
pt->stage1b_count, info);
|
||||
break;
|
||||
case disk_type_eckd_cdl:
|
||||
rc = install_eckd_cdl_ccw(fd,
|
||||
&pt->table,
|
||||
pt->stage1b_list,
|
||||
pt->stage1b_count, info);
|
||||
if (rc)
|
||||
break;
|
||||
/* install one more table for List-Directed IPL */
|
||||
pt = &tables[BLKPTR_FORMAT_ID];
|
||||
rc = install_eckd_cdl_ld(fd, pt->stage1b_list, info);
|
||||
break;
|
||||
case disk_type_diag:
|
||||
error_reason("Inappropriarte device type (%d) for IPL",
|
||||
info->type);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a program table for List-Directed dump
|
||||
* See the comment before install_bootloader() for details
|
||||
*/
|
||||
static int install_bootloader_dump(struct program_table *tables,
|
||||
struct disk_info *info,
|
||||
disk_blockptr_t *scsi_dump_sb_blockptr,
|
||||
int ngdump_enabled,
|
||||
int fd)
|
||||
{
|
||||
struct program_table *pt = &tables[BLKPTR_FORMAT_ID];
|
||||
int rc = -1;
|
||||
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
rc = install_scsi(fd, &pt->table, info, scsi_dump_sb_blockptr);
|
||||
if (rc == 0 && !ngdump_enabled)
|
||||
rc = overwrite_partition_start(fd, info, 0);
|
||||
break;
|
||||
case disk_type_eckd_cdl:
|
||||
rc = install_eckd_cdl_ld(fd, pt->stage1b_list, info);
|
||||
break;
|
||||
default:
|
||||
error_reason("Inappropriarte device type (%d) for List-Directed dump",
|
||||
info->type);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a "compatible" boot record referring one, or two "similar"
|
||||
* program tables.
|
||||
*
|
||||
* The picture below shows which program table is used for IPL
|
||||
* of specified type from disk of specified type.
|
||||
* E.g. program table "0" is used for CCW-type IPL from ECKD DASD,
|
||||
* LD-IPL from DASD FBA is unsupported (respectively, only one program
|
||||
* table "0" is used), etc.
|
||||
*
|
||||
* CCW-IPL LD-IPL
|
||||
*
|
||||
* SCSI X 0
|
||||
* DASD FBA 0 X
|
||||
* ECKD DASD LDL 0 X
|
||||
* ECKD DASD CDL 0 1
|
||||
* For compatibility reasons zIPL installs multiple "similar"
|
||||
* program tables which differ only in block pointers format.
|
||||
* Each such table is identified by an offset in the array BIS->tables
|
||||
* of in-memory program table representations built by prepare_bootloader().
|
||||
* The common rule is that tables built for CCW-type IPL are placed
|
||||
* at offset 0, and tables built for List-Directed IPL are placed at
|
||||
* offset 1. The same works for dumps.
|
||||
*/
|
||||
int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
{
|
||||
disk_blockptr_t *scsi_dump_sb_blockptr = &bis->scsi_dump_sb_blockptr;
|
||||
struct program_table *pt0 = &bis->tables[PROGRAM_TABLE_0];
|
||||
struct program_table *pt1 = &bis->tables[PROGRAM_TABLE_1];
|
||||
struct disk_info *info = bis->info;
|
||||
char *device = bis->device;
|
||||
int fd, rc;
|
||||
|
||||
if (!info)
|
||||
return 0;
|
||||
/* Inform user about what we're up to */
|
||||
printf("Preparing boot device for %sIPL: ",
|
||||
disk_get_ipl_type(info->type));
|
||||
printf("Preparing boot device for %s%s: ",
|
||||
disk_get_ipl_type(info->type,
|
||||
job->id == job_dump_partition),
|
||||
job->id == job_dump_partition ? "dump" : "IPL");
|
||||
if (info->name) {
|
||||
printf("%s", info->name);
|
||||
if (info->devno >= 0)
|
||||
@@ -379,39 +434,13 @@ int install_bootloader(struct job_data *job, struct install_set *bis)
|
||||
* for CCW-type IPL and (or) for List-Directed IPL (see the
|
||||
* picture in comments above)
|
||||
*/
|
||||
rc = -1;
|
||||
switch (info->type) {
|
||||
case disk_type_scsi:
|
||||
rc = install_scsi(fd, &pt0->table, info,
|
||||
scsi_dump_sb_blockptr);
|
||||
if (rc == 0 && job->id == job_dump_partition &&
|
||||
!is_ngdump_enabled(device, &job->target))
|
||||
rc = overwrite_partition_start(fd, info, 0);
|
||||
break;
|
||||
case disk_type_fba:
|
||||
rc = install_fba_ccw(fd,
|
||||
&pt0->table,
|
||||
pt0->stage1b_list,
|
||||
pt0->stage1b_count, info);
|
||||
break;
|
||||
case disk_type_eckd_ldl:
|
||||
rc = install_eckd_ldl_ccw(fd,
|
||||
&pt0->table,
|
||||
pt0->stage1b_list,
|
||||
pt0->stage1b_count, info);
|
||||
break;
|
||||
case disk_type_eckd_cdl:
|
||||
rc = install_eckd_cdl_ccw(fd,
|
||||
&pt0->table,
|
||||
pt0->stage1b_list,
|
||||
pt0->stage1b_count, info);
|
||||
if (rc)
|
||||
break;
|
||||
rc = install_eckd_cdl_ld(fd, pt1->stage1b_list, info);
|
||||
break;
|
||||
case disk_type_diag:
|
||||
/* Should not happen */
|
||||
break;
|
||||
if (job->id == job_dump_partition) {
|
||||
rc = install_bootloader_dump(bis->tables, info,
|
||||
scsi_dump_sb_blockptr,
|
||||
is_ngdump_enabled(job),
|
||||
fd);
|
||||
} else {
|
||||
rc = install_bootloader_ipl(bis->tables, info, fd);
|
||||
}
|
||||
|
||||
if (fsync(fd))
|
||||
|
||||
@@ -63,6 +63,7 @@ static struct option options[] = {
|
||||
{ "dry-run", no_argument, NULL, '0'},
|
||||
{ "force", no_argument, NULL, 'f'},
|
||||
{ "kdump", required_argument, NULL, 'k'},
|
||||
{ "ldipl-dump", no_argument, NULL, 0xb0},
|
||||
{ "secure", required_argument, NULL, 'S'},
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
@@ -93,6 +94,7 @@ struct command_line {
|
||||
int dry_run;
|
||||
int force;
|
||||
int is_secure;
|
||||
int is_ldipl_dump;
|
||||
enum scan_section_type type;
|
||||
};
|
||||
|
||||
@@ -284,6 +286,9 @@ get_command_line(int argc, char* argv[], struct command_line* line)
|
||||
case 'f':
|
||||
cmdline.force = 1;
|
||||
break;
|
||||
case 0xb0:
|
||||
cmdline.is_ldipl_dump = 1;
|
||||
break;
|
||||
case 1:
|
||||
/* Non-option is interpreted as section name */
|
||||
if (cmdline.section != NULL) {
|
||||
@@ -561,11 +566,13 @@ get_common_components(struct job_common_ipl_data *common,
|
||||
MAXIMUM_PHYSICAL_BLOCKSIZE);
|
||||
if (rc)
|
||||
goto error;
|
||||
rc = set_cl_element(&cl[num++], "parmline", NULL, &common->parm_addr,
|
||||
MAXIMUM_PARMLINE_SIZE, 0,
|
||||
MAXIMUM_PHYSICAL_BLOCKSIZE);
|
||||
if (rc)
|
||||
goto error;
|
||||
if (common->parmline) {
|
||||
rc = set_cl_element(&cl[num++], "parmline", NULL, &common->parm_addr,
|
||||
MAXIMUM_PARMLINE_SIZE, 0,
|
||||
MAXIMUM_PHYSICAL_BLOCKSIZE);
|
||||
if (rc)
|
||||
goto error;
|
||||
}
|
||||
if (common->ramdisk) {
|
||||
rc = set_cl_element(&cl[num++], "initial ramdisk",
|
||||
common->ramdisk, &common->ramdisk_addr,
|
||||
@@ -781,10 +788,13 @@ check_common_ipl_data(struct job_common_ipl_data *common, const char *section,
|
||||
rc = 0;
|
||||
goto skip_image;
|
||||
}
|
||||
fprintf(stderr, "Section '%s': Could not read image file '%s'\n",
|
||||
section, common->image);
|
||||
return rc;
|
||||
}
|
||||
if (size < MAX_COMMAND_LINE_SIZE + sizeof(uint64_t)) {
|
||||
error_text_section("Image file", section, common->image);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -797,8 +807,11 @@ check_common_ipl_data(struct job_common_ipl_data *common, const char *section,
|
||||
error_text("The length of the parameters line "
|
||||
"(%d bytes) exceeds the allowed maximum "
|
||||
"(%d bytes) in section '%s'", len, max_parm_size, section);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
}
|
||||
skip_image:
|
||||
if (common->ramdisk != NULL) {
|
||||
@@ -811,6 +824,8 @@ skip_image:
|
||||
common->ignore = true;
|
||||
rc = 0;
|
||||
} else {
|
||||
fprintf(stderr, "Section '%s': Missing ramdisk file '%s'\n",
|
||||
section, common->ramdisk);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@@ -908,7 +923,7 @@ check_job_images_ngdump(struct job_dump_data* dump, char *name)
|
||||
FILE *fp;
|
||||
int rc;
|
||||
|
||||
misc_asprintf(&ppn_cmd, "%s %s", helper, dump->device);
|
||||
misc_asprintf(&ppn_cmd, "%s %s %d", helper, dump->device, dry_run);
|
||||
printf("Run %s\n", ppn_cmd);
|
||||
|
||||
fp = popen(ppn_cmd, "r");
|
||||
@@ -1972,6 +1987,7 @@ job_get(int argc, char* argv[], struct job_data** data)
|
||||
job->data.mvdump.force = cmdline.force;
|
||||
job->dry_run = cmdline.dry_run;
|
||||
job->is_secure = SECURE_BOOT_UNDEFINED;
|
||||
job->is_ldipl_dump = cmdline.is_ldipl_dump;
|
||||
if (job->verbose)
|
||||
printf("Looking for components in '%s'\n", util_libdir());
|
||||
|
||||
@@ -2014,7 +2030,9 @@ job_get(int argc, char* argv[], struct job_data** data)
|
||||
}
|
||||
|
||||
bool
|
||||
is_ngdump_enabled(const char* device, struct job_target_data* target)
|
||||
is_ngdump_enabled(struct job_data *job)
|
||||
{
|
||||
return disk_is_nvme(device, target);
|
||||
if (job->is_ldipl_dump)
|
||||
return true;
|
||||
return disk_is_nvme(job->data.dump.device, &job->target);
|
||||
}
|
||||
|
||||
@@ -1873,8 +1873,10 @@ void scan_update_bls_path(struct scan_token *scan)
|
||||
if (misc_check_readable_file(file)) {
|
||||
misc_asprintf(&img_value, "%s%s",
|
||||
target_value, file);
|
||||
if (misc_check_readable_file(img_value))
|
||||
if (misc_check_readable_file(img_value)) {
|
||||
free(img_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* when file has stripped the load address part,
|
||||
|
||||
@@ -72,6 +72,7 @@ static const char* usage_text[] = {
|
||||
" stand-alone dump tool",
|
||||
"-d, --dumpto DUMPDEV[,SIZE] Install a system dump record on tape device",
|
||||
" or disk partition DUMPDEV",
|
||||
" --ldipl-dump Install a List-directed dump",
|
||||
"-M, --mvdump DEVLIST[,SIZE] Install a multi-volume dump record on each",
|
||||
" disk partition listed in file DEVLIST",
|
||||
"-f, --force Disable sanity check while producing a",
|
||||
@@ -171,8 +172,9 @@ main(int argc, char* argv[])
|
||||
/* Do it */
|
||||
switch (job->id) {
|
||||
case job_dump_partition:
|
||||
if (disk_is_tape(job->data.dump.device) ||
|
||||
!disk_is_scsi(job->data.dump.device, &job->target)) {
|
||||
if (!is_ngdump_enabled(job) &&
|
||||
(disk_is_tape(job->data.dump.device) ||
|
||||
!disk_is_scsi(job->data.dump.device, &job->target))) {
|
||||
rc = install_dump(job->data.dump.device, &job->target,
|
||||
job->data.dump.mem);
|
||||
break;
|
||||
@@ -184,10 +186,16 @@ main(int argc, char* argv[])
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
if (is_ngdump_enabled(job->data.dump.device, &job->target))
|
||||
if (is_ngdump_enabled(job)) {
|
||||
if (disk_is_eckd_ldl(job->data.dump.device, &job->target)) {
|
||||
error_reason("List-directed dump on ECKD with LDL not supported");
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
rc = check_job_images_ngdump(&job->data.dump, job->name);
|
||||
else
|
||||
} else {
|
||||
rc = check_job_dump_images(&job->data.dump, job->name);
|
||||
}
|
||||
if (rc != 0)
|
||||
break;
|
||||
/* Fall through. */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user