home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.perl
- Path: sparky!uunet!ukma!wupost!zaphod.mps.ohio-state.edu!cs.utexas.edu!bcm!rice!rsnow
- From: rsnow@rice.edu (Robert Snow)
- Subject: Perl network backup script for SUN/Exabyte
- Message-ID: <rsnow.721097201@proton>
- Summary: Perl network backup script for SUN/Exabyte
- Keywords: Exabyte backup sun network
- Sender: news@rice.edu (News)
- Organization: Rice University
- Date: Sat, 7 Nov 1992 00:46:41 GMT
- Lines: 399
-
- The following is a script for backing up all the drives on a network onto
- an Exabyte 8mm (8500) SCSI drive.
-
- I have seen it run on SGI also.
-
- It prints out labels also.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: bcs.pl
- # Wrapped by rsnow@proton on Fri Nov 6 18:44:43 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'bcs.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bcs.pl'\"
- else
- echo shar: Extracting \"'bcs.pl'\" \(11264 characters\)
- sed "s/^X//" >'bcs.pl' <<'END_OF_FILE'
- X#!/usr/local/bin/perl
- X#
- X# backup all listed disks to the exabyte.
- X#
- X# original was SGI version ported to Sun by Rob Snow.
- X# mail suggestions or problems to:
- X#
- X# Rob Snow
- X# rsnow@proton.rice.edu
- X#
- X#
- X# comand line options used to overide default options
- X# -o sysop - uid of system operator
- X# -m kbytes - size of tape in kbytes of tape
- X# -d host - remote host.
- X# -L logfile - name of logfile.
- X# -p - print a label using data in $logfile starting w/ partition $recover
- X# -r partition - restart backup w/ partition partition. this option assumes that
- X# the preceding partitions in the list have already been backed up
- X# on the current tape. the script will automatically adjust the
- X# the $sum variable. the user need not calculate the num of kbytes
- X# on the tape.
- X# -s kbytes - set starting number of kbytes used on tape. if sum is specified, amount
- X# of data on the tape is _NOT_ calculated.
- X# -l level - dump level
- X# -P printer - over ride the default printer for lpr.
- X# -D - turn on debugging
- X# -t tapenum - starting tape number
- X# -a - append to current tape.
- X
- X#
- X# user selectable parameters. can also be set via comand line options
- X$sysop = 'rob'; # uid of person to receive mail
- X$maxkbytes = 4.8*1024*1024; # max size of tape
- X$dhost = 'oasis'; # remote host containing the tape drive
- X$rawdev = '/dev/nrst1';
- X$dump = '/usr/etc/rdump'; # dump program to use
- X$logfile = '/home/rob/tmp/backup.log'; # name of logfile
- X$recover = ""; # if not null continue backup starting w/ partition name = $recover
- X$sum = -1; # number of kbytes used so far.
- X$level = 0; # dump level
- X$printer = "ps"; # printer for lpr.
- X$debug = 0; # 1 == debug mode.
- X$label = 0; # 1 == print a label using $logfile starting w/ partition $recover
- X # no other action is taken.
- X$tape = 1; # current tape number
- X$append = 0; # true if you want to seek to the end of the tape before starting
- X
- X#
- X# some constants
- X$USAGE = "Usage: $argv[0] [-o uid][-m tapelen][-d host:dev][-L log][-r part][-s len][-l level][-P printer][-t num][-paD]";
- X
- X# to add a new partition to the list
- X# a) add partition name and machine to the list
- X# b) edit /.rhosts on remote machine to add the name of the machine
- X# running this scrip.
- X# c) add remote machine to /.rhosts table on machine containing the
- X# tape drive.
- X#
- X@partitions = (
- X# 'partition', 'machine', bytes/block
- X# backup partitions
- X '/', 'oasis', 512,
- X '/usr', 'oasis', 512,
- X '/home', 'oasis', 512,
- X '/trep3', 'oasis', 512,
- X '/', 'sweetie', 512,
- X '/usr', 'sweetie', 512,
- X '/trep1', 'sweetie', 512,
- X '/trep2', 'sweetie', 512,
- X);
- X
- Xdo ParseArgs();
- X
- Xif ( $label == 1 ) {
- X do PrintLabel(do GetPartName($recover), do GetHostName($recover), $level);
- X exit(0);
- X}
- X
- Xdo CheckMachines();
- X
- Xif ( $recover eq "" ) {
- X @oldlogfile[0] = $logfile;
- X @oldlogfile[1] = `date +'%m%d%y'`;
- X chop @oldlogfile[1];
- X rename($logfile, join('',@oldlogfile));
- X $sum = 0;
- X} elsif ( $sum != -1 ) {
- X local ($host) = do GetHostName($recover);
- X local ($part) = do GetPartName($recover);
- X for ( $i = 0; $i < $#partitions; $i += 3 ) {
- X if ( $host eq $partitions[$i+1] && $part eq $partitions[$i] ) {
- X last;
- X }
- X }
- X $startindex = $i;
- X} elsif ( $sum == -1 && -s $logfile ) {
- X # determine num kbytes on tape if recovering and sum not specified by the user
- X local ($host) = do GetHostName($recover);
- X local ($part) = do GetPartName($recover);
- X local ($numFilePerTape) = 0;
- X for ( $i = 0; $i < $#partitions; $i += 3 ) {
- X
- X # get current partition size from the log file
- X $size = do GetPartSize($partitions[$i], $partitions[$i+1],
- X $partitions[$i+2], $level);
- X
- X $sum += $size;
- X $numFilesPerTape += 1;
- Xprint STDERR "sum = $sum \n";
- X if ( $sum > ($maxkbytes) ) {
- X $numFilesPerTape = 0;
- X $sum = $size;
- X $tape += 1;
- X }
- X if ( $partitions[$i] eq $part && $partitions[$i+1] eq $host) {
- X $sum -= $size;
- X last;
- X }
- X }
- X $startindex = $i - 3;
- X # advance tape to new position
- X do PrintLog ("rsh $dhost mt -f $rawdev rew\n");
- X do PrintLog ("rsh $dhost mt -f $rawdev fsf $numFilesPerTape\n");
- X if ( $debug == 0 ) {
- X system ("rsh $dhost mt -f $rawdev rew");
- X system ("rsh $dhost mt -f $rawdev fsf $numFilesPerTape");
- X }
- X} elsif ( $sum == -1 ) {
- X do PrintMailLog ("Backup aborted, Could not determine amount of data on tape. Use -s options");
- X do PrintLog("\n");
- X die ("Backup aborted, Could not determine amount of data on tape. Use -s options");
- X}
- X
- Xif ( $append == 1 ) {
- X do PrintLog("seeking to end of tape. note that sum may be in correct.\n");
- X do PrintLog("rsh $dhost mt -f $rawdev feom\n");
- X system("rsh $dhost mt -f $rawdev feom");
- X}
- X
- Xdo OpenLpr("");
- X
- X$firstlevel = sprintf("%dubsdf 1024 6000 108000", $level);
- X#$firstlevel = sprintf("%dubsf 6000 108000", $level);
- Xfor ( $i = $startindex; $i < $#partitions; $i += 3 ) {
- X
- X # make a guess at the partition size so that we dont overflow the tape.
- X # df gives us the MAX possible size for the partitions.
- X do PrintLog ("rsh $partitions[$i+1] df | grep $partitions[$i]\n");
- X $tmp = `rsh $partitions[$i+1] df | grep $partitions[$i]`;
- X if ( $? ) {
- X do PrintLog ("$partitions[$i+1] is down, skiping partition $partitions[$i]\n");
- X next;
- X }
- X @tmp1 = split(/ \ */,$tmp);
- X if ( ($sum + (@tmp1[2])) > ($maxkbytes) ) {
- X do CloseLpr ("");
- X do OpenLpr("");
- X do PrintLog ("rsh $dhost mt -f $rawdev rewoffl\n");
- X if ( $debug == 0 ) {
- X system("rsh $dhost mt -f $rawdev rew");
- X system("rsh $dhost mt -f $rawdev offline");
- X }
- X do PrintMailLog ("insert new tape, CR when done");
- X do PrintLog ("\n");
- X getc;
- X $sum = 0;
- X }
- X do PrintLog ("rsh $partitions[$i+1] $dump $firstlevel $dhost:$rawdev $partitions[$i]\n");
- X if ( $debug == 0 ) {
- X system("(rsh $partitions[$i+1] $dump $firstlevel $dhost:$rawdev $partitions[$i]) 2>&1 | tee -a $logfile");
- X } else {
- X system("(rsh $partitions[$i+1] ls -C $partitions[$i]) 2>&1 | tee -a $logfile");
- X }
- X
- X # get the actual paritions size from the log file and use this value
- X # to update the running sum of bytes on tape.
- X $sum += do PrintPartSize($i, $level);
- X
- X do PrintLog("running sum = $sum \n");
- X}
- Xdo CloseLpr ("");
- Xdo PrintLog ("rsh $dhost mt -f $rawdev rewoffl \n");
- Xif ( $debug == 0 ) {
- X system("rsh $dhost mt -f $rawdev rew");
- X system("rsh $dhost mt -f $rawdev offline");
- X}
- Xdo PrintMailLog ("======= TAPE BACKUP DONE ======= ");
- Xdo PrintLog ("\n");
- X
- Xformat LABEL =
- X@<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<@||||
- X$_offset, $_partition, $_size, $_level
- X.
- X
- Xsub PrintPartSize {
- X local ($partindex, $dumplevel) = @_;
- X local ($size);
- X $size = do GetPartSize($partitions[$partindex],
- X $partitions[$partindex +1],
- X $partitions[$partindex +2],
- X $dumplevel);
- X if ( $size != 0) {
- X $_partition = "$partitions[$partindex+1]:$partitions[$partindex]";
- X $_level = $dumplevel;
- X $_size = $size;
- X write LABEL;
- X $_offset += 1;
- X }
- X $size;
- X}
- X
- Xsub CloseLpr {
- X print LABEL "---------------------------------------\n";
- X print LABEL " $sum\n";
- X close (LABEL);
- X $tape += 1;
- X}
- X
- Xsub OpenLpr {
- X open(LABEL,"| lp -d$printer");
- X $date = `date`;
- X $_offset = 0;
- X print LABEL "Backup: $date";
- X print LABEL "Tape: $tape\n";
- X print LABEL "Machine:Partition Size(KB) Level\n";
- X print LABEL "---------------------------------------\n";
- X}
- X
- X# search thru the log file for the size of the partition named
- X# in the argument.
- Xsub GetPartSize {
- X local ($partition, $host, $BytesPerBlock, $dumplevel) = @_;
- X local ($curhost);
- X local ($size) = 0;
- X local ($curdumplevel);
- X
- X open(LOGFIL,"<$logfile");
- X
- X while ( <LOGFIL> ) {
- X if ( $_ ne "\n" ) {
- X @tmp = split(/ \ */,$_);
- X }
- X
- X if ( $#tmp > 2 && @tmp[0] eq "rsh" ) {
- X $curhost = $tmp[1];
- X }
- X # look for DUMP: Date of this level ? dump ...
- X if ( $#tmp > 3 && @tmp[4] eq "this" ) {
- X $curdumplevel = @tmp[6];
- X }
- X if ( $curdumplevel == $dumplevel && $#tmp > 3 && @tmp[4] eq "($partition)" && $curhost eq $host) {
- X while ( <LOGFIL> ) {
- X if ( $_ ne "\n" ) {
- X @tmp = split(/ \ */,$_);
- X }
- X if ( @tmp[3] eq "blocks" ) {
- X $size = @tmp[2];
- X last;
- X }
- X }
- X }
- X }
- X close(LOGFIL);
- X $size = ($size*$BytesPerBlock)/1024;
- X
- Xprint STDERR "GetPartSize: size of level $dumplevel dump for $host:$partition = $size\n";
- X
- X $size;
- X}
- X
- Xsub PrintMailLog {
- X do PrintLog (@_);
- X system ("echo @_ | mail $sysop");
- X}
- X
- Xsub PrintLog {
- X open(LOGFIL,">>$logfile");
- X print STDERR @_;
- X print LOGFIL @_;
- X close(LOGFIL);
- X}
- X
- Xsub PrintLabel {
- X local ($partition, $host, $dumplevel) = @_;
- X local ($i, $size);
- X local ($sum) = 0;
- X
- X if ( $partition eq "" ) {
- X $i = 0;
- X } else {
- X for ( $i = 0; $i < $#partitions &&
- X ($partitions[$i] ne $partition ||
- X $partitions[$i+1] ne $host); $i += 3 ) {
- X ;
- X }
- X }
- X do OpenLpr();
- X do {
- X $size = do PrintPartSize($i, $level);
- X $sum += $size;
- X $i += 3;
- X } while ( $size && $i < $#partitions);
- X do CloseLpr();
- X}
- X
- Xsub GetName {
- X local ($rpart) = @_;
- X local (@retv);
- X if ( index($rpart, ":") == $[-1 ) {
- X print STDERR "partitions must be specified as \"host:/partition\" \n";
- X exit(1);
- X }
- X @retv = split(':', $rpart);
- X if ( @retv[0] eq "" || @retv[1] eq "" ) {
- X print STDERR "partitions must be specified as \"host:/partition\" \n";
- X exit(1);
- X }
- X @retv;
- X}
- X
- Xsub GetHostName {
- X local ($rpart) = @_;
- X local (@retval) = do GetName($rpart);
- X @retval[0];
- X}
- X
- Xsub GetPartName {
- X local ($rpart) = @_;
- X local (@retval) = do GetName($rpart);
- X @retval[1];
- X}
- X
- Xsub ParseArgs {
- X do 'getopt.pl';
- X do Getopt('omdlrsPLt'); # add only options that have arguments
- X foreach $i ( ('a','p','o','m','d','l','r','s','L','P','D','t') ) { # include _ALL_ arguments here
- X $tmp = eval"\$opt_$i";
- X if ( $tmp ne "" ) {
- X # options w/ aruguments go here.
- X if ( $tmp =~ /-/ ) {
- X die $USAGE;
- X }
- X if ( $i eq 'D' ) {$debug = 1;}
- X if ( $i eq 'a' ) {$append = 1;}
- X if ( $i eq 'o' ) {$sysop = $tmp ;}
- X if ( $i eq 'm' ) {$maxkbytes = $tmp;}
- X if ( $i eq 'd' ) {$dhost = $tmp;}
- X if ( $i eq 'L' ) {$logfile = $tmp;}
- X if ( $i eq 'r' ) {$recover = $tmp;}
- X if ( $i eq 's' ) {$sum = $tmp;}
- X if ( $i eq 'P' ) {$printer = "-P $tmp";}
- X if ( $i eq 'l' ) {$level = $tmp;}
- X if ( $i eq 'p' ) {$label = 1;}
- X if ( $i eq 't' ) {$tape = $tmp;}
- X }
- X }
- X}
- X
- X
- X# make sure that all machines are alive
- Xsub CheckMachines {
- X local ($i, $j, @dead);
- X for ( $i = 1, $j = 0; $i < $#partitions+1; $i += 3 ) {
- X system("/usr/etc/ping -c1 $partitions[$i]");
- X if ( $? ) {
- X $dead[$j++] = $partitions[$i];
- X }
- X }
- X if ( $dead[0] ne "" ) {
- X do PrintMailLog ("Backup aborted, the following systems are dead: @dead");
- X do PrintLog("\n");
- X die ("\n");
- X }
- X}
- X
-
-