Compare commits

..

178 Commits

Author SHA1 Message Date
Ingo Franzki
5e07b30bdf New release s390-tools-2.41.0
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 15:33:48 +01:00
Jan Höppner
35596e1dd7 rust: Update Cargo.lock
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 12:04:50 +01:00
Marc Hartmayer
0311cf7c5e pvimg/man: Update 'pvimg info' manpage
Update the manpage of the 'pvimg info' command.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:49:00 +01:00
Marc Hartmayer
78fdf56d38 pvimg: Improve long help message of the info subcommand
Improve the long help message of the 'info' subcommand.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:49:00 +01:00
Marc Hartmayer
b5c4ff68d7 pvimg: Document the JSON output format of the info command
Add documentation for the JSON structure outputted by 'pvimg info
--format=json ...'.

Created with assistance from IBM Bob AI.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:49:00 +01:00
Marc Hartmayer
3b0fc8cfda pvimg: Add '--print-schema <FORMAT>' option to 'pvimg info'
Add a new '--print-schema <FORMAT>' option to the 'pvimg info' command
that prints the schema, if available, describing the given output
format. For example, 'pvimg info --print-schema json' prints the JSON
schema for the 'pvimg info' command output.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:49:00 +01:00
Marc Hartmayer
8d40b5c97a pvimg info: Add '--show-secrets' flag
Add '--show-secrets' flag to 'pvimg info' to make secret output explicit
and avoid accidental disclosure.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
ad4075804f pvimg: Auto-detect default format for info command
Auto-detect default format for 'pvimg info' command. If stdout is a
terminal, use 'text', otherwise 'json'.

Adapt the tests accordingly.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
126ba7e336 pvimg: info: Add '--format text' support
Add human-readable output format to 'pvimg info' command. The format
'text:normal' shows only basic information about the Secure Execution
header, but skips the keys and other binary data; the format 'text:full'
shows everything.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
1d2a89b387 pvimg: Improve the readability of Display output for control flags
The Display implementation should produce human-readable output. Convert
the flags into a descriptive flag list to improve readability.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
7c4b029020 pvimg: info: Use the s390-tools JSON meta data
Use the s390-tools JSON meta data for the JSON output of 'pvimg info' to
make the JSON output more stable and to provide an stable API.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
b5a750c2cc rust: utils: Introduce S390ToolsMetaData
Introduce S390ToolsMetaData struct, it can be used to generate the
s390-tools specific JSON metadata.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
893667e73e rust: utils: Add 'gethostname()' function
Add 'gethostname' function to retrieve the system hostname using libc
gethostname.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
95fb1e2b03 pvimg: Improve error messages
Improve error messages for errors when reading the SE header protection
key or when the decryption/verification of the SE header has failed.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
87966251c4 pvimg: info: Improve JSON output
Improve JSON output and implement deserialization.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
012025595f pvimg: info: Provide two JSON output variants: pretty and minify
Add two JSON output variants: pretty and minify. The desired variant can
be selected via '--format json:pretty' and '--format json:minify'. Using
'--format json' without a variant defaults to pretty.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
48c8fc8321 pvimg: info: Warn when the SE header has not been verified
Add a warning to notify the user when the Secure Execution (SE) header
is present but its integrity and authenticity has not been verified.
This makes the lack of validation explicit and helps avoid unintended
use of untrusted data.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
19995638e9 pvimg: Remove redundant check
Remove redundant check.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
91ee8e0593 pvimg: Improve code documentation
Improve the documentation of flags and secured components.

Created with assistance from IBM Bob AI.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Marc Hartmayer
238ca83b99 Update pvattest and pvsecret mapnages and README.md
Update pvattest and pvsecret mapnages and README.md, as for example the
'pvsecret create update-cck' was not documented.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 11:48:59 +01:00
Jan Polensky
df8aac7084 zdev: Remove misc_readlink() helper function
zdev uses util_readlink() now and there are no users left
for misc_readlink() anymore. Remove it.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
8ad28f7856 zdev: Use util_readlink() for consistent error handling
Avoid code duplication and inconsistent error handling by replacing
readlink() with util_readlink(), which is used project-wide to
standardize readlink() usage.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
dd818ccc15 lsqeth: Use util_readlink() for consistent error handling
Avoid code duplication and inconsistent error handling by replacing
readlink() with util_readlink(), which is used project-wide to
standardize readlink() usage.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
e7203069cc libutil/util_sys: Use util_readlink() for consistent error handling
Avoid code duplication and inconsistent error handling by replacing
readlink() with util_readlink(), which is used project-wide to
standardize readlink() usage.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
d4ee1ff01f zconf/lscss: Use util_readlink() for consistent error handling
Avoid code duplication and inconsistent error handling by replacing
readlink() with util_readlink(), which is used project-wide to
standardize readlink() usage.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
9c60ceccd4 dasdinfo: Use util_readlink() for consistent error handling
Avoid code duplication and inconsistent error handling by replacing
readlink() with util_readlink(), which is used project-wide to
standardize readlink() usage.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
6da56acf4b dump2tar: Use readlinkat() unconditionally in read_symlink()
Replace the readlink() branch with readlinkat() and normalize
parameters: use AT_FDCWD with filename when relname is NULL. This
removes duplicate code paths while preserving behavior, including the
growth loop and size limits. readlinkat() is a superset of readlink().

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
365be71dfc util_libc: Add util_readlink() and util_readlinkat() helpers
Introduce util_readlinkat() to read symbolic links relative to a
directory file descriptor, and util_readlink() as a convenience wrapper
using AT_FDCWD.

util_readlink() delegates to util_readlinkat() instead of duplicating
logic, ensuring a single implementation for both interfaces.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
789b097d3a libvtoc: Cleanup trailing whitespaces
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:54 +01:00
Jan Polensky
06df08ae49 libvtoc: Convert comments from ISO-8859-1 to UTF-8
Convert comment encoding from ISO-8859-1 to UTF-8 to avoid encoding
mismatches and simplify future maintenance.

Align the libvtoc comments with the change introduced in the kernel
by commit 8f2bc80c6ef8 ("s390: ebcdic: convert comments to UTF-8").

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Jan Polensky
56a656f1c9 lsqeth: Fix typos
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Jan Polensky
8efd4da53b cpumf/pai: Fix sparse warning for NULL pointer usage
Fix sparse warning by using NULL instead of integer literal for pointer.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Wisdom
d2efda1ac2 libutil: Add utility parsing functions
Add functions to parse boolean values, sizes, ranges, and numbers.
Declarations are in util_parse.h for use across all s390-tools.

Signed-off-by: Wisdom Erhimwionsobo <werh29@linux.ibm.com>
Co-developed-by: Dean Doyle <ddoyle@linux.ibm.com>
Signed-off-by: Dean Doyle <ddoyle@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Wisdom Erhimwionsobo
aa29a5f1f9 libutil: Add util_startswith() to util_str
Add util_startswith to util_str to check if a string starts with the
given prefix and returns a pointer to the rest of the string,
or NULL if it does not.

Signed-off-by: Wisdom Erhimwionsobo <werh29@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Vasily Gorbik
28815d3928 ipl_tools/chreipl: Rename BOOTPARMS_FCP_MAX to BOOTPARMS_SCPDATA_MAX
chreipl passes additional boot parameters via the firmware scp_data
sysfs attribute. This mechanism is shared by multiple re-IPL types (FCP,
NVMe, and ECKD) and they all have the same scp_data size limit. The
BOOTPARMS_FCP_MAX name is therefore misleading.

Rename BOOTPARMS_FCP_MAX to BOOTPARMS_SCPDATA_MAX and update all callers
to make the intent clear and avoid implying this limit is FCP-only.

Reviewed-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Vasily Gorbik
65a891fa35 ipl_tools/chreipl: Make --bootparms work for ECKD re-IPL
chreipl accepts --bootparms for list-directed IPL, but for ECKD re-IPL the
value was never committed to sysfs, so the requested boot parameters did
not take effect.

Write the boot parameters to the firmware scp_data attribute when
configuring an ECKD re-IPL target. Also validate that the ECKD re-IPL
sysfs interface exists and enforce the maximum supported boot parameter
length up front.

Fixes: 7c24855ba1 ("ipl_tools: add support for list-directed IPL from ECKD DASD")
Reviewed-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Vasily Gorbik
5dc39e87e7 ipl_tools/lsreipl: Suppress 'clear' output if not supported
Some environments do not expose the /sys/firmware/reipl/*/clear attribute
(e.g. z/VM guests without "Load Normal" support). lsreipl currently tries to
read the attribute unconditionally for ECKD re-IPL and emits a confusing
"Could not read file .../clear" error when it is missing.

Re-IPL type: eckd
Device:      0.0.6d74
bootprog:    0
br_chr:      auto
Bootparm:    ""
Loadparm:    ""
Could not read file /sys/firmware/reipl/eckd/clear: No such file or directory
clear:       (null)
Secure boot: 0

Only print the "clear" field when the corresponding sysfs attribute is
present, avoiding the spurious error output.

Fixes: 7c24855ba1 ("ipl_tools: add support for list-directed IPL from ECKD DASD")
Reviewed-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Vasily Gorbik
3358a30dae zipl/stage3: Always use diag308 LOAD_NORMAL_RESET
stage3 still contains a legacy fallback path that transfers control to
the new kernel via LPSW 0 when diag 0x308 is not available.

The current start_kernel() inline asm issues "diag %[code],%[code],0x308"
without enforcing the required even/odd register pairing for the first
operand. With recent distro toolchains (e.g. GCC 15.x as shipped by Fedora
43 and Ubuntu 25.10), register allocation picks an odd register for the
first diag operand in start_kernel(), which triggers a specification
exception. That exception is then caught by the program-check handler
and stage3 silently takes the fallback, booting the kernel via LPSW 0
instead of performing diag308 LOAD_NORMAL_RESET.

All supported environments are expected to provide diag308, and the rest
of the code already relies on it. Drop start_kernel() and the obsolete
LPSW fallback and always reset into the new kernel via the properly
coded diag308() helper. Mark start() as __noreturn.

Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
Tested-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Marc Hartmayer
d7ba322d69 uvsecret: Fix unresolved links in the documentation
warning: unresolved link to `GuestSecret::retrievable`
  --> pv/src/uvsecret/guest_secret.rs:56:37
   |
56 |     /// Create Retrievables using [`GuestSecret::retrievable`]
   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^ the enum `GuestSecret` has no variant or associated item named `retrievable`
   |
   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: unresolved link to `GuestSecret::RetrievableKey::name`
  --> pv/src/uvsecret/guest_secret.rs:63:30
   |
63 |         /// SHA256 hash of [`GuestSecret::RetrievableKey::name`]
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the enum `GuestSecret` has no variant or associated item named `RetrievableKey`

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:11:44 +01:00
Nikita Dubrovskii
3123f56765 scripts/cpictl: Detect RHCOS using VARIANT_ID
CoreOS uses VARIANT_ID instead of a unique ID in /etc/os-release.
Extend distro detection to identify RHCOS, other CoreOS variants
may be added later if needed.

RHCOS is showing in HMC as RHEL, because `system_level' is:
```
[core@cosa-devsh ~]$ cat /sys/firmware/cpi/system_level
0x010906023a050e00
```
But should be:
```
[core@cosa-devsh ~]$ cat /sys/firmware/cpi/system_level
0x070906023a050e00
```

Issue: https://jsw.ibm.com/browse/OCPVIP-1471

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/199
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:09:34 +01:00
Nikita Dubrovskii
eb881c2a39 scripts/cpictl: Fix ShellCheck warnings
Fix SC2162, SC2166 and SC2181 reported by ShellCheck without changing
script behavior.

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/199
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:08:47 +01:00
Eduard Shishkin
5c2e6fd730 zipl/src: Fix dump job on tape devices
Fix incorrect handling of tape devices leading to inability of
creating dumps on them.
Make the check for tape device go first, to not miss it on irrelevant
errors

Reported-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:08:47 +01:00
Volkan Unal
47cac92ca2 lscss: Fix memory leak
When the subchannel type read from sysfs does not match the requested
type, the allocated path is not freed before continuing to the next
loop iteration. This causes a memory leak as reported by valgrind.

Free the path before continuing.

Signed-off-by: Volkan Unal <vunal@linux.ibm.com>
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-12 13:08:47 +01:00
Aswin Karuvally
11f2ccb957 hsci: Automatically set appropriate MTU for HSCI
At present, the hsci tool creates HiperSockets Converged Interface
(HSCI) with MTU of 1500 bytes regardless of the values of MTU for the
external and HiperSockets interface from which it is formed. This can
degrade performance or worse, affect network connectivity through the
converged interface.

Update the tool to automatically set MTU of HSCI as the lower of the
MTU values of external and HiperSockets interface.

Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Aswin Karuvally <aswin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:10:34 +01:00
Finn Callies
5b909a40cb cpacfstats: Add unauthorized state to CPU-MF counters
Introduce the new state 'unauthorized' to the three already existing
states disabled, enabled, and unsupported to CPU-MF counters.
CPU-MF counters are only available on LPARs.
The intent is to differentiate whether a system simply does not support
the CPU-MF counters like a z/VM guest or if they are supported like on
LPAR but have to be authorized via HMC/SE.

Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
[hoeppner@linux.ibm.com: Adapt commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:10:34 +01:00
Volkan Unal
591eb30854 lschp: Support for structured output
Introduce a new command line flag ("--format") to specify the output
format. Valid options are "pairs" for shell-compatible key
value pairs, "csv" for CSV, "json" for a formatted JSON document, and
"json-seq" for a stream of JSON text sequences as per RFC7464[1].

[1]: https://datatracker.ietf.org/doc/html/rfc7464

Signed-off-by: Volkan Unal <vunal@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:10:34 +01:00
Volkan Unal
3083f5dc85 lschp: Clean up unnecessary padding
Alignment in tabular output is already guaranteed via the
UTIL_REC_ALIGN_LEFT setting.

Signed-off-by: Volkan Unal <vunal@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:10:34 +01:00
Volkan Unal
2325d94453 lschp: Refactor channel path strings into macros
Replace repeated channel path strings with macros in preparation
for a follow-up patch.

Signed-off-by: Volkan Unal <vunal@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:10:34 +01:00
Steffen Eiden
fef70e3e95 pvinfo: Improve User experience on non-SE enabled systems
For systems without SE:
	- Do not exit with an error if `--version` is specified but
	  print the version
	- Do not exit with an error if `--se-status` is specified but
	  print `Secure Execution is not enabled`

Closes: https://github.com/ibm-s390-linux/s390-tools/issues/197
Closes: https://github.com/ibm-s390-linux/s390-tools/issues/198
Reported-by: Dan Horák <dan@danny.cz>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:08:58 +01:00
Steffen Eiden
808b766407 pvattest: Change default firmware hash verification endpoint
Change the default firmware hash verification to its final location.
For the old one, there is a redirection in place for the foreseeable
future.

Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Acked-by: Brendon Drew <bdrew@us.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 18:08:53 +01:00
Harald Freudenberger
346a69e5a9 lszcrypt: Update depth field calculation based on kernel change
The sysfs field 'depth' for AP queues now shows the real depth
and not the depth -1 as it is reported by the TAPQ instruction.
lszcrypt did under the hood already this +1 but now this increment
is done by the kernel and thus not needed in lszcrypt any more.

Suggested-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-06 17:58:54 +01:00
Thomas Richter
52ddd291d4 cpumf/pai: Handle different size of perf_event_attr
The structure perf_event_attr sometimes gets new members appended
at the end of the structure. Then the size of the structure increases.
This may lead to the situation where sizeof(struct perf_event_attr)
calculated at the pai program compile time during s390-tools build
differs from the one used to build application programs on the target
system.

The report files written by various tools write the contents of the
perf_event_attr structure followed by indivual samples to a binary file.
The second member perf_event_attr::size contains the size of that
structure in bytes.

Use that perf_event_attr::size from the target system to scan the
report files given as command line argument. This ensure the correct
size of structure perf_event_attr is used.

Output before:
Current situation: The pai program uses a perf_event_attr structure
which contains 8 bytes less than the one used on the target system.
The first sample header (8 bytes) then actually refers to the last
eight bytes of structure perf_event_attr, which are all zeroes. This
is an invalid sample entry and the program terminates with error.

 # pai -r -V painnpa.0004043; echo $?
 painnpa.0004043 size:1344
 [0x000088] type 0 misc 0 size 0
 1

Output after:
Use the correct size of structure perf_event_attr, which was read
from be binary file, written by the tools compiled on the target system:
 # pai -r -V painnpa.0004043; echo $?
 painnpa.0004043 size:1344
 size perf_event_attr mismatch 136/144
 [0x000090] type 9 misc 1 size 58 0x13537f71715 18 event 6144 \
	 sample pid 4043/4043 15:0x8a,16:0x88,22:0x112,25:0xc0
 ...
 0

Also show an debug message when verbose mode is turned on.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
André Wild
4cf239b8b6 scripts/cpictl: Fix typo --permit_cpi to --permit-cpi in help output
Signed-off-by: André Wild <awild@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
André Wild
b292ce565f ap_tools/ap-check: Fix typo AQPN -> APQN
Signed-off-by: André Wild <awild@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Peter Oberparleiter
75ab455cf6 libutil: Avoid realloc() with zero size
According to the valgrind man-page, "the behaviour of realloc() with a
size of zero is implementation defined in C17 and undefined in C23."

The current glibc implementation frees the specified buffer, returns
NULL and doesn't set errno. While this behavior is unlikely to change
in the near future, code relying on it may not be compatible with other
libc implementations. Also this realloc() use is flagged as an error in
valgrind runs, making valgrind output less usable.

Fix this by explicitly adding code to cover the realloc(buffer, 0) case
in util_realloc(). Also change libutil users of realloc() to use
util_realloc() instead.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Alexander Egorenkov
25088b340b README.md: zipl depends on mkfs.ext4
Add mkfs.ext4 to zipl dependency list. It is required to prepare
a NGDump dump partition.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Alexander Egorenkov
8edc5558b5 zipl/ngdump: Ensure ext4 file system is used on dump partition
If not specified, mkfs' default file system type is ext2 but
a NGDump dump partition must be formatted with ext4 file system.

Fixes: 41108c98aa ("zipl: move mkfs to ngdump prepare script")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Tested-by:   Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
cd93949d17 zkey: Add phmac_s390 to initramfs and load it via modules-load.d
Add kernel module phmac_s390 to the initramfs hook and dracut config file
to ensure that the PHMAC cipher is available during early boot, in case
the root disk is integrity protected via PHMAC.

Also load phmac_s390 via modules-load.d to ensure that the PHMAC ciphers
are available.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
97136585da zkey-cryptsetup: Support PHMAC integrity with convert command
In case the volume is integrity protected, and the integrity algorithm is
PHMAC, then the convert command also checks the integrity key part of the
volume key, and then uses the secure integrity key, and sets the
verification pattern to the verification-pattern token.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
96d5b0bb02 zkey-cryptsetup: Support PHMAC integrity with reencipher command
In case the volume is integrity protected, and the integrity algorithm is
PHMAC, then the reencipher command also reenciphers the integrity key part
of the volume key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
771c794580 zkey-cryptsetup: Support PHMAC integrity with setkey command
In case the volume is integrity protected, and the integrity algorithm is
PHMAC, then the setkey command also checks the integrity key part of the
volume key, and then sets the key into a new key slot, and sets the
verification pattern to the verification-pattern token.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
f11c71237e zkey-cryptsetup: Support PHMAC integrity with setvp command
In case the volume is integrity protected, and the integrity algorithm is
PHMAC, then the setvp command also adds the verification pattern of the
integrity key into the token.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
8dd5758341 zkey-cryptsetup: Support PHMAC integrity with validate command
In case the volume is integrity protected, and the integrity algorithm is
PHMAC, then also validate the integrity key and print its validation
status.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
20cc99feb7 zkey-cryptsetup: Add support for integrity verification pattern in token
In case the volume is integrity protected, and the integrity algorithm is
PHMAC, then the verification-pattern token as well as the reencipher-token
contain the verification pattern of the integrity key as well.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
9fa165de7a zkey-cryptsetup: Unify type of pointer to key blob
Use 'u8 *' instead of 'char *' for pointers to key blobs everywhere.
This saves a lot of casts.

The libcryptsetup API still uses 'char *' as pointer type for volume keys,
so a few casts are required when passing those pointers to libcryptsetup
API functions.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
103a99fa34 zkey: Support LUKS2 with combined encryption and integrity
The commands 'zkey cryptsetup' generates commands for formatting and
opening volumes of type PLAIN and LUKS2.

For LUKS2, if there exists an HMAC key that is associated to the same
volume as the AES key, generate a 'cryptsetup luksFormat' command for
combined encryption and integrity protection. This uses the '--integrity'
and '--integrity-key-size' options of the 'cryptsetup luksFormat'
command to specify the integrity settings.

The volume key specified with '--master-key-file' must contain the
encryption key and the integrity key concatenated to each other. The
size of the volume key specified with '--key-size' however must be the
size of the encryption key only, in bits. The 'cryptsetup luksFormat'
command will internally read the whole file, use the first part as
encryption key, and the second part as integrity key. The size of the
second part must be specified with the '--integrity-key-size'.

Note: This requires 'wrapped integrity key' support in the cryptsetup
package, as well as in the dm-crypt kernel module.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
c161c04392 zkey: Add integritytab and integritysetup commands for integrity volumes
The commands 'zkey integritytab' generates /etc/integritytab entries for
volumes of type INTEGRITY.

The 'zkey integritysetup' generates integritysetup commands for formatting
and opening volumes of type INTEGRITY.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
8e74293c2d zkey: Generate crypttab and cryptsetup commands for AES type keys only
The commands 'zkey crypttab' and 'zkey cryptsetup' should only operate on
AES-type keys, but not on HMAC keys.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
e14e0aa858 zkey: Can't set a sector size for HMAC keys on LUKS2 volumes
You can only set a sector size for an HMAC key of a volume of type
INTEGTRITY. For combined integrity protection with encryption, the
sector size of a LUKS2 volume must be set on the AES key, but can
not be set on the HMAC key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
355700d606 zkey: Allow to associate a LUKS volume to an AES key and a HMAC key
For combined integrity protected with encryption, a LUKS2 volume can be
associated to exactly one AES type key and also to exactly one HMAC type
key.

For other volume types, a volume can only be associated to exactly one
key, either an AES type key, or an HMAC type key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
ddf30feb89 zkey: Only allow to set a dummy passphrase for AES-type keys
Although HMAC keys can be associated to volumes of type 'LUKS2', the dummy
passphrase can only be set to AES-type keys, i.e. to keys that encrypt the
volume.

Reject trying to set a dummy passphrase for an HMAC key with a volume type
of 'LUKS2'.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
0047fc162e zkey: Add INTEGRITY volume type
Keys of type PVSECRET-HMAC can be associated to volumes of volume type
'INTEGTRITY' or 'LUKS2'.

Volumes of type 'INTEGTRITY' are set up for standalone dm-integrity via
the 'integritysetup' tool. Volumes of type 'LUKS2' are setup for combined
encryption and integrity using the 'cryptsetup' tool using the integrity
option.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
d9eee82ab0 zkey: Support generating verification patterns for HMAC keys
Similar as for AES keys, a verification pattern is calculated from an HMAC
key by MACing an all zero message of 64 bytes. The first 32 bytes of the
result is the verification pattern.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
a9059449b9 zkey: Add PVSECRET-HMAC key type and general HMAC support
Add the definitions and utility functions for the PVSECRET-HMAC key type.
A PVSECRET-HMAC key token contains the secret id of a protected
virtualization secret. It does not contain the key material, just a
reference to the key in the ultravisor.

When such a key token is used to perform HMAC operations later on, the
PHMAC kernel cipher will obtain the protected key belonging to this secret
id with the help of the pkey kernel module.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Ingo Franzki
c3d8208a57 zkey: Require cryptsetup v2.8.2 or later
For supporting integrity protected volumes with dm-integrity,
cryptsetup of version 2.8.2 or later is required.

Make cryptsetup of version 2.8.2 a build requirement for zkey, not
only for zkey-cryptsetup. Although zkey could be built with an older
cryptsetup version, the commands that it generates might not work
with older cryptsetup versions.

This makes the compile switch HAVE_LUKS2_SUPPORT superfluous, since
cryptsetup v2.8.2 always includes LUKS2 support. Remove the ifdefs
from the code and update the man pages to not mention LUKS2 support.

Also, starting with cryptsetup version 2.5.0 the luksFormat command
accepts option '--volume-key-file' to specify the volume key file
instead of --master-key-file'. Thus, use '--volume-key-file' in
cryptsetup commands generated by zkey.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:03:19 +01:00
Marc Hartmayer
a2663ec8d3 zipl/boot: Fix unsigned long overflow
Fix two issues in boot menu input parsing:

1. ebcdic_strtoul returns unsigned long but the value was stored in an int.
2. ebcdic_strtoul could overflow if @value exceeds ULONG_MAX.

Both problems are easy to trigger by entering an excessively large value
in the boot menu, which can lead to unsigned long overflow and memory
corruption.

Use a checked addition to prevent overflow and change menu_read() return
type to unsigned long.

Suggested-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-01-19 13:01:01 +01:00
Jan Höppner
12d9d24437 Prepare for next release
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 17:03:36 +01:00
Jan Höppner
aca6704cfa New release s390-tools-2.40.0
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 17:03:28 +01:00
Sertonix
3a85d1ebe6 opticsmon: Remove unused execinfo.h include
Avoids the need to guard the include for only glibc

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
e8f9244224 opticsmon: Use $(PKG_CONFIG) instead of calling pkg-config directly
Is more consistent with other Makefiles and fixes cross compilation
if it relies on a modified $(PKG_CONFIG).

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
a49887de1f include/boot/s390.h: Always use __vector128 from asm/types.h
asm/types.h may be included after the guard. This happens eg. when
compiling with musl libc. When including the header directly the
include is always there and the fallback __vector128 is not needed
anymore.

The guard was introduced by commit 11bdab2629 ("include/boot/s390.h:
add guard for `struct __vector128`")

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
[hoeppner@linux.ibm.com: Adapt commit message]
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
4e61b4c9f4 hyptop/helper: Define _PATH_MOUNTED fallback
_PATH_MOUNTED is not defined in musl libc

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
d884cc27c1 hyptop/helper: Remove duplicate include
Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
bf3810ea6a libutil/util_opt: Remove unused argz.h include
Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
99d7ec51a7 Use execinfo.h only on glibc
libunwind could also work on musl but that would require more drastic
code changes

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
327d132aac rust/pvcore/uvdevice: Fix compilation on musl libc
musl libc ioctl uses int instead of unsigned long.

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
fcb89662e0 chreipl-fcp-mpath: Use sha256sum -c instead of --check
The --check long option is not available in some sha256sum
implementations like busybox.

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:59 +01:00
Sertonix
a52243ea04 Makefile: Install netboot on non-s390 architectures
mk-s390image can be used on all arches. mk-pxelinux-ramfs probably only
works on a s390 system but it should also not hurt to install since it's
just an example.

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:57 +01:00
Sertonix
805a4d4408 Use _FILE_OFFSET_BITS=64 instead of _LARGEFILE64_SOURCE everywhere
Allows using more portable function/type names while still using 64-bit
values on 32-bit glibc systems.

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:05 +01:00
Sertonix
b1e4f6f331 dasdinfo: Define FTW_{CONTINUE,STOP} when not available
These are not available in musl libc and not mentioned in the POSIX spec

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:05 +01:00
Sertonix
10d72caac0 Add missing includes
include/lib/util_sys.h: missing dev_t
ziomon/ziomon_msg_tools.h: missing time_t
zkey/keystore.c: missing open
mon_tools/mon_procd.c: missing gettimeofday

Fixes some build failures on musl libc

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:05 +01:00
Sertonix
0ea693d95c Use standard uint*_t instead of u_int*_t
Fixes some compilation issues on musl libc. uint*_t is already used so
this should not introduce any new issues.

Github-ID: https://github.com/ibm-s390-linux/s390-tools/pull/193
Signed-off-by: Sertonix <sertonix@posteo.net>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-11 15:46:05 +01:00
Steffen Eiden
0ff130ed84 Add tool to verify host-key documents
Add a tool that can be used to verify if a given IBM host-key document is
valid. This uses the same logic (and code) as the image/request tools
for IBM Secure Execution, pvimg, pvattest, and pvsecret.

This tool basically just does the first step of the above tools; but without
creating any request or image.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:43:15 +01:00
Steffen Eiden
8a57017af3 rust/utils: Add s390-tools version macro
This new macro allows (rust) tools reporting the s390-tools version
string via clap functionalities, instead of implementing that on their
own. That clap interface requires a string and not a void function that
prints the version string. Define a macro that provides this string.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:43 +01:00
Ajaykumar Rajappa
41ec030db1 ziomon: Update man page to document device symlink support
Enhance the ziomon man page to document support for persistent SCSI device
symlinks under /dev/disk/ subdirectories (by-id, by-path, by-uuid, etc.).

The DESCRIPTION section now clarifies that multipath devices and/or device
symlinks resolve to their underlying regular block devices for monitoring.
Updated EXAMPLES to include a scenario demonstrating usage with a device
symlink alongside regular and multipath devices.

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: M Nikhil <nikh1092@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:43 +01:00
Steffen Eiden
34aff761d0 rust: Do not fail install if no man page is available
Some (rust) tools may not provide man pages. In absence of a man file
the install process currently fails. Solve this by expanding the glob
using Make logic instead of sh logic.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:43 +01:00
Jan Höppner
01cb8c4085 clang-tidy: Do not warn about multiple declarations
Omit the readability-isolate-declaration [1] check that warns about
multiple declarations in one line as the s390-tools coding style prefers
this approach.

[1] https://clang.llvm.org/extra/clang-tidy/checks/readability/isolate-declaration.html

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:43 +01:00
Marc Hartmayer
8d58a9abb0 zipl/boot: Fix two off-by-one bugs
Fix two off-by-one errors:

+ One caused an out-of-bounds read when the loadparm value was 63
+ The other made a boot entry unselectable.

Currently, these bugs have no practical impact because:

1. The memory area beyond __stage2_params.config[63] is empty.
2. BOOT_MENU_ENTRIES is set to 63, which exceeds the number of boot menu
   entries that can be written to disk.

Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:43 +01:00
Annu Sharma
ce82010827 Add tool to display Secure Execution system information
Add 'pvinfo' a tool to display the information of enabled flags, and
print the debug information in Yaml and Human format.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Serena Santosh <serena@linux.ibm.com>
Signed-off-by: Ann Mariya Jojo <annjojo@linux.ibm.com>
Signed-off-by: Annu Sharma <annu09@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:43 +01:00
Ellen McIntyre
c0d8034962 dasdfmt: Implement zsh and bash autocompletion
Add autocomplete script generation for dasdfmt tool.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Ellen McIntyre <ellen@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:41:41 +01:00
Szabina Korbai
95290562e0 cpumf: Implement zsh and bash autocompletion
Add autocompletion script generation for the cpumf
family of tools (chcpumf, lscpumf, lshwc, lspai, pai)

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:52 +01:00
Szabina Korbai
638cbbe332 libutil: Implement zsh and bash autocompletion
Add functionality for generating autocompletion scripts,
allowing for tab completion of tool options for bash and zsh.

This functionality relies on reading the available options
from the util_opt struct at runtime.

The script generation happens on the build system.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:52 +01:00
Szabina Korbai
70157462d8 common.mak: Add explanation to *_FOR_BUILD variables
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:52 +01:00
Marc Hartmayer
40bc181f31 zipl/boot: Fix out-of-bounds read if loadparm value is too large
When a loadparm is presented by the user it's not checked whether it's
too large. Add this missing check to fix an out-of-bounds read.

The problem did not show up because the area behind the buffer is empty.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:52 +01:00
Marc Hartmayer
a2eb03660d zipl/boot: Fix unused loadparm when SCLP line-mode console is absent
Currently, 'sclp_setup(SCLP_INIT)' fails if no SCLP line-mode console is
available. As a result 'menu_param()' is never called, even though it is
required to retrieve the 'loadparm' value.

However, reading the loadparm via SCLP remains useful even when a SCLP
line-mode console is absent, because this value determines which boot
entry should be selected. Therefore, the boot process should continue by
retrieving the loadparm without requiring an SCLP line-mode console.

It's safe to continue without a SCLP console as 'printf' and
'menu_param' tolerates the absence of a SCLP line-mode console.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/196
Reported-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:52 +01:00
Mete Durlu
f4c4c40b78 hyptop: Remove unnecessary extern keywords in headers
Remove extern keyword from function signatures in header files.
Function signatures in headers are already extern implicitly.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
fe78faa8ae hyptop/table: Fill system name column for CSV output
When machine parseable format is specified via hyptop --format csv
the summary row for csv does not have any indicator or and a blank
system name. Avoid this confusion by adding "SUM" as system name.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
617a8248e8 hyptop: Add option to show omitted fields on formatted output
Fields without a valid value are normally excluded from formatted output
of hyptop. Add "--all" option to force hyptop to display those fields
with null values.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
c5695e43c4 hyptop/opts: Replace long option formats for consistency
Hyptop uses underscore("_") in between words for options, this breaks
consistency. Use hyphens ("-") in between words in options moving
forward. Underscore formats are still supported for compatibility.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
7b3add9389 hyptop: Use util_time helpers for time calculations
Use the common helpers in lib/util_time instead of using hardcoded
values for time calculations.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
44fdf586e1 libutil: Introduce util_time
Introduce util_time as a place for time related macros, definitions,
and functions that are commonly used. Add NSEC_PER_USEC, NSEC_PER_MSEC,
USEC_PER_SEC and NSEC_PER_SEC definitions that are used for time
conversion calculations as a start. Add time conversion helper functions.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
0d6e63abdc hyptop: Calculate sample time delta for physical partition
Physical machine information does not include any monotonically
increasing time field like other per CPU information blocks. This
Prevents the percentage calculation for the physical information fields
as the divisor(time_delta) is missing;

field% = (value_current - value_previous) / time_delta

To circumvent that, use the current partition's per CPU online time
values to calculate the time_delta. Integrate time_delta as a new
field(phys_delta_us) specific to the physical systems.

Explicitly CPU0 online time is used, since CPU0 is always online
and cannot be deconfigured on s390x. Its online-time deltas would
match those of the physical CPUs.

Since a new field has to be used for physical systems a new
column in the table also has to be created but instead map the
physical system field to the corresponding regular system fields
for a nicer table view.

Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Mete Durlu
1771e7f2f3 hyptop: Add physical information row
Introduce a new row to represent the underlying physical machine
and the physical information hyptop gathers from diag.

Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Steffen Eiden
c403208332 rust: Apply suggested fixes from clippy
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2025-12-10 14:40:51 +01:00
Steffen Eiden
2a99007a6e zkey: Fix spelling issues
Some codespell findings.

`codespell zkey/keystore.c`

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Steffen Eiden
994269c278 rust: Fix formatting issues
Some `rustfmt` findings.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
ae5687f1d1 libvtoc: Replace bzero with memset
Replace deprecated bzero() with memset() to maintain portability and
comply with the C standard.

No functional change.

Link: https://www.man7.org/linux/man-pages/man3/bzero.3.html
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
b856ae62a7 dasdview: Replace bzero with memset
Replace deprecated bzero() with memset() to maintain portability and
comply with the C standard.

Correct typo causing double zero on s4 instead of s4 and t4.

Link: https://www.man7.org/linux/man-pages/man3/bzero.3.html
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
7b4be02441 dasdview: Fix typo
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
2403d1e166 zdsfs: Replace bzero with memset
Replace deprecated bzero() with memset() to maintain portability and
comply with the C standard.

No functional change.

Link: https://www.man7.org/linux/man-pages/man3/bzero.3.html
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
3f03ceb007 fdasd: Replace bzero with memset
Replace deprecated bzero() with memset() to maintain portability and
comply with the C standard.

No functional change.

Link: https://www.man7.org/linux/man-pages/man3/bzero.3.html
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
150ae08678 dasdinfo: Replace bzero with memset
Replace deprecated bzero() with memset() to maintain portability and
comply with the C standard.

No functional change.

Link: https://www.man7.org/linux/man-pages/man3/bzero.3.html
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Ingo Franzki
43a10f4806 common.mak: Add '-Wl,--as-needed' to DEFAULT_LDFLAGS
Many distros and buildsystems use '-Wl,--as-needed' default-wise anyway.
For example, Ubuntu, Fedora, and Meson default to '-Wl,--as-needed'.
Considering some of the projects that use/support Meson, e.g. util-linux,
systemd, libvirt, or git, are all built with '-Wl,--as-needed' as well.

So add '-Wl,--as-needed' to DEFAULT_LDFLAGS to also default to that.

Note that with '-Wl,--as-needed' the order of flags, objects, and libraries
matters for the link step. The link rule in common.mak already has the
correct order, so using '-Wl,--as-needed' will not hurt.

    %: %.o
	    $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Ingo Franzki
4e08c5fcd8 common.mak: Fix the check for shared libraries with check_dep
The check_dep macro allows to pass additional compiler & linker
options as 5th argument. This argument might contain shared
libraries to link against (i.e. -lsomething). To ensure that
the check_dep macro always attempts to link to these libraries
'-Wl,--no-as-needed' is needed.

At least on Ubuntu '-Wl,--as-needed' is the default, and with
that, the library might get skipped if it is not really needed
by the program built by the check_dep macro. Furthermore, with
'-Wl,--as-needed' the order of the arguments matters, and thus
a library specified in the 5th argument is at the wrong position,
which leads to link errors and thus the check_dep macro will
report that the dependency is not fulfilled, although it might
be fulfilled.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Matthew Rosato
6532bf02c2 zdev: Add ap bus coldplug replay trigger for ap.rules
Add an additional trigger to the zdev-generated 41-ap.rules file.  This
trigger will check the bindings_complete_count value during coldplug
replay of the ap bus, which allows the udev rule to handle the case
where zcrypt has already fired the BINDINGS==complete with
COMPLETECOUNT==1 before the udev rule was accessible (example: before
rootfs has been mounted).  Without this, it's possible for the rule to
never fire despite the initial bindings having completed.
While it was always possible for zcrypt to be forced onto initrd, it
becomes far more likely with changes like 14c977768 ("zkey/dracut: Add
a dracut config file for zkey").

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Acked-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
3f7b459606 dump2tar: Remove unused header file
Drop idcache.h as it is not used in this file.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
14830b1ead zdev: Remove unused header files
Remove unused header files from these sources.
This simplifies maintenance and slightly reduces compile time.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
1dae9b4f49 zconf/lsqeth: Remove unused internal headers
Drop unused headers from the internal s390-tools library. These headers
were only indirectly pulling in stdlib.h, which is now included
explicitly to support memory deallocation via free().

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
b58414d7dc zconf/lscss: Remove unused header
Drop lib/util_base.h and lib/zt_common.h as they are not used in this
file.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
64524f17fa libutil/util_path: Remove unused headers
Drop lib/util_base.h and lib/util_prg.h as they are not used in this
file.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
1b87b016d4 libutil/util_list: Remove unused header stdio.h
Drop stdio.h as it is not used in this file.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
94bdb17d01 cpumf/lscpumf: Remove unused header
Remove ctype.h and errno.h since they are not referenced in this
file.
Add err.h to explicitly declare the dependency on warnx().

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
2625cd704f cpumf/chcpumf: Remove unused header
Remove lib/util_base.h and errno.h since they are not referenced in this
file.
Add err.h to explicitly declare the dependency on err() and warn().

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:37 +01:00
Jan Polensky
59df2c6d02 util_libc: Fix typo
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Jan Polensky
8ba03642b7 libvtoc: Fix typos
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Jan Polensky
1956e7abc5 zdsfs: Fix typos
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Jan Polensky
d76cb1d53a fdasd: Fix typos
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Jan Polensky
7d5f2ba038 zconf/lscss: Fix typos
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Jan Polensky
8bbf1d5bea checkpatch: Ignore STRNCPY warning for userspace code
For s390-tools util_strlcpy() would be a safer replacement. However,
no code is changed, only .checkpatch.conf is updated to avoid false
positives in userspace.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Jan Polensky
b2fcb608d5 Add project-wide .clang-tidy configuration
Introduce a .clang-tidy file to provide consistent code quality checks
across the project.

The configuration is not integrated into .pre-commit-config.yaml because
it depends on a recently generated compile_commands.json file.

Example usage:

	clang-tidy --fix-errors **/*.[ch]

Note: Running clang-tidy should be considered optional, not enforced.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Marc Hartmayer
76b7928592 netboot: Format mk-s390image
Command line used:

  $ shfmt --space-redirects --case-indent --simplify --func-next-line --write mk-s390image

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Marc Hartmayer
339b69cf3b netboot: Ignore the removal of nonexistent file in mk-s390image
Ignore the removal of nonexistent $image file. This removes the
following error message:

$ mk-s390image /var/lib/libvirt/images/hades/vmlinux-s390x out.img
...
rm: cannot remove 'out.img': No such file or directory

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Marc Hartmayer
419f042f55 netboot: Improve error reporting in mk-s390image
If an input file is not readable return a proper error message indicating
this.

Before:

$ mk-s390image /var/lib/libvirt/images/hades/vmlinux-s390x out.img
mk-s390image: Unrecognized file format for /var/lib/libvirt/images/hades/vmlinux-s390x

After:

$ mk-s390image /var/lib/libvirt/images/hades/vmlinux-s390x out.img
mk-s390image: File /var/lib/libvirt/images/hades/vmlinux-s390x cannot be read, no read permission

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Marc Hartmayer
128e5f86fe netboot: Add longer kernel command lines support
Since Linux commit 5ecb2da660ab ("s390: support command lines longer
than 896 bytes") the s390x kernel supports longer command lines than 896
bytes. The indication of the maximum size is stored in a new field at
address 0x10430, older kernels without the support store a value of 0
there so in that case fallback to the old maximum length of 896.

In addition, use the checked size as limit to copy in the 'dd' call.
This prevents Linux kernel corruption in case the parmline has changed
in between.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/194
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Marc Hartmayer
b29e824923 netboot: Fix shellcheck findings in mk-s390image and make the script more robust
Most of the fixes were auto-generated using the following command:

     $ shellcheck --format=diff mk-s390image | git apply -

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:36 +01:00
Ajaykumar Rajappa
3175d52ce7 ziomon: Add support to sample device symlinks
Enhance 'ziomon' utility to support persistent SCSI device symlinks,
including regular, multipath and partitioned devices. Supports /dev/disk/
subdirectories (by-id, by-path, by-uuid, by-label, etc.), resolving the
symlinks to their SCSI block devices.

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Tested-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Reviewed-by: Nihar Panda <niharp@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:33 +01:00
Jörn Siglen
17024c02af dbginfo.sh: Adding stp time information
Calling lsstp to get the status on STP time sync.

Suggested-by: Michael Storzer <MSTORZER@de.ibm.com>
Reviewed-by: Michael Storzer <MSTORZER@de.ibm.com>
Signed-off-by: Jörn Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:32 +01:00
Jörn Siglen
5cd680c0be dbginfo.sh: Simplify procfs collection
Using the base dir only, will ensure to get all needed info independent of
configuration and future changes.

├── dasd
│   ├── devices
│   └── statistics

├── net
│   ├── anycast6
│   ├── arp

│   ├── bonding

│   ├── dev
│   ├── dev_mcast
│   ├── dev_snmp6
│   │   ├── encbdf0
│   │   └── lo

│   ├── sockstat
│   ├── sockstat6
│   ├── softnet_stat
│   ├── stat
│   │   ├── arp_cache
│   │   ├── ndisc_cache
│   │   ├── nf_conntrack
│   │   └── rt_cache

│   ├── vlan

The change in size and collection speed can be ignored.

Reviewed-by: Michael Storzer <MSTORZER@de.ibm.com>
Signed-off-by: Jörn Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-12-01 13:45:32 +01:00
Ajaykumar Rajappa
c333f91d4c ziomon/ziorep_config: Add fcp-lun to -M option output
Update the ‘ziorep_config’ utility to print FCP-LUN details
when the ‘-M’ option is used.

Now, ‘ziorep_config -M' option prints FCP LUN(fcp-lun) ID along with the
existing FCP device bus-id and WWPN. This addition helps correlate the
output with command 'multipathd -k', subcommand 'show topo' output,
aiding in better visibility and mapping of FCP devices to their respective
LUNs in multipath environments.

$ ziorep_config -t -M
adapter  remote_port        LUN                scsi_dev multipath_device
========================================================================
0.0.1967 0x500507630704572c 0x405240f500000000 /dev/sda /dev/mapper/mpatha
0.0.1967 0x500507630704572c 0x405340f500000000 /dev/sdb /dev/mapper/mpathb
0.0.1927 0x500507630700572c 0x405240f500000000 /dev/sdc /dev/mapper/mpatha
0.0.1967 0x500507630704572c 0x405440f500000000 /dev/sdd /dev/mapper/mpathc
0.0.1927 0x500507630700572c 0x405340f500000000 /dev/sde /dev/mapper/mpathb
0.0.1927 0x500507630700572c 0x405440f500000000 /dev/sdf /dev/mapper/mpathc
0.0.1967 0x500507630704572c 0x405540f500000000 /dev/sdg /dev/mapper/mpathd
0.0.1927 0x500507630700572c 0x405540f500000000 /dev/sdh /dev/mapper/mpathd

The LUN IDs from the above output can be correlated with multipath's
H-C-T-L(LUN ID in decimal) of each FCP devices as shown below,
$ multipathd -k
multipathd > show topo
create: mpatha (36005076307ffd72c00000000000052f5) dm-0 IBM,2107900
size=40G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 0:0:0:1089814610 sdc 8:32  active ready running
  `- 1:0:0:1089814610 sda 8:0   active ready running
create: mpathb (36005076307ffd72c00000000000053f5) dm-1 IBM,2107900
size=40G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 0:0:0:1089814611 sde 8:64  active ready running
  `- 1:0:0:1089814611 sdb 8:16  active ready running
create: mpathc (36005076307ffd72c00000000000054f5) dm-4 IBM,2107900
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 0:0:0:1089814612 sdf 8:80  active ready running
  `- 1:0:0:1089814612 sdd 8:48  active ready running
create: mpathd (36005076307ffd72c00000000000055f5) dm-5 IBM,2107900
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 0:0:0:1089814613 sdh 8:112 active ready running
  `- 1:0:0:1089814613 sdg 8:96  active ready running

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Reviewed-by: Nihar Panda <niharp@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-10 10:30:08 +01:00
Ajaykumar Rajappa
095e5ee226 ziomon/ziorep_config: Add port_id and failed attributes to -A option output
Update ziorep_config utility to extract and display the local fc_host
port_id and failed /sysfs attributes when -A(adapter) option is used.

$ ziorep_config -A
Host:    host0
PCHID:   0308
CHPID:   60
Adapter: 0.0.1927
Sub-Ch.: 0.0.0004
Name:    0xc05076fff38075d4
Port-Id: 0x33c016
P-Name:  0xc05076fff3803081
Version: 0x000b
LIC:     0x24500103
Type:    NPIV VPORT
Speed:   32 Gbit
State:   Online
Failed:  No

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Reviewed-by: Nihar Panda <niharp@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-10 10:29:57 +01:00
Peter Jin
6ee5ffef91 udev/rules.d: Set default io scheduler to 'none' for virtio-blk
Use 'none' as default io scheduler for virtio-blk devices. Performance
improvements for multi-queue setups and to reduce CPU consumption.

Signed-off-by: Peter Jin <pjin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-10 10:29:52 +01:00
Peter Jin
82f8c137e1 udev/rules.d: make virtio-blk devices non-rotational
Performance measurements turned out that in certain situations the
paging/swap logic turns on the rotational feature for block devices. In the
past, this feature has been disabled for DASD devices. FCP and NVMe devices
are considered non-rotational by default (or exposed by the storage server).
Because those are the backing devices on Linux on Z/LinuxONE instances,
ensure that virtio-blk devices are always non-rotational.

Signed-off-by: Peter Jin <pjin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-10 10:29:46 +01:00
Marc Hartmayer
b21a824fda cpacfinfo and pv: Fix comment style
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
f74b8d7d6f cpacfinfo: Remove commented-out code
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
b766d4a53c rust: Apply clippy fixes to format strings
Makes the code easier to read.

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>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
a1126352ec zipl/boot: Improve linker scripts
Output all text input sections into one text section and map all input
sections .bss.* .text.*, .rodata.*, and .data.* as it's done by the
default linker script [1]. In addition, make the linker script easier to
read by replacing the magic value of 32 with 'SIZEOF(.sb.trailer)'.

[1] Check the output of 'ld --verbose'.

Reviewed-by: Mikhail Zaslonko <zaslonko@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>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
35e539a428 zipl/boot: Declare 'magic' variable as static
Reviewed-by: Mikhail Zaslonko <zaslonko@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>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
99100b3f99 zipl/boot: Explicitly declare stage2.head as used
Although stage2.head is not directly used in stage2, it is required by
other stages. To ensure it is retained during link-time
optimization (LTO), explicitly mark it as used. This improves code
readability and prevents LTO from mistakenly removing it.

Reviewed-by: Mikhail Zaslonko <zaslonko@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>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
49faa1d7fd lib/zt_common.h: Add '__used' macro
The macro will be used in the next patch and makes checkpatch happy.

Reviewed-by: Mikhail Zaslonko <zaslonko@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>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
86ce85b3a6 zipl/boot: Fix typos
Reviewed-by: Mikhail Zaslonko <zaslonko@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>
2025-11-07 14:34:48 +01:00
Marc Hartmayer
b1c1bea4e2 zipl/boot: Rename *.exec into *.elf
Rename .exec into .elf because they are ELF files, no reason to use a
different file extension.

This change improves the shell's autocompletion of tools such as
'readelf'.

Acked-by: Mikhail Zaslonko <zaslonko@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>
2025-11-07 14:34:48 +01:00
Ingo Franzki
e68547f06f libkmipclient: Fix return code passing
Function kmip_connection_tls_verify_server() erroneously always returns
zero, even if an error is detected inside the function. Fix this by
returning the return code value at the end of the function.

Found by clang static code analyzer.

Fixes: 56fecf1832 ("libkmipclient: Add KMIP client shared library")
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:34:48 +01:00
Ajaykumar Rajappa
95d784d866 ziomon/ziomon_fcpconf: Set mode to 755 to match install
No functional changes to the file content.

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
[hoeppner@linux.ibm.com: Adapt commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00
Shalini Chellathurai Saroja
783ae9735e dbginfo: Collect CPI data of the KVM guests
Collect Control-Program Identification (CPI) data of the KVM
guests. The CPI data contains system name, system type,
system level and sysplex name of the guests. It also provides
the timestamp in which these data were colleceted from the
guests.

Note:
CPI information for SEL guests require explicit enablement.

Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com>
Suggested-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Jörn Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00
Ingo Franzki
5a78c7f45d zkey: Report the KCV as part of the KMS label for KMS keys
The key check value (KCV) is the first 3 bytes of the ENC-ZERO key
verification pattern of a key. ENC-ZERO encrypts an all zero block with
the key using AES-ECB and returns the result truncated to 3 bytes as
key check value.

Report the KCV of a KMS generated key as part of its label. This is
especially useful for AES-XTS keys, where the KCV is reported on each
of the 2 individual AES keys that an AES-XTS key is built of. It allows
users to compare the KCV displayed by zkey with the KCV displayed by
the key management system where the key was generated on. If the KCV
value is the same, then the key values are the same, too.

The key verification pattern reported by zkey is also an ENC-ZERO
key check value, but for AES-XTS keys it is built by encrypting
the all zero block with AES-XTS, which produces a KCV for the complete
AES-XTS key, but does not allow to check the individual key parts.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00
Ingo Franzki
586040a0ad zkey/ekmfweb: Validate the certificate during client registration
When registering a zkey client at the EKMFWeb server, validate the
certificate if it's public key matches with the identity key of
the zkey client.

Only allow registration when the certificate matches. This helps to
prevent users from erroneously registering a wrong or outdated
certificate for a zkey client.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00
Ingo Franzki
deb61b5cd9 libekmfweb: Add function to validate a certificate against the identity key
Function ekmf_validate_cert() checks if the public key contained in a x509
certificate matches the public key of the identity key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00
Ingo Franzki
8be51ad454 zkey: Perform KMS login before making any permanent changes to a key
A KMS login may prompt the user for its credentials. Users may abort that
prompt by Cntl-C. Do not make any permanent changes to a key before the
KMS login, because those changes can not be undone when the user has
aborted during KMS login, leaving the key in a potentially inconsistent
state.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:26 +01:00
Finn Callies
cef50c2140 cpacfstats: Recommend systemctl to manage daemon
Update manpage to recommend using systemctl to manage the cpacfstatsd.

Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:17 +01:00
L. E. Segovia
33bd112e2f s390-tools: Fix compilation with musl and gcc 14
lscss.c: In function 'is_sch_vfio':
lscss.c:392:20: error: implicit declaration of function 'basename' [-Wimplicit-function-declaration]
  392 |         if (strcmp(basename(driver_path), "vfio_ccw") == 0)

device.c: In function 'device_read_active_attrib':
device.c:426:45: error: implicit declaration of function 'basename'; did you mean 'rename'? [-Wimplicit-function-declaration]
  426 |                         value = misc_strdup(basename(link));
      |                                             ^~~~~~~~
      |                                             rename

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/192
[hoeppner@linux.ibm.com: Sort includes]
Signed-off-by: L. E. Segovia <amy@amyspark.me>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:17 +01:00
Sertonix
2c31ed6f14 lib(ekmfweb|kmipclient): Use ln without -r
The option isn't portable (not in POSIX or busybox) and it easily works
without.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/191
Signed-off-by: Sertonix <sertonix@posteo.net>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:16 +01:00
Jörn Siglen
771623832b dbginfo.sh: Add NetworkManager and netplan
NetworkManager stores new network profiles in keyfile format in the
/etc/NetworkManager/system-connections/ directory.

/etc/network/interfaces might be replaced by /etc/netplan on some systems

Reviewed-by: Mario Held <mario.held@de.ibm.com>
Reviewed-by: Michael Storzer <MSTORZER@de.ibm.com>
Signed-off-by: Jörn Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:16 +01:00
Jörn Siglen
b8060baf44 dbginfo.sh: Add kvm_stat
Add collecting of KVM kernel module event counters for one second.

Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Reviewed-by: Mario Held <mario.held@de.ibm.com>
Reviewed-by: Michael Storzer <MSTORZER@de.ibm.com>
Signed-off-by: Jörn Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:33:16 +01:00
Jan Höppner
76a0401deb common.mak: Remove NO_PIE_CFLAGS
The definition NO_PIE_CFLAGS has only two users and specifies only a
single compiler flag. There is no point having this definition anymore.

Remove the definition and specify -fno-pie directly for the two users.

Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:31:47 +01:00
Jan Höppner
e6ac87d7a2 common.mak: Remove NO_PIE_LDFLAGS
Commit c5a91199e3 ("zipl: Always build and link without PIE.")
introduced -fno-pie (for compilation) and -no-pie (for linking) for
zipl. At the time the linker was still used directly before commit
5e46632767 ("zipl: Use the compiler for linking instead of ld")
eventually switched to calling the compiler for the linking step.

During that adaption -static was introduced to the linker flags. -no-pie
was carried over as well. However -static implies -no-pie and it is
therefore not required. For GCC see also man 1 gcc (-static) [1]. Whilst
not explicitly documented, Clang shows the same behaviour. Clang also
complains when -static and -no-pie are specified in the linker step at
the same time with the following warning:

clang: warning: argument unused during compilation: '-no-pie' [-Wunused-command-line-argument]

Since -no-pie is not required, remove it and get rid of the warning.

[1] https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#index-static
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:31:47 +01:00
Jan Höppner
0a711d4934 common.mak: Remove no-pie support check
The command line options -fno-pie/-no-pie are required by boot loaders
as they have strict layout requirements. A check was implemented using
-dumpspecs to evaluate the compiler support as older compilers didn't
support the no-pie command line options.
However, -dumpspecs is a GCC specific option and the check will
therefore always fail for Clang. The objective is to enable Clang
compilation support for s390-tools in the long-run.

Since support for -fno-pie/-no-pie in GCC was introduced 2015 with
version 6.1.0 and in Clang 2010 with version 3.0.0, general support can
be assumed.

Simply remove the support check and get rid of another obstacle that's
in the way for full Clang support.

Suggested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:31:47 +01:00
Marc Hartmayer
f90e913806 pvimg/boot: Remove double quotes in section keyword
The 'clang' compiler generates a section with the name '".loader_parms"'
and gcc '.loader_parms' if the double quotes are used. Fix this by
removing the superfluous double quotes, this results in a section with
the name '.loader_parms' for both clang and gcc.

Reported-by: Richie Buturla <richie@linux.ibm.com>
Reviewed-by: Euan Bourke <euan@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-11-07 14:31:47 +01:00
Jan Höppner
94a7ec22f2 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2025-10-14 10:38:51 +02:00
275 changed files with 10197 additions and 2423 deletions

View File

@@ -10,3 +10,4 @@
--ignore FILE_PATH_CHANGES
--ignore NEW_TYPEDEFS
--ignore SPDX_LICENSE_TAG
--ignore STRNCPY

37
.clang-tidy Normal file
View File

@@ -0,0 +1,37 @@
Checks: >
bugprone-*,
clang-analyzer-*,
misc-*,
performance-*,
portability-*,
readability-*,
-bugprone-easily-swappable-parameters,
-misc-include-cleaner,
-readability-braces-around-statements,
-readability-identifier-length,
-readability-isolate-declaration,
-modernize-*,
-performance-*,
-portability-*,
-readability-implicit-bool-conversion
CheckOptions:
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.FunctionCase
value: lower_case
- key: readability-identifier-naming.StructCase
value: lower_case
- key: readability-identifier-naming.EnumCase
value: lower_case
- key: readability-identifier-naming.EnumConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.MacroDefinitionCase
value: UPPER_CASE
- key: bugprone-sizeof-expression.WarnOnSizeOfPointer
value: true
- key: misc-unused-parameters.StrictMode
value: true
FormatStyle: file
UseColor: true

17
.gitignore vendored
View File

@@ -25,6 +25,7 @@ compile_commands.json
#
**/.detect-openssl.dep.c
*.debug
*/autocompletion_generator_host
ap_tools/ap-check
cmsfs-fuse/cmsfs-fuse
cpacfstats/cpacfstats
@@ -34,8 +35,20 @@ cpumf/lscpumf
cpumf/lshwc
cpumf/lspai
cpumf/pai
cpumf/_chcpumf
cpumf/_lscpumf
cpumf/_lshwc
cpumf/_lspai
cpumf/_pai
cpumf/chcpumf.bash
cpumf/lscpumf.bash
cpumf/lshwc.bash
cpumf/lspai.bash
cpumf/pai.bash
cpuplugd/cpuplugd
dasdfmt/dasdfmt
dasdfmt/_dasdfmt
dasdfmt/dasdfmt.bash
dasdinfo/dasdinfo
dasdview/dasdview
dump2tar/src/dump2tar
@@ -63,7 +76,7 @@ libekmfweb/check-dep-libekmfweb
libekmfweb/detect-openssl-version.dep
libekmfweb/libekmfweb.so
libekmfweb/libekmfweb.so.1
libekmfweb/libekmfweb.so.1.0
libekmfweb/libekmfweb.so.1.1
libkmipclient/check-dep-libkmipclient
libkmipclient/detect-openssl-version.dep
libkmipclient/libkmipclient.so
@@ -119,7 +132,7 @@ ziomon/ziomon_zfcpdd
ziomon/ziorep_traffic
ziomon/ziorep_utilization
zipl/boot/*.bin
zipl/boot/*.exec
zipl/boot/*.elf
zipl/boot/.loaders
zipl/boot/data.h
zipl/src/chreipl_helper.device-mapper

View File

@@ -1,13 +1,16 @@
List of all individuals having contributed content to s390-tools
----------------------------------------------------------------
- Ajaykumar Rajappa
- Alexander Egorenkov
- Alexandra Winter
- Alexey Ishchuk
- Andreas Herrmann
- André Wild
- Annu Sharma
- Antoinette Kaschner
- Arnd Bergmann
- Aswin Karuvally
- Axel Wirbser
- Balint Reczey
- Benjamin Block
@@ -23,11 +26,13 @@ List of all individuals having contributed content to s390-tools
- Dan Horak
- Dan Horák
- Daniel S. Haischt
- Dean Doyle
- Despina Papadopoulou
- Dimitri John Ledkov
- Eberhard Pasch
- Eduard Shishkin
- Einar Lueck
- Ellen McIntyre
- Eric Farman
- Eric Sandeen
- Erwin Vicari
@@ -49,8 +54,8 @@ List of all individuals having contributed content to s390-tools
- Graham Inggs
- Guevenc Guelce
- Hannes Reinecke
- Hans-Joachim Picht
- Hans Wippel
- Hans-Joachim Picht
- Harald Freudenberger
- Heiko Carstens
- Hendrik Brueckner
@@ -72,12 +77,13 @@ List of all individuals having contributed content to s390-tools
- Jens Remus
- Jochen Roehrig
- Joern Siglen
- Jörn Siglen
- Juergen Christ
- Julian Wiedmann
- Jörn Siglen
- Karsten Graul
- Kittipon Meesompop
- Klaus-Dieter Wacker
- L. E. Segovia
- Lakhvich Dmitriy
- Marc Hartmayer
- Mario Held
@@ -133,6 +139,7 @@ List of all individuals having contributed content to s390-tools
- Sven Schnelle
- Sven Schuetz
- Swen Schillig
- Szabina Korbai
- Taraka R. Bodireddy
- Thomas Heidrich
- Thomas Huth
@@ -149,7 +156,9 @@ List of all individuals having contributed content to s390-tools
- Vasily Gorbik
- Viktor Mihajlovski
- Vineeth Vijayan
- Volkan Unal
- Volker Sameske
- Wenjia Zhang
- Wisdom Erhimwionsobo
- Wolfgang Taphorn
- Yaakov Selkowitz

View File

@@ -1,6 +1,70 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.41.0 (2026-02-16)__
For Linux kernel version: 6.19
Changes of existing tools:
- chreipl: Make --bootparms work for ECKD re-IPL
- cpacfstats: Add 'unauthorized' state to CPU-MF counters
- cpictl: Detect RHCOS using VARIANT_ID
- hsci: Automatically set appropriate MTU for HSCI
- libutil: Add util_readlink() and util_readlinkat() helpers
- libutil: Add util_startswith() to util_str
- libutil: Add utility parsing functions
- lschp: Add support for structured output (--format)
- lsreipl: Suppress 'clear' output if not supported
- pvimg: Add '--format text' support to 'pvimg info'
- pvimg: Add '--print-schema <FORMAT>' option to 'pvimg info'
- pvimg: Add '--show-secrets' flag to 'pvimg info'
- pvimg: Provide improved JSON output to 'pvimg info --format json'
- pvinfo: Improve User experience on non-SE enabled systems
- zipl/ngdump: Ensure ext4 file system is used on dump partition
- zkey: Add support for integrity protected disks using HMAC keys
Bug Fixes:
- cpumf/pai: Handle different size of perf_event_attr
- lscss: Fix memory leak
- zipl: Fix dump job on tape devices
* __v2.40.0 (2025-12-11)__
For Linux kernel version: 6.18
Add new tools / libraries:
- Add project-wide .clang-tidy configuration
- libutil: Introduce util_time for time related functionality
- libutil: Introduce zsh/bash autocompletion tooling based on util_opt
- pvinfo: Tool to display Secure Execution system information
- pvverify: Tool to verify host-key documents
Changes of existing tools:
- cpumf: Implement zsh and bash autocompletion
- dasdfmt: Implement zsh and bash autocompletion
- dbginfo.sh: Add NetworkManager and netplan
- dbginfo.sh: Add kvm_stat
- dbginfo.sh: Adding stp time information
- dbginfo.sh: Simplify procfs collection
- hyptop: Add physical information row
- hyptop: Calculate sample time delta for physical partition
- hyptop: Replace long option names using _ with - for consistency
For example: --cpu_types -> --cpu-types
(Options with _ are still supported for backward compatibility)
- libekmfweb: Add function to validate a certificate against the identity key
- netboot: Add longer kernel command lines support
- udev/rules.d: Make virtio-blk devices non-rotational
- udev/rules.d: Set default io scheduler to 'none' for virtio-blk
- ziomon: Add support to sample device symlinks (/dev/disk/...)
- ziorep_config: Add fcp-lun details to -M option output
- ziorep_config: Add port_id and failed attributes to -A option output
- netboot: Install on non-s390 architectures
Bug Fixes:
- lib(ekmfweb|kmipclient): Use ln without -r
- s390-tools: Fix various compilation issues with musl libc
- zipl/boot: Fix unused loadparm when SCLP line-mode console is absent
* __v2.39.0 (2025-10-14)__
For Linux kernel version: 6.16 / 6.17

View File

@@ -21,7 +21,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
else
BASELIB_DIRS =
LIB_DIRS = libpv
TOOL_DIRS = rust
TOOL_DIRS = netboot rust
endif
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)

View File

@@ -415,7 +415,7 @@ the different tools are provided:
Removing the inflate modules and function prototypes are the only major
modifications made to the kernel version of zlib.
For stand-alone NVMe and list-directed DASD dump, the following tools/packages
are required to populate dumper's initramfs:
are required to populate dumper's initramfs and prepare a dump partition:
- cat
- cut
- findmnt
@@ -426,6 +426,7 @@ the different tools are provided:
- sha256sum
- sync
- umount
- mkfs.ext4
* zgetdump
For building zgetdump you need OpenSSL version 1.1.0 or newer
@@ -517,11 +518,11 @@ the different tools are provided:
* zkey:
For building the zkey tools you need openssl version 0.9.7 or newer installed
(openssl-devel.rpm). Also required are cryptsetup version 2.0.3 or newer
(openssl-devel.rpm). Also required are cryptsetup version 2.8.2 or newer
(cryptsetup-devel.rpm), and json-c version 0.12 or newer (json-c-devel.rpm).
Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0`, and you may
may skip the zkey-cryptsetup build by adding `HAVE_CRYPTSETUP2=0`, or
`HAVE_JSONC=0` to the make invocation.
Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0` or
`HAVE_CRYPTSETUP2=0`, and you may skip the zkey-cryptsetup build
by adding `HAVE_JSONC=0` to the make invocation.
A new group 'zkeyadm' needs to be created and all users intending to use the
tool must be added to this group. The owner of the default key repository
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission

View File

@@ -303,11 +303,11 @@ static void conflict_error(const char *uuid, unsigned int a, unsigned int d,
}
} else {
if (persistent) {
fprintf(stderr, "AQPN %u.%u is not defined for "
fprintf(stderr, "APQN %u.%u is not defined for "
"vfio_ap-passthrough use by the persistent "
"ap bus mask settings\n", a, d);
} else {
fprintf(stderr, "AQPN %u.%u is not allowed for "
fprintf(stderr, "APQN %u.%u is not allowed for "
"vfio_ap-passthrough use by the active ap "
"bus mask settings\n", a, d);
}
@@ -531,7 +531,7 @@ out:
* Determine if there are any conflicts between the specified device and
* the apmask/aqmask settings stored in udev. This is done by treating
* the masks as a temporary vfio_ap_device with all of the associated
* AQPNs owned by the system.
* APQNs owned by the system.
*/
static int check_cfg_mask_conflicts(struct ap_check_anchor *anc)
{

View File

@@ -129,7 +129,7 @@ else # $(ENABLE_DOC) != 1
# freshness of the man page can be checked, even if `pandoc` is not available,
# or ENABLE_DOC disabled.
MANPAGE_FRESH := $(shell sha256sum --check .chreipl-fcp-mpath.7.cksum >/dev/null && echo 1 || echo 0)
MANPAGE_FRESH := $(shell sha256sum -c .chreipl-fcp-mpath.7.cksum >/dev/null && echo 1 || echo 0)
ifeq ($(MANPAGE_FRESH),0)
$(warning chreipl-fcp-mpath.7 is outdated, please regenerate it by calling `make ENABLE_DOC=1`)
endif

View File

@@ -32,7 +32,7 @@ endif
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION := 2
RELEASE := 39
RELEASE := 41
PATCHLEVEL := 0
DISTRELEASE := build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -119,6 +119,10 @@ ifneq ($(HOST_ARCH),$(BUILD_ARCH))
endif
endif
# *_FOR_BUILD variables define compilation configurations for binaries used
# during the build process (e.g. autocompleteion script generators). This
# is especially important for cross-compilation where these binaries need to
# be executed on the build system.
$(eval $(call define_toolchain_variables,_FOR_BUILD,))
$(eval $(call define_toolchain_variables,,$(CROSS_COMPILE)))
@@ -165,7 +169,7 @@ ifeq ("${ENABLE_WERROR}", "1")
endif
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
DEFAULT_LDFLAGS = -rdynamic
DEFAULT_LDFLAGS = -rdynamic -Wl,--as-needed
ifeq ("${ASAN}","1")
DEFAULT_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
@@ -201,7 +205,7 @@ endef
# $5: Additional compiler & linker options (optional)
#
check_dep=\
printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -x c - ) > /dev/null 2>&1; \
printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) -Wl,--no-as-needed $5 -o /dev/null -x c - ) > /dev/null 2>&1; \
if [ $$? != 0 ]; \
then \
printf " REQCHK %s (%s)\n" $1 $2; \
@@ -340,14 +344,6 @@ endif
export INSTALL CFLAGS CXXFLAGS \
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
NO_PIE_CFLAGS := -fno-pie
NO_PIE_LDFLAGS := -no-pie
else
NO_PIE_CFLAGS :=
NO_PIE_LDFLAGS :=
endif
# Overwrite implicit makefile rules for having nice compile output
%.o: %.c
ifeq ("${C}","1")

81
common_autocomp.mak Normal file
View File

@@ -0,0 +1,81 @@
# SPDX-License-Identifier: MIT
# Copyright IBM Corp. 2025
# This file defines the build process for shell autocompletion binaries
#
# How to incorporate it into tool Makefiles:
#
# 0. The file with the autocompletion script generation code should be named
# 'autocompletion_generator_host.c'
#
# 1. Define the 'bash-completions' and 'zsh-completions' variables: both must be a list
# of the names of all the shell completion scripts that belong to the tools the Makefile
# is responsible for building.
#
# (The name of a zsh completion script is the same as the name of the tool,
# prefixed by an underscore)
#
# (The name of a bash completion script is the same as the name of the tool,
# suffixed by '.bash')
#
# 2. include this file
#
# +1: Add the autocompletion scripts to the .gitignore file
#
# (See cpumf or dasdfmt as example)
autocomplete-bin := autocompletion_generator_host
autocomp-object := $(rootdir)/libutil/util_autocomp_host.o
$(autocomp-object): $(rootdir)/libutil
$(MAKE) -C $(rootdir)/libutil/ $(notdir $@)
$(autocomplete-bin).o: $(autocomplete-bin).c
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I $(rootdir)/include -c $< -o $@
$(autocomplete-bin): $(autocomplete-bin).o $(autocomp-object)
$(LINK_FOR_BUILD) $^ -o $@
$(bash-completions) $(zsh-completions) &: $(autocomplete-bin)
./$(autocomplete-bin)
install-shell-completions: $(bash-completions) $(zsh-completions)
$(INSTALL) -d -m 755 $(DESTDIR)$(ZSHCOMPLETIONDIR)
$(INSTALL) -d -m 755 $(DESTDIR)$(BASHCOMPLETIONDIR)
for completion in $(bash-completions); do \
$(INSTALL) -m 644 $$completion $(DESTDIR)$(BASHCOMPLETIONDIR); \
done
for completion in $(zsh-completions); do \
$(INSTALL) -m 644 $$completion $(DESTDIR)$(ZSHCOMPLETIONDIR); \
done
all: $(zsh-completions) $(bash-completions)
install: install-shell-completions
.PHONY: install-shell-completions $(rootdir)/libutil
clean-autocomplete-bin:
$(RM) -- $(autocomplete-bin)
clean: clean-autocomplete-bin
ifdef bash-completions
clean-bash-completions:
$(RM) -- $(bash-completions)
clean: clean-bash-completions
endif
ifdef zsh-completions
clean-zsh-completions:
$(RM) -- $(zsh-completions)
clean: clean-zsh-completions
endif
.PHONY: clean-autocomplete-bin clean-bash-completions clean-zsh-completions

View File

@@ -79,9 +79,11 @@ the cpacfstats client application.
Example usage scenario:
.P
1. Start the cpacfstatsd daemon with root privileges.
1. Start the cpacfstatsd daemon with root privileges using 'systemctl start
cpacfstatsd'.
.P
2. Check for successful startup by using the ps and syslog commands.
2. Check for successful startup by using the 'systemctl status cpacfstatsd'
command.
.P
3. Enable the CPACF counters of interest. For example, enable all counters
by issuing cpacfstats -e.
@@ -95,7 +97,7 @@ cryptographic counters as required. To reset, use, for example, cpacfstats
6. Disable all the CPACF measurements, for example, by using cpacfstats
-d.
.P
7. Shutdown the cpacfstatsd daemon by using killall cpacfstatsd.
7. Shutdown the cpacfstatsd daemon by using 'systemctl stop cpacfstatsd'.
.SH OPTIONS
.TP
@@ -177,6 +179,12 @@ the errno value.
ECC counters are only available since z15. cpacfstats will show the
counters as \fIunsupported\fR if the hardware does not support ECC
counters.
CPU-MF counters have to be authorized on HMC or SE to be available and are
otherwise shown as \fIunauthorized\fR. On the HMC or SE, authorize the LPAR
for each counter set you want to use. Customize the LPAR activation profile
and modify the Counter Facility Security Options. You need to activate the
\fICrypto activity counter set authorization control\fR checkbox.
.
.SH APPENDIX
The detailed pai counter names are:

View File

@@ -175,9 +175,10 @@ static void print_virtual_counter_answer(int s,
int ctr, int state, uint64_t value)
{
static const char *const states[] = {
[DISABLED] = "disabled",
[ENABLED] = "enabled",
[UNSUPPORTED] = "unsupported"
[DISABLED] = "disabled",
[ENABLED] = "enabled",
[UNSUPPORTED] = "unsupported",
[UNAUTHORIZED] = "unauthorized"
};
int paictr = 0, paistate = 0, ec;
uint64_t i, paivalue = 0;
@@ -242,6 +243,8 @@ static void print_answer(int s, int ctr, int state, uint64_t value)
printf(" %s counter: disabled\n", counter_str[ctr]);
else if (state == UNSUPPORTED)
printf(" %s counter: unsupported\n", counter_str[ctr]);
else if (state == UNAUTHORIZED)
printf(" %s counter: unauthorized\n", counter_str[ctr]);
else
printf(" %s counter: %lu\n", counter_str[ctr], value);
}

View File

@@ -74,7 +74,8 @@ enum cmd_e {
enum state_e {
DISABLED = 0,
ENABLED,
UNSUPPORTED
UNSUPPORTED,
UNAUTHORIZED
};
enum counter_type {

View File

@@ -179,7 +179,7 @@ static int do_enable(int s, enum ctr_e ctr, unsigned int *supported_counters)
}
state = ENABLED;
}
if (state != UNSUPPORTED) {
if (state != UNSUPPORTED && state != UNAUTHORIZED) {
rc = perf_read_ctr(i, &value, supported_counters);
if (rc != 0) {
send_answer(s, i, rc, 0);

View File

@@ -141,6 +141,10 @@ static int perf_counter_supported(const char *pmu, const char *counter)
return !access(buf, R_OK);
}
/**
* Returns 1 if counters are authorized, -1 if counters are unauthorized,
* and 0 otherwise which indicates that the counters are unsupported
*/
static int cpumf_authorized(void)
{
unsigned vermin, vermax, auth;
@@ -159,10 +163,12 @@ static int cpumf_authorized(void)
if (sscanf(line,
"CPU-MF: Counter facility: version=%d.%d authorization=%x",
&vermin, &vermax, &auth) == 3) {
if (auth & 0x8)
if (auth & 0x8) {
res = 1;
else
} else {
eprint("CPU-MF counters not authorized.\n");
res = -1;
}
found = 1;
break;
}
@@ -233,7 +239,7 @@ static int activatecpu(unsigned int cpu, unsigned int *supported_counters)
}
/* activate CPU-MF */
for (i = 0; i < ALL_COUNTER; ++i) {
if (ctr_state[i] == UNSUPPORTED)
if (ctr_state[i] == UNSUPPORTED || ctr_state[i] == UNAUTHORIZED)
continue;
memset(&pfm_event, 0, sizeof(pfm_event));
pfm_event.size = sizeof(pfm_event);
@@ -398,7 +404,7 @@ static int perf_load_counter_data(void)
int i, res = 0;
for (i = 0; i < ALL_COUNTER; ++i) {
if (ctr_state[i] != UNSUPPORTED)
if (ctr_state[i] != UNSUPPORTED && ctr_state[i] != UNAUTHORIZED)
res |= perf_event_encode(&pmf_counter_data[i].pmutype,
&pmf_counter_data[i].eventid,
pmf_counter_name[i].pmu,
@@ -474,6 +480,7 @@ int perf_init(unsigned int *supported_counters)
};
unsigned long maxfd;
struct rlimit rlim;
int cpumf_state;
int i, num;
FILE *f;
@@ -487,10 +494,15 @@ int perf_init(unsigned int *supported_counters)
* counters for PAI. */
num = ALL_COUNTER + 2;
if (!cpumf_authorized()) {
cpumf_state = cpumf_authorized();
if (cpumf_state == 0) {
for (i = 0; i < ALL_COUNTER; ++i)
ctr_state[i] = UNSUPPORTED;
num -= ALL_COUNTER;
} else if (cpumf_state == -1) {
for (i = 0; i < ALL_COUNTER; ++i)
ctr_state[i] = UNAUTHORIZED;
num -= ALL_COUNTER;
} else {
for (i = 0; i < ALL_COUNTER; i++) {
if (!perf_counter_supported("cpum_cf", cpum_cf[i])) {

View File

@@ -16,6 +16,7 @@
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>

View File

@@ -3,6 +3,11 @@ include ../common.mak
BIN_FILES = lscpumf chcpumf lshwc pai lspai
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8 lspai.8
zsh-completions := $(addprefix _,$(BIN_FILES))
bash-completions := $(addsuffix .bash,$(BIN_FILES))
include ../common_autocomp.mak
all: $(BIN_FILES)
libs = $(rootdir)/libcpumf/libcpumf.a $(rootdir)/libutil/libutil.a

View File

@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
/*
* Autocompletion generation - for cpumf family of tools
*
* Copyright IBM Corp. 2025
*
* 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 "lib/util_autocomp.h"
#include "chcpumf_cli.h"
#include "lscpumf_cli.h"
#include "lshwc_cli.h"
#include "lspai_cli.h"
#include "pai_cli.h"
int main(void)
{
generate_autocomp(chcpumf_opt_vec, "chcpumf");
generate_autocomp(lscpumf_opt_vec, "lscpumf");
generate_autocomp(lshwc_opt_vec, "lshwc");
generate_autocomp(lspai_opt_vec, "lspai");
generate_autocomp(pai_opt_vec, "pai");
return 0;
}

View File

@@ -7,7 +7,7 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
@@ -17,37 +17,15 @@
#include <sys/stat.h>
#include "lib/libcpumf.h"
#include "lib/util_base.h"
#include "lib/util_opt.h"
#include "lib/util_path.h"
#include "lib/util_prg.h"
#include "chcpumf_cli.h"
static unsigned int verbose;
static unsigned long min_sdb, max_sdb;
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "min", required_argument, NULL, 'm' },
.argument = "num_sdb",
.desc = "Specifies the initial size of the sampling buffer.\n"
"A sample-data-block (SDB) consumes about 4 kilobytes.",
},
{
.option = { "max", required_argument, NULL, 'x' },
.argument = "num_sdb",
.desc = "Specifies the maximum size of the sampling buffer.\n"
"A sample-data-block (SDB) consumes about 4 kilobytes.",
},
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Verbose, display new sample-data-block values.",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "Change CPU Measurement facility charactertics",
.copyright_vec = {
@@ -163,7 +141,7 @@ int main(int argc, char **argv)
unsigned long my_min, my_max;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
util_opt_init(chcpumf_opt_vec, NULL);
parse_args(argc, argv);
if (geteuid())

40
cpumf/chcpumf_cli.h Normal file
View File

@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for chcpumf
*
* Copyright IBM Corp. 2025
*
* 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 CHCPUMF_CLI_H
#define CHCPUMF_CLI_H
#include "lib/util_fmt.h"
#include "lib/util_opt.h"
static struct util_opt chcpumf_opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "min", required_argument, NULL, 'm' },
.argument = "num_sdb",
.desc = "Specifies the initial size of the sampling buffer.\n"
"A sample-data-block (SDB) consumes about 4 kilobytes.",
},
{
.option = { "max", required_argument, NULL, 'x' },
.argument = "num_sdb",
.desc = "Specifies the maximum size of the sampling buffer.\n"
"A sample-data-block (SDB) consumes about 4 kilobytes.",
},
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Verbose, display new sample-data-block values.",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -7,8 +7,7 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <errno.h>
#include <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
@@ -31,6 +30,8 @@
#include "lib/libcpumf.h"
#include "lscpumf_cli.h"
#define ACTION_NONE 0
#define ACTION_INFO 1
#define ACTION_CNT 2
@@ -47,33 +48,6 @@ static bool actions[ACTION_SAMPLE + 1]; /* Specified command line options */
/* File names to read data from */
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "list-counters", no_argument, NULL, 'c' },
.desc = "Lists counters for which the LPAR is authorized.",
},
{
.option = { "list-all-counters", no_argument, NULL, 'C' },
.desc = "Lists counters regardless of LPAR authorization.",
},
{
.option = { "name", no_argument, NULL, 'n' },
.desc = "Displays counter names.",
},
{
.option = { "info", no_argument, NULL, 'i' },
.desc = "Displays detailed information.",
},
{
.option = { "list-sampling-events", no_argument, NULL, 's' },
.desc = "Lists sampling events for which the LPAR is authorized.",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "List CPU Measurement facility charactertics",
.copyright_vec = {
@@ -4160,7 +4134,7 @@ int main(int argc, char **argv)
int ret;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
util_opt_init(lscpumf_opt_vec, NULL);
ret = parse_args(argc, argv);
if (read_info() == EXIT_FAILURE)

44
cpumf/lscpumf_cli.h Normal file
View File

@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for lscpumf
*
* Copyright IBM Corp. 2025
*
* 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 LSCPUMF_CLI_H
#define LSCPUMF_CLI_H
#include "lib/util_fmt.h"
#include "lib/util_opt.h"
static struct util_opt lscpumf_opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "list-counters", no_argument, NULL, 'c' },
.desc = "Lists counters for which the LPAR is authorized.",
},
{
.option = { "list-all-counters", no_argument, NULL, 'C' },
.desc = "Lists counters regardless of LPAR authorization.",
},
{
.option = { "name", no_argument, NULL, 'n' },
.desc = "Displays counter names.",
},
{
.option = { "info", no_argument, NULL, 'i' },
.desc = "Displays detailed information.",
},
{
.option = { "list-sampling-events", no_argument, NULL, 's' },
.desc = "Lists sampling events for which the LPAR is authorized.",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -43,6 +43,7 @@
#include "lib/libcpumf.h"
#include "lshwc.h"
#include "lshwc_cli.h"
#define CPUS_ONLINE "/sys/devices/system/cpu/online"
#define CPUS_POSSIBLE "/sys/devices/system/cpu/possible"
@@ -732,67 +733,6 @@ static int do_it(char *s)
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Displays all CPUs in output"
},
{
.option = { "loop", required_argument, NULL, 'l' },
.argument = "NUMBER",
.desc = "Specifies loop count for next read"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "NUMBER",
.desc = "Specifies interval between read operations (seconds)"
},
{
.option = { "short", no_argument, NULL, 's' },
.desc = "Abbreviate counter name with counter set letter and number"
},
{
.option = { "hex0x", no_argument, NULL, 'X' },
.desc = "Counter values in hexadecimal format with leading 0x"
},
{
.option = { "hex", no_argument, NULL, 'x' },
.desc = "Counter values in hexadecimal format"
},
{
.option = { "hide", no_argument, NULL, 'H' },
.desc = "Do not display undefined counters of a counter set"
},
{
.option = { "delta", no_argument, NULL, 'd' },
.desc = "Display delta counter values"
},
{
.option = { "timeout", required_argument, NULL, 't' },
.argument = "NUMBER",
.desc = "run time in s (seconds) m (minutes) h (hours) and d (days)"
},
{
.option = { "quote-all", no_argument, NULL, 'q' },
.desc = "Apply quoting to all output elements"
},
{
.option = { "format", required_argument, NULL, 'f' },
.argument = "FORMAT",
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
},
{
.option = { "counters", required_argument, NULL, 'c' },
.argument = "LIST",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "Specify comma separated list of counters to display"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "Read CPU Measurement facility counter sets",
.copyright_vec = {
@@ -823,7 +763,7 @@ int main(int argc, char **argv)
int ch;
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
util_opt_init(lshwc_opt_vec, NULL);
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
switch (ch) {

78
cpumf/lshwc_cli.h Normal file
View File

@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for lshwc
*
* Copyright IBM Corp. 2025
*
* 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 LSHWC_CLI_H
#define LSHWC_CLI_H
#include "lib/util_fmt.h"
#include "lib/util_opt.h"
static struct util_opt lshwc_opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Displays all CPUs in output"
},
{
.option = { "loop", required_argument, NULL, 'l' },
.argument = "NUMBER",
.desc = "Specifies loop count for next read"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "NUMBER",
.desc = "Specifies interval between read operations (seconds)"
},
{
.option = { "short", no_argument, NULL, 's' },
.desc = "Abbreviate counter name with counter set letter and number"
},
{
.option = { "hex0x", no_argument, NULL, 'X' },
.desc = "Counter values in hexadecimal format with leading 0x"
},
{
.option = { "hex", no_argument, NULL, 'x' },
.desc = "Counter values in hexadecimal format"
},
{
.option = { "hide", no_argument, NULL, 'H' },
.desc = "Do not display undefined counters of a counter set"
},
{
.option = { "delta", no_argument, NULL, 'd' },
.desc = "Display delta counter values"
},
{
.option = { "timeout", required_argument, NULL, 't' },
.argument = "NUMBER",
.desc = "run time in s (seconds) m (minutes) h (hours) and d (days)"
},
{
.option = { "quote-all", no_argument, NULL, 'q' },
.desc = "Apply quoting to all output elements"
},
{
.option = { "format", required_argument, NULL, 'f' },
.argument = "FORMAT",
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
},
{
.option = { "counters", required_argument, NULL, 'c' },
.argument = "LIST",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "Specify comma separated list of counters to display"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -35,69 +35,7 @@
#include "lib/util_str.h"
#include "lib/libcpumf.h"
#define STR_SUB(x) #x
#define STR(x) STR_SUB(x)
#define OPT_FORMAT 256 /* --format XXX option */
#define DEFAULT_LOOP_INTERVAL 60 /* loop interval in seconds */
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Displays all CPUs in output"
},
{
.option = { "delta", no_argument, NULL, 'd' },
.desc = "Display delta counter values"
},
{
.option = { "counters", required_argument, NULL, 'c' },
.argument = "LIST",
.desc = "Specify comma separated list of counters to display"
},
{
.option = { "format", required_argument, NULL, OPT_FORMAT },
.argument = "FORMAT",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
},
{
.option = { "loops", required_argument, NULL, 'l' },
.argument = "COUNT",
.desc = "Number of read operations"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "SECONDS",
.desc = "Time to wait between loop iterations (default "
STR(DEFAULT_LOOP_INTERVAL) "s)"
},
{
.option = { "numeric", no_argument, NULL, 'n' },
.desc = "Sort PAI counters by counter number"
},
{
.option = { "short", no_argument, NULL, 's' },
.desc = "Abbreviate counter name with counter set letter and number"
},
{
.option = { "type", required_argument, NULL, 't' },
.argument = "TYPE",
.desc = "Type of PAI counters to show: crypto, nnpa"
},
{
.option = { "hex0x", no_argument, NULL, 'X' },
.desc = "Counter values in hexadecimal format with leading 0x"
},
{
.option = { "hex", no_argument, NULL, 'x' },
.desc = "Counter values in hexadecimal format"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#include "lspai_cli.h"
static const struct util_prg prg = {
.desc = "List Processor Assist Information counter sets",
@@ -727,7 +665,7 @@ int main(int argc, char **argv)
util_list_init(&pai_list, struct pai_node, node);
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
util_opt_init(lspai_opt_vec, NULL);
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
switch (ch) {

81
cpumf/lspai_cli.h Normal file
View File

@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for lspai
*
* Copyright IBM Corp. 2025
*
* 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 LSPAI_CLI_H
#define LSPAI_CLI_H
#include "lib/util_fmt.h"
#include "lib/util_opt.h"
#define STR_SUB(x) #x
#define STR(x) STR_SUB(x)
#define OPT_FORMAT 256 /* --format XXX option */
#define DEFAULT_LOOP_INTERVAL 60 /* loop interval in seconds */
static struct util_opt lspai_opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Displays all CPUs in output"
},
{
.option = { "delta", no_argument, NULL, 'd' },
.desc = "Display delta counter values"
},
{
.option = { "counters", required_argument, NULL, 'c' },
.argument = "LIST",
.desc = "Specify comma separated list of counters to display"
},
{
.option = { "format", required_argument, NULL, OPT_FORMAT },
.argument = "FORMAT",
.flags = UTIL_OPT_FLAG_NOSHORT,
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
},
{
.option = { "loops", required_argument, NULL, 'l' },
.argument = "COUNT",
.desc = "Number of read operations"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "SECONDS",
.desc = "Time to wait between loop iterations (default "
STR(DEFAULT_LOOP_INTERVAL) "s)"
},
{
.option = { "numeric", no_argument, NULL, 'n' },
.desc = "Sort PAI counters by counter number"
},
{
.option = { "short", no_argument, NULL, 's' },
.desc = "Abbreviate counter name with counter set letter and number"
},
{
.option = { "type", required_argument, NULL, 't' },
.argument = "TYPE",
.desc = "Type of PAI counters to show: crypto, nnpa"
},
{
.option = { "hex0x", no_argument, NULL, 'X' },
.desc = "Counter values in hexadecimal format with leading 0x"
},
{
.option = { "hex", no_argument, NULL, 'x' },
.desc = "Counter values in hexadecimal format"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -40,7 +40,9 @@
#include "lib/util_prg.h"
#include "lib/util_scandir.h"
#include "lib/libcpumf.h"
#include "pai.h"
#include "pai_cli.h"
#define S390_EVT_PAI_CRYPTO 0x1000
#define S390_EVT_PAI_NNPA 0x1800
@@ -501,7 +503,7 @@ static int evt_scan(char *fn, unsigned char *buf, size_t len,
__u64 sample_type = pa->sample_type;
int allcnt = 0, cnt = 0, rawok = 0;
struct perf_event_header *hdr;
size_t offset = sizeof(*pa);
size_t offset = pa->size;
__u64 evtnum = pa->config;
struct pai_event_out ev;
size_t limit;
@@ -512,6 +514,8 @@ static int evt_scan(char *fn, unsigned char *buf, size_t len,
unsigned char valid;
} last_csout = { 0, 0, 0 };
if (verbose && (sizeof(*pa) != pa->size))
printf("size perf_event_attr mismatch %zu/%zu\n", sizeof(*pa), offset);
while (offset < len) {
hdr = (struct perf_event_header *)(buf + offset);
memset(&ev, 0, sizeof(ev));
@@ -833,7 +837,7 @@ static int map_check(char *fn, int (*fct)(char *, unsigned char *, size_t,
return 0;
}
p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
p = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
warnx("%s cannot map file", fn);
close(fd);
@@ -925,54 +929,6 @@ static void parse_cpulist(int enr, const char *parm)
}
}
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "crypto", optional_argument, NULL, 'c' },
.argument = "CPULIST[:DATA]",
.desc = "Collect PAI crypto counters"
},
{
.option = { "nnpa", optional_argument, NULL, 'n' },
.argument = "CPULIST[:DATA]",
.desc = "Collect PAI nnpa counters"
},
{
.option = { "mapsize", required_argument, NULL, 'm' },
.argument = "SIZE",
.desc = "Specifies number of 4KB pages for event ring buffer"
},
{
.option = { "report", no_argument, NULL, 'r' },
.desc = "Report file contents"
},
{
.option = { "realtime", required_argument, NULL, 'R' },
.argument = "PRIO",
.desc = "Collect data with this RT SCHED_FIFO priority"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "NUMBER",
.desc = "Specifies interval between read operations in milliseconds"
},
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Verbose output"
},
{
.option = { "humantime", no_argument, NULL, 'H' },
.desc = "Human readable timestamp in seconds.nanoseconds"
},
{
.option = { "summary", no_argument, NULL, 'S' },
.desc = "Print summary of all non-zero counter values"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static const struct util_prg prg = {
.desc = "Record and report Processor Activity Instrumentation Facility Counters.",
.copyright_vec = {
@@ -1038,7 +994,7 @@ int main(int argc, char **argv)
util_list_init(&list_pai_event, struct pai_event, node);
util_list_init(&list_pmu_event, struct pmu_events, node);
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
util_opt_init(pai_opt_vec, NULL);
/* Read currently online CPUs and create a bit mask.
* This bitmap of online CPUs is used to check command line parameter

65
cpumf/pai_cli.h Normal file
View File

@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for pai
*
* Copyright IBM Corp. 2025
*
* 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 PAI_CLI_H
#define PAI_CLI_H
#include "lib/util_fmt.h"
#include "lib/util_opt.h"
static struct util_opt pai_opt_vec[] = {
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "crypto", optional_argument, NULL, 'c' },
.argument = "CPULIST[:DATA]",
.desc = "Collect PAI crypto counters"
},
{
.option = { "nnpa", optional_argument, NULL, 'n' },
.argument = "CPULIST[:DATA]",
.desc = "Collect PAI nnpa counters"
},
{
.option = { "mapsize", required_argument, NULL, 'm' },
.argument = "SIZE",
.desc = "Specifies number of 4KB pages for event ring buffer"
},
{
.option = { "report", no_argument, NULL, 'r' },
.desc = "Report file contents"
},
{
.option = { "realtime", required_argument, NULL, 'R' },
.argument = "PRIO",
.desc = "Collect data with this RT SCHED_FIFO priority"
},
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "NUMBER",
.desc = "Specifies interval between read operations in milliseconds"
},
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Verbose output"
},
{
.option = { "humantime", no_argument, NULL, 'H' },
.desc = "Human readable timestamp in seconds.nanoseconds"
},
{
.option = { "summary", no_argument, NULL, 'S' },
.desc = "Print summary of all non-zero counter values"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -1,5 +1,10 @@
include ../common.mak
zsh-completions = _dasdfmt
bash-completions = dasdfmt.bash
include ../common_autocomp.mak
all: dasdfmt
libs = $(rootdir)/libdasd/libdasd.a \

View File

@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
/*
* Autocompletion generation - for dasdfmt tool
*
* Copyright IBM Corp. 2025
*
* 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 "lib/util_autocomp.h"
#include "dasdfmt_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "dasdfmt");
return 0;
}

View File

@@ -24,6 +24,7 @@
#include "lib/zt_common.h"
#include "dasdfmt.h"
#include "dasdfmt_cli.h"
#define BUSIDSIZE 8
#define SEC_PER_DAY (60 * 60 * 24)
@@ -81,112 +82,6 @@ static struct dasdfmt_globals {
.dasd_info = { 0 },
};
/* Defines for options with no short command */
#define OPT_CHECK 128
#define OPT_NOZERO 129
#define OPT_NODISCARD 130
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("FORMAT ACTIONS"),
{
.option = { "mode", required_argument, NULL, 'M' },
.argument = "MODE",
.desc = "Specify scope of operation using MODE:\n"
" full: Full device (default)\n"
" quick: Only the first two tracks\n"
" expand: Unformatted tracks at device end",
},
{
.option = { "check", no_argument, NULL, OPT_CHECK },
.desc = "Perform complete format check on device",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("FORMAT OPTIONS"),
{
.option = { "blocksize", required_argument, NULL, 'b' },
.argument = "SIZE",
.desc = "Format blocks to SIZE bytes (default 4096)",
},
{
.option = { "disk_layout", required_argument, NULL, 'd' },
.argument = "LAYOUT",
.desc = "Specify the disk layout:\n"
" cdl: Compatible Disk Layout (default)\n"
" ldl: Linux Disk Layout",
},
{
.option = { "keep_volser", no_argument, NULL, 'k' },
.desc = "Do not change the current volume serial",
},
{
.option = { "label", required_argument, NULL, 'l' },
.argument = "VOLSER",
.desc = "Specify volume serial number",
},
{
.option = { "no_label", no_argument, NULL, 'L' },
.desc = "Don't write a disk label",
},
{
.option = { "requestsize", required_argument, NULL, 'r' },
.argument = "NUM",
.desc = "Process NUM cylinders in one formatting step",
},
{
.option = { "norecordzero", no_argument, NULL, OPT_NOZERO },
.desc = "Prevent storage server from modifying record 0",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "no-discard", no_argument, NULL, OPT_NODISCARD },
.desc = "Do not discard space before formatting",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { NULL, no_argument, NULL, 'y' },
.desc = "Start formatting without further user-confirmation",
.flags = UTIL_OPT_FLAG_NOLONG,
},
UTIL_OPT_SECTION("DISPLAY PROGRESS"),
{
.option = { "hashmarks", required_argument, NULL, 'm' },
.argument = "NUM",
.desc = "Show a hashmark every NUM cylinders",
},
{
.option = { "progressbar", no_argument, NULL, 'p' },
.desc = "Show a progressbar",
},
{
.option = { "percentage", no_argument, NULL, 'P' },
.desc = "Show progress in percent",
},
UTIL_OPT_SECTION("MISC"),
{
.option = { "check_host_count", no_argument, NULL, 'C' },
.desc = "Check if device is in use by other hosts",
},
{
.option = { "force", no_argument, NULL, 'F' },
.desc = "Format without performing sanity checking",
},
{
.option = { "test", no_argument, NULL, 't' },
.desc = "Run in dry-run mode without modifying the DASD",
},
{
.option = { NULL, no_argument, NULL, 'v' },
.desc = "Print verbose messages when executing",
.flags = UTIL_OPT_FLAG_NOLONG,
},
UTIL_OPT_HELP,
{
.option = { "version", no_argument, NULL, 'V' },
.desc = "Print version information, then exit",
},
UTIL_OPT_END
};
/* Report error, free memory, and exit */
static void error(const char *format, ...)
{

View File

@@ -19,6 +19,7 @@
#include <limits.h>
#include <mntent.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -69,13 +70,13 @@ static void error(const char *format, ...)
"is in invalid format\n",prog_name);}
typedef struct bootstrap1 {
u_int32_t key;
u_int32_t data[6];
uint32_t key;
uint32_t data[6];
} __attribute__ ((packed)) bootstrap1_t;
typedef struct bootstrap2 {
u_int32_t key;
u_int32_t data[36];
uint32_t key;
uint32_t data[36];
} __attribute__ ((packed)) bootstrap2_t;

123
dasdfmt/dasdfmt_cli.h Normal file
View File

@@ -0,0 +1,123 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for dasdfmt
*
* Copyright IBM Corp. 2025
*
* 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 DASDFMT_CLI_H
#define DASDFMT_CLI_H
#include "lib/util_fmt.h"
#include "lib/util_opt.h"
/* Defines for options with no short command */
#define OPT_CHECK 128
#define OPT_NOZERO 129
#define OPT_NODISCARD 130
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("FORMAT ACTIONS"),
{
.option = { "mode", required_argument, NULL, 'M' },
.argument = "MODE",
.desc = "Specify scope of operation using MODE:\n"
" full: Full device (default)\n"
" quick: Only the first two tracks\n"
" expand: Unformatted tracks at device end",
},
{
.option = { "check", no_argument, NULL, OPT_CHECK },
.desc = "Perform complete format check on device",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("FORMAT OPTIONS"),
{
.option = { "blocksize", required_argument, NULL, 'b' },
.argument = "SIZE",
.desc = "Format blocks to SIZE bytes (default 4096)",
},
{
.option = { "disk_layout", required_argument, NULL, 'd' },
.argument = "LAYOUT",
.desc = "Specify the disk layout:\n"
" cdl: Compatible Disk Layout (default)\n"
" ldl: Linux Disk Layout",
},
{
.option = { "keep_volser", no_argument, NULL, 'k' },
.desc = "Do not change the current volume serial",
},
{
.option = { "label", required_argument, NULL, 'l' },
.argument = "VOLSER",
.desc = "Specify volume serial number",
},
{
.option = { "no_label", no_argument, NULL, 'L' },
.desc = "Don't write a disk label",
},
{
.option = { "requestsize", required_argument, NULL, 'r' },
.argument = "NUM",
.desc = "Process NUM cylinders in one formatting step",
},
{
.option = { "norecordzero", no_argument, NULL, OPT_NOZERO },
.desc = "Prevent storage server from modifying record 0",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "no-discard", no_argument, NULL, OPT_NODISCARD },
.desc = "Do not discard space before formatting",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { NULL, no_argument, NULL, 'y' },
.desc = "Start formatting without further user-confirmation",
.flags = UTIL_OPT_FLAG_NOLONG,
},
UTIL_OPT_SECTION("DISPLAY PROGRESS"),
{
.option = { "hashmarks", required_argument, NULL, 'm' },
.argument = "NUM",
.desc = "Show a hashmark every NUM cylinders",
},
{
.option = { "progressbar", no_argument, NULL, 'p' },
.desc = "Show a progressbar",
},
{
.option = { "percentage", no_argument, NULL, 'P' },
.desc = "Show progress in percent",
},
UTIL_OPT_SECTION("MISC"),
{
.option = { "check_host_count", no_argument, NULL, 'C' },
.desc = "Check if device is in use by other hosts",
},
{
.option = { "force", no_argument, NULL, 'F' },
.desc = "Format without performing sanity checking",
},
{
.option = { "test", no_argument, NULL, 't' },
.desc = "Run in dry-run mode without modifying the DASD",
},
{
.option = { NULL, no_argument, NULL, 'v' },
.desc = "Print verbose messages when executing",
.flags = UTIL_OPT_FLAG_NOLONG,
},
UTIL_OPT_HELP,
{
.option = { "version", no_argument, NULL, 'V' },
.desc = "Print version information, then exit",
},
UTIL_OPT_END
};
#endif

View File

@@ -33,6 +33,11 @@
#define RD_BUFFER_SIZE 80
#define TEMP_DEV_MAX_RETRIES 1000
#ifndef FTW_CONTINUE
#define FTW_CONTINUE 0
#define FTW_STOP 1
#endif
static const struct util_prg prg = {
.desc = "Display DASD volume serial number and ID information",
.args = "-i BUSID | -b BLOCKDEV | -d DEVNODE",
@@ -212,7 +217,7 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
if (lseek(f, vlabel_start, SEEK_SET) < 0)
goto error_close;
bzero(vlabel, vlsize);
memset(vlabel, 0, vlsize);
if (read(f, vlabel, vlsize) != vlsize) {
warnx("Could not read volume label");
@@ -220,15 +225,15 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
}
if (dasd_info.FBA_layout) {
bzero(&tmp, vlsize);
memset(&tmp, 0, vlsize);
memcpy(&tmp, vlabel, vlsize);
memcpy(vlabel->vollbl, &tmp, vlsize - 4);
}
close(f);
bzero(readbuf, 7);
bzero(vollbl, 5);
memset(readbuf, 0, 7);
memset(vollbl, 0, 5);
strncpy(vollbl, vlabel->vollbl, 4);
dinfo_ebcdic_dec(vollbl, vollbl, 4);
@@ -334,7 +339,7 @@ static int dinfo_extract_dev(dev_t *dev, char *str)
char *p = NULL;
int ma, mi;
bzero(tmp, RD_BUFFER_SIZE);
memset(tmp, 0, RD_BUFFER_SIZE);
util_strlcpy(tmp, str, RD_BUFFER_SIZE);
p = strchr(tmp, ':');
if (p == NULL) {
@@ -381,10 +386,8 @@ static int
dinfo_is_busiddir(const char *fpath, const struct stat *UNUSED(sb),
int tflag, struct FTW *ftwbuf)
{
enum { LINK_DIR_SIZE = 128 };
char linkdir[LINK_DIR_SIZE];
char *tempdir;
ssize_t i;
char *linkdir;
if (tflag != FTW_D || (strncmp((fpath + ftwbuf->base), searchbusid,
strlen(searchbusid)) != 0))
@@ -396,14 +399,13 @@ dinfo_is_busiddir(const char *fpath, const struct stat *UNUSED(sb),
*/
if (asprintf(&tempdir, "%s/driver", fpath) < 0)
return -1;
i = readlink(tempdir, linkdir, LINK_DIR_SIZE);
linkdir = util_readlink(tempdir);
free(tempdir);
if (i < 0 || i >= LINK_DIR_SIZE)
return -1;
/* append '\0' because readlink returns non zero terminated string */
linkdir[i] = '\0';
if (strstr(linkdir, "dasd") == NULL)
if (strstr(linkdir, "dasd") == NULL) {
free(linkdir);
return FTW_CONTINUE;
}
free(linkdir);
free(busiddir);
busiddir = strdup(fpath);
if (busiddir == NULL)

View File

@@ -7,7 +7,6 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#define _LARGEFILE64_SOURCE /* needed for unistd.h */
#define _FILE_OFFSET_BITS 64 /* needed for unistd.h */
#include <ctype.h>
@@ -17,6 +16,7 @@
#include <linux/version.h>
#include <malloc.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -428,7 +428,7 @@ dasdview_read_vlabel(dasdview_info_t *info, volume_label_t *vlabel)
pos = info->dasd_info.label_block * info->blksize;
bzero(vlabel, sizeof(volume_label_t));
memset(vlabel, 0, sizeof(volume_label_t));
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
!info->dasd_info.FBA_layout) {
/* OS/390 and zOS compatible disk layout */
@@ -466,7 +466,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
printf("\n--- volume label -----------------------------"
"---------------------------------\n");
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.volkey, 4);
memset(s4, 0, 5);
memset(t4, 0, 5);
strncpy((char *)s4, vlabel.volkey, 4);
printf("volume label key : ascii '%4s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
printf(" : ebcdic '%4s'\n", t4);
@@ -474,7 +476,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 4; i++)
printf("%02x", s4[i]);
bzero(s4, 5); bzero(s4, 5); strncpy((char *)s4, vlabel.vollbl, 4);
memset(s4, 0, 5);
memset(t4, 0, 5);
strncpy((char *)s4, vlabel.vollbl, 4);
printf("\n\nvolume label identifier : ascii '%4s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
printf(" : ebcdic '%4s'\n", t4);
@@ -482,7 +486,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 4; i++)
printf("%02x", s4[i]);
bzero(s6, 7); bzero(t6, 7); strncpy((char *)s6, vlabel.volid, 6);
memset(s6, 0, 7);
memset(t6, 0, 7);
strncpy((char *)s6, vlabel.volid, 6);
printf("\n\nvolume identifier : ascii '%6s'\n", s6);
vtoc_ebcdic_dec((char *)s6, (char *)t6, 6);
printf(" : ebcdic '%6s'\n", t6);
@@ -503,7 +509,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
vtoc_get_cyl_from_cchhb(&vlabel.vtoc),
vtoc_get_head_from_cchhb(&vlabel.vtoc), vlabel.vtoc.b);
bzero(s5, 6); bzero(t5, 6); strncpy((char *)s5, vlabel.res1, 5);
memset(s5, 0, 6);
memset(t5, 0, 6);
strncpy((char *)s5, vlabel.res1, 5);
printf("reserved : ascii '%5s'\n", s5);
vtoc_ebcdic_dec((char *)s5, (char *)t5, 5);
printf(" : ebcdic '%5s'\n", t5);
@@ -511,7 +519,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 5; i++)
printf("%02x", s5[i]);
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.cisize, 4);
memset(s4, 0, 5);
memset(t4, 0, 5);
strncpy((char *)s4, vlabel.cisize, 4);
printf("\n\nCI size for FBA : ascii '%4s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
printf(" : ebcdic '%4s'\n", t4);
@@ -519,7 +529,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 4; i++)
printf("%02x", s4[i]);
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.blkperci, 4);
memset(s4, 0, 5);
memset(t4, 0, 5);
strncpy((char *)s4, vlabel.blkperci, 4);
printf("\n\nblocks per CI (FBA) : ascii '%4s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
printf(" : ebcdic '%4s'\n", t4);
@@ -527,7 +539,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 4; i++)
printf("%02x", s4[i]);
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.labperci, 4);
memset(s4, 0, 5);
memset(t4, 0, 5);
strncpy((char *)s4, vlabel.labperci, 4);
printf("\n\nlabels per CI (FBA) : ascii '%4s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
printf(" : ebcdic '%4s'\n", t4);
@@ -535,7 +549,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 4; i++)
printf("%02x", s4[i]);
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.res2, 4);
memset(s4, 0, 5);
memset(t4, 0, 5);
strncpy((char *)s4, vlabel.res2, 4);
printf("\n\nreserved : ascii '%4s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
printf(" : ebcdic '%4s'\n", t4);
@@ -543,7 +559,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
for (i = 0; i < 4; i++)
printf("%02x", s4[i]);
bzero(s14, 15); bzero(t14, 15); strncpy(s14, vlabel.lvtoc, 14);
memset(s14, 0, 15);
memset(t14, 0, 15);
strncpy(s14, vlabel.lvtoc, 14);
printf("\n\nowner code for VTOC : ascii '%14s'\n", s14);
vtoc_ebcdic_dec(s14, t14, 14);
printf(" ebcdic '%14s'\n", t14);
@@ -556,9 +574,10 @@ dasdview_print_vlabel(dasdview_info_t *info)
printf(" ");
}
bzero(s29, 30); strncpy(s29, vlabel.res3, 28);
memset(s29, 0, 30);
strncpy(s29, vlabel.res3, 28);
printf("\n\nreserved : ascii '%28s'\n", s29);
bzero(t29, 30);
memset(t29, 0, 30);
vtoc_ebcdic_dec(s29, t29, 28);
printf(" ebcdic '%28s'\n", t29);
printf(" hex ");
@@ -573,7 +592,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
" ");
}
bzero(s4, 5); bzero(t4, 5); s4[0] = vlabel.ldl_version;
memset(s4, 0, 5);
memset(t4, 0, 5);
s4[0] = vlabel.ldl_version;
printf("\n\nldl_version : ascii '%1s'\n", s4);
vtoc_ebcdic_dec((char *)s4, (char *)t4, 1);
printf(" : ebcdic '%1s'\n", t4);
@@ -609,8 +630,8 @@ dasdview_print_volser(dasdview_info_t *info)
dasdview_read_vlabel(info, &vlabel);
}
bzero(vollbl, 5);
bzero(volser, 7);
memset(vollbl, 0, 5);
memset(volser, 0, 7);
strncpy(vollbl, vlabel.vollbl, 4);
vtoc_ebcdic_dec(vollbl, vollbl, 4);
@@ -631,12 +652,12 @@ dasdview_read_vtoc(dasdview_info_t *info)
volume_label_t vlabel;
format1_label_t tmp;
unsigned long maxblk, pos;
u_int64_t vtocblk;
uint64_t vtocblk;
int i;
pos = info->dasd_info.label_block * info->blksize;
bzero(&vlabel, sizeof(vlabel));
memset(&vlabel, 0, sizeof(vlabel));
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
!info->dasd_info.FBA_layout) {
/* OS/390 and zOS compatible disk layout */
@@ -648,7 +669,7 @@ dasdview_read_vtoc(dasdview_info_t *info)
exit(EXIT_FAILURE);
}
vtocblk = (u_int64_t)vtoc_get_cyl_from_cchhb(&vlabel.vtoc) *
vtocblk = (uint64_t)vtoc_get_cyl_from_cchhb(&vlabel.vtoc) *
info->geo.heads * info->geo.sectors +
vtoc_get_head_from_cchhb(&vlabel.vtoc) * info->geo.sectors +
vlabel.vtoc.b;
@@ -747,13 +768,13 @@ static void dasdview_print_format1_8_short_info(format1_label_t *f1,
char s6[7], s13[14], s44[45];
unsigned long track_low, track_up;
bzero(s44, 45);
memset(s44, 0, 45);
strncpy(s44, f1->DS1DSNAM, 44);
vtoc_ebcdic_dec(s44, s44, 44);
bzero(s6, 7);
memset(s6, 0, 7);
strncpy(s6, (char *)f1->DS1DSSN, 6);
vtoc_ebcdic_dec(s6, s6, 6);
bzero(s13, 14);
memset(s13, 0, 14);
strncpy(s13, (char *)f1->DS1SYSCD, 13);
vtoc_ebcdic_dec(s13, s13, 13);
@@ -837,13 +858,13 @@ static void dasdview_print_format1_8_short_info_raw(format1_label_t *f1,
struct dscb *dscb;
int rc;
bzero(s44, 45);
memset(s44, 0, 45);
strncpy(s44, f1->DS1DSNAM, 44);
vtoc_ebcdic_dec(s44, s44, 44);
bzero(s6, 7);
memset(s6, 0, 7);
strncpy(s6, (char *)f1->DS1DSSN, 6);
vtoc_ebcdic_dec(s6, s6, 6);
bzero(s13, 14);
memset(s13, 0, 14);
strncpy(s13, (char *)f1->DS1SYSCD, 13);
vtoc_ebcdic_dec(s13, s13, 13);
@@ -1071,7 +1092,7 @@ static void dasdview_print_vtoc_info_raw(dasdview_info_t *info)
/*
* Note: the explicit cylinder/head conversion for large volume
* adresses should not be necessary for entries that point to
* addresses should not be necessary for entries that point to
* vtoc labels, as those must be located in the first 65K-1 tracks,
* but we do it anyway to be on the safe side.
*/
@@ -1080,9 +1101,9 @@ static void dasdview_print_format1_8_no_head(format1_label_t *f1)
char s6[7], s13[14], s44[45];
int i;
bzero(s6, 7);
bzero(s13, 14);
bzero(s44, 45);
memset(s6, 0, 7);
memset(s13, 0, 14);
memset(s44, 0, 45);
strncpy(s44, f1->DS1DSNAM, 44);
printf("DS1DSNAM : ascii '%44s'\n", s44);
@@ -1865,7 +1886,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
/* seek in SEEK_STEP steps */
for (i = 1; i <= j; i++) {
rc = lseek64(fd, SEEK_STEP, SEEK_CUR);
rc = lseek(fd, SEEK_STEP, SEEK_CUR);
if (rc == -1) {
printf("*** rc: %d (%d) ***\n", rc, errno);
printf("*** j: %llu ***\n", j);
@@ -1918,7 +1939,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
count = info->begin;
for (i = 1; i <= j; i++) {
bzero(dumpstr, DUMP_STRING_SIZE);
memset(dumpstr, 0, DUMP_STRING_SIZE);
rc = read(fd, &dumpstr, DUMP_STRING_SIZE);
if (rc != DUMP_STRING_SIZE) {
close(fd);
@@ -1937,7 +1958,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
}
if (k > 0) {
bzero(dumpstr, DUMP_STRING_SIZE);
memset(dumpstr, 0, DUMP_STRING_SIZE);
rc = read(fd, &dumpstr, k);
if (rc != (int)k) {
close(fd);
@@ -1976,8 +1997,8 @@ static void dasdview_print_format_raw(unsigned int size, char *dumpstr)
while (residual) {
/* we handle at most 16 bytes per line */
count = MIN(residual, 16u);
bzero(asc, 17);
bzero(ebc, 17);
memset(asc, 0, 17);
memset(ebc, 0, 17);
printf("|");
memcpy(asc, data, count);
memcpy(ebc, data, count);
@@ -2066,7 +2087,7 @@ static void dasdview_print_raw_track(char *trackdata,
{
struct eckd_count *ecount;
char *data;
u_int32_t record;
uint32_t record;
record = 0;
data = trackdata;
@@ -2091,8 +2112,8 @@ static void dasdview_print_raw_track(char *trackdata,
static void dasdview_view_raw(dasdview_info_t *info)
{
u_int64_t residual, trckstart, trckend, track, trckbuffsize;
u_int64_t tracks_to_read, trckcount, i;
uint64_t residual, trckstart, trckend, track, trckbuffsize;
uint64_t tracks_to_read, trckcount, i;
char *trackdata;
char *data;
int rc;
@@ -2187,7 +2208,7 @@ int main(int argc, char *argv[])
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
bzero(&info, sizeof(info));
memset(&info, 0, sizeof(info));
while (1) {
oc = util_opt_getopt_long(argc, argv);

View File

@@ -11,6 +11,7 @@
#define DASDVIEW_H
#include <limits.h>
#include <stdint.h>
/********************************************************************************
* SECTION: Definitions needed for DASD-API (see dasd.h)
@@ -68,7 +69,7 @@ typedef struct dasdview_info
int dasd_info_version;
unsigned int blksize;
struct hd_geometry geo;
u_int32_t hw_cylinders;
uint32_t hw_cylinders;
unsigned long long begin;
unsigned long long size;

View File

@@ -30,7 +30,6 @@
#include "dref.h"
#include "dump.h"
#include "global.h"
#include "idcache.h"
#include "misc.h"
#include "tar.h"
@@ -656,16 +655,18 @@ static int read_symlink(struct task *task, const char *filename,
task->opts->read_chunk_size;
int rc = EXIT_OK;
/* If @relname is NULL, use @filename with AT_FDCWD. */
if (!relname) {
relname = filename;
dirfd = AT_FDCWD;
}
while (!is_aborted(task)) {
buffer_make_room(buffer, currlen, false,
task->opts->max_buffer_size);
cancel_enable();
if (relname)
actual = readlinkat(dirfd, relname, buffer->addr,
buffer->size);
else
actual = readlink(filename, buffer->addr, buffer->size);
actual = readlinkat(dirfd, relname, buffer->addr, buffer->size);
cancel_disable();
if (actual == -1) {

View File

@@ -4,3 +4,4 @@ pkey_pckmo
pkey_ep11
pkey_cca
paes_s390
phmac_s390

View File

@@ -0,0 +1,2 @@
SUBSYSTEM=="block", ACTION=="add", KERNEL=="vd*[!0-9]", TEST=="queue/rotational", ATTR{queue/rotational}="0"
SUBSYSTEM=="block", ACTION=="add", KERNEL=="vd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="none"

View File

@@ -8,6 +8,7 @@
*/
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/sysmacros.h>
@@ -211,9 +212,9 @@ static void setpos(fdasd_anchor_t *anc, int dsn, int pos)
anc->partno[dsn] = pos;
}
static u_int32_t get_usable_cylinders(fdasd_anchor_t *anc)
static uint32_t get_usable_cylinders(fdasd_anchor_t *anc)
{
u_int32_t cyl;
uint32_t cyl;
/* large volume */
if (anc->f4->DS4DEVCT.DS4DSCYL == LV_COMPAT_CYL &&
@@ -221,7 +222,7 @@ static u_int32_t get_usable_cylinders(fdasd_anchor_t *anc)
return anc->f4->DS4DCYL;
/* normal volume */
if (anc->f4->DS4DEVCT.DS4DEVFG & ALTERNATE_CYLINDERS_USED)
cyl = anc->f4->DS4DEVCT.DS4DSCYL - (u_int16_t)anc->f4->DS4DEVAC;
cyl = anc->f4->DS4DEVCT.DS4DSCYL - (uint16_t)anc->f4->DS4DEVAC;
else
cyl = anc->f4->DS4DEVCT.DS4DSCYL;
@@ -230,7 +231,7 @@ static u_int32_t get_usable_cylinders(fdasd_anchor_t *anc)
static void get_addr_of_highest_f1_f8_label(fdasd_anchor_t *anc, cchhb_t *addr)
{
u_int8_t record;
uint8_t record;
/* We have to count the following labels:
* one format 4
* one format 5
@@ -406,7 +407,7 @@ static void fdasd_error(fdasd_anchor_t *anc, enum fdasd_failure why, char *str)
*/
static int read_line(void)
{
bzero(line_buffer, LINE_LENGTH);
memset(line_buffer, 0, LINE_LENGTH);
line_ptr = line_buffer;
if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
clearerr(stdin);
@@ -493,7 +494,7 @@ static void fdasd_initialize_anchor(fdasd_anchor_t *anc)
volume_label_t *vlabel;
int i;
bzero(anc, sizeof(fdasd_anchor_t));
memset(anc, 0, sizeof(fdasd_anchor_t));
for (i = 0; i < USABLE_PARTITIONS; i++)
setpos(anc, i, -1);
@@ -519,17 +520,17 @@ static void fdasd_initialize_anchor(fdasd_anchor_t *anc)
fdasd_error(anc, malloc_failed,
"FMT9 DSCB memory allocation failed.");
bzero(anc->f4, sizeof(format4_label_t));
bzero(anc->f5, sizeof(format5_label_t));
bzero(anc->f7, sizeof(format7_label_t));
bzero(anc->f9, sizeof(format9_label_t));
memset(anc->f4, 0, sizeof(format4_label_t));
memset(anc->f5, 0, sizeof(format5_label_t));
memset(anc->f7, 0, sizeof(format7_label_t));
memset(anc->f9, 0, sizeof(format9_label_t));
vtoc_init_format9_label(anc->f9);
vlabel = malloc(sizeof(volume_label_t));
if (vlabel == NULL)
fdasd_error(anc, malloc_failed,
"Volume label memory allocation failed.");
bzero(vlabel, sizeof(volume_label_t));
memset(vlabel, 0, sizeof(volume_label_t));
anc->vlabel = vlabel;
for (i = 1; i <= USABLE_PARTITIONS; i++) {
@@ -551,7 +552,7 @@ static void fdasd_initialize_anchor(fdasd_anchor_t *anc)
if (part_info->f1 == NULL)
fdasd_error(anc, malloc_failed,
"FMT1 DSCB memory allocation failed.");
bzero(part_info->f1, sizeof(format1_label_t));
memset(part_info->f1, 0, sizeof(format1_label_t));
if (prev_part_info) {
prev_part_info->next = part_info;
@@ -975,7 +976,7 @@ static void fdasd_verify_device(fdasd_anchor_t *anc, char *name)
* Note:
* - 'version' and 'help' are priority options.
* All other parameters are ignored in that case.
* - 'silent' and 'verbose' are allways allowed in any
* - 'silent' and 'verbose' are always allowed in any
* combination.
*
*/
@@ -1052,10 +1053,10 @@ static void fdasd_show_mapping(fdasd_anchor_t *anc)
int i = 0, j = 0, dev_len;
printf("\ndevice .........: %s\n", options.device);
bzero(str, sizeof(str));
memset(str, 0, sizeof(str));
vtoc_volume_label_get_label(anc->vlabel, str);
printf("volume label ...: %.4s\n", str);
bzero(str, sizeof(str));
memset(str, 0, sizeof(str));
vtoc_volume_label_get_volser(anc->vlabel, str);
printf("volume serial ..: %s\n\n", str);
@@ -1080,7 +1081,7 @@ static void fdasd_show_mapping(fdasd_anchor_t *anc)
if (part_info->used != 0x01)
continue;
bzero(dsname, sizeof(dsname));
memset(dsname, 0, sizeof(dsname));
strncpy(dsname, part_info->f1->DS1DSNAM, 44);
vtoc_ebcdic_dec(dsname, dsname, 44);
@@ -1103,7 +1104,7 @@ static void fdasd_print_volser(fdasd_anchor_t *anc)
{
char volser[VOLSER_LENGTH + 1];
bzero(volser, VOLSER_LENGTH);
memset(volser, 0, VOLSER_LENGTH);
vtoc_ebcdic_dec(anc->vlabel->volid, volser, VOLSER_LENGTH);
printf("%6.6s\n", volser);
}
@@ -1372,7 +1373,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
}
/* write empty labels to the rest of the blocks */
bzero(&emptyf1, sizeof(emptyf1));
memset(&emptyf1, 0, sizeof(emptyf1));
while (blk < maxblk) {
vtoc_write_label(options.device, blk, &emptyf1, NULL,
NULL, NULL, NULL);
@@ -1425,7 +1426,7 @@ static void fdasd_recreate_vtoc_unconditional(fdasd_anchor_t *anc)
anc->formatted_cylinders, geo.heads);
while (part_info != NULL) {
bzero(part_info->f1, sizeof(format1_label_t));
memset(part_info->f1, 0, sizeof(format1_label_t));
if (part_info->used == 0x01) {
part_info->used = 0x00;
@@ -1826,7 +1827,7 @@ static void fdasd_process_valid_vtoc(fdasd_anchor_t *anc, unsigned long blk)
/* go through remaining labels, f4 label already done */
for (i = 1; i < geo.sectors; i++) {
bzero(&f1_label, f1_size);
memset(&f1_label, 0, f1_size);
vtoc_read_label(options.device, blk, &f1_label, NULL, NULL,
NULL);
@@ -2470,9 +2471,9 @@ static int fdasd_get_partition_data(fdasd_anchor_t *anc, extent_t *part_extent,
unsigned long start, stop, limit;
partition_info_t *part_tmp;
cchh_t llimit, ulimit;
u_int16_t hh, head;
u_int32_t cc, cyl;
u_int8_t b1, b2;
uint16_t hh, head;
uint32_t cc, cyl;
uint8_t b1, b2;
char mesg[48];
start = FIRST_USABLE_TRK;
@@ -2675,7 +2676,7 @@ static void fdasd_dequeue_old_partition(fdasd_anchor_t *anc,
part_info->start_trk = 0x0;
part_info->end_trk = 0x0;
part_info->fspace_trk = 0x0;
bzero(part_info->f1, sizeof(format1_label_t));
memset(part_info->f1, 0, sizeof(format1_label_t));
}
/*
@@ -2758,7 +2759,7 @@ static void fdasd_remove_partition(fdasd_anchor_t *anc)
if (anc->used_partitions != 0)
get_addr_of_highest_f1_f8_label(anc, &hf1);
else
bzero(&hf1, sizeof(struct cchhb));
memset(&hf1, 0, sizeof(struct cchhb));
vtoc_update_format4_label(anc->f4, &hf1, anc->f4->DS4DSREC + 1);
vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '+', anc->verbose,
@@ -2777,8 +2778,8 @@ static void fdasd_auto_partition(fdasd_anchor_t *anc)
{
partition_info_t *part_info = anc->first;
cchh_t llimit, ulimit;
u_int16_t head;
u_int32_t cyl;
uint16_t head;
uint32_t cyl;
extent_t ext;
cchhb_t hf1;

View File

@@ -10,6 +10,8 @@
#ifndef FDASD_H
#define FDASD_H
#include <stdint.h>
/*****************************************************************************
* SECTION: Definitions needed for DASD-API (see dasd.h) *
*****************************************************************************/
@@ -67,7 +69,7 @@ static struct fdasd_options options = {
};
typedef struct partition_info {
u_int8_t used;
uint8_t used;
unsigned long start_trk;
unsigned long end_trk;
unsigned long len_trk;
@@ -100,7 +102,7 @@ typedef struct fdasd_anchor {
int option_reuse;
int option_recreate;
int partno[USABLE_PARTITIONS];
u_int16_t dev_type;
uint16_t dev_type;
unsigned int used_partitions;
unsigned long label_pos;
unsigned int blksize;
@@ -113,8 +115,8 @@ typedef struct fdasd_anchor {
partition_info_t *last;
volume_label_t *vlabel;
config_data_t confdata[USABLE_PARTITIONS];
u_int32_t hw_cylinders;
u_int32_t formatted_cylinders;
uint32_t hw_cylinders;
uint32_t formatted_cylinders;
} fdasd_anchor_t;
enum offset {lower, upper};

View File

@@ -365,6 +365,13 @@ function add_hsci {
fi
fi
#### Set MTU for the veth pair
ndev_mtu="$(cat /sys/class/net/${ndev}/mtu)"
hsdev_mtu="$(cat /sys/class/net/${hsdev}/mtu)"
hsci_mtu=$(( ndev_mtu < hsdev_mtu ? ndev_mtu : hsdev_mtu ))
ip link set dev $hscibp mtu $hsci_mtu
ip link set dev $hsci mtu $hsci_mtu
#### Set veth pair to UP
ip link set dev $hscibp up >/dev/null 2>&1
if [ $? -ne 0 ]; then

View File

@@ -16,10 +16,10 @@
#define DBFS_WAIT_TIME_US 10000
extern int dg_debugfs_init(int exit_on_err);
extern int dg_debugfs_vm_init(void);
extern int dg_debugfs_lpar_init(void);
extern int dg_debugfs_open(const char *file);
int dg_debugfs_init(int exit_on_err);
int dg_debugfs_vm_init(void);
int dg_debugfs_lpar_init(void);
int dg_debugfs_open(const char *file);
/*
* z/VM diag 0C prototypes

View File

@@ -26,6 +26,7 @@
#define CPU_TYPE_LEN 16
#define DEBUGFS_FILE "diag_204"
static struct sd_sys *l_cur_lpar;
static u64 l_update_time_us;
static long l_204_buf_size;
@@ -36,7 +37,8 @@ static long l_204_buf_size;
struct l_x_info_blk_hdr {
u8 npar;
u8 flags;
u8 reserved1[6];
u8 reserved1[4];
u16 this_part;
u64 curtod1;
u64 curtod2;
u8 reserved[40];
@@ -158,6 +160,21 @@ static void *l_sd_sys_fill(struct sd_sys *lpar, struct l_x_sys_hdr *sys_hdr)
return cpu_info;
}
/*
* Calculate the time delta between samples using current partition's
* online time.
*/
static u64 l_sd_cur_lpar_delta_time_get(void)
{
struct sd_cpu *cpu;
cpu = sd_cpu_get(l_cur_lpar, "0");
if (!cpu->d_prev || !cpu->d_cur)
return 0;
return l_sub_64(cpu->d_cur->online_time_us,
cpu->d_prev->online_time_us);
}
/*
* Fill one physical CPU with data
*/
@@ -241,9 +258,9 @@ static void l_read_debugfs(struct l_debugfs_d204_hdr **hdr,
*/
static void l_sd_sys_root_fill(struct sd_sys *sys)
{
struct l_x_sys_hdr *sys_hdr, *this_part;
struct l_x_info_blk_hdr *time_hdr;
struct l_debugfs_d204_hdr *hdr;
struct l_x_sys_hdr *sys_hdr;
struct sd_sys *lpar;
char lpar_id[10];
int i;
@@ -262,18 +279,23 @@ static void l_sd_sys_root_fill(struct sd_sys *sys)
usleep(DBFS_WAIT_TIME_US);
} while (1);
sys_hdr = ((void *) time_hdr) + sizeof(struct l_x_info_blk_hdr);
this_part = ((void *)time_hdr) + time_hdr->this_part;
for (i = 0; i < time_hdr->npar; i++) {
l_sys_hdr__sys_name(sys_hdr, lpar_id);
lpar = sd_sys_get(sys, lpar_id);
if (!lpar)
lpar = sd_sys_new(sys, lpar_id);
if (sys_hdr == this_part)
l_cur_lpar = lpar;
lpar->threads_per_core = l_thread_cnt(sys_hdr);
sys_hdr = l_sd_sys_fill(lpar, sys_hdr);
sd_sys_commit(lpar);
}
if (time_hdr->flags & LPAR_PHYS_FLG)
if (time_hdr->flags & LPAR_PHYS_FLG) {
l_sd_sys_root_cpu_phys_fill(sys, (void *) sys_hdr);
sd_phys_delta_time_us_set(sys, l_sd_cur_lpar_delta_time_get());
}
ht_free(hdr);
sd_sys_commit(sys);
}
@@ -290,6 +312,16 @@ static void l_sd_update(void)
sd_sys_update_end(root, l_update_time_us);
}
/*
* Supported physical information items
*/
static struct sd_sys_item *l_phys_item_vec[] = {
&sd_sys_item_core_cnt,
&sd_sys_item_phys_mgm_diff,
&sd_sys_item_mgm,
NULL,
};
/*
* Supported system items
*/
@@ -364,6 +396,7 @@ static struct sd_cpu_type *l_cpu_type_vec[] = {
static struct sd_dg l_sd_dg = {
.update_sys = l_sd_update,
.cpu_type_vec = l_cpu_type_vec,
.phys_item_vec = l_phys_item_vec,
.sys_item_vec = l_sys_item_vec,
.sys_item_enable_vec = l_sys_item_enable_vec,
.cpu_item_vec = l_cpu_item_vec,
@@ -383,6 +416,6 @@ int dg_debugfs_lpar_init(void)
return fh;
else
close(fh);
sd_dg_register(&l_sd_dg, 1);
sd_dg_register(&l_sd_dg, 1, 1);
return 0;
}

View File

@@ -358,6 +358,6 @@ int dg_debugfs_vm_init(void)
close(fh);
l_2fc_buf_size = sizeof(struct l_debugfs_d2fc_hdr);
l_guest_name_init();
sd_dg_register(&dg_debugfs_vm_dg, 0);
sd_dg_register(&dg_debugfs_vm_dg, 0, 0);
return 0;
}

View File

@@ -15,7 +15,6 @@
#include <iconv.h>
#include <limits.h>
#include <mntent.h>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -25,6 +24,10 @@
#include <time.h>
#include <unistd.h>
#ifndef _PATH_MOUNTED
#define _PATH_MOUNTED "/etc/mtab"
#endif
#include "lib/util_fmt.h"
#include "lib/util_libc.h"

View File

@@ -18,6 +18,7 @@
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/util_time.h"
#include "lib/zt_common.h"
#define G0(x) MAX(0, (s64) (x))
@@ -25,23 +26,23 @@
/*
* Helper Prototypes
*/
extern void hyptop_helper_init(void);
extern char *ht_strstrip(char *str);
extern char *ht_strdup(const char *str);
extern void ht_print_head(const char *sys);
extern void ht_print_help_icon(void);
extern void ht_ebcdic_to_ascii(char *in, char *out, size_t len);
extern char *ht_mount_point_get(const char *fs_type);
extern u64 ht_ext_tod_2_us(void *tod_ext);
extern void ht_print_time(void);
extern s64 ht_calculate_smt_util(u64 core_us, u64 thr_us, u64 mgm_us, int thread_per_core);
void hyptop_helper_init(void);
char *ht_strstrip(char *str);
char *ht_strdup(const char *str);
void ht_print_head(const char *sys);
void ht_print_help_icon(void);
void ht_ebcdic_to_ascii(char *in, char *out, size_t len);
char *ht_mount_point_get(const char *fs_type);
u64 ht_ext_tod_2_us(void *tod_ext);
void ht_print_time(void);
s64 ht_calculate_smt_util(u64 core_us, u64 thr_us, u64 mgm_us, int thread_per_core);
/*
* Memory alloc functions
*/
extern void *ht_zalloc(size_t size);
extern void *ht_alloc(size_t size);
extern void *ht_realloc(void *ptr, size_t size);
void *ht_zalloc(size_t size);
void *ht_alloc(size_t size);
void *ht_realloc(void *ptr, size_t size);
static inline void ht_free(void *ptr)
{
free(ptr);

View File

@@ -62,11 +62,11 @@ shown.
Select sort field for current window. To reverse the sort order, specify the
option twice. See FIELDS below for definitions.
.TP
.BR "\-t <TYPE>,..." " or " "\-\-cpu_types=<TYPE>,..."
.BR "\-t <TYPE>,..." " or " "\-\-cpu-types=<TYPE>,..."
Select CPU types that are used for CPU time calculations. See CPU TYPES
below for definitions.
.TP
.BR "\-b" " or " "\-\-batch_mode"
.BR "\-b" " or " "\-\-batch-mode"
Use batch mode (no curses). This can be useful for sending output from hyptop
to another program, a file, or a line mode terminal.
In this mode no user input is accepted.
@@ -113,13 +113,20 @@ All values are enclosed in double quotation marks and separated by commas. The
first line of output contains a list of headings. Subsequent lines each
represent data for one system in one iteration.
.PP
This option implies the "\-\-batch_mode" option.
This option implies the "\-\-batch-mode" option.
.RE
.BR "\-\-all"
.RS
Use this option with the "--format" option to include fields without valid
values in the output. Fields without valid values are omitted from the output
by default. When you use the "--all" option, the invalid values are included
and shown as "null".
.RE
.TP
.BR "\-d <SECONDS>" " or " "\-\-delay=<SECONDS>"
Specifies the delay between screen updates.
.TP
.BR "\-m <FACTOR>" " or " "\-\-smt_factor=<FACTOR>"
.BR "\-m <FACTOR>" " or " "\-\-smt-factor=<FACTOR>"
Specifies a workload dependent SMT speedup factor.
For IBM z15 servers, the default value is 1.3. If the workload benefits
from SMT, you can specify a higher value. If the workload does not benefit
@@ -239,7 +246,7 @@ The following units are supported:
.SH CPU TYPES
Depending on the hypervisor different CPU types are supported. These CPU
types can be selected either interactively or with the "--cpu_types"
types can be selected either interactively or with the "--cpu-types"
command line option. The calculation of the CPU data only uses CPUs of
the specified types.

View File

@@ -112,7 +112,7 @@ static enum hyptop_win_action l_sleep(time_t time_s, long time_us)
struct timespec ts;
ts.tv_sec = time_s;
ts.tv_nsec = time_us * 1000;
ts.tv_nsec = util_usecs_to_nsecs(time_us);
nanosleep(&ts, NULL);
return WIN_KEEP;
@@ -231,6 +231,8 @@ static void l_fmt_init(void)
return;
if (g.o.format == FMT_CSV)
flags |= FMT_QUOTEALL;
if (g.o.format == FMT_CSV || g.o.format_all)
flags |= FMT_KEEPINVAL;
if (g.o.format == FMT_JSON || g.o.format == FMT_JSONSEQ)
flags |= FMT_HANDLEINT;
util_fmt_init(stdout, g.o.format, flags, 1);

View File

@@ -55,6 +55,7 @@ struct hyptop_opts {
unsigned int win_specified;
unsigned int batch_mode_specified;
unsigned int format_specified;
unsigned int format_all;
enum util_fmt_t format;
unsigned int iterations_specified;
unsigned int iterations;
@@ -183,10 +184,10 @@ enum hyptop_win_action {
WIN_KEEP,
};
extern enum hyptop_win_action hyptop_process_input_timeout(void);
extern enum hyptop_win_action hyptop_process_input(void);
extern enum hyptop_win_action win_switch(struct hyptop_win *w);
extern enum hyptop_win_action win_back(void);
enum hyptop_win_action hyptop_process_input_timeout(void);
enum hyptop_win_action hyptop_process_input(void);
enum hyptop_win_action win_switch(struct hyptop_win *w);
enum hyptop_win_action win_back(void);
struct hyptop_win;
struct hyptop_win {
@@ -205,25 +206,25 @@ struct hyptop_win {
* Window sys_list
*/
extern struct hyptop_win win_sys_list;
extern void win_sys_list_init(void);
void win_sys_list_init(void);
/*
* Window sys
*/
extern struct hyptop_win win_sys;
extern void win_sys_set(const char *sys_id);
extern void win_sys_init(void);
void win_sys_set(const char *sys_id);
void win_sys_init(void);
/*
* Window cpu_types
*/
extern void win_cpu_types_init(void);
void win_cpu_types_init(void);
/*
* Misc functions
*/
extern void hyptop_update_term(void);
extern void __noreturn hyptop_exit(int rc);
extern void hyptop_text_mode(void);
void hyptop_update_term(void);
void __noreturn hyptop_exit(int rc);
void hyptop_text_mode(void);
#endif /* HYPTOP_H */

View File

@@ -39,17 +39,28 @@ static char HELP_TEXT[] =
"-s, --sys SYSTEM[,..] Systems for current window\n"
"-f, --fields LETTER[:UNIT][,..] Fields and units for current window\n"
"-S, --sort LETTER Sort field for current window\n"
"-t, --cpu_types TYPE[,..] CPU types used for time calculations\n"
"-b, --batch_mode Use batch mode (no curses)\n"
"-t, --cpu-types TYPE[,..] CPU types used for time calculations\n"
"-b, --batch-mode Use batch mode (no curses)\n"
" --format FORMAT Output format (" FMT_TYPE_NAMES "), implies -b\n"
" --all Include omitted fields (with values of null)\n"
" in the output of --format.\n"
"-d, --delay SECONDS Delay time between screen updates\n"
"-m, --smt_factor FACTOR Machine generation dependent SMT speedup factor.\n"
"-m, --smt-factor FACTOR Machine generation dependent SMT speedup factor.\n"
"-n, --iterations NUMBER Number of iterations before ending\n";
/*
* Options with long-name only
*/
#define OPT_FORMAT 256 /* --format */
#define OPT_FORMAT_ALL 261 /* --all*/
/*
* Options with underscore to keep compatibility
*/
#define OPT_BATCH_MODE 257 /* --batch_mode */
#define OPT_SORT_FIELD 258 /* --sort | --sort_field */
#define OPT_CPU_TYPES 259 /* --cpu_types */
#define OPT_SMT_FACTOR 260 /* --smt_factor */
/*
* Initialize default settings
@@ -313,6 +324,15 @@ static void l_format_set(const char *str)
g.o.format = fmt;
}
/*
* Set the "--all" option to display omitted null values
* while using "--format"
*/
static void l_format_all_set(void)
{
g.o.format_all = 1;
}
/*
* Make option consisteny checks at end of command line parsing
*/
@@ -320,6 +340,8 @@ static void l_parse_finish(void)
{
if (g.o.iterations_specified && g.o.iterations == 0)
hyptop_exit(0);
if (!g.o.format_specified && g.o.format_all)
ERR_EXIT("The --all option requires the -format option\n");
if (g.o.cur_win != &win_sys)
return;
if (!win_sys.opts.sys.specified)
@@ -339,15 +361,20 @@ void opts_parse(int argc, char *argv[])
static struct option long_options[] = {
{ "version", no_argument, NULL, 'v'},
{ "help", no_argument, NULL, 'h'},
{ "batch_mode", no_argument, NULL, 'b'},
{ "batch-mode", no_argument, NULL, 'b'},
{ "batch_mode", no_argument, NULL, OPT_BATCH_MODE},
{ "all", no_argument, NULL, OPT_FORMAT_ALL },
{ "delay", required_argument, NULL, 'd'},
{ "smt_factor", required_argument, NULL, 'm'},
{ "smt-factor", required_argument, NULL, 'm'},
{ "smt_factor", required_argument, NULL, OPT_SMT_FACTOR},
{ "window", required_argument, NULL, 'w'},
{ "sys", required_argument, NULL, 's'},
{ "iterations", required_argument, NULL, 'n'},
{ "fields", required_argument, NULL, 'f'},
{ "sort_field", required_argument, NULL, 'S'},
{ "cpu_types", required_argument, NULL, 't'},
{ "sort-field", required_argument, NULL, 'S'},
{ "sort_field", required_argument, NULL, OPT_SORT_FIELD},
{ "cpu-types", required_argument, NULL, 't'},
{ "cpu_types", required_argument, NULL, OPT_CPU_TYPES},
{ "format", required_argument, NULL, OPT_FORMAT },
{ NULL, 0, NULL, 0 }
};
@@ -366,12 +393,14 @@ void opts_parse(int argc, char *argv[])
case 'h':
l_usage();
hyptop_exit(0);
case OPT_BATCH_MODE:
case 'b':
l_batch_mode_set();
break;
case 'd':
l_delay_set(optarg);
break;
case OPT_SMT_FACTOR:
case 'm':
l_factor_set(optarg);
break;
@@ -384,18 +413,23 @@ void opts_parse(int argc, char *argv[])
case 'n':
l_iterations_set(optarg);
break;
case OPT_CPU_TYPES:
case 't':
l_cpu_types_set(optarg);
break;
case 'f':
l_fields_set(optarg);
break;
case OPT_SORT_FIELD:
case 'S':
l_sort_field_set(optarg);
break;
case OPT_FORMAT:
l_format_set(optarg);
break;
case OPT_FORMAT_ALL:
l_format_all_set();
break;
default:
l_std_usage_exit();
}

View File

@@ -14,9 +14,9 @@
#include "hyptop.h"
extern void opts_parse(int argc, char *argv[]);
extern void opts_iterations_next(void);
extern int opts_sys_specified(struct hyptop_win *win, const char* sys_name);
extern void opt_verify_systems(void);
void opts_parse(int argc, char *argv[]);
void opts_iterations_next(void);
int opts_sys_specified(struct hyptop_win *win, const char *sys_name);
void opt_verify_systems(void);
#endif /* OPTS_H */

View File

@@ -19,6 +19,7 @@
#define SD_DG_INIT_INTERVAL_SEC 1
#define SD_SYS_ID_SIZE 9
#define SD_SYS_DEFAULT_ID "PHYSICAL"
/*
* CPU info
@@ -77,6 +78,7 @@ struct sd_sys {
struct util_list_node list;
struct sd_info i;
u64 update_time_us;
u64 phys_delta_us;
u32 child_cnt;
u32 child_cnt_active;
struct util_list child_list;
@@ -134,6 +136,11 @@ static inline void sd_sys_update_time_us_set(struct sd_sys *sys, u64 value)
sys->update_time_us = value;
}
static inline void sd_phys_delta_time_us_set(struct sd_sys *sys, u64 value)
{
sys->phys_delta_us = value;
}
/*
* CPU type
*/
@@ -301,8 +308,8 @@ struct sd_cpu_item {
#define sd_cpu_item_type(x) ((x)->type)
#define sd_cpu_item_table_col(item) (&(item)->table_col)
extern int sd_cpu_item_available(struct sd_cpu_item *item);
extern int sd_cpu_item_cnt(void);
int sd_cpu_item_available(struct sd_cpu_item *item);
int sd_cpu_item_cnt(void);
/*
* Item access functions
@@ -370,8 +377,8 @@ struct sd_sys_item {
#define sd_sys_item_table_col(item) (&item->table_col)
#define sd_sys_item_type(item) (item->type)
extern int sd_sys_item_available(struct sd_sys_item *item);
extern int sd_sys_item_cnt(void);
int sd_sys_item_available(struct sd_sys_item *item);
int sd_sys_item_cnt(void);
/*
* Item access functions
@@ -437,19 +444,23 @@ extern struct sd_sys_item sd_sys_item_os_name;
extern struct sd_sys_item sd_sys_item_samples_total;
extern struct sd_sys_item sd_sys_item_samples_cpu_using;
extern struct sd_sys_item sd_sys_item_phys_mgm_diff;
/*
* Data gatherer backend
*/
struct sd_dg {
void (*update_sys)(void);
struct sd_cpu_type **cpu_type_vec;
struct sd_sys_item **phys_item_vec;
struct sd_sys_item **sys_item_vec;
struct sd_sys_item **sys_item_enable_vec;
struct sd_cpu_item **cpu_item_vec;
struct sd_cpu_item **cpu_item_enable_vec;
};
void sd_dg_register(struct sd_dg *, int);
void sd_dg_register(struct sd_dg *, int, int);
int sd_dg_has_phys_data(void);
int sd_dg_has_core_data(void);
/*
@@ -461,6 +472,9 @@ int sd_dg_has_core_data(void);
#define sd_cpu_iterate(parent, cpu) \
util_list_iterate(&parent->cpu_list, cpu)
#define sd_phys_item_iterate(ptr, i) \
for (i = 0; (ptr = sd.dg->phys_item_vec[i]); i++)
#define sd_sys_item_iterate(ptr, i) \
for (i = 0; (ptr = sd.dg->sys_item_vec[i]); i++)
@@ -506,7 +520,7 @@ static inline s64 l_cpu_info_s64(struct sd_cpu_info *info,
* Misc
*/
void sd_update(void);
extern void sd_init(void);
void sd_init(void);
static inline u64 l_sub_64(u64 x, u64 y)
{

View File

@@ -26,6 +26,7 @@ static int l_cpu_type_cnt;
static int l_sys_item_cnt;
static int l_cpu_item_cnt;
static int l_has_core_data;
static int l_has_phys_data;
static struct sd_sys *l_root_sys;
/*
@@ -148,7 +149,7 @@ void sd_update(void)
/*
* Register a data gatherer
*/
void sd_dg_register(struct sd_dg *dg, int has_core_data)
void sd_dg_register(struct sd_dg *dg, int has_core_data, int has_phys_data)
{
struct timespec ts = {SD_DG_INIT_INTERVAL_SEC, 0};
struct sd_sys_item *sys_item;
@@ -156,6 +157,7 @@ void sd_dg_register(struct sd_dg *dg, int has_core_data)
unsigned int i;
l_has_core_data = has_core_data;
l_has_phys_data = has_phys_data;
sd.dg = dg;
for (i = 0; dg->cpu_type_vec[i]; i++)
dg->cpu_type_vec[i]->idx = (1UL << i);
@@ -172,6 +174,14 @@ void sd_dg_register(struct sd_dg *dg, int has_core_data)
l_cpu_types_init();
}
/*
* Does backend has physical CPUs data?
*/
int sd_dg_has_phys_data(void)
{
return l_has_phys_data;
}
/*
* Does backend has core data?
*/
@@ -419,7 +429,7 @@ int sd_cpu_item_cnt(void)
*/
void sd_init(void)
{
l_root_sys = sd_sys_new(NULL, "root");
l_root_sys = sd_sys_new(NULL, SD_SYS_DEFAULT_ID);
}
/*

View File

@@ -48,7 +48,7 @@ static double l_cpu_diff(struct sd_cpu_item *item, struct sd_cpu *cpu, int sign)
if (online_time_diff_us == 0)
return 0;
factor = ((double) online_time_diff_us) / 1000000 * cpu->cnt;
factor = util_usecs_to_secs(online_time_diff_us) * cpu->cnt;
if (sign)
diff_us = l_cpu_info_s64(cpu->d_cur, item->offset) -
l_cpu_info_s64(cpu->d_prev, item->offset);

View File

@@ -171,7 +171,7 @@ static double l_cpu_info_diff_u64(struct sd_sys_item *item, struct sd_cpu *cpu,
diff_us = l_sub_64(l_cpu_info_u64(cpu->d_cur, item->offset),
l_cpu_info_u64(cpu->d_prev, item->offset));
}
factor = ((double) online_time_diff_us) / 1000000;
factor = util_usecs_to_secs(online_time_diff_us);
diff_us /= factor;
return diff_us;
}
@@ -220,9 +220,56 @@ static u64 l_sys_smt_util(struct sd_sys_item *item, struct sd_sys *sys)
return ht_calculate_smt_util(core_us, thr_us, mgm_us, sys->threads_per_core);
}
/*
* value = (value_current - value_prev) / online_time_diff
*/
static double l_phys_cpu_info_diff_u64(struct sd_sys_item *item,
struct sd_cpu *cpu,
u64 time_diff_us)
{
double factor, diff_us;
if (!sd_cpu_type_selected(cpu->type))
return 0;
if (sd_cpu_state(cpu) == SD_CPU_STATE_STOPPED)
return 0;
if (time_diff_us == 0)
return 0;
diff_us = l_sub_64(l_cpu_info_u64(cpu->d_cur, item->offset),
l_cpu_info_u64(cpu->d_prev, item->offset));
factor = util_usecs_to_secs(time_diff_us);
diff_us /= factor;
return diff_us;
}
/*
* SUM over all CPUs: value = (value_current - value_prev) / online_time_diff
*/
static u64 l_sys_phys_cpu_info_diff_u64(struct sd_sys_item *item, struct sd_sys *sys)
{
struct sd_cpu *cpu;
u64 rc = 0;
sd_cpu_iterate(sys, cpu) {
if (!cpu->d_prev || !cpu->d_cur)
return 0;
rc += l_phys_cpu_info_diff_u64(item, cpu, sys->phys_delta_us);
}
return rc;
}
/*
* System item definitions
*/
struct sd_sys_item sd_sys_item_phys_mgm_diff = {
.table_col = TABLE_COL_TIME_DIFF_SUM(table_col_unit_perc, 'm', "mgm"),
.offset = SD_CPU_INFO_OFFSET(mgm_time_us),
.type = SD_TYPE_U64,
.desc = "Management time per second",
.fn_set = l_sys_cpu_info_set,
.fn_u64 = l_sys_phys_cpu_info_diff_u64,
};
struct sd_sys_item sd_sys_item_core_cnt = {
.table_col = TABLE_COL_CNT_SUM('#', "#core"),
.type = SD_TYPE_U32,

View File

@@ -260,6 +260,10 @@ void table_row_del_all(struct table *t)
util_list_remove(&t->row_list, row);
table_row_free(row);
}
if (t->row_physical) {
table_row_free(t->row_physical);
t->row_physical = NULL;
}
l_row_last_init(t);
t->row_cnt_marked = 0;
t->ready = 0;
@@ -418,6 +422,8 @@ static void l_row_last_calc(struct table *t)
*/
void table_finish(struct table *t)
{
if (t->row_physical)
l_row_format(t, t->row_physical);
l_row_last_calc(t);
t->ready = 1;
}
@@ -463,6 +469,8 @@ void table_rebuild(struct table *t)
l_col_max_width_init(t, col);
util_list_iterate(&t->row_list, row)
l_row_format(t, row);
if (t->row_physical)
l_row_format(t, t->row_physical);
l_row_format(t, t->row_last);
}
@@ -921,6 +929,10 @@ static void l_table_print_curses(struct table *t)
}
ht_reverse_on();
l_row_print(t, t->row_last);
if (t->row_physical) {
hyptop_print_nl();
l_row_print(t, t->row_physical);
}
hyptop_print_seek_back(0);
ht_reverse_off();
#ifdef WITH_SCROLL_BAR
@@ -952,6 +964,10 @@ static void l_table_print_all(struct table *t)
}
l_row_print(t, t->row_last);
hyptop_print_nl();
if (t->row_physical) {
l_row_print(t, t->row_physical);
hyptop_print_nl();
}
hyptop_printf("------------------------------------------------------"
"-------------------------\n");
}
@@ -972,10 +988,15 @@ static void l_row_print_formatted(struct table *t, struct table_row *row)
unsigned int flags = 0;
struct table_entry *e = &row->entries[col_nr];
if (row == t->row_last && col_nr == 0)
if (row == t->row_last && col_nr == 0) {
if (g.o.format == FMT_CSV)
util_fmt_pair(FMT_QUOTE, col->head, "SUM", e->str);
continue;
}
if (table_col_needs_quotes(col))
flags = FMT_QUOTE;
if (strcmp(e->str, "-") == 0 || strcmp(e->str, "") == 0)
flags |= FMT_INVAL;
util_fmt_pair(flags, col->head, "%s", e->str);
}
}
@@ -991,6 +1012,11 @@ static void l_table_print_all_formatted(struct table *t)
util_fmt_pair(FMT_PERSIST, "iteration", "%u", g.o.iterations_act);
ht_fmt_time();
ht_fmt_cpu_types();
if (t->row_physical) {
util_fmt_obj_start(FMT_ROW, "physical_information");
l_row_print_formatted(t, t->row_physical);
util_fmt_obj_end(); /* physical_information{} */
}
if (strcmp(g.o.cur_win->id, "sys_list") == 0)
util_fmt_obj_start(FMT_LIST, "systems");
else

View File

@@ -324,6 +324,7 @@ struct table {
struct table_col **col_vec;
struct table_col *col_selected;
struct table_row *row_last;
struct table_row *row_physical;
int row_cnt;
int row_cnt_marked;
int row_cnt_extra;
@@ -361,37 +362,37 @@ enum table_scroll_unit {
*/
extern struct table *table_new(int extra_rows, int sorted, int first_bold,
int with_units);
extern void table_reset(struct table *t);
extern void table_rebuild(struct table *t);
extern void table_finish(struct table *t);
extern void table_print(struct table *t);
extern void table_process_input(struct table *t, int c);
void table_reset(struct table *t);
void table_rebuild(struct table *t);
void table_finish(struct table *t);
void table_print(struct table *t);
void table_process_input(struct table *t, int c);
extern void table_col_unit_next(struct table *t, char hotkey);
extern void table_col_unit_prev(struct table *t, char hotkey);
extern int table_col_unit_set(struct table *t, char hotkey, const char *unit);
extern void table_col_add(struct table *t, struct table_col *col);
extern int table_col_select(struct table *t, char hotkey);
extern void table_col_select_next(struct table *t);
extern void table_col_select_prev(struct table *t);
extern void table_col_enable_toggle(struct table *t, char hotkey);
void table_col_unit_next(struct table *t, char hotkey);
void table_col_unit_prev(struct table *t, char hotkey);
int table_col_unit_set(struct table *t, char hotkey, const char *unit);
void table_col_add(struct table *t, struct table_col *col);
int table_col_select(struct table *t, char hotkey);
void table_col_select_next(struct table *t);
void table_col_select_prev(struct table *t);
void table_col_enable_toggle(struct table *t, char hotkey);
extern void table_row_del_all(struct table *t);
extern void table_row_add(struct table *t, struct table_row *row);
extern void table_row_mark(struct table *t, struct table_row *row);
extern void table_row_mark_del_all(struct table *t);
extern void table_row_mark_toggle(struct table *t, struct table_row *row);
extern void table_row_mark_toggle_by_key(struct table *t, const char *mark_key);
extern void table_row_select_down(struct table *t, enum table_scroll_unit unit);
extern void table_row_select_up(struct table *t, enum table_scroll_unit unit);
extern void table_row_select_key_get(struct table *t, char str[TABLE_STR_MAX]);
extern struct table_row *table_row_alloc(struct table *t);
void table_row_del_all(struct table *t);
void table_row_add(struct table *t, struct table_row *row);
void table_row_mark(struct table *t, struct table_row *row);
void table_row_mark_del_all(struct table *t);
void table_row_mark_toggle(struct table *t, struct table_row *row);
void table_row_mark_toggle_by_key(struct table *t, const char *mark_key);
void table_row_select_down(struct table *t, enum table_scroll_unit unit);
void table_row_select_up(struct table *t, enum table_scroll_unit unit);
void table_row_select_key_get(struct table *t, char str[TABLE_STR_MAX]);
struct table_row *table_row_alloc(struct table *t);
extern void table_scroll_down(struct table *t, enum table_scroll_unit unit);
extern void table_scroll_up(struct table *t, enum table_scroll_unit unit);
void table_scroll_down(struct table *t, enum table_scroll_unit unit);
void table_scroll_up(struct table *t, enum table_scroll_unit unit);
extern void table_fmt_start(void);
extern void table_fmt_end(void);
void table_fmt_start(void);
void table_fmt_end(void);
/*
* Entry add functions

View File

@@ -153,7 +153,7 @@ struct table_col_unit table_col_unit_us = {
*/
static int l_unit_ms(struct table_col *col, struct table_entry *e)
{
return l_unit_raw_div(col, e, 1000, L_COL_FMT_STR_2);
return l_unit_raw_div(col, e, USEC_PER_MSEC, L_COL_FMT_STR_2);
}
struct table_col_unit table_col_unit_ms = {
@@ -167,7 +167,7 @@ struct table_col_unit table_col_unit_ms = {
*/
static int l_unit_perc(struct table_col *col, struct table_entry *e)
{
return l_unit_raw_div(col, e, 10000, L_COL_FMT_STR_2);
return l_unit_raw_div(col, e, (USEC_PER_SEC / 100), L_COL_FMT_STR_2);
}
struct table_col_unit table_col_unit_perc = {
@@ -182,7 +182,7 @@ struct table_col_unit table_col_unit_perc = {
*/
static int l_unit_s(struct table_col *col, struct table_entry *e)
{
return l_unit_raw_div(col, e, 1000000, L_COL_FMT_STR_2);
return l_unit_raw_div(col, e, USEC_PER_SEC, L_COL_FMT_STR_2);
}
struct table_col_unit table_col_unit_s = {
@@ -197,7 +197,7 @@ struct table_col_unit table_col_unit_s = {
*/
static int l_unit_m(struct table_col *col, struct table_entry *e)
{
return l_unit_raw_div(col, e, 1000000 * 60, L_COL_FMT_STR_0);
return l_unit_raw_div(col, e, USEC_PER_SEC * 60, L_COL_FMT_STR_0);
}
static struct table_col_unit table_col_unit_m = {
@@ -214,7 +214,7 @@ static int l_unit_hm_u64(char *str, u64 v1, int negative)
{
u64 time_tmp, time_h, time_m;
time_tmp = v1 / (1000000 * 60);
time_tmp = v1 / (USEC_PER_SEC * 60);
time_h = time_tmp / 60;
time_m = time_tmp - time_h * 60;
@@ -259,7 +259,7 @@ static int l_unit_dhm_u64(char *str, u64 v1, int negative)
{
u64 time_tmp, time_d, time_h, time_m;
time_tmp = v1 / (1000000 * 60);
time_tmp = v1 / (USEC_PER_SEC * 60);
time_d = time_tmp / (60 * 24);
time_h = time_tmp / 60 - time_d * 24;
time_m = time_tmp - time_h * 60 - time_d * 60 * 24;
@@ -312,10 +312,8 @@ static int l_unit_vis(struct table_col *col, struct table_entry *e)
assert(col->type == TABLE_COL_TYPE_U64);
sprintf(e->str, "|");
val1_perc = e->d.u64.v1;
val1_perc /= 1000000;
val2_perc = e->d.u64.v2;
val2_perc /= 1000000;
val1_perc = util_usecs_to_secs(e->d.u64.v1);
val2_perc = util_usecs_to_secs(e->d.u64.v2);
val1_nr = (val1_perc * L_VISUAL_ROW_CNT) + 0.5;
val2_nr = (val2_perc * L_VISUAL_ROW_CNT) + 0.5;

View File

@@ -23,6 +23,6 @@ struct win_cpu_types {
struct hyptop_win *win_help;
};
extern struct hyptop_win *win_cpu_types_new(void);
struct hyptop_win *win_cpu_types_new(void);
#endif /* WIN_CPU_TYPES_H */

View File

@@ -162,6 +162,22 @@ static void l_sys_item_add(struct table_row *table_row, struct sd_sys *sys,
}
}
static void l_row_add_physical(struct table *t, struct sd_sys *sys)
{
struct sd_sys_item *item;
struct table_row *row;
unsigned int i;
row = table_row_alloc(t);
table_row_entry_str_add(row, &l_col_sys, sd_sys_id(sys));
sd_phys_item_iterate(item, i) {
if (!sd_sys_item_set(sys, item))
continue;
l_sys_item_add(row, sys, item);
}
t->row_physical = row;
}
/*
* Add system to table
*/
@@ -196,6 +212,8 @@ static void l_table_create(void)
continue;
l_sys_add(guest);
}
if (sd_dg_has_phys_data())
l_row_add_physical(l_t, parent);
table_finish(l_t);
}
@@ -324,6 +342,11 @@ static void l_run(struct hyptop_win *win)
}
}
static void win_sys_list_set_phys_table_cols(void)
{
sd_sys_item_phys_mgm_diff.table_col = sd_sys_item_mgm_diff.table_col;
}
/*
* Initialize window
*/
@@ -337,7 +360,7 @@ void win_sys_list_init(void)
int item_cnt;
/* Alloc table and add columns */
l_t = table_new(1, 1, 1, 1);
l_t = table_new(2, 1, 1, 1);
table_col_add(l_t, &l_col_sys);
item_cnt = sd_sys_item_cnt() + 1;
@@ -351,6 +374,8 @@ void win_sys_list_init(void)
col_vec[i] = col;
col_desc_vec[i] = item->desc;
}
if (sd_dg_has_phys_data())
win_sys_list_set_phys_table_cols();
/* Enable fields */
if (win_sys_list.opts.fields.specified)
l_fields_enable_cmdline();

View File

@@ -29,6 +29,7 @@
#define UNPACK_FACILITY _AC(161, U)
#ifndef __ASSEMBLER__
#include <asm/types.h>
#include <stdint.h>
/*
@@ -380,18 +381,6 @@ static __always_inline int is_zvm(void)
return cpuid.version == 0xff;
}
/* To avoid conflicts add a macro guard since __vector128 is also
* defined in 'linux/asm/types.h'.
*/
#ifndef _S390_TYPES_H
/*
* Vector register definition
*/
typedef struct {
uint32_t u[4];
} __vector128;
#endif
/*
* Save vector registers
*/

View File

@@ -379,6 +379,25 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
const char *cert_pem_filename,
const struct ekmf_ext_lib *ext_lib, bool verbose);
/**
* Validates that a certificate has the same public key as the secure identity
* key (field identity_secure_key in config structure) .
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param x509_cert the X509 certificate object to validate
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success.
* -EINVAL: invalid parameter, or certificate is not valid
* -ENOMEM: Failed to allocate memory
* any other errno from file I/O routines
*/
int ekmf_validate_cert(const struct ekmf_config *config, const X509 *x509_cert,
const struct ekmf_ext_lib *ext_lib, bool verbose);
/**
* Retrieves settings from the EKMFWeb server, such as the template names for
* generating keys in EKMFWeb.

View File

@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: MIT */
/*
* autocomp - command line autocompletion
*
* Generating autocompletion scripts for bash and zsh
* based on util_opt struct
*
* Copyright IBM Corp. 2025
*
* 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 LIB_UTIL_AUTOCOMP_H
#define LIB_UTIL_AUTOCOMP_H
#include "lib/util_opt.h"
void generate_autocomp(struct util_opt *opt_vec, char *tool_name);
#endif

View File

@@ -12,6 +12,7 @@
#ifndef LIB_UTIL_LIBC_H
#define LIB_UTIL_LIBC_H
#include <fcntl.h>
#include <stdio.h>
#ifdef __cplusplus
@@ -45,7 +46,7 @@ void *__util_zalloc(const char *func, const char *file, int line, size_t size);
/**
* Re-allocate memory or exit in case of failure
*
* @param[in] ptr Pointer ot old memory buffer
* @param[in] ptr Pointer to old memory buffer
* @param[in] size Number of bytes to be allocated
*
* @returns Pointer to memory buffer created with realloc()
@@ -124,6 +125,29 @@ do { \
va_end(ap); \
} while (0)
/**
* Reads the target of a symbolic link at the given path.
*
* @param[in] path Path to the symbolic link
* @return Newly allocated string with the link target, or NULL on error
*/
#define util_readlink(path) __util_readlinkat(__func__, __FILE__, __LINE__, AT_FDCWD, path)
/**
* Reads the target of a symbolic link relative to a directory file descriptor.
*
* Semantics:
* - If path is absolute, dirfd is ignored, per readlinkat semantics.
* - If path is relative, it is resolved relative to dirfd.
*
* @param[in] dirfd Directory file descriptor or AT_FDCWD
* @param[in] path Path to the symbolic link
* @return Newly allocated string with the link target, or NULL on error
*/
#define util_readlinkat(dirfd, path) __util_readlinkat(__func__, __FILE__, __LINE__, dirfd, path)
char *__util_readlinkat(const char *func, const char *file, int line, int dirfd, const char *path);
int __util_vsprintf(const char *func, const char *file, int line,
char *str, const char *fmt, va_list ap);
char *util_strcat_realloc(char *str1, const char *str2);

58
include/lib/util_parse.h Normal file
View File

@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: MIT */
/*
* util - Utility function library
*
* String parsing utility functions
*
* Copyright IBM Corp. 2026
*/
#ifndef LIB_UTIL_PARSE_H
#define LIB_UTIL_PARSE_H
#include <stdbool.h>
#include <stddef.h>
struct util_range {
size_t start;
size_t end;
};
/*
* Parse a boolean input string into a boolean value
* Accepts: "0"/"1", "n"/"y", "no"/"yes", "f"/"t", "false"/"true", "off"/"on"
* Case-insensitive
* @param input: Input string to parse
* @return: 1 for true, 0 for false, -EINVAL for invalid input
*/
int util_parse_bool(const char *input);
/*
* Parse byte sizes with optional unit suffixes
* Supports: K/KiB, M/MiB, G/GiB, T/TiB, P/PiB, E/EiB
* K/M/G/T/P/E use 1000-based multipliers
* KiB/MiB/GiB/TiB/PiB/EiB use 1024-based multipliers
* @param input: Input string to parse
* @param bytes: Pointer to store parsed byte size
* @return: 0 on success, negative error code on failure
*/
int util_parse_byte_size(const char *input, size_t *bytes);
/*
* Parse numeric ranges in the format "start-end"
* @param input: Input string to parse (format: "start-end")
* @param range: Pointer to util_range struct to store result
* @return: 0 on success, negative error code on failure
*/
int util_parse_range(const char *input, struct util_range *range);
/*
* Parse integers with support for different bases
* Supports: decimal, hex (0x prefix), binary (0b prefix), octal (0o prefix)
* @param input: Input string to parse
* @param value: Pointer to store parsed integer value
* @return: 0 on success, negative error code on failure
*/
int util_parse_int(const char *input, size_t *value);
#endif

View File

@@ -13,5 +13,7 @@
#define LIB_UTIL_STR_H
void util_str_rm_whitespace(const char *src, char *dest);
const char *util_startswith(const char *s, const char *prefix);
const char *util_startswith_no_case(const char *s, const char *prefix);
#endif /** LIB_UTIL_STR_H @} */

View File

@@ -13,6 +13,7 @@
#define LIB_UTIL_SYS_H
#include <stdbool.h>
#include <sys/types.h>
int util_sys_get_dev_addr(const char *dev, char *addr);
bool util_sys_dev_is_partition(dev_t dev);

202
include/lib/util_time.h Normal file
View File

@@ -0,0 +1,202 @@
/*
* util_time - Time related helper functions and definitions
*
* Copyright IBM Corp. 2025
*
* 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 LIB_UTIL_TIME_H
#define LIB_UTIL_TIME_H
#define NSEC_PER_USEC 1000L
#define NSEC_PER_MSEC 1000000L
#define NSEC_PER_SEC 1000000000L
#define USEC_PER_MSEC 1000L
#define USEC_PER_SEC 1000000L
#define MSEC_PER_SEC 1000L
/**
* Convert nanoseconds to microseconds
*
* Convert value from nanoseconds to microseconds by dividing the
* value to NSEC_PER_USEC constant.
*
* @param[in] val Time value in nanoseconds
*
* @returns Time value in microseconds
*/
static inline double util_nsecs_to_usecs(double val)
{
return val / NSEC_PER_USEC;
}
/**
* Convert nanoseconds to milliseconds
*
* Convert value from nanoseconds to milliseconds by dividing the
* value to NSEC_PER_MSEC constant.
*
* @param[in] val Time value in nanoseconds
*
* @returns Time value in milliseconds
*/
static inline double util_nsecs_to_msecs(double val)
{
return val / NSEC_PER_MSEC;
}
/**
* Convert nanoseconds to seconds
*
* Convert value from nanoseconds to seconds by dividing the
* value to NSEC_PER_SEC constant.
*
* @param[in] val Time value in nanoseconds
*
* @returns Time value in seconds
*/
static inline double util_nsecs_to_secs(double val)
{
return val / NSEC_PER_SEC;
}
/**
* Convert microseconds to nanoseconds
*
* Convert value from microseconds to nanoseconds by multiplying the
* value with NSEC_PER_USEC constant.
*
* @param[in] val Time value in microseconds
*
* @returns Time value in nanoseconds
*/
static inline double util_usecs_to_nsecs(double val)
{
return val * NSEC_PER_USEC;
}
/**
* Convert microseconds to milliseconds
*
* Convert value from microseconds to milliseconds by dividing the
* value to USEC_PER_MSEC constant.
*
* @param[in] val Time value in microseconds
*
* @returns Time value in milliseconds
*/
static inline double util_usecs_to_msecs(double val)
{
return val / USEC_PER_MSEC;
}
/**
* Convert microseconds to seconds
*
* Convert value from microseconds to seconds by dividing the
* value to USEC_PER_SEC constant.
*
* @param[in] val Time value in nanoseconds
*
* @returns Time value in seconds
*/
static inline double util_usecs_to_secs(double val)
{
return val / USEC_PER_SEC;
}
/**
* Convert milliseconds to nanoseconds
*
* Convert value from milliseconds to nanoseconds by multiplying the
* value with NSEC_PER_MSEC constant.
*
* @param[in] val Time value in milliseconds
*
* @returns Time value in nanoseconds
*/
static inline double util_msecs_to_nsecs(double val)
{
return val * NSEC_PER_MSEC;
}
/**
* Convert milliseconds to microseconds
*
* Convert value from milliseconds to microseconds by multiplying the
* value with USEC_PER_MSEC constant.
*
* @param[in] val Time value in milliseconds
*
* @returns Time value in microseconds
*/
static inline double util_msecs_to_usecs(double val)
{
return val * USEC_PER_MSEC;
}
/**
* Convert milliseconds to seconds
*
* Convert value from milliseconds to seconds by dividing the
* value to MSEC_PER_SEC constant.
*
* @param[in] val Time value in milliseconds
*
* @returns Time value in seconds
*/
static inline double util_msecs_to_secs(double val)
{
return val / MSEC_PER_SEC;
}
/**
* Convert seconds to nanoseconds
*
* Convert value from seconds to nanoseconds by multiplying the
* value with NSEC_PER_SEC constant.
*
* @param[in] val Time value in seconds
*
* @returns Time value in nanoseconds
*/
static inline double util_secs_to_nsecs(double val)
{
return val * NSEC_PER_SEC;
}
/**
* Convert seconds to microseconds
*
* Convert value from seconds to microseconds by multiplying the
* value with USEC_PER_SEC constant.
*
* @param[in] val Time value in seconds
*
* @returns Time value in microseconds
*/
static inline double util_secs_to_usecs(double val)
{
return val * USEC_PER_SEC;
}
/**
* Convert seconds to milliseconds
*
* Convert value from seconds to milliseconds by multiplying the
* value with MSEC_PER_SEC constant.
*
* @param[in] val Time value in seconds
*
* @returns Time value in milliseconds
*/
static inline double util_secs_to_msecs(double val)
{
return val * MSEC_PER_SEC;
}
#endif /* LIB_UTIL_TIME_H */

View File

@@ -11,6 +11,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -44,27 +45,27 @@
typedef struct ttr
{
u_int16_t tt;
u_int8_t r;
uint16_t tt;
uint8_t r;
} __attribute__ ((packed)) ttr_t;
typedef struct cchhb
{
u_int16_t cc;
u_int16_t hh;
u_int8_t b;
uint16_t cc;
uint16_t hh;
uint8_t b;
} __attribute__ ((packed)) cchhb_t;
typedef struct cchh
{
u_int16_t cc;
u_int16_t hh;
uint16_t cc;
uint16_t hh;
} __attribute__ ((packed)) cchh_t;
typedef struct labeldate
{
u_int8_t year;
u_int16_t day;
uint8_t year;
uint16_t day;
} __attribute__ ((packed)) labeldate_t;
/*
@@ -84,7 +85,7 @@ typedef struct volume_label
char volkey[4]; /* volume key = volume label */
char vollbl[4]; /* volume label */
char volid[6]; /* volume identifier */
u_int8_t security; /* security byte */
uint8_t security; /* security byte */
cchhb_t vtoc; /* VTOC address */
char res1[5]; /* reserved */
char cisize[4]; /* CI-size for FBA,... */
@@ -118,8 +119,8 @@ static inline int is_vol1(char *this)
typedef struct extent
{
u_int8_t typeind; /* extent type indicator */
u_int8_t seqno; /* extent sequence number */
uint8_t typeind; /* extent type indicator */
uint8_t seqno; /* extent sequence number */
cchh_t llimit; /* starting point of this extent */
cchh_t ulimit; /* ending point of this extent */
} __attribute__ ((packed)) extent_t;
@@ -127,16 +128,16 @@ typedef struct extent
typedef struct dev_const
{
u_int16_t DS4DSCYL; /* number of logical cyls */
u_int16_t DS4DSTRK; /* number of tracks in a logical cylinder */
u_int16_t DS4DEVTK; /* device track length */
u_int8_t DS4DEVI; /* non-last keyed record overhead */
u_int8_t DS4DEVL; /* last keyed record overhead */
u_int8_t DS4DEVK; /* non-keyed record overhead differential */
u_int8_t DS4DEVFG; /* flag byte */
u_int16_t DS4DEVTL; /* device tolerance */
u_int8_t DS4DEVDT; /* number of DSCB's per track */
u_int8_t DS4DEVDB; /* number of directory blocks per track */
uint16_t DS4DSCYL; /* number of logical cyls */
uint16_t DS4DSTRK; /* number of tracks in a logical cylinder */
uint16_t DS4DEVTK; /* device track length */
uint8_t DS4DEVI; /* non-last keyed record overhead */
uint8_t DS4DEVL; /* last keyed record overhead */
uint8_t DS4DEVK; /* non-keyed record overhead differential */
uint8_t DS4DEVFG; /* flag byte */
uint16_t DS4DEVTL; /* device tolerance */
uint8_t DS4DEVDT; /* number of DSCB's per track */
uint8_t DS4DEVDB; /* number of directory blocks per track */
} __attribute__ ((packed)) dev_const_t;
/*
@@ -146,33 +147,33 @@ typedef struct dev_const
typedef struct format1_label
{
char DS1DSNAM[44]; /* data set name */
u_int8_t DS1FMTID; /* format identifier */
uint8_t DS1FMTID; /* format identifier */
unsigned char DS1DSSN[6];/* data set serial number */
u_int16_t DS1VOLSQ; /* volume sequence number */
uint16_t DS1VOLSQ; /* volume sequence number */
labeldate_t DS1CREDT; /* creation date: ydd */
labeldate_t DS1EXPDT; /* expiration date */
u_int8_t DS1NOEPV; /* number of extents on volume */
u_int8_t DS1NOBDB; /* no. of bytes used in last direction blk */
u_int8_t DS1FLAG1; /* flag 1 */
uint8_t DS1NOEPV; /* number of extents on volume */
uint8_t DS1NOBDB; /* no. of bytes used in last direction blk */
uint8_t DS1FLAG1; /* flag 1 */
unsigned char DS1SYSCD[13]; /* system code */
labeldate_t DS1REFD; /* date last referenced */
u_int8_t DS1SMSFG; /* system managed storage indicators */
u_int8_t DS1SCXTF; /* sec. space extension flag byte */
u_int16_t DS1SCXTV; /* secondary space extension value */
u_int8_t DS1DSRG1; /* data set organisation byte 1 */
u_int8_t DS1DSRG2; /* data set organisation byte 2 */
u_int8_t DS1RECFM; /* record format */
u_int8_t DS1OPTCD; /* option code */
u_int16_t DS1BLKL; /* block length */
u_int16_t DS1LRECL; /* record length */
u_int8_t DS1KEYL; /* key length */
u_int16_t DS1RKP; /* relative key position */
u_int8_t DS1DSIND; /* data set indicators */
u_int8_t DS1SCAL1; /* secondary allocation flag byte */
uint8_t DS1SMSFG; /* system managed storage indicators */
uint8_t DS1SCXTF; /* sec. space extension flag byte */
uint16_t DS1SCXTV; /* secondary space extension value */
uint8_t DS1DSRG1; /* data set organisation byte 1 */
uint8_t DS1DSRG2; /* data set organisation byte 2 */
uint8_t DS1RECFM; /* record format */
uint8_t DS1OPTCD; /* option code */
uint16_t DS1BLKL; /* block length */
uint16_t DS1LRECL; /* record length */
uint8_t DS1KEYL; /* key length */
uint16_t DS1RKP; /* relative key position */
uint8_t DS1DSIND; /* data set indicators */
uint8_t DS1SCAL1; /* secondary allocation flag byte */
char DS1SCAL3[3]; /* secondary allocation quantity */
ttr_t DS1LSTAR; /* last used track and block on track */
u_int16_t DS1TRBAL; /* space remaining on last used track */
u_int16_t res1; /* reserved */
uint16_t DS1TRBAL; /* space remaining on last used track */
uint16_t res1; /* reserved */
extent_t DS1EXT1; /* first extent description */
extent_t DS1EXT2; /* second extent description */
extent_t DS1EXT3; /* third extent description */
@@ -184,7 +185,7 @@ typedef struct format3_label
{
char DS3KEYID[4]; /* key identifier */
extent_t DS3EXTNT[4]; /* first 4 extent descriptions */
u_int8_t DS3FMTID; /* format identifier */
uint8_t DS3FMTID; /* format identifier */
extent_t DS3ADEXT[9]; /* last 9 extent description */
cchhb_t DS3PTRDS; /* pointer to next format3 DSCB */
} __attribute__ ((packed)) format3_label_t;
@@ -193,15 +194,15 @@ typedef struct format3_label
typedef struct format4_label
{
char DS4KEYCD[44]; /* key code for VTOC labels: 44 times 0x04 */
u_int8_t DS4IDFMT; /* format identifier */
uint8_t DS4IDFMT; /* format identifier */
cchhb_t DS4HPCHR; /* highest address of a format 1 DSCB */
u_int16_t DS4DSREC; /* number of available DSCB's */
uint16_t DS4DSREC; /* number of available DSCB's */
cchh_t DS4HCCHH; /* CCHH of next available alternate track */
u_int16_t DS4NOATK; /* number of remaining alternate tracks */
u_int8_t DS4VTOCI; /* VTOC indicators */
u_int8_t DS4NOEXT; /* number of extents in VTOC */
u_int8_t DS4SMSFG; /* system managed storage indicators */
u_int8_t DS4DEVAC; /* number of alternate cylinders.
uint16_t DS4NOATK; /* number of remaining alternate tracks */
uint8_t DS4VTOCI; /* VTOC indicators */
uint8_t DS4NOEXT; /* number of extents in VTOC */
uint8_t DS4SMSFG; /* system managed storage indicators */
uint8_t DS4DEVAC; /* number of alternate cylinders.
Subtract from first two bytes of
DS4DEVSZ to get number of usable
cylinders. can be zero. valid
@@ -214,21 +215,21 @@ typedef struct format4_label
char DS4F6PTR[5]; /* pointer to first format 6 DSCB */
extent_t DS4VTOCE; /* VTOC extent description */
char res2[10]; /* reserved */
u_int8_t DS4EFLVL; /* extended free-space management level */
uint8_t DS4EFLVL; /* extended free-space management level */
cchhb_t DS4EFPTR; /* pointer to extended free-space info */
char res3; /* reserved */
u_int32_t DS4DCYL; /* number of logical cyls */
uint32_t DS4DCYL; /* number of logical cyls */
char res4[2]; /* reserved */
u_int8_t DS4DEVF2; /* device flags */
uint8_t DS4DEVF2; /* device flags */
char res5; /* reserved */
} __attribute__ ((packed)) format4_label_t;
typedef struct ds5ext
{
u_int16_t t; /* RTA of the first track of free extent */
u_int16_t fc; /* number of whole cylinders in free ext. */
u_int8_t ft; /* number of remaining free tracks */
uint16_t t; /* RTA of the first track of free extent */
uint16_t fc; /* number of whole cylinders in free ext. */
uint8_t ft; /* number of remaining free tracks */
} __attribute__ ((packed)) ds5ext_t;
@@ -237,7 +238,7 @@ typedef struct format5_label
char DS5KEYID[4]; /* key identifier */
ds5ext_t DS5AVEXT; /* first available (free-space) extent. */
ds5ext_t DS5EXTAV[7]; /* seven available extents */
u_int8_t DS5FMTID; /* format identifier */
uint8_t DS5FMTID; /* format identifier */
ds5ext_t DS5MAVET[18]; /* eighteen available extents */
cchhb_t DS5PTRDS; /* pointer to next format5 DSCB */
} __attribute__ ((packed)) format5_label_t;
@@ -245,8 +246,8 @@ typedef struct format5_label
typedef struct ds7ext
{
u_int32_t a; /* starting RTA value */
u_int32_t b; /* ending RTA value + 1 */
uint32_t a; /* starting RTA value */
uint32_t b; /* ending RTA value + 1 */
} __attribute__ ((packed)) ds7ext_t;
@@ -254,7 +255,7 @@ typedef struct format7_label
{
char DS7KEYID[4]; /* key identifier */
ds7ext_t DS7EXTNT[5]; /* space for 5 extent descriptions */
u_int8_t DS7FMTID; /* format identifier */
uint8_t DS7FMTID; /* format identifier */
ds7ext_t DS7ADEXT[11]; /* space for 11 extent descriptions */
char res1[2]; /* reserved */
cchhb_t DS7PTRDS; /* pointer to next FMT7 DSCB */
@@ -263,12 +264,12 @@ typedef struct format7_label
typedef struct format9_label
{
u_int8_t DS9KEYID; /* key code for format 9 labels (0x09) */
u_int8_t DS9SUBTY; /* subtype (0x01) */
u_int8_t DS9NUMF9; /* number of F9 datasets */
u_int8_t res1[41]; /* reserved */
u_int8_t DS9FMTID; /* format identifier */
u_int8_t res2[90]; /* reserved */
uint8_t DS9KEYID; /* key code for format 9 labels (0x09) */
uint8_t DS9SUBTY; /* subtype (0x01) */
uint8_t DS9NUMF9; /* number of F9 datasets */
uint8_t res1[41]; /* reserved */
uint8_t DS9FMTID; /* format identifier */
uint8_t res2[90]; /* reserved */
cchhb_t DS9PTRDS; /* pointer to next DSCB */
} __attribute__ ((packed)) format9_label_t;
@@ -276,31 +277,31 @@ char * vtoc_ebcdic_enc (char *source, char *target, int l);
char * vtoc_ebcdic_dec (char *source, char *target, int l);
void vtoc_set_extent (
extent_t * ext,
u_int8_t typeind,
u_int8_t seqno,
uint8_t typeind,
uint8_t seqno,
cchh_t * lower,
cchh_t * upper);
void vtoc_set_cchh (
cchh_t * addr,
u_int32_t cc,
u_int16_t hh);
u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr);
u_int16_t vtoc_get_head_from_cchh(cchh_t *addr);
uint32_t cc,
uint16_t hh);
uint32_t vtoc_get_cyl_from_cchh(cchh_t *addr);
uint16_t vtoc_get_head_from_cchh(cchh_t *addr);
void vtoc_set_cchhb (
cchhb_t * addr,
u_int32_t cc,
u_int16_t hh,
u_int8_t b);
u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr);
u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr);
u_int64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo);
u_int64_t cchh2blk (cchh_t *p, struct hd_geometry *geo);
u_int32_t cchh2trk (cchh_t *p, struct hd_geometry *geo);
uint32_t cc,
uint16_t hh,
uint8_t b);
uint32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr);
uint16_t vtoc_get_head_from_cchhb(cchhb_t *addr);
uint64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo);
uint64_t cchh2blk (cchh_t *p, struct hd_geometry *geo);
uint32_t cchh2trk (cchh_t *p, struct hd_geometry *geo);
void vtoc_set_date (
labeldate_t * d,
u_int8_t year,
u_int16_t day);
uint8_t year,
uint16_t day);
void vtoc_volume_label_init (
volume_label_t *vlabel);
@@ -365,12 +366,12 @@ void vtoc_init_format4_label (
unsigned int tracks,
unsigned int blocks,
unsigned int blksize,
u_int16_t dev_type);
uint16_t dev_type);
void vtoc_update_format4_label (
format4_label_t *f4,
cchhb_t *highest_f1,
u_int16_t unused_update);
uint16_t unused_update);
void vtoc_init_format5_label (
format5_label_t *f5);
@@ -379,17 +380,17 @@ void vtoc_update_format5_label_add (
format5_label_t *f5,
int verbose,
int trk,
u_int16_t a,
u_int16_t b,
u_int8_t c);
uint16_t a,
uint16_t b,
uint8_t c);
void vtoc_update_format5_label_del (
format5_label_t *f5,
int verbose,
int trk,
u_int16_t a,
u_int16_t b,
u_int8_t c);
uint16_t a,
uint16_t b,
uint8_t c);
void vtoc_init_format7_label (
format7_label_t *f7);
@@ -397,14 +398,14 @@ void vtoc_init_format7_label (
void vtoc_update_format7_label_add (
format7_label_t *f7,
int verbose,
u_int32_t a,
u_int32_t b);
uint32_t a,
uint32_t b);
void vtoc_update_format7_label_del (
format7_label_t *f7,
int verbose,
u_int32_t a,
u_int32_t b);
uint32_t a,
uint32_t b);
void vtoc_init_format8_label (
unsigned int blksize,
@@ -424,9 +425,9 @@ void vtoc_set_freespace(
format7_label_t *f7,
char ch,
int verbose,
u_int32_t start,
u_int32_t stop,
u_int32_t cyl,
u_int32_t trk);
uint32_t start,
uint32_t stop,
uint32_t cyl,
uint32_t trk);
#endif /* LIB_VTOC_H */

View File

@@ -64,6 +64,7 @@
#define TOOLS_BINDIR STRINGIFY (S390_TOOLS_BINDIR)
#define TOOLS_DATADIR STRINGIFY (S390_TOOLS_DATADIR)
#define __used __attribute__((used))
#define __noreturn __attribute__((noreturn))
#define __packed __attribute__((packed))
#define __aligned(x) __attribute__((aligned(x)))

View File

@@ -26,7 +26,7 @@
#define BOOTPARMS_NSS_MAX 56
#define BOOTPARMS_CCW_MAX 64
#define BOOTPARMS_FCP_MAX 3452
#define BOOTPARMS_SCPDATA_MAX 3452
#define OPT_BRCHR 0x80
@@ -835,6 +835,12 @@ static void chreipl_eckd(void)
ERR_EXIT("Could not find DASD ECKD device \"%s\"", l.busid);
}
check_exists("reipl/eckd/device", "\"eckd\" re-IPL target");
if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_SCPDATA_MAX) {
ERR_EXIT("Maximum boot parameter length exceeded (%zu/%u)",
strlen(l.bootparms), BOOTPARMS_SCPDATA_MAX);
}
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");
@@ -848,6 +854,8 @@ static void chreipl_eckd(void)
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_optional(l.bootparms, "reipl/eckd/scp_data", l.bootparms_set,
"boot parameters");
write_str("eckd", "reipl/reipl_type");
print_eckd(0, "eckd");
}
@@ -862,9 +870,9 @@ static void chreipl_fcp(void)
ERR_EXIT("Could not find FCP device \"%s\"", l.busid);
}
check_exists("reipl/fcp/device", "\"fcp\" re-IPL target");
if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_FCP_MAX) {
if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_SCPDATA_MAX) {
ERR_EXIT("Maximum boot parameter length exceeded (%zu/%u)",
strlen(l.bootparms), BOOTPARMS_FCP_MAX);
strlen(l.bootparms), BOOTPARMS_SCPDATA_MAX);
}
if (l.reipl_clear >= 0) {
@@ -905,9 +913,9 @@ static void chreipl_nvme(void)
}
check_exists("reipl/nvme/fid", "\"nvme\" re-IPL target");
if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_FCP_MAX) {
if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_SCPDATA_MAX) {
ERR_EXIT("Maximum boot parameter length exceeded (%zu/%u)",
strlen(l.bootparms), BOOTPARMS_FCP_MAX);
strlen(l.bootparms), BOOTPARMS_SCPDATA_MAX);
}
if (l.reipl_clear >= 0) {

View File

@@ -157,6 +157,7 @@ void print_eckd(int show_ipl, const char *name)
{
char *dir = show_ipl ? "ipl" : "reipl/eckd";
char *path_loadparm = util_path_sysfs("firmware/%s/loadparm", dir);
char *path_reipl_clear = util_path_sysfs("firmware/reipl/eckd/clear");
char *path_secure_boot = util_path_sysfs("firmware/ipl/secure");
char *loadparm;
@@ -172,7 +173,7 @@ void print_eckd(int show_ipl, const char *name)
printf("Loadparm: \"%s\"\n", loadparm);
free(loadparm);
}
if (!show_ipl)
if (!show_ipl && access(path_reipl_clear, R_OK) == 0)
print_fw_str("clear: %s\n", dir, "clear");
if (access(path_secure_boot, R_OK) == 0)
print_fw_str("Secure boot: %s\n", "ipl", "secure");

View File

@@ -11,6 +11,7 @@
#include <sys/types.h>
#include <dirent.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
@@ -99,7 +100,7 @@ static int next_entry(DIR *dir, char *in_path, char *out_path,
static int nvme_getdev_by_fid(char *fidstr, char *devpath)
{
char temp_path[PATH_MAX + 19], real_path[PATH_MAX];
u_int64_t target_fid, curfid;
uint64_t target_fid, curfid;
char *sys_path;
DIR *dir;
char *end;
@@ -140,7 +141,7 @@ static int nvme_getdev_by_nsid(char *nsid_str, char *path, char *dev_path)
{
char full_path[NVME_PATH_MAX+1], nsid_path[sizeof(full_path)+5];
char *end;
u_int64_t nsid, curnsid;
uint64_t nsid, curnsid;
DIR *dir;
nsid = strtoul(nsid_str, &end, 10);

View File

@@ -1,6 +1,6 @@
include ../common.mak
VERSION = 1.0
VERSION = 1.1
VERM = $(shell echo $(VERSION) | cut -d '.' -f 1)
ifneq (${HAVE_OPENSSL},0)
@@ -91,13 +91,13 @@ libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o $(libs)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so
ln -sf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
ln -sf libekmfweb.so.$(VERSION) libekmfweb.so
install-libekmfweb.so.$(VERSION): libekmfweb.so.$(VERSION)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION)
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERM)
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so
ln -sf libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERM)
ln -sf libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so
$(INSTALL) -d -m 755 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb

View File

@@ -5283,6 +5283,85 @@ out:
return rc;
}
/**
* Validates that a certificate has the same public key as the secure identity
* key (field identity_secure_key in config structure) .
*
* @param config the configuration structure. Only field
* identity_secure_key must be specified, all others
* are optional.
* @param x509_cert the X509 certificate object to validate
* @param ext_lib External secure key crypto library to use
* @param verbose if true, verbose messages are printed
*
* @returns a negative errno in case of an error, 0 if success.
* -EINVAL: invalid parameter, or certificate is not valid
* -ENOMEM: Failed to allocate memory
* any other errno from file I/O routines
*/
int ekmf_validate_cert(const struct ekmf_config *config, const X509 *x509_cert,
const struct ekmf_ext_lib *ext_lib, bool verbose)
{
unsigned char key_blob[MAX_KEY_BLOB_SIZE];
size_t key_blob_size = sizeof(key_blob);
struct ext_lib_info ext_lib_info;
EVP_PKEY *pkey = NULL;
int rc;
if (config == NULL || ext_lib == NULL || x509_cert == NULL)
return -EINVAL;
if (config->identity_secure_key == NULL)
return -EINVAL;
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
rc = SK_OPENSSL_init(verbose);
if (rc != 0) {
pr_verbose(verbose, "Failed to initialize secure key support: "
"%s", strerror(-rc));
return rc;
}
rc = read_key_blob(config->identity_secure_key, key_blob,
&key_blob_size);
if (rc != 0) {
pr_verbose(verbose, "Failed to read identity key from file "
"'%s': %s", config->identity_secure_key,
strerror(-rc));
goto out;
}
rc = SK_OPENSSL_get_secure_key_as_pkey(key_blob, key_blob_size,
false, &pkey,
&ext_lib_info.ext_lib, verbose);
if (rc != 0) {
pr_verbose(verbose, "Failed to get the PKEY from the identity "
"key: %s", strerror(-rc));
goto out;
}
#if !OPENSSL_VERSION_PREREQ(3, 0)
if (EVP_PKEY_cmp(pkey, X509_get0_pubkey(x509_cert)) != 1) {
#else
if (EVP_PKEY_eq(pkey, X509_get0_pubkey(x509_cert)) != 1) {
#endif
pr_verbose(verbose, "The certificate does not match with the "
"identity key");
rc = -EINVAL;
goto out;
}
pr_verbose(verbose, "Certificate successfully validated");
out:
if (pkey != NULL)
EVP_PKEY_free(pkey);
SK_OPENSSL_term();
return rc;
}
/**
* Close the connection to the EKMFWeb server by destroying the CURL handle.
*

View File

@@ -8,6 +8,7 @@ LIBEKMFWEB_1.0 {
ekmf_reencipher_identity_key;
ekmf_generate_csr;
ekmf_generate_ss_cert;
ekmf_validate_cert;
ekmf_get_public_key;
ekmf_get_settings;
ekmf_check_feature;
@@ -28,3 +29,9 @@ LIBEKMFWEB_1.0 {
ekmf_curl_destroy;
local: *;
};
LIBEKMFWEB_1.1 {
global:
ekmf_validate_cert;
local: *;
};

View File

@@ -113,13 +113,13 @@ libkmipclient.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libkmip
libkmipclient.so.$(VERSION): kmip.o request.o response.o attribute.o key.o ttlv.o json.o \
xml.o https.o tls.o names.o utils.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ln -srf libkmipclient.so.$(VERSION) libkmipclient.so.$(VERM)
ln -srf libkmipclient.so.$(VERSION) libkmipclient.so
ln -sf libkmipclient.so.$(VERSION) libkmipclient.so.$(VERM)
ln -sf libkmipclient.so.$(VERSION) libkmipclient.so
install-libkmipclient.so.$(VERSION): libkmipclient.so.$(VERSION)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERSION)
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERM)
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so
ln -sf libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERM)
ln -sf libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so
$(INSTALL) -d -m 755 $(DESTDIR)$(USRINCLUDEDIR)/kmipclient
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/kmipclient/kmipclient.h $(DESTDIR)$(USRINCLUDEDIR)/kmipclient

View File

@@ -233,7 +233,7 @@ out:
if (server_cert != NULL)
X509_free(server_cert);
return 0;
return rc;
}
/**

View File

@@ -1,13 +1,16 @@
include ../common.mak
include ../common_autocomp.mak
lib := libutil.a
sources := $(filter-out %_example.c,$(wildcard *.c))
sources := $(filter-out %_example.c %_host.c, $(wildcard *.c))
objects := $(patsubst %.c,%.o,$(sources))
autocomp-object := util_autocomp_host.o
examples := $(patsubst %.c,%,$(wildcard *_example.c))
all: $(lib)
all: $(lib) $(autocomp-object)
examples: $(examples)
$(examples): %: %.o $(lib)

View File

@@ -0,0 +1,299 @@
// SPDX-License-Identifier: MIT
/*
* autocomp - command line autocompletion
*
* Generating autocompletion scripts for bash and zsh
* based on util_opt struct
*
* Copyright IBM Corp. 2025
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lib/util_autocomp.h"
#include "lib/util_opt.h"
static const char *bash_script_part1 = "() {\n\n\
\tlocal current_word previous_word options_array\n\n\
\tCOMPREPLY=()\n\n\
\tcurrent_word=\"${COMP_WORDS[COMP_CWORD]}\"\n\n\
\tprevious_word=\"${COMP_WORDS[COMP_CWORD-1]}\"\n\n\
\toptions_array=\"";
static const char *bash_script_part2 = "\tif [[ ${current_word} == -* || ${COMP_CWORD} -eq 1 ]] ; then\n\n\
\t\tCOMPREPLY=( $(compgen -W \"${options_array}\" -- ${current_word} ) )\n\n\
\t\treturn 0\n\n\
\tfi\n\n\
}\n\n\
complete -F ";
static char *format_name(const char *fmt, char *tool_name)
{
char *func_name;
if (asprintf(&func_name, fmt, tool_name) == -1)
return NULL;
return func_name;
}
/*
* The convention for a completion function name is to be the same
* as the command's name, but prefixed by '_'.
*/
static char *generate_func_name(char *tool_name)
{
return format_name("_%s", tool_name);
}
static char *generate_bash_filename(char *tool_name)
{
return format_name("%s.bash", tool_name);
}
static int init_scriptfile(char *file_path)
{
int fd;
fd = open(file_path, O_CREAT | O_WRONLY, 0644);
if (fd < 0)
return -EIO;
return fd;
}
static int start_bash_scriptfile(int fd, char *func_name)
{
int len, ret = 0;
char *str;
len = asprintf(&str, "%s%s", func_name, bash_script_part1);
if (len == -1)
return -EIO;
if (write(fd, str, len) != len)
ret = -EIO;
free(str);
return ret;
}
static int start_zsh_scriptfile(int fd, char *func_name, char *tool_name)
{
const char *part3 = " {\n\n\t_arguments -C \\\n";
const char *part2 = "\n\nfunction ";
const char *part1 = "#compdef ";
int len, ret = 0;
char *str;
len = asprintf(&str, "%s%s%s%s%s", part1, tool_name, part2, func_name, part3);
if (len == -1)
return -EIO;
if (write(fd, str, len) != len)
ret = -EIO;
free(str);
return ret;
}
static int write_bash_command_options(struct util_opt *opt_vec, int fd)
{
const char *prefix = " --";
char *str;
int len;
for (int i = 0; opt_vec[i].desc; i++) {
if (opt_vec[i].option.name) {
len = asprintf(&str, "%s%s", prefix, opt_vec[i].option.name);
if (len == -1)
return -EIO;
if (write(fd, str, len) != len) {
free(str);
return -EIO;
}
free(str);
}
}
if (write(fd, "\"\n\n", 3) != 3)
return -EIO;
return 0;
}
static int write_zsh_command_options(struct util_opt *opt_vec, int fd)
{
const char *name, *desc;
char *str;
int len;
for (int i = 0; opt_vec[i].desc; i++) {
if (opt_vec[i].option.name) {
name = opt_vec[i].option.name;
desc = opt_vec[i].desc;
len = asprintf(&str, "\t\t\"--%s[%s]\" \\\n", name, desc);
if (len == -1)
return -EIO;
if (write(fd, str, len) != len) {
free(str);
return -EIO;
}
free(str);
}
}
if (write(fd, "\n}\n", 3) != 3)
return -EIO;
return 0;
}
static int finish_bash_scriptfile(char *tool_name, int fd, char *func_name)
{
int len, ret = 0;
char *str;
len = asprintf(&str, "%s%s %s\n", bash_script_part2, func_name, tool_name);
if (len == -1)
return -EIO;
if (write(fd, str, len) != len)
ret = -EIO;
free(str);
return ret;
}
/*
* Adds tab completion in bash for a command.
* Works by generating an autocompletion
* script file at '/usr/share/bash-completion/completions'.
*
* The full script will be as follows, supposing the tool name is
* 'example' and it only has the options '--help' and
* '--version':
*
* _example() {
*
* local current_word previous_word options_array
*
* COMPREPLY=()
*
* current_word="${COMP_WORDS[COMP_CWORD]}"
*
* previous_word="${COMP_WORDS[COMP_CWORD-1]}"
*
* options_array="--version --help"
*
* if [[ ${current_word} == -* || ${COMP_CWORD} -eq 1 ]] ; then
*
* COMPREPLY=( $(compgen -W "${options_array}" -- ${current_word} ) )
*
* return 0
*
* fi
*
* }
*
* complete -F _example example
*
*/
static void generate_bash_autocomp(struct util_opt *opt_vec, char *tool_name)
{
char *func_name, *filename;
int fd, ret = 0;
func_name = generate_func_name(tool_name);
if (!func_name) {
ret = -ENOMEM;
goto end;
}
filename = generate_bash_filename(tool_name);
if (!filename) {
ret = -ENOMEM;
goto free_func;
}
fd = init_scriptfile(filename);
if (fd < 0) {
ret = fd;
goto free_file;
}
ret = start_bash_scriptfile(fd, func_name);
if (ret < 0)
goto close;
ret = write_bash_command_options(opt_vec, fd);
if (ret < 0)
goto close;
ret = finish_bash_scriptfile(tool_name, fd, func_name);
close:
close(fd);
if (ret)
remove(filename);
free_file:
free(filename);
free_func:
free(func_name);
end:
printf(" AUTOCOMP\t%s/%s.bash\n", tool_name, tool_name);
if (ret)
printf("%s.bash: error - %s\n", tool_name, strerror(abs(ret)));
}
/*
* Adds tab completion in zsh for a command.
* Works by generating an autocompletion
* script file at '/usr/share/zsh/site-functions'.
*
* The full script will be as follows, supposing the tool name is
* 'example' and it only has the options '--help', -h and
* '--version' (the descriptions, as well as the flags are
* taken from a util_opt struct):
*
* #compdef example_completion
*
* function _example_completion {
*
* _arguments -C \
* "-h[Show help information]" \
* "--help[Show help but long format]" \
* "--version[Show version]"
* }
*
*/
static void generate_zsh_autocomp(struct util_opt *opt_vec, char *tool_name)
{
char *func_name;
int fd, ret = 0;
func_name = generate_func_name(tool_name);
if (!func_name) {
ret = -ENOMEM;
goto end;
}
fd = init_scriptfile(func_name);
if (fd < 0) {
ret = fd;
goto free_func;
}
ret = start_zsh_scriptfile(fd, func_name, tool_name);
if (ret < 0)
goto close;
ret = write_zsh_command_options(opt_vec, fd);
close:
close(fd);
if (ret)
remove(func_name);
free_func:
free(func_name);
end:
printf(" AUTOCOMP\t%s/_%s\n", tool_name, tool_name);
if (ret)
printf("_%s: error - %s\n", tool_name, strerror(abs(ret)));
}
void generate_autocomp(struct util_opt *opt_vec, char *tool_name)
{
generate_bash_autocomp(opt_vec, tool_name);
generate_zsh_autocomp(opt_vec, tool_name);
}

View File

@@ -544,19 +544,6 @@ int util_file_read_va(const char *path, const char *fmt, ...)
return ret;
}
/**
* Print an error message indicating an out-of-memory situation and exit.
*/
static void oom(void)
{
fprintf(stderr, "Out of memory\n");
/* We can't rely on our clean-up routines to work reliably during an
* OOM situation, so just exit here.
*/
exit(UTIL_EXIT_OUT_OF_MEMORY);
}
/**
* Read all data from @fd and return address of resulting buffer in
* @buffer_ptr. If @size_ptr is non-zero, use it to store the size of the
@@ -576,9 +563,7 @@ util_exit_code_t util_file_read_fd_buf(FILE *fd, void **buffer_ptr,
size_t done = 0;
while (!feof(fd)) {
buffer = realloc(buffer, done + READ_CHUNK_SIZE);
if (!buffer)
oom();
buffer = util_realloc(buffer, done + READ_CHUNK_SIZE);
done += fread(&buffer[done], 1, READ_CHUNK_SIZE, fd);
if (ferror(fd)) {
free(buffer);
@@ -586,9 +571,7 @@ util_exit_code_t util_file_read_fd_buf(FILE *fd, void **buffer_ptr,
}
}
buffer = realloc(buffer, done);
if (!buffer && done > 0)
oom();
buffer = util_realloc(buffer, done);
*buffer_ptr = buffer;
if (size_ptr)
@@ -635,9 +618,7 @@ char *util_file_read_fd(FILE *fd, int chomp)
done--;
/* NULL-terminate. */
buffer = realloc(buffer, done + 1);
if (!buffer)
oom();
buffer = util_realloc(buffer, done + 1);
buffer[done] = 0;
return buffer;

View File

@@ -10,11 +10,15 @@
*/
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "lib/util_base.h"
#include "lib/util_libc.h"
@@ -89,6 +93,11 @@ void *__util_realloc(const char *func, const char *file, int line,
{
void *buf;
if (size == 0) {
free(ptr);
return NULL;
}
buf = realloc(ptr, size);
if (buf == NULL)
@@ -290,3 +299,31 @@ size_t util_strlcpy(char *dest, const char *src, size_t size)
return str_len;
}
char *__util_readlinkat(const char *func, const char *file, int line, int dirfd, const char *path)
{
ssize_t link_len = PATH_MAX;
struct stat st;
char *linkdir;
ssize_t len;
if (fstatat(dirfd, path, &st, AT_SYMLINK_NOFOLLOW) == 0 && st.st_size > 0)
link_len = st.st_size + 1;
linkdir = __util_malloc(func, file, line, link_len);
len = readlinkat(dirfd, path, linkdir, link_len);
if (len == -1) {
free(linkdir);
return NULL;
}
if (len >= link_len) {
warnx("%s: Link target too long", path);
free(linkdir);
return NULL;
}
linkdir[len] = '\0';
return __util_realloc(func, file, line, linkdir, (size_t)len + 1);
}

View File

@@ -9,7 +9,6 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -9,7 +9,6 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <argz.h>
#include <libgen.h>
#include <stdbool.h>
#include <stdio.h>

View File

@@ -9,12 +9,14 @@
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <execinfo.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <sys/time.h>
#ifdef __GLIBC__
#include <execinfo.h>
#endif
#include "lib/util_base.h"
#include "lib/util_panic.h"
@@ -24,6 +26,7 @@
*
* To get symbols, link the code with "-rdynamic".
*/
#ifdef __GLIBC__
static void print_backtrace(void)
{
void *array[256];
@@ -42,6 +45,9 @@ static void print_backtrace(void)
free(strings);
}
#else
static void print_backtrace(void) {}
#endif
/*
* Check for core ulimit

220
libutil/util_parse.c Normal file
View File

@@ -0,0 +1,220 @@
/* SPDX-License-Identifier: MIT */
/*
* util - Utility function library
*
* String parsing utility functions
*
* Copyright IBM Corp. 2026
*/
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lib/util_libc.h"
#include "lib/util_parse.h"
#include "lib/util_str.h"
#include "lib/zt_common.h"
enum size_unit {
UNIT_BYTES = 0,
UNIT_KIB, /* 1024 */
UNIT_K, /* 1000 */
UNIT_MIB, /* 1024^2 */
UNIT_M, /* 1000^2 */
UNIT_GIB, /* 1024^3 */
UNIT_G, /* 1000^3 */
UNIT_TIB, /* 1024^4 */
UNIT_T, /* 1000^4 */
UNIT_PIB, /* 1024^5 */
UNIT_P, /* 1000^5 */
UNIT_EIB, /* 1024^6 */
UNIT_E, /* 1000^6 */
};
struct unit_mapping {
const char *suffix;
enum size_unit unit;
uint64_t multiplier;
};
static const struct unit_mapping unit_table[] = {
{ "EiB", UNIT_EIB, 1024ULL * 1024 * 1024 * 1024 * 1024 * 1024 },
{ "E", UNIT_E, 1000ULL * 1000 * 1000 * 1000 * 1000 * 1000 },
{ "PiB", UNIT_PIB, 1024ULL * 1024 * 1024 * 1024 * 1024 },
{ "P", UNIT_P, 1000ULL * 1000 * 1000 * 1000 * 1000 },
{ "TiB", UNIT_TIB, 1024ULL * 1024 * 1024 * 1024 },
{ "T", UNIT_T, 1000ULL * 1000 * 1000 * 1000 },
{ "GiB", UNIT_GIB, 1024ULL * 1024 * 1024 },
{ "G", UNIT_G, 1000ULL * 1000 * 1000 },
{ "MiB", UNIT_MIB, 1024ULL * 1024 },
{ "M", UNIT_M, 1000ULL * 1000 },
{ "KiB", UNIT_KIB, 1024ULL },
{ "K", UNIT_K, 1000ULL },
{ "", UNIT_BYTES, 1ULL }
};
static const char *const bool_false_values[] = { "0", "n", "no", "f", "false", "off" };
static const char *const bool_true_values[] = { "1", "y", "yes", "t", "true", "on" };
/* Ensure both arrays have the same size for consistency */
STATIC_ASSERT(ARRAY_SIZE(bool_false_values) == ARRAY_SIZE(bool_true_values));
static const struct unit_mapping *find_unit_suffix(const char *suffix)
{
size_t i;
if (!suffix || *suffix == '\0')
return &unit_table[ARRAY_SIZE(unit_table) - 1];
for (i = 0; i < ARRAY_SIZE(unit_table); i++) {
if (strcasecmp(suffix, unit_table[i].suffix) == 0)
return &unit_table[i];
}
return NULL;
}
/**
* util_parse_bool - Parse a boolean value from a string
* @input: Input string to parse
*
* Returns: 1 for true, 0 for false, -EINVAL on error
*/
int util_parse_bool(const char *input)
{
size_t i;
if (!input)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(bool_false_values); i++) {
if (strcasecmp(input, bool_false_values[i]) == 0)
return 0;
}
for (i = 0; i < ARRAY_SIZE(bool_true_values); i++) {
if (strcasecmp(input, bool_true_values[i]) == 0)
return 1;
}
return -EINVAL;
}
int util_parse_byte_size(const char *input, size_t *bytes)
{
const struct unit_mapping *unit;
uint64_t multiplier = 1;
unsigned long value;
char *endptr;
if (!input || !bytes)
return -EINVAL;
errno = 0;
value = strtoul(input, &endptr, 10);
if (errno == ERANGE)
return -ERANGE;
if (errno != 0)
return -errno;
if (endptr == input)
return -EINVAL;
if (*endptr != '\0') {
unit = find_unit_suffix(endptr);
if (!unit)
return -EINVAL;
multiplier = unit->multiplier;
}
if (value > SIZE_MAX / multiplier)
return -ERANGE;
*bytes = (size_t)(value * multiplier);
return 0;
}
int util_parse_range(const char *input, struct util_range *range)
{
char *start_str, *end_str;
char *input_copy;
char *dash_pos;
int ret = 0;
if (!input || !range)
return -EINVAL;
input_copy = util_strdup(input);
dash_pos = strchr(input_copy, '-');
if (!dash_pos) {
ret = -EINVAL;
goto out;
}
*dash_pos = '\0';
start_str = input_copy;
end_str = dash_pos + 1;
ret = util_parse_int(start_str, &range->start);
if (ret)
goto out;
ret = util_parse_int(end_str, &range->end);
if (ret)
goto out;
if (range->start > range->end) {
ret = -ERANGE;
goto out;
}
out:
free(input_copy);
return ret;
}
int util_parse_int(const char *input, size_t *value)
{
const char *num_start, *rest;
char *endptr = NULL;
int base = 0;
if (!input || !value)
return -EINVAL;
if (*input == '\0')
return -EINVAL;
num_start = input;
/* Determine base from prefix */
/* Supports: 0x (hex), 0b (binary), 0o/0 (octal), decimal */
rest = util_startswith_no_case(input, "0b");
if (rest) {
base = 2;
num_start = rest;
if (*num_start == '\0')
return -EINVAL;
} else {
rest = util_startswith_no_case(input, "0o");
if (rest) {
base = 8;
num_start = rest;
if (*num_start == '\0')
return -EINVAL;
}
/* base=0: strtoull handles 0x (hex) and 0 (octal) */
}
errno = 0;
*value = strtoull(num_start, &endptr, base);
if (errno == ERANGE)
return -ERANGE;
if (!endptr || endptr == num_start || *endptr != '\0')
return -EINVAL;
return 0;
}

View File

@@ -16,10 +16,8 @@
#include <sys/types.h>
#include <unistd.h>
#include "lib/util_base.h"
#include "lib/util_libc.h"
#include "lib/util_path.h"
#include "lib/util_prg.h"
/*
* Verify that directory exists

View File

@@ -68,7 +68,7 @@ static int __scandir(struct dirent ***de_vec, const char *path,
continue;
de_new = util_malloc(sizeof(*de_new));
*de_new = *de;
de_vec_new = realloc(de_vec_new, sizeof(void *) * (count + 1));
de_vec_new = util_realloc(de_vec_new, sizeof(void *) * (count + 1));
de_vec_new[count++] = de_new;
}
closedir(dirp);

View File

@@ -3,14 +3,16 @@
*
* Manipulate and work with strings
*
* Copyright IBM Corp. 2025
* Copyright IBM Corp. 2026
*
* 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 <string.h>
#include "lib/util_panic.h"
#include "lib/util_str.h"
/**
@@ -31,3 +33,45 @@ void util_str_rm_whitespace(const char *src, char *dest)
}
*dest = '\0';
}
/**
* Check if string \a s starts with \a prefix
*
* @param[in] s String to check
* @param[in] prefix Prefix to match
*
* @returns Pointer to the character after the prefix if match is found,
* NULL otherwise
*/
const char *util_startswith(const char *s, const char *prefix)
{
size_t sz;
util_assert(s != NULL, "Internal error: s input is NULL");
util_assert(prefix != NULL, "Internal error: prefix input is NULL");
sz = strlen(prefix);
if (strncmp(s, prefix, sz) == 0)
return s + sz;
return NULL;
}
/**
* Check if string \a s starts with \a prefix (case-insensitive)
*
* @param[in] s String to check
* @param[in] prefix Prefix to match (case-insensitive)
*
* @returns Pointer to the character after the prefix if match is found,
* NULL otherwise
*/
const char *util_startswith_no_case(const char *s, const char *prefix)
{
size_t sz;
util_assert(s != NULL, "Internal error: s input is NULL");
util_assert(prefix != NULL, "Internal error: prefix input is NULL");
sz = strlen(prefix);
if (strncasecmp(s, prefix, sz) == 0)
return s + sz;
return NULL;
}

View File

@@ -24,8 +24,6 @@
#include "lib/util_path.h"
#include "lib/util_sys.h"
/* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */
#define READLINK_SIZE 256
#define PAGE_SIZE 4096
/**
@@ -137,10 +135,10 @@ int util_sys_get_base_dev(dev_t dev, dev_t *base_dev)
*/
int util_sys_get_dev_addr(const char *dev, char *addr)
{
char device[READLINK_SIZE], *result;
unsigned int maj, min;
struct stat s;
ssize_t len;
char *linkdir;
char *result;
dev_t base;
char *path;
@@ -160,19 +158,18 @@ int util_sys_get_dev_addr(const char *dev, char *addr)
else
return -1;
len = readlink(path, device, READLINK_SIZE - 1);
linkdir = util_readlink(path);
free(path);
if (len != -1)
device[len] = '\0';
else
if (!linkdir)
return -1;
result = strrchr(device, '/');
result = strrchr(linkdir, '/');
if (result)
result++;
else
result = device;
result = linkdir;
strcpy(addr, result);
free(linkdir);
return 0;
}

View File

@@ -6,6 +6,8 @@
*
*/
#include <stdint.h>
#include "lib/vtoc.h"
static unsigned char EBCtoASC[256] =
@@ -24,23 +26,23 @@ static unsigned char EBCtoASC[256] =
-INP */
0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
-SW */
-SW */
0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
/* 0x40 SP RSP <EFBFBD> ---- */
/* 0x40 SP RSP ä ---- */
0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
/* 0x48 . < ( + | */
0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
/* 0x50 & ---- */
0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
/* 0x58 <EFBFBD> ! $ * ) ; */
/* 0x58 ß ! $ * ) ; */
0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
/* 0x60 - / ---- <EFBFBD> ---- ---- ---- */
/* 0x60 - / ---- Ä ---- ---- ---- */
0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
/* 0x68 ---- , % _ > ? */
/* 0x68 ---- , % _ > ? */
0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
/* 0x70 --- ---- ---- ---- ---- ---- ---- */
0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
@@ -50,7 +52,7 @@ static unsigned char EBCtoASC[256] =
0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
/* 0x88 h i ---- ---- ---- */
0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
/* 0x90 <EFBFBD> j k l m n o p */
/* 0x90 ° j k l m n o p */
0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
/* 0x98 q r ---- ---- */
0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
@@ -58,25 +60,25 @@ static unsigned char EBCtoASC[256] =
0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
/* 0xA8 y z ---- ---- ---- ---- */
0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
/* 0xB0 ^ ---- <EFBFBD> ---- */
/* 0xB0 ^ ---- § ---- */
0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
/* 0xB8 ---- [ ] ---- ---- ---- ---- */
0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
/* 0xC0 { A B C D E F G */
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
/* 0xC8 H I ---- <EFBFBD> ---- */
/* 0xC8 H I ---- ö ---- */
0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
/* 0xD0 } J K L M N O P */
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
/* 0xD8 Q R ---- <EFBFBD> */
/* 0xD8 Q R ---- ü */
0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
/* 0xE0 \ S T U V W X */
0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
/* 0xE8 Y Z ---- <EFBFBD> ---- ---- ---- */
/* 0xE8 Y Z ---- Ö ---- ---- ---- */
0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
/* 0xF0 0 1 2 3 4 5 6 7 */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
/* 0xF8 8 9 ---- ---- <EFBFBD> ---- ---- ---- */
/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
};
@@ -142,7 +144,7 @@ static char buffer[85];
/*
*
*/
static void vtoc_error(enum failure why, char *s1, char *s2)
static void vtoc_error(enum failure why, char *s1, char *s2)
{
switch (why) {
case unable_to_open:
@@ -170,11 +172,11 @@ static void vtoc_error(enum failure why, char *s1, char *s2)
/*
*
*/
char * vtoc_ebcdic_enc (char *source, char *target, int l)
char * vtoc_ebcdic_enc (char *source, char *target, int l)
{
int i;
for (i = 0; i < l; i++)
for (i = 0; i < l; i++)
target[i]=ASCtoEBC[(unsigned char)(source[i])];
return target;
@@ -184,11 +186,11 @@ char * vtoc_ebcdic_enc (char *source, char *target, int l)
/*
*
*/
char * vtoc_ebcdic_dec (char *source, char *target, int l)
char * vtoc_ebcdic_dec (char *source, char *target, int l)
{
int i;
for (i = 0; i < l; i++)
for (i = 0; i < l; i++)
target[i]=EBCtoASC[(unsigned char)(source[i])];
return target;
@@ -198,9 +200,9 @@ char * vtoc_ebcdic_dec (char *source, char *target, int l)
/*
*
*/
void vtoc_set_extent (extent_t *ext, u_int8_t typeind, u_int8_t seqno,
cchh_t *lower, cchh_t *upper)
{
void vtoc_set_extent (extent_t *ext, uint8_t typeind, uint8_t seqno,
cchh_t *lower, cchh_t *upper)
{
ext->typeind = typeind;
ext->seqno = seqno;
memcpy(&ext->llimit,lower,sizeof(cchh_t));
@@ -211,17 +213,17 @@ void vtoc_set_extent (extent_t *ext, u_int8_t typeind, u_int8_t seqno,
/*
*
*/
void vtoc_set_cchh (cchh_t *addr, u_int32_t cc, u_int16_t hh)
void vtoc_set_cchh (cchh_t *addr, uint32_t cc, uint16_t hh)
{
addr->cc = (u_int16_t) cc;
addr->cc = (uint16_t) cc;
addr->hh = cc >> 16;
addr->hh <<= 4;
addr->hh |= hh;
}
u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr)
uint32_t vtoc_get_cyl_from_cchh(cchh_t *addr)
{
u_int32_t cyl;
uint32_t cyl;
/*decode cylinder for large volumes */
cyl = addr->hh & 0xFFF0;
@@ -230,7 +232,7 @@ u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr)
return cyl;
}
u_int16_t vtoc_get_head_from_cchh(cchh_t *addr)
uint16_t vtoc_get_head_from_cchh(cchh_t *addr)
{
/* decode heads for large volumes */
return addr->hh & 0x000F;
@@ -239,7 +241,7 @@ u_int16_t vtoc_get_head_from_cchh(cchh_t *addr)
/*
*
*/
static void vtoc_set_ttr (ttr_t *addr, u_int16_t tt, u_int8_t r)
static void vtoc_set_ttr (ttr_t *addr, uint16_t tt, uint8_t r)
{
addr->tt = tt;
addr->r = r;
@@ -249,18 +251,18 @@ static void vtoc_set_ttr (ttr_t *addr, u_int16_t tt, u_int8_t r)
/*
*
*/
void vtoc_set_cchhb (cchhb_t *addr, u_int32_t cc, u_int16_t hh, u_int8_t b)
void vtoc_set_cchhb (cchhb_t *addr, uint32_t cc, uint16_t hh, uint8_t b)
{
addr->cc = (u_int16_t) cc;
addr->cc = (uint16_t) cc;
addr->hh = cc >> 16;
addr->hh <<= 4;
addr->hh |= hh;
addr->b = b;
}
u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr)
uint32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr)
{
u_int32_t cyl;
uint32_t cyl;
/* decode cylinder for large volumes */
cyl = addr->hh & 0xFFF0;
@@ -269,7 +271,7 @@ u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr)
return cyl;
}
u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr)
uint16_t vtoc_get_head_from_cchhb(cchhb_t *addr)
{
/* decode heads for large volumes */
return addr->hh & 0x000F;
@@ -281,22 +283,22 @@ u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr)
* Note: Record zero is special, so first block on a track is
* in record 1!
*/
u_int64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo)
uint64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo)
{
return (u_int64_t) vtoc_get_cyl_from_cchhb(p) *
return (uint64_t) vtoc_get_cyl_from_cchhb(p) *
geo->heads * geo->sectors +
vtoc_get_head_from_cchhb(p) * geo->sectors +
p->b;
}
u_int64_t cchh2blk (cchh_t *p, struct hd_geometry *geo) {
uint64_t cchh2blk (cchh_t *p, struct hd_geometry *geo) {
return (u_int64_t) vtoc_get_cyl_from_cchh(p) *
return (uint64_t) vtoc_get_cyl_from_cchh(p) *
geo->heads * geo->sectors +
vtoc_get_head_from_cchh(p) * geo->sectors;
}
u_int32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
uint32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
return vtoc_get_cyl_from_cchh(p) * geo->heads +
vtoc_get_head_from_cchh(p);
@@ -305,7 +307,7 @@ u_int32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
/*
*
*/
void vtoc_set_date (labeldate_t * d, u_int8_t year, u_int16_t day)
void vtoc_set_date (labeldate_t * d, uint8_t year, uint16_t day)
{
d->year = year;
d->day = day;
@@ -318,7 +320,7 @@ void vtoc_set_date (labeldate_t * d, u_int8_t year, u_int16_t day)
void vtoc_volume_label_init (volume_label_t *vlabel)
{
sprintf(buffer, "%84s", " ");
vtoc_ebcdic_enc(buffer, buffer, 84);
vtoc_ebcdic_enc(buffer, buffer, 84);
memcpy(vlabel, buffer, 84);
}
@@ -327,7 +329,7 @@ void vtoc_volume_label_init (volume_label_t *vlabel)
* reads the volume label from dasd
*/
int vtoc_read_volume_label (char *device, unsigned long vlabel_start,
volume_label_t *vlabel)
volume_label_t *vlabel)
{
int f, rc;
@@ -358,7 +360,7 @@ int vtoc_read_volume_label (char *device, unsigned long vlabel_start,
* writes the volume label to dasd
*/
int vtoc_write_volume_label (char *device, unsigned long vlabel_start,
volume_label_t *vlabel)
volume_label_t *vlabel)
{
int rc, f;
@@ -373,8 +375,8 @@ int vtoc_write_volume_label (char *device, unsigned long vlabel_start,
"Could not write volume label.");
}
rc = write(f, vlabel, sizeof(volume_label_t));
if (rc != sizeof(volume_label_t))
rc = write(f, vlabel, sizeof(volume_label_t));
if (rc != sizeof(volume_label_t))
{
close(f);
vtoc_error(unable_to_write, device,
@@ -416,7 +418,7 @@ void vtoc_volume_label_set_volser (volume_label_t *vlabel, char *volser)
/*
* returns the volume serial number right after it is translated
* returns the volume serial number right after it is translated
* to ASCII
*/
char * vtoc_volume_label_get_volser (volume_label_t *vlabel, char *volser)
@@ -434,11 +436,11 @@ char * vtoc_volume_label_get_volser (volume_label_t *vlabel, char *volser)
void vtoc_volume_label_set_key (volume_label_t *vlabel, char *key)
{
char s[4];
vtoc_ebcdic_enc(key, s, 4);
strncpy(vlabel->volkey, s, 4);
return;
}
}
/*
@@ -473,12 +475,12 @@ char * vtoc_volume_label_get_label (volume_label_t *vlabel, char *lbl)
*/
void vtoc_read_label (char *device, unsigned long position,
format1_label_t *f1, format4_label_t *f4,
format5_label_t *f5, format7_label_t *f7)
{
format5_label_t *f5, format7_label_t *f7)
{
int f,t;
if ((f = open(device, O_RDONLY)) < 0)
vtoc_error(unable_to_open, device,
vtoc_error(unable_to_open, device,
"Could not read VTOC labels.");
if (lseek(f, position, SEEK_SET) < 0) {
@@ -534,7 +536,7 @@ void vtoc_read_label (char *device, unsigned long position,
void
vtoc_write_label (char *device,
unsigned long position,
format1_label_t *f1,
format1_label_t *f1,
format4_label_t *f4,
format5_label_t *f5,
format7_label_t *f7,
@@ -548,7 +550,7 @@ vtoc_write_label (char *device,
"Could not write VTOC labels.");
}
if (lseek(f, position, SEEK_SET) == -1)
if (lseek(f, position, SEEK_SET) == -1)
{
close(f);
vtoc_error(unable_to_seek, device,
@@ -558,7 +560,7 @@ vtoc_write_label (char *device,
if (f1 != NULL)
{
t = sizeof(format1_label_t);
if (write(f, f1, t) != t)
if (write(f, f1, t) != t)
{
close(f);
vtoc_error(unable_to_write, device,
@@ -569,7 +571,7 @@ vtoc_write_label (char *device,
if (f4 != NULL)
{
t = sizeof(format4_label_t);
if (write(f, f4, t) != t)
if (write(f, f4, t) != t)
{
close(f);
vtoc_error(unable_to_write, device,
@@ -580,7 +582,7 @@ vtoc_write_label (char *device,
if (f5 != NULL)
{
t = sizeof(format5_label_t);
if (write(f, f5, t) != t)
if (write(f, f5, t) != t)
{
close(f);
vtoc_error(unable_to_write, device,
@@ -591,7 +593,7 @@ vtoc_write_label (char *device,
if (f7 != NULL)
{
t = sizeof(format7_label_t);
if (write(f, f7, t) != t)
if (write(f, f7, t) != t)
{
close(f);
vtoc_error(unable_to_write, device,
@@ -617,7 +619,7 @@ vtoc_write_label (char *device,
/*
* initializes a format4 label
*/
void
void
vtoc_init_format4_label (
format4_label_t *f4,
unsigned int compat_cylinders,
@@ -625,7 +627,7 @@ vtoc_init_format4_label (
unsigned int tracks,
unsigned int blocks,
unsigned int blksize,
u_int16_t dev_type)
uint16_t dev_type)
{
int i;
@@ -674,24 +676,24 @@ vtoc_init_format4_label (
f4->DS4DEVCT.DS4DEVDB = 0x00;
/* -- end f4->DS4DEVCT -- */
bzero(f4->DS4AMTIM, sizeof(f4->DS4AMTIM));
bzero(f4->DS4AMCAT, sizeof(f4->DS4AMCAT));
bzero(f4->DS4R2TIM, sizeof(f4->DS4R2TIM));
bzero(f4->res1, sizeof(f4->res1));
bzero(f4->DS4F6PTR, sizeof(f4->DS4F6PTR));
memset(f4->DS4AMTIM, 0, sizeof(f4->DS4AMTIM));
memset(f4->DS4AMCAT, 0, sizeof(f4->DS4AMCAT));
memset(f4->DS4R2TIM, 0, sizeof(f4->DS4R2TIM));
memset(f4->res1, 0, sizeof(f4->res1));
memset(f4->DS4F6PTR, 0, sizeof(f4->DS4F6PTR));
/* -- begin f4lbl->DS4VTOCE -- */
vtoc_set_extent(&f4->DS4VTOCE, 0x01, 0x00, &lower, &upper);
/* -- end f4lbl->DS4VTOCE -- */
bzero(f4->res2, sizeof(f4->res2));
memset(f4->res2, 0, sizeof(f4->res2));
f4->DS4EFLVL = 0x00;
bzero(&f4->DS4EFPTR, sizeof(f4->DS4EFPTR));
bzero(&f4->res3, sizeof(f4->res3));
memset(&f4->DS4EFPTR, 0, sizeof(f4->DS4EFPTR));
memset(&f4->res3, 0, sizeof(f4->res3));
f4->DS4DCYL = real_cylinders;
bzero(f4->res4, sizeof(f4->res4));
memset(f4->res4, 0, sizeof(f4->res4));
f4->DS4DEVF2 = 0x40; /* allow format 8 and 9 labels */
bzero(&f4->res5, sizeof(f4->res5));
memset(&f4->res5, 0, sizeof(f4->res5));
}
@@ -699,11 +701,11 @@ vtoc_init_format4_label (
* initializes a format5 label
*/
void
vtoc_init_format5_label (format5_label_t *f5)
vtoc_init_format5_label (format5_label_t *f5)
{
int i;
bzero(f5, sizeof(format5_label_t));
memset(f5, 0, sizeof(format5_label_t));
for (i=0; i<4; i++) f5->DS5KEYID[i] = 0x05;
f5->DS5FMTID = 0xf5;
}
@@ -713,11 +715,11 @@ vtoc_init_format5_label (format5_label_t *f5)
* initializes a format7 label
*/
void
vtoc_init_format7_label (format7_label_t *f7)
vtoc_init_format7_label (format7_label_t *f7)
{
int i;
bzero(f7, sizeof(format7_label_t));
memset(f7, 0, sizeof(format7_label_t));
for (i=0; i<4; i++) f7->DS7KEYID[i] = 0x07;
f7->DS7FMTID = 0xf7;
}
@@ -740,7 +742,7 @@ static void vtoc_init_format_1_8_label (
t = time(NULL);
creatime = gmtime(&t);
bzero(f1->DS1DSNAM, sizeof(f1->DS1DSNAM));
memset(f1->DS1DSNAM, 0, sizeof(f1->DS1DSNAM));
sprintf(str, "PART .NEW ");
vtoc_ebcdic_enc(str, str, 44);
memcpy(f1->DS1DSNAM, str, 44);
@@ -748,8 +750,8 @@ static void vtoc_init_format_1_8_label (
f1->DS1VOLSQ = 0x0001;
vtoc_set_date(&f1->DS1CREDT,
(u_int8_t) creatime->tm_year,
(u_int16_t) creatime->tm_yday);
(uint8_t) creatime->tm_year,
(uint16_t) creatime->tm_yday);
/* expires never - 99 365 */
vtoc_set_date(&f1->DS1EXPDT,
0x63,
@@ -760,8 +762,8 @@ static void vtoc_init_format_1_8_label (
vtoc_ebcdic_enc("IBM LINUX ", str, 13);
memcpy((char *)f1->DS1SYSCD, str, 13);
vtoc_set_date(&f1->DS1REFD,
(u_int8_t) creatime->tm_year,
(u_int16_t) creatime->tm_yday);
(uint8_t) creatime->tm_year,
(uint16_t) creatime->tm_yday);
f1->DS1SMSFG = 0x00;
f1->DS1SCXTF = 0x00;
f1->DS1SCXTV = 0x0000;
@@ -775,17 +777,17 @@ static void vtoc_init_format_1_8_label (
f1->DS1RKP = 0x0000;
f1->DS1DSIND = 0x80; /* last volume for this dataset */
f1->DS1SCAL1 = 0x80;
bzero(&f1->DS1SCAL3, sizeof(f1->DS1SCAL3));
memset(&f1->DS1SCAL3, 0, sizeof(f1->DS1SCAL3));
vtoc_set_ttr(&f1->DS1LSTAR,
0x0000,
0x00);
f1->DS1TRBAL = 0x00;
bzero(&f1->res1, sizeof(f1->res1));
memset(&f1->res1, 0, sizeof(f1->res1));
memcpy(&f1->DS1EXT1,
part_extent,
sizeof(extent_t));
bzero(&f1->DS1EXT2, sizeof(extent_t));
bzero(&f1->DS1EXT3, sizeof(extent_t));
memset(&f1->DS1EXT2, 0, sizeof(extent_t));
memset(&f1->DS1EXT3, 0, sizeof(extent_t));
vtoc_set_cchhb(&f1->DS1PTRDS,
0x0000, 0x0000, 0x00);
}
@@ -827,11 +829,11 @@ void vtoc_init_format9_label (
/*
* do some updates to the VTOC format4 label
*/
void
void
vtoc_update_format4_label (
format4_label_t *f4,
cchhb_t *highest_f1,
u_int16_t unused_update)
uint16_t unused_update)
{
/* update highest address of a format 1 label */
memcpy(&f4->DS4HPCHR, highest_f1, sizeof(cchhb_t));
@@ -845,15 +847,15 @@ vtoc_update_format4_label (
* reorganizes all extents within a FMT5 label
*/
static void
vtoc_reorganize_FMT5_extents (format5_label_t *f5)
vtoc_reorganize_FMT5_extents (format5_label_t *f5)
{
ds5ext_t *ext, *last, tmp;
int i, j;
for (i=0; i<26; i++)
{
if (i==0)
last = &f5->DS5AVEXT;
if (i==0)
last = &f5->DS5AVEXT;
else if ((i > 0) && (i < 8))
last = &f5->DS5EXTAV[i-1];
else
@@ -861,14 +863,14 @@ vtoc_reorganize_FMT5_extents (format5_label_t *f5)
for (j=i; j<26; j++)
{
if (j==0)
ext = &f5->DS5AVEXT;
if (j==0)
ext = &f5->DS5AVEXT;
else if ((j > 0) && (j < 8))
ext = &f5->DS5EXTAV[j-1];
else
ext = &f5->DS5MAVET[j-8];
if (((ext->t > 0) && (last->t == 0)) ||
if (((ext->t > 0) && (last->t == 0)) ||
((ext->t > 0) && (ext->t < last->t)))
{
tmp.t = last->t;
@@ -889,27 +891,27 @@ vtoc_reorganize_FMT5_extents (format5_label_t *f5)
/*
* add a free space extent description to the VTOC FMT5 DSCB
*/
void
void
vtoc_update_format5_label_add (format5_label_t *f5,
int verbose,
int trk,
u_int16_t a,
u_int16_t b,
u_int8_t c)
uint16_t a,
uint16_t b,
uint8_t c)
{
ds5ext_t *ext = NULL, *tmp = NULL;
int i;
int i;
for (i=0; i<26; i++)
{
if (i==0)
ext = &f5->DS5AVEXT;
if (i==0)
ext = &f5->DS5AVEXT;
else if ((i > 0) && (i < 8))
ext = &f5->DS5EXTAV[i-1];
else
ext = &f5->DS5MAVET[i-8];
if (((a < ext->t) && (a + b*trk + c > ext->t)) ||
if (((a < ext->t) && (a + b*trk + c > ext->t)) ||
((a > ext->t) && (ext->t + ext->fc*trk + ext->ft > a)))
{
printf("BUG: overlapping free space extents " \
@@ -923,7 +925,7 @@ vtoc_update_format5_label_add (format5_label_t *f5,
ext->fc = b;
ext->ft = c;
tmp = ext;
if (verbose)
if (verbose)
printf("FMT5 add extent: " \
"add new extent\n");
break;
@@ -954,14 +956,14 @@ vtoc_update_format5_label_add (format5_label_t *f5,
/* this extent precedes the new one */
ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
ext->ft = (tmp->ft + ext->ft) % trk;
bzero(tmp, sizeof(ds5ext_t));
memset(tmp, 0, sizeof(ds5ext_t));
tmp = ext;
if (verbose)
if (verbose)
printf("FMT5 add extent: " \
"merge with predecessor\n");
i = -1;
continue;
}
}
if ((tmp->t + tmp->fc*trk + tmp->ft) == ext->t)
{
@@ -969,14 +971,14 @@ vtoc_update_format5_label_add (format5_label_t *f5,
ext->t = tmp->t;
ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
ext->ft = (tmp->ft + ext->ft) % trk;
bzero(tmp, sizeof(ds5ext_t));
memset(tmp, 0, sizeof(ds5ext_t));
tmp = ext;
if (verbose)
if (verbose)
printf("FMT5 add extent: " \
"merge with successor\n");
i = -1;
continue;
}
}
}
}
@@ -984,21 +986,21 @@ vtoc_update_format5_label_add (format5_label_t *f5,
/*
* remove a free space extent description from the VTOC FMT5 DSCB
*/
void
void
vtoc_update_format5_label_del (format5_label_t *f5,
int verbose,
int trk,
u_int16_t a,
u_int16_t b,
u_int8_t c)
uint16_t a,
uint16_t b,
uint8_t c)
{
ds5ext_t *ext;
int i, counter=0;
for (i=0; i<26; i++)
{
if (i==0)
ext = &f5->DS5AVEXT;
if (i==0)
ext = &f5->DS5AVEXT;
else if ((i > 0) && (i < 8))
ext = &f5->DS5EXTAV[i-1];
else
@@ -1007,8 +1009,8 @@ vtoc_update_format5_label_del (format5_label_t *f5,
if ((a == ext->t) && (b == ext->fc) && (c == ext->ft))
{
/* fills up whole free space gap */
bzero(ext, sizeof(ds5ext_t));
if (verbose)
memset(ext, 0, sizeof(ds5ext_t));
if (verbose)
printf("FMT5 del extent: fills whole gap\n");
counter++;
break;
@@ -1028,13 +1030,13 @@ vtoc_update_format5_label_del (format5_label_t *f5,
ext->fc -= b;
ext->ft -= c;
}
if (verbose)
if (verbose)
printf("FMT5 del extent: left bounded\n");
counter++;
break;
}
if ((ext->t < a) &&
if ((ext->t < a) &&
((ext->t + ext->fc*trk + ext->ft) == (a + b*trk + c)))
{
/* right-bounded in free space gap */
@@ -1048,7 +1050,7 @@ vtoc_update_format5_label_del (format5_label_t *f5,
ext->fc -= b;
ext->ft -= c;
}
if (verbose)
if (verbose)
printf("FMT5 del extent: right bounded\n");
counter++;
break;
@@ -1057,10 +1059,10 @@ vtoc_update_format5_label_del (format5_label_t *f5,
if ((a > ext->t) &&
((ext->t + ext->fc*trk + ext->ft) > (a + b*trk + c)))
{
/* partition devides free space into 2 pieces */
u_int16_t x = a + b*trk + c;
u_int16_t w,y;
u_int8_t z;
/* partition divides free space into 2 pieces */
uint16_t x = a + b*trk + c;
uint16_t w,y;
uint8_t z;
w = (ext->t + ext->fc*trk + ext->ft) - (a + b*trk + c);
y = w / trk;
@@ -1072,7 +1074,7 @@ vtoc_update_format5_label_del (format5_label_t *f5,
vtoc_update_format5_label_add(f5, verbose,
trk, x, y, z);
if (verbose)
if (verbose)
printf("FMT5 del extent: 2 pieces\n");
counter++;
break;
@@ -1086,8 +1088,8 @@ vtoc_update_format5_label_del (format5_label_t *f5,
"in FMT5 DSCB!\nexiting...\n");
exit(1);
}
if ((a > ext->t) && (a < ext->t + ext->fc*trk + ext->ft) &&
if ((a > ext->t) && (a < ext->t + ext->fc*trk + ext->ft) &&
(a + b*trk + c > ext->t + ext->fc*trk + ext->ft))
{
printf("BUG: specified free space extent for " \
@@ -1111,26 +1113,26 @@ vtoc_update_format5_label_del (format5_label_t *f5,
* reorganizes all extents within a FMT7 label
*/
static void
vtoc_reorganize_FMT7_extents (format7_label_t *f7)
vtoc_reorganize_FMT7_extents (format7_label_t *f7)
{
ds7ext_t *ext, *last, tmp;
int i, j;
for (i=0; i<16; i++)
{
if (i<5)
last = &f7->DS7EXTNT[i];
else
if (i<5)
last = &f7->DS7EXTNT[i];
else
last = &f7->DS7ADEXT[i-5];
for (j=i; j<16; j++)
{
if (j<5)
ext = &f7->DS7EXTNT[j];
else
if (j<5)
ext = &f7->DS7EXTNT[j];
else
ext = &f7->DS7ADEXT[j-5];
if (((ext->a > 0) && (last->a == 0)) ||
if (((ext->a > 0) && (last->a == 0)) ||
((ext->a > 0) && (ext->a < last->a)))
{
tmp.a = last->a;
@@ -1148,19 +1150,19 @@ vtoc_reorganize_FMT7_extents (format7_label_t *f7)
/*
* add a free space extent description to the VTOC FMT7 DSCB
*/
void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
u_int32_t a, u_int32_t b)
void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
uint32_t a, uint32_t b)
{
ds7ext_t *ext = NULL, *tmp = NULL;
int i;
int i;
for (i=0; i<16; i++) {
if (i<5)
ext = &f7->DS7EXTNT[i];
else
if (i<5)
ext = &f7->DS7EXTNT[i];
else
ext = &f7->DS7ADEXT[i-5];
if (((a < ext->a) && (b > ext->a) && (b < ext->b)) ||
if (((a < ext->a) && (b > ext->a) && (b < ext->b)) ||
((a > ext->a) && (a < ext->b) && (b > ext->b))) {
printf("BUG: overlapping free space extents "
"in FMT7 DSCB!\nexiting...\n");
@@ -1171,7 +1173,7 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
ext->a = a;
ext->b = b;
tmp = ext;
if (verbose)
if (verbose)
printf("FMT7 add extent: add new extent\n");
break;
}
@@ -1183,9 +1185,9 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
}
for (i=0; i<16; i++) {
if (i<5)
ext = &f7->DS7EXTNT[i];
else
if (i<5)
ext = &f7->DS7EXTNT[i];
else
ext = &f7->DS7ADEXT[i-5];
if ((ext->a + ext->b) == 0x00000000)
@@ -1194,27 +1196,27 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
if ((ext->b) == tmp->a) {
/* this extent precedes the new one */
ext->b = tmp->b;
bzero(tmp, sizeof(ds7ext_t));
memset(tmp, 0, sizeof(ds7ext_t));
tmp = ext;
if (verbose)
if (verbose)
printf("FMT7 add extent: " \
"merge with predecessor\n");
i = -1;
continue;
}
}
if (ext->a == (tmp->b))
{
/* this extent succeeds the new one */
ext->a = tmp->a;
bzero(tmp, sizeof(ds7ext_t));
memset(tmp, 0, sizeof(ds7ext_t));
tmp = ext;
if (verbose)
if (verbose)
printf("FMT7 add extent: " \
"merge with successor\n");
i = -1;
continue;
}
}
}
}
@@ -1222,22 +1224,22 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
/*
* remove a free space extent description from the VTOC FMT7 DSCB
*/
void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
u_int32_t a, u_int32_t b)
void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
uint32_t a, uint32_t b)
{
ds7ext_t *ext;
int i, counter=0;
for (i=0; i<16; i++) {
if (i<5)
ext = &f7->DS7EXTNT[i];
else
if (i<5)
ext = &f7->DS7EXTNT[i];
else
ext = &f7->DS7ADEXT[i-5];
if ((a == ext->a) && (b == ext->b)) {
/* fills up whole free space gap */
bzero(ext, sizeof(ds7ext_t));
if (verbose)
memset(ext, 0, sizeof(ds7ext_t));
if (verbose)
printf("FMT7 del extent: fills whole gap\n");
counter++;
break;
@@ -1246,7 +1248,7 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
if ((a == ext->a) && (b < ext->b)) {
/* left-bounded in free space gap */
ext->a = b;
if (verbose)
if (verbose)
printf("FMT7 add extent: left-bounded\n");
counter++;
break;
@@ -1255,24 +1257,24 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
if ((a > ext->a) && (b == ext->b)) {
/* right-bounded in free space gap */
ext->b = a;
if (verbose)
if (verbose)
printf("FMT7 add extent: right-bounded\n");
counter++;
break;
}
if ((a > ext->a) && (b < ext->b)) {
/* partition devides free space into 2 pieces */
vtoc_update_format7_label_add(f7, verbose,
/* partition divides free space into 2 pieces */
vtoc_update_format7_label_add(f7, verbose,
b, ext->b);
ext->b = a;
if (verbose)
if (verbose)
printf("FMT7 add extent: 2 pieces\n");
counter++;
break;
}
if (((a < ext->a) && (b > ext->a)) ||
if (((a < ext->a) && (b > ext->a)) ||
((a < ext->b) && (b > ext->b))) {
printf("BUG: specified free space extent for deleting "
"doesn't match free space currently shown in "
@@ -1294,7 +1296,7 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
*/
void vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
format7_label_t *f7, char ch, int verbose,
u_int32_t start, u_int32_t stop, u_int32_t cyl, u_int32_t trk)
uint32_t start, uint32_t stop, uint32_t cyl, uint32_t trk)
{
if ((cyl * trk) > BIG_DISK_SIZE) {
if (ch == '+') {
@@ -1317,12 +1319,12 @@ void vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
f4->DS4EFLVL = 0x07;
vtoc_set_cchhb(&f4->DS4EFPTR, 0x0000, 0x0001, 0x03);
} else {
u_int16_t x,y;
u_int8_t z;
uint16_t x,y;
uint8_t z;
x = (u_int16_t) start;
y = (u_int16_t) ((stop - start + 1) / trk);
z = (u_int8_t) ((stop - start + 1) % trk);
x = (uint16_t) start;
y = (uint16_t) ((stop - start + 1) / trk);
z = (uint8_t) ((stop - start + 1) % trk);
if (ch == '+') {
vtoc_update_format5_label_add(f5, verbose, trk,

View File

@@ -25,7 +25,7 @@
#include <sys/statvfs.h>
#include <sys/vfs.h>
#include <syslog.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <utmp.h>

View File

@@ -21,11 +21,12 @@
# Offsets
OFFS_INITRD_START_BYTES=66568
OFFS_INITRD_SIZE_BYTES=66576
OFFS_COMMANDLINE_MAX_SIZE_BYTES=66608
OFFS_COMMANDLINE_BYTES=66688
MAX_PARMFILE_SIZE=896
LEGACY_MAX_PARMFILE_SIZE=896
# Variables
cmd=$(basename $0)
cmd=$(basename -- "$0")
kernel=
ramdisk=
parmfile=
@@ -34,15 +35,14 @@ binval=
success=no
# Cleanup on exit
# shellcheck disable=SC2317
cleanup()
{
if [ -n "$binval" ]
then
rm -f $binval
if [ -n "$binval" ]; then
rm -f -- "$binval"
fi
if [ -n "$image" -a $success = no ]
then
rm $image
if [ -n "$image" ] && [ "$success" = no ]; then
rm -f -- "$image"
fi
}
trap cleanup EXIT
@@ -50,25 +50,25 @@ trap cleanup EXIT
# Usage
usage()
{
cat <<-EOF
Usage: $cmd KERNEL BOOT_IMAGE [-r RAMDISK] [-p PARMFILE]
cat <<- EOF
Usage: $cmd KERNEL BOOT_IMAGE [-r RAMDISK] [-p PARMFILE]
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
KVM firmware image using a stripped Linux kernel file KERNEL.
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
KVM firmware image using a stripped Linux kernel file KERNEL.
OPTIONS
-p Use PARMFILE with kernel parameters in the image
-r Include RAMDISK in the image
-h Print this help, then exit
-v Print version information, then exit
EOF
OPTIONS
-p Use PARMFILE with kernel parameters in the image
-r Include RAMDISK in the image
-h Print this help, then exit
-v Print version information, then exit
EOF
}
printversion()
{
cat <<-EOD
$cmd: version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2017
cat <<- EOD
$cmd: version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2017
EOD
}
@@ -78,12 +78,30 @@ dec2be64()
local num=$1
local b
local i
for i in $(seq 1 8)
do
b="\\x$(printf '%x' $(expr $num % 256))$b"
num=$(expr $num / 256) || true
for i in $(seq 1 8); do
b="\\x$(printf '%x' "$((num % 256))")$b"
num=$((num / 256)) || true
done
printf $b
printf '%b' "$b"
}
max_kernel_cmdline_size()
{
local __kernel=$1 size v
size_be="$(od -A n -j "${OFFS_COMMANDLINE_MAX_SIZE_BYTES}" -N 8 -t uL -- "$__kernel")"
# If little endian then swap bytes
if (("$(printf '\1' | od -dAn)" == 1)); then
v="$(printf '%016x0' "$size_be")"
size="0x${v:14:2}${v:12:2}${v:10:2}${v:8:2}${v:6:2}${v:4:2}${v:2:2}${v:0:2}"
else
size="$size_be"
fi
if ((size == 0)); then
size="${LEGACY_MAX_PARMFILE_SIZE}"
fi
# Use arithmetic expression to remove leading and trailing whitespace.
printf '%s' "$((size))"
}
# Do the image build
@@ -95,16 +113,17 @@ dobuild()
local ramdisk_offset
local parmfile_size
# check whether all specified files exist
for i in $kernel $ramdisk $parmfile
do
if [ ! -f $i ]
then
echo "$cmd: File $i not found" >&2
return 1
fi
for i in $kernel $ramdisk $parmfile; do
if [ ! -f "$i" ]; then
echo "$cmd: File $i not found" >&2
return 1
fi
if [ ! -r "$i" ]; then
echo "$cmd: File $i cannot be read, no read permission" >&2
return 1
fi
done
if ! file -b $(readlink -f $kernel) | grep "Linux S390" > /dev/null
then
if ! file -b -- "$(readlink -f -- "$kernel")" | grep "Linux S390" > /dev/null; then
echo "$cmd: Unrecognized file format for $kernel" >&2
return 1
fi
@@ -114,37 +133,36 @@ dobuild()
set -e
# copy over kernel padded with zeroes to page boundary
dd if=$kernel of=$image bs=4096 conv=sync status=none
dd if="$kernel" of="$image" bs=4096 conv=sync status=none
# append ramdisk if specified
if [ "$ramdisk" != "" ]
then
ramdisk_size=$(du -b -L $ramdisk | cut -f1)
kernel_size=$(du -b -L $kernel | cut -f1)
ramdisk_offset=$(du -b -L $image | cut -f1)
cat $ramdisk >> $image
if [ "$ramdisk" != "" ]; then
ramdisk_size=$(du -b -L -- "$ramdisk" | cut -f1)
# shellcheck disable=SC2034
kernel_size=$(du -b -L -- "$kernel" | cut -f1)
ramdisk_offset=$(du -b -L -- "$image" | cut -f1)
cat -- "$ramdisk" >> "$image"
binval=$(mktemp)
dec2be64 $ramdisk_offset > $binval
dd seek=$OFFS_INITRD_START_BYTES if=$binval of=$image bs=1 \
dec2be64 "$ramdisk_offset" > "$binval"
dd seek=$OFFS_INITRD_START_BYTES if="$binval" of="$image" bs=1 \
count=8 conv=notrunc status=none
dec2be64 $ramdisk_size > $binval
dd seek=$OFFS_INITRD_SIZE_BYTES if=$binval of=$image bs=1 \
dec2be64 "$ramdisk_size" > "$binval"
dd seek=$OFFS_INITRD_SIZE_BYTES if="$binval" of="$image" bs=1 \
count=8 conv=notrunc status=none
fi
# set cmdline
if [ "$parmfile" != "" ]
then
parmfile_size=$(du -b -L $parmfile | cut -f1)
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
then
if [ "$parmfile" != "" ]; then
max_parmfile_size=$(max_kernel_cmdline_size "$kernel")
parmfile_size=$(du -b -L -- "$parmfile" | cut -f1)
if ((parmfile_size <= max_parmfile_size)); then
# Clear any previous parameters
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count=$MAX_PARMFILE_SIZE \
if=/dev/zero of=$image conv=notrunc status=none
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
of=$image conv=notrunc status=none
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count="$max_parmfile_size" \
if=/dev/zero of="$image" conv=notrunc status=none
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count="$parmfile_size" \
if="$parmfile" of="$image" conv=notrunc status=none
else
echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $MAX_PARMFILE_SIZE" >&2
echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $max_parmfile_size bytes" >&2
return 1
fi
fi
@@ -154,25 +172,41 @@ dobuild()
}
# check args and build
args=$(getopt "r:p:hv" $*)
if [ $? = 0 ]
then
# shellcheck disable=SC2086,SC2048
if args=$(getopt "r:p:hv" $*); then
# shellcheck disable=SC2086
set -- $args
while [ $1 != "" ]
do
while [ "$1" != "" ]; do
case $1 in
-r) ramdisk=$2; shift 2;;
-p) parmfile=$2; shift 2;;
-h) usage; exit 0;;
-v) printversion; exit 0;;
--) shift; break;;
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
-r)
ramdisk=$2
shift 2
;;
-p)
parmfile=$2
shift 2
;;
-h)
usage
exit 0
;;
-v)
printversion
exit 0
;;
--)
shift
break
;;
*)
echo "$cmd: Unexpected argument $1, exiting..." >&2
exit 1
;;
esac
done
fi
if [ $# = 2 ]
then
if [ $# = 2 ]; then
kernel=$1
image=$2
dobuild

View File

@@ -42,17 +42,17 @@ install:
else
ifneq ($(shell sh -c 'command -v pkg-config'),)
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libnl-3.0)
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libnl-genl-3.0)
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libnl-route-3.0)
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libnl-3.0)
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libnl-genl-3.0)
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libnl-route-3.0)
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libcrypto)
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libnl-3.0)
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libnl-genl-3.0)
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libnl-route-3.0)
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libnl-3.0)
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libnl-genl-3.0)
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libnl-route-3.0)
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libcrypto)
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
else
LIB_CFLAGS += -I /usr/include/libnl3/
LIB_LFLAGS += -lnl-route-3 -lnl-genl-3 -lnl-3

View File

@@ -1,4 +1,3 @@
#include <execinfo.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <fcntl.h>

70
rust/Cargo.lock generated
View File

@@ -132,6 +132,15 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
dependencies = [
"num-traits",
]
[[package]]
name = "clap"
version = "4.5.23"
@@ -637,6 +646,7 @@ name = "pvimg"
version = "0.12.0"
dependencies = [
"anyhow",
"base64",
"clap",
"clap_complete",
"deku",
@@ -652,6 +662,20 @@ dependencies = [
"utils",
]
[[package]]
name = "pvinfo"
version = "0.12.0"
dependencies = [
"anyhow",
"clap",
"clap_complete",
"s390_pv_core",
"serde",
"serde_yaml",
"tempfile",
"utils",
]
[[package]]
name = "pvsecret"
version = "0.12.0"
@@ -665,6 +689,18 @@ dependencies = [
"utils",
]
[[package]]
name = "pvverify"
version = "0.12.0"
dependencies = [
"anyhow",
"clap",
"clap_complete",
"log",
"s390_pv",
"utils",
]
[[package]]
name = "quick-error"
version = "1.2.3"
@@ -870,18 +906,28 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.217"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.217"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
@@ -890,13 +936,15 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.99"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"ryu",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
@@ -1049,11 +1097,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
name = "utils"
version = "0.12.0"
dependencies = [
"chrono",
"clap",
"libc",
"log",
"s390_pv",
"serde",
"serde_json",
]
[[package]]
@@ -1205,3 +1255,9 @@ dependencies = [
"quote",
"syn",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

View File

@@ -6,7 +6,9 @@ members = [
"pvapconfig",
"pvattest",
"pvimg",
"pvinfo",
"pvsecret",
"pvverify",
"utils",
]
resolver = "2"

View File

@@ -25,12 +25,12 @@ endif #HOSTARCH
ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_LIBCURL},0)
PV_TARGETS := pvsecret pvattest pvimg
PV_TARGETS := pvsecret pvattest pvimg pvverify
ifeq ($(HOST_ARCH),s390x)
PV_TARGETS += pvapconfig
PV_TARGETS += pvapconfig pvinfo
else
BUILD_TARGETS += skip-pvapconfig
BUILD_TARGETS += skip-pvapconfig skip-pvinfo
endif #HOSTARCH
PV_BUILD_TARGETS := $(PV_TARGETS)
@@ -75,6 +75,9 @@ skip-build:
skip-pv-build:
echo " SKIP rust-pv-tools due to unresolved dependencies"
skip-pvinfo:
echo " SKIP pvinfo due to unsupported architecture (s390x only)"
skip-pvapconfig:
echo " SKIP pvapconfig due to unsupported architecture (s390x only)"
@@ -110,10 +113,9 @@ install-rust-tools: $(BUILD_TARGETS)
install-man:
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
$(foreach target,$(CARGO_TARGETS),\
$(INSTALL) -m 644 $(target)/man/*.1 -t $(DESTDIR)$(MANDIR)/man1;)
$(foreach target,$(PV_TARGETS),\
$(INSTALL) -m 644 $(target)/man/*.1 -t $(DESTDIR)$(MANDIR)/man1;)
$(foreach target,$(CARGO_TARGETS) $(PV_TARGETS),\
$(foreach man,$(wildcard $(target)/man/*.1), \
$(INSTALL) -m 644 $(man) -t $(DESTDIR)$(MANDIR)/man1;))
ln -sf pvimg-create.1 $(DESTDIR)$(MANDIR)/man1/genprotimg.1
install-shell-completions: install-bash-completion install-zsh-completion

Some files were not shown because too many files have changed in this diff Show More