Skip to content

Instantly share code, notes, and snippets.

@xiansu
Last active February 26, 2021 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xiansu/3d81fdd57ac360625c21 to your computer and use it in GitHub Desktop.
Save xiansu/3d81fdd57ac360625c21 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Please send questions or comments to Xian Su <xianwsu@gmail.com>
[[ $UID != 0 ]] && echo get root && exit 1
[[ ! $BASH_VERSION =~ ^[45] ]] && echo needs bash v4+ && exit 1
if [[ $(which smartctl 2>/dev/null) ]]; then
serial () { smartctl -i /dev/$device | awk -F '[ -]' '/^Serial.[nN]umber/{print $NF}'; }
elif [[ $(which sg_inq 2>/dev/null) ]]; then
serial () { sg_inq /dev/$device | awk '/Unit.serial.number/{print substr($NF,match($NF,"-")+1)}'; }
else
echo you need either udevadm or smartctl from package smartmontools or sg_inq from package sg3_utils on rhel, sg3-utils on debian && exit 1
fi
while [[ $1 ]]; do
case $1 in
"-u") export udev=1;;
"-v") export verbose=1;;
"-q") export quiet=1;;
"-b") shift; onlybp=$1;;
"-l") shift; locate=( $locate $1 );;
"-n") shift; locoff=( $locoff $1 );;
*) printf "usage: $0 -u -q -v -b \$ID -l \$DEVICE -n \$DEVICE\n\t-u: use udev to query serial (wwn)\n\t-q: do not draw backplane\n\t-v: show detailed device information\n\t-b: only show backplane matching id\n\t-l: toggle LED on for serial, device or scsi addr\n\t-n: toggle LED off for serial, device or scsi addr\n"; exit 0;;
esac
shift
done
[[ $udev ]] && [[ $(which udevadm 2>/dev/null) ]] && serial () { udevadm info --query=property --name=/dev/$device | awk '/^ID_SERIAL_SHORT/{s=substr($NF,17); print substr(s,match(s,"-")+1)}'; }
export TERM=xterm
red=$(tput setaf 1)
wht=$(tput sgr0)
declare -A drive color
populate () {
device=$(ls $enclosure/"$slot"*/device/block/ 2>/dev/null)
if [[ -b /dev/$device ]]; then
serial=$(serial)
hbtlun=$(ls $enclosure/"$slot"*/device/scsi_disk)
[[ ${#serial} -gt $maxlength ]] && maxlength=${#serial}
[[ $locate ]] && for i in $device $serial $hbtlun; do for j in ${locate[*]}; do [[ $i == $j ]] && echo 1 > $enclosure/"$slot"*/locate && sleep .3; done; done
[[ $locoff ]] && for i in $device $serial $hbtlun; do for j in ${locoff[*]}; do [[ $i == $j ]] && echo 0 > $enclosure/"$slot"*/locate && sleep .3; done; done
[[ $verbose ]] && echo -e "$backplane/R${r}C${c}\t$slot\t$device\t$serial\t$hbtlun"
grep -q 1 $enclosure/"$slot"*/locate && color["$backplane:$B:R${r}C${c}"]=$red
drive["$backplane:$B:R${r}C${c}"]=$serial
fi
}
walkbp () {
maxlength=3
for ((r=1;r<=R;r++)); do for ((c=1;c<=C;c++)); do
case $M in
"UR") slot=$(printf "%s%${D}d%s" "$H" $((c*R-r+A)) "$T");;
"DR") slot=$(printf "%s%${D}d%s" "$H" $((c*R-R+r-1+A)) "$T");;
"RU") slot=$(printf "%s%${D}d%s" "$H" $((R*C-C*r+c-1+A)) "$T");;
"UR-456") if [[ $c == 1 ]]; then
case $r in
[123]) slot="" && drive["$backplane:$B:R${r}C${c}"]="PSU";;
[456]) slot=$(printf "%s%${D}d%s" "$H" $((c*R-r+A)) "$T");;
esac
else
slot=$(printf "%s%${D}d%s" "$H" $((c*R-r+A-3)) "$T")
fi;;
esac
[[ $slot ]] && populate
done; done
}
drawbp () {
printf "╔"; for ((c=1;c<=C;c++)); do printf "%0.s═" $(seq $((maxlength+2))); printf "╤"; done; printf "\b╗\n"
for ((r=1;r<=R;r++)); do printf "║"; for ((c=1;c<=C;c++)); do printf " ${color["$backplane:$B:R${r}C${c}"]}%${maxlength}s${wht} │" "${drive["$backplane:$B:R${r}C${c}"]}"; done; printf "\b║\n"; done
printf "╚"; for ((c=1;c<=C;c++)); do printf "%0.s═" $(seq $((maxlength+2))); printf "╧"; done; printf "\b╝\n\n"
}
b () {
B=$1; M=$2; R=$3; C=$4; A=$5; H=$6; T=$7; D=02; [[ $8 ]] && D=$8
walkbp
[[ ! $quiet ]] && drawbp
}
for enclosure in /sys/class/enclosure/*; do
components=0
[[ -r $enclosure/device/model ]] && model=$(cat $enclosure/device/model) || continue
[[ ! -z $onlybp ]] && [[ ! $(cat $enclosure/id) =~ $onlybp ]] && continue
backplane=${enclosure/*\//}
printf "$backplane: $model $(cat $enclosure/id)\n"
case $model in
"SAS3x40 ") b 0 UR 6 4 0 "Slot" "";; #supermicro 3.5" haven't yet seen 16/21 bay sas3
"SAS3x28 ") b 0 UR 3 4 0 "Slot" "";;
"SAS2X36 ") components=$(cat $enclosure/components)
case $components in
24) b 0 UR 6 4 1 "Slot " "";;
16) b 0 UR 4 4 1 "Slot " "";;
21) b 0 UR-456 6 4 1 "Slot " "";;
esac;;
"SAS2X28 ") b 0 UR 3 4 1 "Slot " "";;
"SASX36 A.1 ") b 0 UR 6 4 0 "0" "";; #supermicro 3.5" haven't yet seen 16/21 bay sas1
"SASX28 A.1 ") b 0 UR 3 4 0 "0" "";;
"Cobra ") b 0 DR 3 4 0 "Connector" "";; #celestica 3.5" 2u/12bay still have components=16
"X5-2L ") b 0 RU 3 4 0 "HDD" "" #oracle x5-2l
b 1 RU 1 2 0 "RHDD" "" 1;;
"LYNX-H ") b 0 DR 24 1 1 "Drive Slot #" "_" 1;; #celestica 2.5"
"Bobcat ") b 0 DR 24 1 0 "ArrayDevice" "";; #celestica 2.5"
"BARBADOS ") b 0 DR 12 5 0 "Slot " "" 2;; #jabil
"NDS-4600-JD ") b 0 DR 12 5 1 "SLOT " " " 2;; #newisys
"R0904-F0001-01 ") b 0 DR 12 5 0 "Drive Slot #" "_" 1;; #? viren
*) printf "unknown model\n\n";;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment