#/usr/local/bin/perl # # @(#) backup 22-Jul-91 # use line in crontab like this : # 0 22 * * * /usr/etc/sysadm/backup >/dev/null 2>&1 # or call directly using e.g. backup -d thurs # # RAN 26-Jan-93 remove surf (sob, sob) # RAN 12-Sep-92 allow incremental backup of one machine to be split # RAN 10-Sep-92 allow full backup of one machine to be split # IAN 09-Sep-92 put in /techs, remove /news from brimstone # RAN 24-Jul-92 remove ariel # RAN 23-May-92 put hostname into mail subject line # RAN 09-May-92 put hostname into report line # RAN 06-May-92 change Tuesday so fairy doesn't run out of tape # RAN 18-Feb-92 move fairy to different day (Tuesday) # RAN 17-Feb-92 add failure lines to summary # RAN 29-Jan-92 use backup@brimstone:/dev/nrst1 to remove security hole # RAN 09-Jan-92 modified to change $0 during run # RAN 31-Dec-91 modified summary, added filename to report # RAN 31-Dec-91 changed dump parameters # RAN 31-Dec-91 added catching of signals # RAN 26-Dec-91 added summary # RAN 26-Dec-91 added saving of backuplogs to directory # RAN 31-Oct-91 ariel had /usr/local/course removed. # RAN 08-Oct-91 fairy added, brimstone has incremental every day # Copyright (C) Richard Nuttall richard@pipex.net All rights reserved. # You may use this and change it so long as the copyright message stays require "abbrev.pl"; require "getopts.pl"; require "helpers.pl"; &Getopts('Hd:h:l:r'); $usage = "[-H] [-d day] [-h host] [-l level] [-r]"; %help = ( 'H',"print this help text", 'h',"host to dump from", 'l',"level of dump", 'd',"day of week - defaults to today", 'r',"report to stdout as well as file", ); @days =('monday','tuesday','wednesday','thursday','friday','saturday','sunday','special'); %abbrev = (); &abbrev(*abbrev,@days); &today; $day = $opt_d ? $opt_d : $DAY; $day =~ tr/A-Z/a-z/; $Day = $abbrev{$day}; $level = ($opt_l =~ /\d/) ? $opt_l : 5; $host = $opt_h if $opt_h; # check for number of args &usage() if $opt_H || $#ARGV != -1; die "No such day $day, stopping" unless $host || $Day; $SIG{'INT'} = 'cleanup'; $SIG{'HUP'} = 'cleanup'; $num = 1; # number of file on tape, starts at 1 $who = 'backup'; $tempdir = '/brimstone/home/tmp'; $device = '/dev/nrst1'; $tapehost = 'brimstone'; $tapeuser = 'backup'; $revdate = $YEAR.$MON.$MDAY; &today; $logdir = "/home/backuplogs"; $logbase = "$logdir/$revdate"; $uniq = 1; $logfile = "$logbase.$uniq"; while( -f $logfile) { $uniq++; $logfile = "$logbase.$uniq"; } $filew = length($logfile); $hostw = length($tapehost); # all hosts and the partitions you want to backup %hosts = ( 'brimstone','/home /usr /export /var / /unipalm /archive /techs', 'flash','/ /usr /src /src2 /oldroot /oldroot/usr', 'bold','/ /usr /files', 'unipalm','/ /usr /home', 'fairy','/ /usr /home /src /src2', ); # if you need to split all file systems on a host among several nights %splits = ( 'brimstone1','/home /usr /export /var / /unipalm', 'brimstone2','/archive /techs', 'fairy1','/ /usr /home /src', 'fairy2','/src2', ); # list of all hosts for convenience @hosts = ( 'brimstone', 'flash', 'bold', 'wisk', 'fairy', #'ariel', 'unipalm', ); ############################# # Main program starts here ############################# $startday = $TODAY; &report("Backup log for $TODAY from [$tapehost]"); &report("Saved in file $logfile"); die "Cannot access backup device [$device] on [$tapehost], stopping" unless &mtstat(); &rewind(); if ($host) { &report("Manual backup of [$host], level [$level]"); $pstype = "[manual]"; &dump($host,$level) if &ping($host); } else { &report("Manually actioned Backup") if $opt_d; &report("Backup for [$Day]"); $pstype = "[$Day]"; eval("&$Day()"); } $normal++; &cleanup; ############################ # subroutines below here ############################ # Day by day backups # Use '&incremental' and '&full' with hosts from @hosts sub monday { &incremental('brimstone'); &full('flash','bold'); } sub tuesday { &incremental('brimstone'); &full('fairy1'); } sub wednesday { &incremental('brimstone2'); &full('brimstone1'); } sub thursday { &incremental('brimstone'); &full('unipalm'); &full('fairy2'); } sub friday { &incremental('brimstone1'); &full('brimstone2'); } # used if not the default daily backup sub special { &report("Special manual for [@hosts]"); &check(@hosts); &report("End of Backup log for $startday"); system("/usr/ucb/Mail -s \"Backup log of [$tapehost] for $startday\" $who < $logfile"); unlink($logfile); exit 0; } # support functions sub incremental { local($host); foreach $host (@_) { local($realhost) = $host; chop($realhost = $host) if $splits{$host}; next if ( ! &ping($realhost) ); &dump($host,5); } } sub check { local($host,$ret); foreach $host (@_) { $ret = &ping($host); &report("Ping of [$host] returns [$ret]"); } } sub full { local($host); foreach $host (@_) { local($realhost) = $host; chop($realhost = $host) if $splits{$host}; next if ( ! &ping($realhost) ); &dump($host,0); } } sub dump { local($Host,$level) = @_; local($command); local($fs); local($fss); local($host) = $Host; if ($splits{$Host}) { chop($host = $Host); $fss = $splits{$Host}; } else { $fss = $hosts{$host}; } local(@fs) = split(' ',$fss); local($ret); &report("\nWill dump [$fss] from [$host]"); foreach $fs (@fs) { if ($host eq $tapehost) { $command = "/usr/etc/dump $level" . "ucbsdf 56 5190 41000000 $device $fs"; } else { $command = "/usr/ucb/rsh $host /usr/etc/rdump $level" . "ucbsdf 56 5190 41000000 ${tapeuser}@$tapehost:$device $fs"; } &report($command); push(@list, sprintf("$TODAY %3.0d $level $logfile %${hostw}s $fs",$num,$host)); $0 = "BACKUP $pstype $TODAY ${host}:$fs"; $num++; $ret = system("$command >> $logfile 2>&1"); push(@list,"$TODAY Command returns [$ret] for above action") if $ret; &report("Command returns [$ret]\n") if $ret; } &report(''); } sub ping { local($host) = @_; $_ = `/usr/etc/ping $host 1`; return 1 if /is alive$/; if (/^no answer from/) { &report("\nCannot ping [$host], skipping this host\n\n"); push(@list,"$TODAY Cannot ping [$host], skipping this host"); return 0; } &report("Strange result [$_] from ping [$host], skipping this host\n"); return 0; } sub mtstat { return ! system("mt -f $device status > /dev/null 2>&1"); } sub rewind { $ret = system("mt -f $device rewind > /dev/null 2>&1"); &fatal("Tape rewind command failed, error code [$ret]") if $ret; &report("Rewinding tape") unless $ret; } sub eject { &rewind(); $ret = system("mt -f $device offline > /dev/null 2>&1"); &report("Tape eject command failed, error code [$ret]\n") if $ret; &report("Ejecting tape\n") unless $ret; } sub fatal { open(LOG,">> $logfile") || die "Cannot open [logfile], stopping"; print(LOG @_,"\n"); print(LOG "\nFATAL ERROR, DUMP ABORTED\n"); close(LOG); exit(1); } sub report { open(LOG,">> $logfile"); print(LOG @_,"\n"); close(LOG); print(@_,"\n") if $opt_r; } sub cleanup { $0 = "BACKUP $pstype $TODAY cleaning up"; &report("\nAbnormal exit, cleaning up") unless $normal; &eject(); &today; &report("Backup for [$Day] finished at $TIME on $TODAY"); &report("\nSummary follows :"); &report(sprintf("\nDate Num Lev %-${filew}s %${hostw}s Filesystem\n", "File","Host")); foreach (@list) { &report($_); } system("/usr/ucb/Mail -s \"Backup log of [$tapehost] for $startday\" $who < $logfile"); }