#/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
[email protected] 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");
}