mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
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
|
||||
- Axel Wirbser
|
||||
@@ -28,6 +30,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Eberhard Pasch
|
||||
- Eduard Shishkin
|
||||
- Einar Lueck
|
||||
- Ellen McIntyre
|
||||
- Eric Farman
|
||||
- Eric Sandeen
|
||||
- Erwin Vicari
|
||||
@@ -49,8 +52,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 +75,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 +137,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
|
||||
|
||||
37
CHANGELOG.md
37
CHANGELOG.md
@@ -1,6 +1,43 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __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)
|
||||
|
||||
@@ -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 := 40
|
||||
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
|
||||
|
||||
@@ -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
|
||||
52
cpumf/pai.c
52
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
|
||||
@@ -925,54 +927,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 +992,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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
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};
|
||||
|
||||
@@ -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
|
||||
@@ -45,7 +45,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()
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
134
libvtoc/vtoc.c
134
libvtoc/vtoc.c
@@ -6,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/vtoc.h"
|
||||
|
||||
static unsigned char EBCtoASC[256] =
|
||||
@@ -198,7 +200,7 @@ 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,
|
||||
void vtoc_set_extent (extent_t *ext, uint8_t typeind, uint8_t seqno,
|
||||
cchh_t *lower, cchh_t *upper)
|
||||
{
|
||||
ext->typeind = typeind;
|
||||
@@ -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;
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -703,7 +705,7 @@ 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;
|
||||
}
|
||||
@@ -717,7 +719,7 @@ 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);
|
||||
}
|
||||
@@ -831,7 +833,7 @@ 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));
|
||||
@@ -893,9 +895,9 @@ 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;
|
||||
@@ -954,7 +956,7 @@ 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)
|
||||
printf("FMT5 add extent: " \
|
||||
@@ -969,7 +971,7 @@ 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)
|
||||
printf("FMT5 add extent: " \
|
||||
@@ -988,9 +990,9 @@ 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;
|
||||
@@ -1007,7 +1009,7 @@ 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));
|
||||
memset(ext, 0, sizeof(ds5ext_t));
|
||||
if (verbose)
|
||||
printf("FMT5 del extent: fills whole gap\n");
|
||||
counter++;
|
||||
@@ -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;
|
||||
@@ -1149,7 +1151,7 @@ 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)
|
||||
uint32_t a, uint32_t b)
|
||||
{
|
||||
ds7ext_t *ext = NULL, *tmp = NULL;
|
||||
int i;
|
||||
@@ -1194,7 +1196,7 @@ 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)
|
||||
printf("FMT7 add extent: " \
|
||||
@@ -1207,7 +1209,7 @@ void vtoc_update_format7_label_add (format7_label_t *f7, int verbose,
|
||||
{
|
||||
/* 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)
|
||||
printf("FMT7 add extent: " \
|
||||
@@ -1223,7 +1225,7 @@ 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)
|
||||
uint32_t a, uint32_t b)
|
||||
{
|
||||
ds7ext_t *ext;
|
||||
int i, counter=0;
|
||||
@@ -1236,7 +1238,7 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
|
||||
if ((a == ext->a) && (b == ext->b)) {
|
||||
/* fills up whole free space gap */
|
||||
bzero(ext, sizeof(ds7ext_t));
|
||||
memset(ext, 0, sizeof(ds7ext_t));
|
||||
if (verbose)
|
||||
printf("FMT7 del extent: fills whole gap\n");
|
||||
counter++;
|
||||
@@ -1262,7 +1264,7 @@ void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
|
||||
}
|
||||
|
||||
if ((a > ext->a) && (b < ext->b)) {
|
||||
/* partition devides free space into 2 pieces */
|
||||
/* partition divides free space into 2 pieces */
|
||||
vtoc_update_format7_label_add(f7, verbose,
|
||||
b, ext->b);
|
||||
ext->b = a;
|
||||
@@ -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>
|
||||
|
||||
26
rust/Cargo.lock
generated
26
rust/Cargo.lock
generated
@@ -652,6 +652,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 +679,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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -108,16 +108,16 @@ fn out_instructions(args: &Cli, instructions: &Vec<Instruction>) {
|
||||
}
|
||||
|
||||
fn main() -> anyhowRes<()> {
|
||||
/* ---- PARSE COMMAND LINE ARGUMENTS ---- */
|
||||
// ---- PARSE COMMAND LINE ARGUMENTS ----
|
||||
let args: Cli = Cli::parse();
|
||||
|
||||
/* ---- PRINT VERSION STRING ---- */
|
||||
// ---- PRINT VERSION STRING ----
|
||||
if args.version {
|
||||
print_version!("2024");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/* ---- SET CONSTANTS ---- */
|
||||
// ---- SET CONSTANTS ----
|
||||
let mut instructions = Vec::new();
|
||||
init_instructions(&mut instructions);
|
||||
|
||||
@@ -133,7 +133,7 @@ fn main() -> anyhowRes<()> {
|
||||
update_msa_function_count(&args, &mut levels[idx_of_last_element], &instructions);
|
||||
}
|
||||
|
||||
/* ---- GET INFORMATION ---- */
|
||||
// ---- GET INFORMATION ----
|
||||
// get stfle bits
|
||||
let stfle_bits = Stfle::new()?;
|
||||
|
||||
@@ -245,7 +245,7 @@ fn main() -> anyhowRes<()> {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- OUTPUT ---- */
|
||||
// ---- OUTPUT ----
|
||||
match args.msa {
|
||||
true => out_msa(&args, &levels, &instructions),
|
||||
false => out_instructions(&args, &instructions),
|
||||
|
||||
@@ -162,7 +162,7 @@ impl Display for MsaLevel {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
write!(f, "{} ", self.msa_level)?;
|
||||
match self.stfle_bit {
|
||||
Some(bit) => write!(f, "STFLE bit [ {:>3} ] : ", bit)?,
|
||||
Some(bit) => write!(f, "STFLE bit [ {bit:>3} ] : ")?,
|
||||
None => write!(f, " : ")?,
|
||||
}
|
||||
match self.enabled {
|
||||
|
||||
@@ -233,10 +233,6 @@ pub fn query(ins: &InstructionKind, fc: u8) -> Result<Param, Error> {
|
||||
|
||||
fn read_file_to_buf(file: &mut File, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
file.read(buf)
|
||||
/* match file.read(buf) {
|
||||
Result::Ok(bytes_read) => Ok(bytes_read),
|
||||
Err(e) => Err(e),
|
||||
} */
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -48,7 +48,7 @@ impl TryFrom<Vec<u8>> for BootHdrTags {
|
||||
|
||||
/// Struct representing the Secure Execution boot image metadata
|
||||
#[allow(unused)]
|
||||
#[repr(packed)]
|
||||
#[repr(C, packed)]
|
||||
#[derive(Debug, Clone, FromBytes, IntoBytes, PartialEq, Eq, Immutable, KnownLayout)]
|
||||
pub struct SeImgMetaData {
|
||||
/// Magic value
|
||||
@@ -140,15 +140,14 @@ pub fn seek_se_hdr_start<R>(img: &mut R) -> Result<bool>
|
||||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
let max_iter: usize;
|
||||
const BUF_SIZE: i64 = 8;
|
||||
static_assert!(BootHdrMagic::MAGIC.len() == BUF_SIZE as usize);
|
||||
|
||||
let old_position = img.stream_position()?;
|
||||
if !SeImgMetaData::seek_start(img)? {
|
||||
let max_iter: usize = if !SeImgMetaData::seek_start(img)? {
|
||||
// Search from the previous position.
|
||||
img.seek(std::io::SeekFrom::Start(old_position))?;
|
||||
max_iter = 0x15;
|
||||
0x15
|
||||
} else {
|
||||
let mut img_metadata_bytes = vec![0u8; size_of::<SeImgMetaData>()];
|
||||
// read in the header
|
||||
@@ -161,8 +160,8 @@ where
|
||||
}
|
||||
|
||||
img.seek(std::io::SeekFrom::Start(img_metadata.hdr_off.into()))?;
|
||||
max_iter = 1;
|
||||
}
|
||||
1
|
||||
};
|
||||
|
||||
let mut buf = [0; BUF_SIZE as usize];
|
||||
for _ in 0..max_iter {
|
||||
|
||||
@@ -104,11 +104,11 @@ impl<'d> InnerPem<'d> {
|
||||
/// println!("PEM {pem}");
|
||||
/// ```
|
||||
/// ```PEM
|
||||
///-----BEGIN <name>-----
|
||||
///<header>
|
||||
/// -----BEGIN <name>-----
|
||||
/// <header>
|
||||
///
|
||||
///<Base64 formatted binary data>
|
||||
///-----END <name>-----
|
||||
/// <Base64 formatted binary data>
|
||||
/// -----END <name>-----
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pem {
|
||||
|
||||
@@ -142,7 +142,7 @@ impl AttestationRequest {
|
||||
}
|
||||
|
||||
/// Checks for magic and returns [`BinReqValues`]
|
||||
fn bin_values(arcb: &[u8]) -> Result<BinReqValues> {
|
||||
fn bin_values(arcb: &[u8]) -> Result<BinReqValues<'_>> {
|
||||
if !AttestationMagic::starts_with_magic(arcb) {
|
||||
return Err(Error::NoArcb);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ use zerocopy::{FromBytes, U16};
|
||||
///
|
||||
/// Will convert into PEM as:
|
||||
/// ```PEM
|
||||
///-----BEGIN IBM PROTECTED KEY-----
|
||||
///kind: <name>
|
||||
/// -----BEGIN IBM PROTECTED KEY-----
|
||||
/// kind: <name>
|
||||
///
|
||||
///<protected key in base64>
|
||||
///-----END IBM PROTECTED KEY-----
|
||||
/// <protected key in base64>
|
||||
/// -----END IBM PROTECTED KEY-----
|
||||
/// ```
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct IbmProtectedKey {
|
||||
|
||||
@@ -167,8 +167,7 @@ impl CertVerifier {
|
||||
/// * `cert_paths` - Paths to certificates for the chain of trust
|
||||
/// * `crl_paths` - Paths to certificate revocation lists for the chain of trust
|
||||
/// * `root_ca_path` - Path to the root of trust
|
||||
/// * `offline` - if set to true the verification process will not try to download CRLs from the
|
||||
/// internet.
|
||||
/// * `offline` - if set to true the verification process will not try to download CRLs from the internet.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
||||
@@ -443,17 +443,17 @@ mod test {
|
||||
let ibm_wrong_subj = load_gen_cert("ibm_wrong_subject.crt");
|
||||
let no_sign_crt = load_gen_cert("inter_ca.crt");
|
||||
|
||||
assert!(super::get_ibm_z_sign_key(&[ibm_crt.clone()]).is_ok());
|
||||
assert!(super::get_ibm_z_sign_key(std::slice::from_ref(&ibm_crt)).is_ok());
|
||||
assert!(matches!(
|
||||
super::get_ibm_z_sign_key(&[ibm_crt.clone(), ibm_crt.clone()]),
|
||||
Err(Error::HkdVerify(ManyIbmSignKeys))
|
||||
));
|
||||
assert!(matches!(
|
||||
super::get_ibm_z_sign_key(&[ibm_wrong_subj]),
|
||||
super::get_ibm_z_sign_key(std::slice::from_ref(&ibm_wrong_subj)),
|
||||
Err(Error::HkdVerify(NoIbmSignKey))
|
||||
));
|
||||
assert!(matches!(
|
||||
super::get_ibm_z_sign_key(&[no_sign_crt.clone()]),
|
||||
super::get_ibm_z_sign_key(std::slice::from_ref(&no_sign_crt)),
|
||||
Err(Error::HkdVerify(NoIbmSignKey))
|
||||
));
|
||||
assert!(super::get_ibm_z_sign_key(&[ibm_crt, no_sign_crt]).is_ok(),);
|
||||
|
||||
@@ -303,10 +303,7 @@ pub enum BindState {
|
||||
/// Returns a BindState enum as defined above or on failure
|
||||
/// an error string. Does NOT print any error messages.
|
||||
pub fn get_apqn_bind_state(card: u32, dom: u32) -> Result<BindState> {
|
||||
let path = format!(
|
||||
"{}/card{:02x}/{:02x}.{:04x}/se_bind",
|
||||
PATH_SYS_DEVICES_AP, card, card, dom
|
||||
);
|
||||
let path = format!("{PATH_SYS_DEVICES_AP}/card{card:02x}/{card:02x}.{dom:04x}/se_bind");
|
||||
let state_str = read_file_string(path, "se_bind attribute")?;
|
||||
let state = state_str.trim();
|
||||
match state {
|
||||
@@ -331,10 +328,7 @@ pub fn get_apqn_bind_state(card: u32, dom: u32) -> Result<BindState> {
|
||||
/// Panics if a desired bind state other than Bound or Unbound is given.
|
||||
pub fn set_apqn_bind_state(card: u32, dom: u32, state: BindState) -> Result<()> {
|
||||
let ctx = "bind APQN";
|
||||
let path = format!(
|
||||
"{}/card{:02x}/{:02x}.{:04x}/se_bind",
|
||||
PATH_SYS_DEVICES_AP, card, card, dom
|
||||
);
|
||||
let path = format!("{PATH_SYS_DEVICES_AP}/card{card:02x}/{card:02x}.{dom:04x}/se_bind");
|
||||
match state {
|
||||
BindState::Bound => write_file(path, 1.to_string(), ctx),
|
||||
BindState::Unbound => write_file(path, 0.to_string(), ctx),
|
||||
@@ -374,10 +368,7 @@ pub enum AssocState {
|
||||
/// Returns an AssocState enum as defined above or on failure
|
||||
/// an error string. Does NOT print any error messages.
|
||||
pub fn get_apqn_associate_state(card: u32, dom: u32) -> Result<AssocState> {
|
||||
let path = format!(
|
||||
"{}/card{:02x}/{:02x}.{:04x}/se_associate",
|
||||
PATH_SYS_DEVICES_AP, card, card, dom
|
||||
);
|
||||
let path = format!("{PATH_SYS_DEVICES_AP}/card{card:02x}/{card:02x}.{dom:04x}/se_associate");
|
||||
let state_str = read_file_string(path, "se_associate attribute")?;
|
||||
let state = state_str.trim();
|
||||
match state.strip_prefix("associated ") {
|
||||
@@ -392,10 +383,7 @@ pub fn get_apqn_associate_state(card: u32, dom: u32) -> Result<AssocState> {
|
||||
}
|
||||
|
||||
fn set_apqn_associate_state_associate(card: u32, dom: u32, idx: u16) -> Result<()> {
|
||||
let path = format!(
|
||||
"{}/card{:02x}/{:02x}.{:04x}/se_associate",
|
||||
PATH_SYS_DEVICES_AP, card, card, dom
|
||||
);
|
||||
let path = format!("{PATH_SYS_DEVICES_AP}/card{card:02x}/{card:02x}.{dom:04x}/se_associate");
|
||||
write_file(path, idx.to_string(), "associate APQN")?;
|
||||
let mut ms: u64 = 0;
|
||||
loop {
|
||||
@@ -422,10 +410,7 @@ fn set_apqn_associate_state_associate(card: u32, dom: u32, idx: u16) -> Result<(
|
||||
}
|
||||
|
||||
fn set_apqn_associate_state_unbind(card: u32, dom: u32) -> Result<()> {
|
||||
let bindpath = format!(
|
||||
"{}/card{:02x}/{:02x}.{:04x}/se_bind",
|
||||
PATH_SYS_DEVICES_AP, card, card, dom
|
||||
);
|
||||
let bindpath = format!("{PATH_SYS_DEVICES_AP}/card{card:02x}/{card:02x}.{dom:04x}/se_bind");
|
||||
write_file(bindpath, 0.to_string(), "unbind APQN")?;
|
||||
let mut ms: u64 = 0;
|
||||
loop {
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::{Error, Result};
|
||||
use log::debug;
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
ffi::c_ulong,
|
||||
fs::File,
|
||||
os::unix::prelude::{AsRawFd, RawFd},
|
||||
};
|
||||
@@ -46,7 +45,7 @@ pub type UvFlags = crate::misc::Msb0Flags64;
|
||||
///
|
||||
/// # Safety:
|
||||
/// Raw fd must point to an open file
|
||||
fn ioctl_raw(raw_fd: RawFd, cmd: c_ulong, cb: &mut IoctlCb) -> Result<()> {
|
||||
fn ioctl_raw(raw_fd: RawFd, cmd: u64, cb: &mut IoctlCb) -> Result<()> {
|
||||
debug!("calling unsafe fn wrapper uv::ioctl_raw with {raw_fd:#x?}, {cmd:#x?}, {cb:?}");
|
||||
|
||||
let rc;
|
||||
@@ -56,7 +55,7 @@ fn ioctl_raw(raw_fd: RawFd, cmd: c_ulong, cb: &mut IoctlCb) -> Result<()> {
|
||||
// SAFETY: the passed pointer points to a valid memory region that
|
||||
// contains the expected C-struct. The struct outlives this function.
|
||||
unsafe {
|
||||
rc = ioctl(raw_fd, cmd, cb.as_ptr_mut());
|
||||
rc = ioctl(raw_fd, cmd.try_into().unwrap(), cb.as_ptr_mut());
|
||||
}
|
||||
|
||||
// NOTE io::Error handles all errnos ioctl uses
|
||||
|
||||
@@ -245,6 +245,7 @@ assert_size!(SecretListHdr, 16);
|
||||
/// The list should ONLY be created from an UV-Call result using either:
|
||||
/// - [`TryInto::try_into`] from [`ListCmd`]
|
||||
/// - [`SecretList::decode`]
|
||||
///
|
||||
/// Any other ways can create invalid lists that do not represent the UV secret store.
|
||||
/// The list must not hold more than [`u32::MAX`] elements
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Default)]
|
||||
|
||||
@@ -126,10 +126,7 @@ impl ApqnList {
|
||||
match sysfs_get_list_of_subdirs_matching_regex(PATH_SYS_DEVICES_AP, RE_CARD_DIR) {
|
||||
Ok(r) => r,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"Failure reading AP devices {} ({:?}).",
|
||||
PATH_SYS_DEVICES_AP, err
|
||||
);
|
||||
eprintln!("Failure reading AP devices {PATH_SYS_DEVICES_AP} ({err:?}).");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
@@ -138,10 +135,7 @@ impl ApqnList {
|
||||
let queue_dirs = match sysfs_get_list_of_subdirs_matching_regex(&path, RE_QUEUE_DIR) {
|
||||
Ok(r) => r,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"Failure reading AP queue directories in {} ({:?}).",
|
||||
path, err
|
||||
);
|
||||
eprintln!("Failure reading AP queue directories in {path} ({err:?}).");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
@@ -209,7 +203,7 @@ impl ApqnList {
|
||||
continue;
|
||||
}
|
||||
if i1.mkvp == i2.mkvp {
|
||||
eprintln!("APQN {} and APQN {} have same MPVK", a1, a2);
|
||||
eprintln!("APQN {a1} and APQN {a2} have same MPVK");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ impl ApConfigEntry {
|
||||
self.mode = mode;
|
||||
self.validate_accel_entry()?;
|
||||
}
|
||||
_ => return Err(format!("Unknown or invalid mode '{}'.", mode)),
|
||||
_ => return Err(format!("Unknown or invalid mode '{mode}'.")),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -174,19 +174,11 @@ impl ApConfigList {
|
||||
fn read_yaml_file(fname: &str) -> Result<Vec<ApConfigEntry>, String> {
|
||||
let file = match File::open(fname) {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
return Err(format!(
|
||||
"Failure to open AP config file {}: {:?}",
|
||||
fname, err
|
||||
))
|
||||
}
|
||||
Err(err) => return Err(format!("Failure to open AP config file {fname}: {err:?}")),
|
||||
};
|
||||
match serde_yaml::from_reader(file) {
|
||||
Ok(cfg) => Ok(cfg),
|
||||
Err(err) => Err(format!(
|
||||
"Failure parsing AP config file {}: {:?}",
|
||||
fname, err
|
||||
)),
|
||||
Err(err) => Err(format!("Failure parsing AP config file {fname}: {err:?}")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,10 +187,10 @@ impl ApConfigList {
|
||||
let ename = if !entry.name.trim().is_empty() {
|
||||
format!("AP config entry {} '{}'", i, entry.name.trim())
|
||||
} else {
|
||||
format!("AP config entry {}", i)
|
||||
format!("AP config entry {i}")
|
||||
};
|
||||
if let Err(err) = &entry.validate() {
|
||||
return Err(format!("{}: {}", ename, err));
|
||||
return Err(format!("{ename}: {err}"));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -102,10 +102,7 @@ fn main() -> ExitCode {
|
||||
Err(err) => println_and_exit_failure!("{}", err),
|
||||
};
|
||||
if apconfig.is_empty() {
|
||||
println!(
|
||||
"No AP configuration entries in config file '{}': Nothing to do.",
|
||||
configfile
|
||||
);
|
||||
println!("No AP configuration entries in config file '{configfile}': Nothing to do.");
|
||||
return ExitCode::SUCCESS;
|
||||
}
|
||||
info!("Found {} AP configuration entries.\n", apconfig.len());
|
||||
@@ -382,7 +379,7 @@ fn do_ap_config(
|
||||
if let Err(err) = apqn.set_bind_state(pvap::bind_state::Bound) {
|
||||
// bind failed, unbind/reset this apqn, return with failure
|
||||
let _ = apqn.set_bind_state(pvap::bind_state::Unbound);
|
||||
return Err(format!("Failure binding APQN {}: {}", apqn, err));
|
||||
return Err(format!("Failure binding APQN {apqn}: {err}"));
|
||||
}
|
||||
}
|
||||
// try to associate
|
||||
@@ -662,6 +659,6 @@ mod tests {
|
||||
let r = do_ap_config(&mut apqnlist, &secretlist, &apcfglist, true);
|
||||
assert!(r.is_ok());
|
||||
let n = r.unwrap();
|
||||
assert!(n == 3, "n = {} != 3", n);
|
||||
assert!(n == 3, "n = {n} != 3");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ pub fn has_list_secrets_facility() -> Result<(), String> {
|
||||
/// The list may be empty if the UV doesn't have any secrets stored.
|
||||
pub fn gather_secrets() -> Result<SecretList, String> {
|
||||
let uv = match UvDevice::open() {
|
||||
Err(e) => return Err(format!("Failed to open UV device: {:?}.", e)),
|
||||
Err(e) => return Err(format!("Failed to open UV device: {e:?}.")),
|
||||
Ok(u) => u,
|
||||
};
|
||||
let mut cmd = ListCmd::default();
|
||||
|
||||
@@ -44,15 +44,15 @@ impl Display for AttestationResult<'_> {
|
||||
writeln!(f, "{:#}", self.cuid)?;
|
||||
if let Some(data) = &self.add {
|
||||
writeln!(f, "Additional-data:")?;
|
||||
writeln!(f, "{:#}", data)?;
|
||||
writeln!(f, "{data:#}")?;
|
||||
}
|
||||
if let Some(data) = &self.add_fields {
|
||||
writeln!(f, "Additional-data content:")?;
|
||||
writeln!(f, "{:#}", data)?;
|
||||
writeln!(f, "{data:#}")?;
|
||||
}
|
||||
if let Some(data) = &self.user_data {
|
||||
writeln!(f, "user-data:")?;
|
||||
writeln!(f, "{:#}", data)?;
|
||||
writeln!(f, "{data:#}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -123,8 +123,7 @@ pub fn host_key_check<'a, 'b>(
|
||||
}) {
|
||||
Some(phkh) => contains_phkh(&hkd_hashes, phkh, kind, check_enforced),
|
||||
None if check_enforced => CheckState::Err(format!(
|
||||
"The Attestation result does not contain an {}, but checking was enabled.",
|
||||
kind
|
||||
"The Attestation result does not contain an {kind}, but checking was enabled."
|
||||
)),
|
||||
None => CheckState::Data(HostKeyCheck::default()),
|
||||
};
|
||||
@@ -135,7 +134,6 @@ pub fn host_key_check<'a, 'b>(
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -170,7 +168,7 @@ mod test {
|
||||
let res = contains_phkh(&hash, &HexSlice::from(&hash[0].1), HkCheck::Image, true);
|
||||
assert!(matches!(
|
||||
res,
|
||||
CheckState::Data(s) if s.hash.unwrap() == PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/assets/host.pem.crt"))
|
||||
CheckState::Data(s) if s.hash.unwrap() == Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/assets/host.pem.crt"))
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user