#! /bin/sh # # $Id: nsrsup.sh,v 6.20.62.1 2006/04/26 19:32:50 castrv Exp $ Copyright (c) 2003-2006, EMC Corporation. # # All rights reserved. # # # initialize some program names; We'll use 'whence' later to get the # full path # AWK=awk CAT=cat COMPRESS=compress EGREP=egrep FIND=find GREP=grep MMINFO=mminfo NSRJB=nsrjb NSRLS=nsrls PRINTF=printf RM=rm SAVEGRP=savegrp SED=sed STRINGS=strings SUM=sum RPCINFO=rpcinfo TEE='tee -a' TR=tr WHAT=what XARGS=xargs ######################################################################## # General auxilliary functions ######################################################################## # # Use this when each command line arg corresponds to a variable # that needs to be set. the first arg holds the 1-1 relationship # between the cmd line args and the variables to be set. # Format of first arg is a sequence of tokens of the form # cmd-line-arg:variable-to-set # $* -- command line args to be processed. # in $1 the variables to match and set # $2 the command line arg to match # getargs() { l_args="$1"; shift for arg in `echo X$@ | $SED 's/^X//' | $TR ',' ' '`; do l_foundarg=no case $arg in '?' ) usage ;; *=* ) arg=`echo $arg | cut -d= -f1` val=`echo $arg | cut -d= -f2` ;; * ) arg="$arg" val=yes ;; esac for j in $l_args; do thisarg=`echo $j | cut -d: -f1` if [ X"$thisarg" = X"$arg" ]; then thisvar=`echo $j | cut -d: -f2` eval "$thisvar=\$val" l_foundarg=yes break fi done if [ X"$l_foundarg" != Xyes ]; then usage fi done } # # the first arg holds variable name to set, the rest is its value # as given by a command line argument, or '?' if no command # line arg was given # getparam() { arg="$1"; shift case "$1" in '?' ) usage ;; * ) eval "$arg='`echo X$@ | $SED 's/^X//' | $TR ',' ' '`'" ;; esac } # # the first argument holds the name of the variable to set, the second # is the command line flag, the rest is the command line # getparam_long filelist --file-list --file-list=hello,world # getparam_long() { l_arg="$1"; shift l_command_arg="$1"; shift l_tmp=`echo X"$1" | $SED "s/^X$l_command_arg=//" | $TR , ' '` eval "$l_arg=\"$l_tmp\"" } # # process long style arguments and set them to yes or no # $1 is the actual argument to script # $2 to $n is the allowed long style args with mapping if necessary # if there is a mapping like user-info:userinfo then the command line # arg is --user-info but the variable to set is called userinfo # set_long_arg_yes_no() { l_arg="$1"; shift l_foundarg=no for arg_map in "$@"; do case $arg_map in *:*) command_line=`echo $arg_map | cut -f1 -d:` variable=`echo $arg_map | cut -f2 -d:` ;; *) command_line="$arg_map" variable="$arg_map" ;; esac case $l_arg in --$command_line ) eval "$variable=yes" ; l_foundarg=yes ; break ;; --no$command_line ) eval "$variable=no" ; l_foundarg=yes ; break ;; --$command_line=yes ) eval "$variable=yes" ; l_foundarg=yes ; break ;; --$command_line=no ) eval "$variable=no" ; l_foundarg=yes ; break ;; esac done if [ X"$l_foundarg" != Xyes ]; then echo Illegal option -- $l_arg 1>&2 long_usage fi } # # process simple arguments with mapping # first argument is the switch to process, the rest are mappings of # switch:variable:value where switch is the switch to map, the variable # is the variable to set and value is the value to set it to if matched # eg. # set_arg $1 -a:all:yes -A:all:no -v:verbose:yes -V:verbose:no # set_arg $1 a:all:yes A:all:no v:verbose:yes V:verbose:no # a single flag can set more than one variable # set_arg L L:log_nsr:no L:log_sysmess:no # set_arg() { eval `for l_arg in "$@"; do echo X$l_arg; done | $AWK -F: 'NR == 1 { arg = $0; next } { if ($1 == arg) printf("%s=\"%s\"\n", $2, $3) }'` } # # function to test user input # Confirm() { $PRINTF '%s' "$1 [y/n]? " 1>&2 while true; do read ans case $ans in [yY] | [yY]es | YES) ans=yes break ;; [nN] | [nN]o | NO ) ans=no break ;; * ) $PRINTF '%s' "'Yes' or 'No' please: " 1>&2 ;; esac done $PRINTF '%s\n' $ans } # # $1 is the prompt # $2 is the possible default answer # Getinput() { if [ X"$2" = X ]; then while true; do $PRINTF '%s' "$1: " 1>&2 read ans [ X"$ans" != X ] && break done else while true; do $PRINTF '%s' "$1 [$2]: " 1>&2 read ans if [ X"$ans" != X ]; then break else ans="$2" break fi done fi $PRINTF '%s\n' "$ans" } # # usage: waittil nn pid # Assume process with given pid is running. Requires AWK to be defined # Wait not longer than nn seconds for it to # complete. Quit when either nn secs have elapsed, or process pid is done, # whichever comes first. # waittil() { nn="$1" pid="$2" count=1; running='' while [ "$count" -le "$nn" ]; do sleep 1 running=`ps -e | $AWK '$1 == pidstr' pidstr=$pid` if [ X"$running" = X ]; then break fi count=`expr $count + 1` done if [ X"$running" != X ]; then kill -9 "$pid" > /dev/null 2>&1 return 1 fi } # # sanitize the path by getting rid of duplicates, null entries, relative # paths # sanitize_path() { PATH=`echo "$PATH" | $AWK '{ n = split($0, a, ":"); for (i = 1; i <= n; ++i) { if (length(a[i]) > 0 && a[i] ~ /^\//) print a[i]; for (j = i + 1; j <= n; ++j) { if (a[i] == a[j]) a[j] = ""; } } }' | $AWK 'NR == 1 { OFS = ""; ORS = ""; print $0; next } { print ":", $0 }'` } # # $1 is the name of a variable, not the contents! # $2 is the separator # remove_dups() { eval "echo \$$1" | $AWK '{ n = split($0, a, sep); for (i = 1; i <= n; ++i) { if (length(a[i]) > 0) print a[i]; for (j = i + 1; j <= n; ++j) { if (a[i] == a[j]) a[j] = ""; } } }' sep="$2" | $AWK 'NR == 1 { OFS = ""; ORS = ""; print $0; next } { print sep, $0 }' sep="$2" } ######################################################################## # Specific auxilliary functions ######################################################################## #################### html related output processing #################### # # print a table of contents # doesn't do anything unless --html-output was specified # print_toc() { if [ X"$usehtml" = Xyes ]; then ( cat <<__EOF__ __EOF__ echo '
General Machine Information General NetWorker Information Server Specific NetWorker Information
    ' echo '
  • ' if [ X"$ps" = Xyes ]; then $PRINTF '%s\n' 'Process Status' else echo Process Status'
    --ps' fi echo '
  • ' if [ X"$netstat" = Xyes ]; then $PRINTF '%s\n' 'Network Status' else echo Network Status'
    --netstat' fi echo '
  • ' if [ X"$swapinfo" = Xyes ]; then $PRINTF '%s\n' 'Swap Information' else echo Swap Information'
    --swap-info' fi echo '
  • ' if [ X"$vmstat" = Xyes ]; then $PRINTF '%s\n' 'Virtual Memory Statistics' else echo Virtual Memory Statistics'
    --vmstat' fi echo '
  • ' if [ X"$ipcsinfo" = Xyes -a X"$IPCS" != X ]; then $PRINTF '%s\n' 'IPC Facilities' else echo IPC Facilities'
    --ipcs-info' fi echo '
  • ' if [ X"$dmesg" = Xyes -a X"$DMESG" != X ]; then $PRINTF '%s\n' 'System Diagnostics Messages' else echo System Diagnostics Messages'
    --dmesg' fi echo '
  • ' if [ X"$hwconf" = Xyes ]; then $PRINTF '%s\n' 'Hardware Inventory / Kernel Configuration' else echo 'Hardware Inventory / Kernel Configuration
    --hw-conf' fi echo '
  • ' if [ X"$showpkgs" = Xyes ]; then $PRINTF '%s\n' 'Installed Software' else echo Installed Software'
    --show-pkgs' fi echo '
    ' echo '
  • ' if [ X"$ckpath" = Xyes ]; then $PRINTF '%s\n' 'Executable Checksums & Release Info' else echo 'Executable Checksums & Release Info
    --check-path' fi echo '
  • ' if [ X"$rpcinfo" = Xyes ]; then $PRINTF '%s\n' 'Server List' else echo Server List'
    --rpcinfo' fi echo '
  • ' if [ X"$tracelist" != X ]; then $PRINTF '%s\n' 'Traced NetWorker Processes' else echo Traced NetWorker Processes fi echo '
  • ' if [ X"$log_nsrd" = Xyes ]; then $PRINTF '%s\n' 'Daemon Log' else echo Daemon Log'
    --daemon-log' fi echo '
  • ' if [ X"$log_nsr" = Xyes -o \ X"$log_sysmess" = Xyes -o X"$filelist" != X -o \ X"$greplist" != X ]; then $PRINTF '%s\n' 'Log Files' else echo Log Files fi echo '
    ' echo '
  • ' if [ X"$mminfoarg" != X ]; then $PRINTF '%s\n' 'Volume Information' else echo Volume Information'
    --mminfo' fi echo '
  • ' if [ X"$indexes" = Xyes ]; then $PRINTF '%s\n' 'Index Information' else echo Index Information'
    --indexes' fi echo '
  • ' if [ X"$savegrp" = Xyes ]; then $PRINTF '%s\n' 'Group Information' else echo Group Information'
    --savegrp' fi echo '
  • ' if [ X"$clients" = Xyes ]; then $PRINTF '%s\n' 'Client Daemon Probe' else echo Client Daemon Probe'
    --clients' fi echo '
  • ' if [ X"$clients" = Xyes ]; then $PRINTF '%s\n' 'Client List' else echo Client List'
    --clients' fi echo '
  • ' if [ X"$cores" = Xyes ]; then $PRINTF '%s\n' 'Core Analysis' else echo Core Analysis'
    --dbg-cores' fi echo '
  • ' if [ X"$rap_res" = Xyes ]; then $PRINTF '%s\n' 'Resource Files: Dynamic Attributes' else echo Resource Files: Dynamic Attributes'
    --rap-res' fi echo '
  • ' if [ X"$nsr_res" = Xyes ]; then $PRINTF '%s\n' 'Resource Files: Attributes' else echo Resource Files: Attributes'
    --nsr-res' fi echo '
  • ' if [ X"$daemons" = Xyes ]; then $PRINTF '%s\n' 'Debugger Analysis on NetWorker Daemons' else echo 'Debugger Analysis on NetWorker Daemons
    --dbg-daemons' fi echo '
  • ' if [ X"$jbinfo" = Xyes ]; then $PRINTF '%s\n' 'Jukebox Information' else echo Jukebox Information'
    --jb-info' fi echo '

' ) | $of fi } print_message() { ( if [ X"$usehtml" = Xyes ]; then echo "

$*



" else $PRINTF '\n%s\n%s\n%s\n\n\n' "$sep" "$*" "$sep" fi ) | $of } print_error() { ( if [ X"$usehtml" = Xyes ]; then echo "

Error: $*



" else $PRINTF '\n%s\nError: %s\n%s\n\n\n' "$sep" "$*" "$sep" fi ) | $of } # # print name of command and then run it # print_command() { ( if [ X"$usehtml" = Xyes ]; then echo "$*
"
	( eval "$@" ) 2>&1
	echo '


' else $PRINTF '%s\n%s\n%s\n\n' "$sep" "$*" "$sep" ( eval "$@" ) 2>&1 echo fi ) | $of } # # input: # $1 heading name # $2 anchor name; ignored if not html output # print_anchor() { anchor="$2" mail_output_files="$mail_output_files$2.$$ " [ X"$verbose" = Xyes -o X"$userinfo" = Xyes ] && echo $2 1>&2 ( if [ X"$usehtml" = Xyes ]; then $PRINTF '%s\n' "

$1


" else $PRINTF '\n\n%s\n\n' "$1" fi ) | $of } begin_raw_output() { if [ X"$usehtml" = Xyes ]; then echo '
' | $of
    fi
}

end_raw_output()
{
    if [ X"$usehtml" = Xyes ]; then
	echo '
' | $of fi } print_separator() { ( if [ X"$usehtml" = Xyes ]; then echo '

' else $PRINTF '%s\n\n' "$sep" fi ) | $of } print_echo() { ( if [ X"$usehtml" = Xyes ]; then echo "

$@


" else $PRINTF '%s\n\n' "$*" fi ) | $of } print_header() { networker=`query_res '' version | $TR -d \;` if [ X"$usehtml" = Xyes ]; then ( cat <<-__EOF__ NetWorker Support Tool Report

NetWorker Support Tool: System Diagnostics


User Information

Incident Number:${incidentnum} 
Contact:${name} 
Company:${company} 
Telephone:${phone} 
Email Address:$email 

Report Creation Environment

Date:`date`
`basename $0` version:${RELEASE}
NetWorker version:${networker}
Hostname:$host __EOF__ ) | $of type domainname > /dev/null 2>&1 && echo "
Domain Name:`domainname`" | $of echo "
$UNAME:`$UNAME`" | $of if [ X"$system" = XAIX ]; then echo "
osrel$aixrel" | $of fi echo '


' | $of else ( echo echo Report Creation Environment echo echo " Date: `date`" $PRINTF '%17s %s\n' `basename $0` "version: $RELEASE" echo " NetWorker version: $networker" echo " Hostname: ${host}" type domainname > /dev/null 2>&1 && echo " Dommain Name: `domainname`" $PRINTF '%25s: %s\n' "$UNAME" "`$UNAME`" [ X"$system" = XAIX ] && echo " osrel: $aixrel" echo echo ) | $of fi } ################# end of html related output processing ################ usage() { if [ -n "$1" ]; then exitcode="$1" else exitcode=1 fi cat <<__EOF__ 1>&2 `basename $0` [flags [args] ...] Every flag marked [arg] has a required argument, which may be a comma or space-separated quoted list. Defaults are given inside <...>. Permissible enumerated argument values are given inside {...}. Use capitalized flag to turn off feature. -a turn on all flags -b [arg] {cores,daemons} debugger run on core files/daemons -c clients examined -d dmesg info printed -e append the PATH from the environment -f [arg] print/tail additional named files -g [arg] grep logfiles (named with -l) for [arg] -h print help message (usage) and exit -i [arg] output from mminfo: [arg] is a list of mminfo command args without the preceding dash -j display jukebox info, if available -l [arg] {nsrd,nsr,sysmess,rapres,nsrres,lines=nnn} print last nnn lines of log files; 'all' means whole file; default = 3000 -m [arg] set mail addresses to [arg] tar, compress, uuencode, mail output -n netstat output printed -o [arg] set output filename to [arg] -p check for presence of nsr executables in PATH -r run rpcinfo -b 390109 2 to find NetWorker servers -s run ps commands -t [arg] do strace/truss: proc names and tracetime appear in [arg] -u interactively get incident #, contact name, client list etc. -v vmstat/sar output -w print swap info -x index data printed (nsrls, df, and ls -ld of index directories) -z output file is compressed --help get help on the long flags __EOF__ cleanup exit $exitcode } long_usage() { if [ -n "$1" ]; then exitcode="$1" else exitcode=1 fi cat <<__EOF__ 1>&2 `basename $0` [flags | flags=args ...] Flags marked with = have required arguments. Flags marked with a * are on by default. --all turn on all flags --check-path * check for presence of nsr executables in PATH --clients * examine clients --compress compress output file --daemon-log * print last --log-lines of deamon.log --dbg-cores * run debugger on core files --dbg-daemons run debugger on daemons --dmesg * dmesg device info printed --env-path append the PATH from the environment --file-list= tail additional named files --grep-list= * grep logfiles (named with -l) for --hw-conf * show hardware and kernel configuration --html-output add html tags to output so it can be viewed with a browser --indexes * index data printed (nsrls, df, and ls -ld of index directories) --ipcs-info * show IPC information --jb-info * display jukebox info, if available --log-lines= how many lines to print, can be the string 'all' --mail= set mail addresses to mail is tarred, compressed and uuencoded --mminfo= * output from mminfo: is a list of mminfo command args separated by comma, without the preceding dash --netstat * netstat output printed --nsr-log * print last --log-lines of log files from /nsr/logs --nsr-res * grab res files contents --output-file= set output filename to --path= add specified paths to PATH --ps * run ps --rap-res grab dynamic rap data --rpcinfo * run rpcinfo -b 390109 2 to find NetWorker servers --savegrp * run savegrp -p on all defined groups --show-pkgs * show installed packages --subject= set the Subject: field of the email --swap-info * print swap info --sysmess-log * print last --log-lines of system messages from /var --trace-list= * do strace/truss: proc names appear in --trace-time= set tracetime to --user-info * interactively get incident #, contact name, client list etc. --verbose print values of command line flags --vmstat * vmstat/sar output -h get help on the short flags __EOF__ cleanup exit $exitcode } client_usage() { cat <<__EOF__ 1>&2 You can gather additional information about NetWorker clients by making entries at the following prompt(s). You will have the opportunity to specify the clients to check. The more entries that you make the longer this script will take. __EOF__ } client_help() { cat <<__EOF__ 1>&2 Entering a client name at the prompt will produce additional information on that client. .all will check the status of all defined NetWorker clients. .set-all will list all defined NetWorker clients, and also set the client list to check. .list will show you the clients that have been selected. .reset clears the list and leaves only the local hostname. .quit exits this query loop. __EOF__ } cleanup() { $RM -f $tmpdir/gdb.args if [ X"$keeptemp" = Xno -a X"$tempout" != X ]; then $RM -f $tempout fi if [ X"$mail_output_files" != X ]; then $RM -f $mail_output_files fi } ps_set() { PS="$1" PS_BIG="$2" PS_SMALL="$3" PS_COM_COL="$4" # column in $PS $PS_SMALL output where command name is } dumpswitches() { cat <<__EOF__ 1>&2 --check-path ckpath $ckpath --clients clients $clients --compress compress $compress --cores cores $cores --daemons daemons $daemons --dmesg dmesg $dmesg --file-list filelist $filelist --grep-list greplist $greplist --html-output usehtml $usehtml --hw-conf hwconf $hwconf --indexes indexes $indexes --ipcs-info ipcsinfo $ipcsinfo --jb-info jbinfo $jbinfo --log-nsr log_nsr $log_nsr --log-nsrd log_nsrd $log_nsrd --log-sysmess log_sysmess $log_sysmess --log-lines howmuch $howmuch --mail sendto $sendto --mminfo mminfoarg $mminfoarg --netstat netstat $netstat --nsr-res nsr_res $nsr_res --output-file savefile $savefile --ps ps $ps --rap-res rap_res $rap_res --rpcinfo rpcinfo $rpcinfo --savegrp savegrp $savegrp --show-pkgs showpkgs $showpkgs --subject subject $subject --swap-info swapinfo $swapinfo --trace-list tracelist $tracelist --trace-time tracetime $tracetime --user-info userinfo $userinfo --vmstat vmstat $vmstat of $tempout __EOF__ } setdefaults() { verbose=no cores=yes daemons=no clients=yes dmesg=yes of="$tempout" filelist='' savefile='' greplist=mbuf mminfoarg='mvV avV' jbinfo=yes log_nsrd=yes log_nsr=yes log_sysmess=yes nsr_res=yes rap_res=no howmuch=3000 sendto='' netstat=yes ckpath=yes ps=yes rpcinfo=yes tracelist='nsr rap save asm' tracetime=20 userinfo=yes vmstat=yes swapinfo=yes indexes=yes compress=no hwconf=yes ipcsinfo=yes savegrp=yes showpkgs=yes subject=`basename $0` usehtml=no } setallon() { verbose=yes cores=yes daemons=yes clients=yes dmesg=yes filelist='' savefile='' greplist=mbuf mminfoarg='mvV avV' jbinfo=yes log_nsrd=yes log_nsr=yes log_sysmess=yes nsr_res=yes rap_res=yes howmuch=all sendto='' netstat=yes ckpath=yes ps=yes rpcinfo=yes tracelist='nsr rap save asm' tracetime=30 userinfo=yes vmstat=yes swapinfo=yes indexes=yes compress=yes hwconf=yes ipcsinfo=yes savegrp=yes showpkgs=yes subject=`basename $0` usehtml=yes } setalloff() { verbose=no cores=no daemons=no clients=no dmesg=no filelist='' savefile='' greplist='' mminfoarg='' jbinfo=no log_nsrd=no log_nsr=no log_sysmess=no nsr_res=no rap_res=no howmuch=0 sendto='' netstat=no ckpath=no ps=no rpcinfo=no tracelist='' tracetime=0 userinfo=no vmstat=no swapinfo=no indexes=no compress=no hwconf=no ipcsinfo=no savegrp=no showpkgs=no subject=`basename $0` usehtml=no } # # in: $1 the resource to query # $2 is optional and it's the resource name, the default is 'name' # checks to see if nsradmin can be accessed through RAP, if not it uses # the res files or nsrdb depending on release # query_res() { res_name=name [ X"$2" != X ] && res_name="$2" # check if we can make a call to nsradmin if type nsradmin > /dev/null 2>&1; then [ X"$verbose" = Xyes ] && echo Running nsradmin, this could hang 1>&2 # check if the the server is up to use nsradmin if echo quit | nsradmin -i - > /dev/null 2>&1; then if $PRINTF "types\nquit\n" | nsradmin -i - | $GREP "$1" > /dev/null 2>&1; then $PRINTF "show $res_name\nprint type:NSR $1\nquit\n" | nsradmin -i - | $SED 's/^[^:]\{1,\}: *//;s/, */;/g' | $TR -d '\012' else echo fi elif [ X"$res_files" != X ] && echo quit | nsradmin $res_files -i - > /dev/null 2>&1; then if $PRINTF "types\nquit\n" | nsradmin $res_files -i - | $GREP "$1" > /dev/null 2>&1; then $PRINTF "show $res_name\nprint type:NSR $1\nquit\n" | nsradmin $res_files -i - | $SED 's/^[^:]\{1,\}: *//;s/, */;/g' | $TR -d '\012' else echo fi else echo fi [ X"$verbose" = Xyes ] && echo OK, we did not hang 1>&2 else echo fi } # # runs nsradmin -s to get the user info and then calls # nsrres_getuserinfo to parse the output file # nsradmin_getuserinfo() { [ X"$verbose" = Xyes ] && echo Running nsradmin, this could hang 1>&2 $PRINTF "print type: NSR\nquit\n" | nsradmin -s "$1" -i - > /tmp/.$$ [ X"$verbose" = Xyes ] && echo OK, we did not hang 1>&2 nsrres_getuserinfo /tmp/.$$ $RM -f /tmp/.$$ } nsrdb_getuserinfo() { name="`$FIND /nsr/res/nsrdb | $XARGS $GREP -h 'contact name:' | $SED 's/[^:]*: *//;s/;.*//'`" company="`$FIND /nsr/res/nsrdb | $XARGS $GREP -h 'company:' | $SED 's/[^:]*: *//;s/;.*//`" phone="`$FIND /nsr/res/nsrdb | $XARGS $GREP -h 'phone:' | $SED 's/[^:]*: *//;s/;.*//`" email="`$FIND /nsr/res/nsrdb | $XARGS $GREP -h 'email address:' | $SED 's/[^:]*: *//;s/;.*//`" } nsrres_getuserinfo() { name="`$GREP 'contact name:' $1 | $SED 's/[^:]*: *//;s/;.*//'`" company="`$GREP 'company:' $1 | $SED 's/[^:]*: *//;s/;.*//`" phone="`$GREP 'phone:' $1 | $SED 's/[^:]*: *//;s/;.*//`" email="`$GREP 'email address:' $1 | $SED 's/[^:]*: *//;s/;.*//`" } # # get name, company, phone and email. # Getuserinfo() { case "$1" in usegrep_nsrdb ) echo Retrieving user information from /nsr/res/nsrdb 1>&2 nsrdb_getuserinfo ;; usegrep ) echo Retrieving user information from $ifile 1>&2 nsrres_getuserinfo "$ifile" ;; useadmin ) echo Retrieving user information from $ihost 1>&2 nsradmin_getuserinfo "$ihost" ;; *) # typically "manual" or "incomplete" echo "Please enter a value or \"none\" for the following questions." 1>&2 while true; do name=`Getinput 'Contact name' "$name"` company=`Getinput Company "$company"` phone=`Getinput Phone "$phone"` email=`Getinput 'email address' "$email"` Dispuserinfo ans=`Confirm 'Is this information correct'` if [ X"$ans" = Xyes ]; then break fi done ;; esac } # # print user information # Dispuserinfo() { ( echo "Contact for this incident: $name" echo " Company Name: $company" echo " Telephone Number: $phone" echo " Contact's email Address: $email" echo ) 1>&2 } # # Process output temporary files # output_all() { if type compress > /dev/null 2>&1; then compress_cmd='compress -f' else compress=no fi if [ X"$sendto" != X ]; then if [ X"$usehtml" = Xyes ]; then cd `dirname $tempout` tar cf $tmpdir/tmp.$$ `basename $tempout` if [ X"$compress" = Xyes -o X"$compress_cmd" != X ]; then outfile=$tmpdir/tmp.${$}.Z $compress_cmd $tmpdir/tmp.$$ else outfile=$tmpdir/tmp.$$ fi else cd $tmpdir tar cf tmp.$$ $mail_output_files $RM -f $mail_output_files mail_output_files='' if [ X"$compress" = Xyes -o X"$compress_cmd" != X ]; then outfile=$tmpdir/tmp.${$}.Z $compress_cmd $tmpdir/tmp.$$ else outfile=$tmpdir/tmp.$$ fi fi uuencode $outfile < $outfile > $outfile.uu $MAIL_COMM -s "$subject" $sendto < $outfile.uu $RM -f $tmpdir/tmp.${$}* fi if [ X"$tempout" != X ]; then if [ X"$savefile" != X -o X"$sendto" = X ]; then if [ X"$compress" = Xyes ]; then $compress_cmd $tempout outfilename=${tempout}.Z else outfilename=$tempout fi keeptemp=yes echo Output is in $outfilename 1>&2 else $RM -f $tempout tempout='' fi fi cleanup } reset_path() { # # set our own PATH to the default; we check to see if others exist # PATH=/sbin:/usr/sbin:/usr/bin:/bin:/etc # # check this first and stick it at the beginning # [ -d /usr/xpg4/bin ] && PATH=/usr/xpg4/bin:$PATH # # check the existence of directories and add them to the PATH # for dir in /usr/ucb \ /usr/bsd \ /usr/sadm/bin \ /usr/ccs/bin \ /usr/proc/bin \ /usr/etc \ /etc/LGTOuscsi \ /usr/local/bin \ /usr/libexec \ /usr/libexec/sccs \ /usr/sbin/nsr \ /usr/bin/nsr \ /usr/nsrsbin \ /usr/nsrbin \ /opt/SUNWspro/bin \ /opt/networker/bin \ /usr/opt/networker/bin; do [ -d "$dir" ] && PATH="$PATH:$dir" done # # on HP-UX /etc/PATH holds the default PATH for the system; just append # it and then we sanitize after in case there are duplicates # case `uname` in HP-UX ) if [ -f /etc/PATH ]; then PATH="$PATH:`cat /etc/PATH`" sanitize_path fi ;; esac } ######################################################################## # Hardware configuration functions for various platforms ######################################################################## SunOShwconf() { if [ -x /usr/sbin/devinfo -a -f /etc/vfstab ]; then for dev in `cut -f2 /etc/vfstab | grep rdsk`; do print_command /usr/sbin/devinfo -i $dev print_command /usr/sbin/devinfo -p $dev done fi type prtvtoc > /dev/null 2>&1 && print_command `whence prtvtoc` /dev/rdsk/c\?t\?d\?s2 type modinfo > /dev/null 2>&1 && print_command `whence modinfo` \| 'while read line; do echo $line; done | $AWK "{ split(\$0, a, /[ \\t]+/) } a[6] ~ /^(lus|psc)\$/ { print \$0 }"' type sysdef > /dev/null 2>&1 && print_command `whence sysdef` -i type prtconf > /dev/null 2>&1 && print_command `whence prtconf` -v type prtdiag > /dev/null 2>&1 && print_command `whence prtdiag` -v type showrev > /dev/null 2>&1 && print_command `whence showrev` -a [ -f /kernel/drv/st.conf ] && print_command $CAT /kernel/drv/st.conf } OSF1hwconf() { if type sysconfig > /dev/null 2>&1; then for subsystem in `sysconfig -s | $AWK -F: '{ print $1 }'`; do print_command `whence sysconfig` -q $subsystem done fi } HPhwconf() { type ioscan > /dev/null 2>&1 && print_command `whence ioscan` -kfn [ -f /stand/system ] && print_command $CAT /stand/system } AIXhwconf() { type errpt > /dev/null 2>&1 && print_command `whence errpt` -a type lscfg > /dev/null 2>&1 && print_command `whence lscfg` -v type lsdev > /dev/null 2>&1 && print_command `whence lsdev` -C -s scsi type lslpp > /dev/null 2>&1 && print_command `whence lslpp` -al \| $AWK \''$1 ~ /^lus$/ { print }'\' type lspv > /dev/null 2>&1 && print_command `whence lspv` type lsfs > /dev/null 2>&1 && print_command `whence lsfs` type lsjfs > /dev/null 2>&1 && print_command `whence lsjfs` type lsvfs > /dev/null 2>&1 && print_command `whence lsvfs` if type lsdev lsattr > /dev/null 2>&1; then drivelist=`lsdev -C -s scsi | $AWK '{ print $1 }'` for drive in $drivelist; do print_command lsattr -E -l $drive done fi } Linuxhwconf() { for file in /proc/cpuinfo \ /proc/devices \ /proc/filesystems \ /proc/interrupts \ /proc/iports \ /proc/ksyms \ /proc/modules \ /proc/mounts \ /proc/partitions \ /proc/pci \ /proc/slabinfo \ /proc/stat \ /proc/scsi/scsi; do [ -f "$file" ] && print_command cat "$file" done type lsmod > /dev/null 2>&1 && print_command `whence lsmod` type lsdev > /dev/null 2>&1 && print_command `whence lsdev` type lspci > /dev/null 2>&1 && print_command `whence lspci` } IRIXhwconf() { type hinv > /dev/null 2>&1 && print_command `whence hinv` -v type systune > /dev/null 2>&1 && print_command `whence systune` if [ -x /usr/sbin/scsicontrol -a X"`ls /dev/scsi/* 2>/dev/null`" != X ]; then for dev in /dev/scsi/*; do print_command /usr/sbin/scsicontrol -i $dev done fi } Darwinhwconf() { type ioreg > /dev/null 2>&1 && print_command `whence ioreg` -bls } ######################################################################## # Set path and get out if we are not root ######################################################################## # # save the environments PATH # envpath="$PATH" reset_path # # determine where the res files/nsrdb are # if [ -d /nsr/res/nsrdb ]; then res_files='-d /nsr/res/nsrdb ' else for res_file in /nsr/res/*.res; do [ -f "$res_file" ] && res_files="${res_files}-f ${res_file} " done fi if type id > /dev/null 2>&1; then id | $GREP root > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "$0: can only be run as root" 1>&2 exit 3 fi else echo "WARNING: This script is expected be run as root." 1>&2 echo "Attempting to run without verification of root permissions." 1>&2 fi ######################################################################## # Set up temp files ######################################################################## set_temp() { if [ -d "$tmpdir" ]; then tempout="$tmpdir/"`basename $0`".$$.out" else echo The specified directory \<$tmpdir\> is not a directory exit 5 fi } reset_temp() { if [ -d /nsr/tmp ]; then tmpdir=/nsr/tmp elif [ -d /tmp ]; then tmpdir=/tmp else tmpdir='' fi tempout="$tmpdir/"`basename $0`".$$.out" } # # remove left overs from previous run # reset_temp $RM -f $tmpdir/`basename $0`.* \ $tmpdir/gdb.args ######################################################################## # Who we are; pre-housekeeping ######################################################################## keeptemp=no # this has to happen here, very early, in case ^C # gets trapped and cleanup() is executed trap 'cleanup; exit 1' 2 3 15 # trap SIGINT SIGQUIT SIGTERM and cleanup RELEASE=7.3.2.Build.364 if uname -s > /dev/null 2>&1; then system=`uname -s` else system=`uname` fi if type hostname > /dev/null 2>&1; then host=`hostname` else host=`uname -n` fi ######################################################################## # Set arch-dependent command names and arguments ######################################################################## # # check to see if this version of the Bourne shell supports whence; if # not we make our own # if type whence > /dev/null 2>&1; then : else eval ' whence() { retval=1 if [ -x "$1" ]; then echo $1 retval=0 else for dir in `echo $PATH | $AWK -F: "{ for (i = 1; i <= NF; ++i) print \\$i }"`; do if [ -x "$dir/$1" ]; then echo "$dir/$1" retval=0 break fi done fi return $retval }' fi sep='------------------------------------------------------------------------' DF=df DMESG='' HWCONF='' IFCONFIG='' IPCS='' type ipcs > /dev/null 2>&1 && IPCS=`whence ipcs`' -a' MAIL_COMM=mailx MMINFO=`whence mminfo` NETSTAT_I='' NETSTAT_INET=`whence netstat`' -f inet' NETSTAT_STREAMS=`whence netstat`' -m' NSRJB=`whence nsrjb` NSRLS=`whence nsrls` PACKAGES='' SWAP_INFO='' TRACE='' UNAME=`whence uname`' -a' VMSTAT=`whence vmstat`' 5 10' AWK=`whence awk` CAT=`whence cat` COMPRESS=`whence compress` EGREP=`whence egrep` FIND=`whence find` GREP=`whence grep` MAIL_COMM=`whence mailx` if [ $? -ne 0 ]; then MAIL_COMM=`whence mail` fi PRINTF=`whence printf` RM=`whence rm` RPCINFO=`whence rpcinfo` SAVEGRP=`whence savegrp` SED=`whence sed` STRINGS=`whence strings` SUM=`whence cksum` if [ $? -ne 0 ]; then SUM=`whence sum` fi TEE=`whence tee`' -a' TR=`whence tr` XARGS=`whence xargs` DBXEXEC=dbx dbx_commands='where;detach;quit' dbxargstring='$pname $procid' # # these are the 'supported' systems # set up certain variables # case "$system" in SunOS ) ps_set /usr/bin/ps -ef '-ef -opid,comm' 2 dbxargstring='- $procid' DF=`whence df`' -k' DMESG=`whence dmesg` HWCONF=SunOShwconf IFCONFIG=`whence ifconfig`' -a' NETSTAT_I=`whence netstat`' -i' PACKAGES=`whence pkginfo`' -l' SWAP_INFO=`whence swap`' -s' TRACE=`whence truss`' -p' ;; OSF1 ) ps_set /usr/bin/ps -ef '-ef -opid,comm' 2 DF=`whence df`' -k' type uerf > /dev/null 2>&1 && DMESG=`whence uerf`' -R' IFCONFIG=`whence ifconfig`' -a' HWCONF=OSF1hwconf NETSTAT_I=`whence netstat`' -i' PACKAGES=`whence setld`' -i' SWAP_INFO=`whence swapon`' -s' ;; HP-UX ) ps_set /usr/bin/ps -ef -e 4 DF=`whence df`' -kP' DMESG=`whence dmesg` HWCONF=HPhwconf NETSTAT_I=`whence netstat`' -i' PACKAGES=`whence swlist` SWAP_INFO=`whence swapinfo` ;; AIX ) aixrel=`uname -v`.`uname -r` osrel=`uname -v` if [ "$osrel" -gt 3 ]; then aixrel=`oslevel` fi ps_set /usr/bin/ps axlww '-ef -opid,comm' 2 dbxargstring='-a $procid' DF=`whence df`' -kP' HWCONF=AIXhwconf type ifconfig > /dev/null 2>&1 && IFCONFIG=`whence ifconfig`' -a' NETSTAT_I=`whence netstat`' -i' PACKAGES=`whence lslpp`' -la' SWAP_INFO=`whence lsps`' -a' ;; Linux ) ps_set /bin/ps -efww -e 4 DF=`whence df`' -k' DMESG=`whence dmesg` IFCONFIG=`whence ifconfig`' -a' HWCONF=Linuxhwconf NETSTAT_INET=`whence netstat`' -i inet' NETSTAT_STREAMS=`whence netstat`' -s' PACKAGES=`whence rpm`' -aq' TRACE=`whence strace`' -p' if [ -f /proc/meminfo ]; then SWAP_INFO='cat /proc/meminfo' [ -f /proc/swaps ] && SWAP_INFO='cat /proc/swaps;echo;cat /proc/meminfo' fi ;; IRIX | IRIX64 ) osrel=`uname -r | cut -d. -f1``uname -r | cut -d. -f2` ps_set /bin/ps -ef -e 4 dbx_commands='where;resume;quit' dbxargstring='-p $procid' DF=`whence df`' -k' HWCONF=IRIXhwconf PACKAGES=`whence versions`' -v' SWAP_INFO=`whence swap`' -s' TRACE=`whence par`' -is -SS -p' [ $osrel -ge 64 ] && TRACE=`whence par`' -isk -SS -t 20 -p' VMSTAT=`whence sar`' -upw 5 10' ;; Darwin ) ps_set /bin/ps -aux 'ax -opid,command' 2 DF=`whence df`' -k' DMESG=`whence dmesg` IFCONFIG=`whence ifconfig` HWCONF=Darwinhwconf NETSTAT_INET=`whence netstat`' -i' NETSTAT_STREAMS=`whence netstat`' -s' PACKAGES=`whence ls`'/Library/Receipts/*' SWAP_INFO=`whence ls`' -l /var/vm' VMSTAT=`whence vm_stat` TRACE=`whence ktrace`' -p' ;; * ) echo $system is not officially supported by this script ;; esac ######################################################################## # Process command line ######################################################################## # # Process the command line options. # allows us to process command line contractions like: # $0 -ab cores -Np # as though it were # $0 -a -b cores -N -p # optstr holds the switches that take arguments # savecommandline="$@" set X `for arg in "$@"; do echo "X$arg"; done | $SED 's/^X//' | $AWK ' NR == 1 { len = length(optstr); for (i = 1; i <= len; i++) { c = substr(optstr, i, 1); arg[c] = 1; } finished = 0; expect = 0; } { if (finished == 0) { expect = 0; str = $0; len = length(str); if (substr(str, 1, 1) != "-") { printf("\"%s\"\n", str); } else if (substr(str, 1, 2) == "--") { printf("\"%s\"\n", str); if (length(str) == 2) { finished = 1; } } else { for (i = 2; i <= len; i++) { c = substr(str, i, 1); printf("-%s\n", c); if (arg[c]) { if (i < len) { tmp = substr(str, i + 1); printf("\"%s\"\n", tmp); } else { expect = 1; } next; } } } } else { printf("\"%s\"\n", $0); } } END { if (expect) { print "?"; } }' optstr=bfgilmot` eval "set $@" setdefaults shift # the X while [ $# -gt 0 ]; do case "$1" in -a ) setallon ;; -A ) setalloff ;; -b ) shift getargs 'cores:cores daemons:daemons' "$1" ;; -e | --env-path | --env-path=yes ) PATH="$PATH:$envpath" sanitize_path ;; -E | --noenv-path | --env-path=no ) reset_path ;; -f ) shift getparam filelist "$1" ;; -g ) shift getparam greplist "$1" ;; -[hH] ) usage 0 ;; -i ) shift getparam mminfoarg "$1" ;; -l ) shift getargs "nsrd:log_nsrd \ nsr:log_nsr \ sysmess:log_sysmess \ nsrres:nsr_res \ rapres:rap_res \ lines:howmuch" "$1" ;; -m ) shift getparam sendto "$1" ;; -o ) shift getparam savefile "$1" ;; -O ) savefile='' ;; -t ) shift getparam tmptracelist "$1" for tmp in $tmptracelist; do case $tmp in [0-9]* ) tracetime="$tmp" ;; time=[0-9]* ) tracetime=`echo $tmp | $SED 's/^time=//'` ;; *=* ) usage ;; * ) if [ X"$seensome" = Xyes ]; then tracelist="$tracelist $tmp" else tracelist="$tmp" ; seensome=yes fi ;; esac done tmptime=`echo $tracetime | $SED 's/[^0-9]/X/g'` [ X"$tracetime" != X"$tmptime" ] && usage ;; -[BcCdDFGIjJLMnNpPrRsSTuUvVwWxXzZ] ) set_arg "$1" -B:cores:no \ -B:daemons:no \ -c:clients:yes \ -C:clients:no \ -d:dmesg:yes \ -D:dmesg:no \ -F:filelist: \ -G:greplist: \ -I:mminfoarg: \ -j:jbinfo:yes \ -J:jbinfo:no \ -L:log_nsrd:no \ -L:log_nsr:no \ -L:log_sysmess:no \ -L:nsr_res:no \ -L:rap_res:no \ -M:sendto: \ -n:netstat:yes \ -N:netstat:no \ -p:ckpath:yes \ -P:ckpath:no \ -r:rpcinfo:yes \ -R:rpcinfo:no \ -s:ps:yes \ -S:ps:no \ -T:tracelist: \ -u:userinfo:yes \ -U:userinfo:no \ -v:vmstat:yes \ -V:vmstat:no \ -w:swapinfo:yes \ -W:swapinfo:no \ -x:indexes:yes \ -X:indexes:no \ -z:compress:yes \ -Z:compress:no ;; --all | --all=yes ) setallon ;; --noall | --all=no ) setalloff ;; --nofile-list | --file-list= ) filelist='' ;; --file-list=?* ) getparam_long filelist --file-list "$1" ;; --nogrep-list | --grep-list= ) greplist='' ;; --grep-list=?* ) getparam_long greplist --grep-list "$1" ;; --help* ) long_usage 0 ;; --nolog-lines | --log-lines= ) howmuch=0 ;; --log-lines=?* ) howmuch=`echo X"$1" | $SED 's/X--log-lines=//'` if [ X"$howmuch" != Xall ]; then tmptime=`echo $howmuch | $SED 's/[^0-9]/X/g'` [ X"$howmuch" != X"$tmptime" ] && long_usage fi ;; --nomminfo | --mminfo= ) mminfoarg='' ;; --mminfo ) mminfoarg=mvV ;; --mminfo=?* ) getparam_long mminfoarg --mminfo "$1" ;; --nomail | --mail= ) sendto='' ;; --mail=?* ) getparam_long sendto --mail "$1" ;; --nonsr-res | --nsr-res= ) nsr_res='' ;; --nsr-res=?* ) getparam_long nsr_res --nsr-res "$1" ;; --nooutput-file | --output-file= ) savefile='' ;; --output-file=?* ) getparam_long savefile --output-file "$1" ;; --nopath | --path= ) : ;; --path=?* ) PATH="$PATH:`echo X"$1" | $SED 's/^X--path=//'`" sanitize_path ;; --nosubject | --subject= ) subject=`basename $0` ;; --subject=?* ) getparam_long subject --subject "$1" ;; --temp-dir | --temp-dir= ) reset_temp ;; --temp-dir=?* ) getparam_long tmpdir --temp-dir "$1" set_temp ;; --notrace-list | --trace-list= ) tracelist='' ;; --trace-list=?* ) getparam_long tracelist --trace-list "$1" ;; --notrace-time | --trace-time= ) tracetime=0 ;; --trace-time=[0-9]* ) tracetime=`echo X"$1" | $SED 's/^X--trace-time=//'` tmptime=`echo $tracetime | $SED 's/[^0-9]/X/g'` [ X"$tracetime" != X"$tmptime" ] && long_usage ;; --trace-time=* ) long_usage ;; --* ) set_long_arg_yes_no "$1" \ check-path:ckpath \ ckpath \ clients \ compress \ daemon-log:log_nsrd \ dbg-cores:cores \ dbg-daemons:daemons \ dmesg \ hw-conf:hwconf \ html-output:usehtml \ html:usehtml \ indexes \ ipcs-info:ipcsinfo \ jbinfo \ jb-info:jbinfo \ netstat \ nsr-log:log_nsr \ nsr-res:nsr_res \ ps \ rap-res:rap_res \ rpcinfo \ rpc-info:rpcinfo \ savegrp \ show-pkgs:showpkgs \ swap-info:swapinfo \ sysmess-log:log_sysmess \ user-info:userinfo \ verbose \ vmstat ;; -- ) break ;; * ) echo Illegal option -- $1 1>&2 ; usage ;; esac shift done # # if compress set to yes then check to see if it is available. If not # then warn the user. # if [ X"$compress" = Xyes ]; then if [ ! -x "$COMPRESS" ]; then echo Cannot find the compress utility, or, it is not set executable. 1>&2 echo Output files will not be compressed. 1>&2 fi fi # # if a file to save output was specified then we check to see if it can # be written to # if [ X"$savefile" != X ]; then if touch "$savefile" 2>/dev/null; then $RM -f "$savefile" tempout="$savefile" is_tempout=no else echo Unable to write to $savefile 1>&2 echo Exiting 1>&2 exit 11 fi fi # # if the output is not being emailed and no file was specified for the # output, we use a temp file and first check if we can write to it # if [ X"$sendto" = X -a X"$savefile" = X ]; then if touch "$tempout" 2>/dev/null; then $RM -f "$tempout" else echo Unable to create an output file in $tmpdir 1>&2 echo Exiting 1>&2 exit 12 fi fi # # if we're emailing the output and no local copy was requested and we're # not outputting in html mode, then just don't bother with a local copy # if [ X"$sendto" != X -a X"$savefile" = X -a X"$usehtml" = Xno ]; then tempout='' fi # # if we're sending email, we need to check if we can create temp files # to store the output # if [ X"$sendto" != X ]; then if touch $tmpdir/.$$ 2>/dev/null; then $RM -f $tmpdir/.$$ else echo Unable to create temp files for mailing 1>&2 echo Exiting 1>&2 exit 13 fi fi # # if the output is going to be mailed and won't be html output, then we # create multiple output files to be later tarred and compressed # if [ X"$sendto" != X -a X"$usehtml" != Xyes ]; then of="eval $TEE $tempout $tmpdir/\$anchor.$$ > /dev/null" else of="eval $TEE $tempout > /dev/null" fi # # this needs to be set up early on # anchor=header mail_output_files="${mail_output_files}header.$$ " ######################################################################## # Get user/incident specific information ######################################################################## if [ X"$userinfo" = Xyes ]; then # get incident number newincident=no ans=`Confirm 'Is this a new incident'` if [ X"$ans" = Xyes ]; then incidentnum='new incident' else incidentnum=`Getinput 'Please enter the incident number ' ''` fi [ X"$subject" = X`basename $0` ] && subject="Incident $incidentnum" # determine where user information will come from infomode=usegrep if [ -f /nsr/res/nsr.res ]; then ifile=/nsr/res/nsr.res elif [ -d /nsr/res/nsrdb ]; then infomode=usegrep_nsrdb elif [ -f /usr/lib/nsr/nsruser ]; then ifile=/usr/lib/nsr/nsruser elif [ -f /tmp/nsruser ]; then ifile=/tmp/nsruser else echo 1>&2 echo "Then following information is required when running" 1>&2 echo "$0 but it was not found on this computer." 1>&2 Dispuserinfo echo "Please enter a NetWorker server where this information" 1>&2 $PRINTF "can be found or [Return] to enter it manually: " 1>&2 while true; do read ihost if [ X"$ihost" != X ]; then infomode=useadmin nsrdrun=`$RPCINFO -t $ihost 390109 2>&1 | $GREP "ready" | wc -l` else infomode=manual break fi if [ "$nsrdrun" -gt 0 ]; then break else echo "Error. There is no server daemon running on \"$ihost\"." 1>&2 $PRINTF "Specify a valid NetWorker server or [Return]: " 1>&2 fi done fi # Initial attempt at getting the user info Getuserinfo "$infomode" # test automated info retrieval for completeness if [ X"$infomode" != Xmanual ]; then [ X"$name" = X ] && infomode=incomplete [ X"$company" = X ] && infomode=incomplete [ X"$phone" = X ] && infomode=incomplete [ X"$email" = X ] && infomode=incomplete if [ X"$infomode" = Xincomplete ]; then echo "The following values are from your Server Setup." 1>&2 Dispuserinfo echo "The information is incomplete, please enter it below." 1>&2 else Dispuserinfo ans=`Confirm 'Is this information correct'` if [ X"$ans" = Xno ]; then infomode=incomplete fi fi fi # go back to the user if necessary if [ X"$infomode" = Xincomplete ]; then Getuserinfo "$infomode" fi # now that we absolutely have the info, # send it to output and optionally, save if [ X"$usehtml" = Xno ]; then ( echo echo User Information echo echo " Incident Number: $incidentnum" Dispuserinfo 2>&1 ) | $of fi # save this user information locally, if requested ans=no if [ X"$infomode" = Xmanual ]; then ans=`Confirm 'Would you like to save your information on this computer'` fi if [ X"$ans" = Xyes ]; then writefile=no while true; do if [ -d /usr/lib/nsr ]; then ifile=/usr/lib/nsr/nsruser writefile=yes break elif [ -d /tmp ]; then ifile=/tmp/nsruser writefile=yes break fi echo "Could not save information. Proceeding with $0 anyway." 1>&2 break done if [ X"$writefile" = Xyes ]; then if [ -f "$ifile" ]; then ans=`Confirm "$ifile already exists. Do you want to overwrite it"` if [ X"$ans" = Xyes ];then $RM -f "$ifile" fi fi touch "$ifile" if [ -f "$ifile" ]; then ( echo "contact name: $name;" echo "company: $company;" echo "phone: $phone;" echo "email address: $email;" ) >> $ifile echo "Information saved to: $ifile" 1>&2 else echo "Could not create file. Proceeding with $0 anyway." 1>&2 fi fi fi fi # userinfo = yes if $RPCINFO -t $host 390109 2 > /dev/null 2>&1; then if [ X"$clients" = Xyes ]; then clntlist="${host};" tmp_clntlist=`query_res client aliases` if [ X"$userinfo" = Xyes ]; then client_usage while true; do $PRINTF "Enter a client name or (.help|.list|.set-all|.all|.reset|.quit): " 1>&2 read probclnt case "$probclnt" in .h | .he | .hel | .help ) client_help ;; .l | .li | .lis | .list ) $PRINTF '%s' "$clntlist" | $TR ';' '\012' 1>&2 ;; .s | .se | .set | .set-all ) clntlist=`query_res client` $PRINTF '%s' "$clntlist" | $TR ';' '\012' 1>&2 ;; .a | .al | .all ) clntlist=`query_res client` echo "The following clients will be checked:" 1>&2 $PRINTF '%s' "$clntlist" | $TR ';' '\012' 1>&2 echo 1>&2 break ;; .r | .re | .res | .rese | .reset ) clntlist="${host};" ;; *) if [ X"$probclnt" = X -o X"$probclnt" = X.q -o X"$probclnt" = X.qu -o X"$probclnt" = X.qui -o X"$probclnt" = X.quit ]; then clntlist=`$PRINTF '%s' "$clntlist" | $TR ';' '\012' | sort -u | $TR '\012' ';'` echo "The following clients will be checked:" 1>&2 $PRINTF '%s' "$clntlist" | $TR ';' '\012' 1>&2 echo 1>&2 break else ifs="$IFS" IFS=\; set X $tmp_clntlist IFS="$ifs" shift found=0 for clnt in "$@"; do if [ X"$probclnt" = X"$clnt" ]; then found=1 clntlist="${clntlist}${probclnt};" fi done if [ $found -ne 1 ]; then echo The given name \($probclnt\) is not a valid client name for this server 1>&2 echo 1>&2 fi fi clntlist=`$PRINTF '%s' "$clntlist" | $TR ';' '\012' | sort -u | $TR '\012' ';'` ;; esac done fi # clean up the list by getting rid of possible duplicates clntlist=`$PRINTF '%s' "$clntlist" | $TR ';' '\012' | sort -u | $TR '\012' ';'` fi fi if [ X"$howmuch" = Xall ]; then TAIL=`whence cat` else TAIL=`whence tail`" -$howmuch" fi ######################################################################## # Begin generating output ######################################################################## print_header print_toc if [ X"$verbose" = Xyes ]; then dumpswitches fi if [ X"$ps" = Xyes ]; then print_anchor 'Process Status' ps print_command $PS $PS_BIG fi if [ X"$netstat" = Xyes ]; then print_anchor 'Network Status' netstat [ X"$NETSTAT_STREAMS" != X ] && print_command $NETSTAT_STREAMS [ X"$NETSTAT_INET" != X ] && print_command $NETSTAT_INET [ X"$NETSTAT_I" != X ] && print_command $NETSTAT_I [ X"$IFCONFIG" != X ] && print_command $IFCONFIG fi if [ X"$swapinfo" = Xyes ]; then print_anchor 'Swap Information' swap [ X"$SWAP_INFO" != X ] && print_command $SWAP_INFO fi if [ X"$vmstat" = Xyes ]; then print_anchor 'Virtual Memory Statistics' vmstat [ X"$VMSTAT" != X ] && print_command $VMSTAT fi if [ X"$ipcsinfo" = Xyes -a X"$IPCS" != X ]; then print_anchor 'IPC Facilities' ipc print_command $IPCS fi if [ X"$dmesg" = Xyes -a X"$DMESG" != X ]; then print_anchor 'System Diagnostics Messages' dmesg print_command $DMESG fi if [ X"$hwconf" = Xyes ]; then print_anchor 'Hardware Inventory / Kernel Configuration' hwconf [ X"$HWCONF" != X ] && $HWCONF print_command ulimit -Sa print_command ulimit -Ha fi if [ X"$ckpath" = Xyes ]; then # check to see if we have the what command available on this # platform, if not, we roll our own if type what > /dev/null 2>&1; then WHAT=`whence what` else eval ' what() { if [ -f "$1" ]; then $PRINTF '%s\n' "$1" $STRINGS -a "$1" | $GREP "@(#)" | $SED "s/^@(#) *//" | while read line; do $PRINTF '\t%s\n' "$line"; done else echo unable to open $1 return 1 fi }' WHAT=what fi print_anchor 'Executable Checksums and Release Info' cksums begin_raw_output ( echo The PATH in the Environment was echo $envpath | $AWK -F: '{ for (i = 1; i <= NF; ++i) print "\t" $i }' echo echo The PATH in `basename $0` is echo $PATH | $AWK -F: '{ for (i = 1; i <= NF; ++i) print "\t" $i }' echo ) | $of end_raw_output for f in ansrd nsrck nsrd nsrindexd nsrlmc nsrmmd nsrmmdbd nsrexecd save savefs savegrp nsrjb mminfo; do CMD=`whence $f` if [ $? -eq 0 ]; then print_command $SUM $CMD print_command $WHAT $CMD fi done for f in nsr_ize nsr_support; do CMD=`whence $f` [ $? -eq 0 ] && print_command $GREP \''^RELEASE='\' $CMD done fi if [ X"$rpcinfo" = Xyes ]; then print_anchor 'Server List' nsrlist print_command $RPCINFO -b 390109 2 \| sort -t. -un +0 -1 +1 -2 +2 -3 +3 -4 +4 -5 fi ######################################################################## # trace processes - the default is to trace 'nsr rap save asm' # The following will work on a client or a server . . . ######################################################################## if [ X"$tracelist" != X -a $tracetime -gt 0 ]; then print_anchor 'Traced NetWorker Processes' trace if [ X"$TRACE" = X ]; then print_error trace requested, but there is no trace command for $system else proclist=`echo $tracelist | $TR ' ' '|'` # put a listing of procids=procname in ptab prog="\$${PS_COM_COL} ~ /${proclist}/ && \$${PS_COM_COL} !~ /nsrsup|nsr_support/ { print \$1 \"=\" \$${PS_COM_COL} }" ptab=`$PS $PS_SMALL | $AWK "$prog"` begin_raw_output ( for tmp in $ptab; do $PRINTF '\t%s\n' "$tmp" | $TR = '\011' done ) | $of end_raw_output [ X"$verbose" = Xyes ] && echo $ptab 1>&2 # # Note we can't start up several simultaneous trace processes # since some trace utilities (e.g. par under IRIX) # cannot have >1 instance running on a machine at one time. # for proc in $ptab; do procid=`echo $proc | cut -d= -f1` procname=`echo $proc | cut -d= -f2` # put trace in the background in order to time it print_message $TRACE $procid \( $procname \) [ X"$verbose" = Xyes ] && echo $procname $procid 1>&2 [ X"$verbose" = Xyes ] && echo Running a trace for $tracetime seconds, this could hang 1>&2 begin_raw_output ( $TRACE $procid 2>&1 & child=$! [ X"$verbose" = Xyes ] && echo child\'s pid is $child 1>&2 # wait a while, now that traces are started ... sleep $tracetime kill -15 "$child" > /dev/null 2>&1 echo ) | $of end_raw_output [ X"$verbose" = Xyes ] && echo OK, we did not hang 1>&2 if [ X"$system" = XSunOS -a -x /usr/proc/bin/pstack ]; then print_command /usr/proc/bin/pstack $procid fi done fi fi ######################################################################## # Server only diagnostics ######################################################################## if $RPCINFO -t $host 390109 2 > /dev/null 2>&1; then if [ X"$mminfoarg" != X ]; then print_anchor 'Volume Information' mminfo for arg in $mminfoarg; do print_command $MMINFO -$arg 2>&1 done fi # Print info which may be useful regarding size, location of indexes if [ X"$indexes" = Xyes ]; then print_anchor 'Index Information' indexes print_command ls -ld /nsr print_command ls -ld /nsr/index print_command ls -lR /nsr/index print_command ls -ld /nsr/index/* print_command $NSRLS print_command $NSRLS -m print_command $DF fi if [ X"$savegrp" = Xyes ]; then print_anchor 'Group Information' savegrp groups=`query_res group` ifs="$IFS" IFS=\; set X $groups IFS="$ifs" shift for group in "$@"; do [ X"$group" != X ] && print_command $SAVEGRP -p $group done fi if [ X"$clients" = Xyes ]; then # find out if the client daemons are running # note: "rpcinfo -p" times out faster than "rpcinfo -t" print_anchor 'Client Daemon Probe' clntprobe ifs="$IFS" IFS=\; set X $clntlist IFS="$ifs" shift for clnt in "$@"; do [ X"$verbose" = Xyes ] && echo client probe - $clnt 1>&2 print_command $RPCINFO -p $clnt \| \ $EGREP \''(contact|error|unknown|390[0-9][0-9][0-9])'\' done clntlist=`query_res client` if [ -f /etc/hosts ]; then anchor=hosts mail_output_files="${mail_output_files}hosts.$$ " print_message /etc/hosts # retrieve client information in host table begin_raw_output ( $GREP "127.0.0.1" /etc/hosts clnt=`$PRINTF '%s\n' "$clntlist" | $SED 's/;$//;s/;/|/g'` [ X"$clnt" != X ] && $EGREP "$clnt" /etc/hosts ) | $of end_raw_output print_separator else print_error "NO /etc/hosts TABLE!" fi print_anchor "List of $host's Clients" clntlist begin_raw_output ( ifs="$IFS" IFS=\; set X $clntlist IFS="$ifs" shift for clnt in "$@"; do $PRINTF '\t%s\n' "$clnt" done ) | $of end_raw_output fi #################################################################### # check core files #################################################################### if [ X"$cores" = Xyes ]; then print_anchor 'Core Analysis' cores execdirs='' for f in nsrck nsrd nsrexecd nsrindexd nsrjb nsrlmc nsrmmd nsrmmdbd save savefs savegrp; do if type "$f" > /dev/null 2>&1; then fullname=`whence $f` execdirs="$execdirs "`dirname $fullname` fi done execdirs=`remove_dups execdirs ' '` maybecores="/nsr/cores/*/* /core" corefiles="`/bin/ls -d $maybecores 2> /dev/null`" if [ X"$corefiles" = X ]; then print_message no cores found in $maybecores coresfound=no else print_echo "$corefiles" for corefile in $corefiles; do for dir in $execdirs; do # take out daemon name ( need this for adb ) fileo="`file $corefile | $GREP ':.*core'`" 2>&1 if [ X"$fileo" = X ]; then # this might be the rs6000 use the # other way to get daemon name daemon=`echo $corefile | cut -d/ -f4` if [ X"$daemon" = X ]; then print_error $corefile is not a corefile, or unable to get daemon name print_separator continue fi else daemon=`echo $fileo | cut -d/ -f4` 2>&1 fi if [ -x "$dir/$daemon" ]; then print_echo "using $dir/$daemon for file $corefile" [ X"$verbose" = Xyes ] && echo Running a debugger, this could hang 1>&2 begin_raw_output ( if type adb > /dev/null 2>&1; then # This should cover SunOS, AIX, HP-UX echo '$c;$r;$q' | adb $dir/$daemon $corefile 2>&1 elif type dbx > /dev/null 2>&1; then # should cover OSF1, IRIX case "$system" in IRIX* ) echo 'where;printregs;quit' | dbx $dir/$daemon $corefile ;; * ) echo 'where;regs;quit' | dbx $dir/$daemon $corefile ;; esac elif type gdb > /dev/null 2>&1; then # This should cover Linux, or other platforms # where it was installed $PRINTF "set height 0\nbacktrace\ninfo frame\ninfo args\ninfo locals\ninfo all-registers\nquit\n" > $tmpdir/gdb.args gdb -x $tmpdir/gdb.args $dir/$daemon $corefile fi ) | $of end_raw_output [ X"$verbose" = Xyes ] && echo OK, we did not hang 1>&2 print_separator fi done done fi fi #################################################################### # check resource dynamic attributes #################################################################### if [ X"$rap_res" = Xyes ]; then print_anchor 'Resource Files: Dynamic Attributes' dynres [ X"$verbose" = Xyes ] && echo Running nsradmin, this could hang 1>&2 begin_raw_output ( if echo quit | nsradmin -i - > /dev/null 2>&1; then $PRINTF "option hidden: on\noption dynamic: on\nprint\nquit\n" | nsradmin -i - 2>&1 else print_error cannot get dynamic attributes fi ) | $of end_raw_output [ X"$verbose" = Xyes ] && echo OK, we did not hang 1>&2 print_separator fi #################################################################### # check resource file attributes #################################################################### nsrfiles='' if [ X"$nsr_res" = Xyes ]; then print_anchor 'Resource Files: Attributes' nsrres nsrfiles="/nsr/res/*.res /nsr/res/servers " fi if [ X"$rap_res" = Xyes ]; then nsrfiles="${nsrfiles}/etc/la.res " fi for f in $nsrfiles; do if [ -f "$f" ]; then print_command cat $f fi done if [ X"$nsr_res" = Xyes -a -d /nsr/res/nsrdb ]; then begin_raw_output ( $FIND /nsr/res/nsrdb -type f | $XARGS cat ) | $of end_raw_output fi #################################################################### # Run dbx on the nsr daemons. #################################################################### if [ X"$daemons" = Xyes ]; then print_anchor 'Debugger Analysis on NetWorker Daemons' debugger if type $DBXEXEC > /dev/null 2>&1; then case "$system" in SunOS ) DBXEXEC=`whence dbx`' -q' ;; esac nsrpath=`whence nsrd` nsrbase=`dirname $nsrpath` # get a listing of procids, procnames prog="\$${PS_COM_COL} ~ /nsrd|nsrmmd|nsrmmdbd|nsrindexd|nsrexecd/ { print \$1 \"=\" \$${PS_COM_COL} }" ptab=`$PS $PS_SMALL | $AWK "$prog"` proctab='' for proc in $ptab; do procid="`echo $proc | cut -d= -f1`" pname=`echo $proc | cut -d= -f2` if [ `expr "$pname" : "/."` -eq 0 ]; then pname="$nsrbase/$pname" fi procname=`basename $pname` # put dbx in the background; just in case it hangs print_message "$procname:$procid" dbxproc='' dbxargs=`eval echo $dbxargstring` begin_raw_output ( echo "$dbx_commands" | $DBXEXEC $dbxargs & child=$! sleep 20 kill -15 "$child" > /dev/null 2>&1 ) | $of end_raw_output proctab="$proctab $proc=$child" done # insure that each one is dead . . . for proc in $proctab; do # check that each proc is dead: if not dead=1 procid=`echo $proc | cut -d= -f1` procname=`echo $proc | cut -d= -f2` dbxid=`echo $proc | cut -d= -f3` $PS $PS_SMALL | $AWK '{ print $1 }' | $GREP $dbxid > /dev/null 2>&1 if [ $? -eq 0 ]; then for i in $dbxid; do kill -15 "$dbxid" > /dev/null 2>&1 $PS $PS_SMALL | $AWK '{ print $1 }' | $GREP $dbxid > /dev/null 2>&1 dead=$? echo "reached inside of for loop due to unstop. $dead" if [ X"$dead" != X0 ];then break fi done fi if [ X"$dead" = X0 ];then kill -9 "$dbxid" > /dev/null 2>&1 $PS $PS_SMALL | $AWK '{ print $1 }' | $GREP $dbxid > /dev/null 2>&1 dead=$? fi if [ X"$dead" = X0 ]; then echo "unable to kill process $dbxid" 1>&2 fi done else if type gdb > /dev/null 2>&1 && [ X"$system" = Linux ]; then proctab='' $PRINTF "set height 0\nbacktrace\ninfo frame\ninfo args\ninfo locals\ninfo all-registers\ndetach\nquit\n" > $tmpdir/gdb.args nsrpath=`whence nsrd` nsrbase=`dirname $nsrpath` prog="\$${PS_COM_COL} ~ /nsrd|nsrmmd|nsrmmdbd|nsrindexd|nsrexecd/ { print \$1 \"=\" \$${PS_COM_COL} }" ptab=`$PS $PS_SMALL | $AWK "$prog"` for proc in $ptab; do procid="`echo $proc | cut -d= -f1`" pname="`echo $proc | cut -d= -f2`" case $pname in /* ) procname="$pname" ;; * ) procname="$nsrbase/$pname" ;; esac print_echo "$procname:$procid" begin_raw_output ( gdb -x $tmpdir/gdb.args "$procname" $procid & child=$! sleep 20 kill -15 "$child" > /dev/null 2>&1 ) | $of end_raw_output proctab="$proctab $proc=$child" done else print_error debugger tracing requested, but no debugger found fi fi print_separator fi # end of $daemons = yes #################################################################### # if jukebox info was requested then get some info #################################################################### if [ X"$jbinfo" = Xyes ]; then print_anchor 'Jukebox Information' jukebox jukeboxes=no pscdrvr=no lusdrvr=no for i in 0 1 2 3 4 5 6 7; do if [ -c /dev/psc$i ]; then pscdrvr=yes break fi done if [ -c /dev/lus ]; then lusdrvr=yes fi juke_boxes=`query_res jukebox` if [ X"$juke_boxes" != X ]; then jukeboxes=yes else jukeboxes=no fi if [ X"$jukeboxes" = Xyes ]; then if [ X"$pscdrvr" = Xyes ]; then print_command ls -l /dev/sji* type pscinfo > /dev/null 2>&1 && print_command `whence pscinfo` -c INQUIRY /dev/sjid1u1 elif [ X"$lusdrvr" = Xyes ]; then print_command ls -l /dev/lus* fi type changers > /dev/null 2>&1 && print_command `whence changers` ifs="$IFS" IFS=\; set X $juke_boxes IFS="$ifs" shift for juke in "$@"; do print_command $NSRJB -j $juke -V print_command $NSRJB -j $juke -Cv print_message Jukebox $juke [ X"$verbose" = Xyes ] && echo Running nsradmin, this could hang 1>&2 begin_raw_output ( if echo quit | nsradmin -i - > /dev/null 2>&1; then $PRINTF "option hidden: on\noption dynamic:on\nprint type:NSR jukebox\nquit\n" | nsradmin -i - elif echo quit | nsradmin $res_files -i - > /dev/null 2>&1; then $PRINTF "option hidden: on\noption dynamic:on\nprint type:NSR jukebox\nquit\n" | nsradmin $res_files -i - fi ) | $of print_separator [ X"$verbose" = Xyes ] && echo OK, we did not hang 1>&2 end_raw_output done if type inquire > /dev/null 2>&1; then print_command `whence inquire` output=`inquire | $AWK ' /Tape/ { printf("ls -lL %s;ls -l %s;", $NF, $NF) } /\(Juke/ { printf("type sjirjc > /dev/null 2>&1 && sjirjc %s;type sjirdtag > /dev/null 2>&1 && sjirdtag %s;", $1, $1) } END { print "\n" }'` ifs="$IFS" IFS=\; set X $output IFS="$ifs" shift for comm in "$@"; do [ X"$comm" != X ] && print_command "$comm" done fi type lusbinfo > /dev/null 2>&1 && print_command `whence lusbinfo` -v else print_error no jukebox devices found fi devices=`query_res device` if [ X"$devices" != X ]; then print_message Devices begin_raw_output ( ifs="$IFS" IFS=\; set X $devices IFS="$ifs" shift for dev in "$@"; do [ X"$dev" != X ] && $PRINTF '\t%s\n' "$dev" done ) | $of end_raw_output fi fi else print_error $host is a client only [ X"$mminfoarg" != X ] && print_anchor 'NO Volume Information' mminfo [ X"$indexes" = Xyes ] && print_anchor 'NO Index Information' indexes [ X"$savegrp" = Xyes ] && print_anchor 'NO Group Information' savegrp [ X"$clients" = Xyes ] && print_anchor 'NO Client Daemon Probe' clntprobe [ X"$clients" = Xyes ] && print_anchor "NO List of $host's Clients" clntlist [ X"$cores" = Xyes ] && print_anchor 'NO Core Analysis' cores [ X"$rap_res" = Xyes ] && print_anchor 'NO Resource Files: Dynamic Attributes' dynres [ X"$nsr_res" = Xyes ] && print_anchor 'NO Resource Files: Attributes' nsrres [ X"$daemons" = Xyes ] && print_anchor 'NO Debugger Analysis on NetWorker Daemons' debugger [ X"$jbinfo" = Xyes ] && print_anchor 'NO Jukebox Information' jukebox fi if [ X"$showpkgs" = Xyes ]; then print_anchor 'Installed Software' pkgs [ X"$PACKAGES" != X ] && print_command $PACKAGES fi ######################################################################## # tail various logfiles specified on the command line ######################################################################## logfiles='' if [ X"$log_nsrd" = Xyes ]; then print_anchor 'Daemon Log' daemonlog [ -f /nsr/logs/daemon.log ] && print_command $TAIL /nsr/logs/daemon.log fi if [ X"$log_nsr" = Xyes ]; then [ -f /nsr/logs/messages ] && logfiles="$logfiles /nsr/logs/messages" [ -f /nsr/logs/ssi_event.log ] && logfiles="$logfiles /nsr/logs/ssi_event.log" [ -f /nsr/logs/summary ] && logfiles="$logfiles /nsr/logs/summary" fi if [ X"$log_sysmess" = Xyes ]; then [ -f /var/adm/messages ] && logfiles="$logfiles /var/adm/messages" [ -f /var/log/messages ] && logfiles="$logfiles /var/log/messages" [ -f /var/adm/SYSLOG ] && logfiles="$logfiles /var/adm/SYSLOG" [ -f /var/adm/syslog/syslog.log ] && logfiles="$logfiles /var/adm/syslog/syslog.log" [ -f /var/adm/ras/bootlog ] && logfiles="$logfiles /var/adm/ras/bootlog" [ -f /var/log/boot.log ] && logfiles="$logfiles /var/log/boot.log" fi if [ X"$howmuch" != X0 -a X"$logfiles" != X ]; then print_anchor 'Log Files' logs for f in $logfiles $filelist; do if [ -f "$f" ]; then print_command $TAIL $f else print_error cannot $TAIL $f\; no such file fi done fi ######################################################################## # grep various logfiles specified on the command line ######################################################################## if [ X"$greplist" != X ]; then for f in $logfiles; do if [ -f "$f" ]; then for gexpr in $greplist; do print_command $EGREP $gexpr $f done else print_error cannot $EGREP $f\; no such file fi done fi output_all