mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
178 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e07b30bdf | ||
|
|
35596e1dd7 | ||
|
|
0311cf7c5e | ||
|
|
78fdf56d38 | ||
|
|
b5c4ff68d7 | ||
|
|
3b0fc8cfda | ||
|
|
8d40b5c97a | ||
|
|
ad4075804f | ||
|
|
126ba7e336 | ||
|
|
1d2a89b387 | ||
|
|
7c4b029020 | ||
|
|
b5a750c2cc | ||
|
|
893667e73e | ||
|
|
95fb1e2b03 | ||
|
|
87966251c4 | ||
|
|
012025595f | ||
|
|
48c8fc8321 | ||
|
|
19995638e9 | ||
|
|
91ee8e0593 | ||
|
|
238ca83b99 | ||
|
|
df8aac7084 | ||
|
|
8ad28f7856 | ||
|
|
dd818ccc15 | ||
|
|
e7203069cc | ||
|
|
d4ee1ff01f | ||
|
|
9c60ceccd4 | ||
|
|
6da56acf4b | ||
|
|
365be71dfc | ||
|
|
789b097d3a | ||
|
|
06df08ae49 | ||
|
|
56a656f1c9 | ||
|
|
8efd4da53b | ||
|
|
d2efda1ac2 | ||
|
|
aa29a5f1f9 | ||
|
|
28815d3928 | ||
|
|
65a891fa35 | ||
|
|
5dc39e87e7 | ||
|
|
3358a30dae | ||
|
|
d7ba322d69 | ||
|
|
3123f56765 | ||
|
|
eb881c2a39 | ||
|
|
5c2e6fd730 | ||
|
|
47cac92ca2 | ||
|
|
11f2ccb957 | ||
|
|
5b909a40cb | ||
|
|
591eb30854 | ||
|
|
3083f5dc85 | ||
|
|
2325d94453 | ||
|
|
fef70e3e95 | ||
|
|
808b766407 | ||
|
|
346a69e5a9 | ||
|
|
52ddd291d4 | ||
|
|
4cf239b8b6 | ||
|
|
b292ce565f | ||
|
|
75ab455cf6 | ||
|
|
25088b340b | ||
|
|
8edc5558b5 | ||
|
|
cd93949d17 | ||
|
|
97136585da | ||
|
|
96d5b0bb02 | ||
|
|
771c794580 | ||
|
|
f11c71237e | ||
|
|
8dd5758341 | ||
|
|
20cc99feb7 | ||
|
|
9fa165de7a | ||
|
|
103a99fa34 | ||
|
|
c161c04392 | ||
|
|
8e74293c2d | ||
|
|
e14e0aa858 | ||
|
|
355700d606 | ||
|
|
ddf30feb89 | ||
|
|
0047fc162e | ||
|
|
d9eee82ab0 | ||
|
|
a9059449b9 | ||
|
|
c3d8208a57 | ||
|
|
a2663ec8d3 | ||
|
|
12d9d24437 | ||
|
|
aca6704cfa | ||
|
|
3a85d1ebe6 | ||
|
|
e8f9244224 | ||
|
|
a49887de1f | ||
|
|
4e61b4c9f4 | ||
|
|
d884cc27c1 | ||
|
|
bf3810ea6a | ||
|
|
99d7ec51a7 | ||
|
|
327d132aac | ||
|
|
fcb89662e0 | ||
|
|
a52243ea04 | ||
|
|
805a4d4408 | ||
|
|
b1e4f6f331 | ||
|
|
10d72caac0 | ||
|
|
0ea693d95c | ||
|
|
0ff130ed84 | ||
|
|
8a57017af3 | ||
|
|
41ec030db1 | ||
|
|
34aff761d0 | ||
|
|
01cb8c4085 | ||
|
|
8d58a9abb0 | ||
|
|
ce82010827 | ||
|
|
c0d8034962 | ||
|
|
95290562e0 | ||
|
|
638cbbe332 | ||
|
|
70157462d8 | ||
|
|
40bc181f31 | ||
|
|
a2eb03660d | ||
|
|
f4c4c40b78 | ||
|
|
fe78faa8ae | ||
|
|
617a8248e8 | ||
|
|
c5695e43c4 | ||
|
|
7b3add9389 | ||
|
|
44fdf586e1 | ||
|
|
0d6e63abdc | ||
|
|
1771e7f2f3 | ||
|
|
c403208332 | ||
|
|
2a99007a6e | ||
|
|
994269c278 | ||
|
|
ae5687f1d1 | ||
|
|
b856ae62a7 | ||
|
|
7b4be02441 | ||
|
|
2403d1e166 | ||
|
|
3f03ceb007 | ||
|
|
150ae08678 | ||
|
|
43a10f4806 | ||
|
|
4e08c5fcd8 | ||
|
|
6532bf02c2 | ||
|
|
3f7b459606 | ||
|
|
14830b1ead | ||
|
|
1dae9b4f49 | ||
|
|
b58414d7dc | ||
|
|
64524f17fa | ||
|
|
1b87b016d4 | ||
|
|
94bdb17d01 | ||
|
|
2625cd704f | ||
|
|
59df2c6d02 | ||
|
|
8ba03642b7 | ||
|
|
1956e7abc5 | ||
|
|
d76cb1d53a | ||
|
|
7d5f2ba038 | ||
|
|
8bbf1d5bea | ||
|
|
b2fcb608d5 | ||
|
|
76b7928592 | ||
|
|
339b69cf3b | ||
|
|
419f042f55 | ||
|
|
128e5f86fe | ||
|
|
b29e824923 | ||
|
|
3175d52ce7 | ||
|
|
17024c02af | ||
|
|
5cd680c0be | ||
|
|
c333f91d4c | ||
|
|
095e5ee226 | ||
|
|
6ee5ffef91 | ||
|
|
82f8c137e1 | ||
|
|
b21a824fda | ||
|
|
f74b8d7d6f | ||
|
|
b766d4a53c | ||
|
|
a1126352ec | ||
|
|
35e539a428 | ||
|
|
99100b3f99 | ||
|
|
49faa1d7fd | ||
|
|
86ce85b3a6 | ||
|
|
b1c1bea4e2 | ||
|
|
e68547f06f | ||
|
|
95d784d866 | ||
|
|
783ae9735e | ||
|
|
5a78c7f45d | ||
|
|
586040a0ad | ||
|
|
deb61b5cd9 | ||
|
|
8be51ad454 | ||
|
|
cef50c2140 | ||
|
|
33bd112e2f | ||
|
|
2c31ed6f14 | ||
|
|
771623832b | ||
|
|
b8060baf44 | ||
|
|
76a0401deb | ||
|
|
e6ac87d7a2 | ||
|
|
0a711d4934 | ||
|
|
f90e913806 | ||
|
|
94a7ec22f2 |
@@ -10,3 +10,4 @@
|
||||
--ignore FILE_PATH_CHANGES
|
||||
--ignore NEW_TYPEDEFS
|
||||
--ignore SPDX_LICENSE_TAG
|
||||
--ignore STRNCPY
|
||||
|
||||
37
.clang-tidy
Normal file
37
.clang-tidy
Normal file
@@ -0,0 +1,37 @@
|
||||
Checks: >
|
||||
bugprone-*,
|
||||
clang-analyzer-*,
|
||||
misc-*,
|
||||
performance-*,
|
||||
portability-*,
|
||||
readability-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-misc-include-cleaner,
|
||||
-readability-braces-around-statements,
|
||||
-readability-identifier-length,
|
||||
-readability-isolate-declaration,
|
||||
-modernize-*,
|
||||
-performance-*,
|
||||
-portability-*,
|
||||
-readability-implicit-bool-conversion
|
||||
|
||||
CheckOptions:
|
||||
- key: readability-identifier-naming.VariableCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.FunctionCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.StructCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.EnumConstantCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.MacroDefinitionCase
|
||||
value: UPPER_CASE
|
||||
- key: bugprone-sizeof-expression.WarnOnSizeOfPointer
|
||||
value: true
|
||||
- key: misc-unused-parameters.StrictMode
|
||||
value: true
|
||||
|
||||
FormatStyle: file
|
||||
UseColor: true
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -25,6 +25,7 @@ compile_commands.json
|
||||
#
|
||||
**/.detect-openssl.dep.c
|
||||
*.debug
|
||||
*/autocompletion_generator_host
|
||||
ap_tools/ap-check
|
||||
cmsfs-fuse/cmsfs-fuse
|
||||
cpacfstats/cpacfstats
|
||||
@@ -34,8 +35,20 @@ cpumf/lscpumf
|
||||
cpumf/lshwc
|
||||
cpumf/lspai
|
||||
cpumf/pai
|
||||
cpumf/_chcpumf
|
||||
cpumf/_lscpumf
|
||||
cpumf/_lshwc
|
||||
cpumf/_lspai
|
||||
cpumf/_pai
|
||||
cpumf/chcpumf.bash
|
||||
cpumf/lscpumf.bash
|
||||
cpumf/lshwc.bash
|
||||
cpumf/lspai.bash
|
||||
cpumf/pai.bash
|
||||
cpuplugd/cpuplugd
|
||||
dasdfmt/dasdfmt
|
||||
dasdfmt/_dasdfmt
|
||||
dasdfmt/dasdfmt.bash
|
||||
dasdinfo/dasdinfo
|
||||
dasdview/dasdview
|
||||
dump2tar/src/dump2tar
|
||||
@@ -63,7 +76,7 @@ libekmfweb/check-dep-libekmfweb
|
||||
libekmfweb/detect-openssl-version.dep
|
||||
libekmfweb/libekmfweb.so
|
||||
libekmfweb/libekmfweb.so.1
|
||||
libekmfweb/libekmfweb.so.1.0
|
||||
libekmfweb/libekmfweb.so.1.1
|
||||
libkmipclient/check-dep-libkmipclient
|
||||
libkmipclient/detect-openssl-version.dep
|
||||
libkmipclient/libkmipclient.so
|
||||
@@ -119,7 +132,7 @@ ziomon/ziomon_zfcpdd
|
||||
ziomon/ziorep_traffic
|
||||
ziomon/ziorep_utilization
|
||||
zipl/boot/*.bin
|
||||
zipl/boot/*.exec
|
||||
zipl/boot/*.elf
|
||||
zipl/boot/.loaders
|
||||
zipl/boot/data.h
|
||||
zipl/src/chreipl_helper.device-mapper
|
||||
|
||||
13
AUTHORS.md
13
AUTHORS.md
@@ -1,13 +1,16 @@
|
||||
List of all individuals having contributed content to s390-tools
|
||||
----------------------------------------------------------------
|
||||
|
||||
- Ajaykumar Rajappa
|
||||
- Alexander Egorenkov
|
||||
- Alexandra Winter
|
||||
- Alexey Ishchuk
|
||||
- Andreas Herrmann
|
||||
- André Wild
|
||||
- Annu Sharma
|
||||
- Antoinette Kaschner
|
||||
- Arnd Bergmann
|
||||
- Aswin Karuvally
|
||||
- Axel Wirbser
|
||||
- Balint Reczey
|
||||
- Benjamin Block
|
||||
@@ -23,11 +26,13 @@ List of all individuals having contributed content to s390-tools
|
||||
- Dan Horak
|
||||
- Dan Horák
|
||||
- Daniel S. Haischt
|
||||
- Dean Doyle
|
||||
- Despina Papadopoulou
|
||||
- Dimitri John Ledkov
|
||||
- Eberhard Pasch
|
||||
- Eduard Shishkin
|
||||
- Einar Lueck
|
||||
- Ellen McIntyre
|
||||
- Eric Farman
|
||||
- Eric Sandeen
|
||||
- Erwin Vicari
|
||||
@@ -49,8 +54,8 @@ List of all individuals having contributed content to s390-tools
|
||||
- Graham Inggs
|
||||
- Guevenc Guelce
|
||||
- Hannes Reinecke
|
||||
- Hans-Joachim Picht
|
||||
- Hans Wippel
|
||||
- Hans-Joachim Picht
|
||||
- Harald Freudenberger
|
||||
- Heiko Carstens
|
||||
- Hendrik Brueckner
|
||||
@@ -72,12 +77,13 @@ List of all individuals having contributed content to s390-tools
|
||||
- Jens Remus
|
||||
- Jochen Roehrig
|
||||
- Joern Siglen
|
||||
- Jörn Siglen
|
||||
- Juergen Christ
|
||||
- Julian Wiedmann
|
||||
- Jörn Siglen
|
||||
- Karsten Graul
|
||||
- Kittipon Meesompop
|
||||
- Klaus-Dieter Wacker
|
||||
- L. E. Segovia
|
||||
- Lakhvich Dmitriy
|
||||
- Marc Hartmayer
|
||||
- Mario Held
|
||||
@@ -133,6 +139,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Sven Schnelle
|
||||
- Sven Schuetz
|
||||
- Swen Schillig
|
||||
- Szabina Korbai
|
||||
- Taraka R. Bodireddy
|
||||
- Thomas Heidrich
|
||||
- Thomas Huth
|
||||
@@ -149,7 +156,9 @@ List of all individuals having contributed content to s390-tools
|
||||
- Vasily Gorbik
|
||||
- Viktor Mihajlovski
|
||||
- Vineeth Vijayan
|
||||
- Volkan Unal
|
||||
- Volker Sameske
|
||||
- Wenjia Zhang
|
||||
- Wisdom Erhimwionsobo
|
||||
- Wolfgang Taphorn
|
||||
- Yaakov Selkowitz
|
||||
|
||||
64
CHANGELOG.md
64
CHANGELOG.md
@@ -1,6 +1,70 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.41.0 (2026-02-16)__
|
||||
|
||||
For Linux kernel version: 6.19
|
||||
|
||||
Changes of existing tools:
|
||||
- chreipl: Make --bootparms work for ECKD re-IPL
|
||||
- cpacfstats: Add 'unauthorized' state to CPU-MF counters
|
||||
- cpictl: Detect RHCOS using VARIANT_ID
|
||||
- hsci: Automatically set appropriate MTU for HSCI
|
||||
- libutil: Add util_readlink() and util_readlinkat() helpers
|
||||
- libutil: Add util_startswith() to util_str
|
||||
- libutil: Add utility parsing functions
|
||||
- lschp: Add support for structured output (--format)
|
||||
- lsreipl: Suppress 'clear' output if not supported
|
||||
- pvimg: Add '--format text' support to 'pvimg info'
|
||||
- pvimg: Add '--print-schema <FORMAT>' option to 'pvimg info'
|
||||
- pvimg: Add '--show-secrets' flag to 'pvimg info'
|
||||
- pvimg: Provide improved JSON output to 'pvimg info --format json'
|
||||
- pvinfo: Improve User experience on non-SE enabled systems
|
||||
- zipl/ngdump: Ensure ext4 file system is used on dump partition
|
||||
- zkey: Add support for integrity protected disks using HMAC keys
|
||||
|
||||
Bug Fixes:
|
||||
- cpumf/pai: Handle different size of perf_event_attr
|
||||
- lscss: Fix memory leak
|
||||
- zipl: Fix dump job on tape devices
|
||||
|
||||
* __v2.40.0 (2025-12-11)__
|
||||
|
||||
For Linux kernel version: 6.18
|
||||
|
||||
Add new tools / libraries:
|
||||
- Add project-wide .clang-tidy configuration
|
||||
- libutil: Introduce util_time for time related functionality
|
||||
- libutil: Introduce zsh/bash autocompletion tooling based on util_opt
|
||||
- pvinfo: Tool to display Secure Execution system information
|
||||
- pvverify: Tool to verify host-key documents
|
||||
|
||||
Changes of existing tools:
|
||||
- cpumf: Implement zsh and bash autocompletion
|
||||
- dasdfmt: Implement zsh and bash autocompletion
|
||||
- dbginfo.sh: Add NetworkManager and netplan
|
||||
- dbginfo.sh: Add kvm_stat
|
||||
- dbginfo.sh: Adding stp time information
|
||||
- dbginfo.sh: Simplify procfs collection
|
||||
- hyptop: Add physical information row
|
||||
- hyptop: Calculate sample time delta for physical partition
|
||||
- hyptop: Replace long option names using _ with - for consistency
|
||||
For example: --cpu_types -> --cpu-types
|
||||
(Options with _ are still supported for backward compatibility)
|
||||
- libekmfweb: Add function to validate a certificate against the identity key
|
||||
- netboot: Add longer kernel command lines support
|
||||
- udev/rules.d: Make virtio-blk devices non-rotational
|
||||
- udev/rules.d: Set default io scheduler to 'none' for virtio-blk
|
||||
- ziomon: Add support to sample device symlinks (/dev/disk/...)
|
||||
- ziorep_config: Add fcp-lun details to -M option output
|
||||
- ziorep_config: Add port_id and failed attributes to -A option output
|
||||
- netboot: Install on non-s390 architectures
|
||||
|
||||
Bug Fixes:
|
||||
- lib(ekmfweb|kmipclient): Use ln without -r
|
||||
- s390-tools: Fix various compilation issues with musl libc
|
||||
- zipl/boot: Fix unused loadparm when SCLP line-mode console is absent
|
||||
|
||||
* __v2.39.0 (2025-10-14)__
|
||||
|
||||
For Linux kernel version: 6.16 / 6.17
|
||||
|
||||
2
Makefile
2
Makefile
@@ -21,7 +21,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
else
|
||||
BASELIB_DIRS =
|
||||
LIB_DIRS = libpv
|
||||
TOOL_DIRS = rust
|
||||
TOOL_DIRS = netboot rust
|
||||
endif
|
||||
|
||||
SUB_DIRS = $(BASELIB_DIRS) $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
11
README.md
11
README.md
@@ -415,7 +415,7 @@ the different tools are provided:
|
||||
Removing the inflate modules and function prototypes are the only major
|
||||
modifications made to the kernel version of zlib.
|
||||
For stand-alone NVMe and list-directed DASD dump, the following tools/packages
|
||||
are required to populate dumper's initramfs:
|
||||
are required to populate dumper's initramfs and prepare a dump partition:
|
||||
- cat
|
||||
- cut
|
||||
- findmnt
|
||||
@@ -426,6 +426,7 @@ the different tools are provided:
|
||||
- sha256sum
|
||||
- sync
|
||||
- umount
|
||||
- mkfs.ext4
|
||||
|
||||
* zgetdump
|
||||
For building zgetdump you need OpenSSL version 1.1.0 or newer
|
||||
@@ -517,11 +518,11 @@ the different tools are provided:
|
||||
|
||||
* zkey:
|
||||
For building the zkey tools you need openssl version 0.9.7 or newer installed
|
||||
(openssl-devel.rpm). Also required are cryptsetup version 2.0.3 or newer
|
||||
(openssl-devel.rpm). Also required are cryptsetup version 2.8.2 or newer
|
||||
(cryptsetup-devel.rpm), and json-c version 0.12 or newer (json-c-devel.rpm).
|
||||
Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0`, and you may
|
||||
may skip the zkey-cryptsetup build by adding `HAVE_CRYPTSETUP2=0`, or
|
||||
`HAVE_JSONC=0` to the make invocation.
|
||||
Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0` or
|
||||
`HAVE_CRYPTSETUP2=0`, and you may skip the zkey-cryptsetup build
|
||||
by adding `HAVE_JSONC=0` to the make invocation.
|
||||
A new group 'zkeyadm' needs to be created and all users intending to use the
|
||||
tool must be added to this group. The owner of the default key repository
|
||||
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -129,7 +129,7 @@ else # $(ENABLE_DOC) != 1
|
||||
# freshness of the man page can be checked, even if `pandoc` is not available,
|
||||
# or ENABLE_DOC disabled.
|
||||
|
||||
MANPAGE_FRESH := $(shell sha256sum --check .chreipl-fcp-mpath.7.cksum >/dev/null && echo 1 || echo 0)
|
||||
MANPAGE_FRESH := $(shell sha256sum -c .chreipl-fcp-mpath.7.cksum >/dev/null && echo 1 || echo 0)
|
||||
ifeq ($(MANPAGE_FRESH),0)
|
||||
$(warning chreipl-fcp-mpath.7 is outdated, please regenerate it by calling `make ENABLE_DOC=1`)
|
||||
endif
|
||||
|
||||
18
common.mak
18
common.mak
@@ -32,7 +32,7 @@ endif
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION := 2
|
||||
RELEASE := 39
|
||||
RELEASE := 41
|
||||
PATCHLEVEL := 0
|
||||
DISTRELEASE := build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
@@ -119,6 +119,10 @@ ifneq ($(HOST_ARCH),$(BUILD_ARCH))
|
||||
endif
|
||||
endif
|
||||
|
||||
# *_FOR_BUILD variables define compilation configurations for binaries used
|
||||
# during the build process (e.g. autocompleteion script generators). This
|
||||
# is especially important for cross-compilation where these binaries need to
|
||||
# be executed on the build system.
|
||||
$(eval $(call define_toolchain_variables,_FOR_BUILD,))
|
||||
$(eval $(call define_toolchain_variables,,$(CROSS_COMPILE)))
|
||||
|
||||
@@ -165,7 +169,7 @@ ifeq ("${ENABLE_WERROR}", "1")
|
||||
endif
|
||||
|
||||
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
|
||||
DEFAULT_LDFLAGS = -rdynamic
|
||||
DEFAULT_LDFLAGS = -rdynamic -Wl,--as-needed
|
||||
|
||||
ifeq ("${ASAN}","1")
|
||||
DEFAULT_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||
@@ -201,7 +205,7 @@ endef
|
||||
# $5: Additional compiler & linker options (optional)
|
||||
#
|
||||
check_dep=\
|
||||
printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -x c - ) > /dev/null 2>&1; \
|
||||
printf "\#include <%s>\n int main(void) {return 0;}\n" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) -Wl,--no-as-needed $5 -o /dev/null -x c - ) > /dev/null 2>&1; \
|
||||
if [ $$? != 0 ]; \
|
||||
then \
|
||||
printf " REQCHK %s (%s)\n" $1 $2; \
|
||||
@@ -340,14 +344,6 @@ endif
|
||||
export INSTALL CFLAGS CXXFLAGS \
|
||||
LDFLAGS CPPFLAGS ALL_CFLAGS ALL_CXXFLAGS ALL_LDFLAGS ALL_CPPFLAGS
|
||||
|
||||
ifneq ($(shell $(CC_SILENT) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
|
||||
NO_PIE_CFLAGS := -fno-pie
|
||||
NO_PIE_LDFLAGS := -no-pie
|
||||
else
|
||||
NO_PIE_CFLAGS :=
|
||||
NO_PIE_LDFLAGS :=
|
||||
endif
|
||||
|
||||
# Overwrite implicit makefile rules for having nice compile output
|
||||
%.o: %.c
|
||||
ifeq ("${C}","1")
|
||||
|
||||
81
common_autocomp.mak
Normal file
81
common_autocomp.mak
Normal file
@@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright IBM Corp. 2025
|
||||
|
||||
|
||||
# This file defines the build process for shell autocompletion binaries
|
||||
#
|
||||
# How to incorporate it into tool Makefiles:
|
||||
#
|
||||
# 0. The file with the autocompletion script generation code should be named
|
||||
# 'autocompletion_generator_host.c'
|
||||
#
|
||||
# 1. Define the 'bash-completions' and 'zsh-completions' variables: both must be a list
|
||||
# of the names of all the shell completion scripts that belong to the tools the Makefile
|
||||
# is responsible for building.
|
||||
#
|
||||
# (The name of a zsh completion script is the same as the name of the tool,
|
||||
# prefixed by an underscore)
|
||||
#
|
||||
# (The name of a bash completion script is the same as the name of the tool,
|
||||
# suffixed by '.bash')
|
||||
#
|
||||
# 2. include this file
|
||||
#
|
||||
# +1: Add the autocompletion scripts to the .gitignore file
|
||||
#
|
||||
# (See cpumf or dasdfmt as example)
|
||||
|
||||
|
||||
autocomplete-bin := autocompletion_generator_host
|
||||
|
||||
autocomp-object := $(rootdir)/libutil/util_autocomp_host.o
|
||||
|
||||
$(autocomp-object): $(rootdir)/libutil
|
||||
$(MAKE) -C $(rootdir)/libutil/ $(notdir $@)
|
||||
|
||||
$(autocomplete-bin).o: $(autocomplete-bin).c
|
||||
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -I $(rootdir)/include -c $< -o $@
|
||||
|
||||
$(autocomplete-bin): $(autocomplete-bin).o $(autocomp-object)
|
||||
$(LINK_FOR_BUILD) $^ -o $@
|
||||
|
||||
$(bash-completions) $(zsh-completions) &: $(autocomplete-bin)
|
||||
./$(autocomplete-bin)
|
||||
|
||||
install-shell-completions: $(bash-completions) $(zsh-completions)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(ZSHCOMPLETIONDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BASHCOMPLETIONDIR)
|
||||
for completion in $(bash-completions); do \
|
||||
$(INSTALL) -m 644 $$completion $(DESTDIR)$(BASHCOMPLETIONDIR); \
|
||||
done
|
||||
for completion in $(zsh-completions); do \
|
||||
$(INSTALL) -m 644 $$completion $(DESTDIR)$(ZSHCOMPLETIONDIR); \
|
||||
done
|
||||
|
||||
all: $(zsh-completions) $(bash-completions)
|
||||
|
||||
install: install-shell-completions
|
||||
|
||||
.PHONY: install-shell-completions $(rootdir)/libutil
|
||||
|
||||
clean-autocomplete-bin:
|
||||
$(RM) -- $(autocomplete-bin)
|
||||
|
||||
clean: clean-autocomplete-bin
|
||||
|
||||
ifdef bash-completions
|
||||
clean-bash-completions:
|
||||
$(RM) -- $(bash-completions)
|
||||
|
||||
clean: clean-bash-completions
|
||||
endif
|
||||
|
||||
|
||||
ifdef zsh-completions
|
||||
clean-zsh-completions:
|
||||
$(RM) -- $(zsh-completions)
|
||||
|
||||
clean: clean-zsh-completions
|
||||
endif
|
||||
|
||||
.PHONY: clean-autocomplete-bin clean-bash-completions clean-zsh-completions
|
||||
@@ -79,9 +79,11 @@ the cpacfstats client application.
|
||||
|
||||
Example usage scenario:
|
||||
.P
|
||||
1. Start the cpacfstatsd daemon with root privileges.
|
||||
1. Start the cpacfstatsd daemon with root privileges using 'systemctl start
|
||||
cpacfstatsd'.
|
||||
.P
|
||||
2. Check for successful startup by using the ps and syslog commands.
|
||||
2. Check for successful startup by using the 'systemctl status cpacfstatsd'
|
||||
command.
|
||||
.P
|
||||
3. Enable the CPACF counters of interest. For example, enable all counters
|
||||
by issuing cpacfstats -e.
|
||||
@@ -95,7 +97,7 @@ cryptographic counters as required. To reset, use, for example, cpacfstats
|
||||
6. Disable all the CPACF measurements, for example, by using cpacfstats
|
||||
-d.
|
||||
.P
|
||||
7. Shutdown the cpacfstatsd daemon by using killall cpacfstatsd.
|
||||
7. Shutdown the cpacfstatsd daemon by using 'systemctl stop cpacfstatsd'.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
@@ -177,6 +179,12 @@ the errno value.
|
||||
ECC counters are only available since z15. cpacfstats will show the
|
||||
counters as \fIunsupported\fR if the hardware does not support ECC
|
||||
counters.
|
||||
|
||||
CPU-MF counters have to be authorized on HMC or SE to be available and are
|
||||
otherwise shown as \fIunauthorized\fR. On the HMC or SE, authorize the LPAR
|
||||
for each counter set you want to use. Customize the LPAR activation profile
|
||||
and modify the Counter Facility Security Options. You need to activate the
|
||||
\fICrypto activity counter set authorization control\fR checkbox.
|
||||
.
|
||||
.SH APPENDIX
|
||||
The detailed pai counter names are:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ enum cmd_e {
|
||||
enum state_e {
|
||||
DISABLED = 0,
|
||||
ENABLED,
|
||||
UNSUPPORTED
|
||||
UNSUPPORTED,
|
||||
UNAUTHORIZED
|
||||
};
|
||||
|
||||
enum counter_type {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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])) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <poll.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -3,6 +3,11 @@ include ../common.mak
|
||||
BIN_FILES = lscpumf chcpumf lshwc pai lspai
|
||||
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8 lspai.8
|
||||
|
||||
zsh-completions := $(addprefix _,$(BIN_FILES))
|
||||
bash-completions := $(addsuffix .bash,$(BIN_FILES))
|
||||
|
||||
include ../common_autocomp.mak
|
||||
|
||||
all: $(BIN_FILES)
|
||||
|
||||
libs = $(rootdir)/libcpumf/libcpumf.a $(rootdir)/libutil/libutil.a
|
||||
|
||||
28
cpumf/autocompletion_generator_host.c
Normal file
28
cpumf/autocompletion_generator_host.c
Normal file
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Autocompletion generation - for cpumf family of tools
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "lib/util_autocomp.h"
|
||||
|
||||
#include "chcpumf_cli.h"
|
||||
#include "lscpumf_cli.h"
|
||||
#include "lshwc_cli.h"
|
||||
#include "lspai_cli.h"
|
||||
#include "pai_cli.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
generate_autocomp(chcpumf_opt_vec, "chcpumf");
|
||||
generate_autocomp(lscpumf_opt_vec, "lscpumf");
|
||||
generate_autocomp(lshwc_opt_vec, "lshwc");
|
||||
generate_autocomp(lspai_opt_vec, "lspai");
|
||||
generate_autocomp(pai_opt_vec, "pai");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
@@ -17,37 +17,15 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "lib/libcpumf.h"
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/util_prg.h"
|
||||
|
||||
#include "chcpumf_cli.h"
|
||||
|
||||
static unsigned int verbose;
|
||||
static unsigned long min_sdb, max_sdb;
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "min", required_argument, NULL, 'm' },
|
||||
.argument = "num_sdb",
|
||||
.desc = "Specifies the initial size of the sampling buffer.\n"
|
||||
"A sample-data-block (SDB) consumes about 4 kilobytes.",
|
||||
},
|
||||
{
|
||||
.option = { "max", required_argument, NULL, 'x' },
|
||||
.argument = "num_sdb",
|
||||
.desc = "Specifies the maximum size of the sampling buffer.\n"
|
||||
"A sample-data-block (SDB) consumes about 4 kilobytes.",
|
||||
},
|
||||
{
|
||||
.option = { "verbose", no_argument, NULL, 'V' },
|
||||
.desc = "Verbose, display new sample-data-block values.",
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Change CPU Measurement facility charactertics",
|
||||
.copyright_vec = {
|
||||
@@ -163,7 +141,7 @@ int main(int argc, char **argv)
|
||||
unsigned long my_min, my_max;
|
||||
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
util_opt_init(chcpumf_opt_vec, NULL);
|
||||
|
||||
parse_args(argc, argv);
|
||||
if (geteuid())
|
||||
|
||||
40
cpumf/chcpumf_cli.h
Normal file
40
cpumf/chcpumf_cli.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Command line utilities - for chcpumf
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef CHCPUMF_CLI_H
|
||||
#define CHCPUMF_CLI_H
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
static struct util_opt chcpumf_opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "min", required_argument, NULL, 'm' },
|
||||
.argument = "num_sdb",
|
||||
.desc = "Specifies the initial size of the sampling buffer.\n"
|
||||
"A sample-data-block (SDB) consumes about 4 kilobytes.",
|
||||
},
|
||||
{
|
||||
.option = { "max", required_argument, NULL, 'x' },
|
||||
.argument = "num_sdb",
|
||||
.desc = "Specifies the maximum size of the sampling buffer.\n"
|
||||
"A sample-data-block (SDB) consumes about 4 kilobytes.",
|
||||
},
|
||||
{
|
||||
.option = { "verbose", no_argument, NULL, 'V' },
|
||||
.desc = "Verbose, display new sample-data-block values.",
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -7,8 +7,7 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
@@ -31,6 +30,8 @@
|
||||
|
||||
#include "lib/libcpumf.h"
|
||||
|
||||
#include "lscpumf_cli.h"
|
||||
|
||||
#define ACTION_NONE 0
|
||||
#define ACTION_INFO 1
|
||||
#define ACTION_CNT 2
|
||||
@@ -47,33 +48,6 @@ static bool actions[ACTION_SAMPLE + 1]; /* Specified command line options */
|
||||
|
||||
/* File names to read data from */
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "list-counters", no_argument, NULL, 'c' },
|
||||
.desc = "Lists counters for which the LPAR is authorized.",
|
||||
},
|
||||
{
|
||||
.option = { "list-all-counters", no_argument, NULL, 'C' },
|
||||
.desc = "Lists counters regardless of LPAR authorization.",
|
||||
},
|
||||
{
|
||||
.option = { "name", no_argument, NULL, 'n' },
|
||||
.desc = "Displays counter names.",
|
||||
},
|
||||
{
|
||||
.option = { "info", no_argument, NULL, 'i' },
|
||||
.desc = "Displays detailed information.",
|
||||
},
|
||||
{
|
||||
.option = { "list-sampling-events", no_argument, NULL, 's' },
|
||||
.desc = "Lists sampling events for which the LPAR is authorized.",
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "List CPU Measurement facility charactertics",
|
||||
.copyright_vec = {
|
||||
@@ -4160,7 +4134,7 @@ int main(int argc, char **argv)
|
||||
int ret;
|
||||
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
util_opt_init(lscpumf_opt_vec, NULL);
|
||||
|
||||
ret = parse_args(argc, argv);
|
||||
if (read_info() == EXIT_FAILURE)
|
||||
|
||||
44
cpumf/lscpumf_cli.h
Normal file
44
cpumf/lscpumf_cli.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Command line utilities - for lscpumf
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LSCPUMF_CLI_H
|
||||
#define LSCPUMF_CLI_H
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
static struct util_opt lscpumf_opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "list-counters", no_argument, NULL, 'c' },
|
||||
.desc = "Lists counters for which the LPAR is authorized.",
|
||||
},
|
||||
{
|
||||
.option = { "list-all-counters", no_argument, NULL, 'C' },
|
||||
.desc = "Lists counters regardless of LPAR authorization.",
|
||||
},
|
||||
{
|
||||
.option = { "name", no_argument, NULL, 'n' },
|
||||
.desc = "Displays counter names.",
|
||||
},
|
||||
{
|
||||
.option = { "info", no_argument, NULL, 'i' },
|
||||
.desc = "Displays detailed information.",
|
||||
},
|
||||
{
|
||||
.option = { "list-sampling-events", no_argument, NULL, 's' },
|
||||
.desc = "Lists sampling events for which the LPAR is authorized.",
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "lib/libcpumf.h"
|
||||
|
||||
#include "lshwc.h"
|
||||
#include "lshwc_cli.h"
|
||||
|
||||
#define CPUS_ONLINE "/sys/devices/system/cpu/online"
|
||||
#define CPUS_POSSIBLE "/sys/devices/system/cpu/possible"
|
||||
@@ -732,67 +733,6 @@ static int do_it(char *s)
|
||||
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "all", no_argument, NULL, 'a' },
|
||||
.desc = "Displays all CPUs in output"
|
||||
},
|
||||
{
|
||||
.option = { "loop", required_argument, NULL, 'l' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "Specifies loop count for next read"
|
||||
},
|
||||
{
|
||||
.option = { "interval", required_argument, NULL, 'i' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "Specifies interval between read operations (seconds)"
|
||||
},
|
||||
{
|
||||
.option = { "short", no_argument, NULL, 's' },
|
||||
.desc = "Abbreviate counter name with counter set letter and number"
|
||||
},
|
||||
{
|
||||
.option = { "hex0x", no_argument, NULL, 'X' },
|
||||
.desc = "Counter values in hexadecimal format with leading 0x"
|
||||
},
|
||||
{
|
||||
.option = { "hex", no_argument, NULL, 'x' },
|
||||
.desc = "Counter values in hexadecimal format"
|
||||
},
|
||||
{
|
||||
.option = { "hide", no_argument, NULL, 'H' },
|
||||
.desc = "Do not display undefined counters of a counter set"
|
||||
},
|
||||
{
|
||||
.option = { "delta", no_argument, NULL, 'd' },
|
||||
.desc = "Display delta counter values"
|
||||
},
|
||||
{
|
||||
.option = { "timeout", required_argument, NULL, 't' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "run time in s (seconds) m (minutes) h (hours) and d (days)"
|
||||
},
|
||||
{
|
||||
.option = { "quote-all", no_argument, NULL, 'q' },
|
||||
.desc = "Apply quoting to all output elements"
|
||||
},
|
||||
{
|
||||
.option = { "format", required_argument, NULL, 'f' },
|
||||
.argument = "FORMAT",
|
||||
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
|
||||
},
|
||||
{
|
||||
.option = { "counters", required_argument, NULL, 'c' },
|
||||
.argument = "LIST",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "Specify comma separated list of counters to display"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Read CPU Measurement facility counter sets",
|
||||
.copyright_vec = {
|
||||
@@ -823,7 +763,7 @@ int main(int argc, char **argv)
|
||||
int ch;
|
||||
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
util_opt_init(lshwc_opt_vec, NULL);
|
||||
|
||||
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
|
||||
switch (ch) {
|
||||
|
||||
78
cpumf/lshwc_cli.h
Normal file
78
cpumf/lshwc_cli.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Command line utilities - for lshwc
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LSHWC_CLI_H
|
||||
#define LSHWC_CLI_H
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
static struct util_opt lshwc_opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "all", no_argument, NULL, 'a' },
|
||||
.desc = "Displays all CPUs in output"
|
||||
},
|
||||
{
|
||||
.option = { "loop", required_argument, NULL, 'l' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "Specifies loop count for next read"
|
||||
},
|
||||
{
|
||||
.option = { "interval", required_argument, NULL, 'i' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "Specifies interval between read operations (seconds)"
|
||||
},
|
||||
{
|
||||
.option = { "short", no_argument, NULL, 's' },
|
||||
.desc = "Abbreviate counter name with counter set letter and number"
|
||||
},
|
||||
{
|
||||
.option = { "hex0x", no_argument, NULL, 'X' },
|
||||
.desc = "Counter values in hexadecimal format with leading 0x"
|
||||
},
|
||||
{
|
||||
.option = { "hex", no_argument, NULL, 'x' },
|
||||
.desc = "Counter values in hexadecimal format"
|
||||
},
|
||||
{
|
||||
.option = { "hide", no_argument, NULL, 'H' },
|
||||
.desc = "Do not display undefined counters of a counter set"
|
||||
},
|
||||
{
|
||||
.option = { "delta", no_argument, NULL, 'd' },
|
||||
.desc = "Display delta counter values"
|
||||
},
|
||||
{
|
||||
.option = { "timeout", required_argument, NULL, 't' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "run time in s (seconds) m (minutes) h (hours) and d (days)"
|
||||
},
|
||||
{
|
||||
.option = { "quote-all", no_argument, NULL, 'q' },
|
||||
.desc = "Apply quoting to all output elements"
|
||||
},
|
||||
{
|
||||
.option = { "format", required_argument, NULL, 'f' },
|
||||
.argument = "FORMAT",
|
||||
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
|
||||
},
|
||||
{
|
||||
.option = { "counters", required_argument, NULL, 'c' },
|
||||
.argument = "LIST",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "Specify comma separated list of counters to display"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -35,69 +35,7 @@
|
||||
#include "lib/util_str.h"
|
||||
#include "lib/libcpumf.h"
|
||||
|
||||
#define STR_SUB(x) #x
|
||||
#define STR(x) STR_SUB(x)
|
||||
|
||||
#define OPT_FORMAT 256 /* --format XXX option */
|
||||
#define DEFAULT_LOOP_INTERVAL 60 /* loop interval in seconds */
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "all", no_argument, NULL, 'a' },
|
||||
.desc = "Displays all CPUs in output"
|
||||
},
|
||||
{
|
||||
.option = { "delta", no_argument, NULL, 'd' },
|
||||
.desc = "Display delta counter values"
|
||||
},
|
||||
{
|
||||
.option = { "counters", required_argument, NULL, 'c' },
|
||||
.argument = "LIST",
|
||||
.desc = "Specify comma separated list of counters to display"
|
||||
},
|
||||
{
|
||||
.option = { "format", required_argument, NULL, OPT_FORMAT },
|
||||
.argument = "FORMAT",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
|
||||
},
|
||||
{
|
||||
.option = { "loops", required_argument, NULL, 'l' },
|
||||
.argument = "COUNT",
|
||||
.desc = "Number of read operations"
|
||||
},
|
||||
{
|
||||
.option = { "interval", required_argument, NULL, 'i' },
|
||||
.argument = "SECONDS",
|
||||
.desc = "Time to wait between loop iterations (default "
|
||||
STR(DEFAULT_LOOP_INTERVAL) "s)"
|
||||
},
|
||||
{
|
||||
.option = { "numeric", no_argument, NULL, 'n' },
|
||||
.desc = "Sort PAI counters by counter number"
|
||||
},
|
||||
{
|
||||
.option = { "short", no_argument, NULL, 's' },
|
||||
.desc = "Abbreviate counter name with counter set letter and number"
|
||||
},
|
||||
{
|
||||
.option = { "type", required_argument, NULL, 't' },
|
||||
.argument = "TYPE",
|
||||
.desc = "Type of PAI counters to show: crypto, nnpa"
|
||||
},
|
||||
{
|
||||
.option = { "hex0x", no_argument, NULL, 'X' },
|
||||
.desc = "Counter values in hexadecimal format with leading 0x"
|
||||
},
|
||||
{
|
||||
.option = { "hex", no_argument, NULL, 'x' },
|
||||
.desc = "Counter values in hexadecimal format"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
#include "lspai_cli.h"
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "List Processor Assist Information counter sets",
|
||||
@@ -727,7 +665,7 @@ int main(int argc, char **argv)
|
||||
|
||||
util_list_init(&pai_list, struct pai_node, node);
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
util_opt_init(lspai_opt_vec, NULL);
|
||||
|
||||
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
|
||||
switch (ch) {
|
||||
|
||||
81
cpumf/lspai_cli.h
Normal file
81
cpumf/lspai_cli.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Command line utilities - for lspai
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LSPAI_CLI_H
|
||||
#define LSPAI_CLI_H
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
#define STR_SUB(x) #x
|
||||
#define STR(x) STR_SUB(x)
|
||||
|
||||
#define OPT_FORMAT 256 /* --format XXX option */
|
||||
#define DEFAULT_LOOP_INTERVAL 60 /* loop interval in seconds */
|
||||
|
||||
static struct util_opt lspai_opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "all", no_argument, NULL, 'a' },
|
||||
.desc = "Displays all CPUs in output"
|
||||
},
|
||||
{
|
||||
.option = { "delta", no_argument, NULL, 'd' },
|
||||
.desc = "Display delta counter values"
|
||||
},
|
||||
{
|
||||
.option = { "counters", required_argument, NULL, 'c' },
|
||||
.argument = "LIST",
|
||||
.desc = "Specify comma separated list of counters to display"
|
||||
},
|
||||
{
|
||||
.option = { "format", required_argument, NULL, OPT_FORMAT },
|
||||
.argument = "FORMAT",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "List counters in specified FORMAT (" FMT_TYPE_NAMES ")"
|
||||
},
|
||||
{
|
||||
.option = { "loops", required_argument, NULL, 'l' },
|
||||
.argument = "COUNT",
|
||||
.desc = "Number of read operations"
|
||||
},
|
||||
{
|
||||
.option = { "interval", required_argument, NULL, 'i' },
|
||||
.argument = "SECONDS",
|
||||
.desc = "Time to wait between loop iterations (default "
|
||||
STR(DEFAULT_LOOP_INTERVAL) "s)"
|
||||
},
|
||||
{
|
||||
.option = { "numeric", no_argument, NULL, 'n' },
|
||||
.desc = "Sort PAI counters by counter number"
|
||||
},
|
||||
{
|
||||
.option = { "short", no_argument, NULL, 's' },
|
||||
.desc = "Abbreviate counter name with counter set letter and number"
|
||||
},
|
||||
{
|
||||
.option = { "type", required_argument, NULL, 't' },
|
||||
.argument = "TYPE",
|
||||
.desc = "Type of PAI counters to show: crypto, nnpa"
|
||||
},
|
||||
{
|
||||
.option = { "hex0x", no_argument, NULL, 'X' },
|
||||
.desc = "Counter values in hexadecimal format with leading 0x"
|
||||
},
|
||||
{
|
||||
.option = { "hex", no_argument, NULL, 'x' },
|
||||
.desc = "Counter values in hexadecimal format"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
58
cpumf/pai.c
58
cpumf/pai.c
@@ -40,7 +40,9 @@
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/util_scandir.h"
|
||||
#include "lib/libcpumf.h"
|
||||
|
||||
#include "pai.h"
|
||||
#include "pai_cli.h"
|
||||
|
||||
#define S390_EVT_PAI_CRYPTO 0x1000
|
||||
#define S390_EVT_PAI_NNPA 0x1800
|
||||
@@ -501,7 +503,7 @@ static int evt_scan(char *fn, unsigned char *buf, size_t len,
|
||||
__u64 sample_type = pa->sample_type;
|
||||
int allcnt = 0, cnt = 0, rawok = 0;
|
||||
struct perf_event_header *hdr;
|
||||
size_t offset = sizeof(*pa);
|
||||
size_t offset = pa->size;
|
||||
__u64 evtnum = pa->config;
|
||||
struct pai_event_out ev;
|
||||
size_t limit;
|
||||
@@ -512,6 +514,8 @@ static int evt_scan(char *fn, unsigned char *buf, size_t len,
|
||||
unsigned char valid;
|
||||
} last_csout = { 0, 0, 0 };
|
||||
|
||||
if (verbose && (sizeof(*pa) != pa->size))
|
||||
printf("size perf_event_attr mismatch %zu/%zu\n", sizeof(*pa), offset);
|
||||
while (offset < len) {
|
||||
hdr = (struct perf_event_header *)(buf + offset);
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
@@ -833,7 +837,7 @@ static int map_check(char *fn, int (*fct)(char *, unsigned char *, size_t,
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
p = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
warnx("%s cannot map file", fn);
|
||||
close(fd);
|
||||
@@ -925,54 +929,6 @@ static void parse_cpulist(int enr, const char *parm)
|
||||
}
|
||||
}
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "crypto", optional_argument, NULL, 'c' },
|
||||
.argument = "CPULIST[:DATA]",
|
||||
.desc = "Collect PAI crypto counters"
|
||||
},
|
||||
{
|
||||
.option = { "nnpa", optional_argument, NULL, 'n' },
|
||||
.argument = "CPULIST[:DATA]",
|
||||
.desc = "Collect PAI nnpa counters"
|
||||
},
|
||||
{
|
||||
.option = { "mapsize", required_argument, NULL, 'm' },
|
||||
.argument = "SIZE",
|
||||
.desc = "Specifies number of 4KB pages for event ring buffer"
|
||||
},
|
||||
{
|
||||
.option = { "report", no_argument, NULL, 'r' },
|
||||
.desc = "Report file contents"
|
||||
},
|
||||
{
|
||||
.option = { "realtime", required_argument, NULL, 'R' },
|
||||
.argument = "PRIO",
|
||||
.desc = "Collect data with this RT SCHED_FIFO priority"
|
||||
},
|
||||
{
|
||||
.option = { "interval", required_argument, NULL, 'i' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "Specifies interval between read operations in milliseconds"
|
||||
},
|
||||
{
|
||||
.option = { "verbose", no_argument, NULL, 'V' },
|
||||
.desc = "Verbose output"
|
||||
},
|
||||
{
|
||||
.option = { "humantime", no_argument, NULL, 'H' },
|
||||
.desc = "Human readable timestamp in seconds.nanoseconds"
|
||||
},
|
||||
{
|
||||
.option = { "summary", no_argument, NULL, 'S' },
|
||||
.desc = "Print summary of all non-zero counter values"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Record and report Processor Activity Instrumentation Facility Counters.",
|
||||
.copyright_vec = {
|
||||
@@ -1038,7 +994,7 @@ int main(int argc, char **argv)
|
||||
util_list_init(&list_pai_event, struct pai_event, node);
|
||||
util_list_init(&list_pmu_event, struct pmu_events, node);
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
util_opt_init(pai_opt_vec, NULL);
|
||||
|
||||
/* Read currently online CPUs and create a bit mask.
|
||||
* This bitmap of online CPUs is used to check command line parameter
|
||||
|
||||
65
cpumf/pai_cli.h
Normal file
65
cpumf/pai_cli.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Command line utilities - for pai
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef PAI_CLI_H
|
||||
#define PAI_CLI_H
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
static struct util_opt pai_opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "crypto", optional_argument, NULL, 'c' },
|
||||
.argument = "CPULIST[:DATA]",
|
||||
.desc = "Collect PAI crypto counters"
|
||||
},
|
||||
{
|
||||
.option = { "nnpa", optional_argument, NULL, 'n' },
|
||||
.argument = "CPULIST[:DATA]",
|
||||
.desc = "Collect PAI nnpa counters"
|
||||
},
|
||||
{
|
||||
.option = { "mapsize", required_argument, NULL, 'm' },
|
||||
.argument = "SIZE",
|
||||
.desc = "Specifies number of 4KB pages for event ring buffer"
|
||||
},
|
||||
{
|
||||
.option = { "report", no_argument, NULL, 'r' },
|
||||
.desc = "Report file contents"
|
||||
},
|
||||
{
|
||||
.option = { "realtime", required_argument, NULL, 'R' },
|
||||
.argument = "PRIO",
|
||||
.desc = "Collect data with this RT SCHED_FIFO priority"
|
||||
},
|
||||
{
|
||||
.option = { "interval", required_argument, NULL, 'i' },
|
||||
.argument = "NUMBER",
|
||||
.desc = "Specifies interval between read operations in milliseconds"
|
||||
},
|
||||
{
|
||||
.option = { "verbose", no_argument, NULL, 'V' },
|
||||
.desc = "Verbose output"
|
||||
},
|
||||
{
|
||||
.option = { "humantime", no_argument, NULL, 'H' },
|
||||
.desc = "Human readable timestamp in seconds.nanoseconds"
|
||||
},
|
||||
{
|
||||
.option = { "summary", no_argument, NULL, 'S' },
|
||||
.desc = "Print summary of all non-zero counter values"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,10 @@
|
||||
include ../common.mak
|
||||
|
||||
zsh-completions = _dasdfmt
|
||||
bash-completions = dasdfmt.bash
|
||||
|
||||
include ../common_autocomp.mak
|
||||
|
||||
all: dasdfmt
|
||||
|
||||
libs = $(rootdir)/libdasd/libdasd.a \
|
||||
|
||||
20
dasdfmt/autocompletion_generator_host.c
Normal file
20
dasdfmt/autocompletion_generator_host.c
Normal file
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Autocompletion generation - for dasdfmt tool
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "lib/util_autocomp.h"
|
||||
|
||||
#include "dasdfmt_cli.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
generate_autocomp(opt_vec, "dasdfmt");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "dasdfmt.h"
|
||||
#include "dasdfmt_cli.h"
|
||||
|
||||
#define BUSIDSIZE 8
|
||||
#define SEC_PER_DAY (60 * 60 * 24)
|
||||
@@ -81,112 +82,6 @@ static struct dasdfmt_globals {
|
||||
.dasd_info = { 0 },
|
||||
};
|
||||
|
||||
/* Defines for options with no short command */
|
||||
#define OPT_CHECK 128
|
||||
#define OPT_NOZERO 129
|
||||
#define OPT_NODISCARD 130
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("FORMAT ACTIONS"),
|
||||
{
|
||||
.option = { "mode", required_argument, NULL, 'M' },
|
||||
.argument = "MODE",
|
||||
.desc = "Specify scope of operation using MODE:\n"
|
||||
" full: Full device (default)\n"
|
||||
" quick: Only the first two tracks\n"
|
||||
" expand: Unformatted tracks at device end",
|
||||
},
|
||||
{
|
||||
.option = { "check", no_argument, NULL, OPT_CHECK },
|
||||
.desc = "Perform complete format check on device",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
UTIL_OPT_SECTION("FORMAT OPTIONS"),
|
||||
{
|
||||
.option = { "blocksize", required_argument, NULL, 'b' },
|
||||
.argument = "SIZE",
|
||||
.desc = "Format blocks to SIZE bytes (default 4096)",
|
||||
},
|
||||
{
|
||||
.option = { "disk_layout", required_argument, NULL, 'd' },
|
||||
.argument = "LAYOUT",
|
||||
.desc = "Specify the disk layout:\n"
|
||||
" cdl: Compatible Disk Layout (default)\n"
|
||||
" ldl: Linux Disk Layout",
|
||||
},
|
||||
{
|
||||
.option = { "keep_volser", no_argument, NULL, 'k' },
|
||||
.desc = "Do not change the current volume serial",
|
||||
},
|
||||
{
|
||||
.option = { "label", required_argument, NULL, 'l' },
|
||||
.argument = "VOLSER",
|
||||
.desc = "Specify volume serial number",
|
||||
},
|
||||
{
|
||||
.option = { "no_label", no_argument, NULL, 'L' },
|
||||
.desc = "Don't write a disk label",
|
||||
},
|
||||
{
|
||||
.option = { "requestsize", required_argument, NULL, 'r' },
|
||||
.argument = "NUM",
|
||||
.desc = "Process NUM cylinders in one formatting step",
|
||||
},
|
||||
{
|
||||
.option = { "norecordzero", no_argument, NULL, OPT_NOZERO },
|
||||
.desc = "Prevent storage server from modifying record 0",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "no-discard", no_argument, NULL, OPT_NODISCARD },
|
||||
.desc = "Do not discard space before formatting",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { NULL, no_argument, NULL, 'y' },
|
||||
.desc = "Start formatting without further user-confirmation",
|
||||
.flags = UTIL_OPT_FLAG_NOLONG,
|
||||
},
|
||||
UTIL_OPT_SECTION("DISPLAY PROGRESS"),
|
||||
{
|
||||
.option = { "hashmarks", required_argument, NULL, 'm' },
|
||||
.argument = "NUM",
|
||||
.desc = "Show a hashmark every NUM cylinders",
|
||||
},
|
||||
{
|
||||
.option = { "progressbar", no_argument, NULL, 'p' },
|
||||
.desc = "Show a progressbar",
|
||||
},
|
||||
{
|
||||
.option = { "percentage", no_argument, NULL, 'P' },
|
||||
.desc = "Show progress in percent",
|
||||
},
|
||||
UTIL_OPT_SECTION("MISC"),
|
||||
{
|
||||
.option = { "check_host_count", no_argument, NULL, 'C' },
|
||||
.desc = "Check if device is in use by other hosts",
|
||||
},
|
||||
{
|
||||
.option = { "force", no_argument, NULL, 'F' },
|
||||
.desc = "Format without performing sanity checking",
|
||||
},
|
||||
{
|
||||
.option = { "test", no_argument, NULL, 't' },
|
||||
.desc = "Run in dry-run mode without modifying the DASD",
|
||||
},
|
||||
{
|
||||
.option = { NULL, no_argument, NULL, 'v' },
|
||||
.desc = "Print verbose messages when executing",
|
||||
.flags = UTIL_OPT_FLAG_NOLONG,
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
{
|
||||
.option = { "version", no_argument, NULL, 'V' },
|
||||
.desc = "Print version information, then exit",
|
||||
},
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
/* Report error, free memory, and exit */
|
||||
static void error(const char *format, ...)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <limits.h>
|
||||
#include <mntent.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -69,13 +70,13 @@ static void error(const char *format, ...)
|
||||
"is in invalid format\n",prog_name);}
|
||||
|
||||
typedef struct bootstrap1 {
|
||||
u_int32_t key;
|
||||
u_int32_t data[6];
|
||||
uint32_t key;
|
||||
uint32_t data[6];
|
||||
} __attribute__ ((packed)) bootstrap1_t;
|
||||
|
||||
typedef struct bootstrap2 {
|
||||
u_int32_t key;
|
||||
u_int32_t data[36];
|
||||
uint32_t key;
|
||||
uint32_t data[36];
|
||||
} __attribute__ ((packed)) bootstrap2_t;
|
||||
|
||||
|
||||
|
||||
123
dasdfmt/dasdfmt_cli.h
Normal file
123
dasdfmt/dasdfmt_cli.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Command line utilities - for dasdfmt
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef DASDFMT_CLI_H
|
||||
#define DASDFMT_CLI_H
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
/* Defines for options with no short command */
|
||||
#define OPT_CHECK 128
|
||||
#define OPT_NOZERO 129
|
||||
#define OPT_NODISCARD 130
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("FORMAT ACTIONS"),
|
||||
{
|
||||
.option = { "mode", required_argument, NULL, 'M' },
|
||||
.argument = "MODE",
|
||||
.desc = "Specify scope of operation using MODE:\n"
|
||||
" full: Full device (default)\n"
|
||||
" quick: Only the first two tracks\n"
|
||||
" expand: Unformatted tracks at device end",
|
||||
},
|
||||
{
|
||||
.option = { "check", no_argument, NULL, OPT_CHECK },
|
||||
.desc = "Perform complete format check on device",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
UTIL_OPT_SECTION("FORMAT OPTIONS"),
|
||||
{
|
||||
.option = { "blocksize", required_argument, NULL, 'b' },
|
||||
.argument = "SIZE",
|
||||
.desc = "Format blocks to SIZE bytes (default 4096)",
|
||||
},
|
||||
{
|
||||
.option = { "disk_layout", required_argument, NULL, 'd' },
|
||||
.argument = "LAYOUT",
|
||||
.desc = "Specify the disk layout:\n"
|
||||
" cdl: Compatible Disk Layout (default)\n"
|
||||
" ldl: Linux Disk Layout",
|
||||
},
|
||||
{
|
||||
.option = { "keep_volser", no_argument, NULL, 'k' },
|
||||
.desc = "Do not change the current volume serial",
|
||||
},
|
||||
{
|
||||
.option = { "label", required_argument, NULL, 'l' },
|
||||
.argument = "VOLSER",
|
||||
.desc = "Specify volume serial number",
|
||||
},
|
||||
{
|
||||
.option = { "no_label", no_argument, NULL, 'L' },
|
||||
.desc = "Don't write a disk label",
|
||||
},
|
||||
{
|
||||
.option = { "requestsize", required_argument, NULL, 'r' },
|
||||
.argument = "NUM",
|
||||
.desc = "Process NUM cylinders in one formatting step",
|
||||
},
|
||||
{
|
||||
.option = { "norecordzero", no_argument, NULL, OPT_NOZERO },
|
||||
.desc = "Prevent storage server from modifying record 0",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "no-discard", no_argument, NULL, OPT_NODISCARD },
|
||||
.desc = "Do not discard space before formatting",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { NULL, no_argument, NULL, 'y' },
|
||||
.desc = "Start formatting without further user-confirmation",
|
||||
.flags = UTIL_OPT_FLAG_NOLONG,
|
||||
},
|
||||
UTIL_OPT_SECTION("DISPLAY PROGRESS"),
|
||||
{
|
||||
.option = { "hashmarks", required_argument, NULL, 'm' },
|
||||
.argument = "NUM",
|
||||
.desc = "Show a hashmark every NUM cylinders",
|
||||
},
|
||||
{
|
||||
.option = { "progressbar", no_argument, NULL, 'p' },
|
||||
.desc = "Show a progressbar",
|
||||
},
|
||||
{
|
||||
.option = { "percentage", no_argument, NULL, 'P' },
|
||||
.desc = "Show progress in percent",
|
||||
},
|
||||
UTIL_OPT_SECTION("MISC"),
|
||||
{
|
||||
.option = { "check_host_count", no_argument, NULL, 'C' },
|
||||
.desc = "Check if device is in use by other hosts",
|
||||
},
|
||||
{
|
||||
.option = { "force", no_argument, NULL, 'F' },
|
||||
.desc = "Format without performing sanity checking",
|
||||
},
|
||||
{
|
||||
.option = { "test", no_argument, NULL, 't' },
|
||||
.desc = "Run in dry-run mode without modifying the DASD",
|
||||
},
|
||||
{
|
||||
.option = { NULL, no_argument, NULL, 'v' },
|
||||
.desc = "Print verbose messages when executing",
|
||||
.flags = UTIL_OPT_FLAG_NOLONG,
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
{
|
||||
.option = { "version", no_argument, NULL, 'V' },
|
||||
.desc = "Print version information, then exit",
|
||||
},
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -33,6 +33,11 @@
|
||||
#define RD_BUFFER_SIZE 80
|
||||
#define TEMP_DEV_MAX_RETRIES 1000
|
||||
|
||||
#ifndef FTW_CONTINUE
|
||||
#define FTW_CONTINUE 0
|
||||
#define FTW_STOP 1
|
||||
#endif
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Display DASD volume serial number and ID information",
|
||||
.args = "-i BUSID | -b BLOCKDEV | -d DEVNODE",
|
||||
@@ -212,7 +217,7 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
|
||||
if (lseek(f, vlabel_start, SEEK_SET) < 0)
|
||||
goto error_close;
|
||||
|
||||
bzero(vlabel, vlsize);
|
||||
memset(vlabel, 0, vlsize);
|
||||
|
||||
if (read(f, vlabel, vlsize) != vlsize) {
|
||||
warnx("Could not read volume label");
|
||||
@@ -220,15 +225,15 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
|
||||
}
|
||||
|
||||
if (dasd_info.FBA_layout) {
|
||||
bzero(&tmp, vlsize);
|
||||
memset(&tmp, 0, vlsize);
|
||||
memcpy(&tmp, vlabel, vlsize);
|
||||
memcpy(vlabel->vollbl, &tmp, vlsize - 4);
|
||||
}
|
||||
|
||||
close(f);
|
||||
|
||||
bzero(readbuf, 7);
|
||||
bzero(vollbl, 5);
|
||||
memset(readbuf, 0, 7);
|
||||
memset(vollbl, 0, 5);
|
||||
strncpy(vollbl, vlabel->vollbl, 4);
|
||||
dinfo_ebcdic_dec(vollbl, vollbl, 4);
|
||||
|
||||
@@ -334,7 +339,7 @@ static int dinfo_extract_dev(dev_t *dev, char *str)
|
||||
char *p = NULL;
|
||||
int ma, mi;
|
||||
|
||||
bzero(tmp, RD_BUFFER_SIZE);
|
||||
memset(tmp, 0, RD_BUFFER_SIZE);
|
||||
util_strlcpy(tmp, str, RD_BUFFER_SIZE);
|
||||
p = strchr(tmp, ':');
|
||||
if (p == NULL) {
|
||||
@@ -381,10 +386,8 @@ static int
|
||||
dinfo_is_busiddir(const char *fpath, const struct stat *UNUSED(sb),
|
||||
int tflag, struct FTW *ftwbuf)
|
||||
{
|
||||
enum { LINK_DIR_SIZE = 128 };
|
||||
char linkdir[LINK_DIR_SIZE];
|
||||
char *tempdir;
|
||||
ssize_t i;
|
||||
char *linkdir;
|
||||
|
||||
if (tflag != FTW_D || (strncmp((fpath + ftwbuf->base), searchbusid,
|
||||
strlen(searchbusid)) != 0))
|
||||
@@ -396,14 +399,13 @@ dinfo_is_busiddir(const char *fpath, const struct stat *UNUSED(sb),
|
||||
*/
|
||||
if (asprintf(&tempdir, "%s/driver", fpath) < 0)
|
||||
return -1;
|
||||
i = readlink(tempdir, linkdir, LINK_DIR_SIZE);
|
||||
linkdir = util_readlink(tempdir);
|
||||
free(tempdir);
|
||||
if (i < 0 || i >= LINK_DIR_SIZE)
|
||||
return -1;
|
||||
/* append '\0' because readlink returns non zero terminated string */
|
||||
linkdir[i] = '\0';
|
||||
if (strstr(linkdir, "dasd") == NULL)
|
||||
if (strstr(linkdir, "dasd") == NULL) {
|
||||
free(linkdir);
|
||||
return FTW_CONTINUE;
|
||||
}
|
||||
free(linkdir);
|
||||
free(busiddir);
|
||||
busiddir = strdup(fpath);
|
||||
if (busiddir == NULL)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#define _LARGEFILE64_SOURCE /* needed for unistd.h */
|
||||
#define _FILE_OFFSET_BITS 64 /* needed for unistd.h */
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -17,6 +16,7 @@
|
||||
#include <linux/version.h>
|
||||
#include <malloc.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -428,7 +428,7 @@ dasdview_read_vlabel(dasdview_info_t *info, volume_label_t *vlabel)
|
||||
|
||||
pos = info->dasd_info.label_block * info->blksize;
|
||||
|
||||
bzero(vlabel, sizeof(volume_label_t));
|
||||
memset(vlabel, 0, sizeof(volume_label_t));
|
||||
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
|
||||
!info->dasd_info.FBA_layout) {
|
||||
/* OS/390 and zOS compatible disk layout */
|
||||
@@ -466,7 +466,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
printf("\n--- volume label -----------------------------"
|
||||
"---------------------------------\n");
|
||||
|
||||
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.volkey, 4);
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
strncpy((char *)s4, vlabel.volkey, 4);
|
||||
printf("volume label key : ascii '%4s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
||||
printf(" : ebcdic '%4s'\n", t4);
|
||||
@@ -474,7 +476,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%02x", s4[i]);
|
||||
|
||||
bzero(s4, 5); bzero(s4, 5); strncpy((char *)s4, vlabel.vollbl, 4);
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
strncpy((char *)s4, vlabel.vollbl, 4);
|
||||
printf("\n\nvolume label identifier : ascii '%4s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
||||
printf(" : ebcdic '%4s'\n", t4);
|
||||
@@ -482,7 +486,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%02x", s4[i]);
|
||||
|
||||
bzero(s6, 7); bzero(t6, 7); strncpy((char *)s6, vlabel.volid, 6);
|
||||
memset(s6, 0, 7);
|
||||
memset(t6, 0, 7);
|
||||
strncpy((char *)s6, vlabel.volid, 6);
|
||||
printf("\n\nvolume identifier : ascii '%6s'\n", s6);
|
||||
vtoc_ebcdic_dec((char *)s6, (char *)t6, 6);
|
||||
printf(" : ebcdic '%6s'\n", t6);
|
||||
@@ -503,7 +509,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
vtoc_get_cyl_from_cchhb(&vlabel.vtoc),
|
||||
vtoc_get_head_from_cchhb(&vlabel.vtoc), vlabel.vtoc.b);
|
||||
|
||||
bzero(s5, 6); bzero(t5, 6); strncpy((char *)s5, vlabel.res1, 5);
|
||||
memset(s5, 0, 6);
|
||||
memset(t5, 0, 6);
|
||||
strncpy((char *)s5, vlabel.res1, 5);
|
||||
printf("reserved : ascii '%5s'\n", s5);
|
||||
vtoc_ebcdic_dec((char *)s5, (char *)t5, 5);
|
||||
printf(" : ebcdic '%5s'\n", t5);
|
||||
@@ -511,7 +519,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 5; i++)
|
||||
printf("%02x", s5[i]);
|
||||
|
||||
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.cisize, 4);
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
strncpy((char *)s4, vlabel.cisize, 4);
|
||||
printf("\n\nCI size for FBA : ascii '%4s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
||||
printf(" : ebcdic '%4s'\n", t4);
|
||||
@@ -519,7 +529,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%02x", s4[i]);
|
||||
|
||||
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.blkperci, 4);
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
strncpy((char *)s4, vlabel.blkperci, 4);
|
||||
printf("\n\nblocks per CI (FBA) : ascii '%4s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
||||
printf(" : ebcdic '%4s'\n", t4);
|
||||
@@ -527,7 +539,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%02x", s4[i]);
|
||||
|
||||
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.labperci, 4);
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
strncpy((char *)s4, vlabel.labperci, 4);
|
||||
printf("\n\nlabels per CI (FBA) : ascii '%4s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
||||
printf(" : ebcdic '%4s'\n", t4);
|
||||
@@ -535,7 +549,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%02x", s4[i]);
|
||||
|
||||
bzero(s4, 5); bzero(t4, 5); strncpy((char *)s4, vlabel.res2, 4);
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
strncpy((char *)s4, vlabel.res2, 4);
|
||||
printf("\n\nreserved : ascii '%4s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 4);
|
||||
printf(" : ebcdic '%4s'\n", t4);
|
||||
@@ -543,7 +559,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("%02x", s4[i]);
|
||||
|
||||
bzero(s14, 15); bzero(t14, 15); strncpy(s14, vlabel.lvtoc, 14);
|
||||
memset(s14, 0, 15);
|
||||
memset(t14, 0, 15);
|
||||
strncpy(s14, vlabel.lvtoc, 14);
|
||||
printf("\n\nowner code for VTOC : ascii '%14s'\n", s14);
|
||||
vtoc_ebcdic_dec(s14, t14, 14);
|
||||
printf(" ebcdic '%14s'\n", t14);
|
||||
@@ -556,9 +574,10 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
bzero(s29, 30); strncpy(s29, vlabel.res3, 28);
|
||||
memset(s29, 0, 30);
|
||||
strncpy(s29, vlabel.res3, 28);
|
||||
printf("\n\nreserved : ascii '%28s'\n", s29);
|
||||
bzero(t29, 30);
|
||||
memset(t29, 0, 30);
|
||||
vtoc_ebcdic_dec(s29, t29, 28);
|
||||
printf(" ebcdic '%28s'\n", t29);
|
||||
printf(" hex ");
|
||||
@@ -573,7 +592,9 @@ dasdview_print_vlabel(dasdview_info_t *info)
|
||||
" ");
|
||||
}
|
||||
|
||||
bzero(s4, 5); bzero(t4, 5); s4[0] = vlabel.ldl_version;
|
||||
memset(s4, 0, 5);
|
||||
memset(t4, 0, 5);
|
||||
s4[0] = vlabel.ldl_version;
|
||||
printf("\n\nldl_version : ascii '%1s'\n", s4);
|
||||
vtoc_ebcdic_dec((char *)s4, (char *)t4, 1);
|
||||
printf(" : ebcdic '%1s'\n", t4);
|
||||
@@ -609,8 +630,8 @@ dasdview_print_volser(dasdview_info_t *info)
|
||||
dasdview_read_vlabel(info, &vlabel);
|
||||
}
|
||||
|
||||
bzero(vollbl, 5);
|
||||
bzero(volser, 7);
|
||||
memset(vollbl, 0, 5);
|
||||
memset(volser, 0, 7);
|
||||
strncpy(vollbl, vlabel.vollbl, 4);
|
||||
vtoc_ebcdic_dec(vollbl, vollbl, 4);
|
||||
|
||||
@@ -631,12 +652,12 @@ dasdview_read_vtoc(dasdview_info_t *info)
|
||||
volume_label_t vlabel;
|
||||
format1_label_t tmp;
|
||||
unsigned long maxblk, pos;
|
||||
u_int64_t vtocblk;
|
||||
uint64_t vtocblk;
|
||||
int i;
|
||||
|
||||
pos = info->dasd_info.label_block * info->blksize;
|
||||
|
||||
bzero(&vlabel, sizeof(vlabel));
|
||||
memset(&vlabel, 0, sizeof(vlabel));
|
||||
if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
|
||||
!info->dasd_info.FBA_layout) {
|
||||
/* OS/390 and zOS compatible disk layout */
|
||||
@@ -648,7 +669,7 @@ dasdview_read_vtoc(dasdview_info_t *info)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
vtocblk = (u_int64_t)vtoc_get_cyl_from_cchhb(&vlabel.vtoc) *
|
||||
vtocblk = (uint64_t)vtoc_get_cyl_from_cchhb(&vlabel.vtoc) *
|
||||
info->geo.heads * info->geo.sectors +
|
||||
vtoc_get_head_from_cchhb(&vlabel.vtoc) * info->geo.sectors +
|
||||
vlabel.vtoc.b;
|
||||
@@ -747,13 +768,13 @@ static void dasdview_print_format1_8_short_info(format1_label_t *f1,
|
||||
char s6[7], s13[14], s44[45];
|
||||
unsigned long track_low, track_up;
|
||||
|
||||
bzero(s44, 45);
|
||||
memset(s44, 0, 45);
|
||||
strncpy(s44, f1->DS1DSNAM, 44);
|
||||
vtoc_ebcdic_dec(s44, s44, 44);
|
||||
bzero(s6, 7);
|
||||
memset(s6, 0, 7);
|
||||
strncpy(s6, (char *)f1->DS1DSSN, 6);
|
||||
vtoc_ebcdic_dec(s6, s6, 6);
|
||||
bzero(s13, 14);
|
||||
memset(s13, 0, 14);
|
||||
strncpy(s13, (char *)f1->DS1SYSCD, 13);
|
||||
vtoc_ebcdic_dec(s13, s13, 13);
|
||||
|
||||
@@ -837,13 +858,13 @@ static void dasdview_print_format1_8_short_info_raw(format1_label_t *f1,
|
||||
struct dscb *dscb;
|
||||
int rc;
|
||||
|
||||
bzero(s44, 45);
|
||||
memset(s44, 0, 45);
|
||||
strncpy(s44, f1->DS1DSNAM, 44);
|
||||
vtoc_ebcdic_dec(s44, s44, 44);
|
||||
bzero(s6, 7);
|
||||
memset(s6, 0, 7);
|
||||
strncpy(s6, (char *)f1->DS1DSSN, 6);
|
||||
vtoc_ebcdic_dec(s6, s6, 6);
|
||||
bzero(s13, 14);
|
||||
memset(s13, 0, 14);
|
||||
strncpy(s13, (char *)f1->DS1SYSCD, 13);
|
||||
vtoc_ebcdic_dec(s13, s13, 13);
|
||||
|
||||
@@ -1071,7 +1092,7 @@ static void dasdview_print_vtoc_info_raw(dasdview_info_t *info)
|
||||
|
||||
/*
|
||||
* Note: the explicit cylinder/head conversion for large volume
|
||||
* adresses should not be necessary for entries that point to
|
||||
* addresses should not be necessary for entries that point to
|
||||
* vtoc labels, as those must be located in the first 65K-1 tracks,
|
||||
* but we do it anyway to be on the safe side.
|
||||
*/
|
||||
@@ -1080,9 +1101,9 @@ static void dasdview_print_format1_8_no_head(format1_label_t *f1)
|
||||
char s6[7], s13[14], s44[45];
|
||||
int i;
|
||||
|
||||
bzero(s6, 7);
|
||||
bzero(s13, 14);
|
||||
bzero(s44, 45);
|
||||
memset(s6, 0, 7);
|
||||
memset(s13, 0, 14);
|
||||
memset(s44, 0, 45);
|
||||
|
||||
strncpy(s44, f1->DS1DSNAM, 44);
|
||||
printf("DS1DSNAM : ascii '%44s'\n", s44);
|
||||
@@ -1865,7 +1886,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
|
||||
|
||||
/* seek in SEEK_STEP steps */
|
||||
for (i = 1; i <= j; i++) {
|
||||
rc = lseek64(fd, SEEK_STEP, SEEK_CUR);
|
||||
rc = lseek(fd, SEEK_STEP, SEEK_CUR);
|
||||
if (rc == -1) {
|
||||
printf("*** rc: %d (%d) ***\n", rc, errno);
|
||||
printf("*** j: %llu ***\n", j);
|
||||
@@ -1918,7 +1939,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
|
||||
|
||||
count = info->begin;
|
||||
for (i = 1; i <= j; i++) {
|
||||
bzero(dumpstr, DUMP_STRING_SIZE);
|
||||
memset(dumpstr, 0, DUMP_STRING_SIZE);
|
||||
rc = read(fd, &dumpstr, DUMP_STRING_SIZE);
|
||||
if (rc != DUMP_STRING_SIZE) {
|
||||
close(fd);
|
||||
@@ -1937,7 +1958,7 @@ static void dasdview_view_standard(dasdview_info_t *info)
|
||||
}
|
||||
|
||||
if (k > 0) {
|
||||
bzero(dumpstr, DUMP_STRING_SIZE);
|
||||
memset(dumpstr, 0, DUMP_STRING_SIZE);
|
||||
rc = read(fd, &dumpstr, k);
|
||||
if (rc != (int)k) {
|
||||
close(fd);
|
||||
@@ -1976,8 +1997,8 @@ static void dasdview_print_format_raw(unsigned int size, char *dumpstr)
|
||||
while (residual) {
|
||||
/* we handle at most 16 bytes per line */
|
||||
count = MIN(residual, 16u);
|
||||
bzero(asc, 17);
|
||||
bzero(ebc, 17);
|
||||
memset(asc, 0, 17);
|
||||
memset(ebc, 0, 17);
|
||||
printf("|");
|
||||
memcpy(asc, data, count);
|
||||
memcpy(ebc, data, count);
|
||||
@@ -2066,7 +2087,7 @@ static void dasdview_print_raw_track(char *trackdata,
|
||||
{
|
||||
struct eckd_count *ecount;
|
||||
char *data;
|
||||
u_int32_t record;
|
||||
uint32_t record;
|
||||
|
||||
record = 0;
|
||||
data = trackdata;
|
||||
@@ -2091,8 +2112,8 @@ static void dasdview_print_raw_track(char *trackdata,
|
||||
|
||||
static void dasdview_view_raw(dasdview_info_t *info)
|
||||
{
|
||||
u_int64_t residual, trckstart, trckend, track, trckbuffsize;
|
||||
u_int64_t tracks_to_read, trckcount, i;
|
||||
uint64_t residual, trckstart, trckend, track, trckbuffsize;
|
||||
uint64_t tracks_to_read, trckcount, i;
|
||||
char *trackdata;
|
||||
char *data;
|
||||
int rc;
|
||||
@@ -2187,7 +2208,7 @@ int main(int argc, char *argv[])
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
bzero(&info, sizeof(info));
|
||||
memset(&info, 0, sizeof(info));
|
||||
while (1) {
|
||||
oc = util_opt_getopt_long(argc, argv);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define DASDVIEW_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/********************************************************************************
|
||||
* SECTION: Definitions needed for DASD-API (see dasd.h)
|
||||
@@ -68,7 +69,7 @@ typedef struct dasdview_info
|
||||
int dasd_info_version;
|
||||
unsigned int blksize;
|
||||
struct hd_geometry geo;
|
||||
u_int32_t hw_cylinders;
|
||||
uint32_t hw_cylinders;
|
||||
|
||||
unsigned long long begin;
|
||||
unsigned long long size;
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "dref.h"
|
||||
#include "dump.h"
|
||||
#include "global.h"
|
||||
#include "idcache.h"
|
||||
#include "misc.h"
|
||||
#include "tar.h"
|
||||
|
||||
@@ -656,16 +655,18 @@ static int read_symlink(struct task *task, const char *filename,
|
||||
task->opts->read_chunk_size;
|
||||
int rc = EXIT_OK;
|
||||
|
||||
/* If @relname is NULL, use @filename with AT_FDCWD. */
|
||||
if (!relname) {
|
||||
relname = filename;
|
||||
dirfd = AT_FDCWD;
|
||||
}
|
||||
|
||||
while (!is_aborted(task)) {
|
||||
buffer_make_room(buffer, currlen, false,
|
||||
task->opts->max_buffer_size);
|
||||
|
||||
cancel_enable();
|
||||
if (relname)
|
||||
actual = readlinkat(dirfd, relname, buffer->addr,
|
||||
buffer->size);
|
||||
else
|
||||
actual = readlink(filename, buffer->addr, buffer->size);
|
||||
actual = readlinkat(dirfd, relname, buffer->addr, buffer->size);
|
||||
cancel_disable();
|
||||
|
||||
if (actual == -1) {
|
||||
|
||||
@@ -4,3 +4,4 @@ pkey_pckmo
|
||||
pkey_ep11
|
||||
pkey_cca
|
||||
paes_s390
|
||||
phmac_s390
|
||||
|
||||
2
etc/udev/rules.d/59-virtio-blk.rules
Normal file
2
etc/udev/rules.d/59-virtio-blk.rules
Normal file
@@ -0,0 +1,2 @@
|
||||
SUBSYSTEM=="block", ACTION=="add", KERNEL=="vd*[!0-9]", TEST=="queue/rotational", ATTR{queue/rotational}="0"
|
||||
SUBSYSTEM=="block", ACTION=="add", KERNEL=="vd*[!0-9]", TEST=="queue/scheduler", ATTR{queue/scheduler}="none"
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
@@ -211,9 +212,9 @@ static void setpos(fdasd_anchor_t *anc, int dsn, int pos)
|
||||
anc->partno[dsn] = pos;
|
||||
}
|
||||
|
||||
static u_int32_t get_usable_cylinders(fdasd_anchor_t *anc)
|
||||
static uint32_t get_usable_cylinders(fdasd_anchor_t *anc)
|
||||
{
|
||||
u_int32_t cyl;
|
||||
uint32_t cyl;
|
||||
|
||||
/* large volume */
|
||||
if (anc->f4->DS4DEVCT.DS4DSCYL == LV_COMPAT_CYL &&
|
||||
@@ -221,7 +222,7 @@ static u_int32_t get_usable_cylinders(fdasd_anchor_t *anc)
|
||||
return anc->f4->DS4DCYL;
|
||||
/* normal volume */
|
||||
if (anc->f4->DS4DEVCT.DS4DEVFG & ALTERNATE_CYLINDERS_USED)
|
||||
cyl = anc->f4->DS4DEVCT.DS4DSCYL - (u_int16_t)anc->f4->DS4DEVAC;
|
||||
cyl = anc->f4->DS4DEVCT.DS4DSCYL - (uint16_t)anc->f4->DS4DEVAC;
|
||||
else
|
||||
cyl = anc->f4->DS4DEVCT.DS4DSCYL;
|
||||
|
||||
@@ -230,7 +231,7 @@ static u_int32_t get_usable_cylinders(fdasd_anchor_t *anc)
|
||||
|
||||
static void get_addr_of_highest_f1_f8_label(fdasd_anchor_t *anc, cchhb_t *addr)
|
||||
{
|
||||
u_int8_t record;
|
||||
uint8_t record;
|
||||
/* We have to count the following labels:
|
||||
* one format 4
|
||||
* one format 5
|
||||
@@ -406,7 +407,7 @@ static void fdasd_error(fdasd_anchor_t *anc, enum fdasd_failure why, char *str)
|
||||
*/
|
||||
static int read_line(void)
|
||||
{
|
||||
bzero(line_buffer, LINE_LENGTH);
|
||||
memset(line_buffer, 0, LINE_LENGTH);
|
||||
line_ptr = line_buffer;
|
||||
if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
|
||||
clearerr(stdin);
|
||||
@@ -493,7 +494,7 @@ static void fdasd_initialize_anchor(fdasd_anchor_t *anc)
|
||||
volume_label_t *vlabel;
|
||||
int i;
|
||||
|
||||
bzero(anc, sizeof(fdasd_anchor_t));
|
||||
memset(anc, 0, sizeof(fdasd_anchor_t));
|
||||
|
||||
for (i = 0; i < USABLE_PARTITIONS; i++)
|
||||
setpos(anc, i, -1);
|
||||
@@ -519,17 +520,17 @@ static void fdasd_initialize_anchor(fdasd_anchor_t *anc)
|
||||
fdasd_error(anc, malloc_failed,
|
||||
"FMT9 DSCB memory allocation failed.");
|
||||
|
||||
bzero(anc->f4, sizeof(format4_label_t));
|
||||
bzero(anc->f5, sizeof(format5_label_t));
|
||||
bzero(anc->f7, sizeof(format7_label_t));
|
||||
bzero(anc->f9, sizeof(format9_label_t));
|
||||
memset(anc->f4, 0, sizeof(format4_label_t));
|
||||
memset(anc->f5, 0, sizeof(format5_label_t));
|
||||
memset(anc->f7, 0, sizeof(format7_label_t));
|
||||
memset(anc->f9, 0, sizeof(format9_label_t));
|
||||
vtoc_init_format9_label(anc->f9);
|
||||
|
||||
vlabel = malloc(sizeof(volume_label_t));
|
||||
if (vlabel == NULL)
|
||||
fdasd_error(anc, malloc_failed,
|
||||
"Volume label memory allocation failed.");
|
||||
bzero(vlabel, sizeof(volume_label_t));
|
||||
memset(vlabel, 0, sizeof(volume_label_t));
|
||||
anc->vlabel = vlabel;
|
||||
|
||||
for (i = 1; i <= USABLE_PARTITIONS; i++) {
|
||||
@@ -551,7 +552,7 @@ static void fdasd_initialize_anchor(fdasd_anchor_t *anc)
|
||||
if (part_info->f1 == NULL)
|
||||
fdasd_error(anc, malloc_failed,
|
||||
"FMT1 DSCB memory allocation failed.");
|
||||
bzero(part_info->f1, sizeof(format1_label_t));
|
||||
memset(part_info->f1, 0, sizeof(format1_label_t));
|
||||
|
||||
if (prev_part_info) {
|
||||
prev_part_info->next = part_info;
|
||||
@@ -975,7 +976,7 @@ static void fdasd_verify_device(fdasd_anchor_t *anc, char *name)
|
||||
* Note:
|
||||
* - 'version' and 'help' are priority options.
|
||||
* All other parameters are ignored in that case.
|
||||
* - 'silent' and 'verbose' are allways allowed in any
|
||||
* - 'silent' and 'verbose' are always allowed in any
|
||||
* combination.
|
||||
*
|
||||
*/
|
||||
@@ -1052,10 +1053,10 @@ static void fdasd_show_mapping(fdasd_anchor_t *anc)
|
||||
int i = 0, j = 0, dev_len;
|
||||
|
||||
printf("\ndevice .........: %s\n", options.device);
|
||||
bzero(str, sizeof(str));
|
||||
memset(str, 0, sizeof(str));
|
||||
vtoc_volume_label_get_label(anc->vlabel, str);
|
||||
printf("volume label ...: %.4s\n", str);
|
||||
bzero(str, sizeof(str));
|
||||
memset(str, 0, sizeof(str));
|
||||
vtoc_volume_label_get_volser(anc->vlabel, str);
|
||||
printf("volume serial ..: %s\n\n", str);
|
||||
|
||||
@@ -1080,7 +1081,7 @@ static void fdasd_show_mapping(fdasd_anchor_t *anc)
|
||||
if (part_info->used != 0x01)
|
||||
continue;
|
||||
|
||||
bzero(dsname, sizeof(dsname));
|
||||
memset(dsname, 0, sizeof(dsname));
|
||||
strncpy(dsname, part_info->f1->DS1DSNAM, 44);
|
||||
vtoc_ebcdic_dec(dsname, dsname, 44);
|
||||
|
||||
@@ -1103,7 +1104,7 @@ static void fdasd_print_volser(fdasd_anchor_t *anc)
|
||||
{
|
||||
char volser[VOLSER_LENGTH + 1];
|
||||
|
||||
bzero(volser, VOLSER_LENGTH);
|
||||
memset(volser, 0, VOLSER_LENGTH);
|
||||
vtoc_ebcdic_dec(anc->vlabel->volid, volser, VOLSER_LENGTH);
|
||||
printf("%6.6s\n", volser);
|
||||
}
|
||||
@@ -1372,7 +1373,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
|
||||
}
|
||||
|
||||
/* write empty labels to the rest of the blocks */
|
||||
bzero(&emptyf1, sizeof(emptyf1));
|
||||
memset(&emptyf1, 0, sizeof(emptyf1));
|
||||
while (blk < maxblk) {
|
||||
vtoc_write_label(options.device, blk, &emptyf1, NULL,
|
||||
NULL, NULL, NULL);
|
||||
@@ -1425,7 +1426,7 @@ static void fdasd_recreate_vtoc_unconditional(fdasd_anchor_t *anc)
|
||||
anc->formatted_cylinders, geo.heads);
|
||||
|
||||
while (part_info != NULL) {
|
||||
bzero(part_info->f1, sizeof(format1_label_t));
|
||||
memset(part_info->f1, 0, sizeof(format1_label_t));
|
||||
|
||||
if (part_info->used == 0x01) {
|
||||
part_info->used = 0x00;
|
||||
@@ -1826,7 +1827,7 @@ static void fdasd_process_valid_vtoc(fdasd_anchor_t *anc, unsigned long blk)
|
||||
|
||||
/* go through remaining labels, f4 label already done */
|
||||
for (i = 1; i < geo.sectors; i++) {
|
||||
bzero(&f1_label, f1_size);
|
||||
memset(&f1_label, 0, f1_size);
|
||||
vtoc_read_label(options.device, blk, &f1_label, NULL, NULL,
|
||||
NULL);
|
||||
|
||||
@@ -2470,9 +2471,9 @@ static int fdasd_get_partition_data(fdasd_anchor_t *anc, extent_t *part_extent,
|
||||
unsigned long start, stop, limit;
|
||||
partition_info_t *part_tmp;
|
||||
cchh_t llimit, ulimit;
|
||||
u_int16_t hh, head;
|
||||
u_int32_t cc, cyl;
|
||||
u_int8_t b1, b2;
|
||||
uint16_t hh, head;
|
||||
uint32_t cc, cyl;
|
||||
uint8_t b1, b2;
|
||||
char mesg[48];
|
||||
|
||||
start = FIRST_USABLE_TRK;
|
||||
@@ -2675,7 +2676,7 @@ static void fdasd_dequeue_old_partition(fdasd_anchor_t *anc,
|
||||
part_info->start_trk = 0x0;
|
||||
part_info->end_trk = 0x0;
|
||||
part_info->fspace_trk = 0x0;
|
||||
bzero(part_info->f1, sizeof(format1_label_t));
|
||||
memset(part_info->f1, 0, sizeof(format1_label_t));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2758,7 +2759,7 @@ static void fdasd_remove_partition(fdasd_anchor_t *anc)
|
||||
if (anc->used_partitions != 0)
|
||||
get_addr_of_highest_f1_f8_label(anc, &hf1);
|
||||
else
|
||||
bzero(&hf1, sizeof(struct cchhb));
|
||||
memset(&hf1, 0, sizeof(struct cchhb));
|
||||
|
||||
vtoc_update_format4_label(anc->f4, &hf1, anc->f4->DS4DSREC + 1);
|
||||
vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '+', anc->verbose,
|
||||
@@ -2777,8 +2778,8 @@ static void fdasd_auto_partition(fdasd_anchor_t *anc)
|
||||
{
|
||||
partition_info_t *part_info = anc->first;
|
||||
cchh_t llimit, ulimit;
|
||||
u_int16_t head;
|
||||
u_int32_t cyl;
|
||||
uint16_t head;
|
||||
uint32_t cyl;
|
||||
extent_t ext;
|
||||
cchhb_t hf1;
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef FDASD_H
|
||||
#define FDASD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* SECTION: Definitions needed for DASD-API (see dasd.h) *
|
||||
*****************************************************************************/
|
||||
@@ -67,7 +69,7 @@ static struct fdasd_options options = {
|
||||
};
|
||||
|
||||
typedef struct partition_info {
|
||||
u_int8_t used;
|
||||
uint8_t used;
|
||||
unsigned long start_trk;
|
||||
unsigned long end_trk;
|
||||
unsigned long len_trk;
|
||||
@@ -100,7 +102,7 @@ typedef struct fdasd_anchor {
|
||||
int option_reuse;
|
||||
int option_recreate;
|
||||
int partno[USABLE_PARTITIONS];
|
||||
u_int16_t dev_type;
|
||||
uint16_t dev_type;
|
||||
unsigned int used_partitions;
|
||||
unsigned long label_pos;
|
||||
unsigned int blksize;
|
||||
@@ -113,8 +115,8 @@ typedef struct fdasd_anchor {
|
||||
partition_info_t *last;
|
||||
volume_label_t *vlabel;
|
||||
config_data_t confdata[USABLE_PARTITIONS];
|
||||
u_int32_t hw_cylinders;
|
||||
u_int32_t formatted_cylinders;
|
||||
uint32_t hw_cylinders;
|
||||
uint32_t formatted_cylinders;
|
||||
} fdasd_anchor_t;
|
||||
|
||||
enum offset {lower, upper};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
#define DBFS_WAIT_TIME_US 10000
|
||||
|
||||
extern int dg_debugfs_init(int exit_on_err);
|
||||
extern int dg_debugfs_vm_init(void);
|
||||
extern int dg_debugfs_lpar_init(void);
|
||||
extern int dg_debugfs_open(const char *file);
|
||||
int dg_debugfs_init(int exit_on_err);
|
||||
int dg_debugfs_vm_init(void);
|
||||
int dg_debugfs_lpar_init(void);
|
||||
int dg_debugfs_open(const char *file);
|
||||
|
||||
/*
|
||||
* z/VM diag 0C prototypes
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define CPU_TYPE_LEN 16
|
||||
#define DEBUGFS_FILE "diag_204"
|
||||
|
||||
static struct sd_sys *l_cur_lpar;
|
||||
static u64 l_update_time_us;
|
||||
static long l_204_buf_size;
|
||||
|
||||
@@ -36,7 +37,8 @@ static long l_204_buf_size;
|
||||
struct l_x_info_blk_hdr {
|
||||
u8 npar;
|
||||
u8 flags;
|
||||
u8 reserved1[6];
|
||||
u8 reserved1[4];
|
||||
u16 this_part;
|
||||
u64 curtod1;
|
||||
u64 curtod2;
|
||||
u8 reserved[40];
|
||||
@@ -158,6 +160,21 @@ static void *l_sd_sys_fill(struct sd_sys *lpar, struct l_x_sys_hdr *sys_hdr)
|
||||
return cpu_info;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the time delta between samples using current partition's
|
||||
* online time.
|
||||
*/
|
||||
static u64 l_sd_cur_lpar_delta_time_get(void)
|
||||
{
|
||||
struct sd_cpu *cpu;
|
||||
|
||||
cpu = sd_cpu_get(l_cur_lpar, "0");
|
||||
if (!cpu->d_prev || !cpu->d_cur)
|
||||
return 0;
|
||||
return l_sub_64(cpu->d_cur->online_time_us,
|
||||
cpu->d_prev->online_time_us);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill one physical CPU with data
|
||||
*/
|
||||
@@ -241,9 +258,9 @@ static void l_read_debugfs(struct l_debugfs_d204_hdr **hdr,
|
||||
*/
|
||||
static void l_sd_sys_root_fill(struct sd_sys *sys)
|
||||
{
|
||||
struct l_x_sys_hdr *sys_hdr, *this_part;
|
||||
struct l_x_info_blk_hdr *time_hdr;
|
||||
struct l_debugfs_d204_hdr *hdr;
|
||||
struct l_x_sys_hdr *sys_hdr;
|
||||
struct sd_sys *lpar;
|
||||
char lpar_id[10];
|
||||
int i;
|
||||
@@ -262,18 +279,23 @@ static void l_sd_sys_root_fill(struct sd_sys *sys)
|
||||
usleep(DBFS_WAIT_TIME_US);
|
||||
} while (1);
|
||||
sys_hdr = ((void *) time_hdr) + sizeof(struct l_x_info_blk_hdr);
|
||||
this_part = ((void *)time_hdr) + time_hdr->this_part;
|
||||
for (i = 0; i < time_hdr->npar; i++) {
|
||||
l_sys_hdr__sys_name(sys_hdr, lpar_id);
|
||||
lpar = sd_sys_get(sys, lpar_id);
|
||||
if (!lpar)
|
||||
lpar = sd_sys_new(sys, lpar_id);
|
||||
if (sys_hdr == this_part)
|
||||
l_cur_lpar = lpar;
|
||||
lpar->threads_per_core = l_thread_cnt(sys_hdr);
|
||||
sys_hdr = l_sd_sys_fill(lpar, sys_hdr);
|
||||
sd_sys_commit(lpar);
|
||||
}
|
||||
|
||||
if (time_hdr->flags & LPAR_PHYS_FLG)
|
||||
if (time_hdr->flags & LPAR_PHYS_FLG) {
|
||||
l_sd_sys_root_cpu_phys_fill(sys, (void *) sys_hdr);
|
||||
sd_phys_delta_time_us_set(sys, l_sd_cur_lpar_delta_time_get());
|
||||
}
|
||||
ht_free(hdr);
|
||||
sd_sys_commit(sys);
|
||||
}
|
||||
@@ -290,6 +312,16 @@ static void l_sd_update(void)
|
||||
sd_sys_update_end(root, l_update_time_us);
|
||||
}
|
||||
|
||||
/*
|
||||
* Supported physical information items
|
||||
*/
|
||||
static struct sd_sys_item *l_phys_item_vec[] = {
|
||||
&sd_sys_item_core_cnt,
|
||||
&sd_sys_item_phys_mgm_diff,
|
||||
&sd_sys_item_mgm,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Supported system items
|
||||
*/
|
||||
@@ -364,6 +396,7 @@ static struct sd_cpu_type *l_cpu_type_vec[] = {
|
||||
static struct sd_dg l_sd_dg = {
|
||||
.update_sys = l_sd_update,
|
||||
.cpu_type_vec = l_cpu_type_vec,
|
||||
.phys_item_vec = l_phys_item_vec,
|
||||
.sys_item_vec = l_sys_item_vec,
|
||||
.sys_item_enable_vec = l_sys_item_enable_vec,
|
||||
.cpu_item_vec = l_cpu_item_vec,
|
||||
@@ -383,6 +416,6 @@ int dg_debugfs_lpar_init(void)
|
||||
return fh;
|
||||
else
|
||||
close(fh);
|
||||
sd_dg_register(&l_sd_dg, 1);
|
||||
sd_dg_register(&l_sd_dg, 1, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -358,6 +358,6 @@ int dg_debugfs_vm_init(void)
|
||||
close(fh);
|
||||
l_2fc_buf_size = sizeof(struct l_debugfs_d2fc_hdr);
|
||||
l_guest_name_init();
|
||||
sd_dg_register(&dg_debugfs_vm_dg, 0);
|
||||
sd_dg_register(&dg_debugfs_vm_dg, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <iconv.h>
|
||||
#include <limits.h>
|
||||
#include <mntent.h>
|
||||
#include <mntent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -25,6 +24,10 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef _PATH_MOUNTED
|
||||
#define _PATH_MOUNTED "/etc/mtab"
|
||||
#endif
|
||||
|
||||
#include "lib/util_fmt.h"
|
||||
#include "lib/util_libc.h"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_time.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define G0(x) MAX(0, (s64) (x))
|
||||
@@ -25,23 +26,23 @@
|
||||
/*
|
||||
* Helper Prototypes
|
||||
*/
|
||||
extern void hyptop_helper_init(void);
|
||||
extern char *ht_strstrip(char *str);
|
||||
extern char *ht_strdup(const char *str);
|
||||
extern void ht_print_head(const char *sys);
|
||||
extern void ht_print_help_icon(void);
|
||||
extern void ht_ebcdic_to_ascii(char *in, char *out, size_t len);
|
||||
extern char *ht_mount_point_get(const char *fs_type);
|
||||
extern u64 ht_ext_tod_2_us(void *tod_ext);
|
||||
extern void ht_print_time(void);
|
||||
extern s64 ht_calculate_smt_util(u64 core_us, u64 thr_us, u64 mgm_us, int thread_per_core);
|
||||
void hyptop_helper_init(void);
|
||||
char *ht_strstrip(char *str);
|
||||
char *ht_strdup(const char *str);
|
||||
void ht_print_head(const char *sys);
|
||||
void ht_print_help_icon(void);
|
||||
void ht_ebcdic_to_ascii(char *in, char *out, size_t len);
|
||||
char *ht_mount_point_get(const char *fs_type);
|
||||
u64 ht_ext_tod_2_us(void *tod_ext);
|
||||
void ht_print_time(void);
|
||||
s64 ht_calculate_smt_util(u64 core_us, u64 thr_us, u64 mgm_us, int thread_per_core);
|
||||
|
||||
/*
|
||||
* Memory alloc functions
|
||||
*/
|
||||
extern void *ht_zalloc(size_t size);
|
||||
extern void *ht_alloc(size_t size);
|
||||
extern void *ht_realloc(void *ptr, size_t size);
|
||||
void *ht_zalloc(size_t size);
|
||||
void *ht_alloc(size_t size);
|
||||
void *ht_realloc(void *ptr, size_t size);
|
||||
static inline void ht_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
|
||||
@@ -62,11 +62,11 @@ shown.
|
||||
Select sort field for current window. To reverse the sort order, specify the
|
||||
option twice. See FIELDS below for definitions.
|
||||
.TP
|
||||
.BR "\-t <TYPE>,..." " or " "\-\-cpu_types=<TYPE>,..."
|
||||
.BR "\-t <TYPE>,..." " or " "\-\-cpu-types=<TYPE>,..."
|
||||
Select CPU types that are used for CPU time calculations. See CPU TYPES
|
||||
below for definitions.
|
||||
.TP
|
||||
.BR "\-b" " or " "\-\-batch_mode"
|
||||
.BR "\-b" " or " "\-\-batch-mode"
|
||||
Use batch mode (no curses). This can be useful for sending output from hyptop
|
||||
to another program, a file, or a line mode terminal.
|
||||
In this mode no user input is accepted.
|
||||
@@ -113,13 +113,20 @@ All values are enclosed in double quotation marks and separated by commas. The
|
||||
first line of output contains a list of headings. Subsequent lines each
|
||||
represent data for one system in one iteration.
|
||||
.PP
|
||||
This option implies the "\-\-batch_mode" option.
|
||||
This option implies the "\-\-batch-mode" option.
|
||||
.RE
|
||||
.BR "\-\-all"
|
||||
.RS
|
||||
Use this option with the "--format" option to include fields without valid
|
||||
values in the output. Fields without valid values are omitted from the output
|
||||
by default. When you use the "--all" option, the invalid values are included
|
||||
and shown as "null".
|
||||
.RE
|
||||
.TP
|
||||
.BR "\-d <SECONDS>" " or " "\-\-delay=<SECONDS>"
|
||||
Specifies the delay between screen updates.
|
||||
.TP
|
||||
.BR "\-m <FACTOR>" " or " "\-\-smt_factor=<FACTOR>"
|
||||
.BR "\-m <FACTOR>" " or " "\-\-smt-factor=<FACTOR>"
|
||||
Specifies a workload dependent SMT speedup factor.
|
||||
For IBM z15 servers, the default value is 1.3. If the workload benefits
|
||||
from SMT, you can specify a higher value. If the workload does not benefit
|
||||
@@ -239,7 +246,7 @@ The following units are supported:
|
||||
|
||||
.SH CPU TYPES
|
||||
Depending on the hypervisor different CPU types are supported. These CPU
|
||||
types can be selected either interactively or with the "--cpu_types"
|
||||
types can be selected either interactively or with the "--cpu-types"
|
||||
command line option. The calculation of the CPU data only uses CPUs of
|
||||
the specified types.
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ static enum hyptop_win_action l_sleep(time_t time_s, long time_us)
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = time_s;
|
||||
ts.tv_nsec = time_us * 1000;
|
||||
ts.tv_nsec = util_usecs_to_nsecs(time_us);
|
||||
|
||||
nanosleep(&ts, NULL);
|
||||
return WIN_KEEP;
|
||||
@@ -231,6 +231,8 @@ static void l_fmt_init(void)
|
||||
return;
|
||||
if (g.o.format == FMT_CSV)
|
||||
flags |= FMT_QUOTEALL;
|
||||
if (g.o.format == FMT_CSV || g.o.format_all)
|
||||
flags |= FMT_KEEPINVAL;
|
||||
if (g.o.format == FMT_JSON || g.o.format == FMT_JSONSEQ)
|
||||
flags |= FMT_HANDLEINT;
|
||||
util_fmt_init(stdout, g.o.format, flags, 1);
|
||||
|
||||
@@ -55,6 +55,7 @@ struct hyptop_opts {
|
||||
unsigned int win_specified;
|
||||
unsigned int batch_mode_specified;
|
||||
unsigned int format_specified;
|
||||
unsigned int format_all;
|
||||
enum util_fmt_t format;
|
||||
unsigned int iterations_specified;
|
||||
unsigned int iterations;
|
||||
@@ -183,10 +184,10 @@ enum hyptop_win_action {
|
||||
WIN_KEEP,
|
||||
};
|
||||
|
||||
extern enum hyptop_win_action hyptop_process_input_timeout(void);
|
||||
extern enum hyptop_win_action hyptop_process_input(void);
|
||||
extern enum hyptop_win_action win_switch(struct hyptop_win *w);
|
||||
extern enum hyptop_win_action win_back(void);
|
||||
enum hyptop_win_action hyptop_process_input_timeout(void);
|
||||
enum hyptop_win_action hyptop_process_input(void);
|
||||
enum hyptop_win_action win_switch(struct hyptop_win *w);
|
||||
enum hyptop_win_action win_back(void);
|
||||
|
||||
struct hyptop_win;
|
||||
struct hyptop_win {
|
||||
@@ -205,25 +206,25 @@ struct hyptop_win {
|
||||
* Window sys_list
|
||||
*/
|
||||
extern struct hyptop_win win_sys_list;
|
||||
extern void win_sys_list_init(void);
|
||||
void win_sys_list_init(void);
|
||||
|
||||
/*
|
||||
* Window sys
|
||||
*/
|
||||
extern struct hyptop_win win_sys;
|
||||
extern void win_sys_set(const char *sys_id);
|
||||
extern void win_sys_init(void);
|
||||
void win_sys_set(const char *sys_id);
|
||||
void win_sys_init(void);
|
||||
|
||||
/*
|
||||
* Window cpu_types
|
||||
*/
|
||||
extern void win_cpu_types_init(void);
|
||||
void win_cpu_types_init(void);
|
||||
|
||||
/*
|
||||
* Misc functions
|
||||
*/
|
||||
extern void hyptop_update_term(void);
|
||||
extern void __noreturn hyptop_exit(int rc);
|
||||
extern void hyptop_text_mode(void);
|
||||
void hyptop_update_term(void);
|
||||
void __noreturn hyptop_exit(int rc);
|
||||
void hyptop_text_mode(void);
|
||||
|
||||
#endif /* HYPTOP_H */
|
||||
|
||||
@@ -39,17 +39,28 @@ static char HELP_TEXT[] =
|
||||
"-s, --sys SYSTEM[,..] Systems for current window\n"
|
||||
"-f, --fields LETTER[:UNIT][,..] Fields and units for current window\n"
|
||||
"-S, --sort LETTER Sort field for current window\n"
|
||||
"-t, --cpu_types TYPE[,..] CPU types used for time calculations\n"
|
||||
"-b, --batch_mode Use batch mode (no curses)\n"
|
||||
"-t, --cpu-types TYPE[,..] CPU types used for time calculations\n"
|
||||
"-b, --batch-mode Use batch mode (no curses)\n"
|
||||
" --format FORMAT Output format (" FMT_TYPE_NAMES "), implies -b\n"
|
||||
" --all Include omitted fields (with values of null)\n"
|
||||
" in the output of --format.\n"
|
||||
"-d, --delay SECONDS Delay time between screen updates\n"
|
||||
"-m, --smt_factor FACTOR Machine generation dependent SMT speedup factor.\n"
|
||||
"-m, --smt-factor FACTOR Machine generation dependent SMT speedup factor.\n"
|
||||
"-n, --iterations NUMBER Number of iterations before ending\n";
|
||||
|
||||
/*
|
||||
* Options with long-name only
|
||||
*/
|
||||
#define OPT_FORMAT 256 /* --format */
|
||||
#define OPT_FORMAT_ALL 261 /* --all*/
|
||||
|
||||
/*
|
||||
* Options with underscore to keep compatibility
|
||||
*/
|
||||
#define OPT_BATCH_MODE 257 /* --batch_mode */
|
||||
#define OPT_SORT_FIELD 258 /* --sort | --sort_field */
|
||||
#define OPT_CPU_TYPES 259 /* --cpu_types */
|
||||
#define OPT_SMT_FACTOR 260 /* --smt_factor */
|
||||
|
||||
/*
|
||||
* Initialize default settings
|
||||
@@ -313,6 +324,15 @@ static void l_format_set(const char *str)
|
||||
g.o.format = fmt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the "--all" option to display omitted null values
|
||||
* while using "--format"
|
||||
*/
|
||||
static void l_format_all_set(void)
|
||||
{
|
||||
g.o.format_all = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make option consisteny checks at end of command line parsing
|
||||
*/
|
||||
@@ -320,6 +340,8 @@ static void l_parse_finish(void)
|
||||
{
|
||||
if (g.o.iterations_specified && g.o.iterations == 0)
|
||||
hyptop_exit(0);
|
||||
if (!g.o.format_specified && g.o.format_all)
|
||||
ERR_EXIT("The --all option requires the -–format option\n");
|
||||
if (g.o.cur_win != &win_sys)
|
||||
return;
|
||||
if (!win_sys.opts.sys.specified)
|
||||
@@ -339,15 +361,20 @@ void opts_parse(int argc, char *argv[])
|
||||
static struct option long_options[] = {
|
||||
{ "version", no_argument, NULL, 'v'},
|
||||
{ "help", no_argument, NULL, 'h'},
|
||||
{ "batch_mode", no_argument, NULL, 'b'},
|
||||
{ "batch-mode", no_argument, NULL, 'b'},
|
||||
{ "batch_mode", no_argument, NULL, OPT_BATCH_MODE},
|
||||
{ "all", no_argument, NULL, OPT_FORMAT_ALL },
|
||||
{ "delay", required_argument, NULL, 'd'},
|
||||
{ "smt_factor", required_argument, NULL, 'm'},
|
||||
{ "smt-factor", required_argument, NULL, 'm'},
|
||||
{ "smt_factor", required_argument, NULL, OPT_SMT_FACTOR},
|
||||
{ "window", required_argument, NULL, 'w'},
|
||||
{ "sys", required_argument, NULL, 's'},
|
||||
{ "iterations", required_argument, NULL, 'n'},
|
||||
{ "fields", required_argument, NULL, 'f'},
|
||||
{ "sort_field", required_argument, NULL, 'S'},
|
||||
{ "cpu_types", required_argument, NULL, 't'},
|
||||
{ "sort-field", required_argument, NULL, 'S'},
|
||||
{ "sort_field", required_argument, NULL, OPT_SORT_FIELD},
|
||||
{ "cpu-types", required_argument, NULL, 't'},
|
||||
{ "cpu_types", required_argument, NULL, OPT_CPU_TYPES},
|
||||
{ "format", required_argument, NULL, OPT_FORMAT },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
@@ -366,12 +393,14 @@ void opts_parse(int argc, char *argv[])
|
||||
case 'h':
|
||||
l_usage();
|
||||
hyptop_exit(0);
|
||||
case OPT_BATCH_MODE:
|
||||
case 'b':
|
||||
l_batch_mode_set();
|
||||
break;
|
||||
case 'd':
|
||||
l_delay_set(optarg);
|
||||
break;
|
||||
case OPT_SMT_FACTOR:
|
||||
case 'm':
|
||||
l_factor_set(optarg);
|
||||
break;
|
||||
@@ -384,18 +413,23 @@ void opts_parse(int argc, char *argv[])
|
||||
case 'n':
|
||||
l_iterations_set(optarg);
|
||||
break;
|
||||
case OPT_CPU_TYPES:
|
||||
case 't':
|
||||
l_cpu_types_set(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
l_fields_set(optarg);
|
||||
break;
|
||||
case OPT_SORT_FIELD:
|
||||
case 'S':
|
||||
l_sort_field_set(optarg);
|
||||
break;
|
||||
case OPT_FORMAT:
|
||||
l_format_set(optarg);
|
||||
break;
|
||||
case OPT_FORMAT_ALL:
|
||||
l_format_all_set();
|
||||
break;
|
||||
default:
|
||||
l_std_usage_exit();
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include "hyptop.h"
|
||||
|
||||
extern void opts_parse(int argc, char *argv[]);
|
||||
extern void opts_iterations_next(void);
|
||||
extern int opts_sys_specified(struct hyptop_win *win, const char* sys_name);
|
||||
extern void opt_verify_systems(void);
|
||||
void opts_parse(int argc, char *argv[]);
|
||||
void opts_iterations_next(void);
|
||||
int opts_sys_specified(struct hyptop_win *win, const char *sys_name);
|
||||
void opt_verify_systems(void);
|
||||
|
||||
#endif /* OPTS_H */
|
||||
|
||||
26
hyptop/sd.h
26
hyptop/sd.h
@@ -19,6 +19,7 @@
|
||||
|
||||
#define SD_DG_INIT_INTERVAL_SEC 1
|
||||
#define SD_SYS_ID_SIZE 9
|
||||
#define SD_SYS_DEFAULT_ID "PHYSICAL"
|
||||
|
||||
/*
|
||||
* CPU info
|
||||
@@ -77,6 +78,7 @@ struct sd_sys {
|
||||
struct util_list_node list;
|
||||
struct sd_info i;
|
||||
u64 update_time_us;
|
||||
u64 phys_delta_us;
|
||||
u32 child_cnt;
|
||||
u32 child_cnt_active;
|
||||
struct util_list child_list;
|
||||
@@ -134,6 +136,11 @@ static inline void sd_sys_update_time_us_set(struct sd_sys *sys, u64 value)
|
||||
sys->update_time_us = value;
|
||||
}
|
||||
|
||||
static inline void sd_phys_delta_time_us_set(struct sd_sys *sys, u64 value)
|
||||
{
|
||||
sys->phys_delta_us = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU type
|
||||
*/
|
||||
@@ -301,8 +308,8 @@ struct sd_cpu_item {
|
||||
#define sd_cpu_item_type(x) ((x)->type)
|
||||
#define sd_cpu_item_table_col(item) (&(item)->table_col)
|
||||
|
||||
extern int sd_cpu_item_available(struct sd_cpu_item *item);
|
||||
extern int sd_cpu_item_cnt(void);
|
||||
int sd_cpu_item_available(struct sd_cpu_item *item);
|
||||
int sd_cpu_item_cnt(void);
|
||||
|
||||
/*
|
||||
* Item access functions
|
||||
@@ -370,8 +377,8 @@ struct sd_sys_item {
|
||||
#define sd_sys_item_table_col(item) (&item->table_col)
|
||||
#define sd_sys_item_type(item) (item->type)
|
||||
|
||||
extern int sd_sys_item_available(struct sd_sys_item *item);
|
||||
extern int sd_sys_item_cnt(void);
|
||||
int sd_sys_item_available(struct sd_sys_item *item);
|
||||
int sd_sys_item_cnt(void);
|
||||
|
||||
/*
|
||||
* Item access functions
|
||||
@@ -437,19 +444,23 @@ extern struct sd_sys_item sd_sys_item_os_name;
|
||||
extern struct sd_sys_item sd_sys_item_samples_total;
|
||||
extern struct sd_sys_item sd_sys_item_samples_cpu_using;
|
||||
|
||||
extern struct sd_sys_item sd_sys_item_phys_mgm_diff;
|
||||
|
||||
/*
|
||||
* Data gatherer backend
|
||||
*/
|
||||
struct sd_dg {
|
||||
void (*update_sys)(void);
|
||||
struct sd_cpu_type **cpu_type_vec;
|
||||
struct sd_sys_item **phys_item_vec;
|
||||
struct sd_sys_item **sys_item_vec;
|
||||
struct sd_sys_item **sys_item_enable_vec;
|
||||
struct sd_cpu_item **cpu_item_vec;
|
||||
struct sd_cpu_item **cpu_item_enable_vec;
|
||||
};
|
||||
|
||||
void sd_dg_register(struct sd_dg *, int);
|
||||
void sd_dg_register(struct sd_dg *, int, int);
|
||||
int sd_dg_has_phys_data(void);
|
||||
int sd_dg_has_core_data(void);
|
||||
|
||||
/*
|
||||
@@ -461,6 +472,9 @@ int sd_dg_has_core_data(void);
|
||||
#define sd_cpu_iterate(parent, cpu) \
|
||||
util_list_iterate(&parent->cpu_list, cpu)
|
||||
|
||||
#define sd_phys_item_iterate(ptr, i) \
|
||||
for (i = 0; (ptr = sd.dg->phys_item_vec[i]); i++)
|
||||
|
||||
#define sd_sys_item_iterate(ptr, i) \
|
||||
for (i = 0; (ptr = sd.dg->sys_item_vec[i]); i++)
|
||||
|
||||
@@ -506,7 +520,7 @@ static inline s64 l_cpu_info_s64(struct sd_cpu_info *info,
|
||||
* Misc
|
||||
*/
|
||||
void sd_update(void);
|
||||
extern void sd_init(void);
|
||||
void sd_init(void);
|
||||
|
||||
static inline u64 l_sub_64(u64 x, u64 y)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ static int l_cpu_type_cnt;
|
||||
static int l_sys_item_cnt;
|
||||
static int l_cpu_item_cnt;
|
||||
static int l_has_core_data;
|
||||
static int l_has_phys_data;
|
||||
static struct sd_sys *l_root_sys;
|
||||
|
||||
/*
|
||||
@@ -148,7 +149,7 @@ void sd_update(void)
|
||||
/*
|
||||
* Register a data gatherer
|
||||
*/
|
||||
void sd_dg_register(struct sd_dg *dg, int has_core_data)
|
||||
void sd_dg_register(struct sd_dg *dg, int has_core_data, int has_phys_data)
|
||||
{
|
||||
struct timespec ts = {SD_DG_INIT_INTERVAL_SEC, 0};
|
||||
struct sd_sys_item *sys_item;
|
||||
@@ -156,6 +157,7 @@ void sd_dg_register(struct sd_dg *dg, int has_core_data)
|
||||
unsigned int i;
|
||||
|
||||
l_has_core_data = has_core_data;
|
||||
l_has_phys_data = has_phys_data;
|
||||
sd.dg = dg;
|
||||
for (i = 0; dg->cpu_type_vec[i]; i++)
|
||||
dg->cpu_type_vec[i]->idx = (1UL << i);
|
||||
@@ -172,6 +174,14 @@ void sd_dg_register(struct sd_dg *dg, int has_core_data)
|
||||
l_cpu_types_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Does backend has physical CPUs data?
|
||||
*/
|
||||
int sd_dg_has_phys_data(void)
|
||||
{
|
||||
return l_has_phys_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does backend has core data?
|
||||
*/
|
||||
@@ -419,7 +429,7 @@ int sd_cpu_item_cnt(void)
|
||||
*/
|
||||
void sd_init(void)
|
||||
{
|
||||
l_root_sys = sd_sys_new(NULL, "root");
|
||||
l_root_sys = sd_sys_new(NULL, SD_SYS_DEFAULT_ID);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -48,7 +48,7 @@ static double l_cpu_diff(struct sd_cpu_item *item, struct sd_cpu *cpu, int sign)
|
||||
if (online_time_diff_us == 0)
|
||||
return 0;
|
||||
|
||||
factor = ((double) online_time_diff_us) / 1000000 * cpu->cnt;
|
||||
factor = util_usecs_to_secs(online_time_diff_us) * cpu->cnt;
|
||||
if (sign)
|
||||
diff_us = l_cpu_info_s64(cpu->d_cur, item->offset) -
|
||||
l_cpu_info_s64(cpu->d_prev, item->offset);
|
||||
|
||||
@@ -171,7 +171,7 @@ static double l_cpu_info_diff_u64(struct sd_sys_item *item, struct sd_cpu *cpu,
|
||||
diff_us = l_sub_64(l_cpu_info_u64(cpu->d_cur, item->offset),
|
||||
l_cpu_info_u64(cpu->d_prev, item->offset));
|
||||
}
|
||||
factor = ((double) online_time_diff_us) / 1000000;
|
||||
factor = util_usecs_to_secs(online_time_diff_us);
|
||||
diff_us /= factor;
|
||||
return diff_us;
|
||||
}
|
||||
@@ -220,9 +220,56 @@ static u64 l_sys_smt_util(struct sd_sys_item *item, struct sd_sys *sys)
|
||||
return ht_calculate_smt_util(core_us, thr_us, mgm_us, sys->threads_per_core);
|
||||
}
|
||||
|
||||
/*
|
||||
* value = (value_current - value_prev) / online_time_diff
|
||||
*/
|
||||
static double l_phys_cpu_info_diff_u64(struct sd_sys_item *item,
|
||||
struct sd_cpu *cpu,
|
||||
u64 time_diff_us)
|
||||
{
|
||||
double factor, diff_us;
|
||||
|
||||
if (!sd_cpu_type_selected(cpu->type))
|
||||
return 0;
|
||||
if (sd_cpu_state(cpu) == SD_CPU_STATE_STOPPED)
|
||||
return 0;
|
||||
if (time_diff_us == 0)
|
||||
return 0;
|
||||
diff_us = l_sub_64(l_cpu_info_u64(cpu->d_cur, item->offset),
|
||||
l_cpu_info_u64(cpu->d_prev, item->offset));
|
||||
factor = util_usecs_to_secs(time_diff_us);
|
||||
diff_us /= factor;
|
||||
return diff_us;
|
||||
}
|
||||
|
||||
/*
|
||||
* SUM over all CPUs: value = (value_current - value_prev) / online_time_diff
|
||||
*/
|
||||
static u64 l_sys_phys_cpu_info_diff_u64(struct sd_sys_item *item, struct sd_sys *sys)
|
||||
{
|
||||
struct sd_cpu *cpu;
|
||||
u64 rc = 0;
|
||||
|
||||
sd_cpu_iterate(sys, cpu) {
|
||||
if (!cpu->d_prev || !cpu->d_cur)
|
||||
return 0;
|
||||
rc += l_phys_cpu_info_diff_u64(item, cpu, sys->phys_delta_us);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* System item definitions
|
||||
*/
|
||||
struct sd_sys_item sd_sys_item_phys_mgm_diff = {
|
||||
.table_col = TABLE_COL_TIME_DIFF_SUM(table_col_unit_perc, 'm', "mgm"),
|
||||
.offset = SD_CPU_INFO_OFFSET(mgm_time_us),
|
||||
.type = SD_TYPE_U64,
|
||||
.desc = "Management time per second",
|
||||
.fn_set = l_sys_cpu_info_set,
|
||||
.fn_u64 = l_sys_phys_cpu_info_diff_u64,
|
||||
};
|
||||
|
||||
struct sd_sys_item sd_sys_item_core_cnt = {
|
||||
.table_col = TABLE_COL_CNT_SUM('#', "#core"),
|
||||
.type = SD_TYPE_U32,
|
||||
|
||||
@@ -260,6 +260,10 @@ void table_row_del_all(struct table *t)
|
||||
util_list_remove(&t->row_list, row);
|
||||
table_row_free(row);
|
||||
}
|
||||
if (t->row_physical) {
|
||||
table_row_free(t->row_physical);
|
||||
t->row_physical = NULL;
|
||||
}
|
||||
l_row_last_init(t);
|
||||
t->row_cnt_marked = 0;
|
||||
t->ready = 0;
|
||||
@@ -418,6 +422,8 @@ static void l_row_last_calc(struct table *t)
|
||||
*/
|
||||
void table_finish(struct table *t)
|
||||
{
|
||||
if (t->row_physical)
|
||||
l_row_format(t, t->row_physical);
|
||||
l_row_last_calc(t);
|
||||
t->ready = 1;
|
||||
}
|
||||
@@ -463,6 +469,8 @@ void table_rebuild(struct table *t)
|
||||
l_col_max_width_init(t, col);
|
||||
util_list_iterate(&t->row_list, row)
|
||||
l_row_format(t, row);
|
||||
if (t->row_physical)
|
||||
l_row_format(t, t->row_physical);
|
||||
l_row_format(t, t->row_last);
|
||||
}
|
||||
|
||||
@@ -921,6 +929,10 @@ static void l_table_print_curses(struct table *t)
|
||||
}
|
||||
ht_reverse_on();
|
||||
l_row_print(t, t->row_last);
|
||||
if (t->row_physical) {
|
||||
hyptop_print_nl();
|
||||
l_row_print(t, t->row_physical);
|
||||
}
|
||||
hyptop_print_seek_back(0);
|
||||
ht_reverse_off();
|
||||
#ifdef WITH_SCROLL_BAR
|
||||
@@ -952,6 +964,10 @@ static void l_table_print_all(struct table *t)
|
||||
}
|
||||
l_row_print(t, t->row_last);
|
||||
hyptop_print_nl();
|
||||
if (t->row_physical) {
|
||||
l_row_print(t, t->row_physical);
|
||||
hyptop_print_nl();
|
||||
}
|
||||
hyptop_printf("------------------------------------------------------"
|
||||
"-------------------------\n");
|
||||
}
|
||||
@@ -972,10 +988,15 @@ static void l_row_print_formatted(struct table *t, struct table_row *row)
|
||||
unsigned int flags = 0;
|
||||
struct table_entry *e = &row->entries[col_nr];
|
||||
|
||||
if (row == t->row_last && col_nr == 0)
|
||||
if (row == t->row_last && col_nr == 0) {
|
||||
if (g.o.format == FMT_CSV)
|
||||
util_fmt_pair(FMT_QUOTE, col->head, "SUM", e->str);
|
||||
continue;
|
||||
}
|
||||
if (table_col_needs_quotes(col))
|
||||
flags = FMT_QUOTE;
|
||||
if (strcmp(e->str, "-") == 0 || strcmp(e->str, "") == 0)
|
||||
flags |= FMT_INVAL;
|
||||
util_fmt_pair(flags, col->head, "%s", e->str);
|
||||
}
|
||||
}
|
||||
@@ -991,6 +1012,11 @@ static void l_table_print_all_formatted(struct table *t)
|
||||
util_fmt_pair(FMT_PERSIST, "iteration", "%u", g.o.iterations_act);
|
||||
ht_fmt_time();
|
||||
ht_fmt_cpu_types();
|
||||
if (t->row_physical) {
|
||||
util_fmt_obj_start(FMT_ROW, "physical_information");
|
||||
l_row_print_formatted(t, t->row_physical);
|
||||
util_fmt_obj_end(); /* physical_information{} */
|
||||
}
|
||||
if (strcmp(g.o.cur_win->id, "sys_list") == 0)
|
||||
util_fmt_obj_start(FMT_LIST, "systems");
|
||||
else
|
||||
|
||||
@@ -324,6 +324,7 @@ struct table {
|
||||
struct table_col **col_vec;
|
||||
struct table_col *col_selected;
|
||||
struct table_row *row_last;
|
||||
struct table_row *row_physical;
|
||||
int row_cnt;
|
||||
int row_cnt_marked;
|
||||
int row_cnt_extra;
|
||||
@@ -361,37 +362,37 @@ enum table_scroll_unit {
|
||||
*/
|
||||
extern struct table *table_new(int extra_rows, int sorted, int first_bold,
|
||||
int with_units);
|
||||
extern void table_reset(struct table *t);
|
||||
extern void table_rebuild(struct table *t);
|
||||
extern void table_finish(struct table *t);
|
||||
extern void table_print(struct table *t);
|
||||
extern void table_process_input(struct table *t, int c);
|
||||
void table_reset(struct table *t);
|
||||
void table_rebuild(struct table *t);
|
||||
void table_finish(struct table *t);
|
||||
void table_print(struct table *t);
|
||||
void table_process_input(struct table *t, int c);
|
||||
|
||||
extern void table_col_unit_next(struct table *t, char hotkey);
|
||||
extern void table_col_unit_prev(struct table *t, char hotkey);
|
||||
extern int table_col_unit_set(struct table *t, char hotkey, const char *unit);
|
||||
extern void table_col_add(struct table *t, struct table_col *col);
|
||||
extern int table_col_select(struct table *t, char hotkey);
|
||||
extern void table_col_select_next(struct table *t);
|
||||
extern void table_col_select_prev(struct table *t);
|
||||
extern void table_col_enable_toggle(struct table *t, char hotkey);
|
||||
void table_col_unit_next(struct table *t, char hotkey);
|
||||
void table_col_unit_prev(struct table *t, char hotkey);
|
||||
int table_col_unit_set(struct table *t, char hotkey, const char *unit);
|
||||
void table_col_add(struct table *t, struct table_col *col);
|
||||
int table_col_select(struct table *t, char hotkey);
|
||||
void table_col_select_next(struct table *t);
|
||||
void table_col_select_prev(struct table *t);
|
||||
void table_col_enable_toggle(struct table *t, char hotkey);
|
||||
|
||||
extern void table_row_del_all(struct table *t);
|
||||
extern void table_row_add(struct table *t, struct table_row *row);
|
||||
extern void table_row_mark(struct table *t, struct table_row *row);
|
||||
extern void table_row_mark_del_all(struct table *t);
|
||||
extern void table_row_mark_toggle(struct table *t, struct table_row *row);
|
||||
extern void table_row_mark_toggle_by_key(struct table *t, const char *mark_key);
|
||||
extern void table_row_select_down(struct table *t, enum table_scroll_unit unit);
|
||||
extern void table_row_select_up(struct table *t, enum table_scroll_unit unit);
|
||||
extern void table_row_select_key_get(struct table *t, char str[TABLE_STR_MAX]);
|
||||
extern struct table_row *table_row_alloc(struct table *t);
|
||||
void table_row_del_all(struct table *t);
|
||||
void table_row_add(struct table *t, struct table_row *row);
|
||||
void table_row_mark(struct table *t, struct table_row *row);
|
||||
void table_row_mark_del_all(struct table *t);
|
||||
void table_row_mark_toggle(struct table *t, struct table_row *row);
|
||||
void table_row_mark_toggle_by_key(struct table *t, const char *mark_key);
|
||||
void table_row_select_down(struct table *t, enum table_scroll_unit unit);
|
||||
void table_row_select_up(struct table *t, enum table_scroll_unit unit);
|
||||
void table_row_select_key_get(struct table *t, char str[TABLE_STR_MAX]);
|
||||
struct table_row *table_row_alloc(struct table *t);
|
||||
|
||||
extern void table_scroll_down(struct table *t, enum table_scroll_unit unit);
|
||||
extern void table_scroll_up(struct table *t, enum table_scroll_unit unit);
|
||||
void table_scroll_down(struct table *t, enum table_scroll_unit unit);
|
||||
void table_scroll_up(struct table *t, enum table_scroll_unit unit);
|
||||
|
||||
extern void table_fmt_start(void);
|
||||
extern void table_fmt_end(void);
|
||||
void table_fmt_start(void);
|
||||
void table_fmt_end(void);
|
||||
|
||||
/*
|
||||
* Entry add functions
|
||||
|
||||
@@ -153,7 +153,7 @@ struct table_col_unit table_col_unit_us = {
|
||||
*/
|
||||
static int l_unit_ms(struct table_col *col, struct table_entry *e)
|
||||
{
|
||||
return l_unit_raw_div(col, e, 1000, L_COL_FMT_STR_2);
|
||||
return l_unit_raw_div(col, e, USEC_PER_MSEC, L_COL_FMT_STR_2);
|
||||
}
|
||||
|
||||
struct table_col_unit table_col_unit_ms = {
|
||||
@@ -167,7 +167,7 @@ struct table_col_unit table_col_unit_ms = {
|
||||
*/
|
||||
static int l_unit_perc(struct table_col *col, struct table_entry *e)
|
||||
{
|
||||
return l_unit_raw_div(col, e, 10000, L_COL_FMT_STR_2);
|
||||
return l_unit_raw_div(col, e, (USEC_PER_SEC / 100), L_COL_FMT_STR_2);
|
||||
}
|
||||
|
||||
struct table_col_unit table_col_unit_perc = {
|
||||
@@ -182,7 +182,7 @@ struct table_col_unit table_col_unit_perc = {
|
||||
*/
|
||||
static int l_unit_s(struct table_col *col, struct table_entry *e)
|
||||
{
|
||||
return l_unit_raw_div(col, e, 1000000, L_COL_FMT_STR_2);
|
||||
return l_unit_raw_div(col, e, USEC_PER_SEC, L_COL_FMT_STR_2);
|
||||
}
|
||||
|
||||
struct table_col_unit table_col_unit_s = {
|
||||
@@ -197,7 +197,7 @@ struct table_col_unit table_col_unit_s = {
|
||||
*/
|
||||
static int l_unit_m(struct table_col *col, struct table_entry *e)
|
||||
{
|
||||
return l_unit_raw_div(col, e, 1000000 * 60, L_COL_FMT_STR_0);
|
||||
return l_unit_raw_div(col, e, USEC_PER_SEC * 60, L_COL_FMT_STR_0);
|
||||
}
|
||||
|
||||
static struct table_col_unit table_col_unit_m = {
|
||||
@@ -214,7 +214,7 @@ static int l_unit_hm_u64(char *str, u64 v1, int negative)
|
||||
{
|
||||
u64 time_tmp, time_h, time_m;
|
||||
|
||||
time_tmp = v1 / (1000000 * 60);
|
||||
time_tmp = v1 / (USEC_PER_SEC * 60);
|
||||
time_h = time_tmp / 60;
|
||||
time_m = time_tmp - time_h * 60;
|
||||
|
||||
@@ -259,7 +259,7 @@ static int l_unit_dhm_u64(char *str, u64 v1, int negative)
|
||||
{
|
||||
u64 time_tmp, time_d, time_h, time_m;
|
||||
|
||||
time_tmp = v1 / (1000000 * 60);
|
||||
time_tmp = v1 / (USEC_PER_SEC * 60);
|
||||
time_d = time_tmp / (60 * 24);
|
||||
time_h = time_tmp / 60 - time_d * 24;
|
||||
time_m = time_tmp - time_h * 60 - time_d * 60 * 24;
|
||||
@@ -312,10 +312,8 @@ static int l_unit_vis(struct table_col *col, struct table_entry *e)
|
||||
assert(col->type == TABLE_COL_TYPE_U64);
|
||||
|
||||
sprintf(e->str, "|");
|
||||
val1_perc = e->d.u64.v1;
|
||||
val1_perc /= 1000000;
|
||||
val2_perc = e->d.u64.v2;
|
||||
val2_perc /= 1000000;
|
||||
val1_perc = util_usecs_to_secs(e->d.u64.v1);
|
||||
val2_perc = util_usecs_to_secs(e->d.u64.v2);
|
||||
val1_nr = (val1_perc * L_VISUAL_ROW_CNT) + 0.5;
|
||||
val2_nr = (val2_perc * L_VISUAL_ROW_CNT) + 0.5;
|
||||
|
||||
|
||||
@@ -23,6 +23,6 @@ struct win_cpu_types {
|
||||
struct hyptop_win *win_help;
|
||||
};
|
||||
|
||||
extern struct hyptop_win *win_cpu_types_new(void);
|
||||
struct hyptop_win *win_cpu_types_new(void);
|
||||
|
||||
#endif /* WIN_CPU_TYPES_H */
|
||||
|
||||
@@ -162,6 +162,22 @@ static void l_sys_item_add(struct table_row *table_row, struct sd_sys *sys,
|
||||
}
|
||||
}
|
||||
|
||||
static void l_row_add_physical(struct table *t, struct sd_sys *sys)
|
||||
{
|
||||
struct sd_sys_item *item;
|
||||
struct table_row *row;
|
||||
unsigned int i;
|
||||
|
||||
row = table_row_alloc(t);
|
||||
table_row_entry_str_add(row, &l_col_sys, sd_sys_id(sys));
|
||||
sd_phys_item_iterate(item, i) {
|
||||
if (!sd_sys_item_set(sys, item))
|
||||
continue;
|
||||
l_sys_item_add(row, sys, item);
|
||||
}
|
||||
t->row_physical = row;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add system to table
|
||||
*/
|
||||
@@ -196,6 +212,8 @@ static void l_table_create(void)
|
||||
continue;
|
||||
l_sys_add(guest);
|
||||
}
|
||||
if (sd_dg_has_phys_data())
|
||||
l_row_add_physical(l_t, parent);
|
||||
table_finish(l_t);
|
||||
}
|
||||
|
||||
@@ -324,6 +342,11 @@ static void l_run(struct hyptop_win *win)
|
||||
}
|
||||
}
|
||||
|
||||
static void win_sys_list_set_phys_table_cols(void)
|
||||
{
|
||||
sd_sys_item_phys_mgm_diff.table_col = sd_sys_item_mgm_diff.table_col;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize window
|
||||
*/
|
||||
@@ -337,7 +360,7 @@ void win_sys_list_init(void)
|
||||
int item_cnt;
|
||||
|
||||
/* Alloc table and add columns */
|
||||
l_t = table_new(1, 1, 1, 1);
|
||||
l_t = table_new(2, 1, 1, 1);
|
||||
table_col_add(l_t, &l_col_sys);
|
||||
|
||||
item_cnt = sd_sys_item_cnt() + 1;
|
||||
@@ -351,6 +374,8 @@ void win_sys_list_init(void)
|
||||
col_vec[i] = col;
|
||||
col_desc_vec[i] = item->desc;
|
||||
}
|
||||
if (sd_dg_has_phys_data())
|
||||
win_sys_list_set_phys_table_cols();
|
||||
/* Enable fields */
|
||||
if (win_sys_list.opts.fields.specified)
|
||||
l_fields_enable_cmdline();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define UNPACK_FACILITY _AC(161, U)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <asm/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
@@ -380,18 +381,6 @@ static __always_inline int is_zvm(void)
|
||||
return cpuid.version == 0xff;
|
||||
}
|
||||
|
||||
/* To avoid conflicts add a macro guard since __vector128 is also
|
||||
* defined in 'linux/asm/types.h'.
|
||||
*/
|
||||
#ifndef _S390_TYPES_H
|
||||
/*
|
||||
* Vector register definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t u[4];
|
||||
} __vector128;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Save vector registers
|
||||
*/
|
||||
|
||||
@@ -379,6 +379,25 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
|
||||
const char *cert_pem_filename,
|
||||
const struct ekmf_ext_lib *ext_lib, bool verbose);
|
||||
|
||||
/**
|
||||
* Validates that a certificate has the same public key as the secure identity
|
||||
* key (field identity_secure_key in config structure) .
|
||||
*
|
||||
* @param config the configuration structure. Only field
|
||||
* identity_secure_key must be specified, all others
|
||||
* are optional.
|
||||
* @param x509_cert the X509 certificate object to validate
|
||||
* @param ext_lib External secure key crypto library to use
|
||||
* @param verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns a negative errno in case of an error, 0 if success.
|
||||
* -EINVAL: invalid parameter, or certificate is not valid
|
||||
* -ENOMEM: Failed to allocate memory
|
||||
* any other errno from file I/O routines
|
||||
*/
|
||||
int ekmf_validate_cert(const struct ekmf_config *config, const X509 *x509_cert,
|
||||
const struct ekmf_ext_lib *ext_lib, bool verbose);
|
||||
|
||||
/**
|
||||
* Retrieves settings from the EKMFWeb server, such as the template names for
|
||||
* generating keys in EKMFWeb.
|
||||
|
||||
22
include/lib/util_autocomp.h
Normal file
22
include/lib/util_autocomp.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* autocomp - command line autocompletion
|
||||
*
|
||||
* Generating autocompletion scripts for bash and zsh
|
||||
* based on util_opt struct
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIB_UTIL_AUTOCOMP_H
|
||||
#define LIB_UTIL_AUTOCOMP_H
|
||||
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
void generate_autocomp(struct util_opt *opt_vec, char *tool_name);
|
||||
|
||||
#endif
|
||||
@@ -12,6 +12,7 @@
|
||||
#ifndef LIB_UTIL_LIBC_H
|
||||
#define LIB_UTIL_LIBC_H
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -45,7 +46,7 @@ void *__util_zalloc(const char *func, const char *file, int line, size_t size);
|
||||
/**
|
||||
* Re-allocate memory or exit in case of failure
|
||||
*
|
||||
* @param[in] ptr Pointer ot old memory buffer
|
||||
* @param[in] ptr Pointer to old memory buffer
|
||||
* @param[in] size Number of bytes to be allocated
|
||||
*
|
||||
* @returns Pointer to memory buffer created with realloc()
|
||||
@@ -124,6 +125,29 @@ do { \
|
||||
va_end(ap); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Reads the target of a symbolic link at the given path.
|
||||
*
|
||||
* @param[in] path Path to the symbolic link
|
||||
* @return Newly allocated string with the link target, or NULL on error
|
||||
*/
|
||||
#define util_readlink(path) __util_readlinkat(__func__, __FILE__, __LINE__, AT_FDCWD, path)
|
||||
|
||||
/**
|
||||
* Reads the target of a symbolic link relative to a directory file descriptor.
|
||||
*
|
||||
* Semantics:
|
||||
* - If path is absolute, dirfd is ignored, per readlinkat semantics.
|
||||
* - If path is relative, it is resolved relative to dirfd.
|
||||
*
|
||||
* @param[in] dirfd Directory file descriptor or AT_FDCWD
|
||||
* @param[in] path Path to the symbolic link
|
||||
* @return Newly allocated string with the link target, or NULL on error
|
||||
*/
|
||||
#define util_readlinkat(dirfd, path) __util_readlinkat(__func__, __FILE__, __LINE__, dirfd, path)
|
||||
|
||||
char *__util_readlinkat(const char *func, const char *file, int line, int dirfd, const char *path);
|
||||
|
||||
int __util_vsprintf(const char *func, const char *file, int line,
|
||||
char *str, const char *fmt, va_list ap);
|
||||
char *util_strcat_realloc(char *str1, const char *str2);
|
||||
|
||||
58
include/lib/util_parse.h
Normal file
58
include/lib/util_parse.h
Normal 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
|
||||
@@ -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 @} */
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define LIB_UTIL_SYS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int util_sys_get_dev_addr(const char *dev, char *addr);
|
||||
bool util_sys_dev_is_partition(dev_t dev);
|
||||
|
||||
202
include/lib/util_time.h
Normal file
202
include/lib/util_time.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* util_time - Time related helper functions and definitions
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef LIB_UTIL_TIME_H
|
||||
#define LIB_UTIL_TIME_H
|
||||
|
||||
#define NSEC_PER_USEC 1000L
|
||||
#define NSEC_PER_MSEC 1000000L
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
|
||||
#define USEC_PER_MSEC 1000L
|
||||
#define USEC_PER_SEC 1000000L
|
||||
|
||||
#define MSEC_PER_SEC 1000L
|
||||
|
||||
/**
|
||||
* Convert nanoseconds to microseconds
|
||||
*
|
||||
* Convert value from nanoseconds to microseconds by dividing the
|
||||
* value to NSEC_PER_USEC constant.
|
||||
*
|
||||
* @param[in] val Time value in nanoseconds
|
||||
*
|
||||
* @returns Time value in microseconds
|
||||
*/
|
||||
static inline double util_nsecs_to_usecs(double val)
|
||||
{
|
||||
return val / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert nanoseconds to milliseconds
|
||||
*
|
||||
* Convert value from nanoseconds to milliseconds by dividing the
|
||||
* value to NSEC_PER_MSEC constant.
|
||||
*
|
||||
* @param[in] val Time value in nanoseconds
|
||||
*
|
||||
* @returns Time value in milliseconds
|
||||
*/
|
||||
static inline double util_nsecs_to_msecs(double val)
|
||||
{
|
||||
return val / NSEC_PER_MSEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert nanoseconds to seconds
|
||||
*
|
||||
* Convert value from nanoseconds to seconds by dividing the
|
||||
* value to NSEC_PER_SEC constant.
|
||||
*
|
||||
* @param[in] val Time value in nanoseconds
|
||||
*
|
||||
* @returns Time value in seconds
|
||||
*/
|
||||
static inline double util_nsecs_to_secs(double val)
|
||||
{
|
||||
return val / NSEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert microseconds to nanoseconds
|
||||
*
|
||||
* Convert value from microseconds to nanoseconds by multiplying the
|
||||
* value with NSEC_PER_USEC constant.
|
||||
*
|
||||
* @param[in] val Time value in microseconds
|
||||
*
|
||||
* @returns Time value in nanoseconds
|
||||
*/
|
||||
static inline double util_usecs_to_nsecs(double val)
|
||||
{
|
||||
return val * NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert microseconds to milliseconds
|
||||
*
|
||||
* Convert value from microseconds to milliseconds by dividing the
|
||||
* value to USEC_PER_MSEC constant.
|
||||
*
|
||||
* @param[in] val Time value in microseconds
|
||||
*
|
||||
* @returns Time value in milliseconds
|
||||
*/
|
||||
static inline double util_usecs_to_msecs(double val)
|
||||
{
|
||||
return val / USEC_PER_MSEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert microseconds to seconds
|
||||
*
|
||||
* Convert value from microseconds to seconds by dividing the
|
||||
* value to USEC_PER_SEC constant.
|
||||
*
|
||||
* @param[in] val Time value in nanoseconds
|
||||
*
|
||||
* @returns Time value in seconds
|
||||
*/
|
||||
static inline double util_usecs_to_secs(double val)
|
||||
{
|
||||
return val / USEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert milliseconds to nanoseconds
|
||||
*
|
||||
* Convert value from milliseconds to nanoseconds by multiplying the
|
||||
* value with NSEC_PER_MSEC constant.
|
||||
*
|
||||
* @param[in] val Time value in milliseconds
|
||||
*
|
||||
* @returns Time value in nanoseconds
|
||||
*/
|
||||
static inline double util_msecs_to_nsecs(double val)
|
||||
{
|
||||
return val * NSEC_PER_MSEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert milliseconds to microseconds
|
||||
*
|
||||
* Convert value from milliseconds to microseconds by multiplying the
|
||||
* value with USEC_PER_MSEC constant.
|
||||
*
|
||||
* @param[in] val Time value in milliseconds
|
||||
*
|
||||
* @returns Time value in microseconds
|
||||
*/
|
||||
static inline double util_msecs_to_usecs(double val)
|
||||
{
|
||||
return val * USEC_PER_MSEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert milliseconds to seconds
|
||||
*
|
||||
* Convert value from milliseconds to seconds by dividing the
|
||||
* value to MSEC_PER_SEC constant.
|
||||
*
|
||||
* @param[in] val Time value in milliseconds
|
||||
*
|
||||
* @returns Time value in seconds
|
||||
*/
|
||||
static inline double util_msecs_to_secs(double val)
|
||||
{
|
||||
return val / MSEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert seconds to nanoseconds
|
||||
*
|
||||
* Convert value from seconds to nanoseconds by multiplying the
|
||||
* value with NSEC_PER_SEC constant.
|
||||
*
|
||||
* @param[in] val Time value in seconds
|
||||
*
|
||||
* @returns Time value in nanoseconds
|
||||
*/
|
||||
static inline double util_secs_to_nsecs(double val)
|
||||
{
|
||||
return val * NSEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert seconds to microseconds
|
||||
*
|
||||
* Convert value from seconds to microseconds by multiplying the
|
||||
* value with USEC_PER_SEC constant.
|
||||
*
|
||||
* @param[in] val Time value in seconds
|
||||
*
|
||||
* @returns Time value in microseconds
|
||||
*/
|
||||
static inline double util_secs_to_usecs(double val)
|
||||
{
|
||||
return val * USEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert seconds to milliseconds
|
||||
*
|
||||
* Convert value from seconds to milliseconds by multiplying the
|
||||
* value with MSEC_PER_SEC constant.
|
||||
*
|
||||
* @param[in] val Time value in seconds
|
||||
*
|
||||
* @returns Time value in milliseconds
|
||||
*/
|
||||
static inline double util_secs_to_msecs(double val)
|
||||
{
|
||||
return val * MSEC_PER_SEC;
|
||||
}
|
||||
|
||||
#endif /* LIB_UTIL_TIME_H */
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -44,27 +45,27 @@
|
||||
|
||||
typedef struct ttr
|
||||
{
|
||||
u_int16_t tt;
|
||||
u_int8_t r;
|
||||
uint16_t tt;
|
||||
uint8_t r;
|
||||
} __attribute__ ((packed)) ttr_t;
|
||||
|
||||
typedef struct cchhb
|
||||
{
|
||||
u_int16_t cc;
|
||||
u_int16_t hh;
|
||||
u_int8_t b;
|
||||
uint16_t cc;
|
||||
uint16_t hh;
|
||||
uint8_t b;
|
||||
} __attribute__ ((packed)) cchhb_t;
|
||||
|
||||
typedef struct cchh
|
||||
{
|
||||
u_int16_t cc;
|
||||
u_int16_t hh;
|
||||
uint16_t cc;
|
||||
uint16_t hh;
|
||||
} __attribute__ ((packed)) cchh_t;
|
||||
|
||||
typedef struct labeldate
|
||||
{
|
||||
u_int8_t year;
|
||||
u_int16_t day;
|
||||
uint8_t year;
|
||||
uint16_t day;
|
||||
} __attribute__ ((packed)) labeldate_t;
|
||||
|
||||
/*
|
||||
@@ -84,7 +85,7 @@ typedef struct volume_label
|
||||
char volkey[4]; /* volume key = volume label */
|
||||
char vollbl[4]; /* volume label */
|
||||
char volid[6]; /* volume identifier */
|
||||
u_int8_t security; /* security byte */
|
||||
uint8_t security; /* security byte */
|
||||
cchhb_t vtoc; /* VTOC address */
|
||||
char res1[5]; /* reserved */
|
||||
char cisize[4]; /* CI-size for FBA,... */
|
||||
@@ -118,8 +119,8 @@ static inline int is_vol1(char *this)
|
||||
|
||||
typedef struct extent
|
||||
{
|
||||
u_int8_t typeind; /* extent type indicator */
|
||||
u_int8_t seqno; /* extent sequence number */
|
||||
uint8_t typeind; /* extent type indicator */
|
||||
uint8_t seqno; /* extent sequence number */
|
||||
cchh_t llimit; /* starting point of this extent */
|
||||
cchh_t ulimit; /* ending point of this extent */
|
||||
} __attribute__ ((packed)) extent_t;
|
||||
@@ -127,16 +128,16 @@ typedef struct extent
|
||||
|
||||
typedef struct dev_const
|
||||
{
|
||||
u_int16_t DS4DSCYL; /* number of logical cyls */
|
||||
u_int16_t DS4DSTRK; /* number of tracks in a logical cylinder */
|
||||
u_int16_t DS4DEVTK; /* device track length */
|
||||
u_int8_t DS4DEVI; /* non-last keyed record overhead */
|
||||
u_int8_t DS4DEVL; /* last keyed record overhead */
|
||||
u_int8_t DS4DEVK; /* non-keyed record overhead differential */
|
||||
u_int8_t DS4DEVFG; /* flag byte */
|
||||
u_int16_t DS4DEVTL; /* device tolerance */
|
||||
u_int8_t DS4DEVDT; /* number of DSCB's per track */
|
||||
u_int8_t DS4DEVDB; /* number of directory blocks per track */
|
||||
uint16_t DS4DSCYL; /* number of logical cyls */
|
||||
uint16_t DS4DSTRK; /* number of tracks in a logical cylinder */
|
||||
uint16_t DS4DEVTK; /* device track length */
|
||||
uint8_t DS4DEVI; /* non-last keyed record overhead */
|
||||
uint8_t DS4DEVL; /* last keyed record overhead */
|
||||
uint8_t DS4DEVK; /* non-keyed record overhead differential */
|
||||
uint8_t DS4DEVFG; /* flag byte */
|
||||
uint16_t DS4DEVTL; /* device tolerance */
|
||||
uint8_t DS4DEVDT; /* number of DSCB's per track */
|
||||
uint8_t DS4DEVDB; /* number of directory blocks per track */
|
||||
} __attribute__ ((packed)) dev_const_t;
|
||||
|
||||
/*
|
||||
@@ -146,33 +147,33 @@ typedef struct dev_const
|
||||
typedef struct format1_label
|
||||
{
|
||||
char DS1DSNAM[44]; /* data set name */
|
||||
u_int8_t DS1FMTID; /* format identifier */
|
||||
uint8_t DS1FMTID; /* format identifier */
|
||||
unsigned char DS1DSSN[6];/* data set serial number */
|
||||
u_int16_t DS1VOLSQ; /* volume sequence number */
|
||||
uint16_t DS1VOLSQ; /* volume sequence number */
|
||||
labeldate_t DS1CREDT; /* creation date: ydd */
|
||||
labeldate_t DS1EXPDT; /* expiration date */
|
||||
u_int8_t DS1NOEPV; /* number of extents on volume */
|
||||
u_int8_t DS1NOBDB; /* no. of bytes used in last direction blk */
|
||||
u_int8_t DS1FLAG1; /* flag 1 */
|
||||
uint8_t DS1NOEPV; /* number of extents on volume */
|
||||
uint8_t DS1NOBDB; /* no. of bytes used in last direction blk */
|
||||
uint8_t DS1FLAG1; /* flag 1 */
|
||||
unsigned char DS1SYSCD[13]; /* system code */
|
||||
labeldate_t DS1REFD; /* date last referenced */
|
||||
u_int8_t DS1SMSFG; /* system managed storage indicators */
|
||||
u_int8_t DS1SCXTF; /* sec. space extension flag byte */
|
||||
u_int16_t DS1SCXTV; /* secondary space extension value */
|
||||
u_int8_t DS1DSRG1; /* data set organisation byte 1 */
|
||||
u_int8_t DS1DSRG2; /* data set organisation byte 2 */
|
||||
u_int8_t DS1RECFM; /* record format */
|
||||
u_int8_t DS1OPTCD; /* option code */
|
||||
u_int16_t DS1BLKL; /* block length */
|
||||
u_int16_t DS1LRECL; /* record length */
|
||||
u_int8_t DS1KEYL; /* key length */
|
||||
u_int16_t DS1RKP; /* relative key position */
|
||||
u_int8_t DS1DSIND; /* data set indicators */
|
||||
u_int8_t DS1SCAL1; /* secondary allocation flag byte */
|
||||
uint8_t DS1SMSFG; /* system managed storage indicators */
|
||||
uint8_t DS1SCXTF; /* sec. space extension flag byte */
|
||||
uint16_t DS1SCXTV; /* secondary space extension value */
|
||||
uint8_t DS1DSRG1; /* data set organisation byte 1 */
|
||||
uint8_t DS1DSRG2; /* data set organisation byte 2 */
|
||||
uint8_t DS1RECFM; /* record format */
|
||||
uint8_t DS1OPTCD; /* option code */
|
||||
uint16_t DS1BLKL; /* block length */
|
||||
uint16_t DS1LRECL; /* record length */
|
||||
uint8_t DS1KEYL; /* key length */
|
||||
uint16_t DS1RKP; /* relative key position */
|
||||
uint8_t DS1DSIND; /* data set indicators */
|
||||
uint8_t DS1SCAL1; /* secondary allocation flag byte */
|
||||
char DS1SCAL3[3]; /* secondary allocation quantity */
|
||||
ttr_t DS1LSTAR; /* last used track and block on track */
|
||||
u_int16_t DS1TRBAL; /* space remaining on last used track */
|
||||
u_int16_t res1; /* reserved */
|
||||
uint16_t DS1TRBAL; /* space remaining on last used track */
|
||||
uint16_t res1; /* reserved */
|
||||
extent_t DS1EXT1; /* first extent description */
|
||||
extent_t DS1EXT2; /* second extent description */
|
||||
extent_t DS1EXT3; /* third extent description */
|
||||
@@ -184,7 +185,7 @@ typedef struct format3_label
|
||||
{
|
||||
char DS3KEYID[4]; /* key identifier */
|
||||
extent_t DS3EXTNT[4]; /* first 4 extent descriptions */
|
||||
u_int8_t DS3FMTID; /* format identifier */
|
||||
uint8_t DS3FMTID; /* format identifier */
|
||||
extent_t DS3ADEXT[9]; /* last 9 extent description */
|
||||
cchhb_t DS3PTRDS; /* pointer to next format3 DSCB */
|
||||
} __attribute__ ((packed)) format3_label_t;
|
||||
@@ -193,15 +194,15 @@ typedef struct format3_label
|
||||
typedef struct format4_label
|
||||
{
|
||||
char DS4KEYCD[44]; /* key code for VTOC labels: 44 times 0x04 */
|
||||
u_int8_t DS4IDFMT; /* format identifier */
|
||||
uint8_t DS4IDFMT; /* format identifier */
|
||||
cchhb_t DS4HPCHR; /* highest address of a format 1 DSCB */
|
||||
u_int16_t DS4DSREC; /* number of available DSCB's */
|
||||
uint16_t DS4DSREC; /* number of available DSCB's */
|
||||
cchh_t DS4HCCHH; /* CCHH of next available alternate track */
|
||||
u_int16_t DS4NOATK; /* number of remaining alternate tracks */
|
||||
u_int8_t DS4VTOCI; /* VTOC indicators */
|
||||
u_int8_t DS4NOEXT; /* number of extents in VTOC */
|
||||
u_int8_t DS4SMSFG; /* system managed storage indicators */
|
||||
u_int8_t DS4DEVAC; /* number of alternate cylinders.
|
||||
uint16_t DS4NOATK; /* number of remaining alternate tracks */
|
||||
uint8_t DS4VTOCI; /* VTOC indicators */
|
||||
uint8_t DS4NOEXT; /* number of extents in VTOC */
|
||||
uint8_t DS4SMSFG; /* system managed storage indicators */
|
||||
uint8_t DS4DEVAC; /* number of alternate cylinders.
|
||||
Subtract from first two bytes of
|
||||
DS4DEVSZ to get number of usable
|
||||
cylinders. can be zero. valid
|
||||
@@ -214,21 +215,21 @@ typedef struct format4_label
|
||||
char DS4F6PTR[5]; /* pointer to first format 6 DSCB */
|
||||
extent_t DS4VTOCE; /* VTOC extent description */
|
||||
char res2[10]; /* reserved */
|
||||
u_int8_t DS4EFLVL; /* extended free-space management level */
|
||||
uint8_t DS4EFLVL; /* extended free-space management level */
|
||||
cchhb_t DS4EFPTR; /* pointer to extended free-space info */
|
||||
char res3; /* reserved */
|
||||
u_int32_t DS4DCYL; /* number of logical cyls */
|
||||
uint32_t DS4DCYL; /* number of logical cyls */
|
||||
char res4[2]; /* reserved */
|
||||
u_int8_t DS4DEVF2; /* device flags */
|
||||
uint8_t DS4DEVF2; /* device flags */
|
||||
char res5; /* reserved */
|
||||
} __attribute__ ((packed)) format4_label_t;
|
||||
|
||||
|
||||
typedef struct ds5ext
|
||||
{
|
||||
u_int16_t t; /* RTA of the first track of free extent */
|
||||
u_int16_t fc; /* number of whole cylinders in free ext. */
|
||||
u_int8_t ft; /* number of remaining free tracks */
|
||||
uint16_t t; /* RTA of the first track of free extent */
|
||||
uint16_t fc; /* number of whole cylinders in free ext. */
|
||||
uint8_t ft; /* number of remaining free tracks */
|
||||
} __attribute__ ((packed)) ds5ext_t;
|
||||
|
||||
|
||||
@@ -237,7 +238,7 @@ typedef struct format5_label
|
||||
char DS5KEYID[4]; /* key identifier */
|
||||
ds5ext_t DS5AVEXT; /* first available (free-space) extent. */
|
||||
ds5ext_t DS5EXTAV[7]; /* seven available extents */
|
||||
u_int8_t DS5FMTID; /* format identifier */
|
||||
uint8_t DS5FMTID; /* format identifier */
|
||||
ds5ext_t DS5MAVET[18]; /* eighteen available extents */
|
||||
cchhb_t DS5PTRDS; /* pointer to next format5 DSCB */
|
||||
} __attribute__ ((packed)) format5_label_t;
|
||||
@@ -245,8 +246,8 @@ typedef struct format5_label
|
||||
|
||||
typedef struct ds7ext
|
||||
{
|
||||
u_int32_t a; /* starting RTA value */
|
||||
u_int32_t b; /* ending RTA value + 1 */
|
||||
uint32_t a; /* starting RTA value */
|
||||
uint32_t b; /* ending RTA value + 1 */
|
||||
} __attribute__ ((packed)) ds7ext_t;
|
||||
|
||||
|
||||
@@ -254,7 +255,7 @@ typedef struct format7_label
|
||||
{
|
||||
char DS7KEYID[4]; /* key identifier */
|
||||
ds7ext_t DS7EXTNT[5]; /* space for 5 extent descriptions */
|
||||
u_int8_t DS7FMTID; /* format identifier */
|
||||
uint8_t DS7FMTID; /* format identifier */
|
||||
ds7ext_t DS7ADEXT[11]; /* space for 11 extent descriptions */
|
||||
char res1[2]; /* reserved */
|
||||
cchhb_t DS7PTRDS; /* pointer to next FMT7 DSCB */
|
||||
@@ -263,12 +264,12 @@ typedef struct format7_label
|
||||
|
||||
typedef struct format9_label
|
||||
{
|
||||
u_int8_t DS9KEYID; /* key code for format 9 labels (0x09) */
|
||||
u_int8_t DS9SUBTY; /* subtype (0x01) */
|
||||
u_int8_t DS9NUMF9; /* number of F9 datasets */
|
||||
u_int8_t res1[41]; /* reserved */
|
||||
u_int8_t DS9FMTID; /* format identifier */
|
||||
u_int8_t res2[90]; /* reserved */
|
||||
uint8_t DS9KEYID; /* key code for format 9 labels (0x09) */
|
||||
uint8_t DS9SUBTY; /* subtype (0x01) */
|
||||
uint8_t DS9NUMF9; /* number of F9 datasets */
|
||||
uint8_t res1[41]; /* reserved */
|
||||
uint8_t DS9FMTID; /* format identifier */
|
||||
uint8_t res2[90]; /* reserved */
|
||||
cchhb_t DS9PTRDS; /* pointer to next DSCB */
|
||||
} __attribute__ ((packed)) format9_label_t;
|
||||
|
||||
@@ -276,31 +277,31 @@ char * vtoc_ebcdic_enc (char *source, char *target, int l);
|
||||
char * vtoc_ebcdic_dec (char *source, char *target, int l);
|
||||
void vtoc_set_extent (
|
||||
extent_t * ext,
|
||||
u_int8_t typeind,
|
||||
u_int8_t seqno,
|
||||
uint8_t typeind,
|
||||
uint8_t seqno,
|
||||
cchh_t * lower,
|
||||
cchh_t * upper);
|
||||
void vtoc_set_cchh (
|
||||
cchh_t * addr,
|
||||
u_int32_t cc,
|
||||
u_int16_t hh);
|
||||
u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr);
|
||||
u_int16_t vtoc_get_head_from_cchh(cchh_t *addr);
|
||||
uint32_t cc,
|
||||
uint16_t hh);
|
||||
uint32_t vtoc_get_cyl_from_cchh(cchh_t *addr);
|
||||
uint16_t vtoc_get_head_from_cchh(cchh_t *addr);
|
||||
void vtoc_set_cchhb (
|
||||
cchhb_t * addr,
|
||||
u_int32_t cc,
|
||||
u_int16_t hh,
|
||||
u_int8_t b);
|
||||
u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr);
|
||||
u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr);
|
||||
u_int64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo);
|
||||
u_int64_t cchh2blk (cchh_t *p, struct hd_geometry *geo);
|
||||
u_int32_t cchh2trk (cchh_t *p, struct hd_geometry *geo);
|
||||
uint32_t cc,
|
||||
uint16_t hh,
|
||||
uint8_t b);
|
||||
uint32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr);
|
||||
uint16_t vtoc_get_head_from_cchhb(cchhb_t *addr);
|
||||
uint64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo);
|
||||
uint64_t cchh2blk (cchh_t *p, struct hd_geometry *geo);
|
||||
uint32_t cchh2trk (cchh_t *p, struct hd_geometry *geo);
|
||||
|
||||
void vtoc_set_date (
|
||||
labeldate_t * d,
|
||||
u_int8_t year,
|
||||
u_int16_t day);
|
||||
uint8_t year,
|
||||
uint16_t day);
|
||||
|
||||
void vtoc_volume_label_init (
|
||||
volume_label_t *vlabel);
|
||||
@@ -365,12 +366,12 @@ void vtoc_init_format4_label (
|
||||
unsigned int tracks,
|
||||
unsigned int blocks,
|
||||
unsigned int blksize,
|
||||
u_int16_t dev_type);
|
||||
uint16_t dev_type);
|
||||
|
||||
void vtoc_update_format4_label (
|
||||
format4_label_t *f4,
|
||||
cchhb_t *highest_f1,
|
||||
u_int16_t unused_update);
|
||||
uint16_t unused_update);
|
||||
|
||||
void vtoc_init_format5_label (
|
||||
format5_label_t *f5);
|
||||
@@ -379,17 +380,17 @@ void vtoc_update_format5_label_add (
|
||||
format5_label_t *f5,
|
||||
int verbose,
|
||||
int trk,
|
||||
u_int16_t a,
|
||||
u_int16_t b,
|
||||
u_int8_t c);
|
||||
uint16_t a,
|
||||
uint16_t b,
|
||||
uint8_t c);
|
||||
|
||||
void vtoc_update_format5_label_del (
|
||||
format5_label_t *f5,
|
||||
int verbose,
|
||||
int trk,
|
||||
u_int16_t a,
|
||||
u_int16_t b,
|
||||
u_int8_t c);
|
||||
uint16_t a,
|
||||
uint16_t b,
|
||||
uint8_t c);
|
||||
|
||||
void vtoc_init_format7_label (
|
||||
format7_label_t *f7);
|
||||
@@ -397,14 +398,14 @@ void vtoc_init_format7_label (
|
||||
void vtoc_update_format7_label_add (
|
||||
format7_label_t *f7,
|
||||
int verbose,
|
||||
u_int32_t a,
|
||||
u_int32_t b);
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
void vtoc_update_format7_label_del (
|
||||
format7_label_t *f7,
|
||||
int verbose,
|
||||
u_int32_t a,
|
||||
u_int32_t b);
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
void vtoc_init_format8_label (
|
||||
unsigned int blksize,
|
||||
@@ -424,9 +425,9 @@ void vtoc_set_freespace(
|
||||
format7_label_t *f7,
|
||||
char ch,
|
||||
int verbose,
|
||||
u_int32_t start,
|
||||
u_int32_t stop,
|
||||
u_int32_t cyl,
|
||||
u_int32_t trk);
|
||||
uint32_t start,
|
||||
uint32_t stop,
|
||||
uint32_t cyl,
|
||||
uint32_t trk);
|
||||
|
||||
#endif /* LIB_VTOC_H */
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#define TOOLS_BINDIR STRINGIFY (S390_TOOLS_BINDIR)
|
||||
#define TOOLS_DATADIR STRINGIFY (S390_TOOLS_DATADIR)
|
||||
|
||||
#define __used __attribute__((used))
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#define __packed __attribute__((packed))
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -99,7 +100,7 @@ static int next_entry(DIR *dir, char *in_path, char *out_path,
|
||||
static int nvme_getdev_by_fid(char *fidstr, char *devpath)
|
||||
{
|
||||
char temp_path[PATH_MAX + 19], real_path[PATH_MAX];
|
||||
u_int64_t target_fid, curfid;
|
||||
uint64_t target_fid, curfid;
|
||||
char *sys_path;
|
||||
DIR *dir;
|
||||
char *end;
|
||||
@@ -140,7 +141,7 @@ static int nvme_getdev_by_nsid(char *nsid_str, char *path, char *dev_path)
|
||||
{
|
||||
char full_path[NVME_PATH_MAX+1], nsid_path[sizeof(full_path)+5];
|
||||
char *end;
|
||||
u_int64_t nsid, curnsid;
|
||||
uint64_t nsid, curnsid;
|
||||
DIR *dir;
|
||||
|
||||
nsid = strtoul(nsid_str, &end, 10);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include ../common.mak
|
||||
|
||||
VERSION = 1.0
|
||||
VERSION = 1.1
|
||||
VERM = $(shell echo $(VERSION) | cut -d '.' -f 1)
|
||||
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
@@ -91,13 +91,13 @@ libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb
|
||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
|
||||
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
|
||||
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so
|
||||
ln -sf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
|
||||
ln -sf libekmfweb.so.$(VERSION) libekmfweb.so
|
||||
|
||||
install-libekmfweb.so.$(VERSION): libekmfweb.so.$(VERSION)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION)
|
||||
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERM)
|
||||
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so
|
||||
ln -sf libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERM)
|
||||
ln -sf libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
|
||||
|
||||
@@ -5283,6 +5283,85 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a certificate has the same public key as the secure identity
|
||||
* key (field identity_secure_key in config structure) .
|
||||
*
|
||||
* @param config the configuration structure. Only field
|
||||
* identity_secure_key must be specified, all others
|
||||
* are optional.
|
||||
* @param x509_cert the X509 certificate object to validate
|
||||
* @param ext_lib External secure key crypto library to use
|
||||
* @param verbose if true, verbose messages are printed
|
||||
*
|
||||
* @returns a negative errno in case of an error, 0 if success.
|
||||
* -EINVAL: invalid parameter, or certificate is not valid
|
||||
* -ENOMEM: Failed to allocate memory
|
||||
* any other errno from file I/O routines
|
||||
*/
|
||||
int ekmf_validate_cert(const struct ekmf_config *config, const X509 *x509_cert,
|
||||
const struct ekmf_ext_lib *ext_lib, bool verbose)
|
||||
{
|
||||
unsigned char key_blob[MAX_KEY_BLOB_SIZE];
|
||||
size_t key_blob_size = sizeof(key_blob);
|
||||
struct ext_lib_info ext_lib_info;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int rc;
|
||||
|
||||
if (config == NULL || ext_lib == NULL || x509_cert == NULL)
|
||||
return -EINVAL;
|
||||
if (config->identity_secure_key == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
|
||||
rc = SK_OPENSSL_init(verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to initialize secure key support: "
|
||||
"%s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = read_key_blob(config->identity_secure_key, key_blob,
|
||||
&key_blob_size);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to read identity key from file "
|
||||
"'%s': %s", config->identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = SK_OPENSSL_get_secure_key_as_pkey(key_blob, key_blob_size,
|
||||
false, &pkey,
|
||||
&ext_lib_info.ext_lib, verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get the PKEY from the identity "
|
||||
"key: %s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if !OPENSSL_VERSION_PREREQ(3, 0)
|
||||
if (EVP_PKEY_cmp(pkey, X509_get0_pubkey(x509_cert)) != 1) {
|
||||
#else
|
||||
if (EVP_PKEY_eq(pkey, X509_get0_pubkey(x509_cert)) != 1) {
|
||||
#endif
|
||||
pr_verbose(verbose, "The certificate does not match with the "
|
||||
"identity key");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_verbose(verbose, "Certificate successfully validated");
|
||||
|
||||
out:
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
SK_OPENSSL_term();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the connection to the EKMFWeb server by destroying the CURL handle.
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@ LIBEKMFWEB_1.0 {
|
||||
ekmf_reencipher_identity_key;
|
||||
ekmf_generate_csr;
|
||||
ekmf_generate_ss_cert;
|
||||
ekmf_validate_cert;
|
||||
ekmf_get_public_key;
|
||||
ekmf_get_settings;
|
||||
ekmf_check_feature;
|
||||
@@ -28,3 +29,9 @@ LIBEKMFWEB_1.0 {
|
||||
ekmf_curl_destroy;
|
||||
local: *;
|
||||
};
|
||||
|
||||
LIBEKMFWEB_1.1 {
|
||||
global:
|
||||
ekmf_validate_cert;
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -113,13 +113,13 @@ libkmipclient.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libkmip
|
||||
libkmipclient.so.$(VERSION): kmip.o request.o response.o attribute.o key.o ttlv.o json.o \
|
||||
xml.o https.o tls.o names.o utils.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
ln -srf libkmipclient.so.$(VERSION) libkmipclient.so.$(VERM)
|
||||
ln -srf libkmipclient.so.$(VERSION) libkmipclient.so
|
||||
ln -sf libkmipclient.so.$(VERSION) libkmipclient.so.$(VERM)
|
||||
ln -sf libkmipclient.so.$(VERSION) libkmipclient.so
|
||||
|
||||
install-libkmipclient.so.$(VERSION): libkmipclient.so.$(VERSION)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERSION)
|
||||
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERM)
|
||||
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so
|
||||
ln -sf libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so.$(VERM)
|
||||
ln -sf libkmipclient.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libkmipclient.so
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRINCLUDEDIR)/kmipclient
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/kmipclient/kmipclient.h $(DESTDIR)$(USRINCLUDEDIR)/kmipclient
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ out:
|
||||
if (server_cert != NULL)
|
||||
X509_free(server_cert);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
include ../common.mak
|
||||
include ../common_autocomp.mak
|
||||
|
||||
lib := libutil.a
|
||||
|
||||
sources := $(filter-out %_example.c,$(wildcard *.c))
|
||||
sources := $(filter-out %_example.c %_host.c, $(wildcard *.c))
|
||||
objects := $(patsubst %.c,%.o,$(sources))
|
||||
|
||||
autocomp-object := util_autocomp_host.o
|
||||
|
||||
examples := $(patsubst %.c,%,$(wildcard *_example.c))
|
||||
|
||||
all: $(lib)
|
||||
all: $(lib) $(autocomp-object)
|
||||
examples: $(examples)
|
||||
|
||||
$(examples): %: %.o $(lib)
|
||||
|
||||
299
libutil/util_autocomp_host.c
Normal file
299
libutil/util_autocomp_host.c
Normal file
@@ -0,0 +1,299 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* autocomp - command line autocompletion
|
||||
*
|
||||
* Generating autocompletion scripts for bash and zsh
|
||||
* based on util_opt struct
|
||||
*
|
||||
* Copyright IBM Corp. 2025
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_autocomp.h"
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
static const char *bash_script_part1 = "() {\n\n\
|
||||
\tlocal current_word previous_word options_array\n\n\
|
||||
\tCOMPREPLY=()\n\n\
|
||||
\tcurrent_word=\"${COMP_WORDS[COMP_CWORD]}\"\n\n\
|
||||
\tprevious_word=\"${COMP_WORDS[COMP_CWORD-1]}\"\n\n\
|
||||
\toptions_array=\"";
|
||||
|
||||
static const char *bash_script_part2 = "\tif [[ ${current_word} == -* || ${COMP_CWORD} -eq 1 ]] ; then\n\n\
|
||||
\t\tCOMPREPLY=( $(compgen -W \"${options_array}\" -- ${current_word} ) )\n\n\
|
||||
\t\treturn 0\n\n\
|
||||
\tfi\n\n\
|
||||
}\n\n\
|
||||
complete -F ";
|
||||
|
||||
static char *format_name(const char *fmt, char *tool_name)
|
||||
{
|
||||
char *func_name;
|
||||
|
||||
if (asprintf(&func_name, fmt, tool_name) == -1)
|
||||
return NULL;
|
||||
return func_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* The convention for a completion function name is to be the same
|
||||
* as the command's name, but prefixed by '_'.
|
||||
*/
|
||||
static char *generate_func_name(char *tool_name)
|
||||
{
|
||||
return format_name("_%s", tool_name);
|
||||
}
|
||||
|
||||
static char *generate_bash_filename(char *tool_name)
|
||||
{
|
||||
return format_name("%s.bash", tool_name);
|
||||
}
|
||||
|
||||
static int init_scriptfile(char *file_path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(file_path, O_CREAT | O_WRONLY, 0644);
|
||||
if (fd < 0)
|
||||
return -EIO;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int start_bash_scriptfile(int fd, char *func_name)
|
||||
{
|
||||
int len, ret = 0;
|
||||
char *str;
|
||||
|
||||
len = asprintf(&str, "%s%s", func_name, bash_script_part1);
|
||||
if (len == -1)
|
||||
return -EIO;
|
||||
|
||||
if (write(fd, str, len) != len)
|
||||
ret = -EIO;
|
||||
free(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int start_zsh_scriptfile(int fd, char *func_name, char *tool_name)
|
||||
{
|
||||
const char *part3 = " {\n\n\t_arguments -C \\\n";
|
||||
const char *part2 = "\n\nfunction ";
|
||||
const char *part1 = "#compdef ";
|
||||
int len, ret = 0;
|
||||
char *str;
|
||||
|
||||
len = asprintf(&str, "%s%s%s%s%s", part1, tool_name, part2, func_name, part3);
|
||||
if (len == -1)
|
||||
return -EIO;
|
||||
|
||||
if (write(fd, str, len) != len)
|
||||
ret = -EIO;
|
||||
free(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int write_bash_command_options(struct util_opt *opt_vec, int fd)
|
||||
{
|
||||
const char *prefix = " --";
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
for (int i = 0; opt_vec[i].desc; i++) {
|
||||
if (opt_vec[i].option.name) {
|
||||
len = asprintf(&str, "%s%s", prefix, opt_vec[i].option.name);
|
||||
if (len == -1)
|
||||
return -EIO;
|
||||
if (write(fd, str, len) != len) {
|
||||
free(str);
|
||||
return -EIO;
|
||||
}
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
if (write(fd, "\"\n\n", 3) != 3)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_zsh_command_options(struct util_opt *opt_vec, int fd)
|
||||
{
|
||||
const char *name, *desc;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
for (int i = 0; opt_vec[i].desc; i++) {
|
||||
if (opt_vec[i].option.name) {
|
||||
name = opt_vec[i].option.name;
|
||||
desc = opt_vec[i].desc;
|
||||
len = asprintf(&str, "\t\t\"--%s[%s]\" \\\n", name, desc);
|
||||
if (len == -1)
|
||||
return -EIO;
|
||||
if (write(fd, str, len) != len) {
|
||||
free(str);
|
||||
return -EIO;
|
||||
}
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
if (write(fd, "\n}\n", 3) != 3)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finish_bash_scriptfile(char *tool_name, int fd, char *func_name)
|
||||
{
|
||||
int len, ret = 0;
|
||||
char *str;
|
||||
|
||||
len = asprintf(&str, "%s%s %s\n", bash_script_part2, func_name, tool_name);
|
||||
if (len == -1)
|
||||
return -EIO;
|
||||
|
||||
if (write(fd, str, len) != len)
|
||||
ret = -EIO;
|
||||
free(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds tab completion in bash for a command.
|
||||
* Works by generating an autocompletion
|
||||
* script file at '/usr/share/bash-completion/completions'.
|
||||
*
|
||||
* The full script will be as follows, supposing the tool name is
|
||||
* 'example' and it only has the options '--help' and
|
||||
* '--version':
|
||||
*
|
||||
* _example() {
|
||||
*
|
||||
* local current_word previous_word options_array
|
||||
*
|
||||
* COMPREPLY=()
|
||||
*
|
||||
* current_word="${COMP_WORDS[COMP_CWORD]}"
|
||||
*
|
||||
* previous_word="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
*
|
||||
* options_array="--version --help"
|
||||
*
|
||||
* if [[ ${current_word} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||
*
|
||||
* COMPREPLY=( $(compgen -W "${options_array}" -- ${current_word} ) )
|
||||
*
|
||||
* return 0
|
||||
*
|
||||
* fi
|
||||
*
|
||||
* }
|
||||
*
|
||||
* complete -F _example example
|
||||
*
|
||||
*/
|
||||
static void generate_bash_autocomp(struct util_opt *opt_vec, char *tool_name)
|
||||
{
|
||||
char *func_name, *filename;
|
||||
int fd, ret = 0;
|
||||
|
||||
func_name = generate_func_name(tool_name);
|
||||
if (!func_name) {
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
filename = generate_bash_filename(tool_name);
|
||||
if (!filename) {
|
||||
ret = -ENOMEM;
|
||||
goto free_func;
|
||||
}
|
||||
fd = init_scriptfile(filename);
|
||||
if (fd < 0) {
|
||||
ret = fd;
|
||||
goto free_file;
|
||||
}
|
||||
ret = start_bash_scriptfile(fd, func_name);
|
||||
if (ret < 0)
|
||||
goto close;
|
||||
ret = write_bash_command_options(opt_vec, fd);
|
||||
if (ret < 0)
|
||||
goto close;
|
||||
ret = finish_bash_scriptfile(tool_name, fd, func_name);
|
||||
close:
|
||||
close(fd);
|
||||
if (ret)
|
||||
remove(filename);
|
||||
free_file:
|
||||
free(filename);
|
||||
free_func:
|
||||
free(func_name);
|
||||
end:
|
||||
printf(" AUTOCOMP\t%s/%s.bash\n", tool_name, tool_name);
|
||||
if (ret)
|
||||
printf("%s.bash: error - %s\n", tool_name, strerror(abs(ret)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds tab completion in zsh for a command.
|
||||
* Works by generating an autocompletion
|
||||
* script file at '/usr/share/zsh/site-functions'.
|
||||
*
|
||||
* The full script will be as follows, supposing the tool name is
|
||||
* 'example' and it only has the options '--help', -h and
|
||||
* '--version' (the descriptions, as well as the flags are
|
||||
* taken from a util_opt struct):
|
||||
*
|
||||
* #compdef example_completion
|
||||
*
|
||||
* function _example_completion {
|
||||
*
|
||||
* _arguments -C \
|
||||
* "-h[Show help information]" \
|
||||
* "--help[Show help but long format]" \
|
||||
* "--version[Show version]"
|
||||
* }
|
||||
*
|
||||
*/
|
||||
static void generate_zsh_autocomp(struct util_opt *opt_vec, char *tool_name)
|
||||
{
|
||||
char *func_name;
|
||||
int fd, ret = 0;
|
||||
|
||||
func_name = generate_func_name(tool_name);
|
||||
if (!func_name) {
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
fd = init_scriptfile(func_name);
|
||||
if (fd < 0) {
|
||||
ret = fd;
|
||||
goto free_func;
|
||||
}
|
||||
ret = start_zsh_scriptfile(fd, func_name, tool_name);
|
||||
if (ret < 0)
|
||||
goto close;
|
||||
ret = write_zsh_command_options(opt_vec, fd);
|
||||
close:
|
||||
close(fd);
|
||||
if (ret)
|
||||
remove(func_name);
|
||||
free_func:
|
||||
free(func_name);
|
||||
end:
|
||||
printf(" AUTOCOMP\t%s/_%s\n", tool_name, tool_name);
|
||||
if (ret)
|
||||
printf("_%s: error - %s\n", tool_name, strerror(abs(ret)));
|
||||
}
|
||||
|
||||
void generate_autocomp(struct util_opt *opt_vec, char *tool_name)
|
||||
{
|
||||
generate_bash_autocomp(opt_vec, tool_name);
|
||||
generate_zsh_autocomp(opt_vec, tool_name);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <argz.h>
|
||||
#include <libgen.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef __GLIBC__
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_panic.h"
|
||||
@@ -24,6 +26,7 @@
|
||||
*
|
||||
* To get symbols, link the code with "-rdynamic".
|
||||
*/
|
||||
#ifdef __GLIBC__
|
||||
static void print_backtrace(void)
|
||||
{
|
||||
void *array[256];
|
||||
@@ -42,6 +45,9 @@ static void print_backtrace(void)
|
||||
|
||||
free(strings);
|
||||
}
|
||||
#else
|
||||
static void print_backtrace(void) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for core ulimit
|
||||
|
||||
220
libutil/util_parse.c
Normal file
220
libutil/util_parse.c
Normal 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;
|
||||
}
|
||||
@@ -16,10 +16,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/util_prg.h"
|
||||
|
||||
/*
|
||||
* Verify that directory exists
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
330
libvtoc/vtoc.c
330
libvtoc/vtoc.c
@@ -6,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/vtoc.h"
|
||||
|
||||
static unsigned char EBCtoASC[256] =
|
||||
@@ -24,23 +26,23 @@ static unsigned char EBCtoASC[256] =
|
||||
-INP */
|
||||
0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
|
||||
/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
|
||||
-SW */
|
||||
-SW */
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
|
||||
/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
|
||||
0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
|
||||
/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
|
||||
0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
|
||||
/* 0x40 SP RSP <EFBFBD> ---- */
|
||||
/* 0x40 SP RSP ä ---- */
|
||||
0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
|
||||
/* 0x48 . < ( + | */
|
||||
0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
|
||||
/* 0x50 & ---- */
|
||||
0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
|
||||
/* 0x58 <EFBFBD> ! $ * ) ; */
|
||||
/* 0x58 ß ! $ * ) ; */
|
||||
0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
|
||||
/* 0x60 - / ---- <EFBFBD> ---- ---- ---- */
|
||||
/* 0x60 - / ---- Ä ---- ---- ---- */
|
||||
0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
|
||||
/* 0x68 ---- , % _ > ? */
|
||||
/* 0x68 ---- , % _ > ? */
|
||||
0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
|
||||
/* 0x70 --- ---- ---- ---- ---- ---- ---- */
|
||||
0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
@@ -50,7 +52,7 @@ static unsigned char EBCtoASC[256] =
|
||||
0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||
/* 0x88 h i ---- ---- ---- */
|
||||
0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
|
||||
/* 0x90 <EFBFBD> j k l m n o p */
|
||||
/* 0x90 ° j k l m n o p */
|
||||
0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
|
||||
/* 0x98 q r ---- ---- */
|
||||
0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
|
||||
@@ -58,25 +60,25 @@ static unsigned char EBCtoASC[256] =
|
||||
0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
|
||||
/* 0xA8 y z ---- ---- ---- ---- */
|
||||
0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
|
||||
/* 0xB0 ^ ---- <EFBFBD> ---- */
|
||||
/* 0xB0 ^ ---- § ---- */
|
||||
0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
|
||||
/* 0xB8 ---- [ ] ---- ---- ---- ---- */
|
||||
0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
|
||||
/* 0xC0 { A B C D E F G */
|
||||
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
/* 0xC8 H I ---- <EFBFBD> ---- */
|
||||
/* 0xC8 H I ---- ö ---- */
|
||||
0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
|
||||
/* 0xD0 } J K L M N O P */
|
||||
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
|
||||
/* 0xD8 Q R ---- <EFBFBD> */
|
||||
/* 0xD8 Q R ---- ü */
|
||||
0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
|
||||
/* 0xE0 \ S T U V W X */
|
||||
0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
/* 0xE8 Y Z ---- <EFBFBD> ---- ---- ---- */
|
||||
/* 0xE8 Y Z ---- Ö ---- ---- ---- */
|
||||
0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
|
||||
/* 0xF0 0 1 2 3 4 5 6 7 */
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
/* 0xF8 8 9 ---- ---- <EFBFBD> ---- ---- ---- */
|
||||
/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
|
||||
0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
|
||||
};
|
||||
|
||||
@@ -142,7 +144,7 @@ static char buffer[85];
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void vtoc_error(enum failure why, char *s1, char *s2)
|
||||
static void vtoc_error(enum failure why, char *s1, char *s2)
|
||||
{
|
||||
switch (why) {
|
||||
case unable_to_open:
|
||||
@@ -170,11 +172,11 @@ static void vtoc_error(enum failure why, char *s1, char *s2)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
char * vtoc_ebcdic_enc (char *source, char *target, int l)
|
||||
char * vtoc_ebcdic_enc (char *source, char *target, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
for (i = 0; i < l; i++)
|
||||
target[i]=ASCtoEBC[(unsigned char)(source[i])];
|
||||
|
||||
return target;
|
||||
@@ -184,11 +186,11 @@ char * vtoc_ebcdic_enc (char *source, char *target, int l)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
char * vtoc_ebcdic_dec (char *source, char *target, int l)
|
||||
char * vtoc_ebcdic_dec (char *source, char *target, int l)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
for (i = 0; i < l; i++)
|
||||
target[i]=EBCtoASC[(unsigned char)(source[i])];
|
||||
|
||||
return target;
|
||||
@@ -198,9 +200,9 @@ char * vtoc_ebcdic_dec (char *source, char *target, int l)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void vtoc_set_extent (extent_t *ext, u_int8_t typeind, u_int8_t seqno,
|
||||
cchh_t *lower, cchh_t *upper)
|
||||
{
|
||||
void vtoc_set_extent (extent_t *ext, uint8_t typeind, uint8_t seqno,
|
||||
cchh_t *lower, cchh_t *upper)
|
||||
{
|
||||
ext->typeind = typeind;
|
||||
ext->seqno = seqno;
|
||||
memcpy(&ext->llimit,lower,sizeof(cchh_t));
|
||||
@@ -211,17 +213,17 @@ void vtoc_set_extent (extent_t *ext, u_int8_t typeind, u_int8_t seqno,
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void vtoc_set_cchh (cchh_t *addr, u_int32_t cc, u_int16_t hh)
|
||||
void vtoc_set_cchh (cchh_t *addr, uint32_t cc, uint16_t hh)
|
||||
{
|
||||
addr->cc = (u_int16_t) cc;
|
||||
addr->cc = (uint16_t) cc;
|
||||
addr->hh = cc >> 16;
|
||||
addr->hh <<= 4;
|
||||
addr->hh |= hh;
|
||||
}
|
||||
|
||||
u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr)
|
||||
uint32_t vtoc_get_cyl_from_cchh(cchh_t *addr)
|
||||
{
|
||||
u_int32_t cyl;
|
||||
uint32_t cyl;
|
||||
|
||||
/*decode cylinder for large volumes */
|
||||
cyl = addr->hh & 0xFFF0;
|
||||
@@ -230,7 +232,7 @@ u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr)
|
||||
return cyl;
|
||||
}
|
||||
|
||||
u_int16_t vtoc_get_head_from_cchh(cchh_t *addr)
|
||||
uint16_t vtoc_get_head_from_cchh(cchh_t *addr)
|
||||
{
|
||||
/* decode heads for large volumes */
|
||||
return addr->hh & 0x000F;
|
||||
@@ -239,7 +241,7 @@ u_int16_t vtoc_get_head_from_cchh(cchh_t *addr)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void vtoc_set_ttr (ttr_t *addr, u_int16_t tt, u_int8_t r)
|
||||
static void vtoc_set_ttr (ttr_t *addr, uint16_t tt, uint8_t r)
|
||||
{
|
||||
addr->tt = tt;
|
||||
addr->r = r;
|
||||
@@ -249,18 +251,18 @@ static void vtoc_set_ttr (ttr_t *addr, u_int16_t tt, u_int8_t r)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void vtoc_set_cchhb (cchhb_t *addr, u_int32_t cc, u_int16_t hh, u_int8_t b)
|
||||
void vtoc_set_cchhb (cchhb_t *addr, uint32_t cc, uint16_t hh, uint8_t b)
|
||||
{
|
||||
addr->cc = (u_int16_t) cc;
|
||||
addr->cc = (uint16_t) cc;
|
||||
addr->hh = cc >> 16;
|
||||
addr->hh <<= 4;
|
||||
addr->hh |= hh;
|
||||
addr->b = b;
|
||||
}
|
||||
|
||||
u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr)
|
||||
uint32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr)
|
||||
{
|
||||
u_int32_t cyl;
|
||||
uint32_t cyl;
|
||||
|
||||
/* decode cylinder for large volumes */
|
||||
cyl = addr->hh & 0xFFF0;
|
||||
@@ -269,7 +271,7 @@ u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr)
|
||||
return cyl;
|
||||
}
|
||||
|
||||
u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr)
|
||||
uint16_t vtoc_get_head_from_cchhb(cchhb_t *addr)
|
||||
{
|
||||
/* decode heads for large volumes */
|
||||
return addr->hh & 0x000F;
|
||||
@@ -281,22 +283,22 @@ u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr)
|
||||
* Note: Record zero is special, so first block on a track is
|
||||
* in record 1!
|
||||
*/
|
||||
u_int64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo)
|
||||
uint64_t cchhb2blk(cchhb_t *p, struct hd_geometry *geo)
|
||||
{
|
||||
return (u_int64_t) vtoc_get_cyl_from_cchhb(p) *
|
||||
return (uint64_t) vtoc_get_cyl_from_cchhb(p) *
|
||||
geo->heads * geo->sectors +
|
||||
vtoc_get_head_from_cchhb(p) * geo->sectors +
|
||||
p->b;
|
||||
}
|
||||
|
||||
u_int64_t cchh2blk (cchh_t *p, struct hd_geometry *geo) {
|
||||
uint64_t cchh2blk (cchh_t *p, struct hd_geometry *geo) {
|
||||
|
||||
return (u_int64_t) vtoc_get_cyl_from_cchh(p) *
|
||||
return (uint64_t) vtoc_get_cyl_from_cchh(p) *
|
||||
geo->heads * geo->sectors +
|
||||
vtoc_get_head_from_cchh(p) * geo->sectors;
|
||||
}
|
||||
|
||||
u_int32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
|
||||
uint32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
|
||||
|
||||
return vtoc_get_cyl_from_cchh(p) * geo->heads +
|
||||
vtoc_get_head_from_cchh(p);
|
||||
@@ -305,7 +307,7 @@ u_int32_t cchh2trk (cchh_t *p, struct hd_geometry *geo) {
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void vtoc_set_date (labeldate_t * d, u_int8_t year, u_int16_t day)
|
||||
void vtoc_set_date (labeldate_t * d, uint8_t year, uint16_t day)
|
||||
{
|
||||
d->year = year;
|
||||
d->day = day;
|
||||
@@ -318,7 +320,7 @@ void vtoc_set_date (labeldate_t * d, u_int8_t year, u_int16_t day)
|
||||
void vtoc_volume_label_init (volume_label_t *vlabel)
|
||||
{
|
||||
sprintf(buffer, "%84s", " ");
|
||||
vtoc_ebcdic_enc(buffer, buffer, 84);
|
||||
vtoc_ebcdic_enc(buffer, buffer, 84);
|
||||
memcpy(vlabel, buffer, 84);
|
||||
}
|
||||
|
||||
@@ -327,7 +329,7 @@ void vtoc_volume_label_init (volume_label_t *vlabel)
|
||||
* reads the volume label from dasd
|
||||
*/
|
||||
int vtoc_read_volume_label (char *device, unsigned long vlabel_start,
|
||||
volume_label_t *vlabel)
|
||||
volume_label_t *vlabel)
|
||||
{
|
||||
int f, rc;
|
||||
|
||||
@@ -358,7 +360,7 @@ int vtoc_read_volume_label (char *device, unsigned long vlabel_start,
|
||||
* writes the volume label to dasd
|
||||
*/
|
||||
int vtoc_write_volume_label (char *device, unsigned long vlabel_start,
|
||||
volume_label_t *vlabel)
|
||||
volume_label_t *vlabel)
|
||||
{
|
||||
int rc, f;
|
||||
|
||||
@@ -373,8 +375,8 @@ int vtoc_write_volume_label (char *device, unsigned long vlabel_start,
|
||||
"Could not write volume label.");
|
||||
}
|
||||
|
||||
rc = write(f, vlabel, sizeof(volume_label_t));
|
||||
if (rc != sizeof(volume_label_t))
|
||||
rc = write(f, vlabel, sizeof(volume_label_t));
|
||||
if (rc != sizeof(volume_label_t))
|
||||
{
|
||||
close(f);
|
||||
vtoc_error(unable_to_write, device,
|
||||
@@ -416,7 +418,7 @@ void vtoc_volume_label_set_volser (volume_label_t *vlabel, char *volser)
|
||||
|
||||
|
||||
/*
|
||||
* returns the volume serial number right after it is translated
|
||||
* returns the volume serial number right after it is translated
|
||||
* to ASCII
|
||||
*/
|
||||
char * vtoc_volume_label_get_volser (volume_label_t *vlabel, char *volser)
|
||||
@@ -434,11 +436,11 @@ char * vtoc_volume_label_get_volser (volume_label_t *vlabel, char *volser)
|
||||
void vtoc_volume_label_set_key (volume_label_t *vlabel, char *key)
|
||||
{
|
||||
char s[4];
|
||||
|
||||
|
||||
vtoc_ebcdic_enc(key, s, 4);
|
||||
strncpy(vlabel->volkey, s, 4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -473,12 +475,12 @@ char * vtoc_volume_label_get_label (volume_label_t *vlabel, char *lbl)
|
||||
*/
|
||||
void vtoc_read_label (char *device, unsigned long position,
|
||||
format1_label_t *f1, format4_label_t *f4,
|
||||
format5_label_t *f5, format7_label_t *f7)
|
||||
{
|
||||
format5_label_t *f5, format7_label_t *f7)
|
||||
{
|
||||
int f,t;
|
||||
|
||||
if ((f = open(device, O_RDONLY)) < 0)
|
||||
vtoc_error(unable_to_open, device,
|
||||
vtoc_error(unable_to_open, device,
|
||||
"Could not read VTOC labels.");
|
||||
|
||||
if (lseek(f, position, SEEK_SET) < 0) {
|
||||
@@ -534,7 +536,7 @@ void vtoc_read_label (char *device, unsigned long position,
|
||||
void
|
||||
vtoc_write_label (char *device,
|
||||
unsigned long position,
|
||||
format1_label_t *f1,
|
||||
format1_label_t *f1,
|
||||
format4_label_t *f4,
|
||||
format5_label_t *f5,
|
||||
format7_label_t *f7,
|
||||
@@ -548,7 +550,7 @@ vtoc_write_label (char *device,
|
||||
"Could not write VTOC labels.");
|
||||
}
|
||||
|
||||
if (lseek(f, position, SEEK_SET) == -1)
|
||||
if (lseek(f, position, SEEK_SET) == -1)
|
||||
{
|
||||
close(f);
|
||||
vtoc_error(unable_to_seek, device,
|
||||
@@ -558,7 +560,7 @@ vtoc_write_label (char *device,
|
||||
if (f1 != NULL)
|
||||
{
|
||||
t = sizeof(format1_label_t);
|
||||
if (write(f, f1, t) != t)
|
||||
if (write(f, f1, t) != t)
|
||||
{
|
||||
close(f);
|
||||
vtoc_error(unable_to_write, device,
|
||||
@@ -569,7 +571,7 @@ vtoc_write_label (char *device,
|
||||
if (f4 != NULL)
|
||||
{
|
||||
t = sizeof(format4_label_t);
|
||||
if (write(f, f4, t) != t)
|
||||
if (write(f, f4, t) != t)
|
||||
{
|
||||
close(f);
|
||||
vtoc_error(unable_to_write, device,
|
||||
@@ -580,7 +582,7 @@ vtoc_write_label (char *device,
|
||||
if (f5 != NULL)
|
||||
{
|
||||
t = sizeof(format5_label_t);
|
||||
if (write(f, f5, t) != t)
|
||||
if (write(f, f5, t) != t)
|
||||
{
|
||||
close(f);
|
||||
vtoc_error(unable_to_write, device,
|
||||
@@ -591,7 +593,7 @@ vtoc_write_label (char *device,
|
||||
if (f7 != NULL)
|
||||
{
|
||||
t = sizeof(format7_label_t);
|
||||
if (write(f, f7, t) != t)
|
||||
if (write(f, f7, t) != t)
|
||||
{
|
||||
close(f);
|
||||
vtoc_error(unable_to_write, device,
|
||||
@@ -617,7 +619,7 @@ vtoc_write_label (char *device,
|
||||
/*
|
||||
* initializes a format4 label
|
||||
*/
|
||||
void
|
||||
void
|
||||
vtoc_init_format4_label (
|
||||
format4_label_t *f4,
|
||||
unsigned int compat_cylinders,
|
||||
@@ -625,7 +627,7 @@ vtoc_init_format4_label (
|
||||
unsigned int tracks,
|
||||
unsigned int blocks,
|
||||
unsigned int blksize,
|
||||
u_int16_t dev_type)
|
||||
uint16_t dev_type)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -674,24 +676,24 @@ vtoc_init_format4_label (
|
||||
f4->DS4DEVCT.DS4DEVDB = 0x00;
|
||||
/* -- end f4->DS4DEVCT -- */
|
||||
|
||||
bzero(f4->DS4AMTIM, sizeof(f4->DS4AMTIM));
|
||||
bzero(f4->DS4AMCAT, sizeof(f4->DS4AMCAT));
|
||||
bzero(f4->DS4R2TIM, sizeof(f4->DS4R2TIM));
|
||||
bzero(f4->res1, sizeof(f4->res1));
|
||||
bzero(f4->DS4F6PTR, sizeof(f4->DS4F6PTR));
|
||||
memset(f4->DS4AMTIM, 0, sizeof(f4->DS4AMTIM));
|
||||
memset(f4->DS4AMCAT, 0, sizeof(f4->DS4AMCAT));
|
||||
memset(f4->DS4R2TIM, 0, sizeof(f4->DS4R2TIM));
|
||||
memset(f4->res1, 0, sizeof(f4->res1));
|
||||
memset(f4->DS4F6PTR, 0, sizeof(f4->DS4F6PTR));
|
||||
|
||||
/* -- begin f4lbl->DS4VTOCE -- */
|
||||
vtoc_set_extent(&f4->DS4VTOCE, 0x01, 0x00, &lower, &upper);
|
||||
/* -- end f4lbl->DS4VTOCE -- */
|
||||
|
||||
bzero(f4->res2, sizeof(f4->res2));
|
||||
memset(f4->res2, 0, sizeof(f4->res2));
|
||||
f4->DS4EFLVL = 0x00;
|
||||
bzero(&f4->DS4EFPTR, sizeof(f4->DS4EFPTR));
|
||||
bzero(&f4->res3, sizeof(f4->res3));
|
||||
memset(&f4->DS4EFPTR, 0, sizeof(f4->DS4EFPTR));
|
||||
memset(&f4->res3, 0, sizeof(f4->res3));
|
||||
f4->DS4DCYL = real_cylinders;
|
||||
bzero(f4->res4, sizeof(f4->res4));
|
||||
memset(f4->res4, 0, sizeof(f4->res4));
|
||||
f4->DS4DEVF2 = 0x40; /* allow format 8 and 9 labels */
|
||||
bzero(&f4->res5, sizeof(f4->res5));
|
||||
memset(&f4->res5, 0, sizeof(f4->res5));
|
||||
}
|
||||
|
||||
|
||||
@@ -699,11 +701,11 @@ vtoc_init_format4_label (
|
||||
* initializes a format5 label
|
||||
*/
|
||||
void
|
||||
vtoc_init_format5_label (format5_label_t *f5)
|
||||
vtoc_init_format5_label (format5_label_t *f5)
|
||||
{
|
||||
int i;
|
||||
|
||||
bzero(f5, sizeof(format5_label_t));
|
||||
memset(f5, 0, sizeof(format5_label_t));
|
||||
for (i=0; i<4; i++) f5->DS5KEYID[i] = 0x05;
|
||||
f5->DS5FMTID = 0xf5;
|
||||
}
|
||||
@@ -713,11 +715,11 @@ vtoc_init_format5_label (format5_label_t *f5)
|
||||
* initializes a format7 label
|
||||
*/
|
||||
void
|
||||
vtoc_init_format7_label (format7_label_t *f7)
|
||||
vtoc_init_format7_label (format7_label_t *f7)
|
||||
{
|
||||
int i;
|
||||
|
||||
bzero(f7, sizeof(format7_label_t));
|
||||
memset(f7, 0, sizeof(format7_label_t));
|
||||
for (i=0; i<4; i++) f7->DS7KEYID[i] = 0x07;
|
||||
f7->DS7FMTID = 0xf7;
|
||||
}
|
||||
@@ -740,7 +742,7 @@ static void vtoc_init_format_1_8_label (
|
||||
t = time(NULL);
|
||||
creatime = gmtime(&t);
|
||||
|
||||
bzero(f1->DS1DSNAM, sizeof(f1->DS1DSNAM));
|
||||
memset(f1->DS1DSNAM, 0, sizeof(f1->DS1DSNAM));
|
||||
sprintf(str, "PART .NEW ");
|
||||
vtoc_ebcdic_enc(str, str, 44);
|
||||
memcpy(f1->DS1DSNAM, str, 44);
|
||||
@@ -748,8 +750,8 @@ static void vtoc_init_format_1_8_label (
|
||||
f1->DS1VOLSQ = 0x0001;
|
||||
|
||||
vtoc_set_date(&f1->DS1CREDT,
|
||||
(u_int8_t) creatime->tm_year,
|
||||
(u_int16_t) creatime->tm_yday);
|
||||
(uint8_t) creatime->tm_year,
|
||||
(uint16_t) creatime->tm_yday);
|
||||
/* expires never - 99 365 */
|
||||
vtoc_set_date(&f1->DS1EXPDT,
|
||||
0x63,
|
||||
@@ -760,8 +762,8 @@ static void vtoc_init_format_1_8_label (
|
||||
vtoc_ebcdic_enc("IBM LINUX ", str, 13);
|
||||
memcpy((char *)f1->DS1SYSCD, str, 13);
|
||||
vtoc_set_date(&f1->DS1REFD,
|
||||
(u_int8_t) creatime->tm_year,
|
||||
(u_int16_t) creatime->tm_yday);
|
||||
(uint8_t) creatime->tm_year,
|
||||
(uint16_t) creatime->tm_yday);
|
||||
f1->DS1SMSFG = 0x00;
|
||||
f1->DS1SCXTF = 0x00;
|
||||
f1->DS1SCXTV = 0x0000;
|
||||
@@ -775,17 +777,17 @@ static void vtoc_init_format_1_8_label (
|
||||
f1->DS1RKP = 0x0000;
|
||||
f1->DS1DSIND = 0x80; /* last volume for this dataset */
|
||||
f1->DS1SCAL1 = 0x80;
|
||||
bzero(&f1->DS1SCAL3, sizeof(f1->DS1SCAL3));
|
||||
memset(&f1->DS1SCAL3, 0, sizeof(f1->DS1SCAL3));
|
||||
vtoc_set_ttr(&f1->DS1LSTAR,
|
||||
0x0000,
|
||||
0x00);
|
||||
f1->DS1TRBAL = 0x00;
|
||||
bzero(&f1->res1, sizeof(f1->res1));
|
||||
memset(&f1->res1, 0, sizeof(f1->res1));
|
||||
memcpy(&f1->DS1EXT1,
|
||||
part_extent,
|
||||
sizeof(extent_t));
|
||||
bzero(&f1->DS1EXT2, sizeof(extent_t));
|
||||
bzero(&f1->DS1EXT3, sizeof(extent_t));
|
||||
memset(&f1->DS1EXT2, 0, sizeof(extent_t));
|
||||
memset(&f1->DS1EXT3, 0, sizeof(extent_t));
|
||||
vtoc_set_cchhb(&f1->DS1PTRDS,
|
||||
0x0000, 0x0000, 0x00);
|
||||
}
|
||||
@@ -827,11 +829,11 @@ void vtoc_init_format9_label (
|
||||
/*
|
||||
* do some updates to the VTOC format4 label
|
||||
*/
|
||||
void
|
||||
void
|
||||
vtoc_update_format4_label (
|
||||
format4_label_t *f4,
|
||||
cchhb_t *highest_f1,
|
||||
u_int16_t unused_update)
|
||||
uint16_t unused_update)
|
||||
{
|
||||
/* update highest address of a format 1 label */
|
||||
memcpy(&f4->DS4HPCHR, highest_f1, sizeof(cchhb_t));
|
||||
@@ -845,15 +847,15 @@ vtoc_update_format4_label (
|
||||
* reorganizes all extents within a FMT5 label
|
||||
*/
|
||||
static void
|
||||
vtoc_reorganize_FMT5_extents (format5_label_t *f5)
|
||||
vtoc_reorganize_FMT5_extents (format5_label_t *f5)
|
||||
{
|
||||
ds5ext_t *ext, *last, tmp;
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<26; i++)
|
||||
{
|
||||
if (i==0)
|
||||
last = &f5->DS5AVEXT;
|
||||
if (i==0)
|
||||
last = &f5->DS5AVEXT;
|
||||
else if ((i > 0) && (i < 8))
|
||||
last = &f5->DS5EXTAV[i-1];
|
||||
else
|
||||
@@ -861,14 +863,14 @@ vtoc_reorganize_FMT5_extents (format5_label_t *f5)
|
||||
|
||||
for (j=i; j<26; j++)
|
||||
{
|
||||
if (j==0)
|
||||
ext = &f5->DS5AVEXT;
|
||||
if (j==0)
|
||||
ext = &f5->DS5AVEXT;
|
||||
else if ((j > 0) && (j < 8))
|
||||
ext = &f5->DS5EXTAV[j-1];
|
||||
else
|
||||
ext = &f5->DS5MAVET[j-8];
|
||||
|
||||
if (((ext->t > 0) && (last->t == 0)) ||
|
||||
if (((ext->t > 0) && (last->t == 0)) ||
|
||||
((ext->t > 0) && (ext->t < last->t)))
|
||||
{
|
||||
tmp.t = last->t;
|
||||
@@ -889,27 +891,27 @@ vtoc_reorganize_FMT5_extents (format5_label_t *f5)
|
||||
/*
|
||||
* add a free space extent description to the VTOC FMT5 DSCB
|
||||
*/
|
||||
void
|
||||
void
|
||||
vtoc_update_format5_label_add (format5_label_t *f5,
|
||||
int verbose,
|
||||
int trk,
|
||||
u_int16_t a,
|
||||
u_int16_t b,
|
||||
u_int8_t c)
|
||||
uint16_t a,
|
||||
uint16_t b,
|
||||
uint8_t c)
|
||||
{
|
||||
ds5ext_t *ext = NULL, *tmp = NULL;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0; i<26; i++)
|
||||
{
|
||||
if (i==0)
|
||||
ext = &f5->DS5AVEXT;
|
||||
if (i==0)
|
||||
ext = &f5->DS5AVEXT;
|
||||
else if ((i > 0) && (i < 8))
|
||||
ext = &f5->DS5EXTAV[i-1];
|
||||
else
|
||||
ext = &f5->DS5MAVET[i-8];
|
||||
|
||||
if (((a < ext->t) && (a + b*trk + c > ext->t)) ||
|
||||
if (((a < ext->t) && (a + b*trk + c > ext->t)) ||
|
||||
((a > ext->t) && (ext->t + ext->fc*trk + ext->ft > a)))
|
||||
{
|
||||
printf("BUG: overlapping free space extents " \
|
||||
@@ -923,7 +925,7 @@ vtoc_update_format5_label_add (format5_label_t *f5,
|
||||
ext->fc = b;
|
||||
ext->ft = c;
|
||||
tmp = ext;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT5 add extent: " \
|
||||
"add new extent\n");
|
||||
break;
|
||||
@@ -954,14 +956,14 @@ vtoc_update_format5_label_add (format5_label_t *f5,
|
||||
/* this extent precedes the new one */
|
||||
ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
|
||||
ext->ft = (tmp->ft + ext->ft) % trk;
|
||||
bzero(tmp, sizeof(ds5ext_t));
|
||||
memset(tmp, 0, sizeof(ds5ext_t));
|
||||
tmp = ext;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT5 add extent: " \
|
||||
"merge with predecessor\n");
|
||||
i = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp->t + tmp->fc*trk + tmp->ft) == ext->t)
|
||||
{
|
||||
@@ -969,14 +971,14 @@ vtoc_update_format5_label_add (format5_label_t *f5,
|
||||
ext->t = tmp->t;
|
||||
ext->fc += (tmp->fc + (tmp->ft + ext->ft)/trk);
|
||||
ext->ft = (tmp->ft + ext->ft) % trk;
|
||||
bzero(tmp, sizeof(ds5ext_t));
|
||||
memset(tmp, 0, sizeof(ds5ext_t));
|
||||
tmp = ext;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT5 add extent: " \
|
||||
"merge with successor\n");
|
||||
i = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,21 +986,21 @@ vtoc_update_format5_label_add (format5_label_t *f5,
|
||||
/*
|
||||
* remove a free space extent description from the VTOC FMT5 DSCB
|
||||
*/
|
||||
void
|
||||
void
|
||||
vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
int verbose,
|
||||
int trk,
|
||||
u_int16_t a,
|
||||
u_int16_t b,
|
||||
u_int8_t c)
|
||||
uint16_t a,
|
||||
uint16_t b,
|
||||
uint8_t c)
|
||||
{
|
||||
ds5ext_t *ext;
|
||||
int i, counter=0;
|
||||
|
||||
|
||||
for (i=0; i<26; i++)
|
||||
{
|
||||
if (i==0)
|
||||
ext = &f5->DS5AVEXT;
|
||||
if (i==0)
|
||||
ext = &f5->DS5AVEXT;
|
||||
else if ((i > 0) && (i < 8))
|
||||
ext = &f5->DS5EXTAV[i-1];
|
||||
else
|
||||
@@ -1007,8 +1009,8 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
if ((a == ext->t) && (b == ext->fc) && (c == ext->ft))
|
||||
{
|
||||
/* fills up whole free space gap */
|
||||
bzero(ext, sizeof(ds5ext_t));
|
||||
if (verbose)
|
||||
memset(ext, 0, sizeof(ds5ext_t));
|
||||
if (verbose)
|
||||
printf("FMT5 del extent: fills whole gap\n");
|
||||
counter++;
|
||||
break;
|
||||
@@ -1028,13 +1030,13 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
ext->fc -= b;
|
||||
ext->ft -= c;
|
||||
}
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT5 del extent: left bounded\n");
|
||||
counter++;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ext->t < a) &&
|
||||
if ((ext->t < a) &&
|
||||
((ext->t + ext->fc*trk + ext->ft) == (a + b*trk + c)))
|
||||
{
|
||||
/* right-bounded in free space gap */
|
||||
@@ -1048,7 +1050,7 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
ext->fc -= b;
|
||||
ext->ft -= c;
|
||||
}
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT5 del extent: right bounded\n");
|
||||
counter++;
|
||||
break;
|
||||
@@ -1057,10 +1059,10 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
if ((a > ext->t) &&
|
||||
((ext->t + ext->fc*trk + ext->ft) > (a + b*trk + c)))
|
||||
{
|
||||
/* partition devides free space into 2 pieces */
|
||||
u_int16_t x = a + b*trk + c;
|
||||
u_int16_t w,y;
|
||||
u_int8_t z;
|
||||
/* partition divides free space into 2 pieces */
|
||||
uint16_t x = a + b*trk + c;
|
||||
uint16_t w,y;
|
||||
uint8_t z;
|
||||
|
||||
w = (ext->t + ext->fc*trk + ext->ft) - (a + b*trk + c);
|
||||
y = w / trk;
|
||||
@@ -1072,7 +1074,7 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
vtoc_update_format5_label_add(f5, verbose,
|
||||
trk, x, y, z);
|
||||
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT5 del extent: 2 pieces\n");
|
||||
counter++;
|
||||
break;
|
||||
@@ -1086,8 +1088,8 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
"in FMT5 DSCB!\nexiting...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((a > ext->t) && (a < ext->t + ext->fc*trk + ext->ft) &&
|
||||
|
||||
if ((a > ext->t) && (a < ext->t + ext->fc*trk + ext->ft) &&
|
||||
(a + b*trk + c > ext->t + ext->fc*trk + ext->ft))
|
||||
{
|
||||
printf("BUG: specified free space extent for " \
|
||||
@@ -1111,26 +1113,26 @@ vtoc_update_format5_label_del (format5_label_t *f5,
|
||||
* reorganizes all extents within a FMT7 label
|
||||
*/
|
||||
static void
|
||||
vtoc_reorganize_FMT7_extents (format7_label_t *f7)
|
||||
vtoc_reorganize_FMT7_extents (format7_label_t *f7)
|
||||
{
|
||||
ds7ext_t *ext, *last, tmp;
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
if (i<5)
|
||||
last = &f7->DS7EXTNT[i];
|
||||
else
|
||||
if (i<5)
|
||||
last = &f7->DS7EXTNT[i];
|
||||
else
|
||||
last = &f7->DS7ADEXT[i-5];
|
||||
|
||||
for (j=i; j<16; j++)
|
||||
{
|
||||
if (j<5)
|
||||
ext = &f7->DS7EXTNT[j];
|
||||
else
|
||||
if (j<5)
|
||||
ext = &f7->DS7EXTNT[j];
|
||||
else
|
||||
ext = &f7->DS7ADEXT[j-5];
|
||||
|
||||
if (((ext->a > 0) && (last->a == 0)) ||
|
||||
if (((ext->a > 0) && (last->a == 0)) ||
|
||||
((ext->a > 0) && (ext->a < last->a)))
|
||||
{
|
||||
tmp.a = last->a;
|
||||
@@ -1148,19 +1150,19 @@ vtoc_reorganize_FMT7_extents (format7_label_t *f7)
|
||||
/*
|
||||
* add a free space extent description to the VTOC FMT7 DSCB
|
||||
*/
|
||||
void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
u_int32_t a, u_int32_t b)
|
||||
void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
uint32_t a, uint32_t b)
|
||||
{
|
||||
ds7ext_t *ext = NULL, *tmp = NULL;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
if (i<5)
|
||||
ext = &f7->DS7EXTNT[i];
|
||||
else
|
||||
if (i<5)
|
||||
ext = &f7->DS7EXTNT[i];
|
||||
else
|
||||
ext = &f7->DS7ADEXT[i-5];
|
||||
|
||||
if (((a < ext->a) && (b > ext->a) && (b < ext->b)) ||
|
||||
if (((a < ext->a) && (b > ext->a) && (b < ext->b)) ||
|
||||
((a > ext->a) && (a < ext->b) && (b > ext->b))) {
|
||||
printf("BUG: overlapping free space extents "
|
||||
"in FMT7 DSCB!\nexiting...\n");
|
||||
@@ -1171,7 +1173,7 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
ext->a = a;
|
||||
ext->b = b;
|
||||
tmp = ext;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT7 add extent: add new extent\n");
|
||||
break;
|
||||
}
|
||||
@@ -1183,9 +1185,9 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
if (i<5)
|
||||
ext = &f7->DS7EXTNT[i];
|
||||
else
|
||||
if (i<5)
|
||||
ext = &f7->DS7EXTNT[i];
|
||||
else
|
||||
ext = &f7->DS7ADEXT[i-5];
|
||||
|
||||
if ((ext->a + ext->b) == 0x00000000)
|
||||
@@ -1194,27 +1196,27 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
if ((ext->b) == tmp->a) {
|
||||
/* this extent precedes the new one */
|
||||
ext->b = tmp->b;
|
||||
bzero(tmp, sizeof(ds7ext_t));
|
||||
memset(tmp, 0, sizeof(ds7ext_t));
|
||||
tmp = ext;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT7 add extent: " \
|
||||
"merge with predecessor\n");
|
||||
i = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ext->a == (tmp->b))
|
||||
{
|
||||
/* this extent succeeds the new one */
|
||||
ext->a = tmp->a;
|
||||
bzero(tmp, sizeof(ds7ext_t));
|
||||
memset(tmp, 0, sizeof(ds7ext_t));
|
||||
tmp = ext;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT7 add extent: " \
|
||||
"merge with successor\n");
|
||||
i = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1222,22 +1224,22 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
/*
|
||||
* remove a free space extent description from the VTOC FMT7 DSCB
|
||||
*/
|
||||
void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
u_int32_t a, u_int32_t b)
|
||||
void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
uint32_t a, uint32_t b)
|
||||
{
|
||||
ds7ext_t *ext;
|
||||
int i, counter=0;
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
if (i<5)
|
||||
ext = &f7->DS7EXTNT[i];
|
||||
else
|
||||
if (i<5)
|
||||
ext = &f7->DS7EXTNT[i];
|
||||
else
|
||||
ext = &f7->DS7ADEXT[i-5];
|
||||
|
||||
if ((a == ext->a) && (b == ext->b)) {
|
||||
/* fills up whole free space gap */
|
||||
bzero(ext, sizeof(ds7ext_t));
|
||||
if (verbose)
|
||||
memset(ext, 0, sizeof(ds7ext_t));
|
||||
if (verbose)
|
||||
printf("FMT7 del extent: fills whole gap\n");
|
||||
counter++;
|
||||
break;
|
||||
@@ -1246,7 +1248,7 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
if ((a == ext->a) && (b < ext->b)) {
|
||||
/* left-bounded in free space gap */
|
||||
ext->a = b;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT7 add extent: left-bounded\n");
|
||||
counter++;
|
||||
break;
|
||||
@@ -1255,24 +1257,24 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
if ((a > ext->a) && (b == ext->b)) {
|
||||
/* right-bounded in free space gap */
|
||||
ext->b = a;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT7 add extent: right-bounded\n");
|
||||
counter++;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((a > ext->a) && (b < ext->b)) {
|
||||
/* partition devides free space into 2 pieces */
|
||||
vtoc_update_format7_label_add(f7, verbose,
|
||||
/* partition divides free space into 2 pieces */
|
||||
vtoc_update_format7_label_add(f7, verbose,
|
||||
b, ext->b);
|
||||
ext->b = a;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
printf("FMT7 add extent: 2 pieces\n");
|
||||
counter++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (((a < ext->a) && (b > ext->a)) ||
|
||||
if (((a < ext->a) && (b > ext->a)) ||
|
||||
((a < ext->b) && (b > ext->b))) {
|
||||
printf("BUG: specified free space extent for deleting "
|
||||
"doesn't match free space currently shown in "
|
||||
@@ -1294,7 +1296,7 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
*/
|
||||
void vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
|
||||
format7_label_t *f7, char ch, int verbose,
|
||||
u_int32_t start, u_int32_t stop, u_int32_t cyl, u_int32_t trk)
|
||||
uint32_t start, uint32_t stop, uint32_t cyl, uint32_t trk)
|
||||
{
|
||||
if ((cyl * trk) > BIG_DISK_SIZE) {
|
||||
if (ch == '+') {
|
||||
@@ -1317,12 +1319,12 @@ void vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
|
||||
f4->DS4EFLVL = 0x07;
|
||||
vtoc_set_cchhb(&f4->DS4EFPTR, 0x0000, 0x0001, 0x03);
|
||||
} else {
|
||||
u_int16_t x,y;
|
||||
u_int8_t z;
|
||||
uint16_t x,y;
|
||||
uint8_t z;
|
||||
|
||||
x = (u_int16_t) start;
|
||||
y = (u_int16_t) ((stop - start + 1) / trk);
|
||||
z = (u_int8_t) ((stop - start + 1) % trk);
|
||||
x = (uint16_t) start;
|
||||
y = (uint16_t) ((stop - start + 1) / trk);
|
||||
z = (uint8_t) ((stop - start + 1) % trk);
|
||||
|
||||
if (ch == '+') {
|
||||
vtoc_update_format5_label_add(f5, verbose, trk,
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
# Offsets
|
||||
OFFS_INITRD_START_BYTES=66568
|
||||
OFFS_INITRD_SIZE_BYTES=66576
|
||||
OFFS_COMMANDLINE_MAX_SIZE_BYTES=66608
|
||||
OFFS_COMMANDLINE_BYTES=66688
|
||||
MAX_PARMFILE_SIZE=896
|
||||
LEGACY_MAX_PARMFILE_SIZE=896
|
||||
|
||||
# Variables
|
||||
cmd=$(basename $0)
|
||||
cmd=$(basename -- "$0")
|
||||
kernel=
|
||||
ramdisk=
|
||||
parmfile=
|
||||
@@ -34,15 +35,14 @@ binval=
|
||||
success=no
|
||||
|
||||
# Cleanup on exit
|
||||
# shellcheck disable=SC2317
|
||||
cleanup()
|
||||
{
|
||||
if [ -n "$binval" ]
|
||||
then
|
||||
rm -f $binval
|
||||
if [ -n "$binval" ]; then
|
||||
rm -f -- "$binval"
|
||||
fi
|
||||
if [ -n "$image" -a $success = no ]
|
||||
then
|
||||
rm $image
|
||||
if [ -n "$image" ] && [ "$success" = no ]; then
|
||||
rm -f -- "$image"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
@@ -50,25 +50,25 @@ trap cleanup EXIT
|
||||
# Usage
|
||||
usage()
|
||||
{
|
||||
cat <<-EOF
|
||||
Usage: $cmd KERNEL BOOT_IMAGE [-r RAMDISK] [-p PARMFILE]
|
||||
cat <<- EOF
|
||||
Usage: $cmd KERNEL BOOT_IMAGE [-r RAMDISK] [-p PARMFILE]
|
||||
|
||||
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
|
||||
KVM firmware image using a stripped Linux kernel file KERNEL.
|
||||
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
|
||||
KVM firmware image using a stripped Linux kernel file KERNEL.
|
||||
|
||||
OPTIONS
|
||||
-p Use PARMFILE with kernel parameters in the image
|
||||
-r Include RAMDISK in the image
|
||||
-h Print this help, then exit
|
||||
-v Print version information, then exit
|
||||
EOF
|
||||
OPTIONS
|
||||
-p Use PARMFILE with kernel parameters in the image
|
||||
-r Include RAMDISK in the image
|
||||
-h Print this help, then exit
|
||||
-v Print version information, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
printversion()
|
||||
{
|
||||
cat <<-EOD
|
||||
$cmd: version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2017
|
||||
cat <<- EOD
|
||||
$cmd: version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2017
|
||||
EOD
|
||||
}
|
||||
|
||||
@@ -78,12 +78,30 @@ dec2be64()
|
||||
local num=$1
|
||||
local b
|
||||
local i
|
||||
for i in $(seq 1 8)
|
||||
do
|
||||
b="\\x$(printf '%x' $(expr $num % 256))$b"
|
||||
num=$(expr $num / 256) || true
|
||||
for i in $(seq 1 8); do
|
||||
b="\\x$(printf '%x' "$((num % 256))")$b"
|
||||
num=$((num / 256)) || true
|
||||
done
|
||||
printf $b
|
||||
printf '%b' "$b"
|
||||
}
|
||||
|
||||
max_kernel_cmdline_size()
|
||||
{
|
||||
local __kernel=$1 size v
|
||||
|
||||
size_be="$(od -A n -j "${OFFS_COMMANDLINE_MAX_SIZE_BYTES}" -N 8 -t uL -- "$__kernel")"
|
||||
# If little endian then swap bytes
|
||||
if (("$(printf '\1' | od -dAn)" == 1)); then
|
||||
v="$(printf '%016x0' "$size_be")"
|
||||
size="0x${v:14:2}${v:12:2}${v:10:2}${v:8:2}${v:6:2}${v:4:2}${v:2:2}${v:0:2}"
|
||||
else
|
||||
size="$size_be"
|
||||
fi
|
||||
if ((size == 0)); then
|
||||
size="${LEGACY_MAX_PARMFILE_SIZE}"
|
||||
fi
|
||||
# Use arithmetic expression to remove leading and trailing whitespace.
|
||||
printf '%s' "$((size))"
|
||||
}
|
||||
|
||||
# Do the image build
|
||||
@@ -95,16 +113,17 @@ dobuild()
|
||||
local ramdisk_offset
|
||||
local parmfile_size
|
||||
# check whether all specified files exist
|
||||
for i in $kernel $ramdisk $parmfile
|
||||
do
|
||||
if [ ! -f $i ]
|
||||
then
|
||||
echo "$cmd: File $i not found" >&2
|
||||
return 1
|
||||
fi
|
||||
for i in $kernel $ramdisk $parmfile; do
|
||||
if [ ! -f "$i" ]; then
|
||||
echo "$cmd: File $i not found" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ ! -r "$i" ]; then
|
||||
echo "$cmd: File $i cannot be read, no read permission" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
if ! file -b $(readlink -f $kernel) | grep "Linux S390" > /dev/null
|
||||
then
|
||||
if ! file -b -- "$(readlink -f -- "$kernel")" | grep "Linux S390" > /dev/null; then
|
||||
echo "$cmd: Unrecognized file format for $kernel" >&2
|
||||
return 1
|
||||
fi
|
||||
@@ -114,37 +133,36 @@ dobuild()
|
||||
set -e
|
||||
|
||||
# copy over kernel padded with zeroes to page boundary
|
||||
dd if=$kernel of=$image bs=4096 conv=sync status=none
|
||||
dd if="$kernel" of="$image" bs=4096 conv=sync status=none
|
||||
|
||||
# append ramdisk if specified
|
||||
if [ "$ramdisk" != "" ]
|
||||
then
|
||||
ramdisk_size=$(du -b -L $ramdisk | cut -f1)
|
||||
kernel_size=$(du -b -L $kernel | cut -f1)
|
||||
ramdisk_offset=$(du -b -L $image | cut -f1)
|
||||
cat $ramdisk >> $image
|
||||
if [ "$ramdisk" != "" ]; then
|
||||
ramdisk_size=$(du -b -L -- "$ramdisk" | cut -f1)
|
||||
# shellcheck disable=SC2034
|
||||
kernel_size=$(du -b -L -- "$kernel" | cut -f1)
|
||||
ramdisk_offset=$(du -b -L -- "$image" | cut -f1)
|
||||
cat -- "$ramdisk" >> "$image"
|
||||
binval=$(mktemp)
|
||||
dec2be64 $ramdisk_offset > $binval
|
||||
dd seek=$OFFS_INITRD_START_BYTES if=$binval of=$image bs=1 \
|
||||
dec2be64 "$ramdisk_offset" > "$binval"
|
||||
dd seek=$OFFS_INITRD_START_BYTES if="$binval" of="$image" bs=1 \
|
||||
count=8 conv=notrunc status=none
|
||||
dec2be64 $ramdisk_size > $binval
|
||||
dd seek=$OFFS_INITRD_SIZE_BYTES if=$binval of=$image bs=1 \
|
||||
dec2be64 "$ramdisk_size" > "$binval"
|
||||
dd seek=$OFFS_INITRD_SIZE_BYTES if="$binval" of="$image" bs=1 \
|
||||
count=8 conv=notrunc status=none
|
||||
fi
|
||||
|
||||
# set cmdline
|
||||
if [ "$parmfile" != "" ]
|
||||
then
|
||||
parmfile_size=$(du -b -L $parmfile | cut -f1)
|
||||
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
|
||||
then
|
||||
if [ "$parmfile" != "" ]; then
|
||||
max_parmfile_size=$(max_kernel_cmdline_size "$kernel")
|
||||
parmfile_size=$(du -b -L -- "$parmfile" | cut -f1)
|
||||
if ((parmfile_size <= max_parmfile_size)); then
|
||||
# Clear any previous parameters
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count=$MAX_PARMFILE_SIZE \
|
||||
if=/dev/zero of=$image conv=notrunc status=none
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
|
||||
of=$image conv=notrunc status=none
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count="$max_parmfile_size" \
|
||||
if=/dev/zero of="$image" conv=notrunc status=none
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count="$parmfile_size" \
|
||||
if="$parmfile" of="$image" conv=notrunc status=none
|
||||
else
|
||||
echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $MAX_PARMFILE_SIZE" >&2
|
||||
echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $max_parmfile_size bytes" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
@@ -154,25 +172,41 @@ dobuild()
|
||||
}
|
||||
|
||||
# check args and build
|
||||
args=$(getopt "r:p:hv" $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
# shellcheck disable=SC2086,SC2048
|
||||
if args=$(getopt "r:p:hv" $*); then
|
||||
# shellcheck disable=SC2086
|
||||
set -- $args
|
||||
while [ $1 != "" ]
|
||||
do
|
||||
while [ "$1" != "" ]; do
|
||||
case $1 in
|
||||
-r) ramdisk=$2; shift 2;;
|
||||
-p) parmfile=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
-v) printversion; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
-r)
|
||||
ramdisk=$2
|
||||
shift 2
|
||||
;;
|
||||
-p)
|
||||
parmfile=$2
|
||||
shift 2
|
||||
;;
|
||||
-h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-v)
|
||||
printversion
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "$cmd: Unexpected argument $1, exiting..." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $# = 2 ]
|
||||
then
|
||||
if [ $# = 2 ]; then
|
||||
kernel=$1
|
||||
image=$2
|
||||
dobuild
|
||||
|
||||
@@ -42,17 +42,17 @@ install:
|
||||
else
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libnl-3.0)
|
||||
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libnl-genl-3.0)
|
||||
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libnl-route-3.0)
|
||||
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libnl-3.0)
|
||||
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libnl-genl-3.0)
|
||||
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libnl-route-3.0)
|
||||
|
||||
LIB_CFLAGS += $(shell pkg-config --silence-errors --cflags libcrypto)
|
||||
LIB_CFLAGS += $(shell $(PKG_CONFIG) --silence-errors --cflags libcrypto)
|
||||
|
||||
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libnl-3.0)
|
||||
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libnl-genl-3.0)
|
||||
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libnl-route-3.0)
|
||||
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libnl-3.0)
|
||||
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libnl-genl-3.0)
|
||||
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libnl-route-3.0)
|
||||
|
||||
LIB_LFLAGS += $(shell pkg-config --silence-errors --libs libcrypto)
|
||||
LIB_LFLAGS += $(shell $(PKG_CONFIG) --silence-errors --libs libcrypto)
|
||||
else
|
||||
LIB_CFLAGS += -I /usr/include/libnl3/
|
||||
LIB_LFLAGS += -lnl-route-3 -lnl-genl-3 -lnl-3
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <execinfo.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
70
rust/Cargo.lock
generated
70
rust/Cargo.lock
generated
@@ -132,6 +132,15 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.23"
|
||||
@@ -637,6 +646,7 @@ name = "pvimg"
|
||||
version = "0.12.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"deku",
|
||||
@@ -652,6 +662,20 @@ dependencies = [
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pvinfo"
|
||||
version = "0.12.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"s390_pv_core",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"tempfile",
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pvsecret"
|
||||
version = "0.12.0"
|
||||
@@ -665,6 +689,18 @@ dependencies = [
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pvverify"
|
||||
version = "0.12.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"log",
|
||||
"s390_pv",
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
@@ -870,18 +906,28 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.217"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.217"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -890,13 +936,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.99"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1049,11 +1097,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
name = "utils"
|
||||
version = "0.12.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"libc",
|
||||
"log",
|
||||
"s390_pv",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1205,3 +1255,9 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
|
||||
@@ -6,7 +6,9 @@ members = [
|
||||
"pvapconfig",
|
||||
"pvattest",
|
||||
"pvimg",
|
||||
"pvinfo",
|
||||
"pvsecret",
|
||||
"pvverify",
|
||||
"utils",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
@@ -25,12 +25,12 @@ endif #HOSTARCH
|
||||
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
ifneq (${HAVE_LIBCURL},0)
|
||||
PV_TARGETS := pvsecret pvattest pvimg
|
||||
PV_TARGETS := pvsecret pvattest pvimg pvverify
|
||||
|
||||
ifeq ($(HOST_ARCH),s390x)
|
||||
PV_TARGETS += pvapconfig
|
||||
PV_TARGETS += pvapconfig pvinfo
|
||||
else
|
||||
BUILD_TARGETS += skip-pvapconfig
|
||||
BUILD_TARGETS += skip-pvapconfig skip-pvinfo
|
||||
endif #HOSTARCH
|
||||
|
||||
PV_BUILD_TARGETS := $(PV_TARGETS)
|
||||
@@ -75,6 +75,9 @@ skip-build:
|
||||
skip-pv-build:
|
||||
echo " SKIP rust-pv-tools due to unresolved dependencies"
|
||||
|
||||
skip-pvinfo:
|
||||
echo " SKIP pvinfo due to unsupported architecture (s390x only)"
|
||||
|
||||
skip-pvapconfig:
|
||||
echo " SKIP pvapconfig due to unsupported architecture (s390x only)"
|
||||
|
||||
@@ -110,10 +113,9 @@ install-rust-tools: $(BUILD_TARGETS)
|
||||
|
||||
install-man:
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
$(foreach target,$(CARGO_TARGETS),\
|
||||
$(INSTALL) -m 644 $(target)/man/*.1 -t $(DESTDIR)$(MANDIR)/man1;)
|
||||
$(foreach target,$(PV_TARGETS),\
|
||||
$(INSTALL) -m 644 $(target)/man/*.1 -t $(DESTDIR)$(MANDIR)/man1;)
|
||||
$(foreach target,$(CARGO_TARGETS) $(PV_TARGETS),\
|
||||
$(foreach man,$(wildcard $(target)/man/*.1), \
|
||||
$(INSTALL) -m 644 $(man) -t $(DESTDIR)$(MANDIR)/man1;))
|
||||
ln -sf pvimg-create.1 $(DESTDIR)$(MANDIR)/man1/genprotimg.1
|
||||
|
||||
install-shell-completions: install-bash-completion install-zsh-completion
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user