SHA256
1
0
forked from pool/s390-tools
s390-tools/s390-tools-sles12sp3-lsdasd-tunedasd-Add-channel-path-aware-erp.patch
2017-02-21 11:14:26 +00:00

559 lines
21 KiB
Diff

Subject: [PATCH] [FEAT LS1502] lsdasd/tunedasd: Add channel path aware erp
From: Stefan Haberland <sth@linux.vnet.ibm.com>
Summary: lsdasd/tunedasd: Add channel path aware erp
Description: Add tools support for channel path aware error recovery.
lsdasd shows the newly added IFCC path mask and HPF availability.
tunedasd gets an option to reset channel paths for a device.
Upstream-ID: -
Problem-ID: LS1502
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
---
include/dasd_sys.h | 1
libdasd/dasd_sys.c | 94 +++++++++++++++++++++++++++++++++++++
tunedasd/include/disk.h | 3 -
tunedasd/man/tunedasd.8 | 17 ++++++
tunedasd/src/Makefile | 2
tunedasd/src/disk.c | 35 ++++++++++++++
tunedasd/src/tunedasd.c | 120 ++++++++++++++++++++++++++++--------------------
zconf/lsdasd | 36 +++++++++++---
8 files changed, 251 insertions(+), 57 deletions(-)
--- a/include/dasd_sys.h
+++ b/include/dasd_sys.h
@@ -13,5 +13,6 @@
#include "u2s.h"
int dasd_sys_raw_track_access(char *);
+int dasd_reset_chpid(char *, char *);
#endif /* DASD_SYS_H */
--- a/libdasd/dasd_sys.c
+++ b/libdasd/dasd_sys.c
@@ -6,6 +6,9 @@
* Copyright IBM Corp. 2016
*/
+#include <stdlib.h>
+#include <errno.h>
+
#include "dasd_sys.h"
/**
@@ -44,3 +47,94 @@ int dasd_sys_raw_track_access(char *devn
return (rc == 1) ? 1 : 0;
}
+
+
+int dasd_get_pm_from_chpid(char *busid, unsigned int chpid, int *mask)
+{
+ unsigned int val;
+ char path[40];
+ int count, i;
+ FILE *fp;
+
+ sprintf(path, "/sys/bus/ccw/devices/%s/../chpids", busid);
+ *mask = 0;
+ fp = fopen(path, "r");
+ if (!fp)
+ return ENODEV;
+
+ for (i = 0; i < 8; i++) {
+ count = fscanf(fp, " %x", &val);
+ if (count != 1) {
+ fclose(fp);
+ return EIO;
+ }
+ if (val == chpid)
+ *mask = 0x80 >> i;
+ }
+ fclose(fp);
+
+ return 0;
+}
+
+/**
+ * reset chpid
+ *
+ * The "devnode" parameter can be any valid relative or absolute path to
+ * a DASD device node, for example:
+ *
+ * - /dev/dasda
+ * - /dev/disk/by-path/ccw-0.0.bf20
+ *
+ * @param[in] devnode Device node of interest
+ * @param[in] chpid The chpid to reset
+ * If NULL all chpids will be reset
+ *
+ * @return 0 on success, otherwise one of the following error codes:
+ * - EINVAL No valid chpid specified.
+ * - ENODEV Could not open device.
+ * - ENOENT Specified chpid not found.
+ * - EIO Other I/O error
+ *
+ */
+int dasd_reset_chpid(char *devnode, char *chpid_char)
+{
+ unsigned int chpid;
+ char path[41];
+ char busid[9];
+ int mask, rc;
+ char *endptr;
+ FILE *fp;
+
+ if (u2s_getbusid(devnode, busid))
+ return ENODEV;
+
+ if (!chpid_char) {
+ sprintf(path, "/sys/bus/ccw/devices/%s/path_reset", busid);
+ fp = fopen(path, "w");
+ if (!fp)
+ return ENODEV;
+ fprintf(fp, "%s", "all\n");
+ fclose(fp);
+ return 0;
+ }
+
+ errno = 0;
+ chpid = strtoul(chpid_char, &endptr, 16);
+ if (errno || (endptr && (*endptr != '\0')))
+ return EINVAL;
+
+ rc = dasd_get_pm_from_chpid(busid, chpid, &mask);
+ if (rc)
+ return rc;
+ if (!mask)
+ return ENOENT;
+
+ sprintf(path, "/sys/bus/ccw/devices/%s/path_reset", busid);
+ fp = fopen(path, "w");
+ if (!fp)
+ return ENODEV;
+ fprintf(fp, "%02x", mask);
+ fclose(fp);
+
+ return 0;
+}
--- a/tunedasd/include/disk.h
+++ b/tunedasd/include/disk.h
@@ -27,7 +27,8 @@ int disk_release (char* device);
int disk_slock (char* device);
int disk_query_reserve_status(char* device);
int disk_profile (char* device, char* prof_item);
-int disk_reset_prof (char* device);
+int disk_reset_prof(char *device);
+int disk_reset_chpid(char *device, char *chpid);
#endif /* not DISK_H */
--- a/tunedasd/man/tunedasd.8
+++ b/tunedasd/man/tunedasd.8
@@ -149,6 +149,18 @@ Following rows are supported:
.TP
.BR "\-R" " or " "\-\-reset_prof"
Reset profile info of device.
+.TP
+.BR "\-p" " or " "\-\-path_reset <chpid>"
+Reset a channel path <chpid> of a selected device. A channel path
+might be suspended due to high IFCC error rates or a High Performance
+FICON failure. Use this option to resume considering the channel path
+for I/O.
+.TP
+.BR "\-\-path_reset_all"
+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 "\-o" " or " "\-\-online"
@@ -166,8 +178,13 @@ Reset profile info of device.
.br
tunedasd -c prestage -n 1 /dev/dasdc
+
+.br
+3. Scenario: Reset failed channel path with CHPID 45
.br
+ tunedasd -p 45 /dev/dasdc
+.br
.SH "SEE ALSO"
.BR dasdview (8),
.BR dasdfmt (8),
--- a/tunedasd/src/Makefile
+++ b/tunedasd/src/Makefile
@@ -5,7 +5,7 @@ includes = $(wildcard ../include/*.h)
all: tunedasd
-objects = tunedasd.o disk.o
+objects = tunedasd.o disk.o ../../libdasd/dasd_sys.o ../../libu2s/u2s.o
$(objects): $(includes)
tunedasd: $(objects)
--- a/tunedasd/src/disk.c
+++ b/tunedasd/src/disk.c
@@ -9,6 +9,7 @@
#include "disk.h"
#include "tunedasd.h"
+#include "dasd_sys.h"
#include <sys/types.h>
#include <sys/ioctl.h>
@@ -682,3 +683,37 @@ disk_reset_prof (char* device)
return 0;
}
+int disk_reset_chpid(char *device, char *chpid)
+{
+ int rc;
+
+ if (chpid)
+ printf("Resetting chpid %s for device <%s>...\n", chpid,
+ device);
+ else
+ printf("Resetting all chpids for device <%s>...\n", device);
+
+ rc = dasd_reset_chpid(device, chpid);
+ switch (rc) {
+ case 0:
+ printf("Done.\n");
+ return 0;
+ case ENODEV:
+ error_print("%s: %s", device, strerror(errno));
+ break;
+ case EINVAL:
+ error_print("%s: Could not reset chpid %s: Invalid CHPID",
+ device, chpid);
+ break;
+ case ENOENT:
+ error_print("%s: Could not reset chpid %s: CHPID not defined for device",
+ device, chpid);
+ break;
+ default:
+ error_print("%s: Could not reset chpid %s",
+ device, chpid);
+ break;
+ }
+
+ return -1;
+}
--- a/tunedasd/src/tunedasd.c
+++ b/tunedasd/src/tunedasd.c
@@ -34,28 +34,30 @@ static const char* usage_text[] = {
"(e.g. '/dev/dasda') or a list of devices separated by a space "
"character.",
"",
- "-h, --help Print this help, then exit",
- "-v, --version Print version information, then exit",
- "-g, --get_cache Get current storage server caching behaviour",
- "-c, --cache <behavior> Define caching behavior on storage server",
- " (normal/bypass/inhibit/sequential/prestage/"
- "record)",
- "-n, --no_cyl <n> Number of cylinders to be cached ",
- " (only valid together with --cache)",
- "-S, --reserve Reserve device",
- "-L, --release Release device",
- "-O, --slock Unconditional reserve device",
- " Note: Use with care, this breaks an existing "
- "lock",
- "-Q, --query_reserve Print reserve status of device ",
- "-P, --profile Print profile info of device",
- "-I, --prof_item Print single profile item",
- " (reqs/sects/sizes/total/totsect/start/irq/",
- " irqsect/end/queue)",
- "-R, --reset_prof Reset profile info of device"
+ "-h, --help Print this help, then exit",
+ "-v, --version Print version information, then exit",
+ "-g, --get_cache Get current storage server caching behaviour",
+ "-c, --cache <behavior> Define caching behavior on storage server",
+ " (normal/bypass/inhibit/sequential/prestage/"
+ "record)",
+ "-n, --no_cyl <n> Number of cylinders to be cached ",
+ " (only valid together with --cache)",
+ "-S, --reserve Reserve device",
+ "-L, --release Release device",
+ "-O, --slock Unconditional reserve device",
+ " Note: Use with care, this breaks an existing "
+ "lock",
+ "-Q, --query_reserve Print reserve status of device ",
+ "-P, --profile Print profile info of device",
+ "-I, --prof_item Print single profile item",
+ " (reqs/sects/sizes/total/totsect/start/irq/",
+ " irqsect/end/queue)",
+ "-R, --reset_prof Reset profile info of device",
+ "-p, --path_reset <chpid> Reset channel path <chpid> of a device",
+ " --path_reset_all Reset all channel paths of a device"
};
-#define CMD_KEYWORD_NUM 12
+#define CMD_KEYWORD_NUM 14
#define DEVICES_NUM 256
enum cmd_keyword_id {
@@ -71,6 +73,8 @@ enum cmd_keyword_id {
cmd_keyword_prof_item = 9,
cmd_keyword_reset_prof = 10,
cmd_keyword_query_reserve = 11,
+ cmd_keyword_path = 12,
+ cmd_keyword_path_all = 13,
};
@@ -79,18 +83,20 @@ static const struct {
char* keyword;
enum cmd_keyword_id id;
} keyword_list[] = {
- { "help", cmd_keyword_help },
- { "version", cmd_keyword_version },
- { "get_cache", cmd_keyword_get_cache },
- { "cache", cmd_keyword_cache },
- { "no_cyl", cmd_keyword_no_cyl },
- { "reserve", cmd_keyword_reserve },
- { "release", cmd_keyword_release },
- { "slock", cmd_keyword_slock },
- { "profile", cmd_keyword_profile },
- { "prof_item", cmd_keyword_prof_item },
- { "reset_prof", cmd_keyword_reset_prof },
- { "query_reserve", cmd_keyword_query_reserve }
+ { "help", cmd_keyword_help },
+ { "version", cmd_keyword_version },
+ { "get_cache", cmd_keyword_get_cache },
+ { "cache", cmd_keyword_cache },
+ { "no_cyl", cmd_keyword_no_cyl },
+ { "reserve", cmd_keyword_reserve },
+ { "release", cmd_keyword_release },
+ { "slock", cmd_keyword_slock },
+ { "profile", cmd_keyword_profile },
+ { "prof_item", cmd_keyword_prof_item },
+ { "reset_prof", cmd_keyword_reset_prof },
+ { "query_reserve", cmd_keyword_query_reserve },
+ { "path_reset", cmd_keyword_path },
+ { "path_reset_all", cmd_keyword_path_all }
};
@@ -103,22 +109,24 @@ enum cmd_key_state {
/* Determines which combination of keywords are valid */
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
- * ion cach e yl rve ase k ile _ite t_pr y_re
+ /* 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 */ { req, opt, opt, opt, opt, opt, opt, opt, opt, opt, opt, inv },
- /* version */ { inv, req, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv },
- /* get_cache */ { opt, opt, req, inv, inv, inv, inv, inv, inv, inv, inv, inv },
- /* cache */ { opt, opt, inv, req, opt, inv, inv, inv, inv, inv, inv, inv },
- /* no_cyl */ { opt, opt, inv, req, req, inv, inv, inv, inv, inv, inv, inv },
- /* reserve */ { opt, opt, inv, inv, inv, req, inv, inv, inv, inv, inv, inv },
- /* release */ { opt, opt, inv, inv, inv, inv, req, inv, inv, inv, inv, inv },
- /* slock */ { opt, opt, inv, inv, inv, inv, inv, req, inv, inv, inv, inv },
- /* profile */ { opt, opt, inv, inv, inv, inv, inv, inv, req, opt, inv, inv },
- /* prof_item */ { opt, opt, inv, inv, inv, inv, inv, inv, req, req, inv, inv },
- /* reset_prof */ { opt, opt, inv, inv, inv, inv, inv, inv, inv, inv, req, inv },
- /* query_reserve */ { 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 },
+ /* version */ { inv, req, 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 },
+ /* cache */ { opt, opt, inv, req, opt, 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 },
+ /* reserve */ { opt, opt, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv, inv },
+ /* release */ { opt, opt, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv, inv },
+ /* slock */ { opt, opt, inv, inv, inv, inv, inv, req, inv, inv, inv, inv, inv, inv },
+ /* profile */ { opt, opt, inv, inv, inv, inv, inv, inv, req, opt, inv, inv, inv, inv },
+ /* prof_item */ { opt, opt, inv, inv, inv, inv, inv, inv, req, req, inv, inv, inv, inv },
+ /* reset_prof */ { opt, opt, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv, inv },
+ /* query_reserve */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv, inv },
+ /* path */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, inv },
+ /* path_all */ { inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req },
};
struct parameter {
@@ -146,11 +154,13 @@ static struct option options[] = {
{ "prof_item", required_argument, NULL, 'I'},
{ "reset_prof", no_argument, NULL, 'R'},
{ "query_reserve", no_argument, NULL, 'Q'},
+ { "path_reset", required_argument, NULL, 'p'},
+ { "path_reset_all", no_argument, NULL, 'A'},
{ NULL, 0, NULL, 0 }
};
/* Command line option abbreviations */
-static const char option_string[] = "hvgc:n:SLOPI:RQ";
+static const char option_string[] = "hvgc:n:SLOPI:RQp:";
/* Error message string */
@@ -348,6 +358,14 @@ get_command_line (int argc, char* argv[]
optarg);
}
break;
+ case 'p':
+ rc = store_option(&cmdline, cmd_keyword_path,
+ optarg);
+ break;
+ case 'A':
+ rc = store_option(&cmdline, cmd_keyword_path_all,
+ optarg);
+ break;
case 'S':
rc = store_option (&cmdline, cmd_keyword_reserve,
optarg);
@@ -400,7 +418,6 @@ get_command_line (int argc, char* argv[]
return 0;
}
-
/*
* Execute the command.
*/
@@ -444,6 +461,13 @@ do_command (char* device, struct command
case cmd_keyword_query_reserve:
rc = disk_query_reserve_status(device);
break;
+ case cmd_keyword_path:
+ rc = disk_reset_chpid(device,
+ cmdline.parm[cmd_keyword_path].data);
+ break;
+ case cmd_keyword_path_all:
+ rc = disk_reset_chpid(device, NULL);
+ break;
default:
error_print ("Unknown command '%s' specified",
get_keyword_name (i));
--- a/zconf/lsdasd
+++ b/zconf/lsdasd
@@ -368,13 +368,15 @@ function extended()
CABLEPM=0
CUIRPM=0
HPFPM=0
+ IFCCPM=0
# additional information
read DIAG 2> /dev/null < $DEVPATH/use_diag || continue
read EER 2> /dev/null < $DEVPATH/eer_enabled || continue
read ERP 2> /dev/null < $DEVPATH/erplog || continue
+ read HPF 2> /dev/null < $DEVPATH/hpf
# in case the path_masks do not exist simply ignore it
- read OPM NPPM CABLEPM CUIRPM HPFPM 2> /dev/null < $DEVPATH/path_masks
+ read OPM NPPM CABLEPM CUIRPM HPFPM IFCCPM 2> /dev/null < $DEVPATH/path_masks
read -a C 2> /dev/null < $DEVPATH/../chpids || continue
read PIM PAM POM 2> /dev/null < $DEVPATH/../pimpampom || continue
@@ -385,6 +387,7 @@ function extended()
CABLEPM=0x$CABLEPM
CUIRPM=0x$CUIRPM
HPFPM=0x$HPFPM
+ IFCCPM=0x$IFCCPM
#-----------------------------------------------------------#
# aggregate chpids and path mask to useful information #
@@ -397,6 +400,7 @@ function extended()
CUIR_PATHS=(" " " " " " " " " " " " " " " ")
CABLE_PATHS=(" " " " " " " " " " " " " " " ")
HPF_PATHS=(" " " " " " " " " " " " " " " ")
+ IFCC_PATHS=(" " " " " " " " " " " " " " " ")
# installed paths
j=0
@@ -470,13 +474,25 @@ function extended()
(( mask>>=1 ))
done
+ # IFCC unusable paths
+ j=0
+ mask=0x80
+ for (( i=0; i<8; i++ )) ;do
+ PM=$(($IFCCPM&$mask))
+ if [ $PM -gt 0 ] ;then
+ IFCC_PATHS[j]=${C[$i]} ;
+ ((j++)) ;
+ fi
+ (( mask>>=1 ))
+ done
+
#-------------------------------------------#
# format data for output #
#-------------------------------------------#
if [[ "$ONLINE" == 0 ]]; then
ACTIVE="offline"
- printf "%s:%s:%s# status:\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# uid: \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#\n" \
+ printf "%s:%s:%s# status:\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# 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" \
"$SORTKEYLEN" "$SORTKEY" \
"$BUSID" \
"$ACTIVE" \
@@ -484,18 +500,20 @@ function extended()
"$READONLY" \
"$EER" \
"$ERP" \
+ "$HPF" \
"$DEV_UID" \
"${INSTALLED_PATHS[@]}" \
"${USED_PATHS[@]}" \
"${NP_PATHS[@]}" \
"${CABLE_PATHS[@]}" \
"${CUIR_PATHS[@]}" \
- "${HPF_PATHS[@]}" ;
+ "${HPF_PATHS[@]}" \
+ "${IFCC_PATHS[@]}" ;
continue
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 # uid: \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#\n" \
+ 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# 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" \
"$SORTKEYLEN" "$SORTKEY" \
"$BUSID" \
"$ACTIVE" \
@@ -504,13 +522,15 @@ function extended()
"$READONLY" \
"$EER" \
"$ERP" \
+ "$HPF" \
"$DEV_UID" \
"${INSTALLED_PATHS[@]}" \
"${USED_PATHS[@]}" \
"${NP_PATHS[@]}" \
"${CABLE_PATHS[@]}" \
"${CUIR_PATHS[@]}" \
- "${HPF_PATHS[@]}" ;
+ "${HPF_PATHS[@]}" \
+ "${IFCC_PATHS[@]}" ;
continue
else
continue
@@ -533,7 +553,7 @@ function extended()
COLON=":"
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# 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# uid: \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#\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# 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# 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" \
"$SORTKEYLEN" "$SORTKEY" \
"$BUSID" \
"$BLOCKNAME" \
@@ -549,13 +569,15 @@ function extended()
"$READONLY" \
"$EER" \
"$ERP" \
+ "$HPF" \
"$DEV_UID" \
"${INSTALLED_PATHS[@]}" \
"${USED_PATHS[@]}" \
"${NP_PATHS[@]}" \
"${CABLE_PATHS[@]}" \
"${CUIR_PATHS[@]}" \
- "${HPF_PATHS[@]}" ;
+ "${HPF_PATHS[@]}" \
+ "${IFCC_PATHS[@]}" ;
}
function host()