#!/usr/bin/perl # Read all the configuration files and check that all filesystems # are either backed up in both full and incremental dumps or # listed as exceptions. BEGIN { $etc= '/etc/backup'; require "$etc/settings.pl"; require 'backuplib.pl'; } $|=1; open X,'last-tape' or die $!; chomp($tape= ); close X or die $!; while (!defined $tapedone{$tape}) { open X,"$etc/tape.$tape" or die "$tape $!"; $fsg=''; $next=''; for (;;) { $_= or die $1; chomp; s/\s*$//; last if m/^end$/; next unless m/\S/; next if m/^\#/; if (m/^filesystems (\w+)$/) { $fsg= $1; } elsif (m/^next (\w+)$/) { $next=$1; } else { die "$tape $_ ?"; } } length $fsg or die "$tape $!"; length $next or die "$tape $!"; push @{$fsgdone{$fsg}}, $tape; $tapedone{$tape}=1; $tape= $next; } for $fsg (sort keys %fsgdone) { print "filesystem group $fsg: ".join(' ',@{$fsgdone{$fsg}}).":\n "; @fsys= (); readfsys($fsg); for $tf (@fsys) { parsefsys(); $pstr= $prefix ne '' ? "$prefix:$atf" : $atf; &e("dumped twice ($backed{$pstr}, $fsg): $pstr") if defined $backed{$pstr}; $backed{$pstr}= $fsg; print " $pstr"; } print "\n"; } print "incremental group:\n "; @fsys= (); readfsys('all'); for $tf (@fsys) { parsefsys(); $pstr= $prefix ne '' ? "$prefix:$atf" : $atf; $incrd{$pstr}= $fsg; print " $pstr"; } print "\n"; for $pfx ('', sort keys %prefix) { $rstr= length($pfx) ? $prefix{$pfx}.' ' : ''; $dfstr= exists($prefixdf{$pfx}) ? $prefixdf{$pfx} : 'df --no-sync -xiso9660 -xnfs -xproc'; $cmd= "$rstr $dfstr"; open X, "$cmd |" or die $!; $_= ; m/^Filesystem/ or die "$cmd => $_ ?"; $ppstr= length($pfx) ? $pfx : ''; $pstr= length($pfx) ? "$pfx:" : ''; print "mount points: $ppstr:"; while () { chomp; next if m,^procfs\s,; m,^/dev/(\S+)\s.*\s(/\S*)\s*$, or die "$_ ?"; ($dev,$mp) = ($1,$2); $mounted{"$pstr$mp"}="$pstr$dev"; print " $1-$2"; if (defined($backto= $backed{"$pstr$mp"})) { if (m,^/dev/\S+\s+\d+\s+(\d+)\s,) { $usedkb{$backto} += $1; } else { $usedkb{$backto} += 0; $unkkb{$backto} .= " + $pstr$mp"; } } } print "\n"; $!=0; close(X); $? and die "$? $!"; } foreach $fsg (keys %usedkb) { print "filesystem group $fsg: $usedkb{$fsg} 1K-blocks$unkkb{$fsg}\n"; } # We check that all mounted filesystems are dumped and all # filesystems to be dumped are mounted. The expected-diffs # config file allows us to make exceptions. # eg: # #expect disk2 to be mounted but not dumped # !/disk2 # # CD may or may not be mounted but should not be dumped in either case # ?/cdrom open Z,"$etc/expected-diffs" or die $!; for (;;) { $_= or die; chomp; s/\s*$//; last if m/^end$/; next unless m/^\S/; next if m/^\#/; if (s/^\?//) { print "non-permanent filesystem expected not to be dumped: $_\n"; if (defined($mounted{$_})) { delete $mounted{$_}; } } elsif (s/^\!//) { &e("expected not to be dumped, but not a mount point: $_") unless defined($mounted{$_}); print "filesystem expected not to be dumped: $_\n"; delete $mounted{$_}; } else { &e("non-filesystem expected to be dumped is mounted: $_ on $mounted{$_}") if defined($mounted{$_}); $mounted{$_}= 'expected-diffs'; print "non-filesystem expected to be dumped: $_\n"; } } for $fs (sort keys %backed) { length($mounted{$fs}) || &e("dumped ($backed{$fs}), not a mount point: $fs"); } for $fs (sort keys %incrd) { length($mounted{$fs}) || &e("increm'd ($incrd{$fs}), not a mount point: $fs"); } for $fs (sort keys %mounted) { length($backed{$fs}) || &e("mount point ($mounted{$fs}), not dumped: $fs"); } for $fs (sort keys %mounted) { length($incrd{$fs}) || &e("mount point ($mounted{$fs}), not increm'd: $fs"); } $emsg.= "configuration ok\n" unless $e; print STDERR $emsg; exit($e); sub e { $emsg.="** @_\n"; $e=1; }