#!/bin/sh

# clayton at coraid dot com
# nate at coraid dot com
# robin at coraid dot com
# srowe at coraid dot com
# matt at coraid dot com
# Primum non nocere

VERSION=1390230109

if [ "$(uname -r)" = "5.10" ] ; then
    echo "Solaris 10 not supported at this time."
    exit 99
fi

now=$(date +%s)

tmpdir=/tmp/coraid-$(hostname)-${now}
outfile=/tmp/coraid-$(hostname)-${now}.txt

if [ -t 1 -a -t 0 ] ; then # running in a terminal?
    MODE=file
    GRABMSGS=0
    EXTENDED=1 #extended is now the default. -E turns it off.
    HEADERS=1
    while getopts Eehlmtvx: flag
    do
        case $flag in
            E)
                EXTENDED=0
                ;;
            e)
                EXTENDED=1
                echo "Please be patient. Extended diagnostics may take several minutes to collect."
                ;;
            h)
                echo Usage:
                printf "%s [-h] | [-e] [-m] [-t]\n" "${0}"
                printf "\t-h : Show this help and exit\n"
                printf "\t-E : Disable extended diagnostics\n"
                printf "\t-e : Deprecated. left for backwards compatibility\n"
                printf "\t-m : Capture a copy of OS's messages file\n"
                printf "\t-t : Capture diagnostics in tarball format\n"
                exit 0
                ;;
            l)
                MODE=local
                ;;
            m)
                GRABMSGS=1
                ;;
            t)
                MODE=tar
                ;;
            v)
                echo Version: ${VERSION}
                exit 0
                ;;
            x)
                EXEX="${OPTARG}"
                HEADERS=0
                ;;
        esac
    done
else # running in a pipeline?
    [ -z "${MODE}" ] && MODE=file
    [ -z "${GRABMSGS}" ] && GRABMSGS=0
    [ -z "${EXTENDED}" ] && EXTENDED=1 #extended is now the default. -E turns it off.
    [ -z "${HEADERS}" ] && HEADERS=1
fi
if [ "${MODE}" = tar ] ; then
    mkdir -p ${tmpdir}
    cd ${tmpdir}
elif [ -z "${EXEX}" -a "${MODE}" = file ] ; then
    exec >${outfile}
fi

merooty(){
    if [ "$(id -u)" != 0 ]; then
        echo "please run as root" >&2
        exit 1
    fi
}

cleanup(){
    cd /tmp
    [ "${MODE}" = "tar" ] && rm -rf ${tmpdir}
}
trap "cleanup" EXIT
sepuku(){
    cleanup
    exit
}
trap "sepuku" INT

have(){
    unset -v have;
    type "${1}" > /dev/null 2>&1 && have='yes'
}

header(){
    if [ ${HEADERS} = 1 ] ; then
        printf "\n==========================================\n"
        echo "${@}"
        printf "==========================================\n"
    fi
}

unslash(){
    echo "${*}" | sed -e 's/\//_/g' -e 's/[^A-Za-z0-9._-]/-/g'
}

run(){
    run="${1}"
    shift
    label="${@}"
    if [ -z "${label}" ] ; then
        label=$run
    fi
    if [ -z "${EXEX}" ] ; then
        printf . >&2
    fi
    if [ "${MODE}" = "tar" ] ; then
        label=$(unslash $label)
        eval ${run} >> ${label} 2>&1
    else
        header "${label}"
        eval ${run} 2>&1
    fi
}

grab(){
    if [ "${MODE}" = "tar" ] ; then
        grep -h . "${1}" >> $(basename ${1})
    else
        header "${1}"
        grep -h . "${1}"
    fi
}

columnt(){
    python -c 'import sys;from copy import deepcopy;a=[x.strip().split() for x in sys.stdin.readlines()];sys.exit(0) if len(a) == 0 else "";qq=deepcopy(a);longest=len(max(a,key=len));b=[i for i in a if len(i)==longest];z=[[row[i] for row in b] for i in range(len(b[0]))];l=[len(max(x, key=len))+2 for x in z]; o=[[ v.ljust(l[i]) for i,v in enumerate(x)] for x in b]; print "\n".join(["".join(y) for y in o]);print("TRUNCATED!TRUNCATED!TRUNCATED!TRUNCATED!TRUNCATED!") if len(b) != len(qq) else "";'
}

if have column ; then
    unset -f columnt
    alias columnt='column -t'
fi

driver(){
    if [ "${MODE}" = "tar" ] ; then
        mkdir driver
        cd driver
    fi
    DRVLOC=uninstalled
    if [ -e /proc/scsi/ethdrv ] ; then
        DRVLOC="/proc/scsi/ethdrv/ethdrv."
        loopdriver ${DRVLOC}
    fi
    if [ -e /proc/ethdrv ] ; then
        DRVLOC=/proc/ethdrv/
        loopdriver ${DRVLOC}
        case ${me} in
            Linux)
                run ethdrv-stat
                ;;
        esac
    fi
    if [ "${me}" = SunOS -a -e /dev/ethdrv ] ; then
        DRVLOC=/dev/ethdrv/
        loopdriver ${DRVLOC}
        run "ethdrvadm list-devices"
    fi
    if [ -e /proc/ethdrv.release ] ; then
        DRVLOC="/proc/ethdrv."
        loopdriver ${DRVLOC}
    fi
    if [ ! -e ${DRVLOC} -o "${DRVLOC}" = "uninstalled" ] ; then
        run 'echo "HBA Driver either too old or not installed."' 'nodriver'
    fi
    [ "${MODE}" = "tar" ] && cd ${tmpdir}
}

loopdriver(){
    if [ -z "${EXEX}" ] ; then
        printf . >&2
    fi
    DRVLOC=${1}
    for f in ${DRVLOC}* ; do
        if [ "${f}" = "${DRVLOC}cec" ] ; then continue ; fi
        case "${f}" in
            *config|*corestats|*elstats|*ifstats)
                grab "${f}"
                ;;
            *)
                DHEADERS=''
                if [ "${f}" = "${DRVLOC}acbs" ] ; then
                    DHEADERS='ln 4 s.s cwrk mxwn cscsi caoe cmds rtx unre'
                fi
                if [ "${f}" = "${DRVLOC}ca" ] ; then
                    DHEADERS='ln s.s cwrk clamp mxwn ssthresh rttavg rttdev'
                fi
                if [ "${MODE}" = tar ] ; then
                    cat "${f}" > "$(basename ${f})" #original
                    DDEST="$(basename ${f})-t"    #column-t'ed
                    if [ ! -z "${DHEADERS}" ] ; then
                        (echo "${DHEADERS}" ; cat "${f}") | columnt >> "${DDEST}"
                    else
                        grep -h . "${f}" | columnt >> "${DDEST}"
                    fi
                else
                    header "${f}"
                    if [ ! -z "${DHEADERS}" ] ; then
                        (echo "${DHEADERS}" ; cat "${f}") | columnt
                    else
                        grep -h . "${f}" | columnt
                    fi
                fi
                ;;
        esac
    done
}

targeted(){
    if [ "${me}" = "SunOS" ]; then
        if [ "${MODE}" = local ] ; then
            # :(
            DRVLOC=/dev/ethdrv/
        fi
        targets=$(for zpool in $(zpool list -H -o name |egrep -v 'rpool|syspool') ; do zpool status "${zpool}" |awk '{print $1}' |egrep '^c[0-9]+t' |sort -n |uniq |sed -e 's/^c[0-9]*t//' -e 's/d/\./'; done)
    fi
    if [ "${me}" = "VMkernel" ]; then
        if [ "${MODE}" = local ] ; then
            DRVLOC=/proc/ethdrv/
        fi
        targets=$(mapnaatoctd | awk '{print $2}')
    fi
    if [ -n "${targets}" ] ; then
        if [ "${MODE}" = local ] ; then
            diagconcatenator ${targets} | columnt
        else
            run "diagconcatenator ${targets} | columnt" targeted-diags
        fi
    fi
}

diagconcatenator(){
    if [ ! -e "${DRVLOC}acbs" ] ; then
        return ""
    fi
    grep=grep
    if [ "${me}" = "SunOS" ]; then
        grep=/usr/xpg4/bin/grep
    fi
    echo 's.s 4 cwrk mxwn clamp cscsi caoe cmds rtx unre ssthresh rttavg rttdelt'
    for t in ${@} ; do
        $grep -hE "^[[:digit:]]+ 4*[[:space:]]*$t " "${DRVLOC}acbs" "${DRVLOC}ca" | sed -e 'H;$!d;x;s/\n/ /g' -e 's/^ //' | awk '{print $3 " " $2 " " $4 " " $5 " " $14 " " $6 " " $7 " " $8 " " $9 " " $10 " " $16 " " $17 " " $18}'
    done
}


#esx
esxversion(){
    run "vmware -v"
}

esxmpath(){
    run "esxcfg-mpath -L"
}

esxmodinfo(){
    run "esxcfg-module -i ethdrv"
}

esxvolume(){
    run "esxcfg-volume -l"
}

esxscsidevs(){
    run "esxcfg-scsidevs -m"
}

esxnas(){
    run "esxcfg-nas -l"
}

esxnics(){
    run "esxcfg-nics -l"
}

esxvswitch(){
    run "esxcfg-vswitch -l"
}

esxvmknic(){
    run "esxcfg-vmknic -l"
}

lsvms(){
    run 'vim-cmd vmsvc/getallvms'
}

esxsnapshotsandvmdkinfo(){
    local table=$(vim-cmd vmsvc/getallvms | grep -v Vmid | grep '^[0-9]' | sed -e 's/\[.*//' | awk 'ORS=":"')
    # determine what VMs are powered on
    out=""
    count=0
    OLDIFS=$IFS
    IFS=':'
    for h in $table ; do
        vmnum=$(echo "${h}" | awk '{print $1}')
        vmlabel=$(echo "${h}" | sed -e 's/^ *//g' -e 's/ *$//g' -e 's/^[0-9]* *//')
        run "vim-cmd vmsvc/get.filelayout ${vmnum} 2>/dev/null | grep -C2 -E 'vmdk|vmsn'" "get.filelayout ${vmlabel}"
        run "vim-cmd vmsvc/snapshot.get ${vmnum}" "snapshot.get ${vmlabel}"
        if vim-cmd vmsvc/power.getstate "${vmnum}" | grep 'Powered on' >/dev/null 2>&1; then
            out="${out}${vmlabel} "
            count=$(expr $count + 1)
        fi
    done
    if [ -n "${out}" ] ; then
        run "echo $out" "Powered on VMs ${count}"
    fi
    IFS=$OLDIFS #probably unnecessary
}

mapnaatoctd(){
    esxcfg-mpath -L | sort | awk '{print $1 " " $3}' |  awk "BEGIN { n=1; while (getline < \"${DRVLOC}devices\" > 0){ target[\$1] = n; aoe[n] = \$2; n++; } while (\"esxcfg-scsidevs -m\" | getline) { naa = \$1; naal[naa] = \$5; for( i=6; i<=NF; i++){ naal[\$1] = naal[naa] \" \" \$i; } } }{ if (target[\$1]){ mtarget=\$1; mnaa=\$2; print mtarget \" \" aoe[target[mtarget]]\" \" mnaa \" \" naal[mnaa\":1\"] }else{ ignore } }" | sort -k2
}

wrapmap(){
    run mapnaatoctd "naa-map"
}

esxlspci(){
    run "lspci -v"
}
#end ESX

#solaris

ethdrvadmlistdevicesa(){
    have ethdrvadm && run "ethdrvadm list-devices -a"
}

solarismapnaa(){
    # find the ctds
    for ctd in $(iostat -xn | ggrep -E 'c[[:digit:]]+t[[:digit:]]' | awk '{print $NF}') ; do
        # some devices might not be in use, so only print out naa records
        naa=$(prtconf -v "/dev/rdsk/${ctd}" 2>/dev/null| ggrep ',sd@' | cut -d@ -f 2 | sed -e "s/'//g" -e "s/^n//")
        # for our purposes we only care about in-use devices, so only echo them
        if [ -n "${naa}" ] ; then
            # find the sd device by unfortunately calling iostat many many times
            sd=$(iostat -x "${ctd}" | grep sd | cut -f 1 -d ' ')
            echo "${sd} ${naa} ${ctd}"
        fi
    # now look up these devices in our driver file
    done | gawk "
    BEGIN {
        n=1;
        while (getline < \"/dev/ethdrv/devices\" > 0){
            target[\$1] = n;
            aoe[n] = \$2;
            n++;
        }
    }{
        if (target[\$1]){
            sd=\$1;
            mnaa=\$2;
            ctd=\$3;
            print sd \" \" mnaa \" \" ctd \" \" aoe[target[sd]] 
        }else{
            ignore
        }

    }" | columnt
}
wrapsolarismapnaa(){
    run solarismapnaa naa-map
}

solethdrvstats(){
    kstat -p -c kmem_cache |grep ethdrv |awk -F":" '{print $3":"$4"\t"$5}' |sort -n |columnt
}

sd2ctd(){
    iostat -xn "$(awk '{print $1}' /dev/ethdrv/devices)" |grep -v device | awk '{print $NF}'
}

solcstates(){
    if [ $(kstat -p cpu_info:::supported_max_cstates |awk '$2 ~ /^[3-9]$/' |wc -l) -gt 0 ] ; then
        run echo "c-states detected - please disable in BIOS" solcstates
    fi
}

solupdates(){
    for t in $(pkg history -o start,operation,outcome |grep "update *Succeeded" |awk '{print $1}') ; do
        printf "%s " ${t} |sed 's|T|\.|g' ;pkg history -lt "${t}" |grep "solaris/entire" |grep -v "/usr/bin/pkg" \
            |uniq |sed -e 's|pkg://solaris/entire@0.5.11,5.11-0.175|11|g' -e 's/:20.\{0,6\}T.\{0,6\}Z//g'
    done
}

whatsol(){
    run 'uname -a'
    [ -e /etc/release ] && run 'cat /etc/release' release
    have sneep && run sneep
    have hostid && run hostid
    [ -f /etc/hostid ] && grab /etc/hostid
    have pkg && run 'pkg info entire'
    run "solupdates |columnt" update-history
    #have pkg && run 'pkg info kernel' pkg-info-kernel
    #have pkg && run 'pkg info zfs' pkg-info-zfs
    have pkg && run "for idr in $(pkg info |grep "Name: idr" |awk '{print $2}') ; do pkg info \${idr} ; done" pkg-info-idr

}

solilom(){
    if have ilomconfig ; then
        for value in system-summary user identification network dns clock interconnect ; do
            run "ilomconfig list ${value}" ilomconfig-${value}
        done
    fi
}

cscanpci(){
    have scanpci && run 'scanpci | grep -v ^$' scanpci
}

fmtopo(){
    if [ -x /usr/lib/fm/fmd/fmtopo ] ; then
        run '/usr/lib/fm/fmd/fmtopo -Vp' fmtopo-Vp
    fi
}

lsiscan(){
    if have sas2flash ; then
        for c in $(sas2flash -listall 2>/dev/null |egrep ^[0-9] |awk '{print $1}') ; do
            run "sas2flash -c ${c} -list" "LSI firmware c ${c}"
        done
    else
        run "echo sas2flash not found" "sas2flash-not-found"
    fi
}

lsidisks(){
    if have sas2ircu ; then
        for c in $(sas2ircu LIST 2>/dev/null |awk '{print $1}' |egrep ^[0-9]) ; do
            run "sas2ircu ${c} DISPLAY" "sas2ircu ${c} DISPLAY"
        done
    else
        run "echo sas2ircu not found" "sas2ircu-not-found"
    fi
}

solipmitool(){
    have ipmitool && run "ipmitool fru"
}

solfw(){
    have fwupdate && run "fwupdate list all"
}

solintrstat(){
    have intrstat && run "intrstat 3 1" intrstat
}

soltuning(){
    for tunable in /etc/system /lib/svc/method/coraid-tuning.sh ; do
        if [ -f "${tunable}" ] ; then
            run 'egrep -v "^#|^\*|LD_LIBRARY_PATH|include.sh|^$" ${tunable} |sort |uniq' "${tunable}"
        fi
    done
}

cvmstat(){
    if have vmstat ; then
        run vmstat
        run 'vmstat -s'
    fi
}

fmstatus(){
    have fmstat && run 'fmstat'
}

fmadmconfig(){
    have fmadm && run 'fmadm config'
}

cprtdiag(){
    have prtdiag && run 'prtdiag -v'
}

cfmdump(){
    if have fmdump ; then
        run 'fmdump -t 7d' fmdump
        for uuid in $(fmdump -t 7d |egrep -v '^TIME|Repaired|Resolved' |awk '{print $4}') ; do
            run "fmdump -m -u ${uuid}" "fmdump-m ${uuid}"
            run "fmdump -eV -u ${uuid}" "fmdump-eV ${uuid}"
        done
    fi
    #if [ ${GRABMSGS} -eq 1 ] ; then
    #    run "fmdump -eV -t 7d" fmdump-eV-t7d
    #fi
}

cfmfaulty(){
    have fmadm && run 'fmadm faulty -av'
}

csig(){
    have machinesig && run machinesig
}

csvcs(){
    have svcs && run 'svcs -xv'
}

zpoollist(){
    run 'zpool list'
}

#zfslistsnapshots(){
#    run 'zfs list -H -r -t snapshot |egrep -v "rpool|syspool" |columnt' zfs-list-snapshots
#    run 'zfs list -H -r -t snapshot -o snapshot:type,name ||egrep -v "rpool|syspool" }columnt' zfs-list-snapshots-type
#}

solshare(){
    if have sharemgr; then
        run 'sharemgr show -pv'
    else
        if [ "$(uname -a |awk '{print $4}')" = "11.1" ] ; then
            run "zfs get -H share.all |columnt" zfs-get-share-all
        fi
        have share && run 'share -A |columnt' share-A
        if have sharectl ; then
            run 'sharectl get nfs |sort' sharectl-nfs
            run 'sharectl get smb |sort' sharectl-smb
        fi
    fi
}

solcifsmode(){
    have smbadm && run 'smbadm list'
}

solsmbusers(){
    if [ -f /var/smb/smbpasswd ] ; then
        grab /var/smb/smbpasswd
    fi
}

solsidmap(){
    have svccfg && run 'svccfg -s idmap listprop config/unresolvable_sid_mapping' idmap-sid-mapping
}

zpoolgetall(){
    for zpool in $(zpool list -H -o name); do
        run "zpool status -D ${zpool}"
        run "zpool get all ${zpool}" "zpool get all ${zpool}"
        #run "iostat -xen $(zpool status ${zpool} |awk '{print $1}' |egrep '^c[0-9]+t') 3 1" iostat-${zpool}
        if [ "${zpool}" != "rpool" ] ; then
            run "zfs list -r -t filesystem ${zpool} |columnt" "zfs list ${zpool}"
            for zvol in $(zfs list -Hr -t filesystem |grep ^${zpool} |awk '{print $1}' |sort) ; do
                run "zfs list -o space ${zvol} |columnt" "zfs list space ${zvol}"
                run "zfs list -r -t snapshot ${zvol} |columnt" "zfs list snapshots ${zvol}"
                run "zfs list -r -t snapshot -o snapshot:type,name ${zvol} |columnt" "zfs list snapshots type ${zvol}"
                run "zfs get all ${zvol}" "zfs get all ${zvol}"
                run "zfs get share ${zvol}" "zfs get share ${zvol}"
                if [ "$(uname -a |awk '{print $4}')" = "11.1" ] ; then
                    run "zfs get share.nfs.all ${zvol} 2>/dev/null" "zfs get share nfs all ${zvol}"
                    run "zfs get share.smb.all ${zvol} 2>/dev/null" "zfs get share smb all ${zvol}"
                fi
            done
        fi
        run "zpool history -l ${zpool}"
    done
}

solmapdevices(){
    python -c 'import os;devs=[y.split()[0] for y in open("/dev/ethdrv/devices").readlines()];x=[y.split()[0] for y in os.popen("iostat -x").readlines()];xn=[y.split()[-1] for y in os.popen("iostat -xn")];c=dict(zip(x,xn)); print "\n".join(["%s = %s" % (y,c.get(y)) for y in devs])'
}

solcpuinfo(){
    have psrinfo && run 'psrinfo -pv'
}

solcron(){
    if [ -d /var/spool/cron/crontabs ] ; then
        for c in $(find /var/spool/cron/crontabs -type f |grep -v "\.au") ; do
            run "egrep -v '^\#|^$' ${c}" ${c}
        done
    fi
}

solcfgsas(){
    sasinfo hba-port |grep "HBA Port Name" |awk -F"/" '{print $4}'|xargs -i cfgadm -alv {} |egrep -v "Ap_Id|^When"
}

soldiskinfo(){
    have diskinfo && run "diskinfo -t disk -o Rcmenf1 -v" diskinfo
    if have sasinfo ; then
        run "sasinfo hba -v"
        run "sasinfo hba-port -v"
        run "sasinfo expander -v"
        run "sasinfo lu -v"
    fi
    if have mpathadm ; then
        run "mpathadm list lu"
        for rdsk in $(mpathadm list lu|grep "/dev/rdsk/") ; do
            run "mpathadm show lu ${rdsk}"
        done
    fi
    if have sdmcmd ; then
        for s in $(sdmcmd scanlocal |grep 'devices\[' |awk '{print $NF}' |grep -v other:) ; do
            run "sdmcmd getinfo target=${s}" "sdmcmd-getinfo-${s}"
        done
    else
        run "echo sdmcmd not found" "sdmcmd-not-found"
    fi
    for conf in /etc/driver/drv/scsi_vhci.conf /kernel/drv/scsi_vhci.conf ; do
        [ -f ${conf} ] && run "egrep -v '^\#|^$' ${conf}" ${conf}
    done
    have stmsboot && run "stmsboot -L"
    #run 'echo "::mptsas -t" | mdb -k' mptsas-t-mdb
}

soldnlc(){
    run 'kstat -n dnlcstats' kstat-dnlcstats
    run 'kstat -n ncstats' kstat-ncstats
}

solswap(){
    if have swap ; then
        run 'swap -lh |columnt' swap-lh
        run 'swap -sh' swap-sh
    fi
    have swapinfo.pl && run "swapinfo.pl" swapinfo.pl
}

solmemstat(){
    run 'echo "::memstat" |mdb -k 2> /dev/null' mdb-memstat
}
zfs_file_data(){
    run "echo "::vmem" |mdb -k |egrep '^ADDR|zfs'" mdb-vmem-zfs_file_data
}

solkmastat(){
    run 'echo "::kmastat -g" | mdb -k 2> /dev/null' mdb-kmastat
}

solirq(){
    run 'echo "::interrupts -d" |mdb -k 2> /dev/null' mdb-interrupts
}

solarcstat(){
    run 'echo "::arc" |mdb -k 2> /dev/null' mdb-arcstat
}

solsar(){
    if svcs sar |grep online > /dev/null 2>&1 ; then
        run 'sar -A' sar-A
    fi
}

solkernparams(){
    kp="aok apic_intr_policy apic_panic_on_nmi"
    kp="${kp} autoup availrmem"
    kp="${kp} bufhwm"
    kp="${kp} clnt_max_conns cotsmaxdupreqs"
    kp="${kp} ddi_msix_alloc_limit do_tcp_fusion dnlc_max_nentries dnlc_nentries"
    kp="${kp} fastscan freemem hires_hz hires_tick ip_squeue_bind ip_squeue_fanout ip_squeue_worker_wait"
    kp="${kp} kmem_flags"
    kp="${kp} lotsfree"
    kp="${kp} mac_cpu_binding_on mac_cpu_socket_binding maxdupreqs maxpgio maxphys maxusers"
    kp="${kp} mpss_coalesce_disable mptsas_enable_msi"
    kp="${kp} ncsize nfs3_bsize nfs3_max_threads nfs3_max_transfer_size nfs3_max_transfer_size_clts"
    kp="${kp} nfs3_max_transfer_size_cots nfs3_nra nfs4_bsize nfs4_max_threads nfs4_max_transfer_size"
    kp="${kp} nfs4_max_transfer_size_clts nfs4_max_transfer_size_cots nfs4_nra"
    kp="${kp} nfs_bsize nfs_max_threads nfs_max_transfer_size nfs_max_transfer_size_clts"
    kp="${kp} nfs_max_transfer_size_cots nfs_nra"
    kp="${kp} npages"
    kp="${kp} pages_pp_maximum pg_contig_disable"
    kp="${kp} sd_io_time sd_max_throttle ssd_max_throttle sd_xbuf_active_limit ssd_xbuf_active_limit"
    kp="${kp} snoop_interval snooping sq_max_size swapfs_minfree swapfs_reserve"
    kp="${kp} tune_t_fsflushr"
    kp="${kp} ufs_HW ufs_LW"
    kp="${kp} vpm_enable"
    solparamerator $kp
}

solzfsparams(){
    zparams1=$(echo "::zfs_params" |mdb -k 2>/dev/null |awk '{print $1}' |tr '\n' ' ')
    zp="arc_grow_retry"
    zp="${zp} arc_loaned_bytes"
    zp="${zp} arc_lotsfree_percent"
    zp="${zp} arc_p_min_shift"
    zp="${zp} arc_reduce_dnlc_percent"
    zp="${zp} arc_shrink_shift"
    zp="${zp} fzap_default_block_shift"
    zp="${zp} l2arc_feed_again"
    zp="${zp} l2arc_feed_min_ms"
    zp="${zp} l2arc_headroom"
    zp="${zp} l2arc_noprefetch"
    zp="${zp} l2arc_norw"
    zp="${zp} l2arc_write_boost"
    zp="${zp} l2arc_write_max"
    zp="${zp} metaslab_aliquot"
    zp="${zp} metaslab_debug"
    zp="${zp} metaslab_df_alloc_threshold"
    zp="${zp} metaslab_df_free_pct"
    zp="${zp} metaslab_gang_bang"
    zp="${zp} metaslab_gang_threshold"
    zp="${zp} metaslab_min_alloc_size"
    zp="${zp} spa_asize_inflation"
    zp="${zp} spa_max_replication_override"
    zp="${zp} spa_mode_global"
    zp="${zp} vdev_mirror_shift"
    zp="${zp} zfetch_array_rd_sz"
    zp="${zp} zfetch_block_cap"
    zp="${zp} zfetch_max_streams"
    zp="${zp} zfetch_min_sec_reap"
    zp="${zp} zfs_arc_max"
    zp="${zp} zfs_arc_meta_limit"
    zp="${zp} zfs_arc_min"
    zp="${zp} zfs_default_bs"
    zp="${zp} zfs_default_ibs"
    zp="${zp} zfs_delay_max_ns"
    zp="${zp} zfs_delay_min_dirty_percent"
    zp="${zp} zfs_delay_scale"
    zp="${zp} zfs_dirty_data_max"
    zp="${zp} zfs_dirty_data_sync"
    zp="${zp} zfs_flags"
    zp="${zp} zfs_free_min_synctime_pct"
    zp="${zp} zfs_immediate_write_sz"
    zp="${zp} zfs_mdcomp_disable"
    zp="${zp} zfs_no_scrub_io"
    zp="${zp} zfs_no_scrub_prefetch"
    zp="${zp} zfs_no_write_throttle"
    zp="${zp} zfs_nocacheflush"
    zp="${zp} zfs_prefetch_disable"
    zp="${zp} zfs_read_chunk_size"
    zp="${zp} zfs_recover"
    zp="${zp} zfs_resilver_delay"
    zp="${zp} zfs_resilver_min_time_ms"
    zp="${zp} zfs_resilver_synctime_pct"
    zp="${zp} zfs_scan_idle"
    zp="${zp} zfs_scan_min_synctime_pct"
    zp="${zp} zfs_scrub_delay"
    zp="${zp} zfs_scrub_limit"
    zp="${zp} zfs_top_maxinflight"
    zp="${zp} zfs_txg_synctime_ms"
    zp="${zp} zfs_txg_timeout"
    zp="${zp} zfs_unmap_ignore_size"
    zp="${zp} zfs_vdev_aggregation_limit"
    zp="${zp} zfs_vdev_async_read_max_active"
    zp="${zp} zfs_vdev_async_read_min_active"
    zp="${zp} zfs_vdev_async_write_active_max_dirty_percent"
    zp="${zp} zfs_vdev_async_write_active_min_dirty_percent"
    zp="${zp} zfs_vdev_async_write_max_active"
    zp="${zp} zfs_vdev_async_write_min_active"
    zp="${zp} zfs_vdev_cache_bshift"
    zp="${zp} zfs_vdev_cache_max"
    zp="${zp} zfs_vdev_cache_size"
    zp="${zp} zfs_vdev_future_pending"
    zp="${zp} zfs_vdev_max_active"
    zp="${zp} zfs_vdev_max_pending"
    zp="${zp} zfs_vdev_min_pending"
    zp="${zp} zfs_vdev_ramp_rate"
    zp="${zp} zfs_vdev_scrub_max_active"
    zp="${zp} zfs_vdev_scrub_min_active"
    zp="${zp} zfs_vdev_sync_read_max_active"
    zp="${zp} zfs_vdev_sync_read_min_active"
    zp="${zp} zfs_vdev_sync_write_max_active"
    zp="${zp} zfs_vdev_sync_write_min_active"
    zp="${zp} zfs_vdev_time_shift"
    zp="${zp} zfs_write_limit_max"
    zp="${zp} zfs_write_limit_min"
    zp="${zp} zfs_write_limit_override"
    zp="${zp} zfs_write_limit_shift"
    zp="${zp} zil_replay_disable"
    zp="${zp} zil_slog_limit"
    zp="${zp} zio_injection_enabled"
    zp="${zp} zvol_immediate_write_sz"
    zp="${zparams1} ${zp}"
    solparamerator ${zp}
}

solparamerator(){
    params=$(printf "%s\n" ${*} | sort | uniq)
    for param in $params ; do
        echo "${param}/D" |mdb -k 2>/dev/null | grep -v ':$'
    done | awk -F: '{print $1" "$2}' |columnt
}

solarcsummary(){
    have arc_summary.pl && run arc_summary.pl arc_summary
}

solnetwork(){
    have netadm && run 'netadm list' netadm-list
    if have dladm ; then
        run 'dladm show-phys -m |grep -v ^LINK |sort' dladm-show-phys-m
        if dladm show-phys -L > /dev/null> /dev/null  2>&1 ; then
            run 'dladm show-phys -L |grep -v ^LINK |sort' dladm-show-phys-L
        else
            run 'dladm show-phys |grep -v ^LINK |sort' dladm-show-phys
        fi
        run 'dladm show-link |grep -v ^LINK |sort' dladm-show-link
        run 'dladm show-ether |grep -v ^LINK |sort' dladm-show-ether
        run 'dladm show-aggr'
        run 'dladm show-aggr -x'
        run "for aggr in $(dladm show-aggr |sort |grep -v ^LINK |awk '{print $1}') ; do dladm show-aggr -L \${aggr} ; done" dladm-show-aggr-L
        run 'dladm show-vlan'
        run 'dladm show-aggr -s'
    fi
    run 'ifconfig -a' ifconfig-a
    if have ipadm ; then
        run 'ipadm show-addr'
        run 'ipadm show-if'
        run 'ipadm show-prop -p hostmodel ipv4' ipadm-show-prop-hostmodel
    fi
    if have ipmpstat ; then
        run 'ipmpstat -i'
        run 'ipmpstat -an'
    fi
    if have dlstat ; then
        run 'dlstat show-phys'
        run 'dlstat show-aggr'
    fi
    have netstat && run 'netstat -nr'
    have ipf && run 'ipfstat -hion'
    if [ ${GRABMSGS} -eq 1 ] ; then
        have dladm && run "for net in $(dladm show-link |sort |grep -v ^LINK |awk '{print $1}') ; do dladm show-linkprop \${net} 2>/dev/null |grep -v ^LINK ; echo ; done" dladm-show-linkprop
        have ipadm && run "ipadm show-prop"
        #kstat -c net
    fi
    for f in hosts resolv.conf netmasks static_routes inet/static_routes inet/static_routes-DefaultFixed ; do
        if [ -f /etc/${f} ] ; then
            run "egrep -v '^\#|^$' /etc/${f}" etc-${f}
        fi
    done
}
solcluster() {
    if [ -d /usr/cluster/bin ] ; then
        run 'cluster show'
        run 'clrg status'
        run 'clrs status'
        run 'clq status'
        run 'clinterconnect show -v'
        run 'solmapdevices'
        grab /etc/cluster/ccr/global/infrastructure
        #clrg show
        #clrs show
        #cldevice list -v
    fi
}

rsfdiags(){
    if pkginfo -l rsf-1  > /dev/null 2>&1 ; then
        for f in init.d/rsfmonrc rc0.d/K01rsf rc1.d/K01rsf rc2.d/S99rsf rcS.d/K01rsf ; do
            if [ ! -e "/etc/${f}" ] ; then
                run "echo RSF-1 INIT SCRIPT /etc/${f} NOT INSTALLED" "DANGER DANGER"
            fi
        done
        run 'pkginfo -l rsf-1' rsf-1-version
        rsfpath=/opt/HAC/RSF-1
        rsfconf=${rsfpath}/etc/config
        if [ -f "${rsfconf}" ] ; then
            grab "${rsfconf}"
        fi
        run "${rsfpath}/bin/rsfmon -v" rsfmon-v
	run "${rsfpath}/bin/rsfmon -RR" rsfmon-RR
        if [ -f ${rsfpath}/bin/rsfcli ] ; then
            run "${rsfpath}/bin/rsfcli -i0 -v list 2>/dev/null" rsfcli-list
            run "${rsfpath}/bin/rsfcli -i0 -v heartbeats 2>/dev/null" rsfcli-hearbeat
            run "${rsfpath}/bin/rsfcli -i0 status 2>/dev/null" rsfcli-status
            run "${rsfpath}/bin/rsfcli modes" rsfcli-modes
        fi
        for lic in ${rsfpath}/etc/license.* ; do
            if [ -f "${lic}" ] ; then
                grab "${lic}"
            fi
        done
        if [ -f "${rsfpath}/etc/passwd" ] ; then
            grab "${rsfpath}/etc/passwd"
        fi
        if [ ${GRABMSGS} -eq 1 ] ; then
            rsflogs="${rsfpath}/log"
            for log in config_dist.log mapmgr.log rsfmon.log ${rsflogs}/*.panic.log ; do
                if [ -f "${rsflogs}/${log}" ] ; then
                    grab "${rsflogs}/${log}"
                fi
                if [ -f "${log}" ] ; then
                    grab "${log}"
                fi
            done
        fi
    fi
}
solprstat(){
    run 'echo |prstat -amv -n 999999 0 1' top
}

solmemconf(){
    have memconf && run 'memconf -v'
}
cpackies(){
    if have pkginfo ; then
        if pkginfo |grep -i coraid > /dev/null 2>&1 ; then
            for p in $(pkginfo |grep -i coraid |awk '{print $2}') ; do
                run "pkginfo -l ${p} |egrep 'PKGINST:|NAME:|VERSION:'" cpackies-${p}
            done
        fi
    fi
}

hmptools(){
    if uname -v | grep Nexenta > /dev/null 2>&1 ; then
        :
    else
        pkgs="biosdrv hmp-hwmgmt hmp-ipmiflash hmp-ipmitool hmp-libs hmp-snmp hmp-tools hmp-tools-biosconfig hmp-tools-ubiosconfig hmp-utils"
        for p in $(echo ${pkgs}) ; do
            if pkginfo |grep "${p}" > /dev/null 2>&1 ; then
                run "pkg info -l ${p} 2>/dev/null" hmp-tools-${p}
            fi
        done
    fi
}

nexall(){
    # this is massive -- probably a better way
    if uname -v | grep Nexenta > /dev/null 2>&1 ; then
        if [ ${GRABMSGS} -eq 1 ] ; then
        have nmc && run 'echo "show all"|nmc' nmc-show-all
        for log in nms.log nmv.log nms-down.log nmcd.log ; do
            if [ -f /var/log/${log} ] ; then
                grab /var/log/${log}
            fi
        done
        fi
    fi
}

soliscsiview(){
    for i in $(stmfadm list-lu | awk -F ':' '{print $2}' | sed 's/^\s//g'); do
        echo "LU Name: ${i}"
        stmfadm list-view -l "${i}"
    done
}

soliscsi(){
    if have itadm ; then
        run 'itadm list-target -v'
        run 'itadm list-tpg -v'
    fi
    if have stmfadm ; then
        run 'stmfadm list-lu -v'
        run 'soliscsiview' stmfadm-list-view
    fi
}

#end solaris
#begin linux
liniostat(){
    have iostat && run "iostat -xdh"
}
whatlinux(){
    run "uname -a" uname-a
    run 'grep . /etc/*release* /etc/*version* | sed 50q' version
}
linmodinfo(){
    run "find /sys/module/aoe -name version | xargs cat" module-name
}
linmounts(){
    grab /proc/mounts
}
linaoe(){
    have aoe-version && run aoe-version
    have aoe-interfaces && run aoe-interfaces
    linnetwork
    for ko in $(find /lib/modules/ -type f -name "aoe.ko") ; do
        run "strings ${ko} |grep -i ^version=" "${ko}"
    done
    if lsmod | grep aoe > /dev/null 2>&1 ; then
        have aoe-stat && run aoe-stat
        linmodinfo
        aoedebugfiles
    fi
}
linmdstat(){
    have mdadm && run "mdadm --detail --scan" mdadm-detail-scan
    grab /proc/mdstat
}
linpvs(){
    #have lvm && run "lvm dumpconfig" lvm-dumpconfig
    have pvs && run pvs
}
linux_vgdisplay(){
    have vgdisplay && run "vgdisplay -v"
}
linnetwork(){
    run 'ifconfig -a'
    have ethtool && linethtool
}
linethtool(){
    for nic in $(find /sys/class/net/*  -type l ! -name lo |awk -F"/" '{print $5}'); do
        run "ethtool -i ${nic};ethtool -k ${nic}; ethtool -g ${nic} ; ethtool -S ${nic}" ethtool-${nic}
    done
}
linfree(){
    run free
}
lindmesg(){
    run 'dmesg | tail -n 100' dmesg
}
linsysctl(){
    run "sysctl -a |sort" sysctl-asort
}
aoedebugfiles(){
    if have aoe-version ; then
        if [ "$(aoe-version | tail -1 | awk '{print $NF}' 2>/dev/null)" -lt 85 ] ; then
            for f in /sys/block/etherd*/debug ; do
                name="$(echo ${f}|sed -e 's/.*\!//' -e 's!/!-!')"
                if [ "${MODE}" = "tar" ] ; then
                    cat "${f}" > ${name}
                else
                    header "${name}"
                    cat "${f}"
                fi
            done
        else
            dmnt=/sys/kernel/debug
            mounted=$(awk '$3=="debugfs"{print $2}' /proc/mounts)
            if [ -z "${mounted}" ] ; then
                if mount -t debugfs none "${dmnt}" ; then
                    imountedit=${dmnt}
                    mounted=${dmnt}
                fi
            fi
            if [ -e ${mounted}/aoe ] ; then
                for f in ${mounted}/aoe/e*.* ; do
                    name="$(echo ${f}| sed -e 's/.*e//')"
                    if [ "${MODE}" = "tar" ] ; then
                        cat "${f}" > "${name}.debug"
                    else
                        header "${f}"
                        cat "${f}"
                    fi
                done
            fi
            if [ -n "${imountedit}" ] ; then
                umount "${dmnt}"
            fi
        fi
    fi
    [ -e /sys/module/aoe/parameters ] && run 'grep . /sys/module/aoe/parameters/*' module-parameters
}
cdmidecode(){
    have dmidecode && run dmidecode
}
lintop(){
    run 'top -b -n1' top
}
chostname(){
    have hostname && run hostname
}

whoisit(){
    have check-hostname && run check-hostname
}

#end linux

clspci(){
    have lspci && run "lspci -vM 2>/dev/null" lspci-vM
}

cuptime(){
    run uptime
}

grablog(){
    printf .
    if [ -e /var/log/vmkernel.log ] ; then
        grab /var/log/vmkernel.log
    fi
    if [ -f /var/log/messages ] ; then
        grab /var/log/messages
    fi
    if [ "${me}" = "Linux" ] ; then
        if [ -f /var/log/syslog ] ; then
            grab /var/log/syslog
        fi
    fi
    if [ -f /var/adm/messages ] ; then
        grab /var/adm/messages
    fi
    if [ "${me}" = "VMkernel" ] ; then
        run "ls -l /var/log/" "ls-l-var-log"
    fi
}

package(){
    echo Complete. >&2
    if [ "${MODE}" = "tar" ] ; then
        cd /tmp
        b="$(basename ${tmpdir})"
        tar cf "${b}.tar" "${b}"
        echo "Output file is /tmp/${b}.tar" >&2
    else
        echo "Output file is ${outfile}" >&2
    fi
}

stamp(){
    run "echo 'Coraid Diags Version: ${VERSION}'" coraid-diags-version
    run "date -u +%Y-%m-%d\ %H:%M\ %Z" date
}

esxdiags(){
    HEADERS=1
    esxversion
    whoisit
    cuptime
    driver
    if [ ${EXTENDED} -eq 1 ] ; then
        targeted
        esxvolume
        esxmpath
        wrapmap
        esxscsidevs
        esxnas
        esxvmknic
        esxvswitch
        esxnics
        lsvms
        esxsnapshotsandvmdkinfo
        esxlspci
        esxmodinfo
    fi
}

soldiags(){
    HEADERS=1
    have ntpq && run "ntpq -p"
    chostname
    whoisit
    cuptime
    whatsol
    solcstates
    cpackies
    hmptools
    csig
    driver
    ethdrvadmlistdevicesa
    if [ ${EXTENDED} -eq 1 ] ; then
        targeted
        #run sd2ctd ethdrv-ctds
        wrapsolarismapnaa
        soldiskinfo
        zpoollist
        zpoolgetall
        solshare
        solcifsmode
        solsmbusers
        soliscsi
        solsidmap
        solcpuinfo
        solprstat
        cvmstat
        #soldnlc
        solmemconf
        solmemstat
        solswap
        zfs_file_data
        #solkmastat
        run solethdrvstats ethdrv-kstat-kmem_cache
        solirq
        run solkernparams kernel-parameters
        run solzfsparams zfs-parameters
        solarcstat
        solarcsummary
        #solsar
        soltuning
        solintrstat
        solnetwork
        solcron
        csvcs
        cscanpci
        clspci
        #fmtopo
        cdmidecode
        cprtdiag
        solipmitool
        solfw
        solilom
        lsiscan
        lsidisks
        solcluster
        rsfdiags
        fmstatus
        fmadmconfig
        cfmfaulty
        cfmdump
        nexall
    fi
}

lindiags(){
    HEADERS=1
    chostname
    whatlinux
    whoisit
    cuptime
    if [ -e /proc/ethdrv ] ; then
        driver
        #targeted
    fi
    linaoe
    linfree
    linmounts
    linpvs
    linux_vgdisplay
    linmdstat
    if [ ${EXTENDED} -eq 1 ] ; then
        lintop
        cvmstat
        liniostat
        clspci
        lsiscan
        linsysctl
        cdmidecode
    fi
}

me=$(uname)

[ -e "/bin/vmware" -o -e "/usr/bin/vmware" ] && me="VMkernel"

export $me

case ${me} in
    VMkernel)
        PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
        ;;
    SunOS)
        PATH=/usr/cluster/bin:/usr/bin:/usr/sbin:/bin:/sbin:/opt/coraid/bin:/opt/HAC/RSF-1/bin
        [ -d /usr/gnu/bin ] && export PATH=/usr/gnu/bin:${PATH}
        for d in /usr/lib/fm/fmd /usr/cluster/bin /opt/HAC/RSF-1/bin /opt/coraid/bin; do
            [ -d ${d} ] && export PATH=${PATH}:${d}:
        done
        ;;
esac

if [ -n "${EXEX}" ] ; then
    stamp
    driver 1>/dev/null
    eval "${EXEX}"
    exit 0
fi

if [ ! "${MODE}" = local ] ; then
    stamp

    case ${me} in
        VMkernel)
            esxdiags
            ;;
        SunOS)
            PATH=/usr/cluster/bin:/usr/bin:/usr/sbin:/bin:/sbin:/opt/coraid/bin:/opt/HAC/RSF-1/bin
            [ -d /usr/gnu/bin ] && export PATH=/usr/gnu/bin:${PATH}
            merooty
            soldiags
            ;;
        Linux)
            merooty
            lindiags
            ;;
    esac
    if [ ${GRABMSGS} -eq 1 ] ; then
        grablog
    fi

    package
else
    targeted
fi

