mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
135 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf9fd47918 | ||
|
|
5aec1dc2a1 | ||
|
|
cf730a9632 | ||
|
|
73bab8e1a1 | ||
|
|
f97d048643 | ||
|
|
d8c630e5f4 | ||
|
|
45132ce1ee | ||
|
|
57a797350c | ||
|
|
75e3afb6a0 | ||
|
|
7915c9257b | ||
|
|
6014d07cb1 | ||
|
|
5d2ebe5301 | ||
|
|
ab510cff39 | ||
|
|
8c06dea4e5 | ||
|
|
0efacac5b8 | ||
|
|
6ea645b345 | ||
|
|
331b54d573 | ||
|
|
7e7a77675d | ||
|
|
dc2e439550 | ||
|
|
75d4317f20 | ||
|
|
58a7462f65 | ||
|
|
7c7e10ed8f | ||
|
|
0c1a63ce5e | ||
|
|
6825645a21 | ||
|
|
e764f460c4 | ||
|
|
63089835b0 | ||
|
|
e4cd42900f | ||
|
|
7f033938b8 | ||
|
|
f2dee9f542 | ||
|
|
c7a255fcd9 | ||
|
|
be7b854969 | ||
|
|
05a0f8e0eb | ||
|
|
43fcb694bf | ||
|
|
8be43a1f16 | ||
|
|
7b4a05e5a3 | ||
|
|
9911a95144 | ||
|
|
9c56255a70 | ||
|
|
a20cabccc4 | ||
|
|
f67758160e | ||
|
|
e84287e76e | ||
|
|
0c78add815 | ||
|
|
94b7a8f68d | ||
|
|
4036e80b26 | ||
|
|
a236180ad8 | ||
|
|
a9684b9154 | ||
|
|
6d31760872 | ||
|
|
b0dcc61ed5 | ||
|
|
a3e37953fe | ||
|
|
abf18cb711 | ||
|
|
22a4d45e3b | ||
|
|
e693173eef | ||
|
|
11bfa1d3c8 | ||
|
|
3ed8ab4e2a | ||
|
|
5a0c93443c | ||
|
|
b0c7965234 | ||
|
|
cdb23f8d22 | ||
|
|
60bda7ed0d | ||
|
|
4ff6519961 | ||
|
|
90dc65659f | ||
|
|
ec9c67189e | ||
|
|
951bd1ae54 | ||
|
|
ed6e3b7270 | ||
|
|
79ce120553 | ||
|
|
b45b564681 | ||
|
|
c8d0fca36c | ||
|
|
bbd88f26c9 | ||
|
|
79bfa818ed | ||
|
|
299144264d | ||
|
|
a69470d7e0 | ||
|
|
b26dbfe832 | ||
|
|
d95dc6d698 | ||
|
|
847f16f632 | ||
|
|
bc053a975a | ||
|
|
e9c030f202 | ||
|
|
dffd41943e | ||
|
|
58189b8786 | ||
|
|
b165500b69 | ||
|
|
5f2ddad6a8 | ||
|
|
28deb03178 | ||
|
|
8f1fa2a83c | ||
|
|
7677d3c0b4 | ||
|
|
6f7cb68dcf | ||
|
|
4d008849f7 | ||
|
|
d921c230ab | ||
|
|
6151889dcd | ||
|
|
224dc2e414 | ||
|
|
5a10aa73a9 | ||
|
|
428d41034e | ||
|
|
cf265cc46a | ||
|
|
84623f39dc | ||
|
|
8cbdfebc4f | ||
|
|
4951044213 | ||
|
|
667516681e | ||
|
|
10ce432196 | ||
|
|
320a49fc1a | ||
|
|
f0d18ddf2b | ||
|
|
2962248e7b | ||
|
|
773c8672ac | ||
|
|
637750f299 | ||
|
|
a17b52a043 | ||
|
|
d14051e309 | ||
|
|
d85cf20981 | ||
|
|
7df8edd88a | ||
|
|
6d382d30d9 | ||
|
|
9f8d245f92 | ||
|
|
cf39f26dee | ||
|
|
83106991ab | ||
|
|
b631c74df5 | ||
|
|
c675096899 | ||
|
|
5a9e93fb5b | ||
|
|
aefc8cd3ff | ||
|
|
a208463e49 | ||
|
|
a931428908 | ||
|
|
c2297a0a7e | ||
|
|
70a79fab3c | ||
|
|
b5a7b13e71 | ||
|
|
52b2cb8424 | ||
|
|
03b2bf028b | ||
|
|
81f9a67d6f | ||
|
|
c15f481181 | ||
|
|
4170cceb52 | ||
|
|
a648dbb014 | ||
|
|
322d51e5e4 | ||
|
|
a1db08160d | ||
|
|
31b77e1646 | ||
|
|
a4acf7c991 | ||
|
|
17cade6e7f | ||
|
|
90ea5d9e5d | ||
|
|
6accffd583 | ||
|
|
4e5afb9b71 | ||
|
|
9f247795f3 | ||
|
|
71976f8e4b | ||
|
|
851f685993 | ||
|
|
9100327092 | ||
|
|
e2d433bb10 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -69,6 +69,7 @@ zconf/scm/lsscm
|
|||||||
zconf/zcrypt/chzcrypt
|
zconf/zcrypt/chzcrypt
|
||||||
zconf/zcrypt/lszcrypt
|
zconf/zcrypt/lszcrypt
|
||||||
zconf/zcrypt/zcryptctl
|
zconf/zcrypt/zcryptctl
|
||||||
|
zconf/zcrypt/zcryptstats
|
||||||
zdev/src/chzdev
|
zdev/src/chzdev
|
||||||
zdev/src/chzdev_usage.c
|
zdev/src/chzdev_usage.c
|
||||||
zdev/src/lszdev
|
zdev/src/lszdev
|
||||||
|
|||||||
71
CHANGELOG.md
71
CHANGELOG.md
@@ -1,5 +1,76 @@
|
|||||||
Release history for s390-tools (MIT version)
|
Release history for s390-tools (MIT version)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
* __v2.9.0 (2019-05-21)__
|
||||||
|
|
||||||
|
For Linux kernel version: 5.0 / 5.1
|
||||||
|
|
||||||
|
Add new tool:
|
||||||
|
- zcryptstats: Add zcryptstats to display usage statistics of
|
||||||
|
IBM Crypto Express adapters
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- lszfcp: New command line option to show module parameters
|
||||||
|
- lszfcp: Sdev attributes for scsi_disk, block, integrity, queue, iosched
|
||||||
|
- lszfcp: Add new output marker for non-good SCSI devices (luns)
|
||||||
|
- lszfcp: Add new output marker for non-good fc_rports
|
||||||
|
- lszfcp: Clean up whitespace (mixed indentation, trailing)
|
||||||
|
- lschp: Add support for specifying a CHPID
|
||||||
|
- zipl: Add secure boot capabilities
|
||||||
|
- zkey: Add common passphrase options for cryptsetup and crypttab
|
||||||
|
- zkey: Add batch-mode option to cryptsetup and zkey-cryptsetup
|
||||||
|
- libu2s: Remove the entire library and provide more robust functionality
|
||||||
|
in libdasd and libutil instead
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- lszfcp: Allow to show zfcp_units without associated SCSI device
|
||||||
|
- lszfcp: Attribute details for: css, zfcp_port, zfcp_unit
|
||||||
|
- lszfcp: Allow to also enumerate FCP device that have never been online
|
||||||
|
- lszfcp: Fix error message if no zfcp-attached SCSI device found
|
||||||
|
- lszfcp: Fix to show defunct FCP devices again
|
||||||
|
- lszfcp: Fix to show non-good target ports again
|
||||||
|
- lszfcp: Fix missing block & sg device output without CONFIG_SYSFS_DEPRECATED
|
||||||
|
- lszfcp: New command line option for extended output format
|
||||||
|
- zfcpdbf: Warn about ambiguous payload records with dup reqid & payarea
|
||||||
|
- zpcictl: Check for regular directory to prevent possible buffer overflow
|
||||||
|
|
||||||
|
* __v2.8.0 (2019-02-15)__
|
||||||
|
|
||||||
|
For Linux kernel version: 4.20
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- Switch to using /run directory instead of the legacy /var/run
|
||||||
|
- zkey: Add --pbkdf pbkdf2 to generated cryptsetup luksFormat command
|
||||||
|
- zdsfs: Add online VTOC refresh
|
||||||
|
- pkey: Support autoloading kernel pkey module
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- zkey: Avoid EPERM on key change if user is not owner of key file
|
||||||
|
- cpumf/cpumf_helper: Always return list reference for --sfb-size
|
||||||
|
|
||||||
|
* __v2.7.1 (2018-12-13)__
|
||||||
|
|
||||||
|
For Linux kernel version: 4.19
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- zkey: Enhance file read/write error handling
|
||||||
|
- cmsfs-fuse: Write more than a single line in linefeed mode
|
||||||
|
- zpcictl: Add warning for unsupported operations
|
||||||
|
- zipl: Use the BLS "title" field as the IPL section name
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- cmsfs-fuse: Fix iconv buffer aliasing
|
||||||
|
- cmsfs-fuse: Fix memory leak in cmsfs_rename()
|
||||||
|
- fdasd: Fix possible integer overflow
|
||||||
|
- fdasd: Fix resource leak in fdasd_parse_conffile()
|
||||||
|
- zdev: Fix memory leak in misc_readlink()
|
||||||
|
- dasdinfo: Display error messages on stderr
|
||||||
|
- zkey: Include /sbin into PATH when executing commands
|
||||||
|
- Makefile: Fix parallel build
|
||||||
|
- GCC8 warning fixes across the board for:
|
||||||
|
cmsfs-fuse, dasdinfo, dasdview, dump2tar, fdasd, hmcdrvfs, hyptop,
|
||||||
|
ip_watcher, libvmdump, libvtoc, lsqeth, lszcrypt, qethqoat, zdev, zdsfs,
|
||||||
|
zgetdump, zipl, zpcictl
|
||||||
|
|
||||||
* __v2.7.0 (2018-10-31)__
|
* __v2.7.0 (2018-10-31)__
|
||||||
|
|
||||||
For Linux kernel version: 4.19
|
For Linux kernel version: 4.19
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
|
|||||||
# Include common definitions
|
# Include common definitions
|
||||||
include common.mak
|
include common.mak
|
||||||
|
|
||||||
LIB_DIRS = libvtoc libu2s libutil libzds libdasd libvmdump libccw libvmcp
|
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp
|
||||||
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
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 \
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ Package contents
|
|||||||
or show encryption state of attached LUNs.
|
or show encryption state of attached LUNs.
|
||||||
- lszcrypt: Show Information about zcrypt devices and configuration.
|
- lszcrypt: Show Information about zcrypt devices and configuration.
|
||||||
- chzcrypt: Modify the zcrypt configuration.
|
- chzcrypt: Modify the zcrypt configuration.
|
||||||
|
- zcryptstats: Display usage statistics of IBM Crypto Express adapters.
|
||||||
- znetconf: List and configure network devices for s390 network adapters.
|
- znetconf: List and configure network devices for s390 network adapters.
|
||||||
- cio_ignore: Query and modify the contents of the CIO device driver
|
- cio_ignore: Query and modify the contents of the CIO device driver
|
||||||
blacklist.
|
blacklist.
|
||||||
@@ -284,6 +285,9 @@ Build and runtime requirements for specific tools
|
|||||||
In the following more details on the build an runtime requirements of
|
In the following more details on the build an runtime requirements of
|
||||||
the different tools are provided:
|
the different tools are provided:
|
||||||
|
|
||||||
|
* dbginfo.sh:
|
||||||
|
The tar package is required to archive collected data.
|
||||||
|
|
||||||
* osasnmpd:
|
* osasnmpd:
|
||||||
You need at least the NET-SNMP 5.1.x package (net-snmp-devel.rpm)
|
You need at least the NET-SNMP 5.1.x package (net-snmp-devel.rpm)
|
||||||
installed, before building the osasnmpd subagent.
|
installed, before building the osasnmpd subagent.
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ 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 = 7
|
RELEASE = 9
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 0
|
||||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
@@ -331,10 +331,6 @@ $(rootdir)/libzds/libzds.a: $(rootdir)/libzds
|
|||||||
$(MAKE) -C $(rootdir)/libzds/ libzds.a
|
$(MAKE) -C $(rootdir)/libzds/ libzds.a
|
||||||
.PHONY: $(rootdir)/libzds
|
.PHONY: $(rootdir)/libzds
|
||||||
|
|
||||||
$(rootdir)/libu2s/libu2s.a: $(rootdir)/libu2s
|
|
||||||
$(MAKE) -C $(rootdir)/libu2s/ libu2s.a
|
|
||||||
.PHONY: $(rootdir)/libu2s
|
|
||||||
|
|
||||||
$(rootdir)/libvmdump/libvmdump.a: $(rootdir)/libvmdump
|
$(rootdir)/libvmdump/libvmdump.a: $(rootdir)/libvmdump
|
||||||
$(MAKE) -C $(rootdir)/libvmdump/ libvmdump.a
|
$(MAKE) -C $(rootdir)/libvmdump/ libvmdump.a
|
||||||
.PHONY: $(rootdir)/libvmdump
|
.PHONY: $(rootdir)/libvmdump
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ The default command is --print all.
|
|||||||
.
|
.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.nf
|
.nf
|
||||||
/var/run/cpacfstatsd_socket
|
/run/cpacfstatsd_socket
|
||||||
.fi
|
.fi
|
||||||
.
|
.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ struct msg_answer {
|
|||||||
|
|
||||||
#define BACKLOG 10
|
#define BACKLOG 10
|
||||||
|
|
||||||
#define SOCKET_FILE "/var/run/cpacfstatsd_socket"
|
#define SOCKET_FILE "/run/cpacfstatsd_socket"
|
||||||
#define PID_FILE "/var/run/cpacfstatsd.pid"
|
#define PID_FILE "/run/cpacfstatsd.pid"
|
||||||
|
|
||||||
#define CPACFSTATS_GROUP "cpacfstats"
|
#define CPACFSTATS_GROUP "cpacfstats"
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ restart the daemon to ensure correct summing of the per-CPU performance
|
|||||||
counters.
|
counters.
|
||||||
|
|
||||||
The starting daemon first checks for any stale pid file
|
The starting daemon first checks for any stale pid file
|
||||||
/var/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
/run/cpacfstatsd.pid. If this file exists, and the process ID in the
|
||||||
file belongs to an active process, an error message is printed to the
|
file belongs to an active process, an error message is printed to the
|
||||||
console and the program terminates.
|
console and the program terminates.
|
||||||
|
|
||||||
@@ -81,8 +81,8 @@ daemon startup and initialization failures.
|
|||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.nf
|
.nf
|
||||||
/var/run/cpacfstatsd_socket
|
/run/cpacfstatsd_socket
|
||||||
/var/run/cpacfstatsd.pid
|
/run/cpacfstatsd.pid
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
|||||||
@@ -51,10 +51,11 @@ sub cpumf_get_sfb_size()
|
|||||||
my $val = "0,0";
|
my $val = "0,0";
|
||||||
my $SFBSIZE;
|
my $SFBSIZE;
|
||||||
|
|
||||||
return $val unless open($SFBSIZE, '<', $CPUM_SFB_SIZE);
|
if (open($SFBSIZE, '<', $CPUM_SFB_SIZE)) {
|
||||||
$val = <$SFBSIZE>;
|
$val = <$SFBSIZE>;
|
||||||
chomp($val);
|
chomp($val);
|
||||||
close($SFBSIZE);
|
close($SFBSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
return [split /,/, $val];
|
return [split /,/, $val];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -161,8 +161,8 @@ int is_online(int cpuid)
|
|||||||
retval = 1;
|
retval = 1;
|
||||||
if (state == 0)
|
if (state == 0)
|
||||||
retval = 0;
|
retval = 0;
|
||||||
fclose(filp);
|
|
||||||
}
|
}
|
||||||
|
fclose(filp);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -220,8 +220,8 @@ int cpu_is_configured(int cpuid)
|
|||||||
retval = 1;
|
retval = 1;
|
||||||
if (state == 0)
|
if (state == 0)
|
||||||
retval = 0;
|
retval = 0;
|
||||||
fclose(filp);
|
|
||||||
}
|
}
|
||||||
|
fclose(filp);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#define NAME "cpuplugd"
|
#define NAME "cpuplugd"
|
||||||
#define MAX_HISTORY 100
|
#define MAX_HISTORY 100
|
||||||
#define PIDFILE "/var/run/cpuplugd.pid"
|
#define PIDFILE "/run/cpuplugd.pid"
|
||||||
#define LOCKFILE "/var/lock/cpuplugd.lock"
|
#define LOCKFILE "/var/lock/cpuplugd.lock"
|
||||||
#define PROCINFO_LINE 512
|
#define PROCINFO_LINE 512
|
||||||
#define CPUSTAT_SIZE 1024
|
#define CPUSTAT_SIZE 1024
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ all: dasdfmt
|
|||||||
|
|
||||||
libs = $(rootdir)/libdasd/libdasd.a \
|
libs = $(rootdir)/libdasd/libdasd.a \
|
||||||
$(rootdir)/libvtoc/libvtoc.a \
|
$(rootdir)/libvtoc/libvtoc.a \
|
||||||
$(rootdir)/libu2s/libu2s.a \
|
|
||||||
$(rootdir)/libutil/libutil.a
|
$(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
dasdfmt: dasdfmt.o $(libs)
|
dasdfmt: dasdfmt.o $(libs)
|
||||||
|
|||||||
@@ -1394,7 +1394,7 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
|||||||
if ((info->verbosity > 0) || !info->withoutprompt || info->testmode)
|
if ((info->verbosity > 0) || !info->withoutprompt || info->testmode)
|
||||||
dasdfmt_print_info(info, devname, vlabel, cylinders, heads, p);
|
dasdfmt_print_info(info, devname, vlabel, cylinders, heads, p);
|
||||||
|
|
||||||
count = u2s_get_host_access_count(devname);
|
count = dasd_get_host_access_count(devname);
|
||||||
if (info->force_host) {
|
if (info->force_host) {
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
ERRMSG_EXIT(EXIT_FAILURE,
|
ERRMSG_EXIT(EXIT_FAILURE,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
include ../common.mak
|
include ../common.mak
|
||||||
|
|
||||||
libs = $(rootdir)/libu2s/libu2s.a \
|
libs = $(rootdir)/libutil/libutil.a \
|
||||||
$(rootdir)/libutil/libutil.a \
|
|
||||||
$(rootdir)/libdasd/libdasd.a
|
$(rootdir)/libdasd/libdasd.a
|
||||||
|
|
||||||
all: dasdinfo
|
all: dasdinfo
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ all: dasdview
|
|||||||
libs = $(rootdir)/libdasd/libdasd.a \
|
libs = $(rootdir)/libdasd/libdasd.a \
|
||||||
$(rootdir)/libzds/libzds.a \
|
$(rootdir)/libzds/libzds.a \
|
||||||
$(rootdir)/libvtoc/libvtoc.a \
|
$(rootdir)/libvtoc/libvtoc.a \
|
||||||
$(rootdir)/libu2s/libu2s.a \
|
|
||||||
$(rootdir)/libutil/libutil.a
|
$(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
dasdview: dasdview.o $(libs)
|
dasdview: dasdview.o $(libs)
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
#include "lib/dasd_base.h"
|
#include "lib/dasd_base.h"
|
||||||
#include "lib/dasd_sys.h"
|
#include "lib/dasd_sys.h"
|
||||||
#include "lib/libzds.h"
|
#include "lib/libzds.h"
|
||||||
#include "lib/u2s.h"
|
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
#include "lib/util_opt.h"
|
#include "lib/util_opt.h"
|
||||||
#include "lib/util_prg.h"
|
#include "lib/util_prg.h"
|
||||||
|
#include "lib/util_sys.h"
|
||||||
#include "lib/vtoc.h"
|
#include "lib/vtoc.h"
|
||||||
#include "lib/zt_common.h"
|
#include "lib/zt_common.h"
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ dasdview_get_info(dasdview_info_t *info)
|
|||||||
else
|
else
|
||||||
info->hw_cylinders = characteristics->no_cyl;
|
info->hw_cylinders = characteristics->no_cyl;
|
||||||
|
|
||||||
if (u2s_getbusid(info->device, info->busid) == -1)
|
if (util_sys_get_dev_addr(info->device, info->busid) != 0)
|
||||||
info->busid_valid = 0;
|
info->busid_valid = 0;
|
||||||
else
|
else
|
||||||
info->busid_valid = 1;
|
info->busid_valid = 1;
|
||||||
@@ -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);
|
||||||
@@ -1741,7 +1741,7 @@ static void dasdview_print_vtoc_raw(dasdview_info_t *info)
|
|||||||
" rc=%d\n", rc);
|
" rc=%d\n", rc);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
rc = lzds_dasd_read_rawvtoc(info->dasd);
|
rc = lzds_dasd_alloc_rawvtoc(info->dasd);
|
||||||
if (rc == EINVAL) {
|
if (rc == EINVAL) {
|
||||||
zt_error_print("dasdview: Cannot read VTOC because disk does"
|
zt_error_print("dasdview: Cannot read VTOC because disk does"
|
||||||
" not contain valid VOL1 label.\n",
|
" not contain valid VOL1 label.\n",
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#define DASDVIEW_H
|
#define DASDVIEW_H
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "lib/u2s.h"
|
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* SECTION: Definitions needed for DASD-API (see dasd.h)
|
* SECTION: Definitions needed for DASD-API (see dasd.h)
|
||||||
@@ -109,7 +108,7 @@ typedef struct dasdview_info
|
|||||||
int f8c;
|
int f8c;
|
||||||
int f9c;
|
int f9c;
|
||||||
|
|
||||||
char busid[U2S_BUS_ID_SIZE];
|
char busid[DASD_BUS_ID_SIZE];
|
||||||
int busid_valid;
|
int busid_valid;
|
||||||
int raw_track_access;
|
int raw_track_access;
|
||||||
struct zdsroot *zdsroot;
|
struct zdsroot *zdsroot;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
DAEMON=cpacfstatsd
|
DAEMON=cpacfstatsd
|
||||||
DAEMON_PATH=/usr/sbin/cpacfstatsd
|
DAEMON_PATH=/usr/sbin/cpacfstatsd
|
||||||
RUN_PID_FILE=/var/run/cpacfstatsd.pid
|
RUN_PID_FILE=/run/cpacfstatsd.pid
|
||||||
RETVAL=0
|
RETVAL=0
|
||||||
OPTIONS=""
|
OPTIONS=""
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
DAEMON=cpuplugd
|
DAEMON=cpuplugd
|
||||||
DAEMON_PATH=/usr/sbin/cpuplugd
|
DAEMON_PATH=/usr/sbin/cpuplugd
|
||||||
CONFIG_FILE=/etc/cpuplugd.conf
|
CONFIG_FILE=/etc/cpuplugd.conf
|
||||||
RUN_PID_FILE=/var/run/cpuplugd.pid
|
RUN_PID_FILE=/run/cpuplugd.pid
|
||||||
RETVAL=0
|
RETVAL=0
|
||||||
OPTIONS="-c $CONFIG_FILE"
|
OPTIONS="-c $CONFIG_FILE"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ DUMP_CONFIG_FILE=/etc/sysconfig/dumpconf
|
|||||||
CMDFULL=$0
|
CMDFULL=$0
|
||||||
CMD="dumpconf"
|
CMD="dumpconf"
|
||||||
LOCKFILE=/var/lock/$CMD
|
LOCKFILE=/var/lock/$CMD
|
||||||
PIDFILE=/var/run/$CMD.pid
|
PIDFILE=/run/$CMD.pid
|
||||||
ERRMSG="Check $DUMP_CONFIG_FILE!"
|
ERRMSG="Check $DUMP_CONFIG_FILE!"
|
||||||
|
|
||||||
RETVAL=0
|
RETVAL=0
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ PROCD=mon_procd
|
|||||||
FSSTATD_PATH=/usr/sbin/$FSSTATD
|
FSSTATD_PATH=/usr/sbin/$FSSTATD
|
||||||
PROCD_PATH=/usr/sbin/$PROCD
|
PROCD_PATH=/usr/sbin/$PROCD
|
||||||
CONFIG_FILE=/etc/sysconfig/$DAEMON
|
CONFIG_FILE=/etc/sysconfig/$DAEMON
|
||||||
FSSTATD_PID_FILE=/var/run/$FSSTATD.pid
|
FSSTATD_PID_FILE=/run/$FSSTATD.pid
|
||||||
PROCD_PID_FILE=/var/run/$PROCD.pid
|
PROCD_PID_FILE=/run/$PROCD.pid
|
||||||
|
|
||||||
# source function library
|
# source function library
|
||||||
. /lib/lsb/init-functions
|
. /lib/lsb/init-functions
|
||||||
|
|||||||
2
etc/modules-load.d/s390-pkey.conf
Normal file
2
etc/modules-load.d/s390-pkey.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Load protected key support module on s390 early at boot
|
||||||
|
pkey
|
||||||
@@ -3,7 +3,6 @@ include ../common.mak
|
|||||||
libs = $(rootdir)/libvtoc/libvtoc.a \
|
libs = $(rootdir)/libvtoc/libvtoc.a \
|
||||||
$(rootdir)/libzds/libzds.a \
|
$(rootdir)/libzds/libzds.a \
|
||||||
$(rootdir)/libdasd/libdasd.a \
|
$(rootdir)/libdasd/libdasd.a \
|
||||||
$(rootdir)/libu2s/libu2s.a \
|
|
||||||
$(rootdir)/libutil/libutil.a
|
$(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
all: fdasd
|
all: fdasd
|
||||||
|
|||||||
@@ -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]);
|
||||||
@@ -935,7 +935,7 @@ static void fdasd_verify_device(fdasd_anchor_t *anc, char *name)
|
|||||||
fdasd_error(anc, device_verification_failed, err_str);
|
fdasd_error(anc, device_verification_failed, err_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = u2s_get_host_access_count(name);
|
count = dasd_get_host_access_count(name);
|
||||||
if (anc->force_host) {
|
if (anc->force_host) {
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
snprintf(err_str, ERROR_STRING_SIZE,
|
snprintf(err_str, ERROR_STRING_SIZE,
|
||||||
@@ -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';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
/* A bus id of a DASD is 8 characters long. E.g. 0.0.4711 */
|
||||||
|
#define DASD_BUS_ID_SIZE 9
|
||||||
|
|
||||||
typedef struct dasd_information2_t {
|
typedef struct dasd_information2_t {
|
||||||
unsigned int devno; /* S/390 devno */
|
unsigned int devno; /* S/390 devno */
|
||||||
unsigned int real_devno; /* for aliases */
|
unsigned int real_devno; /* for aliases */
|
||||||
@@ -170,6 +173,10 @@ struct hd_geometry {
|
|||||||
#define BIODASDDISABLE _IO(DASD_IOCTL_LETTER, 0)
|
#define BIODASDDISABLE _IO(DASD_IOCTL_LETTER, 0)
|
||||||
/* Enable the volume (for Linux) */
|
/* Enable the volume (for Linux) */
|
||||||
#define BIODASDENABLE _IO(DASD_IOCTL_LETTER, 1)
|
#define BIODASDENABLE _IO(DASD_IOCTL_LETTER, 1)
|
||||||
|
/* Reserve the device for the current LPAR */
|
||||||
|
#define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2)
|
||||||
|
/* Release the device for the current LPAR */
|
||||||
|
#define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3)
|
||||||
/* Get information on a dasd device (enhanced) */
|
/* Get information on a dasd device (enhanced) */
|
||||||
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
||||||
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
||||||
@@ -203,5 +210,7 @@ int dasd_get_geo(const char *device, struct hd_geometry *geo);
|
|||||||
int dasd_get_info(const char *device, dasd_information2_t *info);
|
int dasd_get_info(const char *device, dasd_information2_t *info);
|
||||||
int dasd_is_ro(const char *device, bool *ro);
|
int dasd_is_ro(const char *device, bool *ro);
|
||||||
int dasd_reread_partition_table(const char *device, int ntries);
|
int dasd_reread_partition_table(const char *device, int ntries);
|
||||||
|
int dasd_disk_reserve(const char *device);
|
||||||
|
int dasd_disk_release(const char *device);
|
||||||
|
|
||||||
#endif /* LIB_DASD_BASE_H */
|
#endif /* LIB_DASD_BASE_H */
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
#define LIB_DASD_SYS_H
|
#define LIB_DASD_SYS_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "u2s.h"
|
|
||||||
|
|
||||||
int dasd_sys_raw_track_access(char *);
|
int dasd_sys_raw_track_access(char *);
|
||||||
int dasd_reset_chpid(char *, char *);
|
int dasd_reset_chpid(char *, char *);
|
||||||
|
int dasd_get_host_access_count(char *device);
|
||||||
|
|
||||||
#endif /* LIB_DASD_SYS_H */
|
#endif /* LIB_DASD_SYS_H */
|
||||||
|
|||||||
@@ -112,6 +112,8 @@
|
|||||||
*/
|
*/
|
||||||
#define LIB_LIBZDS_H
|
#define LIB_LIBZDS_H
|
||||||
|
|
||||||
|
#include "lib/util_base.h"
|
||||||
|
#include "lib/util_list.h"
|
||||||
#include "vtoc.h"
|
#include "vtoc.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -328,11 +330,74 @@ struct pds_member_entry {
|
|||||||
*/
|
*/
|
||||||
struct zdsroot;
|
struct zdsroot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct raw_vtoc
|
||||||
|
* @brief The VTOC is a directory of data sets on one DASD
|
||||||
|
*
|
||||||
|
* As the VTOC is the data area on the DASD that describes all data sets,
|
||||||
|
* this library will often have to refer to the various records in the VTOC.
|
||||||
|
* To make this more efficient, we will read the whole VTOC once and identify
|
||||||
|
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
||||||
|
* DSCBs is stored.
|
||||||
|
*/
|
||||||
|
struct raw_vtoc {
|
||||||
|
/** @brief The raw track data */
|
||||||
|
char *rawdata;
|
||||||
|
/** @brief This size of the raw track data in bytes */
|
||||||
|
unsigned long long rawdatasize;
|
||||||
|
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
||||||
|
char **vtocindex;
|
||||||
|
/** @brief Number of entries in the index */
|
||||||
|
unsigned int vtocindexcount;
|
||||||
|
/** @brief Number of records per VTOC track
|
||||||
|
*
|
||||||
|
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
||||||
|
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
||||||
|
* for record 0.
|
||||||
|
*/
|
||||||
|
unsigned int vtoc_rec_per_track;
|
||||||
|
/** @brief The track number at which the vtoc begins on the DASD */
|
||||||
|
unsigned int vtoctrackoffset;
|
||||||
|
/** @brief Start record of VTOC.
|
||||||
|
*
|
||||||
|
* The rawdata contains full tracks. This is the number of the first
|
||||||
|
* record that actually belongs to the VTOC
|
||||||
|
*/
|
||||||
|
unsigned int vtocrecno;
|
||||||
|
/** @brief The DASD this vtoc was read from */
|
||||||
|
struct dasd *dasd;
|
||||||
|
/** @brief Detailed error messages in case of a problem */
|
||||||
|
struct errorlog *log;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct dasd
|
* @struct dasd
|
||||||
* @brief Represents one physical device, may have a vtoc
|
* @brief Represents one physical device, may have a vtoc
|
||||||
*/
|
*/
|
||||||
struct dasd;
|
struct dasd {
|
||||||
|
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
||||||
|
struct util_list_node list;
|
||||||
|
/** @brief Name of the block device, e.g. /dev/dasde */
|
||||||
|
char *device;
|
||||||
|
/** @brief File descriptor for the block device.
|
||||||
|
*
|
||||||
|
* The device is kept open for as along as the library uses it.
|
||||||
|
* This lets the system know that the device is still in use.
|
||||||
|
*/
|
||||||
|
int inusefd;
|
||||||
|
/* @brief where to find the volume label */
|
||||||
|
unsigned int label_block;
|
||||||
|
/** @brief Device geometry. How many cylinders does the DASD have. */
|
||||||
|
unsigned int cylinders;
|
||||||
|
/** @brief Device geometry. How many heads does the DASD have. */
|
||||||
|
unsigned int heads;
|
||||||
|
/** @brief The VTOC data that has been read from this device */
|
||||||
|
struct raw_vtoc *rawvtoc;
|
||||||
|
/** @brief The volume label that has been read from this device */
|
||||||
|
volume_label_t *vlabel;
|
||||||
|
/** @brief Detailed error messages in case of a problem */
|
||||||
|
struct errorlog *log;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct dasditerator
|
* @struct dasditerator
|
||||||
@@ -350,12 +415,6 @@ struct dasditerator;
|
|||||||
*/
|
*/
|
||||||
struct dasdhandle;
|
struct dasdhandle;
|
||||||
|
|
||||||
/**
|
|
||||||
* @struct raw_vtoc
|
|
||||||
* @brief The VTOC is a directory of data sets on one dasd
|
|
||||||
*/
|
|
||||||
struct raw_vtoc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct dscbiterator
|
* @struct dscbiterator
|
||||||
* @brief allows to iterate over all DSCBs in a vtoc
|
* @brief allows to iterate over all DSCBs in a vtoc
|
||||||
@@ -572,7 +631,13 @@ int lzds_dasd_get_vlabel(struct dasd *dasd, struct volume_label **vlabel);
|
|||||||
* @brief Read the vtoc data from device. The data as stored as part
|
* @brief Read the vtoc data from device. The data as stored as part
|
||||||
* of the struct dasd.
|
* of the struct dasd.
|
||||||
*/
|
*/
|
||||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd);
|
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *vtoc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the vtoc data from device. The data as stored as part
|
||||||
|
* of the struct dasd.
|
||||||
|
*/
|
||||||
|
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the previously read raw_vtoc data.
|
* @brief Get the previously read raw_vtoc data.
|
||||||
@@ -787,6 +852,8 @@ int lzds_zdsroot_extract_datasets_from_dasd(struct zdsroot *root,
|
|||||||
struct dasd *dasd);
|
struct dasd *dasd);
|
||||||
|
|
||||||
|
|
||||||
|
void lzds_dslist_free(struct zdsroot *root);
|
||||||
|
|
||||||
|
|
||||||
/** @} */ /* end of group libzds_functions_high */
|
/** @} */ /* end of group libzds_functions_high */
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright IBM Corp. 2004, 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.
|
|
||||||
*
|
|
||||||
* History of changes (starts July 2004)
|
|
||||||
* 2004-07-02 initial
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LIB_U2S_H
|
|
||||||
#define LIB_U2S_H
|
|
||||||
|
|
||||||
#define U2S_BUS_ID_SIZE 32
|
|
||||||
|
|
||||||
int u2s_getbusid(char *, char *);
|
|
||||||
int u2s_read_attribute(char *, char *, char *, size_t);
|
|
||||||
int u2s_get_host_access_count(char *);
|
|
||||||
|
|
||||||
#endif /* LIB_U2S_H */
|
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,5 +68,8 @@ const char *util_rec_get(struct util_rec *rec, const char *key);
|
|||||||
|
|
||||||
void util_rec_print_hdr(struct util_rec *rec);
|
void util_rec_print_hdr(struct util_rec *rec);
|
||||||
void util_rec_print(struct util_rec *rec);
|
void util_rec_print(struct util_rec *rec);
|
||||||
|
void util_rec_print_separator(struct util_rec *rec);
|
||||||
|
|
||||||
|
void util_rec_set_indent(struct util_rec *rec, int indent);
|
||||||
|
|
||||||
#endif /** LIB_UTIL_REC_H @} */
|
#endif /** LIB_UTIL_REC_H @} */
|
||||||
|
|||||||
17
include/lib/util_sys.h
Normal file
17
include/lib/util_sys.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* @defgroup util_sys_h util_sys: SysFS interface
|
||||||
|
* @{
|
||||||
|
* @brief Work with SysFS
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2019
|
||||||
|
*
|
||||||
|
* 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 LIB_UTIL_SYS_H
|
||||||
|
#define LIB_UTIL_SYS_H
|
||||||
|
|
||||||
|
int util_sys_get_dev_addr(const char *dev, char *addr);
|
||||||
|
|
||||||
|
#endif /** LIB_UTIL_SYS_H @} */
|
||||||
@@ -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,11 +1,15 @@
|
|||||||
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) $^ $(LDLIBS) -o $@
|
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
lsreipl:
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -261,3 +261,42 @@ int dasd_reread_partition_table(const char *device, int ntries)
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserve DASD disk.
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int dasd_disk_reserve(const char *device)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDRSRV, NULL);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release DASD disk
|
||||||
|
*
|
||||||
|
* @param[in] device node device node's name
|
||||||
|
*
|
||||||
|
* @retval 0 in case of success
|
||||||
|
* @retval errno in case of failure
|
||||||
|
*/
|
||||||
|
int dasd_disk_release(const char *device)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dasd_open_device(device, O_RDONLY);
|
||||||
|
RUN_IOCTL(fd, BIODASDRLSE, NULL);
|
||||||
|
dasd_close_device(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lib/dasd_base.h"
|
||||||
#include "lib/dasd_sys.h"
|
#include "lib/dasd_sys.h"
|
||||||
|
#include "lib/util_file.h"
|
||||||
|
#include "lib/util_path.h"
|
||||||
|
#include "lib/util_sys.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get raw-track access mode status
|
* Get raw-track access mode status
|
||||||
@@ -31,22 +35,24 @@
|
|||||||
*/
|
*/
|
||||||
int dasd_sys_raw_track_access(char *devnode)
|
int dasd_sys_raw_track_access(char *devnode)
|
||||||
{
|
{
|
||||||
char busid[9];
|
char busid[DASD_BUS_ID_SIZE];
|
||||||
char path[47];
|
char *path;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (u2s_getbusid(devnode, busid))
|
if (util_sys_get_dev_addr(devnode, busid) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sprintf(path, "/sys/bus/ccw/devices/%s/raw_track_access", busid);
|
path = util_path_sysfs("bus/ccw/devices/%s/raw_track_access", busid);
|
||||||
|
|
||||||
fp = fopen(path, "r");
|
fp = fopen(path, "r");
|
||||||
if (!fp)
|
if (!fp) {
|
||||||
|
free(path);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
rc = fgetc(fp) - '0';
|
rc = fgetc(fp) - '0';
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(path);
|
||||||
|
|
||||||
return (rc == 1) ? 1 : 0;
|
return (rc == 1) ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -55,15 +61,17 @@ int dasd_sys_raw_track_access(char *devnode)
|
|||||||
int dasd_get_pm_from_chpid(char *busid, unsigned int chpid, int *mask)
|
int dasd_get_pm_from_chpid(char *busid, unsigned int chpid, int *mask)
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
char path[40];
|
|
||||||
int count, i;
|
int count, i;
|
||||||
|
char *path;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
sprintf(path, "/sys/bus/ccw/devices/%s/../chpids", busid);
|
path = util_path_sysfs("bus/ccw/devices/%s/../chpids", busid);
|
||||||
*mask = 0;
|
*mask = 0;
|
||||||
fp = fopen(path, "r");
|
fp = fopen(path, "r");
|
||||||
if (!fp)
|
if (!fp) {
|
||||||
|
free(path);
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
count = fscanf(fp, " %x", &val);
|
count = fscanf(fp, " %x", &val);
|
||||||
@@ -75,6 +83,7 @@ int dasd_get_pm_from_chpid(char *busid, unsigned int chpid, int *mask)
|
|||||||
*mask = 0x80 >> i;
|
*mask = 0x80 >> i;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -102,22 +111,25 @@ int dasd_get_pm_from_chpid(char *busid, unsigned int chpid, int *mask)
|
|||||||
int dasd_reset_chpid(char *devnode, char *chpid_char)
|
int dasd_reset_chpid(char *devnode, char *chpid_char)
|
||||||
{
|
{
|
||||||
unsigned int chpid;
|
unsigned int chpid;
|
||||||
char path[41];
|
char busid[DASD_BUS_ID_SIZE];
|
||||||
char busid[9];
|
|
||||||
int mask, rc;
|
int mask, rc;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
char *path;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (u2s_getbusid(devnode, busid))
|
if (util_sys_get_dev_addr(devnode, busid) != 0)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|
||||||
if (!chpid_char) {
|
if (!chpid_char) {
|
||||||
sprintf(path, "/sys/bus/ccw/devices/%s/path_reset", busid);
|
path = util_path_sysfs("bus/ccw/devices/%s/path_reset", busid);
|
||||||
fp = fopen(path, "w");
|
fp = fopen(path, "w");
|
||||||
if (!fp)
|
if (!fp) {
|
||||||
|
free(path);
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
}
|
||||||
fprintf(fp, "%s", "all\n");
|
fprintf(fp, "%s", "all\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,12 +144,45 @@ int dasd_reset_chpid(char *devnode, char *chpid_char)
|
|||||||
if (!mask)
|
if (!mask)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
|
||||||
sprintf(path, "/sys/bus/ccw/devices/%s/path_reset", busid);
|
path = util_path_sysfs("bus/ccw/devices/%s/path_reset", busid);
|
||||||
fp = fopen(path, "w");
|
fp = fopen(path, "w");
|
||||||
if (!fp)
|
if (!fp) {
|
||||||
|
free(path);
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
}
|
||||||
fprintf(fp, "%02x", mask);
|
fprintf(fp, "%02x", mask);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read amount of host with access to \p device
|
||||||
|
*
|
||||||
|
* The \p device can be any valid relative or absolute path to a DASD device
|
||||||
|
* node, for example:
|
||||||
|
*
|
||||||
|
* - /dev/dasda
|
||||||
|
* - /dev/disk/by-path/ccw-0.0.bf20
|
||||||
|
*
|
||||||
|
* @param[in] device Device node of interest
|
||||||
|
*
|
||||||
|
* @retval n Number of hosts with access to \p device
|
||||||
|
* @retval 0 Value could not be determined
|
||||||
|
*/
|
||||||
|
int dasd_get_host_access_count(char *device)
|
||||||
|
{
|
||||||
|
char busid[9];
|
||||||
|
char *path;
|
||||||
|
long value;
|
||||||
|
|
||||||
|
if (!util_sys_get_dev_addr(device, busid))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
path = util_path_sysfs("bus/ccw/devices/%s/host_access_count", busid);
|
||||||
|
util_file_read_l(&value, 10, path);
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
include ../common.mak
|
|
||||||
|
|
||||||
lib = libu2s.a
|
|
||||||
|
|
||||||
all: $(lib)
|
|
||||||
|
|
||||||
objects = u2s.o misc.o
|
|
||||||
|
|
||||||
$(lib): $(objects)
|
|
||||||
|
|
||||||
install: all
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o $(lib)
|
|
||||||
@@ -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 */
|
|
||||||
334
libu2s/u2s.c
334
libu2s/u2s.c
@@ -1,334 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright IBM Corp. 2004, 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 <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/sysmacros.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <wait.h>
|
|
||||||
|
|
||||||
#include "lib/u2s.h"
|
|
||||||
#include "misc.h"
|
|
||||||
|
|
||||||
#define DEV_BUFFER_LENGTH 20
|
|
||||||
#define PATH_BUFFER_LENGTH 256
|
|
||||||
#define BUSIDSIZE 9
|
|
||||||
|
|
||||||
#define BLOCKPATH "/sys/block/"
|
|
||||||
#define DEVICE_LINK "device"
|
|
||||||
#define DEV_ATTRIBUTE "dev"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper function that expects a file name and returns 1 if this
|
|
||||||
* is a directory or 0 otherwise.
|
|
||||||
*/
|
|
||||||
static int isdir(char *name) {
|
|
||||||
|
|
||||||
struct stat statbuf;
|
|
||||||
|
|
||||||
if (stat(name, &statbuf) < 0)
|
|
||||||
return 0;
|
|
||||||
return S_ISDIR(statbuf.st_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper function that expects a directory name in sysfs of the form
|
|
||||||
* /sys/block/<devname>/ or /sys/block/<devname>/<partname>/.
|
|
||||||
* It will try to read the file "dev" in this directory and compare
|
|
||||||
* it's contents with the given dev string of the form <major>:<minor>.
|
|
||||||
* Trailing white space (newline) is ignored.
|
|
||||||
* The buffer name is expected to be long enough to hold the additional "dev".
|
|
||||||
* Returns 1 if the directory matches dev, 0 otherwise.
|
|
||||||
*/
|
|
||||||
static int check_directory(char *name, char *dev) {
|
|
||||||
|
|
||||||
char buffer[DEV_BUFFER_LENGTH];
|
|
||||||
char *end;
|
|
||||||
int fd;
|
|
||||||
ssize_t count;
|
|
||||||
int dev_attr_len, dev_parm_len;
|
|
||||||
unsigned int namelen;
|
|
||||||
|
|
||||||
namelen = strlen(name);
|
|
||||||
if ((PATH_BUFFER_LENGTH - namelen) < sizeof(DEV_ATTRIBUTE))
|
|
||||||
return 0;
|
|
||||||
end = name + namelen;
|
|
||||||
strcpy(end, DEV_ATTRIBUTE);
|
|
||||||
fd = open(name, O_RDONLY);
|
|
||||||
*end = 0;
|
|
||||||
if (fd < 0)
|
|
||||||
return 0;
|
|
||||||
count = read(fd, buffer, DEV_BUFFER_LENGTH);
|
|
||||||
close(fd);
|
|
||||||
if (count < 0)
|
|
||||||
return 0;
|
|
||||||
dev_attr_len = strspn(buffer, "1234567890:");
|
|
||||||
dev_parm_len = strlen(dev);
|
|
||||||
if (dev_attr_len != dev_parm_len )
|
|
||||||
return 0;
|
|
||||||
return (strncmp(dev, buffer, dev_parm_len) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper function that expects a directory name in sysfs of the form
|
|
||||||
* /sys/block/<devname>/. It will try to read a link "device"
|
|
||||||
* in this directory and extract the busid, which is the last part
|
|
||||||
* of that link. The buffer name is expected to be long enough
|
|
||||||
* to hold the additional "device".
|
|
||||||
* name: block device path in sysfs.
|
|
||||||
* busid: buffer in which the busid string will be returned
|
|
||||||
* returns 0 for successful operation and -1 in case of an error.
|
|
||||||
*/
|
|
||||||
static int extract_busid(char *name, char *busid) {
|
|
||||||
|
|
||||||
int count;
|
|
||||||
unsigned int namelen;
|
|
||||||
char linkbuffer[PATH_BUFFER_LENGTH];
|
|
||||||
char *start, *end;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
namelen = strlen(name);
|
|
||||||
if ((PATH_BUFFER_LENGTH - namelen) < sizeof(DEVICE_LINK))
|
|
||||||
return 0;
|
|
||||||
end = name + namelen;
|
|
||||||
strcpy(end, DEVICE_LINK);
|
|
||||||
count = readlink(name, linkbuffer, PATH_BUFFER_LENGTH - 1);
|
|
||||||
if (count < 0)
|
|
||||||
return -1;
|
|
||||||
linkbuffer[count] = 0;
|
|
||||||
start = strrchr(linkbuffer, '/');
|
|
||||||
if (!start)
|
|
||||||
return -1;
|
|
||||||
start++;
|
|
||||||
len = misc_strlcpy(busid, start, BUSIDSIZE);
|
|
||||||
if (len >= BUSIDSIZE)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper function that makes some basic checks on a directory entry.
|
|
||||||
* The function checks if there is still enough space left in the buffer
|
|
||||||
* for the new string, excludes '.' and '..', and verifies that the entry
|
|
||||||
* is actually a directory.
|
|
||||||
* buffer: the beginning of the name buffer
|
|
||||||
* oldend: the current end of the string in the name buffer
|
|
||||||
* dir: the dirent in question
|
|
||||||
* returns: a pointer to the new end of the string in buffer or NULL if
|
|
||||||
* one of the checks failed
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char *append_if_directory(char *buffer, char *oldend, struct dirent *dir) {
|
|
||||||
|
|
||||||
char *newend;
|
|
||||||
int oldlength, dirlength;
|
|
||||||
|
|
||||||
if (strcmp(dir->d_name, ".") == 0 ||
|
|
||||||
strcmp(dir->d_name, "..") == 0)
|
|
||||||
return NULL;
|
|
||||||
oldlength = strlen(buffer);
|
|
||||||
dirlength = strlen(dir->d_name);
|
|
||||||
if (PATH_BUFFER_LENGTH < oldlength + dirlength + 2)
|
|
||||||
return NULL;
|
|
||||||
strcpy(oldend, dir->d_name);
|
|
||||||
if (!isdir(buffer)) {
|
|
||||||
*oldend = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
newend = oldend + dirlength;
|
|
||||||
strcpy(newend, "/");
|
|
||||||
newend++;
|
|
||||||
|
|
||||||
return newend;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* helper function that searches for a specific block device and returns
|
|
||||||
* it's busid
|
|
||||||
* dev: <major>:<minor> of the device
|
|
||||||
* busid: buffer in which the busid string will be returned
|
|
||||||
* returns 0 for successful operation and -1 in case of an error.
|
|
||||||
*/
|
|
||||||
static int find_busid_in_sysfs(char *dev, char *busid) {
|
|
||||||
|
|
||||||
DIR *blockdir, *diskdir;
|
|
||||||
struct dirent *blockde, *diskde;
|
|
||||||
int found = 0;
|
|
||||||
char namebuffer[PATH_BUFFER_LENGTH];
|
|
||||||
char *blockend, *diskend = NULL, *partend;
|
|
||||||
|
|
||||||
/* everything, including the other helper functions, works on the
|
|
||||||
* same buffer area 'namebuffer'. The pointers blockend, diskend
|
|
||||||
* and partend point to the end of the various names.
|
|
||||||
* Example:
|
|
||||||
* "/sys/block/dasda/dasda1/"
|
|
||||||
* ^ blockend
|
|
||||||
* ^ diskend
|
|
||||||
* ^ partend
|
|
||||||
*/
|
|
||||||
|
|
||||||
strcpy(namebuffer,BLOCKPATH);
|
|
||||||
blockdir = opendir(namebuffer);
|
|
||||||
if (!blockdir)
|
|
||||||
return -1;
|
|
||||||
blockend = namebuffer + strlen(namebuffer);
|
|
||||||
/* check each entry in /sys/block */
|
|
||||||
while ((blockde = readdir(blockdir))) {
|
|
||||||
diskend = append_if_directory(namebuffer, blockend, blockde);
|
|
||||||
if (!diskend)
|
|
||||||
continue;
|
|
||||||
found = check_directory(namebuffer, dev);
|
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
diskdir = opendir(namebuffer);
|
|
||||||
if (!diskdir)
|
|
||||||
continue;
|
|
||||||
/* check each entry in /sys/block/<disk name> */
|
|
||||||
while ((diskde = readdir(diskdir))) {
|
|
||||||
partend = append_if_directory(
|
|
||||||
namebuffer, diskend, diskde);
|
|
||||||
if (!partend)
|
|
||||||
continue;
|
|
||||||
found = check_directory(namebuffer, dev);
|
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
closedir(diskdir);
|
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
closedir(blockdir);
|
|
||||||
if (found) {
|
|
||||||
*diskend = 0; /* remove partition directory from name */
|
|
||||||
return extract_busid(namebuffer, busid);
|
|
||||||
} else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* helper function that searches for a specific block device in
|
|
||||||
* /proc/dasd/devices and returns it's bus-ID
|
|
||||||
* maja, mina: <major>, <minor> of the device
|
|
||||||
* busid: buffer in which the bus-ID string will be returned
|
|
||||||
* returns 0 for successful operation and -1 in case of an error
|
|
||||||
* e.g. /proc/dasd/devices does not exist.
|
|
||||||
*
|
|
||||||
* An entry looks like:
|
|
||||||
* 0.0.XXXX(DISCIPLINE) at ( MAJ: MIN) is dasdX :
|
|
||||||
* active at blocksize: BLOCKSIZE, BLOCKS blocks, SIZE MB
|
|
||||||
*/
|
|
||||||
static int find_busid_in_proc(int maja, int mina, char *busid)
|
|
||||||
{
|
|
||||||
FILE *filp;
|
|
||||||
char bus[BUSIDSIZE];
|
|
||||||
int majb, minb, rc;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
filp = fopen("/proc/dasd/devices", "r");
|
|
||||||
if (!filp)
|
|
||||||
return rc;
|
|
||||||
while (fscanf(filp, "%[^(] %*[^)] ) at ( %d : %d %*[^\n]\n",
|
|
||||||
bus, &majb, &minb) != EOF) {
|
|
||||||
if ((maja == majb) && (mina == minb)) {
|
|
||||||
len = misc_strlcpy(busid, bus, BUSIDSIZE);
|
|
||||||
if (len < BUSIDSIZE)
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(filp);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the busid of a given device node.
|
|
||||||
* Works only for block devices.
|
|
||||||
* devicenode: path to the device node
|
|
||||||
* busid: buffer in which the busid string will be returned
|
|
||||||
* returns 0 for successful operation and -1 in case of an error.
|
|
||||||
*/
|
|
||||||
int u2s_getbusid(char *devicenode, char *busid)
|
|
||||||
{
|
|
||||||
int maj, min, rc;
|
|
||||||
struct stat stat_buf;
|
|
||||||
char dev_string[DEV_BUFFER_LENGTH];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get major and minor information of the device special file
|
|
||||||
* and combine them to a <maj>:<min> string, as returned by
|
|
||||||
* the dev attributes in sysfs
|
|
||||||
*/
|
|
||||||
if (stat(devicenode, &stat_buf))
|
|
||||||
return -1;
|
|
||||||
if (!S_ISBLK(stat_buf.st_mode))
|
|
||||||
return -1;
|
|
||||||
maj = major(stat_buf.st_rdev);
|
|
||||||
min = minor(stat_buf.st_rdev);
|
|
||||||
|
|
||||||
rc = find_busid_in_proc(maj, min, busid);
|
|
||||||
if (rc) {
|
|
||||||
snprintf(dev_string, DEV_BUFFER_LENGTH, "%u:%u", maj, min);
|
|
||||||
rc = find_busid_in_sysfs(dev_string, busid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Attempts to find the sysfs entry for the given busid and reads
|
|
||||||
* the contents of a specified attribute to the buffer
|
|
||||||
*/
|
|
||||||
int u2s_read_attribute(char *busid, char *attribute, char *buffer,
|
|
||||||
size_t count)
|
|
||||||
{
|
|
||||||
char path[100];
|
|
||||||
int rc, fd;
|
|
||||||
ssize_t rcount;
|
|
||||||
|
|
||||||
rc = 0;
|
|
||||||
snprintf(path, sizeof(path), "/sys/bus/ccw/devices/%s/%s",
|
|
||||||
busid, attribute);
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
return errno;
|
|
||||||
rcount = read(fd, buffer, count);
|
|
||||||
if (rcount < 0)
|
|
||||||
rc = errno;
|
|
||||||
close(fd);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int u2s_get_host_access_count(char *devicenode)
|
|
||||||
{
|
|
||||||
char busid[BUSIDSIZE];
|
|
||||||
unsigned long value;
|
|
||||||
char buffer[10];
|
|
||||||
char *endp;
|
|
||||||
|
|
||||||
u2s_getbusid(devicenode, busid);
|
|
||||||
u2s_read_attribute(busid, "host_access_count", buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
value = strtoul(buffer, &endp, 0);
|
|
||||||
|
|
||||||
if (endp == buffer)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
@@ -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 \
|
||||||
@@ -26,7 +27,8 @@ objects = util_base.o \
|
|||||||
util_part.o \
|
util_part.o \
|
||||||
util_prg.o \
|
util_prg.o \
|
||||||
util_proc.o \
|
util_proc.o \
|
||||||
util_rec.o
|
util_rec.o \
|
||||||
|
util_sys.o
|
||||||
|
|
||||||
util_base_example: util_base_example.o $(lib)
|
util_base_example: util_base_example.o $(lib)
|
||||||
util_panic_example: util_panic_example.o $(lib)
|
util_panic_example: util_panic_example.o $(lib)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ struct rec_fmt {
|
|||||||
int argz_sep;
|
int argz_sep;
|
||||||
} csv_p;
|
} csv_p;
|
||||||
} d;
|
} d;
|
||||||
|
int indent;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -122,9 +123,50 @@ struct util_rec *util_rec_new_wide(const char *hdr_sep)
|
|||||||
rec->fmt.type = REC_FMT_WIDE;
|
rec->fmt.type = REC_FMT_WIDE;
|
||||||
rec->fmt.d.wide_p.hdr_sep = util_strdup(hdr_sep);
|
rec->fmt.d.wide_p.hdr_sep = util_strdup(hdr_sep);
|
||||||
rec->fmt.d.wide_p.argz_sep = ',';
|
rec->fmt.d.wide_p.argz_sep = ',';
|
||||||
|
rec->fmt.indent = 0;
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the indentation characters
|
||||||
|
*/
|
||||||
|
static inline void rec_print_indention(int indent)
|
||||||
|
{
|
||||||
|
if (indent <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("%*s", indent, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print record separator in "wide" output format
|
||||||
|
*/
|
||||||
|
static void rec_print_wide_separator(struct util_rec *rec)
|
||||||
|
{
|
||||||
|
const char *hdr_sep = rec->fmt.d.wide_p.hdr_sep;
|
||||||
|
int size = 0, field_count = 0;
|
||||||
|
struct util_rec_fld *fld;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if (!hdr_sep)
|
||||||
|
return;
|
||||||
|
|
||||||
|
util_list_iterate(rec->list, fld) {
|
||||||
|
if (fld->hdr) {
|
||||||
|
size += fld->width;
|
||||||
|
field_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size += field_count - 1;
|
||||||
|
buf = util_malloc(size + 1);
|
||||||
|
memset(buf, (int)hdr_sep[0], size);
|
||||||
|
buf[size] = 0;
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
|
printf("%s\n", buf);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print record header in "wide" output format
|
* Print record header in "wide" output format
|
||||||
*/
|
*/
|
||||||
@@ -135,6 +177,7 @@ static void rec_print_wide_hdr(struct util_rec *rec)
|
|||||||
struct util_rec_fld *fld;
|
struct util_rec_fld *fld;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
util_list_iterate(rec->list, fld) {
|
util_list_iterate(rec->list, fld) {
|
||||||
if (col_nr)
|
if (col_nr)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
@@ -156,6 +199,7 @@ static void rec_print_wide_hdr(struct util_rec *rec)
|
|||||||
buf = util_malloc(size + 1);
|
buf = util_malloc(size + 1);
|
||||||
memset(buf, (int)hdr_sep[0], size);
|
memset(buf, (int)hdr_sep[0], size);
|
||||||
buf[size] = 0;
|
buf[size] = 0;
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
@@ -172,6 +216,7 @@ void rec_print_wide(struct util_rec *rec)
|
|||||||
int fld_count = 0;
|
int fld_count = 0;
|
||||||
char *entry;
|
char *entry;
|
||||||
|
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
util_list_iterate(rec->list, fld) {
|
util_list_iterate(rec->list, fld) {
|
||||||
if (!fld->hdr)
|
if (!fld->hdr)
|
||||||
continue;
|
continue;
|
||||||
@@ -225,6 +270,7 @@ struct util_rec *util_rec_new_long(const char *hdr_sep, const char *col_sep,
|
|||||||
rec->fmt.d.long_p.key_size = key_size;
|
rec->fmt.d.long_p.key_size = key_size;
|
||||||
rec->fmt.d.long_p.val_size = val_size;
|
rec->fmt.d.long_p.val_size = val_size;
|
||||||
rec->fmt.d.long_p.argz_sep = ' ';
|
rec->fmt.d.long_p.argz_sep = ' ';
|
||||||
|
rec->fmt.indent = 0;
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +287,7 @@ static void rec_print_long_hdr(struct util_rec *rec)
|
|||||||
fld = rec_get_fld(rec, p->key);
|
fld = rec_get_fld(rec, p->key);
|
||||||
util_assert(fld != NULL, "Record not found\n");
|
util_assert(fld != NULL, "Record not found\n");
|
||||||
util_assert(fld->hdr != NULL, "Header for field not found\n");
|
util_assert(fld->hdr != NULL, "Header for field not found\n");
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
if (p->col_sep) {
|
if (p->col_sep) {
|
||||||
printf("%-*s %s %-*s\n", p->key_size, fld->hdr,
|
printf("%-*s %s %-*s\n", p->key_size, fld->hdr,
|
||||||
p->col_sep, fld->width, fld->val);
|
p->col_sep, fld->width, fld->val);
|
||||||
@@ -255,6 +302,7 @@ static void rec_print_long_hdr(struct util_rec *rec)
|
|||||||
buf = util_malloc(len + 1);
|
buf = util_malloc(len + 1);
|
||||||
memset(buf, p->hdr_sep[0], len);
|
memset(buf, p->hdr_sep[0], len);
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
@@ -277,19 +325,24 @@ static void rec_print_long(struct util_rec *rec)
|
|||||||
continue;
|
continue;
|
||||||
if (!fld->val)
|
if (!fld->val)
|
||||||
continue;
|
continue;
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
item = argz_next(fld->val, fld->len, item);
|
item = argz_next(fld->val, fld->len, item);
|
||||||
if (p->col_sep) {
|
if (p->col_sep) {
|
||||||
printf(" %-*s %s %s\n",
|
printf(" %-*s %s %s\n",
|
||||||
p->key_size - 8, fld->hdr, p->col_sep, item);
|
p->key_size - 8, fld->hdr, p->col_sep, item);
|
||||||
while ((item = argz_next(fld->val, fld->len, item)))
|
while ((item = argz_next(fld->val, fld->len, item))) {
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
printf(" %-*s %c %s\n",
|
printf(" %-*s %c %s\n",
|
||||||
p->key_size - 8, "", p->argz_sep, item);
|
p->key_size - 8, "", p->argz_sep, item);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf(" %-*s %s\n",
|
printf(" %-*s %s\n",
|
||||||
p->key_size - 8, fld->hdr, fld->val);
|
p->key_size - 8, fld->hdr, fld->val);
|
||||||
while ((item = argz_next(fld->val, fld->len, item)))
|
while ((item = argz_next(fld->val, fld->len, item))) {
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
printf(" %-*s %s\n",
|
printf(" %-*s %s\n",
|
||||||
p->key_size - 8, "", item);
|
p->key_size - 8, "", item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -320,6 +373,7 @@ struct util_rec *util_rec_new_csv(const char *col_sep)
|
|||||||
rec->fmt.type = REC_FMT_CSV;
|
rec->fmt.type = REC_FMT_CSV;
|
||||||
rec->fmt.d.csv_p.col_sep = util_strdup(col_sep);
|
rec->fmt.d.csv_p.col_sep = util_strdup(col_sep);
|
||||||
rec->fmt.d.csv_p.argz_sep = ' ';
|
rec->fmt.d.csv_p.argz_sep = ' ';
|
||||||
|
rec->fmt.indent = 0;
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,6 +386,7 @@ void rec_print_csv_hdr(struct util_rec *rec)
|
|||||||
struct util_rec_fld *fld;
|
struct util_rec_fld *fld;
|
||||||
int fld_count = 0;
|
int fld_count = 0;
|
||||||
|
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
util_list_iterate(rec->list, fld) {
|
util_list_iterate(rec->list, fld) {
|
||||||
if (fld_count)
|
if (fld_count)
|
||||||
printf("%c", *col_sep);
|
printf("%c", *col_sep);
|
||||||
@@ -354,6 +409,7 @@ void rec_print_csv(struct util_rec *rec)
|
|||||||
int fld_count = 0;
|
int fld_count = 0;
|
||||||
char *item = NULL;
|
char *item = NULL;
|
||||||
|
|
||||||
|
rec_print_indention(rec->fmt.indent);
|
||||||
util_list_iterate(rec->list, fld) {
|
util_list_iterate(rec->list, fld) {
|
||||||
item = argz_next(fld->val, fld->len, item);
|
item = argz_next(fld->val, fld->len, item);
|
||||||
if (fld_count)
|
if (fld_count)
|
||||||
@@ -470,6 +526,24 @@ void util_rec_print_hdr(struct util_rec *rec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print record separator according to output format
|
||||||
|
*
|
||||||
|
* @param[in] rec Record pointer
|
||||||
|
*/
|
||||||
|
void util_rec_print_separator(struct util_rec *rec)
|
||||||
|
{
|
||||||
|
switch (rec->fmt.type) {
|
||||||
|
case REC_FMT_WIDE:
|
||||||
|
rec_print_wide_separator(rec);
|
||||||
|
break;
|
||||||
|
case REC_FMT_LONG:
|
||||||
|
break;
|
||||||
|
case REC_FMT_CSV:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a field value to an argz vector
|
* Set a field value to an argz vector
|
||||||
*
|
*
|
||||||
@@ -537,3 +611,14 @@ const char *util_rec_get(struct util_rec *rec, const char *key)
|
|||||||
|
|
||||||
return (fld != NULL) ? fld->val : NULL;
|
return (fld != NULL) ? fld->val : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the indentation of the record
|
||||||
|
*
|
||||||
|
* @param[in] rec Record pointer
|
||||||
|
* @param[in] indent Number of characters to indent
|
||||||
|
*/
|
||||||
|
void util_rec_set_indent(struct util_rec *rec, int indent)
|
||||||
|
{
|
||||||
|
rec->fmt.indent = indent;
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ static void print_records(const char *format, struct util_rec *rec)
|
|||||||
/* Print the record */
|
/* Print the record */
|
||||||
util_rec_print(rec);
|
util_rec_print(rec);
|
||||||
}
|
}
|
||||||
|
/* Print a separator line (is a nop for long and csv format) */
|
||||||
|
util_rec_print_separator(rec);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +74,11 @@ int main(void)
|
|||||||
print_records("Wide format", rec);
|
print_records("Wide format", rec);
|
||||||
util_rec_free(rec);
|
util_rec_free(rec);
|
||||||
|
|
||||||
|
rec = util_rec_new_wide("-");
|
||||||
|
util_rec_set_indent(rec, 4);
|
||||||
|
print_records("Wide format with indentation", rec);
|
||||||
|
util_rec_free(rec);
|
||||||
|
|
||||||
rec = util_rec_new_long("-", ":", "number", 30, 20);
|
rec = util_rec_new_long("-", ":", "number", 30, 20);
|
||||||
print_records("Long format", rec);
|
print_records("Long format", rec);
|
||||||
util_rec_free(rec);
|
util_rec_free(rec);
|
||||||
|
|||||||
77
libutil/util_sys.c
Normal file
77
libutil/util_sys.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* util - Utility function library
|
||||||
|
*
|
||||||
|
* SysFS helper functions
|
||||||
|
*
|
||||||
|
* Copyright IBM Corp. 2019
|
||||||
|
*
|
||||||
|
* 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 <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lib/util_path.h"
|
||||||
|
#include "lib/util_sys.h"
|
||||||
|
|
||||||
|
/* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */
|
||||||
|
#define READLINK_SIZE 256
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify device address
|
||||||
|
*
|
||||||
|
* Identifying the device address with this function works for almost any
|
||||||
|
* character and block device (e.g. NVMe, SCSI, DASD, etc).
|
||||||
|
* The user must provide a buffer that is large enough for the desired device
|
||||||
|
* address to be read into \p addr.
|
||||||
|
*
|
||||||
|
* @param[in] dev Device node of interest
|
||||||
|
* @param[out] addr Identified device address
|
||||||
|
*
|
||||||
|
* @retval 0 Success
|
||||||
|
* @retval -1 Error while reading device information or
|
||||||
|
* constructed path
|
||||||
|
*/
|
||||||
|
int util_sys_get_dev_addr(const char *dev, char *addr)
|
||||||
|
{
|
||||||
|
char device[READLINK_SIZE], *result;
|
||||||
|
unsigned int maj, min;
|
||||||
|
struct stat s;
|
||||||
|
ssize_t len;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (stat(dev, &s) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
maj = major(s.st_rdev);
|
||||||
|
min = minor(s.st_rdev);
|
||||||
|
|
||||||
|
if (S_ISBLK(s.st_mode))
|
||||||
|
path = util_path_sysfs("dev/block/%u:%u/device", maj, min);
|
||||||
|
else if (S_ISCHR(s.st_mode))
|
||||||
|
path = util_path_sysfs("dev/char/%u:%u/device", maj, min);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len = readlink(path, device, READLINK_SIZE - 1);
|
||||||
|
free(path);
|
||||||
|
if (len != -1)
|
||||||
|
device[len] = '\0';
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
result = strrchr(device, '/');
|
||||||
|
if (result)
|
||||||
|
result++;
|
||||||
|
else
|
||||||
|
result = device;
|
||||||
|
strcpy(addr, result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
188
libzds/libzds.c
188
libzds/libzds.c
@@ -20,10 +20,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "lib/dasd_base.h"
|
#include "lib/dasd_base.h"
|
||||||
|
#include "lib/dasd_sys.h"
|
||||||
#include "lib/libzds.h"
|
#include "lib/libzds.h"
|
||||||
#include "lib/u2s.h"
|
|
||||||
#include "lib/util_base.h"
|
|
||||||
#include "lib/util_list.h"
|
|
||||||
#include "lib/vtoc.h"
|
#include "lib/vtoc.h"
|
||||||
|
|
||||||
/** @cond PRIVATE */
|
/** @cond PRIVATE */
|
||||||
@@ -70,42 +68,6 @@ struct errormsg {
|
|||||||
char text[ERRORMSG];
|
char text[ERRORMSG];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* As the VTOC is the data area on the DASD that describes all data sets,
|
|
||||||
* this library will often have to refer to the various records in the VTOC.
|
|
||||||
* To make this more efficiant, we will read the whole VTOC once and identify
|
|
||||||
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
|
||||||
* DSCBs is stored.
|
|
||||||
*/
|
|
||||||
struct raw_vtoc {
|
|
||||||
/** @brief The raw track data */
|
|
||||||
char *rawdata;
|
|
||||||
/** @brief This size of the raw track data in bytes */
|
|
||||||
unsigned long long rawdatasize;
|
|
||||||
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
|
||||||
char **vtocindex;
|
|
||||||
/** @brief Number of entries in the index */
|
|
||||||
unsigned int vtocindexcount;
|
|
||||||
/** @brief Number of records per VTOC track
|
|
||||||
*
|
|
||||||
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
|
||||||
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
|
||||||
* for record 0.
|
|
||||||
*/
|
|
||||||
unsigned int vtoc_rec_per_track;
|
|
||||||
/** @brief The track number in which the vtoc begins on the DASD */
|
|
||||||
unsigned int vtoctrackoffset;
|
|
||||||
/** @brief Start record of VTOC.
|
|
||||||
*
|
|
||||||
* The rawdata contains full tracks. This is the number of the first
|
|
||||||
* record that actually belongs to the VTOC */
|
|
||||||
unsigned int vtocrecno;
|
|
||||||
/** @brief The DASD this vtoc was read from */
|
|
||||||
struct dasd *dasd;
|
|
||||||
/** @brief Detailed error messages in case of a problem */
|
|
||||||
struct errorlog *log;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dscbiterator {
|
struct dscbiterator {
|
||||||
/** @brief The raw_vtoc this iterator refers to */
|
/** @brief The raw_vtoc this iterator refers to */
|
||||||
struct raw_vtoc *rawvtoc;
|
struct raw_vtoc *rawvtoc;
|
||||||
@@ -113,31 +75,6 @@ struct dscbiterator {
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dasd {
|
|
||||||
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
|
||||||
struct util_list_node list;
|
|
||||||
/** @brief Name of the block device, e.g. /dev/dasde */
|
|
||||||
char *device;
|
|
||||||
/** @brief File descriptor for the block device.
|
|
||||||
*
|
|
||||||
* The device is kept open for as along as the library uses it.
|
|
||||||
* This lets the system know that the device is still in use.
|
|
||||||
*/
|
|
||||||
int inusefd;
|
|
||||||
/* @brief where to find the volume label */
|
|
||||||
unsigned int label_block;
|
|
||||||
/** @brief Device geometry. How many cylinders does the DASD have. */
|
|
||||||
unsigned int cylinders;
|
|
||||||
/** @brief Device geometry. How many heads does the DASD have. */
|
|
||||||
unsigned int heads;
|
|
||||||
/** @brief The VTOC data that has been read from this device */
|
|
||||||
struct raw_vtoc *rawvtoc;
|
|
||||||
/** @brief The volume label that has been read from this device */
|
|
||||||
volume_label_t *vlabel;
|
|
||||||
/** @brief Detailed error messages in case of a problem */
|
|
||||||
struct errorlog *log;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dasdhandle {
|
struct dasdhandle {
|
||||||
/** @brief The struct dasd this context relates to */
|
/** @brief The struct dasd this context relates to */
|
||||||
struct dasd *dasd;
|
struct dasd *dasd;
|
||||||
@@ -412,6 +349,29 @@ int lzds_zdsroot_alloc(struct zdsroot **root)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It should be noted that this frees all structures that are owned by the
|
||||||
|
* root structure as well. For example, a pointer to a struct dasd that
|
||||||
|
* has been returned by lzds_zdsroot_add_device is not valid anymore.
|
||||||
|
*
|
||||||
|
* @param[in] root Reference to the zdsroot structure that is to be freed.
|
||||||
|
*/
|
||||||
|
void lzds_dslist_free(struct zdsroot *root)
|
||||||
|
{
|
||||||
|
struct dataset *ds, *nextds;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
util_list_iterate_safe(root->datasetlist, ds, nextds) {
|
||||||
|
util_list_remove(root->datasetlist, ds);
|
||||||
|
dataset_free_memberlist(ds);
|
||||||
|
for (i = 0; i < MAXVOLUMESPERDS; ++i)
|
||||||
|
free(ds->dsp[i]);
|
||||||
|
errorlog_free(ds->log);
|
||||||
|
free(ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It should be noted that this frees all structures that are owned by the
|
* It should be noted that this frees all structures that are owned by the
|
||||||
* root structure as well. For example, a pointer to a struct dasd that
|
* root structure as well. For example, a pointer to a struct dasd that
|
||||||
@@ -422,8 +382,6 @@ int lzds_zdsroot_alloc(struct zdsroot **root)
|
|||||||
void lzds_zdsroot_free(struct zdsroot *root)
|
void lzds_zdsroot_free(struct zdsroot *root)
|
||||||
{
|
{
|
||||||
struct dasd *dasd, *nextdasd;
|
struct dasd *dasd, *nextdasd;
|
||||||
struct dataset *ds, *nextds;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!root)
|
if (!root)
|
||||||
return;
|
return;
|
||||||
@@ -433,15 +391,7 @@ void lzds_zdsroot_free(struct zdsroot *root)
|
|||||||
dasd_free(dasd);
|
dasd_free(dasd);
|
||||||
}
|
}
|
||||||
util_list_free(root->dasdlist);
|
util_list_free(root->dasdlist);
|
||||||
|
lzds_dslist_free(root);
|
||||||
util_list_iterate_safe(root->datasetlist, ds, nextds) {
|
|
||||||
util_list_remove(root->datasetlist, ds);
|
|
||||||
dataset_free_memberlist(ds);
|
|
||||||
for (i = 0; i < MAXVOLUMESPERDS; ++i)
|
|
||||||
free(ds->dsp[i]);
|
|
||||||
errorlog_free(ds->log);
|
|
||||||
free(ds);
|
|
||||||
}
|
|
||||||
util_list_free(root->datasetlist);
|
util_list_free(root->datasetlist);
|
||||||
errorlog_free(root->log);
|
errorlog_free(root->log);
|
||||||
free(root);
|
free(root);
|
||||||
@@ -1443,7 +1393,7 @@ int lzds_raw_vtoc_get_dscb_from_cchhb(struct raw_vtoc *rv, cchhb_t *p,
|
|||||||
* - EPROTO The VTOC data is not in a valid format.
|
* - EPROTO The VTOC data is not in a valid format.
|
||||||
* - EIO Other I/O error
|
* - EIO Other I/O error
|
||||||
*/
|
*/
|
||||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *rawvtoc)
|
||||||
{
|
{
|
||||||
unsigned long long vtoctrckno, vtocrecno;
|
unsigned long long vtoctrckno, vtocrecno;
|
||||||
unsigned int vtoctrack_start, vtoctrack_end, vtocindexsize;
|
unsigned int vtoctrack_start, vtoctrack_end, vtocindexsize;
|
||||||
@@ -1455,26 +1405,11 @@ int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
|||||||
format4_label_t *f4;
|
format4_label_t *f4;
|
||||||
unsigned long long rawvtocsize;
|
unsigned long long rawvtocsize;
|
||||||
|
|
||||||
struct raw_vtoc *rawvtoc = NULL;
|
|
||||||
volume_label_t *vlabel = NULL;
|
volume_label_t *vlabel = NULL;
|
||||||
char *trackdata = NULL;
|
char *trackdata = NULL;
|
||||||
char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00}; /* "VOL1" in EBCDIC */
|
char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00}; /* "VOL1" in EBCDIC */
|
||||||
|
|
||||||
errorlog_clear(dasd->log);
|
errorlog_clear(dasd->log);
|
||||||
/* cleanup the old rawvtoc structures before we read new ones */
|
|
||||||
rawvtoc = dasd->rawvtoc;
|
|
||||||
dasd->rawvtoc = NULL;
|
|
||||||
if (rawvtoc) {
|
|
||||||
free(rawvtoc->rawdata);
|
|
||||||
free(rawvtoc->vtocindex);
|
|
||||||
free(rawvtoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
rawvtoc = malloc(sizeof(*rawvtoc));
|
|
||||||
if (!rawvtoc)
|
|
||||||
return ENOMEM;
|
|
||||||
memset(rawvtoc, 0, sizeof(*rawvtoc));
|
|
||||||
rawvtoc->dasd = dasd;
|
|
||||||
|
|
||||||
rc = lzds_dasd_get_vlabel(dasd, &vlabel);
|
rc = lzds_dasd_get_vlabel(dasd, &vlabel);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@@ -1611,13 +1546,49 @@ int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
dasd->rawvtoc = rawvtoc;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
free(rawvtoc->vtocindex);
|
|
||||||
free(trackdata);
|
free(trackdata);
|
||||||
free(rawvtoc);
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[in] dasd The struct dasd that represents the device we want to read
|
||||||
|
* the VTOC from.
|
||||||
|
* @return 0 on success, otherwise one of the following error codes:
|
||||||
|
* - ENOMEM Could not allocate internal structure due to lack of memory.
|
||||||
|
* - EINVAL The volume label has not yet been read or it is not valid.
|
||||||
|
* - EPROTO The VTOC data is not in a valid format.
|
||||||
|
* - EIO Other I/O error
|
||||||
|
*/
|
||||||
|
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd)
|
||||||
|
{
|
||||||
|
struct raw_vtoc *rawvtoc = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* cleanup the old rawvtoc structures before we read new ones */
|
||||||
|
rawvtoc = dasd->rawvtoc;
|
||||||
|
dasd->rawvtoc = NULL;
|
||||||
|
if (rawvtoc) {
|
||||||
|
free(rawvtoc->rawdata);
|
||||||
|
free(rawvtoc->vtocindex);
|
||||||
|
free(rawvtoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
rawvtoc = malloc(sizeof(*rawvtoc));
|
||||||
|
if (!rawvtoc)
|
||||||
|
return ENOMEM;
|
||||||
|
memset(rawvtoc, 0, sizeof(*rawvtoc));
|
||||||
|
rawvtoc->dasd = dasd;
|
||||||
|
|
||||||
|
rc = lzds_dasd_read_rawvtoc(dasd, rawvtoc);
|
||||||
|
if (rc) {
|
||||||
|
free(rawvtoc->vtocindex);
|
||||||
|
free(rawvtoc);
|
||||||
|
} else {
|
||||||
|
dasd->rawvtoc = rawvtoc;
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2261,6 +2232,7 @@ out1:
|
|||||||
static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
||||||
{
|
{
|
||||||
int k, l, dspcount;
|
int k, l, dspcount;
|
||||||
|
|
||||||
for (k = 0; k < MAXVOLUMESPERDS; ++k) {
|
for (k = 0; k < MAXVOLUMESPERDS; ++k) {
|
||||||
/* if both datasets have a part in position k,
|
/* if both datasets have a part in position k,
|
||||||
* then something is wrong */
|
* then something is wrong */
|
||||||
@@ -2280,18 +2252,20 @@ static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
|||||||
* Since dsp[0] may not be set yet, we loop over the
|
* Since dsp[0] may not be set yet, we loop over the
|
||||||
* base dsp array until we find an entry.
|
* base dsp array until we find an entry.
|
||||||
*/
|
*/
|
||||||
for (l = 0; l < MAXVOLUMESPERDS; ++l)
|
for (l = 0; l < MAXVOLUMESPERDS; ++l) {
|
||||||
if (baseds->dsp[l]) {
|
if (!baseds->dsp[l])
|
||||||
if (memcmp(baseds->dsp[l]->f1->DS1DSSN,
|
continue;
|
||||||
newds->dsp[k]->f1->DS1DSSN,
|
if (memcmp(baseds->dsp[l]->f1->DS1DSSN,
|
||||||
MAXVOLSER))
|
newds->dsp[k]->f1->DS1DSSN,
|
||||||
return errorlog_add_message(
|
MAXVOLSER))
|
||||||
&baseds->log, NULL, EPROTO,
|
return errorlog_add_message(
|
||||||
"merge dataset: part %d has incompatible"
|
&baseds->log, NULL, EPROTO,
|
||||||
" base volume serial\n", k);
|
"merge dataset: part %d has incompatible base volume serial\n",
|
||||||
else
|
k);
|
||||||
break;
|
else
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
baseds->dsp[k] = newds->dsp[k];
|
baseds->dsp[k] = newds->dsp[k];
|
||||||
baseds->dspcount++;
|
baseds->dspcount++;
|
||||||
|
|
||||||
@@ -3727,7 +3701,7 @@ int lzds_analyse_open_count(struct zdsroot *root, int warn)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
util_list_iterate(root->dasdlist, dasd) {
|
util_list_iterate(root->dasdlist, dasd) {
|
||||||
value = u2s_get_host_access_count(dasd->device);
|
value = dasd_get_host_access_count(dasd->device);
|
||||||
|
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ static char small_mon_record[SMALL_MON_RECORD_LEN];
|
|||||||
static char large_mon_record[LARGE_MON_RECORD_LEN];
|
static char large_mon_record[LARGE_MON_RECORD_LEN];
|
||||||
static long sample_interval = 60;
|
static long sample_interval = 60;
|
||||||
|
|
||||||
static const char *pid_file = "/var/run/mon_fsstatd.pid";
|
static const char *pid_file = "/run/mon_fsstatd.pid";
|
||||||
|
|
||||||
struct mw_name_lens {
|
struct mw_name_lens {
|
||||||
__u16 mw_name_len;
|
__u16 mw_name_len;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ static char buf[BUF_SIZE];
|
|||||||
static char mon_record[MAX_REC_LEN];
|
static char mon_record[MAX_REC_LEN];
|
||||||
static long sample_interval = 60;
|
static long sample_interval = 60;
|
||||||
|
|
||||||
static const char *pid_file = "/var/run/mon_procd.pid";
|
static const char *pid_file = "/run/mon_procd.pid";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean up when SIGTERM or SIGINT received
|
* Clean up when SIGTERM or SIGINT received
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -287,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)
|
||||||
@@ -340,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);
|
||||||
@@ -541,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) {
|
||||||
@@ -613,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;
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,9 @@ readonly OUTPUT_FILE_VMCMD="${WORKPATH}zvm_runtime.out"
|
|||||||
# File that includes content of files from sysfs
|
# File that includes content of files from sysfs
|
||||||
readonly OUTPUT_FILE_SYSFS="${WORKPATH}sysfsfiles.out"
|
readonly OUTPUT_FILE_SYSFS="${WORKPATH}sysfsfiles.out"
|
||||||
|
|
||||||
|
# File that includes the output of lsof
|
||||||
|
readonly OUTPUT_FILE_LSOF="${WORKPATH}open_files.out"
|
||||||
|
|
||||||
# File that includes content of OSA OAT
|
# File that includes content of OSA OAT
|
||||||
readonly OUTPUT_FILE_OSAOAT="${WORKPATH}osa_oat"
|
readonly OUTPUT_FILE_OSAOAT="${WORKPATH}osa_oat"
|
||||||
|
|
||||||
@@ -307,12 +310,13 @@ LOGFILES="\
|
|||||||
/var/log/lin_tape.trace\
|
/var/log/lin_tape.trace\
|
||||||
/var/log/lin_tape.errorlog\
|
/var/log/lin_tape.errorlog\
|
||||||
/var/log/messages*\
|
/var/log/messages*\
|
||||||
|
/var/log/opencryptoki\
|
||||||
/var/log/syslog*\
|
/var/log/syslog*\
|
||||||
/var/log/sa\
|
/var/log/sa\
|
||||||
/var/log/yum.log\
|
/var/log/yum.log\
|
||||||
/var/log/openvswitch/ovs-vswitchd.log\
|
/var/log/openvswitch/ovs-vswitchd.log\
|
||||||
/var/log/openvswitch/ovsdb-server.log\
|
/var/log/openvswitch/ovsdb-server.log\
|
||||||
/var/run/docker/libcontainerd/containerd/events.log\
|
/run/docker/libcontainerd/containerd/events.log\
|
||||||
/run/containerd/events.log\
|
/run/containerd/events.log\
|
||||||
"
|
"
|
||||||
|
|
||||||
@@ -441,7 +445,8 @@ CMDS="uname -a\
|
|||||||
:SPident\
|
:SPident\
|
||||||
:rpm -qa | sort\
|
:rpm -qa | sort\
|
||||||
:sysctl -a\
|
:sysctl -a\
|
||||||
:lsof\
|
:lsof \
|
||||||
|
> '${OUTPUT_FILE_LSOF}'\
|
||||||
:mount\
|
:mount\
|
||||||
:df -h\
|
:df -h\
|
||||||
:df -i\
|
:df -i\
|
||||||
@@ -465,6 +470,8 @@ CMDS="uname -a\
|
|||||||
:docker version\
|
:docker version\
|
||||||
:docker stats --no-stream\
|
:docker stats --no-stream\
|
||||||
:systemctl status docker.service\
|
:systemctl status docker.service\
|
||||||
|
:blockdev --report\
|
||||||
|
:lvdisplay\
|
||||||
"
|
"
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
|
|||||||
@@ -291,6 +291,13 @@ sub get_payload_records
|
|||||||
my $area = str_from_hex(substr($record[2], 2, 14));
|
my $area = str_from_hex(substr($record[2], 2, 14));
|
||||||
my $counter = hex(substr($record[2], 0, 2));
|
my $counter = hex(substr($record[2], 0, 2));
|
||||||
my $fsf_req_id = substr($record[2], 16, 16);
|
my $fsf_req_id = substr($record[2], 16, 16);
|
||||||
|
# ($counter == 0) is just a simple heuristic which can fail if
|
||||||
|
# there are missing payload record junks due to PAY area wrap!
|
||||||
|
if ($counter == 0 &&
|
||||||
|
defined($PAYLOAD_RECORDS{$fsf_req_id}{$area})) {
|
||||||
|
print "Warning: Ambiguous PAYload records. reqid:" .
|
||||||
|
$fsf_req_id . " area:" . $area . "\n";
|
||||||
|
}
|
||||||
$PAYLOAD_RECORDS{$fsf_req_id}{$area}[$counter] = [@record];
|
$PAYLOAD_RECORDS{$fsf_req_id}{$area}[$counter] = [@record];
|
||||||
if ($def_error && ($area =~ /def_err/)) {
|
if ($def_error && ($area =~ /def_err/)) {
|
||||||
$def_error{$fsf_req_id}[$counter] = [@record];
|
$def_error{$fsf_req_id}[$counter] = [@record];
|
||||||
@@ -515,11 +522,16 @@ sub print_payload
|
|||||||
my $field_name = shift();
|
my $field_name = shift();
|
||||||
my $tmp_str;
|
my $tmp_str;
|
||||||
|
|
||||||
|
if ($payload) {
|
||||||
|
# workaround to let user determine ambiguous PAYload records
|
||||||
|
printf "%-14s : %s\n", "Payload time", $payload->[0]->[0];
|
||||||
|
}
|
||||||
printf "%-14s : ", $field_name;
|
printf "%-14s : ", $field_name;
|
||||||
if (!$payload) {
|
if (!$payload) {
|
||||||
print "record not available anymore.\n";
|
print "record not available anymore.\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
# TODO: iterate with $counter loop and notify user about missing junks
|
||||||
foreach my $cc (@$payload) {
|
foreach my $cc (@$payload) {
|
||||||
$tmp_str .= substr($cc->[2], 32);
|
$tmp_str .= substr($cc->[2], 32);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"]*$//')"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ ConditionVirtualization=no
|
|||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
ExecStart=@usrsbin_path@/cpacfstatsd
|
ExecStart=@usrsbin_path@/cpacfstatsd
|
||||||
PIDFile=/var/run/cpacfstatsd.pid
|
PIDFile=/run/cpacfstatsd.pid
|
||||||
KillMode=process
|
KillMode=process
|
||||||
Restart=no
|
Restart=no
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ ExecStart=@usrsbin_path@/cpuplugd -c @sysconf_path@/cpuplugd.conf
|
|||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
KillMode=process
|
KillMode=process
|
||||||
Type=forking
|
Type=forking
|
||||||
PIDFile=/var/run/cpuplugd.pid
|
PIDFile=/run/cpuplugd.pid
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ ExecStart=@usrsbin_path@/mon_fsstatd -i $FSSTAT_INTERVAL
|
|||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
KillMode=process
|
KillMode=process
|
||||||
Type=forking
|
Type=forking
|
||||||
PIDFile=/var/run/mon_fsstatd.pid
|
PIDFile=/run/mon_fsstatd.pid
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ ExecStart=@usrsbin_path@/mon_procd -i $PROC_INTERVAL
|
|||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
KillMode=process
|
KillMode=process
|
||||||
Type=forking
|
Type=forking
|
||||||
PIDFile=/var/run/mon_procd.pid
|
PIDFile=/run/mon_procd.pid
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ include ../../common.mak
|
|||||||
ALL_CPPFLAGS += -I../include -I../boot
|
ALL_CPPFLAGS += -I../include -I../boot
|
||||||
|
|
||||||
libs = $(rootdir)/libdasd/libdasd.a \
|
libs = $(rootdir)/libdasd/libdasd.a \
|
||||||
$(rootdir)/libu2s/libu2s.a \
|
|
||||||
$(rootdir)/libutil/libutil.a
|
$(rootdir)/libutil/libutil.a
|
||||||
|
|
||||||
all: tunedasd
|
all: tunedasd
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -11,10 +11,24 @@ lschp \- list information about available channel\-paths.
|
|||||||
.B lschp
|
.B lschp
|
||||||
.RB [ \-h|\-\-help ]
|
.RB [ \-h|\-\-help ]
|
||||||
.RB [ \-v|\-\-version ]
|
.RB [ \-v|\-\-version ]
|
||||||
|
.RB [
|
||||||
|
.I CHPID
|
||||||
|
]
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The lschp command lists status and type information about available
|
The lschp command lists status and type information about available
|
||||||
channel\-paths.
|
channel\-paths. A
|
||||||
|
.I CHPID
|
||||||
|
argument can be specified to return the information for the respective
|
||||||
|
channel-path identifier only.
|
||||||
|
Channel\-path identifiers are specified in hexadecimal notation either simply
|
||||||
|
as the CHPID\-number (e.g. e0) or in the form
|
||||||
|
|
||||||
|
.RS
|
||||||
|
<cssid>.<id>
|
||||||
|
.RE
|
||||||
|
|
||||||
|
where <cssid> is the channel\-subsystem identifier and <id> is the CHPID\-number (e.g. 0.7e).
|
||||||
|
|
||||||
.B Column description:
|
.B Column description:
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Provide main function and command line parsing.
|
* Provide main function and command line parsing.
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2016, 2017
|
* Copyright IBM Corp. 2016, 2019
|
||||||
*
|
*
|
||||||
* 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 <err.h>
|
#include <err.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "lib/util_base.h"
|
#include "lib/util_base.h"
|
||||||
#include "lib/util_file.h"
|
#include "lib/util_file.h"
|
||||||
@@ -31,7 +32,7 @@ static const struct util_prg prg = {
|
|||||||
{
|
{
|
||||||
.owner = "IBM Corp.",
|
.owner = "IBM Corp.",
|
||||||
.pub_first = 2016,
|
.pub_first = 2016,
|
||||||
.pub_last = 2017,
|
.pub_last = 2019,
|
||||||
},
|
},
|
||||||
UTIL_PRG_COPYRIGHT_END
|
UTIL_PRG_COPYRIGHT_END
|
||||||
}
|
}
|
||||||
@@ -55,9 +56,10 @@ static struct util_opt opt_vec[] = {
|
|||||||
* @param[in] dir Path of the desired directory
|
* @param[in] dir Path of the desired directory
|
||||||
* @param[in] css_id ID for device identification
|
* @param[in] css_id ID for device identification
|
||||||
* @param[in] rec The buffer structure, where results are written to
|
* @param[in] rec The buffer structure, where results are written to
|
||||||
|
* @param[in] chp If set: CHPID to filter by
|
||||||
*/
|
*/
|
||||||
static void print_chpid(const char *chp_dir, unsigned int css_id,
|
static void print_chpid(const char *chp_dir, unsigned int css_id,
|
||||||
struct util_rec *rec)
|
struct util_rec *rec, char *chp)
|
||||||
{
|
{
|
||||||
unsigned int css_id_tmp, chp_id;
|
unsigned int css_id_tmp, chp_id;
|
||||||
bool chid_external;
|
bool chid_external;
|
||||||
@@ -123,7 +125,8 @@ static void print_chpid(const char *chp_dir, unsigned int css_id,
|
|||||||
} else {
|
} else {
|
||||||
util_rec_set(rec, "pchid", "%s", "-");
|
util_rec_set(rec, "pchid", "%s", "-");
|
||||||
}
|
}
|
||||||
util_rec_print(rec);
|
if (!strlen(chp) || strcmp(util_rec_get(rec, "chpid"), chp) == 0)
|
||||||
|
util_rec_print(rec);
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,8 +156,9 @@ static int chpsort(const struct dirent **de1, const struct dirent **de2)
|
|||||||
*
|
*
|
||||||
* @param[in] css_dir The desired directory
|
* @param[in] css_dir The desired directory
|
||||||
* @param[in] rec The buffer structure, where results are written to
|
* @param[in] rec The buffer structure, where results are written to
|
||||||
|
* @param[in] chp If set: CHPID to filter by
|
||||||
*/
|
*/
|
||||||
static void print_css(const char *css_dir, struct util_rec *rec)
|
static void print_css(const char *css_dir, struct util_rec *rec, char *chp)
|
||||||
{
|
{
|
||||||
struct dirent **de_vec;
|
struct dirent **de_vec;
|
||||||
unsigned int css_id;
|
unsigned int css_id;
|
||||||
@@ -167,15 +171,17 @@ static void print_css(const char *css_dir, struct util_rec *rec)
|
|||||||
path = util_path_sysfs("devices/css%d", css_id);
|
path = util_path_sysfs("devices/css%d", css_id);
|
||||||
count = util_scandir(&de_vec, chpsort, path, "chp%x.*", css_id);
|
count = util_scandir(&de_vec, chpsort, path, "chp%x.*", css_id);
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
print_chpid(de_vec[i]->d_name, css_id, rec);
|
print_chpid(de_vec[i]->d_name, css_id, rec, chp);
|
||||||
util_scandir_free(de_vec, count);
|
util_scandir_free(de_vec, count);
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print chpid table
|
* Print chpid table
|
||||||
|
*
|
||||||
|
* @param[in] chp If set: CHPID to filter by
|
||||||
*/
|
*/
|
||||||
static void cmd_lschp(void)
|
static void cmd_lschp(char *chp)
|
||||||
{
|
{
|
||||||
struct dirent **de_vec;
|
struct dirent **de_vec;
|
||||||
struct util_rec *rec;
|
struct util_rec *rec;
|
||||||
@@ -198,17 +204,19 @@ static void cmd_lschp(void)
|
|||||||
path = util_path_sysfs("devices");
|
path = util_path_sysfs("devices");
|
||||||
count = util_scandir(&de_vec, alphasort, path, "^css[[:xdigit:]]{1,2}$");
|
count = util_scandir(&de_vec, alphasort, path, "^css[[:xdigit:]]{1,2}$");
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
print_css(de_vec[i]->d_name, rec);
|
print_css(de_vec[i]->d_name, rec, chp);
|
||||||
util_ptr_vec_free((void **) de_vec, count);
|
util_ptr_vec_free((void **) de_vec, count);
|
||||||
free(path);
|
free(path);
|
||||||
util_rec_free(rec);
|
util_rec_free(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHP_LEN 4
|
||||||
/*
|
/*
|
||||||
* Parse options and execute the command
|
* Parse options and execute the command
|
||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
char chp[CHP_LEN + 1] = "";
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
util_prg_init(&prg);
|
util_prg_init(&prg);
|
||||||
@@ -231,10 +239,30 @@ int main(int argc, char *argv[])
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (argc > optind) {
|
if (argc > optind + 1)
|
||||||
util_prg_print_arg_error(argv[optind]);
|
errx(EXIT_FAILURE, "Too many arguments specified");
|
||||||
return EXIT_FAILURE;
|
if (argc == optind + 1) {
|
||||||
|
/* we take a single argument only */
|
||||||
|
switch (strlen(argv[optind])) {
|
||||||
|
case 1:
|
||||||
|
sprintf(chp, "0.0%s", argv[optind]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sprintf(chp, "0.%s", argv[optind]);
|
||||||
|
break;
|
||||||
|
case CHP_LEN:
|
||||||
|
strcpy(chp, argv[optind]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errx(EXIT_FAILURE, "%s is not a valid channel-path ID",
|
||||||
|
argv[optind]);
|
||||||
|
}
|
||||||
|
if (!isdigit(chp[0]) || chp[1] != '.' || !isxdigit(chp[2]) ||
|
||||||
|
!isxdigit(chp[3]))
|
||||||
|
errx(EXIT_FAILURE, "%s is not a valid channel-path ID",
|
||||||
|
chp);
|
||||||
}
|
}
|
||||||
cmd_lschp();
|
cmd_lschp(chp);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
357
zconf/lszfcp
357
zconf/lszfcp
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# lszfcp - Tool to display information about zfcp devices (adapters/ports/units)
|
# lszfcp - Tool to display information about zfcp devices (adapters/ports/units)
|
||||||
#
|
#
|
||||||
# Copyright IBM Corp. 2006, 2017
|
# Copyright IBM Corp. 2006, 2019
|
||||||
#
|
#
|
||||||
# s390-tools is free software; you can redistribute it and/or modify
|
# s390-tools is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the MIT license. See LICENSE for details.
|
# it under the terms of the MIT license. See LICENSE for details.
|
||||||
@@ -14,10 +14,13 @@ FC_CLASS=false
|
|||||||
|
|
||||||
# Command line parameters
|
# Command line parameters
|
||||||
VERBOSITY=0
|
VERBOSITY=0
|
||||||
|
SHOW_MODPARMS=0
|
||||||
SHOW_HOSTS=0
|
SHOW_HOSTS=0
|
||||||
SHOW_PORTS=0
|
SHOW_PORTS=0
|
||||||
SHOW_DEVICES=0
|
SHOW_DEVICES=0
|
||||||
SHOW_ATTRIBUTES=false
|
SHOW_ATTRIBUTES=false
|
||||||
|
SHOW_MORE_ATTRS=0
|
||||||
|
SHOW_EXTENDED=false
|
||||||
unset PAR_BUSID PAR_WWPN PAR_LUN
|
unset PAR_BUSID PAR_WWPN PAR_LUN
|
||||||
|
|
||||||
|
|
||||||
@@ -26,8 +29,8 @@ unset PAR_BUSID PAR_WWPN PAR_LUN
|
|||||||
check_sysfs()
|
check_sysfs()
|
||||||
{
|
{
|
||||||
if [ -z $SYSFS -o ! -d $SYSFS -o ! -r $SYSFS ]; then
|
if [ -z $SYSFS -o ! -d $SYSFS -o ! -r $SYSFS ]; then
|
||||||
echo "Error: sysfs not available."
|
echo "Error: sysfs not available."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +46,36 @@ check_zfcp_support()
|
|||||||
|
|
||||||
check_fcp_devs()
|
check_fcp_devs()
|
||||||
{
|
{
|
||||||
|
local found=0
|
||||||
|
|
||||||
if $FC_CLASS; then
|
if $FC_CLASS; then
|
||||||
|
# theoretically this includes "defunct" (and thus online) devs
|
||||||
ignore=`ls $SYSFS/class/fc_host/host* 2>&1`
|
ignore=`ls $SYSFS/class/fc_host/host* 2>&1`
|
||||||
else
|
else
|
||||||
ignore=`ls $SYSFS/devices/css0/[0-9]*/[0-9]*/host[0-9]* 2>&1`
|
ignore=`ls $SYSFS/devices/css0/[0-9]*/[0-9]*/host[0-9]* 2>&1`
|
||||||
fi
|
fi
|
||||||
|
[ $? -eq 0 ] && found=1
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $found -eq 0 ] && $SHOW_EXTENDED; then
|
||||||
|
# nothing found yet so search for "defunct" FCP devices
|
||||||
|
ignore=$(ls -dX $SYSFS/devices/css[0-9]*/defunct/[0-9]*/host[0-9]* 2>&1)
|
||||||
|
[ $? -eq 0 ] && found=1
|
||||||
|
fi
|
||||||
|
if [ $found -eq 0 ] && $SHOW_EXTENDED; then
|
||||||
|
local mypath mylist=""
|
||||||
|
# nothing found yet so search for FCP devices never been online
|
||||||
|
for mypath in $SYSFS/bus/ccw/drivers/zfcp/*.*.*; do
|
||||||
|
if [ "$mypath" = "$SYSFS/bus/ccw/drivers/zfcp/*.*.*" ];
|
||||||
|
then
|
||||||
|
break # glob did not match anything
|
||||||
|
fi
|
||||||
|
[ -d $mypath/host[0-9]* ] && continue # is/was online
|
||||||
|
mylist="$mylist $(readlink -e $mypath)/-"
|
||||||
|
done
|
||||||
|
[ -n "$mylist" ] && found=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $found -eq 0 ]; then
|
||||||
echo "Error: No fcp devices found."
|
echo "Error: No fcp devices found."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -57,7 +83,7 @@ check_fcp_devs()
|
|||||||
|
|
||||||
check_fc_class()
|
check_fc_class()
|
||||||
{
|
{
|
||||||
if [ -d "$SYSFS/class/fc_host" ]; then
|
if [ -d "$SYSFS/class/fc_host" ]; then
|
||||||
FC_CLASS=true
|
FC_CLASS=true
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -66,7 +92,7 @@ print_version()
|
|||||||
{
|
{
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
$SCRIPTNAME: version %S390_TOOLS_VERSION%
|
$SCRIPTNAME: version %S390_TOOLS_VERSION%
|
||||||
Copyright IBM Corp. 2006, 2017
|
Copyright IBM Corp. 2006, 2019
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,18 +110,24 @@ OPTIONS:
|
|||||||
-H, --hosts show host information (default)
|
-H, --hosts show host information (default)
|
||||||
-P, --ports show remote port information
|
-P, --ports show remote port information
|
||||||
-D, --devices show SCSI device information
|
-D, --devices show SCSI device information
|
||||||
|
-Z, --modparms show zfcp (module) parameters
|
||||||
-b, --busid=BUSID select specific busid
|
-b, --busid=BUSID select specific busid
|
||||||
-p, --wwpn=WWPN select specific port name
|
-p, --wwpn=WWPN select specific port name
|
||||||
-l, --lun=LUN select specific LUN
|
-l, --lun=LUN select specific LUN
|
||||||
-a, --attributes show all attributes
|
-a, --attributes show attributes
|
||||||
|
-m, --moreattrs show more attributes
|
||||||
|
(host: css; port: zfcp_port; SCSI device: zfcp_unit)
|
||||||
|
specify twice to show more attributes for SCSI devices
|
||||||
|
(scsi_disk,block,integrity,queue,iosched)
|
||||||
-V, --verbose show sysfs paths of associated class
|
-V, --verbose show sysfs paths of associated class
|
||||||
and bus devices
|
and bus devices
|
||||||
|
-e, --extended extended output format
|
||||||
-s, --sysfs=PATH use path as sysfs (for dbginfo archives)
|
-s, --sysfs=PATH use path as sysfs (for dbginfo archives)
|
||||||
-h, --help print this help
|
-h, --help print this help
|
||||||
-v, --version print version information
|
-v, --version print version information
|
||||||
|
|
||||||
EXAMPLE:
|
EXAMPLE:
|
||||||
List for all zfcp adapters, ports and units the names of their
|
List for all zfcp adapters, ports and units the names of their
|
||||||
associated SCSI hosts, FC remote ports and SCSI devices.
|
associated SCSI hosts, FC remote ports and SCSI devices.
|
||||||
|
|
||||||
#> lszfcp -P -H -D
|
#> lszfcp -P -H -D
|
||||||
@@ -129,29 +161,95 @@ show_attributes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
show_modparms()
|
||||||
|
{
|
||||||
|
local modparmdir=$SYSFS/module/zfcp/parameters
|
||||||
|
|
||||||
|
[ -d "$modparmdir" ] || return
|
||||||
|
|
||||||
|
if [ $VERBOSITY -ne 0 ]; then
|
||||||
|
echo "$modparmdir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'Module = "zfcp"'
|
||||||
|
show_attributes "$modparmdir"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
show_hosts()
|
show_hosts()
|
||||||
{
|
{
|
||||||
HOST_LIST=`ls -dX $SYSFS/devices/css0/[0-9]*/[0-9]*/host[0-9]*`
|
HOST_LIST=`ls -dX $SYSFS/devices/css0/[0-9]*/[0-9]*/host[0-9]* \
|
||||||
|
2> /dev/null`
|
||||||
|
|
||||||
|
if $SHOW_EXTENDED; then
|
||||||
|
# add all "defunct" FCP devices
|
||||||
|
HOST_LIST="$HOST_LIST
|
||||||
|
$(ls -dX $SYSFS/devices/css[0-9]*/defunct/[0-9]*/host[0-9]* 2>/dev/null)"
|
||||||
|
# add all FCP devices that have never been online
|
||||||
|
for HOST_PATH in $SYSFS/bus/ccw/drivers/zfcp/*.*.*; do
|
||||||
|
[ -d $HOST_PATH/host[0-9]* ] && continue # is/was online
|
||||||
|
HOST_LIST="$HOST_LIST
|
||||||
|
$(readlink -e $HOST_PATH)/-"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
for HOST_PATH in $HOST_LIST; do
|
for HOST_PATH in $HOST_LIST; do
|
||||||
SCSI_HOST=`basename $HOST_PATH`
|
SCSI_HOST=`basename $HOST_PATH`
|
||||||
ADAPTER_PATH=`dirname $HOST_PATH`
|
ADAPTER_PATH=`dirname $HOST_PATH`
|
||||||
ADAPTER=`basename $ADAPTER_PATH`
|
ADAPTER=`basename $ADAPTER_PATH`
|
||||||
|
|
||||||
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
||||||
|
|
||||||
|
read ONLINE < $ADAPTER_PATH/online
|
||||||
|
read AVAILABILITY < $ADAPTER_PATH/availability
|
||||||
|
[ -r $ADAPTER_PATH/failed ] && read FAILED < $ADAPTER_PATH/failed
|
||||||
|
DEFUNCT=${ADAPTER_PATH%/*} # strip devbusid
|
||||||
|
DEFUNCT=${DEFUNCT##*/} # basename
|
||||||
|
HOSTMARKER=""
|
||||||
|
if $SHOW_EXTENDED; then
|
||||||
|
if [ "$DEFUNCT" = "defunct" ]; then
|
||||||
|
HOSTMARKER=" defunct"
|
||||||
|
elif [ "$ONLINE" = "0" ]; then
|
||||||
|
HOSTMARKER=" offline"
|
||||||
|
elif [ "$FAILED" = "1" ]; then
|
||||||
|
HOSTMARKER=" failed"
|
||||||
|
elif [ "$AVAILABILITY" != "good" ]; then
|
||||||
|
HOSTMARKER=" NotAvailable"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if [ $VERBOSITY -eq 0 ]; then
|
if [ $VERBOSITY -eq 0 ]; then
|
||||||
echo $ADAPTER $SCSI_HOST
|
echo $ADAPTER $SCSI_HOST$HOSTMARKER
|
||||||
else
|
else
|
||||||
echo $ADAPTER_PATH
|
echo $ADAPTER_PATH$HOSTMARKER
|
||||||
$FC_CLASS && echo "$SYSFS/class/fc_host/$SCSI_HOST"
|
if [ "$SCSI_HOST" != "-" ]; then
|
||||||
echo "$SYSFS/class/scsi_host/$SCSI_HOST"
|
$FC_CLASS && echo "$SYSFS/class/fc_host/$SCSI_HOST"
|
||||||
|
echo "$SYSFS/class/scsi_host/$SCSI_HOST"
|
||||||
|
else
|
||||||
|
echo "-"
|
||||||
|
echo "-"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $SHOW_ATTRIBUTES; then
|
if $SHOW_ATTRIBUTES; then
|
||||||
|
if [ $SHOW_MORE_ATTRS -ge 1 ]; then
|
||||||
|
echo 'Bus = "css"'
|
||||||
|
if [ "$DEFUNCT" = "defunct" ]; then
|
||||||
|
printf " %-19s\n" "defunct"
|
||||||
|
else
|
||||||
|
show_attributes ${ADAPTER_PATH%/*}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo 'Bus = "ccw"'
|
echo 'Bus = "ccw"'
|
||||||
show_attributes $ADAPTER_PATH
|
show_attributes $ADAPTER_PATH
|
||||||
|
|
||||||
|
if [ "$SCSI_HOST" = "-" ]; then
|
||||||
|
# skip output of non-existent fc_host & scsi_host
|
||||||
|
echo
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
if $FC_CLASS; then
|
if $FC_CLASS; then
|
||||||
echo 'Class = "fc_host"'
|
echo 'Class = "fc_host"'
|
||||||
show_attributes \
|
show_attributes \
|
||||||
@@ -175,7 +273,7 @@ show_ports()
|
|||||||
for PORT_PATH in $PORT_LIST; do
|
for PORT_PATH in $PORT_LIST; do
|
||||||
WWPN=`basename $PORT_PATH`
|
WWPN=`basename $PORT_PATH`
|
||||||
ADAPTER=`basename \`dirname $PORT_PATH\``
|
ADAPTER=`basename \`dirname $PORT_PATH\``
|
||||||
|
|
||||||
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
||||||
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
||||||
|
|
||||||
@@ -196,30 +294,60 @@ show_ports()
|
|||||||
for FC_PORT_PATH in $PORT_LIST; do
|
for FC_PORT_PATH in $PORT_LIST; do
|
||||||
PORT=`basename $FC_PORT_PATH`
|
PORT=`basename $FC_PORT_PATH`
|
||||||
read PORT_STATE < $FC_PORT_PATH/port_state
|
read PORT_STATE < $FC_PORT_PATH/port_state
|
||||||
if [ "$PORT_STATE" == "Online" ];
|
if [ "$PORT_STATE" == "Online" ] || $SHOW_EXTENDED; then
|
||||||
then
|
|
||||||
read WWPN < $FC_PORT_PATH/port_name
|
read WWPN < $FC_PORT_PATH/port_name
|
||||||
else
|
else
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
PORTSTATEMARKER=""
|
||||||
|
$SHOW_EXTENDED && [ "$PORT_STATE" != "Online" ] \
|
||||||
|
&& PORTSTATEMARKER=" NotOnline"
|
||||||
|
|
||||||
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
||||||
|
|
||||||
ADAPTER_PORT_PATH=`ls -d \
|
local sysreal=$(readlink -e "$FC_PORT_PATH")
|
||||||
$SYSFS/devices/css0/*/*/$WWPN/../host[0-9]*/$PORT |\
|
local ADAPTER=""
|
||||||
awk -F "/../host" '{ print $1 }'`
|
while [ -n "$sysreal" ]; do
|
||||||
ADAPTER=`basename \`dirname $ADAPTER_PORT_PATH\``
|
# ascend to parent: strip last path part
|
||||||
|
sysreal=${sysreal%/*}
|
||||||
|
[ -h $sysreal/subsystem ] || continue
|
||||||
|
local subsystem=$(readlink -e $sysreal/subsystem)
|
||||||
|
if [ "${subsystem##*/}" = "ccw" ]; then
|
||||||
|
ADAPTER=${sysreal##*/}
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ -z "$ADAPTER" ] && continue # skip not zfcp-attached ones
|
||||||
|
if [ -d $SYSFS/devices/css[0-9]*/[0-9d]*/[0-9]*/$WWPN/../host[0-9]*/$PORT ];
|
||||||
|
then
|
||||||
|
ADAPTER_PORT_PATH=$SYSFS/devices/css[0-9]*/[0-9d]*/$ADAPTER/$WWPN
|
||||||
|
else
|
||||||
|
ADAPTER_PORT_PATH="-"
|
||||||
|
fi
|
||||||
|
|
||||||
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
||||||
|
|
||||||
if [ $VERBOSITY -eq 0 ]; then
|
if [ $VERBOSITY -eq 0 ]; then
|
||||||
echo "$ADAPTER/$WWPN $PORT"
|
echo "$ADAPTER/$WWPN $PORT$PORTSTATEMARKER"
|
||||||
else
|
else
|
||||||
echo $ADAPTER_PORT_PATH
|
if [ "$ADAPTER_PORT_PATH" != "-" ]; then
|
||||||
echo $FC_PORT_PATH
|
echo $ADAPTER_PORT_PATH
|
||||||
|
else
|
||||||
|
echo "- (NoMoreZfcpPort:$ADAPTER/$WWPN)"
|
||||||
|
fi
|
||||||
|
echo $FC_PORT_PATH$PORTSTATEMARKER
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $SHOW_ATTRIBUTES; then
|
if $SHOW_ATTRIBUTES; then
|
||||||
|
if [ $SHOW_MORE_ATTRS -ge 1 ] \
|
||||||
|
&& [ "$ADAPTER_PORT_PATH" != "-" ] \
|
||||||
|
&& [ -d $ADAPTER_PORT_PATH ];
|
||||||
|
then
|
||||||
|
# fc_rport can exist without zfcp_port
|
||||||
|
# (e.g. after port_remove)
|
||||||
|
echo 'Class = "zfcp_port"'
|
||||||
|
show_attributes "$ADAPTER_PORT_PATH"
|
||||||
|
fi
|
||||||
echo 'Class = "fc_remote_ports"'
|
echo 'Class = "fc_remote_ports"'
|
||||||
show_attributes "$FC_PORT_PATH"
|
show_attributes "$FC_PORT_PATH"
|
||||||
echo
|
echo
|
||||||
@@ -234,54 +362,166 @@ show_devices()
|
|||||||
if $FC_CLASS; then
|
if $FC_CLASS; then
|
||||||
SCSI_DEVICE_LIST=`ls -d \
|
SCSI_DEVICE_LIST=`ls -d \
|
||||||
$SYSFS/bus/ccw/drivers/zfcp/*/host*/rport*/target*/*/ \
|
$SYSFS/bus/ccw/drivers/zfcp/*/host*/rport*/target*/*/ \
|
||||||
2>/dev/null |grep -P '\d+:\d+:\d+:\d+'`
|
2>/dev/null |grep -P '\d+:\d+:\d+:\d+'`
|
||||||
else
|
else
|
||||||
SCSI_DEVICE_LIST=`ls -d $SYSFS/devices/css0/*/*/host[0-9]*/*/`
|
SCSI_DEVICE_LIST=`ls -d $SYSFS/devices/css0/*/*/host[0-9]*/*/`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$SCSI_DEVICE_LIST" ]; then
|
if $SHOW_EXTENDED; then
|
||||||
echo "Error: No fcp devices found."
|
ZFCP_UNIT_LIST=$(ls -d \
|
||||||
|
$SYSFS/devices/css[0-9]*/[0-9d]*/[0-9]*/0x*/0x* \
|
||||||
|
2> /dev/null)
|
||||||
|
else
|
||||||
|
ZFCP_UNIT_LIST=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$SCSI_DEVICE_LIST" ] && [ -z "$ZFCP_UNIT_LIST" ]; then
|
||||||
|
if $SHOW_EXTENDED; then
|
||||||
|
echo "Error: No zfcp-attached SCSI devices found."
|
||||||
|
else
|
||||||
|
echo "Error: No fcp devices found."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for SCSI_DEVICE_PATH in $SCSI_DEVICE_LIST; do
|
for SCSI_DEVICE_PATH in $SCSI_DEVICE_LIST; do
|
||||||
read ADAPTER < $SCSI_DEVICE_PATH/hba_id
|
read ADAPTER < $SCSI_DEVICE_PATH/hba_id
|
||||||
read WWPN < $SCSI_DEVICE_PATH/wwpn
|
read WWPN < $SCSI_DEVICE_PATH/wwpn
|
||||||
read LUN < $SCSI_DEVICE_PATH/fcp_lun
|
read LUN < $SCSI_DEVICE_PATH/fcp_lun
|
||||||
|
|
||||||
|
# remove from ZFCP_UNIT_LIST if SCSI device exists
|
||||||
|
REDUCED_LIST=""
|
||||||
|
for UNIT_PATH in $ZFCP_UNIT_LIST; do
|
||||||
|
STRIPPED_PATH=$UNIT_PATH
|
||||||
|
L=${UNIT_PATH##*/}
|
||||||
|
STRIPPED_PATH=${STRIPPED_PATH%/*}
|
||||||
|
W=${STRIPPED_PATH##*/}
|
||||||
|
STRIPPED_PATH=${STRIPPED_PATH%/*}
|
||||||
|
A=${STRIPPED_PATH##*/}
|
||||||
|
[ "$A/$W/$L" = "$ADAPTER/$WWPN/$LUN" ] && continue
|
||||||
|
REDUCED_LIST="$REDUCED_LIST $UNIT_PATH"
|
||||||
|
done
|
||||||
|
ZFCP_UNIT_LIST="$REDUCED_LIST"
|
||||||
|
|
||||||
|
[ $LUN != ${PAR_LUN:-$LUN} ] && continue
|
||||||
|
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
||||||
|
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
||||||
|
|
||||||
|
ZFCP_UNIT_PATH=$SYSFS/devices/css[0-9]*/[0-9d]*/$ADAPTER/$WWPN/$LUN
|
||||||
|
SDEVMARKER=""
|
||||||
|
if $SHOW_EXTENDED; then
|
||||||
|
[ -d $ZFCP_UNIT_PATH ] || SDEVMARKER="$SDEVMARKER auto"
|
||||||
|
[ -r $SCSI_DEVICE_PATH/state ] \
|
||||||
|
&& read SDEVSTATE < $SCSI_DEVICE_PATH/state
|
||||||
|
[ "$SDEVSTATE" != "running" ] \
|
||||||
|
&& SDEVMARKER="$SDEVMARKER NotRunning"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $VERBOSITY -eq 0 ]; then
|
||||||
|
echo "$ADAPTER/$WWPN/$LUN `basename $SCSI_DEVICE_PATH`$SDEVMARKER"
|
||||||
|
else
|
||||||
|
echo "`ls -d $SYSFS/devices/css0/[0-9d]*/$ADAPTER`/$WWPN/$LUN"
|
||||||
|
echo ${SCSI_DEVICE_PATH%*/}$SDEVMARKER # without trailing slash
|
||||||
|
|
||||||
|
# On live systems, there are links to the block and
|
||||||
|
# generic devices. In a dbginfo archive, these links
|
||||||
|
# are not present. Therefore, fall back to reading
|
||||||
|
# the runtime.out log file.
|
||||||
|
if [ `ls $SCSI_DEVICE_PATH | grep -c block:` -eq 1 ]
|
||||||
|
then
|
||||||
|
BLOCK_DEV=`ls $SCSI_DEVICE_PATH | grep block:`
|
||||||
|
GEN_DEV=`ls $SCSI_DEVICE_PATH |\
|
||||||
|
grep scsi_generic:`
|
||||||
|
echo -n "$SYSFS/block/${BLOCK_DEV#*:} "
|
||||||
|
echo "$SYSFS/class/scsi_generic/${GEN_DEV#*:}"
|
||||||
|
|
||||||
|
elif [ -d $SCSI_DEVICE_PATH/block ] && $SHOW_EXTENDED
|
||||||
|
then
|
||||||
|
# case without CONFIG_SYSFS_DEPRECATED
|
||||||
|
BLOCK_DEV=$(echo $SCSI_DEVICE_PATH/block/*)
|
||||||
|
BLOCK_DEV=${BLOCK_DEV##*/}
|
||||||
|
echo -n "$SYSFS/block/$BLOCK_DEV "
|
||||||
|
local SGPATH=$SCSI_DEVICE_PATH/scsi_generic
|
||||||
|
if [ -d $SGPATH ]; then
|
||||||
|
GEN_DEV=$(echo $SGPATH/*)
|
||||||
|
GEN_DEV=${GEN_DEV##*/}
|
||||||
|
echo "$SYSFS/class/scsi_generic/$GEN_DEV"
|
||||||
|
else
|
||||||
|
echo "-"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FIXME Find a way to assign the generic devices.
|
||||||
|
elif [ -r $SYSFS/../runtime.out ]; then
|
||||||
|
SCSI_DEV=`basename $SCSI_DEVICE_PATH`
|
||||||
|
echo "$SYSFS/block/"`grep -r "\[$SCSI_DEV\]"\
|
||||||
|
$SYSFS/../runtime.out |\
|
||||||
|
awk -F "/dev/" '{print $2}'`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $SHOW_ATTRIBUTES && [ $SHOW_MORE_ATTRS -ge 1 ]; then
|
||||||
|
# auto scan LUNs not necessarily have a zfcp_unit
|
||||||
|
if [ -d $ZFCP_UNIT_PATH ]; then
|
||||||
|
echo 'Class = "zfcp_unit"'
|
||||||
|
show_attributes "$ZFCP_UNIT_PATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if $SHOW_ATTRIBUTES; then
|
||||||
|
echo 'Class = "scsi_device"'
|
||||||
|
show_attributes "$SCSI_DEVICE_PATH"
|
||||||
|
fi
|
||||||
|
if $SHOW_ATTRIBUTES && [ $SHOW_MORE_ATTRS -ge 2 ]; then
|
||||||
|
if [ -d $SCSI_DEVICE_PATH/scsi_disk ]; then
|
||||||
|
echo 'Class = "scsi_disk"'
|
||||||
|
show_attributes "$SCSI_DEVICE_PATH/scsi_disk/$(basename $SCSI_DEVICE_PATH)"
|
||||||
|
fi
|
||||||
|
if [ -d $SCSI_DEVICE_PATH/block ]; then
|
||||||
|
echo 'Class = "block"'
|
||||||
|
show_attributes "$SCSI_DEVICE_PATH/block/*/"
|
||||||
|
fi
|
||||||
|
if [ -d $SCSI_DEVICE_PATH/block/*/integrity ]; then
|
||||||
|
echo 'Class = "block_integrity"'
|
||||||
|
show_attributes "$SCSI_DEVICE_PATH/block/*/integrity"
|
||||||
|
fi
|
||||||
|
if [ -d $SCSI_DEVICE_PATH/block/*/queue ]; then
|
||||||
|
echo 'Class = "block_queue"'
|
||||||
|
show_attributes "$SCSI_DEVICE_PATH/block/*/queue"
|
||||||
|
fi
|
||||||
|
if [ -d $SCSI_DEVICE_PATH/block/*/queue/iosched ]; then
|
||||||
|
echo 'Class = "block_queue_iosched"'
|
||||||
|
show_attributes "$SCSI_DEVICE_PATH/block/*/queue/iosched"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if $SHOW_ATTRIBUTES; then
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# what's left in ZFCP_UNIT_LIST are now units without SCSI device
|
||||||
|
for UNIT_PATH in $ZFCP_UNIT_LIST; do
|
||||||
|
STRIPPED_PATH=$UNIT_PATH
|
||||||
|
LUN=${UNIT_PATH##*/}
|
||||||
|
STRIPPED_PATH=${STRIPPED_PATH%/*}
|
||||||
|
WWPN=${STRIPPED_PATH##*/}
|
||||||
|
STRIPPED_PATH=${STRIPPED_PATH%/*}
|
||||||
|
ADAPTER=${STRIPPED_PATH##*/}
|
||||||
|
|
||||||
[ $LUN != ${PAR_LUN:-$LUN} ] && continue
|
[ $LUN != ${PAR_LUN:-$LUN} ] && continue
|
||||||
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
[ $WWPN != ${PAR_WWPN:-$WWPN} ] && continue
|
||||||
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
[ $ADAPTER != ${PAR_BUSID:-$ADAPTER} ] && continue
|
||||||
|
|
||||||
if [ $VERBOSITY -eq 0 ]; then
|
if [ $VERBOSITY -eq 0 ]; then
|
||||||
echo "$ADAPTER/$WWPN/$LUN `basename $SCSI_DEVICE_PATH`"
|
echo "$ADAPTER/$WWPN/$LUN - failed"
|
||||||
else
|
else
|
||||||
echo "`ls -d $SYSFS/devices/css0/*/$ADAPTER`/$WWPN/$LUN"
|
echo "$UNIT_PATH failed"
|
||||||
echo ${SCSI_DEVICE_PATH%*/} # without trailing slash
|
echo "-"
|
||||||
|
fi
|
||||||
|
|
||||||
# On live systems, there are links to the block and
|
if $SHOW_ATTRIBUTES && [ $SHOW_MORE_ATTRS -ge 1 ]; then
|
||||||
# generic devices. In a dbginfo archive, these links
|
echo 'Class = "zfcp_unit"'
|
||||||
# are not present. Therefore, fall back to reading
|
show_attributes "$UNIT_PATH"
|
||||||
# the runtime.out log file.
|
|
||||||
if [ `ls $SCSI_DEVICE_PATH | grep -c block:` -eq 1 ]
|
|
||||||
then
|
|
||||||
BLOCK_DEV=`ls $SCSI_DEVICE_PATH | grep block:`
|
|
||||||
GEN_DEV=`ls $SCSI_DEVICE_PATH |\
|
|
||||||
grep scsi_generic:`
|
|
||||||
echo -n "$SYSFS/block/${BLOCK_DEV#*:} "
|
|
||||||
echo "$SYSFS/class/scsi_generic/${GEN_DEV#*:}"
|
|
||||||
|
|
||||||
# FIXME Find a way to assign the generic devices.
|
|
||||||
elif [ -r $SYSFS/../runtime.out ]; then
|
|
||||||
SCSI_DEV=`basename $SCSI_DEVICE_PATH`
|
|
||||||
echo "$SYSFS/block/"`grep -r "\[$SCSI_DEV\]"\
|
|
||||||
$SYSFS/../runtime.out |\
|
|
||||||
awk -F "/dev/" '{print $2}'`
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $SHOW_ATTRIBUTES; then
|
if $SHOW_ATTRIBUTES; then
|
||||||
echo 'Class = "scsi_device"'
|
|
||||||
show_attributes "$SCSI_DEVICE_PATH"
|
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -290,8 +530,8 @@ show_devices()
|
|||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
ARGS=`getopt --options ahvHPDVb:p:l:s: --longoptions \
|
ARGS=`getopt --options ahvHPDVb:p:l:s:emZ --longoptions \
|
||||||
attributes,help,version,hosts,ports,devices,verbose,busid:,wwpn:,lun:,sysfs: \
|
attributes,help,version,hosts,ports,devices,verbose,busid:,wwpn:,lun:,sysfs:,extended,moreattrs,modparms \
|
||||||
-n "$SCRIPTNAME" -- "$@"`
|
-n "$SCRIPTNAME" -- "$@"`
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
@@ -305,6 +545,8 @@ eval set -- "$ARGS"
|
|||||||
for ARG; do
|
for ARG; do
|
||||||
case "$ARG" in
|
case "$ARG" in
|
||||||
-a|--attributes) SHOW_ATTRIBUTES=true; shift 1;;
|
-a|--attributes) SHOW_ATTRIBUTES=true; shift 1;;
|
||||||
|
-m|--moreattrs) ((SHOW_MORE_ATTRS++)); shift 1;;
|
||||||
|
-e|--extended) SHOW_EXTENDED=true; shift 1;;
|
||||||
-b|--busid) PAR_BUSID=$2; shift 2;;
|
-b|--busid) PAR_BUSID=$2; shift 2;;
|
||||||
-h|--help) print_help; exit 0;;
|
-h|--help) print_help; exit 0;;
|
||||||
-l|--lun) PAR_LUN=$2; shift 2;;
|
-l|--lun) PAR_LUN=$2; shift 2;;
|
||||||
@@ -314,6 +556,7 @@ for ARG; do
|
|||||||
-D|--devices) SHOW_DEVICES=1; shift 1;;
|
-D|--devices) SHOW_DEVICES=1; shift 1;;
|
||||||
-P|--ports) SHOW_PORTS=1; shift 1;;
|
-P|--ports) SHOW_PORTS=1; shift 1;;
|
||||||
-V|--verbose) VERBOSITY=1; shift 1;;
|
-V|--verbose) VERBOSITY=1; shift 1;;
|
||||||
|
-Z|--modparms) SHOW_MODPARMS=1; shift 1;;
|
||||||
-s|--sysfs) SYSFS=$2; shift 2;;
|
-s|--sysfs) SYSFS=$2; shift 2;;
|
||||||
--) shift; break;;
|
--) shift; break;;
|
||||||
esac
|
esac
|
||||||
@@ -325,6 +568,10 @@ check_fc_class
|
|||||||
check_fcp_devs
|
check_fcp_devs
|
||||||
|
|
||||||
default=1
|
default=1
|
||||||
|
if [ $SHOW_MODPARMS -eq 1 ]; then
|
||||||
|
default=0; show_modparms
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $SHOW_HOSTS -eq 1 ]; then
|
if [ $SHOW_HOSTS -eq 1 ]; then
|
||||||
default=0; show_hosts
|
default=0; show_hosts
|
||||||
elif [ $SHOW_PORTS -eq 0 -a $SHOW_DEVICES -eq 0 -a -n "$PAR_BUSID" ]; then
|
elif [ $SHOW_PORTS -eq 0 -a $SHOW_DEVICES -eq 0 -a -n "$PAR_BUSID" ]; then
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
.\" Copyright IBM Corp. 2006, 2017
|
.\" Copyright IBM Corp. 2006, 2019
|
||||||
.\" 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 LSZFCP 8 "Mar 2008" "s390-tools"
|
.TH LSZFCP 8 "Feb 2019" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
lszfcp \- list information about zfcp adapters, ports, and units
|
lszfcp \- list information about zfcp adapters, ports, and units
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B lszfcp
|
.B lszfcp
|
||||||
.RB [ \-hvVaHDP ]
|
.RB [ \-hvVaZHDPem ]
|
||||||
.RB [ \-b
|
.RB [ \-b
|
||||||
.IR busid ]
|
.IR busid ]
|
||||||
.RB [ \-l
|
.RB [ \-l
|
||||||
@@ -28,8 +28,10 @@ scsi_devices.
|
|||||||
The default is to list busids of all zfcp adapters and their corresponding
|
The default is to list busids of all zfcp adapters and their corresponding
|
||||||
SCSI host names.
|
SCSI host names.
|
||||||
|
|
||||||
There are three output variants. Default (without options "-a" or
|
There are four output variants. Default (without options "-a" or
|
||||||
"-V") is one line for each object. For adapters the busid and their
|
"-V" or "-Z") is one line for each object.
|
||||||
|
For the zfcp device driver (module), its parameters are listed.
|
||||||
|
For adapters the busid and their
|
||||||
corresponding SCSI host names are listed. For ports the pair
|
corresponding SCSI host names are listed. For ports the pair
|
||||||
"busid"/"wwpn" and their corresponding FC-remote-port names are listed.
|
"busid"/"wwpn" and their corresponding FC-remote-port names are listed.
|
||||||
For units the triple "busid"/"wwpn"/"lun" and their corresponding SCSI
|
For units the triple "busid"/"wwpn"/"lun" and their corresponding SCSI
|
||||||
@@ -37,20 +39,53 @@ device names are listed.
|
|||||||
|
|
||||||
Option "-V" additionally shows the sysfs paths of interest for the
|
Option "-V" additionally shows the sysfs paths of interest for the
|
||||||
listed object.
|
listed object.
|
||||||
|
If a SCSI device has an associated block device (disk)
|
||||||
|
and SCSI generic (sg) device, show their sysfs paths in a 3rd line.
|
||||||
|
|
||||||
Option "-a" additionally shows all attributes of interest found in
|
Option "-a" additionally shows attributes of interest found in
|
||||||
sysfs for the listed object.
|
sysfs for the listed object.
|
||||||
|
|
||||||
|
Option "-m" together with option "-a" shows sysfs attributes if available for:
|
||||||
|
host: css (subchannel); port: zfcp_port; lun: zfcp_unit.
|
||||||
|
Specifying option "-m" twice together with option "-a"
|
||||||
|
additionally shows SCSI device sysfs attributes
|
||||||
|
if available for:
|
||||||
|
scsi_disk, block, block_integrity, block_queue, block_queue_iosched.
|
||||||
|
|
||||||
|
Option "-e" enables an extended output format.
|
||||||
|
It enumerates all hosts/ports/luns independent of their state.
|
||||||
|
It also produces some improved error messages.
|
||||||
|
The extended output format can help determining problems.
|
||||||
|
Since a long time, without option "-e", lszfcp has
|
||||||
|
.I
|
||||||
|
not
|
||||||
|
enumerated:
|
||||||
|
hosts that have never been online (since last bind to zfcp device driver),
|
||||||
|
hosts that are defunct (CHPID configured off, or z/VM detach),
|
||||||
|
ports with fc_rport port_state unequal to "Online" (such as fibres pulled),
|
||||||
|
zfcp units without associated SCSI device (unit_add of non-existent LUN).
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B -a, --attributes
|
.B -a, --attributes
|
||||||
Show all attributes of the specified objects.
|
Show the most interesting attributes of the specified objects.
|
||||||
|
.TP
|
||||||
|
.B -m, --moreattrs
|
||||||
|
Show more attributes of the specified objects.
|
||||||
|
Host: css (subchannel). Port: zfcp_port. Lun: zfcp_unit.
|
||||||
|
If specified twice,
|
||||||
|
show additional attributes of the specified SCSI device objects:
|
||||||
|
scsi_disk, block, block_integrity, block_queue, block_queue_iosched.
|
||||||
|
.TP
|
||||||
|
.B -Z, --modparms
|
||||||
|
List zfcp (module) parameters with a scope of the device driver.
|
||||||
.TP
|
.TP
|
||||||
.B -D, --devices
|
.B -D, --devices
|
||||||
List zfcp units and SCSI devices.
|
List zfcp units and SCSI devices.
|
||||||
.TP
|
.TP
|
||||||
.B -H, --hosts
|
.B -H, --hosts
|
||||||
List zfcp adapters and fc-hosts (default). Information is given only
|
List zfcp adapters, fc-hosts, and scsi-hosts (default).
|
||||||
|
Without option "-e", information is given only
|
||||||
for adapters that are online (registered at the SCSI stack).
|
for adapters that are online (registered at the SCSI stack).
|
||||||
.TP
|
.TP
|
||||||
.B -P, --ports
|
.B -P, --ports
|
||||||
@@ -69,9 +104,14 @@ List zfcp port(s) and FC remote port(s) selected by wwpn. (Information
|
|||||||
for several ports might be shown if a remote port is configured for
|
for several ports might be shown if a remote port is configured for
|
||||||
different adapters.)
|
different adapters.)
|
||||||
.TP
|
.TP
|
||||||
|
.B -e, --extended
|
||||||
|
Generate extended output.
|
||||||
|
.TP
|
||||||
.B -V, --verbose
|
.B -V, --verbose
|
||||||
Generate verbose output. Display sysfs path names of class and bus
|
Generate verbose output. Display sysfs path names of class and bus
|
||||||
devices that are of interest for this object.
|
devices that are of interest for this object.
|
||||||
|
If a SCSI device has an associated block device (disk)
|
||||||
|
and SCSI generic (sg) device, show their sysfs paths in a 3rd line.
|
||||||
.TP
|
.TP
|
||||||
.B -s, --sysfs /path/to/sys
|
.B -s, --sysfs /path/to/sys
|
||||||
Use path as sysfs (for dbginfo archives).
|
Use path as sysfs (for dbginfo archives).
|
||||||
@@ -86,7 +126,7 @@ Display version info and exit.
|
|||||||
.PP
|
.PP
|
||||||
Options "-b", "-p" or "-l" are of restricting nature. They limit the output
|
Options "-b", "-p" or "-l" are of restricting nature. They limit the output
|
||||||
to those adapters, ports or units that match the specified busid, wwpn and lun.
|
to those adapters, ports or units that match the specified busid, wwpn and lun.
|
||||||
If none of the options "-H", "-P" and "-D" are specified, "-b" implies "-H",
|
If none of the options "-Z", "-H", "-P" and "-D" are specified, "-b" implies "-H",
|
||||||
"-p" implies "-P" and "-l" implies "-D".
|
"-p" implies "-P" and "-l" implies "-D".
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
@@ -105,6 +145,8 @@ Show all adapters that match the given busid, all ports that match the given
|
|||||||
busid and wwpnn and show all units that match the given busid, wwpn and lun.
|
busid and wwpnn and show all units that match the given busid, wwpn and lun.
|
||||||
.IP "lszfcp -b 0.0.0815 -p 0x5005123456789000 -l 0x0000000000000000 -H -P -D"
|
.IP "lszfcp -b 0.0.0815 -p 0x5005123456789000 -l 0x0000000000000000 -H -P -D"
|
||||||
Generates same output as previous example.
|
Generates same output as previous example.
|
||||||
|
.IP "lszfcp -ZHPDVeamm"
|
||||||
|
Generates the fullest output in the extended format.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR lscss (8)
|
.BR lscss (8)
|
||||||
|
|
||||||
|
|||||||
@@ -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,24 +1,27 @@
|
|||||||
include ../../common.mak
|
include ../../common.mak
|
||||||
|
|
||||||
all: chzcrypt lszcrypt zcryptctl
|
all: chzcrypt lszcrypt zcryptctl zcryptstats
|
||||||
|
|
||||||
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)
|
zcryptctl: zcryptctl.o misc.o $(libs)
|
||||||
|
zcryptstats: zcryptstats.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) -g $(GROUP) -o $(OWNER) -m 755 zcryptctl $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zcryptstats $(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
|
$(INSTALL) -m 644 -c zcryptctl.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
|
$(INSTALL) -m 644 -c zcryptstats.8 $(DESTDIR)$(MANDIR)/man8
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o chzcrypt lszcrypt zcryptctl
|
rm -f *.o chzcrypt lszcrypt zcryptctl zcryptstats
|
||||||
|
|
||||||
.PHONY: all install clean
|
.PHONY: all install clean
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
.\" nroff -man lszcrypt.8
|
.\" nroff -man lszcrypt.8
|
||||||
.\" to process this source
|
.\" to process this source
|
||||||
.\"
|
.\"
|
||||||
.TH LSZCRYPT 8 "OCT 2017" "s390-tools"
|
.TH LSZCRYPT 8 "JAN 2019" "s390-tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
lszcrypt \- display zcrypt device and configuration information
|
lszcrypt \- display zcrypt device and configuration information
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -111,6 +111,68 @@ Displays help text and exits.
|
|||||||
.TP 8
|
.TP 8
|
||||||
.B -v, --version
|
.B -v, --version
|
||||||
Displays version information and exits.
|
Displays version information and exits.
|
||||||
|
.SH VERBOSE LISTING DETAILS
|
||||||
|
Some of the columns showing up in verbose listing mode may need some
|
||||||
|
explanation:
|
||||||
|
.TP
|
||||||
|
.B TYPE and HWTYPE
|
||||||
|
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
||||||
|
device driver presumes that this crypto card is. The currently known values
|
||||||
|
are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5 and 12=CEX6.
|
||||||
|
.br
|
||||||
|
The TYPE is a human readable value showing the hardware type and the basic
|
||||||
|
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
||||||
|
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
||||||
|
.TP
|
||||||
|
.B REQUESTS
|
||||||
|
This is the counter value of successful processed requests on card or queue
|
||||||
|
level. Successful here means the request was processed without any failure
|
||||||
|
in the whole processing chain.
|
||||||
|
.TP
|
||||||
|
.B PENDING
|
||||||
|
The underlying firmware and hardware layer usually provide some queuing
|
||||||
|
space for requests. When this queue is already filled up, the zcrypt device
|
||||||
|
driver maintains a software queue of pending requests. The sum of these
|
||||||
|
both values is displayed here and shows the amount of requests waiting for
|
||||||
|
processing on card or queue level.
|
||||||
|
.TP
|
||||||
|
.B FUNCTIONS
|
||||||
|
This column shows firmware and hardware function details:
|
||||||
|
.br
|
||||||
|
S - APSC available: card/queue can handle requests with the special bit
|
||||||
|
enabled.
|
||||||
|
.br
|
||||||
|
M - Accelerator card/queue with support for RSA ME with up to 4k key size.
|
||||||
|
.br
|
||||||
|
C - Accelerator card/queue with support for RSA CRT with up to 4k key size.
|
||||||
|
.br
|
||||||
|
D - Card/queue is providing CCA functions (this is the CCA Coprocessor mode).
|
||||||
|
.br
|
||||||
|
A - Card/queue is providing Accelerator functions (this is the Accelerator mode).
|
||||||
|
.br
|
||||||
|
X - Card/queue is providing EP11 functions (this is the EP11 Coprocessor mode).
|
||||||
|
.br
|
||||||
|
N - APXA available (ability to address more than 16 crypto cards and domains).
|
||||||
|
.br
|
||||||
|
F - Full function support (opposed to restricted function support, see below).
|
||||||
|
.br
|
||||||
|
R - Restricted function support. The F and R flag both reflect if a
|
||||||
|
hypervisor is somehow restricting this crypto resource in a virtual
|
||||||
|
environment. Dependent on the hypervisor configuration the crypto requests
|
||||||
|
may be filtered by the hypervisor to allow only a subset of functions
|
||||||
|
within the virtual runtime environment. For example a shared CCA
|
||||||
|
Coprocessor may be restricted by the hypervisor to allow only clear key
|
||||||
|
operations within the guests.
|
||||||
|
.TP
|
||||||
|
.B DRIVER
|
||||||
|
.br
|
||||||
|
Shows which card or queue device driver currently handles this crypto
|
||||||
|
resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX6
|
||||||
|
hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
||||||
|
cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
|
||||||
|
for use by kvm hypervisor for kvm guests and not accessible to host
|
||||||
|
applications). It is also valid to have no driver handling a queue which is
|
||||||
|
shown as a -no-driver- entry.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.TP
|
.TP
|
||||||
.B lszcrypt
|
.B lszcrypt
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -620,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 */
|
||||||
@@ -639,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;
|
||||||
}
|
}
|
||||||
|
|||||||
247
zconf/zcrypt/zcryptstats.8
Normal file
247
zconf/zcrypt/zcryptstats.8
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
.\" Copyright IBM Corp. 2019
|
||||||
|
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
.\"
|
||||||
|
.TH ZCRYPTSTATS 1 "January 2019" "s390-tools"
|
||||||
|
.SH NAME
|
||||||
|
zcryptstats \- Display usage statistics of IBM Crypto Express adapters
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B zcryptstats
|
||||||
|
.RI [ OPTIONS ]
|
||||||
|
.RI [ DEVICE_ID
|
||||||
|
[...] ]
|
||||||
|
.
|
||||||
|
.PP
|
||||||
|
.B zcryptstats
|
||||||
|
.BR \-\-help | \-h
|
||||||
|
.br
|
||||||
|
.B zcryptstats
|
||||||
|
.BR \-\-version | \-v
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.
|
||||||
|
Use \fBzcryptstats\fP to display usage statistics of IBM Crypto Express
|
||||||
|
adapters.
|
||||||
|
.PP
|
||||||
|
\fBzcryptstats\fP obtains cryptographic performance measurement data
|
||||||
|
periodically and displays the data for each cryptographic device for each
|
||||||
|
interval.
|
||||||
|
A cryptographic device can be either a card device or a queue device (APQN).
|
||||||
|
\fBzcryptstats\fP runs forever unless you limit the number of intervals with
|
||||||
|
the \fB\-\-count\fP option. The default interval time is 10 seconds.
|
||||||
|
Use the \fB\-\-interval\fP option to specify a different interval time.
|
||||||
|
.PP
|
||||||
|
By default, all available cryptographic devices are monitored.
|
||||||
|
You can optionally specify the device IDs of the devices to be monitored.
|
||||||
|
The card device representation and the queue device are both in hexadecimal
|
||||||
|
notation.
|
||||||
|
.PP
|
||||||
|
Use the \fB\-\-no-apqn\fP option to omit the performance measurement data of
|
||||||
|
the queues. If the system does not support obtaining cryptographic
|
||||||
|
performance measurement data on the queue devices, only the card devices
|
||||||
|
are monitored.
|
||||||
|
.PP
|
||||||
|
For each device, a set of counters is displayed. The amount and meaning of the
|
||||||
|
counters are dependent on the device type and mode, see the COUNTERS section.
|
||||||
|
For each counter and interval, the following values are displayed:
|
||||||
|
.RS 2
|
||||||
|
.IP "\(bu" 2
|
||||||
|
Number of measured operations.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
Rate of the measured operation in operations per second.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
Utilization of the device in percent.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
Average duration of the operations.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
The sum of all operations is displayed in a separate \fBtotals\fP line.
|
||||||
|
Use the \fB\-\-only-totals\fP option to omit the individual counters and
|
||||||
|
display the totals only. Use the \fB\-\-no\-totals\fP option to omit the
|
||||||
|
totals.
|
||||||
|
.PP
|
||||||
|
|
||||||
|
.B Note:
|
||||||
|
The utilization value of a counter can exceed 100%. This value is caused by
|
||||||
|
the parallel execution of cryptographic operations.
|
||||||
|
.PP
|
||||||
|
Cryptographic performance measurement data might not be available when Linux
|
||||||
|
is running as guest under z/VM or under KVM. \fBzcryptstats\fP then displays an
|
||||||
|
error message and exits.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH OPTIONS
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR DEVICE_ID
|
||||||
|
Specifies a cryptographic device for which statistics are displayed.
|
||||||
|
A device ID can either be a card device ID
|
||||||
|
(\fI<card-id>\fP) or a queue device (APQN) ID (\fI<card-id>.<domain-id>\fP).
|
||||||
|
To filter all devices by domain, provide \fI.<domain-id>\fP.
|
||||||
|
If no IDs are given, statistics are displayed for all available devices.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-i ", " \-\-interval\~\fIINTERVAL\fP
|
||||||
|
Specifies the interval time in seconds. If this option is omitted, then the
|
||||||
|
default interval time of 10 seconds is used.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-c ", " \-\-count\~\fICOUNT\fP
|
||||||
|
Specifies the number of reports that are generated at \fIINTERVAL\fP seconds
|
||||||
|
apart. If this option is omitted, the \fBzcryptstats\fP command generates
|
||||||
|
reports continuously, until it is stopped with control-C.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-o ", " \-\-output\~\fIJSON\fP|\fITABLE\fP|\fICSV\fP
|
||||||
|
Displays the statistics in the specified format. If this option is omitted, a
|
||||||
|
comprehensive report is displayed. Supported output formats are:
|
||||||
|
.RS 8
|
||||||
|
.IP "\(bu" 2
|
||||||
|
\fBJSON:\fP Displays the statistics in Javascript Object Notation (JSON) format.
|
||||||
|
JSON output field order is undefined, and new fields might be added in the
|
||||||
|
future.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
\fBTABLE:\fP Displays the statistics in a human readable simple table format.
|
||||||
|
The individual counters are omitted, and only the totals are displayed.
|
||||||
|
This output format implies option \fB\-\-only-totals\fP.
|
||||||
|
.IP "\(bu" 2
|
||||||
|
\fBCSV:\fP Displays the statistics in comma-separated values format. The values
|
||||||
|
are separated with a semicolon. The individual counters are omitted, and only
|
||||||
|
the totals are displayed. This output format implies option
|
||||||
|
\fB\-\-only-totals\fP.
|
||||||
|
.RE
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-t ", " \-\-no\-totals
|
||||||
|
Excludes the totals of all counters of a card device or queue device
|
||||||
|
(APQN). This option cannot be specified together with option
|
||||||
|
\fB\-\-only\-totals\fP or option \fB\-\-output\fP \fITABLE\fP|\fICSV\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-T ", " \-\-only\-totals
|
||||||
|
Displays only the totals of all counters of a card device or a queue device
|
||||||
|
(APQN), but not the individual counters. This option is implied with
|
||||||
|
option \fB\-\-output\fP \fITABLE\fP|\fICSV\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-a ", " \-\-no\-apqn
|
||||||
|
Displays only the counters of the card device, but omits the counters of the
|
||||||
|
queue device (APQN). If the system does not support obtaining cryptographic
|
||||||
|
performance measurement data on the queue devices, this option is implied.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-M ", " \-\-map\-type\~\fIMAPPING\fP
|
||||||
|
Maps unknown cryptographic device types and modes to known types and modes.
|
||||||
|
This option should only be used when new, so far unknown cryptographic devices
|
||||||
|
are found. You can then map them to known devices and modes, provided that the
|
||||||
|
new cryptographic devices report the same counters as the known cryptographic
|
||||||
|
device to which it is mapped.
|
||||||
|
The mapping specification consists of a comma-separated list of
|
||||||
|
\fIFROM\-TYPE\fP:\fIFROM\-MODE\fP=\fITO\-TYPE\fP:\fITO\-MODE\fP specifications.
|
||||||
|
The type and mode values must be specified in decimal notation.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-A ", " \-\-all
|
||||||
|
Displays all cards devices and queue devices (APQNs), not only those that are
|
||||||
|
available to the Linux instance. Using this option additional cryptographic
|
||||||
|
devices that are available in the CEC, but not available to the Linux system
|
||||||
|
are also monitored.
|
||||||
|
This option cannot be specified together with option \fB\-\-only-online\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-O ", " \-\-only\-online
|
||||||
|
Displays only online cards devices and queue devices (APQNs). This option
|
||||||
|
cannot be specified together with option \fB\-\-all\fP.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.BR \-V ", " \-\-verbose
|
||||||
|
Displays additional information messages during processing.
|
||||||
|
.TP
|
||||||
|
.BR \-h ", " \-\-help
|
||||||
|
Displays help text and exits.
|
||||||
|
.TP
|
||||||
|
.BR \-v ", " \-\-version
|
||||||
|
Displays version information and exits.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH COUNTERS
|
||||||
|
.
|
||||||
|
.PP
|
||||||
|
.B IBM Crypto Express adapter in accelerator mode:
|
||||||
|
.RS 4
|
||||||
|
.TP
|
||||||
|
.B All
|
||||||
|
All operations on the adapter
|
||||||
|
.TP
|
||||||
|
.B RSA Key-gen
|
||||||
|
RSA-key-generation operations (also included in \fBAll\fP).
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.B IBM Crypto Express adapter in CCA co-processor mode:
|
||||||
|
.RS 4
|
||||||
|
.TP
|
||||||
|
.B RSA 1024 ME
|
||||||
|
1024-bit ME-format RSA operations.
|
||||||
|
.TP
|
||||||
|
.B RSA 2048 ME
|
||||||
|
2048-bit ME-format RSA operations.
|
||||||
|
.TP
|
||||||
|
.B RSA 1024 CRT
|
||||||
|
1024-bit CRT-format RSA operations.
|
||||||
|
.TP
|
||||||
|
.B RSA 2048 CRT
|
||||||
|
2048-bit CRT-format RSA operations.
|
||||||
|
.TP
|
||||||
|
.B RSA 4096 ME
|
||||||
|
4096-bit ME-format RSA operations.
|
||||||
|
.TP
|
||||||
|
.B RSA 4096 CTR
|
||||||
|
4096-bit CRT-format RSA operations.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.B IBM Crypto Express adapter in EP11 co-processor mode:
|
||||||
|
.RS 4
|
||||||
|
.TP
|
||||||
|
.B Asym. Slow
|
||||||
|
Slow asymmetric-key functions.
|
||||||
|
.TP
|
||||||
|
.B Asym. Fast
|
||||||
|
Fast asymmetric-key functions.
|
||||||
|
.TP
|
||||||
|
.B Symm. Partial
|
||||||
|
Symmetric-key functions that return partial or incremental results.
|
||||||
|
.TP
|
||||||
|
.B Symm. Complete
|
||||||
|
Symmetric-key functions that return a complete or final result.
|
||||||
|
.TP
|
||||||
|
.B Asym. Key-gen
|
||||||
|
asymmetric-key generation function.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.TP
|
||||||
|
.B zcryptstats 02
|
||||||
|
Display statistics for all cryptographic devices with card ID \fB02\fP.
|
||||||
|
.TP
|
||||||
|
.B zcryptstats 02.0005 --interval 5
|
||||||
|
Display statistics for cryptographic devices with card ID \fB02\fP and domain
|
||||||
|
ID \fB0005\fP in a 5 second interval.
|
||||||
|
.TP
|
||||||
|
.B zcryptstats .0005 --count 10
|
||||||
|
Display statistics for cryptographic devices with domain ID \fB0005\fP with the
|
||||||
|
default interval time of 10 seconds, for 10 intervals.
|
||||||
|
.TP
|
||||||
|
.B zcryptstats 02 --output JSON
|
||||||
|
Display statistics for all cryptographic devices with card ID \fB02\fP in
|
||||||
|
\fBJSON\fP output format.
|
||||||
|
.TP
|
||||||
|
|
||||||
2418
zconf/zcrypt/zcryptstats.c
Normal file
2418
zconf/zcrypt/zcryptstats.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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 *);
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ static bool is_exportable(struct setting *s, config_t config)
|
|||||||
/* Skip values that cannot be determined. */
|
/* Skip values that cannot be determined. */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!attrib_check_value(a, s->value)) {
|
||||||
|
/* Skip values that are not acceptable input values. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!attrib_match_default(s->attrib, s->value)) {
|
if (!attrib_match_default(s->attrib, s->value)) {
|
||||||
/* All non-default values should be exported. */
|
/* All non-default values should be exported. */
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user