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 60eb822a1Scindi# Common Development and Distribution License (the "License"). 70eb822a1Scindi# 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# 230eb822a1Scindi# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate# Use is subject to license terms. 257c478bd9Sstevel@tonic-gate# 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gateexport PATH=/usr/bin:/usr/sbin:/usr/ccs/bin 287c478bd9Sstevel@tonic-gateunset ENV TMPDIR 297c478bd9Sstevel@tonic-gateumask 022 307c478bd9Sstevel@tonic-gatecwd=$PWD 317c478bd9Sstevel@tonic-gate 32d9638e54Smwsisa=$(uname -p) 33d9638e54Smwsif [[ $isa = sparc ]]; then 34d9638e54Smws isa64=sparcv9 35d9638e54Smwselif [[ $isa = i386 ]]; then 36d9638e54Smws isa64=amd64 37d9638e54Smwselse 38d9638e54Smws isa64=unknown 39d9638e54Smwsfi 40d9638e54Smws 417c478bd9Sstevel@tonic-gateif [[ -n "$CODEMGR_WS" ]]; then 42d9638e54Smws sysroot=$CODEMGR_WS/proto/root_$isa 437c478bd9Sstevel@tonic-gateelif [[ -n "$ROOT" ]]; then 447c478bd9Sstevel@tonic-gate sysroot=$ROOT 457c478bd9Sstevel@tonic-gateelse 467c478bd9Sstevel@tonic-gate sysroot=/ 477c478bd9Sstevel@tonic-gatefi 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gatequote= 507c478bd9Sstevel@tonic-gateeol='\' 517c478bd9Sstevel@tonic-gatefiles= 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gatesimchan=com.sun:fm:fmd$$ 547c478bd9Sstevel@tonic-gatesimroot=/tmp/fmd.$$ 557c478bd9Sstevel@tonic-gatesimscript=run 567c478bd9Sstevel@tonic-gatesimpid= 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gatetruss_cmd= 597c478bd9Sstevel@tonic-gatetruss_args= 607c478bd9Sstevel@tonic-gatedump_args= 617c478bd9Sstevel@tonic-gateinj_args= 627c478bd9Sstevel@tonic-gatefmd_args= 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gateopt_h=false 657c478bd9Sstevel@tonic-gateopt_i=false 667c478bd9Sstevel@tonic-gateopt_s=false 67d9638e54Smwsopt_w=false 687c478bd9Sstevel@tonic-gateopt_x=false 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gatefunction cp_so 717c478bd9Sstevel@tonic-gate{ 727c478bd9Sstevel@tonic-gate nm -ghp $1 2>/dev/null | while read addr type name; do 737c478bd9Sstevel@tonic-gate [[ $type != T ]] && continue 747c478bd9Sstevel@tonic-gate case $name in 757c478bd9Sstevel@tonic-gate _fmd_init) cp $1 $2/usr/lib/fm/fmd/plugins; return ;; 767c478bd9Sstevel@tonic-gate fmd_fmri_nvl2str) cp $1 $2/usr/lib/fm/fmd/schemes; return ;; 770eb822a1Scindi topo_load) cp $1 $2/usr/lib/fm/topo/plugins; return ;; 787c478bd9Sstevel@tonic-gate esac 797c478bd9Sstevel@tonic-gate done 807c478bd9Sstevel@tonic-gate die "\nunknown .so type -- $1" 817c478bd9Sstevel@tonic-gate} 827c478bd9Sstevel@tonic-gate 830eb822a1Scindifunction cp_topo 840eb822a1Scindi{ 850eb822a1Scindi mkdir -p $2/usr/lib/fm/topo/maps 860eb822a1Scindi cp $1 $2/usr/lib/fm/topo/maps; 870eb822a1Scindi for platdir in $2/usr/platform/*/lib/fm/topo/maps; do 880eb822a1Scindi rm -f $platdir/* 2>/dev/null 890eb822a1Scindi done 900eb822a1Scindi} 910eb822a1Scindi 927c478bd9Sstevel@tonic-gatefunction list_cmds 937c478bd9Sstevel@tonic-gate{ 947c478bd9Sstevel@tonic-gate for cmd in fmadm fmdump fmstat; do 957c478bd9Sstevel@tonic-gate echo usr/sbin/$cmd 967c478bd9Sstevel@tonic-gate done 977c478bd9Sstevel@tonic-gate} 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gatefunction wait_status 1007c478bd9Sstevel@tonic-gate{ 1017c478bd9Sstevel@tonic-gate if [[ $1 -gt 128 ]]; then 1027c478bd9Sstevel@tonic-gate sig=$(kill -l $(($1 - 128))) 1037c478bd9Sstevel@tonic-gate die "fmd terminated from signal $sig (see $simroot)" 1047c478bd9Sstevel@tonic-gate elif [[ $1 -ne 0 ]]; then 1057c478bd9Sstevel@tonic-gate die "fmd terminated with status $1 (see $simroot)" 1067c478bd9Sstevel@tonic-gate fi 1077c478bd9Sstevel@tonic-gate} 1087c478bd9Sstevel@tonic-gate 109d9638e54Smwsfunction wait_prompt 110d9638e54Smws{ 111d9638e54Smws echo "fmsim: [ Press return to $* ] \c" 112d9638e54Smws mode=$(stty -g) 113d9638e54Smws stty -echo -isig min 1 time 0 114d9638e54Smws read s; echo 115d9638e54Smws stty $mode 116d9638e54Smws} 117d9638e54Smws 1187c478bd9Sstevel@tonic-gatefunction die 1197c478bd9Sstevel@tonic-gate{ 1207c478bd9Sstevel@tonic-gate echo "fmsim: $*" >& 2 121d9638e54Smws $opt_w && wait_prompt exit 1227c478bd9Sstevel@tonic-gate [[ -n "$simpid" ]] && exit 1 || exit 2 1237c478bd9Sstevel@tonic-gate} 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gatewhile [[ $# -gt 0 ]]; do 126d9638e54Smws OPTIND=1; while getopts ':d:D:ehio:st:vVwx' c; do 1277c478bd9Sstevel@tonic-gate case "$c" in 1287c478bd9Sstevel@tonic-gate d) 1297c478bd9Sstevel@tonic-gate simroot=$OPTARG 1307c478bd9Sstevel@tonic-gate ;; 1317c478bd9Sstevel@tonic-gate D) 1327c478bd9Sstevel@tonic-gate truss_cmd=dtrace 1337c478bd9Sstevel@tonic-gate truss_args="-s $OPTARG -c" 1347c478bd9Sstevel@tonic-gate quote="'"; eol="" 1357c478bd9Sstevel@tonic-gate ;; 1367c478bd9Sstevel@tonic-gate e|v|V) 1377c478bd9Sstevel@tonic-gate dump_args="$dump_args -$c" 1387c478bd9Sstevel@tonic-gate ;; 139d9638e54Smws h|i|s|w|x) 1407c478bd9Sstevel@tonic-gate eval opt_$c'='true 1417c478bd9Sstevel@tonic-gate ;; 1427c478bd9Sstevel@tonic-gate o) 1437c478bd9Sstevel@tonic-gate fmd_args="$fmd_args -o $OPTARG" 1447c478bd9Sstevel@tonic-gate ;; 1457c478bd9Sstevel@tonic-gate t) 1467c478bd9Sstevel@tonic-gate truss_cmd=truss 1477c478bd9Sstevel@tonic-gate truss_args="$OPTARG" 1487c478bd9Sstevel@tonic-gate ;; 1497c478bd9Sstevel@tonic-gate :) 1507c478bd9Sstevel@tonic-gate die "option requires an argument -- $OPTARG" 1517c478bd9Sstevel@tonic-gate ;; 1527c478bd9Sstevel@tonic-gate *) 1537c478bd9Sstevel@tonic-gate die "illegal option -- $OPTARG" 1547c478bd9Sstevel@tonic-gate ;; 1557c478bd9Sstevel@tonic-gate esac 1567c478bd9Sstevel@tonic-gate done 1577c478bd9Sstevel@tonic-gate let OPTIND="$OPTIND - 1"; shift $OPTIND 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if [[ $# -gt 0 ]]; then 1607c478bd9Sstevel@tonic-gate if [[ -d $1 ]]; then 1617c478bd9Sstevel@tonic-gate files="$files $1/*" 1627c478bd9Sstevel@tonic-gate else 1637c478bd9Sstevel@tonic-gate files="$files $1" 1647c478bd9Sstevel@tonic-gate fi 1657c478bd9Sstevel@tonic-gate shift 1667c478bd9Sstevel@tonic-gate fi 1677c478bd9Sstevel@tonic-gatedone 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gatefor file in $files; do 1707c478bd9Sstevel@tonic-gate [[ -r $file ]] || die "input file is missing or not readable -- $file" 1717c478bd9Sstevel@tonic-gatedone 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gateif $opt_h || [[ -z "$files" && $opt_i = false ]]; then 174d9638e54Smws echo "Usage: fmsim [-ehisvVwx] [-d dir] [-D a.d] [-o opt=val]" \ 1757c478bd9Sstevel@tonic-gate "[-t args] [file ...]" 1767c478bd9Sstevel@tonic-gate 177d9638e54Smws echo "\t-d set the simulation root directory to the given location" 178*bbf21555SRichard Lowe echo "\t-D start fmd(8) using dtrace(8) and specified D script" 1797c478bd9Sstevel@tonic-gate echo "\t-e display error log content instead of fault log content" 1807c478bd9Sstevel@tonic-gate echo "\t-h display usage information for fmsim and exit" 1817c478bd9Sstevel@tonic-gate echo "\t-i set interactive mode: do not stop after sending events" 182*bbf21555SRichard Lowe echo "\t-o set fmd(8) option to specified value during simulation" 1837c478bd9Sstevel@tonic-gate echo "\t-s set up simulation world but do not actually run simulation" 184*bbf21555SRichard Lowe echo "\t-t start fmd(8) using truss(1) and specified arguments" 1857c478bd9Sstevel@tonic-gate echo "\t-v set verbose mode: display additional event detail" 1867c478bd9Sstevel@tonic-gate echo "\t-V set very verbose mode: display complete event contents" 187d9638e54Smws echo "\t-w wait for a keypress after simulation completes" 1887c478bd9Sstevel@tonic-gate echo "\t-x delete simulation world if simulation is successful" 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate exit 0 1917c478bd9Sstevel@tonic-gatefi 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gateecho "fmsim: creating simulation world $simroot ... \c" 1947c478bd9Sstevel@tonic-gate[[ -d $simroot ]] || mkdir -p $simroot || exit 1 1957c478bd9Sstevel@tonic-gatecd $simroot || exit 1 1967c478bd9Sstevel@tonic-gateecho "done." 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gateecho "fmsim: populating /var ... \c" 1997c478bd9Sstevel@tonic-gatemkdir -p -m 0755 var/fm/fmd 2007c478bd9Sstevel@tonic-gatemkdir -p -m 0700 var/fm/fmd/ckpt 2017c478bd9Sstevel@tonic-gatemkdir -p -m 0700 var/fm/fmd/rsrc 202d9638e54Smwsmkdir -p -m 0700 var/fm/fmd/xprt 2037c478bd9Sstevel@tonic-gateecho "done." 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/lib/fm from $sysroot ... \c" 2067c478bd9Sstevel@tonic-gate(cd $sysroot && find usr/lib/fm -depth -print | cpio -pdmu $simroot) 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gatefor platdir in $sysroot/usr/platform/*/lib/fm; do 2097c478bd9Sstevel@tonic-gate [[ -d $platdir ]] && platdir=${platdir#$sysroot} || continue 2107c478bd9Sstevel@tonic-gate echo "fmsim: populating $platdir from $sysroot ... \c" 2117c478bd9Sstevel@tonic-gate (cd $sysroot && find ${platdir#/} -depth -print | cpio -pdmu $simroot) 2127c478bd9Sstevel@tonic-gatedone 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/lib/locale/$LANG from $sysroot ... \c" 2157c478bd9Sstevel@tonic-gate(cd $sysroot && find usr/lib/locale/$LANG -depth -print | cpio -pdmu $simroot) 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gateecho "fmsim: populating /usr/sbin from $sysroot ... \c" 2187c478bd9Sstevel@tonic-gate(cd $sysroot && list_cmds | cpio -pdmu $simroot) 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gateecho "fmsim: adding customizations:\c" 2217c478bd9Sstevel@tonic-gatecd $cwd || exit $1 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gatefor file in $files; do 2247c478bd9Sstevel@tonic-gate base=$(basename $file) 2257c478bd9Sstevel@tonic-gate case $base in 2267c478bd9Sstevel@tonic-gate *.cmd) die "\neversholt command file not yet supported -- $file" ;; 2277c478bd9Sstevel@tonic-gate fmd.conf) cp $file $simroot/etc/fm/fmd ;; 2287c478bd9Sstevel@tonic-gate *.conf) cp $file $simroot/usr/lib/fm/fmd/plugins ;; 2297c478bd9Sstevel@tonic-gate *.dict) cp $file $simroot/usr/lib/fm/dict ;; 2300eb822a1Scindi *.eft) cp $file $simroot/usr/lib/fm/eft ;; 2317c478bd9Sstevel@tonic-gate *.esc) die "\neversholt source file not yet supported -- $file" ;; 2327c478bd9Sstevel@tonic-gate *.inj) inj_args="$inj_args $file" ;; 2337c478bd9Sstevel@tonic-gate *.log) inj_args="$inj_args $file" ;; 2347c478bd9Sstevel@tonic-gate *log) inj_args="$inj_args $file" ;; 2357c478bd9Sstevel@tonic-gate *.mo) cp $file $simroot/usr/lib/locale/$LANG/LC_MESSAGES ;; 2367c478bd9Sstevel@tonic-gate *.so) cp_so $file $simroot ;; 2370eb822a1Scindi *.topo) die "\n .topo files not supported -- $file" ;; 2380eb822a1Scindi *.xml) cp_topo $file $simroot ;; 2397c478bd9Sstevel@tonic-gate *) die "\nunknown file type or suffix -- $file" ;; 2407c478bd9Sstevel@tonic-gate esac 2417c478bd9Sstevel@tonic-gate echo " $base\c" 2427c478bd9Sstevel@tonic-gatedone 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gatecd $simroot || exit 1 2457c478bd9Sstevel@tonic-gateecho " done." 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gateecho "fmsim: generating script ... \c" 2487c478bd9Sstevel@tonic-gatecat >$simscript <<EOS 2497c478bd9Sstevel@tonic-gate#!/bin/ksh -p 2507c478bd9Sstevel@tonic-gate# 251d9638e54Smws# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2527c478bd9Sstevel@tonic-gate# Use is subject to license terms. 2537c478bd9Sstevel@tonic-gate# 2540eb822a1Scindi#ident "@(#)fmsim.ksh 1.5 06/10/11 SMI" 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate# 257*bbf21555SRichard Lowe# fmsim(8) script generated for $simroot $(date) 2587c478bd9Sstevel@tonic-gate# 2597c478bd9Sstevel@tonic-gate 260d9638e54Smwsexport LD_LIBRARY_PATH=$simroot/usr/lib:$simroot/usr/lib/fm 261d9638e54Smwsexport LD_LIBRARY_PATH_64=$simroot/usr/lib/64:$simroot/usr/lib/fm/$isa64 262d9638e54Smws 263d9638e54Smwsexport _THREAD_ERROR_DETECTION=2 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gateexec $truss_cmd $truss_args $quote./usr/lib/fm/fmd/fmd -R $simroot $eol 266d9638e54Smws -o fg=true -o clock=simulated $eol 267d9638e54Smws -o rpc.adm.prog=0 -o rpc.adm.path=$simroot/rpc $eol 268d9638e54Smws -o sysevent-transport:device=/dev/null $eol 269d9638e54Smws -o sysevent-transport:channel=$simchan $fmd_args$quote 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gateEOS 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gatechmod 0555 $simscript 2747c478bd9Sstevel@tonic-gateecho "done." 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gateif $opt_s; then 2777c478bd9Sstevel@tonic-gate echo "fmsim: simulation is saved in $simroot" 2787c478bd9Sstevel@tonic-gate exit 0 2797c478bd9Sstevel@tonic-gatefi 2807c478bd9Sstevel@tonic-gate 281d9638e54Smwsexport LD_LIBRARY_PATH=$simroot/usr/lib:$simroot/usr/lib/fm 282d9638e54Smwsexport LD_LIBRARY_PATH_64=$simroot/usr/lib/64:$simroot/usr/lib/fm/$isa64 2837c478bd9Sstevel@tonic-gate 284*bbf21555SRichard Loweecho "fmsim: simulation $$ running fmd(8)\c" 2857c478bd9Sstevel@tonic-gate./usr/lib/fm/fmd/fmd -V | cut -d: -f2 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate./$simscript & 2887c478bd9Sstevel@tonic-gatesimpid=$! 2897c478bd9Sstevel@tonic-gatetrap '' INT HUP 2907c478bd9Sstevel@tonic-gatecd $cwd 2917c478bd9Sstevel@tonic-gatei=0 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gatewhile [[ ! -s $simroot/rpc ]]; do 2947c478bd9Sstevel@tonic-gate [[ $i -ge 30 ]] && kill -9 $simpid >/dev/null 2>&1 2957c478bd9Sstevel@tonic-gate kill -0 $simpid >/dev/null 2>&1 || break 2967c478bd9Sstevel@tonic-gate let i="$i + 1" 2977c478bd9Sstevel@tonic-gate sleep 1 2987c478bd9Sstevel@tonic-gatedone 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gatekill -0 $simpid >/dev/null 2>&1 || { 3017c478bd9Sstevel@tonic-gate wait $simpid 3027c478bd9Sstevel@tonic-gate wait_status $? 3037c478bd9Sstevel@tonic-gate} 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gateecho "fmsim: rpc adm requests can rendezvous at" $(<$simroot/rpc) 3067c478bd9Sstevel@tonic-gateecho "fmsim: injectors should use channel $simchan" 3077c478bd9Sstevel@tonic-gateecho "fmsim: debuggers should attach to PID $simpid" 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gatefor arg in $inj_args; do 3107c478bd9Sstevel@tonic-gate echo "fmsim: injecting events from $arg ... \c" 3117c478bd9Sstevel@tonic-gate $simroot/usr/lib/fm/fmd/fminject -q -c $simchan $arg || { 3127c478bd9Sstevel@tonic-gate echo "fmsim: fminject failed for $arg: aborting simulation" >& 2 3137c478bd9Sstevel@tonic-gate kill $simpid >/dev/null 2>&1 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate echo "done." 3167c478bd9Sstevel@tonic-gatedone 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gateif [[ $opt_i = false ]]; then 3197c478bd9Sstevel@tonic-gate echo "fmsim: injecting event to advance to end-of-time ... \c" 3207c478bd9Sstevel@tonic-gate echo 'endhrtime;' | $simroot/usr/lib/fm/fmd/fminject -q -c $simchan - 3217c478bd9Sstevel@tonic-gate echo "done." 3227c478bd9Sstevel@tonic-gatefi 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gatewait $simpid 3257c478bd9Sstevel@tonic-gatestatus=$? 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gateif [[ -f $simroot/var/fm/fmd/errlog ]]; then 3287c478bd9Sstevel@tonic-gate echo; $simroot/usr/sbin/fmdump -R $simroot $dump_args; echo 3297c478bd9Sstevel@tonic-gatefi 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gatewait_status $status 332d9638e54Smws$opt_w && wait_prompt exit 3337c478bd9Sstevel@tonic-gate$opt_x && rm -rf $simroot 334d9638e54Smws 3357c478bd9Sstevel@tonic-gateexit 0 336