mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
114 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
d6925a30da | ||
|
|
fe4cc7c479 | ||
|
|
fa3cabc8af | ||
|
|
5a9b56f814 | ||
|
|
20145b6d06 | ||
|
|
9561a0b983 | ||
|
|
97fa88299f | ||
|
|
aaaebb2030 | ||
|
|
ff2a403bd2 | ||
|
|
66ed1727f9 | ||
|
|
c33cc5a619 | ||
|
|
cd46297d7c | ||
|
|
07b11982e3 | ||
|
|
35348c302b | ||
|
|
35312d0c47 | ||
|
|
342c6a3707 | ||
|
|
e2a8d85916 | ||
|
|
8f0496b26a | ||
|
|
d03be73536 | ||
|
|
a87268d62e | ||
|
|
9cc06a0529 | ||
|
|
3b1ccce515 | ||
|
|
ffe91d1b30 | ||
|
|
f35c5d01fd | ||
|
|
b23c35c390 | ||
|
|
177cf8cfeb | ||
|
|
f05f7d656b | ||
|
|
0bf4f1b957 | ||
|
|
cd38119888 | ||
|
|
cadef5c0ff | ||
|
|
02e1c783f6 | ||
|
|
07e30951f8 | ||
|
|
0a0b4c3826 | ||
|
|
eade995185 | ||
|
|
0eba8d11df | ||
|
|
257490366b | ||
|
|
5ef1320a7b | ||
|
|
f2f572fa70 | ||
|
|
e655f0cd7b | ||
|
|
68b46eea7a | ||
|
|
9894e391ef | ||
|
|
5982fd98bf | ||
|
|
d5291eed1c | ||
|
|
34260f1736 | ||
|
|
b9b3d2d230 | ||
|
|
4cf8f5f46c | ||
|
|
eba744a25e | ||
|
|
80e0c41b89 | ||
|
|
cdc787db1b | ||
|
|
ef4dc7a45b | ||
|
|
cb3e949772 | ||
|
|
f02de298c1 | ||
|
|
eb0dc13c88 | ||
|
|
d08bd23c1e | ||
|
|
724f1fea2c | ||
|
|
dcc63e6dfc | ||
|
|
576034e94a | ||
|
|
3ec49ba7bd |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -68,6 +68,7 @@ zconf/qeth/lsqeth
|
|||||||
zconf/scm/lsscm
|
zconf/scm/lsscm
|
||||||
zconf/zcrypt/chzcrypt
|
zconf/zcrypt/chzcrypt
|
||||||
zconf/zcrypt/lszcrypt
|
zconf/zcrypt/lszcrypt
|
||||||
|
zconf/zcrypt/zcryptctl
|
||||||
zdev/src/chzdev
|
zdev/src/chzdev
|
||||||
zdev/src/chzdev_usage.c
|
zdev/src/chzdev_usage.c
|
||||||
zdev/src/lszdev
|
zdev/src/lszdev
|
||||||
@@ -76,7 +77,8 @@ zdsfs/zdsfs
|
|||||||
zdump/zgetdump
|
zdump/zgetdump
|
||||||
zfcpdump/cpioinit
|
zfcpdump/cpioinit
|
||||||
zfcpdump/zfcpdump_part
|
zfcpdump/zfcpdump_part
|
||||||
zfcpdump/zfcpdump_part.rd
|
zfcpdump/zfcpdump-initrd
|
||||||
|
zfcpdump/10-zfcpdump.install
|
||||||
ziomon/ziomon_mgr
|
ziomon/ziomon_mgr
|
||||||
ziomon/ziomon_util
|
ziomon/ziomon_util
|
||||||
ziomon/ziomon_zfcpdd
|
ziomon/ziomon_zfcpdd
|
||||||
@@ -89,3 +91,8 @@ zipl/src/chreipl_helper.device-mapper
|
|||||||
zipl/src/zipl
|
zipl/src/zipl
|
||||||
zipl/src/zipl_helper.device-mapper
|
zipl/src/zipl_helper.device-mapper
|
||||||
zkey/zkey
|
zkey/zkey
|
||||||
|
zkey/zkey-cryptsetup
|
||||||
|
zkey/check-dep-zkey
|
||||||
|
zkey/check-dep-zkey-cryptsetup
|
||||||
|
zkey/detect-libcryptsetup.dep
|
||||||
|
zpcictl/zpcictl
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ List of all individuals having contributed content to s390-tools
|
|||||||
- Dimitri John Ledkov
|
- Dimitri John Ledkov
|
||||||
- Eberhard Pasch
|
- Eberhard Pasch
|
||||||
- Einar Lueck
|
- Einar Lueck
|
||||||
|
- Eric Sandeen
|
||||||
- Erwin Vicari
|
- Erwin Vicari
|
||||||
- Eugene Crosser
|
- Eugene Crosser
|
||||||
- Eugene Dvurechenski
|
- Eugene Dvurechenski
|
||||||
|
|||||||
49
CHANGELOG.md
49
CHANGELOG.md
@@ -1,5 +1,54 @@
|
|||||||
Release history for s390-tools (MIT version)
|
Release history for s390-tools (MIT version)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
* __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
|
||||||
|
|
||||||
|
Add new tool:
|
||||||
|
- zcryptctl: Add zcryptctl for multiple zcrypt node management
|
||||||
|
- zpcictl: Add zpcictl for reporting defective PCI devices
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- qethqoat: Add OSA-Express7S support
|
||||||
|
- lszcrypt: Add support for alternative zcrypt device drivers
|
||||||
|
- zfcpdump: Add install script for zfcpdump
|
||||||
|
- zipl: Make zipl work with XFS by using the FIEMAP mapping ioctl
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- lstape: Fix output with SCSI lin_tape and multiple paths to same unit
|
||||||
|
- lstape: Fix output without SCSI generic (sg)
|
||||||
|
- lsluns: Fix to prevent error messages if there are non-zfcp SCSI devices
|
||||||
|
- lstape: Fix to prevent error messages if there are non-zfcp SCSI devices
|
||||||
|
- lstape: Fix description of --type and <devbusid> filter for channel tapes
|
||||||
|
- lstape: Fix SCSI output description in man page
|
||||||
|
- lstape: Fix SCSI HBA CCW device bus-ID e.g. for virtio-scsi-ccw
|
||||||
|
- Direct --help and --version output to stdout for several tools
|
||||||
|
- osasnmpd: Start without real OSA devices
|
||||||
|
|
||||||
* __v2.6.0 (2018-08-10)__
|
* __v2.6.0 (2018-08-10)__
|
||||||
|
|
||||||
For Linux kernel version: 4.18
|
For Linux kernel version: 4.18
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
|||||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc
|
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl
|
||||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||||
|
|
||||||
all: $(TOOL_DIRS)
|
all: $(TOOL_DIRS)
|
||||||
|
|||||||
@@ -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
|
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.
|
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
|
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.
|
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
|
* Main function
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2010, 2017
|
* Copyright IBM Corp. 2010, 2018
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <fuse.h>
|
#include <fuse.h>
|
||||||
#include <fuse_opt.h>
|
#include <fuse_opt.h>
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#ifdef HAVE_SETXATTR
|
#ifdef HAVE_SETXATTR
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_list.h"
|
#include "lib/util_list.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@ static const struct fuse_opt cmsfs_opts[] = {
|
|||||||
|
|
||||||
static void usage(const char *progname)
|
static void usage(const char *progname)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stdout,
|
||||||
"Usage: %s DEVICE MOUNTPOINT [OPTIONS]\n"
|
"Usage: %s DEVICE MOUNTPOINT [OPTIONS]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Use the cmsfs-fuse command to read and write files stored on a z/VM CMS disk.\n"
|
"Use the cmsfs-fuse command to read and write files stored on a z/VM CMS disk.\n"
|
||||||
@@ -232,6 +234,8 @@ struct file {
|
|||||||
int null_records;
|
int null_records;
|
||||||
/* write cache for text mode */
|
/* write cache for text mode */
|
||||||
char *wcache;
|
char *wcache;
|
||||||
|
/* buffer for iconv */
|
||||||
|
char *iconv_buf;
|
||||||
/* used bytes in write cache */
|
/* used bytes in write cache */
|
||||||
int wcache_used;
|
int wcache_used;
|
||||||
/* committed written bytes to FUSE */
|
/* committed written bytes to FUSE */
|
||||||
@@ -601,7 +605,7 @@ static struct file *file_open(const char *name)
|
|||||||
char uc_name[MAX_FNAME];
|
char uc_name[MAX_FNAME];
|
||||||
struct file *f;
|
struct file *f;
|
||||||
|
|
||||||
strncpy(uc_name, name, MAX_FNAME);
|
util_strlcpy(uc_name, name, MAX_FNAME);
|
||||||
str_toupper(uc_name);
|
str_toupper(uc_name);
|
||||||
|
|
||||||
util_list_iterate(&open_file_list, f)
|
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)
|
static void add_record_ext(struct record *rec, struct record_ext *ext)
|
||||||
{
|
{
|
||||||
struct record_ext *tmp;
|
struct record_ext *tmp;
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (rec->ext == NULL) {
|
if (rec->ext == NULL) {
|
||||||
rec->ext = ext;
|
rec->ext = ext;
|
||||||
@@ -931,9 +934,7 @@ static void add_record_ext(struct record *rec, struct record_ext *ext)
|
|||||||
ext->next = NULL;
|
ext->next = NULL;
|
||||||
} else {
|
} else {
|
||||||
tmp = rec->ext;
|
tmp = rec->ext;
|
||||||
i++;
|
|
||||||
while (tmp->next != NULL) {
|
while (tmp->next != NULL) {
|
||||||
i++;
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
tmp->next = ext;
|
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;
|
off_t faddr = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
strncpy(uc_name, name, MAX_FNAME);
|
util_strlcpy(uc_name, name, MAX_FNAME);
|
||||||
str_toupper(uc_name);
|
str_toupper(uc_name);
|
||||||
|
|
||||||
if (flag == HIDE_UNLINKED && file_unlinked(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)
|
if (f->wcache == NULL)
|
||||||
return -ENOMEM;
|
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);
|
str_toupper(f->path);
|
||||||
|
|
||||||
f->use_count = 1;
|
f->use_count = 1;
|
||||||
@@ -2108,7 +2128,7 @@ static int cmsfs_create(const char *path, mode_t mode,
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* force uppercase */
|
/* force uppercase */
|
||||||
strncpy(uc_name, path + 1, MAX_FNAME);
|
util_strlcpy(uc_name, path + 1, MAX_FNAME);
|
||||||
str_toupper(uc_name);
|
str_toupper(uc_name);
|
||||||
|
|
||||||
rc = encode_edf_name(uc_name, fname, ftype);
|
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 out_count = size;
|
||||||
size_t in_count = size;
|
size_t in_count = size;
|
||||||
char *data_ptr = buf;
|
|
||||||
int rc;
|
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)) {
|
if ((rc == -1) || (in_count != 0)) {
|
||||||
DEBUG("Code page translation EBCDIC-ASCII failed\n");
|
DEBUG("Code page translation EBCDIC-ASCII failed\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@@ -2618,14 +2637,15 @@ static int cmsfs_read(const char *path, char *buf, size_t size, off_t offset,
|
|||||||
/* read one record */
|
/* read one record */
|
||||||
if (addr == NULL_BLOCK)
|
if (addr == NULL_BLOCK)
|
||||||
memset(buf, 0, chunk);
|
memset(buf, 0, chunk);
|
||||||
else {
|
else if (f->translate) {
|
||||||
rc = _read(buf, chunk, addr);
|
rc = _read(f->iconv_buf, chunk, addr);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
rc = convert_text(cmsfs.iconv_from, f->iconv_buf, buf, chunk);
|
||||||
|
if (rc < 0)
|
||||||
if (f->translate) {
|
return rc;
|
||||||
rc = convert_text(cmsfs.iconv_from, buf, chunk);
|
} else {
|
||||||
|
rc = _read(buf, chunk, addr);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2757,7 +2777,7 @@ static int delete_file(const char *path)
|
|||||||
fst_last = find_last_fdir_entry(cmsfs.fdir, cmsfs.dir_levels);
|
fst_last = find_last_fdir_entry(cmsfs.fdir, cmsfs.dir_levels);
|
||||||
|
|
||||||
/* remove unlinked file from fcache */
|
/* remove unlinked file from fcache */
|
||||||
strncpy(file, path + 1, MAX_FNAME);
|
util_strlcpy(file, path + 1, MAX_FNAME);
|
||||||
str_toupper(file);
|
str_toupper(file);
|
||||||
invalidate_htab_entry(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);
|
str_toupper(uc_new_name);
|
||||||
|
|
||||||
rc = encode_edf_name(uc_new_name, fname, ftype);
|
rc = encode_edf_name(uc_new_name, fname, ftype);
|
||||||
|
free(uc_new_name);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
memcpy(&fst.name[0], fname, 8);
|
memcpy(&fst.name[0], fname, 8);
|
||||||
memcpy(&fst.type[0], ftype, 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);
|
str_toupper(uc_old_name);
|
||||||
invalidate_htab_entry(uc_old_name);
|
invalidate_htab_entry(uc_old_name);
|
||||||
|
|
||||||
/* update name in file object if the file is opened */
|
/* update name in file object if the file is opened */
|
||||||
f = file_open(uc_old_name);
|
f = file_open(uc_old_name);
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
strncpy(f->path, new_path, MAX_FNAME + 1);
|
util_strlcpy(f->path, new_path, MAX_FNAME + 1);
|
||||||
str_toupper(f->path);
|
str_toupper(f->path);
|
||||||
memcpy(f->fst->name, fname, 8);
|
memcpy(f->fst->name, fname, 8);
|
||||||
memcpy(f->fst->type, ftype, 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);
|
DEBUG("%s: wrote %d record bytes\n", __func__, rlen);
|
||||||
if (size <= 0)
|
if (size == 0)
|
||||||
return copied;
|
return copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4167,22 +4188,13 @@ static ssize_t find_newline(const char *buf, int len)
|
|||||||
return pos - buf;
|
return pos - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmsfs_write(const char *path, const char *buf, size_t size,
|
static int cmsfs_write_strings(struct file *f, const char *buf,
|
||||||
off_t offset, struct fuse_file_info *fi)
|
size_t size, off_t offset)
|
||||||
{
|
{
|
||||||
int scan_len = MIN(size, (size_t)MAX_RECORD_LEN + 1);
|
int scan_len = MIN(size, (size_t)MAX_RECORD_LEN + 1);
|
||||||
int rc, nl_byte = 1, null_record = 0, pad = 0;
|
int rc, nl_byte = 1, null_record = 0, pad = 0;
|
||||||
struct file *f = get_fobj(fi);
|
|
||||||
ssize_t rsize;
|
ssize_t rsize;
|
||||||
|
|
||||||
(void) path;
|
|
||||||
|
|
||||||
if (cmsfs.readonly)
|
|
||||||
return -EROFS;
|
|
||||||
|
|
||||||
if (!f->linefeed)
|
|
||||||
return do_write(f, buf, size, offset);
|
|
||||||
|
|
||||||
/* remove already committed bytes */
|
/* remove already committed bytes */
|
||||||
offset -= f->wcache_commited;
|
offset -= f->wcache_commited;
|
||||||
|
|
||||||
@@ -4222,7 +4234,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* translate */
|
/* 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)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -4232,6 +4244,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
|||||||
*/
|
*/
|
||||||
if (!f->wcache_used) {
|
if (!f->wcache_used) {
|
||||||
*f->wcache = FILLER_EBCDIC;
|
*f->wcache = FILLER_EBCDIC;
|
||||||
|
*f->iconv_buf = FILLER_EBCDIC;
|
||||||
f->wcache_used = 1;
|
f->wcache_used = 1;
|
||||||
nl_byte = 0;
|
nl_byte = 0;
|
||||||
null_record = 1;
|
null_record = 1;
|
||||||
@@ -4242,7 +4255,7 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
|||||||
offset += f->pad_bytes;
|
offset += f->pad_bytes;
|
||||||
BUG(offset < 0);
|
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)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -4257,6 +4270,36 @@ static int cmsfs_write(const char *path, const char *buf, size_t size,
|
|||||||
return rc;
|
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)
|
static int cmsfs_unlink(const char *path)
|
||||||
{
|
{
|
||||||
struct fst_entry fst;
|
struct fst_entry fst;
|
||||||
@@ -4284,7 +4327,7 @@ static int flush_wcache(struct file *f)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* translate */
|
/* 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)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -4292,7 +4335,7 @@ static int flush_wcache(struct file *f)
|
|||||||
offset -= (f->fst->nr_records - f->null_records);
|
offset -= (f->fst->nr_records - f->null_records);
|
||||||
BUG(offset < 0);
|
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);
|
purge_wcache(f);
|
||||||
f->null_records = 0;
|
f->null_records = 0;
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
@@ -4415,6 +4458,7 @@ static void destroy_file_object(struct file *f)
|
|||||||
struct record *rec;
|
struct record *rec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
free(f->iconv_buf);
|
||||||
free(f->wcache);
|
free(f->wcache);
|
||||||
free(f->wstate);
|
free(f->wstate);
|
||||||
|
|
||||||
@@ -4498,14 +4542,23 @@ static int cmsfs_process_args(void *data, const char *arg, int key,
|
|||||||
return 1;
|
return 1;
|
||||||
case KEY_HELP:
|
case KEY_HELP:
|
||||||
usage(outargs->argv[0]);
|
usage(outargs->argv[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usage output needs to go to stdout to be consistent with
|
||||||
|
* coding guidelines. FUSE versions before 3.0.0 print help
|
||||||
|
* output to stderr. Redirect stderr to stdout here to enforce
|
||||||
|
* consistent behavior.
|
||||||
|
*/
|
||||||
|
fflush(stderr);
|
||||||
|
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||||
|
|
||||||
fuse_opt_add_arg(outargs, "-ho");
|
fuse_opt_add_arg(outargs, "-ho");
|
||||||
cmsfs_fuse_main(outargs, &cmsfs_oper);
|
cmsfs_fuse_main(outargs, &cmsfs_oper);
|
||||||
exit(0);
|
exit(0);
|
||||||
case KEY_VERSION:
|
case KEY_VERSION:
|
||||||
fprintf(stderr, COMP "FUSE file system for CMS disks "
|
fprintf(stdout, COMP "FUSE file system for CMS disks "
|
||||||
"program version %s\n", RELEASE_STRING);
|
"program version %s\n", RELEASE_STRING);
|
||||||
fprintf(stderr, "Copyright IBM Corp. 2010, 2017\n");
|
fprintf(stdout, "Copyright IBM Corp. 2010, 2017\n");
|
||||||
fuse_opt_add_arg(outargs, "--version");
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#include "cmsfs-fuse.h"
|
#include "cmsfs-fuse.h"
|
||||||
@@ -65,7 +66,7 @@ static void add_filetype(char *name, struct util_list *list)
|
|||||||
entry = malloc(sizeof(*entry));
|
entry = malloc(sizeof(*entry));
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
DIE_PERROR("malloc failed");
|
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);
|
util_list_add_head(list, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
common.mak
13
common.mak
@@ -5,8 +5,8 @@ COMMON_INCLUDED = true
|
|||||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
RELEASE = 6
|
RELEASE = 7
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 1
|
||||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
export S390_TOOLS_RELEASE
|
export S390_TOOLS_RELEASE
|
||||||
@@ -182,9 +182,10 @@ GROUP = $(shell id -gn)
|
|||||||
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
|
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
|
||||||
|
|
||||||
# Special defines for zfcpdump
|
# Special defines for zfcpdump
|
||||||
ZFCPDUMP_PART_IMAGE = zfcpdump_part.image
|
ZFCPDUMP_IMAGE = zfcpdump-image
|
||||||
ZFCPDUMP_PART_RD = zfcpdump_part.rd
|
ZFCPDUMP_INITRD = zfcpdump-initrd
|
||||||
export ZFCPDUMP_DIR ZFCPDUMP_PART_IMAGE ZFCPDUMP_PART_RD
|
ZFCPDUMP_FLAVOR = zfcpdump
|
||||||
|
export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_INITRD ZFCPDUMP_FLAVOR
|
||||||
|
|
||||||
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
CFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||||
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
HOSTCFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||||
@@ -239,7 +240,7 @@ endif
|
|||||||
$(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
|
$(CXX) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
%: %.o
|
%: %.o
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
%.a:
|
%.a:
|
||||||
$(AR) rcs $@ $^
|
$(AR) rcs $@ $^
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ LDLIBS += -lm
|
|||||||
OBJECTS = daemon.o cpu.o info.o terms.o config.o main.o getopt.o mem.o
|
OBJECTS = daemon.o cpu.o info.o terms.o config.o main.o getopt.o mem.o
|
||||||
|
|
||||||
cpuplugd: $(OBJECTS)
|
cpuplugd: $(OBJECTS)
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f cpuplugd $(OBJECTS)
|
rm -f cpuplugd $(OBJECTS)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Config file parsing
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -201,6 +201,7 @@ void parse_configfile(char *file)
|
|||||||
linebuffer);
|
linebuffer);
|
||||||
parse_configline(linebuffer);
|
parse_configline(linebuffer);
|
||||||
}
|
}
|
||||||
|
fclose(filp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Print DASD uid
|
|||||||
This option prints the full uid of the DASD. When z/VM provides two
|
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
|
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
|
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
|
different minidisks. You need both support in the Linux kernel and
|
||||||
z/VM to receive such an additional token.
|
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"
|
.BI "-u|--uid"
|
||||||
Print DASD uid without z/VM minidisk token
|
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
|
between different minidisks (see --extended-uid option). To remain
|
||||||
compatibile with systems that were installed on older Linux or z/VM
|
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
|
levels, the -u option will print the uid excluding any z/VM-provided
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "lib/dasd_base.h"
|
#include "lib/dasd_base.h"
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
#include "lib/util_file.h"
|
#include "lib/util_file.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_opt.h"
|
#include "lib/util_opt.h"
|
||||||
#include "lib/util_prg.h"
|
#include "lib/util_prg.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
@@ -192,18 +193,18 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
|
|||||||
char *space;
|
char *space;
|
||||||
|
|
||||||
if (dasd_get_blocksize(device, &blksize) != 0) {
|
if (dasd_get_blocksize(device, &blksize) != 0) {
|
||||||
printf("Unable to figure out block size.\n");
|
warnx("Unable to figure out block size");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dasd_get_info(device, &dasd_info) != 0) {
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = open(device, O_RDONLY);
|
f = open(device, O_RDONLY);
|
||||||
if (f < 0) {
|
if (f < 0) {
|
||||||
printf("Could not open device node.\n");
|
warnx("Could not open device node");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +215,7 @@ static int dinfo_read_dasd_vlabel(char *device, struct volume_label *vlabel,
|
|||||||
bzero(vlabel, vlsize);
|
bzero(vlabel, vlsize);
|
||||||
|
|
||||||
if (read(f, vlabel, vlsize) != vlsize) {
|
if (read(f, vlabel, vlsize) != vlsize) {
|
||||||
printf("Could not read volume label.\n");
|
warnx("Could not read volume label");
|
||||||
goto error_close;
|
goto error_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,10 +256,9 @@ static void *dinfo_malloc(size_t size)
|
|||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
result = malloc(size);
|
result = malloc(size);
|
||||||
if (result == NULL) {
|
if (result == NULL)
|
||||||
printf("Could not allocate %lld bytes of memory",
|
warnx("Could not allocate %lu bytes of memory", size);
|
||||||
(unsigned long long)size);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,16 +318,14 @@ static int dinfo_create_devnode(dev_t dev, char **devno)
|
|||||||
free(result);
|
free(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("Error: Unable to create temporary device node");
|
warnx("Error: Unable to create temporary device node");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dinfo_free_devnode(char *device)
|
static void dinfo_free_devnode(char *device)
|
||||||
{
|
{
|
||||||
if (remove(device)) {
|
if (remove(device))
|
||||||
printf("Warning: Could not remove "
|
warnx("Warning: Could not remove temporary file %s", device);
|
||||||
"temporary file %s", device);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dinfo_extract_dev(dev_t *dev, char *str)
|
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;
|
int ma, mi;
|
||||||
|
|
||||||
bzero(tmp, RD_BUFFER_SIZE);
|
bzero(tmp, RD_BUFFER_SIZE);
|
||||||
strncpy(tmp, str, RD_BUFFER_SIZE);
|
util_strlcpy(tmp, str, RD_BUFFER_SIZE);
|
||||||
p = strchr(tmp, ':');
|
p = strchr(tmp, ':');
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
printf("Error: unable to extract major/minor\n");
|
warnx("Error: unable to extract major/minor");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +357,7 @@ static int dinfo_get_dev_from_blockdev(char *blockdev, dev_t *dev)
|
|||||||
|
|
||||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||||
if (!readbuf) {
|
if (!readbuf) {
|
||||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
warnx("Error: Not enough memory to allocate readbuffer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (util_file_read_line(readbuf, RD_BUFFER_SIZE,
|
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;
|
int rc = 0;
|
||||||
|
|
||||||
if (stat(devnode, &stat_buffer) != 0) {
|
if (stat(devnode, &stat_buffer) != 0) {
|
||||||
printf("Error: could not stat %s\n", devnode);
|
warnx("Error: could not stat %s", devnode);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,13 +497,13 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
|||||||
|
|
||||||
directory = opendir("/sys/block/");
|
directory = opendir("/sys/block/");
|
||||||
if (directory == NULL) {
|
if (directory == NULL) {
|
||||||
printf("Error: could not open directory /sys/block\n");
|
warnx("Error: could not open directory /sys/block");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
readbuf = dinfo_malloc(RD_BUFFER_SIZE);
|
||||||
if (!readbuf) {
|
if (!readbuf) {
|
||||||
printf("Error: Not enough memory to allocate readbuffer\n");
|
warnx("Error: Not enough memory to allocate readbuffer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,25 +605,23 @@ int main(int argc, char *argv[])
|
|||||||
sscanf(uname_buf.release, "%d.%d", &version, &release);
|
sscanf(uname_buf.release, "%d.%d", &version, &release);
|
||||||
if (strcmp(uname_buf.sysname, "Linux") ||
|
if (strcmp(uname_buf.sysname, "Linux") ||
|
||||||
version < 2 || (version == 2 && release < 6)) {
|
version < 2 || (version == 2 && release < 6)) {
|
||||||
printf("%s %d.%d is not supported\n", uname_buf.sysname,
|
warnx("%s %d.%d is not supported", uname_buf.sysname,
|
||||||
version, release);
|
version, release);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!busid && !blockdev && !devnode) {
|
if (!busid && !blockdev && !devnode) {
|
||||||
printf("Error: please specify a device using either -b, -i "
|
warnx("Error: please specify a device using either -b, -i or -d");
|
||||||
"or -d\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((busid && blockdev) || (busid && devnode) || (blockdev && devnode)) {
|
if ((busid && blockdev) || (busid && devnode) || (blockdev && devnode)) {
|
||||||
printf("Error: please specify device only once, either -b, -i "
|
warnx("Error: please specify device only once, either -b, -i or -d");
|
||||||
"or -d\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!print_uid && !print_extended_uid && !print_vlabel) {
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,7 +714,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
printf("Error: could not read unique DASD ID\n");
|
warnx("Error: could not read unique DASD ID");
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|||||||
@@ -618,7 +618,7 @@ dasdview_print_volser(dasdview_info_t *info)
|
|||||||
strncpy(volser, vlabel.volid, 6);
|
strncpy(volser, vlabel.volid, 6);
|
||||||
vtoc_ebcdic_dec(volser, volser, 6);
|
vtoc_ebcdic_dec(volser, volser, 6);
|
||||||
} else {
|
} else {
|
||||||
strncpy(volser, " ", 6);
|
memcpy(volser, " ", 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%6.6s\n", volser);
|
printf("%6.6s\n", volser);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static void set_time(char *dest, size_t len, time_t value)
|
|||||||
#define SET_TIME_FIELD(obj, name, value) \
|
#define SET_TIME_FIELD(obj, name, value) \
|
||||||
set_time((obj)->name, sizeof((obj)->name), (time_t) (value))
|
set_time((obj)->name, sizeof((obj)->name), (time_t) (value))
|
||||||
#define SET_STR_FIELD(obj, name, 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 */
|
/* Initialize the tar file @header with the provided data */
|
||||||
static void init_header(struct tar_header *header, const char *filename,
|
static void init_header(struct tar_header *header, const char *filename,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* fdasd - Create or modify partitions on ECKD DASDs
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -258,7 +258,7 @@ static void fdasd_check_volser(char *volser, int devno)
|
|||||||
{
|
{
|
||||||
int from, to;
|
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 &&
|
if ((volser[from] >= 0x23 &&
|
||||||
volser[from] <= 0x25) || /* # $ % */
|
volser[from] <= 0x25) || /* # $ % */
|
||||||
(volser[from] >= 0x30 &&
|
(volser[from] >= 0x30 &&
|
||||||
@@ -727,9 +727,9 @@ static int fdasd_parse_conffile(fdasd_anchor_t *anc,
|
|||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
rc = read(fd, buffer, sizeof(buffer) - 1);
|
rc = read(fd, buffer, sizeof(buffer) - 1);
|
||||||
|
close(fd);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
return -1;
|
||||||
close(fd);
|
|
||||||
|
|
||||||
for (i = 0; i < rc; i++)
|
for (i = 0; i < rc; i++)
|
||||||
buffer[i] = toupper(buffer[i]);
|
buffer[i] = toupper(buffer[i]);
|
||||||
@@ -1257,7 +1257,7 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
|
|||||||
printf("DSCBs: ");
|
printf("DSCBs: ");
|
||||||
|
|
||||||
blk = (cchhb2blk(&anc->vlabel->vtoc, &geo) - 1) * anc->blksize;
|
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, "");
|
fdasd_error(anc, vlabel_corrupted, "");
|
||||||
maxblk = blk + anc->blksize * 9; /* f4+f5+f7+3*f8+3*f9 */
|
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] = ' ';
|
volser[VOLSER_LENGTH] = ' ';
|
||||||
strncpy(c1, volser, VOLSER_LENGTH + 1);
|
strncpy(c1, volser, VOLSER_LENGTH + 1);
|
||||||
c1 = strchr(ch, ' ');
|
c1 = strchr(ch, ' ');
|
||||||
strncpy(c1, s2, 31);
|
memcpy(c1, s2, 31);
|
||||||
} else {
|
} else {
|
||||||
if (get_part_type_by_dsname(ch, &part_info->type))
|
if (get_part_type_by_dsname(ch, &part_info->type))
|
||||||
part_info->type = PARTITION_NATIVE;
|
part_info->type = PARTITION_NATIVE;
|
||||||
@@ -1321,23 +1321,23 @@ static void fdasd_write_vtoc_labels(fdasd_anchor_t *anc)
|
|||||||
|
|
||||||
setpos(anc, k, i - 1);
|
setpos(anc, k, i - 1);
|
||||||
|
|
||||||
strncpy(ch, "LINUX.V "
|
memcpy(ch, "LINUX.V "
|
||||||
" ", 44);
|
" ", 44);
|
||||||
|
|
||||||
strncpy(volser, anc->vlabel->volid, VOLSER_LENGTH);
|
strncpy(volser, anc->vlabel->volid, VOLSER_LENGTH);
|
||||||
vtoc_ebcdic_dec(volser, volser, VOLSER_LENGTH);
|
vtoc_ebcdic_dec(volser, volser, VOLSER_LENGTH);
|
||||||
strncpy(c1, volser, VOLSER_LENGTH);
|
memcpy(c1, volser, VOLSER_LENGTH);
|
||||||
|
|
||||||
c1 = strchr(ch, ' ');
|
c1 = strchr(ch, ' ');
|
||||||
strncpy(c1, ".PART", 5);
|
memcpy(c1, ".PART", 5);
|
||||||
c1 += 5;
|
c1 += 5;
|
||||||
|
|
||||||
sprintf(dsno, "%04d.", k + 1);
|
sprintf(dsno, "%04d.", k + 1);
|
||||||
strncpy(c1, dsno, 5);
|
memcpy(c1, dsno, 5);
|
||||||
c1 += 5;
|
c1 += 5;
|
||||||
|
|
||||||
get_part_dsname_by_type(part_info->type, &dsname);
|
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);
|
vtoc_ebcdic_enc(ch, ch, 44);
|
||||||
if (anc->verbose)
|
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;
|
ch = strstr(part_info->f1->DS1DSNAM, "PART") + 9;
|
||||||
if (ch != NULL)
|
if (ch != NULL)
|
||||||
strncpy(ch, str, 6);
|
memcpy(ch, str, 6);
|
||||||
vtoc_ebcdic_enc(part_info->f1->DS1DSNAM, part_info->f1->DS1DSNAM, 44);
|
vtoc_ebcdic_enc(part_info->f1->DS1DSNAM, part_info->f1->DS1DSNAM, 44);
|
||||||
anc->vtoc_changed++;
|
anc->vtoc_changed++;
|
||||||
}
|
}
|
||||||
@@ -1994,7 +1994,7 @@ static int fdasd_check_volume(fdasd_anchor_t *anc)
|
|||||||
printf(" VOL1\n");
|
printf(" VOL1\n");
|
||||||
|
|
||||||
blk = (cchhb2blk(&vlabel->vtoc, &geo) - 1) * anc->blksize;
|
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);
|
rc = fdasd_valid_vtoc_pointer(anc, blk);
|
||||||
|
|
||||||
if (anc->print_table && (rc < 0))
|
if (anc->print_table && (rc < 0))
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ LDLIBS += $(FUSE_LDLIBS) -lpthread -lrt -ldl -lm
|
|||||||
|
|
||||||
OBJECTS = hmcdrvfs.o
|
OBJECTS = hmcdrvfs.o
|
||||||
|
|
||||||
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
all: check_dep hmcdrvfs
|
all: check_dep hmcdrvfs
|
||||||
|
|
||||||
$(OBJECTS): Makefile
|
$(OBJECTS): Makefile
|
||||||
|
|
||||||
hmcdrvfs: $(OBJECTS)
|
hmcdrvfs: $(OBJECTS) $(libs)
|
||||||
|
|
||||||
install: all install-scripts
|
install: all install-scripts
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 hmcdrvfs \
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 hmcdrvfs \
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#define HMCDRV_FUSE_LOGNAME "hmcdrvfs" /* log prefix */
|
#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);
|
fp->symlnk = malloc(HMCDRV_FUSE_MAXPATH);
|
||||||
|
|
||||||
if (fp->symlnk != NULL) {
|
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';
|
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;
|
current_offset += retlen;
|
||||||
strncpy(last_ftpcmd, fp->ftpcmd, HMCDRV_FUSE_MAXCMDLEN);
|
util_strlcpy(last_ftpcmd, fp->ftpcmd, HMCDRV_FUSE_MAXCMDLEN);
|
||||||
last_ftpcmd[HMCDRV_FUSE_MAXCMDLEN - 1] = '\0';
|
|
||||||
return retlen;
|
return retlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,13 +853,12 @@ static char *hmcdrv_parse_line(char *line, char *namebuf,
|
|||||||
*arrow = '\0';
|
*arrow = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(namebuf, attr.fname, bufsize);
|
util_strlcpy(namebuf, attr.fname, bufsize);
|
||||||
namebuf[bufsize - 1] = '\0'; /* safety */
|
|
||||||
|
|
||||||
if (arrow == NULL) {
|
if (arrow == NULL) {
|
||||||
symlink[0] = '\0';
|
symlink[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
strncpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
|
util_strlcpy(symlink, arrow + 4, HMCDRV_FUSE_MAXPATH);
|
||||||
*arrow = ' '; /* restore */
|
*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)) {
|
if (!S_ISLNK(fp->st.st_mode)) {
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
strncpy(buf, fp->symlnk, size);
|
util_strlcpy(buf, fp->symlnk, size);
|
||||||
buf[size - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1338,7 +1336,7 @@ static int hmcdrv_fuse_main(struct fuse_args *args)
|
|||||||
*/
|
*/
|
||||||
static void hmcdrv_fuse_usage(const char *progname)
|
static void hmcdrv_fuse_usage(const char *progname)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stdout,
|
||||||
"Usage: %s MOUNTPOINT [OPTIONS]\n\n"
|
"Usage: %s MOUNTPOINT [OPTIONS]\n\n"
|
||||||
"Use the %s command to read files from a HMC drive DVD.\n"
|
"Use the %s command to read files from a HMC drive DVD.\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -1450,7 +1448,7 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case HMCDRV_FUSE_OPTKEY_VERSION:
|
case HMCDRV_FUSE_OPTKEY_VERSION:
|
||||||
fprintf(stderr, HMCDRV_FUSE_LOGHEAD
|
fprintf(stdout, HMCDRV_FUSE_LOGHEAD
|
||||||
"HMC drive DVD file system, version %s\n"
|
"HMC drive DVD file system, version %s\n"
|
||||||
"Copyright IBM Corp. 2015, 2017\n",
|
"Copyright IBM Corp. 2015, 2017\n",
|
||||||
HMCDRV_FUSE_RELEASE);
|
HMCDRV_FUSE_RELEASE);
|
||||||
@@ -1458,6 +1456,16 @@ static int hmcdrv_fuse_optproc(void *data, const char *arg,
|
|||||||
|
|
||||||
case HMCDRV_FUSE_OPTKEY_HELP:
|
case HMCDRV_FUSE_OPTKEY_HELP:
|
||||||
hmcdrv_fuse_usage(outargs->argv[0]);
|
hmcdrv_fuse_usage(outargs->argv[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usage output needs to go to stdout to be consistent with
|
||||||
|
* coding guidelines. FUSE versions before 3.0.0 print help
|
||||||
|
* output to stderr. Redirect stderr to stdout here to enforce
|
||||||
|
* consistent behavior.
|
||||||
|
*/
|
||||||
|
fflush(stderr);
|
||||||
|
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||||
|
|
||||||
fuse_opt_add_arg(outargs, "-ho");
|
fuse_opt_add_arg(outargs, "-ho");
|
||||||
hmcdrv_fuse_main(outargs);
|
hmcdrv_fuse_main(outargs);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|||||||
@@ -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)
|
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(hdr->sys_name, name, LPAR_NAME_LEN);
|
||||||
ht_ebcdic_to_ascii(name, LPAR_NAME_LEN);
|
|
||||||
name[LPAR_NAME_LEN] = 0;
|
name[LPAR_NAME_LEN] = 0;
|
||||||
ht_strstrip(name);
|
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_state_set(cpu, SD_CPU_STATE_UNKNOWN);
|
||||||
}
|
}
|
||||||
sd_cpu_mgm_time_us_set(cpu, cpu_info->mgm_time);
|
sd_cpu_mgm_time_us_set(cpu, cpu_info->mgm_time);
|
||||||
sd_cpu_real_type_set(cpu, cpu_type);
|
|
||||||
sd_cpu_commit(cpu);
|
sd_cpu_commit(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,8 +245,7 @@ static void l_sd_sys_root_fill(struct sd_sys *sys)
|
|||||||
struct sd_sys *guest;
|
struct sd_sys *guest;
|
||||||
|
|
||||||
guest_name[NAME_LEN] = 0;
|
guest_name[NAME_LEN] = 0;
|
||||||
memcpy(guest_name, data->guest_name, NAME_LEN);
|
ht_ebcdic_to_ascii(data->guest_name, guest_name, NAME_LEN);
|
||||||
ht_ebcdic_to_ascii(guest_name, NAME_LEN);
|
|
||||||
ht_strstrip(guest_name);
|
ht_strstrip(guest_name);
|
||||||
|
|
||||||
guest = sd_sys_get(sys, 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
|
* 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 <sys/types.h>
|
||||||
|
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#define G0(x) MAX(0, (s64) (x))
|
#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 char *ht_strdup(const char *str);
|
||||||
extern void ht_print_head(const char *sys);
|
extern void ht_print_head(const char *sys);
|
||||||
extern void ht_print_help_icon(void);
|
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 char *ht_mount_point_get(const char *fs_type);
|
||||||
extern u64 ht_ext_tod_2_us(void *tod_ext);
|
extern u64 ht_ext_tod_2_us(void *tod_ext);
|
||||||
extern void ht_print_time(void);
|
extern void ht_print_time(void);
|
||||||
|
|||||||
@@ -195,7 +195,6 @@ struct sd_cpu {
|
|||||||
struct sd_info i;
|
struct sd_info i;
|
||||||
char id[9];
|
char id[9];
|
||||||
struct sd_cpu_type *type;
|
struct sd_cpu_type *type;
|
||||||
char real_type[CPU_TYPE_ID_LEN];
|
|
||||||
struct sd_cpu_info d1;
|
struct sd_cpu_info d1;
|
||||||
struct sd_cpu_info d2;
|
struct sd_cpu_info d2;
|
||||||
struct sd_cpu_info *d_cur;
|
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;
|
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)
|
static inline void sd_cpu_cpu_time_us_set(struct sd_cpu *cpu, u64 value)
|
||||||
{
|
{
|
||||||
cpu->d_cur->cpu_time_us = 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 = ht_zalloc(sizeof(*cpu));
|
||||||
cpu->i.parent = parent;
|
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->type = l_cpu_type_by_id(type);
|
||||||
cpu->d_cur = &cpu->d1;
|
cpu->d_cur = &cpu->d1;
|
||||||
cpu->cnt = cnt;
|
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;
|
struct sd_sys *sys_new;
|
||||||
|
|
||||||
sys_new = ht_zalloc(sizeof(*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->child_list, struct sd_sys, list);
|
||||||
util_list_init(&sys_new->cpu_list, struct sd_cpu, 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;
|
struct table_mark_key *key;
|
||||||
|
|
||||||
key = ht_zalloc(sizeof(*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);
|
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;
|
struct table_row *row;
|
||||||
|
|
||||||
row = l_selected_row(t);
|
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 line_cpy[TBOX_MAX_STR + 1];
|
||||||
char *ptr_old, *ptr;
|
char *ptr_old, *ptr;
|
||||||
|
|
||||||
strncpy(line_cpy, line, sizeof(line_cpy));
|
util_strlcpy(line_cpy, line, sizeof(line_cpy));
|
||||||
ptr_old = ptr = line_cpy;
|
ptr_old = ptr = line_cpy;
|
||||||
do {
|
do {
|
||||||
ptr = strchr(ptr, '\\');
|
ptr = strchr(ptr, '\\');
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ void win_sys_set(const char *sys_id)
|
|||||||
{
|
{
|
||||||
if (l_initialized)
|
if (l_initialized)
|
||||||
table_reset(l_t);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ static inline void util_ptr_vec_free(void **ptr_vec, int count)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!ptr_vec || count < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
free(ptr_vec[i]);
|
free(ptr_vec[i]);
|
||||||
free(ptr_vec);
|
free(ptr_vec);
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ char *util_strcat_realloc(char *str1, const char *str2);
|
|||||||
void util_str_toupper(char *str);
|
void util_str_toupper(char *str);
|
||||||
|
|
||||||
char *util_strstrip(char *s);
|
char *util_strstrip(char *s);
|
||||||
|
size_t util_strlcpy(char *dest, const char *src, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ include ../common.mak
|
|||||||
|
|
||||||
all: xcec-bridge
|
all: xcec-bridge
|
||||||
|
|
||||||
xcec-bridge: xcec-bridge.o
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
|
xcec-bridge: xcec-bridge.o $(libs)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o core xcec-bridge
|
rm -f *.o core xcec-bridge
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
/* a signal causes the interfaces to be re-checked */
|
/* a signal causes the interfaces to be re-checked */
|
||||||
@@ -40,7 +41,7 @@
|
|||||||
|
|
||||||
#define UPDATE_SIGNAL SIGUSR1
|
#define UPDATE_SIGNAL SIGUSR1
|
||||||
|
|
||||||
#define DEV_NAME_LEN IFNAMSIZ
|
#define DEV_NAME_SIZE IFNAMSIZ
|
||||||
|
|
||||||
#define BUFFER_LEN 65536
|
#define BUFFER_LEN 65536
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ struct int_sock {
|
|||||||
int features;
|
int features;
|
||||||
int i_fd;
|
int i_fd;
|
||||||
int o_fd;
|
int o_fd;
|
||||||
char dev_name[DEV_NAME_LEN];
|
char dev_name[DEV_NAME_SIZE];
|
||||||
int mtu_warning;
|
int mtu_warning;
|
||||||
|
|
||||||
struct int_sock *next;
|
struct int_sock *next;
|
||||||
@@ -91,7 +92,7 @@ int open_incoming_socket(char *dev_name)
|
|||||||
return -1;
|
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);
|
retval=ioctl(fd,SIOCGIFINDEX,&if_req);
|
||||||
if (retval==-1) {
|
if (retval==-1) {
|
||||||
syslog(LOG_ERR,"can't ioctl on raw packet socket, " \
|
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)
|
int interface_in_list(struct int_sock *item,struct int_sock *list)
|
||||||
{
|
{
|
||||||
for (;list;list=list->next) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,7 +282,7 @@ int read_sys(struct int_sock **nlist)
|
|||||||
do_broadcast_bridging=0;
|
do_broadcast_bridging=0;
|
||||||
|
|
||||||
is->mtu_warning=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)) {
|
if (!strncmp(if_name,"hsi",3)) {
|
||||||
is->features=I_S_FEATURE_PASSTHROUGH;
|
is->features=I_S_FEATURE_PASSTHROUGH;
|
||||||
}
|
}
|
||||||
@@ -317,7 +318,7 @@ void update_interfaces()
|
|||||||
prev=NULL;
|
prev=NULL;
|
||||||
while (j) {
|
while (j) {
|
||||||
if (!strncmp(j->dev_name,i->dev_name,
|
if (!strncmp(j->dev_name,i->dev_name,
|
||||||
DEV_NAME_LEN)) {
|
DEV_NAME_SIZE)) {
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
select_set.i_s_list=j->next;
|
select_set.i_s_list=j->next;
|
||||||
} else {
|
} else {
|
||||||
@@ -360,7 +361,7 @@ void update_interfaces()
|
|||||||
continue;
|
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->i_fd=i_fd;
|
||||||
new_int->o_fd=o_fd;
|
new_int->o_fd=o_fd;
|
||||||
new_int->features=i->features;
|
new_int->features=i->features;
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
all: chreipl lsreipl chshut lsshut
|
all: chreipl lsreipl chshut lsshut
|
||||||
|
|
||||||
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
objects = main.o ccw.o fcp.o system.o shutdown.o \
|
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
|
cmd_lsshut.o cmd_chshut.o cmd_lsreipl.o cmd_chreipl.o proc.o
|
||||||
|
|
||||||
chreipl: $(objects)
|
chreipl: $(objects) $(libs)
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
lsreipl:
|
lsreipl:
|
||||||
ln -sf chreipl lsreipl
|
ln -sf chreipl lsreipl
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#include "ipl_tools.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);
|
ERR_EXIT("Bootprog \"%s\" is not a decimal number", bootprog);
|
||||||
if (bootprog_int > UINT_MAX)
|
if (bootprog_int > UINT_MAX)
|
||||||
ERR_EXIT("Invalid bootprog specified");
|
ERR_EXIT("Invalid bootprog specified");
|
||||||
strncpy(l.bootprog, bootprog, sizeof(l.bootprog));
|
util_strlcpy(l.bootprog, bootprog, sizeof(l.bootprog));
|
||||||
l.bootprog_set = 1;
|
l.bootprog_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +295,7 @@ static int set_reipl_type(const char *dev_name)
|
|||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
strncpy(l.dev, dev_name, sizeof(l.dev));
|
util_strlcpy(l.dev, dev_name, sizeof(l.dev));
|
||||||
dev_from_part(l.dev);
|
dev_from_part(l.dev);
|
||||||
l.dev_set = 1;
|
l.dev_set = 1;
|
||||||
return 0;
|
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])
|
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;
|
struct proc_dev_entry pde;
|
||||||
|
|
||||||
if (proc_dev_get_entry(dev, 1, &pde) != 0)
|
if (proc_dev_get_entry(dev, 1, &pde) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
snprintf(chreipl_helper, PATH_MAX,
|
util_asprintf(&chreipl_helper,
|
||||||
"%s/%s.%s", TOOLS_LIBDIR, "chreipl_helper", pde.name);
|
"%s/%s.%s", TOOLS_LIBDIR, "chreipl_helper", pde.name);
|
||||||
if (access(chreipl_helper, X_OK) != 0) {
|
if (access(chreipl_helper, X_OK) != 0) {
|
||||||
proc_dev_free_entry(&pde);
|
proc_dev_free_entry(&pde);
|
||||||
|
free(chreipl_helper);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sprintf(cmd, "%s %d:%d", chreipl_helper, major(dev), minor(dev));
|
sprintf(cmd, "%s %d:%d", chreipl_helper, major(dev), minor(dev));
|
||||||
proc_dev_free_entry(&pde);
|
proc_dev_free_entry(&pde);
|
||||||
|
free(chreipl_helper);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "ipl_tools.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)
|
void fcp_wwpn_get(const char *device, char *wwpn)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX], buf[4096];
|
char path[PATH_MAX], buf[20];
|
||||||
FILE *fh;
|
FILE *fh;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ void fcp_wwpn_get(const char *device, char *wwpn)
|
|||||||
rc = fscanf(fh, "%s", buf);
|
rc = fscanf(fh, "%s", buf);
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
ERR_EXIT("Could not lookup WWPN \"%s\"", path);
|
ERR_EXIT("Could not lookup WWPN \"%s\"", path);
|
||||||
strncpy(wwpn, buf, 20);
|
util_strlcpy(wwpn, buf, 20);
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ void fcp_wwpn_get(const char *device, char *wwpn)
|
|||||||
*/
|
*/
|
||||||
void fcp_lun_get(const char *device, char *lun)
|
void fcp_lun_get(const char *device, char *lun)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX], buf[4096];
|
char path[PATH_MAX], buf[20];
|
||||||
FILE *fh;
|
FILE *fh;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ void fcp_lun_get(const char *device, char *lun)
|
|||||||
rc = fscanf(fh, "%s", buf);
|
rc = fscanf(fh, "%s", buf);
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
ERR_EXIT("Could not lookup LUN \"%s\"", path);
|
ERR_EXIT("Could not lookup LUN \"%s\"", path);
|
||||||
strncpy(lun, buf, 20);
|
util_strlcpy(lun, buf, 20);
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#include "ipl_tools.h"
|
#include "ipl_tools.h"
|
||||||
|
|
||||||
struct globals g;
|
struct globals g;
|
||||||
@@ -31,7 +33,7 @@ void __noreturn print_version_exit(void)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
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) {
|
if (strstr(argv[0], "chreipl") != NULL) {
|
||||||
cmd_chreipl(argc, argv);
|
cmd_chreipl(argc, argv);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "ipl_tools.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)
|
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);
|
util_asprintf(&path, "/sys/firmware/%s", file);
|
||||||
return read_str(string, path, len);
|
read_str(string, path, len);
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -75,9 +75,11 @@ static const struct tool_info iucv_tool[2] = {
|
|||||||
static void __noreturn usage_exit(const struct tool_info *prg, int is_error,
|
static void __noreturn usage_exit(const struct tool_info *prg, int is_error,
|
||||||
const char *msg)
|
const char *msg)
|
||||||
{
|
{
|
||||||
|
FILE *file = is_error ? stderr : stdout;
|
||||||
|
|
||||||
if (msg != NULL)
|
if (msg != NULL)
|
||||||
fprintf(stderr, _("%s: %s\n"), prg->name, msg);
|
fprintf(file, _("%s: %s\n"), prg->name, msg);
|
||||||
fprintf(stderr, _(prg->usage), prg->name, prg->name);
|
fprintf(file, _(prg->usage), prg->name, prg->name);
|
||||||
exit(is_error ? 1 : 0); /* rc=1 .. invalid args */
|
exit(is_error ? 1 : 0); /* rc=1 .. invalid args */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ all: $(lib)
|
|||||||
|
|
||||||
objects = dasd_sys.o dasd_ioctl.o
|
objects = dasd_sys.o dasd_ioctl.o
|
||||||
|
|
||||||
$(lib): $(objects) Makefile
|
$(lib): $(objects)
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ lib = libu2s.a
|
|||||||
|
|
||||||
all: $(lib)
|
all: $(lib)
|
||||||
|
|
||||||
objects = u2s.o misc.o
|
objects = u2s.o
|
||||||
|
|
||||||
$(lib): $(objects)
|
$(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 <wait.h>
|
||||||
|
|
||||||
#include "lib/u2s.h"
|
#include "lib/u2s.h"
|
||||||
#include "misc.h"
|
#include "lib/util_libc.h"
|
||||||
|
|
||||||
#define DEV_BUFFER_LENGTH 20
|
#define DEV_BUFFER_LENGTH 20
|
||||||
#define PATH_BUFFER_LENGTH 256
|
#define PATH_BUFFER_LENGTH 256
|
||||||
@@ -113,7 +113,7 @@ static int extract_busid(char *name, char *busid) {
|
|||||||
if (!start)
|
if (!start)
|
||||||
return -1;
|
return -1;
|
||||||
start++;
|
start++;
|
||||||
len = misc_strlcpy(busid, start, BUSIDSIZE);
|
len = util_strlcpy(busid, start, BUSIDSIZE);
|
||||||
if (len >= BUSIDSIZE)
|
if (len >= BUSIDSIZE)
|
||||||
return -1;
|
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",
|
while (fscanf(filp, "%[^(] %*[^)] ) at ( %d : %d %*[^\n]\n",
|
||||||
bus, &majb, &minb) != EOF) {
|
bus, &majb, &minb) != EOF) {
|
||||||
if ((maja == majb) && (mina == minb)) {
|
if ((maja == majb) && (mina == minb)) {
|
||||||
len = misc_strlcpy(busid, bus, BUSIDSIZE);
|
len = util_strlcpy(busid, bus, BUSIDSIZE);
|
||||||
if (len < BUSIDSIZE)
|
if (len < BUSIDSIZE)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ examples = util_base_example \
|
|||||||
util_prg_example \
|
util_prg_example \
|
||||||
util_rec_example
|
util_rec_example
|
||||||
|
|
||||||
all: $(lib) $(examples)
|
all: $(lib)
|
||||||
|
examples: $(lib) $(examples)
|
||||||
|
|
||||||
objects = util_base.o \
|
objects = util_base.o \
|
||||||
util_path.o \
|
util_path.o \
|
||||||
|
|||||||
@@ -228,3 +228,30 @@ char *util_strstrip(char *s)
|
|||||||
|
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ static void test_util_path_is_xxx(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Usage: util_path_example [sysfs mount point] | "is_xxx"
|
* Usage: util_path_example sysfs [MOUNT_POINT] | is_xxx
|
||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -111,6 +111,6 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
out_fail:
|
out_fail:
|
||||||
errx(EXIT_FAILURE, "Usage: %s sysfs <path> | is_xxx", argv[0]);
|
errx(EXIT_FAILURE, "Usage: %s sysfs [MOUNT_POINT] | is_xxx", argv[0]);
|
||||||
}
|
}
|
||||||
//! [code]
|
//! [code]
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ const struct util_prg prg = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct option opt_list[] = {
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ "version", no_argument, NULL, 'v' },
|
||||||
|
{ NULL, no_argument, NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Demonstrate the util_prg_print() functions
|
* Demonstrate the util_prg_print() functions
|
||||||
*/
|
*/
|
||||||
@@ -49,7 +55,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
util_prg_init(&prg);
|
util_prg_init(&prg);
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "vhe")) != -1) {
|
while ((opt = getopt_long(argc, argv, "vhe", opt_list, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'v':
|
case 'v':
|
||||||
util_prg_print_version();
|
util_prg_print_version();
|
||||||
|
|||||||
@@ -442,9 +442,9 @@ util_proc_dev_get_entry(dev_t device, int blockdev,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Provide one record form a /proc/mounts like file
|
* Provide one record from a /proc/mounts like file
|
||||||
*
|
*
|
||||||
* The parameter file_name distinguishes the file form procfs which
|
* The parameter file_name distinguishes the file from procfs which
|
||||||
* is read, the parameter spec is the selector for the record.
|
* is read, the parameter spec is the selector for the record.
|
||||||
*/
|
*/
|
||||||
int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
||||||
@@ -456,7 +456,6 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
|||||||
rc = get_file_buffer(&file, file_name);
|
rc = get_file_buffer(&file, file_name);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
rc = -1;
|
|
||||||
while (!eof(&file)) {
|
while (!eof(&file)) {
|
||||||
rc = scan_mnt_entry(&file, entry);
|
rc = scan_mnt_entry(&file, entry);
|
||||||
if (rc)
|
if (rc)
|
||||||
@@ -467,6 +466,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
|||||||
}
|
}
|
||||||
util_proc_mnt_free_entry(entry);
|
util_proc_mnt_free_entry(entry);
|
||||||
}
|
}
|
||||||
|
rc = -1;
|
||||||
out_free:
|
out_free:
|
||||||
free_file_buffer(&file);
|
free_file_buffer(&file);
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ static int __scandir(struct dirent ***de_vec, const char *path,
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
|
|
||||||
|
*de_vec = NULL;
|
||||||
dirp = opendir(path);
|
dirp = opendir(path);
|
||||||
if (!dirp)
|
if (!dirp)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -134,13 +135,13 @@ int util_scandir_hexsort(const struct dirent **de1, const struct dirent **de2)
|
|||||||
* directory entries. The entries as well as the pointer array itself are
|
* directory entries. The entries as well as the pointer array itself are
|
||||||
* allocated by the function and has to be released by the user via free.
|
* allocated by the function and has to be released by the user via free.
|
||||||
*
|
*
|
||||||
* @param[out] de_vec Vector of matched directory entries
|
* @param[out] de_vec Vector of matched directory entries, or NULL
|
||||||
* @param[in] compar_fn Callback function for sorting the entry list
|
* @param[in] compar_fn Callback function for sorting the entry list
|
||||||
* @param[in] path Path to the directory to scan
|
* @param[in] path Path to the directory to scan
|
||||||
* @param[in] fmt Format string, describes the search pattern as POSIX regex
|
* @param[in] fmt Format string, describes the search pattern as POSIX regex
|
||||||
* @param[in] ... Values for format string
|
* @param[in] ... Values for format string
|
||||||
*
|
*
|
||||||
* @returns Number of returned directory entries
|
* @returns Number of returned directory entries, or -1 on error
|
||||||
*/
|
*/
|
||||||
int util_scandir(struct dirent ***de_vec,
|
int util_scandir(struct dirent ***de_vec,
|
||||||
int compar_fn(const struct dirent **first,
|
int compar_fn(const struct dirent **first,
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ lib = libvmcp.a
|
|||||||
|
|
||||||
examples = vmcp_example
|
examples = vmcp_example
|
||||||
|
|
||||||
all: $(lib) $(examples)
|
all: $(lib)
|
||||||
|
examples: $(lib) $(examples)
|
||||||
|
|
||||||
objects = vmcp.o
|
objects = vmcp.o
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
const char *what(void) const { return msg; }
|
const char *what(void) const { return msg; }
|
||||||
int code(void) const { return errorCode; }
|
int code(void) const { return errorCode; }
|
||||||
protected:
|
protected:
|
||||||
char msg[200];
|
char msg[2048];
|
||||||
int errorCode;
|
int errorCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -98,19 +98,20 @@ VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
|
|||||||
dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
|
dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
|
char buf_asc[1024];
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf(stderr, "off=%d\n", adsrRecord.sec5_offset);
|
fprintf(stderr, "off=%d\n", adsrRecord.sec5_offset);
|
||||||
dump_seek(fh, adsrRecord.sec5_offset, SEEK_SET);
|
dump_seek(fh, adsrRecord.sec5_offset, SEEK_SET);
|
||||||
dump_read(buf, adsrRecord.sec5_len, 1, fh);
|
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++) {
|
for (i=0; i < adsrRecord.sec5_len; i++) {
|
||||||
if ((buf[i]==0) || iscntrl(buf[i]))
|
if ((buf_asc[i]==0) || iscntrl(buf_asc[i]))
|
||||||
buf[i]=' ';
|
buf_asc[i]=' ';
|
||||||
}
|
}
|
||||||
buf[adsrRecord.sec5_len] = 0;
|
buf_asc[adsrRecord.sec5_len] = 0;
|
||||||
printf("symptom string1: %s\n",buf);
|
printf("symptom string1: %s\n",buf_asc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record 2: fmbk */
|
/* Record 2: fmbk */
|
||||||
@@ -142,7 +143,8 @@ struct timeval VMDump::getDumpTime(void) const
|
|||||||
void VMDump::printDebug(void)
|
void VMDump::printDebug(void)
|
||||||
{
|
{
|
||||||
struct timeval time;
|
struct timeval time;
|
||||||
char buf[1024];
|
char fmbk_id[8];
|
||||||
|
char albk_id[8];
|
||||||
|
|
||||||
s390TodToTimeval(adsrRecord.tod, &time);
|
s390TodToTimeval(adsrRecord.tod, &time);
|
||||||
|
|
||||||
@@ -165,9 +167,9 @@ void VMDump::printDebug(void)
|
|||||||
|
|
||||||
/* fmbk */
|
/* fmbk */
|
||||||
|
|
||||||
ebcAsc(fmbkRecord.id, sizeof(fmbkRecord.id));
|
ebcAsc(fmbkRecord.id, fmbk_id, sizeof(fmbkRecord.id));
|
||||||
fmbkRecord.id[7] = 0;
|
fmbk_id[7] = 0;
|
||||||
printf("id : %s\n", fmbkRecord.id);
|
printf("id : %s\n", fmbk_id);
|
||||||
printf("fir rec nr: %i\n", fmbkRecord.rec_nr_fir);
|
printf("fir rec nr: %i\n", fmbkRecord.rec_nr_fir);
|
||||||
printf("vec rec nr: %i\n", fmbkRecord.rec_nr_vector);
|
printf("vec rec nr: %i\n", fmbkRecord.rec_nr_vector);
|
||||||
printf("access rec nr: %i\n", fmbkRecord.rec_nr_access);
|
printf("access rec nr: %i\n", fmbkRecord.rec_nr_access);
|
||||||
@@ -175,21 +177,9 @@ void VMDump::printDebug(void)
|
|||||||
|
|
||||||
/* albk */
|
/* albk */
|
||||||
|
|
||||||
memcpy(buf, albkRecord.id, sizeof(albkRecord.id));
|
ebcAsc(albkRecord.id, albk_id, sizeof(albkRecord.id));
|
||||||
ebcAsc(buf, sizeof(albkRecord.id));
|
albk_id[7]=0;
|
||||||
buf[8]=0;
|
printf("ALBK id : %s\n",albk_id);
|
||||||
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);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMDump::printInfo(void)
|
void VMDump::printInfo(void)
|
||||||
|
|||||||
@@ -140,9 +140,15 @@ protected:
|
|||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/* Methods */
|
/* 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 */
|
/* Members */
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ void vtoc_volume_label_set_volser (volume_label_t *vlabel, char *volser)
|
|||||||
|
|
||||||
strcpy(s, " ");
|
strcpy(s, " ");
|
||||||
vtoc_ebcdic_enc(s, s, VOLSER_LENGTH);
|
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;
|
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));
|
bzero(f1->DS1DSNAM, sizeof(f1->DS1DSNAM));
|
||||||
sprintf(str, "PART .NEW ");
|
sprintf(str, "PART .NEW ");
|
||||||
vtoc_ebcdic_enc(str, str, 44);
|
vtoc_ebcdic_enc(str, str, 44);
|
||||||
strncpy(f1->DS1DSNAM, str, 44);
|
memcpy(f1->DS1DSNAM, str, 44);
|
||||||
strncpy((char *) f1->DS1DSSN, " ", 6);
|
memcpy((char *) f1->DS1DSSN, " ", 6);
|
||||||
f1->DS1VOLSQ = 0x0001;
|
f1->DS1VOLSQ = 0x0001;
|
||||||
|
|
||||||
vtoc_set_date(&f1->DS1CREDT,
|
vtoc_set_date(&f1->DS1CREDT,
|
||||||
@@ -758,7 +758,7 @@ static void vtoc_init_format_1_8_label (
|
|||||||
f1->DS1NOBDB = 0x00;
|
f1->DS1NOBDB = 0x00;
|
||||||
f1->DS1FLAG1 = 0x00;
|
f1->DS1FLAG1 = 0x00;
|
||||||
vtoc_ebcdic_enc("IBM LINUX ", str, 13);
|
vtoc_ebcdic_enc("IBM LINUX ", str, 13);
|
||||||
strncpy((char *)f1->DS1SYSCD, str, 13);
|
memcpy((char *)f1->DS1SYSCD, str, 13);
|
||||||
vtoc_set_date(&f1->DS1REFD,
|
vtoc_set_date(&f1->DS1REFD,
|
||||||
(u_int8_t) creatime->tm_year,
|
(u_int8_t) creatime->tm_year,
|
||||||
(u_int16_t) creatime->tm_yday);
|
(u_int16_t) creatime->tm_yday);
|
||||||
|
|||||||
@@ -85,20 +85,12 @@ void init_ibmOSAMib(void) {
|
|||||||
|
|
||||||
/* query OSA-E device driver for OSA-E devices and mark them in IF-MIB interface list */
|
/* query OSA-E device driver for OSA-E devices and mark them in IF-MIB interface list */
|
||||||
osaexp_num = query_OSA_EXP ( &if_list, ifNumber );
|
osaexp_num = query_OSA_EXP ( &if_list, ifNumber );
|
||||||
if ( osaexp_num < 0 )
|
if ( osaexp_num == 0 )
|
||||||
{
|
{
|
||||||
fprintf( stderr, "init_ibmOSAMib(): "
|
get_time( time_buf );
|
||||||
"OSA-E device driver query interface ioctl() failed\n"
|
snmp_log( LOG_ERR, "%s init_ibmOSAMib(): none of the %d interfaces is a real "
|
||||||
"check agent log file for more details\n"
|
"OSA-E device - starting subagent anyway\n", time_buf, ifNumber);
|
||||||
"Cannot start subagent...exiting...\n");
|
return;
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else if ( osaexp_num == 0 )
|
|
||||||
{
|
|
||||||
fprintf( stderr, "init_ibmOSAMib(): bad or no OSA-E devices reported\n"
|
|
||||||
"check agent log file for more details\n"
|
|
||||||
"Cannot start subagent...exiting...\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
/* end if */
|
/* end if */
|
||||||
|
|
||||||
|
|||||||
@@ -1204,18 +1204,7 @@ void update_mib_info ()
|
|||||||
* and mark them in IF-MIB interface list
|
* and mark them in IF-MIB interface list
|
||||||
* */
|
* */
|
||||||
osaexp_num = query_OSA_EXP( &tmp_list, if_num );
|
osaexp_num = query_OSA_EXP( &tmp_list, if_num );
|
||||||
if ( osaexp_num < 0 )
|
if ( osaexp_num == 0 )
|
||||||
{
|
|
||||||
get_time( time_buf );
|
|
||||||
fprintf( stderr, "%s update_mib_info(): "
|
|
||||||
"OSA-E device driver query interface ioctl() "
|
|
||||||
"failed\nupdate_mib_info(): going to stop osasnmpd daemon\n"
|
|
||||||
"update_mib_info(): check subagent logfile for more details\n"
|
|
||||||
"update_mib_info(): sending termination signal to osasnmpd...\n",
|
|
||||||
time_buf );
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else if ( osaexp_num == 0 )
|
|
||||||
{
|
{
|
||||||
get_time( time_buf );
|
get_time( time_buf );
|
||||||
snmp_log( LOG_ERR, "%s update_mib_info(): "
|
snmp_log( LOG_ERR, "%s update_mib_info(): "
|
||||||
@@ -1698,9 +1687,8 @@ int query_IF_MIB ( IF_LIST** ifList )
|
|||||||
* IN int if_Number: number of network interfaces
|
* IN int if_Number: number of network interfaces
|
||||||
* returns: int num - number of OSA Express devices found on this
|
* returns: int num - number of OSA Express devices found on this
|
||||||
* system (>=0)
|
* system (>=0)
|
||||||
* -1 -an error occurred , no valid info avail
|
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
int query_OSA_EXP ( IF_LIST** ifList, int if_Number )
|
unsigned int query_OSA_EXP ( IF_LIST** ifList, int if_Number )
|
||||||
{
|
{
|
||||||
int j, num = 0;
|
int j, num = 0;
|
||||||
char time_buf[TIME_BUF_SIZE]; /* date/time buffer */
|
char time_buf[TIME_BUF_SIZE]; /* date/time buffer */
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ void update_mib_info ( );
|
|||||||
int query_IF_MIB( IF_LIST** );
|
int query_IF_MIB( IF_LIST** );
|
||||||
|
|
||||||
/* retrieves OSA Express interface information from kernel */
|
/* retrieves OSA Express interface information from kernel */
|
||||||
int query_OSA_EXP ( IF_LIST** ,int );
|
unsigned int query_OSA_EXP ( IF_LIST** ,int );
|
||||||
|
|
||||||
/* get time of day */
|
/* get time of day */
|
||||||
int get_time( char* );
|
int get_time( char* );
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ e.g. \-xc0a80a26
|
|||||||
.TP
|
.TP
|
||||||
\fIMASKBITS\fR
|
\fIMASKBITS\fR
|
||||||
Number of bits set in the network mask.
|
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.
|
This subparameter is only valid for function IPA.
|
||||||
.TP
|
.TP
|
||||||
\fIINTERFACE\fR
|
\fIINTERFACE\fR
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ include ../common.mak
|
|||||||
|
|
||||||
all: qethqoat
|
all: qethqoat
|
||||||
|
|
||||||
qethqoat: qethqoat.o
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
|
qethqoat: qethqoat.o $(libs)
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "qethqoat.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]);
|
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()
|
static void print_version()
|
||||||
@@ -208,6 +215,9 @@ static void print_physical(struct qeth_qoat_physical *phdr)
|
|||||||
case OAT_OSA_GEN_OSAE6S:
|
case OAT_OSA_GEN_OSAE6S:
|
||||||
osagen = "OSA-Express6S";
|
osagen = "OSA-Express6S";
|
||||||
break;
|
break;
|
||||||
|
case OAT_OSA_GEN_OSAE7S:
|
||||||
|
osagen = "OSA-Express7S";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(tmp, "unknown (0x%x)", phdr->osa_gen);
|
sprintf(tmp, "unknown (0x%x)", phdr->osa_gen);
|
||||||
osagen = tmp;
|
osagen = tmp;
|
||||||
@@ -239,6 +249,9 @@ static void print_physical(struct qeth_qoat_physical *phdr)
|
|||||||
case OAT_PORT_SPEED_10gbs_full:
|
case OAT_PORT_SPEED_10gbs_full:
|
||||||
speed = "10 Gb/s / full duplex";
|
speed = "10 Gb/s / full duplex";
|
||||||
break;
|
break;
|
||||||
|
case OAT_PORT_SPEED_25gbs_full:
|
||||||
|
speed = "25 Gb/s / full duplex";
|
||||||
|
break;
|
||||||
case OAT_PORT_SPEED_UNKNOWN:
|
case OAT_PORT_SPEED_UNKNOWN:
|
||||||
speed = "unknown / unknown";
|
speed = "unknown / unknown";
|
||||||
break;
|
break;
|
||||||
@@ -281,6 +294,7 @@ static void print_logical(struct qeth_qoat_logical *lhdr)
|
|||||||
char prouter[] = "primary";
|
char prouter[] = "primary";
|
||||||
char srouter[] = "secondary";
|
char srouter[] = "secondary";
|
||||||
char nrouter[] = "no";
|
char nrouter[] = "no";
|
||||||
|
char port_name[8];
|
||||||
char *router;
|
char *router;
|
||||||
|
|
||||||
if (lhdr->ip4_primary_router)
|
if (lhdr->ip4_primary_router)
|
||||||
@@ -334,8 +348,8 @@ static void print_logical(struct qeth_qoat_logical *lhdr)
|
|||||||
|
|
||||||
|
|
||||||
if (lhdr->port_name_f) {
|
if (lhdr->port_name_f) {
|
||||||
ebctoasc((char *)lhdr->port_name, 8);
|
ebctoasc((char *)lhdr->port_name, port_name, 8);
|
||||||
printf("Port name: %.8s\n", lhdr->port_name);
|
printf("Port name: %.8s\n", port_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("IPv4 assists enabled: 0x%08x\n", lhdr->ip4_ass_enabled);
|
printf("IPv4 assists enabled: 0x%08x\n", lhdr->ip4_ass_enabled);
|
||||||
@@ -535,6 +549,7 @@ int main(int argc, char **argv)
|
|||||||
opts.raw = 0;
|
opts.raw = 0;
|
||||||
opts.scope = 1;
|
opts.scope = 1;
|
||||||
opts.file = NULL;
|
opts.file = NULL;
|
||||||
|
opts.ifname = NULL;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, qethqoat_opts_str, qethqoat_opts,
|
while ((c = getopt_long(argc, argv, qethqoat_opts_str, qethqoat_opts,
|
||||||
&index)) != -1) {
|
&index)) != -1) {
|
||||||
@@ -607,7 +622,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, opts.ifname, IFNAMSIZ);
|
util_strlcpy(ifr.ifr_name, opts.ifname, IFNAMSIZ);
|
||||||
oat_data.command = opts.scope;
|
oat_data.command = opts.scope;
|
||||||
ifr.ifr_ifru.ifru_data = (void *)&oat_data;
|
ifr.ifr_ifru.ifru_data = (void *)&oat_data;
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ struct qeth_qoat_physical {
|
|||||||
#define OAT_OSA_GEN_OSAE4S 0x02
|
#define OAT_OSA_GEN_OSAE4S 0x02
|
||||||
#define OAT_OSA_GEN_OSAE5S 0x03
|
#define OAT_OSA_GEN_OSAE5S 0x03
|
||||||
#define OAT_OSA_GEN_OSAE6S 0x04
|
#define OAT_OSA_GEN_OSAE6S 0x04
|
||||||
|
#define OAT_OSA_GEN_OSAE7S 0x05
|
||||||
__u8 osa_gen;
|
__u8 osa_gen;
|
||||||
#define OAT_PORT_SPEED_UNKNOWN 0x00
|
#define OAT_PORT_SPEED_UNKNOWN 0x00
|
||||||
#define OAT_PORT_SPEED_10mbs_half 0x01
|
#define OAT_PORT_SPEED_10mbs_half 0x01
|
||||||
@@ -68,6 +69,7 @@ struct qeth_qoat_physical {
|
|||||||
#define OAT_PORT_SPEED_1000mbs_full 0x06
|
#define OAT_PORT_SPEED_1000mbs_full 0x06
|
||||||
#define OAT_PORT_SPEED_NA 0x07
|
#define OAT_PORT_SPEED_NA 0x07
|
||||||
#define OAT_PORT_SPEED_10gbs_full 0x08
|
#define OAT_PORT_SPEED_10gbs_full 0x08
|
||||||
|
#define OAT_PORT_SPEED_25gbs_full 0x0A
|
||||||
__u8 port_speed;
|
__u8 port_speed;
|
||||||
#define OAT_PORT_MEDIA_COPPER 0x01
|
#define OAT_PORT_MEDIA_COPPER 0x01
|
||||||
#define OAT_PORT_MEDIA_MULTI_MODE 0x02
|
#define OAT_PORT_MEDIA_MULTI_MODE 0x02
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ while IFS='= ' read key val; do
|
|||||||
if [ -f "${OUTPUT}" ]; then
|
if [ -f "${OUTPUT}" ]; then
|
||||||
print_error "BLS file ${OUTPUT} already exists"
|
print_error "BLS file ${OUTPUT} already exists"
|
||||||
fi
|
fi
|
||||||
|
echo "title $section" >> ${OUTPUT}
|
||||||
fi
|
fi
|
||||||
elif [[ $val ]]; then
|
elif [[ $val ]]; then
|
||||||
val="$(echo $val | sed -e 's/^[ \t"]*//;s/[ \t"]*$//')"
|
val="$(echo $val | sed -e 's/^[ \t"]*//;s/[ \t"]*$//')"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=CPACF statistics collection daemon process for Linux on System z
|
Description=CPACF statistics collection daemon process for Linux on System z
|
||||||
Documentation=man:cpacfstatsd(8)
|
Documentation=man:cpacfstatsd(8)
|
||||||
|
ConditionVirtualization=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ int main(int argc, char *argv[]) {
|
|||||||
) {
|
) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
fprintf(stderr, "%s", help_text);
|
fprintf(stdout, "%s", help_text);
|
||||||
exit(0);
|
exit(0);
|
||||||
case 'b':
|
case 'b':
|
||||||
ds.cntrl.blink = 1;
|
ds.cntrl.blink = 1;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ libs = $(rootdir)/libvmdump/libvmdump.a
|
|||||||
objects = vmconvert.o
|
objects = vmconvert.o
|
||||||
|
|
||||||
vmconvert: $(objects) $(libs)
|
vmconvert: $(objects) $(libs)
|
||||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) $(DESTDIR)$(MANDIR)/man1
|
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR) $(DESTDIR)$(MANDIR)/man1
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ libs = $(rootdir)/libvmdump/libvmdump.a \
|
|||||||
objects = vmur.o
|
objects = vmur.o
|
||||||
|
|
||||||
vmur: $(objects) $(libs)
|
vmur: $(objects) $(libs)
|
||||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRSBINDIR) $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -d -m 755 $(DESTDIR)$(USRSBINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ vmur \- Work with z/VM spool file queues
|
|||||||
.
|
.
|
||||||
.
|
.
|
||||||
.SH DESCRIPTION
|
.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).
|
on the z/VM spool files queues (RDR, PUN, and PRT).
|
||||||
|
|
||||||
\*v supports the following commands:
|
\*v supports the following commands:
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ device identifier may also be displayed as "none". In this case use the
|
|||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
.nf
|
.nf
|
||||||
This man-page was written by Stefan Bader <shbader@de.ibm.com>.
|
This man-page was written by Stefan Bader <shbader@de.ibm.com>.
|
||||||
New options added by Sebastian Ott <sebott@linux.vnet.ibm.com>.
|
New options added by Sebastian Ott <sebott@linux.ibm.com>.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR chccwdev (8)
|
.BR chccwdev (8)
|
||||||
.fi
|
.fi
|
||||||
|
|||||||
14
zconf/lsluns
14
zconf/lsluns
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
|
# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
|
||||||
#
|
#
|
||||||
# Copyright IBM Corp. 2008, 2017
|
# Copyright IBM Corp. 2008, 2018
|
||||||
#
|
#
|
||||||
# s390-tools is free software; you can redistribute it and/or modify
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the MIT license. See LICENSE for details.
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -152,6 +152,11 @@ sub get_lun_hash
|
|||||||
my %lun_hash;
|
my %lun_hash;
|
||||||
|
|
||||||
foreach my $device (</$sg_dir/sg*>) {
|
foreach my $device (</$sg_dir/sg*>) {
|
||||||
|
# skip non-zfcp SCSI devices and avoid file access error messages
|
||||||
|
next unless -r "$device/device/fcp_lun";
|
||||||
|
next unless -r "$device/device/wwpn";
|
||||||
|
next unless -r "$device/device/hba_id";
|
||||||
|
|
||||||
my $l = `cat $device/device/fcp_lun`;
|
my $l = `cat $device/device/fcp_lun`;
|
||||||
my $p = `cat $device/device/wwpn`;
|
my $p = `cat $device/device/wwpn`;
|
||||||
my $a = `cat $device/device/hba_id`;
|
my $a = `cat $device/device/hba_id`;
|
||||||
@@ -170,9 +175,8 @@ sub get_lun_hash
|
|||||||
sub lsluns_usage {
|
sub lsluns_usage {
|
||||||
print <<EOD;
|
print <<EOD;
|
||||||
Usage:
|
Usage:
|
||||||
This tool is designed for environments where all SCSI devices are attached
|
This tool is designed for environments with SCSI devices attached
|
||||||
through the zfcp device driver. Expect error messages in mixed environments
|
through the zfcp device driver.
|
||||||
such as with iSCSI.
|
|
||||||
|
|
||||||
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||||
|
|
||||||
@@ -220,7 +224,7 @@ EOD
|
|||||||
|
|
||||||
sub lsluns_version {
|
sub lsluns_version {
|
||||||
print "$PROGRAM_NAME: version %S390_TOOLS_VERSION%\n";
|
print "$PROGRAM_NAME: version %S390_TOOLS_VERSION%\n";
|
||||||
print "Copyright IBM Corp. 2008, 2017\n";
|
print "Copyright IBM Corp. 2008, 2018\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub lsluns_invalid_usage {
|
sub lsluns_invalid_usage {
|
||||||
|
|||||||
@@ -28,9 +28,8 @@ zfcp-attached LUNs
|
|||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
This tool is designed for environments where all SCSI devices are attached
|
This tool is designed for environments with SCSI devices attached
|
||||||
through the zfcp device driver. Expect error messages in mixed environments
|
through the zfcp device driver.
|
||||||
such as with iSCSI.
|
|
||||||
|
|
||||||
.B lsluns
|
.B lsluns
|
||||||
lists all logical unit numbers (LUNs) discovered in the
|
lists all logical unit numbers (LUNs) discovered in the
|
||||||
|
|||||||
71
zconf/lstape
71
zconf/lstape
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# lstape - Tool to show information about tape devices
|
# lstape - Tool to show information about tape devices
|
||||||
#
|
#
|
||||||
# Copyright IBM Corp. 2003, 2017
|
# Copyright IBM Corp. 2003, 2018
|
||||||
#
|
#
|
||||||
# s390-tools is free software; you can redistribute it and/or modify
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the MIT license. See LICENSE for details.
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -48,6 +48,9 @@ function PrintUsage() {
|
|||||||
: -v|--version
|
: -v|--version
|
||||||
: Display the version of the tools package and
|
: Display the version of the tools package and
|
||||||
: the lstape command.
|
: the lstape command.
|
||||||
|
:
|
||||||
|
:$(basename $0) without the --ccw-only option causes extra SAN traffic
|
||||||
|
:for each SCSI tape or changer device by invoking the sg_inq command.
|
||||||
EOD
|
EOD
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ function PrintVersion()
|
|||||||
{
|
{
|
||||||
cat <<-EOD
|
cat <<-EOD
|
||||||
$CMD: version %S390_TOOLS_VERSION%
|
$CMD: version %S390_TOOLS_VERSION%
|
||||||
Copyright IBM Corp. 2003, 2017
|
Copyright IBM Corp. 2003, 2018
|
||||||
EOD
|
EOD
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +223,24 @@ function SysfsCreateListCCW() {
|
|||||||
' | sort
|
' | sort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# handle SCSI device not necessarily zfcp-attached, e.g. virtio-scsi-ccw
|
||||||
|
function SCSISearchCCWBusid()
|
||||||
|
{
|
||||||
|
local SCSI_DEV=$1
|
||||||
|
local SDEVCAN=$(readlink -e $SCSI_DEV)
|
||||||
|
while [ -n "$SDEVCAN" ]; do
|
||||||
|
# ascend to parent: strip last path part
|
||||||
|
SDEVCAN=${SDEVCAN%/*}
|
||||||
|
[ -h $SDEVCAN/subsystem ] || continue
|
||||||
|
local SUBSYSTEM=$(readlink -e $SDEVCAN/subsystem)
|
||||||
|
if [ "${SUBSYSTEM##*/}" = "ccw" ]; then
|
||||||
|
echo ${SDEVCAN##*/}
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "N/A"
|
||||||
|
}
|
||||||
|
|
||||||
function SysfsCreateListSCSI()
|
function SysfsCreateListSCSI()
|
||||||
{
|
{
|
||||||
for SCSI_DEV in $1/bus/scsi/devices/*:*:*:*; do
|
for SCSI_DEV in $1/bus/scsi/devices/*:*:*:*; do
|
||||||
@@ -249,11 +270,16 @@ function SysfsCreateListSCSI()
|
|||||||
if [ -h $SG_DEV ]; then
|
if [ -h $SG_DEV ]; then
|
||||||
# deprecated sysfs layout
|
# deprecated sysfs layout
|
||||||
SG_DEV=$(echo $SG_DEV | awk -F: '{print $NF}')
|
SG_DEV=$(echo $SG_DEV | awk -F: '{print $NF}')
|
||||||
else
|
elif [ -d $SCSI_DEV/scsi_generic ]; then
|
||||||
SG_DEV=$(basename $SG_DEV/*)
|
SG_DEV=$(basename $SG_DEV/*)
|
||||||
|
else
|
||||||
|
SG_DEV=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$SG_INQ" != "" ]; then
|
if [ -z "$SG_DEV" ]; then
|
||||||
|
SG_DEV="N/A"
|
||||||
|
TAPE_SERIAL="NO/SG"
|
||||||
|
elif [ "$SG_INQ" != "" ]; then
|
||||||
TAPE_SERIAL=$(
|
TAPE_SERIAL=$(
|
||||||
sg_inq /dev/$SG_DEV |
|
sg_inq /dev/$SG_DEV |
|
||||||
awk '/serial/{print $NF}'
|
awk '/serial/{print $NF}'
|
||||||
@@ -291,17 +317,31 @@ function SysfsCreateListSCSI()
|
|||||||
if [ "$CHG_IDX" != "" ]; then
|
if [ "$CHG_IDX" != "" ]; then
|
||||||
TAPE_DEV=$CHG_IDX
|
TAPE_DEV=$CHG_IDX
|
||||||
fi
|
fi
|
||||||
elif [ -r /proc/scsi/$DEV_NAME ]; then
|
elif [ "$(echo "$SCSI_LIST"|grep lin_tape)" != "" ]; then
|
||||||
if [ "$TAPE_SERIAL" != "NO/INQ" ]; then
|
# bash glob sorts so IBMtape0 comes before IBMtape0n
|
||||||
|
local IBM_PATH=$(
|
||||||
|
ls -1d $SCSI_DEV/lin_tape/$DEV_NAME[0-9]* |
|
||||||
|
head -n 1)
|
||||||
|
if [ -d "$IBM_PATH" ]; then
|
||||||
|
IBM_IDX=${IBM_PATH##*/}
|
||||||
|
else
|
||||||
|
# deprecated sysfs layout
|
||||||
IBM_IDX=$(
|
IBM_IDX=$(
|
||||||
awk '$3 == "'$TAPE_SERIAL'"{
|
echo "$SCSI_LIST" |
|
||||||
print $1
|
awk -F: '/lin_tape\:'"$DEV_NAME"'[0-9]+$/{print $NF}'
|
||||||
}' /proc/scsi/$DEV_NAME
|
)
|
||||||
|
fi
|
||||||
|
if [ "$IBM_IDX" != "" ]; then
|
||||||
|
TAPE_DEV=$IBM_IDX
|
||||||
|
fi
|
||||||
|
elif [ -r /proc/scsi/$DEV_NAME ]; then
|
||||||
|
IBM_IDX=$(
|
||||||
|
grep -wF "$SCSI_ID" /proc/scsi/$DEV_NAME |
|
||||||
|
cut -d ' ' -f 1
|
||||||
)
|
)
|
||||||
if [ "$IBM_IDX" != "" ]; then
|
if [ "$IBM_IDX" != "" ]; then
|
||||||
TAPE_DEV=$DEV_NAME$IBM_IDX
|
TAPE_DEV=$DEV_NAME$IBM_IDX
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf "$SCSIFORMAT" \
|
printf "$SCSIFORMAT" \
|
||||||
@@ -313,9 +353,16 @@ function SysfsCreateListSCSI()
|
|||||||
$STATE
|
$STATE
|
||||||
|
|
||||||
if $VERBOSE; then
|
if $VERBOSE; then
|
||||||
|
if [ -r $SCSI_DEV/hba_id ]; then
|
||||||
|
HBA_ID=$(cat $SCSI_DEV/hba_id)
|
||||||
|
else
|
||||||
|
HBA_ID=$(SCSISearchCCWBusid $SCSI_DEV)
|
||||||
|
fi
|
||||||
|
WWPN="N/A"
|
||||||
|
[ -r $SCSI_DEV/wwpn ] && WWPN=$(cat $SCSI_DEV/wwpn)
|
||||||
printf "$SCSIVFORMAT" \
|
printf "$SCSIVFORMAT" \
|
||||||
$(cat $SCSI_DEV/hba_id) \
|
"$HBA_ID" \
|
||||||
$(cat $SCSI_DEV/wwpn) \
|
"$WWPN" \
|
||||||
$TAPE_SERIAL
|
$TAPE_SERIAL
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
.\" Copyright 2017 IBM Corp.
|
.\" Copyright 2017, 2018 IBM Corp.
|
||||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
.TH LSTAPE 8 "Jul 2007" "s390-tools"
|
.TH LSTAPE 8 "Jun 2018" "s390-tools"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
lstape \- list tape devices.
|
lstape \- list tape devices.
|
||||||
@@ -20,6 +20,8 @@ lstape \- list tape devices.
|
|||||||
.br
|
.br
|
||||||
.RB [ -t
|
.RB [ -t
|
||||||
.IR <device-type> [, <device-type> ] "" ...]
|
.IR <device-type> [, <device-type> ] "" ...]
|
||||||
|
.br
|
||||||
|
.RI [ <device-bus-ID> ...]
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The lstape command lists all available tape devices on the current host. For
|
The lstape command lists all available tape devices on the current host. For
|
||||||
@@ -27,19 +29,8 @@ channel attached tape devices this output is the same as the contents of
|
|||||||
/proc/tapedevices (which is obsolete) but also includes offline devices. By
|
/proc/tapedevices (which is obsolete) but also includes offline devices. By
|
||||||
default all tape devices are displayed.
|
default all tape devices are displayed.
|
||||||
|
|
||||||
Since SCSI tape devices are accessed differently to channel attached tape
|
The lstape command without the --ccw-only option causes extra SAN traffic
|
||||||
devices they are only visible if they are known to the SCSI layer. There
|
for each SCSI tape or changer device by invoking the sg_inq command.
|
||||||
are at least two possible drivers that can claim a SCSI tape device and the
|
|
||||||
lstape command tries to find out which one this is. For the generic tape
|
|
||||||
and changer driver the device names start with "st" or "sch", while for the
|
|
||||||
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
|
||||||
the correct driver could not be obtained.
|
|
||||||
This happens for example if there is no sg_inq command installed which is
|
|
||||||
required to read the drive's serial number which in turn is used to find out
|
|
||||||
the device number of the IBM tape driver.
|
|
||||||
|
|
||||||
The serial number of a SCSI tape can be displayed with the --verbose option. If
|
|
||||||
there is no sg_inq command available "NO/INQ" is shown as the tape's serial.
|
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP 8
|
.TP 8
|
||||||
@@ -75,12 +66,64 @@ on the output of SCSI devices.
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR -t | --type " \fI<device-type>\fR"
|
.BR -t | --type " \fI<device-type>\fR"
|
||||||
Limit output to given device types (currently only applies to channel attached
|
Limit output to given device types, for example 3490
|
||||||
|
(currently only applies to channel-attached
|
||||||
tape devices).
|
tape devices).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB<device-type>\fR =
|
.I <device-bus-ID>
|
||||||
Device type of devices that should be displayed (e.g. 3490).
|
Limits the output to information about the specified tape device or
|
||||||
|
devices only. For CCW-attached devices only.
|
||||||
|
|
||||||
|
.SH OUTPUT FIELDS FOR SCSI TAPE/CHANGER DEVICES
|
||||||
|
.TP
|
||||||
|
.B Generic
|
||||||
|
SCSI generic device file for the tape drive, for example /dev/sg0.
|
||||||
|
"N/A" if the SCSI generic (sg) kernel functionality is not available.
|
||||||
|
.TP
|
||||||
|
.B Device
|
||||||
|
Main character device node file for accessing the tape drive or medium changer.
|
||||||
|
SCSI tape devices are only visible if they are known to the SCSI layer. There
|
||||||
|
are at least two possible drivers that can claim a SCSI tape device. The
|
||||||
|
lstape command tries to determine the device driver. For the generic tape
|
||||||
|
and changer driver the device names start with "st" or "sch", while for the
|
||||||
|
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
||||||
|
the device driver could not be determined.
|
||||||
|
.TP
|
||||||
|
.B Target
|
||||||
|
Linux SCSI device name in H:C:T:L format.
|
||||||
|
.TP
|
||||||
|
.B Vendor
|
||||||
|
The vendor field from the SCSI device.
|
||||||
|
.TP
|
||||||
|
.B Model
|
||||||
|
The model field from the SCSI device.
|
||||||
|
.TP
|
||||||
|
.B Type
|
||||||
|
"tapedrv" for a tape drive or "changer" for a medium changer.
|
||||||
|
.TP
|
||||||
|
.B State
|
||||||
|
The state of the SCSI device object in the kernel.
|
||||||
|
Any state other than "running" can indicate problems.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
|
||||||
|
For SCSI devices, the --verbose option additionally displays:
|
||||||
|
.TP
|
||||||
|
.B HBA
|
||||||
|
The device bus-ID of the FCP device
|
||||||
|
or of the virtio-scsi-ccw virtual HBA
|
||||||
|
through which the tape drive is attached.
|
||||||
|
"N/A" if the device does not have a sysfs ancestor with subsystem ccw.
|
||||||
|
.TP
|
||||||
|
.B WWPN
|
||||||
|
The WWPN (worldwide port name) of the tape drive in the SAN.
|
||||||
|
"N/A" if device is not attached through zfcp.
|
||||||
|
.TP
|
||||||
|
.B Serial
|
||||||
|
The serial number.
|
||||||
|
"NO/INQ" if there is no sg_inq command available.
|
||||||
|
"NO/SG" if no SCSI generic (sg) kernel support is available.
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
\fBlstape\fR
|
\fBlstape\fR
|
||||||
@@ -92,3 +135,8 @@ List all tape devices that are available
|
|||||||
.RS
|
.RS
|
||||||
Show all 3490 CCW devices that are online.
|
Show all 3490 CCW devices that are online.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
\fBlstape --scsi-only --verbose\fR
|
||||||
|
.RS
|
||||||
|
Show all SCSI tape or changer devices with maximum information.
|
||||||
|
.RE
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ static void ethtool_checksumming(char *buf, const char *if_name)
|
|||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
errx(EXIT_FAILURE, "Internal error: cannot get SOCK_DGRAM socket");
|
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;
|
val.cmd = ETHTOOL_GRXCSUM;
|
||||||
ifr.ifr_data = (void *)&val;
|
ifr.ifr_data = (void *)&val;
|
||||||
rc = ioctl(fd, SIOCETHTOOL, &ifr);
|
rc = ioctl(fd, SIOCETHTOOL, &ifr);
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
include ../../common.mak
|
include ../../common.mak
|
||||||
|
|
||||||
all: chzcrypt lszcrypt
|
all: chzcrypt lszcrypt zcryptctl
|
||||||
|
|
||||||
libs = $(rootdir)/libutil/libutil.a
|
libs = $(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
chzcrypt: chzcrypt.o misc.o $(libs)
|
chzcrypt: chzcrypt.o misc.o $(libs)
|
||||||
lszcrypt: lszcrypt.o misc.o $(libs)
|
lszcrypt: lszcrypt.o misc.o $(libs)
|
||||||
|
zcryptctl: zcryptctl.o misc.o $(libs)
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)
|
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 chzcrypt $(DESTDIR)$(BINDIR)
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 chzcrypt $(DESTDIR)$(BINDIR)
|
||||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lszcrypt $(DESTDIR)$(BINDIR)
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lszcrypt $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zcryptctl $(DESTDIR)$(BINDIR)
|
||||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man8
|
||||||
$(INSTALL) -m 644 -c chzcrypt.8 $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -m 644 -c chzcrypt.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
$(INSTALL) -m 644 -c lszcrypt.8 $(DESTDIR)$(MANDIR)/man8
|
$(INSTALL) -m 644 -c lszcrypt.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL) -m 644 -c zcryptctl.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o chzcrypt lszcrypt
|
rm -f *.o chzcrypt lszcrypt zcryptctl
|
||||||
|
|
||||||
.PHONY: all install clean
|
.PHONY: all install clean
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ status.
|
|||||||
.B -V, --verbose
|
.B -V, --verbose
|
||||||
The verbose level for cryptographic device information.
|
The verbose level for cryptographic device information.
|
||||||
With this verbose level additional information like hardware card type,
|
With this verbose level additional information like hardware card type,
|
||||||
hardware queue depth, pending request queue count, outstanding
|
hardware queue depth, pending requests count, installed function
|
||||||
request queue count, and installed function facilities are displayed.
|
facilities and driver binding is displayed.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B <device-id>
|
.B <device-id>
|
||||||
Specifies a cryptographic device to display. A cryptographic device can be
|
Specifies a cryptographic device to display. A cryptographic device can be
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* lszcrypt - Display zcrypt devices and configuration settings
|
* lszcrypt - Display zcrypt devices and configuration settings
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2008, 2017
|
* Copyright IBM Corp. 2008, 2018
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
#include "lib/util_file.h"
|
#include "lib/util_file.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/util_opt.h"
|
#include "lib/util_opt.h"
|
||||||
#include "lib/util_panic.h"
|
#include "lib/util_panic.h"
|
||||||
#include "lib/util_path.h"
|
#include "lib/util_path.h"
|
||||||
@@ -56,6 +57,25 @@ struct lszcrypt_l *lszcrypt_l = &l;
|
|||||||
#define MASK_CLASS_STATELESS 0x00400000
|
#define MASK_CLASS_STATELESS 0x00400000
|
||||||
#define CLASS_STATELESS "restricted function set"
|
#define CLASS_STATELESS "restricted function set"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* facility bits
|
||||||
|
*/
|
||||||
|
#define MAX_FAC_BITS 9
|
||||||
|
static struct fac_bits_s {
|
||||||
|
int mask;
|
||||||
|
char c;
|
||||||
|
} fac_bits[MAX_FAC_BITS] = {
|
||||||
|
{ 0x80000000, 'S' },
|
||||||
|
{ 0x40000000, 'M' },
|
||||||
|
{ 0x20000000, 'C' },
|
||||||
|
{ 0x10000000, 'D' },
|
||||||
|
{ 0x08000000, 'A' },
|
||||||
|
{ 0x04000000, 'X' },
|
||||||
|
{ 0x02000000, 'N' },
|
||||||
|
{ 0x00800000, 'F' },
|
||||||
|
{ 0x00400000, 'R' },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Program configuration
|
* Program configuration
|
||||||
*/
|
*/
|
||||||
@@ -66,7 +86,7 @@ const struct util_prg prg = {
|
|||||||
{
|
{
|
||||||
.owner = "IBM Corp.",
|
.owner = "IBM Corp.",
|
||||||
.pub_first = 2008,
|
.pub_first = 2008,
|
||||||
.pub_last = 2017,
|
.pub_last = 2018,
|
||||||
},
|
},
|
||||||
UTIL_PRG_COPYRIGHT_END
|
UTIL_PRG_COPYRIGHT_END
|
||||||
}
|
}
|
||||||
@@ -255,7 +275,8 @@ static void show_capability(const char *id_str)
|
|||||||
/* Skip devices, which are not supported by zcrypt layer */
|
/* Skip devices, which are not supported by zcrypt layer */
|
||||||
if (!util_path_is_readable("%s/type", dev) ||
|
if (!util_path_is_readable("%s/type", dev) ||
|
||||||
!util_path_is_readable("%s/online", dev)) {
|
!util_path_is_readable("%s/online", dev)) {
|
||||||
printf("Detailed capability information for %s (hardware type %ld) is not available.\n", card, hwtype);
|
printf("Detailed capability information for %s (hardware type %ld) is not available.\n",
|
||||||
|
card, hwtype);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cbuf[0] = '\0';
|
cbuf[0] = '\0';
|
||||||
@@ -299,11 +320,13 @@ static void show_capability(const char *id_str)
|
|||||||
} else if (func_val & MASK_EP11) {
|
} else if (func_val & MASK_EP11) {
|
||||||
printf("%s", CAP_EP11);
|
printf("%s", CAP_EP11);
|
||||||
} else {
|
} else {
|
||||||
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
printf("Detailed capability information for %s (hardware type %ld) is not available.",
|
||||||
|
card, hwtype);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
printf("Detailed capability information for %s (hardware type %ld) is not available.",
|
||||||
|
card, hwtype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -315,17 +338,22 @@ static void show_capability(const char *id_str)
|
|||||||
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||||
const char *sub_dev)
|
const char *sub_dev)
|
||||||
{
|
{
|
||||||
unsigned long facility;
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
unsigned long facility;
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
|
if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
|
||||||
util_rec_set(rec, "type", buf);
|
util_rec_set(rec, "type", "-");
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/%s/online", grp_dev, sub_dev);
|
|
||||||
if (strcmp(buf, "0") == 0)
|
|
||||||
util_rec_set(rec, "online", "offline");
|
|
||||||
else
|
else
|
||||||
util_rec_set(rec, "online", "online");
|
util_rec_set(rec, "type", buf);
|
||||||
|
|
||||||
|
if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
|
||||||
|
grp_dev, sub_dev))
|
||||||
|
util_rec_set(rec, "online", "-");
|
||||||
|
else
|
||||||
|
if (strcmp(buf, "0") == 0)
|
||||||
|
util_rec_set(rec, "online", "offline");
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "online", "online");
|
||||||
|
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||||
if (facility & MASK_COPRO)
|
if (facility & MASK_COPRO)
|
||||||
@@ -339,7 +367,7 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
|||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/%s/request_count",
|
util_file_read_line(buf, sizeof(buf), "%s/%s/request_count",
|
||||||
grp_dev, sub_dev);
|
grp_dev, sub_dev);
|
||||||
util_rec_set(rec, "request_count", buf);
|
util_rec_set(rec, "requests", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -348,20 +376,19 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
|||||||
static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||||
const char *sub_dev)
|
const char *sub_dev)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
unsigned long facility;
|
unsigned long facility;
|
||||||
char buf[256];
|
char buf[256], afile[PATH_MAX];
|
||||||
long depth;
|
long depth, pending1, pending2;
|
||||||
|
|
||||||
if (l.verbose == 0)
|
if (l.verbose == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/%s/pendingq_count",
|
util_file_read_l(&pending1, 10, "%s/%s/pendingq_count",
|
||||||
grp_dev, sub_dev);
|
grp_dev, sub_dev);
|
||||||
util_rec_set(rec, "pendingq_count", buf);
|
util_file_read_l(&pending2, 10, "%s/%s/requestq_count",
|
||||||
|
grp_dev, sub_dev);
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/%s/requestq_count",
|
util_rec_set(rec, "pending", "%ld", pending1 + pending2);
|
||||||
grp_dev, sub_dev);
|
|
||||||
util_rec_set(rec, "requestq_count", buf);
|
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
||||||
util_rec_set(rec, "hwtype", buf);
|
util_rec_set(rec, "hwtype", buf);
|
||||||
@@ -370,7 +397,18 @@ static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
|||||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||||
|
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||||
util_rec_set(rec, "facility", "0x%08x", facility);
|
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||||
|
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||||
|
buf[i] = '\0';
|
||||||
|
util_rec_set(rec, "facility", buf);
|
||||||
|
|
||||||
|
snprintf(afile, sizeof(afile), "%s/%s/driver", grp_dev, sub_dev);
|
||||||
|
afile[sizeof(afile) - 1] = '\0';
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
if (readlink(afile, buf, sizeof(buf)) > 0)
|
||||||
|
util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "driver", "-no-driver-");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -382,9 +420,13 @@ static void show_subdevice(struct util_rec *rec, const char *grp_dev,
|
|||||||
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
|
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
|
||||||
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
|
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
|
||||||
|
|
||||||
/* Skip devices, which are not supported by zcrypt layer */
|
/*
|
||||||
if (!util_path_is_readable("%s/type", grp_dev) ||
|
* If not verbose mode, skip devices which are not supported
|
||||||
!util_path_is_readable("%s/%s/online", grp_dev, sub_dev))
|
* by the zcrypt layer.
|
||||||
|
*/
|
||||||
|
if (l.verbose == 0 &&
|
||||||
|
(!util_path_is_readable("%s/type", grp_dev) ||
|
||||||
|
!util_path_is_readable("%s/%s/online", grp_dev, sub_dev)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
util_rec_set(rec, "card", sub_dev);
|
util_rec_set(rec, "card", sub_dev);
|
||||||
@@ -414,11 +456,13 @@ static void show_subdevices(struct util_rec *rec, const char *grp_dev)
|
|||||||
*/
|
*/
|
||||||
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||||
{
|
{
|
||||||
unsigned long facility;
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
unsigned long facility;
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
|
if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
|
||||||
util_rec_set(rec, "type", buf);
|
util_rec_set(rec, "type", "-");
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "type", buf);
|
||||||
|
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||||
if (facility & MASK_COPRO)
|
if (facility & MASK_COPRO)
|
||||||
@@ -430,14 +474,16 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
|||||||
else
|
else
|
||||||
util_rec_set(rec, "mode", "Unknown");
|
util_rec_set(rec, "mode", "Unknown");
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev);
|
if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
|
||||||
if (strcmp(buf, "0") == 0)
|
util_rec_set(rec, "online", "-");
|
||||||
util_rec_set(rec, "online", "offline");
|
|
||||||
else
|
else
|
||||||
util_rec_set(rec, "online", "online");
|
if (strcmp(buf, "0") == 0)
|
||||||
|
util_rec_set(rec, "online", "offline");
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "online", "online");
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
||||||
util_rec_set(rec, "request_count", buf);
|
util_rec_set(rec, "requests", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -445,18 +491,17 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
|||||||
*/
|
*/
|
||||||
static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
unsigned long facility;
|
unsigned long facility;
|
||||||
char buf[256];
|
char buf[256], afile[PATH_MAX];
|
||||||
long depth;
|
long depth, pending1, pending2;
|
||||||
|
|
||||||
if (l.verbose == 0)
|
if (l.verbose == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/pendingq_count", grp_dev);
|
util_file_read_l(&pending1, 10, "%s/pendingq_count", grp_dev);
|
||||||
util_rec_set(rec, "pendingq_count", buf);
|
util_file_read_l(&pending2, 10, "%s/requestq_count", grp_dev);
|
||||||
|
util_rec_set(rec, "pending", "%ld", pending1 + pending2);
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/requestq_count", grp_dev);
|
|
||||||
util_rec_set(rec, "requestq_count", buf);
|
|
||||||
|
|
||||||
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
||||||
util_rec_set(rec, "hwtype", buf);
|
util_rec_set(rec, "hwtype", buf);
|
||||||
@@ -465,7 +510,18 @@ static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
|||||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||||
|
|
||||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||||
util_rec_set(rec, "facility", "0x%08x", facility);
|
for (i = 0; i < MAX_FAC_BITS; i++)
|
||||||
|
buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||||
|
buf[i] = '\0';
|
||||||
|
util_rec_set(rec, "facility", buf);
|
||||||
|
|
||||||
|
snprintf(afile, sizeof(afile), "%s/driver", grp_dev);
|
||||||
|
afile[sizeof(afile) - 1] = '\0';
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
if (readlink(afile, buf, sizeof(buf)) > 0)
|
||||||
|
util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
|
||||||
|
else
|
||||||
|
util_rec_set(rec, "driver", "-no-driver-");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -481,9 +537,14 @@ static void show_device(struct util_rec *rec, const char *device)
|
|||||||
grp_dev = util_path_sysfs("devices/ap/%s", device);
|
grp_dev = util_path_sysfs("devices/ap/%s", device);
|
||||||
if (!util_path_is_dir(grp_dev))
|
if (!util_path_is_dir(grp_dev))
|
||||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
||||||
/* Skip devices, which are not supported by zcrypt layer */
|
|
||||||
if (!util_path_is_readable("%s/type", grp_dev) ||
|
/*
|
||||||
!util_path_is_readable("%s/online", grp_dev)) {
|
* If not verbose mode, skip devices which are not supported
|
||||||
|
* by the zcrypt layer.
|
||||||
|
*/
|
||||||
|
if (l.verbose == 0 &&
|
||||||
|
(!util_path_is_readable("%s/type", grp_dev) ||
|
||||||
|
!util_path_is_readable("%s/online", grp_dev))) {
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
util_rec_set(rec, "card", card);
|
util_rec_set(rec, "card", card);
|
||||||
@@ -506,8 +567,7 @@ static void define_rec_default(struct util_rec *rec)
|
|||||||
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
|
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
|
||||||
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
|
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
|
||||||
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
|
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
|
||||||
util_rec_def(rec, "request_count", UTIL_REC_ALIGN_RIGHT, 11,
|
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
|
||||||
"REQUEST_CNT");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -517,13 +577,11 @@ static void define_rec_verbose(struct util_rec *rec)
|
|||||||
{
|
{
|
||||||
if (l.verbose == 0)
|
if (l.verbose == 0)
|
||||||
return;
|
return;
|
||||||
util_rec_def(rec, "pendingq_count", UTIL_REC_ALIGN_RIGHT, 12,
|
util_rec_def(rec, "pending", UTIL_REC_ALIGN_RIGHT, 8, "PENDING");
|
||||||
"PENDINGQ_CNT");
|
util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 6, "HWTYPE");
|
||||||
util_rec_def(rec, "requestq_count", UTIL_REC_ALIGN_RIGHT, 12,
|
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
||||||
"REQUESTQ_CNT");
|
|
||||||
util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 7, "HW_TYPE");
|
|
||||||
util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 7, "Q_DEPTH");
|
|
||||||
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
||||||
|
util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -563,7 +621,7 @@ static void show_devices_argv(char *argv[])
|
|||||||
{
|
{
|
||||||
struct util_rec *rec = util_rec_new_wide("-");
|
struct util_rec *rec = util_rec_new_wide("-");
|
||||||
struct dirent **dev_vec, **subdev_vec;
|
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;
|
int id, dom, i, n, dev_cnt, sub_cnt;
|
||||||
|
|
||||||
/* check if ap driver is available */
|
/* check if ap driver is available */
|
||||||
@@ -582,14 +640,16 @@ static void show_devices_argv(char *argv[])
|
|||||||
if (sscanf(argv[i], "%x.%x", &id, &dom) >= 1) {
|
if (sscanf(argv[i], "%x.%x", &id, &dom) >= 1) {
|
||||||
/* at least the id field was valid */
|
/* at least the id field was valid */
|
||||||
if (id >= 0 && dom >= 0) { /* single subdevice */
|
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",
|
grp_dev = util_path_sysfs("devices/ap/card%02x",
|
||||||
id);
|
id);
|
||||||
show_subdevice(rec, grp_dev, sub_dev);
|
show_subdevice(rec, grp_dev, sub_dev);
|
||||||
free(grp_dev);
|
free(grp_dev);
|
||||||
|
free(sub_dev);
|
||||||
} else { /* group device */
|
} else { /* group device */
|
||||||
sprintf(card, "card%02x", id);
|
util_asprintf(&card, "card%02x", id);
|
||||||
show_device(rec, card);
|
show_device(rec, card);
|
||||||
|
free(card);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
147
zconf/zcrypt/zcryptctl.8
Normal file
147
zconf/zcrypt/zcryptctl.8
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
.\" zcryptctl.8
|
||||||
|
.\"
|
||||||
|
.\" Copyright 2018 IBM Corp.
|
||||||
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
.\"
|
||||||
|
.\" use
|
||||||
|
.\" groff -man -Tutf8 zcryptctl.8
|
||||||
|
.\" or
|
||||||
|
.\" nroff -man zcryptctl.8
|
||||||
|
.\" to process this source
|
||||||
|
.\"
|
||||||
|
.TH ZCRYPTCTL 8 "AUG 2018" "s390-tools"
|
||||||
|
.SH NAME
|
||||||
|
zcryptctl \- display information and administrate zcrypt multiple device nodes
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.TP 8
|
||||||
|
.B zcryptctl list
|
||||||
|
.TP
|
||||||
|
.B zcryptctl create
|
||||||
|
.R [
|
||||||
|
.I node-name
|
||||||
|
.R ]
|
||||||
|
.TP
|
||||||
|
.B zcryptctl destroy
|
||||||
|
.I node-name
|
||||||
|
.TP
|
||||||
|
.B zcryptctl addap
|
||||||
|
.R |
|
||||||
|
.B delap
|
||||||
|
.I node-name adapter-nr
|
||||||
|
.TP
|
||||||
|
.B zcryptctl adddom
|
||||||
|
.R |
|
||||||
|
.B deldom
|
||||||
|
.I node-name domain-nr
|
||||||
|
.TP
|
||||||
|
.B zcryptctl addioctl
|
||||||
|
.R |
|
||||||
|
.B delioctl
|
||||||
|
.I node-name ioctl-term
|
||||||
|
.TP
|
||||||
|
.B zcryptctl config
|
||||||
|
.I config-file
|
||||||
|
.TP
|
||||||
|
.B zcryptctl listconfig
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B zcryptctl
|
||||||
|
command displays information and maintains the multi device node
|
||||||
|
extension for the zcrypt device driver.
|
||||||
|
.P
|
||||||
|
With the multi device node extension you can create and configure
|
||||||
|
additional zcrypt device nodes which can be used as alternate device
|
||||||
|
nodes to access the crypto hardware provided by the zcrypt device
|
||||||
|
driver. Each zcrypt device node can be restricted in terms of crypto
|
||||||
|
cards, domains, and available ioctls. Such a device node can be used
|
||||||
|
as a base for container solutions like Docker to control and restrict
|
||||||
|
the access to crypto resources.
|
||||||
|
.SH COMMANDS
|
||||||
|
.TP 8
|
||||||
|
.B zcryptctl list
|
||||||
|
Show all the additional device nodes that are currently active.
|
||||||
|
.TP
|
||||||
|
.B zcryptctl create
|
||||||
|
.R [
|
||||||
|
.I node-name
|
||||||
|
.R ]
|
||||||
|
Create a new zcrypt device node. The \fInode-name\fP might be given
|
||||||
|
and needs to be unique and not in use. If there is no node name
|
||||||
|
provided, the zcrypt device driver will create a new one with pattern
|
||||||
|
zcrypt_\fIx\fP, with \fIx\fP being the next free number. Up to 256
|
||||||
|
additional device nodes can be created. The newly created additional
|
||||||
|
device node appears in /dev and has read and write permissions enabled
|
||||||
|
only for root. By default all adapters, domains and ioctls are
|
||||||
|
initially disabled on this new device node.
|
||||||
|
.TP
|
||||||
|
.B zcryptctl destroy
|
||||||
|
.I node-name
|
||||||
|
Destroy an additional zcrypt device node. The device node is only
|
||||||
|
marked for disposal and destroyed when it is no longer used.
|
||||||
|
.TP
|
||||||
|
.B zcryptctl addap
|
||||||
|
.R |
|
||||||
|
.B delap
|
||||||
|
.I node-name adapter-nr
|
||||||
|
Update the filter for the specified zcrypt device node and add or
|
||||||
|
delete a crypto adapter to be accessible via this node. The symbol
|
||||||
|
\fBALL\fP can be used to enable or disable all adapters.
|
||||||
|
.TP
|
||||||
|
.B zcryptctl adddom
|
||||||
|
.R |
|
||||||
|
.B deldom
|
||||||
|
.I node-name domain-nr
|
||||||
|
Update the filter for the specified zcrypt device node and add or
|
||||||
|
delete a domain to be accessible through this node. The symbol
|
||||||
|
\fBALL\fP can be used to enable or disable all domains.
|
||||||
|
.TP
|
||||||
|
.B zcryptctl addioctl
|
||||||
|
.R |
|
||||||
|
.B delioctl
|
||||||
|
.I node-name ioctl-term
|
||||||
|
Update the filter for the specified zcrypt device node and add or
|
||||||
|
delete an ioctl. The ioctl might be specified as symbolic string (one
|
||||||
|
of \fBICARSAMODEXPO\fP, \fBICARSACRT\fP, \fBZSECSENDCPRB\fP,
|
||||||
|
\fBZSENDEP11CPRB\fP, \fBZCRYPT_DEVICE_STATUS\fP,
|
||||||
|
\fBZCRYPT_STATUS_MASK\fP, \fBZCRYPT_QDEPTH_MASK\fP,
|
||||||
|
\fBZCRYPT_PERDEV_REQCNT\fP) or numeric value in the range 0-255 and
|
||||||
|
the symbol \fBALL\fP can be used to include all ioctls.
|
||||||
|
.TP
|
||||||
|
.B zcryptctl config
|
||||||
|
.I config-file
|
||||||
|
Process a config file. The given configuration file is read line by
|
||||||
|
line and the settings are applied. Syntax is simple:
|
||||||
|
.RS
|
||||||
|
.IP "node=<node-name>"
|
||||||
|
.IP "aps=<list of ap numbers separated by space, tab or ','>"
|
||||||
|
.IP "doms=<list of domain numbers separated by space, tab or ','>"
|
||||||
|
.IP "ioctls=<list of ioctl as numeric or symbolic number separated by space, tab or ','>"
|
||||||
|
.LP
|
||||||
|
Empty lines are ignored and the '#' marks the rest of the
|
||||||
|
line as comment.
|
||||||
|
.LP
|
||||||
|
The \fBnode=\fP line creates a new zcrypt device node, the \fBaps=\fP,
|
||||||
|
\fBdoms=\fP and \fBioctls=\fP lines customize the previously created
|
||||||
|
node. The symbol \fBALL\fP is also recognized for aps, doms, and
|
||||||
|
ioctls.
|
||||||
|
.LP
|
||||||
|
Each action must fit into one line, spreading over multiple lines is
|
||||||
|
not supported. But you can use more than one \fBaps=\fP, \fBdoms=\fP
|
||||||
|
and \fBioctls=\fP lines to customize the very same node.
|
||||||
|
.LP
|
||||||
|
Processing stops when a line cannot be parsed or the current action
|
||||||
|
fails. In this case the exit status is non zero but the successful
|
||||||
|
actions until the failure occurs are not rolled back.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.B zcryptctl listconfig
|
||||||
|
List the current configuration in a form suitable for input to the
|
||||||
|
\fBzcryptctl config\fP command.
|
||||||
|
.LP
|
||||||
|
.SH EXIT STATUS
|
||||||
|
On successful completion of the command the exit status is 0. A non
|
||||||
|
zero return code (and some kind of failure message) is emitted if the
|
||||||
|
processing could not complete successful.
|
||||||
|
.SH SEE ALSO
|
||||||
|
\fBlszcrypt\fR(8)
|
||||||
1030
zconf/zcrypt/zcryptctl.c
Normal file
1030
zconf/zcrypt/zcryptctl.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -62,10 +62,12 @@ struct ccw_devinfo {
|
|||||||
* ccw_subtype_data - CCW subtype specific information
|
* ccw_subtype_data - CCW subtype specific information
|
||||||
* @ccwdrv: The name of the CCW device driver for this subtype
|
* @ccwdrv: The name of the CCW device driver for this subtype
|
||||||
* @mod: The name of the main kernel module for this subtype
|
* @mod: The name of the main kernel module for this subtype
|
||||||
|
* @any_driver: If set, the exact driver for this subtype are not known
|
||||||
*/
|
*/
|
||||||
struct ccw_subtype_data {
|
struct ccw_subtype_data {
|
||||||
const char *ccwdrv;
|
const char *ccwdrv;
|
||||||
const char *mod;
|
const char *mod;
|
||||||
|
bool any_driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct attrib ccw_attr_online;
|
extern struct attrib ccw_attr_online;
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ enum nic_target {
|
|||||||
nic_lan,
|
nic_lan,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NIC_OWNER_LEN 9
|
#define NIC_OWNER_SIZE 9
|
||||||
#define NIC_NAME_LEN 9
|
#define NIC_NAME_SIZE 9
|
||||||
|
|
||||||
struct nic_data {
|
struct nic_data {
|
||||||
enum nic_type type;
|
enum nic_type type;
|
||||||
enum nic_target target;
|
enum nic_target target;
|
||||||
char owner[NIC_OWNER_LEN];
|
char owner[NIC_OWNER_SIZE];
|
||||||
char name[NIC_NAME_LEN];
|
char name[NIC_NAME_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
bool nic_data_get(const char *, struct nic_data *);
|
bool nic_data_get(const char *, struct nic_data *);
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ INITTOP := $(INITRAMFSDIR)/scripts/init-top
|
|||||||
ifeq ($(HAVE_INITRAMFS),1)
|
ifeq ($(HAVE_INITRAMFS),1)
|
||||||
install:
|
install:
|
||||||
$(INSTALL) -m 755 -d $(DESTDIR)/$(HOOKDIR) $(DESTDIR)/$(INITTOP)
|
$(INSTALL) -m 755 -d $(DESTDIR)/$(HOOKDIR) $(DESTDIR)/$(INITTOP)
|
||||||
$(INSTALL) -m 755 hooks/zdev $(DESTDIR)/$(HOOKDIR)
|
$(INSTALL) -m 755 hooks/s390-tools-zdev $(DESTDIR)/$(HOOKDIR)
|
||||||
$(INSTALL) -m 755 scripts/init-top/zdev $(DESTDIR)/$(INITTOP)
|
$(INSTALL) -m 755 scripts/init-top/s390-tools-zdev $(DESTDIR)/$(INITTOP)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# s390-tools is free software; you can redistribute it and/or modify
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the MIT license. See LICENSE for details.
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
#
|
#
|
||||||
# hooks/zdev
|
# hooks/s390-tools-zdev
|
||||||
# This hook script adds files required to apply firmware-provided I/O
|
# This hook script adds files required to apply firmware-provided I/O
|
||||||
# configuration data during boot.
|
# configuration data during boot.
|
||||||
#
|
#
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
# s390-tools is free software; you can redistribute it and/or modify
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the MIT license. See LICENSE for details.
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
#
|
#
|
||||||
# scripts/init-top/zdev
|
# scripts/init-top/s390-tools-zdev
|
||||||
# Parse the kernel command line for rd.zdev kernel parameters. These
|
# Parse the kernel command line for rd.zdev kernel parameters. These
|
||||||
# parameters are evaluated and used to configure z Systems specific devices.
|
# parameters are evaluated and used to configure z Systems specific devices.
|
||||||
#
|
#
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
static struct ccw_subtype_data generic_ccw_data = {
|
static struct ccw_subtype_data generic_ccw_data = {
|
||||||
.ccwdrv = NULL,
|
.ccwdrv = NULL,
|
||||||
.mod = NULL,
|
.mod = NULL,
|
||||||
|
.any_driver = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Check if there is a non-generic subtype in the CCW namespace that uses the
|
/* Check if there is a non-generic subtype in the CCW namespace that uses the
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* zdev - Modify and display the persistent configuration of devices
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -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. */
|
* at the specified path or NULL on error. */
|
||||||
char *misc_readlink(const char *path)
|
char *misc_readlink(const char *path)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name, *name2;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
debug("Reading link %s\n", path);
|
debug("Reading link %s\n", path);
|
||||||
@@ -1103,7 +1103,8 @@ char *misc_readlink(const char *path)
|
|||||||
}
|
}
|
||||||
name[len++] = 0;
|
name[len++] = 0;
|
||||||
|
|
||||||
return realloc(name, len);
|
name2 = realloc(name, len);
|
||||||
|
return (name2) ? name2 : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine configuration set. */
|
/* Determine configuration set. */
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "lib/util_libc.h"
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "nic.h"
|
#include "nic.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
@@ -55,8 +57,8 @@ bool nic_data_get(const char *id, struct nic_data *data_ptr)
|
|||||||
else
|
else
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
strncpy(data.owner, argv[11], sizeof(data.owner));
|
util_strlcpy(data.owner, argv[11], NIC_OWNER_SIZE);
|
||||||
strncpy(data.name, argv[12], sizeof(data.name));
|
util_strlcpy(data.name, argv[12], NIC_NAME_SIZE);
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
*data_ptr = data;
|
*data_ptr = data;
|
||||||
|
|||||||
@@ -1171,6 +1171,37 @@ static exit_code_t check_ineffective_settings(struct setting_list *list,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if a possibly conflicting setting is active in the configuration */
|
||||||
|
static bool conflict_setting_active(struct setting *s)
|
||||||
|
{
|
||||||
|
enum qeth_attr_group_type t;
|
||||||
|
|
||||||
|
t = get_attr_group_type(s);
|
||||||
|
if (t != group_bridge && t != group_vnicc) {
|
||||||
|
/* Check BridgePort and VNICC attributes only */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (s->specified) {
|
||||||
|
/* Specified on the command line: We are strict here and do not
|
||||||
|
* allow to specify VNICC and BridgePort attributes in the same
|
||||||
|
* command to avoid issues when attributes are enabled/disabled
|
||||||
|
* in the wrong order. Example: disable VNICC and enable
|
||||||
|
* BridgePort in the same command would result in an error
|
||||||
|
* because BridgePort attributes are set first.
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (attrib_match_default(s->attrib, s->value)) {
|
||||||
|
/* Not active if set to default value */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (s->actual_value && strncmp(s->actual_value, "n/a", 3) == 0) {
|
||||||
|
/* Not active if in n/a state (conflicting attribute set) */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if there are conflicting attribute settings */
|
/* Check if there are conflicting attribute settings */
|
||||||
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||||
{
|
{
|
||||||
@@ -1182,6 +1213,8 @@ static exit_code_t check_conflicting_settings(struct setting_list *list)
|
|||||||
util_list_iterate(&list->list, s) {
|
util_list_iterate(&list->list, s) {
|
||||||
if (s->removed)
|
if (s->removed)
|
||||||
continue;
|
continue;
|
||||||
|
if (!conflict_setting_active(s))
|
||||||
|
continue;
|
||||||
t = get_attr_group_type(s);
|
t = get_attr_group_type(s);
|
||||||
if (t == group_bridge && (!bridge || !bridge->specified))
|
if (t == group_bridge && (!bridge || !bridge->specified))
|
||||||
bridge = s;
|
bridge = s;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* zdev - Modify and display the persistent configuration of devices
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -550,7 +550,7 @@ void setting_list_merge(struct setting_list *to, struct setting_list *from,
|
|||||||
if (specified)
|
if (specified)
|
||||||
n->specified = s->specified;
|
n->specified = s->specified;
|
||||||
if (modified)
|
if (modified)
|
||||||
n->modified = n->modified;
|
n->modified = s->modified;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ exit_code_t udev_ccw_write_device(struct device *dev, bool autoconf)
|
|||||||
{
|
{
|
||||||
struct subtype *st = dev->subtype;
|
struct subtype *st = dev->subtype;
|
||||||
struct ccw_subtype_data *data = st->data;
|
struct ccw_subtype_data *data = st->data;
|
||||||
const char *type = st->name, *drv = data->ccwdrv, *id = dev->id;
|
const char *type = st->name, *drv = data->any_driver ? "*" : data->ccwdrv, *id = dev->id;
|
||||||
struct device_state *state = autoconf ? &dev->autoconf :
|
struct device_state *state = autoconf ? &dev->autoconf :
|
||||||
&dev->persistent;
|
&dev->persistent;
|
||||||
char *path, *cfg_label = NULL, *end_label = NULL;
|
char *path, *cfg_label = NULL, *end_label = NULL;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "lib/libzds.h"
|
#include "lib/libzds.h"
|
||||||
|
#include "lib/util_libc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#define COMP "zdsfs: "
|
#define COMP "zdsfs: "
|
||||||
@@ -75,11 +76,10 @@ static void path_to_ds_name(const char *path, char *normds, size_t size)
|
|||||||
|
|
||||||
if (*path == '/')
|
if (*path == '/')
|
||||||
++path;
|
++path;
|
||||||
strncpy(normds, path, size);
|
util_strlcpy(normds, path, size);
|
||||||
normds[size - 1] = 0;
|
|
||||||
end = strchr(normds, '/');
|
end = strchr(normds, '/');
|
||||||
if (end)
|
if (end)
|
||||||
*end = 0;
|
*end = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void path_to_member_name(const char *path, char *normds, size_t size)
|
static void path_to_member_name(const char *path, char *normds, size_t size)
|
||||||
@@ -88,11 +88,10 @@ static void path_to_member_name(const char *path, char *normds, size_t size)
|
|||||||
++path;
|
++path;
|
||||||
path = strchr(path, '/');
|
path = strchr(path, '/');
|
||||||
if (!path)
|
if (!path)
|
||||||
normds[0] = 0;
|
normds[0] = '\0';
|
||||||
else {
|
else {
|
||||||
++path;
|
++path;
|
||||||
strncpy(normds, path, size);
|
util_strlcpy(normds, path, size);
|
||||||
normds[size - 1] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,7 +773,7 @@ static const struct fuse_opt zdsfs_opts[] = {
|
|||||||
|
|
||||||
static void usage(const char *progname)
|
static void usage(const char *progname)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stdout,
|
||||||
"Usage: %s <devices> <mountpoint> [<options>]\n"
|
"Usage: %s <devices> <mountpoint> [<options>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Use the zdsfs command to provide read access to data sets stored on one or\n"
|
"Use the zdsfs command to provide read access to data sets stored on one or\n"
|
||||||
@@ -976,14 +975,24 @@ static int zdsfs_process_args(void *UNUSED(data), const char *arg, int key,
|
|||||||
return 0;
|
return 0;
|
||||||
case KEY_HELP:
|
case KEY_HELP:
|
||||||
usage(outargs->argv[0]);
|
usage(outargs->argv[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usage output needs to go to stdout to be consistent with
|
||||||
|
* coding guidelines. FUSE versions before 3.0.0 print help
|
||||||
|
* output to stderr. Redirect stderr to stdout here to enforce
|
||||||
|
* consistent behavior.
|
||||||
|
*/
|
||||||
|
fflush(stderr);
|
||||||
|
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||||
|
|
||||||
fuse_opt_add_arg(outargs, "-ho");
|
fuse_opt_add_arg(outargs, "-ho");
|
||||||
/* call fuse_main to let library print fuse options */
|
/* call fuse_main to let library print fuse options */
|
||||||
fuse_main(outargs->argc, outargs->argv, &rdf_oper, NULL);
|
fuse_main(outargs->argc, outargs->argv, &rdf_oper, NULL);
|
||||||
exit(0);
|
exit(0);
|
||||||
case KEY_VERSION:
|
case KEY_VERSION:
|
||||||
fprintf(stderr, COMP "FUSE file system for z/OS data set access"
|
fprintf(stdout, COMP "FUSE file system for z/OS data set access"
|
||||||
", program version %s\n", RELEASE_STRING);
|
", program version %s\n", RELEASE_STRING);
|
||||||
fprintf(stderr, "Copyright IBM Corp. 2013, 2017\n");
|
fprintf(stdout, "Copyright IBM Corp. 2013, 2017\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unknown argument key %x\n", key);
|
fprintf(stderr, "Unknown argument key %x\n", key);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -20,6 +21,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_path.h"
|
||||||
|
|
||||||
#include "zgetdump.h"
|
#include "zgetdump.h"
|
||||||
#include "dfi_s390mv.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)
|
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;
|
struct dirent *direntp;
|
||||||
int fh, minor, major;
|
int fh, minor, major;
|
||||||
char buf[10];
|
char buf[10];
|
||||||
DIR *fh_dir;
|
DIR *fh_dir;
|
||||||
|
char *sysfs;
|
||||||
|
|
||||||
snprintf(dev_file, PATH_MAX, "%s/%s", SYSFS_BUSDIR, bus_id);
|
sysfs = util_path_sysfs("%s/%s", SYSFS_BUSDIR, bus_id);
|
||||||
fh_dir = opendir(dev_file);
|
fh_dir = opendir(sysfs);
|
||||||
|
free(sysfs);
|
||||||
if (!fh_dir)
|
if (!fh_dir)
|
||||||
return DEV_UNDEFINED;
|
return DEV_UNDEFINED;
|
||||||
|
|
||||||
snprintf(tmp_file, PATH_MAX, "%s/online", dev_file);
|
sysfs = util_path_sysfs("%s/%s/online", SYSFS_BUSDIR, bus_id);
|
||||||
fh = open(tmp_file, O_RDONLY);
|
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)
|
if (read(fh, buf, 1) == -1)
|
||||||
ERR_EXIT_ERRNO("Could not read online attribute");
|
ERR_EXIT_ERRNO("Could not read online attribute");
|
||||||
close(fh);
|
close(fh);
|
||||||
@@ -128,27 +137,49 @@ static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
|
|||||||
closedir(fh_dir);
|
closedir(fh_dir);
|
||||||
|
|
||||||
if (direntp == NULL) {
|
if (direntp == NULL) {
|
||||||
snprintf(dev_file, PATH_MAX, "%s/%s/block", SYSFS_BUSDIR,
|
sysfs = util_path_sysfs("%s/%s/block", SYSFS_BUSDIR, bus_id);
|
||||||
bus_id);
|
fh_dir = opendir(sysfs);
|
||||||
fh_dir = opendir(dev_file);
|
if (!fh_dir) {
|
||||||
if (!fh_dir)
|
warnx("Could not open \"%s\" (%s) ",
|
||||||
ERR_EXIT_ERRNO("Could not open \"%s\"", dev_file);
|
sysfs, strerror(errno));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
while ((direntp = readdir(fh_dir)))
|
while ((direntp = readdir(fh_dir)))
|
||||||
if (strncmp(direntp->d_name, "dasd", 4) == 0)
|
if (strncmp(direntp->d_name, "dasd", 4) == 0)
|
||||||
break;
|
break;
|
||||||
closedir(fh_dir);
|
closedir(fh_dir);
|
||||||
if (direntp == NULL)
|
if (direntp == NULL) {
|
||||||
ERR_EXIT("Problem with contents of \"%s\"", dev_file);
|
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);
|
close(fh);
|
||||||
if (sscanf(buf, "%i:%i", &major, &minor) != 2)
|
if (sscanf(buf, "%i:%i", &major, &minor) != 2) {
|
||||||
ERR_EXIT("Malformed content of \"%s\": %s", tmp_file, buf);
|
warnx("Malformed content of \"%s\": %s", sysfs, buf);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
*dev = makedev(major, minor);
|
*dev = makedev(major, minor);
|
||||||
|
|
||||||
|
free(sysfs);
|
||||||
|
|
||||||
return DEV_ONLINE;
|
return DEV_ONLINE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free(sysfs);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -467,19 +498,6 @@ fail:
|
|||||||
return rc;
|
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
|
* 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;
|
u64 mem_off = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
check_sysfs();
|
|
||||||
|
|
||||||
for (i = 0; i < l.table.vol_cnt; i++) {
|
for (i = 0; i < l.table.vol_cnt; i++) {
|
||||||
l.vol_vec[i].nr = i;
|
l.vol_vec[i].nr = i;
|
||||||
vol_init(&l.vol_vec[i], &l.table.vol_parm[i], l.table.ssid[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) {
|
if (l.extended) {
|
||||||
l.magic_number = DF_S390_MAGIC_EXT;
|
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 {
|
} else {
|
||||||
l.magic_number = DF_S390_MAGIC;
|
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"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
#define SYSFS_BUSDIR "/sys/bus/ccw/devices"
|
#define SYSFS_BUSDIR "bus/ccw/devices"
|
||||||
#define MAX_VOLUMES 32
|
#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)
|
static void action_set(enum zg_action action)
|
||||||
{
|
{
|
||||||
if (g.opts.action_specified)
|
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");
|
"\"-m\" or \"-u\" option");
|
||||||
g.opts.action = action;
|
g.opts.action = action;
|
||||||
g.opts.action_specified = 1;
|
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_STDOUT &&
|
||||||
g.opts.action != ZG_ACTION_DUMP_INFO)
|
g.opts.action != ZG_ACTION_DUMP_INFO)
|
||||||
ERR_EXIT("The \"--select\" option can only be "
|
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)
|
if (!g.opts.fmt_specified)
|
||||||
return;
|
return;
|
||||||
|
|||||||
114
zfcpdump/10-zfcpdump.install.in
Executable file
114
zfcpdump/10-zfcpdump.install.in
Executable file
@@ -0,0 +1,114 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# 10-zfcpdump.install - Installation script to handle zfcpdump kernels
|
||||||
|
#
|
||||||
|
# Copyright IBM Corp. 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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# This script supports two modes:
|
||||||
|
#
|
||||||
|
# 1) Installing the images to /boot/<machine-id>/<kernel-version>
|
||||||
|
# subdirectories, i.e. BOOT_DIR_ABS, as recommended by the BLS.
|
||||||
|
# In this case file names are taken over from the original files.
|
||||||
|
#
|
||||||
|
# 2) Installing the images directly to /boot. In this case the files are
|
||||||
|
# renamed to <original-name>-<kernel-version>.
|
||||||
|
#
|
||||||
|
# The existence of BOOT_DIR_ABS is taken as trigger to switch between both
|
||||||
|
# modes.
|
||||||
|
#
|
||||||
|
# The KERNEL_VERSION is assumed to contain '@flavor@' to identify the image
|
||||||
|
# as a zfcpdump kernel.
|
||||||
|
|
||||||
|
COMMAND="$1"
|
||||||
|
KERNEL_VERSION="$2"
|
||||||
|
BOOT_DIR_ABS="$3"
|
||||||
|
KERNEL_IMAGE="$4"
|
||||||
|
|
||||||
|
# Location zipl looks for the zfcpdump kernel
|
||||||
|
ZFCPDUMP_IMAGE='@zfcpdump_image@'
|
||||||
|
|
||||||
|
# Only handle zfcpdump kernels
|
||||||
|
echo "$KERNEL_VERSION" | grep -q '@flavor@' || exit 0
|
||||||
|
|
||||||
|
case "$COMMAND" in
|
||||||
|
add)
|
||||||
|
KERNEL_DIR="$(dirname $KERNEL_IMAGE)"
|
||||||
|
KERNEL_NAME="$(basename $KERNEL_IMAGE)"
|
||||||
|
|
||||||
|
for f in \
|
||||||
|
"$KERNEL_IMAGE" \
|
||||||
|
"$KERNEL_DIR"/System.map \
|
||||||
|
"$KERNEL_DIR"/config \
|
||||||
|
"$KERNEL_DIR"/zImage.stub
|
||||||
|
do
|
||||||
|
test -e "$f" || continue
|
||||||
|
test -d "$BOOT_DIR_ABS" \
|
||||||
|
&& DEST="$BOOT_DIR_ABS/$(basename $f)" \
|
||||||
|
|| DEST="/boot/$(basename $f)-$KERNEL_VERSION"
|
||||||
|
|
||||||
|
cp -aT "$f" "$DEST"
|
||||||
|
test $(command -v restorecon) && restorecon -R "$DEST"
|
||||||
|
done
|
||||||
|
|
||||||
|
# hmac file need special treatment
|
||||||
|
f="$KERNEL_DIR/.$KERNEL_NAME.hmac"
|
||||||
|
if [ -e "$f" ]; then
|
||||||
|
test -d "$BOOT_DIR_ABS" \
|
||||||
|
&& DEST="$BOOT_DIR_ABS/$(basename $f)" \
|
||||||
|
|| DEST="/boot/.$KERNEL_NAME-$KERNEL_VERSION.hmac"
|
||||||
|
|
||||||
|
cp -aT "$f" "$DEST"
|
||||||
|
test $(command -v restorecon) && restorecon -R "$DEST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set link so zipl finds the kernel
|
||||||
|
test -d "$BOOT_DIR_ABS" \
|
||||||
|
&& TARGET="$BOOT_DIR_ABS/$KERNEL_NAME" \
|
||||||
|
|| TARGET="/boot/$KERNEL_NAME-$KERNEL_VERSION"
|
||||||
|
ln -sf "$TARGET" "$ZFCPDUMP_IMAGE"
|
||||||
|
;;
|
||||||
|
|
||||||
|
remove)
|
||||||
|
# On removal
|
||||||
|
# $KERNEL_IMAGE is empty -> $KERNEL_NAME is empty -> rebuild it
|
||||||
|
KERNEL_NAME="$(basename $(readlink $ZFCPDUMP_IMAGE))"
|
||||||
|
if [ -d "$BOOT_DIR_ABS" ]; then
|
||||||
|
INSTALL_DIR="$(dirname $BOOT_DIR_ABS)"
|
||||||
|
else
|
||||||
|
INSTALL_DIR="/boot/"
|
||||||
|
KERNEL_NAME="$(echo $KERNEL_NAME \
|
||||||
|
| sed -e "s#\(.*\)-$KERNEL_VERSION#\1#")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in $(find "$INSTALL_DIR" -name "*$KERNEL_VERSION*"); do
|
||||||
|
rm -rf "$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Update link to latest remaining zfcpdump kernel.
|
||||||
|
if [ $(readlink "$ZFCPDUMP_IMAGE" | grep "$KERNEL_VERSION") ]
|
||||||
|
then
|
||||||
|
NEXT_IMAGE=$( \
|
||||||
|
find "$INSTALL_DIR" -type f \
|
||||||
|
| grep '@flavor@' \
|
||||||
|
| grep "$KERNEL_NAME" \
|
||||||
|
| grep -v "hmac" \
|
||||||
|
| sort -V \
|
||||||
|
| tail -n1 )
|
||||||
|
|
||||||
|
test $NEXT_IMAGE \
|
||||||
|
&& ln -sf "$NEXT_IMAGE" "$ZFCPDUMP_IMAGE" \
|
||||||
|
|| rm -f "$ZFCPDUMP_IMAGE"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Prevent execution of all other scripts.
|
||||||
|
# The zfcpdump kernel is stripped down to the bare minimum needed for
|
||||||
|
# dumping. It is not supposed to be used for any other purpose.
|
||||||
|
exit 77
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
|
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
|
||||||
|
INSTALL_SCRIPTS = 10-zfcpdump.install
|
||||||
|
|
||||||
ifeq (${HAVE_LIBC_STATIC},0)
|
ifeq (${HAVE_LIBC_STATIC},0)
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ check_dep:
|
|||||||
"HAVE_LIBC_STATIC=0", \
|
"HAVE_LIBC_STATIC=0", \
|
||||||
"-static")
|
"-static")
|
||||||
|
|
||||||
all: check_dep $(ZFCPDUMP_PART_RD)
|
all: check_dep $(ZFCPDUMP_INITRD) scripts
|
||||||
|
|
||||||
cpioinit: cpioinit.c
|
cpioinit: cpioinit.c
|
||||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
|
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
|
||||||
@@ -29,17 +30,26 @@ zfcpdump_part: zfcpdump.o zfcpdump_part.o
|
|||||||
$(LINK) $(ALL_LDFLAGS) $^ -static -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ -static -o $@
|
||||||
$(STRIP) -s $@
|
$(STRIP) -s $@
|
||||||
|
|
||||||
$(ZFCPDUMP_PART_RD): cpioinit zfcpdump_part
|
$(ZFCPDUMP_INITRD): cpioinit zfcpdump_part
|
||||||
$(CPIOINIT) zfcpdump_part > $@.tmp
|
$(CPIOINIT) zfcpdump_part > $@.tmp
|
||||||
$(GZIP) -f $@.tmp
|
$(GZIP) -f $@.tmp
|
||||||
$(MV) $@.tmp.gz $(ZFCPDUMP_PART_RD)
|
$(MV) $@.tmp.gz $(ZFCPDUMP_INITRD)
|
||||||
|
|
||||||
|
scripts: $(INSTALL_SCRIPTS)
|
||||||
|
chmod +x $(INSTALL_SCRIPTS)
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -m 611 $(ZFCPDUMP_PART_RD) $(DESTDIR)$(ZFCPDUMP_DIR)
|
$(INSTALL) -m 611 $(ZFCPDUMP_INITRD) $(DESTDIR)$(ZFCPDUMP_DIR)
|
||||||
|
|
||||||
|
%: %.in
|
||||||
|
zfcpdump_image=$(ZFCPDUMP_DIR)/$(ZFCPDUMP_IMAGE); \
|
||||||
|
$(SED) -e "s#@zfcpdump_image@#$$zfcpdump_image#g" \
|
||||||
|
-e "s#@flavor@#$(ZFCPDUMP_FLAVOR)#g" \
|
||||||
|
< $< > $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_PART_RD)
|
rm -f *.o *.gz *.tmp *~ zfcpdump_part cpioinit $(ZFCPDUMP_INITRD) \
|
||||||
|
$(INSTALL_SCRIPTS)
|
||||||
|
|
||||||
.PHONY: all clean install check_dep
|
.PHONY: all clean install check_dep scripts
|
||||||
|
|||||||
@@ -29,9 +29,6 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef GZIP_SUPPORT
|
|
||||||
#include <zlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
#include "zfcpdump.h"
|
#include "zfcpdump.h"
|
||||||
@@ -288,12 +285,10 @@ no_reipl:
|
|||||||
/*
|
/*
|
||||||
* Signal handler for zfcp_dumper
|
* Signal handler for zfcp_dumper
|
||||||
*/
|
*/
|
||||||
static __sighandler_t dump_sig_handler(int sig, siginfo_t *UNUSED(sip),
|
static void dump_sig_handler(int sig, siginfo_t *UNUSED(sip), void *UNUSED(p))
|
||||||
void *UNUSED(p))
|
|
||||||
{
|
{
|
||||||
PRINT_ERR("Got signal: %i\n", sig);
|
PRINT_ERR("Got signal: %i\n", sig);
|
||||||
terminate(1);
|
terminate(1);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -304,7 +299,7 @@ static __sighandler_t dump_sig_handler(int sig, siginfo_t *UNUSED(sip),
|
|||||||
static int init_sig(void)
|
static int init_sig(void)
|
||||||
{
|
{
|
||||||
g.sigact.sa_flags = (SA_NODEFER | SA_SIGINFO | SA_RESETHAND);
|
g.sigact.sa_flags = (SA_NODEFER | SA_SIGINFO | SA_RESETHAND);
|
||||||
g.sigact.sa_handler = (__sighandler_t)dump_sig_handler;
|
g.sigact.sa_sigaction = dump_sig_handler;
|
||||||
if (sigemptyset(&g.sigact.sa_mask) < 0)
|
if (sigemptyset(&g.sigact.sa_mask) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (sigaction(SIGINT, &g.sigact, NULL) < 0)
|
if (sigaction(SIGINT, &g.sigact, NULL) < 0)
|
||||||
@@ -359,41 +354,10 @@ void show_progress(unsigned long done)
|
|||||||
time_next = tv.tv_sec + 10;
|
time_next = tv.tv_sec + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Load a kernel module
|
|
||||||
*/
|
|
||||||
static void modprobe(const char *module)
|
|
||||||
{
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid < 0) {
|
|
||||||
PRINT_PERR("fork failed\n");
|
|
||||||
return;
|
|
||||||
} else if (pid == 0) {
|
|
||||||
execl("/bin/modprobe", "modprobe", module, "-q", NULL);
|
|
||||||
execl("/sbin/modprobe", "modprobe", module, "-q", NULL);
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
waitpid(pid, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load all required kernel modules
|
|
||||||
*/
|
|
||||||
static void load_modules(const char *module_list[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; module_list[i]; i++)
|
|
||||||
modprobe(module_list[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize zfcpdump
|
* Initialize zfcpdump
|
||||||
*/
|
*/
|
||||||
int zfcpdump_init(const char *module_list[])
|
int zfcpdump_init(void)
|
||||||
{
|
{
|
||||||
char start_time_str[128], linux_version[256];
|
char start_time_str[128], linux_version[256];
|
||||||
|
|
||||||
@@ -436,7 +400,6 @@ int zfcpdump_init(const char *module_list[])
|
|||||||
PRINT_ERR("Could not parse parmline\n");
|
PRINT_ERR("Could not parse parmline\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
load_modules(module_list);
|
|
||||||
if (enable_zfcp_device()) {
|
if (enable_zfcp_device()) {
|
||||||
PRINT_ERR("Could not enable dump device\n");
|
PRINT_ERR("Could not enable dump device\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ struct mem_chunk {
|
|||||||
*/
|
*/
|
||||||
void release_hsa(void);
|
void release_hsa(void);
|
||||||
__u64 get_hsa_size(void);
|
__u64 get_hsa_size(void);
|
||||||
int zfcpdump_init(const char *module_list[]);
|
int zfcpdump_init(void);
|
||||||
void print_newline(void);
|
void print_newline(void);
|
||||||
void show_progress(unsigned long done);
|
void show_progress(unsigned long done);
|
||||||
int terminate(int rc);
|
int terminate(int rc);
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ struct scsi_mbr {
|
|||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
static const char *module_list[] = {"zfcp", "sd_mod", "zcore_mod", NULL};
|
|
||||||
static struct scsi_dump_sb dump_sb;
|
static struct scsi_dump_sb dump_sb;
|
||||||
static struct scsi_mbr mbr;
|
static struct scsi_mbr mbr;
|
||||||
|
|
||||||
@@ -440,7 +439,7 @@ int main(int UNUSED(argc), char *UNUSED(argv[]))
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (zfcpdump_init(module_list))
|
if (zfcpdump_init())
|
||||||
return terminate(1);
|
return terminate(1);
|
||||||
PRINT("Dump parameters:\n");
|
PRINT("Dump parameters:\n");
|
||||||
PRINT(" devno....: %s\n", g.dump_devno);
|
PRINT(" devno....: %s\n", g.dump_devno);
|
||||||
|
|||||||
@@ -12,33 +12,33 @@ ziomon_mgr_main.o: ziomon_mgr.c
|
|||||||
ziomon_mgr: LDLIBS += -lm
|
ziomon_mgr: LDLIBS += -lm
|
||||||
ziomon_mgr: ziomon_dacc.o ziomon_util.o ziomon_mgr_main.o ziomon_tools.o \
|
ziomon_mgr: ziomon_dacc.o ziomon_util.o ziomon_mgr_main.o ziomon_tools.o \
|
||||||
ziomon_zfcpdd.o ziomon_msg_tools.o
|
ziomon_zfcpdd.o ziomon_msg_tools.o
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
ziomon_util_main.o: ziomon_util.c ziomon_util.h
|
ziomon_util_main.o: ziomon_util.c ziomon_util.h
|
||||||
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
|
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
|
||||||
ziomon_util: LDLIBS += -lm
|
ziomon_util: LDLIBS += -lm
|
||||||
ziomon_util: ziomon_util_main.o ziomon_tools.o
|
ziomon_util: ziomon_util_main.o ziomon_tools.o
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
ziomon_zfcpdd_main.o: ziomon_zfcpdd.c ziomon_zfcpdd.h
|
ziomon_zfcpdd_main.o: ziomon_zfcpdd.c ziomon_zfcpdd.h
|
||||||
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
|
$(CC) -DWITH_MAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< -o $@
|
||||||
ziomon_zfcpdd: LDLIBS += -lm -lrt -lpthread
|
ziomon_zfcpdd: LDLIBS += -lm -lrt -lpthread
|
||||||
ziomon_zfcpdd: ziomon_zfcpdd_main.o ziomon_tools.o
|
ziomon_zfcpdd: ziomon_zfcpdd_main.o ziomon_tools.o
|
||||||
$(LINK) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
ziorep_traffic: ziorep_traffic.o ziorep_framer.o ziorep_frameset.o \
|
ziorep_traffic: ziorep_traffic.o ziorep_framer.o ziorep_frameset.o \
|
||||||
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
|
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
|
||||||
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
|
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
|
||||||
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
|
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
|
||||||
ziorep_filters.o
|
ziorep_filters.o
|
||||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
ziorep_utilization: ziorep_utilization.o ziorep_framer.o ziorep_frameset.o \
|
ziorep_utilization: ziorep_utilization.o ziorep_framer.o ziorep_frameset.o \
|
||||||
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
|
ziorep_printers.o ziomon_dacc.o ziomon_util.o \
|
||||||
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
|
ziomon_msg_tools.o ziomon_tools.o ziomon_zfcpdd.o \
|
||||||
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
|
ziorep_cfgreader.o ziorep_collapser.o ziorep_utils.o \
|
||||||
ziorep_filters.o
|
ziorep_filters.o
|
||||||
$(LINKXX) $(ALL_LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
$(LINKXX) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Bootmenu Subroutines
|
* Bootmenu Subroutines
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2013, 2017
|
* Copyright IBM Corp. 2013, 2018
|
||||||
*
|
*
|
||||||
* s390-tools is free software; you can redistribute it and/or modify
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -123,7 +123,7 @@ static int menu_param(unsigned long *value)
|
|||||||
/* no number, check for keyword */
|
/* no number, check for keyword */
|
||||||
i = 0;
|
i = 0;
|
||||||
/* skip leading whitespaces */
|
/* skip leading whitespaces */
|
||||||
while (ebc_isspace(loadparm[i]) && (i < PARAM_SIZE))
|
while ((i < PARAM_SIZE) && ebc_isspace(loadparm[i]))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (!strncmp(&loadparm[i], "PROMPT", 6)) {
|
if (!strncmp(&loadparm[i], "PROMPT", 6)) {
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ struct _lowcore {
|
|||||||
|
|
||||||
/* align to the top of the prefix area */
|
/* align to the top of the prefix area */
|
||||||
uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */
|
uint8_t pad_0x1900[0x2000-0x1900]; /* 0x1900 */
|
||||||
} __packed;
|
} __packed __aligned(8192);
|
||||||
|
|
||||||
#define S390_lowcore (*((struct _lowcore *) 0))
|
#define S390_lowcore (*((struct _lowcore *) 0))
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Main program for stage3 bootloader
|
* 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
|
* s390-tools is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the MIT license. See LICENSE for details.
|
* it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -257,7 +257,7 @@ void start(void)
|
|||||||
length++;
|
length++;
|
||||||
|
|
||||||
/* find end of original parm line */
|
/* find end of original parm line */
|
||||||
while (command_line[end] != 0 && command_line[end] != 0)
|
while (command_line[end] != 0)
|
||||||
end++;
|
end++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user