SHA256
1
0
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:
Mark Post 2019-11-26 09:42:09 +00:00 committed by Git OBS Bridge
parent 0414295c92
commit 50eb270fbf
141 changed files with 10638 additions and 29446 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fd1883e12f9da16be6b081508108abd3ce8cd80168efe4cd339ba33837f8f4aa
size 1164539

View File

@ -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);
}

View File

@ -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.

View File

@ -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 |

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;
}
--

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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}")

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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";

View File

@ -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;
}

View File

@ -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).

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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>) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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++;

View File

@ -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(&reg_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(&reg_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);
}

View File

@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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',
};

View File

@ -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;

View File

@ -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;
+}

View File

@ -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);
}

View File

@ -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;

View File

@ -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',

View File

@ -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.

View File

@ -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");
}
/*

View File

@ -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;

View File

@ -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",

View File

@ -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>

View File

@ -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;
}

View File

@ -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';
+}

View File

@ -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
.

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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',
};

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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