ServDoc_disks - Describe everything about the diskspace for a unixsystem.
$Id: ServDoc_0120disks,v 1.29 2004/02/16 20:11:01 uherbst Exp $
ServDoc_disks [-h|help] [-v|version] [--debug DISK,intensity]
ServDoc_disks describes everything about the diskspace for a unixsystem.
That includes:
The debug feature for that module is named ``DISK''.
Ulrich Herbst <Ulrich.Herbst@gmx.de>
#!/usr/bin/perl -w
## POD
#---------------------------------------------------------------------- ## use modules # standard perl modules use strict; # print error about unknown variables ... use English; # long internal variable names; use FindBin; # In which directory is ServDoc itself ? # There has to be the module and the lib dir! use lib $FindBin::Bin. "/lib"; # Here are the ServDoc-perl-modules use vars qw($options); # our own perl modules use ServDoc; #---------------------------------------------------------------------- $options->{Version} = '$Id: ServDoc_0120disks,v 1.29 2004/02/16 20:11:01 uherbst Exp $'; # We need the cmdline to call the modules with the same debug options. $options->{cmdline} = join " ", @ARGV; sub debug { ServDoc_debug( "DISK", $options, shift, shift ); } $options = &process_cmdline($options); %{$options->{lang}->{en}}= ( running => i18n_std('running',$0), ide => 'Unix%%+Disk%%+IDE driver version', ide_short => i18n_std('filecontent','/proc/ide/drivers'), ide_long => "", idechip => 'Unix%%+Disk%%+IDE chipset information', #idechip_short not used! idechip_long => "", idedisk => 'Unix%%+Disk%%+%s%%+Disk model', #idedisk_short not used idedisk_long => "Manufacturer, model number", idemedia => 'Unix%%+Disk%%+%s%%+Media Type', #idemedia_short not used idemedia_long => "", idecap => 'Unix%%+Disk%%+%s%%+Capacity', #idecap_short not used idecap_long => 'Raw Capacity', idegeo => 'Unix%%+Disk%%+%s%%+Geometry', #idegeo_short not used idegeo_long => 'Cylinder/Head/Sector', scsidev => 'Unix%%+Disk%%+SCSI devices', scsidev_short => i18n_std('filecontent',"/proc/scsi/scsi"), scsidev_long => "", aixdev => 'Unix%%+Disk%%+Devices', aixdev_short => i18n_std('cmdout','lsdev -C | grep disk'), aixdev_long => "Just 'lsdev -Cc disk' doesn't show the SSA-pdisks.", hpdev => 'Unix%%+Disk%%+Devices', hpdev_short => i18n_std('cmdout','ioscan -C disk'), hpdev_long => '', sundev => 'Unix%%+Disk%%+Devices', sundev_short => i18n_std('cmdout','format'), sundev_long => '', unsupported => 'Unsupported OS for Disk-Hardware', part => 'Unix%%+Disk%%+%s%%+Partition', # part_short not used part_long => '', aixpv => 'Unix%%+Disk%%+LVM%%+Physical Volumes', aixpv_short => i18n_std('cmdout','lspv'), aixpv_long => '', aixvg => 'Unix%%+Disk%%+LVM%%+Volumegroups', aixvg_short => i18n_std('cmdout','lsvg'), aixvg_long => '', aixvg1 => 'Unix%%+Disk%%+LVM%%+Volumegroups%%+%s', #aixvg_short aixvg1_long => '', aixlv => 'Unix%%+Disk%%+LVM%%+Logical Volumes%%+%s', # aixlv_short not used aixlv_long => '', aixoverview => 'Unix%%+Disk%%+LVM%%+Overview', aixoverview_short=> '', aixoverview_long=> 'All your LVs, Mirrors, Filesystems, Serial Numbers', # aix overview headlines aixovLV => 'LV', aixovLP => 'LP', aixovPP => 'PP', aixovVG => 'VG', aixovTYPE => 'Type', aixovFS => 'FS', aixovNAME => 'Name(%s)', aixovSERIAL => 'Serial(%s)', aixovSIZE => 'Size(%s)', aixovPP2 => 'PP(%s)', hplvm => 'Unix%%+Disk%%+LVM%%+Volumegroups, PVs, LVs', hplvm_short => i18n_std('cmdout','vgdisplay -v'), hplvm_long => '', sunV => 'Unix%%+Disk%%+Software Raid%%+Version', sunV_short => i18n_std('cmdout','pkginfo -l SUNWmd'), sunV_long => '', metastat => 'Unix%%+Disk%%+Software Raid%%+metastat', metastat_short => i18n_std('cmdout','metastat'), metastat_long => '', metadb => 'Unix%%+Disk%%+Software Raid%%+metadb', metadb_short => i18n_std('cmdout','metadb'), metadb_long => 'Where is your RAID meta information ?', md => 'Unix%%+Disk%%+Software Raid%%+state', md_short => i18n_std('filecontent','/proc/mdtab'), md_long => 'Which raid, which partitions,...', raidtab => 'Unix%%+Disk%%+Software Raid%%+Configuration', raidtab_short => i18n_std('filecontent','/etc/raidtab'), raidtab_long => '', linpv => 'Unix%%+Disk%%+LVM%%+Physical Volumes', linpv_short => i18n_std('cmdout','pvscan -vv'), linpv_long => '', linvg => 'Unix%%+Disk%%+LVM%%+Volume Groups and Logical Volumes', linvg_short => i18n_std('cmdout','vgdisplay -v'), linvg_long => '', fstab => 'Unix%%+Disk%%+Filesystems%%+configured filesystems', fstab_short => i18n_std('filecontent','/etc/fstab'), fstab_long => 'Which filesystems can you mount on your system ?', mount => 'Unix%%+Disk%%+Filesystems%%+Mounted Filesystems', mount_short => i18n_std('cmdout','mount'), mount_long => "configured and mounted filesystems are NOT ". "always the same...", filesystems => 'Unix%%+Disk%%+Filesystems%%+configured filesystems', filesystems_short=> i18n_std('filecontent','/etc/filesystems'), filesystems_long => 'Which filesystems can you mount on your system ?', sbtab => 'Unix%%+Disk%%+Filesystems%%+Redundant Superblocks', sbtab_short => i18n_std('filecontent','/etc/sbtab'), sbtab_long => '', vfstab => 'Unix%%+Disk%%+Filesystems%%+configured filesystems', vfstab_short => i18n_std('filecontent','/etc/vfstab'), vfstab_long => 'Which filesystems can you mount on your system ?', mounttab => 'Unix%%+Disk%%+Filesystems%%+Mounted Filesystems', mounttab_short => i18n_std('filecontent','/etc/mnttab'), mounttab_long => "configured and mounted filesystems are NOT ". "always the same...", unsupported_fs => "This OS isn't currently supported for ". "FileSystem Configuration", df1 => 'Unix%%+Disk%%+Filesystems%%+Mounted Filesystems and Sizes', # df1_short not used df1_long => "Which filesystems are currently mounted and how big are they ?", df2 => 'Unix%%+Disk%%+Filesystems%%+Mounted Filesystems and Usage', # df2_short not used df2_long => "Which filesystems are currently mounted, how big are " . "they and how are they used ?", linswap => 'Unix%%+Disk%%+Swapspace', linswap_short => i18n_std('cmdout','swapon -s'), linswap_long => 'Which / how many swap space do you have ?', aixps => 'Unix%%+Disk%%+Paging Space', aixps_short => i18n_std('cmdout','lsps -a'), aixps_long => 'Which /how many paging space do you have ?', hp_ps => 'Unix%%+Disk%%+Paging Space', hp_ps_short => i18n_std('cmdout','swapinfo'), hp_ps_long => 'Which /how many paging space do you have ?', sunswap => 'Unix%%+Disk%%+Swapspace', sunswap_short => i18n_std('cmdout','swap -l'), sunswap_long => 'Which / how many swap space do you have ?', unsupported_swap=> "This OS isn't currently supported for swap configuration", ); %{$options->{lang}->{de}}= ( running => i18n_std('running',$0), ide => 'Unix%%+Disk%%+IDE Treiber', ide_short => i18n_std('filecontent','/proc/ide/drivers'), ide_long => "", idechip => 'Unix%%+Disk%%+IDE Chipsatz', #idechip_short not used! idechip_long => "", idedisk => 'Unix%%+Disk%%+%s%%+Modell', #idedisk_short not used idedisk_long => "Hersteller, Modellnummer", idemedia => 'Unix%%+Disk%%+%s%%+Medientyp', #idemedia_short not used idemedia_long => "", idecap => 'Unix%%+Disk%%+%s%%+Kapazität', #idecap_short not used idecap_long => 'Raw Capacity', idegeo => 'Unix%%+Disk%%+%s%%+Festplatten-Geometrie', #idegeo_short not used idegeo_long => 'Zylinder/Köpfe/Sektoren', scsidev => 'Unix%%+Disk%%+SCSI Geräte', scsidev_short => i18n_std('filecontent',"/proc/scsi/scsi"), scsidev_long => "", aixdev => 'Unix%%+Disk%%+Geräte', aixdev_short => i18n_std('cmdout','lsdev -C | grep disk'), aixdev_long => "Nur 'lsdev -Cc disk' zeigt nicht die SSA-pdisks!", hpdev => 'Unix%%+Disk%%+Geräte', hpdev_short => i18n_std('cmdout','ioscan -C disk'), hpdev_long => '', sundev => 'Unix%%+Disk%%+Geräte', sundev_short => i18n_std('cmdout','format'), sundev_long => '', unsupported => 'Betriebssystem wird von ServDoc für ". Plattenhardware nicht unterstützt.', part => 'Unix%%+Disk%%+%s%%+Partitionen', # part_short not used part_long => '', aixpv => 'Unix%%+Disk%%+LVM%%+Physical Volumes', aixpv_short => i18n_std('cmdout','lspv'), aixpv_long => '', aixvg => 'Unix%%+Disk%%+LVM%%+Volume-Gruppen', aixvg_short => i18n_std('cmdout','lsvg'), aixvg_long => '', aixvg1 => 'Unix%%+Disk%%+LVM%%+Volume-Gruppen%%+%s', #aixvg_short aixvg1_long => '', aixlv => 'Unix%%+Disk%%+LVM%%+Logical Volumes%%+%s', # aixlv_short not used aixlv_long => '', aixoverview => 'Unix%%+Disk%%+LVM%%+Überblick', aixoverview_short=> '', aixoverview_long=> 'Alle LVs, Spiegel, Filesysteme, Seriennummern', # aix overview headlines aixovLV => 'LV', aixovLP => 'LP', aixovPP => 'PP', aixovVG => 'VG', aixovTYPE => 'Typ', aixovFS => 'FS', aixovNAME => 'Name(%s)', aixovSERIAL => 'Seriennr(%s)', aixovSIZE => 'Größ(%s)', aixovPP2 => 'PP(%s)', hplvm => 'Unix%%+Disk%%+LVM%%+Volume-Gruppen, PVs, LVs', hplvm_short => i18n_std('cmdout','vgdisplay -v'), hplvm_long => '', sunV => 'Unix%%+Disk%%+Software Raid%%+Version', sunV_short => i18n_std('cmdout','pkginfo -l SUNWmd'), sunV_long => '', metastat => 'Unix%%+Disk%%+Software Raid%%+metastat', metastat_short => i18n_std('cmdout','metastat'), metastat_long => '', metadb => 'Unix%%+Disk%%+Software Raid%%+metadb', metadb_short => i18n_std('cmdout','metadb'), metadb_long => 'Wo liegen IHRE RAID-Verwaltungs-Daten ?', md => 'Unix%%+Disk%%+Software Raid%%+Zustand', md_short => i18n_std('filecontent','/proc/mdtab'), md_long => 'Welcher RAID-Typ, welche Partitionen,...', raidtab => 'Unix%%+Disk%%+Software Raid%%+Konfiguration', raidtab_short => i18n_std('filecontent','/etc/raidtab'), raidtab_long => '', linpv => 'Unix%%+Disk%%+LVM%%+Physical Volumes', linpv_short => i18n_std('cmdout','pvscan -vv'), linpv_long => '', linvg => 'Unix%%+Disk%%+LVM%%+Volume-Gruppen and Logical Volumes', linvg_short => i18n_std('cmdout','vgdisplay -v'), linvg_long => '', fstab => 'Unix%%+Disk%%+Filesystems%%+konfigurierte Filesysteme', fstab_short => i18n_std('filecontent','/etc/fstab'), fstab_long => 'Welche Filesysteme können auf diesem '. 'System gemountet werden ?', mount => 'Unix%%+Disk%%+Filesystems%%+Gemountete Filesysteme', mount_short => i18n_std('cmdout','mount'), mount_long => "konfiguriert and gemountet ist NICHT das gleiche...", filesystems => 'Unix%%+Disk%%+Filesystems%%+konfigurierte Filesysteme', filesystems_short=> i18n_std('filecontent','/etc/filesystems'), filesystems_long =>'Welche Filesysteme können auf diesem '. 'System gemountet werden ?', sbtab => 'Unix%%+Disk%%+Filesystems%%+Redundante Superblöcke', sbtab_short => i18n_std('filecontent','/etc/sbtab'), sbtab_long => '', vfstab => 'Unix%%+Disk%%+Filesystems%%+konfigurierte Filesysteme', vfstab_short => i18n_std('filecontent','/etc/vfstab'), vfstab_long => 'Welche Filesysteme können auf diesem '. 'System gemountet werden ?', mounttab => 'Unix%%+Disk%%+Filesystems%%+Gemountete Filesysteme', mounttab_short => i18n_std('filecontent','/etc/mnttab'), mounttab_long => "konfiguriert and gemountet ist NICHT das gleiche...", unsupported_fs => "Für dieses Betriebssystem unterstützt ". "ServDoc (noch) nicht die Festplattenkonfiguration.", df1 => 'Unix%%+Disk%%+Filesystems%%+Gemountete Filesysteme und Grösse', # df1_short not used df1_long => "Welche Filesysteme sind z.Zt. gemountet und wie ". "gross sind diese ?", df2 => 'Unix%%+Disk%%+Filesystems%%+Gemountete Filesysteme und Auslastung', # df2_short not used df2_long => "Welche Filesysteme sind z.Zt gemountet, wie ". "gross und mit welcher Auslastung ?", linswap => 'Unix%%+Disk%%+Swapspace', linswap_short => i18n_std('cmdout','swapon -s'), linswap_long => 'Wieviel Swap/Paging Space haben Sie wo ?', aixps => 'Unix%%+Disk%%+Paging Space', aixps_short => i18n_std('cmdout','lsps -a'), aixps_long => 'Wieviel Swap/Paging Space haben Sie wo ?', hp_ps => 'Unix%%+Disk%%+Paging Space', hp_ps_short => i18n_std('cmdout','swapinfo'), hp_ps_long => 'Wieviel Swap/Paging Space haben Sie wo ?', sunswap => 'Unix%%+Disk%%+Swapspace', sunswap_short => i18n_std('cmdout','swap -l'), sunswap_long => 'Wieviel Swap/Paging Space haben Sie wo ?', unsupported_swap=> "Für dieses Betriebssystem unterstützt ". "ServDoc (noch) nicht die SWAP-Konfiguration.", ); debug( 9, i18n_std('running',$0)); #---------------------------------------------------------------------- # All my hdisks my @hdisk; ## Disk Hardware, maybe controller hardware if ( $OSNAME =~ /linux/ ) { ### Disk Hardware Linux my $IDEDIR = "/proc/ide"; if ( -e $IDEDIR ) { # IDE hardware: # /proc/ide: # drivers: driver version numbers # hdx: Link to the disk-directory # idex: Controller directory # One file (eg via|piix|svwks) for the controller chip # hdx/(capacity|model|geometry) data for that disk report_i18n('file','ide','/proc/ide/drivers'); my @idefiles = listdir($IDEDIR); # ls /proc/ide | grep -v '^hd' | grep -v drivers | grep -v '^ide'; foreach my $chipset ( grep { !/$IDEDIR\/hd/ } grep { !/$IDEDIR\/drivers/ } grep { !/$IDEDIR\/ide/ } @idefiles ) { report_file(i18n_mesg('idechip'),i18n_std('filecontent',$chipset), i18n_mesg('idechip_long'),$chipset); } foreach my $disk ( grep { /$IDEDIR\/hd/ } @idefiles ) { report_file(i18n_mesg('idedisk',$disk), i18n_std('filecontent',"$disk/model"), i18n_mesg('idedisk_long'), "$disk/model"); my $media = readfile("$disk/media"); my $mediatype = "unknown mediatype"; if ( $media =~ /cdrom/ ) { $mediatype = "CDROM/DVD"; } if ( $media =~ /disk/ ) { $mediatype = "Harddisk"; my $hdisk = $disk; $hdisk =~ s/$IDEDIR\///; push @hdisk, $hdisk; } report_string(i18n_mesg('idemedia',$disk), i18n_std('filecontent',"$disk/media"), i18n_mesg('idemedia_long'), $mediatype); # capacity and geometry are only for harddisk useful. if ( $media =~ /disk/ ) { # /proc/ide/hdx/capacity: 512byte-blocks # (s. /usr/src/linux/doc/filesystems/proc.txt) my $capacity = int( readfile("$disk/capacity") / 2 / 1024 / 1024 ); report_string(i18n_mesg('idecap',$disk), i18n_std('filecontent', "$disk/capacity"), i18n_mesg('idecap_long'), "$capacity GByte"); report_file(i18n_mesg('idegeo',$disk), i18n_std('filecontent',"$disk/geometry"), i18n_mesg('idegeo_long'), "$disk/geometry"); } } } # (-e $IDEDIR) my $SCSIDIR = "/proc/scsi"; if ( -e $SCSIDIR ) { # SCSI: # /proc/scsi/scsi: All disks # /proc/scsi/<ctrl>/: controller descriptions report_i18n('file','scsidev',"$SCSIDIR/scsi"); # FIXME: I can't describe the controllers.! # Vermutlich (UH, 23.02.04): # scsi/<dir>/x (Kanäle) # for i in scsi/*/*; do cat $i; done } # Sonstige RAID-Controller: # cat /proc/driver/cpqarray/* # OSNAME = linux } elsif ( $OSNAME =~ /aix/ ) { ### Disk Hardware AIX report_i18n('cmd','aixdev','lsdev -C | grep disk'); # FIXME: What about lscfg ? # OSNAME = aix } elsif ( $OSNAME =~ /hpux/ ) { ### Disk Hardware HPUX report_i18n('cmd','hpdev','ioscan -C disk',UID=>0); # OSNAME = hpux } elsif ( $OSNAME =~ /solaris/ ) { ### Disk Hardware solaris my $format="format <<EOF\nEOF"; # Ugly, isn't it ? # Maybe we should do something with # open ( "...| ") ? # This call for format doesn't work very good with do_cmd. my $output=`$format`; report_i18n('string','sundev',$output); } else {debug(1,i18n_mesg('unsupported'));} # End of DISK_HW ## PARTITIONS PARTITIONS: { if ( $OSNAME =~ /aix/ ) { last; } # AIX uses no partitions but a LVM if ( $OSNAME =~ /hpux/ ) { last; } # HPUX uses no partitions but a LVM if ( $OSNAME =~ /linux/ ) { ### PARTITIONS linux # you can fdisk only do as root foreach my $disk (@hdisk) { report_cmd( i18n_mesg('part',$disk), i18n_std('cmdout',"fdisk -l /dev/$disk"), i18n_mesg('part_long'), "fdisk -l /dev/$disk", UID => 0 ); } } } ## LVM and RAID LVM_RAID: { if ( $OSNAME =~ /aix/ ) { ### LVM/RAID AIX report_i18n('cmd','aixpv','lspv'); report_i18n('cmd','aixvg','lsvg'); # Fixme: Which VGs are active, which not ? foreach my $vg (split /\n/,do_cmd("lsvg -o")) { report_cmd (i18n_mesg('aixvg1',$vg), i18n_std('cmdout',"lsvg $vg"), i18n_mesg('aixvg1_long'), "lsvg $vg", ); } foreach my $vg (split /\n/,do_cmd("lsvg -o")) { report_cmd (i18n_mesg('aixlv',$vg), i18n_std('cmdout',"lsvg -l $vg"), i18n_mesg('aixlv_long'), "lsvg -l $vg", ); } report_i18n('string', 'aixoverview', array2table(&aixlvm_overview)); } if ( $OSNAME =~ /hpux/ ) { ### LVM/RAID HP/UX report_i18n('cmd','hplvm','vgdisplav -v'); } if ( $OSNAME =~ /solaris/ ) { ### LVM/RAID SOLARIS my $metastat = "/usr/opt/SUNWmd/sbin/metastat"; my $metadb = "/usr/opt/SUNWmd/sbin/metadb"; if ( -x $metastat ){ report_i18n('cmd','sunV','pkginfo -l SUNWmd'); report_i18n('cmd','metastat',$metastat); report_i18n('cmd','metadb',$metadb); } # FIXME: Has anyone a LVM for solaris running ? } if ( $OSNAME =~ /linux/ ) { ### LVM/RAID Linux # First: Software-Raid if ( -e "/proc/mdtab" ) { report_i18n('file','md','/proc/mdtab'); } if ( -e "/etc/raidtab" ) { report_i18n('file','raidtab','/etc/raidtab'); } # Second: LVM if ( -e "/proc/lvm" ) { report_i18n('cmd','linpv','pvscan -vv',UID=>0); report_i18n('cmd','linvg','vgdisplay -v',UID=>0); } } } ## FILESYSTEMS FILESYSTEMS: { if ( $OSNAME =~ /linux/ ) { ### Filesystems Linux report_i18n('file','fstab','/etc/fstab'); report_i18n('cmd','mount','mount'); } elsif ( $OSNAME =~ /aix/ ) { ### Filesystems AIX report_i18n('file','filesystems','/etc/filesystems'); report_i18n('cmd','mount','mount'); } elsif ( $OSNAME =~ /hpux/ ) { ### Filesystems HP/UX report_i18n('file','fstab','/etc/fstab'); report_i18n('cmd','mount','mount'); report_i18n('file','sbtab','/etc/sbtab'); } elsif ( $OSNAME =~ /solaris/ ) { ### Filesystems Solaris report_i18n('file','vfstab','/etc/vfstab'); report_i18n('file','mounttab','/etc/mnttab'); } else { debug( 1,i18n_mesg('unsupported_fs')); } ### df: Filesystems and Sizes my $DF = 'df -k'; $DF = 'bdf' if ( $OSNAME =~ /hpux/ ); $DF = 'df -kt' if ( $OSNAME =~ /aix/ ); my ($mountpoint,$total,$used)=(5,1,2); my $multiline = 0; my $oldline = 0; my $counter = 1; # First output: Just Mountpoint and total KB # Second Output, Mountpoint, total, used, used percentage my @DFOUT1; my @DFOUT2; @{$DFOUT1[0]}=('Mountpoint','Total'); @{$DFOUT2[0]}=('Mountpoint','Total','Used','Used (%)'); foreach (`$DF`) { chomp; /Filesystem/ and next; # cut Heading /Dateisystem/ and next; # cut Heading (AIX german) /proc/ and next; # No /proc-FS (AIX, Solaris) s/^\s*//; # delete whitespace at linestart # sometimes, df does multiline output. if ($multiline) { $_=$oldline." ".$_; $multiline=0}; my @dummy=split; if ($#dummy<2 ) { $oldline=$_; $multiline=1;next; }; my @fields; if ((@fields=split/\s+/) > 1) { @{$DFOUT1[$counter]}=($fields[$mountpoint],byte2hrn($fields[$total],'K')); @{$DFOUT2[$counter]}=($fields[$mountpoint],byte2hrn($fields[$total],'K'), byte2hrn($fields[$used],'K'), sprintf("%i", ($fields[$total] == 0) ? 0: $fields[$used]/$fields[$total]*100)); } $counter++; } report_string( i18n_mesg('df1'), i18n_std('cmdout',$DF), i18n_mesg('df1_long'), array2table(@DFOUT1) ); report_string( i18n_mesg('df2'), i18n_std('cmdout',$DF), i18n_mesg('df2_long'), array2table(@DFOUT2) ); } exit; ## SWAP SWAP: { if ( $OSNAME =~ /linux/ ) { ### SWAP Linux report_i18n('cmd','linswap','/sbin/swapon -s'); } elsif ( $OSNAME =~ /aix/ ) { ### SWAP AIX report_i18n('cmd','aixps','lsps -a'); } elsif ( $OSNAME =~ /hpux/ ) { ### SWAP HPUX report_i18n('cmd','hp_ps','swapinfo', UID=>0); } elsif ( $OSNAME =~ /solaris/ ) { ### SWAP Solaris report_i18n('cmd','sunswap','swap -l'); } else { debug( 1,i18n_mesg('unsupported_swap')); } } exit 0; sub aixlvm_overview { # Data-Format: # $out->{LVNAME}->{LPs} # ->{PPs} # ->{typs} # ->{'DEV'}->[0]->{Name} # ->{bootinfo} # ->{PPs} # ->{serial#.} # ->[1]->... my $out; # # 1. list of all LVs # 1.1 therefor you need a list of all (open) VGs my @lv; my $max_copies=1; foreach (`lsvg -o`) { chomp; my @dummy=map {s/\s.*//g; $_} grep !/LV NAME/, grep !/:/, `lsvg -l $_`; push (@lv,@dummy); } my $counter=0; my $disks; foreach my $lv (@lv) { $counter++; # for every lv get: # LPs, PPs, typ # All hdisk/vpathes # For all hdisk/vpathes: Size (Bootinfo), size (PP), serial my $dummyout=`lslv $lv`; $dummyout =~ m/LPs:\s+(\d+)\s+PPs:\s+(\d+)/x; $out->{$lv}->{LP}=$1; $out->{$lv}->{PP}=$2; $dummyout =~ m/TYPE:\s+([a-zA-Z0-9]+)/x; $out->{$lv}->{TYPE}=$1; $dummyout =~ m/GROUP:\s+(.*)/x; $out->{$lv}->{VG}=$1; $dummyout =~ m/LABEL:\s+(.*)/x; $out->{$lv}->{FS}=$1; # which disks ? my @disks = map {s/\s.*//g; $_} grep !/COPIES/, grep !/$lv/, `lslv -l $lv`; if ($#disks >= $max_copies) {$max_copies=$#disks+1;} for (my $x=0; $x<=$#disks; $x++) { my $hd = $disks[$x]; if (!defined $disks->{$hd}) { $disks->{$hd}->{BOOTINFO} = do_cmd("bootinfo -s $hd"); chomp($disks->{$hd}->{BOOTINFO}); $dummyout = `lspv $hd`; $dummyout =~ m/TOTAL.*PPs:\s*(\d+)/x; $disks->{$hd}->{PP}=$1; # Serial for hdisks: if ($hd =~ m/hdisk/) { $dummyout = `lscfg -vl $hd | grep "Serial Number"`; $dummyout =~ /\.\.\.([^.].*)/; $disks->{$hd}->{SERIAL} = $1||'-'; } elsif ($hd =~ m/vpath/) { $dummyout = `datapath query device | grep "$hd "`; $dummyout =~ m/SERIAL:\s*(.*)/x; if (defined $1) { $disks->{$hd}->{SERIAL} = $1; } else { $dummyout =~ m/^DEV.*?:\s*(\d+)\s*DEVICE/x; $dummyout = `datapath query device $1`; $dummyout =~ m/SERIAL:\s*(.*)/x; $disks->{$hd}->{SERIAL} = $1; } } else { die "unknown disktype $hd\n"; } } $out->{$lv}->{DEV}->[$x]->{NAME}=$hd; $out->{$lv}->{DEV}->[$x]->{BOOTINFO} = $disks->{$hd}->{BOOTINFO}; $out->{$lv}->{DEV}->[$x]->{PP}= $disks->{$hd}->{PP}; $out->{$lv}->{DEV}->[$x]->{SERIAL} = $disks->{$hd}->{SERIAL}; } } ###print Dumper($out); # Do the Output: # 1. LVName # 2-5: LP,PP,VG,TYP # 6: if TYPE =~ jfs , then Filesystem, else "-" # 7-11: Description disk1: # NAME, SERIAL, BOOTINFO (in MB), PP # 12-16: Description Disk2: # NAME, SERIAL, BOOTINFO (in MB), PP # 17- : Description Disk3 my @Output; @{$Output[0]}=(i18n_mesg('aixovLV'), i18n_mesg('aixovLP'), i18n_mesg('aixovPP'), i18n_mesg('aixovVG'), i18n_mesg('aixovTYPE'), i18n_mesg('aixovFS'), i18n_mesg('aixovNAME',1), i18n_mesg('aixovSERIAL',1), i18n_mesg('aixovSIZE',1), i18n_mesg('aixovPP2',1) ); if ($max_copies > 1) { push @{$Output[0]},( i18n_mesg('aixovNAME',2), i18n_mesg('aixovSERIAL',2), i18n_mesg('aixovSIZE',2), i18n_mesg('aixovPP2',2) ); } if ($max_copies > 2) { push @{$Output[0]},( i18n_mesg('aixovNAME',3), i18n_mesg('aixovSERIAL',3), i18n_mesg('aixovSIZE',3), i18n_mesg('aixovPP2',3) ); } my $row = 1; foreach my $lv (keys %$out) { push @{$Output[$row]},$lv; my $lvh=$out->{$lv}; # Details about $lv: push @{$Output[$row]}, ( $lvh->{LP}, $lvh->{PP}, $lvh->{VG}, $lvh->{TYPE}, $lvh->{FS} ); # And now for each disk: foreach my $hd (@{$lvh->{DEV}}) { push @{$Output[$row]}, ( $hd->{NAME}, $hd->{SERIAL}, $hd->{BOOTINFO}, $hd->{PP} ); } $row++; } return @Output; }