1*7c478bd9Sstevel@tonic-gate#!/bin/ksh -p 2*7c478bd9Sstevel@tonic-gate# 3*7c478bd9Sstevel@tonic-gate# CDDL HEADER START 4*7c478bd9Sstevel@tonic-gate# 5*7c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*7c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 7*7c478bd9Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 8*7c478bd9Sstevel@tonic-gate# with the License. 9*7c478bd9Sstevel@tonic-gate# 10*7c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*7c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 12*7c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 13*7c478bd9Sstevel@tonic-gate# and limitations under the License. 14*7c478bd9Sstevel@tonic-gate# 15*7c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 16*7c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*7c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 18*7c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 19*7c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 20*7c478bd9Sstevel@tonic-gate# 21*7c478bd9Sstevel@tonic-gate# CDDL HEADER END 22*7c478bd9Sstevel@tonic-gate# 23*7c478bd9Sstevel@tonic-gate# 24*7c478bd9Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc. All rights reserved. 25*7c478bd9Sstevel@tonic-gate# Use is subject to license terms. 26*7c478bd9Sstevel@tonic-gate# 27*7c478bd9Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gateexport PATH=/usr/bin:/usr/sbin:/usr/ccs/bin 30*7c478bd9Sstevel@tonic-gateunset ENV TMPDIR 31*7c478bd9Sstevel@tonic-gateumask 022 32*7c478bd9Sstevel@tonic-gatecwd=$PWD 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gateif [[ -n "$CODEMGR_WS" ]]; then 35*7c478bd9Sstevel@tonic-gate sysroot=$CODEMGR_WS/proto/root_`uname -p` 36*7c478bd9Sstevel@tonic-gateelif [[ -n "$ROOT" ]]; then 37*7c478bd9Sstevel@tonic-gate sysroot=$ROOT 38*7c478bd9Sstevel@tonic-gateelse 39*7c478bd9Sstevel@tonic-gate sysroot=/ 40*7c478bd9Sstevel@tonic-gatefi 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gatequote= 43*7c478bd9Sstevel@tonic-gateeol='\' 44*7c478bd9Sstevel@tonic-gatefiles= 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gatesimchan=com.sun:fm:fmd$$ 47*7c478bd9Sstevel@tonic-gatesimroot=/tmp/fmd.$$ 48*7c478bd9Sstevel@tonic-gatesimscript=run 49*7c478bd9Sstevel@tonic-gatesimpid= 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gatetruss_cmd= 52*7c478bd9Sstevel@tonic-gatetruss_args= 53*7c478bd9Sstevel@tonic-gatedump_args= 54*7c478bd9Sstevel@tonic-gateinj_args= 55*7c478bd9Sstevel@tonic-gatefmd_args= 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gateopt_h=false 58*7c478bd9Sstevel@tonic-gateopt_i=false 59*7c478bd9Sstevel@tonic-gateopt_s=false 60*7c478bd9Sstevel@tonic-gateopt_x=false 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gatefunction cp_so 63*7c478bd9Sstevel@tonic-gate{ 64*7c478bd9Sstevel@tonic-gate nm -ghp $1 2>/dev/null | while read addr type name; do 65*7c478bd9Sstevel@tonic-gate [[ $type != T ]] && continue 66*7c478bd9Sstevel@tonic-gate case $name in 67*7c478bd9Sstevel@tonic-gate _fmd_init) cp $1 $2/usr/lib/fm/fmd/plugins; return ;; 68*7c478bd9Sstevel@tonic-gate fmd_fmri_nvl2str) cp $1 $2/usr/lib/fm/fmd/schemes; return ;; 69*7c478bd9Sstevel@tonic-gate topo_load) cp $1 $2/usr/lib/fm/topo; return ;; 70*7c478bd9Sstevel@tonic-gate esac 71*7c478bd9Sstevel@tonic-gate done 72*7c478bd9Sstevel@tonic-gate die "\nunknown .so type -- $1" 73*7c478bd9Sstevel@tonic-gate} 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gatefunction list_cmds 76*7c478bd9Sstevel@tonic-gate{ 77*7c478bd9Sstevel@tonic-gate for cmd in fmadm fmdump fmstat; do 78*7c478bd9Sstevel@tonic-gate echo usr/sbin/$cmd 79*7c478bd9Sstevel@tonic-gate done 80*7c478bd9Sstevel@tonic-gate} 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gatefunction wait_status 83*7c478bd9Sstevel@tonic-gate{ 84*7c478bd9Sstevel@tonic-gate if [[ $1 -gt 128 ]]; then 85*7c478bd9Sstevel@tonic-gate sig=$(kill -l $(($1 - 128))) 86*7c478bd9Sstevel@tonic-gate die "fmd terminated from signal $sig (see $simroot)" 87*7c478bd9Sstevel@tonic-gate elif [[ $1 -ne 0 ]]; then 88*7c478bd9Sstevel@tonic-gate die "fmd terminated with status $1 (see $simroot)" 89*7c478bd9Sstevel@tonic-gate fi 90*7c478bd9Sstevel@tonic-gate} 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gatefunction die 93*7c478bd9Sstevel@tonic-gate{ 94*7c478bd9Sstevel@tonic-gate echo "fmsim: $*" >& 2 95*7c478bd9Sstevel@tonic-gate [[ -n "$simpid" ]] && exit 1 || exit 2 96*7c478bd9Sstevel@tonic-gate} 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gatewhile [[ $# -gt 0 ]]; do 99*7c478bd9Sstevel@tonic-gate OPTIND=1; while getopts ':d:D:ehio:st:vVx' c; do 100*7c478bd9Sstevel@tonic-gate case "$c" in 101*7c478bd9Sstevel@tonic-gate d) 102*7c478bd9Sstevel@tonic-gate simroot=$OPTARG 103*7c478bd9Sstevel@tonic-gate ;; 104*7c478bd9Sstevel@tonic-gate D) 105*7c478bd9Sstevel@tonic-gate truss_cmd=dtrace 106*7c478bd9Sstevel@tonic-gate truss_args="-s $OPTARG -c" 107*7c478bd9Sstevel@tonic-gate quote="'"; eol="" 108*7c478bd9Sstevel@tonic-gate ;; 109*7c478bd9Sstevel@tonic-gate e|v|V) 110*7c478bd9Sstevel@tonic-gate dump_args="$dump_args -$c" 111*7c478bd9Sstevel@tonic-gate ;; 112*7c478bd9Sstevel@tonic-gate h|i|s|x) 113*7c478bd9Sstevel@tonic-gate eval opt_$c'='true 114*7c478bd9Sstevel@tonic-gate ;; 115*7c478bd9Sstevel@tonic-gate o) 116*7c478bd9Sstevel@tonic-gate fmd_args="$fmd_args -o $OPTARG" 117*7c478bd9Sstevel@tonic-gate ;; 118*7c478bd9Sstevel@tonic-gate t) 119*7c478bd9Sstevel@tonic-gate truss_cmd=truss 120*7c478bd9Sstevel@tonic-gate truss_args="$OPTARG" 121*7c478bd9Sstevel@tonic-gate ;; 122*7c478bd9Sstevel@tonic-gate :) 123*7c478bd9Sstevel@tonic-gate die "option requires an argument -- $OPTARG" 124*7c478bd9Sstevel@tonic-gate ;; 125*7c478bd9Sstevel@tonic-gate *) 126*7c478bd9Sstevel@tonic-gate die "illegal option -- $OPTARG" 127*7c478bd9Sstevel@tonic-gate ;; 128*7c478bd9Sstevel@tonic-gate esac 129*7c478bd9Sstevel@tonic-gate done 130*7c478bd9Sstevel@tonic-gate let OPTIND="$OPTIND - 1"; shift $OPTIND 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate if [[ $# -gt 0 ]]; then 133*7c478bd9Sstevel@tonic-gate if [[ -d $1 ]]; then 134*7c478bd9Sstevel@tonic-gate files="$files $1/*" 135*7c478bd9Sstevel@tonic-gate else 136*7c478bd9Sstevel@tonic-gate files="$files $1" 137*7c478bd9Sstevel@tonic-gate fi 138*7c478bd9Sstevel@tonic-gate shift 139*7c478bd9Sstevel@tonic-gate fi 140*7c478bd9Sstevel@tonic-gatedone 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gatefor file in $files; do 143*7c478bd9Sstevel@tonic-gate [[ -r $file ]] || die "input file is missing or not readable -- $file" 144*7c478bd9Sstevel@tonic-gatedone 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gateif $opt_h || [[ -z "$files" && $opt_i = false ]]; then 147*7c478bd9Sstevel@tonic-gate echo "Usage: fmsim [-ehiksvV] [-d dir] [-D a.d] [-o opt=val]" \ 148*7c478bd9Sstevel@tonic-gate "[-t args] [file ...]" 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate echo "\t-D start fmd(1M) using dtrace(1M) and specified D script" 151*7c478bd9Sstevel@tonic-gate echo "\t-e display error log content instead of fault log content" 152*7c478bd9Sstevel@tonic-gate echo "\t-h display usage information for fmsim and exit" 153*7c478bd9Sstevel@tonic-gate echo "\t-i set interactive mode: do not stop after sending events" 154*7c478bd9Sstevel@tonic-gate echo "\t-o set fmd(1M) option to specified value during simulation" 155*7c478bd9Sstevel@tonic-gate echo "\t-s set up simulation world but do not actually run simulation" 156*7c478bd9Sstevel@tonic-gate echo "\t-t start fmd(1M) using truss(1) and specified arguments" 157*7c478bd9Sstevel@tonic-gate echo "\t-v set verbose mode: display additional event detail" 158*7c478bd9Sstevel@tonic-gate echo "\t-V set very verbose mode: display complete event contents" 159*7c478bd9Sstevel@tonic-gate echo "\t-x delete simulation world if simulation is successful" 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate exit 0 162*7c478bd9Sstevel@tonic-gatefi 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gateecho "fmsim: creating simulation world $simroot ... \c" 165*7c478bd9Sstevel@tonic-gate[[ -d $simroot ]] || mkdir -p $simroot || exit 1 166*7c478bd9Sstevel@tonic-gatecd $simroot || exit 1 167*7c478bd9Sstevel@tonic-gateecho "done." 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gateecho "fmsim: populating /var ... \c" 170*7c478bd9Sstevel@tonic-gatemkdir -p -m 0755 var/fm/fmd 171*7c478bd9Sstevel@tonic-gatemkdir -p -m 0700 var/fm/fmd/ckpt 172*7c478bd9Sstevel@tonic-gatemkdir -p -m 0700 var/fm/fmd/rsrc 173*7c478bd9Sstevel@tonic-gateecho "done." 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/lib/fm from $sysroot ... \c" 176*7c478bd9Sstevel@tonic-gate(cd $sysroot && find usr/lib/fm -depth -print | cpio -pdmu $simroot) 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gatefor platdir in $sysroot/usr/platform/*/lib/fm; do 179*7c478bd9Sstevel@tonic-gate [[ -d $platdir ]] && platdir=${platdir#$sysroot} || continue 180*7c478bd9Sstevel@tonic-gate echo "fmsim: populating $platdir from $sysroot ... \c" 181*7c478bd9Sstevel@tonic-gate (cd $sysroot && find ${platdir#/} -depth -print | cpio -pdmu $simroot) 182*7c478bd9Sstevel@tonic-gatedone 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/lib/locale/$LANG from $sysroot ... \c" 185*7c478bd9Sstevel@tonic-gate(cd $sysroot && find usr/lib/locale/$LANG -depth -print | cpio -pdmu $simroot) 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/sbin from $sysroot ... \c" 188*7c478bd9Sstevel@tonic-gate(cd $sysroot && list_cmds | cpio -pdmu $simroot) 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gateecho "fmsim: adding customizations:\c" 191*7c478bd9Sstevel@tonic-gatecd $cwd || exit $1 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gatefor file in $files; do 194*7c478bd9Sstevel@tonic-gate base=$(basename $file) 195*7c478bd9Sstevel@tonic-gate case $base in 196*7c478bd9Sstevel@tonic-gate *.cmd) die "\neversholt command file not yet supported -- $file" ;; 197*7c478bd9Sstevel@tonic-gate fmd.conf) cp $file $simroot/etc/fm/fmd ;; 198*7c478bd9Sstevel@tonic-gate *.conf) cp $file $simroot/usr/lib/fm/fmd/plugins ;; 199*7c478bd9Sstevel@tonic-gate *.dict) cp $file $simroot/usr/lib/fm/dict ;; 200*7c478bd9Sstevel@tonic-gate *.eft) die "\neversholt fault tree file not yet supported -- $file" ;; 201*7c478bd9Sstevel@tonic-gate *.esc) die "\neversholt source file not yet supported -- $file" ;; 202*7c478bd9Sstevel@tonic-gate *.inj) inj_args="$inj_args $file" ;; 203*7c478bd9Sstevel@tonic-gate *.log) inj_args="$inj_args $file" ;; 204*7c478bd9Sstevel@tonic-gate *log) inj_args="$inj_args $file" ;; 205*7c478bd9Sstevel@tonic-gate *.mo) cp $file $simroot/usr/lib/locale/$LANG/LC_MESSAGES ;; 206*7c478bd9Sstevel@tonic-gate *.so) cp_so $file $simroot ;; 207*7c478bd9Sstevel@tonic-gate *.topo) cp $file $simroot/usr/lib/fm/topo ;; 208*7c478bd9Sstevel@tonic-gate *) die "\nunknown file type or suffix -- $file" ;; 209*7c478bd9Sstevel@tonic-gate esac 210*7c478bd9Sstevel@tonic-gate echo " $base\c" 211*7c478bd9Sstevel@tonic-gatedone 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gatecd $simroot || exit 1 214*7c478bd9Sstevel@tonic-gateecho " done." 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gateecho "fmsim: generating script ... \c" 217*7c478bd9Sstevel@tonic-gatecat >$simscript <<EOS 218*7c478bd9Sstevel@tonic-gate#!/bin/ksh -p 219*7c478bd9Sstevel@tonic-gate# 220*7c478bd9Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc. All rights reserved. 221*7c478bd9Sstevel@tonic-gate# Use is subject to license terms. 222*7c478bd9Sstevel@tonic-gate# 223*7c478bd9Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate# 226*7c478bd9Sstevel@tonic-gate# fmsim(1M) script generated for $simroot $(date) 227*7c478bd9Sstevel@tonic-gate# 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gateexport LD_LIBRARY_PATH=$simroot/usr/lib 230*7c478bd9Sstevel@tonic-gateexport LD_LIBRARY_PATH_64=$simroot/usr/lib/64 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gateexec $truss_cmd $truss_args $quote./usr/lib/fm/fmd/fmd -R $simroot $eol 233*7c478bd9Sstevel@tonic-gate -o fg=true -o rpc.adm.path=$simroot/rpc -o xprt.device=/dev/null $eol 234*7c478bd9Sstevel@tonic-gate -o errchan=$simchan -o clock=simulated $fmd_args$quote 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gateEOS 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gatechmod 0555 $simscript 239*7c478bd9Sstevel@tonic-gateecho "done." 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gateif $opt_s; then 242*7c478bd9Sstevel@tonic-gate echo "fmsim: simulation is saved in $simroot" 243*7c478bd9Sstevel@tonic-gate exit 0 244*7c478bd9Sstevel@tonic-gatefi 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gateexport LD_LIBRARY_PATH=$simroot/usr/lib 247*7c478bd9Sstevel@tonic-gateexport LD_LIBRARY_PATH_64=$simroot/usr/lib/64 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gateecho "fmsim: simulation $$ running fmd(1M)\c" 250*7c478bd9Sstevel@tonic-gate./usr/lib/fm/fmd/fmd -V | cut -d: -f2 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate./$simscript & 253*7c478bd9Sstevel@tonic-gatesimpid=$! 254*7c478bd9Sstevel@tonic-gatetrap '' INT HUP 255*7c478bd9Sstevel@tonic-gatecd $cwd 256*7c478bd9Sstevel@tonic-gatei=0 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gatewhile [[ ! -s $simroot/rpc ]]; do 259*7c478bd9Sstevel@tonic-gate [[ $i -ge 30 ]] && kill -9 $simpid >/dev/null 2>&1 260*7c478bd9Sstevel@tonic-gate kill -0 $simpid >/dev/null 2>&1 || break 261*7c478bd9Sstevel@tonic-gate let i="$i + 1" 262*7c478bd9Sstevel@tonic-gate sleep 1 263*7c478bd9Sstevel@tonic-gatedone 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gatekill -0 $simpid >/dev/null 2>&1 || { 266*7c478bd9Sstevel@tonic-gate wait $simpid 267*7c478bd9Sstevel@tonic-gate wait_status $? 268*7c478bd9Sstevel@tonic-gate} 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gateecho "fmsim: rpc adm requests can rendezvous at" $(<$simroot/rpc) 271*7c478bd9Sstevel@tonic-gateecho "fmsim: injectors should use channel $simchan" 272*7c478bd9Sstevel@tonic-gateecho "fmsim: debuggers should attach to PID $simpid" 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gatefor arg in $inj_args; do 275*7c478bd9Sstevel@tonic-gate echo "fmsim: injecting events from $arg ... \c" 276*7c478bd9Sstevel@tonic-gate $simroot/usr/lib/fm/fmd/fminject -q -c $simchan $arg || { 277*7c478bd9Sstevel@tonic-gate echo "fmsim: fminject failed for $arg: aborting simulation" >& 2 278*7c478bd9Sstevel@tonic-gate kill $simpid >/dev/null 2>&1 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate echo "done." 281*7c478bd9Sstevel@tonic-gatedone 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gateif [[ $opt_i = false ]]; then 284*7c478bd9Sstevel@tonic-gate echo "fmsim: injecting event to advance to end-of-time ... \c" 285*7c478bd9Sstevel@tonic-gate echo 'endhrtime;' | $simroot/usr/lib/fm/fmd/fminject -q -c $simchan - 286*7c478bd9Sstevel@tonic-gate echo "done." 287*7c478bd9Sstevel@tonic-gatefi 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gatewait $simpid 290*7c478bd9Sstevel@tonic-gatestatus=$? 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gateif [[ -f $simroot/var/fm/fmd/errlog ]]; then 293*7c478bd9Sstevel@tonic-gate echo; $simroot/usr/sbin/fmdump -R $simroot $dump_args; echo 294*7c478bd9Sstevel@tonic-gatefi 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gatewait_status $status 297*7c478bd9Sstevel@tonic-gate$opt_x && rm -rf $simroot 298*7c478bd9Sstevel@tonic-gateexit 0 299