#!/bin/ksh93 typeset -r VERSION='1.0' FPROG=${.sh.file} PROG=${FPROG##*/} SDIR=${FPROG%/*} typeset -r \ MPTSAS_CONF='/kernel/drv/mpt_sas.conf' \ TOPO_DIR='/usr/platform/i86pc/lib/fm/topo' \ FM_MOD='/usr/lib/fm/topo/plugins/mpt_sas_da_led.so' \ HC_FILE='maps/i86pc-legacy-hc-topology.xml' \ DISK_FILE='maps/F224A-disk-hc-topology.xml' \ function showUsage { [[ -n $1 ]] && X='-?' || X='--man' getopts -a ${PROG} "${ print ${USAGE} ; }" OPT $X } function createFmDiskTopoSES { print ' ' >${TOPO_DIR}/${DISK_FILE} } function createFmDiskTopoDA { typeset X PLUGIN="${FM_MOD##*/}" METHOD_NAME='mptsas_led_mode' \ OUT=' ' [[ ! -e ${FM_MOD} ]] && \ print -u2 "${FM_MOD} ist noch nicht installiert!!!" typeset -A NAME2VAL=( [fail]=0 [ident]=1 [ok2rm]=2 ) for X in ${!NAME2VAL[@]} ; do OUT+=' \t\t" \t\t \t\t \t\t \t\t \t\t \t\t ' done OUT+=' \t\t \t\t \t\t \t\t \t\t ' print "${OUT}" >${TOPO_DIR}/${DISK_FILE} } function modifyHcFile { if /usr/xpg4/bin/egrep -q 'F2(16|24)A-' ${TOPO_DIR}/${HC_FILE} ; then print -u2 'F2xxA Topo-Eintrag ist bereits vorhanden.' (( FORCE )) || return 4 fi typeset TMPF=${ mktemp /tmp/by.XXXXXX; } TMPF2=${ mktemp /tmp/by2.XXXXXX; } [[ -z ${TMPF} ]] && return 5 [[ -z ${TMPF2} ]] && rm -f ${TMPF2} && return 5 cat >${TMPF}< EOF xsltproc ${TMPF} ${TOPO_DIR}/${HC_FILE} >${TMPF2} || \ { rm -f ${TMPF2} ${TMPF2}; return 6; } cp ${TMPF2} ${TOPO_DIR}/${HC_FILE} rm -f ${TMPF2} ${TMPF2} } function fixFmTopo { modifyHcFile (( USE_SES )) && createFmDiskTopoSES || createFmDiskTopoDA chmod 0644 ${TOPO_DIR}/${DISK_FILE} return 0 } function ascii2str { typeset -n V=$1 typeset A="${2//./}" X integer I N K K=${#A} for (( I=0; I < K; I+=2 )); do X=${A:I:2} N=16#${X} (( N > 31 && N < 128 )) && V+="\x{$X}" || V+=" 0x$N " done } # das reicht aus, damit bei diskinfo und croinfo die Platten inkl. Label agezeigt # werden bzw. zpool -l die Labels statt devicename ausgibt. function fixMpt_sas { if /usr/xpg4/bin/egrep -q 'F2(16|24)A-' ${MPTSAS_CONF} ; then print -u2 'F2xxA MPTsas-Eintrag ist bereits vorhanden.' (( FORCE )) || return 6 fi # seit 11.2 SRU 8.4 typeset ZB CF=' # default "schema": # compatible="pciex${vendorId},${DeviceId}.${vendorId}.${SubsystemId}" # ancestor-compatible="system-component.${smbios-t1-product}" # Wir nehmen aber nicht "system-component.F224A-DE5", da sich alle 3 controller # in dessen Subbaum befinden und damit das ganze nicht mehr eindeutig wäre. # Ergo nehmen wir einen mit dem jeweiligen PCI-Slot assoziierte "compatible" # name (Hardware Properties section) als "ancestor-compatible". Aber Vorsicht, # auch die sind nicht eindeutig - Slots 1|4 2|6 3|7 haben die gleichen aliases # ergo sollte immer nur in einem der beiden Slots ein SAS-DA-Controller sitzen! #' # das muß dabei in etwa rauskommen ZB='compatible="pciex1000,87.1000.3020" hba-sas-int="iport:@ff"; # name="slot-names" value=00000001.746f6c53.00000031 => 01.tols.1 compatible="pciex1000,87.1000.3020" ancestor-compatible= "pciex8086,e08.4" sas-bay-labels= "/HDD0:@8", "/HDD1:@4", "/HDD2:@2", "/HDD3:@1", "/HDD4:@80", "/HDD5:@40", "/HDD6:@20", "/HDD7:@10"; # name="slot-names" value=00000001.746f6c53.00000036 => 01.tols.6 compatible="pciex1000,87.1000.3020" ancestor-compatible= "pciex8086,e04.4" sas-bay-labels= "/HDD8:@8", "/HDD9:@4", "/HDD10:@2", "/HDD11:@1", "/HDD12:@80", "/HDD13:@40", "/HDD14:@20", "/HDD15:@10"; # name="slot-names" value=00000001.746f6c53.00000037 => 01.tols.7 compatible="pciex1000,87.1000.3020" ancestor-compatible= "pciex8086,e06.4" sas-bay-labels= "/HDD16:@8", "/HDD17:@4", "/HDD18:@2", "/HDD19:@1", "/HDD20:@80", "/HDD21:@40", "/HDD22:@20", "/HDD23:@10"; ' typeset DPATH INST DRIVER TAIL PCIEB CTRL A \ MPXIO='\n# Direct Attached (DA) disks sind i.d.R. nicht redundant ' MPXIO+='angeschlossen.' integer I N=0 sort /etc/path_to_inst | while read DPATH INST DRIVER TAIL ; do if [[ ${DRIVER} == '"pcieb"' ]]; then PCIEB="${DPATH:1:${#DPATH}-2}" CTRL= elif [[ -z ${CTRL} && ${DRIVER} == '"mpt_sas"' ]]; then CTRL="${DPATH:1:${#DPATH}-2}" elif [[ ${DRIVER} == '"smp"' ]]; then CTRL= # SES enumerated, not direct attached (DA), so ignore elif [[ -n ${CTRL} && ${DPATH: -10:9} == '/iport@v0' && -n ${PCIEB} ]] then X=${ devprop -n "${PCIEB}" -i slot-names ; } A=( ${X//./ } ) I=16#${A##+(0)} TAIL="$I" for (( I=1; I < ${#A[@]}; I++ )); do TAIL+='.' ascii2str TAIL ${A[I]##+(0)} done CF+="\n# name='slot-names' value=$X => ${TAIL}" MPXIO+='\nname="mpt_sas" parent="'"${CTRL}"'"\n\tmpxio-disable="yes";' X="${ devprop -n "${CTRL}" -s compatible ; }" A=( ${X//+} ) for X in ${A[@]} ; do [[ $X =~ ^pciex[0-9a-f]+,[0-9a-f]+\.[0-9a-f]+\.[0-9a-f]+$ ]] &&\ CF+="\ncompatible=\"$X\"" && break done X="${ devprop -n "${PCIEB}" -s compatible ; }" A=( ${X//+} ) for X in ${A[@]} ; do [[ $X =~ ^pciex[0-9a-f]+,[0-9a-f]+\.[0-9a-f]+$ ]] && \ CF+="\n\tancestor-compatible=\"$X\"" && break done CF+='\n\tsas-bay-labels=\n' for X in 8 4 2 1 0 80 40 20 10 ; do [[ $X == 0 ]] && CF+='\n' && continue CF+="\t\"/HDD${N}:@$X\"," (( N++ )) done CF="${CF%,};" fi done (( ! WRITE )) && printf "# ${MPTSAS_CONF}:\n${MPXIO}\n${CF}\n" && return [[ -e ${MPTSAS_CONF}.orig ]] || cp -p ${MPTSAS_CONF} ${MPTSAS_CONF}.orig printf "${MPXIO}\n${CF}\n" >>${MPTSAS_CONF} print "ACHTUNG: ${MPTSAS_CONF} Einträge gegen 'prtconf -v' checken!" } function checkVersion { X=${ pkg list -H entire 2>/dev/null ; } [[ -z $X ]] && WRITE=0 && print 'Not Solaris 11+ - write disabled.' && return X=${X#*-} X=${X% *} A=( ${X//./ } ) typeset -il \ VERS=${ printf "%d%03d%03d%03d" ${A[1]} ${A[2]} ${A[3]} ${A[5]}; } (( VERS < 175002008004 )) || return print 'Solaris 11.2 SRU 8.4 required - write disabled.' && WRITE=0 } function doMain { typeset -a A=( ${ smbios -t 1 | grep Product: ; } ) typeset X [[ -z ${A[1]} ]] && \ print 'Keine "Product:" Infos via smbios verfügbar.' && return 1 [[ ${A[1]} =~ ^F2(16|24)A- ]] || \ { print -u2 'Dies scheint keine F2xxA Kiste zu sein.'; return 1 ; } cd ${TOPO_DIR} || \ { print -u2 "${TOPO_DIR} scheint es nicht zu geben.";return 3; } (( WRITE )) && checkVersion fixMpt_sas (( FIX_TOPO )) && fixFmTopo } USAGE="[-?${VERSION}"' ] [-copyright?Copyright (c) 2016 Jens Elkner. All rights reserved.] [-license?CDDL 1.0] [+NAME?'"${PROG}"' - disk location info setup] [+DESCRIPTION?Nimmt entsprechende Einträge \b'"${MPTSAS_CONF##*/}\b und optional \b${HC_FILE##*/}"'\b vor (soweit noch nicht vorhanden), so daß diskinfo/croinfo was anzeigen und z.B. "zpool status -l" das konfigurierte Bay-Label statt den device path ausgibt.] [+?In "prtconf -v" sollte danach für jede "disk, instance #n" unter einem mpt_sas getriebenen Controller eine "location" property mit dem Wert "/dev/chassis/SYS/HDDm/disk" anzeigen. Ebenso sollte bei jedem SAS-Controller "pci1000,3020, instance #k" (o.ä., subsystemId: 1000=LSI,3020=9207-8i) unter "System software properties" eine property namens "sas-bay-labels" auftauchen, die als value die Liste der Bay-Labels aus der '"${MPTSAS_CONF##*/}"' besitzt.] [+?Last but not least werden für die relevanten Controller der \bmpxio-disable\b Wert explizit auf \byes\b gesetzt, wenn an keinem wide port des Controller ein SES-Gerät/SAS-Expander gefunden wird (anderenfalls wird der Controller komplett ignoriert).] [h:help?Print this help and exit.] [F:functions?Print a list of all functions available.] [T:trace]:[functionList?A comma separated list of functions of this script to trace (convinience for troubleshooting).] [+?] [f:force?Falls die Modifikationen für diese Maschine schon in den jeweiligen Dateien vorhanden sind, tut das Script normalerweise nichts. Mit dieser Option wird zwar diesbzgl. geprüft und ggf. ein Meldung ausgegeben, ansonsten das Ergebnis aber ignoriert.] [s:ses?Use SES variante of '"${DISK_FILE}"' instead of the direct-atached (DA) variant.] [t:topo?Fixe/generiere auch topo files. Normalerweise reicht das Update von '"${MPTSAS_CONF##*/}"' aus. Rest ist rein experimentell.] [w:write?Write config additions to the related file. If not given, just show the changes, which need to be made.] [+FILES?Nach einem Lauf sind die relevanten Dateien unbedingt zu kontrollieren, gegen den output von "prtconf -v" zu checken und ggf. abzugleichen! Wenn der mpxio Wert geändert wird, kann es sein, daß das system nicht mehr bootet, da beim nächsten Boot dann [nicht]] der \b/devices/scsi_vhci/disk@*\b statt \b/pci@*/pci8086,*/pci1000,*/iport@*/disk@*:b\b erwartet wird.]{ [+?] [+/etc/path_to_inst?Datei mit den benötigten Basisinformationen bzgl. mpt_sas(7d) Controller und Art.] [+'"${TOPO_DIR}"'?Verzeichnis mit den relevanten fmtopo Sachen] [+'"${TOPO_DIR}/${HC_FILE}"'?Haupt-fmtopo-Mapfile (entry point). Experimentell.] [+'"${TOPO_DIR}/${DISK_FILE}"'?Zu verwendende Disk-Topologie-Info für F2{16|24}A-* Kisten. Experimentell.] [+'"${FM_MOD%/*}[/amd64]]/${FM_MOD##*/}"'?fmtopo plugin zum Managen der Bay-LEDs. Experimentell.] [+'"${MPTSAS_CONF}"'?Hier wird das Mapping von SAS-Controller:iport auf Bay-Label eingetragen. Im Prinzip reicht das bzgl. diskinfo/croinfo bzw. location aware cmds wie "zpool status -l". Die anderen fmtopo Sachen sind nur convinience.] } [+SEE ALSO?\bpath_to_inst\b(4), \bprtconf\b(1M), \bstmsboot\b(1M).] [+NOTES?Diese Variante mittels '"${MPTSAS_CONF##*/}"' funktioniert nur für Kisten mit Solaris 11.2 SRU 8.4 und höher. Davor (seit 11.0) wurden "*,bay_labels" stattdessen benutzt, womit die locations bzgl. "zpool status -l" funktionierten, dafür aber diskinfo/croinfo nicht. Für ältere System kann man die "*,bay_labels" Datei mittels /net/software/export/install/dos/flashutils.dsk/lsi/etc/diskutil.sh erstellen, bringt für neuere aber wie gesagt nix.] ' X="${ print ${USAGE} ; }" integer USE_SES=0 FIX_TOPO=0 WRITE=0 FORCE=0 while getopts "${X}" OPT ; do case ${OPT} in h) showUsage ; exit 0 ;; T) if [[ ${OPTARG} == 'ALL' ]]; then typeset -ft ${ typeset +f ; } else typeset -ft ${OPTARG//,/ } fi ;; F) typeset +f && exit 0 ;; f) FORCE=1 ;; s) USE_SES=1 ;; t) FIX_TOPO=1 ;; w) WRITE=1 ;; *) showUsage 1 ; exit 1 ;; esac done X=$((OPTIND-1)) shift $X && OPTIND=1 unset X doMain "$@"