diff --git a/xCAT-genesis-scripts/bin/diskdiscover b/xCAT-genesis-scripts/bin/diskdiscover new file mode 100755 index 000000000..1869f8f68 --- /dev/null +++ b/xCAT-genesis-scripts/bin/diskdiscover @@ -0,0 +1,435 @@ +#!/bin/bash +# +# Usage: +# +# This script is to discover disk devices. +# +# Input parameter : or nothing +# +# Output : disk and RAID arrys information +# +# Examples: +# 1. When PCI_ID value is 1014:034a, execute "diskdiscover 1014:034a", the output format is as following: +# +# PCI_ID=1014:034a +# ---------------------------------------------------------------------------- +# PCI_SLOT_NAME Resource_Path Device Description Status +# ------------- ------------- ------ ----------- --------------------------- +# 0001:08:00.0 0:0:0:0 sg0 0 Array Member Active +# 0001:08:00.0 0:0:1:0 sg1 Function Disk Active +# --------------------------------------------------------------------------- +# Get ipr RAID arrays by PCI_SLOT_NAME: 0001:08:00.0 +# --------------------------------------------------------------------------- +# Name PCI/SCSI Location Description Status +# ------ ------------------------- ------------------------- ----------------- +# sda 0001:08:00.0/0:2:0:0 RAID 0 Disk Array Optimized +# +# 2. Execute "diskdiscover", the output format is as following: +# +# -------------------------------------------------------------------------- +# PCI_ID PCI_SLOT_NAME Resource_Path Device Description Status +# ------ ------------- ------------- ------ ----------- ---------------- +# 1014:034a 0001:08:00.0 0:0:0:0 sg0 0 Array Member Active +# 1014:034a 0001:08:00.0 0:0:1:0 sg1 Function Disk Active +# ------------------------------------------------------------------- +# Get ipr RAID arrays by PCI_SLOT_NAME: 0001:08:00.0 +# ------------------------------------------------------------------- +# Name PCI/SCSI Location Description Status +# ------ ------------------------- ------------------------- ----------------- +# sda 0001:08:00.0/0:2:0:0 RAID 0 Disk Array Optimized +# +# 3. Print help: diskdiscover --help|-h + +# P8 SAS adapter info +# http://pci-ids.ucw.cz/read/PC/1014/034a +# 1014 034a PCI-E IPR SAS Adapter (ASIC) +# Subsystems +# 1014 03ff PCIe3 x8 SAS RAID Internal Adapter 6Gb (57D7) <-- use this subsys id to represent internal SAS adapter +# 1014 033b PCIe2 6Gb SAS RAID Adapter Quad-port (57B4) <-- use this subsys id to represent GTO adapter + +# declare all commands +iprconfig="iprconfig" +awk="awk" +sed="sed" +cut="cut" +sleep="sleep" +sort="sort" +ps="ps" +head="head" +readlink="readlink" +basename="basename" +udevadm="udevadm" +touch="touch" +tail="tail" +dmesg="dmesg" +grep="grep" +lspci="lspci" + +################################################################ +# +# Input PCI_ID to get PCI location +# +################################################################ +function get_pciloc_by_id { + local __in_pciid=$1 + if echo "$__in_pciid" | $grep -sq "_"; then + __in_pciid=`echo "$__in_pciid" | $sed -e 's/_/:/'` + fi + local sysdevdir=/sys/bus/pci/devices + local pcilocs=`cd $sysdevdir 2>/dev/null && for dev in * + do + lines=$($udevadm info --query=property --path=$sysdevdir/$dev) + if echo "$lines" | $grep -i -sq -E "^PCI_ID=$__in_pciid$|^PCI_SUBSYS_ID=$__in_pciid$"; then + echo $dev + fi + done ` + [ -z "$pcilocs" ] && return 1 + echo "$pcilocs" + return 0 +} + +###################################################### +# +# get pci_slot scsi device +# +###################################################### +function convert_sloc_to_sg { + local __slocs="$*" + for __sloc in $__slocs + do + if echo "$__sloc" | grep -sq "[0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+"; then + __sg=`$readlink /sys/class/scsi_device/$__sloc/device/generic` + if [ "$__sg" ]; then + __sg=`$basename $__sg` + fi + elif echo "$__sloc" | grep -sq -E '^sg[0-9]+|^sd[a-z]+'; then + __sg="$__sloc" + __sloc=`convert_sg_to_sloc $__sg | $awk -F= '{print $2}'` + fi + echo "$__sloc=$__sg" + done + return 0 +} + +################################################################# +# +# Through PCI/SCSI device to find PCI/SCSI location +# +################################################################ +function convert_sg_to_sloc { + local __sgs="$*" + local __sloc="" + for __sg in $__sgs + do + if echo "$__sg" | grep -sq "^sg[0-9]\+"; then + __sloc=`$readlink /sys/class/scsi_generic/$__sg/device` + if [ "$__sloc" ]; then + __sloc=`$basename $__sloc` + fi + elif echo "$__sg" | grep -sq "^sd[a-z]\+"; then + __sloc=`$readlink /sys/block/$__sg/device` + if [ "$__sloc" ]; then + __sloc=`$basename $__sloc` + fi + elif echo "$__sg" | grep -sq "[0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+"; then + __sloc="$__sg" + __sg=`convert_sloc_to_sg $__sloc | $awk -F= '{print $2}'` + fi + echo "$__sg=$__sloc" + done + return 0 +} + +############################################################################ +# get devices which are qualified to be used to create raid +# it should equals to "query-raid-create" after all array had +# been deleted. +# Note: output format of this command is multilines +# =,,... +# =,,... +# ... +########################################################################### +function get_raid_create_devices_by_pciloc { + local lines="" + local pcilocs="$*" + [ -z "$pcilocs" ] && return 1 + + # reorder ipr ioa pcilocs by its Primary and Secondary state + local ioas=`get_ipr_ioas_by_pciloc $pcilocs` + pcilocs=`get_sg_pciloc $ioas | $awk -F= '{print $2}' ` + lines=`$iprconfig -c show-config` + local slocs="" + local line="" + for pciloc in $pcilocs + do + # exclude: + # 1) scsi adapter(ioa); + # 2) scsi enclosure; + # 3) disk array; + slocs=`echo "$lines" \ + | grep '^.*[ ]\+'$pciloc'\/[0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+.*$' \ + | grep -v -E "Adapter|Enclosure|Disk Array" \ + | cut_sloc_from_iprconfig_line \ + | $sort -V \ + | $sed -e 's/ /,/g' \ + | awk '{printf (NR>1)?","$0:$0}'` + if [ -n "$slocs" ]; then + line="$pciloc=$slocs" + echo "$line" + fi + done + return 0 +} + +######################################################################################## +# +# return list of ioas on target pciloc with order of Primary --> Secondary --> Others +# +######################################################################################### +function get_ipr_ioas_by_pciloc { + local pcilocs="$*" + [ -z "$pcilocs" ] && return 1 + + # find out all ioas and its current adapter state + #local ioas_all=`$iprconfig -c show-ioas | grep "^sg[0-9]\+.*Operational" | $awk '{print $1}' ` +local ioas_all=`$iprconfig -c show-ioas | grep "^sg[0-9]\+.*Operational" | $awk '{print $1}'` + # group them into "Primary" and "Secondary" groups + local lines=`for ioa in $ioas_all + do + state=$($iprconfig -c show-details $ioa | grep "Current Dual Adapter State" | $sed -e 's/^.* : \+\(.*\)$/\1/') + echo "$state=$ioa" + done` + local ioa_primary=`echo "$lines" | $awk -F= '($1 == "Primary") {print $2}'` + local ioa_secondary=`echo "$lines" | $awk -F= '($1 == "Secondary") {print $2}'` + local ioa_others=`echo "$lines" | $awk -F= '($1 != "Primary") && ($1 != "Secondary") {print $2}'` + ioas_all="$ioa_primary $ioa_secondary $ioa_others" + + # pick up ioa on target pciloc + lines=`echo "$pcilocs" | $sed -e 's/[, ]/\n/g'` + local ioas_in="" + if [ "$lines" = "all" ]; then + ioas_in="$ioas_all" + else + ioas_in=`for ioa in $ioas_all + do + ioa_pciloc=$(get_sg_pciloc $ioa | awk -F= '{print $2}') + if echo "$lines" | grep -sq -i "^${ioa_pciloc}$"; then + echo $ioa + fi + done ` + fi + [ -z "$ioas_in" ] && return 1 + echo "$ioas_in" + return 0 +} + +############################################### +# +# use udev to determine pciloc of sg device +# +############################################### +function get_sg_pciloc { + local sgs="$*" + [ -z "$sgs" ] && return 1 + + local sg="" + local pciloc="" + for item in $sgs + do + sg=`convert_sloc_to_sg $item | $awk -F= '{print $2}'` + [ -z "$sg" ] && continue + pciloc=`$iprconfig -c show-details $sg | grep "^PCI Address" | $sed -e 's/.*:[ ]\+\([0-9]\+:[0-9]\+:[0-9]\+\.[0-9]\+\).*$/\1/'` + + if [ -n "$pciloc" ]; then + echo "$sg=$pciloc" + fi + done + return 0 +} + +###################################################### +# +# cut resouce_path +# +##################################################### +function cut_sloc_from_iprconfig_line { + $sed -e 's/^.*[ ]\+\(.*\)\/\([0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+\).*$/\2/g' +} + +################################################### +# +# find descriptions and status for device +# +################################################### +function find_desc_status_sg { + local lines="" + local pciscsilocs="$*" + [ -z "$pciscsilocs" ] && return 1 + + lines=`$iprconfig -c show-config` + local slocs="" + local line="" + for pciscsiloc in $pciscsilocs + do + slocs=`echo "$lines" \ + | $grep "${pciscsilocs}" \ + | awk '{for(i=3;i<=NF;++i) printf $i "\t";printf "\n"}'` + echo $slocs + done + return 0 + +} + +####################################################### +# +# get disk devices through pci_id +# +####################################################### +function get_devices_by_pciid { + + local pciid="$*" + [ -z "$pciid" ] && return 1 + + echo "PCI_ID=$pciid" + + pcilocs=`get_pciloc_by_id $pciid` + + + if [ -z "$pcilocs" ]; then + echo "There is no PCI_SLOT_NAME for PCI_ID:$pciid." + return 1 + fi + slocs_grps=`get_raid_create_devices_by_pciloc $pcilocs` + if [ -z "$slocs_grps" ]; then + echo "Could not find any disk on target pciloc ${pcilocs}!" + return 1 + fi + + # find the required member disks + echo "----------------------------------------------------------------------------" + echo "PCI_SLOT_NAME Resource_Path Device Description Status" + echo "------------- ------------- ------ ----------- ---------------------------" + slocs="" + for item in $slocs_grps + do + pciloc=`echo "$item" | $awk -F= '{print $1}'` + slocs_grp=`echo "$item" | $awk -F= '{print $2;}'i \ + | $sed 's/,/ /g'` + for sloc in $slocs_grp + do + pciscsiloc="$pciloc/$sloc" + desc=`find_desc_status_sg $pciscsiloc` + disk=`convert_sloc_to_sg $sloc | $awk -F= '{print $2}'` + echo "$pciloc $sloc $disk $desc " + done + echo "---------------------------------------------------------------------------" + echo "Get ipr RAID arrays by PCI_SLOT_NAME: $pciloc" + echo "---------------------------------------------------------------------------" + get_ipr_arrays_by_pciloc $pciloc + + done +} + +###################################################################### +# +# get ipr raid arrays by PCI location +# +##################################################################### +function get_ipr_arrays_by_pciloc { + local pcilocs="$*" + [ -z "$pcilocs" ] && return 1 + + # reorder ipr ioa pcilocs by its Primary and Secondary state + local ioas=`get_ipr_ioas_by_pciloc $pcilocs` + pcilocs=`get_sg_pciloc $ioas | $awk -F= '{print $2}' ` + + local lines=$($iprconfig -c show-arrays) + local slocs=`for pciloc in $pcilocs + do + echo "$lines" + done ` + [ -n "$slocs" ] && echo "$slocs" + return 0 +} + +##################################################################### +# +# get all af and jbod disks +# +#################################################################### +function get_all_devices_for_raid { + + pcilocs=`$iprconfig -c show-config \ + | $grep -v -E "Adapter|Enclosure|Disk Array" \ + | $grep '^.*[ ]\+\(.*\)\/\([0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+\).*$'|$sed 's/ /,/g'|cut -c 8-19` + + [ -z "$pcilocs" ] && return 1 + slocs_grps=`get_raid_create_devices_by_pciloc $pcilocs` + if [ -z "$slocs_grps" ]; then + echo "Could not find any disk on target pciloc ${pcilocs}!" + fi + # find the required member disks + echo "--------------------------------------------------------------------------" + echo "PCI_ID PCI_SLOT_NAME Resource_Path Device Description Status" + echo "------ ------------- ------------- ------ ----------- ----------------" + slocs="" + for item in $slocs_grps + do + pciloc=`echo "$item" | $awk -F= '{print $1}'` + slocs_grp=`echo "$item" | $awk -F= '{print $2;}'i \ + | $sed 's/,/ /g'` + pciid=`get_PCI_ID $pciloc` + for sloc in $slocs_grp + do + pciscsiloc="$pciloc/$sloc" + desc=`find_desc_status_sg $pciscsiloc` + disk=`convert_sloc_to_sg $sloc | $awk -F= '{print $2}'` + #vendor=`find_Vendor_PID_sg disk` + echo "$pciid $pciloc $sloc $disk $desc " + done + echo "-------------------------------------------------------------------" + echo "Get ipr RAID arrays by PCI_SLOT_NAME: $pciloc" + echo "-------------------------------------------------------------------" + get_ipr_arrays_by_pciloc $pciloc + done +} + +############################################################### +# +# get PCI_ID through lspci +# +############################################################### +function get_PCI_ID { + pcislot=$1 + pciid=`$lspci | $grep ${pcislot} | $awk '{print $5}'` + echo $pciid +} + +function usagesc { + echo "Usage: diskdiscover " + echo " If input parameter is , return devices and RAID arrays info by PCI_ID." + echo " If there is no value for , return all af/jbod disks and RAID arrays info." + +} + +######################################## +# +# Main processi: +# +# if input parameter is PCI_ID: +# Get devices and RAID arrays info by PCI_ID +# if there is no input parameter for PCI_ID : +# Get all af disks and jbod disks info +# Get all RAID arrays info +# +########################################## +input=$1 +if [ "x$input" == "x--help" -o "x$input" == "x-h" ]; then + usagesc + exit 0 +fi +if [ -z $input ]; then + get_all_devices_for_raid +else + get_devices_by_pciid $input +fi