mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c217f6be6a | ||
|
|
21662d38e6 | ||
|
|
19f3842292 | ||
|
|
ae0cbf00b1 | ||
|
|
9019c6864a | ||
|
|
d1b61c37fa | ||
|
|
32b68a5fad | ||
|
|
55fdb17b18 | ||
|
|
af730c79a6 | ||
|
|
041e6131d1 | ||
|
|
5a7d7e05b8 | ||
|
|
71b93d55ef | ||
|
|
d2b5e1e2d6 | ||
|
|
a3cb877c54 | ||
|
|
6895a71cc4 | ||
|
|
d9034b01f1 | ||
|
|
488ac8c3f2 | ||
|
|
ecf36d53c8 | ||
|
|
893ad920c5 | ||
|
|
0695c79f4e | ||
|
|
8837ea24cb | ||
|
|
65222d03b9 | ||
|
|
54937495e2 | ||
|
|
8a783b81a4 | ||
|
|
093da2a5a7 | ||
|
|
b68ea5fc7d | ||
|
|
90c587408f | ||
|
|
90475fbaa5 | ||
|
|
07ff9e1da0 | ||
|
|
5637799c92 | ||
|
|
73c82441e7 | ||
|
|
6d06921276 | ||
|
|
2996b34ddf | ||
|
|
e5821301f6 | ||
|
|
f4d1874ac5 | ||
|
|
f3428929a2 | ||
|
|
263d6950a1 | ||
|
|
8024f8e31a | ||
|
|
3849b29594 | ||
|
|
0e4d4da0e5 | ||
|
|
ca3cd51f91 | ||
|
|
fda1e0d33d | ||
|
|
1a850392bc | ||
|
|
14a79eb142 | ||
|
|
271b809495 | ||
|
|
2363269c1c | ||
|
|
f1db473d11 | ||
|
|
e35d05a5e3 | ||
|
|
c61783546b | ||
|
|
c08794bdfb | ||
|
|
4905975f81 | ||
|
|
d53bfb9201 | ||
|
|
0dac47cb62 | ||
|
|
7b68552359 | ||
|
|
775495c7e7 | ||
|
|
1057f13cdc | ||
|
|
ce59a299cb | ||
|
|
8235e025d4 | ||
|
|
b301381f90 | ||
|
|
c62f930634 | ||
|
|
85eb44ac95 | ||
|
|
d5f8063900 | ||
|
|
ee66929465 | ||
|
|
1b044b8a40 | ||
|
|
f46f6d34d3 | ||
|
|
3a96e8826f | ||
|
|
84738668ca | ||
|
|
dbea311aa8 |
@@ -29,5 +29,5 @@ indent_size = 4
|
||||
[{Makefile,*.mak}]
|
||||
indent_style = tab
|
||||
|
||||
[COMMIT_EDITMSG]
|
||||
[{COMMIT_EDITMSG,EDIT_DESCRIPTION}]
|
||||
max_line_length = 72
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,6 +32,7 @@ cpacfstats/cpacfstatsd
|
||||
cpumf/chcpumf
|
||||
cpumf/lscpumf
|
||||
cpumf/lshwc
|
||||
cpumf/lspai
|
||||
cpumf/pai
|
||||
cpuplugd/cpuplugd
|
||||
dasdfmt/dasdfmt
|
||||
|
||||
5
.shellcheckrc
Normal file
5
.shellcheckrc
Normal file
@@ -0,0 +1,5 @@
|
||||
# Search in the current script's directory by default (since 0.7.0)
|
||||
source-path=SCRIPTDIR
|
||||
|
||||
# Allow external-sources (since 0.8.0)
|
||||
external-sources=true
|
||||
@@ -27,6 +27,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Eberhard Pasch
|
||||
- Eduard Shishkin
|
||||
- Einar Lueck
|
||||
- Eric Farman
|
||||
- Eric Sandeen
|
||||
- Erwin Vicari
|
||||
- Eugene Crosser
|
||||
@@ -56,6 +57,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Horst Hummel
|
||||
- Ingo Franzki
|
||||
- Ingo Tuchscherer
|
||||
- Jakub Čajka
|
||||
- Jan Glauber
|
||||
- Jan Höppner
|
||||
- Jan Willeke
|
||||
@@ -124,6 +126,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Thomas Richter
|
||||
- Thomas Spatzier
|
||||
- Thomas Weber
|
||||
- Thorsten Winkler
|
||||
- Tuan Hoang
|
||||
- Ursula Braun
|
||||
- Utz Bacher
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,6 +1,33 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.30.0 (2023-12-01)__
|
||||
|
||||
For Linux kernel version: 6.6
|
||||
|
||||
Add new tools / libraries:
|
||||
- lspai: Tool to display PAI counter sets
|
||||
- s390-tools: Provide a ShellCheck configuration
|
||||
|
||||
Changes of existing tools / libraries:
|
||||
- cpumf/pai: Add command line option for realtime scheduling
|
||||
- dbginfo.sh: enhance ethtool collection for ROCE
|
||||
- libutil/util_lockfile: add routine to return owning pid of file lock
|
||||
- lszcrypt: Improve lszcrypt output on SE guests
|
||||
- rust: Use a single workspace for all rust tools
|
||||
- zdev: limit the derivation of ZDEV_SITE_ID
|
||||
- zdump/df_s390: Update 'zgetdump -i' output with zlib info
|
||||
- zdump/dfi_s390: Support reading compressed s390_ext dumps
|
||||
- zipl/boot: Integrate zlib compression to single volume DASD dumper
|
||||
- zipl/boot: compile the bootloaders only if HOST_ARCH is s390x
|
||||
- zipl: Add --no-compress option to zipl command
|
||||
- zkey: Also check for deconfigured and check-stopped cards
|
||||
|
||||
Bug Fixes:
|
||||
- ap_tools/ap-check: handle get-attributes between pre and post event
|
||||
- libutil: fix util_file_read_*() using wrong format specifiers
|
||||
- rust/pv: fix Invalid write of size 1
|
||||
|
||||
* __v2.29.0 (2023-08-04)__
|
||||
|
||||
For Linux kernel version: 6.5
|
||||
|
||||
18
README.md
18
README.md
@@ -386,6 +386,24 @@ the different tools are provided:
|
||||
- Packages: blktrace, multipath-tools, sg3-utils
|
||||
- Tools: rsync, tar, lsscsi
|
||||
|
||||
* zipl
|
||||
For CCW-type DASD dump, zlib compression can be used to compress the dump
|
||||
data before writing it to the DASD partition. It can benefit from
|
||||
s390 on-chip compression accelerator (DFLTCC) and provide a faster dumping
|
||||
process, hence lower system downtime.
|
||||
The zlib version integrated with zipl (zipl/boot/zlib) is based on the Linux
|
||||
kernel zlib (kernel version 6.3) which represents zlib version 1.1.3 with a
|
||||
limited number of functions and a number of updates on top including s390
|
||||
hardware compression (DFLTCC) support. Also, all memory allocations are
|
||||
performed in advance, which aligns with zipl requirements.
|
||||
The CCW-type standalone dumper is built as a single binary and must be
|
||||
loaded to stage2 during boot. Hence, all required zlib functions must be
|
||||
integrated into it, and its size is restricted. To limit the size, only
|
||||
deflate-related parts are integrated (no decompression is required during
|
||||
dumping).
|
||||
Removing the inflate modules and function prototypes are the only major
|
||||
modifications made to the kernel version of zlib.
|
||||
|
||||
* zgetdump
|
||||
For building zgetdump you need OpenSSL version 1.1.0 or newer
|
||||
installed (openssl-devel.rpm). Also required is glib2
|
||||
|
||||
@@ -798,12 +798,34 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
|
||||
FILE *f;
|
||||
int rc;
|
||||
|
||||
rc = ap_get_lock_callout();
|
||||
if (rc) {
|
||||
fprintf(stderr, "Failed to acquire configuration lock %d\n", rc);
|
||||
return -1;
|
||||
/*
|
||||
* For the get-attributes callout, we are typically called without the
|
||||
* callout lock held. However, there is a particular scenario (define
|
||||
* of an active mdev) where we may or may not be called with the lock
|
||||
* already held on behalf of mdevctl, depending on the mdevctl version.
|
||||
* Let's test for lock ownership first and, if already owned by the
|
||||
* parent (mdevctl) proceed rather than waiting on the file lock.
|
||||
*/
|
||||
rc = ap_try_lock_callout();
|
||||
switch (rc) {
|
||||
case 0:
|
||||
/* Lock acquired */
|
||||
anc->cleanup_lock = true;
|
||||
break;
|
||||
case 1:
|
||||
/* Lock held by parent -- trust the lock will remain held */
|
||||
break;
|
||||
default:
|
||||
/* Lock not acquired or held by parent -- do a normal obtain */
|
||||
rc = ap_get_lock_callout();
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"Failed to acquire configuration lock %d\n",
|
||||
rc);
|
||||
return -1;
|
||||
}
|
||||
anc->cleanup_lock = true;
|
||||
}
|
||||
anc->cleanup_lock = true;
|
||||
|
||||
/*
|
||||
* Read the 'matrix' and 'control_domains' attributes to get the
|
||||
|
||||
32
common.mak
32
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 = 29
|
||||
RELEASE = 30
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
@@ -93,19 +93,19 @@ define cmd_define_and_export
|
||||
endef
|
||||
|
||||
define define_toolchain_variables
|
||||
$(eval $(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as))
|
||||
$(eval $(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc))
|
||||
$(eval $(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1))))
|
||||
$(eval $(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++))
|
||||
$(eval $(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1))))
|
||||
$(eval $(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E))
|
||||
$(eval $(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar))
|
||||
$(eval $(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm))
|
||||
$(eval $(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip))
|
||||
$(eval $(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy))
|
||||
$(eval $(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump))
|
||||
$(eval PKG_CONFIG$(1) = pkg-config)
|
||||
$(eval export PKG_CONFIG$(1))
|
||||
$(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as)
|
||||
$(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc)
|
||||
$(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1)))
|
||||
$(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++)
|
||||
$(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1)))
|
||||
$(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E)
|
||||
$(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar)
|
||||
$(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm)
|
||||
$(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip)
|
||||
$(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy)
|
||||
$(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump)
|
||||
PKG_CONFIG$(1) = pkg-config
|
||||
export PKG_CONFIG$(1)
|
||||
endef
|
||||
|
||||
# If the host architecture is not the same as the build architecture
|
||||
@@ -119,8 +119,8 @@ ifneq ($(HOST_ARCH),$(BUILD_ARCH))
|
||||
endif
|
||||
endif
|
||||
|
||||
$(call define_toolchain_variables,_FOR_BUILD,)
|
||||
$(call define_toolchain_variables,,$(CROSS_COMPILE))
|
||||
$(eval $(call define_toolchain_variables,_FOR_BUILD,))
|
||||
$(eval $(call define_toolchain_variables,,$(CROSS_COMPILE)))
|
||||
|
||||
|
||||
$(eval $(call cmd_define, RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
include ../common.mak
|
||||
|
||||
BIN_FILES = lscpumf chcpumf lshwc pai
|
||||
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8
|
||||
BIN_FILES = lscpumf chcpumf lshwc pai lspai
|
||||
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8 lspai.8
|
||||
|
||||
all: $(BIN_FILES)
|
||||
|
||||
@@ -11,6 +11,7 @@ lscpumf: lscpumf.o $(libs)
|
||||
chcpumf: chcpumf.o $(libs)
|
||||
lshwc: lshwc.o $(libs)
|
||||
pai: pai.o $(libs)
|
||||
lspai: lspai.o $(libs)
|
||||
|
||||
install: all install-man
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
352
cpumf/lspai.c
Normal file
352
cpumf/lspai.c
Normal file
@@ -0,0 +1,352 @@
|
||||
/* Copyright IBM Corp. 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
/* List available Processor Assist Instrumentation (PAI) counters. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/util_scandir.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_list.h"
|
||||
#include "lib/libcpumf.h"
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_SECTION("OPTIONS"),
|
||||
{
|
||||
.option = { "numeric", no_argument, NULL, 'n' },
|
||||
.desc = "Sort PAI counters by counter number"
|
||||
},
|
||||
{
|
||||
.option = { "type", required_argument, NULL, 't' },
|
||||
.argument = "TYPE",
|
||||
.desc = "Type of PAI counters to show: crypto, nnpa"
|
||||
},
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "List Processor Assist Information counter sets",
|
||||
.copyright_vec = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2023,
|
||||
.pub_last = 2023,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
};
|
||||
|
||||
static bool numsort; /* If true sort counter numerically */
|
||||
|
||||
#define PAI_PATH "/bus/event_source/devices/%s"
|
||||
|
||||
enum pai_types { /* Bit mask for supported PAI counters */
|
||||
pai_type_crypto = 0, /* PAI Crypto Counters */
|
||||
pai_type_nnpa = 1, /* PAI NNPA Counters */
|
||||
pai_type_max = 2, /* PAI maximum value, must be last */
|
||||
};
|
||||
|
||||
static int pai_types_show;
|
||||
|
||||
struct pai_ctrname { /* List of defined counters */
|
||||
char *name; /* Counter name */
|
||||
unsigned long nr; /* Counter number */
|
||||
};
|
||||
|
||||
struct pai_node { /* Head for PAI counter sets */
|
||||
struct util_list_node node; /* Successor in PAI counter set list */
|
||||
enum pai_types type; /* PAI type */
|
||||
int pmu; /* Assigned PMU type number */
|
||||
const char *name; /* Counter set name */
|
||||
char *name_uc; /* Counter set name upper case */
|
||||
const char *sysfs_name; /* Counter set name in /sysfs tree */
|
||||
const char *filter_name; /* Counter set name for scandir filter */
|
||||
struct pai_ctrname *ctrlist; /* List of counter names & numbers */
|
||||
size_t ctrsize; /* Total size in bytes of ctrlist */
|
||||
int ctridx; /* Index of last entry used in ctrlist */
|
||||
unsigned long base; /* Base number for counter set */
|
||||
};
|
||||
|
||||
static struct util_list pai_list;
|
||||
|
||||
/* Return base of counter set, this is the first counter of this set. */
|
||||
static unsigned long pai_type_base(enum pai_types t)
|
||||
{
|
||||
switch (t) {
|
||||
case pai_type_crypto:
|
||||
return 0x1000;
|
||||
case pai_type_nnpa:
|
||||
return 0x1800;
|
||||
case pai_type_max:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test PAI counter name from command line option. */
|
||||
static const char *pai_type_name(enum pai_types t)
|
||||
{
|
||||
switch (t) {
|
||||
case pai_type_crypto:
|
||||
return "crypto";
|
||||
case pai_type_nnpa:
|
||||
return "nnpa";
|
||||
case pai_type_max:
|
||||
break;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/* Convert PAI counter type to sysfs directory name. Only validated
|
||||
* input at this time.
|
||||
*/
|
||||
static const char *pai_type_sysfs(enum pai_types t)
|
||||
{
|
||||
if (t == pai_type_crypto)
|
||||
return "pai_crypto";
|
||||
return "pai_ext";
|
||||
}
|
||||
|
||||
/* Convert PAI counter type to sysfs directory name filter for scandir(). */
|
||||
static const char *pai_type_filter(enum pai_types t)
|
||||
{
|
||||
if (t == pai_type_nnpa)
|
||||
return "^NNPA";
|
||||
return "[^.]"; /* Matches anything but . and .. in sysfs */
|
||||
}
|
||||
|
||||
/* Sort PAI counter names by assigned counter number. */
|
||||
static int pai_ctrcmp(const void *p1, const void *p2)
|
||||
{
|
||||
struct pai_ctrname *l = (struct pai_ctrname *)p1;
|
||||
struct pai_ctrname *r = (struct pai_ctrname *)p2;
|
||||
|
||||
return l->nr > r->nr ? 1 : -1;
|
||||
}
|
||||
|
||||
/* Convert string to upper case. */
|
||||
static char *str2uc(const char *s)
|
||||
{
|
||||
char *uc = util_strdup(s), *old_uc = uc;
|
||||
|
||||
for (; *uc; ++uc)
|
||||
*uc = toupper(*uc);
|
||||
return old_uc;
|
||||
}
|
||||
|
||||
/* Read counter names and assigned event number from sysfs file tree.
|
||||
* Exit when sysfs directory can not be scanned.
|
||||
*/
|
||||
static void read_counternames(struct pai_node *node)
|
||||
{
|
||||
int i, more = 0, ctr = 0, count = 0;
|
||||
struct dirent **namelist = NULL;
|
||||
char *path, *ctrpath;
|
||||
|
||||
/* Read counter names and assigned event number. */
|
||||
path = util_path_sysfs(PAI_PATH "/events", node->sysfs_name);
|
||||
count = util_scandir(&namelist, alphasort, path, node->filter_name);
|
||||
if (count <= 0)
|
||||
errx(EXIT_FAILURE, "Cannot open %s", path);
|
||||
|
||||
node->ctrsize = count * sizeof(*node->ctrlist);
|
||||
node->ctrlist = util_malloc(node->ctrsize);
|
||||
for (i = 0; i < count && ctr >= 0; i++) {
|
||||
util_asprintf(&ctrpath, "%s/%s", path, namelist[i]->d_name);
|
||||
if (util_file_read_va(ctrpath, "event=%x", &ctr) == 1) {
|
||||
node->ctrlist[node->ctridx].name = util_strdup(namelist[i]->d_name);
|
||||
node->ctrlist[node->ctridx++].nr = ctr;
|
||||
more++;
|
||||
} else {
|
||||
warnx("Cannot parse %s", ctrpath);
|
||||
}
|
||||
free(ctrpath);
|
||||
}
|
||||
util_scandir_free(namelist, count);
|
||||
free(path);
|
||||
|
||||
if (numsort && more > 1)
|
||||
qsort(node->ctrlist, more, sizeof(*node->ctrlist), pai_ctrcmp);
|
||||
}
|
||||
|
||||
static void show_painode(void)
|
||||
{
|
||||
struct pai_node *node;
|
||||
int indent = 0;
|
||||
int offset = 0;
|
||||
|
||||
util_list_iterate(&pai_list, node) {
|
||||
for (int i = 0; i < node->ctridx; ++i)
|
||||
indent = MAX((size_t)indent, strlen(node->ctrlist[i].name));
|
||||
}
|
||||
|
||||
printf("RAW %*s NAME %*s DESCRIPTION\n", 3, "", indent - 5, "");
|
||||
util_list_iterate(&pai_list, node) {
|
||||
for (int i = 0; i < node->ctridx; ++i) {
|
||||
printf("%d:%ld %s", node->pmu,
|
||||
node->ctrlist[i].nr, node->ctrlist[i].name);
|
||||
|
||||
offset = indent - strlen(node->ctrlist[i].name) + 1;
|
||||
printf("%*s", offset, "");
|
||||
|
||||
printf("Counter %ld / PAI %s counter set\n",
|
||||
node->ctrlist[i].nr - node->base, node->name_uc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Release all memory allocated at make_painode(). */
|
||||
static void free_painode(void)
|
||||
{
|
||||
struct pai_node *next, *node;
|
||||
|
||||
util_list_iterate_safe(&pai_list, node, next) {
|
||||
free(node->name_uc);
|
||||
for (int i = 0; i < node->ctridx; ++i)
|
||||
free(node->ctrlist[i].name);
|
||||
free(node->ctrlist);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void make_painode(enum pai_types t)
|
||||
{
|
||||
struct pai_node *node = util_zalloc(sizeof(*node));
|
||||
char *path;
|
||||
|
||||
node->type = t;
|
||||
node->sysfs_name = pai_type_sysfs(t);
|
||||
node->name = pai_type_name(t);
|
||||
node->name_uc = str2uc(node->name);
|
||||
node->filter_name = pai_type_filter(t);
|
||||
node->base = pai_type_base(t);
|
||||
|
||||
/* Read PMU type number. */
|
||||
path = util_path_sysfs(PAI_PATH, node->sysfs_name);
|
||||
node->pmu = libcpumf_pmutype(path);
|
||||
if (node->pmu < 0)
|
||||
errx(EXIT_FAILURE, "Cannot open %s", path);
|
||||
free(path);
|
||||
|
||||
read_counternames(node);
|
||||
|
||||
util_list_add_tail(&pai_list, node);
|
||||
}
|
||||
|
||||
static int painode_cmp(void *a, void *b, void *UNUSED(data))
|
||||
{
|
||||
struct pai_node *n1 = (struct pai_node *)a;
|
||||
struct pai_node *n2 = (struct pai_node *)b;
|
||||
|
||||
return n1->pmu < n2->pmu ? -1 : 1;
|
||||
}
|
||||
|
||||
static void sort_painode(void)
|
||||
{
|
||||
util_list_sort(&pai_list, painode_cmp, NULL);
|
||||
}
|
||||
|
||||
/* Check for hardware support and return false if not available. */
|
||||
static bool have_support(enum pai_types t)
|
||||
{
|
||||
const char *sysfn = pai_type_sysfs(t);
|
||||
char *path = util_path_sysfs(PAI_PATH, sysfn);
|
||||
bool rc = true;
|
||||
|
||||
if (!util_path_is_dir(path)) {
|
||||
warnx("No support for PAI %s facility", pai_type_name(t));
|
||||
rc = false;
|
||||
}
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the argument for option -t. It must be a valid PAI counter set.
|
||||
* Exit when an invalid PAI counter set name has been specified.
|
||||
*/
|
||||
static void check_type_name(const char *type)
|
||||
{
|
||||
bool no_match = true;
|
||||
enum pai_types i;
|
||||
const char *fn;
|
||||
|
||||
for (i = pai_type_crypto; i < pai_type_max; ++i) {
|
||||
fn = pai_type_name(i);
|
||||
if (!strcasecmp(fn, type)) {
|
||||
pai_types_show |= (1 << i);
|
||||
no_match = false;
|
||||
}
|
||||
}
|
||||
if (no_match)
|
||||
errx(EXIT_FAILURE, "Invalid argument for -t %s", type);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
|
||||
util_list_init(&pai_list, struct pai_node, node);
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
while ((ch = util_opt_getopt_long(argc, argv)) != -1) {
|
||||
switch (ch) {
|
||||
default:
|
||||
util_opt_print_parse_error(ch, argv);
|
||||
return EXIT_FAILURE;
|
||||
case 'h':
|
||||
util_prg_print_help();
|
||||
util_opt_print_help();
|
||||
return EXIT_SUCCESS;
|
||||
case 'v':
|
||||
util_prg_print_version();
|
||||
return EXIT_SUCCESS;
|
||||
case 'n':
|
||||
numsort = true;
|
||||
break;
|
||||
case 't':
|
||||
check_type_name(optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing specified, show all PAI counters */
|
||||
if (!pai_types_show)
|
||||
pai_types_show = (1 << pai_type_crypto) | (1 << pai_type_nnpa);
|
||||
|
||||
/* Check for hardware support */
|
||||
for (enum pai_types i = pai_type_crypto; i < pai_type_max; ++i) {
|
||||
if ((pai_types_show & (1 << i))) {
|
||||
if (!have_support(i))
|
||||
pai_types_show &= ~(1 << i);
|
||||
else
|
||||
make_painode(i);
|
||||
}
|
||||
}
|
||||
sort_painode();
|
||||
show_painode();
|
||||
free_painode();
|
||||
return ch;
|
||||
}
|
||||
80
cpumf/man/lspai.8
Normal file
80
cpumf/man/lspai.8
Normal file
@@ -0,0 +1,80 @@
|
||||
.\" lspai.8
|
||||
.\"
|
||||
.\"
|
||||
.\" Copyright IBM Corp. 2021
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\" ----------------------------------------------------------------------
|
||||
.ds c \fBlspai\fP
|
||||
.
|
||||
.TH \*c "8" "August 2023" "s390-tools" "CPU-MF management programs"
|
||||
.
|
||||
.SH NAME
|
||||
\*c \- list Processor Activity Instrumentation (PAI) counters
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
\*c
|
||||
.RB [ \-n ]
|
||||
.RB [ \-t
|
||||
.IR "\ TYPE" ]
|
||||
.br
|
||||
\*c
|
||||
.BR \-h | \-\-help
|
||||
.br
|
||||
\*c
|
||||
.BR \-v | \-\-version
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
\*c displays the Processor Activity Instrumentation (PAI) counters
|
||||
for Linux on IBM Z.
|
||||
The output is a human-readable list of available PAI counter
|
||||
names and numbers.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Displays help information, then exits.
|
||||
.
|
||||
.TP
|
||||
.BR \-v ", " \-\-version
|
||||
Displays version information, then exits.
|
||||
.
|
||||
.TP
|
||||
.BR \-t ", " \-\-type "\ TYPE"
|
||||
Specifies the PAI counter set to list.
|
||||
Valid counter set values are
|
||||
.I crypto
|
||||
and
|
||||
.IR nnpa .
|
||||
By default, the command lists all available PAI counter sets.
|
||||
NNPA refers to the Neural Network Processing Assist facility counter set.
|
||||
Crypto refers to the Cryptografic Processing Assist facility counter set.
|
||||
.
|
||||
.TP
|
||||
.BR \-n ", " \-\-numeric
|
||||
Shows the PAI counter sets sorted by counter number.
|
||||
Default sort order is PAI counter name.
|
||||
.
|
||||
.SH "EXAMPLE"
|
||||
The \*c invocation lists all PAI Neural Network Processing Assist Facility
|
||||
(NNPA) counters in numeric order:
|
||||
.nf
|
||||
# lspai -t nnpa -n
|
||||
RAW NAME DESCRIPTION
|
||||
13:6144 NNPA_ALL Counter 0 / PAI NNPA counter set
|
||||
13:6145 NNPA_ADD Counter 1 / PAI NNPA counter set
|
||||
13:6146 NNPA_SUB Counter 2 / PAI NNPA counter set
|
||||
13:6147 NNPA_MUL Counter 3 / PAI NNPA counter set
|
||||
\&...
|
||||
.fi
|
||||
The first column shows the raw event number suitable for
|
||||
.IR perf "(8)"
|
||||
raw event specification.
|
||||
The second column shows the PAI NNPA counter name,
|
||||
suitable for
|
||||
.IR perf "(8)"
|
||||
event specification by name.
|
||||
The third gives a short explanation, if available.
|
||||
.SH "SEE ALSO"
|
||||
.BR pai (8)
|
||||
.BR lscpumf (8)
|
||||
@@ -18,6 +18,8 @@
|
||||
.IR size ]
|
||||
.RB [ \-i | \-\-interval
|
||||
.IR ms ]
|
||||
.RB [ \-R | \-\-realtime
|
||||
.IR prio ]
|
||||
.BR \-c | \-\-crypto [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
|
||||
.br
|
||||
\*c
|
||||
@@ -25,6 +27,8 @@
|
||||
.IR size ]
|
||||
.RB [ \-i | \-\-interval
|
||||
.IR ms ]
|
||||
.RB [ \-R | \-\-realtime
|
||||
.IR prio ]
|
||||
.BR \-n | \-\-nnpa [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
|
||||
.br
|
||||
\*c
|
||||
@@ -191,6 +195,14 @@ The ring buffer is created with the
|
||||
.IR mmap (2)
|
||||
system call.
|
||||
.
|
||||
.TP
|
||||
.BR \-R ", " \-\-realtime "\ prio"
|
||||
Collect data using the RT SCHED_FIFO priority specified by
|
||||
.BR prio .
|
||||
Valid values are integers in the range 1 (low) to 99 (high).
|
||||
Use this option when gathering data from multiple CPUs
|
||||
to prevent data loss.
|
||||
.
|
||||
.SH ARGUMENT
|
||||
The command line options determine how command line
|
||||
arguments are interpreted.
|
||||
|
||||
21
cpumf/pai.c
21
cpumf/pai.c
@@ -944,6 +944,11 @@ static struct util_opt opt_vec[] = {
|
||||
.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",
|
||||
@@ -1007,6 +1012,19 @@ static unsigned long check_mapsize(unsigned long n)
|
||||
return cnt == 1 ? n : 0;
|
||||
}
|
||||
|
||||
static void setprio(const char *prio)
|
||||
{
|
||||
struct sched_param param;
|
||||
char *endstr;
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.sched_priority = strtoul(prio, &endstr, 0);
|
||||
if (*endstr)
|
||||
errno = EINVAL;
|
||||
if (*endstr || sched_setscheduler(0, SCHED_FIFO, ¶m))
|
||||
err(EXIT_FAILURE, "Could not set realtime priority");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool crypto_record = false, report = false;
|
||||
@@ -1061,6 +1079,9 @@ int main(int argc, char **argv)
|
||||
record_cpus_nnpa(optarg);
|
||||
nnpa_record = true;
|
||||
break;
|
||||
case 'R':
|
||||
setprio(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
report = true;
|
||||
break;
|
||||
|
||||
@@ -15,13 +15,13 @@ dasdfmt \- formatting of DASD (ECKD) disk drives.
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it
|
||||
for usage with Linux for S/390.
|
||||
for usage with Linux for S/390.
|
||||
The \fIdevice\fR is the node of the device (e.g. '/dev/dasda').
|
||||
Any device node created by udev for kernel 2.6 can be used
|
||||
Any device node created by udev for kernel 2.6 can be used
|
||||
(e.g. '/dev/dasd/0.0.b100/disc').
|
||||
.br
|
||||
|
||||
\fBWARNING\fR: Careless usage of \fBdasdfmt\fR can result in
|
||||
\fBWARNING\fR: Careless usage of \fBdasdfmt\fR can result in
|
||||
\fBLOSS OF DATA\fR.
|
||||
|
||||
.SH OPTIONS
|
||||
@@ -31,7 +31,7 @@ Print usage and exit.
|
||||
|
||||
.TP
|
||||
\fB-t\fR or \fB--test\fR
|
||||
Disables any modification of the disk drive.
|
||||
Disables any modification of the disk drive.
|
||||
.br
|
||||
\fBdasdfmt\fR just prints
|
||||
out, what it \fBwould\fR do.
|
||||
@@ -41,7 +41,7 @@ out, what it \fBwould\fR do.
|
||||
Increases verbosity.
|
||||
|
||||
.TP
|
||||
\fB-y\fR
|
||||
\fB-y\fR
|
||||
Start formatting without further user-confirmation.
|
||||
|
||||
.TP
|
||||
@@ -59,7 +59,7 @@ Omit the writing of a disk label after formatting.
|
||||
.br
|
||||
This makes only sense for the 'ldl' disk layout.
|
||||
.br
|
||||
The '-L' option has to be specified after the '-d ldl' option.
|
||||
The '-L' option has to be specified after the '-d ldl' option.
|
||||
.br
|
||||
|
||||
e.g. dasdfmt -d ldl -L /dev/...
|
||||
@@ -84,13 +84,13 @@ Formats the device with compatible disk layout or linux disk layout.
|
||||
\fIlayout\fR is either \fIcdl\fR for the compatible disk layout
|
||||
(default) or \fIldl\fR for the linux disk layout.
|
||||
.br
|
||||
Compatible disk layout means a special handling of the
|
||||
first two tracks of the volume. This enables other S/390 or zSeries
|
||||
Compatible disk layout means a special handling of the
|
||||
first two tracks of the volume. This enables other S/390 or zSeries
|
||||
operating systems to access this device (e.g. for backup purposes).
|
||||
|
||||
.TP
|
||||
\fB-p\fR or \fB--progressbar\fR
|
||||
Print a progress bar while formatting.
|
||||
Print a progress bar while formatting.
|
||||
Do not use this option if you are using a 3270 console,
|
||||
running in background or redirecting the output to a file.
|
||||
|
||||
@@ -164,30 +164,30 @@ and always be a power of two. The recommended blocksize is 4096 bytes.
|
||||
|
||||
.TP
|
||||
\fB-l\fR \fIvolser\fR or \fB--label\fR=\fIvolser\fR
|
||||
Specify the volume serial number or volume identifier to be written
|
||||
to disk after formatting. If no label is specified, a sensible default
|
||||
is used. \fIvolser\fR is interpreted as ASCII string and is automatically
|
||||
Specify the volume serial number or volume identifier to be written
|
||||
to disk after formatting. If no label is specified, a sensible default
|
||||
is used. \fIvolser\fR is interpreted as ASCII string and is automatically
|
||||
converted to uppercase and then to EBCDIC.
|
||||
.br
|
||||
|
||||
e.g. -l LNX001 or --label=DASD01
|
||||
.br
|
||||
|
||||
The \fIvolser\fR identifies by serial number the volume. A volume serial
|
||||
The \fIvolser\fR identifies by serial number the volume. A volume serial
|
||||
number is 1 through 6 alphanumeric or one of the following special
|
||||
characters: $, #, @, %. Enclose a serial number that contains special
|
||||
characters in apostrophes. If the number is shorter than six
|
||||
characters: $, #, @, %. Enclose a serial number that contains special
|
||||
characters in apostrophes. If the number is shorter than six
|
||||
characters, it is padded with trailing blanks.
|
||||
.br
|
||||
.br
|
||||
|
||||
Do not code a volume serial number as SCRTCH, PRIVAT, or Lnnnnn (L with
|
||||
five numbers); these are used in OS/390 messages to ask the operator to
|
||||
mount a volume. Do not code a volume serial number as MIGRAT, which is
|
||||
used by the OS/390 Hierarchical Storage Manager DFSMShsm for migrated
|
||||
Do not code a volume serial number as SCRTCH, PRIVAT, or Lnnnnn (L with
|
||||
five numbers); these are used in OS/390 messages to ask the operator to
|
||||
mount a volume. Do not code a volume serial number as MIGRAT, which is
|
||||
used by the OS/390 Hierarchical Storage Manager DFSMShsm for migrated
|
||||
data sets.
|
||||
.br
|
||||
|
||||
NOTE: Try to avoid using special characters in the volume serial. This may cause problems accessing a disk by volser.
|
||||
NOTE: Try to avoid using special characters in the volume serial. This may cause problems accessing a disk by volser.
|
||||
.br
|
||||
In case you really have to use special characters, make sure you are using quotes. In addition there is a special handling for the '$' sign. Please specify it using '\\$' if necessary.
|
||||
.br
|
||||
@@ -197,9 +197,8 @@ e.g. -l 'a@b\\$c#' to get A@B$C#
|
||||
|
||||
.TP
|
||||
\fB-k\fR or \fB--keep_volser\fR
|
||||
Keeps the Volume Serial Number, when writing the Volume Label. This is
|
||||
useful, if the Serial Number has been written with a VM Tool and should not
|
||||
be overwritten.
|
||||
Keeps the Volume Serial Number when writing the Volume Label. This is useful if
|
||||
the volume already has a Serial Number that should not be overwritten.
|
||||
.br
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
@@ -19,10 +19,10 @@ help:
|
||||
.br
|
||||
\fBfdasd\fR {-h|-v}
|
||||
.SH DESCRIPTION
|
||||
\fBfdasd\fR writes a partition table to a cdl (compatible disk layout)
|
||||
\fBfdasd\fR writes a partition table to a cdl (compatible disk layout)
|
||||
formatted DASD, in the form of
|
||||
a VTOC (volume table of contents) for usage with Linux for S/390
|
||||
or zSeries. If fdasd detects a valid \fBVOL1\fR volume label, it
|
||||
or zSeries. If fdasd detects a valid \fBVOL1\fR volume label, it
|
||||
will use it, otherwise it asks to write a new one.
|
||||
.br
|
||||
|
||||
@@ -34,51 +34,51 @@ will use it, otherwise it asks to write a new one.
|
||||
Print usage information, then exit.
|
||||
|
||||
.TP
|
||||
\fB-v\fR or \fB--version\fR
|
||||
\fB-v\fR or \fB--version\fR
|
||||
Print version information, then exit.
|
||||
|
||||
.TP
|
||||
\fB-s\fR or \fB--silent\fR
|
||||
\fB-s\fR or \fB--silent\fR
|
||||
Suppress messages in non-interactive mode.
|
||||
|
||||
.TP
|
||||
\fB-r\fR or \fB--verbose\fR
|
||||
\fB-r\fR or \fB--verbose\fR
|
||||
Provide more verbose output.
|
||||
|
||||
.TP
|
||||
\fB-a\fR or \fB--auto\fR
|
||||
Automatically create a partition using the entire disk in non-interactive
|
||||
\fB-a\fR or \fB--auto\fR
|
||||
Automatically create a partition using the entire disk in non-interactive
|
||||
mode.
|
||||
|
||||
.TP
|
||||
\fB-k\fR or \fB--keep_volser\fR
|
||||
Keeps the volume serial when writing the volume label.
|
||||
Keeps the Volume Serial Number when writing the Volume Label.
|
||||
.br
|
||||
This is useful, if the volume serial has been written before and should not
|
||||
be overwritten. This option is only applicable in non-interactive mode.
|
||||
This is useful if the volume already has a Serial Number that should not be
|
||||
overwritten. This option is only applicable in non-interactive mode.
|
||||
|
||||
.TP
|
||||
\fB-l\fR \fIvolser\fR or \fB--label\fR \fIvolser\fR
|
||||
Specify the volume serial.
|
||||
.br
|
||||
\fIvolser\fR is interpreted as ASCII string and is automatically converted to
|
||||
\fIvolser\fR is interpreted as ASCII string and is automatically converted to
|
||||
uppercase, padded with blanks and finally converted to EBCDIC to be written
|
||||
to disk. This option is only applicable in non-interactive mode.
|
||||
.br
|
||||
|
||||
Do not use the following reserved volume serial: SCRTCH, PRIVAT, MIGRAT,
|
||||
or Lnnnnn (L with five digit number); These are used as keywords by
|
||||
Do not use the following reserved volume serial: SCRTCH, PRIVAT, MIGRAT,
|
||||
or Lnnnnn (L with five digit number); These are used as keywords by
|
||||
other operating systems (OS/390).
|
||||
.br
|
||||
|
||||
A volume serial is 1 through 6 alphanumeric characters or one of the
|
||||
following special characters: $, #, @, %. All other characters are simply
|
||||
ignored.
|
||||
A volume serial is 1 through 6 alphanumeric characters or one of the
|
||||
following special characters: $, #, @, %. All other characters are simply
|
||||
ignored.
|
||||
.br
|
||||
Try to avoid using special characters in the volume serial.
|
||||
This may cause problems accessing a disk by volser.
|
||||
In case you really have to use special characters, make sure you are using
|
||||
quotes. In addition there is a special handling for the '$' sign.
|
||||
Try to avoid using special characters in the volume serial.
|
||||
This may cause problems accessing a disk by volser.
|
||||
In case you really have to use special characters, make sure you are using
|
||||
quotes. In addition there is a special handling for the '$' sign.
|
||||
Please specify it using '\\$' if necessary.
|
||||
.br
|
||||
|
||||
@@ -124,14 +124,14 @@ partitions that use the entire disk:
|
||||
.br
|
||||
|
||||
.TP
|
||||
\fB-i\fR or \fB--volser\fR
|
||||
\fB-i\fR or \fB--volser\fR
|
||||
Print the volume serial, then exit.
|
||||
|
||||
.TP
|
||||
\fB-p\fR or \fB--table\fR
|
||||
Print partition table, then exit.
|
||||
\fB-p\fR or \fB--table\fR
|
||||
Print partition table, then exit.
|
||||
.br
|
||||
In combination with the -s option fdasd will display a short version of the
|
||||
In combination with the -s option fdasd will display a short version of the
|
||||
partition table.
|
||||
|
||||
.TP
|
||||
@@ -179,7 +179,7 @@ In case your are not using the device file system, please specify:
|
||||
.br
|
||||
|
||||
where \fIx\fR is one or more lowercase letter(s) or any other device
|
||||
node specification configured by udev for kernel 2.6 or higher.
|
||||
node specification configured by udev for kernel 2.6 or higher.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR dasdfmt (8)
|
||||
|
||||
@@ -79,6 +79,7 @@ stage3b.elf: head.o $(ZIPL_OBJS)
|
||||
|
||||
%.bin.debug: %.elf
|
||||
$(OBJCOPY) --only-keep-debug $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
@@ -61,13 +61,17 @@ void __noreturn start(void)
|
||||
if (cmdline->size > get_kernel_cmdline_size())
|
||||
panic(EINTERNAL, "Command line is too large\n");
|
||||
|
||||
/* move the kernel cmdline */
|
||||
memmove((void *)COMMAND_LINE,
|
||||
(void *)cmdline->src,
|
||||
cmdline->size);
|
||||
if (cmdline->size > 0) {
|
||||
/* make sure the cmdline is a null-terminated string */
|
||||
if (((char *)cmdline->src)[cmdline->size - 1] != '\0')
|
||||
panic(EINTERNAL, "Command line needs to be null-terminated\n");
|
||||
|
||||
/* move the kernel cmdline */
|
||||
memmove((void *)COMMAND_LINE, (void *)cmdline->src, cmdline->size);
|
||||
}
|
||||
/* the initrd does not need to be moved */
|
||||
|
||||
if (initrd->size != 0) {
|
||||
if (initrd->size > 0) {
|
||||
/* copy initrd start address and size into new kernel space */
|
||||
*(unsigned long long *)INITRD_START = initrd->src;
|
||||
*(unsigned long long *)INITRD_SIZE = initrd->size;
|
||||
|
||||
@@ -684,7 +684,26 @@ gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err)
|
||||
{
|
||||
g_autoptr(PvComponent) comp = NULL;
|
||||
|
||||
comp = pv_component_new_file(arg->type, arg->path, err);
|
||||
switch (arg->type) {
|
||||
case PV_COMP_TYPE_INITRD:
|
||||
case PV_COMP_TYPE_KERNEL:
|
||||
case PV_COMP_TYPE_STAGE3B:
|
||||
comp = pv_component_new_file(arg->type, arg->path, err);
|
||||
break;
|
||||
case PV_COMP_TYPE_CMDLINE: {
|
||||
g_autoptr(PvBuffer) buf = NULL;
|
||||
g_autofree char *data = NULL;
|
||||
gsize length;
|
||||
|
||||
if (!g_file_get_contents(arg->path, &data, &length, err))
|
||||
return -1;
|
||||
|
||||
/* Add one for the null terminator */
|
||||
buf = pv_buffer_take(g_steal_pointer(&data), length + 1);
|
||||
comp = pv_component_new_buf(arg->type, buf, err);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (!comp)
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -26,6 +26,15 @@ PvBuffer *pv_buffer_alloc(gsize size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
PvBuffer *pv_buffer_take(char *data, gsize size)
|
||||
{
|
||||
PvBuffer *ret = g_new0(PvBuffer, 1);
|
||||
|
||||
ret->data = data;
|
||||
ret->size = size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
PvBuffer *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned)
|
||||
{
|
||||
PvBuffer *ret;
|
||||
|
||||
@@ -21,6 +21,10 @@ typedef struct PvBuffer {
|
||||
} PvBuffer;
|
||||
|
||||
PvBuffer *pv_buffer_alloc(gsize size);
|
||||
/* After this call @data belongs to the PvBuffer and must no longer be modified
|
||||
* by the caller.
|
||||
*/
|
||||
PvBuffer *pv_buffer_take(char *data, gsize size);
|
||||
void pv_buffer_free(PvBuffer *buf);
|
||||
void pv_buffer_clear(PvBuffer **buf);
|
||||
gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err);
|
||||
|
||||
@@ -404,11 +404,11 @@ s64 ht_calculate_smt_util(u64 core_us, u64 thr_us, u64 mgm_us, int thread_per_co
|
||||
s64 component1, component2, smt_us;
|
||||
double smt_factor = g.o.smt_factor;
|
||||
|
||||
component1 = G0(thread_per_core * core_us - thr_us);
|
||||
component1 = thread_per_core * core_us - thr_us;
|
||||
if (thread_per_core > 1)
|
||||
component1 /= smt_factor;
|
||||
component2 = G0(thr_us - core_us);
|
||||
smt_us = component1 + component2 + mgm_us;
|
||||
component2 = thr_us - core_us;
|
||||
smt_us = G0(component1 + component2 + mgm_us);
|
||||
|
||||
return smt_us;
|
||||
}
|
||||
|
||||
@@ -22,11 +22,19 @@
|
||||
#define STAGE2_DESC _AC(0x78, UL)
|
||||
#define STAGE2_ENTRY _AC(0x2018, UL)
|
||||
#define STAGE2_HEAP_ADDRESS _AC(0x6000, UL)
|
||||
#define ECKD2DUMP_SV_HEAP_ADDRESS _AC(0xb000, UL)
|
||||
#define STAGE2_HEAP_SIZE _AC(0x3000, UL)
|
||||
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
|
||||
#define STAGE2_STACK_SIZE _AC(0x1c00, UL)
|
||||
#define ECKD2DUMP_SV_STACK_ADDRESS _AC(0xe000, UL)
|
||||
#define ECKD2DUMP_SV_STACK_SIZE _AC(0x2000, UL)
|
||||
#define STAGE2_MAX_SIZE _AC(0x3000, UL)
|
||||
|
||||
#define STAGE2_DUMPER_SIZE_V1 _AC(0x1000, UL)
|
||||
#define STAGE2_DUMPER_SIZE_V2 _AC(0x2000, UL)
|
||||
#define STAGE2_DUMPER_SIZE_V3 _AC(0x3000, UL)
|
||||
#define STAGE2_DUMPER_SIZE_ZLIB _AC(0x8000, UL)
|
||||
|
||||
#define STAGE3_ENTRY _AC(0xa000, UL)
|
||||
|
||||
#define STAGE2_LOAD_ADDRESS _AC(0x2000, UL)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
||||
|
||||
/* Facilities */
|
||||
#define DFLTCC_FACILITY _AC(151, U)
|
||||
#define UNPACK_FACILITY _AC(161, U)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
134
include/dump/s390_dump.h
Normal file
134
include/dump/s390_dump.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* s390 related definitions and functions.
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef S390_DUMP_H
|
||||
#define S390_DUMP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/page.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
/*
|
||||
* S390 dump format defines
|
||||
*/
|
||||
#define DF_S390_MAGIC 0xa8190173618f23fdULL
|
||||
#define DF_S390_MAGIC_EXT 0xa8190173618f23feULL
|
||||
#define DF_S390_HDR_SIZE 0x1000
|
||||
#define DF_S390_EM_SIZE 16
|
||||
#define DF_S390_EM_MAGIC 0x44554d505f454e44ULL
|
||||
#define DF_S390_EM_STR "DUMP_END"
|
||||
#define DF_S390_CPU_MAX 512
|
||||
#define DF_S390_MAGIC_BLK_ECKD 3
|
||||
|
||||
/*
|
||||
* Architecture of dumped system
|
||||
*/
|
||||
enum df_s390_arch {
|
||||
DF_S390_ARCH_32 = 1,
|
||||
DF_S390_ARCH_64 = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* zipl parameters passed at tail of dump tools
|
||||
*/
|
||||
struct stage2dump_parm_tail {
|
||||
char reserved[6];
|
||||
uint8_t no_compress;
|
||||
uint8_t mvdump_force;
|
||||
uint64_t mem_upper_limit;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* s390 dump header format
|
||||
*/
|
||||
struct df_s390_hdr {
|
||||
uint64_t magic; /* 0x000 */
|
||||
uint32_t version; /* 0x008 */
|
||||
uint32_t hdr_size; /* 0x00c */
|
||||
uint32_t dump_level; /* 0x010 */
|
||||
uint32_t page_size; /* 0x014 */
|
||||
uint64_t mem_size; /* 0x018 */
|
||||
uint64_t mem_start; /* 0x020 */
|
||||
uint64_t mem_end; /* 0x028 */
|
||||
uint32_t num_pages; /* 0x030 */
|
||||
uint32_t pad; /* 0x034 */
|
||||
uint64_t tod; /* 0x038 */
|
||||
uint64_t cpu_id; /* 0x040 */
|
||||
uint32_t arch; /* 0x048 */
|
||||
uint32_t volnr; /* 0x04c */
|
||||
uint32_t build_arch; /* 0x050 */
|
||||
uint64_t mem_size_real; /* 0x054 */
|
||||
uint8_t mvdump; /* 0x05c */
|
||||
uint16_t cpu_cnt; /* 0x05d */
|
||||
uint16_t real_cpu_cnt; /* 0x05f */
|
||||
uint8_t zlib_version_s390; /* 0x061 */
|
||||
uint32_t zlib_entry_size; /* 0x062 */
|
||||
uint8_t end_pad1[0x200 - 0x066]; /* 0x066 */
|
||||
uint64_t mvdump_sign; /* 0x200 */
|
||||
uint64_t mvdump_zipl_time; /* 0x208 */
|
||||
uint8_t end_pad2[0x800 - 0x210]; /* 0x210 */
|
||||
uint32_t lc_vec[DF_S390_CPU_MAX]; /* 0x800 */
|
||||
} __packed __aligned(16);
|
||||
|
||||
/*
|
||||
* End marker: Should be at the end of every valid s390 crash dump
|
||||
*/
|
||||
struct df_s390_em {
|
||||
union {
|
||||
uint64_t magic;
|
||||
char str[8];
|
||||
};
|
||||
uint64_t tod;
|
||||
} __packed __aligned(16);
|
||||
|
||||
/*
|
||||
* Dump segment header
|
||||
*/
|
||||
struct df_s390_dump_segm_hdr {
|
||||
union {
|
||||
struct {
|
||||
uint64_t start; /* 0x000 */
|
||||
uint64_t len; /* 0x008 */
|
||||
uint64_t stop_marker; /* 0x010 */
|
||||
/* Size in blocks of compressed dump segment written to disk */
|
||||
uint32_t size_on_disk; /* 0x018 */
|
||||
uint8_t reserved_pad[0x30 - 0x1c]; /* 0x01c */
|
||||
/*
|
||||
* Number of compressed entries in this dump segment (up to
|
||||
* 1011 entries)
|
||||
*/
|
||||
uint32_t entry_count; /* 0x030 */
|
||||
/*
|
||||
* Offsets in blocks to compressed entries written to disk
|
||||
* from the start of the dump segment.
|
||||
* High-order bit is set if the entry has been written
|
||||
* uncompressed.
|
||||
*/
|
||||
uint32_t entry_offset[]; /* 0x034 */
|
||||
} __packed;
|
||||
uint8_t padding[PAGE_SIZE];
|
||||
};
|
||||
};
|
||||
|
||||
/* Data compression granularity (size of input data chunk for zlib deflate) */
|
||||
#define DUMP_SEGM_ZLIB_ENTSIZE (1 * MIB)
|
||||
/* Maximum number of compressed entries in one dump segment */
|
||||
#define DUMP_SEGM_ZLIB_MAXENTS ((sizeof(struct df_s390_dump_segm_hdr) \
|
||||
- offsetof(struct df_s390_dump_segm_hdr, entry_offset)) \
|
||||
/ sizeof(uint32_t))
|
||||
/*
|
||||
* Maximum length of compressed dump segment considering the size of
|
||||
* a single input chunk
|
||||
*/
|
||||
#define DUMP_SEGM_ZLIB_MAXLEN (DUMP_SEGM_ZLIB_MAXENTS * DUMP_SEGM_ZLIB_ENTSIZE)
|
||||
/* Bitmask to mark uncompressed chunks */
|
||||
#define DUMP_SEGM_ENTRY_UNCOMPRESSED 0x80000000
|
||||
|
||||
#endif /* S390_DUMP_H */
|
||||
@@ -89,6 +89,7 @@ void ap_list_remove_all(struct util_list *list);
|
||||
/* Lock Functions */
|
||||
int ap_get_lock(void);
|
||||
int ap_get_lock_callout(void);
|
||||
int ap_try_lock_callout(void);
|
||||
int ap_release_lock(void);
|
||||
int ap_release_lock_callout(void);
|
||||
|
||||
|
||||
@@ -23,4 +23,6 @@ int util_lockfile_parent_lock(char *lockfile, int retries);
|
||||
int util_lockfile_release(char *lockfile);
|
||||
int util_lockfile_parent_release(char *lockfile);
|
||||
|
||||
int util_lockfile_peek_owner(char *lockfile, int *pid);
|
||||
|
||||
#endif /** LIB_UTIL_LOCKFILE_H @} */
|
||||
|
||||
28
libap/ap.c
28
libap/ap.c
@@ -722,6 +722,34 @@ int ap_get_lock_callout(void)
|
||||
return util_lockfile_parent_lock(AP_LOCKFILE, AP_LOCK_RETRIES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to acquire the ap config lock using the Parent Process ID without
|
||||
* waiting/retries. Detect if the attempt was rejected because the lock is
|
||||
* already held by the Parent Process ID.
|
||||
*
|
||||
* @retval 0 Lock acquired on behalf of parent process
|
||||
* @retval 1 Lock not obtained, already held by parent
|
||||
* @retval != 0 Lock was not obtained, other error
|
||||
*/
|
||||
int ap_try_lock_callout(void)
|
||||
{
|
||||
int pid, ppid, rc;
|
||||
|
||||
if (util_lockfile_parent_lock(AP_LOCKFILE, 0)) {
|
||||
/* Lock is already held, let's peek at the owner */
|
||||
ppid = getppid();
|
||||
rc = util_lockfile_peek_owner(AP_LOCKFILE, &pid);
|
||||
if (rc || pid != ppid) {
|
||||
/* We didn't get the lock, unknown or other owner */
|
||||
return 2;
|
||||
}
|
||||
/* Signify that the lock is already held by the caller */
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the ap config lock
|
||||
*
|
||||
|
||||
@@ -55,7 +55,7 @@ check-dep-libekmfweb: detect-openssl-version.dep
|
||||
"detect-openssl-version.dep", \
|
||||
"openssl-devel version >= 1.1.1", \
|
||||
"HAVE_OPENSSL=0", \
|
||||
-I. -lcrypto -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||
-I. `$(PKG_CONFIG) --cflags --libs libcrypto` -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||
$(call check_dep, \
|
||||
"libekmfweb", \
|
||||
"json-c/json.h", \
|
||||
@@ -66,7 +66,7 @@ check-dep-libekmfweb: detect-openssl-version.dep
|
||||
"curl/curl.h", \
|
||||
"libcurl-devel", \
|
||||
"HAVE_LIBCURL=0" \
|
||||
`$(CURL_CONFIG) --cflags` `$(CURL_CONFIG) --libs`)
|
||||
`$(PKG_CONFIG) --cflags --libs libcurl`)
|
||||
$(CURL_CONFIG) --ssl-backends | grep OpenSSL >/dev/null 2>&1 || { echo "Error: libcurl is not built with the OpenSSL backend"; exit 1; }
|
||||
touch check-dep-libekmfweb
|
||||
|
||||
@@ -85,8 +85,8 @@ ekmfweb.o: check-dep-libekmfweb ekmfweb.c utilities.h cca.h $(rootdir)include/ek
|
||||
utilities.o: check-dep-libekmfweb utilities.c utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||
cca.o: check-dep-libekmfweb cca.c cca.h utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||
|
||||
libekmfweb.so.$(VERSION): ALL_CFLAGS += -fPIC `$(CURL_CONFIG) --cflags`
|
||||
libekmfweb.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl `$(CURL_CONFIG) --libs` -ldl
|
||||
libekmfweb.so.$(VERSION): ALL_CFLAGS += -fPIC `$(PKG_CONFIG) --cflags json-c libcurl libcrypto libssl`
|
||||
libekmfweb.so.$(VERSION): LDLIBS = `$(PKG_CONFIG) --libs json-c libcurl libcrypto libssl` -ldl
|
||||
libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb.map \
|
||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
|
||||
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o $(libs)
|
||||
|
||||
@@ -51,7 +51,6 @@ detect-openssl-version.dep:
|
||||
mv $(TMPFILE) $@
|
||||
|
||||
CURL_CONFIG ?= curl-config
|
||||
XML2_CONFIG ?= xml2-config
|
||||
|
||||
check-dep-libkmipclient: detect-openssl-version.dep
|
||||
$(call check_dep, \
|
||||
@@ -59,7 +58,7 @@ check-dep-libkmipclient: detect-openssl-version.dep
|
||||
"detect-openssl-version.dep", \
|
||||
"openssl-devel version >= 1.1.1", \
|
||||
"HAVE_OPENSSL=0", \
|
||||
-I. -lcrypto -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||
-I. `$(PKG_CONFIG) --cflags --libs libcrypto` -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||
$(call check_dep, \
|
||||
"libkmipclient", \
|
||||
"json-c/json.h", \
|
||||
@@ -70,13 +69,13 @@ check-dep-libkmipclient: detect-openssl-version.dep
|
||||
"libxml/tree.h", \
|
||||
"libxml2-devel", \
|
||||
"HAVE_LIBXML2=0", \
|
||||
`$(XML2_CONFIG) --cflags` `$(XML2_CONFIG) --libs`)
|
||||
`$(PKG_CONFIG) --cflags --libs libxml-2.0`)
|
||||
$(call check_dep, \
|
||||
"libkmipclient", \
|
||||
"curl/curl.h", \
|
||||
"libcurl-devel", \
|
||||
"HAVE_LIBCURL=0" \
|
||||
`$(CURL_CONFIG) --cflags` `$(CURL_CONFIG) --libs`)
|
||||
`$(PKG_CONFIG) --cflags --libs libcurl`)
|
||||
$(CURL_CONFIG) --ssl-backends | grep OpenSSL >/dev/null 2>&1 || { echo "Error: libcurl is not built with the OpenSSL backend"; exit 1; }
|
||||
touch check-dep-libkmipclient
|
||||
|
||||
@@ -107,8 +106,8 @@ tls.o: check-dep-libkmipclient tls.c kmip.h utils.h $(rootdir)include/kmipclient
|
||||
names.o: check-dep-libkmipclient names.c names.h utils.h $(rootdir)include/kmipclient/kmipclient.h
|
||||
utils.o: check-dep-libkmipclient utils.c names.h utils.h $(rootdir)include/kmipclient/kmipclient.h
|
||||
|
||||
libkmipclient.so.$(VERSION): ALL_CFLAGS += -fPIC `$(XML2_CONFIG) --cflags` `$(CURL_CONFIG) --cflags`
|
||||
libkmipclient.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl `$(XML2_CONFIG) --libs` `$(CURL_CONFIG) --libs`
|
||||
libkmipclient.so.$(VERSION): ALL_CFLAGS += -fPIC `$(PKG_CONFIG) --cflags json-c libcrypto libssl libxml-2.0 libcurl`
|
||||
libkmipclient.so.$(VERSION): LDLIBS = `$(PKG_CONFIG) --libs json-c libcrypto libssl libxml-2.0 libcurl`
|
||||
libkmipclient.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libkmipclient.map \
|
||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libkmipclient.so.$(VERM)
|
||||
libkmipclient.so.$(VERSION): kmip.o request.o response.o attribute.o key.o ttlv.o json.o \
|
||||
|
||||
@@ -311,13 +311,13 @@ int util_file_read_i(int *val, int base, const char *fmt, ...)
|
||||
return -1;
|
||||
switch (base) {
|
||||
case 8:
|
||||
count = sscanf(buf, "%do", val);
|
||||
count = sscanf(buf, "%o", val);
|
||||
break;
|
||||
case 10:
|
||||
count = sscanf(buf, "%dd", val);
|
||||
count = sscanf(buf, "%d", val);
|
||||
break;
|
||||
case 16:
|
||||
count = sscanf(buf, "%dx", val);
|
||||
count = sscanf(buf, "%x", val);
|
||||
break;
|
||||
default:
|
||||
util_panic("Invalid base: %d\n", base);
|
||||
@@ -425,13 +425,13 @@ int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...)
|
||||
return -1;
|
||||
switch (base) {
|
||||
case 8:
|
||||
count = sscanf(buf, "%uo", val);
|
||||
count = sscanf(buf, "%o", val);
|
||||
break;
|
||||
case 10:
|
||||
count = sscanf(buf, "%uu", val);
|
||||
count = sscanf(buf, "%u", val);
|
||||
break;
|
||||
case 16:
|
||||
count = sscanf(buf, "%ux", val);
|
||||
count = sscanf(buf, "%x", val);
|
||||
break;
|
||||
default:
|
||||
util_panic("Invalid base: %d\n", base);
|
||||
|
||||
@@ -299,3 +299,35 @@ int util_lockfile_parent_release(char *lockfile)
|
||||
{
|
||||
return do_lockfile_release(lockfile, getppid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pid that owns the specified lockfile.
|
||||
*
|
||||
* @param[in] lockfile Path to the lock file
|
||||
* @param[in,out] pid Buffer to place owning pid
|
||||
*
|
||||
* @retval 0 pid provided in buffer
|
||||
* @retval !=0 Error, no pid provided
|
||||
*/
|
||||
int util_lockfile_peek_owner(char *lockfile, int *pid)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
int fd, len;
|
||||
|
||||
if (!lockfile || !pid)
|
||||
return UTIL_LOCKFILE_ERR;
|
||||
|
||||
/* Open lockfile, read the owning pid if it exists */
|
||||
fd = open(lockfile, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return UTIL_LOCKFILE_ERR;
|
||||
|
||||
len = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
if (len <= 0)
|
||||
return UTIL_LOCKFILE_ERR;
|
||||
buf[len] = 0;
|
||||
*pid = atoi(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/* we may use header_generic and header_simple_table from the util_funcs module */
|
||||
|
||||
config_require(util_funcs)
|
||||
config_require(util_funcs);
|
||||
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
3
rust/.gitignore
vendored
3
rust/.gitignore
vendored
@@ -9,6 +9,3 @@ target/
|
||||
# Generated during make build can be removed at any point
|
||||
.check-dep-pvtools
|
||||
.check-cargo
|
||||
|
||||
# Ignore lock files by default
|
||||
Cargo.lock
|
||||
|
||||
684
rust/pvsecret/Cargo.lock → rust/Cargo.lock
generated
684
rust/pvsecret/Cargo.lock → rust/Cargo.lock
generated
@@ -2,6 +2,30 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.3.2"
|
||||
@@ -57,24 +81,61 @@ version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "assert-json-diff"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
@@ -106,7 +167,7 @@ checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
"terminal_size",
|
||||
@@ -147,15 +208,15 @@ dependencies = [
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"socket2",
|
||||
"socket2 0.4.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.4.63+curl-8.1.2"
|
||||
version = "0.4.68+curl-8.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc"
|
||||
checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -163,9 +224,15 @@ dependencies = [
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"winapi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.1"
|
||||
@@ -187,6 +254,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
@@ -202,12 +275,152 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap 2.1.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
@@ -220,6 +433,64 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2 0.4.9",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
@@ -227,7 +498,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -259,6 +540,12 @@ version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.146"
|
||||
@@ -283,12 +570,85 @@ version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mockito"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8d3038e23466858569c2d30a537f691fa0d53b51626630ae08262943e3bbb8b"
|
||||
dependencies = [
|
||||
"assert-json-diff",
|
||||
"futures",
|
||||
"hyper",
|
||||
"log",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"similar",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
@@ -297,11 +657,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.54"
|
||||
version = "0.10.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019"
|
||||
checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@@ -329,9 +689,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.88"
|
||||
version = "0.9.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617"
|
||||
checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -350,12 +710,59 @@ dependencies = [
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.60"
|
||||
@@ -373,11 +780,14 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"clap",
|
||||
"curl",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"mockito",
|
||||
"openssl",
|
||||
"openssl_extensions",
|
||||
"serde",
|
||||
"serde_test",
|
||||
"thiserror",
|
||||
"zerocopy",
|
||||
]
|
||||
@@ -404,12 +814,86 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.20"
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
@@ -432,6 +916,12 @@ dependencies = [
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.164"
|
||||
@@ -452,19 +942,81 @@ dependencies = [
|
||||
"syn 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_test"
|
||||
version = "1.0.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.9"
|
||||
@@ -475,6 +1027,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
@@ -533,6 +1095,81 @@ dependencies = [
|
||||
"syn 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2 0.5.4",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.9"
|
||||
@@ -561,6 +1198,21 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
14
rust/Cargo.toml
Normal file
14
rust/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"pv",
|
||||
"pvsecret",
|
||||
"utils",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
@@ -15,16 +15,17 @@ ifneq (${HAVE_CARGO},0)
|
||||
|
||||
BUILD_TARGETS = $(CARGO_TARGETS)
|
||||
INSTALL_TARGETS := install-rust-tools install-man
|
||||
CARGO_TEST_TARGETS = $(addsuffix, _test, $(CARGO_TARGETS))
|
||||
CARGO_TEST_TARGETS = $(addsuffix .test, $(CARGO_TARGETS))
|
||||
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
ifneq (${HAVE_LIBCURL},0)
|
||||
PV_TARGETS := pvsecret
|
||||
|
||||
PV_BUILD_TARGETS = $(PV_TARGETS)
|
||||
CARGO_TEST_TARGETS += $(addsuffix, _test, $(PV_TARGETS)) pv
|
||||
PV_BUILD_TARGETS := $(PV_TARGETS)
|
||||
CARGO_TEST_TARGETS += $(addsuffix .test,pv $(PV_TARGETS))
|
||||
endif #LIBCURL
|
||||
endif #OPENSSL
|
||||
TEST_TARGETS := $(addsuffix _build,$(CARGO_TEST_TARGETS))
|
||||
endif #CARGO
|
||||
|
||||
BUILD_TARGETS += $(PV_BUILD_TARGETS)
|
||||
@@ -39,18 +40,15 @@ endif
|
||||
$(BUILD_TARGETS) rust-test: CC = $(CC_SILENT)
|
||||
$(BUILD_TARGETS) rust-test: AR = $(AR_SILENT)
|
||||
|
||||
$(CARGO_TARGETS): .check-cargo .no-cross-compile
|
||||
$(CARGO_BUILD) --manifest-path=$@/Cargo.toml $(ALL_CARGOFLAGS)
|
||||
.PHONY: $(CARGO_TARGETS)
|
||||
$(PV_TARGETS): .check-dep-pvtools
|
||||
$(PV_TARGETS) $(CARGO_TARGETS): .check-cargo .no-cross-compile
|
||||
$(CARGO_BUILD) --bin $@ $(ALL_CARGOFLAGS)
|
||||
.PHONY: $(PV_TARGETS) $(CARGO_TARGETS)
|
||||
|
||||
|
||||
$(CARGO_TEST_TARGETS): .check-cargo .no-cross-compile
|
||||
$(CARGO_TEST) --manifest-path=$@/Cargo.toml --all-features $(CARGOFLAGS)
|
||||
.PHONY: $(CARGO_TEST_TARGETS)
|
||||
|
||||
$(PV_TARGETS): .check-cargo .no-cross-compile .check-dep-pvtools
|
||||
$(CARGO_BUILD) --manifest-path=$@/Cargo.toml $(ALL_CARGOFLAGS)
|
||||
.PHONY: $(PV_TARGETS)
|
||||
$(TEST_TARGETS): ALL_CARGOFLAGS += --no-run
|
||||
$(CARGO_TEST_TARGETS) $(TEST_TARGETS): .check-cargo .no-cross-compile
|
||||
$(CARGO_TEST) --package $(basename $@) --all-features $(ALL_CARGOFLAGS)
|
||||
.PHONY: $(TEST_TARGETS) $(CARGO_TEST_TARGETS)
|
||||
|
||||
skip-build:
|
||||
echo " SKIP rust-tools due to unresolved dependencies"
|
||||
@@ -65,22 +63,17 @@ print-rust-targets:
|
||||
echo $(BUILD_TARGETS)
|
||||
|
||||
clean:
|
||||
$(foreach target,$(CARGO_TARGETS),\
|
||||
$(CARGO_CLEAN) --manifest-path=$(target)/Cargo.toml ${ALL_CARGOFLAGS} ;)
|
||||
$(foreach target,$(PV_TARGETS),\
|
||||
$(CARGO_CLEAN) --manifest-path=$(target)/Cargo.toml ${CARGOFLAGS} ;)
|
||||
$(CARGO_CLEAN) ${ALL_CARGOFLAGS}
|
||||
$(RM) -- .check-dep-pvtools .detect-openssl.dep.c .check-cargo
|
||||
|
||||
rust-test: .check-cargo .no-cross-compile
|
||||
$(foreach target,$(CARGO_TEST_TARGETS),\
|
||||
$(CARGO_TEST) --manifest-path=$(target)/Cargo.toml --all-features ${ALL_CARGOFLAGS} ;)
|
||||
rust-test: $(CARGO_TEST_TARGETS)
|
||||
|
||||
install-rust-tools: $(BUILD_TARGETS)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||
$(foreach target,$(CARGO_TARGETS),\
|
||||
$(INSTALL) $(target)/target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
||||
$(INSTALL) target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
||||
$(foreach target,$(PV_TARGETS),\
|
||||
$(INSTALL) $(target)/target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
||||
$(INSTALL) target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
||||
|
||||
install-man:
|
||||
$(foreach target,$(CARGO_TARGETS),\
|
||||
@@ -118,13 +111,13 @@ endif
|
||||
|
||||
.check-dep-pvtools: .detect-openssl.dep.c
|
||||
$(call check_dep, \
|
||||
"$(BIN_PROGRAM)", \
|
||||
"Rust-pv", \
|
||||
$^, \
|
||||
"openssl-devel / libssl-dev version >= 1.1.1", \
|
||||
"HAVE_OPENSSL=0", \
|
||||
"-I.")
|
||||
$(call check_dep, \
|
||||
"$(BIN_PROGRAM)", \
|
||||
"Rust-pv", \
|
||||
"curl/curl.h", \
|
||||
"libcurl-devel", \
|
||||
"HAVE_LIBCURL=0")
|
||||
|
||||
@@ -7,21 +7,21 @@ https://www.rust-lang.org/learn/get-started
|
||||
## Building rust code
|
||||
### s390-tools build system
|
||||
If `cargo` is installed a simple `make` should do the job. Note that,
|
||||
compiling rust programs take significaltly longer than C code. To closely
|
||||
monitor the prgress use `make V=1` By default release builds are made.
|
||||
compiling rust programs take significantly longer than C code. To closely
|
||||
monitor the progress use `make V=1` By default release builds are made.
|
||||
|
||||
With `make CARGOFLAGS=<flags>` one can pass additional flags to cargo.
|
||||
With `make HAVE_CARGO=0` one can turn of any compilation that requires cargo.
|
||||
With `make CARGO=<...>` one can set the cargo binary
|
||||
|
||||
### cargo
|
||||
If you need to run cargo directly, cd to each project you want to build and
|
||||
If you need to run cargo directly, `cd` to each project you want to build and
|
||||
issue your cargo commands. Do **NOT** forget to specify `--release` if you are
|
||||
building tools for a release. The s390-tools expect the environment variable
|
||||
`S390_TOOLS_RELEASE` to be present at build time. This is the version string the
|
||||
rust tools provide.
|
||||
|
||||
Tpp: You can use `make version` to get the version string.
|
||||
Tip: You can use `make version` to get the version string.
|
||||
|
||||
## Internal Libraries
|
||||
* __utils__ _Library for rust tools that bundles common stuff for the 390-tools_
|
||||
@@ -43,7 +43,7 @@ Exiting tools may be rewritten in Rust.
|
||||
|
||||
### What (third-party) crates can be used for s390-tools?
|
||||
A huge list of libraries are made available through Rusts' ecosystem and is one
|
||||
of many upsides. However, just like with Coding Style Guidlines, it is
|
||||
of many upsides. However, just like with Coding Style Guidelines, it is
|
||||
important to limit the usage of those libraries so that within a project,
|
||||
everyone is on the same page and that code written in Rust uses similar
|
||||
approaches. It makes it easier for code review and maintainability in general.
|
||||
@@ -81,11 +81,27 @@ is a start, but can change over time.
|
||||
Dependencies used by the crates listed above can be used, too.
|
||||
|
||||
### Add new tool
|
||||
To add a new tool issue `cargo new <TOOLNAME>` in the `rust` directory.
|
||||
To add a new tool issue `cargo new $TOOLNAME` in the `rust` directory.
|
||||
|
||||
Add the tool to the _s390-tools_ build system:
|
||||
```Makefile
|
||||
CARGO_TARGETS := TOOLNAME
|
||||
CARGO_TARGETS := $TOOLNAME
|
||||
```
|
||||
Add the library to the _s390-tools_ test list:
|
||||
```Makefile
|
||||
CARGO_TEST_TARGETS := $LIBNAME
|
||||
```
|
||||
|
||||
Add the tool/library to the cargo workspace:
|
||||
```toml
|
||||
[workspace]
|
||||
members = [
|
||||
"pv",
|
||||
"pvsecret",
|
||||
"$TOOLNAME",
|
||||
"$LIBNAME"
|
||||
"utils",
|
||||
]
|
||||
```
|
||||
|
||||
### Versions
|
||||
@@ -98,8 +114,8 @@ use utils::release_string;
|
||||
fn print_version() {
|
||||
println!(
|
||||
"{} version {}\nCopyright IBM Corp. 2023",
|
||||
env!("CARGO_PKG_NAME"), // collapes into the crates name
|
||||
release_string!() // this (very likely) collapes into a compile time constant
|
||||
env!("CARGO_PKG_NAME"), // collapses into the crates name
|
||||
release_string!() // this (very likely) collapses into a compile time constant
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,36 +1,32 @@
|
||||
[package]
|
||||
name = "pv"
|
||||
version = "0.9.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
log = { version = "0.4", features = ["std", "release_max_level_debug"] }
|
||||
thiserror = "1"
|
||||
libc = "0.2.49"
|
||||
log = { version = "0.4.6", features = ["std", "release_max_level_debug"] }
|
||||
thiserror = "1.0.33"
|
||||
zerocopy = "0.6"
|
||||
cfg-if = "1.0.0"
|
||||
|
||||
# dependencies for request feature
|
||||
clap = { version ="4", features = ["derive", "wrap_help"], optional = true }
|
||||
curl = { version ="0.4", optional = true }
|
||||
openssl = {version = "0.10", optional = true }
|
||||
curl = { version ="0.4.7", optional = true }
|
||||
openssl = {version = "0.10.49", optional = true }
|
||||
openssl_extensions = { path = "openssl_extensions", optional = true }
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
serde = { version = "1.0.139", features = ["derive"], optional = true }
|
||||
|
||||
# misc optional dependencies
|
||||
byteorder = {version = "1", optional = true }
|
||||
byteorder = {version = "1.3", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
mockito = {version = "0.31", default-features = false }
|
||||
mockito = {version = "1", default-features = false }
|
||||
serde_test = "1"
|
||||
lazy_static = "1"
|
||||
lazy_static = "1.1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
request = ["dep:openssl", "dep:curl", "dep:openssl_extensions", "dep:serde", "dep:clap"]
|
||||
uvsecret = ["dep:byteorder", "dep:serde"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = "abort" # release builds now do not clean up stack after panics. .1 Mb
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[package]
|
||||
name = "openssl_extensions"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
foreign-types = "0.3"
|
||||
libc = {version = "0.2", features = [ "extra_traits"] }
|
||||
log = { version = "0.4", features = ["std", "release_max_level_debug"] }
|
||||
openssl = "0.10"
|
||||
openssl-sys = "0.9"
|
||||
foreign-types = "0.3.1"
|
||||
libc = {version = "0.2.49", features = [ "extra_traits"] }
|
||||
log = { version = "0.4.6", features = ["std", "release_max_level_debug"] }
|
||||
openssl = "0.10.49"
|
||||
openssl-sys = "0.9.85"
|
||||
|
||||
@@ -205,7 +205,7 @@ mod tests {
|
||||
#[test]
|
||||
fn from_se_image_hdr() {
|
||||
let bin_hdr = get_test_asset!("exp/secure_guest.hdr");
|
||||
let hdr_tags = BootHdrTags::from_se_image(&mut Cursor::new(bin_hdr.clone())).unwrap();
|
||||
let hdr_tags = BootHdrTags::from_se_image(&mut Cursor::new(*bin_hdr)).unwrap();
|
||||
assert_eq!(hdr_tags, EXP_HDR);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ mod tests {
|
||||
));
|
||||
|
||||
// mess up magic
|
||||
let mut bin_hdr_copy = bin_hdr.clone();
|
||||
let mut bin_hdr_copy = *bin_hdr;
|
||||
bin_hdr_copy.swap(0, 1);
|
||||
assert!(matches!(
|
||||
BootHdrTags::from_se_image(&mut Cursor::new(bin_hdr_copy)),
|
||||
|
||||
@@ -315,7 +315,7 @@ mod tests {
|
||||
];
|
||||
|
||||
let res = encrypt_aes(
|
||||
&&SymKey::Aes256(aes_gcm_key.into()),
|
||||
&SymKey::Aes256(aes_gcm_key.into()),
|
||||
&aes_gcm_iv,
|
||||
&aes_gcm_plain,
|
||||
)
|
||||
|
||||
@@ -451,7 +451,7 @@ mod tests {
|
||||
let ks = vec![
|
||||
Keyslot::new(host_key.clone()),
|
||||
Keyslot::new(host_key.clone()),
|
||||
Keyslot::new(host_key.clone()),
|
||||
Keyslot::new(host_key),
|
||||
];
|
||||
let mut aad = Vec::<Aad>::new();
|
||||
ks.iter().for_each(|ks| aad.push(Aad::Ks(ks)));
|
||||
|
||||
@@ -34,8 +34,8 @@ impl Zeroize for Vec<u8> {
|
||||
// * Vec allocated at least capacity elements continuously
|
||||
// * dst points always to a valid location
|
||||
unsafe {
|
||||
std::ptr::write_volatile(dst, 0);
|
||||
dst = dst.add(1);
|
||||
std::ptr::write_volatile(dst, 0)
|
||||
}
|
||||
}
|
||||
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
@@ -105,7 +105,7 @@ mod test {
|
||||
0xef, 0xc7, 0x3c, 0x62,
|
||||
];
|
||||
let name = "association secret".to_string();
|
||||
let secret = GuestSecret::association("association secret", secret_value.clone()).unwrap();
|
||||
let secret = GuestSecret::association("association secret", secret_value).unwrap();
|
||||
let exp = GuestSecret::Association {
|
||||
name,
|
||||
id: exp_id,
|
||||
|
||||
@@ -117,7 +117,7 @@ impl Display for SecretEntry {
|
||||
writeln!(f, "{} {}:", self.index, stype_str(self.stype.get()))?;
|
||||
write!(f, " ")?;
|
||||
for b in self.id {
|
||||
write!(f, "{:02x}", b)?;
|
||||
write!(f, "{b:02x}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -484,20 +484,20 @@ 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(&vec!(ibm_crt.clone())).is_ok());
|
||||
assert!(super::get_ibm_z_sign_key(&[ibm_crt.clone()]).is_ok());
|
||||
assert!(matches!(
|
||||
super::get_ibm_z_sign_key(&vec!(ibm_crt.clone(), ibm_crt.clone())),
|
||||
super::get_ibm_z_sign_key(&[ibm_crt.clone(), ibm_crt.clone()]),
|
||||
Err(Error::HkdVerify(ManyIbmSignKeys))
|
||||
));
|
||||
assert!(matches!(
|
||||
super::get_ibm_z_sign_key(&vec!(ibm_wrong_subj)),
|
||||
super::get_ibm_z_sign_key(&[ibm_wrong_subj]),
|
||||
Err(Error::HkdVerify(NoIbmSignKey))
|
||||
));
|
||||
assert!(matches!(
|
||||
super::get_ibm_z_sign_key(&vec!(no_sign_crt.clone())),
|
||||
super::get_ibm_z_sign_key(&[no_sign_crt.clone()]),
|
||||
Err(Error::HkdVerify(NoIbmSignKey))
|
||||
));
|
||||
assert!(super::get_ibm_z_sign_key(&vec!(ibm_crt.clone(), no_sign_crt.clone())).is_ok(),);
|
||||
assert!(super::get_ibm_z_sign_key(&[ibm_crt, no_sign_crt]).is_ok(),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -14,7 +14,9 @@ use crate::test_utils::*;
|
||||
pub fn mock_endpt(res: &str) -> mockito::Mock {
|
||||
let res_path = get_cert_asset_path(res);
|
||||
|
||||
mockito::mock("GET", format!("/crl/{res}").as_str())
|
||||
let mut server = mockito::Server::new();
|
||||
server
|
||||
.mock("GET", format!("/crl/{res}").as_str())
|
||||
.with_header("content-type", "application/pkix-crl")
|
||||
.with_body_from_file(res_path)
|
||||
.create()
|
||||
@@ -26,7 +28,7 @@ fn verify_sign_error(exp_raw: libc::c_int, obs: Error) {
|
||||
}
|
||||
fn verify_sign_error_slice(exp_raw: &[libc::c_int], obs: Error) {
|
||||
if exp_raw
|
||||
.into_iter()
|
||||
.iter()
|
||||
.filter(|e| match &obs {
|
||||
Error::HkdVerify(ty) => match ty {
|
||||
IbmSignInvalid(err, _d) => &&err.as_raw() == e,
|
||||
@@ -51,7 +53,7 @@ fn store_setup() {
|
||||
let ibm_str = get_cert_asset_path_string("ibm.crt");
|
||||
let inter_str = get_cert_asset_path_string("inter.crt");
|
||||
|
||||
let store = helper::store_setup(&None, &vec![], &vec![ibm_str, inter_str]);
|
||||
let store = helper::store_setup(&None, &[], &[ibm_str, inter_str]);
|
||||
assert!(store.is_ok());
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ fn verify_chain_online() {
|
||||
|
||||
let mock_inter = mock_endpt("inter_ca.crl");
|
||||
|
||||
let mut store = helper::store_setup(&Some(root_crt), &vec![], &vec![]).unwrap();
|
||||
let mut store = helper::store_setup(&Some(root_crt), &[], &[]).unwrap();
|
||||
download_crls_into_store(&mut store, slice::from_ref(&ibm_crt)).unwrap();
|
||||
let store = store.build();
|
||||
|
||||
@@ -71,8 +73,8 @@ fn verify_chain_online() {
|
||||
|
||||
let mut sk = Stack::<X509>::new().unwrap();
|
||||
sk.push(inter_crt).unwrap();
|
||||
verify_chain(&store, &sk, &vec![ibm_crt.clone()]).unwrap();
|
||||
assert!(verify_chain(&store, &sk, &vec!(ibm_crt)).is_ok());
|
||||
verify_chain(&store, &sk, &[ibm_crt.clone()]).unwrap();
|
||||
assert!(verify_chain(&store, &sk, &[ibm_crt]).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -82,13 +84,13 @@ fn verify_chain_offline() {
|
||||
let inter_crt = load_gen_cert("inter_ca.crt");
|
||||
let root_crt = get_cert_asset_path_string("root_ca.chained.crt");
|
||||
|
||||
let store = helper::store_setup(&Some(root_crt), &vec![inter_crl], &vec![])
|
||||
let store = helper::store_setup(&Some(root_crt), &[inter_crl], &[])
|
||||
.unwrap()
|
||||
.build();
|
||||
|
||||
let mut sk = Stack::<X509>::new().unwrap();
|
||||
sk.push(inter_crt).unwrap();
|
||||
assert!(verify_chain(&store, &sk, &vec![ibm_crt]).is_ok());
|
||||
assert!(verify_chain(&store, &sk, &[ibm_crt]).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -107,8 +109,8 @@ fn verify_online() {
|
||||
let inter_crl = get_cert_asset_path_string("inter_ca.crl");
|
||||
let ibm_crl = get_cert_asset_path_string("ibm.crl");
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![ibm_crt, inter_crt],
|
||||
&vec![ibm_crl, inter_crl],
|
||||
&[ibm_crt, inter_crt],
|
||||
&[ibm_crl, inter_crl],
|
||||
&Some(root_crt),
|
||||
false,
|
||||
)
|
||||
@@ -148,8 +150,8 @@ fn verify_offline() {
|
||||
let hkd = load_gen_cert("host.crt");
|
||||
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![ibm_crt, inter_crt],
|
||||
&vec![ibm_crl, inter_crl],
|
||||
&[ibm_crt, inter_crt],
|
||||
&[ibm_crl, inter_crl],
|
||||
&Some(root_crt),
|
||||
true,
|
||||
)
|
||||
@@ -186,25 +188,20 @@ fn verifier_new() {
|
||||
let ibm_rev_crt = get_cert_asset_path_string("ibm_rev.crt");
|
||||
|
||||
// To many signing keys
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![ibm_crt.clone(), ibm_rev_crt.clone()],
|
||||
&vec![],
|
||||
&None,
|
||||
true,
|
||||
);
|
||||
let verifier = CertVerifier::new(&[ibm_crt.clone(), ibm_rev_crt.clone()], &[], &None, true);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(ManyIbmSignKeys))));
|
||||
|
||||
// no CRL for each X509
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
||||
&vec![inter_crl.clone()],
|
||||
&Some(root_crt.clone()),
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_crt),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(3, verifier.unwrap_err());
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
||||
&vec![],
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
@@ -212,8 +209,8 @@ fn verifier_new() {
|
||||
|
||||
// wrong intermediate (or ibm key)
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_fake_crt, ibm_crt.clone()],
|
||||
&vec![inter_fake_crl],
|
||||
&[inter_fake_crt, ibm_crt.clone()],
|
||||
&[inter_fake_crl],
|
||||
&Some(root_chn_crt.clone()),
|
||||
true,
|
||||
);
|
||||
@@ -222,8 +219,8 @@ fn verifier_new() {
|
||||
|
||||
//wrong root ca
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
||||
&vec![inter_crl.clone()],
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&None,
|
||||
true,
|
||||
);
|
||||
@@ -231,33 +228,28 @@ fn verifier_new() {
|
||||
|
||||
//correct signing key + intermediate cert
|
||||
let _verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
||||
&vec![inter_crl.clone()],
|
||||
&[inter_crt.clone(), ibm_crt.clone()],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// no intermediate key
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![ibm_crt.clone()],
|
||||
&vec![],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
let verifier = CertVerifier::new(&[ibm_crt], &[], &Some(root_chn_crt.clone()), false);
|
||||
verify_sign_error(20, verifier.unwrap_err());
|
||||
|
||||
//Ibm Sign outdated
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_early_crt.clone()],
|
||||
&vec![inter_crl.clone()],
|
||||
&[inter_crt.clone(), ibm_early_crt],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_late_crt.clone()],
|
||||
&vec![inter_crl.clone()],
|
||||
&[inter_crt.clone(), ibm_late_crt],
|
||||
&[inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
false,
|
||||
);
|
||||
@@ -265,9 +257,9 @@ fn verifier_new() {
|
||||
|
||||
// revoked
|
||||
let verifier = CertVerifier::new(
|
||||
&vec![inter_crt.clone(), ibm_rev_crt.clone()],
|
||||
&vec![inter_crl.clone()],
|
||||
&Some(root_chn_crt.clone()),
|
||||
&[inter_crt, ibm_rev_crt],
|
||||
&[inter_crl],
|
||||
&Some(root_chn_crt),
|
||||
false,
|
||||
);
|
||||
verify_sign_error(23, verifier.unwrap_err());
|
||||
|
||||
@@ -18,7 +18,7 @@ use pv::{
|
||||
const TAGS: BootHdrTags = BootHdrTags::new([1; 64], [2; 64], [3; 64], [4; 16]);
|
||||
const CUID: ConfigUid = [0x42u8; 16];
|
||||
const ASSOC_SECRET: [u8; 32] = [0x11; 32];
|
||||
const ASSOC_ID: &'static str = "add_secret_request";
|
||||
const ASSOC_ID: &str = "add_secret_request";
|
||||
|
||||
fn create_asrcb(
|
||||
guest_secret: GuestSecret,
|
||||
@@ -38,7 +38,7 @@ fn create_asrcb(
|
||||
};
|
||||
|
||||
asrcb.add_hostkey(hkd);
|
||||
Ok(asrcb.encrypt(ctx)?)
|
||||
asrcb.encrypt(ctx)
|
||||
}
|
||||
|
||||
fn get_crypto() -> (PKey<Public>, ReqEncrCtx) {
|
||||
@@ -63,17 +63,10 @@ where
|
||||
{
|
||||
let (host_key, ctx) = get_crypto();
|
||||
let cuid = match cuid {
|
||||
true => Some(CUID.into()),
|
||||
true => Some(CUID),
|
||||
false => None,
|
||||
};
|
||||
create_asrcb(
|
||||
guest_secret,
|
||||
ext_secret.into(),
|
||||
flags,
|
||||
cuid.into(),
|
||||
host_key,
|
||||
&ctx,
|
||||
)
|
||||
create_asrcb(guest_secret, ext_secret.into(), flags, cuid, host_key, &ctx)
|
||||
}
|
||||
|
||||
fn association() -> GuestSecret {
|
||||
@@ -156,7 +149,7 @@ fn null_none_default_cuid_seven() {
|
||||
let mut asrcb =
|
||||
AddSecretRequest::new(AddSecretVersion::One, GuestSecret::Null, TAGS, no_flag());
|
||||
(0..7).for_each(|_| asrcb.add_hostkey(hkd.clone()));
|
||||
asrcb.set_cuid(CUID.into());
|
||||
asrcb.set_cuid(CUID);
|
||||
let asrcb = asrcb.encrypt(&ctx).unwrap();
|
||||
|
||||
let exp = get_test_asset!("exp/asrcb/null_none_default_cuid_seven");
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
[package]
|
||||
name = "pvsecret"
|
||||
version = "0.9.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1", features = ["std"] }
|
||||
anyhow = { version = "1.0.70", features = ["std"] }
|
||||
clap = { version ="4", features = ["derive", "wrap_help"]}
|
||||
log = { version = "0.4", features = ["std", "release_max_level_debug"] }
|
||||
log = { version = "0.4.6", features = ["std", "release_max_level_debug"] }
|
||||
serde_yaml = "0.9"
|
||||
|
||||
pv = { path = "../pv", features = ["uvsecret", "request"] }
|
||||
utils = { path = "../utils" }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = "abort" # release builds now do not clean up stack after panics. .1 Mb
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "utils"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
@@ -246,6 +246,9 @@ get_system_level()
|
||||
read -r k_ver k_patchlvl k_sublvl k_sublvl2 <<< "$(split_kver "$kver_str" 4)"
|
||||
|
||||
# Handle excessive sublevel numbers consistently
|
||||
if [[ "$k_sublvl" -gt 255 ]] ; then
|
||||
k_sublvl=0
|
||||
fi
|
||||
if [[ "$k_sublvl2" -gt 65535 ]] ; then
|
||||
k_sublvl2=0
|
||||
fi
|
||||
|
||||
@@ -262,6 +262,7 @@ readonly OUTPUT_FILE_OVS="${WORKPATH}network.out"
|
||||
readonly OUTPUT_FILE_ISW="${WORKPATH}installed_sw.out"
|
||||
readonly OUTPUT_FILE_TC="${WORKPATH}network.out"
|
||||
readonly OUTPUT_FILE_VMCMD="${WORKPATH}zvm_runtime.out"
|
||||
readonly OUTPUT_FILE_UDEVDB="${WORKPATH}udevdb.out"
|
||||
# Base file names for different output files - no extension !
|
||||
readonly OUTPUT_FILE_KUBERNETES="${WORKPATH}kubernetes"
|
||||
readonly OUTPUT_FILE_OSAOAT="${WORKPATH}network"
|
||||
@@ -400,6 +401,7 @@ CONFIGFILES="\
|
||||
/etc/hosts*\
|
||||
/etc/iscsi\
|
||||
/etc/inittab\
|
||||
/etc/kdump\
|
||||
/etc/libvirt\
|
||||
/etc/logrotate.d\
|
||||
/etc/lvm\
|
||||
@@ -439,6 +441,7 @@ CONFIGFILES="\
|
||||
/run/modules-load.d/*.conf\
|
||||
/run/udev/chreiplzfcpmp-ipl-volume-id\
|
||||
/run/udev/rules.d\
|
||||
/run/zdev_id.env\
|
||||
"
|
||||
|
||||
########################################
|
||||
@@ -555,6 +558,7 @@ CMDS="${CMDS}\
|
||||
>> '${OUTPUT_FILE_JOURNALCTL}'\
|
||||
:lsof >> '${OUTPUT_FILE_LSOF}'\
|
||||
:rpm -qa | sort >> '${OUTPUT_FILE_ISW}'\
|
||||
:udevadm info --export-db >> '${OUTPUT_FILE_UDEVDB}'\
|
||||
"
|
||||
|
||||
########################################
|
||||
@@ -833,6 +837,7 @@ collect_sysfs() {
|
||||
-x '*/page_idle/bitmap*' \
|
||||
-x '*/tracing/per_cpu/*' \
|
||||
-x '*/tracing/free_buffer' \
|
||||
-x '*/devices/css[0-9]*/[0-9]*.*.*/[0-9]*.*.*/host[0-9]*/rport-[0-9]*:*-*/target[0-9]*:*:*/[0-9]*:*:*:*/block/sd*/mq/0/cpu[0-9]*' \
|
||||
--ignore-failed-read -J 1 -T 5 2>>${OUTPUT_FILE_SYSFS}.err
|
||||
rc=$?
|
||||
else
|
||||
@@ -860,6 +865,7 @@ collect_sysfs() {
|
||||
-a -not \( -path '*page_idle*' -a -name 'bitmap*' \) \
|
||||
-a -not -path '*tracing/per_cpu*' \
|
||||
-a -not -path '*/tracing/free_buffer' \
|
||||
-a -not -path '*/devices/css[0-9]*/[0-9]*.*.*/[0-9]*.*.*/host[0-9]*/rport-[0-9]*:*-*/target[0-9]*:*:*/[0-9]*:*:*:*/block/sd*/mq/0/cpu[0-9]*' \
|
||||
2>/dev/null | while IFS= read -r file_name; do
|
||||
echo " ${file_name}"
|
||||
if ! dd if="${file_name}" status=noxfer iflag=nonblock \
|
||||
@@ -904,7 +910,8 @@ collect_osaoat() {
|
||||
local network_device
|
||||
|
||||
network_devices=$(lsqeth 2>/dev/null | grep "Device name" \
|
||||
| sed 's/D.*:[[:space:]]*\([^[:space:]]*\)[[:space:]]\+/\1/g')
|
||||
| sed 's/D.*:[[:space:]]*\([^[:space:]]*\)[[:space:]]\+/\1/g' \
|
||||
| sed 's/[()]//g' )
|
||||
if type qethqoat >/dev/null; then
|
||||
if test -n "${network_devices}"; then
|
||||
pr_collect_output "osa oat"
|
||||
@@ -954,6 +961,8 @@ collect_ethtool() {
|
||||
"${OUTPUT_FILE_ETHTOOL}"
|
||||
call_run_command "ethtool -T ${network_device}" \
|
||||
"${OUTPUT_FILE_ETHTOOL}"
|
||||
call_run_command "ethtool --module-info ${network_device}" \
|
||||
"${OUTPUT_FILE_ETHTOOL}"
|
||||
done
|
||||
else
|
||||
pr_skip "ethtool: no devices"
|
||||
@@ -1389,7 +1398,7 @@ pr_log_stdout() {
|
||||
pr_syslog_stdout() {
|
||||
echo "$@" >&8
|
||||
echo
|
||||
echo "$(date +%H:%M:%S.%N) - $@"
|
||||
echo "$(date +%H:%M:%S.%N) - " "$@"
|
||||
logger -t "${SCRIPTNAME}" "$@"
|
||||
}
|
||||
|
||||
@@ -1402,13 +1411,13 @@ pr_collect_output() {
|
||||
########################################
|
||||
# print "Collecting ..." like fs
|
||||
pr_collect() {
|
||||
pr_syslog_stdout ${step_num} "Collecting" $@
|
||||
pr_syslog_stdout ${step_num} "Collecting" "$@"
|
||||
}
|
||||
|
||||
########################################
|
||||
# print "Skipping ..." info with reason
|
||||
pr_skip() {
|
||||
pr_syslog_stdout ${step_num} "Skip" $@
|
||||
pr_syslog_stdout ${step_num} "Skip" "$@"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -486,12 +486,16 @@ static void show_queue_capability(int id, int dom)
|
||||
printf("queue %02x.%04x capabilities:\n", id, dom);
|
||||
|
||||
if (util_path_is_reg_file("%s/se_bind", dev)) {
|
||||
util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev);
|
||||
printf("SE bind state: %s\n", buf);
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev))
|
||||
printf("SE bind state: error\n");
|
||||
else
|
||||
printf("SE bind state: %s\n", buf);
|
||||
}
|
||||
if (util_path_is_reg_file("%s/se_associate", dev)) {
|
||||
util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev);
|
||||
printf("SE association state: %s\n", buf);
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev))
|
||||
printf("SE association state: error\n");
|
||||
else
|
||||
printf("SE association state: %s\n", buf);
|
||||
}
|
||||
if (util_path_is_reg_file("%s/mkvps", dev)) {
|
||||
char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue);
|
||||
@@ -674,16 +678,21 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
util_file_read_l(&depth, 10, "%s/depth", grp_dev);
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev))
|
||||
util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev);
|
||||
else
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev))
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - Read of sysfs attribute %s/ap_functions failed.",
|
||||
grp_dev);
|
||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
buf[i] = '\0';
|
||||
util_rec_set(rec, "facility", buf);
|
||||
|
||||
if (ap_bus_has_SB_support()) {
|
||||
if (util_file_read_ul(&facility, 16, "%s/%s/ap_functions",
|
||||
grp_dev, sub_dev)) {
|
||||
util_rec_set(rec, "sestat", "error");
|
||||
return;
|
||||
}
|
||||
switch (EXTRACT_BS_BITS(facility)) {
|
||||
case 0:
|
||||
util_rec_set(rec, "sestat", "usable");
|
||||
|
||||
@@ -15,24 +15,11 @@
|
||||
#include "exit_code.h"
|
||||
#include "hash.h"
|
||||
#include "misc.h"
|
||||
#include "site.h"
|
||||
|
||||
struct subtype;
|
||||
struct setting_list;
|
||||
|
||||
/**
|
||||
* Currently zdev supports 10 sites. Which means, zdev support 10 different
|
||||
* set of attributes which are specific to each site. When the user does
|
||||
* not provide any site information, the common set will be used which is
|
||||
* not specific to any site. So, total we have 11 persistent attribute sets
|
||||
* Where,
|
||||
* 0- 9: Site specific attributes
|
||||
* 10: Common attributes which do not belong to any sites
|
||||
*/
|
||||
|
||||
#define NUM_SITES 11
|
||||
#define NUM_USER_SITES (NUM_SITES - 1)
|
||||
#define SITE_FALLBACK NUM_USER_SITES
|
||||
|
||||
/**
|
||||
* struct device_state - Represent the state of a device in a configuration
|
||||
* @settings: List of attribute settings
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#define MODPROBE_PREFIX "s390x"
|
||||
#define UDEV_PREFIX "41"
|
||||
#define UDEV_SUFFIX ".rules"
|
||||
#define ZDEV_PREFIX "40"
|
||||
|
||||
#define PATH_MODPROBE_CONF "/etc/modprobe.d"
|
||||
#define PATH_MODPROBE "/sbin/modprobe"
|
||||
@@ -66,7 +65,6 @@ char *path_get_zfcp_lun_dev(struct zfcp_lun_devid *);
|
||||
char *path_get_zfcp_port_dev(struct zfcp_lun_devid *);
|
||||
char *path_get_scsi_hctl_dev(const char *);
|
||||
char *path_get_bus_attr(const char *, const char *);
|
||||
char *path_get_zdev_rule(const char *name);
|
||||
|
||||
exit_code_t path_for_each(const char *,
|
||||
exit_code_t (*callback)(const char *, const char *,
|
||||
|
||||
31
zdev/include/site.h
Normal file
31
zdev/include/site.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* zdev - Information regarding site-specific configurations used for
|
||||
* zdev tools.
|
||||
*
|
||||
* Copyright IBM Corp. 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef SITE_H
|
||||
#define SITE_H
|
||||
|
||||
/**
|
||||
* Currently zdev supports 10 sites. Which means, zdev support 10 different
|
||||
* set of attributes which are specific to each site. When the user does
|
||||
* not provide any site information, the common set will be used which is
|
||||
* not specific to any site. So, total we have 11 persistent attribute sets
|
||||
* Where,
|
||||
* 0- 9: Site specific attributes
|
||||
* 10: Common attributes which do not belong to any sites
|
||||
*/
|
||||
|
||||
#define NUM_SITES 11
|
||||
#define NUM_USER_SITES (NUM_SITES - 1)
|
||||
#define SITE_FALLBACK NUM_USER_SITES
|
||||
|
||||
/* Helper to find the availability of site-configuration */
|
||||
#define dev_site_configured(dev, x) (dev->site_specific[(x)].exists && \
|
||||
!dev->site_specific[(x)].deconfigured)
|
||||
#endif /* SITE_H */
|
||||
@@ -34,7 +34,6 @@ void udev_add_internal_from_entry(struct setting_list *list,
|
||||
struct util_udev_entry_node *entry,
|
||||
struct attrib **attribs);
|
||||
|
||||
exit_code_t udev_write_site_rule(void);
|
||||
bool is_legacy_rule(struct util_udev_file *file);
|
||||
|
||||
#endif /* UDEV_H */
|
||||
|
||||
@@ -404,13 +404,3 @@ char *path_get_bus_attr(const char *bus, const char *attr)
|
||||
{
|
||||
return path_get("/sys/bus/%s/%s", bus, attr);
|
||||
}
|
||||
|
||||
/* Return path will be with ZDEV_PREFIX oon PATH_UDEV_RULES */
|
||||
char *path_get_zdev_rule(const char *name)
|
||||
{
|
||||
const char *path = PATH_UDEV_RULES;
|
||||
|
||||
/* Create file. */
|
||||
return path_get("%s/%s-%s%s", path,
|
||||
ZDEV_PREFIX, name, UDEV_SUFFIX);
|
||||
}
|
||||
|
||||
@@ -413,13 +413,16 @@ static struct attrib qeth_attr_isolation = {
|
||||
|
||||
static struct attrib qeth_attr_performance_stats = {
|
||||
.name = "performance_stats",
|
||||
.title = "Control performance statistics collection",
|
||||
.title = "Reset the statistic values",
|
||||
.desc =
|
||||
"Control the collection of QETH performance statistics data:\n"
|
||||
" 0: Performance statistics data is not collected\n"
|
||||
" 1: Performance statistics data is collected\n",
|
||||
.defval = "0",
|
||||
"Write '1' to this attribute to reset the statistic values to 0.\n"
|
||||
"Use the ethtool command to display the statistics.\n",
|
||||
/* read will always return 1 */
|
||||
.defval = "1",
|
||||
/* writing 0 is possible, but has no effect */
|
||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
.activeonly = 1,
|
||||
.rewrite = 1,
|
||||
.st_data = QETH_DATA(layer_any, group_none),
|
||||
};
|
||||
|
||||
|
||||
@@ -139,53 +139,6 @@ out:
|
||||
free(copy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the UDEV rule that determines the active SITE_ID
|
||||
*/
|
||||
exit_code_t udev_write_site_rule(void)
|
||||
{
|
||||
char *path, *name = "zdev-id";
|
||||
exit_code_t rc = EXIT_OK;
|
||||
FILE *fd;
|
||||
|
||||
/* Create file. */
|
||||
path = path_get_zdev_rule(name);
|
||||
|
||||
if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = misc_fopen(path, "w");
|
||||
if (!fd) {
|
||||
error("Could not write to file %s: %s\n", path,
|
||||
strerror(errno));
|
||||
rc = EXIT_RUNTIME_ERROR;
|
||||
goto out;
|
||||
}
|
||||
fprintf(fd, "# Generated by chzdev\n");
|
||||
fprintf(fd, "\n");
|
||||
/* We have to make sure that we are not trying to determine the SITE_ID
|
||||
* for all the corresponding uevent. Check if the SITE_ID is already
|
||||
* determined by reading the file /run/zdev_site_id; and if it is not
|
||||
* available, execute the zdev_id program and determine the SITE_ID and
|
||||
* create the new zdev_site_id file for next run.
|
||||
*/
|
||||
fprintf(fd, "TEST!=\"%s\", IMPORT{program}="
|
||||
"\"%s/zdev_id\",GOTO=\"end\"\n", ZDEV_SITE_ID_FILE,
|
||||
TOOLS_LIBDIR);
|
||||
fprintf(fd, "IMPORT{file}=\"%s\"\n", ZDEV_SITE_ID_FILE);
|
||||
fprintf(fd, "LABEL=\"end\"\n");
|
||||
|
||||
if (misc_fclose(fd))
|
||||
warn("Could not close file %s: %s\n", path, strerror(errno));
|
||||
|
||||
out:
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool is_legacy_rule(struct util_udev_file *file)
|
||||
{
|
||||
struct util_udev_line_node *line;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "setting.h"
|
||||
#include "udev.h"
|
||||
#include "udev_ccw.h"
|
||||
#include "zdev_id.h"
|
||||
|
||||
#define SITE_FALLBACK_SUFFIX "fb"
|
||||
|
||||
@@ -323,7 +324,7 @@ static exit_code_t udev_ccw_write_device_new(struct device *dev)
|
||||
char *path, *cfg_label = NULL, *end_label = NULL;
|
||||
exit_code_t rc = EXIT_OK;
|
||||
FILE *fd;
|
||||
int i, configured = 0;
|
||||
int i, configured = 0, site_configured = 0;
|
||||
|
||||
/*
|
||||
* Remove the previous file; The new udev rule will be created based on the
|
||||
@@ -338,9 +339,10 @@ static exit_code_t udev_ccw_write_device_new(struct device *dev)
|
||||
|
||||
dev_state_copy(&dev->site_specific[global_site_id], &dev->persistent);
|
||||
for (i = 0; i < NUM_SITES; i++) {
|
||||
configured += dev->site_specific[i].exists;
|
||||
configured -= dev->site_specific[i].deconfigured;
|
||||
configured += dev_site_configured(dev, i) ? 1 : 0;
|
||||
}
|
||||
site_configured = configured - (dev_site_configured(dev, SITE_FALLBACK) ?
|
||||
1 : 0);
|
||||
|
||||
/*
|
||||
* If there is no configuration settings available, do not create the new
|
||||
@@ -386,21 +388,41 @@ static exit_code_t udev_ccw_write_device_new(struct device *dev)
|
||||
fprintf(fd, "\n");
|
||||
|
||||
fprintf(fd, "LABEL=\"%s\"\n", cfg_label);
|
||||
|
||||
/*
|
||||
* Determine the ZDEV_SITE_ID here. If ZDEV_SITE_ID_FILE available,
|
||||
* simply import the content. If not, execute zdev_id and import the
|
||||
* output of the same.
|
||||
*/
|
||||
if (site_configured) {
|
||||
fprintf(fd, "# Determine ZDEV_SITE_ID to continue\n");
|
||||
fprintf(fd, "TEST==\"%s\",IMPORT{file}=\"%s\"\n",
|
||||
ZDEV_SITE_ID_FILE, ZDEV_SITE_ID_FILE);
|
||||
fprintf(fd, "TEST!=\"%s\",IMPORT{program}=\"%s/zdev_id\"\n\n",
|
||||
ZDEV_SITE_ID_FILE, TOOLS_LIBDIR);
|
||||
}
|
||||
|
||||
/* site comparison block */
|
||||
for (i = 0; i < NUM_USER_SITES; i++) {
|
||||
if (dev->site_specific[i].exists &&
|
||||
!dev->site_specific[i].deconfigured) {
|
||||
if (dev_site_configured(dev, i)) {
|
||||
fprintf(fd, "ENV{ZDEV_SITE_ID}==\"%d\",GOTO=\"%s_site%d\"\n", i,
|
||||
cfg_label, i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If no site configurations are available, then we need to make sure that
|
||||
* the udev-rule stays as compact as possible. We do not want to add any
|
||||
* extra labels on it.
|
||||
*/
|
||||
if (!site_configured)
|
||||
goto fallback;
|
||||
|
||||
/*
|
||||
* If we have a generic configuration available, then use that setting as a
|
||||
* fail-over incase of no site-id information in LOADPARM
|
||||
*/
|
||||
if (dev->site_specific[SITE_FALLBACK].exists &&
|
||||
!dev->site_specific[SITE_FALLBACK].deconfigured)
|
||||
if (dev_site_configured(dev, SITE_FALLBACK))
|
||||
fprintf(fd, "GOTO=\"%s_site_fb\"\n", cfg_label);
|
||||
else
|
||||
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
||||
@@ -408,8 +430,7 @@ static exit_code_t udev_ccw_write_device_new(struct device *dev)
|
||||
|
||||
/* Write the site blocks for all the available configurations */
|
||||
for (i = 0; i < NUM_USER_SITES; i++) {
|
||||
if (dev->site_specific[i].exists &&
|
||||
!dev->site_specific[i].deconfigured) {
|
||||
if (dev_site_configured(dev, i)) {
|
||||
fprintf(fd, "# site_start_%d\n", i);
|
||||
fprintf(fd, "LABEL=\"%s_site%d\"\n", cfg_label, i);
|
||||
|
||||
@@ -420,11 +441,12 @@ static exit_code_t udev_ccw_write_device_new(struct device *dev)
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
}
|
||||
if (dev->site_specific[SITE_FALLBACK].exists &&
|
||||
!dev->site_specific[SITE_FALLBACK].deconfigured) {
|
||||
fprintf(fd, "# site_start_fb\n");
|
||||
fprintf(fd, "LABEL=\"%s_site_fb\"\n", cfg_label);
|
||||
|
||||
fallback:
|
||||
if (dev_site_configured(dev, SITE_FALLBACK)) {
|
||||
fprintf(fd, "# site_start_fb\n");
|
||||
if (site_configured)
|
||||
fprintf(fd, "LABEL=\"%s_site_fb\"\n", cfg_label);
|
||||
write_attr_to_file(fd, &dev->site_specific[i], id);
|
||||
/* Write udev rule epilog. */
|
||||
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
||||
@@ -439,9 +461,6 @@ static exit_code_t udev_ccw_write_device_new(struct device *dev)
|
||||
if (misc_fclose(fd))
|
||||
warn("Could not close file %s: %s\n", path, strerror(errno));
|
||||
|
||||
rc = udev_write_site_rule();
|
||||
if (rc)
|
||||
goto out;
|
||||
out:
|
||||
free(end_label);
|
||||
free(cfg_label);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "site.h"
|
||||
#include "zdev_id.h"
|
||||
|
||||
#define SYSINFO "/proc/sysinfo"
|
||||
@@ -20,7 +21,6 @@
|
||||
#define LOADPARM "/sys/firmware/ipl/loadparm"
|
||||
#define IPL_DEV_ID "/sys/firmware/ipl/device"
|
||||
#define IPL_DEV_TYPE "/sys/firmware/ipl/ipl_type"
|
||||
#define SITE_FALLBACK 10
|
||||
|
||||
#define WHITESPACE " \t\n"
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "df_s390.h"
|
||||
|
||||
/*
|
||||
@@ -100,6 +102,8 @@ void df_s390_hdr_add(struct df_s390_hdr *hdr)
|
||||
if ((hdr->version >= 5 || hdr->magic == DF_S390_MAGIC_EXT) &&
|
||||
hdr->real_cpu_cnt)
|
||||
dfi_attr_real_cpu_cnt_set(hdr->real_cpu_cnt);
|
||||
if (!hdr->mvdump && hdr->zlib_version_s390 && hdr->zlib_entry_size)
|
||||
dfi_attr_zlib_info_set(hdr->zlib_version_s390, hdr->zlib_entry_size);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -151,16 +155,19 @@ void df_s390_dumper_read(struct zg_fh *fh, int blk_size,
|
||||
case 1:
|
||||
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT, 7) == 0 ||
|
||||
strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7) == 0)
|
||||
dumper->size = DF_S390_DUMPER_SIZE_V3;
|
||||
dumper->size = STAGE2_DUMPER_SIZE_V3;
|
||||
else
|
||||
dumper->size = DF_S390_DUMPER_SIZE_V1;
|
||||
dumper->size = STAGE2_DUMPER_SIZE_V1;
|
||||
break;
|
||||
case 2:
|
||||
dumper->size = DF_S390_DUMPER_SIZE_V2;
|
||||
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT, 7) == 0)
|
||||
dumper->size = STAGE2_DUMPER_SIZE_ZLIB;
|
||||
else
|
||||
dumper->size = STAGE2_DUMPER_SIZE_V2;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
dumper->size = DF_S390_DUMPER_SIZE_V3;
|
||||
dumper->size = STAGE2_DUMPER_SIZE_V3;
|
||||
}
|
||||
/* Read force and mem fields in the end of the dumper */
|
||||
bytes_to_read = sizeof(dumper->force) + sizeof(dumper->mem);
|
||||
|
||||
@@ -13,74 +13,12 @@
|
||||
#define DF_S390_H
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "dump/s390_dump.h"
|
||||
#include "boot/loaders_layout.h"
|
||||
|
||||
#include "dt.h"
|
||||
#include "zg.h"
|
||||
|
||||
#define DF_S390_MAGIC 0xa8190173618f23fdULL
|
||||
#define DF_S390_MAGIC_EXT 0xa8190173618f23feULL
|
||||
#define DF_S390_HDR_SIZE 0x1000
|
||||
#define DF_S390_EM_SIZE 16
|
||||
#define DF_S390_EM_STR "DUMP_END"
|
||||
#define DF_S390_CPU_MAX 512
|
||||
#define DF_S390_MAGIC_BLK_ECKD 3
|
||||
|
||||
/*
|
||||
* Architecture of dumped system
|
||||
*/
|
||||
enum df_s390_arch {
|
||||
DF_S390_ARCH_32 = 1,
|
||||
DF_S390_ARCH_64 = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* s390 dump header format
|
||||
*/
|
||||
struct df_s390_hdr {
|
||||
u64 magic; /* 0x000 */
|
||||
u32 version; /* 0x008 */
|
||||
u32 hdr_size; /* 0x00c */
|
||||
u32 dump_level; /* 0x010 */
|
||||
u32 page_size; /* 0x014 */
|
||||
u64 mem_size; /* 0x018 */
|
||||
u64 mem_start; /* 0x020 */
|
||||
u64 mem_end; /* 0x028 */
|
||||
u32 num_pages; /* 0x030 */
|
||||
u32 pad; /* 0x034 */
|
||||
u64 tod; /* 0x038 */
|
||||
u64 cpu_id; /* 0x040 */
|
||||
u32 arch; /* 0x048 */
|
||||
u32 volnr; /* 0x04c */
|
||||
u32 build_arch; /* 0x050 */
|
||||
u64 mem_size_real; /* 0x054 */
|
||||
u8 mvdump; /* 0x05c */
|
||||
u16 cpu_cnt; /* 0x05d */
|
||||
u16 real_cpu_cnt; /* 0x05f */
|
||||
u8 end_pad1[0x200-0x061]; /* 0x061 */
|
||||
u64 mvdump_sign; /* 0x200 */
|
||||
u64 mvdump_zipl_time; /* 0x208 */
|
||||
u8 end_pad2[0x800-0x210]; /* 0x210 */
|
||||
u32 lc_vec[DF_S390_CPU_MAX]; /* 0x800 */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* End marker: Should be at the end of every valid s390 crash dump.
|
||||
*/
|
||||
struct df_s390_em {
|
||||
char str[8];
|
||||
u64 tod;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Segment header for s390 extended dump format
|
||||
*/
|
||||
struct df_s390_dump_segm_hdr {
|
||||
u64 start;
|
||||
u64 len;
|
||||
u64 stop_marker;
|
||||
u8 reserved[0x1000 - 24];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Convert DFI arch to s390 arch
|
||||
*/
|
||||
@@ -97,9 +35,6 @@ static inline enum dfi_arch df_s390_to_dfi_arch(enum df_s390_arch df_s390_arch)
|
||||
return df_s390_arch == DF_S390_ARCH_64 ? DFI_ARCH_64 : DFI_ARCH_32;
|
||||
}
|
||||
|
||||
#define DF_S390_DUMPER_SIZE_V1 0x1000
|
||||
#define DF_S390_DUMPER_SIZE_V2 0x2000
|
||||
#define DF_S390_DUMPER_SIZE_V3 0x3000
|
||||
#define DF_S390_DUMPER_MAGIC32 "ZECKD31"
|
||||
#define DF_S390_DUMPER_MAGIC64 "ZECKD64"
|
||||
#define DF_S390_DUMPER_MAGIC_EXT "XECKD64"
|
||||
|
||||
27
zdump/dfi.c
27
zdump/dfi.c
@@ -74,6 +74,8 @@ struct attr {
|
||||
struct new_utsname *utsname;
|
||||
char *dump_method;
|
||||
u64 *file_size;
|
||||
u8 *zlib_version;
|
||||
u32 *zlib_entsize;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -146,6 +148,11 @@ void dfi_info_print(void)
|
||||
if (l.attr.file_size)
|
||||
STDERR(" Dump file size.....: %lld MB\n",
|
||||
TO_MIB(*l.attr.file_size));
|
||||
if (g.opts.verbose && l.attr.zlib_version && l.attr.zlib_entsize) {
|
||||
STDERR(" Zlib version.......: %lld\n", *l.attr.zlib_version);
|
||||
STDERR(" Zlib compression unit: %lld MB\n",
|
||||
TO_MIB(*l.attr.zlib_entsize));
|
||||
}
|
||||
if (dfi_mem_range())
|
||||
dfi_mem_map_print(g.opts.verbose);
|
||||
if (l.dfi->info_dump) {
|
||||
@@ -426,6 +433,26 @@ u64 *dfi_attr_file_size(void)
|
||||
return l.attr.file_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attribute: Zlib version and zlib entry size
|
||||
*/
|
||||
void dfi_attr_zlib_info_set(u8 version, u32 entry_size)
|
||||
{
|
||||
l.attr.zlib_version = zg_alloc(sizeof(*l.attr.zlib_version));
|
||||
*l.attr.zlib_version = version;
|
||||
l.attr.zlib_entsize = zg_alloc(sizeof(*l.attr.zlib_entsize));
|
||||
*l.attr.zlib_entsize = entry_size;
|
||||
}
|
||||
|
||||
u8 *dfi_attr_zlib_version(void)
|
||||
{
|
||||
return l.attr.zlib_version;
|
||||
}
|
||||
|
||||
u32 *dfi_attr_zlib_entsize(void)
|
||||
{
|
||||
return l.attr.zlib_entsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attribute: Build architecture
|
||||
|
||||
@@ -182,6 +182,10 @@ u64 *dfi_attr_mem_size_real(void);
|
||||
void dfi_attr_file_size_set(u64 dump_size);
|
||||
u64 *dfi_attr_file_size(void);
|
||||
|
||||
void dfi_attr_zlib_info_set(u8 version, u32 entry_size);
|
||||
u8 *dfi_attr_zlib_version(void);
|
||||
u32 *dfi_attr_zlib_entsize(void);
|
||||
|
||||
void dfi_attr_vol_nr_set(unsigned int vol_nr);
|
||||
unsigned int *dfi_attr_vol_nr(void);
|
||||
|
||||
|
||||
193
zdump/dfi_s390.c
193
zdump/dfi_s390.c
@@ -18,8 +18,10 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "lib/util_log.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "zgetdump.h"
|
||||
#include "zg.h"
|
||||
@@ -35,8 +37,21 @@ static struct {
|
||||
struct df_s390_hdr hdr; /* s390 dump header */
|
||||
struct df_s390_em em; /* s390 end marker */
|
||||
bool extended; /* Extended input dump format */
|
||||
int blk_size; /* Dump device block size */
|
||||
} l;
|
||||
|
||||
struct mem_chunk_compressed_data {
|
||||
/* Offset of the dump segment data on disk in bytes */
|
||||
u64 offset_on_disk;
|
||||
/* Number of compressed entries */
|
||||
u32 entry_count;
|
||||
/*
|
||||
* Offsets to compressed entries from
|
||||
* the start of mem_chunk in blocks
|
||||
*/
|
||||
u32 entry_offset[];
|
||||
};
|
||||
|
||||
/*
|
||||
* s390 mem chunk read callback
|
||||
*/
|
||||
@@ -56,11 +71,118 @@ static void dfi_s390_ext_mem_chunk_read(struct dfi_mem_chunk *mem_chunk,
|
||||
u64 off, void *buf, u64 cnt)
|
||||
{
|
||||
u64 *mem_chunk_off = mem_chunk->data;
|
||||
util_log_print(UTIL_LOG_DEBUG,
|
||||
"DFI S390 mem_chunk_read: start=0x%016lx, off=0x%016lx, cnt=0x%08lx\n",
|
||||
mem_chunk->start, off, cnt);
|
||||
|
||||
zg_seek(g.fh, *mem_chunk_off + off, ZG_CHECK);
|
||||
zg_read(g.fh, buf, cnt, ZG_CHECK);
|
||||
}
|
||||
|
||||
static inline unsigned long b2m(unsigned long blk)
|
||||
{
|
||||
return blk * l.blk_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read compressed data entry using global file handle and decompress up to
|
||||
* count bytes to the output buffer. The size of the output buffer considered
|
||||
* to be enough to fit the decompressed data.
|
||||
*/
|
||||
static unsigned long read_decompress_entry(void *buf_out, u64 count)
|
||||
{
|
||||
unsigned char buf_in[8 * PAGE_SIZE];
|
||||
z_stream strm = { 0 };
|
||||
u64 total_out;
|
||||
int rc;
|
||||
|
||||
/* Initialize inflate stream */
|
||||
strm.next_in = NULL;
|
||||
strm.avail_in = 0;
|
||||
rc = inflateInit2(&strm, MAX_WBITS);
|
||||
if (rc != Z_OK)
|
||||
ERR_EXIT("Decompression failed, inflateInit RC = %d", rc);
|
||||
strm.next_out = buf_out;
|
||||
strm.avail_out = count;
|
||||
/* Decompress data entry to the output buffer */
|
||||
while (rc != Z_STREAM_END) {
|
||||
/* Read in more compressed data */
|
||||
if (strm.avail_in == 0) {
|
||||
strm.next_in = buf_in;
|
||||
rc = zg_read(g.fh, buf_in, sizeof(buf_in), ZG_CHECK_NONE);
|
||||
if (rc < 0)
|
||||
ERR_EXIT("Decompression failed, read error encountered");
|
||||
strm.avail_in = rc;
|
||||
}
|
||||
rc = inflate(&strm, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END)
|
||||
ERR_EXIT("Decompression failed, inflate RC = %d", rc);
|
||||
/* No need to decompress more data */
|
||||
if (strm.avail_out == 0)
|
||||
break;
|
||||
}
|
||||
total_out = strm.total_out;
|
||||
inflateEnd(&strm);
|
||||
return total_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* s390_ext compressed mem chunk read callback
|
||||
*/
|
||||
static void dfi_s390_ext_mem_chunk_read_decompress(struct dfi_mem_chunk *mem_chunk,
|
||||
u64 off, void *buf, u64 cnt)
|
||||
{
|
||||
u64 bytes_to_copy, start_offset, compressed_data_addr, copied, decompressed_out;
|
||||
struct mem_chunk_compressed_data *data = mem_chunk->data;
|
||||
u32 uncompressed, entry_size, entry_index;
|
||||
void *buf_out;
|
||||
|
||||
util_log_print(UTIL_LOG_DEBUG,
|
||||
"DFI S390 mem_chunk_read_decomp: start=0x%016lx, offset_on_disk=0x%016lx, off=0x%016lx, cnt=0x%08lx\n",
|
||||
mem_chunk->start, data->offset_on_disk, off, cnt);
|
||||
/*
|
||||
* The dump is compressed in data pieces of equal size (stored in the dump header).
|
||||
* Identify the first compressed entry of interest within a memory chunk.
|
||||
*/
|
||||
entry_size = l.hdr.zlib_entry_size;
|
||||
entry_index = off / entry_size;
|
||||
/* Offset within the decompressed data of the first entry */
|
||||
start_offset = off % entry_size;
|
||||
buf_out = zg_alloc(entry_size);
|
||||
copied = 0;
|
||||
while (copied < cnt) {
|
||||
if (entry_index >= data->entry_count)
|
||||
ERR_EXIT("Decompression failed, compressed entry index out of bounds");
|
||||
/* Check if the entry is actually compressed */
|
||||
uncompressed = data->entry_offset[entry_index] & DUMP_SEGM_ENTRY_UNCOMPRESSED;
|
||||
/* Calculate entry location on disk */
|
||||
compressed_data_addr = data->offset_on_disk +
|
||||
b2m(~DUMP_SEGM_ENTRY_UNCOMPRESSED & data->entry_offset[entry_index]);
|
||||
if (uncompressed) {
|
||||
/* Read entire uncompressed entry from disk */
|
||||
zg_seek(g.fh, compressed_data_addr + start_offset, ZG_CHECK);
|
||||
bytes_to_copy = MIN(cnt - copied, entry_size - start_offset);
|
||||
zg_read(g.fh, buf + copied, bytes_to_copy, ZG_CHECK);
|
||||
} else {
|
||||
/*
|
||||
* Decompress entry to the output buffer. Limit the size of the
|
||||
* output data if needed.
|
||||
*/
|
||||
zg_seek(g.fh, compressed_data_addr, ZG_CHECK);
|
||||
decompressed_out = MIN(start_offset + cnt - copied, entry_size);
|
||||
decompressed_out = read_decompress_entry(buf_out, decompressed_out);
|
||||
/* Copy the decompressed output produced so far */
|
||||
bytes_to_copy = MIN(decompressed_out - start_offset, cnt - copied);
|
||||
memcpy(buf + copied, buf_out + start_offset, bytes_to_copy);
|
||||
}
|
||||
copied += bytes_to_copy;
|
||||
entry_index++;
|
||||
/* For further entries, copy from the start of the decompressed data */
|
||||
start_offset = 0;
|
||||
}
|
||||
zg_free(buf_out);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read s390 dump header
|
||||
@@ -78,6 +200,8 @@ static int read_s390_hdr(void)
|
||||
return -ENODEV;
|
||||
if (l.hdr.cpu_cnt > DF_S390_CPU_MAX)
|
||||
return -ENODEV;
|
||||
if (l.hdr.zlib_version_s390 && l.hdr.version != 2)
|
||||
return -ENODEV;
|
||||
util_log_print(UTIL_LOG_INFO, "DFI S390 version %u\n", l.hdr.version);
|
||||
df_s390_hdr_add(&l.hdr);
|
||||
return 0;
|
||||
@@ -121,6 +245,44 @@ static int mem_chunks_add(void)
|
||||
return read_s390_em();
|
||||
}
|
||||
|
||||
/*
|
||||
* Add memory chunk for a compressed dump segment. Set file handle position
|
||||
* and return the offset to the next dump segment.
|
||||
*/
|
||||
static void create_compressed_mem_chunk(const struct df_s390_dump_segm_hdr *dump_segm,
|
||||
u64 offset)
|
||||
{
|
||||
/*
|
||||
* Need to preserve entry_offset array from the header of a
|
||||
* compressed segment along with the segment offset on disk
|
||||
* for the read callback function.
|
||||
*/
|
||||
struct mem_chunk_compressed_data *data = zg_alloc(sizeof(*data) +
|
||||
dump_segm->entry_count * sizeof(u32));
|
||||
data->offset_on_disk = offset;
|
||||
data->entry_count = dump_segm->entry_count;
|
||||
memcpy(&data->entry_offset, &dump_segm->entry_offset,
|
||||
data->entry_count * sizeof(u32));
|
||||
dfi_mem_chunk_add(dump_segm->start, dump_segm->len, data,
|
||||
dfi_s390_ext_mem_chunk_read_decompress, zg_free);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add memory chunk for a non-compressed dump segment. Set file handle position
|
||||
* and return the offset to the next dump segment.
|
||||
*/
|
||||
static void create_uncompressed_mem_chunk(const struct df_s390_dump_segm_hdr *dump_segm,
|
||||
u64 offset)
|
||||
{
|
||||
/* For non-compressed segment just an offset is needed for a callback */
|
||||
u64 *off_ptr = zg_alloc(sizeof(*off_ptr));
|
||||
*off_ptr = offset;
|
||||
dfi_mem_chunk_add(dump_segm->start, dump_segm->len, off_ptr,
|
||||
dfi_s390_ext_mem_chunk_read, zg_free);
|
||||
off_ptr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register memory chunks (extended dump format) and verify the end marker
|
||||
*/
|
||||
@@ -132,26 +294,30 @@ static int mem_chunks_add_ext(void)
|
||||
off = zg_seek(g.fh, DF_S390_HDR_SIZE, ZG_CHECK_NONE);
|
||||
if (off != DF_S390_HDR_SIZE)
|
||||
return -EINVAL;
|
||||
while (off < DF_S390_HDR_SIZE + l.hdr.mem_size - PAGE_SIZE) {
|
||||
rc = zg_read(g.fh, &dump_segm, PAGE_SIZE, ZG_CHECK_ERR);
|
||||
if (rc != PAGE_SIZE)
|
||||
while (off < DF_S390_HDR_SIZE + l.hdr.mem_size) {
|
||||
rc = zg_read(g.fh, &dump_segm, sizeof(dump_segm), ZG_CHECK_ERR);
|
||||
if (rc != sizeof(dump_segm))
|
||||
return -EINVAL;
|
||||
util_log_print(UTIL_LOG_DEBUG,
|
||||
"DFI S390 dump segment start 0x%016lx size 0x%016lx stop marker %d\n",
|
||||
dump_segm.start, dump_segm.len, dump_segm.stop_marker);
|
||||
off += PAGE_SIZE;
|
||||
"DFI S390 dump segment start 0x%016lx size 0x%016lx compr_size 0x%08lx stop marker %d\n",
|
||||
dump_segm.start, dump_segm.len, b2m(dump_segm.size_on_disk),
|
||||
dump_segm.stop_marker ? 1 : 0);
|
||||
off += sizeof(dump_segm);
|
||||
/* Add zero memory chunk */
|
||||
dfi_mem_chunk_add(old, dump_segm.start - old, NULL,
|
||||
dfi_mem_chunk_read_zero, NULL);
|
||||
/* Add memory chunk for a dump segment */
|
||||
u64 *off_ptr = zg_alloc(sizeof(*off_ptr));
|
||||
*off_ptr = off;
|
||||
dfi_mem_chunk_add(dump_segm.start, dump_segm.len, off_ptr,
|
||||
dfi_s390_ext_mem_chunk_read, zg_free);
|
||||
off_ptr = NULL;
|
||||
if (dump_segm.size_on_disk) {
|
||||
/* Compressed dump segment detected */
|
||||
create_compressed_mem_chunk(&dump_segm, off);
|
||||
off = zg_seek_cur(g.fh, b2m(dump_segm.size_on_disk), ZG_CHECK_NONE);
|
||||
dump_size += b2m(dump_segm.size_on_disk);
|
||||
} else {
|
||||
create_uncompressed_mem_chunk(&dump_segm, off);
|
||||
off = zg_seek_cur(g.fh, dump_segm.len, ZG_CHECK_NONE);
|
||||
dump_size += dump_segm.len;
|
||||
}
|
||||
old = dump_segm.start + dump_segm.len;
|
||||
dump_size += dump_segm.len;
|
||||
off = zg_seek_cur(g.fh, dump_segm.len, ZG_CHECK_NONE);
|
||||
if (dump_segm.stop_marker)
|
||||
break;
|
||||
}
|
||||
@@ -180,6 +346,7 @@ int dfi_s390_init_gen(bool extended)
|
||||
l.extended = extended;
|
||||
if (read_s390_hdr() != 0)
|
||||
return -ENODEV;
|
||||
zg_ioctl(g.fh, BLKSSZGET, &l.blk_size, "BLKSSZGET", ZG_CHECK);
|
||||
if (!extended)
|
||||
rc = mem_chunks_add();
|
||||
else
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_path.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "zgetdump.h"
|
||||
#include "dt.h"
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "zgetdump.h"
|
||||
#include "df_s390.h"
|
||||
#include "dfi.h"
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "df_s390.h"
|
||||
#include "dfi_mem_chunk.h"
|
||||
#include "dfo_mem_chunk.h"
|
||||
@@ -69,7 +71,7 @@ static void cpu2lc_32(void *lc_32, struct dfi_cpu *cpu_64)
|
||||
/*
|
||||
* Convert timeval to s390 TOD clock
|
||||
*/
|
||||
static void timeval2tod(u64 *tod, struct timeval *xtime)
|
||||
static void timeval2tod(uint64_t *tod, struct timeval *xtime)
|
||||
{
|
||||
u64 us = xtime->tv_sec * 1000000 + xtime->tv_usec;
|
||||
*tod = (us << 12);
|
||||
|
||||
@@ -109,11 +109,11 @@ static int dumper_read_validate_fba(int size, struct df_s390_dumper *dumper)
|
||||
*/
|
||||
static int dumper_read_fba(void)
|
||||
{
|
||||
if (dumper_read_validate_fba(DF_S390_DUMPER_SIZE_V3, &l.dumper) == 0)
|
||||
if (dumper_read_validate_fba(STAGE2_DUMPER_SIZE_V3, &l.dumper) == 0)
|
||||
return 0;
|
||||
if (dumper_read_validate_fba(DF_S390_DUMPER_SIZE_V2, &l.dumper) == 0)
|
||||
if (dumper_read_validate_fba(STAGE2_DUMPER_SIZE_V2, &l.dumper) == 0)
|
||||
return 0;
|
||||
if (dumper_read_validate_fba(DF_S390_DUMPER_SIZE_V1, &l.dumper) == 0)
|
||||
if (dumper_read_validate_fba(STAGE2_DUMPER_SIZE_V1, &l.dumper) == 0)
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
#include "dfo.h"
|
||||
#include "output.h"
|
||||
|
||||
#define BUFFER_SIZE (1 * MIB)
|
||||
|
||||
int write_dump(FILE *stream)
|
||||
{
|
||||
const u64 output_size = dfo_size();
|
||||
char buf[8UL * PAGE_SIZE];
|
||||
char *buf = zg_alloc(BUFFER_SIZE);
|
||||
u64 written = 0;
|
||||
|
||||
if (!dfi_feat_copy())
|
||||
@@ -31,7 +33,7 @@ int write_dump(FILE *stream)
|
||||
size_t rc;
|
||||
u64 cnt;
|
||||
|
||||
cnt = dfo_read(buf, sizeof(buf));
|
||||
cnt = dfo_read(buf, BUFFER_SIZE);
|
||||
rc = fwrite(buf, cnt, 1, stream);
|
||||
if (rc != 1 && ferror(stream))
|
||||
ERR_EXIT("Error: Write failed");
|
||||
@@ -40,5 +42,6 @@ int write_dump(FILE *stream)
|
||||
};
|
||||
STDERR("\n");
|
||||
STDERR("Success: Dump has been copied\n");
|
||||
zg_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@ The following dump formats are supported for the source dump only:
|
||||
.TP
|
||||
.BR "s390_ext"
|
||||
This dump format is IBM zSystems specific and is used for DASD dumps only.
|
||||
Starting with s390_ext format version 2, dumps also support zlib compression.
|
||||
.TP
|
||||
.BR "vmdump"
|
||||
Dumps with this format are created by the z/VM vmdump command
|
||||
@@ -277,7 +278,16 @@ tool (see man zipl).
|
||||
.TP
|
||||
.BR "Dump file size"
|
||||
Actual size of dump file on disk in megabytes. "Dump file size" may differ from
|
||||
the "dump memory range" because of zero memory chunks.
|
||||
the "dump memory range" because of zero memory chunks or dump compression.
|
||||
.TP
|
||||
.BR "Zlib version"
|
||||
The version of zlib used for compressed dumps.
|
||||
.TP
|
||||
.BR "Zlib compression unit"
|
||||
Size of the input data chunks that has been used for the dump zlib compression
|
||||
by the dump tool. Every chunk of data is compressed separately and can be
|
||||
decompressed independently, allowing zgetdump to make fast read seeks.
|
||||
.br
|
||||
.TP
|
||||
.BR "Memory map"
|
||||
Available memory chunks in the dump. Some dump tools create multiple memory
|
||||
|
||||
@@ -6,6 +6,7 @@ all:
|
||||
$(MAKE) -C src
|
||||
|
||||
install: all
|
||||
$(MAKE) -C boot install
|
||||
$(MAKE) -C src install
|
||||
$(MAKE) -C man install
|
||||
$(MAKE) -C dracut install
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
# Common definitions
|
||||
include ../../common.mak
|
||||
|
||||
EMBEDDED_BOOTLOADERS := fba0.bin fba1b.bin fba2.bin \
|
||||
eckd0_ldl.bin eckd0_cdl.bin \
|
||||
eckd1.bin eckd1b.bin eckd2.bin \
|
||||
tape0.bin \
|
||||
eckd2dump_sv.bin tape2dump.bin fba2dump.bin eckd2dump_mv.bin
|
||||
DEBUG_EMBEDDED_BOOTLOADERS := $(addsuffix .debug,$(EMBEDDED_BOOTLOADERS))
|
||||
EXTERNAL_BOOTLOADERS := stage3.bin
|
||||
DEBUG_EXTERNAL_BOOTLOADERS := $(addsuffix .debug,$(EXTERNAL_BOOTLOADERS))
|
||||
|
||||
.loaders: $(EMBEDDED_BOOTLOADERS) $(DEBUG_EMBEDDED_BOOTLOADERS)
|
||||
touch .loaders
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
all: .loaders $(EXTERNAL_BOOTLOADERS) $(DEBUG_EXTERNAL_BOOTLOADERS)
|
||||
|
||||
clean:
|
||||
rm -f -- ./**/*.o *.o *.exec *.bin *.lds .*.lds.d .loaders *.debug
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
ifeq ($(HOST_ARCH),s390x)
|
||||
INCLUDE_PATHS := $(rootdir)/zipl/include $(rootdir)/include
|
||||
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
||||
|
||||
@@ -13,19 +34,6 @@ ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g $(INCLUDE_PARMS) \
|
||||
-W -Wall -Wformat-security -fno-sanitize=all -Wno-array-bounds
|
||||
ALL_LDFLAGS += -fno-sanitize=all
|
||||
|
||||
INC_FILES := fba0.bin fba1b.bin fba2.bin \
|
||||
eckd0_ldl.bin eckd0_cdl.bin \
|
||||
eckd1.bin eckd1b.bin eckd2.bin \
|
||||
tape0.bin \
|
||||
eckd2dump_sv.bin tape2dump.bin fba2dump.bin eckd2dump_mv.bin
|
||||
FILES := $(INC_FILES) stage3.bin
|
||||
DEBUG_FILES := $(addsuffix .debug,$(FILES))
|
||||
|
||||
all: .loaders $(FILES) $(DEBUG_FILES)
|
||||
|
||||
.loaders: $(INC_FILES)
|
||||
touch .loaders
|
||||
|
||||
# Prevent make from using some default rules...
|
||||
%: %.S
|
||||
|
||||
@@ -56,8 +64,9 @@ eckd1b.exec fba1b.exec: \
|
||||
stage1b.lds
|
||||
|
||||
eckd2dump_sv.exec: \
|
||||
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o \
|
||||
libc.o ebcdic.o sclp.o entry.o stage2.lds
|
||||
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o eckd2dump_zlib.o \
|
||||
zlib/deflate.o zlib/deftree.o zlib/dfltcc.o zlib/dfltcc_deflate.o \
|
||||
libc.o ebcdic.o sclp.o entry.o eckd2dump_sv.lds
|
||||
eckd2dump_mv.exec: \
|
||||
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_mv.o \
|
||||
libc.o ebcdic.o sclp.o entry.o stage2.lds
|
||||
@@ -76,15 +85,27 @@ stage3.exec: head.o stage3.o kdump3.o libc.o ebcdic.o ebcdic_conv.o sclp.o \
|
||||
|
||||
%.exec: %.o
|
||||
$(LINK) -Wl,-T,$(filter %.lds,$^) $(NO_PIE_LDFLAGS) $(NO_WARN_RWX_SEGMENTS_LDFLAGS) -Wl,--build-id=none -m64 -static -nostdlib $(filter %.o, $^) -o $@
|
||||
@chmod a-x $@
|
||||
|
||||
%.bin.debug: %.exec
|
||||
$(OBJCOPY) --only-keep-debug $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
%.bin: %.exec
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
install: $(EXTERNAL_BOOTLOADERS)
|
||||
$(INSTALL) -d -m 755 "$(DESTDIR)$(TOOLS_LIBDIR)"
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(EXTERNAL_BOOTLOADERS) "$(DESTDIR)$(TOOLS_LIBDIR)"
|
||||
else
|
||||
# Don't generate the dependency files (see `common.mak` for the
|
||||
# `-include $(dependencies_c)` statement).
|
||||
.PHONY: $(dependencies_c)
|
||||
|
||||
clean:
|
||||
rm -f -- *.o *.exec *.bin *.lds .*.lds.d .loaders *.debug
|
||||
$(EMBEDDED_BOOTLOADERS) $(DEBUG_EMBEDDED_BOOTLOADERS) $(EXTERNAL_BOOTLOADERS) $(DEBUG_EXTERNAL_BOOTLOADERS):
|
||||
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||
|
||||
.PHONY: all clean
|
||||
install:
|
||||
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||
endif
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
*
|
||||
* Common ECKD dump I/O functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "cio.h"
|
||||
#include "eckd2dump.h"
|
||||
#include "boot/error.h"
|
||||
@@ -444,6 +446,38 @@ void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count)
|
||||
io_block(cmd, blk, addr, blk_count, 0, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write len/device.blk_size blocks of data at start address starting from
|
||||
* given block and return the next free block number. The len value must be
|
||||
* a multiple of a block size (4096 bytes).
|
||||
*/
|
||||
unsigned long write_addr_range(unsigned long blk, unsigned long start,
|
||||
unsigned long len, int print_progress)
|
||||
{
|
||||
unsigned long addr, start_blk, blk_count, zero_page;
|
||||
|
||||
/* Verify the range is a multiple of a block size */
|
||||
if (len % device.blk_size)
|
||||
panic(EINTERNAL, "Invalid address range: [%016x, %016x]",
|
||||
start, start + len);
|
||||
addr = start;
|
||||
start_blk = blk;
|
||||
while (addr < start + len) {
|
||||
/* Remaining blocks to write */
|
||||
blk_count = m2b(len) - (blk - start_blk);
|
||||
blk_count = MIN(blk_count, eckd_blk_max);
|
||||
zero_page = get_zeroed_page();
|
||||
writeblock(blk, addr, blk_count, zero_page);
|
||||
free_page(zero_page);
|
||||
blk += blk_count;
|
||||
addr += b2m(blk_count);
|
||||
total_dump_size += b2m(blk_count);
|
||||
if (print_progress)
|
||||
progress_print(addr);
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write dump segment with the header to DASD and return the next free
|
||||
* block number
|
||||
@@ -451,28 +485,16 @@ void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count)
|
||||
unsigned long write_dump_segment(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *segm)
|
||||
{
|
||||
unsigned long addr, start_blk, blk_count, zero_page;
|
||||
unsigned long zero_page;
|
||||
|
||||
/* Write the dump segment header itself (1 page) */
|
||||
zero_page = get_zeroed_page();
|
||||
writeblock(blk, (unsigned long)segm, m2b(PAGE_SIZE), zero_page);
|
||||
writeblock(blk, (unsigned long)segm,
|
||||
m2b(sizeof(struct df_s390_dump_segm_hdr)), zero_page);
|
||||
free_page(zero_page);
|
||||
blk += m2b(PAGE_SIZE);
|
||||
/* Write the dump segment */
|
||||
addr = segm->start;
|
||||
start_blk = blk;
|
||||
while (addr < segm->start + segm->len) {
|
||||
/* Remaining blocks to write */
|
||||
blk_count = m2b(segm->len) - (blk - start_blk);
|
||||
blk_count = MIN(blk_count, eckd_blk_max);
|
||||
zero_page = get_zeroed_page();
|
||||
writeblock(blk, addr, blk_count, zero_page);
|
||||
free_page(zero_page);
|
||||
progress_print(addr);
|
||||
blk += blk_count;
|
||||
addr += b2m(blk_count);
|
||||
}
|
||||
return blk;
|
||||
return write_addr_range(blk, segm->start, segm->len, PRINT_PROGRESS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common ECKD dump I/O functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef ECKD2DUMP_H
|
||||
#define ECKD2DUMP_H
|
||||
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "cio.h"
|
||||
#include "stage2dump.h"
|
||||
|
||||
@@ -49,5 +51,9 @@ void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_count,
|
||||
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
|
||||
unsigned long write_dump_segment(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *segm);
|
||||
#define NO_PROGRESS 0
|
||||
#define PRINT_PROGRESS 1
|
||||
unsigned long write_addr_range(unsigned long blk, unsigned long addr,
|
||||
unsigned long len, int print_progress);
|
||||
|
||||
#endif /* ECKD2DUMP_H */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Multi-volume ECKD DASD dump tool
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/error.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "eckd2dump.h"
|
||||
#include "stage2dump.h"
|
||||
@@ -268,7 +269,6 @@ static unsigned long write_volume(unsigned long addr,
|
||||
/* Reserve one block for the next segment header */
|
||||
if (free_space)
|
||||
free_space -= b2m(1);
|
||||
total_dump_size += dump_segm->len;
|
||||
/* Check if no more dump segments follow */
|
||||
if (dump_segm->stop_marker) {
|
||||
/* Write end marker */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Single-volume ECKD DASD dump tool
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -12,14 +12,16 @@
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/boot_defs.h"
|
||||
#include "boot/error.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "eckd2dump.h"
|
||||
#include "eckd2dump_zlib.h"
|
||||
#include "stage2dump.h"
|
||||
|
||||
/*
|
||||
* Magic number at start of dump record
|
||||
*/
|
||||
const uint64_t __section(.stage2.head) magic = 0x5845434b44363401ULL; /* "XECKD64", version 1 */
|
||||
const uint64_t __section(.stage2.head) magic = 0x5845434b44363402ULL; /* "XECKD64", version 2 */
|
||||
|
||||
/*
|
||||
* Get device characteristics from zipl parameter block
|
||||
@@ -46,40 +48,113 @@ void dt_device_enable(void)
|
||||
stage2dump_eckd_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump all memory to DASD partition
|
||||
*/
|
||||
void dt_dump_mem(void)
|
||||
static unsigned long dt_dump_mem_non_compressed(unsigned long addr,
|
||||
unsigned long blk)
|
||||
{
|
||||
unsigned long blk, addr, end, page;
|
||||
struct df_s390_dump_segm_hdr *dump_segm;
|
||||
unsigned long end;
|
||||
|
||||
blk = device.blk_start;
|
||||
dump_segm = (void *)get_zeroed_page();
|
||||
|
||||
/* Write dump header */
|
||||
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += m2b(DF_S390_HDR_SIZE);
|
||||
|
||||
/* Write memory */
|
||||
addr = 0;
|
||||
total_dump_size = 0;
|
||||
/* Write memory uncompressed */
|
||||
end = dump_hdr->mem_size;
|
||||
while (addr < end) {
|
||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||
blk = write_dump_segment(blk, dump_segm);
|
||||
total_dump_size += dump_segm->len;
|
||||
if (dump_segm->stop_marker) {
|
||||
addr = end;
|
||||
if (dump_segm->start + dump_segm->len < end)
|
||||
progress_print(addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free_page(__pa(dump_segm));
|
||||
progress_print(addr);
|
||||
return blk;
|
||||
}
|
||||
|
||||
static unsigned long dt_dump_mem_compressed(unsigned long addr,
|
||||
unsigned long blk)
|
||||
{
|
||||
struct df_s390_dump_segm_hdr *dump_segm;
|
||||
unsigned long end;
|
||||
z_stream strm;
|
||||
|
||||
/* Write memory compressed with zlib deflate */
|
||||
dump_segm = (void *)get_zeroed_page();
|
||||
end = dump_hdr->mem_size;
|
||||
/*
|
||||
* Always write first megabyte of memory uncompressed in
|
||||
* order to use it as zlib workarea
|
||||
*/
|
||||
dump_segm->start = addr;
|
||||
dump_segm->len = ZLIB_WORKSPACE_LIMIT;
|
||||
blk = write_dump_segment(blk, dump_segm);
|
||||
addr += dump_segm->len;
|
||||
/* Initialize zlib workarea, return value 0 is expected */
|
||||
if (zlib_workarea_init(dump_segm->start, &strm)) {
|
||||
printf("Zlib workarea initialization failed! Dumping without compression");
|
||||
free_page(__pa(dump_segm));
|
||||
return dt_dump_mem_non_compressed(addr, blk);
|
||||
}
|
||||
/*
|
||||
* Compress on level 1 (hardware only) using default zlib
|
||||
* wrapped stream.
|
||||
*/
|
||||
if (zlib_deflateInit2(&strm, 1, Z_DEFLATED, MAX_WBITS,
|
||||
DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) {
|
||||
/*
|
||||
* Could not allocate or initialyze a workarea for zlib deflate,
|
||||
* continue dumping without compression.
|
||||
*/
|
||||
printf("Deflate initialization failed! Dumping without compression");
|
||||
free_page(__pa(dump_segm));
|
||||
return dt_dump_mem_non_compressed(addr, blk);
|
||||
}
|
||||
while (addr < end) {
|
||||
/*
|
||||
* Limit the max size of compressed dump segment in order to
|
||||
* fit all the compressed chunk entries in the segment header.
|
||||
*/
|
||||
addr = find_dump_segment(addr, end, DUMP_SEGM_ZLIB_MAXLEN,
|
||||
dump_segm);
|
||||
blk = write_compressed_dump_segment(blk, dump_segm, &strm);
|
||||
if (dump_segm->stop_marker) {
|
||||
addr = end;
|
||||
if (dump_segm->start + dump_segm->len < end)
|
||||
progress_print(addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
zlib_deflateEnd(&strm);
|
||||
free_page(__pa(dump_segm));
|
||||
return blk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump all memory to DASD partition.
|
||||
* Use zlib compression if DFLTCC facility is available.
|
||||
*/
|
||||
void dt_dump_mem(void)
|
||||
{
|
||||
unsigned long blk, start, page;
|
||||
|
||||
total_dump_size = 0;
|
||||
/* Write dump header */
|
||||
blk = device.blk_start;
|
||||
writeblock(blk, __pa(dump_hdr), m2b(DF_S390_HDR_SIZE), 0);
|
||||
blk += m2b(DF_S390_HDR_SIZE);
|
||||
/* Write memory starting from zero address */
|
||||
start = 0;
|
||||
/* Check for zlib flag in the dump header */
|
||||
if (dump_hdr->zlib_version_s390) {
|
||||
printf("DFLTCC facility available, using zlib compression");
|
||||
blk = dt_dump_mem_compressed(start, blk);
|
||||
} else {
|
||||
blk = dt_dump_mem_non_compressed(start, blk);
|
||||
}
|
||||
/* Write end marker */
|
||||
page = get_zeroed_page();
|
||||
df_s390_em_page_init(page);
|
||||
writeblock(blk, page, 1, 0);
|
||||
blk++;
|
||||
free_page(page);
|
||||
}
|
||||
|
||||
76
zipl/boot/eckd2dump_sv.lds.S
Normal file
76
zipl/boot/eckd2dump_sv.lds.S
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Memory layout of stage 2 for single volume dasd
|
||||
* dump tool with compression support
|
||||
* ===============================================
|
||||
*
|
||||
* General memory layout
|
||||
* ---------------------
|
||||
*
|
||||
* 0x0000-0x1fff Lowcore
|
||||
* 0x2000-0x9fff Sections (load): head, text, data, rodata, rodata.str
|
||||
* 0xa000-0xafff Sections: bss
|
||||
* 0xb000-0xdfff Memory allocation (heap)
|
||||
* 0xe000-0xffff Stack
|
||||
*
|
||||
* Special memory locations
|
||||
* ------------------------
|
||||
*
|
||||
* 0x78 Stage 2 description parameters
|
||||
* 0x2018 Stage 2 entry point
|
||||
* 0x9ff8 Max mem dump parameter
|
||||
*/
|
||||
|
||||
#include "boot/loaders_layout.h"
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = STAGE2_DESC;
|
||||
__stage2_desc = .;
|
||||
|
||||
. = STAGE2_LOAD_ADDRESS;
|
||||
.stage2.head : { *(.stage2.head) }
|
||||
. = STAGE2_ENTRY;
|
||||
.text.start : {
|
||||
*(.text.start)
|
||||
}
|
||||
.text : { *(.text) }
|
||||
__ex_table_start = .;
|
||||
.ex_table : { *(.ex_table) }
|
||||
__ex_table_stop = .;
|
||||
.rodata : {*(.rodata) }
|
||||
.data : { *(.data) }
|
||||
__stage2_params = .;
|
||||
|
||||
. = 0x9ff0;
|
||||
.stage2dump.tail : { *(.stage2dump.tail) }
|
||||
|
||||
. = 0xa000;
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
__bss_stop = .;
|
||||
|
||||
. = ECKD2DUMP_SV_HEAP_ADDRESS;
|
||||
__heap_start = .;
|
||||
.heap : {
|
||||
. += STAGE2_HEAP_SIZE;
|
||||
ASSERT(__heap_stop - __heap_start == STAGE2_HEAP_SIZE,
|
||||
"Heap section doesn't conform to the described memory layout");
|
||||
}
|
||||
__heap_stop = .;
|
||||
|
||||
. = ECKD2DUMP_SV_STACK_ADDRESS;
|
||||
__stack_start = .;
|
||||
.stack : {
|
||||
. += ECKD2DUMP_SV_STACK_SIZE;
|
||||
ASSERT(__stack_end - __stack_start == ECKD2DUMP_SV_STACK_SIZE,
|
||||
"Stack section doesn't conform to the described memory layout");
|
||||
}
|
||||
__stack_end = .;
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
}
|
||||
183
zipl/boot/eckd2dump_zlib.c
Normal file
183
zipl/boot/eckd2dump_zlib.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* zipl - zSeries Initial Program Loader tool
|
||||
*
|
||||
* Common ECKD dump I/O functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "cio.h"
|
||||
#include "eckd2dump.h"
|
||||
#include "eckd2dump_zlib.h"
|
||||
#include "boot/linux_layout.h"
|
||||
#include "boot/s390.h"
|
||||
#include "stage2dump.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
/*
|
||||
* The first megabyte of memory is used for zlib workspace and
|
||||
* the output buffer for compressed data.
|
||||
*/
|
||||
static void *zlib_out_buf; // zlib output buffer
|
||||
static unsigned long zlib_buf_size; // zlib output buffer size
|
||||
|
||||
/* Zlib workspace memory offset (skipping first 64K for the dumper itself) */
|
||||
#define ZLIB_WORKSPACE_OFFSET IMAGE_ENTRY
|
||||
|
||||
/*
|
||||
* Zlib workspace initialization.
|
||||
* Return -1 if zlib deflate workspace requires more than half of the
|
||||
* reserved memory area. Otherwise return 0.
|
||||
*/
|
||||
int zlib_workarea_init(unsigned long addr, z_stream *strm)
|
||||
{
|
||||
strm->workspace = (void *)MAX(addr, ZLIB_WORKSPACE_OFFSET);
|
||||
zlib_out_buf = (void *)ROUND_UP((unsigned long)strm->workspace +
|
||||
zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
|
||||
PAGE_SIZE);
|
||||
/* Make sure there is enough space left for zlib output buffer (at least half) */
|
||||
if ((unsigned long)(zlib_out_buf - strm->workspace) > ZLIB_WORKSPACE_LIMIT / 2)
|
||||
return -1;
|
||||
/* Memory left for zlib output buffer (currently 692K) */
|
||||
zlib_buf_size = addr + ZLIB_WORKSPACE_LIMIT - (unsigned long)zlib_out_buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define COMPRESSED 0
|
||||
#define UNCOMPRESSED 1
|
||||
#define COMPRESSION_ERROR -1
|
||||
|
||||
/*
|
||||
* Compress chunk of data of given length at the given address using zlib
|
||||
* deflate compression and write it starting from the given block number.
|
||||
* Variable *blk is updated to the next free block number.
|
||||
* Return 0 if memory chunk is successfully compressed and written.
|
||||
* Return 1 if compression is ineffective and the entire chunk is written
|
||||
* uncompressed.
|
||||
* In case of deflate error, write the chunk uncompressed and return -1
|
||||
*/
|
||||
static int compress_write_next_chunk(unsigned long addr, unsigned long len,
|
||||
unsigned long *blk, z_stream *strm)
|
||||
{
|
||||
unsigned long start_blk;
|
||||
int rc;
|
||||
|
||||
/* Reset the stream for each new chunk */
|
||||
zlib_deflateReset(strm);
|
||||
strm->next_in = (void *)addr;
|
||||
strm->avail_in = len;
|
||||
strm->next_out = zlib_out_buf;
|
||||
strm->avail_out = zlib_buf_size;
|
||||
start_blk = *blk;
|
||||
while (strm->avail_in != 0) {
|
||||
rc = zlib_deflate(strm, Z_NO_FLUSH);
|
||||
/*
|
||||
* Compression error. Write this data chunk uncompressed and
|
||||
* notify the caller.
|
||||
*/
|
||||
if (rc != Z_OK) {
|
||||
*blk = write_addr_range(start_blk, addr, len, NO_PROGRESS);
|
||||
return COMPRESSION_ERROR;
|
||||
}
|
||||
if (strm->avail_out == 0) {
|
||||
/*
|
||||
* If compressed output is larger than the input, write this chunk of
|
||||
* data uncompressed and notify the caller with the return code.
|
||||
* Do it only if no compressed output has been written yet.
|
||||
*/
|
||||
if (strm->total_out >= strm->total_in &&
|
||||
*blk == start_blk) {
|
||||
*blk = write_addr_range(start_blk, addr, len, NO_PROGRESS);
|
||||
return UNCOMPRESSED;
|
||||
}
|
||||
*blk = write_addr_range(*blk, (unsigned long)zlib_out_buf,
|
||||
zlib_buf_size, NO_PROGRESS);
|
||||
strm->next_out = (void *)zlib_out_buf;
|
||||
strm->avail_out = zlib_buf_size;
|
||||
}
|
||||
}
|
||||
while (rc == Z_OK) {
|
||||
strm->next_in = NULL;
|
||||
strm->avail_in = 0;
|
||||
rc = zlib_deflate(strm, Z_FINISH);
|
||||
len = ROUND_UP(zlib_buf_size - strm->avail_out, PAGE_SIZE);
|
||||
*blk = write_addr_range(*blk, (unsigned long)zlib_out_buf, len, NO_PROGRESS);
|
||||
if (strm->avail_out == 0) {
|
||||
strm->next_out = zlib_out_buf;
|
||||
strm->avail_out = zlib_buf_size;
|
||||
rc = Z_OK;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return COMPRESSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compress and write memory dump segment with the uncompressed header to DASD
|
||||
* and return the next free block number.
|
||||
* The compression takes place in chunks of data of equal size (currently 1MB)
|
||||
* and the offset of each compressed chunk is stored in the dump segment
|
||||
* header. Due to limited size of header, the maximum size of compressed dump
|
||||
* segment is limited to DUMP_SEGM_ZLIB_MAXLEN.
|
||||
* If compression of a memory chunk leads to the data expansion (due to
|
||||
* incompressible input), the chunk of data is written uncompressed.
|
||||
* Thus every chunk of data is compressed separately and can be
|
||||
* decompressed independently. The main reason is to enable zgetdump to make
|
||||
* fast read seeks. Otherwise, zgetdump would need to uncompress a big dump
|
||||
* segment in the worst case to extract a single piece of data.
|
||||
*/
|
||||
unsigned long write_compressed_dump_segment(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *segm,
|
||||
z_stream *strm)
|
||||
{
|
||||
unsigned long head_blk, start_blk, zero_page, len, offset = 0;
|
||||
unsigned long chunk_size;
|
||||
int rc;
|
||||
|
||||
head_blk = blk;
|
||||
/* Skip one block for the header (written later on) */
|
||||
blk += m2b(sizeof(struct df_s390_dump_segm_hdr));
|
||||
/* Compress each data chunk of the dump segment separately */
|
||||
chunk_size = dump_hdr->zlib_entry_size;
|
||||
for (unsigned int i = 0; i <= segm->len / chunk_size; i++) {
|
||||
/* Save starting block number */
|
||||
start_blk = blk;
|
||||
len = i < segm->len / chunk_size ?
|
||||
chunk_size : segm->len % chunk_size;
|
||||
if (len == 0)
|
||||
break;
|
||||
rc = compress_write_next_chunk(segm->start + i * chunk_size,
|
||||
len, &blk, strm);
|
||||
/*
|
||||
* Store the offset to the compressed chunk of data written
|
||||
* to disk in blocks.
|
||||
*/
|
||||
segm->entry_count++;
|
||||
segm->entry_offset[i] = (uint32_t)offset;
|
||||
/*
|
||||
* Compression was ineffective or compression error ocurred,
|
||||
* data chunk has benn written uncompressed.
|
||||
*/
|
||||
if (rc == UNCOMPRESSED || rc == COMPRESSION_ERROR)
|
||||
segm->entry_offset[i] |= DUMP_SEGM_ENTRY_UNCOMPRESSED;
|
||||
offset += blk - start_blk;
|
||||
/* Print progress after each compressed chunk written */
|
||||
progress_print(segm->start + i * chunk_size + len);
|
||||
}
|
||||
/* Compression successful, store compressed size in the segment header */
|
||||
segm->size_on_disk = (uint32_t)offset;
|
||||
/*
|
||||
* Write the dump segment header itself (1 page, uncompressed) to
|
||||
* the predefined location.
|
||||
*/
|
||||
zero_page = get_zeroed_page();
|
||||
writeblock(head_blk, (unsigned long)segm,
|
||||
m2b(sizeof(struct df_s390_dump_segm_hdr)), zero_page);
|
||||
free_page(zero_page);
|
||||
|
||||
return blk;
|
||||
}
|
||||
25
zipl/boot/eckd2dump_zlib.h
Normal file
25
zipl/boot/eckd2dump_zlib.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* zipl - zSeries Initial Program Loader tool
|
||||
*
|
||||
* Common ECKD dump I/O functions for zlib compression support
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
#ifndef ECKD2DUMP_ZLIB_H
|
||||
#define ECKD2DUMP_ZLIB_H
|
||||
|
||||
#include "zlib/zlib.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#define ZLIB_WORKSPACE_LIMIT (1 * MIB)
|
||||
|
||||
/* Compression related functions */
|
||||
int zlib_workarea_init(unsigned long addr, z_stream *strm);
|
||||
unsigned long write_compressed_dump_segment(unsigned long blk,
|
||||
struct df_s390_dump_segm_hdr *segm,
|
||||
z_stream *strm);
|
||||
|
||||
#endif /* ECKD2DUMP_ZLIB_H */
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Single-volume FBA DASD dump tool
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/boot_defs.h"
|
||||
#include "boot/error.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "fba.h"
|
||||
#include "stage2dump.h"
|
||||
@@ -152,9 +153,10 @@ unsigned long write_dump_segment_fba(unsigned long blk,
|
||||
zero_page = get_zeroed_page();
|
||||
writeblock_fba(blk, addr, blk_count, zero_page);
|
||||
free_page(zero_page);
|
||||
progress_print(addr);
|
||||
blk += blk_count;
|
||||
addr += b2m(blk_count);
|
||||
total_dump_size += b2m(blk_count);
|
||||
progress_print(addr);
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
@@ -206,7 +208,6 @@ void dt_dump_mem(void)
|
||||
while (addr < end) {
|
||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||
blk = write_dump_segment_fba(blk, dump_segm);
|
||||
total_dump_size += dump_segm->len;
|
||||
if (dump_segm->stop_marker) {
|
||||
addr = end;
|
||||
break;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common functions for stand-alone dump tools
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -13,12 +13,14 @@
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/error.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "libc.h"
|
||||
#include "sclp.h"
|
||||
#include "stage2dump.h"
|
||||
#include "boot/ipl.h"
|
||||
#include "boot/os_info.h"
|
||||
#include "boot/s390.h"
|
||||
|
||||
#define CPU_ADDRESS_MAX 1000
|
||||
#define MACHINE_HAS_VX machine_has_vx
|
||||
@@ -72,7 +74,6 @@ void progress_print(unsigned long addr)
|
||||
}
|
||||
if (time < next && addr != dump_hdr->mem_size)
|
||||
return;
|
||||
|
||||
printf("%08lu / %08lu MB (Dump file size %08lu MB)", addr >> 20,
|
||||
dump_hdr->mem_size >> 20, total_dump_size >> 20);
|
||||
next = time + delta;
|
||||
@@ -215,13 +216,23 @@ static void df_s390_dump_init(void)
|
||||
dh->hdr_size = DF_S390_HDR_SIZE;
|
||||
dh->page_size = PAGE_SIZE;
|
||||
dh->dump_level = 4;
|
||||
dh->version = 1;
|
||||
dh->version = 2;
|
||||
dh->mem_start = 0;
|
||||
dh->arch = DF_S390_ARCH_64;
|
||||
dh->build_arch = DF_S390_ARCH_64;
|
||||
get_cpu_id((struct cpuid *) &dh->cpu_id);
|
||||
dh->tod = get_tod_clock();
|
||||
dh->volnr = 0;
|
||||
dh->zlib_version_s390 = 0;
|
||||
/*
|
||||
* Ignore compression if --no-compress attribute has been specified
|
||||
* or DFLTCC facility not available.
|
||||
*/
|
||||
if (test_facility(DFLTCC_FACILITY) &&
|
||||
parm_tail.no_compress == 0) {
|
||||
dh->zlib_version_s390 = 1; /* Indicate interlnal Zlib version */
|
||||
dh->zlib_entry_size = DUMP_SEGM_ZLIB_ENTSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -444,10 +455,15 @@ void __noreturn start(void)
|
||||
init_early();
|
||||
dt_device_parm_setup();
|
||||
sclp_setup(SCLP_INIT);
|
||||
/* Store facility-list for future checks */
|
||||
stfle(S390_lowcore.stfle_fac_list,
|
||||
ARRAY_SIZE(S390_lowcore.stfle_fac_list));
|
||||
dt_device_enable();
|
||||
df_s390_dump_init();
|
||||
printf("zIPL v%s dump tool (64 bit)", RELEASE_STRING);
|
||||
printf("Dumping 64 bit OS");
|
||||
if (parm_tail.no_compress)
|
||||
printf("Dump compression prevented by the --no-compress attribute");
|
||||
mem_and_cpu_init();
|
||||
store_status();
|
||||
dt_dump_mem();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Common dump functions
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -12,90 +12,16 @@
|
||||
#ifndef STAGE2DUMP_H
|
||||
#define STAGE2DUMP_H
|
||||
|
||||
#include "libc.h"
|
||||
#include "boot/s390.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#define IPL_SC S390_lowcore.tpi_info.schid
|
||||
#define ROUND_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1))
|
||||
#define ROUND_UP(x, a) ROUND_DOWN((x) + (typeof(x))(a) - 1, a)
|
||||
#define IS_ALIGNED(x, a) ~((x) & ((typeof(x))(a) - 1))
|
||||
|
||||
/*
|
||||
* zipl parameters passed at tail of dump tools
|
||||
*/
|
||||
struct stage2dump_parm_tail {
|
||||
char reserved[6];
|
||||
uint16_t mvdump_force;
|
||||
uint64_t mem_upper_limit;
|
||||
} __packed;
|
||||
|
||||
extern struct stage2dump_parm_tail __section(.stage2dump.tail) parm_tail;
|
||||
|
||||
/*
|
||||
* S390 dump format defines
|
||||
*/
|
||||
#define DF_S390_MAGIC 0xa8190173618f23fdULL
|
||||
#define DF_S390_MAGIC_EXT 0xa8190173618f23feULL
|
||||
#define DF_S390_HDR_SIZE 0x1000
|
||||
#define DF_S390_EM_SIZE 16
|
||||
#define DF_S390_EM_MAGIC 0x44554d505f454e44ULL
|
||||
#define DF_S390_CPU_MAX 512
|
||||
#define DF_S390_MAGIC_BLK_ECKD 3
|
||||
|
||||
/*
|
||||
* Architecture of dumped system
|
||||
*/
|
||||
enum df_s390_arch {
|
||||
DF_S390_ARCH_32 = 1,
|
||||
DF_S390_ARCH_64 = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* s390 dump header format
|
||||
*/
|
||||
struct df_s390_hdr {
|
||||
uint64_t magic; /* 0x000 */
|
||||
uint32_t version; /* 0x008 */
|
||||
uint32_t hdr_size; /* 0x00c */
|
||||
uint32_t dump_level; /* 0x010 */
|
||||
uint32_t page_size; /* 0x014 */
|
||||
uint64_t mem_size; /* 0x018 */
|
||||
uint64_t mem_start; /* 0x020 */
|
||||
uint64_t mem_end; /* 0x028 */
|
||||
uint32_t num_pages; /* 0x030 */
|
||||
uint32_t pad; /* 0x034 */
|
||||
uint64_t tod; /* 0x038 */
|
||||
uint64_t cpu_id; /* 0x040 */
|
||||
uint32_t arch; /* 0x048 */
|
||||
uint32_t volnr; /* 0x04c */
|
||||
uint32_t build_arch; /* 0x050 */
|
||||
uint64_t mem_size_real; /* 0x054 */
|
||||
uint8_t mvdump; /* 0x05c */
|
||||
uint16_t cpu_cnt; /* 0x05d */
|
||||
uint16_t real_cpu_cnt; /* 0x05f */
|
||||
uint8_t end_pad1[0x200-0x061]; /* 0x061 */
|
||||
uint64_t mvdump_sign; /* 0x200 */
|
||||
uint64_t mvdump_zipl_time; /* 0x208 */
|
||||
uint8_t end_pad2[0x800-0x210]; /* 0x210 */
|
||||
uint32_t lc_vec[DF_S390_CPU_MAX]; /* 0x800 */
|
||||
} __packed __aligned(16);
|
||||
|
||||
/*
|
||||
* End marker: Should be at the end of every valid s390 crash dump
|
||||
*/
|
||||
struct df_s390_em {
|
||||
uint64_t magic;
|
||||
uint64_t tod;
|
||||
} __packed __aligned(16);
|
||||
|
||||
/*
|
||||
* Dump segment header
|
||||
*/
|
||||
struct df_s390_dump_segm_hdr {
|
||||
uint64_t start;
|
||||
uint64_t len;
|
||||
uint64_t stop_marker;
|
||||
};
|
||||
|
||||
/*
|
||||
* Linker script defined symbols
|
||||
*/
|
||||
@@ -113,7 +39,6 @@ extern unsigned long total_dump_size;
|
||||
*/
|
||||
void create_ida_list(unsigned long *list, int len, unsigned long addr,
|
||||
unsigned long zero_page);
|
||||
void init_progress_print(void);
|
||||
void progress_print(unsigned long addr);
|
||||
void df_s390_em_page_init(unsigned long page);
|
||||
void pgm_check_handler(void);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Dump tool for channel-attached tape devices
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2023
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "boot/error.h"
|
||||
#include "boot/loaders_layout.h"
|
||||
#include "boot/s390.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "cio.h"
|
||||
#include "stage2dump.h"
|
||||
@@ -205,13 +206,14 @@ void dt_dump_mem(void)
|
||||
setup_idrc_compression();
|
||||
ccw_write_tapemark();
|
||||
|
||||
total_dump_size = 0;
|
||||
ccw_write_block((unsigned long) dump_hdr, DF_S390_HDR_SIZE, 0);
|
||||
for (addr = 0; addr < dump_hdr->mem_size; addr += BLK_SIZE) {
|
||||
ccw_write_block(addr, BLK_SIZE, page);
|
||||
progress_print(addr);
|
||||
progress_print_disp(addr);
|
||||
total_dump_size += BLK_SIZE;
|
||||
progress_print(addr + BLK_SIZE);
|
||||
progress_print_disp(addr + BLK_SIZE);
|
||||
}
|
||||
progress_print(addr);
|
||||
df_s390_em_page_init(page);
|
||||
ccw_write_block(page, sizeof(struct df_s390_em), 0);
|
||||
free_page(page);
|
||||
|
||||
1152
zipl/boot/zlib/deflate.c
Normal file
1152
zipl/boot/zlib/deflate.c
Normal file
File diff suppressed because it is too large
Load Diff
1058
zipl/boot/zlib/deftree.c
Normal file
1058
zipl/boot/zlib/deftree.c
Normal file
File diff suppressed because it is too large
Load Diff
446
zipl/boot/zlib/defutil.h
Normal file
446
zipl/boot/zlib/defutil.h
Normal file
@@ -0,0 +1,446 @@
|
||||
#ifndef DEFUTIL_H
|
||||
#define DEFUTIL_H
|
||||
|
||||
#include "zlib/zutil.h"
|
||||
#include "../libc.h"
|
||||
|
||||
#define Assert(err, str)
|
||||
#define Trace(dummy)
|
||||
#define Tracev(dummy)
|
||||
#define Tracecv(err, dummy)
|
||||
#define Tracevv(dummy)
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
|
||||
#define max(a, b) MAX(a, b)
|
||||
|
||||
#define LENGTH_CODES 29
|
||||
/* number of length codes, not counting the special END_BLOCK code */
|
||||
|
||||
#define LITERALS 256
|
||||
/* number of literal bytes 0..255 */
|
||||
|
||||
#define L_CODES (LITERALS+1+LENGTH_CODES)
|
||||
/* number of Literal or Length codes, including the END_BLOCK code */
|
||||
|
||||
#define D_CODES 30
|
||||
/* number of distance codes */
|
||||
|
||||
#define BL_CODES 19
|
||||
/* number of codes used to transfer the bit lengths */
|
||||
|
||||
#define HEAP_SIZE (2*L_CODES+1)
|
||||
/* maximum heap size */
|
||||
|
||||
#define MAX_BITS 15
|
||||
/* All codes must not exceed MAX_BITS bits */
|
||||
|
||||
#define INIT_STATE 42
|
||||
#define BUSY_STATE 113
|
||||
#define FINISH_STATE 666
|
||||
/* Stream status */
|
||||
|
||||
|
||||
/* Data structure describing a single value and its code string. */
|
||||
typedef struct ct_data_s {
|
||||
union {
|
||||
ush freq; /* frequency count */
|
||||
ush code; /* bit string */
|
||||
} fc;
|
||||
union {
|
||||
ush dad; /* father node in Huffman tree */
|
||||
ush len; /* length of bit string */
|
||||
} dl;
|
||||
} ct_data;
|
||||
|
||||
#define Freq fc.freq
|
||||
#define Code fc.code
|
||||
#define Dad dl.dad
|
||||
#define Len dl.len
|
||||
|
||||
typedef struct static_tree_desc_s static_tree_desc;
|
||||
|
||||
typedef struct tree_desc_s {
|
||||
ct_data *dyn_tree; /* the dynamic tree */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
static_tree_desc *stat_desc; /* the corresponding static tree */
|
||||
} tree_desc;
|
||||
|
||||
typedef ush Pos;
|
||||
typedef unsigned IPos;
|
||||
|
||||
/* A Pos is an index in the character window. We use short instead of int to
|
||||
* save space in the various tables. IPos is used only for parameter passing.
|
||||
*/
|
||||
|
||||
typedef struct deflate_state {
|
||||
z_streamp strm; /* pointer back to this zlib stream */
|
||||
int status; /* as the name implies */
|
||||
Byte *pending_buf; /* output still pending */
|
||||
ulg pending_buf_size; /* size of pending_buf */
|
||||
Byte *pending_out; /* next pending byte to output to the stream */
|
||||
int pending; /* nb of bytes in the pending buffer */
|
||||
int noheader; /* suppress zlib header and adler32 */
|
||||
Byte data_type; /* UNKNOWN, BINARY or ASCII */
|
||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
|
||||
uInt w_size; /* LZ77 window size (32K by default) */
|
||||
uInt w_bits; /* log2(w_size) (8..16) */
|
||||
uInt w_mask; /* w_size - 1 */
|
||||
|
||||
Byte *window;
|
||||
/* Sliding window. Input bytes are read into the second half of the window,
|
||||
* and move to the first half later to keep a dictionary of at least wSize
|
||||
* bytes. With this organization, matches are limited to a distance of
|
||||
* wSize-MAX_MATCH bytes, but this ensures that IO is always
|
||||
* performed with a length multiple of the block size. Also, it limits
|
||||
* the window size to 64K, which is quite useful on MSDOS.
|
||||
* To do: use the user input buffer as sliding window.
|
||||
*/
|
||||
|
||||
ulg window_size;
|
||||
/* Actual size of window: 2*wSize, except when the user input buffer
|
||||
* is directly used as sliding window.
|
||||
*/
|
||||
|
||||
Pos *prev;
|
||||
/* Link to older string with same hash index. To limit the size of this
|
||||
* array to 64K, this link is maintained only for the last 32K strings.
|
||||
* An index in this array is thus a window index modulo 32K.
|
||||
*/
|
||||
|
||||
Pos *head; /* Heads of the hash chains or NIL. */
|
||||
|
||||
uInt ins_h; /* hash index of string to be inserted */
|
||||
uInt hash_size; /* number of elements in hash table */
|
||||
uInt hash_bits; /* log2(hash_size) */
|
||||
uInt hash_mask; /* hash_size-1 */
|
||||
|
||||
uInt hash_shift;
|
||||
/* Number of bits by which ins_h must be shifted at each input
|
||||
* step. It must be such that after MIN_MATCH steps, the oldest
|
||||
* byte no longer takes part in the hash key, that is:
|
||||
* hash_shift * MIN_MATCH >= hash_bits
|
||||
*/
|
||||
|
||||
long block_start;
|
||||
/* Window position at the beginning of the current output block. Gets
|
||||
* negative when the window is moved backwards.
|
||||
*/
|
||||
|
||||
uInt match_length; /* length of best match */
|
||||
IPos prev_match; /* previous match */
|
||||
int match_available; /* set if previous match exists */
|
||||
uInt strstart; /* start of string to insert */
|
||||
uInt match_start; /* start of matching string */
|
||||
uInt lookahead; /* number of valid bytes ahead in window */
|
||||
|
||||
uInt prev_length;
|
||||
/* Length of the best match at previous step. Matches not greater than this
|
||||
* are discarded. This is used in the lazy match evaluation.
|
||||
*/
|
||||
|
||||
uInt max_chain_length;
|
||||
/* To speed up deflation, hash chains are never searched beyond this
|
||||
* length. A higher limit improves compression ratio but degrades the
|
||||
* speed.
|
||||
*/
|
||||
|
||||
uInt max_lazy_match;
|
||||
/* Attempt to find a better match only when the current match is strictly
|
||||
* smaller than this value. This mechanism is used only for compression
|
||||
* levels >= 4.
|
||||
*/
|
||||
# define max_insert_length max_lazy_match
|
||||
/* Insert new strings in the hash table only if the match length is not
|
||||
* greater than this length. This saves time but degrades compression.
|
||||
* max_insert_length is used only for compression levels <= 3.
|
||||
*/
|
||||
|
||||
int level; /* compression level (1..9) */
|
||||
int strategy; /* favor or force Huffman coding*/
|
||||
|
||||
uInt good_match;
|
||||
/* Use a faster search when the previous match is longer than this */
|
||||
|
||||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||
|
||||
struct tree_desc_s l_desc; /* desc. for literal tree */
|
||||
struct tree_desc_s d_desc; /* desc. for distance tree */
|
||||
struct tree_desc_s bl_desc; /* desc. for bit length tree */
|
||||
|
||||
ush bl_count[MAX_BITS+1];
|
||||
/* number of codes at each bit length for an optimal tree */
|
||||
|
||||
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
|
||||
int heap_len; /* number of elements in the heap */
|
||||
int heap_max; /* element of largest frequency */
|
||||
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
|
||||
* The same heap array is used to build all trees.
|
||||
*/
|
||||
|
||||
uch depth[2*L_CODES+1];
|
||||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||||
*/
|
||||
|
||||
uch *l_buf; /* buffer for literals or lengths */
|
||||
|
||||
uInt lit_bufsize;
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
* limiting lit_bufsize to 64K:
|
||||
* - frequencies can be kept in 16 bit counters
|
||||
* - if compression is not successful for the first block, all input
|
||||
* data is still in the window so we can still emit a stored block even
|
||||
* when input comes from standard input. (This can also be done for
|
||||
* all blocks if lit_bufsize is not greater than 32K.)
|
||||
* - if compression is not successful for a file smaller than 64K, we can
|
||||
* even emit a stored file instead of a stored block (saving 5 bytes).
|
||||
* This is applicable only for zip (not gzip or zlib).
|
||||
* - creating new Huffman trees less frequently may not provide fast
|
||||
* adaptation to changes in the input data statistics. (Take for
|
||||
* example a binary file with poorly compressible code followed by
|
||||
* a highly compressible string table.) Smaller buffer sizes give
|
||||
* fast adaptation but have of course the overhead of transmitting
|
||||
* trees more frequently.
|
||||
* - I can't count above 4
|
||||
*/
|
||||
|
||||
uInt last_lit; /* running index in l_buf */
|
||||
|
||||
ush *d_buf;
|
||||
/* Buffer for distances. To simplify the code, d_buf and l_buf have
|
||||
* the same number of elements. To use different lengths, an extra flag
|
||||
* array would be necessary.
|
||||
*/
|
||||
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
ulg compressed_len; /* total bit length of compressed file */
|
||||
uInt matches; /* number of string matches in current block */
|
||||
int last_eob_len; /* bit length of EOB code for last block */
|
||||
|
||||
#ifdef DEBUG_ZLIB
|
||||
ulg bits_sent; /* bit length of the compressed data */
|
||||
#endif
|
||||
|
||||
ush bi_buf;
|
||||
/* Output buffer. bits are inserted starting at the bottom (least
|
||||
* significant bits).
|
||||
*/
|
||||
int bi_valid;
|
||||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||||
* are always zero.
|
||||
*/
|
||||
|
||||
} deflate_state;
|
||||
|
||||
#ifdef CONFIG_ZLIB_DFLTCC
|
||||
#define zlib_deflate_window_memsize(windowBits) \
|
||||
(2 * (1 << (windowBits)) * sizeof(Byte) + PAGE_SIZE)
|
||||
#else
|
||||
#define zlib_deflate_window_memsize(windowBits) \
|
||||
(2 * (1 << (windowBits)) * sizeof(Byte))
|
||||
#endif
|
||||
#define zlib_deflate_prev_memsize(windowBits) \
|
||||
((1 << (windowBits)) * sizeof(Pos))
|
||||
#define zlib_deflate_head_memsize(memLevel) \
|
||||
((1 << ((memLevel)+7)) * sizeof(Pos))
|
||||
#define zlib_deflate_overlay_memsize(memLevel) \
|
||||
((1 << ((memLevel)+6)) * (sizeof(ush)+2))
|
||||
|
||||
/* Output a byte on the stream.
|
||||
* IN assertion: there is enough room in pending_buf.
|
||||
*/
|
||||
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
|
||||
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
|
||||
/* In order to simplify the code, particularly on 16 bit machines, match
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
/* in trees.c */
|
||||
void zlib_tr_init (deflate_state *s);
|
||||
int zlib_tr_tally (deflate_state *s, unsigned dist, unsigned lc);
|
||||
ulg zlib_tr_flush_block (deflate_state *s, char *buf, ulg stored_len,
|
||||
int eof);
|
||||
void zlib_tr_align (deflate_state *s);
|
||||
void zlib_tr_stored_block (deflate_state *s, char *buf, ulg stored_len,
|
||||
int eof);
|
||||
void zlib_tr_stored_type_only (deflate_state *);
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
* Output a short LSB first on the stream.
|
||||
* IN assertion: there is enough room in pendingBuf.
|
||||
*/
|
||||
#define put_short(s, w) { \
|
||||
put_byte(s, (uch)((w) & 0xff)); \
|
||||
put_byte(s, (uch)((ush)(w) >> 8)); \
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Reverse the first len bits of a code, using straightforward code (a faster
|
||||
* method would use a table)
|
||||
* IN assertion: 1 <= len <= 15
|
||||
*/
|
||||
static inline unsigned bi_reverse(
|
||||
unsigned code, /* the value to invert */
|
||||
int len /* its bit length */
|
||||
)
|
||||
{
|
||||
register unsigned res = 0;
|
||||
do {
|
||||
res |= code & 1;
|
||||
code >>= 1, res <<= 1;
|
||||
} while (--len > 0);
|
||||
return res >> 1;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Flush the bit buffer, keeping at most 7 bits in it.
|
||||
*/
|
||||
static inline void bi_flush(deflate_state *s)
|
||||
{
|
||||
if (s->bi_valid == 16) {
|
||||
put_short(s, s->bi_buf);
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
} else if (s->bi_valid >= 8) {
|
||||
put_byte(s, (Byte)s->bi_buf);
|
||||
s->bi_buf >>= 8;
|
||||
s->bi_valid -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Flush the bit buffer and align the output on a byte boundary
|
||||
*/
|
||||
static inline void bi_windup(deflate_state *s)
|
||||
{
|
||||
if (s->bi_valid > 8) {
|
||||
put_short(s, s->bi_buf);
|
||||
} else if (s->bi_valid > 0) {
|
||||
put_byte(s, (Byte)s->bi_buf);
|
||||
}
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
#ifdef DEBUG_ZLIB
|
||||
s->bits_sent = (s->bits_sent+7) & ~7;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
need_more, /* block not completed, need more input or more output */
|
||||
block_done, /* block flush performed */
|
||||
finish_started, /* finish started, need only more output at next deflate */
|
||||
finish_done /* finish done, accept no more input or output */
|
||||
} block_state;
|
||||
|
||||
#define Buf_size (8 * 2*sizeof(char))
|
||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
||||
* more than 16 bits on some systems.)
|
||||
*/
|
||||
|
||||
/* ===========================================================================
|
||||
* Send a value on a given number of bits.
|
||||
* IN assertion: length <= 16 and value fits in length bits.
|
||||
*/
|
||||
#ifdef DEBUG_ZLIB
|
||||
static void send_bits (deflate_state *s, int value, int length);
|
||||
|
||||
static void send_bits(
|
||||
deflate_state *s,
|
||||
int value, /* value to send */
|
||||
int length /* number of bits */
|
||||
)
|
||||
{
|
||||
Tracevv((stderr," l %2d v %4x ", length, value));
|
||||
Assert(length > 0 && length <= 15, "invalid length");
|
||||
s->bits_sent += (ulg)length;
|
||||
|
||||
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
|
||||
* unused bits in value.
|
||||
*/
|
||||
if (s->bi_valid > (int)Buf_size - length) {
|
||||
s->bi_buf |= (value << s->bi_valid);
|
||||
put_short(s, s->bi_buf);
|
||||
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
|
||||
s->bi_valid += length - Buf_size;
|
||||
} else {
|
||||
s->bi_buf |= value << s->bi_valid;
|
||||
s->bi_valid += length;
|
||||
}
|
||||
}
|
||||
#else /* !DEBUG_ZLIB */
|
||||
|
||||
#define send_bits(s, value, length) \
|
||||
{ int len = length;\
|
||||
if (s->bi_valid > (int)Buf_size - len) {\
|
||||
int val = value;\
|
||||
s->bi_buf |= (val << s->bi_valid);\
|
||||
put_short(s, s->bi_buf);\
|
||||
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
|
||||
s->bi_valid += len - Buf_size;\
|
||||
} else {\
|
||||
s->bi_buf |= (value) << s->bi_valid;\
|
||||
s->bi_valid += len;\
|
||||
}\
|
||||
}
|
||||
#endif /* DEBUG_ZLIB */
|
||||
|
||||
static inline void zlib_tr_send_bits(
|
||||
deflate_state *s,
|
||||
int value,
|
||||
int length
|
||||
)
|
||||
{
|
||||
send_bits(s, value, length);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* Flush as much pending output as possible. All deflate() output goes
|
||||
* through this function so some applications may wish to modify it
|
||||
* to avoid allocating a large strm->next_out buffer and copying into it.
|
||||
* (See also read_buf()).
|
||||
*/
|
||||
static inline void flush_pending(
|
||||
z_streamp strm
|
||||
)
|
||||
{
|
||||
unsigned len;
|
||||
deflate_state *s = (deflate_state *) strm->state;
|
||||
|
||||
bi_flush(s);
|
||||
len = s->pending;
|
||||
if (len > strm->avail_out) len = strm->avail_out;
|
||||
if (len == 0) return;
|
||||
|
||||
if (strm->next_out != NULL) {
|
||||
memcpy(strm->next_out, s->pending_out, len);
|
||||
strm->next_out += len;
|
||||
}
|
||||
s->pending_out += len;
|
||||
strm->total_out += len;
|
||||
strm->avail_out -= len;
|
||||
s->pending -= len;
|
||||
if (s->pending == 0) {
|
||||
s->pending_out = s->pending_buf;
|
||||
}
|
||||
}
|
||||
#endif /* DEFUTIL_H */
|
||||
37
zipl/boot/zlib/dfltcc.c
Normal file
37
zipl/boot/zlib/dfltcc.c
Normal file
@@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */
|
||||
|
||||
#include "dfltcc_util.h"
|
||||
#include "dfltcc.h"
|
||||
|
||||
char *oesc_msg(
|
||||
char *buf,
|
||||
int oesc
|
||||
)
|
||||
{
|
||||
if (oesc == 0x00)
|
||||
return NULL; /* Successful completion */
|
||||
else {
|
||||
#ifdef STATIC
|
||||
return NULL; /* Ignore for pre-boot decompressor */
|
||||
#else
|
||||
snprintf(buf, 64, "Operation-Ending-Supplemental Code is 0x%.2X", oesc);
|
||||
return buf;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) {
|
||||
/* Initialize available functions */
|
||||
if (is_dfltcc_enabled()) {
|
||||
dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL);
|
||||
memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af));
|
||||
} else
|
||||
memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
|
||||
|
||||
/* Initialize parameter block */
|
||||
memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param));
|
||||
dfltcc_state->param.nt = 1;
|
||||
dfltcc_state->param.ribm = DFLTCC_RIBM;
|
||||
}
|
||||
|
||||
123
zipl/boot/zlib/dfltcc.h
Normal file
123
zipl/boot/zlib/dfltcc.h
Normal file
@@ -0,0 +1,123 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
#ifndef DFLTCC_H
|
||||
#define DFLTCC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lib/zt_common.h"
|
||||
#include "defutil.h"
|
||||
|
||||
/*
|
||||
* Tuning parameters.
|
||||
*/
|
||||
#define DFLTCC_LEVEL_MASK 0x2 /* DFLTCC compression for level 1 only */
|
||||
#define DFLTCC_LEVEL_MASK_DEBUG 0x3fe /* DFLTCC compression for all levels */
|
||||
#define DFLTCC_BLOCK_SIZE 1048576
|
||||
#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096
|
||||
#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096
|
||||
#define DFLTCC_RIBM 0
|
||||
|
||||
#define DFLTCC_FACILITY 151
|
||||
|
||||
/*
|
||||
* Parameter Block for Query Available Functions.
|
||||
*/
|
||||
struct dfltcc_qaf_param {
|
||||
char fns[16];
|
||||
char reserved1[8];
|
||||
char fmts[2];
|
||||
char reserved2[6];
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(struct dfltcc_qaf_param) == 32);
|
||||
|
||||
#define DFLTCC_FMT0 0
|
||||
|
||||
/*
|
||||
* Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand.
|
||||
*/
|
||||
struct dfltcc_param_v0 {
|
||||
uint16_t pbvn; /* Parameter-Block-Version Number */
|
||||
uint8_t mvn; /* Model-Version Number */
|
||||
uint8_t ribm; /* Reserved for IBM use */
|
||||
unsigned reserved32 : 31;
|
||||
unsigned cf : 1; /* Continuation Flag */
|
||||
uint8_t reserved64[8];
|
||||
unsigned nt : 1; /* New Task */
|
||||
unsigned reserved129 : 1;
|
||||
unsigned cvt : 1; /* Check Value Type */
|
||||
unsigned reserved131 : 1;
|
||||
unsigned htt : 1; /* Huffman-Table Type */
|
||||
unsigned bcf : 1; /* Block-Continuation Flag */
|
||||
unsigned bcc : 1; /* Block Closing Control */
|
||||
unsigned bhf : 1; /* Block Header Final */
|
||||
unsigned reserved136 : 1;
|
||||
unsigned reserved137 : 1;
|
||||
unsigned dhtgc : 1; /* DHT Generation Control */
|
||||
unsigned reserved139 : 5;
|
||||
unsigned reserved144 : 5;
|
||||
unsigned sbb : 3; /* Sub-Byte Boundary */
|
||||
uint8_t oesc; /* Operation-Ending-Supplemental Code */
|
||||
unsigned reserved160 : 12;
|
||||
unsigned ifs : 4; /* Incomplete-Function Status */
|
||||
uint16_t ifl; /* Incomplete-Function Length */
|
||||
uint8_t reserved192[8];
|
||||
uint8_t reserved256[8];
|
||||
uint8_t reserved320[4];
|
||||
uint16_t hl; /* History Length */
|
||||
unsigned reserved368 : 1;
|
||||
uint16_t ho : 15; /* History Offset */
|
||||
uint32_t cv; /* Check Value */
|
||||
unsigned eobs : 15; /* End-of-block Symbol */
|
||||
unsigned reserved431: 1;
|
||||
uint8_t eobl : 4; /* End-of-block Length */
|
||||
unsigned reserved436 : 12;
|
||||
unsigned reserved448 : 4;
|
||||
uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table
|
||||
Length */
|
||||
uint8_t reserved464[6];
|
||||
uint8_t cdht[288];
|
||||
uint8_t reserved[32];
|
||||
uint8_t csb[1152];
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(struct dfltcc_param_v0) == 1536);
|
||||
|
||||
#define CVT_CRC32 0
|
||||
#define CVT_ADLER32 1
|
||||
#define HTT_FIXED 0
|
||||
#define HTT_DYNAMIC 1
|
||||
|
||||
/*
|
||||
* Extension of inflate_state and deflate_state for DFLTCC.
|
||||
*/
|
||||
struct dfltcc_state {
|
||||
struct dfltcc_param_v0 param; /* Parameter block */
|
||||
struct dfltcc_qaf_param af; /* Available functions */
|
||||
char msg[64]; /* Buffer for strm->msg */
|
||||
};
|
||||
|
||||
/*
|
||||
* Extension of inflate_state and deflate_state for DFLTCC.
|
||||
*/
|
||||
struct dfltcc_deflate_state {
|
||||
struct dfltcc_state common; /* Parameter block */
|
||||
uLong level_mask; /* Levels on which to use DFLTCC */
|
||||
uLong block_size; /* New block each X bytes */
|
||||
uLong block_threshold; /* New block after total_in > X */
|
||||
uLong dht_threshold; /* New block only if avail_in >= X */
|
||||
};
|
||||
|
||||
#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
|
||||
/* Resides right after inflate_state or deflate_state */
|
||||
#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8)))
|
||||
|
||||
void dfltcc_reset_state(struct dfltcc_state *dfltcc_state);
|
||||
|
||||
static inline int is_dfltcc_enabled(void)
|
||||
{
|
||||
return 1; /* Consider DFLTCC facility always enabled */
|
||||
}
|
||||
|
||||
#define DEFLATE_DFLTCC_ENABLED() is_dfltcc_enabled()
|
||||
|
||||
#endif /* DFLTCC_H */
|
||||
300
zipl/boot/zlib/dfltcc_deflate.c
Normal file
300
zipl/boot/zlib/dfltcc_deflate.c
Normal file
@@ -0,0 +1,300 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
|
||||
#include "defutil.h"
|
||||
#include "dfltcc_util.h"
|
||||
#include "dfltcc_deflate.h"
|
||||
#include "zlib/zutil.h"
|
||||
|
||||
#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state))
|
||||
|
||||
/*
|
||||
* Compress.
|
||||
*/
|
||||
int dfltcc_can_deflate(
|
||||
z_streamp strm
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
|
||||
|
||||
/* Unsupported compression settings */
|
||||
if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy,
|
||||
dfltcc_state->level_mask))
|
||||
return 0;
|
||||
|
||||
/* Unsupported hardware */
|
||||
if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) ||
|
||||
!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) ||
|
||||
!is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dfltcc_reset_deflate_state(z_streamp strm) {
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
|
||||
|
||||
dfltcc_reset_state(&dfltcc_state->common);
|
||||
|
||||
/* Initialize tuning parameters */
|
||||
dfltcc_state->level_mask = DFLTCC_LEVEL_MASK;
|
||||
dfltcc_state->block_size = DFLTCC_BLOCK_SIZE;
|
||||
dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE;
|
||||
dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE;
|
||||
}
|
||||
|
||||
static void dfltcc_gdht(
|
||||
z_streamp strm
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
|
||||
size_t avail_in = strm->avail_in;
|
||||
|
||||
dfltcc(DFLTCC_GDHT,
|
||||
param, NULL, NULL,
|
||||
&strm->next_in, &avail_in, NULL);
|
||||
}
|
||||
|
||||
static dfltcc_cc dfltcc_cmpr(
|
||||
z_streamp strm
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
|
||||
size_t avail_in = strm->avail_in;
|
||||
size_t avail_out = strm->avail_out;
|
||||
dfltcc_cc cc;
|
||||
|
||||
cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR,
|
||||
param, &strm->next_out, &avail_out,
|
||||
&strm->next_in, &avail_in, state->window);
|
||||
strm->total_in += (strm->avail_in - avail_in);
|
||||
strm->total_out += (strm->avail_out - avail_out);
|
||||
strm->avail_in = avail_in;
|
||||
strm->avail_out = avail_out;
|
||||
return cc;
|
||||
}
|
||||
|
||||
static void send_eobs(
|
||||
z_streamp strm,
|
||||
const struct dfltcc_param_v0 *param
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
|
||||
zlib_tr_send_bits(
|
||||
state,
|
||||
bi_reverse(param->eobs >> (15 - param->eobl), param->eobl),
|
||||
param->eobl);
|
||||
flush_pending(strm);
|
||||
if (state->pending != 0) {
|
||||
/* The remaining data is located in pending_out[0:pending]. If someone
|
||||
* calls put_byte() - this might happen in deflate() - the byte will be
|
||||
* placed into pending_buf[pending], which is incorrect. Move the
|
||||
* remaining data to the beginning of pending_buf so that put_byte() is
|
||||
* usable again.
|
||||
*/
|
||||
memmove(state->pending_buf, state->pending_out, state->pending);
|
||||
state->pending_out = state->pending_buf;
|
||||
}
|
||||
#ifdef ZLIB_DEBUG
|
||||
state->compressed_len += param->eobl;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dfltcc_deflate(
|
||||
z_streamp strm,
|
||||
int flush,
|
||||
block_state *result
|
||||
)
|
||||
{
|
||||
deflate_state *state = (deflate_state *)strm->state;
|
||||
struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state);
|
||||
struct dfltcc_param_v0 *param = &dfltcc_state->common.param;
|
||||
uInt masked_avail_in;
|
||||
dfltcc_cc cc;
|
||||
int need_empty_block;
|
||||
int soft_bcc;
|
||||
int no_flush;
|
||||
|
||||
if (!dfltcc_can_deflate(strm)) {
|
||||
/* Clear history. */
|
||||
if (flush == Z_FULL_FLUSH)
|
||||
param->hl = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
again:
|
||||
masked_avail_in = 0;
|
||||
soft_bcc = 0;
|
||||
no_flush = flush == Z_NO_FLUSH;
|
||||
|
||||
/* No input data. Return, except when Continuation Flag is set, which means
|
||||
* that DFLTCC has buffered some output in the parameter block and needs to
|
||||
* be called again in order to flush it.
|
||||
*/
|
||||
if (strm->avail_in == 0 && !param->cf) {
|
||||
/* A block is still open, and the hardware does not support closing
|
||||
* blocks without adding data. Thus, close it manually.
|
||||
*/
|
||||
if (!no_flush && param->bcf) {
|
||||
send_eobs(strm, param);
|
||||
param->bcf = 0;
|
||||
}
|
||||
/* Let one of deflate_* functions write a trailing empty block. */
|
||||
if (flush == Z_FINISH)
|
||||
return 0;
|
||||
/* Clear history. */
|
||||
if (flush == Z_FULL_FLUSH)
|
||||
param->hl = 0;
|
||||
/* Trigger block post-processing if necessary. */
|
||||
*result = no_flush ? need_more : block_done;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* There is an open non-BFINAL block, we are not going to close it just
|
||||
* yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see
|
||||
* more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new
|
||||
* DHT in order to adapt to a possibly changed input data distribution.
|
||||
*/
|
||||
if (param->bcf && no_flush &&
|
||||
strm->total_in > dfltcc_state->block_threshold &&
|
||||
strm->avail_in >= dfltcc_state->dht_threshold) {
|
||||
if (param->cf) {
|
||||
/* We need to flush the DFLTCC buffer before writing the
|
||||
* End-of-block Symbol. Mask the input data and proceed as usual.
|
||||
*/
|
||||
masked_avail_in += strm->avail_in;
|
||||
strm->avail_in = 0;
|
||||
no_flush = 0;
|
||||
} else {
|
||||
/* DFLTCC buffer is empty, so we can manually write the
|
||||
* End-of-block Symbol right away.
|
||||
*/
|
||||
send_eobs(strm, param);
|
||||
param->bcf = 0;
|
||||
dfltcc_state->block_threshold =
|
||||
strm->total_in + dfltcc_state->block_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* No space for compressed data. If we proceed, dfltcc_cmpr() will return
|
||||
* DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still
|
||||
* set BCF=1, which is wrong. Avoid complications and return early.
|
||||
*/
|
||||
if (strm->avail_out == 0) {
|
||||
*result = need_more;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The caller gave us too much data. Pass only one block worth of
|
||||
* uncompressed data to DFLTCC and mask the rest, so that on the next
|
||||
* iteration we start a new block.
|
||||
*/
|
||||
if (no_flush && strm->avail_in > dfltcc_state->block_size) {
|
||||
masked_avail_in += (strm->avail_in - dfltcc_state->block_size);
|
||||
strm->avail_in = dfltcc_state->block_size;
|
||||
}
|
||||
|
||||
/* When we have an open non-BFINAL deflate block and caller indicates that
|
||||
* the stream is ending, we need to close an open deflate block and open a
|
||||
* BFINAL one.
|
||||
*/
|
||||
need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf;
|
||||
|
||||
/* Translate stream to parameter block */
|
||||
param->cvt = CVT_ADLER32;
|
||||
if (!no_flush)
|
||||
/* We need to close a block. Always do this in software - when there is
|
||||
* no input data, the hardware will not hohor BCC. */
|
||||
soft_bcc = 1;
|
||||
if (flush == Z_FINISH && !param->bcf)
|
||||
/* We are about to open a BFINAL block, set Block Header Final bit
|
||||
* until the stream ends.
|
||||
*/
|
||||
param->bhf = 1;
|
||||
/* DFLTCC-CMPR will write to next_out, so make sure that buffers with
|
||||
* higher precedence are empty.
|
||||
*/
|
||||
Assert(state->pending == 0, "There must be no pending bytes");
|
||||
Assert(state->bi_valid < 8, "There must be less than 8 pending bits");
|
||||
param->sbb = (unsigned int)state->bi_valid;
|
||||
if (param->sbb > 0)
|
||||
*strm->next_out = (Byte)state->bi_buf;
|
||||
/* Honor history and check value */
|
||||
param->nt = 0;
|
||||
param->cv = strm->adler;
|
||||
|
||||
/* When opening a block, choose a Huffman-Table Type */
|
||||
if (!param->bcf) {
|
||||
if (strm->total_in == 0 && dfltcc_state->block_threshold > 0) {
|
||||
param->htt = HTT_FIXED;
|
||||
}
|
||||
else {
|
||||
param->htt = HTT_DYNAMIC;
|
||||
dfltcc_gdht(strm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deflate */
|
||||
do {
|
||||
cc = dfltcc_cmpr(strm);
|
||||
if (strm->avail_in < 4096 && masked_avail_in > 0)
|
||||
/* We are about to call DFLTCC with a small input buffer, which is
|
||||
* inefficient. Since there is masked data, there will be at least
|
||||
* one more DFLTCC call, so skip the current one and make the next
|
||||
* one handle more data.
|
||||
*/
|
||||
break;
|
||||
} while (cc == DFLTCC_CC_AGAIN);
|
||||
|
||||
/* Translate parameter block to stream */
|
||||
strm->msg = oesc_msg(dfltcc_state->common.msg, param->oesc);
|
||||
state->bi_valid = param->sbb;
|
||||
if (state->bi_valid == 0)
|
||||
state->bi_buf = 0; /* Avoid accessing next_out */
|
||||
else
|
||||
state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1);
|
||||
strm->adler = param->cv;
|
||||
|
||||
/* Unmask the input data */
|
||||
strm->avail_in += masked_avail_in;
|
||||
masked_avail_in = 0;
|
||||
|
||||
/* If we encounter an error, it means there is a bug in DFLTCC call */
|
||||
Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG");
|
||||
|
||||
/* Update Block-Continuation Flag. It will be used to check whether to call
|
||||
* GDHT the next time.
|
||||
*/
|
||||
if (cc == DFLTCC_CC_OK) {
|
||||
if (soft_bcc) {
|
||||
send_eobs(strm, param);
|
||||
param->bcf = 0;
|
||||
dfltcc_state->block_threshold =
|
||||
strm->total_in + dfltcc_state->block_size;
|
||||
} else
|
||||
param->bcf = 1;
|
||||
if (flush == Z_FINISH) {
|
||||
if (need_empty_block)
|
||||
/* Make the current deflate() call also close the stream */
|
||||
return 0;
|
||||
else {
|
||||
bi_windup(state);
|
||||
*result = finish_done;
|
||||
}
|
||||
} else {
|
||||
if (flush == Z_FULL_FLUSH)
|
||||
param->hl = 0; /* Clear history */
|
||||
*result = flush == Z_NO_FLUSH ? need_more : block_done;
|
||||
}
|
||||
} else {
|
||||
param->bcf = 1;
|
||||
*result = need_more;
|
||||
}
|
||||
if (strm->avail_in != 0 && strm->avail_out != 0)
|
||||
goto again; /* deflate() must use all input or all output */
|
||||
return 1;
|
||||
}
|
||||
21
zipl/boot/zlib/dfltcc_deflate.h
Normal file
21
zipl/boot/zlib/dfltcc_deflate.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
#ifndef DFLTCC_DEFLATE_H
|
||||
#define DFLTCC_DEFLATE_H
|
||||
|
||||
#include "dfltcc.h"
|
||||
|
||||
/* External functions */
|
||||
int dfltcc_can_deflate(z_streamp strm);
|
||||
int dfltcc_deflate(z_streamp strm,
|
||||
int flush,
|
||||
block_state *result);
|
||||
void dfltcc_reset_deflate_state(z_streamp strm);
|
||||
|
||||
#define DEFLATE_RESET_HOOK(strm) \
|
||||
dfltcc_reset_deflate_state((strm))
|
||||
|
||||
#define DEFLATE_HOOK dfltcc_deflate
|
||||
|
||||
#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm)))
|
||||
|
||||
#endif /* DFLTCC_DEFLATE_H */
|
||||
104
zipl/boot/zlib/dfltcc_util.h
Normal file
104
zipl/boot/zlib/dfltcc_util.h
Normal file
@@ -0,0 +1,104 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
#ifndef DFLTCC_UTIL_H
|
||||
#define DFLTCC_UTIL_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "zlib/zutil.h"
|
||||
|
||||
/*
|
||||
* C wrapper for the DEFLATE CONVERSION CALL instruction.
|
||||
*/
|
||||
typedef enum {
|
||||
DFLTCC_CC_OK = 0,
|
||||
DFLTCC_CC_OP1_TOO_SHORT = 1,
|
||||
DFLTCC_CC_OP2_TOO_SHORT = 2,
|
||||
DFLTCC_CC_OP2_CORRUPT = 2,
|
||||
DFLTCC_CC_AGAIN = 3,
|
||||
} dfltcc_cc;
|
||||
|
||||
#define DFLTCC_QAF 0
|
||||
#define DFLTCC_GDHT 1
|
||||
#define DFLTCC_CMPR 2
|
||||
#define DFLTCC_XPND 4
|
||||
#define HBT_CIRCULAR (1 << 7)
|
||||
#define HB_BITS 15
|
||||
#define HB_SIZE (1 << HB_BITS)
|
||||
|
||||
static inline dfltcc_cc dfltcc(
|
||||
int fn,
|
||||
void *param,
|
||||
Byte **op1,
|
||||
size_t *len1,
|
||||
const Byte **op2,
|
||||
size_t *len2,
|
||||
void *hist
|
||||
)
|
||||
{
|
||||
Byte *t2 = op1 ? *op1 : NULL;
|
||||
size_t t3 = len1 ? *len1 : 0;
|
||||
const Byte *t4 = op2 ? *op2 : NULL;
|
||||
size_t t5 = len2 ? *len2 : 0;
|
||||
register int r0 __asm__("r0") = fn;
|
||||
register void *r1 __asm__("r1") = param;
|
||||
register Byte *r2 __asm__("r2") = t2;
|
||||
register size_t r3 __asm__("r3") = t3;
|
||||
register const Byte *r4 __asm__("r4") = t4;
|
||||
register size_t r5 __asm__("r5") = t5;
|
||||
int cc;
|
||||
|
||||
__asm__ volatile(
|
||||
".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
|
||||
"ipm %[cc]\n"
|
||||
: [r2] "+r" (r2)
|
||||
, [r3] "+r" (r3)
|
||||
, [r4] "+r" (r4)
|
||||
, [r5] "+r" (r5)
|
||||
, [cc] "=r" (cc)
|
||||
: [r0] "r" (r0)
|
||||
, [r1] "r" (r1)
|
||||
, [hist] "r" (hist)
|
||||
: "cc", "memory");
|
||||
t2 = r2; t3 = r3; t4 = r4; t5 = r5;
|
||||
|
||||
if (op1)
|
||||
*op1 = t2;
|
||||
if (len1)
|
||||
*len1 = t3;
|
||||
if (op2)
|
||||
*op2 = t4;
|
||||
if (len2)
|
||||
*len2 = t5;
|
||||
return (cc >> 28) & 3;
|
||||
}
|
||||
|
||||
static inline int is_bit_set(
|
||||
const char *bits,
|
||||
int n
|
||||
)
|
||||
{
|
||||
return bits[n / 8] & (1 << (7 - (n % 8)));
|
||||
}
|
||||
|
||||
static inline void turn_bit_off(
|
||||
char *bits,
|
||||
int n
|
||||
)
|
||||
{
|
||||
bits[n / 8] &= ~(1 << (7 - (n % 8)));
|
||||
}
|
||||
|
||||
static inline int dfltcc_are_params_ok(
|
||||
int level,
|
||||
uInt window_bits,
|
||||
int strategy,
|
||||
uLong level_mask
|
||||
)
|
||||
{
|
||||
return (level_mask & (1 << level)) != 0 &&
|
||||
(window_bits == HB_BITS) &&
|
||||
(strategy == Z_DEFAULT_STRATEGY);
|
||||
}
|
||||
|
||||
char *oesc_msg(char *buf, int oesc);
|
||||
|
||||
#endif /* DFLTCC_UTIL_H */
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "boot/boot_defs.h"
|
||||
#include "lib/zt_common.h"
|
||||
#include "dump/s390_dump.h"
|
||||
|
||||
#include "disk.h"
|
||||
#include "job.h"
|
||||
@@ -185,12 +186,16 @@ int boot_get_stage3_parms(void **buffer, size_t *bytecount, address_t parm_addr,
|
||||
address_t envblk_addr, size_t envblk_len);
|
||||
int boot_get_tape_ipl(void** data, size_t* size, address_t parm_addr,
|
||||
address_t initrd_addr, address_t image_addr);
|
||||
int boot_get_tape_dump(void** data, size_t* size, uint64_t mem);
|
||||
int boot_get_eckd_dump_stage2(void** data, size_t* size, uint64_t mem);
|
||||
int boot_get_tape_dump(void **data, size_t *size,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms);
|
||||
int boot_get_eckd_dump_stage2(void **data, size_t *size,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms);
|
||||
int boot_get_eckd_ld_ipl_br(void **br_ptr, size_t *size_ptr,
|
||||
disk_blockptr_t *table, struct disk_info *info);
|
||||
int boot_get_eckd_mvdump_stage2(void** data, size_t* size, uint64_t mem,
|
||||
uint8_t force, struct mvdump_parm_table);
|
||||
int boot_get_fba_dump_stage2(void** data, size_t* size, uint64_t mem);
|
||||
int boot_get_eckd_mvdump_stage2(void **data, size_t *size,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms,
|
||||
const struct mvdump_parm_table *mv_parm_table);
|
||||
int boot_get_fba_dump_stage2(void **data, size_t *size,
|
||||
const struct stage2dump_parm_tail *stage2dump_parms);
|
||||
|
||||
#endif /* BOOT_H */
|
||||
|
||||
@@ -120,8 +120,8 @@ int install_tapeloader(const char* device, const char* image,
|
||||
const char* parmline, const char* ramdisk,
|
||||
address_t image_addr, address_t parm_addr,
|
||||
address_t initrd_addr);
|
||||
int install_dump(const char* device, struct job_target_data* target,
|
||||
uint64_t mem);
|
||||
int install_dump(const char *device, struct job_target_data *target,
|
||||
uint64_t mem, bool no_compress);
|
||||
int install_mvdump(char* const device[], struct job_target_data* target,
|
||||
int device_count, uint64_t mem, uint8_t force);
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ struct job_dump_data {
|
||||
struct job_common_ipl_data common;
|
||||
char* device;
|
||||
uint64_t mem;
|
||||
bool no_compress;
|
||||
};
|
||||
|
||||
struct job_mvdump_data {
|
||||
@@ -87,7 +88,6 @@ struct job_ipl_tape_data {
|
||||
char* device;
|
||||
};
|
||||
|
||||
|
||||
union job_menu_entry_data {
|
||||
struct job_ipl_data ipl;
|
||||
struct job_dump_data dump;
|
||||
|
||||
57
zipl/include/zlib/zconf.h
Normal file
57
zipl/include/zlib/zconf.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-1998 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef _ZCONF_H
|
||||
#define _ZCONF_H
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# define MAX_MEM_LEVEL 8
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
|
||||
/* default memLevel */
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
typedef void *voidp;
|
||||
|
||||
#endif /* _ZCONF_H */
|
||||
385
zipl/include/zlib/zlib.h
Normal file
385
zipl/include/zlib/zlib.h
Normal file
@@ -0,0 +1,385 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
|
||||
Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files https://www.ietf.org/rfc/rfc1950.txt
|
||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||||
*/
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#define _ZLIB_H
|
||||
|
||||
#include "zconf.h"
|
||||
|
||||
/* Always build with DFLTCC support */
|
||||
#define CONFIG_ZLIB_DFLTCC
|
||||
|
||||
/* zlib deflate based on ZLIB_VERSION "1.1.3" */
|
||||
|
||||
/*
|
||||
This is a modified version of zlib for use inside s390-tools for dump
|
||||
compression. It contains deflate parts only. Inflate code and function
|
||||
prototypes are removed.
|
||||
All memory allocations are to be performed in advance.
|
||||
*/
|
||||
|
||||
/*
|
||||
The 'zlib' compression library provides in-memory compression and
|
||||
decompression functions, including integrity checks of the uncompressed
|
||||
data. This version of the library supports only one compression method
|
||||
(deflation) but other algorithms will be added later and will have the same
|
||||
stream interface.
|
||||
|
||||
Compression can be done in a single step if the buffers are large
|
||||
enough (for example if an input file is mmap'ed), or can be done by
|
||||
repeated calls of the compression function. In the latter case, the
|
||||
application must provide more input and/or consume the output
|
||||
(providing more output space) before each call.
|
||||
|
||||
The compressed data format used by default by the in-memory functions is
|
||||
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
|
||||
around a deflate stream, which is itself documented in RFC 1951.
|
||||
|
||||
The library also supports reading and writing files in gzip (.gz) format
|
||||
with an interface similar to that of stdio.
|
||||
|
||||
The zlib format was designed to be compact and fast for use in memory
|
||||
and on communications channels. The gzip format was designed for single-
|
||||
file compression on file systems, has a larger header than zlib to maintain
|
||||
directory information, and uses a different, slower check method than zlib.
|
||||
|
||||
The library does not install any signal handler. The decoder checks
|
||||
the consistency of the compressed data, so the library should never
|
||||
crash even in case of corrupted input.
|
||||
*/
|
||||
|
||||
struct internal_state;
|
||||
|
||||
typedef struct z_stream_s {
|
||||
const Byte *next_in; /* next input byte */
|
||||
uLong avail_in; /* number of bytes available at next_in */
|
||||
uLong total_in; /* total nb of input bytes read so far */
|
||||
|
||||
Byte *next_out; /* next output byte should be put there */
|
||||
uLong avail_out; /* remaining free space at next_out */
|
||||
uLong total_out; /* total nb of bytes output so far */
|
||||
|
||||
char *msg; /* last error message, NULL if no error */
|
||||
struct internal_state *state; /* not visible by applications */
|
||||
|
||||
void *workspace; /* memory allocated for this stream */
|
||||
|
||||
int data_type; /* best guess about the data type: ascii or binary */
|
||||
uLong adler; /* adler32 value of the uncompressed data */
|
||||
uLong reserved; /* reserved for future use */
|
||||
} z_stream;
|
||||
|
||||
typedef z_stream *z_streamp;
|
||||
|
||||
/*
|
||||
The application must update next_in and avail_in when avail_in has
|
||||
dropped to zero. It must update next_out and avail_out when avail_out
|
||||
has dropped to zero. The application must initialize zalloc, zfree and
|
||||
opaque before calling the init function. All other fields are set by the
|
||||
compression library and must not be updated by the application.
|
||||
|
||||
The opaque value provided by the application will be passed as the first
|
||||
parameter for calls of zalloc and zfree. This can be useful for custom
|
||||
memory management. The compression library attaches no meaning to the
|
||||
opaque value.
|
||||
|
||||
zalloc must return NULL if there is not enough memory for the object.
|
||||
If zlib is used in a multi-threaded application, zalloc and zfree must be
|
||||
thread safe.
|
||||
|
||||
On 16-bit systems, the functions zalloc and zfree must be able to allocate
|
||||
exactly 65536 bytes, but will not be required to allocate more than this
|
||||
if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
|
||||
pointers returned by zalloc for objects of exactly 65536 bytes *must*
|
||||
have their offset normalized to zero. The default allocation function
|
||||
provided by this library ensures this (see zutil.c). To reduce memory
|
||||
requirements and avoid any allocation of 64K objects, at the expense of
|
||||
compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
|
||||
|
||||
The fields total_in and total_out can be used for statistics or
|
||||
progress reports. After compression, total_in holds the total size of
|
||||
the uncompressed data and may be saved for use in the decompressor
|
||||
(particularly if the decompressor wants to decompress everything in
|
||||
a single step).
|
||||
*/
|
||||
|
||||
/* constants */
|
||||
|
||||
#define Z_NO_FLUSH 0
|
||||
#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
|
||||
#define Z_PACKET_FLUSH 2
|
||||
#define Z_SYNC_FLUSH 3
|
||||
#define Z_FULL_FLUSH 4
|
||||
#define Z_FINISH 5
|
||||
#define Z_BLOCK 6 /* Only for inflate at present */
|
||||
/* Allowed flush values; see deflate() and inflate() below for details */
|
||||
|
||||
#define Z_OK 0
|
||||
#define Z_STREAM_END 1
|
||||
#define Z_NEED_DICT 2
|
||||
#define Z_ERRNO (-1)
|
||||
#define Z_STREAM_ERROR (-2)
|
||||
#define Z_DATA_ERROR (-3)
|
||||
#define Z_MEM_ERROR (-4)
|
||||
#define Z_BUF_ERROR (-5)
|
||||
#define Z_VERSION_ERROR (-6)
|
||||
/* Return codes for the compression/decompression functions. Negative
|
||||
* values are errors, positive values are used for special but normal events.
|
||||
*/
|
||||
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_DEFAULT_COMPRESSION (-1)
|
||||
/* compression levels */
|
||||
|
||||
#define Z_FILTERED 1
|
||||
#define Z_HUFFMAN_ONLY 2
|
||||
#define Z_DEFAULT_STRATEGY 0
|
||||
/* compression strategy; see deflateInit2() below for details */
|
||||
|
||||
#define Z_BINARY 0
|
||||
#define Z_ASCII 1
|
||||
#define Z_UNKNOWN 2
|
||||
/* Possible values of the data_type field */
|
||||
|
||||
#define Z_DEFLATED 8
|
||||
/* The deflate compression method (the only one supported in this version) */
|
||||
|
||||
/* basic functions */
|
||||
|
||||
extern int zlib_deflate_workspacesize (int windowBits, int memLevel);
|
||||
/*
|
||||
Returns the number of bytes that needs to be allocated for a per-
|
||||
stream workspace with the specified parameters. A pointer to this
|
||||
number of bytes should be returned in stream->workspace before
|
||||
you call zlib_deflateInit() or zlib_deflateInit2(). If you call
|
||||
zlib_deflateInit(), specify windowBits = MAX_WBITS and memLevel =
|
||||
MAX_MEM_LEVEL here. If you call zlib_deflateInit2(), the windowBits
|
||||
and memLevel parameters passed to zlib_deflateInit2() must not
|
||||
exceed those passed here.
|
||||
*/
|
||||
|
||||
extern int zlib_deflate_dfltcc_enabled (void);
|
||||
/*
|
||||
Returns 1 if Deflate-Conversion facility is installed and enabled,
|
||||
otherwise 0.
|
||||
*/
|
||||
|
||||
/*
|
||||
extern int deflateInit (z_streamp strm, int level);
|
||||
|
||||
Initializes the internal stream state for compression. The fields
|
||||
zalloc, zfree and opaque must be initialized before by the caller.
|
||||
If zalloc and zfree are set to NULL, deflateInit updates them to
|
||||
use default allocation functions.
|
||||
|
||||
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
|
||||
1 gives best speed, 9 gives best compression, 0 gives no compression at
|
||||
all (the input data is simply copied a block at a time).
|
||||
Z_DEFAULT_COMPRESSION requests a default compromise between speed and
|
||||
compression (currently equivalent to level 6).
|
||||
|
||||
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_STREAM_ERROR if level is not a valid compression level,
|
||||
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
|
||||
with the version assumed by the caller (ZLIB_VERSION).
|
||||
msg is set to null if there is no error message. deflateInit does not
|
||||
perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
|
||||
extern int zlib_deflate (z_streamp strm, int flush);
|
||||
/*
|
||||
deflate compresses as much data as possible, and stops when the input
|
||||
buffer becomes empty or the output buffer becomes full. It may introduce some
|
||||
output latency (reading input without producing any output) except when
|
||||
forced to flush.
|
||||
|
||||
The detailed semantics are as follows. deflate performs one or both of the
|
||||
following actions:
|
||||
|
||||
- Compress more input starting at next_in and update next_in and avail_in
|
||||
accordingly. If not all input can be processed (because there is not
|
||||
enough room in the output buffer), next_in and avail_in are updated and
|
||||
processing will resume at this point for the next call of deflate().
|
||||
|
||||
- Provide more output starting at next_out and update next_out and avail_out
|
||||
accordingly. This action is forced if the parameter flush is non zero.
|
||||
Forcing flush frequently degrades the compression ratio, so this parameter
|
||||
should be set only when necessary (in interactive applications).
|
||||
Some output may be provided even if flush is not set.
|
||||
|
||||
Before the call of deflate(), the application should ensure that at least
|
||||
one of the actions is possible, by providing more input and/or consuming
|
||||
more output, and updating avail_in or avail_out accordingly; avail_out
|
||||
should never be zero before the call. The application can consume the
|
||||
compressed output when it wants, for example when the output buffer is full
|
||||
(avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
|
||||
and with zero avail_out, it must be called again after making room in the
|
||||
output buffer because there might be more output pending.
|
||||
|
||||
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
|
||||
flushed to the output buffer and the output is aligned on a byte boundary, so
|
||||
that the decompressor can get all input data available so far. (In particular
|
||||
avail_in is zero after the call if enough output space has been provided
|
||||
before the call.) Flushing may degrade compression for some compression
|
||||
algorithms and so it should be used only when necessary.
|
||||
|
||||
If flush is set to Z_FULL_FLUSH, all output is flushed as with
|
||||
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
|
||||
restart from this point if previous compressed data has been damaged or if
|
||||
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
|
||||
the compression.
|
||||
|
||||
If deflate returns with avail_out == 0, this function must be called again
|
||||
with the same value of the flush parameter and more output space (updated
|
||||
avail_out), until the flush is complete (deflate returns with non-zero
|
||||
avail_out).
|
||||
|
||||
If the parameter flush is set to Z_FINISH, pending input is processed,
|
||||
pending output is flushed and deflate returns with Z_STREAM_END if there
|
||||
was enough output space; if deflate returns with Z_OK, this function must be
|
||||
called again with Z_FINISH and more output space (updated avail_out) but no
|
||||
more input data, until it returns with Z_STREAM_END or an error. After
|
||||
deflate has returned Z_STREAM_END, the only possible operations on the
|
||||
stream are deflateReset or deflateEnd.
|
||||
|
||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||
is to be done in a single step. In this case, avail_out must be at least
|
||||
0.1% larger than avail_in plus 12 bytes. If deflate does not return
|
||||
Z_STREAM_END, then it must be called again as described above.
|
||||
|
||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||
so far (that is, total_in bytes).
|
||||
|
||||
deflate() may update data_type if it can make a good guess about
|
||||
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
|
||||
binary. This field is only for information purposes and does not affect
|
||||
the compression algorithm in any manner.
|
||||
|
||||
deflate() returns Z_OK if some progress has been made (more input
|
||||
processed or more output produced), Z_STREAM_END if all input has been
|
||||
consumed and all output has been produced (only when flush is set to
|
||||
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
|
||||
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
|
||||
(for example avail_in or avail_out was zero).
|
||||
*/
|
||||
|
||||
|
||||
extern int zlib_deflateEnd (z_streamp strm);
|
||||
/*
|
||||
All dynamically allocated data structures for this stream are freed.
|
||||
This function discards any unprocessed input and does not flush any
|
||||
pending output.
|
||||
|
||||
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
|
||||
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
|
||||
prematurely (some input or output was discarded). In the error case,
|
||||
msg may be set but then points to a static string (which must not be
|
||||
deallocated).
|
||||
*/
|
||||
|
||||
/* Advanced functions */
|
||||
|
||||
/*
|
||||
The following functions are needed only in some special applications.
|
||||
*/
|
||||
|
||||
/*
|
||||
extern int deflateInit2 (z_streamp strm,
|
||||
int level,
|
||||
int method,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy);
|
||||
|
||||
This is another version of deflateInit with more compression options. The
|
||||
fields next_in, zalloc, zfree and opaque must be initialized before by
|
||||
the caller.
|
||||
|
||||
The method parameter is the compression method. It must be Z_DEFLATED in
|
||||
this version of the library.
|
||||
|
||||
The windowBits parameter is the base two logarithm of the window size
|
||||
(the size of the history buffer). It should be in the range 8..15 for this
|
||||
version of the library. Larger values of this parameter result in better
|
||||
compression at the expense of memory usage. The default value is 15 if
|
||||
deflateInit is used instead.
|
||||
|
||||
The memLevel parameter specifies how much memory should be allocated
|
||||
for the internal compression state. memLevel=1 uses minimum memory but
|
||||
is slow and reduces compression ratio; memLevel=9 uses maximum memory
|
||||
for optimal speed. The default value is 8. See zconf.h for total memory
|
||||
usage as a function of windowBits and memLevel.
|
||||
|
||||
The strategy parameter is used to tune the compression algorithm. Use the
|
||||
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
|
||||
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
|
||||
string match). Filtered data consists mostly of small values with a
|
||||
somewhat random distribution. In this case, the compression algorithm is
|
||||
tuned to compress them better. The effect of Z_FILTERED is to force more
|
||||
Huffman coding and less string matching; it is somewhat intermediate
|
||||
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
|
||||
the compression ratio but not the correctness of the compressed output even
|
||||
if it is not set appropriately.
|
||||
|
||||
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
|
||||
method). msg is set to null if there is no error message. deflateInit2 does
|
||||
not perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
extern int zlib_deflateReset (z_streamp strm);
|
||||
/*
|
||||
This function is equivalent to deflateEnd followed by deflateInit,
|
||||
but does not free and reallocate all the internal compression state.
|
||||
The stream will keep the same compression level and any other attributes
|
||||
that may have been set by deflateInit2.
|
||||
|
||||
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
static inline unsigned long deflateBound(unsigned long s)
|
||||
{
|
||||
return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11;
|
||||
}
|
||||
|
||||
#define zlib_deflateInit(strm, level) \
|
||||
zlib_deflateInit2((strm), (level), Z_DEFLATED, MAX_WBITS, \
|
||||
DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY)
|
||||
extern int zlib_deflateInit2(z_streamp strm, int level, int method,
|
||||
int windowBits, int memLevel,
|
||||
int strategy);
|
||||
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
|
||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
||||
#endif
|
||||
|
||||
#endif /* _ZLIB_H */
|
||||
105
zipl/include/zlib/zutil.h
Normal file
105
zipl/include/zlib/zutil.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-1998 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id: zutil.h,v 1.1 2000/01/01 03:32:23 davem Exp $ */
|
||||
|
||||
#ifndef _Z_UTIL_H
|
||||
#define _Z_UTIL_H
|
||||
|
||||
#include "zlib.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
/* common constants */
|
||||
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
/* The three kinds of block type */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
/* Common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
typedef uLong (*check_func) (uLong check, const Byte *buf,
|
||||
uInt len);
|
||||
|
||||
|
||||
/* checksum functions */
|
||||
|
||||
#define BASE 65521L /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* ========================================================================= */
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||
return the updated checksum. If buf is NULL, this function returns
|
||||
the required initial value for the checksum.
|
||||
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
|
||||
much faster. Usage example:
|
||||
|
||||
uLong adler = zlib_adler32(0L, NULL, 0);
|
||||
|
||||
while (read_buffer(buffer, length) != EOF) {
|
||||
adler = zlib_adler32(adler, buffer, length);
|
||||
}
|
||||
if (adler != original_adler) error();
|
||||
*/
|
||||
static inline uLong zlib_adler32(uLong adler,
|
||||
const Byte *buf,
|
||||
uInt len)
|
||||
{
|
||||
unsigned long s1 = adler & 0xffff;
|
||||
unsigned long s2 = (adler >> 16) & 0xffff;
|
||||
int k;
|
||||
|
||||
if (buf == NULL) return 1L;
|
||||
|
||||
while (len > 0) {
|
||||
k = len < NMAX ? len : NMAX;
|
||||
len -= k;
|
||||
while (k >= 16) {
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
k -= 16;
|
||||
}
|
||||
if (k != 0) do {
|
||||
s1 += *buf++;
|
||||
s2 += s1;
|
||||
} while (--k);
|
||||
s1 %= BASE;
|
||||
s2 %= BASE;
|
||||
}
|
||||
return (s2 << 16) | s1;
|
||||
}
|
||||
|
||||
#endif /* _Z_UTIL_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user