Last active
February 25, 2022 20:20
-
-
Save akorn/64beb47d0f134556b8cde04e44e41fa8 to your computer and use it in GitHub Desktop.
Query the status of all local SATA/SAS hard drives and summarize in a table; also for disks on hpsa controllers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
# | |
# Copyright (C) 2016, 2022 András Korn. Licensed under the GPL v3. | |
# | |
# Purpose: query the status of all local SATA hard drives and summarize in a table. | |
# | |
# Not complete, but good enough for my own purposes. Patches welcome. | |
typeset -A diskattrs | |
typeset -A diskargs | |
typeset -A hpraid_sg # e.g. hpraid_sg[0]=/dev/sg42 means that ctrl 0 is at /dev/sg42 | |
[[ -e /etc/default/list-disk-status ]] && . /etc/default/list-disk-status | |
# configuration takes the following form: | |
# | |
#diskargs[/dev/sdd]="-d cciss,0 /dev/sg0" | |
#diskargs[/dev/sde]="-d cciss,1 /dev/sg0" | |
# | |
# this means to query /dev/sg0 with '-d cciss,0' instead of /dev/sdd, but | |
# record the attributes obtained as if they were /dev/sdd's. | |
# this bit tries to guess the diskargs if none have been configured: | |
# make sure we have a fixed number of fields; cut out the bits that can contain spaces: | |
lsscsi -g | cut -c 1-30,54- | tr -d '][' | tr : ' ' | grep 'storage *HP' | while read ctrlnum crap crap disknum type brand devnode sgnode; do | |
hpraid_sg[$ctrlnum]=$sgnode | |
found_hpraid=1 | |
done | |
if [[ $found_hpraid = 1 ]]; then | |
# note: lsscsi sometimes prints the wrong device node for hpraid attached disks, which will confuse this script | |
lsscsi -g | cut -c 1-30,54- | tr -d '][' | tr : ' ' | while read ctrlnum crap crap disknum type brand devnode sgnode; do | |
if [[ $type = disk ]] && [[ -n $hpraid_sg[$ctrlnum] ]]; then # this disk is on a hpraid controller | |
[[ -z "$diskargs[$devnode]" ]] && diskargs[$devnode]="-d cciss,$disknum $hpraid_sg[$ctrlnum]" # && echo 'diskargs['$devnode'] set to '"'-d cciss,$disknum $hpraid_sg[$ctrlnum]'" | |
fi | |
done | |
fi | |
# get_smart_attrib attrname disk | |
function get_attrib() { | |
echo -n "${diskattrs[${2}_${1}]:-n/a} " | |
} | |
function get_all_attribs() { | |
{ | |
for disk in /dev/sd? /dev/sd[a-z][a-z](N); do | |
{ | |
smartctl -i --attributes -f brief ${=diskargs[$disk]:-$disk} \ | |
| sed -rn " | |
/^[[:space:]]*[0-9]/{ | |
s/^[[:space:]]*[0-9]*[[:space:]]*/${disk//\//\\/}_/ | |
s/^([^[:space:]]+)[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+([^[:space:]]+)$/\\1 \\2/p | |
} | |
/^Device [Mm]odel:/{ | |
s/^[^:]*:[[:space:]]*// | |
s/ /_/g | |
s/^/${disk//\//\\/}_model /p | |
} | |
/^Serial [Nn]umber:/{ | |
s/^[^:]*:[[:space:]]*// | |
s/^/${disk//\//\\/}_serial /p | |
} | |
/^LU WWN Device Id:/{ | |
s/^[^:]*:[[:space:]]*// | |
s/ //g | |
s/^/${disk//\//\\/}_wwn 0x/p | |
} | |
/^Firmware [Vv]ersion:/{ | |
s/^[^:]*:[[:space:]]*// | |
s/ /_/g | |
s/^/${disk//\//\\/}_fwversion /p | |
} | |
/^User [Cc]apacity:/{ | |
s/^[^:]*:[[:space:]]*// | |
s/.*\\[// | |
s/\\].*// | |
s/ //g | |
s/^/${disk//\//\\/}_capacity /p | |
} | |
/^Sector [Ss]izes:.* bytes logical, .* bytes physical/{ | |
s/^[^:]*:[[:space:]]*// | |
s/([0-9]*) bytes logical, ([0-9]*) bytes physical/${disk//\//\\/}_logicalsector \\1\\n${disk//\//\\/}_physicalsector \\2/p | |
} | |
/^Sector [Ss]ize:.* bytes logical\/physical/{ | |
s/^[^:]*:[[:space:]]*// | |
s@([0-9]*) bytes logical/physical@${disk//\//\\/}_logicalsector \\1\n${disk//\//\\/}_physicalsector \\1@p | |
} | |
/^Rotation [Rr]ate:/{ | |
s/^[^:]*:[[:space:]]*// | |
s/Solid State Device/SSD/ | |
s/ //g | |
s/^/${disk//\//\\/}_rpm /p | |
} | |
" | |
} & | |
done | |
wait | |
} | while read disk_attr val; do | |
diskattrs[${disk_attr}]="$val" | |
done | |
lsscsi | fgrep /dev | while read line; do | |
disk="$line[54,$]" | |
scsiid="${line[1,13]/ */}" | |
disktype="${line[14,21]/ */}" | |
bus="${line[22,30]/ */}" | |
diskattrs[${disk}_scsiid]="$scsiid" | |
diskattrs[${disk}_disktype]="$disktype" | |
diskattrs[${disk}_bus]="$bus" | |
done | |
} | |
get_all_attribs | |
{ | |
if ((found_hpraid)); then | |
echo "[scsi_id] type bus model fw devnode(*) serial cap rpm pend uncorr realloc lsz psz wwn args" | |
else | |
echo "[scsi_id] type bus model fw devnode serial cap rpm pend uncorr realloc lsz psz wwn args" | |
fi | |
for disk in /dev/sd? /dev/sd[a-z][a-z](N); do | |
get_attrib scsiid $disk | |
get_attrib disktype $disk | |
get_attrib bus $disk | |
get_attrib model $disk | |
get_attrib fwversion $disk | |
echo -n "$disk " | |
get_attrib serial $disk | |
get_attrib capacity $disk | |
get_attrib rpm $disk | |
get_attrib Current_Pending_Sector $disk | |
get_attrib Offline_Uncorrectable $disk | |
get_attrib Reallocated_Sector_Ct $disk | |
get_attrib logicalsector $disk | |
get_attrib physicalsector $disk | |
get_attrib wwn $disk | |
echo -n "$diskargs[$disk]" | |
echo | |
done | |
} | column -t | |
((found_hpraid)) && echo "NOTE: devnode detection is based on lsscsi output and unreliable if RAID controllers are used. Most of the rest of the information comes from smartctl (using 'args') and should be reliable." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment