#!/bin/ksh
#
# $Id: metamap,v 1.1 2002/02/05 13:11:41 root Exp $
#
# metamap - Adrian Ball - 02/2002
#
# Lists metadevices in a more useful format than metastat
# Assumes the usual tools are available in the path
# Must be run as root for prtvtoc to function

TMPDIR=/tmp/metamap.$$
mkdir -p $TMPDIR
VTOC=$TMPDIR/vtoc
METASTAT=$TMPDIR/metastat
TRANS=$TMPDIR/trans
METADB=$TMPDIR/metadb
DFK=$TMPDIR/dfk
SWAP=$TMPDIR/swap
DUMP=$TMPDIR/dump

FMT="%2s   %6.2f | %-6s %-6s |  %s\n"

echo "Gathering information, into $TMPDIR..." >&2

# metastat -p can split lines, so unsplit them
metastat -p | nawk \
    '/\\/ { split ($0, a, "\\") ; printf "%s", a[1] } !/\\/ { printf "%s\n", $0 }' \
    > $METASTAT

# List of trans devices	
grep "\-t" $METASTAT > $TRANS

# List of metastate databases
metadb > $METADB

# Mounted filesystems
df -k > $DFK

# Swap partitions
swap -l > $SWAP

# Dump devices
dumpadm|grep device > $DUMP

### Create some easy-to-read data files for each disk...

for devpath in `ls /dev/rdsk/*0` ; do
    disk=`basename $devpath | sed -e 's/s0$//'` # Basename (eg c0t0d0)
    if [ ! -r /vol/dev/rdsk/$disk ] ; then  	# Ignore CD drive
    	prtvtoc $devpath > $VTOC 2>/dev/null				
        cat $VTOC | nawk '/^ +[0-9]/ {printf "%s %6.2f\n", $1, $5/1024/1024/2}' \
	    > $TMPDIR/${disk}.size		# List slices with sizes in GB
		
	# Calculate the size of the disk manually, as slice 2 may not be set correctly
	cat $VTOC | nawk \
	    '/bytes\/sector/ 	    {bs=$2} 
	     /sectors\/cylinder/    {sc=$2}
	     /accessible/   	    {cyl=$2}
	     END    	    	    {printf "%.2f", bs*sc*cyl/1024/1024/1024}' \
	     > $TMPDIR/${disk}.total	
    fi
done

softparts() 
{

	alloc=0
	parent=$1
	softparts=$2
	for softpart in $softparts ; do
	    ssize=$(grep "$softpart " $METASTAT | awk '{print $7/2048/1024}')
	    slice=""

	    # usage
	    use=`egrep "dsk/$softpart " $DFK | nawk '{print $6}'`
            if [ "$use" = "" ] ; then
	    	egrep "dsk/$softpart " $SWAP > /dev/null
			[ $? -eq 0 ] && use="SWAP"
	    fi

	    egrep "dsk/$softpart" $DUMP > /dev/null
	    if [ $? -eq 0 ] ; then
		[ "$use" = "SWAP" ] && use="SWAP/DUMP" || use="DUMP"
            fi

  	    alloc=`echo "$alloc $ssize" | nawk '{print $1 + $2}'`
    	    printf "$FMT" "$slice" "$ssize" "+---->" "$softpart" "$use"
	done
	printf "                               %-.2f GB allocated\n" $alloc
}


### Now write the report

echo "\nSolstice DiskSuite Mappings for `hostname` - `date`"
echo "==============================================================================="


### Dump the list of trans devices, as trying to map these would get very
### cluttered.

echo "\nTrans devices...\n---------------"
cat $TRANS

for sizefile in `ls $TMPDIR/*.size` ; do

    disk=`basename $sizefile .size`
    disksize=`cat $TMPDIR/${disk}.total`
    used=0

    echo "\n\n$disk (${disksize}GB)\n-----------------"

    while read slice size ; do
    	dev="${disk}s${slice}"
	md=""
	mmd=""
	use=""
	softpart=""
	
	### Are we a metadevice?
	md=`egrep $dev $METASTAT | nawk '!/-p/ {print $1}'`
	
	### We are a metadevice, so lets see if we are part of a mirror
	[ "$md" != "" ] && mmd=`egrep "$md " $METASTAT | nawk '/-m/ { print $1 }'`

	### If we are a metadevice, see if we are a filesystem, used for swap, or a translog
	if [ "$md" != "" ] ; then

	    # Check for a mounted filesystem
	    use=`egrep "dsk/$md |dsk/$mmd " $DFK | nawk '{print $6}'`

	    # Empty, so see if we are used for swap
            if [ "$use" = "" ] ; then
	    	egrep "dsk/$md|dsk/$mmd " $SWAP > /dev/null
			[ $? -eq 0 ] && use="SWAP"
	    fi
		
		# Or dump
		egrep "dsk/$md |dsk/$mmd " $DUMP > /dev/null
		if [ $? -eq 0 ] ; then
			[ "$use" = "SWAP" ] && use="SWAP/DUMP" || use="DUMP"
		fi

		# Still empty, so we may be a translog
		if [ "$use" = "" ] ; then
			cat $TRANS | nawk '{print $4}' | egrep "$md|$mmd" > /dev/null
			[ $? -eq 0 ] && use="TRANSLOG"
		fi

		# STILL empty, so we could be part of a trans device
		if [ "$use" = "" ] ; then
			use=`cat $TRANS | egrep "\-t $md |\-t $mmd " | nawk '{print $1}'`
			[ "$use" != "" ] && use=`egrep "/$use " $DFK | nawk '{print $6}'`" ($use trans)"
		fi

		# STILL STILL empty, so there's a possibility that we have soft partitions
		# created underneath
		if [ "$use" = "" ] ; then
			softpart=$(grep -- "-p $md" $METASTAT | awk '{printf "%s ", $1}') 		
			[ "$softpart" = "" -a "$mmd" != "" ] && softpart=$(grep -- "-p $mmd" $METASTAT | awk '{printf "%s ", $1}') 
			if [ "$softpart" != "" ] ;then 
			    use="Soft partitions:-"	
			fi
		fi

	else
	    ### We are not a metadevice, so see if we are a metadb,
		### or maybe a plain filesystem/swap/dump
	    egrep "$dev" $METADB > /dev/null
	    if [ $? -eq 0 ] ; then 
	    	use="METADB"
	    else
    		use=`egrep "dsk/$dev " $DFK | nawk '{print $6}'`
	    fi
		
		# Not a file system, so check for swap
		if [ "$use" = "" ] ; then
			egrep "$dev" $SWAP > /dev/null
			[ $? -eq 0 ] && use="SWAP"
		fi
		
		# And/or dump
		egrep "$dev" $DUMP > /dev/null
		if [ $? -eq 0 ] ; then
			[ "$use" = "SWAP" ] && use="SWAP/DUMP" || use="DUMP"
		fi

		if [ "$use" = "" ] ; then
			softpart=$(grep -- "-p $dev" $METASTAT | awk '{printf "%s ", $1}') 		
			if [ "$softpart" != "" ] ;then 
			    use="Soft partitions:-"	
			fi
		fi
	fi
		
    	printf "$FMT" "$slice" "$size" "$md" "$mmd" "$use"
	[ "$softpart" != "" ] && softparts "$md" "$softpart"

	[ "$use" != "" ] && used=`echo "$used $size" | nawk '{print $1 + $2}'`

    done < $sizefile
	
    printf "------------\nUsed:%6.2f\n" $used


done

rm -rf $TMPDIR
