mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8d0fca36c | ||
|
|
bbd88f26c9 | ||
|
|
79bfa818ed | ||
|
|
299144264d | ||
|
|
a69470d7e0 | ||
|
|
b26dbfe832 | ||
|
|
d95dc6d698 | ||
|
|
847f16f632 | ||
|
|
bc053a975a | ||
|
|
e9c030f202 | ||
|
|
dffd41943e | ||
|
|
58189b8786 | ||
|
|
b165500b69 | ||
|
|
5f2ddad6a8 | ||
|
|
28deb03178 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,5 +1,19 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
* __v2.8.0 (2019-02-15)__
|
||||
|
||||
For Linux kernel version: 4.20
|
||||
|
||||
Changes of existing tools:
|
||||
- Switch to using /run directory instead of the legacy /var/run
|
||||
- zkey: Add --pbkdf pbkdf2 to generated cryptsetup luksFormat command
|
||||
- zdsfs: Add online VTOC refresh
|
||||
- pkey: Support autoloading kernel pkey module
|
||||
|
||||
Bug Fixes:
|
||||
- zkey: Avoid EPERM on key change if user is not owner of key file
|
||||
- cpumf/cpumf_helper: Always return list reference for --sfb-size
|
||||
|
||||
* __v2.7.1 (2018-12-13)__
|
||||
|
||||
For Linux kernel version: 4.19
|
||||
|
||||
@@ -5,8 +5,8 @@ COMMON_INCLUDED = true
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION = 2
|
||||
RELEASE = 7
|
||||
PATCHLEVEL = 1
|
||||
RELEASE = 8
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
export S390_TOOLS_RELEASE
|
||||
|
||||
@@ -110,7 +110,7 @@ The default command is --print all.
|
||||
.
|
||||
.SH FILES
|
||||
.nf
|
||||
/var/run/cpacfstatsd_socket
|
||||
/run/cpacfstatsd_socket
|
||||
.fi
|
||||
.
|
||||
.SH RETURN VALUE
|
||||
|
||||
@@ -78,8 +78,8 @@ struct msg_answer {
|
||||
|
||||
#define BACKLOG 10
|
||||
|
||||
#define SOCKET_FILE "/var/run/cpacfstatsd_socket"
|
||||
#define PID_FILE "/var/run/cpacfstatsd.pid"
|
||||
#define SOCKET_FILE "/run/cpacfstatsd_socket"
|
||||
#define PID_FILE "/run/cpacfstatsd.pid"
|
||||
|
||||
#define CPACFSTATS_GROUP "cpacfstats"
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ restart the daemon to ensure correct summing of the per-CPU performance
|
||||
counters.
|
||||
|
||||
The starting daemon first checks for any stale pid file
|
||||
/var/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
||||
/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
||||
file belongs to an active process, an error message is printed to the
|
||||
console and the program terminates.
|
||||
|
||||
@@ -81,8 +81,8 @@ daemon startup and initialization failures.
|
||||
|
||||
.SH FILES
|
||||
.nf
|
||||
/var/run/cpacfstatsd_socket
|
||||
/var/run/cpacfstatsd.pid
|
||||
/run/cpacfstatsd_socket
|
||||
/run/cpacfstatsd.pid
|
||||
.fi
|
||||
|
||||
.SH RETURN VALUE
|
||||
|
||||
@@ -51,10 +51,11 @@ sub cpumf_get_sfb_size()
|
||||
my $val = "0,0";
|
||||
my $SFBSIZE;
|
||||
|
||||
return $val unless open($SFBSIZE, '<', $CPUM_SFB_SIZE);
|
||||
$val = <$SFBSIZE>;
|
||||
chomp($val);
|
||||
close($SFBSIZE);
|
||||
if (open($SFBSIZE, '<', $CPUM_SFB_SIZE)) {
|
||||
$val = <$SFBSIZE>;
|
||||
chomp($val);
|
||||
close($SFBSIZE);
|
||||
}
|
||||
|
||||
return [split /,/, $val];
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#define NAME "cpuplugd"
|
||||
#define MAX_HISTORY 100
|
||||
#define PIDFILE "/var/run/cpuplugd.pid"
|
||||
#define PIDFILE "/run/cpuplugd.pid"
|
||||
#define LOCKFILE "/var/lock/cpuplugd.lock"
|
||||
#define PROCINFO_LINE 512
|
||||
#define CPUSTAT_SIZE 1024
|
||||
|
||||
@@ -1741,7 +1741,7 @@ static void dasdview_print_vtoc_raw(dasdview_info_t *info)
|
||||
" rc=%d\n", rc);
|
||||
exit(-1);
|
||||
}
|
||||
rc = lzds_dasd_read_rawvtoc(info->dasd);
|
||||
rc = lzds_dasd_alloc_rawvtoc(info->dasd);
|
||||
if (rc == EINVAL) {
|
||||
zt_error_print("dasdview: Cannot read VTOC because disk does"
|
||||
" not contain valid VOL1 label.\n",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
DAEMON=cpacfstatsd
|
||||
DAEMON_PATH=/usr/sbin/cpacfstatsd
|
||||
RUN_PID_FILE=/var/run/cpacfstatsd.pid
|
||||
RUN_PID_FILE=/run/cpacfstatsd.pid
|
||||
RETVAL=0
|
||||
OPTIONS=""
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
DAEMON=cpuplugd
|
||||
DAEMON_PATH=/usr/sbin/cpuplugd
|
||||
CONFIG_FILE=/etc/cpuplugd.conf
|
||||
RUN_PID_FILE=/var/run/cpuplugd.pid
|
||||
RUN_PID_FILE=/run/cpuplugd.pid
|
||||
RETVAL=0
|
||||
OPTIONS="-c $CONFIG_FILE"
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ DUMP_CONFIG_FILE=/etc/sysconfig/dumpconf
|
||||
CMDFULL=$0
|
||||
CMD="dumpconf"
|
||||
LOCKFILE=/var/lock/$CMD
|
||||
PIDFILE=/var/run/$CMD.pid
|
||||
PIDFILE=/run/$CMD.pid
|
||||
ERRMSG="Check $DUMP_CONFIG_FILE!"
|
||||
|
||||
RETVAL=0
|
||||
|
||||
@@ -20,8 +20,8 @@ PROCD=mon_procd
|
||||
FSSTATD_PATH=/usr/sbin/$FSSTATD
|
||||
PROCD_PATH=/usr/sbin/$PROCD
|
||||
CONFIG_FILE=/etc/sysconfig/$DAEMON
|
||||
FSSTATD_PID_FILE=/var/run/$FSSTATD.pid
|
||||
PROCD_PID_FILE=/var/run/$PROCD.pid
|
||||
FSSTATD_PID_FILE=/run/$FSSTATD.pid
|
||||
PROCD_PID_FILE=/run/$PROCD.pid
|
||||
|
||||
# source function library
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
2
etc/modules-load.d/s390-pkey.conf
Normal file
2
etc/modules-load.d/s390-pkey.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
# Load protected key support module on s390 early at boot
|
||||
pkey
|
||||
@@ -170,6 +170,10 @@ struct hd_geometry {
|
||||
#define BIODASDDISABLE _IO(DASD_IOCTL_LETTER, 0)
|
||||
/* Enable the volume (for Linux) */
|
||||
#define BIODASDENABLE _IO(DASD_IOCTL_LETTER, 1)
|
||||
/* Reserve the device for the current LPAR */
|
||||
#define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2)
|
||||
/* Release the device for the current LPAR */
|
||||
#define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3)
|
||||
/* Get information on a dasd device (enhanced) */
|
||||
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
||||
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
||||
@@ -203,5 +207,7 @@ int dasd_get_geo(const char *device, struct hd_geometry *geo);
|
||||
int dasd_get_info(const char *device, dasd_information2_t *info);
|
||||
int dasd_is_ro(const char *device, bool *ro);
|
||||
int dasd_reread_partition_table(const char *device, int ntries);
|
||||
int dasd_disk_reserve(const char *device);
|
||||
int dasd_disk_release(const char *device);
|
||||
|
||||
#endif /* LIB_DASD_BASE_H */
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
*/
|
||||
#define LIB_LIBZDS_H
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_list.h"
|
||||
#include "vtoc.h"
|
||||
|
||||
|
||||
@@ -328,11 +330,74 @@ struct pds_member_entry {
|
||||
*/
|
||||
struct zdsroot;
|
||||
|
||||
/**
|
||||
* @struct raw_vtoc
|
||||
* @brief The VTOC is a directory of data sets on one DASD
|
||||
*
|
||||
* As the VTOC is the data area on the DASD that describes all data sets,
|
||||
* this library will often have to refer to the various records in the VTOC.
|
||||
* To make this more efficient, we will read the whole VTOC once and identify
|
||||
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
||||
* DSCBs is stored.
|
||||
*/
|
||||
struct raw_vtoc {
|
||||
/** @brief The raw track data */
|
||||
char *rawdata;
|
||||
/** @brief This size of the raw track data in bytes */
|
||||
unsigned long long rawdatasize;
|
||||
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
||||
char **vtocindex;
|
||||
/** @brief Number of entries in the index */
|
||||
unsigned int vtocindexcount;
|
||||
/** @brief Number of records per VTOC track
|
||||
*
|
||||
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
||||
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
||||
* for record 0.
|
||||
*/
|
||||
unsigned int vtoc_rec_per_track;
|
||||
/** @brief The track number at which the vtoc begins on the DASD */
|
||||
unsigned int vtoctrackoffset;
|
||||
/** @brief Start record of VTOC.
|
||||
*
|
||||
* The rawdata contains full tracks. This is the number of the first
|
||||
* record that actually belongs to the VTOC
|
||||
*/
|
||||
unsigned int vtocrecno;
|
||||
/** @brief The DASD this vtoc was read from */
|
||||
struct dasd *dasd;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct dasd
|
||||
* @brief Represents one physical device, may have a vtoc
|
||||
*/
|
||||
struct dasd;
|
||||
struct dasd {
|
||||
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
||||
struct util_list_node list;
|
||||
/** @brief Name of the block device, e.g. /dev/dasde */
|
||||
char *device;
|
||||
/** @brief File descriptor for the block device.
|
||||
*
|
||||
* The device is kept open for as along as the library uses it.
|
||||
* This lets the system know that the device is still in use.
|
||||
*/
|
||||
int inusefd;
|
||||
/* @brief where to find the volume label */
|
||||
unsigned int label_block;
|
||||
/** @brief Device geometry. How many cylinders does the DASD have. */
|
||||
unsigned int cylinders;
|
||||
/** @brief Device geometry. How many heads does the DASD have. */
|
||||
unsigned int heads;
|
||||
/** @brief The VTOC data that has been read from this device */
|
||||
struct raw_vtoc *rawvtoc;
|
||||
/** @brief The volume label that has been read from this device */
|
||||
volume_label_t *vlabel;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct dasditerator
|
||||
@@ -350,12 +415,6 @@ struct dasditerator;
|
||||
*/
|
||||
struct dasdhandle;
|
||||
|
||||
/**
|
||||
* @struct raw_vtoc
|
||||
* @brief The VTOC is a directory of data sets on one dasd
|
||||
*/
|
||||
struct raw_vtoc;
|
||||
|
||||
/**
|
||||
* @struct dscbiterator
|
||||
* @brief allows to iterate over all DSCBs in a vtoc
|
||||
@@ -572,7 +631,13 @@ int lzds_dasd_get_vlabel(struct dasd *dasd, struct volume_label **vlabel);
|
||||
* @brief Read the vtoc data from device. The data as stored as part
|
||||
* of the struct dasd.
|
||||
*/
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd);
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *vtoc);
|
||||
|
||||
/**
|
||||
* @brief Read the vtoc data from device. The data as stored as part
|
||||
* of the struct dasd.
|
||||
*/
|
||||
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd);
|
||||
|
||||
/**
|
||||
* @brief Get the previously read raw_vtoc data.
|
||||
@@ -787,6 +852,8 @@ int lzds_zdsroot_extract_datasets_from_dasd(struct zdsroot *root,
|
||||
struct dasd *dasd);
|
||||
|
||||
|
||||
void lzds_dslist_free(struct zdsroot *root);
|
||||
|
||||
|
||||
/** @} */ /* end of group libzds_functions_high */
|
||||
|
||||
|
||||
@@ -68,5 +68,8 @@ const char *util_rec_get(struct util_rec *rec, const char *key);
|
||||
|
||||
void util_rec_print_hdr(struct util_rec *rec);
|
||||
void util_rec_print(struct util_rec *rec);
|
||||
void util_rec_print_separator(struct util_rec *rec);
|
||||
|
||||
void util_rec_set_indent(struct util_rec *rec, int indent);
|
||||
|
||||
#endif /** LIB_UTIL_REC_H @} */
|
||||
|
||||
@@ -261,3 +261,42 @@ int dasd_reread_partition_table(const char *device, int ntries)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve DASD disk.
|
||||
*
|
||||
* @param[in] device node device node's name
|
||||
*
|
||||
* @retval 0 in case of success
|
||||
* @retval errno in case of failure
|
||||
*
|
||||
*/
|
||||
int dasd_disk_reserve(const char *device)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = dasd_open_device(device, O_RDONLY);
|
||||
RUN_IOCTL(fd, BIODASDRSRV, NULL);
|
||||
dasd_close_device(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release DASD disk
|
||||
*
|
||||
* @param[in] device node device node's name
|
||||
*
|
||||
* @retval 0 in case of success
|
||||
* @retval errno in case of failure
|
||||
*/
|
||||
int dasd_disk_release(const char *device)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = dasd_open_device(device, O_RDONLY);
|
||||
RUN_IOCTL(fd, BIODASDRLSE, NULL);
|
||||
dasd_close_device(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ struct rec_fmt {
|
||||
int argz_sep;
|
||||
} csv_p;
|
||||
} d;
|
||||
int indent;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -122,9 +123,50 @@ struct util_rec *util_rec_new_wide(const char *hdr_sep)
|
||||
rec->fmt.type = REC_FMT_WIDE;
|
||||
rec->fmt.d.wide_p.hdr_sep = util_strdup(hdr_sep);
|
||||
rec->fmt.d.wide_p.argz_sep = ',';
|
||||
rec->fmt.indent = 0;
|
||||
return rec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the indentation characters
|
||||
*/
|
||||
static inline void rec_print_indention(int indent)
|
||||
{
|
||||
if (indent <= 0)
|
||||
return;
|
||||
|
||||
printf("%*s", indent, "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Print record separator in "wide" output format
|
||||
*/
|
||||
static void rec_print_wide_separator(struct util_rec *rec)
|
||||
{
|
||||
const char *hdr_sep = rec->fmt.d.wide_p.hdr_sep;
|
||||
int size = 0, field_count = 0;
|
||||
struct util_rec_fld *fld;
|
||||
char *buf;
|
||||
|
||||
if (!hdr_sep)
|
||||
return;
|
||||
|
||||
util_list_iterate(rec->list, fld) {
|
||||
if (fld->hdr) {
|
||||
size += fld->width;
|
||||
field_count++;
|
||||
}
|
||||
}
|
||||
|
||||
size += field_count - 1;
|
||||
buf = util_malloc(size + 1);
|
||||
memset(buf, (int)hdr_sep[0], size);
|
||||
buf[size] = 0;
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
printf("%s\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print record header in "wide" output format
|
||||
*/
|
||||
@@ -135,6 +177,7 @@ static void rec_print_wide_hdr(struct util_rec *rec)
|
||||
struct util_rec_fld *fld;
|
||||
char *buf;
|
||||
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
util_list_iterate(rec->list, fld) {
|
||||
if (col_nr)
|
||||
printf(" ");
|
||||
@@ -156,6 +199,7 @@ static void rec_print_wide_hdr(struct util_rec *rec)
|
||||
buf = util_malloc(size + 1);
|
||||
memset(buf, (int)hdr_sep[0], size);
|
||||
buf[size] = 0;
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
printf("%s\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
@@ -172,6 +216,7 @@ void rec_print_wide(struct util_rec *rec)
|
||||
int fld_count = 0;
|
||||
char *entry;
|
||||
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
util_list_iterate(rec->list, fld) {
|
||||
if (!fld->hdr)
|
||||
continue;
|
||||
@@ -225,6 +270,7 @@ struct util_rec *util_rec_new_long(const char *hdr_sep, const char *col_sep,
|
||||
rec->fmt.d.long_p.key_size = key_size;
|
||||
rec->fmt.d.long_p.val_size = val_size;
|
||||
rec->fmt.d.long_p.argz_sep = ' ';
|
||||
rec->fmt.indent = 0;
|
||||
return rec;
|
||||
}
|
||||
|
||||
@@ -241,6 +287,7 @@ static void rec_print_long_hdr(struct util_rec *rec)
|
||||
fld = rec_get_fld(rec, p->key);
|
||||
util_assert(fld != NULL, "Record not found\n");
|
||||
util_assert(fld->hdr != NULL, "Header for field not found\n");
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
if (p->col_sep) {
|
||||
printf("%-*s %s %-*s\n", p->key_size, fld->hdr,
|
||||
p->col_sep, fld->width, fld->val);
|
||||
@@ -255,6 +302,7 @@ static void rec_print_long_hdr(struct util_rec *rec)
|
||||
buf = util_malloc(len + 1);
|
||||
memset(buf, p->hdr_sep[0], len);
|
||||
buf[len] = 0;
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
printf("%s\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
@@ -277,19 +325,24 @@ static void rec_print_long(struct util_rec *rec)
|
||||
continue;
|
||||
if (!fld->val)
|
||||
continue;
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
item = argz_next(fld->val, fld->len, item);
|
||||
if (p->col_sep) {
|
||||
printf(" %-*s %s %s\n",
|
||||
p->key_size - 8, fld->hdr, p->col_sep, item);
|
||||
while ((item = argz_next(fld->val, fld->len, item)))
|
||||
while ((item = argz_next(fld->val, fld->len, item))) {
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
printf(" %-*s %c %s\n",
|
||||
p->key_size - 8, "", p->argz_sep, item);
|
||||
}
|
||||
} else {
|
||||
printf(" %-*s %s\n",
|
||||
p->key_size - 8, fld->hdr, fld->val);
|
||||
while ((item = argz_next(fld->val, fld->len, item)))
|
||||
while ((item = argz_next(fld->val, fld->len, item))) {
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
printf(" %-*s %s\n",
|
||||
p->key_size - 8, "", item);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
@@ -320,6 +373,7 @@ struct util_rec *util_rec_new_csv(const char *col_sep)
|
||||
rec->fmt.type = REC_FMT_CSV;
|
||||
rec->fmt.d.csv_p.col_sep = util_strdup(col_sep);
|
||||
rec->fmt.d.csv_p.argz_sep = ' ';
|
||||
rec->fmt.indent = 0;
|
||||
return rec;
|
||||
}
|
||||
|
||||
@@ -332,6 +386,7 @@ void rec_print_csv_hdr(struct util_rec *rec)
|
||||
struct util_rec_fld *fld;
|
||||
int fld_count = 0;
|
||||
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
util_list_iterate(rec->list, fld) {
|
||||
if (fld_count)
|
||||
printf("%c", *col_sep);
|
||||
@@ -354,6 +409,7 @@ void rec_print_csv(struct util_rec *rec)
|
||||
int fld_count = 0;
|
||||
char *item = NULL;
|
||||
|
||||
rec_print_indention(rec->fmt.indent);
|
||||
util_list_iterate(rec->list, fld) {
|
||||
item = argz_next(fld->val, fld->len, item);
|
||||
if (fld_count)
|
||||
@@ -470,6 +526,24 @@ void util_rec_print_hdr(struct util_rec *rec)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print record separator according to output format
|
||||
*
|
||||
* @param[in] rec Record pointer
|
||||
*/
|
||||
void util_rec_print_separator(struct util_rec *rec)
|
||||
{
|
||||
switch (rec->fmt.type) {
|
||||
case REC_FMT_WIDE:
|
||||
rec_print_wide_separator(rec);
|
||||
break;
|
||||
case REC_FMT_LONG:
|
||||
break;
|
||||
case REC_FMT_CSV:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a field value to an argz vector
|
||||
*
|
||||
@@ -537,3 +611,14 @@ const char *util_rec_get(struct util_rec *rec, const char *key)
|
||||
|
||||
return (fld != NULL) ? fld->val : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the indentation of the record
|
||||
*
|
||||
* @param[in] rec Record pointer
|
||||
* @param[in] indent Number of characters to indent
|
||||
*/
|
||||
void util_rec_set_indent(struct util_rec *rec, int indent)
|
||||
{
|
||||
rec->fmt.indent = indent;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ static void print_records(const char *format, struct util_rec *rec)
|
||||
/* Print the record */
|
||||
util_rec_print(rec);
|
||||
}
|
||||
/* Print a separator line (is a nop for long and csv format) */
|
||||
util_rec_print_separator(rec);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -72,6 +74,11 @@ int main(void)
|
||||
print_records("Wide format", rec);
|
||||
util_rec_free(rec);
|
||||
|
||||
rec = util_rec_new_wide("-");
|
||||
util_rec_set_indent(rec, 4);
|
||||
print_records("Wide format with indentation", rec);
|
||||
util_rec_free(rec);
|
||||
|
||||
rec = util_rec_new_long("-", ":", "number", 30, 20);
|
||||
print_records("Long format", rec);
|
||||
util_rec_free(rec);
|
||||
|
||||
184
libzds/libzds.c
184
libzds/libzds.c
@@ -22,8 +22,6 @@
|
||||
#include "lib/dasd_base.h"
|
||||
#include "lib/libzds.h"
|
||||
#include "lib/u2s.h"
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_list.h"
|
||||
#include "lib/vtoc.h"
|
||||
|
||||
/** @cond PRIVATE */
|
||||
@@ -70,42 +68,6 @@ struct errormsg {
|
||||
char text[ERRORMSG];
|
||||
};
|
||||
|
||||
/**
|
||||
* As the VTOC is the data area on the DASD that describes all data sets,
|
||||
* this library will often have to refer to the various records in the VTOC.
|
||||
* To make this more efficiant, we will read the whole VTOC once and identify
|
||||
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
||||
* DSCBs is stored.
|
||||
*/
|
||||
struct raw_vtoc {
|
||||
/** @brief The raw track data */
|
||||
char *rawdata;
|
||||
/** @brief This size of the raw track data in bytes */
|
||||
unsigned long long rawdatasize;
|
||||
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
||||
char **vtocindex;
|
||||
/** @brief Number of entries in the index */
|
||||
unsigned int vtocindexcount;
|
||||
/** @brief Number of records per VTOC track
|
||||
*
|
||||
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
||||
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
||||
* for record 0.
|
||||
*/
|
||||
unsigned int vtoc_rec_per_track;
|
||||
/** @brief The track number in which the vtoc begins on the DASD */
|
||||
unsigned int vtoctrackoffset;
|
||||
/** @brief Start record of VTOC.
|
||||
*
|
||||
* The rawdata contains full tracks. This is the number of the first
|
||||
* record that actually belongs to the VTOC */
|
||||
unsigned int vtocrecno;
|
||||
/** @brief The DASD this vtoc was read from */
|
||||
struct dasd *dasd;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
struct dscbiterator {
|
||||
/** @brief The raw_vtoc this iterator refers to */
|
||||
struct raw_vtoc *rawvtoc;
|
||||
@@ -113,31 +75,6 @@ struct dscbiterator {
|
||||
unsigned int i;
|
||||
};
|
||||
|
||||
struct dasd {
|
||||
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
||||
struct util_list_node list;
|
||||
/** @brief Name of the block device, e.g. /dev/dasde */
|
||||
char *device;
|
||||
/** @brief File descriptor for the block device.
|
||||
*
|
||||
* The device is kept open for as along as the library uses it.
|
||||
* This lets the system know that the device is still in use.
|
||||
*/
|
||||
int inusefd;
|
||||
/* @brief where to find the volume label */
|
||||
unsigned int label_block;
|
||||
/** @brief Device geometry. How many cylinders does the DASD have. */
|
||||
unsigned int cylinders;
|
||||
/** @brief Device geometry. How many heads does the DASD have. */
|
||||
unsigned int heads;
|
||||
/** @brief The VTOC data that has been read from this device */
|
||||
struct raw_vtoc *rawvtoc;
|
||||
/** @brief The volume label that has been read from this device */
|
||||
volume_label_t *vlabel;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
struct dasdhandle {
|
||||
/** @brief The struct dasd this context relates to */
|
||||
struct dasd *dasd;
|
||||
@@ -412,6 +349,29 @@ int lzds_zdsroot_alloc(struct zdsroot **root)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It should be noted that this frees all structures that are owned by the
|
||||
* root structure as well. For example, a pointer to a struct dasd that
|
||||
* has been returned by lzds_zdsroot_add_device is not valid anymore.
|
||||
*
|
||||
* @param[in] root Reference to the zdsroot structure that is to be freed.
|
||||
*/
|
||||
void lzds_dslist_free(struct zdsroot *root)
|
||||
{
|
||||
struct dataset *ds, *nextds;
|
||||
int i;
|
||||
|
||||
util_list_iterate_safe(root->datasetlist, ds, nextds) {
|
||||
util_list_remove(root->datasetlist, ds);
|
||||
dataset_free_memberlist(ds);
|
||||
for (i = 0; i < MAXVOLUMESPERDS; ++i)
|
||||
free(ds->dsp[i]);
|
||||
errorlog_free(ds->log);
|
||||
free(ds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It should be noted that this frees all structures that are owned by the
|
||||
* root structure as well. For example, a pointer to a struct dasd that
|
||||
@@ -422,8 +382,6 @@ int lzds_zdsroot_alloc(struct zdsroot **root)
|
||||
void lzds_zdsroot_free(struct zdsroot *root)
|
||||
{
|
||||
struct dasd *dasd, *nextdasd;
|
||||
struct dataset *ds, *nextds;
|
||||
int i;
|
||||
|
||||
if (!root)
|
||||
return;
|
||||
@@ -433,15 +391,7 @@ void lzds_zdsroot_free(struct zdsroot *root)
|
||||
dasd_free(dasd);
|
||||
}
|
||||
util_list_free(root->dasdlist);
|
||||
|
||||
util_list_iterate_safe(root->datasetlist, ds, nextds) {
|
||||
util_list_remove(root->datasetlist, ds);
|
||||
dataset_free_memberlist(ds);
|
||||
for (i = 0; i < MAXVOLUMESPERDS; ++i)
|
||||
free(ds->dsp[i]);
|
||||
errorlog_free(ds->log);
|
||||
free(ds);
|
||||
}
|
||||
lzds_dslist_free(root);
|
||||
util_list_free(root->datasetlist);
|
||||
errorlog_free(root->log);
|
||||
free(root);
|
||||
@@ -1443,7 +1393,7 @@ int lzds_raw_vtoc_get_dscb_from_cchhb(struct raw_vtoc *rv, cchhb_t *p,
|
||||
* - EPROTO The VTOC data is not in a valid format.
|
||||
* - EIO Other I/O error
|
||||
*/
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *rawvtoc)
|
||||
{
|
||||
unsigned long long vtoctrckno, vtocrecno;
|
||||
unsigned int vtoctrack_start, vtoctrack_end, vtocindexsize;
|
||||
@@ -1455,26 +1405,11 @@ int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
||||
format4_label_t *f4;
|
||||
unsigned long long rawvtocsize;
|
||||
|
||||
struct raw_vtoc *rawvtoc = NULL;
|
||||
volume_label_t *vlabel = NULL;
|
||||
char *trackdata = NULL;
|
||||
char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00}; /* "VOL1" in EBCDIC */
|
||||
|
||||
errorlog_clear(dasd->log);
|
||||
/* cleanup the old rawvtoc structures before we read new ones */
|
||||
rawvtoc = dasd->rawvtoc;
|
||||
dasd->rawvtoc = NULL;
|
||||
if (rawvtoc) {
|
||||
free(rawvtoc->rawdata);
|
||||
free(rawvtoc->vtocindex);
|
||||
free(rawvtoc);
|
||||
}
|
||||
|
||||
rawvtoc = malloc(sizeof(*rawvtoc));
|
||||
if (!rawvtoc)
|
||||
return ENOMEM;
|
||||
memset(rawvtoc, 0, sizeof(*rawvtoc));
|
||||
rawvtoc->dasd = dasd;
|
||||
|
||||
rc = lzds_dasd_get_vlabel(dasd, &vlabel);
|
||||
if (rc) {
|
||||
@@ -1611,13 +1546,49 @@ int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
||||
++i;
|
||||
}
|
||||
|
||||
dasd->rawvtoc = rawvtoc;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
free(rawvtoc->vtocindex);
|
||||
free(trackdata);
|
||||
free(rawvtoc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param[in] dasd The struct dasd that represents the device we want to read
|
||||
* the VTOC from.
|
||||
* @return 0 on success, otherwise one of the following error codes:
|
||||
* - ENOMEM Could not allocate internal structure due to lack of memory.
|
||||
* - EINVAL The volume label has not yet been read or it is not valid.
|
||||
* - EPROTO The VTOC data is not in a valid format.
|
||||
* - EIO Other I/O error
|
||||
*/
|
||||
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd)
|
||||
{
|
||||
struct raw_vtoc *rawvtoc = NULL;
|
||||
int rc;
|
||||
|
||||
/* cleanup the old rawvtoc structures before we read new ones */
|
||||
rawvtoc = dasd->rawvtoc;
|
||||
dasd->rawvtoc = NULL;
|
||||
if (rawvtoc) {
|
||||
free(rawvtoc->rawdata);
|
||||
free(rawvtoc->vtocindex);
|
||||
free(rawvtoc);
|
||||
}
|
||||
|
||||
rawvtoc = malloc(sizeof(*rawvtoc));
|
||||
if (!rawvtoc)
|
||||
return ENOMEM;
|
||||
memset(rawvtoc, 0, sizeof(*rawvtoc));
|
||||
rawvtoc->dasd = dasd;
|
||||
|
||||
rc = lzds_dasd_read_rawvtoc(dasd, rawvtoc);
|
||||
if (rc) {
|
||||
free(rawvtoc->vtocindex);
|
||||
free(rawvtoc);
|
||||
} else {
|
||||
dasd->rawvtoc = rawvtoc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2261,6 +2232,7 @@ out1:
|
||||
static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
||||
{
|
||||
int k, l, dspcount;
|
||||
|
||||
for (k = 0; k < MAXVOLUMESPERDS; ++k) {
|
||||
/* if both datasets have a part in position k,
|
||||
* then something is wrong */
|
||||
@@ -2280,18 +2252,20 @@ static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
||||
* Since dsp[0] may not be set yet, we loop over the
|
||||
* base dsp array until we find an entry.
|
||||
*/
|
||||
for (l = 0; l < MAXVOLUMESPERDS; ++l)
|
||||
if (baseds->dsp[l]) {
|
||||
if (memcmp(baseds->dsp[l]->f1->DS1DSSN,
|
||||
newds->dsp[k]->f1->DS1DSSN,
|
||||
MAXVOLSER))
|
||||
return errorlog_add_message(
|
||||
&baseds->log, NULL, EPROTO,
|
||||
"merge dataset: part %d has incompatible"
|
||||
" base volume serial\n", k);
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (l = 0; l < MAXVOLUMESPERDS; ++l) {
|
||||
if (!baseds->dsp[l])
|
||||
continue;
|
||||
if (memcmp(baseds->dsp[l]->f1->DS1DSSN,
|
||||
newds->dsp[k]->f1->DS1DSSN,
|
||||
MAXVOLSER))
|
||||
return errorlog_add_message(
|
||||
&baseds->log, NULL, EPROTO,
|
||||
"merge dataset: part %d has incompatible base volume serial\n",
|
||||
k);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
baseds->dsp[k] = newds->dsp[k];
|
||||
baseds->dspcount++;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ static char small_mon_record[SMALL_MON_RECORD_LEN];
|
||||
static char large_mon_record[LARGE_MON_RECORD_LEN];
|
||||
static long sample_interval = 60;
|
||||
|
||||
static const char *pid_file = "/var/run/mon_fsstatd.pid";
|
||||
static const char *pid_file = "/run/mon_fsstatd.pid";
|
||||
|
||||
struct mw_name_lens {
|
||||
__u16 mw_name_len;
|
||||
|
||||
@@ -59,7 +59,7 @@ static char buf[BUF_SIZE];
|
||||
static char mon_record[MAX_REC_LEN];
|
||||
static long sample_interval = 60;
|
||||
|
||||
static const char *pid_file = "/var/run/mon_procd.pid";
|
||||
static const char *pid_file = "/run/mon_procd.pid";
|
||||
|
||||
/*
|
||||
* Clean up when SIGTERM or SIGINT received
|
||||
|
||||
@@ -167,6 +167,9 @@ readonly OUTPUT_FILE_VMCMD="${WORKPATH}zvm_runtime.out"
|
||||
# File that includes content of files from sysfs
|
||||
readonly OUTPUT_FILE_SYSFS="${WORKPATH}sysfsfiles.out"
|
||||
|
||||
# File that includes the output of lsof
|
||||
readonly OUTPUT_FILE_LSOF="${WORKPATH}open_files.out"
|
||||
|
||||
# File that includes content of OSA OAT
|
||||
readonly OUTPUT_FILE_OSAOAT="${WORKPATH}osa_oat"
|
||||
|
||||
@@ -307,12 +310,13 @@ LOGFILES="\
|
||||
/var/log/lin_tape.trace\
|
||||
/var/log/lin_tape.errorlog\
|
||||
/var/log/messages*\
|
||||
/var/log/opencryptoki\
|
||||
/var/log/syslog*\
|
||||
/var/log/sa\
|
||||
/var/log/yum.log\
|
||||
/var/log/openvswitch/ovs-vswitchd.log\
|
||||
/var/log/openvswitch/ovsdb-server.log\
|
||||
/var/run/docker/libcontainerd/containerd/events.log\
|
||||
/run/docker/libcontainerd/containerd/events.log\
|
||||
/run/containerd/events.log\
|
||||
"
|
||||
|
||||
@@ -441,7 +445,8 @@ CMDS="uname -a\
|
||||
:SPident\
|
||||
:rpm -qa | sort\
|
||||
:sysctl -a\
|
||||
:lsof\
|
||||
:lsof \
|
||||
> '${OUTPUT_FILE_LSOF}'\
|
||||
:mount\
|
||||
:df -h\
|
||||
:df -i\
|
||||
|
||||
@@ -15,7 +15,7 @@ ConditionVirtualization=no
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=@usrsbin_path@/cpacfstatsd
|
||||
PIDFile=/var/run/cpacfstatsd.pid
|
||||
PIDFile=/run/cpacfstatsd.pid
|
||||
KillMode=process
|
||||
Restart=no
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ ExecStart=@usrsbin_path@/cpuplugd -c @sysconf_path@/cpuplugd.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Type=forking
|
||||
PIDFile=/var/run/cpuplugd.pid
|
||||
PIDFile=/run/cpuplugd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -34,7 +34,7 @@ ExecStart=@usrsbin_path@/mon_fsstatd -i $FSSTAT_INTERVAL
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Type=forking
|
||||
PIDFile=/var/run/mon_fsstatd.pid
|
||||
PIDFile=/run/mon_fsstatd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -34,7 +34,7 @@ ExecStart=@usrsbin_path@/mon_procd -i $PROC_INTERVAL
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Type=forking
|
||||
PIDFile=/var/run/mon_procd.pid
|
||||
PIDFile=/run/mon_procd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
.\" nroff -man lszcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
.TH LSZCRYPT 8 "OCT 2017" "s390-tools"
|
||||
.TH LSZCRYPT 8 "JAN 2019" "s390-tools"
|
||||
.SH NAME
|
||||
lszcrypt \- display zcrypt device and configuration information
|
||||
.SH SYNOPSIS
|
||||
@@ -111,6 +111,68 @@ Displays help text and exits.
|
||||
.TP 8
|
||||
.B -v, --version
|
||||
Displays version information and exits.
|
||||
.SH VERBOSE LISTING DETAILS
|
||||
Some of the columns showing up in verbose listing mode may need some
|
||||
explanation:
|
||||
.TP
|
||||
.B TYPE and HWTYPE
|
||||
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
||||
device driver presumes that this crypto card is. The currently known values
|
||||
are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5 and 12=CEX6.
|
||||
.br
|
||||
The TYPE is a human readable value showing the hardware type and the basic
|
||||
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
||||
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
||||
.TP
|
||||
.B REQUESTS
|
||||
This is the counter value of successful processed requests on card or queue
|
||||
level. Successful here means the request was processed without any failure
|
||||
in the whole processing chain.
|
||||
.TP
|
||||
.B PENDING
|
||||
The underlying firmware and hardware layer usually provide some queuing
|
||||
space for requests. When this queue is already filled up, the zcrypt device
|
||||
driver maintains a software queue of pending requests. The sum of these
|
||||
both values is displayed here and shows the amount of requests waiting for
|
||||
processing on card or queue level.
|
||||
.TP
|
||||
.B FUNCTIONS
|
||||
This column shows firmware and hardware function details:
|
||||
.br
|
||||
S - APSC available: card/queue can handle requests with the special bit
|
||||
enabled.
|
||||
.br
|
||||
M - Accelerator card/queue with support for RSA ME with up to 4k key size.
|
||||
.br
|
||||
C - Accelerator card/queue with support for RSA CRT with up to 4k key size.
|
||||
.br
|
||||
D - Card/queue is providing CCA functions (this is the CCA Coprocessor mode).
|
||||
.br
|
||||
A - Card/queue is providing Accelerator functions (this is the Accelerator mode).
|
||||
.br
|
||||
X - Card/queue is providing EP11 functions (this is the EP11 Coprocessor mode).
|
||||
.br
|
||||
N - APXA available (ability to address more than 16 crypto cards and domains).
|
||||
.br
|
||||
F - Full function support (opposed to restricted function support, see below).
|
||||
.br
|
||||
R - Restricted function support. The F and R flag both reflect if a
|
||||
hypervisor is somehow restricting this crypto resource in a virtual
|
||||
environment. Dependent on the hypervisor configuration the crypto requests
|
||||
may be filtered by the hypervisor to allow only a subset of functions
|
||||
within the virtual runtime environment. For example a shared CCA
|
||||
Coprocessor may be restricted by the hypervisor to allow only clear key
|
||||
operations within the guests.
|
||||
.TP
|
||||
.B DRIVER
|
||||
.br
|
||||
Shows which card or queue device driver currently handles this crypto
|
||||
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX6
|
||||
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
||||
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
|
||||
for use by kvm hypervisor for kvm guests and not accessible to host
|
||||
applications). It is also valid to have no driver handling a queue which is
|
||||
shown as a -no-driver- entry.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B lszcrypt
|
||||
|
||||
@@ -53,6 +53,8 @@ struct zdsfs_info {
|
||||
};
|
||||
|
||||
static struct zdsfs_info zdsfsinfo;
|
||||
static int zdsfs_create_meta_data_buffer(struct zdsfs_info *);
|
||||
static int zdsfs_verify_datasets(void);
|
||||
|
||||
struct zdsfs_file_info {
|
||||
struct dshandle *dsh;
|
||||
@@ -193,6 +195,48 @@ static int zdsfs_getattr(const char *path, struct stat *stbuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void zdsfs_read_device(struct dasd *newdasd, const char *device)
|
||||
{
|
||||
struct errorlog *log;
|
||||
int rc;
|
||||
|
||||
rc = dasd_disk_reserve(device);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when reserving device %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_dasd_alloc_rawvtoc(newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when reading VTOC from device %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_zdsroot_extract_datasets_from_dasd(zdsfsinfo.zdsroot,
|
||||
newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"error when extracting data sets from dasd %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_zdsroot_get_errorlog(zdsfsinfo.zdsroot, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = dasd_disk_release(device);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when releasing device %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int zdsfs_statfs(const char *UNUSED(path), struct statvfs *statvfs)
|
||||
{
|
||||
struct dasditerator *dasdit;
|
||||
@@ -239,6 +283,33 @@ static int zdsfs_statfs(const char *UNUSED(path), struct statvfs *statvfs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int zdsfs_update_vtoc(void)
|
||||
{
|
||||
struct dasditerator *dasdit;
|
||||
struct dasd *dasd;
|
||||
int rc;
|
||||
|
||||
lzds_dslist_free(zdsfsinfo.zdsroot);
|
||||
rc = lzds_zdsroot_alloc_dasditerator(zdsfsinfo.zdsroot, &dasdit);
|
||||
if (rc)
|
||||
return -ENOMEM;
|
||||
|
||||
while (!lzds_dasditerator_get_next_dasd(dasdit, &dasd))
|
||||
zdsfs_read_device(dasd, dasd->device);
|
||||
|
||||
lzds_dasditerator_free(dasdit);
|
||||
rc = zdsfs_verify_datasets();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = zdsfs_create_meta_data_buffer(&zdsfsinfo);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zdsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
off_t UNUSED(offset), struct fuse_file_info *UNUSED(fi))
|
||||
{
|
||||
@@ -252,6 +323,10 @@ static int zdsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
int rc;
|
||||
int ispds, issupported;
|
||||
|
||||
rc = zdsfs_update_vtoc();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* we have two type of directories
|
||||
* type one: the root directory contains all data sets
|
||||
*/
|
||||
@@ -328,6 +403,9 @@ static int zdsfs_open(const char *path, struct fuse_file_info *fi)
|
||||
goto error1;
|
||||
|
||||
if (strcmp(path, "/"METADATAFILE) == 0) {
|
||||
rc = zdsfs_update_vtoc();
|
||||
if (rc)
|
||||
return rc;
|
||||
zfi->dsh = NULL;
|
||||
zfi->is_metadata_file = 1;
|
||||
zfi->metaread = 0;
|
||||
@@ -595,6 +673,7 @@ static int zdsfs_verify_datasets(void)
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
while (!lzds_dsiterator_get_next_dataset(dsit, &ds)) {
|
||||
lzds_dataset_get_name(ds, &dsname);
|
||||
lzds_dataset_get_is_complete(ds, &iscomplete);
|
||||
if (!iscomplete) {
|
||||
lzds_dataset_get_name(ds, &dsname);
|
||||
@@ -821,23 +900,7 @@ static void zdsfs_process_device(const char *device)
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_dasd_read_rawvtoc(newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when reading VTOC from device %s:"
|
||||
" %s\n", device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_zdsroot_extract_datasets_from_dasd(zdsfsinfo.zdsroot,
|
||||
newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when extracting data sets from dasd %s:"
|
||||
" %s\n", device, strerror(rc));
|
||||
lzds_zdsroot_get_errorlog(zdsfsinfo.zdsroot, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
zdsfs_read_device(newdasd, device);
|
||||
}
|
||||
|
||||
static void zdsfs_process_device_file(const char *devfile)
|
||||
|
||||
@@ -405,7 +405,7 @@ function check_cpuplugd {
|
||||
# check if cpuplugd is running
|
||||
# If so, the whole per-cpu mechanism of blktrace gets corrupted, which
|
||||
# results in the infamous 'bad trace magic' message
|
||||
if [ -e /var/run/cpuplugd.pid ]; then
|
||||
if [ -e /run/cpuplugd.pid ]; then
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
|
||||
echo "$WRP_TOOLNAME: Warning: cpuplugd is running which can corrupt the traces.";
|
||||
echo " It is recommended to stop cpuplugd for the duration of the";
|
||||
|
||||
@@ -259,13 +259,13 @@ static int _keystore_set_file_permission(struct keystore *keystore,
|
||||
|
||||
if (chmod(filename, keystore->mode) != 0) {
|
||||
rc = -errno;
|
||||
warnx("chmod faild on file '%s': %s", filename, strerror(-rc));
|
||||
warnx("chmod failed on file '%s': %s", filename, strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (chown(filename, geteuid(), keystore->owner) != 0) {
|
||||
rc = -errno;
|
||||
warnx("chown faild on file '%s': %s", filename, strerror(-rc));
|
||||
warnx("chown failed on file '%s': %s", filename, strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1982,10 +1982,6 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _keystore_set_file_permission(keystore, file_names.info_filename);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
pr_verbose(keystore, "Successfully changed key '%s'", name);
|
||||
|
||||
out:
|
||||
@@ -2683,10 +2679,6 @@ static int _keystore_process_reencipher(struct keystore *keystore,
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = _keystore_set_file_permission(keystore, out_file);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
if (params.complete || params.inplace == 1) {
|
||||
rc = _keystore_set_timestamp_property(properties,
|
||||
PROP_NAME_REENC_TIME);
|
||||
@@ -2712,11 +2704,6 @@ static int _keystore_process_reencipher(struct keystore *keystore,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _keystore_set_file_permission(keystore,
|
||||
file_names->info_filename);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
util_asprintf(&temp, "The following LUKS2 volumes are "
|
||||
"encrypted with key '%s'. You should also "
|
||||
"re-encipher the volume key of those volumes "
|
||||
@@ -3314,10 +3301,16 @@ static int _keystore_process_cryptsetup(struct keystore *keystore,
|
||||
printf("%s\n", cmd);
|
||||
}
|
||||
} else if (strcasecmp(volume_type, VOLUME_TYPE_LUKS2) == 0) {
|
||||
/*
|
||||
* Use PBKDF2 as key derivation function for LUKS2 volumes.
|
||||
* LUKS2 uses Argon2i as default, but this might cause
|
||||
* out-of-memory errors when multiple LUKS2 volumes are opened
|
||||
* automatically via /etc/crypttab
|
||||
*/
|
||||
util_asprintf(&cmd,
|
||||
"cryptsetup luksFormat %s--type luks2 "
|
||||
"--master-key-file '%s' --key-size %lu "
|
||||
"--cipher %s %s%s",
|
||||
"--cipher %s --pbkdf pbkdf2 %s%s",
|
||||
keystore->verbose ? "-v " : "", key_file_name,
|
||||
key_file_size * 8, cipher_spec,
|
||||
sector_size > 0 ? temp : "", volume);
|
||||
|
||||
@@ -180,6 +180,20 @@ and
|
||||
to control which part of the key file is used as passphrase. These options
|
||||
behave in the same way as with \fBcryptsetup\fP.
|
||||
.PP
|
||||
The
|
||||
.B reencipher
|
||||
command creates a new key slot with the re-enciphered secure AES volume key.
|
||||
The new key slot uses
|
||||
.B PBKDF2
|
||||
as password based key derivation function. LUKS2 volumes typically default to
|
||||
.B Argon2i
|
||||
as password based key derivation function,
|
||||
but this might cause out-of-memory errors when multiple encrypted volumes are
|
||||
unlocked automatically at boot through /etc/crypttab. Because PAES
|
||||
uses secure AES keys as volume keys, the security of the key derivation
|
||||
function used to encrypt the volume key in the LUKS key slots is of less
|
||||
relevance.
|
||||
.PP
|
||||
.B Note:
|
||||
The \fBreencipher\fP command requires the CCA host library (libcsulcca.so)
|
||||
to be installed. For the supported environments and downloads, see:
|
||||
@@ -288,6 +302,20 @@ and
|
||||
.B \-\-keyfile\-size
|
||||
to control which part of the key file is used as passphrase. These options
|
||||
behave in the same way the same as with \fBcryptsetup\fP.
|
||||
.PP
|
||||
The
|
||||
.B setkey
|
||||
command creates a new key slot with the re-enciphered secure AES volume key.
|
||||
The new key slot uses
|
||||
.B PBKDF2
|
||||
as password based key derivation function. LUKS2 volumes typically default to
|
||||
.B Argon2i
|
||||
as password based key derivation function,
|
||||
but this might cause out-of-memory errors when multiple encrypted volumes are
|
||||
unlocked automatically at boot through /etc/crypttab. Because PAES
|
||||
uses secure AES keys as volume keys, the security of the key derivation
|
||||
function used to encrypt the volume key in the LUKS key slots is of less
|
||||
relevance.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
@@ -1096,7 +1096,11 @@ static int put_vp_token(struct crypt_device *cd, int token,
|
||||
*/
|
||||
static int open_device(const char *device, struct crypt_device **cd)
|
||||
{
|
||||
const struct crypt_pbkdf_type *pbkdf;
|
||||
const struct crypt_pbkdf_type pbkdf2 = {
|
||||
.type = CRYPT_KDF_PBKDF2,
|
||||
.hash = "sha256",
|
||||
.time_ms = 2000,
|
||||
};
|
||||
struct crypt_device *cdev = NULL;
|
||||
int rc;
|
||||
|
||||
@@ -1128,10 +1132,14 @@ static int open_device(const char *device, struct crypt_device **cd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
pbkdf = crypt_get_pbkdf_type(cdev);
|
||||
rc = crypt_set_pbkdf_type(cdev, pbkdf);
|
||||
/*
|
||||
* Set PBKDF2 as default key derivation function. LUKS2 uses
|
||||
* Argon2i as default, but this might cause out-of-memory errors when
|
||||
* multiple LUKS2 volumes are opened automatically via /etc/crypttab
|
||||
*/
|
||||
rc = crypt_set_pbkdf_type(cdev, &pbkdf2);
|
||||
if (rc != 0) {
|
||||
warnx("Failed to set the PBKDF-type for device '%s': %s",
|
||||
warnx("Failed to set the PBKDF for device '%s': %s",
|
||||
device, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -567,6 +567,15 @@ option to generate cryptsetup commands for the specified volume type only.
|
||||
Specify the
|
||||
.B \-\-run
|
||||
option to run the generated cryptsetup commands.
|
||||
.P
|
||||
For LUKS2 volumes, the generated \fBcryptsetup luksFormat\fP contains
|
||||
option \fB\-\-pbkdf pbkdf2\fP to set \fBPBKDF2\fP as password based key
|
||||
derivation function. LUKS2 volumes typically default to \fBArgon2i\fP as
|
||||
password based key derivation function, but this might cause out-of-memory
|
||||
errors when multiple encrypted volumes are unlocked automatically at boot
|
||||
through /etc/crypttab. Because PAES uses secure AES keys as volume keys, the
|
||||
security of the key derivation function used to encrypt the volume key in the
|
||||
LUKS key slots is of less relevance.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
Reference in New Issue
Block a user