mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6925a30da | ||
|
|
fe4cc7c479 | ||
|
|
fa3cabc8af | ||
|
|
5a9b56f814 | ||
|
|
20145b6d06 | ||
|
|
9561a0b983 | ||
|
|
97fa88299f | ||
|
|
aaaebb2030 | ||
|
|
ff2a403bd2 | ||
|
|
66ed1727f9 | ||
|
|
c33cc5a619 | ||
|
|
cd46297d7c | ||
|
|
07b11982e3 | ||
|
|
35348c302b | ||
|
|
35312d0c47 | ||
|
|
342c6a3707 | ||
|
|
e2a8d85916 | ||
|
|
8f0496b26a | ||
|
|
d03be73536 | ||
|
|
a87268d62e | ||
|
|
9cc06a0529 | ||
|
|
3b1ccce515 | ||
|
|
ffe91d1b30 | ||
|
|
f35c5d01fd | ||
|
|
b23c35c390 | ||
|
|
177cf8cfeb | ||
|
|
f05f7d656b | ||
|
|
0bf4f1b957 | ||
|
|
cd38119888 | ||
|
|
cadef5c0ff | ||
|
|
02e1c783f6 | ||
|
|
07e30951f8 | ||
|
|
0a0b4c3826 | ||
|
|
eade995185 | ||
|
|
0eba8d11df | ||
|
|
257490366b | ||
|
|
5ef1320a7b | ||
|
|
f2f572fa70 | ||
|
|
e655f0cd7b | ||
|
|
68b46eea7a | ||
|
|
9894e391ef | ||
|
|
5982fd98bf | ||
|
|
d5291eed1c | ||
|
|
34260f1736 | ||
|
|
b9b3d2d230 | ||
|
|
4cf8f5f46c | ||
|
|
eba744a25e | ||
|
|
80e0c41b89 | ||
|
|
cdc787db1b | ||
|
|
ef4dc7a45b | ||
|
|
cb3e949772 | ||
|
|
f02de298c1 | ||
|
|
eb0dc13c88 | ||
|
|
d08bd23c1e | ||
|
|
724f1fea2c | ||
|
|
dcc63e6dfc | ||
|
|
576034e94a | ||
|
|
3ec49ba7bd | ||
|
|
60c687238d | ||
|
|
57b992ffa1 | ||
|
|
1f07a41d5a | ||
|
|
512b47c004 | ||
|
|
818ffbc4b0 | ||
|
|
5e65df7375 | ||
|
|
4eb80d14a0 | ||
|
|
7247a61e0b | ||
|
|
c856f28e11 | ||
|
|
ca30cfd341 | ||
|
|
58ecf1f363 | ||
|
|
d36ff82999 | ||
|
|
d4398aea89 | ||
|
|
672548ce30 | ||
|
|
344965bd29 | ||
|
|
d6a96f07c1 | ||
|
|
6a99d95d4f |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -68,6 +68,7 @@ zconf/qeth/lsqeth
|
||||
zconf/scm/lsscm
|
||||
zconf/zcrypt/chzcrypt
|
||||
zconf/zcrypt/lszcrypt
|
||||
zconf/zcrypt/zcryptctl
|
||||
zdev/src/chzdev
|
||||
zdev/src/chzdev_usage.c
|
||||
zdev/src/lszdev
|
||||
@@ -76,7 +77,8 @@ zdsfs/zdsfs
|
||||
zdump/zgetdump
|
||||
zfcpdump/cpioinit
|
||||
zfcpdump/zfcpdump_part
|
||||
zfcpdump/zfcpdump_part.rd
|
||||
zfcpdump/zfcpdump-initrd
|
||||
zfcpdump/10-zfcpdump.install
|
||||
ziomon/ziomon_mgr
|
||||
ziomon/ziomon_util
|
||||
ziomon/ziomon_zfcpdd
|
||||
@@ -89,3 +91,8 @@ zipl/src/chreipl_helper.device-mapper
|
||||
zipl/src/zipl
|
||||
zipl/src/zipl_helper.device-mapper
|
||||
zkey/zkey
|
||||
zkey/zkey-cryptsetup
|
||||
zkey/check-dep-zkey
|
||||
zkey/check-dep-zkey-cryptsetup
|
||||
zkey/detect-libcryptsetup.dep
|
||||
zpcictl/zpcictl
|
||||
|
||||
@@ -16,8 +16,10 @@ List of all individuals having contributed content to s390-tools
|
||||
- Clemens von Mann
|
||||
- Dan Horak
|
||||
- Despina Papadopoulou
|
||||
- Dimitri John Ledkov
|
||||
- Eberhard Pasch
|
||||
- Einar Lueck
|
||||
- Eric Sandeen
|
||||
- Erwin Vicari
|
||||
- Eugene Crosser
|
||||
- Eugene Dvurechenski
|
||||
|
||||
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,5 +1,44 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
* __v2.7.0 (2018-10-31)__
|
||||
|
||||
For Linux kernel version: 4.19
|
||||
|
||||
Add new tool:
|
||||
- zcryptctl: Add zcryptctl for multiple zcrypt node management
|
||||
- zpcictl: Add zpcictl for reporting defective PCI devices
|
||||
|
||||
Changes of existing tools:
|
||||
- qethqoat: Add OSA-Express7S support
|
||||
- lszcrypt: Add support for alternative zcrypt device drivers
|
||||
- zfcpdump: Add install script for zfcpdump
|
||||
- zipl: Make zipl work with XFS by using the FIEMAP mapping ioctl
|
||||
|
||||
Bug Fixes:
|
||||
- lstape: Fix output with SCSI lin_tape and multiple paths to same unit
|
||||
- lstape: Fix output without SCSI generic (sg)
|
||||
- lsluns: Fix to prevent error messages if there are non-zfcp SCSI devices
|
||||
- lstape: Fix to prevent error messages if there are non-zfcp SCSI devices
|
||||
- lstape: Fix description of --type and <devbusid> filter for channel tapes
|
||||
- lstape: Fix SCSI output description in man page
|
||||
- lstape: Fix SCSI HBA CCW device bus-ID e.g. for virtio-scsi-ccw
|
||||
- Direct --help and --version output to stdout for several tools
|
||||
- osasnmpd: Start without real OSA devices
|
||||
|
||||
* __v2.6.0 (2018-08-10)__
|
||||
|
||||
For Linux kernel version: 4.18
|
||||
|
||||
Add new tool:
|
||||
- zkey: Add zkey-cryptsetup tool
|
||||
Changes of existing tools:
|
||||
- netboot: add BOOTIF support
|
||||
|
||||
Bug Fixes:
|
||||
- mon_procd: fix parsing of /proc/<pid>/stat
|
||||
- netboot: Include compressed kernel modules in initramfs
|
||||
- netboot: Send client architecture and handle path prefix
|
||||
|
||||
* __v2.5.0 (2018-06-08)__
|
||||
|
||||
For Linux kernel version: 4.17
|
||||
|
||||
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
all: $(TOOL_DIRS)
|
||||
|
||||
13
README.md
13
README.md
@@ -265,6 +265,8 @@ build options:
|
||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
||||
| openssl | `HAVE_OPENSSL` | zkey |
|
||||
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
||||
| json-c | `HAVE_JSONC` | zkey-cryptsetup |
|
||||
|
||||
This table lists additional build or install options:
|
||||
|
||||
@@ -371,9 +373,12 @@ the different tools are provided:
|
||||
|
||||
* zkey:
|
||||
For building the zkey tools you need openssl version 0.9.7 or newer installed
|
||||
(openssl-devel.rpm). Tip: you may skip the zkey build by adding
|
||||
`HAVE_OPENSSL=0` to the make invocation.
|
||||
(openssl-devel.rpm). Also required are cryptsetup version 2.0.3 or newer
|
||||
(cryptsetup-devel.rpm), and json-c version 0.12 or newer (json-c-devel.rpm).
|
||||
Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0`, and you may
|
||||
may skip the zkey-cryptsetup build by adding `HAVE_CRYPTSETUP2=0`, or
|
||||
`HAVE_JSONC=0` to the make invocation.
|
||||
A new group 'zkeyadm' needs to be created and all users intending to use the
|
||||
tool must be added to this group. The owner of the default key repository
|
||||
tool must be added to this group. The owner of the default key repository
|
||||
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
|
||||
for this group.
|
||||
for this group.
|
||||
|
||||
@@ -76,7 +76,7 @@ static const struct fuse_opt cmsfs_opts[] = {
|
||||
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
fprintf(stdout,
|
||||
"Usage: %s DEVICE MOUNTPOINT [OPTIONS]\n"
|
||||
"\n"
|
||||
"Use the cmsfs-fuse command to read and write files stored on a z/VM CMS disk.\n"
|
||||
@@ -4498,14 +4498,23 @@ static int cmsfs_process_args(void *data, const char *arg, int key,
|
||||
return 1;
|
||||
case KEY_HELP:
|
||||
usage(outargs->argv[0]);
|
||||
|
||||
/*
|
||||
* Usage output needs to go to stdout to be consistent with
|
||||
* coding guidelines. FUSE versions before 3.0.0 print help
|
||||
* output to stderr. Redirect stderr to stdout here to enforce
|
||||
* consistent behavior.
|
||||
*/
|
||||
fflush(stderr);
|
||||
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||
|
||||
fuse_opt_add_arg(outargs, "-ho");
|
||||
cmsfs_fuse_main(outargs, &cmsfs_oper);
|
||||
exit(0);
|
||||
case KEY_VERSION:
|
||||
fprintf(stderr, COMP "FUSE file system for CMS disks "
|
||||
fprintf(stdout, COMP "FUSE file system for CMS disks "
|
||||
"program version %s\n", RELEASE_STRING);
|
||||
fprintf(stderr, "Copyright IBM Corp. 2010, 2017\n");
|
||||
fuse_opt_add_arg(outargs, "--version");
|
||||
fprintf(stdout, "Copyright IBM Corp. 2010, 2017\n");
|
||||
exit(0);
|
||||
|
||||
default:
|
||||
|
||||
11
common.mak
11
common.mak
@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION = 2
|
||||
RELEASE = 5
|
||||
RELEASE = 7
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
@@ -182,9 +182,10 @@ GROUP = $(shell id -gn)
|
||||
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
|
||||
|
||||
# Special defines for zfcpdump
|
||||
ZFCPDUMP_PART_IMAGE = zfcpdump_part.image
|
||||
ZFCPDUMP_PART_RD = zfcpdump_part.rd
|
||||
export ZFCPDUMP_DIR ZFCPDUMP_PART_IMAGE ZFCPDUMP_PART_RD
|
||||
ZFCPDUMP_IMAGE = zfcpdump-image
|
||||
ZFCPDUMP_INITRD = zfcpdump-initrd
|
||||
ZFCPDUMP_FLAVOR = zfcpdump
|
||||
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
|
||||
|
||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
@@ -239,7 +240,7 @@ endif
|
||||
$(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
|
||||
|
||||
%: %.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
%.a:
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
@@ -7,7 +7,7 @@ LDLIBS += -lm
|
||||
OBJECTS = daemon.o cpu.o info.o terms.o config.o main.o getopt.o mem.o
|
||||
|
||||
cpuplugd: $(OBJECTS)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
clean:
|
||||
rm -f cpuplugd $(OBJECTS)
|
||||
|
||||
@@ -1338,7 +1338,7 @@ static int hmcdrv_fuse_main(struct fuse_args *args)
|
||||
*/
|
||||
static void hmcdrv_fuse_usage(const char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
fprintf(stdout,
|
||||
"Usage: %s MOUNTPOINT [OPTIONS]\n\n"
|
||||
"Use the %s command to read files from a HMC drive DVD.\n"
|
||||
"\n"
|
||||
@@ -1450,7 +1450,7 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
|
||||
return 1;
|
||||
|
||||
case HMCDRV_FUSE_OPTKEY_VERSION:
|
||||
fprintf(stderr, HMCDRV_FUSE_LOGHEAD
|
||||
fprintf(stdout, HMCDRV_FUSE_LOGHEAD
|
||||
"HMC drive DVD file system, version %s\n"
|
||||
"Copyright IBM Corp. 2015, 2017\n",
|
||||
HMCDRV_FUSE_RELEASE);
|
||||
@@ -1458,6 +1458,16 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
|
||||
|
||||
case HMCDRV_FUSE_OPTKEY_HELP:
|
||||
hmcdrv_fuse_usage(outargs->argv[0]);
|
||||
|
||||
/*
|
||||
* Usage output needs to go to stdout to be consistent with
|
||||
* coding guidelines. FUSE versions before 3.0.0 print help
|
||||
* output to stderr. Redirect stderr to stdout here to enforce
|
||||
* consistent behavior.
|
||||
*/
|
||||
fflush(stderr);
|
||||
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||
|
||||
fuse_opt_add_arg(outargs, "-ho");
|
||||
hmcdrv_fuse_main(outargs);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
@@ -42,6 +42,9 @@ static inline void util_ptr_vec_free(void **ptr_vec, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ptr_vec || count < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
free(ptr_vec[i]);
|
||||
free(ptr_vec);
|
||||
|
||||
@@ -6,7 +6,7 @@ objects = main.o ccw.o fcp.o system.o shutdown.o \
|
||||
cmd_lsshut.o cmd_chshut.o cmd_lsreipl.o cmd_chreipl.o proc.o
|
||||
|
||||
chreipl: $(objects)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
lsreipl:
|
||||
ln -sf chreipl lsreipl
|
||||
|
||||
@@ -75,9 +75,11 @@ static const struct tool_info iucv_tool[2] = {
|
||||
static void __noreturn usage_exit(const struct tool_info *prg, int is_error,
|
||||
const char *msg)
|
||||
{
|
||||
FILE *file = is_error ? stderr : stdout;
|
||||
|
||||
if (msg != NULL)
|
||||
fprintf(stderr, _("%s: %s\n"), prg->name, msg);
|
||||
fprintf(stderr, _(prg->usage), prg->name, prg->name);
|
||||
fprintf(file, _("%s: %s\n"), prg->name, msg);
|
||||
fprintf(file, _(prg->usage), prg->name, prg->name);
|
||||
exit(is_error ? 1 : 0); /* rc=1 .. invalid args */
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ static void test_util_path_is_xxx(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Usage: util_path_example [sysfs mount point] | "is_xxx"
|
||||
* Usage: util_path_example sysfs [MOUNT_POINT] | is_xxx
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -111,6 +111,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
out_fail:
|
||||
errx(EXIT_FAILURE, "Usage: %s sysfs <path> | is_xxx", argv[0]);
|
||||
errx(EXIT_FAILURE, "Usage: %s sysfs [MOUNT_POINT] | is_xxx", argv[0]);
|
||||
}
|
||||
//! [code]
|
||||
|
||||
@@ -34,6 +34,12 @@ const struct util_prg prg = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct option opt_list[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'v' },
|
||||
{ NULL, no_argument, NULL, 0 },
|
||||
};
|
||||
|
||||
/*
|
||||
* Demonstrate the util_prg_print() functions
|
||||
*/
|
||||
@@ -49,7 +55,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
util_prg_init(&prg);
|
||||
|
||||
while ((opt = getopt(argc, argv, "vhe")) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, "vhe", opt_list, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'v':
|
||||
util_prg_print_version();
|
||||
|
||||
@@ -442,9 +442,9 @@ util_proc_dev_get_entry(dev_t device, int blockdev,
|
||||
|
||||
|
||||
/*
|
||||
* Provide one record form a /proc/mounts like file
|
||||
* Provide one record from a /proc/mounts like file
|
||||
*
|
||||
* The parameter file_name distinguishes the file form procfs which
|
||||
* The parameter file_name distinguishes the file from procfs which
|
||||
* is read, the parameter spec is the selector for the record.
|
||||
*/
|
||||
int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
||||
@@ -456,7 +456,6 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
||||
rc = get_file_buffer(&file, file_name);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = -1;
|
||||
while (!eof(&file)) {
|
||||
rc = scan_mnt_entry(&file, entry);
|
||||
if (rc)
|
||||
@@ -467,6 +466,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
||||
}
|
||||
util_proc_mnt_free_entry(entry);
|
||||
}
|
||||
rc = -1;
|
||||
out_free:
|
||||
free_file_buffer(&file);
|
||||
return rc;
|
||||
|
||||
@@ -59,6 +59,7 @@ static int __scandir(struct dirent ***de_vec, const char *path,
|
||||
int count = 0;
|
||||
DIR *dirp;
|
||||
|
||||
*de_vec = NULL;
|
||||
dirp = opendir(path);
|
||||
if (!dirp)
|
||||
return -1;
|
||||
@@ -134,13 +135,13 @@ int util_scandir_hexsort(const struct dirent **de1, const struct dirent **de2)
|
||||
* directory entries. The entries as well as the pointer array itself are
|
||||
* allocated by the function and has to be released by the user via free.
|
||||
*
|
||||
* @param[out] de_vec Vector of matched directory entries
|
||||
* @param[out] de_vec Vector of matched directory entries, or NULL
|
||||
* @param[in] compar_fn Callback function for sorting the entry list
|
||||
* @param[in] path Path to the directory to scan
|
||||
* @param[in] fmt Format string, describes the search pattern as POSIX regex
|
||||
* @param[in] ... Values for format string
|
||||
*
|
||||
* @returns Number of returned directory entries
|
||||
* @returns Number of returned directory entries, or -1 on error
|
||||
*/
|
||||
int util_scandir(struct dirent ***de_vec,
|
||||
int compar_fn(const struct dirent **first,
|
||||
|
||||
@@ -594,17 +594,18 @@ static void cal_task_pcpu(struct task_t *task, const unsigned long long tics)
|
||||
*/
|
||||
static int read_stat(struct task_t *task)
|
||||
{
|
||||
int ppid, tty, proc;
|
||||
unsigned long flags, pri, nice;
|
||||
unsigned long long maj_flt, utime, stime, cutime, cstime;
|
||||
unsigned long long maj_flt = 0, utime = 0, stime = 0, cutime = 0,
|
||||
cstime = 0;
|
||||
unsigned long flags = 0, pri = 0, nice = 0;
|
||||
char *cmd_start, *cmd_end, *cmdlenp, *cmdp;
|
||||
int ppid = 0, tty = 0, proc = 0, rc;
|
||||
|
||||
snprintf(fname, sizeof(fname), "/proc/%u/stat", task->pid);
|
||||
if (read_file(fname, buf, sizeof(buf) - 1) == -1)
|
||||
return 0;
|
||||
|
||||
cmd_start = strchr(buf, '(') + 1;
|
||||
cmd_end = strchr(cmd_start, ')');
|
||||
cmd_end = strrchr(cmd_start, ')');
|
||||
name_lens.cmd_len = cmd_end - cmd_start;
|
||||
cmdlenp = mon_record + sizeof(struct monwrite_hdr);
|
||||
cmdlenp += sizeof(struct procd_hdr);
|
||||
@@ -625,7 +626,7 @@ static int read_stat(struct task_t *task)
|
||||
memcpy(cmdlenp, &name_lens.cmd_len, sizeof(__u16));
|
||||
|
||||
cmd_end += 2;
|
||||
sscanf(cmd_end,
|
||||
rc = sscanf(cmd_end,
|
||||
"%c %d %*d %*d %d %*d "
|
||||
"%lu %*s %*s %Lu %*s "
|
||||
"%Lu %Lu %Lu %Lu "
|
||||
@@ -642,6 +643,8 @@ static int read_stat(struct task_t *task)
|
||||
&utime, &stime, &cutime, &cstime,
|
||||
&pri, &nice,
|
||||
&proc);
|
||||
if (rc != 12)
|
||||
syslog(LOG_ERR, "bad data in %s \n", fname);
|
||||
task->ppid = (__u32)ppid;
|
||||
task->tty = (__u16)tty;
|
||||
task->flags = (__u32)flags;
|
||||
|
||||
@@ -134,8 +134,8 @@ echo "$cmd: Copying virtio modules"
|
||||
mkdir -p $builddir/$netdir
|
||||
mkdir -p $builddir/$blkdir
|
||||
set +e
|
||||
cp $netdir/virtio_net.ko $builddir/$netdir 2> /dev/null
|
||||
cp $blkdir/virtio_blk.ko $builddir/$blkdir 2> /dev/null
|
||||
cp $netdir/virtio_net.ko* $builddir/$netdir 2> /dev/null
|
||||
cp $blkdir/virtio_blk.ko* $builddir/$blkdir 2> /dev/null
|
||||
set -e
|
||||
|
||||
# Busybox (+ dependencies)
|
||||
@@ -170,7 +170,7 @@ cat <<'EOF' > $builddir/init
|
||||
/bin/mount -t tmpfs none /run
|
||||
|
||||
/sbin/modprobe virtio_net
|
||||
/sbin/udhcpc -O pxeconffile -O pxepathprefix &
|
||||
/sbin/udhcpc -O pxeconffile -O pxepathprefix -x 93:001F &
|
||||
|
||||
/sbin/pxeboot.script
|
||||
EOF
|
||||
@@ -237,6 +237,7 @@ case "$1" in
|
||||
echo " router: $router"
|
||||
echo " domain: $domain $dns"
|
||||
echo " tftp: $siaddr"
|
||||
echo " pxepathprefix: $pxepathprefix"
|
||||
# flush routes
|
||||
/sbin/ip route flush table all
|
||||
# setup if link
|
||||
@@ -272,6 +273,7 @@ case "$1" in
|
||||
echo "siaddr=$siaddr" > $PXECONF
|
||||
echo "interface=$interface" >> $PXECONF
|
||||
echo "ip=$ip" >> $PXECONF
|
||||
echo "pxepathprefix=$pxepathprefix" >> $PXECONF
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -354,7 +356,7 @@ then
|
||||
for c in $CONFIGS
|
||||
do
|
||||
echo "fetching config pxelinux.cfg/$c from $siaddr"
|
||||
if /usr/bin/tftp -g -l /tmp/config -r pxelinux.cfg/$c $siaddr
|
||||
if /usr/bin/tftp -g -l /tmp/config -r ${pxepathprefix}pxelinux.cfg/$c $siaddr
|
||||
then
|
||||
break
|
||||
fi
|
||||
@@ -371,6 +373,7 @@ fi
|
||||
kernel=$(/bin/grep -i "^[[:space:]]*kernel" /tmp/config | sed "s/^[[:space:]]*kernel[[:space:]]*//I")
|
||||
initrd=$(/bin/grep -i "^[[:space:]]*initrd" /tmp/config | sed "s/^[[:space:]]*initrd[[:space:]]*//I")
|
||||
append=$(/bin/grep -i "^[[:space:]]*append" /tmp/config | sed "s/^[[:space:]]*append[[:space:]]*//I")
|
||||
ipappend=$(/bin/grep -i "^[[:space:]]*ipappend" /tmp/config | sed "s/^[[:space:]]*ipappend[[:space:]]*//I")
|
||||
|
||||
if [ -z "$kernel" ]
|
||||
then
|
||||
@@ -378,13 +381,13 @@ then
|
||||
exit
|
||||
else
|
||||
echo fetch kernel $kernel from $siaddr
|
||||
/usr/bin/tftp -g -l /tmp/kernel -r $kernel $siaddr
|
||||
/usr/bin/tftp -g -l /tmp/kernel -r $pxepathprefix$kernel $siaddr
|
||||
fi
|
||||
|
||||
if [ -n "$initrd" ]
|
||||
then
|
||||
echo fetch initrd $initrd from $siaddr
|
||||
/usr/bin/tftp -g -l /tmp/initrd -r $initrd $siaddr
|
||||
/usr/bin/tftp -g -l /tmp/initrd -r $pxepathprefix$initrd $siaddr
|
||||
INITRD="--initrd=/tmp/initrd"
|
||||
else
|
||||
INITRD=""
|
||||
@@ -394,6 +397,9 @@ if [ -z "$append" ]; then
|
||||
echo "Kexec load: kexec -l /tmp/kernel $INITRD"
|
||||
kexec -l /tmp/kernel $INITRD
|
||||
else
|
||||
if [ "$ipappend" = "2" ]; then
|
||||
$append="$append BOOTIF=01-$ifaddr"
|
||||
fi
|
||||
echo "Kexec load: kexec -l /tmp/kernel $INITRD --append=\"$append\""
|
||||
kexec -l /tmp/kernel $INITRD --append="$append"
|
||||
fi
|
||||
|
||||
@@ -85,20 +85,12 @@ void init_ibmOSAMib(void) {
|
||||
|
||||
/* query OSA-E device driver for OSA-E devices and mark them in IF-MIB interface list */
|
||||
osaexp_num = query_OSA_EXP ( &if_list, ifNumber );
|
||||
if ( osaexp_num < 0 )
|
||||
if ( osaexp_num == 0 )
|
||||
{
|
||||
fprintf( stderr, "init_ibmOSAMib(): "
|
||||
"OSA-E device driver query interface ioctl() failed\n"
|
||||
"check agent log file for more details\n"
|
||||
"Cannot start subagent...exiting...\n");
|
||||
exit(1);
|
||||
}
|
||||
else if ( osaexp_num == 0 )
|
||||
{
|
||||
fprintf( stderr, "init_ibmOSAMib(): bad or no OSA-E devices reported\n"
|
||||
"check agent log file for more details\n"
|
||||
"Cannot start subagent...exiting...\n");
|
||||
exit(1);
|
||||
get_time( time_buf );
|
||||
snmp_log( LOG_ERR, "%s init_ibmOSAMib(): none of the %d interfaces is a real "
|
||||
"OSA-E device - starting subagent anyway\n", time_buf, ifNumber);
|
||||
return;
|
||||
}
|
||||
/* end if */
|
||||
|
||||
|
||||
@@ -1204,18 +1204,7 @@ void update_mib_info ()
|
||||
* and mark them in IF-MIB interface list
|
||||
* */
|
||||
osaexp_num = query_OSA_EXP( &tmp_list, if_num );
|
||||
if ( osaexp_num < 0 )
|
||||
{
|
||||
get_time( time_buf );
|
||||
fprintf( stderr, "%s update_mib_info(): "
|
||||
"OSA-E device driver query interface ioctl() "
|
||||
"failed\nupdate_mib_info(): going to stop osasnmpd daemon\n"
|
||||
"update_mib_info(): check subagent logfile for more details\n"
|
||||
"update_mib_info(): sending termination signal to osasnmpd...\n",
|
||||
time_buf );
|
||||
exit(-1);
|
||||
}
|
||||
else if ( osaexp_num == 0 )
|
||||
if ( osaexp_num == 0 )
|
||||
{
|
||||
get_time( time_buf );
|
||||
snmp_log( LOG_ERR, "%s update_mib_info(): "
|
||||
@@ -1698,9 +1687,8 @@ int query_IF_MIB ( IF_LIST** ifList )
|
||||
* IN int if_Number: number of network interfaces
|
||||
* returns: int num - number of OSA Express devices found on this
|
||||
* system (>=0)
|
||||
* -1 -an error occurred , no valid info avail
|
||||
*********************************************************************/
|
||||
int query_OSA_EXP ( IF_LIST** ifList, int if_Number )
|
||||
unsigned int query_OSA_EXP ( IF_LIST** ifList, int if_Number )
|
||||
{
|
||||
int j, num = 0;
|
||||
char time_buf[TIME_BUF_SIZE]; /* date/time buffer */
|
||||
|
||||
@@ -91,7 +91,7 @@ void update_mib_info ( );
|
||||
int query_IF_MIB( IF_LIST** );
|
||||
|
||||
/* retrieves OSA Express interface information from kernel */
|
||||
int query_OSA_EXP ( IF_LIST** ,int );
|
||||
unsigned int query_OSA_EXP ( IF_LIST** ,int );
|
||||
|
||||
/* get time of day */
|
||||
int get_time( char* );
|
||||
|
||||
@@ -208,6 +208,9 @@ static void print_physical(struct qeth_qoat_physical *phdr)
|
||||
case OAT_OSA_GEN_OSAE6S:
|
||||
osagen = "OSA-Express6S";
|
||||
break;
|
||||
case OAT_OSA_GEN_OSAE7S:
|
||||
osagen = "OSA-Express7S";
|
||||
break;
|
||||
default:
|
||||
sprintf(tmp, "unknown (0x%x)", phdr->osa_gen);
|
||||
osagen = tmp;
|
||||
@@ -239,6 +242,9 @@ static void print_physical(struct qeth_qoat_physical *phdr)
|
||||
case OAT_PORT_SPEED_10gbs_full:
|
||||
speed = "10 Gb/s / full duplex";
|
||||
break;
|
||||
case OAT_PORT_SPEED_25gbs_full:
|
||||
speed = "25 Gb/s / full duplex";
|
||||
break;
|
||||
case OAT_PORT_SPEED_UNKNOWN:
|
||||
speed = "unknown / unknown";
|
||||
break;
|
||||
|
||||
@@ -58,6 +58,7 @@ struct qeth_qoat_physical {
|
||||
#define OAT_OSA_GEN_OSAE4S 0x02
|
||||
#define OAT_OSA_GEN_OSAE5S 0x03
|
||||
#define OAT_OSA_GEN_OSAE6S 0x04
|
||||
#define OAT_OSA_GEN_OSAE7S 0x05
|
||||
__u8 osa_gen;
|
||||
#define OAT_PORT_SPEED_UNKNOWN 0x00
|
||||
#define OAT_PORT_SPEED_10mbs_half 0x01
|
||||
@@ -68,6 +69,7 @@ struct qeth_qoat_physical {
|
||||
#define OAT_PORT_SPEED_1000mbs_full 0x06
|
||||
#define OAT_PORT_SPEED_NA 0x07
|
||||
#define OAT_PORT_SPEED_10gbs_full 0x08
|
||||
#define OAT_PORT_SPEED_25gbs_full 0x0A
|
||||
__u8 port_speed;
|
||||
#define OAT_PORT_MEDIA_COPPER 0x01
|
||||
#define OAT_PORT_MEDIA_MULTI_MODE 0x02
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# dbginfo.sh - Tool to collect runtime, configuration, and trace information
|
||||
#
|
||||
# Copyright IBM Corp. 2002, 2017
|
||||
# Copyright IBM Corp. 2002, 2018
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -21,7 +21,7 @@ readonly SCRIPTNAME="${0##*/}"
|
||||
print_version() {
|
||||
cat <<EOF
|
||||
${SCRIPTNAME}: Debug information script version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2002, 2017
|
||||
Copyright IBM Corp. 2002, 2018
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -480,6 +480,7 @@ VM_CMDS="q userid\
|
||||
:q cpus\
|
||||
:q srm\
|
||||
:q vtod\
|
||||
:q time full\
|
||||
:q timezone\
|
||||
:q loaddev\
|
||||
:q v osa\
|
||||
@@ -1016,25 +1017,31 @@ environment_setup()
|
||||
# create gzip-ped tar file
|
||||
create_package()
|
||||
{
|
||||
local rc_tar
|
||||
pr_stdout "Finalizing: Creating archive with collected data"
|
||||
cd "${WORKDIR_BASE}"
|
||||
|
||||
if ! tar -czf "${WORKARCHIVE}" "${WORKDIR_CURRENT}"; then
|
||||
pr_stdout " "
|
||||
pr_stdout "${SCRIPTNAME}: Error: Collection of data failed!"
|
||||
pr_stdout " The creation of \"${WORKARCHIVE}\" was not successful."
|
||||
pr_stdout " Please check the directory \"${WORKDIR_BASE}\""
|
||||
pr_stdout " to provide enough free available space."
|
||||
tar -czf "${WORKARCHIVE}" "${WORKDIR_CURRENT}"
|
||||
rc_tar=$?
|
||||
if [ $rc_tar -eq 0 ]; then
|
||||
chmod 0600 "${WORKARCHIVE}"
|
||||
pr_stdout " "
|
||||
pr_stdout "Collected data was saved to:"
|
||||
pr_stdout " >> ${WORKARCHIVE} <<"
|
||||
pr_stdout " "
|
||||
pr_stdout "Review the collected data before sending to your service organization. "
|
||||
pr_stdout " "
|
||||
elif [ $rc_tar -eq 127 ]; then
|
||||
pr_stdout " "
|
||||
pr_stdout "${SCRIPTNAME}: Error: tar command is not available!"
|
||||
pr_stdout " Please install the corresponding package!"
|
||||
else
|
||||
chmod 0600 "${WORKARCHIVE}"
|
||||
pr_stdout " "
|
||||
pr_stdout "Collected data was saved to:"
|
||||
pr_stdout " >> ${WORKARCHIVE} <<"
|
||||
pr_stdout " "
|
||||
pr_stdout "${SCRIPTNAME}: Error: Collection of data failed!"
|
||||
pr_stdout " The creation of \"${WORKARCHIVE}\" was not successful."
|
||||
pr_stdout " Please check the directory \"${WORKDIR_BASE}\""
|
||||
pr_stdout " to provide enough free available space."
|
||||
fi
|
||||
|
||||
pr_stdout " "
|
||||
pr_stdout "Review the collected data before sending to your service organization. "
|
||||
pr_stdout " "
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
[Unit]
|
||||
Description=CPACF statistics collection daemon process for Linux on System z
|
||||
Documentation=man:cpacfstatsd(8)
|
||||
ConditionVirtualization=no
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
|
||||
@@ -174,7 +174,7 @@ int main(int argc, char *argv[]) {
|
||||
) {
|
||||
switch(c) {
|
||||
case 'h':
|
||||
fprintf(stderr, "%s", help_text);
|
||||
fprintf(stdout, "%s", help_text);
|
||||
exit(0);
|
||||
case 'b':
|
||||
ds.cntrl.blink = 1;
|
||||
|
||||
@@ -9,7 +9,7 @@ libs = $(rootdir)/libvmdump/libvmdump.a
|
||||
objects = vmconvert.o
|
||||
|
||||
vmconvert: $(objects) $(libs)
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
@@ -11,7 +11,7 @@ libs = $(rootdir)/libvmdump/libvmdump.a \
|
||||
objects = vmur.o
|
||||
|
||||
vmur: $(objects) $(libs)
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRSBINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
@@ -111,10 +111,14 @@ In rare situations a device might temporarily not be accessible to
|
||||
the subchannel. Then "none" is displayed as the device identifier and the
|
||||
other device attributes are empty.
|
||||
|
||||
For subchannels bound to an alternate driver (most notably vfio_ccw) the
|
||||
device identifier may also be displayed as "none". In this case use the
|
||||
\fB--vfio\fR option to show VFIO specific subchannel information.
|
||||
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
This man-page was written by Stefan Bader <shbader@de.ibm.com>.
|
||||
New options added by Sebastian Ott <sebott@linux.vnet.ibm.com>.
|
||||
New options added by Sebastian Ott <sebott@linux.ibm.com>.
|
||||
.SH "SEE ALSO"
|
||||
.BR chccwdev (8)
|
||||
.fi
|
||||
|
||||
14
zconf/lsluns
14
zconf/lsluns
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
|
||||
#
|
||||
# Copyright IBM Corp. 2008, 2017
|
||||
# Copyright IBM Corp. 2008, 2018
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -152,6 +152,11 @@ sub get_lun_hash
|
||||
my %lun_hash;
|
||||
|
||||
foreach my $device (</$sg_dir/sg*>) {
|
||||
# skip non-zfcp SCSI devices and avoid file access error messages
|
||||
next unless -r "$device/device/fcp_lun";
|
||||
next unless -r "$device/device/wwpn";
|
||||
next unless -r "$device/device/hba_id";
|
||||
|
||||
my $l = `cat $device/device/fcp_lun`;
|
||||
my $p = `cat $device/device/wwpn`;
|
||||
my $a = `cat $device/device/hba_id`;
|
||||
@@ -170,9 +175,8 @@ sub get_lun_hash
|
||||
sub lsluns_usage {
|
||||
print <<EOD;
|
||||
Usage:
|
||||
This tool is designed for environments where all SCSI devices are attached
|
||||
through the zfcp device driver. Expect error messages in mixed environments
|
||||
such as with iSCSI.
|
||||
This tool is designed for environments with SCSI devices attached
|
||||
through the zfcp device driver.
|
||||
|
||||
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
@@ -220,7 +224,7 @@ EOD
|
||||
|
||||
sub lsluns_version {
|
||||
print "$PROGRAM_NAME: version %S390_TOOLS_VERSION%\n";
|
||||
print "Copyright IBM Corp. 2008, 2017\n";
|
||||
print "Copyright IBM Corp. 2008, 2018\n";
|
||||
}
|
||||
|
||||
sub lsluns_invalid_usage {
|
||||
|
||||
@@ -28,9 +28,8 @@ zfcp-attached LUNs
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This tool is designed for environments where all SCSI devices are attached
|
||||
through the zfcp device driver. Expect error messages in mixed environments
|
||||
such as with iSCSI.
|
||||
This tool is designed for environments with SCSI devices attached
|
||||
through the zfcp device driver.
|
||||
|
||||
.B lsluns
|
||||
lists all logical unit numbers (LUNs) discovered in the
|
||||
|
||||
71
zconf/lstape
71
zconf/lstape
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# lstape - Tool to show information about tape devices
|
||||
#
|
||||
# Copyright IBM Corp. 2003, 2017
|
||||
# Copyright IBM Corp. 2003, 2018
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -48,6 +48,9 @@ function PrintUsage() {
|
||||
: -v|--version
|
||||
: Display the version of the tools package and
|
||||
: the lstape command.
|
||||
:
|
||||
:$(basename $0) without the --ccw-only option causes extra SAN traffic
|
||||
:for each SCSI tape or changer device by invoking the sg_inq command.
|
||||
EOD
|
||||
}
|
||||
|
||||
@@ -55,7 +58,7 @@ function PrintVersion()
|
||||
{
|
||||
cat <<-EOD
|
||||
$CMD: version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2003, 2017
|
||||
Copyright IBM Corp. 2003, 2018
|
||||
EOD
|
||||
}
|
||||
|
||||
@@ -220,6 +223,24 @@ function SysfsCreateListCCW() {
|
||||
' | sort
|
||||
}
|
||||
|
||||
# handle SCSI device not necessarily zfcp-attached, e.g. virtio-scsi-ccw
|
||||
function SCSISearchCCWBusid()
|
||||
{
|
||||
local SCSI_DEV=$1
|
||||
local SDEVCAN=$(readlink -e $SCSI_DEV)
|
||||
while [ -n "$SDEVCAN" ]; do
|
||||
# ascend to parent: strip last path part
|
||||
SDEVCAN=${SDEVCAN%/*}
|
||||
[ -h $SDEVCAN/subsystem ] || continue
|
||||
local SUBSYSTEM=$(readlink -e $SDEVCAN/subsystem)
|
||||
if [ "${SUBSYSTEM##*/}" = "ccw" ]; then
|
||||
echo ${SDEVCAN##*/}
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo "N/A"
|
||||
}
|
||||
|
||||
function SysfsCreateListSCSI()
|
||||
{
|
||||
for SCSI_DEV in $1/bus/scsi/devices/*:*:*:*; do
|
||||
@@ -249,11 +270,16 @@ function SysfsCreateListSCSI()
|
||||
if [ -h $SG_DEV ]; then
|
||||
# deprecated sysfs layout
|
||||
SG_DEV=$(echo $SG_DEV | awk -F: '{print $NF}')
|
||||
else
|
||||
elif [ -d $SCSI_DEV/scsi_generic ]; then
|
||||
SG_DEV=$(basename $SG_DEV/*)
|
||||
else
|
||||
SG_DEV=""
|
||||
fi
|
||||
|
||||
if [ "$SG_INQ" != "" ]; then
|
||||
if [ -z "$SG_DEV" ]; then
|
||||
SG_DEV="N/A"
|
||||
TAPE_SERIAL="NO/SG"
|
||||
elif [ "$SG_INQ" != "" ]; then
|
||||
TAPE_SERIAL=$(
|
||||
sg_inq /dev/$SG_DEV |
|
||||
awk '/serial/{print $NF}'
|
||||
@@ -291,17 +317,31 @@ function SysfsCreateListSCSI()
|
||||
if [ "$CHG_IDX" != "" ]; then
|
||||
TAPE_DEV=$CHG_IDX
|
||||
fi
|
||||
elif [ -r /proc/scsi/$DEV_NAME ]; then
|
||||
if [ "$TAPE_SERIAL" != "NO/INQ" ]; then
|
||||
elif [ "$(echo "$SCSI_LIST"|grep lin_tape)" != "" ]; then
|
||||
# bash glob sorts so IBMtape0 comes before IBMtape0n
|
||||
local IBM_PATH=$(
|
||||
ls -1d $SCSI_DEV/lin_tape/$DEV_NAME[0-9]* |
|
||||
head -n 1)
|
||||
if [ -d "$IBM_PATH" ]; then
|
||||
IBM_IDX=${IBM_PATH##*/}
|
||||
else
|
||||
# deprecated sysfs layout
|
||||
IBM_IDX=$(
|
||||
awk '$3 == "'$TAPE_SERIAL'"{
|
||||
print $1
|
||||
}' /proc/scsi/$DEV_NAME
|
||||
echo "$SCSI_LIST" |
|
||||
awk -F: '/lin_tape\:'"$DEV_NAME"'[0-9]+$/{print $NF}'
|
||||
)
|
||||
fi
|
||||
if [ "$IBM_IDX" != "" ]; then
|
||||
TAPE_DEV=$IBM_IDX
|
||||
fi
|
||||
elif [ -r /proc/scsi/$DEV_NAME ]; then
|
||||
IBM_IDX=$(
|
||||
grep -wF "$SCSI_ID" /proc/scsi/$DEV_NAME |
|
||||
cut -d ' ' -f 1
|
||||
)
|
||||
if [ "$IBM_IDX" != "" ]; then
|
||||
TAPE_DEV=$DEV_NAME$IBM_IDX
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "$SCSIFORMAT" \
|
||||
@@ -313,9 +353,16 @@ function SysfsCreateListSCSI()
|
||||
$STATE
|
||||
|
||||
if $VERBOSE; then
|
||||
if [ -r $SCSI_DEV/hba_id ]; then
|
||||
HBA_ID=$(cat $SCSI_DEV/hba_id)
|
||||
else
|
||||
HBA_ID=$(SCSISearchCCWBusid $SCSI_DEV)
|
||||
fi
|
||||
WWPN="N/A"
|
||||
[ -r $SCSI_DEV/wwpn ] && WWPN=$(cat $SCSI_DEV/wwpn)
|
||||
printf "$SCSIVFORMAT" \
|
||||
$(cat $SCSI_DEV/hba_id) \
|
||||
$(cat $SCSI_DEV/wwpn) \
|
||||
"$HBA_ID" \
|
||||
"$WWPN" \
|
||||
$TAPE_SERIAL
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.\" Copyright 2017 IBM Corp.
|
||||
.\" Copyright 2017, 2018 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH LSTAPE 8 "Jul 2007" "s390-tools"
|
||||
.TH LSTAPE 8 "Jun 2018" "s390-tools"
|
||||
|
||||
.SH NAME
|
||||
lstape \- list tape devices.
|
||||
@@ -20,6 +20,8 @@ lstape \- list tape devices.
|
||||
.br
|
||||
.RB [ -t
|
||||
.IR <device-type> [, <device-type> ] "" ...]
|
||||
.br
|
||||
.RI [ <device-bus-ID> ...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
The lstape command lists all available tape devices on the current host. For
|
||||
@@ -27,19 +29,8 @@ channel attached tape devices this output is the same as the contents of
|
||||
/proc/tapedevices (which is obsolete) but also includes offline devices. By
|
||||
default all tape devices are displayed.
|
||||
|
||||
Since SCSI tape devices are accessed differently to channel attached tape
|
||||
devices they are only visible if they are known to the SCSI layer. There
|
||||
are at least two possible drivers that can claim a SCSI tape device and the
|
||||
lstape command tries to find out which one this is. For the generic tape
|
||||
and changer driver the device names start with "st" or "sch", while for the
|
||||
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
||||
the correct driver could not be obtained.
|
||||
This happens for example if there is no sg_inq command installed which is
|
||||
required to read the drive's serial number which in turn is used to find out
|
||||
the device number of the IBM tape driver.
|
||||
|
||||
The serial number of a SCSI tape can be displayed with the --verbose option. If
|
||||
there is no sg_inq command available "NO/INQ" is shown as the tape's serial.
|
||||
The lstape command without the --ccw-only option causes extra SAN traffic
|
||||
for each SCSI tape or changer device by invoking the sg_inq command.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
@@ -75,12 +66,64 @@ on the output of SCSI devices.
|
||||
|
||||
.TP
|
||||
.BR -t | --type " \fI<device-type>\fR"
|
||||
Limit output to given device types (currently only applies to channel attached
|
||||
Limit output to given device types, for example 3490
|
||||
(currently only applies to channel-attached
|
||||
tape devices).
|
||||
|
||||
.TP
|
||||
\fB<device-type>\fR =
|
||||
Device type of devices that should be displayed (e.g. 3490).
|
||||
.I <device-bus-ID>
|
||||
Limits the output to information about the specified tape device or
|
||||
devices only. For CCW-attached devices only.
|
||||
|
||||
.SH OUTPUT FIELDS FOR SCSI TAPE/CHANGER DEVICES
|
||||
.TP
|
||||
.B Generic
|
||||
SCSI generic device file for the tape drive, for example /dev/sg0.
|
||||
"N/A" if the SCSI generic (sg) kernel functionality is not available.
|
||||
.TP
|
||||
.B Device
|
||||
Main character device node file for accessing the tape drive or medium changer.
|
||||
SCSI tape devices are only visible if they are known to the SCSI layer. There
|
||||
are at least two possible drivers that can claim a SCSI tape device. The
|
||||
lstape command tries to determine the device driver. For the generic tape
|
||||
and changer driver the device names start with "st" or "sch", while for the
|
||||
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
||||
the device driver could not be determined.
|
||||
.TP
|
||||
.B Target
|
||||
Linux SCSI device name in H:C:T:L format.
|
||||
.TP
|
||||
.B Vendor
|
||||
The vendor field from the SCSI device.
|
||||
.TP
|
||||
.B Model
|
||||
The model field from the SCSI device.
|
||||
.TP
|
||||
.B Type
|
||||
"tapedrv" for a tape drive or "changer" for a medium changer.
|
||||
.TP
|
||||
.B State
|
||||
The state of the SCSI device object in the kernel.
|
||||
Any state other than "running" can indicate problems.
|
||||
|
||||
.PP
|
||||
|
||||
For SCSI devices, the --verbose option additionally displays:
|
||||
.TP
|
||||
.B HBA
|
||||
The device bus-ID of the FCP device
|
||||
or of the virtio-scsi-ccw virtual HBA
|
||||
through which the tape drive is attached.
|
||||
"N/A" if the device does not have a sysfs ancestor with subsystem ccw.
|
||||
.TP
|
||||
.B WWPN
|
||||
The WWPN (worldwide port name) of the tape drive in the SAN.
|
||||
"N/A" if device is not attached through zfcp.
|
||||
.TP
|
||||
.B Serial
|
||||
The serial number.
|
||||
"NO/INQ" if there is no sg_inq command available.
|
||||
"NO/SG" if no SCSI generic (sg) kernel support is available.
|
||||
|
||||
.SH EXAMPLES
|
||||
\fBlstape\fR
|
||||
@@ -92,3 +135,8 @@ List all tape devices that are available
|
||||
.RS
|
||||
Show all 3490 CCW devices that are online.
|
||||
.RE
|
||||
|
||||
\fBlstape --scsi-only --verbose\fR
|
||||
.RS
|
||||
Show all SCSI tape or changer devices with maximum information.
|
||||
.RE
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
include ../../common.mak
|
||||
|
||||
all: chzcrypt lszcrypt
|
||||
all: chzcrypt lszcrypt zcryptctl
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
chzcrypt: chzcrypt.o misc.o $(libs)
|
||||
lszcrypt: lszcrypt.o misc.o $(libs)
|
||||
zcryptctl: zcryptctl.o misc.o $(libs)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 chzcrypt $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lszcrypt $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zcryptctl $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 644 -c chzcrypt.8 $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 644 -c lszcrypt.8 $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 644 -c zcryptctl.8 $(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
clean:
|
||||
rm -f *.o chzcrypt lszcrypt
|
||||
rm -f *.o chzcrypt lszcrypt zcryptctl
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
@@ -54,8 +54,8 @@ status.
|
||||
.B -V, --verbose
|
||||
The verbose level for cryptographic device information.
|
||||
With this verbose level additional information like hardware card type,
|
||||
hardware queue depth, pending request queue count, outstanding
|
||||
request queue count, and installed function facilities are displayed.
|
||||
hardware queue depth, pending requests count, installed function
|
||||
facilities and driver binding is displayed.
|
||||
.TP 8
|
||||
.B <device-id>
|
||||
Specifies a cryptographic device to display. A cryptographic device can be
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* lszcrypt - Display zcrypt devices and configuration settings
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2017
|
||||
* Copyright IBM Corp. 2008, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -56,6 +56,25 @@ struct lszcrypt_l *lszcrypt_l = &l;
|
||||
#define MASK_CLASS_STATELESS 0x00400000
|
||||
#define CLASS_STATELESS "restricted function set"
|
||||
|
||||
/*
|
||||
* facility bits
|
||||
*/
|
||||
#define MAX_FAC_BITS 9
|
||||
static struct fac_bits_s {
|
||||
int mask;
|
||||
char c;
|
||||
} fac_bits[MAX_FAC_BITS] = {
|
||||
{ 0x80000000, 'S' },
|
||||
{ 0x40000000, 'M' },
|
||||
{ 0x20000000, 'C' },
|
||||
{ 0x10000000, 'D' },
|
||||
{ 0x08000000, 'A' },
|
||||
{ 0x04000000, 'X' },
|
||||
{ 0x02000000, 'N' },
|
||||
{ 0x00800000, 'F' },
|
||||
{ 0x00400000, 'R' },
|
||||
};
|
||||
|
||||
/*
|
||||
* Program configuration
|
||||
*/
|
||||
@@ -66,7 +85,7 @@ const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
.pub_last = 2017,
|
||||
.pub_last = 2018,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -255,7 +274,8 @@ static void show_capability(const char *id_str)
|
||||
/* Skip devices, which are not supported by zcrypt layer */
|
||||
if (!util_path_is_readable("%s/type", dev) ||
|
||||
!util_path_is_readable("%s/online", dev)) {
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.\n", card, hwtype);
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.\n",
|
||||
card, hwtype);
|
||||
return;
|
||||
}
|
||||
cbuf[0] = '\0';
|
||||
@@ -299,11 +319,13 @@ static void show_capability(const char *id_str)
|
||||
} else if (func_val & MASK_EP11) {
|
||||
printf("%s", CAP_EP11);
|
||||
} else {
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.",
|
||||
card, hwtype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.",
|
||||
card, hwtype);
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
@@ -315,17 +337,22 @@ static void show_capability(const char *id_str)
|
||||
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
unsigned long facility;
|
||||
char buf[256];
|
||||
unsigned long facility;
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
|
||||
util_rec_set(rec, "type", buf);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/%s/online", grp_dev, sub_dev);
|
||||
if (strcmp(buf, "0") == 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
|
||||
util_rec_set(rec, "type", "-");
|
||||
else
|
||||
util_rec_set(rec, "online", "online");
|
||||
util_rec_set(rec, "type", buf);
|
||||
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
|
||||
grp_dev, sub_dev))
|
||||
util_rec_set(rec, "online", "-");
|
||||
else
|
||||
if (strcmp(buf, "0") == 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
else
|
||||
util_rec_set(rec, "online", "online");
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (facility & MASK_COPRO)
|
||||
@@ -339,7 +366,7 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/%s/request_count",
|
||||
grp_dev, sub_dev);
|
||||
util_rec_set(rec, "request_count", buf);
|
||||
util_rec_set(rec, "requests", buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -348,20 +375,19 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||
static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
int i;
|
||||
unsigned long facility;
|
||||
char buf[256];
|
||||
long depth;
|
||||
char buf[256], afile[PATH_MAX];
|
||||
long depth, pending1, pending2;
|
||||
|
||||
if (l.verbose == 0)
|
||||
return;
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/%s/pendingq_count",
|
||||
grp_dev, sub_dev);
|
||||
util_rec_set(rec, "pendingq_count", buf);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/%s/requestq_count",
|
||||
grp_dev, sub_dev);
|
||||
util_rec_set(rec, "requestq_count", buf);
|
||||
util_file_read_l(&pending1, 10, "%s/%s/pendingq_count",
|
||||
grp_dev, sub_dev);
|
||||
util_file_read_l(&pending2, 10, "%s/%s/requestq_count",
|
||||
grp_dev, sub_dev);
|
||||
util_rec_set(rec, "pending", "%ld", pending1 + pending2);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
||||
util_rec_set(rec, "hwtype", buf);
|
||||
@@ -370,7 +396,18 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
util_rec_set(rec, "facility", "0x%08x", facility);
|
||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
buf[i] = '\0';
|
||||
util_rec_set(rec, "facility", buf);
|
||||
|
||||
snprintf(afile, sizeof(afile), "%s/%s/driver", grp_dev, sub_dev);
|
||||
afile[sizeof(afile) - 1] = '\0';
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (readlink(afile, buf, sizeof(buf)) > 0)
|
||||
util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
|
||||
else
|
||||
util_rec_set(rec, "driver", "-no-driver-");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -382,9 +419,13 @@ static void show_subdevice(struct util_rec *rec, const char *grp_dev,
|
||||
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
|
||||
|
||||
/* Skip devices, which are not supported by zcrypt layer */
|
||||
if (!util_path_is_readable("%s/type", grp_dev) ||
|
||||
!util_path_is_readable("%s/%s/online", grp_dev, sub_dev))
|
||||
/*
|
||||
* If not verbose mode, skip devices which are not supported
|
||||
* by the zcrypt layer.
|
||||
*/
|
||||
if (l.verbose == 0 &&
|
||||
(!util_path_is_readable("%s/type", grp_dev) ||
|
||||
!util_path_is_readable("%s/%s/online", grp_dev, sub_dev)))
|
||||
return;
|
||||
|
||||
util_rec_set(rec, "card", sub_dev);
|
||||
@@ -414,11 +455,13 @@ static void show_subdevices(struct util_rec *rec, const char *grp_dev)
|
||||
*/
|
||||
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||
{
|
||||
unsigned long facility;
|
||||
char buf[256];
|
||||
unsigned long facility;
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
|
||||
util_rec_set(rec, "type", buf);
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
|
||||
util_rec_set(rec, "type", "-");
|
||||
else
|
||||
util_rec_set(rec, "type", buf);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (facility & MASK_COPRO)
|
||||
@@ -430,14 +473,16 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||
else
|
||||
util_rec_set(rec, "mode", "Unknown");
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev);
|
||||
if (strcmp(buf, "0") == 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
|
||||
util_rec_set(rec, "online", "-");
|
||||
else
|
||||
util_rec_set(rec, "online", "online");
|
||||
if (strcmp(buf, "0") == 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
else
|
||||
util_rec_set(rec, "online", "online");
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
||||
util_rec_set(rec, "request_count", buf);
|
||||
util_rec_set(rec, "requests", buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -445,18 +490,17 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||
*/
|
||||
static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
{
|
||||
int i;
|
||||
unsigned long facility;
|
||||
char buf[256];
|
||||
long depth;
|
||||
char buf[256], afile[PATH_MAX];
|
||||
long depth, pending1, pending2;
|
||||
|
||||
if (l.verbose == 0)
|
||||
return;
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/pendingq_count", grp_dev);
|
||||
util_rec_set(rec, "pendingq_count", buf);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/requestq_count", grp_dev);
|
||||
util_rec_set(rec, "requestq_count", buf);
|
||||
util_file_read_l(&pending1, 10, "%s/pendingq_count", grp_dev);
|
||||
util_file_read_l(&pending2, 10, "%s/requestq_count", grp_dev);
|
||||
util_rec_set(rec, "pending", "%ld", pending1 + pending2);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
||||
util_rec_set(rec, "hwtype", buf);
|
||||
@@ -465,7 +509,18 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
util_rec_set(rec, "facility", "0x%08x", facility);
|
||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
buf[i] = '\0';
|
||||
util_rec_set(rec, "facility", buf);
|
||||
|
||||
snprintf(afile, sizeof(afile), "%s/driver", grp_dev);
|
||||
afile[sizeof(afile) - 1] = '\0';
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (readlink(afile, buf, sizeof(buf)) > 0)
|
||||
util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
|
||||
else
|
||||
util_rec_set(rec, "driver", "-no-driver-");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -481,9 +536,14 @@ static void show_device(struct util_rec *rec, const char *device)
|
||||
grp_dev = util_path_sysfs("devices/ap/%s", device);
|
||||
if (!util_path_is_dir(grp_dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
||||
/* Skip devices, which are not supported by zcrypt layer */
|
||||
if (!util_path_is_readable("%s/type", grp_dev) ||
|
||||
!util_path_is_readable("%s/online", grp_dev)) {
|
||||
|
||||
/*
|
||||
* If not verbose mode, skip devices which are not supported
|
||||
* by the zcrypt layer.
|
||||
*/
|
||||
if (l.verbose == 0 &&
|
||||
(!util_path_is_readable("%s/type", grp_dev) ||
|
||||
!util_path_is_readable("%s/online", grp_dev))) {
|
||||
goto out_free;
|
||||
}
|
||||
util_rec_set(rec, "card", card);
|
||||
@@ -506,8 +566,7 @@ static void define_rec_default(struct util_rec *rec)
|
||||
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
|
||||
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
|
||||
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
|
||||
util_rec_def(rec, "request_count", UTIL_REC_ALIGN_RIGHT, 11,
|
||||
"REQUEST_CNT");
|
||||
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -517,13 +576,11 @@ static void define_rec_verbose(struct util_rec *rec)
|
||||
{
|
||||
if (l.verbose == 0)
|
||||
return;
|
||||
util_rec_def(rec, "pendingq_count", UTIL_REC_ALIGN_RIGHT, 12,
|
||||
"PENDINGQ_CNT");
|
||||
util_rec_def(rec, "requestq_count", UTIL_REC_ALIGN_RIGHT, 12,
|
||||
"REQUESTQ_CNT");
|
||||
util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 7, "HW_TYPE");
|
||||
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 7, "Q_DEPTH");
|
||||
util_rec_def(rec, "pending", UTIL_REC_ALIGN_RIGHT, 8, "PENDING");
|
||||
util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 6, "HWTYPE");
|
||||
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
||||
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
||||
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
147
zconf/zcrypt/zcryptctl.8
Normal file
147
zconf/zcrypt/zcryptctl.8
Normal file
@@ -0,0 +1,147 @@
|
||||
.\" zcryptctl.8
|
||||
.\"
|
||||
.\" Copyright 2018 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.\" use
|
||||
.\" groff -man -Tutf8 zcryptctl.8
|
||||
.\" or
|
||||
.\" nroff -man zcryptctl.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
.TH ZCRYPTCTL 8 "AUG 2018" "s390-tools"
|
||||
.SH NAME
|
||||
zcryptctl \- display information and administrate zcrypt multiple device nodes
|
||||
.SH SYNOPSIS
|
||||
.TP 8
|
||||
.B zcryptctl list
|
||||
.TP
|
||||
.B zcryptctl create
|
||||
.R [
|
||||
.I node-name
|
||||
.R ]
|
||||
.TP
|
||||
.B zcryptctl destroy
|
||||
.I node-name
|
||||
.TP
|
||||
.B zcryptctl addap
|
||||
.R |
|
||||
.B delap
|
||||
.I node-name adapter-nr
|
||||
.TP
|
||||
.B zcryptctl adddom
|
||||
.R |
|
||||
.B deldom
|
||||
.I node-name domain-nr
|
||||
.TP
|
||||
.B zcryptctl addioctl
|
||||
.R |
|
||||
.B delioctl
|
||||
.I node-name ioctl-term
|
||||
.TP
|
||||
.B zcryptctl config
|
||||
.I config-file
|
||||
.TP
|
||||
.B zcryptctl listconfig
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B zcryptctl
|
||||
command displays information and maintains the multi device node
|
||||
extension for the zcrypt device driver.
|
||||
.P
|
||||
With the multi device node extension you can create and configure
|
||||
additional zcrypt device nodes which can be used as alternate device
|
||||
nodes to access the crypto hardware provided by the zcrypt device
|
||||
driver. Each zcrypt device node can be restricted in terms of crypto
|
||||
cards, domains, and available ioctls. Such a device node can be used
|
||||
as a base for container solutions like Docker to control and restrict
|
||||
the access to crypto resources.
|
||||
.SH COMMANDS
|
||||
.TP 8
|
||||
.B zcryptctl list
|
||||
Show all the additional device nodes that are currently active.
|
||||
.TP
|
||||
.B zcryptctl create
|
||||
.R [
|
||||
.I node-name
|
||||
.R ]
|
||||
Create a new zcrypt device node. The \fInode-name\fP might be given
|
||||
and needs to be unique and not in use. If there is no node name
|
||||
provided, the zcrypt device driver will create a new one with pattern
|
||||
zcrypt_\fIx\fP, with \fIx\fP being the next free number. Up to 256
|
||||
additional device nodes can be created. The newly created additional
|
||||
device node appears in /dev and has read and write permissions enabled
|
||||
only for root. By default all adapters, domains and ioctls are
|
||||
initially disabled on this new device node.
|
||||
.TP
|
||||
.B zcryptctl destroy
|
||||
.I node-name
|
||||
Destroy an additional zcrypt device node. The device node is only
|
||||
marked for disposal and destroyed when it is no longer used.
|
||||
.TP
|
||||
.B zcryptctl addap
|
||||
.R |
|
||||
.B delap
|
||||
.I node-name adapter-nr
|
||||
Update the filter for the specified zcrypt device node and add or
|
||||
delete a crypto adapter to be accessible via this node. The symbol
|
||||
\fBALL\fP can be used to enable or disable all adapters.
|
||||
.TP
|
||||
.B zcryptctl adddom
|
||||
.R |
|
||||
.B deldom
|
||||
.I node-name domain-nr
|
||||
Update the filter for the specified zcrypt device node and add or
|
||||
delete a domain to be accessible through this node. The symbol
|
||||
\fBALL\fP can be used to enable or disable all domains.
|
||||
.TP
|
||||
.B zcryptctl addioctl
|
||||
.R |
|
||||
.B delioctl
|
||||
.I node-name ioctl-term
|
||||
Update the filter for the specified zcrypt device node and add or
|
||||
delete an ioctl. The ioctl might be specified as symbolic string (one
|
||||
of \fBICARSAMODEXPO\fP, \fBICARSACRT\fP, \fBZSECSENDCPRB\fP,
|
||||
\fBZSENDEP11CPRB\fP, \fBZCRYPT_DEVICE_STATUS\fP,
|
||||
\fBZCRYPT_STATUS_MASK\fP, \fBZCRYPT_QDEPTH_MASK\fP,
|
||||
\fBZCRYPT_PERDEV_REQCNT\fP) or numeric value in the range 0-255 and
|
||||
the symbol \fBALL\fP can be used to include all ioctls.
|
||||
.TP
|
||||
.B zcryptctl config
|
||||
.I config-file
|
||||
Process a config file. The given configuration file is read line by
|
||||
line and the settings are applied. Syntax is simple:
|
||||
.RS
|
||||
.IP "node=<node-name>"
|
||||
.IP "aps=<list of ap numbers separated by space, tab or ','>"
|
||||
.IP "doms=<list of domain numbers separated by space, tab or ','>"
|
||||
.IP "ioctls=<list of ioctl as numeric or symbolic number separated by space, tab or ','>"
|
||||
.LP
|
||||
Empty lines are ignored and the '#' marks the rest of the
|
||||
line as comment.
|
||||
.LP
|
||||
The \fBnode=\fP line creates a new zcrypt device node, the \fBaps=\fP,
|
||||
\fBdoms=\fP and \fBioctls=\fP lines customize the previously created
|
||||
node. The symbol \fBALL\fP is also recognized for aps, doms, and
|
||||
ioctls.
|
||||
.LP
|
||||
Each action must fit into one line, spreading over multiple lines is
|
||||
not supported. But you can use more than one \fBaps=\fP, \fBdoms=\fP
|
||||
and \fBioctls=\fP lines to customize the very same node.
|
||||
.LP
|
||||
Processing stops when a line cannot be parsed or the current action
|
||||
fails. In this case the exit status is non zero but the successful
|
||||
actions until the failure occurs are not rolled back.
|
||||
.RE
|
||||
.TP
|
||||
.B zcryptctl listconfig
|
||||
List the current configuration in a form suitable for input to the
|
||||
\fBzcryptctl config\fP command.
|
||||
.LP
|
||||
.SH EXIT STATUS
|
||||
On successful completion of the command the exit status is 0. A non
|
||||
zero return code (and some kind of failure message) is emitted if the
|
||||
processing could not complete successful.
|
||||
.SH SEE ALSO
|
||||
\fBlszcrypt\fR(8)
|
||||
1030
zconf/zcrypt/zcryptctl.c
Normal file
1030
zconf/zcrypt/zcryptctl.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -62,10 +62,12 @@ struct ccw_devinfo {
|
||||
* ccw_subtype_data - CCW subtype specific information
|
||||
* @ccwdrv: The name of the CCW device driver for this subtype
|
||||
* @mod: The name of the main kernel module for this subtype
|
||||
* @any_driver: If set, the exact driver for this subtype are not known
|
||||
*/
|
||||
struct ccw_subtype_data {
|
||||
const char *ccwdrv;
|
||||
const char *mod;
|
||||
bool any_driver;
|
||||
};
|
||||
|
||||
extern struct attrib ccw_attr_online;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define UDEV_SUFFIX ".rules"
|
||||
|
||||
#define PATH_MODPROBE_CONF "/etc/modprobe.d"
|
||||
#define PATH_MODPROBE "/usr/sbin/modprobe"
|
||||
#define PATH_MODPROBE "/sbin/modprobe"
|
||||
#define PATH_CCW_BUS "/sys/bus/ccw"
|
||||
#define PATH_CCWGROUP_BUS "/sys/bus/ccwgroup"
|
||||
#define PATH_UDEV_RULES "/etc/udev/rules.d"
|
||||
|
||||
@@ -17,6 +17,6 @@ INITTOP := $(INITRAMFSDIR)/scripts/init-top
|
||||
ifeq ($(HAVE_INITRAMFS),1)
|
||||
install:
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)/$(HOOKDIR) $(DESTDIR)/$(INITTOP)
|
||||
$(INSTALL) -m 755 hooks/zdev $(DESTDIR)/$(HOOKDIR)
|
||||
$(INSTALL) -m 755 scripts/init-top/zdev $(DESTDIR)/$(INITTOP)
|
||||
$(INSTALL) -m 755 hooks/s390-tools-zdev $(DESTDIR)/$(HOOKDIR)
|
||||
$(INSTALL) -m 755 scripts/init-top/s390-tools-zdev $(DESTDIR)/$(INITTOP)
|
||||
endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
# hooks/zdev
|
||||
# hooks/s390-tools-zdev
|
||||
# This hook script adds files required to apply firmware-provided I/O
|
||||
# configuration data during boot.
|
||||
#
|
||||
@@ -5,7 +5,7 @@
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
# scripts/init-top/zdev
|
||||
# scripts/init-top/s390-tools-zdev
|
||||
# Parse the kernel command line for rd.zdev kernel parameters. These
|
||||
# parameters are evaluated and used to configure z Systems specific devices.
|
||||
#
|
||||
@@ -29,6 +29,7 @@
|
||||
static struct ccw_subtype_data generic_ccw_data = {
|
||||
.ccwdrv = NULL,
|
||||
.mod = NULL,
|
||||
.any_driver = true,
|
||||
};
|
||||
|
||||
/* Check if there is a non-generic subtype in the CCW namespace that uses the
|
||||
|
||||
@@ -1171,6 +1171,37 @@ static exit_code_t check_ineffective_settings(struct setting_list *list,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Check if a possibly conflicting setting is active in the configuration */
|
||||
static bool conflict_setting_active(struct setting *s)
|
||||
{
|
||||
enum qeth_attr_group_type t;
|
||||
|
||||
t = get_attr_group_type(s);
|
||||
if (t != group_bridge && t != group_vnicc) {
|
||||
/* Check BridgePort and VNICC attributes only */
|
||||
return false;
|
||||
}
|
||||
if (s->specified) {
|
||||
/* Specified on the command line: We are strict here and do not
|
||||
* allow to specify VNICC and BridgePort attributes in the same
|
||||
* command to avoid issues when attributes are enabled/disabled
|
||||
* in the wrong order. Example: disable VNICC and enable
|
||||
* BridgePort in the same command would result in an error
|
||||
* because BridgePort attributes are set first.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
if (attrib_match_default(s->attrib, s->value)) {
|
||||
/* Not active if set to default value */
|
||||
return false;
|
||||
}
|
||||
if (s->actual_value && strncmp(s->actual_value, "n/a", 3) == 0) {
|
||||
/* Not active if in n/a state (conflicting attribute set) */
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if there are conflicting attribute settings */
|
||||
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||
{
|
||||
@@ -1182,6 +1213,8 @@ static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||
util_list_iterate(&list->list, s) {
|
||||
if (s->removed)
|
||||
continue;
|
||||
if (!conflict_setting_active(s))
|
||||
continue;
|
||||
t = get_attr_group_type(s);
|
||||
if (t == group_bridge && (!bridge || !bridge->specified))
|
||||
bridge = s;
|
||||
|
||||
@@ -140,7 +140,7 @@ exit_code_t udev_ccw_write_device(struct device *dev, bool autoconf)
|
||||
{
|
||||
struct subtype *st = dev->subtype;
|
||||
struct ccw_subtype_data *data = st->data;
|
||||
const char *type = st->name, *drv = data->ccwdrv, *id = dev->id;
|
||||
const char *type = st->name, *drv = data->any_driver ? "*" : data->ccwdrv, *id = dev->id;
|
||||
struct device_state *state = autoconf ? &dev->autoconf :
|
||||
&dev->persistent;
|
||||
char *path, *cfg_label = NULL, *end_label = NULL;
|
||||
|
||||
@@ -774,7 +774,7 @@ static const struct fuse_opt zdsfs_opts[] = {
|
||||
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
fprintf(stdout,
|
||||
"Usage: %s <devices> <mountpoint> [<options>]\n"
|
||||
"\n"
|
||||
"Use the zdsfs command to provide read access to data sets stored on one or\n"
|
||||
@@ -976,14 +976,24 @@ static int zdsfs_process_args(void *UNUSED(data), const char *arg, int key,
|
||||
return 0;
|
||||
case KEY_HELP:
|
||||
usage(outargs->argv[0]);
|
||||
|
||||
/*
|
||||
* Usage output needs to go to stdout to be consistent with
|
||||
* coding guidelines. FUSE versions before 3.0.0 print help
|
||||
* output to stderr. Redirect stderr to stdout here to enforce
|
||||
* consistent behavior.
|
||||
*/
|
||||
fflush(stderr);
|
||||
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||
|
||||
fuse_opt_add_arg(outargs, "-ho");
|
||||
/* call fuse_main to let library print fuse options */
|
||||
fuse_main(outargs->argc, outargs->argv, &rdf_oper, NULL);
|
||||
exit(0);
|
||||
case KEY_VERSION:
|
||||
fprintf(stderr, COMP "FUSE file system for z/OS data set access"
|
||||
fprintf(stdout, COMP "FUSE file system for z/OS data set access"
|
||||
", program version %s\n", RELEASE_STRING);
|
||||
fprintf(stderr, "Copyright IBM Corp. 2013, 2017\n");
|
||||
fprintf(stdout, "Copyright IBM Corp. 2013, 2017\n");
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "Unknown argument key %x\n", key);
|
||||
|
||||
114
zfcpdump/10-zfcpdump.install.in
Executable file
114
zfcpdump/10-zfcpdump.install.in
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 10-zfcpdump.install - Installation script to handle zfcpdump kernels
|
||||
#
|
||||
# Copyright IBM Corp. 2018
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
#
|
||||
# This script supports two modes:
|
||||
#
|
||||
# 1) Installing the images to /boot/<machine-id>/<kernel-version>
|
||||
# subdirectories, i.e. BOOT_DIR_ABS, as recommended by the BLS.
|
||||
# In this case file names are taken over from the original files.
|
||||
#
|
||||
# 2) Installing the images directly to /boot. In this case the files are
|
||||
# renamed to <original-name>-<kernel-version>.
|
||||
#
|
||||
# The existence of BOOT_DIR_ABS is taken as trigger to switch between both
|
||||
# modes.
|
||||
#
|
||||
# The KERNEL_VERSION is assumed to contain '@flavor@' to identify the image
|
||||
# as a zfcpdump kernel.
|
||||
|
||||
COMMAND="$1"
|
||||
KERNEL_VERSION="$2"
|
||||
BOOT_DIR_ABS="$3"
|
||||
KERNEL_IMAGE="$4"
|
||||
|
||||
# Location zipl looks for the zfcpdump kernel
|
||||
ZFCPDUMP_IMAGE='@zfcpdump_image@'
|
||||
|
||||
# Only handle zfcpdump kernels
|
||||
echo "$KERNEL_VERSION" | grep -q '@flavor@' || exit 0
|
||||
|
||||
case "$COMMAND" in
|
||||
add)
|
||||
KERNEL_DIR="$(dirname $KERNEL_IMAGE)"
|
||||
KERNEL_NAME="$(basename $KERNEL_IMAGE)"
|
||||
|
||||
for f in \
|
||||
"$KERNEL_IMAGE" \
|
||||
"$KERNEL_DIR"/System.map \
|
||||
"$KERNEL_DIR"/config \
|
||||
"$KERNEL_DIR"/zImage.stub
|
||||
do
|
||||
test -e "$f" || continue
|
||||
test -d "$BOOT_DIR_ABS" \
|
||||
&& DEST="$BOOT_DIR_ABS/$(basename $f)" \
|
||||
|| DEST="/boot/$(basename $f)-$KERNEL_VERSION"
|
||||
|
||||
cp -aT "$f" "$DEST"
|
||||
test $(command -v restorecon) && restorecon -R "$DEST"
|
||||
done
|
||||
|
||||
# hmac file need special treatment
|
||||
f="$KERNEL_DIR/.$KERNEL_NAME.hmac"
|
||||
if [ -e "$f" ]; then
|
||||
test -d "$BOOT_DIR_ABS" \
|
||||
&& DEST="$BOOT_DIR_ABS/$(basename $f)" \
|
||||
|| DEST="/boot/.$KERNEL_NAME-$KERNEL_VERSION.hmac"
|
||||
|
||||
cp -aT "$f" "$DEST"
|
||||
test $(command -v restorecon) && restorecon -R "$DEST"
|
||||
fi
|
||||
|
||||
# Set link so zipl finds the kernel
|
||||
test -d "$BOOT_DIR_ABS" \
|
||||
&& TARGET="$BOOT_DIR_ABS/$KERNEL_NAME" \
|
||||
|| TARGET="/boot/$KERNEL_NAME-$KERNEL_VERSION"
|
||||
ln -sf "$TARGET" "$ZFCPDUMP_IMAGE"
|
||||
;;
|
||||
|
||||
remove)
|
||||
# On removal
|
||||
# $KERNEL_IMAGE is empty -> $KERNEL_NAME is empty -> rebuild it
|
||||
KERNEL_NAME="$(basename $(readlink $ZFCPDUMP_IMAGE))"
|
||||
if [ -d "$BOOT_DIR_ABS" ]; then
|
||||
INSTALL_DIR="$(dirname $BOOT_DIR_ABS)"
|
||||
else
|
||||
INSTALL_DIR="/boot/"
|
||||
KERNEL_NAME="$(echo $KERNEL_NAME \
|
||||
| sed -e "s#\(.*\)-$KERNEL_VERSION#\1#")"
|
||||
fi
|
||||
|
||||
for f in $(find "$INSTALL_DIR" -name "*$KERNEL_VERSION*"); do
|
||||
rm -rf "$f"
|
||||
done
|
||||
|
||||
# Update link to latest remaining zfcpdump kernel.
|
||||
if [ $(readlink "$ZFCPDUMP_IMAGE" | grep "$KERNEL_VERSION") ]
|
||||
then
|
||||
NEXT_IMAGE=$( \
|
||||
find "$INSTALL_DIR" -type f \
|
||||
| grep '@flavor@' \
|
||||
| grep "$KERNEL_NAME" \
|
||||
| grep -v "hmac" \
|
||||
| sort -V \
|
||||
| tail -n1 )
|
||||
|
||||
test $NEXT_IMAGE \
|
||||
&& ln -sf "$NEXT_IMAGE" "$ZFCPDUMP_IMAGE" \
|
||||
|| rm -f "$ZFCPDUMP_IMAGE"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Prevent execution of all other scripts.
|
||||
# The zfcpdump kernel is stripped down to the bare minimum needed for
|
||||
# dumping. It is not supposed to be used for any other purpose.
|
||||
exit 77
|
||||
@@ -1,6 +1,7 @@
|
||||
include ../common.mak
|
||||
|
||||
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
|
||||
INSTALL_SCRIPTS = 10-zfcpdump.install
|
||||
|
||||
ifeq (${HAVE_LIBC_STATIC},0)
|
||||
|
||||
@@ -20,7 +21,7 @@ check_dep:
|
||||
"HAVE_LIBC_STATIC=0", \
|
||||
"-static")
|
||||
|
||||
all: check_dep $(ZFCPDUMP_PART_RD)
|
||||
all: check_dep $(ZFCPDUMP_INITRD) scripts
|
||||
|
||||
cpioinit: cpioinit.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
|
||||
@@ -29,17 +30,26 @@ zfcpdump_part: zfcpdump.o zfcpdump_part.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ -static -o $@
|
||||
$(STRIP) -s $@
|
||||
|
||||
$(ZFCPDUMP_PART_RD): cpioinit zfcpdump_part
|
||||
$(ZFCPDUMP_INITRD): cpioinit zfcpdump_part
|
||||
$(CPIOINIT) zfcpdump_part > $@.tmp
|
||||
$(GZIP) -f $@.tmp
|
||||
$(MV) $@.tmp.gz $(ZFCPDUMP_PART_RD)
|
||||
$(MV) $@.tmp.gz $(ZFCPDUMP_INITRD)
|
||||
|
||||
scripts: $(INSTALL_SCRIPTS)
|
||||
chmod +x $(INSTALL_SCRIPTS)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -m 611 $(ZFCPDUMP_PART_RD) $(DESTDIR)$(ZFCPDUMP_DIR)
|
||||
$(INSTALL) -m 611 $(ZFCPDUMP_INITRD) $(DESTDIR)$(ZFCPDUMP_DIR)
|
||||
|
||||
%: %.in
|
||||
zfcpdump_image=$(ZFCPDUMP_DIR)/$(ZFCPDUMP_IMAGE); \
|
||||
$(SED) -e "s#@zfcpdump_image@#$$zfcpdump_image#g" \
|
||||
-e "s#@flavor@#$(ZFCPDUMP_FLAVOR)#g" \
|
||||
< $< > $@
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_PART_RD)
|
||||
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_INITRD) \
|
||||
$(INSTALL_SCRIPTS)
|
||||
|
||||
.PHONY: all clean install check_dep
|
||||
.PHONY: all clean install check_dep scripts
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#ifdef GZIP_SUPPORT
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "zfcpdump.h"
|
||||
@@ -288,12 +285,10 @@ no_reipl:
|
||||
/*
|
||||
* Signal handler for zfcp_dumper
|
||||
*/
|
||||
static __sighandler_t dump_sig_handler(int sig, siginfo_t *UNUSED(sip),
|
||||
void *UNUSED(p))
|
||||
static void dump_sig_handler(int sig, siginfo_t *UNUSED(sip), void *UNUSED(p))
|
||||
{
|
||||
PRINT_ERR("Got signal: %i\n", sig);
|
||||
terminate(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -304,7 +299,7 @@ static __sighandler_t dump_sig_handler(int sig, siginfo_t *UNUSED(sip),
|
||||
static int init_sig(void)
|
||||
{
|
||||
g.sigact.sa_flags = (SA_NODEFER | SA_SIGINFO | SA_RESETHAND);
|
||||
g.sigact.sa_handler = (__sighandler_t)dump_sig_handler;
|
||||
g.sigact.sa_sigaction = dump_sig_handler;
|
||||
if (sigemptyset(&g.sigact.sa_mask) < 0)
|
||||
return -1;
|
||||
if (sigaction(SIGINT, &g.sigact, NULL) < 0)
|
||||
@@ -359,41 +354,10 @@ void show_progress(unsigned long done)
|
||||
time_next = tv.tv_sec + 10;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load a kernel module
|
||||
*/
|
||||
static void modprobe(const char *module)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
PRINT_PERR("fork failed\n");
|
||||
return;
|
||||
} else if (pid == 0) {
|
||||
execl("/bin/modprobe", "modprobe", module, "-q", NULL);
|
||||
execl("/sbin/modprobe", "modprobe", module, "-q", NULL);
|
||||
exit(1);
|
||||
} else {
|
||||
waitpid(pid, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Load all required kernel modules
|
||||
*/
|
||||
static void load_modules(const char *module_list[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; module_list[i]; i++)
|
||||
modprobe(module_list[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize zfcpdump
|
||||
*/
|
||||
int zfcpdump_init(const char *module_list[])
|
||||
int zfcpdump_init(void)
|
||||
{
|
||||
char start_time_str[128], linux_version[256];
|
||||
|
||||
@@ -436,7 +400,6 @@ int zfcpdump_init(const char *module_list[])
|
||||
PRINT_ERR("Could not parse parmline\n");
|
||||
return -1;
|
||||
}
|
||||
load_modules(module_list);
|
||||
if (enable_zfcp_device()) {
|
||||
PRINT_ERR("Could not enable dump device\n");
|
||||
return -1;
|
||||
|
||||
@@ -103,7 +103,7 @@ struct mem_chunk {
|
||||
*/
|
||||
void release_hsa(void);
|
||||
__u64 get_hsa_size(void);
|
||||
int zfcpdump_init(const char *module_list[]);
|
||||
int zfcpdump_init(void);
|
||||
void print_newline(void);
|
||||
void show_progress(unsigned long done);
|
||||
int terminate(int rc);
|
||||
|
||||
@@ -103,7 +103,6 @@ struct scsi_mbr {
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
static const char *module_list[] = {"zfcp", "sd_mod", "zcore_mod", NULL};
|
||||
static struct scsi_dump_sb dump_sb;
|
||||
static struct scsi_mbr mbr;
|
||||
|
||||
@@ -440,7 +439,7 @@ int main(int UNUSED(argc), char *UNUSED(argv[]))
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (zfcpdump_init(module_list))
|
||||
if (zfcpdump_init())
|
||||
return terminate(1);
|
||||
PRINT("Dump parameters:\n");
|
||||
PRINT(" devno....: %s\n", g.dump_devno);
|
||||
|
||||
@@ -12,33 +12,33 @@ ziomon_mgr_main.o: ziomon_mgr.c
|
||||
ziomon_mgr: LDLIBS += -lm
|
||||
ziomon_mgr: ziomon_dacc.o ziomon_util.o ziomon_mgr_main.o ziomon_tools.o \
|
||||
ziomon_zfcpdd.o ziomon_msg_tools.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
ziomon_util_main.o: ziomon_util.c ziomon_util.h
|
||||
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
|
||||
ziomon_util: LDLIBS += -lm
|
||||
ziomon_util: ziomon_util_main.o ziomon_tools.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
ziomon_zfcpdd_main.o: ziomon_zfcpdd.c ziomon_zfcpdd.h
|
||||
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
|
||||
ziomon_zfcpdd: LDLIBS += -lm -lrt -lpthread
|
||||
ziomon_zfcpdd: ziomon_zfcpdd_main.o ziomon_tools.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
ziorep_traffic: ziorep_traffic.o ziorep_framer.o ziorep_frameset.o \
|
||||
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
|
||||
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
|
||||
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
|
||||
ziorep_filters.o
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
ziorep_utilization: ziorep_utilization.o ziorep_framer.o ziorep_frameset.o \
|
||||
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
|
||||
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
|
||||
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
|
||||
ziorep_filters.o
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
|
||||
@@ -48,13 +48,6 @@
|
||||
#define MENU_DEFAULT_PROMPT 0
|
||||
#define MENU_DEFAULT_TIMEOUT 0
|
||||
|
||||
#define FSDUMP_IMAGE STRINGIFY(ZFCPDUMP_DIR) "/" STRINGIFY(ZFCPDUMP_FS_IMAGE)
|
||||
#define FSDUMP_RAMDISK STRINGIFY(ZFCPDUMP_DIR) "/" STRINGIFY(ZFCPDUMP_FS_RD)
|
||||
#define FSDUMP_PART_IMAGE STRINGIFY(ZFCPDUMP_DIR) "/" \
|
||||
STRINGIFY(ZFCPDUMP_PART_IMAGE)
|
||||
#define FSDUMP_PART_RAMDISK STRINGIFY(ZFCPDUMP_DIR) "/" \
|
||||
STRINGIFY(ZFCPDUMP_PART_RD)
|
||||
|
||||
#define MAX_DUMP_VOLUMES 32
|
||||
|
||||
/* Internal component load address type */
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
include ../../common.mak
|
||||
|
||||
ALL_CPPFLAGS += -I../include -I../boot \
|
||||
-DZFCPDUMP_DIR=$(ZFCPDUMP_DIR) \
|
||||
-DZFCPDUMP_FS_IMAGE=$(ZFCPDUMP_FS_IMAGE) \
|
||||
-DZFCPDUMP_FS_RD=$(ZFCPDUMP_FS_RD) \
|
||||
-DZFCPDUMP_PART_IMAGE=$(ZFCPDUMP_PART_IMAGE) \
|
||||
-DZFCPDUMP_PART_RD=$(ZFCPDUMP_PART_RD) \
|
||||
-DZFCPDUMP_IMAGE="STRINGIFY($(ZFCPDUMP_DIR)/$(ZFCPDUMP_IMAGE))" \
|
||||
-DZFCPDUMP_INITRD="STRINGIFY($(ZFCPDUMP_DIR)/$(ZFCPDUMP_INITRD))" \
|
||||
-D_FILE_OFFSET_BITS=64 $(NO_PIE_CFLAGS)
|
||||
ALL_LDFLAGS += -Wl,-z,noexecstack $(NO_PIE_LDFLAGS)
|
||||
|
||||
@@ -44,6 +41,8 @@ clean:
|
||||
|
||||
# Additional manual dependencies
|
||||
|
||||
.boot.o.d boot.o: ../boot/data.h
|
||||
|
||||
../boot/data.h:
|
||||
make -C ../boot data.h
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fiemap.h>
|
||||
|
||||
#include "lib/util_proc.h"
|
||||
|
||||
@@ -550,8 +552,12 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
|
||||
{
|
||||
struct statfs buf;
|
||||
blocknum_t phy_per_fs;
|
||||
int mapped;
|
||||
blocknum_t mapped;
|
||||
int block;
|
||||
int subblock;
|
||||
int fiemap_size;
|
||||
int map_offset;
|
||||
struct fiemap *fiemap;
|
||||
|
||||
/* No file system: partition or raw disk */
|
||||
if (info->fs_block_size == -1) {
|
||||
@@ -576,12 +582,55 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
|
||||
}
|
||||
/* Get mapping in file system blocks */
|
||||
phy_per_fs = info->fs_block_size / info->phy_block_size;
|
||||
mapped = logical / phy_per_fs;
|
||||
subblock = logical % phy_per_fs;
|
||||
if (ioctl(fd, FIBMAP, &mapped)) {
|
||||
error_reason("Could not get file mapping");
|
||||
|
||||
/* First try FIEMAP, more complicated to set up */
|
||||
fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent);
|
||||
|
||||
fiemap = misc_malloc(fiemap_size);
|
||||
if (!fiemap)
|
||||
return -1;
|
||||
memset(fiemap, 0, fiemap_size);
|
||||
|
||||
fiemap->fm_extent_count = 1;
|
||||
fiemap->fm_flags = FIEMAP_FLAG_SYNC;
|
||||
/* fm_start, fm_length in bytes; logical is in physical block units */
|
||||
fiemap->fm_start = logical * info->phy_block_size;
|
||||
fiemap->fm_length = info->phy_block_size;
|
||||
|
||||
if (ioctl(fd, FS_IOC_FIEMAP, (unsigned long)fiemap)) {
|
||||
/* FIEMAP failed, fall back to FIBMAP */
|
||||
block = logical / phy_per_fs;
|
||||
if (ioctl(fd, FIBMAP, &block)) {
|
||||
error_reason("Could not get file mapping");
|
||||
free(fiemap);
|
||||
return -1;
|
||||
}
|
||||
mapped = block;
|
||||
} else {
|
||||
if (fiemap->fm_mapped_extents) {
|
||||
if (fiemap->fm_extents[0].fe_flags &
|
||||
FIEMAP_EXTENT_ENCODED) {
|
||||
error_reason("File mapping is encoded");
|
||||
free(fiemap);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* returned extent may start prior to our request
|
||||
*/
|
||||
map_offset = fiemap->fm_start -
|
||||
fiemap->fm_extents[0].fe_logical;
|
||||
mapped = fiemap->fm_extents[0].fe_physical +
|
||||
map_offset;
|
||||
/* set mapped to fs block units */
|
||||
mapped = mapped / info->fs_block_size;
|
||||
} else {
|
||||
mapped = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free(fiemap);
|
||||
|
||||
if (mapped == 0) {
|
||||
/* This is a hole in the file */
|
||||
*physical = 0;
|
||||
|
||||
@@ -874,22 +874,22 @@ check_job_dump_images(struct job_dump_data* dump, char* name)
|
||||
{
|
||||
int rc;
|
||||
/* Add data needed to convert fs dump job to IPL job */
|
||||
rc = misc_check_readable_file(FSDUMP_PART_IMAGE);
|
||||
rc = misc_check_readable_file(ZFCPDUMP_IMAGE);
|
||||
if (rc) {
|
||||
error_text("Need external file '%s' for partition dump",
|
||||
FSDUMP_PART_IMAGE);
|
||||
ZFCPDUMP_IMAGE);
|
||||
return rc;
|
||||
}
|
||||
dump->image = misc_strdup(FSDUMP_PART_IMAGE);
|
||||
dump->image = misc_strdup(ZFCPDUMP_IMAGE);
|
||||
if (dump->image == NULL)
|
||||
return -1;
|
||||
dump->image_addr = DEFAULT_IMAGE_ADDRESS;
|
||||
|
||||
/* Ramdisk is no longer required with new initramfs dump system */
|
||||
if (misc_check_readable_file(FSDUMP_PART_RAMDISK))
|
||||
if (misc_check_readable_file(ZFCPDUMP_INITRD))
|
||||
dump->ramdisk = NULL;
|
||||
else {
|
||||
dump->ramdisk = misc_strdup(FSDUMP_PART_RAMDISK);
|
||||
dump->ramdisk = misc_strdup(ZFCPDUMP_INITRD);
|
||||
if (dump->ramdisk == NULL)
|
||||
return -1;
|
||||
dump->ramdisk_addr = UNSPECIFIED_ADDRESS;
|
||||
|
||||
@@ -1,47 +1,103 @@
|
||||
include ../common.mak
|
||||
|
||||
ifeq (${HAVE_OPENSSL},0)
|
||||
|
||||
all:
|
||||
$(SKIP) HAVE_OPENSSL=0
|
||||
|
||||
install:
|
||||
$(SKIP) HAVE_OPENSSL=0
|
||||
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
BUILD_TARGETS += zkey
|
||||
INSTALL_TARGETS += install-zkey
|
||||
else
|
||||
BUILD_TARGETS += zkey-skip
|
||||
INSTALL_TARGETS += zkey-skip
|
||||
endif
|
||||
|
||||
check_dep:
|
||||
ifneq (${HAVE_CRYPTSETUP2},0)
|
||||
ifneq (${HAVE_JSONC},0)
|
||||
BUILD_TARGETS += zkey-cryptsetup
|
||||
INSTALL_TARGETS += install-zkey-cryptsetup
|
||||
CPPFLAGS += -DHAVE_LUKS2_SUPPORT
|
||||
else
|
||||
BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
|
||||
INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
|
||||
endif
|
||||
else
|
||||
BUILD_TARGETS += zkey-cryptsetup-skip-cryptsetup2
|
||||
INSTALL_TARGETS += zkey-cryptsetup-skip-cryptsetup2
|
||||
endif
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
detect-libcryptsetup.dep:
|
||||
echo "#include <libcryptsetup.h>" > detect-libcryptsetup.dep
|
||||
echo "#ifndef CRYPT_LUKS2" >> detect-libcryptsetup.dep
|
||||
echo " #error libcryptsetup version 2.0.3 is required" >> detect-libcryptsetup.dep
|
||||
echo "#endif" >> detect-libcryptsetup.dep
|
||||
echo "int i = CRYPT_SLOT_UNBOUND;" >> detect-libcryptsetup.dep
|
||||
|
||||
check-dep-zkey:
|
||||
$(call check_dep, \
|
||||
"zkey", \
|
||||
"openssl/evp.h", \
|
||||
"openssl-devel", \
|
||||
"HAVE_OPENSSL=0")
|
||||
touch check-dep-zkey
|
||||
|
||||
CPPFLAGS += -I../include
|
||||
LDLIBS += -ldl -lcrypto
|
||||
check-dep-zkey-cryptsetup: detect-libcryptsetup.dep
|
||||
$(call check_dep, \
|
||||
"zkey-cryptsetup", \
|
||||
"detect-libcryptsetup.dep", \
|
||||
"cryptsetup-devel version 2.0.3", \
|
||||
"HAVE_CRYPTSETUP2=0", \
|
||||
"-I.")
|
||||
$(call check_dep, \
|
||||
"zkey-cryptsetup", \
|
||||
"json-c/json.h", \
|
||||
"json-c-devel", \
|
||||
"HAVE_JSONC=0")
|
||||
touch check-dep-zkey-cryptsetup
|
||||
|
||||
all: check_dep zkey
|
||||
zkey-skip:
|
||||
echo " SKIP zkey due to HAVE_OPENSSL=0"
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
zkey-cryptsetup-skip-cryptsetup2:
|
||||
echo " SKIP zkey-cryptsetup due to HAVE_CRYPTSETUP2=0"
|
||||
|
||||
zkey-cryptsetup-skip-jsonc:
|
||||
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
|
||||
|
||||
all: $(BUILD_TARGETS)
|
||||
|
||||
zkey.o: zkey.c pkey.h misc.h
|
||||
pkey.o: pkey.c pkey.h
|
||||
properties.o: properties.c properties.h
|
||||
properties.o: check-dep-zkey properties.c properties.h
|
||||
keystore.o: keystore.c keystore.h properties.h
|
||||
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h misc.h
|
||||
|
||||
zkey: LDLIBS = -ldl -lcrypto
|
||||
zkey: zkey.o pkey.o properties.o keystore.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install: all
|
||||
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c
|
||||
zkey-cryptsetup: zkey-cryptsetup.o pkey.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install-common:
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
install-zkey:
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
|
||||
endif
|
||||
install-zkey-cryptsetup:
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
install: all install-common $(INSTALL_TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f *.o zkey
|
||||
rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.dep \
|
||||
check-dep-zkey check-dep-zkey-cryptsetup
|
||||
|
||||
.PHONY: all install clean
|
||||
.PHONY: all install clean zkey-skip zkey-cryptsetup-skip-cryptsetup2 \
|
||||
zkey-cryptsetup-skip-jsonc install-common install-zkey \
|
||||
install-zkey-cryptsetup
|
||||
|
||||
586
zkey/keystore.c
586
zkey/keystore.c
File diff suppressed because it is too large
Load Diff
@@ -30,16 +30,17 @@ int keystore_generate_key(struct keystore *keystore, const char *name,
|
||||
const char *description, const char *volumes,
|
||||
const char *apqns, size_t sector_size,
|
||||
size_t keybits, bool xts, const char *clear_key_file,
|
||||
int pkey_fd);
|
||||
const char *volume_type, int pkey_fd);
|
||||
|
||||
int keystore_import_key(struct keystore *keystore, const char *name,
|
||||
const char *description, const char *volumes,
|
||||
const char *apqns, size_t sector_size,
|
||||
const char *import_file);
|
||||
const char *import_file, const char *volume_type);
|
||||
|
||||
int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
const char *description, const char *volumes,
|
||||
const char *apqns, long int sector_size);
|
||||
const char *apqns, long int sector_size,
|
||||
const char *volume_type);
|
||||
|
||||
int keystore_rename_key(struct keystore *keystore, const char *name,
|
||||
const char *newname);
|
||||
@@ -63,12 +64,14 @@ int keystore_remove_key(struct keystore *keystore, const char *name,
|
||||
bool quiet);
|
||||
|
||||
int keystore_list_keys(struct keystore *keystore, const char *name_filter,
|
||||
const char *volume_filter, const char *apqn_filter);
|
||||
const char *volume_filter, const char *apqn_filter,
|
||||
const char *volume_type);
|
||||
|
||||
int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
|
||||
bool execute);
|
||||
bool execute, const char *volume_type);
|
||||
|
||||
int keystore_crypttab(struct keystore *keystore, const char *volume_filter);
|
||||
int keystore_crypttab(struct keystore *keystore, const char *volume_filter,
|
||||
const char *volume_type);
|
||||
|
||||
void keystore_free(struct keystore *keystore);
|
||||
|
||||
|
||||
158
zkey/pkey.c
158
zkey/pkey.c
@@ -11,11 +11,13 @@
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/if_alg.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -25,6 +27,12 @@
|
||||
|
||||
#include "pkey.h"
|
||||
|
||||
#ifndef AF_ALG
|
||||
#define AF_ALG 38
|
||||
#endif
|
||||
#ifndef SOL_ALG
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
#define pr_verbose(verbose, fmt...) do { \
|
||||
if (verbose) \
|
||||
@@ -34,6 +42,8 @@
|
||||
#define DOUBLE_KEYSIZE_FOR_XTS(keysize, xts) ((xts) ? 2 * (keysize) : (keysize))
|
||||
#define HALF_KEYSIZE_FOR_XTS(keysize, xts) ((xts) ? (keysize) / 2 : (keysize))
|
||||
|
||||
#define MAX_CIPHER_LEN 32
|
||||
|
||||
/*
|
||||
* Definitions for the CCA library
|
||||
*/
|
||||
@@ -367,6 +377,8 @@ int generate_secure_key_random(int pkey_fd, const char *keyfile,
|
||||
if (rc < 0) {
|
||||
rc = -errno;
|
||||
warnx("Failed to generate a secure key: %s", strerror(errno));
|
||||
warnx("Make sure that all available CCA crypto adapters are "
|
||||
"setup with the same master key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -378,6 +390,8 @@ int generate_secure_key_random(int pkey_fd, const char *keyfile,
|
||||
rc = -errno;
|
||||
warnx("Failed to generate a secure key: %s",
|
||||
strerror(errno));
|
||||
warnx("Make sure that all available CCA crypto "
|
||||
"adapters are setup with the same master key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -465,6 +479,8 @@ int generate_secure_key_clear(int pkey_fd, const char *keyfile,
|
||||
rc = -errno;
|
||||
warnx("Failed to generate a secure key from a "
|
||||
"clear key: %s", strerror(errno));
|
||||
warnx("Make sure that all available CCA crypto adapters are "
|
||||
"setup with the same master key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -479,6 +495,8 @@ int generate_secure_key_clear(int pkey_fd, const char *keyfile,
|
||||
rc = -errno;
|
||||
warnx("Failed to generate a secure key from "
|
||||
"a clear key: %s", strerror(errno));
|
||||
warnx("Make sure that all available CCA crypto "
|
||||
"adapters are setup with the same master key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -746,3 +764,143 @@ int validate_secure_key(int pkey_fd,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a key verification pattern of a secure key by encrypting the all
|
||||
* zero message with the secure key using the AF_ALG interface
|
||||
*
|
||||
* @param[in] key the secure key token
|
||||
* @param[in] key_size the size of the secure key
|
||||
* @param[in] vp buffer where the verification pattern is returned
|
||||
* @param[in] vp_len the size of the buffer
|
||||
* @param[in] verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns 0 on success, a negative errno in case of an error
|
||||
*/
|
||||
int generate_key_verification_pattern(const char *key, size_t key_size,
|
||||
char *vp, size_t vp_len, bool verbose)
|
||||
{
|
||||
int tfmfd = -1, opfd = -1, rc = 0;
|
||||
char null_msg[ENC_ZERO_LEN];
|
||||
char enc_zero[ENC_ZERO_LEN];
|
||||
struct af_alg_iv *alg_iv;
|
||||
struct cmsghdr *header;
|
||||
uint32_t *type;
|
||||
ssize_t len;
|
||||
size_t i;
|
||||
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "skcipher",
|
||||
};
|
||||
struct iovec iov = {
|
||||
.iov_base = (void *)null_msg,
|
||||
.iov_len = sizeof(null_msg),
|
||||
};
|
||||
int iv_msg_size = CMSG_SPACE(sizeof(*alg_iv) + PAES_BLOCK_SIZE);
|
||||
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
|
||||
struct msghdr msg = {
|
||||
.msg_control = buffer,
|
||||
.msg_controllen = sizeof(buffer),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (vp_len < VERIFICATION_PATTERN_LEN) {
|
||||
rc = -EMSGSIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(paes)",
|
||||
key_size > SECURE_KEY_SIZE ? "xts" : "cbc");
|
||||
|
||||
tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||
if (tfmfd < 0) {
|
||||
rc = -errno;
|
||||
pr_verbose(verbose, "Failed to open an AF_ALG socket");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
|
||||
rc = -errno;
|
||||
pr_verbose(verbose, "Failed to bind the AF_ALG socket, "
|
||||
"salg_name='%s' ", sa.salg_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, key,
|
||||
key_size) < 0) {
|
||||
rc = -errno;
|
||||
pr_verbose(verbose, "Failed to set the key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
opfd = accept(tfmfd, NULL, 0);
|
||||
if (opfd < 0) {
|
||||
rc = -errno;
|
||||
pr_verbose(verbose, "Failed to accept on the AF_ALG socket");
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(null_msg, 0, sizeof(null_msg));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
header = CMSG_FIRSTHDR(&msg);
|
||||
if (header == NULL) {
|
||||
pr_verbose(verbose, "Failed to obtain control message header");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
header->cmsg_level = SOL_ALG;
|
||||
header->cmsg_type = ALG_SET_OP;
|
||||
header->cmsg_len = CMSG_LEN(sizeof(*type));
|
||||
type = (void *)CMSG_DATA(header);
|
||||
*type = ALG_OP_ENCRYPT;
|
||||
|
||||
header = CMSG_NXTHDR(&msg, header);
|
||||
if (header == NULL) {
|
||||
pr_verbose(verbose, "Failed to obtain control message "
|
||||
"header");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
header->cmsg_level = SOL_ALG;
|
||||
header->cmsg_type = ALG_SET_IV;
|
||||
header->cmsg_len = iv_msg_size;
|
||||
alg_iv = (void *)CMSG_DATA(header);
|
||||
alg_iv->ivlen = PAES_BLOCK_SIZE;
|
||||
memcpy(alg_iv->iv, null_msg, PAES_BLOCK_SIZE);
|
||||
|
||||
len = sendmsg(opfd, &msg, 0);
|
||||
if (len != ENC_ZERO_LEN) {
|
||||
pr_verbose(verbose, "Failed to send to the AF_ALG socket");
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = read(opfd, enc_zero, sizeof(enc_zero));
|
||||
if (len != ENC_ZERO_LEN) {
|
||||
pr_verbose(verbose, "Failed to receive from the AF_ALG socket");
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(vp, 0, vp_len);
|
||||
for (i = 0; i < sizeof(enc_zero); i++)
|
||||
sprintf(&vp[i * 2], "%02x", enc_zero[i]);
|
||||
|
||||
pr_verbose(verbose, "Key verification pattern: %s", vp);
|
||||
|
||||
out:
|
||||
if (opfd != -1)
|
||||
close(opfd);
|
||||
if (tfmfd != -1)
|
||||
close(tfmfd);
|
||||
|
||||
if (rc != 0)
|
||||
pr_verbose(verbose, "Failed to generate the key verification "
|
||||
"pattern: %s", strerror(-rc));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,10 @@ typedef void (*t_CSNBKTC)(long *return_code,
|
||||
unsigned char *rule_array,
|
||||
unsigned char *key_identifier);
|
||||
|
||||
#define PAES_BLOCK_SIZE 16
|
||||
#define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE)
|
||||
#define VERIFICATION_PATTERN_LEN (2 * ENC_ZERO_LEN + 1)
|
||||
|
||||
int load_cca_library(void **lib_csulcca, t_CSNBKTC *dll_CSNBKTC, bool verbose);
|
||||
|
||||
int open_pkey_device(bool verbose);
|
||||
@@ -122,4 +126,7 @@ int key_token_change(t_CSNBKTC dll_CSNBKTC,
|
||||
u8 *secure_key, unsigned int secure_key_size,
|
||||
char *method, bool verbose);
|
||||
|
||||
int generate_key_verification_pattern(const char *key, size_t key_size,
|
||||
char *vp, size_t vp_len, bool verbose);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -149,6 +149,7 @@ void properties_free(struct properties *properties)
|
||||
free(property->name);
|
||||
free(property->value);
|
||||
util_list_remove(&properties->list, property);
|
||||
free(property);
|
||||
}
|
||||
|
||||
free(properties);
|
||||
@@ -259,6 +260,7 @@ int properties_remove(struct properties *properties, const char *name)
|
||||
free(property->name);
|
||||
free(property->value);
|
||||
util_list_remove(&properties->list, property);
|
||||
free(property);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -614,10 +616,13 @@ char *str_list_remove(const char *str_list, const char *str)
|
||||
*/
|
||||
void str_list_free_string_array(char **strings)
|
||||
{
|
||||
char **list = strings;
|
||||
|
||||
util_assert(strings != NULL, "Internal error: strings is NULL");
|
||||
|
||||
while (*strings != NULL) {
|
||||
free((void *)*strings);
|
||||
strings++;
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
|
||||
403
zkey/zkey-cryptsetup.1
Normal file
403
zkey/zkey-cryptsetup.1
Normal file
@@ -0,0 +1,403 @@
|
||||
.\" Copyright IBM Corp. 2018
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH ZKEY\-CRYPTSETUP 1 "May 2018" "s390-tools"
|
||||
.SH NAME
|
||||
zkey\-cryptsetup \- Manage secure AES volume keys of volumes encrypted with
|
||||
\fBLUKS2\fP and the \fBpaes\fP cipher
|
||||
.
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
.B zkey\-cryptsetup
|
||||
.I command
|
||||
.I device
|
||||
.RI [ OPTIONS ]
|
||||
.
|
||||
.PP
|
||||
.B zkey\-cryptsetup
|
||||
.RI [ command ]
|
||||
.BR \-\-help | \-h
|
||||
.br
|
||||
.B zkey\-cryptsetup
|
||||
.BR \-\-version | \-v
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
Use \fBzkey\-cryptsetup\fP to validate and re-encipher secure AES
|
||||
volume keys of volumes encrypted with \fBLUKS2\fP and the \fBpaes\fP cipher.
|
||||
These secure AES volume keys are enciphered with a master key of an IBM
|
||||
cryptographic adapter in CCA coprocessor mode.
|
||||
.PP
|
||||
To encrypt a volume using \fBLUKS2\fP and the \fBpaes\fP cipher, generate a
|
||||
secure AES key using \fBzkey\fP: \fB'zkey generate luks.key --xts'\fP.
|
||||
Then format the device with \fBcryptsetup\fP using the just generated secure
|
||||
AES key from file luks.key: \fB'cryptsetup luksFormat <device> --type luks2
|
||||
--cipher paes-xts-plain64 --master-key-file luks.key --key-size 1024'\fP. For
|
||||
more details about \fBzkey\fP or \fBcryptsetup\fP see the
|
||||
corresponding man pages.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH COMMANDS
|
||||
.
|
||||
.
|
||||
.SS "Validate secure AES volume keys"
|
||||
.
|
||||
.B zkey\-cryptsetup
|
||||
.BR validate | val
|
||||
.I device
|
||||
.RB [ \-\-key\-file | \-d
|
||||
.IR file-name ]
|
||||
.RB [ \-\-keyfile\-offset | \-o
|
||||
.IR bytes ]
|
||||
.RB [ \-\-keyfile\-size | \-l
|
||||
.IR bytes ]
|
||||
.RB [ \-\-tries | \-T
|
||||
.IR number ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.RB [ \-\-debug | \-D ]
|
||||
.PP
|
||||
Use the
|
||||
.B validate
|
||||
command to validate a secure AES volume key of a volume encrypted with
|
||||
\fBLUKS2\fP and the \fBpaes\fP cipher.
|
||||
It checks if the LUKS2 header of the volume contains a valid secure key.
|
||||
It also displays the attributes of the secure key, such as key size, whether
|
||||
it is a secure key that can be used for the XTS cipher mode, and the master key
|
||||
register (CURRENT or OLD) with which the secure key is enciphered.
|
||||
For further information about master key registers, see the
|
||||
\fBreencipher\fP command.
|
||||
.PP
|
||||
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
required. You are prompted for the passphrase, unless option
|
||||
.B \-\-key\-file
|
||||
is specified. Option
|
||||
.B \-\-tries
|
||||
specifies how often a passphrase can be re-entered. When option
|
||||
.B \-\-key\-file
|
||||
is specified, the passphrase is read from the specified file. You can specify
|
||||
options
|
||||
.B \-\-keyfile\-offset
|
||||
and
|
||||
.B \-\-keyfile\-size
|
||||
to control which part of the key file is used as passphrase. These options
|
||||
behave in the same way as with \fBcryptsetup\fP.
|
||||
.
|
||||
.SS "Re-encipher secure AES volume keys"
|
||||
.
|
||||
.PP
|
||||
.B zkey\-cryptsetup
|
||||
.BR reencipher | re
|
||||
.I device
|
||||
.RB [ \-\-staged | \-s ]
|
||||
.RB [ \-\-in\-place | \-i ]
|
||||
.RB [ \-\-complete | \-c ]
|
||||
.RB [ \-\-key\-file | \-d
|
||||
.IR file-name ]
|
||||
.RB [ \-\-keyfile\-offset | \-o
|
||||
.IR bytes ]
|
||||
.RB [ \-\-keyfile\-size | \-l
|
||||
.IR bytes ]
|
||||
.RB [ \-\-tries | \-T
|
||||
.IR number ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.RB [ \-\-debug | \-D ]
|
||||
.PP
|
||||
Use the
|
||||
.B reencipher
|
||||
command to re-encipher a secure AES volume key of a volume encrypted with
|
||||
\fBLUKS2\fP and the \fBpaes\fP cipher. A secure AES volume key must be
|
||||
re-enciphered when the master key of the cryptographic adapter in CCA
|
||||
coprocessor mode changes.
|
||||
.PP
|
||||
The cryptographic adapter in CCA coprocessor mode has three different registers
|
||||
to store master keys:
|
||||
.RS 2
|
||||
.IP "\(bu" 2
|
||||
The \fBCURRENT\fP register contains the current master key.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBOLD\fP register contains the previously used master key.
|
||||
Secure keys enciphered with the master key contained in the \fBOLD\fP
|
||||
register can still be used until the master key is changed again.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBNEW\fP register contains the new master key to be set.
|
||||
The master key in the \fBNEW\fP register cannot be used until it is made
|
||||
the current master key. You can pro-actively re-encipher a secure key with the
|
||||
\fBNEW\fP master key before this key is made the \fBCURRENT\fP key.
|
||||
.RE
|
||||
.PP
|
||||
\fBzkey\-cryptsetup\fP automatically detects whether the secure volume key
|
||||
is currently enciphered with the master key in the \fBOLD\fP register or with
|
||||
the master key in the \fBCURRENT\fP register. If currently enciphered with the
|
||||
master key in the \fBOLD\fP register, it is re-enciphered with the master key
|
||||
in the \fBCURRENT\fP register. If it is currently enciphered with the master
|
||||
key in the \fBCURRENT\fP register, it is re-enciphered with the master key in
|
||||
the \fBNEW\fP register. If for this case the \fBNEW\fP register does not
|
||||
contain a valid master key, then the re-encipher operation fails.
|
||||
.PP
|
||||
Re-enciphering a secure volume key of a volume encrypted with
|
||||
\fBLUKS2\fP and the \fBpaes\fP cipher can be performed \fBin-place\fP, or in
|
||||
\fBstaged\fP mode.
|
||||
.PP
|
||||
\fB"In-place"\fP immediately replaces the secure volume key in the LUKS2
|
||||
header of the encrypted volume with the re-enciphered secure volume key.
|
||||
Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed in-place per
|
||||
default. You can use option \fB--in-place\fP to force an in-place
|
||||
re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case. Be aware that
|
||||
an encrypted volume with a secure volume key that was re-enciphered in-place
|
||||
from \fBCURRENT\fP to \fBNEW\fP is no longer usable, until the new CCA master
|
||||
key has been made the current one.
|
||||
.PP
|
||||
\fBStaged\fP mode means that the re-enciphered secure volume key is stored in a
|
||||
separate (unbound) key slot in the LUKS2 header of the encrypted volume. Thus
|
||||
all key slots containing the current secure volume key are still valid at this
|
||||
point. Once the new CCA master key has been set (made active), you must rerun
|
||||
the reencipher command with option \fB--complete\fP to complete the staged
|
||||
re-enciphering. When completing the staged re-enciphering, the (unbound) key
|
||||
slot containing the re-enciphered secure volume key becomes the active
|
||||
key slot and, optionally, all key slots containing the old secure volume key
|
||||
are removed.
|
||||
Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is performed in staged mode per
|
||||
default. You can use option \fB--staged\fP to force a staged re-enciphering for
|
||||
the \fBOLD\fP to \fBCURRENT\fP case.
|
||||
.PP
|
||||
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
required. You are prompted for the passphrase, unless option
|
||||
.B \-\-key\-file
|
||||
is specified. Option
|
||||
.B \-\-tries
|
||||
specifies how often a passphrase can be re-entered. When option
|
||||
.B \-\-key\-file
|
||||
is specified, the passphrase is read from the specified file. You can specify
|
||||
options
|
||||
.B \-\-keyfile\-offset
|
||||
and
|
||||
.B \-\-keyfile\-size
|
||||
to control which part of the key file is used as passphrase. These options
|
||||
behave in the same way as with \fBcryptsetup\fP.
|
||||
.PP
|
||||
.B Note:
|
||||
The \fBreencipher\fP command requires the CCA host library (libcsulcca.so)
|
||||
to be installed.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Set a verification pattern of the secure AES volume key"
|
||||
.
|
||||
.B zkey\-cryptsetup
|
||||
.BR setvp | setv
|
||||
.I device
|
||||
.RB [ \-\-key\-file | \-d
|
||||
.IR file-name ]
|
||||
.RB [ \-\-keyfile\-offset | \-o
|
||||
.IR bytes ]
|
||||
.RB [ \-\-keyfile\-size | \-l
|
||||
.IR bytes ]
|
||||
.RB [ \-\-tries | \-T
|
||||
.IR number ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.RB [ \-\-debug | \-D ]
|
||||
.PP
|
||||
Use the
|
||||
.B setvp
|
||||
command to set a verification pattern of the secure AES volume key of a volume
|
||||
encrypted with \fBLUKS2\fP and the \fBpaes\fP cipher. The verification pattern
|
||||
identifies the effective key used to encrypt the volume's data.
|
||||
The verification pattern is stored in a token named
|
||||
\fBpaes-verification-pattern\fP in the LUKS2 header.
|
||||
.PP
|
||||
.B Note:
|
||||
Set the verification pattern right after formatting the volume using
|
||||
\fB'cryptsetup luksFormat'\fP.
|
||||
.PP
|
||||
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
required. You are prompted for the passphrase, unless option
|
||||
.B \-\-key\-file
|
||||
is specified. Option
|
||||
.B \-\-tries
|
||||
specifies how often a passphrase can be re-entered. When option
|
||||
.B \-\-key\-file
|
||||
is specified, the passphrase is read from the specified file. You can specify
|
||||
options
|
||||
.B \-\-keyfile\-offset
|
||||
and
|
||||
.B \-\-keyfile\-size
|
||||
to control which part of the key file is used as passphrase. These options
|
||||
behave in the same way as with \fBcryptsetup\fP.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Set a new secure AES volume key for a volume"
|
||||
.
|
||||
.B zkey\-cryptsetup
|
||||
.BR setkey | setk
|
||||
.I device
|
||||
.BR \-\-master\-key\-file | \-m
|
||||
.IR file-name
|
||||
.RB [ \-\-key\-file | \-d
|
||||
.IR file-name ]
|
||||
.RB [ \-\-keyfile\-offset | \-o
|
||||
.IR bytes ]
|
||||
.RB [ \-\-keyfile\-size | \-l
|
||||
.IR bytes ]
|
||||
.RB [ \-\-tries | \-T
|
||||
.IR number ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.RB [ \-\-debug | \-D ]
|
||||
.PP
|
||||
Use the
|
||||
.B setkey
|
||||
command to set a new secure AES volume key for a volume encrypted with
|
||||
\fBLUKS2\fP and the \fBpaes\fP cipher. Use this command to recover from an
|
||||
invalid secure AES volume key contained in the LUKS2 header.
|
||||
A secure AES volume key contained in the LUKS2 header can become invalid when
|
||||
the CCA master key is changed without re-enciphering the secure volume key.
|
||||
.PP
|
||||
You can recover the secure volume key only if you have a copy of the secure key
|
||||
in a file, and this copy was re-enciphered when the CCA master key has been
|
||||
changed. Thus, the copy of the secure key must be currently enciphered with the
|
||||
CCA master key in the CURRENT or OLD master key register.
|
||||
Specify the secure key file with option
|
||||
.B \-\-master\-key\-file
|
||||
to set this secure key as the new volume key.
|
||||
.PP
|
||||
In case the LUKS2 header of the volume contains a verification pattern token,
|
||||
it is used to ensure that the new volume key contains the same effective key.
|
||||
If no verification pattern token is available, then you are prompted to confirm
|
||||
that the specified secure key is the correct one.
|
||||
.B ATTENTION:
|
||||
If you set a wrong secure key you will loose all the data on the encrypted
|
||||
volume!
|
||||
.PP
|
||||
To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
required. You are prompted for the passphrase, unless option
|
||||
.B \-\-key\-file
|
||||
is specified. Option
|
||||
.B \-\-tries
|
||||
specifies how often a passphrase can be re-entered. When option
|
||||
.B \-\-key\-file
|
||||
is specified, the passphrase is read from the specified file. You can specify
|
||||
options
|
||||
.B \-\-keyfile\-offset
|
||||
and
|
||||
.B \-\-keyfile\-size
|
||||
to control which part of the key file is used as passphrase. These options
|
||||
behave in the same way the same as with \fBcryptsetup\fP.
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
.
|
||||
.SS "Options for the reencipher command"
|
||||
.TP
|
||||
.BR \-i ", " \-\-in-place
|
||||
Forces an in-place re-enciphering of a secure volume key in the LUKS2
|
||||
header. This option immediately replaces the secure volume key in the LUKS2
|
||||
header of the encrypted volume with the re-enciphered secure volume key.
|
||||
Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed in-place per
|
||||
default.
|
||||
.TP
|
||||
.BR \-s ", " \-\-staged
|
||||
Forces that the re-enciphering of a secure volume key in the LUKS2
|
||||
header is performed in staged mode. Staged mode means that the re-enciphered
|
||||
secure volume key is stored in a separate (unbound) key slot in the LUKS2
|
||||
header of the encrypted volume. Thus all key slots containing the current
|
||||
secure volume key are still valid at this point. Once the new CCA master key
|
||||
has been set (made active), you must rerun the reencipher command with option
|
||||
\fB--complete\fP to complete the staged re-enciphering. Re-enciphering from
|
||||
\fBCURRENT\fP to \fBNEW\fP is performed in staged mode per default.
|
||||
.TP
|
||||
.BR \-p ", " \-\-complete
|
||||
Completes a staged re-enciphering. Use this option after the new CCA master key
|
||||
has been set (made active). When completing the staged re-enciphering, the
|
||||
(unbound) key slot containing the re-enciphered secure volume key becomes
|
||||
the active key slot and, optionally, all key slots containing the old secure
|
||||
volume key are removed.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the setkey command"
|
||||
.TP
|
||||
.BR \-m ", " \-\-master\-key\-file\~\fIfile\-name\fP
|
||||
Specifies the name of a file containing the secure AES key that is set as the
|
||||
new volume key.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for supplying the passphrase"
|
||||
.TP
|
||||
.BR \-d ", " \-\-key\-file\~\fIfile\-name\fP
|
||||
Reads the passphrase from the specified file. If this option is omitted,
|
||||
or if the file\-name is \fI-\fP (a dash), then you are prompted to enter the
|
||||
passphrase interactively.
|
||||
.TP
|
||||
.BR \-o ", " \-\-keyfile\-offset\~\fIbytes\fP
|
||||
Specifies the number of bytes to skip before starting to read in the file
|
||||
specified with option \fB\-\-key\-file\fP. If omitted, the file is read
|
||||
from the beginning. When option \fB\-\-key\-file\fP is not specified, this
|
||||
option is ignored.
|
||||
.TP
|
||||
.BR \-l ", " \-\-keyfile\-size\~\fIbytes\fP
|
||||
Specifies the number of bytes to be read from the beginning of the file
|
||||
specified with option \fB\-\-key\-file\fP. If omitted, the file is read
|
||||
until the end. When \fB\-\-keyfile\-offset\fP is also specified, reading starts
|
||||
at the offset. When option \fB\-\-key\-file\fP is not specified, this option is
|
||||
ignored.
|
||||
.TP
|
||||
.BR \-T ", " \-\-tries\~\fInumber\fP
|
||||
Specifies how often the interactive input of the passphrase can be re-entered.
|
||||
The default is 3 times. When option \fB\-\-key\-file\fP is specified, this
|
||||
option is ignored, and the passphrase is read only once from the file.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "General options"
|
||||
.TP
|
||||
.BR \-V ", " \-\-verbose
|
||||
Displays additional information messages during processing.
|
||||
.TP
|
||||
.BR \-D ", " \-\-debug
|
||||
Displays additional debugging messages during processing. This option also
|
||||
implies \fB\-\-verbose\fP.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Displays help text and exits.
|
||||
.TP
|
||||
.BR \-v ", " \-\-version
|
||||
Displays version information and exits.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B zkey-cryptsetup reencipher /dev/dasdd1
|
||||
Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1.
|
||||
.TP
|
||||
.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-staged
|
||||
Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1 in
|
||||
staged mode.
|
||||
.TP
|
||||
.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-complete
|
||||
Completes re-enciphers the secure volume key of the encrypted
|
||||
volume /dev/dasdd1.
|
||||
.TP
|
||||
.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-in\-place
|
||||
Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1 in
|
||||
in-place mode.
|
||||
.TP
|
||||
.B zkey-cryptsetup validate /dev/dasdd1
|
||||
Validates the secure volume key of the encrypted volume /dev/dasdd1 and
|
||||
displays its attributes.
|
||||
.TP
|
||||
.B zkey-cryptsetup setvp /dev/dasdd1
|
||||
Sets the verification pattern of the secure volume key of the encrypted
|
||||
volume /dev/dasdd1.
|
||||
.TP
|
||||
.B zkey-cryptsetup setkey /dev/dasdd1 --master-key-file seckey.key
|
||||
Sets the secure key contained in file seckey.key as the new volume key
|
||||
for the encrypted volume /dev/dasdd1.
|
||||
2270
zkey/zkey-cryptsetup.c
Normal file
2270
zkey/zkey-cryptsetup.c
Normal file
File diff suppressed because it is too large
Load Diff
310
zkey/zkey.1
310
zkey/zkey.1
@@ -75,30 +75,32 @@ key repository.
|
||||
.BR generate | gen
|
||||
.I secure\-key\-file
|
||||
.RB [ \-\-keybits | \-k
|
||||
.IB size ]
|
||||
.IR size ]
|
||||
.RB [ \-\-xts | \-x ]
|
||||
.RB [ \-\-clearkey | \-c
|
||||
.IB clear\-key\-file ]
|
||||
.IR clear\-key\-file ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
.B zkey
|
||||
.BR generate | gen
|
||||
.B \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.RB [ \-\-description | \-d
|
||||
.IB description ]
|
||||
.IR description ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IB card1.domain1[,card2.domain2[,...]] ]
|
||||
.IR card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ \-\-sector-size | \-S
|
||||
.IB bytes ]
|
||||
.IR bytes ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-keybits | \-k
|
||||
.IB size ]
|
||||
.IR size ]
|
||||
.RB [ \-\-xts | \-x ]
|
||||
.RB [ \-\-clearkey | \-c
|
||||
.IB clear\-key\-file ]
|
||||
.IR clear\-key\-file ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.PP
|
||||
Use the
|
||||
@@ -115,16 +117,16 @@ The generated secure key can either be stored in a file in the file system,
|
||||
or in the secure key repository. To store the generated secure key in a
|
||||
file, specify the file name with option \fIsecure\-key\-file\fP. To store the
|
||||
secure key in the secure key repository, specify the name of the key using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option. When storing the secure key in a key repository,
|
||||
additional information can be associated with a secure key using the
|
||||
.B --description
|
||||
.B \-\-description
|
||||
,
|
||||
.B --volumes
|
||||
.B \-\-volumes
|
||||
,
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
, or the
|
||||
.B --sector-size
|
||||
.B \-\-sector-size
|
||||
options.
|
||||
.
|
||||
.SS "Validating secure AES keys"
|
||||
@@ -138,7 +140,7 @@ options.
|
||||
.B zkey
|
||||
.BR validate | val
|
||||
.RB [ \-\-name | \-N
|
||||
.IB key-name ]
|
||||
.IR key-name ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.PP
|
||||
Use the
|
||||
@@ -156,10 +158,10 @@ secure key repository. To validate a secure key contained in a file, specify
|
||||
the file name with option \fIsecure\-key\-file\fP. To validate secure keys
|
||||
contained in the secure key repository, specify the name of the key
|
||||
or a pattern containing wildcards using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option. When wildcards are used you must quote the value.
|
||||
If neither option \fIsecure\-key\-file\fP nor option
|
||||
.B --name
|
||||
.B \-\-name
|
||||
are specified, then all secure keys contained in the key repository
|
||||
are validated.
|
||||
.
|
||||
@@ -171,15 +173,15 @@ are validated.
|
||||
.RB [ \-\-to\-new | \-n ]
|
||||
.RB [ \-\-from\-old | \-o ]
|
||||
.RB [ \-\-output | \-f
|
||||
.IB output\-file ]
|
||||
.IR output\-file ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.PP
|
||||
.B zkey
|
||||
.BR reencipher | re
|
||||
.RB [ \-\-name | \-N
|
||||
.IB key-name ]
|
||||
.IR key-name ]
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IB card1.domain1[,card2.domain2[,...]] ]
|
||||
.IR card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ \-\-to\-new | \-n ]
|
||||
.RB [ \-\-from\-old | \-o ]
|
||||
.RB [ \-\-in-place | \-i ]
|
||||
@@ -190,7 +192,7 @@ are validated.
|
||||
Use the
|
||||
.B reencipher
|
||||
command to re-encipher an existing secure key with a new master key.
|
||||
A secure key bust be re-enciphered when the master key of the CCA
|
||||
A secure key must be re-enciphered when the master key of the CCA
|
||||
cryptographic adapter changes.
|
||||
.PP
|
||||
The CCA cryptographic adapter has three different registers to store
|
||||
@@ -243,18 +245,18 @@ secure key repository. To re-encipher a secure key contained in a file,
|
||||
specify the file name with option \fIsecure\-key\-file\fP. To re-encipher
|
||||
secure keys contained in the secure key repository, specify the name of the key
|
||||
or a pattern containing wildcards using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option. When wildcards are used you must quote the value.
|
||||
You can also specify the
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
option to re-encipher those secure
|
||||
keys which are associated with the specified cryptographic adapters (APQNs).
|
||||
You can use wildcards for the APQN specification.
|
||||
When wildcards are used you must quote the value.
|
||||
If both option
|
||||
.B --name
|
||||
.B \-\-name
|
||||
and option
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
are specified then all secure keys
|
||||
contained in the key repository that match both patterns are re-enciphered.
|
||||
If all both options are omitted, then all secure keys contained in the key
|
||||
@@ -265,7 +267,7 @@ performed \fBin-place\fP, or in \fBstaged\fP mode.
|
||||
.PP
|
||||
\fB"In-place"\fP immediately replaces the secure key in the repository with
|
||||
the re-enciphered secure key. Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is
|
||||
performed in-place per default. You can use option \fB--in-place\fP to force an
|
||||
performed in-place per default. You can use option \fB\-\-in-place\fP to force an
|
||||
in-place re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case. Be aware that
|
||||
a secure key that was re-enciphered in-place from \fBCURRENT\fP to \fBNEW\fP
|
||||
is no longer valid, until the new CCA master key has been made the current one.
|
||||
@@ -273,9 +275,9 @@ is no longer valid, until the new CCA master key has been made the current one.
|
||||
\fBStaged\fP mode means that the re-enciphered secure key is stored in a
|
||||
separate file in the secure key repository. Thus the current secure key is still
|
||||
valid at this point. Once the new CCA master key has been set (made active), you
|
||||
must rerun the reencipher command with option \fB--complete\fP to complete the
|
||||
must rerun the reencipher command with option \fB\-\-complete\fP to complete the
|
||||
staged re-enciphering. Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is
|
||||
performed in staged mode per default. You can use option \fB--staged\fP to force
|
||||
performed in staged mode per default. You can use option \fB\-\-staged\fP to force
|
||||
a staged re-enciphering for the \fBOLD\fP to \fBCURRENT\fP case.
|
||||
.PP
|
||||
.B Note:
|
||||
@@ -288,15 +290,17 @@ to be installed.
|
||||
.BR import | im
|
||||
.I secure\-key\-file
|
||||
.B \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.RB [ \-\-description | \-d
|
||||
.IB description ]
|
||||
.IR description ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IB card1.domain1[,card2.domain2[,...]] ]
|
||||
.IR card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ \-\-sector-size | \-S
|
||||
.IB bytes ]
|
||||
.IR bytes ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -305,13 +309,13 @@ Use the
|
||||
command to import an existing secure key contained in a file into the the
|
||||
secure key repository. When importing a secure key in a key repository,
|
||||
additional information can be associated with a secure key using the
|
||||
.B --description
|
||||
.B \-\-description
|
||||
,
|
||||
.B --volumes
|
||||
.B \-\-volumes
|
||||
,
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
, or the
|
||||
.B --sector-size
|
||||
.B \-\-sector-size
|
||||
options.
|
||||
.
|
||||
.SS "Export AES secure keys from the secure key repository"
|
||||
@@ -320,7 +324,7 @@ options.
|
||||
.BR export | ex
|
||||
.I secure\-key\-file
|
||||
.B \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -329,9 +333,8 @@ Use the
|
||||
command to export an existing secure key contained in the secure key repository
|
||||
to a file in the file system. Specify the name of the key that is to be exported
|
||||
using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option. You cannot use wildcards.
|
||||
When wildcards are used you must quote the value.
|
||||
The exported secure key also remains in the secure key repository.
|
||||
.
|
||||
.SS "List AES secure keys contained in the secure key repository"
|
||||
@@ -339,20 +342,22 @@ The exported secure key also remains in the secure key repository.
|
||||
.B zkey
|
||||
.BR list | li
|
||||
.RB [ \-\-name | \-N
|
||||
.IB key-name ]
|
||||
.IR key-name ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IB card1.domain1[,card2.domain2[,...]] ]
|
||||
.IR card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B list
|
||||
command to display a list of secure keys contained in the secure key repository.
|
||||
You can filter the displayed list by key name, associated volumes, and
|
||||
associated cryptographic adapters (APQNs). You can use wildcards for the key
|
||||
name, associated APQNs, and associated volumes. The device-mapper name of an
|
||||
You can filter the displayed list by key name, associated volumes, associated
|
||||
cryptographic adapters (APQNs), and volume type. You can use wildcards for the
|
||||
key name, associated APQNs, and associated volumes. The device-mapper name of an
|
||||
associated volume can be omitted; if it is specified then only those keys are
|
||||
listed that are associated with the specified volume and device-mapper name.
|
||||
.PP
|
||||
@@ -361,15 +366,15 @@ The
|
||||
command displays the attributes of the secure keys, such as key sizes,
|
||||
whether it is a secure key that can be used for the XTS cipher mode, the textual
|
||||
description, associated cryptographic adapters (APQNs) and volumes, the
|
||||
sector size, and timestamps for key creation, last modification and last
|
||||
re-encipherment.
|
||||
sector size, the key verification pattern, and timestamps for key creation, last
|
||||
modification and last re-encipherment.
|
||||
.
|
||||
.SS "Remove existing AES secure keys from the secure key repository"
|
||||
.
|
||||
.B zkey
|
||||
.BR remove | rem
|
||||
.B \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.RB [ \-\-force | \-F ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
@@ -378,60 +383,64 @@ Use the
|
||||
.B remove
|
||||
command to remove an existing secure key from the secure key repository.
|
||||
Specify the name of the key that is to be removed using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option. You cannot use wildcards. The remove command prompts for
|
||||
a confirmation, unless you specify the
|
||||
.B --force
|
||||
.B \-\-force
|
||||
option.
|
||||
.PP
|
||||
.B Note:
|
||||
When removing a secure key that is associated with one or multiple volumes,
|
||||
and the key's volume type is \fBplain\fP,
|
||||
a message informs you about the associated volumes. When the secure key is
|
||||
removed, these volumes can no longer be used, unless you have a backup of the
|
||||
secure key.
|
||||
secure key. For keys with volume type \fBluks2\fP no such message is issued,
|
||||
because the secure key is contained in the LUKS2 header.
|
||||
.
|
||||
.SS "Change existing AES secure keys contained the secure key repository"
|
||||
.
|
||||
.B zkey
|
||||
.BR change | ch
|
||||
.B \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.RB [ \-\-description | \-d
|
||||
.IB description ]
|
||||
.IR description ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB [+|-]volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.IR [+|-]volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IB [+|-]card1.domain1[,card2.domain2[,...]] ]
|
||||
.IR [+|-]card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ \-\-sector-size | \-S
|
||||
.IB bytes ]
|
||||
.IR bytes ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B change
|
||||
command to change the description, the associated volumes, the associated
|
||||
cryptographic adapters (APQNs), and the sector size of a secure key contained
|
||||
in the secure key repository. Specify the name of the key that is to be changed
|
||||
using the
|
||||
.B --name
|
||||
cryptographic adapters (APQNs), the sector size, and the volume type of a secure
|
||||
key contained in the secure key repository. Specify the name of the key that is
|
||||
to be changed using the
|
||||
.B \-\-name
|
||||
option. You cannot use wildcards.
|
||||
.PP
|
||||
You can set (replace), add, or
|
||||
remove volume and cryptographic adapters (APQN) associations. To set
|
||||
(replace) an association, specify the association with the
|
||||
.B --volumes
|
||||
.B \-\-volumes
|
||||
or the
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
options. To add an association,
|
||||
specify the new association prefixed with a \fI+\fP with the
|
||||
.B --volumes
|
||||
.B \-\-volumes
|
||||
or the
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
options. To remove an association,
|
||||
specify the association to remove prefixed with a \fI-\fP with the
|
||||
.B --volumes
|
||||
.B \-\-volumes
|
||||
or the
|
||||
.B --apqns
|
||||
.B \-\-apqns
|
||||
options. You cannot mix \fI+\fP and
|
||||
\fI-\fP in one specification. You can either add or remove (or set) the
|
||||
associations with one command.
|
||||
@@ -447,9 +456,9 @@ command.
|
||||
.B zkey
|
||||
.BR rename | ren
|
||||
.B \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.B \-\-new-name | \-w
|
||||
.IB new-key-name
|
||||
.IR new-key-name
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -457,21 +466,30 @@ Use the
|
||||
.B rename
|
||||
command to rename an existing secure key in the secure key repository.
|
||||
Specify the name of the key that is to be renamed using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option and the new name using the
|
||||
.B --new-name
|
||||
.B \-\-new-name
|
||||
option. You cannot use wildcards.
|
||||
.
|
||||
.B Note:
|
||||
When renaming a secure key that is associated with one or multiple volumes and
|
||||
the key's volume type is \fBplain\fP, a message informs you about the
|
||||
associated volumes. When the secure key is renamed, these volumes can no
|
||||
longer be used, unless you change the name of the secure key in the 'cryptsetup
|
||||
plainOpen' commands and in the '/etc/crypttab' entries.
|
||||
For keys with volume type \fBluks2\fP no such message is issued, because the
|
||||
secure key is contained in the LUKS2 header.
|
||||
.
|
||||
.SS "Copy (duplicate) existing AES secure keys in the secure key repository"
|
||||
.
|
||||
.B zkey
|
||||
.B copy | co
|
||||
.RB \-\-name | \-N
|
||||
.IB key-name
|
||||
.IR key-name
|
||||
.B \-\-new-key-name | \-w
|
||||
.IB new-name
|
||||
.IR new-name
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -479,15 +497,15 @@ Use the
|
||||
.B copy
|
||||
command to copy (duplicate) an existing secure key in the secure key repository.
|
||||
Specify the name of the key that is to be copied using the
|
||||
.B --name
|
||||
.B \-\-name
|
||||
option and the name of the copied key using the
|
||||
.B --new-name
|
||||
.B \-\-new-name
|
||||
option. You cannot use wildcards.
|
||||
.PP
|
||||
.B Note:
|
||||
When copying a secure key, the volume associations are not copied, because
|
||||
a specific volume can only be associated with a single secure key. Specify the
|
||||
.B --volumes
|
||||
.B \-\-volumes
|
||||
option to associate different
|
||||
volumes with the copied secure key, or use the \fBchange\fP command to associate
|
||||
volumes afterwards.
|
||||
@@ -497,45 +515,56 @@ volumes afterwards.
|
||||
.B zkey
|
||||
.BR crypttab | cryptt
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B crypttab
|
||||
command to generate crypttab entries using the \fBplain\fP dm-crypt mode
|
||||
for volumes that are associated with secure keys contained in the secure key
|
||||
repository. Specify the
|
||||
.B --volumes
|
||||
command to generate crypttab entries using the \fBplain\fP or \fBLUKS2\fP
|
||||
dm-crypt mode for volumes that are associated with secure keys contained in the
|
||||
secure key repository. Specify the
|
||||
.B \-\-volumes
|
||||
option to limit the list
|
||||
of volumes where crypttab entries are generated for. You can use wildcards.
|
||||
When wildcards are used you must quote the value.
|
||||
The device-mapper name of an associated volume can be omitted; if it is
|
||||
specified then only those volumes with the specified volume and device-mapper
|
||||
name are selected.
|
||||
Specify the
|
||||
.B \-\-volume-type
|
||||
option to generate crypttab entries for the specified volume type only.
|
||||
.
|
||||
.SS "Generate cryptsetup commands for volumes associated with secure AES keys"
|
||||
.
|
||||
.B zkey
|
||||
.BR cryptsetup | crypts
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IB volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-run | \-r ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B cryptsetup
|
||||
command to generate \fBcryptsetup plainOpen\fP commands for volumes that are
|
||||
associated with secure keys contained in the secure key repository. Specify the
|
||||
.B --volumes
|
||||
command to generate \fBcryptsetup plainOpen\fP or \fBcryptsetup luksFormat\fP
|
||||
commands for volumes that are associated with secure keys contained in the
|
||||
secure key repository. Specify the
|
||||
.B \-\-volumes
|
||||
option to limit the list
|
||||
of volumes where cryptsetup commands are generated for. You can use wildcards.
|
||||
When wildcards are used you must quote the value.
|
||||
The device-mapper name of an associated volume can be omitted; if it is
|
||||
specified then only those volumes with the specified volume and device-mapper
|
||||
name are selected. Specify the
|
||||
.B --run
|
||||
.B \-\-volume-type
|
||||
option to generate cryptsetup commands for the specified volume type only.
|
||||
Specify the
|
||||
.B \-\-run
|
||||
option to run the generated cryptsetup commands.
|
||||
.
|
||||
.
|
||||
@@ -589,8 +618,17 @@ This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
|
||||
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
|
||||
and in the range 512 - 4096 bytes. If omitted, the system default sector size
|
||||
is used.
|
||||
and in the range of 512 to 4096 bytes. If omitted, the system default sector
|
||||
size is used.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is used.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled,
|
||||
the default volume type is \fBplain\fP.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.
|
||||
.
|
||||
@@ -650,7 +688,7 @@ repository is performed in staged mode. Staged mode means that the re-enciphered
|
||||
secure key is stored in a separate file in the secure key repository. Thus the
|
||||
current secure key is still valid at this point. Once the new CCA master key has
|
||||
been set (made active), you must rerun the reencipher command with option
|
||||
\fB--complete\fP to complete the staged re-enciphering.
|
||||
\fB\-\-complete\fP to complete the staged re-enciphering.
|
||||
Re-enciphering from CURRENT to NEW is performed in staged mode per default.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
@@ -690,8 +728,17 @@ This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
|
||||
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
|
||||
and in the range 512 - 4096 bytes. If omitted, the system default sector size
|
||||
is used.
|
||||
and in the range of 512 to 4096 bytes. If omitted, the system default sector
|
||||
size is used.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. If omitted, \fBluks2\fP is used.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled. If LUKS2 support is not enabled,
|
||||
the default volume type is \fBplain\fP.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.
|
||||
.
|
||||
@@ -734,6 +781,15 @@ APQNs. Each APQN association specifies a card and domain number separated
|
||||
by a period (like lszcrypt displays it). You can use wildcards in the APQN
|
||||
specification.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
||||
type are listed.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -791,9 +847,16 @@ This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-S ", " \-\-sector-size\~\fIbytes\fP
|
||||
Specifies the sector size in bytes used with dm-crypt. It must be a power of two
|
||||
and in the range 512 - 4096 bytes. If omitted, the system default sector size
|
||||
is used. Specify \fI0\fP to un-set the sector size so that the system default
|
||||
is used.
|
||||
and in the range of 512 to 4096 bytes. Specify \fI0\fP to set the sector size
|
||||
to the system default.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.
|
||||
.
|
||||
@@ -845,6 +908,15 @@ specified volume and device-mapper name. You can use wildcards to specify
|
||||
the volumes and device-mapper names.
|
||||
When wildcards are used you must quote the value.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
||||
type are selected to generate crypttab entries for.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -861,10 +933,18 @@ the volumes and device-mapper names.
|
||||
When wildcards are used you must quote the value.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-r ", " \-\-run\fP
|
||||
Runs the generated cryptsetup commands. When an execution of a cryptsetup
|
||||
command fails, no further cryptsetup commands are executed, and zkey ends
|
||||
with an error.
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
||||
type are selected to generate cryptsetup commands for.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-r ", " \-\-run
|
||||
Runs the generated cryptsetup commands. When one of the cryptsetup command fail,
|
||||
no further cryptsetup commands are run, and zkey ends with an error.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.
|
||||
.
|
||||
@@ -895,15 +975,20 @@ in file 'seckey.bin'.
|
||||
Generates a secure AES key from the clear key in file 'clearkey.bin' and
|
||||
stores it in file 'seckey.bin'.
|
||||
.TP
|
||||
.B zkey generate --name seckey
|
||||
.B zkey generate \-\-name seckey
|
||||
Generates a random 256-bit secure AES key and stores it in the secure key
|
||||
repository under the name 'seckey'.
|
||||
repository using the name 'seckey'.
|
||||
.TP
|
||||
.B zkey generate --name seckey --volumes /dev/dasdc1:encvol --apqns 03.004c
|
||||
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-apqns 03.004c
|
||||
Generates a random 256-bit secure AES key and stores it in the secure key
|
||||
repository under the name 'seckey' and associates it with block
|
||||
repository using the name 'seckey' and associates it with block
|
||||
device '/dev/dasdc1' and device-mapper name 'encvol', and APQN '03.004c'.
|
||||
.TP
|
||||
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-volume-type luks2
|
||||
Generates a random 256-bit secure AES key and stores it in the secure key
|
||||
repository using the name 'seckey' and associates it with block
|
||||
device '/dev/dasdc1' and device-mapper name 'encvol', and a volume type of luks2.
|
||||
.TP
|
||||
.B zkey reencipher seckey.bin \-\-from\-old
|
||||
Re-enciphers the secure key in file 'seckey.bin' which is currently enciphered
|
||||
with the master key in the OLD register with the master key in the CURRENT
|
||||
@@ -915,17 +1000,17 @@ Re-enciphers the secure key in file 'seckey.bin' which is currently enciphered
|
||||
with the master key in the CURRENT register with the master key in the NEW
|
||||
register, and saves the re-enciphered secure key to file 'seckey2.bin'.
|
||||
.TP
|
||||
.B zkey reencipher --name seckey
|
||||
.B zkey reencipher \-\-name seckey
|
||||
Re-enciphers the secure key 'seckey' in the secure key repository.
|
||||
.TP
|
||||
.B zkey reencipher --apqns 03.004c
|
||||
.B zkey reencipher \-\-apqns 03.004c
|
||||
Re-enciphers all secure keys contained in the secure key repository that are
|
||||
associated with APQN '03.004c'.
|
||||
.TP
|
||||
.B zkey validate seckey.bin
|
||||
Validates the secure key in file 'seckey.bin' and displays its attributes.
|
||||
.TP
|
||||
.B zkey validate --name seckey
|
||||
.B zkey validate \-\-name seckey
|
||||
Validates the secure key 'seckey' in the secure key repository and displays its
|
||||
attributes.
|
||||
.TP
|
||||
@@ -933,25 +1018,28 @@ attributes.
|
||||
Lists all secure keys in the secure key repository and displays its
|
||||
attributes.
|
||||
.TP
|
||||
.B zkey list --name '*key'
|
||||
.B zkey list \-\-name '*key'
|
||||
Lists all secure keys in the secure key repository with names ending with 'key'
|
||||
and displays its attributes.
|
||||
.TP
|
||||
.B zkey change --name seckey --volumes +/dev/dasdc2:encvol2
|
||||
.B zkey change \-\-name seckey \-\-volumes +/dev/dasdc2:encvol2
|
||||
Changes the secure key 'seckey' in the secure key repository and adds
|
||||
volume '/dev/dasdc2' with device-mapper name 'encvol2' to the list of associated
|
||||
volumes of this secure key.
|
||||
.TP
|
||||
.B zkey change --name seckey --apqns -03.004c
|
||||
.B zkey change \-\-name seckey \-\-apqns -03.004c
|
||||
Changes the secure key 'seckey' in the secure key repository and removes
|
||||
APQN '03.004c' from the list of associated APQNs of this secure key.
|
||||
.TP
|
||||
.B zkey crypttab --volumes '/dev/dasdc*'
|
||||
.B zkey crypttab \-\-volumes '/dev/dasdc*'
|
||||
Generates crypttab entries for all volumes that match the pattern '/dev/dasdc*'.
|
||||
.TP
|
||||
.B zkey cryptsetup --volumes '*:enc_dasd'
|
||||
.B zkey cryptsetup \-\-volumes '*:enc_dasd'
|
||||
Generates cryptsetup commands for the volumes that uses the device-mapper
|
||||
name 'enc_dasd'.
|
||||
.TP
|
||||
.B zkey cryptsetup \-\-volume-type luks2
|
||||
Generates cryptsetup commands for all volumes of type luks2.
|
||||
.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
|
||||
127
zkey/zkey.c
127
zkey/zkey.c
@@ -68,6 +68,7 @@ static struct zkey_globals {
|
||||
char *volumes;
|
||||
char *apqns;
|
||||
long int sector_size;
|
||||
char *volume_type;
|
||||
char *newname;
|
||||
bool run;
|
||||
bool force;
|
||||
@@ -180,6 +181,16 @@ static struct util_opt opt_vec[] = {
|
||||
"used",
|
||||
.command = COMMAND_GENERATE,
|
||||
},
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
{
|
||||
.option = { "volume-type", required_argument, NULL, 't'},
|
||||
.argument = "type",
|
||||
.desc = "The type of the associated volume(s). Possible values "
|
||||
"are 'plain' and 'luks2'. When this option is omitted, "
|
||||
"the default is 'luks2'",
|
||||
.command = COMMAND_GENERATE,
|
||||
},
|
||||
#endif
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
@@ -211,19 +222,23 @@ static struct util_opt opt_vec[] = {
|
||||
},
|
||||
{
|
||||
.option = {"complete", 0, NULL, 'p'},
|
||||
.desc = "Completes a pending re-enciphering of a secure AES "
|
||||
"key that was re-enciphered with the master key in the "
|
||||
"NEW register",
|
||||
.desc = "Completes a staged re-enciphering. Use this option "
|
||||
"after the new CCA master key has been set (made "
|
||||
"active)",
|
||||
.command = COMMAND_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"in-place", 0, NULL, 'i'},
|
||||
.desc = "Forces an in-place re-enchipering of a secure AES key",
|
||||
.desc = "Forces an in-place re-enchipering of a secure AES "
|
||||
"key. Re-enciphering from OLD to CURRENT is performed "
|
||||
"in-place per default",
|
||||
.command = COMMAND_REENCIPHER,
|
||||
},
|
||||
{
|
||||
.option = {"staged", 0, NULL, 's'},
|
||||
.desc = "Forces a staged re-enchipering of a secure AES key",
|
||||
.desc = "Forces that the re-enciphering of a secure AES key is "
|
||||
"performed in staged mode. Re-enciphering from CURRENT "
|
||||
"to NEW is performed in staged mode per default",
|
||||
.command = COMMAND_REENCIPHER,
|
||||
},
|
||||
{
|
||||
@@ -310,6 +325,16 @@ static struct util_opt opt_vec[] = {
|
||||
"used",
|
||||
.command = COMMAND_IMPORT,
|
||||
},
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
{
|
||||
.option = { "volume-type", required_argument, NULL, 't'},
|
||||
.argument = "type",
|
||||
.desc = "The type of the associated volume(s). Possible values "
|
||||
"are 'plain' and 'luks2'. When this option is omitted, "
|
||||
"the default is 'luks2'",
|
||||
.command = COMMAND_IMPORT,
|
||||
},
|
||||
#endif
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
@@ -358,6 +383,16 @@ static struct util_opt opt_vec[] = {
|
||||
"associated with specific crypto cards",
|
||||
.command = COMMAND_LIST,
|
||||
},
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
{
|
||||
.option = { "volume-type", required_argument, NULL, 't'},
|
||||
.argument = "type",
|
||||
.desc = "The type of the associated volume(s). Possible values "
|
||||
"are 'plain' and 'luks2'. Use this option to list all "
|
||||
"keys with the specified volumes type.",
|
||||
.command = COMMAND_LIST,
|
||||
},
|
||||
#endif
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
@@ -422,11 +457,19 @@ static struct util_opt opt_vec[] = {
|
||||
.option = { "sector-size", required_argument, NULL, 'S'},
|
||||
.argument = "0|512|4096",
|
||||
.desc = "The sector size used with dm-crypt. It must be power "
|
||||
"of two and in range 512 - 4096 bytes. If this option "
|
||||
"is omitted, the system default sector size (512) is "
|
||||
"used",
|
||||
"of two and in range 512 - 4096 bytes. Specify 0 to "
|
||||
"use the system default sector size (512)",
|
||||
.command = COMMAND_CHANGE,
|
||||
},
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
{
|
||||
.option = { "volume-type", required_argument, NULL, 't'},
|
||||
.argument = "type",
|
||||
.desc = "The type of the associated volume(s). Possible values "
|
||||
"are 'plain' and 'luks2'",
|
||||
.command = COMMAND_CHANGE,
|
||||
},
|
||||
#endif
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
@@ -494,6 +537,17 @@ static struct util_opt opt_vec[] = {
|
||||
"volume and the device-mapper name matches",
|
||||
.command = COMMAND_CRYPTTAB,
|
||||
},
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
{
|
||||
.option = { "volume-type", required_argument, NULL, 't'},
|
||||
.argument = "type",
|
||||
.desc = "The type of the associated volume(s). Possible values "
|
||||
"are 'plain' and 'luks2'. Use this option to select "
|
||||
"the keys by its volume type for which a crypttab "
|
||||
"entry is to be generated",
|
||||
.command = COMMAND_CRYPTTAB,
|
||||
},
|
||||
#endif
|
||||
/***********************************************************/
|
||||
{
|
||||
.flags = UTIL_OPT_FLAG_SECTION,
|
||||
@@ -512,6 +566,17 @@ static struct util_opt opt_vec[] = {
|
||||
"both, the volume and the device-mapper name matches",
|
||||
.command = COMMAND_CRYPTSETUP,
|
||||
},
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
{
|
||||
.option = { "volume-type", required_argument, NULL, 't'},
|
||||
.argument = "type",
|
||||
.desc = "The type of the associated volume(s). Possible values "
|
||||
"are 'plain' and 'luks2'. Use this option to select "
|
||||
"the keys by its volume type for which a crypttab "
|
||||
"entry is to be generated",
|
||||
.command = COMMAND_CRYPTSETUP,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.option = {"run", 0, NULL, 'r'},
|
||||
.desc = "Runs the generated cryptsetup command",
|
||||
@@ -819,7 +884,7 @@ static int command_generate_repository(void)
|
||||
|
||||
rc = keystore_generate_key(g.keystore, g.name, g.description, g.volumes,
|
||||
g.apqns, g.sector_size, g.keybits, g.xts,
|
||||
g.clearkeyfile, g.pkey_fd);
|
||||
g.clearkeyfile, g.volume_type, g.pkey_fd);
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1057,6 +1122,7 @@ static int command_reencipher(void)
|
||||
*/
|
||||
static int command_validate_file(void)
|
||||
{
|
||||
char vp[VERIFICATION_PATTERN_LEN];
|
||||
size_t secure_key_size;
|
||||
size_t clear_key_size;
|
||||
u8 *secure_key;
|
||||
@@ -1089,14 +1155,30 @@ static int command_validate_file(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = generate_key_verification_pattern((char *)secure_key,
|
||||
secure_key_size, vp, sizeof(vp),
|
||||
g.verbose);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to generate the verification pattern: %s",
|
||||
strerror(-rc));
|
||||
warnx("Make sure that kernel module 'paes_s390' is loaded and "
|
||||
"that the 'paes' cipher is available");
|
||||
rc = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Validation of secure key in file '%s':\n", g.pos_arg);
|
||||
printf(" Status: Valid\n");
|
||||
printf(" Secure key size: %lu bytes\n", secure_key_size);
|
||||
printf(" Clear key size: %lu bits\n", clear_key_size);
|
||||
printf(" XTS type key: %s\n",
|
||||
printf(" Status: Valid\n");
|
||||
printf(" Secure key size: %lu bytes\n", secure_key_size);
|
||||
printf(" Clear key size: %lu bits\n", clear_key_size);
|
||||
printf(" XTS type key: %s\n",
|
||||
secure_key_size > SECURE_KEY_SIZE ? "Yes" : "No");
|
||||
printf(" Encrypted with: %s CCA master key\n",
|
||||
printf(" Enciphered with: %s CCA master key\n",
|
||||
is_old_mk ? "OLD" : "CURRENT");
|
||||
printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2,
|
||||
vp);
|
||||
printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2,
|
||||
&vp[VERIFICATION_PATTERN_LEN / 2]);
|
||||
|
||||
out:
|
||||
free(secure_key);
|
||||
@@ -1150,7 +1232,8 @@ static int command_import(void)
|
||||
g.sector_size = 0;
|
||||
|
||||
rc = keystore_import_key(g.keystore, g.name, g.description, g.volumes,
|
||||
g.apqns, g.sector_size, g.pos_arg);
|
||||
g.apqns, g.sector_size, g.pos_arg,
|
||||
g.volume_type);
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1183,7 +1266,8 @@ static int command_list(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns);
|
||||
rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns,
|
||||
g.volume_type);
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1222,7 +1306,7 @@ static int command_change(void)
|
||||
}
|
||||
|
||||
rc = keystore_change_key(g.keystore, g.name, g.description, g.volumes,
|
||||
g.apqns, g.sector_size);
|
||||
g.apqns, g.sector_size, g.volume_type);
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1282,7 +1366,7 @@ static int command_crypttab(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = keystore_crypttab(g.keystore, g.volumes);
|
||||
rc = keystore_crypttab(g.keystore, g.volumes, g.volume_type);
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1296,7 +1380,7 @@ static int command_cryptsetup(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = keystore_cryptsetup(g.keystore, g.volumes, g.run);
|
||||
rc = keystore_cryptsetup(g.keystore, g.volumes, g.run, g.volume_type);
|
||||
|
||||
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1473,6 +1557,11 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_LUKS2_SUPPORT
|
||||
case 't':
|
||||
g.volume_type = optarg;
|
||||
break;
|
||||
#endif
|
||||
case 'w':
|
||||
g.newname = optarg;
|
||||
break;
|
||||
|
||||
18
zpcictl/Makefile
Normal file
18
zpcictl/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
include ../common.mak
|
||||
|
||||
all: zpcictl
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
zpcictl: zpcictl.o $(libs)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zpcictl $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 zpcictl.8 \
|
||||
$(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ zpcictl core
|
||||
|
||||
.PHONY: all install clean
|
||||
75
zpcictl/zpcictl.8
Normal file
75
zpcictl/zpcictl.8
Normal file
@@ -0,0 +1,75 @@
|
||||
.\" Copyright IBM Corp. 2018
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.\" Macro for inserting an option description prologue.
|
||||
.\" .OD <long> [<short>] [args]
|
||||
.de OD
|
||||
. ds args "
|
||||
. if !'\\$3'' .as args \fI\\$3\fP
|
||||
. if !'\\$4'' .as args \\$4
|
||||
. if !'\\$5'' .as args \fI\\$5\fP
|
||||
. if !'\\$6'' .as args \\$6
|
||||
. if !'\\$7'' .as args \fI\\$7\fP
|
||||
. PD 0
|
||||
. if !'\\$2'' .IP "\fB\-\\$2\fP \\*[args]" 4
|
||||
. if !'\\$1'' .IP "\fB\-\-\\$1\fP \\*[args]" 4
|
||||
. PD
|
||||
..
|
||||
.
|
||||
.TH zpcictl 8 "Oct 2018" s390-tools zpcictl
|
||||
.
|
||||
.SH NAME
|
||||
zpcictl - Manage PCI devices on IBM Z
|
||||
.
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
.B "zpcictl"
|
||||
.I "OPTIONS"
|
||||
.I "DEVICE"
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
Use
|
||||
.B zpcictl
|
||||
to manage PCI devices on the IBM Z platform. In particular,
|
||||
use this command to report defective PCI devices to the service element.
|
||||
|
||||
.B Note:
|
||||
For NVMe devices additional data (such as S.M.A.R.T. data) is collected and sent
|
||||
with any error handling action. For this extendend data collection, the
|
||||
smartmontools must be installed.
|
||||
.PP
|
||||
.
|
||||
.
|
||||
.SH DEVICE
|
||||
A PCI slot address (e.g. 0000:00:00.0) or the main device node of an NVMe
|
||||
device (e.g.
|
||||
.I /dev/nvme0
|
||||
).
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
.SS Error Handling Options
|
||||
.OD reset "" "DEVICE"
|
||||
Reset and re-initialize the PCI device.
|
||||
.PP
|
||||
.
|
||||
.OD deconfigure "" "DEVICE"
|
||||
Deconfigure the PCI device and prepare for any repair action. This action
|
||||
changes the status of the PCI device from configured to reserved.
|
||||
.PP
|
||||
.
|
||||
.OD report-error "" "DEVICE"
|
||||
Report any device error for the PCI device.
|
||||
The device is marked as defective but no further action is taken.
|
||||
.PP
|
||||
.
|
||||
.SS General Options
|
||||
.OD help "h" ""
|
||||
Print usage information, then exit.
|
||||
.PP
|
||||
.
|
||||
.OD version "v" ""
|
||||
Print version information, then exit.
|
||||
.PP
|
||||
402
zpcictl/zpcictl.c
Normal file
402
zpcictl/zpcictl.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* zpcictl - Manage PCI devices on z Systems
|
||||
*
|
||||
* Copyright IBM Corp. 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/util_proc.h"
|
||||
#include "lib/util_rec.h"
|
||||
#include "lib/util_scandir.h"
|
||||
|
||||
#include "zpcictl.h"
|
||||
|
||||
#define SMARTCTL_CMDLINE "smartctl -x %s 2>/dev/null"
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Use zpcictl to manage PCI devices on IBM Z\n"
|
||||
"DEVICE is the slot ID or node of the device "
|
||||
"(e.g. 0000:00:00.0 or /dev/nvme0)",
|
||||
.args = "DEVICE",
|
||||
.copyright_vec = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2018,
|
||||
.pub_last = 2018,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
};
|
||||
|
||||
/* Defines for options with no short command */
|
||||
#define OPT_RESET 128
|
||||
#define OPT_DECONF 129
|
||||
#define OPT_REPORT_ERR 130
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("ERROR HANDLING OPTIONS"),
|
||||
{
|
||||
.option = { "reset", no_argument, NULL, OPT_RESET },
|
||||
.desc = "Reset the device",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "deconfigure", no_argument, NULL, OPT_DECONF },
|
||||
.desc = "Deconfigure the device to prepare for any repair action",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "report-error", no_argument, NULL, OPT_REPORT_ERR },
|
||||
.desc = "Report a device error to the service element (SE)",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
UTIL_OPT_SECTION("GENERAL OPTIONS"),
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
static int is_char_dev(const char *dev)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if (stat(dev, &s))
|
||||
return 0;
|
||||
|
||||
return S_ISCHR(s.st_mode);
|
||||
}
|
||||
|
||||
static int is_blk_dev(const char *dev)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if (stat(dev, &s))
|
||||
return 0;
|
||||
|
||||
return S_ISBLK(s.st_mode);
|
||||
}
|
||||
|
||||
static void fopen_err(char *path)
|
||||
{
|
||||
warnx("Could not open file %s: %s", path, strerror(errno));
|
||||
free(path);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define READ_CHUNK_SIZE 512
|
||||
|
||||
static char *collect_smart_data(struct zpci_device *pdev)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
size_t count = 0;
|
||||
char *cmd;
|
||||
FILE *fd;
|
||||
|
||||
if (!pdev->device)
|
||||
return NULL;
|
||||
|
||||
util_asprintf(&cmd, SMARTCTL_CMDLINE, pdev->device);
|
||||
fd = popen(cmd, "r");
|
||||
if (!fd)
|
||||
goto out;
|
||||
|
||||
while (!feof(fd)) {
|
||||
buffer = realloc(buffer, count + READ_CHUNK_SIZE);
|
||||
if (!buffer) {
|
||||
warnx("Could not collect S.M.A.R.T. data");
|
||||
goto out;
|
||||
}
|
||||
count += fread(&buffer[count], 1, READ_CHUNK_SIZE, fd);
|
||||
if (ferror(fd)) {
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = realloc(buffer, count);
|
||||
if (!buffer && count > 0)
|
||||
warnx("Could not collect S.M.A.R.T. data");
|
||||
if (buffer)
|
||||
buffer[count] = '\0';
|
||||
|
||||
out:
|
||||
pclose(fd);
|
||||
free(cmd);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static unsigned int sysfs_read_value(struct zpci_device *pdev, const char *attr)
|
||||
{
|
||||
unsigned int val;
|
||||
char *path;
|
||||
FILE *fp;
|
||||
|
||||
path = util_path_sysfs("bus/pci/devices/%s/%s", pdev->slot, attr);
|
||||
fp = fopen(path, "r");
|
||||
if (!fp)
|
||||
fopen_err(path);
|
||||
fscanf(fp, "%x", &val);
|
||||
fclose(fp);
|
||||
free(path);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void sysfs_write_data(struct zpci_report_error *report, char *slot)
|
||||
{
|
||||
size_t r_size;
|
||||
char *path;
|
||||
FILE *fp;
|
||||
|
||||
r_size = sizeof(*report);
|
||||
|
||||
path = util_path_sysfs("bus/pci/devices/%s/report_error", slot);
|
||||
fp = fopen(path, "w");
|
||||
if (!fp)
|
||||
fopen_err(path);
|
||||
if (fwrite(report, 1, r_size, fp) != r_size)
|
||||
warnx("Could not write to file: %s: %s", path, strerror(errno));
|
||||
if (fclose(fp))
|
||||
warnx("Could not close file: %s: %s", path, strerror(errno));
|
||||
free(path);
|
||||
}
|
||||
|
||||
/* lstat() doesn't work for sysfs files, so we have to work with a fixed size */
|
||||
#define READLINK_SIZE 256
|
||||
|
||||
static int sysfs_get_slot_addr(const char *dev, char *slot)
|
||||
{
|
||||
char device[READLINK_SIZE], *result;
|
||||
unsigned int major, minor;
|
||||
struct stat dev_stat;
|
||||
ssize_t len;
|
||||
char *path;
|
||||
|
||||
if (stat(dev, &dev_stat) != 0) {
|
||||
warnx("Could not get stat information for %s: %s",
|
||||
dev, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
major = major(dev_stat.st_rdev);
|
||||
minor = minor(dev_stat.st_rdev);
|
||||
|
||||
path = util_path_sysfs("dev/char/%u:%u/device", major, minor);
|
||||
len = readlink(path, device, READLINK_SIZE - 1);
|
||||
free(path);
|
||||
if (len != -1) {
|
||||
device[len] = '\0';
|
||||
} else {
|
||||
warnx("Could not read device link for %s", dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = strrchr(device, '/');
|
||||
if (result)
|
||||
result++;
|
||||
else
|
||||
result = device;
|
||||
strcpy(slot, result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void get_device_node(struct zpci_device *pdev)
|
||||
{
|
||||
struct dirent **de_vec;
|
||||
char *path, *dev;
|
||||
char slot[13];
|
||||
int count, i;
|
||||
|
||||
path = util_path_sysfs("bus/pci/devices/%s/nvme", pdev->slot);
|
||||
count = util_scandir(&de_vec, alphasort, path, "nvme*");
|
||||
if (count == -1) {
|
||||
warnx("Could not read directory %s: %s", path, strerror(errno));
|
||||
free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
util_asprintf(&dev, "/dev/%s", de_vec[i]->d_name);
|
||||
if (!sysfs_get_slot_addr(dev, slot))
|
||||
continue;
|
||||
if (strcmp(slot, pdev->slot) == 0) {
|
||||
pdev->device = dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
util_scandir_free(de_vec, count);
|
||||
free(path);
|
||||
}
|
||||
|
||||
static int device_exists(char *dev)
|
||||
{
|
||||
char *path;
|
||||
int rc = 0;
|
||||
|
||||
path = util_path_sysfs("bus/pci/devices/%s", dev);
|
||||
if (util_path_exists(path) || util_path_exists(dev))
|
||||
rc = 1;
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void get_device_info(struct zpci_device *pdev, char *dev)
|
||||
{
|
||||
if (!device_exists(dev))
|
||||
errx(EXIT_FAILURE, "Could not find device %s", dev);
|
||||
if (is_blk_dev(dev))
|
||||
errx(EXIT_FAILURE, "Unsupported device type %s", dev);
|
||||
if (is_char_dev(dev)) {
|
||||
if (!sysfs_get_slot_addr(dev, pdev->slot))
|
||||
errx(EXIT_FAILURE,
|
||||
"Could not determine slot address for %s", dev);
|
||||
pdev->device = dev;
|
||||
} else {
|
||||
strcpy(pdev->slot, dev);
|
||||
}
|
||||
|
||||
pdev->class = sysfs_read_value(pdev, "class");
|
||||
pdev->fid = sysfs_read_value(pdev, "function_id");
|
||||
pdev->pchid = sysfs_read_value(pdev, "pchid");
|
||||
|
||||
/*
|
||||
* In case a slot address was specified, the device node for NVMe
|
||||
* devices is still needed. Otherwise it won't be possible to collect
|
||||
* S.M.A.R.T. data at a later point.
|
||||
*/
|
||||
if (!pdev->device && pdev->class == PCI_CLASS_NVME)
|
||||
get_device_node(pdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue an SCLP Adapter Error Notification event with a specific action
|
||||
* qualifier.
|
||||
*
|
||||
* Collect additional information when possible (e.g. S.M.A.R.T. data for NVMe
|
||||
* devices).
|
||||
*/
|
||||
static void sclp_issue_action(struct zpci_device *pdev, int action)
|
||||
{
|
||||
struct zpci_report_error report = {
|
||||
.header = { 0 },
|
||||
.data = { 0 }
|
||||
};
|
||||
char *sdata = NULL;
|
||||
|
||||
report.header.version = 1;
|
||||
report.header.action = action;
|
||||
report.header.length = sizeof(report.data);
|
||||
report.data.timestamp = (__u64)time(NULL);
|
||||
report.data.err_log_id = 0x4713;
|
||||
|
||||
if (pdev->class == PCI_CLASS_NVME)
|
||||
sdata = collect_smart_data(pdev);
|
||||
if (sdata) {
|
||||
strncpy(report.data.log_data, sdata, sizeof(report.data.log_data));
|
||||
free(sdata);
|
||||
}
|
||||
sysfs_write_data(&report, pdev->slot);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the PCI device and initiate a re-initialization.
|
||||
*/
|
||||
static void sclp_reset_device(struct zpci_device *pdev)
|
||||
{
|
||||
sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_RESET);
|
||||
}
|
||||
|
||||
/*
|
||||
* De-Configure/repair PCI device. Moves the device from configured
|
||||
* to reserved state.
|
||||
*/
|
||||
static void sclp_deconfigure(struct zpci_device *pdev)
|
||||
{
|
||||
sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_DECONF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Report an error to the SE.
|
||||
*/
|
||||
static void sclp_report_error(struct zpci_device *pdev)
|
||||
{
|
||||
sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_REPORT_ERR);
|
||||
}
|
||||
|
||||
static void parse_cmdline(int argc, char *argv[], struct options *opts)
|
||||
{
|
||||
int cmd;
|
||||
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
do {
|
||||
cmd = util_opt_getopt_long(argc, argv);
|
||||
|
||||
switch (cmd) {
|
||||
case OPT_RESET:
|
||||
opts->reset = 1;
|
||||
break;
|
||||
case OPT_DECONF:
|
||||
opts->deconfigure = 1;
|
||||
break;
|
||||
case OPT_REPORT_ERR:
|
||||
opts->report = 1;
|
||||
break;
|
||||
case 'h':
|
||||
util_prg_print_help();
|
||||
util_opt_print_help();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'v':
|
||||
util_prg_print_version();
|
||||
exit(EXIT_SUCCESS);
|
||||
case -1:
|
||||
/* End of options string */
|
||||
if (argc == 1) {
|
||||
errx(EXIT_FAILURE,
|
||||
"Use '%s --help' for more information",
|
||||
argv[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (cmd != -1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct zpci_device pdev = { 0 };
|
||||
struct options opts = { 0 };
|
||||
|
||||
parse_cmdline(argc, argv, &opts);
|
||||
|
||||
if (optind >= argc)
|
||||
errx(EXIT_FAILURE, "No device specified");
|
||||
|
||||
get_device_info(&pdev, argv[optind]);
|
||||
|
||||
if (opts.reset)
|
||||
sclp_reset_device(&pdev);
|
||||
else if (opts.deconfigure)
|
||||
sclp_deconfigure(&pdev);
|
||||
else if (opts.report)
|
||||
sclp_report_error(&pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
60
zpcictl/zpcictl.h
Normal file
60
zpcictl/zpcictl.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* zpcictl - Manage PCI devices on z Systems
|
||||
*
|
||||
* Copyright IBM Corp. 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef ZPCICTL_H
|
||||
#define ZPCICTL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define SCLP_ERRNOTIFY_AQ_RESET 0
|
||||
#define SCLP_ERRNOTIFY_AQ_DECONF 1
|
||||
#define SCLP_ERRNOTIFY_AQ_REPORT_ERR 2
|
||||
|
||||
#define PCI_CLASS_UNCLASSIFIED 0x000000U
|
||||
#define PCI_CLASS_NVME 0x010802U
|
||||
#define PCI_CLASS_NETWORK 0x020000U
|
||||
|
||||
struct options {
|
||||
unsigned int reset;
|
||||
unsigned int deconfigure;
|
||||
unsigned int report;
|
||||
};
|
||||
|
||||
struct zpci_device {
|
||||
u16 fid;
|
||||
u16 pchid;
|
||||
u32 class;
|
||||
char slot[13];
|
||||
char *device;
|
||||
};
|
||||
|
||||
struct zpci_report_error_header {
|
||||
__u8 version; /* Interface version byte */
|
||||
__u8 action; /* Action qualifier byte
|
||||
* 0: Adapter Reset Request
|
||||
* 1: Deconfigure and repair action requested
|
||||
* 2: Informational Report
|
||||
*/
|
||||
__u16 length; /* Length of Subsequent Data (up to 4K – SCLP header) */
|
||||
__u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */
|
||||
};
|
||||
|
||||
struct zpci_report_error_data {
|
||||
__u64 timestamp;
|
||||
__u64 err_log_id;
|
||||
char log_data[4054]; /* We cannot exceed a total of 4074 bytes (header + data) */
|
||||
};
|
||||
|
||||
struct zpci_report_error {
|
||||
struct zpci_report_error_header header;
|
||||
struct zpci_report_error_data data;
|
||||
} __packed;
|
||||
|
||||
#endif /* ZPCICTL_H */
|
||||
Reference in New Issue
Block a user