Compare commits

...

183 Commits

Author SHA1 Message Date
Jan Höppner
77083b1cbb New release s390-tools-2.42.1
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-22 16:34:32 +02:00
Thomas Richter
21c2a04347 cpumf/pai: Remove unnecessary const parameter definition
With glibc 2.43 const-ness is preserved for standard library functions
and a compiler warning will be issued if this is violated.

pai parse_cpulist() receives user input via the parm function
parameter. The parameter is defined as 'const char *' and used as input
value for strchr(). The target pointer (cp) is defined as mutable
'char *' leading to violation of const correctness and this compiler
warning:

pai.c: In function ‘parse_cpulist’:
pai.c:907:20: warning: assignment discards ‘const’ qualifier from
			pointer target type [-Wdiscarded-qualifiers]
  907 |                 cp = strchr(parm, ':');

Since the user input is coming from optarg 'non-const char *', it is
unnecessary to have the function parameters carrying this data defined
as const.

Remove the unnecessary const definition in the function call chain to
fix the described issue.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Suggested-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Suggested-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-22 15:59:36 +02:00
Thomas Richter
8f2d77c9d3 cpumf/pai: Improve -m XXX argument verification
Speed up the check of the option -m argument and improve
the error message. The argument number must be a power of 2 number
and this check is improved.
Furthermore split the error message and provide one message for
invalid characters and one error message for the argument
not being a power of 2 number.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Suggested-by: Eduard Stefes <eddy@linux.ibm.com>
Suggested-by: Juergen Christ <jchrist@linux.ibm.com>
Tested-by: Jan Polensky <japo@linux.ibm.com>
Reviewed-by: Jan Polensky <japo@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-22 15:59:36 +02:00
Steffen Eiden
b6a4d7a6c1 pvsecret: Update man files
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-22 15:50:15 +02:00
Steffen Eiden
f223069f0b pvsecret: Fix argument parsing
The latest commit 'promote' a few optional arguments to required.
Fix this breaking behaviour by making them optional again.

Fixes: 080a6678fb ("pvsecret: Add -i -o option variants")
Reported-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Tested-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-22 15:50:15 +02:00
Steffen Eiden
19a5af8da9 rust/utils: Add functions to combine I/O arguments
Add functions to properly parse required and optional input/output
parameters that have to be combined into one.

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-05-22 15:49:45 +02:00
Steffen Eiden
03b73ab3f9 pvsecret: Update man and Readme
man and README got out of sync with --help over time.
Resync them.

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-05-21 13:20:06 +02:00
Steffen Eiden
080a6678fb pvsecret: Add -i -o option variants
All pvattest subcommands use the command line option -i <input> and -o
<output> to specify file input and output respectively. pvsecret however
uses mostly positional arguments for <input> and <output> exclusively,
e.g. pvattest check input.bin output.yaml

$ pvsecret add secret.bin

This provides an inconsistent user interface within the Secure
Execution tools and may confuse users.

Add the -i and -o option to the subcommands if applicable.
Input/output can then be specified like so:

$ pvsecret add -i secret.bin
$ pvsecret list -o list.yaml
$ pvsecret verify -i FILE -o out.yaml
$ pvsecret retrieve -i ID -o id.yaml

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-05-21 13:20:06 +02:00
Steffen Eiden
1d6f7d0bec pvattest: Update man and Readme
man and README got out of sync with --help over time.
Resync them.

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-05-21 13:20:06 +02:00
Steffen Eiden
a50d0485c9 pvattest: Add -i -o option variant for check
Most pvattest subcommands use the command line option -i <input> and -o
<output> to specify file input and output respectively. pvattest check
however only uses positional arguments for <input> and <output>, e.g.

$ pvattest check input.bin output.yaml

This provides an inconsistent user interface within the tool and may
confuse users.

Add the command -i and -o option to the check subcommand to bring it in
line with the rest of the tool.

$ pvattest check -i input.bin -o output.yaml

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-05-21 13:20:06 +02:00
Steffen Eiden
d2a6a771a5 pvattest: Show perform -i & -o option in help
Show -i & -o option and display them in the help output. Showing the
additional options to the user may provide a better experience. Users
may expect -i /-o options as other subcommands have them as well.

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-05-21 13:20:06 +02:00
Steffen Eiden
7568a0790f pv: Fix error description
The error texts printed a hardcoded .0 instead of the actual value.
Fix this by using the proper string format arguments.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Fixes: 61c5d7d431 ("rust/pv: Attestation generation and verification support")
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-21 13:20:06 +02:00
Finn Callies
ca0ee966b8 pvics: Add image prereqs in manpage
Specify the requirements for the base image in the pvics manpage.

Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-21 13:20:06 +02:00
Finn Callies
36a7b2e6eb pvebc: Minor bash improvements
Add minor improvements to the scripts the dracut module calls.

Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-21 13:20:06 +02:00
Finn Callies
851f63eb03 pvebc: Fix dependency for non EBC guests
For guests that do not make use of the EBC feature the boot should not
be impacted by this module. This requires removing the boot.mount unit
because it will unconditionally create a dependency on a unit that
conflicts with that idea. The downside is that mounting of the boot
partition has to be done manually.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/202
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-21 13:20:06 +02:00
Finn Callies
3d679f61fc pvebc: Disable unit logging to /boot
The boot partition is not designed for log files. Disable logging of the
EBC units to /boot/sics/log.

Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-21 13:20:06 +02:00
Finn Callies
9237c5b675 pvebc: Fix kernel module dependencies
Include the required kernel modules unconditionally when this module is
installed into an initramfs.
The new .conf file contains a list of kernel modules that are loaded by
the systemd-modules-load.service systemd unit.

Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-05-21 13:20:06 +02:00
Eduard Shishkin
d1ab6be082 zipl/src: Don't modify job->data.dump and job->data.mvdump sequentially
Set job->data.dump.no_compress (job->data.mvdump.force) only after
making sure that the job is 'dump' ('mvdump') respectively. Othrewise,
the second assignment can potentially corrupt the value that was set by
the first assignment.

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-05-21 13:20:06 +02:00
Jan Höppner
d6c2bac99f Prepare for next release
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 17:07:01 +02:00
Jan Höppner
997343f841 New release s390-tools-2.42.0
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 17:06:55 +02:00
Finn Callies
6a767408b3 ebc: Add new tool pvics
pvics (PV Image Customization Support) is a comprehensive tool for
converting existing qcow2 KVM guest images to IBM Secure Execution for
Linux (SEL) images with Early Boot Customization (EBC) support and
encrypted root filesystems.

The tool provides four main actions:
- list: Retrieve information about boot loader entries in a base image
- convert: Convert a base image to an EBC-ready SEL image
- encrypt: Encrypt the root filesystem and prepare EBC resources
- full: Perform both conversion and encryption in one operation

Assisted-by: IBM Bob:1.0.1
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 13:47:26 +02:00
Finn Callies
3aa5c38714 ebc: Add ibm-sel-ebc dracut module
Add 95ibm-sel-ebc dracut module for secure boot-time customization of
SEL guests.

Introduce the IBM SEL EBC dracut module (95ibm-sel-ebc) that enables
Early Boot Customization for SEL guests during the initramfs phase.

The module implements a critical security architecture to prevent
injection attacks: all EBC resources (.asr and .pol files) are copied from
/boot/sics (which resides in the qcow2 image on the host filesystem) to
/run/ibm-sel-ebc (a tmpfs/RAM-backed directory). Since guest RAM is
protected by the Ultravisor, this prevents malicious hosts from modifying
EBC resources during boot.

Systemd units and their purposes:
 - ibm-sel-ebc.target: Groups all EBC-related units
 - boot.mount: Mounts /dev/disk/by-label/boot to /boot
 - ibm-sel-ebc-ensure-sics.service: Fallback to create /boot/sics/ if boot
   partition mount fails (supports Kata VM scenarios)
 - ibm-sel-ebc-pvebc.service: Main unit that copies EBC resources to RAM,
   invokes pvebc tool to verify integrity and add ASRs to UV, retrieves
   LUKS passphrase from UV secret store
 - ibm-sel-ebc-override-crypttab.service: Replaces /etc/crypttab with
   prepared IBM SEL EBC crypttab, reloads systemd daemon, starts cryptsetup
   service
 - ibm-sel-ebc-paes-enforce.service: Verifies root filesystem uses PAES
   encryption to prevent root filesystem substitution attacks

All units write logs to /boot/sics/log for debugging, accessible even if
root filesystem fails to mount. Units are triggered by rd.ibm-sel-ebc
kernel parameter and only execute in initramfs
(ConditionPathExists=/etc/initrd-release).

Assisted-by: IBM Bob:1.0.1
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 13:46:31 +02:00
Finn Callies
c04a0919f6 rust: Add new tool pvebc
Add pvebc tool for parsing and verifying EBC Add-Secret-Request structures

Introduce pvebc, a CLI tool that parses and verifies the integrity of
Add-Secret-Request (ASR) structures used in Early Boot Customization for
SEL guests.

The tool processes an integrity-protected ASR structure consisting of:
 - toc.asr: Meta secret that links to toc.pol via relative filepath and
   SHA512 hash, integrity-protected by its AES GCM authentication tag
 - toc.pol: Policy file containing AES GCM authentication tags (last 16
   bytes) of all user-provided ASRs
 - User ASRs: Individual Add-Secret-Requests containing encrypted secrets

This structure guarantees:
 - Prevents ASR removal: toc.pol lists all expected ASR authentication tags
 - Prevents ASR insertion: Unlisted ASRs are rejected
 - Prevents ASR modification: AES GCM authentication tags provide
   cryptographic integrity
 - Prevents toc.pol tampering: toc.asr's integrity protection secures the
   link

The tool verifies completeness by checking that all ASRs listed in toc.pol
are present and their AES GCM authentication tags match. This prevents
attackers from removing, inserting, or modifying ASRs during transport over
unsecured channels.

After verification, pvebc adds all ASRs to the Ultravisor (UV), which
decrypts them using the guest's secret key and makes them available to
the guest during early boot.

Assisted-by: IBM Bob:1.0.1
Acked-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 13:46:31 +02:00
Finn Callies
c803cb925e rust: Add toc support for ebc to pvsecret
Add two new command-line options to pvsecret create for Early Boot
Customization (EBC) Table of Contents (TOC) support:

 1. --policy FILE
    Links an Add-Secret-Request (ASR) to a policy file by embedding a
    PolicyReference in the ASR's user data field. The PolicyReference
    contains the relative file path and SHA512 hash of the policy file,
    enabling integrity verification of the policy. This option conflicts
    with --user-data as both use the same user data field in the ASR
    structure.

 2. --toc-policy FILE
    Appends the AES-GCM authentication tag (MAC tag - last 16 bytes of
    the encrypted ASR) to the specified TOC policy file. This enables
    the TOC policy to maintain a list of all ASR MAC tags for
    completeness verification during boot. The TOC can verify that all
    expected ASRs are present and unmodified by checking their MAC tags
    against this list. This option also conflicts with --user-data.

Both options support the EBC multi-party workflow where an ISV/CSP builds
a generic SEL image and customers customize it with their own secrets. The
TOC mechanism ensures the integrity and completeness of all EBC resources
during the boot process.

Assisted-by: IBM Bob:1.0.1
Acked-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 13:46:31 +02:00
Finn Callies
1741ecff96 rust: Add EBC support to pv_core library
Add EBC (Early Boot Customization) utility functions to pv_core library
for parsing and verifying Add-Secret-Request structures.

Introduce the core library functionality needed for EBC:
- Add ebc_utils module to pv_core with ASR parsing and verification
- Export ebc_utils in pv_core lib.rs
- Re-export ebc_utils in pv lib.rs for downstream consumers
- Update pvsecret Cargo.toml dependencies

The library provides the foundation for tools that work with
integrity-protected ASR structures used in SEL guest customization.

Assisted-by: IBM Bob:1.0.1
Acked-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 13:46:31 +02:00
Finn Callies
20de1fce2a rust: Fix typo in pv
Change "Extracrted" to "Extracted".

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Finn Callies <fcallies@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 13:46:31 +02:00
Szabina Korbai
a5af5bcf70 zcrypt: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts
to chzcrypt, lszcrypt and zcryptstats.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:51:04 +02:00
Szabina Korbai
7730f2489f zipl-editenv: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:51:04 +02:00
Szabina Korbai
6dbc5646f9 lsscm: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:51:04 +02:00
Szabina Korbai
f70991ab1e lsqeth: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:51:04 +02:00
Szabina Korbai
e9ee658492 lscss: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.
Modify --devtype flag description to make it
compatible with zsh autocompletion.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:51:04 +02:00
Szabina Korbai
35d5f41232 chpstat: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:51:03 +02:00
Szabina Korbai
260a0a2428 chp: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts
to chchp and lschp.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:50:38 +02:00
Szabina Korbai
b444e71ee3 zmemtopo: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Tested-by: Mete Durlu <meted@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:50:10 +02:00
Szabina Korbai
31d576a595 zpwr: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:49:28 +02:00
Szabina Korbai
68309ccb7f zpcictl: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:49:26 +02:00
Szabina Korbai
755ea88d5d vmcp: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:49:03 +02:00
Szabina Korbai
af99efaab2 tunedasd: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:48:33 +02:00
Szabina Korbai
3b55ca085e opticsmon: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.
Modify --module-info flag description to make it
compatible with zsh autocompletion.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:48:33 +02:00
Szabina Korbai
9fdfd1a6dc lsstp: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:48:33 +02:00
Szabina Korbai
c459ec08c6 hsavmcore: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:48:33 +02:00
Szabina Korbai
eb63434f44 fdasd: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:48:30 +02:00
Szabina Korbai
0eae712cc2 dump2tar: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:47:35 +02:00
Szabina Korbai
e7e9f137c1 dasdview: Implement zsh and bash autocompletion
Add generation of shell autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:47:33 +02:00
Szabina Korbai
364cb9d869 dasdinfo: Implement zsh and bash autocompletion
Add generation of shell	autocompletion scripts.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:47:05 +02:00
Szabina Korbai
a64e9cab67 dasdfmt: Remove license boilerplate
Remove outdated license boilerplate from autocompletion
generator and cli header file. Fix SPDX-tag style.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Szabina Korbai
74cb6ee40e cpumf: Remove license boilerplate
Remove outdated license boilerplate from autocompletion
generator and cli header files. Fix SPDX-tag style.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Szabina Korbai
8c99c3878e libutil/util_autocomp_host: Remove license boilerplate
Remove outdated license boilerplate and fix
SPDX-tag style.

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
f302f5734b zpwr: Adapt to new JSON Lines text format
util_fmt now provides support for JSON Lines text format. Adapt certain
checks in the code and document the newly supported format in the man
page accordingly.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
3485192791 zmemtopo: Adapt to new JSON Lines text format
util_fmt now provides support for JSON Lines text format.
Document the newly supported format in the man page accordingly.

Reviewed-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
715da84030 lschp: Adapt to new JSON Lines text format
util_fmt now provides support for JSON Lines text format.
Document the newly supported format in the man page accordingly.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
6e53be736e chpstat: Adapt to new JSON Lines text format
util_fmt now provides support for JSON Lines text format. Adapt certain
checks in the code and document the newly supported format in the man
page accordingly.

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
88bf638487 cpumf: Adapt to new JSON Lines text format
util_fmt now provides support for JSON Lines text format. Adapt certain
checks in the code and document the newly supported format in the man
pages for lshwc and lspai accordingly.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
182892da12 hyptop: Adapt to new JSON Lines text format
util_fmt now provides support for JSON Lines text format. Adapt certain
checks in the code and document the newly supported format in the man
page accordingly.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
f9e07c3916 libutil/util_fmt: Introduce JSON Lines text format
JSON Lines text format (JSONL) [1] is a line-delimited JSON format where
objects are separated by the new line character (\n, LF) as opposed to
the JSON Sequence text format (json-seq) where JSON text is encapsulated
in an ASCII Record Separator (0x1E, RS) and ASCII Line Feed character
(0x0A, LF).

Whilst JSONL is also used for data streaming, this simpler format is
better suited for logging and works also well with traditional
line-oriented Unix tooling (e.g. grep or sed).

Add this format to util_fmt so that users have more choice and control
over formats that are required for their usecases.

Add helper functions that let the user determine whether a given format
type is JSON in general or a JSON streaming format (such as json-seq or
jsonl).

For better readability and more clarity use the helper function
util_fmt_is_json_stream() where the same decision is made for both
JSON streaming formats FMT_JSONSEQ and FMT_JSONL.

[1] https://jsonlines.org/

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Thomas Richter
3aaf3c067e cpumf/pai.c: Install SIGINT/SIGTERM handler for graceful termination
Sending signal SIGINT/SIGTERM to a running pai process causes immediate
termination of that running process. This usually interrupts a
select() system call waiting for more input to read from the installed
events and its mapped memory buffers. As there is no signal handler
installed, a SIGINT or SIGTERM signal simply terminates the process,
sometimes leaving incomplete recorded output file paicryto.XXX
(where XXX is the CPU number).
Install a signal handler to intercept signal SIGINT or SIGTERM and run
one more data collection loop to read out pending data and close all
recording output files properly.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Steffen Eiden
801e404160 pvimg: Fix hidden inferred bound
The associated type bound  for Iterator::Item was unsatisfied for Self.
Fix this by requiring Sized for IntoEnumIterator.

Fixes: 1d2a89b387 ("pvimg: Improve the readability of Display output for control flags")
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-04-30 08:44:02 +02:00
Steffen Eiden
280b8509d1 pvimg: Remove unnecessary references
Referencing here is superfluous and makes clippy sad.

Fixes: 87966251c4 ("pvimg: info: Improve JSON output")
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-04-30 08:44:02 +02:00
Steffen Eiden
0f56416d82 pvsecret: Improve UX on non-s390 systems
If pvsecret {add, list, retrieve} is executed with options on a non-s390
system the user gets misleading error messages as the options are not
defined.

> pvsecret add -i secret.bin
error: unexpected argument '-i' found

This may lead the user to think wrong arguments where chosen, which is
not entirely true as they are valid on s390. The more helpful error
message would be
error: Command only available on s390x

Which is already the case if no arguments are given.
Solve this by allowing non-s390 systems to parse the options:

> pvsecret add -i secret.bin
  error: Command only available on s390x

Reported-by: Carlo Della Giusta <carlo.dellagiusta@suse.com>
Fixes: dd82c26f87 ("rust: Add tool to manage UV-secrets")
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-04-30 08:44:02 +02:00
Steffen Eiden
c88e0276c1 pvattest: Improve UX on non-s390 systems
If pvattest perform is executed with options on a non-s390 system the
user gets misleading error messages as the options are not defined.

> pvattest perform -i attestation_request.bin  -o attresp.bin
  error: unexpected argument '-i' found

This may lead the user to think wrong arguments where chosen, which is
not entirely true as they are valid on s390. The more helpful error
message would be
error: Command only available on s390x

Which is already the case if no arguments are given.
Solve this by allowing non-s390 systems to parse the options:

> pvattest perform -i attestation_request.bin  -o attresp.bin
  error: Command only available on s390x

While at it ignore some unused code warnings in the exchange format code
that appear on non-s390 systems as not all code is used.

Reported-by: Carlo Della Giusta <carlo.dellagiusta@suse.com>
Fixes: 16610a211f ("rust: pvattest-Rust")
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-04-30 08:44:02 +02:00
Szabina Korbai
5b7f08624b libutil/util_autocomp_host: Fix script updating
Force the autocompletion script generator to always write to a new
empty file, thus preventing the potential corruption of script contents.

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: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jörn Siglen
b94d5e8f87 dbginfo.sh: Add command zmemtopo
Display CEC memory topology of allocated memory increments

Suggested-by: Mario Held <mario.held@de.ibm.com>
Suggested-by: Eberhard Pasch <epasch@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>
2026-04-30 08:44:02 +02:00
Jörn Siglen
a4f171d4ba dbginfo.sh: Update comments and copyright year
first change for 2026 and some clarification in comments

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>
2026-04-30 08:44:02 +02:00
Ingo Franzki
93f8d093ce libkmipclient: Adjustments for OpenSSL v4.0.0 API changes and deprecations
With OpenSSL 4.0.0 function SSL_set1_host() is deprecated and should be
replaced by SSL_set1_ipaddr() and SSL_set1_dnsname().

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Ingo Franzki
7e68d7f61a libseckey: Adjustments for OpenSSL v4.0.0 API changes and deprecations
With OpenSSL 4.0.0 function X509_NAME_get_entry() returns a const pointer.
Make the local variable also const to avoid compile warnings like:

  warning: assignment discards ‘const’ qualifier from pointer target type
  [-Wdiscarded-qualifiers]

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Ingo Franzki
7755d35995 libekmfweb: Adjustments for OpenSSL v4.0.0 API changes and deprecations
With OpenSSL 4.0.0 function X509_NAME_get_entry() returns a const pointer.
Make the local variable also const to avoid compile warnings like:

  warning: assignment discards ‘const’ qualifier from pointer target type
  [-Wdiscarded-qualifiers]

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Ingo Franzki
211431abc2 zkey: Adjustments for OpenSSL v4.0.0 API changes and deprecations
With OpenSSL 4.0.0 function X509_cmp_current_time() is deprecated and
should be replaced by X509_check_certificate_times().

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:02 +02:00
Jan Höppner
0ae29148f0 gitignore: Update gitignore
zdev usage files were converted from .c to .h files. Adapt the file
names in gitignore.

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:01 +02:00
Jan Polensky
43cf7873be zdev: generate usage text headers instead of C files
Generating and then including C source files from another C file can
lead to unexpected compilation errors in certain environments.

Switch the usage text generation from %_usage.c to %_usage.h. The
generated header provides the usage_text definition directly, and
chzdev.c and lszdev.c include the corresponding *_usage.h instead.

Update depfile prerequisites and the clean target to match the new
generated artifacts.

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-04-30 08:44:01 +02:00
Jan Polensky
d8cea21e1e zdev: Makefile: deduplicate *_usage.c generation
Consolidate the duplicated sed command sequences used to generate
*_usage.c files into a shared CSTR_SED definition and a single pattern
rule:

	%_usage.c: %_usage.txt

This removes the copy/pasted rules for chzdev_usage.c and lszdev_usage.c
and keeps the Makefile easier to maintain.

Also drop the explicit chzdev.o/lszdev.o prerequisites on the generated
sources as dependencies are already tracked via the .*.o.d depfiles.

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-04-30 08:44:01 +02:00
Jan Polensky
7093a70b51 dasdinfo: Drop obsolete kernel check and use errx() for arg errors
Remove the uname()/sscanf()-based kernel version gate (Linux < 2.6),
which is long obsolete and does not belong in user-space argument
validation.

While touching the code, replace the repeated warnx() + exit(1) pattern
with errx(EXIT_FAILURE, ...) in the option sanity checks to reduce
boilerplate and keep error paths consistent.

Behaviour is unchanged for supported environments; the version gate is
dropped because it is obsolete.

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-04-30 08:44:01 +02:00
Jan Polensky
06984cd9ee dasdinfo: Modernize NULL pointer checks
Replace explicit NULL comparisons with idiomatic C style:
- 'if (ptr == NULL)' -> 'if (!ptr)'
- 'if (ptr != NULL)' -> 'if (ptr)'

No functional changes.

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-04-30 08:44:01 +02:00
Jan Polensky
3a05ab769d dasdinfo: Apply code style improvements
- Use __packed instead of __attribute__ ((packed))
- Rename EBCtoASC to ebc_to_asc following naming conventions
- Consolidate multi-line error message into single line

No functional changes.

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-04-30 08:44:01 +02:00
Jan Polensky
bcbc69c77f zkey/kmip: Normalize encoding; remove non-UTF-8 artifact
Normalize the man page source to UTF-8/US-ASCII and remove a mojibake
artifact that could not be represented cleanly.

Documentation only, no functional changes.

Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:01 +02:00
Niklas Schnelle
b385b8cc38 opticsmon: Fix wrong reference to --daemon flag in man page
Even before release the flag was renamed to --monitor but the mention in
the man page was missed.

Reported-by: Halil Pasic <pasic@linux.ibm.com>
Fixes: c34adb9cab ("opticsmon: Introduce opticsmon tool")
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:01 +02:00
Jan Höppner
2b282bdacd libutil/util_autocomp: Remove comments describing resulting scripts
Future updates might change the outcome of the resulting scripts and the
comments describing the script output would need to be updated every
time as well. It's not worth the effort.

Remove the comments that list script examples from the functions
generate_bash_autocomp() and generate_zsh_autocomp().

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:01 +02:00
Jan Höppner
bd2610d275 libutil/util_autocomp: Fix default file completion
For Bash, when compspecs are found the generated script is returned as
the full set of possible completions and default completions are
disabled [1]. This leads to the behaviour that command line arguments
are not completed, only options defined by the script.

Zsh has the same issue.

Fix the issue by always adding the bash defaults to the generated
script. For zsh the corresponding file completion is always added to the
end of the argument list and the -A "*" option is added to allow
completion after positional arguments.

[1] https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html#Programmable-Completion-1

Fixes: 638cbbe332 ("libutil: Implement zsh and bash autocompletion")
Reported-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:01 +02:00
Jan Höppner
5cf2cefa94 libutil/util_autocomp: Fix ShellCheck findings and apply coding style
Apply coding style changes by reducing line breaks for a more compactly
generated script and add double quotes to fix ShellCheck findings.
Furthermore, remove the unused variable previous_word and use mapfile to
read the output of compgen into the COMPREPLY array to avoid unwanted
splitting and glob expansion.

Reviewed-by: Szabina Korbai <szkorbai@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-30 08:44:01 +02:00
Eduard Shishkin
984e008127 zipl/src: Indicate in a verbose output if a component is signed
Regardless of secure boot support, indicate in the verbose zipl(8)
output if a component is signed.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-10 11:22:10 +02:00
Eduard Shishkin
fcfee1aa84 zipl/src: Fix a bug in building replicated program tables
When installing IPL on mirrored targets, zipl builds multiple program
tables (one such table per each mirror). If the option "--add-files"
was specified, then zipl uses the in-bootmap files, that was written
at the prevoius iteration (for the mirror ID #0) to build program
tables for mirrors with ID #1 (and larger). The in-bootmap files
already don't contain trailers. Despite this, the building process
cuts off the tail of trailer size, which results in corrupted boot
data.

This bug may result in crashing the kernel when booting from mirrors
with ID #1 (and larger) and manifests only if the boot components are
signed and the option "--add-files" is specified for the installation
session.

Don't count the trailer, when building program tables using in-bootmap
files written at the previous iteration.

Fixes: 431e4542ca ("zipl/src: Reuse data of file components in bootmap")
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-10 11:22:10 +02:00
Chinmaya Kajagar
b401ad0da0 zfcpdbf: Print sysfs unit add store events
New trace tags "sysuas*" added in kernel to trace zfcp sysfs unit add
store events.

Print the trace events under HBA with new record ID 6. The fields under
this tag are WWPN, FCP LUN and return value of the device having issues.

Example zfcpdbf output for unit add store events:

Timestamp      : 2026-02-02-10:50:02:474983
Area           : HBA
Subarea        : 00
Level          : 4
Exception      : -
CPU ID         : 0003
Caller         : 0x000001d89a86bd0e
Record ID      : 6
Tag            : sysuas2
Description    : sysuas2 HBA, Sysfs unit add store failure, unit add failed
Request ID     : 0x00000000ffffffff
Request status : 0xffffffff
FSF cmnd       : 0xffffffff
FSF sequence no: 0xffffffff
WWPN           : 0x500507680b26c449
LUN            : 0x01d0000000000000
Return Value   : 0xfffffff4

Timestamp      : 2026-02-02-10:50:02:475037
Area           : HBA
Subarea        : 00
Level          : 4
Exception      : -
CPU ID         : 0003
Caller         : 0x000001d89a86bd0e
Record ID      : 6
Tag            : sysuas2
Description    : sysuas2 HBA, Sysfs unit add store failure, unit add failed
Request ID     : 0x00000000ffffffff
Request status : 0xffffffff
FSF cmnd       : 0xffffffff
FSF sequence no: 0xffffffff
WWPN           : 0x500507680b26c449
LUN            : 0x01d1000000000000
Return Value   : 0xfffffff4

Signed-off-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-10 11:21:23 +02:00
Vasily Gorbik
50f909db8f zipl/boot: Fix stage3 secure boot trailer placement
The stage3 linker script places .sb.trailer so that it must end at
COMMAND_LINE_EXTRA. The current script derives the start address from
SIZEOF(.sb.trailer) before the section is emitted:

  . = COMMAND_LINE_EXTRA - SIZEOF(.sb.trailer);

With binutils older than 2.39 before commit 648f6099d4dc ("-z relro
relaxation and ld script SIZEOF") this can result in .sb.trailer being
placed at COMMAND_LINE_EXTRA instead, moving the trailer into the
following area and breaking the expected layout.

The trailer has a fixed size, so use an explicit constant for the
placement calculation and keep the ASSERT to verify the final section
size. This makes the placement deterministic again.

Fixes: a1126352ec ("zipl/boot: Improve linker scripts")
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-04-10 11:21:23 +02:00
Harald Freudenberger
d0046257b6 lszcrypt/chzcrypt: Warn if default domain is unavailable
Improvements for lszcrypt and chzcrypt:
* lszcrypt -b and lszcrypt -d now check for default domain
  available and gives a warning if the current default domain
  is not in the usage_domain_mask of the AP bus.
* lszcrypt without any further device also checks for the
  default domain and emits a warning string if the default
  domain is not available.
* chzcrypt --default-domain emits a warning if the newly
  set default domain is not enabled in the usage_domain_mask
  of the AP bus.

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-03-11 11:25:25 +01:00
Ajaykumar Rajappa
daad3bf0e7 ziomon: Send MQ poll status messages to stdout
Move MQ poll status messages from stderr to stdout since they are
normal progress indications rather than warnings/errors.

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: M Nikhil <nikh1092@linux.ibm.com>
Reviewed-by: Nihar Panda <niharp@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:25:18 +01:00
Ajaykumar Rajappa
6537f711a6 ziomon: Ignore benign blkiomon early-read warnings
The blkiomon warnings "bad trace magic 0" and "blkiomon: bad trace" are
benign startup artifacts caused by early pipeline reads before blktrace
produces a complete record. These messages do not affect processing and
valid reports are still generated. Filter them out so only real errors
trigger failures.

Signed-off-by: Ajaykumar Rajappa <ajaykr@linux.ibm.com>
Reviewed-by: Nihar Panda <niharp@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:25:13 +01:00
Mete Durlu
7c75df9e96 hyptop/opts: Fix long command line option abbreviations
Hyptop should be able to accept abbreviations of the long command line
options as getopt() is able to match them. Ex;

$ hyptop --batch-mode

$ hyptop --batch

$ hyptop --bat

From getopt(3) man page:
"""
  Long option names may be abbreviated if the abbreviation is unique
  or is an exact match for some defined option.
"""

After the introduction of commit c5695e43c4 ("hyptop/opts: Replace long
option formats for consistency") long command line options for hyptop
received additional definitions to support dash separated option formats.
Unfortunately these definitions were defined as new and unique options
and caused an ambiguity for getopt() when abbreviations matched both
definitions. Ex;

$ hyptop --batch
hyptop: option '--batch' is ambiguous;
possibilities: '--batch-mode' '--batch_mode'

Map both long option formats to the same short option to fix the
issue and restore the functionality.

Fixes: c5695e43c4 ("hyptop/opts: Replace long option formats for consistency")
Reported-by: Gorkem Kilinc <kilinc@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:25:03 +01:00
Mete Durlu
376ddfbd22 hyptop/opts: Replace sort_field option with sort
Hyptop's "--sort_field" command line option has always been documented
as "--sort", while the code _only_ explicitly has "--sort_field".
Specifying the shorter "--sort" happened to work due to an unnoticed
getopt() behavior.

From getopt(3) man page:
"""
  Long option names may be abbreviated if the abbreviation is unique
  or is an exact match for some defined option.
"""

With the addition of "--sort-field" as another unique identifier via
commit c5695e43c4 ("hyptop/opts: Replace long option formats for
consistency") "--sort" is no longer unique. getopt() won't be able to
use that as an abbreviation, since there is ambiguity between
"--sort_field" and new "--sort-field" as they are defined as separate
options.

Replace "--sort-field" and "--sort_field" with plain "--sort" to adhere
to the documented hyptop command line argument specification and resolve
the broken behavior.

Fixes: c5695e43c4 ("hyptop/opts: Replace long option formats for consistency")
Reported-by: Gorkem Kilinc <kilinc@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:46 +01:00
Holger Dengler
1afa6efb26 lszcrypt: Change exit code to 0 for empty device list
An empty device list is not an error case, if `lszcrypt` is called
without a specific device list or device filter. Return with rc == 0 in
such cases.

Remove the message about the empty device list on stderr.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:42 +01:00
Jan Höppner
69c89416b0 lsznet: Remove support for lcs device type
Kernel support for LCS devices was removed with commit 6cccb3bb0561
("s390/net: Remove LCS driver") in kernel v6.15. Remove the associated
lsznet support for the lcs device type.

Reviewed-by: Aswin Karuvally <aswin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:38 +01:00
Jan Höppner
81e0d02d90 znetcontrolunits: Remove znetcontrolunits library
znetcontrolunits provided two arrays and a search function that were
only used by lsznet. Since lsznet has it's own implementation of this
function now and the CU array was a duplicate of CU_TCPIP anyway, remove
znetcontrolunits as it serves no purpose.

Reviewed-by: Aswin Karuvally <aswin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:36 +01:00
Jan Höppner
d41d968792 znet: Move functionality from znetcontrolunits to lsznet
lsznet sources znetcontrolunits to use search_cu() and set the variable
cu_idx. lsznet's own function search_cu_tcpip() is doing the same thing
as search_cu() without setting cu_idx.

Declare and move cu_idx to the global variable CU_IDX and consolidate
the functions by letting search_cu_tcpip() set CU_IDX. Call
search_cu_tcpip() instead of search_cu() and replace cu_idx with CU_IDX
accordingly. search_cu() is removed and the CU_DEVDRV array is moved to
lsznet.

Reviewed-by: Aswin Karuvally <aswin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:35 +01:00
Jan Höppner
c81ca8f01b lsznet: Convert space indentation to tabs
Reviewed-by: Aswin Karuvally <aswin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:33 +01:00
Mikhail Zaslonko
73ab25f419 zipl/boot: Add secure boot option to the dump programm
With SECURE_BOOT_DISABLED always set in add_dump_program() no signature
entries for a dump kernel are written. This might lead to security
violation error from the IPL Loader on the systems with secure boot support
on the attempt to boot the dump kernel:
  MLOLOA6269321F A security violation error was encountered when loading from device <device>
  MLOLOA62693212 Audit: No signed components found for program 0 loaded from device <device>

Propagate '--secure' zipl option to add_dump_program() in order to sign
relevant components upon dump program installation and thus support
secure boot execution for List-directed dump kernels.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:23 +01:00
Chinmaya Kajagar
6fc1ed1a67 zfcpdbf: Print plogi and prli within open port response as payload
Print plogi and prli of each incoming open port response. Additional
payload ‘fsf_els’ HBA area to trace and print the new open port response
details.

Relevant kernel dbf structure changes are done in a separate patch. New
fields plogi_len and prli_len (u32 i.e. 4 hex digits at new appended
offsets 112 and 120) and payload record(s) are available.
The kernel structure with added members,
struct zfcp_dbf_hba_res {
	u64                        req_issued;           /*     0     8 */
	u32                        prot_status;          /*     8     4 */
	u8                         prot_status_qual[16]; /*    12    16 */
	u32                        fsf_status;           /*    28     4 */
	u8                         fsf_status_qual[16];  /*    32    16 */
	u32                        port_handle;          /*    48     4 */
	u32                        lun_handle;           /*    52     4 */
	u32                        plogi_len;            /*    56     4 */
	u32                        prli_len;             /*    60     4 */
};

zfcpdbf partial output for HBA area with relevant kernel code changes
displaying PLOGI/ PRLI info log with length for each:

PLOGI length   : 116
PRLI length    : 20
Payload time   : 2026-01-29-06:19:15:626629
PLOGI/PRLIinfo : 02000000 00000000 80000800 000a0002
                 00000000 2002000e 1115c62f 2001000e
                 1115c62f 00000000 00000000 00000000
                 00000000 80000000 00000000 00000000
                 00000000 80000000 00000000 000a0000
                 00010000 00000000 00000000 00000000
                 00000000 00000000 00000000 00000000
                 00000000 02100014 08002100 00000000
                 00000000 00000112

Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
Signed-off-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:16 +01:00
Chinmaya Kajagar
1c3547d205 zfcpdbf: Trace all fsf status read buffer fields under HBA
This patch is to enhance fsf status read buffer tracing. Add remaining
status read buffer (SRB) fields including S_ID and reserved fields under
HBA trace area.

Relevant kernel dbf structure changes are done in a seperate patch.

zfcpdbf output for HBA area with relevant kernel code changes:

Timestamp      : 2025-08-22-05:52:04:171750
Area           : HBA
Subarea        : 00
Level          : 2
Exception      : -
CPU ID         : 0003
Caller         : 0x0000021e278c07c8
Record ID      : 2
Tag            : fssrh_4
Description    : fssrh_4 HBA, FSF unsolicited status
Request ID     : 0x0000000000004bfc
Request status : 0x00000000
FSF cmnd       : 0x00006305
FSF sequence no: 0x00000000
SRB stat type  : 0x00000002
SRB stat sub   : 0x00000000
SRB D_ID       : 0x00fffffd
SRB LUN        : 0x0000000000000000
SRB q-design.  : 0x0000000000000000
SRB length     : 0x0000004c
SRB res1       : 0x00000000
SRB res2       : 0x00
SRB class      : 0x00000000
SRB res3       : 0x00
SRB S_ID       : 0x0033c048
SRB res4       : 00000000 00000000 00000000 00000000
                 00000000
SRB pay length : 12
Payload time   : 2025-08-22-05:52:04:171743
SRB info       : 6104000c 0033c024 0033c02e

Signed-off-by: Chinmaya Kajagar <chinmayk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:11 +01:00
Vineeth Vijayan
b6bb87f377 zdev: Remove support for lcs device type
Kernel support for LCS devices was removed with commit 6cccb3bb0561
("s390/net: Remove LCS driver") in kernel v6.15. Remove the associated
zdev support for the lcs device type.

Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:07 +01:00
Jan Höppner
bd0bb9dd5c zipl/man: Remove trailing whitespace
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:05 +01:00
Jan Höppner
075f7f7186 zipl/man: Only mention 3490 tape devices
The Virtual Tape Server (VTS) only supports 3490 tape devices. Remove
all other older device types from the man pages.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:04 +01:00
Jan Höppner
5af1e8cc69 zipl/tape2dump: Remove check for data compaction support
Data compaction is only supported by 3490 tape devices. For Virtual Tape
Server (VTS) this is the only supported device. Reading device
characteristics and checking the type is unnecessary.

Remove the corresponding code and simply enable data compaction.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:02 +01:00
Jan Höppner
145c21a9ca zipl/tape2dump: Remove load display command
Load Display (LDD) X'9F' is still accepted by the Virtual Tape Server
(VTS) but does not perform any action. Remove code that still uses this
command in tape2dump.c.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:01 +01:00
Jan Höppner
1bd8ee4b79 lstape: Remove type filter support
There is only one supported tape device type left. A filter command line
option doesn't make any sense anymore.

Remove the functionality and documentation of the --type option.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:24:00 +01:00
Jan Höppner
4f0dfae97e lstape: Remove 3480 and 3590 tape support
The device models 3480 and 3590 are no longer supported by the tape
device driver. Remove them from the device list

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:23:58 +01:00
Jan Höppner
3d6bb988c2 lstape: Remove trailing whitespace
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:23:57 +01:00
Jan Höppner
8f83002e37 tape390: Remove tape390_display and tape390_crypt
The tape390_display tool was used to send text to the display of tape
storage server. The corresponding command is still accepted by the
Virtual Tape Server (VTS) but no action is performed. The tool is
useless, remove it.

The tape390_crypt tool was used to manage encryption for tape devices.
However, only 3590/3592 models did support encryption. Support for these
models is removed from the Kernel as there is no support for these tape
models in general anymore. The tool is not required anymore, remove it.

Note: VTS uses encryption transparantly for its virtualized 3490 models.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:23:55 +01:00
Mikhail Zaslonko
d92f419836 zdump/dfi: Fix dump header check for dfi_s390tape
The magic number used in the dump header for all stage2 dumps (including
tape dump) is DF_S390_MAGIC_EXT since commit ff475d9c7d0a ("zipl: Extend
DASD stand-alone dumpers to drop zero pages").
Adjust dfi_s390tape code accordingly.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-03-11 11:23:52 +01:00
Jan Höppner
8ff8b40182 Prepare for next release
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2026-02-16 15:34:05 +01:00
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
298 changed files with 12722 additions and 5476 deletions

52
.gitignore vendored
View File

@@ -25,7 +25,7 @@ compile_commands.json
#
**/.detect-openssl.dep.c
*.debug
*/autocompletion_generator_host
**/autocompletion_generator_host
ap_tools/ap-check
cmsfs-fuse/cmsfs-fuse
cpacfstats/cpacfstats
@@ -50,12 +50,22 @@ dasdfmt/dasdfmt
dasdfmt/_dasdfmt
dasdfmt/dasdfmt.bash
dasdinfo/dasdinfo
dasdinfo/_dasdinfo
dasdinfo/dasdinfo.bash
dasdview/dasdview
dasdview/_dasdview
dasdview/dasdview.bash
dump2tar/src/dump2tar
dump2tar/src/_dump2tar
dump2tar/src/dump2tar.bash
fdasd/fdasd
fdasd/_fdasd
fdasd/fdasd.bash
hmcdrvfs/hmcdrvfs
hsavmcore/check-dep-fuse
hsavmcore/hsavmcore
hsavmcore/_hsavmcore
hsavmcore/hsavmcore.bash
hyptop/hyptop
ip_watcher/xcec-bridge
ipl_tools/chreipl
@@ -88,34 +98,58 @@ libutil/*_example
libvmcp/vmcp_example
libzds/libzds.a
lsstp/lsstp
lsstp/_lsstp
lsstp/lsstp.bash
mon_tools/mon_fsstatd
mon_tools/mon_procd
opticsmon/opticsmon
opticsmon/_opticsmon
opticsmon/opticsmon.bash
osasnmpd/osasnmpd
qetharp/qetharp
qethqoat/qethqoat
systemd/cpacfstatsd.service
systemd/iucvtty-login@.service
systemd/ttyrun-getty@.service
tape390/tape390_crypt
tape390/tape390_display
tunedasd/src/tunedasd
tunedasd/src/_tunedasd
tunedasd/src/tunedasd.bash
vmcp/vmcp
vmcp/_vmcp
vmcp/vmcp.bash
vmur/vmur
zconf/chp/chchp
zconf/chp/_chchp
zconf/chp/chchp.bash
zconf/chp/lschp
zconf/chp/_lschp
zconf/chp/lschp.bash
zconf/chp/chpstat/chpstat
zconf/chp/chpstat/_chpstat
zconf/chp/chpstat/chpstat.bash
zconf/css/lscss
zconf/css/_lscss
zconf/css/lscss.bash
zconf/qeth/lsqeth
zconf/qeth/_lsqeth
zconf/qeth/lsqeth.bash
zconf/scm/lsscm
zconf/scm/_lsscm
zconf/scm/lsscm.bash
zconf/zcrypt/chzcrypt
zconf/zcrypt/_chzcrypt
zconf/zcrypt/chzcrypt.bash
zconf/zcrypt/lszcrypt
zconf/zcrypt/_lszcrypt
zconf/zcrypt/lszcrypt.bash
zconf/zcrypt/zcryptctl
zconf/zcrypt/zcryptstats
zconf/zcrypt/_zcryptstats
zconf/zcrypt/zcryptstats.bash
zdev/src/chzdev
zdev/src/chzdev_usage.c
zdev/src/chzdev_usage.h
zdev/src/lszdev
zdev/src/lszdev_usage.c
zdev/src/lszdev_usage.h
zdev/src/zdev_id
zdsfs/zdsfs
zdump/.check_dep_fuse
@@ -139,6 +173,8 @@ zipl/src/chreipl_helper.device-mapper
zipl/src/chreipl_helper.md
zipl/src/zipl
zipl/src/zipl-editenv
zipl/src/_zipl-editenv
zipl/src/zipl-editenv.bash
zipl/src/zipl_helper.device-mapper
zipl/src/zipl_helper.md
zkey/check-dep-zkey
@@ -151,5 +187,11 @@ zkey/kmip/zkey-kmip.so
zkey/zkey
zkey/zkey-cryptsetup
zmemtopo/zmemtopo
zmemtopo/_zmemtopo
zmemtopo/zmemtopo.bash
zpcictl/zpcictl
zpcictl/_zpcictl
zpcictl/zpcictl.bash
zpwr/zpwr
zpwr/_zpwr
zpwr/zpwr.bash

View File

@@ -10,12 +10,14 @@ List of all individuals having contributed content to s390-tools
- Annu Sharma
- Antoinette Kaschner
- Arnd Bergmann
- Aswin Karuvally
- Axel Wirbser
- Balint Reczey
- Benjamin Block
- Bjoern Walk
- Brian C. Lane
- Carsten Otte
- Chinmaya Kajagar
- Christian Borntraeger
- Christian Ehrhardt
- Christof Schmitt
@@ -25,6 +27,7 @@ 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
@@ -154,7 +157,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,82 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.42.1 (2026-05-22)__
For Linux kernel version: 7.0
Changes of existing tools:
- cpumf/pai: Improve -m XXX argument verification
- pvattest: Add -i -o option variant for check
- pvattest: Show perform -i & -o option in help
- pvebc: Disable unit logging to /boot
- pvsecret: Add -i -o option variants
Bug Fixes:
- cpumf/pai: Remove unnecessary const parameter definition
- pv: Fix error description
- pvebc: Fix dependency for non EBC guests
- pvebc: Fix kernel module dependencies
- zipl: Don't modify job->data.dump and job->data.mvdump sequentially
* __v2.42.0 (2026-04-30)__
For Linux kernel version: 7.0
Add new tools / libraries:
- Enable zsh and bash autocompletion for various tools
- pvebc: Resolve ASR integrity structure for EBC
- pvics: Generate SEL guests from base images
Remove:
- tape390_display and tape390_crypt removed due to long gone hardware support
- znetcontrolunits: Remove znetcontrolunits library
Changes of existing tools:
- cpumf/pai: Install SIGINT/SIGTERM handler for graceful termination
- dbginfo.sh: Add command zmemtopo
- libutil/util_fmt: Add support for JSON Lines text format
- lstape: Remove 3480 and 3590 tape support
- lsznet: Remove support for lcs device type
- pvsecret: Add support for ASR integrity structure for EBC
- zfcpdbf: Print plogi and prli within open port response as payload
- zfcpdbf: Trace all fsf status read buffer fields under HBA
- zipl/boot: Add secure boot option to the dump programm
- zkey, libekmfweb, libseckey, libkmipclient: Adjust for OpenSSL v4.0.0 API
changes and deprecations
Bug Fixes:
- hyptop/opts: Fix long command line option abbreviations
- libutil/util_autocomp: Fix default file completion
- zipl/boot: Fix stage3 secure boot trailer placement
* __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

View File

@@ -11,7 +11,7 @@ BASELIB_DIRS = libutil libseckey
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
libkmipclient libcpumf libap libpv libzpci
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \

View File

@@ -30,6 +30,8 @@ Package contents
Manage secrets for IBM Secure Execution guests
- pvimg:
Create and inspect IBM Secure Execution images
- pvebc:
Verify a secret structure for IBM Secure Execution for Linux.
* dasdfmt:
Low-level format ECKD DASDs with the classical Linux disk layout or the new
@@ -50,6 +52,10 @@ Package contents
Create an IBM Secure Execution (protected virtualization) image. The
genprotimg command is a symbolic link to the `pvimg create` command.
* pvics:
Convert a qcow2 image to a qcow2 image ready to boot as IBM Secure Execution
for Linux guest.
* udev rules:
- 59-dasd.rules: rules for unique DASD device nodes created in /dev/disk/.
- 57-osasnmpd.rules: udev rules for osasnmpd.
@@ -79,13 +85,6 @@ Package contents
* qetharp:
Read and flush the ARP cache on OSA Express network cards.
* tape390_display:
Display information on the message display facility of a s390 tape
device.
* tape390_crypt:
Control and query crypto settings for 3592 tape devices.
* osasnmpd:
NET-SNMP subagent implementing MIBs provided by OSA-Express
features Fast Ethernet, Gigabit Ethernet, 10 Gigabit Ethernet.
@@ -415,7 +414,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 +425,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 +517,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

@@ -32,8 +32,8 @@ endif
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION := 2
RELEASE := 40
PATCHLEVEL := 0
RELEASE := 42
PATCHLEVEL := 1
DISTRELEASE := build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
export S390_TOOLS_RELEASE

View File

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

@@ -1,11 +1,7 @@
// SPDX-License-Identifier: MIT
/*
* Autocompletion generation - for cpumf family of tools
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"

View File

@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for chcpumf
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#ifndef CHCPUMF_CLI_H

View File

@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for lscpumf
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#ifndef LSCPUMF_CLI_H

View File

@@ -700,7 +700,7 @@ static int do_it(char *s)
if (output_format == FMT_CSV)
flags |= FMT_NOMETA;
if (output_format == FMT_JSON || output_format == FMT_JSONSEQ)
if (util_fmt_is_json(output_format))
flags |= FMT_HANDLEINT;
if (quote_all)
flags |= FMT_QUOTEALL;
@@ -708,7 +708,7 @@ static int do_it(char *s)
mk_labels();
util_fmt_init(stdout, output_format, flags, 1);
util_fmt_obj_start(FMT_DEFAULT, "lshwc");
if (output_format == FMT_JSON || output_format == FMT_JSONSEQ) {
if (util_fmt_is_json(output_format)) {
util_fmt_obj_start(FMT_ROW, "cpumcf info");
util_fmt_pair(FMT_PERSIST, "counter first", "%d", cfvn);
util_fmt_pair(FMT_PERSIST, "counter second", "%d", csvn);

View File

@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for lshwc
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#ifndef LSHWC_CLI_H

View File

@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for lspai
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#ifndef LSPAI_CLI_H

View File

@@ -138,7 +138,7 @@ Apply quoting to every output element, regardless of content or format.
.TP
.BR \-f ", " \-\-format \fI\ FORMAT\fP
Retrieve output in one of the following formats:
JSON, CSV, JSON-SEQ or PAIRS.
JSON, CSV, JSON-SEQ, JSONL or PAIRS.
If no format is specified, the output defaults to CSV.
.
.SS JSON Output Structure

View File

@@ -136,7 +136,7 @@ Default sort order is PAI counter name.
.TP
.BI \-\-format "\ FORMAT"
Retrieve output in one of the following formats:
JSON, csv, json-seq or pairs.
JSON, csv, json-seq, jsonl or pairs.
If no format is specified,
the output defaults to a human-readable format.
.

View File

@@ -14,6 +14,7 @@
#include <fcntl.h>
#include <limits.h>
#include <sched.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
@@ -47,6 +48,8 @@
#define S390_EVT_PAI_CRYPTO 0x1000
#define S390_EVT_PAI_NNPA 0x1800
/* SIGINT or SIGTERM signal received */
static volatile unsigned int sigterm;
/* Default values for select() timeout: 1 second */
static unsigned long read_interval = 1000;
/* Size of mapped perf event ring buffer in 4KB pages.
@@ -350,6 +353,10 @@ static int collect(unsigned long cnt)
if (FD_ISSET(i, &r_fds))
readmap(i);
}
} else if (errno == EINTR && sigterm) {
/* Interrupt by signal SIGINT/SIGTERM, one more iteration */
cnt = 2;
rc = 0;
}
} while (rc != -1 && --cnt > 0);
return rc;
@@ -503,7 +510,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;
@@ -514,6 +521,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));
@@ -835,7 +844,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);
@@ -885,7 +894,7 @@ static int parse_event_attr(char *cp)
}
/* Parse CPU list and event specifications */
static void parse_cpulist(int enr, const char *parm)
static void parse_cpulist(int enr, char *parm)
{
unsigned int evt_attr = 0;
cpu_set_t cmdlist, result;
@@ -939,33 +948,27 @@ static const struct util_prg prg = {
}
};
static void record_cpus_crypto(const char *cp)
static void record_cpus_crypto(char *cp)
{
if (!libcpumf_have_pai_crypto())
errx(EXIT_FAILURE, "No support for PAI crypto counters");
parse_cpulist(S390_EVT_PAI_CRYPTO, cp);
}
static void record_cpus_nnpa(const char *cp)
static void record_cpus_nnpa(char *cp)
{
if (!libcpumf_have_pai_nnpa())
errx(EXIT_FAILURE, "No support for PAI nnpa counters");
parse_cpulist(S390_EVT_PAI_NNPA, cp);
}
/* Mapsize must be power of 2 and larger than 4. Count bits in n and
* return 0 if input is invalid and has a bit count larger than one.
/* Mapsize must be power of 2 and larger than 4. Return true in this case.
*/
static unsigned long check_mapsize(unsigned long n)
static bool check_mapsize(unsigned long n)
{
int bit, cnt = 0;
if (n < 4)
return 0;
for (bit = 0; bit < __BITS_PER_LONG; ++bit)
if (n & (1 << bit))
++cnt;
return cnt == 1 ? n : 0;
return (n & (n - 1)) == 0;
}
static void setprio(const char *prio)
@@ -981,6 +984,12 @@ static void setprio(const char *prio)
err(EXIT_FAILURE, "Could not set realtime priority");
}
static void sig_handler(int no)
{
if (no == SIGINT || no == SIGTERM)
sigterm = 1;
}
int main(int argc, char **argv)
{
bool crypto_record = false, report = false;
@@ -1025,11 +1034,11 @@ int main(int argc, char **argv)
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
break;
case 'm':
errno = 0;
mapsize = strtoul(optarg, &slash, 0);
mapsize = check_mapsize(mapsize);
if (errno || !mapsize || *slash)
if (!mapsize || *slash)
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
if (!check_mapsize(mapsize))
errx(EXIT_FAILURE, "No power of 2 number for -%c", ch);
break;
case 'n':
record_cpus_nnpa(optarg);
@@ -1068,6 +1077,10 @@ int main(int argc, char **argv)
errx(EXIT_FAILURE, "Invalid argument for runtime");
}
if (signal(SIGTERM, sig_handler) == SIG_ERR ||
signal(SIGINT, sig_handler) == SIG_ERR)
errx(EXIT_FAILURE, "Failed to set signal handler");
ev_install(group);
ev_enable();

View File

@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for pai
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#ifndef PAI_CLI_H

View File

@@ -1,11 +1,7 @@
// SPDX-License-Identifier: MIT
/*
* Autocompletion generation - for dasdfmt tool
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"

View File

@@ -1,11 +1,7 @@
/* SPDX-License-Identifier: MIT */
/*
* Command line utilities - for dasdfmt
* SPDX-License-Identifier: MIT
*
* 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.
* Copyright IBM Corp.
*/
#ifndef DASDFMT_CLI_H

View File

@@ -1,5 +1,10 @@
include ../common.mak
zsh-completions = _dasdinfo
bash-completions = dasdinfo.bash
include ../common_autocomp.mak
libs = $(rootdir)/libutil/libutil.a \
$(rootdir)/libdasd/libdasd.a

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "dasdinfo_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "dasdinfo");
return 0;
}

View File

@@ -30,6 +30,8 @@
#include "lib/util_path.h"
#include "lib/zt_common.h"
#include "dasdinfo_cli.h"
#define RD_BUFFER_SIZE 80
#define TEMP_DEV_MAX_RETRIES 1000
@@ -50,49 +52,6 @@ static const struct util_prg prg = {
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("DEVICE"),
{
.option = { "block", required_argument, NULL, 'b' },
.argument = "BLOCKDEV",
.desc = "Block device name, e.g. dasdb",
},
{
.option = { "devnode", required_argument, NULL, 'd' },
.argument = "DEVNODE",
.desc = "Device node, e.g. /dev/dasda",
},
{
.option = { "busid", required_argument, NULL, 'i' },
.argument = "BUSID",
.desc = "Bus ID, e.g. 0.0.e910",
},
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "label", no_argument, NULL, 'l' },
.desc = "Print DASD volume label (volser)",
},
{
.option = { "uid", no_argument, NULL, 'u' },
.desc = "Print DASD uid (without z/VM minidisk token)",
},
{
.option = { "extended-uid", no_argument, NULL, 'x' },
.desc = "Print DASD uid (including z/VM minidisk token)",
},
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Same as -u -x -l",
},
{
.option = { "export", no_argument, NULL, 'e' },
.desc = "Export ID_BUS, ID_TYPE, ID_SERIAL for use in udev",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
/* needed because ftw can not pass arbitrary arguments */
static char *searchbusid;
static char *busiddir;
@@ -101,9 +60,9 @@ struct volume_label {
char volkey[4];
char vollbl[4];
char volid[6];
} __attribute__ ((packed));
} __packed;
static char EBCtoASC[256] = {
static char ebc_to_asc[256] = {
/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
/* 0x08 -GE -SPS -RPT VT FF CR SO SI */
@@ -175,7 +134,7 @@ static char *dinfo_ebcdic_dec(char *source, char *target, int l)
int i;
for (i = 0; i < l; i++)
target[i] = EBCtoASC[(unsigned char)(source[i])];
target[i] = ebc_to_asc[(unsigned char)(source[i])];
return target;
}
@@ -261,7 +220,7 @@ static void *dinfo_malloc(size_t size)
void *result;
result = malloc(size);
if (result == NULL)
if (!result)
warnx("Could not allocate %lu bytes of memory", size);
return result;
@@ -274,7 +233,7 @@ static char *dinfo_make_path(char *dirname, char *filename)
len = strlen(dirname) + strlen(filename) + 2;
result = (char *)dinfo_malloc(len);
if (result == NULL)
if (!result)
return NULL;
sprintf(result, "%s/%s", dirname, filename);
return result;
@@ -296,12 +255,12 @@ static int dinfo_create_devnode(dev_t dev, char **devno)
/* Try several locations for the temporary device node. */
for (path = 0; path < ARRAY_SIZE(pathname); path++) {
if (pathname[path] == NULL)
if (!pathname[path])
continue;
for (retry = 0; retry < TEMP_DEV_MAX_RETRIES; retry++) {
snprintf(filename, sizeof(filename), "dasdinfo%04d", retry);
result = dinfo_make_path(pathname[path], filename);
if (result == NULL)
if (!result)
return -1;
rc = mknod(result, mode, dev);
if (rc == 0) {
@@ -342,7 +301,7 @@ static int dinfo_extract_dev(dev_t *dev, char *str)
memset(tmp, 0, RD_BUFFER_SIZE);
util_strlcpy(tmp, str, RD_BUFFER_SIZE);
p = strchr(tmp, ':');
if (p == NULL) {
if (!p) {
warnx("Error: unable to extract major/minor");
return -1;
}
@@ -386,10 +345,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))
@@ -401,17 +358,16 @@ 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")) {
free(linkdir);
return FTW_CONTINUE;
}
free(linkdir);
free(busiddir);
busiddir = strdup(fpath);
if (busiddir == NULL)
if (!busiddir)
return -1;
return FTW_STOP;
}
@@ -424,7 +380,7 @@ dinfo_find_entry(const char *dir, const char *searchstring,
struct dirent *dir_entry = NULL;
directory = opendir(dir);
if (directory == NULL)
if (!directory)
return -1;
while ((dir_entry = readdir(directory)) != NULL) {
/* compare if the found entry has exactly the same name and type
@@ -434,7 +390,7 @@ dinfo_find_entry(const char *dir, const char *searchstring,
strlen(searchstring)) == 0) &&
(dir_entry->d_type & type)) {
*result = strdup(dir_entry->d_name);
if (*result == NULL)
if (!*result)
goto out;
closedir(directory);
return 0; /* found */
@@ -480,7 +436,7 @@ dinfo_get_blockdev_from_busid(char *busid, char **blkdev)
if (rc != 0)
goto out2;
*blkdev = strdup(strchr(result, ':') + 1);
if (*blkdev == NULL)
if (!*blkdev)
rc = -1;
}
@@ -513,7 +469,7 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
path = util_path_sysfs("block/");
directory = opendir(path);
if (directory == NULL) {
if (!directory) {
warnx("Error: could not open directory %s", path);
free(path);
return -1;
@@ -553,8 +509,6 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
int main(int argc, char *argv[])
{
struct utsname uname_buf;
int version, release;
char *uidfile = NULL;
char *device = NULL;
char *readbuf = NULL;
@@ -614,35 +568,19 @@ int main(int argc, char *argv[])
util_prg_print_version();
exit(EXIT_SUCCESS);
default:
fprintf(stderr, "Try 'dasdinfo --help' for more "
"information.\n");
fprintf(stderr, "Try 'dasdinfo --help' for more information.\n");
exit(1);
}
}
uname(&uname_buf);
sscanf(uname_buf.release, "%d.%d", &version, &release);
if (strcmp(uname_buf.sysname, "Linux") ||
version < 2 || (version == 2 && release < 6)) {
warnx("%s %d.%d is not supported", uname_buf.sysname,
version, release);
exit(1);
}
if (!busid && !blockdev && !devnode)
errx(EXIT_FAILURE, "Error: please specify a device using either -b, -i or -d");
if (!busid && !blockdev && !devnode) {
warnx("Error: please specify a device using either -b, -i or -d");
exit(1);
}
if ((busid && blockdev) || (busid && devnode) || (blockdev && devnode))
errx(EXIT_FAILURE, "Error: please specify device only once, either -b, -i or -d");
if ((busid && blockdev) || (busid && devnode) || (blockdev && devnode)) {
warnx("Error: please specify device only once, either -b, -i or -d");
exit(1);
}
if (!print_uid && !print_extended_uid && !print_vlabel) {
warnx("Error: no action specified (e.g. -u)");
exit(1);
}
if (!print_uid && !print_extended_uid && !print_vlabel)
errx(EXIT_FAILURE, "Error: no action specified (e.g. -u)");
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
if (!readbuf)

55
dasdinfo/dasdinfo_cli.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef DASDINFO_CLI_H
#define DASDINFO_CLI_H
#include "lib/util_opt.h"
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("DEVICE"),
{
.option = { "block", required_argument, NULL, 'b' },
.argument = "BLOCKDEV",
.desc = "Block device name, e.g. dasdb",
},
{
.option = { "devnode", required_argument, NULL, 'd' },
.argument = "DEVNODE",
.desc = "Device node, e.g. /dev/dasda",
},
{
.option = { "busid", required_argument, NULL, 'i' },
.argument = "BUSID",
.desc = "Bus ID, e.g. 0.0.e910",
},
UTIL_OPT_SECTION("OPTIONS"),
{
.option = { "label", no_argument, NULL, 'l' },
.desc = "Print DASD volume label (volser)",
},
{
.option = { "uid", no_argument, NULL, 'u' },
.desc = "Print DASD uid (without z/VM minidisk token)",
},
{
.option = { "extended-uid", no_argument, NULL, 'x' },
.desc = "Print DASD uid (including z/VM minidisk token)",
},
{
.option = { "all", no_argument, NULL, 'a' },
.desc = "Same as -u -x -l",
},
{
.option = { "export", no_argument, NULL, 'e' },
.desc = "Export ID_BUS, ID_TYPE, ID_SERIAL for use in udev",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -1,5 +1,10 @@
include ../common.mak
zsh-completions = _dasdview
bash-completions = dasdview.bash
include ../common_autocomp.mak
libs = $(rootdir)/libdasd/libdasd.a \
$(rootdir)/libzds/libzds.a \
$(rootdir)/libvtoc/libvtoc.a \

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "dasdview_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "dasdview");
return 0;
}

View File

@@ -37,6 +37,7 @@
#include "lib/zt_common.h"
#include "dasdview.h"
#include "dasdview_cli.h"
/* Characters per line */
#define DASDVIEW_CPL 16
@@ -56,61 +57,6 @@ static const struct util_prg prg = {
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("DUMP OPTIONS"),
{
.option = { NULL, no_argument, NULL, '1' },
.desc = "Show DASD content in short Hex/EBCDIC/ASCII format",
.flags = UTIL_OPT_FLAG_NOLONG,
},
{
.option = { NULL, no_argument, NULL, '2' },
.desc = "Show DASD content in detailed Hex/EBCDIC/ASCII format",
.flags = UTIL_OPT_FLAG_NOLONG,
},
{
.option = { "begin", required_argument, NULL, 'b' },
.argument = "BEGIN",
.desc = "Specify start of dump in kilobytes (suffix k), "
"megabytes (m), blocks (b), tracks (t), or cylinders (c)",
},
{
.option = { "size", required_argument, NULL, 's' },
.argument = "SIZE",
.desc = "Specify size of dump in kilobytes (suffix k), "
"megabytes (m), blocks (b), tracks (t), or cylinders (c)",
},
UTIL_OPT_SECTION("MISC"),
{
.option = { "characteristic", no_argument, NULL, 'c' },
.desc = "Print the characteristics of a device",
},
{
.option = { "info", no_argument, NULL, 'i' },
.desc = "Print general DASD information and geometry",
},
{
.option = { "volser", no_argument, NULL, 'j' },
.desc = "Print the volume serial number",
},
{
.option = { "label", no_argument, NULL, 'l' },
.desc = "Print information about the volume label",
},
{
.option = { "vtoc", required_argument, NULL, 't' },
.argument = "SPEC",
.desc = "Print the table of content (VTOC)",
},
{
.option = { "extended", no_argument, NULL, 'x' },
.desc = "Print extended DASD information",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
/*
* Generate and print an error message based on the formatted
* text string FMT and a variable amount of extra arguments.

67
dasdview/dasdview_cli.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef DASDVIEW_CLI_H
#define DASDVIEW_CLI_H
#include "lib/util_opt.h"
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("DUMP OPTIONS"),
{
.option = { NULL, no_argument, NULL, '1' },
.desc = "Show DASD content in short Hex/EBCDIC/ASCII format",
.flags = UTIL_OPT_FLAG_NOLONG,
},
{
.option = { NULL, no_argument, NULL, '2' },
.desc = "Show DASD content in detailed Hex/EBCDIC/ASCII format",
.flags = UTIL_OPT_FLAG_NOLONG,
},
{
.option = { "begin", required_argument, NULL, 'b' },
.argument = "BEGIN",
.desc = "Specify start of dump in kilobytes (suffix k), "
"megabytes (m), blocks (b), tracks (t), or cylinders (c)",
},
{
.option = { "size", required_argument, NULL, 's' },
.argument = "SIZE",
.desc = "Specify size of dump in kilobytes (suffix k), "
"megabytes (m), blocks (b), tracks (t), or cylinders (c)",
},
UTIL_OPT_SECTION("MISC"),
{
.option = { "characteristic", no_argument, NULL, 'c' },
.desc = "Print the characteristics of a device",
},
{
.option = { "info", no_argument, NULL, 'i' },
.desc = "Print general DASD information and geometry",
},
{
.option = { "volser", no_argument, NULL, 'j' },
.desc = "Print the volume serial number",
},
{
.option = { "label", no_argument, NULL, 'l' },
.desc = "Print information about the volume label",
},
{
.option = { "vtoc", required_argument, NULL, 't' },
.argument = "SPEC",
.desc = "Print the table of content (VTOC)",
},
{
.option = { "extended", no_argument, NULL, 'x' },
.desc = "Print extended DASD information",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -0,0 +1,136 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef DUMP2TAR_CLI_H
#define DUMP2TAR_CLI_H
#include "lib/util_opt.h"
#define OPT_NOSHORT_BASE 256
#define OPT_DEREFERENCE (OPT_NOSHORT_BASE + 0)
#define OPT_NORECURSION (OPT_NOSHORT_BASE + 1)
#define OPT_EXCLUDETYPE (OPT_NOSHORT_BASE + 2)
/* Definition of command line options */
static struct util_opt dump2tar_opts[] = {
UTIL_OPT_SECTION("OUTPUT OPTIONS"),
{
.option = { "output-file", required_argument, NULL, 'o' },
.argument = "FILE",
.desc = "Write archive to FILE (default: standard output)",
},
#ifdef HAVE_ZLIB
{
.option = { "gzip", no_argument, NULL, 'z' },
.desc = "Write a gzip compressed archive",
},
#endif /* HAVE_ZLIB */
{
.option = { "max-size", required_argument, NULL, 'm' },
.argument = "N",
.desc = "Stop adding files when archive size exceeds N bytes",
},
{
.option = { "timeout", required_argument, NULL, 't' },
.argument = "SEC",
.desc = "Stop adding files after SEC seconds",
},
{
.option = { "no-eof", no_argument, NULL, 131 },
.desc = "Do not write an end-of-file marker",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "add-cmd-status", no_argument, NULL, 132 },
.desc = "Add status of commands as separate file",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "append", no_argument, NULL, 133 },
.desc = "Append output to end of file",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("INPUT OPTIONS"),
{
.option = { "files-from", required_argument, NULL, 'F' },
.argument = "FILE",
.desc = "Read filenames from FILE (- for standard input)",
},
{
.option = { "ignore-failed-read", no_argument, NULL, 'i' },
.desc = "Continue after read errors",
},
{
.option = { "buffer-size", required_argument, NULL, 'b' },
.argument = "N",
.desc = "Read data in chunks of N byte (default: 16384)",
},
{
.option = { "file-timeout", required_argument, NULL, 'T' },
.desc = "Stop reading file after SEC seconds",
.argument = "SEC",
},
{
.option = { "file-max-size", required_argument, NULL, 'M' },
.argument = "N",
.desc = "Stop reading file after N bytes",
},
{
.option = { "jobs", required_argument, NULL, 'j' },
.argument = "N",
.desc = "Read N files in parallel (default: 1)",
},
{
.option = { "jobs-per-cpu", required_argument, NULL, 'J' },
.argument = "N",
.desc = "Read N files per CPU in parallel",
},
{
.option = { "exclude", required_argument, NULL, 'x' },
.argument = "PATTERN",
.desc = "Don't add files matching PATTERN",
},
{
.option = { "exclude-from", required_argument, NULL, 'X' },
.argument = "FILE",
.desc = "Don't add files matching patterns in FILE",
},
{
.option = { "exclude-type", required_argument, NULL,
OPT_EXCLUDETYPE },
.argument = "TYPE",
.desc = "Don't add files of specified TYPE (one of: fdcbpls)",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "dereference", no_argument, NULL, OPT_DEREFERENCE },
.desc = "Add link targets instead of links",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "no-recursion", no_argument, NULL,
OPT_NORECURSION },
.desc = "Don't add files from sub-directories",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("MISC OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Print additional informational output",
},
{
.option = { "quiet", no_argument, NULL, 'q' },
.desc = "Suppress printing of informational output",
},
UTIL_OPT_END,
};
#endif

View File

@@ -1,6 +1,11 @@
# Common definitions
include ../../common.mak
zsh-completions = _dump2tar
bash-completions = dump2tar.bash
include ../../common_autocomp.mak
ALL_CPPFLAGS += -I../include -Wno-unused-parameter
LDLIBS += -lpthread -lrt
ifneq ($(HAVE_ZLIB),0)

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "../include/dump2tar_cli.h"
int main(void)
{
generate_autocomp(dump2tar_opts, "dump2tar");
return 0;
}

View File

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

@@ -21,6 +21,7 @@
#include "lib/util_prg.h"
#include "dump.h"
#include "dump2tar_cli.h"
#include "global.h"
#include "idcache.h"
#include "misc.h"
@@ -28,12 +29,6 @@
#define MIN_BUFFER_SIZE 4096
#define OPT_NOSHORT_BASE 256
#define OPT_DEREFERENCE (OPT_NOSHORT_BASE + 0)
#define OPT_NORECURSION (OPT_NOSHORT_BASE + 1)
#define OPT_EXCLUDETYPE (OPT_NOSHORT_BASE + 2)
/* Program description */
static const struct util_prg dump2tar_prg = {
.desc = "Use dump2tar to create a tar archive from the contents "
@@ -52,124 +47,6 @@ static const struct util_prg dump2tar_prg = {
},
};
/* Definition of command line options */
static struct util_opt dump2tar_opts[] = {
UTIL_OPT_SECTION("OUTPUT OPTIONS"),
{
.option = { "output-file", required_argument, NULL, 'o' },
.argument = "FILE",
.desc = "Write archive to FILE (default: standard output)",
},
#ifdef HAVE_ZLIB
{
.option = { "gzip", no_argument, NULL, 'z' },
.desc = "Write a gzip compressed archive",
},
#endif /* HAVE_ZLIB */
{
.option = { "max-size", required_argument, NULL, 'm' },
.argument = "N",
.desc = "Stop adding files when archive size exceeds N bytes",
},
{
.option = { "timeout", required_argument, NULL, 't' },
.argument = "SEC",
.desc = "Stop adding files after SEC seconds",
},
{
.option = { "no-eof", no_argument, NULL, 131 },
.desc = "Do not write an end-of-file marker",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "add-cmd-status", no_argument, NULL, 132 },
.desc = "Add status of commands as separate file",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "append", no_argument, NULL, 133 },
.desc = "Append output to end of file",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("INPUT OPTIONS"),
{
.option = { "files-from", required_argument, NULL, 'F' },
.argument = "FILE",
.desc = "Read filenames from FILE (- for standard input)",
},
{
.option = { "ignore-failed-read", no_argument, NULL, 'i' },
.desc = "Continue after read errors",
},
{
.option = { "buffer-size", required_argument, NULL, 'b' },
.argument = "N",
.desc = "Read data in chunks of N byte (default: 16384)",
},
{
.option = { "file-timeout", required_argument, NULL, 'T' },
.desc = "Stop reading file after SEC seconds",
.argument = "SEC",
},
{
.option = { "file-max-size", required_argument, NULL, 'M' },
.argument = "N",
.desc = "Stop reading file after N bytes",
},
{
.option = { "jobs", required_argument, NULL, 'j' },
.argument = "N",
.desc = "Read N files in parallel (default: 1)",
},
{
.option = { "jobs-per-cpu", required_argument, NULL, 'J' },
.argument = "N",
.desc = "Read N files per CPU in parallel",
},
{
.option = { "exclude", required_argument, NULL, 'x' },
.argument = "PATTERN",
.desc = "Don't add files matching PATTERN",
},
{
.option = { "exclude-from", required_argument, NULL, 'X' },
.argument = "FILE",
.desc = "Don't add files matching patterns in FILE",
},
{
.option = { "exclude-type", required_argument, NULL,
OPT_EXCLUDETYPE },
.argument = "TYPE",
.desc = "Don't add files of specified TYPE (one of: fdcbpls)",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "dereference", no_argument, NULL, OPT_DEREFERENCE },
.desc = "Add link targets instead of links",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
{
.option = { "no-recursion", no_argument, NULL,
OPT_NORECURSION },
.desc = "Don't add files from sub-directories",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("MISC OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Print additional informational output",
},
{
.option = { "quiet", no_argument, NULL, 'q' },
.desc = "Suppress printing of informational output",
},
UTIL_OPT_END,
};
/* Split buffer size specification in @arg into two numbers to be stored in
* @from_ptr and @to_ptr. Return %EXIT_OK on success. */
static int parse_buffer_size(char *arg, size_t *from_ptr, size_t *to_ptr)

View File

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

View File

@@ -1,5 +1,10 @@
include ../common.mak
zsh-completions = _fdasd
bash-completions = fdasd.bash
include ../common_autocomp.mak
libs = $(rootdir)/libvtoc/libvtoc.a \
$(rootdir)/libzds/libzds.a \
$(rootdir)/libdasd/libdasd.a \

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "fdasd_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "fdasd");
return 0;
}

View File

@@ -21,6 +21,7 @@
#include "lib/zt_common.h"
#include "fdasd.h"
#include "fdasd_cli.h"
/* global variables */
static struct hd_geometry geo;
@@ -138,58 +139,6 @@ static const struct util_prg prg = {
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("NON-INTERACTIVE MODE"),
{
.option = { "auto", no_argument, NULL, 'a' },
.desc = "Create a single partition spanning the entire disk",
},
{
.option = { "config", required_argument, NULL, 'c' },
.argument = "FILE",
.desc = "Create partitions(s) based on content of FILE",
},
{
.option = { "keep_volser", no_argument, NULL, 'k' },
.desc = "Do not change the current volume serial",
},
{
.option = { "label", required_argument, NULL, 'l' },
.argument = "VOLSER",
.desc = "Set the volume serial to VOLSER",
},
UTIL_OPT_SECTION("MISC"),
{
.option = { "check_host_count", no_argument, NULL, 'C' },
.desc = "Check if device is in use by other hosts",
},
{
.option = { "force", optional_argument, NULL, 'f' },
.argument = "TYPE,SIZE",
.desc = "Force fdasd to work on non DASD devices with assumed "
"TYPE (3390, 3380, or 9345) and blocksize SIZE",
},
{
.option = { "volser", no_argument, NULL, 'i' },
.desc = "Print volume serial",
},
{
.option = { "table", no_argument, NULL, 'p' },
.desc = "Print partition table",
},
{
.option = { "verbose", no_argument, NULL, 'r' },
.desc = "Provide more verbose output",
},
{
.option = { "silent", no_argument, NULL, 's' },
.desc = "Suppress messages",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static int getpos(fdasd_anchor_t *anc, int dsn)
{
return anc->partno[dsn];

64
fdasd/fdasd_cli.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef FDASD_CLI_H
#define FDASD_CLI_H
#include "lib/util_opt.h"
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("NON-INTERACTIVE MODE"),
{
.option = { "auto", no_argument, NULL, 'a' },
.desc = "Create a single partition spanning the entire disk",
},
{
.option = { "config", required_argument, NULL, 'c' },
.argument = "FILE",
.desc = "Create partitions(s) based on content of FILE",
},
{
.option = { "keep_volser", no_argument, NULL, 'k' },
.desc = "Do not change the current volume serial",
},
{
.option = { "label", required_argument, NULL, 'l' },
.argument = "VOLSER",
.desc = "Set the volume serial to VOLSER",
},
UTIL_OPT_SECTION("MISC"),
{
.option = { "check_host_count", no_argument, NULL, 'C' },
.desc = "Check if device is in use by other hosts",
},
{
.option = { "force", optional_argument, NULL, 'f' },
.argument = "TYPE,SIZE",
.desc = "Force fdasd to work on non DASD devices with assumed "
"TYPE (3390, 3380, or 9345) and blocksize SIZE",
},
{
.option = { "volser", no_argument, NULL, 'i' },
.desc = "Print volume serial",
},
{
.option = { "table", no_argument, NULL, 'p' },
.desc = "Print partition table",
},
{
.option = { "verbose", no_argument, NULL, 'r' },
.desc = "Provide more verbose output",
},
{
.option = { "silent", no_argument, NULL, 's' },
.desc = "Suppress messages",
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -7,6 +7,11 @@
include ../common.mak
zsh-completions = _hsavmcore
bash-completions = hsavmcore.bash
include ../common_autocomp.mak
ALL_CPPFLAGS += -D_FILE_OFFSET_BITS=64
ifeq (${HAVE_FUSE},0)
@@ -41,7 +46,7 @@ endif
ALL_CFLAGS += $(FUSE_CFLAGS) $(SYSTEMD_CFLAGS)
LDLIBS += $(FUSE_LDLIBS) $(SYSTEMD_LDLIBS) -lpthread
sources := $(wildcard *.c)
sources := $(filter-out %_host.c, $(wildcard *.c))
objects := $(patsubst %.c,%.o,$(sources))
libs = $(rootdir)/libutil/libutil.a

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "hsavmcore_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "hsavmcore");
return 0;
}

View File

@@ -16,6 +16,7 @@
#include "lib/util_log.h"
#include "cmdline_options.h"
#include "hsavmcore_cli.h"
static const struct util_prg prg = {
.desc = "hsavmcore is designed to make the dump process with kdump more "
@@ -32,91 +33,6 @@ static const struct util_prg prg = {
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("CONFIGURATION"),
{
.option = { "config", required_argument, NULL, 'c' },
.argument = "CONFIGFILE",
.desc = "Path to the configuration file.\n"
"Default: no configuration file is used",
},
{
.option = { "vmcore", required_argument, NULL, 'C' },
.argument = "VMCOREFILE",
.desc = "Path to the vmcore file.\n"
"Default: " PROC_VMCORE,
},
{
.option = { "hsa", required_argument, NULL, 'H' },
.argument = "ZCOREHSAFILE",
.desc = "Path to the zcore HSA file.\n"
"Default: " ZCORE_HSA,
},
{
.option = { "workdir", required_argument, NULL, 'W' },
.argument = "WORKDIR",
.desc = "Path to the work directory where temporary files can be "
"stored.\nDefault: " WORKDIR,
},
{
.option = { "bmvmcore", required_argument, NULL, 'B' },
.argument = "VMCOREFILE",
.desc = "Path to the target of the bind mount for the vmcore "
"replacement.\nDefault: " PROC_VMCORE,
},
{
.option = { "swap", required_argument, NULL, 'S' },
.argument = "PATH",
.desc = "Path to a swap device or file. The specified swap "
"device or file must exist and have the proper swap "
"format.\nDefault: no swap device or file is activated",
},
{
.option = { "hsasize", required_argument, NULL, 'T' },
.argument = "HSASIZE",
.desc = "HSA size in bytes.\n"
"Default: -1 (read from the zcore HSA file)",
},
{
.option = { "dbgfsmnt", no_argument, NULL, 'D' },
.desc = "Mount the debug file system.\n"
"Default: the debug file system is not mounted",
},
{
.option = { "hsamem", no_argument, NULL, 'F' },
.desc = "Cache the HSA memory in regular memory.\n"
"Default: the HSA memory is cached as a file within "
"WORKDIR",
},
{
.option = { "norelhsa", no_argument, NULL, 'R' },
.desc = "Do NOT release the HSA memory after caching.\n"
"Default: the HSA memory is released",
},
{
.option = { "nobindmnt", no_argument, NULL, 'N' },
.desc = "Do NOT replace the system's vmcore.\n"
"Default: the system's vmcore is replaced",
},
UTIL_OPT_SECTION("LOGGING"),
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Print verbose messages to stdout. Repeat this option "
"for increased verbosity from just error messages to "
"also include warning, information, debug, and trace "
"messages. This option is intended for debugging",
},
{
.option = { "fusedbg", no_argument, NULL, 'G' },
.desc = "Enable FUSE debugging.\n"
"Default: FUSE debugging is disabled",
},
UTIL_OPT_SECTION("GENERAL OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
void parse_cmdline_options(int argc, char *argv[], struct config *config)
{
int opt, ret;

99
hsavmcore/hsavmcore_cli.h Normal file
View File

@@ -0,0 +1,99 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef HSAVMCORE_CLI_H
#define HSAVMCORE_CLI_H
#include "lib/util_opt.h"
#include "common.h"
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("CONFIGURATION"),
{
.option = { "config", required_argument, NULL, 'c' },
.argument = "CONFIGFILE",
.desc = "Path to the configuration file.\n"
"Default: no configuration file is used",
},
{
.option = { "vmcore", required_argument, NULL, 'C' },
.argument = "VMCOREFILE",
.desc = "Path to the vmcore file.\n"
"Default: " PROC_VMCORE,
},
{
.option = { "hsa", required_argument, NULL, 'H' },
.argument = "ZCOREHSAFILE",
.desc = "Path to the zcore HSA file.\n"
"Default: " ZCORE_HSA,
},
{
.option = { "workdir", required_argument, NULL, 'W' },
.argument = "WORKDIR",
.desc = "Path to the work directory where temporary files can be "
"stored.\nDefault: " WORKDIR,
},
{
.option = { "bmvmcore", required_argument, NULL, 'B' },
.argument = "VMCOREFILE",
.desc = "Path to the target of the bind mount for the vmcore "
"replacement.\nDefault: " PROC_VMCORE,
},
{
.option = { "swap", required_argument, NULL, 'S' },
.argument = "PATH",
.desc = "Path to a swap device or file. The specified swap "
"device or file must exist and have the proper swap "
"format.\nDefault: no swap device or file is activated",
},
{
.option = { "hsasize", required_argument, NULL, 'T' },
.argument = "HSASIZE",
.desc = "HSA size in bytes.\n"
"Default: -1 (read from the zcore HSA file)",
},
{
.option = { "dbgfsmnt", no_argument, NULL, 'D' },
.desc = "Mount the debug file system.\n"
"Default: the debug file system is not mounted",
},
{
.option = { "hsamem", no_argument, NULL, 'F' },
.desc = "Cache the HSA memory in regular memory.\n"
"Default: the HSA memory is cached as a file within "
"WORKDIR",
},
{
.option = { "norelhsa", no_argument, NULL, 'R' },
.desc = "Do NOT release the HSA memory after caching.\n"
"Default: the HSA memory is released",
},
{
.option = { "nobindmnt", no_argument, NULL, 'N' },
.desc = "Do NOT replace the system's vmcore.\n"
"Default: the system's vmcore is replaced",
},
UTIL_OPT_SECTION("LOGGING"),
{
.option = { "verbose", no_argument, NULL, 'V' },
.desc = "Print verbose messages to stdout. Repeat this option "
"for increased verbosity from just error messages to "
"also include warning, information, debug, and trace "
"messages. This option is intended for debugging",
},
{
.option = { "fusedbg", no_argument, NULL, 'G' },
.desc = "Enable FUSE debugging.\n"
"Default: FUSE debugging is disabled",
},
UTIL_OPT_SECTION("GENERAL OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

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

@@ -96,6 +96,17 @@ with an ASCII Record Separator character (0x1e) and suffixed with an ASCII Line
Feed character (0x0a) in accordance with RFC7464.
.BR
See section "OUTPUT FORMAT" for more details.
.BR
.PP
.IP \(bu 3
.B jsonl:
Line-delimited JSON data structures
Data for each iteration is formatted as a separate JSON data structure
separated by ASCII Line Feed character (0x0a, LF).
.BR
See section "OUTPUT FORMAT" for more details.
.BR
.PP
@@ -458,6 +469,14 @@ Subsequent objects each represent performance data for one iteration
.br
.PP
.SS jsonl
The jsonl output format is a data streaming variation of the JSON output format
described above with the same properties as the json\-seq output with the
difference that JSON data is separated only by an ASCII Line Feed character
(0x0a, LF).
.SH EXAMPLES
To start hyptop with the "sys_list" window in interactive mode, enter:
.br

View File

@@ -233,7 +233,7 @@ static void l_fmt_init(void)
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)
if (util_fmt_is_json(g.o.format))
flags |= FMT_HANDLEINT;
util_fmt_init(stdout, g.o.format, flags, 1);
}

View File

@@ -54,14 +54,6 @@ static char HELP_TEXT[] =
#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
*/
@@ -224,7 +216,7 @@ static void l_fields_set(char *str)
}
/*
* Set the "--sort_field" option
* Set the "--sort" option
*/
static void l_sort_field_set(char *str)
{
@@ -362,19 +354,18 @@ void opts_parse(int argc, char *argv[])
{ "version", no_argument, NULL, 'v'},
{ "help", no_argument, NULL, 'h'},
{ "batch-mode", no_argument, NULL, 'b'},
{ "batch_mode", no_argument, NULL, OPT_BATCH_MODE},
{ "batch_mode", no_argument, NULL, 'b'},
{ "all", no_argument, NULL, OPT_FORMAT_ALL },
{ "delay", required_argument, NULL, 'd'},
{ "smt-factor", required_argument, NULL, 'm'},
{ "smt_factor", required_argument, NULL, OPT_SMT_FACTOR},
{ "smt_factor", required_argument, NULL, 'm'},
{ "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'},
{ "sort_field", required_argument, NULL, OPT_SORT_FIELD},
{ "sort", required_argument, NULL, 'S'},
{ "cpu-types", required_argument, NULL, 't'},
{ "cpu_types", required_argument, NULL, OPT_CPU_TYPES},
{ "cpu_types", required_argument, NULL, 't'},
{ "format", required_argument, NULL, OPT_FORMAT },
{ NULL, 0, NULL, 0 }
};
@@ -393,14 +384,12 @@ 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;
@@ -413,14 +402,12 @@ 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;

View File

@@ -1037,7 +1037,7 @@ void table_fmt_start(void)
{
if (!g.o.format_specified)
return;
if (g.o.format != FMT_JSONSEQ)
if (!util_fmt_is_json_stream(g.o.format))
util_fmt_obj_start(FMT_LIST, "hyptop");
}
@@ -1045,7 +1045,7 @@ void table_fmt_end(void)
{
if (!g.o.format_specified)
return;
if (g.o.format != FMT_JSONSEQ)
if (!util_fmt_is_json_stream(g.o.format))
util_fmt_obj_end(); /* hyptop[] */
}

View File

@@ -1,15 +1,7 @@
/* 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.
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef LIB_UTIL_AUTOCOMP_H

View File

@@ -45,12 +45,13 @@
#define FMT_DEFAULT 0
/* Names of supported output format types. */
#define FMT_TYPE_NAMES "json json-seq pairs csv"
#define FMT_TYPE_NAMES "json json-seq jsonl pairs csv"
/**
* enum util_fmt_t - Output format types.
* @FMT_JSON: JavaScript Object Notation output data structure
* @FMT_JSONSEQ: Sequence of JSON data structures according to RFC7464
* @FMT_JSONL: Line-delimited JSON
* @FMT_PAIRS: Textual key=value pairs
* @FMT_CSV: Comma-separated-values output
*
@@ -59,6 +60,7 @@
enum util_fmt_t {
FMT_JSON,
FMT_JSONSEQ,
FMT_JSONL,
FMT_PAIRS,
FMT_CSV,
};
@@ -232,4 +234,23 @@ void util_fmt_obj_end(void);
*/
void util_fmt_pair(unsigned int mflags, const char *key, const char *fmt, ...);
/**
* util_fmt_is_json() - Determine whether format is JSON.
* @type: Format type identifier.
*
* Return: %true if type is JSON, %false otherwise.
*/
bool util_fmt_is_json(enum util_fmt_t type);
/**
* util_fmt_is_json_stream() - Determine whether format is JSON stream.
* @type: Format type identifier.
*
* Determine whether a given format @type represents a JSON streaming format
* such as json-seq (@FMT_JSONSEQ) or jsonl (@FMT_JSONL).
*
* Return: %true if type is either @FMT_JSONSEQ or @FMT_JSONL, %false otherwise.
*/
bool util_fmt_is_json_stream(enum util_fmt_t type);
#endif /* LIB_UTIL_FMT_H */

View File

@@ -12,6 +12,7 @@
#ifndef LIB_UTIL_LIBC_H
#define LIB_UTIL_LIBC_H
#include <fcntl.h>
#include <stdio.h>
#ifdef __cplusplus
@@ -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

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

@@ -2172,7 +2172,7 @@ int write_public_key(const char *pem_filename, EVP_PKEY *pkey)
*/
static bool is_duplicate_name_entry(X509_NAME *name, X509_NAME_ENTRY *entry)
{
X509_NAME_ENTRY *ne;
const X509_NAME_ENTRY *ne;
int count, i;
count = X509_NAME_entry_count(name);

View File

@@ -378,8 +378,14 @@ int kmip_connection_tls_init(struct kmip_connection *conn, bool debug)
if (conn->config.tls_verify_host) {
SSL_set_hostflags(conn->plain_tls.ssl,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
#if OPENSSL_VERSION_PREREQ(4, 0)
if (SSL_set1_ipaddr(conn->plain_tls.ssl, hostname) != 1 &&
SSL_set1_dnsname(conn->plain_tls.ssl, hostname) != 1) {
kmip_debug(debug, "SSL_set1_ipaddr/dnsname failed");
#else
if (SSL_set1_host(conn->plain_tls.ssl, hostname) != 1) {
kmip_debug(debug, "SSL_set1_host failed");
#endif
if (debug)
ERR_print_errors_fp(stderr);
rc = -EIO;

View File

@@ -395,7 +395,7 @@ const struct sk_digest_info *SK_UTIL_get_digest_info(int digest_nid)
static bool SK_UTILS_is_duplicate_name_entry(const X509_NAME *name,
const X509_NAME_ENTRY *entry)
{
X509_NAME_ENTRY *ne;
const X509_NAME_ENTRY *ne;
int count, i;
count = X509_NAME_entry_count(name);

View File

@@ -1,15 +1,7 @@
// 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.
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include <errno.h>
@@ -22,18 +14,19 @@
#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\
static const char *bash_script_part1 = "() {\n\
\tlocal current_word options_array\n\
\tCOMPREPLY=()\n\n\
\tcurrent_word=\"${COMP_WORDS[COMP_CWORD]}\"\n\n\
\tprevious_word=\"${COMP_WORDS[COMP_CWORD-1]}\"\n\n\
\tcurrent_word=\"${COMP_WORDS[COMP_CWORD]}\"\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\
static const char *bash_script_part2 = "\tif [[ ${current_word} == -* ]] ; then\n\
\t\tmapfile -t \"COMPREPLY\" < <(compgen -W \"${options_array}\" -- \"$current_word\")\n\
\telse\n\
\t\tcompopt -o bashdefault -o default\n\
\tfi\n\
\treturn 0\n\
}\n\
complete -F ";
static char *format_name(const char *fmt, char *tool_name)
@@ -63,7 +56,7 @@ static int init_scriptfile(char *file_path)
{
int fd;
fd = open(file_path, O_CREAT | O_WRONLY, 0644);
fd = open(file_path, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd < 0)
return -EIO;
return fd;
@@ -86,7 +79,7 @@ static int start_bash_scriptfile(int fd, char *func_name)
static int start_zsh_scriptfile(int fd, char *func_name, char *tool_name)
{
const char *part3 = " {\n\n\t_arguments -C \\\n";
const char *part3 = " {\n\n\t_arguments -C -A \"*\" \\\n";
const char *part2 = "\n\nfunction ";
const char *part1 = "#compdef ";
int len, ret = 0;
@@ -127,6 +120,7 @@ static int write_bash_command_options(struct util_opt *opt_vec, int fd)
static int write_zsh_command_options(struct util_opt *opt_vec, int fd)
{
const char *end = "\t\t\"*:files:_files\"\n}\n";
const char *name, *desc;
char *str;
int len;
@@ -145,8 +139,14 @@ static int write_zsh_command_options(struct util_opt *opt_vec, int fd)
free(str);
}
}
if (write(fd, "\n}\n", 3) != 3)
len = asprintf(&str, "%s", end);
if (len == -1)
return -EIO;
if (write(fd, str, len) != len) {
free(str);
return -EIO;
}
free(str);
return 0;
}
@@ -169,35 +169,6 @@ static int finish_bash_scriptfile(char *tool_name, int fd, char *func_name)
* 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)
{
@@ -244,22 +215,6 @@ end:
* 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)
{

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

@@ -91,6 +91,7 @@ static const struct {
} formats[] = {
{ "json", FMT_JSON },
{ "json-seq", FMT_JSONSEQ },
{ "jsonl", FMT_JSONL },
{ "pairs", FMT_PAIRS },
{ "csv", FMT_CSV },
};
@@ -111,6 +112,29 @@ bool util_fmt_name_to_type(const char *name, enum util_fmt_t *type)
return false;
}
bool util_fmt_is_json(enum util_fmt_t type)
{
switch (type) {
case FMT_JSON:
case FMT_JSONSEQ:
case FMT_JSONL:
return true;
default:
return false;
}
}
bool util_fmt_is_json_stream(enum util_fmt_t type)
{
switch (type) {
case FMT_JSONSEQ:
case FMT_JSONL:
return true;
default:
return false;
}
}
static void safe_write(const char *str)
{
size_t done, todo;
@@ -129,7 +153,7 @@ static void _indent(unsigned int off, bool safe)
{
unsigned int num, i;
if (f.type == FMT_JSONSEQ)
if (util_fmt_is_json_stream(f.type))
return;
num = f.ind_base + off;
if (f.type == FMT_JSON && f.lvl > 0)
@@ -408,8 +432,8 @@ static void emit_meta_object(void)
util_fmt_pair(quoted, "time", "%s", date);
_util_fmt_obj_end();
if (f.type == FMT_JSONSEQ) {
/* Tool meta-data is a separate object for JSONSEQ. */
if (util_fmt_is_json_stream(f.type)) {
/* Tool meta-data is a separate object for JSON streams. */
util_fmt_obj_end();
}
}
@@ -478,7 +502,7 @@ void util_fmt_obj_end(void)
{
_util_fmt_obj_end();
if (f.lvl == 1 && f.meta_done && f.type != FMT_JSONSEQ) {
if (f.lvl == 1 && f.meta_done && !util_fmt_is_json_stream(f.type)) {
/* Emit closure for top-level meta-container object. */
util_fmt_obj_end();
}
@@ -737,7 +761,7 @@ void util_fmt_init(FILE *fd, enum util_fmt_t type, unsigned int flags,
f.do_warn = (flags & FMT_WARN);
f.handle_int = (flags & FMT_HANDLEINT);
f.api_level = api_level;
if (type == FMT_JSONSEQ)
if (util_fmt_is_json_stream(type))
f.nl = "";
else
f.nl = "\n";
@@ -750,6 +774,7 @@ void util_fmt_init(FILE *fd, enum util_fmt_t type, unsigned int flags,
break;
case FMT_JSON:
case FMT_JSONSEQ:
case FMT_JSONL:
f.obj_start = &json_obj_start;
f.obj_end = &json_obj_end;
f.map = &json_map;

View File

@@ -193,6 +193,9 @@ int main(int UNUSED(argc), char *UNUSED(argv[]))
announce("JSON formatted as sequence");
simple_example(FMT_JSONSEQ, FMT_DEFAULT);
announce("JSON Lines format");
simple_example(FMT_JSONL, FMT_DEFAULT);
announce("Pairs output");
simple_example(FMT_PAIRS, FMT_KEEPINVAL);
@@ -232,6 +235,9 @@ int main(int UNUSED(argc), char *UNUSED(argv[]))
announce("JSON sequence output with meta-data");
meta_example(FMT_JSONSEQ);
announce("JSON Lines output with meta-data");
meta_example(FMT_JSONL);
announce("Pairs output with meta-data");
meta_example(FMT_PAIRS);

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

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

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

@@ -26,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,
@@ -52,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,
@@ -60,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
};
@@ -144,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:
@@ -172,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;
@@ -186,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;
@@ -201,8 +201,8 @@ char * vtoc_ebcdic_dec (char *source, char *target, int l)
*
*/
void vtoc_set_extent (extent_t *ext, uint8_t typeind, uint8_t seqno,
cchh_t *lower, cchh_t *upper)
{
cchh_t *lower, cchh_t *upper)
{
ext->typeind = typeind;
ext->seqno = seqno;
memcpy(&ext->llimit,lower,sizeof(cchh_t));
@@ -307,7 +307,7 @@ uint32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
/*
*
*/
void vtoc_set_date (labeldate_t * d, uint8_t year, uint16_t day)
void vtoc_set_date (labeldate_t * d, uint8_t year, uint16_t day)
{
d->year = year;
d->day = day;
@@ -320,7 +320,7 @@ void vtoc_set_date (labeldate_t * d, uint8_t year, uint16_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);
}
@@ -329,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;
@@ -360,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;
@@ -375,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,
@@ -418,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)
@@ -436,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;
}
}
/*
@@ -475,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) {
@@ -536,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,
@@ -550,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,
@@ -560,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,
@@ -571,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,
@@ -582,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,
@@ -593,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,
@@ -619,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,
@@ -627,7 +627,7 @@ vtoc_init_format4_label (
unsigned int tracks,
unsigned int blocks,
unsigned int blksize,
uint16_t dev_type)
uint16_t dev_type)
{
int i;
@@ -701,7 +701,7 @@ 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;
@@ -715,7 +715,7 @@ 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;
@@ -829,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,
uint16_t unused_update)
uint16_t unused_update)
{
/* update highest address of a format 1 label */
memcpy(&f4->DS4HPCHR, highest_f1, sizeof(cchhb_t));
@@ -847,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
@@ -863,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;
@@ -891,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,
uint16_t a,
uint16_t b,
uint8_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 " \
@@ -925,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;
@@ -958,12 +958,12 @@ vtoc_update_format5_label_add (format5_label_t *f5,
ext->ft = (tmp->ft + ext->ft) % trk;
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)
{
@@ -973,12 +973,12 @@ vtoc_update_format5_label_add (format5_label_t *f5,
ext->ft = (tmp->ft + ext->ft) % trk;
memset(tmp, 0, sizeof(ds5ext_t));
tmp = ext;
if (verbose)
if (verbose)
printf("FMT5 add extent: " \
"merge with successor\n");
i = -1;
continue;
}
}
}
}
@@ -986,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,
uint16_t a,
uint16_t b,
uint8_t c)
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
@@ -1010,7 +1010,7 @@ vtoc_update_format5_label_del (format5_label_t *f5,
{
/* fills up whole free space gap */
memset(ext, 0, sizeof(ds5ext_t));
if (verbose)
if (verbose)
printf("FMT5 del extent: fills whole gap\n");
counter++;
break;
@@ -1030,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 */
@@ -1050,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;
@@ -1074,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;
@@ -1088,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 " \
@@ -1113,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;
@@ -1150,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,
uint32_t a, uint32_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");
@@ -1173,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;
}
@@ -1185,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)
@@ -1198,12 +1198,12 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
ext->b = tmp->b;
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))
{
@@ -1211,12 +1211,12 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
ext->a = tmp->a;
memset(tmp, 0, sizeof(ds7ext_t));
tmp = ext;
if (verbose)
if (verbose)
printf("FMT7 add extent: " \
"merge with successor\n");
i = -1;
continue;
}
}
}
}
@@ -1224,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,
uint32_t a, uint32_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 */
memset(ext, 0, sizeof(ds7ext_t));
if (verbose)
if (verbose)
printf("FMT7 del extent: fills whole gap\n");
counter++;
break;
@@ -1248,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;
@@ -1257,7 +1257,7 @@ 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;
@@ -1265,16 +1265,16 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
if ((a > ext->a) && (b < ext->b)) {
/* partition divides free space into 2 pieces */
vtoc_update_format7_label_add(f7, verbose,
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 "

View File

@@ -1,5 +1,10 @@
include ../common.mak
zsh-completions = _lsstp
bash-completions = lsstp.bash
include ../common_autocomp.mak
libs = $(rootdir)/libutil/libutil.a
all: lsstp

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "lsstp_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "lsstp");
return 0;
}

View File

@@ -22,6 +22,8 @@
#include "lib/util_prg.h"
#include "lib/util_path.h"
#include "lsstp_cli.h"
static const struct util_prg prg = {
.desc = "Display STP system information",
.args = "",
@@ -34,12 +36,6 @@ static const struct util_prg prg = {
}
};
static struct util_opt opt_vec[] = {
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
struct stp_parms {
uint64_t ctn_id;
unsigned int online;

18
lsstp/lsstp_cli.h Normal file
View File

@@ -0,0 +1,18 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef LSSTP_CLI_H
#define LSSTP_CLI_H
#include "lib/util_opt.h"
static struct util_opt opt_vec[] = {
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

View File

@@ -2,6 +2,11 @@ include ../common.mak
TESTS := tests/
zsh-completions = _opticsmon
bash-completions = opticsmon.bash
include ../common_autocomp.mak
libs =$(rootdir)/libzpci/libzpci.a $(rootdir)/libutil/libutil.a
ifneq (${HAVE_OPENSSL},0)

View File

@@ -0,0 +1,16 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#include "lib/util_autocomp.h"
#include "opticsmon_cli.h"
int main(void)
{
generate_autocomp(opt_vec, "opticsmon");
return 0;
}

View File

@@ -45,7 +45,7 @@ opticsmon - Monitor optical modules for directly attached PCI based NICs
Use
.B opticsmon
to monitor the health of the optical modules of directly attached PCI based
NICs. When executed without the \fB--daemon\fR option it will collect optical
NICs. When executed without the \fB--monitor\fR option it will collect optical
module data from all available PCI network interface physical functions and
print a summary in JSON format. Add the \fB--send-report\fR option to report
this data to the support element.
@@ -55,7 +55,7 @@ this data to the support element.
.
.SH OPTIONS
.SS Operation Options
.OD daemon "d"
.OD monitor "m"
Run continuously and report on link state changes and periodically
.PP
.

View File

@@ -27,10 +27,11 @@
#include <openssl/evp.h>
#include "optics_info.h"
#include "optics_sclp.h"
#include "ethtool.h"
#include "link_mon.h"
#include "optics_info.h"
#include "optics_sclp.h"
#include "opticsmon_cli.h"
#define API_LEVEL 1
@@ -61,44 +62,6 @@ static const struct util_prg prg = {
UTIL_PRG_COPYRIGHT_END }
};
#define OPT_DUMP 128
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPERATION OPTIONS"),
{
.option = { "monitor", no_argument, NULL, 'm' },
.desc = "Run continuously and report on link state changes "
"collecting optics health data when a change is detected",
},
{
.option = { "send-report", no_argument, NULL, 'r' },
.desc = "Report the optics health data to the Support Element",
},
{
.option = { "quiet", no_argument, NULL, 'q' },
.desc = "Be quiet and don't print optics health summary",
},
{
.option = { "module-info", no_argument, NULL, OPT_DUMP },
.desc = "Include a base64 encoded binary dump of the module's "
"SFF-8636/8472/8024 standard data for each netdev. "
"This matches \"ethtool --module-info <netdev> raw on\"",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("OPTIONS WITH ARGUMENTS"),
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "seconds",
.desc = "Interval in seconds at which to collect monitoring data "
"in the absence of link state changes. A value larger than "
"24 hours (86400 seconds) is clamped down to 24 hours.",
},
UTIL_OPT_SECTION("GENERAL OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
static void parse_cmdline(int argc, char *argv[], struct options *opts)
{
uint32_t seconds;

50
opticsmon/opticsmon_cli.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright IBM Corp.
*/
#ifndef OPTICSMON_CLI_H
#define OPTICSMON_CLI_H
#include "lib/util_opt.h"
#define OPT_DUMP 128
static struct util_opt opt_vec[] = {
UTIL_OPT_SECTION("OPERATION OPTIONS"),
{
.option = { "monitor", no_argument, NULL, 'm' },
.desc = "Run continuously and report on link state changes "
"collecting optics health data when a change is detected",
},
{
.option = { "send-report", no_argument, NULL, 'r' },
.desc = "Report the optics health data to the Support Element",
},
{
.option = { "quiet", no_argument, NULL, 'q' },
.desc = "Be quiet and don't print optics health summary",
},
{
.option = { "module-info", no_argument, NULL, OPT_DUMP },
.desc = "Include a base64 encoded binary dump of the module's "
"SFF-8636/8472/8024 standard data for each netdev. "
"This matches 'ethtool --module-info <netdev> raw on'",
.flags = UTIL_OPT_FLAG_NOSHORT,
},
UTIL_OPT_SECTION("OPTIONS WITH ARGUMENTS"),
{
.option = { "interval", required_argument, NULL, 'i' },
.argument = "seconds",
.desc = "Interval in seconds at which to collect monitoring data "
"in the absence of link state changes. A value larger than "
"24 hours (86400 seconds) is clamped down to 24 hours.",
},
UTIL_OPT_SECTION("GENERAL OPTIONS"),
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
};
#endif

149
rust/Cargo.lock generated
View File

@@ -62,9 +62,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.95"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "autocfg"
@@ -111,6 +111,15 @@ dependencies = [
"wyz",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "byteorder"
version = "1.5.0"
@@ -132,6 +141,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"
@@ -203,6 +221,25 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "curl"
version = "0.4.49"
@@ -293,6 +330,16 @@ dependencies = [
"syn",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "enum_dispatch"
version = "0.3.13"
@@ -354,6 +401,16 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.16"
@@ -395,6 +452,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -632,11 +695,26 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "pvebc"
version = "0.12.0"
dependencies = [
"anyhow",
"clap",
"clap_complete",
"hex",
"s390_pv_core",
"sha2",
"utils",
"zerocopy",
]
[[package]]
name = "pvimg"
version = "0.12.0"
dependencies = [
"anyhow",
"base64",
"clap",
"clap_complete",
"deku",
@@ -677,6 +755,7 @@ dependencies = [
"s390_pv",
"serde_yaml",
"utils",
"zerocopy",
]
[[package]]
@@ -881,6 +960,7 @@ dependencies = [
"regex",
"serde",
"serde_test",
"sha2",
"thiserror",
"zerocopy",
]
@@ -896,18 +976,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",
@@ -916,13 +1006,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]]
@@ -947,6 +1039,17 @@ dependencies = [
"unsafe-libyaml",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
@@ -1047,6 +1150,12 @@ dependencies = [
"winnow",
]
[[package]]
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unarray"
version = "0.1.4"
@@ -1075,11 +1184,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
name = "utils"
version = "0.12.0"
dependencies = [
"chrono",
"clap",
"libc",
"log",
"s390_pv",
"serde",
"serde_json",
]
[[package]]
@@ -1088,6 +1199,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wait-timeout"
version = "0.2.0"
@@ -1214,20 +1331,26 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.25"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

View File

@@ -5,6 +5,7 @@ members = [
"pv_core",
"pvapconfig",
"pvattest",
"pvebc",
"pvimg",
"pvinfo",
"pvsecret",

View File

@@ -10,8 +10,10 @@ CARGO_TARGETS :=
PV_TARGETS :=
CARGO_TEST_TARGETS :=
SEL_EBC_MODDIR := 95sel-ebc
ifneq (${HAVE_CARGO},0)
CARGO_TARGETS :=
CARGO_TARGETS := pvebc
BUILD_TARGETS = $(CARGO_TARGETS)
INSTALL_TARGETS := install-rust-tools install-man install-shell-completions
@@ -29,6 +31,7 @@ ifneq (${HAVE_LIBCURL},0)
ifeq ($(HOST_ARCH),s390x)
PV_TARGETS += pvapconfig pvinfo
INSTALL_TARGETS += install-ebc-dracut-module
else
BUILD_TARGETS += skip-pvapconfig skip-pvinfo
endif #HOSTARCH
@@ -104,6 +107,25 @@ endif # CARGO
rust-test: $(CARGO_TEST_TARGETS)
install-ebc-dracut-module:
ifneq ($(HAVE_DRACUT),0)
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(SEL_EBC_MODDIR)
$(INSTALL) -m 755 pvebc/$(SEL_EBC_MODDIR)/module-setup.sh \
pvebc/$(SEL_EBC_MODDIR)/override-crypttab.sh \
pvebc/$(SEL_EBC_MODDIR)/pvebc-wrapper.sh \
pvebc/$(SEL_EBC_MODDIR)/boot-mount.sh \
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-modules.conf \
$(DESTDIR)$(DRACUTMODDIR)/$(SEL_EBC_MODDIR)
$(INSTALL) -m 644 pvebc/$(SEL_EBC_MODDIR)/sel-ebc-boot-mount.service \
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-override-crypttab.service \
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-paes-enforce.service \
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-pvebc.service \
pvebc/$(SEL_EBC_MODDIR)/sel-ebc.crypttab \
pvebc/$(SEL_EBC_MODDIR)/sel-ebc.target \
$(DESTDIR)$(DRACUTMODDIR)/$(SEL_EBC_MODDIR)
endif
install-rust-tools: $(BUILD_TARGETS)
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
$(foreach target,$(CARGO_TARGETS),\

View File

@@ -90,11 +90,11 @@ pub enum Error {
#[error("Input does not contain an attestation request")]
NoArcb,
#[error("The attestation request has an unknown version (.0)")]
#[error("The attestation request has an unknown version {0}")]
BinArcbInvVersion(u32),
#[error(
"The attestation request encrypted sice is to0 small (.0). Request probably tampered with."
"The attestation request encrypted sice is to0 small {0}. Request probably tampered with."
)]
BinArcbSeaSmall(u32),

View File

@@ -104,7 +104,14 @@ pub mod request {
/// Reexports some useful OpenSSL symbols
pub mod openssl {
pub use openssl::{error::ErrorStack, hash::DigestBytes, nid::Nid, pkey, x509};
pub use openssl::{
error::ErrorStack,
hash::DigestBytes,
nid::Nid,
pkey,
sha::{Sha256, Sha512},
x509,
};
// rust-OpenSSL does not define these NIDs
#[allow(missing_docs)]
pub const NID_ED25519: Nid = Nid::from_raw(openssl_sys::NID_ED25519);
@@ -113,6 +120,8 @@ pub mod request {
}
pub use pv_core::request::*;
pub use pv_core::PolicyReference;
}
/// Functionalities for creating add-secret requests

View File

@@ -53,14 +53,14 @@ pub enum GuestSecret {
},
/// Retrievable key
///
/// Create Retrievables using [`GuestSecret::retrievable`]
/// Create Retrievables using [`GuestSecret::Retrievable`]
/// Secret size is always valid for the type/kind
Retrievable {
/// Retrievable secret type
kind: RetrievableSecret,
/// Name of the secret
name: String,
/// SHA256 hash of [`GuestSecret::RetrievableKey::name`]
/// SHA256 hash of [`GuestSecret::Retrievable::name`]
id: SecretId,
/// Confidential actual retrievable secret
#[serde(skip)]

View File

@@ -248,7 +248,7 @@ fn check_key_format(kind: UserDataType, key: &PKeyRef<Public>) -> Result<()> {
///
/// # Returns
///
/// Extracrted user-data if available
/// Extracted user-data if available
///
/// # Errors
///

View File

@@ -23,6 +23,7 @@ zerocopy = {version = "0.8", features = ["derive"]}
serde = { version = "1.0.217", features = ["derive"]}
byteorder = "1.5"
regex = "1.10"
sha2 = "0.10.9"
[dev-dependencies]
serde_test = "1.0.177"

View File

@@ -6,6 +6,7 @@ mod apdevice;
mod confidential;
mod error;
mod macros;
mod policy;
mod utils;
mod uvattest;
mod uvdevice;
@@ -13,6 +14,13 @@ mod uvsecret;
pub use error::{Error, FileAccessErrorType, FileIoErrorType, Result};
/// Early Boot Customization (EBC) utilities.
///
/// This module provides types and functions for working with Early Boot
/// Customization. The integrity and completeness of ASRs are ensured through
/// cryptographically protected table of contents files.
pub use policy::PolicyReference;
/// Functionalities for reading attestation requests
pub mod attest {
pub use crate::uvattest::{AttestationMagic, AttestationMeasAlg};

112
rust/pv_core/src/policy.rs Normal file
View File

@@ -0,0 +1,112 @@
// SPDX-License-Identifier: MIT
//
// Copyright IBM Corp.
use crate::misc::encode_hex;
use crate::utils::open_file;
use crate::{Error, Result};
use std::{
fmt::{Display, Formatter, Result as Resfmt},
fs::File,
os::unix::ffi::OsStrExt,
path::{Path, PathBuf},
str::from_utf8,
};
use zerocopy::{FromBytes, Immutable, IntoBytes};
const HASH_LEN: usize = 32;
// UserDataType::Unsigned.max() returns 512
const USER_DATA_MAX_SIZE: usize = 512;
/// A reference to a policy file containing its SHA-256 hash and file path.
///
/// This structure is used in Early Boot Customization (EBC) to store
/// a reference to a policy file. It contains the SHA-256 hash of the policy
/// file content and the file path as a fixed-size byte array.
///
/// The total size is constrained by `USER_DATA_MAX_SIZE` (512 bytes), with
/// 32 bytes allocated for the hash and the remaining bytes for the file path.
#[derive(Debug, FromBytes, IntoBytes, Immutable, Copy, Clone)]
#[repr(C)]
pub struct PolicyReference {
/// SHA-256 hash of the policy file content (32 bytes)
pub hash: [u8; HASH_LEN],
/// File path stored as a null-terminated byte array
pub name: [u8; USER_DATA_MAX_SIZE - HASH_LEN],
}
impl PolicyReference {
/// Creates a new `PolicyReference` from a file path.
///
/// Opens the file, reads its content, and computes the SHA-256 hash.
///
/// # Parameters
///
/// * `src` - The path to the policy file
/// * `sha256` - A function that computes the SHA-256 hash of the content
///
/// # Returns
///
/// Returns a `PolicyReference` containing the SHA-256 hash and the file path,
/// or an error if the file cannot be opened or the hash computation fails.
///
/// # Note
///
/// The file path is truncated if it exceeds the available space in the `name` field.
pub fn new<P, H>(src: P, sha256: H) -> Result<Self>
where
P: AsRef<Path>,
H: Fn(File) -> Result<Vec<u8>>,
{
let mut ret = Self {
hash: [0; HASH_LEN],
name: [0; USER_DATA_MAX_SIZE - HASH_LEN],
};
let file = open_file(src.as_ref())?;
ret.hash.copy_from_slice(sha256(file)?.as_bytes());
let strbytes = src.as_ref().as_os_str().as_bytes();
let nbytes = strbytes.len().min(ret.name.len());
ret.name[..nbytes].copy_from_slice(&strbytes[..nbytes]);
Ok(ret)
}
/// Converts the stored file path back to a `PathBuf`.
///
/// # Returns
///
/// Returns the file path as a `PathBuf`, or an error if the stored name
/// is not valid UTF-8.
///
/// # Errors
///
/// * `Error::ParseError` - If the name contains invalid UTF-8
pub fn to_path(&self) -> Result<PathBuf> {
// Extract bytes until the first null byte (null-terminated string)
let name_bytes: Vec<u8> = self
.name
.iter()
.copied()
.take_while(|&byte| byte != 0)
.collect();
let rust_string = String::from_utf8(name_bytes).map_err(|e| Error::ParseError {
subject: "PolicyReference name".to_string(),
content: format!("Invalid UTF-8 in name: {}", e),
})?;
Ok(Path::new(&rust_string).to_owned())
}
}
impl Display for PolicyReference {
fn fmt(&self, f: &mut Formatter) -> Resfmt {
write!(
f,
"{} {}",
encode_hex(self.hash),
from_utf8(&self.name).expect("unable to convert name")
)
}
}

View File

@@ -1,5 +1,5 @@
<!--
Copyright 2024 IBM Corp.
Copyright 2024, 2026 IBM Corp.
s390-tools is free software; you can redistribute it and/or modify
it under the terms of the MIT license. See LICENSE for details.
-->
@@ -17,7 +17,7 @@ Create an attestation measurement request
- **perform**
<ul>
Send the attestation request to the Ultravisor
Send the attestation request to the Ultravisor (s390x only.)
</ul>
- **verify**
@@ -150,11 +150,11 @@ Print help (see a summary with '-h').
### Synopsis
`pvattest perform [OPTIONS] [IN] [OUT]`
### Description
Send the attestation request to the Ultravisor. Run a measurement of this system
through /dev/uv. This device must be accessible and the attestation
Ultravisor facility must be present. The input must be an attestation request
created with pvattest create. Output will contain the original request and
the response from the Ultravisor.
Send the attestation request to the Ultravisor (s390x only.) Run a measurement
of this system through /dev/uv. This device must be accessible and the
attestation Ultravisor facility must be present. The input must be an
attestation request created with pvattest create. Output will contain the
original request and the response from the Ultravisor. Only available on s390x.
### Arguments
`<IN>`
@@ -171,6 +171,18 @@ Write the result to FILE.
### Options
`-i`, `--input <FILE>`
<ul>
Specify the request to be sent.
</ul>
`-o`, `--output <FILE>`
<ul>
Write the result to FILE.
</ul>
`-u`, `--user-data <File>`
<ul>
Provide up to 256 bytes of user input User-data is arbitrary user-defined data
@@ -256,7 +268,7 @@ Print help (see a summary with '-h').
## pvattest check
### Synopsis
`pvattest check [OPTIONS] <IN> <OUT>`
`pvattest check [OPTIONS] [IN] [OUT]`
### Description
Check if the attestation result matches defined policies. After the attestation
verification, check whether the attestation result complies with user-defined
@@ -277,6 +289,18 @@ Specify the output file for the check result.
### Options
`-i`, `--input <FILE>`
<ul>
Specify the attestation response to check whether the policies are validated.
</ul>
`-o`, `--output <FILE>`
<ul>
Specify the output file for the check result.
</ul>
`--format <FORMAT>`
<ul>
Define the output format.

View File

@@ -3,7 +3,7 @@
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH "PVATTEST-CHECK" "1" "2025-03-12" "s390-tools" "Attestation Manual"
.TH "PVATTEST-CHECK" "1" "2026-05-19" "s390-tools" "Attestation Manual"
.nh
.ad l
.SH NAME
@@ -11,7 +11,7 @@ pvattest-check \- Check if the attestation result matches defined policies
.SH SYNOPSIS
.nf
.fam C
pvattest check [OPTIONS] <IN> <OUT>
pvattest check [OPTIONS] [IN] [OUT]
.fam C
.fi
.SH DESCRIPTION
@@ -31,6 +31,18 @@ Specify the output file for the check result.
.RE
.RE
.PP
\-i, \-\-input <FILE>
.RS 4
Specify the attestation response to check whether the policies are validated.
.RE
.RE
.PP
\-o, \-\-output <FILE>
.RS 4
Specify the output file for the check result.
.RE
.RE
.PP
\-\-format <FORMAT>
.RS 4

View File

@@ -3,7 +3,7 @@
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH "PVATTEST-CREATE" "1" "2025-03-12" "s390-tools" "Attestation Manual"
.TH "PVATTEST-CREATE" "1" "2026-05-20" "s390-tools" "Attestation Manual"
.nh
.ad l
.SH NAME
@@ -11,7 +11,7 @@ pvattest-create \- Create an attestation measurement request
.SH SYNOPSIS
.nf
.fam C
pvattest create [OPTIONS] --host-key-document <FILE> --output <FILE> --arpk <FILE> <--no-verify|--cert <FILE>>
pvattest create [OPTIONS] \-\-host\-key\-document <FILE> \-\-output <FILE> \-\-arpk <FILE> <\-\-no\-verify|\-\-cert <FILE>>
.fam C
.fi
.SH DESCRIPTION
@@ -21,6 +21,7 @@ Workstation. To avoid compromising the attestation do not publish the
attestation request protection key and shred it after verification. Every
\fBcreate\fR will generate a new, random protection key.
.SH OPTIONS
.PP
\-k, \-\-host\-key\-document <FILE>
.RS 4
@@ -107,15 +108,15 @@ Print help (see a summary with \fB\-h\fR).
.RE
.SH EXAMPLES
Create an attestation request with the protection key 'arp.key', write the request to 'arcb.bin', and verify the host-key document using the CA-signed key 'DigiCertCA.crt' and the intermediate key 'IbmSigningKey.crt'.
Create an attestation request with the protection key 'arp.key', write the request to 'arcb.bin', and verify the host\-key document using the CA\-signed key 'DigiCertCA.crt' and the intermediate key 'IbmSigningKey.crt'.
.PP
.nf
.fam C
$ pvattest create \-k hkd.crt -\-\arpk arp.key \-o attreq.bin \-\-cert DigiCertCA.crt \-\-cert IbmSigningKey.crt
$ pvattest create \-k hkd.crt \-\-\arpk arp.key \-o attreq.bin \-\-cert DigiCertCA.crt \-\-cert IbmSigningKey.crt
.fam T
.fi
Create an attestation request with the protection key 'arp.key', write the request to 'arcb.bin', verify the host-key document using the CA-signed key 'DigiCertCA.crt' and the intermediate key 'IbmSigningKey.crt', and instead of downloading the certificate revocation list use certificate revocation lists 'DigiCertCA.crl', 'IbmSigningKey.crl', and 'rootCA.crl'.
Create an attestation request with the protection key 'arp.key', write the request to 'arcb.bin', verify the host\-key document using the CA\-signed key 'DigiCertCA.crt' and the intermediate key 'IbmSigningKey.crt', and instead of downloading the certificate revocation list use certificate revocation lists 'DigiCertCA.crl', 'IbmSigningKey.crl', and 'rootCA.crl'.
.PP
.nf
.fam C

View File

@@ -3,11 +3,11 @@
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH "PVATTEST-PERFORM" "1" "2025-03-12" "s390-tools" "Attestation Manual"
.TH "PVATTEST-PERFORM" "1" "2026-05-19" "s390-tools" "Attestation Manual"
.nh
.ad l
.SH NAME
pvattest-perform \- Send the attestation request to the Ultravisor
pvattest-perform \- Send the attestation request to the Ultravisor (s390x only.)
.SH SYNOPSIS
.nf
.fam C
@@ -18,7 +18,8 @@ pvattest perform [OPTIONS] [IN] [OUT]
Run a measurement of this system through /dev/uv. This device must be
accessible and the attestation Ultravisor facility must be present. The input
must be an attestation request created with pvattest create. Output will
contain the original request and the response from the Ultravisor.
contain the original request and the response from the Ultravisor. Only
available on s390x.
.SH OPTIONS
.PP
<IN>
@@ -33,6 +34,18 @@ Write the result to FILE.
.RE
.RE
.PP
\-i, \-\-input <FILE>
.RS 4
Specify the request to be sent.
.RE
.RE
.PP
\-o, \-\-output <FILE>
.RS 4
Write the result to FILE.
.RE
.RE
.PP
\-u, \-\-user\-data <File>
.RS 4

View File

@@ -3,7 +3,7 @@
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH "PVATTEST-VERIFY" "1" "2025-03-12" "s390-tools" "Attestation Manual"
.TH "PVATTEST-VERIFY" "1" "2026-05-20" "s390-tools" "Attestation Manual"
.nh
.ad l
.SH NAME
@@ -11,7 +11,7 @@ pvattest-verify \- Verify an attestation response
.SH SYNOPSIS
.nf
.fam C
pvattest verify [OPTIONS] --input <FILE> --hdr <FILE> --arpk <FILE>
pvattest verify [OPTIONS] \-\-input <FILE> \-\-hdr <FILE> \-\-arpk <FILE>
.fam C
.fi
.SH DESCRIPTION
@@ -26,6 +26,7 @@ solely verifies that the Attestation measurement is correct. It does not check
for the content of additional data or user data. See `pvattest check` for policy
checks after you verified the Attestation measurement.
.SH OPTIONS
.PP
\-i, \-\-input <FILE>
.RS 4
@@ -83,25 +84,25 @@ Print help (see a summary with \fB\-h\fR).
.SH EXIT STATUS
.TP 8
.B 0 - Attestation Verified
.B 0 \- Attestation Verified
Attesatation measurement verified successfully. Measured guest is in Secure Execution mode.
.RE
.TP 8
.B 1 - Program Error
.B 1 \- Program Error
Something went wrong during the local calculation or receiving of the measurement value. Refer to the error message.
.RE
.TP 8
.B 2 - Attestation NOT Verified
.B 2 \- Attestation NOT Verified
Attesation measurement calculation does not match the received value. Measured guest is very likely not in Secure Execution mode.
.RE
.SH EXAMPLES
To verify a measurement in 'measurement.bin' with the protection key 'arp.kep' and SE-guest header 'se_guest.hdr'.
To verify a measurement in 'measurement.bin' with the protection key 'arp.kep' and SE\-guest header 'se_guest.hdr'.
.PP
.nf
.fam C
$ pvattest verify --input attresp.bin --arpk arp.key --hdr se_guest.hdr
$ pvattest verify \-\-input attresp.bin \-\-arpk arp.key \-\-hdr se_guest.hdr
.fam T
.fi

View File

@@ -3,7 +3,7 @@
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH "PVATTEST" "1" "2025-03-12" "s390-tools" "Attestation Manual"
.TH "PVATTEST" "1" "2026-05-19" "s390-tools" "Attestation Manual"
.nh
.ad l
.SH NAME
@@ -20,33 +20,34 @@ guest systems.
.SH "PVATTEST COMMANDS"
.PP
\fBpvattest-create(1)\fR
\fBpvattest\-create(1)\fR
.RS 4
Create an attestation measurement request
.RE
.PP
\fBpvattest-perform(1)\fR
\fBpvattest\-perform(1)\fR
.RS 4
Send the attestation request to the Ultravisor
Send the attestation request to the Ultravisor (s390x only.)
.RE
.PP
\fBpvattest-verify(1)\fR
\fBpvattest\-verify(1)\fR
.RS 4
Verify an attestation response
.RE
.PP
\fBpvattest-check(1)\fR
\fBpvattest\-check(1)\fR
.RS 4
Check if the attestation result matches defined policies
.RE
.SH OPTIONS
.PP
\-v, \-\-verbose
.RS 4
@@ -83,7 +84,7 @@ Create the request on a trusted system.
.fam T
.fi
On the SE-guest, \fIperform\fP the attestation.
On the SE\-guest, \fIperform\fP the attestation.
.PP
.nf
.fam C
@@ -91,7 +92,7 @@ On the SE-guest, \fIperform\fP the attestation.
.fam T
.fi
On a trusted system, \fIverify\fP that the response is correct. Here, the protection key from the creation and the SE-guests header is used to \fIverify\fP the measurement.
On a trusted system, \fIverify\fP that the response is correct. Here, the protection key from the creation and the SE\-guests header is used to \fIverify\fP the measurement.
.PP
.nf
.fam C
@@ -102,7 +103,7 @@ On a trusted system, \fIverify\fP that the response is correct. Here, the protec
.fam T
.fi
If the measurements do not match \fBpvattest\fP exits with code 2 and emits an error message. The SE-guest attestation failed.
If the measurements do not match \fBpvattest\fP exits with code 2 and emits an error message. The SE\-guest attestation failed.
.PP
.nf
.fam C
@@ -116,4 +117,4 @@ If the measurements do not match \fBpvattest\fP exits with code 2 and emits an e
.fi
.SH "SEE ALSO"
.sp
\fBpvattest-create\fR(1) \fBpvattest-perform\fR(1) \fBpvattest-verify\fR(1) \fBpvattest-check\fR(1)
\fBpvattest\-create\fR(1) \fBpvattest\-perform\fR(1) \fBpvattest\-verify\fR(1) \fBpvattest\-check\fR(1)

View File

@@ -35,12 +35,12 @@ pub enum Command {
/// shred it after verification. Every 'create' will generate a new, random protection key.
Create(Box<CreateAttOpt>),
/// Send the attestation request to the Ultravisor.
/// Send the attestation request to the Ultravisor (s390x only.)
///
/// Run a measurement of this system through /dev/uv. This device must be accessible and the
/// attestation Ultravisor facility must be present. The input must be an attestation request
/// created with pvattest create. Output will contain the original request and the response
/// from the Ultravisor.
/// from the Ultravisor. Only available on s390x.
Perform(PerformAttOpt),
/// Verify an attestation response.
@@ -110,28 +110,23 @@ pub enum AttAddFlags {
FirmwareState,
}
// all members s390x only
#[derive(Args, Debug)]
pub struct PerformAttOpt {
/// Specify the request to be sent.
#[cfg(target_arch = "s390x")]
#[arg(hide=true, short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
pub input: Option<String>,
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
input: Option<String>,
/// Specify the request to be sent.
#[cfg(target_arch = "s390x")]
#[arg(value_name = "IN", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
pub input_pos: Option<String>,
input_pos: Option<String>,
/// Write the result to FILE.
#[cfg(target_arch = "s390x")]
#[arg(hide=true, short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
pub output: Option<String>,
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
output: Option<String>,
/// Write the result to FILE.
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath, required_unless_present("output"), conflicts_with("output"))]
#[cfg(target_arch = "s390x")]
pub output_pos: Option<String>,
output_pos: Option<String>,
/// Provide up to 256 bytes of user input
///
@@ -139,7 +134,7 @@ pub struct PerformAttOpt {
/// It is verified during the Attestation measurement verification.
/// May be any arbitrary data, as long as it is less or equal to 256 bytes
#[arg(short, long, value_name = "File", value_hint = ValueHint::FilePath,)]
pub user_data: Option<String>,
user_data: Option<String>,
}
#[cfg(target_arch = "s390x")]
@@ -222,12 +217,20 @@ pub enum OutputType {
#[derive(Args, Debug)]
pub struct CheckOpt {
/// Specify the attestation response to check whether the policies are validated.
#[arg(value_name = "IN", value_hint = ValueHint::FilePath,)]
pub input: PathBuf,
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
input: Option<PathBuf>,
/// Specify the attestation response to check whether the policies are validated.
#[arg(value_name = "IN", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
input_pos: Option<PathBuf>,
/// Specify the output file for the check result.
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath,)]
pub output: PathBuf,
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
output: Option<PathBuf>,
/// Specify the output file for the check result.
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath, required_unless_present("output"), conflicts_with("output"))]
output_pos: Option<PathBuf>,
/// Define the output format.
#[arg(long, value_enum, default_value_t)]
@@ -305,6 +308,30 @@ pub struct CheckOpt {
pub firmware_verify_url: Option<String>,
}
#[derive(Debug)]
pub struct CheckOptIO<'a> {
pub input: &'a PathBuf,
pub output: &'a PathBuf,
}
impl<'a> From<&'a CheckOpt> for CheckOptIO<'a> {
fn from(value: &'a CheckOpt) -> Self {
let input = match (&value.input, &value.input_pos) {
(None, Some(i)) => i,
(Some(i), None) => i,
(Some(_), Some(_)) => unreachable!(),
(None, None) => unreachable!(),
};
let output = match (&value.output, &value.output_pos) {
(None, Some(o)) => o,
(Some(o), None) => o,
(Some(_), Some(_)) => unreachable!(),
(None, None) => unreachable!(),
};
Self { input, output }
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
pub enum HostKeyCheckPolicy {
/// Check the host-key used for the attestation request.

View File

@@ -12,7 +12,12 @@ use self::{
secret_store::secret_store_check,
secret_store::SecretStoreCheck,
};
use crate::{additional::AttestationResult, cli::CheckOpt, exchange::ExchangeFormatResponse};
use crate::{
additional::AttestationResult,
cli::{CheckOpt, CheckOptIO},
exchange::ExchangeFormatResponse,
};
use anyhow::Result;
use log::{debug, info, warn};
use pv::{
@@ -104,7 +109,8 @@ pub struct CheckResult<'a> {
/// Perform the policy checks
pub fn check(opt: &CheckOpt) -> Result<ExitCode> {
let mut input = open_file(&opt.input)?;
let opt_io = CheckOptIO::from(opt);
let mut input = open_file(opt_io.input)?;
let inp = ExchangeFormatResponse::read(&mut input)?;
let auth = AttestationRequest::auth_bin(inp.arcb())?;
let att_res = AttestationResult::from_exchange(&inp, auth.flags())?;
@@ -139,7 +145,7 @@ pub fn check(opt: &CheckOpt) -> Result<ExitCode> {
};
debug!("res {res:?}");
let output = create_file(&opt.output)?;
let output = create_file(opt_io.output)?;
serde_yaml::to_writer(output, &res)?;
match res.successful {

View File

@@ -13,8 +13,8 @@ use serde::{Deserialize, Serialize};
use super::{bail_check, CheckState};
use crate::{additional::AttestationResult, cli::CheckOpt};
const CHECK_DEFAULT_ENDP: &str = "https://www.ibm.com/support/resourcelink/api";
const VERIFY_API: &str = "firmware-attestation/verify/v1";
const CHECK_DEFAULT_ENDP: &str = "https://esupport.ibm.com/eccedge/ent/z";
const VERIFY_API: &str = "hmrs/firmware/attestation/v1/verify";
const TIMEOUT_MAX: Duration = Duration::from_secs(3);
const USER_AGENT: &str = "s390-tools-pvattest";
const CONTENT_TYPE: &str = "Content-Type: application/json";

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
//
// Copyright IBM Corp. 2024
#![allow(unused)]
use anyhow::{anyhow, bail, Error, Result};
use pv::{assert_size, request::MagicValue, uv::AttestationCmd, uv::ConfigUid};
use std::{

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