mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
364b4c0686 | ||
|
|
8818e229cc | ||
|
|
ed18044925 | ||
|
|
3c80f7e025 | ||
|
|
70243b8135 | ||
|
|
2f461f673e | ||
|
|
c0dc514af8 | ||
|
|
e831269e74 | ||
|
|
063425d515 | ||
|
|
61b60baf57 | ||
|
|
cd085dc721 | ||
|
|
c2cb410b8f | ||
|
|
0b4686dd76 | ||
|
|
ca50924acb | ||
|
|
8ff6af3a4b | ||
|
|
221e74c27c | ||
|
|
6c3c721275 | ||
|
|
93d91679c3 | ||
|
|
6b8b336cf0 | ||
|
|
616d379c60 | ||
|
|
f3f16a7ca4 | ||
|
|
d029030308 | ||
|
|
097c498340 | ||
|
|
73d5e17026 | ||
|
|
f3e552d67c | ||
|
|
5ba519973f | ||
|
|
18f1730b92 | ||
|
|
f1a5ab20b7 | ||
|
|
39382ec5fd | ||
|
|
2e8ad91d3d | ||
|
|
7548b470c2 | ||
|
|
b4714e6113 | ||
|
|
fe0b2d96f7 | ||
|
|
b53793d1b6 | ||
|
|
9b5568d2ef |
@@ -2,8 +2,8 @@ List of all individuals having contributed content to s390-tools
|
||||
----------------------------------------------------------------
|
||||
|
||||
- Alexey Ishchuk
|
||||
- Andreas Herrmann
|
||||
- Andre Wild
|
||||
- Andreas Herrmann
|
||||
- Antoinette Kaschner
|
||||
- Arnd Bergmann
|
||||
- Axel Wirbser
|
||||
@@ -11,13 +11,14 @@ List of all individuals having contributed content to s390-tools
|
||||
- Carsten Otte
|
||||
- Christian Borntraeger
|
||||
- Christof Schmitt
|
||||
- Claudio Imbrenda
|
||||
- Clemens von Mann
|
||||
- Despina Papadopoulou
|
||||
- Eberhard Pasch
|
||||
- Einar Lueck
|
||||
- Erwin Vicari
|
||||
- Eugene Dvurechenski
|
||||
- Eugene Crosser
|
||||
- Eugene Dvurechenski
|
||||
- Farhan Ali
|
||||
- Felix Beck
|
||||
- Frank Blaschka
|
||||
@@ -62,6 +63,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Mikhail Zaslonko
|
||||
- Peter Oberparleiter
|
||||
- Peter Tiedemann
|
||||
- Philipp Kern
|
||||
- Raimund Schroeder
|
||||
- Ralph Wuerthner
|
||||
- Rene Trumpp
|
||||
|
||||
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,11 +1,39 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.1.0 (2017-09-25)__
|
||||
|
||||
Added new tools:
|
||||
- netboot: Scripts for building a PXE-style netboot image for KVM
|
||||
- 90-cpi.rules/cpictl: New udev rule to update CPI when KVM is used
|
||||
|
||||
Changes of existing tools:
|
||||
- lsqeth/zdev: Add VNIC Characteristics support
|
||||
|
||||
Bug Fixes:
|
||||
- chzcrypt: Corrected handling of insufficient permissions
|
||||
- cpacfstats: Add size setting to perf event
|
||||
- fdasd: Skip partition check with the force option
|
||||
- ttyrun: Fix deprecated BindTo usage in ttyrun-getty@.service.in
|
||||
- lszcrypt: Fix core dump caused by stack overwrite
|
||||
- lszcrypt: Fix random domain printout when no config available
|
||||
- zdev: Fix segfault with unknown qeth attribute
|
||||
- zdev: Fix IPv6 NDP proxy description
|
||||
- zdev: Fix zdev dracut module temp file location
|
||||
- zkey: Correctly detect abbreviated commands
|
||||
- zkey: Validate XTS key: ignore domain and card
|
||||
- zkey: Use octal values instead of S_IRWX* constants
|
||||
- zkey: Properly set umask to prohibit permissions to group and others
|
||||
- zkey: Add -ldl to LDLIBS (not LDFLAGS)
|
||||
- znetconf: Re-add missing line in lsznet.raw
|
||||
- Fix several gcc 7 warnings
|
||||
|
||||
* __v2.0.0 (2017-08-21)__
|
||||
|
||||
- Publish package under the MIT license with the same contents as
|
||||
the already available s390-tools-1.39.0
|
||||
|
||||
Previous releases of s390-tools can be found on the IBM Developer Works web pages:
|
||||
Previous releases of s390-tools can be found on the IBM Developer Works
|
||||
web pages:
|
||||
|
||||
- https://www.ibm.com/developerworks/linux/linux390/s390-tools.html
|
||||
|
||||
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
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
all: $(TOOL_DIRS)
|
||||
|
||||
@@ -35,6 +35,8 @@ Package contents
|
||||
- 57-osasnmpd.rules: udev rules for osasnmpd.
|
||||
- 60-readahead.rules: udev rules to set increased "default max readahead".
|
||||
- 40-z90crypt.rules: udev rules for z90crypt driver
|
||||
- 90-cpi.rules: udev rule to update Control-Program-Information when KVM is
|
||||
used.
|
||||
|
||||
* systemd units:
|
||||
- cpi.service: Unit to apply CPI settings
|
||||
@@ -234,6 +236,10 @@ Package contents
|
||||
arbitrary files. It works even when the size of the actual file content
|
||||
is not known beforehand (e.g. FIFOs, sysfs files).
|
||||
|
||||
* netboot:
|
||||
Provides simple tools to create a binary that can be used to implement
|
||||
simple network boot setups following the PXELINUX conventions.
|
||||
|
||||
For more information refer to the following publications:
|
||||
|
||||
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
|
||||
|
||||
135
bin/mk-authors
Executable file
135
bin/mk-authors
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# mk-authors - Update the s390-tools authors file (AUTHORS.md)
|
||||
#
|
||||
# Invocation examples:
|
||||
#
|
||||
# $ mk-authors
|
||||
# $ mk-authors -t v2.0.0
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
cmd=$(basename $0)
|
||||
authors_file="AUTHORS.md"
|
||||
|
||||
cleanup()
|
||||
{
|
||||
test -f $authors_file_tmp && rm -f $authors_file_tmp
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
#
|
||||
# Print usage information
|
||||
#
|
||||
print_usage()
|
||||
{
|
||||
cat <<EoUSAGE
|
||||
Usage: $cmd [-t LAST_GIT_TAG]
|
||||
|
||||
Add all new authors since last release to the $authors_file file. Without
|
||||
the -t option the tool uses the last available git tag as last release.
|
||||
|
||||
The tool should be called form the s390-tools master branch.
|
||||
|
||||
OPTIONS
|
||||
-t, --tag LAST_GIT_TAG Use git tag LAST_GIT_TAG as starting point
|
||||
-h, --help Print this help, then exit
|
||||
EoUSAGE
|
||||
}
|
||||
|
||||
#
|
||||
# Print help hint for option parsing error
|
||||
#
|
||||
print_parse_error_and_exit()
|
||||
{
|
||||
echo "Try '$cmd -h' for more information." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Parse options
|
||||
#
|
||||
opts=$(getopt -o ht: -l help,tag: -n $cmd -- "$@")
|
||||
if [ $? != 0 ]; then
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
# Use eval to remove getopt quotes
|
||||
eval set -- $opts
|
||||
while [ -n $1 ]; do
|
||||
case $1 in
|
||||
-h | --help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
-t | --tag)
|
||||
release_tag_last=$2
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $# != 0 ]; then
|
||||
echo "$cmd: Invalid argument $1" >&2
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
#
|
||||
# Get git root and last release tag
|
||||
#
|
||||
git_root=$(git rev-parse --show-toplevel 2> /dev/null)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$cmd: Use tool within s390-tools git repository" >&2
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
authors_file_path=$git_root/$authors_file
|
||||
# Get last release tag if not specified via -t
|
||||
if [ -z $release_tag_last ]; then
|
||||
tag_commit=$(git rev-list --tags --max-count=1)
|
||||
release_tag_last=$(git describe --tags $tag_commit)
|
||||
fi
|
||||
# Verify release tag
|
||||
git show $release_tag_last &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$cmd: Cannot find tag '$release_tag_last'" >&2
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
#
|
||||
# Update authors file
|
||||
#
|
||||
|
||||
# Create temporary file for new author list
|
||||
authors_file_tmp=$(mktemp /tmp/authors.XXXXXX)
|
||||
|
||||
echo "$cmd: Adding new authors since tag: $release_tag_last"
|
||||
{
|
||||
# Print authors list without header
|
||||
tail -n +4 $authors_file_path
|
||||
# Add the new authors
|
||||
git log --format="- %an" $release_tag_last..
|
||||
# Then sort everything and remove duplicates
|
||||
} | sort | uniq > $authors_file_tmp
|
||||
# Create new AUTHORS file with header ...
|
||||
cat <<EoHEADER > $authors_file_path
|
||||
List of all individuals having contributed content to s390-tools
|
||||
----------------------------------------------------------------
|
||||
|
||||
EoHEADER
|
||||
# ... and add new content
|
||||
cat $authors_file_tmp >> $authors_file_path
|
||||
|
||||
cat <<EoUPDATE_MSG
|
||||
- Updated file: $authors_file_path
|
||||
- Verify changes with: git diff $authors_file_path
|
||||
- Do a manual *cleanup* before commiting if necessary.
|
||||
EoUPDATE_MSG
|
||||
@@ -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 = 0
|
||||
RELEASE = 1
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
|
||||
@@ -97,6 +97,7 @@ int perf_init(void)
|
||||
memset(&pfm_event, 0, sizeof(pfm_event));
|
||||
pfm_arg.attr = &pfm_event;
|
||||
pfm_arg.size = sizeof(pfm_arg);
|
||||
pfm_event.size = sizeof(pfm_event);
|
||||
|
||||
/* search for the counter's corresponding pfm name */
|
||||
for (i = ALL_COUNTER-1; i >= 0; i--)
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define READCHUNK 80
|
||||
#define RD_BUFFER_SIZE 80
|
||||
#define BLKSSZGET _IO(0x12,104)
|
||||
#define DASD_IOCTL_LETTER 'D'
|
||||
#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,struct dasd_information)
|
||||
@@ -236,29 +237,9 @@ static char *dinfo_ebcdic_dec (char *source, char *target, int l)
|
||||
return target;
|
||||
}
|
||||
|
||||
static int dinfo_read_dasd_uid (char *uidfile, char *readbuf, int readbuflen)
|
||||
static int dinfo_read_dasd_uid(char *uidfile, char *readbuf)
|
||||
{
|
||||
FILE *dasduid;
|
||||
int offset = 0;
|
||||
|
||||
if ((dasduid = fopen(uidfile,"r")) == NULL)
|
||||
return -1;
|
||||
|
||||
while (fgets(readbuf + offset, READCHUNK, dasduid) &&
|
||||
readbuf[strlen(readbuf)-1] != '\n' ) {
|
||||
offset += READCHUNK-1;
|
||||
if ( offset+READCHUNK-1 >= readbuflen ) {
|
||||
readbuf = realloc(readbuf,
|
||||
readbuflen + READCHUNK-1);
|
||||
readbuflen += READCHUNK-1;
|
||||
}
|
||||
}
|
||||
fclose(dasduid);
|
||||
|
||||
if (strlen(readbuf) <= 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return util_file_read_line(readbuf, RD_BUFFER_SIZE, uidfile);
|
||||
}
|
||||
|
||||
static int dinfo_read_dasd_vlabel (char *device, struct volume_label *vlabel,
|
||||
@@ -411,14 +392,14 @@ static void dinfo_free_devnode(char *device)
|
||||
}
|
||||
}
|
||||
|
||||
static int dinfo_extract_dev(dev_t *dev, char *str, int readbuflen)
|
||||
static int dinfo_extract_dev(dev_t *dev, char *str)
|
||||
{
|
||||
char tmp[readbuflen];
|
||||
char tmp[RD_BUFFER_SIZE];
|
||||
char *p = NULL;
|
||||
int ma, mi;
|
||||
|
||||
bzero(tmp, readbuflen);
|
||||
strncpy(tmp, str, readbuflen);
|
||||
bzero(tmp, RD_BUFFER_SIZE);
|
||||
strncpy(tmp, str, RD_BUFFER_SIZE);
|
||||
if ((p = strchr(tmp, ':')) == NULL) {
|
||||
printf("Error: unable to extract major/minor\n");
|
||||
return -1;
|
||||
@@ -435,37 +416,17 @@ static int dinfo_extract_dev(dev_t *dev, char *str, int readbuflen)
|
||||
|
||||
static int dinfo_get_dev_from_blockdev(char *blockdev, dev_t *dev)
|
||||
{
|
||||
FILE *dasddev;
|
||||
int offset = 0;
|
||||
char *devfile = NULL;
|
||||
char *readbuf = NULL;
|
||||
int readbuflen = READCHUNK;
|
||||
|
||||
if ((devfile = dinfo_malloc(readbuflen)) == NULL)
|
||||
return -1;
|
||||
|
||||
sprintf(devfile,"/sys/block/%s/dev", blockdev);
|
||||
|
||||
if ((readbuf = dinfo_malloc(readbuflen)) == NULL) {
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!readbuf) {
|
||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((dasddev = fopen(devfile,"r")) == NULL)
|
||||
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
|
||||
"/sys/block/%s/dev", blockdev) < 0)
|
||||
return -1;
|
||||
|
||||
while (fgets(readbuf + offset, READCHUNK, dasddev) &&
|
||||
readbuf[strlen(readbuf)-1] != '\n' ) {
|
||||
offset += READCHUNK-1;
|
||||
if (offset+READCHUNK-1 >= readbuflen) {
|
||||
readbuf = realloc(readbuf,
|
||||
readbuflen + READCHUNK-1);
|
||||
readbuflen += READCHUNK-1;
|
||||
}
|
||||
}
|
||||
fclose(dasddev);
|
||||
|
||||
if (dinfo_extract_dev(dev, readbuf, readbuflen) != 0)
|
||||
if (dinfo_extract_dev(dev, readbuf) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@@ -580,14 +541,10 @@ out2:
|
||||
static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
{
|
||||
struct stat stat_buffer;
|
||||
char stat_dev[READCHUNK];
|
||||
char sys_dev_path[READCHUNK];
|
||||
char stat_dev[RD_BUFFER_SIZE];
|
||||
char *readbuf;
|
||||
DIR *directory = NULL;
|
||||
struct dirent *dir_entry = NULL;
|
||||
FILE *block_dev;
|
||||
int readbuflen = READCHUNK;
|
||||
int offset;
|
||||
|
||||
if (stat(devnode, &stat_buffer) != 0) {
|
||||
printf("Error: could not stat %s\n", devnode);
|
||||
@@ -602,33 +559,22 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((readbuf = dinfo_malloc(readbuflen)) == NULL) {
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!readbuf) {
|
||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((dir_entry = readdir(directory)) != NULL) {
|
||||
sprintf(sys_dev_path, "/sys/block/%s/dev", dir_entry->d_name);
|
||||
|
||||
if ((block_dev = fopen(sys_dev_path,"r")) == NULL)
|
||||
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
|
||||
"/sys/block/%s/dev",
|
||||
dir_entry->d_name) < 0)
|
||||
continue;
|
||||
|
||||
offset = 0;
|
||||
while (fgets(readbuf + offset, READCHUNK, block_dev) &&
|
||||
readbuf[strlen(readbuf)-1] != '\n' ) {
|
||||
offset += READCHUNK-1;
|
||||
if ( offset+READCHUNK-1 >= readbuflen ) {
|
||||
readbuf = realloc(readbuf,
|
||||
readbuflen + READCHUNK-1);
|
||||
readbuflen += READCHUNK-1;
|
||||
}
|
||||
}
|
||||
fclose(block_dev);
|
||||
|
||||
if (strncmp(stat_dev, readbuf,
|
||||
MAX(strlen(stat_dev), strlen(readbuf)-1)) == 0) {
|
||||
sprintf(*uidfile,"/sys/block/%s/device/uid",
|
||||
dir_entry->d_name);
|
||||
snprintf(*uidfile, RD_BUFFER_SIZE,
|
||||
"/sys/block/%s/device/uid", dir_entry->d_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -644,7 +590,6 @@ int main(int argc, char * argv[])
|
||||
char *uidfile = NULL;
|
||||
char *device = NULL;
|
||||
char *readbuf = NULL;
|
||||
int readbuflen = READCHUNK;
|
||||
dev_t dev;
|
||||
int export = 0;
|
||||
int c;
|
||||
@@ -733,8 +678,9 @@ int main(int argc, char * argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (((readbuf = dinfo_malloc(readbuflen)) == NULL) ||
|
||||
((uidfile = dinfo_malloc(readbuflen)) == NULL))
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
uidfile = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!(readbuf && uidfile))
|
||||
exit(1);
|
||||
|
||||
/* try to read the uid attribute */
|
||||
@@ -753,7 +699,7 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
|
||||
if (print_uid) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf, readbuflen) == 0) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf) == 0) {
|
||||
/* look for the 4th '.' and cut there */
|
||||
srchuid = readbuf - 1;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
@@ -766,20 +712,20 @@ int main(int argc, char * argv[])
|
||||
srchuid[1] = 0;
|
||||
}
|
||||
if (export) {
|
||||
printf("ID_UID=%s",readbuf);
|
||||
printf("ID_UID=%s\n", readbuf);
|
||||
} else
|
||||
printf("%s",readbuf);
|
||||
printf("%s\n", readbuf);
|
||||
if (!print_vlabel && !print_extended_uid)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_extended_uid) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf, readbuflen) == 0) {
|
||||
if (dinfo_read_dasd_uid(uidfile, readbuf) == 0) {
|
||||
if (export) {
|
||||
printf("ID_XUID=%s",readbuf);
|
||||
printf("ID_XUID=%s\n", readbuf);
|
||||
} else
|
||||
printf("%s",readbuf);
|
||||
printf("%s\n", readbuf);
|
||||
if (!print_vlabel)
|
||||
goto out;
|
||||
}
|
||||
@@ -808,7 +754,8 @@ int main(int argc, char * argv[])
|
||||
goto error;
|
||||
|
||||
} else if (devnode) {
|
||||
if ((device = dinfo_malloc(readbuflen)) == NULL)
|
||||
device = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!device)
|
||||
exit(1);
|
||||
strcpy(device, devnode);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
# The system and sysplex names consist of up to eight characters of
|
||||
# the following set: A-Z, 0-9, $, @, #, and blank.
|
||||
|
||||
#
|
||||
# CPI system type
|
||||
#
|
||||
CPI_SYSTEM_TYPE="LINUX"
|
||||
|
||||
#
|
||||
# CPI system name
|
||||
#
|
||||
|
||||
6
etc/udev/rules.d/90-cpi.rules
Normal file
6
etc/udev/rules.d/90-cpi.rules
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# Rules to trigger cpictl when KVM is used
|
||||
# This file should be installed in /etc/udev/rules.d
|
||||
#
|
||||
|
||||
SUBSYSTEM=="misc", KERNEL=="kvm", ENV{CREATED}=="1", ENV{EVENT}=="create", RUN+="/lib/s390-tools/cpictl -b kvm"
|
||||
@@ -308,7 +308,7 @@ static void fdasd_cleanup(fdasd_anchor_t *anchor)
|
||||
/*
|
||||
* Exit fdasd.
|
||||
*/
|
||||
static void fdasd_exit(fdasd_anchor_t *anchor, int rc)
|
||||
static void __noreturn fdasd_exit(fdasd_anchor_t *anchor, int rc)
|
||||
{
|
||||
fdasd_cleanup(anchor);
|
||||
exit(rc);
|
||||
@@ -921,7 +921,7 @@ static void fdasd_verify_device(fdasd_anchor_t *anc, char *name)
|
||||
fdasd_error(anc, device_verification_failed, err_str);
|
||||
}
|
||||
|
||||
if (minor(dst.st_rdev) & PARTN_MASK) {
|
||||
if (!anc->force_virtual && minor(dst.st_rdev) & PARTN_MASK) {
|
||||
snprintf(err_str, ERROR_STRING_SIZE,
|
||||
"Partition '%s' (%d/%d) detected where device is "
|
||||
"required\n", name,
|
||||
|
||||
@@ -348,7 +348,7 @@ void hyptop_text_mode(void)
|
||||
/*
|
||||
* Exit hyptop
|
||||
*/
|
||||
void hyptop_exit(int rc)
|
||||
void __noreturn hyptop_exit(int rc)
|
||||
{
|
||||
hyptop_text_mode();
|
||||
exit(rc);
|
||||
|
||||
@@ -216,7 +216,7 @@ extern void win_cpu_types_init(void);
|
||||
* Misc functions
|
||||
*/
|
||||
extern void hyptop_update_term(void);
|
||||
extern void hyptop_exit(int rc);
|
||||
extern void __noreturn hyptop_exit(int rc);
|
||||
extern void hyptop_text_mode(void);
|
||||
|
||||
#endif /* HYPTOP_H */
|
||||
|
||||
@@ -97,7 +97,7 @@ static struct locals {
|
||||
enum reipl_type reipl_type; /* CCW, FCP, NSS */
|
||||
} l;
|
||||
|
||||
static void print_usage_chreipl_exit(void)
|
||||
static void __noreturn print_usage_chreipl_exit(void)
|
||||
{
|
||||
printf(usage_chreipl, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -34,7 +34,7 @@ static const char *const usage_chshut =
|
||||
" -h, --help Print this help, then exit\n"
|
||||
" -v, --version Print version information, then exit\n";
|
||||
|
||||
static void print_usage_chshut_exit(void)
|
||||
static void __noreturn print_usage_chshut_exit(void)
|
||||
{
|
||||
printf(usage_chshut, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -25,7 +25,7 @@ static const char *const usage_lsreipl =
|
||||
" -h, --help Print this help, then exit\n"
|
||||
" -v, --version Print version information, then exit\n";
|
||||
|
||||
static void print_usage_lsreipl_exit(void)
|
||||
static void __noreturn print_usage_lsreipl_exit(void)
|
||||
{
|
||||
printf(usage_lsreipl, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -20,7 +20,7 @@ static const char *const usage_lsshut =
|
||||
" -h, --help Print this help, then exit\n"
|
||||
" -v, --version Print version information, then exit\n";
|
||||
|
||||
static void print_usage_lsshut_exit(void)
|
||||
static __noreturn void print_usage_lsshut_exit(void)
|
||||
{
|
||||
printf(usage_lsshut, g.prog_name);
|
||||
exit(0);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <lib/zt_common.h>
|
||||
|
||||
#define IPL_TYPE_LEN_MAX 100
|
||||
#define NSS_NAME_LEN_MAX 8
|
||||
|
||||
@@ -57,8 +59,8 @@ extern void read_str(char *string, const char *file, size_t len);
|
||||
extern void read_fw_str(char *string, const char *file, size_t len);
|
||||
extern void print_fw_str(const char *fmt, const char *dir, const char *file);
|
||||
|
||||
extern void print_version_exit(void);
|
||||
extern void print_help_hint_exit(void);
|
||||
extern void __noreturn print_version_exit(void);
|
||||
extern void __noreturn print_help_hint_exit(void);
|
||||
|
||||
/*
|
||||
* FCP
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
|
||||
struct globals g;
|
||||
|
||||
void print_help_hint_exit(void)
|
||||
void __noreturn print_help_hint_exit(void)
|
||||
{
|
||||
fprintf(stderr, "Try '%s' --help' for more information.\n",
|
||||
g.prog_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void print_version_exit(void)
|
||||
void __noreturn print_version_exit(void)
|
||||
{
|
||||
printf("%s: Linux on System z shutdown actions version %s\n",
|
||||
g.prog_name, RELEASE_STRING);
|
||||
|
||||
@@ -71,8 +71,8 @@ static const struct tool_info iucv_tool[2] = {
|
||||
};
|
||||
|
||||
|
||||
static void usage_exit(const struct tool_info *prg, int is_error,
|
||||
const char *msg)
|
||||
static void __noreturn usage_exit(const struct tool_info *prg, int is_error,
|
||||
const char *msg)
|
||||
{
|
||||
if (msg != NULL)
|
||||
fprintf(stderr, _("%s: %s\n"), prg->name, msg);
|
||||
@@ -80,7 +80,7 @@ static void usage_exit(const struct tool_info *prg, int is_error,
|
||||
exit(is_error ? 1 : 0); /* rc=1 .. invalid args */
|
||||
}
|
||||
|
||||
static void version_exit(const struct tool_info *prg)
|
||||
static void __noreturn version_exit(const struct tool_info *prg)
|
||||
{
|
||||
printf(_("%s: IUCV Terminal Applications, version %s\n"),
|
||||
prg->name, RELEASE_STRING);
|
||||
|
||||
@@ -62,13 +62,13 @@ static const char usage[] =
|
||||
"-h, --help Displays this help, then exits.\n"
|
||||
"-v, --version Displays version information, then exits.\n";
|
||||
|
||||
static void help_exit(const char *prg)
|
||||
static void __noreturn help_exit(const char *prg)
|
||||
{
|
||||
printf(usage, prg, prg);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void version_exit(const char *prg)
|
||||
static void __noreturn version_exit(const char *prg)
|
||||
{
|
||||
printf("%s: Start a program if a terminal device is available, "
|
||||
"version %s\n", prg, RELEASE_STRING);
|
||||
|
||||
21
netboot/Dockerfile
Normal file
21
netboot/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Sample Dockerfile to build PXE-style boot image for KVM on s390
|
||||
#
|
||||
|
||||
FROM s390x/ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
linux-image-4.4.0-78-generic \
|
||||
make \
|
||||
wget \
|
||||
bzip2 \
|
||||
linux-headers-4.4.0-78-generic \
|
||||
gcc \
|
||||
kexec-tools \
|
||||
file
|
||||
|
||||
RUN mkdir /netboot
|
||||
|
||||
COPY . /netboot
|
||||
|
||||
RUN cd /netboot && make -f Makefile.pxelinux.0 KERNEL_VERSION=4.4.0-78-generic
|
||||
16
netboot/Makefile
Normal file
16
netboot/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
# Install the netboot image build scripts as samples
|
||||
|
||||
include ../common.mak
|
||||
|
||||
NETBOOT_SAMPLEDIR=$(TOOLS_DATADIR)/netboot
|
||||
|
||||
all:
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
$(INSTALL) -m 755 mk-s390image mk-pxelinux-ramfs \
|
||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
$(INSTALL) -m 644 Dockerfile Makefile.pxelinux.0 README.md \
|
||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
|
||||
.PHONY: all install clean
|
||||
46
netboot/Makefile.pxelinux.0
Normal file
46
netboot/Makefile.pxelinux.0
Normal file
@@ -0,0 +1,46 @@
|
||||
# Sample Makefile to produce a pxe-style netboot image
|
||||
# matching the currently active kernel.
|
||||
# If the image is to be build for a different kernel version
|
||||
# the KERNEL_VERSION variable must be overridden
|
||||
# To use a local busybox installation, change BBINSTALL
|
||||
# to point to the local busybox install path
|
||||
|
||||
ifeq ("$(KERNEL_VERSION)","")
|
||||
KERNEL_VERSION=$(shell uname -r)
|
||||
endif
|
||||
export KERNEL_VERSION
|
||||
|
||||
filetype=$(shell file $1 | grep "Linux S390")
|
||||
s390_check=$(if $(call filetype,$1), $1)
|
||||
prefixes=image vmlinux vmlinuz
|
||||
kernel_images=$(foreach prefix, $(prefixes), \
|
||||
$(call s390_check,/boot/$(prefix)-$(KERNEL_VERSION)))
|
||||
KERNEL_IMAGE=$(firstword $(kernel_images))
|
||||
|
||||
ifeq ($(KERNEL_IMAGE),)
|
||||
$(error Could not find a kernel image under /boot)
|
||||
endif
|
||||
|
||||
BUSYBOX=busybox-1.27.1
|
||||
BBINSTALL=$(BUSYBOX)/_install
|
||||
|
||||
all: $(KERNEL_IMAGE) pxelinux.initramfs
|
||||
/bin/bash mk-s390image $(KERNEL_IMAGE) pxelinux.0 -r pxelinux.initramfs
|
||||
|
||||
pxelinux.initramfs: $(BBINSTALL)
|
||||
/bin/bash mk-pxelinux-ramfs -b $< -k $(KERNEL_VERSION) $@
|
||||
|
||||
$(BUSYBOX)/_install:
|
||||
wget https://busybox.net/downloads/$(BUSYBOX).tar.bz2
|
||||
tar xjf $(BUSYBOX).tar.bz2
|
||||
make -C $(BUSYBOX) defconfig
|
||||
make -C $(BUSYBOX) install
|
||||
|
||||
install:
|
||||
|
||||
clean:
|
||||
$(RM) pxelinux.0 pxelinux.initramfs $(BUSYBOX).tar.bz2
|
||||
$(RM) -r $(BUSYBOX)
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
99
netboot/README.md
Normal file
99
netboot/README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# How to build a PXELINUX-style network boot image for KVM
|
||||
|
||||
## Synopsis
|
||||
|
||||
To build a PXELINUX-style netboot image usable for KVM a s390 Linux system
|
||||
with access to the internet is required.
|
||||
|
||||
Running the following command will generate the netboot image pxlinux.0:
|
||||
|
||||
` $ make -f Makefile.pxelinux.0`
|
||||
|
||||
Alternatively you can use docker to build the image:
|
||||
|
||||
```
|
||||
$ docker build -t pxelinux0 .
|
||||
$ docker run --rm -v $(pwd):/out pxelinux0 cp /netboot/pxelinux.0 /out
|
||||
$ docker rmi pxelinux0
|
||||
```
|
||||
|
||||
The resulting file pxelinux.0 must be copied to the system acting as
|
||||
DHCP/BOOTP server for the KVM installation.
|
||||
|
||||
## Full Description
|
||||
|
||||
Starting with QEMU 2.10 it is possible to boot s390 virtual machines over a
|
||||
network interface using DHCP. As usual for DHCP/BOOTP a single bootable image
|
||||
is copied from the boot server, loaded into memory and booted. In order to
|
||||
boot a Linux Operating System, it is typically necessary to load a kernel
|
||||
together with an initial ramdisk (initramfs) and optionally specify some kernel
|
||||
command line parameters.
|
||||
|
||||
Alternatively, on s390 it is possible to load a single file consisting of
|
||||
the kernel image followed by an initial ramdisk. Such single boot images can
|
||||
be provided by a Linux distributor, e.g. on the installation media.
|
||||
|
||||
Single boot images can also easily be built from pre-existing kernel/initramfs
|
||||
pairs by concatenating these files. In order to allow the kernel to find the
|
||||
ramdisk, it is necessary to update the 8 bytes at location 0x10408 with the
|
||||
offset value of the ramdisk in the new binary, and the 8 bytes at location
|
||||
0x10410 with the size of the ramdisk. Both values need to be updated in binary,
|
||||
big endian format.
|
||||
|
||||
Since PXELINUX, the PXE boot implementation provided by the Syslinux project,
|
||||
has introduced a popular way to set up network boot servers for Linux, it
|
||||
is desirable that s390 network boot setups can be done in a similar way.
|
||||
A boot image simulating a PXELINUX-like boot for s390 can be easily
|
||||
constructed by combining a Linux kernel with a small fit-to-purpose initial
|
||||
ramdisk as described above. For practical purposes, using the host kernel is
|
||||
a reasonable way for this kind of approach. If possible, the initial ramdisk
|
||||
should be independent of the host, which is not always possible, as the kernel
|
||||
might require modules for e.g. virtio network and block devices.
|
||||
|
||||
### Example: Building a PXELINUX-style boot image
|
||||
|
||||
The approach described below consists of bundling some shell scripts, busybox
|
||||
and the kexec binary bundled into the initial ramdisk.
|
||||
|
||||
The init process can be a simple shell script that will mount a few essential
|
||||
file systems, like /dev, /proc, and /sys, start a DHCP client (e.g. busybox's
|
||||
udchpc) and then invoke another script to perform the network boot.
|
||||
udchpc will invoke the script /usr/share/udhcpc/default.script in response
|
||||
to DHCP server messages to perform configuration actions.
|
||||
The sample default.script delivered with busybox can be used for that purpose,
|
||||
but needs to be extended to evaluate the bootp specific DHCP options (most
|
||||
important the tftp server address) and store them for use by the boot script.
|
||||
|
||||
The boot script itself has to retrieve the PXELINUX configuration from the
|
||||
tftp server according to the rules described [here][1] then retrieve the
|
||||
remote kernel and initial ramdisk and finally use kexec to boot the network
|
||||
kernel.
|
||||
|
||||
In essence, the following steps are performed to produce the initial
|
||||
ramdisk:
|
||||
|
||||
1. Create a skeleton initramfs directory structure
|
||||
2. Create the init script, the boot script and the DHCP default script
|
||||
3. Copy kexec and it's dependencies from the host into the initramfs
|
||||
4. Copy virtio network and block modules of the host's active kernel into
|
||||
the initramfs
|
||||
5. Copy the busybox binaries into the initramfs.
|
||||
6. Copy the DHCP configuration and PXE boot scripts to the initramfs
|
||||
7. Build the ramdisk (in compressed CPIO format)
|
||||
8. Concatenate the kernel image and the initial ramdisk, and adjust the
|
||||
ramdisk offset as described above.
|
||||
|
||||
Steps 1 to 7 are performed by the sample script mk-pxelinux-ramfs, while step
|
||||
8 is done with the help of mk-s390image.
|
||||
|
||||
The binary resulting from the procedure described above can now be deployed
|
||||
to a DHCP/BOOTP server. This server should also act as a TFTP server for the
|
||||
PXELINUX configuration and binary files needed to complete the network boot.
|
||||
|
||||
Alternatively, it is possible to use programs like [petitboot][2] or
|
||||
[pxe-kexec][3] in the initial ramdisk, as these provide more sophisticated
|
||||
and robust processing of PXELINUX-style configurations.
|
||||
|
||||
[1]: http://www.syslinux.org/wiki/index.php?title=PXELINUX
|
||||
[2]: https://github.com/open-power/petitboot
|
||||
[3]: https://sourceforge.net/projects/pxe-kexec.berlios/
|
||||
402
netboot/mk-pxelinux-ramfs
Executable file
402
netboot/mk-pxelinux-ramfs
Executable file
@@ -0,0 +1,402 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# netboot - PXE-style boot for KVM on s390
|
||||
#
|
||||
# Sample script to build an initramfs image suitable for performing a
|
||||
# PXELINUX-style boot for KVM guests from a DHCP/BOOTP Server.
|
||||
# Has to be executed on the KVM host where it will be deployed and needs
|
||||
# to be re-run after kernel updates on the host, unless the virtio
|
||||
# drivers are statically built into the host kernel.
|
||||
#
|
||||
# The script requires a busybox install tree, e.g. resulting from a build
|
||||
# from source, after make defconfig && make install
|
||||
#
|
||||
# To keep things simple, we don't include udev but use devtmpfs
|
||||
# which means the host kernel must have been built with CONFIG_DEVTMPFS=y
|
||||
#
|
||||
# Sample invocation:
|
||||
#
|
||||
# ./mk-pxelinux-ramfs -b /downloads/busyboxdir pxelinux.initramfs
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
# Variables
|
||||
cmd=$(basename $0)
|
||||
busyboxdir=
|
||||
builddir=
|
||||
initramfs=
|
||||
success=no
|
||||
|
||||
# Cleanup on exit
|
||||
cleanup()
|
||||
{
|
||||
if [ -n $builddir ]
|
||||
then
|
||||
rm -rf $builddir
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Usage
|
||||
usage()
|
||||
{
|
||||
cat <<-EOF
|
||||
Usage: $cmd -b BUSYBOX_DIR [-k KERNEL_VERSION] INITRAMFS_FILE
|
||||
|
||||
Build a PXELINUX style boot initramfs INITRAMFS_FILE using a busybox installed
|
||||
in BUSYBOX_DIR and kernel modules from the currently running kernel or from
|
||||
the kernel version specified with the '-k KERNEL_VERSION' option.
|
||||
|
||||
OPTIONS
|
||||
-b Search installed busybox in directory BUSYBOX_DIR
|
||||
-k Use KERNEL_VERSION instead of currently running kernel
|
||||
-h Print this help, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
# Get shared objects for binary
|
||||
sharedobjs()
|
||||
{
|
||||
ldd $1 | sed -e 's?[^/]*??' -e 's/(.*)//'
|
||||
}
|
||||
|
||||
# Check args
|
||||
args=$(getopt b:k:h $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
set -- $args
|
||||
while [ -n $1 ]
|
||||
do
|
||||
case $1 in
|
||||
-b) busyboxdir=$2; shift 2;;
|
||||
-k) kernelversion=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $# != 1 -o "$busyboxdir" = "" ]
|
||||
then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Full output file path
|
||||
initramfs=$(readlink -m $(dirname $1))/$(basename $1)
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
# Module locations
|
||||
if [ -n $kernelversion ]; then
|
||||
moddir=/lib/modules/$kernelversion
|
||||
else
|
||||
moddir=/lib/modules/$(uname -r)
|
||||
fi
|
||||
netdir=$moddir/kernel/drivers/net
|
||||
blkdir=$moddir/kernel/drivers/block
|
||||
|
||||
# Setup build directory
|
||||
builddir=$(mktemp -d)
|
||||
echo "$cmd: Building in $builddir"
|
||||
|
||||
ramfsdirs="/bin /dev /etc /lib64 /lib /mnt /proc /run /sbin /sys /tmp /usr /var"
|
||||
for d in $ramfsdirs
|
||||
do
|
||||
mkdir -p $builddir/$d
|
||||
done
|
||||
|
||||
# Kexec
|
||||
echo "$cmd: Copying kexec"
|
||||
|
||||
# Install both binary and required shared libraries
|
||||
OLDPATH=$PATH
|
||||
PATH=$OLDPATH:/sbin:/usr/sbin
|
||||
kexec_bin=$(which kexec)
|
||||
kexec_sos=$(sharedobjs $kexec_bin)
|
||||
PATH=$OLDPATH
|
||||
|
||||
cp $kexec_bin $builddir/sbin
|
||||
for so in $kexec_sos
|
||||
do
|
||||
mkdir -p $builddir/$(dirname $so)
|
||||
cp $so $builddir/$(dirname $so)
|
||||
done
|
||||
|
||||
# virtio module(s), if present
|
||||
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
|
||||
set -e
|
||||
|
||||
# Busybox (+ dependencies)
|
||||
echo "$cmd: Copying busybox files"
|
||||
|
||||
cp -a $busyboxdir/* $builddir
|
||||
busybox_sos=$(sharedobjs $busyboxdir/bin/busybox)
|
||||
for so in $busybox_sos
|
||||
do
|
||||
mkdir -p $builddir/$(dirname $so)
|
||||
cp $so $builddir/$(dirname $so)
|
||||
done
|
||||
|
||||
# ad_packet module(s), if present
|
||||
echo "$cmd: Copying af_packet modules"
|
||||
|
||||
packetdir=$moddir/kernel/net/packet
|
||||
mkdir -p $builddir/$packetdir
|
||||
set +e
|
||||
cp $packetdir/* $builddir/$packetdir 2> /dev/null
|
||||
set -e
|
||||
|
||||
# Init script
|
||||
echo "$cmd: Making init script"
|
||||
|
||||
# --- begin init script
|
||||
cat <<'EOF' > $builddir/init
|
||||
#!/bin/sh
|
||||
/bin/mount -t devtmpfs none /dev
|
||||
/bin/mount -t proc none /proc
|
||||
/bin/mount -t sysfs none /sys
|
||||
/bin/mount -t tmpfs none /run
|
||||
|
||||
/sbin/modprobe virtio_net
|
||||
/sbin/udhcpc -O pxeconffile -O pxepathprefix &
|
||||
|
||||
while true
|
||||
do
|
||||
/sbin/pxeboot.script
|
||||
/bin/sleep 1
|
||||
done
|
||||
EOF
|
||||
# --- end init script
|
||||
chmod +x $builddir/init
|
||||
|
||||
# udhcpc script
|
||||
echo "$cmd: Making DHCP script"
|
||||
|
||||
mkdir -p $builddir/usr/share/udhcpc
|
||||
# -- begin dhcp script
|
||||
cat <<'EOF' > $builddir/usr/share/udhcpc/default.script
|
||||
#!/bin/sh
|
||||
# Setup name resolution and PXE boot configuration
|
||||
# called by udhcpc
|
||||
|
||||
RESOLVCONF="/etc/resolv.conf"
|
||||
PXECONF="/etc/pxe.conf"
|
||||
|
||||
ccidr()
|
||||
{
|
||||
# clumsy netmask to cidr transformation
|
||||
# with minimal sanity checking
|
||||
OLDIFS=$IFS
|
||||
IFS=.
|
||||
c=0
|
||||
n=4
|
||||
for i in $1
|
||||
do
|
||||
n=$(/usr/bin/expr $n - 1)
|
||||
case $i in
|
||||
255) c=$(/usr/bin/expr $c + 8);;
|
||||
254) c=$(/usr/bin/expr $c + 7); break;;
|
||||
252) c=$(/usr/bin/expr $c + 6); break;;
|
||||
248) c=$(/usr/bin/expr $c + 5); break;;
|
||||
240) c=$(/usr/bin/expr $c + 4); break;;
|
||||
224) c=$(/usr/bin/expr $c + 3); break;;
|
||||
192) c=$(/usr/bin/expr $c + 2); break;;
|
||||
128) c=$(/usr/bin/expr $c + 1); break;;
|
||||
0) break;;
|
||||
*) c=0; break;;
|
||||
esac
|
||||
if [ $n = 0 ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$OLDIFS
|
||||
echo $c
|
||||
}
|
||||
|
||||
echo "DHCP response $1: "
|
||||
case "$1" in
|
||||
deconfig)
|
||||
echo " interface: $interface"
|
||||
/sbin/ip route flush table all
|
||||
/sbin/ip addr flush $interface
|
||||
/sbin/ip link set $interface up
|
||||
/bin/rm -f $PXECONF $RESOLVCONF
|
||||
;;
|
||||
|
||||
renew|bound)
|
||||
echo " interface: $interface $ip $subnet"
|
||||
echo " router: $router"
|
||||
echo " domain: $domain $dns"
|
||||
echo " tftp: $siaddr"
|
||||
# flush routes
|
||||
/sbin/ip route flush table all
|
||||
# setup if link
|
||||
/sbin/ip addr flush $interface
|
||||
/sbin/ip link set $interface up
|
||||
# setup if addr
|
||||
if [ -n "$subnet" ]
|
||||
then
|
||||
maskedip="$ip"/$(ccidr $subnet)
|
||||
else
|
||||
maskedip="ip"
|
||||
fi
|
||||
/sbin/ip addr add $maskedip broadcast $broadcast dev $interface
|
||||
# setup default routes
|
||||
if [ -n "$router" ]
|
||||
then
|
||||
/sbin/ip route add default via $router
|
||||
fi
|
||||
|
||||
# setup resolv.conf
|
||||
if [ -n "$domain" ]
|
||||
then
|
||||
echo "search $domain" > $RESOLVCONF
|
||||
for i in $dns
|
||||
do
|
||||
echo " nameserver $i" >> $RESOLVCONF
|
||||
done
|
||||
fi
|
||||
|
||||
# pxe control
|
||||
if [ -n "$siaddr" ]
|
||||
then
|
||||
echo "siaddr=$siaddr" > $PXECONF
|
||||
echo "interface=$interface" >> $PXECONF
|
||||
echo "ip=$ip" >> $PXECONF
|
||||
fi
|
||||
;;
|
||||
|
||||
nak)
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
EOF
|
||||
# -- end dhcp script
|
||||
chmod +x $builddir/usr/share/udhcpc/default.script
|
||||
|
||||
# pxeboot script
|
||||
echo "$cmd: Making PXE boot script"
|
||||
|
||||
# -- begin pxeboot script
|
||||
cat <<'EOF' > $builddir/sbin/pxeboot.script
|
||||
#!/bin/sh
|
||||
# Perform a PXE style boot using kexec
|
||||
# Supports only super-simple config files
|
||||
|
||||
set -e
|
||||
|
||||
# Source the DHCP-generated TFTP info
|
||||
# Currently we are just looking for siaddr
|
||||
PXE_CONF=/etc/pxe.conf
|
||||
if [ -f $PXE_CONF ]
|
||||
then
|
||||
. $PXE_CONF
|
||||
else
|
||||
echo waiting for PXE configuration
|
||||
exit
|
||||
fi
|
||||
|
||||
# Retrieve the config (default only for now)
|
||||
CONFIGS=""
|
||||
if [ -n "$siaddr" ];
|
||||
then
|
||||
# Enable UUID based config on s390
|
||||
if [ $(/bin/uname -m) = "s390x" ]
|
||||
then
|
||||
set +e
|
||||
uuid=$(/bin/grep UUID /proc/sysinfo | tail -1 | tr -d ' ' | cut -d ':' -f 2) 2> /dev/null
|
||||
set -e
|
||||
else
|
||||
# not caring for other arches right now
|
||||
uuid=""
|
||||
fi
|
||||
CONFIGS="$CONFIGS $uuid"
|
||||
|
||||
# Enable MAC based config
|
||||
ifaddr=$(/bin/cat /sys/class/net/$interface/address | tr ':' '-')
|
||||
CONFIGS="$CONFIGS 01-$ifaddr"
|
||||
|
||||
# Enable IP based config
|
||||
iphex=$(printf %02X $(echo $ip | tr '.' ' '))
|
||||
for i in 8 7 6 5 4 3 2 1
|
||||
do
|
||||
CONFIGS="$CONFIGS $(echo $iphex | cut -c 1-$i)"
|
||||
done
|
||||
|
||||
# Finally enable default config
|
||||
CONFIGS="$CONFIGS default"
|
||||
|
||||
set +e
|
||||
for c in $CONFIGS
|
||||
do
|
||||
if /usr/bin/tftp -g -l /tmp/config -r pxelinux.cfg/$c $siaddr
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -f /tmp/config ]
|
||||
then
|
||||
echo no config found
|
||||
exit
|
||||
fi
|
||||
|
||||
# Simple config file parsing, only one entry allowed
|
||||
kernel=$(/bin/grep "^[[:space:]]*kernel" /tmp/config | sed "s/^[[:space:]]*kernel[[:space:]]*//")
|
||||
initrd=$(/bin/grep "^[[:space:]]*initrd" /tmp/config | sed "s/^[[:space:]]*initrd[[:space:]]*//")
|
||||
append=$(/bin/grep "^[[:space:]]*append" /tmp/config | sed "s/^[[:space:]]*append[[:space:]]*//")
|
||||
|
||||
if [ -z "$kernel" ]
|
||||
then
|
||||
echo no kernel statement found in config
|
||||
exit
|
||||
else
|
||||
/usr/bin/tftp -g -l /tmp/kernel -r $kernel $siaddr
|
||||
fi
|
||||
|
||||
if [ -n "$initrd" ]
|
||||
then
|
||||
/usr/bin/tftp -g -l /tmp/initrd -r $initrd $siaddr
|
||||
INITRD="--initrd=/tmp/initrd"
|
||||
else
|
||||
INITRD=""
|
||||
fi
|
||||
|
||||
if [ -n "$append" ]
|
||||
then
|
||||
APPEND="--append=$append"
|
||||
else
|
||||
APPEND=""
|
||||
fi
|
||||
|
||||
kexec -l /tmp/kernel $INITRD $APPEND
|
||||
kexec -e
|
||||
EOF
|
||||
# -- end pxeboot script
|
||||
chmod +x $builddir/sbin/pxeboot.script
|
||||
|
||||
# The final initramfs
|
||||
echo Building initramfs
|
||||
|
||||
cd $builddir
|
||||
find . | cpio -o -Hnewc | gzip - > $initramfs
|
||||
cd $OLDPWD
|
||||
171
netboot/mk-s390image
Executable file
171
netboot/mk-s390image
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# netboot - PXE-style boot for KVM on s390
|
||||
#
|
||||
# Sample script to build a single s390 boot image consisting of
|
||||
# kernel, an initial ramdisk and kernel parameters from
|
||||
# individual components. Note that bash is required to run this script!
|
||||
#
|
||||
# Sample invocation:
|
||||
#
|
||||
# ./mk-s390image /boot/image -r /boot/initrd image
|
||||
#
|
||||
# The resulting image can be used to build a bootable
|
||||
# ISO or as firmware image for KVM.
|
||||
#
|
||||
# Copyright IBM Corp. 2017
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
|
||||
# Offsets
|
||||
OFFS_INITRD_START_BYTES=66568
|
||||
OFFS_INITRD_SIZE_BYTES=66576
|
||||
OFFS_COMMANDLINE_BYTES=66688
|
||||
MAX_PARMFILE_SIZE=896
|
||||
|
||||
# Variables
|
||||
cmd=$(basename $0)
|
||||
kernel=
|
||||
ramdisk=
|
||||
parmfile=
|
||||
image=
|
||||
binval=
|
||||
success=no
|
||||
|
||||
# Cleanup on exit
|
||||
cleanup()
|
||||
{
|
||||
if [ -n "$binval" ]
|
||||
then
|
||||
rm -f $binval
|
||||
fi
|
||||
if [ -n "$image" -a $success = no ]
|
||||
then
|
||||
rm $image
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Usage
|
||||
usage()
|
||||
{
|
||||
cat <<-EOF
|
||||
Usage: $cmd KERNEL BOOT_IMAGE [-r RAMDISK] [-p PARMFILE]
|
||||
|
||||
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
|
||||
KVM firmware image using a stripped Linux kernel file KERNEL.
|
||||
|
||||
OPTIONS
|
||||
-p Use PARMFILE with kernel parameters in the image
|
||||
-r Include RAMDISK in the image
|
||||
-h Print this help, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
# Convert decimal number to big endian doubleword
|
||||
dec2be64()
|
||||
{
|
||||
local num=$1
|
||||
local b
|
||||
local i
|
||||
for i in $(seq 1 8)
|
||||
do
|
||||
b="\\x$(printf '%x' $(expr $num % 256))$b"
|
||||
num=$(expr $num / 256) || true
|
||||
done
|
||||
printf $b
|
||||
}
|
||||
|
||||
# Do the image build
|
||||
dobuild()
|
||||
{
|
||||
local i
|
||||
local kernel_size
|
||||
local ramdisk_size
|
||||
local ramdisk_offset
|
||||
local parmfile_size
|
||||
# check whether all specified files exist
|
||||
for i in $kernel $ramdisk $parmfile
|
||||
do
|
||||
if [ ! -f $i ]
|
||||
then
|
||||
echo "$cmd: File $i not found" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
if ! file -b $(readlink -f $kernel) | grep "Linux S390" > /dev/null
|
||||
then
|
||||
echo "$cmd: Unrecognized file format for $kernel" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# from now on we SHOULD only fail on disk shortage
|
||||
# or file permissions, let the shell handle that
|
||||
set -e
|
||||
|
||||
# copy over kernel padded with zeroes to page boundary
|
||||
dd if=$kernel of=$image bs=4096 conv=sync status=none
|
||||
|
||||
# append ramdisk if specified
|
||||
if [ "$ramdisk" != "" ]
|
||||
then
|
||||
ramdisk_size=$(du -b $ramdisk | cut -f1)
|
||||
kernel_size=$(du -b $kernel | cut -f1)
|
||||
ramdisk_offset=$(du -b $image | cut -f1)
|
||||
cat $ramdisk >> $image
|
||||
binval=$(mktemp)
|
||||
dec2be64 $ramdisk_offset > $binval
|
||||
dd seek=$OFFS_INITRD_START_BYTES if=$binval of=$image bs=1 \
|
||||
count=8 conv=notrunc status=none
|
||||
dec2be64 $ramdisk_size > $binval
|
||||
dd seek=$OFFS_INITRD_SIZE_BYTES if=$binval of=$image bs=1 \
|
||||
count=8 conv=notrunc status=none
|
||||
fi
|
||||
|
||||
# set cmdline
|
||||
if [ "$parmfile" != "" ]
|
||||
then
|
||||
parmfile_size=$(du -b $parmfile | cut -f1)
|
||||
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
|
||||
then
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
|
||||
of=$image conv=notrunc status=none
|
||||
else
|
||||
echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $MAX_PARMFILE_SIZE" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# we've done it
|
||||
success=yes
|
||||
}
|
||||
|
||||
# check args and build
|
||||
args=$(getopt "r:p:h" $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
set -- $args
|
||||
while [ $1 != "" ]
|
||||
do
|
||||
case $1 in
|
||||
-r) ramdisk=$2; shift 2;;
|
||||
-p) parmfile=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $# = 2 ]
|
||||
then
|
||||
kernel=$1
|
||||
image=$2
|
||||
dobuild
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# something wasn't right
|
||||
usage >&2
|
||||
exit 1
|
||||
@@ -15,7 +15,12 @@ install:
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(BINDIR)/$$i; \
|
||||
done
|
||||
|
||||
|
||||
sed -e 's+%S390_TOOLS_VERSION%+$(S390_TOOLS_RELEASE)+' cpictl > \
|
||||
$(DESTDIR)$(TOOLS_LIBDIR)/cpictl
|
||||
chown $(OWNER):$(GROUP) $(DESTDIR)$(TOOLS_LIBDIR)/cpictl
|
||||
chmod 775 $(DESTDIR)$(TOOLS_LIBDIR)/cpictl
|
||||
|
||||
@for i in $(MAN_PAGES); \
|
||||
do \
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $$i \
|
||||
|
||||
275
scripts/cpictl
Executable file
275
scripts/cpictl
Executable file
@@ -0,0 +1,275 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# cpictl - Configure the Control-Program-Information (CPI) settings
|
||||
#
|
||||
# This is an internal helper script that is used by the "cpi.service"
|
||||
# systemd unit and the "90-cpi.rules" udev rule.
|
||||
#
|
||||
# The bash shell is really needed. Other shells have different ideas of how
|
||||
# bitwise operators work.
|
||||
#
|
||||
# Copyright 2017 IBM Corp.
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
|
||||
readonly CPI_LOCK="/var/lock/cpictl.lock"
|
||||
|
||||
readonly PRG="${0##*/}"
|
||||
|
||||
readonly SYSTEM_LEVEL_PATH="/sys/firmware/cpi/system_level"
|
||||
readonly SYSTEM_TYPE_PATH="/sys/firmware/cpi/system_type"
|
||||
readonly SYSTEM_NAME_PATH="/sys/firmware/cpi/system_name"
|
||||
readonly SYSPLEX_NAME_PATH="/sys/firmware/cpi/sysplex_name"
|
||||
readonly CPI_SET="/sys/firmware/cpi/set"
|
||||
|
||||
declare LEVEL
|
||||
declare TYPE
|
||||
declare NAME
|
||||
declare SYSPLEX
|
||||
|
||||
declare -i DRYRUN=0
|
||||
|
||||
# Exit codes
|
||||
readonly EXIT_SUCCESS=0
|
||||
readonly EXIT_FAILURE=1
|
||||
readonly EXIT_ARG_TOO_LONG=3
|
||||
readonly EXIT_INVALID_CHARS=4
|
||||
|
||||
print_help_and_exit()
|
||||
{
|
||||
cat <<EndHelp
|
||||
Usage: $PRG [OPTIONS]
|
||||
|
||||
Configure the Control-Program-Information (CPI) settings.
|
||||
|
||||
-b, --set-bit BIT Set and commit the bit BIT in the flags
|
||||
-e, --environment Set and commit the system type, level, name and
|
||||
sysplex name with values taken from environment
|
||||
variables
|
||||
-h, --help Print this help, then exit
|
||||
-L, --level LEVEL Set and commit OS level to LEVEL (format xx.yy.zzABCD)
|
||||
-N, --name SYSTEM Set and commit the system name to SYSTEM
|
||||
-S, --sysplex SYSPLEX Set and commit the sysplex name to SYSPLEX
|
||||
-T, --type TYPE Set and commit OS type to TYPE
|
||||
-v, --version Print version information, then exit
|
||||
--commit Ignore all other options and commit any uncommitted
|
||||
values
|
||||
--dry-run Do not actually set or commit anything, but show what
|
||||
would be done
|
||||
--show Ignore all other options and show current (possibly
|
||||
uncommitted) values
|
||||
|
||||
Environment variables used for the --defaults option:
|
||||
CPI_SYSTEM_TYPE, CPI_SYSTEM_LEVEL, CPI_SYSTEM_NAME, CPI_SYSPLEX_NAME
|
||||
|
||||
Available bits for the --set-bit option:
|
||||
kvm: Indicate that system is a KVM host
|
||||
|
||||
The maximum length for system type, system name, and sysplex name is 8
|
||||
characters. The allowed characters are: [A-Z0-9 @#$]
|
||||
|
||||
This tool should be called as root.
|
||||
EndHelp
|
||||
exit $EXIT_SUCCESS
|
||||
}
|
||||
|
||||
print_version_and_exit()
|
||||
{
|
||||
cat <<EndVersion
|
||||
$PRG: Configure the CPI settings version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2017
|
||||
EndVersion
|
||||
exit $EXIT_SUCCESS
|
||||
}
|
||||
|
||||
cpi_show()
|
||||
{
|
||||
cat <<-EndShow
|
||||
System type: $(cat "$SYSTEM_TYPE_PATH")
|
||||
System level: $(cat "$SYSTEM_LEVEL_PATH")
|
||||
System name: $(cat "$SYSTEM_NAME_PATH")
|
||||
Sysplex name: $(cat "$SYSPLEX_NAME_PATH")
|
||||
EndShow
|
||||
}
|
||||
|
||||
print_parse_error_and_exit()
|
||||
{
|
||||
echo "Try '$PRG --help' for more information." >&2
|
||||
exit $EXIT_FAILURE
|
||||
}
|
||||
|
||||
fail_with()
|
||||
{
|
||||
echo "$1" >&2
|
||||
echo "Try '$PRG --help' for more information." >&2
|
||||
exit ${2:-$EXIT_FAILURE}
|
||||
}
|
||||
|
||||
cpi_commit()
|
||||
{
|
||||
echo 1 > "$CPI_SET"
|
||||
}
|
||||
|
||||
do_length_check()
|
||||
{
|
||||
[ ${#1} -gt 8 ] &&
|
||||
fail_with "$PRG: Specified $2 too long. The maximum length is 8 characters." $EXIT_ARG_TOO_LONG
|
||||
}
|
||||
|
||||
do_character_check()
|
||||
{
|
||||
echo "$1" | grep -q -E '^[a-zA-Z0-9@#$ ]*$' ||
|
||||
fail_with "$PRG: Invalid characters in $2. Valid characters are: A-Z0-9 @#$" $EXIT_INVALID_CHARS
|
||||
}
|
||||
|
||||
cpi_set_bit()
|
||||
{
|
||||
LEVEL=$(printf '0x%x' $((LEVEL | (1 << (63 - $1)) )) )
|
||||
}
|
||||
|
||||
cpi_set_oslevel()
|
||||
{
|
||||
local kver=$(echo "${1:-$(uname -r)}" | grep -E -o '^[0-9]+[.][0-9]+[.][0-9]+')
|
||||
local maj=$((${kver%%.*} % 256))
|
||||
local min=${kver#*.}
|
||||
min=$((${min%.*} % 256))
|
||||
local rev=$((${kver##*.} % 256))
|
||||
local hexlevel=$(printf '0x%02x%02x%02x' $maj $min $rev)
|
||||
LEVEL=$(printf '0x%016x' $(((LEVEL & 0xFFFFFFFFFF000000) | hexlevel)))
|
||||
}
|
||||
|
||||
cpi_set_type()
|
||||
{
|
||||
TYPE="$1"
|
||||
do_length_check "$TYPE" "system type"
|
||||
do_character_check "$TYPE" "system type"
|
||||
}
|
||||
|
||||
cpi_set_sysplex()
|
||||
{
|
||||
SYSPLEX="$1"
|
||||
do_length_check "$SYSPLEX" "sysplex name"
|
||||
do_character_check "$SYSPLEX" "sysplex name"
|
||||
}
|
||||
|
||||
cpi_set_name()
|
||||
{
|
||||
NAME="$1"
|
||||
do_length_check "$NAME" "system name"
|
||||
do_character_check "$NAME" "system name"
|
||||
}
|
||||
|
||||
# cpictl starts here
|
||||
|
||||
if [ $# -le 0 ]; then
|
||||
echo "$PRG: No parameters specified"
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
opts=$(getopt -o b:ehL:N:S:T:v -l set-bit:,environment,help,level:,name:,sysplex:,type:,commit,dry-run,show,version -n $PRG -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
print_parse_error_and_exit
|
||||
fi
|
||||
|
||||
# This guarantees that only one instance will be running, and will serialize
|
||||
# the execution of multiple instances
|
||||
[ -e "$CPI_LOCK" -a ! -w "$CPI_LOCK" ] &&
|
||||
fail_with "$PRG: Cannot access lock file: $CPI_LOCK"
|
||||
[ ! -w "${CPI_LOCK%/*}" ] &&
|
||||
fail_with "$PRG: Cannot access lock file: $CPI_LOCK"
|
||||
|
||||
exec 9<> "$CPI_LOCK"
|
||||
flock -x 9
|
||||
|
||||
# Get current values from sys/firmware
|
||||
read LEVEL < "$SYSTEM_LEVEL_PATH"
|
||||
read TYPE < "$SYSTEM_TYPE_PATH"
|
||||
read NAME < "$SYSTEM_NAME_PATH"
|
||||
read SYSPLEX < "$SYSPLEX_NAME_PATH"
|
||||
|
||||
# Parse command line options: Use eval to remove getopt quotes
|
||||
eval set -- $opts
|
||||
while [ -n $1 ]; do
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
print_help_and_exit
|
||||
;;
|
||||
--version|-v)
|
||||
print_version_and_exit
|
||||
;;
|
||||
-b|--set-bit)
|
||||
case "$2" in
|
||||
kvm)
|
||||
cpi_set_bit 0
|
||||
;;
|
||||
*)
|
||||
fail_with "$PRG: Unknown bit \"$2\" for the $1 option"
|
||||
;;
|
||||
esac
|
||||
shift 2
|
||||
;;
|
||||
-L|--level)
|
||||
cpi_set_oslevel "$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--environment)
|
||||
cpi_set_type "$CPI_SYSTEM_TYPE"
|
||||
cpi_set_name "$CPI_SYSTEM_NAME"
|
||||
cpi_set_oslevel "$CPI_SYSTEM_LEVEL"
|
||||
cpi_set_sysplex "$CPI_SYSPLEX_NAME"
|
||||
shift
|
||||
;;
|
||||
-T|--type)
|
||||
cpi_set_type "$2"
|
||||
shift 2
|
||||
;;
|
||||
-S|--sysplex)
|
||||
cpi_set_sysplex "$2"
|
||||
shift 2
|
||||
;;
|
||||
-N|--name)
|
||||
cpi_set_name "$2"
|
||||
shift 2
|
||||
;;
|
||||
--show)
|
||||
cpi_show
|
||||
exit $EXIT_SUCCESS
|
||||
;;
|
||||
--commit)
|
||||
cpi_commit
|
||||
exit $EXIT_SUCCESS
|
||||
;;
|
||||
--dry-run)
|
||||
DRYRUN=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Print settings for --dry-run or commit them to sysfs otherwise
|
||||
|
||||
if [ $DRYRUN -eq 1 ]; then
|
||||
cat <<-EndDryrun
|
||||
System type: $TYPE
|
||||
System level: $LEVEL
|
||||
System name: $NAME
|
||||
Sysplex name: $SYSPLEX
|
||||
EndDryrun
|
||||
else
|
||||
echo "$LEVEL" > "$SYSTEM_LEVEL_PATH"
|
||||
echo "$TYPE" > "$SYSTEM_TYPE_PATH"
|
||||
echo "$NAME" > "$SYSTEM_NAME_PATH"
|
||||
echo "$SYSPLEX" > "$SYSPLEX_NAME_PATH"
|
||||
cpi_commit
|
||||
fi
|
||||
|
||||
exit $EXIT_SUCCESS
|
||||
@@ -35,12 +35,6 @@ EnvironmentFile=/etc/sysconfig/cpi
|
||||
# Environment=CPI_SYSTEM_LEVEL=
|
||||
# Environment=CPI_SYSTEM_TYPE=LINUX
|
||||
|
||||
#
|
||||
# Apply settings
|
||||
ExecStartPre=/bin/sh -c 'if test -n "$CPI_SYSTEM_TYPE"; then echo $CPI_SYSTEM_TYPE |tr a-z A-Z > /sys/firmware/cpi/system_type; fi'
|
||||
ExecStartPre=/bin/sh -c 'if test -n "$CPI_SYSTEM_NAME"; then echo $CPI_SYSTEM_NAME |tr a-z A-Z > /sys/firmware/cpi/system_name; fi'
|
||||
ExecStartPre=/bin/sh -c 'if test -n "$CPI_SYSPLEX_NAME"; then echo $CPI_SYSPLEX_NAME |tr a-z A-Z > /sys/firmware/cpi/sysplex_name; fi'
|
||||
ExecStartPre=/bin/sh -c 'test -n "$CPI_SYSTEM_LEVEL" || CPI_SYSTEM_LEVEL="$(uname -r)" ; echo $CPI_SYSTEM_LEVEL |cut -d- -f1 | tr . " " |xargs printf "0x0000000000%02x%02x%02x\n" > /sys/firmware/cpi/system_level'
|
||||
#
|
||||
# Sending data to the HMC/SE
|
||||
ExecStart=/bin/sh -c 'echo 1 > /sys/firmware/cpi/set'
|
||||
ExecStart=@toolslib_path@/cpictl -e
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[Unit]
|
||||
Description=TTYRun on %I
|
||||
Documentation=man:ttyrun(8) man:agetty(8)
|
||||
BindTo=dev-%i.device
|
||||
BindsTo=dev-%i.device
|
||||
After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
|
||||
After=rc-local.service
|
||||
Before=getty.target
|
||||
|
||||
@@ -41,8 +41,7 @@
|
||||
#define UUID_FORMAT "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$"
|
||||
|
||||
/* Misc constants */
|
||||
#define MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES 37
|
||||
#define MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES 16
|
||||
#define MAX_BUF_SIZE 256
|
||||
#define PREFIX_ID_LENGTH 4
|
||||
#define SHORT_ID_LENGTH 4
|
||||
#define CHPIDS_SEGMENT_LENGTH 8
|
||||
@@ -310,8 +309,8 @@ static bool in_devtypes_list(char *dtype)
|
||||
*/
|
||||
static int fill_device_info(struct util_rec *rec, char *path, char *device)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
unsigned long int val_ul;
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
if (!path || !device) {
|
||||
if (cmd.opt_devtype && cmd.dev_count > 0)
|
||||
@@ -403,7 +402,7 @@ static bool is_sch_vfio(char *path)
|
||||
*/
|
||||
static int fill_vfio_devid(struct util_rec *rec, char *path)
|
||||
{
|
||||
char *device, buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
|
||||
char *device, buf[MAX_BUF_SIZE];
|
||||
struct dirent **de_vec;
|
||||
int count;
|
||||
|
||||
@@ -433,7 +432,7 @@ static int fill_vfio_devid(struct util_rec *rec, char *path)
|
||||
*/
|
||||
static int fill_io_devid(struct util_rec *rec, char *path)
|
||||
{
|
||||
char *device, buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
|
||||
char *device, buf[MAX_BUF_SIZE];
|
||||
struct dirent **de_vec;
|
||||
int count;
|
||||
|
||||
@@ -479,8 +478,8 @@ static int fill_io_devid(struct util_rec *rec, char *path)
|
||||
*/
|
||||
static void print_sch_io(struct util_rec *rec, char *path, char *sch_dir)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
|
||||
unsigned int pim, pam, pom;
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
/* Fill in subchannel ID */
|
||||
if (cmd.opt_short) {
|
||||
@@ -560,7 +559,7 @@ static void print_sch_io(struct util_rec *rec, char *path, char *sch_dir)
|
||||
*/
|
||||
static void print_sch_chsc(struct util_rec *rec, char *sch_dir)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
/* Skip entry if devrange or devtype option is active */
|
||||
if (cmd.opt_devrange && cmd.rng_count > 0)
|
||||
@@ -596,7 +595,7 @@ static void print_sch_chsc(struct util_rec *rec, char *sch_dir)
|
||||
*/
|
||||
static void print_sch_eadm(struct util_rec *rec, char *sch_dir)
|
||||
{
|
||||
char buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
char buf[MAX_BUF_SIZE];
|
||||
|
||||
/* Skip entry if devrange or devtype option is active */
|
||||
if (cmd.opt_devrange && cmd.rng_count > 0)
|
||||
@@ -632,7 +631,7 @@ static void print_sch_eadm(struct util_rec *rec, char *sch_dir)
|
||||
*/
|
||||
static void print_defunct_devices(struct util_rec *rec, char *path)
|
||||
{
|
||||
char *device, buf[MAX_BUFFER_SIZE_FOR_DEVICE_ATTRIBUTES];
|
||||
char *device, buf[MAX_BUF_SIZE];
|
||||
struct dirent **de_vec;
|
||||
int i, count;
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ function debug() {
|
||||
function search_cu_tcpip() {
|
||||
local scu=$1
|
||||
local i
|
||||
for ((i=0; i < ${#CU_TCPIP[@]}; i++)); do
|
||||
if [ "$scu" == "${CU_TCPIP[i]}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -547,6 +547,22 @@ static void setup_rec_long(struct util_rec *rec)
|
||||
util_rec_def(rec, "ipa", UTIL_REC_ALIGN_LEFT, 0, "ipa");
|
||||
util_rec_def(rec, "vipa", UTIL_REC_ALIGN_LEFT, 0, "vipa");
|
||||
util_rec_def(rec, "parp", UTIL_REC_ALIGN_LEFT, 0, "parp");
|
||||
util_rec_def(rec, "vnicc/bridge_invisible", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/bridge_invisible");
|
||||
util_rec_def(rec, "vnicc/flooding", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/flooding");
|
||||
util_rec_def(rec, "vnicc/learning", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/learning");
|
||||
util_rec_def(rec, "vnicc/learning_timeout", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/learning_timeout");
|
||||
util_rec_def(rec, "vnicc/mcast_flooding", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/mcast_flooding");
|
||||
util_rec_def(rec, "vnicc/rx_bcast", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/rx_bcast");
|
||||
util_rec_def(rec, "vnicc/takeover_learning", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/takeover_learning");
|
||||
util_rec_def(rec, "vnicc/takeover_setvmac", UTIL_REC_ALIGN_LEFT, 0,
|
||||
"vnicc/takeover_setvmac");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -560,7 +576,7 @@ static struct util_rec *setup_rec()
|
||||
rec = util_rec_new_wide("-");
|
||||
setup_rec_wide(rec);
|
||||
} else {
|
||||
rec = util_rec_new_long("-", ":", "if_name", 30, 42);
|
||||
rec = util_rec_new_long("-", ":", "if_name", 32, 40);
|
||||
setup_rec_long(rec);
|
||||
}
|
||||
return rec;
|
||||
|
||||
@@ -286,7 +286,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
const char *online, *online_text = NULL, *poll_thread, *config_time;
|
||||
const char *poll_timeout, *default_domain;
|
||||
char *path, *dev_path, *dev, *dev_list, device[256], online_read[2];
|
||||
char *path, *dev_path, *dev, *dev_list, device[256], online_read[32];
|
||||
bool all = false, actionset = false;
|
||||
size_t len;
|
||||
int id, dom, c, i, j;
|
||||
@@ -406,12 +406,14 @@ int main(int argc, char *argv[])
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
||||
if (!util_path_is_writable("%s/online", dev_path))
|
||||
continue;
|
||||
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n Wrong permissions"
|
||||
" or wrong tools version.", dev_path);
|
||||
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
||||
util_file_write_s(online, "%s/online", dev_path);
|
||||
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
||||
if (strcmp(online, online_read) != 0)
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.", device, online_text);
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||
device, online_text);
|
||||
free(dev_path);
|
||||
}
|
||||
free(dev_list);
|
||||
|
||||
@@ -18,12 +18,12 @@ lszcrypt \- display zcrypt device and configuration information
|
||||
.B lszcrypt
|
||||
.RB "[ " -V " ] "
|
||||
[
|
||||
.I <device id>
|
||||
.I <device-id>
|
||||
[...]]
|
||||
.TP
|
||||
.B lszcrypt
|
||||
.B -c
|
||||
<device id>
|
||||
<card-id>
|
||||
.TP
|
||||
.B lszcrypt -b
|
||||
.TP
|
||||
@@ -57,18 +57,17 @@ 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.
|
||||
.TP 8
|
||||
.B <device id>
|
||||
.B <device-id>
|
||||
Specifies a cryptographic device to display. A cryptographic device can be
|
||||
either a card device or a queue device. If no devices are specified information
|
||||
about all available devices is displayed.
|
||||
|
||||
Please note that the card device representation and the queue device are both
|
||||
in hexadecimal notation.
|
||||
Please note that the card device representation and the queue device
|
||||
are both in hexadecimal notation.
|
||||
.TP 8
|
||||
.B -b, --bus
|
||||
Displays the AP bus attributes and exits.
|
||||
.TP 8
|
||||
.B -c, --capability <card device id>
|
||||
.B -c, --capability <card-id>
|
||||
Shows the capabilities of a cryptographic card device of hardware type 6 or
|
||||
higher. The card device id value may be given as decimal or hex value (with
|
||||
a leading 0x). The capabilities of a cryptographic card device depend on
|
||||
@@ -92,12 +91,12 @@ Shows the usage and control domains of the cryptographic devices.
|
||||
The displayed domains of the cryptographic device depends on the initial
|
||||
cryptographic configuration.
|
||||
.RS
|
||||
.IP "o" 2
|
||||
'C' indicate a control domain
|
||||
.IP "o" 3
|
||||
C - indicate a control domain
|
||||
.IP "o"
|
||||
'U' indicate a usage domain
|
||||
U - indicate a usage domain
|
||||
.IP "o"
|
||||
'B' indicate both (control and usage domain)
|
||||
B - indicate both (control and usage domain)
|
||||
.RE
|
||||
.TP 8
|
||||
.B -h, --help
|
||||
|
||||
@@ -168,7 +168,7 @@ static void show_domains_util_rec(char *domain_array[])
|
||||
*/
|
||||
static void show_domains(void)
|
||||
{
|
||||
char ctrl_domain_mask[67], usag_domain_mask[67], byte_str[3] = {};
|
||||
char ctrl_domain_mask[80], usag_domain_mask[80], byte_str[3] = {};
|
||||
int ctrl_chunk, usag_chunk;
|
||||
char *ap, *domain_array[32 * 8 + 4];
|
||||
int i, x, n;
|
||||
@@ -181,8 +181,12 @@ static void show_domains(void)
|
||||
|
||||
util_file_read_line(ctrl_domain_mask, sizeof(ctrl_domain_mask),
|
||||
"%s/ap_control_domain_mask", ap);
|
||||
if (strstr(ctrl_domain_mask, "not"))
|
||||
errx(EXIT_FAILURE, "Control domain mask not available.");
|
||||
util_file_read_line(usag_domain_mask, sizeof(usag_domain_mask),
|
||||
"%s/ap_usage_domain_mask", ap);
|
||||
if (strstr(usag_domain_mask, "not"))
|
||||
errx(EXIT_FAILURE, "Usage domain mask not available.");
|
||||
/* remove leading '0x' from domain mask string */
|
||||
memmove(&ctrl_domain_mask[0], &ctrl_domain_mask[2],
|
||||
sizeof(ctrl_domain_mask) - 2);
|
||||
@@ -222,7 +226,7 @@ static void show_capability(const char *id_str)
|
||||
{
|
||||
unsigned long func_val;
|
||||
long hwtype, id;
|
||||
char *p, *ap, *dev, card[7];
|
||||
char *p, *ap, *dev, card[16];
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
@@ -450,7 +454,7 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
*/
|
||||
static void show_device(struct util_rec *rec, const char *device)
|
||||
{
|
||||
char *grp_dev, card[3];
|
||||
char *grp_dev, card[16];
|
||||
|
||||
util_rec_set(rec, "card", card);
|
||||
|
||||
@@ -540,7 +544,7 @@ static void show_devices_argv(char *argv[])
|
||||
{
|
||||
struct util_rec *rec = util_rec_new_wide("-");
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
char *ap, *grp_dev, *path, card[7], sub_dev[7];
|
||||
char *ap, *grp_dev, *path, card[16], sub_dev[16];
|
||||
int id, dom, i, n, dev_cnt, sub_cnt;
|
||||
|
||||
/* check if ap driver is available */
|
||||
|
||||
@@ -35,7 +35,7 @@ installkernel() {
|
||||
}
|
||||
|
||||
install() {
|
||||
local _tempfile=$(mktemp dracut-zdev.XXXX)
|
||||
local _tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
|
||||
if chzdev --export - --persistent --by-path / >/dev/null 2>&1 ; then
|
||||
# Use persistent configuration
|
||||
|
||||
306
zdev/src/qeth.c
306
zdev/src/qeth.c
@@ -258,11 +258,17 @@ struct qeth_attrib_data {
|
||||
layer_2,
|
||||
layer_3
|
||||
} layer_type;
|
||||
enum qeth_attr_group_type {
|
||||
group_none,
|
||||
group_bridge,
|
||||
group_vnicc
|
||||
} attr_group;
|
||||
};
|
||||
|
||||
#define QETH_DATA(layer) \
|
||||
#define QETH_DATA(layer, group) \
|
||||
((struct qeth_attrib_data []) { { \
|
||||
.layer_type = layer, \
|
||||
.attr_group = group, \
|
||||
} })
|
||||
|
||||
/*
|
||||
@@ -304,7 +310,7 @@ static struct attrib qeth_attr_portname = {
|
||||
.order_cmp = ccw_offline_only_order_cmp,
|
||||
.check = ccw_offline_only_check,
|
||||
.map = VALUE_MAP_ARRAY(VALUE_MAP("no portname required", "")),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_priority_queueing = {
|
||||
@@ -335,7 +341,7 @@ static struct attrib qeth_attr_priority_queueing = {
|
||||
ACCEPT_STR("no_prio_queueing:3")
|
||||
),
|
||||
.unstable = 1,
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_buffer_count = {
|
||||
@@ -348,7 +354,7 @@ static struct attrib qeth_attr_buffer_count = {
|
||||
.order_cmp = ccw_offline_only_order_cmp,
|
||||
.check = ccw_offline_only_check,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(8, 128)),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_portno = {
|
||||
@@ -360,7 +366,7 @@ static struct attrib qeth_attr_portno = {
|
||||
.order_cmp = ccw_offline_only_order_cmp,
|
||||
.check = ccw_offline_only_check,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_hsuid = {
|
||||
@@ -370,7 +376,7 @@ static struct attrib qeth_attr_hsuid = {
|
||||
"Specify a 1-8 character identifier used to identify a HiperSockets\n"
|
||||
"QETH device in the AF_IUCV addressing family support.\n",
|
||||
.defval = "",
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_recover = {
|
||||
@@ -386,7 +392,7 @@ static struct attrib qeth_attr_recover = {
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_NUM(1)),
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_isolation = {
|
||||
@@ -401,7 +407,7 @@ static struct attrib qeth_attr_isolation = {
|
||||
.defval = "none",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("none"), ACCEPT_STR("drop"),
|
||||
ACCEPT_STR("forward")),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_performance_stats = {
|
||||
@@ -413,7 +419,7 @@ static struct attrib qeth_attr_performance_stats = {
|
||||
" 1: Performance statistics data is collected\n",
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_hw_trap = {
|
||||
@@ -428,7 +434,7 @@ static struct attrib qeth_attr_hw_trap = {
|
||||
.defval = "disarm",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("disarm"), ACCEPT_STR("arm"),
|
||||
ACCEPT_STR("trap")),
|
||||
.st_data = QETH_DATA(layer_any),
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_route4 = {
|
||||
@@ -464,7 +470,7 @@ static struct attrib qeth_attr_route4 = {
|
||||
"secondary_connector"),
|
||||
VALUE_MAP("secondary connector",
|
||||
"secondary_connector")),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_route6 = {
|
||||
@@ -501,7 +507,7 @@ static struct attrib qeth_attr_route6 = {
|
||||
VALUE_MAP("secondary connector",
|
||||
"secondary_connector")),
|
||||
.unstable = 1,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_fake_broadcast = {
|
||||
@@ -515,7 +521,7 @@ static struct attrib qeth_attr_fake_broadcast = {
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_enable = {
|
||||
@@ -529,7 +535,7 @@ static struct attrib qeth_attr_ipa_takeover_enable = {
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_add4 = {
|
||||
@@ -544,7 +550,7 @@ static struct attrib qeth_attr_ipa_takeover_add4 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_add6 = {
|
||||
@@ -559,7 +565,7 @@ static struct attrib qeth_attr_ipa_takeover_add6 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_del4 = {
|
||||
@@ -573,7 +579,7 @@ static struct attrib qeth_attr_ipa_takeover_del4 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_del6 = {
|
||||
@@ -586,7 +592,7 @@ static struct attrib qeth_attr_ipa_takeover_del6 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_invert4 = {
|
||||
@@ -601,7 +607,7 @@ static struct attrib qeth_attr_ipa_takeover_invert4 = {
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_ipa_takeover_invert6 = {
|
||||
@@ -616,7 +622,7 @@ static struct attrib qeth_attr_ipa_takeover_invert6 = {
|
||||
.defval = "0",
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_add4 = {
|
||||
@@ -629,20 +635,20 @@ static struct attrib qeth_attr_rxip_add4 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_add6 = {
|
||||
.name = "rxip/add6",
|
||||
.title = "Add IPv6 address to ARP proxy list",
|
||||
.title = "Add IPv6 address to NDP proxy list",
|
||||
.desc =
|
||||
"Write an IPv6 address to this attribute to add it to the list of\n"
|
||||
"addresses for which this QETH device should act as ARP proxy.\n",
|
||||
"addresses for which this QETH device should act as NDP proxy.\n",
|
||||
.defval = "",
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_del4 = {
|
||||
@@ -654,19 +660,19 @@ static struct attrib qeth_attr_rxip_del4 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_rxip_del6 = {
|
||||
.name = "rxip/del6",
|
||||
.title = "Remove IPv6 address from ARP proxy list",
|
||||
.title = "Remove IPv6 address from NDP proxy list",
|
||||
.desc =
|
||||
"Write an IPv6 address to this attribute to remove it from the list\n"
|
||||
"of addresses for which this QETH device acts as an ARP proxy.\n",
|
||||
"of addresses for which this QETH device acts as an NDP proxy.\n",
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_sniffer = {
|
||||
@@ -679,7 +685,7 @@ static struct attrib qeth_attr_sniffer = {
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_add4 = {
|
||||
@@ -692,7 +698,7 @@ static struct attrib qeth_attr_vipa_add4 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_add6 = {
|
||||
@@ -705,7 +711,7 @@ static struct attrib qeth_attr_vipa_add6 = {
|
||||
.multi = 1,
|
||||
.activerem = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_del4 = {
|
||||
@@ -717,7 +723,7 @@ static struct attrib qeth_attr_vipa_del4 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vipa_del6 = {
|
||||
@@ -729,7 +735,7 @@ static struct attrib qeth_attr_vipa_del6 = {
|
||||
.writeonly = 1,
|
||||
.activeonly = 1,
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.st_data = QETH_DATA(layer_3),
|
||||
.st_data = QETH_DATA(layer_3, group_none),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_bridge_role = {
|
||||
@@ -739,13 +745,16 @@ static struct attrib qeth_attr_bridge_role = {
|
||||
"Configure a QETH device as a bridge port:\n"
|
||||
" primary: The device acts as the primary bridge port\n"
|
||||
" secondary: The device acts as a secondary bridge port\n"
|
||||
" none: The device has no bridge port role\n",
|
||||
" none: The device has no bridge port role\n"
|
||||
" n/a (VNIC characteristics):\n"
|
||||
" The device is configured with VNIC characteristics\n"
|
||||
" and cannot have a bridge role (read-only)\n",
|
||||
.defval = "none",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("primary"),
|
||||
ACCEPT_STR("secondary"),
|
||||
ACCEPT_STR("none")),
|
||||
.st_data = QETH_DATA(layer_2),
|
||||
.st_data = QETH_DATA(layer_2, group_bridge),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_bridge_hostnotify = {
|
||||
@@ -755,11 +764,14 @@ static struct attrib qeth_attr_bridge_hostnotify = {
|
||||
"Control whether host connection and disconnection events are\n"
|
||||
"reported through kernel uevents:\n"
|
||||
" 0: Notifications are disabled\n"
|
||||
" 1: Notifications are enabled\n",
|
||||
" 1: Notifications are enabled\n"
|
||||
" n/a (VNIC characteristics):\n"
|
||||
" The device is configured with VNIC characteristics\n"
|
||||
" and cannot have a bridge role (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2),
|
||||
.st_data = QETH_DATA(layer_2, group_bridge),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_bridge_reflect_promisc = {
|
||||
@@ -773,13 +785,159 @@ static struct attrib qeth_attr_bridge_reflect_promisc = {
|
||||
" primary: Attempt to configure the device as the primary bridge\n"
|
||||
" port\n"
|
||||
" secondary: Attempt to configure the device as a secondary bridge\n"
|
||||
" port\n",
|
||||
" port\n"
|
||||
" n/a (VNIC characteristics):\n"
|
||||
" The device is configured with VNIC characteristics\n"
|
||||
" and cannot have a bridge role (read-only)\n",
|
||||
.defval = "none",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_STR("primary"),
|
||||
ACCEPT_STR("secondary"),
|
||||
ACCEPT_STR("none")),
|
||||
.st_data = QETH_DATA(layer_2),
|
||||
.st_data = QETH_DATA(layer_2, group_bridge),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_flooding = {
|
||||
.name = "vnicc/flooding",
|
||||
.title = "Control setting of VNICC flooding",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic flooding\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Flooding disabled\n"
|
||||
" 1: Flooding enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_mcast_flooding = {
|
||||
.name = "vnicc/mcast_flooding",
|
||||
.title = "Control setting of VNICC multicast flooding",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic multicast flooding\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Multicast flooding disabled\n"
|
||||
" 1: Multicast flooding enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_learning = {
|
||||
.name = "vnicc/learning",
|
||||
.title = "Control setting of VNICC learning",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic learning\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Learning disabled\n"
|
||||
" 1: Learning enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_learning_timeout = {
|
||||
.name = "vnicc/learning_timeout",
|
||||
.title = "Control setting of the VNICC learning timeout",
|
||||
.desc =
|
||||
"Control and show the timeout of the VNIC characteristic learning\n"
|
||||
"on the networking device:\n"
|
||||
" <N>: Timeout in seconds\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "600",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(60, 86400)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_takeover_setvmac = {
|
||||
.name = "vnicc/takeover_setvmac",
|
||||
.title = "Control setting of VNICC takeover SETVMAC",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic takeover SETVMAC\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Takeover SETVMAC disabled\n"
|
||||
" 1: Takeover SETVMAC enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_takeover_learning = {
|
||||
.name = "vnicc/takeover_learning",
|
||||
.title = "Control setting of VNICC takeover learning",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic takeover learning\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Takeover learning disabled\n"
|
||||
" 1: Takeover learning enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_bridge_invisible = {
|
||||
.name = "vnicc/bridge_invisible",
|
||||
.title = "Control setting of VNICC bridge invisible",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic bridge invisible\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Bridge invisible disabled\n"
|
||||
" 1: Bridge invisible enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "0",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
static struct attrib qeth_attr_vnicc_rx_bcast = {
|
||||
.name = "vnicc/rx_bcast",
|
||||
.title = "Control setting of VNICC receive broadcast",
|
||||
.desc =
|
||||
"Control and show the VNIC characteristic receive broadcast\n"
|
||||
"on the networking device:\n"
|
||||
" 0: Receive broadcast disabled\n"
|
||||
" 1: Receive broadcast enabled\n"
|
||||
" n/a: Information unavailable (read-only)\n"
|
||||
" n/a (BridgePort):\n"
|
||||
" The device is part of a Linux bridge and cannot be\n"
|
||||
" configured with VNIC characteristics (read-only)\n",
|
||||
.defval = "1",
|
||||
.order_cmp = after_layer2_order_cmp,
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.st_data = QETH_DATA(layer_2, group_vnicc),
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -913,7 +1071,11 @@ static exit_code_t setting_ineffective(struct setting *s, int layer2)
|
||||
|
||||
static enum qeth_layer_type get_layer_type(struct setting *s)
|
||||
{
|
||||
struct qeth_attrib_data *data = s->attrib->st_data;
|
||||
struct qeth_attrib_data *data;
|
||||
|
||||
if (!s->attrib)
|
||||
return layer_any;
|
||||
data = s->attrib->st_data;
|
||||
|
||||
if (!data)
|
||||
return layer_any;
|
||||
@@ -921,6 +1083,20 @@ static enum qeth_layer_type get_layer_type(struct setting *s)
|
||||
return data->layer_type;
|
||||
}
|
||||
|
||||
static enum qeth_attr_group_type get_attr_group_type(struct setting *s)
|
||||
{
|
||||
struct qeth_attrib_data *data;
|
||||
|
||||
if (!s->attrib)
|
||||
return group_none;
|
||||
data = s->attrib->st_data;
|
||||
|
||||
if (!data)
|
||||
return group_none;
|
||||
else
|
||||
return data->attr_group;
|
||||
}
|
||||
|
||||
static void add_layer2_setting(struct setting_list *list, int layer2)
|
||||
{
|
||||
setting_list_apply(list, &qeth_attr_layer2,
|
||||
@@ -994,6 +1170,38 @@ static exit_code_t check_ineffective_settings(struct setting_list *list,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Check if there are conflicting attribute settings */
|
||||
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||
{
|
||||
const char *text = "Settings %s and %s are in conflict\n";
|
||||
struct setting *bridge = NULL, *vnicc = NULL;
|
||||
enum qeth_attr_group_type t;
|
||||
struct setting *s;
|
||||
|
||||
util_list_iterate(&list->list, s) {
|
||||
if (s->removed)
|
||||
continue;
|
||||
t = get_attr_group_type(s);
|
||||
if (t == group_bridge && (!bridge || !bridge->specified))
|
||||
bridge = s;
|
||||
if (t == group_vnicc && (!vnicc || !vnicc->specified))
|
||||
vnicc = s;
|
||||
}
|
||||
|
||||
/* BridgePort and VNICC cannot both be configured at the same time */
|
||||
if (bridge && vnicc && (bridge->specified || vnicc->specified)) {
|
||||
if (force) {
|
||||
delayed_warn(text, bridge->attrib->name,
|
||||
vnicc->attrib->name);
|
||||
return EXIT_OK;
|
||||
}
|
||||
delayed_forceable(text, bridge->attrib->name,
|
||||
vnicc->attrib->name);
|
||||
return EXIT_INVALID_CONFIG;
|
||||
}
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
/* Check if layer2 setting can be correctly applied. */
|
||||
static exit_code_t check_layer2(struct device *dev, config_t config)
|
||||
{
|
||||
@@ -1045,7 +1253,17 @@ static exit_code_t check_layer2(struct device *dev, config_t config)
|
||||
if (SCOPE_PERSISTENT(config)) {
|
||||
rc = check_ineffective_settings(dev->persistent.settings,
|
||||
layer2_persistent);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
/* check for conflicting layer2 attribute groups */
|
||||
if (SCOPE_ACTIVE(config)) {
|
||||
rc = check_conflicting_settings(dev->active.settings);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
if (SCOPE_PERSISTENT(config))
|
||||
rc = check_conflicting_settings(dev->persistent.settings);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
@@ -1195,6 +1413,14 @@ static struct subtype qeth_subtype_qeth = {
|
||||
&qeth_attr_bridge_role,
|
||||
&qeth_attr_bridge_hostnotify,
|
||||
&qeth_attr_bridge_reflect_promisc,
|
||||
&qeth_attr_vnicc_flooding,
|
||||
&qeth_attr_vnicc_mcast_flooding,
|
||||
&qeth_attr_vnicc_learning,
|
||||
&qeth_attr_vnicc_learning_timeout,
|
||||
&qeth_attr_vnicc_takeover_setvmac,
|
||||
&qeth_attr_vnicc_takeover_learning,
|
||||
&qeth_attr_vnicc_bridge_invisible,
|
||||
&qeth_attr_vnicc_rx_bcast,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
.support_definable = 1,
|
||||
|
||||
@@ -81,7 +81,7 @@ struct vol {
|
||||
u64 part_size;
|
||||
u64 mem_start;
|
||||
u64 mem_end;
|
||||
char bus_id[9];
|
||||
char bus_id[10];
|
||||
u32 nr;
|
||||
u16 blk_size;
|
||||
struct df_s390_dumper dumper;
|
||||
|
||||
@@ -75,7 +75,7 @@ static void init_defaults(void)
|
||||
/*
|
||||
* Print "help" hint
|
||||
*/
|
||||
static void print_usage_exit(void)
|
||||
static void __noreturn print_usage_exit(void)
|
||||
{
|
||||
STDERR("Try '%s --help' for more information.\n", g.prog_name);
|
||||
zg_exit(1);
|
||||
@@ -84,7 +84,7 @@ static void print_usage_exit(void)
|
||||
/*
|
||||
* Print help text
|
||||
*/
|
||||
static void print_help_exit(void)
|
||||
static void __noreturn print_help_exit(void)
|
||||
{
|
||||
STDOUT("%s", help_text);
|
||||
zg_exit(0);
|
||||
@@ -93,7 +93,7 @@ static void print_help_exit(void)
|
||||
/*
|
||||
* Print version information
|
||||
*/
|
||||
static void print_version_exit(void)
|
||||
static void __noreturn print_version_exit(void)
|
||||
{
|
||||
STDOUT("%s: Tool for copying and converting dumps version %s\n",
|
||||
g.prog_name, RELEASE_STRING);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
include ../common.mak
|
||||
|
||||
CPPFLAGS += -I../include
|
||||
LDFLAGS += -ldl
|
||||
LDLIBS += -ldl
|
||||
|
||||
all: zkey
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ master key in the \fBNEW\fP register.
|
||||
If both options are omitted, \fBzkey\fP automatically detects whether the
|
||||
secure 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 i\fBOLD\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.
|
||||
@@ -137,7 +137,7 @@ to be installed.
|
||||
.SH OPTIONS
|
||||
.SS "Options for the generate command"
|
||||
.TP
|
||||
.BR \-k ", " \-\-keybits \fIsize\fP
|
||||
.BR \-k ", " \-\-keybits\~\fIsize\fP
|
||||
Specifies the size of the AES key to be generated in bits.
|
||||
Valid sizes are 128, 192, and 256 bits. Secure keys for use with the
|
||||
XTS cipher mode can only use keys of 128 or 256 bits.
|
||||
@@ -147,7 +147,7 @@ The default is 256 bits.
|
||||
Generates a secure AES key for the XTS cipher mode. A secure AES key for
|
||||
the XTS cipher mode consist of two concatenated secure keys.
|
||||
.TP
|
||||
.BR \-c ", " \-\-clearkey \fIclear\-key\-file\fP
|
||||
.BR \-c ", " \-\-clearkey\~\fIclear\-key\-file\fP
|
||||
Specifies a file path that contains the clear AES key in binary form.
|
||||
If option \fB\-\-keybits\fP is omitted, the size of the specified file
|
||||
determines the size of the AES key. If option \fB\-\-keybits\fP
|
||||
@@ -165,7 +165,7 @@ master key in the CURRENT register with the master key in the NEW register.
|
||||
Re-enciphers a secure AES key that is currently enciphered with the
|
||||
master key in the OLD register with the master key in the CURRENT register.
|
||||
.TP
|
||||
.BR \-f ", " \-\-output \fIoutput\-file\fP
|
||||
.BR \-f ", " \-\-output\~\fIoutput\-file\fP
|
||||
Specifies the name of the output file to which the re-enciphered secure key
|
||||
is written. If this option is omitted, the re-enciphered secure key
|
||||
is replaced in the file that currently contains the secure key.
|
||||
|
||||
33
zkey/zkey.c
33
zkey/zkey.c
@@ -138,7 +138,7 @@ static struct util_opt opt_vec[] = {
|
||||
*/
|
||||
struct zkey_command {
|
||||
char *command;
|
||||
unsigned int abrev_len;
|
||||
unsigned int abbrev_len;
|
||||
int (*function)(const char *keyfile);
|
||||
int need_cca_library;
|
||||
int need_pkey_device;
|
||||
@@ -154,7 +154,7 @@ static int command_validate(const char *keyfile);
|
||||
static struct zkey_command zkey_commands[] = {
|
||||
{
|
||||
.command = COMMAND_GENERATE,
|
||||
.abrev_len = 3,
|
||||
.abbrev_len = 3,
|
||||
.function = command_generate,
|
||||
.need_pkey_device = 1,
|
||||
.short_desc = "Generate a secure AES key",
|
||||
@@ -164,7 +164,7 @@ static struct zkey_command zkey_commands[] = {
|
||||
},
|
||||
{
|
||||
.command = COMMAND_REENCIPHER,
|
||||
.abrev_len = 2,
|
||||
.abbrev_len = 2,
|
||||
.function = command_reencipher,
|
||||
.need_cca_library = 1,
|
||||
.need_pkey_device = 1,
|
||||
@@ -175,7 +175,7 @@ static struct zkey_command zkey_commands[] = {
|
||||
},
|
||||
{
|
||||
.command = COMMAND_VALIDATE,
|
||||
.abrev_len = 3,
|
||||
.abbrev_len = 3,
|
||||
.function = command_validate,
|
||||
.need_pkey_device = 1,
|
||||
.short_desc = "Validate an existing secure AES key",
|
||||
@@ -197,7 +197,7 @@ static void print_usage_command(const struct zkey_command *command)
|
||||
unsigned int i;
|
||||
|
||||
strncpy(command_str, command->command, sizeof(command_str) - 1);
|
||||
for (i = 0; i < command->abrev_len; i++)
|
||||
for (i = 0; i < command->abbrev_len; i++)
|
||||
command_str[i] = toupper(command_str[i]);
|
||||
|
||||
printf("Usage: %s %s SECURE-KEY-FILE",
|
||||
@@ -223,7 +223,7 @@ static void print_usage_command_list(void)
|
||||
printf("COMMANDS\n");
|
||||
while (cmd->command) {
|
||||
strcpy(command_str, cmd->command);
|
||||
for (i = 0; i < cmd->abrev_len; i++)
|
||||
for (i = 0; i < cmd->abbrev_len; i++)
|
||||
command_str[i] = toupper(command_str[i]);
|
||||
printf(" %s\t%s\n", command_str, cmd->short_desc);
|
||||
cmd++;
|
||||
@@ -718,7 +718,6 @@ static int key_token_change(u8 *secure_key, unsigned int secure_key_size,
|
||||
}
|
||||
|
||||
static int validate_secure_xts_key(u8 *secure_key, size_t secure_key_size,
|
||||
u16 part1_cardnr, u16 part1_domain,
|
||||
u16 part1_keysize, u32 part1_attributes,
|
||||
size_t *clear_key_bitsize)
|
||||
{
|
||||
@@ -765,18 +764,6 @@ static int validate_secure_xts_key(u8 *secure_key, size_t secure_key_size,
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (verifykey.cardnr != part1_cardnr) {
|
||||
pr_verbose("XTS secure key contains 2 keys using different "
|
||||
"cards");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (verifykey.domain != part1_domain) {
|
||||
pr_verbose("XTS secure key contains 2 keys using different "
|
||||
"domains");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (verifykey.keysize != part1_keysize) {
|
||||
pr_verbose("XTS secure key contains 2 keys using different "
|
||||
"key sizes");
|
||||
@@ -827,8 +814,6 @@ static int validate_secure_key(u8 *secure_key, size_t secure_key_size,
|
||||
/* XTS uses 2 secure key tokens concatenated to each other */
|
||||
if (secure_key_size > SECURE_KEY_SIZE) {
|
||||
rc = validate_secure_xts_key(secure_key, secure_key_size,
|
||||
verifykey.cardnr,
|
||||
verifykey.domain,
|
||||
verifykey.keysize,
|
||||
verifykey.attributes,
|
||||
clear_key_bitsize);
|
||||
@@ -974,12 +959,12 @@ static bool is_command(struct zkey_command *command, const char *str)
|
||||
|
||||
util_assert(sizeof(command_str) > strlen(command->command),
|
||||
"Buffer 'command_str' too small for %s", command->command);
|
||||
if (str_len < command->abrev_len)
|
||||
if (str_len < command->abbrev_len)
|
||||
return false;
|
||||
if (str_len > strlen(command->command))
|
||||
return false;
|
||||
strncpy(command_str, command->command, str_len);
|
||||
if (strcasecmp(str, command_str) != 0)
|
||||
if (strncasecmp(str, command_str, str_len) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1108,6 +1093,8 @@ int main(int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
umask(0077);
|
||||
|
||||
rc = command->function(keyfile);
|
||||
|
||||
out:
|
||||
|
||||
Reference in New Issue
Block a user