#!/usr/local/bin/perl #get-dev-info.pl # get information on installed drives and how they are used by disksuite if (! defined($ENV{SUDO_USER})) { print "USAGE: sudo $0\n"; exit(1); } my (%cf,%data,@devices,%used); if ($#ARGV == -1) { $debug = 0; } else { $debug = 1; } read_vfstab(); run_format(); run_metadb(); run_metastat(); run_prtvtoc(); foreach $dev (sort keys %data) { $tmp = $dev; $tmp =~ s#(\d+)$#2#; if ($i != 2) { delete($data{$tmp}); } } foreach $dev (sort keys %data) { print "$dev\t$data{$dev}\n"; } ################################################################################ sub run_format ################################################################################ { # ## get disk information from format # if ($debug) { print "data from format\n"; } $input = "/tmp/format.input"; open(OUT,">$input"); print OUT "0\nq\n"; close(OUT); $format = "/tmp/format.output"; @res = `/usr/sbin/format < $input > $format`; open(IN,"$format"); while ($line = ) { chomp($line); if ($line =~ m#^\s+(\d+)\.\s+(.*?)\s+<(.*?)>#) { if ($debug) { print "$1 - $2\n"; } push(@devices,$2); } } close(IN); if ($debug) { print "\n"; } } ################################################################################ sub run_metadb ################################################################################ { # ## get meta-device information from metadb # if (-f "/usr/opt/SUNWmd/sbin/metadb") { $execdir = "/usr/opt/SUNWmd/sbin"; } elsif (-f "/usr/sbin/metadb") { $execdir = "/usr/sbin"; } if ($debug) { print "data from metadb\n"; } $cmd = $execdir."/metadb"; open(METADB,"$cmd |"); while ($line = ) { chomp($line); ($flags,$first,$count,$unk,$unk2,$file) = split(m#\t#,$line); if ($file =~ m#/#) { @parts = split(m#/#,$file); $devname = pop(@parts); $used{$devname} = "metadb"; } } close(METADB); } ################################################################################ sub run_metastat ################################################################################ { # ## get meta-device information from metastat # if (-f "/usr/opt/SUNWmd/sbin/metastat") { $execdir = "/usr/opt/SUNWmd/sbin"; } if (-f "/usr/sbin/metastat") { $execdir = "/usr/sbin"; } # /usr/opt/SUNWmd/sbin/metastat # /usr/sbin/metastat if ($debug) { print "data from metastat\n"; } $metafile = "/tmp/metastat.output"; @res = system($execdir."/metastat > $metafile"); # ### TESTING ################################ # $metafile = "/tmp/metastat.output.website1"; $size = (-s $metafile); open(IN,"$metafile"); read(IN,$buf,$size); close(IN); # join the multi-line outup for each meta device $buf =~ s#\s+Invoke:#\tInvoke:#g; $buf =~ s#\s+State:#\tState:#g; $buf =~ s#\s+Size:#\tSize:#g; $buf =~ s#\s+Submirror#\tSubmirror#g; $buf =~ s#\s+Stripe#\tStripe#g; $buf =~ s#\s+Device\s+Start\s+Block\s+Dbase\s+State\s+Hot\s+Spare\s+# #g; while ($buf =~ m#\n\t(c\d+t\d+d\d+s\d)#) { $buf =~ s#\n\t(c\d+t\d+d\d+s\d)# $1#; } @data = split(m#[\n\r]+#,$buf); # @devs = grep(m#c\d+t\d+d\d+s\d#,$buf); foreach $line (@data) { chomp($line); # print "$line\n"; $line =~ s#^\s+##; @words = split(m#\s+#,$line); # print "$#words\t$line\n"; if (($line =~ m#^d#) && ($words[1] =~ m#Mirror#)) { # print "mirror - $line\n"; $volume = $words[0]; $voltype = $words[1]; @parts = split(m#\t#,$line); foreach $pair (@parts) { ($name,$val) = split(m#:#,$pair,2); if ($name =~ m#Submirror#) { # print " Submirror: $val\n"; } elsif ($name =~ m#State#) { # print " State: $val\n"; } elsif ($name =~ m#Size#) { # print " Size: $val\n"; } elsif ($name =~ m#Stripe#) { # print " $name: $val\n"; } } } if (($line =~ m#^d#) && ($words[1] =~ m#Submirror#)) { # print "submirror - $line\n"; $volume = $words[0]; $volume =~ s#:$##; $voltype = $words[1]; $parent = $words[3]; @parts = split(m#\t#,$line); foreach $pair (@parts) { if ($pair =~ m#(.*?):(.*?)$#) { $name = $1; $val = $2; # ($name,$val) = split(m#:#,$pair,2); if ($name =~ m#Submirror#) { # print " Submirror: $val\n"; } elsif ($name =~ m#State#) { # print " State: $val\n"; } elsif ($name =~ m#Size#) { # print " Size: $val\n"; } elsif ($name =~ m#Stripe#) { # print " $pair] [$name:] [$val\n"; if ($val =~ m#\)#) { ($front,$back) = split(m#\)#,$val); # print "[$front] [$back]\n"; $val = $back; } $val =~ s#\s+c#XYzzYc#g; @slices = split(m#XYzzY#,$val); foreach $slice (@slices) { ($dev,$start,$dbase,$state,$spare) = split(m#\s+#,$slice); if ($dev ne "") { if (($debug) or ($state =~ m#Maintenance#)) { print " Dev: $dev\t$state\t$spare\tsubmirror $volume of $parent\n"; } $string = "submirror $volume of $parent ($used{$parent})\t$state\t$spare"; $used{$dev} = $string; } } } } if ($pair =~ m#^c#) { ($dev,$start,$dbase,$state,$spare) = split(m#\s+#,$pair); print " dev: $dev] [$start][$dbase]\n"; } } } } if ($debug) { print "\n"; } } #exit(); ################################################################################ sub read_vfstab ################################################################################ { # ## get mount point info from vfstab # if ($debug) { print "data from vfstab\n"; } $vfstab = "/etc/vfstab"; open(IN,"$vfstab"); read(IN,$buf,$size); while ($line = ) { chomp($line); if ($line =~ m/^#/) { #ignore comments } else { # if ($line =~ m#/dev/dsk#) { ($vdevice,$vrawdevice,$vmountpoint,$vfsck,$vpass,$vboot,$vopt) = split(m#\s+#,$line); @dparts = split(m#/#,$vdevice); $dev = pop(@dparts); if ($vfsck =~ m#swap#) { $vmountpoint = $vfsck; } if (($vfsck ne "proc") && ($vfsck ne "nfs")) { $used{$dev} = $vmountpoint; if ($debug) { print "$dev -> $vmountpoint\n"; } } } # elsif ($line =~ m#/dev/md#) # { # ($vdevice,$vrawdevice,$vmountpoint,$vfsck,$vpass,$vboot,$vopt) = split(m#\s+#,$line); # @dparts = split(m#/#,$vdevice); # $dev = pop(@dparts); # $used{$dev} = $vmountpoint; # } } } close(IN); if ($debug) { print "\n"; } } # ## put it all together # ################################################################################ sub run_prtvtoc ################################################################################ { if ($debug) { print "data from prtvtoc\n"; } foreach $dev (@devices) { $file = "/dev/rdsk/".$dev."s2"; if (-e $file) { $lc = 0; open(IN,"/usr/sbin/prtvtoc $file |"); @data = ; close(IN); # while ($line = ) foreach $line (@data) { $lc++; chomp($line); # print "$line\n"; if ($line =~ m#^\*#) { if ($line =~ m#bytes/sector#) { ($j,$bytes_per_sector,$j) = split(m#\s+#,$line); } } else { ($j,$partition,$tag,$flags,$first,$count,$last,$dir) = split(m#\s+#,$line); $devname = $dev."s".$partition; $size = $bytes_per_sector * $count; $ksize = $size / 1024; $size = add_commas($size); $ksize = add_commas($ksize); if (($dir eq "") && (defined($used{$devname}))) { $dir = $used{$devname}; } # print "$devname\t$size\tbytes\t$ksize\tKB\tmounted as\t$dir\n"; # print "$devname\t$ksize\tKB\tmounted as\t$dir\n"; if ($dir eq "") { $string = sprintf "%12s\tKB",$ksize; } else { $string = sprintf "%12s\tKB\tmounted as\t$dir",$ksize; } $data{$devname} = $string; # if ($ksize < 15000) # { # delete($data{$devname}); # } } } close(IN); # ## if the drive has failed, prtvtoc fails ## build info from the .cf file # if ($lc == 0) { parse_cf(); @parts = split(m#/#,$file); $device = pop(@parts); $device =~ s#s2#s#; foreach $devname (keys %cf) { if ($devname =~ m#$device#) { $data{$devname} = $cf{$devname}; } } print "disk Error: $file\n"; } } } } ################################################################################ sub parse_cf ################################################################################ { my ($devname); open(CF,"/etc/lvm/md.cf"); while ($line = ) { if ($line =~ m#\s+-m\s+#) { chomp($line); ($mir,$j,$rest) = split(m#\s+#,$line,3); # print "[$mir][$j][$rest]\n"; } elsif ($line =~ m#(.*?)\s+\d+\s+\d+\s+(.*?)$#) { $submir = $1; $devname = $2; # print "[$submir] [$devname]\n"; if (($dir eq "") && (defined($used{$devname}))) { $dir = $used{$devname}; } $string = sprintf "%12s\t\tmounted as\tsubmirror $submir of $mir ($used{$mir})\t[Maintenance?]",$foo; $cf{$devname} = $string; # print "$devname => $string\n"; } } close(CF); } ################################################################################ sub add_commas ################################################################################ { local($num) = @_; $wholenumber = (split(m#\.#,$num))[0]; while ($wholenumber =~ s#(.*\d)(\d\d\d)#$1,$2#) { # print "$wholenumber\n"; } return($wholenumber); }