home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / perl / 6884 < prev    next >
Encoding:
Text File  |  1992-11-08  |  12.4 KB  |  412 lines

  1. Newsgroups: comp.lang.perl
  2. Path: sparky!uunet!ukma!wupost!zaphod.mps.ohio-state.edu!cs.utexas.edu!bcm!rice!rsnow
  3. From: rsnow@rice.edu (Robert Snow)
  4. Subject: Perl network backup script for SUN/Exabyte
  5. Message-ID: <rsnow.721097201@proton>
  6. Summary: Perl network backup script for SUN/Exabyte
  7. Keywords: Exabyte backup sun network
  8. Sender: news@rice.edu (News)
  9. Organization: Rice University
  10. Date: Sat, 7 Nov 1992 00:46:41 GMT
  11. Lines: 399
  12.  
  13. The following is a script for backing up all the drives on a network onto
  14. an Exabyte 8mm (8500) SCSI drive.
  15.  
  16. I have seen it run on SGI also.
  17.  
  18. It prints out labels also.
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of shell archive."
  27. # Contents:  bcs.pl
  28. # Wrapped by rsnow@proton on Fri Nov  6 18:44:43 1992
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'bcs.pl' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'bcs.pl'\"
  32. else
  33. echo shar: Extracting \"'bcs.pl'\" \(11264 characters\)
  34. sed "s/^X//" >'bcs.pl' <<'END_OF_FILE'
  35. X#!/usr/local/bin/perl 
  36. X#
  37. X# backup all listed disks to the exabyte.
  38. X#
  39. X# original was SGI version ported to Sun by Rob Snow.
  40. X# mail suggestions or problems to:
  41. X# 
  42. X#    Rob Snow
  43. X#    rsnow@proton.rice.edu
  44. X#
  45. X#
  46. X# comand line options used to overide default options
  47. X#   -o sysop        - uid of system operator
  48. X#   -m kbytes       - size of tape in kbytes of tape
  49. X#   -d host         - remote host.
  50. X#   -L logfile      - name of logfile.
  51. X#   -p              - print a label using data in $logfile starting w/ partition $recover
  52. X#   -r partition    - restart backup w/ partition partition.  this option assumes that
  53. X#                     the preceding partitions in the list have already been backed up
  54. X#                     on the current tape.  the script will automatically adjust the
  55. X#                     the $sum variable.  the user need not calculate the num of kbytes
  56. X#                     on the tape.
  57. X#  -s kbytes        - set starting number of kbytes used on tape. if sum is specified, amount
  58. X#                     of data on the tape is _NOT_ calculated.
  59. X#  -l level         - dump level
  60. X#  -P printer       - over ride the default printer for lpr.
  61. X#  -D               - turn on debugging
  62. X#  -t tapenum       - starting tape number
  63. X#  -a               - append to current tape.
  64. X
  65. X# 
  66. X# user selectable parameters. can also be set via comand line options
  67. X$sysop     = 'rob';                # uid of person to receive mail
  68. X$maxkbytes = 4.8*1024*1024;        # max size of tape
  69. X$dhost     = 'oasis';              # remote host containing the tape drive
  70. X$rawdev    = '/dev/nrst1';
  71. X$dump      = '/usr/etc/rdump';          # dump program to use
  72. X$logfile   = '/home/rob/tmp/backup.log';     # name of logfile
  73. X$recover   = "";                    # if not null continue backup starting w/ partition name = $recover
  74. X$sum       = -1;                    # number of kbytes used so far.
  75. X$level     = 0;                     # dump level
  76. X$printer   = "ps";                  # printer for lpr.
  77. X$debug     = 0;                     # 1 == debug mode.
  78. X$label     = 0;                     # 1 == print a label using $logfile starting w/ partition $recover
  79. X                                    # no other action is taken.
  80. X$tape      = 1;                     # current tape number
  81. X$append    = 0;                     # true if you want to seek to the end of the tape before starting
  82. X
  83. X#
  84. X# some constants
  85. 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]";
  86. X
  87. X# to add a new partition to the list
  88. X#   a) add partition name and machine to the list
  89. X#   b) edit /.rhosts on remote machine to add the name of the machine
  90. X#       running this scrip.
  91. X#   c) add remote machine to /.rhosts table on machine containing the
  92. X#       tape drive.
  93. X#
  94. X@partitions = (
  95. X#   'partition',    'machine',   bytes/block
  96. X# backup  partitions
  97. X    '/',        'oasis',           512, 
  98. X    '/usr',     'oasis',           512,
  99. X    '/home',    'oasis',           512,
  100. X    '/trep3',   'oasis',           512,
  101. X    '/',        'sweetie',         512,
  102. X    '/usr',     'sweetie',         512,
  103. X    '/trep1',   'sweetie',         512,
  104. X    '/trep2',   'sweetie',         512,
  105. X);
  106. X
  107. Xdo ParseArgs();
  108. X
  109. Xif ( $label == 1 ) {
  110. X    do PrintLabel(do GetPartName($recover), do GetHostName($recover), $level);
  111. X    exit(0);
  112. X}
  113. X
  114. Xdo CheckMachines();
  115. X
  116. Xif ( $recover eq "" ) {
  117. X    @oldlogfile[0] = $logfile;
  118. X    @oldlogfile[1] = `date +'%m%d%y'`;
  119. X    chop @oldlogfile[1];
  120. X    rename($logfile, join('',@oldlogfile));
  121. X    $sum = 0;
  122. X} elsif ( $sum != -1 ) {
  123. X    local ($host) = do GetHostName($recover);
  124. X    local ($part) = do GetPartName($recover);
  125. X    for ( $i = 0; $i < $#partitions; $i += 3 ) {
  126. X        if ( $host eq $partitions[$i+1] && $part eq $partitions[$i] ) {
  127. X            last;
  128. X        }
  129. X    }
  130. X    $startindex = $i;
  131. X} elsif ( $sum == -1 && -s $logfile )  {
  132. X    # determine num kbytes on tape if recovering and sum not specified by the user
  133. X    local ($host) = do GetHostName($recover);
  134. X    local ($part) = do GetPartName($recover);
  135. X    local ($numFilePerTape) = 0;
  136. X    for ( $i = 0; $i < $#partitions; $i += 3 ) {
  137. X
  138. X        # get current partition size from the log file
  139. X        $size = do GetPartSize($partitions[$i], $partitions[$i+1],
  140. X                               $partitions[$i+2], $level);
  141. X
  142. X        $sum += $size;
  143. X        $numFilesPerTape += 1;
  144. Xprint STDERR "sum = $sum \n";
  145. X        if ( $sum > ($maxkbytes) ) {
  146. X            $numFilesPerTape = 0;
  147. X            $sum = $size;
  148. X            $tape += 1;
  149. X        } 
  150. X        if ( $partitions[$i] eq $part && $partitions[$i+1] eq $host) {
  151. X            $sum -= $size;
  152. X            last;
  153. X        }
  154. X    }
  155. X    $startindex = $i - 3;
  156. X    # advance tape to new position
  157. X    do PrintLog ("rsh $dhost mt -f $rawdev rew\n");
  158. X    do PrintLog ("rsh $dhost mt -f $rawdev fsf $numFilesPerTape\n");
  159. X    if ( $debug == 0 ) {
  160. X        system ("rsh $dhost mt -f $rawdev rew");
  161. X        system ("rsh $dhost mt -f $rawdev fsf $numFilesPerTape");
  162. X    }
  163. X} elsif ( $sum == -1 ) {
  164. X    do PrintMailLog ("Backup aborted, Could not determine amount of data on tape. Use -s options");
  165. X    do PrintLog("\n");
  166. X    die ("Backup aborted, Could not determine amount of data on tape. Use -s options");
  167. X}
  168. X
  169. Xif ( $append == 1 ) {
  170. X    do PrintLog("seeking to end of tape.  note that sum may be in correct.\n");
  171. X    do PrintLog("rsh $dhost mt -f $rawdev feom\n");
  172. X    system("rsh $dhost mt -f $rawdev feom");
  173. X}
  174. X
  175. Xdo OpenLpr("");
  176. X    
  177. X$firstlevel  = sprintf("%dubsdf 1024 6000 108000", $level);
  178. X#$firstlevel  = sprintf("%dubsf 6000 108000", $level);
  179. Xfor ( $i = $startindex; $i < $#partitions; $i += 3 ) {
  180. X
  181. X    # make a guess at the partition size so that we dont overflow the tape.
  182. X    # df gives us the MAX possible size for the partitions.
  183. X    do PrintLog ("rsh $partitions[$i+1] df | grep $partitions[$i]\n");
  184. X    $tmp = `rsh $partitions[$i+1] df | grep $partitions[$i]`;
  185. X    if ( $? ) {
  186. X        do PrintLog ("$partitions[$i+1] is down, skiping partition $partitions[$i]\n");
  187. X        next;
  188. X    }
  189. X    @tmp1 = split(/ \ */,$tmp);
  190. X    if ( ($sum + (@tmp1[2])) > ($maxkbytes) ) {
  191. X        do CloseLpr ("");
  192. X        do OpenLpr("");
  193. X        do PrintLog ("rsh $dhost mt -f $rawdev rewoffl\n");
  194. X        if ( $debug == 0 ) {
  195. X            system("rsh $dhost mt -f $rawdev rew");
  196. X            system("rsh $dhost mt -f $rawdev offline");
  197. X        }
  198. X        do PrintMailLog ("insert new tape, CR when done");
  199. X        do PrintLog ("\n");
  200. X        getc;
  201. X        $sum = 0;
  202. X    } 
  203. X    do PrintLog ("rsh $partitions[$i+1] $dump $firstlevel $dhost:$rawdev $partitions[$i]\n");
  204. X    if ( $debug == 0 ) {
  205. X        system("(rsh $partitions[$i+1] $dump $firstlevel $dhost:$rawdev $partitions[$i]) 2>&1 | tee -a $logfile");
  206. X    } else {
  207. X        system("(rsh $partitions[$i+1] ls -C $partitions[$i]) 2>&1 | tee -a $logfile");
  208. X    }
  209. X
  210. X    # get the actual paritions size from the log file and use this value
  211. X    # to update the running sum of bytes on tape.
  212. X    $sum += do PrintPartSize($i, $level);
  213. X
  214. X    do PrintLog("running sum = $sum \n");
  215. X}
  216. Xdo CloseLpr ("");
  217. Xdo PrintLog ("rsh $dhost mt -f $rawdev rewoffl \n");
  218. Xif ( $debug == 0 ) {
  219. X    system("rsh $dhost mt -f $rawdev rew");
  220. X    system("rsh $dhost mt -f $rawdev offline");
  221. X}
  222. Xdo PrintMailLog ("======= TAPE BACKUP DONE ======= ");
  223. Xdo PrintLog ("\n");
  224. X
  225. Xformat LABEL = 
  226. X@<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<@||||
  227. X$_offset, $_partition, $_size, $_level
  228. X.
  229. X
  230. Xsub PrintPartSize {
  231. X    local ($partindex, $dumplevel)  = @_;
  232. X    local ($size);
  233. X    $size = do GetPartSize($partitions[$partindex], 
  234. X                           $partitions[$partindex +1], 
  235. X                           $partitions[$partindex +2], 
  236. X                           $dumplevel);
  237. X    if ( $size != 0) {
  238. X        $_partition = "$partitions[$partindex+1]:$partitions[$partindex]";
  239. X        $_level = $dumplevel;
  240. X        $_size  = $size;
  241. X        write LABEL;
  242. X        $_offset += 1;
  243. X    }
  244. X    $size;
  245. X}
  246. X
  247. Xsub CloseLpr {
  248. X    print LABEL "---------------------------------------\n";
  249. X    print LABEL "                        $sum\n";
  250. X    close (LABEL);
  251. X    $tape += 1;
  252. X}
  253. X
  254. Xsub OpenLpr {
  255. X    open(LABEL,"| lp -d$printer");
  256. X    $date = `date`;
  257. X    $_offset = 0;
  258. X    print LABEL "Backup: $date";
  259. X    print LABEL "Tape: $tape\n";
  260. X    print LABEL "Machine:Partition       Size(KB)  Level\n";
  261. X    print LABEL "---------------------------------------\n";
  262. X}
  263. X
  264. X# search thru the log file for the size of the partition named
  265. X# in the argument.
  266. Xsub GetPartSize {
  267. X    local ($partition, $host, $BytesPerBlock, $dumplevel) = @_;
  268. X    local ($curhost);
  269. X    local ($size) = 0;
  270. X    local ($curdumplevel);
  271. X
  272. X    open(LOGFIL,"<$logfile");
  273. X
  274. X    while ( <LOGFIL> ) {
  275. X        if ( $_ ne "\n" ) {
  276. X            @tmp = split(/ \ */,$_);
  277. X        }
  278. X
  279. X        if ( $#tmp > 2 && @tmp[0] eq "rsh" ) {
  280. X            $curhost = $tmp[1];
  281. X        }
  282. X        # look for DUMP: Date of this level ? dump ...
  283. X        if ( $#tmp > 3 && @tmp[4] eq "this" ) {
  284. X            $curdumplevel = @tmp[6];
  285. X        }
  286. X        if ( $curdumplevel == $dumplevel && $#tmp > 3 && @tmp[4] eq "($partition)" && $curhost eq $host) {
  287. X            while ( <LOGFIL> ) {
  288. X                if ( $_ ne "\n" ) {
  289. X                    @tmp = split(/ \ */,$_);
  290. X                }
  291. X                if ( @tmp[3] eq "blocks" ) {
  292. X                    $size = @tmp[2];
  293. X                    last;
  294. X                }
  295. X            }
  296. X        }
  297. X    }
  298. X    close(LOGFIL);
  299. X    $size = ($size*$BytesPerBlock)/1024;
  300. X
  301. Xprint STDERR "GetPartSize: size of level $dumplevel dump for $host:$partition = $size\n";
  302. X
  303. X    $size;
  304. X}
  305. X
  306. Xsub PrintMailLog {
  307. X    do PrintLog (@_);
  308. X    system ("echo @_ | mail $sysop");
  309. X}
  310. X
  311. Xsub PrintLog {
  312. X    open(LOGFIL,">>$logfile");
  313. X    print STDERR @_;
  314. X    print LOGFIL @_;
  315. X    close(LOGFIL);
  316. X}
  317. X
  318. Xsub PrintLabel {
  319. X    local ($partition, $host, $dumplevel) = @_;
  320. X    local ($i, $size);
  321. X    local ($sum) = 0;
  322. X
  323. X    if ( $partition eq "" ) {
  324. X        $i = 0;
  325. X    } else {
  326. X        for ( $i = 0; $i < $#partitions && 
  327. X                      ($partitions[$i] ne $partition || 
  328. X                      $partitions[$i+1] ne $host); $i += 3 ) {
  329. X            ;
  330. X        }
  331. X    }
  332. X    do OpenLpr();
  333. X    do {
  334. X        $size = do PrintPartSize($i, $level);
  335. X        $sum += $size;
  336. X        $i += 3;
  337. X    } while ( $size && $i < $#partitions);
  338. X    do CloseLpr();
  339. X}
  340. X
  341. Xsub GetName {
  342. X    local ($rpart) = @_;
  343. X    local (@retv);
  344. X    if ( index($rpart, ":") == $[-1 ) {
  345. X        print STDERR "partitions must be specified as \"host:/partition\" \n";
  346. X        exit(1);
  347. X    }
  348. X    @retv = split(':', $rpart);
  349. X    if ( @retv[0] eq "" || @retv[1] eq "" ) {
  350. X        print STDERR "partitions must be specified as \"host:/partition\" \n";
  351. X        exit(1);
  352. X    }
  353. X    @retv;
  354. X}
  355. X
  356. Xsub GetHostName {
  357. X    local ($rpart) = @_;
  358. X    local (@retval) = do GetName($rpart);
  359. X    @retval[0];
  360. X}
  361. X
  362. Xsub GetPartName {
  363. X    local ($rpart) = @_;
  364. X    local (@retval) = do GetName($rpart);
  365. X    @retval[1];
  366. X}
  367. X
  368. Xsub ParseArgs {
  369. X    do 'getopt.pl';
  370. X    do Getopt('omdlrsPLt');  # add only options that have arguments
  371. X    foreach $i ( ('a','p','o','m','d','l','r','s','L','P','D','t') ) { # include _ALL_ arguments here
  372. X        $tmp = eval"\$opt_$i";
  373. X        if ( $tmp ne "" ) {
  374. X            # options w/ aruguments go here.
  375. X            if ( $tmp =~ /-/ ) {
  376. X                die $USAGE;
  377. X            }
  378. X            if ( $i eq 'D' ) {$debug = 1;}
  379. X            if ( $i eq 'a' ) {$append = 1;}
  380. X            if ( $i eq 'o' ) {$sysop = $tmp ;}
  381. X            if ( $i eq 'm' ) {$maxkbytes = $tmp;}
  382. X            if ( $i eq 'd' ) {$dhost = $tmp;}
  383. X            if ( $i eq 'L' ) {$logfile = $tmp;}
  384. X            if ( $i eq 'r' ) {$recover = $tmp;}
  385. X            if ( $i eq 's' ) {$sum = $tmp;}
  386. X            if ( $i eq 'P' ) {$printer = "-P $tmp";}
  387. X            if ( $i eq 'l' ) {$level = $tmp;}
  388. X            if ( $i eq 'p' ) {$label = 1;}
  389. X            if ( $i eq 't' ) {$tape = $tmp;}    
  390. X        }
  391. X    }
  392. X}
  393. X
  394. X
  395. X# make sure that all machines are alive 
  396. Xsub CheckMachines {
  397. X    local ($i, $j, @dead);
  398. X    for ( $i = 1, $j = 0; $i < $#partitions+1; $i += 3 ) {
  399. X        system("/usr/etc/ping -c1 $partitions[$i]");
  400. X        if ( $? ) {
  401. X            $dead[$j++] = $partitions[$i];
  402. X        }
  403. X    }
  404. X    if ( $dead[0] ne "" ) {
  405. X        do PrintMailLog ("Backup aborted, the following systems are dead: @dead");
  406. X        do PrintLog("\n");
  407. X        die ("\n");
  408. X    }
  409. X}
  410. X
  411.  
  412.