17c478bd9Sstevel@tonic-gate#!/bin/ksh -p 27c478bd9Sstevel@tonic-gate# 37c478bd9Sstevel@tonic-gate# CDDL HEADER START 47c478bd9Sstevel@tonic-gate# 57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 67c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 77c478bd9Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 87c478bd9Sstevel@tonic-gate# with the License. 97c478bd9Sstevel@tonic-gate# 107c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 117c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 127c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 137c478bd9Sstevel@tonic-gate# and limitations under the License. 147c478bd9Sstevel@tonic-gate# 157c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 167c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 177c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 187c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 197c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 207c478bd9Sstevel@tonic-gate# 217c478bd9Sstevel@tonic-gate# CDDL HEADER END 227c478bd9Sstevel@tonic-gate# 237c478bd9Sstevel@tonic-gate# 24*d9638e54Smws# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate# Use is subject to license terms. 267c478bd9Sstevel@tonic-gate# 277c478bd9Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gateexport PATH=/usr/bin:/usr/sbin:/usr/ccs/bin 307c478bd9Sstevel@tonic-gateunset ENV TMPDIR 317c478bd9Sstevel@tonic-gateumask 022 327c478bd9Sstevel@tonic-gatecwd=$PWD 337c478bd9Sstevel@tonic-gate 34*d9638e54Smwsisa=$(uname -p) 35*d9638e54Smwsif [[ $isa = sparc ]]; then 36*d9638e54Smws isa64=sparcv9 37*d9638e54Smwselif [[ $isa = i386 ]]; then 38*d9638e54Smws isa64=amd64 39*d9638e54Smwselse 40*d9638e54Smws isa64=unknown 41*d9638e54Smwsfi 42*d9638e54Smws 437c478bd9Sstevel@tonic-gateif [[ -n "$CODEMGR_WS" ]]; then 44*d9638e54Smws sysroot=$CODEMGR_WS/proto/root_$isa 457c478bd9Sstevel@tonic-gateelif [[ -n "$ROOT" ]]; then 467c478bd9Sstevel@tonic-gate sysroot=$ROOT 477c478bd9Sstevel@tonic-gateelse 487c478bd9Sstevel@tonic-gate sysroot=/ 497c478bd9Sstevel@tonic-gatefi 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gatequote= 527c478bd9Sstevel@tonic-gateeol='\' 537c478bd9Sstevel@tonic-gatefiles= 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gatesimchan=com.sun:fm:fmd$$ 567c478bd9Sstevel@tonic-gatesimroot=/tmp/fmd.$$ 577c478bd9Sstevel@tonic-gatesimscript=run 587c478bd9Sstevel@tonic-gatesimpid= 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gatetruss_cmd= 617c478bd9Sstevel@tonic-gatetruss_args= 627c478bd9Sstevel@tonic-gatedump_args= 637c478bd9Sstevel@tonic-gateinj_args= 647c478bd9Sstevel@tonic-gatefmd_args= 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gateopt_h=false 677c478bd9Sstevel@tonic-gateopt_i=false 687c478bd9Sstevel@tonic-gateopt_s=false 69*d9638e54Smwsopt_w=false 707c478bd9Sstevel@tonic-gateopt_x=false 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gatefunction cp_so 737c478bd9Sstevel@tonic-gate{ 747c478bd9Sstevel@tonic-gate nm -ghp $1 2>/dev/null | while read addr type name; do 757c478bd9Sstevel@tonic-gate [[ $type != T ]] && continue 767c478bd9Sstevel@tonic-gate case $name in 777c478bd9Sstevel@tonic-gate _fmd_init) cp $1 $2/usr/lib/fm/fmd/plugins; return ;; 787c478bd9Sstevel@tonic-gate fmd_fmri_nvl2str) cp $1 $2/usr/lib/fm/fmd/schemes; return ;; 797c478bd9Sstevel@tonic-gate topo_load) cp $1 $2/usr/lib/fm/topo; return ;; 807c478bd9Sstevel@tonic-gate esac 817c478bd9Sstevel@tonic-gate done 827c478bd9Sstevel@tonic-gate die "\nunknown .so type -- $1" 837c478bd9Sstevel@tonic-gate} 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gatefunction list_cmds 867c478bd9Sstevel@tonic-gate{ 877c478bd9Sstevel@tonic-gate for cmd in fmadm fmdump fmstat; do 887c478bd9Sstevel@tonic-gate echo usr/sbin/$cmd 897c478bd9Sstevel@tonic-gate done 907c478bd9Sstevel@tonic-gate} 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gatefunction wait_status 937c478bd9Sstevel@tonic-gate{ 947c478bd9Sstevel@tonic-gate if [[ $1 -gt 128 ]]; then 957c478bd9Sstevel@tonic-gate sig=$(kill -l $(($1 - 128))) 967c478bd9Sstevel@tonic-gate die "fmd terminated from signal $sig (see $simroot)" 977c478bd9Sstevel@tonic-gate elif [[ $1 -ne 0 ]]; then 987c478bd9Sstevel@tonic-gate die "fmd terminated with status $1 (see $simroot)" 997c478bd9Sstevel@tonic-gate fi 1007c478bd9Sstevel@tonic-gate} 1017c478bd9Sstevel@tonic-gate 102*d9638e54Smwsfunction wait_prompt 103*d9638e54Smws{ 104*d9638e54Smws echo "fmsim: [ Press return to $* ] \c" 105*d9638e54Smws mode=$(stty -g) 106*d9638e54Smws stty -echo -isig min 1 time 0 107*d9638e54Smws read s; echo 108*d9638e54Smws stty $mode 109*d9638e54Smws} 110*d9638e54Smws 1117c478bd9Sstevel@tonic-gatefunction die 1127c478bd9Sstevel@tonic-gate{ 1137c478bd9Sstevel@tonic-gate echo "fmsim: $*" >& 2 114*d9638e54Smws $opt_w && wait_prompt exit 1157c478bd9Sstevel@tonic-gate [[ -n "$simpid" ]] && exit 1 || exit 2 1167c478bd9Sstevel@tonic-gate} 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gatewhile [[ $# -gt 0 ]]; do 119*d9638e54Smws OPTIND=1; while getopts ':d:D:ehio:st:vVwx' c; do 1207c478bd9Sstevel@tonic-gate case "$c" in 1217c478bd9Sstevel@tonic-gate d) 1227c478bd9Sstevel@tonic-gate simroot=$OPTARG 1237c478bd9Sstevel@tonic-gate ;; 1247c478bd9Sstevel@tonic-gate D) 1257c478bd9Sstevel@tonic-gate truss_cmd=dtrace 1267c478bd9Sstevel@tonic-gate truss_args="-s $OPTARG -c" 1277c478bd9Sstevel@tonic-gate quote="'"; eol="" 1287c478bd9Sstevel@tonic-gate ;; 1297c478bd9Sstevel@tonic-gate e|v|V) 1307c478bd9Sstevel@tonic-gate dump_args="$dump_args -$c" 1317c478bd9Sstevel@tonic-gate ;; 132*d9638e54Smws h|i|s|w|x) 1337c478bd9Sstevel@tonic-gate eval opt_$c'='true 1347c478bd9Sstevel@tonic-gate ;; 1357c478bd9Sstevel@tonic-gate o) 1367c478bd9Sstevel@tonic-gate fmd_args="$fmd_args -o $OPTARG" 1377c478bd9Sstevel@tonic-gate ;; 1387c478bd9Sstevel@tonic-gate t) 1397c478bd9Sstevel@tonic-gate truss_cmd=truss 1407c478bd9Sstevel@tonic-gate truss_args="$OPTARG" 1417c478bd9Sstevel@tonic-gate ;; 1427c478bd9Sstevel@tonic-gate :) 1437c478bd9Sstevel@tonic-gate die "option requires an argument -- $OPTARG" 1447c478bd9Sstevel@tonic-gate ;; 1457c478bd9Sstevel@tonic-gate *) 1467c478bd9Sstevel@tonic-gate die "illegal option -- $OPTARG" 1477c478bd9Sstevel@tonic-gate ;; 1487c478bd9Sstevel@tonic-gate esac 1497c478bd9Sstevel@tonic-gate done 1507c478bd9Sstevel@tonic-gate let OPTIND="$OPTIND - 1"; shift $OPTIND 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate if [[ $# -gt 0 ]]; then 1537c478bd9Sstevel@tonic-gate if [[ -d $1 ]]; then 1547c478bd9Sstevel@tonic-gate files="$files $1/*" 1557c478bd9Sstevel@tonic-gate else 1567c478bd9Sstevel@tonic-gate files="$files $1" 1577c478bd9Sstevel@tonic-gate fi 1587c478bd9Sstevel@tonic-gate shift 1597c478bd9Sstevel@tonic-gate fi 1607c478bd9Sstevel@tonic-gatedone 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gatefor file in $files; do 1637c478bd9Sstevel@tonic-gate [[ -r $file ]] || die "input file is missing or not readable -- $file" 1647c478bd9Sstevel@tonic-gatedone 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gateif $opt_h || [[ -z "$files" && $opt_i = false ]]; then 167*d9638e54Smws echo "Usage: fmsim [-ehisvVwx] [-d dir] [-D a.d] [-o opt=val]" \ 1687c478bd9Sstevel@tonic-gate "[-t args] [file ...]" 1697c478bd9Sstevel@tonic-gate 170*d9638e54Smws echo "\t-d set the simulation root directory to the given location" 1717c478bd9Sstevel@tonic-gate echo "\t-D start fmd(1M) using dtrace(1M) and specified D script" 1727c478bd9Sstevel@tonic-gate echo "\t-e display error log content instead of fault log content" 1737c478bd9Sstevel@tonic-gate echo "\t-h display usage information for fmsim and exit" 1747c478bd9Sstevel@tonic-gate echo "\t-i set interactive mode: do not stop after sending events" 1757c478bd9Sstevel@tonic-gate echo "\t-o set fmd(1M) option to specified value during simulation" 1767c478bd9Sstevel@tonic-gate echo "\t-s set up simulation world but do not actually run simulation" 1777c478bd9Sstevel@tonic-gate echo "\t-t start fmd(1M) using truss(1) and specified arguments" 1787c478bd9Sstevel@tonic-gate echo "\t-v set verbose mode: display additional event detail" 1797c478bd9Sstevel@tonic-gate echo "\t-V set very verbose mode: display complete event contents" 180*d9638e54Smws echo "\t-w wait for a keypress after simulation completes" 1817c478bd9Sstevel@tonic-gate echo "\t-x delete simulation world if simulation is successful" 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate exit 0 1847c478bd9Sstevel@tonic-gatefi 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gateecho "fmsim: creating simulation world $simroot ... \c" 1877c478bd9Sstevel@tonic-gate[[ -d $simroot ]] || mkdir -p $simroot || exit 1 1887c478bd9Sstevel@tonic-gatecd $simroot || exit 1 1897c478bd9Sstevel@tonic-gateecho "done." 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gateecho "fmsim: populating /var ... \c" 1927c478bd9Sstevel@tonic-gatemkdir -p -m 0755 var/fm/fmd 1937c478bd9Sstevel@tonic-gatemkdir -p -m 0700 var/fm/fmd/ckpt 1947c478bd9Sstevel@tonic-gatemkdir -p -m 0700 var/fm/fmd/rsrc 195*d9638e54Smwsmkdir -p -m 0700 var/fm/fmd/xprt 1967c478bd9Sstevel@tonic-gateecho "done." 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/lib/fm from $sysroot ... \c" 1997c478bd9Sstevel@tonic-gate(cd $sysroot && find usr/lib/fm -depth -print | cpio -pdmu $simroot) 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gatefor platdir in $sysroot/usr/platform/*/lib/fm; do 2027c478bd9Sstevel@tonic-gate [[ -d $platdir ]] && platdir=${platdir#$sysroot} || continue 2037c478bd9Sstevel@tonic-gate echo "fmsim: populating $platdir from $sysroot ... \c" 2047c478bd9Sstevel@tonic-gate (cd $sysroot && find ${platdir#/} -depth -print | cpio -pdmu $simroot) 2057c478bd9Sstevel@tonic-gatedone 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/lib/locale/$LANG from $sysroot ... \c" 2087c478bd9Sstevel@tonic-gate(cd $sysroot && find usr/lib/locale/$LANG -depth -print | cpio -pdmu $simroot) 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/sbin from $sysroot ... \c" 2117c478bd9Sstevel@tonic-gate(cd $sysroot && list_cmds | cpio -pdmu $simroot) 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gateecho "fmsim: adding customizations:\c" 2147c478bd9Sstevel@tonic-gatecd $cwd || exit $1 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gatefor file in $files; do 2177c478bd9Sstevel@tonic-gate base=$(basename $file) 2187c478bd9Sstevel@tonic-gate case $base in 2197c478bd9Sstevel@tonic-gate *.cmd) die "\neversholt command file not yet supported -- $file" ;; 2207c478bd9Sstevel@tonic-gate fmd.conf) cp $file $simroot/etc/fm/fmd ;; 2217c478bd9Sstevel@tonic-gate *.conf) cp $file $simroot/usr/lib/fm/fmd/plugins ;; 2227c478bd9Sstevel@tonic-gate *.dict) cp $file $simroot/usr/lib/fm/dict ;; 2237c478bd9Sstevel@tonic-gate *.eft) die "\neversholt fault tree file not yet supported -- $file" ;; 2247c478bd9Sstevel@tonic-gate *.esc) die "\neversholt source file not yet supported -- $file" ;; 2257c478bd9Sstevel@tonic-gate *.inj) inj_args="$inj_args $file" ;; 2267c478bd9Sstevel@tonic-gate *.log) inj_args="$inj_args $file" ;; 2277c478bd9Sstevel@tonic-gate *log) inj_args="$inj_args $file" ;; 2287c478bd9Sstevel@tonic-gate *.mo) cp $file $simroot/usr/lib/locale/$LANG/LC_MESSAGES ;; 2297c478bd9Sstevel@tonic-gate *.so) cp_so $file $simroot ;; 2307c478bd9Sstevel@tonic-gate *.topo) cp $file $simroot/usr/lib/fm/topo ;; 2317c478bd9Sstevel@tonic-gate *) die "\nunknown file type or suffix -- $file" ;; 2327c478bd9Sstevel@tonic-gate esac 2337c478bd9Sstevel@tonic-gate echo " $base\c" 2347c478bd9Sstevel@tonic-gatedone 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gatecd $simroot || exit 1 2377c478bd9Sstevel@tonic-gateecho " done." 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gateecho "fmsim: generating script ... \c" 2407c478bd9Sstevel@tonic-gatecat >$simscript <<EOS 2417c478bd9Sstevel@tonic-gate#!/bin/ksh -p 2427c478bd9Sstevel@tonic-gate# 243*d9638e54Smws# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2447c478bd9Sstevel@tonic-gate# Use is subject to license terms. 2457c478bd9Sstevel@tonic-gate# 2467c478bd9Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate# 2497c478bd9Sstevel@tonic-gate# fmsim(1M) script generated for $simroot $(date) 2507c478bd9Sstevel@tonic-gate# 2517c478bd9Sstevel@tonic-gate 252*d9638e54Smwsexport LD_LIBRARY_PATH=$simroot/usr/lib:$simroot/usr/lib/fm 253*d9638e54Smwsexport LD_LIBRARY_PATH_64=$simroot/usr/lib/64:$simroot/usr/lib/fm/$isa64 254*d9638e54Smws 255*d9638e54Smwsexport _THREAD_ERROR_DETECTION=2 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gateexec $truss_cmd $truss_args $quote./usr/lib/fm/fmd/fmd -R $simroot $eol 258*d9638e54Smws -o fg=true -o clock=simulated $eol 259*d9638e54Smws -o rpc.adm.prog=0 -o rpc.adm.path=$simroot/rpc $eol 260*d9638e54Smws -o sysevent-transport:device=/dev/null $eol 261*d9638e54Smws -o sysevent-transport:channel=$simchan $fmd_args$quote 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gateEOS 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gatechmod 0555 $simscript 2667c478bd9Sstevel@tonic-gateecho "done." 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gateif $opt_s; then 2697c478bd9Sstevel@tonic-gate echo "fmsim: simulation is saved in $simroot" 2707c478bd9Sstevel@tonic-gate exit 0 2717c478bd9Sstevel@tonic-gatefi 2727c478bd9Sstevel@tonic-gate 273*d9638e54Smwsexport LD_LIBRARY_PATH=$simroot/usr/lib:$simroot/usr/lib/fm 274*d9638e54Smwsexport LD_LIBRARY_PATH_64=$simroot/usr/lib/64:$simroot/usr/lib/fm/$isa64 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gateecho "fmsim: simulation $$ running fmd(1M)\c" 2777c478bd9Sstevel@tonic-gate./usr/lib/fm/fmd/fmd -V | cut -d: -f2 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate./$simscript & 2807c478bd9Sstevel@tonic-gatesimpid=$! 2817c478bd9Sstevel@tonic-gatetrap '' INT HUP 2827c478bd9Sstevel@tonic-gatecd $cwd 2837c478bd9Sstevel@tonic-gatei=0 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gatewhile [[ ! -s $simroot/rpc ]]; do 2867c478bd9Sstevel@tonic-gate [[ $i -ge 30 ]] && kill -9 $simpid >/dev/null 2>&1 2877c478bd9Sstevel@tonic-gate kill -0 $simpid >/dev/null 2>&1 || break 2887c478bd9Sstevel@tonic-gate let i="$i + 1" 2897c478bd9Sstevel@tonic-gate sleep 1 2907c478bd9Sstevel@tonic-gatedone 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gatekill -0 $simpid >/dev/null 2>&1 || { 2937c478bd9Sstevel@tonic-gate wait $simpid 2947c478bd9Sstevel@tonic-gate wait_status $? 2957c478bd9Sstevel@tonic-gate} 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gateecho "fmsim: rpc adm requests can rendezvous at" $(<$simroot/rpc) 2987c478bd9Sstevel@tonic-gateecho "fmsim: injectors should use channel $simchan" 2997c478bd9Sstevel@tonic-gateecho "fmsim: debuggers should attach to PID $simpid" 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gatefor arg in $inj_args; do 3027c478bd9Sstevel@tonic-gate echo "fmsim: injecting events from $arg ... \c" 3037c478bd9Sstevel@tonic-gate $simroot/usr/lib/fm/fmd/fminject -q -c $simchan $arg || { 3047c478bd9Sstevel@tonic-gate echo "fmsim: fminject failed for $arg: aborting simulation" >& 2 3057c478bd9Sstevel@tonic-gate kill $simpid >/dev/null 2>&1 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate echo "done." 3087c478bd9Sstevel@tonic-gatedone 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gateif [[ $opt_i = false ]]; then 3117c478bd9Sstevel@tonic-gate echo "fmsim: injecting event to advance to end-of-time ... \c" 3127c478bd9Sstevel@tonic-gate echo 'endhrtime;' | $simroot/usr/lib/fm/fmd/fminject -q -c $simchan - 3137c478bd9Sstevel@tonic-gate echo "done." 3147c478bd9Sstevel@tonic-gatefi 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gatewait $simpid 3177c478bd9Sstevel@tonic-gatestatus=$? 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gateif [[ -f $simroot/var/fm/fmd/errlog ]]; then 3207c478bd9Sstevel@tonic-gate echo; $simroot/usr/sbin/fmdump -R $simroot $dump_args; echo 3217c478bd9Sstevel@tonic-gatefi 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gatewait_status $status 324*d9638e54Smws$opt_w && wait_prompt exit 3257c478bd9Sstevel@tonic-gate$opt_x && rm -rf $simroot 326*d9638e54Smws 3277c478bd9Sstevel@tonic-gateexit 0 328