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 |
+1
-1
@@ -29,5 +29,5 @@ indent_size = 4
|
|||||||
[{Makefile,*.mak}]
|
[{Makefile,*.mak}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[COMMIT_EDITMSG]
|
[{COMMIT_EDITMSG,EDIT_DESCRIPTION}]
|
||||||
max_line_length = 72
|
max_line_length = 72
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ cpacfstats/cpacfstatsd
|
|||||||
cpumf/chcpumf
|
cpumf/chcpumf
|
||||||
cpumf/lscpumf
|
cpumf/lscpumf
|
||||||
cpumf/lshwc
|
cpumf/lshwc
|
||||||
|
cpumf/lspai
|
||||||
cpumf/pai
|
cpumf/pai
|
||||||
cpuplugd/cpuplugd
|
cpuplugd/cpuplugd
|
||||||
dasdfmt/dasdfmt
|
dasdfmt/dasdfmt
|
||||||
|
|||||||
@@ -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
|
- Eberhard Pasch
|
||||||
- Eduard Shishkin
|
- Eduard Shishkin
|
||||||
- Einar Lueck
|
- Einar Lueck
|
||||||
|
- Eric Farman
|
||||||
- Eric Sandeen
|
- Eric Sandeen
|
||||||
- Erwin Vicari
|
- Erwin Vicari
|
||||||
- Eugene Crosser
|
- Eugene Crosser
|
||||||
@@ -56,6 +57,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Horst Hummel
|
- Horst Hummel
|
||||||
- Ingo Franzki
|
- Ingo Franzki
|
||||||
- Ingo Tuchscherer
|
- Ingo Tuchscherer
|
||||||
|
- Jakub Čajka
|
||||||
- Jan Glauber
|
- Jan Glauber
|
||||||
- Jan Höppner
|
- Jan Höppner
|
||||||
- Jan Willeke
|
- Jan Willeke
|
||||||
@@ -124,6 +126,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Thomas Richter
|
- Thomas Richter
|
||||||
- Thomas Spatzier
|
- Thomas Spatzier
|
||||||
- Thomas Weber
|
- Thomas Weber
|
||||||
|
- Thorsten Winkler
|
||||||
- Tuan Hoang
|
- Tuan Hoang
|
||||||
- Ursula Braun
|
- Ursula Braun
|
||||||
- Utz Bacher
|
- Utz Bacher
|
||||||
|
|||||||
@@ -1,6 +1,33 @@
|
|||||||
Release history for s390-tools (MIT version)
|
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)__
|
* __v2.29.0 (2023-08-04)__
|
||||||
|
|
||||||
For Linux kernel version: 6.5
|
For Linux kernel version: 6.5
|
||||||
|
|||||||
@@ -386,6 +386,24 @@ the different tools are provided:
|
|||||||
- Packages: blktrace, multipath-tools, sg3-utils
|
- Packages: blktrace, multipath-tools, sg3-utils
|
||||||
- Tools: rsync, tar, lsscsi
|
- 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
|
* zgetdump
|
||||||
For building zgetdump you need OpenSSL version 1.1.0 or newer
|
For building zgetdump you need OpenSSL version 1.1.0 or newer
|
||||||
installed (openssl-devel.rpm). Also required is glib2
|
installed (openssl-devel.rpm). Also required is glib2
|
||||||
|
|||||||
+27
-5
@@ -798,12 +798,34 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ap_get_lock_callout();
|
/*
|
||||||
if (rc) {
|
* For the get-attributes callout, we are typically called without the
|
||||||
fprintf(stderr, "Failed to acquire configuration lock %d\n", rc);
|
* callout lock held. However, there is a particular scenario (define
|
||||||
return -1;
|
* 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
|
* Read the 'matrix' and 'control_domains' attributes to get the
|
||||||
|
|||||||
+16
-16
@@ -32,7 +32,7 @@ endif
|
|||||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
RELEASE = 29
|
RELEASE = 30
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 0
|
||||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
@@ -93,19 +93,19 @@ define cmd_define_and_export
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
define define_toolchain_variables
|
define define_toolchain_variables
|
||||||
$(eval $(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as))
|
$(call cmd_define_and_export, AS$(1)," AS$(1) ",$(2)as)
|
||||||
$(eval $(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc))
|
$(call cmd_define_and_export, CC$(1)," CC$(1) ",$(2)gcc)
|
||||||
$(eval $(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1))))
|
$(call cmd_define_and_export, LINK$(1)," LINK$(1) ",$$(CC$(1)))
|
||||||
$(eval $(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++))
|
$(call cmd_define_and_export, CXX$(1)," CXX$(1) ",$(2)g++)
|
||||||
$(eval $(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1))))
|
$(call cmd_define_and_export, LINKXX$(1)," LINKXX$(1) ",$$(CXX$(1)))
|
||||||
$(eval $(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E))
|
$(call cmd_define_and_export, CPP$(1)," CPP$(1) ",$(2)gcc -E)
|
||||||
$(eval $(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar))
|
$(call cmd_define_and_export, AR$(1)," AR$(1) ",$(2)ar)
|
||||||
$(eval $(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm))
|
$(call cmd_define_and_export, NM$(1)," NM$(1) ",$(2)nm)
|
||||||
$(eval $(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip))
|
$(call cmd_define_and_export, STRIP$(1)," STRIP$(1) ",$(2)strip)
|
||||||
$(eval $(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy))
|
$(call cmd_define_and_export,OBJCOPY$(1)," OBJCOPY$(1) ",$(2)objcopy)
|
||||||
$(eval $(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump))
|
$(call cmd_define_and_export,OBJDUMP$(1)," OBJDUMP$(1) ",$(2)objdump)
|
||||||
$(eval PKG_CONFIG$(1) = pkg-config)
|
PKG_CONFIG$(1) = pkg-config
|
||||||
$(eval export PKG_CONFIG$(1))
|
export PKG_CONFIG$(1)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
# If the host architecture is not the same as the build architecture
|
# If the host architecture is not the same as the build architecture
|
||||||
@@ -119,8 +119,8 @@ ifneq ($(HOST_ARCH),$(BUILD_ARCH))
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(call define_toolchain_variables,_FOR_BUILD,)
|
$(eval $(call define_toolchain_variables,_FOR_BUILD,))
|
||||||
$(call define_toolchain_variables,,$(CROSS_COMPILE))
|
$(eval $(call define_toolchain_variables,,$(CROSS_COMPILE)))
|
||||||
|
|
||||||
|
|
||||||
$(eval $(call cmd_define, RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
$(eval $(call cmd_define, RUNTEST," RUNTEST ",$(S390_TEST_LIB_PATH)/s390_runtest))
|
||||||
|
|||||||
+3
-2
@@ -1,7 +1,7 @@
|
|||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
BIN_FILES = lscpumf chcpumf lshwc pai
|
BIN_FILES = lscpumf chcpumf lshwc pai lspai
|
||||||
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8
|
MAN_FILES = lscpumf.8 chcpumf.8 lshwc.8 pai.8 lspai.8
|
||||||
|
|
||||||
all: $(BIN_FILES)
|
all: $(BIN_FILES)
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@ lscpumf: lscpumf.o $(libs)
|
|||||||
chcpumf: chcpumf.o $(libs)
|
chcpumf: chcpumf.o $(libs)
|
||||||
lshwc: lshwc.o $(libs)
|
lshwc: lshwc.o $(libs)
|
||||||
pai: pai.o $(libs)
|
pai: pai.o $(libs)
|
||||||
|
lspai: lspai.o $(libs)
|
||||||
|
|
||||||
install: all install-man
|
install: all install-man
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||||
|
|||||||
+352
@@ -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;
|
||||||
|
}
|
||||||
@@ -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 ]
|
.IR size ]
|
||||||
.RB [ \-i | \-\-interval
|
.RB [ \-i | \-\-interval
|
||||||
.IR ms ]
|
.IR ms ]
|
||||||
|
.RB [ \-R | \-\-realtime
|
||||||
|
.IR prio ]
|
||||||
.BR \-c | \-\-crypto [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
|
.BR \-c | \-\-crypto [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
|
||||||
.br
|
.br
|
||||||
\*c
|
\*c
|
||||||
@@ -25,6 +27,8 @@
|
|||||||
.IR size ]
|
.IR size ]
|
||||||
.RB [ \-i | \-\-interval
|
.RB [ \-i | \-\-interval
|
||||||
.IR ms ]
|
.IR ms ]
|
||||||
|
.RB [ \-R | \-\-realtime
|
||||||
|
.IR prio ]
|
||||||
.BR \-n | \-\-nnpa [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
|
.BR \-n | \-\-nnpa [ \fIcpulist ][: \fIdata\fR "] [" \fIloops\fP ]
|
||||||
.br
|
.br
|
||||||
\*c
|
\*c
|
||||||
@@ -191,6 +195,14 @@ The ring buffer is created with the
|
|||||||
.IR mmap (2)
|
.IR mmap (2)
|
||||||
system call.
|
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
|
.SH ARGUMENT
|
||||||
The command line options determine how command line
|
The command line options determine how command line
|
||||||
arguments are interpreted.
|
arguments are interpreted.
|
||||||
|
|||||||
+21
@@ -944,6 +944,11 @@ static struct util_opt opt_vec[] = {
|
|||||||
.option = { "report", no_argument, NULL, 'r' },
|
.option = { "report", no_argument, NULL, 'r' },
|
||||||
.desc = "Report file contents"
|
.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' },
|
.option = { "interval", required_argument, NULL, 'i' },
|
||||||
.argument = "NUMBER",
|
.argument = "NUMBER",
|
||||||
@@ -1007,6 +1012,19 @@ static unsigned long check_mapsize(unsigned long n)
|
|||||||
return cnt == 1 ? n : 0;
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool crypto_record = false, report = false;
|
bool crypto_record = false, report = false;
|
||||||
@@ -1061,6 +1079,9 @@ int main(int argc, char **argv)
|
|||||||
record_cpus_nnpa(optarg);
|
record_cpus_nnpa(optarg);
|
||||||
nnpa_record = true;
|
nnpa_record = true;
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
setprio(optarg);
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
report = true;
|
report = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+23
-24
@@ -15,13 +15,13 @@ dasdfmt \- formatting of DASD (ECKD) disk drives.
|
|||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it
|
\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').
|
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').
|
(e.g. '/dev/dasd/0.0.b100/disc').
|
||||||
.br
|
.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.
|
\fBLOSS OF DATA\fR.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
@@ -31,7 +31,7 @@ Print usage and exit.
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-t\fR or \fB--test\fR
|
\fB-t\fR or \fB--test\fR
|
||||||
Disables any modification of the disk drive.
|
Disables any modification of the disk drive.
|
||||||
.br
|
.br
|
||||||
\fBdasdfmt\fR just prints
|
\fBdasdfmt\fR just prints
|
||||||
out, what it \fBwould\fR do.
|
out, what it \fBwould\fR do.
|
||||||
@@ -41,7 +41,7 @@ out, what it \fBwould\fR do.
|
|||||||
Increases verbosity.
|
Increases verbosity.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-y\fR
|
\fB-y\fR
|
||||||
Start formatting without further user-confirmation.
|
Start formatting without further user-confirmation.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
@@ -59,7 +59,7 @@ Omit the writing of a disk label after formatting.
|
|||||||
.br
|
.br
|
||||||
This makes only sense for the 'ldl' disk layout.
|
This makes only sense for the 'ldl' disk layout.
|
||||||
.br
|
.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
|
.br
|
||||||
|
|
||||||
e.g. dasdfmt -d ldl -L /dev/...
|
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
|
\fIlayout\fR is either \fIcdl\fR for the compatible disk layout
|
||||||
(default) or \fIldl\fR for the linux disk layout.
|
(default) or \fIldl\fR for the linux disk layout.
|
||||||
.br
|
.br
|
||||||
Compatible disk layout means a special handling of the
|
Compatible disk layout means a special handling of the
|
||||||
first two tracks of the volume. This enables other S/390 or zSeries
|
first two tracks of the volume. This enables other S/390 or zSeries
|
||||||
operating systems to access this device (e.g. for backup purposes).
|
operating systems to access this device (e.g. for backup purposes).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-p\fR or \fB--progressbar\fR
|
\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,
|
Do not use this option if you are using a 3270 console,
|
||||||
running in background or redirecting the output to a file.
|
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
|
.TP
|
||||||
\fB-l\fR \fIvolser\fR or \fB--label\fR=\fIvolser\fR
|
\fB-l\fR \fIvolser\fR or \fB--label\fR=\fIvolser\fR
|
||||||
Specify the volume serial number or volume identifier to be written
|
Specify the volume serial number or volume identifier to be written
|
||||||
to disk after formatting. If no label is specified, a sensible default
|
to disk after formatting. If no label is specified, a sensible default
|
||||||
is used. \fIvolser\fR is interpreted as ASCII string and is automatically
|
is used. \fIvolser\fR is interpreted as ASCII string and is automatically
|
||||||
converted to uppercase and then to EBCDIC.
|
converted to uppercase and then to EBCDIC.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
e.g. -l LNX001 or --label=DASD01
|
e.g. -l LNX001 or --label=DASD01
|
||||||
.br
|
.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
|
number is 1 through 6 alphanumeric or one of the following special
|
||||||
characters: $, #, @, %. Enclose a serial number that contains special
|
characters: $, #, @, %. Enclose a serial number that contains special
|
||||||
characters in apostrophes. If the number is shorter than six
|
characters in apostrophes. If the number is shorter than six
|
||||||
characters, it is padded with trailing blanks.
|
characters, it is padded with trailing blanks.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
Do not code a volume serial number as SCRTCH, PRIVAT, or Lnnnnn (L with
|
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
|
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
|
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
|
used by the OS/390 Hierarchical Storage Manager DFSMShsm for migrated
|
||||||
data sets.
|
data sets.
|
||||||
.br
|
.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
|
.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.
|
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
|
.br
|
||||||
@@ -197,9 +197,8 @@ e.g. -l 'a@b\\$c#' to get A@B$C#
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-k\fR or \fB--keep_volser\fR
|
\fB-k\fR or \fB--keep_volser\fR
|
||||||
Keeps the Volume Serial Number, when writing the Volume Label. This is
|
Keeps the Volume Serial Number when writing the Volume Label. This is useful if
|
||||||
useful, if the Serial Number has been written with a VM Tool and should not
|
the volume already has a Serial Number that should not be overwritten.
|
||||||
be overwritten.
|
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
|||||||
+25
-25
@@ -19,10 +19,10 @@ help:
|
|||||||
.br
|
.br
|
||||||
\fBfdasd\fR {-h|-v}
|
\fBfdasd\fR {-h|-v}
|
||||||
.SH DESCRIPTION
|
.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
|
formatted DASD, in the form of
|
||||||
a VTOC (volume table of contents) for usage with Linux for S/390
|
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.
|
will use it, otherwise it asks to write a new one.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
@@ -34,51 +34,51 @@ will use it, otherwise it asks to write a new one.
|
|||||||
Print usage information, then exit.
|
Print usage information, then exit.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-v\fR or \fB--version\fR
|
\fB-v\fR or \fB--version\fR
|
||||||
Print version information, then exit.
|
Print version information, then exit.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-s\fR or \fB--silent\fR
|
\fB-s\fR or \fB--silent\fR
|
||||||
Suppress messages in non-interactive mode.
|
Suppress messages in non-interactive mode.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-r\fR or \fB--verbose\fR
|
\fB-r\fR or \fB--verbose\fR
|
||||||
Provide more verbose output.
|
Provide more verbose output.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-a\fR or \fB--auto\fR
|
\fB-a\fR or \fB--auto\fR
|
||||||
Automatically create a partition using the entire disk in non-interactive
|
Automatically create a partition using the entire disk in non-interactive
|
||||||
mode.
|
mode.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-k\fR or \fB--keep_volser\fR
|
\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
|
.br
|
||||||
This is useful, if the volume serial has been written before and should not
|
This is useful if the volume already has a Serial Number that should not be
|
||||||
be overwritten. This option is only applicable in non-interactive mode.
|
overwritten. This option is only applicable in non-interactive mode.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-l\fR \fIvolser\fR or \fB--label\fR \fIvolser\fR
|
\fB-l\fR \fIvolser\fR or \fB--label\fR \fIvolser\fR
|
||||||
Specify the volume serial.
|
Specify the volume serial.
|
||||||
.br
|
.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
|
uppercase, padded with blanks and finally converted to EBCDIC to be written
|
||||||
to disk. This option is only applicable in non-interactive mode.
|
to disk. This option is only applicable in non-interactive mode.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
Do not use the following reserved volume serial: SCRTCH, PRIVAT, MIGRAT,
|
Do not use the following reserved volume serial: SCRTCH, PRIVAT, MIGRAT,
|
||||||
or Lnnnnn (L with five digit number); These are used as keywords by
|
or Lnnnnn (L with five digit number); These are used as keywords by
|
||||||
other operating systems (OS/390).
|
other operating systems (OS/390).
|
||||||
.br
|
.br
|
||||||
|
|
||||||
A volume serial is 1 through 6 alphanumeric characters or one of the
|
A volume serial is 1 through 6 alphanumeric characters or one of the
|
||||||
following special characters: $, #, @, %. All other characters are simply
|
following special characters: $, #, @, %. All other characters are simply
|
||||||
ignored.
|
ignored.
|
||||||
.br
|
.br
|
||||||
Try to avoid using special characters in the volume serial.
|
Try to avoid using special characters in the volume serial.
|
||||||
This may cause problems accessing a disk by volser.
|
This may cause problems accessing a disk by volser.
|
||||||
In case you really have to use special characters, make sure you are using
|
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.
|
quotes. In addition there is a special handling for the '$' sign.
|
||||||
Please specify it using '\\$' if necessary.
|
Please specify it using '\\$' if necessary.
|
||||||
.br
|
.br
|
||||||
|
|
||||||
@@ -124,14 +124,14 @@ partitions that use the entire disk:
|
|||||||
.br
|
.br
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-i\fR or \fB--volser\fR
|
\fB-i\fR or \fB--volser\fR
|
||||||
Print the volume serial, then exit.
|
Print the volume serial, then exit.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB-p\fR or \fB--table\fR
|
\fB-p\fR or \fB--table\fR
|
||||||
Print partition table, then exit.
|
Print partition table, then exit.
|
||||||
.br
|
.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.
|
partition table.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
@@ -179,7 +179,7 @@ In case your are not using the device file system, please specify:
|
|||||||
.br
|
.br
|
||||||
|
|
||||||
where \fIx\fR is one or more lowercase letter(s) or any other device
|
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
|
.SH SEE ALSO
|
||||||
.BR dasdfmt (8)
|
.BR dasdfmt (8)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ stage3b.elf: head.o $(ZIPL_OBJS)
|
|||||||
|
|
||||||
%.bin.debug: %.elf
|
%.bin.debug: %.elf
|
||||||
$(OBJCOPY) --only-keep-debug $< $@
|
$(OBJCOPY) --only-keep-debug $< $@
|
||||||
|
@chmod a-x $@
|
||||||
|
|
||||||
%.bin: %.elf
|
%.bin: %.elf
|
||||||
$(OBJCOPY) -O binary $< $@
|
$(OBJCOPY) -O binary $< $@
|
||||||
|
|||||||
@@ -61,13 +61,17 @@ void __noreturn start(void)
|
|||||||
if (cmdline->size > get_kernel_cmdline_size())
|
if (cmdline->size > get_kernel_cmdline_size())
|
||||||
panic(EINTERNAL, "Command line is too large\n");
|
panic(EINTERNAL, "Command line is too large\n");
|
||||||
|
|
||||||
/* move the kernel cmdline */
|
if (cmdline->size > 0) {
|
||||||
memmove((void *)COMMAND_LINE,
|
/* make sure the cmdline is a null-terminated string */
|
||||||
(void *)cmdline->src,
|
if (((char *)cmdline->src)[cmdline->size - 1] != '\0')
|
||||||
cmdline->size);
|
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 */
|
/* 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 */
|
/* copy initrd start address and size into new kernel space */
|
||||||
*(unsigned long long *)INITRD_START = initrd->src;
|
*(unsigned long long *)INITRD_START = initrd->src;
|
||||||
*(unsigned long long *)INITRD_SIZE = initrd->size;
|
*(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;
|
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)
|
if (!comp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ PvBuffer *pv_buffer_alloc(gsize size)
|
|||||||
return ret;
|
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 *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned)
|
||||||
{
|
{
|
||||||
PvBuffer *ret;
|
PvBuffer *ret;
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ typedef struct PvBuffer {
|
|||||||
} PvBuffer;
|
} PvBuffer;
|
||||||
|
|
||||||
PvBuffer *pv_buffer_alloc(gsize size);
|
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_free(PvBuffer *buf);
|
||||||
void pv_buffer_clear(PvBuffer **buf);
|
void pv_buffer_clear(PvBuffer **buf);
|
||||||
gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err);
|
gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err);
|
||||||
|
|||||||
+3
-3
@@ -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;
|
s64 component1, component2, smt_us;
|
||||||
double smt_factor = g.o.smt_factor;
|
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)
|
if (thread_per_core > 1)
|
||||||
component1 /= smt_factor;
|
component1 /= smt_factor;
|
||||||
component2 = G0(thr_us - core_us);
|
component2 = thr_us - core_us;
|
||||||
smt_us = component1 + component2 + mgm_us;
|
smt_us = G0(component1 + component2 + mgm_us);
|
||||||
|
|
||||||
return smt_us;
|
return smt_us;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,19 @@
|
|||||||
#define STAGE2_DESC _AC(0x78, UL)
|
#define STAGE2_DESC _AC(0x78, UL)
|
||||||
#define STAGE2_ENTRY _AC(0x2018, UL)
|
#define STAGE2_ENTRY _AC(0x2018, UL)
|
||||||
#define STAGE2_HEAP_ADDRESS _AC(0x6000, 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_HEAP_SIZE _AC(0x3000, UL)
|
||||||
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
|
#define STAGE2_STACK_ADDRESS _AC(0xe400, UL)
|
||||||
#define STAGE2_STACK_SIZE _AC(0x1c00, 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_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 STAGE3_ENTRY _AC(0xa000, UL)
|
||||||
|
|
||||||
#define STAGE2_LOAD_ADDRESS _AC(0x2000, UL)
|
#define STAGE2_LOAD_ADDRESS _AC(0x2000, UL)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
#define STACK_FRAME_OVERHEAD _AC(160, U)
|
||||||
|
|
||||||
/* Facilities */
|
/* Facilities */
|
||||||
|
#define DFLTCC_FACILITY _AC(151, U)
|
||||||
#define UNPACK_FACILITY _AC(161, U)
|
#define UNPACK_FACILITY _AC(161, U)
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|||||||
@@ -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 */
|
/* Lock Functions */
|
||||||
int ap_get_lock(void);
|
int ap_get_lock(void);
|
||||||
int ap_get_lock_callout(void);
|
int ap_get_lock_callout(void);
|
||||||
|
int ap_try_lock_callout(void);
|
||||||
int ap_release_lock(void);
|
int ap_release_lock(void);
|
||||||
int ap_release_lock_callout(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_release(char *lockfile);
|
||||||
int util_lockfile_parent_release(char *lockfile);
|
int util_lockfile_parent_release(char *lockfile);
|
||||||
|
|
||||||
|
int util_lockfile_peek_owner(char *lockfile, int *pid);
|
||||||
|
|
||||||
#endif /** LIB_UTIL_LOCKFILE_H @} */
|
#endif /** LIB_UTIL_LOCKFILE_H @} */
|
||||||
|
|||||||
+28
@@ -722,6 +722,34 @@ int ap_get_lock_callout(void)
|
|||||||
return util_lockfile_parent_lock(AP_LOCKFILE, AP_LOCK_RETRIES);
|
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
|
* Release the ap config lock
|
||||||
*
|
*
|
||||||
|
|||||||
+4
-4
@@ -55,7 +55,7 @@ check-dep-libekmfweb: detect-openssl-version.dep
|
|||||||
"detect-openssl-version.dep", \
|
"detect-openssl-version.dep", \
|
||||||
"openssl-devel version >= 1.1.1", \
|
"openssl-devel version >= 1.1.1", \
|
||||||
"HAVE_OPENSSL=0", \
|
"HAVE_OPENSSL=0", \
|
||||||
-I. -lcrypto -DOPENSSL_SUPPRESS_DEPRECATED)
|
-I. `$(PKG_CONFIG) --cflags --libs libcrypto` -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
"libekmfweb", \
|
"libekmfweb", \
|
||||||
"json-c/json.h", \
|
"json-c/json.h", \
|
||||||
@@ -66,7 +66,7 @@ check-dep-libekmfweb: detect-openssl-version.dep
|
|||||||
"curl/curl.h", \
|
"curl/curl.h", \
|
||||||
"libcurl-devel", \
|
"libcurl-devel", \
|
||||||
"HAVE_LIBCURL=0" \
|
"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; }
|
$(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
|
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
|
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
|
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): ALL_CFLAGS += -fPIC `$(PKG_CONFIG) --cflags json-c libcurl libcrypto libssl`
|
||||||
libekmfweb.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl `$(CURL_CONFIG) --libs` -ldl
|
libekmfweb.so.$(VERSION): LDLIBS = `$(PKG_CONFIG) --libs json-c libcurl libcrypto libssl` -ldl
|
||||||
libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb.map \
|
libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb.map \
|
||||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
|
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
|
||||||
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o $(libs)
|
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o $(libs)
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ detect-openssl-version.dep:
|
|||||||
mv $(TMPFILE) $@
|
mv $(TMPFILE) $@
|
||||||
|
|
||||||
CURL_CONFIG ?= curl-config
|
CURL_CONFIG ?= curl-config
|
||||||
XML2_CONFIG ?= xml2-config
|
|
||||||
|
|
||||||
check-dep-libkmipclient: detect-openssl-version.dep
|
check-dep-libkmipclient: detect-openssl-version.dep
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
@@ -59,7 +58,7 @@ check-dep-libkmipclient: detect-openssl-version.dep
|
|||||||
"detect-openssl-version.dep", \
|
"detect-openssl-version.dep", \
|
||||||
"openssl-devel version >= 1.1.1", \
|
"openssl-devel version >= 1.1.1", \
|
||||||
"HAVE_OPENSSL=0", \
|
"HAVE_OPENSSL=0", \
|
||||||
-I. -lcrypto -DOPENSSL_SUPPRESS_DEPRECATED)
|
-I. `$(PKG_CONFIG) --cflags --libs libcrypto` -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
"libkmipclient", \
|
"libkmipclient", \
|
||||||
"json-c/json.h", \
|
"json-c/json.h", \
|
||||||
@@ -70,13 +69,13 @@ check-dep-libkmipclient: detect-openssl-version.dep
|
|||||||
"libxml/tree.h", \
|
"libxml/tree.h", \
|
||||||
"libxml2-devel", \
|
"libxml2-devel", \
|
||||||
"HAVE_LIBXML2=0", \
|
"HAVE_LIBXML2=0", \
|
||||||
`$(XML2_CONFIG) --cflags` `$(XML2_CONFIG) --libs`)
|
`$(PKG_CONFIG) --cflags --libs libxml-2.0`)
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
"libkmipclient", \
|
"libkmipclient", \
|
||||||
"curl/curl.h", \
|
"curl/curl.h", \
|
||||||
"libcurl-devel", \
|
"libcurl-devel", \
|
||||||
"HAVE_LIBCURL=0" \
|
"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; }
|
$(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
|
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
|
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
|
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): ALL_CFLAGS += -fPIC `$(PKG_CONFIG) --cflags json-c libcrypto libssl libxml-2.0 libcurl`
|
||||||
libkmipclient.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl `$(XML2_CONFIG) --libs` `$(CURL_CONFIG) --libs`
|
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 \
|
libkmipclient.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libkmipclient.map \
|
||||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libkmipclient.so.$(VERM)
|
-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 \
|
libkmipclient.so.$(VERSION): kmip.o request.o response.o attribute.o key.o ttlv.o json.o \
|
||||||
|
|||||||
+6
-6
@@ -311,13 +311,13 @@ int util_file_read_i(int *val, int base, const char *fmt, ...)
|
|||||||
return -1;
|
return -1;
|
||||||
switch (base) {
|
switch (base) {
|
||||||
case 8:
|
case 8:
|
||||||
count = sscanf(buf, "%do", val);
|
count = sscanf(buf, "%o", val);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
count = sscanf(buf, "%dd", val);
|
count = sscanf(buf, "%d", val);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
count = sscanf(buf, "%dx", val);
|
count = sscanf(buf, "%x", val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
util_panic("Invalid base: %d\n", base);
|
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;
|
return -1;
|
||||||
switch (base) {
|
switch (base) {
|
||||||
case 8:
|
case 8:
|
||||||
count = sscanf(buf, "%uo", val);
|
count = sscanf(buf, "%o", val);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
count = sscanf(buf, "%uu", val);
|
count = sscanf(buf, "%u", val);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
count = sscanf(buf, "%ux", val);
|
count = sscanf(buf, "%x", val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
util_panic("Invalid base: %d\n", base);
|
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 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 */
|
/* we may use header_generic and header_simple_table from the util_funcs module */
|
||||||
|
|
||||||
config_require(util_funcs)
|
config_require(util_funcs);
|
||||||
|
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
|
|||||||
@@ -9,6 +9,3 @@ target/
|
|||||||
# Generated during make build can be removed at any point
|
# Generated during make build can be removed at any point
|
||||||
.check-dep-pvtools
|
.check-dep-pvtools
|
||||||
.check-cargo
|
.check-cargo
|
||||||
|
|
||||||
# Ignore lock files by default
|
|
||||||
Cargo.lock
|
|
||||||
|
|||||||
+668
-16
@@ -2,6 +2,30 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
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]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -57,24 +81,61 @@ version = "1.0.71"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
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]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
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]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.79"
|
version = "1.0.79"
|
||||||
@@ -106,7 +167,7 @@ checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
"strsim",
|
"strsim",
|
||||||
"terminal_size",
|
"terminal_size",
|
||||||
@@ -147,15 +208,15 @@ dependencies = [
|
|||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"schannel",
|
"schannel",
|
||||||
"socket2",
|
"socket2 0.4.9",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "curl-sys"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc"
|
checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -163,9 +224,15 @@ dependencies = [
|
|||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"vcpkg",
|
"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]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -187,6 +254,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -202,12 +275,152 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
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]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -220,6 +433,64 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
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]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.3"
|
version = "1.9.3"
|
||||||
@@ -227,7 +498,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"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]]
|
[[package]]
|
||||||
@@ -259,6 +540,12 @@ version = "1.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.146"
|
version = "0.2.146"
|
||||||
@@ -283,12 +570,85 @@ version = "0.3.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
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]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.19"
|
version = "0.4.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
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]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
@@ -297,11 +657,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.54"
|
version = "0.10.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019"
|
checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.4.1",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -329,9 +689,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.88"
|
version = "0.9.96"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617"
|
checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -350,12 +710,59 @@ dependencies = [
|
|||||||
"openssl-sys",
|
"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]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.27"
|
version = "0.3.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.60"
|
version = "1.0.60"
|
||||||
@@ -373,11 +780,14 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"clap",
|
"clap",
|
||||||
"curl",
|
"curl",
|
||||||
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"mockito",
|
||||||
"openssl",
|
"openssl",
|
||||||
"openssl_extensions",
|
"openssl_extensions",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_test",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
@@ -404,12 +814,86 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rand"
|
||||||
version = "0.37.20"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
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",
|
"errno",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -432,6 +916,12 @@ dependencies = [
|
|||||||
"windows-sys 0.42.0",
|
"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]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.164"
|
version = "1.0.164"
|
||||||
@@ -452,19 +942,81 @@ dependencies = [
|
|||||||
"syn 2.0.18",
|
"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]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.9.21"
|
version = "0.9.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c"
|
checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 1.9.3",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
"unsafe-libyaml",
|
"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]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
@@ -475,6 +1027,16 @@ dependencies = [
|
|||||||
"winapi",
|
"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]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -533,6 +1095,81 @@ dependencies = [
|
|||||||
"syn 2.0.18",
|
"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]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
@@ -561,6 +1198,21 @@ version = "0.2.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
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]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"pv",
|
||||||
|
"pvsecret",
|
||||||
|
"utils",
|
||||||
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
|
[workspace.package]
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
+18
-25
@@ -15,16 +15,17 @@ ifneq (${HAVE_CARGO},0)
|
|||||||
|
|
||||||
BUILD_TARGETS = $(CARGO_TARGETS)
|
BUILD_TARGETS = $(CARGO_TARGETS)
|
||||||
INSTALL_TARGETS := install-rust-tools install-man
|
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_OPENSSL},0)
|
||||||
ifneq (${HAVE_LIBCURL},0)
|
ifneq (${HAVE_LIBCURL},0)
|
||||||
PV_TARGETS := pvsecret
|
PV_TARGETS := pvsecret
|
||||||
|
|
||||||
PV_BUILD_TARGETS = $(PV_TARGETS)
|
PV_BUILD_TARGETS := $(PV_TARGETS)
|
||||||
CARGO_TEST_TARGETS += $(addsuffix, _test, $(PV_TARGETS)) pv
|
CARGO_TEST_TARGETS += $(addsuffix .test,pv $(PV_TARGETS))
|
||||||
endif #LIBCURL
|
endif #LIBCURL
|
||||||
endif #OPENSSL
|
endif #OPENSSL
|
||||||
|
TEST_TARGETS := $(addsuffix _build,$(CARGO_TEST_TARGETS))
|
||||||
endif #CARGO
|
endif #CARGO
|
||||||
|
|
||||||
BUILD_TARGETS += $(PV_BUILD_TARGETS)
|
BUILD_TARGETS += $(PV_BUILD_TARGETS)
|
||||||
@@ -39,18 +40,15 @@ endif
|
|||||||
$(BUILD_TARGETS) rust-test: CC = $(CC_SILENT)
|
$(BUILD_TARGETS) rust-test: CC = $(CC_SILENT)
|
||||||
$(BUILD_TARGETS) rust-test: AR = $(AR_SILENT)
|
$(BUILD_TARGETS) rust-test: AR = $(AR_SILENT)
|
||||||
|
|
||||||
$(CARGO_TARGETS): .check-cargo .no-cross-compile
|
$(PV_TARGETS): .check-dep-pvtools
|
||||||
$(CARGO_BUILD) --manifest-path=$@/Cargo.toml $(ALL_CARGOFLAGS)
|
$(PV_TARGETS) $(CARGO_TARGETS): .check-cargo .no-cross-compile
|
||||||
.PHONY: $(CARGO_TARGETS)
|
$(CARGO_BUILD) --bin $@ $(ALL_CARGOFLAGS)
|
||||||
|
.PHONY: $(PV_TARGETS) $(CARGO_TARGETS)
|
||||||
|
|
||||||
|
$(TEST_TARGETS): ALL_CARGOFLAGS += --no-run
|
||||||
$(CARGO_TEST_TARGETS): .check-cargo .no-cross-compile
|
$(CARGO_TEST_TARGETS) $(TEST_TARGETS): .check-cargo .no-cross-compile
|
||||||
$(CARGO_TEST) --manifest-path=$@/Cargo.toml --all-features $(CARGOFLAGS)
|
$(CARGO_TEST) --package $(basename $@) --all-features $(ALL_CARGOFLAGS)
|
||||||
.PHONY: $(CARGO_TEST_TARGETS)
|
.PHONY: $(TEST_TARGETS) $(CARGO_TEST_TARGETS)
|
||||||
|
|
||||||
$(PV_TARGETS): .check-cargo .no-cross-compile .check-dep-pvtools
|
|
||||||
$(CARGO_BUILD) --manifest-path=$@/Cargo.toml $(ALL_CARGOFLAGS)
|
|
||||||
.PHONY: $(PV_TARGETS)
|
|
||||||
|
|
||||||
skip-build:
|
skip-build:
|
||||||
echo " SKIP rust-tools due to unresolved dependencies"
|
echo " SKIP rust-tools due to unresolved dependencies"
|
||||||
@@ -65,22 +63,17 @@ print-rust-targets:
|
|||||||
echo $(BUILD_TARGETS)
|
echo $(BUILD_TARGETS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(foreach target,$(CARGO_TARGETS),\
|
$(CARGO_CLEAN) ${ALL_CARGOFLAGS}
|
||||||
$(CARGO_CLEAN) --manifest-path=$(target)/Cargo.toml ${ALL_CARGOFLAGS} ;)
|
|
||||||
$(foreach target,$(PV_TARGETS),\
|
|
||||||
$(CARGO_CLEAN) --manifest-path=$(target)/Cargo.toml ${CARGOFLAGS} ;)
|
|
||||||
$(RM) -- .check-dep-pvtools .detect-openssl.dep.c .check-cargo
|
$(RM) -- .check-dep-pvtools .detect-openssl.dep.c .check-cargo
|
||||||
|
|
||||||
rust-test: .check-cargo .no-cross-compile
|
rust-test: $(CARGO_TEST_TARGETS)
|
||||||
$(foreach target,$(CARGO_TEST_TARGETS),\
|
|
||||||
$(CARGO_TEST) --manifest-path=$(target)/Cargo.toml --all-features ${ALL_CARGOFLAGS} ;)
|
|
||||||
|
|
||||||
install-rust-tools: $(BUILD_TARGETS)
|
install-rust-tools: $(BUILD_TARGETS)
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||||
$(foreach target,$(CARGO_TARGETS),\
|
$(foreach target,$(CARGO_TARGETS),\
|
||||||
$(INSTALL) $(target)/target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
$(INSTALL) target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
||||||
$(foreach target,$(PV_TARGETS),\
|
$(foreach target,$(PV_TARGETS),\
|
||||||
$(INSTALL) $(target)/target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
$(INSTALL) target/release/$(target) $(DESTDIR)$(USRBINDIR);)
|
||||||
|
|
||||||
install-man:
|
install-man:
|
||||||
$(foreach target,$(CARGO_TARGETS),\
|
$(foreach target,$(CARGO_TARGETS),\
|
||||||
@@ -118,13 +111,13 @@ endif
|
|||||||
|
|
||||||
.check-dep-pvtools: .detect-openssl.dep.c
|
.check-dep-pvtools: .detect-openssl.dep.c
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
"$(BIN_PROGRAM)", \
|
"Rust-pv", \
|
||||||
$^, \
|
$^, \
|
||||||
"openssl-devel / libssl-dev version >= 1.1.1", \
|
"openssl-devel / libssl-dev version >= 1.1.1", \
|
||||||
"HAVE_OPENSSL=0", \
|
"HAVE_OPENSSL=0", \
|
||||||
"-I.")
|
"-I.")
|
||||||
$(call check_dep, \
|
$(call check_dep, \
|
||||||
"$(BIN_PROGRAM)", \
|
"Rust-pv", \
|
||||||
"curl/curl.h", \
|
"curl/curl.h", \
|
||||||
"libcurl-devel", \
|
"libcurl-devel", \
|
||||||
"HAVE_LIBCURL=0")
|
"HAVE_LIBCURL=0")
|
||||||
|
|||||||
+25
-9
@@ -7,21 +7,21 @@ https://www.rust-lang.org/learn/get-started
|
|||||||
## Building rust code
|
## Building rust code
|
||||||
### s390-tools build system
|
### s390-tools build system
|
||||||
If `cargo` is installed a simple `make` should do the job. Note that,
|
If `cargo` is installed a simple `make` should do the job. Note that,
|
||||||
compiling rust programs take significaltly longer than C code. To closely
|
compiling rust programs take significantly longer than C code. To closely
|
||||||
monitor the prgress use `make V=1` By default release builds are made.
|
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 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 HAVE_CARGO=0` one can turn of any compilation that requires cargo.
|
||||||
With `make CARGO=<...>` one can set the cargo binary
|
With `make CARGO=<...>` one can set the cargo binary
|
||||||
|
|
||||||
### cargo
|
### 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
|
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
|
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
|
`S390_TOOLS_RELEASE` to be present at build time. This is the version string the
|
||||||
rust tools provide.
|
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
|
## Internal Libraries
|
||||||
* __utils__ _Library for rust tools that bundles common stuff for the 390-tools_
|
* __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?
|
### What (third-party) crates can be used for s390-tools?
|
||||||
A huge list of libraries are made available through Rusts' ecosystem and is one
|
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,
|
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
|
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.
|
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.
|
Dependencies used by the crates listed above can be used, too.
|
||||||
|
|
||||||
### Add new tool
|
### 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:
|
Add the tool to the _s390-tools_ build system:
|
||||||
```Makefile
|
```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
|
### Versions
|
||||||
@@ -98,8 +114,8 @@ use utils::release_string;
|
|||||||
fn print_version() {
|
fn print_version() {
|
||||||
println!(
|
println!(
|
||||||
"{} version {}\nCopyright IBM Corp. 2023",
|
"{} version {}\nCopyright IBM Corp. 2023",
|
||||||
env!("CARGO_PKG_NAME"), // collapes into the crates name
|
env!("CARGO_PKG_NAME"), // collapses into the crates name
|
||||||
release_string!() // this (very likely) collapes into a compile time constant
|
release_string!() // this (very likely) collapses into a compile time constant
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
+11
-15
@@ -1,36 +1,32 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "pv"
|
name = "pv"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
edition = "2021"
|
edition.workspace = true
|
||||||
license = "MIT"
|
license.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2.49"
|
||||||
log = { version = "0.4", features = ["std", "release_max_level_debug"] }
|
log = { version = "0.4.6", features = ["std", "release_max_level_debug"] }
|
||||||
thiserror = "1"
|
thiserror = "1.0.33"
|
||||||
zerocopy = "0.6"
|
zerocopy = "0.6"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
# dependencies for request feature
|
# dependencies for request feature
|
||||||
clap = { version ="4", features = ["derive", "wrap_help"], optional = true }
|
clap = { version ="4", features = ["derive", "wrap_help"], optional = true }
|
||||||
curl = { version ="0.4", optional = true }
|
curl = { version ="0.4.7", optional = true }
|
||||||
openssl = {version = "0.10", optional = true }
|
openssl = {version = "0.10.49", optional = true }
|
||||||
openssl_extensions = { path = "openssl_extensions", 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
|
# misc optional dependencies
|
||||||
byteorder = {version = "1", optional = true }
|
byteorder = {version = "1.3", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
mockito = {version = "0.31", default-features = false }
|
mockito = {version = "1", default-features = false }
|
||||||
serde_test = "1"
|
serde_test = "1"
|
||||||
lazy_static = "1"
|
lazy_static = "1.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
request = ["dep:openssl", "dep:curl", "dep:openssl_extensions", "dep:serde", "dep:clap"]
|
request = ["dep:openssl", "dep:curl", "dep:openssl_extensions", "dep:serde", "dep:clap"]
|
||||||
uvsecret = ["dep:byteorder", "dep:serde"]
|
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]
|
[package]
|
||||||
name = "openssl_extensions"
|
name = "openssl_extensions"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition.workspace = true
|
||||||
license = "MIT"
|
license.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
foreign-types = "0.3"
|
foreign-types = "0.3.1"
|
||||||
libc = {version = "0.2", features = [ "extra_traits"] }
|
libc = {version = "0.2.49", features = [ "extra_traits"] }
|
||||||
log = { version = "0.4", features = ["std", "release_max_level_debug"] }
|
log = { version = "0.4.6", features = ["std", "release_max_level_debug"] }
|
||||||
openssl = "0.10"
|
openssl = "0.10.49"
|
||||||
openssl-sys = "0.9"
|
openssl-sys = "0.9.85"
|
||||||
|
|||||||
+2
-2
@@ -205,7 +205,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn from_se_image_hdr() {
|
fn from_se_image_hdr() {
|
||||||
let bin_hdr = get_test_asset!("exp/secure_guest.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);
|
assert_eq!(hdr_tags, EXP_HDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ mod tests {
|
|||||||
));
|
));
|
||||||
|
|
||||||
// mess up magic
|
// mess up magic
|
||||||
let mut bin_hdr_copy = bin_hdr.clone();
|
let mut bin_hdr_copy = *bin_hdr;
|
||||||
bin_hdr_copy.swap(0, 1);
|
bin_hdr_copy.swap(0, 1);
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
BootHdrTags::from_se_image(&mut Cursor::new(bin_hdr_copy)),
|
BootHdrTags::from_se_image(&mut Cursor::new(bin_hdr_copy)),
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let res = encrypt_aes(
|
let res = encrypt_aes(
|
||||||
&&SymKey::Aes256(aes_gcm_key.into()),
|
&SymKey::Aes256(aes_gcm_key.into()),
|
||||||
&aes_gcm_iv,
|
&aes_gcm_iv,
|
||||||
&aes_gcm_plain,
|
&aes_gcm_plain,
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -451,7 +451,7 @@ mod tests {
|
|||||||
let ks = vec![
|
let ks = vec![
|
||||||
Keyslot::new(host_key.clone()),
|
Keyslot::new(host_key.clone()),
|
||||||
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();
|
let mut aad = Vec::<Aad>::new();
|
||||||
ks.iter().for_each(|ks| aad.push(Aad::Ks(ks)));
|
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
|
// * Vec allocated at least capacity elements continuously
|
||||||
// * dst points always to a valid location
|
// * dst points always to a valid location
|
||||||
unsafe {
|
unsafe {
|
||||||
|
std::ptr::write_volatile(dst, 0);
|
||||||
dst = dst.add(1);
|
dst = dst.add(1);
|
||||||
std::ptr::write_volatile(dst, 0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst);
|
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ mod test {
|
|||||||
0xef, 0xc7, 0x3c, 0x62,
|
0xef, 0xc7, 0x3c, 0x62,
|
||||||
];
|
];
|
||||||
let name = "association secret".to_string();
|
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 {
|
let exp = GuestSecret::Association {
|
||||||
name,
|
name,
|
||||||
id: exp_id,
|
id: exp_id,
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl Display for SecretEntry {
|
|||||||
writeln!(f, "{} {}:", self.index, stype_str(self.stype.get()))?;
|
writeln!(f, "{} {}:", self.index, stype_str(self.stype.get()))?;
|
||||||
write!(f, " ")?;
|
write!(f, " ")?;
|
||||||
for b in self.id {
|
for b in self.id {
|
||||||
write!(f, "{:02x}", b)?;
|
write!(f, "{b:02x}")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -484,20 +484,20 @@ mod test {
|
|||||||
let ibm_wrong_subj = load_gen_cert("ibm_wrong_subject.crt");
|
let ibm_wrong_subj = load_gen_cert("ibm_wrong_subject.crt");
|
||||||
let no_sign_crt = load_gen_cert("inter_ca.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!(
|
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))
|
Err(Error::HkdVerify(ManyIbmSignKeys))
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
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))
|
Err(Error::HkdVerify(NoIbmSignKey))
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
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))
|
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]
|
#[test]
|
||||||
|
|||||||
+34
-42
@@ -14,7 +14,9 @@ use crate::test_utils::*;
|
|||||||
pub fn mock_endpt(res: &str) -> mockito::Mock {
|
pub fn mock_endpt(res: &str) -> mockito::Mock {
|
||||||
let res_path = get_cert_asset_path(res);
|
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_header("content-type", "application/pkix-crl")
|
||||||
.with_body_from_file(res_path)
|
.with_body_from_file(res_path)
|
||||||
.create()
|
.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) {
|
fn verify_sign_error_slice(exp_raw: &[libc::c_int], obs: Error) {
|
||||||
if exp_raw
|
if exp_raw
|
||||||
.into_iter()
|
.iter()
|
||||||
.filter(|e| match &obs {
|
.filter(|e| match &obs {
|
||||||
Error::HkdVerify(ty) => match ty {
|
Error::HkdVerify(ty) => match ty {
|
||||||
IbmSignInvalid(err, _d) => &&err.as_raw() == e,
|
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 ibm_str = get_cert_asset_path_string("ibm.crt");
|
||||||
let inter_str = get_cert_asset_path_string("inter.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());
|
assert!(store.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +65,7 @@ fn verify_chain_online() {
|
|||||||
|
|
||||||
let mock_inter = mock_endpt("inter_ca.crl");
|
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();
|
download_crls_into_store(&mut store, slice::from_ref(&ibm_crt)).unwrap();
|
||||||
let store = store.build();
|
let store = store.build();
|
||||||
|
|
||||||
@@ -71,8 +73,8 @@ fn verify_chain_online() {
|
|||||||
|
|
||||||
let mut sk = Stack::<X509>::new().unwrap();
|
let mut sk = Stack::<X509>::new().unwrap();
|
||||||
sk.push(inter_crt).unwrap();
|
sk.push(inter_crt).unwrap();
|
||||||
verify_chain(&store, &sk, &vec![ibm_crt.clone()]).unwrap();
|
verify_chain(&store, &sk, &[ibm_crt.clone()]).unwrap();
|
||||||
assert!(verify_chain(&store, &sk, &vec!(ibm_crt)).is_ok());
|
assert!(verify_chain(&store, &sk, &[ibm_crt]).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -82,13 +84,13 @@ fn verify_chain_offline() {
|
|||||||
let inter_crt = load_gen_cert("inter_ca.crt");
|
let inter_crt = load_gen_cert("inter_ca.crt");
|
||||||
let root_crt = get_cert_asset_path_string("root_ca.chained.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()
|
.unwrap()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut sk = Stack::<X509>::new().unwrap();
|
let mut sk = Stack::<X509>::new().unwrap();
|
||||||
sk.push(inter_crt).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]
|
#[test]
|
||||||
@@ -107,8 +109,8 @@ fn verify_online() {
|
|||||||
let inter_crl = get_cert_asset_path_string("inter_ca.crl");
|
let inter_crl = get_cert_asset_path_string("inter_ca.crl");
|
||||||
let ibm_crl = get_cert_asset_path_string("ibm.crl");
|
let ibm_crl = get_cert_asset_path_string("ibm.crl");
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![ibm_crt, inter_crt],
|
&[ibm_crt, inter_crt],
|
||||||
&vec![ibm_crl, inter_crl],
|
&[ibm_crl, inter_crl],
|
||||||
&Some(root_crt),
|
&Some(root_crt),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
@@ -148,8 +150,8 @@ fn verify_offline() {
|
|||||||
let hkd = load_gen_cert("host.crt");
|
let hkd = load_gen_cert("host.crt");
|
||||||
|
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![ibm_crt, inter_crt],
|
&[ibm_crt, inter_crt],
|
||||||
&vec![ibm_crl, inter_crl],
|
&[ibm_crl, inter_crl],
|
||||||
&Some(root_crt),
|
&Some(root_crt),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
@@ -186,25 +188,20 @@ fn verifier_new() {
|
|||||||
let ibm_rev_crt = get_cert_asset_path_string("ibm_rev.crt");
|
let ibm_rev_crt = get_cert_asset_path_string("ibm_rev.crt");
|
||||||
|
|
||||||
// To many signing keys
|
// To many signing keys
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(&[ibm_crt.clone(), ibm_rev_crt.clone()], &[], &None, true);
|
||||||
&vec![ibm_crt.clone(), ibm_rev_crt.clone()],
|
|
||||||
&vec![],
|
|
||||||
&None,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
assert!(matches!(verifier, Err(Error::HkdVerify(ManyIbmSignKeys))));
|
assert!(matches!(verifier, Err(Error::HkdVerify(ManyIbmSignKeys))));
|
||||||
|
|
||||||
// no CRL for each X509
|
// no CRL for each X509
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
&[inter_crt.clone(), ibm_crt.clone()],
|
||||||
&vec![inter_crl.clone()],
|
&[inter_crl.clone()],
|
||||||
&Some(root_crt.clone()),
|
&Some(root_crt),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
verify_sign_error(3, verifier.unwrap_err());
|
verify_sign_error(3, verifier.unwrap_err());
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
&[inter_crt.clone(), ibm_crt.clone()],
|
||||||
&vec![],
|
&[],
|
||||||
&Some(root_chn_crt.clone()),
|
&Some(root_chn_crt.clone()),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
@@ -212,8 +209,8 @@ fn verifier_new() {
|
|||||||
|
|
||||||
// wrong intermediate (or ibm key)
|
// wrong intermediate (or ibm key)
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_fake_crt, ibm_crt.clone()],
|
&[inter_fake_crt, ibm_crt.clone()],
|
||||||
&vec![inter_fake_crl],
|
&[inter_fake_crl],
|
||||||
&Some(root_chn_crt.clone()),
|
&Some(root_chn_crt.clone()),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
@@ -222,8 +219,8 @@ fn verifier_new() {
|
|||||||
|
|
||||||
//wrong root ca
|
//wrong root ca
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
&[inter_crt.clone(), ibm_crt.clone()],
|
||||||
&vec![inter_crl.clone()],
|
&[inter_crl.clone()],
|
||||||
&None,
|
&None,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
@@ -231,33 +228,28 @@ fn verifier_new() {
|
|||||||
|
|
||||||
//correct signing key + intermediate cert
|
//correct signing key + intermediate cert
|
||||||
let _verifier = CertVerifier::new(
|
let _verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_crt.clone()],
|
&[inter_crt.clone(), ibm_crt.clone()],
|
||||||
&vec![inter_crl.clone()],
|
&[inter_crl.clone()],
|
||||||
&Some(root_chn_crt.clone()),
|
&Some(root_chn_crt.clone()),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// no intermediate key
|
// no intermediate key
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(&[ibm_crt], &[], &Some(root_chn_crt.clone()), false);
|
||||||
&vec![ibm_crt.clone()],
|
|
||||||
&vec![],
|
|
||||||
&Some(root_chn_crt.clone()),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
verify_sign_error(20, verifier.unwrap_err());
|
verify_sign_error(20, verifier.unwrap_err());
|
||||||
|
|
||||||
//Ibm Sign outdated
|
//Ibm Sign outdated
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_early_crt.clone()],
|
&[inter_crt.clone(), ibm_early_crt],
|
||||||
&vec![inter_crl.clone()],
|
&[inter_crl.clone()],
|
||||||
&Some(root_chn_crt.clone()),
|
&Some(root_chn_crt.clone()),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
assert!(matches!(verifier, Err(Error::HkdVerify(NoIbmSignKey))));
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_late_crt.clone()],
|
&[inter_crt.clone(), ibm_late_crt],
|
||||||
&vec![inter_crl.clone()],
|
&[inter_crl.clone()],
|
||||||
&Some(root_chn_crt.clone()),
|
&Some(root_chn_crt.clone()),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
@@ -265,9 +257,9 @@ fn verifier_new() {
|
|||||||
|
|
||||||
// revoked
|
// revoked
|
||||||
let verifier = CertVerifier::new(
|
let verifier = CertVerifier::new(
|
||||||
&vec![inter_crt.clone(), ibm_rev_crt.clone()],
|
&[inter_crt, ibm_rev_crt],
|
||||||
&vec![inter_crl.clone()],
|
&[inter_crl],
|
||||||
&Some(root_chn_crt.clone()),
|
&Some(root_chn_crt),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
verify_sign_error(23, verifier.unwrap_err());
|
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 TAGS: BootHdrTags = BootHdrTags::new([1; 64], [2; 64], [3; 64], [4; 16]);
|
||||||
const CUID: ConfigUid = [0x42u8; 16];
|
const CUID: ConfigUid = [0x42u8; 16];
|
||||||
const ASSOC_SECRET: [u8; 32] = [0x11; 32];
|
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(
|
fn create_asrcb(
|
||||||
guest_secret: GuestSecret,
|
guest_secret: GuestSecret,
|
||||||
@@ -38,7 +38,7 @@ fn create_asrcb(
|
|||||||
};
|
};
|
||||||
|
|
||||||
asrcb.add_hostkey(hkd);
|
asrcb.add_hostkey(hkd);
|
||||||
Ok(asrcb.encrypt(ctx)?)
|
asrcb.encrypt(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_crypto() -> (PKey<Public>, ReqEncrCtx) {
|
fn get_crypto() -> (PKey<Public>, ReqEncrCtx) {
|
||||||
@@ -63,17 +63,10 @@ where
|
|||||||
{
|
{
|
||||||
let (host_key, ctx) = get_crypto();
|
let (host_key, ctx) = get_crypto();
|
||||||
let cuid = match cuid {
|
let cuid = match cuid {
|
||||||
true => Some(CUID.into()),
|
true => Some(CUID),
|
||||||
false => None,
|
false => None,
|
||||||
};
|
};
|
||||||
create_asrcb(
|
create_asrcb(guest_secret, ext_secret.into(), flags, cuid, host_key, &ctx)
|
||||||
guest_secret,
|
|
||||||
ext_secret.into(),
|
|
||||||
flags,
|
|
||||||
cuid.into(),
|
|
||||||
host_key,
|
|
||||||
&ctx,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn association() -> GuestSecret {
|
fn association() -> GuestSecret {
|
||||||
@@ -156,7 +149,7 @@ fn null_none_default_cuid_seven() {
|
|||||||
let mut asrcb =
|
let mut asrcb =
|
||||||
AddSecretRequest::new(AddSecretVersion::One, GuestSecret::Null, TAGS, no_flag());
|
AddSecretRequest::new(AddSecretVersion::One, GuestSecret::Null, TAGS, no_flag());
|
||||||
(0..7).for_each(|_| asrcb.add_hostkey(hkd.clone()));
|
(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 asrcb = asrcb.encrypt(&ctx).unwrap();
|
||||||
|
|
||||||
let exp = get_test_asset!("exp/asrcb/null_none_default_cuid_seven");
|
let exp = get_test_asset!("exp/asrcb/null_none_default_cuid_seven");
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "pvsecret"
|
name = "pvsecret"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
edition = "2021"
|
edition.workspace = true
|
||||||
license = "MIT"
|
license.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { version = "1", features = ["std"] }
|
anyhow = { version = "1.0.70", features = ["std"] }
|
||||||
clap = { version ="4", features = ["derive", "wrap_help"]}
|
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"
|
serde_yaml = "0.9"
|
||||||
|
|
||||||
pv = { path = "../pv", features = ["uvsecret", "request"] }
|
pv = { path = "../pv", features = ["uvsecret", "request"] }
|
||||||
utils = { path = "../utils" }
|
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]
|
[package]
|
||||||
name = "utils"
|
name = "utils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition.workspace = true
|
||||||
license = "MIT"
|
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)"
|
read -r k_ver k_patchlvl k_sublvl k_sublvl2 <<< "$(split_kver "$kver_str" 4)"
|
||||||
|
|
||||||
# Handle excessive sublevel numbers consistently
|
# Handle excessive sublevel numbers consistently
|
||||||
|
if [[ "$k_sublvl" -gt 255 ]] ; then
|
||||||
|
k_sublvl=0
|
||||||
|
fi
|
||||||
if [[ "$k_sublvl2" -gt 65535 ]] ; then
|
if [[ "$k_sublvl2" -gt 65535 ]] ; then
|
||||||
k_sublvl2=0
|
k_sublvl2=0
|
||||||
fi
|
fi
|
||||||
|
|||||||
+13
-4
@@ -262,6 +262,7 @@ readonly OUTPUT_FILE_OVS="${WORKPATH}network.out"
|
|||||||
readonly OUTPUT_FILE_ISW="${WORKPATH}installed_sw.out"
|
readonly OUTPUT_FILE_ISW="${WORKPATH}installed_sw.out"
|
||||||
readonly OUTPUT_FILE_TC="${WORKPATH}network.out"
|
readonly OUTPUT_FILE_TC="${WORKPATH}network.out"
|
||||||
readonly OUTPUT_FILE_VMCMD="${WORKPATH}zvm_runtime.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 !
|
# Base file names for different output files - no extension !
|
||||||
readonly OUTPUT_FILE_KUBERNETES="${WORKPATH}kubernetes"
|
readonly OUTPUT_FILE_KUBERNETES="${WORKPATH}kubernetes"
|
||||||
readonly OUTPUT_FILE_OSAOAT="${WORKPATH}network"
|
readonly OUTPUT_FILE_OSAOAT="${WORKPATH}network"
|
||||||
@@ -400,6 +401,7 @@ CONFIGFILES="\
|
|||||||
/etc/hosts*\
|
/etc/hosts*\
|
||||||
/etc/iscsi\
|
/etc/iscsi\
|
||||||
/etc/inittab\
|
/etc/inittab\
|
||||||
|
/etc/kdump\
|
||||||
/etc/libvirt\
|
/etc/libvirt\
|
||||||
/etc/logrotate.d\
|
/etc/logrotate.d\
|
||||||
/etc/lvm\
|
/etc/lvm\
|
||||||
@@ -439,6 +441,7 @@ CONFIGFILES="\
|
|||||||
/run/modules-load.d/*.conf\
|
/run/modules-load.d/*.conf\
|
||||||
/run/udev/chreiplzfcpmp-ipl-volume-id\
|
/run/udev/chreiplzfcpmp-ipl-volume-id\
|
||||||
/run/udev/rules.d\
|
/run/udev/rules.d\
|
||||||
|
/run/zdev_id.env\
|
||||||
"
|
"
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
@@ -555,6 +558,7 @@ CMDS="${CMDS}\
|
|||||||
>> '${OUTPUT_FILE_JOURNALCTL}'\
|
>> '${OUTPUT_FILE_JOURNALCTL}'\
|
||||||
:lsof >> '${OUTPUT_FILE_LSOF}'\
|
:lsof >> '${OUTPUT_FILE_LSOF}'\
|
||||||
:rpm -qa | sort >> '${OUTPUT_FILE_ISW}'\
|
:rpm -qa | sort >> '${OUTPUT_FILE_ISW}'\
|
||||||
|
:udevadm info --export-db >> '${OUTPUT_FILE_UDEVDB}'\
|
||||||
"
|
"
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
@@ -833,6 +837,7 @@ collect_sysfs() {
|
|||||||
-x '*/page_idle/bitmap*' \
|
-x '*/page_idle/bitmap*' \
|
||||||
-x '*/tracing/per_cpu/*' \
|
-x '*/tracing/per_cpu/*' \
|
||||||
-x '*/tracing/free_buffer' \
|
-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
|
--ignore-failed-read -J 1 -T 5 2>>${OUTPUT_FILE_SYSFS}.err
|
||||||
rc=$?
|
rc=$?
|
||||||
else
|
else
|
||||||
@@ -860,6 +865,7 @@ collect_sysfs() {
|
|||||||
-a -not \( -path '*page_idle*' -a -name 'bitmap*' \) \
|
-a -not \( -path '*page_idle*' -a -name 'bitmap*' \) \
|
||||||
-a -not -path '*tracing/per_cpu*' \
|
-a -not -path '*tracing/per_cpu*' \
|
||||||
-a -not -path '*/tracing/free_buffer' \
|
-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
|
2>/dev/null | while IFS= read -r file_name; do
|
||||||
echo " ${file_name}"
|
echo " ${file_name}"
|
||||||
if ! dd if="${file_name}" status=noxfer iflag=nonblock \
|
if ! dd if="${file_name}" status=noxfer iflag=nonblock \
|
||||||
@@ -904,7 +910,8 @@ collect_osaoat() {
|
|||||||
local network_device
|
local network_device
|
||||||
|
|
||||||
network_devices=$(lsqeth 2>/dev/null | grep "Device name" \
|
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 type qethqoat >/dev/null; then
|
||||||
if test -n "${network_devices}"; then
|
if test -n "${network_devices}"; then
|
||||||
pr_collect_output "osa oat"
|
pr_collect_output "osa oat"
|
||||||
@@ -954,6 +961,8 @@ collect_ethtool() {
|
|||||||
"${OUTPUT_FILE_ETHTOOL}"
|
"${OUTPUT_FILE_ETHTOOL}"
|
||||||
call_run_command "ethtool -T ${network_device}" \
|
call_run_command "ethtool -T ${network_device}" \
|
||||||
"${OUTPUT_FILE_ETHTOOL}"
|
"${OUTPUT_FILE_ETHTOOL}"
|
||||||
|
call_run_command "ethtool --module-info ${network_device}" \
|
||||||
|
"${OUTPUT_FILE_ETHTOOL}"
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
pr_skip "ethtool: no devices"
|
pr_skip "ethtool: no devices"
|
||||||
@@ -1389,7 +1398,7 @@ pr_log_stdout() {
|
|||||||
pr_syslog_stdout() {
|
pr_syslog_stdout() {
|
||||||
echo "$@" >&8
|
echo "$@" >&8
|
||||||
echo
|
echo
|
||||||
echo "$(date +%H:%M:%S.%N) - $@"
|
echo "$(date +%H:%M:%S.%N) - " "$@"
|
||||||
logger -t "${SCRIPTNAME}" "$@"
|
logger -t "${SCRIPTNAME}" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1402,13 +1411,13 @@ pr_collect_output() {
|
|||||||
########################################
|
########################################
|
||||||
# print "Collecting ..." like fs
|
# print "Collecting ..." like fs
|
||||||
pr_collect() {
|
pr_collect() {
|
||||||
pr_syslog_stdout ${step_num} "Collecting" $@
|
pr_syslog_stdout ${step_num} "Collecting" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# print "Skipping ..." info with reason
|
# print "Skipping ..." info with reason
|
||||||
pr_skip() {
|
pr_skip() {
|
||||||
pr_syslog_stdout ${step_num} "Skip" $@
|
pr_syslog_stdout ${step_num} "Skip" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
+17
-8
@@ -486,12 +486,16 @@ static void show_queue_capability(int id, int dom)
|
|||||||
printf("queue %02x.%04x capabilities:\n", id, dom);
|
printf("queue %02x.%04x capabilities:\n", id, dom);
|
||||||
|
|
||||||
if (util_path_is_reg_file("%s/se_bind", dev)) {
|
if (util_path_is_reg_file("%s/se_bind", dev)) {
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev);
|
if (util_file_read_line(buf, sizeof(buf), "%s/se_bind", dev))
|
||||||
printf("SE bind state: %s\n", buf);
|
printf("SE bind state: error\n");
|
||||||
|
else
|
||||||
|
printf("SE bind state: %s\n", buf);
|
||||||
}
|
}
|
||||||
if (util_path_is_reg_file("%s/se_associate", dev)) {
|
if (util_path_is_reg_file("%s/se_associate", dev)) {
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev);
|
if (util_file_read_line(buf, sizeof(buf), "%s/se_associate", dev))
|
||||||
printf("SE association state: %s\n", buf);
|
printf("SE association state: error\n");
|
||||||
|
else
|
||||||
|
printf("SE association state: %s\n", buf);
|
||||||
}
|
}
|
||||||
if (util_path_is_reg_file("%s/mkvps", dev)) {
|
if (util_path_is_reg_file("%s/mkvps", dev)) {
|
||||||
char *mkvps = util_path_sysfs("devices/ap/%s/%s/mkvps", card, queue);
|
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_file_read_l(&depth, 10, "%s/depth", grp_dev);
|
||||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||||
|
|
||||||
if (util_path_is_readable("%s/%s/ap_functions", grp_dev, sub_dev))
|
if (util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev))
|
||||||
util_file_read_ul(&facility, 16, "%s/%s/ap_functions", grp_dev, sub_dev);
|
errx(EXIT_FAILURE,
|
||||||
else
|
"Error - Read of sysfs attribute %s/ap_functions failed.",
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
grp_dev);
|
||||||
for (i = 0; i < MAX_FAC_BITS; i++)
|
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||||
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
util_rec_set(rec, "facility", buf);
|
util_rec_set(rec, "facility", buf);
|
||||||
|
|
||||||
if (ap_bus_has_SB_support()) {
|
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)) {
|
switch (EXTRACT_BS_BITS(facility)) {
|
||||||
case 0:
|
case 0:
|
||||||
util_rec_set(rec, "sestat", "usable");
|
util_rec_set(rec, "sestat", "usable");
|
||||||
|
|||||||
+1
-14
@@ -15,24 +15,11 @@
|
|||||||
#include "exit_code.h"
|
#include "exit_code.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "site.h"
|
||||||
|
|
||||||
struct subtype;
|
struct subtype;
|
||||||
struct setting_list;
|
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
|
* struct device_state - Represent the state of a device in a configuration
|
||||||
* @settings: List of attribute settings
|
* @settings: List of attribute settings
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#define MODPROBE_PREFIX "s390x"
|
#define MODPROBE_PREFIX "s390x"
|
||||||
#define UDEV_PREFIX "41"
|
#define UDEV_PREFIX "41"
|
||||||
#define UDEV_SUFFIX ".rules"
|
#define UDEV_SUFFIX ".rules"
|
||||||
#define ZDEV_PREFIX "40"
|
|
||||||
|
|
||||||
#define PATH_MODPROBE_CONF "/etc/modprobe.d"
|
#define PATH_MODPROBE_CONF "/etc/modprobe.d"
|
||||||
#define PATH_MODPROBE "/sbin/modprobe"
|
#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_zfcp_port_dev(struct zfcp_lun_devid *);
|
||||||
char *path_get_scsi_hctl_dev(const char *);
|
char *path_get_scsi_hctl_dev(const char *);
|
||||||
char *path_get_bus_attr(const char *, 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 path_for_each(const char *,
|
||||||
exit_code_t (*callback)(const char *, const char *,
|
exit_code_t (*callback)(const char *, const char *,
|
||||||
|
|||||||
@@ -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 util_udev_entry_node *entry,
|
||||||
struct attrib **attribs);
|
struct attrib **attribs);
|
||||||
|
|
||||||
exit_code_t udev_write_site_rule(void);
|
|
||||||
bool is_legacy_rule(struct util_udev_file *file);
|
bool is_legacy_rule(struct util_udev_file *file);
|
||||||
|
|
||||||
#endif /* UDEV_H */
|
#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_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);
|
|
||||||
}
|
|
||||||
|
|||||||
+8
-5
@@ -413,13 +413,16 @@ static struct attrib qeth_attr_isolation = {
|
|||||||
|
|
||||||
static struct attrib qeth_attr_performance_stats = {
|
static struct attrib qeth_attr_performance_stats = {
|
||||||
.name = "performance_stats",
|
.name = "performance_stats",
|
||||||
.title = "Control performance statistics collection",
|
.title = "Reset the statistic values",
|
||||||
.desc =
|
.desc =
|
||||||
"Control the collection of QETH performance statistics data:\n"
|
"Write '1' to this attribute to reset the statistic values to 0.\n"
|
||||||
" 0: Performance statistics data is not collected\n"
|
"Use the ethtool command to display the statistics.\n",
|
||||||
" 1: Performance statistics data is collected\n",
|
/* read will always return 1 */
|
||||||
.defval = "0",
|
.defval = "1",
|
||||||
|
/* writing 0 is possible, but has no effect */
|
||||||
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||||
|
.activeonly = 1,
|
||||||
|
.rewrite = 1,
|
||||||
.st_data = QETH_DATA(layer_any, group_none),
|
.st_data = QETH_DATA(layer_any, group_none),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -139,53 +139,6 @@ out:
|
|||||||
free(copy);
|
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)
|
bool is_legacy_rule(struct util_udev_file *file)
|
||||||
{
|
{
|
||||||
struct util_udev_line_node *line;
|
struct util_udev_line_node *line;
|
||||||
|
|||||||
+35
-16
@@ -25,6 +25,7 @@
|
|||||||
#include "setting.h"
|
#include "setting.h"
|
||||||
#include "udev.h"
|
#include "udev.h"
|
||||||
#include "udev_ccw.h"
|
#include "udev_ccw.h"
|
||||||
|
#include "zdev_id.h"
|
||||||
|
|
||||||
#define SITE_FALLBACK_SUFFIX "fb"
|
#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;
|
char *path, *cfg_label = NULL, *end_label = NULL;
|
||||||
exit_code_t rc = EXIT_OK;
|
exit_code_t rc = EXIT_OK;
|
||||||
FILE *fd;
|
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
|
* 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);
|
dev_state_copy(&dev->site_specific[global_site_id], &dev->persistent);
|
||||||
for (i = 0; i < NUM_SITES; i++) {
|
for (i = 0; i < NUM_SITES; i++) {
|
||||||
configured += dev->site_specific[i].exists;
|
configured += dev_site_configured(dev, i) ? 1 : 0;
|
||||||
configured -= dev->site_specific[i].deconfigured;
|
|
||||||
}
|
}
|
||||||
|
site_configured = configured - (dev_site_configured(dev, SITE_FALLBACK) ?
|
||||||
|
1 : 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no configuration settings available, do not create the new
|
* 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, "\n");
|
||||||
|
|
||||||
fprintf(fd, "LABEL=\"%s\"\n", cfg_label);
|
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 */
|
/* site comparison block */
|
||||||
for (i = 0; i < NUM_USER_SITES; i++) {
|
for (i = 0; i < NUM_USER_SITES; i++) {
|
||||||
if (dev->site_specific[i].exists &&
|
if (dev_site_configured(dev, i)) {
|
||||||
!dev->site_specific[i].deconfigured) {
|
|
||||||
fprintf(fd, "ENV{ZDEV_SITE_ID}==\"%d\",GOTO=\"%s_site%d\"\n", i,
|
fprintf(fd, "ENV{ZDEV_SITE_ID}==\"%d\",GOTO=\"%s_site%d\"\n", i,
|
||||||
cfg_label, 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
|
* If we have a generic configuration available, then use that setting as a
|
||||||
* fail-over incase of no site-id information in LOADPARM
|
* fail-over incase of no site-id information in LOADPARM
|
||||||
*/
|
*/
|
||||||
if (dev->site_specific[SITE_FALLBACK].exists &&
|
if (dev_site_configured(dev, SITE_FALLBACK))
|
||||||
!dev->site_specific[SITE_FALLBACK].deconfigured)
|
|
||||||
fprintf(fd, "GOTO=\"%s_site_fb\"\n", cfg_label);
|
fprintf(fd, "GOTO=\"%s_site_fb\"\n", cfg_label);
|
||||||
else
|
else
|
||||||
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
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 */
|
/* Write the site blocks for all the available configurations */
|
||||||
for (i = 0; i < NUM_USER_SITES; i++) {
|
for (i = 0; i < NUM_USER_SITES; i++) {
|
||||||
if (dev->site_specific[i].exists &&
|
if (dev_site_configured(dev, i)) {
|
||||||
!dev->site_specific[i].deconfigured) {
|
|
||||||
fprintf(fd, "# site_start_%d\n", i);
|
fprintf(fd, "# site_start_%d\n", i);
|
||||||
fprintf(fd, "LABEL=\"%s_site%d\"\n", cfg_label, 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");
|
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_attr_to_file(fd, &dev->site_specific[i], id);
|
||||||
/* Write udev rule epilog. */
|
/* Write udev rule epilog. */
|
||||||
fprintf(fd, "GOTO=\"%s\"\n", end_label);
|
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))
|
if (misc_fclose(fd))
|
||||||
warn("Could not close file %s: %s\n", path, strerror(errno));
|
warn("Could not close file %s: %s\n", path, strerror(errno));
|
||||||
|
|
||||||
rc = udev_write_site_rule();
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
out:
|
out:
|
||||||
free(end_label);
|
free(end_label);
|
||||||
free(cfg_label);
|
free(cfg_label);
|
||||||
|
|||||||
+1
-1
@@ -13,6 +13,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "site.h"
|
||||||
#include "zdev_id.h"
|
#include "zdev_id.h"
|
||||||
|
|
||||||
#define SYSINFO "/proc/sysinfo"
|
#define SYSINFO "/proc/sysinfo"
|
||||||
@@ -20,7 +21,6 @@
|
|||||||
#define LOADPARM "/sys/firmware/ipl/loadparm"
|
#define LOADPARM "/sys/firmware/ipl/loadparm"
|
||||||
#define IPL_DEV_ID "/sys/firmware/ipl/device"
|
#define IPL_DEV_ID "/sys/firmware/ipl/device"
|
||||||
#define IPL_DEV_TYPE "/sys/firmware/ipl/ipl_type"
|
#define IPL_DEV_TYPE "/sys/firmware/ipl/ipl_type"
|
||||||
#define SITE_FALLBACK 10
|
|
||||||
|
|
||||||
#define WHITESPACE " \t\n"
|
#define WHITESPACE " \t\n"
|
||||||
|
|
||||||
|
|||||||
+11
-4
@@ -17,6 +17,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "df_s390.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) &&
|
if ((hdr->version >= 5 || hdr->magic == DF_S390_MAGIC_EXT) &&
|
||||||
hdr->real_cpu_cnt)
|
hdr->real_cpu_cnt)
|
||||||
dfi_attr_real_cpu_cnt_set(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:
|
case 1:
|
||||||
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT, 7) == 0 ||
|
if (strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_EXT, 7) == 0 ||
|
||||||
strncmp(dumper->magic, DF_S390_DUMPER_MAGIC_MV_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
|
else
|
||||||
dumper->size = DF_S390_DUMPER_SIZE_V1;
|
dumper->size = STAGE2_DUMPER_SIZE_V1;
|
||||||
break;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
default:
|
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 */
|
/* Read force and mem fields in the end of the dumper */
|
||||||
bytes_to_read = sizeof(dumper->force) + sizeof(dumper->mem);
|
bytes_to_read = sizeof(dumper->force) + sizeof(dumper->mem);
|
||||||
|
|||||||
+2
-67
@@ -13,74 +13,12 @@
|
|||||||
#define DF_S390_H
|
#define DF_S390_H
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
#include "boot/loaders_layout.h"
|
||||||
|
|
||||||
#include "dt.h"
|
#include "dt.h"
|
||||||
#include "zg.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
|
* 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;
|
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_MAGIC32 "ZECKD31"
|
||||||
#define DF_S390_DUMPER_MAGIC64 "ZECKD64"
|
#define DF_S390_DUMPER_MAGIC64 "ZECKD64"
|
||||||
#define DF_S390_DUMPER_MAGIC_EXT "XECKD64"
|
#define DF_S390_DUMPER_MAGIC_EXT "XECKD64"
|
||||||
|
|||||||
+27
@@ -74,6 +74,8 @@ struct attr {
|
|||||||
struct new_utsname *utsname;
|
struct new_utsname *utsname;
|
||||||
char *dump_method;
|
char *dump_method;
|
||||||
u64 *file_size;
|
u64 *file_size;
|
||||||
|
u8 *zlib_version;
|
||||||
|
u32 *zlib_entsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -146,6 +148,11 @@ void dfi_info_print(void)
|
|||||||
if (l.attr.file_size)
|
if (l.attr.file_size)
|
||||||
STDERR(" Dump file size.....: %lld MB\n",
|
STDERR(" Dump file size.....: %lld MB\n",
|
||||||
TO_MIB(*l.attr.file_size));
|
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())
|
if (dfi_mem_range())
|
||||||
dfi_mem_map_print(g.opts.verbose);
|
dfi_mem_map_print(g.opts.verbose);
|
||||||
if (l.dfi->info_dump) {
|
if (l.dfi->info_dump) {
|
||||||
@@ -426,6 +433,26 @@ u64 *dfi_attr_file_size(void)
|
|||||||
return l.attr.file_size;
|
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
|
* Attribute: Build architecture
|
||||||
|
|||||||
@@ -182,6 +182,10 @@ u64 *dfi_attr_mem_size_real(void);
|
|||||||
void dfi_attr_file_size_set(u64 dump_size);
|
void dfi_attr_file_size_set(u64 dump_size);
|
||||||
u64 *dfi_attr_file_size(void);
|
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);
|
void dfi_attr_vol_nr_set(unsigned int vol_nr);
|
||||||
unsigned int *dfi_attr_vol_nr(void);
|
unsigned int *dfi_attr_vol_nr(void);
|
||||||
|
|
||||||
|
|||||||
+180
-13
@@ -18,8 +18,10 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "lib/util_log.h"
|
#include "lib/util_log.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "zgetdump.h"
|
#include "zgetdump.h"
|
||||||
#include "zg.h"
|
#include "zg.h"
|
||||||
@@ -35,8 +37,21 @@ static struct {
|
|||||||
struct df_s390_hdr hdr; /* s390 dump header */
|
struct df_s390_hdr hdr; /* s390 dump header */
|
||||||
struct df_s390_em em; /* s390 end marker */
|
struct df_s390_em em; /* s390 end marker */
|
||||||
bool extended; /* Extended input dump format */
|
bool extended; /* Extended input dump format */
|
||||||
|
int blk_size; /* Dump device block size */
|
||||||
} l;
|
} 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
|
* 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 off, void *buf, u64 cnt)
|
||||||
{
|
{
|
||||||
u64 *mem_chunk_off = mem_chunk->data;
|
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_seek(g.fh, *mem_chunk_off + off, ZG_CHECK);
|
||||||
zg_read(g.fh, buf, cnt, 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
|
* Read s390 dump header
|
||||||
@@ -78,6 +200,8 @@ static int read_s390_hdr(void)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
if (l.hdr.cpu_cnt > DF_S390_CPU_MAX)
|
if (l.hdr.cpu_cnt > DF_S390_CPU_MAX)
|
||||||
return -ENODEV;
|
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);
|
util_log_print(UTIL_LOG_INFO, "DFI S390 version %u\n", l.hdr.version);
|
||||||
df_s390_hdr_add(&l.hdr);
|
df_s390_hdr_add(&l.hdr);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -121,6 +245,44 @@ static int mem_chunks_add(void)
|
|||||||
return read_s390_em();
|
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
|
* 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);
|
off = zg_seek(g.fh, DF_S390_HDR_SIZE, ZG_CHECK_NONE);
|
||||||
if (off != DF_S390_HDR_SIZE)
|
if (off != DF_S390_HDR_SIZE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
while (off < DF_S390_HDR_SIZE + l.hdr.mem_size - PAGE_SIZE) {
|
while (off < DF_S390_HDR_SIZE + l.hdr.mem_size) {
|
||||||
rc = zg_read(g.fh, &dump_segm, PAGE_SIZE, ZG_CHECK_ERR);
|
rc = zg_read(g.fh, &dump_segm, sizeof(dump_segm), ZG_CHECK_ERR);
|
||||||
if (rc != PAGE_SIZE)
|
if (rc != sizeof(dump_segm))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
util_log_print(UTIL_LOG_DEBUG,
|
util_log_print(UTIL_LOG_DEBUG,
|
||||||
"DFI S390 dump segment start 0x%016lx size 0x%016lx stop marker %d\n",
|
"DFI S390 dump segment start 0x%016lx size 0x%016lx compr_size 0x%08lx stop marker %d\n",
|
||||||
dump_segm.start, dump_segm.len, dump_segm.stop_marker);
|
dump_segm.start, dump_segm.len, b2m(dump_segm.size_on_disk),
|
||||||
off += PAGE_SIZE;
|
dump_segm.stop_marker ? 1 : 0);
|
||||||
|
off += sizeof(dump_segm);
|
||||||
/* Add zero memory chunk */
|
/* Add zero memory chunk */
|
||||||
dfi_mem_chunk_add(old, dump_segm.start - old, NULL,
|
dfi_mem_chunk_add(old, dump_segm.start - old, NULL,
|
||||||
dfi_mem_chunk_read_zero, NULL);
|
dfi_mem_chunk_read_zero, NULL);
|
||||||
/* Add memory chunk for a dump segment */
|
/* Add memory chunk for a dump segment */
|
||||||
u64 *off_ptr = zg_alloc(sizeof(*off_ptr));
|
if (dump_segm.size_on_disk) {
|
||||||
*off_ptr = off;
|
/* Compressed dump segment detected */
|
||||||
dfi_mem_chunk_add(dump_segm.start, dump_segm.len, off_ptr,
|
create_compressed_mem_chunk(&dump_segm, off);
|
||||||
dfi_s390_ext_mem_chunk_read, zg_free);
|
off = zg_seek_cur(g.fh, b2m(dump_segm.size_on_disk), ZG_CHECK_NONE);
|
||||||
off_ptr = NULL;
|
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;
|
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)
|
if (dump_segm.stop_marker)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -180,6 +346,7 @@ int dfi_s390_init_gen(bool extended)
|
|||||||
l.extended = extended;
|
l.extended = extended;
|
||||||
if (read_s390_hdr() != 0)
|
if (read_s390_hdr() != 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
zg_ioctl(g.fh, BLKSSZGET, &l.blk_size, "BLKSSZGET", ZG_CHECK);
|
||||||
if (!extended)
|
if (!extended)
|
||||||
rc = mem_chunks_add();
|
rc = mem_chunks_add();
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "lib/util_file.h"
|
#include "lib/util_file.h"
|
||||||
#include "lib/util_path.h"
|
#include "lib/util_path.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "zgetdump.h"
|
#include "zgetdump.h"
|
||||||
#include "dt.h"
|
#include "dt.h"
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "zgetdump.h"
|
#include "zgetdump.h"
|
||||||
#include "df_s390.h"
|
#include "df_s390.h"
|
||||||
#include "dfi.h"
|
#include "dfi.h"
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "df_s390.h"
|
#include "df_s390.h"
|
||||||
#include "dfi_mem_chunk.h"
|
#include "dfi_mem_chunk.h"
|
||||||
#include "dfo_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
|
* 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;
|
u64 us = xtime->tv_sec * 1000000 + xtime->tv_usec;
|
||||||
*tod = (us << 12);
|
*tod = (us << 12);
|
||||||
|
|||||||
+3
-3
@@ -109,11 +109,11 @@ static int dumper_read_validate_fba(int size, struct df_s390_dumper *dumper)
|
|||||||
*/
|
*/
|
||||||
static int dumper_read_fba(void)
|
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;
|
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;
|
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 0;
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -14,10 +14,12 @@
|
|||||||
#include "dfo.h"
|
#include "dfo.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
|
||||||
|
#define BUFFER_SIZE (1 * MIB)
|
||||||
|
|
||||||
int write_dump(FILE *stream)
|
int write_dump(FILE *stream)
|
||||||
{
|
{
|
||||||
const u64 output_size = dfo_size();
|
const u64 output_size = dfo_size();
|
||||||
char buf[8UL * PAGE_SIZE];
|
char *buf = zg_alloc(BUFFER_SIZE);
|
||||||
u64 written = 0;
|
u64 written = 0;
|
||||||
|
|
||||||
if (!dfi_feat_copy())
|
if (!dfi_feat_copy())
|
||||||
@@ -31,7 +33,7 @@ int write_dump(FILE *stream)
|
|||||||
size_t rc;
|
size_t rc;
|
||||||
u64 cnt;
|
u64 cnt;
|
||||||
|
|
||||||
cnt = dfo_read(buf, sizeof(buf));
|
cnt = dfo_read(buf, BUFFER_SIZE);
|
||||||
rc = fwrite(buf, cnt, 1, stream);
|
rc = fwrite(buf, cnt, 1, stream);
|
||||||
if (rc != 1 && ferror(stream))
|
if (rc != 1 && ferror(stream))
|
||||||
ERR_EXIT("Error: Write failed");
|
ERR_EXIT("Error: Write failed");
|
||||||
@@ -40,5 +42,6 @@ int write_dump(FILE *stream)
|
|||||||
};
|
};
|
||||||
STDERR("\n");
|
STDERR("\n");
|
||||||
STDERR("Success: Dump has been copied\n");
|
STDERR("Success: Dump has been copied\n");
|
||||||
|
zg_free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -194,6 +194,7 @@ The following dump formats are supported for the source dump only:
|
|||||||
.TP
|
.TP
|
||||||
.BR "s390_ext"
|
.BR "s390_ext"
|
||||||
This dump format is IBM zSystems specific and is used for DASD dumps only.
|
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
|
.TP
|
||||||
.BR "vmdump"
|
.BR "vmdump"
|
||||||
Dumps with this format are created by the z/VM vmdump command
|
Dumps with this format are created by the z/VM vmdump command
|
||||||
@@ -277,7 +278,16 @@ tool (see man zipl).
|
|||||||
.TP
|
.TP
|
||||||
.BR "Dump file size"
|
.BR "Dump file size"
|
||||||
Actual size of dump file on disk in megabytes. "Dump file size" may differ from
|
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
|
.TP
|
||||||
.BR "Memory map"
|
.BR "Memory map"
|
||||||
Available memory chunks in the dump. Some dump tools create multiple memory
|
Available memory chunks in the dump. Some dump tools create multiple memory
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ all:
|
|||||||
$(MAKE) -C src
|
$(MAKE) -C src
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
$(MAKE) -C boot install
|
||||||
$(MAKE) -C src install
|
$(MAKE) -C src install
|
||||||
$(MAKE) -C man install
|
$(MAKE) -C man install
|
||||||
$(MAKE) -C dracut install
|
$(MAKE) -C dracut install
|
||||||
|
|||||||
+39
-18
@@ -1,6 +1,27 @@
|
|||||||
# Common definitions
|
# Common definitions
|
||||||
include ../../common.mak
|
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_PATHS := $(rootdir)/zipl/include $(rootdir)/include
|
||||||
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
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
|
-W -Wall -Wformat-security -fno-sanitize=all -Wno-array-bounds
|
||||||
ALL_LDFLAGS += -fno-sanitize=all
|
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...
|
# Prevent make from using some default rules...
|
||||||
%: %.S
|
%: %.S
|
||||||
|
|
||||||
@@ -56,8 +64,9 @@ eckd1b.exec fba1b.exec: \
|
|||||||
stage1b.lds
|
stage1b.lds
|
||||||
|
|
||||||
eckd2dump_sv.exec: \
|
eckd2dump_sv.exec: \
|
||||||
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o \
|
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_sv.o eckd2dump_zlib.o \
|
||||||
libc.o ebcdic.o sclp.o entry.o stage2.lds
|
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: \
|
eckd2dump_mv.exec: \
|
||||||
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_mv.o \
|
head.o stage2dump.o cio.o eckd2dump.o eckd2dump_mv.o \
|
||||||
libc.o ebcdic.o sclp.o entry.o stage2.lds
|
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
|
%.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 $@
|
$(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
|
%.bin.debug: %.exec
|
||||||
$(OBJCOPY) --only-keep-debug $< $@
|
$(OBJCOPY) --only-keep-debug $< $@
|
||||||
|
@chmod a-x $@
|
||||||
|
|
||||||
%.bin: %.exec
|
%.bin: %.exec
|
||||||
$(OBJCOPY) -O binary $< $@
|
$(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:
|
$(EMBEDDED_BOOTLOADERS) $(DEBUG_EMBEDDED_BOOTLOADERS) $(EXTERNAL_BOOTLOADERS) $(DEBUG_EXTERNAL_BOOTLOADERS):
|
||||||
rm -f -- *.o *.exec *.bin *.lds .*.lds.d .loaders *.debug
|
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||||
|
|
||||||
.PHONY: all clean
|
install:
|
||||||
|
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||||
|
endif
|
||||||
|
|||||||
+39
-17
@@ -3,12 +3,14 @@
|
|||||||
*
|
*
|
||||||
* Common ECKD dump I/O functions
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "cio.h"
|
#include "cio.h"
|
||||||
#include "eckd2dump.h"
|
#include "eckd2dump.h"
|
||||||
#include "boot/error.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);
|
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
|
* Write dump segment with the header to DASD and return the next free
|
||||||
* block number
|
* 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,
|
unsigned long write_dump_segment(unsigned long blk,
|
||||||
struct df_s390_dump_segm_hdr *segm)
|
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) */
|
/* Write the dump segment header itself (1 page) */
|
||||||
zero_page = get_zeroed_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);
|
free_page(zero_page);
|
||||||
blk += m2b(PAGE_SIZE);
|
blk += m2b(PAGE_SIZE);
|
||||||
/* Write the dump segment */
|
/* Write the dump segment */
|
||||||
addr = segm->start;
|
return write_addr_range(blk, segm->start, segm->len, PRINT_PROGRESS);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Common ECKD dump I/O functions
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
#ifndef ECKD2DUMP_H
|
#ifndef ECKD2DUMP_H
|
||||||
#define ECKD2DUMP_H
|
#define ECKD2DUMP_H
|
||||||
|
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "cio.h"
|
#include "cio.h"
|
||||||
#include "stage2dump.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);
|
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
|
||||||
unsigned long write_dump_segment(unsigned long blk,
|
unsigned long write_dump_segment(unsigned long blk,
|
||||||
struct df_s390_dump_segm_hdr *segm);
|
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 */
|
#endif /* ECKD2DUMP_H */
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Multi-volume ECKD DASD dump tool
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/error.h"
|
#include "boot/error.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "eckd2dump.h"
|
#include "eckd2dump.h"
|
||||||
#include "stage2dump.h"
|
#include "stage2dump.h"
|
||||||
@@ -268,7 +269,6 @@ static unsigned long write_volume(unsigned long addr,
|
|||||||
/* Reserve one block for the next segment header */
|
/* Reserve one block for the next segment header */
|
||||||
if (free_space)
|
if (free_space)
|
||||||
free_space -= b2m(1);
|
free_space -= b2m(1);
|
||||||
total_dump_size += dump_segm->len;
|
|
||||||
/* Check if no more dump segments follow */
|
/* Check if no more dump segments follow */
|
||||||
if (dump_segm->stop_marker) {
|
if (dump_segm->stop_marker) {
|
||||||
/* Write end marker */
|
/* Write end marker */
|
||||||
|
|||||||
+93
-18
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Single-volume ECKD DASD dump tool
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -12,14 +12,16 @@
|
|||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/boot_defs.h"
|
#include "boot/boot_defs.h"
|
||||||
#include "boot/error.h"
|
#include "boot/error.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "eckd2dump.h"
|
#include "eckd2dump.h"
|
||||||
|
#include "eckd2dump_zlib.h"
|
||||||
#include "stage2dump.h"
|
#include "stage2dump.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Magic number at start of dump record
|
* 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
|
* Get device characteristics from zipl parameter block
|
||||||
@@ -46,40 +48,113 @@ void dt_device_enable(void)
|
|||||||
stage2dump_eckd_init();
|
stage2dump_eckd_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static unsigned long dt_dump_mem_non_compressed(unsigned long addr,
|
||||||
* Dump all memory to DASD partition
|
unsigned long blk)
|
||||||
*/
|
|
||||||
void dt_dump_mem(void)
|
|
||||||
{
|
{
|
||||||
unsigned long blk, addr, end, page;
|
|
||||||
struct df_s390_dump_segm_hdr *dump_segm;
|
struct df_s390_dump_segm_hdr *dump_segm;
|
||||||
|
unsigned long end;
|
||||||
|
|
||||||
blk = device.blk_start;
|
|
||||||
dump_segm = (void *)get_zeroed_page();
|
dump_segm = (void *)get_zeroed_page();
|
||||||
|
/* Write memory uncompressed */
|
||||||
/* 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;
|
|
||||||
end = dump_hdr->mem_size;
|
end = dump_hdr->mem_size;
|
||||||
while (addr < end) {
|
while (addr < end) {
|
||||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||||
blk = write_dump_segment(blk, dump_segm);
|
blk = write_dump_segment(blk, dump_segm);
|
||||||
total_dump_size += dump_segm->len;
|
|
||||||
if (dump_segm->stop_marker) {
|
if (dump_segm->stop_marker) {
|
||||||
addr = end;
|
addr = end;
|
||||||
|
if (dump_segm->start + dump_segm->len < end)
|
||||||
|
progress_print(addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_page(__pa(dump_segm));
|
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 */
|
/* Write end marker */
|
||||||
page = get_zeroed_page();
|
page = get_zeroed_page();
|
||||||
df_s390_em_page_init(page);
|
df_s390_em_page_init(page);
|
||||||
writeblock(blk, page, 1, 0);
|
writeblock(blk, page, 1, 0);
|
||||||
|
blk++;
|
||||||
free_page(page);
|
free_page(page);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/boot_defs.h"
|
#include "boot/boot_defs.h"
|
||||||
#include "boot/error.h"
|
#include "boot/error.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "fba.h"
|
#include "fba.h"
|
||||||
#include "stage2dump.h"
|
#include "stage2dump.h"
|
||||||
@@ -152,9 +153,10 @@ unsigned long write_dump_segment_fba(unsigned long blk,
|
|||||||
zero_page = get_zeroed_page();
|
zero_page = get_zeroed_page();
|
||||||
writeblock_fba(blk, addr, blk_count, zero_page);
|
writeblock_fba(blk, addr, blk_count, zero_page);
|
||||||
free_page(zero_page);
|
free_page(zero_page);
|
||||||
progress_print(addr);
|
|
||||||
blk += blk_count;
|
blk += blk_count;
|
||||||
addr += b2m(blk_count);
|
addr += b2m(blk_count);
|
||||||
|
total_dump_size += b2m(blk_count);
|
||||||
|
progress_print(addr);
|
||||||
}
|
}
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
@@ -206,7 +208,6 @@ void dt_dump_mem(void)
|
|||||||
while (addr < end) {
|
while (addr < end) {
|
||||||
addr = find_dump_segment(addr, end, 0, dump_segm);
|
addr = find_dump_segment(addr, end, 0, dump_segm);
|
||||||
blk = write_dump_segment_fba(blk, dump_segm);
|
blk = write_dump_segment_fba(blk, dump_segm);
|
||||||
total_dump_size += dump_segm->len;
|
|
||||||
if (dump_segm->stop_marker) {
|
if (dump_segm->stop_marker) {
|
||||||
addr = end;
|
addr = end;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+19
-3
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Common functions for stand-alone dump tools
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -13,12 +13,14 @@
|
|||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "boot/error.h"
|
#include "boot/error.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
#include "sclp.h"
|
#include "sclp.h"
|
||||||
#include "stage2dump.h"
|
#include "stage2dump.h"
|
||||||
#include "boot/ipl.h"
|
#include "boot/ipl.h"
|
||||||
#include "boot/os_info.h"
|
#include "boot/os_info.h"
|
||||||
|
#include "boot/s390.h"
|
||||||
|
|
||||||
#define CPU_ADDRESS_MAX 1000
|
#define CPU_ADDRESS_MAX 1000
|
||||||
#define MACHINE_HAS_VX machine_has_vx
|
#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)
|
if (time < next && addr != dump_hdr->mem_size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printf("%08lu / %08lu MB (Dump file size %08lu MB)", addr >> 20,
|
printf("%08lu / %08lu MB (Dump file size %08lu MB)", addr >> 20,
|
||||||
dump_hdr->mem_size >> 20, total_dump_size >> 20);
|
dump_hdr->mem_size >> 20, total_dump_size >> 20);
|
||||||
next = time + delta;
|
next = time + delta;
|
||||||
@@ -215,13 +216,23 @@ static void df_s390_dump_init(void)
|
|||||||
dh->hdr_size = DF_S390_HDR_SIZE;
|
dh->hdr_size = DF_S390_HDR_SIZE;
|
||||||
dh->page_size = PAGE_SIZE;
|
dh->page_size = PAGE_SIZE;
|
||||||
dh->dump_level = 4;
|
dh->dump_level = 4;
|
||||||
dh->version = 1;
|
dh->version = 2;
|
||||||
dh->mem_start = 0;
|
dh->mem_start = 0;
|
||||||
dh->arch = DF_S390_ARCH_64;
|
dh->arch = DF_S390_ARCH_64;
|
||||||
dh->build_arch = DF_S390_ARCH_64;
|
dh->build_arch = DF_S390_ARCH_64;
|
||||||
get_cpu_id((struct cpuid *) &dh->cpu_id);
|
get_cpu_id((struct cpuid *) &dh->cpu_id);
|
||||||
dh->tod = get_tod_clock();
|
dh->tod = get_tod_clock();
|
||||||
dh->volnr = 0;
|
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();
|
init_early();
|
||||||
dt_device_parm_setup();
|
dt_device_parm_setup();
|
||||||
sclp_setup(SCLP_INIT);
|
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();
|
dt_device_enable();
|
||||||
df_s390_dump_init();
|
df_s390_dump_init();
|
||||||
printf("zIPL v%s dump tool (64 bit)", RELEASE_STRING);
|
printf("zIPL v%s dump tool (64 bit)", RELEASE_STRING);
|
||||||
printf("Dumping 64 bit OS");
|
printf("Dumping 64 bit OS");
|
||||||
|
if (parm_tail.no_compress)
|
||||||
|
printf("Dump compression prevented by the --no-compress attribute");
|
||||||
mem_and_cpu_init();
|
mem_and_cpu_init();
|
||||||
store_status();
|
store_status();
|
||||||
dt_dump_mem();
|
dt_dump_mem();
|
||||||
|
|||||||
+3
-78
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Common dump functions
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -12,90 +12,16 @@
|
|||||||
#ifndef STAGE2DUMP_H
|
#ifndef STAGE2DUMP_H
|
||||||
#define STAGE2DUMP_H
|
#define STAGE2DUMP_H
|
||||||
|
|
||||||
#include "libc.h"
|
|
||||||
#include "boot/s390.h"
|
#include "boot/s390.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#define IPL_SC S390_lowcore.tpi_info.schid
|
#define IPL_SC S390_lowcore.tpi_info.schid
|
||||||
#define ROUND_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1))
|
#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))
|
#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;
|
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
|
* 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,
|
void create_ida_list(unsigned long *list, int len, unsigned long addr,
|
||||||
unsigned long zero_page);
|
unsigned long zero_page);
|
||||||
void init_progress_print(void);
|
|
||||||
void progress_print(unsigned long addr);
|
void progress_print(unsigned long addr);
|
||||||
void df_s390_em_page_init(unsigned long page);
|
void df_s390_em_page_init(unsigned long page);
|
||||||
void pgm_check_handler(void);
|
void pgm_check_handler(void);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Dump tool for channel-attached tape devices
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "boot/error.h"
|
#include "boot/error.h"
|
||||||
#include "boot/loaders_layout.h"
|
#include "boot/loaders_layout.h"
|
||||||
#include "boot/s390.h"
|
#include "boot/s390.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "cio.h"
|
#include "cio.h"
|
||||||
#include "stage2dump.h"
|
#include "stage2dump.h"
|
||||||
@@ -205,13 +206,14 @@ void dt_dump_mem(void)
|
|||||||
setup_idrc_compression();
|
setup_idrc_compression();
|
||||||
ccw_write_tapemark();
|
ccw_write_tapemark();
|
||||||
|
|
||||||
|
total_dump_size = 0;
|
||||||
ccw_write_block((unsigned long) dump_hdr, DF_S390_HDR_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) {
|
for (addr = 0; addr < dump_hdr->mem_size; addr += BLK_SIZE) {
|
||||||
ccw_write_block(addr, BLK_SIZE, page);
|
ccw_write_block(addr, BLK_SIZE, page);
|
||||||
progress_print(addr);
|
total_dump_size += BLK_SIZE;
|
||||||
progress_print_disp(addr);
|
progress_print(addr + BLK_SIZE);
|
||||||
|
progress_print_disp(addr + BLK_SIZE);
|
||||||
}
|
}
|
||||||
progress_print(addr);
|
|
||||||
df_s390_em_page_init(page);
|
df_s390_em_page_init(page);
|
||||||
ccw_write_block(page, sizeof(struct df_s390_em), 0);
|
ccw_write_block(page, sizeof(struct df_s390_em), 0);
|
||||||
free_page(page);
|
free_page(page);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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 */
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
+10
-5
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "boot/boot_defs.h"
|
#include "boot/boot_defs.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
#include "dump/s390_dump.h"
|
||||||
|
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "job.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);
|
address_t envblk_addr, size_t envblk_len);
|
||||||
int boot_get_tape_ipl(void** data, size_t* size, address_t parm_addr,
|
int boot_get_tape_ipl(void** data, size_t* size, address_t parm_addr,
|
||||||
address_t initrd_addr, address_t image_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_tape_dump(void **data, size_t *size,
|
||||||
int boot_get_eckd_dump_stage2(void** data, size_t* size, uint64_t mem);
|
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,
|
int boot_get_eckd_ld_ipl_br(void **br_ptr, size_t *size_ptr,
|
||||||
disk_blockptr_t *table, struct disk_info *info);
|
disk_blockptr_t *table, struct disk_info *info);
|
||||||
int boot_get_eckd_mvdump_stage2(void** data, size_t* size, uint64_t mem,
|
int boot_get_eckd_mvdump_stage2(void **data, size_t *size,
|
||||||
uint8_t force, struct mvdump_parm_table);
|
const struct stage2dump_parm_tail *stage2dump_parms,
|
||||||
int boot_get_fba_dump_stage2(void** data, size_t* size, uint64_t mem);
|
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 */
|
#endif /* BOOT_H */
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ int install_tapeloader(const char* device, const char* image,
|
|||||||
const char* parmline, const char* ramdisk,
|
const char* parmline, const char* ramdisk,
|
||||||
address_t image_addr, address_t parm_addr,
|
address_t image_addr, address_t parm_addr,
|
||||||
address_t initrd_addr);
|
address_t initrd_addr);
|
||||||
int install_dump(const char* device, struct job_target_data* target,
|
int install_dump(const char *device, struct job_target_data *target,
|
||||||
uint64_t mem);
|
uint64_t mem, bool no_compress);
|
||||||
int install_mvdump(char* const device[], struct job_target_data* target,
|
int install_mvdump(char* const device[], struct job_target_data* target,
|
||||||
int device_count, uint64_t mem, uint8_t force);
|
int device_count, uint64_t mem, uint8_t force);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -72,6 +72,7 @@ struct job_dump_data {
|
|||||||
struct job_common_ipl_data common;
|
struct job_common_ipl_data common;
|
||||||
char* device;
|
char* device;
|
||||||
uint64_t mem;
|
uint64_t mem;
|
||||||
|
bool no_compress;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct job_mvdump_data {
|
struct job_mvdump_data {
|
||||||
@@ -87,7 +88,6 @@ struct job_ipl_tape_data {
|
|||||||
char* device;
|
char* device;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
union job_menu_entry_data {
|
union job_menu_entry_data {
|
||||||
struct job_ipl_data ipl;
|
struct job_ipl_data ipl;
|
||||||
struct job_dump_data dump;
|
struct job_dump_data dump;
|
||||||
|
|||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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