Xref: feenix.metronet.com comp.sys.sun.admin:10741 Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!spool.mu.edu!olivea!tardis!jms From: jms@tardis.Tymnet.COM (Joe Smith) Newsgroups: comp.sys.sun.admin Subject: Re: Making Backups? Message-ID: <3687@tardis.Tymnet.COM> Date: 23 Aug 93 07:14:48 GMT References: Organization: BT Tymnet, San Jose, CA Lines: 1837 In article sharris@chopin.udel.edu (Scott A Harris) writes: > > >I'm just curious if there is a way to put >rsd0a, rsd0h, and rsd0g all on one tape? >Is there a way to just append the info? Yes. Just use /dev/nrst0 instead of /dev/rst0. Here is a script I've written in PERL to do just that. -Joe -rw-r--r-- 1 root 14520 Jan 10 1993 usr/local/admin/dump/backup.doc The shar (shell archive) starts 315 lines into this message. From: Joe Smith Date: 10-Jan-92 Subject: Backup script for 8mm tapes This 'backup' script has several advantages over other backup utilities: o Dumps multiple disk partitions from multiple hosts to a single Exabyte (8mm) tape. o Keeps a short table of contents (in human readable form) at the beginning of the tape. It lists which partitions were saved and their file numbers, so that 'restore' can be told how many files to skip. (You can use "cat /dev/rst0" to read the table of contents.) o Includes a 'tar' save of shell scripts that are useful in restoring files from the tape. Operators need not remember all the details required to restore files. All they have to remember is that the tape can be read using "/usr/etc/extract_unbundled" and everything else is automatic. o The 'tar' save also includes the output from 'du', which provides a summary of all directories saved on the tape. o Keeps track of how many times a tape (or set of tapes) has been used. o Logs all output from 'dump' to a disk file in /var/adm/dumplog. o Keeps track of how many hours it took to dump each partition. o Can handle multiple tape drives (such as /dev/nrst0 and /dev/nrst1). o Can be used to save single partitions to multiple 1/2-inch or 1/4-inch tapes. Automatically specifies the right size/density/tracks for each type of tape. o Can be used in "long play" mode, where a week's worth of incremental saves are stored on a single, nonrewinding tape. Sample commands: alpha# /usr/local/admin/dump/backup 8mm all set-2 beta# /usr/local/admin/dump/backup cart all inc-01 delta# /usr/local/admin/dump/backup c150 all inc-31 gamma# /usr/local/admin/dump/backup 6250 all set-4 Fri The arguments are: 1) TapeType = type of tape (8mm 1600 6250 cart c150) or device (st1 mt9). 2) HostSet = either the name of a single host to dump, or an alias. 3) TapeSet = either the name of a single tape (for incrementals) or the name of a set of tapes (for level-0 saves of the entire file system). (If TapeSet is not supplied, a list of tape sets will be extracted from /etc/dumptapes and displayed for the user.) 4) SchedDay = optional day-of-week for scheduling purposes. In the last example above, it means to pretend that today is Friday. The following files are part of the 'backup' package: /usr/local/admin/dump/backup.doc This document. /usr/local/admin/dump/backup The backup program, written in PERL. /usr/local/admin/dump/retrieve Invokes 'restore', also in PERL. /usr/local/admin/dump/disk-usage Creates summary for each local disk. /usr/local/admin/restore/restore_8mm Shell script put at beginning of tape. /usr/local/admin/restore/install_unbundled For /usr/etc/extract_unbundled. /var/admin/dump/dumptapes Counts how often each tape is used. /var/admin/dump/{8mm,6250}/* Table of Contents files for each tape. /var/adm/dumplog/YYMMDD Output from the 'dump' command, one per day. /etc/admin/dump/candidates Used to translate HostSet to list of hosts. /etc/admin/dump/schedule.`hostname` Used to define available tape drives. /etc/admin/dump/schedule.* Lists file systems and how often to dump them. /etc/dumptapes Symbolic link to /var/admin/dump/dumptapes. /bin/perl Symbolic link to /usr/local/bin/perl (PERL 4.0.19 came from comp.sources.misc in April and November of 1991.) -------------------------------------- Tape format: The first two files on the tape are: 1) A human readable Table of Contents and copyright notice. 2) A 'tar' save of files that can be used to read the rest of the tape. Note that this layout is compatible with Sun's 'extract_unbundled' script. If the tapes are labled with "Use /usr/etc/extract_unbundled", then it means that you don't have to worry about losing the documentation on how to restore files from the tape; all the necessary information is included automatically. The scripts in tape file #2 are written to be processed using /bin/sh and /bin/csh, so they can be used if PERL is not available (such as when booting from the miniroot in order to restore /usr/local or all of /usr). Also included in this 'tar' save is a directory called 'du' which has the output from the 'du' command for each partition. This data can be used to determine which partition a give directory was on at the time of the dump. Files 3 though N are 'dump' saves. The last file on the tape is a copy of the Table of Contents, but includes a log of how many hours it took to process each partition. The Table of Contents files are kept in /var/admin/dump/$TapeType/$TapeSet.*. The files are overwritten when that particular tapeset is reused. -------------------------------------- Sample input files: ==> /etc/admin/dump/candidates <== seta alpha beta setb delta gamma all alpha beta delta gamma This defines aliases for lists of hosts. Anything not found in the candidates file is assumed to be the name of a single host. ==> /etc/admin/dump/schedule.alpha <== localtape 8mm=st0 6250=gamma:mt8 # schedule.alpha # alpha is diskless - this file exists only to define 'localtape'. ==> /etc/admin/dump/schedule.gamma <== localtape cart=st8 1600=mt0 6250=mt8 1600=mt1 6250=mt9 # schedule.gamma #dev days level tape-name list of partitions 8mm .....f. 0 all-tape1 xd0a:root xd0e:var 8mm .....f. 0 all-tape1 xd0g:usr xd1g:export xd0h:home/gamma 8mm .....f. 0 all-tape2 xd1h:netnews 8mm ....... X no-backup xd1f:export/swap # never backed up 8mm smtwt.s 0 all-daily xd0a:root xd0e:var 8mm smtwt.s 5 all-daily xd0g:usr xd1g:export xd0h:home/gamma 8mm smtwt.s 5 all-daily xd1h:netnews 6250 .....f. 0 gamma-usr-root xd0g:usr xd0a:root xd0e:var 6250 .....f. 0 gamma-export xd1g:export 6250 .....f. 0 gamma-home xd0h:home/gamma 6250 .....f. 0 gamma-news xd1h:netnews Workstation "alpha" is a diskless client with an 8mm tape drive addressed as /dev/rst0 (as opposed to /dev/rst1). Server "gamma" is shown to have a 60 megabyte 1/4-inch cartridge on /dev/rst8 and two 1/2-inch tape drives. The 'backup' script will use the first 1/2-inch drive if the TapeType is set to "1600", "mt0", "6250" or "mt8". It will use the second one only for "mt1" or "mt9". In the schedule file, the first word on each line is checked to see if it matches the selected TapeType. Then the second word is checked to see if it matches the SchedDay (which defaults to the current day of the week). The appropriate column is checked for a period (which says to ignore the rest of the line). Anything else means to process the rest of the line. In the examples above, if 'backup' is invoked on host alpha, it will ask host gamma to report which partitions need to be backed up and which tapes to use. If it is Friday, gamma will say that it wants to have 6 partitions backed up using a "level 0" dump onto two 8mm tapes. On any other day of the week, gamma will say that it wants to do a "level 0" dump of /var and the root partition, and do a "level 5" dump of all the other partitions to a single 8mm tape. Not shown are the schedule files for hosts delta and beta, which get included on tapes "all-tape2" and "all-daily". ==> /etc/admin/dump/proprietary <== +---------------------------------------------------------------------------+ | Proprietary rights of **THIS COMPANY** are included in information stored | | on this tape. The contents of this tape are to be used for backup and | | recovery purposes only. Any other use is a violation of XXXX guidelines. | +---------------------------------------------------------------------------+ This file, if it exists, will be included in the Table of Contents file that is put on the beginning and end of the tape. It should be customized to reflect the department's policy on computer access. -------------------------------------- Sample output files: ==> /var/admin/dump/8mm/set1.all-tape1 <== Set "set1" Tape "all-tape1" written Fri Jan 24 07:30:25 PST 1992 Device "st0" (8mm) blocked 126 at 54000 bpi for 6000 feet. 01 Table of Contents 02 Restore Scripts 03 gamma lvl-0 xd0a /root 04 gamma lvl-0 xd0e /var 05 gamma lvl-0 xd0g /usr 06 gamma lvl-0 xd1g /export 07 gamma lvl-0 xd0h /home/gamma 12 Table of Contents (copy) [End of Tape] +---------------------------------------------------------------------------+ | Proprietary rights of **THIS COMPANY** are included in information stored | | on this tape. The contents of this tape are to be used for backup and | | recovery purposes only. Any other use is a violation of XXXX guidelines. | +---------------------------------------------------------------------------+ Tape set1.all-tape1 started at Fri Jan 24 07:32:58 PST 1992 (hours) Disk gamma:xd0a finished at Fri Jan 24 07:34:42 PST 1992 ( 0.03) Disk gamma:xd0e finished at Fri Jan 24 07:37:16 PST 1992 ( 0.04) Disk gamma:xd0g finished at Fri Jan 24 07:56:13 PST 1992 ( 0.31) Disk gamma:xd1g finished at Fri Jan 24 08:30:55 PST 1992 ( 0.58) Disk gamma:xd0h finished at Fri Jan 24 09:27:28 PST 1992 ( 0.94) Tape set1.all-tape1 finished at Fri Jan 24 11:39:51 PST 1992 ( 1.90) The last line is the total amount of time it took to process all the partitions that were stored on this tape. ==> /var/adm/dumplog/920124 <== TOC written to /var/admin/dump/8mm/set1.all-tape1 starting gamma:/dev/rxd0a (root) level 0 dump on set1.all-tape1 03 rsh gamma /usr/etc/dump u0bdsf 126 54000 6000 alpha:/dev/nrst0 /dev/rxd0a DUMP: Date of this level 0 dump: Fri Jan 24 07:33:14 1992 DUMP: Date of last level 0 dump: the epoch DUMP: Dumping /dev/rxd0a (/) to /dev/nrst0 on host alpha DUMP: mapping (Pass I) [regular files] DUMP: mapping (Pass II) [directories] DUMP: estimated 12544 blocks (6.12MB) on 0.00 tape(s). DUMP: dumping (Pass III) [directories] DUMP: dumping (Pass IV) [regular files] DUMP: level 0 dump on Fri Jan 24 07:33:14 1992 DUMP: Tape rewinding DUMP: 12544 blocks (6.12MB) on 1 volume DUMP: DUMP IS DONE starting gamma:/dev/rxd0e (var) level 0 dump on set1.all-tape1 04 rsh gamma /usr/etc/dump u0bdsf 126 54000 6000 alpha:/dev/nrst0 /dev/rxd0e DUMP: Date of this level 0 dump: Fri Jan 24 07:34:56 1992 ... [several lines of output deleted here] DUMP: DUMP IS DONE Tape set1.all-tape1 finished at Fri Jan 24 11:39:51 PST 1992 ( 1.90) TOC written to /var/admin/dump/8mm/set1.all-tape1 TOC written to /var/admin/dump/8mm/set1.all-tape2 starting gamma:/dev/rxd1h (netnews) level 0 dump on set1.all-tape2 03 rsh gamma /usr/etc/dump u0bdsf 126 54000 6000 alpha:/dev/nrst0 /dev/rxd1h DUMP: Date of this level 0 dump: Fri Jan 24 11:46:12 1992 ... [several lines of output deleted here] DUMP: DUMP IS DONE Tape set1.all-tape2 finished at Fri Jan 24 14:45:21 PST 1992 ( 3.02) TOC written to /var/admin/dump/8mm/set1.all-tape2 The name of the directory for these log files, /var/adm/dumplog, was chosen to match the one used by Sun's "Backup CoPilot" utility. The name of the the log file is today's date in YYMMDD form. If the backup has to be restarted, the output will be appended to the existing log file. ==> /etc/dumptapes <== 8mm.day-01.incremental 6 Wed Apr 1 18:57:17 PST 1992 8mm.wed.incremental 52 Wed Apr 1 17:38:54 PST 1992 8mm.day-31.incremental 6 Tue Mar 31 19:13:47 PST 1992 8mm.tue.incremental 52 Tue Mar 31 17:45:14 PST 1992 8mm.day-30.incremental 6 Mon Mar 30 20:51:20 PST 1992 8mm.mon.incremental 52 Mon Mar 30 18:14:31 PST 1992 8mm.set8.all-tape2 2 Sun Mar 29 04:19:41 PST 1992 8mm.set8.all-tape1 2 Sun Mar 29 02:40:30 PST 1992 6250.set1.gamma-boot 8 Fri Feb 7 20:00:34 PST 1992 This file is sorted with the most recently used tape first. The first column is the TapeType.TapeSet.TapeName, the second is the number of times that this tape was used. The date/time is when the dump finished on this tape. -------------------------------------- New features (since January 1992): o Added /etc/dumptapes to keep track of tapes used. o Added an explicit "mt -f /dev/r$TAPE rewind" to 'retrieve' script. This is to avoid crashing if running SunOS-4.1.1 without patch 100280-02 installed. (The symptom was "panic: psig action" when 'restore s N' tried to skip forward N savesets.) o Changed blocking factor from 126 to 112 so that the buffer size (56K) is the largest multiple of 8K less than 64K (since SunOS uses 8K pages). o Eliminated blocking factor from the 'retrieve' script since 'restore' detects the blocking factor automatically. o If /usr/local/admin/dump/disk-usage is excuted daily, then the output from /usr/bin/du for each partition is stored on the tape. This is very handy when user directories get moved from one /home partition to another. The old location can be determined by using 'grep' on the 'du' file. o Use "-8mm" to start an incremental save; the tape will not be rewound after the dump. Use "+8mm" to append to an incremental; the tape is not rewound before or after the dump. Use "=8mm" to finish an incremental tape; the tape is rewound after the dump (but not before). This allows a full week's worth of incrementals to be saved on a single tape, as long as you dedicate one 8mm drive for doing backups only. Things to do: o Read the first line off the tape to make sure the correct tape is mounted. o Do more with the output from 'estimate.8mm', which estimates what fraction of an Exabyte tape will be required to backup a given partition. o Replace "candidates" file with /etc/host.aliases. o Calculate the number of tapes each dump is going to take and verify that multiple saves to a single tape won't hit end-of-tape unexpectedly. o Handle schedules that do not repeat every 7 days. o Provide enough defaults so that 'backup' can be run with no arguments. o Update /usr/local/admin/dump/retrieve. (It has not had as much attention as the other scripts.) Make prompt for missing command line arguments. o Rewrite 'backup' so that can prompt for missing command line arguments and display reasonable default values. (Much work needed here.) [End of backup.doc] ---------------- cut here ---------------- #! /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 'usr/local/admin/dump/autobackup' <<'END_OF_FILE' X#!/bin/perl X# Name: /usr/local/admin/dump/autobackup Author: Joe Smith X# Purpose: Invoked by cron to automatically starts the backup dumps. X X# This is not a general-purpose script; it works only for a system with X# two tape drives (one for incrementals, one for full saves). It assumes X# that an entire week's worth of incrementals can fit on a single 2.3Gb tape X# and that the level-0 dump of all disks fits onto a single 5.0Gb tape. X X($progdir,$me) = $0 =~ m%(^.*)/(.*)%; # Directory where program was run X($progdir,$me) = (".",$0) if $progdir eq ""; X X$hostset = $ARGV[0]; # Name of hostset (in candidates file) X$hostset = "all" unless $hostset; X$log = $ARGV[1]; # Name of logfile or directory X$log = "/var/admin/dump/autobackup" unless $log; X X($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; X$yymmdd = sprintf("%02d%02d%02d",$year,$mon+1,$mday); X$autofile = "/etc/admin/dump/autobackup"; X X# Sample contents of /etc/admin/dump/autobackup: X# 8mm week1 921121 921122 921123 921124 921125 921126 X# 8mm2 set01 921127 X Xif (open(FILE,$autofile)) { X while() { X chop; s/\s*#.*//; next if /^$/; # Skip comments and blank lines X ($dev,$tape,@dates) = split if /$yymmdd/o; # Look for today's date X } X close(FILE); X} else { X die "Cannot read data from $autofile - $!\n"; X} Xdie "No entry found for $yymmdd\n" unless $dev; Xprint "$yymmdd: dev=$dev tape=$tape dates=",join(',',@dates),"\n"; X X$firstdate = $dates[0]; $lastdate = pop(@dates); X$p = "+"; $type = "incr"; $unload = 0; # Default is to append to current save X$p = "-" if $firstdate eq $yymmdd; # Start a new save, no unload X$p = "=", $unload++ if $lastdate eq $yymmdd; # End of incremental, unload X$p = "", $unload++ if $firstdate eq $lastdate; # Full save and unload X$type = "full" if $p eq ""; X$logfile = (-d $log) ? "$log/$type" : "$log.$type"; X X$foo = "$progdir/backup $p$dev $hostset $tape >$logfile"; X$| = 1; print " $foo\n"; # Display the command about to be executed Xsystem($foo); Xprint " ls -l $logfile\n"; system("ls -l $logfile"); Xprint "Be sure to insert next tape in $dev before 5:00pm\n" if $unload; END_OF_FILE if test 2125 -ne `wc -c <'usr/local/admin/dump/autobackup'`; then echo shar: \"'usr/local/admin/dump/autobackup'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/autobackup' # end of 'usr/local/admin/dump/autobackup' fi if test -f 'usr/local/admin/dump/backup' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/backup'\" else echo shar: Extracting \"'usr/local/admin/dump/backup'\" \(21850 characters\) sed "s/^X//" >'usr/local/admin/dump/backup' <<'END_OF_FILE' X#!/bin/perl X# Name: /usr/local/admin/dump/backup Author: DH,CB,CF, Joe Smith X# Purpose: Dumps several diskfull workstations to a single 8mm tape. X# (Also handles 1/2 and 1/4 inch tapes.) Automatically determines when X# to do level-0 dumps and when to do incremental saves. X# Assumes that /usr/local/admin/dump/disk-usage is run once a day. X# X# See /usr/local/admin/dump/backup.doc for more details. X X$TapeType = $ARGV[0]; # Type of tape device: "8mm", "6250", etc X$HostSet = $ARGV[1]; # Keyword describing which hosts to back up X$TapeSet = $ARGV[2]; # Tape set name (such as "set-1", "inc-31", etc) X$SchedDay = $ARGV[3]; # Optional day (to re-do Friday's save on Saturday) X Xif ($TapeSet eq "") { X print "Usage: $0 tape-type host-set tape-set [ schedule-day ]\n" . X " eg. $0 8mm all set-a fri\n" . X "use '-8mm' to start a multi-day save (no rewind), '+8mm' to\n" . X "append to multi-day save, '=8mm' to finish a multi-day save.\n"; X exit 1; X} X X# Configuration parameters - change these to match your site's conventions. X# Directories in /var will be created as needed. X X$ETCDIR = "/etc/admin/dump"; # Dir for parameter files X$MYDIR = "/usr/local/admin/dump"; # Dir for scripts to create dump tapes X$RESTORE = "/usr/local/admin/restore"; # Dir for scripts to read dump tapes X$VARDIR = "/var/admin/dump"; # Dir for data (tape list, file list) X$debug = 0; X X# Names of files and directories based on the above parameters X X$candidates = "$ETCDIR/candidates"; # List of diskfull workstations X$schedule = "$ETCDIR/schedule"; # List of disks and their schedule X$proprietary= "$ETCDIR/proprietary"; # Copyright notice and/or warning X$readtape = "$RESTORE/read_contents"; # Program to verify the tape X$tocdir = "$VARDIR/toc"; # Written by $RESTORE/read_contents X$dudir = "$VARDIR/du"; # Output from 'du' = dir summary X$logdir = "$VARDIR/log"; # Messages from 'dump' go here X$vartapes = "$VARDIR/dumptapes"; # Where tape list is stored X$dumptapes = "/etc/dumptapes"; # Where we say it is (symlink name) X# $dumpdir = "$VARDIR/8mm" or "$VARDIR/6250" depending on what drive is used. X# $logfile = "$logdir/$yymmdd.$ThisHost" to match current year, month, day. X X# Use block 112 instead of 126 to make block size a multiple of 8Kbytes. X%DumpParams = ( # Parameters for /usr/etc/dump (as of SunOS-4.1.2) X "8mm", "bdsf 112 54000 6000 : 2.3G", # Exabyte 8200 X "8mm2", "bdsf 112 108000 6000 : 5.2G", # Exabyte 8500 (double density) X "8mm4", "bdsf 112 216000 6000 :10.4G", # Exabyte 8500-Compression X "6250", "bdsf 64 6250 2300 : 180M", # 1/2-inch GCR X "1600", "bdsf 20 1600 2300 : 44M", # 1/2-inch PE X "cart", "cbdsf 112 1000 425 : 60M", # 1/4-inch QIC-24 X "c150", "cbdstf 112 1000 700 18: 150M" # 1/4-inch QIC-150 X); #key opts blocking density feet tracks:size X X%WeekDays = ( X "sun",0, "Sun",0, "Sunday", 0, "mon",1, "Mon",1, "Monday", 1, X "tue",2, "Tue",2, "Tuesday", 2, "wed",3, "Wed",3, "Wednesday",3, X "thu",4, "Thu",4, "Thursday", 4, "fri",5, "Fri",5, "Friday", 5, X "sat",6, "Sat",6, "Saturday", 6 X); X X@WeekDays = ("Sunday", "Monday", "Tuesday", X "Wednesday", "Thursday", "Friday", "Saturday"); X X############################################################################# X X# Start of main program X X$StartSec = time; # For calculating elapsed time Xchop($ThisHost = `hostname`); X# The time from midnight to 6:00am is considered to be the previous day. X($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time-6*60*60); X$yymmdd=sprintf("%02d%02d%02d",$year,$mon+1,$mday); X X# Determine what tape drives are attached to the local host. X Xopen(SCHEDULE,"$schedule.$ThisHost") || X die "Can't find 'localtape' in $schedule.$ThisHost: $!\n"; Xwhile() { X chop; s/\s*#.*//; next if /^$/; X ($keyword,@list) = split; # Look for "localtape 8mm=st0 6250=mt8" X if ( $keyword eq "localtape" ) { # or "localtape 8mm=alpha:st0" X print "Tape drives for $ThisHost:"; X foreach (@list) { X ($tape,$dev) = split('='); X if ( $DumpParams{$tape} ) { # If defined in our list X $TapeDev{$tape} = $dev if ! $TapeDev{$tape}; # Remember only 1st one X $DevTape{$dev} = $tape; X print " $tape=$dev"; # Show which ones we recognize X } else { X print " $tape+$dev=unknown"; X } X } # each list X print "\n"; last; # "localtape" should be on 1st line of file X } X} # end Xclose(SCHEDULE); Xdie "'localtape' not defined in $schedule.$ThisHost\n" if ! defined %TapeDev; X$| = 1; # Don't buffer STDOUT (so system() works right when output to a file) X X############################################################################# X X# Verify the 1st argument (TapeType) X# "8mm" = rewind before saving TOC and scripts, unload after dump. X# "-8mm" = rewind before saving TOC and scripts, but not after. X# "+8mm" = append incremental to tape, don't rewind tape. X# "=8mm" = append incremental to tape, write trailing TOC, unload tape. X Xif ($TapeType =~ /^\-(.*)/) { # Use "-8mm" to start a new incremental tape X $TapeType = $1; $RewindBefore = 1; $RewindAfter = 0; X print "\n Starting a new incremental dump tape (no rewind at end).\n\n"; X} elsif ($TapeType =~ /^\+(.*)/) { # Use "+8mm" to append to current incremental X $TapeType = $1; $RewindBefore = 0; $RewindAfter = 0; X print "\n Appending to incremental dump tape; no rewind.\n\n"; X} elsif ($TapeType =~ /^\=(.*)/) { # Use "=8mm" to finish off an incremental X $TapeType = $1; $RewindBefore = 0; $RewindAfter = 1; X print "\n Finishing an incremental dump tape; will unload.\n\n"; X} else { X $RewindBefore = 1; $RewindAfter = 1; # Default is not long-play mode X} X$Interactive = -t; # 1 if STDIN is a terminal, null if not X Xif ($DevTape{$TapeType}) { # If given "st1" and both 8mm=st0 and 8mm=st1 X $Dev = $TapeType; # are defined, use the specified /dev name X $TapeType = $DevTape{$Dev}; # and set TapeType to 8mm. X} else { X $Dev = $TapeDev{$TapeType}; # Get the /dev name for this type of tape. X} X X$Dev || die "Host $ThisHost does not have '$TapeType' defined as localtape.\n"; X($tpar,$tapesize) = split(":",$DumpParams{$TapeType}); X$tpar =~ s/\s+/ /g; X($options,$block,$density,$size) = split(" ",$tpar); X X ######## X X# Expand 2nd argument (HostSet) to a list of hosts X X@hostlist = ($HostSet); # This allows single hosts to be done Xif ( open(CANDIDATES,"<$candidates") ) { X while() { X chop; s/\s*#.*//; next if /^$/; X ($keyword,@list)=split; # Look for alias in this file X @hostlist = @list if ($keyword eq $HostSet); X } X close(CANDIDATES); X} else { warn "Cannot read candidates list $candidates\n$!\n"; X} X X ######## X X# Check that 3rd argument (TapeSet) is defined in /etc/dumptapes. Format is: X# type set tapename usecount date_of_last_use X# 8mm.set1.tso-tape1 3 Fri Feb 7 17:30:41 PST 1992 X Xsymlink($vartapes,$dumptapes) if ! -f $dumptapes; Xprint "Checking $dumptapes for tape set '$TapeSet'\n"; Xif ( open(DUMPTAPES,"<$dumptapes") ) { X while() { X ($type,$set,$rest)=split('\.'); X ($tape,$usecount,$date)=split('[ \t]+',$rest,3); X if ("$type.$set" eq "$TapeType.$TapeSet") { X $TAPE="$set.$tape"; X printf(" %-25s used %3d times as of %s",$TAPE,$usecount,$date); X $foundset++; X } X $sets{$set}++ if $type eq $TapeType; X } X close(DUMPTAPES); X if (! $foundset && $TapeSet =~ /(mon|tue|wed|thu|fri|sat|sun)-\d+/ ) { X print "\07 Using '$1' instead of '$TapeSet'\n"; X $TapeSet = $1; # Use "mon" instead of "mon-31" for Monday the 31st X $foundset++; X } X if (! $foundset) { X print "TapeSet '$TapeSet' not found in $dumptapes."; X print " Current sets for $TapeType are:\n"; X if ($_ =&MakeCols(" ",79,"",sort short keys %sets)) { X if ($Interactive) { X print "$_\nIs '$TapeSet' the correct name of the tape set? "; X $_ = ; X die "Please try again.\n" if ! /[Yy]/; X } X } else { X print " (none currently defined)\n"; X } X } X} else { warn "Could not read $dumptapes: $!\n"; X} X X ######## X X# The 4th argument is optional and defaults to the current day of the week. X X$SchedDay = $WeekDays[$wday] if ($SchedDay eq ""); # Sunday-Saturday Xdefined $WeekDays{$SchedDay} || die "Invalid schedule day '$SchedDay'\n"; X X############################################################################# X X# All command line arguments have been verified. Now go to work. X# Create the needed directories, clean up files from last night's run. X X$dumpdir = "$VARDIR/$TapeType"; # Typically "/var/admin/dump/8mm" X$logfile = "$logdir/$yymmdd.$ThisHost"; # Messages from 'dump' go here Xsystem("mkdir -p $dumpdir") if ! -d $dumpdir; Xsystem("mkdir -p $logdir") if ! -d $logdir; Xsystem("mkdir -p $dudir") if ! -d $dudir; X X# Ping each host in the list. If up, append its 'schedule' file to list. X Xprint "Looking for $TapeType:$SchedDay in $schedule.`hostname`\n"; Xprint " Directory_Summary_File Level Tape_Name\n"; Xforeach $rHost (@hostlist) { # Try each host in list X next if $partitions{$rHost}; # Skip if duplicate host name X if (!system("/usr/etc/ping $rHost 5 > /dev/null")) { X push(@candidates,$rHost); # Record Rhost in list X open(DUMPME,"rsh $rHost cat $schedule.$rHost |") || die "rsh $rHost $!"; X while () { X chop; s/\s*#.*//; next if /^$/; X ($tapetype,$when,$level,$tape,@filesystems)=split; X if ( $tapetype eq $TapeType ) { # If first token on line matches X next if &NotToday($when); # Check schedule info X foreach (@filesystems) { # Add each target to tape list X $partitions{$rHost}++; X ($target,$text) = split(':'); X $tapes{$tape} .= join(":",$rHost,$level,$target,$text) . " "; X $du = "$dudir/$rHost.$target"; X print("$rHost:$du\t$level $tape\n"); # Show name of summary file X if ($rHost ne $ThisHost) { X warn "system('rcp -p $rHost:$du $du.tmp')\n" if $debug; X system("rcp -p $rHost:$du $du.tmp"); X warn "system('rsh $rHost mv $du.tmp $du')\n" if $debug; X system("rsh $rHost mv $du.tmp $du"); X } X } # each target X } # if tapetype X } # while X } else { # if ping failed X print "Host $rHost did not respond...will not be dumped\n"; X } X} # end foreach (@hostlist) X X@tapes = sort keys(%tapes); X$TapeCount = @tapes; # Number of different tapes Xprint "$TapeCount tapes required: ", join(" ",@tapes), "\n\n"; X$Interactive = 0 if $TapeCount == 1; # Don't prompt if only one tape Xif ($TapeCount > 1 && ! $Interactive) { X die "Must be run from a terminal to handle multiple tapes.\n"; X} X X############################################################################# X X# Do all hosts that fit on a single 8mm tape X X$TapeHost = $ThisHost; # Assume tape is on this host X($TapeHost,$Dev) = split(':',$Dev) if $Dev =~ /:/; # If remote tape X Xforeach $tape (@tapes) { X chop; # Remove space at end of string X $TAPE="$TapeSet.$tape"; # Something like "set1.incremental" X @parts = split(" ",$tapes{$tape}); # All parts for a single tape X $TapeSec = time; # For this tape's elapsed time X X $header = qq|Set "$TapeSet" Tape "$tape" started | . `date` X . qq|Device "$Dev" ($TapeType) blocked $block at $density bpi | X . qq|for $size feet.\n\n|; X X if ($Interactive) { X # Tell operator which tape to mount and wait for it. X print qq|Please insert $TapeType tape "$TAPE" on $TapeHost:/dev/r$Dev.\n|; X print "\07Type Y when ready or N to skip this tape. Waiting...\07"; X $_ = ; X next if /^[NnQqAa]/; # Skip to next tape if No, Abort, or Quit X } X X $tocname = "$dumpdir/$TAPE.toc"; # Filename matches tape name X $dufile = "$TAPE.du"; # List of directories on this tape X $duname = "$dumpdir/$dufile"; X X $LastFile = "00"; X if ($RewindBefore) { X @dump_toc = ($header) X } else { X if (open(TOC,$tocname)) { X @dump_toc = ; X close(TOC); X foreach (@dump_toc) { X $LastFile = $1 if /^(\d+)\t/; # Find last line with digits-tab X } X push(@dump_toc,"\n\t\t(last save file was $LastFile)\n\n"); X } else { X warn "Could not find previous Table of Contents $tocname\n"; X } X } X $FileNumber = $LastFile; X push(@dump_toc, ++$FileNumber,"\tTable of Contents\n"); X push(@dump_toc, ++$FileNumber,"\tRestore Scripts + 'du' lists\n"); X X foreach (@parts) { X ($rHost,$level,$target,$text)=split(/:/, $_); X push(@dump_toc,++$FileNumber,"\t$rHost\tlvl-$level\t$target\t/$text\n"); X } X X if ($RewindAfter) { X push(@dump_toc,++$FileNumber,"\tTable of Contents (summary)\n"); X push(@dump_toc,"\n[End of Tape]\n\n"); X } else { X push(@dump_toc, "$FileNumber+ ...\t(additional saves to be appended later)\n\n"); X } X X if (-f $proprietary && $RewindBefore) { # If warning file exists X open(TOC,"$proprietary"); X push(@dump_toc,); # Read in the entire file X close(TOC); X } X X ######## X X # Write Table Of Contents to $dumpdir directory to disk and maybe to tape X X open(TOC,">$tocname") || die "can't open $tocname: $!"; X print TOC @dump_toc; X close (TOC); X X print "\nWriting Table of Contents to tape...\n file = $tocname\n"; X $rsh=""; $rsh="rsh $TapeHost" if $TapeHost ne $ThisHost; X if ($RewindBefore) { X system("$rsh mt -f /dev/nr$Dev rewind"); X $tocdev="/dev/r$Dev"; # This will rewind after X $FileNumber = "00"; X } else { X $tocdev="/dev/nr$Dev"; # Don't rewind after writing TOC X print @dump_toc; X $FileNumber = $LastFile; X } X $FileNumber++; # The TOC is file 01 if RewindBefore X system("<$tocname $rsh dd of=$tocdev conv=sync 2>&1"); X print("Table of Contents written. "); X X # Set up the directory summary while waiting for tape to rewind X X print("Creating directory summary file.\n"); X unlink $duname; # In case tape being overwritten X foreach (@parts) { X ($rHost,$level,$target,$text)=split(/:/, $_); X $foo="awk '{print \"$rHost:$target\t\"\$0}' $dudir/$rHost.$target"; X system("$foo >>$duname"); X } X system("ls -l $duname | cut -c23-"); # Show name of summary file X X # Now read the TOC to prove that the tape is readable. Tape will be X # left positioned after the TOC. X X system("$rsh cat /dev/nr$Dev") if $RewindBefore; # Note use of "/dev/nr" here. X X ######## X X # 2nd file on tape is a tar save to be compatible with 'extract_unbundled'. X # This save also has the saved output from 'du' - a list of all directories. X # The 'du' files are handy for verifying which save set contains a given X # directory. For this reason they are written even if TOC is not. X X print "\nCreating 'tar' save of the 'restore' files to $rHost:/dev/nr$Dev\n"; X $FileNumber++; # The 'tar' save is file 02 if RewindBefore X ($duParent,$duSubdir) = $dudir =~ m%(.*)/(.*)%; X $foo="tar cvfb - $block -C $RESTORE . -C $duParent ./$duSubdir"; X $foo="$foo | $rsh dd bs=${block}b of=/dev/nr$Dev"; X system("($foo)2>&1"); X X ######## X X $format1="%s %-25s started at %s (hours)\n"; # 1st line of summary X $format2="%s %-25s finished at %s (%5.2f)\n"; # all other lines X X chop($date=`date`); X $trailer = sprintf($format1,"Tape",$TAPE,$date); X open(TOC,">>$tocname"); print TOC $trailer; close(TOC); X open(LOG,">>$logfile"); print LOG "TOC written to $tocname\n"; close(LOG); X foreach (@parts) { # Do all partitions on this tape X $FileNumber++; X ($rHost,$level,$target,$text)=split(/:/, $_); X system("/usr/5bin/banner $rHost"); X $PartSec=time; X open(LOG,">>$logfile"); X $foo="starting $rHost:/dev/r$target ($text) level $level dump on $TAPE $FileNumber\n"; X print $foo; print LOG "\n$foo"; X $rsh=""; $rsh="rsh $rHost" if $rHost ne $ThisHost; X $rmt=""; $rmt="$TapeHost:" if $rHost ne $TapeHost; X $u="u"; $u="" if $TapeSet =~ /test/; X $foo="$rsh /usr/etc/dump $u$level$tpar $rmt/dev/nr$Dev" X#bug# . " $dumpdir.$FileNumber" # "dump -a" fails on sun3x X . " /dev/r$target"; X system("rsh $rHost mkdir -p $dumpdir $dudir $LOG") if $rHost ne $ThisHost; X print "$foo\n"; print LOG "$foo\n"; # Show command to be executed X close(LOG); X $err=system("$foo 2>&1 | tee -a $logfile"); # Invoke the 'dump' program X $foo="finished $rHost:/dev/r$target ($text) level $level dump on $TAPE $FileNumber\n"; X print $foo; X open(LOG,">>$logfile"); print LOG "$foo\n"; close(LOG); X if ($err) { # If dump returned an error code X $trailer="Dump failed - error code ".int($err/256)."/".($err&255)."\n"; X print $trailer; X open(TOC,">>$tocname"); print TOC $trailer; close(TOC); X if ($rHost ne $ThisHost) { # Use "mv" in case $dumpdir is NFS mounted X warn "system('rcp -p $tocname $rHost:$tocname.tmp')\n" if $debug; X system("rcp -p $tocname $rHost:$tocname.tmp"); X warn "system('rsh $rHost mv $tocname.tmp $tocname')\n" if $debug; X system("rsh $rHost mv $tocname.tmp $tocname"); X } X $|=1; print "Type Control-C within 20 seconds to abort everything.\n"; X sleep 20; X $|=0; print "[Continuing]\n"; X } else { # If dump did not return an error X $hours = (time-$PartSec)/3600; X chop($date=`date`); $disk="$rHost:$target"; X $trailer = sprintf($format2,"Disk",$disk,$date,$hours); X open(TOC,">>$tocname"); print TOC $trailer; close(TOC); X system("rcp -p $tocname $rHost:$tocname.tmp") if $rHost ne $ThisHost; X system("rsh $rHost mv $tocname.tmp $tocname") if $rHost ne $ThisHost; X @HostsDone = (@HostsDone, $rHost); X } X if ($rHost ne $ThisHost) { X warn "system('rcp -p $logfile $rHost:$logfile.tmp')\n" if $debug; X system("rcp -p $logfile $rHost:$logfile.tmp"); X warn "system('rsh $rHost mv $logfile.tmp $logfile')\n" if $debug; X system("rsh $rHost mv $logfile.tmp $logfile"); X } X } # End of foreach (@parts) X X # Put ending time in the TOC, append 2nd copy of TOC to end of tape X X $hours = (time-$TapeSec)/3600; X $used = &UpdateDumptapes($TapeType,$TAPE); # Put in /etc/dumpdates X $trailer = sprintf($format2,"Tape",$TAPE,$date,$hours) . $used; X print $trailer; X open(TOC,">>$tocname"); print TOC $trailer; close(TOC); X open(LOG,">>$logfile"); X print LOG $trailer, "TOC written to $tocname\n\n"; X close(LOG); X $rsh=""; $rsh="rsh $TapeHost" if $TapeHost ne $ThisHost; X system("<$tocname $rsh dd of=/dev/r$Dev conv=sync") if $RewindAfter; X $FileNumber++ if $RewindAfter; X print "Verifying that tape is readable\n\n"; X open(LOG,">>$logfile"); print LOG "Verifying tape"; close(LOG); X $foo="&1 | tee -a $logfile"); X X foreach (@HostsDone) { # Make sure earlier hosts have a complete copy of log X next if $_ eq $ThisHost; X system("rcp -p $tocname $_:$tocname.tmp"); X system("rsh $_ mv $tocname.tmp $tocname"); # In case NFS mounted X warn "system('rcp -p $logfile $_:$logfile.tmp')\n" if $debug; X system("rcp -p $logfile $_:$logfile.tmp"); X system("rsh $_ mv $logfile.tmp $logfile"); # In case NFS mounted X } X X system("/usr/5bin/banner 'Tape Done'") if --$TapeCount; # Not on last tape X system("$rsh mt -f /dev/r$Dev offline") if $RewindAfter; X print "Tape $Dev unloaded\n" if $RewindAfter; X printf("Tape %s took %5.2f hours to complete\n",$TAPE,$hours); X} # End of foreach (@tapes) X Xsystem("/usr/5bin/banner Finished"); X$hours=(time-$StartSec)/3600; Xprintf("Total time %5.2f hours\n",$hours); Xexit 0; # End of program X X############################################################################ X Xsub NotToday { # Check if this line should be processed today X local ($checkday) = @_; X return( substr( $checkday, $WeekDays{$SchedDay}, 1 ) eq "." ); X} X Xsub UpdateDumptapes { # Rewrites /etc/dumptapes for each tape done X local ($TapeType,$TAPE) = @_; X local (@text,$type,$set,$rest,$use,$date); X $MyUseCount = 1; # If not already in file X if ( open(DUMPTAPES,"<$dumptapes") ) { X while() { X ($type,$set,$rest)=split('\.'); X ($tape,$use,$date)=split('[ \t]+',$rest,3); X if ("$type.$set.$tape" eq "$TapeType.$TAPE") { X $MyUseCount = $use + $RewindBefore; # Increment if at BOT X } else { X push(@text,$_); X } X } X close(DUMPTAPES); X } X $rest="$TapeType.$TAPE"; X $use=sprintf("%-30s %3d %s",$rest,$MyUseCount,`date`); X unshift(@text,$use); # Put this line at beginning of file X open(DUMPTAPES,">$dumptapes"); print DUMPTAPES @text; close(DUMPTAPES); X return $use; X} X X Xsub MakeCols { # Create lines of specified width (with prefix and suffix) X local($pre,$width,$suf,@data) = @_; X local($result,$line,$rightj,$space,$ncols); X X local($max) = 0; X foreach (@data) { $max = length($_) if length($_) > $max; } X return "" if $max eq 0; X X if ($width > 0) { X $rightj = 0; # Left justified columns X } else { X $rightj = 1; # Right justified columns X $width = -$width; X } X X $width = $width - length($pre) - length($suf); X $ncols = int(($width+1)/($max+1)); # Number of columns on a line X $space = " " x int(($width - $ncols * $max) / ($ncols - 1)); X X $result = ""; $line = ""; X foreach (@data) { X if ((length($_)+length($line)) > $width) { # If line is full X $result .= $pre . $line . " " x ($width - length($line)) . "$suf\n"; X if ($rightj) { X $line = " " x ($max - length($_)) . $_ . $space; X } else { X $line = $_ . " " x ($max - length($_)) . $space; X } X } else { # If line is not full X if ($rightj) { X $line .= " " x ($max - length($_)) . $_ . $space; X } else { X $line .= $_ . " " x ($max - length($_)) . $space; X } X } X } X $result .= $pre . $line . " " x ($width - length($line)) . "$suf\n"; X return $result; X} X X# Subroutine to make short names (such as "mon","tue","wed") sort before X# before medium names ("set09","set10") and long names ("day-29","day-30"). X Xsub short { X length($a) == length($b) ? $a cmp $b : length($a) - length($b); X} END_OF_FILE if test 21850 -ne `wc -c <'usr/local/admin/dump/backup'`; then echo shar: \"'usr/local/admin/dump/backup'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/backup' # end of 'usr/local/admin/dump/backup' fi if test -f 'usr/local/admin/dump/df-i' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/df-i'\" else echo shar: Extracting \"'usr/local/admin/dump/df-i'\" \(1185 characters\) sed "s/^X//" >'usr/local/admin/dump/df-i' <<'END_OF_FILE' X#!/bin/sh X# Name: /usr/local/bin/df-i Author: Joe Smith X# Purpose: Combines the output of "df" and "df -i" so show number of blocks X# and number of inodes used on the same line. X Xhost=`hostname` Xdev="/dev/" Xif [ "x$1" = "x-h" ]; then X dev="$host:" # -h to include hostname in output X shift Xfi Xif [ "x$1" = "x-H" ]; then X dev="$host:" # -H same as -h but without header X shift X noheader=1 Xfi X Xmounts="$*" # List of mountpoints Xif [ "$mounts" = "" ]; then X mounts=`awk '/^\/dev\//{print $2}' /etc/mtab` Xfi X Xdate=`date "+%y%m%d_%H:%M"` # Date and time as yymmdd_hh:mm X X# Ignore nfs mounts by searching for lines that start with "/dev" Xdf $mounts | sed -n "/^\/dev/s%/dev/%$dev%p" | sort >/tmp/df.a$$ Xdf -i $mounts | sed -n "/^\/dev/s%/dev/%$dev%p" | sort >/tmp/df.b$$ X X# Join on first field, don't print mount point twice, make columns line up X(if [ "$noheader" = "" ]; then X echo "Filesystem iused ifree i% Mount kbytes used avail use As_of_$date" X fi Xjoin /tmp/df.b$$ /tmp/df.a$$ | sort +9) | awk \ X'{printf "%-12s%6s%7s %3s%8s%8s%8s%5s %s\n",$1,$2,$3,$4,$6,$7,$8,$9,$10}' X# Output is sorted alphabetically by mount point name X Xrm /tmp/df.a$$ /tmp/df.b$$ END_OF_FILE if test 1185 -ne `wc -c <'usr/local/admin/dump/df-i'`; then echo shar: \"'usr/local/admin/dump/df-i'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/df-i' # end of 'usr/local/admin/dump/df-i' fi if test -f 'usr/local/admin/dump/disk-usage' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/disk-usage'\" else echo shar: Extracting \"'usr/local/admin/dump/disk-usage'\" \(4643 characters\) sed "s/^X//" >'usr/local/admin/dump/disk-usage' <<'END_OF_FILE' X#!/bin/sh X# Name: /usr/local/admin/dump/disk-usage Author: Joe Smith X# Purpose: Creates a summary of disk usage on locally mounted disks. X# These summary files are included at the beginning of each 'dump' tape X# to make it easier to determine which tape contains a given directory. X X# This script is run daily around midnight and does the following: X# 1) Runs 'du' on each mounted disk and creates three files: X# "/var/admin/dump/du/$host.$device" lists all directories on the partition, X# "/mountpoint/.etc/du.$host" has the same information sorted with biggest X# users first, and "/mountpoint/.etc/du.$weekday" has summary of top-level X# directories. X# 2) Creates a file "/mountpoint/+$host+$device+" which includes the output X# from 'df' and the top 20 users. Note: The presence of this file X# in the top level directory of a partition means that it will be X# visible when doing a "restore i"; this makes it easy to verify X# that the dump tape you mounted is really the one you think it is. X# Since the file is 22 lines long, "cat /home/`hostname`/+*" works nicely. X# X# To run 'du' on the root parition and not have it go into any other X# partition, put the following into your /etc/fstab file: X# localhost:/ /mnt/root nfs rw,nosuid,hard,bg,intr 0 0 # for 'du' X# The "bg" is needed because the standard /etc/rc.local file does not X# start up rpc.mounted until much after "mount -vat nfs". X# X# See also: /usr/local/bin/df-i which combines "df" with "df -i" and "date". X XPATH=/usr/ucb:/usr/bin:/usr/etc; export PATH X Xadmindump=/var/admin/dump # Where to put "tapes.$host" report Xdudir=/var/admin/dump/du # Where to store output from 'du' Xdfi=/usr/local/bin/df-i # To list % inodes and timestamp Xlsf=/usr/local/bin/lsf # Program to create filename database Xestimate=/usr/local/admin/dump/estimate.8mm # Reports tapes to do a dump X Xif [ -x $dfi ]; then DF=$dfi; else DF="df"; fi # Use 'df-i' if it exists Xif [ -x $estimate ]; then EST="$estimate 0"; else EST=$df; fi Xhost=`hostname` # Files are stored as /mountdir/.etc/du.$host Xweekday=`date +%a` # Sun though Sat Xtmp=/tmp/disk-usage.$$ X Xdate # Send timestamp to stdout Xmkdir -p $dudir # This does nothing if directory already exists X$DF >$dudir/$host.all # List % disk space used and % inodes used X X# Format of /etc/mtab: "/dev/xd0e /var 4.2 rw,grpid,dev=0a04 1 3" X# Don't process any disk that is mounted read-only (such as the CD-ROM). X Xegrep '4\.2|localhost|vbfs' /etc/mtab | grep -v 'ro,' | \ Xwhile read dev mount other Xdo # The 'egrep' filters out everything but local disks. X device=`basename $dev` # xd0a, sd0a, id000a, etc X if [ $mount = / ]; then X rootdev=$device # Remember for later X continue # root is handled as "localhost:/" X else X outdir=$mount/.etc X fi X case $dev in X localhost:/) outdir=/.etc device=$rootdev ;; X localhost:*) continue ;; # Ignore loopback file systems X esac X X [ -d $outdir ] || mkdir -p $outdir # Create the .etc directory if needed X out=${outdir}/du.$host X summary=$dudir/$host.$device X plusfile="+$host+$device+" # Recognizable name for "restore -ivs" X $DF $outdir # Show name of partition to stdout X X # Create a 'du' (disk usage) report. This can take a while. X X if [ $mount = /var ]; then a="-a"; else a=""; fi # List all /var files X cd $mount X du $a . >$summary 2>/dev/null # Summarize all subdirectories X X # Create a list of all files on the partition, if wanted. The 'lsf' X # program will remove 'core' and '.nfs*' files more than a week old. X # It replaces both of the usual crontab entries: X # 0 0 * * * find / -type nfs -prune -o -name core -mtime +7 -exec rm {} \; X # 0 2 * * * find / -type nfs -prune -o -name .nfs\* -mtime +7 -exec rm {} \; X # (Use /usr/local/admin/updatedb.lsf to eliminate yet another "find /" job.) X X if [ -x $lsf ]; then # If /usr/local/bin/lsf exists X if [ -f $mount/.etc/$host.lsf ]; then X $lsf -xdev -rm_core -rm_nfs -output $mount/.etc/$host.lsf . X else X $lsf -xdev -rm_core -rm_nfs -brief . >/dev/null X fi X fi X X # Create the sorted summary of usage by directory. X X sort -n -r $summary -o $out # Numeric sort, biggest first X head -10 $out # List top 10 directories to stdout X $DF $outdir >$plusfile # Includes inodes and datestamp X head -20 $out >>$plusfile # List top 20 directorys to +host+dev+ X # Search for X grep ' \./[^/]*$' $summary | grep -v 'lost+found' | sort +1 | \ X sed "s%\.%$mount%" >$outdir/du.$weekday # List top-level directories X echo "" Xdone X X$EST | tee $admindump/tapes.$host # Number of tapes to do a dump X Xdate END_OF_FILE if test 4643 -ne `wc -c <'usr/local/admin/dump/disk-usage'`; then echo shar: \"'usr/local/admin/dump/disk-usage'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/disk-usage' # end of 'usr/local/admin/dump/disk-usage' fi if test -f 'usr/local/admin/dump/estimate.8mm' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/estimate.8mm'\" else echo shar: Extracting \"'usr/local/admin/dump/estimate.8mm'\" \(1592 characters\) sed "s/^X//" >'usr/local/admin/dump/estimate.8mm' <<'END_OF_FILE' X#!/bin/sh X# Name: /usr/local/admin/dump/estimate.8mm Author: Joe Smith X# Purpose: Determines how many tapes are required for today's dump X# Usage: "estimate 0" to calculate number of tapes for a level 0 dump. X Xif [ "$1" = "" ]; then X level=9 # Default is for an incremental save Xelse X level=$1; shift Xfi Xdisks="$*" # Default is all 4.2 partitions in /etc/mtab X Xif [ "$disks" = "" ]; then # Find 4.2 disks, excluding /dev/sr0 (/cdrom) X disks=`grep '4\.2' /etc/mtab | awk '!/dev\/sr[0-9]/ {print $1}'` Xfi X Xalldisks=`echo $disks | tr ' ' ','` # Comma separated list Xecho "# ($alldisks) 0% .00$level" # Show which partitions will be checked X X# Typical output from "dump bdsf9 112 54000 6000 /dev/null /usr" X# DUMP: Date of this level 0 dump: Fri Aug 7 01:21:41 1992 X# DUMP: Date of last level 0 dump: the epoch X# DUMP: Dumping /dev/rsd0g (/usr) to /dev/null X# DUMP: mapping (Pass I) [regular files] X# DUMP: mapping (Pass II) [directories] X# DUMP: mapping (Pass II) [directories] X# DUMP: estimated 333448 blocks (162.82MB) on 0.09 tape(s). X#** 'awk' will exit and stop the dump here X# DUMP: dumping (Pass III) [directories] X# DUMP: dumping (Pass IV) [regular files] X#** Pass IV can take up to 30 minutes, that's why dump needs to be stopped X Xfor disk in $disks Xdo # Break the pipe as soon as "estimated" is seen X p=`df $disk | tail -1 | awk '{print $5}` # Percent full X dump bdsf$level 112 54000 6000 /dev/null $disk &1 | \ X awk '/Dumping/{printf "%-12s %-16s %-4s ",$3,$4,"'$p'"}; \ X /estimated/{print $7;exit}' Xdone # This takes about 5 minutes per gigabyte END_OF_FILE if test 1592 -ne `wc -c <'usr/local/admin/dump/estimate.8mm'`; then echo shar: \"'usr/local/admin/dump/estimate.8mm'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/estimate.8mm' # end of 'usr/local/admin/dump/estimate.8mm' fi if test -f 'usr/local/admin/dump/make-autoback' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/make-autoback'\" else echo shar: Extracting \"'usr/local/admin/dump/make-autoback'\" \(1568 characters\) sed "s/^X//" >'usr/local/admin/dump/make-autoback' <<'END_OF_FILE' X#!/bin/perl X# Name: /usr/local/admin/dump/make-autoback Author: Joe Smith X# Purpose: Produces output for /etc/autobackup with the following format: X#device tapeset Fri/Sat Sun Mon Tue Wed Thu X#8mm2 set15 930618 X#8mm week4 930619 930620 930621 930622 930623 930624 X#8mm2 set01 930625 X#8mm week1 930626 930627 930628 930629 930630 930701 X X($incrmin,$incrmax,$incrdev) = ("week1","week4","8mm"); X($fullmin,$fullmax,$fulldev) = ("set01","set15","8mm2"); X$fullday = 5; # 0=Sun,1=Mon,2=Tue,3=Wed,4=Thu,5=Fri,6=Sat X X$full = $ARGV[0]; # Name of next full save tape X$full = $fullmax unless $full; X$incr = $ARGV[1]; # Name of next incremental save tape X$incr = $incrmax unless $incr; X Xsub yymmdd { X local($day) = @_; X local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($day); X return (sprintf("%02d%02d%02d",$year,$mon+1,$mday),$wday); X} X X$SecondsPerDay = 24 * 60 * 60; X$StartDay = int(time/$SecondsPerDay)-1; Xdo { # Skip forward to date of next full save X ($yymmdd,$wday) = &yymmdd(++$StartDay * $SecondsPerDay); X} until $wday == $fullday; X Xprint "device\tTapeset\tFri/Sat Sun Mon Tue Wed Thu\n"; Xfor ($i=$StartDay; $i<$StartDay+365; $i++) { X ($yymmdd,$wday) = &yymmdd($i*$SecondsPerDay); X if ($wday != $fullday) { # If this is not the day to do a full save X push(@days,$yymmdd); # then save this date for later X } else { X print "$incrdev\t$incr\t@days\n" if @days; X print "$fulldev\t$full\t$yymmdd\n"; X @days = (); X $incr = $incrmin if ++$incr gt $incrmax; X $full = $fullmin if ++$full gt $fullmax; X } X} END_OF_FILE if test 1568 -ne `wc -c <'usr/local/admin/dump/make-autoback'`; then echo shar: \"'usr/local/admin/dump/make-autoback'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/make-autoback' # end of 'usr/local/admin/dump/make-autoback' fi if test -f 'usr/local/admin/dump/make-shar' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/make-shar'\" else echo shar: Extracting \"'usr/local/admin/dump/make-shar'\" \(937 characters\) sed "s/^X//" >'usr/local/admin/dump/make-shar' <<'END_OF_FILE' X#!/bin/csh X# Name: /usr/local/admin/dump/make-shar Author: Joe Smith X# Purpose: Creates a shell-archive of the backup scripts. X Xset doc=usr/local/admin/dump/backup.doc Xset tmp=/tmp/backup.shar Xcd / # Use pathnames relative to root X Xtouch etc/admin/dump/\#make-shar Xrm -f usr/local/admin/*/\#* etc/admin/*/\#* # Get rid of old editor files Xset files=(usr/local/admin usr/local/admin/dump usr/local/admin/restore \ X usr/local/admin/{dump,restore}/* etc/admin etc/admin/dump \ X etc/admin/dump/{candidates,proprietary,schedule.{alpha,beta,gamma}}) Xset files=(`echo $files | sed s:${doc}::`) # Doc file is outside of shar X Xls -lL $doc | tee $tmp Xecho -n "The shar (shell archive) starts " >>$tmp Xecho `wc -l <$doc` "lines into this message." >>$tmp Xcat $doc >>$tmp Xecho "" >>$tmp Xecho "---------------- cut here ----------------" >>$tmp Xls -ldL $files Xshar $files >>$tmp Xecho ""; echo " SHAR file is now in $tmp" Xecho ""; ls -l $tmp END_OF_FILE if test 937 -ne `wc -c <'usr/local/admin/dump/make-shar'`; then echo shar: \"'usr/local/admin/dump/make-shar'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/make-shar' # end of 'usr/local/admin/dump/make-shar' fi if test -f 'usr/local/admin/dump/retrieve' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/dump/retrieve'\" else echo shar: Extracting \"'usr/local/admin/dump/retrieve'\" \(4157 characters\) sed "s/^X//" >'usr/local/admin/dump/retrieve' <<'END_OF_FILE' X#!/bin/perl X# Name: /usr/local/admin/dump/retrieve Author: Joe Smith X# Purpose: Reads tapes created by /usr/local/admin/dump/backup X X# 08/06/92 Removed blocking factor - 'restore' does the right thing without it. X# 08/24/92 Added "8mm2" for /dev/rst2. X X$myTape = $ARGV[0]; # Device type, "8mm", "6250", etc X$tapehost = $ARGV[1]; # Hostname to restore from (optional) X$mountdir = $ARGV[2]; # Where to restore the files (optional) X Xdie "Usage: $0 device [tapehost [mountpoint] ]\n" . X " eg. $0 8mm gemini\n" if $myTape eq ""; X X$ETC = "/etc/admin"; # /etc files X$USR = "/usr/local/admin"; # /usr files X$VAR = "/var/admin"; # /var files X$PAGER = "/usr/ucb/more"; # For displaying TOC X X$candidates = "$ETC/dump/candidates"; # candidates X$schedule = "$ETC/dump/schedule"; # schedule (.$candidate) X$restore = "$USR/restore"; # restore scripts X$toc = "$VAR/dump"; # save toc files here X@restoredir = ("/home/restore", "/var/tmp/restore"); # where to restore X X X%Tapes = ( X# key dev X "st0", "st0", X "cart", "st0", X "8mm", "st0", X "8mm1", "st1", X "st1", "st1", X "8mm2", "st9", # Kludge for 'delta' and 'titan' X "st2", "st9", X "mt8", "mt8", X "6250", "mt8", X "mt0", "mt0", X "1600", "mt0", X); X X# $ENV{"PAGER"} is not used because 'less' does not exit automatically like X# 'more' does when given a file that fits on a single screen. X X$PAGER = "cat" if ! -x $PAGER; # Make sure that the pager program exists X X# Select an appropriate directory to restore the files into. X# This will avoid overwriting existing files unless explicitly asked to. X X$mode = "i"; # Default is interactive restore Xif ("$mountdir" eq "") { # If no directory specified, X for (@restoredir) { # from one of the standard places. X $mountdir = $_; X last if -d $_; # Select the first one that exists X } X if (! -d $mountdir) { # If none exist, use last one X mkdir("$mountdir",0777) && print "Created $mountdir\n"; X } X print "No mount point specified, defaulting to $mountdir\n"; X $showdir = "du"; # List all subdirectories that get extracted X} else { X $showdir = "ls -lgd"; # List only top level if explicit directory X die "No such directory $mountdir\n" if (! -d $mountdir); X print "You have specified $mountdir as the place to restore files.\n"; X system("df $mountdir"); X print "Do you wish to restore the entire disk partition? (y/n) "; X $_ = ; X $mode = "r" if /[yY]/; X} Xchdir($mountdir) || die "Could not 'cd' to $mountdir"; X$mountdir = `pwd`; # Resolve symbolic link (if any) X X# if illegal tape device die before going on [MORE WORK NEEDED HERE] X$TAPE = $Tapes{ $myTape } X || die "Device must be one of: " . join(" ",keys(%Tapes)) . "\n"; X Xchop($thishost = `hostname`); X$tapehost = $thishost if "$tapehost" eq ""; X$rsh = ""; $rsh = "rsh $tapehost " if $tapehost ne $thishost; X$remotetape = ""; $remotetape = "$tapehost:" if $tapehost ne $thishost; X X# Read table of contents X# X# Be sure tape is rewound Xprint "Please insert the desired backup tape in /dev/r$TAPE on $tapehost.\n"; Xprint "Type when ready. Waiting..."; X$foo = ; # Wait for cr X Xprint "Reading Table of Contents from tape...\n"; Xsystem("$rsh mt -f /dev/r$TAPE rewind"); X X# Read first part of Table of Contents from first file on dump tape. Xsystem("$rsh sed /End.of.Tape/,999d /dev/r$TAPE | $PAGER"); # Rewind tape after X X# The following statement should not be necessary, but if you are running X# SunOS-4.1.1 and have not installed SCSI patch 100280-02, then the system X# will crash with "panic: psig action". Xsystem("$rsh mt -f /dev/r$TAPE rewind"); # Force an extra rewind X Xprint "\nEnter the number of the desired file system: "; X$ssn = ; # Get saveset number X Xprint "\nSearching tape for requested file system. This takes some time.\n"; Xprint "Use 'ls', 'add', and 'extract' commands.\n" if "$mode" eq "i"; Xprint "cd $mountdir\n"; X$foo = "/usr/etc/restore $mode"."vfs $remotetape/dev/r$TAPE $ssn"; Xprint $foo; $status=system($foo); Xprint "Rewinding\n"; Xprint "Files restored to: $showdir $mountdir\n"; Xsystem("$showdir $mountdir"); # Show where files have were restored Xexit $status; END_OF_FILE if test 4157 -ne `wc -c <'usr/local/admin/dump/retrieve'`; then echo shar: \"'usr/local/admin/dump/retrieve'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/dump/retrieve' # end of 'usr/local/admin/dump/retrieve' fi if test -f 'usr/local/admin/restore/install_unbundled' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/restore/install_unbundled'\" else echo shar: Extracting \"'usr/local/admin/restore/install_unbundled'\" \(1088 characters\) sed "s/^X//" >'usr/local/admin/restore/install_unbundled' <<'END_OF_FILE' X#! /bin/csh -fb X# Name: /usr/local/admin/restore/install_unbundled Author: Joe Smith X# Purpose: Ombudsman between extract_unbundled and restore_8mm. X X# /usr/etc/extract_unbundled will read the first file off the tape, show X# it to the user, and ask if the user wants to proceed. If yes, it X# goes to the /usr/tmp/unbundled directory and invokes 'tar' to extract X# the scripts from the second file on the tape (which should include X# the file "./install_unbundled"). Assuming that operation was a success, X# extract_unbundled then calls ./install_unbundled (this file). This X# file converts the command line arguments to what ./restore_8mm expects. X Xset remotehost="" Xset tapedevice=/dev/nrst0 Xwhile ("x$1" =~ x-*) X if ("x$1" =~ x-r*) set remotehost=`expr x$1 : 'x-r\(.*\)'` X if ("x$1" =~ x-d*) set tapedevice=/dev/nr`expr x$1 : 'x-d\(.*\)'` X if ("x$1" =~ x-f*) set forced=-f X shift Xend Xecho ./restore_8mm $forced $tapedevice $remotehost X./restore_8mm $forced $tapedevice $remotehost Xif ($cwd =~ */tmp/*) then X rm $0; exit 0 # Delete /var/tmp/unbundled/install_unbundled Xendif END_OF_FILE if test 1088 -ne `wc -c <'usr/local/admin/restore/install_unbundled'`; then echo shar: \"'usr/local/admin/restore/install_unbundled'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/restore/install_unbundled' # end of 'usr/local/admin/restore/install_unbundled' fi if test -f 'usr/local/admin/restore/read_contents' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/restore/read_contents'\" else echo shar: Extracting \"'usr/local/admin/restore/read_contents'\" \(4994 characters\) sed "s/^X//" >'usr/local/admin/restore/read_contents' <<'END_OF_FILE' X#!/bin/csh X# Name: /usr/local/admin/restore/read_contents Author: Joe Smith X# Purpose: Creates a list of all files on a dump tape using "restore tv". X X# Each day's save has a table-of-contents file, a 'tar' save, and N 'dump' X# saves. The table-of-contents file is parsed to determine the value for N. X# The saves for several days may be appended on the tape. After the X# contents have been read, the tape is positioned such that additional X# saves may be appended. X X# Usage: read_contents -v $TAPE /var/admin/dump/toc N X Xset listfiles=0 # Default is to list only directories Xif ("x$1" == "x-v") then X set listfiles=1; shift # Use "-v" to list all the saved files Xendif Xif ("$1" != "") setenv TAPE "$1" Xif ($?TAPE == 0) setenv TAPE /dev/nrst0 # Default tape device Xset dir=/var/admin/dump/toc # Change this if needed Xif ("$2" != "") set dir=$2 Xset maxfile=9999 # Read to end of tape Xif ("$3" != "") then X set maxfile=$3 # File number where to stop reading X if ($maxfile =~ ?) set maxfile=0$maxfile X echo "Highest tape file number expected = $maxfile" Xendif X Xif (! -d $dir) mkdir $dir Xcd $dir && echo "Changing current directory to $dir" X Xset first="" Xset retries=0 Xwhile ("$first" == "") X @ retries++ X if ($retries > 7) then X echo "$0: unable to read contents from tape - aborting" X exit 1 X endif X echo "Rewinding tape $TAPE" X mt -f $TAPE rewind X sleep ${retries}0 # Sleep 10 seconds, then 20 seconds, etc X set first=`head -1 $TAPE` # Set "week1" Tape "gnsmp-daily" written Xend X Xecho "" Xset tapename=`echo $first[2].$first[4] | sed 's/"//g'` Xmkdir -p $tapename Xset summary=$tapename/00 Xecho "Contents of $TAPE as of `date`" >$summary Xecho "$first" | tee -a $summary; echo "" >>$summary Xmt -f $TAPE rewind # Go back to beginning of tape Xset i=0 Xecho "$summary date level host:disk mount directories/files" | tee -a $summary X Xalias tapefile 'echo $tapestat | sed -e "s/.*file no= \([0-9]*\).*/\1/"' Xalias set_i 'set tf=`tapefile`; @ i = $tf + 1; if ($i < 10) set i=0$i' X Xwhile($i <= $maxfile) # Loop through each day on tape X set tapestat=`mt -f $TAPE status` X if ("$tapestat" =~ *EOT*) goto eot X set reason="Interrupt:" X onintr quit X set_i # Set $i to dump save number X X set file=$tapename/$i; echo -n "$file " X cp $TAPE $file # Table of contents X set last=`grep '^[0-9].*lvl' $file | tail -1 | sed 's/\([0-9]*\).*/\1/' ` X if ($last > $i) then X @ first = $i + 2 # i+0 = contents, i+1 = tar save X if ($first < 10) set first="0$first" X else X set first=`grep '^[0-9].*lvl' $file | head -1 | sed 's/\([0-9]*\).*/\1/' ` X endif X echo " Contents for savesets $first-$last" X echo "$file Contents for savesets $first-$last" >>$summary X X set tapestat=`mt -f $TAPE status` X if ("$tapestat" =~ *EOT*) goto eot X set_i X if ($i > $maxfile) break X set file=$tapename/$i; echo -n "$file " X tar tvifb $TAPE 112 >& $file # "install_unbundled" restore scripts X if ($status != 0) then X set tapestat=`mt -f $TAPE status | tee -a $file` X if ("$tapestat" =~ *EOT* || "$tapestat" =~ *blank*) rm $file X echo "End of tape $TAPE as of `date`" >>$summary X goto eot X endif X set wc=`wc -l <$file` X echo " 'tar' save with $wc files (scripts for restore)" X echo "$file 'tar' save with $wc files (scripts for restore)" >>$summary X set_i X mt -f $TAPE asf $i # Skip to end of tar file X X set dumpfiles=1 X while ($dumpfiles) # Loop through all parts of daily save X set tapestat=`mt -f $TAPE status` X set_i # Set $tf and $i X if ($i > $last) then X set dumpfiles=0 # Switch to reading contents again X break X endif X set file=$tapename/$i; echo -n "$file " X restore tvf $TAPE >$file X if ($status == 0) then X set dirs=`grep -c '^dir' $file` # Number of directories save to tape X set files=`grep -c '^leaf' $file` # Number of nondirectories saved X if ($listfiles == 0) then X grep -v '^leaf' $file >$file.tmp X sed 's/^dir *[0-9]*./dir /' $file.tmp >$file X rm -f $file.tmp X endif X # Look for "Dump date: Day Mon dd hh:mm:ss yyyy" X set dd=(`head $file | grep 'Dump *date:'`) # Date dump was taken X if ($#dd > 6) then # "Level 0 dump of / on tardis:/dev/sd0a" X set dl=(`head $file | grep 'Level . dump'` . . . . . . .) X # month day year level host:disk mount X set temp="$dd[4] $dd[5] $dd[7] $dl[2] $dl[7] $dl[5] $dirs/$files" X else X set temp="`wc -l <$file` lines" # Should never get here X endif X echo "$temp" X echo "$file $temp" >>$summary X mt asf $i # Skip to start of next file X else X /usr/5bin/echo '...retrying...\r\c' X mt -f $TAPE asf $tf # Go back to start of current file X set dumpfiles=0 # To read TOC next X endif X end # End loop through 'dump' files Xend # End loop through multi-day save X Xeot: Xmt -f $TAPE asf $tf # Position tape to where it can be written to Xset reason="End of tape:" Xquit: Xecho "$reason $tapestat" END_OF_FILE if test 4994 -ne `wc -c <'usr/local/admin/restore/read_contents'`; then echo shar: \"'usr/local/admin/restore/read_contents'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/restore/read_contents' # end of 'usr/local/admin/restore/read_contents' fi if test -f 'usr/local/admin/restore/restore_8mm' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'usr/local/admin/restore/restore_8mm'\" else echo shar: Extracting \"'usr/local/admin/restore/restore_8mm'\" \(2398 characters\) sed "s/^X//" >'usr/local/admin/restore/restore_8mm' <<'END_OF_FILE' X#! /bin/csh -fb X# Name: /usr/local/admin/restore/restore-8mm Author: Joe Smith X# Purpose: Automates restoring files from an 8mm with multiple file systems. X# Note: This is a stripped-down equivalent of /usr/local/admin/dump/retrieve. X# This script does not require /bin/perl or /usr/local/bin/perl, X# and therefore is suitable for restoring /usr/local or all of /usr. X Xset path=(/usr/ucb /usr/bin /usr/etc) Xset tape=/dev/nrst0 # Default if not specified on command line Xset host="" # " " " Xset restoredir=/home/restore # " " " Xset pager=/usr/ucb/pager # This works better than 'less' in this case Xif (! -x $pager) set pager=cat Xif (! -d $restoredir) set restoredir=/var/tmp/restore Xset mounted=no # Set to "yes" if tape is known to be online Xset showdir=du Xif ("x$1" == "x-f") then X set mounted=yes; shift # If called via install_unbundled Xendif Xif ("$1" != "") set tape=$1 Xif ("$2" != "") set host=$2 Xif ("$3" != "") set restoredir=$3 showdir="ls -lgd" Xif ("$host" != "") then X set hosttape=${host}:$tape X set host="rsh $host" Xelse X set hosttape=$tape Xendif Xif (! -d $restoredir) then X if ("$restoredir" =~ /var/tmp/*) then X mkdir -p $restoredir && echo "Created $restoredir" X else X echo "Directory $restoredir does not exist" X exit 1 X endif Xendif X X# Xif ($mounted == yes) then X if (-d du) then X echo "The files in $cwd/du may be helpful in locating directories:" X ls du X else X echo "Cannot find the 'du' files in $cwd/du, proceeding" X endif Xelse X echo "Please mount the desired backup tape on $hosttape" X echo "Type when ready. Waiting..." X set skip = $< Xendif X Xrepeat 4 echo "" Xecho "The following file systems are available on this dump tape:" X$host mt -f $tape rewind Xecho "" X$host $pager $tape X$host mt -f $tape rewind Xecho "" Xecho -n "Enter the number of the desired file system: " Xset skip = $< X# Xecho "SEARCHING DUMP CARTRIDGE...PLEASE BE PATIENT...THIS TAKES A LONG TIME..." Xecho "(Type 'ls' at the 'restore>' prompt to verify tape directory.)"; echo "" Xset echo Xcd $restoredir Xset restoredir=`pwd` # In case of symbolic link Xrestore ivfs $hosttape $skip Xunset echo Xecho ""; echo "The files have been restored to:" X$showdir $restoredir # Show disk usage if to default dir Xecho -n "Rewinding $hosttape ..." X$host mt -f $tape rewind Xecho " done" Xif (-f /usr/5bin/banner) then X /usr/5bin/banner Remove Tape Xelse X echo "REMOVE TAPE" Xendif END_OF_FILE if test 2398 -ne `wc -c <'usr/local/admin/restore/restore_8mm'`; then echo shar: \"'usr/local/admin/restore/restore_8mm'\" unpacked with wrong size! fi chmod +x 'usr/local/admin/restore/restore_8mm' # end of 'usr/local/admin/restore/restore_8mm' fi if test ! -d 'etc/admin' ; then echo shar: Creating directory \"'etc/admin'\" mkdir 'etc/admin' fi if test ! -d 'etc/admin/dump' ; then echo shar: Creating directory \"'etc/admin/dump'\" mkdir 'etc/admin/dump' fi if test -f 'etc/admin/dump/candidates' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'etc/admin/dump/candidates'\" else echo shar: Extracting \"'etc/admin/dump/candidates'\" \(535 characters\) sed "s/^X//" >'etc/admin/dump/candidates' <<'END_OF_FILE' X# Name: /etc/sysadm/dump/candidates Author: Carl Baltrunas X# Purpose: Used by /usr/sysadm/dump/backup to get a list of hosts to dump. X# Format: "groupname" "list of hosts" X X# Fremont, CA Xpublic delta titan Xprivate tymload tymgen Xseta delta Xsetb titan Xsetc tymload tymgen X X# Temporary HACK to avoid operator error Xtymload tymload tymgen Xtymgen tymload tymgen X X# Norristown, PA Xbackup1 boomer flyer Xbackup2 charger X X# San Jose, CA Xtso tardis doctor romana borusa Xgnsmp tardis doctor romana borusa Xall tardis doctor romana borusa X END_OF_FILE if test 535 -ne `wc -c <'etc/admin/dump/candidates'`; then echo shar: \"'etc/admin/dump/candidates'\" unpacked with wrong size! fi # end of 'etc/admin/dump/candidates' fi if test -f 'etc/admin/dump/proprietary' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'etc/admin/dump/proprietary'\" else echo shar: Extracting \"'etc/admin/dump/proprietary'\" \(401 characters\) sed "s/^X//" >'etc/admin/dump/proprietary' <<'END_OF_FILE' X+-----------------------------------------------------------------------------+ X| Proprietary rights of BT North America are included in files stored on this | X| tape. The contents of this tape are to be used for backup and recovery | X| purposes only. Any other use is a violation of BTNA guidelines. (c) 1993 | X+-----------------------------------------------------------------------------+ X END_OF_FILE if test 401 -ne `wc -c <'etc/admin/dump/proprietary'`; then echo shar: \"'etc/admin/dump/proprietary'\" unpacked with wrong size! fi # end of 'etc/admin/dump/proprietary' fi if test -f 'etc/admin/dump/schedule.alpha' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'etc/admin/dump/schedule.alpha'\" else echo shar: Extracting \"'etc/admin/dump/schedule.alpha'\" \(106 characters\) sed "s/^X//" >'etc/admin/dump/schedule.alpha' <<'END_OF_FILE' Xlocaltape 8mm=st0 # schedule.alpha X# alpha is diskless - this file exists only to define 'localtape'. END_OF_FILE if test 106 -ne `wc -c <'etc/admin/dump/schedule.alpha'`; then echo shar: \"'etc/admin/dump/schedule.alpha'\" unpacked with wrong size! fi # end of 'etc/admin/dump/schedule.alpha' fi if test -f 'etc/admin/dump/schedule.beta' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'etc/admin/dump/schedule.beta'\" else echo shar: Extracting \"'etc/admin/dump/schedule.beta'\" \(1039 characters\) sed "s/^X//" >'etc/admin/dump/schedule.beta' <<'END_OF_FILE' Xlocaltape cart=st8 8mm=alpha:st0 8mm2=gamma:st8 # schedule.beta X X#dev days level tape-name list of partitions X8mm smtwt.s 0 tso-daily sd0a:root sd3a:misc3a X8mm smtwt.s 5 tso-daily sd0g:usr sd3g:local sd3h:home/beta X8mm .....f. 0 tso-tape2 sd0a:root sd3a:misc3a X8mm .....f. 0 tso-tape2 sd0g:usr sd3g:local sd3h:home/beta X8mm2 smtwt.s 0 tso-daily sd0a:root sd3a:misc3a X8mm2 smtwt.s 5 tso-daily sd0g:usr sd3g:local sd3h:home/beta X8mm2 .....f. 0 tso-full sd0a:root sd3a:misc3a X8mm2 .....f. 0 tso-full sd0g:usr sd3g:local sd3h:home/beta X Xcart smtwt.s 0 tso-daily sd0a:root sd3a:misc3a Xcart smtwt.s 5 tso-daily sd0g:usr sd3g:local sd3h:home/beta Xcart .....f. 0 beta-0 sd0a:root sd3a:misc3a Xcart .....f. 0 beta-usr sd0g:usr # 3.10 tapes Xcart .....f. 0 beta-local sd3h:home/beta # 7.86 tapes X Xc150 smtwt.s 0 tso-daily sd0a:root sd3a:misc3a Xc150 smtwt.s 5 tso-daily sd0g:usr sd3g:local sd3h:home/beta Xc150 .....f. 0 beta-0 sd0a:root sd3a:misc3a Xc150 .....f. 0 beta-usr sd0g:usr # 1.24 tapes Xc150 .....f. 0 beta-local sd3h:home/beta # 3.14 tapes END_OF_FILE if test 1039 -ne `wc -c <'etc/admin/dump/schedule.beta'`; then echo shar: \"'etc/admin/dump/schedule.beta'\" unpacked with wrong size! fi # end of 'etc/admin/dump/schedule.beta' fi if test -f 'etc/admin/dump/schedule.gamma' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'etc/admin/dump/schedule.gamma'\" else echo shar: Extracting \"'etc/admin/dump/schedule.gamma'\" \(925 characters\) sed "s/^X//" >'etc/admin/dump/schedule.gamma' <<'END_OF_FILE' Xlocaltape 8mm2=st10 8mm=alpha:st0 cart=beta:st8 c150=delta:st8 # schedule.gamma X X#dev days level tape-name list of partitions X8mm smtwt.s 0 tso-daily sd0a:root sd0d:var X8mm smtwt.s 5 tso-daily sd0g:usr sd0h:home/gamma X8mm smtwt.s 5 tso-daily sd2a:export sd2h:production X8mm smtwt.s 5 tso-daily sd1a:home/testing sd1h:misc4h X8mm .....f. 0 tso-tape1 sd0a:root sd0d:var X8mm .....f. 0 tso-tape1 sd0g:usr sd0h:home/gamma X8mm .....f. 0 tso-tape1 sd2a:export sd2h:production X8mm .....f. 0 tso-tape2 sd1a:home/testing sd1h:misc4h X X8mm2 smtwt.s 0 tso-daily sd0a:root sd0d:var X8mm2 smtwt.s 5 tso-daily sd0g:usr sd0h:home/gamma X8mm2 smtwt.s 5 tso-daily sd2a:export sd2h:production X8mm2 smtwt.s 5 tso-daily sd1a:home/testing sd1h:misc4h X8mm2 .....f. 0 tso-full sd0a:root sd0d:var X8mm2 .....f. 0 tso-full sd0g:usr sd0h:home/gamma X8mm2 .....f. 0 tso-full sd2a:export sd2h:production X8mm2 .....f. 0 tso-full sd1a:home/testing sd1h:misc4h X END_OF_FILE if test 925 -ne `wc -c <'etc/admin/dump/schedule.gamma'`; then echo shar: \"'etc/admin/dump/schedule.gamma'\" unpacked with wrong size! fi # end of 'etc/admin/dump/schedule.gamma' fi echo shar: End of shell archive. exit 0 -- Joe Smith (408)922-6220 BTNA GNS Major Programs, TYMNET Global Network P.O. Box 49019, MS-C51, San Jose, CA 95161-9019 CA license plate: "POPJ P," Married to the LB, Quantum Leap's #1 net.fan PDP-10, 36-bits forever! Humorous disclaimer: "My Amiga 3000 speaks for me."