#!/local/bin/perl5 -w # sjekkpart looks for disks on the system, and lists all partitions and unused space. # # A report looks like this: # ==== c0t0d0 ===== 2028 MB, SUN2.1G, F&W SCSI # c0t0d0s0 256 MB 16% [1998-05-09] / # c0t0d0s1 748 MB [ never ] swap # c0t0d0s6 1024 MB 47% [1998-05-09] /usr # # The first line contains device name, disc size, disc name and the # type of SCSI controller. (The last two are only available on Solaris.) # # The other lines are device name, partition size, %full (if mounted), # date of last backup and local mount point. There may be a "G" to # denote an exported disc. # # Handles SunOS 4.x, Solaris 2.x, Irix and Ultrix 4. # # Todo: Handle dumpdates from xfsdump on Irix. # Get model of disc drive on Irix (get it from fx) # Parse automount NIS map (only checks auto_direct) # Parse /etc/exports and /etc/dfs/sharetab. # # Written by Kjetil T. Homme 2000-01-04 # Spread freely, but please send me enhancements. # We need to find the other modules. Should be in same directory as # this file. $dir = $0; $dir =~ s,/[^/]+$,,; push (@INC, $dir); require 'sjekkpart.pm'; # Shut up perl -w: %dumpdate_bypart = (); %cyls_bydisc= (); &sjekkpart::run ("fstab"); &sjekkpart::run ("dumpdates"); &sjekkpart::run ("discinfo"); &read_yp; foreach $disc (sort keys %part_bydisc) { $short = $disc; $short =~ s,.*/,,; printf("\n==== %s ===== %d MB", $short, $cyls_bydisc{$disc} * $cylsize_bydisc{$disc}); if (defined $description{$disc}) { print ", ", $description{$disc}; } print "\n"; for $slice (sort $part_bydisc{$disc}->list()) { $part = &sjekkpart::partname ($disc, $slice); $mount = $path_bypart{$part}; $full_percentage = &sjekkpart::diskfree ($mount, $part); $date = $dumpdate_bypart{$part}; $date = " never " unless defined $date; $date = substr ($date, 0, 10); printf("%-10s %6d MB %4s [%10s] %1s %s\n", &sjekkpart::partname ($short, $slice), $part_bydisc{$disc}->size($slice) * $cylsize_bydisc{$disc}, $full_percentage, $date, (defined $is_global{$path_bypart{$part}}) ? "G" : "", $mount); } $holes = $part_bydisc{$disc}->complement(); for (sort $holes->list()) { printf("%-10s %6d MB %10s %1s %s (%d..%d)\n", $short, $holes->size($_) * $cylsize_bydisc{$disc}, "", "", "UNUSED", $holes->start($_), $holes->start($_) + $holes->size($_)); } $overlap = $part_bydisc{$disc}->overlap(); for (sort $overlap->list()) { printf("%-10s %6d MB %10s %1s %s (%d..%d)\n", $short, $overlap->size($_) * $cylsize_bydisc{$disc}, "", "", "OVERLAP", $overlap->start($_), $overlap->start($_) + $overlap->size($_)); } } # Parse the "&" in automount maps, return local mount point. sub mount_point { local ($top, $dir, $mount) = @_; # Remove the hostname part $mount =~ s/[^:]*://; # Concat to get the global mount point $top .= "/" . $dir if $dir ne ""; return $mount eq "&" ? $top : $mount; } sub read_yp { local ($hostname, @a, $i); open (YP, "ypcat -k auto_direct |") || return; $hostname = `uname -n`; chop ($hostname); $hostname =~ s,\..*,,; while () { # Remove mount options s/\s+-\S+//g; next unless /$hostname:/; chop; @a = split(/\s+/); if ($#a < 2) { # A simple mount point. $is_global{&mount_point($a[0], "", $a[1])} = 1; } else { # Hierarchical mount point. $i = 0; do { $i += 2; next unless $a[$i] =~ /^$hostname:/; $is_global{&mount_point($a[0], $a[$i-1], $a[$i])} = 1; } while ($i < $#a); } } close (YP); }