c5faed242e
- KVM: Tool to process encrypted Secure Execution guest dumps (#2044198) - zdev: Site-aware device configuration (#2044202) - Support IBM z16 Processor-Activity-Instrumentation Facility (#2110298) - Transparent DASD PPRC (Peer-to-Peer Remote Copy) handling (#2126617) - Support IBM z16 Processor Activity Instrumentation Extension 1 (#2127435) - Resolves: #2110310 #2044198 #2044202 #2110298 #2126617 #2127435
1666 lines
53 KiB
Diff
1666 lines
53 KiB
Diff
From 5107a7be16e4849fbda7beae0504fdbc0f2cb4b5 Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Tue, 9 Aug 2022 13:12:26 +0200
|
|
Subject: [PATCH 1/7] zconf/lsdasd: fix Copy Pair related output
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Fix the default output for copy pair secondary devices to not show
|
|
a faulty blockdevice entry and major:minor combination.
|
|
|
|
The new output looks like:
|
|
|
|
# lsdasd
|
|
Bus-ID Status Name Device Type BlkSz Size Blocks
|
|
================================================================================
|
|
0.0.9740 secondary ECKD
|
|
0.0.9741 secondary ECKD
|
|
0.0.9742 secondary ECKD
|
|
0.0.e964 active dasda 94:0 ECKD 4096 21129MB 5409180
|
|
0.0.e967 active dasdb 94:4 ECKD 4096 21129MB 5409180
|
|
0.0.9330 active dasdc 94:8 ECKD 4096 782MB 200340
|
|
0.0.9700 active dasdd 94:12 ECKD 4096 782MB 200340
|
|
0.0.9701 active dasdf 94:20 ECKD 4096 782MB 200340
|
|
0.0.9702 active dasdh 94:28 ECKD 4096 782MB 200340
|
|
|
|
Also add copy_pairs to extended output:
|
|
|
|
# lsdasd -l 9700
|
|
0.0.9700/dasdd/94:12
|
|
status: active
|
|
type: ECKD
|
|
blksz: 4096
|
|
size: 782MB
|
|
blocks: 200340
|
|
extent_size: 1113
|
|
logical_capacity: 1113
|
|
space_allocated: 1113
|
|
use_diag: 0
|
|
readonly: 0
|
|
eer_enabled: 0
|
|
erplog: 0
|
|
hpf: 1
|
|
uid: IBM.750000000ABT31.9700.00
|
|
fc_security: Unsupported
|
|
paths_installed: 38 39 3a 3b
|
|
paths_in_use: 38 39 3a 3b
|
|
paths_non_preferred:
|
|
paths_invalid_cabling:
|
|
paths_cuir_quiesced:
|
|
paths_invalid_hpf_characteristics:
|
|
paths_error_threshold_exceeded:
|
|
copy_pairs: 0.0.9700,0.0.9740 0.0.9700,0.0.9743 0.0.9700,0.0.9744 0.0.9700,0.0.9745
|
|
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zconf/lsdasd | 113 +++++++++++++++++++++++++++++++++++++++++++--------
|
|
1 file changed, 96 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/zconf/lsdasd b/zconf/lsdasd
|
|
index 795b33b..8b2cc0f 100755
|
|
--- a/zconf/lsdasd
|
|
+++ b/zconf/lsdasd
|
|
@@ -146,6 +146,62 @@ function findDASDDebugfsDirectorie() {
|
|
fi
|
|
}
|
|
|
|
+#------------------------------------------------------------------------------
|
|
+# The blockpath can usually be found over the DEVPATH
|
|
+# In case of a swapped Copy Pair device the blockdev is likely associated
|
|
+# with one of the secondary devices
|
|
+# this function checks if the blockdev is associated with the primary device
|
|
+# and if not search for it in the secondary device list
|
|
+#------------------------------------------------------------------------------
|
|
+function setCorrectBlockPath() {
|
|
+ local DRIVERECKD="$SYSFSDIR/bus/ccw/drivers/dasd-eckd/"
|
|
+ local DRIVERFBA="$SYSFSDIR/bus/ccw/drivers/dasd-fba/"
|
|
+ local SEARCHDIRS=
|
|
+ local SEARCHLIST=
|
|
+
|
|
+ if [[ "$COPYROLE" == "none" ]] || [[ -d "$DEVPATH/block" ]]; then
|
|
+ BLOCKPATH="$DEVPATH"/block/dasd*
|
|
+ return
|
|
+ fi
|
|
+
|
|
+ if [[ -d "$DRIVERECKD" ]]; then
|
|
+ SEARCHDIRS="$DRIVERECKD"
|
|
+ fi
|
|
+ if [[ -d "$DRIVERFBA" ]]; then
|
|
+ SEARCHDIRS="$SEARCHDIRS $DRIVERFBA"
|
|
+ fi
|
|
+
|
|
+ SEARCHLIST=$(echo $SECONDARY_LIST | sed 's/,/ /g')
|
|
+ for SEARCHDEV in $SEARCHLIST
|
|
+ do
|
|
+ if [[ -n "$SEARCHDIRS" ]]; then
|
|
+ PRIM_DEVPATH=$(find $SEARCHDIRS -type l -name $SEARCHDEV \
|
|
+ -printf "%h/%l\n" 2> /dev/null)
|
|
+ if [[ -d "$PRIM_DEVPATH/block" ]]; then
|
|
+ break
|
|
+ fi
|
|
+ else
|
|
+ # The above paths may become invalid in the future, so we keep the
|
|
+ # following query as backup:
|
|
+ PRIM_DEVPATH=$(find "$SYSFSDIR/devices" -type l -name $SEARCHDEV \
|
|
+ "driver" -lname "*/dasd*" -printf "%h\n" \
|
|
+ 2> /dev/null)
|
|
+ fi
|
|
+ done
|
|
+
|
|
+ BLOCKPATH="$PRIM_DEVPATH"/block/dasd*
|
|
+}
|
|
+
|
|
+#------------------------------------------------------------------------------
|
|
+# gather Copy Pair related data
|
|
+#------------------------------------------------------------------------------
|
|
+function gatherCopyPairData() {
|
|
+ read COPYPAIR 2> /dev/null < $DEVPATH/copy_pair
|
|
+ PRIMARY_UID=`echo $COPYPAIR | cut -d " " -f1 | cut -d "," -f1`
|
|
+ COPYPAIR=`echo "$COPYPAIR" | sed 's/ /,/g' | sed 's/^,//' `
|
|
+ SECONDARY_LIST=`echo ${COPYPAIR//$PRIMARY_UID","/} `
|
|
+}
|
|
+
|
|
#------------------------------------------------------------------------------
|
|
# gather device data and call appropriate output function
|
|
#------------------------------------------------------------------------------
|
|
@@ -165,16 +221,18 @@ function gatherDeviceData() {
|
|
read READONLY 2> /dev/null < $DEVPATH/readonly || continue
|
|
read DISCIPLINE 2> /dev/null < $DEVPATH/discipline || continue
|
|
read ESE 2> /dev/null < $DEVPATH/ese
|
|
+ read COPYROLE 2> /dev/null < $DEVPATH/copy_role
|
|
|
|
+ if [[ "$COPYROLE" != "none" ]]; then
|
|
+ gatherCopyPairData
|
|
+ fi
|
|
# Block device specific information is only available for
|
|
# devices that are online and not a PAV alias
|
|
- if [[ ! "$ONLINE" == 0 ]] && [[ ! "$ALIAS" == 1 ]]; then
|
|
- #find device Path to the block device
|
|
- if [[ -d "$DEVPATH/block" ]]; then
|
|
- set - "$DEVPATH"/block/dasd*
|
|
- else
|
|
- set - "$DEVPATH"/block:dasd*
|
|
- fi
|
|
+ if [[ ! "$ONLINE" == 0 ]] && [[ ! "$ALIAS" == 1 ]] &&
|
|
+ [[ ! "$COPYROLE" == "secondary" ]]; then
|
|
+ #find device Path to the block device
|
|
+ setCorrectBlockPath
|
|
+ set - $BLOCKPATH
|
|
MAJMIN=
|
|
MAJOR=
|
|
MINOR=
|
|
@@ -194,10 +252,12 @@ function gatherDeviceData() {
|
|
fi
|
|
fi
|
|
else
|
|
- # BLOCKNAME for offline and alias devices will not be
|
|
- # printed, it's just a key for sorting
|
|
+ # BLOCKNAME for offline, alias and secondary devices
|
|
+ # will not be printed, it's just a key for sorting
|
|
if [[ "$ONLINE" == 0 ]]; then
|
|
BLOCKNAME=""
|
|
+ elif [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ BLOCKNAME="b"
|
|
else
|
|
BLOCKNAME="a"
|
|
fi
|
|
@@ -261,6 +321,15 @@ function newoutput()
|
|
return
|
|
fi
|
|
|
|
+ if [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ printf "%s:%s:%-8s secondary %-8s %13s\n" \
|
|
+ "$SORTKEYLEN" "$SORTKEY" \
|
|
+ "$BUSID" \
|
|
+ "$PRIMARY_BLOCKNAME" \
|
|
+ "$DISCIPLINE"
|
|
+ return
|
|
+ fi
|
|
+
|
|
if [[ "$READONLY" == 0 ]]; then
|
|
ROSTRING=""
|
|
else
|
|
@@ -519,10 +588,14 @@ function extended()
|
|
"${HPF_PATHS[@]}" \
|
|
"${IFCC_PATHS[@]}" ;
|
|
return
|
|
- elif [[ "$ALIAS" == 1 ]]; then
|
|
- if [[ "$BASEONLY" == "false" ]]; then
|
|
- ACTIVE="alias"
|
|
- printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
|
+ elif [[ "$ALIAS" == 1 ]] || [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ if [[ "$BASEONLY" == "false" ]] || [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ if [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ ACTIVE="secondary"
|
|
+ else
|
|
+ ACTIVE="alias"
|
|
+ fi
|
|
+ printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s# copy_pairs:\t\t\t\t%s#\n" \
|
|
"$SORTKEYLEN" "$SORTKEY" \
|
|
"$BUSID" \
|
|
"$ACTIVE" \
|
|
@@ -540,7 +613,8 @@ function extended()
|
|
"${CABLE_PATHS[@]}" \
|
|
"${CUIR_PATHS[@]}" \
|
|
"${HPF_PATHS[@]}" \
|
|
- "${IFCC_PATHS[@]}" ;
|
|
+ "${IFCC_PATHS[@]}" \
|
|
+ "${COPYPAIR}" ;
|
|
fi
|
|
return
|
|
elif [[ -z "$BLOCKNAME" ]] || [[ -z "$SIZE" ]]; then
|
|
@@ -565,7 +639,7 @@ function extended()
|
|
DISCIPLINE="${DISCIPLINE} (ESE)"
|
|
fi
|
|
|
|
- printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
|
+ printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s# copy_pairs:\t\t\t\t%s#\n" \
|
|
"$SORTKEYLEN" "$SORTKEY" \
|
|
"$BUSID" \
|
|
"$BLOCKNAME" \
|
|
@@ -593,7 +667,8 @@ function extended()
|
|
"${CABLE_PATHS[@]}" \
|
|
"${CUIR_PATHS[@]}" \
|
|
"${HPF_PATHS[@]}" \
|
|
- "${IFCC_PATHS[@]}" ;
|
|
+ "${IFCC_PATHS[@]}" \
|
|
+ "${COPYPAIR}" ;
|
|
}
|
|
|
|
function host()
|
|
@@ -710,7 +785,11 @@ function uid()
|
|
fi
|
|
fi
|
|
|
|
- printf "%s:%s:%-8s %-8s %s\n" \
|
|
+ if [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ BLOCKNAME="secondary"
|
|
+ fi
|
|
+
|
|
+ printf "%s:%s:%-8s %-10s %s\n" \
|
|
"$SORTKEYLEN" "$SORTKEY" \
|
|
"$BUSID" \
|
|
"$BLOCKNAME" \
|
|
--
|
|
2.38.1
|
|
|
|
|
|
From 803b87e324d704036c5bef1d1daba6cf5b69b668 Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Wed, 12 Oct 2022 15:55:43 +0200
|
|
Subject: [PATCH 2/7] zconf/lsdasd: add Copy Pair output option
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add an option -P|--copy-pairs to show all DASD devices with copy
|
|
relations set up in the system and their roles.
|
|
|
|
The output looks like:
|
|
|
|
# ./s390-tools/zconf/lsdasd -h
|
|
[...]
|
|
-P|--copy-pairs
|
|
Print information about copy pairs.
|
|
|
|
# ./s390-tools/zconf/lsdasd -P
|
|
Bus-ID Role Name Paired devices
|
|
================================================================================
|
|
0.0.9700 primary dasdd 0.0.9740,0.0.9743,0.0.9744,0.0.9745
|
|
0.0.9740 secondary 0.0.9700
|
|
0.0.9701 primary dasdf 0.0.9741
|
|
0.0.9741 secondary 0.0.9701
|
|
0.0.9702 primary dasdh 0.0.9742
|
|
0.0.9742 secondary 0.0.9702
|
|
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zconf/lsdasd | 45 +++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 45 insertions(+)
|
|
|
|
diff --git a/zconf/lsdasd b/zconf/lsdasd
|
|
index 8b2cc0f..59720b6 100755
|
|
--- a/zconf/lsdasd
|
|
+++ b/zconf/lsdasd
|
|
@@ -35,6 +35,8 @@ function PrintUsage() {
|
|
Print extended information about DASDs.
|
|
-H|--host-access-list
|
|
Print information about hosts accessing DASDs.
|
|
+ -P|--copy-pairs
|
|
+ Print information about copy pairs.
|
|
-v|--verbose
|
|
For compatibility/future use. Currently ignored.
|
|
--version
|
|
@@ -292,6 +294,8 @@ function gatherDeviceData() {
|
|
uid
|
|
elif [[ "$OUTPUT" == "host" ]]; then
|
|
host
|
|
+ elif [[ "$OUTPUT" == "copy" ]]; then
|
|
+ copy
|
|
else
|
|
newoutput
|
|
fi
|
|
@@ -769,6 +773,41 @@ printf "\n";
|
|
rm -f $temp
|
|
}
|
|
|
|
+# pad sortkey with given number zeroes
|
|
+function padSortKey()
|
|
+{
|
|
+ local LEN=$1
|
|
+ for (( i=0; i<$LEN; i++ ))
|
|
+ do
|
|
+ printf -v SORTKEY "%s0" $SORTKEY
|
|
+ done
|
|
+}
|
|
+
|
|
+function copy()
|
|
+{
|
|
+ if [[ "$COPYROLE" == "none" ]]; then
|
|
+ return
|
|
+ fi
|
|
+
|
|
+ SORTKEYLEN=$((${#PRIMARY_UID}+${#DEV_UID}))
|
|
+ if [[ "$COPYROLE" == "secondary" ]]; then
|
|
+ SORTKEY=$PRIMARY_UID$DEV_UID
|
|
+ PAIREDDEVICES=$PRIMARY_UID
|
|
+ BLOCKNAME=""
|
|
+ else
|
|
+ SORTKEY=$PRIMARY_UID
|
|
+ padSortKey ${#DEV_UID}
|
|
+ PAIREDDEVICES=$SECONDARY_LIST
|
|
+ fi
|
|
+
|
|
+ printf "%s:%s:%-8s %-10s %-8s %-8s %s \n" \
|
|
+ "$SORTKEYLEN" "$SORTKEY" \
|
|
+ "$BUSID" \
|
|
+ "$COPYROLE" \
|
|
+ "$BLOCKNAME" \
|
|
+ "$PAIREDDEVICES";
|
|
+}
|
|
+
|
|
function uid()
|
|
{
|
|
#-------------------------------------------#
|
|
@@ -835,6 +874,9 @@ while [ $# -gt 0 ]; do
|
|
--host-access-list|-H)
|
|
OUTPUT="host"
|
|
;;
|
|
+ --copy-pairs|-P)
|
|
+ OUTPUT="copy"
|
|
+ ;;
|
|
--version)
|
|
PrintVersion
|
|
exit 0
|
|
@@ -889,6 +931,9 @@ if [[ "$PRINTUID" == "true" ]] && [[ "$OUTPUT" != "old" ]]; then
|
|
elif [[ "$OUTPUT" == "new" ]]; then
|
|
printf "Bus-ID Status Name Device Type BlkSz Size Blocks\n"
|
|
printf "================================================================================\n"
|
|
+elif [[ "$OUTPUT" == "copy" ]]; then
|
|
+ printf "Bus-ID Role Name Paired devices\n";
|
|
+ printf "================================================================================\n";
|
|
elif [[ "$OUTPUT" == "extended" ]]; then
|
|
PROCESSING=" $PROCESSING | sed 's/#/\n/g' "
|
|
fi
|
|
--
|
|
2.38.1
|
|
|
|
|
|
From e742d1c9ae5103c9f88d3fde085e0694efaeeb5a Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Thu, 11 Aug 2022 13:52:30 +0200
|
|
Subject: [PATCH 3/7] zdev: correctly handle multiple values for CCW devices
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Correctly create multiple lines in the udev rule for CCW device attributes
|
|
with multi bit set that contain multiple values.
|
|
|
|
Suggested-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zdev/src/udev_ccw.c | 10 ++++++++--
|
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/zdev/src/udev_ccw.c b/zdev/src/udev_ccw.c
|
|
index 7c0a703..3375a5e 100644
|
|
--- a/zdev/src/udev_ccw.c
|
|
+++ b/zdev/src/udev_ccw.c
|
|
@@ -221,6 +221,7 @@ static void write_attr_to_file(FILE *fd, struct device_state *state, const char
|
|
struct ptrlist_node *p;
|
|
struct setting *s;
|
|
struct util_list *list = NULL;
|
|
+ struct strlist_node *str;
|
|
|
|
/* Apply attributes in correct order. */
|
|
list = setting_list_get_sorted(state->settings);
|
|
@@ -229,8 +230,13 @@ static void write_attr_to_file(FILE *fd, struct device_state *state, const char
|
|
s = p->ptr;
|
|
if (s->removed)
|
|
continue;
|
|
- if ((s->attrib && s->attrib->internal) ||
|
|
- internal_by_name(s->name)) {
|
|
+ if (s->values) {
|
|
+ util_list_iterate(s->values, str) {
|
|
+ fprintf(fd, "ATTR{[ccw/%s]%s}=\"%s\"\n",
|
|
+ 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 {
|
|
--
|
|
2.38.1
|
|
|
|
|
|
From f654b971d0e78a139c7ed8c0df821af2f4356a8b Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Tue, 9 Aug 2022 16:17:23 +0200
|
|
Subject: [PATCH 4/7] zdev: add copy_pair attribute for DASD devices
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The DASD device driver has a new attribute copy_pair to make storage
|
|
server copy pairs known to the driver.
|
|
Add this attribute to zdev.
|
|
|
|
Usage example:
|
|
|
|
Add two copy pairs 1000,2000 and 1000,3000 to a DASD device 1000
|
|
$ chzdev dasd 1000 copy_pairs=1000,2000 copy_pairs=1000,3000
|
|
|
|
or
|
|
|
|
$ chzdev dasd 1000 copy_pairs="1000,2000 1000,3000"
|
|
|
|
To add a third copy pair later on:
|
|
$ chzdev dasd 1000 copy_pairs=1000,4000
|
|
|
|
To remove all copy pairs from the device 1000:
|
|
$ chzdev dasd 1000 -r copy_pairs
|
|
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zdev/src/dasd.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 93 insertions(+)
|
|
|
|
diff --git a/zdev/src/dasd.c b/zdev/src/dasd.c
|
|
index daec916..f9fd231 100644
|
|
--- a/zdev/src/dasd.c
|
|
+++ b/zdev/src/dasd.c
|
|
@@ -137,6 +137,21 @@ static struct attrib dasd_attr_readonly = {
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
+static struct attrib dasd_attr_copy_pair = {
|
|
+ .name = "copy_pair",
|
|
+ .title = "Modify copy-pair relations",
|
|
+ .desc = "Make a copy-pair relation for this device known to the DASD "
|
|
+ "driver.\n"
|
|
+ "A copy-pair is a comma-separated pair of device bus-IDs\n"
|
|
+ "<primary>,<secondary>.\n"
|
|
+ "Example: 0.0.1000,0.0.2000\n"
|
|
+ "Up to 4 copy-pairs are accepted by the DASD driver for each "
|
|
+ "device.\n",
|
|
+ .unstable = 1,
|
|
+ .multi = 1,
|
|
+ .activerem = 1,
|
|
+};
|
|
+
|
|
static struct attrib dasd_attr_erplog = {
|
|
.name = "erplog",
|
|
.title = "Enable logging of Error Recovery Processing",
|
|
@@ -600,6 +615,81 @@ persistent:
|
|
return rc;
|
|
}
|
|
|
|
+/* Remove all entries from the copy_pair attribute by writing 'clear' to it. */
|
|
+static void dasd_clear_copy_pair(struct setting *s)
|
|
+{
|
|
+ free(s->value);
|
|
+ s->value = misc_strdup("clear");
|
|
+ strlist_free(s->values);
|
|
+ s->values = strlist_new();
|
|
+ strlist_add(s->values, "clear");
|
|
+ s->removed = 0;
|
|
+ s->modified = 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Copy-pair values may contain multiple values in one line
|
|
+ * those need to be split up and put in multiple values entries
|
|
+ * delimiter is " " and "\n" depending on the source
|
|
+ * values read from sysfs have " " as delimiter and values from
|
|
+ * zdev have "\n"
|
|
+ */
|
|
+static void dasd_split_copy_pair(struct setting *s)
|
|
+{
|
|
+ struct util_list *new = NULL;
|
|
+ struct strlist_node *node;
|
|
+
|
|
+ new = strlist_new();
|
|
+ util_list_iterate(s->values, node)
|
|
+ strlist_add_multi(new, node->str, "\n ", 0);
|
|
+
|
|
+ strlist_free(s->values);
|
|
+ s->values = new;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * For persistent configurations one value per values[] entry is required
|
|
+ * to achieve a correct multi-line copy-pair statement in the resulting
|
|
+ * udev-rule.
|
|
+ */
|
|
+static exit_code_t dasd_st_configure_persistent(struct subtype *st,
|
|
+ struct device *dev)
|
|
+{
|
|
+ struct setting *s;
|
|
+
|
|
+ util_list_iterate(&dev->persistent.settings->list, s) {
|
|
+ if (strcmp(s->name, "copy_pair") == 0)
|
|
+ dasd_split_copy_pair(s);
|
|
+ }
|
|
+
|
|
+ return st->super->configure_persistent(st, dev);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * For active configurations one value per values[] entry is required to
|
|
+ * correctly operate the sysfs attribute.
|
|
+ *
|
|
+ * In case of removal the string "clear" has to be written to the
|
|
+ * value and values[] entry.
|
|
+ */
|
|
+static exit_code_t dasd_st_configure_active(struct subtype *st,
|
|
+ struct device *dev)
|
|
+{
|
|
+ struct setting *s;
|
|
+
|
|
+ util_list_iterate(&dev->active.settings->list, s) {
|
|
+ if (strcmp(s->name, "copy_pair") != 0)
|
|
+ continue;
|
|
+
|
|
+ if (s->removed)
|
|
+ dasd_clear_copy_pair(s);
|
|
+ else
|
|
+ dasd_split_copy_pair(s);
|
|
+ }
|
|
+
|
|
+ return st->super->configure_active(st, dev);
|
|
+}
|
|
+
|
|
/*
|
|
* DASD device sub-types.
|
|
*/
|
|
@@ -634,10 +724,13 @@ struct subtype dasd_subtype_eckd = {
|
|
&dasd_attr_last_known_reservation_state,
|
|
&dasd_attr_safe_offline,
|
|
&dasd_attr_fc_security,
|
|
+ &dasd_attr_copy_pair,
|
|
&internal_attr_early,
|
|
),
|
|
.unknown_dev_attribs = 1,
|
|
|
|
+ .configure_active = &dasd_st_configure_active,
|
|
+ .configure_persistent = &dasd_st_configure_persistent,
|
|
.check_pre_configure = &dasd_st_check_pre_configure,
|
|
.add_modules = &dasd_st_add_modules,
|
|
};
|
|
--
|
|
2.38.1
|
|
|
|
|
|
From 4e28047eb4cacc7b7208018a8c095102517517e8 Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Thu, 10 Nov 2022 16:11:09 +0100
|
|
Subject: [PATCH 5/7] tunedasd: move tunedasd ioctls to libdasd
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Move all DASD IOCTLs to libdasd and adapt all affected
|
|
users accordingly.
|
|
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
include/lib/dasd_base.h | 73 +++++++++++
|
|
libdasd/dasd_ioctl.c | 129 +++++++++++++++++++
|
|
tunedasd/src/disk.c | 268 ++++++++--------------------------------
|
|
3 files changed, 252 insertions(+), 218 deletions(-)
|
|
|
|
diff --git a/include/lib/dasd_base.h b/include/lib/dasd_base.h
|
|
index b12e1f9..11ec94b 100644
|
|
--- a/include/lib/dasd_base.h
|
|
+++ b/include/lib/dasd_base.h
|
|
@@ -187,6 +187,61 @@ typedef struct format_check_t {
|
|
#define DASD_FMT_ERR_RECORD_ID 4
|
|
#define DASD_FMT_ERR_KEY_LENGTH 5
|
|
|
|
+/*
|
|
+ * struct profile_info_t
|
|
+ * holds the profiling information
|
|
+ */
|
|
+typedef struct dasd_profile_info_t {
|
|
+ unsigned int dasd_io_reqs; /* # of requests processed at all */
|
|
+ unsigned int dasd_io_sects; /* # of sectors processed at all */
|
|
+ unsigned int dasd_io_secs[32]; /* request's sizes */
|
|
+ unsigned int dasd_io_times[32]; /* requests's times */
|
|
+ unsigned int dasd_io_timps[32]; /* requests's times per sector */
|
|
+ unsigned int dasd_io_time1[32]; /* time from build to start */
|
|
+ unsigned int dasd_io_time2[32]; /* time from start to irq */
|
|
+ unsigned int dasd_io_time2ps[32]; /* time from start to irq */
|
|
+ unsigned int dasd_io_time3[32]; /* time from irq to end */
|
|
+ unsigned int dasd_io_nr_req[32]; /* # of requests in chanq */
|
|
+} dasd_profile_info_t;
|
|
+
|
|
+/*
|
|
+ * struct attrib_data_t
|
|
+ * represents the operation (cache) bits for the device.
|
|
+ * Used in DE to influence caching of the DASD.
|
|
+ */
|
|
+typedef struct attrib_data_t {
|
|
+ unsigned char operation : 3; /* cache operation mode */
|
|
+ unsigned char reserved : 5;
|
|
+ unsigned short nr_cyl; /* no of cyliners for read ahaed */
|
|
+ unsigned char reserved2[29]; /* for future use */
|
|
+} __attribute__((packed)) attrib_data_t;
|
|
+
|
|
+/* definition of operation (cache) bits within attributes of DE */
|
|
+#define DASD_NORMAL_CACHE 0x0
|
|
+#define DASD_BYPASS_CACHE 0x1
|
|
+#define DASD_INHIBIT_LOAD 0x2
|
|
+#define DASD_SEQ_ACCESS 0x3
|
|
+#define DASD_SEQ_PRESTAGE 0x4
|
|
+#define DASD_REC_ACCESS 0x5
|
|
+
|
|
+/*
|
|
+ * Data returned by Sense Path Group ID (SNID)
|
|
+ */
|
|
+struct dasd_snid_data {
|
|
+ struct {
|
|
+ __u8 group : 2;
|
|
+ __u8 reserve : 2;
|
|
+ __u8 mode : 1;
|
|
+ __u8 res : 3;
|
|
+ } __attribute__((packed)) path_state;
|
|
+ __u8 pgid[11];
|
|
+} __attribute__((packed));
|
|
+
|
|
+struct dasd_snid_ioctl_data {
|
|
+ struct dasd_snid_data data;
|
|
+ __u8 path_mask;
|
|
+} __attribute__((packed));
|
|
+
|
|
#ifndef __linux__
|
|
/* definition from hdreg.h */
|
|
struct hd_geometry {
|
|
@@ -207,12 +262,24 @@ struct hd_geometry {
|
|
#define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2)
|
|
/* Release the device for the current LPAR */
|
|
#define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3)
|
|
+/* Unconditional reserve the device for the current LPAR */
|
|
+#define BIODASDSLCK _IO(DASD_IOCTL_LETTER, 4)
|
|
+/* reset profiling information of a device */
|
|
+#define BIODASDPRRST _IO(DASD_IOCTL_LETTER, 5)
|
|
+/* retrieve profiling information of a device */
|
|
+#define BIODASDPRRD _IOR(DASD_IOCTL_LETTER, 2, dasd_profile_info_t)
|
|
/* Get information on a dasd device (enhanced) */
|
|
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
|
+/* Get Attributes (cache operations) */
|
|
+#define BIODASDGATTR _IOR(DASD_IOCTL_LETTER, 5, attrib_data_t)
|
|
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
|
#define BIODASDFMT _IOW(DASD_IOCTL_LETTER, 1, format_data_t)
|
|
+/* Set Attributes (cache operations) */
|
|
+#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER, 2, attrib_data_t)
|
|
/* Release Allocated Space */
|
|
#define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t)
|
|
+/* Get Sense Path Group ID (SNID) data */
|
|
+#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
|
|
/* Check device format according to format_data_t */
|
|
#define BIODASDCHECKFMT _IOWR(DASD_IOCTL_LETTER, 2, format_check_t)
|
|
|
|
@@ -245,5 +312,11 @@ int dasd_is_ro(const char *device, bool *ro);
|
|
int dasd_reread_partition_table(const char *device, int ntries);
|
|
int dasd_disk_reserve(const char *device);
|
|
int dasd_disk_release(const char *device);
|
|
+int dasd_slock(const char *device);
|
|
+int dasd_get_cache(const char *device, attrib_data_t *attrib_data);
|
|
+int dasd_set_cache(const char *device, attrib_data_t *attrib_data);
|
|
+int dasd_query_reserve(const char *device);
|
|
+int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info);
|
|
+int dasd_reset_profile(const char *device);
|
|
|
|
#endif /* LIB_DASD_BASE_H */
|
|
diff --git a/libdasd/dasd_ioctl.c b/libdasd/dasd_ioctl.c
|
|
index f954961..40e726c 100644
|
|
--- a/libdasd/dasd_ioctl.c
|
|
+++ b/libdasd/dasd_ioctl.c
|
|
@@ -16,6 +16,7 @@
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
+#include <string.h>
|
|
|
|
#include "lib/dasd_base.h"
|
|
|
|
@@ -321,3 +322,131 @@ int dasd_disk_release(const char *device)
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+/*
|
|
+ * Unconditionally reserve DASD disk
|
|
+ *
|
|
+ * An existing reserve lock is lifted (steal lock) and the device
|
|
+ * is reserved.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ *
|
|
+ * @retval 0 in case of success
|
|
+ * @retval errno in case of failure
|
|
+ */
|
|
+int dasd_slock(const char *device)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDSLCK, NULL);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Get the caching algorithm used for the channel programs of this device.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ * @param[out] attrib_data pointer to dasd attrib data with:
|
|
+ * 'cache' is the caching mode
|
|
+ * 'no_cyl' the number of cylinders to be cached.
|
|
+ *
|
|
+ * @retval 0 in case of success
|
|
+ * @retval errno in case of failure
|
|
+ */
|
|
+int dasd_get_cache(const char *device, attrib_data_t *attrib_data)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDGATTR, attrib_data);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Set the caching algorithm used for the channel programs of this device.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ * @param[in] attrib_data pointer to dasd attrib data with:
|
|
+ * 'cache' is the caching mode
|
|
+ * 'no_cyl' the number of cylinders to be cached.
|
|
+ *
|
|
+ * @retval 0 in case of success
|
|
+ * @retval errno in case of failure
|
|
+ */
|
|
+int dasd_set_cache(const char *device, attrib_data_t *attrib_data)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDSATTR, attrib_data);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Get reserve status of device.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ *
|
|
+ * @retval errno in case of failure
|
|
+ * @retval 0 unreserved
|
|
+ * @retval 1 implicit reserved
|
|
+ * @retval 2 other reservation
|
|
+ * @retval 3 reserved
|
|
+ */
|
|
+int dasd_query_reserve(const char *device)
|
|
+{
|
|
+ struct dasd_snid_ioctl_data snid = { 0 };
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDSNID, &snid);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return snid.data.path_state.reserve;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Get and print the profiling info of the device.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ * @param[in] dasd_profile_info pointer to dasd profile info
|
|
+ *
|
|
+ * @retval 0 in case of success
|
|
+ * @retval errno in case of failure
|
|
+ */
|
|
+int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDPRRD, dasd_profile_info);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Reset the profiling counters of the device.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ *
|
|
+ * @retval 0 in case of success
|
|
+ * @retval errno in case of failure
|
|
+ */
|
|
+int dasd_reset_profile(const char *device)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDPRRST, NULL);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/tunedasd/src/disk.c b/tunedasd/src/disk.c
|
|
index f240651..1e8de16 100644
|
|
--- a/tunedasd/src/disk.c
|
|
+++ b/tunedasd/src/disk.c
|
|
@@ -19,6 +19,7 @@
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
+#include "lib/dasd_base.h"
|
|
#include "lib/dasd_sys.h"
|
|
|
|
#include "disk.h"
|
|
@@ -26,91 +27,6 @@
|
|
|
|
#define BUS_ID_SIZE 30
|
|
|
|
-/*
|
|
- * DASD DEFINITIONS (copied from dasd.h)
|
|
- */
|
|
-
|
|
-#define DASD_IOCTL_LETTER 'D'
|
|
-
|
|
-/*
|
|
- * struct profile_info_t
|
|
- * holds the profiling information
|
|
- */
|
|
-typedef struct dasd_profile_info_t {
|
|
- unsigned int dasd_io_reqs; /* # of requests processed at all */
|
|
- unsigned int dasd_io_sects; /* # of sectors processed at all */
|
|
- unsigned int dasd_io_secs[32]; /* request's sizes */
|
|
- unsigned int dasd_io_times[32]; /* requests's times */
|
|
- unsigned int dasd_io_timps[32]; /* requests's times per sector */
|
|
- unsigned int dasd_io_time1[32]; /* time from build to start */
|
|
- unsigned int dasd_io_time2[32]; /* time from start to irq */
|
|
- unsigned int dasd_io_time2ps[32]; /*time from start to irq */
|
|
- unsigned int dasd_io_time3[32]; /* time from irq to end */
|
|
- unsigned int dasd_io_nr_req[32]; /* # of requests in chanq */
|
|
-} dasd_profile_info_t;
|
|
-
|
|
-
|
|
-/*
|
|
- * struct attrib_data_t
|
|
- * represents the operation (cache) bits for the device.
|
|
- * Used in DE to influence caching of the DASD.
|
|
- */
|
|
-typedef struct attrib_data_t {
|
|
- unsigned char operation:3; /* cache operation mode */
|
|
- unsigned char reserved:5;
|
|
- unsigned short nr_cyl; /* no of cyliners for read ahaed */
|
|
- unsigned char reserved2[29]; /* for future use */
|
|
-} __attribute__ ((packed)) attrib_data_t;
|
|
-
|
|
-/* definition of operation (cache) bits within attributes of DE */
|
|
-#define DASD_NORMAL_CACHE 0x0
|
|
-#define DASD_BYPASS_CACHE 0x1
|
|
-#define DASD_INHIBIT_LOAD 0x2
|
|
-#define DASD_SEQ_ACCESS 0x3
|
|
-#define DASD_SEQ_PRESTAGE 0x4
|
|
-#define DASD_REC_ACCESS 0x5
|
|
-
|
|
-/*
|
|
- * Data returned by Sense Path Group ID (SNID)
|
|
- */
|
|
-struct dasd_snid_data {
|
|
- struct {
|
|
- __u8 group:2;
|
|
- __u8 reserve:2;
|
|
- __u8 mode:1;
|
|
- __u8 res:3;
|
|
- } __attribute__ ((packed)) path_state;
|
|
- __u8 pgid[11];
|
|
-} __attribute__ ((packed));
|
|
-
|
|
-struct dasd_snid_ioctl_data {
|
|
- struct dasd_snid_data data;
|
|
- __u8 path_mask;
|
|
-} __attribute__ ((packed));
|
|
-
|
|
-
|
|
-/*
|
|
- * DASD-IOCTLs (copied from dasd.h)
|
|
- */
|
|
-/* Issue a reserve/release command, rsp. */
|
|
-#define BIODASDRSRV _IO (DASD_IOCTL_LETTER,2) /* reserve */
|
|
-#define BIODASDRLSE _IO (DASD_IOCTL_LETTER,3) /* release */
|
|
-#define BIODASDSLCK _IO (DASD_IOCTL_LETTER,4) /* steal lock */
|
|
-/* reset profiling information of a device */
|
|
-#define BIODASDPRRST _IO (DASD_IOCTL_LETTER,5)
|
|
-
|
|
-/* retrieve profiling information of a device */
|
|
-#define BIODASDPRRD _IOR (DASD_IOCTL_LETTER,2,dasd_profile_info_t)
|
|
-/* Get Attributes (cache operations) */
|
|
-#define BIODASDGATTR _IOR(DASD_IOCTL_LETTER,5,attrib_data_t)
|
|
-
|
|
-/* Set Attributes (cache operations) */
|
|
-#define BIODASDSATTR _IOW (DASD_IOCTL_LETTER,2,attrib_data_t)
|
|
-
|
|
-/* Get Sense Path Group ID (SNID) data */
|
|
-#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
|
|
-
|
|
-
|
|
/* id definition for profile items */
|
|
enum prof_id {
|
|
prof_reqs = 0,
|
|
@@ -241,48 +157,33 @@ check_prof_item (char* prof_item)
|
|
* 'cache' is the caching mode (see ESS docu for more info) and 'no_cyl'
|
|
* the number of cylinders to be cached.
|
|
*/
|
|
-int
|
|
-disk_get_cache (char* device)
|
|
+int disk_get_cache(char *device)
|
|
{
|
|
- int fd;
|
|
attrib_data_t attrib_data;
|
|
-
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
+ int rc;
|
|
|
|
- /* Get the given caching attributes */
|
|
- if (ioctl (fd, BIODASDGATTR, &attrib_data)) {
|
|
- error_print ("Could not get cache attributes for device <%s>",
|
|
- device);
|
|
- close (fd);
|
|
- return -1;
|
|
- }
|
|
+ rc = dasd_get_cache(device, &attrib_data);
|
|
+ if (rc)
|
|
+ return rc;
|
|
|
|
printf ("%s (%i cyl)\n",
|
|
get_cache_name(attrib_data.operation),
|
|
attrib_data.nr_cyl);
|
|
|
|
- close (fd);
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
/*
|
|
* Set the caching algorithm used for the channel programs of this device.
|
|
* 'cache' is the caching mode (see ESS docu for more info) and 'no_cyl'
|
|
* the number of cylinders to be cached.
|
|
*/
|
|
-int
|
|
-disk_set_cache (char* device, char* cache, char* no_cyl)
|
|
+int disk_set_cache(char *device, char *cache, char *no_cyl)
|
|
{
|
|
- int fd;
|
|
attrib_data_t attrib_data;
|
|
-
|
|
- /* get caching mode and # cylinders */
|
|
+ int rc;
|
|
+
|
|
+ /* get caching mode and # cylinders */
|
|
attrib_data.operation = check_cache (cache);
|
|
attrib_data.nr_cyl = check_no_cyl (no_cyl);
|
|
|
|
@@ -292,52 +193,34 @@ disk_set_cache (char* device, char* cache, char* no_cyl)
|
|
attrib_data.nr_cyl);
|
|
}
|
|
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
-
|
|
/* Set the given caching attributes */
|
|
printf ("Setting cache mode for device <%s>...\n", device);
|
|
- if (ioctl (fd, BIODASDSATTR, &attrib_data)) {
|
|
- error_print ("Could not set caching for device <%s>", device);
|
|
- close (fd);
|
|
+ rc = dasd_set_cache(device, &attrib_data);
|
|
+ if (rc) {
|
|
+ error_print("Could not set caching for device <%s>", device);
|
|
return -1;
|
|
}
|
|
-
|
|
printf ("Done.\n");
|
|
- close (fd);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
/*
|
|
* Reserve the device.
|
|
*/
|
|
-int
|
|
-disk_reserve (char* device)
|
|
+int disk_reserve(char *device)
|
|
{
|
|
- int fd;
|
|
-
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
+ int rc;
|
|
|
|
/* Reserve device */
|
|
printf ("Reserving device <%s>...\n", device);
|
|
- if (ioctl (fd, BIODASDRSRV)) {
|
|
- error_print ("Could not reserve device <%s>", device);
|
|
- close (fd);
|
|
+ rc = dasd_disk_reserve(device);
|
|
+ if (rc) {
|
|
+ error_print("Could not reserve device <%s>", device);
|
|
return -1;
|
|
}
|
|
|
|
- printf ("Done.\n");
|
|
- close (fd);
|
|
+ printf("Done.\n");
|
|
return 0;
|
|
}
|
|
|
|
@@ -345,28 +228,18 @@ disk_reserve (char* device)
|
|
/*
|
|
* Release the device.
|
|
*/
|
|
-int
|
|
-disk_release (char* device)
|
|
+int disk_release(char *device)
|
|
{
|
|
- int fd;
|
|
-
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
+ int rc;
|
|
|
|
- /* Release device */
|
|
printf ("Releasing device <%s>...\n", device);
|
|
- if (ioctl (fd, BIODASDRLSE)) {
|
|
- error_print ("Could not release device <%s>", device);
|
|
- close (fd);
|
|
+ rc = dasd_disk_release(device);
|
|
+ if (rc) {
|
|
+ error_print("Could not release device <%s>", device);
|
|
return -1;
|
|
}
|
|
|
|
- printf ("Done.\n");
|
|
- close (fd);
|
|
+ printf("Done.\n");
|
|
return 0;
|
|
}
|
|
|
|
@@ -376,29 +249,19 @@ disk_release (char* device)
|
|
* This means to reserve the device even if it was already reserved.
|
|
* The current reserve is broken (steal lock).
|
|
*/
|
|
-int
|
|
-disk_slock (char* device)
|
|
+int disk_slock(char *device)
|
|
{
|
|
- int fd;
|
|
-
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
+ int rc;
|
|
|
|
/* Unconditional reserve device */
|
|
printf ("Unconditional reserving device <%s>...\n", device);
|
|
- if (ioctl (fd, BIODASDSLCK)) {
|
|
- error_print ("Could not unconditional reserve device <%s>",
|
|
- device);
|
|
- close (fd);
|
|
+ rc = dasd_slock(device);
|
|
+ if (rc) {
|
|
+ error_print("Could not unconditional reserve device <%s>", device);
|
|
return -1;
|
|
}
|
|
-
|
|
printf ("Done.\n");
|
|
- close (fd);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -407,27 +270,16 @@ disk_slock (char* device)
|
|
* Uses the Sense Path Group ID (SNID) ioctl to find out if
|
|
* a device is reserved to it's path group.
|
|
*/
|
|
-int
|
|
-disk_query_reserve_status(char* device)
|
|
+int disk_query_reserve_status(char *device)
|
|
{
|
|
- int fd;
|
|
- struct dasd_snid_ioctl_data snid;
|
|
+ int rc;
|
|
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
+ rc = dasd_query_reserve(device);
|
|
+ if (rc < 0) {
|
|
+ error_print("Could not read reserve status for device <%s>", device);
|
|
return -1;
|
|
}
|
|
- snid.path_mask = 0;
|
|
- /* Release device */
|
|
- if (ioctl(fd, BIODASDSNID, &snid)) {
|
|
- error_print("Could not read reserve status"
|
|
- " for device <%s>", device);
|
|
- close (fd);
|
|
- return -1;
|
|
- }
|
|
- switch (snid.data.path_state.reserve) {
|
|
+ switch (rc) {
|
|
case 0:
|
|
printf("none\n");
|
|
break;
|
|
@@ -441,7 +293,7 @@ disk_query_reserve_status(char* device)
|
|
printf("reserved\n");
|
|
break;
|
|
}
|
|
- close (fd);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -615,21 +467,14 @@ static int disk_profile_item(dasd_profile_info_t dasd_profile_info,
|
|
/*
|
|
* Get and print the profiling info of the device.
|
|
*/
|
|
-int
|
|
-disk_profile (char* device, char* prof_item)
|
|
+int disk_profile(char *device, char *prof_item)
|
|
{
|
|
- int fd, rc;
|
|
dasd_profile_info_t dasd_profile_info;
|
|
-
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
+ int rc;
|
|
|
|
/* Get the profile info */
|
|
- if (ioctl (fd, BIODASDPRRD, &dasd_profile_info)) {
|
|
+ rc = dasd_profile(device, &dasd_profile_info);
|
|
+ if (rc) {
|
|
switch (errno) {
|
|
case EIO: /* profiling is not active */
|
|
error_print ("Profiling (on device <%s>) is not "
|
|
@@ -639,7 +484,6 @@ disk_profile (char* device, char* prof_item)
|
|
error_print ("Could not get profile info for device "
|
|
"<%s>.", device);
|
|
}
|
|
- close (fd);
|
|
return -1;
|
|
}
|
|
/* Check for profile item or summary */
|
|
@@ -648,38 +492,26 @@ disk_profile (char* device, char* prof_item)
|
|
} else {
|
|
rc = disk_profile_item (dasd_profile_info, prof_item);
|
|
}
|
|
-
|
|
- close (fd);
|
|
+
|
|
return rc;
|
|
}
|
|
|
|
-
|
|
/*
|
|
* Reset the profiling counters of the device.
|
|
*/
|
|
-int
|
|
-disk_reset_prof (char* device)
|
|
+int disk_reset_prof(char *device)
|
|
{
|
|
- int fd;
|
|
-
|
|
- /* Open device file */
|
|
- fd = open (device, O_RDONLY);
|
|
- if (fd == -1) {
|
|
- error_print ("<%s> - %s", device, strerror (errno));
|
|
- return -1;
|
|
- }
|
|
+ int rc;
|
|
|
|
/* reset profile info */
|
|
printf ("Resetting profile info for device <%s>...\n", device);
|
|
- if (ioctl (fd, BIODASDPRRST)) {
|
|
- error_print ("Could not reset profile info for device <%s>",
|
|
- device);
|
|
- close (fd);
|
|
+ rc = dasd_reset_profile(device);
|
|
+ if (rc) {
|
|
+ error_print("Could not reset profile info for device <%s>", device);
|
|
return -1;
|
|
}
|
|
-
|
|
printf ("Done.\n");
|
|
- close (fd);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--
|
|
2.38.1
|
|
|
|
|
|
From 3aa7f6e29871c06537ab95bf2a14b5eb3ca6e847 Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Thu, 27 Oct 2022 15:51:00 +0200
|
|
Subject: [PATCH 6/7] libdasd: fix ioctl macro to return also positive return
|
|
codes
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
In case of an error the ioctl macro only returns errno to the calling
|
|
function.
|
|
This misses positive returncodes from ioctls.
|
|
Change the macro to also return positive return codes.
|
|
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
libdasd/dasd_ioctl.c | 10 ++++++----
|
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/libdasd/dasd_ioctl.c b/libdasd/dasd_ioctl.c
|
|
index 40e726c..3a36375 100644
|
|
--- a/libdasd/dasd_ioctl.c
|
|
+++ b/libdasd/dasd_ioctl.c
|
|
@@ -28,11 +28,13 @@
|
|
|
|
#define RUN_IOCTL(fd, req, argp) \
|
|
do { \
|
|
- if (ioctl(fd, req, argp) != 0) { \
|
|
- int err = errno; \
|
|
- if (err != EBADF) \
|
|
+ int rc = ioctl(fd, req, argp); \
|
|
+ if (rc != 0) { \
|
|
+ if (rc == -1) \
|
|
+ rc = errno; \
|
|
+ if (rc != EBADF) \
|
|
dasd_close_device(fd); \
|
|
- return err; \
|
|
+ return rc; \
|
|
} \
|
|
} while (0)
|
|
|
|
--
|
|
2.38.1
|
|
|
|
|
|
From 3f12bdf4c728caeaeaa64158efb26f917d905b08 Mon Sep 17 00:00:00 2001
|
|
From: Stefan Haberland <sth@linux.ibm.com>
|
|
Date: Fri, 11 Nov 2022 13:17:32 +0100
|
|
Subject: [PATCH 7/7] tunedasd: add copy_pair swap capability
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add an option to tunedasd to trigger a copy pair swap using the appropriate
|
|
ioctl for DASD devices.
|
|
|
|
-s, --copy-pair-swap COPY_PAIR
|
|
|
|
This command requires a comma separated pair of primary,secondary to be
|
|
specified. In case of success the old secondary will become the new primary
|
|
device and the old primary will become a secondary device.
|
|
|
|
Example:
|
|
|
|
tunedasd /dev/dasda -s 0.0.9700,0.0.9740
|
|
|
|
This will set the old secondary device 0.0.9740 as the new primary.
|
|
The old primary device 0.0.9700 will automatically become a secondary
|
|
device.
|
|
|
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
include/lib/dasd_base.h | 14 ++++++++--
|
|
libdasd/dasd_ioctl.c | 28 ++++++++++++++++++++
|
|
tunedasd/include/disk.h | 1 +
|
|
tunedasd/man/tunedasd.8 | 14 ++++++++++
|
|
tunedasd/src/disk.c | 50 ++++++++++++++++++++++++++++++++++--
|
|
tunedasd/src/tunedasd.c | 57 +++++++++++++++++++++++++----------------
|
|
6 files changed, 138 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/include/lib/dasd_base.h b/include/lib/dasd_base.h
|
|
index 11ec94b..400e374 100644
|
|
--- a/include/lib/dasd_base.h
|
|
+++ b/include/lib/dasd_base.h
|
|
@@ -20,8 +20,8 @@
|
|
#include <stdio.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
-/* A bus id of a DASD is 8 characters long. E.g. 0.0.4711 */
|
|
-#define DASD_BUS_ID_SIZE 9
|
|
+/* the definition of a BUSID in the DASD driver is 20 */
|
|
+#define DASD_BUS_ID_SIZE 20
|
|
|
|
typedef struct dasd_information2_t {
|
|
unsigned int devno; /* S/390 devno */
|
|
@@ -242,6 +242,13 @@ struct dasd_snid_ioctl_data {
|
|
__u8 path_mask;
|
|
} __attribute__((packed));
|
|
|
|
+struct dasd_copypair_swap_data {
|
|
+ char primary[DASD_BUS_ID_SIZE]; /* BUSID of primary */
|
|
+ char secondary[DASD_BUS_ID_SIZE]; /* BUSID of secondary */
|
|
+ /* Reserved for future updates. */
|
|
+ char reserved[64];
|
|
+};
|
|
+
|
|
#ifndef __linux__
|
|
/* definition from hdreg.h */
|
|
struct hd_geometry {
|
|
@@ -278,6 +285,8 @@ struct hd_geometry {
|
|
#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER, 2, attrib_data_t)
|
|
/* Release Allocated Space */
|
|
#define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t)
|
|
+/* Swap copy pair */
|
|
+#define BIODASDPPRCSWAP _IOW(DASD_IOCTL_LETTER, 4, struct dasd_copypair_swap_data)
|
|
/* Get Sense Path Group ID (SNID) data */
|
|
#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
|
|
/* Check device format according to format_data_t */
|
|
@@ -318,5 +327,6 @@ int dasd_set_cache(const char *device, attrib_data_t *attrib_data);
|
|
int dasd_query_reserve(const char *device);
|
|
int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info);
|
|
int dasd_reset_profile(const char *device);
|
|
+int dasd_copy_swap(const char *device, struct dasd_copypair_swap_data *data);
|
|
|
|
#endif /* LIB_DASD_BASE_H */
|
|
diff --git a/libdasd/dasd_ioctl.c b/libdasd/dasd_ioctl.c
|
|
index 3a36375..f684761 100644
|
|
--- a/libdasd/dasd_ioctl.c
|
|
+++ b/libdasd/dasd_ioctl.c
|
|
@@ -452,3 +452,31 @@ int dasd_reset_profile(const char *device)
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+/*
|
|
+ * Initiate the swap of a copy pairs primary,secondary relation.
|
|
+ * The old secondary will become the new primary and vice versa.
|
|
+ *
|
|
+ * @param[in] device node device node's name
|
|
+ * @param[in] copy_pair data pointer to dasd copypair data with:
|
|
+ * 'primary' old primary, becoming secondary
|
|
+ * 'secondary' old secondary, becoming primary.
|
|
+ *
|
|
+ * @retval errno in case of failure
|
|
+ * @retval 0 in case of success
|
|
+ * @retval 1 swap data invalid
|
|
+ * @retval 2 no active device found
|
|
+ * @retval 3 wrong primary specified
|
|
+ * @retval 4 secondary device not found
|
|
+ * @retval 5 swap already running
|
|
+ */
|
|
+int dasd_copy_swap(const char *device, struct dasd_copypair_swap_data *data)
|
|
+{
|
|
+ int fd;
|
|
+
|
|
+ fd = dasd_open_device(device, O_RDONLY);
|
|
+ RUN_IOCTL(fd, BIODASDPPRCSWAP, data);
|
|
+ dasd_close_device(fd);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/tunedasd/include/disk.h b/tunedasd/include/disk.h
|
|
index ea35f6f..55a32d0 100644
|
|
--- a/tunedasd/include/disk.h
|
|
+++ b/tunedasd/include/disk.h
|
|
@@ -31,6 +31,7 @@ int disk_query_reserve_status(char* device);
|
|
int disk_profile (char* device, char* prof_item);
|
|
int disk_reset_prof(char *device);
|
|
int disk_reset_chpid(char *device, char *chpid);
|
|
+int disk_copy_swap(char *device, char *copy_pair);
|
|
|
|
#endif /* not DISK_H */
|
|
|
|
diff --git a/tunedasd/man/tunedasd.8 b/tunedasd/man/tunedasd.8
|
|
index 94c3608..ae41b97 100644
|
|
--- a/tunedasd/man/tunedasd.8
|
|
+++ b/tunedasd/man/tunedasd.8
|
|
@@ -174,6 +174,14 @@ Reset all channel paths of the selected device. The channel paths
|
|
might be suspended due to high IFCC error rates or a High Performance
|
|
FICON failure. Use this option to resume considering all defined
|
|
channel paths for I/O.
|
|
+.TP
|
|
+.BR "\-s" " or " "\-\-copy\-pair\-swap <copy_pair>"
|
|
+Swap the copy roles of the specified copy pair. The <copy_pair> has to
|
|
+be a comma separated pair of \fBPRIMARY,SECONDARY\fR where
|
|
+\fBPRIMARY\fR is the old primary device that will become a secondary
|
|
+automatically. The old \fBSECONDARY\fR device will become the new
|
|
+primary device. Both devices have to be online for this operation to
|
|
+succeed.
|
|
.\"
|
|
.\".TP
|
|
.\".BR "\-o" " or " "\-\-online"
|
|
@@ -197,6 +205,12 @@ channel paths for I/O.
|
|
.br
|
|
|
|
tunedasd -p 45 /dev/dasdc
|
|
+
|
|
+.br
|
|
+4. Scenario: Swap copy pair 0.0.9700 and 0.0.9740
|
|
+.br
|
|
+
|
|
+ tunedasd -s 0.0.9700,0.0.9740 /dev/dasdc
|
|
.br
|
|
.SH "SEE ALSO"
|
|
.BR dasdview (8),
|
|
diff --git a/tunedasd/src/disk.c b/tunedasd/src/disk.c
|
|
index 1e8de16..490c1c5 100644
|
|
--- a/tunedasd/src/disk.c
|
|
+++ b/tunedasd/src/disk.c
|
|
@@ -21,12 +21,11 @@
|
|
|
|
#include "lib/dasd_base.h"
|
|
#include "lib/dasd_sys.h"
|
|
+#include "lib/util_libc.h"
|
|
|
|
#include "disk.h"
|
|
#include "tunedasd.h"
|
|
|
|
-#define BUS_ID_SIZE 30
|
|
-
|
|
/* id definition for profile items */
|
|
enum prof_id {
|
|
prof_reqs = 0,
|
|
@@ -549,3 +548,50 @@ int disk_reset_chpid(char *device, char *chpid)
|
|
|
|
return -1;
|
|
}
|
|
+
|
|
+int disk_copy_swap(char *device, char *copy_pair)
|
|
+{
|
|
+ struct dasd_copypair_swap_data data = { 0 };
|
|
+ char *primary, *secondary;
|
|
+ int rc = 0;
|
|
+
|
|
+ primary = strtok(copy_pair, ",");
|
|
+ secondary = strtok(NULL, ",");
|
|
+
|
|
+ if (!primary || !secondary) {
|
|
+ error_print("%s: Error parsing Copy Pair %s", device, copy_pair);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ util_strlcpy(data.primary, primary, DASD_BUS_ID_SIZE);
|
|
+ util_strlcpy(data.secondary, secondary, DASD_BUS_ID_SIZE);
|
|
+
|
|
+ printf("Swapping copy pair %s %s on device <%s>...\n", primary, secondary, device);
|
|
+ rc = dasd_copy_swap(device, &data);
|
|
+
|
|
+ switch (rc) {
|
|
+ case 0:
|
|
+ printf("Done.\n");
|
|
+ return 0;
|
|
+ case 1:
|
|
+ error_print("Swap data invalid");
|
|
+ break;
|
|
+ case 2:
|
|
+ error_print("No active device found");
|
|
+ break;
|
|
+ case 3:
|
|
+ error_print("Wrong primary device specified");
|
|
+ break;
|
|
+ case 4:
|
|
+ error_print("Secondary device not found");
|
|
+ break;
|
|
+ case 5:
|
|
+ error_print("Swap already running");
|
|
+ break;
|
|
+ default:
|
|
+ error_print("Swap not successful rc %d", rc);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
diff --git a/tunedasd/src/tunedasd.c b/tunedasd/src/tunedasd.c
|
|
index 3c14eb8..691841c 100644
|
|
--- a/tunedasd/src/tunedasd.c
|
|
+++ b/tunedasd/src/tunedasd.c
|
|
@@ -119,12 +119,17 @@ static struct util_opt opt_vec[] = {
|
|
.desc = "Reset all channel paths of a device",
|
|
.flags = UTIL_OPT_FLAG_NOSHORT,
|
|
},
|
|
+ {
|
|
+ .option = { "copy-pair-swap", required_argument, NULL, 's' },
|
|
+ .argument = "COPY_PAIR",
|
|
+ .desc = "Swap a specified, comma separated copy pair.",
|
|
+ },
|
|
UTIL_OPT_HELP,
|
|
UTIL_OPT_VERSION,
|
|
UTIL_OPT_END
|
|
};
|
|
|
|
-#define CMD_KEYWORD_NUM 16
|
|
+#define CMD_KEYWORD_NUM 17
|
|
#define DEVICES_NUM 256
|
|
|
|
enum cmd_keyword_id {
|
|
@@ -144,6 +149,7 @@ enum cmd_keyword_id {
|
|
cmd_keyword_path_all,
|
|
cmd_keyword_enable_stats,
|
|
cmd_keyword_disable_stats,
|
|
+ cmd_keyword_copy_swap,
|
|
};
|
|
|
|
|
|
@@ -167,7 +173,8 @@ static const struct {
|
|
{ "path_reset", cmd_keyword_path },
|
|
{ "path_reset_all", cmd_keyword_path_all },
|
|
{ "enable-stats", cmd_keyword_enable_stats },
|
|
- { "disable-stats", cmd_keyword_disable_stats }
|
|
+ { "disable-stats", cmd_keyword_disable_stats },
|
|
+ { "copy-swap", cmd_keyword_copy_swap },
|
|
};
|
|
|
|
|
|
@@ -180,26 +187,27 @@ enum cmd_key_state {
|
|
|
|
/* Determines which combination of keywords are valid */
|
|
static enum cmd_key_state cmd_key_table[CMD_KEYWORD_NUM][CMD_KEYWORD_NUM] = {
|
|
- /* help vers get_ cach no_c rese rele sloc prof prof rese quer path path
|
|
- * ion cach e yl rve ase k ile _ite t_pr y_re _all
|
|
- * e m of serv
|
|
+ /* help vers get_ cach no_c rese rele sloc prof prof rese quer path path enab disa copy
|
|
+ * ion cach e yl rve ase k ile _ite t_pr y_re _all le-s ble- -swa
|
|
+ * e m of serv tats stat p
|
|
*/
|
|
- /* help */ { req, opt, opt, opt, opt, opt, opt, opt, opt, opt, opt, inv, inv, inv, inv, inv },
|
|
- /* version */ { inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* get_cache */ { opt, opt, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* cache */ { opt, opt, inv, req, opt, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* no_cyl */ { opt, opt, inv, req, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* reserve */ { opt, opt, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* release */ { opt, opt, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* slock */ { opt, opt, inv, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
- /* profile */ { opt, opt, inv, inv, inv, inv, inv, inv, req, opt, inv, inv, inv, inv, inv, inv },
|
|
- /* prof_item */ { opt, opt, inv, inv, inv, inv, inv, inv, req, req, inv, inv, inv, inv, inv, inv },
|
|
- /* reset_prof */ { opt, opt, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv, inv, inv },
|
|
- /* query_reserve */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv, inv },
|
|
- /* path */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv },
|
|
- /* path_all */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv },
|
|
- /* enable-stats */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv },
|
|
- /* disable-stats */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req },
|
|
+ /* help */ { req, opt, opt, opt, opt, opt, opt, opt, opt, opt, opt, inv, inv, inv, inv, inv, inv },
|
|
+ /* version */ { inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* get_cache */ { opt, opt, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* cache */ { opt, opt, inv, req, opt, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* no_cyl */ { opt, opt, inv, req, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* reserve */ { opt, opt, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* release */ { opt, opt, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* slock */ { opt, opt, inv, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* profile */ { opt, opt, inv, inv, inv, inv, inv, inv, req, opt, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* prof_item */ { opt, opt, inv, inv, inv, inv, inv, inv, req, req, inv, inv, inv, inv, inv, inv, inv },
|
|
+ /* reset_prof */ { opt, opt, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv },
|
|
+ /* query_reserve */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv, inv, inv },
|
|
+ /* path */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv, inv },
|
|
+ /* path_all */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv },
|
|
+ /* enable-stats */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv },
|
|
+ /* disable-stats */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv },
|
|
+ /* copy-swap */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req },
|
|
};
|
|
|
|
struct parameter {
|
|
@@ -439,7 +447,9 @@ static int get_command_line(int argc, char *argv[], struct command_line *line)
|
|
rc = store_option (&cmdline, cmd_keyword_query_reserve,
|
|
optarg);
|
|
break;
|
|
-
|
|
+ case 's':
|
|
+ rc = store_option(&cmdline, cmd_keyword_copy_swap, optarg);
|
|
+ break;
|
|
case -1:
|
|
/* End of options string - start of devices list */
|
|
cmdline.device_id = optind;
|
|
@@ -508,6 +518,9 @@ static int do_command(char *device, struct command_line cmdline)
|
|
case cmd_keyword_path_all:
|
|
rc = disk_reset_chpid(device, NULL);
|
|
break;
|
|
+ case cmd_keyword_copy_swap:
|
|
+ rc = disk_copy_swap(device, cmdline.parm[cmd_keyword_copy_swap].data);
|
|
+ break;
|
|
default:
|
|
error_print ("Unknown command '%s' specified",
|
|
get_keyword_name (i));
|
|
--
|
|
2.38.1
|
|
|