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