mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8d0fca36c | ||
|
|
bbd88f26c9 | ||
|
|
79bfa818ed | ||
|
|
299144264d | ||
|
|
a69470d7e0 | ||
|
|
b26dbfe832 | ||
|
|
d95dc6d698 | ||
|
|
847f16f632 | ||
|
|
bc053a975a | ||
|
|
e9c030f202 | ||
|
|
dffd41943e | ||
|
|
58189b8786 | ||
|
|
b165500b69 | ||
|
|
5f2ddad6a8 | ||
|
|
28deb03178 | ||
|
|
8f1fa2a83c | ||
|
|
7677d3c0b4 | ||
|
|
6f7cb68dcf | ||
|
|
4d008849f7 | ||
|
|
d921c230ab | ||
|
|
6151889dcd | ||
|
|
224dc2e414 | ||
|
|
5a10aa73a9 | ||
|
|
428d41034e | ||
|
|
cf265cc46a | ||
|
|
84623f39dc | ||
|
|
8cbdfebc4f | ||
|
|
4951044213 | ||
|
|
667516681e | ||
|
|
10ce432196 | ||
|
|
320a49fc1a | ||
|
|
f0d18ddf2b | ||
|
|
2962248e7b | ||
|
|
773c8672ac | ||
|
|
637750f299 | ||
|
|
a17b52a043 | ||
|
|
d14051e309 | ||
|
|
d85cf20981 | ||
|
|
7df8edd88a | ||
|
|
6d382d30d9 | ||
|
|
9f8d245f92 | ||
|
|
cf39f26dee | ||
|
|
83106991ab | ||
|
|
b631c74df5 | ||
|
|
c675096899 | ||
|
|
5a9e93fb5b | ||
|
|
aefc8cd3ff | ||
|
|
a208463e49 | ||
|
|
a931428908 | ||
|
|
c2297a0a7e | ||
|
|
70a79fab3c | ||
|
|
b5a7b13e71 | ||
|
|
52b2cb8424 | ||
|
|
03b2bf028b | ||
|
|
81f9a67d6f | ||
|
|
c15f481181 | ||
|
|
4170cceb52 | ||
|
|
a648dbb014 | ||
|
|
322d51e5e4 | ||
|
|
a1db08160d | ||
|
|
31b77e1646 | ||
|
|
a4acf7c991 | ||
|
|
17cade6e7f | ||
|
|
90ea5d9e5d | ||
|
|
6accffd583 | ||
|
|
4e5afb9b71 | ||
|
|
9f247795f3 | ||
|
|
71976f8e4b | ||
|
|
851f685993 | ||
|
|
9100327092 | ||
|
|
e2d433bb10 |
38
CHANGELOG.md
38
CHANGELOG.md
@@ -1,5 +1,43 @@
|
||||
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
|
||||
|
||||
Changes of existing tools:
|
||||
- zkey: Enhance file read/write error handling
|
||||
- cmsfs-fuse: Write more than a single line in linefeed mode
|
||||
- zpcictl: Add warning for unsupported operations
|
||||
- zipl: Use the BLS "title" field as the IPL section name
|
||||
|
||||
Bug Fixes:
|
||||
- cmsfs-fuse: Fix iconv buffer aliasing
|
||||
- cmsfs-fuse: Fix memory leak in cmsfs_rename()
|
||||
- fdasd: Fix possible integer overflow
|
||||
- fdasd: Fix resource leak in fdasd_parse_conffile()
|
||||
- zdev: Fix memory leak in misc_readlink()
|
||||
- dasdinfo: Display error messages on stderr
|
||||
- zkey: Include /sbin into PATH when executing commands
|
||||
- Makefile: Fix parallel build
|
||||
- GCC8 warning fixes across the board for:
|
||||
cmsfs-fuse, dasdinfo, dasdview, dump2tar, fdasd, hmcdrvfs, hyptop,
|
||||
ip_watcher, libvmdump, libvtoc, lsqeth, lszcrypt, qethqoat, zdev, zdsfs,
|
||||
zgetdump, zipl, zpcictl
|
||||
|
||||
* __v2.7.0 (2018-10-31)__
|
||||
|
||||
For Linux kernel version: 4.19
|
||||
|
||||
@@ -165,7 +165,7 @@ cmsfs-fuse uses a configuration file for automatic translation based on the file
|
||||
Upon startup, cmsfs-fuse evaluates the file .cmsfs-fuse/filetypes.conf in the user's home directory. If the file does not
|
||||
exist cmsfs-fuse evaluates the file /etc/cmsfs-fuse/filetypes.conf.
|
||||
|
||||
The filetypes.conf file contains the CMS file types that are automaticaly translated to ASCII if cmsfs-fuse is started
|
||||
The filetypes.conf file contains the CMS file types that are automatically translated to ASCII if cmsfs-fuse is started
|
||||
with the -t option. The syntax of the configuration file is one file type per line. Lines that start with a # followed by a space are treated as
|
||||
comments and are ignored. The file type is 8 characters long and must consist of valid CMS file name characters only.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Main function
|
||||
*
|
||||
* Copyright IBM Corp. 2010, 2017
|
||||
* Copyright IBM Corp. 2010, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <fuse.h>
|
||||
#include <fuse_opt.h>
|
||||
#include <iconv.h>
|
||||
#include <limits.h>
|
||||
#include <linux/fs.h>
|
||||
#ifdef HAVE_SETXATTR
|
||||
#include <linux/xattr.h>
|
||||
@@ -36,6 +37,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_list.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
@@ -232,6 +234,8 @@ struct file {
|
||||
int null_records;
|
||||
/* write cache for text mode */
|
||||
char *wcache;
|
||||
/* buffer for iconv */
|
||||
char *iconv_buf;
|
||||
/* used bytes in write cache */
|
||||
int wcache_used;
|
||||
/* committed written bytes to FUSE */
|
||||
@@ -601,7 +605,7 @@ static struct file *file_open(const char *name)
|
||||
char uc_name[MAX_FNAME];
|
||||
struct file *f;
|
||||
|
||||
strncpy(uc_name, name, MAX_FNAME);
|
||||
util_strlcpy(uc_name, name, MAX_FNAME);
|
||||
str_toupper(uc_name);
|
||||
|
||||
util_list_iterate(&open_file_list, f)
|
||||
@@ -923,7 +927,6 @@ static void set_record(struct file *f, int *record, off_t addr, int len,
|
||||
static void add_record_ext(struct record *rec, struct record_ext *ext)
|
||||
{
|
||||
struct record_ext *tmp;
|
||||
int i = 0;
|
||||
|
||||
if (rec->ext == NULL) {
|
||||
rec->ext = ext;
|
||||
@@ -931,9 +934,7 @@ static void add_record_ext(struct record *rec, struct record_ext *ext)
|
||||
ext->next = NULL;
|
||||
} else {
|
||||
tmp = rec->ext;
|
||||
i++;
|
||||
while (tmp->next != NULL) {
|
||||
i++;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp->next = ext;
|
||||
@@ -1567,7 +1568,7 @@ static off_t lookup_file(const char *name, struct fst_entry *fst, int flag)
|
||||
off_t faddr = 0;
|
||||
int rc;
|
||||
|
||||
strncpy(uc_name, name, MAX_FNAME);
|
||||
util_strlcpy(uc_name, name, MAX_FNAME);
|
||||
str_toupper(uc_name);
|
||||
|
||||
if (flag == HIDE_UNLINKED && file_unlinked(uc_name))
|
||||
@@ -1851,7 +1852,26 @@ static int cmsfs_open(const char *path, struct fuse_file_info *fi)
|
||||
if (f->wcache == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
strncpy(f->path, path, MAX_FNAME + 1);
|
||||
/*
|
||||
* For fixed-length records f->fst->record_len contains
|
||||
* the fixed record length, which will not change. For
|
||||
* variable-length records it contains the (current) maximum
|
||||
* record length, which could be increased later by appending
|
||||
* new records, so use MAX_RECORD_LEN for the iconv buffer.
|
||||
* The MAX_RECORD_LEN is not valid for fixed-length records,
|
||||
* only for variable-length records, so use the actual record
|
||||
* length (f->fst->record_len) for fixed-length records.
|
||||
*/
|
||||
if (f->fst->record_format == RECORD_LEN_FIXED)
|
||||
f->iconv_buf = malloc(f->fst->record_len + 1);
|
||||
else
|
||||
f->iconv_buf = malloc(MAX_RECORD_LEN + 1);
|
||||
if (f->iconv_buf == NULL) {
|
||||
destroy_file_object(f);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
util_strlcpy(f->path, path, MAX_FNAME + 1);
|
||||
str_toupper(f->path);
|
||||
|
||||
f->use_count = 1;
|
||||
@@ -2108,7 +2128,7 @@ static int cmsfs_create(const char *path, mode_t mode,
|
||||
return rc;
|
||||
|
||||
/* force uppercase */
|
||||
strncpy(uc_name, path + 1, MAX_FNAME);
|
||||
util_strlcpy(uc_name, path + 1, MAX_FNAME);
|
||||
str_toupper(uc_name);
|
||||
|
||||
rc = encode_edf_name(uc_name, fname, ftype);
|
||||
@@ -2550,14 +2570,13 @@ static void get_block_data_from_record(struct record *rec, off_t offset,
|
||||
}
|
||||
}
|
||||
|
||||
static int convert_text(iconv_t conv, char *buf, int size)
|
||||
static int convert_text(iconv_t conv, char *in_buf, char *out_buf, int size)
|
||||
{
|
||||
size_t out_count = size;
|
||||
size_t in_count = size;
|
||||
char *data_ptr = buf;
|
||||
int rc;
|
||||
|
||||
rc = iconv(conv, &data_ptr, &in_count, &data_ptr, &out_count);
|
||||
rc = iconv(conv, &in_buf, &in_count, &out_buf, &out_count);
|
||||
if ((rc == -1) || (in_count != 0)) {
|
||||
DEBUG("Code page translation EBCDIC-ASCII failed\n");
|
||||
return -EIO;
|
||||
@@ -2618,14 +2637,15 @@ static int cmsfs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||
/* read one record */
|
||||
if (addr == NULL_BLOCK)
|
||||
memset(buf, 0, chunk);
|
||||
else {
|
||||
rc = _read(buf, chunk, addr);
|
||||
else if (f->translate) {
|
||||
rc = _read(f->iconv_buf, chunk, addr);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (f->translate) {
|
||||
rc = convert_text(cmsfs.iconv_from, buf, chunk);
|
||||
rc = convert_text(cmsfs.iconv_from, f->iconv_buf, buf, chunk);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
} else {
|
||||
rc = _read(buf, chunk, addr);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
@@ -2757,7 +2777,7 @@ static int delete_file(const char *path)
|
||||
fst_last = find_last_fdir_entry(cmsfs.fdir, cmsfs.dir_levels);
|
||||
|
||||
/* remove unlinked file from fcache */
|
||||
strncpy(file, path + 1, MAX_FNAME);
|
||||
util_strlcpy(file, path + 1, MAX_FNAME);
|
||||
str_toupper(file);
|
||||
invalidate_htab_entry(file);
|
||||
|
||||
@@ -2841,20 +2861,21 @@ static int cmsfs_rename(const char *path, const char *new_path)
|
||||
str_toupper(uc_new_name);
|
||||
|
||||
rc = encode_edf_name(uc_new_name, fname, ftype);
|
||||
free(uc_new_name);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memcpy(&fst.name[0], fname, 8);
|
||||
memcpy(&fst.type[0], ftype, 8);
|
||||
|
||||
strncpy(uc_old_name, path + 1, MAX_FNAME);
|
||||
util_strlcpy(uc_old_name, path + 1, MAX_FNAME);
|
||||
str_toupper(uc_old_name);
|
||||
invalidate_htab_entry(uc_old_name);
|
||||
|
||||
/* update name in file object if the file is opened */
|
||||
f = file_open(uc_old_name);
|
||||
if (f != NULL) {
|
||||
strncpy(f->path, new_path, MAX_FNAME + 1);
|
||||
util_strlcpy(f->path, new_path, MAX_FNAME + 1);
|
||||
str_toupper(f->path);
|
||||
memcpy(f->fst->name, fname, 8);
|
||||
memcpy(f->fst->type, ftype, 8);
|
||||
@@ -3743,7 +3764,7 @@ static int extend_block_variable(struct file *f, const char *buf, int len,
|
||||
}
|
||||
|
||||
DEBUG("%s: wrote %d record bytes\n", __func__, rlen);
|
||||
if (size <= 0)
|
||||
if (size == 0)
|
||||
return copied;
|
||||
}
|
||||
|
||||
@@ -4167,22 +4188,13 @@ static ssize_t find_newline(const char *buf, int len)
|
||||
return pos - buf;
|
||||
}
|
||||
|
||||
static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *fi)
|
||||
static int cmsfs_write_strings(struct file *f, const char *buf,
|
||||
size_t size, off_t offset)
|
||||
{
|
||||
int scan_len = MIN(size, (size_t)MAX_RECORD_LEN + 1);
|
||||
int rc, nl_byte = 1, null_record = 0, pad = 0;
|
||||
struct file *f = get_fobj(fi);
|
||||
ssize_t rsize;
|
||||
|
||||
(void) path;
|
||||
|
||||
if (cmsfs.readonly)
|
||||
return -EROFS;
|
||||
|
||||
if (!f->linefeed)
|
||||
return do_write(f, buf, size, offset);
|
||||
|
||||
/* remove already committed bytes */
|
||||
offset -= f->wcache_commited;
|
||||
|
||||
@@ -4222,7 +4234,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
}
|
||||
|
||||
/* translate */
|
||||
rc = convert_text(cmsfs.iconv_to, f->wcache, f->wcache_used);
|
||||
rc = convert_text(cmsfs.iconv_to, f->wcache, f->iconv_buf, f->wcache_used);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -4232,6 +4244,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
*/
|
||||
if (!f->wcache_used) {
|
||||
*f->wcache = FILLER_EBCDIC;
|
||||
*f->iconv_buf = FILLER_EBCDIC;
|
||||
f->wcache_used = 1;
|
||||
nl_byte = 0;
|
||||
null_record = 1;
|
||||
@@ -4242,7 +4255,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
offset += f->pad_bytes;
|
||||
BUG(offset < 0);
|
||||
|
||||
rc = do_write(f, f->wcache, f->wcache_used, offset);
|
||||
rc = do_write(f, f->iconv_buf, f->wcache_used, offset);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -4257,6 +4270,36 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cmsfs_write(const char *path, const char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *fi)
|
||||
{
|
||||
struct file *f = get_fobj(fi);
|
||||
int rc, written, nbytes;
|
||||
|
||||
(void) path;
|
||||
|
||||
if (cmsfs.readonly)
|
||||
return -EROFS;
|
||||
|
||||
if (!f->linefeed)
|
||||
return do_write(f, buf, size, offset);
|
||||
|
||||
/* Limit the size to what we can report back as written */
|
||||
nbytes = MIN(size, (size_t) INT_MAX);
|
||||
|
||||
written = 0;
|
||||
while (nbytes) {
|
||||
rc = cmsfs_write_strings(f, buf, nbytes, offset);
|
||||
if (rc < 0)
|
||||
return written ? written : rc;
|
||||
written += rc;
|
||||
offset += rc;
|
||||
buf += rc;
|
||||
nbytes -= rc;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
static int cmsfs_unlink(const char *path)
|
||||
{
|
||||
struct fst_entry fst;
|
||||
@@ -4284,7 +4327,7 @@ static int flush_wcache(struct file *f)
|
||||
int rc;
|
||||
|
||||
/* translate */
|
||||
rc = convert_text(cmsfs.iconv_to, f->wcache, f->wcache_used);
|
||||
rc = convert_text(cmsfs.iconv_to, f->wcache, f->iconv_buf, f->wcache_used);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -4292,7 +4335,7 @@ static int flush_wcache(struct file *f)
|
||||
offset -= (f->fst->nr_records - f->null_records);
|
||||
BUG(offset < 0);
|
||||
|
||||
rc = do_write(f, f->wcache, f->wcache_used, offset);
|
||||
rc = do_write(f, f->iconv_buf, f->wcache_used, offset);
|
||||
purge_wcache(f);
|
||||
f->null_records = 0;
|
||||
if (rc < 0)
|
||||
@@ -4415,6 +4458,7 @@ static void destroy_file_object(struct file *f)
|
||||
struct record *rec;
|
||||
int i;
|
||||
|
||||
free(f->iconv_buf);
|
||||
free(f->wcache);
|
||||
free(f->wstate);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "cmsfs-fuse.h"
|
||||
@@ -65,7 +66,7 @@ static void add_filetype(char *name, struct util_list *list)
|
||||
entry = malloc(sizeof(*entry));
|
||||
if (entry == NULL)
|
||||
DIE_PERROR("malloc failed");
|
||||
strncpy(entry->name, name, MAX_TYPE_LEN);
|
||||
util_strlcpy(entry->name, name, MAX_TYPE_LEN);
|
||||
util_list_add_head(list, entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
RELEASE = 8
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Config file parsing
|
||||
*
|
||||
* Copyright IBM Corp. 2007, 2017
|
||||
* Copyright IBM Corp. 2007, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -201,6 +201,7 @@ void parse_configfile(char *file)
|
||||
linebuffer);
|
||||
parse_configline(linebuffer);
|
||||
}
|
||||
fclose(filp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -34,7 +34,7 @@ Print DASD uid
|
||||
This option prints the full uid of the DASD. When z/VM provides two
|
||||
virtual devices that are actually located on the same real device, the
|
||||
first four tokens of the uid will be identical for both devices. z/VM
|
||||
may provide an additional token that allows to distinguish between
|
||||
may provide an additional token that can be used to distinguish between
|
||||
different minidisks. You need both support in the Linux kernel and
|
||||
z/VM to receive such an additional token.
|
||||
|
||||
@@ -45,7 +45,7 @@ available by applying the PTFs for VM APAR VM64273 on z/VM 5.2.0 and higher.
|
||||
.BI "-u|--uid"
|
||||
Print DASD uid without z/VM minidisk token
|
||||
|
||||
z/VM may provide an additional token that allows to distinguish
|
||||
z/VM may provide an additional token that can be used to distinguish
|
||||
between different minidisks (see --extended-uid option). To remain
|
||||
compatibile with systems that were installed on older Linux or z/VM
|
||||
levels, the -u option will print the uid excluding any z/VM-provided
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "lib/dasd_base.h"
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/zt_common.h"
|
||||
@@ -192,18 +193,18 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
|
||||
char *space;
|
||||
|
||||
if (dasd_get_blocksize(device, &blksize) != 0) {
|
||||
printf("Unable to figure out block size.\n");
|
||||
warnx("Unable to figure out block size");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dasd_get_info(device, &dasd_info) != 0) {
|
||||
printf("Unable to figure out DASD informations.\n");
|
||||
warnx("Unable to figure out DASD information");
|
||||
goto error;
|
||||
}
|
||||
|
||||
f = open(device, O_RDONLY);
|
||||
if (f < 0) {
|
||||
printf("Could not open device node.\n");
|
||||
warnx("Could not open device node");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -214,7 +215,7 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
|
||||
bzero(vlabel, vlsize);
|
||||
|
||||
if (read(f, vlabel, vlsize) != vlsize) {
|
||||
printf("Could not read volume label.\n");
|
||||
warnx("Could not read volume label");
|
||||
goto error_close;
|
||||
}
|
||||
|
||||
@@ -255,10 +256,9 @@ static void *dinfo_malloc(size_t size)
|
||||
void *result;
|
||||
|
||||
result = malloc(size);
|
||||
if (result == NULL) {
|
||||
printf("Could not allocate %lld bytes of memory",
|
||||
(unsigned long long)size);
|
||||
}
|
||||
if (result == NULL)
|
||||
warnx("Could not allocate %lu bytes of memory", size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -318,16 +318,14 @@ static int dinfo_create_devnode(dev_t dev, char **devno)
|
||||
free(result);
|
||||
}
|
||||
}
|
||||
printf("Error: Unable to create temporary device node");
|
||||
warnx("Error: Unable to create temporary device node");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void dinfo_free_devnode(char *device)
|
||||
{
|
||||
if (remove(device)) {
|
||||
printf("Warning: Could not remove "
|
||||
"temporary file %s", device);
|
||||
}
|
||||
if (remove(device))
|
||||
warnx("Warning: Could not remove temporary file %s", device);
|
||||
}
|
||||
|
||||
static int dinfo_extract_dev(dev_t *dev, char *str)
|
||||
@@ -337,10 +335,10 @@ static int dinfo_extract_dev(dev_t *dev, char *str)
|
||||
int ma, mi;
|
||||
|
||||
bzero(tmp, RD_BUFFER_SIZE);
|
||||
strncpy(tmp, str, RD_BUFFER_SIZE);
|
||||
util_strlcpy(tmp, str, RD_BUFFER_SIZE);
|
||||
p = strchr(tmp, ':');
|
||||
if (p == NULL) {
|
||||
printf("Error: unable to extract major/minor\n");
|
||||
warnx("Error: unable to extract major/minor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -359,7 +357,7 @@ static int dinfo_get_dev_from_blockdev(char *blockdev, dev_t *dev)
|
||||
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!readbuf) {
|
||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
||||
warnx("Error: Not enough memory to allocate readbuffer");
|
||||
return -1;
|
||||
}
|
||||
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
|
||||
@@ -490,7 +488,7 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
int rc = 0;
|
||||
|
||||
if (stat(devnode, &stat_buffer) != 0) {
|
||||
printf("Error: could not stat %s\n", devnode);
|
||||
warnx("Error: could not stat %s", devnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -499,13 +497,13 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
|
||||
directory = opendir("/sys/block/");
|
||||
if (directory == NULL) {
|
||||
printf("Error: could not open directory /sys/block\n");
|
||||
warnx("Error: could not open directory /sys/block");
|
||||
return -1;
|
||||
}
|
||||
|
||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||
if (!readbuf) {
|
||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
||||
warnx("Error: Not enough memory to allocate readbuffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -607,25 +605,23 @@ int main(int argc, char *argv[])
|
||||
sscanf(uname_buf.release, "%d.%d", &version, &release);
|
||||
if (strcmp(uname_buf.sysname, "Linux") ||
|
||||
version < 2 || (version == 2 && release < 6)) {
|
||||
printf("%s %d.%d is not supported\n", uname_buf.sysname,
|
||||
version, release);
|
||||
warnx("%s %d.%d is not supported", uname_buf.sysname,
|
||||
version, release);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!busid && !blockdev && !devnode) {
|
||||
printf("Error: please specify a device using either -b, -i "
|
||||
"or -d\n");
|
||||
warnx("Error: please specify a device using either -b, -i or -d");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((busid && blockdev) || (busid && devnode) || (blockdev && devnode)) {
|
||||
printf("Error: please specify device only once, either -b, -i "
|
||||
"or -d\n");
|
||||
warnx("Error: please specify device only once, either -b, -i or -d");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!print_uid && !print_extended_uid && !print_vlabel) {
|
||||
printf("Error: no action specified (e.g. -u)\n");
|
||||
warnx("Error: no action specified (e.g. -u)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -718,7 +714,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
error:
|
||||
printf("Error: could not read unique DASD ID\n");
|
||||
warnx("Error: could not read unique DASD ID");
|
||||
rc = 1;
|
||||
|
||||
out:
|
||||
|
||||
@@ -618,7 +618,7 @@ dasdview_print_volser(dasdview_info_t *info)
|
||||
strncpy(volser, vlabel.volid, 6);
|
||||
vtoc_ebcdic_dec(volser, volser, 6);
|
||||
} else {
|
||||
strncpy(volser, " ", 6);
|
||||
memcpy(volser, " ", 6);
|
||||
}
|
||||
|
||||
printf("%6.6s\n", volser);
|
||||
@@ -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",
|
||||
|
||||
@@ -78,7 +78,7 @@ static void set_time(char *dest, size_t len, time_t value)
|
||||
#define SET_TIME_FIELD(obj, name, value) \
|
||||
set_time((obj)->name, sizeof((obj)->name), (time_t) (value))
|
||||
#define SET_STR_FIELD(obj, name, value) \
|
||||
strncpy((obj)->name, (value), sizeof((obj)->name))
|
||||
util_strlcpy((obj)->name, (value), sizeof((obj)->name))
|
||||
|
||||
/* Initialize the tar file @header with the provided data */
|
||||
static void init_header(struct tar_header *header, const char *filename,
|
||||
|
||||
@@ -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
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* fdasd - Create or modify partitions on ECKD DASDs
|
||||
*
|
||||
* Copyright IBM Corp. 2001, 2017
|
||||
* Copyright IBM Corp. 2001, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -258,7 +258,7 @@ static void fdasd_check_volser(char *volser, int devno)
|
||||
{
|
||||
int from, to;
|
||||
|
||||
for (from = 0, to = 0; volser[from] && from < VOLSER_LENGTH; from++)
|
||||
for (from = 0, to = 0; from < VOLSER_LENGTH && volser[from]; from++)
|
||||
if ((volser[from] >= 0x23 &&
|
||||
volser[from] <= 0x25) || /* # $ % */
|
||||
(volser[from] >= 0x30 &&
|
||||
@@ -727,9 +727,9 @@ static int fdasd_parse_conffile(fdasd_anchor_t *anc,
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
rc = read(fd, buffer, sizeof(buffer) - 1);
|
||||
close(fd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
close(fd);
|
||||
|
||||
for (i = 0; i < rc; i++)
|
||||
buffer[i] = toupper(buffer[i]);
|
||||
@@ -1257,7 +1257,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
|
||||
printf("DSCBs: ");
|
||||
|
||||
blk = (cchhb2blk(&anc->vlabel->vtoc, &geo) - 1) * anc->blksize;
|
||||
if (blk <= 0)
|
||||
if (cchhb2blk(&anc->vlabel->vtoc, &geo) == 0 || blk == 0)
|
||||
fdasd_error(anc, vlabel_corrupted, "");
|
||||
maxblk = blk + anc->blksize * 9; /* f4+f5+f7+3*f8+3*f9 */
|
||||
|
||||
@@ -1310,7 +1310,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
|
||||
volser[VOLSER_LENGTH] = ' ';
|
||||
strncpy(c1, volser, VOLSER_LENGTH + 1);
|
||||
c1 = strchr(ch, ' ');
|
||||
strncpy(c1, s2, 31);
|
||||
memcpy(c1, s2, 31);
|
||||
} else {
|
||||
if (get_part_type_by_dsname(ch, &part_info->type))
|
||||
part_info->type = PARTITION_NATIVE;
|
||||
@@ -1321,23 +1321,23 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
|
||||
|
||||
setpos(anc, k, i - 1);
|
||||
|
||||
strncpy(ch, "LINUX.V "
|
||||
memcpy(ch, "LINUX.V "
|
||||
" ", 44);
|
||||
|
||||
strncpy(volser, anc->vlabel->volid, VOLSER_LENGTH);
|
||||
vtoc_ebcdic_dec(volser, volser, VOLSER_LENGTH);
|
||||
strncpy(c1, volser, VOLSER_LENGTH);
|
||||
memcpy(c1, volser, VOLSER_LENGTH);
|
||||
|
||||
c1 = strchr(ch, ' ');
|
||||
strncpy(c1, ".PART", 5);
|
||||
memcpy(c1, ".PART", 5);
|
||||
c1 += 5;
|
||||
|
||||
sprintf(dsno, "%04d.", k + 1);
|
||||
strncpy(c1, dsno, 5);
|
||||
memcpy(c1, dsno, 5);
|
||||
c1 += 5;
|
||||
|
||||
get_part_dsname_by_type(part_info->type, &dsname);
|
||||
strncpy(c1, dsname, strlen(dsname)); /* We don't want \0 */
|
||||
memcpy(c1, dsname, strlen(dsname)); /* We don't want \0 */
|
||||
}
|
||||
vtoc_ebcdic_enc(ch, ch, 44);
|
||||
if (anc->verbose)
|
||||
@@ -1636,7 +1636,7 @@ static void fdasd_change_part_type(fdasd_anchor_t *anc)
|
||||
|
||||
ch = strstr(part_info->f1->DS1DSNAM, "PART") + 9;
|
||||
if (ch != NULL)
|
||||
strncpy(ch, str, 6);
|
||||
memcpy(ch, str, 6);
|
||||
vtoc_ebcdic_enc(part_info->f1->DS1DSNAM, part_info->f1->DS1DSNAM, 44);
|
||||
anc->vtoc_changed++;
|
||||
}
|
||||
@@ -1994,7 +1994,7 @@ static int fdasd_check_volume(fdasd_anchor_t *anc)
|
||||
printf(" VOL1\n");
|
||||
|
||||
blk = (cchhb2blk(&vlabel->vtoc, &geo) - 1) * anc->blksize;
|
||||
if (blk > 0) {
|
||||
if (cchhb2blk(&vlabel->vtoc, &geo) > 0 && blk > 0) {
|
||||
rc = fdasd_valid_vtoc_pointer(anc, blk);
|
||||
|
||||
if (anc->print_table && (rc < 0))
|
||||
|
||||
@@ -31,12 +31,13 @@ LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
|
||||
|
||||
OBJECTS = hmcdrvfs.o
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
all: check_dep hmcdrvfs
|
||||
|
||||
$(OBJECTS): Makefile
|
||||
|
||||
hmcdrvfs: $(OBJECTS)
|
||||
hmcdrvfs: $(OBJECTS) $(libs)
|
||||
|
||||
install: all install-scripts
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 hmcdrvfs \
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define HMCDRV_FUSE_LOGNAME "hmcdrvfs" /* log prefix */
|
||||
@@ -276,7 +277,7 @@ static void hmcdrv_cache_symlink(struct hmcdrv_fuse_file *fp,
|
||||
fp->symlnk = malloc(HMCDRV_FUSE_MAXPATH);
|
||||
|
||||
if (fp->symlnk != NULL) {
|
||||
strncpy(fp->symlnk, symlink, HMCDRV_FUSE_MAXPATH);
|
||||
util_strlcpy(fp->symlnk, symlink, HMCDRV_FUSE_MAXPATH);
|
||||
fp->symlnk[HMCDRV_FUSE_MAXPATH - 1] = '\0';
|
||||
}
|
||||
}
|
||||
@@ -483,8 +484,7 @@ static ssize_t hmcdrv_ftp_transfer(struct hmcdrv_fuse_file *fp, char *buf,
|
||||
}
|
||||
|
||||
current_offset += retlen;
|
||||
strncpy(last_ftpcmd, fp->ftpcmd, HMCDRV_FUSE_MAXCMDLEN);
|
||||
last_ftpcmd[HMCDRV_FUSE_MAXCMDLEN - 1] = '\0';
|
||||
util_strlcpy(last_ftpcmd, fp->ftpcmd, HMCDRV_FUSE_MAXCMDLEN);
|
||||
return retlen;
|
||||
}
|
||||
|
||||
@@ -853,13 +853,12 @@ static char *hmcdrv_parse_line(char *line, char *namebuf,
|
||||
*arrow = '\0';
|
||||
}
|
||||
|
||||
strncpy(namebuf, attr.fname, bufsize);
|
||||
namebuf[bufsize - 1] = '\0'; /* safety */
|
||||
util_strlcpy(namebuf, attr.fname, bufsize);
|
||||
|
||||
if (arrow == NULL) {
|
||||
symlink[0] = '\0';
|
||||
} else {
|
||||
strncpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
|
||||
util_strlcpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
|
||||
*arrow = ' '; /* restore */
|
||||
}
|
||||
|
||||
@@ -1148,8 +1147,7 @@ static int hmcdrv_fuse_readlink(const char *path, char *buf, size_t size)
|
||||
if (!S_ISLNK(fp->st.st_mode)) {
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
strncpy(buf, fp->symlnk, size);
|
||||
buf[size - 1] = '\0';
|
||||
util_strlcpy(buf, fp->symlnk, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ struct l_x_sys_hdr {
|
||||
|
||||
static inline void l_sys_hdr__sys_name(struct l_x_sys_hdr *hdr, char *name)
|
||||
{
|
||||
memcpy(name, hdr->sys_name, LPAR_NAME_LEN);
|
||||
ht_ebcdic_to_ascii(name, LPAR_NAME_LEN);
|
||||
ht_ebcdic_to_ascii(hdr->sys_name, name, LPAR_NAME_LEN);
|
||||
name[LPAR_NAME_LEN] = 0;
|
||||
ht_strstrip(name);
|
||||
}
|
||||
@@ -176,7 +175,6 @@ static void l_sd_cpu_phys_fill(struct sd_sys *sys,
|
||||
sd_cpu_state_set(cpu, SD_CPU_STATE_UNKNOWN);
|
||||
}
|
||||
sd_cpu_mgm_time_us_set(cpu, cpu_info->mgm_time);
|
||||
sd_cpu_real_type_set(cpu, cpu_type);
|
||||
sd_cpu_commit(cpu);
|
||||
}
|
||||
|
||||
|
||||
@@ -245,8 +245,7 @@ static void l_sd_sys_root_fill(struct sd_sys *sys)
|
||||
struct sd_sys *guest;
|
||||
|
||||
guest_name[NAME_LEN] = 0;
|
||||
memcpy(guest_name, data->guest_name, NAME_LEN);
|
||||
ht_ebcdic_to_ascii(guest_name, NAME_LEN);
|
||||
ht_ebcdic_to_ascii(data->guest_name, guest_name, NAME_LEN);
|
||||
ht_strstrip(guest_name);
|
||||
|
||||
guest = sd_sys_get(sys, guest_name);
|
||||
|
||||
@@ -98,9 +98,15 @@ void *ht_realloc(void *old_ptr, size_t size)
|
||||
/*
|
||||
* Convert EBCDIC string to ASCII
|
||||
*/
|
||||
void ht_ebcdic_to_ascii(char *inout, size_t len)
|
||||
void ht_ebcdic_to_ascii(char *in, char *out, size_t size)
|
||||
{
|
||||
iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
|
||||
size_t size_out = size;
|
||||
size_t size_in = size;
|
||||
size_t rc;
|
||||
|
||||
rc = iconv(l_iconv_ebcdic_ascii, &in, &size_in, &out, &size_out);
|
||||
if (rc == (size_t) -1)
|
||||
ERR_EXIT_ERRNO("Code page translation EBCDIC-ASCII failed");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define G0(x) MAX(0, (s64) (x))
|
||||
@@ -29,7 +30,7 @@ extern char *ht_strstrip(char *str);
|
||||
extern char *ht_strdup(const char *str);
|
||||
extern void ht_print_head(const char *sys);
|
||||
extern void ht_print_help_icon(void);
|
||||
extern void ht_ebcdic_to_ascii(char *inout, size_t len);
|
||||
extern void ht_ebcdic_to_ascii(char *in, char *out, size_t len);
|
||||
extern char *ht_mount_point_get(const char *fs_type);
|
||||
extern u64 ht_ext_tod_2_us(void *tod_ext);
|
||||
extern void ht_print_time(void);
|
||||
|
||||
@@ -195,7 +195,6 @@ struct sd_cpu {
|
||||
struct sd_info i;
|
||||
char id[9];
|
||||
struct sd_cpu_type *type;
|
||||
char real_type[CPU_TYPE_ID_LEN];
|
||||
struct sd_cpu_info d1;
|
||||
struct sd_cpu_info d2;
|
||||
struct sd_cpu_info *d_cur;
|
||||
@@ -228,11 +227,6 @@ static inline void sd_cpu_state_set(struct sd_cpu *cpu, enum sd_cpu_state state)
|
||||
cpu->state = state;
|
||||
}
|
||||
|
||||
static inline void sd_cpu_real_type_set(struct sd_cpu *cpu, const char *type)
|
||||
{
|
||||
strncpy(cpu->real_type, type, sizeof(cpu->real_type));
|
||||
}
|
||||
|
||||
static inline void sd_cpu_cpu_time_us_set(struct sd_cpu *cpu, u64 value)
|
||||
{
|
||||
cpu->d_cur->cpu_time_us = value;
|
||||
|
||||
@@ -219,7 +219,7 @@ struct sd_cpu *sd_cpu_new(struct sd_sys *parent, const char *id,
|
||||
|
||||
cpu = ht_zalloc(sizeof(*cpu));
|
||||
cpu->i.parent = parent;
|
||||
strncpy(cpu->id, id, sizeof(cpu->id));
|
||||
util_strlcpy(cpu->id, id, sizeof(cpu->id));
|
||||
cpu->type = l_cpu_type_by_id(type);
|
||||
cpu->d_cur = &cpu->d1;
|
||||
cpu->cnt = cnt;
|
||||
@@ -251,7 +251,7 @@ struct sd_sys *sd_sys_new(struct sd_sys *parent, const char *id)
|
||||
struct sd_sys *sys_new;
|
||||
|
||||
sys_new = ht_zalloc(sizeof(*sys_new));
|
||||
strncpy(sys_new->id, id, sizeof(sys_new->id));
|
||||
util_strlcpy(sys_new->id, id, sizeof(sys_new->id));
|
||||
util_list_init(&sys_new->child_list, struct sd_sys, list);
|
||||
util_list_init(&sys_new->cpu_list, struct sd_cpu, list);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ static void l_mark_key_add(struct table *t, char *str)
|
||||
struct table_mark_key *key;
|
||||
|
||||
key = ht_zalloc(sizeof(*key));
|
||||
strncpy(key->str, str, sizeof(key->str));
|
||||
util_strlcpy(key->str, str, sizeof(key->str));
|
||||
util_list_add_tail(&t->mark_key_list, key);
|
||||
}
|
||||
|
||||
@@ -617,7 +617,7 @@ void table_row_select_key_get(struct table *t, char str[TABLE_STR_MAX])
|
||||
struct table_row *row;
|
||||
|
||||
row = l_selected_row(t);
|
||||
strncpy(str, row->entries[0].str, TABLE_STR_MAX);
|
||||
util_strlcpy(str, row->entries[0].str, TABLE_STR_MAX);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -157,7 +157,7 @@ static void l_print_line(const char *line)
|
||||
char line_cpy[TBOX_MAX_STR + 1];
|
||||
char *ptr_old, *ptr;
|
||||
|
||||
strncpy(line_cpy, line, sizeof(line_cpy));
|
||||
util_strlcpy(line_cpy, line, sizeof(line_cpy));
|
||||
ptr_old = ptr = line_cpy;
|
||||
do {
|
||||
ptr = strchr(ptr, '\\');
|
||||
|
||||
@@ -326,7 +326,7 @@ void win_sys_set(const char *sys_id)
|
||||
{
|
||||
if (l_initialized)
|
||||
table_reset(l_t);
|
||||
strncpy(l_sys_id, sys_id, sizeof(l_sys_id));
|
||||
util_strlcpy(l_sys_id, sys_id, sizeof(l_sys_id));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ char *util_strcat_realloc(char *str1, const char *str2);
|
||||
void util_str_toupper(char *str);
|
||||
|
||||
char *util_strstrip(char *s);
|
||||
size_t util_strlcpy(char *dest, const char *src, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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 @} */
|
||||
|
||||
@@ -2,7 +2,9 @@ include ../common.mak
|
||||
|
||||
all: xcec-bridge
|
||||
|
||||
xcec-bridge: xcec-bridge.o
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
xcec-bridge: xcec-bridge.o $(libs)
|
||||
|
||||
clean:
|
||||
rm -f *.o core xcec-bridge
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
/* a signal causes the interfaces to be re-checked */
|
||||
@@ -40,7 +41,7 @@
|
||||
|
||||
#define UPDATE_SIGNAL SIGUSR1
|
||||
|
||||
#define DEV_NAME_LEN IFNAMSIZ
|
||||
#define DEV_NAME_SIZE IFNAMSIZ
|
||||
|
||||
#define BUFFER_LEN 65536
|
||||
|
||||
@@ -55,7 +56,7 @@ struct int_sock {
|
||||
int features;
|
||||
int i_fd;
|
||||
int o_fd;
|
||||
char dev_name[DEV_NAME_LEN];
|
||||
char dev_name[DEV_NAME_SIZE];
|
||||
int mtu_warning;
|
||||
|
||||
struct int_sock *next;
|
||||
@@ -91,7 +92,7 @@ int open_incoming_socket(char *dev_name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(if_req.ifr_name,dev_name,DEV_NAME_LEN);
|
||||
util_strlcpy(if_req.ifr_name, dev_name, DEV_NAME_SIZE);
|
||||
retval=ioctl(fd,SIOCGIFINDEX,&if_req);
|
||||
if (retval==-1) {
|
||||
syslog(LOG_ERR,"can't ioctl on raw packet socket, " \
|
||||
@@ -192,7 +193,7 @@ int open_outgoing_socket(char *dev_name)
|
||||
int interface_in_list(struct int_sock *item,struct int_sock *list)
|
||||
{
|
||||
for (;list;list=list->next) {
|
||||
if (!strncmp(item->dev_name,list->dev_name,DEV_NAME_LEN)) {
|
||||
if (!strncmp(item->dev_name,list->dev_name,DEV_NAME_SIZE)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -281,7 +282,7 @@ int read_sys(struct int_sock **nlist)
|
||||
do_broadcast_bridging=0;
|
||||
|
||||
is->mtu_warning=0;
|
||||
strncpy(is->dev_name, if_name, DEV_NAME_LEN);
|
||||
util_strlcpy(is->dev_name, if_name, DEV_NAME_SIZE);
|
||||
if (!strncmp(if_name,"hsi",3)) {
|
||||
is->features=I_S_FEATURE_PASSTHROUGH;
|
||||
}
|
||||
@@ -317,7 +318,7 @@ void update_interfaces()
|
||||
prev=NULL;
|
||||
while (j) {
|
||||
if (!strncmp(j->dev_name,i->dev_name,
|
||||
DEV_NAME_LEN)) {
|
||||
DEV_NAME_SIZE)) {
|
||||
if (!prev) {
|
||||
select_set.i_s_list=j->next;
|
||||
} else {
|
||||
@@ -360,7 +361,7 @@ void update_interfaces()
|
||||
continue;
|
||||
}
|
||||
|
||||
strncpy(new_int->dev_name,i->dev_name,DEV_NAME_LEN);
|
||||
util_strlcpy(new_int->dev_name, i->dev_name, DEV_NAME_SIZE);
|
||||
new_int->i_fd=i_fd;
|
||||
new_int->o_fd=o_fd;
|
||||
new_int->features=i->features;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
include ../common.mak
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
all: chreipl lsreipl chshut lsshut
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
objects = main.o ccw.o fcp.o system.o shutdown.o \
|
||||
cmd_lsshut.o cmd_chshut.o cmd_lsreipl.o cmd_chreipl.o proc.o
|
||||
|
||||
chreipl: $(objects)
|
||||
chreipl: $(objects) $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
lsreipl:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <ctype.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "ipl_tools.h"
|
||||
@@ -182,7 +183,7 @@ static void set_bootprog(const char *bootprog)
|
||||
ERR_EXIT("Bootprog \"%s\" is not a decimal number", bootprog);
|
||||
if (bootprog_int > UINT_MAX)
|
||||
ERR_EXIT("Invalid bootprog specified");
|
||||
strncpy(l.bootprog, bootprog, sizeof(l.bootprog));
|
||||
util_strlcpy(l.bootprog, bootprog, sizeof(l.bootprog));
|
||||
l.bootprog_set = 1;
|
||||
}
|
||||
|
||||
@@ -294,7 +295,7 @@ static int set_reipl_type(const char *dev_name)
|
||||
else
|
||||
return -1;
|
||||
|
||||
strncpy(l.dev, dev_name, sizeof(l.dev));
|
||||
util_strlcpy(l.dev, dev_name, sizeof(l.dev));
|
||||
dev_from_part(l.dev);
|
||||
l.dev_set = 1;
|
||||
return 0;
|
||||
@@ -302,19 +303,21 @@ static int set_reipl_type(const char *dev_name)
|
||||
|
||||
static int get_chreipl_helper_cmd(dev_t dev, char cmd[PATH_MAX])
|
||||
{
|
||||
char chreipl_helper[PATH_MAX];
|
||||
char *chreipl_helper;
|
||||
struct proc_dev_entry pde;
|
||||
|
||||
if (proc_dev_get_entry(dev, 1, &pde) != 0)
|
||||
return -1;
|
||||
snprintf(chreipl_helper, PATH_MAX,
|
||||
"%s/%s.%s", TOOLS_LIBDIR, "chreipl_helper", pde.name);
|
||||
util_asprintf(&chreipl_helper,
|
||||
"%s/%s.%s", TOOLS_LIBDIR, "chreipl_helper", pde.name);
|
||||
if (access(chreipl_helper, X_OK) != 0) {
|
||||
proc_dev_free_entry(&pde);
|
||||
free(chreipl_helper);
|
||||
return -1;
|
||||
}
|
||||
sprintf(cmd, "%s %d:%d", chreipl_helper, major(dev), minor(dev));
|
||||
proc_dev_free_entry(&pde);
|
||||
free(chreipl_helper);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "ipl_tools.h"
|
||||
|
||||
/*
|
||||
@@ -30,7 +31,7 @@ int fcp_is_device(const char *devno)
|
||||
*/
|
||||
void fcp_wwpn_get(const char *device, char *wwpn)
|
||||
{
|
||||
char path[PATH_MAX], buf[4096];
|
||||
char path[PATH_MAX], buf[20];
|
||||
FILE *fh;
|
||||
int rc;
|
||||
|
||||
@@ -41,7 +42,7 @@ void fcp_wwpn_get(const char *device, char *wwpn)
|
||||
rc = fscanf(fh, "%s", buf);
|
||||
if (rc <= 0)
|
||||
ERR_EXIT("Could not lookup WWPN \"%s\"", path);
|
||||
strncpy(wwpn, buf, 20);
|
||||
util_strlcpy(wwpn, buf, 20);
|
||||
fclose(fh);
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ void fcp_wwpn_get(const char *device, char *wwpn)
|
||||
*/
|
||||
void fcp_lun_get(const char *device, char *lun)
|
||||
{
|
||||
char path[PATH_MAX], buf[4096];
|
||||
char path[PATH_MAX], buf[20];
|
||||
FILE *fh;
|
||||
int rc;
|
||||
|
||||
@@ -62,7 +63,7 @@ void fcp_lun_get(const char *device, char *lun)
|
||||
rc = fscanf(fh, "%s", buf);
|
||||
if (rc <= 0)
|
||||
ERR_EXIT("Could not lookup LUN \"%s\"", path);
|
||||
strncpy(lun, buf, 20);
|
||||
util_strlcpy(lun, buf, 20);
|
||||
fclose(fh);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "ipl_tools.h"
|
||||
|
||||
struct globals g;
|
||||
@@ -31,7 +33,7 @@ void __noreturn print_version_exit(void)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
strncpy(g.prog_name, argv[0], sizeof(g.prog_name));
|
||||
util_strlcpy(g.prog_name, argv[0], sizeof(g.prog_name));
|
||||
if (strstr(argv[0], "chreipl") != NULL) {
|
||||
cmd_chreipl(argc, argv);
|
||||
return 0;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "ipl_tools.h"
|
||||
|
||||
/*
|
||||
@@ -81,10 +82,11 @@ void read_str(char *string, const char *path, size_t len)
|
||||
*/
|
||||
void read_fw_str(char *string, const char *file, size_t len)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char *path;
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/firmware/%s", file);
|
||||
return read_str(string, path, len);
|
||||
util_asprintf(&path, "/sys/firmware/%s", file);
|
||||
read_str(string, path, len);
|
||||
free(path);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,7 +6,7 @@ all: $(lib)
|
||||
|
||||
objects = dasd_sys.o dasd_ioctl.o
|
||||
|
||||
$(lib): $(objects) Makefile
|
||||
$(lib): $(objects)
|
||||
|
||||
install: all
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ lib = libu2s.a
|
||||
|
||||
all: $(lib)
|
||||
|
||||
objects = u2s.o misc.o
|
||||
objects = u2s.o
|
||||
|
||||
$(lib): $(objects)
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Misc - Local helper functions
|
||||
*
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include "lib/util_base.h"
|
||||
|
||||
/*
|
||||
* Helper function that copies a string safely
|
||||
*/
|
||||
size_t misc_strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t str_len = strlen(src);
|
||||
size_t len;
|
||||
|
||||
if (size) {
|
||||
len = MIN(size - 1, str_len);
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
return str_len;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Misc - Local helper functions
|
||||
*
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
*
|
||||
* 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 MISC_H
|
||||
#define MISC_H
|
||||
|
||||
size_t misc_strlcpy(char *, const char *, size_t);
|
||||
|
||||
#endif /* MISC_H */
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <wait.h>
|
||||
|
||||
#include "lib/u2s.h"
|
||||
#include "misc.h"
|
||||
#include "lib/util_libc.h"
|
||||
|
||||
#define DEV_BUFFER_LENGTH 20
|
||||
#define PATH_BUFFER_LENGTH 256
|
||||
@@ -113,7 +113,7 @@ static int extract_busid(char *name, char *busid) {
|
||||
if (!start)
|
||||
return -1;
|
||||
start++;
|
||||
len = misc_strlcpy(busid, start, BUSIDSIZE);
|
||||
len = util_strlcpy(busid, start, BUSIDSIZE);
|
||||
if (len >= BUSIDSIZE)
|
||||
return -1;
|
||||
|
||||
@@ -246,7 +246,7 @@ static int find_busid_in_proc(int maja, int mina, char *busid)
|
||||
while (fscanf(filp, "%[^(] %*[^)] ) at ( %d : %d %*[^\n]\n",
|
||||
bus, &majb, &minb) != EOF) {
|
||||
if ((maja == majb) && (mina == minb)) {
|
||||
len = misc_strlcpy(busid, bus, BUSIDSIZE);
|
||||
len = util_strlcpy(busid, bus, BUSIDSIZE);
|
||||
if (len < BUSIDSIZE)
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
@@ -13,7 +13,8 @@ examples = util_base_example \
|
||||
util_prg_example \
|
||||
util_rec_example
|
||||
|
||||
all: $(lib) $(examples)
|
||||
all: $(lib)
|
||||
examples: $(lib) $(examples)
|
||||
|
||||
objects = util_base.o \
|
||||
util_path.o \
|
||||
|
||||
@@ -228,3 +228,30 @@ char *util_strstrip(char *s)
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy \a src to buffer \a dest of size \a size. At most size - 1
|
||||
* chars will be copied. \a dest will always be NUL terminated.
|
||||
*
|
||||
* Note: If the return value is greater than or equal to size truncation
|
||||
* occurred.
|
||||
*
|
||||
* @param[in] dest Destination buffer
|
||||
* @param[in] src Source string
|
||||
* @param[in] size Size of destination buffer
|
||||
*
|
||||
* @returns strlen Length of \a src string
|
||||
*/
|
||||
size_t util_strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t str_len = strlen(src);
|
||||
size_t len;
|
||||
|
||||
if (size) {
|
||||
len = MIN(size - 1, str_len);
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
|
||||
return str_len;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -4,7 +4,8 @@ lib = libvmcp.a
|
||||
|
||||
examples = vmcp_example
|
||||
|
||||
all: $(lib) $(examples)
|
||||
all: $(lib)
|
||||
examples: $(lib) $(examples)
|
||||
|
||||
objects = vmcp.o
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
const char *what(void) const { return msg; }
|
||||
int code(void) const { return errorCode; }
|
||||
protected:
|
||||
char msg[200];
|
||||
char msg[2048];
|
||||
int errorCode;
|
||||
};
|
||||
|
||||
|
||||
@@ -98,19 +98,20 @@ VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
|
||||
dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
|
||||
|
||||
if(debug) {
|
||||
char buf_asc[1024];
|
||||
char buf[1024];
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "off=%d\n", adsrRecord.sec5_offset);
|
||||
dump_seek(fh, adsrRecord.sec5_offset, SEEK_SET);
|
||||
dump_read(buf, adsrRecord.sec5_len, 1, fh);
|
||||
ebcAsc(buf, adsrRecord.sec5_len);
|
||||
ebcAsc(buf, buf_asc, adsrRecord.sec5_len);
|
||||
for (i=0; i < adsrRecord.sec5_len; i++) {
|
||||
if ((buf[i]==0) || iscntrl(buf[i]))
|
||||
buf[i]=' ';
|
||||
if ((buf_asc[i]==0) || iscntrl(buf_asc[i]))
|
||||
buf_asc[i]=' ';
|
||||
}
|
||||
buf[adsrRecord.sec5_len] = 0;
|
||||
printf("symptom string1: %s\n",buf);
|
||||
buf_asc[adsrRecord.sec5_len] = 0;
|
||||
printf("symptom string1: %s\n",buf_asc);
|
||||
}
|
||||
|
||||
/* Record 2: fmbk */
|
||||
@@ -142,7 +143,8 @@ struct timeval VMDump::getDumpTime(void) const
|
||||
void VMDump::printDebug(void)
|
||||
{
|
||||
struct timeval time;
|
||||
char buf[1024];
|
||||
char fmbk_id[8];
|
||||
char albk_id[8];
|
||||
|
||||
s390TodToTimeval(adsrRecord.tod, &time);
|
||||
|
||||
@@ -165,9 +167,9 @@ void VMDump::printDebug(void)
|
||||
|
||||
/* fmbk */
|
||||
|
||||
ebcAsc(fmbkRecord.id, sizeof(fmbkRecord.id));
|
||||
fmbkRecord.id[7] = 0;
|
||||
printf("id : %s\n", fmbkRecord.id);
|
||||
ebcAsc(fmbkRecord.id, fmbk_id, sizeof(fmbkRecord.id));
|
||||
fmbk_id[7] = 0;
|
||||
printf("id : %s\n", fmbk_id);
|
||||
printf("fir rec nr: %i\n", fmbkRecord.rec_nr_fir);
|
||||
printf("vec rec nr: %i\n", fmbkRecord.rec_nr_vector);
|
||||
printf("access rec nr: %i\n", fmbkRecord.rec_nr_access);
|
||||
@@ -175,21 +177,9 @@ void VMDump::printDebug(void)
|
||||
|
||||
/* albk */
|
||||
|
||||
memcpy(buf, albkRecord.id, sizeof(albkRecord.id));
|
||||
ebcAsc(buf, sizeof(albkRecord.id));
|
||||
buf[8]=0;
|
||||
printf("ALBK id : %s\n",buf);
|
||||
|
||||
/* asibk */
|
||||
/*
|
||||
XXX
|
||||
memcpy(buf,asibkRecord.id,sizeof(asibkRecord.id));
|
||||
ebcAsc(buf,sizeof(asibkRecord.id));
|
||||
asibkRecord.id[8]=0;
|
||||
printf("ASIBK id : %s\n",buf);
|
||||
printf("storage : %x\n",asibkRecord.storage_size_2GB);
|
||||
printf("bitmapsrecs : %i\n",asibkRecord.nr_of_recs_of_first_bit_map);
|
||||
*/
|
||||
ebcAsc(albkRecord.id, albk_id, sizeof(albkRecord.id));
|
||||
albk_id[7]=0;
|
||||
printf("ALBK id : %s\n",albk_id);
|
||||
}
|
||||
|
||||
void VMDump::printInfo(void)
|
||||
|
||||
@@ -140,9 +140,15 @@ protected:
|
||||
} __packed;
|
||||
|
||||
/* Methods */
|
||||
inline void ebcAsc(char *inout, size_t len) const
|
||||
inline void ebcAsc(char *in, char *out, size_t size) const
|
||||
{
|
||||
iconv(ebcdicAsciiConv, &inout, &len, &inout, &len);
|
||||
size_t size_out = size;
|
||||
size_t size_in = size;
|
||||
size_t rc;
|
||||
|
||||
rc = iconv(ebcdicAsciiConv, &in, &size_in, &out, &size_out);
|
||||
if (rc == (size_t) -1)
|
||||
throw(DumpException("Code page translation EBCDIC-ASCII failed"));
|
||||
}
|
||||
|
||||
/* Members */
|
||||
|
||||
@@ -398,7 +398,7 @@ void vtoc_volume_label_set_volser (volume_label_t *vlabel, char *volser)
|
||||
|
||||
strcpy(s, " ");
|
||||
vtoc_ebcdic_enc(s, s, VOLSER_LENGTH);
|
||||
strncpy(vlabel->volid, s, VOLSER_LENGTH);
|
||||
memcpy(vlabel->volid, s, VOLSER_LENGTH);
|
||||
|
||||
if (i > VOLSER_LENGTH) i = VOLSER_LENGTH;
|
||||
|
||||
@@ -743,8 +743,8 @@ static void vtoc_init_format_1_8_label (
|
||||
bzero(f1->DS1DSNAM, sizeof(f1->DS1DSNAM));
|
||||
sprintf(str, "PART .NEW ");
|
||||
vtoc_ebcdic_enc(str, str, 44);
|
||||
strncpy(f1->DS1DSNAM, str, 44);
|
||||
strncpy((char *) f1->DS1DSSN, " ", 6);
|
||||
memcpy(f1->DS1DSNAM, str, 44);
|
||||
memcpy((char *) f1->DS1DSSN, " ", 6);
|
||||
f1->DS1VOLSQ = 0x0001;
|
||||
|
||||
vtoc_set_date(&f1->DS1CREDT,
|
||||
@@ -758,7 +758,7 @@ static void vtoc_init_format_1_8_label (
|
||||
f1->DS1NOBDB = 0x00;
|
||||
f1->DS1FLAG1 = 0x00;
|
||||
vtoc_ebcdic_enc("IBM LINUX ", str, 13);
|
||||
strncpy((char *)f1->DS1SYSCD, str, 13);
|
||||
memcpy((char *)f1->DS1SYSCD, str, 13);
|
||||
vtoc_set_date(&f1->DS1REFD,
|
||||
(u_int8_t) creatime->tm_year,
|
||||
(u_int16_t) creatime->tm_yday);
|
||||
|
||||
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
|
||||
|
||||
@@ -58,7 +58,7 @@ e.g. \-xc0a80a26
|
||||
.TP
|
||||
\fIMASKBITS\fR
|
||||
Number of bits set in the network mask.
|
||||
This allows to specify an address range, e.g. 192.168.10.0/24.
|
||||
Network masks can be used to specify address ranges, e.g. 192.168.10.0/24.
|
||||
This subparameter is only valid for function IPA.
|
||||
.TP
|
||||
\fIINTERFACE\fR
|
||||
|
||||
@@ -2,7 +2,9 @@ include ../common.mak
|
||||
|
||||
all: qethqoat
|
||||
|
||||
qethqoat: qethqoat.o
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
qethqoat: qethqoat.o $(libs)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
#include "qethqoat.h"
|
||||
|
||||
@@ -46,9 +47,15 @@ static int mac_is_zero(__u8 *mac)
|
||||
return !(mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]);
|
||||
}
|
||||
|
||||
static void ebctoasc(char *inout, size_t len)
|
||||
static void ebctoasc(char *in, char *out, size_t size)
|
||||
{
|
||||
iconv(l_iconv_ebcdic_ascii, &inout, &len, &inout, &len);
|
||||
size_t size_out = size;
|
||||
size_t size_in = size;
|
||||
size_t rc;
|
||||
|
||||
rc = iconv(l_iconv_ebcdic_ascii, &in, &size_in, &out, &size_out);
|
||||
if (rc == (size_t) -1)
|
||||
fprintf(stderr, "Code page translation EBCDIC-ASCII failed\n");
|
||||
}
|
||||
|
||||
static void print_version()
|
||||
@@ -287,6 +294,7 @@ static void print_logical(struct qeth_qoat_logical *lhdr)
|
||||
char prouter[] = "primary";
|
||||
char srouter[] = "secondary";
|
||||
char nrouter[] = "no";
|
||||
char port_name[8];
|
||||
char *router;
|
||||
|
||||
if (lhdr->ip4_primary_router)
|
||||
@@ -340,8 +348,8 @@ static void print_logical(struct qeth_qoat_logical *lhdr)
|
||||
|
||||
|
||||
if (lhdr->port_name_f) {
|
||||
ebctoasc((char *)lhdr->port_name, 8);
|
||||
printf("Port name: %.8s\n", lhdr->port_name);
|
||||
ebctoasc((char *)lhdr->port_name, port_name, 8);
|
||||
printf("Port name: %.8s\n", port_name);
|
||||
}
|
||||
|
||||
printf("IPv4 assists enabled: 0x%08x\n", lhdr->ip4_ass_enabled);
|
||||
@@ -541,6 +549,7 @@ int main(int argc, char **argv)
|
||||
opts.raw = 0;
|
||||
opts.scope = 1;
|
||||
opts.file = NULL;
|
||||
opts.ifname = NULL;
|
||||
|
||||
while ((c = getopt_long(argc, argv, qethqoat_opts_str, qethqoat_opts,
|
||||
&index)) != -1) {
|
||||
@@ -613,7 +622,7 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy(ifr.ifr_name, opts.ifname, IFNAMSIZ);
|
||||
util_strlcpy(ifr.ifr_name, opts.ifname, IFNAMSIZ);
|
||||
oat_data.command = opts.scope;
|
||||
ifr.ifr_ifru.ifru_data = (void *)&oat_data;
|
||||
|
||||
|
||||
@@ -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\
|
||||
|
||||
@@ -150,6 +150,7 @@ while IFS='= ' read key val; do
|
||||
if [ -f "${OUTPUT}" ]; then
|
||||
print_error "BLS file ${OUTPUT} already exists"
|
||||
fi
|
||||
echo "title $section" >> ${OUTPUT}
|
||||
fi
|
||||
elif [[ $val ]]; then
|
||||
val="$(echo $val | sed -e 's/^[ \t"]*//;s/[ \t"]*$//')"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,7 +21,7 @@ vmur \- Work with z/VM spool file queues
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
The \*v program allows to read, create, list, purge, or order files
|
||||
With the \*v program you can read, create, list, purge, or order files
|
||||
on the z/VM spool files queues (RDR, PUN, and PRT).
|
||||
|
||||
\*v supports the following commands:
|
||||
|
||||
@@ -168,7 +168,7 @@ static void ethtool_checksumming(char *buf, const char *if_name)
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
errx(EXIT_FAILURE, "Internal error: cannot get SOCK_DGRAM socket");
|
||||
strncpy(ifr.ifr_name, if_name, IFNAMSIZ);
|
||||
util_strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
|
||||
val.cmd = ETHTOOL_GRXCSUM;
|
||||
ifr.ifr_data = (void *)&val;
|
||||
rc = ioctl(fd, SIOCETHTOOL, &ifr);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_panic.h"
|
||||
#include "lib/util_path.h"
|
||||
@@ -620,7 +621,7 @@ static void show_devices_argv(char *argv[])
|
||||
{
|
||||
struct util_rec *rec = util_rec_new_wide("-");
|
||||
struct dirent **dev_vec, **subdev_vec;
|
||||
char *ap, *grp_dev, *path, card[16], sub_dev[16];
|
||||
char *ap, *grp_dev, *path, *card, *sub_dev;
|
||||
int id, dom, i, n, dev_cnt, sub_cnt;
|
||||
|
||||
/* check if ap driver is available */
|
||||
@@ -639,14 +640,16 @@ static void show_devices_argv(char *argv[])
|
||||
if (sscanf(argv[i], "%x.%x", &id, &dom) >= 1) {
|
||||
/* at least the id field was valid */
|
||||
if (id >= 0 && dom >= 0) { /* single subdevice */
|
||||
sprintf(sub_dev, "%02x.%04x", id, dom);
|
||||
util_asprintf(&sub_dev, "%02x.%04x", id, dom);
|
||||
grp_dev = util_path_sysfs("devices/ap/card%02x",
|
||||
id);
|
||||
show_subdevice(rec, grp_dev, sub_dev);
|
||||
free(grp_dev);
|
||||
free(sub_dev);
|
||||
} else { /* group device */
|
||||
sprintf(card, "card%02x", id);
|
||||
util_asprintf(&card, "card%02x", id);
|
||||
show_device(rec, card);
|
||||
free(card);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ enum nic_target {
|
||||
nic_lan,
|
||||
};
|
||||
|
||||
#define NIC_OWNER_LEN 9
|
||||
#define NIC_NAME_LEN 9
|
||||
#define NIC_OWNER_SIZE 9
|
||||
#define NIC_NAME_SIZE 9
|
||||
|
||||
struct nic_data {
|
||||
enum nic_type type;
|
||||
enum nic_target target;
|
||||
char owner[NIC_OWNER_LEN];
|
||||
char name[NIC_NAME_LEN];
|
||||
char owner[NIC_OWNER_SIZE];
|
||||
char name[NIC_NAME_SIZE];
|
||||
};
|
||||
|
||||
bool nic_data_get(const char *, struct nic_data *);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* zdev - Modify and display the persistent configuration of devices
|
||||
*
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
* Copyright IBM Corp. 2016, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -1091,7 +1091,7 @@ exit_code_t misc_write_text_file_retry(const char *path, const char *text,
|
||||
* at the specified path or NULL on error. */
|
||||
char *misc_readlink(const char *path)
|
||||
{
|
||||
char *name;
|
||||
char *name, *name2;
|
||||
ssize_t len;
|
||||
|
||||
debug("Reading link %s\n", path);
|
||||
@@ -1103,7 +1103,8 @@ char *misc_readlink(const char *path)
|
||||
}
|
||||
name[len++] = 0;
|
||||
|
||||
return realloc(name, len);
|
||||
name2 = realloc(name, len);
|
||||
return (name2) ? name2 : name;
|
||||
}
|
||||
|
||||
/* Determine configuration set. */
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_libc.h"
|
||||
|
||||
#include "misc.h"
|
||||
#include "nic.h"
|
||||
#include "path.h"
|
||||
@@ -55,8 +57,8 @@ bool nic_data_get(const char *id, struct nic_data *data_ptr)
|
||||
else
|
||||
goto out;
|
||||
|
||||
strncpy(data.owner, argv[11], sizeof(data.owner));
|
||||
strncpy(data.name, argv[12], sizeof(data.name));
|
||||
util_strlcpy(data.owner, argv[11], NIC_OWNER_SIZE);
|
||||
util_strlcpy(data.name, argv[12], NIC_NAME_SIZE);
|
||||
|
||||
result = true;
|
||||
*data_ptr = data;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* zdev - Modify and display the persistent configuration of devices
|
||||
*
|
||||
* Copyright IBM Corp. 2016, 2017
|
||||
* Copyright IBM Corp. 2016, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -550,7 +550,7 @@ void setting_list_merge(struct setting_list *to, struct setting_list *from,
|
||||
if (specified)
|
||||
n->specified = s->specified;
|
||||
if (modified)
|
||||
n->modified = n->modified;
|
||||
n->modified = s->modified;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
108
zdsfs/zdsfs.c
108
zdsfs/zdsfs.c
@@ -27,6 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include "lib/libzds.h"
|
||||
#include "lib/util_libc.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define COMP "zdsfs: "
|
||||
@@ -52,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;
|
||||
@@ -75,11 +78,10 @@ static void path_to_ds_name(const char *path, char *normds, size_t size)
|
||||
|
||||
if (*path == '/')
|
||||
++path;
|
||||
strncpy(normds, path, size);
|
||||
normds[size - 1] = 0;
|
||||
util_strlcpy(normds, path, size);
|
||||
end = strchr(normds, '/');
|
||||
if (end)
|
||||
*end = 0;
|
||||
*end = '\0';
|
||||
}
|
||||
|
||||
static void path_to_member_name(const char *path, char *normds, size_t size)
|
||||
@@ -88,11 +90,10 @@ static void path_to_member_name(const char *path, char *normds, size_t size)
|
||||
++path;
|
||||
path = strchr(path, '/');
|
||||
if (!path)
|
||||
normds[0] = 0;
|
||||
normds[0] = '\0';
|
||||
else {
|
||||
++path;
|
||||
strncpy(normds, path, size);
|
||||
normds[size - 1] = 0;
|
||||
util_strlcpy(normds, path, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,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;
|
||||
@@ -240,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))
|
||||
{
|
||||
@@ -253,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
|
||||
*/
|
||||
@@ -329,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;
|
||||
@@ -596,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);
|
||||
@@ -822,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)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <stdio.h>
|
||||
@@ -20,6 +21,8 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "zgetdump.h"
|
||||
#include "dfi_s390mv.h"
|
||||
|
||||
@@ -102,19 +105,25 @@ static void em_init(struct vol *vol)
|
||||
*/
|
||||
static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
|
||||
{
|
||||
char tmp_file[PATH_MAX], dev_file[PATH_MAX];
|
||||
struct dirent *direntp;
|
||||
int fh, minor, major;
|
||||
char buf[10];
|
||||
DIR *fh_dir;
|
||||
char *sysfs;
|
||||
|
||||
snprintf(dev_file, PATH_MAX, "%s/%s", SYSFS_BUSDIR, bus_id);
|
||||
fh_dir = opendir(dev_file);
|
||||
sysfs = util_path_sysfs("%s/%s", SYSFS_BUSDIR, bus_id);
|
||||
fh_dir = opendir(sysfs);
|
||||
free(sysfs);
|
||||
if (!fh_dir)
|
||||
return DEV_UNDEFINED;
|
||||
|
||||
snprintf(tmp_file, PATH_MAX, "%s/online", dev_file);
|
||||
fh = open(tmp_file, O_RDONLY);
|
||||
sysfs = util_path_sysfs("%s/%s/online", SYSFS_BUSDIR, bus_id);
|
||||
fh = open(sysfs, O_RDONLY);
|
||||
if (fh == -1) {
|
||||
warnx("Could not open \"%s\" (%s)", sysfs, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
free(sysfs);
|
||||
if (read(fh, buf, 1) == -1)
|
||||
ERR_EXIT_ERRNO("Could not read online attribute");
|
||||
close(fh);
|
||||
@@ -128,27 +137,49 @@ static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
|
||||
closedir(fh_dir);
|
||||
|
||||
if (direntp == NULL) {
|
||||
snprintf(dev_file, PATH_MAX, "%s/%s/block", SYSFS_BUSDIR,
|
||||
bus_id);
|
||||
fh_dir = opendir(dev_file);
|
||||
if (!fh_dir)
|
||||
ERR_EXIT_ERRNO("Could not open \"%s\"", dev_file);
|
||||
sysfs = util_path_sysfs("%s/%s/block", SYSFS_BUSDIR, bus_id);
|
||||
fh_dir = opendir(sysfs);
|
||||
if (!fh_dir) {
|
||||
warnx("Could not open \"%s\" (%s) ",
|
||||
sysfs, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
while ((direntp = readdir(fh_dir)))
|
||||
if (strncmp(direntp->d_name, "dasd", 4) == 0)
|
||||
break;
|
||||
closedir(fh_dir);
|
||||
if (direntp == NULL)
|
||||
ERR_EXIT("Problem with contents of \"%s\"", dev_file);
|
||||
if (direntp == NULL) {
|
||||
warnx("Problem with contents of \"%s\"", sysfs);
|
||||
goto err;
|
||||
}
|
||||
free(sysfs);
|
||||
}
|
||||
|
||||
sysfs = util_path_sysfs("%s/%s/%s/dev",
|
||||
SYSFS_BUSDIR, bus_id, direntp->d_name);
|
||||
fh = open(sysfs, O_RDONLY);
|
||||
if (fh == -1) {
|
||||
warnx("Could not open \"%s\" (%s)", sysfs, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
if (read(fh, buf, sizeof(buf)) == -1) {
|
||||
warnx("Could not read dev file (%s)", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
snprintf(tmp_file, PATH_MAX, "%s/%s/dev", dev_file, direntp->d_name);
|
||||
fh = open(tmp_file, O_RDONLY);
|
||||
if (read(fh, buf, sizeof(buf)) == -1)
|
||||
ERR_EXIT_ERRNO("Could not read dev file");
|
||||
close(fh);
|
||||
if (sscanf(buf, "%i:%i", &major, &minor) != 2)
|
||||
ERR_EXIT("Malformed content of \"%s\": %s", tmp_file, buf);
|
||||
if (sscanf(buf, "%i:%i", &major, &minor) != 2) {
|
||||
warnx("Malformed content of \"%s\": %s", sysfs, buf);
|
||||
goto err;
|
||||
}
|
||||
*dev = makedev(major, minor);
|
||||
|
||||
free(sysfs);
|
||||
|
||||
return DEV_ONLINE;
|
||||
|
||||
err:
|
||||
free(sysfs);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -467,19 +498,6 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if sysfs is available
|
||||
*/
|
||||
static void check_sysfs(void)
|
||||
{
|
||||
DIR *fh_dir;
|
||||
|
||||
fh_dir = opendir(SYSFS_BUSDIR);
|
||||
if (!fh_dir)
|
||||
ERR_EXIT_ERRNO("Could not open %s\n", SYSFS_BUSDIR);
|
||||
closedir(fh_dir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read dump tool from DASD and check if we have a multi-volume dump tool
|
||||
*/
|
||||
@@ -503,8 +521,6 @@ static void volumes_init(void)
|
||||
u64 mem_off = 0;
|
||||
unsigned int i;
|
||||
|
||||
check_sysfs();
|
||||
|
||||
for (i = 0; i < l.table.vol_cnt; i++) {
|
||||
l.vol_vec[i].nr = i;
|
||||
vol_init(&l.vol_vec[i], &l.table.vol_parm[i], l.table.ssid[i],
|
||||
@@ -552,10 +568,10 @@ static void set_magic_numbers(void)
|
||||
{
|
||||
if (l.extended) {
|
||||
l.magic_number = DF_S390_MAGIC_EXT;
|
||||
strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7);
|
||||
memcpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV_EXT, 7);
|
||||
} else {
|
||||
l.magic_number = DF_S390_MAGIC;
|
||||
strncpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV, 7);
|
||||
memcpy(l.dumper_magic, DF_S390_DUMPER_MAGIC_MV, 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#define SYSFS_BUSDIR "/sys/bus/ccw/devices"
|
||||
#define SYSFS_BUSDIR "bus/ccw/devices"
|
||||
#define MAX_VOLUMES 32
|
||||
|
||||
/*
|
||||
|
||||
@@ -167,7 +167,7 @@ static void argv_fuse_set(char **argv, int argc)
|
||||
static void action_set(enum zg_action action)
|
||||
{
|
||||
if (g.opts.action_specified)
|
||||
ERR_EXIT("Please specifiy only one of the \"-i\", \"-d\", "
|
||||
ERR_EXIT("Please specify only one of the \"-i\", \"-d\", "
|
||||
"\"-m\" or \"-u\" option");
|
||||
g.opts.action = action;
|
||||
g.opts.action_specified = 1;
|
||||
@@ -183,7 +183,7 @@ static void verify_opts(void)
|
||||
g.opts.action != ZG_ACTION_STDOUT &&
|
||||
g.opts.action != ZG_ACTION_DUMP_INFO)
|
||||
ERR_EXIT("The \"--select\" option can only be "
|
||||
"specifed for info, mount, or copy");
|
||||
"specified for info, mount, or copy");
|
||||
}
|
||||
if (!g.opts.fmt_specified)
|
||||
return;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Bootmenu Subroutines
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -123,7 +123,7 @@ static int menu_param(unsigned long *value)
|
||||
/* no number, check for keyword */
|
||||
i = 0;
|
||||
/* skip leading whitespaces */
|
||||
while (ebc_isspace(loadparm[i]) && (i < PARAM_SIZE))
|
||||
while ((i < PARAM_SIZE) && ebc_isspace(loadparm[i]))
|
||||
i++;
|
||||
|
||||
if (!strncmp(&loadparm[i], "PROMPT", 6)) {
|
||||
|
||||
@@ -190,7 +190,7 @@ struct _lowcore {
|
||||
|
||||
/* align to the top of the prefix area */
|
||||
uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */
|
||||
} __packed;
|
||||
} __packed __aligned(8192);
|
||||
|
||||
#define S390_lowcore (*((struct _lowcore *) 0))
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Main program for stage3 bootloader
|
||||
*
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
* Copyright IBM Corp. 2013, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -257,7 +257,7 @@ void start(void)
|
||||
length++;
|
||||
|
||||
/* find end of original parm line */
|
||||
while (command_line[end] != 0 && command_line[end] != 0)
|
||||
while (command_line[end] != 0)
|
||||
end++;
|
||||
|
||||
/*
|
||||
|
||||
@@ -59,9 +59,9 @@ tool implements a boot menu which includes the following features:
|
||||
.IP " -"
|
||||
display a list of available configurations
|
||||
.IP " -"
|
||||
allow to choose a configuration
|
||||
choose a configuration
|
||||
.IP " -"
|
||||
allow to specify additional kernel command line parameters
|
||||
specify additional kernel command line parameters
|
||||
.PP
|
||||
|
||||
See the
|
||||
|
||||
@@ -7,8 +7,8 @@ ALL_CPPFLAGS += -I../include -I../boot \
|
||||
-D_FILE_OFFSET_BITS=64 $(NO_PIE_CFLAGS)
|
||||
ALL_LDFLAGS += -Wl,-z,noexecstack $(NO_PIE_LDFLAGS)
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a \
|
||||
$(rootdir)/libu2s/libu2s.a
|
||||
libs = $(rootdir)/libu2s/libu2s.a \
|
||||
$(rootdir)/libutil/libutil.a
|
||||
|
||||
objects = misc.o error.o scan.o job.o boot.o bootmap.o disk.o \
|
||||
install.o zipl.o $(rootdir)/zipl/boot/data.o
|
||||
|
||||
@@ -117,7 +117,7 @@ boot_init_fba_stage0(struct boot_fba_stage0 *stage0,
|
||||
blocknum_t i;
|
||||
|
||||
/* Initialize stage 0 data */
|
||||
memcpy(stage0, DATA_ADDR(fba0), sizeof(*stage0));
|
||||
memcpy(stage0, DATA_ADDR(fba0), DATA_SIZE(fba0));
|
||||
/* Fill in blocklist for stage 2 loader */
|
||||
if (stage1b_count > STAGE1B_BLK_CNT_MAX) {
|
||||
error_reason("Not enough room for FBA stage 1b loader");
|
||||
@@ -137,7 +137,7 @@ boot_init_fba_stage0(struct boot_fba_stage0 *stage0,
|
||||
void
|
||||
boot_init_eckd_ldl_stage0(struct boot_eckd_ldl_stage0 *stage0)
|
||||
{
|
||||
memcpy(stage0, DATA_ADDR(eckd0_ldl), sizeof(*stage0));
|
||||
memcpy(stage0, DATA_ADDR(eckd0_ldl), DATA_SIZE(eckd0_ldl));
|
||||
/* Fill in size of stage 1 plus stage 0 loader */
|
||||
stage0->read_r1.count = sizeof(struct boot_eckd_stage1) +
|
||||
sizeof(struct boot_eckd_ldl_stage0);
|
||||
@@ -146,7 +146,7 @@ boot_init_eckd_ldl_stage0(struct boot_eckd_ldl_stage0 *stage0)
|
||||
void
|
||||
boot_init_eckd_cdl_stage0(struct boot_eckd_cdl_stage0 *stage0)
|
||||
{
|
||||
memcpy(stage0, DATA_ADDR(eckd0_cdl), sizeof(*stage0));
|
||||
memcpy(stage0, DATA_ADDR(eckd0_cdl), DATA_SIZE(eckd0_cdl));
|
||||
/* Fill in size of stage 1 loader */
|
||||
stage0->read.count = sizeof(struct boot_eckd_stage1);
|
||||
}
|
||||
@@ -157,7 +157,7 @@ boot_init_eckd_stage1(struct boot_eckd_stage1 *stage1,
|
||||
{
|
||||
blocknum_t i;
|
||||
|
||||
memcpy(stage1, DATA_ADDR(eckd1), sizeof(*stage1));
|
||||
memcpy(stage1, DATA_ADDR(eckd1), DATA_SIZE(eckd1));
|
||||
/* Fill in blocklist for stage 1b loader */
|
||||
if (stage1b_count > STAGE1B_BLK_CNT_MAX) {
|
||||
error_reason("Not enough room for ECKD stage 1b loader "
|
||||
@@ -185,7 +185,7 @@ boot_init_fba_stage1b(struct boot_fba_stage1b *stage1b,
|
||||
{
|
||||
blocknum_t i;
|
||||
|
||||
memcpy(stage1b, DATA_ADDR(fba1b), sizeof(*stage1b));
|
||||
memcpy(stage1b, DATA_ADDR(fba1b), DATA_SIZE(fba1b));
|
||||
if (stage2_count > STAGE2_BLK_CNT_MAX) {
|
||||
error_reason("Not enough room for FBA stage 2 loader");
|
||||
return -1;
|
||||
@@ -207,7 +207,7 @@ boot_init_eckd_stage1b(struct boot_eckd_stage1b *stage1b,
|
||||
{
|
||||
blocknum_t i;
|
||||
|
||||
memcpy(stage1b, DATA_ADDR(eckd1b), sizeof(*stage1b));
|
||||
memcpy(stage1b, DATA_ADDR(eckd1b), DATA_SIZE(eckd1b));
|
||||
if (stage2_count > STAGE2_BLK_CNT_MAX) {
|
||||
error_reason("Not enough room for ECKD stage 2 loader "
|
||||
"(try larger block size)");
|
||||
|
||||
@@ -198,8 +198,8 @@ disk_get_info(const char* device, struct job_target_data* target,
|
||||
long devsize;
|
||||
FILE *fh;
|
||||
char *script_pre = TOOLS_LIBDIR "/zipl_helper.";
|
||||
char script_file[80];
|
||||
char ppn_cmd[80];
|
||||
char *script_file;
|
||||
char *ppn_cmd;
|
||||
char buffer[80];
|
||||
char value[40];
|
||||
int majnum, minnum;
|
||||
@@ -235,23 +235,22 @@ disk_get_info(const char* device, struct job_target_data* target,
|
||||
}
|
||||
data->source = source_user;
|
||||
/* Check if targetbase script is available */
|
||||
strcpy(script_file, script_pre);
|
||||
if (data->drv_name) {
|
||||
strcat(script_file, data->drv_name);
|
||||
}
|
||||
if (data->drv_name)
|
||||
misc_asprintf(&script_file, "%s%s", script_pre, data->drv_name);
|
||||
else
|
||||
misc_asprintf(&script_file, "%s", script_pre);
|
||||
if ((target->targetbase == NULL) &&
|
||||
(!stat(script_file, &script_stats))) {
|
||||
data->source = source_script;
|
||||
/* Run targetbase script */
|
||||
strcpy(ppn_cmd, script_file);
|
||||
if (target->bootmap_dir == NULL) {
|
||||
/* happens in case of partition dump */
|
||||
snprintf(ppn_cmd, sizeof(ppn_cmd), "%s %d:%d",
|
||||
script_file, major(stats.st_rdev),
|
||||
minor(stats.st_rdev));
|
||||
misc_asprintf(&ppn_cmd, "%s %d:%d",
|
||||
script_file, major(stats.st_rdev),
|
||||
minor(stats.st_rdev));
|
||||
} else {
|
||||
strcat(ppn_cmd, " ");
|
||||
strcat(ppn_cmd, target->bootmap_dir);
|
||||
misc_asprintf(&ppn_cmd, "%s %s",
|
||||
script_file, target->bootmap_dir);
|
||||
}
|
||||
printf("Run %s\n", ppn_cmd);
|
||||
fh = popen(ppn_cmd, "r");
|
||||
@@ -447,6 +446,7 @@ type_determined:
|
||||
return 0;
|
||||
out_close:
|
||||
close(fd);
|
||||
free(ppn_cmd);
|
||||
free(data);
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -701,7 +701,7 @@ scan_bls_field(struct misc_file_buffer *file, struct scan_token* scan,
|
||||
file->buffer[key_end] = '\0';
|
||||
file->buffer[val_end] = '\0';
|
||||
|
||||
if (strncmp("version", &file->buffer[key_start], key_end - key_start) == 0) {
|
||||
if (strncmp("title", &file->buffer[key_start], key_end - key_start) == 0) {
|
||||
scan_append_section_heading(scan, index, &file->buffer[val_start]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 "
|
||||
@@ -3235,7 +3222,7 @@ static int _keystore_execute_cmd(const char *cmd,
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = setenv("PATH", "/bin:/usr/bin:/usr/sbin", 1);
|
||||
rc = setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin", 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -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);
|
||||
|
||||
23
zkey/pkey.c
23
zkey/pkey.c
@@ -48,6 +48,7 @@
|
||||
* Definitions for the CCA library
|
||||
*/
|
||||
#define CCA_LIBRARY_NAME "libcsulcca.so"
|
||||
#define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards"
|
||||
|
||||
#define DEFAULT_KEYBITS 256
|
||||
|
||||
@@ -71,16 +72,20 @@ int load_cca_library(void **lib_csulcca, t_CSNBKTC *dll_CSNBKTC, bool verbose)
|
||||
/* Load the CCA library */
|
||||
*lib_csulcca = dlopen(CCA_LIBRARY_NAME, RTLD_GLOBAL | RTLD_NOW);
|
||||
if (*lib_csulcca == NULL) {
|
||||
warnx("%s\nEnsure that the IBM CCA Host Libraries and "
|
||||
"Tools are installed properly", dlerror());
|
||||
pr_verbose(verbose, "%s", dlerror());
|
||||
warnx("The command requires the IBM CCA Host Libraries and "
|
||||
"Tools.\nFor the supported environments and downloads, "
|
||||
"see:\n%s", CCA_WEB_PAGE);
|
||||
return -ELIBACC;
|
||||
}
|
||||
|
||||
/* Get the Key Token Change function */
|
||||
*dll_CSNBKTC = (t_CSNBKTC)dlsym(*lib_csulcca, "CSNBKTC");
|
||||
if (*dll_CSNBKTC == NULL) {
|
||||
warnx("%s\nEnsure that the IBM CCA Host Libraries and "
|
||||
"Tools are installed properly", dlerror());
|
||||
pr_verbose(verbose, "%s", dlerror());
|
||||
warnx("The command requires the IBM CCA Host Libraries and "
|
||||
"Tools.\nFor the supported environments and downloads, "
|
||||
"see:\n%s", CCA_WEB_PAGE);
|
||||
dlclose(*lib_csulcca);
|
||||
*lib_csulcca = NULL;
|
||||
return -ELIBACC;
|
||||
@@ -158,8 +163,8 @@ u8 *read_secure_key(const char *keyfile, size_t *secure_key_size,
|
||||
|
||||
buf = util_malloc(size);
|
||||
count = fread(buf, 1, size, fp);
|
||||
if (count <= 0) {
|
||||
msg = feof(fp) ? "File is too small" : strerror(errno);
|
||||
if (count != size) {
|
||||
msg = ferror(fp) ? strerror(errno) : "File is too small";
|
||||
warnx("File '%s': %s", keyfile, msg);
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
@@ -206,7 +211,7 @@ int write_secure_key(const char *keyfile, const u8 *secure_key,
|
||||
}
|
||||
|
||||
count = fwrite(secure_key, 1, secure_key_size, fp);
|
||||
if (count <= 0) {
|
||||
if (count != secure_key_size) {
|
||||
warnx("File '%s': %s", keyfile, strerror(errno));
|
||||
fclose(fp);
|
||||
return -EIO;
|
||||
@@ -296,8 +301,8 @@ static u8 *read_clear_key(const char *keyfile, size_t keybits, bool xts,
|
||||
|
||||
buf = util_malloc(size);
|
||||
count = fread(buf, 1, size, fp);
|
||||
if (count <= 0) {
|
||||
msg = feof(fp) ? "File is too small" : strerror(errno);
|
||||
if (count != size) {
|
||||
msg = ferror(fp) ? strerror(errno) : "File is too small";
|
||||
warnx("File '%s': %s", keyfile, msg);
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
|
||||
@@ -180,9 +180,24 @@ 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.
|
||||
to be installed. For the supported environments and downloads, see:
|
||||
\fIhttp://www.ibm.com/security/cryptocards\fP
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -287,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;
|
||||
}
|
||||
|
||||
12
zkey/zkey.1
12
zkey/zkey.1
@@ -282,7 +282,8 @@ a staged re-enciphering for the \fBOLD\fP to \fBCURRENT\fP case.
|
||||
.PP
|
||||
.B Note:
|
||||
The \fBreencipher\fP command requires the CCA host library (libcsulcca.so)
|
||||
to be installed.
|
||||
to be installed. For the supported environments and downloads, see:
|
||||
\fIhttp://www.ibm.com/security/cryptocards\fP
|
||||
.
|
||||
.SS "Import existing AES secure keys into the secure key repository"
|
||||
.
|
||||
@@ -566,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.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
@@ -33,7 +33,7 @@ zpcictl - Manage PCI devices on IBM Z
|
||||
Use
|
||||
.B zpcictl
|
||||
to manage PCI devices on the IBM Z platform. In particular,
|
||||
use this command to report defective PCI devices to the service element.
|
||||
use this command to report defective PCI devices to the Support Element (SE).
|
||||
|
||||
.B Note:
|
||||
For NVMe devices additional data (such as S.M.A.R.T. data) is collected and sent
|
||||
|
||||
@@ -60,7 +60,7 @@ static struct util_opt opt_vec[] = {
|
||||
},
|
||||
{
|
||||
.option = { "report-error", no_argument, NULL, OPT_REPORT_ERR },
|
||||
.desc = "Report a device error to the service element (SE)",
|
||||
.desc = "Report a device error to the Support Element (SE)",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
UTIL_OPT_SECTION("GENERAL OPTIONS"),
|
||||
@@ -171,8 +171,12 @@ static void sysfs_write_data(struct zpci_report_error *report, char *slot)
|
||||
fopen_err(path);
|
||||
if (fwrite(report, 1, r_size, fp) != r_size)
|
||||
warnx("Could not write to file: %s: %s", path, strerror(errno));
|
||||
if (fclose(fp))
|
||||
warnx("Could not close file: %s: %s", path, strerror(errno));
|
||||
if (fclose(fp)) {
|
||||
if (errno == EIO || errno == EOPNOTSUPP)
|
||||
warnx("Unsupported operation: %s: %s", path, strerror(errno));
|
||||
else
|
||||
warnx("Could not close file: %s: %s", path, strerror(errno));
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
|
||||
@@ -309,7 +313,8 @@ static void sclp_issue_action(struct zpci_device *pdev, int action)
|
||||
if (pdev->class == PCI_CLASS_NVME)
|
||||
sdata = collect_smart_data(pdev);
|
||||
if (sdata) {
|
||||
strncpy(report.data.log_data, sdata, sizeof(report.data.log_data));
|
||||
util_strlcpy(report.data.log_data, sdata,
|
||||
sizeof(report.data.log_data));
|
||||
free(sdata);
|
||||
}
|
||||
sysfs_write_data(&report, pdev->slot);
|
||||
|
||||
Reference in New Issue
Block a user