Compare commits

...

38 Commits

Author SHA1 Message Date
Jan Höppner
4014087876 New release s390-tools-2.26.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-14 14:05:17 +01:00
Harald Freudenberger
8a878a0d61 lszcrypt: display hardware filtering support capability
The CEX8 card has in CCA mode a new capability 'stateless
hardware filtering support' which is now displayed as
'H' bit in the FUNCTIONS column and with the -c option.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-14 13:03:06 +01:00
Sven Schnelle
2b511aa2b9 zipl/dump: move dump parmline processing and verification
The current code has different paths to construct the kernel parameters
depending on whether it's a dump kernel or a normal kernel. This would
require adding special handling to get_common_component(), because for
normal kernels the parmline is already set, contrary to dump kernels,
where the command line is constructed later.

To make the code simpler and fix a bug where the default command line no
longer works, move the dump command line processing to an earlier stage.
Also rename the old function to make the function name match what it is
actually doing.

Fixes: 5fb6434548 ("zipl: add get_common_components() and finalize_common_address_data()")
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-14 13:03:06 +01:00
Steffen Maier
6d8243d1b1 zdev: add default queue_depth value for zfcp-lun scsi_device
This avoids exporting explicit settings if it's the default anyway.
I.e. avoid the last line in the example below:

$ chzdev --export - --active --type --all
[active zfcp-lun 0.0.1941:0x500507630904d...:0x4055408f00000000]
scsi_dev/queue_depth=32

Suggested-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Steffen Maier
7ecaeb1a3d zdev: add zfcp ber_stop parameter handling
Complements Linux kernel v5.4 commit 2190168aaea4 ("scsi: zfcp: fix
reaction on bit error threshold notification").

Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
9ada8332d8 zipl: Embed loader data directly into boot object
Currently, each generated loader binary is linked into one data.o object
file which is then linked against boot.o. The data.o file is also used
to generate the data.h header file using nm, which will contain all
symbols required by zipl.

The linking process is somewhat depended on the directory, as the symbol
names are derived from the file names of the input files, which is the
default behavior of the linker. The file name in this case being the
entire path.

Examples for the current situation (starting from root dir in each case):
  $ cd zipl/boot && make eckd0_cdl.bin
  $ cc -no-pie -static -nostdlib -Wl,--relocatable -Wl,--format,binary -o data.o eckd0_cdl.bin
  $ nm data.o
  0000000000000018 D _binary_eckd0_cdl_bin_end
  0000000000000018 A _binary_eckd0_cdl_bin_size
  0000000000000000 D _binary_eckd0_cdl_bin_start

  $ make -C zipl/boot eckd0_cdl.bin
  $ cc -no-pie -static -nostdlib -Wl,--relocatable -Wl,--format,binary -o data.o zipl/boot/eckd0_cdl.bin
  $ nm data.o
  000000000000018 D _binary_zipl_boot_eckd0_cdl_bin_end
  000000000000018 A _binary_zipl_boot_eckd0_cdl_bin_size
  000000000000000 D _binary_zipl_boot_eckd0_cdl_bin_start

The example above shows that the entire path would end up in the symbol
name if specified that way.

To make this more robust, future proof, and get more control of the
resulting symbol names, use '.incbin' and some macros for embedding the
loader binary files. This also reduces the linker step and the
generation of the data.h header file.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Co-developed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
ca25f71a6e genprotimg/boot: stage3b_reloc.bin: add linker script
Use a linker script instead of a linker flags for the layout. While at
it, use common naming `_start` for entry. This change allows us to
simplify the Makefile by using the linker option `-T` for all
bootloaders.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
67790d3787 genprotimg/boot: stage3b: add size check to the linker script
The stage3b loader memory layout must not be larger than 0x10000 bytes.
Let's check this in the linker script.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
d301668811 genprotimg/boot: improve linker scripts
+ the input section names `.text.init` and `.text.start` aren't
   ambiguous, therefore there is no reason so specify a file name
 + discard `.interp` section since no loader is used

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
6097ee3f9d genprotimg/boot: Makefile: simplify objcopy command
Instead of maintaining an include list, use an exclude list (if
neccessary). This simplifies the `objcopy` calls a lot, and it's
possible because `objcopy -O binary` only includes the memory dump of
the contents of the input object file. [1] This means that sections like
for debug information that do not occupy memory during the process
execution are discarded by design. [2]

In addition, if we do not want a particular ELF section, we can list it
in the discard section of the linker script.

[1] https://man7.org/linux/man-pages/man1/objcopy.1.html
[2] https://man7.org/linux/man-pages/man5/elf.5.html

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
43967feb2c genprotimg/boot: disable build-id
Disable the build-id since it was never used. Adapt the linker scripts
accordingly.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
8f4535f5eb genprotimg/boot: use --no-warn-rwx-segments linker flag
This disables the following warning `ld: warning: stag3a.elf has a LOAD
segment with RWX permissions` for newer linker. This changes nothing in
functionality for the bootloaders, since only the binaries and not the
ELF files are actually used.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
dfe8a4f803 genprotimg/boot: declare that no executable stack is required
Normally, `gcc` takes care of adding the `GNU_STACK` marking except for
assembly code. Therefore, let's add the marking manually. Discard the
`.note.GNU-stack` section in the linker script since it's just a
"message" from the compiler to the linker. This fixes the linker
warning:

ld: warning: entry.o: missing .note.GNU-stack section implies executable stack

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
fe0d42e295 zipl/boot: use linker scripts for all bootloaders
Use linker script for all bootloaders instead of having the load
addresses of the bootloaders hard-coded in the Makefile. This allows us
to simplify the Makefile and it fixes the dependency tracking for the
bootloaders *0.bin, *1.bin, and *1b.bin.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
baf7e9aa2e zipl: move STAGE2_MAX_SIZE and STAGE1B_LOAD_ADDR to loaders_layout.h
This allows the reuse of the macro in the next patch. In order to match
the naming scheme rename `STAGE1B_LOAD_ADDR` to `STAGE1B_LOAD_ADDRESS`.

Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
60d03262d8 zipl/boot: simplify objcopy commands
Instead of maintaining an include list, use an exclude list (if
neccessary). This simplifies the `objcopy` calls a lot, and it's
possible because `objcopy -O binary` only includes the memory dump of
the contents of the input object file. [1] This means that sections like
for debug information that do not occupy memory during the process
execution are discarded by design. [2]

In addition, if we do not want a particular ELF section, we can list it
in the discard section of the linker script.

[1] https://man7.org/linux/man-pages/man1/objcopy.1.html
[2] https://man7.org/linux/man-pages/man5/elf.5.html

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
4bed503aa7 zipl/boot: disable build-id
Disable the build-id since it was never used. Adapt the linker scripts
accordingly.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
4518bf7d73 zipl/boot: use --no-warn-rwx-segments linker flag
This disables the following warning `ld: warning: stage3.exec has a LOAD
segment with RWX permissions` for newer linker. This changes nothing in
functionality for the zipl bootloaders, since only the binaries and not
the ELF files are actually used.

Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
3d168fac14 zipl/boot: declare that no executable stack is required
Normally, `gcc` takes care of adding the `GNU_STACK` marking except for
assembly code. Therefore, let's add the marking manually. Discard the
`.note.GNU-stack` section in the linker script since it's just a
"message" from the compiler to the linker. This fixes the linker
warning:

ld: warning: entry.o: missing .note.GNU-stack section implies executable stack

Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
746a703079 zipl/boot: discard .eh_frame and .interp input sections
The ELF section `.eh_frame` is used for frame unwinding during, for
example, exception handling and the section `.interp` is used by the
program interpreter. [1] Since no frame unwinding nor a program
interpreter is used for the bootloaders we can discard these input
section.

The content of the (exec|bin) files don't change after this change.

[1] https://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/specialsections.html

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Marc Hartmayer
4aa5534f1d common.mak: fix typo and remove blank line at the EOF
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-13 22:18:49 +01:00
Sven Schnelle
7c24855ba1 ipl_tools: add support for list-directed IPL from ECKD DASD
Add support to chreipl/lsreipl to show and reconfigure ipl parameters
for list-directed IPL from ECKD DASD.

Parameters accepted:

device   - ccw device id
bootprog - Boot Prog Selector
loadparm - Load parameters
brchr    - location of bootrecord in cylinder/head/record format.
clear    - clear memory before loading

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2023-02-03 14:48:37 +01:00
Ingo Franzki
6222c38495 zkey: Support EP11 host library version 4
Try to load libep11.so.4 if available, but fallback to older
library versions if not.

Reviewed-by: Jörg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Ingo Franzki
8709a47f6f libseckey: RSA cipher: Tolerate "implicit rejection" option
With parameter OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION one can enable or
disable the implicit rejection mechanism for RSA PKCS#1 v1.5 decryption.
For the default provider, this is enabled by default.

We do not support implicit rejection so far, so disable it for the
default provider operation context when the key contains an RSA secure key,
and reject to set it to anything else then 0 (disabled).

See OpenSSL commit 5ab3ec1bb1

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Ingo Franzki
1fb05038cd libseckey: RSA signature: Support OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX
Since OpenSSL 3.1 a new RSA-PSS salt length constant exists to select
the maximum possible salt length based on the RSA-PSS parameters and the
digest used: OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX
This is the default salt length when no other salt length is set by
the caller.

In contrast to OSSL_PKEY_RSA_PSS_SALT_LEN_MAX, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX
also ensures that the resulting salt length is not larger than the used
digest size. The salt length calculated with OSSL_PKEY_RSA_PSS_SALT_LEN_MAX
may be larger than the digest size, dependent on the RSA-PSS parameters.

FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
the hash function output block (in bytes)."

See OpenSSL commit 6c73ca4a2f

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Ingo Franzki
4f5d33988d libseckey: EC signature: Reject deterministic signatures
With parameter OSSL_SIGNATURE_PARAM_NONCE_TYPE one can choose to generate
a deterministic signature, i.e. using a deterministic nonce K.

We do not support that so far, so reject to set the nonce type to
anything other than 0 (random nonce K).

See OpenSSL commit f3090fc710

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Eduard Shishkin
75513ee975 zipl/src: Fix the improper order of resource releasing
Fix the improper order of resource releasing resulted in failed umount
Do umount after closing (not before)

Fixes: f7d2339 (zipl: List-Directed IPL from ECKD DASD)
Reported-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Thomas Richter
b8fff9b750 libvmdump: Remove libvmdump and vmconvert
The library libvmdump is written in C++ and uses exception handling
and class inheritance. The tools vmur and vmconnect are compiled using
the C++ compiler for linking with the libvmdump library.

With integration of vmdump file support into the zgetdump tool and
the removal of vmur vmdump file conversion support there is no need
anymore the vmconvert tool.
With removal of the tool vmconvert, the libvmdump library written in C++
has no more user and can be deleted.

Remove the vmconvert command from the zgetdump man page.

Remove the directories libvmdump and vmconvert and adjust the Makefile.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Suggested-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Thomas Richter
d5f853c460 vmur: Remove option -c for dump file conversion
Remove option -c for implicit dump file conversion from vmdump format
to lkcd format. If option -c is specified, an error message
is printed and the program terminates. A hint to the new conversion
tool zgetdump is shown.  Option -c is not listed in the help text.
The man page is also updated to reflect this change.
With zgetdump tool now supporting vmdump file format there is no need to
convert a vmdump file while extracting it from the reader device.

Use commands
1. vmur rec <spool-id> VMDUMP_FILE
2. zgetdump VMDUMP_FILE ELF_FILE
to extract a vmdump file from the reader and convert it to elf format.

Note to Maintainer:
The rename of file vmur.cpp to vmur.c triggers the pre-commit
checking of git-format-clang. This checking fails. This is intended.
The patch shows the changes for this line item.
The pre-commit checking fails on many, many changes not touched
for changed by this patch.
The pre-commit failure should be fixed with a follow-on patch.

Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Thomas Richter
067dd5c7ef zdump: Add vmdump dfi for vmdump format to elf format
Add support for vmdump 64big format to the zgetdump utility.
The result is an elf file suitable for tool crash.
This patch adds file dfi_vmdump.c to handle conversion from
z/VM vmdump format to the internal memory representation of this tool.
Therefore both output formats elf and s390 are supported as target
of the conversion.

The vmdump file formats 32bit and 64bit are not supported anymore.
They have been obsolete since CP version 5.1 (end of service since
30-Sep-2009).

Vector register set is not part of a vmdump file and can not be
displayed.

Output before:
 # zgetdump ~/vmdump-0383
 zgetdump: No valid dump found on "/root/vmdump-0383"
 #

Output after:
 # ./zgetdump ~/vmdump-0383 ~/vmdump-0383.elf
 Format Info:
  Source: vmdump
  Target: elf

 Copying dump:
  00000000 / 00000379 MB
  00000379 / 00000379 MB

 Success: Dump has been copied
 # file ~/vmdump-0383.elf
 /root/vmdump-0383.elf: ELF 64-bit MSB core file, IBM S/390, version 1 \
	 .... (SYSV), SVR4-style, from 'vmlinux'
 #

 # ./zgetdump -i ~/vmdump-0383
 General dump info:
  Dump format........: vmdump
  Version............: 2
  UTS node name......: s8360046.lnxne.boe
  UTS kernel release.: 6.1.0-rc2-d-perf+
  UTS kernel version.: #1 SMP Fri Oct 28 09:42:13 CEST 2022
  System arch........: s390x (64 bit)
  CPU count (online).: 2
  CPU count (real)...: 2
  Dump memory range..: 2048 MB

 Memory map:
  0000000000000000 - 000000007fffffff (2048 MB)
 #

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Joern Siglen
af1d05c4a4 dbginfo.sh: correct location of qemu guest agent command
qemu-ga command was accidently moved to z/VM commands

Reviewed-by: Michael Storzer <mstorzer@de.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Joern Siglen
c5ec01420f dbginfo.sh: add zVM command q syscontrol
determine the current values of the algorithm settings controlled
by the SET SYSCONTROL

Reported-by: Eberhard Pasch <epasch@de.ibm.com>
Reviewed-by: Michael Storzer <mstorzer@de.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Joern Siglen
f25984e716 dbginfo.sh: update copyright date
update copyright date

Reviewed-by: Michael Storzer <mstorzer@de.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2023-01-27 14:12:38 +01:00
Marc Hartmayer
7babd82e6f zgetdump/Makefile: don't use .check_dep_zgetdump as linker input
The `.check_dep_zgetdump` file is used to cache the result of the
dependency checks and should not be used as input for linking or
anything else. Let's add it as dependency for the objects file. This
shouldn't cause any problems since the Makefile rule for object files is
defined in `common.mak` as follows:

%.o: %.c
	$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/147
Fixes: 8d8d5e9746 ("zdump: Fix Makefile dependencies")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>
2022-12-20 08:17:20 +01:00
Steffen Eiden
d030874050 libpv: disallow glib features from after 2.56
Enforce that the first glib.h include is done via glib-helper.h for libpv
so that glib version checks are in place.

Change zdump and pvattest such that they never include glibstuff before
libpv/glib-helper.h

Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2022-12-15 11:33:46 +01:00
Steffen Eiden
394a6dd5ea zdump: replace atomic refcount with atomic int
(Atomic) refcounting was introduced in glib2.58.
We want to support v2.56 as well, so replace it with int and the atomic
operations introduced in glib 2.4.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/146
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2022-12-15 11:26:11 +01:00
Nikolay Gueorguiev
db6eb7d554 s390-tools: Fix Makefile install step chown warnings
Since coreutils v9.1 commit 8f31074cb ("chown: warn about USER.GROUP")
chown utility now warns about using of wrong separator for USER and
GROUP options.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/145
Signed-off-by: Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2022-12-15 11:23:37 +01:00
Jan Höppner
032304d503 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-12-08 13:40:15 +01:00
72 changed files with 1378 additions and 2395 deletions

2
.gitignore vendored
View File

@@ -78,7 +78,6 @@ systemd/ttyrun-getty@.service
tape390/tape390_crypt
tape390/tape390_display
tunedasd/src/tunedasd
vmconvert/vmconvert
vmcp/vmcp
vmur/vmur
zconf/chp/chchp
@@ -110,6 +109,7 @@ ziomon/ziorep_traffic
ziomon/ziorep_utilization
zipl/boot/*.bin
zipl/boot/*.exec
zipl/boot/.loaders
zipl/boot/data.h
zipl/src/chreipl_helper.device-mapper
zdev/src/zdev_id

View File

@@ -90,6 +90,7 @@ List of all individuals having contributed content to s390-tools
- Mikhail Zaslonko
- Nikita Dubrovskii
- Niklas Schnelle
- Nikolay Gueorguiev
- Peter Oberparleiter
- Peter Tiedemann
- Philipp Kern

View File

@@ -1,6 +1,25 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.26.0 (2023-02-14)__
For Linux kernel version: 6.2
Remove tools / libraries:
- Remove vmconvert and libvmdump in favor of vmdump file support in zdump
Changes of existing tools:
- ipl_tools: Add support for list-directed IPL from ECKD DASD
- lszcrypt: Display hardware filtering support capability
- vmur: Remove option -c for dump file conversion (See zdump changes)
- zdev: Add zfcp ber_stop parameter handling
- zdump: Add vmdump dfi for vmdump format to elf format
- zkey: Support EP11 host library version
Bug Fixes:
- zipl: Move dump parmline processing and verification
- zipl/genprotimg: Various build improvements
* __v2.25.0 (2022-12-08)__
For Linux kernel version: 6.1

View File

@@ -9,11 +9,11 @@ include common.mak
# TOOLS: Tools that can have a dependency to base libraries or libraries
#
BASELIB_DIRS = libutil libseckey
LIB_DIRS = libvtoc libzds libdasd libvmdump libccw libvmcp libekmfweb \
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
libkmipclient libcpumf libap libpv
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
genprotimg lsstp hsci hsavmcore chreipl-fcp-mpath ap_tools pvattest

View File

@@ -98,11 +98,6 @@ Package contents
* tunedasd:
Adjust tunable parameters on DASD devices.
* vmconvert:
Convert system dumps created by the z/VM VMDUMP command into dumps with
LKCD format. These LKCD dumps can then be analyzed with the dump analysis
tool lcrash.
* vmcp:
Send commands from Linux as a z/VM guest to the z/VM control program (CP).
Call vmcp with the CP command as an argument. The response of z/VM is

View File

@@ -26,9 +26,9 @@ ap-check: ap-check.o $(libs)
install: all
@if [ ! -d $(DESTDIR)$(MDEVCTL_CALLOUTS) ]; then \
mkdir -p $(DESTDIR)$(MDEVCTL_CALLOUTS); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DIR); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_SCRIPTS); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_CALLOUTS); \
chmod 755 $(DESTDIR)$(MDEVCTL_DIR); \
chmod 755 $(DESTDIR)$(MDEVCTL_SCRIPTS); \
chmod 755 $(DESTDIR)$(MDEVCTL_CALLOUTS); \
@@ -37,9 +37,9 @@ install: all
$(DESTDIR)$(MDEVCTL_CALLOUTS)
@if [ ! -d $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS) ]; then \
mkdir -p $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_DIR); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_DIR); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_DIR); \
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_SCRIPTS); \
chmod 755 $(DESTDIR)$(MDEVCTL_DEP_CALLOUTS); \

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 = 25
RELEASE = 26
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -145,6 +145,20 @@ then \
exit 1; \
fi
#
# Test for linker option
#
# $1: Linker option
#
# Returns the linker option if available and nothing otherwise
#
define test_linker_flag
$(shell printf "int main(void) {return 0;}\n" | \
( $(CC) "-Wl,$1" -o /dev/null -x c - ) >/dev/null 2>&1 && printf -- '-Wl,%s' "$1")
endef
NO_WARN_RWX_SEGMENTS_LDFLAGS := $(call test_linker_flag,"--no-warn-rwx-segments")
#
# Support alternate install root
#
@@ -261,7 +275,7 @@ else
NO_PIE_LDFLAGS :=
endif
# Overwrite implicite makefile rules for having nice compile output
# Overwrite implicit makefile rules for having nice compile output
%.o: %.c
ifeq ("${C}","1")
$(CHECKTOOL) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c $< -o $@
@@ -364,10 +378,6 @@ $(rootdir)/libzds/libzds.a: $(rootdir)/libzds
$(MAKE) -C $(rootdir)/libzds/ libzds.a
.PHONY: $(rootdir)/libzds
$(rootdir)/libvmdump/libvmdump.a: $(rootdir)/libvmdump
$(MAKE) -C $(rootdir)/libvmdump/ libvmdump.a
.PHONY: $(rootdir)/libvmdump
$(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
.PHONY: $(rootdir)/libvmcp
@@ -396,8 +406,8 @@ $(rootdir)/libpv/libpv.a: $(rootdir)/libpv
$(MAKE) -C $(rootdir)/libpv libpv.a
.PHONY: $(rootdir)/libpv
$(rootdir)/zipl/boot/data.o:
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
$(rootdir)/zipl/boot/.loaders:
$(MAKE) -C $(rootdir)/zipl/boot/ .loaders
install_dirs:
for dir in $(INSTDIRS); do \
@@ -422,4 +432,3 @@ clean_dep:
clean: clean_echo clean_gcov clean_dep
endif

View File

@@ -69,27 +69,15 @@ endif
stage3b_reloc.o: stage3b.bin
stage3a.elf: head.o stage3a_init.o stage3a.o stage3a.lds $(ZIPL_OBJS)
stage3b.elf: head.o stage3b.o stage3b.lds $(ZIPL_OBJS)
stage3b_reloc.elf:
stage3a.elf: head.o stage3a_init.o $(ZIPL_OBJS)
stage3b.elf: head.o $(ZIPL_OBJS)
%.elf: %.o
case $* in \
stage3a) SFLAGS="-Wl,-T,stage3a.lds";; \
stage3b) SFLAGS="-Wl,-T,stage3b.lds";; \
stage3b_reloc) SFLAGS="-Wl,-estage3b_reloc_start,-Ttext,0";; \
esac; \
$(LINK) $$SFLAGS $(NO_PIE_LDFLAGS) -m64 -static -nostdlib $(filter %.o, $^) -o $@
%.elf: %.lds %.o
$(LINK) $(NO_PIE_LDFLAGS) $(NO_WARN_RWX_SEGMENTS_LDFLAGS) -Wl,-T,$< -Wl,--build-id=none -m64 -static -nostdlib $(filter %.o, $^) -o $@
@chmod a-x $@
%.bin: %.elf
$(OBJCOPY) -O binary \
--only-section=.text* \
--only-section=.ex_table* \
--only-section=.fixup* \
--only-section=.data* \
--only-section=.rodata* \
$< $@
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
@chmod a-x $@
clean:

View File

@@ -29,3 +29,8 @@ _start:
brasl %r14, initialize
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
.previous
/* The code doesn't require an executable stack */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -23,8 +23,6 @@ ENTRY(_init)
SECTIONS
{
. = 0x0;
. = HEAP_ADDRESS;
__heap_start = .;
.heap : {
@@ -46,7 +44,7 @@ SECTIONS
. = STAGE3A_INIT_ENTRY;
__text_init_start = .;
.text : {
stage3a_init.o(.text.init)
*(.text.init)
__text_init_stop = ABSOLUTE(.);
/* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY',
* otherwise the text data could be overwritten by the original zipl stage3
@@ -56,8 +54,8 @@ SECTIONS
. = 0x1000;
ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY,
"Text section doesn't conform to the described memory layout");
head.o(.text.start)
*(.text)
*(.text.start)
*(.text .text.*)
}
.ex_table ALIGN(16) : {
@@ -74,7 +72,7 @@ SECTIONS
.rodata ALIGN(16) : {
*(.rodata)
*(.rodata.*)
*(.rodata*)
}
.data ALIGN(16) : {
@@ -90,14 +88,10 @@ SECTIONS
ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout");
}
/* List this explicitly as otherwise .note.gnu.build-id will be
* put at 0x0 */
.notes : {
*(.note.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

View File

@@ -26,3 +26,8 @@ _init:
br %r1
.Lstage3a_entry: .long STAGE3A_ENTRY
.previous
/* The code doesn't require an executable stack */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -21,8 +21,6 @@ ENTRY(_start)
SECTIONS
{
. = 0x0;
. = HEAP_ADDRESS;
__heap_start = .;
.heap : {
@@ -34,8 +32,8 @@ SECTIONS
. = STAGE3B_ENTRY;
.text : {
head.o(.text.start)
*(.text)
*(.text.start)
*(.text .text.*)
}
.ex_table ALIGN(16) : {
@@ -52,7 +50,7 @@ SECTIONS
.rodata ALIGN(16) : {
*(.rodata)
*(.rodata.*)
*(.rodata*)
}
.data ALIGN(16) : {
@@ -74,14 +72,12 @@ SECTIONS
}
__stack_end = .;
/* List this explicitly as otherwise .note.gnu.build-id will be
* put at 0x0 */
.notes : {
*(.note.*)
}
ASSERT(. <= IMAGE_ENTRY, "stage3b size must be smaller than 0x10000 bytes")
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

View File

@@ -22,8 +22,8 @@
.org 0x0
.section .text.start
.globl stage3b_reloc_start
stage3b_reloc_start:
.globl _start
_start:
/* Might be called after a diag308 so better set
* architecture and addressing mode
*/
@@ -53,3 +53,8 @@ stage3b_start:
.incbin "stage3b.bin"
stage3b_end:
.previous
/* The code doesn't require an executable stack */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,19 @@
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
ENTRY(_start)
SECTIONS
{
.text : {
*(.text.start)
*(.text .text.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

View File

@@ -52,7 +52,7 @@ install-scripts: lshmc
cat $$i | \
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
>$(DESTDIR)$(USRSBINDIR)/$$i; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
chmod 755 $(DESTDIR)$(USRSBINDIR)/$$i; \
done

View File

@@ -5,7 +5,7 @@ all:
install: hsci
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
chmod 755 $(DESTDIR)$(BINDIR)/hsci; \
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \

View File

@@ -14,12 +14,18 @@
#include "lib/zt_common.h"
#include "linux_layout.h"
#define STAGE0_LOAD_ADDRESS _AC(0x0, UL)
#define STAGE1_LOAD_ADDRESS _AC(0x18, UL)
#define STAGE1B_LOAD_ADDRESS _AC(0xe000, UL)
#define STAGE2_DESC _AC(0x78, UL)
#define STAGE2_ENTRY _AC(0x2018, UL)
#define STAGE2_HEAP_ADDRESS _AC(0x6000, UL)
#define STAGE2_HEAP_SIZE _AC(0x3000, UL)
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
#define STAGE2_STACK_SIZE _AC(0x1c00, UL)
#define STAGE2_MAX_SIZE _AC(0x3000, UL)
#define STAGE3_ENTRY _AC(0xa000, UL)

View File

@@ -18,6 +18,12 @@
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56
#endif
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56
#ifdef __G_LIB_H__
#error "glib.h must be included via libpv/glib-helper.h"
#endif
#include <glib.h>
#include <gmodule.h>
#include <stdio.h>

View File

@@ -12,7 +12,7 @@ clean:
install: ip_watcher.pl xcec-bridge start_hsnc.sh
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
< start_hsnc.sh >$(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
chmod 755 $(DESTDIR)$(USRSBINDIR)/start_hsnc.sh; \
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 ip_watcher.pl \
$(DESTDIR)$(USRSBINDIR)

View File

@@ -23,12 +23,15 @@
#define BOOTPARMS_CCW_MAX 64
#define BOOTPARMS_FCP_MAX 3452
#define OPT_BRCHR 0x80
enum target_type {
TT_CCW,
TT_FCP,
TT_NSS,
TT_NODE,
TT_NVME,
TT_ECKD,
};
enum reipl_type {
@@ -36,12 +39,14 @@ enum reipl_type {
REIPL_CCW,
REIPL_NSS,
REIPL_NVME,
REIPL_ECKD,
};
static const char *const usage_chreipl =
"Usage: %s [TARGET] [ARGS] [OPTIONS]\n"
"\n"
" chreipl [ccw] [-d] <DEVICE> [OPTIONS]\n"
" chreipl [eckd] [-d] <DEVICE> [OPTIONS]\n"
" chreipl [fcp] [-d] <DEVICE> [-w] <WWPN> [-l] <LUN> [OPTIONS]\n"
" chreipl nvme [-i] <FID> [-s] <NSID> [OPTIONS]\n"
" chreipl [node] <NODE|DIR> [OPTIONS]\n"
@@ -50,6 +55,7 @@ static const char *const usage_chreipl =
"\n"
"The following re-IPL targets are supported:\n"
" ccw IPL from CCW device\n"
" eckd IPL from ECKD device\n"
" fcp IPL from FCP device\n"
" nvme IPL from NVME device\n"
" nss IPL from NSS\n"
@@ -66,6 +72,13 @@ static const char *const usage_chreipl =
" -L, --loadparm <PARM> Loadparm specification\n"
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
"\n"
"Options for eckd target:\n"
" -d, --device <DEVICE> Device number of the ECKD IPL device\n"
" -b, --bootprog <BPROG> Bootprog specification\n"
" --brchr <C,H,R> Boot record location in Cylinder,Head,Record format\n"
" -L, --loadparm <PARM> Loadparm specification\n"
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
"\n"
"Options for fcp target:\n"
" -d, --device <DEVICE> Device number of the adapter of the FCP IPL device\n"
" -l --lun <LUN> Logical unit number of the FCP IPL device\n"
@@ -114,6 +127,8 @@ static struct locals {
int target_type_auto_mode;
enum reipl_type reipl_type; /* CCW, FCP, NVME, NSS */
int reipl_clear;
char *brchr;
int brchr_set;
} l;
static void __noreturn print_usage_chreipl_exit(void)
@@ -329,6 +344,19 @@ static void parse_ccw_args(char *nargv[], int nargc)
set_device(nargv[0]);
}
static void parse_eckd_args(char *nargv[], int nargc)
{
/*
* we might be called like this:
* chreipl eckd 4711
*/
if (l.busid_set)
ERR_EXIT("Use either options or positional parameters");
if (nargc > 1)
ERR_EXIT("Too many arguments specified for \"eckd\" re-IPL type");
set_device(nargv[0]);
}
static void parse_nss_args(char *nargv[], int nargc)
{
/*
@@ -369,6 +397,8 @@ static int set_reipl_type(const char *dev_name)
l.reipl_type = REIPL_FCP;
else if (strncmp(dev_name, "nvme", strlen("nvme")) == 0)
l.reipl_type = REIPL_NVME;
else if (strncmp(dev_name, "eckd", strlen("eckd")) == 0)
l.reipl_type = REIPL_ECKD;
else
return -1;
@@ -493,12 +523,15 @@ static void parse_pos_args(char *nargv[], int nargc)
case TT_NODE:
parse_node_args(nargv, nargc);
break;
case TT_ECKD:
parse_eckd_args(nargv, nargc);
break;
}
}
static void check_fcp_opts(void)
{
if (l.nss_name_set)
if (l.nss_name_set || l.brchr_set)
ERR_EXIT("Invalid option for \"fcp\" target specified");
if (!(l.busid_set && l.wwpn_set && l.lun_set))
ERR_EXIT("The \"fcp\" target requires device, WWPN, "
@@ -507,7 +540,8 @@ static void check_fcp_opts(void)
static void check_nvme_opts(void)
{
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set)
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set ||
l.brchr_set)
ERR_EXIT("Invalid option for \"nvme\" target specified");
if (!(l.fid_set && l.nsid_set))
ERR_EXIT("The \"nvme\" target requires FID, and optional NSID");
@@ -515,16 +549,25 @@ static void check_nvme_opts(void)
static void check_ccw_opts(void)
{
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set)
if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set ||
l.brchr_set)
ERR_EXIT("Invalid option for \"ccw\" target specified");
if (!l.busid_set)
ERR_EXIT("The \"ccw\" target requires device");
}
static void check_eckd_opts(void)
{
if (l.nss_name_set || l.wwpn_set || l.lun_set || l.fid_set)
ERR_EXIT("Invalid option for \"eckd\" target specified");
if (!(l.busid_set))
ERR_EXIT("The \"eckd\" target requires device");
}
static void check_nss_opts(void)
{
if (l.bootprog_set || l.loadparm_set || l.busid_set || l.wwpn_set ||
l.lun_set)
l.lun_set || l.brchr_set)
ERR_EXIT("Invalid option for \"nss\" target specified");
if (!l.nss_name_set)
ERR_EXIT("The \"nss\" target requires NSS name");
@@ -563,6 +606,12 @@ static void set_reipl_clear(const char *arg)
ERR_EXIT("re-IPL clear argument must be either 1 or 0");
}
static void set_brchr(const char *arg)
{
l.brchr = strdup(arg);
l.brchr_set = 1;
}
static void parse_chreipl_options(int argc, char *argv[])
{
int opt, idx;
@@ -580,6 +629,7 @@ static void parse_chreipl_options(int argc, char *argv[])
{ "force", no_argument, NULL, 'f' },
{ "version", no_argument, NULL, 'v' },
{ "clear", required_argument, NULL, 'c' },
{ "brchr", required_argument, NULL, OPT_BRCHR },
{ NULL, 0, NULL, 0 }
};
static const char optstr[] = "hd:vw:l:fL:b:n:p:c:i:s:";
@@ -592,6 +642,8 @@ static void parse_chreipl_options(int argc, char *argv[])
set_target_type(TT_FCP, 0);
else if (strcmp(argv[1], "ccw") == 0)
set_target_type(TT_CCW, 0);
else if (strcmp(argv[1], "eckd") == 0)
set_target_type(TT_ECKD, 0);
else if (strcmp(argv[1], "nss") == 0)
set_target_type(TT_NSS, 0);
else if (strcmp(argv[1], "nvme") == 0)
@@ -640,6 +692,9 @@ static void parse_chreipl_options(int argc, char *argv[])
case 'c':
set_reipl_clear(optarg);
break;
case OPT_BRCHR:
set_brchr(optarg);
break;
case 'v':
print_version_exit();
default:
@@ -737,6 +792,34 @@ static void chreipl_ccw(void)
print_ccw(0);
}
static void chreipl_eckd(void)
{
check_eckd_opts();
if (!ccw_is_device(l.busid) && !l.force_set) {
if (is_ignored(l.busid))
ERR_EXIT("Device is on cio_ignore list, try \"cio_ignore -r %s\"?",
l.busid);
ERR_EXIT("Could not find DASD ECKD device \"%s\"", l.busid);
}
if (l.reipl_clear >= 0) {
check_exists("reipl/eckd/clear", "ECKD re-IPL clear attribute");
write_str(l.reipl_clear ? "1" : "0", "reipl/eckd/clear");
}
if (!l.brchr_set)
l.brchr = "auto";
write_str(l.brchr, "reipl/eckd/br_chr");
if (!l.bootprog_set)
sprintf(l.bootprog, "0");
write_str(l.bootprog, "reipl/eckd/bootprog");
write_str(l.busid, "reipl/eckd/device");
write_str_optional(l.loadparm, "reipl/eckd/loadparm", l.loadparm_set, "loadparm");
write_str("eckd", "reipl/reipl_type");
print_eckd(0, "eckd");
}
static void chreipl_fcp(void)
{
check_fcp_opts();
@@ -850,6 +933,11 @@ static void chreipl_node(void)
l.busid_set = 1;
chreipl_ccw();
break;
case REIPL_ECKD:
ccw_busid_get(l.dev, l.busid);
l.busid_set = 1;
chreipl_eckd();
break;
case REIPL_FCP:
fcp_wwpn_get(l.dev, l.wwpn);
l.wwpn_set = 1;
@@ -878,6 +966,9 @@ void cmd_chreipl(int argc, char *argv[])
case TT_CCW:
chreipl_ccw();
break;
case TT_ECKD:
chreipl_eckd();
break;
case TT_FCP:
chreipl_fcp();
break;

View File

@@ -141,6 +141,30 @@ void print_ccw(int show_ipl)
print_fw_str("clear: %s\n", dir, "clear");
}
void print_eckd(int show_ipl, const char *name)
{
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
"/sys/firmware/reipl/eckd/loadparm";
char *dir = show_ipl ? "ipl" : "reipl/eckd";
char loadparm[9], loadparm_path[PATH_MAX];
printf("%-12s %s\n", get_ipl_banner(show_ipl), name);
print_fw_str("Device: %s\n", dir, "device");
print_fw_str("bootprog: %s\n", dir, "bootprog");
print_fw_str("br_chr: %s\n", dir, "br_chr");
print_fw_str("Bootparm: \"%s\"\n", dir, "scp_data");
if (access(path_loadparm, R_OK) == 0) {
sprintf(loadparm_path, "%s/%s", dir, "loadparm");
read_fw_str(loadparm, loadparm_path, sizeof(loadparm));
if (strcmp(loadparm, " ") == 0)
loadparm[0] = 0;
printf("Loadparm: \"%s\"\n", loadparm);
}
if (!show_ipl)
print_fw_str("clear: %s\n", dir, "clear");
}
static void parse_lsreipl_options(int argc, char *argv[])
{
int opt, idx;
@@ -193,6 +217,9 @@ void cmd_lsreipl(int argc, char *argv[])
print_nvme(l.ipl_set, 1);
else if (strcmp(reipl_type_str, "ccw") == 0)
print_ccw(l.ipl_set);
else if (strcmp(reipl_type_str, "eckd") == 0 ||
strcmp(reipl_type_str, "eckd_dump") == 0)
print_eckd(l.ipl_set, reipl_type_str);
else if (strcmp(reipl_type_str, "nss") == 0)
print_nss(l.ipl_set);
else

View File

@@ -45,6 +45,7 @@ extern void print_ccw(int show_ipl);
extern void print_fcp(int show_ipl, int dump);
extern void print_nvme(int show_ipl, int dump);
extern void print_nss(int show_ipl);
extern void print_eckd(int show_ipl, const char *name);
/*
* Helper

View File

@@ -36,6 +36,9 @@ The first argument specifies the re-IPL target:
.RB "- " ccw :
Specify a DASD CCW device for reboot
.TP
.RB "- " eckd :
Specify a DASD ECKD device for reboot
.TP
.RB "- " fcp :
Specify a FCP device for reboot
.TP
@@ -175,6 +178,63 @@ in the installed zIPL environment block for evaluation of zIPL environment
variables in the kernel command line:
\fB# chreipl ccw -d 0.0.7e78 -L 1S2\fP
.SH eckd
Use the eckd re-IPL target for DASD devices that are accessed by the hardware
using channel command word (CCW) channels. In contrast to the ccw re-IPL target,
the eckd target uses a list-directed bootloader that supports secure boot.
.TP
.BR "\-d" " or " "\-\-device"
Specifies the device bus-ID of the DASD. If the bus-ID starts with "0.0." this
prefix can be omitted and the four digit short notation can be used (e.g. 5000 is
the same as 0.0.5000).
.TP
.BR "\-b" " or " "\-\-bootprog"
Specifies an entry in the ECKD boot configuration by defining the IPL boot
program selector. If omitted, '0' is used.
.TP
.BR "\-\-brchr"
Specifies the block on the DASD where the boot record is located. If omitted,
0 is used. The specification comprises comma-separated values for cylinder, head,
and record: "--brchr C,H,R". Alternatively, specifying "0" or "auto" makes the
bootloader determine the boot record location from the volume label.
.TP
.BR "\-L" " or " "\-\-loadparm"
The loadparm for the eckd re-IPL target is not used to control the ECKD boot
configuration that is defined by the
.BR zipl (8)
boot menu. Instead it can be used to control higher level boot loaders
like GRUB. For more details refer to distribution specific documentation.
.TP
.BR "\-c" " or " "\-\-clear"
Controls whether memory is cleared on re-IPL. Possible values are 0 to
disable and 1 to enable memory clearing on re-IPL.
Memory clearing is supported if the "clear" attribute is present in
/sys/firmware/reipl/eckd/.
.PP
\fBExamples:\fP
.br
1. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and boot
program selector 0:
\fB# chreipl eckd 0.0.7e78\fP
2. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and boot
program selector 2:
\fB# chreipl eckd -d 0.0.7e78 -b 2\fP
3. Next time reboot from the ECKD device with the bus-ID 0.0.7e78 and tell
the bootloader that the bootrecord is located in Cylinder 3, Head 0, Record 1:
\fB# chreipl eckd -d 0.0.7e78 --brchr 3,0,1\fP
.SH fcp
Use the fcp re-IPL target for SCSI disks that are accessed by the hardware
using Fibre Channel Protocol (FCP) channels.

View File

@@ -552,6 +552,33 @@ static const OSSL_PARAM *sk_prov_cached_params_build(
return provctx->cached_parms[index];
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static bool sk_prov_check_uint_param(const OSSL_PARAM params[],
const char *param_name,
const struct sk_prov_key *key,
int key_type,
unsigned int expected_value)
{
const OSSL_PARAM *p;
unsigned int value;
if (key == NULL)
return true;
if (key->type != key_type)
return true;
p = OSSL_PARAM_locate_const(params, param_name);
if (p == NULL)
return true;
if (OSSL_PARAM_get_uint(p, &value) != 1)
return true;
return value == expected_value;
}
#pragma GCC diagnostic pop
static struct sk_prov_op_ctx *sk_prov_op_newctx(struct sk_prov_ctx *provctx,
const char *propq,
int type)
@@ -850,6 +877,20 @@ static int sk_prov_asym_op_set_ctx_params(void *vctx, const OSSL_PARAM params[])
for (p = params; p != NULL && p->key != NULL; p++)
sk_debug_op_ctx(ctx, "param: %s", p->key);
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
/* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION is for RSA decrypt only */
if (!sk_prov_check_uint_param(params,
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
ctx->key, EVP_PKEY_RSA, 0) ||
!sk_prov_check_uint_param(params,
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
ctx->key, EVP_PKEY_RSA_PSS, 0)) {
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
"Implicit rejection is not supported");
return 0;
}
#endif
default_set_params_fn = (OSSL_FUNC_asym_cipher_set_ctx_params_fn *)
sk_prov_get_default_asym_func(ctx->provctx,
ctx->type,
@@ -1125,6 +1166,14 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
struct sk_prov_op_ctx *ctx = vctx;
struct sk_prov_key *key = vkey;
const OSSL_PARAM *p;
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
unsigned int implicit_rejection = 0;
OSSL_PARAM set_params[] = {
OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
&implicit_rejection),
OSSL_PARAM_END
};
#endif
if (ctx == NULL || key == NULL)
return 0;
@@ -1133,6 +1182,20 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
for (p = params; p != NULL && p->key != NULL; p++)
sk_debug_op_ctx(ctx, "param: %s", p->key);
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
/* OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION is for RSA decrypt only */
if (!sk_prov_check_uint_param(params,
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
key, EVP_PKEY_RSA, 0) ||
!sk_prov_check_uint_param(params,
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION,
key, EVP_PKEY_RSA_PSS, 0)) {
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
"Implicit rejection is not supported");
return 0;
}
#endif
default_decrypt_init_fn = (OSSL_FUNC_asym_cipher_decrypt_init_fn *)
sk_prov_get_default_asym_func(ctx->provctx,
ctx->type,
@@ -1155,6 +1218,26 @@ static int sk_prov_asym_op_decrypt_init(void *vctx, void *vkey,
return 0;
}
#ifdef OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION
if ((key->type == EVP_PKEY_RSA || key->type == EVP_PKEY_RSA_PSS) &&
key->secure_key != NULL) {
/*
* By default, implicit rejection is enabled for the default
* provider. We currently do not support implicit rejection with
* secure keys, so disable implicit rejection in the default
* provider operation context to report its status correctly
* with get-params.
*/
implicit_rejection = 0;
if (!sk_prov_asym_op_set_ctx_params(ctx, set_params)) {
sk_debug_op_ctx(ctx,
"ERROR: sk_prov_asym_op_set_ctx_params "
"failed");
return 0;
}
}
#endif
return 1;
}
@@ -1361,6 +1444,16 @@ static int sk_prov_sign_op_set_ctx_params(void *vctx, const OSSL_PARAM params[])
for (p = params; p != NULL && p->key != NULL; p++)
sk_debug_op_ctx(ctx, "param: %s", p->key);
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
ctx->key, EVP_PKEY_EC, 0)) {
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
"Deterministic signature is not supported");
return 0;
}
#endif
default_set_params_fn = (OSSL_FUNC_signature_set_ctx_params_fn *)
sk_prov_get_default_sign_func(ctx->provctx,
ctx->type, OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS);
@@ -1701,6 +1794,11 @@ static int sk_prov_sign_op_get_pss_saltlen(struct sk_prov_op_ctx *ctx,
salt_len = max_saltlen;
else if (strcmp(saltlen, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
salt_len = max_saltlen;
#ifdef OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX
else if (strcmp(saltlen,
OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
salt_len = MIN(max_saltlen, EVP_MD_size(mgf_md));
#endif
else
salt_len = atoi(saltlen);
@@ -1729,6 +1827,16 @@ static int sk_prov_sign_op_sign_init(void *vctx, void *vkey,
for (p = params; p != NULL && p->key != NULL; p++)
sk_debug_op_ctx(ctx, "param: %s", p->key);
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
key, EVP_PKEY_EC, 0)) {
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
"Deterministic signature is not supported");
return 0;
}
#endif
default_sign_init_fn = (OSSL_FUNC_signature_sign_init_fn *)
sk_prov_get_default_sign_func(ctx->provctx,
ctx->type,
@@ -1955,6 +2063,16 @@ static int sk_prov_sign_op_digest_sign_init(struct sk_prov_op_ctx *ctx,
for (p = params; p != NULL && p->key != NULL; p++)
sk_debug_op_ctx(ctx, "param: %s", p->key);
#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE
/* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */
if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE,
key, EVP_PKEY_EC, 0)) {
put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM,
"Deterministic signature is not supported");
return 0;
}
#endif
default_digest_sign_init_fn =
(OSSL_FUNC_signature_digest_sign_init_fn *)
sk_prov_get_default_sign_func(ctx->provctx,

View File

@@ -1,15 +0,0 @@
include ../common.mak
lib = libvmdump.a
all: $(lib)
objects = register_content.o dump.o lkcd_dump.o register_content.o \
vmdump_convert.o vm_dump.o
$(lib): $(objects)
install: all
clean:
rm -f *.o $(lib)

View File

@@ -1,65 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Dump base class
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "dump.h"
int debug = 0;
void s390TodToTimeval(uint64_t todval, struct timeval *xtime)
{
/* adjust todclock to 1970 */
todval -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
todval >>= 12;
xtime->tv_sec = todval / 1000000;
xtime->tv_usec = todval % 1000000;
}
Dump::Dump(const char *filename, const char *mode)
{
fh = fopen(filename, mode);
if(!fh){
throw(DumpErrnoException("Open dump file failed!"));
}
}
Dump::~Dump(void)
{
if(fh){
fclose(fh);
}
}
void ProgressBar::initProgress(void)
{
progressPercentage = -1;
}
void ProgressBar::displayProgress(uint64_t value, uint64_t maxValue)
{
char progress_bar[51];
int j;
if (progressPercentage == (int) (value * 100 / maxValue))
fprintf(stderr, "%6lld of %6lld |\r",
(long long) value, (long long) maxValue);
else { /* percent value has changed */
progressPercentage = (value * 100 / maxValue);
for (j = 0; j < progressPercentage / 2; j++)
progress_bar[j] = '#';
for (j = progressPercentage / 2; j < 50; j++)
progress_bar[j] = '-';
progress_bar[50] = 0;
fprintf(stderr, "%6lld of %6lld |%s| %3d%% \r",
(long long) value, (long long) maxValue,
progress_bar, progressPercentage);
}
}

View File

@@ -1,95 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Dump base class
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef DUMP_H
#define DUMP_H
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
extern int debug;
class DumpException
{
public:
DumpException(void) {
msg[0] = 0;
errorCode = 0;
}
DumpException(const char *m) {
sprintf(msg, "%s", m);
errorCode = 0;
}
const char *what(void) const { return msg; }
int code(void) const { return errorCode; }
protected:
char msg[2048];
int errorCode;
};
class DumpErrnoException : public DumpException
{
public:
DumpErrnoException(const char *m) {
sprintf(msg, "%s (%s)", m, strerror(errno));
errorCode = errno;
}
};
class Dump
{
public:
Dump(const char *filename, const char *mode);
Dump(void) : fh(0) {}
virtual ~Dump(void);
typedef enum {DT_VM32, DT_VM64, DT_VM64_BIG, DT_LKCD32, DT_LKCD64,
DT_UNKNOWN} DumpType;
virtual void readMem(char *buf, int size) = 0;
virtual int seekMem(uint64_t offset) = 0;
virtual uint64_t getMemSize(void) const = 0;
virtual struct timeval getDumpTime(void) const = 0;
protected:
FILE *fh;
};
class ProgressBar
{
public:
ProgressBar(void) { progressPercentage = -1; }
void initProgress(void);
void displayProgress(uint64_t value, uint64_t maxValue);
private:
int progressPercentage;
};
void s390TodToTimeval(uint64_t todval, struct timeval *xtime);
int vm_convert(const char *inputFileName, const char *outputFileName,
const char *progName);
static inline void dump_read(void *ptr, size_t size, size_t nmemb,
FILE *stream)
{
if (fread(ptr, size, nmemb, stream) != nmemb)
throw(DumpErrnoException("fread failed"));
}
static inline void dump_seek(FILE *stream, long offset, int whence)
{
if (fseek(stream, offset, whence) == -1)
throw(DumpErrnoException("fseek failed"));
}
#endif /* DUMP_H */

View File

@@ -1,261 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* LKCD dump classes: LKCDDump, LKCDDump32, LKCDDump64
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#include "lkcd_dump.h"
LKCDDump::LKCDDump(Dump* dump, const char* arch) {
referenceDump = dump;
dumpHeader.magic_number = DUMP_MAGIC_NUMBER;
dumpHeader.version = DUMP_VERSION_NUMBER;
dumpHeader.header_size = sizeof(struct _lkcd_dump_header);
dumpHeader.time.tv_sec = dump->getDumpTime().tv_sec;
dumpHeader.time.tv_usec = dump->getDumpTime().tv_usec;
strcpy(dumpHeader.utsname_machine, arch);
dumpHeader.memory_size = dump->getMemSize();
dumpHeader.memory_start = 0;
dumpHeader.memory_end = dump->getMemSize();
dumpHeader.num_dump_pages = dump->getMemSize()/0x1000;
dumpHeader.page_size = 0x1000;
dumpHeader.dump_compress = DUMP_COMPRESS_GZIP;
dumpHeader.dump_level = DUMP_LEVEL_ALL;
dumpHeaderAsm.magic_number = DUMP_ASM_MAGIC_NUMBER;
dumpHeaderAsm.version = 1;
dumpHeaderAsm.header_size = sizeof(dumpHeaderAsm);
}
int LKCDDump::compressGZIP(const char *old, uint32_t old_size, char *n,
uint32_t new_size)
{
unsigned long len = old_size;
int rc;
rc = compress((Bytef*)n, &len, (const Bytef*)old, new_size);
switch(rc) {
case Z_OK:
rc = len;
break;
case Z_BUF_ERROR:
/* In this case the compressed output is bigger than */
/* the uncompressed */
rc = GZIP_NOT_COMPRESSED;
break;
case Z_MEM_ERROR:
throw(DumpException("gzip call failed: out of memory"));
case Z_DATA_ERROR:
throw(DumpException("gzip call failed: input data " \
"corrupted!"));
default:
throw(DumpException("gzip call failed: unknown error"));
}
return rc;
}
void LKCDDump::writeDump(const char* fileName)
{
char dump_header_buf[DUMP_HEADER_SIZE] = {};
char dump_page_buf[DUMP_BUFFER_SIZE];
char dpcpage[DUMP_PAGE_SIZE];
uint32_t dp_size,dp_flags;
ProgressBar progressBar;
char buf[DUMP_PAGE_SIZE];
struct _dump_page dp;
uint64_t mem_loc = 0;
ssize_t buf_loc = 0;
int size, fd;
if (fileName == NULL) {
fd = STDOUT_FILENO;
} else {
fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR);
if (fd == -1) {
char msg[1024];
sprintf(msg, "Open of dump '%s' failed.", fileName);
throw(DumpErrnoException(msg));
}
}
/* write dump header */
memcpy(dump_header_buf, &dumpHeader, sizeof(dumpHeader));
memcpy(&dump_header_buf[sizeof(dumpHeader)], &dumpHeaderAsm,
sizeof(dumpHeaderAsm));
if (write(fd, dump_header_buf, sizeof(dump_header_buf)) !=
sizeof(dump_header_buf)) {
throw(DumpErrnoException("write failed"));
}
/* write memory */
referenceDump->seekMem(0);
while (mem_loc < dumpHeader.memory_size) {
referenceDump->readMem(buf, DUMP_PAGE_SIZE);
copyRegsToPage(mem_loc,buf);
memset(dpcpage, 0, DUMP_PAGE_SIZE);
/*
* Get the new compressed page size
*/
size = compressGZIP((char *)buf, DUMP_PAGE_SIZE,
(char *)dpcpage, DUMP_PAGE_SIZE);
/*
* If compression failed or compressed was ineffective,
* we write an uncompressed page
*/
if (size == GZIP_NOT_COMPRESSED) {
dp_flags = DUMP_DH_RAW;
dp_size = DUMP_PAGE_SIZE;
} else {
dp_flags = DUMP_DH_COMPRESSED;
dp_size = size;
}
dp.address = mem_loc;
dp.size = dp_size;
dp.flags = dp_flags;
memcpy((void *)(dump_page_buf + buf_loc),
(const void *)&dp, sizeof(dp));
buf_loc += sizeof(dp);
/*
* Copy the page of memory
*/
if (dp_flags & DUMP_DH_COMPRESSED) {
/* Copy the compressed page */
memcpy((void *)(dump_page_buf + buf_loc),
(const void *)dpcpage, dp_size);
} else {
/* Copy directly from memory */
memcpy((void *)(dump_page_buf + buf_loc),
(const void *)buf, dp_size);
}
buf_loc += dp_size;
if(write(fd, dump_page_buf, buf_loc) != buf_loc){
throw(DumpErrnoException("write failed"));
}
buf_loc = 0;
mem_loc += DUMP_PAGE_SIZE;
progressBar.displayProgress(mem_loc/(1024*1024),
dumpHeader.memory_size/(1024*1024));
}
/*
* Write end marker
*/
dp.address = 0x0;
dp.size = 0x0;
dp.flags = DUMP_DH_END;
if(write(fd, &dp, sizeof(dp)) != sizeof(dp)){
throw(DumpErrnoException("write failed"));
}
fprintf(stderr, "\n");
if (fd != STDOUT_FILENO)
close(fd);
}
struct timeval LKCDDump::getDumpTime(void) const
{
struct timeval rc;
rc.tv_sec = dumpHeader.time.tv_sec;
rc.tv_usec = dumpHeader.time.tv_usec;
return rc;
}
LKCDDump32::LKCDDump32(Dump* dump, const RegisterContent32& r)
: LKCDDump(dump,"s390")
{
unsigned int i;
dumpHeaderAsm.real_cpu_cnt = (uint32_t) r.getNumCpus();
for (i = 0; i < dumpHeaderAsm.real_cpu_cnt; i++) {
if (!r.regSets[i].prefix)
continue;
dumpHeaderAsm.lc_vec[i] = r.regSets[i].prefix;
dumpHeaderAsm.cpu_cnt++;
}
registerContent = r;
}
void LKCDDump32::copyRegsToPage(uint64_t offset, char *buf)
{
int cpu;
for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
if(offset == registerContent.regSets[cpu].prefix){
memcpy(buf+0xd8,&registerContent.regSets[cpu].cpuTimer,
sizeof(registerContent.regSets[cpu].cpuTimer));
memcpy(buf+0xe0,&registerContent.regSets[cpu].clkCmp,
sizeof(registerContent.regSets[cpu].clkCmp));
memcpy(buf+0x100,&registerContent.regSets[cpu].psw,
sizeof(registerContent.regSets[cpu].psw));
memcpy(buf+0x108,&registerContent.regSets[cpu].prefix,
sizeof(registerContent.regSets[cpu].prefix));
memcpy(buf+0x120,&registerContent.regSets[cpu].acrs,
sizeof(registerContent.regSets[cpu].acrs));
memcpy(buf+0x160,&registerContent.regSets[cpu].fprs,
sizeof(registerContent.regSets[cpu].fprs));
memcpy(buf+0x180,&registerContent.regSets[cpu].gprs,
sizeof(registerContent.regSets[cpu].gprs));
memcpy(buf+0x1c0,&registerContent.regSets[cpu].crs,
sizeof(registerContent.regSets[cpu].crs));
}
}
}
LKCDDump64::LKCDDump64(Dump* dump, const RegisterContent64& r)
: LKCDDump(dump,"s390x")
{
unsigned int i;
dumpHeaderAsm.real_cpu_cnt = (uint32_t) r.getNumCpus();
for (i = 0; i < dumpHeaderAsm.real_cpu_cnt; i++) {
if (!r.regSets[i].prefix)
continue;
dumpHeaderAsm.lc_vec[i] = r.regSets[i].prefix;
dumpHeaderAsm.cpu_cnt++;
}
registerContent = r;
}
void LKCDDump64::copyRegsToPage(uint64_t offset, char *buf)
{
int cpu;
for(cpu = 0; cpu < registerContent.getNumCpus(); cpu++){
if(offset == (registerContent.regSets[cpu].prefix + 0x1000)){
memcpy(buf+0x328,&registerContent.regSets[cpu].cpuTimer,
sizeof(registerContent.regSets[cpu].cpuTimer));
memcpy(buf+0x330,&registerContent.regSets[cpu].clkCmp,
sizeof(registerContent.regSets[cpu].clkCmp));
memcpy(buf+0x300,&registerContent.regSets[cpu].psw,
sizeof(registerContent.regSets[cpu].psw));
memcpy(buf+0x318,&registerContent.regSets[cpu].prefix,
sizeof(registerContent.regSets[cpu].prefix));
memcpy(buf+0x340,&registerContent.regSets[cpu].acrs,
sizeof(registerContent.regSets[cpu].acrs));
memcpy(buf+0x200,&registerContent.regSets[cpu].fprs,
sizeof(registerContent.regSets[cpu].fprs));
memcpy(buf+0x280,&registerContent.regSets[cpu].gprs,
sizeof(registerContent.regSets[cpu].gprs));
memcpy(buf+0x380,&registerContent.regSets[cpu].crs,
sizeof(registerContent.regSets[cpu].crs));
memcpy(buf+0x31c,&registerContent.regSets[cpu].fpCr,
sizeof(registerContent.regSets[cpu].fpCr));
}
}
}

View File

@@ -1,149 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* LKCD dump classes: LKCDDump, LKCDDump32, LKCDDump64
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef LKCD_DUMP_H
#define LKCD_DUMP_H
#include "lib/zt_common.h"
#include "dump.h"
#include "register_content.h"
#define UTS_LEN 65
#define DUMP_BUFFER_SIZE 0x2000 /* Size of dump buffer */
/* Standard header definitions */
#define DUMP_HEADER_SIZE 0x10000
#define DUMP_MAGIC_NUMBER 0xa8190173618f23edULL /* Dump magic number */
#define DUMP_ASM_MAGIC_NUMBER 0x733339302d64756dULL /* asm magic number */
#define DUMP_VERSION_NUMBER 0x8 /* Dump version number */
#define DUMP_PANIC_LEN 0x100 /* Dump panic string length */
/* Dump levels - type specific stuff added later */
#define DUMP_LEVEL_ALL 0x10 /* Dump all memory RAM and firmware */
/* Dump compression options */
#define DUMP_COMPRESS_GZIP 0x2 /* Use GZIP compression */
/* Dump header flags */
#define DUMP_DH_RAW 0x1 /* Raw page (no compression) */
#define DUMP_DH_COMPRESSED 0x2 /* Page is compressed */
#define DUMP_DH_END 0x4 /* End marker on a full dump */
/* Dump page defines */
#define DUMP_PAGE_SHIFT 12ULL
#define DUMP_PAGE_SIZE (1ULL << DUMP_PAGE_SHIFT)
#define GZIP_NOT_COMPRESSED -1
class LKCDDump : public Dump
{
public:
LKCDDump(Dump*, const char *);
virtual ~LKCDDump(void) {}
inline virtual void readMem(char *UNUSED(buf), int UNUSED(size))
{
throw(DumpException("LKCDDump::readMem() not implemented!"));
}
inline int seekMem(uint64_t UNUSED(offset))
{
throw(DumpException("LKCDDump::seekMem() not implemented!"));
}
inline virtual uint64_t getMemSize() const
{
return dumpHeader.memory_size;
}
virtual struct timeval getDumpTime(void) const;
virtual void writeDump(const char *fileName);
virtual void copyRegsToPage(uint64_t offset, char *buf) = 0;
protected:
struct _lkcd_dump_header {
uint64_t magic_number; /* dump magic number,unique to verify */
/* dump */
uint32_t version; /* version number of this dump */
uint32_t header_size; /* size of this header */
uint32_t dump_level; /* level of this dump */
uint32_t page_size; /* page size (e.g. 4K, 8K, 16K, etc.) */
uint64_t memory_size; /* size of entire physical memory */
uint64_t memory_start; /* start of physical memory */
uint64_t memory_end; /* end of physical memory */
/* the number of dump pages in this dump specifically */
uint32_t num_dump_pages;
char panic_string[DUMP_PANIC_LEN];
/* timeval depends on machine, two long values */
struct {uint64_t tv_sec;
uint64_t tv_usec;
} time; /* the time of the system crash */
/* the NEW utsname (uname) information -- in character form */
/* we do this so we don't have to include utsname.h */
/* plus it helps us be more architecture independent */
char utsname_sysname[UTS_LEN];
char utsname_nodename[UTS_LEN];
char utsname_release[UTS_LEN];
char utsname_version[UTS_LEN];
char utsname_machine[UTS_LEN];
char utsname_domainname[UTS_LEN];
uint64_t current_task;
uint32_t dump_compress; /* compression type used in this dump */
uint32_t dump_flags; /* any additional flags */
uint32_t dump_device; /* any additional flags */
uint64_t s390_asm_magic;
uint16_t cpu_cnt;
uint32_t lowcore_ptr[512];
} __packed;
struct _lkcd_dump_header_asm {
uint64_t magic_number;
uint32_t version;
uint32_t header_size;
uint16_t cpu_cnt;
uint16_t real_cpu_cnt;
uint32_t lc_vec[512];
} __packed;
struct _dump_page {
uint64_t address; /* the address of this dump page */
uint32_t size; /* the size of this dump page */
uint32_t flags; /* flags (DUMP_COMPRESSED, DUMP_RAW */
/* or DUMP_END) */
} __packed;
struct _lkcd_dump_header dumpHeader;
struct _lkcd_dump_header_asm dumpHeaderAsm;
private:
int compressGZIP(const char *old, uint32_t old_size, char *n,
uint32_t new_size);
Dump *referenceDump;
};
class LKCDDump32 : public LKCDDump
{
public:
LKCDDump32(Dump *dump, const RegisterContent32 &rc);
virtual void copyRegsToPage(uint64_t offset, char *buf);
private:
RegisterContent32 registerContent;
};
class LKCDDump64 : public LKCDDump
{
public:
LKCDDump64(Dump *dump, const RegisterContent64 &rc);
virtual void copyRegsToPage(uint64_t offset, char *buf);
private:
RegisterContent64 registerContent;
};
#endif /* LKCD_DUMP_H */

View File

@@ -1,76 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <string.h>
#include "register_content.h"
#include "dump.h"
RegisterContent32::RegisterContent32(void)
: regSets(), nrCpus(0)
{
}
RegisterContent32::RegisterContent32(const RegisterContent32& r)
{
nrCpus = r.nrCpus;
memcpy(&regSets,&r.regSets,sizeof(regSets));
}
void RegisterContent32::addRegisterSet(const RegisterSet32& rs)
{
if(nrCpus < MAX_CPUS){
regSets[nrCpus++] = rs;
} else {
throw(DumpException("RegisterContent32::addRegisterSet - " \
"No more register sets available"));
}
}
RegisterSet32 RegisterContent32::getRegisterSet(int cpu){
if(cpu <= nrCpus){
return regSets[cpu];
} else {
throw(DumpException("RegisterContent32::getRegisterSet - " \
"No register set for cpu"));
}
}
RegisterContent64::RegisterContent64(void)
: regSets(), nrCpus(0)
{
}
RegisterContent64::RegisterContent64(const RegisterContent64& r)
{
nrCpus = r.nrCpus;
memcpy(&regSets,&r.regSets,sizeof(regSets));
}
void RegisterContent64::addRegisterSet(const RegisterSet64& rs)
{
if(nrCpus < MAX_CPUS){
regSets[nrCpus++] = rs;
} else {
throw(DumpException("RegisterContent64::addRegisterSet - " \
"No more register sets available"));
}
}
RegisterSet64 RegisterContent64::getRegisterSet(int cpu)
{
if(cpu <= nrCpus){
return regSets[cpu];
} else {
throw(DumpException("RegisterContent64::getRegisterSet - " \
"No register set for cpu"));
}
}

View File

@@ -1,75 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef REGISTER_CONTENT_H
#define REGISTER_CONTENT_H
#include <stdint.h>
#define MAX_CPUS 512
class RegisterSet64
{
public:
uint64_t gprs[16];
uint64_t crs[16];
uint32_t acrs[16];
uint64_t fprs[16];
uint32_t fpCr;
uint64_t psw[2];
uint32_t prefix;
uint64_t cpuTimer;
uint64_t clkCmp;
};
class RegisterSet32
{
public:
uint32_t gprs[16];
uint32_t crs[16];
uint32_t acrs[16];
uint64_t fprs[4];
uint32_t psw[2];
uint32_t prefix;
uint64_t cpuTimer;
uint64_t clkCmp;
};
class RegisterContent64{
public:
RegisterContent64(void);
RegisterContent64(const RegisterContent64&);
RegisterSet64 getRegisterSet(int cpu);
void addRegisterSet(const RegisterSet64&);
inline int getNumCpus(void) const { return nrCpus; }
RegisterContent64& operator=(const RegisterContent64&) = default;
RegisterSet64 regSets[MAX_CPUS];
private:
int nrCpus;
};
class RegisterContent32{
public:
RegisterContent32(void);
RegisterContent32(const RegisterContent32&);
RegisterSet32 getRegisterSet(int cpu);
void addRegisterSet(const RegisterSet32&);
inline int getNumCpus(void) const { return nrCpus; }
RegisterContent32& operator=(const RegisterContent32&) = default;
RegisterSet32 regSets[MAX_CPUS];
private:
int nrCpus;
};
#endif /* REGISTER_CONTENT_H */

View File

@@ -1,624 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes:
* VMDump, VMDumpClassic, VMDump64, VMDump64Big, VMDump32
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <stdint.h>
#include <time.h>
#include "vm_dump.h"
Dump::DumpType VMDump::getDumpType(const char* inputFileName)
{
uint8_t fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
struct _fir_basic fir;
struct _fmbk fmbk;
struct _adsr adsr;
char msg[200];
FILE* fh;
fh = fopen(inputFileName,"r");
if (!fh) {
sprintf(msg,"Could not open '%s'",inputFileName);
throw DumpErrnoException(msg);
}
/* Record 1: adsr */
dump_read(&adsr, sizeof(adsr), 1, fh);
/* Record 2: fmbk */
dump_seek(fh, 0x1000, SEEK_SET);
if (fread(&fmbk, sizeof(fmbk), 1, fh) != 1) {
if(ferror(fh)) {
sprintf(msg,"Could not read header of vmdump '%s'",
inputFileName);
fclose(fh);
throw DumpErrnoException(msg);
} else{
sprintf(msg,"Input file '%s' is not a vmdump",
inputFileName);
fclose(fh);
throw DumpException(msg);
}
}
/* Check if this is a vmdump */
if (memcmp(fmbk.id, fmbk_id, 8) != 0 ||
adsr.dump_type != 0xe5d4c4e4d4d74040ULL) {
fclose(fh);
sprintf(msg, "Input file '%s' is not a vmdump", inputFileName);
throw DumpException(msg);
}
/* Record 3-7: fir */
dump_seek(fh, (fmbk.rec_nr_fir - 1) * 0x1000, SEEK_SET);
if(fread(&fir, sizeof(fir), 1, fh) != 1) {
if (ferror(fh)) {
sprintf(msg,"Could not read header of vmdump '%s'",
inputFileName);
fclose(fh);
throw DumpErrnoException(msg);
}
else{
sprintf(msg, "Could not read header of vmdump '%s'",
inputFileName);
fclose(fh);
throw DumpException(msg);
}
}
fclose(fh);
if (fir.fir_format == 0) {
return DT_VM32;
} else if (fir.fir_format == 0x02) {/*XXX && (fir.dump_format == 0x1))*/
return DT_VM64_BIG;
} else if (fir.fir_format == 0x82) {
return DT_VM64;
} else {
return DT_UNKNOWN;
}
}
VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
{
uint8_t fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
ebcdicAsciiConv = iconv_open("ISO-8859-1", "EBCDIC-US");
/* Record 1: adsrRecord */
dump_seek(fh,0,SEEK_SET);
dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
if(debug) {
char buf_asc[1024];
char buf[1024];
int i;
fprintf(stderr, "off=%d\n", adsrRecord.sec5_offset);
dump_seek(fh, adsrRecord.sec5_offset, SEEK_SET);
dump_read(buf, adsrRecord.sec5_len, 1, fh);
ebcAsc(buf, buf_asc, adsrRecord.sec5_len);
for (i=0; i < adsrRecord.sec5_len; i++) {
if ((buf_asc[i]==0) || iscntrl(buf_asc[i]))
buf_asc[i]=' ';
}
buf_asc[adsrRecord.sec5_len] = 0;
printf("symptom string1: %s\n",buf_asc);
}
/* Record 2: fmbk */
dump_seek(fh,0x1000,SEEK_SET);
dump_read(&fmbkRecord,sizeof(fmbkRecord),1,fh);
/* Check if this is a vmdump */
if(memcmp(fmbkRecord.id, fmbk_id, 8) != 0) {
throw DumpException("Input file is not a vmdump");
}
/* Record 3-7: fir records read by subclasses */
/* Record 8: albk */
dump_seek(fh,(fmbkRecord.rec_nr_access-1)*0x1000 ,SEEK_SET);
dump_read(&albkRecord,sizeof(albkRecord),1,fh);
}
struct timeval VMDump::getDumpTime(void) const
{
struct timeval rc;
s390TodToTimeval(adsrRecord.tod,&rc);
return rc;
}
void VMDump::printDebug(void)
{
struct timeval time;
char fmbk_id[8];
char albk_id[8];
s390TodToTimeval(adsrRecord.tod, &time);
/* adsr */
printf("time : %s\n", ctime(&time.tv_sec));
printf("stat1 : %x\n", adsrRecord.record_status_flag1);
printf("stat2 : %x\n", adsrRecord.record_status_flag2);
printf("sec 2 len: %i\n", adsrRecord.sec2_len);
printf("sec 2.1 len: %i/%i\n", adsrRecord.sec2_1_len,
adsrRecord.sec2_1_offset);
printf("sec 3 len: %i/%i\n", adsrRecord.sec3_len,
adsrRecord.sec3_offset);
printf("sec 4 len: %i/%i\n", adsrRecord.sec4_len,
adsrRecord.sec4_offset);
printf("sec 5 len: %i/%i\n", adsrRecord.sec5_len,
adsrRecord.sec5_offset);
printf("sec 6 len: %i/%i\n", adsrRecord.sec6_len,
adsrRecord.sec6_offset);
/* fmbk */
ebcAsc(fmbkRecord.id, fmbk_id, sizeof(fmbkRecord.id));
fmbk_id[7] = 0;
printf("id : %s\n", fmbk_id);
printf("fir rec nr: %i\n", fmbkRecord.rec_nr_fir);
printf("vec rec nr: %i\n", fmbkRecord.rec_nr_vector);
printf("access rec nr: %i\n", fmbkRecord.rec_nr_access);
/* albk */
ebcAsc(albkRecord.id, albk_id, sizeof(albkRecord.id));
albk_id[7]=0;
printf("ALBK id : %s\n",albk_id);
}
void VMDump::printInfo(void)
{
struct timeval time;
s390TodToTimeval(adsrRecord.tod,&time);
fprintf(stderr, " date........: %s",ctime(&time.tv_sec));
}
int VMDump::seekMem(uint64_t offset)
{
if (offset != 0) {
return -1;
}
pageOffset = 0;
return 0;
}
void VMDump::readMem(char* buf, int size)
{
int i;
if (pageOffset == 0)
dump_seek(fh, memoryStartRecord, SEEK_SET);
if (size % 0x1000 != 0) {
throw(DumpException("internal error: VMDump::readMem() " \
"can only handle sizes which are multiples of page size"));
}
for(i = 0; i < size; i += 0x1000) {
if(testPage(pageOffset)) {
dump_read(buf + i, 0x1000, 1, fh);
} else {
memset(buf + i, 0, 0x1000);
}
pageOffset += 1;
}
}
VMDump::~VMDump(void)
{
}
/*****************************************************************************/
/* VMDumpClassic: traditional 32/64 bit vmdump (before z/VM 5.2) */
/*****************************************************************************/
VMDumpClassic::VMDumpClassic(const char *fileName) : VMDump(fileName)
{
int storageKeyPages,bitMapPages;
pageOffset = 0;
/* Record 9: asibk */
dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
dump_read(&asibkRecord,sizeof(asibkRecord),1,fh);
/* Record 10: bitmaps */
dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
bitmap = new char[asibkRecord.storage_size_2GB / (0x1000 * 8)];
dump_read(bitmap,asibkRecord.storage_size_2GB / (0x1000*8),1,fh);
bitMapPages=asibkRecord.storage_size_2GB / (0x1000 * 8);
if (bitMapPages % 0x1000 != 0)
bitMapPages = bitMapPages/0x1000 + 1;
else
bitMapPages = bitMapPages/0x1000;
storageKeyPages=asibkRecord.storage_size_2GB / 0x1000;
if(storageKeyPages % 0x1000 != 0) {
storageKeyPages = storageKeyPages/0x1000 + 1;
} else {
storageKeyPages = storageKeyPages/0x1000;
}
/* Skip storage keys */
memoryStartRecord = (fmbkRecord.rec_nr_access + 1) *0x1000 /* 0x9000 */
+ (bitMapPages + storageKeyPages)*0x1000;
if(debug) {
printf("Mem Offset: %llx\n", (long long) memoryStartRecord);
}
}
void VMDumpClassic::printInfo(void)
{
VMDump::printInfo();
fprintf(stderr, " storage.....: %i MB\n",
asibkRecord.storage_size_2GB/(1024*1024));
}
VMDumpClassic::~VMDumpClassic(void)
{
delete bitmap;
}
/*****************************************************************************/
/* VMDump32: 32 bit vmdump */
/*****************************************************************************/
VMDump32::VMDump32(const char* filename) : VMDumpClassic(filename)
{
int i;
if(!fh) {
return;
}
dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
dump_read(&fir32Record,sizeof(fir32Record),1,fh);
fir32OtherRecords = new _fir_other_32[fir32Record.online_cpus];
for(i=0; i < fir32Record.online_cpus; i++) {
/* fir other */
dump_read(&fir32OtherRecords[i],sizeof(fir32OtherRecords[i]),1,
fh);
}
if(debug)
printDebug();
}
RegisterContent32 VMDump32::getRegisterContent(void)
{
RegisterContent32 rc;
RegisterSet32 rs;
int cpu;
/* First CPU */
memcpy(&rs.gprs, &fir32Record.gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir32Record.crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir32Record.acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir32Record.psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir32Record.prefix, sizeof(rs.prefix));
memcpy(&rs.fprs, &fir32Record.fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir32Record.cpu_timer, sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir32Record.clock_cmp, sizeof(rs.clkCmp));
rc.addRegisterSet(rs);
/* Other online cpus */
for(cpu = 0; cpu < fir32Record.online_cpus; cpu++) {
memcpy(&rs.gprs, &fir32OtherRecords[cpu].gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir32OtherRecords[cpu].crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir32OtherRecords[cpu].acrs, sizeof(rs.acrs));
/* No psw for ESA vmdumps */
rs.psw[0] = 0xdeadbeef;
rs.psw[1] = 0xdeadbeef;
memcpy(&rs.prefix, &fir32OtherRecords[cpu].prefix,
sizeof(rs.prefix));
memcpy(&rs.fprs, &fir32OtherRecords[cpu].fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir32OtherRecords[cpu].cpu_timer,
sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir32OtherRecords[cpu].clock_cmp,
sizeof(rs.clkCmp));
rc.addRegisterSet(rs);
}
return rc;
}
void VMDump32::printDebug(void)
{
int i;
VMDump::printDebug();
printf("prefix: %x\n", fir32Record.prefix);
printf("cpus: %x\n", fir32Record.online_cpus);
printf("psw: %08x %08x\n", fir32Record.psw[0], fir32Record.psw[1]);
for (i=0; i < fir32Record.online_cpus; i++) {
/* fir other */
printf("prefix (%i): %x\n", i, fir32OtherRecords[i].prefix);
}
}
void
VMDump32::printInfo(void)
{
fprintf(stderr, "vmdump information:\n");
fprintf(stderr, " architecture: 32 bit\n");
VMDumpClassic::printInfo();
fprintf(stderr, " cpus........: %x\n", fir32Record.online_cpus + 1);
}
VMDump32::~VMDump32(void)
{
delete fir32OtherRecords;
}
/*****************************************************************************/
/* VMDump64: 64 bit vmdump for old vmdump format (z/VM < 5.2) */
/*****************************************************************************/
VMDump64::VMDump64(const char* filename) : VMDumpClassic(filename)
{
int i;
if(!fh) {
return;
}
dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
dump_read(&fir64Record,sizeof(fir64Record),1,fh);
fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
dump_read(&fir64OtherRecords[i], sizeof(fir64OtherRecords[i]),
1, fh);
}
if(debug)
printDebug();
}
void VMDump64::printDebug(void)
{
int i;
VMDump::printDebug();
printf("prefix: %x\n", fir64Record.prefix);
printf("cpus: %x\n", fir64Record.online_cpus);
printf("psw: %016llx %016llx\n", (long long)fir64Record.psw[0],
(long long)fir64Record.psw[1]);
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
printf("prefix (%i): %x\n", i, fir64OtherRecords[i].prefix);
}
}
void VMDump64::printInfo(void)
{
fprintf(stderr, "vmdump information:\n");
fprintf(stderr, " architecture: 64 bit\n");
VMDumpClassic::printInfo();
fprintf(stderr, " cpus........: %x\n",fir64Record.online_cpus + 1);
}
RegisterContent64 VMDump64::getRegisterContent(void)
{
RegisterContent64 rc;
RegisterSet64 rs;
int cpu;
/* First CPU */
memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
rc.addRegisterSet(rs);
/* other online cpus */
for (cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
sizeof(rs.fpCr));
rc.addRegisterSet(rs);
}
return rc;
}
VMDump64::~VMDump64(void)
{
delete fir64OtherRecords;
}
/*****************************************************************************/
/* VMDump64Big: 64 bit vmdump with new big storage dump format */
/*****************************************************************************/
VMDump64Big::VMDump64Big(const char* filename) : VMDump(filename)
{
uint64_t pageNum, nrDumpedPages;
int i, j;
if(!fh) {
return;
}
/* Record 9: asibk */
dump_seek(fh, fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
dump_read(&asibkRecordNew, sizeof(asibkRecordNew), 1, fh);
/* Record 10: bitmaps: */
/* Read all bitmap pages and setup bitmap array */
pageNum = 0;
nrDumpedPages = asibkRecordNew.storage_size_def_store / 0x1000;
memoryStartRecord = (fmbkRecord.rec_nr_access + 1) * 0x1000;
bitmap = new char[asibkRecordNew.storage_size_def_store/(0x1000 * 8)];
if(!bitmap) {
throw(DumpErrnoException("out of memory"));
}
memset(bitmap,0,asibkRecordNew.storage_size_def_store/(0x1000 * 8));
dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
do {
char bmIndexPage[0x1000];
dump_read(bmIndexPage, sizeof(bmIndexPage), 1, fh);
memoryStartRecord += 0x1000;
for (i=0; i < 0x1000; i++) {
if(testBitmapPage(bmIndexPage, i)) {
char bmPage[0x1000];
dump_read(bmPage,sizeof(bmPage),1,fh);
memoryStartRecord += 0x1000;
for(j = 0; j < 0x1000; j++) {
if(testBitmapKeyPage(bmPage, j)) {
setPageBit(pageNum);
}
pageNum++;
if(pageNum == nrDumpedPages) {
goto all_bitmaps_read;
}
}
} else {
pageNum += 0x1000; /* Empty pages */
}
}
} while (pageNum < nrDumpedPages);
all_bitmaps_read:
if(debug)
printf("Mem Offset: %llx\n", (long long)memoryStartRecord);
dump_seek(fh, (fmbkRecord.rec_nr_fir-1)* 0x1000, SEEK_SET);
dump_read(&fir64Record, sizeof(fir64Record), 1, fh);
fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
dump_read(&fir64OtherRecords[i], sizeof(fir64OtherRecords[i]),
1, fh);
}
if(debug)
printDebug();
}
void VMDump64Big::printDebug(void)
{
int i;
VMDump::printDebug();
printf("prefix: %x\n", fir64Record.prefix);
printf("cpus: %x\n", fir64Record.online_cpus);
printf("psw: %016llx %016llx\n", (long long)fir64Record.psw[0],
(long long)fir64Record.psw[1]);
for (i=0; i < fir64Record.online_cpus; i++) {
/* fir other */
printf("prefix (%i): %x\n", i, fir64OtherRecords[i].prefix);
}
}
void VMDump64Big::printInfo(void)
{
fprintf(stderr, "vmdump information:\n");
fprintf(stderr, " architecture: 64 bit (big)\n");
fprintf(stderr, " storage.....: %lli MB\n",
(long long)asibkRecordNew.storage_size_def_store / (1024*1024));
VMDump::printInfo();
fprintf(stderr, " cpus........: %x\n", fir64Record.online_cpus + 1);
}
RegisterContent64 VMDump64Big::getRegisterContent(void)
{
RegisterContent64 rc;
RegisterSet64 rs;
int cpu;
/* First CPU */
memcpy(&rs.gprs, &fir64Record.gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64Record.crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64Record.acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64Record.psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64Record.prefix, sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64Record.fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64Record.cpu_timer, sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64Record.clock_cmp, sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64Record.fp_cntrl_reg, sizeof(rs.fpCr));
rc.addRegisterSet(rs);
/* other online cpus */
for(cpu = 0; cpu < fir64Record.online_cpus; cpu++) {
memcpy(&rs.gprs, &fir64OtherRecords[cpu].gprs, sizeof(rs.gprs));
memcpy(&rs.crs, &fir64OtherRecords[cpu].crs, sizeof(rs.crs));
memcpy(&rs.acrs, &fir64OtherRecords[cpu].acrs, sizeof(rs.acrs));
memcpy(&rs.psw, &fir64OtherRecords[cpu].psw, sizeof(rs.psw));
memcpy(&rs.prefix, &fir64OtherRecords[cpu].prefix,
sizeof(rs.prefix));
memcpy(&rs.fprs, &fir64OtherRecords[cpu].fprs, sizeof(rs.fprs));
memcpy(&rs.cpuTimer, &fir64OtherRecords[cpu].cpu_timer,
sizeof(rs.cpuTimer));
memcpy(&rs.clkCmp, &fir64OtherRecords[cpu].clock_cmp,
sizeof(rs.clkCmp));
memcpy(&rs.fpCr, &fir64OtherRecords[cpu].fp_cntrl_reg,
sizeof(rs.fpCr));
rc.addRegisterSet(rs);
}
return rc;
}
VMDump64Big::~VMDump64Big(void)
{
delete bitmap;
delete fir64OtherRecords;
}

View File

@@ -1,484 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Register content classes:
* VMDump, VMDumpClassic, VMDump64, VMDump64Big, VMDump32
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
/*===========================*
* The format of an vmdump: *
*===========================*
*---------------------------*
* Symptom Record *
* (ADSR COPY) Record 1 *
*---------------------------*
* Dump File Map Record *
* (HCPDFMBK COPY) Record 2 *
*---------------------------*
* Dump File Info Record *
* (HCPDFIR COPY) Records 3-7*
*---------------------------*
* Vector Registers *
* (optional) *
*---------------------------*
* Access Lists (HCPDALBK) *
*---------------------------*
* Address Space A *
* Information and Map *
* Record (HCPASIBK) *
*---------------------------*
* Address Space A *
* Bit Maps *
*---------------------------*
* Address Space A *
* Key Maps *
*---------------------------*
* Address Space A *
* Guest Storage *
*---------------------------*
* Additional Address Spaces *
* ASIBK *
* Bit Maps *
* Key Maps *
* Guest Storage *
* *NOTE* These probably *
* aren't in a Linux guest. *
*---------------------------*
*/
#ifndef VMDUMP_H
#define VMDUMP_H
#include <iconv.h>
#include <string.h>
#include "lib/zt_common.h"
#include "dump.h"
#include "register_content.h"
class VMDump : public Dump
{
public:
VMDump(const char *filename);
virtual ~VMDump(void);
virtual void readMem(char *buf, int size);
virtual int seekMem(uint64_t offset);
virtual struct timeval getDumpTime(void) const;
void printDebug(void);
void printInfo(void);
static DumpType getDumpType(const char *);
inline int testPage(uint64_t bit) const
{
return (bitmap[bit/8] & (1 << (7-(bit % 8))));
}
inline void setPageBit(uint64_t bit) const
{
bitmap[bit/8] |= (1 << (7-(bit % 8)));
}
protected:
/* Types */
struct _adsr {
/* Section 1*/
uint16_t sr;
uint32_t cpu_model;
char cpu_serial[6];
uint32_t time_zone_conversion_factor;
uint64_t tod;
char time_stamp_str[4];
char date_str[6];
char node_name[8];
char product_id[4];
char feature_level[8];
uint8_t record_status_flag1;
uint8_t record_status_flag2;
uint64_t dump_type;
/* Section 2*/
char arch_level[2];
uint16_t sec2_len;
uint16_t sec2_1_len;
uint16_t sec2_1_offset;
uint16_t sec3_len;
uint16_t sec3_offset;
uint16_t sec4_len;
uint16_t sec4_offset;
uint16_t sec5_len;
uint16_t sec5_offset;
uint16_t sec6_len;
uint16_t sec6_offset;
} __packed;
struct _fmbk {
char id[8];
uint32_t rec_nr_fir;
uint32_t rec_nr_vector;
uint32_t rec_nr_access;
uint32_t num_acc_recs;
uint32_t num_addr_spaces;
uint32_t rec_nr_asibk;
} __packed;
struct _fir_basic {
char filler1[15];
uint8_t dump_format;/* 0x1 for big storage dump, 0x2 for cp */
/* hard abend, 0x3 for cp soft abend */
char filler2[171];
uint8_t fir_format; /* 0x2 for big esame, 0x82 for esame, */
/* 0x00 for esa */
} __packed;
struct _albk {
char id[8];
} __packed;
/* Methods */
inline void ebcAsc(char *in, char *out, size_t size) const
{
size_t size_out = size;
size_t size_in = size;
size_t rc;
rc = iconv(ebcdicAsciiConv, &in, &size_in, &out, &size_out);
if (rc == (size_t) -1)
throw(DumpException("Code page translation EBCDIC-ASCII failed"));
}
/* Members */
struct _adsr adsrRecord;
struct _fmbk fmbkRecord;
struct _albk albkRecord;
uint64_t memoryStartRecord;
char *bitmap;
uint64_t pageOffset;
private:
iconv_t ebcdicAsciiConv;
};
class VMDumpClassic : public VMDump
{
public:
VMDumpClassic(const char *filename);
virtual ~VMDumpClassic(void);
void printInfo(void);
inline virtual uint64_t getMemSize(void) const
{
return (uint64_t)asibkRecord.storage_size_2GB;
}
protected:
/* Types */
struct _asibk {
char id[8];
char as_token[8];
char spaceid[33];
char reserved1[3];
uint32_t storage_size_2GB;
uint32_t dcss_bitmap_first_rec;
uint32_t byte_past_highest_defined_byte;
uint64_t format_of_as;
char dump_id[100];
uint32_t nr_of_recs_of_first_bit_map;
} __packed;
/* Members */
struct _asibk asibkRecord;
};
#define MAX_BKEY_PAGES 2
class VMDump64Big : public VMDump
{
public:
VMDump64Big(const char *filename);
virtual ~VMDump64Big(void);
RegisterContent64 getRegisterContent(void);
void printDebug(void);
void printInfo(void);
inline virtual uint64_t getMemSize(void) const
{
return (uint64_t)asibkRecordNew.storage_size_def_store;
}
private:
inline int testBitmapPage(char *page, uint64_t bit) const
{
return (page[bit/8] & (1 << (7-(bit % 8))));
}
inline int testBitmapKeyPage(char *page, uint64_t bit) const
{
return (page[bit] & 0x01);
}
/* types */
struct _asibk_64_new {
char id[8];
char as_token[8];
char spaceid[33];
char reserved1[2];
uint8_t asibk_format;
char filler1[12];
uint64_t storage_size_with_dcss;
uint64_t storage_size_def_store;
char filler2[136];
uint64_t online_storage_table[8]; /* for "def store config" */
uint64_t fence1;
uint64_t requested_range_table[8];
uint64_t fence2;
uint32_t record_number_of_first_bit_map; /* XXX */
} __packed;
struct _fir_64 {
char id[8];
uint64_t reserved1;
uint64_t gprs[16];
uint32_t prefix;
char reserved2[5];
uint64_t tod;
char reserved3[8];
uint64_t cpu_timer;
char reserved4[7];
uint8_t flag;
uint8_t type;
uint8_t complete;
uint8_t fir_format; /* 0x82 for esame - 0x00 for esa */
uint8_t cont_flags;
uint8_t crypto_domain_index_reg;
uint8_t virt_cpu_info;
uint8_t arch_mode_id;
uint64_t psw[2];
uint64_t crs[16];
uint64_t fprs[16];
uint8_t reserved5;
uint64_t clock_cmp;
char reserved6[3];
uint32_t tod_programmable_reg;
uint32_t reserved_for_dvf[20];
uint32_t acrs[16];
uint32_t storage_size_2GB;
uint32_t reserved7;
uint32_t hcpsys_addr;
uint32_t reserved8;
uint64_t storage_size;
uint32_t snap_area_map_blk;
uint32_t reserved9;
char loc_mem[256];
uint16_t online_cpus;
uint16_t cpu_addr;
uint16_t section_size_vector;
uint16_t reserved10;
char asit_primary[8];
char space_id_primary[33];
char reserved12[3];
uint16_t crypto_domain_index_mask;
uint16_t reserved11;
uint32_t fp_cntrl_reg;
uint32_t reserved13;
uint64_t reserved14[16];
} __packed;
struct _fir_other_64 {
uint16_t cpu_addr;
uint16_t vector_sec_size;
uint8_t crypto_index_reg;
uint8_t virt_cpu_info;
uint16_t crypto_index_mask;
uint32_t reserved1[2];
uint64_t fprs[16];
uint64_t gprs[16];
uint64_t psw[2];
uint32_t reserved2[2];
uint32_t prefix;
uint32_t fp_cntrl_reg;
uint32_t reserved3;
uint32_t tod;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint32_t reserved4[2];
uint32_t acrs[16];
uint64_t crs[16];
uint64_t mc_interrupt_code;
uint32_t reserved5;
uint32_t external_damage_code;
uint64_t mc_failing_storage_addr;
} __packed;
/* Members */
struct _asibk_64_new asibkRecordNew;
struct _fir_64 fir64Record;
struct _fir_other_64 *fir64OtherRecords;
};
class VMDump64 : public VMDumpClassic
{
public:
VMDump64(const char *filename);
virtual ~VMDump64(void);
RegisterContent64 getRegisterContent(void);
void printDebug(void);
void printInfo(void);
private:
/* Types */
struct _fir_64 {
char id[8];
uint64_t reserved1;
uint64_t gprs[16];
uint32_t prefix;
char reserved2[5];
uint64_t tod;
char reserved3[8];
uint64_t cpu_timer;
char reserved4[7];
uint8_t flag;
uint8_t type;
uint8_t complete;
uint8_t fir_format; /* 0x82 for esame - 0x00 for esa */
uint8_t cont_flags;
uint8_t crypto_domain_index_reg;
uint8_t virt_cpu_info;
uint8_t arch_mode_id;
uint64_t psw[2];
uint64_t crs[16];
uint64_t fprs[16];
uint8_t reserved5;
uint64_t clock_cmp;
char reserved6[3];
uint32_t tod_programmable_reg;
uint32_t reserved_for_dvf[20];
uint32_t acrs[16];
uint32_t storage_size_2GB;
uint32_t reserved7;
uint32_t hcpsys_addr;
uint32_t reserved8;
uint64_t storage_size;
uint32_t snap_area_map_blk;
uint32_t reserved9;
char loc_mem[256];
uint16_t online_cpus;
uint16_t cpu_addr;
uint16_t section_size_vector;
uint16_t reserved10;
char asit_primary[8];
char space_id_primary[33];
char reserved12[3];
uint16_t crypto_domain_index_mask;
uint16_t reserved11;
uint32_t fp_cntrl_reg;
uint32_t reserved13;
uint64_t reserved14[16];
} __packed;
struct _fir_other_64 {
uint16_t cpu_addr;
uint16_t vector_sec_size;
uint8_t crypto_index_reg;
uint8_t virt_cpu_info;
uint16_t crypto_index_mask;
uint32_t reserved1[2];
uint64_t fprs[16];
uint64_t gprs[16];
uint64_t psw[2];
uint32_t reserved2[2];
uint32_t prefix;
uint32_t fp_cntrl_reg;
uint32_t reserved3;
uint32_t tod;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint32_t reserved4[2];
uint32_t acrs[16];
uint64_t crs[16];
uint64_t mc_interrupt_code;
uint32_t reserved5;
uint32_t external_damage_code;
uint64_t mc_failing_storage_addr;
} __packed;
/* Members */
struct _fir_64 fir64Record;
struct _fir_other_64 *fir64OtherRecords;
};
class VMDump32 : public VMDumpClassic
{
public:
VMDump32(const char *filename);
virtual ~VMDump32(void);
RegisterContent32 getRegisterContent(void);
void printDebug(void);
void printInfo(void);
private:
/* Types */
struct _fir_32 {
uint32_t gprs[16];
uint32_t crs[16];
uint64_t fprs[4];
uint64_t tod;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint8_t flag;
uint8_t type;
uint8_t complete;
uint8_t fir_format;
uint32_t storage_size_2GB;
char loc_mem[256];
uint32_t prefix;
uint16_t online_cpus;
uint8_t cont_flags;
uint8_t crypto_domain_index_reg;
uint8_t virt_cpu_info;
uint8_t arch_mode_id;
uint16_t crypto_domain_index_mask;
uint32_t reserved1;
uint32_t snap_area_map_blk;
uint64_t reserved2;
uint32_t hcpsys_addr;
uint32_t reserved3[20];
uint32_t psw[2];
uint16_t cpu_addr;
uint16_t section_size_vector;
uint32_t acrs[16];
char asit_primary[8];
char space_id_primary[33];
char reserved4[131];
} __packed;
struct _fir_other_32 {
uint16_t cpu_addr;
uint16_t vector_sec_size;
uint32_t prefix;
uint8_t crypto_index_reg;
uint8_t virt_cpu_info;
uint16_t crypto_index_mask;
uint32_t reserved1;
uint64_t cpu_timer;
uint64_t clock_cmp;
uint64_t mc_interrupt_code;
uint64_t reserved2;
uint32_t mc_failing_storage_addr;
uint32_t machine_dependent_region_code;
uint32_t lixed_logout_area[4];
char reserved3[16];
uint32_t acrs[16];
uint64_t fprs[4];
uint32_t gprs[16];
uint32_t crs[16];
} __packed;
/* Members */
struct _fir_32 fir32Record;
struct _fir_other_32 *fir32OtherRecords;
};
#endif /* VMDUMP_H */

View File

@@ -1,72 +0,0 @@
/*
* vmdump - z/VM dump conversion library
*
* Dump convert function: Converts VMDUMP to LKCD dump
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "lkcd_dump.h"
#include "vm_dump.h"
int vmdump_convert(const char* inputFileName, const char* outputFileName,
const char* progName)
{
/* Do the conversion */
try {
switch(VMDump::getDumpType(inputFileName)){
case Dump::DT_VM64_BIG:
{
LKCDDump64* lkcddump;
VMDump64Big* vmdump;
vmdump = new VMDump64Big(inputFileName);
vmdump->printInfo();
lkcddump = new LKCDDump64(vmdump,
vmdump->getRegisterContent());
lkcddump->writeDump(outputFileName);
delete vmdump;
delete lkcddump;
break;
}
case Dump::DT_VM64:
{
LKCDDump64* lkcddump;
VMDump64* vmdump;
vmdump = new VMDump64(inputFileName);
vmdump->printInfo();
lkcddump = new LKCDDump64(vmdump,
vmdump->getRegisterContent());
lkcddump->writeDump(outputFileName);
delete vmdump;
delete lkcddump;
break;
}
case Dump::DT_VM32:
{
LKCDDump32* lkcddump;
VMDump32* vmdump;
vmdump = new VMDump32(inputFileName);
vmdump->printInfo();
lkcddump = new LKCDDump32(vmdump,
vmdump->getRegisterContent());
lkcddump->writeDump(outputFileName);
delete vmdump;
delete lkcddump;
break;
}
default:
throw DumpException("This is not a vmdump");
}
} catch (DumpException ex) {
printf("%s: %s\n", progName, ex.what());
fflush(stdout);
return 1;
}
return 0;
}

View File

@@ -15,13 +15,13 @@ install: install-scripts
install-scripts: $(SCRIPTS)
@if [ ! -d $(DESTDIR)$(NETBOOT_SAMPLEDIR) ]; then \
mkdir -p $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
fi; \
for i in $^; do \
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
< $$i >$(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
done

View File

@@ -11,10 +11,10 @@
/* Must be included before any other header */
#include "config.h"
#include <glib/gi18n.h>
#include <stdio.h>
#include "libpv/glib-helper.h"
#include <glib/gi18n.h>
#include "libpv/macros.h"
#include "lib/zt_common.h"

View File

@@ -5,7 +5,7 @@ all:
install: qethconf
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
< qethconf >$(DESTDIR)$(BINDIR)/qethconf; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/qethconf; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/qethconf; \
chmod 755 $(DESTDIR)$(BINDIR)/qethconf; \
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 qethconf.8 \

View File

@@ -2,7 +2,7 @@
#
# dbginfo.sh - Tool to collect runtime, configuration, and trace information
#
# Copyright IBM Corp. 2002, 2022
# Copyright IBM Corp. 2002, 2023
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
@@ -71,7 +71,7 @@ paramWORKDIR_BASE="/tmp" # initial default path
print_version() {
cat <<EOF
${SCRIPTNAME}: Debug information script version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2002, 2022
Copyright IBM Corp. 2002, 2023
EOF
}
@@ -525,6 +525,7 @@ CMDS="${CMDS}\
# product / distro specific commands
CMDS="${CMDS}\
:java -version\
:qemu-ga -V\
:SPident # SLES service package\
"
@@ -655,10 +656,10 @@ VM_CMDS="q userid\
:q quickdsp VMUSERID\
:q pcifunction\
:q vmrelocate\
:q syscontrol\
:ind load\
:ind sp\
:ind user\
:qemu-ga -V\
"
###############################################################################

View File

@@ -1,24 +0,0 @@
include ../common.mak
ALL_CPPFLAGS += -D_FILE_OFFSET_BITS=64
LDLIBS += -lz
all: vmconvert
libs = $(rootdir)/libvmdump/libvmdump.a
objects = vmconvert.o
vmconvert: $(objects) $(libs)
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) $(DESTDIR)$(MANDIR)/man1
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 vmconvert \
$(DESTDIR)$(USRBINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 vmconvert.1 \
$(DESTDIR)\$(MANDIR)/man1
clean:
rm -f *.o vmconvert
.PHONY: all install clean

View File

@@ -1,36 +0,0 @@
.\" Copyright 2017 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH VMCONVERT 1 "Apr 2006" "s390-tools"
.SH NAME
vmconvert \- convert VMDUMPs into lkcd dumps
.SH SYNOPSIS
.B vmconvert
-f \fIVMDUMPFILE\fR [-o \fIOUTPUTFILE\fR] [-h] [-v]
.B vmconvert
\fIVMDUMPFILE\fR [\fIOUTPUTFILE\fR]
.SH DESCRIPTION
.B vmconvert
is a tool to convert VMDUMPs into lkcd dumps, which can be analyzed by Linux
dumpanalysis tools (e.g. lcrash or crash).
.SH OPTIONS
.TP
.BR "\-h" " or " "\-\-help"
Print usage information, then exit.
.TP
.BR "\-v" " or " "\-\-version"
Print version information, then exit.
.TP
.BR "\-f VMDUMPFILE" " or " "\-\-file=VMDUMPFILE"
Use the specified VMDUMPFILE as input file.
.TP
.BR "\-o OUTPUTFILE" " or " "\-\-output=OUTPUTFILE"
Use the specified OUTPUTFILE as filename for the lkcd dump. The default
filename is 'dump.lkcd'

View File

@@ -1,135 +0,0 @@
/*
* vmconvert - Convert z/VM VMDUMPs into Linux lkcd dumps
*
* Main program
*
* Copyright IBM Corp. 2004, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <getopt.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "lib/vmdump.h"
#include "lib/zt_common.h"
static struct option longopts[] = {
{"file",required_argument,0,'f'},
{"help",no_argument,0,'h'},
{"version",no_argument,0,'v'},
{"output",required_argument,0,'o'},
{0,0,0,0}
};
#define OPTSTRING "f:o:vh"
extern char *optarg;
/* Version info */
static const char version_text[] = "vmconvert: vmdump converter tool version "\
RELEASE_STRING;
/* Copyright notice */
static const char copyright_notice[] = "Copyright IBM Corp. 2004, 2017";
/* Usage information */
static const char usage_text[] = \
"Usage: vmconvert -f VMDUMPFILE [-o OUTPUTFILE]\n" \
" vmconvert VMDUMPFILE [OUTPUTFILE]\n" \
"\n" \
"Convert a vmdump into a lkcd (linux kernel crash dumps) dump.\n" \
"\n" \
"-h, --help Print this help, then exit.\n" \
"-v, --version Print version information, then exit.\n" \
"-f, --file VMDUMPFILE The vmdump file VMDUMPFILE, which should be\n"\
" converted.\n" \
"-o, --output OUTPUTFILE The converted lkcd dump file OUTPUTFILE.\n"\
" The default file name is 'dump.lkcd'.\n";
/* Globals */
char inputFileName[1024];
char outputFileName[1024] = "dump.lkcd";
void
parseOpts(int argc, char* argv[])
{
int inputFileSet = 0;
int outputFileSet = 0;
int c, longIndex;
while((c = getopt_long(argc, argv, OPTSTRING, longopts,
&longIndex)) != -1) {
switch (c) {
case 'f':
strcpy(inputFileName, optarg);
inputFileSet = 1;
break;
case 'o':
strcpy(outputFileName, optarg);
outputFileSet = 1;
break;
case 'h':
printf("%s", usage_text);
exit(0);
case 'v':
printf("%s\n", version_text);
printf("%s\n", copyright_notice);
exit(0);
default:
fprintf(stderr, "Try 'vmconvert --help' for"
" more information.\n");
exit(1);
}
}
/* check for positional parameters */
if (optind < argc) {
int count = 0;
while (optind < argc){
if(!inputFileSet && count==0){
strcpy(inputFileName, argv[optind]);
inputFileSet = 1;
} else if(!outputFileSet && count==1){
strcpy(outputFileName, argv[optind]);
outputFileSet = 1;
} else if(count == 2){
printf("%s", usage_text);
exit(0);
}
count++;
optind++;
}
}
if(!inputFileSet){
printf("%s: input file required - use '-f' option!\n",argv[0]);
exit(1);
}
}
int
main(int argc, char* argv[])
{
struct stat s;
int rc;
parseOpts(argc,argv);
/* Check if output file already exists */
if(stat(outputFileName,&s) == 0){
char answer[100];
printf("%s: overwrite file '%s'? ",argv[0],outputFileName);
if(scanf("%s",answer) != 1)
exit(1);
if((strcmp(answer,"y") != 0) && (strcmp(answer,"yes") != 0))
exit(0);
}
rc = vmdump_convert(inputFileName, outputFileName, argv[0]);
if (!rc)
printf("'%s' has been written successfully.\n", outputFileName);
return rc;
}

View File

@@ -5,13 +5,12 @@ LDLIBS += -lz
all: vmur
libs = $(rootdir)/libvmdump/libvmdump.a \
$(rootdir)/libvmcp/libvmcp.a $(rootdir)/libutil/libutil.a
libs = $(rootdir)/libvmcp/libvmcp.a $(rootdir)/libutil/libutil.a
objects = vmur.o
vmur: $(objects) $(libs)
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(USRSBINDIR) $(DESTDIR)$(MANDIR)/man8

View File

@@ -50,7 +50,7 @@ Position a file at the top of a spool file queue
The \*v program requires the vmcp kernel module as prerequisite.
For the receive, punch, and print commands the vmur kernel module is also
required, and the corresponding z/VM virtual unit record devices
(in most cases 000c as reader, 000d as punch, and 000e as printer)
(in most cases 000c as reader, 000d as punch, and 000e as printer)
must be set online.
See
.BR chccwdev (8)
@@ -77,7 +77,7 @@ respective command context.
.IP "" 0
Synopsis:
.IP "" 2
receive [-fH] [-d dev_node] [-C class] [-t | -b sep.pad | -c]
receive [-fH] [-d dev_node] [-C class] [-t | -b sep.pad]
spoolid
[-O | outfile]
.PP
@@ -124,7 +124,7 @@ If omitted, /dev/vmrdr-0.0.000c is assumed.
.IP "" 0
\fB-t or --text\fR
.IP "" 2
Specifies that a text file requiring EBCDIC-to-ASCII conversion is to be
Specifies that a text file requiring EBCDIC-to-ASCII conversion is to be
received. Character sets IBM037 and ISO-8859-1 are used for the conversion.
An ASCII line feed character (0x0a) is inserted for each 80-byte input
record read from the z/VM reader. Trailing EBCDIC blanks (0x40) in the
@@ -150,8 +150,14 @@ using the appropriate character sets, for example:
.IP "" 0
\fB-c or --convert\fR
.IP "" 2
Specifies to convert the VMDUMP spool file into a
format appropriate for further analysis with crash or lcrash.
Dump file conversion has been removed from
.BR vmur (8)
and -c is no longer a valid option.
An error message is displayed and the program terminates.
Use
.BR zgetdump (8)
to convert VMDUMP files to a format
appropriate for further analysis with crash.
.SP
.IP "" 0
\fB-O or --stdout\fR
@@ -299,7 +305,7 @@ residual of the record is filled up with the specified padding byte.
If a line exceeds the record length, an error is printed.
.br
.BR iconv (1)
output can be piped to punch or print, for example:
output can be piped to punch or print, for example:
.IP "" 2
# iconv xyz -f ISO-8859-1 -t EBCDIC-US | vmur pun -b 0x25,0x40 -N abc
.SP
@@ -403,7 +409,7 @@ The following command argument is supported by \fBlist\fR:
\fBspoolid\fR
.IP "" 2
Identifies the z/VM spool file to be listed.
If omitted, all spool files on the specified queue are listed
If omitted, all spool files on the specified queue are listed
.PD
.IP "" 0
.SP
@@ -530,7 +536,7 @@ In the example below, the spool ID is 398:
.in +0.25in
.nf
# vmcp sp cons clo \(rs* rdr
RDR FILE 0398 SENT FROM LINUX025 CON WAS 0398 RECS 1872
RDR FILE 0398 SENT FROM LINUX025 CON WAS 0398 RECS 1872
.fi
.in -0.25in
.ft
@@ -605,6 +611,7 @@ Prepare re-IPL from the z/VM reader and reboot:
.SH "SEE ALSO"
.BR chccwdev (8),
.BR vmcp (8),
.BR iconv (1)
.BR iconv (1),
.BR zgetdump (8)
.I "Linux on System z - Device Drivers, Features, and Commands"

View File

@@ -77,7 +77,6 @@ struct vmur {
int force_specified;
int stdout_specified;
int hold_specified;
int convert_specified;
enum ur_action action;
int devno;
int ur_reclen;
@@ -183,8 +182,6 @@ static char HELP_TEXT[] =
"-t, --text Indicates text data causing EBCDIC to ASCII\n"
" conversion.\n"
"-b, --blocked Use blocked mode.\n"
"-c, --convert Specifies to convert VMDUMP file into a format\n"
" appropriate for further analysis with (l)crash.\n"
"-O, --stdout Write spool file to stdout.\n"
"-f, --force Overwrite files without prompt.\n"
"-H, --hold Hold spool file in reader after receive.\n"
@@ -814,7 +811,10 @@ static void parse_opts_receive(struct vmur *info, int argc, char *argv[])
++info->hold_specified;
break;
case 'c':
++info->convert_specified;
fprintf(stderr, "%s: Option '-c' is no longer valid. "
"Use zgetdump for dump file conversion.\n",
prog_name);
std_usage_exit();
break;
case 'C':
set_spool_class(info, optarg, 1);
@@ -834,14 +834,12 @@ static void parse_opts_receive(struct vmur *info, int argc, char *argv[])
CHECK_SPEC_MAX(info->force_specified, 1, "force");
CHECK_SPEC_MAX(info->hold_specified, 1, "hold");
CHECK_SPEC_MAX(info->stdout_specified, 1, "stdout");
CHECK_SPEC_MAX(info->convert_specified, 1, "convert");
CHECK_SPEC_MAX(info->spool_class_specified, 1, "class");
if (info->stdout_specified && info->file_name_specified)
ERR_EXIT("File name not allowed, when --stdout specified!\n");
if (info->blocked_specified + info->text_specified +
info->convert_specified > 1)
ERR_EXIT("Conflicting options: -b, -t and -c are mutually "
if (info->blocked_specified + info->text_specified)
ERR_EXIT("Conflicting options: -b and -t are mutually "
"exclusive.\n");
if (!info->spool_class_specified)
set_spool_class(info, "*", 1);
@@ -1749,25 +1747,6 @@ static void ur_receive(struct vmur *info)
}
type = get_spoolfile_fmt(info, &sfdata[0]);
if (info->convert_specified) {
if (type != TYPE_VMDUMP) {
ERR("Reader file %s does not have VMDUMP format, "
"conversion not possible.\n", info->spoolid);
goto fail;
} else {
close(fhi);
if (info->stdout_specified)
rc = vmdump_convert(info->devnode, NULL,
prog_name);
else
rc = vmdump_convert(info->devnode,
info->file_name, prog_name);
if (rc)
goto fail;
else
goto vm_convert_done;
}
}
if (type == TYPE_VMDUMP)
ERR("INFO: Reader file %s has VMDUMP format.\n", info->spoolid);
if (type == TYPE_NETDATA)
@@ -1819,7 +1798,6 @@ static void ur_receive(struct vmur *info)
if (fho != STDOUT_FILENO)
close(fho);
close(fhi);
vm_convert_done:
if (info->hold_specified)
close_reader(info, "HOLD");
else

View File

@@ -25,7 +25,7 @@ install-scripts: $(SCRIPTS)
cat $$i | \
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
>$(DESTDIR)$(BINDIR)/$$i; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/$$i; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(BINDIR)/$$i; \
chmod 755 $(DESTDIR)$(BINDIR)/$$i; \
done
@@ -34,15 +34,15 @@ install-usrsbin-scripts: $(USRSBIN_SCRIPTS)
cat $$i | \
sed -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
>$(DESTDIR)$(USRSBINDIR)/$$i; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(USRSBINDIR)/$$i; \
chmod 755 $(DESTDIR)$(USRSBINDIR)/$$i; \
done
install-manpages: $(MANPAGES)
@if [ ! -d $(DESTDIR)$(MANDIR) ]; then \
mkdir -p $(DESTDIR)$(MANDIR)/man8; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MANDIR); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(MANDIR)/man8; \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MANDIR); \
chown $(OWNER):$(GROUP) $(DESTDIR)$(MANDIR)/man8; \
chmod 755 $(DESTDIR)$(MANDIR); \
chmod 755 $(DESTDIR)$(MANDIR)/man8; \
fi; \

View File

@@ -218,6 +218,8 @@ X - Card/queue is providing EP11 functions (this is the EP11 Coprocessor mode).
.br
N - APXA available (ability to address more than 16 crypto cards and domains).
.br
H - Hardware support for stateless filtering available.
.br
F - Full function support (opposed to restricted function support, see below).
.br
R - Restricted function support. The F and R flag both reflect if a

View File

@@ -45,15 +45,17 @@ static struct lszcrypt_l {
#define CAP_RNG "Long RNG"
#define CAP_EP11 "EP11 Secure Key"
#define CAP_APMMS "AP bus max message size limit %ld Kb"
#define CAP_HSL "Hardware support for stateless filtering"
/*
* Card types
* Card types and other feature masks
*/
#define MASK_APSC 0x80000000
#define MASK_RSA4K 0x60000000
#define MASK_COPRO 0x10000000
#define MASK_ACCEL 0x08000000
#define MASK_EP11 0x04000000
#define MASK_HSL 0x01000000
/*
* Classification
@@ -66,20 +68,21 @@ static struct lszcrypt_l {
/*
* facility bits
*/
#define MAX_FAC_BITS 9
#define MAX_FAC_BITS 10
static struct fac_bits_s {
int mask;
char c;
} fac_bits[MAX_FAC_BITS] = {
{ 0x80000000, 'S' },
{ 0x40000000, 'M' },
{ 0x20000000, 'C' },
{ 0x10000000, 'D' },
{ 0x08000000, 'A' },
{ 0x04000000, 'X' },
{ 0x02000000, 'N' },
{ 0x00800000, 'F' },
{ 0x00400000, 'R' },
{ 0x80000000, 'S' }, /* bit 0 */
{ 0x40000000, 'M' }, /* bit 1 */
{ 0x20000000, 'C' }, /* bit 2 */
{ 0x10000000, 'D' }, /* bit 3, cca mode */
{ 0x08000000, 'A' }, /* bit 4, accel mode */
{ 0x04000000, 'X' }, /* bit 5, ep11 mode */
{ 0x02000000, 'N' }, /* bit 6, apxa */
{ 0x01000000, 'H' }, /* bit 7, stateless filtering by hardware */
{ 0x00800000, 'F' }, /* bit 8, full function set */
{ 0x00400000, 'R' }, /* bit 9, restricted function set */
};
/*
@@ -444,6 +447,8 @@ static void show_capability(const char *id_str)
printf("%s (%s)\n", CAP_CCA, cbuf);
else
printf("%s\n", CAP_CCA);
if (func_val & MASK_HSL)
printf("%s\n", CAP_HSL);
printf("%s\n", CAP_RNG);
} else if (func_val & MASK_EP11) {
printf("%s\n", CAP_EP11);

View File

@@ -144,6 +144,19 @@ static struct attrib zfcp_tattr_port_scan_backoff = {
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 4294967295)),
};
static struct attrib zfcp_tattr_ber_stop = {
.name = "ber_stop",
.title = "Stop FCP devices on bit-error threshold",
.desc =
"Control the automatic shutdown of FCP devices for FCP channels\n"
"that report a bit-error count in excess of its threshold:\n"
" 0: Stop on bit-error threshold is disabled\n"
" 1: Stop on bit-error threshold is enabled\n",
.nounload = 1,
.defval = "1",
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
};
/*
* ZFCP methods.
*/
@@ -171,6 +184,7 @@ static void all_bools_to_num(struct setting_list *list)
util_list_iterate(&list->list, s) {
if (s->attrib == &zfcp_tattr_allow_lun_scan ||
s->attrib == &zfcp_tattr_ber_stop ||
s->attrib == &zfcp_tattr_dif ||
s->attrib == &zfcp_tattr_dix ||
s->attrib == &zfcp_tattr_datarouter ||
@@ -313,6 +327,7 @@ struct devtype zfcp_devtype = {
&zfcp_tattr_no_auto_port_rescan,
&zfcp_tattr_port_scan_ratelimit,
&zfcp_tattr_port_scan_backoff,
&zfcp_tattr_ber_stop,
),
.unknown_type_attribs = 1,

View File

@@ -346,6 +346,7 @@ static struct attrib zfcp_lun_attr_scsi_queue_depth = {
"of a SCSI device. Note that storage servers typically limit the\n"
"total number of outstanding SCSI commands of all SCSI devices\n"
"accessed from all attached hosts.\n",
.defval = "32",
.accept = ACCEPT_ARRAY(ACCEPT_NUM_GE(1)),
};

View File

@@ -76,7 +76,7 @@ OBJECTS = zgetdump.o opts.o zg.o zg_error.o zg_print.o \
dt.o dt_s390sv.o dt_s390sv_ext.o \
dt_s390mv.o dt_s390mv_ext.o \
dt_scsi.o output.o \
ngdump.o dt_ngdump.o dfi_ngdump.o \
ngdump.o dt_ngdump.o dfi_ngdump.o dfi_vmdump.o \
pv_utils.o
ifneq ($(shell sh -c 'command -v pkg-config'),)
@@ -119,7 +119,9 @@ libs = $(rootdir)/libutil/libutil.a $(LIBPV)
all: $(BUILD_TARGETS)
zgetdump: .check_dep_zgetdump $(OBJECTS) $(libs)
$(OBJECTS): .check_dep_zgetdump
zgetdump: $(OBJECTS) $(libs)
skip-zgetdump:
echo " SKIP zgetdump due to unresolved dependencies"

208
zdump/df_vmdump.h Normal file
View File

@@ -0,0 +1,208 @@
/*
* zgetdump - Tool for copying and converting System z dumps
*
* VMDUMP format definitions
*
* Copyright IBM Corp. 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef DF_VMDUMP_H
#define DF_VMDUMP_H
/*
* The format of an vmdump
*
* Symptom Record: (ADSR COPY) Record 1
* Dump File Map Record: (HCPDFMBK COPY) Record 2
* Dump File Info Record: (HCPDFIR COPY) Records 3-7
* Vector Registers: (optional)
* Access Lists (HCPDALBK):
* Address Space A: Information and Map Record (HCPASIBK)
* Address Space A: Bit Maps
* Address Space A: Key Maps
* Address Space A: Guest Storage
* Additional Address Spaces (not in linux):
* - ASIBK
* - Bit Maps
* - Key Maps
* - Guest Storage
*/
/*
* Defines for VMDUMP magic numbers.
*/
/* ID 0xe2d9 --> 'S' 'R' */
const u8 ADSR_MAGIC[2] = { 0xe2, 0xd9 };
/* ID e5d4c4e4d4d74040 --> 'V' 'M' 'D' 'U' 'M' 'P' ' ' ' ' */
const u8 VMDUMP_MAGIC[8] = { 0xe5, 0xd4, 0xc4, 0xe4, 0xd4, 0xd7, 0x40, 0x40 };
/* ID c8c3d7c4c6d4c2d3 --> 'H' 'C' 'P' 'D' 'F' 'M' 'B' 'K' */
const u8 FMBK_MAGIC[8] = { 0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2 };
/* ID c8c3d7c4c6d4c2d3 --> 'H' 'C' 'P' 'D' 'A' 'L' 'B' 'K' */
const u8 ALBK_MAGIC[8] = { 0xc8, 0xc3, 0xd7, 0xc4, 0xc1, 0xd3, 0xc2, 0xd2 };
/*
* Layout of dump symptom record . The ADSR is always the first record in
* a dump file. Its size varies between 200 bytes and 4000 bytes
*/
struct vmd_adsr {
/* Section 1*/
u8 sr[sizeof(ADSR_MAGIC)];
u32 cpu_model;
u8 cpu_serial[6];
u32 time_zone_conversion_factor;
u64 tod;
u8 time_stamp_str[4];
u8 date_str[6];
u8 node_name[8];
u8 product_id[4];
u8 feature_level[8];
u8 record_status_flag1;
u8 record_status_flag2;
u8 dump_type[sizeof(VMDUMP_MAGIC)];
/* Section 2*/
u8 arch_level[2];
u16 sec2_len;
u16 sec2_1_len;
u16 sec2_1_offset;
u16 sec3_len;
u16 sec3_offset;
u16 sec4_len;
u16 sec4_offset;
u16 sec5_len;
u16 sec5_offset;
u16 sec6_len;
u16 sec6_offset;
} __packed;
/*
* Layout of Dump file map record. The DFMBK is always the second record in
* a dump file. Its size is 4 KB
*/
struct vmd_fmbk {
u8 id[sizeof(FMBK_MAGIC)];
u32 rec_nr_fir;
u32 rec_nr_vector;
u32 rec_nr_access;
u32 num_acc_recs;
u32 num_addr_spaces;
u32 rec_nr_asibk;
} __packed;
struct vmd_fir_basic { /* Dump file (basic) information record */
u8 filler1[15];
u8 dump_format; /* 0x1 --> big storage dump
* 0x2 --> cp hard abend
* 0x3 --> cp soft abend
*/
u8 filler2[171];
u8 fir_format; /* 0x02 --> big esame (only one supported)
* 0x82 --> esame
* 0x00 --> esa
*/
} __packed;
struct vmd_albk {
u8 id[sizeof(ALBK_MAGIC)];
} __packed;
struct vmd_asibk_64_new {
u8 id[8];
u8 as_token[8];
u8 spaceid[33];
u8 reserved1[2];
u8 asibk_format;
u8 filler1[12];
u64 storage_size_with_dcss;
u64 storage_size_def_store;
u8 filler2[136];
u64 online_storage_table[8]; /* For "def store config" */
u64 fence1;
u64 requested_range_table[8];
u64 fence2;
u32 record_number_of_first_bit_map;
} __packed;
struct vmd_fir_64 {
u8 id[8];
u64 reserved1;
u64 gprs[16];
u32 prefix;
u8 reserved2[5];
u64 tod;
u8 reserved3[8];
u64 cpu_timer;
u8 reserved4[7];
u8 flag;
u8 type;
u8 complete;
u8 fir_format; /* 0x82 for esame - 0x00 for esa */
u8 cont_flags;
u8 crypto_domain_index_reg;
u8 virt_cpu_info;
u8 arch_mode_id;
u64 psw[2];
u64 crs[16];
u64 fprs[16];
u8 reserved5;
u64 clock_cmp;
u8 reserved6[3];
u32 tod_programmable_reg;
u32 reserved_for_dvf[20];
u32 acrs[16];
u32 storage_size_2GB;
u32 reserved7;
u32 hcpsys_addr;
u32 reserved8;
u64 storage_size;
u32 snap_area_map_blk;
u32 reserved9;
u8 loc_mem[256];
u16 online_cpus;
u16 cpu_addr;
u16 section_size_vector;
u16 reserved10;
u8 asit_primary[8];
u8 space_id_primary[33];
u8 reserved12[3];
u16 crypto_domain_index_mask;
u16 reserved11;
u32 fp_cntrl_reg;
u32 reserved13;
u64 reserved14[16];
} __packed;
struct vmd_fir_other_64 {
u16 cpu_addr;
u16 vector_sec_size;
u8 crypto_index_reg;
u8 virt_cpu_info;
u16 crypto_index_mask;
u32 reserved1[2];
u64 fprs[16];
u64 gprs[16];
u64 psw[2];
u32 reserved2[2];
u32 prefix;
u32 fp_cntrl_reg;
u32 reserved3;
u32 tod;
u64 cpu_timer;
u64 clock_cmp;
u32 reserved4[2];
u32 acrs[16];
u64 crs[16];
u64 mc_interrupt_code;
u32 reserved5;
u32 external_damage_code;
u64 mc_failing_storage_addr;
} __packed;
#define DF_VMDUMP_HDR_SIZE \
(sizeof(struct vmd_adsr) + sizeof(struct vmd_fmbk) + sizeof(struct vmd_fir_basic) + \
sizeof(struct vmd_albk) + sizeof(struct vmd_asibk_64_new) + sizeof(struct vmd_fir_64))
#endif

View File

@@ -3,7 +3,7 @@
*
* Generic input dump format functions (DFI - Dump Format Input)
*
* Copyright IBM Corp. 2001, 2018
* Copyright IBM Corp. 2001, 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -34,6 +34,7 @@ static struct dfi *dfi_vec[] = {
&dfi_s390_ext,
&dfi_s390,
&dfi_lkcd,
&dfi_vmdump,
&dfi_pv_elf,
&dfi_elf,
&dfi_kdump,

View File

@@ -3,7 +3,7 @@
*
* Generic input dump format functions (DFI - Dump Format Input)
*
* Copyright IBM Corp. 2001, 2018
* Copyright IBM Corp. 2001, 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -255,5 +255,6 @@ extern struct dfi dfi_kdump;
extern struct dfi dfi_kdump_flat;
extern struct dfi dfi_devmem;
extern struct dfi dfi_ngdump;
extern struct dfi dfi_vmdump;
#endif /* DFI_H */

View File

@@ -21,7 +21,6 @@
#include <elf.h>
#include <errno.h>
#include <glib.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>

468
zdump/dfi_vmdump.c Normal file
View File

@@ -0,0 +1,468 @@
/*
* zgetdump - Tool for copying and converting IBM zSystem dumps
*
* VMDUMP input format - Convert a vmdump 64big format to internal format.
*
* Copyright IBM Corp. 2023
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <iconv.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <zlib.h>
#include "zgetdump.h"
#include "df_vmdump.h"
#include "dfi.h"
#include "dfi_mem_chunk.h"
#include "lib/util_log.h"
#include "lib/util_libc.h"
static struct {
struct vmd_adsr adsr; /* Dump file symptom record */
struct vmd_fmbk fmbk; /* Dump file map record */
struct vmd_fir_basic fir_basic; /* Dump file info record */
struct vmd_albk albk; /* Dump access list record */
struct vmd_asibk_64_new asibk_new;
struct vmd_fir_64 fir;
struct vmd_fir_other_64 *fir_other;
u64 memory_start_record;
u8 *bitmap;
} l;
/* Convert EBCDIC to ASCII. Used for very few selective fields. */
static void ebc_2_asc(u8 *in, u8 *out, const size_t size)
{
iconv_t etoa = iconv_open("ISO-8859-1", "EBCDIC-US");
size_t size_out = size;
size_t size_in = size;
size_t rc;
rc = iconv(etoa, (char **)&in, &size_in, (char **)&out, &size_out);
if (rc == (size_t)-1)
errx(EXIT_FAILURE, "Code page translation EBCDIC-ASCII failed");
iconv_close(etoa);
}
static void vmdump_tod_to_timeval(u64 todval, struct timeval *xtime)
{
/* adjust todclock to 1970 */
todval -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
todval >>= 12;
xtime->tv_sec = todval / 1000000;
xtime->tv_usec = todval % 1000000;
}
static void vmdump64big_debug(void)
{
u8 fmbk_id[sizeof(FMBK_MAGIC)];
u8 albk_id[sizeof(ALBK_MAGIC)];
struct timeval time;
util_log_print(UTIL_LOG_DEBUG, "Memory Offset: %#lx\n", l.memory_start_record);
util_log_print(UTIL_LOG_DEBUG, "Dumped Pages: %d\n",
l.asibk_new.storage_size_def_store / PAGE_SIZE);
/* adsr */
vmdump_tod_to_timeval(l.adsr.tod, &time);
util_log_print(UTIL_LOG_DEBUG, "Time: %s", ctime(&time.tv_sec));
util_log_print(UTIL_LOG_DEBUG, "Statusflag 1: %#x\n", l.adsr.record_status_flag1);
util_log_print(UTIL_LOG_DEBUG, "Statusflag 2: %#x\n", l.adsr.record_status_flag2);
util_log_print(UTIL_LOG_DEBUG, "Section 2 len: %i\n", l.adsr.sec2_len);
util_log_print(UTIL_LOG_DEBUG, "Section 2.1 len: %i/%i\n", l.adsr.sec2_1_len,
l.adsr.sec2_1_offset);
util_log_print(UTIL_LOG_DEBUG, "Section 3 len: %i/%i\n", l.adsr.sec3_len,
l.adsr.sec3_offset);
util_log_print(UTIL_LOG_DEBUG, "Section 4 len: %i/%i\n", l.adsr.sec4_len,
l.adsr.sec4_offset);
util_log_print(UTIL_LOG_DEBUG, "Section 5 len: %i/%i\n", l.adsr.sec5_len,
l.adsr.sec5_offset);
util_log_print(UTIL_LOG_DEBUG, "Section 6 len: %i/%i\n", l.adsr.sec6_len,
l.adsr.sec6_offset);
/* fmbk */
ebc_2_asc(l.fmbk.id, fmbk_id, sizeof(l.fmbk.id));
fmbk_id[sizeof(fmbk_id) - 1] = 0;
util_log_print(UTIL_LOG_DEBUG, "Fmbk id: %8.8s\n", fmbk_id);
util_log_print(UTIL_LOG_DEBUG, "Fir rec nr: %i\n", l.fmbk.rec_nr_fir);
util_log_print(UTIL_LOG_DEBUG, "Vec rec nr: %i\n", l.fmbk.rec_nr_vector);
util_log_print(UTIL_LOG_DEBUG, "Access rec nr: %i\n", l.fmbk.rec_nr_access);
/* albk */
ebc_2_asc(l.albk.id, albk_id, sizeof(l.albk.id));
albk_id[sizeof(albk_id) - 1] = 0;
util_log_print(UTIL_LOG_DEBUG, "Albk id: %8.8s\n", albk_id);
/* fir */
util_log_print(UTIL_LOG_DEBUG, "Cpus: %d\n", l.fir.online_cpus + 1);
util_log_print(UTIL_LOG_DEBUG, "PSW: %#016lx %#016lx\n", l.fir.psw[0], l.fir.psw[1]);
util_log_print(UTIL_LOG_DEBUG, "Prefix (CPU 0): %#010x\n", l.fir.prefix);
for (unsigned int i = 0; i < l.fir.online_cpus; i++)
util_log_print(UTIL_LOG_DEBUG, "Prefix (CPU %i): %#010x\n", i + 1,
l.fir_other[i].prefix);
}
static bool test_bitmap_key_page(u8 *page, const u64 bit)
{
return page[bit] & 0x01;
}
static bool test_page_bit(u8 *bitmap, const u64 bit)
{
return bitmap[bit / 8] & (1 << (7 - (bit % 8)));
}
static void set_page_bit(u8 *bitmap, const u64 bit)
{
bitmap[bit / 8] |= (1 << (7 - (bit % 8)));
}
/*
* Read VMDUMP headers, page index bit maps and page bit maps to
* construct a list of non-zero pages with memory locations. Zeroed pages
* are not bitmapped and are detected by memory location without bitmap
* entry.
*/
static void vmdump64big_init(void)
{
u64 page_num = 0, nr_dumped_pages;
size_t bitmap_sz;
unsigned int i;
/* Record 1: adsr */
zg_seek(g.fh, 0, ZG_CHECK);
zg_read(g.fh, &l.adsr, sizeof(l.adsr), ZG_CHECK);
if (g.opts.verbose) {
u8 buf_asc[1024], buf[1024];
zg_seek(g.fh, l.adsr.sec5_offset, ZG_CHECK);
zg_read(g.fh, buf, l.adsr.sec5_len, ZG_CHECK);
ebc_2_asc(buf, buf_asc, l.adsr.sec5_len);
for (i = 0; i < l.adsr.sec5_len; i++) {
if (buf_asc[i] == 0 || iscntrl(buf_asc[i]))
buf_asc[i] = ' ';
}
buf_asc[l.adsr.sec5_len] = 0;
util_log_print(UTIL_LOG_DEBUG, "Symptom string: %s\n", buf_asc);
}
/* Record 2: fmbk */
zg_seek(g.fh, PAGE_SIZE, ZG_CHECK);
zg_read(g.fh, &l.fmbk, sizeof(l.fmbk), ZG_CHECK);
/* Record 3-7: fir records */
zg_seek(g.fh, (l.fmbk.rec_nr_fir - 1) * PAGE_SIZE, ZG_CHECK);
zg_read(g.fh, &l.fir, sizeof(l.fir), ZG_CHECK);
bitmap_sz = sizeof(struct vmd_fir_other_64) * l.fir.online_cpus;
l.fir_other = util_zalloc(bitmap_sz);
for (i = 0; i < l.fir.online_cpus; i++)
zg_read(g.fh, &l.fir_other[i], sizeof(l.fir_other[0]), ZG_CHECK);
/* Record 8: albk */
zg_seek(g.fh, (l.fmbk.rec_nr_access - 1) * PAGE_SIZE, SEEK_SET);
zg_read(g.fh, &l.albk, sizeof(l.albk), SEEK_SET);
/* Record 9: asibk */
zg_seek(g.fh, l.fmbk.rec_nr_access * PAGE_SIZE, ZG_CHECK);
zg_read(g.fh, &l.asibk_new, sizeof(l.asibk_new), ZG_CHECK);
l.memory_start_record = (l.fmbk.rec_nr_access + 1) * PAGE_SIZE;
/*
* Record 10: bitmaps:
* Read all bitmap pages and setup bitmap array
*/
nr_dumped_pages = l.asibk_new.storage_size_def_store / PAGE_SIZE;
bitmap_sz = l.asibk_new.storage_size_def_store / (PAGE_SIZE * 8);
if (!bitmap_sz)
ERR_EXIT("Dump file inconsistent, no bitmap detected");
l.bitmap = util_zalloc(bitmap_sz);
zg_seek(g.fh, (l.fmbk.rec_nr_access + 1) * PAGE_SIZE, ZG_CHECK);
do {
u8 bm_index_page[PAGE_SIZE];
zg_read(g.fh, bm_index_page, sizeof(bm_index_page), ZG_CHECK);
l.memory_start_record += PAGE_SIZE;
for (i = 0; i < PAGE_SIZE; i++) {
if (test_page_bit(bm_index_page, i)) {
u8 bm_page[PAGE_SIZE];
zg_read(g.fh, bm_page, sizeof(bm_page), ZG_CHECK);
l.memory_start_record += PAGE_SIZE;
for (unsigned int j = 0; j < PAGE_SIZE; j++) {
if (page_num / 8 >= bitmap_sz)
ERR_EXIT("Dump file inconsistent,"
" corrupted bitmap detected");
if (test_bitmap_key_page(bm_page, j))
set_page_bit(l.bitmap, page_num);
page_num++;
if (page_num == nr_dumped_pages)
goto out;
}
} else {
page_num += PAGE_SIZE; /* Empty page */
}
}
} while (page_num < nr_dumped_pages);
out:
vmdump64big_debug();
}
static void display_register(const struct dfi_cpu *cpu)
{
unsigned int i;
util_log_print(UTIL_LOG_TRACE, "CPU %d\n", cpu->cpu_id);
for (i = 0; i < ARRAY_SIZE(cpu->gprs); i += 2)
util_log_print(UTIL_LOG_TRACE, "gpr%02d: %016lx\t gpr%02d: %016lx\n", i,
cpu->gprs[i], i + 1, cpu->gprs[i + 1]);
for (i = 0; i < ARRAY_SIZE(cpu->ctrs); i += 2)
util_log_print(UTIL_LOG_TRACE, "ctr%02d: %016lx\t ctr%02d: %016lx\n", i,
cpu->ctrs[i], i + 1, cpu->ctrs[i + 1]);
for (i = 0; i < ARRAY_SIZE(cpu->acrs); i += 2)
util_log_print(UTIL_LOG_TRACE, "acr%02d: %016lx\t acr%02d: %016lx\n", i,
cpu->acrs[i], i + 1, cpu->acrs[i + 1]);
for (i = 0; i < ARRAY_SIZE(cpu->fprs); i += 2)
util_log_print(UTIL_LOG_TRACE, "fpr%02d: %016lx\t fpr%02d: %016lx\n", i,
cpu->fprs[i], i + 1, cpu->fprs[i + 1]);
}
/*
* Read out register setting for each CPU.
*/
static void vmdump_read_register(int cpu_nr)
{
struct dfi_cpu *cpu;
if (cpu_nr >= l.fir.online_cpus + 1)
return;
cpu = dfi_cpu_alloc();
cpu->cpu_id = dfi_cpu_cnt();
if (!cpu_nr) { /* First CPU in fir */
memcpy(cpu->gprs, l.fir.gprs, sizeof(cpu->gprs));
memcpy(cpu->ctrs, &l.fir.crs, sizeof(cpu->ctrs));
memcpy(cpu->acrs, &l.fir.acrs, sizeof(cpu->acrs));
memcpy(cpu->fprs, &l.fir.fprs, sizeof(cpu->fprs));
memcpy(cpu->psw, &l.fir.psw, sizeof(cpu->psw));
memcpy(&cpu->prefix, &l.fir.prefix, sizeof(cpu->prefix));
memcpy(&cpu->timer, &l.fir.cpu_timer, sizeof(cpu->timer));
memcpy(&cpu->todcmp, &l.fir.clock_cmp, sizeof(cpu->todcmp));
memcpy(&cpu->fpc, &l.fir.fp_cntrl_reg, sizeof(cpu->fpc));
} else {
cpu_nr -= 1; /* Other CPUs start at offset 0 in fir_other */
memcpy(cpu->gprs, l.fir_other[cpu_nr].gprs, sizeof(cpu->gprs));
memcpy(cpu->ctrs, &l.fir_other[cpu_nr].crs, sizeof(cpu->ctrs));
memcpy(cpu->acrs, &l.fir_other[cpu_nr].acrs, sizeof(cpu->acrs));
memcpy(cpu->fprs, &l.fir_other[cpu_nr].fprs, sizeof(cpu->fprs));
memcpy(cpu->psw, &l.fir_other[cpu_nr].psw, sizeof(cpu->psw));
memcpy(&cpu->prefix, &l.fir_other[cpu_nr].prefix, sizeof(cpu->prefix));
memcpy(&cpu->timer, &l.fir_other[cpu_nr].cpu_timer, sizeof(cpu->timer));
memcpy(&cpu->todcmp, &l.fir_other[cpu_nr].clock_cmp, sizeof(cpu->todcmp));
memcpy(&cpu->fpc, &l.fir_other[cpu_nr].fp_cntrl_reg, sizeof(cpu->fpc));
}
display_register(cpu);
dfi_cpu_add(cpu);
}
/*
* Initialize z/VM VMDUMP file DFI. Check if the input file is vmdump file
* with format 64big. Other formats are not supported.
*/
static int read_vmdump_hdr(void)
{
if (zg_type(g.fh) != ZG_TYPE_FILE)
return -EBADF;
if (zg_size(g.fh) < DF_VMDUMP_HDR_SIZE)
return -ENODEV;
zg_read(g.fh, &l.adsr, sizeof(l.adsr), ZG_CHECK);
if (memcmp(l.adsr.sr, ADSR_MAGIC, sizeof(l.adsr.sr)))
return -EBADF; /* Not an ADSR record */
if (memcmp(l.adsr.dump_type, VMDUMP_MAGIC, sizeof(l.adsr.dump_type)))
return -EBADF; /* Not a vmdump */
zg_seek(g.fh, PAGE_SIZE, ZG_CHECK);
zg_read(g.fh, &l.fmbk, sizeof(l.fmbk), ZG_CHECK);
if (memcmp(l.fmbk.id, FMBK_MAGIC, sizeof(l.fmbk.id)))
return -EBADF; /* Not a FMBK record */
/* Record 3-7: fir */
zg_seek(g.fh, (l.fmbk.rec_nr_fir - 1) * PAGE_SIZE, ZG_CHECK);
zg_read(g.fh, &l.fir, sizeof(l.fir), ZG_CHECK);
switch (l.fir.fir_format) {
case 0x0:
case 0x82:
util_log_print(UTIL_LOG_DEBUG, "Vmdump %d bit format not supported anymore\n",
l.fir.fir_format ? 64 : 32);
return -EBADF;
case 0x2:
util_log_print(UTIL_LOG_DEBUG, "%s: Vmdump 64big format\n", g.opts.device);
break;
default:
util_log_print(UTIL_LOG_DEBUG, "Vmdump unknown format\n");
return -EBADF;
}
return 0;
}
/*
* Read vmdump page. Need to check if page was dumped or is located in a
* hole. Holes are ranges of pages full of zeroes.
* The vmdump file format has a 64KB header followed by some bitmaps for
* valid non-zero pages and the 4KB memory pages itself. Only non-zero pages
* are stored. The memory pages start at vmdump file location stored in
* member named memory_start_record.
*
* Bit map organization:
* Page 0: bitmap byte 0 bit 0 (most signification bit)
* Page 1: bitmap byte 0 bit 1 (seconds most signification bit)
* ...
* Page 15: bitmap byte 1 bit 7 (least signification bit)
*
* If a bit for a page is set, this page is stored in the vmdump file.
* The location in the file depends on the number of previous non-zero pages.
* If bitmap byte zero has value 1 and bitmap byte one has value 5, three
* bits are set and page 15 is located at file offset:
* memory_start_record + 2 * PAGE_SIZE.
*
* Calculate the number of bits set to determine the file location of a
* given page in the vmdump file.
*/
static unsigned int count_bits(u8 x)
{
unsigned int bits_set = 0;
while (x) {
bits_set += x & 1;
x >>= 1;
}
return bits_set;
}
/*
* Return byte offset into vmdump file for a given page number.
*/
static u64 bitmap_2_fileoffset(const u64 pg_num)
{
unsigned int bytes_to_check = pg_num / 8;
unsigned int bits_to_check = pg_num % 8;
unsigned int bits_set = 0;
/* Count bits set in first to second last byte */
for (unsigned int i = 0; i < bytes_to_check; i++)
bits_set += count_bits(l.bitmap[i]);
/* Count bits set in last byte */
bits_set += count_bits(l.bitmap[bytes_to_check] >> (8 - bits_to_check));
return bits_set * PAGE_SIZE;
}
static void read_page(const u64 pg_num, void *buf)
{
if (test_page_bit(l.bitmap, pg_num)) {
u64 file_off = bitmap_2_fileoffset(pg_num);
zg_seek(g.fh, l.memory_start_record + file_off, ZG_CHECK);
zg_read(g.fh, buf, PAGE_SIZE, ZG_CHECK);
} else {
memset(buf, 0, PAGE_SIZE);
}
}
/*
* VMDUMP mem chunk read callback
*/
static void dfi_vmdump_mem_chunk_read_fn(struct dfi_mem_chunk *mem_chunk, u64 off, void *buf,
u64 cnt)
{
u64 copied = 0, size, pg_nr, addr = off + mem_chunk->start;
char pg_buf[PAGE_SIZE];
unsigned int pg_off;
while (copied != cnt) {
pg_nr = (addr + copied) / PAGE_SIZE;
pg_off = (addr + copied) % PAGE_SIZE;
size = MIN(cnt - copied, PAGE_SIZE - pg_off);
read_page(pg_nr, pg_buf);
memcpy(buf + copied, &pg_buf[pg_off], size);
copied += size;
}
}
static void cpu_init(void)
{
dfi_cpu_info_init(DFI_CPU_CONTENT_ALL);
for (unsigned int i = 0; i <= l.fir.online_cpus; i++)
vmdump_read_register(i);
}
/*
* Walk bitmap and find consecutive bitstring consisting of '1' or '0'.
* Return its length.
*/
static u64 find_bitrange(u8 *bitmap, const u64 bit, const u64 max, const bool isset)
{
u64 pos;
for (pos = bit + 1; pos < max && test_page_bit(bitmap, pos) == isset; pos++)
;
return pos - bit;
}
static void mem_init(void)
{
u64 nr_dumped_pages = l.asibk_new.storage_size_def_store / PAGE_SIZE;
u64 pos, more;
for (pos = 0; pos < nr_dumped_pages;) {
bool isset = test_page_bit(l.bitmap, pos);
more = find_bitrange(l.bitmap, pos, nr_dumped_pages, isset);
dfi_mem_chunk_add(pos * PAGE_SIZE, more * PAGE_SIZE, NULL,
isset ? dfi_vmdump_mem_chunk_read_fn : dfi_mem_chunk_read_zero,
NULL);
pos += more;
}
}
static int dfi_vmdump_init(void)
{
if (read_vmdump_hdr())
return -ENODEV;
vmdump64big_init();
dfi_attr_version_set(l.fir.fir_format);
dfi_arch_set(DFI_ARCH_64);
dfi_attr_real_cpu_cnt_set(l.fir.online_cpus + 1);
mem_init();
cpu_init();
return 0;
}
/*
* z/VM VMDUMP DFI operations
*/
struct dfi dfi_vmdump = {
.name = "vmdump",
.init = dfi_vmdump_init,
.feat_bits = DFI_FEAT_SEEK | DFI_FEAT_COPY,
};

View File

@@ -674,7 +674,7 @@ struct _storage_state_mmap {
size_t mapped_size;
pv_tweak_component_t *tweak_components;
size_t num_tweaks;
gatomicrefcount ref_count;
int ref_count;
};
storage_state_mmap_t *storage_state_mmap_new(const int fd, const size_t file_size, const u64 offset,
@@ -733,14 +733,14 @@ storage_state_mmap_t *storage_state_mmap_new(const int fd, const size_t file_siz
ret->tweak_components = (pv_tweak_component_t *)(ptr + in_page_offset);
ret->num_tweaks = tweak_components_cnt;
ret->mapped_size = mmapped_size;
g_atomic_ref_count_init(&ret->ref_count);
ret->ref_count = 1;
return g_steal_pointer(&ret);
}
storage_state_mmap_t *storage_state_mmap_ref(storage_state_mmap_t *storage_state)
{
g_assert(storage_state);
g_atomic_ref_count_inc(&storage_state->ref_count);
g_atomic_int_inc(&storage_state->ref_count);
return storage_state;
}
@@ -748,7 +748,7 @@ void storage_state_mmap_unref(storage_state_mmap_t *storage_state)
{
if (!storage_state)
return;
if (storage_state->ref_count && !g_atomic_ref_count_dec(&storage_state->ref_count))
if (storage_state->ref_count && !g_atomic_int_dec_and_test(&storage_state->ref_count))
return;
if (storage_state->first_page_ptr) {
int rc = munmap(storage_state->first_page_ptr, storage_state->mapped_size);

View File

@@ -1,10 +1,10 @@
.\" Copyright 2022 IBM Corp.
.\" Copyright 2023 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH ZGETDUMP 8 "October 2022" "s390-tools"
.TH ZGETDUMP 8 "January 2023" "s390-tools"
.SH NAME
zgetdump \- Tool for copying and converting System z dumps
zgetdump \- Tool for copying and converting IBM zSystems dumps
.SH SYNOPSIS
\fBzgetdump\fR DUMP [-s SYS] [-f FMT] [-k KEY] > DUMP_FILE
@@ -107,6 +107,8 @@ source dump is located:
.IP " -" 12
Regular dump file (e.g. /dumps/dump.0)
.IP " -" 12
vmdump file (e. g. VMDUMP.FILE)
.IP " -" 12
DASD partition device node (e.g. /dev/dasdc1)
.IP " -" 12
DASD device node for multi-volume dump (e.g. /dev/dasdc)
@@ -186,16 +188,21 @@ Linux user space core dumps.
Protected virtualization vmcore dump in Executable and Linkable Format
.TP
.BR "s390"
This dump format is System z specific and is used for DASD and tape dumps.
This dump format is IBM zSystems specific and is used for DASD and tape dumps.
.TP
The following dump formats are supported for the source dump only:
.TP
.BR "s390_ext"
This dump format is System z specific and is used for DASD dumps only.
This dump format is IBM zSystems specific and is used for DASD dumps only.
.TP
.BR "vmdump"
Dumps with this format are created by the z/VM vmdump command
and stored in the reader device.
Use the "vmur" tool to extract such dumps from the reader
device and save them on disk.
.TP
.BR "lkcd"
This dump format is used by the Linux Kernel Crash Dumps (LKCD) project
and also on System z for the "vmconvert" dump tool.
This dump format is used by the Linux Kernel Crash Dumps (LKCD) project.
.TP
.BR "devmem"
On live systems the /dev/mem or /dev/crash device nodes can be used as source
@@ -505,5 +512,5 @@ attached SCSI disks can also be accessed directly without multipathing,
for example via the "/dev/disk/by-path/" device nodes.
.SH SEE ALSO
.BR zipl (8), crash (8), makedumpfile (8), dumpconf (8), vmconvert (1), vmur (8)
.BR zipl (8), crash (8), makedumpfile (8), dumpconf (8), vmur (8)
.BR fdisk (8), parted (8)

View File

@@ -19,7 +19,10 @@ FILES = fba0.bin fba1b.bin fba2.bin \
tape0.bin \
eckd2dump_sv.bin tape2dump.bin fba2dump.bin eckd2dump_mv.bin
all: data.o data.h tape0.bin stage3.bin
all: .loaders tape0.bin stage3.bin
.loaders: $(FILES)
touch .loaders
# Prevent make from using some default rules...
%: %.S
@@ -41,6 +44,15 @@ endif
%.lds: %.lds.S
$(CPP) -Wp,-MD,.$@.d,-MT,$@ $(INCLUDE_PARMS) -P -C -o $@ $<
fba0.exec eckd0_ldl.exec eckd0_cdl.exec tape0.exec: \
stage0.lds
eckd1.exec: \
stage1.lds
eckd1b.exec fba1b.exec: \
stage1b.lds
eckd2dump_sv.exec: \
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o \
libc.o ebcdic.o sclp.o entry.o stage2.lds
@@ -61,64 +73,14 @@ stage3.exec: head.o stage3.o kdump3.o libc.o ebcdic.o ebcdic_conv.o sclp.o \
sclp_stage3.o kdump.o entry.o stage3.lds
%.exec: %.o
STAGE=$$( \
echo $@ | awk ' \
match($$0,/[0-9]+b*/){ \
print substr($$0,RSTART,RLENGTH) \
}' \
); \
case $$STAGE in \
0) SFLAGS="-Wl,-Ttext,0";; \
1) SFLAGS="-Wl,-Ttext,0x18";; \
1b) SFLAGS="-Wl,-Ttext,0xE000";; \
2) SFLAGS="-Wl,-T,stage2.lds";; \
3) SFLAGS="-Wl,-T,stage3.lds";; \
esac; \
$(LINK) $$SFLAGS $(NO_PIE_LDFLAGS) -m64 -static -nostdlib $(filter %.o, $^) -o $@
$(LINK) -Wl,-T,$(filter %.lds,$^) $(NO_PIE_LDFLAGS) $(NO_WARN_RWX_SEGMENTS_LDFLAGS) -Wl,--build-id=none -m64 -static -nostdlib $(filter %.o, $^) -o $@
%.bin: %.exec
$(OBJCOPY) -O binary \
--only-section=.stage2.head \
--only-section=.text.dummy \
--only-section=.text.start \
--only-section=.text \
--only-section=.ex_table \
--only-section=.data \
--only-section=.rodata.str1.2 \
--only-section=.rodata.cst8 \
--only-section=.rodata \
--only-section=.stage2dump.tail \
--only-section=.eckd2dump_mv.tail \
--only-section=.fixup \
$< $@
$(OBJCOPY) -O binary $< $@
stage3.bin: stage3.exec
$(OBJCOPY) -O binary \
--only-section=.stage2.head \
--only-section=.text.dummy \
--only-section=.text.start \
--only-section=.text \
--only-section=.ex_table \
--only-section=.data \
--only-section=.rodata.str1.2 \
--only-section=.rodata.cst8 \
--only-section=.rodata \
--only-section=.stage2dump.tail \
--only-section=.eckd2dump_mv.tail \
--only-section=.fixup \
--only-section=.sb.trailer \
$< $@
data.o: $(FILES)
$(LINK) $(NO_PIE_LDFLAGS) -static -nostdlib -Wl,--relocatable -Wl,--format,binary -o data.o $(FILES)
data.h: data.o
rm -f data.h
$(NM) data.o | while read ADDR TYPE SYMBOL ; do \
echo "extern char $$SYMBOL;" >>data.h; done
clean:
rm -f -- *.o *.exec *.bin $(FILES) data.o data.h tape0.bin *.xxx *.yyy \
stage3.bin *.lds .*.lds.d
rm -f -- *.o *.exec *.bin $(FILES) tape0.bin *.xxx *.yyy \
stage3.bin *.lds .*.lds.d .loaders
.PHONY: all clean

View File

@@ -18,3 +18,8 @@ pgm_check_handler:
basr %r14,%r14
lmg %r0,%r15,__LC_SAVE_AREA_SYNC
lpswe __LC_PGM_OLD_PSW(%r0)
/* The code doesn't require an executable stack */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -28,3 +28,8 @@ _start:
brasl %r14,initialize
.Lstack: .long 0x10000-160
.previous
/* The code doesn't require an executable stack */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

18
zipl/boot/stage0.lds.S Normal file
View File

@@ -0,0 +1,18 @@
#include "boot/loaders_layout.h"
ENTRY(_start)
SECTIONS
{
. = STAGE0_LOAD_ADDRESS;
.text : {
*(.text .text.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

18
zipl/boot/stage1.lds.S Normal file
View File

@@ -0,0 +1,18 @@
#include "boot/loaders_layout.h"
ENTRY(_start)
SECTIONS
{
. = STAGE1_LOAD_ADDRESS;
.text : {
*(.text .text.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

18
zipl/boot/stage1b.lds.S Normal file
View File

@@ -0,0 +1,18 @@
#include "boot/loaders_layout.h"
ENTRY(_start)
SECTIONS
{
. = STAGE1B_LOAD_ADDRESS;
.text : {
*(.text .text.*)
}
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

View File

@@ -88,6 +88,10 @@ SECTIONS
}
__stack_end = .;
.eh_frame : { *(.eh_frame) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

View File

@@ -39,7 +39,6 @@ SECTIONS
__ex_table_start = .;
.ex_table : { *(.ex_table) }
__ex_table_stop = .;
.eh_frame : { *(.eh_frame) }
__bss_start = .;
.bss : { *(.bss) }
@@ -70,9 +69,10 @@ SECTIONS
}
__stack_end = .;
/* List this explicitly as otherwise .note.gnu.build-id will be
* put at 0x0 */
.notes : {
*(.note.*)
/* Sections to be discarded */
/DISCARD/ : {
*(.eh_frame)
*(.interp)
*(.note.GNU-stack)
}
}

View File

@@ -74,6 +74,9 @@ struct install_set {
int fd;
char *device;
char *filename;
char *dump_mount_point;
unsigned int dump_tmp_dir_created:1;
unsigned int dump_mounted:1;
struct disk_info *info;
disk_blockptr_t scsi_dump_sb_blockptr;
};

View File

@@ -25,6 +25,7 @@
#define BOOTMAP_FILENAME "bootmap"
#define BOOTMAP_TEMPLATE_FILENAME "bootmap_temp.XXXXXX"
#define DUMP_TEMP_MOUNT_POINT_NAME "zipl-dump-mount-point-XXXXXX"
#define DEFAULTBOOT_SECTION "defaultboot"

View File

@@ -4,14 +4,14 @@ include ../../common.mak
ALL_CPPFLAGS += -I../include -I../boot \
-DZFCPDUMP_IMAGE="STRINGIFY($(ZFCPDUMP_DIR)/$(ZFCPDUMP_IMAGE))" \
-DZFCPDUMP_INITRD="STRINGIFY($(ZFCPDUMP_DIR)/$(ZFCPDUMP_INITRD))" \
-D_FILE_OFFSET_BITS=64 $(NO_PIE_CFLAGS)
-D_FILE_OFFSET_BITS=64 $(NO_PIE_CFLAGS) -DBUILD_PATH="../boot"
ALL_LDFLAGS += -Wl,-z,noexecstack $(NO_PIE_LDFLAGS)
libs = $(rootdir)/libutil/libutil.a \
$(rootdir)/libvtoc/libvtoc.a \
objects = misc.o error.o scan.o job.o boot.o bootmap.o fs-map.o disk.o \
bootmap_header.o envblk.o install.o zipl.o $(rootdir)/zipl/boot/data.o
bootmap_header.o envblk.o install.o zipl.o
zipl_helpers = $(basename $(wildcard zipl_helper.*.c))
chreipl_helpers = $(subst zipl_,chreipl_, $(zipl_helpers))
@@ -19,6 +19,7 @@ zipl_stage3 = ../boot/stage3.bin
all: zipl zipl-editenv $(chreipl_helpers) $(zipl_stage3)
boot.o: ../boot/.loaders
zipl: $(objects) $(libs)
zipl_helper.device-mapper: $(rootdir)/libdasd/libdasd.a \
@@ -47,13 +48,8 @@ clean:
# Additional manual dependencies
.boot.o.d boot.o: ../boot/data.h
../boot/data.h:
$(MAKE) -C ../boot data.h
../boot/data.o:
$(MAKE) -C ../boot data.o
../boot/.loaders:
$(MAKE) -C ../boot .loaders
../boot/stage3.bin:
$(MAKE) -C ../boot stage3.bin

View File

@@ -17,27 +17,61 @@
#include <fcntl.h>
#include <sys/stat.h>
#include "lib/util_libc.h"
#include "boot/loaders_layout.h"
#include "stage3.h"
#include "../boot/data.h"
#include "boot.h"
#include "bootmap.h"
#include "error.h"
#include "misc.h"
#define DATA_SIZE(x) ((size_t) (&_binary_##x##_bin_end - &_binary_##x##_bin_start))
#define DATA_ADDR(x) (&_binary_##x##_bin_start)
/* Import a binary file */
/* clang-format off */
#define DATA_NAME(SYM, SUFFIX) _binary_##SYM##_bin##SUFFIX
#define DATA_SIZE(SYM) ((size_t)(&DATA_NAME(SYM, _end) - &DATA_NAME(SYM, _start)))
#define DATA_ADDR(SYM) (&DATA_NAME(SYM, _start))
#define BIN_FILE_PATH(FILE_NAME) STRINGIFY(BUILD_PATH) "/" STRINGIFY(FILE_NAME) ".bin"
#define IMPORT_DATA(SYM) \
extern const uint8_t DATA_NAME(SYM, _start); \
extern const uint8_t DATA_NAME(SYM, _end); \
asm(".section \".rodata\", \"a\", @progbits\n" \
".balign 4\n" \
".global " STRINGIFY(DATA_NAME(SYM, _start)) "\n" \
STRINGIFY(DATA_NAME(SYM, _start)) ":\n" \
".incbin \"" BIN_FILE_PATH(SYM) "\"\n" \
".global " STRINGIFY(DATA_NAME(SYM, _end)) "\n" \
STRINGIFY(DATA_NAME(SYM, _end)) ":\n" \
".balign 4\n" \
".previous\n")
/* clang-format on */
/* Stage 0 Loader */
IMPORT_DATA(eckd0_cdl);
IMPORT_DATA(eckd0_ldl);
IMPORT_DATA(fba0);
IMPORT_DATA(tape0);
/* Stage 1 Loader */
IMPORT_DATA(eckd1);
/* Stage 1b Loader */
IMPORT_DATA(eckd1b);
IMPORT_DATA(fba1b);
/* Stage 2 Loader */
IMPORT_DATA(eckd2);
IMPORT_DATA(fba2);
/* Stage 2 Dump Loader */
IMPORT_DATA(eckd2dump_mv);
IMPORT_DATA(eckd2dump_sv);
IMPORT_DATA(fba2dump);
IMPORT_DATA(tape2dump);
#define STAGE2_MAX_SIZE 0x3000
#define STAGE1B_LOAD_ADDR 0xe000
#define CCW_FLAG_CC 0x40
#define CCW_FLAG_SLI 0x20
#define FBA_BLK_SIZE 512
static struct boot_ccw0 tic_to_stage1b = {
.cmd = 0x08, /* tic */
.address_lo = STAGE1B_LOAD_ADDR,
.address_lo = STAGE1B_LOAD_ADDRESS,
};
/* Check sizes of internal objects. Return 0 if everything is correct,
@@ -133,8 +167,7 @@ boot_init_fba_stage0(struct boot_fba_stage0 *stage0,
for (i = 0; i < stage1b_count; i++) {
stage0->locdata[i].blocknr =
(uint32_t) stage1b_list[i].linear.block;
stage0->locread[i].read.address_lo =
STAGE1B_LOAD_ADDR + i * FBA_BLK_SIZE;
stage0->locread[i].read.address_lo = STAGE1B_LOAD_ADDRESS + i * FBA_BLK_SIZE;
}
/* Terminate CCW chain: Tic to stage 1b */
memcpy(&stage0->locread[i], &tic_to_stage1b, sizeof(tic_to_stage1b));
@@ -178,7 +211,7 @@ boot_init_eckd_stage1(struct boot_eckd_stage1 *stage1,
((stage1b_list[i].chs.cyl >> 12) & 0xfff0);
stage1->seek[i].sec = stage1b_list[i].chs.sec;
stage1->ssrt[i].read.address_lo =
STAGE1B_LOAD_ADDR + i * stage1b_list[i].chs.size;
STAGE1B_LOAD_ADDRESS + i * stage1b_list[i].chs.size;
stage1->ssrt[i].read.flags = CCW_FLAG_CC | CCW_FLAG_SLI;
}
/* Terminate CCW chain: Tic to stage 1b */

View File

@@ -9,6 +9,7 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
@@ -952,30 +953,10 @@ static int add_segment_program(struct install_set *bis,
#define DUMP_PARAM_MAX_LEN 896
static char *
create_dump_parmline(const char* parmline, const char* root_dev,
uint64_t mem, int max_cpus)
{
char* result;
result = misc_malloc(DUMP_PARAM_MAX_LEN);
if (!result)
return NULL;
snprintf(result, DUMP_PARAM_MAX_LEN, "%s%sroot=%s dump_mem=%lld "
"possible_cpus=%d cgroup_disable=memory ",
parmline ? parmline : "", parmline ? " " : "", root_dev,
(unsigned long long) mem, max_cpus);
result[DUMP_PARAM_MAX_LEN - 1] = 0;
return result;
}
static int
get_dump_parmline(char *partition, char *parameters,
struct disk_info *target_info,
struct job_target_data *target, char **result)
check_dump_device_late(char *partition, struct disk_info *target_info,
struct job_target_data *target)
{
char* buffer;
struct disk_info* info;
int rc;
@@ -998,15 +979,7 @@ get_dump_parmline(char *partition, char *parameters,
disk_free_info(info);
return -1;
}
if (is_ngdump_enabled(partition, target))
buffer = misc_strdup(parameters);
else
buffer = create_dump_parmline(parameters, "/dev/ram0",
info->partnum, 1);
disk_free_info(info);
if (buffer == NULL)
return -1;
*result = buffer;
return 0;
}
@@ -1024,10 +997,10 @@ static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
ipl.common = dump->common;
/* Get file system dump parmline */
rc = get_dump_parmline(dump->device, dump->common.parmline,
bis->info, target, &ipl.common.parmline);
rc = check_dump_device_late(dump->device, bis->info, target);
if (rc)
return rc;
ipl.common.parmline = dump->common.parmline;
ipl.common.parm_addr = dump->common.parm_addr;
return add_ipl_program(bis, NULL, false, NULL, &ipl, program,
verbose, 1, type, target, SECURE_BOOT_DISABLED,
@@ -1711,7 +1684,6 @@ static int bootmap_create_device_ngdump(struct job_data *job,
struct install_set *bis,
int program_table_id)
{
char mount_point[] = "/tmp/zipl-dump-mount-point-XXXXXX";
struct disk_info *info;
int rc;
@@ -1723,12 +1695,23 @@ static int bootmap_create_device_ngdump(struct job_data *job,
return -1;
if (check_dump_device(job, info, bis->device))
return -1;
/* Create a mount point directory */
if (mkdtemp(mount_point) == NULL) {
bis->dump_mount_point = misc_make_path("/tmp",
DUMP_TEMP_MOUNT_POINT_NAME);
if (!bis->dump_mount_point) {
error_reason(strerror(errno));
error_text("Could not create mount point '%s'", mount_point);
error_text("Could not make path for '%s'",
DUMP_TEMP_MOUNT_POINT_NAME);
return -1;
}
/* Create a mount point directory */
if (mkdtemp(bis->dump_mount_point) == NULL) {
error_reason(strerror(errno));
error_text("Could not create mount point '%s'",
bis->dump_mount_point);
return -1;
}
bis->dump_tmp_dir_created = 1;
if (!dry_run) {
char *cmd = NULL;
util_asprintf(&cmd, "mkfs.%s -qF %s >/dev/null",
@@ -1742,33 +1725,27 @@ static int bootmap_create_device_ngdump(struct job_data *job,
error_reason(strerror(errno));
error_text("Could not format partition '%s':",
job->data.dump.device);
goto out_rmdir;
return -1;
}
}
/*
* Mount partition where bootmap file and also a dump file will
* be stored.
*/
if (mount(job->data.dump.device, mount_point, NGDUMP_FSTYPE, 0, NULL)) {
if (mount(job->data.dump.device, bis->dump_mount_point,
NGDUMP_FSTYPE, 0, NULL)) {
error_reason(strerror(errno));
error_text("Could not mount partition '%s':",
job->data.dump.device);
goto out_rmdir;
return -1;
}
if (bootmap_create_file(job, mount_point, bis, program_table_id))
goto out_umount;
if (ngdump_create_meta(mount_point))
goto out_umount;
/* Cleanup */
umount(mount_point);
rmdir(mount_point);
bis->dump_mounted = 1;
if (bootmap_create_file(job, bis->dump_mount_point,
bis, program_table_id))
return -1;
if (ngdump_create_meta(bis->dump_mount_point))
return -1;
return 0;
out_umount:
umount(mount_point);
out_rmdir:
rmdir(mount_point);
return -1;
}
@@ -1835,6 +1812,9 @@ int prepare_bootloader(struct job_data *job, struct install_set *bis)
return rc;
}
/**
* Release all resources accumulated along the installation process
*/
void free_bootloader(struct install_set *bis)
{
int i, j;
@@ -1853,4 +1833,13 @@ void free_bootloader(struct install_set *bis)
free(bis->filename);
misc_free_temp_dev(bis->device);
disk_free_info(bis->info);
if (bis->dump_mount_point) {
if (bis->dump_mounted && umount(bis->dump_mount_point))
warn("Could not umount dump device at %s",
bis->dump_mount_point);
if (bis->dump_tmp_dir_created && rmdir(bis->dump_mount_point))
warn("Could not remove directory %s",
bis->dump_mount_point);
free(bis->dump_mount_point);
}
}

View File

@@ -30,6 +30,8 @@
#include "zipl.h"
#include "envblk.h"
#define DEFAULT_DUMP_PARMLINE "root=/dev/ram0 possible_cpus=1 cgroup_disable=memory"
const char *blsdir;
/* Command line options */
@@ -891,6 +893,7 @@ check_job_dump_images(struct job_dump_data* dump, char* name)
dump->common.ramdisk_addr = UNSPECIFIED_ADDRESS;
}
dump->common.parmline = misc_strdup(DEFAULT_DUMP_PARMLINE);
dump->common.parm_addr = UNSPECIFIED_ADDRESS;
return finalize_common_address_data(&dump->common, name);
}

View File

@@ -35,7 +35,7 @@
* Definitions for the EP11 library
*/
#define EP11_LIBRARY_NAME "libep11.so"
#define EP11_LIBRARY_VERSION 3
#define EP11_LIBRARY_VERSION 4
#define EP11_WEB_PAGE "http://www.ibm.com/security/cryptocards"
/**