#/net/taoai.ebay/home/support/perl/bin/perl
#/usr/dist/share/perl,v5.003/5bin.sun4/perl
#/usr/bin/perl

$ENV{PATH} = "/bin:/usr/sbin:/usr/opt/SUNWmd/sbin:/etc/vx/bin:$ENV{PATH}";
$DFCMND    = "df -k -Fufs";
$SWAPCMND  = "swap -l";
$METADBCF  = "/etc/opt/SUNWmd/mddb.cf";
$tempfile  = "/tmp/$BASECMND.tmp.fil";
@DEVICES   = ();
@vxpsdout  = ();
@vxpdmout  = ();
$ofile     = 0;
$BASECMND  = `basename $0`;
chomp($BASECMND);

@ALLDEVS   = `ls /dev/rdsk/*s2 | cut -d"/" -f4`;
@CDROMS    = `ls -l /dev/sr* | cut -d"/" -f4`;
@EXEMPT    = @CDROMS;

&listVMDisks();

if (@ARGV != 0) { &parseOptions(); }

for($i = 0; $i < @ALLDEVS; $i++) {
  chomp($temp = $ALLDEVS[$i]);
  $status1 = grep /($temp)/, @vxpdmout;
  $status2 = grep /($temp)/, @EXEMPT;
  if ((! $status1) && (! $status2)) { push @DEVICES, $ALLDEVS[$i]; }
}

&getSEVMInfo();
$chkmeta = &chkMeta();
&getSliceInfo();

sub chkMeta {
  local $status;

  $status = 0;
  if (-e $METADBCF) {
    $metaparts = `grep -v "^#" $METADBCF`; 
    if ("${metaparts}x" ne "x") { 
      $status = 1; 
      @mstatlist = `metastat -p`;
      @mdblist   = `metadb`;
    }
  }
  return($status);
}

sub chkMetadb {
  local @dlog;
  
  @dlog = grep /$ldevice/, @mdblist;
  if ("@dlog" ne "") { $key  = "metadb"; }
  return($key);
}

sub chkMetadev {
  $prevkey = @_[0];
  local $i, $j, $k, $status, @dlog, @temp, @tmplog;

  @dlog   = grep /$ldevice/, @mstatlist;
  if ("@dlog" eq "") { return($prevkey); }

  if ("$prevkey" eq "unused") { $key = "metadev"; }
  else { $key = "mdbdev"; }

  for($i = 0; $i < @mstatlist; $i++) {
    @tmplog = split(/ /, @mstatlist[$i]);
    $_      = "@tmplog";
    if (/^d\d+/) { $mntdir = "$tmplog[0]"; }
    $status = grep /$ldevice/, "@tmplog";
    if ($status != 0) { 
      @status = grep / $mntdir /, (grep / -m /, @mstatlist);
      if (@status != 0) { 
	@tmplog  = split(/ /, "@status");
	$mntdir .= " ($tmplog[0])";
      }
      $i = @mstatlist; 
    }
  }
  return($key);
}

sub chkMounted {
  local @dlog;

  @dlog = grep /$ldevice/, `$DFCMND`;
  if ("@dlog" ne "") { $key  = "mounted"; }
  return($key);
}

sub chkRaw {
  local @dlog, @temp;

  @dlog = grep /$ldevice/, `ls -lL /dev/rdsk/$ldevice`;
  @dlog = grep !/root/, @dlog;
  if ("@dlog" ne "") { 
    @temp = split(/\s+/, "@dlog");
    $key  = "$temp[2]";
  }
  return($key);
}

sub chkSwap {
  local @dlog;

  @dlog = grep /$ldevice/, `$SWAPCMND`;
  if ("@dlog" ne "" ) { $key  = "swap"; }
  return($key);
}

sub getDiskInfo {
  local $i, @temp;

  @info = split(/\n/, $diskinfo);
  for($i = 0; $i < @info; $i++) {
    $_ = $info[$i];
    SWITCH: {
      /bytes\/sector/	&& do { 
	@temp  = split(/\s+/, $info[$i]);
	$bytPsct = $temp[1];
	last SWITCH; 
      };
      /sectors\/track/ && do {
	@temp  = split(/\s+/, $info[$i]);
	$sctPtrk = $temp[1];
	last SWITCH;
      };
      /tracks\/cylinder/ && do {
	@temp  = split(/\s+/, $info[$i]);
	$trkPcyl = $temp[1];
	last SWITCH;
      };
      /sectors\/cylinder/ && do {
	@temp  = split(/\s+/, $info[$i]);
	$sctPcyl = $temp[1];
	last SWITCH;
      };
    }
  }
#    print "$bytPsct ,, $sctPtrk ,, $trkPcyl ,, $sctPcyl ,, @temp \n";
#    print "$diskinfo \n";
}

sub getSEVMInfo {
  $key = "SEVM";
  printf({$ofile?OUTFILE:"STDOUT"} "%-12s %7s %10s %10s %10s\n\n",
	   "Device", "Key", "Sectors", "Size", "Volume/(Free Space)");

  for($i = 0; $i < @vxpdmout; $i++) {
    @disks    = split(/\s+/, $vxpdmout[$i]);
    @subdisks = grep /($disks[1])/, @vxpsdout;
    $totsize  = 0;
    for($j = 0; $j < @subdisks; $j++) {
      @subdisk = split(/\s+/, $subdisks[$j]);
      $totsize = $totsize + $subdisk[2];
      $size    = $subdisk[2] / 2;
      ($size, $sizein) = &getSize($subdisk[2] / 2, "KB");
      printf({$ofile ? OUTFILE : "STDOUT"} "%-12s %7s %10d %7.2f %2s %s\n",
	     $subdisk[1], $key, $subdisk[2], $size, $sizein, $subdisk[3]);
    }
    ($size, $sizein) = &getSize($disks[2] / 2, "KB");
    $free = ($disks[2] - $totsize) / 2;
    ($free, $freein) = &getSize($free, "KB");
    printf({$ofile?OUTFILE:"STDOUT"} "%-12s %7s %10d %7.2f %2s (%7.2f %2s)",
	   $disks[1], "FULL", $disks[2], $size, $sizein, $free, $freein);
    printf({$ofile?OUTFILE:"STDOUT"} "\n\n");
  }
}
  
sub getSize {
  local($size, $sizein) = @_;

  if ($sizein eq "KB") {
    if ($size >= 1024) {
      $size   = $size / 1024;
      $sizein = "MB";
    }
  }
  if ($size >= 1024) {
    $size   = ($size / 1024);
    $sizein = "GB";
  }
  return($size, $sizein);
}
sub getSliceInfo {
  local $i, $j, @temp, $ldevice;
  
  printf({$ofile?OUTFILE:"STDOUT"} "\n%-12s %7s %5s - %5s %10s (Cyls)\n",
	   "Device", "Key", "Start", "End", "Size");

  for($i = 0; $i < @DEVICES; $i++) {
    chomp($DEVICES[$i]);
    ($devhead, $two) = split(/s/, $DEVICES[$i]);
    $diskinfo = `prtvtoc /dev/rdsk/$DEVICES[$i]`;
    &getDiskInfo();
    $sliceinfo = `prtvtoc -h /dev/rdsk/$DEVICES[$i]`;
    @slices = split(/\n/, $sliceinfo);
    open(TFILE, ">$tempfile");
    for ($j = 0; $j < @slices; $j++) {
      @temp   = split(/\s+/, $slices[$j]);
      $size   = ((@temp[5] / 1024) * $bytPsct) / 1024;
      ($size, $sizein) = &getSize($size, "MB");
      if ($sctPcyl != 0) {
	$numcyl = @temp[5] / $sctPcyl;
	$sttcyl = @temp[4] / $sctPcyl;
	$endcyl = @temp[6] / $sctPcyl;
	$mntdir = @temp[7];
	&getUsage("$devhead" . "s" . "@temp[1]");
      }
    }
    close(TFILE);
    &resolveSlice2();
  }
}

sub getUsage {
  local($ldevice) = @_;

  $key = "unused";
  $key = &chkMounted();
  if ("$key" eq "unused") { $key = &chkSwap(); }
  if ("$key" eq "unused") { $key = &chkRaw(); }
  if (("$key" eq "unused") && $chkmeta) { $key = &chkMetadb(); }
  # force chkMetadev(). A Meta-partition could also hold the Replica info.
  if ($chkmeta) { $key = &chkMetadev("$key"); }
  if ("$key" eq "unused") { $mntdir = ""; }
  printf TFILE "%-12s %7s %5d - %5d %7.2f %2s (%5d c)", $ldevice, $key, 
  $sttcyl, $endcyl, $size, $sizein, $numcyl;
  print TFILE " $mntdir \n";
}

sub listVMDisks {
  @sevmdisks = ();
  if (-d "/dev/vx") {
    @vxprintout = `vxprint -AdsF "%rtype %name %len %vol %assoc"`;
    if (@vxprintout) {
      @vxpsdout = grep /^sd /, @vxprintout;
      @vxpdmout = grep /^dm /, @vxprintout;
    }
  }
}

sub parseOptions {
  for($i = 0; $i < @ARGV; $i++) {
    $_ = $ARGV[$i];
    SWITCH: {
	/^-d/	&& do { 
	  @ALLDEVS = `cd /dev/rdsk; ls $ARGV[++$i] | cut -d"/" -f4`;
	  last SWITCH; 
	};
	/^-o/ && do {
	  $filename = "$ARGV[++$i]";
	  open(OUTFILE, ">$filename");
	  $ofile = 1;
	  last SWITCH;
	};
	print "Unknown option : $ARGV[$i]\n";
	&printUsage();
	die "\n";
      }
  }
}

sub printUsage {
  print "Usage :: $BASECMND [-d <device list>] [-o <outfile>]\n";
  print "\n";
  print "eg    :: $BASECMND -d c0t0d0s2 -o ${BASECMND}.log\n";
  print "      :: $BASECMND -d " . '"c0t0d0s2 c1t0d1s2"' . "\n";
  print "      :: $BASECMND -d " . '"c?t0d*s2"' . "\n";
}

sub resolveSlice2 {
  @slice2    = `grep s2 $tempfile`;
  @sliceRest = `grep  -v s2 $tempfile`;
  @unused    = grep /unused/, @slice2;

  print {$ofile ? OUTFILE : "STDOUT"} "\n";
  
  if (@unused) { 
    print {$ofile ? OUTFILE : "STDOUT"} @sliceRest;
    $_ =  @slice2[0];
    s/unused/  FULL/;
    print "$_";
  }
  else { 
    print {$ofile ? OUTFILE : "STDOUT"} @slice2; 
    print {$ofile ? OUTFILE : "STDOUT"} @sliceRest;
  }
}
