-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhbareport-lpar
1566 lines (1473 loc) · 62.1 KB
/
hbareport-lpar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
#######################################################################
# hbareport - Linux PowerPC LPAR HBA Reporting Tool
#######################################################################
# This tool examines a PowerPC-based SLES v12 or v15 LPAR and attempts
# to determine what Fibre-Channel HBAs, if any, are attached to the
# LPAR using NPIV-delivered by VIOs. If any recognized pseudo-HBAs
# are found, it attempts to display selected information items about
# each pseudo-HBA, and about any SAN-based storage.
#
# REQUIRES:
# 0) A PowerPC-based LPAR with virtualized HBAs presented by one
# or more VIOs
# 1) SLES v12 or later - will refuse to run on earlier versions
# 2) bash_tools.sh v100 or later
# 3) For full functionality, Privileged Access (may be run
# unprivileged; if so, LUN detection and multipath analysis
# will be skipped)
# 4) Appropriate HBA drivers must be loaded - will not detect
# hardware unless driver is loaded
# 5) No special package requirements - handles lack of HBAs
#
# NOTES:
# 0) When invoked in Check Mode (-c), writes to CHECK_FILE a set of
# BASH variables that can be sourced by a Nagios check script
# and then used to generate the return the monitoring host;
# the REPORT_DATE is the number of seconds since 1970-01-01 and
# can be used by the Nagios check script to judge the
# "freshness" of the report
# 1) Was *deliberately* designed as a tool separate from a Nagios
# check script for 3 reasons:
# a) To create a separate tool that had fundamentally the
# same purpose but was operationally restricted to Nagios
# was not worth the effort
# b) Direct execution by NRPE would require the "nagios" ID
# be able to use "sudo" or otherwise attain a Privileged
# state, which is not desirable
# c) Execution can take an extended time on hosts with many
# LUNs and could result in Nagios time-outs
# 2) This tool is based on a version that was written for a
# multi-RHEL-version environment running on physical hardware
# (bare metal) using about 4 or 5 different possible QLogic
# HBAs, some having drivers specific to Veritas NetBackup, with
# support for about 4 different makes/models of SAN back-ends;
# consequently, the tool on which this version is based was
# MUCH more complex, and was designed to account for a great
# number of possible variations in the environment; as a
# result, there is probably more than a little cruft in this
# version of the tool, with variables that are declared but
# never used, and even some control logic that is
# more-complex/cumbersome than it needs to be; cleaning that
# up will be an iterative process
# 3) Additionally, this tool was designed for a SLES for SAP v15
# environment as part of a HANA 2.0 deployment - the code
# makes a number of assumptions about LUN names, the
# host naming convention, and specifics about the platform
# which are probably not true about other environments, so
# it is unlikely this tool will work well without some
# modifications
# 4) In addition to #3, the environment for which this tool was
# designed had 3 different SAN makes/models, and this tool
# does not recognize anything else
# 5) Initial testing indicates that SLES 15 appears functionally
# identical to SLES 12 except for possible deprecated callouts
#
# KNOWN BUGS:
# 0) Does not verify all dependencies
#
# TO DO:
# 0) Verify script can create CHECK_FILE
# 1) Improve how this tool reports its own problems back to a
# Nagios check
# 2) Use mktemp instead of static temporary files
#
#######################################################################
TOOL_VERSION='100'
#######################################################################
# Change Log (Reverse Chronological Order)
# Who When______ What__________________________________________________
# dxb 2018-12-10 Initial creation (v1.00)
#######################################################################
# Require minimum version of bash_tools.sh
MINIMUM_BASH_TOOLS_LIBRARY_VERSION='100'
TOOLS_FILE='/usr/local/lib/bash_tools.sh'
# Make sure it exists, is NOT 0-length, and is a regular file
if [[ -e ${TOOLS_FILE} && -s ${TOOLS_FILE} && -f ${TOOLS_FILE} ]]; then
# Looks like valid TOOLS_FILE - source it and initialize
source ${TOOLS_FILE}
# Check the version
if [[ "${BASH_TOOLS_LIBRARY_VERSION}" -lt "${MINIMUM_BASH_TOOLS_LIBRARY_VERSION}" ]]; then
echo -e "\nFATAL ERROR: Outdated tool library (${TOOLS_FILE}) - found v${BASH_TOOLS_LIBRARY_VERSION} but need ${MINIMUM_BASH_TOOLS_LIBRARY_VERSION} or later\n"
exit 1
else
# Initialize non-SLES-version-specific command-shortcut variables
_init_script_tool_names
# Populate important variables
_init_script_variables
# Set up variables to colorize text output
_init_script_colors
fi
else
echo -e "\nFATAL ERROR: Unable to source a valid tool library from ${TOOLS_FILE}\n"
exit 1
fi
# Log tag for syslog when run with -c
readonly LOG_TAG='hbareport'
# Files and paths
# When in Check Mode, write to a log file for later use by the Nagios
# check script
readonly CHECK_FILE='/var/log/hbareport'
# List of typical SLES-supplied IBM Drivers
readonly DRIVER_LIST='ibmvfc ibmvscsi'
# Maximum number when creating "data#", "log#" and "mpath#" LUN Names
readonly MAX_LUN_COUNTER=100
# Internal debugging flag (no command-line option)
# Defaults to 'NO'
# Set to 'YES' to enable additional screen output for debugging; a later
# check will force this to "NO" if the tool is running in Setup Mode,
# Check Mode or Decomm Mode
__DEBUG='NO'
# Initialize flags for command-line options
CHECK_MODE='NO'
DECOMM='NO'
FULL='NO'
HELP_FLAG='NO'
KERNEL='NO'
SERIALS='NO'
PATHS='NO'
QUICK='NO'
UNKNOWN='NO'
# Select options from the command-line (if any were specified) or, if none
# were given, use the environment variable (if it exists)
if [[ $# -gt 0 ]]; then
# Command Line Argument Processing
while getopts ':cdfhknpqs' OPT; do
case ${OPT} in
c) CHECK_MODE='YES'
_log_script_message 'Starting execution to generate Nagios check file'
;;
d) DECOMM='YES';;
f) FULL='YES';;
h) HELP_FLAG='YES';;
k) KERNEL='YES';;
n) SERIALS='YES';;
p) PATHS='YES';;
q) QUICK='YES';;
s) SETUP='YES';;
*) UNKNOWN='YES';;
esac
done
else
# If the environment variable HBAREPORT_OPTS exists, get arguments
# from it (-d, -f, -k, -n, -p and -q supported)
# Unknown/invalid arguments are silently ignored
if [[ "${HBAREPORT_OPTS}" ]]; then
for OPTION in $( echo "${HBAREPORT_OPTS}" ); do
case ${OPTION} in
'-d') DECOMM='YES';;
'-f') FULL='YES';;
'-k') KERNEL='YES';;
'-n') SERIALS='YES';;
'-p') PATHS='YES';;
'-q') QUICK='YES';;
esac
done
fi
# End of if [[ "${HBAREPORT_OPTS}" ]]
fi
# End of if [[ $# -gt 0 ]]
readonly HELP_FLAG
readonly UNKNOWN
# Help Screen
readonly HELP="
${0} - ${BOLD_TEXT}Linux HBA Detection and Reporting Tool v${TOOL_VERSION}${ALL_OFF}
\t${BOLD_TEXT}Usage :${ALL_OFF} ${0} ${BOLD_TEXT}[ -d | -f | -k -n -p | -c | -q | -s | -h ]${ALL_OFF}
\t${BOLD_TEXT}Syntax:${ALL_OFF}
\t\t${BOLD_TEXT}-c${ALL_OFF} --> Run in Check Mode - Write ${BOLD_TEXT}${MAGENTA_BLACK}${CHECK_FILE}${ALL_OFF} for Nagios check script ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t\t\tCancels out ${BOLD_TEXT}-d -f, -n${ALL_OFF} and ${BOLD_TEXT}-q${ALL_OFF}
\t\t${BOLD_TEXT}-d${ALL_OFF} --> Decomm Info - Write amount (in GB) detected in SAN LUNs to stdout ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t\t\tAlso writes WWPNs of active HBAs, and LUN Serial Numbers, to a file
\t\t\t\tCancels out ${BOLD_TEXT}-f, -k, -n, -p${ALL_OFF} and ${BOLD_TEXT}-q${ALL_OFF}
\t\t${BOLD_TEXT}-f${ALL_OFF} --> Full Report - Same as ${BOLD_TEXT}-k, -n${ALL_OFF} and ${BOLD_TEXT}-p${ALL_OFF} ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t${BOLD_TEXT}-h${ALL_OFF} --> Show this help screen and exit
\t\t${BOLD_TEXT}-k${ALL_OFF} --> Kernel Module Driver ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t\t\tDisplay information about driver kernel modules
\t\t${BOLD_TEXT}-n${ALL_OFF} --> Display LUN Serial Numbers ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t${BOLD_TEXT}-p${ALL_OFF} --> Path Analysis - Associate LUNs to device names/paths ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t${BOLD_TEXT}-q${ALL_OFF} --> Quick Mode ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t\t\tAbbreviated report for ${BOLD_TEXT}active${ALL_OFF} HBAs only (Cancels out ${BOLD_TEXT}-f, -k, -n${ALL_OFF} and ${BOLD_TEXT}-p${ALL_OFF})
\t\t${BOLD_TEXT}-s${ALL_OFF} --> Run in Setup Mode ${RED_BLACK}(REQUIRES PRIVILEGE)${ALL_OFF}
\t\t\t\tDesigned to be invoked by Setup Script (Writes all output to files used by Setup Script)
\t${BOLD_TEXT}${MAGENTA_BLACK}Requires a PowerPC-based LPAR and SLES v12 or later${ALL_OFF}
\tIf it exists, options listed in environment variable ${BOLD_TEXT}HBAREPORT_OPTS${ALL_OFF} will be used
\t\t(only ${BOLD_TEXT}-d, -f, -k, -n, -p${ALL_OFF} and ${BOLD_TEXT}-q${ALL_OFF} supported; everything else ignored)
\t\t${BOLD_TEXT}${MAGENTA_BLACK}Environment variable is ignored if any command-line arguments are specified${ALL_OFF}
\tIn Setup Mode, all arguments except ${BOLD_TEXT}-h${ALL_OFF} are ignored; outside of Setup Mode, arguments are optional
\t${BOLD_TEXT}Found ${GREEN_BLACK}${TOOLS_FILE} v${BASH_TOOLS_LIBRARY_VERSION}${ALL_OFF}
"
# If -h argument given, or an unknown/invalid argument was given,
# display help screen and exit
if [[ "${HELP_FLAG}" == 'YES' || "${UNKNOWN}" == 'YES' ]]; then
if [[ "${CHECK_MODE}" == 'NO' ]]; then
echo -e "${HELP}"
exit 0
else
_log_script_message 'Abort - invalid argument'
echo 'ABORT=1' >> ${CHECK_FILE}
exit 1
fi
fi
# Check Mode supercedes -d!
if [[ "${CHECK_MODE}" == 'YES' ]]; then
readonly DECOMM='NO'
readonly SETUP='NO'
else
# If just getting Decomm info (-d command-line parameter), then I can
# leverage Setup Mode to do the heavy lifting
if [[ "${DECOMM}" == 'YES' ]]; then
readonly DECOMM='NO'
readonly SETUP='YES'
fi
fi
# Define OUTPUT_MODE
# 0 - Normal (run interactively; full output to stdout)
# 1 - Setup Mode (output to file)
# 2 - Decomm (Output limited info to stdout)
# 3 - Check mode (Write to CHECK_FILE for later use by Nagios
# check script)
# Set OUTPUT_MODE if -s flag was on command line (or if I'm cheating
# and using it for Decomm info)
if [[ "${SETUP}" == 'YES' ]]; then
# Note that -c would have cancelled out -s or -d, so I am not in
# Check Mode here
if [[ "${DECOMM}" == 'YES' ]]; then
readonly OUTPUT_MODE=2
# Init string used for output in this mode
DECOMM_LIST=''
else
readonly OUTPUT_MODE=1
fi
# If in Setup Mode, do not ID script
# Also, assume execution is Privileged; however, do not expect
# Multipathing to be setup or for LUNs to be visible, so skip that
# part of this script
# EXCEPTION: If in Output Mode 2 (Decomm Mode)
if [[ "${OUTPUT_MODE}" -eq 2 ]]; then
SKIP_LUN=0
KERNEL='NO'
else
SKIP_LUN=1
KERNEL='YES'
fi
# Turn off everything else too
PATHS='NO'
SERIALS='NO'
# Also initialize file variables
# IMPORTANT: These MUST match those defined in the Setup Script
readonly SETUP_LOG='/root/.setupscriptlog'
readonly TMP_FILE='/tmp/.setup'
readonly SAN_TMP_FILE='/tmp/.setupSAN'
else
# In Check Mode?
if [[ "${CHECK_MODE}" == 'YES' ]]; then
readonly OUTPUT_MODE=3
# Check mode cancels out -n and -q; but includes -k and -p
KERNEL='YES'
PATHS='YES'
QUICK='NO'
SERIALS='NO'
# Check Mode requires Privilege!
if [[ "${EUID}" -ne 0 ]]; then
echo 'ABORT=128' > ${CHECK_FILE}
exit 128
else
SKIP_LUN=0
fi
else
# Not in Check Mode
readonly OUTPUT_MODE=0
# Did user request Full Report Mode?
if [[ "${FULL}" == 'YES' ]]; then
KERNEL='YES'
PATHS='YES'
SERIALS='YES'
fi
# Quick Mode silently overrides Full Report Mode
if [[ "${QUICK}" == 'YES' ]]; then
KERNEL='NO'
PATHS='NO'
SERIALS='NO'
fi
# ID Script
OUTPUT="${0} v${TOOL_VERSION}"
# Determine if user has privilege
if [[ "${EUID}" -ne 0 ]]; then
OUTPUT="${OUTPUT}\t\t${BOLD_TEXT}${MAGENTA_BLACK}WARNING:${ALL_OFF} Running ${BOLD_TEXT}UN-Privileged${ALL_OFF} - Bus Probing and LUN/Multipath Analysis ${BOLD_TEXT}DISABLED${ALL_OFF}"
SKIP_LUN=1
KERNEL='NO'
else
OUTPUT="${OUTPUT}\t\t${BOLD_TEXT}${GREEN_BLACK}Privileged status verified${ALL_OFF}"
SKIP_LUN=0
fi
# Display info
echo -e "${OUTPUT}"
fi
# End of if [[ "${CHECK_MODE}" == 'YES' ]]
fi
# End of if [[ "${SETUP}" == 'YES' ]]
readonly CHECK_MODE
readonly KERNEL
readonly PATHS
readonly SERIALS
readonly SKIP_LUN
# If debugging was turned on above, then turn it off if OUTPUT_MODE is not 0
if [[ "${__DEBUG}" != 'NO' && "${OUTPUT_MODE}" -ne 0 ]]; then
__DEBUG='NO'
fi
readonly __DEBUG
# Check OS version - uses function from TOOLS_FILE
_get_os_release
SLES_VERSION=$?
case "${SLES_VERSION}" in
0) # File parse error
case "${OUTPUT_MODE}" in
0) echo -e "\n${BOLD_TEXT}${RED_BLACK}FATAL ERROR:${ALL_OFF} ${BOLD_TEXT}File Parse Failed in _get_os_release${ALL_OFF}\n"
exit 1
;;
1) echo "ABORTED - ${0} exited with file parse error" > ${TMP_FILE}
exit 0
;;
2) # Exit with error
exit 255
;;
3) # Exit with error
echo 'ABORT=255' > ${CHECK_FILE}
_log_script_message 'Abort - File Parse Failed in _get_os_release'
exit 255
;;
esac
;;
12|15)
readonly MODULE_FILE='/etc/modprobe.d/'
# Directory prefix we use when querying for some data items for a
# VIO-delivered pseudo-HBA
readonly HBA_FIND='/sys/class/scsi_host'
# Files under HBA_FIND that contain specific info items
readonly HBA_VFCHOST_FILE='device_name'
readonly HBA_VIO_FILE='partition_name'
readonly HBA_PORT_FILE='port_loc_code'
# Directory where I'll find the sub-dirs for each VIO-delivered
# pseudo-HBA
readonly HBA_NODE='/sys/class/fc_host'
# Files under HBA_NODE that contain specific info items
readonly HBA_WWPN_FILE='port_name'
readonly HBA_SPEED_FILE='speed'
readonly HBA_STATE_FILE='port_state'
;;
*) case "${OUTPUT_MODE}" in
0) echo -e "\n${BOLD_TEXT}${RED_BLACK}FATAL ERROR:${ALL_OFF} ${BOLD_TEXT}SLES v${SLES_VERSION} is Unsupported${ALL_OFF}\n"
exit 1
;;
1) # In theory, the Setup script should never call this
echo "ABORTED - SLES v${SLES_VERSION} is Unsupported" > ${TMP_FILE}
exit 0
;;
2) # Exit with error
exit 255
;;
3) # Exit with error
echo 'ABORT=255' > ${CHECK_FILE}
_log_script_message "Abort - SLES v${SLES_VERSION} is Unsupported"
exit 255
;;
esac
;;
esac
# End of case "${SLES_VERSION}" in
# Only run in a PowerPC-based LPAR, so check for that - uses function
# from TOOLS_FILE
_get_platform
_MY_PLATFORM=$?
if [[ "${__DEBUG}" == 'YES' ]]; then
echo "FULL is ${FULL}"
echo "PATHS is ${PATHS}"
echo "_MY_PLATFORM is ${_MY_PLATFORM}"
fi
# It should be "0" if I'm on PowerPC
case "${_MY_PLATFORM}" in
0) # Good!
# Initialize a list of standard LUN aliases (plus some
# SLES-default ones to catch when multipathing is set up not
# using standard names)
# IMPORTANT: I add to the list as separate loops for each stem so
# that I get the listings to appear contiguous
LUN_LIST='backup'
# Add more standard "backup*" onto this list using loop
for (( ITERATOR=0 ; ITERATOR<${MAX_LUN_COUNTER} ; ITERATOR++ )); do
if [[ "${ITERATOR}" -le 9 ]]; then
LUN_LIST="${LUN_LIST} backup${ITERATOR} backup0${ITERATOR}"
else
LUN_LIST="${LUN_LIST} backup${ITERATOR}"
fi
done
LUN_LIST="${LUN_LIST} boot cluster"
# Add more standard "cluster*" onto this list using loop
for (( ITERATOR=0 ; ITERATOR<${MAX_LUN_COUNTER} ; ITERATOR++ )); do
LUN_LIST="${LUN_LIST} cluster${ITERATOR}"
done
LUN_LIST="${LUN_LIST} data"
# Add more standard "data*" onto this list using loop
for (( ITERATOR=0 ; ITERATOR<${MAX_LUN_COUNTER} ; ITERATOR++ )); do
LUN_LIST="${LUN_LIST} data${ITERATOR}"
done
# Add more standard names onto this list using loop
LUN_LIST="${LUN_LIST} hana log"
# Add more standard "log*" onto this list using loop
for (( ITERATOR=0 ; ITERATOR<${MAX_LUN_COUNTER} ; ITERATOR++ )); do
LUN_LIST="${LUN_LIST} log${ITERATOR}"
done
# Add more SLES-standard "mpath*" onto this list using loop
for (( ITERATOR=0 ; ITERATOR<${MAX_LUN_COUNTER} ; ITERATOR++ )); do
LUN_LIST="${LUN_LIST} mpath${ITERATOR}"
done
# Add more standard names onto this list using loop
LUN_LIST="${LUN_LIST} sap shared usrsap"
readonly LUN_LIST
;;
1) # VMware - do NOT run on that
case "${OUTPUT_MODE}" in
0) echo -e "\n${BOLD_TEXT}${RED_BLACK}FATAL ERROR:${ALL_OFF} ${BOLD_TEXT}VMware-based Hosts are Unsupported${ALL_OFF}\n"
exit 1
;;
1) # In theory, the Setup script should never call this
echo "ABORTED - VMware-based Hosts are Unsupported" > ${TMP_FILE}
exit 0
;;
2) # Exit with error
exit 255
;;
3) # Exit with error
echo 'ABORT=255' > ${CHECK_FILE}
_log_script_message 'Abort - VMware-based Hosts are Unsupported'
exit 255
;;
esac
;;
*) # BAD - parsing error or other problem
case "${OUTPUT_MODE}" in
0) echo -e "\n${BOLD_TEXT}${RED_BLACK}FATAL ERROR:${ALL_OFF} ${BOLD_TEXT}File Parse Failed in _get_platform${ALL_OFF}\n"
exit 1
;;
1) echo "ABORTED - ${0} exited with file parse error" > ${TMP_FILE}
exit 0
;;
2) # Exit with error
exit 255
;;
3) # Exit with error
echo 'ABORT=255' > ${CHECK_FILE}
_log_script_message 'Abort - File Parse Failed in _get_platform'
exit 255
;;
esac
;;
esac
# End of case "${_MY_PLATFORM}" in
# Counter for Fiber Channel devices delivered by VIOs
SEARCH_FLAG=0
HBA_PORT_COUNT=0
DEVICE_COUNT=0
# Multipath Executable and arguments
readonly MULTIPATH_EXEC="${MULTIPATH_TOOL} -ll"
MULTIPATH_EXEC_OUTPUT='/tmp/mp.out'
# Multipath Service status
readonly MPATH_SVC="${SVC_TOOL} multipathd status"
MPATH_SVCSTAT=0
# Init variables used in loop
PATH_COUNT=0
ACTIVE=0
ENABLED=0
FAILED=0
OUTPUT=''
#################
# Program Start #
#################
# Get host name
CHKSTR=$( ${UNAME_TOOL} -n )
case "${OUTPUT_MODE}" in
0) echo -e "\tChecking for Fiber HBAs in SLES ${BOLD_TEXT}v${SLES_VERSION}${ALL_OFF} host ${BOLD_TEXT}${CHKSTR}${ALL_OFF}" ;;
1) OUTPUT='Detecting installed SAN HBAs'
echo -e "${OUTPUT}\n"
echo -e "${OUTPUT}\n" >> ${SETUP_LOG}
echo -e 'I have scanned for installed HBAs and found the following:\n' >> ${TMP_FILE}
;;
3) # Get UTC date in Epoch format (# of seconds since 1970-01-01)
CHKSTR=$( ${DATE_TOOL} --utc +%s )
_log_script_message 'Execution environment is good'
echo "# ${CHKSTR}:${CHECK_FILE} generated by ${0} v${TOOL_VERSION}" > ${CHECK_FILE}
echo '# Timestamp in UNIX Epoch format' >> ${CHECK_FILE}
echo "REPORT_DATE=${CHKSTR}" >> ${CHECK_FILE}
;;
# No output for any other mode
esac
#######################################################################
# Driver Detection #
####################
# Look at loaded kernel modules and detect HBA-like drivers in my list
# At this point, the only concern is determining what pseudo-HBAs may
# exist in the system
# Look for HBA-like drivers (basically, the IBM Virtual FC driver)
HBA_DETECT_FLAG=0
declare -a DRIVER_NAME_ARRAY
for THIS_DRIVER in ${DRIVER_LIST}; do
CHKSTR=$( ${LISTMOD_TOOL} | ${GREP_TOOL} -w -m 1 -c ${THIS_DRIVER} )
if [[ "${CHKSTR}" -eq 1 ]]; then
DRIVER_NAME_ARRAY[${HBA_DETECT_FLAG}]="${THIS_DRIVER}"
(( HBA_DETECT_FLAG = HBA_DETECT_FLAG + 1 ))
fi
if [[ "${__DEBUG}" == 'YES' ]]; then
echo "CHKSTR is ${CHKSTR}"
echo "HBA_DETECT_FLAG is ${HBA_DETECT_FLAG}"
echo "DRIVER_NAME_ARRAY is ${DRIVER_NAME_ARRAY[*]}"
fi
done
if [[ "${__DEBUG}" == 'YES' ]]; then
echo "Final DRIVER_NAME_ARRAY is ${DRIVER_NAME_ARRAY[*]}"
fi
###########################
# End of Driver Detection #
#######################################################################
# At this point, I know OS version and whether or not there are
# pseudo-HBA drivers loaded
if [[ "${HBA_DETECT_FLAG}" -eq 0 ]]; then
# I can exit because no drivers were found
case "${OUTPUT_MODE}" in
0) echo -e "\n${BOLD_TEXT}${MAGENTA_BLACK}No IBM vSCSI drivers are loaded${ALL_OFF}\n" ;;
1) OUTPUT='No IBM vSCSI HBA Drivers detected'
echo -e "\n${OUTPUT}\n"
echo -e "\n${OUTPUT}\n" >> ${SETUP_LOG}
echo -e "\n${OUTPUT}\n" >> ${TMP_FILE}
;;
2) # Decomm mode - nothing else to do
exit 255
;;
3) # Check Mode - Abort because I'm running where I should not be
# NOTE: Append to $CHECK_FILE, do not overwrite, as I have put
# in REPORT_DATE by now
echo 'ABORT=1' >> ${CHECK_FILE}
_log_script_message 'Abort - No pseudo-HBA drivers found'
exit 255
;;
# No output for other modes
esac
# No drivers so we exit here if not before
exit
else
# Drivers were found - if in proper OUTPUT_MODE and data was
# requested, give name(s) and version(s)
if [[ "${KERNEL}" == 'YES' ]]; then
case "${OUTPUT_MODE}" in
0) if [[ "${HBA_DETECT_FLAG}" -eq 1 ]]; then
NOUN='driver'
else
NOUN='drivers'
fi
echo -e "\n\tDetected ${HBA_DETECT_FLAG} IBM vSCSI HBA ${NOUN}:\n"
echo -e "${BOLD_TEXT}\t_Name___\tVersion_____\tDescription_____________________${ALL_OFF}"
# Only put in separator line if there's more than 2 drivers
for INDEX in $(seq 0 $((${#DRIVER_NAME_ARRAY[@]} - 1))); do
THIS_DRIVER="${DRIVER_NAME_ARRAY[${INDEX}]}"
# Driver version - get from modinfo command
STRIPSTR=$( ${MODINFO_TOOL} ${THIS_DRIVER} | ${GREP_TOOL} -m 1 version | ${AWK_TOOL} -F ': ' '{ print $2 }' )
# Make sure to strip leading spaces
DRIVER_VERSION=$( echo ${STRIPSTR} | ${SED_TOOL} -e 's/^[ \t]*//' )
# Driver description - get from modinfo command
STRIPSTR=$( ${MODINFO_TOOL} ${THIS_DRIVER} | ${GREP_TOOL} -m 1 description | ${AWK_TOOL} -F ': ' '{print $2}' )
# Make sure to strip leading spaces
DRIVER_DESCRIPTION=$( echo ${STRIPSTR} | ${SED_TOOL} -e 's/^[ \t]*//' )
# Adjust output formatting for long driver names
if [[ "${#THIS_DRIVER}" -ge 8 ]]; then
THIS_DRIVER="${THIS_DRIVER}\t"
else
THIS_DRIVER="${THIS_DRIVER}\t\t"
fi
# Output results
echo -e "\t${THIS_DRIVER}${DRIVER_VERSION}\t\t${DRIVER_DESCRIPTION}"
done
# End of for INDEX in $(seq 0 $((${#DRIVER_NAME_ARRAY[@]} - 1)))
# Blank line for spacing between this and next section
echo
;;
1) # Build a list of drive names for later output
HBA_DRIVERS_FOUND=''
for INDEX in $(seq 0 $((${#DRIVER_NAME_ARRAY[@]} - 1))); do
THIS_DRIVER="${DRIVER_NAME_ARRAY[${INDEX}]}"
if [[ "${HBA_DRIVERS_FOUND}" == '' ]]; then
HBA_DRIVERS_FOUND="${THIS_DRIVER}"
else
HBA_DRIVERS_FOUND="${HBA_DRIVERS_FOUND} ${THIS_DRIVER}"
fi
done
;;
3) # I seem to be OK in Check Mode
echo 'ABORT=0' >> ${CHECK_FILE}
echo '# Number of IBM-supplied kernel driver modules found (should be 1 or 2; otherwise, investigate)' >> ${CHECK_FILE}
echo "DRIVER_COUNT=${HBA_DETECT_FLAG}" >> ${CHECK_FILE}
;;
# No output for other modes
esac
# End of case "${OUTPUT_MODE}"
else
if [[ "${OUTPUT_MODE}" -eq 0 ]]; then
# Blank line for spacing between this and next section
echo
fi
fi
# End of if [[ "${KERNEL}" == 'YES' ]]
fi
# End of if [[ "${HBA_DETECT_FLAG}" -eq 0 ]]
# Initialize counter for total number of HBAs
TOTAL_HBA_COUNT=0
ACTIVE_HBA_LIST=''
# Init a counter of ALL HBA ports that have Link
HBA_LINK_COUNT=0
#######################################################################
# HBA Detection and Analysis # REAL WORK STARTS HERE
##############################
# Examine the system closely, looking for HBA ports - which are really
# virtualized HBAs delivered by a VIO
# Only after the pseudo-HBAs have been detected and analyzed will
# Multipathing and/or LUN Analysis occur (depending on command-line
# parameters)
#################
# HBA Detection #
#################
# Remember that in BASH, Arrays index from 0
declare -a BOARD_NAME_ARRAY
declare -a BOARD_PORT_ARRAY
declare -a PORT_STATE_ARRAY
CURRENT_PORT=0
LAST_PORT=-1
# I need to create a SORTED list of directories in ${HBA_NODE}, with
# names "host*" - it's hard to use traditional sorting techniques
# because "host10" and "host1" always end up next to each other in
# the list, and "host9" is at the other end. To address this, I do
# it in two (2) stages, by first looking for directories in the form
# "host??" (which finds 10-99) and then separately for "host?" (which
# finds 0-9) - each one will be sorted consistently within its own
# range, and I can concatenate the lists into one
HOST_DIR_LIST=''
CHKSTR=$( ${LS_TOOL} -d ${HBA_NODE}/host?? 2>&1 )
# LS_TOOL will return 0 if there were matches
RETVAL=$?
if [[ "${RETVAL}" -eq 0 ]]; then
HOST_DIR_LIST="${CHKSTR}"
fi
CHKSTR=$( ${LS_TOOL} -d ${HBA_NODE}/host? 2>&1 )
# LS_TOOL will return 0 if there were matches
RETVAL=$?
if [[ "${RETVAL}" -eq 0 ]]; then
if [[ "${HOST_DIR_LIST}" == '' ]]; then
HOST_DIR_LIST="${CHKSTR}"
else
HOST_DIR_LIST="${CHKSTR} ${HOST_DIR_LIST}"
fi
fi
if [[ "${__DEBUG}" == 'YES' ]]; then
echo "HOST_DIR_LIST is ${HOST_DIR_LIST}"
fi
# HOST_DIR_LIST now only contains those directories that I can
# reasonably be sure are associated with the VIO-provided Virtual
# HBAs (pseudo-HBAs)
# When displaying, I want to use the name of the VIO delivering the
# NPIV connections as my aggregator (similar to how I used the
# physical "board" in the prior version of this tool)
# First, I build a list of the VIOs providing devices; also count
# how many pseudo-HBAs there are in total
VIO_NAME_LIST=''
# Count of VIO-provided HBAs and their ports
HBA_BOARD_COUNT=0
HBA_PORT_COUNT=0
for VIO_DEVICE in ${HOST_DIR_LIST}; do
# I need extract which specific "hostX" sub-dir the device is in,
# so I can subsequenty look under HBA_FIND for info; I need the
# last field of the string
HOST_PATH=$( echo ${VIO_DEVICE} | ${AWK_TOOL} -F '/' '{ print $NF }' )
# The variable should now hold something like "host1"
# Increment our port count
(( HBA_PORT_COUNT = HBA_PORT_COUNT + 1 ))
# Now I get the name of the VIO providing this specific pseudo-HBA
VIO_NAME=$( ${CAT_TOOL} ${HBA_FIND}/${HOST_PATH}/${HBA_VIO_FILE} )
# Make sure I only add an HBA to the list once
if [[ "${VIO_NAME_LIST}" == '' ]]; then
VIO_NAME_LIST="${VIO_NAME}"
(( HBA_BOARD_COUNT = HBA_BOARD_COUNT + 1 ))
else
# Data is already in the list, make sure VIO_NAME is not
# already in it
VIO_SKIP_FLAG=0
for CHECK_NAME in ${VIO_NAME_LIST}; do
if [[ "${CHECK_NAME}" == "${VIO_NAME}" ]]; then
# This VIO is already in the list
VIO_SKIP_FLAG=1
break
fi
done
# If VIO_SKIP_FLAG is still 0, then I can add it to the list
if [[ "${VIO_SKIP_FLAG}" -eq 0 ]]; then
# Not in the list - add it
VIO_NAME_LIST="${VIO_NAME_LIST} ${VIO_NAME}"
# Also increment our "board" count
(( HBA_BOARD_COUNT = HBA_BOARD_COUNT + 1 ))
else
# Already in the list
continue
fi
fi
# End of if [[ "${VIO_NAME_LIST}" == '' ]]; then
done
# End of for VIO_DEVICE in ${HOST_DIR_LIST}
# VIO_NAME_LIST now contains a space-separated list of names of all the
# VIOs that provide pseudo-HBAs to this LPAR
# HBA_BOARD_COUNT should contain an integer equal to the number of VIOs
# in the list
# HBA_PORT_COUNT should contain an integer equal to or greater than
# HBA_BOARD_COUNT and equal to the total number of pseudo-HBAs
case "${OUTPUT_MODE}" in
0) if [[ "${QUICK}" != 'YES' ]]; then
echo -e "\tThere are ${BOLD_TEXT}${HBA_BOARD_COUNT}${ALL_OFF} VIOs providing this system with a total of ${BOLD_TEXT}${HBA_PORT_COUNT}${ALL_OFF} virtual ports"
fi
;;
1) OUTPUT="\tThere are ${HBA_BOARD_COUNT} VIOs providing virtual HBAs in this system (Drivers: ${HBA_DRIVERS_FOUND})"
echo -e "${OUTPUT}\n"
echo -e "${OUTPUT}\n" >> ${SETUP_LOG}
echo -e "${OUTPUT}\n" >> ${TMP_FILE}
;;
3) echo '# Number of VIOs providing pseudo HBAs to this host (should be 2)' >> ${CHECK_FILE}
echo "VIO_COUNT=${HBA_BOARD_COUNT}" >> ${CHECK_FILE}
;;
# No output for other modes
esac
# I aggregate our data display by VIO, so I go through VIO_NAME_LIST
# and retrieve data for each pseudo-HBA; I only do this in
# OUTPUT_MODE 0 (normal) or 1 (Setup)
if [[ "${OUTPUT_MODE}" -eq 0 || "${OUTPUT_MODE}" -eq 1 ]]; then
for VIO_NAME in ${VIO_NAME_LIST}; do
# VIO_NAME now contains the name of the specific VIO I want to
# look for; cycle through the list of pseudo-HBA devices
FOUND_VIO=0
for VIO_DEVICE in ${HOST_DIR_LIST}; do
# I need extract which specific "hostX" sub-dir the device is in,
# so I can subsequenty look under HBA_FIND for info; I need the
# last field of the string
HOST_PATH=$( echo ${VIO_DEVICE} | ${AWK_TOOL} -F '/' '{ print $NF }' )
# The variable should now hold something like "host1"
# Now I get the name of the VIO providing this specific
# pseudo-HBA
CHECK_NAME=$( ${CAT_TOOL} ${HBA_FIND}/${HOST_PATH}/${HBA_VIO_FILE} )
# If it does NOT match VIO_NAME, then skip to next loop
if [[ "${CHECK_NAME}" != "${VIO_NAME}" ]]; then
continue
else
# If this is the first pseudo-HBA I found for this VIO,
# then output a header line
if [[ "${FOUND_VIO}" -eq 0 ]]; then
if [[ "${OUTPUT_MODE}" -eq 0 ]]; then
PORT_INFO=$( ${CAT_TOOL} ${HBA_FIND}/${HOST_PATH}/${HBA_PORT_FILE} )
echo -e "\n\t${BOLD_TEXT}${VIO_NAME}${ALL_OFF} (${PORT_INFO:0:26})\n"
echo -e "\t\t${BOLD_TEXT}Port\tWWPN\t\t\tState\tSpeed\tVIO Device${ALL_OFF}"
else
# Reduced output in Setup Mode
OUTPUT="\t\t\t\t${VIO_NAME}"
echo -e "${OUTPUT}"
echo -e "${OUTPUT}" >> ${SETUP_LOG}
echo -e "${OUTPUT}" >> ${TMP_FILE}
OUTPUT="\tPORT\tWWPN\tState\VIO Device"
echo -e "${OUTPUT}"
echo -e "${OUTPUT}" >> ${SETUP_LOG}
echo -e "${OUTPUT}" >> ${TMP_FILE}
OUTPUT="\t===\t=======================\t====\t========"
echo -e "${OUTPUT}"
echo -e "${OUTPUT}" >> ${SETUP_LOG}
echo -e "${OUTPUT}" >> ${TMP_FILE}
fi
FOUND_VIO=1
fi
# End of if [[ "${FOUND_VIO}" -eq 0 ]]
# Display info about this specific pseudo-HBA
# The "Port" is the same as the last character of HOST_PATH
THIS_PORT="${HOST_PATH:(-1)}"
# The WWPN I can get from HBA_NODE, but I'll need to remove the
# leading 2 characters and format it using _render_wwpn_func
THIS_WWPN=$( ${CAT_TOOL} ${HBA_NODE}/${HOST_PATH}/${HBA_WWPN_FILE} )
RAW_WWPN="${THIS_WWPN:2}"
_render_wwpn_func
# The result is in WWPN
PORT_STATE_STRING=$( ${CAT_TOOL} ${HBA_NODE}/${HOST_PATH}/${HBA_STATE_FILE} )
if [[ "${PORT_STATE_STRING}" == 'Online' ]]; then
if [[ "${OUTPUT_MODE}" -eq 0 ]]; then
PORT_STATE="${BOLD_TEXT} UP${ALL_OFF}"
else
PORT_STATE=' UP'
fi
if [[ "${ACTIVE_HBA_LIST}" == '' ]]; then
ACTIVE_HBA_LIST="${THIS_PORT}"
else
ACTIVE_HBA_LIST="${ACTIVE_HBA_LIST} ${THIS_PORT}"
fi
PORT_SPEED=$( ${CAT_TOOL} ${HBA_NODE}/${HOST_PATH}/${HBA_SPEED_FILE} )
if [[ "${OUTPUT_MODE}" -eq 0 ]]; then
PORT_SPEED="${BOLD_TEXT}${PORT_SPEED}${ALL_OFF}"
fi
else
PORT_STATE='DOWN'
PORT_SPEED='N/A'
fi
PORT_VIO_DEVICE=$( ${CAT_TOOL} ${HBA_FIND}/${HOST_PATH}/${HBA_VFCHOST_FILE} )
if [[ "${OUTPUT_MODE}" -eq 0 ]]; then
echo -e "\t\t${BOLD_TEXT}${THIS_PORT}\t${WWPN}${ALL_OFF}\t${PORT_STATE}\t${PORT_SPEED}\t${PORT_VIO_DEVICE}"
else
# Reduced output in Setup Mode
OUTPUT="${THIS_PORT}\t${WWPN}\t${PORT_STATE}\t${PORT_SPEED}\t${PORT_VIO_DEVICE}"
fi
fi
# End of if [[ "${CHECK_NAME}" != "${VIO_NAME}" ]]
done
# End of for VIO_DEVICE in ${HOST_DIR_LIST}
done
# End of for VIO_NAME in ${VIO_NAME_LIST}
fi
# End of if [[ "${OUTPUT_MODE}" -eq 0 || "${OUTPUT_MODE}" -eq 1 ]]
########################
# End of HBA Detection #
#######################################################################
(( TOTAL_HBA_COUNT = HBA_PORT_COUNT ))
case "${OUTPUT_MODE}" in
0) if [[ "${QUICK}" == 'YES' ]]; then
echo -e "\n\tA total of ${BOLD_TEXT}${TOTAL_HBA_COUNT}${ALL_OFF} VIO-provided HBA Ports were detected"
fi
;;
1) OUTPUT="A total of ${TOTAL_HBA_COUNT} VIO-provided HBA Ports were detected"
echo -e "${OUTPUT}\n"
echo -e "${OUTPUT}\n" >> ${SETUP_LOG}
echo -e "${OUTPUT}\n" >> ${TMP_FILE}
;;
3) echo '# Number of pseudo-HBA ports (that is, paths) provided to this host (should be 4)' >> ${CHECK_FILE}
echo "ACTIVE_PORT_COUNT=${HBA_PORT_COUNT}" >> ${CHECK_FILE}
;;
# No output in other modes
esac
#####################################
# End of HBA Detection and Analysis #
#######################################################################
#######################################################################
# SAN LUN Detection and Multipath Analysis #
############################################
# Only do this if we have Privilege
if [[ "${SKIP_LUN}" -eq 1 && "${OUTPUT_MODE}" -eq 0 ]]; then
# Not Privileged (or in Decomm or Setup Mode)
echo -e "${BOLD_TEXT}${MAGENTA_BLACK}\tSkipping SAN LUN Detection and Multipath Analysis - Not Privileged${ALL_OFF}" ;;
else
# Privileged - get a list of LUNs under DM Multipathing
# Note that this code branch will be entered only if OUTPUT_MODE is
# either 0, 2 or 3, even if the process is Privileged
case "${SLES_VERSION}" in
12|15)
# Look for kernel module
CHKSTR=$( ${LISTMOD_TOOL} | ${GREP_TOOL} -c dm_multipath )
if [[ "${CHKSTR}" -eq 0 ]]; then
# No kernel module loaded; create an empty file to trigger
# logic below
${TOUCH_TOOL} ${MULTIPATH_EXEC_OUTPUT}
else
if [[ -x "${MULTIPATH_EXEC}" ]]; then
# Record MP utility output to file
${MULTIPATH_EXEC} > ${MULTIPATH_EXEC_OUTPUT}
else
# Create an empty file to trigger logic below
${TOUCH_TOOL} ${MULTIPATH_EXEC_OUTPUT}
fi
fi
;;
#XX) FUTURE EXPANSION
# ;;
esac
SINGLE_PATH_WARNING_FLAG=0
# If output file is not empty, check for multipath config
# file mistakes
if [[ -s "${MULTIPATH_EXEC_OUTPUT}" ]]; then
CHKSTR=$( ${GREP_TOOL} -m 1 -c 'duplicate keyword' ${MULTIPATH_EXEC_OUTPUT} )
if [[ "${CHKSTR}" -eq 1 ]]; then
# There is a duplicate keyword in the configuration file
case "${OUTPUT_MODE}" in
0) echo -e "\n\t${BOLD_TEXT}${MAGENTA_BLACK}WARNING:${ALL_OFF} ${BOLD_TEXT}Detected duplicate keyword in /etc/multipath.conf or /etc/multipath/conf.d/*${ALL_OFF}\n" ;;
3) echo '# Flag to indicate if the multipath config reports a "duplicate keyword" error (0=no error; 1=found this problem)' >> ${CHECK_FILE}
echo 'MULTIPATH_CONFIG_WARNING=1' >> ${CHECK_FILE}
;;
# No output in other modes
esac
# Rewrite my temporary file to omit that line, which should
# avoid logic problems below
${MULTIPATH_EXEC} | ${GREP_TOOL} -v 'duplicate keyword' > ${MULTIPATH_EXEC_OUTPUT}
else
# If in Check Mode, write out info saying that multipath.conf
# is OK
if [[ "${OUTPUT_MODE}" -eq 3 ]]; then
echo '# Flag to indicate if the multipath config reports a "duplicate keyword" error (0=no error; 1=found this problem)' >> ${CHECK_FILE}
echo 'MULTIPATH_CONFIG_WARNING=0' >> ${CHECK_FILE}
fi
fi
# End of if [[ "${CHKSTR}" -eq 1 ]]
fi
# End of if [[ -s "${MULTIPATH_EXEC_OUTPUT}" ]]
# If output file is not empty, try to analyze SAN paths present under
# DM Multipathing
if [[ -s "${MULTIPATH_EXEC_OUTPUT}" ]]; then
case "${OUTPUT_MODE}" in
0) echo -e "\n\tDetecting SAN LUNs and analyzing Multipathing:\n"
echo -e "${BOLD_TEXT}\t LUN\t\t LUN\t\tNumber of Paths${ALL_OFF}"
# The composition of the rest of the header depends on if
# the user requested LUN serial numbers
if [[ "${SERIALS}" == 'YES' ]]; then
echo -e "${BOLD_TEXT}\t_Name__\t\tSize_(GB) Detected___Failed _SAN_Vendor_\t________Serial_Number____________${ALL_OFF}"
SEPARATOR="\t---------------------------------------------------------------------------------------------------------"
else
echo -e "${BOLD_TEXT}\t_Name__\t\tSize_(GB) Detected___Failed _SAN_Vendor_${ALL_OFF}"
SEPARATOR="\t--------------------------------------------------------------------------------"
fi
;;
3) # Check Mode - init some variables for loop below
LUNS_WITH_MULTIPLE_FAILED_PATHS=0
LUNS_WITH_SINGLE_FAILED_PATH=0
LUNS_WITH_SINGLE_PATH=0
;;
# No output in other modes
esac
TOTAL_LUN_SIZE=0
LUN_SERIAL_LIST=''
NO_LUN_PATH=0
# Count of LUNs with failed path
FAILED_PATH_LUNS=0
# List of LUN names that have a failed path
FAILED_PATH_LUN_LIST=''