diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2019-03-27 14:20:06 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2019-03-27 14:20:06 +0000 |
commit | 8c86fe26b4e371af1fd007d076025a5d5e442f42 (patch) | |
tree | 9cd95360880722899016f22397bc5a7a64bde112 | |
parent | 072494ad0074ea42df51c8d44608fd63215dac15 (diff) | |
download | sg3_utils-8c86fe26b4e371af1fd007d076025a5d5e442f42.tar.gz |
library: add to '.so' name; rescan-scsi-bus: multiple patches to sync with Suse
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@815 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | doc/rescan-scsi-bus.sh.8 | 4 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/Makefile.in | 2 | ||||
-rw-r--r-- | scripts/58-scsi-sg3_symlink.rules | 4 | ||||
-rwxr-xr-x | scripts/rescan-scsi-bus.sh | 608 | ||||
-rwxr-xr-x | scripts/scsi-enable-target-scan.sh | 15 |
7 files changed, 345 insertions, 294 deletions
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and some description at the top of its ".c" file. All utilities in the main directory have their own "man" pages. There is also a sg3_utils man page. -Changelog for sg3_utils-1.45 [20190325] [svn: r814] +Changelog for sg3_utils-1.45 [20190327] [svn: r815] - sg_ses: bug: --page= being overridden when --control and --data= also given; fix - sg_opcodes: expand MLU (spc5r20) @@ -18,11 +18,13 @@ Changelog for sg3_utils-1.45 [20190325] [svn: r814] - sg_lib: add sg_t10_uuid_desig2str() - tweak sg_pt interface to better handle bidi - sg_cmds_process_resp(): two arguments removed + - add ${PACKAGE_VERSION} to '.so' name - sg_pt_freebsd: fixes for FreeBSD 12.0 release - scripts/scsi-sg3_id: update rules - linux: add nanosecond durations when SG3_UTILS_LINUX_NANO environment variable given - rescan-scsi-bus: widen LUN 0 only scanning + - multiple patches to sync with Suse - testing/sg_tst_async: fix free_list issue - testing/sg_tst_ioctl: for sg 4.0 driver - testing/sg_tst_bidi: for sg 4.0 driver diff --git a/doc/rescan-scsi-bus.sh.8 b/doc/rescan-scsi-bus.sh.8 index 4435c7d9..fa93fcfa 100644 --- a/doc/rescan-scsi-bus.sh.8 +++ b/doc/rescan-scsi-bus.sh.8 @@ -40,10 +40,10 @@ enable debug [default: 0] flush failed multipath devices [default: disabled] .TP \fB\-\-forceremove\fR -remove and readd every device (DANGEROUS) +remove stale devices (DANGEROUS) .TP \fB\-\-forcerescan\fR -rescan existing devices +remove and readd existing devices (DANGEROUS) .TP \fB\-h\fR, \fB\-\-help\fR print usage message then exit diff --git a/lib/Makefile.am b/lib/Makefile.am index f90fed95..75cc071f 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -63,7 +63,7 @@ AM_CFLAGS = -Wall -W $(DBG_CFLAGS) lib_LTLIBRARIES = libsgutils2.la -libsgutils2_la_LDFLAGS = -version-info 2:0:0 -no-undefined +libsgutils2_la_LDFLAGS = -version-info 2:0:0 -no-undefined -release ${PACKAGE_VERSION} libsgutils2_la_LIBADD = @GETOPT_O_FILES@ libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@ diff --git a/lib/Makefile.in b/lib/Makefile.in index 1b28ad22..b6781258 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -368,7 +368,7 @@ AM_CFLAGS = -Wall -W $(DBG_CFLAGS) # AM_CFLAGS = -Wall -W -pedantic -std=c++14 # AM_CFLAGS = -Wall -W -pedantic -std=c++1z lib_LTLIBRARIES = libsgutils2.la -libsgutils2_la_LDFLAGS = -version-info 2:0:0 -no-undefined +libsgutils2_la_LDFLAGS = -version-info 2:0:0 -no-undefined -release ${PACKAGE_VERSION} libsgutils2_la_LIBADD = @GETOPT_O_FILES@ libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@ all: all-am diff --git a/scripts/58-scsi-sg3_symlink.rules b/scripts/58-scsi-sg3_symlink.rules index 2e8dd961..7c193089 100644 --- a/scripts/58-scsi-sg3_symlink.rules +++ b/scripts/58-scsi-sg3_symlink.rules @@ -3,9 +3,7 @@ ACTION=="remove", GOTO="sg3_utils_symlink_end" SUBSYSTEM!="block", GOTO="sg3_utils_symlink_end" - -# Skip symlink generation for multipath -ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="sg3_utils_symlink_end" +ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="sg3_utils_symlink_end" # Select which identifier to use per default # 0: vpd page 0x80 identifier diff --git a/scripts/rescan-scsi-bus.sh b/scripts/rescan-scsi-bus.sh index a2aa8d81..a708df9a 100755 --- a/scripts/rescan-scsi-bus.sh +++ b/scripts/rescan-scsi-bus.sh @@ -16,7 +16,7 @@ setcolor () norm="\e[0;0m" } -unsetcolor () +unsetcolor () { red=""; green="" yellow=""; norm="" @@ -24,7 +24,7 @@ unsetcolor () echo_debug() { - if [ $debug -eq 1 ] ; then + if [ "$debug" -eq 1 ] ; then echo "$1" fi } @@ -38,9 +38,9 @@ print_and_scroll_back () LN=${#STRG} BK="" declare -i cntr=0 - while test $cntr -lt $LN; do BK="$BK\e[D"; let cntr+=1; done + while [ $cntr -lt "$LN" ] ; do BK="$BK\e[D"; let cntr+=1; done echo -en "$STRG$BK" - return $LN + return "$LN" } # Overwrite a text of length $LN with whitespace @@ -48,33 +48,33 @@ white_out () { BK=""; WH="" declare -i cntr=0 - while test $cntr -lt $LN; do BK="$BK\e[D"; WH="$WH "; let cntr+=1; done + while [ $cntr -lt "$LN" ] ; do BK="$BK\e[D"; WH="$WH "; let cntr+=1; done echo -en "$WH$BK" } # Return hosts. sysfs must be mounted findhosts_26 () { - hosts=`find /sys/class/scsi_host/host* -maxdepth 4 -type d -o -type l 2> /dev/null | awk -F'/' '{print $5}' | sed -e 's~host~~' | sort -nu` - scsi_host_data=`echo "$hosts" | sed -e 's~^~/sys/class/scsi_host/host~'` - for hostdir in $scsi_host_data; do + hosts= + for hostdir in /sys/class/scsi_host/host* ; do + [ -e "$hostdir" ] || continue hostno=${hostdir#/sys/class/scsi_host/host} - if [ -f $hostdir/isp_name ] ; then + if [ -f "$hostdir/isp_name" ] ; then hostname="qla2xxx" - elif [ -f $hostdir/lpfc_drvr_version ] ; then + elif [ -f "$hostdir/lpfc_drvr_version" ] ; then hostname="lpfc" else - hostname=`cat $hostdir/proc_name` + hostname=$(cat "$hostdir/proc_name") fi - #hosts="$hosts $hostno" + hosts="$hosts $hostno" echo_debug "Host adapter $hostno ($hostname) found." - done + done if [ -z "$hosts" ] ; then echo "No SCSI host adapters found in sysfs" exit 1; fi # Not necessary just use double quotes around variable to preserve new lines - #hosts=`echo $hosts | tr ' ' '\n'` + #hosts=$(echo $hosts | tr ' ' '\n') } # Return hosts. /proc/scsi/HOSTADAPTER/? must exist @@ -83,13 +83,13 @@ findhosts () hosts= for driverdir in /proc/scsi/*; do driver=${driverdir#/proc/scsi/} - if test $driver = scsi -o $driver = sg -o $driver = dummy -o $driver = device_info; then continue; fi + if [ "$driver" = scsi ] || [ "$driver" = sg ] || [ "$driver" = dummy ] || [ "$driver" = device_info ] ; then continue; fi for hostdir in $driverdir/*; do name=${hostdir#/proc/scsi/*/} - if test $name = add_map -o $name = map -o $name = mod_parm; then continue; fi + if [ "$name" = add_map ] || [ "$name" = map ] || [ "$name" = mod_parm ] ; then continue; fi num=$name driverinfo=$driver - if test -r "$hostdir/status"; then + if [ -r "$hostdir/status" ] ; then num=$(printf '%d\n' "$(sed -n 's/SCSI host number://p' "$hostdir/status")") driverinfo="$driver:$name" fi @@ -125,7 +125,7 @@ printtype () print02i() { - if [ "$1" = "*" ] ; then + if [ "$1" = "*" ] ; then echo "00" else printf "%02i" "$1" @@ -133,30 +133,34 @@ print02i() } # Get /proc/scsi/scsi info for device $host:$channel:$id:$lun -# Optional parameter: Number of lines after first (default = 2), +# Optional parameter: Number of lines after first (default = 2), # result in SCSISTR, return code 1 means empty. procscsiscsi () -{ - if test -z "$1"; then LN=2; else LN=$1; fi - CHANNEL=`print02i "$channel"` - ID=`print02i "$id"` - LUN=`print02i "$lun"` +{ + if [ -z "$1" ] ; then + LN=2 + else + LN=$1 + fi + CHANNEL=$(print02i "$channel") + ID=$(print02i "$id") + LUN=$(print02i "$lun") if [ -d /sys/class/scsi_device ]; then SCSIPATH="/sys/class/scsi_device/${host}:${channel}:${id}:${lun}" if [ -d "$SCSIPATH" ] ; then SCSISTR="Host: scsi${host} Channel: $CHANNEL Id: $ID Lun: $LUN" if [ "$LN" -gt 0 ] ; then - IVEND=$(cat ${SCSIPATH}/device/vendor) - IPROD=$(cat ${SCSIPATH}/device/model) - IPREV=$(cat ${SCSIPATH}/device/rev) + IVEND=$(cat "${SCSIPATH}/device/vendor") + IPROD=$(cat "${SCSIPATH}/device/model") + IPREV=$(cat "${SCSIPATH}/device/rev") SCSIDEV=$(printf ' Vendor: %-08s Model: %-16s Rev: %-4s' "$IVEND" "$IPROD" "$IPREV") SCSISTR="$SCSISTR $SCSIDEV" fi if [ "$LN" -gt 1 ] ; then - ILVL=$(cat ${SCSIPATH}/device/scsi_level) - type=$(cat ${SCSIPATH}/device/type) - ITYPE=$(printtype $type) + ILVL=$(cat "${SCSIPATH}/device/scsi_level") + type=$(cat "${SCSIPATH}/device/type") + ITYPE=$(printtype "$type") SCSITMP=$(printf ' Type: %-17s ANSI SCSI revision: %02d' "$ITYPE" "$((ILVL - 1))") SCSISTR="$SCSISTR $SCSITMP" @@ -168,7 +172,11 @@ $SCSITMP" grepstr="scsi$host Channel: $CHANNEL Id: $ID Lun: $LUN" SCSISTR=$(grep -A "$LN" -e "$grepstr" /proc/scsi/scsi) fi - if test -z "$SCSISTR"; then return 1; else return 0; fi + if [ -z "$SCSISTR" ] ; then + return 1 + else + return 0 + fi } # Find sg device with 2.6 sysfs support @@ -177,24 +185,24 @@ sgdevice26 () local gendev gendev=/sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device/generic - if test -e "$gendev"; then + if [ -e "$gendev" ] ; then SGDEV=$(basename "$(readlink "$gendev")") else for SGDEV in /sys/class/scsi_generic/sg*; do - DEV=`readlink $SGDEV/device` - if test "${DEV##*/}" = "$host:$channel:$id:$lun"; then - SGDEV=`basename $SGDEV`; return + DEV=$(readlink "$SGDEV/device") + if [ "${DEV##*/}" = "$host:$channel:$id:$lun" ] ; then + SGDEV=$(basename "$SGDEV"); return fi done SGDEV="" - fi + fi } # Find sg device with 2.4 report-devs extensions sgdevice24 () { if procscsiscsi 3; then - SGDEV=`echo "$SCSISTR" | grep 'Attached drivers:' | sed 's/^ *Attached drivers: \(sg[0-9]*\).*/\1/'` + SGDEV=$(echo "$SCSISTR" | grep 'Attached drivers:' | sed 's/^ *Attached drivers: \(sg[0-9]*\).*/\1/') fi } @@ -203,15 +211,15 @@ sgdevice24 () sgdevice () { SGDEV= - if test -d /sys/class/scsi_device; then + if [ -d /sys/class/scsi_device ] ; then sgdevice26 - else - DRV=`grep 'Attached drivers:' /proc/scsi/scsi 2>/dev/null` + else + DRV=$(grep 'Attached drivers:' /proc/scsi/scsi 2>/dev/null) repdevstat=$((1-$?)) if [ $repdevstat = 0 ]; then echo "scsi report-devs 1" >/proc/scsi/scsi - DRV=`grep 'Attached drivers:' /proc/scsi/scsi 2>/dev/null` - if [ $? = 1 ]; then return; fi + DRV=$(grep 'Attached drivers:' /proc/scsi/scsi 2>/dev/null) + [ $? -eq 1 ] && return fi if ! echo "$DRV" | grep -q 'drivers: sg'; then modprobe sg @@ -234,8 +242,7 @@ is_removable () p=/sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device/inquiry # Extract the second byte of the INQUIRY response and check bit 7 (mask 0x80). - b=$(od -tx1 -j1 -N1 "$p" 2>/dev/null | - { read -r offset byte rest; echo -n "$byte"; }) + b=$(hexdump -n1 -e '/1 "%02X"' "$p" 2>/dev/null) if [ -n "$b" ]; then echo $(((0x$b & 0x80) != 0)) else @@ -258,16 +265,21 @@ testonline () # Set default values IPTYPE=31 IPQUAL=3 - if test ! -x /usr/bin/sg_turs; then return 0; fi + [ ! -x /usr/bin/sg_turs ] && return 0 sgdevice - if test -z "$SGDEV"; then return 0; fi + [ -z "$SGDEV" ] && return 0 sg_turs /dev/$SGDEV >/dev/null 2>&1 RC=$? # Handle in progress of becoming ready and unit attention - while test $RC = 2 -o $RC = 6 && test $ctr -le 30; do - if test $RC = 2 -a "$RMB" != "1"; then echo -n "."; let LN+=1; sleep 1 - else sleep 0.02; fi + while [ $RC = 2 -o $RC = 6 ] && [ $ctr -le 30 ] ; do + if [ $RC = 2 ] && [ "$RMB" != "1" ] ; then + echo -n "." + let LN+=1 + sleep 1 + else + sleep 0.02 + fi let ctr+=1 sg_turs /dev/$SGDEV >/dev/null 2>&1 RC=$? @@ -275,25 +287,27 @@ testonline () # fail for a removable device with no medium RMB=$(is_removable) print_and_scroll_back "$host:$channel:$id:$lun $SGDEV ($RMB) " - test $RC = 2 -a "$RMB" = "1" && break + [ $RC = 2 ] && [ "$RMB" = "1" ] && break done - if test $ctr != 0; then white_out; fi + if [ $ctr != 0 ] ; then + white_out + fi # echo -e "\e[A\e[A\e[A${yellow}Test existence of $SGDEV = $RC ${norm} \n\n\n" - if test $RC = 1; then return $RC; fi + [ $RC = 1 ] && return $RC # Reset RC (might be !=0 for passive paths) RC=0 # OK, device online, compare INQUIRY string - INQ=`sg_inq $sg_len_arg /dev/$SGDEV 2>/dev/null` + INQ=$(sg_inq "$sg_len_arg" /dev/$SGDEV 2>/dev/null) if [ -z "$INQ" ] ; then echo -e "\e[A\e[A\e[A\e[A${red}$SGDEV changed: ${bold}INQUIRY failed${norm} \n\n\n" return 2 fi - IVEND=`echo "$INQ" | grep 'Vendor identification:' | sed 's/^[^:]*: \(.*\)$/\1/'` - IPROD=`echo "$INQ" | grep 'Product identification:' | sed 's/^[^:]*: \(.*\)$/\1/'` - IPREV=`echo "$INQ" | grep 'Product revision level:' | sed 's/^[^:]*: \(.*\)$/\1/'` - STR=`printf " Vendor: %-08s Model: %-16s Rev: %-4s" "$IVEND" "$IPROD" "$IPREV"` - IPTYPE=`echo "$INQ" | sed -n 's/.* Device_type=\([0-9]*\) .*/\1/p'` - IPQUAL=`echo "$INQ" | sed -n 's/ *PQual=\([0-9]*\) Device.*/\1/p'` + IVEND=$(echo "$INQ" | grep 'Vendor identification:' | sed 's/^[^:]*: \(.*\)$/\1/') + IPROD=$(echo "$INQ" | grep 'Product identification:' | sed 's/^[^:]*: \(.*\)$/\1/') + IPREV=$(echo "$INQ" | grep 'Product revision level:' | sed 's/^[^:]*: \(.*\)$/\1/') + STR=$(printf " Vendor: %-08s Model: %-16s Rev: %-4s" "$IVEND" "$IPROD" "$IPREV") + IPTYPE=$(echo "$INQ" | sed -n 's/.* Device_type=\([0-9]*\) .*/\1/p') + IPQUAL=$(echo "$INQ" | sed -n 's/ *PQual=\([0-9]*\) Device.*/\1/p') if [ "$IPQUAL" != 0 ] ; then [ -z "$IPQUAL" ] && IPQUAL=3 [ -z "$IPTYPE" ] && IPTYPE=31 @@ -306,22 +320,25 @@ testonline () echo -e "\e[A\e[A\e[A\e[A${red}$SGDEV removed.\n\n\n" return 2 fi - TMPSTR=`echo "$SCSISTR" | grep 'Vendor:'` - if test $ignore_rev -eq 0 ; then + TMPSTR=$(echo "$SCSISTR" | grep 'Vendor:') + if [ "$ignore_rev" -eq 0 ] ; then if [ "$TMPSTR" != "$STR" ]; then echo -e "\e[A\e[A\e[A\e[A${red}$SGDEV changed: ${bold}\nfrom:${SCSISTR#* } \nto: $STR ${norm} \n\n\n" return 1 fi else # Ignore disk revision change - local old_str_no_rev=`echo "$TMPSTR" | sed -e 's/.\{4\}$//'` - local new_str_no_rev=`echo "$STR" | sed -e 's/.\{4\}$//'` + local old_str_no_rev= + local new_str_no_rev= + + old_str_no_rev=${TMPSTR%Rev:*} + new_str_no_rev=${STR%Rev:*} if [ "$old_str_no_rev" != "$new_str_no_rev" ]; then echo -e "\e[A\e[A\e[A\e[A${red}$SGDEV changed: ${bold}\nfrom:${SCSISTR#* } \nto: $STR ${norm} \n\n\n" return 1 fi fi - TMPSTR=`echo "$SCSISTR" | sed -n 's/.*Type: *\(.*\) *ANSI.*/\1/p' | sed 's/ *$//g'` + TMPSTR=$(echo "$SCSISTR" | sed -n 's/.*Type: *\(.*\) *ANSI.*/\1/p' | sed 's/ *$//g') if [ "$TMPSTR" != "$TYPE" ] ; then echo -e "\e[A\e[A\e[A\e[A${red}$SGDEV changed: ${bold}\nfrom:${TMPSTR} \nto: $TYPE ${norm} \n\n\n" return 1 @@ -336,7 +353,7 @@ testexist () { : testexist SCSISTR= - if procscsiscsi && test -z "$1"; then + if procscsiscsi && [ -z "$1" ] ; then echo "$SCSISTR" | head -n1 echo "$SCSISTR" | tail -n2 | pr -o4 -l1 fi @@ -351,20 +368,22 @@ chanlist () local tmpchan for dev in /sys/class/scsi_device/${host}:* ; do - [ -d $dev ] || continue; + [ -d "$dev" ] || continue; hcil=${dev##*/} cil=${hcil#*:} chan=${cil%%:*} for tmpchan in $channelsearch ; do - if test "$chan" -eq $tmpchan ; then + if [ "$chan" -eq "$tmpchan" ] ; then chan= fi done - if test -n "$chan" ; then + if [ -n "$chan" ] ; then channelsearch="$channelsearch $chan" fi done - if test -z "$channelsearch"; then channelsearch="0"; fi + if [ -z "$channelsearch" ] ; then + channelsearch="0" + fi } # Returns the list of existing targets per host @@ -374,33 +393,30 @@ idlist () local newid local oldid - oldlist=$(ls /sys/class/scsi_device/ | sed -n "s/${host}:${channel}:\([0-9]*:[0-9]*\)/\1/p" | uniq) + oldlist=$(find /sys/class/scsi_device -name "${host}:${channel}:*" -printf "%f\n") # Rescan LUN 0 to check if we found new targets - echo "${channel} - -" > /sys/class/scsi_host/host${host}/scan - newlist=$(ls /sys/class/scsi_device/ | sed -n "s/${host}:${channel}:\([0-9]*:[0-9]*\)/\1/p" | uniq) + echo "${channel} - -" > "/sys/class/scsi_host/host${host}/scan" + newlist=$(find /sys/class/scsi_device -name "${host}:${channel}:*" -printf "%f\n") for newid in $newlist ; do oldid=$newid for tmpid in $oldlist ; do - if test $newid = $tmpid ; then + if [ "$newid" = "$tmpid" ] ; then oldid= break fi done - if test -n "$oldid" ; then - id=${oldid%%:*} - lun=${oldid##*:} - dev=/sys/class/scsi_device/${host}:${channel}:${id}:${lun} - if [ -d $dev ] ; then - hcil=${dev##*/} - printf "\r${green}NEW: $norm" + if [ -n "$oldid" ] ; then + if [ -d /sys/class/scsi_device/$oldid ] ; then + hcil=${oldid} + printf "\r${green}NEW: %s" "$norm" testexist - if test "$SCSISTR" ; then + if [ "$SCSISTR" ] ; then incrfound "$hcil" fi fi fi done - idsearch=$(ls /sys/class/scsi_device/ | sed -n "s/${host}:${channel}:\([0-9]*\):[0-9]*/\1/p" | uniq) + idsearch=$(find /sys/bus/scsi/devices -name "target${host}:${channel}:*" -printf "%f\n" | cut -f 3 -d :) } # Returns the list of existing LUNs from device $host $channel $id $lun @@ -408,19 +424,25 @@ idlist () getluns() { sgdevice - if test -z "$SGDEV"; then return 1; fi - if test ! -x /usr/bin/sg_luns; then echo 0; return 1; fi - LLUN=`sg_luns /dev/$SGDEV 2>/dev/null | sed -n 's/ \(.*\)/\1/p'` + [ -z "$SGDEV" ] && return 1 + if [ ! -x /usr/bin/sg_luns ] ; then + echo 0 + return 1 + fi + LLUN=$(sg_luns /dev/$SGDEV 2>/dev/null | sed -n 's/ \(.*\)/\1/p') # Added -z $LLUN condition because $? gets the RC from sed, not sg_luns - if test $? != 0 -o -z "$LLUN"; then echo 0; return 1; fi + if [ $? -ne 0 ] || [ -z "$LLUN" ] ; then + echo 0 + return 1 + fi for lun in $LLUN ; do # Swap LUN number l0=0x$lun - l1=$(( ($l0 >> 48) & 0xffff )) - l2=$(( ($l0 >> 32) & 0xffff )) - l3=$(( ($l0 >> 16) & 0xffff )) - l4=$(( $l0 & 0xffff )) - l0=$(( ( ( ($l4 * 0xffff) + $l3 ) * 0xffff + $l2 ) * 0xffff + $l1 )) + l1=$(( (l0 >> 48) & 0xffff )) + l2=$(( (l0 >> 32) & 0xffff )) + l3=$(( (l0 >> 16) & 0xffff )) + l4=$(( l0 & 0xffff )) + l0=$(( ( ( (l4 * 0xffff) + l3 ) * 0xffff + l2 ) * 0xffff + l1 )) printf "%u\n" $l0 done return 0 @@ -430,7 +452,7 @@ getluns() udevadm_settle() { local tmo=60 - if test -x /sbin/udevadm; then + if [ -x /sbin/udevadm ] ; then print_and_scroll_back " Calling udevadm settle (can take a while) " # Loop for up to 60 seconds if sd devices still are settling.. # This allows us to continue if udev events are stuck on multipaths in recovery mode @@ -441,7 +463,7 @@ udevadm_settle() let tmo=$tmo-1 done white_out - elif test -x /sbin/udevsettle; then + elif [ -x /sbin/udevsettle ] ; then print_and_scroll_back " Calling udevsettle (can take a while) " /sbin/udevsettle white_out @@ -454,31 +476,33 @@ udevadm_settle() dolunscan() { local remappedlun0= + local devpath SCSISTR= devnr="$host $channel $id $lun" echo -e " Scanning for device $devnr ... " - printf "${yellow}OLD: $norm" + printf "${yellow}OLD: %s" "$norm" testexist # Device exists: Test whether it's still online # (testonline returns 2 if it's gone and 1 if it has changed) - if test "$SCSISTR" ; then + devpath="/sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device" + if [ "$SCSISTR" ] ; then testonline RC=$? # Well known lun transition case. Only for Direct-Access devs (type 0) # If block directory exists && and PQUAL != 0, we unmapped lun0 and just have a well-known lun # If block directory doesn't exist && PQUAL == 0, we mapped a real lun0 - if test $lun -eq 0 -a $IPTYPE -eq 0 ; then - if test $RC = 2 ; then - if test -e /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device; then - if test -d /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device/block ; then + if [ "$lun" -eq 0 ] && [ $IPTYPE -eq 0 ] ; then + if [ $RC = 2 ] ; then + if [ -e "$devpath" ] ; then + if [ -d "$devpath/block" ] ; then remappedlun0=2 # Transition from real lun 0 to well-known else RC=0 # Set this so the system leaves the existing well known lun alone. This is a lun 0 with no block directory fi fi - elif test $RC = 0 -a $IPTYPE -eq 0; then - if test -e /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device; then - if test ! -d /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device/block ; then + elif [ $RC = 0 ] && [ $IPTYPE -eq 0 ] ; then + if [ -e "$devpath" ] ; then + if [ ! -d "$devpath/block" ] ; then remappedlun0=1 # Transition from well-known to real lun 0 fi fi @@ -488,72 +512,73 @@ dolunscan() # Special case: lun 0 just got added (for reportlunscan), # so make sure we correctly treat it as new - if test "$lun" = "0" -a "$1" = "1" -a -z "$remappedlun0"; then + if [ "$lun" = "0" ] && [ "$1" = "1" ] && [ -z "$remappedlun0" ] ; then SCSISTR="" printf "\r\e[A\e[A\e[A" fi - : f $remove s $SCSISTR - if test "$remove" -a "$SCSISTR" -o "$remappedlun0" = "1"; then - if test $RC != 0 -o ! -z "$forceremove" -o -n "$remappedlun0"; then - if test "$remappedlun0" != "1" ; then + : f "$remove" s $SCSISTR + if [ "$remove" ] && [ "$SCSISTR" -o "$remappedlun0" = "1" ] ; then + if [ $RC != 0 ] || [ ! -z "$forceremove" ] || [ -n "$remappedlun0" ] ; then + if [ "$remappedlun0" != "1" ] ; then echo -en "\r\e[A\e[A\e[A${red}REM: " echo "$SCSISTR" | head -n1 echo -e "${norm}\e[B\e[B" fi - if test -e /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device; then + if [ -e "$devpath" ] ; then # have to preemptively do this so we can figure out the mpath device # Don't do this if we're deleting a well known lun to replace it - if test "$remappedlun0" != "1" ; then + if [ "$remappedlun0" != "1" ] ; then incrrmvd "$host:$channel:$id:$lun" fi - echo 1 > /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device/delete + echo 1 > "$devpath/delete" sleep 0.02 else echo "scsi remove-single-device $devnr" > /proc/scsi/scsi - if test $RC -eq 1 -o $lun -eq 0 ; then + if [ $RC -eq 1 ] || [ "$lun" -eq 0 ] ; then # Try readding, should fail if device is gone echo "scsi add-single-device $devnr" > /proc/scsi/scsi fi fi fi - if test $RC = 0 -o "$forcerescan" ; then - if test -e /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device; then - echo 1 > /sys/class/scsi_device/${host}:${channel}:${id}:${lun}/device/rescan + if [ $RC = 0 ] || [ "$forcerescan" ] ; then + if [ -e "$devpath" ] ; then + echo 1 > "$devpath/rescan" fi fi - printf "\r\e[A\e[A\e[A${yellow}OLD: $norm" + printf "\r\e[A\e[A\e[A${yellow}OLD: %s" "$norm" testexist - if test -z "$SCSISTR" -a $RC != 1 -a "$remappedlun0" != "1"; then - printf "\r${red}DEL: $norm\r\n\n" + if [ -z "$SCSISTR" ] && [ $RC != 1 ] && [ "$remappedlun0" != "1" ] ; then + printf "\r${red}DEL: %s\r\n\n" "$norm" # In the event we're replacing with a well known node, we need to let it continue, to create the replacement node - test "$remappedlun0" != "2" && return 1 + [ "$remappedlun0" != "2" ] && return 2 fi fi - if test -z "$SCSISTR" -o -n "$remappedlun0"; then - if test "$remappedlun0" != "2" ; then + if [ -z "$SCSISTR" ] || [ -n "$remappedlun0" ] ; then + if [ "$remappedlun0" != "2" ] ; then # Device does not exist, try to add - printf "\r${green}NEW: $norm" + printf "\r${green}NEW: %s" "$norm" fi - if test -e /sys/class/scsi_host/host${host}/scan; then - echo "$channel $id $lun" > /sys/class/scsi_host/host${host}/scan 2> /dev/null + if [ -e "/sys/class/scsi_host/host${host}/scan" ] ; then + echo "$channel $id $lun" > "/sys/class/scsi_host/host${host}/scan" 2> /dev/null else echo "scsi add-single-device $devnr" > /proc/scsi/scsi fi testexist - if test -z "$SCSISTR"; then + if [ -z "$SCSISTR" ] ; then # Device not present printf "\r\e[A"; # Optimization: if lun==0, stop here (only if in non-remove mode) - if test $lun = 0 -a -z "$remove" -a $optscan = 1; then - break; + if [ "$lun" = 0 ] && [ -z "$remove" ] && [ "$optscan" = 1 ] ; then + return 1; fi - else - if test "$remappedlun0" != "2" ; then + else + if [ "$remappedlun0" != "2" ] ; then incrfound "$host:$channel:$id:$lun" fi fi fi + return 0; } # Perform report lun scan on $host $channel $id using REPORT_LUNS @@ -564,20 +589,20 @@ doreportlun() devnr="$host $channel $id $lun" echo -en " Scanning for device $devnr ...\r" lun0added= - #printf "${yellow}OLD: $norm" + #printf "${yellow}OLD: %s" "$norm" # Phase one: If LUN0 does not exist, try to add testexist -q - if test -z "$SCSISTR"; then + if [ -z "$SCSISTR" ] ; then # Device does not exist, try to add - #printf "\r${green}NEW: $norm" - if test -e /sys/class/scsi_host/host${host}/scan; then - echo "$channel $id $lun" > /sys/class/scsi_host/host${host}/scan 2> /dev/null + #printf "\r${green}NEW: %s" "$norm" + if [ -e "/sys/class/scsi_host/host${host}/scan" ] ; then + echo "$channel $id $lun" > "/sys/class/scsi_host/host${host}/scan" 2> /dev/null udevadm_settle else echo "scsi add-single-device $devnr" > /proc/scsi/scsi fi testexist -q - if test -n "$SCSISTR"; then + if [ -n "$SCSISTR" ] ; then lun0added=1 #testonline else @@ -591,29 +616,29 @@ doreportlun() done fi fi - targetluns=`getluns` + targetluns=$(getluns) REPLUNSTAT=$? lunremove= #echo "getluns reports " $targetluns - olddev=`find /sys/class/scsi_device/ -name "$host:$channel:$id:*" 2>/dev/null | sort -t: -k4 -n` + olddev=$(find /sys/class/scsi_device/ -name "$host:$channel:$id:*" 2>/dev/null | sort -t: -k4 -n) oldtargets="$targetluns" # OK -- if we don't have a LUN to send a REPORT_LUNS to, we could # fall back to wildcard scanning. Same thing if the device does not # support REPORT_LUNS - # TODO: We might be better off to ALWAYS use wildcard scanning if + # TODO: We might be better off to ALWAYS use wildcard scanning if # it works - if test "$REPLUNSTAT" = "1"; then - if test -e /sys/class/scsi_host/host${host}/scan; then - echo "$channel $id -" > /sys/class/scsi_host/host${host}/scan 2> /dev/null + if [ "$REPLUNSTAT" = "1" ] ; then + if [ -e "/sys/class/scsi_host/host${host}/scan" ] ; then + echo "$channel $id -" > "/sys/class/scsi_host/host${host}/scan" 2> /dev/null udevadm_settle else echo "scsi add-single-device $host $channel $id $SCAN_WILD_CARD" > /proc/scsi/scsi fi - targetluns=`find /sys/class/scsi_device/ -name "$host:$channel:$id:*" 2>/dev/null | awk -F'/' '{print $5}' | awk -F':' '{print $4}' | sort -n` - let found+=`echo "$targetluns" | wc -l` - let found-=`echo "$olddev" | wc -l` + targetluns=$(find /sys/class/scsi_device/ -name "$host:$channel:$id:*" -printf "%f\n" | cut -d : -f 4) + let found+=$(echo "$targetluns" | wc -l) + let found-=$(echo "$olddev" | wc -l) fi - if test -z "$targetluns"; then targetluns="$oldtargets"; fi + [ -z "$targetluns" ] && targetluns="$oldtargets" # Check existing luns for dev in $olddev; do [ -d "$dev" ] || continue @@ -622,73 +647,76 @@ doreportlun() inlist= # OK, is existing $lun (still) in reported list for tmplun in $targetluns; do - if test $tmplun -eq $lun ; then + if [ "$tmplun" = "$lun" ] ; then inlist=1 dolunscan $lun0added + [ $? -eq 1 ] && break else newsearch="$newsearch $tmplun" fi done - # OK, we have now done a lunscan on $lun and + # OK, we have now done a lunscan on $lun and # $newsearch is the old $targetluns without $lun if [ -z "$inlist" ]; then # Stale lun lunremove="$lunremove $lun" fi - # $lun removed from $lunsearch (echo for whitespace cleanup) - targetluns=`echo $newsearch` + # $lun removed from $lunsearch + targetluns=${newsearch# } done # Add new ones and check stale ones for lun in $targetluns $lunremove; do dolunscan $lun0added + [ $? -eq 1 ] && break done } # Perform search (scan $host) dosearch () { - if test -z "$channelsearch" ; then + if [ -z "$channelsearch" ] ; then chanlist fi for channel in $channelsearch; do - if test -z "$idsearch" ; then - if test -z "$lunsearch" ; then + if [ -z "$idsearch" ] ; then + if [ -z "$lunsearch" ] ; then idlist else - idsearch=$(ls /sys/class/scsi_device/ | sed -n "s/${host}:${channel}:\([0-9]*\):[0-9]*/\1/p" | uniq) + idsearch=$(find /sys/bus/scsi/devices -name "target${host}:${channel}:*" -printf "%f\n" | cut -f 3 -d :) fi fi for id in $idsearch; do - if test -z "$lunsearch" ; then + if [ -z "$lunsearch" ] ; then doreportlun else for lun in $lunsearch; do dolunscan + [ $? -eq 1 ] && break done fi done done } - + expandlist () { list=$1 result="" first=${list%%,*} rest=${list#*,} - while test ! -z "$first"; do + while [ ! -z "$first" ] ; do beg=${first%%-*}; - if test "$beg" = "$first"; then + if [ "$beg" = "$first" ] ; then result="$result $beg"; else end=${first#*-} - result="$result `seq $beg $end`" + result="$result $(seq $beg $end)" fi - test "$rest" = "$first" && rest="" + [ "$rest" = "$first" ] && rest="" first=${rest%%,*} rest=${rest#*,} done - echo $result + echo "$result" } searchexisting() @@ -696,29 +724,30 @@ searchexisting() local tmpch; local tmpid local match=0 - local targets=`ls -d /sys/class/scsi_device/$host:* 2> /dev/null | egrep -o $host:[0-9]+:[0-9]+ | sort | uniq` + local targets= + targets=$(find /sys/bus/scsi/devices -name "target${host}:*" -printf "%f\n" | cut -d : -f 2-3) # Nothing came back on this host, so we should skip it - test -z "$targets" && return + [ -z "$targets" ] && return local target=; for target in $targets ; do - channel=`echo $target | cut -d":" -f2` - id=`echo $target | cut -d":" -f 3` + channel=${target%:*} + id=${target#*:} if [ -n "$channelsearch" ] ; then for tmpch in $channelsearch ; do - test $tmpch -eq $channel && match=1 + [ $tmpch -eq "$channel" ] && match=1 done else match=1 fi - test $match -eq 0 && continue + [ $match -eq 0 ] && continue match=0 - if [ $filter_ids -eq 1 ] ; then + if [ "$filter_ids" -eq 1 ] ; then for tmpid in $idsearch ; do - if [ $tmpid -eq $id ] ; then + if [ "$tmpid" = "$id" ] ; then match=1 fi done @@ -726,13 +755,14 @@ searchexisting() match=1 fi - test $match -eq 0 && continue + [ $match -eq 0 ] && continue if [ -z "$lunsearch" ] ; then doreportlun else for lun in $lunsearch ; do dolunscan + [ $? -eq 1 ] && break done fi done @@ -742,24 +772,26 @@ searchexisting() findremapped() { local hctl=; - local devs=`ls /sys/class/scsi_device/` + local devs= local sddev= local id_serial= local id_serial_old= local remapped= mpaths="" - local tmpfile=$(mktemp /tmp/rescan-scsi-bus.XXXXXXXX 2> /dev/null) + local tmpfile= + tmpfile=$(mktemp /tmp/rescan-scsi-bus.XXXXXXXX 2> /dev/null) if [ -z "$tmpfile" ] ; then tmpfile="/tmp/rescan-scsi-bus.$$" rm -f $tmpfile fi # Get all of the ID_SERIAL attributes, after finding their sd node + devs=$(ls /sys/class/scsi_device/) for hctl in $devs ; do - if [ -d /sys/class/scsi_device/$hctl/device/block ] ; then - sddev=`ls /sys/class/scsi_device/$hctl/device/block` - id_serial_old=`udevadm info -q all -n $sddev | grep "ID_SERIAL=" | cut -d"=" -f2` + if [ -d "/sys/class/scsi_device/$hctl/device/block" ] ; then + sddev=$(ls "/sys/class/scsi_device/$hctl/device/block") + id_serial_old=$(udevadm info -q all -n "$sddev" | grep "ID_SERIAL=" | cut -d"=" -f2) [ -z "$id_serial_old" ] && id_serial_old="none" echo "$hctl $sddev $id_serial_old" >> $tmpfile fi @@ -772,9 +804,9 @@ findremapped() echo "Done" # See what changed and reload the respective multipath device if applicable - while read hctl sddev id_serial_old ; do + while read -r hctl sddev id_serial_old ; do remapped=0 - id_serial=`udevadm info -q all -n $sddev | grep "ID_SERIAL=" | cut -d"=" -f2` + id_serial=$(udevadm info -q all -n "$sddev" | grep "ID_SERIAL=" | cut -d"=" -f2) [ -z "$id_serial" ] && id_serial="none" if [ "$id_serial_old" != "$id_serial" ] ; then remapped=1 @@ -782,7 +814,7 @@ findremapped() # If udev events updated the disks already, but the multipath device isn't update # check for old devices to make sure we found remapped luns if [ -n "$mp_enable" ] && [ $remapped -eq 0 ]; then - findmultipath $sddev $id_serial + findmultipath "$sddev" $id_serial if [ $? -eq 1 ] ; then remapped=1 fi @@ -793,18 +825,18 @@ findremapped() if [ "$id_serial" = "1" ] || [ $remapped -eq 0 ] ; then continue fi - printf "${yellow}REMAPPED: $norm" - host=`echo $hctl | cut -d":" -f1` - channel=`echo $hctl | cut -d":" -f2` - id=`echo $hctl | cut -d":" -f3` - lun=`echo $hctl | cut -d":" -f4` + printf "${yellow}REMAPPED: %s" "$norm" + host=$(echo "$hctl" | cut -d":" -f1) + channel=$(echo "$hctl" | cut -d":" -f2) + id=$(echo "$hctl" | cut -d":" -f3) + lun=$(echo "$hctl" | cut -d":" -f4) procscsiscsi echo "$SCSISTR" incrchgd "$hctl" done < $tmpfile rm -f $tmpfile - if test -n "$mp_enable" -a -n "$mpaths" ; then + if [ -n "$mp_enable" ] && [ -n "$mpaths" ] ; then echo "Updating multipath device mappings" flushmpaths $MULTIPATH | grep "create:" 2> /dev/null @@ -814,7 +846,7 @@ findremapped() incrfound() { local hctl="$1" - if test -n "$hctl" ; then + if [ -n "$hctl" ] ; then let found+=1 FOUNDDEVS="$FOUNDDEVS\t[$hctl]\n" else @@ -825,8 +857,8 @@ incrfound() incrchgd() { local hctl="$1" - if test -n "$hctl" ; then - if ! echo $CHGDEVS | grep -q "\[$hctl\]"; then + if [ -n "$hctl" ] ; then + if ! echo "$CHGDEVS" | grep -q "\[$hctl\]"; then let updated+=1 CHGDEVS="$CHGDEVS\t[$hctl]\n" fi @@ -834,9 +866,11 @@ incrchgd() return fi - if test -n "$mp_enable" ; then - local sdev="`findsddev \"$hctl\"`" - if test -n "$sdev" ; then + if [ -n "$mp_enable" ] ; then + local sdev + + sdev=$(findsddev "$hctl") + if [ -n "$sdev" ] ; then findmultipath "$sdev" fi fi @@ -845,16 +879,18 @@ incrchgd() incrrmvd() { local hctl="$1" - if test -n "$hctl" ; then + if [ -n "$hctl" ] ; then let rmvd+=1; RMVDDEVS="$RMVDDEVS\t[$hctl]\n" else return fi - if test -n "$mp_enable" ; then - local sdev="`findsddev \"$hctl\"`" - if test -n "$sdev" ; then + if [ -n "$mp_enable" ] ; then + local sdev + + sdev=$(findsddev "$hctl") + if [ -n "$sdev" ] ; then findmultipath "$sdev" fi fi @@ -863,16 +899,14 @@ incrrmvd() findsddev() { local hctl="$1" - local sddev= - - if test ! -e /sys/class/scsi_device/$hctl/device/block ; then - return 1 - fi - - sddev=`ls /sys/class/scsi_device/$hctl/device/block` - echo $sddev + local sddev= + local blkpath - return 0 + blkpath="/sys/class/scsi_device/$hctl/device/block" + if [ -e "$blkpath" ] ; then + sddev=$(ls "$blkpath") + echo "$sddev" + fi } addmpathtolist() @@ -896,16 +930,17 @@ findmultipath() local mp= local mp2= local found_dup=0 + local maj_min= # Need a sdev, and executable multipath and dmsetup command here - if [ -z "$dev" ] || [ ! -x $DMSETUP ] || [ ! -x "$MULTIPATH" ] ; then + if [ -z "$dev" ] || [ ! -x "$DMSETUP" ] || [ ! -x "$MULTIPATH" ] ; then return 1 fi - local maj_min=`cat /sys/block/$dev/dev` + maj_min=$(cat "/sys/block/$dev/dev") for mp in $($DMSETUP ls --target=multipath | cut -f 1) ; do [ "$mp" = "No" ] && break; - if $DMSETUP status $mp | grep -q " $maj_min "; then + if "$DMSETUP" status "$mp" | grep -q " $maj_min "; then # With two arguments, look up current uuid from sysfs # if it doesn't match what was passed, this multipath # device is not updated, so this is a remapped LUN @@ -913,14 +948,14 @@ findmultipath() mp2=$($MULTIPATH -l "$mp" | egrep -o "dm-[0-9]+") mp2=$(cut -f2 -d- "/sys/block/$mp2/dm/uuid") if [ "$find_mismatch" != "$mp2" ] ; then - addmpathtolist $mp + addmpathtolist "$mp" found_dup=1 fi continue fi # Normal mode: Find the first multipath with the sdev # and add it to the list - addmpathtolist $mp + addmpathtolist "$mp" return fi done @@ -951,8 +986,7 @@ reloadmpaths() # Reload the multipath devices for mpath in $mpaths ; do echo -n "Reloading multipath device $mpath... " - $MULTIPATH -r $mpath > /dev/null 2>&1 - if test "$?" = "0" ; then + if $MULTIPATH -r "$mpath" > /dev/null 2>&1 ; then echo "Done" else echo "Fail" @@ -978,11 +1012,11 @@ flushmpaths() local i local flush_retries=5 - if test -n "$1" ; then + if [ -n "$1" ] ; then for mpath in $($DMSETUP ls --target=multipath | cut -f 1) ; do [ "$mpath" = "No" ] && break - num=$($DMSETUP status $mpath | awk 'BEGIN{RS=" ";active=0}/[0-9]+:[0-9]+/{dev=1}/A/{if (dev == 1) active++; dev=0} END{ print active }') - if [ $num -eq 0 ] ; then + num=$($DMSETUP status "$mpath" | awk 'BEGIN{RS=" ";active=0}/[0-9]+:[0-9]+/{dev=1}/A/{if (dev == 1) active++; dev=0} END{ print active }') + if [ "$num" -eq 0 ] ; then remove="$remove $mpath" fi done @@ -994,12 +1028,11 @@ flushmpaths() i=0 echo -n "Flushing multipath device $mpath... " while [ $i -lt $flush_retries ] ; do - $DMSETUP message $mpath 0 fail_if_no_path > /dev/null 2>&1 - $MULTIPATH -f $mpath > /dev/null 2>&1 - if test "$?" = "0" ; then + $DMSETUP message "$mpath" 0 fail_if_no_path > /dev/null 2>&1 + if $MULTIPATH -f "$mpath" > /dev/null 2>&1 ; then echo "Done ($i retries)" break - elif test $i -eq $flush_retries ; then + elif [ $i -eq $flush_retries ] ; then echo "Fail" fi sleep 0.02 @@ -1023,28 +1056,28 @@ findresized() declare -a mpathsizes if [ -z "$lunsearch" ] ; then - devs=`ls /sys/class/scsi_device/` + devs=$(ls /sys/class/scsi_device/) else for lun in $lunsearch ; do - devs="$devs `(cd /sys/class/scsi_device/ && ls -d *:${lun})`" + devs="$devs $(cd /sys/class/scsi_device/ && ls -d *:${lun})" done fi for hctl in $devs ; do sysfs_path="/sys/class/scsi_device/$hctl/device" if [ -d "$sysfs_path/block" ] ; then - sddev=`ls $sysfs_path/block` - size=`cat $sysfs_path/block/$sddev/size` + sddev=$(ls "$sysfs_path/block") + size=$(cat "$sysfs_path/block/$sddev/size") - echo 1 > $sysfs_path/rescan - new_size=`cat $sysfs_path/block/$sddev/size` + echo 1 > "$sysfs_path/rescan" + new_size=$(cat "$sysfs_path/block/$sddev/size") if [ "$size" != "$new_size" ] && [ "$size" != "0" ] && [ "$new_size" != "0" ] ; then - printf "${yellow}RESIZED: $norm" - host=`echo $hctl | cut -d":" -f1` - channel=`echo $hctl | cut -d":" -f2` - id=`echo $hctl | cut -d":" -f3` - lun=`echo $hctl | cut -d":" -f4` + printf "${yellow}RESIZED: %s" "$norm" + host=$(echo "$hctl" | cut -d":" -f1) + channel=$(echo "$hctl" | cut -d":" -f2) + id=$(echo "$hctl" | cut -d":" -f3) + lun=$(echo "$hctl" | cut -d":" -f4) procscsiscsi echo "$SCSISTR" @@ -1053,16 +1086,16 @@ findresized() fi done - if test -n "$mp_enable" -a -n "$mpaths" ; then + if [ -n "$mp_enable" ] && [ -n "$mpaths" ] ; then i=0 for m in $mpaths ; do - mpathsizes[$i]="`$MULTIPATH -l $m | egrep -o [0-9]+.[0-9]+[KMGT]`" + mpathsizes[$i]="$($MULTIPATH -l "$m" | egrep -o [0-9]+.[0-9]+[KMGT])" let i=$i+1 done resizempaths i=0 for m in $mpaths ; do - mpathsize="`$MULTIPATH -l $m | egrep -o [0-9\.]+[KMGT]`" + mpathsize="$($MULTIPATH -l "$m" | egrep -o [0-9\.]+[KMGT])" echo "$m ${mpathsizes[$i]} => $mpathsize" let i=$i+1 done @@ -1074,7 +1107,7 @@ CHGDEVS="" RMVDDEVS="" # main -if test @$1 = @--help -o @$1 = @-h -o @$1 = @-?; then +if [ "@$1" = @--help ] || [ "@$1" = @-h ] || [ "@$1" = "@-?" ] ; then echo "Usage: rescan-scsi-bus.sh [options] [host [host ...]]" echo "Options:" echo " -a scan all targets, not just currently existing [default: disabled]" @@ -1106,7 +1139,7 @@ if test @$1 = @--help -o @$1 = @-h -o @$1 = @-?; then echo "--issue-lip: same as -i" echo "--issue-lip-wait=SECS: same as -I" echo "--largelun: Tell kernel to support LUNs > 7 even on SCSI2 devs" - echo "--luns=LIST: Scan only lun(s) in LIST" + echo "--luns=LIST: Scan only lun(s) in LIST" echo "--multipath: same as -m" echo "--nooptscan: don't stop looking for LUNs is 0 is not found" echo "--remove: same as -r" @@ -1125,12 +1158,12 @@ if test @$1 = @--help -o @$1 = @-h -o @$1 = @-?; then exit 0 fi -if test @$1 = @--version -o @$1 = @-V ; then +if [ "@$1" = @--version ] || [ "@$1" = @-V ] ; then echo ${VERSION} exit 0 fi -if test ! -d /sys/class/scsi_host/ -a ! -d /proc/scsi/; then +if [ ! -d /sys/class/scsi_host/ ] && [ ! -d /proc/scsi/ ] ; then echo "Error: SCSI subsystem not active" exit 1 fi @@ -1138,30 +1171,30 @@ fi # Make sure sg is there modprobe sg >/dev/null 2>&1 -if test -x /usr/bin/sg_inq; then +if [ -x /usr/bin/sg_inq ] ; then sg_version=$(sg_inq -V 2>&1 | cut -d " " -f 3) - if test -n "$sg_version"; then + if [ -n "$sg_version" ] ; then sg_ver_maj=${sg_version:0:1} sg_version=${sg_version##?.} - let sg_version+=$((100*$sg_ver_maj)) + let sg_version+=$((100 * sg_ver_maj)) fi sg_version=${sg_version##0.} #echo "\"$sg_version\"" - if [ -z "$sg_version" -o "$sg_version" -lt 70 ] ; then + if [ -z "$sg_version" ] || [ "$sg_version" -lt 70 ] ; then sg_len_arg="-36" else sg_len_arg="--len=36" fi else echo "WARN: /usr/bin/sg_inq not present -- please install sg3_utils" - echo " or rescan-scsi-bus.sh might not fully work." -fi + echo " or rescan-scsi-bus.sh might not fully work." +fi # defaults unsetcolor debug=0 lunsearch= -opt_idsearch=`seq 0 7` +opt_idsearch=$(seq 0 7) filter_ids=0 opt_channelsearch= remove= @@ -1179,7 +1212,7 @@ ignore_rev=0 # Scan options opt="$1" -while test ! -z "$opt" -a -z "${opt##-*}"; do +while [ ! -z "$opt" ] && [ -z "${opt##-*}" ] ; do opt=${opt#-} case "$opt" in a) existing_targets=;; #Scan ALL targets when specified @@ -1188,76 +1221,79 @@ while test ! -z "$opt" -a -z "${opt##-*}"; do f) flush=1 ;; i) lipreset=0 ;; I) shift; lipreset=$opt ;; - l) lunsearch=`seq 0 7` ;; - L) lunsearch=`seq 0 $2`; shift ;; + l) lunsearch=$(seq 0 7) ;; + L) lunsearch=$(seq 0 "$2"); shift ;; m) mp_enable=1 ;; r) remove=1 ;; s) resize=1; mp_enable=1 ;; u) update=1 ;; - w) opt_idsearch=`seq 0 15` ;; + w) opt_idsearch=$(seq 0 15) ;; -alltargets) existing_targets=;; - -attachpq3) scan_flags=$(($scan_flags|0x1000000)) ;; - -channels=*) arg=${opt#-channels=};opt_channelsearch=`expandlist $arg` ;; + -attachpq3) scan_flags=$((scan_flags|0x1000000)) ;; + -channels=*) arg=${opt#-channels=};opt_channelsearch=$(expandlist "$arg") ;; -color) setcolor ;; -flush) flush=1 ;; -forceremove) remove=1; forceremove=1 ;; -forcerescan) remove=1; forcerescan=1 ;; - -hosts=*) arg=${opt#-hosts=}; hosts=`expandlist $arg` ;; - -ids=*) arg=${opt#-ids=}; opt_idsearch=`expandlist $arg` ; filter_ids=1;; + -hosts=*) arg=${opt#-hosts=}; hosts=$(expandlist "$arg") ;; + -ids=*) arg=${opt#-ids=}; opt_idsearch=$(expandlist "$arg") ; filter_ids=1;; -ignore-rev) ignore_rev=1;; -issue-lip) lipreset=0 ;; -issue-lip-wait) lipreset=${opt#-issue-lip-wait=};; - -largelun) scan_flags=$(($scan_flags|0x200)) ;; - -luns=*) arg=${opt#-luns=}; lunsearch=`expandlist $arg` ;; + -largelun) scan_flags=$((scan_flags|0x200)) ;; + -luns=*) arg=${opt#-luns=}; lunsearch=$(expandlist "$arg") ;; -multipath) mp_enable=1 ;; -nooptscan) optscan=0 ;; -nosync) sync=0 ;; -remove) remove=1 ;; - -reportlun2) scan_flags=$(($scan_flags|0x20000)) ;; + -reportlun2) scan_flags=$((scan_flags|0x20000)) ;; -resize) resize=1;; -sparselun) scan_flags=$((scan_flags|0x40)) ;; -sync) sync=2 ;; -update) update=1;; - -wide) opt_idsearch=`seq 0 15` ;; + -wide) opt_idsearch=$(seq 0 15) ;; *) echo "Unknown option -$opt !" ;; esac shift opt="$1" -done +done if [ -z "$hosts" ] ; then - if test -d /sys/class/scsi_host; then + if [ -d /sys/class/scsi_host ] ; then findhosts_26 - else + else findhosts - fi + fi fi -if [ -d /sys/class/scsi_host -a ! -w /sys/class/scsi_host ]; then +if [ -d /sys/class/scsi_host ] && [ ! -w /sys/class/scsi_host ]; then echo "You need to run scsi-rescan-bus.sh as root" exit 2 -fi -if test "$sync" = 1 -a "$remove" = 1; then sync=2; fi -if test "$sync" = 2; then echo "Syncing file systems"; sync; fi -if test -w /sys/module/scsi_mod/parameters/default_dev_flags -a $scan_flags != 0; then - OLD_SCANFLAGS=`cat /sys/module/scsi_mod/parameters/default_dev_flags` - NEW_SCANFLAGS=$(($OLD_SCANFLAGS|$scan_flags)) - if test "$OLD_SCANFLAGS" != "$NEW_SCANFLAGS"; then +fi +[ "$sync" = 1 ] && [ "$remove" = 1 ] && sync=2 +if [ "$sync" = 2 ] ; then + echo "Syncing file systems" + sync +fi +if [ -w /sys/module/scsi_mod/parameters/default_dev_flags ] && [ $scan_flags != 0 ] ; then + OLD_SCANFLAGS=$(cat /sys/module/scsi_mod/parameters/default_dev_flags) + NEW_SCANFLAGS=$((OLD_SCANFLAGS|scan_flags)) + if [ "$OLD_SCANFLAGS" != "$NEW_SCANFLAGS" ] ; then echo -n "Temporarily setting kernel scanning flags from " - printf "0x%08x to 0x%08x\n" $OLD_SCANFLAGS $NEW_SCANFLAGS + printf "0x%08x to 0x%08x\n" "$OLD_SCANFLAGS" "$NEW_SCANFLAGS" echo $NEW_SCANFLAGS > /sys/module/scsi_mod/parameters/default_dev_flags else unset OLD_SCANFLAGS fi -fi +fi DMSETUP=$(which dmsetup) [ -z "$DMSETUP" ] && flush= && mp_enable= MULTIPATH=$(which multipath) [ -z "$MULTIPATH" ] && flush= && mp_enable= echo -n "Scanning SCSI subsystem for new devices" -test -z "$flush" || echo -n ", flush failed multipath devices," -test -z "$remove" || echo -n " and remove devices that have disappeared" +[ -z "$flush" ] || echo -n ", flush failed multipath devices," +[ -z "$remove" ] || echo -n " and remove devices that have disappeared" echo declare -i found=0 declare -i updated=0 @@ -1284,13 +1320,13 @@ elif [ $resize -eq 1 ] ; then else for host in $hosts; do echo -n "Scanning host $host " - if test -e /sys/class/fc_host/host$host ; then + if [ -e "/sys/class/fc_host/host$host" ] ; then # It's pointless to do a target scan on FC issue_lip=/sys/class/fc_host/host$host/issue_lip - if test -e $issue_lip -a $lipreset -ge 0 ; then - echo 1 > $issue_lip 2> /dev/null; + if [ -e "$issue_lip" ] && [ "$lipreset" -ge 0 ] ; then + echo 1 > "$issue_lip" 2> /dev/null; udevadm_settle - [ $lipreset -gt 0 ] && sleep $lipreset + [ "$lipreset" -gt 0 ] && sleep "$lipreset" fi channelsearch= idsearch= @@ -1301,12 +1337,12 @@ else [ -n "$channelsearch" ] && echo -n "channels $channelsearch " echo -n "for " if [ -n "$idsearch" ] ; then - echo -n " SCSI target IDs " $idsearch + echo -n " SCSI target IDs $idsearch" else echo -n " all SCSI target IDs" fi if [ -n "$lunsearch" ] ; then - echo ", LUNs " $lunsearch + echo ", LUNs $lunsearch" else echo ", all LUNs" fi @@ -1317,40 +1353,40 @@ else dosearch fi done - if test -n "$OLD_SCANFLAGS"; then - echo $OLD_SCANFLAGS > /sys/module/scsi_mod/parameters/default_dev_flags + if [ -n "$OLD_SCANFLAGS" ] ; then + echo "$OLD_SCANFLAGS" > /sys/module/scsi_mod/parameters/default_dev_flags fi fi let rmvd_found=$rmvd+$found -if test -n "$mp_enable" -a $rmvd_found -gt 0 ; then +if [ -n "$mp_enable" ] && [ $rmvd_found -gt 0 ] ; then echo "Attempting to update multipath devices..." - if test $rmvd -gt 0 ; then + if [ $rmvd -gt 0 ] ; then udevadm_settle echo "Removing multipath mappings for removed devices if all paths are now failed... " flushmpaths 1 fi - if test $found -gt 0 ; then + if [ $found -gt 0 ] ; then /sbin/udevadm trigger --sysname-match=sd* udevadm_settle if [ -x "$MULTIPATH" ] ; then echo "Trying to discover new multipath mappings for newly discovered devices... " $MULTIPATH | grep "create:" 2> /dev/null fi - fi + fi fi echo "$found new or changed device(s) found. " -if test ! -z "$FOUNDDEVS" ; then - printf "$FOUNDDEVS" +if [ ! -z "$FOUNDDEVS" ] ; then + printf "%s" "$FOUNDDEVS" fi echo "$updated remapped or resized device(s) found." -if test ! -z "$CHGDEVS" ; then - printf "$CHGDEVS" +if [ ! -z "$CHGDEVS" ] ; then + printf "%s" "$CHGDEVS" fi echo "$rmvd device(s) removed. " -if test ! -z "$RMVDDEVS" ; then - printf "$RMVDDEVS" +if [ ! -z "$RMVDDEVS" ] ; then + printf "%s" "$RMVDDEVS" fi # Local Variables: diff --git a/scripts/scsi-enable-target-scan.sh b/scripts/scsi-enable-target-scan.sh new file mode 100755 index 00000000..63bb9afb --- /dev/null +++ b/scripts/scsi-enable-target-scan.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +MODPARM=/sys/module/scsi_mod/parameters +if [ -w "$MODPARM/scan" ] ; then + scan_type=$(cat $MODPARM/scan) + if [ "$scan_type" = "manual" ] ; then + echo sync > $MODPARM/scan + + for shost in /sys/class/scsi_host/host* ; do + echo '- - -' > ${shost}/scan + done + fi +fi |