Compare commits

...

35 Commits

Author SHA1 Message Date
Michael Holzheu
364b4c0686 New release s390-tools-2.1.0
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-25 14:15:15 +02:00
Michael Holzheu
8818e229cc CHANGELOG: Update for 90-cpi.rules
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:57:39 +02:00
Michael Holzheu
ed18044925 Add changelog for 2.1.0
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:53:02 +02:00
Stefan Haberland
3c80f7e025 dasdinfo: fix buffer overflow warning
Fix a possible buffer overflow.
The buffer overflow is only theoretical since the device name is max
8 characters in length.

This fixes following gcc 7 warning:

 dasdinfo.c: In function 'main':
 dasdinfo.c:576:33: warning: '%s' directive writing up to 255 bytes into a
                                   region of size 69 [-Wformat-overflow=]
     sprintf(*uidfile,"/sys/block/%s/device/uid",
                                  ^~
 In file included from /usr/include/stdio.h:862:0,
                  from dasdinfo.c:15:
 /usr/include/bits/stdio2.h:33:10: note: '__builtin___sprintf_chk' output
                    between 23 and 278 bytes into a destination of size 80
    return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        __bos (__s), __fmt, __va_arg_pack ());
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:52:45 +02:00
Michael Holzheu
70243b8135 cpictl: Make --help/--version help text s390-tools compliant
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:21:44 +02:00
Claudio Imbrenda
2f461f673e cpi: add missing help line
The information shown with the --help option did not mention the -v or
--version option which can be used to retrieve the version information.

This patch fixes it.

Fixes: 7179f5de2a1582 ("cpi: Introduce new udev rule and integrate with systemd unit")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Reference-ID: VS1706
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:21:31 +02:00
Hans Wippel
c0dc514af8 zdev: Fix segfault with unknown qeth attribute
This patch fixes a segfault in the qeth get_layer function that occurs
when an unknown attribute is used in combination with the force option.

Signed-off-by: Hans Wippel <hwippel@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:20:53 +02:00
Hans Wippel
e831269e74 zdev: Add support for VNIC Characteristics
This patch adds support for the qeth attributes that are used to
configure VNIC Characteristics.

VNIC Characteristics and BridgePort are mutually exclusive. Thus, this
patch also adds a check function for conflicting settings to the qeth
code. Also, the output when VNIC Characteristics is active is added to
the BridgePort attribute descriptions.

Signed-off-by: Hans Wippel <hwippel@linux.vnet.ibm.com>
Acked-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:20:04 +02:00
Ursula Braun
063425d515 znetconf: Re-add missing line in lsznet.raw
Re-add a missing line that was removed by accident when creating the
new s390-tools-2.0.0 release from s390-tools-1.39.0.

Fixes: b627b8d8e1 ("Initial s390-tools-2.0.0 import")
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-22 16:18:02 +02:00
Jan Höppner
61b60baf57 dasdinfo: Fix GCC 7 overflow warning
With GCC 7 we get the following warning as a potential overflow might
happen, if d_name gets too big:

dasdinfo.c: In function 'main':
dasdinfo.c:611:37: warning: '%s' directive writing up to 255 bytes into
  a region of size 69 [-Wformat-overflow=]
   sprintf(sys_dev_path, "/sys/block/%s/dev", dir_entry->d_name);
                                     ^~
dasdinfo.c:611:3: note: 'sprintf' output between 16 and 271 bytes into a
  destination of size 80
   sprintf(sys_dev_path, "/sys/block/%s/dev", dir_entry->d_name);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This could be fixed by simply increasing the buffer size. However, there
is a little bit more to it and the way files are currently read can be
simplified.
Do this by using the libutil functions to read files and clean up a
little along the way.

Reviewed-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-15 05:07:42 +02:00
Jan Höppner
cd085dc721 fdasd: Skip partition check with the force option
Before writing data to the disk, fdasd always checks whether a partition
is specified to prevent writing partition tables to a partition.

However, this also prevents the user from writing partition tables to
loop devices > loop0, even when the force option is specified.
Technically, those are not partitions.

Therefore, allow writing partition tables to partitions when the force
option is specified.

Fixes: #4

Reviewed-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-15 05:05:58 +02:00
Hans Wippel
c2cb410b8f zconf: Add VNIC Characteristics support to lsqeth
This patch adds the qeth attributes that are used to configure
VNIC Characteristics to lsqeth.

The output of lsqeth comprises two columns: one for attribute names, one
for attribute values. Not all VNIC Characteristics attribute names fit
in the corresponding column. Thus, this patch also increases the width
of the attribute names column by 2 characters.

Signed-off-by: Hans Wippel <hwippel@linux.vnet.ibm.com>
Reviewed-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-15 05:04:56 +02:00
Hans Wippel
0b4686dd76 zdev: Fix IPv6 NDP proxy description
Currently, the qeth attributes that are used to configure IPv6 NDP proxy
are described as ARP proxy attributes. This patch changes the titles and
descriptions from ARP to NDP.

Signed-off-by: Hans Wippel <hwippel@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-15 05:04:16 +02:00
Claudio Imbrenda
ca50924acb cpi: Introduce new udev rule and integrate with systemd unit
Add a new udev rule that is triggered when a KVM VM is started
on the system the very first time. This rule reports over the
sysfs CPI kernel interface that the system is a KVM host.

Currently the cpi.service systemd unit already works with
the CPI sysfs interface. Introduce a new internal utility
script "cpictl" that is used by both the udev rule and
the systemd unit to guarantee coordinated access to the
kernel CPU interface.

Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Reviewed-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Reviewed-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-15 05:03:04 +02:00
Michael Holzheu
8ff6af3a4b lscss: Get rid of gcc 7 buffer truncation warnings
With gcc 7 we get warnings for code like the following:

  44 #define MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES      37
 406         char buf[MAX_BUFFER_SIZE_FOR_SUBCHANNEL_ATTRIBUTES];
 416                 device = de_vec[0]->d_name;
 417                 snprintf(buf, sizeof(buf), "%s", device);

 $ grep -r 'd_name\[' /usr/include/
 /usr/include/bits/dirent.h:    char d_name[256];

The compiler assumes that d_name can be up to 255 characters. Therefore
it produces the following warning:

   CC      zconf/css/lscss.o
 lscss.c: In function 'print_sch_io':
 lscss.c:417:31: warning: '%s' directive output may be truncated writing
    up to 255 bytes into a region of size 37 [-Wformat-truncation=]
    snprintf(buf, sizeof(buf), "%s", device);
                               ^~
 In file included from /usr/include/stdio.h:936:0,
                  from lscss.c:10:
 /usr/include/bits/stdio2.h:64:10: note: '__builtin_snprintf' output
                    between 1 and 256 bytes into a destination of size 37
    return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         __bos (__s), __fmt, __va_arg_pack ());
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fix this and use larger buffer sizes to keep gcc quiet.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-06 13:05:12 +02:00
Michael Holzheu
221e74c27c Get rid of gcc 7 "fall through" warnings
With gcc 7 we get warnings like the following:

 fdasd.c: In function 'main':
 fdasd.c:3055:4: warning: this statement may fall through
                          [-Wimplicit-fallthrough=]
     fdasd_exit(&anchor, 0);
     ^~~~~~~~~~~~~~~~~~~~~~
 fdasd.c:3056:3: note: here
    default:
    ^~~~~~~

Fix this by marking functions with "__noreturn" to help gcc.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-06 13:05:01 +02:00
Michael Holzheu
6c3c721275 zgetdump: Fix gcc 7 warning
With gcc 7 the compiler checks for sprintf() the maxium possible resulting
string based on the used datatypes.

Example:

 struct vol {
          ...
          char bus_id[9];
          ...
 }

 sprintf(vol->bus_id, "0.%x.%04x", ssid, vol_parm->devno);

The compiler can prove that "ssid" comes from "u8" and "vol_parm->devno"
from "u16". Therefore the resulting maximum string can be 0.ff.ffff which
requires 10 bytes.

This leads to the following warning:

 dfi_s390mv.c: In function 'volumes_init':
 dfi_s390mv.c:243:45: warning: '__builtin___snprintf_chk' output may be
  truncated before the last format character [-Wformat-truncation=]
  snprintf(vol->bus_id, sizeof(vol->bus_id), "0.%x.%04x", ssid,
                                             ^~~~~~~~~~~
 In file included from /usr/include/stdio.h:936:0,
                  from dfi_s390mv.c:15:
 /usr/include/bits/stdio2.h:64:10: note: '__builtin___snprintf_chk' output
    between 9 and 10 bytes into a destination of size 9
    return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         __bos (__s), __fmt, __va_arg_pack ());
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To get rid of the warning use 10 instead of 9 bytes for the bus_id.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-06 13:04:50 +02:00
Harald Freudenberger
93d91679c3 cpacfstats: Add size setting to perf event
The newer perf_event_open syscall needs a struct
perf_event_attr with the size field set correctly. Older
versions did not even provide this field. However, this
field is now set to the correct size value.

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-06 13:04:19 +02:00
Harald Freudenberger
6b8b336cf0 lszcrypt: Fix core dump caused by stack overwrite.
There was a too tight buffer allocated on the stack
which was overwritten by just one byte caused to
dump the application on function exit's stack check.
Reviewed all the buffer sizes and adapted them
to the need of the functions.

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-06 13:03:31 +02:00
Michael Holzheu
616d379c60 bin/mk-authors: Add script for updating AUTHORS.md file
If called without parameters it updates the authors file with new authors
since last release tag. With the -t option a specific tag can be specified.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
2017-09-06 13:03:06 +02:00
Viktor Mihajlovski
f3f16a7ca4 netboot: Scripts for building a PXE-style netboot image for KVM
A set of scripts and a short documentation describing how to build
a network boot image simulating a PXELINUX-style boot process.

Starting with QEMU 2.10 it is possible to boot a KVM guest over a
network interface using DHCP/BOOTP. The boot process is triggered by
the network boot firmware that is part of QEMU and follows the usual
network boot pattern: a DHCP request is issued by the client and
answered by a DHCP/BOOTP server. The DHCP reply will contain a
TFPT server identification and a bootfile name. The client will
retrieve the bootfile from the TFTP server, load it into memory
and IPL it.

A very common way of setting up a boot server has been defined
by PXELINUX, an open source implementation of PXE. With PXELINUX
the bootfile is a small network boot loader that will retrieve
a potentially client-specific configuration file containing
further instructions for the final boot process (kernel, ramdisk,...).

The set of sample scripts contained in the netboot directory provide
directions for a Linux distributor or a boot server administrator
on how to build a network boot image usable for a simplified
PXELINUX-style network boot setup for s390.

Note that the sample scripts are implementing only a subset of PXELINUX
functionality, specifically the config file parsing. In order to
get full functionality, a more specialized boot loader program
like petitboot or pxe-kexec must be used in the ramdisk.

Further, a sample Dockerfile is provided along with instructions on how
to build the network boot image in a Docker container.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Harald Freudenberger
d029030308 chzcrypt: Corrected handling of insufficient permissions.
The -d and -e options did not show any failure message when
executed with insufficient permissions (e.g. not root user).
Now the behaviour is equal to the other options: A message
'chzcrypt: Error - can't write to xxx. Wrong permissions or
wrong tools version' is printed.

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Harald Freudenberger
097c498340 lszcrypt: fix wrong wording in man page
The -c option was listed with <device-id> and the text
explained that device id may be a card or queue device id.
The --capability option only allows a card as argument so
the man page has been corrected to show this now correctly.

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Harald Freudenberger
73d5e17026 lszcrypt: fix random domain printout when no config available
The sysfs files ap_control_domain_mask and ap_usage_domain_mask
may hold just a string "not supported" if there's no crypto
configuration available. However, lszcrypt always processed
the content of these files as hex number and so produced funny
output if there's no configuration data available.

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Peter Oberparleiter
f3e552d67c zdev: Fix zdev dracut module temp file location
During processing, the zdev-provided dracut module creates a temporary
file using the mktemp tool. Due to a missing path specification
in the filename template, mktemp tries to create the temporary file
in the current working directory which fails if that directory is not
writable:

  # cd /sys
  # dracut -Nf
  mktemp: failed to create file via template 'dracut-zdev.XXXX': No such
  file or directory
  chzdev: Could not write to file : No such file or directory
  sed: can't read : No such file or directory
  chzdev: Could not open file : No such file or directory

Fix this by specifying option --tmpdir when calling mktemp.

Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Hendrik Brueckner
5ba519973f zkey: rename abrev_len -> abbrev_len
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Hendrik Brueckner
18f1730b92 zkey: correctly detect abbreviated commands
Abbreviated commands are not recognized and zkey issues an invalid
command error.

In is_command(), the abbreviated command string is copied into the
command_str variable.  Because this variable is not initialized and,
thus, might contain arbitrary data, a NUL-terminated is not guaranteed.
The following string comparison is very likely to fail.  Correct this
problem by comparing up to the length of the command string only.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Hendrik Brueckner
f1a5ab20b7 zkey: add blank between option and argument
Few options are displayed with their argument concatenated.  This
is due to the nature of the .BR roff macro.  Ensure to separate them
with a blank (using "\~" which is an unbreakable space that stretches
like a normal inter-word space when a line is adjusted).

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-31 17:41:15 +02:00
Philipp Kern
39382ec5fd systemd: Fix deprecated BindTo usage in ttyrun-getty@.service.in
BindTo was renamed to BindsTo in systemd back in v187 from July 2012.

Fixes: #1

Signed-off-by: Philipp Kern <pkern@debian.org>
Acked-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-23 10:41:55 +02:00
Ingo Franzki
2e8ad91d3d zkey: validate XTS key: ignore domain and card
When validating an XTS key, the 2 key parts are validated separately.
This can happen on different crypto cards, when more than one crypto
card is available to the system. Each key part can be validated on
a different card, however, the 2 cards need to have the same master
key, thus the master key validation pattern contained in the 2 key
parts are checked.

Signed-off-by: Ingo Franzki <ifranzki@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-22 19:24:48 +02:00
Michael Holzheu
7548b470c2 Prepare for next release
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-21 12:54:52 +02:00
Hendrik Brueckner
b4714e6113 zkey: use octal values instead of S_IRWX* constants
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-21 12:36:33 +02:00
Hendrik Brueckner
fe0b2d96f7 zkey: properly set umask to prohibit permissions to group and others
Set the umask for the zkey process to clear permissions for genernated
secure key files for group and others.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-21 12:36:33 +02:00
Hendrik Brueckner
b53793d1b6 zkey: add -ldl to LDLIBS (not LDFLAGS)
The LDFLAGS content is added before the object files causing unresolved
symbol dereferences during the build.  This actually happens so far on
Debian/Ubuntu instances.

Hence, use LDLIBS instead.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-21 12:36:33 +02:00
Ingo Franzki
9b5568d2ef zkey: Typo in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.vnet.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-08-21 12:36:33 +02:00
44 changed files with 1612 additions and 217 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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
View 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

View File

@@ -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)

View File

@@ -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--)

View File

@@ -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);
}

View File

@@ -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
#

View 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"

View File

@@ -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,

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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
View 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
View 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

View 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
View 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
View 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
View 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

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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,

View File

@@ -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;

View File

@@ -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);

View File

@@ -1,7 +1,7 @@
include ../common.mak
CPPFLAGS += -I../include
LDFLAGS += -ldl
LDLIBS += -ldl
all: zkey

View File

@@ -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.

View File

@@ -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: