forked from pool/s390-tools
Accepting request 750974 from home:markkp:branches:Base:System
- Upgraded to version 2.11.0 (jsc#7831) - Updated the cputype script and read_values program to recognize machine types up through the new z15. - Added the following patches (bsc#1151859) * s390-tools-sles15sp2-01-zkey-Separate-and-rework-CCA-host-library-loading.patch * s390-tools-sles15sp2-02-zkey-Move-utility-functions-into-separate-source-fil.patch * s390-tools-sles15sp2-03-zkey-Add-utility-function-to-get-the-serial-number-o.patch * s390-tools-sles15sp2-04-zkey-Add-utility-function-to-get-the-mkvp-of-a-crypt.patch * s390-tools-sles15sp2-05-zkey-add-function-to-iterate-over-all-available-CCA-.patch * s390-tools-sles15sp2-06-zkey-Add-function-to-print-the-MKVPs-of-APQNs.patch * s390-tools-sles15sp2-07-zkey-Add-function-to-cross-check-APQNs-for-valid-mas.patch * s390-tools-sles15sp2-08-zkey-Add-function-to-obtain-the-mkvp-of-a-secure-key.patch * s390-tools-sles15sp2-09-zkey-Display-MKVP-when-validating-a-secure-key.patch * s390-tools-sles15sp2-10-zkey-Cross-check-APQNs-when-generating-secure-keys.patch * s390-tools-sles15sp2-11-zkey-Cross-check-APQNs-when-validating-secure-keys.patch * s390-tools-sles15sp2-12-zkey-Cross-check-APQNs-when-importing-secure-keys.patch * s390-tools-sles15sp2-13-zkey-Cross-check-APQNs-when-changing-APQN-associatio.patch * s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch * s390-tools-sles15sp2-15-zkey-Add-function-to-select-a-CCA-adapter-by-mkvp.patch * s390-tools-sles15sp2-16-zkey-Select-CCA-adapter-when-re-enciphering.patch * s390-tools-sles15sp2-17-zkey-cryptsetup-Add-to-new-and-from-old-options.patch - Added the following patches (bsc#1151858) * s390-tools-sles15sp2-18-zkey-Display-key-type-with-list-and-validate-command.patch * s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch * s390-tools-sles15sp2-20-zkey-Allow-to-specify-the-key-type-with-the-generate.patch * s390-tools-sles15sp2-21-zkey-Preparations-for-introducing-a-new-key-type.patch * s390-tools-sles15sp2-22-zkey-Introduce-the-CCA-AESCIPHER-key-type.patch * s390-tools-sles15sp2-23-zkey-Add-wrappers-for-the-new-IOCTLs-with-fallback-t.patch * s390-tools-sles15sp2-24-zkey-Add-helper-functions-to-build-lists-of-APQNs.patch * s390-tools-sles15sp2-25-zkey-Add-support-for-generating-AES-CIPHER-keys.patch * s390-tools-sles15sp2-26-zkey-Add-support-for-validating-AES-CIPHER-keys.patch * s390-tools-sles15sp2-27-zkey-Add-support-for-re-enciphering-AES-CIPHER-keys.patch * s390-tools-sles15sp2-28-zkey-Check-crypto-card-level-during-APQN-cross-check.patch * s390-tools-sles15sp2-29-zkey-Add-helper-function-to-query-the-CCA-firmware-v.patch * s390-tools-sles15sp2-30-zkey-Add-helper-function-to-convert-secure-keys-betw.patch * s390-tools-sles15sp2-31-zkey-Add-helper-function-to-restrict-export-of-secur.patch * s390-tools-sles15sp2-32-zkey-Add-helper-function-to-check-an-AES-CIPHER-key.patch * s390-tools-sles15sp2-33-zkey-Add-key-checks-when-importing-a-CCA-AESCIPHER-k.patch * s390-tools-sles15sp2-34-zkey-Add-convert-command-to-convert-keys-from-one-ty.patch * s390-tools-sles15sp2-35-zkey-Allow-zkey-cryptsetup-setkey-to-set-different-k.patch - Added the following patches (bsc#1153757) * s390-tools-sles15sp2-zcrypt-CEX7S-exploitation-support.patch * s390-tools-sles15sp2-zcryptstats-Add-support-for-CEX7.patch - Added s390-tools-sles15sp2-Close-file-descriptor-when-checking-for-read-only.patch - Forward-ported the following patches to work with the restructuring IBM did for this version * dasdfmt-retry-BIODASDINFO-if-device-is-busy.patch * s390-tools-sles12-fdasd-skip-partition-check-and-BLKRRPART-ioctl.patch * s390-tools-sles15-Allow-multiple-device-arguments.patch * s390-tools-sles15-Format-devices-in-parallel.patch * s390-tools-sles15-Implement-f-for-backwards-compability.patch * s390-tools-sles15-Implement-Y-yast_mode.patch - Removed the following obsolete patches: * s390-tools-sles15-1-lstape-fix-output-with-SCSI-lin_tape-and-multiple-pa.patch * s390-tools-sles15-2-lstape-fix-to-prefer-sysfs-to-find-lin_tape-device-n.patch * s390-tools-sles15-3-lstape-fix-output-without-SCSI-generic-sg.patch * s390-tools-sles15-4-lsluns-fix-to-prevent-error-messages-if-there-are-no.patch * s390-tools-sles15-5-lstape-fix-to-prevent-error-messages-if-there-are-no.patch * s390-tools-sles15-6-lstape-fix-description-of-type-and-devbusid-filter-f.patch * s390-tools-sles15-7-lstape-fix-SCSI-output-description-in-man-page.patch * s390-tools-sles15-8-lstape-fix-SCSI-HBA-CCW-device-bus-ID-e.g.-for-virti.patch * s390-tools-sles15-cpi-add-unit-install-section.patch * s390-tools-sles15-cpuplugd-Improve-systemctl-start-error-handling.patch * s390-tools-sles15-dbginfo-add-data-for-ps-cpprot.patch * s390-tools-sles15-Drop-device_id-parameter.patch * s390-tools-sles15-Fix-truncation-warning.patch * s390-tools-sles15-Fixup-dasdfmt_get_volser.patch * s390-tools-sles15-Fixup-device-name-handling.patch * s390-tools-sles15-hmcdrvfs-fix-parsing-of-link-count.patch * s390-tools-sles15-iucvterm-include-ctype-for-toupper.patch * s390-tools-sles15-lsluns-clarify-discovery-use-case-relation-to-NPIV-a.patch * s390-tools-sles15-lsluns-complement-alternative-tools-with-lszdev.patch * s390-tools-sles15-lsluns-document-restriction-to-zfcp-only-systems.patch * s390-tools-sles15-lsluns-do-not-print-confusing-messages-when-a-filter.patch * s390-tools-sles15-lsluns-do-not-scan-all-if-filters-match-nothing.patch * s390-tools-sles15-lsluns-enhance-usage-statement-and-man-page.patch * s390-tools-sles15-lsluns-fix-flawed-formatting-of-man-page.patch * s390-tools-sles15-lsluns-point-out-IBM-Storwize-configuration-requirem.patch * s390-tools-sles15-mon_procd-fix-parsing-of-proc-pid-stat.patch * s390-tools-sles15-mon_tools-Improve-systemctl-start-error-handling.patch * s390-tools-sles15sp1-0001-zkey-Add-properties-file-handling-routines.patch * s390-tools-sles15sp1-0002-zkey-Add-build-dependency-to-OpenSSL-libcrypto.patch * s390-tools-sles15sp1-0003-zkey-Add-helper-functions-for-comma-separated-string.patch * s390-tools-sles15sp1-0004-zkey-Externalize-secure-key-back-end-functions.patch * s390-tools-sles15sp1-0005-zkey-Add-keystore-implementation.patch * s390-tools-sles15sp1-0006-zkey-Add-keystore-related-commands.patch * s390-tools-sles15sp1-0007-zkey-Create-key-repository-and-group-during-make-ins.patch * s390-tools-sles15sp1-0008-zkey-Man-page-updates.patch * s390-tools-sles15sp1-0009-zkey-let-packaging-create-the-zkeyadm-group-and-perm.patch * s390-tools-sles15sp1-0010-zkey-Update-README-to-add-info-about-packaging-requi.patch * s390-tools-sles15sp1-0011-zkey-Typo-in-message.patch * s390-tools-sles15sp1-0012-zkey-Fix-memory-leak.patch * s390-tools-sles15sp1-0013-zkey-Fix-APQN-validation-routine.patch * s390-tools-sles15sp1-0014-zkey-Fix-generate-and-import-leaving-key-in-an-incon.patch * s390-tools-sles15sp1-0015-zkey-Add-zkey-cryptsetup-tool.patch * s390-tools-sles15sp1-0016-zkey-Add-man-page-for-zkey-cryptsetup.patch * s390-tools-sles15sp1-0017-zkey-Add-build-dependency-for-libcryptsetup-and-json.patch * s390-tools-sles15sp1-0018-zkey-Add-key-verification-pattern-property.patch * s390-tools-sles15sp1-0019-zkey-Add-volume-type-property-to-support-LUKS2-volum.patch * s390-tools-sles15sp1-01-chzcrypt-Corrections-at-the-chzcrypt-man-page.patch * s390-tools-sles15sp1-01-cpumf-Add-extended-counter-defintion-files-for-IBM-z.patch * s390-tools-sles15sp1-01-lszcrypt-CEX6S-exploitation.patch * s390-tools-sles15sp1-01-util_path-add-function-to-check-if-a-path-exists.patch * s390-tools-sles15sp1-01-zcryptctl-new-tool-zcryptctl-for-multiple-zcrypt-node.patch * s390-tools-sles15sp1-01-zdev-use-libutil-provided-path-functions.patch * s390-tools-sles15sp1-01-zkey-Include-sbin-into-PATH-when-executing-commands.patch * s390-tools-sles15sp1-02-cpumf-z14-split-counter-sets-according-to-CFVN-CSVN-.patch * s390-tools-sles15sp1-02-lszcrypt-fix-date-and-wrong-indentation.patch * s390-tools-sles15sp1-02-lszcrypt-support-for-alternate-zcrypt-device-drivers.patch * s390-tools-sles15sp1-02-util_path-Add-description-for-util_path_exists.patch * s390-tools-sles15sp1-02-zdev-Prepare-for-firmware-configuration-file-support.patch * s390-tools-sles15sp1-03-cpumf-cpumf_helper-read-split-counter-sets-part-2-2.patch * s390-tools-sles15sp1-03-util_path-Make-true-false-handling-consistent-with-o.patch * s390-tools-sles15sp1-03-zdev-Add-support-for-reading-firmware-configuration-.patch * s390-tools-sles15sp1-04-cpumf-correct-z14-counter-number.patch * s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch * s390-tools-sles15sp1-04-zpcictl-Introduce-new-tool-zpcictl.patch * s390-tools-sles15sp1-05-cpumf-add-missing-Description-tag-for-z13-z14-ctr-12.patch * s390-tools-sles15sp1-05-zdev-Write-zfcp-lun-udev-rules-to-separate-files.patch * s390-tools-sles15sp1-05-zpcictl-include-sys-sysmacros.h-to-avoid-minor-major.patch * s390-tools-sles15sp1-06-cpumf-correct-counter-name-for-z13-and-z14.patch * s390-tools-sles15sp1-06-zdev-Add-support-for-handling-auto-configuration-dat.patch * s390-tools-sles15sp1-06-zpcictl-Rephrase-man-page-entries-and-tool-output.patch * s390-tools-sles15sp1-07-cpumf-Add-IBM-z14-ZR1-to-the-CPU-Measurement-Facilit.patch * s390-tools-sles15sp1-07-zdev-Integrate-firmware-auto-configuration-with-drac.patch * s390-tools-sles15sp1-07-zpcictl-Use-fopen-instead-of-open-for-writes.patch * s390-tools-sles15sp1-08-zdev-Integrate-firmware-auto-configuration-with-init.patch * s390-tools-sles15sp1-08-zpcictl-Read-device-link-to-obtain-device-address.patch * s390-tools-sles15sp1-09-zdev-Implement-internal-device-attributes.patch * s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch * s390-tools-sles15sp1-10-zdev-Implement-support-for-early-device-configuratio.patch * s390-tools-sles15sp1-10-zpcictl-Change-wording-of-man-page-and-help-output.patch * s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch * s390-tools-sles15sp1-dbginfo-gather-nvme-related-data.patch * s390-tools-sles15sp1-qethqoat-add-OSA-Express7S-support.patch * s390-tools-sles15sp1-zcrypt-refine-lszcrypt-man-page.patch * s390-tools-sles15sp1-zdev-Also-include-the-ctc-driver-in-the-initrd.patch * s390-tools-sles15sp1-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch * s390-tools-sles15sp1-zkey-Enhance-error-message-about-missing-CCA-library.patch * s390-tools-sles15-zdev-Enable-running-chzdev-from-unknown-root-devices.patch * s390-tools-sles15-zdev-Fix-zdev-dracut-module-aborting-on-unknown-root.patch * s390-tools-sles15-zdev-Use-correct-path-to-vmcp-binary.patch * s390-tools-sles15-ziomon-re-add-missing-line.patch * s390-tools-sles15-zipl-remove-invalid-dasdview-command-line-option.patch - Added s390-tools-sles15sp1-ziomon-fix-utilization-data-recording-with-multi-dig.patch ziomon: fix utilization recording with multi-digit scsi hosts (bsc#1141876) OBS-URL: https://build.opensuse.org/request/show/750974 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=83
This commit is contained in:
parent
0414295c92
commit
50eb270fbf
4
cputype
4
cputype
@ -2,7 +2,7 @@
|
||||
#
|
||||
# cputype
|
||||
#
|
||||
# Copyright (c) 2014-2017 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||
# Copyright (c) 2014-2017, 2019 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# Based on the IBM machine model, returns a (hopefully) human understandable
|
||||
# string that identifies the processor.
|
||||
@ -59,6 +59,8 @@ case "${machine}" in
|
||||
2964) echo "${machine} = z13 IBM z13" ;;
|
||||
2965) echo "${machine} = z13s IBM z13s (single frame)" ;;
|
||||
3906) echo "${machine} = z14 IBM z14" ;;
|
||||
3907) echo "${machine} = z14 ZR1 IBM z14 ZR1" ;;
|
||||
8561) echo "${machine} = z15 IBM z15" ;;
|
||||
*) echo "An unknown machine type was reported: ${machine}" >&2
|
||||
echo "Please file a bug report with this output:" >&2
|
||||
/bin/cat /proc/cpuinfo >&2
|
||||
|
@ -23,16 +23,16 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index e1877ac..f03cbad 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -588,7 +616,7 @@
|
||||
@@ -580,7 +580,7 @@
|
||||
*/
|
||||
static void check_disk(dasdfmt_info_t *info, char *devname)
|
||||
{
|
||||
- int ro, errno_save;
|
||||
+ int ro, errno_save, i = 0;
|
||||
- int err;
|
||||
+ int err, index = 0 ;
|
||||
bool ro;
|
||||
|
||||
if (ioctl(filedes, BLKROGET, &ro) != 0) {
|
||||
errno_save = errno;
|
||||
@@ -602,9 +630,27 @@
|
||||
err = dasd_is_ro(devname, &ro);
|
||||
@@ -593,9 +593,27 @@
|
||||
if (ro)
|
||||
ERRMSG_EXIT(EXIT_FAILURE, "Disk is read only!\n");
|
||||
|
||||
@ -47,9 +47,9 @@ index e1877ac..f03cbad 100644
|
||||
+ * And confusing the hell out ouf anyone else.
|
||||
+ * Bah.
|
||||
+ */
|
||||
+ for ( i = 0 ; i < 6 ; i++ ) {
|
||||
+ for ( index = 0 ; index < 6 ; index++ ) {
|
||||
+ if (info->dasd_info.open_count > 1) {
|
||||
+ get_device_info(info);
|
||||
+ dasd_get_info(dev_filename, &info->dasd_info);
|
||||
+ sleep(1);
|
||||
+ }
|
||||
+ else break;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* Copyright (C) 2014-2015, SUSE LLC */
|
||||
/* Copyright (C) 2014-2015, 2019 SUSE LLC */
|
||||
/* */
|
||||
/* All rights reserved.
|
||||
|
||||
@ -63,6 +63,10 @@ struct machinetype {
|
||||
{ "2827", "2827 = z12-EC IBM zEnterprise EC12" },
|
||||
{ "2828", "2828 = z12-BC IBM zEnterprise BC12" },
|
||||
{ "2964", "2964 = z13 IBM z13" },
|
||||
{ "2965", "2965 = z13s IBM z13s (single frame)" },
|
||||
{ "3906", "3906 = z14 IBM z14" },
|
||||
{ "3907", "3907 = z14 ZR1 IBM z14 ZR1" },
|
||||
{ "8561", "8561 = z15 IBM z15" },
|
||||
};
|
||||
|
||||
int debug = 0;
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b5ce3fa0de074dfe7d16c74771fcb5092c4a6f575168bf4e13f88275a6370122
|
||||
size 1046910
|
3
s390-tools-2.11.0.tar.gz
Normal file
3
s390-tools-2.11.0.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fd1883e12f9da16be6b081508108abd3ce8cd80168efe4cd339ba33837f8f4aa
|
||||
size 1164539
|
@ -19,19 +19,17 @@ diff --git a/fdasd/fdasd.c b/fdasd/fdasd.c
|
||||
index 4503d3e..f04dc3d 100644
|
||||
--- a/fdasd/fdasd.c
|
||||
+++ b/fdasd/fdasd.c
|
||||
@@ -1247,9 +1247,12 @@
|
||||
}
|
||||
@@ -1229,10 +1229,12 @@
|
||||
*/
|
||||
static void fdasd_reread_partition_table(fdasd_anchor_t *anc)
|
||||
{
|
||||
+ int rc = 0 ;
|
||||
if (!anc->silent)
|
||||
printf("rereading partition table...\n");
|
||||
|
||||
if (ioctl(fd, BLKRRPART, NULL) != 0) {
|
||||
- close(fd);
|
||||
- fdasd_error(anc, unable_to_ioctl, "Error while rereading "
|
||||
- "partition table.\nPlease reboot!");
|
||||
+ if (errno == EINVAL && !anc->force_virtual) {
|
||||
+ close(fd);
|
||||
+ fdasd_error(anc, unable_to_ioctl,
|
||||
+ "Error while rereading "
|
||||
+ "partition table.\nPlease reboot!");
|
||||
+ }
|
||||
- if (dasd_reread_partition_table(options.device, 1) != 0) {
|
||||
+ rc = dasd_reread_partition_table(options.device, 1);
|
||||
+ if (rc == EINVAL && !anc->force_virtual) {
|
||||
fdasd_error(anc, unable_to_ioctl, "Error while rereading "
|
||||
"partition table.\nPlease reboot!");
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
@ -1,181 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape | 11 ++++-------
|
||||
zconf/lstape.8 | 7 ++-----
|
||||
2 files changed, 6 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/zconf/lstape
|
||||
+++ b/zconf/lstape
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# lstape - Tool to show information about tape devices
|
||||
#
|
||||
-# Copyright IBM Corp. 2003, 2017
|
||||
+# Copyright IBM Corp. 2003, 2018
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -55,7 +55,7 @@ function PrintVersion()
|
||||
{
|
||||
cat <<-EOD
|
||||
$CMD: version %S390_TOOLS_VERSION%
|
||||
- Copyright IBM Corp. 2003, 2017
|
||||
+ Copyright IBM Corp. 2003, 2018
|
||||
EOD
|
||||
}
|
||||
|
||||
@@ -292,16 +292,13 @@ function SysfsCreateListSCSI()
|
||||
TAPE_DEV=$CHG_IDX
|
||||
fi
|
||||
elif [ -r /proc/scsi/$DEV_NAME ]; then
|
||||
- if [ "$TAPE_SERIAL" != "NO/INQ" ]; then
|
||||
IBM_IDX=$(
|
||||
- awk '$3 == "'$TAPE_SERIAL'"{
|
||||
- print $1
|
||||
- }' /proc/scsi/$DEV_NAME
|
||||
+ grep -wF "$SCSI_ID" /proc/scsi/$DEV_NAME |
|
||||
+ cut -d ' ' -f 1
|
||||
)
|
||||
if [ "$IBM_IDX" != "" ]; then
|
||||
TAPE_DEV=$DEV_NAME$IBM_IDX
|
||||
fi
|
||||
- fi
|
||||
fi
|
||||
|
||||
printf "$SCSIFORMAT" \
|
||||
--- a/zconf/lstape.8
|
||||
+++ b/zconf/lstape.8
|
||||
@@ -1,8 +1,8 @@
|
||||
-.\" Copyright 2017 IBM Corp.
|
||||
+.\" Copyright 2017, 2018 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
-.TH LSTAPE 8 "Jul 2007" "s390-tools"
|
||||
+.TH LSTAPE 8 "Jun 2018" "s390-tools"
|
||||
|
||||
.SH NAME
|
||||
lstape \- list tape devices.
|
||||
@@ -34,9 +34,6 @@ lstape command tries to find out which o
|
||||
and changer driver the device names start with "st" or "sch", while for the
|
||||
IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
||||
the correct driver could not be obtained.
|
||||
-This happens for example if there is no sg_inq command installed which is
|
||||
-required to read the drive's serial number which in turn is used to find out
|
||||
-the device number of the IBM tape driver.
|
||||
|
||||
The serial number of a SCSI tape can be displayed with the --verbose option. If
|
||||
there is no sg_inq command available "NO/INQ" is shown as the tape's serial.
|
@ -1,144 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
--- a/zconf/lstape
|
||||
+++ b/zconf/lstape
|
||||
@@ -291,6 +291,23 @@ function SysfsCreateListSCSI()
|
||||
if [ "$CHG_IDX" != "" ]; then
|
||||
TAPE_DEV=$CHG_IDX
|
||||
fi
|
||||
+ elif [ "$(echo "$SCSI_LIST"|grep lin_tape)" != "" ]; then
|
||||
+ # bash glob sorts so IBMtape0 comes before IBMtape0n
|
||||
+ local IBM_PATH=$(
|
||||
+ ls -1d $SCSI_DEV/lin_tape/$DEV_NAME[0-9]* |
|
||||
+ head -n 1)
|
||||
+ if [ -d "$IBM_PATH" ]; then
|
||||
+ IBM_IDX=${IBM_PATH##*/}
|
||||
+ else
|
||||
+ # deprecated sysfs layout
|
||||
+ IBM_IDX=$(
|
||||
+ echo "$SCSI_LIST" |
|
||||
+ awk -F: '/lin_tape\:'"$DEV_NAME"'[0-9]+$/{print $NF}'
|
||||
+ )
|
||||
+ fi
|
||||
+ if [ "$IBM_IDX" != "" ]; then
|
||||
+ TAPE_DEV=$IBM_IDX
|
||||
+ fi
|
||||
elif [ -r /proc/scsi/$DEV_NAME ]; then
|
||||
IBM_IDX=$(
|
||||
grep -wF "$SCSI_ID" /proc/scsi/$DEV_NAME |
|
@ -1,167 +0,0 @@
|
||||
Subject: [PATCH] [BZ 170633] lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape | 12 ++++++++++--
|
||||
zconf/lstape.8 | 8 +++++++-
|
||||
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/zconf/lstape
|
||||
+++ b/zconf/lstape
|
||||
@@ -48,6 +48,9 @@ function PrintUsage() {
|
||||
: -v|--version
|
||||
: Display the version of the tools package and
|
||||
: the lstape command.
|
||||
+ :
|
||||
+ :$(basename $0) without the --ccw-only option causes extra SAN traffic
|
||||
+ :for each SCSI tape or changer device by invoking the sg_inq command.
|
||||
EOD
|
||||
}
|
||||
|
||||
@@ -249,11 +252,16 @@ function SysfsCreateListSCSI()
|
||||
if [ -h $SG_DEV ]; then
|
||||
# deprecated sysfs layout
|
||||
SG_DEV=$(echo $SG_DEV | awk -F: '{print $NF}')
|
||||
- else
|
||||
+ elif [ -d $SCSI_DEV/scsi_generic ]; then
|
||||
SG_DEV=$(basename $SG_DEV/*)
|
||||
+ else
|
||||
+ SG_DEV=""
|
||||
fi
|
||||
|
||||
- if [ "$SG_INQ" != "" ]; then
|
||||
+ if [ -z "$SG_DEV" ]; then
|
||||
+ SG_DEV="N/A"
|
||||
+ TAPE_SERIAL="NO/SG"
|
||||
+ elif [ "$SG_INQ" != "" ]; then
|
||||
TAPE_SERIAL=$(
|
||||
sg_inq /dev/$SG_DEV |
|
||||
awk '/serial/{print $NF}'
|
||||
--- a/zconf/lstape.8
|
||||
+++ b/zconf/lstape.8
|
||||
@@ -36,7 +36,13 @@ IBM tape driver this would be "IBMtape"
|
||||
the correct driver could not be obtained.
|
||||
|
||||
The serial number of a SCSI tape can be displayed with the --verbose option. If
|
||||
-there is no sg_inq command available "NO/INQ" is shown as the tape's serial.
|
||||
+there is no sg_inq command available "NO/INQ" is shown as the serial number
|
||||
+of the tape.
|
||||
+If no SCSI generic (sg) kernel support is available, "NO/SG" is shown
|
||||
+as the serial number of the tape and "N/A" for the "Generic" column.
|
||||
+
|
||||
+The lstape command without the --ccw-only option causes extra SAN traffic
|
||||
+for each SCSI tape or changer device by invoking the sg_inq command.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP 8
|
@ -1,177 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 14 +++++++++-----
|
||||
zconf/lsluns.8 | 5 ++---
|
||||
2 files changed, 11 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
|
||||
#
|
||||
-# Copyright IBM Corp. 2008, 2017
|
||||
+# Copyright IBM Corp. 2008, 2018
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -152,6 +152,11 @@ sub get_lun_hash
|
||||
my %lun_hash;
|
||||
|
||||
foreach my $device (</$sg_dir/sg*>) {
|
||||
+ # skip non-zfcp SCSI devices and avoid file access error messages
|
||||
+ next unless -r "$device/device/fcp_lun";
|
||||
+ next unless -r "$device/device/wwpn";
|
||||
+ next unless -r "$device/device/hba_id";
|
||||
+
|
||||
my $l = `cat $device/device/fcp_lun`;
|
||||
my $p = `cat $device/device/wwpn`;
|
||||
my $a = `cat $device/device/hba_id`;
|
||||
@@ -170,9 +175,8 @@ sub get_lun_hash
|
||||
sub lsluns_usage {
|
||||
print <<EOD;
|
||||
Usage:
|
||||
-This tool is designed for environments where all SCSI devices are attached
|
||||
-through the zfcp device driver. Expect error messages in mixed environments
|
||||
-such as with iSCSI.
|
||||
+This tool is designed for environments with SCSI devices attached
|
||||
+through the zfcp device driver.
|
||||
|
||||
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
@@ -220,7 +224,7 @@ EOD
|
||||
|
||||
sub lsluns_version {
|
||||
print "$PROGRAM_NAME: version %S390_TOOLS_VERSION%\n";
|
||||
- print "Copyright IBM Corp. 2008, 2017\n";
|
||||
+ print "Copyright IBM Corp. 2008, 2018\n";
|
||||
}
|
||||
|
||||
sub lsluns_invalid_usage {
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -28,9 +28,8 @@ zfcp-attached LUNs
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
-This tool is designed for environments where all SCSI devices are attached
|
||||
-through the zfcp device driver. Expect error messages in mixed environments
|
||||
-such as with iSCSI.
|
||||
+This tool is designed for environments with SCSI devices attached
|
||||
+through the zfcp device driver.
|
||||
|
||||
.B lsluns
|
||||
lists all logical unit numbers (LUNs) discovered in the
|
@ -1,136 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/zconf/lstape
|
||||
+++ b/zconf/lstape
|
||||
@@ -335,9 +335,13 @@ function SysfsCreateListSCSI()
|
||||
$STATE
|
||||
|
||||
if $VERBOSE; then
|
||||
+ HBA_ID="N/A"
|
||||
+ [ -r $SCSI_DEV/hba_id ] && HBA_ID=$(cat $SCSI_DEV/hba_id)
|
||||
+ WWPN="N/A"
|
||||
+ [ -r $SCSI_DEV/wwpn ] && WWPN=$(cat $SCSI_DEV/wwpn)
|
||||
printf "$SCSIVFORMAT" \
|
||||
- $(cat $SCSI_DEV/hba_id) \
|
||||
- $(cat $SCSI_DEV/wwpn) \
|
||||
+ "$HBA_ID" \
|
||||
+ "$WWPN" \
|
||||
$TAPE_SERIAL
|
||||
fi
|
||||
done
|
@ -1,147 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape.8 | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/zconf/lstape.8
|
||||
+++ b/zconf/lstape.8
|
||||
@@ -20,6 +20,8 @@ lstape \- list tape devices.
|
||||
.br
|
||||
.RB [ -t
|
||||
.IR <device-type> [, <device-type> ] "" ...]
|
||||
+.br
|
||||
+.RI [ <device-bus-ID> ...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
The lstape command lists all available tape devices on the current host. For
|
||||
@@ -78,12 +80,14 @@ on the output of SCSI devices.
|
||||
|
||||
.TP
|
||||
.BR -t | --type " \fI<device-type>\fR"
|
||||
-Limit output to given device types (currently only applies to channel attached
|
||||
+Limit output to given device types, for example 3490
|
||||
+(currently only applies to channel-attached
|
||||
tape devices).
|
||||
|
||||
.TP
|
||||
-\fB<device-type>\fR =
|
||||
-Device type of devices that should be displayed (e.g. 3490).
|
||||
+.I <device-bus-ID>
|
||||
+Limits the output to information about the specified tape device or
|
||||
+devices only. For CCW-attached devices only.
|
||||
|
||||
.SH EXAMPLES
|
||||
\fBlstape\fR
|
@ -1,206 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape.8 | 68 +++++++++++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 54 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/zconf/lstape.8
|
||||
+++ b/zconf/lstape.8
|
||||
@@ -29,20 +29,6 @@ channel attached tape devices this outpu
|
||||
/proc/tapedevices (which is obsolete) but also includes offline devices. By
|
||||
default all tape devices are displayed.
|
||||
|
||||
-Since SCSI tape devices are accessed differently to channel attached tape
|
||||
-devices they are only visible if they are known to the SCSI layer. There
|
||||
-are at least two possible drivers that can claim a SCSI tape device and the
|
||||
-lstape command tries to find out which one this is. For the generic tape
|
||||
-and changer driver the device names start with "st" or "sch", while for the
|
||||
-IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
||||
-the correct driver could not be obtained.
|
||||
-
|
||||
-The serial number of a SCSI tape can be displayed with the --verbose option. If
|
||||
-there is no sg_inq command available "NO/INQ" is shown as the serial number
|
||||
-of the tape.
|
||||
-If no SCSI generic (sg) kernel support is available, "NO/SG" is shown
|
||||
-as the serial number of the tape and "N/A" for the "Generic" column.
|
||||
-
|
||||
The lstape command without the --ccw-only option causes extra SAN traffic
|
||||
for each SCSI tape or changer device by invoking the sg_inq command.
|
||||
|
||||
@@ -89,6 +75,55 @@ tape devices).
|
||||
Limits the output to information about the specified tape device or
|
||||
devices only. For CCW-attached devices only.
|
||||
|
||||
+.SH OUTPUT FIELDS FOR SCSI TAPE/CHANGER DEVICES
|
||||
+.TP
|
||||
+.B Generic
|
||||
+SCSI generic device file for the tape drive, for example /dev/sg0.
|
||||
+"N/A" if the SCSI generic (sg) kernel functionality is not available.
|
||||
+.TP
|
||||
+.B Device
|
||||
+Main character device node file for accessing the tape drive or medium changer.
|
||||
+SCSI tape devices are only visible if they are known to the SCSI layer. There
|
||||
+are at least two possible drivers that can claim a SCSI tape device. The
|
||||
+lstape command tries to determine the device driver. For the generic tape
|
||||
+and changer driver the device names start with "st" or "sch", while for the
|
||||
+IBM tape driver this would be "IBMtape" or "IBMchanger". If "N/A" is shown,
|
||||
+the device driver could not be determined.
|
||||
+.TP
|
||||
+.B Target
|
||||
+Linux SCSI device name in H:C:T:L format.
|
||||
+.TP
|
||||
+.B Vendor
|
||||
+The vendor field from the SCSI device.
|
||||
+.TP
|
||||
+.B Model
|
||||
+The model field from the SCSI device.
|
||||
+.TP
|
||||
+.B Type
|
||||
+"tapedrv" for a tape drive or "changer" for a medium changer.
|
||||
+.TP
|
||||
+.B State
|
||||
+The state of the SCSI device object in the kernel.
|
||||
+Any state other than "running" can indicate problems.
|
||||
+
|
||||
+.PP
|
||||
+
|
||||
+For SCSI devices, the --verbose option additionally displays:
|
||||
+.TP
|
||||
+.B HBA
|
||||
+The device bus-ID of the FCP device
|
||||
+through which the tape drive is attached.
|
||||
+"N/A" if device is not attached through zfcp.
|
||||
+.TP
|
||||
+.B WWPN
|
||||
+The WWPN (worldwide port name) of the tape drive in the SAN.
|
||||
+"N/A" if device is not attached through zfcp.
|
||||
+.TP
|
||||
+.B Serial
|
||||
+The serial number.
|
||||
+"NO/INQ" if there is no sg_inq command available.
|
||||
+"NO/SG" if no SCSI generic (sg) kernel support is available.
|
||||
+
|
||||
.SH EXAMPLES
|
||||
\fBlstape\fR
|
||||
.RS
|
||||
@@ -99,3 +134,8 @@ List all tape devices that are available
|
||||
.RS
|
||||
Show all 3490 CCW devices that are online.
|
||||
.RE
|
||||
+
|
||||
+\fBlstape --scsi-only --verbose\fR
|
||||
+.RS
|
||||
+Show all SCSI tape or changer devices with maximum information.
|
||||
+.RE
|
@ -1,173 +0,0 @@
|
||||
Subject: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
From: Steffen Maier <maier@linux.ibm.com>
|
||||
|
||||
Description: lstape, lsluns: handle non-zfcp; lin_tape multiple paths
|
||||
|
||||
Symptom: lstape shows unexpected additional Device suffix numbers in
|
||||
excess output columns for each additional path of the same
|
||||
tape/changer driven by the IBM lin_tape device driver
|
||||
(independent of actual path failover enablement in lin_tape).
|
||||
It also shows a wrong number of found devices in the header
|
||||
(without --scsi-only).
|
||||
|
||||
lstape prints error about "Unexpected extra argument:" and the
|
||||
usage for "sg_inq" along with wrong tabular output.
|
||||
|
||||
lsluns prints ENOENT error text for "cat" on SCSI device sysfs
|
||||
attributes hba_id, wwpn, and fcp_lun.
|
||||
|
||||
lstape with --verbose option prints ENOENT error text for
|
||||
"cat" on SCSI device sysfs attributes hba_id and wwpn.
|
||||
|
||||
lstape man page: Description of --type and <devbusid> filter
|
||||
for channel tapes is incomplete. SCSI output description is
|
||||
incomplete.
|
||||
|
||||
lstape shows "N/A" instead of the HBA device bus-ID with
|
||||
virtio-scsi-ccw.
|
||||
|
||||
Problem: s390-tools-1.8.0 before the first upstream commit b627b8d8e1ab
|
||||
("Initial s390-tools-2.0.0 import") introduced SCSI
|
||||
tape/changer output for lstape. It used the SCSI device serial
|
||||
number as lookup key to find a match in IBM lin_tape device
|
||||
driver proc-fs output for a given SCSI device name. Multiple
|
||||
paths to the same tape/changer have the same serial number.
|
||||
Multiple matches cause excess arguments to printf. Explaining
|
||||
the resulting output, the bash man page says: "The format is
|
||||
reused as necessary to consume all of the arguments." This
|
||||
also causes a wrong number of found devices.
|
||||
|
||||
The default bash settings have nullglob disabled so if
|
||||
$SCSI_DEV/scsi_generic* aka
|
||||
/sys/bus/scsi/devices/*:*:*:*/scsi_generic* does not match
|
||||
anything, it leaves the glob pattern unmodified and
|
||||
SG_DEV=$(basename $SG_DEV/*) results in the literal "*". If
|
||||
$SG_INQ exists, it invoked sg_inq with more than the one
|
||||
allowed positional argument for a SCSI generic device node
|
||||
"sg_inq /dev/*". Causing error messages and the usage of
|
||||
sg_inq to land in $TAPE_SERIAL.
|
||||
|
||||
lsluns iterates SCSI generic devices and unconditionally
|
||||
reads zfcp-specific SCSI device sysfs attributes hba_id, wwpn,
|
||||
and fcp_lun.
|
||||
|
||||
lstape --verbose unconditionally reads zfcp-specific SCSI
|
||||
device sysfs attributes hba_id and wwpn.
|
||||
|
||||
<devbusid> filter missing from synopsis. <device-type> example
|
||||
at wrong place with <devbusid> filter. <devbusid> filter
|
||||
option description is a duplicate of <device-type> filter
|
||||
option description. SCSI output description misses fields.
|
||||
|
||||
Lstape only used the zfcp-specific sysfs attribute hba_id.
|
||||
|
||||
Solution: Prefer sysfs to find lin_tape device name for SCSI device.
|
||||
Fallback: The lin_tape proc-fs output format has changed over
|
||||
the years. The HBA device driver string can contain whitespace
|
||||
(e.g. "Virtio SCSI HBA") and breaks the field numbers with
|
||||
tokenized parsing. Grep for the SCSI device name as word (to
|
||||
skip names with same substring, such as 0:0:1:1 also matching
|
||||
0:0:1:10) and cut the first field 'Number' (lin_tape device
|
||||
name suffix). If there is no SCSI column at all [lin_tape
|
||||
before v2.2.0] (and no SCSI LLDD or other column with a name
|
||||
accidentally matching an existing SCSI device name), we get no
|
||||
match and better bail out with the initialized "N/A" for the
|
||||
lstape column "Device".
|
||||
|
||||
To not have to rely on the nullglob setting, explicitly check
|
||||
for the existence of $SCSI_DEV/scsi_generic before evaluating
|
||||
SG_DEV=$(basename $SG_DEV/*). Also handle availability of
|
||||
sg_inq but absence of scsi_generic individually to provide the
|
||||
user with a hint if only sg is missing.
|
||||
|
||||
Simply skip non-zfcp SCSI devices, such as iSCSI or
|
||||
virtio-scsi-ccw, to not erroneously access absent attributes.
|
||||
|
||||
Assume "N/A" for HBA and WWPN of non-zfcp SCSI devices, such
|
||||
as iSCSI or virtio-scsi-ccw, to not erroneously access absent
|
||||
zfcp-specific sysfs attributes.
|
||||
|
||||
Add <devbusid> filter to synopsis. Move <device-type> example
|
||||
to <device-type> option. Replace <devbusid> filter option
|
||||
description. Move existing SCSI output description to a new
|
||||
subsection and add description of missing fields.
|
||||
|
||||
Also search sysfs for an ancestor with subsystem ccw.
|
||||
|
||||
Reproduction: Attach more than one path to the same SCSI tape or changer and
|
||||
load the IBM lin_tape device driver.
|
||||
|
||||
Unload sg kernel module.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
Attach non-zfcp SCSI devices such as iSCSI or virtio-scsi-ccw.
|
||||
|
||||
man lstape
|
||||
|
||||
Attach SCSI tape or changer with virtio-scsi-ccw to a KVM
|
||||
guest and run "lstape --verbose".
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: 170633
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
|
||||
---
|
||||
zconf/lstape | 25 +++++++++++++++++++++++--
|
||||
zconf/lstape.8 | 3 ++-
|
||||
2 files changed, 25 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/zconf/lstape
|
||||
+++ b/zconf/lstape
|
||||
@@ -223,6 +223,24 @@ function SysfsCreateListCCW() {
|
||||
' | sort
|
||||
}
|
||||
|
||||
+# handle SCSI device not necessarily zfcp-attached, e.g. virtio-scsi-ccw
|
||||
+function SCSISearchCCWBusid()
|
||||
+{
|
||||
+ local SCSI_DEV=$1
|
||||
+ local SDEVCAN=$(readlink -e $SCSI_DEV)
|
||||
+ while [ -n "$SDEVCAN" ]; do
|
||||
+ # ascend to parent: strip last path part
|
||||
+ SDEVCAN=${SDEVCAN%/*}
|
||||
+ [ -h $SDEVCAN/subsystem ] || continue
|
||||
+ local SUBSYSTEM=$(readlink -e $SDEVCAN/subsystem)
|
||||
+ if [ "${SUBSYSTEM##*/}" = "ccw" ]; then
|
||||
+ echo ${SDEVCAN##*/}
|
||||
+ return
|
||||
+ fi
|
||||
+ done
|
||||
+ echo "N/A"
|
||||
+}
|
||||
+
|
||||
function SysfsCreateListSCSI()
|
||||
{
|
||||
for SCSI_DEV in $1/bus/scsi/devices/*:*:*:*; do
|
||||
@@ -335,8 +353,11 @@ function SysfsCreateListSCSI()
|
||||
$STATE
|
||||
|
||||
if $VERBOSE; then
|
||||
- HBA_ID="N/A"
|
||||
- [ -r $SCSI_DEV/hba_id ] && HBA_ID=$(cat $SCSI_DEV/hba_id)
|
||||
+ if [ -r $SCSI_DEV/hba_id ]; then
|
||||
+ HBA_ID=$(cat $SCSI_DEV/hba_id)
|
||||
+ else
|
||||
+ HBA_ID=$(SCSISearchCCWBusid $SCSI_DEV)
|
||||
+ fi
|
||||
WWPN="N/A"
|
||||
[ -r $SCSI_DEV/wwpn ] && WWPN=$(cat $SCSI_DEV/wwpn)
|
||||
printf "$SCSIVFORMAT" \
|
||||
--- a/zconf/lstape.8
|
||||
+++ b/zconf/lstape.8
|
||||
@@ -112,8 +112,9 @@ For SCSI devices, the --verbose option a
|
||||
.TP
|
||||
.B HBA
|
||||
The device bus-ID of the FCP device
|
||||
+or of the virtio-scsi-ccw virtual HBA
|
||||
through which the tape drive is attached.
|
||||
-"N/A" if device is not attached through zfcp.
|
||||
+"N/A" if the device does not have a sysfs ancestor with subsystem ccw.
|
||||
.TP
|
||||
.B WWPN
|
||||
The WWPN (worldwide port name) of the tape drive in the SAN.
|
@ -37,7 +37,7 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index b79cff0..607fd1c 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -21,6 +21,7 @@
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "dasdfmt.h"
|
||||
|
||||
@ -45,7 +45,7 @@ index b79cff0..607fd1c 100644
|
||||
#define BUSIDSIZE 8
|
||||
#define SEC_PER_DAY (60 * 60 * 24)
|
||||
#define SEC_PER_HOUR (60 * 60)
|
||||
@@ -456,44 +457,40 @@ static void program_interrupt_signal(int sig)
|
||||
@@ -463,44 +464,40 @@ static void program_interrupt_signal(int sig)
|
||||
/*
|
||||
* check given device name for blanks and some special characters
|
||||
*/
|
||||
@ -107,37 +107,198 @@ index b79cff0..607fd1c 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1457,24 +1454,86 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
@@ -518,7 +515,7 @@ static void get_blocksize(const char *de
|
||||
/*
|
||||
* Check whether a specified blocksize matches the blocksize of the device
|
||||
*/
|
||||
-static void check_blocksize(dasdfmt_info_t *info, unsigned int blksize)
|
||||
+static void check_blocksize(dasdfmt_info_t *info, char *dev_filename, unsigned int blksize)
|
||||
{
|
||||
unsigned int dev_blksize;
|
||||
|
||||
@@ -756,7 +753,7 @@ static void check_hashmarks(dasdfmt_info
|
||||
* This function checks whether a range of tracks is in regular format
|
||||
* with the specified block size.
|
||||
*/
|
||||
-static format_check_t check_track_format(dasdfmt_info_t *info, format_data_t *p)
|
||||
+static format_check_t check_track_format(dasdfmt_info_t *info, char *dev_filename, format_data_t *p)
|
||||
{
|
||||
format_check_t cdata = {
|
||||
.expect = {
|
||||
@@ -812,7 +809,7 @@ static int process_tracks(dasdfmt_info_t
|
||||
step.stop_unit = cur_trk + step_value - 1;
|
||||
|
||||
if (info->check) {
|
||||
- cdata = check_track_format(info, &step);
|
||||
+ cdata = check_track_format(info, dev_filename, &step);
|
||||
if (cdata.result) {
|
||||
cyl = cur_trk / heads + 1;
|
||||
draw_progress(info, cyl, cylinders, 1);
|
||||
@@ -858,7 +855,7 @@ static void check_disk_format(dasdfmt_in
|
||||
return;
|
||||
}
|
||||
|
||||
- check_blocksize(info, check_params->blksize);
|
||||
+ check_blocksize(info, dev_filename, check_params->blksize);
|
||||
check_layout(info, check_params->intensity);
|
||||
|
||||
/*
|
||||
@@ -1188,7 +1185,7 @@ static void dasdfmt_write_labels(dasdfmt
|
||||
* that the device is formatted to a certain extent. Otherwise the
|
||||
* process is terminated.
|
||||
*/
|
||||
-static void dasdfmt_find_start(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
+static void dasdfmt_find_start(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders,
|
||||
unsigned heads, format_data_t *format_params)
|
||||
{
|
||||
format_check_t cdata;
|
||||
@@ -1197,11 +1194,11 @@ static void dasdfmt_find_start(dasdfmt_i
|
||||
unsigned int right = (cylinders * heads) - 1;
|
||||
unsigned int first = left;
|
||||
|
||||
- check_blocksize(info, format_params->blksize);
|
||||
+ check_blocksize(info, dev_filename, format_params->blksize);
|
||||
|
||||
format_params->start_unit = 0;
|
||||
format_params->stop_unit = 4;
|
||||
- cdata = check_track_format(info, format_params);
|
||||
+ cdata = check_track_format(info, dev_filename, format_params);
|
||||
|
||||
if (cdata.result) {
|
||||
evaluate_format_error(info, &cdata, heads);
|
||||
@@ -1217,7 +1214,7 @@ static void dasdfmt_find_start(dasdfmt_i
|
||||
|
||||
format_params->start_unit = middle;
|
||||
format_params->stop_unit = middle;
|
||||
- cdata = check_track_format(info, format_params);
|
||||
+ cdata = check_track_format(info, dev_filename, format_params);
|
||||
if (cdata.blksize != format_params->blksize) {
|
||||
first = middle;
|
||||
right = middle - 1;
|
||||
@@ -1266,6 +1263,7 @@ static void dasdfmt_release_space(dasdfm
|
||||
}
|
||||
|
||||
+void do_dasdfmt(char *dev_filename, dasdfmt_info_t *info,
|
||||
+ volume_label_t *orig_vlabel)
|
||||
static void dasdfmt_prepare_and_format(dasdfmt_info_t *info,
|
||||
+ char *dev_filename,
|
||||
unsigned int cylinders,
|
||||
unsigned int heads, format_data_t *p)
|
||||
{
|
||||
@@ -1324,7 +1322,7 @@ static void dasdfmt_prepare_and_format(d
|
||||
/*
|
||||
* This function will start the expand format process.
|
||||
*/
|
||||
-static void dasdfmt_expand_format(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
+static void dasdfmt_expand_format(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders,
|
||||
unsigned int heads, format_data_t *p)
|
||||
{
|
||||
if (!(info->withoutprompt && (info->verbosity < 1)))
|
||||
@@ -1351,7 +1349,7 @@ static void dasdfmt_expand_format(dasdfm
|
||||
* This function will only format the first two tracks of a DASD.
|
||||
* The rest of the DASD is untouched and left as is.
|
||||
*/
|
||||
-static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
+static void dasdfmt_quick_format(dasdfmt_info_t *info, char *dev_filename, unsigned int cylinders,
|
||||
unsigned int heads, format_data_t *p)
|
||||
{
|
||||
format_check_t cdata = { .expect = {0}, 0 };
|
||||
@@ -1363,18 +1361,18 @@ static void dasdfmt_quick_format(dasdfmt
|
||||
} else if (info->ese) {
|
||||
printf("Skipping format check due to thin-provisioned device.\n");
|
||||
} else {
|
||||
- check_blocksize(info, p->blksize);
|
||||
+ check_blocksize(info, dev_filename, p->blksize);
|
||||
|
||||
printf("Checking the format of selected tracks...\n");
|
||||
|
||||
/* Check device format on the first and last 3 regular tracks */
|
||||
tmp.start_unit = 2;
|
||||
tmp.stop_unit = 4;
|
||||
- cdata = check_track_format(info, &tmp);
|
||||
+ cdata = check_track_format(info, dev_filename, &tmp);
|
||||
if (!cdata.result) {
|
||||
tmp.start_unit = (cylinders * heads) - 3;
|
||||
tmp.stop_unit = (cylinders * heads) - 1;
|
||||
- cdata = check_track_format(info, &tmp);
|
||||
+ cdata = check_track_format(info, dev_filename, &tmp);
|
||||
}
|
||||
if (cdata.result) {
|
||||
evaluate_format_error(info, &cdata, heads);
|
||||
@@ -1419,7 +1417,7 @@ static void do_format_dasd(dasdfmt_info_
|
||||
p->stop_unit = 1;
|
||||
break;
|
||||
case EXPAND: /* only the end of the disk */
|
||||
- dasdfmt_find_start(info, cylinders, heads, p);
|
||||
+ dasdfmt_find_start(info, devname, cylinders, heads, p);
|
||||
p->stop_unit = (cylinders * heads) - 1;
|
||||
break;
|
||||
}
|
||||
@@ -1468,24 +1466,24 @@ static void do_format_dasd(dasdfmt_info_
|
||||
|
||||
switch (mode) {
|
||||
case FULL:
|
||||
- dasdfmt_prepare_and_format(info, cylinders, heads, p);
|
||||
+ dasdfmt_prepare_and_format(info, devname, cylinders, heads, p);
|
||||
break;
|
||||
case QUICK:
|
||||
dasdfmt_release_space(info);
|
||||
- dasdfmt_quick_format(info, cylinders, heads, p);
|
||||
+ dasdfmt_quick_format(info, devname, cylinders, heads, p);
|
||||
break;
|
||||
case EXPAND:
|
||||
- dasdfmt_expand_format(info, cylinders, heads, p);
|
||||
+ dasdfmt_expand_format(info, devname, cylinders, heads, p);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Finished formatting the device.\n");
|
||||
|
||||
if (!(info->writenolabel || mode == EXPAND))
|
||||
- dasdfmt_write_labels(info, vlabel, cylinders, heads);
|
||||
+ dasdfmt_write_labels(info, devname, vlabel, cylinders, heads);
|
||||
|
||||
printf("Rereading the partition table... ");
|
||||
- err = dasd_reread_partition_table(dev_filename, 5);
|
||||
+ err = dasd_reread_partition_table(devname, 5);
|
||||
if (err != 0) {
|
||||
ERRMSG("%s: error during rereading the partition "
|
||||
"table: %s.\n", prog_name, strerror(err));
|
||||
@@ -1508,23 +1506,88 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
mode = info->ese ? QUICK : FULL;
|
||||
}
|
||||
|
||||
+void do_dasdfmt(char *dev_filename, dasdfmt_info_t info,
|
||||
+ volume_label_t *orig_vlabel, format_data_t format_params)
|
||||
+{
|
||||
+ volume_label_t vlabel;
|
||||
+ char old_volser[7];
|
||||
+ char str[ERR_LENGTH];
|
||||
+ unsigned int cylinders, heads;
|
||||
+ unsigned int cylinders, heads; int rc;
|
||||
+
|
||||
+ filedes = open(dev_filename, O_RDWR);
|
||||
+ if (filedes == -1)
|
||||
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n",
|
||||
+ prog_name, dev_filename, strerror(errno));
|
||||
+ close(filedes);
|
||||
+
|
||||
+ rc = dasd_get_info(dev_filename, &info.dasd_info);
|
||||
+ if (rc != 0)
|
||||
+ ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl call to retrieve "
|
||||
+ "device information for %s failed (%s).\n",
|
||||
+ prog_name, dev_filename, strerror(rc));
|
||||
+
|
||||
+ get_device_info(info);
|
||||
+ memcpy(&vlabel, orig_vlabel, sizeof(vlabel));
|
||||
+ /* Either let the user specify the blksize or get it from the kernel */
|
||||
+ if (!info->blksize_specified) {
|
||||
+ if (!info.blksize_specified) {
|
||||
+ if (!(mode == FULL ||
|
||||
+ info->dasd_info.format == DASD_FORMAT_NONE)
|
||||
+ || info->check)
|
||||
+ get_blocksize(&format_params.blksize);
|
||||
+ info.dasd_info.format == DASD_FORMAT_NONE)
|
||||
+ || info.check)
|
||||
+ get_blocksize(dev_filename, &format_params.blksize);
|
||||
+ else
|
||||
+ format_params = ask_user_for_blksize(format_params);
|
||||
+ }
|
||||
+
|
||||
+ if (info->keep_volser) {
|
||||
+ if (info->labelspec) {
|
||||
+ if (info.keep_volser) {
|
||||
+ if (info.labelspec) {
|
||||
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: The -k and -l options "
|
||||
+ "are mutually exclusive\n", prog_name);
|
||||
+ }
|
||||
@ -148,7 +309,7 @@ index b79cff0..607fd1c 100644
|
||||
+ }
|
||||
+
|
||||
+ if (dasdfmt_get_volser(dev_filename,
|
||||
+ &info->dasd_info, old_volser) == 0)
|
||||
+ &info.dasd_info, old_volser) == 0)
|
||||
+ vtoc_volume_label_set_volser(&vlabel, old_volser);
|
||||
+ else
|
||||
+ ERRMSG_EXIT(EXIT_FAILURE,
|
||||
@ -156,24 +317,20 @@ index b79cff0..607fd1c 100644
|
||||
+ prog_name, dev_filename);
|
||||
+ }
|
||||
+
|
||||
+ check_disk(info, dev_filename);
|
||||
+ check_disk(&info, dev_filename);
|
||||
+
|
||||
+ if (check_param(str, ERR_LENGTH, &format_params) < 0)
|
||||
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str);
|
||||
+
|
||||
+ set_geo(info, &cylinders, &heads);
|
||||
+ set_label(info, &vlabel, &format_params, cylinders);
|
||||
+ set_geo(&info, &cylinders, &heads);
|
||||
+ set_label(&info, &vlabel, &format_params, cylinders);
|
||||
+
|
||||
+ if (info->check)
|
||||
+ check_disk_format(info, cylinders, heads, &format_params);
|
||||
+ if (info.check)
|
||||
+ check_disk_format(&info, cylinders, heads, &format_params);
|
||||
+ else
|
||||
+ do_format_dasd(info, dev_filename, &vlabel,
|
||||
+ do_format_dasd(&info, dev_filename, &vlabel,
|
||||
+ &format_params, cylinders, heads);
|
||||
+
|
||||
+ if (close(filedes) != 0)
|
||||
+ ERRMSG("%s: error during close: %s\ncontinuing...\n",
|
||||
+ prog_name, strerror(errno));
|
||||
+
|
||||
+}
|
||||
+
|
||||
int main(int argc, char *argv[])
|
||||
@ -184,7 +341,6 @@ index b79cff0..607fd1c 100644
|
||||
volume_label_t vlabel;
|
||||
- char old_volser[7];
|
||||
|
||||
- char dev_filename[PATH_MAX];
|
||||
- char str[ERR_LENGTH];
|
||||
+ char *dev_filename[MAX_DEVICES];
|
||||
char buf[7];
|
||||
@ -199,35 +355,30 @@ index b79cff0..607fd1c 100644
|
||||
|
||||
/* Establish a handler for interrupt signals. */
|
||||
signal(SIGTERM, program_interrupt_signal);
|
||||
@@ -1634,61 +1693,21 @@ int main(int argc, char *argv[])
|
||||
@@ -1686,59 +1751,24 @@ int main(int argc, char *argv[])
|
||||
if (info.print_hashmarks)
|
||||
PARSE_PARAM_INTO(info.hashstep, hashstep_str, 10, "hashstep");
|
||||
|
||||
- get_device_name(dev_filename, optind, argc, argv);
|
||||
-
|
||||
- filedes = open(dev_filename, O_RDWR);
|
||||
- if (filedes == -1)
|
||||
- ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n",
|
||||
- prog_name, dev_filename, strerror(errno));
|
||||
- rc = dasd_get_info(dev_filename, &info.dasd_info);
|
||||
- if (rc != 0)
|
||||
- ERRMSG_EXIT(EXIT_FAILURE, "%s: the ioctl call to retrieve "
|
||||
- "device information failed (%s).\n",
|
||||
- prog_name, strerror(rc));
|
||||
-
|
||||
- info.ese = dasd_sys_ese(dev_filename);
|
||||
- eval_format_mode(&info);
|
||||
-
|
||||
- get_device_info(&info);
|
||||
+ while (optind < argc) {
|
||||
+ if (optind >= argc)
|
||||
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
+ prog_name);
|
||||
|
||||
- /* Either let the user specify the blksize or get it from the kernel */
|
||||
- if (!info.blksize_specified) {
|
||||
- if (!(mode == FULL ||
|
||||
- info.dasd_info.format == DASD_FORMAT_NONE) || info.check)
|
||||
- get_blocksize(&format_params.blksize);
|
||||
- get_blocksize(dev_filename, &format_params.blksize);
|
||||
- else
|
||||
- format_params = ask_user_for_blksize(format_params);
|
||||
+ get_device_name(dev_filename, numdev, argv[optind]);
|
||||
+ optind++;
|
||||
+ numdev++;
|
||||
}
|
||||
|
||||
- }
|
||||
-
|
||||
- if (info.keep_volser) {
|
||||
- if (info.labelspec) {
|
||||
- ERRMSG_EXIT(EXIT_MISUSE, "%s: The -k and -l options "
|
||||
@ -246,8 +397,19 @@ index b79cff0..607fd1c 100644
|
||||
- ERRMSG_EXIT(EXIT_FAILURE,
|
||||
- "%s: VOLSER not found on device %s\n",
|
||||
- prog_name, dev_filename);
|
||||
- }
|
||||
-
|
||||
+ while (optind < argc) {
|
||||
+ if (optind >= argc)
|
||||
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
+ prog_name);
|
||||
+
|
||||
+ info.ese = dasd_sys_ese(dev_filename[numdev]);
|
||||
+ eval_format_mode(&info);
|
||||
+
|
||||
+ get_device_name(dev_filename, numdev, argv[optind]);
|
||||
+ optind++;
|
||||
+ numdev++;
|
||||
}
|
||||
|
||||
- check_disk(&info, dev_filename);
|
||||
-
|
||||
- if (check_param(str, ERR_LENGTH, &format_params) < 0)
|
||||
@ -261,16 +423,12 @@ index b79cff0..607fd1c 100644
|
||||
- else
|
||||
- do_format_dasd(&info, dev_filename, &vlabel,
|
||||
- &format_params, cylinders, heads);
|
||||
-
|
||||
- if (close(filedes) != 0)
|
||||
- ERRMSG("%s: error during close: %s\ncontinuing...\n",
|
||||
- prog_name, strerror(errno));
|
||||
+ if (!numdev)
|
||||
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
+ prog_name);
|
||||
|
||||
+ for (i = 0; i < numdev; i++)
|
||||
+ do_dasdfmt(dev_filename[i], &info, &vlabel);
|
||||
+ do_dasdfmt(dev_filename[i], info, &vlabel, format_params);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 320946c0e9b2a80c3569d8f736621c99392fc413 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 5 Oct 2017 10:11:57 +0200
|
||||
Subject: [PATCH] dasdfmt: drop 'device_id' parameter
|
||||
|
||||
Drop device_id parameter from dasdfmt_info() and pass in 'optind'
|
||||
directly.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.com>
|
||||
---
|
||||
dasdfmt/dasdfmt.c | 15 +++++++--------
|
||||
dasdfmt/dasdfmt.h | 1 -
|
||||
2 files changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index 3da7902..b79cff0 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -456,24 +456,24 @@ static void program_interrupt_signal(int sig)
|
||||
/*
|
||||
* check given device name for blanks and some special characters
|
||||
*/
|
||||
-static void get_device_name(dasdfmt_info_t *info, char *devname, int argc,
|
||||
- char *argv[])
|
||||
+static void get_device_name(char *devname,
|
||||
+ int optind, int argc, char *argv[])
|
||||
{
|
||||
struct util_proc_dev_entry dev_entry;
|
||||
struct stat dev_stat;
|
||||
|
||||
- if (info->device_id + 1 < argc)
|
||||
+ if (optind + 1 < argc)
|
||||
ERRMSG_EXIT(EXIT_MISUSE,
|
||||
"%s: More than one device specified!\n", prog_name);
|
||||
|
||||
- if (info->device_id >= argc)
|
||||
+ if (optind >= argc)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
prog_name);
|
||||
|
||||
- if (strlen(argv[info->device_id]) >= PATH_MAX)
|
||||
+ if (strlen(argv[optind]) >= PATH_MAX)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: device name too long!\n",
|
||||
prog_name);
|
||||
- strcpy(devname, argv[info->device_id]);
|
||||
+ strcpy(devname, argv[optind]);
|
||||
|
||||
if (stat(devname, &dev_stat) != 0)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: Could not get information for "
|
||||
@@ -1604,7 +1604,6 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case -1:
|
||||
/* End of options string - start of devices list */
|
||||
- info.device_id = optind;
|
||||
break;
|
||||
default:
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "Try '%s --help' for more"
|
||||
@@ -1635,7 +1634,7 @@ int main(int argc, char *argv[])
|
||||
if (info.print_hashmarks)
|
||||
PARSE_PARAM_INTO(info.hashstep, hashstep_str, 10, "hashstep");
|
||||
|
||||
- get_device_name(&info, dev_filename, argc, argv);
|
||||
+ get_device_name(dev_filename, optind, argc, argv);
|
||||
|
||||
filedes = open(dev_filename, O_RDWR);
|
||||
if (filedes == -1)
|
||||
diff --git a/dasdfmt/dasdfmt.h b/dasdfmt/dasdfmt.h
|
||||
index 9ce3b92..a5581f1 100644
|
||||
--- a/dasdfmt/dasdfmt.h
|
||||
+++ b/dasdfmt/dasdfmt.h
|
||||
@@ -303,7 +303,6 @@ typedef struct dasdfmt_info {
|
||||
int cdl_format;
|
||||
int blksize_specified;
|
||||
int reqsize_specified;
|
||||
- int device_id;
|
||||
int keep_volser;
|
||||
int force_host;
|
||||
int layout_specified;
|
||||
--
|
||||
1.7.12.4
|
||||
|
@ -1,69 +0,0 @@
|
||||
From 1261105fe238ad306db29a9d47bb1a293bddf9aa Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20H=C3=B6ppner?= <hoeppner@linux.vnet.ibm.com>
|
||||
Date: Mon, 16 Oct 2017 15:46:07 +0200
|
||||
Subject: [PATCH] dasdinfo: Fix truncation warning
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Commit 3c80f7e025db ("dasdinfo: fix buffer overflow warning") changed a
|
||||
sprintf call to snprintf to avoid a buffer overflow warning. However,
|
||||
GCC 7 now warns about a potential truncation with snprintf:
|
||||
|
||||
dasdinfo.c: In function 'main':
|
||||
dasdinfo.c:577:18: warning: '%s' directive output may be truncated
|
||||
writing up to 255 bytes into a region of size 69 [-Wformat-truncation=]
|
||||
"/sys/block/%s/device/uid", dir_entry->d_name);
|
||||
^~
|
||||
dasdinfo.c:576:4: note: 'snprintf' output between 23 and 278 bytes into
|
||||
a destination of size 80
|
||||
snprintf(*uidfile, RD_BUFFER_SIZE,
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
"/sys/block/%s/device/uid", dir_entry->d_name);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We could get around this by increasing the buffer. Though, the current
|
||||
buffer size is already plenty and we know better anyway.
|
||||
Avoid the warning by simply checking the return value of snprintf and
|
||||
display an error in case data was truncated nonetheless.
|
||||
|
||||
Fixes: 3c80f7e025db ("dasdinfo: fix buffer overflow warning")
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
---
|
||||
dasdinfo/dasdinfo.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dasdinfo/dasdinfo.c b/dasdinfo/dasdinfo.c
|
||||
index c8bda3b..f881f03 100644
|
||||
--- a/dasdinfo/dasdinfo.c
|
||||
+++ b/dasdinfo/dasdinfo.c
|
||||
@@ -545,6 +545,7 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
char *readbuf;
|
||||
DIR *directory = NULL;
|
||||
struct dirent *dir_entry = NULL;
|
||||
+ int rc = 0;
|
||||
|
||||
if (stat(devnode, &stat_buffer) != 0) {
|
||||
printf("Error: could not stat %s\n", devnode);
|
||||
@@ -573,8 +574,15 @@ static int dinfo_get_uid_from_devnode(char **uidfile, char *devnode)
|
||||
|
||||
if (strncmp(stat_dev, readbuf,
|
||||
MAX(strlen(stat_dev), strlen(readbuf)-1)) == 0) {
|
||||
- snprintf(*uidfile, RD_BUFFER_SIZE,
|
||||
- "/sys/block/%s/device/uid", dir_entry->d_name);
|
||||
+ rc = snprintf(*uidfile, RD_BUFFER_SIZE,
|
||||
+ "/sys/block/%s/device/uid",
|
||||
+ dir_entry->d_name);
|
||||
+ if (rc >= RD_BUFFER_SIZE) {
|
||||
+ fprintf(stderr,
|
||||
+ "Error: Device name was truncated\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
break;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.12.4
|
||||
|
@ -1,67 +0,0 @@
|
||||
From f3adc9ca7928a8250f31b242335686ad9879ce10 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 5 Oct 2017 09:42:42 +0200
|
||||
Subject: [PATCH] dasdfmt: Fixup dasdfmt_get_volser()
|
||||
|
||||
dasdfmt_get_volser() opens its own private filedescriptor
|
||||
despite the global filedes already being opened.
|
||||
And we should be passing in only the bits of the info structure
|
||||
that we actually need.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.com>
|
||||
---
|
||||
dasdfmt/dasdfmt.c | 24 ++++++++----------------
|
||||
1 file changed, 8 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index 6043872..4cf423d 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -970,28 +970,19 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
/*
|
||||
* get volser
|
||||
*/
|
||||
-static int dasdfmt_get_volser(dasdfmt_info_t *info, char *volser)
|
||||
+static int dasdfmt_get_volser(char *devname, dasd_information2_t *dasd_info,
|
||||
+ char *volser)
|
||||
{
|
||||
unsigned int blksize;
|
||||
- int f;
|
||||
volume_label_t vlabel;
|
||||
|
||||
- f = open(info->devname, O_RDONLY);
|
||||
- if (f == -1)
|
||||
- ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n",
|
||||
- prog_name, info->devname, strerror(errno));
|
||||
-
|
||||
get_blocksize(&blksize);
|
||||
|
||||
- if (close(f) != 0)
|
||||
- ERRMSG("%s: error during close: %s\ncontinuing...\n",
|
||||
- prog_name, strerror(errno));
|
||||
-
|
||||
- if ((strncmp(info->dasd_info.type, "ECKD", 4) == 0) &&
|
||||
- (!info->dasd_info.FBA_layout)) {
|
||||
+ if ((strncmp(dasd_info->type, "ECKD", 4) == 0) &&
|
||||
+ !dasd_info->FBA_layout) {
|
||||
/* OS/390 and zOS compatible disk layout */
|
||||
- vtoc_read_volume_label(info->devname,
|
||||
- info->dasd_info.label_block * blksize,
|
||||
+ vtoc_read_volume_label(devname,
|
||||
+ dasd_info->label_block * blksize,
|
||||
&vlabel);
|
||||
vtoc_volume_label_get_volser(&vlabel, volser);
|
||||
return 0;
|
||||
@@ -1684,7 +1675,8 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- if (dasdfmt_get_volser(&info, old_volser) == 0)
|
||||
+ if (dasdfmt_get_volser(info.devname,
|
||||
+ &info.dasd_info, old_volser) == 0)
|
||||
vtoc_volume_label_set_volser(&vlabel, old_volser);
|
||||
else
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
--
|
||||
1.7.12.4
|
||||
|
@ -1,233 +0,0 @@
|
||||
From a4101cc9bf1d18b698ead344e6be6fe311fda41d Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 5 Oct 2017 09:59:41 +0200
|
||||
Subject: [PATCH] dasdfmt: Fixup device name handling
|
||||
|
||||
get_device_name() contains a chunk of unreachable code, as the
|
||||
'name' argument is never filled with any value.
|
||||
So turn things around to have get_device_name() always fill the
|
||||
'name' argument with the real device name, and remove the
|
||||
devname entry from the dasdfmt_info_t structure.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.com>
|
||||
---
|
||||
dasdfmt/dasdfmt.c | 70 ++++++++++++++++++++++++-------------------------------
|
||||
dasdfmt/dasdfmt.h | 1 -
|
||||
2 files changed, 30 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index 4cf423d..3da7902 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -456,7 +456,7 @@ static void program_interrupt_signal(int sig)
|
||||
/*
|
||||
* check given device name for blanks and some special characters
|
||||
*/
|
||||
-static void get_device_name(dasdfmt_info_t *info, char *name, int argc,
|
||||
+static void get_device_name(dasdfmt_info_t *info, char *devname, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
struct util_proc_dev_entry dev_entry;
|
||||
@@ -470,32 +470,20 @@ static void get_device_name(dasdfmt_info_t *info, char *name, int argc,
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
prog_name);
|
||||
|
||||
- if (info->device_id < argc) {
|
||||
- strcpy(info->devname, argv[info->device_id]);
|
||||
- } else {
|
||||
- if ((strchr(name, ' ') != NULL) || (strchr(name, '#') != NULL) ||
|
||||
- (strchr(name, '[') != NULL) || (strchr(name, ']') != NULL) ||
|
||||
- (strchr(name, '!') != NULL) || (strchr(name, '>') != NULL) ||
|
||||
- (strchr(name, '(') != NULL) || (strchr(name, '<') != NULL) ||
|
||||
- (strchr(name, ')') != NULL) || (strchr(name, ':') != NULL) ||
|
||||
- (strchr(name, '&') != NULL) || (strchr(name, ';') != NULL))
|
||||
- ERRMSG_EXIT(EXIT_MISUSE, "%s: Your filename contains "
|
||||
- "blanks or special characters!\n",
|
||||
- prog_name);
|
||||
-
|
||||
- strncpy(info->devname, name, PATH_MAX - 1);
|
||||
- info->devname[PATH_MAX - 1] = '\0';
|
||||
- }
|
||||
+ if (strlen(argv[info->device_id]) >= PATH_MAX)
|
||||
+ ERRMSG_EXIT(EXIT_MISUSE, "%s: device name too long!\n",
|
||||
+ prog_name);
|
||||
+ strcpy(devname, argv[info->device_id]);
|
||||
|
||||
- if (stat(info->devname, &dev_stat) != 0)
|
||||
+ if (stat(devname, &dev_stat) != 0)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: Could not get information for "
|
||||
- "device node %s: %s\n", prog_name, info->devname,
|
||||
+ "device node %s: %s\n", prog_name, devname,
|
||||
strerror(errno));
|
||||
|
||||
if (minor(dev_stat.st_rdev) & PARTN_MASK) {
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: Unable to format partition %s. "
|
||||
"Please specify a device.\n", prog_name,
|
||||
- info->devname);
|
||||
+ devname);
|
||||
}
|
||||
|
||||
if (util_proc_dev_get_entry(dev_stat.st_rdev, 1, &dev_entry) == 0) {
|
||||
@@ -505,7 +493,7 @@ static void get_device_name(dasdfmt_info_t *info, char *name, int argc,
|
||||
prog_name, dev_entry.name);
|
||||
} else {
|
||||
printf("%s WARNING: Unable to get driver name for device node %s",
|
||||
- prog_name, info->devname);
|
||||
+ prog_name, devname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +574,7 @@ static void check_layout(dasdfmt_info_t *info, unsigned int intensity)
|
||||
/*
|
||||
* check for disk type and set some variables (e.g. usage count)
|
||||
*/
|
||||
-static void check_disk(dasdfmt_info_t *info)
|
||||
+static void check_disk(dasdfmt_info_t *info, char *devname)
|
||||
{
|
||||
int ro, errno_save;
|
||||
|
||||
@@ -609,13 +597,13 @@ static void check_disk(dasdfmt_info_t *info)
|
||||
if (strncmp(info->dasd_info.type, "ECKD", 4) != 0) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"%s: Unsupported disk type\n%s is not an "
|
||||
- "ECKD disk!\n", prog_name, info->devname);
|
||||
+ "ECKD disk!\n", prog_name, devname);
|
||||
}
|
||||
|
||||
- if (dasd_sys_raw_track_access(info->devname)) {
|
||||
+ if (dasd_sys_raw_track_access(devname)) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"%s: Device '%s' is in raw-track access mode\n",
|
||||
- prog_name, info->devname);
|
||||
+ prog_name, devname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +923,8 @@ static format_data_t ask_user_for_blksize(format_data_t params)
|
||||
/*
|
||||
* print all information needed to format the device
|
||||
*/
|
||||
-static void dasdfmt_print_info(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
+static void dasdfmt_print_info(dasdfmt_info_t *info, char *devname,
|
||||
+ volume_label_t *vlabel,
|
||||
unsigned int cylinders, unsigned int heads,
|
||||
format_data_t *p)
|
||||
{
|
||||
@@ -945,7 +934,7 @@ static void dasdfmt_print_info(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
cylinders, heads, (cylinders * heads));
|
||||
|
||||
printf("\nI am going to format the device ");
|
||||
- printf("%s in the following way:\n", info->devname);
|
||||
+ printf("%s in the following way:\n", devname);
|
||||
printf(" Device number of device : 0x%x\n", info->dasd_info.devno);
|
||||
printf(" Labelling device : %s\n",
|
||||
(info->writenolabel) ? "no" : "yes");
|
||||
@@ -1376,7 +1365,8 @@ static void dasdfmt_quick_format(dasdfmt_info_t *info, unsigned int cylinders,
|
||||
disk_disabled = 0;
|
||||
}
|
||||
|
||||
-static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
+static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
+ volume_label_t *vlabel,
|
||||
format_data_t *p, unsigned int cylinders,
|
||||
unsigned int heads)
|
||||
{
|
||||
@@ -1399,19 +1389,19 @@ static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
}
|
||||
|
||||
if ((info->verbosity > 0) || !info->withoutprompt || info->testmode)
|
||||
- dasdfmt_print_info(info, vlabel, cylinders, heads, p);
|
||||
+ dasdfmt_print_info(info, devname, vlabel, cylinders, heads, p);
|
||||
|
||||
- count = u2s_get_host_access_count(info->devname);
|
||||
+ count = u2s_get_host_access_count(devname);
|
||||
if (info->force_host) {
|
||||
if (count > 1) {
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"\n%s: Disk %s is online on OS instances in %d different LPARs.\n"
|
||||
"Note: Your installation might include z/VM systems that are configured to\n"
|
||||
"automatically vary on disks, regardless of whether they are subsequently used.\n\n",
|
||||
- prog_name, info->devname, count);
|
||||
+ prog_name, devname, count);
|
||||
} else if (count < 0) {
|
||||
ERRMSG("\nHosts access information not available for disk %s.\n\n",
|
||||
- info->devname);
|
||||
+ devname);
|
||||
return;
|
||||
}
|
||||
} else if (count > 1)
|
||||
@@ -1420,7 +1410,7 @@ static void do_format_dasd(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
"Ensure that the disk is not being used by a system outside your LPAR.\n"
|
||||
"Note: Your installation might include z/VM systems that are configured to\n"
|
||||
"automatically vary on disks, regardless of whether they are subsequently used.\n",
|
||||
- info->devname, count);
|
||||
+ devname, count);
|
||||
|
||||
if (!info->testmode) {
|
||||
if (!info->withoutprompt) {
|
||||
@@ -1471,7 +1461,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
dasdfmt_info_t info = {
|
||||
.dasd_info = {0},
|
||||
- {0}
|
||||
};
|
||||
volume_label_t vlabel;
|
||||
char old_volser[7];
|
||||
@@ -1648,10 +1637,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
get_device_name(&info, dev_filename, argc, argv);
|
||||
|
||||
- filedes = open(info.devname, O_RDWR);
|
||||
+ filedes = open(dev_filename, O_RDWR);
|
||||
if (filedes == -1)
|
||||
ERRMSG_EXIT(EXIT_FAILURE, "%s: Unable to open device %s: %s\n",
|
||||
- prog_name, info.devname, strerror(errno));
|
||||
+ prog_name, dev_filename, strerror(errno));
|
||||
|
||||
get_device_info(&info);
|
||||
|
||||
@@ -1675,16 +1664,16 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- if (dasdfmt_get_volser(info.devname,
|
||||
+ if (dasdfmt_get_volser(dev_filename,
|
||||
&info.dasd_info, old_volser) == 0)
|
||||
vtoc_volume_label_set_volser(&vlabel, old_volser);
|
||||
else
|
||||
ERRMSG_EXIT(EXIT_FAILURE,
|
||||
"%s: VOLSER not found on device %s\n",
|
||||
- prog_name, info.devname);
|
||||
+ prog_name, dev_filename);
|
||||
}
|
||||
|
||||
- check_disk(&info);
|
||||
+ check_disk(&info, dev_filename);
|
||||
|
||||
if (check_param(str, ERR_LENGTH, &format_params) < 0)
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str);
|
||||
@@ -1695,7 +1684,8 @@ int main(int argc, char *argv[])
|
||||
if (info.check)
|
||||
check_disk_format(&info, cylinders, heads, &format_params);
|
||||
else
|
||||
- do_format_dasd(&info, &vlabel, &format_params, cylinders, heads);
|
||||
+ do_format_dasd(&info, dev_filename, &vlabel,
|
||||
+ &format_params, cylinders, heads);
|
||||
|
||||
if (close(filedes) != 0)
|
||||
ERRMSG("%s: error during close: %s\ncontinuing...\n",
|
||||
diff --git a/dasdfmt/dasdfmt.h b/dasdfmt/dasdfmt.h
|
||||
index 7c6f0bd..9ce3b92 100644
|
||||
--- a/dasdfmt/dasdfmt.h
|
||||
+++ b/dasdfmt/dasdfmt.h
|
||||
@@ -291,7 +291,6 @@ typedef struct bootstrap2 {
|
||||
|
||||
typedef struct dasdfmt_info {
|
||||
dasd_information2_t dasd_info;
|
||||
- char devname[PATH_MAX];
|
||||
int verbosity;
|
||||
int testmode;
|
||||
int withoutprompt;
|
||||
--
|
||||
1.7.12.4
|
||||
|
@ -34,7 +34,7 @@ index e7fc501..07c674b 100644
|
||||
Print one line for each formatted cylinder showing the number of the
|
||||
cylinder and percentage of formatting process.
|
||||
Intended to be used by higher level interfaces.
|
||||
@@ -153,6 +153,18 @@ Specify blocksize to be used. \fIblksize\fR must be a positive integer
|
||||
@@ -159,6 +159,18 @@ Specify blocksize to be used. \fIblksize\fR must be a positive integer
|
||||
and always be a power of two. The recommended blocksize is 4096 bytes.
|
||||
|
||||
.TP
|
||||
@ -57,15 +57,15 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index 607fd1c..6dd28fa 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -11,6 +11,7 @@
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/utsname.h>
|
||||
+#include <sys/wait.h>
|
||||
|
||||
#include "lib/dasd_base.h"
|
||||
#include "lib/dasd_sys.h"
|
||||
#include "lib/util_opt.h"
|
||||
@@ -68,6 +69,11 @@ static struct util_opt opt_vec[] = {
|
||||
@@ -71,6 +72,11 @@ static struct util_opt opt_vec[] = {
|
||||
.desc = "Perform complete format check on device",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
@ -77,7 +77,7 @@ index 607fd1c..6dd28fa 100644
|
||||
UTIL_OPT_SECTION("FORMAT OPTIONS"),
|
||||
{
|
||||
.option = { "blocksize", required_argument, NULL, 'b' },
|
||||
@@ -120,7 +126,7 @@ static struct util_opt opt_vec[] = {
|
||||
@@ -128,7 +134,7 @@ static struct util_opt opt_vec[] = {
|
||||
.desc = "Show a progressbar",
|
||||
},
|
||||
{
|
||||
@ -86,7 +86,7 @@ index 607fd1c..6dd28fa 100644
|
||||
.desc = "Show progress in percent",
|
||||
},
|
||||
UTIL_OPT_SECTION("MISC"),
|
||||
@@ -254,7 +260,7 @@ static void draw_progress(dasdfmt_info_t *info, int cyl, unsigned int cylinders,
|
||||
@@ -262,7 +268,7 @@ static void draw_progress(dasdfmt_info_t *info, int cyl, unsigned int cylinders,
|
||||
|
||||
if (info->print_hashmarks &&
|
||||
(cyl / info->hashstep - hashcount) != 0) {
|
||||
@ -95,7 +95,7 @@ index 607fd1c..6dd28fa 100644
|
||||
fflush(stdout);
|
||||
hashcount++;
|
||||
}
|
||||
@@ -1533,7 +1539,8 @@ int main(int argc, char *argv[])
|
||||
@@ -1587,7 +1593,8 @@ int main(int argc, char *argv[])
|
||||
char *reqsize_param_str = NULL;
|
||||
char *hashstep_str = NULL;
|
||||
|
||||
@ -105,7 +105,7 @@ index 607fd1c..6dd28fa 100644
|
||||
|
||||
/* Establish a handler for interrupt signals. */
|
||||
signal(SIGTERM, program_interrupt_signal);
|
||||
@@ -1600,7 +1607,7 @@ int main(int argc, char *argv[])
|
||||
@@ -1652,7 +1659,7 @@ int main(int argc, char *argv[])
|
||||
info.print_hashmarks = 1;
|
||||
}
|
||||
break;
|
||||
@ -114,9 +114,9 @@ index 607fd1c..6dd28fa 100644
|
||||
if (!(info.print_hashmarks || info.print_progressbar))
|
||||
info.print_percentage = 1;
|
||||
break;
|
||||
@@ -1658,6 +1665,9 @@ int main(int argc, char *argv[])
|
||||
"more information.\n",
|
||||
prog_name, optarg);
|
||||
@@ -1714,6 +1721,9 @@ int main(int argc, char *argv[])
|
||||
case OPT_NODISCARD:
|
||||
info.no_discard = 1;
|
||||
break;
|
||||
+ case 'P':
|
||||
+ max_parallel = atoi(optarg);
|
||||
@ -124,7 +124,7 @@ index 607fd1c..6dd28fa 100644
|
||||
case OPT_CHECK:
|
||||
info.check = 1;
|
||||
break;
|
||||
@@ -1673,6 +1683,9 @@
|
||||
@@ -1729,6 +1739,9 @@
|
||||
break; /* exit loop if finished */
|
||||
}
|
||||
|
||||
@ -134,12 +134,12 @@ index 607fd1c..6dd28fa 100644
|
||||
CHECK_SPEC_MAX_ONCE(info.blksize_specified, "blocksize");
|
||||
CHECK_SPEC_MAX_ONCE(info.labelspec, "label");
|
||||
CHECK_SPEC_MAX_ONCE(info.writenolabel, "omit-label-writing flag");
|
||||
@@ -1707,7 +1717,33 @@ int main(int argc, char *argv[])
|
||||
@@ -1766,7 +1779,33 @@ int main(int argc, char *argv[])
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: No device specified!\n",
|
||||
prog_name);
|
||||
|
||||
|
||||
- for (i = 0; i < numdev; i++)
|
||||
- do_dasdfmt(dev_filename[i], &info, &vlabel);
|
||||
- do_dasdfmt(dev_filename[i], info, &vlabel, format_params);
|
||||
- return 0;
|
||||
+ for (i = 0; i < numdev; i++) {
|
||||
+ int chpid;
|
||||
@ -152,7 +152,7 @@ index 607fd1c..6dd28fa 100644
|
||||
+ prog_name, strerror(errno));
|
||||
+ if (!chpid) {
|
||||
+ info.procnum = i;
|
||||
+ do_dasdfmt(dev_filename[i], &info, &vlabel);
|
||||
+ do_dasdfmt(dev_filename[i], info, &vlabel, format_params);
|
||||
+ exit(0);
|
||||
+ } else {
|
||||
+ running++;
|
||||
@ -175,10 +175,10 @@ diff --git a/dasdfmt/dasdfmt.h b/dasdfmt/dasdfmt.h
|
||||
index a5581f1..fb6fc34 100644
|
||||
--- a/dasdfmt/dasdfmt.h
|
||||
+++ b/dasdfmt/dasdfmt.h
|
||||
@@ -307,6 +307,7 @@ typedef struct dasdfmt_info {
|
||||
int force_host;
|
||||
int layout_specified;
|
||||
int check;
|
||||
@@ -95,6 +95,7 @@ typedef struct dasdfmt_info {
|
||||
int mode_specified;
|
||||
int ese;
|
||||
int no_discard;
|
||||
+ int procnum;
|
||||
} dasdfmt_info_t;
|
||||
|
||||
|
@ -41,7 +41,7 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index 6dd28fa..5b6023a 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -129,6 +129,10 @@ static struct util_opt opt_vec[] = {
|
||||
@@ -137,6 +137,10 @@ static struct util_opt opt_vec[] = {
|
||||
.option = { "percentage", no_argument, NULL, 'Q' },
|
||||
.desc = "Show progress in percent",
|
||||
},
|
||||
@ -52,7 +52,7 @@ index 6dd28fa..5b6023a 100644
|
||||
UTIL_OPT_SECTION("MISC"),
|
||||
{
|
||||
.option = { "check_host_count", no_argument, NULL, 'C' },
|
||||
@@ -351,7 +355,8 @@ static void evaluate_format_error(dasdfmt_info_t *info, format_check_t *cdata,
|
||||
@@ -343,7 +347,8 @@ static void evaluate_format_error(dasdfmt_info_t *info, format_check_t *cdata,
|
||||
unsigned int kl = 0;
|
||||
int blksize = cdata->expect.blksize;
|
||||
|
||||
@ -62,7 +62,7 @@ index 6dd28fa..5b6023a 100644
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
@@ -758,9 +763,9 @@ static void check_hashmarks(dasdfmt_info_t *info)
|
||||
@@ -749,9 +754,9 @@ static void check_hashmarks(dasdfmt_info_t *info)
|
||||
"using the default.\n");
|
||||
info->hashstep = 10;
|
||||
}
|
||||
@ -75,7 +75,16 @@ index 6dd28fa..5b6023a 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1445,16 +1450,18 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
@@ -985,7 +990,7 @@ static int dasdfmt_get_volser(char *devn
|
||||
/*
|
||||
* do all the labeling (volume label and initial VTOC)
|
||||
*/
|
||||
-static void dasdfmt_write_labels(dasdfmt_info_t *info, volume_label_t *vlabel,
|
||||
+static void dasdfmt_write_labels(dasdfmt_info_t *info, char *dev_filename, volume_label_t *vlabel,
|
||||
unsigned int cylinders, unsigned int heads)
|
||||
{
|
||||
int label_position;
|
||||
@@ -1483,17 +1488,19 @@ static void do_format_dasd(dasdfmt_info_t *info, char *devname,
|
||||
break;
|
||||
}
|
||||
|
||||
@ -84,31 +93,32 @@ index 6dd28fa..5b6023a 100644
|
||||
+ printf("Finished formatting the device.\n");
|
||||
|
||||
if (!(info->writenolabel || mode == EXPAND))
|
||||
dasdfmt_write_labels(info, vlabel, cylinders, heads);
|
||||
dasdfmt_write_labels(info, devname, vlabel, cylinders, heads);
|
||||
|
||||
- printf("Rereading the partition table... ");
|
||||
+ if (!info->yast_mode)
|
||||
+ printf("Rereading the partition table... ");
|
||||
if (reread_partition_table()) {
|
||||
err = dasd_reread_partition_table(devname, 5);
|
||||
if (err != 0) {
|
||||
ERRMSG("%s: error during rereading the partition "
|
||||
"table: %s.\n", prog_name, strerror(errno));
|
||||
"table: %s.\n", prog_name, strerror(err));
|
||||
- } else {
|
||||
+ } else if (!info->yast_mode) {
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
@@ -1511,6 +1518,8 @@ void do_dasdfmt(char *dev_filename, dasdfmt_info_t *info,
|
||||
@@ -1569,6 +1576,8 @@ void do_dasdfmt(char *dev_filename, dasdfmt_info_t *info,
|
||||
ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str);
|
||||
|
||||
set_geo(info, &cylinders, &heads);
|
||||
+ if (info->yast_mode)
|
||||
set_geo(&info, &cylinders, &heads);
|
||||
+ if (info.yast_mode)
|
||||
+ printf("%d\n", cylinders);
|
||||
set_label(info, &vlabel, &format_params, cylinders);
|
||||
set_label(&info, &vlabel, &format_params, cylinders);
|
||||
|
||||
if (info->check)
|
||||
@@ -1665,6 +1674,10 @@ int main(int argc, char *argv[])
|
||||
"more information.\n",
|
||||
prog_name, optarg);
|
||||
if (info.check)
|
||||
@@ -1721,6 +1730,10 @@ int main(int argc, char *argv[])
|
||||
case OPT_NODISCARD:
|
||||
info.no_discard = 1;
|
||||
break;
|
||||
+ case 'Y':
|
||||
+ /* YaST mode */
|
||||
@ -121,9 +131,9 @@ diff --git a/dasdfmt/dasdfmt.h b/dasdfmt/dasdfmt.h
|
||||
index fb6fc34..fe0cc7f 100644
|
||||
--- a/dasdfmt/dasdfmt.h
|
||||
+++ b/dasdfmt/dasdfmt.h
|
||||
@@ -308,6 +308,7 @@ typedef struct dasdfmt_info {
|
||||
int layout_specified;
|
||||
int check;
|
||||
@@ -96,6 +96,7 @@ typedef struct dasdfmt_info {
|
||||
int ese;
|
||||
int no_discard;
|
||||
int procnum;
|
||||
+ int yast_mode;
|
||||
} dasdfmt_info_t;
|
||||
|
@ -41,7 +41,7 @@ diff --git a/dasdfmt/dasdfmt.c b/dasdfmt/dasdfmt.c
|
||||
index 5b6023a..cdd80df 100644
|
||||
--- a/dasdfmt/dasdfmt.c
|
||||
+++ b/dasdfmt/dasdfmt.c
|
||||
@@ -74,6 +74,10 @@ static struct util_opt opt_vec[] = {
|
||||
@@ -77,6 +77,10 @@ static struct util_opt opt_vec[] = {
|
||||
.desc = "Format devices in parallel",
|
||||
.flags = UTIL_OPT_FLAG_NOLONG,
|
||||
},
|
||||
@ -52,7 +52,7 @@ index 5b6023a..cdd80df 100644
|
||||
UTIL_OPT_SECTION("FORMAT OPTIONS"),
|
||||
{
|
||||
.option = { "blocksize", required_argument, NULL, 'b' },
|
||||
@@ -1597,6 +1601,10 @@ int main(int argc, char *argv[])
|
||||
@@ -1649,6 +1653,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
info.layout_specified = 1;
|
||||
break;
|
||||
|
@ -1,27 +0,0 @@
|
||||
Subject: [PATCH] [BZ 160944] cpi: add missing Install section to service unit
|
||||
From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
|
||||
Description: cpi: add missing Install section to service unit
|
||||
Symptom: Enabling the cpi service unit fails because it
|
||||
does not include information about where to install
|
||||
it.
|
||||
Problem: An install section is missing.
|
||||
Solution: Add an install section.
|
||||
Reproduction: Issue systemctl enable cpi.
|
||||
Upstream-ID: -
|
||||
Problem-ID: 160944
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
---
|
||||
systemd/cpi.service.in | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/systemd/cpi.service.in
|
||||
+++ b/systemd/cpi.service.in
|
||||
@@ -38,3 +38,6 @@ EnvironmentFile=/etc/sysconfig/cpi
|
||||
#
|
||||
# Sending data to the HMC/SE
|
||||
ExecStart=@toolslib_path@/cpictl -e
|
||||
+
|
||||
+[Install]
|
||||
+WantedBy=multi-user.target
|
@ -1,202 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161563] cpuplugd: Improve systemctl start error handling
|
||||
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
|
||||
Description: cpuplugd, mon_tools: Improve systemctl start error handling
|
||||
Symptom: "systemctl start cpuplugd/mon_procd/mon_fsstatd" does not
|
||||
report any errors in case the startup fails.
|
||||
Problem: For type=simple, systemd forks/execs the process and if that
|
||||
is successful, it immediately returns. There is no way to
|
||||
find out if the initial startup fails.
|
||||
Solution: Use type=fork and run the process in the background. In this
|
||||
case systemd waits until the initial process returns.
|
||||
In addition, use PIDFile and ensure that the pid file is
|
||||
already available when the initial process returns. To
|
||||
achieve this, use startup synchronization via pipe.
|
||||
Reproduction: Add invalid values to the config files and start the daemons
|
||||
with "systemctl start cpuplugd/mon_procd/mon_fsstatd".
|
||||
Upstream-ID: 82c8148983fc09e9bfa5bf852b2d39571f8475a0
|
||||
Problem-ID: 161563
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpuplugd: Improve systemctl start error handling
|
||||
|
||||
Currently "systemctl start cpuplugd" does not report any errors in
|
||||
case the startup fails.
|
||||
|
||||
Example:
|
||||
|
||||
# mv /etc/cpuplugd.conf /etc/cpuplugd.conf.xxx
|
||||
# systemctl start cpuplugd
|
||||
|
||||
The reason is that for type=simple systemd forks/execs cpuplugd and if
|
||||
that is successful immediately returns. There is no way to find out
|
||||
if the initial startup fails.
|
||||
|
||||
Fix this by using type=fork and running cpuplugd in the background. In
|
||||
this case systemd waits until the initial process returns.
|
||||
|
||||
In addition use PIDFile and ensure that the pid file is already available
|
||||
when the initial cpuplugd process returns. To achieve this, replace the
|
||||
daemon() function by our own implementation that introduces startup
|
||||
synchronization via pipe. Without that systemd would print the following
|
||||
warning:
|
||||
|
||||
systemd[1]: cpuplugd.service: PID file /var/run/cpuplugd.pid not readable
|
||||
(yet?) after start: No such file or directory
|
||||
|
||||
With this patch, an early startup error like in the example above, is now
|
||||
reported correctly in "systemctl start":
|
||||
|
||||
# systemctl start cpuplugd
|
||||
Job for cpuplugd.service failed because the control process exited...
|
||||
See "systemctl status cpuplugd.service" and "journalctl -xe" for ...
|
||||
# journalctl -ex | grep cpuplugd
|
||||
Nov 16 15:52:27 ... cpuplugd[5096]: Opening configuration file failed:
|
||||
No such file or directory
|
||||
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
Acked-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
---
|
||||
cpuplugd/cpuplugd.h | 2 -
|
||||
cpuplugd/daemon.c | 60 ++++++++++++++++++++++++++++++++++++++++++--
|
||||
cpuplugd/main.c | 4 --
|
||||
systemd/cpuplugd.service.in | 5 ++-
|
||||
4 files changed, 63 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/cpuplugd/cpuplugd.h
|
||||
+++ b/cpuplugd/cpuplugd.h
|
||||
@@ -197,10 +197,10 @@ int is_online(int cpuid);
|
||||
long get_cmmpages_size();
|
||||
void parse_options(int argc, char **argv);
|
||||
void check_if_started_twice();
|
||||
-void store_pid(void);
|
||||
void handle_signals(void);
|
||||
void handle_sighup(void);
|
||||
void reload_daemon(void);
|
||||
+int daemonize(void);
|
||||
int check_cmmfiles(void);
|
||||
void check_config();
|
||||
void set_cmm_pages(long size);
|
||||
--- a/cpuplugd/daemon.c
|
||||
+++ b/cpuplugd/daemon.c
|
||||
@@ -9,6 +9,10 @@
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
#include "cpuplugd.h"
|
||||
|
||||
const char *name = NAME;
|
||||
@@ -49,7 +53,7 @@ void print_version()
|
||||
/*
|
||||
* Store daemon's pid so it can be stopped
|
||||
*/
|
||||
-void store_pid(void)
|
||||
+static int store_pid(void)
|
||||
{
|
||||
FILE *filp;
|
||||
|
||||
@@ -57,10 +61,62 @@ void store_pid(void)
|
||||
if (!filp) {
|
||||
cpuplugd_error("cannot open pid file %s: %s\n", pid_file,
|
||||
strerror(errno));
|
||||
- exit(1);
|
||||
+ return -1;
|
||||
}
|
||||
fprintf(filp, "%d\n", getpid());
|
||||
fclose(filp);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Run daemon in background and write pid file
|
||||
+ */
|
||||
+int daemonize(void)
|
||||
+{
|
||||
+ int fd, pipe_fds[2], startup_rc = 1;
|
||||
+ pid_t pid;
|
||||
+
|
||||
+ if (pipe(pipe_fds) == -1) {
|
||||
+ cpuplugd_error("cannot create pipe\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ pid = fork();
|
||||
+ if (pid < 0)
|
||||
+ goto close_pipe;
|
||||
+ if (pid != 0) {
|
||||
+ /* Wait for startup return code from daemon */
|
||||
+ if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
||||
+ cpuplugd_error("cannot read from pipe\n");
|
||||
+ /* On success daemon has written pid file at this point */
|
||||
+ exit(startup_rc);
|
||||
+ }
|
||||
+ /* Create new session */
|
||||
+ if (setsid() < 0)
|
||||
+ goto notify_parent;
|
||||
+ /* Redirect stdin/out/err to /dev/null */
|
||||
+ fd = open("/dev/null", O_RDWR, 0);
|
||||
+ if (fd == -1)
|
||||
+ goto notify_parent;
|
||||
+ if (dup2(fd, STDIN_FILENO) < 0)
|
||||
+ goto notify_parent;
|
||||
+ if (dup2(fd, STDOUT_FILENO) < 0)
|
||||
+ goto notify_parent;
|
||||
+ if (dup2(fd, STDERR_FILENO) < 0)
|
||||
+ goto notify_parent;
|
||||
+ /* Create pid file */
|
||||
+ if (store_pid() < 0)
|
||||
+ goto notify_parent;
|
||||
+ startup_rc = 0;
|
||||
+notify_parent:
|
||||
+ /* Inform waiting parent about startup return code */
|
||||
+ if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
||||
+ cpuplugd_error("cannot write to pipe\n");
|
||||
+ startup_rc = 1;
|
||||
+ }
|
||||
+close_pipe:
|
||||
+ close(pipe_fds[0]);
|
||||
+ close(pipe_fds[1]);
|
||||
+ return startup_rc ? -1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
--- a/cpuplugd/main.c
|
||||
+++ b/cpuplugd/main.c
|
||||
@@ -418,13 +418,11 @@ int main(int argc, char *argv[])
|
||||
check_config();
|
||||
|
||||
if (!foreground) {
|
||||
- rc = daemon(1, 0);
|
||||
+ rc = daemonize();
|
||||
if (rc < 0)
|
||||
cpuplugd_exit("Detach from terminal failed: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
- /* Store daemon pid */
|
||||
- store_pid();
|
||||
/* Unlock lock file */
|
||||
flock(fd, LOCK_UN);
|
||||
close(fd);
|
||||
--- a/systemd/cpuplugd.service.in
|
||||
+++ b/systemd/cpuplugd.service.in
|
||||
@@ -13,10 +13,11 @@ Documentation=man:cpuplugd(8) man:cpuplu
|
||||
After=remote-fs.target
|
||||
|
||||
[Service]
|
||||
-ExecStart=@usrsbin_path@/cpuplugd -f -c /etc/cpuplugd.conf
|
||||
+ExecStart=@usrsbin_path@/cpuplugd -c /etc/cpuplugd.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
-Type=simple
|
||||
+Type=forking
|
||||
+PIDFile=/var/run/cpuplugd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,69 +0,0 @@
|
||||
Subject: [PATCH] [BZ 168517] dbginfo.sh: Extend data collection
|
||||
From: Sa Liu <saliu@de.ibm.com>
|
||||
|
||||
Description: dbginfo.sh: Extend data collection
|
||||
Symptom: This update covers various symptoms on dbginfo.sh data
|
||||
collection:
|
||||
- There is no data collected for docker.
|
||||
- ps command does not show threads infomation.
|
||||
- There is no run queue statistics and scheduler data.
|
||||
- z/VM commands do not show multithread, protect
|
||||
settings and SSI status.
|
||||
Problem: Following problems exist:
|
||||
- No analysis is possible for docker data.
|
||||
- Missing thread information.
|
||||
- Missing run queue statistics and scheduler data.
|
||||
- Missing z/VM information.
|
||||
Solution: - Extend the data collection to collect docker data
|
||||
- Change ps command to show threads informaton
|
||||
- Add commands to display run queue statistics and
|
||||
scheduler data.
|
||||
- Add z/VM commands to show multithread, protect settings
|
||||
and SSI status.
|
||||
Reproduction: Run this script and verify the output
|
||||
Upstream-ID: -
|
||||
Problem-ID: 168517
|
||||
|
||||
Signed-off-by: Sa Liu <saliu@de.ibm.com>
|
||||
---
|
||||
scripts/dbginfo.sh | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/scripts/dbginfo.sh
|
||||
+++ b/scripts/dbginfo.sh
|
||||
@@ -375,7 +375,8 @@ CMDS="uname -a\
|
||||
:runlevel\
|
||||
:iptables -L\
|
||||
:ulimit -a\
|
||||
- :ps -eo pid,tid,nlwp,policy,user,tname,ni,pri,psr,sgi_p,stat,wchan,start_time,time,pcpu,pmem,vsize,size,rss,share,command\
|
||||
+ :ps -emo pid,tid,nlwp,policy,user,tname,ni,pri,psr,sgi_p,stat,wchan,start_time,time,pcpu,pmem,vsize,size,rss,share,command\
|
||||
+ :ps -eHo pid,tid,nlwp,policy,user,tname,ni,pri,psr,sgi_p,stat,wchan,start_time,time,pcpu,pmem,vsize,size,rss,share,command\
|
||||
:ps axX\
|
||||
:dmesg -s 1048576\
|
||||
:last\
|
||||
@@ -470,6 +471,8 @@ VM_CMDS="q userid\
|
||||
:q privclass\
|
||||
:q cplevel\
|
||||
:q cpservice\
|
||||
+ :q cpprot user\
|
||||
+ :q specex\
|
||||
:q ssi\
|
||||
:q cpus\
|
||||
:q srm\
|
||||
@@ -508,6 +511,7 @@ VM_CMDS="q userid\
|
||||
:q cache\
|
||||
:q nic\
|
||||
:q pav\
|
||||
+ :q proc\
|
||||
:q proc topology\
|
||||
:q mt\
|
||||
:q qioass\
|
||||
@@ -831,7 +835,7 @@ post_processing() {
|
||||
local tmp_file
|
||||
local file_name
|
||||
|
||||
- pr_syslog_stdout "11 of ${COLLECTION_COUNT}: Postprocessing"
|
||||
+ pr_syslog_stdout "${COLLECTION_COUNT} of ${COLLECTION_COUNT}: Postprocessing"
|
||||
|
||||
find "${WORKPATH}etc/libvirt/qemu/" -maxdepth 1 -name "*.xml" 2>/dev/null | while IFS= read -r file_name; do
|
||||
file_mtime_epoche=$(stat --format=%Y "${file_name}")
|
@ -1,41 +0,0 @@
|
||||
Subject: [PATCH] [BZ 164881] hmcdrvfs: fix parsing of link count >= 1000
|
||||
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
|
||||
Description: hmcdrvfs: fix parsing of link count >= 1000
|
||||
Symptom: hmcdrvfs will ignore files with a link count >= 1000
|
||||
Problem: The parsing code relies on having spaces between the different
|
||||
fields in its input data. When a file has a link count >= 1000,
|
||||
there will be no space, and the "link count" field will be
|
||||
placed directly after the previous "mode" field. This will
|
||||
confuse the parser, and all such files will not be accesible.
|
||||
Solution: The "mode" field will never contain digits, so the parser can
|
||||
recognize the "link count" field by the presence of a digit.
|
||||
Reproduction: Use a medium containing files with link count >= 1000 in
|
||||
hmcdrvfs, and try to access/list them.
|
||||
Upstream-ID: -
|
||||
Problem-ID: 164881
|
||||
|
||||
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
---
|
||||
hmcdrvfs/hmcdrvfs.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/hmcdrvfs/hmcdrvfs.c
|
||||
+++ b/hmcdrvfs/hmcdrvfs.c
|
||||
@@ -821,10 +821,13 @@ static char *hmcdrv_parse_line(char *lin
|
||||
if ((*line != '\0') && (*line != '\n')) {
|
||||
field = hmcdrv_parse_ntoken(field, line, &attr);
|
||||
|
||||
- while ((*line != '\0') &&
|
||||
- (*line != '\n') &&
|
||||
- !isspace(*line))
|
||||
+ while ((*line != '\0') && (*line != '\n')) {
|
||||
+ if (isspace(*line))
|
||||
+ break;
|
||||
+ if (field == 1 && isdigit(*line))
|
||||
+ break;
|
||||
++line; /* search end of field */
|
||||
+ }
|
||||
}
|
||||
} /* while */
|
||||
|
@ -1,26 +0,0 @@
|
||||
From e179b7a9acdd63caacf352b37e128b5326f151cd Mon Sep 17 00:00:00 2001
|
||||
From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Date: Wed, 18 Oct 2017 11:35:58 +0200
|
||||
Subject: [PATCH] iucvterm: include ctype for toupper()
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
---
|
||||
iucvterm/src/getopt.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/iucvterm/src/getopt.c b/iucvterm/src/getopt.c
|
||||
index 503f6dd..b79b6a9 100644
|
||||
--- a/iucvterm/src/getopt.c
|
||||
+++ b/iucvterm/src/getopt.c
|
||||
@@ -8,6 +8,7 @@
|
||||
* 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 <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
--
|
||||
1.7.12.4
|
||||
|
@ -1,110 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: clarify discovery use case, relation to NPIV and to zfcp auto LUN scan
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: 0daa7ba0b558ff22fa1c1e014e754cbd08366c00
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: clarify discovery use case, relation to NPIV and to zfcp auto LUN scan
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 3 +++
|
||||
zconf/lsluns.8 | 18 ++++++++++++++++++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -174,6 +174,9 @@ $PROGRAM_NAME [-c <busid>] ... [-p <wwpn
|
||||
|
||||
List LUNs discovered in the Fibre Channel (FC) Storage Area Network (SAN).
|
||||
This causes extra SAN traffic for each target port WWPN.
|
||||
+ Discovering LUNs only makes sense for NPIV-enabled FCP devices
|
||||
+ without zfcp automatic LUN scan. zfcp automatic LUN scan is available
|
||||
+ as of kernel version 2.6.37, if not disabled with zfcp.allow_lun_scan=0.
|
||||
|
||||
$PROGRAM_NAME -a [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -46,6 +46,24 @@ encryption, use other tools such as
|
||||
or
|
||||
.BR "lsscsi \-tv" .
|
||||
|
||||
+.SS Details on lsluns without -a option
|
||||
+
|
||||
+.TP
|
||||
+Prerequisite
|
||||
+Discovering LUNs only makes sense for NPIV-enabled FCP devices
|
||||
+without zfcp automatic LUN scan. zfcp automatic LUN scan is available
|
||||
+as of kernel version 2.6.37, if not disabled with zfcp.allow_lun_scan=0.
|
||||
+
|
||||
+With available and enabled zfcp automatic LUN scan,
|
||||
+the kernel already performs LUN discovery.
|
||||
+
|
||||
+.TP
|
||||
+Temporary LUN Attachment
|
||||
+If not attached already, lsluns temporarily attaches LUN 0
|
||||
+(or if this fails the WLUN 0xc101000000000000) during runtime.
|
||||
+Do not terminate lsluns with a signal. Signals interfere
|
||||
+with the removal of temporarily attached LUNs.
|
||||
+
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-a ", " \-\-active
|
@ -1,104 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: complement alternative tools with lszdev
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: e5f9279295780bd297f58cc23319878fadbc80f1
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: complement alternative tools with lszdev
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
|
||||
Reviewed-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 3 ++-
|
||||
zconf/lsluns.8 | 7 +++++--
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -192,7 +192,8 @@ $PROGRAM_NAME -a [-c <busid>] ... [-p <w
|
||||
This causes extra SAN traffic for each attached LUN.
|
||||
|
||||
For all other uses, such as listing attached LUNs or properties other than
|
||||
-encryption, use other tools such as "lszfcp -D" or "lsscsi -tv".
|
||||
+encryption, use other tools such as "lszfcp -D" or "lsscsi -tv"
|
||||
+or "lszdev zfcp-lun -ii".
|
||||
|
||||
Limit the listing by specifying one or more adapters (FCP device
|
||||
bus-IDs) or target port WWPNs or both.
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -48,7 +48,9 @@ For all other uses, such as listing atta
|
||||
encryption, use other tools such as
|
||||
.B lszfcp \-D
|
||||
or
|
||||
-.BR "lsscsi \-tv" .
|
||||
+.BR "lsscsi \-tv"
|
||||
+or
|
||||
+.BR "lszdev zfcp-lun \-ii" .
|
||||
|
||||
.SS Details on lsluns without -a option
|
||||
|
||||
@@ -135,4 +137,5 @@ indicates that the device is encrypted.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR lszfcp (8),
|
||||
-.BR lsscsi (8)
|
||||
+.BR lsscsi (8),
|
||||
+.BR lszdev (8)
|
@ -1,125 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: do not print confusing messages when a filter matches nothing
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: c993ad89c544dd162005a9a1e582b51667c46b66
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: do not print confusing messages when a filter matches nothing
|
||||
|
||||
lsluns printed potentially confusing messages when a filter or combination
|
||||
of filters matched nothing:
|
||||
|
||||
No valid combination found for adapter '0.0.1906'. Removing from
|
||||
resource list.
|
||||
No valid combination found for port '0x50050763071845e3'. Removing from
|
||||
resource list.
|
||||
...
|
||||
|
||||
To the user it is potentially unclear which 'combination' is actually being
|
||||
referred to, as only one part of the combination is mentioned, and what the
|
||||
ominous 'resource list' is. The later information is merely useful for a
|
||||
developer to debug the script.
|
||||
|
||||
Such a message was written for every user supplied filter that did not
|
||||
contribute anything to the resulting subset that is being listed, although
|
||||
the filter actually might match something when used standalone.
|
||||
|
||||
Additionally those messages were printed to stdout instead of stderr. As
|
||||
there is no debug or verbose switch and the information level of those
|
||||
messages is low, we may simply discard them.
|
||||
|
||||
Reported-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Reviewed-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 15 ---------------
|
||||
1 file changed, 15 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -215,7 +215,6 @@ sub get_env_list
|
||||
my $p_ref_list = shift();
|
||||
my @res ;
|
||||
my %res_hash;
|
||||
- my @t_arr;
|
||||
|
||||
@res = </sys/bus/ccw/drivers/zfcp/*.*.*/0x*>;
|
||||
return () if (!@res);
|
||||
@@ -226,20 +225,6 @@ sub get_env_list
|
||||
next if (@$p_ref_list && "@$p_ref_list" !~ /$p/);
|
||||
push @{ $res_hash{$a} }, $p;
|
||||
}
|
||||
- foreach my $a (sort @$a_ref_list) {
|
||||
- if ("@{[keys %res_hash]}" !~ /$a/) {
|
||||
- print "\tNo valid combination found for adapter '$a'. ",
|
||||
- "Removing from resource list.\n";
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- push @t_arr, map { @{$res_hash{$_}} } keys %res_hash;
|
||||
- foreach my $p (@$p_ref_list) {
|
||||
- if ("@t_arr" !~ /$p/) {
|
||||
- print "\tNo valid combination found for port '$p'. ",
|
||||
- "Removing from resource list.\n";
|
||||
- }
|
||||
- }
|
||||
|
||||
if (!%res_hash) {
|
||||
print "$PROGRAM_NAME: Adapter and/or port filter(s) did not match anything\n";
|
@ -1,111 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: do not scan (all) if filters match nothing
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: 398f9ceac8c20705f573671bde4bc482967f5c13
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: do not scan (all) if filters match nothing
|
||||
|
||||
Fix the following undesired behavior of lsluns to scan all resources if the
|
||||
user provided filters did not match anything:
|
||||
|
||||
No valid combination found for adapter '5080'. Removing from resource
|
||||
list.
|
||||
No valid parameters left, using all available resources in system.
|
||||
Scanning for LUNs on adapter 0.0.5080
|
||||
...
|
||||
|
||||
Scanning can be resource consumptive. So if a user already wants to filter,
|
||||
possibly to reduce resource consumption, he does not want to happen to scan
|
||||
everything and thus consume the worst case of resources.
|
||||
|
||||
Instead print a message to inform the user why nothing was scanned.
|
||||
|
||||
Reported-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Reviewed-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -219,7 +219,6 @@ sub get_env_list
|
||||
|
||||
@res = </sys/bus/ccw/drivers/zfcp/*.*.*/0x*>;
|
||||
return () if (!@res);
|
||||
-reload:
|
||||
foreach my $entry (@res) {
|
||||
my $a = ${[split('/', $entry)]}[-2];
|
||||
my $p = ${[split('/', $entry)]}[-1];
|
||||
@@ -243,12 +242,7 @@ reload:
|
||||
}
|
||||
|
||||
if (!%res_hash) {
|
||||
- print "\nNo valid parameters left, ",
|
||||
- "using all available resources in system.\n\n";
|
||||
- @$a_ref_list = ();
|
||||
- @$p_ref_list = ();
|
||||
- @t_arr = ();
|
||||
- goto reload;
|
||||
+ print "$PROGRAM_NAME: Adapter and/or port filter(s) did not match anything\n";
|
||||
}
|
||||
return %res_hash;
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: document restriction to zfcp-only systems
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: 55f0b001d15b3984967e7f87d6118232078e3fe5
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: document restriction to zfcp-only systems
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 4 ++++
|
||||
zconf/lsluns.8 | 8 ++++++--
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -170,6 +170,10 @@ sub get_lun_hash
|
||||
sub lsluns_usage {
|
||||
print <<EOD;
|
||||
Usage:
|
||||
+This tool is designed for environments where all SCSI devices are attached
|
||||
+through the zfcp device driver. Expect error messages in mixed environments
|
||||
+such as with iSCSI.
|
||||
+
|
||||
$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
List LUNs discovered in the Fibre Channel (FC) Storage Area Network (SAN).
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -4,8 +4,8 @@
|
||||
.\"
|
||||
.TH LSLUNS 8 "2017-02-17" "s390-tools"
|
||||
.SH NAME
|
||||
-lsluns \- list LUNs discovered in the FC SAN, or show encryption state of
|
||||
-attached LUNs
|
||||
+lsluns \- list LUNs discovered in the FC SAN through zfcp, or show encryption state of
|
||||
+zfcp-attached LUNs
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B lsluns
|
||||
@@ -28,6 +28,10 @@ attached LUNs
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
+This tool is designed for environments where all SCSI devices are attached
|
||||
+through the zfcp device driver. Expect error messages in mixed environments
|
||||
+such as with iSCSI.
|
||||
+
|
||||
.B lsluns
|
||||
lists all logical unit numbers (LUNs) discovered in the
|
||||
Fibre Channel (FC) Storage Area Network (SAN).
|
@ -1,283 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: enhance usage statement and man page
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: e748fff3479f8f4ae7e8262b4913f6d08ff78f66
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: enhance usage statement and man page
|
||||
|
||||
The wording in the lsluns usage statement and man page was misleading
|
||||
in several aspects:
|
||||
|
||||
* lsluns does not list all LUNs, just those discovered in the FC SAN
|
||||
* lsluns -a should only be used to display the LUN encryption status
|
||||
|
||||
Fix filter option arguments. Clarify filter option usage. Refer to
|
||||
lszfcp and lsscsi.
|
||||
|
||||
Reported-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Reviewed-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 45 +++++++++++++++------------
|
||||
zconf/lsluns.8 | 93 +++++++++++++++++++++++++++++++++++++++------------------
|
||||
2 files changed, 91 insertions(+), 47 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
-# lsluns - Tool to list all available LUNs
|
||||
+# lsluns - list LUNs discovered in the FC SAN, or show encryption state of attached LUNs
|
||||
#
|
||||
# Copyright IBM Corp. 2008, 2017
|
||||
#
|
||||
@@ -169,32 +169,39 @@ sub get_lun_hash
|
||||
|
||||
sub lsluns_usage {
|
||||
print <<EOD;
|
||||
-Usage: $PROGRAM_NAME [<options>]
|
||||
+Usage:
|
||||
+$PROGRAM_NAME [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
- lsluns provides information for LUNs.
|
||||
+ List LUNs discovered in the Fibre Channel (FC) Storage Area Network (SAN).
|
||||
+ This causes extra SAN traffic for each target port WWPN.
|
||||
|
||||
- The default is to list all LUNs that are available via the attached ports.
|
||||
- The display can be limited by specifying an adapter or a port.
|
||||
+$PROGRAM_NAME -a [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
+
|
||||
+ Show encryption state of the attached LUNs.
|
||||
+ This causes extra SAN traffic for each attached LUN.
|
||||
+
|
||||
+For all other uses, such as listing attached LUNs or properties other than
|
||||
+encryption, use other tools such as "lszfcp -D" or "lsscsi -tv".
|
||||
+
|
||||
+Limit the listing by specifying one or more adapters (FCP device
|
||||
+bus-IDs) or target port WWPNs or both.
|
||||
|
||||
Options:
|
||||
- -a, --active
|
||||
- Shows all activated LUNs.
|
||||
- In addition LUN encryption information is provided.
|
||||
- e.g. "lsluns -a"
|
||||
-
|
||||
- -c, --ccw
|
||||
- Shows LUNs for a specific ccw device.
|
||||
- e.g. "lsluns -c 0.0.3922"
|
||||
-
|
||||
- -p, --port
|
||||
- Shows LUNs for a specific port.
|
||||
- e.g. "lsluns -p 0x5005123456789000"
|
||||
+ -c <busid>, --ccw <busid>
|
||||
+ Filter LUNs by adapter with the specified FCP device bus-ID. Can be
|
||||
+ specified multiple times.
|
||||
+ For example: "$PROGRAM_NAME -c 0.0.3922"
|
||||
+
|
||||
+ -p <wwpn>, --port <wwpn>
|
||||
+ Filter LUNs by target port with the specified WWPN. Can be specified
|
||||
+ multiple times.
|
||||
+ For example: "$PROGRAM_NAME -p 0x5005123456789000"
|
||||
|
||||
-h, --help
|
||||
- Print help message and exit.
|
||||
+ Print help message and exit.
|
||||
|
||||
-v, --version
|
||||
- Display version info and exit.
|
||||
+ Display version information and exit.
|
||||
EOD
|
||||
exit 0;
|
||||
}
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -2,61 +2,93 @@
|
||||
.\" 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 LSLUNS 8 "June 2008" "s390-tools"
|
||||
+.TH LSLUNS 8 "2017-02-17" "s390-tools"
|
||||
.SH NAME
|
||||
-lsluns \- list available LUNs
|
||||
+lsluns \- list LUNs discovered in the FC SAN, or show encryption state of
|
||||
+attached LUNs
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B lsluns
|
||||
+.RB [\| \-c
|
||||
+.IR busid \|]\ .\|.\|.
|
||||
+.RB [\| \-p
|
||||
+.IR wwpn \|]\ .\|.\|.
|
||||
+.\" --active
|
||||
+.br
|
||||
+.B lsluns \-a
|
||||
+.RB [\| \-c
|
||||
+.IR busid \|]\ .\|.\|.
|
||||
+.RB [\| \-p
|
||||
+.IR wwpn \|]\ .\|.\|.
|
||||
+.\" --help and --version
|
||||
+.br
|
||||
+.B lsluns
|
||||
.RB [\| \-h \|]
|
||||
.RB [\| \-v \|]
|
||||
-.RB [\| \-c
|
||||
-.IR adapter\ id:0.0.XXXX \|]\ .\|.\|.
|
||||
-.RB [ \-p
|
||||
-.IR port\ number:0xXXXXXXXXXXXXXXXX \|]\ .\|.\|.
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.B lsluns
|
||||
-does a listing of all available LUNs.
|
||||
-
|
||||
-The default is to list all LUNs that are found. The listing can be
|
||||
-limited by specifying an adapter or a port.
|
||||
+lists all logical unit numbers (LUNs) discovered in the
|
||||
+Fibre Channel (FC) Storage Area Network (SAN).
|
||||
+This causes extra SAN traffic for each target port WWPN.
|
||||
+
|
||||
+.B lsluns -a
|
||||
+shows the encryption state of the attached LUNs.
|
||||
+This causes extra SAN traffic for each attached LUN.
|
||||
+
|
||||
+Limit the listing by specifying one or more adapters (FCP device
|
||||
+bus-IDs) or target port WWPNs or both.
|
||||
+
|
||||
+For all other uses, such as listing attached LUNs or properties other than
|
||||
+encryption, use other tools such as
|
||||
+.B lszfcp \-D
|
||||
+or
|
||||
+.BR "lsscsi \-tv" .
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
+.BR \-a ", " \-\-active
|
||||
+Show the encryption state of the attached LUNs. Encrypted devices are indicated
|
||||
+with a bracketed X immediately following the LUN number.
|
||||
+.TP
|
||||
+.BI \-c\ busid \fR,\ \fB\-\-ccw= busid
|
||||
+Filter LUNs by adapter with the specified FCP device bus-ID. This option can be
|
||||
+specified multiple times. When used in conjunction with \fB\-p\fR, only those
|
||||
+LUNs are listed that also satisfy at least one of the \fB\-p\fR constraints.
|
||||
+.TP
|
||||
+.BI \-p\ wwpn \fR,\ \fB\-\-port= wwpn
|
||||
+Filter LUNs by target port with the specified WWPN. This option can be
|
||||
+specified multiple times. When used in conjunction with \fB\-c\fR, only those
|
||||
+LUNs are listed that also satisfy at least one of the \fB\-c\fR constraints.
|
||||
+.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Print help message and exit.
|
||||
.TP
|
||||
.BR \-v ", " \-\-version
|
||||
-Display version info and exit.
|
||||
-.TP
|
||||
-.BI \-c\ adapter \fR,\ \fB\-\-ccw= adapter
|
||||
-Shows LUNs for a specific adapter.
|
||||
-.TP
|
||||
-.BI \-p\ port \fR,\ \fB\-\-port= port
|
||||
-Shows LUNs for a specific port.
|
||||
-.TP
|
||||
-.BR \-a ", " \-\-active
|
||||
-Shows all activated LUNs. In addition information is provided
|
||||
-whether the LUN is encrypted or not. This is indicated with a bracketed X
|
||||
-right after the LUN number.
|
||||
+Display version information and exit.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B "lsluns"
|
||||
.RS
|
||||
-Shows all available LUNs.
|
||||
+Lists all LUNs discovered in the FC SAN.
|
||||
.RE
|
||||
.TP
|
||||
.BI "lsluns \-c " 0.0.3922
|
||||
-Shows all LUNs found on adapter \fI0.0.3922\fR.
|
||||
+Lists all LUNs discovered in the FC SAN on adapter \fI0.0.3922\fR.
|
||||
.TP
|
||||
.BI "lsluns \-p " 0x5005123456789000
|
||||
-Shows all LUNs for port \fI0x5005123456789000\fR.
|
||||
+Lists all LUNs discovered in the FC SAN on target port
|
||||
+\fI0x5005123456789000\fR.
|
||||
.TP
|
||||
-.BI "lsluns \-c " 0.0.3922 " \-p " 0x5005123456789000
|
||||
-Shows all LUNs for adapter \fI0.0.3922\fR and port \fI0x5005123456789000\fR.
|
||||
+.BI "lsluns \-c " 0.0.3922 " \-c " 0.0.fc00 \
|
||||
+" \-p " 0x5005123456789000 " \-p " 0x5005abcdefabc000
|
||||
+Lists all LUNs discovered in the FC SAN on:
|
||||
+adpater \fI0.0.3922\fR and port \fI0x5005123456789000\fR,
|
||||
+adapter \fI0.0.3922\fR and port \fI0x5005abcdefabc000\fR,
|
||||
+adapter \fI0.0.fc00\fR and port \fI0x5005123456789000\fR, or
|
||||
+adapter \fI0.0.fc00\fR and port \fI0x5005abcdefabc000\fR.
|
||||
.TP
|
||||
.B "lsluns -a"
|
||||
adapter = 0.0.3c02
|
||||
@@ -64,4 +96,9 @@ adapter = 0.0.3c02
|
||||
lun = 0x401040a200000000(X) /dev/sg0 Disk IBM:2107900
|
||||
lun = 0x401040a300000000 /dev/sg1 Disk IBM:2107900
|
||||
|
||||
-Shows all active LUNs including the information whether the device is encrypted or not.
|
||||
+Shows the encryption status of attached LUNs. A bracketed X suffixed to a LUN
|
||||
+indicates that the device is encrypted.
|
||||
+
|
||||
+.SH "SEE ALSO"
|
||||
+.BR lszfcp (8),
|
||||
+.BR lsscsi (8)
|
@ -1,170 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: fix flawed formatting of man page
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: d81c4234295f481559a74fb5ad5f498692ff5738
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: fix flawed formatting of man page
|
||||
|
||||
The formatting in the SYNOPSIS, OPTIONS, and EXAMPLES sections was flawed
|
||||
in the lsluns(8) man page:
|
||||
|
||||
* The comma between short and long options were erroneously formatted in
|
||||
bold, which would indicate to be typed exactly as shown. [see man(1)]
|
||||
|
||||
* The option parameters (e.g. adapter and port) were erroneously formatted
|
||||
in bold instead of italic text (usually displayed as underlined on the
|
||||
console), which would again indicate to be typed exactly as shown instead
|
||||
of to be replaced with the appropriate argument. [see man(1)]
|
||||
|
||||
* Ellipses were missing after the the options that may be specified multiple
|
||||
times (e.g. adapter and port). [see man(1)]
|
||||
|
||||
* Dashes in options in the SYNOPSIS and OPTIONS section needed to be
|
||||
escaped. [see man-pages(7)]
|
||||
|
||||
* User input in example shell sessions should have been formatted in bold.
|
||||
[see man-pages(7)]
|
||||
|
||||
Correct formatting based on man(7) and man-pages(7) man pages as reference.
|
||||
Add proper spacing between options and their surrounding square brackets and
|
||||
between the three periods of ellipses.
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Reviewed-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns.8 | 42 +++++++++++++++++++++++-------------------
|
||||
1 file changed, 23 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -8,12 +8,12 @@ lsluns \- list available LUNs
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B lsluns
|
||||
-.RB [ \-h]
|
||||
-.RB [ \-v]
|
||||
-.RB [ \-c
|
||||
-.IR adapter id:0.0.XXXX ]
|
||||
+.RB [\| \-h \|]
|
||||
+.RB [\| \-v \|]
|
||||
+.RB [\| \-c
|
||||
+.IR adapter\ id:0.0.XXXX \|]\ .\|.\|.
|
||||
.RB [ \-p
|
||||
-.IR port number:0xXXXXXXXXXXXXXXXX ]
|
||||
+.IR port\ number:0xXXXXXXXXXXXXXXXX \|]\ .\|.\|.
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -25,36 +25,40 @@ limited by specifying an adapter or a po
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
-.B -h, --help
|
||||
+.BR \-h ", " \-\-help
|
||||
Print help message and exit.
|
||||
.TP
|
||||
-.B -v, --version
|
||||
+.BR \-v ", " \-\-version
|
||||
Display version info and exit.
|
||||
.TP
|
||||
-.B -c, --ccw
|
||||
+.BI \-c\ adapter \fR,\ \fB\-\-ccw= adapter
|
||||
Shows LUNs for a specific adapter.
|
||||
.TP
|
||||
-.B -p, --port
|
||||
+.BI \-p\ port \fR,\ \fB\-\-port= port
|
||||
Shows LUNs for a specific port.
|
||||
.TP
|
||||
-.B -a, --active
|
||||
+.BR \-a ", " \-\-active
|
||||
Shows all activated LUNs. In addition information is provided
|
||||
whether the LUN is encrypted or not. This is indicated with a bracketed X
|
||||
right after the LUN number.
|
||||
|
||||
.SH EXAMPLES
|
||||
-.PP
|
||||
-.IP "lsluns"
|
||||
+.TP
|
||||
+.B "lsluns"
|
||||
.RS
|
||||
Shows all available LUNs.
|
||||
.RE
|
||||
-.IP "lsluns -c 0.0.3922"
|
||||
-Shows all LUNs found on adapter 0.0.3922.
|
||||
-.IP "lsluns -p 0x5005123456789000"
|
||||
-Shows all LUNs for port 0x5005123456789000.
|
||||
-.IP "lsluns -c 0.0.3922 -p 0x5005123456789000"
|
||||
-Shows all LUNs for adapter 0.0.3922 and port 0x5005123456789000.
|
||||
-.IP "lsluns -a "
|
||||
+.TP
|
||||
+.BI "lsluns \-c " 0.0.3922
|
||||
+Shows all LUNs found on adapter \fI0.0.3922\fR.
|
||||
+.TP
|
||||
+.BI "lsluns \-p " 0x5005123456789000
|
||||
+Shows all LUNs for port \fI0x5005123456789000\fR.
|
||||
+.TP
|
||||
+.BI "lsluns \-c " 0.0.3922 " \-p " 0x5005123456789000
|
||||
+Shows all LUNs for adapter \fI0.0.3922\fR and port \fI0x5005123456789000\fR.
|
||||
+.TP
|
||||
+.B "lsluns -a"
|
||||
adapter = 0.0.3c02
|
||||
port = 0x500507630300c562
|
||||
lun = 0x401040a200000000(X) /dev/sg0 Disk IBM:2107900
|
@ -1,105 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161888] lsluns: point out IBM Storwize configuration requirements
|
||||
From: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
|
||||
Description: lsluns: Fix filter handling and documentation enhancements.
|
||||
Symptom: lsluns lists all LUNs discovered in the FC SAN despite user
|
||||
given filter(s) that do not match anything:
|
||||
# lsluns -c 0.0.5080
|
||||
No valid combination found for adapter '0.0.5080'. Removing
|
||||
from resource list.
|
||||
No valid parameters left, using all available resources in
|
||||
system.
|
||||
Scanning for LUNs on adapter 0.0.5090
|
||||
...
|
||||
|
||||
lsluns prints the message "No valid combination found for
|
||||
{adapter|port} '...'. Removing from resource list." for every
|
||||
adapter and port filter that does not contribute to the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
lsluns is used in unexpected or even unsupported ways.
|
||||
Problem: Scanning can be resource consumptive. So if a user already wants
|
||||
to filter, possibly to reduce resource consumption, he does not
|
||||
want to happen to scan everything and thus consume the worst case
|
||||
of resources.
|
||||
|
||||
The message "No valid combination found for {adapter|port} '...'.
|
||||
Removing from resource list." is potentially confusing. It is
|
||||
unclear which combination is being referred to, especially if
|
||||
only one single adapter or port filter was specified. There is
|
||||
also no differentiation whether the denoted adapter or port
|
||||
exists for its own or not. It just does not exist in the final
|
||||
filtered results.
|
||||
|
||||
The formatting of the lsluns (8) man page is flawed.
|
||||
|
||||
The lsluns usage text and lsluns (8) man page lack the
|
||||
information on the intended use cases, requirements, and
|
||||
restrictions.
|
||||
Solution: Print a message and exit when all filters match nothing.
|
||||
|
||||
Do not print confusing messages when a filter matches nothing.
|
||||
|
||||
Fix man page formatting.
|
||||
|
||||
Enhance usage text and man page. Clarify discovery use case,
|
||||
relation to NPIV and to zfcp auto LUN scan. Point out
|
||||
IBM Storwize configuration requirements. Document restriction to
|
||||
zfcp-only systems.
|
||||
Reproduction: Use lsluns and specify adapter bus-ID and/or target port WWPN
|
||||
filter(s) that do not match anything. Either specify inexistent
|
||||
bus-IDs and/or WWPNs or invalid filter arguments.
|
||||
Upstream-ID: 5f768dd52d87efddbd7efa23d57c6da62281728b
|
||||
Problem-ID: 161888
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lsluns: point out IBM Storwize configuration requirements
|
||||
|
||||
Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
Reviewed-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jens Remus <jremus@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/lsluns | 4 ++++
|
||||
zconf/lsluns.8 | 12 ++++++++++++
|
||||
2 files changed, 16 insertions(+)
|
||||
|
||||
--- a/zconf/lsluns
|
||||
+++ b/zconf/lsluns
|
||||
@@ -177,6 +177,10 @@ $PROGRAM_NAME [-c <busid>] ... [-p <wwpn
|
||||
Discovering LUNs only makes sense for NPIV-enabled FCP devices
|
||||
without zfcp automatic LUN scan. zfcp automatic LUN scan is available
|
||||
as of kernel version 2.6.37, if not disabled with zfcp.allow_lun_scan=0.
|
||||
+ For storage products that do not support a REPORT LUNS
|
||||
+ well-known logical unit (such as IBM Storwize products),
|
||||
+ ensure that LUN 0 represents a valid peripheral device type.
|
||||
+ See the man page for more information.
|
||||
|
||||
$PROGRAM_NAME -a [-c <busid>] ... [-p <wwpn>] ... [-h] [-v]
|
||||
|
||||
--- a/zconf/lsluns.8
|
||||
+++ b/zconf/lsluns.8
|
||||
@@ -64,6 +64,18 @@ If not attached already, lsluns temporar
|
||||
Do not terminate lsluns with a signal. Signals interfere
|
||||
with the removal of temporarily attached LUNs.
|
||||
|
||||
+.TP
|
||||
+Storage Products
|
||||
+Some storage products return a peripheral device type of 31==0x1f
|
||||
+with peripheral qualifier 0 in a SCSI standard INQUIRY command
|
||||
+for an unmapped FCP LUN 0. Examples are: IBM Storwize products,
|
||||
+including IBM V7000, IBM V840, IBM V9000, and IBM SAN Volume Controller.
|
||||
+For lsluns to work with such storage products,
|
||||
+you must have a host mapping on the storage, which maps some volume
|
||||
+to exported FCP LUN 0x0000000000000000 (Storwize host map property "SCSI ID" 0)
|
||||
+for each used FCP-device initiator WWPN. The volume can be
|
||||
+a minimum-sized thin-provisioned shared stand-in volume.
|
||||
+
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-a ", " \-\-active
|
@ -1,71 +0,0 @@
|
||||
Subject: mon_procd: fix parsing of /proc/<pid>/stat
|
||||
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
|
||||
Description: mon_procd: fix parsing of /proc/<pid>/stat
|
||||
Symptom: Wrong data from /proc/<pid>/stat for processes that contain
|
||||
a ")" in their name.
|
||||
Problem: The output of /proc/<pid>/stat will show the process name in
|
||||
parentheses. The parsing code in read_stat() tries to filter
|
||||
out the parentheses, which will go wrong when the process name
|
||||
itself also contains parentheses, e.g. in an output like this:
|
||||
"2421 ((sd-pam)) S 2420 2420 2420 ..."
|
||||
In this case, the first closing parentheses will be taken as
|
||||
end marker, and the sscanf() on the remaining string will
|
||||
silently fail, leaving its values in uninitialized state and
|
||||
producing wrong data.
|
||||
Solution: Use strrchr() instead of strchr() to find the last closing
|
||||
parentheses. Also add return value checking for sscanf() and
|
||||
initialize the values to 0.
|
||||
Reproduction: Use mon_procd on a system with running processes that have a
|
||||
")" in their name, like "(sd-pam)".
|
||||
Upstream-ID: -
|
||||
Problem-ID: 169483
|
||||
|
||||
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
---
|
||||
mon_tools/mon_procd.c | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/mon_tools/mon_procd.c
|
||||
+++ b/mon_tools/mon_procd.c
|
||||
@@ -594,17 +594,18 @@ static void cal_task_pcpu(struct task_t
|
||||
*/
|
||||
static int read_stat(struct task_t *task)
|
||||
{
|
||||
- int ppid, tty, proc;
|
||||
- unsigned long flags, pri, nice;
|
||||
- unsigned long long maj_flt, utime, stime, cutime, cstime;
|
||||
+ unsigned long long maj_flt = 0, utime = 0, stime = 0, cutime = 0,
|
||||
+ cstime = 0;
|
||||
+ unsigned long flags = 0, pri = 0, nice = 0;
|
||||
char *cmd_start, *cmd_end, *cmdlenp, *cmdp;
|
||||
+ int ppid = 0, tty = 0, proc = 0, rc;
|
||||
|
||||
snprintf(fname, sizeof(fname), "/proc/%u/stat", task->pid);
|
||||
if (read_file(fname, buf, sizeof(buf) - 1) == -1)
|
||||
return 0;
|
||||
|
||||
cmd_start = strchr(buf, '(') + 1;
|
||||
- cmd_end = strchr(cmd_start, ')');
|
||||
+ cmd_end = strrchr(cmd_start, ')');
|
||||
name_lens.cmd_len = cmd_end - cmd_start;
|
||||
cmdlenp = mon_record + sizeof(struct monwrite_hdr);
|
||||
cmdlenp += sizeof(struct procd_hdr);
|
||||
@@ -625,7 +626,7 @@ static int read_stat(struct task_t *task
|
||||
memcpy(cmdlenp, &name_lens.cmd_len, sizeof(__u16));
|
||||
|
||||
cmd_end += 2;
|
||||
- sscanf(cmd_end,
|
||||
+ rc = sscanf(cmd_end,
|
||||
"%c %d %*d %*d %d %*d "
|
||||
"%lu %*s %*s %Lu %*s "
|
||||
"%Lu %Lu %Lu %Lu "
|
||||
@@ -642,6 +643,8 @@ static int read_stat(struct task_t *task
|
||||
&utime, &stime, &cutime, &cstime,
|
||||
&pri, &nice,
|
||||
&proc);
|
||||
+ if (rc != 12)
|
||||
+ syslog(LOG_ERR, "bad data in %s \n", fname);
|
||||
task->ppid = (__u32)ppid;
|
||||
task->tty = (__u16)tty;
|
||||
task->flags = (__u32)flags;
|
@ -1,290 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161563] mon_tools: Improve systemctl start error handling
|
||||
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
|
||||
Description: cpuplugd, mon_tools: Improve systemctl start error handling
|
||||
Symptom: "systemctl start cpuplugd/mon_procd/mon_fsstatd" does not
|
||||
report any errors in case the startup fails.
|
||||
Problem: For type=simple, systemd forks/execs the process and if that
|
||||
is successful, it immediately returns. There is no way to
|
||||
find out if the initial startup fails.
|
||||
Solution: Use type=fork and run the process in the background. In this
|
||||
case systemd waits until the initial process returns.
|
||||
In addition, use PIDFile and ensure that the pid file is
|
||||
already available when the initial process returns. To
|
||||
achieve this, use startup synchronization via pipe.
|
||||
Reproduction: Add invalid values to the config files and start the daemons
|
||||
with "systemctl start cpuplugd/mon_procd/mon_fsstatd".
|
||||
Upstream-ID: 780133f825687bc931489aaf13959c793d2a4501
|
||||
Problem-ID: 161563
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
mon_tools: Improve systemctl start error handling
|
||||
|
||||
This fixes the same issue as in commit 82c8148983fc ("cpuplugd: Improve
|
||||
systemctl start error handling") for mon_tools (mon_procd and mon_fsstatd).
|
||||
|
||||
Currently "systemctl start mon_procd/fsstatd" does not report any errors
|
||||
in case the startup fails.
|
||||
|
||||
Example (with mon_procd):
|
||||
|
||||
(change interval in /etc/sysconfig/mon_procd to an invalid value "abc")
|
||||
# systemctl start mon_procd
|
||||
|
||||
The reason is that for type=simple systemd forks/execs mon_procd and if
|
||||
that is successful immediately returns. There is no way to find out if the
|
||||
initial startup fails.
|
||||
|
||||
Fix this by using type=fork and running the process in the background. In
|
||||
this case systemd waits until the initial process returns.
|
||||
|
||||
In addition use PIDFile and ensure that the pid file is already available
|
||||
when the initial process returns. To achieve this, use startup
|
||||
synchronization via pipe. Without that systemd would print the following
|
||||
warning:
|
||||
|
||||
systemd[1]: mon_procd.service: PID file /var/run/mon_procd.pid not readable
|
||||
(yet?) after start: No such file or directory
|
||||
|
||||
With this patch, an early startup error like in the example above, is now
|
||||
reported correctly in "systemctl start":
|
||||
|
||||
# systemctl start mon_procd
|
||||
Job for mon_procd.service failed because the control process exited...
|
||||
See "systemctl status mon_procd.service" and "journalctl -xe" for ...
|
||||
# journalctl -xe | grep mon_procd
|
||||
mon_procd[3184]: Error: Invalid interval (needs to be greater than 0)
|
||||
|
||||
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
---
|
||||
mon_tools/mon_fsstatd.c | 40 ++++++++++++++++++++++++++++++++--------
|
||||
mon_tools/mon_procd.c | 40 ++++++++++++++++++++++++++++++++--------
|
||||
systemd/mon_fsstatd.service.in | 5 +++--
|
||||
systemd/mon_procd.service.in | 5 +++--
|
||||
4 files changed, 70 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/mon_tools/mon_fsstatd.c
|
||||
+++ b/mon_tools/mon_fsstatd.c
|
||||
@@ -90,17 +90,18 @@ static void fsstatd_open_monwriter(void)
|
||||
/*
|
||||
* Store daemon's pid so it can be stopped
|
||||
*/
|
||||
-static void store_pid(void)
|
||||
+static int store_pid(void)
|
||||
{
|
||||
FILE *f = fopen(pid_file, "w");
|
||||
|
||||
if (!f) {
|
||||
syslog(LOG_ERR, "cannot open pid file %s: %s", pid_file,
|
||||
strerror(errno));
|
||||
- exit(1);
|
||||
+ return -1;
|
||||
}
|
||||
fprintf(f, "%d\n", getpid());
|
||||
fclose(f);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -244,41 +245,64 @@ static void fsstatd_write_ent(struct mnt
|
||||
*/
|
||||
static void fsstatd_daemonize(void)
|
||||
{
|
||||
+ int pipe_fds[2], startup_rc = 1;
|
||||
pid_t pid;
|
||||
|
||||
+ if (pipe(pipe_fds) == -1) {
|
||||
+ syslog(LOG_ERR, "pipe error: %s\n", strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
syslog(LOG_ERR, "fork error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
- if (pid > 0)
|
||||
- exit(0);
|
||||
+ if (pid > 0) {
|
||||
+ /* Wait for startup return code from daemon */
|
||||
+ if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
||||
+ syslog(LOG_ERR, "pipe read error: %s\n", strerror(errno));
|
||||
+ /* With startup_rc == 0, pid file was written at this point */
|
||||
+ exit(startup_rc);
|
||||
+ }
|
||||
|
||||
/* Change the file mode mask */
|
||||
umask(0);
|
||||
|
||||
- /* Store daemon pid */
|
||||
- store_pid();
|
||||
/* Catch SIGINT and SIGTERM to clean up pid file on exit */
|
||||
fsstatd_handle_signals();
|
||||
|
||||
/* Create a new SID for the child process */
|
||||
if (setsid() < 0) {
|
||||
syslog(LOG_ERR, "setsid error: %s\n", strerror(errno));
|
||||
- exit(1);
|
||||
+ goto notify_parent;
|
||||
}
|
||||
|
||||
/* Change the current working directory */
|
||||
if (chdir("/") < 0) {
|
||||
syslog(LOG_ERR, "chdir error: %s\n", strerror(errno));
|
||||
- exit(1);
|
||||
+ goto notify_parent;
|
||||
}
|
||||
|
||||
/* Close out the standard file descriptors */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
+
|
||||
+ /* Store daemon pid */
|
||||
+ if (store_pid() < 0)
|
||||
+ goto notify_parent;
|
||||
+ startup_rc = 0;
|
||||
+
|
||||
+notify_parent:
|
||||
+ /* Inform waiting parent about startup return code */
|
||||
+ if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
||||
+ syslog(LOG_ERR, "pipe write error: %s\n", strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if (startup_rc != 0)
|
||||
+ exit(startup_rc);
|
||||
}
|
||||
|
||||
static int fsstatd_do_work(void)
|
||||
--- a/mon_tools/mon_procd.c
|
||||
+++ b/mon_tools/mon_procd.c
|
||||
@@ -109,17 +109,18 @@ static void procd_open_monwriter(void)
|
||||
/*
|
||||
* Store daemon's pid so it can be stopped
|
||||
*/
|
||||
-static void store_pid(void)
|
||||
+static int store_pid(void)
|
||||
{
|
||||
FILE *f = fopen(pid_file, "w");
|
||||
|
||||
if (!f) {
|
||||
syslog(LOG_ERR, "cannot open pid file %s: %s", pid_file,
|
||||
strerror(errno));
|
||||
- exit(1);
|
||||
+ return -1;
|
||||
}
|
||||
fprintf(f, "%d\n", getpid());
|
||||
fclose(f);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -897,41 +898,64 @@ static void read_tasks(void)
|
||||
*/
|
||||
static void procd_daemonize(void)
|
||||
{
|
||||
+ int pipe_fds[2], startup_rc = 1;
|
||||
pid_t pid;
|
||||
|
||||
+ if (pipe(pipe_fds) == -1) {
|
||||
+ syslog(LOG_ERR, "pipe error: %s\n", strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
syslog(LOG_ERR, "fork error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
- if (pid > 0)
|
||||
- exit(0);
|
||||
+ if (pid > 0) {
|
||||
+ /* Wait for startup return code from daemon */
|
||||
+ if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
||||
+ syslog(LOG_ERR, "pipe read error: %s\n", strerror(errno));
|
||||
+ /* With startup_rc == 0, pid file was written at this point */
|
||||
+ exit(startup_rc);
|
||||
+ }
|
||||
|
||||
/* Change the file mode mask */
|
||||
umask(0);
|
||||
|
||||
- /* Store daemon pid */
|
||||
- store_pid();
|
||||
/* Catch SIGINT and SIGTERM to clean up pid file on exit */
|
||||
procd_handle_signals();
|
||||
|
||||
/* Create a new SID for the child process */
|
||||
if (setsid() < 0) {
|
||||
syslog(LOG_ERR, "setsid error: %s\n", strerror(errno));
|
||||
- exit(1);
|
||||
+ goto notify_parent;
|
||||
}
|
||||
|
||||
/* Change the current working directory */
|
||||
if (chdir("/") < 0) {
|
||||
syslog(LOG_ERR, "chdir error: %s\n", strerror(errno));
|
||||
- exit(1);
|
||||
+ goto notify_parent;
|
||||
}
|
||||
|
||||
/* Close out the standard file descriptors */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
+
|
||||
+ /* Store daemon pid */
|
||||
+ if (store_pid() < 0)
|
||||
+ goto notify_parent;
|
||||
+ startup_rc = 0;
|
||||
+
|
||||
+notify_parent:
|
||||
+ /* Inform waiting parent about startup return code */
|
||||
+ if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
||||
+ syslog(LOG_ERR, "pipe write error: %s\n", strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if (startup_rc != 0)
|
||||
+ exit(startup_rc);
|
||||
}
|
||||
|
||||
static int procd_do_work(void)
|
||||
--- a/systemd/mon_fsstatd.service.in
|
||||
+++ b/systemd/mon_fsstatd.service.in
|
||||
@@ -30,10 +30,11 @@ EnvironmentFile=/etc/sysconfig/mon_fssta
|
||||
|
||||
ExecStartPre=-/sbin/modprobe monwriter
|
||||
ExecStartPre=/sbin/udevadm settle --timeout=10
|
||||
-ExecStart=@usrsbin_path@/mon_fsstatd -a -i $FSSTAT_INTERVAL
|
||||
+ExecStart=@usrsbin_path@/mon_fsstatd -i $FSSTAT_INTERVAL
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
-Type=simple
|
||||
+Type=forking
|
||||
+PIDFile=/var/run/mon_fsstatd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
--- a/systemd/mon_procd.service.in
|
||||
+++ b/systemd/mon_procd.service.in
|
||||
@@ -30,10 +30,11 @@ EnvironmentFile=/etc/sysconfig/mon_procd
|
||||
|
||||
ExecStartPre=-/sbin/modprobe monwriter
|
||||
ExecStartPre=/sbin/udevadm settle --timeout=10
|
||||
-ExecStart=@usrsbin_path@/mon_procd -a -i $PROC_INTERVAL
|
||||
+ExecStart=@usrsbin_path@/mon_procd -i $PROC_INTERVAL
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
-Type=simple
|
||||
+Type=forking
|
||||
+PIDFile=/var/run/mon_procd.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,53 +0,0 @@
|
||||
From 2a6a28023bdfe127be68ac605f9a026a82884c80 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Date: Tue, 5 Dec 2017 15:40:23 +0100
|
||||
Subject: [PATCH 1/4] zdev: Enable running chzdev from unknown root devices
|
||||
|
||||
When a persistent device configuration is changed, chzdev tries to
|
||||
find out if it needs to perform additional steps to make this change
|
||||
persistent. If this check fails, for example because the root device
|
||||
is located on a RAM-disk, or on a device type not managed by chzdev,
|
||||
the tool reports an error and exits with non-zero exit code:
|
||||
|
||||
chzdev: Could not determine device that provides /
|
||||
|
||||
or
|
||||
|
||||
chzdev: Could not determine device that provides loop0
|
||||
|
||||
This behavior unnecessarily restricts chzdev from being used in
|
||||
scripted environments like an installation initial RAM-disk.
|
||||
|
||||
Fix this by removing the non-zero exit code and moving the message to
|
||||
verbose output mode only.
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
---
|
||||
zdev/src/root.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/zdev/src/root.c b/zdev/src/root.c
|
||||
index 7f0d39f..668bdbd 100644
|
||||
--- a/zdev/src/root.c
|
||||
+++ b/zdev/src/root.c
|
||||
@@ -35,9 +35,14 @@ exit_code_t root_check(void)
|
||||
/* Get list of devices that provide the root device. */
|
||||
selected = selected_dev_list_new();
|
||||
rc = select_by_path(NULL, selected, config_active, scope_mandatory,
|
||||
- NULL, NULL, PATH_ROOT, err_print);
|
||||
- if (rc)
|
||||
+ NULL, NULL, PATH_ROOT, err_ignore);
|
||||
+ if (rc) {
|
||||
+ /* Running from an unknown root device is not an error. */
|
||||
+ verb("Note: Could not determine if root device configuration "
|
||||
+ "needs to be updated\n");
|
||||
+ rc = 0;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
/* Determine if any of the devices or device types has been modified. */
|
||||
mod = strlist_new();
|
||||
--
|
||||
2.13.6
|
||||
|
@ -1,54 +0,0 @@
|
||||
From 0348a8443e5f15636f86ef2533a7d6e8fa5d936d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Date: Thu, 7 Dec 2017 17:21:11 +0100
|
||||
Subject: [PATCH 4/4] zdev: Fix zdev dracut module aborting on unknown root
|
||||
device
|
||||
|
||||
Running dracut when the root device is not known to zdev (for example
|
||||
because it is located on a virtio block device) will cause the zdev
|
||||
dracut module to incorrectly return an error in the installkernel()
|
||||
function. As a result dracut aborts with an error.
|
||||
|
||||
Fix this by ensuring that the non-zero exit code resulting from lszdev
|
||||
not being able to determine the root device is not passed on to the
|
||||
calling function. Also remove unnecessary error output in this case
|
||||
by leaving the install() function early when the root device is not
|
||||
known to zdev.
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
---
|
||||
zdev/dracut/95zdev/module-setup.sh | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/zdev/dracut/95zdev/module-setup.sh b/zdev/dracut/95zdev/module-setup.sh
|
||||
index 7c67cd7..4c13a65 100644
|
||||
--- a/zdev/dracut/95zdev/module-setup.sh
|
||||
+++ b/zdev/dracut/95zdev/module-setup.sh
|
||||
@@ -29,13 +29,21 @@ depends() {
|
||||
}
|
||||
|
||||
installkernel() {
|
||||
- local _modules=$(lszdev --by-path / --columns MODULES --no-headings)
|
||||
+ local _modules=$(lszdev --by-path / --columns MODULES --no-headings 2>/dev/null)
|
||||
|
||||
+ [ -z "$_modules" ] && return 0
|
||||
[ ! -z "$_modules" ] && instmods $_modules
|
||||
}
|
||||
|
||||
install() {
|
||||
- local _tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
+ local _tempfile
|
||||
+
|
||||
+ # Exit early if root device type is unknown
|
||||
+ if ! lszdev --by-path / >/dev/null 2>&1 ; then
|
||||
+ return 0
|
||||
+ fi
|
||||
+
|
||||
+ _tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
|
||||
if chzdev --export - --persistent --by-path / >/dev/null 2>&1 ; then
|
||||
# Use persistent configuration
|
||||
--
|
||||
2.13.6
|
||||
|
@ -1,67 +0,0 @@
|
||||
From a060dc22db06fb14274b72984ae8db51f00a21cd Mon Sep 17 00:00:00 2001
|
||||
From: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Date: Mon, 13 Nov 2017 12:50:32 +0100
|
||||
Subject: [PATCH] zdev: Use correct path to vmcp binary
|
||||
|
||||
The zdev tools use a hard-coded path to locate the vmcp binary. Since
|
||||
this path may differ between distributions, the vmcp binary may not be
|
||||
successfully located in all cases. Fix this by using the BINDIR macro
|
||||
to determine the correct path. This macro is also used during
|
||||
installation of the vmcp binary itself.
|
||||
|
||||
Reviewed-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
---
|
||||
common.mak | 2 ++
|
||||
include/lib/zt_common.h | 1 +
|
||||
zdev/include/path.h | 2 +-
|
||||
3 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common.mak b/common.mak
|
||||
index b9a9f54..bb6cdf0 100644
|
||||
--- a/common.mak
|
||||
+++ b/common.mak
|
||||
@@ -193,12 +193,14 @@ ALL_CFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||
-DS390_TOOLS_DATADIR=$(TOOLS_DATADIR) \
|
||||
-DS390_TOOLS_SYSCONFDIR=$(SYSCONFDIR) \
|
||||
+ -DS390_TOOLS_BINDIR=$(BINDIR) \
|
||||
$(CFLAGS)
|
||||
CXXFLAGS ?= $(DEFAULT_CFLAGS) $(OPT_FLAGS)
|
||||
ALL_CXXFLAGS = -DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-DS390_TOOLS_LIBDIR=$(TOOLS_LIBDIR) \
|
||||
-DS390_TOOLS_DATADIR=$(TOOLS_DATADIR) \
|
||||
-DS390_TOOLS_SYSCONFDIR=$(SYSCONFDIR) \
|
||||
+ -DS390_TOOLS_BINDIR=$(BINDIR) \
|
||||
$(CXXFLAGS)
|
||||
ALL_CPPFLAGS = -I $(rootdir)include $(CPPFLAGS)
|
||||
ALL_LDFLAGS = $(LDFLAGS)
|
||||
diff --git a/include/lib/zt_common.h b/include/lib/zt_common.h
|
||||
index e27b7b0..c486428 100644
|
||||
--- a/include/lib/zt_common.h
|
||||
+++ b/include/lib/zt_common.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#define RELEASE_STRING STRINGIFY (S390_TOOLS_RELEASE)
|
||||
#define TOOLS_LIBDIR STRINGIFY (S390_TOOLS_LIBDIR)
|
||||
#define TOOLS_SYSCONFDIR STRINGIFY (S390_TOOLS_SYSCONFDIR)
|
||||
+#define TOOLS_BINDIR STRINGIFY (S390_TOOLS_BINDIR)
|
||||
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#define __packed __attribute__((packed))
|
||||
diff --git a/zdev/include/path.h b/zdev/include/path.h
|
||||
index 5252bcf..536ca06 100644
|
||||
--- a/zdev/include/path.h
|
||||
+++ b/zdev/include/path.h
|
||||
@@ -27,7 +27,7 @@
|
||||
#define PATH_PROC "/proc"
|
||||
|
||||
#define PATH_UDEVADM "udevadm"
|
||||
-#define PATH_VMCP "/usr/sbin/vmcp"
|
||||
+#define PATH_VMCP TOOLS_BINDIR "/vmcp"
|
||||
#define PATH_IP "ip"
|
||||
|
||||
#define PATH_ROOT "/"
|
||||
--
|
||||
2.13.6
|
||||
|
@ -1,28 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161467] ziomon: Re-add missing line in ziomon_fcpconf
|
||||
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
Description: ziomon: Re-add missing line in ziomon_fcpconf
|
||||
Symptom: ziomon_fcpconf fails on startup with:
|
||||
Global symbol "$map_dev" requires explicit package name ...
|
||||
Problem: During the GPL to MIT conversion process from v1.39.0 to
|
||||
v2.0.0 one line has been lost by accident.
|
||||
Solution: Re-add that line again.
|
||||
Reproduction: Call the ziomon_fcpconf tool.
|
||||
Upstream-ID: 523d833eb31633673847b6da0edbd35903f14dc4
|
||||
Problem-ID: 161467
|
||||
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
---
|
||||
ziomon/ziomon_fcpconf | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/ziomon/ziomon_fcpconf
|
||||
+++ b/ziomon/ziomon_fcpconf
|
||||
@@ -58,6 +58,7 @@ sub store_mapper_devices
|
||||
my $src_dir = shift();
|
||||
my @entries = grep { ! /^\./ } dir_content($src_dir);
|
||||
|
||||
+ foreach my $map_dev (@entries) {
|
||||
my $tf = catfile($src_dir, "$map_dev");
|
||||
my $mm = `stat -L -c%t:%T $tf`;
|
||||
chomp($mm);
|
@ -1,29 +0,0 @@
|
||||
Subject: [PATCH] [BZ 161183] zipl: remove invalid dasdview command line option
|
||||
From: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
Description: zipl: remove invalid dasdview command line option
|
||||
Symptom: zipl does not work when used with a lvm or device mapper
|
||||
target.
|
||||
Problem: The zipl_helper.device-mapper script uses dasdview with
|
||||
an option "-f" that has been removed recently.
|
||||
Solution: Remove "-f" from the dasdview call.
|
||||
Reproduction: Run zipl on a lvm target.
|
||||
Upstream-ID: -
|
||||
Problem-ID: 161183
|
||||
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
---
|
||||
zipl/src/zipl_helper.device-mapper | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/zipl/src/zipl_helper.device-mapper
|
||||
+++ b/zipl/src/zipl_helper.device-mapper
|
||||
@@ -623,7 +623,7 @@ sub get_dasd_info($)
|
||||
my $type;
|
||||
local *HANDLE;
|
||||
|
||||
- open(HANDLE, "$dasdview -x -f $dev 2>/dev/null|") or
|
||||
+ open(HANDLE, "$dasdview -x $dev 2>/dev/null|") or
|
||||
# dasdview returned with an error
|
||||
return undef;
|
||||
while (<HANDLE>) {
|
@ -1,506 +0,0 @@
|
||||
Subject: zkey: Add properties file handling routines
|
||||
From: Philipp Rudo <prudo@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Add support of protected key crypto for dm-crypt.
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
plain format by providing a tool to manage a key repository
|
||||
allowing to associate secure keys with disk partitions or logical
|
||||
volumes.
|
||||
Upstream-ID: 340da73bb7f06a9fc2aecfe4e33f1f3a17b3568d
|
||||
Problem-ID: SEC1800
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Add properties file handling routines
|
||||
|
||||
In preparation for a new feature, introduce property file
|
||||
handling routines. A property file stores key value pairs
|
||||
in a text file. Optionally a hash of all keys and values
|
||||
contained in the properties file can be generated to
|
||||
ensure integrity of the properties file and to detect
|
||||
manual modifications.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
|
||||
---
|
||||
zkey/Makefile | 5
|
||||
zkey/properties.c | 409 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
zkey/properties.h | 36 ++++
|
||||
3 files changed, 448 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/zkey/Makefile
|
||||
+++ b/zkey/Makefile
|
||||
@@ -1,15 +1,16 @@
|
||||
include ../common.mak
|
||||
|
||||
CPPFLAGS += -I../include
|
||||
-LDLIBS += -ldl
|
||||
+LDLIBS += -ldl -lcrypto
|
||||
|
||||
all: zkey
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
zkey.o: zkey.c pkey.h misc.h
|
||||
+properties.o: properties.c properties.h
|
||||
|
||||
-zkey: zkey.o $(libs)
|
||||
+zkey: zkey.o properties.o $(libs)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||
--- /dev/null
|
||||
+++ b/zkey/properties.c
|
||||
@@ -0,0 +1,409 @@
|
||||
+/*
|
||||
+ * zkey - Generate, re-encipher, and validate secure keys
|
||||
+ *
|
||||
+ * Properties file handling functions
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 2018
|
||||
+ *
|
||||
+ * s390-tools is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the MIT license. See LICENSE for details.
|
||||
+ */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <openssl/evp.h>
|
||||
+
|
||||
+#include "lib/util_libc.h"
|
||||
+#include "lib/util_list.h"
|
||||
+#include "lib/util_panic.h"
|
||||
+
|
||||
+#include "properties.h"
|
||||
+
|
||||
+struct properties {
|
||||
+ struct util_list list;
|
||||
+};
|
||||
+
|
||||
+struct property {
|
||||
+ struct util_list_node node;
|
||||
+ char *name;
|
||||
+ char *value;
|
||||
+};
|
||||
+
|
||||
+#define SHA256_DIGEST_LEN 32
|
||||
+#define INTEGRITY_KEY_NAME "__hash__"
|
||||
+
|
||||
+#define RESTRICTED_PROPERTY_NAME_CHARS "=\n"
|
||||
+#define RESTRICTED_PROPERTY_VALUE_CHARS "\n"
|
||||
+
|
||||
+static int openssl_initialized;
|
||||
+
|
||||
+/**
|
||||
+ * Allocate and initialize a SHA-256 context
|
||||
+ *
|
||||
+ * @returns a SHA context
|
||||
+ */
|
||||
+static EVP_MD_CTX *sha256_init(void)
|
||||
+{
|
||||
+ EVP_MD_CTX *ctx;
|
||||
+ int rc;
|
||||
+
|
||||
+ if (!openssl_initialized) {
|
||||
+ OpenSSL_add_all_algorithms();
|
||||
+ openssl_initialized = 1;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_MD_CTX_create();
|
||||
+ util_assert(ctx != NULL,
|
||||
+ "Internal error: OpenSSL MD context allocation failed");
|
||||
+
|
||||
+ rc = EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
|
||||
+ util_assert(rc == 1, "Internal error: SHA-256 digest init failed");
|
||||
+
|
||||
+ return ctx;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Add data to the SHA-256 context
|
||||
+ *
|
||||
+ * @parm[in] ctx the SHA context
|
||||
+ * @parm[in] data the data to be hashed
|
||||
+ * @parm[in] data_len the length of the data
|
||||
+ */
|
||||
+static void sha256_update(EVP_MD_CTX *ctx,
|
||||
+ const char *data, unsigned int data_len)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ util_assert(ctx != NULL, "Internal error: OpenSSL MD context is NULL");
|
||||
+ util_assert(data != NULL || data_len == 0,
|
||||
+ "Internal error: data is NULL");
|
||||
+
|
||||
+ rc = EVP_DigestUpdate(ctx, data, data_len);
|
||||
+
|
||||
+ util_assert(rc == 1, "Internal error: SHA-256 digest udpdate failed");
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Produce the digest for the SHA-256 context and free the context
|
||||
+ *
|
||||
+ * @parm[in] ctx the SHA context
|
||||
+ * @parm[out] digest a buffer where the digest is stored
|
||||
+ * @parm[in/out] digest_len on entry, *digest_len contains the size of the
|
||||
+ * digest buffer, which must be large enough to hold
|
||||
+ * a SHA-256 digest (32 bytes),
|
||||
+ * on exit it contains the size of the digest
|
||||
+ * returned in the buffer.
|
||||
+ */
|
||||
+static void sha256_final(EVP_MD_CTX *ctx,
|
||||
+ unsigned char *digest, unsigned int *digest_len)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ util_assert(ctx != NULL, "Internal error: OpenSSL MD context is NULL");
|
||||
+
|
||||
+ if (digest != NULL && digest_len != NULL) {
|
||||
+ util_assert(*digest_len >= (unsigned int)EVP_MD_CTX_size(ctx),
|
||||
+ "Internal error: digest_len is too small");
|
||||
+
|
||||
+ rc = EVP_DigestFinal_ex(ctx, digest, digest_len);
|
||||
+ util_assert(rc == 1,
|
||||
+ "Internal error: SHA-256 digest final failed");
|
||||
+ }
|
||||
+
|
||||
+ EVP_MD_CTX_destroy(ctx);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Allocates a new properties object
|
||||
+ *
|
||||
+ * @returns the properties object
|
||||
+ */
|
||||
+struct properties *properties_new(void)
|
||||
+{
|
||||
+ struct properties *properties;
|
||||
+
|
||||
+ properties = util_zalloc(sizeof(struct properties));
|
||||
+
|
||||
+ util_list_init_offset(&properties->list,
|
||||
+ offsetof(struct property, node));
|
||||
+ return properties;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Frees a properties object with all its properties
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ */
|
||||
+void properties_free(struct properties *properties)
|
||||
+{
|
||||
+ struct property *property;
|
||||
+
|
||||
+ util_assert(properties != NULL, "Internal error: properties is NULL");
|
||||
+
|
||||
+ while ((property = util_list_start(&properties->list)) != NULL) {
|
||||
+ free(property->name);
|
||||
+ free(property->value);
|
||||
+ util_list_remove(&properties->list, property);
|
||||
+ }
|
||||
+
|
||||
+ free(properties);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Find a property by its name in the list iof properties
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ * @param[in] name the name of the property to find
|
||||
+ *
|
||||
+ * @returns a pointer to the proerty when it has been found, or NULL if not
|
||||
+ */
|
||||
+static struct property *properties_find(struct properties *properties,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct property *property;
|
||||
+
|
||||
+ property = util_list_start(&properties->list);
|
||||
+ while (property != NULL) {
|
||||
+ if (strcmp(property->name, name) == 0)
|
||||
+ return property;
|
||||
+ property = util_list_next(&properties->list, property);
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Adds or updates a property
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ * @param[in] name the name of the property
|
||||
+ * @param[in] value the value of the property
|
||||
+ *
|
||||
+ * @returns 0 on success,
|
||||
+ * -EINVAL if the name or value contains invalid characters
|
||||
+ */
|
||||
+int properties_set(struct properties *properties,
|
||||
+ const char *name, const char *value)
|
||||
+{
|
||||
+ struct property *property;
|
||||
+
|
||||
+ util_assert(properties != NULL, "Internal error: properties is NULL");
|
||||
+ util_assert(name != NULL, "Internal error: name is NULL");
|
||||
+ util_assert(value != NULL, "Internal error: value is NULL");
|
||||
+
|
||||
+ if (strpbrk(name, RESTRICTED_PROPERTY_NAME_CHARS) != NULL)
|
||||
+ return -EINVAL;
|
||||
+ if (strpbrk(value, RESTRICTED_PROPERTY_VALUE_CHARS) != NULL)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ property = properties_find(properties, name);
|
||||
+ if (property != NULL) {
|
||||
+ free(property->value);
|
||||
+ property->value = util_strdup(value);
|
||||
+ } else {
|
||||
+ property = util_zalloc(sizeof(struct property));
|
||||
+ property->name = util_strdup(name);
|
||||
+ property->value = util_strdup(value);
|
||||
+ util_list_add_tail(&properties->list, property);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Gets a property
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ * @param[in] name the name of the property
|
||||
+ *
|
||||
+ * @returns a string containing the property value, or NULL if the property
|
||||
+ * was not found.
|
||||
+ * Note: The returned string must be freed via free() by the caller.
|
||||
+ */
|
||||
+char *properties_get(struct properties *properties, const char *name)
|
||||
+{
|
||||
+ struct property *property;
|
||||
+
|
||||
+ util_assert(properties != NULL, "Internal error: properties is NULL");
|
||||
+ util_assert(name != NULL, "Internal error: name is NULL");
|
||||
+
|
||||
+ property = properties_find(properties, name);
|
||||
+ if (property == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return util_strdup(property->value);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Removes a property
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ * @param[in] name the name of the property
|
||||
+ *
|
||||
+ * @returns 0 on success, -ENOENT if the property was not found.
|
||||
+ */
|
||||
+int properties_remove(struct properties *properties, const char *name)
|
||||
+{
|
||||
+ struct property *property;
|
||||
+
|
||||
+ util_assert(properties != NULL, "Internal error: properties is NULL");
|
||||
+ util_assert(name != NULL, "Internal error: name is NULL");
|
||||
+
|
||||
+ property = properties_find(properties, name);
|
||||
+ if (property == NULL)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ free(property->name);
|
||||
+ free(property->value);
|
||||
+ util_list_remove(&properties->list, property);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Saves the properties to a file
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ * @param[in] filename the file name
|
||||
+ * @param[in] check_integrity if TRUE, an hash of the key and values is
|
||||
+ * stored as part of the file.
|
||||
+ *
|
||||
+ * @returns 0 on success, -EIO the file could not be created
|
||||
+ */
|
||||
+int properties_save(struct properties *properties, const char *filename,
|
||||
+ bool check_integrity)
|
||||
+{
|
||||
+ char digest_hex[SHA256_DIGEST_LEN * 2 + 1];
|
||||
+ unsigned char digest[SHA256_DIGEST_LEN];
|
||||
+ unsigned int digest_len = sizeof(digest);
|
||||
+ struct property *property;
|
||||
+ EVP_MD_CTX *ctx = NULL;
|
||||
+ unsigned int i;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ util_assert(properties != NULL, "Internal error: properties is NULL");
|
||||
+ util_assert(filename != NULL, "Internal error: filename is NULL");
|
||||
+
|
||||
+ fp = fopen(filename, "w");
|
||||
+ if (fp == NULL)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (check_integrity)
|
||||
+ ctx = sha256_init();
|
||||
+
|
||||
+ property = util_list_start(&properties->list);
|
||||
+ while (property != NULL) {
|
||||
+ fprintf(fp, "%s=%s\n", property->name, property->value);
|
||||
+
|
||||
+ if (check_integrity) {
|
||||
+ sha256_update(ctx, property->name,
|
||||
+ strlen(property->name));
|
||||
+ sha256_update(ctx, property->value,
|
||||
+ strlen(property->value));
|
||||
+ }
|
||||
+
|
||||
+ property = util_list_next(&properties->list, property);
|
||||
+ }
|
||||
+
|
||||
+ if (check_integrity) {
|
||||
+ sha256_final(ctx, digest, &digest_len);
|
||||
+ util_assert(digest_len <= SHA256_DIGEST_LEN,
|
||||
+ "Internal error: digest length too long");
|
||||
+
|
||||
+ for (i = 0; i < digest_len; i++)
|
||||
+ sprintf(&digest_hex[i * 2], "%02x", digest[i]);
|
||||
+ digest_hex[digest_len * 2] = '\0';
|
||||
+
|
||||
+ fprintf(fp, "%s=%s\n", INTEGRITY_KEY_NAME, digest_hex);
|
||||
+ }
|
||||
+
|
||||
+ fclose(fp);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Loads the properties from a file
|
||||
+ *
|
||||
+ * @param[in] properties the properties object
|
||||
+ * @param[in] filename the file name
|
||||
+ * @param[in] check_integrity if TRUE, an hash of the key and values is
|
||||
+ * compared with the hash stored as part of the file.
|
||||
+ *
|
||||
+ * @returns 0 on success, -EIO the file could not be created,
|
||||
+ * -EPERM in case of a syntax error or an integrity error
|
||||
+ */
|
||||
+int properties_load(struct properties *properties, const char *filename,
|
||||
+ bool check_integrity)
|
||||
+{
|
||||
+ char digest_hex[SHA256_DIGEST_LEN * 2 + 1];
|
||||
+ unsigned char digest[SHA256_DIGEST_LEN];
|
||||
+ unsigned int digest_len = sizeof(digest);
|
||||
+ char *digest_read = NULL;
|
||||
+ EVP_MD_CTX *ctx = NULL;
|
||||
+ char line[4096];
|
||||
+ unsigned int len, i;
|
||||
+ int rc = 0;
|
||||
+ char *ch;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ util_assert(properties != NULL, "Internal error: properties is NULL");
|
||||
+ util_assert(filename != NULL, "Internal error: filename is NULL");
|
||||
+
|
||||
+ fp = fopen(filename, "r");
|
||||
+ if (fp == NULL)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (check_integrity)
|
||||
+ ctx = sha256_init();
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
+ len = strlen(line);
|
||||
+ if (line[len-1] == '\n')
|
||||
+ line[len-1] = '\0';
|
||||
+ ch = strchr(line, '=');
|
||||
+ if (ch == NULL) {
|
||||
+ rc = -EPERM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ *ch = '\0';
|
||||
+ ch++;
|
||||
+
|
||||
+ if (check_integrity) {
|
||||
+ if (strcmp(line, INTEGRITY_KEY_NAME) == 0) {
|
||||
+ digest_read = util_strdup(ch);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ sha256_update(ctx, line, strlen(line));
|
||||
+ sha256_update(ctx, ch, strlen(ch));
|
||||
+ }
|
||||
+
|
||||
+ properties_set(properties, line, ch);
|
||||
+ }
|
||||
+
|
||||
+ if (check_integrity) {
|
||||
+ sha256_final(ctx, digest, &digest_len);
|
||||
+ ctx = NULL;
|
||||
+ util_assert(digest_len <= SHA256_DIGEST_LEN,
|
||||
+ "Internal error: digest length too long");
|
||||
+
|
||||
+ for (i = 0; i < digest_len; i++)
|
||||
+ sprintf(&digest_hex[i * 2], "%02x", digest[i]);
|
||||
+ digest_hex[digest_len * 2] = '\0';
|
||||
+
|
||||
+ if (digest_read == NULL ||
|
||||
+ strcmp(digest_hex, digest_read) != 0) {
|
||||
+ rc = -EPERM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ if (ctx != NULL)
|
||||
+ sha256_final(ctx, NULL, NULL);
|
||||
+ if (digest_read != NULL)
|
||||
+ free(digest_read);
|
||||
+ fclose(fp);
|
||||
+ return rc;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/zkey/properties.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * zkey - Generate, re-encipher, and validate secure keys
|
||||
+ *
|
||||
+ * Properties file handling functions
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 2018
|
||||
+ *
|
||||
+ * s390-tools is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the MIT license. See LICENSE for details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef PROPFILE_H
|
||||
+#define PROPFILE_H
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+struct properties;
|
||||
+
|
||||
+struct properties *properties_new(void);
|
||||
+
|
||||
+void properties_free(struct properties *properties);
|
||||
+
|
||||
+int properties_set(struct properties *properties,
|
||||
+ const char *name, const char *value);
|
||||
+
|
||||
+char *properties_get(struct properties *properties, const char *name);
|
||||
+
|
||||
+int properties_remove(struct properties *properties, const char *name);
|
||||
+
|
||||
+int properties_save(struct properties *properties, const char *filename,
|
||||
+ bool check_integrity);
|
||||
+
|
||||
+int properties_load(struct properties *properties, const char *filename,
|
||||
+ bool check_integrity);
|
||||
+
|
||||
+#endif
|
@ -1,89 +0,0 @@
|
||||
Subject: zkey: Add build dependency to OpenSSL (libcrypto)
|
||||
From: Philipp Rudo <prudo@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Add support of protected key crypto for dm-crypt.
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
plain format by providing a tool to manage a key repository
|
||||
allowing to associate secure keys with disk partitions or logical
|
||||
volumes.
|
||||
Upstream-ID: 5e24f74fdefc5fe7d315df080832f1b059485f0f
|
||||
Problem-ID: SEC1800
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Add build dependency to OpenSSL (libcrypto)
|
||||
|
||||
The integrity support for the properties file routines use
|
||||
SHA-256 to build a hash of the keys and values of a property file.
|
||||
The codes uses the EVP_DigestInit_ex, EVP_DigestUpdate, and
|
||||
EVP_DigestFinal from the libcrypto library (OpenSSL).
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
|
||||
---
|
||||
README.md | 6 ++++++
|
||||
zkey/Makefile | 21 ++++++++++++++++++++-
|
||||
2 files changed, 26 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -263,6 +263,7 @@ build options:
|
||||
| ncurses | `HAVE_NCURSES` | hyptop |
|
||||
| pfm | `HAVE_PFM` | cpacfstats |
|
||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||
+| openssl | `HAVE_OPENSSL` | zkey |
|
||||
|
||||
This table lists additional build or install options:
|
||||
|
||||
@@ -365,3 +366,8 @@ the different tools are provided:
|
||||
For running znetconf these programs are required:
|
||||
- modprobe (kmod)
|
||||
- vmcp (s390-tools)
|
||||
+
|
||||
+* zkey:
|
||||
+ For building the zkey tools you need openssl version 0.9.7 or newer installed
|
||||
+ (openssl-devel.rpm). Tip: you may skip the zkey build by adding
|
||||
+ `HAVE_OPENSSL=0` to the make invocation.
|
||||
--- a/zkey/Makefile
|
||||
+++ b/zkey/Makefile
|
||||
@@ -1,9 +1,26 @@
|
||||
include ../common.mak
|
||||
|
||||
+ifeq (${HAVE_OPENSSL},0)
|
||||
+
|
||||
+all:
|
||||
+ $(SKIP) HAVE_OPENSSL=0
|
||||
+
|
||||
+install:
|
||||
+ $(SKIP) HAVE_OPENSSL=0
|
||||
+
|
||||
+else
|
||||
+
|
||||
+check_dep:
|
||||
+ $(call check_dep, \
|
||||
+ "zkey", \
|
||||
+ "openssl/evp.h", \
|
||||
+ "openssl-devel", \
|
||||
+ "HAVE_OPENSSL=0")
|
||||
+
|
||||
CPPFLAGS += -I../include
|
||||
LDLIBS += -ldl -lcrypto
|
||||
|
||||
-all: zkey
|
||||
+all: check_dep zkey
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
@@ -18,6 +35,8 @@ install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
+endif
|
||||
+
|
||||
clean:
|
||||
rm -f *.o zkey
|
||||
|
@ -1,276 +0,0 @@
|
||||
Subject: zkey: Add helper functions for comma separated string handling
|
||||
From: Philipp Rudo <prudo@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Add support of protected key crypto for dm-crypt.
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
plain format by providing a tool to manage a key repository
|
||||
allowing to associate secure keys with disk partitions or logical
|
||||
volumes.
|
||||
Upstream-ID: a090a1ffe8bc780059ebed99f19d32a2a6a3426d
|
||||
Problem-ID: SEC1800
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Add helper functions for comma separated string handling
|
||||
|
||||
Comma separated strings are used in property values to store
|
||||
multiple values in one property. These helper functions allow to
|
||||
work with such comma separated strings.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
|
||||
---
|
||||
zkey/properties.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
zkey/properties.h | 12 +++
|
||||
2 files changed, 226 insertions(+)
|
||||
|
||||
--- a/zkey/properties.c
|
||||
+++ b/zkey/properties.c
|
||||
@@ -38,6 +38,8 @@ struct property {
|
||||
#define RESTRICTED_PROPERTY_NAME_CHARS "=\n"
|
||||
#define RESTRICTED_PROPERTY_VALUE_CHARS "\n"
|
||||
|
||||
+#define RESTRICTED_STR_LIST_CHARS ",\n"
|
||||
+
|
||||
static int openssl_initialized;
|
||||
|
||||
/**
|
||||
@@ -407,3 +409,215 @@ out:
|
||||
fclose(fp);
|
||||
return rc;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * Combines a list of strings into one comma separated string
|
||||
+ *
|
||||
+ * @param[in] strings zero terminated array of pointers to C-strings
|
||||
+ *
|
||||
+ * @returns a new string. This must be freed by the caller when no longer used.
|
||||
+ * returns NULL if a string contains an invalid character.
|
||||
+ */
|
||||
+char *str_list_combine(const char **strings)
|
||||
+{
|
||||
+ unsigned int i, size;
|
||||
+ char *str;
|
||||
+
|
||||
+ util_assert(strings != NULL, "Internal error: strings is NULL");
|
||||
+
|
||||
+ for (i = 0, size = 0; strings[i] != NULL; i++) {
|
||||
+ if (strpbrk(strings[i], RESTRICTED_STR_LIST_CHARS) != NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (i > 0)
|
||||
+ size += 1;
|
||||
+ size += strlen(strings[i]);
|
||||
+ }
|
||||
+
|
||||
+ str = util_zalloc(size + 1);
|
||||
+ for (i = 0, size = 0; strings[i] != NULL; i++) {
|
||||
+ if (i > 0)
|
||||
+ strcat(str, ",");
|
||||
+ strcat(str, strings[i]);
|
||||
+ }
|
||||
+
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Splits a comma separated string into its parts
|
||||
+ *
|
||||
+ * @param[in] str_list the comma separated string
|
||||
+ *
|
||||
+ * @returns a zero terminated array of pointers to C-strings. This array
|
||||
+ * and all individual C-Strings need to be freed bay the caller when
|
||||
+ * no longer used. This can be done using str_list_free_string_array().
|
||||
+ */
|
||||
+char **str_list_split(const char *str_list)
|
||||
+{
|
||||
+ unsigned int i, count;
|
||||
+ char **list;
|
||||
+ char *copy;
|
||||
+ char *tok;
|
||||
+
|
||||
+ util_assert(str_list != NULL, "Internal error: str_list is NULL");
|
||||
+
|
||||
+ count = str_list_count(str_list);
|
||||
+ list = util_zalloc((count + 1) * sizeof(char *));
|
||||
+
|
||||
+ copy = util_strdup(str_list);
|
||||
+ tok = strtok(copy, ",");
|
||||
+ i = 0;
|
||||
+ while (tok != NULL) {
|
||||
+ list[i] = util_strdup(tok);
|
||||
+ i++;
|
||||
+ tok = strtok(NULL, ",");
|
||||
+ }
|
||||
+
|
||||
+ free(copy);
|
||||
+ return list;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Count the number of parts a comma separated string contains
|
||||
+ *
|
||||
+ * param[in] str_list the comma separated string
|
||||
+ *
|
||||
+ * @returns the number of parts
|
||||
+ */
|
||||
+unsigned int str_list_count(const char *str_list)
|
||||
+{
|
||||
+ unsigned int i, count;
|
||||
+
|
||||
+ util_assert(str_list != NULL, "Internal error: str_list is NULL");
|
||||
+
|
||||
+ if (strlen(str_list) == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ for (i = 0, count = 1; str_list[i] != '\0'; i++)
|
||||
+ if (str_list[i] == ',')
|
||||
+ count++;
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Find a string in a comma separated string
|
||||
+ *
|
||||
+ * @param str_list the comma separated string.
|
||||
+ * @param str the string to find
|
||||
+ *
|
||||
+ * @returns a pointer to the string within the comma separated string,
|
||||
+ * or NULL if the string was not found
|
||||
+ *
|
||||
+ */
|
||||
+static char *str_list_find(const char *str_list, const char *str)
|
||||
+{
|
||||
+ char *before;
|
||||
+ char *after;
|
||||
+ char *ch;
|
||||
+
|
||||
+ ch = strstr(str_list, str);
|
||||
+ if (ch == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (ch != str_list) {
|
||||
+ before = ch - 1;
|
||||
+ if (*before != ',')
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ after = ch + strlen(str);
|
||||
+ if (*after != ',' && *after != '\0')
|
||||
+ return NULL;
|
||||
+
|
||||
+ return ch;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Appends a string to a comma separated string
|
||||
+ *
|
||||
+ * @param str_list the comma separated string.
|
||||
+ * @param str the string to add
|
||||
+ *
|
||||
+ * @returns a new comma separated string. This must be freed by the caller when
|
||||
+ * no longer used. If the string to add is already contained in the
|
||||
+ * comma separated list, it is not added and NULL is returned.
|
||||
+ * If the string to be added contains a comma, NULL is returned.
|
||||
+ */
|
||||
+char *str_list_add(const char *str_list, const char *str)
|
||||
+{
|
||||
+ char *ret;
|
||||
+
|
||||
+ util_assert(str_list != NULL, "Internal error: str_list is NULL");
|
||||
+ util_assert(str != NULL, "Internal error: str is NULL");
|
||||
+
|
||||
+ if (strpbrk(str, RESTRICTED_STR_LIST_CHARS) != NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (str_list_find(str_list, str))
|
||||
+ return NULL;
|
||||
+
|
||||
+ ret = util_zalloc(strlen(str_list) + 1 + strlen(str) + 1);
|
||||
+ strcpy(ret, str_list);
|
||||
+ if (strlen(str_list) > 0)
|
||||
+ strcat(ret, ",");
|
||||
+ strcat(ret, str);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Removes a string from a comma separated string
|
||||
+ *
|
||||
+ * @param str_list the comma separated string.
|
||||
+ * @param str the string to remove
|
||||
+ *
|
||||
+ * @returns a new comma separated string. This must be freed by the caller when
|
||||
+ * no longer used. If the string to remove is not found in the
|
||||
+ * comma separated string, NULL is returned
|
||||
+ */
|
||||
+char *str_list_remove(const char *str_list, const char *str)
|
||||
+{
|
||||
+ char *after;
|
||||
+ char *ret;
|
||||
+ char *ch;
|
||||
+
|
||||
+ util_assert(str_list != NULL, "Internal error: str_list is NULL");
|
||||
+ util_assert(str != NULL, "Internal error: str is NULL");
|
||||
+
|
||||
+ ch = str_list_find(str_list, str);
|
||||
+ if (ch == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ after = ch + strlen(str);
|
||||
+ if (*after == ',') {
|
||||
+ /* there are more parts after the one to remove */
|
||||
+ ret = util_zalloc(strlen(str_list) - strlen(str) - 1 + 1);
|
||||
+ strncpy(ret, str_list, ch - str_list);
|
||||
+ strcat(ret, after + 1);
|
||||
+ } else if (ch == str_list) {
|
||||
+ /* removing the one and only part -> empty string */
|
||||
+ ret = util_zalloc(1);
|
||||
+ } else {
|
||||
+ /* there are no more parts after the one to remove */
|
||||
+ ret = util_zalloc(strlen(str_list) - strlen(str) - 1 + 1);
|
||||
+ strncpy(ret, str_list, ch - 1 - str_list);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Frees a string array (as produced by str_list_split())
|
||||
+ *
|
||||
+ * @param strings a NULL terminated array of pointers to C-Strings.
|
||||
+ */
|
||||
+void str_list_free_string_array(char **strings)
|
||||
+{
|
||||
+ util_assert(strings != NULL, "Internal error: strings is NULL");
|
||||
+
|
||||
+ while (*strings != NULL) {
|
||||
+ free((void *)*strings);
|
||||
+ strings++;
|
||||
+ }
|
||||
+}
|
||||
--- a/zkey/properties.h
|
||||
+++ b/zkey/properties.h
|
||||
@@ -33,4 +33,16 @@ int properties_save(struct properties *p
|
||||
int properties_load(struct properties *properties, const char *filename,
|
||||
bool check_integrity);
|
||||
|
||||
+char *str_list_combine(const char **strings);
|
||||
+
|
||||
+char **str_list_split(const char *str_list);
|
||||
+
|
||||
+unsigned int str_list_count(const char *str_list);
|
||||
+
|
||||
+char *str_list_add(const char *str_list, const char *str);
|
||||
+
|
||||
+char *str_list_remove(const char *str_list, const char *str);
|
||||
+
|
||||
+void str_list_free_string_array(char **strings);
|
||||
+
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,40 +0,0 @@
|
||||
Subject: zkey: Create key repository and group during make install
|
||||
From: Philipp Rudo <prudo@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Add support of protected key crypto for dm-crypt.
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
plain format by providing a tool to manage a key repository
|
||||
allowing to associate secure keys with disk partitions or logical
|
||||
volumes.
|
||||
Upstream-ID: 6a2f4fd3760420e11b23db13f8b736f87764d409
|
||||
Problem-ID: SEC1800
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Create key repository and group during make install
|
||||
|
||||
Create the default keystore directory '/etc/zkey/repository'
|
||||
and the user group 'zkeyadm' during make install.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
|
||||
---
|
||||
zkey/Makefile | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/zkey/Makefile
|
||||
+++ b/zkey/Makefile
|
||||
@@ -36,6 +36,9 @@ install: all
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
+ getent group zkeyadm >/dev/null || groupadd -r zkeyadm
|
||||
+ $(INSTALL) -d -g zkeyadm -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
+ $(INSTALL) -d -g zkeyadm -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
|
||||
endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
||||
Subject: zkey: let packaging create the zkeyadm group and permission setup
|
||||
From: Philipp Rudo <prudo@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Add support of protected key crypto for dm-crypt.
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
plain format by providing a tool to manage a key repository
|
||||
allowing to associate secure keys with disk partitions or logical
|
||||
volumes.
|
||||
Upstream-ID: 3eb9af9c97c98e9f9665af1c5e671266400aaafc
|
||||
Problem-ID: SEC1800
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: let packaging create the zkeyadm group and permission setup
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
|
||||
---
|
||||
zkey/Makefile | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/zkey/Makefile
|
||||
+++ b/zkey/Makefile
|
||||
@@ -36,9 +36,8 @@ install: all
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
- getent group zkeyadm >/dev/null || groupadd -r zkeyadm
|
||||
- $(INSTALL) -d -g zkeyadm -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
- $(INSTALL) -d -g zkeyadm -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
+ $(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
+ $(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
|
||||
endif
|
||||
|
@ -1,34 +0,0 @@
|
||||
Subject: zkey: Update README to add info about packaging requirements
|
||||
From: Philipp Rudo <prudo@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Add support of protected key crypto for dm-crypt.
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
plain format by providing a tool to manage a key repository
|
||||
allowing to associate secure keys with disk partitions or logical
|
||||
volumes.
|
||||
Upstream-ID: 80b66da1d81793232646d2504c4d4c0ec94170f1
|
||||
Problem-ID: SEC1800
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Update README to add info about packaging requirements
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
|
||||
---
|
||||
README.md | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -371,3 +371,7 @@ the different tools are provided:
|
||||
For building the zkey tools you need openssl version 0.9.7 or newer installed
|
||||
(openssl-devel.rpm). Tip: you may skip the zkey build by adding
|
||||
`HAVE_OPENSSL=0` to the make invocation.
|
||||
+ A new group 'zkeyadm' needs to be created and all users intending to use the
|
||||
+ tool must be added to this group. The owner of the default key repository
|
||||
+ '/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
|
||||
+ for this group.
|
@ -1,34 +0,0 @@
|
||||
Subject: zkey: Typo in message
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: dec58c349e794f6333771457d9dcb9c0768fe28e
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Typo in message
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/keystore.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/zkey/keystore.c
|
||||
+++ b/zkey/keystore.c
|
||||
@@ -2319,7 +2319,7 @@ static int _keystore_process_reencipher(
|
||||
|
||||
if (params.complete) {
|
||||
if (!_keystore_reencipher_key_exists(file_names)) {
|
||||
- warnx("Staged re-enciphering in not pending for key "
|
||||
+ warnx("Staged re-enciphering is not pending for key "
|
||||
"'%s', skipping",
|
||||
name);
|
||||
info->num_skipped++;
|
@ -1,102 +0,0 @@
|
||||
Subject: zkey: Fix memory leak
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: d6a96f07c1a0ba9b1a559561698f82f5a19829ff
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Fix memory leak
|
||||
|
||||
The APQN check routine as well as the properties helper functions
|
||||
do not free all memory that they allocated.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/keystore.c | 22 +++++++++++++++-------
|
||||
zkey/properties.c | 5 +++++
|
||||
2 files changed, 20 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/zkey/keystore.c
|
||||
+++ b/zkey/keystore.c
|
||||
@@ -981,25 +981,33 @@ static int _keystore_apqn_check(const ch
|
||||
rc = regexec(®_buf, apqn, (size_t) 1, pmatch, 0);
|
||||
if (rc != 0) {
|
||||
warnx("the APQN '%s' is not valid", apqn);
|
||||
- return -EINVAL;
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- if (sscanf(apqn, "%x.%x", &card, &domain) != 2)
|
||||
- return -EINVAL;
|
||||
+ if (sscanf(apqn, "%x.%x", &card, &domain) != 2) {
|
||||
+ rc = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
util_asprintf(normalized, "%02x.%04x", card, domain);
|
||||
|
||||
- if (remove)
|
||||
- return 0;
|
||||
+ if (remove) {
|
||||
+ rc = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
rc = _keystore_is_apqn_online(card, domain);
|
||||
if (rc != 1) {
|
||||
warnx("The APQN %02x.%04x is %s", card, domain,
|
||||
rc == -1 ? "not a CCA card" : "not online");
|
||||
- return -EIO;
|
||||
+ rc = -EIO;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+out:
|
||||
+ regfree(®_buf);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
|
||||
--- a/zkey/properties.c
|
||||
+++ b/zkey/properties.c
|
||||
@@ -149,6 +149,7 @@ void properties_free(struct properties *
|
||||
free(property->name);
|
||||
free(property->value);
|
||||
util_list_remove(&properties->list, property);
|
||||
+ free(property);
|
||||
}
|
||||
|
||||
free(properties);
|
||||
@@ -259,6 +260,7 @@ int properties_remove(struct properties
|
||||
free(property->name);
|
||||
free(property->value);
|
||||
util_list_remove(&properties->list, property);
|
||||
+ free(property);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -614,10 +616,13 @@ char *str_list_remove(const char *str_li
|
||||
*/
|
||||
void str_list_free_string_array(char **strings)
|
||||
{
|
||||
+ char **list = strings;
|
||||
+
|
||||
util_assert(strings != NULL, "Internal error: strings is NULL");
|
||||
|
||||
while (*strings != NULL) {
|
||||
free((void *)*strings);
|
||||
strings++;
|
||||
}
|
||||
+ free(list);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
Subject: zkey: Fix APQN validation routine
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: 344965bd296f434ccbd9ad5b16427590b988d480
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Fix APQN validation routine
|
||||
|
||||
When a zkey generate or change command is used to associate one
|
||||
or multiple APQNs the command succeeds, but no key is generated
|
||||
and no APQNs are associated, because the return code returned by
|
||||
_keystore_apqn_check() is wrong.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/keystore.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/zkey/keystore.c
|
||||
+++ b/zkey/keystore.c
|
||||
@@ -986,6 +986,7 @@ static int _keystore_apqn_check(const ch
|
||||
}
|
||||
|
||||
if (sscanf(apqn, "%x.%x", &card, &domain) != 2) {
|
||||
+ warnx("the APQN '%s' is not valid", apqn);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -1003,6 +1004,8 @@ static int _keystore_apqn_check(const ch
|
||||
rc == -1 ? "not a CCA card" : "not online");
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
+ } else {
|
||||
+ rc = 0;
|
||||
}
|
||||
|
||||
out:
|
@ -1,47 +0,0 @@
|
||||
Subject: zkey: Fix generate and import leaving key in an inconsistent state
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: 672548ce30f61e94c8465a560a54a4a8fe568c06
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Fix generate and import leaving key in an inconsistent state
|
||||
|
||||
When a volume or APQN association is made while generating or
|
||||
importing a key, and a duplicate association is detected, then
|
||||
this may leave the key in an inconsistent state.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/keystore.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/zkey/keystore.c
|
||||
+++ b/zkey/keystore.c
|
||||
@@ -1534,7 +1534,7 @@ int keystore_generate_key(struct keystor
|
||||
out_free_props:
|
||||
if (key_props != NULL)
|
||||
properties_free(key_props);
|
||||
- if (rc != 0 && rc != -EEXIST)
|
||||
+ if (rc != 0)
|
||||
remove(file_names.skey_filename);
|
||||
out_free_key_filenames:
|
||||
_keystore_free_key_filenames(&file_names);
|
||||
@@ -1617,7 +1617,7 @@ int keystore_import_key(struct keystore
|
||||
out_free_props:
|
||||
if (key_props != NULL)
|
||||
properties_free(key_props);
|
||||
- if (rc != 0 && rc != -EEXIST)
|
||||
+ if (rc != 0)
|
||||
remove(file_names.skey_filename);
|
||||
out_free_key_filenames:
|
||||
_keystore_free_key_filenames(&file_names);
|
File diff suppressed because it is too large
Load Diff
@ -1,443 +0,0 @@
|
||||
Subject: zkey: Add man page for zkey-cryptsetup
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: 5e65df7375aec81d9348a57cdcbccb89a65422c3
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Add man page for zkey-cryptsetup
|
||||
|
||||
Add documentation for the new zkey-cryptsetup tool
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/Makefile | 1
|
||||
zkey/zkey-cryptsetup.1 | 403 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 404 insertions(+)
|
||||
|
||||
--- a/zkey/Makefile
|
||||
+++ b/zkey/Makefile
|
||||
@@ -42,6 +42,7 @@ install: all
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
+ $(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
|
||||
--- /dev/null
|
||||
+++ b/zkey/zkey-cryptsetup.1
|
||||
@@ -0,0 +1,403 @@
|
||||
+.\" Copyright IBM Corp. 2018
|
||||
+.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
+.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
+.\"
|
||||
+.TH ZKEY\-CRYPTSETUP 1 "May 2018" "s390-tools"
|
||||
+.SH NAME
|
||||
+zkey\-cryptsetup \- Manage secure AES volume keys of volumes encrypted with
|
||||
+\fBLUKS2\fP and the \fBpaes\fP cipher
|
||||
+.
|
||||
+.
|
||||
+.SH SYNOPSIS
|
||||
+.B zkey\-cryptsetup
|
||||
+.I command
|
||||
+.I device
|
||||
+.RI [ OPTIONS ]
|
||||
+.
|
||||
+.PP
|
||||
+.B zkey\-cryptsetup
|
||||
+.RI [ command ]
|
||||
+.BR \-\-help | \-h
|
||||
+.br
|
||||
+.B zkey\-cryptsetup
|
||||
+.BR \-\-version | \-v
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SH DESCRIPTION
|
||||
+Use \fBzkey\-cryptsetup\fP to validate and re-encipher secure AES
|
||||
+volume keys of volumes encrypted with \fBLUKS2\fP and the \fBpaes\fP cipher.
|
||||
+These secure AES volume keys are enciphered with a master key of an IBM
|
||||
+cryptographic adapter in CCA coprocessor mode.
|
||||
+.PP
|
||||
+To encrypt a volume using \fBLUKS2\fP and the \fBpaes\fP cipher, generate a
|
||||
+secure AES key using \fBzkey\fP: \fB'zkey generate luks.key --xts'\fP.
|
||||
+Then format the device with \fBcryptsetup\fP using the just generated secure
|
||||
+AES key from file luks.key: \fB'cryptsetup luksFormat <device> --type luks2
|
||||
+--cipher paes-xts-plain64 --master-key-file luks.key --key-size 1024'\fP. For
|
||||
+more details about \fBzkey\fP or \fBcryptsetup\fP see the
|
||||
+corresponding man pages.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SH COMMANDS
|
||||
+.
|
||||
+.
|
||||
+.SS "Validate secure AES volume keys"
|
||||
+.
|
||||
+.B zkey\-cryptsetup
|
||||
+.BR validate | val
|
||||
+.I device
|
||||
+.RB [ \-\-key\-file | \-d
|
||||
+.IR file-name ]
|
||||
+.RB [ \-\-keyfile\-offset | \-o
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-keyfile\-size | \-l
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-tries | \-T
|
||||
+.IR number ]
|
||||
+.RB [ \-\-verbose | \-V ]
|
||||
+.RB [ \-\-debug | \-D ]
|
||||
+.PP
|
||||
+Use the
|
||||
+.B validate
|
||||
+command to validate a secure AES volume key of a volume encrypted with
|
||||
+\fBLUKS2\fP and the \fBpaes\fP cipher.
|
||||
+It checks if the LUKS2 header of the volume contains a valid secure key.
|
||||
+It also displays the attributes of the secure key, such as key size, whether
|
||||
+it is a secure key that can be used for the XTS cipher mode, and the master key
|
||||
+register (CURRENT or OLD) with which the secure key is enciphered.
|
||||
+For further information about master key registers, see the
|
||||
+\fBreencipher\fP command.
|
||||
+.PP
|
||||
+To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
+required. You are prompted for the passphrase, unless option
|
||||
+.B \-\-key\-file
|
||||
+is specified. Option
|
||||
+.B \-\-tries
|
||||
+specifies how often a passphrase can be re-entered. When option
|
||||
+.B \-\-key\-file
|
||||
+is specified, the passphrase is read from the specified file. You can specify
|
||||
+options
|
||||
+.B \-\-keyfile\-offset
|
||||
+and
|
||||
+.B \-\-keyfile\-size
|
||||
+to control which part of the key file is used as passphrase. These options
|
||||
+behave in the same way as with \fBcryptsetup\fP.
|
||||
+.
|
||||
+.SS "Re-encipher secure AES volume keys"
|
||||
+.
|
||||
+.PP
|
||||
+.B zkey\-cryptsetup
|
||||
+.BR reencipher | re
|
||||
+.I device
|
||||
+.RB [ \-\-staged | \-s ]
|
||||
+.RB [ \-\-in\-place | \-i ]
|
||||
+.RB [ \-\-complete | \-c ]
|
||||
+.RB [ \-\-key\-file | \-d
|
||||
+.IR file-name ]
|
||||
+.RB [ \-\-keyfile\-offset | \-o
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-keyfile\-size | \-l
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-tries | \-T
|
||||
+.IR number ]
|
||||
+.RB [ \-\-verbose | \-V ]
|
||||
+.RB [ \-\-debug | \-D ]
|
||||
+.PP
|
||||
+Use the
|
||||
+.B reencipher
|
||||
+command to re-encipher a secure AES volume key of a volume encrypted with
|
||||
+\fBLUKS2\fP and the \fBpaes\fP cipher. A secure AES volume key must be
|
||||
+re-enciphered when the master key of the cryptographic adapter in CCA
|
||||
+coprocessor mode changes.
|
||||
+.PP
|
||||
+The cryptographic adapter in CCA coprocessor mode has three different registers
|
||||
+to store master keys:
|
||||
+.RS 2
|
||||
+.IP "\(bu" 2
|
||||
+The \fBCURRENT\fP register contains the current master key.
|
||||
+.
|
||||
+.IP "\(bu" 2
|
||||
+The \fBOLD\fP register contains the previously used master key.
|
||||
+Secure keys enciphered with the master key contained in the \fBOLD\fP
|
||||
+register can still be used until the master key is changed again.
|
||||
+.
|
||||
+.IP "\(bu" 2
|
||||
+The \fBNEW\fP register contains the new master key to be set.
|
||||
+The master key in the \fBNEW\fP register cannot be used until it is made
|
||||
+the current master key. You can pro-actively re-encipher a secure key with the
|
||||
+\fBNEW\fP master key before this key is made the \fBCURRENT\fP key.
|
||||
+.RE
|
||||
+.PP
|
||||
+\fBzkey\-cryptsetup\fP automatically detects whether the secure volume key
|
||||
+is currently enciphered with the master key in the \fBOLD\fP register or with
|
||||
+the master key in the \fBCURRENT\fP register. If currently enciphered with the
|
||||
+master key in the \fBOLD\fP register, it is re-enciphered with the master key
|
||||
+in the \fBCURRENT\fP register. If it is currently enciphered with the master
|
||||
+key in the \fBCURRENT\fP register, it is re-enciphered with the master key in
|
||||
+the \fBNEW\fP register. If for this case the \fBNEW\fP register does not
|
||||
+contain a valid master key, then the re-encipher operation fails.
|
||||
+.PP
|
||||
+Re-enciphering a secure volume key of a volume encrypted with
|
||||
+\fBLUKS2\fP and the \fBpaes\fP cipher can be performed \fBin-place\fP, or in
|
||||
+\fBstaged\fP mode.
|
||||
+.PP
|
||||
+\fB"In-place"\fP immediately replaces the secure volume key in the LUKS2
|
||||
+header of the encrypted volume with the re-enciphered secure volume key.
|
||||
+Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed in-place per
|
||||
+default. You can use option \fB--in-place\fP to force an in-place
|
||||
+re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case. Be aware that
|
||||
+an encrypted volume with a secure volume key that was re-enciphered in-place
|
||||
+from \fBCURRENT\fP to \fBNEW\fP is no longer usable, until the new CCA master
|
||||
+key has been made the current one.
|
||||
+.PP
|
||||
+\fBStaged\fP mode means that the re-enciphered secure volume key is stored in a
|
||||
+separate (unbound) key slot in the LUKS2 header of the encrypted volume. Thus
|
||||
+all key slots containing the current secure volume key are still valid at this
|
||||
+point. Once the new CCA master key has been set (made active), you must rerun
|
||||
+the reencipher command with option \fB--complete\fP to complete the staged
|
||||
+re-enciphering. When completing the staged re-enciphering, the (unbound) key
|
||||
+slot containing the re-enciphered secure volume key becomes the active
|
||||
+key slot and, optionally, all key slots containing the old secure volume key
|
||||
+are removed.
|
||||
+Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is performed in staged mode per
|
||||
+default. You can use option \fB--staged\fP to force a staged re-enciphering for
|
||||
+the \fBOLD\fP to \fBCURRENT\fP case.
|
||||
+.PP
|
||||
+To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
+required. You are prompted for the passphrase, unless option
|
||||
+.B \-\-key\-file
|
||||
+is specified. Option
|
||||
+.B \-\-tries
|
||||
+specifies how often a passphrase can be re-entered. When option
|
||||
+.B \-\-key\-file
|
||||
+is specified, the passphrase is read from the specified file. You can specify
|
||||
+options
|
||||
+.B \-\-keyfile\-offset
|
||||
+and
|
||||
+.B \-\-keyfile\-size
|
||||
+to control which part of the key file is used as passphrase. These options
|
||||
+behave in the same way as with \fBcryptsetup\fP.
|
||||
+.PP
|
||||
+.B Note:
|
||||
+The \fBreencipher\fP command requires the CCA host library (libcsulcca.so)
|
||||
+to be installed.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SS "Set a verification pattern of the secure AES volume key"
|
||||
+.
|
||||
+.B zkey\-cryptsetup
|
||||
+.BR setvp | setv
|
||||
+.I device
|
||||
+.RB [ \-\-key\-file | \-d
|
||||
+.IR file-name ]
|
||||
+.RB [ \-\-keyfile\-offset | \-o
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-keyfile\-size | \-l
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-tries | \-T
|
||||
+.IR number ]
|
||||
+.RB [ \-\-verbose | \-V ]
|
||||
+.RB [ \-\-debug | \-D ]
|
||||
+.PP
|
||||
+Use the
|
||||
+.B setvp
|
||||
+command to set a verification pattern of the secure AES volume key of a volume
|
||||
+encrypted with \fBLUKS2\fP and the \fBpaes\fP cipher. The verification pattern
|
||||
+identifies the effective key used to encrypt the volume's data.
|
||||
+The verification pattern is stored in a token named
|
||||
+\fBpaes-verification-pattern\fP in the LUKS2 header.
|
||||
+.PP
|
||||
+.B Note:
|
||||
+Set the verification pattern right after formatting the volume using
|
||||
+\fB'cryptsetup luksFormat'\fP.
|
||||
+.PP
|
||||
+To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
+required. You are prompted for the passphrase, unless option
|
||||
+.B \-\-key\-file
|
||||
+is specified. Option
|
||||
+.B \-\-tries
|
||||
+specifies how often a passphrase can be re-entered. When option
|
||||
+.B \-\-key\-file
|
||||
+is specified, the passphrase is read from the specified file. You can specify
|
||||
+options
|
||||
+.B \-\-keyfile\-offset
|
||||
+and
|
||||
+.B \-\-keyfile\-size
|
||||
+to control which part of the key file is used as passphrase. These options
|
||||
+behave in the same way as with \fBcryptsetup\fP.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SS "Set a new secure AES volume key for a volume"
|
||||
+.
|
||||
+.B zkey\-cryptsetup
|
||||
+.BR setkey | setk
|
||||
+.I device
|
||||
+.BR \-\-master\-key\-file | \-m
|
||||
+.IR file-name
|
||||
+.RB [ \-\-key\-file | \-d
|
||||
+.IR file-name ]
|
||||
+.RB [ \-\-keyfile\-offset | \-o
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-keyfile\-size | \-l
|
||||
+.IR bytes ]
|
||||
+.RB [ \-\-tries | \-T
|
||||
+.IR number ]
|
||||
+.RB [ \-\-verbose | \-V ]
|
||||
+.RB [ \-\-debug | \-D ]
|
||||
+.PP
|
||||
+Use the
|
||||
+.B setkey
|
||||
+command to set a new secure AES volume key for a volume encrypted with
|
||||
+\fBLUKS2\fP and the \fBpaes\fP cipher. Use this command to recover from an
|
||||
+invalid secure AES volume key contained in the LUKS2 header.
|
||||
+A secure AES volume key contained in the LUKS2 header can become invalid when
|
||||
+the CCA master key is changed without re-enciphering the secure volume key.
|
||||
+.PP
|
||||
+You can recover the secure volume key only if you have a copy of the secure key
|
||||
+in a file, and this copy was re-enciphered when the CCA master key has been
|
||||
+changed. Thus, the copy of the secure key must be currently enciphered with the
|
||||
+CCA master key in the CURRENT or OLD master key register.
|
||||
+Specify the secure key file with option
|
||||
+.B \-\-master\-key\-file
|
||||
+to set this secure key as the new volume key.
|
||||
+.PP
|
||||
+In case the LUKS2 header of the volume contains a verification pattern token,
|
||||
+it is used to ensure that the new volume key contains the same effective key.
|
||||
+If no verification pattern token is available, then you are prompted to confirm
|
||||
+that the specified secure key is the correct one.
|
||||
+.B ATTENTION:
|
||||
+If you set a wrong secure key you will loose all the data on the encrypted
|
||||
+volume!
|
||||
+.PP
|
||||
+To open a key slot contained in the LUKS2 header of the volume, a passphrase is
|
||||
+required. You are prompted for the passphrase, unless option
|
||||
+.B \-\-key\-file
|
||||
+is specified. Option
|
||||
+.B \-\-tries
|
||||
+specifies how often a passphrase can be re-entered. When option
|
||||
+.B \-\-key\-file
|
||||
+is specified, the passphrase is read from the specified file. You can specify
|
||||
+options
|
||||
+.B \-\-keyfile\-offset
|
||||
+and
|
||||
+.B \-\-keyfile\-size
|
||||
+to control which part of the key file is used as passphrase. These options
|
||||
+behave in the same way the same as with \fBcryptsetup\fP.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SH OPTIONS
|
||||
+.
|
||||
+.SS "Options for the reencipher command"
|
||||
+.TP
|
||||
+.BR \-i ", " \-\-in-place
|
||||
+Forces an in-place re-enciphering of a secure volume key in the LUKS2
|
||||
+header. This option immediately replaces the secure volume key in the LUKS2
|
||||
+header of the encrypted volume with the re-enciphered secure volume key.
|
||||
+Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed in-place per
|
||||
+default.
|
||||
+.TP
|
||||
+.BR \-s ", " \-\-staged
|
||||
+Forces that the re-enciphering of a secure volume key in the LUKS2
|
||||
+header is performed in staged mode. Staged mode means that the re-enciphered
|
||||
+secure volume key is stored in a separate (unbound) key slot in the LUKS2
|
||||
+header of the encrypted volume. Thus all key slots containing the current
|
||||
+secure volume key are still valid at this point. Once the new CCA master key
|
||||
+has been set (made active), you must rerun the reencipher command with option
|
||||
+\fB--complete\fP to complete the staged re-enciphering. Re-enciphering from
|
||||
+\fBCURRENT\fP to \fBNEW\fP is performed in staged mode per default.
|
||||
+.TP
|
||||
+.BR \-p ", " \-\-complete
|
||||
+Completes a staged re-enciphering. Use this option after the new CCA master key
|
||||
+has been set (made active). When completing the staged re-enciphering, the
|
||||
+(unbound) key slot containing the re-enciphered secure volume key becomes
|
||||
+the active key slot and, optionally, all key slots containing the old secure
|
||||
+volume key are removed.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SS "Options for the setkey command"
|
||||
+.TP
|
||||
+.BR \-m ", " \-\-master\-key\-file\~\fIfile\-name\fP
|
||||
+Specifies the name of a file containing the secure AES key that is set as the
|
||||
+new volume key.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SS "Options for supplying the passphrase"
|
||||
+.TP
|
||||
+.BR \-d ", " \-\-key\-file\~\fIfile\-name\fP
|
||||
+Reads the passphrase from the specified file. If this option is omitted,
|
||||
+or if the file\-name is \fI-\fP (a dash), then you are prompted to enter the
|
||||
+passphrase interactively.
|
||||
+.TP
|
||||
+.BR \-o ", " \-\-keyfile\-offset\~\fIbytes\fP
|
||||
+Specifies the number of bytes to skip before starting to read in the file
|
||||
+specified with option \fB\-\-key\-file\fP. If omitted, the file is read
|
||||
+from the beginning. When option \fB\-\-key\-file\fP is not specified, this
|
||||
+option is ignored.
|
||||
+.TP
|
||||
+.BR \-l ", " \-\-keyfile\-size\~\fIbytes\fP
|
||||
+Specifies the number of bytes to be read from the beginning of the file
|
||||
+specified with option \fB\-\-key\-file\fP. If omitted, the file is read
|
||||
+until the end. When \fB\-\-keyfile\-offset\fP is also specified, reading starts
|
||||
+at the offset. When option \fB\-\-key\-file\fP is not specified, this option is
|
||||
+ignored.
|
||||
+.TP
|
||||
+.BR \-T ", " \-\-tries\~\fInumber\fP
|
||||
+Specifies how often the interactive input of the passphrase can be re-entered.
|
||||
+The default is 3 times. When option \fB\-\-key\-file\fP is specified, this
|
||||
+option is ignored, and the passphrase is read only once from the file.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SS "General options"
|
||||
+.TP
|
||||
+.BR \-V ", " \-\-verbose
|
||||
+Displays additional information messages during processing.
|
||||
+.TP
|
||||
+.BR \-D ", " \-\-debug
|
||||
+Displays additional debugging messages during processing. This option also
|
||||
+implies \fB\-\-verbose\fP.
|
||||
+.TP
|
||||
+.BR \-h ", " \-\-help
|
||||
+Displays help text and exits.
|
||||
+.TP
|
||||
+.BR \-v ", " \-\-version
|
||||
+Displays version information and exits.
|
||||
+.
|
||||
+.
|
||||
+.
|
||||
+.SH EXAMPLES
|
||||
+.TP
|
||||
+.B zkey-cryptsetup reencipher /dev/dasdd1
|
||||
+Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1.
|
||||
+.TP
|
||||
+.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-staged
|
||||
+Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1 in
|
||||
+staged mode.
|
||||
+.TP
|
||||
+.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-complete
|
||||
+Completes re-enciphers the secure volume key of the encrypted
|
||||
+volume /dev/dasdd1.
|
||||
+.TP
|
||||
+.B zkey-cryptsetup reencipher /dev/dasdd1 \-\-in\-place
|
||||
+Re-enciphers the secure volume key of the encrypted volume /dev/dasdd1 in
|
||||
+in-place mode.
|
||||
+.TP
|
||||
+.B zkey-cryptsetup validate /dev/dasdd1
|
||||
+Validates the secure volume key of the encrypted volume /dev/dasdd1 and
|
||||
+displays its attributes.
|
||||
+.TP
|
||||
+.B zkey-cryptsetup setvp /dev/dasdd1
|
||||
+Sets the verification pattern of the secure volume key of the encrypted
|
||||
+volume /dev/dasdd1.
|
||||
+.TP
|
||||
+.B zkey-cryptsetup setkey /dev/dasdd1 --master-key-file seckey.key
|
||||
+Sets the secure key contained in file seckey.key as the new volume key
|
||||
+for the encrypted volume /dev/dasdd1.
|
@ -1,188 +0,0 @@
|
||||
Subject: zkey: Add build dependency for libcryptsetup and json-c
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: 818ffbc4b05783851cc12682d3d8ad6b99312d63
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Add build dependency for libcryptsetup and json-c
|
||||
|
||||
The zkey-cryptsetup tool has a build dependency to
|
||||
libcryptsetup version 2.0.3 or later, and json-c.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
README.md | 9 ++++--
|
||||
common.mak | 3 +-
|
||||
zkey/Makefile | 84 +++++++++++++++++++++++++++++++++++++++++++---------------
|
||||
3 files changed, 72 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -264,6 +264,8 @@ build options:
|
||||
| pfm | `HAVE_PFM` | cpacfstats |
|
||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||
| openssl | `HAVE_OPENSSL` | zkey |
|
||||
+| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
||||
+| json-c | `HAVE_JSONC` | zkey-cryptsetup |
|
||||
|
||||
This table lists additional build or install options:
|
||||
|
||||
@@ -369,8 +371,11 @@ the different tools are provided:
|
||||
|
||||
* zkey:
|
||||
For building the zkey tools you need openssl version 0.9.7 or newer installed
|
||||
- (openssl-devel.rpm). Tip: you may skip the zkey build by adding
|
||||
- `HAVE_OPENSSL=0` to the make invocation.
|
||||
+ (openssl-devel.rpm). Also required are cryptsetup version 2.0.3 or newer
|
||||
+ (cryptsetup-devel.rpm), and json-c version 0.12 or newer (json-c-devel.rpm).
|
||||
+ Tip: you may skip the zkey build by adding `HAVE_OPENSSL=0`, and you may
|
||||
+ may skip the zkey-cryptsetup build by adding `HAVE_CRYPTSETUP2=0`, or
|
||||
+ `HAVE_JSONC=0` to the make invocation.
|
||||
A new group 'zkeyadm' needs to be created and all users intending to use the
|
||||
tool must be added to this group. The owner of the default key repository
|
||||
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
|
||||
--- a/common.mak
|
||||
+++ b/common.mak
|
||||
@@ -113,9 +113,10 @@ DEFAULT_LDFLAGS = -rdynamic
|
||||
# $2: Name of include file to check
|
||||
# $3: Name of required devel package
|
||||
# $4: Option to skip build (e.g. HAVE_FUSE=0)
|
||||
+# $5: Additional compiler & linker options (optional)
|
||||
#
|
||||
check_dep=\
|
||||
-printf "\#include <%s>" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) -c -o /dev/null -xc - ) > /dev/null 2>&1; \
|
||||
+printf "\#include <%s>\n int main(void) {return 0;}" $2 | ( $(CC) $(filter-out --coverage, $(ALL_CFLAGS)) $(ALL_CPPFLAGS) $5 -o /dev/null -xc - ) > /dev/null 2>&1; \
|
||||
if [ $$? != 0 ]; \
|
||||
then \
|
||||
printf " REQCHK %s (%s)\n" $1 $2; \
|
||||
--- a/zkey/Makefile
|
||||
+++ b/zkey/Makefile
|
||||
@@ -1,54 +1,96 @@
|
||||
include ../common.mak
|
||||
|
||||
-ifeq (${HAVE_OPENSSL},0)
|
||||
+ifneq (${HAVE_OPENSSL},0)
|
||||
+ BUILD_TARGETS += zkey
|
||||
+ INSTALL_TARGETS += install-zkey
|
||||
+else
|
||||
+ BUILD_TARGETS += zkey-skip
|
||||
+ INSTALL_TARGETS += zkey-skip
|
||||
+endif
|
||||
|
||||
-all:
|
||||
- $(SKIP) HAVE_OPENSSL=0
|
||||
+ifneq (${HAVE_CRYPTSETUP2},0)
|
||||
+ ifneq (${HAVE_JSONC},0)
|
||||
+ BUILD_TARGETS += zkey-cryptsetup
|
||||
+ INSTALL_TARGETS += install-zkey-cryptsetup
|
||||
+ else
|
||||
+ BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
|
||||
+ INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
|
||||
+ endif
|
||||
+else
|
||||
+ BUILD_TARGETS += zkey-cryptsetup-skip-cryptsetup2
|
||||
+ INSTALL_TARGETS += zkey-cryptsetup-skip-cryptsetup2
|
||||
+endif
|
||||
|
||||
-install:
|
||||
- $(SKIP) HAVE_OPENSSL=0
|
||||
+CPPFLAGS += -I../include
|
||||
+LIBS = $(rootdir)/libutil/libutil.a
|
||||
|
||||
-else
|
||||
+detect-libcryptsetup.h:
|
||||
+ echo "#include <libcryptsetup.h>" > detect-libcryptsetup.h
|
||||
+ echo "#ifndef CRYPT_LUKS2" >> detect-libcryptsetup.h
|
||||
+ echo " #error libcryptsetup version 2.0.3 is required" >> detect-libcryptsetup.h
|
||||
+ echo "#endif" >> detect-libcryptsetup.h
|
||||
+ echo "int i = CRYPT_SLOT_UNBOUND;" >> detect-libcryptsetup.h
|
||||
|
||||
-check_dep:
|
||||
+check-dep-zkey:
|
||||
$(call check_dep, \
|
||||
"zkey", \
|
||||
"openssl/evp.h", \
|
||||
"openssl-devel", \
|
||||
"HAVE_OPENSSL=0")
|
||||
|
||||
-CPPFLAGS += -I../include
|
||||
+check-dep-zkey-cryptsetup: detect-libcryptsetup.h
|
||||
+ $(call check_dep, \
|
||||
+ "zkey-cryptsetup", \
|
||||
+ "detect-libcryptsetup.h", \
|
||||
+ "cryptsetup-devel version 2.0.3", \
|
||||
+ "HAVE_CRYPTSETUP2=0", \
|
||||
+ "-I.")
|
||||
+ $(call check_dep, \
|
||||
+ "zkey-cryptsetup", \
|
||||
+ "json-c/json.h", \
|
||||
+ "json-c-devel", \
|
||||
+ "HAVE_JSONC=0")
|
||||
+
|
||||
+zkey-skip:
|
||||
+ echo " SKIP zkey due to HAVE_OPENSSL=0"
|
||||
+
|
||||
+zkey-cryptsetup-skip-cryptsetup2:
|
||||
+ echo " SKIP zkey-cryptsetup due to HAVE_CRYPTSETUP2=0"
|
||||
|
||||
-all: check_dep zkey zkey-cryptsetup
|
||||
+zkey-cryptsetup-skip-jsonc:
|
||||
+ echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
|
||||
|
||||
-libs = $(rootdir)/libutil/libutil.a
|
||||
+all: $(BUILD_TARGETS)
|
||||
|
||||
zkey.o: zkey.c pkey.h misc.h
|
||||
pkey.o: pkey.c pkey.h
|
||||
-properties.o: properties.c properties.h
|
||||
+properties.o: check-dep-zkey properties.c properties.h
|
||||
keystore.o: keystore.c keystore.h properties.h
|
||||
-zkey-cryptsetup.o: zkey-cryptsetup.c pkey.h misc.h
|
||||
+zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h misc.h
|
||||
|
||||
zkey: LDLIBS = -ldl -lcrypto
|
||||
-zkey: zkey.o pkey.o properties.o keystore.o $(libs)
|
||||
+zkey: zkey.o pkey.o properties.o keystore.o $(LIBS)
|
||||
|
||||
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c
|
||||
-zkey-cryptsetup: zkey-cryptsetup.o pkey.o $(libs)
|
||||
+zkey-cryptsetup: zkey-cryptsetup.o pkey.o $(LIBS)
|
||||
|
||||
-
|
||||
-install: all
|
||||
+install-common:
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||
- $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
- $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
+
|
||||
+install-zkey:
|
||||
+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
- $(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
|
||||
-endif
|
||||
+install-zkey-cryptsetup:
|
||||
+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
||||
+ $(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
||||
+
|
||||
+install: all install-common $(INSTALL_TARGETS)
|
||||
|
||||
clean:
|
||||
- rm -f *.o zkey zkey-cryptsetup
|
||||
+ rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.h
|
||||
|
||||
.PHONY: all install clean
|
@ -1,349 +0,0 @@
|
||||
Subject: zkey: Add key verification pattern property
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Summary: zkey: Support CCA master key change with LUKS2 volumes using paes
|
||||
Description: Support the usage of protected key crypto for dm-crypt disks in
|
||||
LUKS2 format by providing a tool allowing to re-encipher a
|
||||
secure LUKS2 volume key when the CCA master key is changed
|
||||
Upstream-ID: 512b47c0042a3cdedafce8d46dcc76053298116c
|
||||
Problem-ID: SEC1424.1
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zkey: Add key verification pattern property
|
||||
|
||||
Store a verification pattern in the properties file along
|
||||
with the secure key. The verification pattern allows to identify
|
||||
the inner key even when the secure key is no longer valid.
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/keystore.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
zkey/zkey.1 | 4 -
|
||||
zkey/zkey.c | 27 +++++++++--
|
||||
3 files changed, 145 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/zkey/keystore.c
|
||||
+++ b/zkey/keystore.c
|
||||
@@ -58,6 +58,7 @@ struct key_filenames {
|
||||
#define PROP_NAME_CREATION_TIME "creation-time"
|
||||
#define PROP_NAME_CHANGE_TIME "update-time"
|
||||
#define PROP_NAME_REENC_TIME "reencipher-time"
|
||||
+#define PROP_NAME_KEY_VP "verification-pattern"
|
||||
|
||||
#define IS_XTS(secure_key_size) (secure_key_size > SECURE_KEY_SIZE ? 1 : 0)
|
||||
|
||||
@@ -75,6 +76,7 @@ struct key_filenames {
|
||||
#define REC_CREATION_TIME "Created"
|
||||
#define REC_CHANGE_TIME "Changed"
|
||||
#define REC_REENC_TIME "Re-enciphered"
|
||||
+#define REC_KEY_VP "Verification pattern"
|
||||
|
||||
#define pr_verbose(keystore, fmt...) do { \
|
||||
if (keystore->verbose) \
|
||||
@@ -1270,6 +1272,77 @@ struct keystore *keystore_new(const char
|
||||
}
|
||||
|
||||
/**
|
||||
+ * Generate the key verification pattern from the specified secure key file
|
||||
+ *
|
||||
+ * @param[in] keystore the key store
|
||||
+ * @param[in} keyfile the key file
|
||||
+ * @param[in] vp buffer filled with the verification pattern
|
||||
+ * @param[in] vp_len length of the buffer. Must be at
|
||||
+ * least VERIFICATION_PATTERN_LEN bytes in size.
|
||||
+ *
|
||||
+ * @returns 0 for success or a negative errno in case of an error
|
||||
+ */
|
||||
+static int _keystore_generate_verification_pattern(struct keystore *keystore,
|
||||
+ const char *keyfile,
|
||||
+ char *vp, size_t vp_len)
|
||||
+{
|
||||
+ size_t key_size;
|
||||
+ u8 *key;
|
||||
+ int rc;
|
||||
+
|
||||
+ util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
||||
+ util_assert(keyfile != NULL, "Internal error: keyfile is NULL");
|
||||
+ util_assert(vp != NULL, "Internal error: vp is NULL");
|
||||
+
|
||||
+ key = read_secure_key(keyfile, &key_size, keystore->verbose);
|
||||
+ if (key == NULL)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ rc = generate_key_verification_pattern((const char *)key, key_size,
|
||||
+ vp, vp_len, keystore->verbose);
|
||||
+
|
||||
+ free(key);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Checks if the key verification pattern property exists. If not, then it is
|
||||
+ * created from the secure key.
|
||||
+ *
|
||||
+ * @param[in] keystore the key store
|
||||
+ * @param[in] file_names the file names of the key
|
||||
+ * @param[in] key_props the properties of the key
|
||||
+ *
|
||||
+ * @returns 0 for success or a negative errno in case of an error
|
||||
+ */
|
||||
+static int _keystore_ensure_vp_exists(struct keystore *keystore,
|
||||
+ const struct key_filenames *file_names,
|
||||
+ struct properties *key_props)
|
||||
+{
|
||||
+ char vp[VERIFICATION_PATTERN_LEN];
|
||||
+ char *temp;
|
||||
+ int rc;
|
||||
+
|
||||
+ temp = properties_get(key_props, PROP_NAME_KEY_VP);
|
||||
+ if (temp != NULL) {
|
||||
+ free(temp);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ rc = _keystore_generate_verification_pattern(keystore,
|
||||
+ file_names->skey_filename,
|
||||
+ vp, sizeof(vp));
|
||||
+ if (rc != 0)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = properties_set(key_props, PROP_NAME_KEY_VP, vp);
|
||||
+ if (rc != 0)
|
||||
+ return rc;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* Sets a timestamp to be used as creation/update/reencipher time into
|
||||
* the specified property
|
||||
*
|
||||
@@ -1348,7 +1421,7 @@ static int _keystore_set_default_propert
|
||||
*/
|
||||
static int _keystore_create_info_file(struct keystore *keystore,
|
||||
const char *name,
|
||||
- const char *info_filename,
|
||||
+ const struct key_filenames *filenames,
|
||||
const char *description,
|
||||
const char *volumes, const char *apqns,
|
||||
size_t sector_size)
|
||||
@@ -1396,17 +1469,26 @@ static int _keystore_create_info_file(st
|
||||
goto out;
|
||||
}
|
||||
|
||||
- rc = properties_save(key_props, info_filename, 1);
|
||||
+ rc = _keystore_ensure_vp_exists(keystore, filenames, key_props);
|
||||
+ if (rc != 0) {
|
||||
+ warnx("Failed to generate the key verification pattern: %s",
|
||||
+ strerror(-rc));
|
||||
+ warnx("Make sure that kernel module 'paes_s390' is loaded and "
|
||||
+ "that the 'paes' cipher is available");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ rc = properties_save(key_props, filenames->info_filename, 1);
|
||||
if (rc != 0) {
|
||||
pr_verbose(keystore,
|
||||
"Key info file '%s' could not be written: %s",
|
||||
- info_filename, strerror(-rc));
|
||||
+ filenames->info_filename, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
- rc = _keystore_set_file_permission(keystore, info_filename);
|
||||
+ rc = _keystore_set_file_permission(keystore, filenames->info_filename);
|
||||
if (rc != 0) {
|
||||
- remove(info_filename);
|
||||
+ remove(filenames->info_filename);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1519,8 +1601,7 @@ int keystore_generate_key(struct keystor
|
||||
if (rc != 0)
|
||||
goto out_free_props;
|
||||
|
||||
- rc = _keystore_create_info_file(keystore, name,
|
||||
- file_names.info_filename,
|
||||
+ rc = _keystore_create_info_file(keystore, name, &file_names,
|
||||
description, volumes, apqns,
|
||||
sector_size);
|
||||
if (rc != 0)
|
||||
@@ -1603,8 +1684,7 @@ int keystore_import_key(struct keystore
|
||||
if (rc != 0)
|
||||
goto out_free_props;
|
||||
|
||||
- rc = _keystore_create_info_file(keystore, name,
|
||||
- file_names.info_filename,
|
||||
+ rc = _keystore_create_info_file(keystore, name, &file_names,
|
||||
description, volumes, apqns,
|
||||
sector_size);
|
||||
if (rc != 0)
|
||||
@@ -1723,6 +1803,9 @@ int keystore_change_key(struct keystore
|
||||
}
|
||||
}
|
||||
|
||||
+ rc = _keystore_ensure_vp_exists(keystore, &file_names, key_props);
|
||||
+ /* ignore return code, vp generation might fail if key is not valid */
|
||||
+
|
||||
rc = _keystore_set_timestamp_property(key_props, PROP_NAME_CHANGE_TIME);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
@@ -1838,7 +1921,7 @@ static struct util_rec *_keystore_setup_
|
||||
{
|
||||
struct util_rec *rec;
|
||||
|
||||
- rec = util_rec_new_long("-", ":", REC_KEY, 23, 54);
|
||||
+ rec = util_rec_new_long("-", ":", REC_KEY, 28, 54);
|
||||
util_rec_def(rec, REC_KEY, UTIL_REC_ALIGN_LEFT, 54, REC_KEY);
|
||||
if (validation)
|
||||
util_rec_def(rec, REC_STATUS, UTIL_REC_ALIGN_LEFT, 54,
|
||||
@@ -1858,6 +1941,7 @@ static struct util_rec *_keystore_setup_
|
||||
util_rec_def(rec, REC_KEY_FILE, UTIL_REC_ALIGN_LEFT, 54, REC_KEY_FILE);
|
||||
util_rec_def(rec, REC_SECTOR_SIZE, UTIL_REC_ALIGN_LEFT, 54,
|
||||
REC_SECTOR_SIZE);
|
||||
+ util_rec_def(rec, REC_KEY_VP, UTIL_REC_ALIGN_LEFT, 54, REC_KEY_VP);
|
||||
util_rec_def(rec, REC_CREATION_TIME, UTIL_REC_ALIGN_LEFT, 54,
|
||||
REC_CREATION_TIME);
|
||||
util_rec_def(rec, REC_CHANGE_TIME, UTIL_REC_ALIGN_LEFT, 54,
|
||||
@@ -1876,6 +1960,7 @@ static void _keystore_print_record(struc
|
||||
size_t clear_key_bitsize, bool valid,
|
||||
bool is_old_mk, bool reenc_pending)
|
||||
{
|
||||
+ char temp_vp[VERIFICATION_PATTERN_LEN + 2];
|
||||
char *volumes_argz = NULL;
|
||||
size_t volumes_argz_len;
|
||||
char *apqns_argz = NULL;
|
||||
@@ -1888,6 +1973,8 @@ static void _keystore_print_record(struc
|
||||
char *change;
|
||||
char *apqns;
|
||||
char *temp;
|
||||
+ char *vp;
|
||||
+ int len;
|
||||
|
||||
description = properties_get(properties, PROP_NAME_DESCRIPTION);
|
||||
volumes = properties_get(properties, PROP_NAME_VOLUMES);
|
||||
@@ -1913,6 +2000,7 @@ static void _keystore_print_record(struc
|
||||
creation = properties_get(properties, PROP_NAME_CREATION_TIME);
|
||||
change = properties_get(properties, PROP_NAME_CHANGE_TIME);
|
||||
reencipher = properties_get(properties, PROP_NAME_REENC_TIME);
|
||||
+ vp = properties_get(properties, PROP_NAME_KEY_VP);
|
||||
|
||||
util_rec_set(rec, REC_KEY, name);
|
||||
if (validation)
|
||||
@@ -1951,6 +2039,15 @@ static void _keystore_print_record(struc
|
||||
else
|
||||
util_rec_set(rec, REC_SECTOR_SIZE, "%lu bytes",
|
||||
sector_size);
|
||||
+ if (vp != NULL) {
|
||||
+ len = sprintf(temp_vp, "%.*s%c%.*s",
|
||||
+ VERIFICATION_PATTERN_LEN / 2, vp,
|
||||
+ '\0', VERIFICATION_PATTERN_LEN / 2,
|
||||
+ &vp[VERIFICATION_PATTERN_LEN / 2]);
|
||||
+ util_rec_set_argz(rec, REC_KEY_VP, temp_vp, len + 1);
|
||||
+ } else {
|
||||
+ util_rec_set(rec, REC_KEY_VP, "(not available)");
|
||||
+ }
|
||||
util_rec_set(rec, REC_CREATION_TIME, creation);
|
||||
util_rec_set(rec, REC_CHANGE_TIME,
|
||||
change != NULL ? change : "(never)");
|
||||
@@ -1976,6 +2073,8 @@ static void _keystore_print_record(struc
|
||||
free(change);
|
||||
if (reencipher != NULL)
|
||||
free(reencipher);
|
||||
+ if (vp != NULL)
|
||||
+ free(vp);
|
||||
}
|
||||
|
||||
struct validate_info {
|
||||
@@ -2404,6 +2503,17 @@ static int _keystore_process_reencipher(
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
+ rc = _keystore_ensure_vp_exists(keystore, file_names,
|
||||
+ properties);
|
||||
+ if (rc != 0) {
|
||||
+ warnx("Failed to generate the key verification pattern "
|
||||
+ "for key '%s': %s", file_names->skey_filename,
|
||||
+ strerror(-rc));
|
||||
+ warnx("Make sure that kernel module 'paes_s390' is loaded and "
|
||||
+ "that the 'paes' cipher is available");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
rc = properties_save(properties, file_names->info_filename, 1);
|
||||
if (rc != 0) {
|
||||
pr_verbose(keystore,
|
||||
@@ -3040,7 +3150,7 @@ static int _keystore_process_crypttab(st
|
||||
"At the time this utility was developed, systemd's "
|
||||
"support of crypttab did not support to specify a "
|
||||
"sector size with plain dm-crypt devices. The generated "
|
||||
- "crypttab entry may or may not work, and may need "
|
||||
+ "crypttab entry might or might not work, and might need "
|
||||
"manual adoptions.", volume, sector_size);
|
||||
util_print_indented(temp, 0);
|
||||
}
|
||||
--- a/zkey/zkey.1
|
||||
+++ b/zkey/zkey.1
|
||||
@@ -361,8 +361,8 @@ The
|
||||
command displays the attributes of the secure keys, such as key sizes,
|
||||
whether it is a secure key that can be used for the XTS cipher mode, the textual
|
||||
description, associated cryptographic adapters (APQNs) and volumes, the
|
||||
-sector size, and timestamps for key creation, last modification and last
|
||||
-re-encipherment.
|
||||
+sector size, the key verification pattern, and timestamps for key creation, last
|
||||
+modification and last re-encipherment.
|
||||
.
|
||||
.SS "Remove existing AES secure keys from the secure key repository"
|
||||
.
|
||||
--- a/zkey/zkey.c
|
||||
+++ b/zkey/zkey.c
|
||||
@@ -1057,6 +1057,7 @@ static int command_reencipher(void)
|
||||
*/
|
||||
static int command_validate_file(void)
|
||||
{
|
||||
+ char vp[VERIFICATION_PATTERN_LEN];
|
||||
size_t secure_key_size;
|
||||
size_t clear_key_size;
|
||||
u8 *secure_key;
|
||||
@@ -1089,14 +1090,30 @@ static int command_validate_file(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ rc = generate_key_verification_pattern((char *)secure_key,
|
||||
+ secure_key_size, vp, sizeof(vp),
|
||||
+ g.verbose);
|
||||
+ if (rc != 0) {
|
||||
+ warnx("Failed to generate the verification pattern: %s",
|
||||
+ strerror(-rc));
|
||||
+ warnx("Make sure that kernel module 'paes_s390' is loaded and "
|
||||
+ "that the 'paes' cipher is available");
|
||||
+ rc = EXIT_FAILURE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
printf("Validation of secure key in file '%s':\n", g.pos_arg);
|
||||
- printf(" Status: Valid\n");
|
||||
- printf(" Secure key size: %lu bytes\n", secure_key_size);
|
||||
- printf(" Clear key size: %lu bits\n", clear_key_size);
|
||||
- printf(" XTS type key: %s\n",
|
||||
+ printf(" Status: Valid\n");
|
||||
+ printf(" Secure key size: %lu bytes\n", secure_key_size);
|
||||
+ printf(" Clear key size: %lu bits\n", clear_key_size);
|
||||
+ printf(" XTS type key: %s\n",
|
||||
secure_key_size > SECURE_KEY_SIZE ? "Yes" : "No");
|
||||
- printf(" Encrypted with: %s CCA master key\n",
|
||||
+ printf(" Enciphered with: %s CCA master key\n",
|
||||
is_old_mk ? "OLD" : "CURRENT");
|
||||
+ printf(" Verification pattern: %.*s\n", VERIFICATION_PATTERN_LEN / 2,
|
||||
+ vp);
|
||||
+ printf(" %.*s\n", VERIFICATION_PATTERN_LEN / 2,
|
||||
+ &vp[VERIFICATION_PATTERN_LEN / 2]);
|
||||
|
||||
out:
|
||||
free(secure_key);
|
File diff suppressed because it is too large
Load Diff
@ -1,54 +0,0 @@
|
||||
Subject: zcrypt: Corrections at the chzcrypt man page.
|
||||
From: Harald Freudenberger <freude@linux.ibm.com>
|
||||
|
||||
Summary: lszcrypt: support for alternate zcrypt device drivers
|
||||
Description: With kernel 4.19 there comes an extension to the
|
||||
existing AP bus which supports alternate zcrypt
|
||||
drivers. For details about this see kernel patch
|
||||
"s390/zcrypt: AP bus support for alternate
|
||||
driver(s)". So now lszcrypt displays the driver name
|
||||
in verbose mode. As some of the information
|
||||
displayed by lszcrypt was based on sysfs attributes,
|
||||
which are only available when the default zcrypt
|
||||
driver is bound to the device, this also needed some
|
||||
rework. If a sysfs attribute is not available
|
||||
because of an alternate driver binding (or no
|
||||
driver) a question mark is printed into the field.
|
||||
Upstream-ID: 13648dd6f424bdbf855cd756e3039c8d4e9fd944
|
||||
Problem-ID: SEC1806
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zcrypt: Corrections at the chzcrypt man page.
|
||||
|
||||
Fixed typo and added one sentence to explain more details
|
||||
about online switching of queue devices.
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
|
||||
---
|
||||
zconf/zcrypt/chzcrypt.8 | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/zconf/zcrypt/chzcrypt.8
|
||||
+++ b/zconf/zcrypt/chzcrypt.8
|
||||
@@ -57,6 +57,7 @@ Set all available cryptographic device(s
|
||||
.B <device id>
|
||||
Specifies a cryptographic device which will be set either online or offline.
|
||||
The device can either be a card device or a queue device.
|
||||
+A queue device can only get switched online when the providing card is online.
|
||||
|
||||
Please note that the card device and queue device representation are both
|
||||
in hexadecimal notation.
|
||||
@@ -95,7 +96,7 @@ Print version information and exit.
|
||||
.B chzcrypt -e 0 1 12
|
||||
Will set the cryptographic card devices 0, 1 and 12 online.
|
||||
.TP
|
||||
-.B chzcrypt -e 01.0038
|
||||
+.B chzcrypt -e 10.0038
|
||||
Will set the cryptographic device '10.0038' respectively card id 16
|
||||
(0x10) with domain 56 (0x38) online.
|
||||
.TP
|
@ -1,361 +0,0 @@
|
||||
Subject: cpumf: Add extended counter defintion files for IBM z14
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: 57f18c5f59766832822a74cc029a8d3b60e3ba0f
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf: Add extended counter defintion files for IBM z14
|
||||
|
||||
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
[brueckner: Prefer plural for counter names]
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/Makefile | 2
|
||||
cpumf/bin/cpumf_helper.in | 1
|
||||
cpumf/data/cpum-cf-extended-z14.ctr | 303 ++++++++++++++++++++++++++++++++++++
|
||||
cpumf/data/cpum-cf-hw-counter.map | 1
|
||||
4 files changed, 306 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/cpumf/Makefile
|
||||
+++ b/cpumf/Makefile
|
||||
@@ -7,7 +7,7 @@ CPUMF_DATADIR = $(TOOLS_DATADIR)/cpumf
|
||||
DATA_FILES = cpum-cf-hw-counter.map cpum-cf-generic.ctr \
|
||||
cpum-cf-extended-z10.ctr cpum-cf-extended-z196.ctr \
|
||||
cpum-cf-extended-zEC12.ctr cpum-sf-modes.ctr \
|
||||
- cpum-cf-extended-z13.ctr
|
||||
+ cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr
|
||||
LIB_FILES = bin/cpumf_helper
|
||||
USRBIN_SCRIPTS = bin/lscpumf
|
||||
USRSBIN_SCRIPTS = bin/chcpumf
|
||||
--- a/cpumf/bin/cpumf_helper.in
|
||||
+++ b/cpumf/bin/cpumf_helper.in
|
||||
@@ -210,6 +210,7 @@ my $system_z_hwtype_map = {
|
||||
2828 => 'IBM zEnterprise BC12',
|
||||
2964 => 'IBM z13',
|
||||
2965 => 'IBM z13s',
|
||||
+ 3906 => 'IBM z14',
|
||||
};
|
||||
|
||||
sub get_hardware_type()
|
||||
--- /dev/null
|
||||
+++ b/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
@@ -0,0 +1,303 @@
|
||||
+# Counter decriptions for the
|
||||
+# IBM z14 extended counter and MT-diagnostic counter set
|
||||
+#
|
||||
+# Notes for transactional-execution mode symbolic names:
|
||||
+# TX .. transactional-execution mode
|
||||
+# NC .. nonconstrained
|
||||
+# C .. constrained
|
||||
+#
|
||||
+# Undefined counters in the extended counter set:
|
||||
+# 142
|
||||
+# 158-161
|
||||
+# 176-223
|
||||
+# 227-231
|
||||
+# 233-242
|
||||
+# 246-255
|
||||
+# Undefined counters in the MT-diagnostic counter set:
|
||||
+# 450-495
|
||||
+#
|
||||
+#
|
||||
+# Extended Counter Set
|
||||
+# ---------------------------------------------------------------------
|
||||
+Counter:128 Name:L1D_WRITES_RO_EXCL
|
||||
+A directory write to the Level-1 Data cache where the line was
|
||||
+originally in a Read-Only state in the cache but has been updated
|
||||
+to be in the Exclusive state that allows stores to the cache line
|
||||
+.
|
||||
+Counter:129 Name:DTLB2_WRITES
|
||||
+Description:
|
||||
+A translation has been written into The Translation Lookaside
|
||||
+Buffer 2 (TLB2) and the request was made by the data cache
|
||||
+.
|
||||
+Counter:130 Name:DTLB2_MISSES
|
||||
+Description:
|
||||
+A TLB2 miss is in progress for a request made by the data cache.
|
||||
+Incremented by one for every TLB2 miss in progress for the Level-1
|
||||
+Data cache on this cycle
|
||||
+.
|
||||
+Counter:131 Name:DTLB2_HPAGE_WRITES
|
||||
+Description:
|
||||
+A translation entry was written into the Combined Region and Segment
|
||||
+Table Entry array in the Level-2 TLB for a one-megabyte page or a
|
||||
+Last Host Translation was done
|
||||
+.
|
||||
+Counter:132 Name:DTLB2_GPAGE_WRITES
|
||||
+Description:
|
||||
+A translation entry for a two-gigabyte page was written into the
|
||||
+Level-2 TLB
|
||||
+.
|
||||
+Counter:133 Name:L1D_L2D_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the
|
||||
+returned cache line was sourced from the Level-2 Data cache
|
||||
+.
|
||||
+Counter:134 Name:ITLB2_WRITES
|
||||
+Description:
|
||||
+A translation entry has been written into the Translation Lookaside
|
||||
+Buffer 2 (TLB2) and the request was made by the instruction cache
|
||||
+.
|
||||
+Counter:135 Name:ITLB2_MISSES
|
||||
+Description:
|
||||
+A TLB2 miss is in progress for a request made by the instruction cache.
|
||||
+Incremented by one for every TLB2 miss in progress for the Level-1
|
||||
+Instruction cache in a cycle
|
||||
+.
|
||||
+Counter:136 Name:L1I_L2I_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from the Level-2 Instruction cache
|
||||
+.
|
||||
+Counter:137 Name:TLB2_PTE_WRITES
|
||||
+Description:
|
||||
+A translation entry was written into the Page Table Entry array in the
|
||||
+Level-2 TLB
|
||||
+.
|
||||
+Counter:138 Name:TLB2_CRSTE_WRITES
|
||||
+Description:
|
||||
+Translation entries were written into the Combined Region and Segment
|
||||
+Table Entry array and the Page Table Entry array in the Level-2 TLB
|
||||
+.
|
||||
+Counter:139 Name:TLB2_ENGINES_BUSY
|
||||
+Description:
|
||||
+The number of Level-2 TLB translation engines busy in a cycle
|
||||
+.
|
||||
+Counter:140 Name:TX_C_TEND
|
||||
+Description:
|
||||
+A TEND instruction has completed in a constrained transactional-execution
|
||||
+mode
|
||||
+.
|
||||
+Counter:141 Name:TX_NC_TEND
|
||||
+Description:
|
||||
+A TEND instruction has completed in a non-constrained
|
||||
+transactional-execution mode
|
||||
+.
|
||||
+Counter:143 Name:L1C_TLB2_MISSES
|
||||
+Description:
|
||||
+Increments by one for any cycle where a level-1 cache or level-2 TLB miss
|
||||
+is in progress
|
||||
+.
|
||||
+Counter:144 Name:L1D_ONCHIP_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an On-Chip Level-3 cache without intervention
|
||||
+.
|
||||
+Counter:145 Name:L1D_ONCHIP_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from On-Chip memory
|
||||
+.
|
||||
+Counter:146 Name:L1D_ONCHIP_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an On-Chip Level-3 cache with intervention
|
||||
+.
|
||||
+Counter:147 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from On-Cluster Level-3 cache withountervention
|
||||
+.
|
||||
+Counter:148 Name:L1D_ONCLUSTER_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an On-Cluster memory
|
||||
+.
|
||||
+Counter:149 Name:L1D_ONCLUSTER_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an On-Cluster Level-3 cache with intervention
|
||||
+.
|
||||
+Counter:150 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an Off-Cluster Level-3 cache without
|
||||
+intervention
|
||||
+.
|
||||
+Counter:151 Name:L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from Off-Cluster memory
|
||||
+.
|
||||
+Counter:152 Name:L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an Off-Cluster Level-3 cache with intervention
|
||||
+.
|
||||
+Counter:153 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an Off-Drawer Level-3 cache without
|
||||
+intervention
|
||||
+.
|
||||
+Counter:154 Name:L1D_OFFDRAWER_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from Off-Drawer memory
|
||||
+.
|
||||
+Counter:155 Name:L1D_OFFDRAWER_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from an Off-Drawer Level-3 cache with intervention
|
||||
+.
|
||||
+Counter:156 Name:L1D_ONDRAWER_L4_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from On-Drawer Level-4 cache
|
||||
+.
|
||||
+Counter:157 Name:L1D_OFFDRAWER_L4_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from Off-Drawer Level-4 cache
|
||||
+.
|
||||
+Counter:158 Name:L1D_ONCHIP_L3_SOURCED_WRITES_RO
|
||||
+Description:
|
||||
+A directory write to the Level-1 Data cache directory where the returned
|
||||
+cache line was sourced from On-Chip L3 but a read-only invalidate was
|
||||
+done to remove other copies of the cache line
|
||||
+.
|
||||
+Counter:162 Name:L1I_ONCHIP_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache ine was sourced from an On-Chip Level-3 cache without
|
||||
+intervention
|
||||
+.
|
||||
+Counter:163 Name:L1I_ONCHIP_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache ine was sourced from On-Chip memory
|
||||
+.
|
||||
+Counter:164 Name:L1I_ONCHIP_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache ine was sourced from an On-Chip Level-3 cache with
|
||||
+intervention
|
||||
+.
|
||||
+Counter:165 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from an On-Cluster Level-3 cache without
|
||||
+intervention
|
||||
+.
|
||||
+Counter:166 Name:L1I_ONCLUSTER_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from an On-Cluster memory
|
||||
+.
|
||||
+Counter:167 Name:L1I_ONCLUSTER_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from On-Cluster Level-3 cache with
|
||||
+intervention
|
||||
+.
|
||||
+Counter:168 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from an Off-Cluster Level-3 cache without
|
||||
+intervention
|
||||
+.
|
||||
+Counter:169 Name:L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from Off-Cluster memory
|
||||
+.
|
||||
+Counter:170 Name:L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from an Off-Cluster Level-3 cache with
|
||||
+intervention
|
||||
+.
|
||||
+Counter:171 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from an Off-Drawer Level-3 cache without
|
||||
+intervention
|
||||
+.
|
||||
+Counter:172 Name:L1I_OFFDRAWER_MEMORY_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from Off-Drawer memory
|
||||
+.
|
||||
+Counter:173 Name:L1I_OFFDRAWER_L3_SOURCED_WRITES_IV
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from an Off-Drawer Level-3 cache with
|
||||
+intervention
|
||||
+.
|
||||
+Counter:174 Name:L1I_ONDRAWER_L4_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from On-Drawer Level-4 cache
|
||||
+.
|
||||
+Counter:175 Name:L1I_OFFDRAWER_L4_SOURCED_WRITES
|
||||
+Description:
|
||||
+A directory write to the Level-1 Instruction cache directory where the
|
||||
+returned cache line was sourced from Off-Drawer Level-4 cache
|
||||
+.
|
||||
+Counter:224 Name:BCD_DFP_EXECUTION_SLOTS
|
||||
+Description:
|
||||
+Count of floating point execution slots used for finished Binary Coded
|
||||
+Decimal to Decimal Floating Point conversions. Instructions: CDZT,
|
||||
+CXZT, CZDT, CZXT
|
||||
+.
|
||||
+Counter:225 Name:VX_BCD_EXECUTION_SLOTS
|
||||
+Description:
|
||||
+Count of floating point execution slots used for finished vector arithmetic
|
||||
+Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP,
|
||||
+VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG
|
||||
+.
|
||||
+Counter:226 Name:DECIMAL_INSTRUCTIONS
|
||||
+Description:
|
||||
+Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED,
|
||||
+EDMK, MP, SRP, SP, ZAP
|
||||
+.
|
||||
+Counter:233 Name:LAST_HOST_TRANSLATIONS
|
||||
+Description:
|
||||
+Last Host Translation done
|
||||
+.
|
||||
+Counter:243 Name:TX_NC_TABORT
|
||||
+Description:
|
||||
+A transaction abort has occurred in a non-constrained
|
||||
+transactional-execution mode
|
||||
+.
|
||||
+Counter:244 Name:TX_C_TABORT_NO_SPECIAL
|
||||
+Description:
|
||||
+A transaction abort has occurred in a constrained transactional-execution
|
||||
+mode and the CPU is not using any special logic to allow the transaction
|
||||
+to complete
|
||||
+.
|
||||
+Counter:245 Name:TX_C_TABORT_SPECIAL
|
||||
+Description:
|
||||
+A transaction abort has occurred in a constrained transactional-execution
|
||||
+mode and the CPU is using special logic to allow the transaction to
|
||||
+complete
|
||||
+.
|
||||
+#
|
||||
+# MT-diagnostic counter set
|
||||
+# ---------------------------------------------------------------------
|
||||
+Counter:448 Name:MT_DIAG_CYCLES_ONE_THR_ACTIVE
|
||||
+Description:
|
||||
+Cycle count with one thread active
|
||||
+.
|
||||
+Counter:449 Name:MT_DIAG_CYCLES_TWO_THR_ACTIVE
|
||||
+Description:
|
||||
+Cycle count with two threads active
|
||||
+.
|
||||
--- a/cpumf/data/cpum-cf-hw-counter.map
|
||||
+++ b/cpumf/data/cpum-cf-hw-counter.map
|
||||
@@ -14,4 +14,5 @@
|
||||
2828 => 'cpum-cf-extended-zEC12.ctr',
|
||||
2964 => 'cpum-cf-extended-z13.ctr',
|
||||
2965 => 'cpum-cf-extended-z13.ctr',
|
||||
+ 3906 => 'cpum-cf-extended-z14.ctr',
|
||||
};
|
@ -1,124 +0,0 @@
|
||||
Subject: lszcrypt: CEX6S exploitation
|
||||
From: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
|
||||
Summary: s390-tools: Exploitation Support for CEX6S
|
||||
Description: Exploitation Support for CEX6S
|
||||
Upstream-ID: 31866fbfa4bd89606af2a313427ca06d230e20dc
|
||||
Problem-ID: SEC1519
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lszcrypt: CEX6S exploitation
|
||||
|
||||
With z14 there comes a new crypto card 'CEX6S'.
|
||||
|
||||
This patch introduces the s390-tools changes needed
|
||||
to list the new card and show the capabilities correctly.
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/zcrypt/lszcrypt.8 | 6 ++++++
|
||||
zconf/zcrypt/lszcrypt.c | 37 ++++++++++++++++++++++++++++---------
|
||||
2 files changed, 34 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/zconf/zcrypt/lszcrypt.8
|
||||
+++ b/zconf/zcrypt/lszcrypt.8
|
||||
@@ -85,6 +85,12 @@ EP11 Secure Key
|
||||
.IP "o"
|
||||
Long RNG
|
||||
.RE
|
||||
+
|
||||
+.RS 8
|
||||
+The CCA Secure Key capability may be limited by a hypervisor
|
||||
+layer. The remarks 'full function set' or 'restricted function set' may
|
||||
+reflect this. For details about these limitations please check the
|
||||
+hypervisor documentation.
|
||||
.TP 8
|
||||
.B -d, --domains
|
||||
Shows the usage and control domains of the cryptographic devices.
|
||||
--- a/zconf/zcrypt/lszcrypt.c
|
||||
+++ b/zconf/zcrypt/lszcrypt.c
|
||||
@@ -42,11 +42,19 @@ struct lszcrypt_l *lszcrypt_l = &l;
|
||||
/*
|
||||
* Card types
|
||||
*/
|
||||
-#define MASK_APSC 0x80000000
|
||||
-#define MASK_RSA4K 0x60000000
|
||||
-#define MASK_COPRO 0x10000000
|
||||
-#define MASK_ACCEL 0x08000000
|
||||
-#define MASK_EP11 0x04000000
|
||||
+#define MASK_APSC 0x80000000
|
||||
+#define MASK_RSA4K 0x60000000
|
||||
+#define MASK_COPRO 0x10000000
|
||||
+#define MASK_ACCEL 0x08000000
|
||||
+#define MASK_EP11 0x04000000
|
||||
+
|
||||
+/*
|
||||
+ * Classification
|
||||
+ */
|
||||
+#define MASK_CLASS_FULL 0x00800000
|
||||
+#define CLASS_FULL "full function set"
|
||||
+#define MASK_CLASS_STATELESS 0x00400000
|
||||
+#define CLASS_STATELESS "restricted function set"
|
||||
|
||||
/*
|
||||
* Program configuration
|
||||
@@ -226,7 +234,7 @@ static void show_capability(const char *
|
||||
{
|
||||
unsigned long func_val;
|
||||
long hwtype, id;
|
||||
- char *p, *ap, *dev, card[16];
|
||||
+ char *p, *ap, *dev, card[16], cbuf[256];
|
||||
|
||||
/* check if ap driver is available */
|
||||
ap = util_path_sysfs("bus/ap");
|
||||
@@ -250,6 +258,11 @@ static void show_capability(const char *
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.\n", card, hwtype);
|
||||
return;
|
||||
}
|
||||
+ cbuf[0] = '\0';
|
||||
+ if (func_val & MASK_CLASS_FULL)
|
||||
+ snprintf(cbuf, sizeof(cbuf), "%s", CLASS_FULL);
|
||||
+ else if (func_val & MASK_CLASS_STATELESS)
|
||||
+ snprintf(cbuf, sizeof(cbuf), "%s", CLASS_STATELESS);
|
||||
printf("%s provides capability for:\n", card);
|
||||
switch (hwtype) {
|
||||
case 6:
|
||||
@@ -262,11 +275,15 @@ static void show_capability(const char *
|
||||
case 7:
|
||||
case 9:
|
||||
printf("%s\n", CAP_RSA4K);
|
||||
- printf("%s\n", CAP_CCA);
|
||||
+ if (cbuf[0])
|
||||
+ printf("%s (%s)\n", CAP_CCA, cbuf);
|
||||
+ else
|
||||
+ printf("%s\n", CAP_CCA);
|
||||
printf("%s", CAP_RNG);
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
+ case 12:
|
||||
if (func_val & MASK_ACCEL) {
|
||||
if (func_val & MASK_RSA4K)
|
||||
printf("%s", CAP_RSA4K);
|
||||
@@ -274,12 +291,14 @@ static void show_capability(const char *
|
||||
printf("%s", CAP_RSA2K);
|
||||
} else if (func_val & MASK_COPRO) {
|
||||
printf("%s\n", CAP_RSA4K);
|
||||
- printf("%s\n", CAP_CCA);
|
||||
+ if (cbuf[0])
|
||||
+ printf("%s (%s)\n", CAP_CCA, cbuf);
|
||||
+ else
|
||||
+ printf("%s\n", CAP_CCA);
|
||||
printf("%s", CAP_RNG);
|
||||
} else if (func_val & MASK_EP11) {
|
||||
printf("%s", CAP_EP11);
|
||||
} else {
|
||||
-
|
||||
printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
||||
}
|
||||
break;
|
@ -1,55 +0,0 @@
|
||||
Subject: util_path: add function to check if a path exists
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: df133846b5889a7698ac09f00284c1be54926b59
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
util_path: add function to check if a path exists
|
||||
|
||||
GitHub-ID: #20
|
||||
|
||||
Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com>
|
||||
Acked-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
include/lib/util_path.h | 1 +
|
||||
libutil/util_path.c | 12 ++++++++++++
|
||||
2 files changed, 13 insertions(+)
|
||||
|
||||
--- a/include/lib/util_path.h
|
||||
+++ b/include/lib/util_path.h
|
||||
@@ -20,5 +20,6 @@ bool util_path_is_readable(const char *f
|
||||
bool util_path_is_writable(const char *fmt, ...);
|
||||
bool util_path_is_dir(const char *fmt, ...);
|
||||
bool util_path_is_reg_file(const char *fmt, ...);
|
||||
+bool util_path_exists(const char *fmt, ...);
|
||||
|
||||
#endif /** LIB_UTIL_PATH_H @} */
|
||||
--- a/libutil/util_path.c
|
||||
+++ b/libutil/util_path.c
|
||||
@@ -194,3 +194,15 @@ free_str:
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
||||
+
|
||||
+bool util_path_exists(const char *fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ char *path;
|
||||
+ bool rc;
|
||||
+
|
||||
+ UTIL_VASPRINTF(&path, fmt, ap);
|
||||
+ rc = access(path, F_OK) == 0;
|
||||
+ free(path);
|
||||
+ return rc;
|
||||
+}
|
File diff suppressed because it is too large
Load Diff
@ -1,797 +0,0 @@
|
||||
Subject: zdev: use libutil provided path functions
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: d542138868153a36c3de6a21c3dea56125157e26
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: use libutil provided path functions
|
||||
|
||||
Closes: #20
|
||||
|
||||
Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com>
|
||||
Acked-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/include/misc.h | 4 --
|
||||
zdev/src/ccw.c | 20 ++++--------
|
||||
zdev/src/ccwgroup.c | 7 ++--
|
||||
zdev/src/chzdev.c | 3 +
|
||||
zdev/src/ctc_auto.c | 6 ++-
|
||||
zdev/src/device.c | 5 ++-
|
||||
zdev/src/devnode.c | 8 +++-
|
||||
zdev/src/generic_ccw.c | 4 +-
|
||||
zdev/src/lcs_auto.c | 6 ++-
|
||||
zdev/src/misc.c | 63 ---------------------------------------
|
||||
zdev/src/modprobe.c | 8 +++-
|
||||
zdev/src/module.c | 8 +++-
|
||||
zdev/src/qeth_auto.c | 4 +-
|
||||
zdev/src/root.c | 4 +-
|
||||
zdev/src/scsi.c | 4 +-
|
||||
zdev/src/select.c | 4 +-
|
||||
zdev/src/udev.c | 4 +-
|
||||
zdev/src/udev_ccw.c | 10 +++---
|
||||
zdev/src/udev_ccwgroup.c | 10 +++---
|
||||
zdev/src/udev_zfcp_lun.c | 8 +++-
|
||||
zdev/src/zfcp_lun.c | 16 +++++----
|
||||
21 files changed, 84 insertions(+), 122 deletions(-)
|
||||
|
||||
--- a/zdev/include/misc.h
|
||||
+++ b/zdev/include/misc.h
|
||||
@@ -157,10 +157,6 @@ char *misc_asprintf(const char *, ...);
|
||||
int misc_system(err_t, const char *, ...);
|
||||
bool misc_read_dir(const char *, struct util_list *,
|
||||
bool (*)(const char *, void *), void *);
|
||||
-bool path_exists(const char *);
|
||||
-bool file_exists(const char *);
|
||||
-bool file_writable(const char *);
|
||||
-bool dir_exists(const char *);
|
||||
bool file_is_devnode(const char *);
|
||||
exit_code_t remove_file(const char *);
|
||||
char *misc_read_text_file(const char *, int, err_t);
|
||||
--- a/zdev/src/ccw.c
|
||||
+++ b/zdev/src/ccw.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
+#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
@@ -1165,15 +1166,10 @@ out:
|
||||
|
||||
static void read_grouped(struct ccw_devinfo *info, const char *path)
|
||||
{
|
||||
- char *file_path;
|
||||
-
|
||||
- file_path = misc_asprintf("%s/group_device", path);
|
||||
- if (path_exists(file_path))
|
||||
+ if (util_path_exists("%s/group_device", path))
|
||||
info->grouped = 1;
|
||||
else
|
||||
info->grouped = 0;
|
||||
-
|
||||
- free(file_path);
|
||||
}
|
||||
|
||||
static void read_cutype(struct ccw_devinfo *info, const char *path)
|
||||
@@ -1229,7 +1225,7 @@ static struct ccw_devinfo *ccw_devinfo_r
|
||||
|
||||
id = ccw_devid_to_str(devid);
|
||||
path = path_get_ccw_device(NULL, id);
|
||||
- if (!dir_exists(path))
|
||||
+ if (!util_path_is_dir(path))
|
||||
goto out;
|
||||
|
||||
info->exists = 1;
|
||||
@@ -1354,7 +1350,7 @@ bool ccw_exists(const char *drv, const c
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
- rc = dir_exists(path);
|
||||
+ rc = util_path_is_dir(path);
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
@@ -1428,7 +1424,7 @@ static exit_code_t ccw_st_read_active(st
|
||||
state->definable = 0;
|
||||
|
||||
path = path_get_ccw_device(drv, id);
|
||||
- if (path_exists(path)) {
|
||||
+ if (util_path_exists(path)) {
|
||||
state->exists = 1;
|
||||
device_read_active_settings(dev, scope);
|
||||
} else
|
||||
@@ -1641,7 +1637,7 @@ static void ccw_st_add_errors(struct sub
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
- if (!path_exists(path)) {
|
||||
+ if (!util_path_exists(path)) {
|
||||
strlist_add(errors, "CCW device %s does not exist", id);
|
||||
goto out;
|
||||
}
|
||||
@@ -1662,9 +1658,7 @@ static void ccw_st_add_errors(struct sub
|
||||
"paths", id);
|
||||
goto out;
|
||||
}
|
||||
- free(apath);
|
||||
- apath = misc_asprintf("%s/driver", path);
|
||||
- if (!path_exists(apath)) {
|
||||
+ if (!util_path_exists("%s/driver", path)) {
|
||||
strlist_add(errors, "CCW device %s is not bound to a driver",
|
||||
id);
|
||||
goto out;
|
||||
--- a/zdev/src/ccwgroup.c
|
||||
+++ b/zdev/src/ccwgroup.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/util_base.h"
|
||||
+#include "lib/util_path.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
@@ -557,7 +558,7 @@ static bool read_full_id(struct ccwgroup
|
||||
bool result = false;
|
||||
|
||||
path = path_get_ccwgroup_device(drv, id);
|
||||
- if (!dir_exists(path))
|
||||
+ if (!util_path_is_dir(path))
|
||||
goto out;
|
||||
|
||||
memset(&devid, 0, sizeof(struct ccwgroup_devid));
|
||||
@@ -625,7 +626,7 @@ static void ccwgroup_add_ids(const char
|
||||
path = path_get_ccwgroup_devices(drv);
|
||||
if (mod)
|
||||
module_try_load_once(mod, path);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, get_ids_cb, &cb_data);
|
||||
free(path);
|
||||
}
|
||||
@@ -663,7 +664,7 @@ static exit_code_t ccwgroup_st_read_acti
|
||||
state->definable = 0;
|
||||
|
||||
path = ccwgroup_get_dev_path_by_devid(drv, devid);
|
||||
- if (path_exists(path)) {
|
||||
+ if (util_path_exists(path)) {
|
||||
state->exists = 1;
|
||||
device_read_active_settings(dev, scope);
|
||||
} else
|
||||
--- a/zdev/src/chzdev.c
|
||||
+++ b/zdev/src/chzdev.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "attrib.h"
|
||||
@@ -2502,7 +2503,7 @@ static exit_code_t do_export(struct opti
|
||||
info("Exporting configuration data to standard output\n");
|
||||
} else {
|
||||
info("Exporting configuration data to %s\n", opts->export);
|
||||
- if (!path_exists(opts->export)) {
|
||||
+ if (!util_path_exists(opts->export)) {
|
||||
rc = path_create(opts->export);
|
||||
if (rc)
|
||||
return rc;
|
||||
--- a/zdev/src/ctc_auto.c
|
||||
+++ b/zdev/src/ctc_auto.c
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "ctc.h"
|
||||
@@ -125,13 +127,13 @@ static struct util_list *read_sorted_ctc
|
||||
/* Add CCW devices bound to the CTC CCW device driver. */
|
||||
module_try_load_once(CTC_MOD_NAME, NULL);
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
/* Add CCW devices bound to the LCS CCW device driver. */
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
--- a/zdev/src/device.c
|
||||
+++ b/zdev/src/device.c
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
@@ -480,7 +482,8 @@ void device_read_active_settings(struct
|
||||
a = attrib_find(st->dev_attribs, name);
|
||||
s = setting_list_apply_actual(dev->active.settings, a, name,
|
||||
value);
|
||||
- if (link || (scope == scope_all && !file_writable(path)))
|
||||
+ if (link || (scope == scope_all &&
|
||||
+ !util_path_is_writable(path)))
|
||||
s->readonly = 1;
|
||||
if (link)
|
||||
free(link);
|
||||
--- a/zdev/src/devnode.c
|
||||
+++ b/zdev/src/devnode.c
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "devnode.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
@@ -230,7 +232,7 @@ static exit_code_t add_block_cb(const ch
|
||||
|
||||
/* Add additional nodes. */
|
||||
cb_data->prefix = filename;
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_part_cb, cb_data);
|
||||
|
||||
return EXIT_OK;
|
||||
@@ -249,7 +251,7 @@ int devnode_add_block_from_sysfs(struct
|
||||
cb_data.prefix = NULL;
|
||||
|
||||
blkpath = misc_asprintf("%s/block", path);
|
||||
- if (dir_exists(blkpath))
|
||||
+ if (util_path_is_dir(blkpath))
|
||||
path_for_each(blkpath, add_block_cb, &cb_data);
|
||||
free(blkpath);
|
||||
|
||||
@@ -283,7 +285,7 @@ int devnode_add_net_from_sysfs(struct ut
|
||||
cb_data.prefix = NULL;
|
||||
|
||||
netpath = misc_asprintf("%s/net", path);
|
||||
- if (dir_exists(netpath))
|
||||
+ if (util_path_is_dir(netpath))
|
||||
path_for_each(netpath, add_net_cb, &cb_data);
|
||||
free(netpath);
|
||||
|
||||
--- a/zdev/src/generic_ccw.c
|
||||
+++ b/zdev/src/generic_ccw.c
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
@@ -162,7 +164,7 @@ static void generic_ccw_st_add_devnodes(
|
||||
cb_data.devnodes = devnodes;
|
||||
cb_data.id = id;
|
||||
path = path_get_sys_dev_char_devices();
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, &cb_data);
|
||||
free(path);
|
||||
}
|
||||
--- a/zdev/src/lcs_auto.c
|
||||
+++ b/zdev/src/lcs_auto.c
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "ctc.h"
|
||||
@@ -129,13 +131,13 @@ static struct util_list *read_sorted_lcs
|
||||
/* Add CCW devices bound to the LCS CCW device driver. */
|
||||
module_try_load_once(LCS_MOD_NAME, NULL);
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
/* Add CCW devices bound to the CTC CCW device driver. */
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
--- a/zdev/src/misc.c
|
||||
+++ b/zdev/src/misc.c
|
||||
@@ -889,69 +889,6 @@ void ptrlist_move(struct util_list *to,
|
||||
util_list_add_tail(to, node);
|
||||
}
|
||||
|
||||
-/* Check if a path exists. */
|
||||
-bool path_exists(const char *path)
|
||||
-{
|
||||
- struct stat s;
|
||||
-
|
||||
- debug("Checking if file exists: %s\n", path);
|
||||
- if (stat(path, &s) != 0)
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* Check if a file exists. */
|
||||
-bool file_exists(const char *path)
|
||||
-{
|
||||
- struct stat s;
|
||||
-
|
||||
- debug("Checking if regular file exists: %s\n", path);
|
||||
- if (stat(path, &s) != 0)
|
||||
- return false;
|
||||
-
|
||||
- if (!S_ISREG(s.st_mode))
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* Check if a file is writable. */
|
||||
-bool file_writable(const char *path)
|
||||
-{
|
||||
- struct stat s;
|
||||
-
|
||||
- debug("Checking if regular file is writable: %s\n", path);
|
||||
- if (stat(path, &s) != 0)
|
||||
- return false;
|
||||
-
|
||||
- if (!S_ISREG(s.st_mode))
|
||||
- return false;
|
||||
-
|
||||
- if (!(s.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/* Check if a directory exists. */
|
||||
-bool dir_exists(const char *path)
|
||||
-{
|
||||
- bool result = false;
|
||||
- struct stat s;
|
||||
-
|
||||
- debug("Checking if directory exists: %s\n", path);
|
||||
- if (stat(path, &s) != 0)
|
||||
- goto out;
|
||||
- if (!S_ISDIR(s.st_mode))
|
||||
- goto out;
|
||||
- result = true;
|
||||
-out:
|
||||
- debug("Result: %d\n", result);
|
||||
-
|
||||
- return result;
|
||||
-}
|
||||
-
|
||||
/* Check if file is a block or character special file. */
|
||||
bool file_is_devnode(const char *path)
|
||||
{
|
||||
--- a/zdev/src/modprobe.c
|
||||
+++ b/zdev/src/modprobe.c
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "misc.h"
|
||||
#include "modprobe.h"
|
||||
@@ -376,7 +378,7 @@ exit_code_t modprobe_read_settings(const
|
||||
struct modprobe_file *mf;
|
||||
exit_code_t rc;
|
||||
|
||||
- if (!file_exists(path)) {
|
||||
+ if (!util_path_is_reg_file(path)) {
|
||||
*settings = NULL;
|
||||
return EXIT_OK;
|
||||
}
|
||||
@@ -398,7 +400,7 @@ exit_code_t modprobe_write_settings(cons
|
||||
exit_code_t rc;
|
||||
unsigned long lines;
|
||||
|
||||
- if (file_exists(path)) {
|
||||
+ if (util_path_is_reg_file(path)) {
|
||||
rc = modprobe_read(path, &mf);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -414,7 +416,7 @@ exit_code_t modprobe_write_settings(cons
|
||||
lines = util_list_len(&mf->lines);
|
||||
if (lines == 0 || (lines == 1 && find_chzdev_comment(mf))) {
|
||||
/* Do not write empty files. */
|
||||
- if (file_exists(path))
|
||||
+ if (util_path_is_reg_file(path))
|
||||
rc = remove_file(path);
|
||||
} else
|
||||
rc = modprobe_write(mf);
|
||||
--- a/zdev/src/module.c
|
||||
+++ b/zdev/src/module.c
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "misc.h"
|
||||
#include "module.h"
|
||||
@@ -34,7 +36,7 @@ bool module_loaded(const char *mod)
|
||||
char *path = path_get_sys_module(mod);
|
||||
bool rc;
|
||||
|
||||
- rc = dir_exists(path);
|
||||
+ rc = util_path_is_dir(path);
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
@@ -229,7 +231,7 @@ void module_try_load_once(const char *mo
|
||||
} else
|
||||
tried_loading = strlist_new();
|
||||
strlist_add(tried_loading, mod);
|
||||
- if (path && path_exists(path))
|
||||
+ if (path && util_path_exists(path))
|
||||
return;
|
||||
if (module_loaded(mod))
|
||||
return;
|
||||
@@ -275,7 +277,7 @@ bool module_set_params(const char *mod,
|
||||
return false;
|
||||
}
|
||||
path = path_get_sys_module_param(mod, s->name);
|
||||
- result = file_writable(path);
|
||||
+ result = util_path_is_writable(path);
|
||||
free(path);
|
||||
if (!result) {
|
||||
/* Sysfs file is not writable. */
|
||||
--- a/zdev/src/qeth_auto.c
|
||||
+++ b/zdev/src/qeth_auto.c
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "ccw.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
@@ -277,7 +279,7 @@ static struct util_list *read_sorted_qet
|
||||
/* Get CHPID information for all devices bound to the QETH driver. */
|
||||
infos = ptrlist_new();
|
||||
path = path_get_sys_bus_drv(CCW_BUS_NAME, QETH_CCWDRV_NAME);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_cb, infos);
|
||||
free(path);
|
||||
|
||||
--- a/zdev/src/root.c
|
||||
+++ b/zdev/src/root.c
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
#include "misc.h"
|
||||
@@ -74,7 +76,7 @@ exit_code_t root_check(void)
|
||||
"required.\n");
|
||||
|
||||
/* Check if script is available. */
|
||||
- if (!file_exists(PATH_ROOT_SCRIPT))
|
||||
+ if (!util_path_is_reg_file(PATH_ROOT_SCRIPT))
|
||||
goto out;
|
||||
|
||||
/* Ask for confirmation. */
|
||||
--- a/zdev/src/scsi.c
|
||||
+++ b/zdev/src/scsi.c
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "scsi.h"
|
||||
@@ -253,7 +255,7 @@ static struct util_list *read_scsi_zfcp_
|
||||
|
||||
list = ptrlist_new();
|
||||
path = path_get_sys_bus_dev("scsi", NULL);
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, add_ids_cb, list);
|
||||
free(path);
|
||||
|
||||
--- a/zdev/src/select.c
|
||||
+++ b/zdev/src/select.c
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "blkinfo.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -622,7 +624,7 @@ exit_code_t select_by_path(struct select
|
||||
struct ptrlist_node *p;
|
||||
exit_code_t rc;
|
||||
|
||||
- if (!path_exists(path)) {
|
||||
+ if (!util_path_exists(path)) {
|
||||
err_t_print(err, "Path not found: %s\n", path);
|
||||
return EXIT_DEVICE_NOT_FOUND;
|
||||
}
|
||||
--- a/zdev/src/udev.c
|
||||
+++ b/zdev/src/udev.c
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -391,7 +393,7 @@ exit_code_t udev_remove_rule(const char
|
||||
exit_code_t rc = EXIT_OK;
|
||||
|
||||
path = path_get_udev_rule(type, id);
|
||||
- if (file_exists(path))
|
||||
+ if (util_path_is_reg_file(path))
|
||||
rc = remove_file(path);
|
||||
free(path);
|
||||
|
||||
--- a/zdev/src/udev_ccw.c
|
||||
+++ b/zdev/src/udev_ccw.c
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -33,7 +35,7 @@ bool udev_ccw_exists(const char *type, c
|
||||
return false;
|
||||
|
||||
path = path_get_udev_rule(type, normid);
|
||||
- rc = file_exists(path);
|
||||
+ rc = util_path_is_reg_file(path);
|
||||
free(path);
|
||||
free(normid);
|
||||
|
||||
@@ -150,7 +152,7 @@ exit_code_t udev_ccw_write_device(struct
|
||||
|
||||
path = path_get_udev_rule(type, id);
|
||||
debug("Writing %s udev rule file %s\n", type, path);
|
||||
- if (!path_exists(path)) {
|
||||
+ if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -243,7 +245,7 @@ exit_code_t udev_ccw_write_cio_ignore(co
|
||||
|
||||
if (!*id_list) {
|
||||
/* Empty id_list string - remove file. */
|
||||
- if (!file_exists(path)) {
|
||||
+ if (!util_path_is_reg_file(path)) {
|
||||
/* Already removed. */
|
||||
goto out;
|
||||
}
|
||||
@@ -256,7 +258,7 @@ exit_code_t udev_ccw_write_cio_ignore(co
|
||||
goto out;
|
||||
|
||||
debug("Writing cio-ignore udev rule file %s\n", path);
|
||||
- if (!path_exists(path)) {
|
||||
+ if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
--- a/zdev/src/udev_ccwgroup.c
|
||||
+++ b/zdev/src/udev_ccwgroup.c
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
@@ -53,7 +55,7 @@ bool udev_ccwgroup_exists(const char *ty
|
||||
path = get_rule_path(type, id);
|
||||
if (!path)
|
||||
return false;
|
||||
- rc = file_exists(path);
|
||||
+ rc = util_path_is_reg_file(path);
|
||||
free(path);
|
||||
|
||||
return rc;
|
||||
@@ -215,7 +217,7 @@ exit_code_t udev_ccwgroup_write_device(s
|
||||
list = setting_list_get_sorted(dev->persistent.settings);
|
||||
|
||||
debug("Writing %s udev rule file %s\n", type, path);
|
||||
- if (!path_exists(path)) {
|
||||
+ if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -364,7 +366,7 @@ void udev_ccwgroup_add_device_ids(const
|
||||
cb_data.prefix = misc_asprintf("%s-%s-", UDEV_PREFIX, type);
|
||||
cb_data.ids = list;
|
||||
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, get_ids_cb, &cb_data);
|
||||
|
||||
free(cb_data.prefix);
|
||||
@@ -382,7 +384,7 @@ exit_code_t udev_ccwgroup_remove_rule(co
|
||||
return EXIT_INVALID_ID;
|
||||
|
||||
path = path_get_udev_rule(type, partial_id);
|
||||
- if (file_exists(path))
|
||||
+ if (util_path_is_reg_file(path))
|
||||
rc = remove_file(path);
|
||||
free(path);
|
||||
free(partial_id);
|
||||
--- a/zdev/src/udev_zfcp_lun.c
|
||||
+++ b/zdev/src/udev_zfcp_lun.c
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
#include "misc.h"
|
||||
@@ -376,7 +378,7 @@ void udev_zfcp_lun_add_device_ids(struct
|
||||
cb_data.list = list;
|
||||
path = path_get_udev_rules();
|
||||
|
||||
- if (dir_exists(path))
|
||||
+ if (util_path_is_dir(path))
|
||||
path_for_each(path, lun_cb, &cb_data);
|
||||
|
||||
free(path);
|
||||
@@ -497,7 +499,7 @@ static exit_code_t write_luns_rule(const
|
||||
return EXIT_INTERNAL_ERROR;
|
||||
hba_id = ccw_devid_to_str(&node->id.fcp_dev);
|
||||
debug("Writing FCP LUN udev rule file %s\n", path);
|
||||
- if (!path_exists(path)) {
|
||||
+ if (!util_path_exists(path)) {
|
||||
rc = path_create(path);
|
||||
if (rc)
|
||||
goto out;
|
||||
@@ -614,7 +616,7 @@ static exit_code_t update_lun_rule(const
|
||||
|
||||
/* Get previous rule data. */
|
||||
luns = zfcp_lun_node_list_new();
|
||||
- exists = file_exists(path);
|
||||
+ exists = util_path_is_reg_file(path);
|
||||
if (exists)
|
||||
udev_read_zfcp_lun_rule(path, luns);
|
||||
|
||||
--- a/zdev/src/zfcp_lun.c
|
||||
+++ b/zdev/src/zfcp_lun.c
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "lib/util_path.h"
|
||||
+
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
@@ -430,7 +432,7 @@ static exit_code_t zfcp_lun_st_read_acti
|
||||
|
||||
/* Check for FC unit. */
|
||||
fc_path = path_get_zfcp_lun_dev(dev->devid);
|
||||
- fc_exists = path_exists(fc_path);
|
||||
+ fc_exists = util_path_exists(fc_path);
|
||||
free(fc_path);
|
||||
|
||||
/* Check for SCSI device. */
|
||||
@@ -478,7 +480,7 @@ static exit_code_t zfcp_lun_add(struct d
|
||||
/* Check if LUN already exists. */
|
||||
fcp_dev_id = ccw_devid_to_str(&devid->fcp_dev);
|
||||
lunpath = path_get_zfcp_lun_dev(devid);
|
||||
- if (dir_exists(lunpath)) {
|
||||
+ if (util_path_is_dir(lunpath)) {
|
||||
hctl = scsi_hctl_from_zfcp_lun_devid(devid);
|
||||
if (!hctl)
|
||||
goto check_failed;
|
||||
@@ -486,7 +488,7 @@ static exit_code_t zfcp_lun_add(struct d
|
||||
}
|
||||
|
||||
portpath = path_get_zfcp_port_dev(devid);
|
||||
- if (!dir_exists(portpath)) {
|
||||
+ if (!util_path_is_dir(portpath)) {
|
||||
delayed_err("Target port not found\n");
|
||||
rc = EXIT_ZFCP_WWPN_NOT_FOUND;
|
||||
goto out;
|
||||
@@ -681,14 +683,14 @@ static exit_code_t zfcp_lun_st_device_un
|
||||
|
||||
remove_lun:
|
||||
path = path_get_zfcp_lun_dev(devid);
|
||||
- if (!path_exists(path))
|
||||
+ if (!util_path_exists(path))
|
||||
goto out;
|
||||
free(path);
|
||||
path = NULL;
|
||||
|
||||
/* Remove FCP LUN. */
|
||||
devpath = path_get_zfcp_port_dev(devid);
|
||||
- if (!dir_exists(devpath)) {
|
||||
+ if (!util_path_is_dir(devpath)) {
|
||||
rc = EXIT_ZFCP_WWPN_NOT_FOUND;
|
||||
goto out;
|
||||
}
|
||||
@@ -779,7 +781,7 @@ static bool zfcp_lun_fc_lun_exists(const
|
||||
if (zfcp_lun_parse_devid(&devid, id, err_ignore) != EXIT_OK)
|
||||
return false;
|
||||
path = path_get_zfcp_lun_dev(&devid);
|
||||
- result = path_exists(path);
|
||||
+ result = util_path_exists(path);
|
||||
free(path);
|
||||
|
||||
return result;
|
||||
@@ -910,7 +912,7 @@ static void add_sg_from_sysfs(struct uti
|
||||
char *sgpath;
|
||||
|
||||
sgpath = misc_asprintf("%s/scsi_generic", path);
|
||||
- if (dir_exists(sgpath))
|
||||
+ if (util_path_is_dir(sgpath))
|
||||
path_for_each(sgpath, add_sg_cb, list);
|
||||
free(sgpath);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
Subject: zkey: Fails to run commands generated by 'zkey cryptsetup'
|
||||
From: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
Description: zkey: Fails to run commands generated by 'zkey cryptsetup'
|
||||
Symptom: Fails to run commands generated by 'zkey cryptsetup'.
|
||||
Problem: When using 'zkey cryptsetup' with --run option the
|
||||
execution of the generated commands may fail, when
|
||||
the executable to be run is located in '/sbin'.
|
||||
Solution: Include /sbin into PATH when executing commands.
|
||||
Reproduction: Use 'zkey cryptsetup' with option --run on a distribution
|
||||
where 'cryptsetup' is located in '/sbin'.
|
||||
Upstream-ID: -
|
||||
Problem-ID: 173155
|
||||
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
---
|
||||
zkey/keystore.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/zkey/keystore.c
|
||||
+++ b/zkey/keystore.c
|
||||
@@ -3235,7 +3235,7 @@ static int _keystore_execute_cmd(const c
|
||||
{
|
||||
int rc;
|
||||
|
||||
- rc = setenv("PATH", "/bin:/usr/bin:/usr/sbin", 1);
|
||||
+ rc = setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin", 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
@ -1,382 +0,0 @@
|
||||
Subject: cpumf/z14: split counter sets according to CFVN/CSVN (part 1/2)
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: d121ffa3f01e08d2cc53140444dfcab830319012
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf/z14: split counter sets according to CFVN/CSVN (part 1/2)
|
||||
|
||||
With z14, the counters in the problem-state are reduced resulting
|
||||
in an increased first version number of the CPUM CF. To adapt to
|
||||
this change, split the counter sets according to their counter
|
||||
first and second version number. The second version number controls
|
||||
the crypto-activity and extended counter set. Treat the crypto-activity
|
||||
counter set as generic, as the extended counter set is already handled
|
||||
based on hardware models.
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/Makefile | 4 -
|
||||
cpumf/data/cpum-cf-cfvn-1.ctr | 48 +++++++++++++
|
||||
cpumf/data/cpum-cf-cfvn-3.ctr | 32 ++++++++
|
||||
cpumf/data/cpum-cf-csvn-generic.ctr | 84 ++++++++++++++++++++++
|
||||
cpumf/data/cpum-cf-generic.ctr | 132 ------------------------------------
|
||||
cpumf/data/cpum-cf-hw-counter.map | 15 +++-
|
||||
6 files changed, 180 insertions(+), 135 deletions(-)
|
||||
|
||||
--- a/cpumf/Makefile
|
||||
+++ b/cpumf/Makefile
|
||||
@@ -4,7 +4,9 @@ include ../common.mak
|
||||
|
||||
|
||||
CPUMF_DATADIR = $(TOOLS_DATADIR)/cpumf
|
||||
-DATA_FILES = cpum-cf-hw-counter.map cpum-cf-generic.ctr \
|
||||
+DATA_FILES = cpum-cf-hw-counter.map \
|
||||
+ cpum-cf-cfvn-1.ctr cpum-cf-cfvn-3.ctr \
|
||||
+ cpum-cf-csvn-generic.ctr \
|
||||
cpum-cf-extended-z10.ctr cpum-cf-extended-z196.ctr \
|
||||
cpum-cf-extended-zEC12.ctr cpum-sf-modes.ctr \
|
||||
cpum-cf-extended-z13.ctr cpum-cf-extended-z14.ctr
|
||||
--- /dev/null
|
||||
+++ b/cpumf/data/cpum-cf-cfvn-1.ctr
|
||||
@@ -0,0 +1,48 @@
|
||||
+Counter: 0 Name:CPU_CYCLES
|
||||
+Description:
|
||||
+Cycle Count
|
||||
+.
|
||||
+Counter: 1 Name:INSTRUCTIONS
|
||||
+Description:
|
||||
+Instruction Count
|
||||
+.
|
||||
+Counter: 2 Name:L1I_DIR_WRITES
|
||||
+Description:
|
||||
+Level-1 I-Cache Directory Write Count
|
||||
+.
|
||||
+Counter: 3 Name:L1I_PENALTY_CYCLES
|
||||
+Description:
|
||||
+Level-1 I-Cache Penalty Cycle Count
|
||||
+.
|
||||
+Counter: 4 Name:L1D_DIR_WRITES
|
||||
+Description:
|
||||
+Level-1 D-Cache Directory Write Count
|
||||
+.
|
||||
+Counter: 5 Name:L1D_PENALTY_CYCLES
|
||||
+Description:
|
||||
+Level-1 D-Cache Penalty Cycle Count
|
||||
+.
|
||||
+Counter: 32 Name:PROBLEM_STATE_CPU_CYCLES
|
||||
+Description:
|
||||
+Problem-State Cycle Count
|
||||
+.
|
||||
+Counter: 33 Name:PROBLEM_STATE_INSTRUCTIONS
|
||||
+Description:
|
||||
+Problem-State Instruction Count
|
||||
+.
|
||||
+Counter: 34 Name:PROBLEM_STATE_L1I_DIR_WRITES
|
||||
+Description:
|
||||
+Problem-State Level-1 I-Cache Directory Write Count
|
||||
+.
|
||||
+Counter: 35 Name:PROBLEM_STATE_L1I_PENALTY_CYCLES
|
||||
+Description:
|
||||
+Problem-State Level-1 I-Cache Penalty Cycle Count
|
||||
+.
|
||||
+Counter: 36 Name:PROBLEM_STATE_L1D_DIR_WRITES
|
||||
+Description:
|
||||
+Problem-State Level-1 D-Cache Directory Write Count
|
||||
+.
|
||||
+Counter: 37 Name:PROBLEM_STATE_L1D_PENALTY_CYCLES
|
||||
+Description:
|
||||
+Problem-State Level-1 D-Cache Penalty Cycle Count
|
||||
+.
|
||||
--- /dev/null
|
||||
+++ b/cpumf/data/cpum-cf-cfvn-3.ctr
|
||||
@@ -0,0 +1,32 @@
|
||||
+Counter: 0 Name:CPU_CYCLES
|
||||
+Description:
|
||||
+Cycle Count
|
||||
+.
|
||||
+Counter: 1 Name:INSTRUCTIONS
|
||||
+Description:
|
||||
+Instruction Count
|
||||
+.
|
||||
+Counter: 2 Name:L1I_DIR_WRITES
|
||||
+Description:
|
||||
+Level-1 I-Cache Directory Write Count
|
||||
+.
|
||||
+Counter: 3 Name:L1I_PENALTY_CYCLES
|
||||
+Description:
|
||||
+Level-1 I-Cache Penalty Cycle Count
|
||||
+.
|
||||
+Counter: 4 Name:L1D_DIR_WRITES
|
||||
+Description:
|
||||
+Level-1 D-Cache Directory Write Count
|
||||
+.
|
||||
+Counter: 5 Name:L1D_PENALTY_CYCLES
|
||||
+Description:
|
||||
+Level-1 D-Cache Penalty Cycle Count
|
||||
+.
|
||||
+Counter: 32 Name:PROBLEM_STATE_CPU_CYCLES
|
||||
+Description:
|
||||
+Problem-State Cycle Count
|
||||
+.
|
||||
+Counter: 33 Name:PROBLEM_STATE_INSTRUCTIONS
|
||||
+Description:
|
||||
+Problem-State Instruction Count
|
||||
+.
|
||||
--- /dev/null
|
||||
+++ b/cpumf/data/cpum-cf-csvn-generic.ctr
|
||||
@@ -0,0 +1,84 @@
|
||||
+Counter: 64 Name:PRNG_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of the PRNG functions issued by the CPU
|
||||
+.
|
||||
+Counter: 65 Name:PRNG_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles when the DEA/AES coprocessor is busy
|
||||
+performing PRNG functions issued by the CPU
|
||||
+.
|
||||
+Counter: 66 Name:PRNG_BLOCKED_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of the PRNG functions that are issued by the CPU and are
|
||||
+blocked because the DEA/AES coprocessor is busy performing a function
|
||||
+issued by another CPU
|
||||
+.
|
||||
+Counter: 67 Name:PRNG_BLOCKED_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles blocked for the PRNG functions issued by
|
||||
+the CPU because the DEA/AES coprocessor is busy performing a function
|
||||
+issued by another CPU
|
||||
+.
|
||||
+Counter: 68 Name:SHA_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of SHA functions issued by the CPU
|
||||
+.
|
||||
+Counter: 69 Name:SHA_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles when the SHA coprocessor is busy performing
|
||||
+the SHA functions issued by the CPU
|
||||
+.
|
||||
+Counter: 70 Name:SHA_BLOCKED_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of the SHA functions that are issued by the CPU and are
|
||||
+blocked because the SHA coprocessor is busy performing a function issued
|
||||
+by another CPU
|
||||
+.
|
||||
+Counter: 71 Name:SHA_BLOCKED_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles blocked for the SHA functions issued by the
|
||||
+CPU because the SHA coprocessor is busy performing a function issued
|
||||
+by another CPU
|
||||
+.
|
||||
+Counter: 72 Name:DEA_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of the DEA functions issued by the CPU
|
||||
+.
|
||||
+Counter: 73 Name:DEA_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles when the DEA/AES coprocessor is busy
|
||||
+performing the DEA functions issued by the CPU
|
||||
+.
|
||||
+Counter: 74 Name:DEA_BLOCKED_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of the DEA functions that are issued by the CPU and are
|
||||
+blocked because the DEA/AES coprocessor is busy performing a function
|
||||
+issued by another CPU
|
||||
+.
|
||||
+Counter: 75 Name:DEA_BLOCKED_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles blocked for the DEA functions issued by the
|
||||
+CPU because the DEA/AES coprocessor is busy performing a function issued
|
||||
+by another CPU
|
||||
+.
|
||||
+Counter: 76 Name:AES_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of AES functions issued by the CPU
|
||||
+.
|
||||
+Counter: 77 Name:AES_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles when the DEA/AES coprocessor is busy
|
||||
+performing the AES functions issued by the CPU
|
||||
+.
|
||||
+Counter: 78 Name:AES_BLOCKED_FUNCTIONS
|
||||
+Description:
|
||||
+Total number of AES functions that are issued by the CPU and are blocked
|
||||
+because the DEA/AES coprocessor is busy performing a function issued
|
||||
+by another CPU
|
||||
+.
|
||||
+Counter: 79 Name:AES_BLOCKED_CYCLES
|
||||
+Description:
|
||||
+Total number of CPU cycles blocked for the AES functions issued by the
|
||||
+CPU because the DEA/AES coprocessor is busy performing a function issued
|
||||
+by another CPU
|
||||
+.
|
||||
--- a/cpumf/data/cpum-cf-generic.ctr
|
||||
+++ /dev/null
|
||||
@@ -1,132 +0,0 @@
|
||||
-Counter: 0 Name:CPU_CYCLES
|
||||
-Description:
|
||||
-Cycle Count
|
||||
-.
|
||||
-Counter: 1 Name:INSTRUCTIONS
|
||||
-Description:
|
||||
-Instruction Count
|
||||
-.
|
||||
-Counter: 2 Name:L1I_DIR_WRITES
|
||||
-Description:
|
||||
-Level-1 I-Cache Directory Write Count
|
||||
-.
|
||||
-Counter: 3 Name:L1I_PENALTY_CYCLES
|
||||
-Description:
|
||||
-Level-1 I-Cache Penalty Cycle Count
|
||||
-.
|
||||
-Counter: 4 Name:L1D_DIR_WRITES
|
||||
-Description:
|
||||
-Level-1 D-Cache Directory Write Count
|
||||
-.
|
||||
-Counter: 5 Name:L1D_PENALTY_CYCLES
|
||||
-Description:
|
||||
-Level-1 D-Cache Penalty Cycle Count
|
||||
-.
|
||||
-Counter: 32 Name:PROBLEM_STATE_CPU_CYCLES
|
||||
-Description:
|
||||
-Problem-State Cycle Count
|
||||
-.
|
||||
-Counter: 33 Name:PROBLEM_STATE_INSTRUCTIONS
|
||||
-Description:
|
||||
-Problem-State Instruction Count
|
||||
-.
|
||||
-Counter: 34 Name:PROBLEM_STATE_L1I_DIR_WRITES
|
||||
-Description:
|
||||
-Problem-State Level-1 I-Cache Directory Write Count
|
||||
-.
|
||||
-Counter: 35 Name:PROBLEM_STATE_L1I_PENALTY_CYCLES
|
||||
-Description:
|
||||
-Problem-State Level-1 I-Cache Penalty Cycle Count
|
||||
-.
|
||||
-Counter: 36 Name:PROBLEM_STATE_L1D_DIR_WRITES
|
||||
-Description:
|
||||
-Problem-State Level-1 D-Cache Directory Write Count
|
||||
-.
|
||||
-Counter: 37 Name:PROBLEM_STATE_L1D_PENALTY_CYCLES
|
||||
-Description:
|
||||
-Problem-State Level-1 D-Cache Penalty Cycle Count
|
||||
-.
|
||||
-Counter: 64 Name:PRNG_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of the PRNG functions issued by the CPU
|
||||
-.
|
||||
-Counter: 65 Name:PRNG_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles when the DEA/AES coprocessor is busy
|
||||
-performing PRNG functions issued by the CPU
|
||||
-.
|
||||
-Counter: 66 Name:PRNG_BLOCKED_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of the PRNG functions that are issued by the CPU and are
|
||||
-blocked because the DEA/AES coprocessor is busy performing a function
|
||||
-issued by another CPU
|
||||
-.
|
||||
-Counter: 67 Name:PRNG_BLOCKED_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles blocked for the PRNG functions issued by
|
||||
-the CPU because the DEA/AES coprocessor is busy performing a function
|
||||
-issued by another CPU
|
||||
-.
|
||||
-Counter: 68 Name:SHA_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of SHA functions issued by the CPU
|
||||
-.
|
||||
-Counter: 69 Name:SHA_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles when the SHA coprocessor is busy performing
|
||||
-the SHA functions issued by the CPU
|
||||
-.
|
||||
-Counter: 70 Name:SHA_BLOCKED_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of the SHA functions that are issued by the CPU and are
|
||||
-blocked because the SHA coprocessor is busy performing a function issued
|
||||
-by another CPU
|
||||
-.
|
||||
-Counter: 71 Name:SHA_BLOCKED_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles blocked for the SHA functions issued by the
|
||||
-CPU because the SHA coprocessor is busy performing a function issued
|
||||
-by another CPU
|
||||
-.
|
||||
-Counter: 72 Name:DEA_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of the DEA functions issued by the CPU
|
||||
-.
|
||||
-Counter: 73 Name:DEA_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles when the DEA/AES coprocessor is busy
|
||||
-performing the DEA functions issued by the CPU
|
||||
-.
|
||||
-Counter: 74 Name:DEA_BLOCKED_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of the DEA functions that are issued by the CPU and are
|
||||
-blocked because the DEA/AES coprocessor is busy performing a function
|
||||
-issued by another CPU
|
||||
-.
|
||||
-Counter: 75 Name:DEA_BLOCKED_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles blocked for the DEA functions issued by the
|
||||
-CPU because the DEA/AES coprocessor is busy performing a function issued
|
||||
-by another CPU
|
||||
-.
|
||||
-Counter: 76 Name:AES_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of AES functions issued by the CPU
|
||||
-.
|
||||
-Counter: 77 Name:AES_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles when the DEA/AES coprocessor is busy
|
||||
-performing the AES functions issued by the CPU
|
||||
-.
|
||||
-Counter: 78 Name:AES_BLOCKED_FUNCTIONS
|
||||
-Description:
|
||||
-Total number of AES functions that are issued by the CPU and are blocked
|
||||
-because the DEA/AES coprocessor is busy performing a function issued
|
||||
-by another CPU
|
||||
-.
|
||||
-Counter: 79 Name:AES_BLOCKED_CYCLES
|
||||
-Description:
|
||||
-Total number of CPU cycles blocked for the AES functions issued by the
|
||||
-CPU because the DEA/AES coprocessor is busy performing a function issued
|
||||
-by another CPU
|
||||
-.
|
||||
--- a/cpumf/data/cpum-cf-hw-counter.map
|
||||
+++ b/cpumf/data/cpum-cf-hw-counter.map
|
||||
@@ -1,11 +1,22 @@
|
||||
# CPU-measurement facilities
|
||||
#
|
||||
-# Mapping of IBM System z hardware types to extended counter set defintions
|
||||
+# Mapping of:
|
||||
+# 1. CPU-MF counter first/second version numbers to "generic" counter
|
||||
+# definitions
|
||||
+# 2. IBM z Systems hardware to respective extended counter set definitions
|
||||
#
|
||||
#
|
||||
{
|
||||
# Definition # File name
|
||||
- 0 => 'cpum-cf-generic.ctr',
|
||||
+
|
||||
+ # CFVN
|
||||
+ 'cfvn-1' => 'cpum-cf-cfvn-1.ctr',
|
||||
+ 'cfvn-3' => 'cpum-cf-cfvn-3.ctr',
|
||||
+
|
||||
+ # CSVN
|
||||
+ 'csvn-generic' => 'cpum-cf-csvn-generic.ctr',
|
||||
+
|
||||
+ # Extended counters
|
||||
2097 => 'cpum-cf-extended-z10.ctr',
|
||||
2098 => 'cpum-cf-extended-z10.ctr',
|
||||
2817 => 'cpum-cf-extended-z196.ctr',
|
@ -1,56 +0,0 @@
|
||||
Subject: lszcrypt: fix date and wrong indentation
|
||||
From: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
|
||||
Summary: s390-tools: Exploitation Support for CEX6S
|
||||
Description: Exploitation Support for CEX6S
|
||||
Upstream-ID: 4ad5e29f2f02e02c772ca4707b9f10253b1e5692
|
||||
Problem-ID: SEC1519
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lszcrypt: fix date and wrong indentation
|
||||
|
||||
The man page date was AUG 2008. Changed to OCT 2017.
|
||||
A previous commit had a wrong indentation on following
|
||||
options text for lszcrypt. Fixed.
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
|
||||
---
|
||||
zconf/zcrypt/chzcrypt.8 | 2 +-
|
||||
zconf/zcrypt/lszcrypt.8 | 3 ++-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/zconf/zcrypt/chzcrypt.8
|
||||
+++ b/zconf/zcrypt/chzcrypt.8
|
||||
@@ -2,7 +2,7 @@
|
||||
.\" 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 CHZCRYPT 8 "AUG 2008" "s390-tools"
|
||||
+.TH CHZCRYPT 8 "OCT 2017" "s390-tools"
|
||||
.SH NAME
|
||||
chzcrypt \- modify zcrypt configuration
|
||||
.SH SYNOPSIS
|
||||
--- a/zconf/zcrypt/lszcrypt.8
|
||||
+++ b/zconf/zcrypt/lszcrypt.8
|
||||
@@ -10,7 +10,7 @@
|
||||
.\" nroff -man lszcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
-.TH LSZCRYPT 8 "AUG 2008" "s390-tools"
|
||||
+.TH LSZCRYPT 8 "OCT 2017" "s390-tools"
|
||||
.SH NAME
|
||||
lszcrypt \- display zcrypt device and configuration information
|
||||
.SH SYNOPSIS
|
||||
@@ -91,6 +91,7 @@ The CCA Secure Key capability may be lim
|
||||
layer. The remarks 'full function set' or 'restricted function set' may
|
||||
reflect this. For details about these limitations please check the
|
||||
hypervisor documentation.
|
||||
+.RE
|
||||
.TP 8
|
||||
.B -d, --domains
|
||||
Shows the usage and control domains of the cryptographic devices.
|
@ -1,369 +0,0 @@
|
||||
Subject: lszcrypt: support for alternate zcrypt device drivers
|
||||
From: Harald Freudenberger <freude@linux.ibm.com>
|
||||
|
||||
Summary: lszcrypt: support for alternate zcrypt device drivers
|
||||
Description: With kernel 4.19 there comes an extension to the
|
||||
existing AP bus which supports alternate zcrypt
|
||||
drivers. For details about this see kernel patch
|
||||
"s390/zcrypt: AP bus support for alternate
|
||||
driver(s)". So now lszcrypt displays the driver name
|
||||
in verbose mode. As some of the information
|
||||
displayed by lszcrypt was based on sysfs attributes,
|
||||
which are only available when the default zcrypt
|
||||
driver is bound to the device, this also needed some
|
||||
rework. If a sysfs attribute is not available
|
||||
because of an alternate driver binding (or no
|
||||
driver) a question mark is printed into the field.
|
||||
Upstream-ID: 0a0b4c382693cded5652404e8fa2c0e483aa33df
|
||||
Problem-ID: SEC1806
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
lszcrypt: support for alternate zcrypt device drivers
|
||||
|
||||
With kernel 4.19 there comes an extension to the existing
|
||||
AP bus which supports alternate zcrypt drivers. For details
|
||||
about this see kernel patch "s390/zcrypt: AP bus support for
|
||||
alternate driver(s)". So now lszcrypt displays the driver
|
||||
name in verbose mode. As some of the information displayed
|
||||
by lszcrypt was based on sysfs attributes, which are only
|
||||
available when the default zcrypt driver is bound to the
|
||||
device, this also needed some rework. If a sysfs attribute
|
||||
is not available because of an alternate driver binding
|
||||
(or no driver) a question mark is printed into the field.
|
||||
|
||||
Together with this a slight rework of the displayed information
|
||||
has been done. The two columns for pending requests and pending
|
||||
replies has been merged to one pending column and the column
|
||||
sizes have been adjusted.
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
|
||||
---
|
||||
zconf/zcrypt/lszcrypt.8 | 4 -
|
||||
zconf/zcrypt/lszcrypt.c | 163 ++++++++++++++++++++++++++++++++----------------
|
||||
2 files changed, 112 insertions(+), 55 deletions(-)
|
||||
|
||||
--- a/zconf/zcrypt/lszcrypt.8
|
||||
+++ b/zconf/zcrypt/lszcrypt.8
|
||||
@@ -54,8 +54,8 @@ status.
|
||||
.B -V, --verbose
|
||||
The verbose level for cryptographic device information.
|
||||
With this verbose level additional information like hardware card type,
|
||||
-hardware queue depth, pending request queue count, outstanding
|
||||
-request queue count, and installed function facilities are displayed.
|
||||
+hardware queue depth, pending requests count, installed function
|
||||
+facilities and driver binding is displayed.
|
||||
.TP 8
|
||||
.B <device-id>
|
||||
Specifies a cryptographic device to display. A cryptographic device can be
|
||||
--- a/zconf/zcrypt/lszcrypt.c
|
||||
+++ b/zconf/zcrypt/lszcrypt.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* lszcrypt - Display zcrypt devices and configuration settings
|
||||
*
|
||||
- * Copyright IBM Corp. 2008, 2017
|
||||
+ * Copyright IBM Corp. 2008, 2018
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -57,6 +57,25 @@ struct lszcrypt_l *lszcrypt_l = &l;
|
||||
#define CLASS_STATELESS "restricted function set"
|
||||
|
||||
/*
|
||||
+ * facility bits
|
||||
+ */
|
||||
+#define MAX_FAC_BITS 9
|
||||
+static struct fac_bits_s {
|
||||
+ int mask;
|
||||
+ char c;
|
||||
+} fac_bits[MAX_FAC_BITS] = {
|
||||
+ { 0x80000000, 'S' },
|
||||
+ { 0x40000000, 'M' },
|
||||
+ { 0x20000000, 'C' },
|
||||
+ { 0x10000000, 'D' },
|
||||
+ { 0x08000000, 'A' },
|
||||
+ { 0x04000000, 'X' },
|
||||
+ { 0x02000000, 'N' },
|
||||
+ { 0x00800000, 'F' },
|
||||
+ { 0x00400000, 'R' },
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
* Program configuration
|
||||
*/
|
||||
const struct util_prg prg = {
|
||||
@@ -66,7 +85,7 @@ const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
- .pub_last = 2017,
|
||||
+ .pub_last = 2018,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -255,7 +274,8 @@ static void show_capability(const char *
|
||||
/* Skip devices, which are not supported by zcrypt layer */
|
||||
if (!util_path_is_readable("%s/type", dev) ||
|
||||
!util_path_is_readable("%s/online", dev)) {
|
||||
- printf("Detailed capability information for %s (hardware type %ld) is not available.\n", card, hwtype);
|
||||
+ printf("Detailed capability information for %s (hardware type %ld) is not available.\n",
|
||||
+ card, hwtype);
|
||||
return;
|
||||
}
|
||||
cbuf[0] = '\0';
|
||||
@@ -299,11 +319,13 @@ static void show_capability(const char *
|
||||
} else if (func_val & MASK_EP11) {
|
||||
printf("%s", CAP_EP11);
|
||||
} else {
|
||||
- printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
||||
+ printf("Detailed capability information for %s (hardware type %ld) is not available.",
|
||||
+ card, hwtype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
- printf("Detailed capability information for %s (hardware type %ld) is not available.", card, hwtype);
|
||||
+ printf("Detailed capability information for %s (hardware type %ld) is not available.",
|
||||
+ card, hwtype);
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
@@ -315,17 +337,22 @@ static void show_capability(const char *
|
||||
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
- unsigned long facility;
|
||||
char buf[256];
|
||||
+ unsigned long facility;
|
||||
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
|
||||
- util_rec_set(rec, "type", buf);
|
||||
+ if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
|
||||
+ util_rec_set(rec, "type", "-");
|
||||
+ else
|
||||
+ util_rec_set(rec, "type", buf);
|
||||
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/%s/online", grp_dev, sub_dev);
|
||||
- if (strcmp(buf, "0") == 0)
|
||||
- util_rec_set(rec, "online", "offline");
|
||||
+ if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
|
||||
+ grp_dev, sub_dev))
|
||||
+ util_rec_set(rec, "online", "-");
|
||||
else
|
||||
- util_rec_set(rec, "online", "online");
|
||||
+ if (strcmp(buf, "0") == 0)
|
||||
+ util_rec_set(rec, "online", "offline");
|
||||
+ else
|
||||
+ util_rec_set(rec, "online", "online");
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (facility & MASK_COPRO)
|
||||
@@ -339,7 +366,7 @@ static void read_subdev_rec_default(stru
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/%s/request_count",
|
||||
grp_dev, sub_dev);
|
||||
- util_rec_set(rec, "request_count", buf);
|
||||
+ util_rec_set(rec, "requests", buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -348,20 +375,19 @@ static void read_subdev_rec_default(stru
|
||||
static void read_subdev_rec_verbose(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
+ int i;
|
||||
unsigned long facility;
|
||||
- char buf[256];
|
||||
- long depth;
|
||||
+ char buf[256], afile[PATH_MAX];
|
||||
+ long depth, pending1, pending2;
|
||||
|
||||
if (l.verbose == 0)
|
||||
return;
|
||||
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/%s/pendingq_count",
|
||||
- grp_dev, sub_dev);
|
||||
- util_rec_set(rec, "pendingq_count", buf);
|
||||
-
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/%s/requestq_count",
|
||||
- grp_dev, sub_dev);
|
||||
- util_rec_set(rec, "requestq_count", buf);
|
||||
+ util_file_read_l(&pending1, 10, "%s/%s/pendingq_count",
|
||||
+ grp_dev, sub_dev);
|
||||
+ util_file_read_l(&pending2, 10, "%s/%s/requestq_count",
|
||||
+ grp_dev, sub_dev);
|
||||
+ util_rec_set(rec, "pending", "%ld", pending1 + pending2);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
||||
util_rec_set(rec, "hwtype", buf);
|
||||
@@ -370,7 +396,18 @@ static void read_subdev_rec_verbose(stru
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
- util_rec_set(rec, "facility", "0x%08x", facility);
|
||||
+ for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
+ buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
+ buf[i] = '\0';
|
||||
+ util_rec_set(rec, "facility", buf);
|
||||
+
|
||||
+ snprintf(afile, sizeof(afile), "%s/%s/driver", grp_dev, sub_dev);
|
||||
+ afile[sizeof(afile) - 1] = '\0';
|
||||
+ memset(buf, 0, sizeof(buf));
|
||||
+ if (readlink(afile, buf, sizeof(buf)) > 0)
|
||||
+ util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
|
||||
+ else
|
||||
+ util_rec_set(rec, "driver", "-no-driver-");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -382,9 +419,13 @@ static void show_subdevice(struct util_r
|
||||
if (!util_path_is_dir("%s/%s", grp_dev, sub_dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s/%s does not exist.", grp_dev, sub_dev);
|
||||
|
||||
- /* Skip devices, which are not supported by zcrypt layer */
|
||||
- if (!util_path_is_readable("%s/type", grp_dev) ||
|
||||
- !util_path_is_readable("%s/%s/online", grp_dev, sub_dev))
|
||||
+ /*
|
||||
+ * If not verbose mode, skip devices which are not supported
|
||||
+ * by the zcrypt layer.
|
||||
+ */
|
||||
+ if (l.verbose == 0 &&
|
||||
+ (!util_path_is_readable("%s/type", grp_dev) ||
|
||||
+ !util_path_is_readable("%s/%s/online", grp_dev, sub_dev)))
|
||||
return;
|
||||
|
||||
util_rec_set(rec, "card", sub_dev);
|
||||
@@ -414,11 +455,13 @@ static void show_subdevices(struct util_
|
||||
*/
|
||||
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||
{
|
||||
- unsigned long facility;
|
||||
char buf[256];
|
||||
+ unsigned long facility;
|
||||
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev);
|
||||
- util_rec_set(rec, "type", buf);
|
||||
+ if (util_file_read_line(buf, sizeof(buf), "%s/type", grp_dev))
|
||||
+ util_rec_set(rec, "type", "-");
|
||||
+ else
|
||||
+ util_rec_set(rec, "type", buf);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (facility & MASK_COPRO)
|
||||
@@ -430,14 +473,16 @@ static void read_rec_default(struct util
|
||||
else
|
||||
util_rec_set(rec, "mode", "Unknown");
|
||||
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev);
|
||||
- if (strcmp(buf, "0") == 0)
|
||||
- util_rec_set(rec, "online", "offline");
|
||||
+ if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
|
||||
+ util_rec_set(rec, "online", "-");
|
||||
else
|
||||
- util_rec_set(rec, "online", "online");
|
||||
+ if (strcmp(buf, "0") == 0)
|
||||
+ util_rec_set(rec, "online", "offline");
|
||||
+ else
|
||||
+ util_rec_set(rec, "online", "online");
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
||||
- util_rec_set(rec, "request_count", buf);
|
||||
+ util_rec_set(rec, "requests", buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -445,18 +490,17 @@ static void read_rec_default(struct util
|
||||
*/
|
||||
static void read_rec_verbose(struct util_rec *rec, const char *grp_dev)
|
||||
{
|
||||
+ int i;
|
||||
unsigned long facility;
|
||||
- char buf[256];
|
||||
- long depth;
|
||||
+ char buf[256], afile[PATH_MAX];
|
||||
+ long depth, pending1, pending2;
|
||||
|
||||
if (l.verbose == 0)
|
||||
return;
|
||||
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/pendingq_count", grp_dev);
|
||||
- util_rec_set(rec, "pendingq_count", buf);
|
||||
-
|
||||
- util_file_read_line(buf, sizeof(buf), "%s/requestq_count", grp_dev);
|
||||
- util_rec_set(rec, "requestq_count", buf);
|
||||
+ util_file_read_l(&pending1, 10, "%s/pendingq_count", grp_dev);
|
||||
+ util_file_read_l(&pending2, 10, "%s/requestq_count", grp_dev);
|
||||
+ util_rec_set(rec, "pending", "%ld", pending1 + pending2);
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/hwtype", grp_dev);
|
||||
util_rec_set(rec, "hwtype", buf);
|
||||
@@ -465,7 +509,18 @@ static void read_rec_verbose(struct util
|
||||
util_rec_set(rec, "depth", "%02d", depth + 1);
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
- util_rec_set(rec, "facility", "0x%08x", facility);
|
||||
+ for (i = 0; i < MAX_FAC_BITS; i++)
|
||||
+ buf[i] = facility & fac_bits[i].mask ? fac_bits[i].c : '-';
|
||||
+ buf[i] = '\0';
|
||||
+ util_rec_set(rec, "facility", buf);
|
||||
+
|
||||
+ snprintf(afile, sizeof(afile), "%s/driver", grp_dev);
|
||||
+ afile[sizeof(afile) - 1] = '\0';
|
||||
+ memset(buf, 0, sizeof(buf));
|
||||
+ if (readlink(afile, buf, sizeof(buf)) > 0)
|
||||
+ util_rec_set(rec, "driver", strrchr(buf, '/') + 1);
|
||||
+ else
|
||||
+ util_rec_set(rec, "driver", "-no-driver-");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -481,9 +536,14 @@ static void show_device(struct util_rec
|
||||
grp_dev = util_path_sysfs("devices/ap/%s", device);
|
||||
if (!util_path_is_dir(grp_dev))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
||||
- /* Skip devices, which are not supported by zcrypt layer */
|
||||
- if (!util_path_is_readable("%s/type", grp_dev) ||
|
||||
- !util_path_is_readable("%s/online", grp_dev)) {
|
||||
+
|
||||
+ /*
|
||||
+ * If not verbose mode, skip devices which are not supported
|
||||
+ * by the zcrypt layer.
|
||||
+ */
|
||||
+ if (l.verbose == 0 &&
|
||||
+ (!util_path_is_readable("%s/type", grp_dev) ||
|
||||
+ !util_path_is_readable("%s/online", grp_dev))) {
|
||||
goto out_free;
|
||||
}
|
||||
util_rec_set(rec, "card", card);
|
||||
@@ -506,8 +566,7 @@ static void define_rec_default(struct ut
|
||||
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
|
||||
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
|
||||
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
|
||||
- util_rec_def(rec, "request_count", UTIL_REC_ALIGN_RIGHT, 11,
|
||||
- "REQUEST_CNT");
|
||||
+ util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -517,13 +576,11 @@ static void define_rec_verbose(struct ut
|
||||
{
|
||||
if (l.verbose == 0)
|
||||
return;
|
||||
- util_rec_def(rec, "pendingq_count", UTIL_REC_ALIGN_RIGHT, 12,
|
||||
- "PENDINGQ_CNT");
|
||||
- util_rec_def(rec, "requestq_count", UTIL_REC_ALIGN_RIGHT, 12,
|
||||
- "REQUESTQ_CNT");
|
||||
- util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 7, "HW_TYPE");
|
||||
- util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 7, "Q_DEPTH");
|
||||
+ util_rec_def(rec, "pending", UTIL_REC_ALIGN_RIGHT, 8, "PENDING");
|
||||
+ util_rec_def(rec, "hwtype", UTIL_REC_ALIGN_RIGHT, 6, "HWTYPE");
|
||||
+ util_rec_def(rec, "depth", UTIL_REC_ALIGN_RIGHT, 6, "QDEPTH");
|
||||
util_rec_def(rec, "facility", UTIL_REC_ALIGN_LEFT, 10, "FUNCTIONS");
|
||||
+ util_rec_def(rec, "driver", UTIL_REC_ALIGN_LEFT, 11, "DRIVER");
|
||||
}
|
||||
|
||||
/*
|
@ -1,43 +0,0 @@
|
||||
Subject: util_path: Add description for util_path_exists()
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: d0e2caf0ffb195568bba89a95549a5a4f026a4e6
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
util_path: Add description for util_path_exists()
|
||||
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
libutil/util_path.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/libutil/util_path.c
|
||||
+++ b/libutil/util_path.c
|
||||
@@ -195,6 +195,17 @@ free_str:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Test if path to directory or file exists
|
||||
+ *
|
||||
+ * This function has the same semantics as "-e path" in bash.
|
||||
+ *
|
||||
+ * @param[in] fmt Format string for path to test
|
||||
+ * @param[in] ... Variable arguments for format string
|
||||
+ *
|
||||
+ * @returns true Path exists
|
||||
+ * false Otherwise
|
||||
+ */
|
||||
bool util_path_exists(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
@ -1,287 +0,0 @@
|
||||
Subject: zdev: Prepare for firmware configuration file support
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: ab4445c261749caa7aee2154e3b26c767b6c5e60
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Prepare for firmware configuration file support
|
||||
|
||||
Apply some changes to existing functions and data structures to simplify
|
||||
the firmware configuration file support implementation.
|
||||
|
||||
- Make qeth and dasd subtype objects non-static
|
||||
- Change the existing helper functions for reading file contents into
|
||||
memory to also support binary functions
|
||||
- Move some configuration file import functions to make them available
|
||||
for use in other source files
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/include/dasd.h | 3 ++
|
||||
zdev/include/device.h | 2 +
|
||||
zdev/include/export.h | 1
|
||||
zdev/include/misc.h | 1
|
||||
zdev/include/qeth.h | 2 +
|
||||
zdev/src/dasd.c | 4 +--
|
||||
zdev/src/device.c | 13 +++++++++++
|
||||
zdev/src/export.c | 17 +-------------
|
||||
zdev/src/misc.c | 48 ++++++++++++++++++++++++++++++------------
|
||||
zdev/src/qeth.c | 2 -
|
||||
10 files changed, 62 insertions(+), 31 deletions(-)
|
||||
|
||||
--- a/zdev/include/dasd.h
|
||||
+++ b/zdev/include/dasd.h
|
||||
@@ -11,7 +11,10 @@
|
||||
#define DASD_H
|
||||
|
||||
struct devtype;
|
||||
+struct subtype;
|
||||
|
||||
extern struct devtype dasd_devtype;
|
||||
+extern struct subtype dasd_subtype_eckd;
|
||||
+extern struct subtype dasd_subtype_fba;
|
||||
|
||||
#endif /* DASD_H */
|
||||
--- a/zdev/include/device.h
|
||||
+++ b/zdev/include/device.h
|
||||
@@ -94,5 +94,7 @@ void device_list_add(struct device_list
|
||||
struct device *device_list_find(struct device_list *, const char *,
|
||||
struct device *);
|
||||
void device_list_print(struct device_list *, int);
|
||||
+struct setting_list *device_get_setting_list(struct device *dev,
|
||||
+ config_t config);
|
||||
|
||||
#endif /* DEVICE_H */
|
||||
--- a/zdev/include/export.h
|
||||
+++ b/zdev/include/export.h
|
||||
@@ -31,6 +31,7 @@ struct export_object {
|
||||
} ptr;
|
||||
};
|
||||
|
||||
+struct export_object *object_new(export_t type, void *ptr);
|
||||
exit_code_t export_write_device(FILE *, struct device *, config_t, int *);
|
||||
exit_code_t export_write_devtype(FILE *, struct devtype *, config_t, int *);
|
||||
exit_code_t export_read(FILE *, const char *, struct util_list *);
|
||||
--- a/zdev/include/misc.h
|
||||
+++ b/zdev/include/misc.h
|
||||
@@ -159,6 +159,7 @@ bool misc_read_dir(const char *, struct
|
||||
bool (*)(const char *, void *), void *);
|
||||
bool file_is_devnode(const char *);
|
||||
exit_code_t remove_file(const char *);
|
||||
+exit_code_t misc_read_fd(FILE *fd, void **buffer, size_t *size_ptr);
|
||||
char *misc_read_text_file(const char *, int, err_t);
|
||||
char *misc_read_cmd_output(const char *, int, err_t);
|
||||
char *config_read_cmd_output(const char *, int, err_t);
|
||||
--- a/zdev/include/qeth.h
|
||||
+++ b/zdev/include/qeth.h
|
||||
@@ -17,9 +17,11 @@
|
||||
#define QETH_NUM_DEVS 3
|
||||
|
||||
struct devtype;
|
||||
+struct subtype;
|
||||
struct namespace;
|
||||
|
||||
extern struct devtype qeth_devtype;
|
||||
+extern struct subtype qeth_subtype_qeth;
|
||||
extern struct namespace qeth_namespace;
|
||||
|
||||
#endif /* QETH_H */
|
||||
--- a/zdev/src/dasd.c
|
||||
+++ b/zdev/src/dasd.c
|
||||
@@ -589,7 +589,7 @@ static struct ccw_subtype_data dasd_eckd
|
||||
.mod = "dasd_eckd_mod",
|
||||
};
|
||||
|
||||
-static struct subtype dasd_subtype_eckd = {
|
||||
+struct subtype dasd_subtype_eckd = {
|
||||
.super = &ccw_subtype,
|
||||
.devtype = &dasd_devtype,
|
||||
.name = "dasd-eckd",
|
||||
@@ -626,7 +626,7 @@ static struct ccw_subtype_data dasd_fba_
|
||||
.mod = "dasd_fba_mod",
|
||||
};
|
||||
|
||||
-static struct subtype dasd_subtype_fba = {
|
||||
+struct subtype dasd_subtype_fba = {
|
||||
.super = &ccw_subtype,
|
||||
.devtype = &dasd_devtype,
|
||||
.name = "dasd-fba",
|
||||
--- a/zdev/src/device.c
|
||||
+++ b/zdev/src/device.c
|
||||
@@ -570,3 +570,16 @@ exit_code_t device_check_settings(struct
|
||||
|
||||
return EXIT_OK;
|
||||
}
|
||||
+
|
||||
+struct setting_list *device_get_setting_list(struct device *dev,
|
||||
+ config_t config)
|
||||
+{
|
||||
+ struct setting_list *settings = NULL;
|
||||
+
|
||||
+ if (config == config_active)
|
||||
+ settings = dev->active.settings;
|
||||
+ else
|
||||
+ settings = dev->persistent.settings;
|
||||
+
|
||||
+ return settings;
|
||||
+}
|
||||
--- a/zdev/src/export.c
|
||||
+++ b/zdev/src/export.c
|
||||
@@ -282,19 +282,6 @@ static bool parse_setting(const char *li
|
||||
return true;
|
||||
}
|
||||
|
||||
-static struct setting_list *dev_get_setting_list(struct device *dev,
|
||||
- config_t config)
|
||||
-{
|
||||
- struct setting_list *settings = NULL;
|
||||
-
|
||||
- if (config == config_active)
|
||||
- settings = dev->active.settings;
|
||||
- else
|
||||
- settings = dev->persistent.settings;
|
||||
-
|
||||
- return settings;
|
||||
-}
|
||||
-
|
||||
static struct setting_list *dt_get_setting_list(struct devtype *dt,
|
||||
config_t config)
|
||||
{
|
||||
@@ -426,7 +413,7 @@ static exit_code_t handle_setting(const
|
||||
} else if (dev) {
|
||||
/* We're inside a device section. */
|
||||
attribs = dev->subtype->dev_attribs;
|
||||
- list = dev_get_setting_list(dev, config);
|
||||
+ list = device_get_setting_list(dev, config);
|
||||
} else
|
||||
return EXIT_OK;
|
||||
|
||||
@@ -444,7 +431,7 @@ static exit_code_t handle_setting(const
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
-static struct export_object *object_new(export_t type, void *ptr)
|
||||
+struct export_object *object_new(export_t type, void *ptr)
|
||||
{
|
||||
struct export_object *obj;
|
||||
|
||||
--- a/zdev/src/misc.c
|
||||
+++ b/zdev/src/misc.c
|
||||
@@ -98,26 +98,47 @@ static void dryrun_end_data(void)
|
||||
|
||||
#define READ_CHUNK_SIZE 4096
|
||||
|
||||
-/* Read text from @fd and return resulting NULL-terminated text buffer.
|
||||
- * If @chomp is non-zero, remove trailing newline character. Return %NULL
|
||||
- * on error or when unprintable characters are read. */
|
||||
-static char *read_fd(FILE *fd, int chomp)
|
||||
+/* Read all data from @fd and return address of resulting buffer in
|
||||
+ * @buffer_ptr. If @size_ptr is non-zero, use it to store the size of the
|
||||
+ * resulting buffer. Return %EXIT_OK on success. */
|
||||
+exit_code_t misc_read_fd(FILE *fd, void **buffer_ptr, size_t *size_ptr)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
- size_t done, i;
|
||||
+ size_t done = 0;
|
||||
|
||||
- done = 0;
|
||||
while (!feof(fd)) {
|
||||
- buffer = realloc(buffer, done + READ_CHUNK_SIZE + 1);
|
||||
+ buffer = realloc(buffer, done + READ_CHUNK_SIZE);
|
||||
if (!buffer)
|
||||
oom();
|
||||
done += fread(&buffer[done], 1, READ_CHUNK_SIZE, fd);
|
||||
if (ferror(fd)) {
|
||||
free(buffer);
|
||||
- return NULL;
|
||||
+ return EXIT_RUNTIME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+ buffer = realloc(buffer, done);
|
||||
+ if (!buffer && done > 0)
|
||||
+ oom();
|
||||
+
|
||||
+ *buffer_ptr = buffer;
|
||||
+ if (size_ptr)
|
||||
+ *size_ptr = done;
|
||||
+
|
||||
+ return EXIT_OK;
|
||||
+}
|
||||
+
|
||||
+/* Read text from @fd and return resulting NULL-terminated text buffer.
|
||||
+ * If @chomp is non-zero, remove trailing newline character. Return %NULL
|
||||
+ * on error or when unprintable characters are read. */
|
||||
+static char *read_fd(FILE *fd, int chomp)
|
||||
+{
|
||||
+ char *buffer;
|
||||
+ size_t done, i;
|
||||
+
|
||||
+ if (misc_read_fd(fd, (void **) &buffer, &done))
|
||||
+ return NULL;
|
||||
+
|
||||
/* Check if this is a text file at all (required to filter out
|
||||
* binary sysfs attributes). */
|
||||
for (i = 0; i < done; i++) {
|
||||
@@ -131,12 +152,13 @@ static char *read_fd(FILE *fd, int chomp
|
||||
if (chomp && done > 0 && buffer[done - 1] == '\n')
|
||||
done--;
|
||||
|
||||
- if (buffer) {
|
||||
- /* NULL-terminate. */
|
||||
- buffer[done++] = 0;
|
||||
- }
|
||||
+ /* NULL-terminate. */
|
||||
+ buffer = realloc(buffer, done + 1);
|
||||
+ if (!buffer)
|
||||
+ oom();
|
||||
+ buffer[done] = 0;
|
||||
|
||||
- return realloc(buffer, done);
|
||||
+ return buffer;
|
||||
}
|
||||
|
||||
static int count_newline(const char *str)
|
||||
--- a/zdev/src/qeth.c
|
||||
+++ b/zdev/src/qeth.c
|
||||
@@ -1369,7 +1369,7 @@ static struct ccwgroup_subtype_data qeth
|
||||
.num_devs = QETH_NUM_DEVS,
|
||||
};
|
||||
|
||||
-static struct subtype qeth_subtype_qeth = {
|
||||
+struct subtype qeth_subtype_qeth = {
|
||||
.super = &ccwgroup_subtype,
|
||||
.devtype = &qeth_devtype,
|
||||
.name = "qeth",
|
@ -1,107 +0,0 @@
|
||||
Subject: cpumf/cpumf_helper: read split counter sets (part 2/2)
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: 1064e5b9cc3bdeb5731c2e152ce146dfdad27e6f
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf/cpumf_helper: read split counter sets (part 2/2)
|
||||
|
||||
Update the cpumf helper program to read the split counter set
|
||||
definition files. Changes to higher-level program like lscpumf
|
||||
are not necessary.
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/bin/cpumf_helper.in | 50 ++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 42 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/cpumf/bin/cpumf_helper.in
|
||||
+++ b/cpumf/bin/cpumf_helper.in
|
||||
@@ -229,6 +229,28 @@ sub get_hardware_type()
|
||||
return $type;
|
||||
}
|
||||
|
||||
+sub get_cpum_cf_version()
|
||||
+{
|
||||
+ my $SL;
|
||||
+
|
||||
+ my $v = {
|
||||
+ cfvn => 0,
|
||||
+ csvn => 0,
|
||||
+ };
|
||||
+
|
||||
+ return $v unless open($SL, '<', $SERVICE_LEVELS);
|
||||
+ while (my $line = <$SL>) {
|
||||
+ # CPU-MF: Counter facility: version=3.5
|
||||
+ if ($line =~ m/^CPU-MF: Counter facility: version=(\d+)\.(\d+)/) {
|
||||
+ $v->{cfvn} = $1; # Counter First Version Number
|
||||
+ $v->{csvn} = $2; # Counter Second Version Number
|
||||
+ last;
|
||||
+ }
|
||||
+ }
|
||||
+ close($SL);
|
||||
+ return $v
|
||||
+}
|
||||
+
|
||||
sub cpumf_load_ctrdef($;$)
|
||||
{
|
||||
my $hw_type = shift();
|
||||
@@ -237,10 +259,20 @@ sub cpumf_load_ctrdef($;$)
|
||||
my $ctrmap = cpumf_hardware_counter_map();
|
||||
return unless $ctrmap;
|
||||
|
||||
+ # Obtain CPU-MF counter facility versions
|
||||
+ my $version = get_cpum_cf_version();
|
||||
+
|
||||
+ # List of "generic" counter sets
|
||||
+ my @def = ();
|
||||
+ push @def, "cfvn-" . $version->{cfvn};
|
||||
+ push @def, "csvn-generic";
|
||||
+
|
||||
my $h = {};
|
||||
- # Load generic counter sets
|
||||
- cpumf_parse_ctrdef($ctrmap->{0}, $h) or
|
||||
- croak "Failed to read generic counter definition: $!\n";
|
||||
+ # Load counter set definition
|
||||
+ foreach my $ent (@def) {
|
||||
+ cpumf_parse_ctrdef($ctrmap->{$ent}, $h) or
|
||||
+ croak "Failed to read counter definition for $ent: $!\n";
|
||||
+ }
|
||||
# Load hardware model specific counter set(s)
|
||||
if ($hw_type && $ctrmap->{$hw_type}) {
|
||||
# Hardware-model specific counter sets are:
|
||||
@@ -323,7 +355,7 @@ sub cpumf_helper_main()
|
||||
GetOptions(
|
||||
"i|info" => \$conf->{opt_info},
|
||||
"c|counter=i" => \$conf->{opt_ctr},
|
||||
- "ctr-def=i" => \$conf->{opt_ctrdef},
|
||||
+ "ctr-def=s" => \$conf->{opt_ctrdef},
|
||||
"hardware-type" => \$conf->{opt_hwtype},
|
||||
"ctr-set-names" => \$conf->{opt_ctrset_names},
|
||||
"ctr-set-ids" => \$conf->{opt_ctrset_ids},
|
||||
@@ -428,11 +460,13 @@ B<--ctr-def> option and specify the Syst
|
||||
|
||||
Displays the System z hardware type.
|
||||
|
||||
-=item B<--ctr-def> I<hardware_type>
|
||||
+=item B<--ctr-def> I<ctr-definition>
|
||||
|
||||
-Displays detailed information about a particular counter set for the specified
|
||||
-System z hardware type, I<hardware_type>. If you specify zero for
|
||||
-I<hardware_type>, type-independent counter sets are displayed.
|
||||
+Displays detailed information about the specified counter definition.
|
||||
+Valid counter definitions start with C<cfvn-> or <csvn-> followed by
|
||||
+the counter first/second version number of the CPU-Measurement Counter
|
||||
+Facility. To display counter information of model-specific counter
|
||||
+sets, specify the System z hardware type for I<ctr-definition>.
|
||||
|
||||
=item B<--ctr-set-names>
|
||||
|
@ -1,34 +0,0 @@
|
||||
Subject: util_path: Make true/false handling consistent with other functions
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: 2b92bc4c087fd7a2275ba8fd5608cf3c86cdcc98
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
util_path: Make true/false handling consistent with other functions
|
||||
|
||||
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
libutil/util_path.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/libutil/util_path.c
|
||||
+++ b/libutil/util_path.c
|
||||
@@ -213,7 +213,7 @@ bool util_path_exists(const char *fmt, .
|
||||
bool rc;
|
||||
|
||||
UTIL_VASPRINTF(&path, fmt, ap);
|
||||
- rc = access(path, F_OK) == 0;
|
||||
+ rc = access(path, F_OK) == 0 ? true : false;
|
||||
free(path);
|
||||
return rc;
|
||||
}
|
@ -1,874 +0,0 @@
|
||||
Subject: zdev: Add support for reading firmware configuration files
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: 7d355b0fec964ad84ecaf88eb946121d39486070
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Add support for reading firmware configuration files
|
||||
|
||||
Add support for reading firmware-provided I/O configuration data files.
|
||||
Such configuration files are generated by the Dynamic Partition Manager
|
||||
and made available via a kernel interface for consumption by Linux.
|
||||
|
||||
To read a firmware configuration file, use the existing --import option:
|
||||
|
||||
# chzdev --import /sys/firmware/sclp_sd/config/data
|
||||
|
||||
This will apply all I/O configuration data found in the specified file
|
||||
to the persistent configuration.
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/include/firmware.h | 25 +
|
||||
zdev/man/chzdev.8 | 16
|
||||
zdev/src/Makefile | 2
|
||||
zdev/src/chzdev.c | 21 -
|
||||
zdev/src/firmware.c | 676 ++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 730 insertions(+), 10 deletions(-)
|
||||
|
||||
--- /dev/null
|
||||
+++ b/zdev/include/firmware.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/*
|
||||
+ * zdev - Modify and display the persistent configuration of devices
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 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 FIRMWARE_H
|
||||
+#define FIRMWARE_H
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+#include "exit_code.h"
|
||||
+#include "misc.h"
|
||||
+
|
||||
+struct util_list;
|
||||
+
|
||||
+bool firmware_detect(FILE *fd);
|
||||
+exit_code_t firmware_read(FILE *fd, const char *filename, long skip,
|
||||
+ config_t config, struct util_list *objects);
|
||||
+
|
||||
+#endif /* FIRMWARE_H */
|
||||
--- a/zdev/man/chzdev.8
|
||||
+++ b/zdev/man/chzdev.8
|
||||
@@ -409,13 +409,23 @@ default value.
|
||||
.PP
|
||||
.
|
||||
.OD import "" "FILENAME" "|-"
|
||||
-Import configuration data from a text file.
|
||||
+Import configuration data from a text or machine-provided file.
|
||||
|
||||
Reads configuration data from FILENAME and applies it. If a single hyphen ("-")
|
||||
is specified as FILENAME data is read from the standard input stream. The
|
||||
-input format of the data read must be the same format as produced by the
|
||||
-chzdev \-\-export action.
|
||||
+input format must be either in the format as produced by the chzdev \-\-export
|
||||
+action, or in the format of a machine-provided I/O configuration data file.
|
||||
|
||||
+.B Machine-provided data:
|
||||
+Some machine models provide I/O configuration data which is made available
|
||||
+by the Linux kernel via a sysfs interface. While this data is intended for
|
||||
+automatic consumption during the boot phase, you can also apply it manually
|
||||
+using the \-\-import action like in the following example
|
||||
+
|
||||
+.B Example:
|
||||
+.CL chzdev --import /sys/firmware/sclp_sd/config/data
|
||||
+
|
||||
+.B Note:
|
||||
By default all configuration data that is read is also applied. To reduce the
|
||||
scope of imported configuration data, you can select specific devices, a device
|
||||
type, or define whether only data for the active or persistent configuration
|
||||
--- a/zdev/src/Makefile
|
||||
+++ b/zdev/src/Makefile
|
||||
@@ -8,7 +8,7 @@ ALL_CPPFLAGS += -I ../include -std=gnu99
|
||||
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
|
||||
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||
root.o select.o setting.o subtype.o table.o table_attribs.o \
|
||||
- table_types.o net.o
|
||||
+ table_types.o net.o firmware.o
|
||||
|
||||
# Devtype Helpers
|
||||
chzdev_objects += blkinfo.o ccw.o ccwgroup.o findmnt.o modprobe.o module.o \
|
||||
--- a/zdev/src/chzdev.c
|
||||
+++ b/zdev/src/chzdev.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "devnode.h"
|
||||
#include "devtype.h"
|
||||
#include "export.h"
|
||||
+#include "firmware.h"
|
||||
#include "inuse.h"
|
||||
#include "misc.h"
|
||||
#include "module.h"
|
||||
@@ -2500,9 +2501,9 @@ static exit_code_t do_export(struct opti
|
||||
/* Open output stream. */
|
||||
if (strcmp(opts->export, "-") == 0) {
|
||||
fd = stdout;
|
||||
- info("Exporting configuration data to standard output\n");
|
||||
+ info("Exporting data to standard output\n");
|
||||
} else {
|
||||
- info("Exporting configuration data to %s\n", opts->export);
|
||||
+ info("Exporting data to %s\n", opts->export);
|
||||
if (!util_path_exists(opts->export)) {
|
||||
rc = path_create(opts->export);
|
||||
if (rc)
|
||||
@@ -2735,6 +2736,7 @@ static exit_code_t do_import(struct opti
|
||||
exit_code_t drc = EXIT_OK;
|
||||
const char *filename;
|
||||
int found;
|
||||
+ bool is_firmware;
|
||||
|
||||
/* Open input stream. */
|
||||
if (strcmp(opts->import, "-") == 0) {
|
||||
@@ -2744,16 +2746,23 @@ static exit_code_t do_import(struct opti
|
||||
fd = fopen(opts->import, "r");
|
||||
filename = opts->import;
|
||||
}
|
||||
- info("Importing configuration data from %s\n", filename);
|
||||
+
|
||||
if (!fd) {
|
||||
error("Could not open file %s: %s\n", opts->import,
|
||||
strerror(errno));
|
||||
return EXIT_RUNTIME_ERROR;
|
||||
}
|
||||
|
||||
+ is_firmware = firmware_detect(fd);
|
||||
+ info("Importing data from %s%s\n", filename,
|
||||
+ is_firmware ? " (firmware format)" : "");
|
||||
+
|
||||
/* Read data. */
|
||||
objects = ptrlist_new();
|
||||
- rc = export_read(fd, filename, objects);
|
||||
+ if (is_firmware)
|
||||
+ rc = firmware_read(fd, filename, -1, opts->config, objects);
|
||||
+ else
|
||||
+ rc = export_read(fd, filename, objects);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
@@ -2766,8 +2775,8 @@ static exit_code_t do_import(struct opti
|
||||
"selection\n", filename);
|
||||
rc = EXIT_EMPTY_SELECTION;
|
||||
} else {
|
||||
- error("%s: No settings found to import\n", filename);
|
||||
- rc = EXIT_NO_DATA;
|
||||
+ info("%s: No settings found to import\n", filename);
|
||||
+ rc = EXIT_OK;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
--- /dev/null
|
||||
+++ b/zdev/src/firmware.c
|
||||
@@ -0,0 +1,676 @@
|
||||
+/*
|
||||
+ * zdev - Modify and display the persistent configuration of devices
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 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 <err.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "attrib.h"
|
||||
+#include "ccw.h"
|
||||
+#include "ccwgroup.h"
|
||||
+#include "dasd.h"
|
||||
+#include "device.h"
|
||||
+#include "export.h"
|
||||
+#include "firmware.h"
|
||||
+#include "misc.h"
|
||||
+#include "qeth.h"
|
||||
+#include "subtype.h"
|
||||
+#include "zfcp_host.h"
|
||||
+#include "zfcp_lun.h"
|
||||
+
|
||||
+/* In-memory firmware file representation. */
|
||||
+struct fw_file {
|
||||
+ const char *name;
|
||||
+ char *buffer;
|
||||
+ size_t size;
|
||||
+ char *last_access;
|
||||
+ size_t last_size;
|
||||
+};
|
||||
+
|
||||
+/* Record access to fields of the buffered file for use in warning messages. */
|
||||
+#define fwacc(f, x) ((f)->last_access = (char *) &(x), \
|
||||
+ (f)->last_size = sizeof(x), x)
|
||||
+
|
||||
+/*
|
||||
+ * Firmware file format definitions.
|
||||
+ */
|
||||
+
|
||||
+/* Firmware file header. */
|
||||
+struct fw_filehdr {
|
||||
+ uint32_t magic;
|
||||
+ uint16_t ver;
|
||||
+ uint16_t hdr_len;
|
||||
+ uint32_t file_len;
|
||||
+ uint32_t seq;
|
||||
+ uint32_t zeroes;
|
||||
+ uint16_t de_count;
|
||||
+ char unused[10];
|
||||
+} __packed;
|
||||
+
|
||||
+#define FW_HDR_MAGIC 0x7a646576 /* ASCII "zdev" */
|
||||
+#define FW_HDR_VER_Z14 0x0000
|
||||
+
|
||||
+/* I/O device ID. */
|
||||
+struct fw_iodevid {
|
||||
+ uint8_t cssid;
|
||||
+ uint8_t ssid;
|
||||
+ uint16_t devno;
|
||||
+} __packed;
|
||||
+
|
||||
+#define FW_IODEVID_FLAG_MCSS 0x01
|
||||
+
|
||||
+/* Device setting. */
|
||||
+struct fw_setting {
|
||||
+ uint16_t len;
|
||||
+ uint8_t key_type;
|
||||
+ uint8_t key_len;
|
||||
+ uint8_t val_type;
|
||||
+ uint8_t val_len;
|
||||
+ char data[];
|
||||
+} __packed;
|
||||
+
|
||||
+#define FW_SETTING_KEYTYPE_ASCII 0x00
|
||||
+#define FW_SETTING_VALTYPE_ASCII 0x00
|
||||
+#define FW_SETTING_VALTYPE_UINT 0x01
|
||||
+
|
||||
+/* Device settings list. */
|
||||
+struct fw_setlist {
|
||||
+ uint16_t len;
|
||||
+ char data[];
|
||||
+} __packed;
|
||||
+
|
||||
+/* Device entry header. */
|
||||
+struct fw_dehdr {
|
||||
+ uint16_t type;
|
||||
+ uint16_t len;
|
||||
+ uint32_t seq;
|
||||
+} __packed;
|
||||
+
|
||||
+#define FW_DE_HDR_TYPE_DASD 0x0001
|
||||
+#define FW_DE_HDR_TYPE_ZFCP_HOST 0x0002
|
||||
+#define FW_DE_HDR_TYPE_ZFCP_LUN 0x0003
|
||||
+#define FW_DE_HDR_TYPE_QETH 0x0004
|
||||
+
|
||||
+/* DASD device entry. */
|
||||
+struct fw_dasd {
|
||||
+ struct fw_dehdr hdr;
|
||||
+ uint8_t id_flags;
|
||||
+ struct fw_iodevid id;
|
||||
+ char settings[];
|
||||
+} __packed;
|
||||
+
|
||||
+/* zFCP host device entry. */
|
||||
+struct fw_zfcp_host {
|
||||
+ struct fw_dehdr hdr;
|
||||
+ uint8_t id_flags;
|
||||
+ struct fw_iodevid id;
|
||||
+ char settings[];
|
||||
+} __packed;
|
||||
+
|
||||
+/* zFCP LUN device entry. */
|
||||
+struct fw_zfcp_lun {
|
||||
+ struct fw_dehdr hdr;
|
||||
+ uint8_t id_flags;
|
||||
+ struct fw_iodevid id;
|
||||
+ uint64_t wwpn;
|
||||
+ uint64_t fcp_lun;
|
||||
+ char settings[];
|
||||
+} __packed;
|
||||
+
|
||||
+/* QETH device entry. */
|
||||
+struct fw_qeth {
|
||||
+ struct fw_dehdr hdr;
|
||||
+ uint8_t id_flags;
|
||||
+ struct fw_iodevid read_id;
|
||||
+ struct fw_iodevid write_id;
|
||||
+ struct fw_iodevid data_id;
|
||||
+ char settings[];
|
||||
+} __packed;
|
||||
+
|
||||
+/* Emit a warning that refers to a position in a firmware file. */
|
||||
+static void fwwarn(struct fw_file *f, const char *fmt, ...)
|
||||
+{
|
||||
+ va_list args;
|
||||
+ off_t start = (off_t) (f->last_access - f->buffer),
|
||||
+ end = start + f->last_size - 1;
|
||||
+
|
||||
+ fprintf(stderr, "%s: ", f->name);
|
||||
+ if (start == end)
|
||||
+ fprintf(stderr, "Byte 0x%zx: ", start);
|
||||
+ else
|
||||
+ fprintf(stderr, "Bytes 0x%zx-0x%zx: ", start, end);
|
||||
+
|
||||
+ va_start(args, fmt);
|
||||
+ vfprintf(stderr, fmt, args);
|
||||
+ va_end(args);
|
||||
+ fprintf(stderr, "\n");
|
||||
+}
|
||||
+
|
||||
+/* Basic file format header sanity check. */
|
||||
+static bool check_header(struct fw_file *f, struct fw_filehdr *hdr)
|
||||
+{
|
||||
+ if (fwacc(f, hdr->magic) != FW_HDR_MAGIC)
|
||||
+ fwwarn(f, "Invalid file magic (0x%08x)", hdr->magic);
|
||||
+ else if (fwacc(f, hdr->ver) != FW_HDR_VER_Z14)
|
||||
+ fwwarn(f, "Unsupported file version (0x%04x)", hdr->ver);
|
||||
+ else
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+#define READ_RETRY 3
|
||||
+
|
||||
+/* Read a firmware configuration file. */
|
||||
+static exit_code_t read_fw(struct fw_file *file, FILE *fd, const char *filename)
|
||||
+{
|
||||
+ struct fw_file f = { NULL };
|
||||
+ struct fw_filehdr *hdr;
|
||||
+ char *buffer, *buffer2;
|
||||
+ size_t size, size2;
|
||||
+ int retry;
|
||||
+ exit_code_t rc = EXIT_OK;
|
||||
+
|
||||
+ for (retry = 0; retry < READ_RETRY; retry++) {
|
||||
+ /* Read complete file once */
|
||||
+ rc = misc_read_fd(fd, (void **) &buffer, &size);
|
||||
+ if (rc) {
|
||||
+ warn("%s: Could not read file", filename);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ if (!buffer) {
|
||||
+ /* Empty file - skip silently as this is the default
|
||||
+ * on machines without firmware support. */
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* Re-read complete file to detect in-flight modifications. */
|
||||
+ if (fseek(fd, 0, SEEK_SET) == -1) {
|
||||
+ /* Could be a pipe, socket, or FIFO - accept v1. */
|
||||
+ break;
|
||||
+ }
|
||||
+ rc = misc_read_fd(fd, (void **) &buffer2, &size2);
|
||||
+ if (rc || !buffer2) {
|
||||
+ /* Could not get second version - accept v1. */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (size == size2 && memcmp(buffer, buffer2, size) == 0) {
|
||||
+ /* No change */
|
||||
+ free(buffer2);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ free(buffer);
|
||||
+ free(buffer2);
|
||||
+ }
|
||||
+
|
||||
+ if (retry >= READ_RETRY) {
|
||||
+ warnx("%s: File changed %d times while reading - aborting",
|
||||
+ filename, retry);
|
||||
+ return EXIT_RUNTIME_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ /* Perform basic checks */
|
||||
+ f.name = filename;
|
||||
+ f.buffer = buffer;
|
||||
+ f.size = size;
|
||||
+ hdr = (void *) buffer;
|
||||
+ if (!check_header(&f, hdr)) {
|
||||
+ free(buffer);
|
||||
+ return EXIT_FORMAT_ERROR;
|
||||
+ }
|
||||
+ if (fwacc(&f, hdr->file_len) > size) {
|
||||
+ fwwarn(&f, "File length mismatch (expect %zu) - adjusting",
|
||||
+ size);
|
||||
+ hdr->file_len = size;
|
||||
+ }
|
||||
+
|
||||
+ *file = f;
|
||||
+
|
||||
+ return EXIT_OK;
|
||||
+}
|
||||
+
|
||||
+/* Return textual representation of a device entry type. */
|
||||
+static const char *type_to_str(uint16_t type)
|
||||
+{
|
||||
+ switch (type) {
|
||||
+ case FW_DE_HDR_TYPE_DASD:
|
||||
+ return "dasd";
|
||||
+ case FW_DE_HDR_TYPE_ZFCP_HOST:
|
||||
+ return "zfcp-host";
|
||||
+ case FW_DE_HDR_TYPE_ZFCP_LUN:
|
||||
+ return "zfcp-lun";
|
||||
+ case FW_DE_HDR_TYPE_QETH:
|
||||
+ return "qeth";
|
||||
+ default:
|
||||
+ return "<unknown>";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Convert a binary format device setting of the specified length to integer. */
|
||||
+static unsigned long parse_value(char *data, uint8_t len)
|
||||
+{
|
||||
+ switch (len) {
|
||||
+ case 1:
|
||||
+ return (unsigned long) *((uint8_t *) data);
|
||||
+ case 2:
|
||||
+ return (unsigned long) *((uint16_t *) data);
|
||||
+ case 4:
|
||||
+ return (unsigned long) *((uint32_t *) data);
|
||||
+ case 8:
|
||||
+ return (unsigned long) *((uint64_t *) data);
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Perform sanity checks on device setting. */
|
||||
+static bool check_setting(struct fw_file *f, struct fw_setting *set)
|
||||
+{
|
||||
+ /* Key sanity checks */
|
||||
+ if (fwacc(f, set->key_type) != FW_SETTING_KEYTYPE_ASCII) {
|
||||
+ fwwarn(f, "Unsupported key type: %d", set->key_type);
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (fwacc(f, set->key_len) < 1) {
|
||||
+ fwwarn(f, "Unsupported key length: %d", set->key_len);
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (sizeof(struct fw_setting) + fwacc(f, set->key_len) > set->len) {
|
||||
+ fwwarn(f, "Key length exceeds setting");
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (fwacc(f, set->data[set->key_len - 1])) {
|
||||
+ fwwarn(f, "Key not null-terminated");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /* Value sanity checks */
|
||||
+ if (fwacc(f, set->val_type) != FW_SETTING_VALTYPE_UINT &&
|
||||
+ fwacc(f, set->val_type) != FW_SETTING_VALTYPE_ASCII) {
|
||||
+ fwwarn(f, "Unsupported value type: %d", set->val_type);
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (fwacc(f, set->val_len) < 1) {
|
||||
+ fwwarn(f, "Unsupported value length: %d", set->val_len);
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (sizeof(struct fw_setting) + set->key_len +
|
||||
+ fwacc(f, set->val_len) > set->len) {
|
||||
+ fwwarn(f, "Value length exceeds setting");
|
||||
+ return false;
|
||||
+ }
|
||||
+ if ((set->val_type == FW_SETTING_VALTYPE_ASCII) &&
|
||||
+ fwacc(f, set->data[set->key_len + set->val_len - 1])) {
|
||||
+ fwwarn(f, "Value not null-terminated");
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (set->val_type == FW_SETTING_VALTYPE_UINT) {
|
||||
+ switch (fwacc(f, set->val_len)) {
|
||||
+ case 1:
|
||||
+ case 2:
|
||||
+ case 4:
|
||||
+ case 8:
|
||||
+ break;
|
||||
+ default:
|
||||
+ fwwarn(f, "Unsupported integer value length: %d",
|
||||
+ set->val_len);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/* Add a setting to the device. Emit a warning if the setting is not known. */
|
||||
+static void _add_setting(const char *filename, struct device *dev,
|
||||
+ config_t config, const char *key, const char *value)
|
||||
+{
|
||||
+ struct attrib *a;
|
||||
+ struct setting_list *list;
|
||||
+
|
||||
+ list = device_get_setting_list(dev, config);
|
||||
+ a = attrib_find(dev->subtype->dev_attribs, key);
|
||||
+ if (!a) {
|
||||
+ warnx("%s: Applying unknown device setting %s=%s", filename,
|
||||
+ key, value);
|
||||
+ }
|
||||
+ setting_list_apply(list, a, key, value);
|
||||
+}
|
||||
+
|
||||
+static void add_setting(const char *filename, struct device *dev,
|
||||
+ config_t config, const char *key, const char *value)
|
||||
+{
|
||||
+ if (SCOPE_ACTIVE(config))
|
||||
+ _add_setting(filename, dev, config_active, key, value);
|
||||
+ if (SCOPE_PERSISTENT(config))
|
||||
+ _add_setting(filename, dev, config_persistent, key, value);
|
||||
+}
|
||||
+
|
||||
+/* Parse a single device setting in firmware format and apply it to the
|
||||
+ * specified device. */
|
||||
+static void parse_setting(struct fw_file *f, struct fw_setting *set,
|
||||
+ struct device *dev, config_t config)
|
||||
+{
|
||||
+ char *ascii_key, *ascii_val;
|
||||
+ unsigned long ulong_val;
|
||||
+
|
||||
+ if (!check_setting(f, set))
|
||||
+ return;
|
||||
+
|
||||
+ ascii_key = &set->data[0];
|
||||
+ if (set->val_type == FW_SETTING_VALTYPE_UINT) {
|
||||
+ ulong_val = parse_value(&set->data[set->key_len], set->val_len);
|
||||
+ ascii_val = misc_asprintf("%lu", ulong_val);
|
||||
+ add_setting(f->name, dev, config, ascii_key, ascii_val);
|
||||
+ free(ascii_val);
|
||||
+ } else {
|
||||
+ ascii_val = &set->data[set->key_len];
|
||||
+ add_setting(f->name, dev, config, ascii_key, ascii_val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Parse a device settings list in firmware format and apply the resulting
|
||||
+ * settings to the specified device. */
|
||||
+static void parse_settings(struct fw_file *f, char *data, struct device *dev,
|
||||
+ config_t config)
|
||||
+{
|
||||
+ struct fw_setlist *list = (struct fw_setlist *) data;
|
||||
+ struct fw_setting *set;
|
||||
+ uint16_t off;
|
||||
+
|
||||
+ for (off = sizeof(struct fw_setlist); off < list->len;
|
||||
+ off += set->len) {
|
||||
+ set = (struct fw_setting *) &data[off];
|
||||
+ if (fwacc(f, set->len) < sizeof(struct fw_setting)) {
|
||||
+ fwwarn(f, "Setting too short");
|
||||
+ break;
|
||||
+ }
|
||||
+ if (off + fwacc(f, set->len) > list->len) {
|
||||
+ fwwarn(f, "Setting too long");
|
||||
+ break;
|
||||
+ }
|
||||
+ parse_setting(f, set, dev, config);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Perform sanity checks on an I/O device ID. */
|
||||
+static bool check_iodevid(struct fw_file *f, uint8_t *flags,
|
||||
+ struct fw_iodevid *id)
|
||||
+{
|
||||
+
|
||||
+ if (fwacc(f, *flags) & FW_IODEVID_FLAG_MCSS) {
|
||||
+ fwwarn(f, "Unsupported entry in non-default CSS");
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (fwacc(f, id->cssid) != 0) {
|
||||
+ fwwarn(f, "Non-zero CSS-ID");
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/* Perform sanity checks on a device entry. */
|
||||
+static bool check_de_size(struct fw_file *f, struct fw_dehdr *de, size_t size)
|
||||
+{
|
||||
+ if (fwacc(f, de->len) < size) {
|
||||
+ fwwarn(f, "Device entry too short (expect %zu)", size);
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/* Convert an I/O device ID to CCW device ID format. */
|
||||
+static void io_to_ccw(struct ccw_devid *c, struct fw_iodevid *i)
|
||||
+{
|
||||
+ c->cssid = i->cssid;
|
||||
+ c->ssid = i->ssid;
|
||||
+ c->devno = i->devno;
|
||||
+}
|
||||
+
|
||||
+/* Register a new device configuration. */
|
||||
+static struct device *add_device(struct fw_file *f, struct subtype *st,
|
||||
+ const char *id, config_t config,
|
||||
+ struct util_list *objects)
|
||||
+{
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ if (!st->devices)
|
||||
+ st->devices = device_list_new(st);
|
||||
+
|
||||
+ dev = device_list_find(st->devices, id, NULL);
|
||||
+ if (!dev) {
|
||||
+ dev = device_new(st, id);
|
||||
+ if (!dev) {
|
||||
+ warnx("%s: Skipping invalid %s device ID %s", f->name,
|
||||
+ st->name, id);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ device_list_add(st->devices, dev);
|
||||
+ }
|
||||
+ ptrlist_add(objects, object_new(export_device, dev));
|
||||
+
|
||||
+ /* Prepare device for new settings. */
|
||||
+ if (SCOPE_ACTIVE(config)) {
|
||||
+ setting_list_clear(dev->active.settings);
|
||||
+ if (dev->subtype->support_definable)
|
||||
+ dev->active.definable = 1;
|
||||
+ else
|
||||
+ dev->active.exists = 1;
|
||||
+ }
|
||||
+ if (SCOPE_PERSISTENT(config)) {
|
||||
+ setting_list_clear(dev->persistent.settings);
|
||||
+ dev->persistent.exists = 1;
|
||||
+ }
|
||||
+
|
||||
+ return dev;
|
||||
+}
|
||||
+
|
||||
+/* Parse a DASD device entry. */
|
||||
+static void parse_dasd(struct fw_file *f, struct fw_dehdr *de, config_t config,
|
||||
+ struct util_list *objects)
|
||||
+{
|
||||
+ struct fw_dasd *dasd = (struct fw_dasd *) de;
|
||||
+ struct ccw_devid devid;
|
||||
+ struct device *dev_eckd, *dev_fba;
|
||||
+ char *id;
|
||||
+
|
||||
+ if (!check_de_size(f, de, sizeof(struct fw_dasd)))
|
||||
+ return;
|
||||
+ if (!check_iodevid(f, &dasd->id_flags, &dasd->id))
|
||||
+ return;
|
||||
+
|
||||
+ /* Could be either dasd_eckd or dasd_fba - add both entries */
|
||||
+ io_to_ccw(&devid, &dasd->id);
|
||||
+ id = ccw_devid_to_str(&devid);
|
||||
+ dev_eckd = add_device(f, &dasd_subtype_eckd, id, config, objects);
|
||||
+ dev_fba = add_device(f, &dasd_subtype_fba, id, config, objects);
|
||||
+ free(id);
|
||||
+
|
||||
+ if (dasd->hdr.len > sizeof(struct fw_dasd)) {
|
||||
+ if (dev_eckd)
|
||||
+ parse_settings(f, dasd->settings, dev_eckd, config);
|
||||
+ if (dev_fba)
|
||||
+ parse_settings(f, dasd->settings, dev_fba, config);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Parse a zFCP host device entry. */
|
||||
+static void parse_zfcp_host(struct fw_file *f, struct fw_dehdr *de,
|
||||
+ config_t config, struct util_list *objects)
|
||||
+{
|
||||
+ struct fw_zfcp_host *zfcp_host = (struct fw_zfcp_host *) de;
|
||||
+ struct ccw_devid devid;
|
||||
+ struct device *dev;
|
||||
+ char *id;
|
||||
+
|
||||
+ if (!check_de_size(f, de, sizeof(struct fw_zfcp_host)))
|
||||
+ return;
|
||||
+ if (!check_iodevid(f, &zfcp_host->id_flags, &zfcp_host->id))
|
||||
+ return;
|
||||
+
|
||||
+ /* Add zfcp_host entry */
|
||||
+ io_to_ccw(&devid, &zfcp_host->id);
|
||||
+ id = ccw_devid_to_str(&devid);
|
||||
+ dev = add_device(f, &zfcp_host_subtype, id, config, objects);
|
||||
+ free(id);
|
||||
+
|
||||
+ if (dev && zfcp_host->hdr.len > sizeof(struct fw_zfcp_host))
|
||||
+ parse_settings(f, zfcp_host->settings, dev, config);
|
||||
+}
|
||||
+
|
||||
+/* Parse a zFCP LUN device entry. */
|
||||
+static void parse_zfcp_lun(struct fw_file *f, struct fw_dehdr *de,
|
||||
+ config_t config, struct util_list *objects)
|
||||
+{
|
||||
+ struct fw_zfcp_lun *zfcp_lun = (struct fw_zfcp_lun *) de;
|
||||
+ struct zfcp_lun_devid devid;
|
||||
+ struct device *dev;
|
||||
+ char *id;
|
||||
+
|
||||
+ if (!check_de_size(f, de, sizeof(struct fw_zfcp_lun)))
|
||||
+ return;
|
||||
+ if (!check_iodevid(f, &zfcp_lun->id_flags, &zfcp_lun->id))
|
||||
+ return;
|
||||
+
|
||||
+ /* Add zfcp_lun entry */
|
||||
+ io_to_ccw(&devid.fcp_dev, &zfcp_lun->id);
|
||||
+ devid.wwpn = zfcp_lun->wwpn;
|
||||
+ devid.lun = zfcp_lun->fcp_lun;
|
||||
+ id = zfcp_lun_devid_to_str(&devid);
|
||||
+ dev = add_device(f, &zfcp_lun_subtype, id, config, objects);
|
||||
+ free(id);
|
||||
+
|
||||
+ if (dev && zfcp_lun->hdr.len > sizeof(struct fw_zfcp_lun))
|
||||
+ parse_settings(f, zfcp_lun->settings, dev, config);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/* Parse a QETH device entry. */
|
||||
+static void parse_qeth(struct fw_file *f, struct fw_dehdr *de, config_t config,
|
||||
+ struct util_list *objects)
|
||||
+{
|
||||
+ struct fw_qeth *qeth = (struct fw_qeth *) de;
|
||||
+ struct ccwgroup_devid devid;
|
||||
+ struct device *dev;
|
||||
+ char *id;
|
||||
+
|
||||
+ if (!check_de_size(f, de, sizeof(struct fw_qeth)))
|
||||
+ return;
|
||||
+ if (!check_iodevid(f, &qeth->id_flags, &qeth->read_id) ||
|
||||
+ !check_iodevid(f, &qeth->id_flags, &qeth->write_id) ||
|
||||
+ !check_iodevid(f, &qeth->id_flags, &qeth->data_id))
|
||||
+ return;
|
||||
+
|
||||
+ /* Add qeth entry */
|
||||
+ devid.num = 3;
|
||||
+ io_to_ccw(&devid.devid[0], &qeth->read_id);
|
||||
+ io_to_ccw(&devid.devid[1], &qeth->write_id);
|
||||
+ io_to_ccw(&devid.devid[2], &qeth->data_id);
|
||||
+ id = ccwgroup_devid_to_str(&devid);
|
||||
+ dev = add_device(f, &qeth_subtype_qeth, id, config, objects);
|
||||
+ free(id);
|
||||
+
|
||||
+ if (dev && qeth->hdr.len > sizeof(struct fw_qeth))
|
||||
+ parse_settings(f, qeth->settings, dev, config);
|
||||
+}
|
||||
+
|
||||
+/* Parse a firmware file. */
|
||||
+static void parse_fw(struct fw_file *f, long skip, config_t config,
|
||||
+ struct util_list *objects)
|
||||
+{
|
||||
+ char *data = f->buffer;
|
||||
+ struct fw_filehdr *hdr = (struct fw_filehdr *) data;
|
||||
+ struct fw_dehdr *de;
|
||||
+ uint16_t count = 0;
|
||||
+ uint32_t off;
|
||||
+
|
||||
+ for (off = hdr->hdr_len; off < hdr->file_len; off += de->len) {
|
||||
+ count++;
|
||||
+ de = (struct fw_dehdr *) &data[off];
|
||||
+ if (fwacc(f, de->len) == 0) {
|
||||
+ fwwarn(f, "Empty device entry");
|
||||
+ break;
|
||||
+ }
|
||||
+ if (off + fwacc(f, de->len) > hdr->file_len) {
|
||||
+ fwwarn(f, "Device entry too long");
|
||||
+ break;
|
||||
+ }
|
||||
+ if (skip >= 0 && de->seq <= skip) {
|
||||
+ debug("Skipping %s entry due to sequence (%08x)\n",
|
||||
+ type_to_str(de->type), de->seq);
|
||||
+ continue;
|
||||
+ }
|
||||
+ switch (fwacc(f, de->type)) {
|
||||
+ case FW_DE_HDR_TYPE_DASD:
|
||||
+ parse_dasd(f, de, config, objects);
|
||||
+ break;
|
||||
+ case FW_DE_HDR_TYPE_ZFCP_HOST:
|
||||
+ parse_zfcp_host(f, de, config, objects);
|
||||
+ break;
|
||||
+ case FW_DE_HDR_TYPE_ZFCP_LUN:
|
||||
+ parse_zfcp_lun(f, de, config, objects);
|
||||
+ break;
|
||||
+ case FW_DE_HDR_TYPE_QETH:
|
||||
+ parse_qeth(f, de, config, objects);
|
||||
+ break;
|
||||
+ default:
|
||||
+ fwwarn(f, "Unknown entry (type=%04x)", de->type);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (count != fwacc(f, hdr->de_count))
|
||||
+ fwwarn(f, "Device entry count mismatch");
|
||||
+}
|
||||
+
|
||||
+/* Read configuration objects from @fd in firmware file format. Add pointers to
|
||||
+ * newly allocated struct export_objects to ptrlist @objects. If @skip is a
|
||||
+ * positive number, skip over entries with a sequence number equal to or
|
||||
+ * greater than @skip. */
|
||||
+exit_code_t firmware_read(FILE *fd, const char *filename, long skip,
|
||||
+ config_t config, struct util_list *objects)
|
||||
+{
|
||||
+ struct fw_file file;
|
||||
+ exit_code_t rc;
|
||||
+
|
||||
+ rc = read_fw(&file, fd, filename);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ parse_fw(&file, skip, config, objects);
|
||||
+ free(file.buffer);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Check if @fd refers to a file in binary firmware format. */
|
||||
+bool firmware_detect(FILE *fd)
|
||||
+{
|
||||
+ int c;
|
||||
+
|
||||
+ c = fgetc(fd);
|
||||
+ ungetc(c, fd);
|
||||
+
|
||||
+ /* Note: A full check would require looking at least at the first 4
|
||||
+ * bytes, but fd might be non-seekable (e.g. pipe). Since there is no
|
||||
+ * way that a textual import file can start with a 'z', looking at
|
||||
+ * the first char should be enough. */
|
||||
+
|
||||
+ return c == 'z';
|
||||
+}
|
@ -1,32 +0,0 @@
|
||||
Subject: cpumf: correct z14 counter number
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: 144bddbf5bce749549a289acbeb49337edaaea45
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf: correct z14 counter number
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/data/cpum-cf-extended-z14.ctr | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
+++ b/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
@@ -269,7 +269,7 @@ Description:
|
||||
Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED,
|
||||
EDMK, MP, SRP, SP, ZAP
|
||||
.
|
||||
-Counter:233 Name:LAST_HOST_TRANSLATIONS
|
||||
+Counter:232 Name:LAST_HOST_TRANSLATIONS
|
||||
Description:
|
||||
Last Host Translation done
|
||||
.
|
@ -1,157 +0,0 @@
|
||||
Subject: zdev: Implement --no-settle
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: f32bff96881a04bb68b895c23b13ae50daa9e7b4
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Implement --no-settle
|
||||
|
||||
There are some situations where running "udevadm settle" can result in
|
||||
a deadlock, such as in the early stages of initial RAM-disk processing.
|
||||
|
||||
Introduce a new command-line option --no-settle that can be used to
|
||||
suppress calling "udevadm settle" to allow chzdev to be run in such
|
||||
situations.
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/include/udev.h | 1 +
|
||||
zdev/man/chzdev.8 | 9 +++++++++
|
||||
zdev/src/chzdev.c | 9 +++++++++
|
||||
zdev/src/chzdev_usage.txt | 1 +
|
||||
zdev/src/udev.c | 3 +++
|
||||
5 files changed, 23 insertions(+)
|
||||
|
||||
--- a/zdev/include/udev.h
|
||||
+++ b/zdev/include/udev.h
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "exit_code.h"
|
||||
|
||||
extern int udev_need_settle;
|
||||
+extern int udev_no_settle;
|
||||
|
||||
/* Single key-operator-value entry in a udev rule line.*/
|
||||
struct udev_entry_node {
|
||||
--- a/zdev/man/chzdev.8
|
||||
+++ b/zdev/man/chzdev.8
|
||||
@@ -528,6 +528,15 @@ device configuration persistent. Typical
|
||||
initial RAM disk, or modifying the kernel command line.
|
||||
.PP
|
||||
.
|
||||
+.OD no-settle "" ""
|
||||
+Do not wait for udev processing to complete.
|
||||
+
|
||||
+Skips all calls to the udevadm tool that are intended to wait for udev to
|
||||
+finish processing before continuing. There is typically no need to use this
|
||||
+option unless chzdev is run in an environment where udev is not fully
|
||||
+functional (such as in the early phase of an initial RAM disk).
|
||||
+.PP
|
||||
+.
|
||||
.OD persistent "p" ""
|
||||
Apply changes to persistent configuration only.
|
||||
|
||||
--- a/zdev/src/chzdev.c
|
||||
+++ b/zdev/src/chzdev.c
|
||||
@@ -95,6 +95,7 @@ struct options {
|
||||
struct util_list *base; /* List of struct strlist_node */
|
||||
unsigned int verbose:1;
|
||||
unsigned int quiet:1;
|
||||
+ unsigned int no_settle:1;
|
||||
};
|
||||
|
||||
/* Makefile converts chzdev_usage.txt into C file which we include here. */
|
||||
@@ -136,6 +137,7 @@ enum {
|
||||
OPT_VERSION = 'v',
|
||||
OPT_VERBOSE = 'V',
|
||||
OPT_QUIET = 'q',
|
||||
+ OPT_NO_SETTLE = (OPT_ANONYMOUS_BASE+__COUNTER__),
|
||||
};
|
||||
|
||||
static struct opts_conflict conflict_list[] = {
|
||||
@@ -217,6 +219,7 @@ static const struct option opt_list[] =
|
||||
{ "base", required_argument, NULL, OPT_BASE },
|
||||
{ "verbose", no_argument, NULL, OPT_VERBOSE },
|
||||
{ "quiet", no_argument, NULL, OPT_QUIET },
|
||||
+ { "no-settle", no_argument, NULL, OPT_NO_SETTLE },
|
||||
{ NULL, no_argument, NULL, 0 },
|
||||
};
|
||||
|
||||
@@ -937,6 +940,11 @@ static exit_code_t parse_options(struct
|
||||
opts->quiet = 1;
|
||||
break;
|
||||
|
||||
+ case OPT_NO_SETTLE:
|
||||
+ /* --no-settle */
|
||||
+ opts->no_settle = 1;
|
||||
+ break;
|
||||
+
|
||||
case ':':
|
||||
/* Missing option argument. */
|
||||
syntax("Option '%s' requires an argument\n",
|
||||
@@ -2904,6 +2912,7 @@ int main(int argc, char *argv[])
|
||||
force = opts.force;
|
||||
yes = opts.yes;
|
||||
dryrun = opts.dryrun;
|
||||
+ udev_no_settle = opts.no_settle;
|
||||
path_set_base(opts.base);
|
||||
|
||||
if (dryrun)
|
||||
--- a/zdev/src/chzdev_usage.txt
|
||||
+++ b/zdev/src/chzdev_usage.txt
|
||||
@@ -54,5 +54,6 @@ OPTIONS
|
||||
--no-root-update Skip root device update
|
||||
--dry-run Display changes without applying
|
||||
--base PATH Use PATH as base for accessing files
|
||||
+ --no-settle Do not wait for udev to settle
|
||||
-V, --verbose Print additional run-time information
|
||||
-q, --quiet Print only minimal run-time information
|
||||
--- a/zdev/src/udev.c
|
||||
+++ b/zdev/src/udev.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "udev.h"
|
||||
|
||||
int udev_need_settle = 0;
|
||||
+int udev_no_settle;
|
||||
|
||||
/* Create a newly allocated udev entry. */
|
||||
static struct udev_entry_node *udev_entry_node_new(const char *key,
|
||||
@@ -403,5 +404,7 @@ exit_code_t udev_remove_rule(const char
|
||||
/* Wait for all current udev events to finish. */
|
||||
void udev_settle(void)
|
||||
{
|
||||
+ if (udev_no_settle)
|
||||
+ return;
|
||||
misc_system(err_ignore, "%s settle", PATH_UDEVADM);
|
||||
}
|
@ -1,603 +0,0 @@
|
||||
Subject: zpcictl: Introduce new tool zpcictl
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: 177cf8cfeb83f85bc164c462b5534f93be3bd979
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: Introduce new tool zpcictl
|
||||
|
||||
zpcictl is used to manage PCI devices on z Systems. In this first
|
||||
version it is mainly used to handle erroneous PCI devices by changing
|
||||
their state and make those changes known to the SE. Log data, such as
|
||||
S.M.A.R.T. data for NVMe devices, is sent alongside those state changes.
|
||||
|
||||
The state change is issued by sending data via the PCI 'report_error'
|
||||
sysfs attribute. It's a binary attribute which will cause the host to
|
||||
send an Adapter Notification Event.
|
||||
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
.gitignore | 1
|
||||
Makefile | 2
|
||||
zpcictl/Makefile | 18 ++
|
||||
zpcictl/zpcictl.8 | 80 +++++++++++
|
||||
zpcictl/zpcictl.c | 378 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
zpcictl/zpcictl.h | 60 ++++++++
|
||||
6 files changed, 538 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -87,3 +87,4 @@ zipl/boot/data.h
|
||||
zipl/src/chreipl_helper.device-mapper
|
||||
zipl/src/zipl
|
||||
zkey/zkey
|
||||
+zpcictl/zpcictl
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -8,7 +8,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt das
|
||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
- systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot
|
||||
+ systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot zpcictl
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
all: $(TOOL_DIRS)
|
||||
--- /dev/null
|
||||
+++ b/zpcictl/Makefile
|
||||
@@ -0,0 +1,18 @@
|
||||
+include ../common.mak
|
||||
+
|
||||
+all: zpcictl
|
||||
+
|
||||
+libs = $(rootdir)/libutil/libutil.a
|
||||
+
|
||||
+zpcictl: zpcictl.o $(libs)
|
||||
+
|
||||
+install: all
|
||||
+ $(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zpcictl $(DESTDIR)$(BINDIR)
|
||||
+ $(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 zpcictl.8 \
|
||||
+ $(DESTDIR)$(MANDIR)/man8
|
||||
+
|
||||
+clean:
|
||||
+ rm -f *.o *~ zpcictl core
|
||||
+
|
||||
+.PHONY: all install clean
|
||||
--- /dev/null
|
||||
+++ b/zpcictl/zpcictl.8
|
||||
@@ -0,0 +1,80 @@
|
||||
+.\" Copyright 2017 IBM Corp.
|
||||
+.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
+.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
+.\"
|
||||
+.\" Macro for inserting an option description prologue.
|
||||
+.\" .OD <long> [<short>] [args]
|
||||
+.de OD
|
||||
+. ds args "
|
||||
+. if !'\\$3'' .as args \fI\\$3\fP
|
||||
+. if !'\\$4'' .as args \\$4
|
||||
+. if !'\\$5'' .as args \fI\\$5\fP
|
||||
+. if !'\\$6'' .as args \\$6
|
||||
+. if !'\\$7'' .as args \fI\\$7\fP
|
||||
+. PD 0
|
||||
+. if !'\\$2'' .IP "\fB\-\\$2\fP \\*[args]" 4
|
||||
+. if !'\\$1'' .IP "\fB\-\-\\$1\fP \\*[args]" 4
|
||||
+. PD
|
||||
+..
|
||||
+.
|
||||
+.TH zpcictl 8 "Oct 2018" s390-tools zpcictl
|
||||
+.
|
||||
+.SH NAME
|
||||
+zpcictl - Manage PCI devices on z Systems
|
||||
+.
|
||||
+.
|
||||
+.SH SYNOPSIS
|
||||
+.B "zpcictl"
|
||||
+.I "OPTIONS"
|
||||
+.I "DEVICE"
|
||||
+.
|
||||
+.
|
||||
+.SH DESCRIPTION
|
||||
+.B zpcictl
|
||||
+is a tool for managing PCI devices on the IBM z Systems platform. It is
|
||||
+especially used for reporting errorneous PCI devices to the service element.
|
||||
+
|
||||
+.B Note:
|
||||
+For NVMe devices additional data (such as S.M.A.R.T. data) is collected and sent
|
||||
+with any error handling action. The smartmontools are required to be installed
|
||||
+for this to work.
|
||||
+.PP
|
||||
+.
|
||||
+.
|
||||
+.SH DEVICE
|
||||
+.B DEVICE
|
||||
+can be either the PCI slot address (e.g. 0000:00:00.0) or the main device node
|
||||
+of an NVMe device (e.g. /dev/nvme0).
|
||||
+.
|
||||
+.
|
||||
+.SH OPTIONS
|
||||
+.SS Error Handling
|
||||
+.OD reset "" "DEVICE"
|
||||
+Reset
|
||||
+.I DEVICE
|
||||
+and initiate a re-initialisation of the adapter.
|
||||
+.PP
|
||||
+.
|
||||
+.OD deconfigure "" "DEVICE"
|
||||
+De-configure
|
||||
+.I DEVICE
|
||||
+and prepare for any repair action. This action will move the
|
||||
+PCI device from a configured to a reserved state.
|
||||
+.PP
|
||||
+.
|
||||
+.OD report-error "" "DEVICE"
|
||||
+Report any device error for
|
||||
+.IR DEVICE .
|
||||
+The
|
||||
+.I DEVICE
|
||||
+is marked as erroneous and no further action is initiated on it.
|
||||
+.PP
|
||||
+.
|
||||
+.SS Misc
|
||||
+.OD help "h" ""
|
||||
+Print usage information, then exit.
|
||||
+.PP
|
||||
+.
|
||||
+.OD version "v" ""
|
||||
+Print version information, then exit.
|
||||
+.PP
|
||||
--- /dev/null
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -0,0 +1,378 @@
|
||||
+/*
|
||||
+ * zpcictl - Manage PCI devices on z Systems
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 2018
|
||||
+ *
|
||||
+ * s390-tools is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the MIT license. See LICENSE for details.
|
||||
+ */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+#include "lib/util_base.h"
|
||||
+#include "lib/util_libc.h"
|
||||
+#include "lib/util_opt.h"
|
||||
+#include "lib/util_path.h"
|
||||
+#include "lib/util_prg.h"
|
||||
+#include "lib/util_proc.h"
|
||||
+#include "lib/util_rec.h"
|
||||
+#include "lib/util_scandir.h"
|
||||
+
|
||||
+#include "zpcictl.h"
|
||||
+
|
||||
+#define SMARTCTL_CMDLINE "smartctl -x %s 2>/dev/null"
|
||||
+
|
||||
+static const struct util_prg prg = {
|
||||
+ .desc = "Use zpcictl to manage PCI devices on s390\n"
|
||||
+ "DEVICE is the slot id or node of the device (e.g. /dev/nvme0)",
|
||||
+ .args = "DEVICE",
|
||||
+ .copyright_vec = {
|
||||
+ {
|
||||
+ .owner = "IBM Corp.",
|
||||
+ .pub_first = 2018,
|
||||
+ .pub_last = 2018,
|
||||
+ },
|
||||
+ UTIL_PRG_COPYRIGHT_END
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+/* Defines for options with no short command */
|
||||
+#define OPT_RESET 128
|
||||
+#define OPT_DECONF 129
|
||||
+#define OPT_REPORT_ERR 130
|
||||
+
|
||||
+static struct util_opt opt_vec[] = {
|
||||
+ UTIL_OPT_SECTION("ERROR HANDLING"),
|
||||
+ {
|
||||
+ .option = { "reset", no_argument, NULL, OPT_RESET },
|
||||
+ .desc = "Reset device",
|
||||
+ .flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
+ },
|
||||
+ {
|
||||
+ .option = { "deconfigure", no_argument, NULL, OPT_DECONF },
|
||||
+ .desc = "De-configure device and prepare for any repair action",
|
||||
+ .flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
+ },
|
||||
+ {
|
||||
+ .option = { "report-error", no_argument, NULL, OPT_REPORT_ERR },
|
||||
+ .desc = "Report device error to service element (SE)",
|
||||
+ .flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
+ },
|
||||
+ UTIL_OPT_SECTION("MISC"),
|
||||
+ UTIL_OPT_HELP,
|
||||
+ UTIL_OPT_VERSION,
|
||||
+ UTIL_OPT_END
|
||||
+};
|
||||
+
|
||||
+static int is_char_dev(const char *dev)
|
||||
+{
|
||||
+ struct stat s;
|
||||
+
|
||||
+ if (stat(dev, &s))
|
||||
+ return 0;
|
||||
+
|
||||
+ return S_ISCHR(s.st_mode);
|
||||
+}
|
||||
+
|
||||
+static int is_blk_dev(const char *dev)
|
||||
+{
|
||||
+ struct stat s;
|
||||
+
|
||||
+ if (stat(dev, &s))
|
||||
+ return 0;
|
||||
+
|
||||
+ return S_ISBLK(s.st_mode);
|
||||
+}
|
||||
+
|
||||
+static void fopen_err(char *path)
|
||||
+{
|
||||
+ warnx("Could not open file %s: %s", path, strerror(errno));
|
||||
+ free(path);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+}
|
||||
+
|
||||
+#define READ_CHUNK_SIZE 512
|
||||
+
|
||||
+static char *collect_smart_data(struct zpci_device *pdev)
|
||||
+{
|
||||
+ char *buffer = NULL;
|
||||
+ size_t count = 0;
|
||||
+ char *cmd;
|
||||
+ FILE *fd;
|
||||
+
|
||||
+ util_asprintf(&cmd, SMARTCTL_CMDLINE, pdev->device);
|
||||
+ fd = popen(cmd, "r");
|
||||
+ if (!fd)
|
||||
+ goto out;
|
||||
+
|
||||
+ while (!feof(fd)) {
|
||||
+ buffer = realloc(buffer, count + READ_CHUNK_SIZE);
|
||||
+ if (!buffer) {
|
||||
+ warnx("Could not collect S.M.A.R.T. data");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ count += fread(&buffer[count], 1, READ_CHUNK_SIZE, fd);
|
||||
+ if (ferror(fd)) {
|
||||
+ free(buffer);
|
||||
+ buffer = NULL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ buffer = realloc(buffer, count);
|
||||
+ if (!buffer && count > 0)
|
||||
+ warnx("Could not collect S.M.A.R.T. data");
|
||||
+ if (buffer)
|
||||
+ buffer[count] = '\0';
|
||||
+
|
||||
+out:
|
||||
+ pclose(fd);
|
||||
+ free(cmd);
|
||||
+
|
||||
+ return buffer;
|
||||
+}
|
||||
+
|
||||
+static unsigned int sysfs_read_value(struct zpci_device *pdev, const char *attr)
|
||||
+{
|
||||
+ unsigned int val;
|
||||
+ char *path;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ path = util_path_sysfs("bus/pci/devices/%s/%s", pdev->slot, attr);
|
||||
+ fp = fopen(path, "r");
|
||||
+ if (!fp)
|
||||
+ fopen_err(path);
|
||||
+ fscanf(fp, "%x", &val);
|
||||
+ fclose(fp);
|
||||
+ free(path);
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static void sysfs_write_data(struct zpci_report_error *report, char *slot)
|
||||
+{
|
||||
+ char *path;
|
||||
+ int fd, rc;
|
||||
+
|
||||
+ path = util_path_sysfs("bus/pci/devices/%s/report_error", slot);
|
||||
+ fd = open(path, O_WRONLY);
|
||||
+ if (!fd)
|
||||
+ fopen_err(path);
|
||||
+ rc = write(fd, report, sizeof(*report));
|
||||
+ if (rc == -1)
|
||||
+ warnx("Could not write to file: %s: %s", path, strerror(errno));
|
||||
+ if (close(fd))
|
||||
+ warnx("Could not close file: %s: %s", path, strerror(errno));
|
||||
+ free(path);
|
||||
+}
|
||||
+
|
||||
+static void sysfs_get_slot_addr(const char *dev, char *slot)
|
||||
+{
|
||||
+ unsigned int major, minor;
|
||||
+ struct stat dev_stat;
|
||||
+ char addr[13];
|
||||
+ char *path;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ if (stat(dev, &dev_stat) != 0) {
|
||||
+ errx(EXIT_FAILURE, "Could not get stat information for %s: %s",
|
||||
+ dev, strerror(errno));
|
||||
+ }
|
||||
+ major = major(dev_stat.st_rdev);
|
||||
+ minor = minor(dev_stat.st_rdev);
|
||||
+
|
||||
+ path = util_path_sysfs("dev/char/%u:%u/address", major, minor);
|
||||
+ fp = fopen(path, "r");
|
||||
+ if (!fp)
|
||||
+ fopen_err(path);
|
||||
+ fscanf(fp, "%s", addr);
|
||||
+ fclose(fp);
|
||||
+ free(path);
|
||||
+
|
||||
+ strcpy(slot, addr);
|
||||
+}
|
||||
+
|
||||
+static void get_device_node(struct zpci_device *pdev)
|
||||
+{
|
||||
+ struct dirent **de_vec;
|
||||
+ char *path, *dev;
|
||||
+ char slot[13];
|
||||
+ int count, i;
|
||||
+
|
||||
+ path = util_path_sysfs("bus/pci/devices/%s/nvme", pdev->slot);
|
||||
+ count = util_scandir(&de_vec, alphasort, path, "nvme*");
|
||||
+ if (count == -1) {
|
||||
+ warnx("Could not read directory %s: %s", path, strerror(errno));
|
||||
+ free(path);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ util_asprintf(&dev, "/dev/%s", de_vec[i]->d_name);
|
||||
+ sysfs_get_slot_addr(dev, slot);
|
||||
+ if (strcmp(slot, pdev->slot) == 0) {
|
||||
+ pdev->device = dev;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ util_scandir_free(de_vec, count);
|
||||
+ free(path);
|
||||
+}
|
||||
+
|
||||
+static int device_exists(char *dev)
|
||||
+{
|
||||
+ char *path;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ path = util_path_sysfs("bus/pci/devices/%s", dev);
|
||||
+ if (util_path_exists(path) || util_path_exists(dev))
|
||||
+ rc = 1;
|
||||
+ free(path);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static void get_device_info(struct zpci_device *pdev, char *dev)
|
||||
+{
|
||||
+ if (!device_exists(dev))
|
||||
+ errx(EXIT_FAILURE, "Device %s not found", dev);
|
||||
+ if (is_blk_dev(dev))
|
||||
+ errx(EXIT_FAILURE, "Unsupported device type %s", dev);
|
||||
+ if (is_char_dev(dev)) {
|
||||
+ sysfs_get_slot_addr(dev, pdev->slot);
|
||||
+ pdev->device = dev;
|
||||
+ } else {
|
||||
+ strcpy(pdev->slot, dev);
|
||||
+ }
|
||||
+
|
||||
+ pdev->class = sysfs_read_value(pdev, "class");
|
||||
+ pdev->fid = sysfs_read_value(pdev, "function_id");
|
||||
+ pdev->pchid = sysfs_read_value(pdev, "pchid");
|
||||
+
|
||||
+ /* In case a slot address was specified, we still need to figure out
|
||||
+ * the device node for NVMe devices. Otherwise we won't be able to
|
||||
+ * collect S.M.A.R.T. data at a later point.
|
||||
+ */
|
||||
+ if (!pdev->device && pdev->class == PCI_CLASS_NVME)
|
||||
+ get_device_node(pdev);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Issue an SCLP Adapter Error Notification event with a specific action
|
||||
+ * qualifier.
|
||||
+ *
|
||||
+ * Collect additional information when possible (e.g. S.M.A.R.T. data for NVMe
|
||||
+ * devices).
|
||||
+ */
|
||||
+static void sclp_issue_action(struct zpci_device *pdev, int action)
|
||||
+{
|
||||
+ struct zpci_report_error report = {
|
||||
+ .header = { 0 },
|
||||
+ .data = { 0 }
|
||||
+ };
|
||||
+ char *sdata = NULL;
|
||||
+
|
||||
+ report.header.version = 1;
|
||||
+ report.header.action = action;
|
||||
+ report.header.length = sizeof(report.data);
|
||||
+ report.data.timestamp = (__u64)time(NULL);
|
||||
+ report.data.err_log_id = 0x4713;
|
||||
+
|
||||
+ if (pdev->class == PCI_CLASS_NVME)
|
||||
+ sdata = collect_smart_data(pdev);
|
||||
+ if (sdata) {
|
||||
+ strncpy(report.data.log_data, sdata, sizeof(report.data.log_data));
|
||||
+ free(sdata);
|
||||
+ }
|
||||
+ sysfs_write_data(&report, pdev->slot);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Reset the PCI device and initiate a re-initialization.
|
||||
+ */
|
||||
+static void sclp_reset_device(struct zpci_device *pdev)
|
||||
+{
|
||||
+ sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_RESET);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * De-Configure/repair PCI device. Moves the device from configured
|
||||
+ * to reserved state.
|
||||
+ */
|
||||
+static void sclp_deconfigure(struct zpci_device *pdev)
|
||||
+{
|
||||
+ sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_DECONF);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Report an error to the SE.
|
||||
+ */
|
||||
+static void sclp_report_error(struct zpci_device *pdev)
|
||||
+{
|
||||
+ sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_REPORT_ERR);
|
||||
+}
|
||||
+
|
||||
+static void parse_cmdline(int argc, char *argv[], struct options *opts)
|
||||
+{
|
||||
+ int cmd;
|
||||
+
|
||||
+ util_prg_init(&prg);
|
||||
+ util_opt_init(opt_vec, NULL);
|
||||
+
|
||||
+ do {
|
||||
+ cmd = util_opt_getopt_long(argc, argv);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case OPT_RESET:
|
||||
+ opts->reset = 1;
|
||||
+ break;
|
||||
+ case OPT_DECONF:
|
||||
+ opts->deconfigure = 1;
|
||||
+ break;
|
||||
+ case OPT_REPORT_ERR:
|
||||
+ opts->report = 1;
|
||||
+ break;
|
||||
+ case 'h':
|
||||
+ util_prg_print_help();
|
||||
+ util_opt_print_help();
|
||||
+ exit(EXIT_SUCCESS);
|
||||
+ case 'v':
|
||||
+ util_prg_print_version();
|
||||
+ exit(EXIT_SUCCESS);
|
||||
+ case -1:
|
||||
+ /* End of options string */
|
||||
+ if (argc == 1) {
|
||||
+ errx(EXIT_FAILURE,
|
||||
+ "Use '%s --help' for more information",
|
||||
+ argv[0]);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ } while (cmd != -1);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ struct zpci_device pdev = { 0 };
|
||||
+ struct options opts = { 0 };
|
||||
+
|
||||
+ parse_cmdline(argc, argv, &opts);
|
||||
+
|
||||
+ if (optind >= argc)
|
||||
+ errx(EXIT_FAILURE, "No device specified");
|
||||
+
|
||||
+ get_device_info(&pdev, argv[optind]);
|
||||
+
|
||||
+ if (opts.reset)
|
||||
+ sclp_reset_device(&pdev);
|
||||
+ else if (opts.deconfigure)
|
||||
+ sclp_deconfigure(&pdev);
|
||||
+ else if (opts.report)
|
||||
+ sclp_report_error(&pdev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/zpcictl/zpcictl.h
|
||||
@@ -0,0 +1,60 @@
|
||||
+/*
|
||||
+ * zpcictl - Manage PCI devices on z Systems
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 2018
|
||||
+ *
|
||||
+ * s390-tools is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the MIT license. See LICENSE for details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef ZPCICTL_H
|
||||
+#define ZPCICTL_H
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+#include "lib/zt_common.h"
|
||||
+
|
||||
+#define SCLP_ERRNOTIFY_AQ_RESET 0
|
||||
+#define SCLP_ERRNOTIFY_AQ_DECONF 1
|
||||
+#define SCLP_ERRNOTIFY_AQ_REPORT_ERR 2
|
||||
+
|
||||
+#define PCI_CLASS_UNCLASSIFIED 0x000000U
|
||||
+#define PCI_CLASS_NVME 0x010802U
|
||||
+#define PCI_CLASS_NETWORK 0x020000U
|
||||
+
|
||||
+struct options {
|
||||
+ unsigned int reset;
|
||||
+ unsigned int deconfigure;
|
||||
+ unsigned int report;
|
||||
+};
|
||||
+
|
||||
+struct zpci_device {
|
||||
+ u16 fid;
|
||||
+ u16 pchid;
|
||||
+ u32 class;
|
||||
+ char slot[13];
|
||||
+ char *device;
|
||||
+};
|
||||
+
|
||||
+struct zpci_report_error_header {
|
||||
+ __u8 version; /* Interface version byte */
|
||||
+ __u8 action; /* Action qualifier byte
|
||||
+ * 0: Adapter Reset Request
|
||||
+ * 1: Deconfigure and repair action requested
|
||||
+ * 2: Informational Report
|
||||
+ */
|
||||
+ __u16 length; /* Length of Subsequent Data (up to 4K – SCLP header) */
|
||||
+ __u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */
|
||||
+};
|
||||
+
|
||||
+struct zpci_report_error_data {
|
||||
+ __u64 timestamp;
|
||||
+ __u64 err_log_id;
|
||||
+ char log_data[4054]; /* We cannot exceed a total of 4074 bytes (header + data) */
|
||||
+};
|
||||
+
|
||||
+struct zpci_report_error {
|
||||
+ struct zpci_report_error_header header;
|
||||
+ struct zpci_report_error_data data;
|
||||
+} __packed;
|
||||
+
|
||||
+#endif /* ZPCICTL_H */
|
@ -1,42 +0,0 @@
|
||||
Subject: cpumf: add missing Description: tag for z13/z14/ctr:128
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: a3c746846d86ebcee6cbf36505598b7da367665b
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf: add missing Description: tag for z13/z14/ctr:128
|
||||
|
||||
Signed-off-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/data/cpum-cf-extended-z13.ctr | 1 +
|
||||
cpumf/data/cpum-cf-extended-z14.ctr | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
--- a/cpumf/data/cpum-cf-extended-z13.ctr
|
||||
+++ b/cpumf/data/cpum-cf-extended-z13.ctr
|
||||
@@ -17,6 +17,7 @@
|
||||
# Extended Counter Set
|
||||
# ---------------------------------------------------------------------
|
||||
Counter:128 Name:L1D_WRITES_RO_EXCL
|
||||
+Description:
|
||||
A directory write to the Level-1 Data cache where the line was
|
||||
originally in a Read-Only state in the cache but has been updated
|
||||
to be in the Exclusive state that allows stores to the cache line.
|
||||
--- a/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
+++ b/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
@@ -20,6 +20,7 @@
|
||||
# Extended Counter Set
|
||||
# ---------------------------------------------------------------------
|
||||
Counter:128 Name:L1D_WRITES_RO_EXCL
|
||||
+Description:
|
||||
A directory write to the Level-1 Data cache where the line was
|
||||
originally in a Read-Only state in the cache but has been updated
|
||||
to be in the Exclusive state that allows stores to the cache line
|
@ -1,217 +0,0 @@
|
||||
Subject: zdev: Write zfcp-lun udev rules to separate files
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: a86fb8b09118e6de7463882f889eff7e278163cd
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Write zfcp-lun udev rules to separate files
|
||||
|
||||
Change chzdev's udev rule generation from the previous approach of
|
||||
combining all zfcp-lun udev rules associated with an FCP device into a
|
||||
single file to storing zfcp-lun udev rules in one file per zfcp-lun.
|
||||
This is done to enable per-device udev rule masking.
|
||||
|
||||
With udev rule masking, if a udev rule file by the same name exists in
|
||||
both /etc and /run, the udev daemon will only consider the rules found
|
||||
in /etc.
|
||||
|
||||
The auto-configuration feature will make use of per-device udev rule
|
||||
masking to introduce a new class of configuration data (stored in /run)
|
||||
that is only active if no user-provided configuration data (in /etc)
|
||||
exists.
|
||||
|
||||
In addition, change chzdev to allow the regeneration of udev rules by
|
||||
using the --force command line like in the following example:
|
||||
|
||||
# chzdev zfcp-lun --configured --enable --persistent --force
|
||||
|
||||
This can be used to convert all existing zfcp-lun udev rules from the
|
||||
old format to the new one.
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/src/chzdev.c | 6 +++-
|
||||
zdev/src/root.c | 2 -
|
||||
zdev/src/udev_zfcp_lun.c | 56 ++++++++++++++++++++++++++++++++++-----
|
||||
3 files changed, 55 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/zdev/src/chzdev.c
|
||||
+++ b/zdev/src/chzdev.c
|
||||
@@ -1333,7 +1333,7 @@ static exit_code_t cfg_write(struct devi
|
||||
struct subtype *st = dev->subtype;
|
||||
exit_code_t rc = EXIT_OK;
|
||||
|
||||
- if (!device_needs_writing(dev, config))
|
||||
+ if (!device_needs_writing(dev, config) && !force)
|
||||
goto out;
|
||||
|
||||
if (check_active && config == config_persistent &&
|
||||
@@ -1624,6 +1624,10 @@ static exit_code_t print_config_result(s
|
||||
already = device_needs_writing(dev, config) ? 0 : 1;
|
||||
}
|
||||
|
||||
+ /* Re-do actions if run with --force */
|
||||
+ if (force)
|
||||
+ already = 0;
|
||||
+
|
||||
if (dev) {
|
||||
devname = dev->subtype->devname;
|
||||
devid = dev->id;
|
||||
--- a/zdev/src/root.c
|
||||
+++ b/zdev/src/root.c
|
||||
@@ -60,7 +60,7 @@ exit_code_t root_check(void)
|
||||
/* Check devices. */
|
||||
dev = device_list_find(sel->st->devices, sel->id, NULL);
|
||||
if (dev && dev->persistent.exists &&
|
||||
- device_needs_writing(dev, config_persistent)) {
|
||||
+ (device_needs_writing(dev, config_persistent) || force)) {
|
||||
strlist_add(mod, "%s %s", dev->subtype->devname,
|
||||
dev->id);
|
||||
}
|
||||
--- a/zdev/src/udev_zfcp_lun.c
|
||||
+++ b/zdev/src/udev_zfcp_lun.c
|
||||
@@ -385,6 +385,8 @@ void udev_zfcp_lun_add_device_ids(struct
|
||||
free(cb_data.prefix);
|
||||
}
|
||||
|
||||
+/* Return path to zfcp lun udev rule file containing configuration data for
|
||||
+ * all LUNs of a zfcp device. */
|
||||
static char *get_zfcp_lun_path(const char *id)
|
||||
{
|
||||
char *copy, *e, *path;
|
||||
@@ -399,6 +401,13 @@ static char *get_zfcp_lun_path(const cha
|
||||
return path;
|
||||
}
|
||||
|
||||
+/* Return path to zfcp lun udev rule file containing configuration data for
|
||||
+ * a single LUN. */
|
||||
+static char *get_single_zfcp_lun_path(const char *id)
|
||||
+{
|
||||
+ return path_get_udev_rule(ZFCP_LUN_NAME, id);
|
||||
+}
|
||||
+
|
||||
/* Apply the settings found in NODE to STATE. */
|
||||
static void zfcp_lun_node_to_state(struct zfcp_lun_node *node,
|
||||
struct attrib **attribs,
|
||||
@@ -437,7 +446,12 @@ exit_code_t udev_zfcp_lun_read_device(st
|
||||
exit_code_t rc = EXIT_OK;
|
||||
char *path;
|
||||
|
||||
- path = get_zfcp_lun_path(dev->id);
|
||||
+ /* Check for single lun file first then try multi lun file. */
|
||||
+ path = get_single_zfcp_lun_path(dev->id);
|
||||
+ if (!util_path_exists(path)) {
|
||||
+ free(path);
|
||||
+ path = get_zfcp_lun_path(dev->id);
|
||||
+ }
|
||||
|
||||
/* Get previous rule data. */
|
||||
luns = zfcp_lun_node_list_new();
|
||||
@@ -599,8 +613,10 @@ out:
|
||||
|
||||
/* Update the udev rule file that configures the zfcp lun with the specified
|
||||
* ID. If @state is %NULL, remove the rule, otherwise create a rule that
|
||||
- * applies the corresponding parameters. */
|
||||
-static exit_code_t update_lun_rule(const char *id, struct device_state *state)
|
||||
+ * applies the corresponding parameters. If @single is set, update a single
|
||||
+ * lun rule file, otherwise update a multi lun rule file. */
|
||||
+static exit_code_t update_lun_rule(const char *id, struct device_state *state,
|
||||
+ bool single)
|
||||
{
|
||||
struct zfcp_lun_devid devid;
|
||||
struct util_list *luns;
|
||||
@@ -612,7 +628,7 @@ static exit_code_t update_lun_rule(const
|
||||
rc = zfcp_lun_parse_devid(&devid, id, err_delayed_print);
|
||||
if (rc)
|
||||
return rc;
|
||||
- path = get_zfcp_lun_path(id);
|
||||
+ path = single ? get_single_zfcp_lun_path(id) : get_zfcp_lun_path(id);
|
||||
|
||||
/* Get previous rule data. */
|
||||
luns = zfcp_lun_node_list_new();
|
||||
@@ -650,24 +666,50 @@ static exit_code_t update_lun_rule(const
|
||||
* device state. */
|
||||
exit_code_t udev_zfcp_lun_write_device(struct device *dev)
|
||||
{
|
||||
- return update_lun_rule(dev->id, &dev->persistent);
|
||||
+ exit_code_t rc;
|
||||
+
|
||||
+ rc = update_lun_rule(dev->id, &dev->persistent, true);
|
||||
+
|
||||
+ /* We only want single lun rule files so remove any remaining
|
||||
+ * references in multi lun rule files. */
|
||||
+ update_lun_rule(dev->id, NULL, false);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
/* Remove the UDEV rule used to configure the zfcp lun with the specified ID. */
|
||||
exit_code_t udev_zfcp_lun_remove_rule(const char *id)
|
||||
{
|
||||
- return update_lun_rule(id, NULL);
|
||||
+ exit_code_t rc, rc2;
|
||||
+
|
||||
+ rc = update_lun_rule(id, NULL, true);
|
||||
+ rc2 = update_lun_rule(id, NULL, false);
|
||||
+
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ return rc2;
|
||||
}
|
||||
|
||||
/* Determine if a udev rule exists for configuring the specified zfcp lun. */
|
||||
bool udev_zfcp_lun_exists(const char *id)
|
||||
{
|
||||
struct zfcp_lun_devid devid;
|
||||
- char *path, *rule, *pattern = NULL;
|
||||
+ char *path, *rule = NULL, *pattern = NULL;
|
||||
bool rc = false;
|
||||
|
||||
if (zfcp_lun_parse_devid(&devid, id, err_ignore) != EXIT_OK)
|
||||
return false;
|
||||
+
|
||||
+ /* Check for single lun rule file first. */
|
||||
+ path = get_single_zfcp_lun_path(id);
|
||||
+ if (util_path_exists(path)) {
|
||||
+ rc = true;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ free(path);
|
||||
+
|
||||
+ /* Check multi lun rule file next. */
|
||||
path = get_zfcp_lun_path(id);
|
||||
rule = misc_read_text_file(path, 1, err_ignore);
|
||||
if (!rule)
|
@ -1,48 +0,0 @@
|
||||
Subject: zpcictl: include sys/sysmacros.h to avoid minor/major glibc warnings
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: f35c5d01fd04ecf019f31c58edc0c5165ad276ad
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: include sys/sysmacros.h to avoid minor/major glibc warnings
|
||||
|
||||
The minor()/major() function definitions are moved to sys/sysmacros.h
|
||||
and will be removed from sys/types.h. To correct below warning, simply
|
||||
include sys/sysmacros.h.
|
||||
|
||||
zpcictl.c: In function ‘sysfs_get_slot_addr’:
|
||||
zpcictl.c:184:13: warning: In the GNU C Library, "major" is defined
|
||||
by <sys/sysmacros.h>. For historical compatibility, it is
|
||||
currently defined by <sys/types.h> as well, but we plan to
|
||||
remove this soon. To use "major", include <sys/sysmacros.h>
|
||||
directly. If you did not intend to use a system-defined macro
|
||||
"major", you should undefine it after including <sys/types.h>.
|
||||
major = major(dev_stat.st_rdev);
|
||||
^~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
zpcictl/zpcictl.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/zpcictl/zpcictl.c
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <sys/sysmacros.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "lib/util_base.h"
|
@ -1,44 +0,0 @@
|
||||
Subject: cpumf: correct counter name for z13 and z14
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: 9745e4678adf18869e661d13f2b666a929450fa1
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf: correct counter name for z13 and z14
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/data/cpum-cf-extended-z13.ctr | 2 +-
|
||||
cpumf/data/cpum-cf-extended-z14.ctr | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/cpumf/data/cpum-cf-extended-z13.ctr
|
||||
+++ b/cpumf/data/cpum-cf-extended-z13.ctr
|
||||
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# Extended Counter Set
|
||||
# ---------------------------------------------------------------------
|
||||
-Counter:128 Name:L1D_WRITES_RO_EXCL
|
||||
+Counter:128 Name:L1D_RO_EXCL_WRITES
|
||||
Description:
|
||||
A directory write to the Level-1 Data cache where the line was
|
||||
originally in a Read-Only state in the cache but has been updated
|
||||
--- a/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
+++ b/cpumf/data/cpum-cf-extended-z14.ctr
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
# Extended Counter Set
|
||||
# ---------------------------------------------------------------------
|
||||
-Counter:128 Name:L1D_WRITES_RO_EXCL
|
||||
+Counter:128 Name:L1D_RO_EXCL_WRITES
|
||||
Description:
|
||||
A directory write to the Level-1 Data cache where the line was
|
||||
originally in a Read-Only state in the cache but has been updated
|
File diff suppressed because it is too large
Load Diff
@ -1,91 +0,0 @@
|
||||
Subject: zpcictl: Rephrase man page entries and tool output
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: d03be735366de57be0c642f6f21b06b1f2df6a6e
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: Rephrase man page entries and tool output
|
||||
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
zpcictl/zpcictl.8 | 13 ++++++++-----
|
||||
zpcictl/zpcictl.c | 9 +++++----
|
||||
2 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/zpcictl/zpcictl.8
|
||||
+++ b/zpcictl/zpcictl.8
|
||||
@@ -1,4 +1,4 @@
|
||||
-.\" Copyright 2017 IBM Corp.
|
||||
+.\" Copyright IBM Corp. 2018
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
@@ -30,9 +30,10 @@ zpcictl - Manage PCI devices on z System
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
+With
|
||||
.B zpcictl
|
||||
-is a tool for managing PCI devices on the IBM z Systems platform. It is
|
||||
-especially used for reporting errorneous PCI devices to the service element.
|
||||
+, you can manage PCI devices on the IBM z Systems platform. It is especially
|
||||
+used for reporting erroneous PCI devices to the service element.
|
||||
|
||||
.B Note:
|
||||
For NVMe devices additional data (such as S.M.A.R.T. data) is collected and sent
|
||||
@@ -44,7 +45,9 @@ for this to work.
|
||||
.SH DEVICE
|
||||
.B DEVICE
|
||||
can be either the PCI slot address (e.g. 0000:00:00.0) or the main device node
|
||||
-of an NVMe device (e.g. /dev/nvme0).
|
||||
+of an NVMe device (e.g.
|
||||
+.I /dev/nvme0
|
||||
+).
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
@@ -52,7 +55,7 @@ of an NVMe device (e.g. /dev/nvme0).
|
||||
.OD reset "" "DEVICE"
|
||||
Reset
|
||||
.I DEVICE
|
||||
-and initiate a re-initialisation of the adapter.
|
||||
+and initiate a re-initialization of the PCI device.
|
||||
.PP
|
||||
.
|
||||
.OD deconfigure "" "DEVICE"
|
||||
--- a/zpcictl/zpcictl.c
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -240,7 +240,7 @@ static int device_exists(char *dev)
|
||||
static void get_device_info(struct zpci_device *pdev, char *dev)
|
||||
{
|
||||
if (!device_exists(dev))
|
||||
- errx(EXIT_FAILURE, "Device %s not found", dev);
|
||||
+ errx(EXIT_FAILURE, "Could not find device %s", dev);
|
||||
if (is_blk_dev(dev))
|
||||
errx(EXIT_FAILURE, "Unsupported device type %s", dev);
|
||||
if (is_char_dev(dev)) {
|
||||
@@ -254,9 +254,10 @@ static void get_device_info(struct zpci_
|
||||
pdev->fid = sysfs_read_value(pdev, "function_id");
|
||||
pdev->pchid = sysfs_read_value(pdev, "pchid");
|
||||
|
||||
- /* In case a slot address was specified, we still need to figure out
|
||||
- * the device node for NVMe devices. Otherwise we won't be able to
|
||||
- * collect S.M.A.R.T. data at a later point.
|
||||
+ /*
|
||||
+ * In case a slot address was specified, the device node for NVMe
|
||||
+ * devices is still needed. Otherwise it won't be possible to collect
|
||||
+ * S.M.A.R.T. data at a later point.
|
||||
*/
|
||||
if (!pdev->device && pdev->class == PCI_CLASS_NVME)
|
||||
get_device_node(pdev);
|
@ -1,41 +0,0 @@
|
||||
Subject: cpumf: Add IBM z14 ZR1 to the CPU Measurement Facility model list
|
||||
From: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
|
||||
Summary: cpumf: Add CPU-MF hardware counters for z14
|
||||
Description: Add hardware counter definitions for IBM z14.
|
||||
Upstream-ID: f642019bcc17370231666e772c7e4cec19f1dfdc
|
||||
Problem-ID: KRN1608
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
cpumf: Add IBM z14 ZR1 to the CPU Measurement Facility model list
|
||||
|
||||
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
---
|
||||
cpumf/bin/cpumf_helper.in | 1 +
|
||||
cpumf/data/cpum-cf-hw-counter.map | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
--- a/cpumf/bin/cpumf_helper.in
|
||||
+++ b/cpumf/bin/cpumf_helper.in
|
||||
@@ -211,6 +211,7 @@ my $system_z_hwtype_map = {
|
||||
2964 => 'IBM z13',
|
||||
2965 => 'IBM z13s',
|
||||
3906 => 'IBM z14',
|
||||
+ 3907 => 'IBM z14 ZR1',
|
||||
};
|
||||
|
||||
sub get_hardware_type()
|
||||
--- a/cpumf/data/cpum-cf-hw-counter.map
|
||||
+++ b/cpumf/data/cpum-cf-hw-counter.map
|
||||
@@ -26,4 +26,5 @@
|
||||
2964 => 'cpum-cf-extended-z13.ctr',
|
||||
2965 => 'cpum-cf-extended-z13.ctr',
|
||||
3906 => 'cpum-cf-extended-z14.ctr',
|
||||
+ 3907 => 'cpum-cf-extended-z14.ctr',
|
||||
};
|
@ -1,155 +0,0 @@
|
||||
Subject: zdev: Integrate firmware auto-configuration with dracut
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: 3fb356ebd297e4384208b7688d49cb3eb8f5b3e1
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Integrate firmware auto-configuration with dracut
|
||||
|
||||
Add a dracut hook that applies firmware-provided I/O configuration data
|
||||
as auto-configuration during boot. This way, all I/O devices configured
|
||||
by DPM are automatically brought online without further user
|
||||
interaction.
|
||||
|
||||
This mechanism is active by default. It can be deactivated by specifying
|
||||
the following parameter on the kernel command line:
|
||||
|
||||
rd.zdev=no-auto
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/dracut/95zdev/module-setup.sh | 19 ++++++++++----
|
||||
zdev/dracut/95zdev/parse-zdev.sh | 38 +++++++++++++++++++++++++++++
|
||||
zdev/dracut/Makefile | 3 ++
|
||||
3 files changed, 55 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/zdev/dracut/95zdev/module-setup.sh
|
||||
+++ b/zdev/dracut/95zdev/module-setup.sh
|
||||
@@ -9,7 +9,8 @@
|
||||
# 95zdev/module_setup.sh
|
||||
# This module installs configuration files (udev rules and modprobe.conf
|
||||
# files) required to enable the root device on s390. It will only work when
|
||||
-# the root device was configured using the chzdev tool.
|
||||
+# the root device was configured using the chzdev tool. In addition,
|
||||
+# a hook is installed to parse rd.zdev= kernel parameters.
|
||||
#
|
||||
|
||||
check() {
|
||||
@@ -29,15 +30,23 @@ depends() {
|
||||
}
|
||||
|
||||
installkernel() {
|
||||
- local _modules=$(lszdev --by-path / --columns MODULES --no-headings 2>/dev/null)
|
||||
-
|
||||
- [ -z "$_modules" ] && return 0
|
||||
- [ ! -z "$_modules" ] && instmods $_modules
|
||||
+ # Add modules for all device types supported by chzdev (required for
|
||||
+ # auto-configuration)
|
||||
+ instmods lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
|
||||
+ dasd_diag_mod zfcp
|
||||
}
|
||||
|
||||
install() {
|
||||
local _tempfile
|
||||
|
||||
+ # Ensure that required tools are available
|
||||
+ inst_multiple chzdev lszdev vmcp
|
||||
+
|
||||
+ # Hook to parse zdev kernel parameter
|
||||
+ inst_hook cmdline 95 "$moddir/parse-zdev.sh"
|
||||
+
|
||||
+ # Obtain root device configuration
|
||||
+
|
||||
# Exit early if root device type is unknown
|
||||
if ! lszdev --by-path / >/dev/null 2>&1 ; then
|
||||
return 0
|
||||
--- /dev/null
|
||||
+++ b/zdev/dracut/95zdev/parse-zdev.sh
|
||||
@@ -0,0 +1,38 @@
|
||||
+#!/bin/sh
|
||||
+#
|
||||
+# Copyright IBM Corp. 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.
|
||||
+#
|
||||
+# 95zdev/parse-zdev.sh
|
||||
+# Parse the kernel command line for rd.zdev kernel parameters. These
|
||||
+# parameters are evaluated and used to configure z Systems specific devices.
|
||||
+#
|
||||
+# Format:
|
||||
+# rd.zdev=no-auto
|
||||
+#
|
||||
+# where
|
||||
+#
|
||||
+# no-auto: Indicates that firmware-provided I/O configuration data
|
||||
+# should not be applied.
|
||||
+#
|
||||
+
|
||||
+zdev_fw_file="/sys/firmware/sclp_sd/config/data"
|
||||
+zdev_base_args="--force --yes --no-root-update --no-settle --auto-conf --quiet"
|
||||
+
|
||||
+if [ -e "$zdev_fw_file" ] ; then
|
||||
+ zdev_auto=1
|
||||
+else
|
||||
+ zdev_auto=0
|
||||
+fi
|
||||
+
|
||||
+for zdev_arg in $(getargs rd.zdev); do
|
||||
+ if [ "$zdev_arg" = "no-auto" ] ; then
|
||||
+ zdev_auto=0
|
||||
+ fi
|
||||
+done
|
||||
+
|
||||
+if [ $zdev_auto -eq 1 ] ; then
|
||||
+ chzdev --import "$zdev_fw_file" $zdev_base_args
|
||||
+fi
|
||||
--- a/zdev/dracut/Makefile
|
||||
+++ b/zdev/dracut/Makefile
|
||||
@@ -11,11 +11,14 @@ ZDEVDIR := 95zdev
|
||||
# performs the following functions when dracut is run:
|
||||
#
|
||||
# - copy the persistent root device configuration to the initial ram disk
|
||||
+# - install a boot-time hook to apply firmware-provided configuration data
|
||||
+# to the system
|
||||
#
|
||||
ifeq ($(HAVE_DRACUT),1)
|
||||
install:
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(MODDIR)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(MODDIR)/$(ZDEVDIR)
|
||||
$(INSTALL) -m 755 $(ZDEVDIR)/module-setup.sh \
|
||||
+ $(ZDEVDIR)/parse-zdev.sh \
|
||||
$(DESTDIR)$(MODDIR)/$(ZDEVDIR)/
|
||||
endif
|
@ -1,55 +0,0 @@
|
||||
Subject: zpcictl: Use fopen() instead of open() for writes
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: 8f0496b26aae88e206ac9a95b317043e78d147b8
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: Use fopen() instead of open() for writes
|
||||
|
||||
Be consistent with the rest of the code and use fopen() rather than
|
||||
open().
|
||||
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
zpcictl/zpcictl.c | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/zpcictl/zpcictl.c
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -155,17 +155,19 @@ static unsigned int sysfs_read_value(str
|
||||
|
||||
static void sysfs_write_data(struct zpci_report_error *report, char *slot)
|
||||
{
|
||||
+ size_t r_size;
|
||||
char *path;
|
||||
- int fd, rc;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ r_size = sizeof(*report);
|
||||
|
||||
path = util_path_sysfs("bus/pci/devices/%s/report_error", slot);
|
||||
- fd = open(path, O_WRONLY);
|
||||
- if (!fd)
|
||||
+ fp = fopen(path, "w");
|
||||
+ if (!fp)
|
||||
fopen_err(path);
|
||||
- rc = write(fd, report, sizeof(*report));
|
||||
- if (rc == -1)
|
||||
+ if (fwrite(report, 1, r_size, fp) != r_size)
|
||||
warnx("Could not write to file: %s: %s", path, strerror(errno));
|
||||
- if (close(fd))
|
||||
+ if (fclose(fp))
|
||||
warnx("Could not close file: %s: %s", path, strerror(errno));
|
||||
free(path);
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
Subject: zdev: Integrate firmware auto-configuration with initramfs-tools
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: 3c5644ccfd46aab27df6e0ed783e94a620bc3fe6
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Integrate firmware auto-configuration with initramfs-tools
|
||||
|
||||
Add initramfs-tools scripts that apply firmware-provided I/O
|
||||
configuration data as auto-configuration during boot. This way, all I/O
|
||||
devices configured by DPM are automatically brought online without
|
||||
further user interaction.
|
||||
|
||||
This mechanism is active by default. It can be deactivated by specifying
|
||||
the following parameter on the kernel command line:
|
||||
|
||||
rd.zdev=no-auto
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
README.md | 1
|
||||
zdev/Makefile | 1
|
||||
zdev/initramfs/Makefile | 22 ++++++++
|
||||
zdev/initramfs/hooks/zdev | 39 +++++++++++++++
|
||||
zdev/initramfs/scripts/init-top/zdev | 67 +++++++++++++++++++++++++++
|
||||
5 files changed, 130 insertions(+)
|
||||
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -272,6 +272,7 @@ This table lists additional build or ins
|
||||
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|
||||
|----------------|:----------------:|:-------------------------------:|
|
||||
| dracut | `HAVE_DRACUT` | zdev |
|
||||
+| initramfs-tools| `HAVE_INITRAMFS` | zdev |
|
||||
|
||||
The s390-tools build process uses "pkg-config" if available and hard-coded
|
||||
compiler and linker options otherwise.
|
||||
--- a/zdev/Makefile
|
||||
+++ b/zdev/Makefile
|
||||
@@ -8,6 +8,7 @@ install: all
|
||||
$(MAKE) -C src install
|
||||
$(MAKE) -C man install
|
||||
$(MAKE) -C dracut install
|
||||
+ $(MAKE) -C initramfs install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C src clean
|
||||
--- /dev/null
|
||||
+++ b/zdev/initramfs/Makefile
|
||||
@@ -0,0 +1,22 @@
|
||||
+# Common definitions
|
||||
+include ../../common.mak
|
||||
+
|
||||
+INITRAMFSDIR := /usr/share/initramfs-tools
|
||||
+HOOKDIR := $(INITRAMFSDIR)/hooks
|
||||
+INITTOP := $(INITRAMFSDIR)/scripts/init-top
|
||||
+
|
||||
+# HAVE_INITRAMFS
|
||||
+#
|
||||
+# This install time parameter determines whether the zdev initramfs support is
|
||||
+# installed (HAVE_INITRAMFS=1) or not (default). When installed, the module
|
||||
+# performs the following functions when mkinitramfs is run:
|
||||
+#
|
||||
+# - install a boot-time hook to apply firmware-provided configuration data
|
||||
+# to the system
|
||||
+#
|
||||
+ifeq ($(HAVE_INITRAMFS),1)
|
||||
+install:
|
||||
+ $(INSTALL) -m 755 -d $(DESTDIR)/$(HOOKDIR) $(DESTDIR)/$(INITTOP)
|
||||
+ $(INSTALL) -m 755 hooks/zdev $(DESTDIR)/$(HOOKDIR)
|
||||
+ $(INSTALL) -m 755 scripts/init-top/zdev $(DESTDIR)/$(INITTOP)
|
||||
+endif
|
||||
--- /dev/null
|
||||
+++ b/zdev/initramfs/hooks/zdev
|
||||
@@ -0,0 +1,39 @@
|
||||
+#!/bin/sh
|
||||
+#
|
||||
+# 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.
|
||||
+#
|
||||
+# hooks/zdev
|
||||
+# This hook script adds files required to apply firmware-provided I/O
|
||||
+# configuration data during boot.
|
||||
+#
|
||||
+
|
||||
+PREREQ=""
|
||||
+
|
||||
+prereqs()
|
||||
+{
|
||||
+ echo "$PREREQ"
|
||||
+}
|
||||
+
|
||||
+case $1 in
|
||||
+ prereqs)
|
||||
+ prereqs
|
||||
+ exit 0
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+. /usr/share/initramfs-tools/hook-functions
|
||||
+
|
||||
+# Add modules for all device types supported by chzdev (required for
|
||||
+# auto-configuration)
|
||||
+zdev_modules="lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod dasd_diag_mod zfcp"
|
||||
+
|
||||
+for x in $zdev_modules ; do
|
||||
+ manual_add_modules ${x}
|
||||
+done
|
||||
+
|
||||
+copy_exec /sbin/chzdev
|
||||
+copy_exec /sbin/lszdev
|
||||
+copy_exec /sbin/vmcp
|
||||
--- /dev/null
|
||||
+++ b/zdev/initramfs/scripts/init-top/zdev
|
||||
@@ -0,0 +1,67 @@
|
||||
+#!/bin/sh
|
||||
+#
|
||||
+# Copyright IBM Corp. 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.
|
||||
+#
|
||||
+# scripts/init-top/zdev
|
||||
+# Parse the kernel command line for rd.zdev kernel parameters. These
|
||||
+# parameters are evaluated and used to configure z Systems specific devices.
|
||||
+#
|
||||
+# Format:
|
||||
+# rd.zdev=no-auto
|
||||
+#
|
||||
+# where
|
||||
+#
|
||||
+# no-auto: Indicates that firmware-provided I/O configuration data
|
||||
+# should not be applied.
|
||||
+#
|
||||
+
|
||||
+PREREQ="udev"
|
||||
+
|
||||
+prereqs()
|
||||
+{
|
||||
+ echo "$PREREQ"
|
||||
+}
|
||||
+
|
||||
+case $1 in
|
||||
+prereqs)
|
||||
+ prereqs
|
||||
+ exit 0
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+. /scripts/functions
|
||||
+
|
||||
+zdev_fw_file="/sys/firmware/sclp_sd/config/data"
|
||||
+zdev_base_args="--force --yes --no-root-update --no-settle --auto-conf --quiet"
|
||||
+
|
||||
+if [ -e "$zdev_fw_file" ] ; then
|
||||
+ zdev_auto=1
|
||||
+else
|
||||
+ zdev_auto=0
|
||||
+fi
|
||||
+
|
||||
+for x in $(cat /proc/cmdline); do
|
||||
+ case ${x} in
|
||||
+ rd.zdev=*)
|
||||
+ zdev_arg=${x#*=}
|
||||
+ if [ "$zdev_arg" = "no-auto" ] ; then
|
||||
+ zdev_auto=0
|
||||
+ fi
|
||||
+ ;;
|
||||
+ esac
|
||||
+done
|
||||
+
|
||||
+if [ $zdev_auto -eq 1 ] ; then
|
||||
+ log_begin_msg "Starting firmware auto-configuration"
|
||||
+ chzdev --import "$zdev_fw_file" $zdev_base_args
|
||||
+ log_end_msg
|
||||
+
|
||||
+ # Repeat cold-plug after creating udev rules
|
||||
+ udevadm control --reload
|
||||
+ udevadm trigger --type=subsystems --action=add
|
||||
+ udevadm trigger --action=add
|
||||
+ udevadm settle || true
|
||||
+fi
|
@ -1,77 +0,0 @@
|
||||
Subject: zpcictl: Read device link to obtain device address
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: e2a8d85916fb77d2a9b41253446973cd97107c42
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: Read device link to obtain device address
|
||||
|
||||
The address sysfs attribute might not be present on some older kernel
|
||||
levels. Read the device link instead using readlink() to obtain the
|
||||
address.
|
||||
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
zpcictl/zpcictl.c | 27 ++++++++++++++++++---------
|
||||
1 file changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/zpcictl/zpcictl.c
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -172,13 +172,16 @@ static void sysfs_write_data(struct zpci
|
||||
free(path);
|
||||
}
|
||||
|
||||
+/* lstat() doesn't work for sysfs files, so we have to work with a fixed size */
|
||||
+#define READLINK_SIZE 256
|
||||
+
|
||||
static void sysfs_get_slot_addr(const char *dev, char *slot)
|
||||
{
|
||||
+ char device[READLINK_SIZE], *result;
|
||||
unsigned int major, minor;
|
||||
struct stat dev_stat;
|
||||
- char addr[13];
|
||||
+ ssize_t len;
|
||||
char *path;
|
||||
- FILE *fp;
|
||||
|
||||
if (stat(dev, &dev_stat) != 0) {
|
||||
errx(EXIT_FAILURE, "Could not get stat information for %s: %s",
|
||||
@@ -187,15 +190,21 @@ static void sysfs_get_slot_addr(const ch
|
||||
major = major(dev_stat.st_rdev);
|
||||
minor = minor(dev_stat.st_rdev);
|
||||
|
||||
- path = util_path_sysfs("dev/char/%u:%u/address", major, minor);
|
||||
- fp = fopen(path, "r");
|
||||
- if (!fp)
|
||||
- fopen_err(path);
|
||||
- fscanf(fp, "%s", addr);
|
||||
- fclose(fp);
|
||||
+ path = util_path_sysfs("dev/char/%u:%u/device", major, minor);
|
||||
+ len = readlink(path, device, READLINK_SIZE - 1);
|
||||
free(path);
|
||||
+ if (len != -1)
|
||||
+ device[len] = '\0';
|
||||
+ else
|
||||
+ errx(EXIT_FAILURE, "Could not read device link for %s", dev);
|
||||
+
|
||||
+ result = strrchr(device, '/');
|
||||
+ if (result)
|
||||
+ result++;
|
||||
+ else
|
||||
+ result = device;
|
||||
|
||||
- strcpy(slot, addr);
|
||||
+ strcpy(slot, result);
|
||||
}
|
||||
|
||||
static void get_device_node(struct zpci_device *pdev)
|
@ -1,507 +0,0 @@
|
||||
Subject: zdev: Implement internal device attributes
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: c0392efa39e48cb12fdf3524b2f9e683e46f0f14
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Implement internal device attributes
|
||||
|
||||
This change adds base infrastructure for implementing internal device
|
||||
attributes. In the context of the zdev tools, an internal device
|
||||
attribute is a new type of device attribute with the following
|
||||
characteristics:
|
||||
|
||||
- Can be set and removed like normal device attributes
|
||||
- Affects zdev-internal handling only
|
||||
- Does not correspond to an actual device attribute, that is
|
||||
it has no representation in SysFS
|
||||
- Can not be set in the active configuration
|
||||
- Name starts with "zdev:" to prevent conflicts with actual
|
||||
device attributes
|
||||
|
||||
Values for internal device attributes are stored in udev rules alongside
|
||||
the normal persistent configuration of a device. They are encoded as
|
||||
udev environment variables. Note that they have no further effect on
|
||||
udev processing.
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/include/attrib.h | 2
|
||||
zdev/include/internal.h | 20 +++++++++
|
||||
zdev/include/misc.h | 1
|
||||
zdev/include/udev.h | 7 +++
|
||||
zdev/src/Makefile | 4 -
|
||||
zdev/src/device.c | 15 +++++++
|
||||
zdev/src/internal.c | 25 ++++++++++++
|
||||
zdev/src/misc.c | 15 +++++++
|
||||
zdev/src/udev.c | 32 +++++++++++++++
|
||||
zdev/src/udev_ccw.c | 16 +++++++
|
||||
zdev/src/udev_ccwgroup.c | 11 +++++
|
||||
zdev/src/udev_zfcp_lun.c | 80 ++++++++++++++++++++++++++++++++++++---
|
||||
12 files changed, 220 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/zdev/include/attrib.h
|
||||
+++ b/zdev/include/attrib.h
|
||||
@@ -189,6 +189,7 @@ struct value_map {
|
||||
* in the persistent configuration
|
||||
* @nounload: (Device type attributes only) This attribute can be set while
|
||||
* the corresponding kernel module remains loaded.
|
||||
+ * @internal: This attribute only affects internal handling
|
||||
* @order: A number indicating the order in which to apply attribute
|
||||
* @order_cmp: A function determining if a setting for this attribute should
|
||||
* be applied before (-1) or after (1) another setting, or
|
||||
@@ -216,6 +217,7 @@ struct attrib {
|
||||
unsigned int activerem :1;
|
||||
unsigned int defunset :1;
|
||||
unsigned int nounload :1;
|
||||
+ unsigned int internal :1;
|
||||
|
||||
/* Optional */
|
||||
int order;
|
||||
--- /dev/null
|
||||
+++ b/zdev/include/internal.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/*
|
||||
+ * zdev - Modify and display the persistent configuration of devices
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 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 INTERNAL_H
|
||||
+#define INTERNAL_H
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+#define INTERNAL_ATTR_PREFIX "zdev:"
|
||||
+
|
||||
+const char *internal_get_name(const char *name);
|
||||
+bool internal_by_name(const char *name);
|
||||
+
|
||||
+#endif /* INTERNAL_H */
|
||||
--- a/zdev/include/misc.h
|
||||
+++ b/zdev/include/misc.h
|
||||
@@ -183,6 +183,7 @@ bool str_to_config(const char *, config_
|
||||
char *quote_str(const char *, int);
|
||||
char *unquote_str(const char *);
|
||||
char *shrink_str(const char *);
|
||||
+char *misc_strrstr(const char *haystack, const char *needle);
|
||||
|
||||
struct util_list *strlist_new(void);
|
||||
void strlist_free(struct util_list *);
|
||||
--- a/zdev/include/udev.h
|
||||
+++ b/zdev/include/udev.h
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "lib/util_list.h"
|
||||
#include "exit_code.h"
|
||||
|
||||
+struct attrib;
|
||||
+struct setting_list;
|
||||
+
|
||||
extern int udev_need_settle;
|
||||
extern int udev_no_settle;
|
||||
|
||||
@@ -46,4 +49,8 @@ exit_code_t udev_remove_rule(const char
|
||||
|
||||
void udev_settle(void);
|
||||
|
||||
+void udev_add_internal_from_entry(struct setting_list *list,
|
||||
+ struct udev_entry_node *entry,
|
||||
+ struct attrib **attribs);
|
||||
+
|
||||
#endif /* UDEV_H */
|
||||
--- a/zdev/src/Makefile
|
||||
+++ b/zdev/src/Makefile
|
||||
@@ -8,7 +8,7 @@ ALL_CPPFLAGS += -I ../include -std=gnu99
|
||||
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
|
||||
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||
root.o select.o setting.o subtype.o table.o table_attribs.o \
|
||||
- table_types.o net.o firmware.o
|
||||
+ table_types.o net.o firmware.o internal.o
|
||||
|
||||
# Devtype Helpers
|
||||
chzdev_objects += blkinfo.o ccw.o ccwgroup.o findmnt.o modprobe.o module.o \
|
||||
@@ -38,7 +38,7 @@ chzdev_objects += generic_ccw.o
|
||||
lszdev_objects += attrib.o lszdev.o device.o devnode.o devtype.o exit_code.o \
|
||||
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||
root.o select.o setting.o subtype.o table.o table_types.o \
|
||||
- net.o
|
||||
+ net.o internal.o
|
||||
|
||||
# Devtype Helpers
|
||||
lszdev_objects += blkinfo.o ccw.o ccwgroup.o findmnt.o modprobe.o module.o \
|
||||
--- a/zdev/src/device.c
|
||||
+++ b/zdev/src/device.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "namespace.h"
|
||||
#include "setting.h"
|
||||
@@ -221,6 +222,9 @@ static exit_code_t apply_setting(struct
|
||||
goto err_activeonly_forceable;
|
||||
if (!force && SCOPE_AUTOCONF(config) && a->activeonly)
|
||||
goto err_activeonly_forceable;
|
||||
+ /* Check for internal. */
|
||||
+ if (config == config_active && a->internal)
|
||||
+ goto err_int_noactive;
|
||||
/* Check for multiple values. */
|
||||
if (!force && !a->multi && strlist_find(processed, key))
|
||||
goto err_multi_forceable;
|
||||
@@ -230,6 +234,9 @@ static exit_code_t apply_setting(struct
|
||||
goto err_unknown;
|
||||
if (!force)
|
||||
goto err_unknown_forceable;
|
||||
+ /* Check for internal. */
|
||||
+ if (config == config_active && internal_by_name(key))
|
||||
+ goto err_int_noactive;
|
||||
}
|
||||
|
||||
strlist_add(processed, "%s", key);
|
||||
@@ -294,6 +301,11 @@ err_activeonly_forceable:
|
||||
delayed_forceable("Attribute '%s' should only be changed in the active "
|
||||
"config\n", a->name);
|
||||
return EXIT_INVALID_SETTING;
|
||||
+
|
||||
+err_int_noactive:
|
||||
+ delayed_err("Internal attribute '%s' cannot be set in the active config\n",
|
||||
+ key);
|
||||
+ return EXIT_INVALID_SETTING;
|
||||
}
|
||||
|
||||
/* Apply device settings from strlist to device. */
|
||||
@@ -542,6 +554,9 @@ exit_code_t device_write_active_settings
|
||||
s = p->ptr;
|
||||
if (!s->modified || s->removed)
|
||||
continue;
|
||||
+ if ((s->attrib && s->attrib->internal) ||
|
||||
+ internal_by_name(s->name))
|
||||
+ continue;
|
||||
|
||||
path = subtype_get_active_attrib_path(st, dev, s->name);
|
||||
if (!path) {
|
||||
--- /dev/null
|
||||
+++ b/zdev/src/internal.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/*
|
||||
+ * zdev - Modify and display the persistent configuration of devices
|
||||
+ *
|
||||
+ * Copyright IBM Corp. 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 <stdbool.h>
|
||||
+
|
||||
+#include "internal.h"
|
||||
+#include "misc.h"
|
||||
+
|
||||
+/* Return identifier of internal attribute with specified @name. */
|
||||
+const char *internal_get_name(const char *name)
|
||||
+{
|
||||
+ return name + sizeof(INTERNAL_ATTR_PREFIX) - 1;
|
||||
+}
|
||||
+
|
||||
+/* Check if attribute is internal by name. */
|
||||
+bool internal_by_name(const char *name)
|
||||
+{
|
||||
+ return starts_with(name, INTERNAL_ATTR_PREFIX);
|
||||
+}
|
||||
--- a/zdev/src/misc.c
|
||||
+++ b/zdev/src/misc.c
|
||||
@@ -1717,3 +1717,18 @@ void debug_init(int argc, char *argv[])
|
||||
fprintf(stderr, "%s\"%s\"", i > 0 ? ", " : "", argv[i]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
+
|
||||
+/* Return the last occurrence of @needle in @haystack, or %NULL if @needle
|
||||
+ * was not found. */
|
||||
+char *misc_strrstr(const char *haystack, const char *needle)
|
||||
+{
|
||||
+ char *result, *next;
|
||||
+
|
||||
+ result = strstr(haystack, needle);
|
||||
+ if (result) {
|
||||
+ while ((next = strstr(result + 1, needle)))
|
||||
+ result = next;
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
--- a/zdev/src/udev.c
|
||||
+++ b/zdev/src/udev.c
|
||||
@@ -409,3 +409,35 @@ void udev_settle(void)
|
||||
return;
|
||||
misc_system(err_ignore, "%s settle", PATH_UDEVADM);
|
||||
}
|
||||
+
|
||||
+/* Extract internal attribute settings from @entry and add to @list.
|
||||
+ * Associate corresponding attribute if found in @attribs. */
|
||||
+void udev_add_internal_from_entry(struct setting_list *list,
|
||||
+ struct udev_entry_node *entry,
|
||||
+ struct attrib **attribs)
|
||||
+{
|
||||
+ char *copy, *name, *end, *u;
|
||||
+ struct attrib *a;
|
||||
+
|
||||
+ /* ENV{zdev_var}="1" */
|
||||
+ copy = misc_strdup(entry->key);
|
||||
+
|
||||
+ /* Find attribute name start. */
|
||||
+ name = strchr(copy, '{');
|
||||
+ end = strrchr(copy, '}');
|
||||
+ if (!name || !end)
|
||||
+ goto out;
|
||||
+ *end = 0;
|
||||
+ name++;
|
||||
+
|
||||
+ /* zdev_ => zdev: */
|
||||
+ u = strchr(name, '_');
|
||||
+ if (u)
|
||||
+ *u = ':';
|
||||
+
|
||||
+ a = attrib_find(attribs, name);
|
||||
+ setting_list_apply_actual(list, a, name, entry->value);
|
||||
+
|
||||
+out:
|
||||
+ free(copy);
|
||||
+}
|
||||
--- a/zdev/src/udev_ccw.c
|
||||
+++ b/zdev/src/udev_ccw.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "attrib.h"
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "setting.h"
|
||||
@@ -49,6 +50,12 @@ static void add_setting_from_entry(struc
|
||||
char *copy, *name, *end;
|
||||
struct attrib *a;
|
||||
|
||||
+ /* ENV{zdev_var}="1" */
|
||||
+ if (starts_with(entry->key, "ENV{zdev_") &&
|
||||
+ strcmp(entry->op, "=") == 0) {
|
||||
+ udev_add_internal_from_entry(list, entry, attribs);
|
||||
+ return;
|
||||
+ }
|
||||
/* ATTR{[ccw/0.0.37bf]online}=1 */
|
||||
if (strncmp(entry->key, "ATTR{[ccw/", 10) != 0 ||
|
||||
strcmp(entry->op, "=") != 0)
|
||||
@@ -190,7 +197,14 @@ exit_code_t udev_ccw_write_device(struct
|
||||
s = p->ptr;
|
||||
if (s->removed)
|
||||
continue;
|
||||
- fprintf(fd, "ATTR{[ccw/%s]%s}=\"%s\"\n", id, s->name, s->value);
|
||||
+ if ((s->attrib && s->attrib->internal) ||
|
||||
+ internal_by_name(s->name)) {
|
||||
+ fprintf(fd, "ENV{zdev_%s}=\"%s\"\n",
|
||||
+ internal_get_name(s->name), s->value);
|
||||
+ } else {
|
||||
+ fprintf(fd, "ATTR{[ccw/%s]%s}=\"%s\"\n", id, s->name,
|
||||
+ s->value);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Write udev rule epilog. */
|
||||
--- a/zdev/src/udev_ccwgroup.c
|
||||
+++ b/zdev/src/udev_ccwgroup.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "attrib.h"
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "setting.h"
|
||||
@@ -68,6 +69,12 @@ static void add_setting_from_entry(struc
|
||||
char *copy, *name, *end;
|
||||
struct attrib *a;
|
||||
|
||||
+ /* ENV{zdev_var}="1" */
|
||||
+ if (starts_with(entry->key, "ENV{zdev_") &&
|
||||
+ strcmp(entry->op, "=") == 0) {
|
||||
+ udev_add_internal_from_entry(list, entry, attribs);
|
||||
+ return;
|
||||
+ }
|
||||
/* ATTR{[ccwgroup/0.0.f5f0]online}=1 */
|
||||
if (strncmp(entry->key, "ATTR{[ccwgroup/", 10) != 0 ||
|
||||
strcmp(entry->op, "=") != 0)
|
||||
@@ -282,6 +289,10 @@ exit_code_t udev_ccwgroup_write_device(s
|
||||
fprintf(fd, "ATTR{[ccwgroup/%s]%s}=\"%s\"\n",
|
||||
ccw_id, s->name, str->str);
|
||||
}
|
||||
+ } else if ((s->attrib && s->attrib->internal) ||
|
||||
+ internal_by_name(s->name)) {
|
||||
+ fprintf(fd, "ENV{zdev_%s}=\"%s\"\n",
|
||||
+ internal_get_name(s->name), s->value);
|
||||
} else {
|
||||
fprintf(fd, "ATTR{[ccwgroup/%s]%s}=\"%s\"\n", ccw_id,
|
||||
s->name, s->value);
|
||||
--- a/zdev/src/udev_zfcp_lun.c
|
||||
+++ b/zdev/src/udev_zfcp_lun.c
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "scsi.h"
|
||||
@@ -128,7 +129,7 @@ static bool zfcp_lun_devid_from_entry(st
|
||||
struct udev_entry_node *entry)
|
||||
{
|
||||
struct zfcp_lun_devid id;
|
||||
- char *copy = NULL, *s;
|
||||
+ char *copy = NULL, *s, *e, *u;
|
||||
int i;
|
||||
bool rc = false;
|
||||
|
||||
@@ -182,6 +183,28 @@ static bool zfcp_lun_devid_from_entry(st
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||
+ if (starts_with(entry->key, "ENV{zdev_")) {
|
||||
+ copy = misc_strdup(entry->key);
|
||||
+
|
||||
+ /* Find ID start (last __) and end (last }). */
|
||||
+ s = misc_strrstr(copy, "__");
|
||||
+ e = strrchr(copy, '}');
|
||||
+ if (!s || !e)
|
||||
+ goto out;
|
||||
+ *e = 0;
|
||||
+ s += 2;
|
||||
+ /* Convert variable name to ID format. */
|
||||
+ for (i = 0, u = s; (u = strchr(u, '_')); i++, u++) {
|
||||
+ if (i < 2)
|
||||
+ *u = '.';
|
||||
+ else
|
||||
+ *u = ':';
|
||||
+ }
|
||||
+ rc = zfcp_lun_parse_devid(&id, s, err_ignore) == EXIT_OK ?
|
||||
+ true : false;
|
||||
+ }
|
||||
+
|
||||
out:
|
||||
free(copy);
|
||||
if (rc)
|
||||
@@ -211,11 +234,46 @@ static struct zfcp_lun_node *zfcp_lun_no
|
||||
return node;
|
||||
}
|
||||
|
||||
+static void add_internal_setting_from_entry(struct udev_entry_node *entry,
|
||||
+ struct zfcp_lun_node *node)
|
||||
+{
|
||||
+ char *copy, *name, *end, *u;
|
||||
+ struct attrib *a;
|
||||
+
|
||||
+ /*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||
+ copy = misc_strdup(entry->key);
|
||||
+
|
||||
+ /* Find attribute name start and end. */
|
||||
+ name = strchr(copy, '{');
|
||||
+ end = misc_strrstr(copy, "__");
|
||||
+ if (!name || !end)
|
||||
+ goto out;
|
||||
+ *end = 0;
|
||||
+ name++;
|
||||
+
|
||||
+ /* zdev_ => zdev: */
|
||||
+ u = strchr(name, '_');
|
||||
+ if (u)
|
||||
+ *u = ':';
|
||||
+
|
||||
+ a = attrib_find(zfcp_lun_subtype.dev_attribs, name);
|
||||
+ setting_list_apply_actual(node->fc_settings, a, name, entry->value);
|
||||
+
|
||||
+out:
|
||||
+ free(copy);
|
||||
+}
|
||||
+
|
||||
static void add_fc_setting_from_entry(struct udev_entry_node *entry,
|
||||
struct zfcp_lun_node *node)
|
||||
{
|
||||
char *copy, *s, *e;
|
||||
|
||||
+ /*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||
+ if (starts_with(entry->key, "ENV{zdev_") &&
|
||||
+ strcmp(entry->op, "=") == 0) {
|
||||
+ add_internal_setting_from_entry(entry, node);
|
||||
+ return;
|
||||
+ }
|
||||
/*ATTR{[ccw/0.0.1941]0x500507630510c1ae/0x402340d400000000/failed}="0"*/
|
||||
if (!starts_with(entry->key, "ATTR{[ccw/"))
|
||||
return;
|
||||
@@ -490,7 +548,7 @@ static struct zfcp_lun_node *state_to_zf
|
||||
s->value);
|
||||
setting_list_add(node->scsi_settings, n);
|
||||
} else {
|
||||
- n = setting_new(NULL, s->name, s->value);
|
||||
+ n = setting_new(s->attrib, s->name, s->value);
|
||||
setting_list_add(node->fc_settings, n);
|
||||
}
|
||||
}
|
||||
@@ -580,9 +638,21 @@ static exit_code_t write_luns_rule(const
|
||||
node->id.lun);
|
||||
|
||||
util_list_iterate(&node->fc_settings->list, s) {
|
||||
- fprintf(fd, "ATTR{[ccw/%s]0x%016" PRIx64 "/0x%016"
|
||||
- PRIx64 "/%s}=\"%s\"\n", hba_id, node->id.wwpn,
|
||||
- node->id.lun, s->name, s->value);
|
||||
+ if ((s->attrib && s->attrib->internal) ||
|
||||
+ internal_by_name(s->name)) {
|
||||
+ fprintf(fd, "ENV{zdev_%s__%x_%x_%04x_0x%016"
|
||||
+ PRIx64 "_0x%016" PRIx64 "}=\"%s\"\n",
|
||||
+ internal_get_name(s->name),
|
||||
+ node->id.fcp_dev.cssid,
|
||||
+ node->id.fcp_dev.ssid,
|
||||
+ node->id.fcp_dev.devno, node->id.wwpn,
|
||||
+ node->id.lun, s->value);
|
||||
+ } else {
|
||||
+ fprintf(fd, "ATTR{[ccw/%s]0x%016" PRIx64
|
||||
+ "/0x%016" PRIx64 "/%s}=\"%s\"\n",
|
||||
+ hba_id, node->id.wwpn, node->id.lun,
|
||||
+ s->name, s->value);
|
||||
+ }
|
||||
}
|
||||
last_node = node;
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
Subject: zpcictl: Make device node for NVMe optional
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: 342c6a3707315514f0f886fabb532f6c8b59b694
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: Make device node for NVMe optional
|
||||
|
||||
At the moment, if we specify the slot address of an NVMe device but
|
||||
can't find the corresponding device node, the execution is terminated.
|
||||
|
||||
This is a bit harsh as the device node is rather optional and only
|
||||
necessary to collect S.M.A.R.T. data. We should still be able to issue
|
||||
the error reporting, even if we couldn't determine the device node.
|
||||
|
||||
Therefore, make sure the device node for NVMe devices is optional by
|
||||
changing various error messages to warnings.
|
||||
Change sysfs_get_slot_addr() to have a return value and work with that
|
||||
accordingly.
|
||||
Also make sure, that execution is terminated when a valid device node
|
||||
was specified but no matching slot address was determined. The slot
|
||||
address is necessary to issue the error reporting commands.
|
||||
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
zpcictl/zpcictl.c | 30 ++++++++++++++++++++----------
|
||||
1 file changed, 20 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/zpcictl/zpcictl.c
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -104,6 +104,9 @@ static char *collect_smart_data(struct z
|
||||
char *cmd;
|
||||
FILE *fd;
|
||||
|
||||
+ if (!pdev->device)
|
||||
+ return NULL;
|
||||
+
|
||||
util_asprintf(&cmd, SMARTCTL_CMDLINE, pdev->device);
|
||||
fd = popen(cmd, "r");
|
||||
if (!fd)
|
||||
@@ -175,7 +178,7 @@ static void sysfs_write_data(struct zpci
|
||||
/* lstat() doesn't work for sysfs files, so we have to work with a fixed size */
|
||||
#define READLINK_SIZE 256
|
||||
|
||||
-static void sysfs_get_slot_addr(const char *dev, char *slot)
|
||||
+static int sysfs_get_slot_addr(const char *dev, char *slot)
|
||||
{
|
||||
char device[READLINK_SIZE], *result;
|
||||
unsigned int major, minor;
|
||||
@@ -184,8 +187,9 @@ static void sysfs_get_slot_addr(const ch
|
||||
char *path;
|
||||
|
||||
if (stat(dev, &dev_stat) != 0) {
|
||||
- errx(EXIT_FAILURE, "Could not get stat information for %s: %s",
|
||||
- dev, strerror(errno));
|
||||
+ warnx("Could not get stat information for %s: %s",
|
||||
+ dev, strerror(errno));
|
||||
+ return 0;
|
||||
}
|
||||
major = major(dev_stat.st_rdev);
|
||||
minor = minor(dev_stat.st_rdev);
|
||||
@@ -193,18 +197,21 @@ static void sysfs_get_slot_addr(const ch
|
||||
path = util_path_sysfs("dev/char/%u:%u/device", major, minor);
|
||||
len = readlink(path, device, READLINK_SIZE - 1);
|
||||
free(path);
|
||||
- if (len != -1)
|
||||
+ if (len != -1) {
|
||||
device[len] = '\0';
|
||||
- else
|
||||
- errx(EXIT_FAILURE, "Could not read device link for %s", dev);
|
||||
+ } else {
|
||||
+ warnx("Could not read device link for %s", dev);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
result = strrchr(device, '/');
|
||||
if (result)
|
||||
result++;
|
||||
else
|
||||
result = device;
|
||||
-
|
||||
strcpy(slot, result);
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static void get_device_node(struct zpci_device *pdev)
|
||||
@@ -219,12 +226,13 @@ static void get_device_node(struct zpci_
|
||||
if (count == -1) {
|
||||
warnx("Could not read directory %s: %s", path, strerror(errno));
|
||||
free(path);
|
||||
- exit(EXIT_FAILURE);
|
||||
+ return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
util_asprintf(&dev, "/dev/%s", de_vec[i]->d_name);
|
||||
- sysfs_get_slot_addr(dev, slot);
|
||||
+ if (!sysfs_get_slot_addr(dev, slot))
|
||||
+ continue;
|
||||
if (strcmp(slot, pdev->slot) == 0) {
|
||||
pdev->device = dev;
|
||||
break;
|
||||
@@ -255,7 +263,9 @@ static void get_device_info(struct zpci_
|
||||
if (is_blk_dev(dev))
|
||||
errx(EXIT_FAILURE, "Unsupported device type %s", dev);
|
||||
if (is_char_dev(dev)) {
|
||||
- sysfs_get_slot_addr(dev, pdev->slot);
|
||||
+ if (!sysfs_get_slot_addr(dev, pdev->slot))
|
||||
+ errx(EXIT_FAILURE,
|
||||
+ "Could not determine slot address for %s", dev);
|
||||
pdev->device = dev;
|
||||
} else {
|
||||
strcpy(pdev->slot, dev);
|
@ -1,505 +0,0 @@
|
||||
Subject: zdev: Implement support for early device configuration
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: 156450f359bb13776fac2130a1cac00a48c2deda
|
||||
Problem-ID: LS1604
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zdev: Implement support for early device configuration
|
||||
|
||||
Enable user to specify that a device should be configured early, that is
|
||||
during the initial RAM-disk boot phase. This may be necessary, e.g. to
|
||||
override auto-configuration for a device which is also applied during
|
||||
that boot phase. It may also be used to manually specify devices that
|
||||
are required to access the root file system, such as networking devices.
|
||||
|
||||
Users can mark devices as requiring early configuration by specifying
|
||||
a value of 1 for the newly added internal attribute zdev:early:
|
||||
|
||||
# chzdev dasd-eckd 0.0.1234 -p zdev:early=1
|
||||
|
||||
This can be changed back by removing the attribute setting, or by
|
||||
setting the attribute value to 0:
|
||||
|
||||
# chzdev dasd-eckd 0.0.1234 -p -r zdev:early
|
||||
|
||||
or
|
||||
|
||||
# chzdev dasd-eckd 0.0.1234 -p zdev:early=0
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/dracut/95zdev/module-setup.sh | 21 +------
|
||||
zdev/include/internal.h | 5 +
|
||||
zdev/initramfs/hooks/zdev | 19 ++++++
|
||||
zdev/man/chzdev.8 | 29 ++++++++++
|
||||
zdev/src/chzdev.c | 4 -
|
||||
zdev/src/ctc.c | 2
|
||||
zdev/src/dasd.c | 3 +
|
||||
zdev/src/generic_ccw.c | 2
|
||||
zdev/src/internal.c | 13 ++++
|
||||
zdev/src/lcs.c | 2
|
||||
zdev/src/qeth.c | 2
|
||||
zdev/src/root.c | 82 ++++++++++++++++++++++-------
|
||||
zdev/src/zfcp_host.c | 2
|
||||
zdev/src/zfcp_lun.c | 2
|
||||
14 files changed, 152 insertions(+), 36 deletions(-)
|
||||
|
||||
--- a/zdev/dracut/95zdev/module-setup.sh
|
||||
+++ b/zdev/dracut/95zdev/module-setup.sh
|
||||
@@ -45,23 +45,12 @@ install() {
|
||||
# Hook to parse zdev kernel parameter
|
||||
inst_hook cmdline 95 "$moddir/parse-zdev.sh"
|
||||
|
||||
- # Obtain root device configuration
|
||||
-
|
||||
- # Exit early if root device type is unknown
|
||||
- if ! lszdev --by-path / >/dev/null 2>&1 ; then
|
||||
- return 0
|
||||
- fi
|
||||
-
|
||||
+ # Obtain early + root device configuration
|
||||
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||
-
|
||||
- if chzdev --export - --persistent --by-path / >/dev/null 2>&1 ; then
|
||||
- # Use persistent configuration
|
||||
- chzdev --export "$_tempfile" --persistent --by-path / --quiet --type
|
||||
- else
|
||||
- # Use active configuration
|
||||
- chzdev --export "$_tempfile" --active --by-path / --quiet --type
|
||||
- sed -i -e 's/active/persistent/g' "$_tempfile"
|
||||
- fi
|
||||
+ chzdev --export "$_tempfile" --persistent --by-path / --quiet \
|
||||
+ --type 2>/dev/null
|
||||
+ chzdev --export - --persistent --by-attrib "zdev:early=1" --quiet \
|
||||
+ --type 2>/dev/null >> "$_tempfile"
|
||||
|
||||
# Apply via --import to prevent other devices from being configured
|
||||
chzdev --import "$_tempfile" --persistent --base "/etc=$initdir/etc" \
|
||||
--- a/zdev/include/internal.h
|
||||
+++ b/zdev/include/internal.h
|
||||
@@ -12,7 +12,12 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
+#include "attrib.h"
|
||||
+
|
||||
#define INTERNAL_ATTR_PREFIX "zdev:"
|
||||
+#define INTERNAL_ATTR_EARLY INTERNAL_ATTR_PREFIX "early"
|
||||
+
|
||||
+extern struct attrib internal_attr_early;
|
||||
|
||||
const char *internal_get_name(const char *name);
|
||||
bool internal_by_name(const char *name);
|
||||
--- a/zdev/initramfs/hooks/zdev
|
||||
+++ b/zdev/initramfs/hooks/zdev
|
||||
@@ -10,7 +10,8 @@
|
||||
# configuration data during boot.
|
||||
#
|
||||
|
||||
-PREREQ=""
|
||||
+# Needs to run after udev or resulting udev rules could be overwritten
|
||||
+PREREQ="udev"
|
||||
|
||||
prereqs()
|
||||
{
|
||||
@@ -37,3 +38,19 @@ done
|
||||
copy_exec /sbin/chzdev
|
||||
copy_exec /sbin/lszdev
|
||||
copy_exec /sbin/vmcp
|
||||
+
|
||||
+_tempfile=$(mktemp --tmpdir initramfs-zdev.XXXXXX)
|
||||
+
|
||||
+# Obtain early + root device configuration
|
||||
+chzdev --export "$_tempfile" --persistent --by-path / \
|
||||
+ --by-attrib "zdev:early=1" --quiet --type 2>/dev/null
|
||||
+
|
||||
+# Apply via --import to prevent other devices from being configured.
|
||||
+# Rename the resulting cio-ignore rule to ensure that it does not override
|
||||
+# the one copied by the initramfs udev hook to /lib/udev.
|
||||
+chzdev --import "$_tempfile" --persistent \
|
||||
+ --base "/etc/udev/rules.d/41-cio-ignore.rules=$DESTDIR/etc/udev/rules.d/41-cio-ignore-root.rules" \
|
||||
+ --base "/etc=$DESTDIR/etc" --yes --quiet --no-root-update --force \
|
||||
+ >/dev/null
|
||||
+
|
||||
+rm -f "$_tempfile"
|
||||
--- a/zdev/man/chzdev.8
|
||||
+++ b/zdev/man/chzdev.8
|
||||
@@ -334,6 +334,35 @@ a specific attribute.
|
||||
.PP
|
||||
.
|
||||
.
|
||||
+.SS "Special settings"
|
||||
+The following special settings affect how devices are handled by chzdev:
|
||||
+.PP
|
||||
+.
|
||||
+.BR zdev:early =0|1
|
||||
+.RS 4
|
||||
+Control in which stage of the boot process a device is activated:
|
||||
+.TP 4
|
||||
+.B 0
|
||||
+Device is activated normally during boot (default).
|
||||
+.PP
|
||||
+.TP 4
|
||||
+.B 1
|
||||
+Device is activated early in the boot process, by the initial RAM-disk.
|
||||
+.PP
|
||||
+Specify a value of 1 for this attribute in any of the following situations:
|
||||
+.TP 4
|
||||
+\(bu
|
||||
+To ensure that your settings override auto-configuration settings.
|
||||
+.PP
|
||||
+.TP 4
|
||||
+\(bu
|
||||
+To ensure that a device required to access the root file system is correctly
|
||||
+enabled during boot. An example would be a networking device, or a device that
|
||||
+is intended to extend a logical volume that provides the root file system.
|
||||
+.PP
|
||||
+.RE
|
||||
+.
|
||||
+.
|
||||
.SH ACTIONS
|
||||
You can use one of the action options listed below to specify the
|
||||
.B main tool action
|
||||
--- a/zdev/src/chzdev.c
|
||||
+++ b/zdev/src/chzdev.c
|
||||
@@ -3025,8 +3025,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if ((pers_mod_devs || pers_mod_devtypes) && !opts.no_root_check &&
|
||||
!dryrun) {
|
||||
- /* If the root device/device type has been modified, additional
|
||||
- * work might be necessary. */
|
||||
+ /* If the root device/device type or early devices have been
|
||||
+ * modified, additional work might be necessary. */
|
||||
rc = root_check();
|
||||
if (rc && !drc)
|
||||
drc = rc;
|
||||
--- a/zdev/src/ctc.c
|
||||
+++ b/zdev/src/ctc.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ctc_auto.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "namespace.h"
|
||||
#include "path.h"
|
||||
@@ -425,6 +426,7 @@ static struct subtype ctc_subtype = {
|
||||
&ccw_attr_online,
|
||||
&ctc_attr_buffer,
|
||||
&ctc_attr_protocol,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
.support_definable = 1,
|
||||
--- a/zdev/src/dasd.c
|
||||
+++ b/zdev/src/dasd.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "dasd.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "modprobe.h"
|
||||
#include "module.h"
|
||||
@@ -616,6 +617,7 @@ struct subtype dasd_subtype_eckd = {
|
||||
&dasd_attr_reservation_policy,
|
||||
&dasd_attr_last_known_reservation_state,
|
||||
&dasd_attr_safe_offline,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
|
||||
@@ -651,6 +653,7 @@ struct subtype dasd_subtype_fba = {
|
||||
&dasd_attr_reservation_policy,
|
||||
&dasd_attr_last_known_reservation_state,
|
||||
&dasd_attr_safe_offline,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
|
||||
--- a/zdev/src/generic_ccw.c
|
||||
+++ b/zdev/src/generic_ccw.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "devnode.h"
|
||||
#include "devtype.h"
|
||||
#include "generic_ccw.h"
|
||||
+#include "internal.h"
|
||||
#include "namespace.h"
|
||||
#include "path.h"
|
||||
#include "subtype.h"
|
||||
@@ -182,6 +183,7 @@ static struct subtype generic_ccw_subtyp
|
||||
.dev_attribs = ATTRIB_ARRAY(
|
||||
&ccw_attr_online,
|
||||
&ccw_attr_cmb_enable,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
.generic = 1,
|
||||
--- a/zdev/src/internal.c
|
||||
+++ b/zdev/src/internal.c
|
||||
@@ -9,9 +9,22 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
+#include "attrib.h"
|
||||
#include "internal.h"
|
||||
#include "misc.h"
|
||||
|
||||
+struct attrib internal_attr_early = {
|
||||
+ .name = INTERNAL_ATTR_EARLY,
|
||||
+ .title = "Activate device early during boot",
|
||||
+ .desc = "Control the time of activation of a device:\n"
|
||||
+ " 0: Device is activated normally during boot\n"
|
||||
+ " 1: Device is activated early in the boot process, by the\n"
|
||||
+ " initial RAM-disk\n",
|
||||
+ .defval = "0",
|
||||
+ .accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||
+ .internal = 1,
|
||||
+};
|
||||
+
|
||||
/* Return identifier of internal attribute with specified @name. */
|
||||
const char *internal_get_name(const char *name)
|
||||
{
|
||||
--- a/zdev/src/lcs.c
|
||||
+++ b/zdev/src/lcs.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "lcs.h"
|
||||
#include "lcs_auto.h"
|
||||
#include "misc.h"
|
||||
@@ -362,6 +363,7 @@ static struct subtype lcs_subtype = {
|
||||
&ccw_attr_online,
|
||||
&lcs_attr_lancmd_timeout,
|
||||
&lcs_attr_recover,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
.support_definable = 1,
|
||||
--- a/zdev/src/qeth.c
|
||||
+++ b/zdev/src/qeth.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "ccwgroup.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "namespace.h"
|
||||
#include "nic.h"
|
||||
@@ -1445,6 +1446,7 @@ struct subtype qeth_subtype_qeth = {
|
||||
&qeth_attr_vnicc_takeover_learning,
|
||||
&qeth_attr_vnicc_bridge_invisible,
|
||||
&qeth_attr_vnicc_rx_bcast,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
.support_definable = 1,
|
||||
--- a/zdev/src/root.c
|
||||
+++ b/zdev/src/root.c
|
||||
@@ -8,11 +8,13 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "root.h"
|
||||
@@ -20,31 +22,78 @@
|
||||
#include "setting.h"
|
||||
#include "subtype.h"
|
||||
|
||||
-/* Determine if the root device was modified. If it was modified, run the
|
||||
- * corresponding root-install scripts. */
|
||||
+static bool is_early_removed(struct device *dev)
|
||||
+{
|
||||
+ struct setting *s;
|
||||
+
|
||||
+ s = setting_list_find(dev->persistent.settings,
|
||||
+ internal_attr_early.name);
|
||||
+ if (!s || !s->modified)
|
||||
+ return false;
|
||||
+ if (!s->actual_value || strcmp(s->actual_value, "1") != 0)
|
||||
+ return false;
|
||||
+ if (s->removed || strcmp(s->value, "0") == 0)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static void add_early_removed(struct util_list *selected)
|
||||
+{
|
||||
+ int i, j;
|
||||
+ struct devtype *dt;
|
||||
+ struct subtype *st;
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ for (i = 0; devtypes[i]; i++) {
|
||||
+ dt = devtypes[i];
|
||||
+ for (j = 0; dt->subtypes[j]; j++) {
|
||||
+ st = dt->subtypes[j];
|
||||
+ util_list_iterate(&st->devices->hash.list, dev) {
|
||||
+ if (is_early_removed(dev)) {
|
||||
+ selected_dev_list_add(selected, dt, st,
|
||||
+ dev->id, NULL, EXIT_OK);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Determine if initial RAM-disk needs updating. If so, run the corresponding
|
||||
+ * scripts if available. */
|
||||
exit_code_t root_check(void)
|
||||
{
|
||||
struct util_list *selected, *params, *mod = NULL;
|
||||
struct selected_dev_node *sel;
|
||||
struct device *dev;
|
||||
char *params_str;
|
||||
- exit_code_t rc;
|
||||
+ exit_code_t rc = EXIT_OK;
|
||||
struct strlist_node *s;
|
||||
struct devtype *dt;
|
||||
+ struct select_opts *select;
|
||||
|
||||
- debug("Checking for modified root device configuration\n");
|
||||
+ debug("Checking for required initial RAM-disk update\n");
|
||||
|
||||
- /* Get list of devices that provide the root device. */
|
||||
+ /* Get list of devices that provide the root device or require
|
||||
+ * early configuration. */
|
||||
selected = selected_dev_list_new();
|
||||
- rc = select_by_path(NULL, selected, config_active, scope_mandatory,
|
||||
- NULL, NULL, PATH_ROOT, err_ignore);
|
||||
- if (rc) {
|
||||
+ /* First add devices that had zdev:early removed or changed to 0.
|
||||
+ * The subsequent call to select_devices() will filter out any
|
||||
+ * duplicates. */
|
||||
+ add_early_removed(selected);
|
||||
+ /* Now add devices required for root file system. */
|
||||
+ if (select_by_path(NULL, selected, config_active, scope_mandatory,
|
||||
+ NULL, NULL, PATH_ROOT, err_ignore)) {
|
||||
/* Running from an unknown root device is not an error. */
|
||||
verb("Note: Could not determine if root device configuration "
|
||||
"needs to be updated\n");
|
||||
- rc = 0;
|
||||
- goto out;
|
||||
}
|
||||
+ /* Finally add devices with zdev:early=1. */
|
||||
+ select = select_opts_new();
|
||||
+ strlist_add(&select->by_attr, "%s=1", INTERNAL_ATTR_EARLY);
|
||||
+ select_devices(select, selected, 1, 0, 0,
|
||||
+ config_active | config_persistent, scope_mandatory,
|
||||
+ err_ignore);
|
||||
+ select_opts_free(select);
|
||||
|
||||
/* Determine if any of the devices or device types has been modified. */
|
||||
mod = strlist_new();
|
||||
@@ -68,19 +117,18 @@ exit_code_t root_check(void)
|
||||
|
||||
if (util_list_is_empty(mod))
|
||||
goto out;
|
||||
- info("Note: Some of the changes affect devices providing the root "
|
||||
- "file system:\n");
|
||||
+ info("Note: The initial RAM-disk must be updated for these changes to take effect:\n");
|
||||
util_list_iterate(mod, s)
|
||||
info(" - %s\n", s->str);
|
||||
- info(" Additional steps such as rebuilding the RAM-disk might be "
|
||||
- "required.\n");
|
||||
|
||||
/* Check if script is available. */
|
||||
- if (!util_path_is_reg_file(PATH_ROOT_SCRIPT))
|
||||
+ if (!util_path_is_reg_file(PATH_ROOT_SCRIPT)) {
|
||||
+ warn("A manual update of the initial RAM-disk is required.\n");
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
/* Ask for confirmation. */
|
||||
- if (!confirm("Update persistent root device configuration now?")) {
|
||||
+ if (!confirm("Update initial RAM-disk now?")) {
|
||||
rc = EXIT_ABORTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -97,7 +145,7 @@ exit_code_t root_check(void)
|
||||
/* Run update command. */
|
||||
if (misc_system(err_delayed_print, "%s %s", PATH_ROOT_SCRIPT,
|
||||
params_str) != 0) {
|
||||
- error("Failure while updating root device configuration\n");
|
||||
+ error("Failure while updating initial RAM-disk\n");
|
||||
delayed_print(DELAY_INDENT);
|
||||
rc = EXIT_RUNTIME_ERROR;
|
||||
}
|
||||
--- a/zdev/src/zfcp_host.c
|
||||
+++ b/zdev/src/zfcp_host.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ccw.h"
|
||||
#include "device.h"
|
||||
#include "devtype.h"
|
||||
+#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "setting.h"
|
||||
@@ -247,6 +248,7 @@ struct subtype zfcp_host_subtype = {
|
||||
&zfcp_host_attr_failed,
|
||||
&zfcp_host_attr_port_remove,
|
||||
&zfcp_host_attr_port_rescan,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
|
||||
--- a/zdev/src/zfcp_lun.c
|
||||
+++ b/zdev/src/zfcp_lun.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "devnode.h"
|
||||
#include "devtype.h"
|
||||
#include "misc.h"
|
||||
+#include "internal.h"
|
||||
#include "namespace.h"
|
||||
#include "path.h"
|
||||
#include "scsi.h"
|
||||
@@ -1097,6 +1098,7 @@ struct subtype zfcp_lun_subtype = {
|
||||
&zfcp_lun_attr_scsi_timeout,
|
||||
&zfcp_lun_attr_scsi_state,
|
||||
&zfcp_lun_attr_scsi_delete,
|
||||
+ &internal_attr_early,
|
||||
),
|
||||
.prefixes = STRING_ARRAY(SCSI_ATTR_PREFIX),
|
||||
.unknown_dev_attribs = 1,
|
@ -1,143 +0,0 @@
|
||||
Subject: zpcictl: Change wording of man-page and help output
|
||||
From: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
|
||||
Summary: zpcictl: Add tool to manage PCI devices
|
||||
Description: Use the zpcictl tool to manage PCI devices on the IBM Z
|
||||
platform. Initial functions include generating firmware
|
||||
error logs, resetting PCI devices, and preparing a device
|
||||
for further repair actions.
|
||||
Upstream-ID: aaaebb2030c80151ecac528f22cb9a52752b868c
|
||||
Problem-ID: RAS1703
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
zpcictl: Change wording of man-page and help output
|
||||
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Jan Hoeppner <jan.hoeppner@de.ibm.com>
|
||||
---
|
||||
zpcictl/zpcictl.8 | 38 +++++++++++++++-----------------------
|
||||
zpcictl/zpcictl.c | 15 ++++++++-------
|
||||
2 files changed, 23 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/zpcictl/zpcictl.8
|
||||
+++ b/zpcictl/zpcictl.8
|
||||
@@ -20,7 +20,7 @@
|
||||
.TH zpcictl 8 "Oct 2018" s390-tools zpcictl
|
||||
.
|
||||
.SH NAME
|
||||
-zpcictl - Manage PCI devices on z Systems
|
||||
+zpcictl - Manage PCI devices on IBM Z
|
||||
.
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
@@ -30,50 +30,42 @@ zpcictl - Manage PCI devices on z System
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
-With
|
||||
+Use
|
||||
.B zpcictl
|
||||
-, you can manage PCI devices on the IBM z Systems platform. It is especially
|
||||
-used for reporting erroneous PCI devices to the service element.
|
||||
+to manage PCI devices on the IBM Z platform. In particular,
|
||||
+use this command to report defective PCI devices to the service element.
|
||||
|
||||
.B Note:
|
||||
For NVMe devices additional data (such as S.M.A.R.T. data) is collected and sent
|
||||
-with any error handling action. The smartmontools are required to be installed
|
||||
-for this to work.
|
||||
+with any error handling action. For this extendend data collection, the
|
||||
+smartmontools must be installed.
|
||||
.PP
|
||||
.
|
||||
.
|
||||
.SH DEVICE
|
||||
-.B DEVICE
|
||||
-can be either the PCI slot address (e.g. 0000:00:00.0) or the main device node
|
||||
-of an NVMe device (e.g.
|
||||
+A PCI slot address (e.g. 0000:00:00.0) or the main device node of an NVMe
|
||||
+device (e.g.
|
||||
.I /dev/nvme0
|
||||
).
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
-.SS Error Handling
|
||||
+.SS Error Handling Options
|
||||
.OD reset "" "DEVICE"
|
||||
-Reset
|
||||
-.I DEVICE
|
||||
-and initiate a re-initialization of the PCI device.
|
||||
+Reset and re-initialize the PCI device.
|
||||
.PP
|
||||
.
|
||||
.OD deconfigure "" "DEVICE"
|
||||
-De-configure
|
||||
-.I DEVICE
|
||||
-and prepare for any repair action. This action will move the
|
||||
-PCI device from a configured to a reserved state.
|
||||
+Deconfigure the PCI device and prepare for any repair action. This action
|
||||
+changes the status of the PCI device from configured to reserved.
|
||||
.PP
|
||||
.
|
||||
.OD report-error "" "DEVICE"
|
||||
-Report any device error for
|
||||
-.IR DEVICE .
|
||||
-The
|
||||
-.I DEVICE
|
||||
-is marked as erroneous and no further action is initiated on it.
|
||||
+Report any device error for the PCI device.
|
||||
+The device is marked as defective but no further action is taken.
|
||||
.PP
|
||||
.
|
||||
-.SS Misc
|
||||
+.SS General Options
|
||||
.OD help "h" ""
|
||||
Print usage information, then exit.
|
||||
.PP
|
||||
--- a/zpcictl/zpcictl.c
|
||||
+++ b/zpcictl/zpcictl.c
|
||||
@@ -27,8 +27,9 @@
|
||||
#define SMARTCTL_CMDLINE "smartctl -x %s 2>/dev/null"
|
||||
|
||||
static const struct util_prg prg = {
|
||||
- .desc = "Use zpcictl to manage PCI devices on s390\n"
|
||||
- "DEVICE is the slot id or node of the device (e.g. /dev/nvme0)",
|
||||
+ .desc = "Use zpcictl to manage PCI devices on IBM Z\n"
|
||||
+ "DEVICE is the slot ID or node of the device "
|
||||
+ "(e.g. 0000:00:00.0 or /dev/nvme0)",
|
||||
.args = "DEVICE",
|
||||
.copyright_vec = {
|
||||
{
|
||||
@@ -46,23 +47,23 @@ static const struct util_prg prg = {
|
||||
#define OPT_REPORT_ERR 130
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
- UTIL_OPT_SECTION("ERROR HANDLING"),
|
||||
+ UTIL_OPT_SECTION("ERROR HANDLING OPTIONS"),
|
||||
{
|
||||
.option = { "reset", no_argument, NULL, OPT_RESET },
|
||||
- .desc = "Reset device",
|
||||
+ .desc = "Reset the device",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "deconfigure", no_argument, NULL, OPT_DECONF },
|
||||
- .desc = "De-configure device and prepare for any repair action",
|
||||
+ .desc = "Deconfigure the device to prepare for any repair action",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
{
|
||||
.option = { "report-error", no_argument, NULL, OPT_REPORT_ERR },
|
||||
- .desc = "Report device error to service element (SE)",
|
||||
+ .desc = "Report a device error to the service element (SE)",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
},
|
||||
- UTIL_OPT_SECTION("MISC"),
|
||||
+ UTIL_OPT_SECTION("GENERAL OPTIONS"),
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
@ -1,50 +0,0 @@
|
||||
Subject: zdev: Add support for handling I/O configuration data
|
||||
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
|
||||
Summary: zdev: Add support for handling I/O configuration data
|
||||
Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode
|
||||
can access a firmware-generated I/O configuration data file that
|
||||
contains s390-specific information about available I/O devices
|
||||
such as qeth device numbers and parameters, and FCP device IDs.
|
||||
|
||||
This data file is intended to remove the need for users to
|
||||
manually enter the corresponding device data during installation.
|
||||
|
||||
Linux kernels with the corresponding support make the I/O
|
||||
configuration data available at the following location:
|
||||
|
||||
/sys/firmware/sclp_sd/config/data
|
||||
|
||||
This patch set adds support for handling this data file using the
|
||||
chzdev and lszdev tools:
|
||||
|
||||
- I/O configuration data can be applied using chzdev's --import
|
||||
option
|
||||
- Initial RAM-Disk scripts automatically apply the
|
||||
I/O configuration data to the system configuration
|
||||
- lszdev can be used to display the applied auto-configuration
|
||||
data
|
||||
- chzdev can be used to manually override the
|
||||
auto-configuration data
|
||||
|
||||
Upstream-ID: -
|
||||
Problem-ID: LS1604
|
||||
|
||||
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
---
|
||||
zdev/src/zdev-root-update.dracut | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
--- a/zdev/src/zdev-root-update.dracut
|
||||
+++ b/zdev/src/zdev-root-update.dracut
|
||||
@@ -20,10 +20,4 @@ dracut -f || {
|
||||
exit 1
|
||||
}
|
||||
|
||||
-echo "Installing IPL record"
|
||||
-zipl --noninteractive || {
|
||||
- echo "${TOOLNAME}: Error: Could not install IPL record" >&2
|
||||
- exit 1
|
||||
-}
|
||||
-
|
||||
exit 0
|
@ -1,75 +0,0 @@
|
||||
Subject: dbginfo: gather nvme related data
|
||||
From: Sebastian Ott <sebott@linux.ibm.com>
|
||||
|
||||
Summary: s390-tools/dbginfo: Collect NVMe-related debug data
|
||||
Description: Collect SMART (Self-Monitoring, Analysis and Reporting Technology)
|
||||
data in dbginfo.sh .
|
||||
Upstream-ID: b9e47e356bbfc92e41b758e74606baacbab33ee4
|
||||
Problem-ID: RAS1702
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
dbginfo: gather nvme related data
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
|
||||
---
|
||||
scripts/dbginfo.sh | 26 +++++++++++++++++++++++++-
|
||||
1 file changed, 25 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/scripts/dbginfo.sh
|
||||
+++ b/scripts/dbginfo.sh
|
||||
@@ -182,11 +182,14 @@ readonly OUTPUT_FILE_XML="${WORKPATH}dom
|
||||
# File that includes the docker inspect output
|
||||
readonly OUTPUT_FILE_DOCKER="${WORKPATH}docker_inspect.out"
|
||||
|
||||
+# File that includes nvme related information
|
||||
+readonly OUTPUT_FILE_NVME="${WORKPATH}nvme.out"
|
||||
+
|
||||
# Mount point of the debug file system
|
||||
readonly MOUNT_POINT_DEBUGFS="/sys/kernel/debug"
|
||||
|
||||
# The amount of steps running the whole collections
|
||||
-readonly COLLECTION_COUNT=11
|
||||
+readonly COLLECTION_COUNT=12
|
||||
|
||||
# The kernel version (e.g. '2' from 2.6.32 or '3' from 3.2.1)
|
||||
readonly KERNEL_VERSION=$(uname -r 2>/dev/null | cut -d'.' -f1)
|
||||
@@ -829,6 +832,25 @@ collect_docker() {
|
||||
}
|
||||
|
||||
########################################
|
||||
+collect_nvme() {
|
||||
+ local NVME
|
||||
+
|
||||
+ pr_syslog_stdout "11 of ${COLLECTION_COUNT}: Collecting nvme output"
|
||||
+ call_run_command "nvme list" "${OUTPUT_FILE_NVME}"
|
||||
+
|
||||
+ for NVME in /dev/nvme[0-9]*; do
|
||||
+ if [ -c $NVME ]; then
|
||||
+ call_run_command "smartctl -x $NVME" "${OUTPUT_FILE_NVME}"
|
||||
+ call_run_command "nvme fw-log $NVME" "${OUTPUT_FILE_NVME}"
|
||||
+ call_run_command "nvme smart-log $NVME" "${OUTPUT_FILE_NVME}"
|
||||
+ call_run_command "nvme error-log $NVME" "${OUTPUT_FILE_NVME}"
|
||||
+ fi
|
||||
+ done
|
||||
+
|
||||
+ pr_log_stdout " "
|
||||
+}
|
||||
+
|
||||
+########################################
|
||||
post_processing() {
|
||||
local file_mtime
|
||||
local file_mtime_epoche
|
||||
@@ -1120,6 +1142,8 @@ collect_domain_xml
|
||||
|
||||
collect_docker
|
||||
|
||||
+collect_nvme
|
||||
+
|
||||
post_processing
|
||||
|
||||
create_package
|
@ -1,65 +0,0 @@
|
||||
Subject: [PATCH] [FEAT NET1711] qethqoat: add OSA-Express7S support
|
||||
From: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
|
||||
Summary: qethqoat: add OSA-Express7S support
|
||||
Description: Add the missing identifiers to report the correct card name and
|
||||
link speed.
|
||||
Upstream-ID: 20145b6d06debd47944bff0a471d17e5eba07010
|
||||
Problem-ID: NET1711
|
||||
|
||||
Upstream-Description:
|
||||
|
||||
qethqoat: add OSA-Express7S support
|
||||
|
||||
Add the missing identifiers to report the card name and link speed.
|
||||
|
||||
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
|
||||
|
||||
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
---
|
||||
qethqoat/qethqoat.c | 6 ++++++
|
||||
qethqoat/qethqoat.h | 2 ++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
--- a/qethqoat/qethqoat.c
|
||||
+++ b/qethqoat/qethqoat.c
|
||||
@@ -208,6 +208,9 @@ static void print_physical(struct qeth_q
|
||||
case OAT_OSA_GEN_OSAE6S:
|
||||
osagen = "OSA-Express6S";
|
||||
break;
|
||||
+ case OAT_OSA_GEN_OSAE7S:
|
||||
+ osagen = "OSA-Express7S";
|
||||
+ break;
|
||||
default:
|
||||
sprintf(tmp, "unknown (0x%x)", phdr->osa_gen);
|
||||
osagen = tmp;
|
||||
@@ -239,6 +242,9 @@ static void print_physical(struct qeth_q
|
||||
case OAT_PORT_SPEED_10gbs_full:
|
||||
speed = "10 Gb/s / full duplex";
|
||||
break;
|
||||
+ case OAT_PORT_SPEED_25gbs_full:
|
||||
+ speed = "25 Gb/s / full duplex";
|
||||
+ break;
|
||||
case OAT_PORT_SPEED_UNKNOWN:
|
||||
speed = "unknown / unknown";
|
||||
break;
|
||||
--- a/qethqoat/qethqoat.h
|
||||
+++ b/qethqoat/qethqoat.h
|
||||
@@ -58,6 +58,7 @@ struct qeth_qoat_physical {
|
||||
#define OAT_OSA_GEN_OSAE4S 0x02
|
||||
#define OAT_OSA_GEN_OSAE5S 0x03
|
||||
#define OAT_OSA_GEN_OSAE6S 0x04
|
||||
+#define OAT_OSA_GEN_OSAE7S 0x05
|
||||
__u8 osa_gen;
|
||||
#define OAT_PORT_SPEED_UNKNOWN 0x00
|
||||
#define OAT_PORT_SPEED_10mbs_half 0x01
|
||||
@@ -68,6 +69,7 @@ struct qeth_qoat_physical {
|
||||
#define OAT_PORT_SPEED_1000mbs_full 0x06
|
||||
#define OAT_PORT_SPEED_NA 0x07
|
||||
#define OAT_PORT_SPEED_10gbs_full 0x08
|
||||
+#define OAT_PORT_SPEED_25gbs_full 0x0A
|
||||
__u8 port_speed;
|
||||
#define OAT_PORT_MEDIA_COPPER 0x01
|
||||
#define OAT_PORT_MEDIA_MULTI_MODE 0x02
|
@ -1,102 +0,0 @@
|
||||
From e9c030f2026b1b8e0399679600845c298aeb508d Mon Sep 17 00:00:00 2001
|
||||
From: Harald Freudenberger <freude@linux.ibm.com>
|
||||
Date: Mon, 21 Jan 2019 09:07:00 +0100
|
||||
Subject: zcrypt: refine lszcrypt man page
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Added some explanations about the columns shown with the
|
||||
lszcrypt verbose output.
|
||||
|
||||
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
|
||||
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||
---
|
||||
zconf/zcrypt/lszcrypt.8 | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 63 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/zconf/zcrypt/lszcrypt.8 b/zconf/zcrypt/lszcrypt.8
|
||||
index 826e109..bd235ec 100644
|
||||
--- a/zconf/zcrypt/lszcrypt.8
|
||||
+++ b/zconf/zcrypt/lszcrypt.8
|
||||
@@ -10,7 +10,7 @@
|
||||
.\" nroff -man lszcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
-.TH LSZCRYPT 8 "OCT 2017" "s390-tools"
|
||||
+.TH LSZCRYPT 8 "JAN 2019" "s390-tools"
|
||||
.SH NAME
|
||||
lszcrypt \- display zcrypt device and configuration information
|
||||
.SH SYNOPSIS
|
||||
@@ -111,6 +111,68 @@ Displays help text and exits.
|
||||
.TP 8
|
||||
.B -v, --version
|
||||
Displays version information and exits.
|
||||
+.SH VERBOSE LISTING DETAILS
|
||||
+Some of the columns showing up in verbose listing mode may need some
|
||||
+explanation:
|
||||
+.TP
|
||||
+.B TYPE and HWTYPE
|
||||
+The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
||||
+device driver presumes that this crypto card is. The currently known values
|
||||
+are 7=CEX3C, 8=CEX3A, 10=CEX4, 11=CEX5 and 12=CEX6.
|
||||
+.br
|
||||
+The TYPE is a human readable value showing the hardware type and the basic
|
||||
+function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
||||
+for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
||||
+.TP
|
||||
+.B REQUESTS
|
||||
+This is the counter value of successful processed requests on card or queue
|
||||
+level. Successful here means the request was processed without any failure
|
||||
+in the whole processing chain.
|
||||
+.TP
|
||||
+.B PENDING
|
||||
+The underlying firmware and hardware layer usually provide some queuing
|
||||
+space for requests. When this queue is already filled up, the zcrypt device
|
||||
+driver maintains a software queue of pending requests. The sum of these
|
||||
+both values is displayed here and shows the amount of requests waiting for
|
||||
+processing on card or queue level.
|
||||
+.TP
|
||||
+.B FUNCTIONS
|
||||
+This column shows firmware and hardware function details:
|
||||
+.br
|
||||
+S - APSC available: card/queue can handle requests with the special bit
|
||||
+enabled.
|
||||
+.br
|
||||
+M - Accelerator card/queue with support for RSA ME with up to 4k key size.
|
||||
+.br
|
||||
+C - Accelerator card/queue with support for RSA CRT with up to 4k key size.
|
||||
+.br
|
||||
+D - Card/queue is providing CCA functions (this is the CCA Coprocessor mode).
|
||||
+.br
|
||||
+A - Card/queue is providing Accelerator functions (this is the Accelerator mode).
|
||||
+.br
|
||||
+X - Card/queue is providing EP11 functions (this is the EP11 Coprocessor mode).
|
||||
+.br
|
||||
+N - APXA available (ability to address more than 16 crypto cards and domains).
|
||||
+.br
|
||||
+F - Full function support (opposed to restricted function support, see below).
|
||||
+.br
|
||||
+R - Restricted function support. The F and R flag both reflect if a
|
||||
+hypervisor is somehow restricting this crypto resource in a virtual
|
||||
+environment. Dependent on the hypervisor configuration the crypto requests
|
||||
+may be filtered by the hypervisor to allow only a subset of functions
|
||||
+within the virtual runtime environment. For example a shared CCA
|
||||
+Coprocessor may be restricted by the hypervisor to allow only clear key
|
||||
+operations within the guests.
|
||||
+.TP
|
||||
+.B DRIVER
|
||||
+.br
|
||||
+Shows which card or queue device driver currently handles this crypto
|
||||
+resource. Currently known drivers are cex4card/cex4queue (CEX4-CEX6
|
||||
+hardware), cex2card/cex2cqueue (CEX2C and CEX3C hardware),
|
||||
+cex2acard/cex2aqueue (CEX2A and CEX3A hardware) and vfio_ap (queue reserved
|
||||
+for use by kvm hypervisor for kvm guests and not accessible to host
|
||||
+applications). It is also valid to have no driver handling a queue which is
|
||||
+shown as a -no-driver- entry.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B lszcrypt
|
||||
--
|
||||
2.13.7
|
||||
|
@ -1,11 +0,0 @@
|
||||
--- a/zdev/dracut/95zdev/module-setup.sh 2019-01-10 11:39:08.000000000 -0500
|
||||
+++ b/zdev/dracut/95zdev/module-setup.sh 2019-01-14 13:28:33.983461097 -0500
|
||||
@@ -32,7 +32,7 @@
|
||||
installkernel() {
|
||||
# Add modules for all device types supported by chzdev (required for
|
||||
# auto-configuration)
|
||||
- instmods lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
|
||||
+ instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
|
||||
dasd_diag_mod zfcp
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
Subject: zdev: qeth BridgePort and VNICC attribute conflict
|
||||
From: Hans Wippel <hwippel@linux.ibm.com>
|
||||
|
||||
Description: zdev: qeth BridgePort and VNICC attribute conflict
|
||||
Symptom: chzdev cannot set VNICC attributes due to a conflict with
|
||||
BridgePort attributes.
|
||||
Problem: Existing conflict checking always assumes a BridgePort and a
|
||||
VNICC attribute are active.
|
||||
Solution: Introduce a function that determines if BridgePort or VNICC
|
||||
attributes are active and use only active attributes for conflict
|
||||
checking.
|
||||
Reproduction: Set VNICC attribute with chzdev w/o active BridgePort attributes.
|
||||
Upstream-ID: df01c470c2a680a924ccdba3b6657af4669002b2
|
||||
Problem-ID: 172409
|
||||
|
||||
|
||||
Signed-off-by: Hans Wippel <hwippel@linux.ibm.com>
|
||||
---
|
||||
zdev/src/qeth.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
--- a/zdev/src/qeth.c
|
||||
+++ b/zdev/src/qeth.c
|
||||
@@ -1171,6 +1171,37 @@ static exit_code_t check_ineffective_set
|
||||
return rc;
|
||||
}
|
||||
|
||||
+/* Check if a possibly conflicting setting is active in the configuration */
|
||||
+static bool conflict_setting_active(struct setting *s)
|
||||
+{
|
||||
+ enum qeth_attr_group_type t;
|
||||
+
|
||||
+ t = get_attr_group_type(s);
|
||||
+ if (t != group_bridge && t != group_vnicc) {
|
||||
+ /* Check BridgePort and VNICC attributes only */
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (s->specified) {
|
||||
+ /* Specified on the command line: We are strict here and do not
|
||||
+ * allow to specify VNICC and BridgePort attributes in the same
|
||||
+ * command to avoid issues when attributes are enabled/disabled
|
||||
+ * in the wrong order. Example: disable VNICC and enable
|
||||
+ * BridgePort in the same command would result in an error
|
||||
+ * because BridgePort attributes are set first.
|
||||
+ */
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (attrib_match_default(s->attrib, s->value)) {
|
||||
+ /* Not active if set to default value */
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (s->actual_value && strncmp(s->actual_value, "n/a", 3) == 0) {
|
||||
+ /* Not active if in n/a state (conflicting attribute set) */
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/* Check if there are conflicting attribute settings */
|
||||
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||
{
|
||||
@@ -1182,6 +1213,8 @@ static exit_code_t check_conflicting_set
|
||||
util_list_iterate(&list->list, s) {
|
||||
if (s->removed)
|
||||
continue;
|
||||
+ if (!conflict_setting_active(s))
|
||||
+ continue;
|
||||
t = get_attr_group_type(s);
|
||||
if (t == group_bridge && (!bridge || !bridge->specified))
|
||||
bridge = s;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user