Cover V02, I05
Article
Figure 1
Figure 2
Figure 3
Figure 4
Figure 5
Listing 1
Listing 2
Listing 3
Listing 4
Listing 5
Listing 6

sep93.tar


Listing 4: Fast.bu v2.0--Fast Backup Utility

1   # @(#) Listing 4 fast.bu v2.0    Fast Backup Utility
2   # Authors: Jon Alder/Ed Schaefer
3   #######################################################################
4   # This program creates a fast backup tape with the tape directory file being
5   # in volume 0 and each succeeding file system in the backup list in its
6   # own volume
7
8   # Set video variables
9   HI=`tput smso`
10  LO=`tput rmso`
11  CLEAR=`tput clear`
12  BLINK=`tput blink`
13
14  umask 000
15  # Usage Help
16  if [ $1 = "-z" ] ;then
17      echo "usage: fast.bu -c [config file] -l [file with the backup list ]" >&2
18      exit 0
19  fi
20
21  # Checking for two switches, defaulting if they are not there
22  # and breaking out after 5 seconds.
23  if [ x"$2" = x ] ;then
24     echo "fast.bu: argument error"                     >&2
25     $DELAY
26     echo $CLS
27     echo "usage: fast.bu  -c [config file] -l [file with the backup list ]" >&2
28     sleep 1
29     echo "\nSetting -c to $HI$PWD/config$LO and -l to $HI$PWD/backup_list$LO."
30     sleep 1
31     echo "\nPlease break in 5 seconds if that is not OK."
32     sleep 1
33     echo "\nContinuing in 5 seconds.\c"
34     sleep 1;echo ".\c";sleep 1;echo ".\c";sleep 1;echo ".\c";sleep 1;echo
".\c"
35  fi
36  CONFIG=$PWD/config
37  BACKUP_LIST=$PWD/backup_list
38
39  #set config and backup list switches
40  while [ $# -gt 0 ]
41  do
42      case $1 in
43      -c)     shift;CONFIG=$1
44              shift
45              ;;
46
47      -l)     shift;BACKUP_LIST=$1
48              shift
49              ;;
50
51      -c*)    CONFIG=`echo $1|cut -c3-`
52              shift
53              ;;
54
55      -l*)    BACKUP_LIST=`echo $1|cut -c3-`
56              shift
57              ;;
58
59      -*)     echo "Usage error"
60              echo "Usage: fast.bu  -c [config file] -l [file with the list to backup]" >&2
61              exit
62              shift
63              ;;
64
65      *)      echo "Usage error"
66              echo "Usage: fast.bu  -c [config file] -l [file with the list to backup]" >&2
67              exit
68              shift
69              ;;
70
71      esac
72  done
73  export CONFIG BACKUP_LIST
74
75  # Check and make sure the config and list files exist.
76  if [ -r "$CONFIG" ] ;then
77      continue
78  else
79      echo "The config file \"$CONFIG\" was not found. "
80      echo "Check to make sure that the path is correct and re-start."
81      echo "Exiting Fast.bu.";sleep 1;exit 1
82  fi
83  if [ -r "$BACKUP_LIST" ] ;then
84      continue
85  else
86      echo "The BACKUP_LIST file \"$BACKUP_LIST\" was not found. "
87      echo "Check to make sure that the path is correct and re-start."
88      echo "Exiting Fast.bu.";sleep 1;exit 1
89  fi
90
91  #######################################################################
92  # Set variables
93  #######################################################################
94  CURSOR=`grep cursor $CONFIG|cut -d : -f2`            ;export CURSOR
95  DELAY=`grep delay $CONFIG|cut -d : -f2`              ;export DELAY
96  FORWARD=`grep fsf $CONFIG|cut -d : -f2`              ;export FORWARD
97  KERNEL=`grep kernel $CONFIG|cut -d : -f2`            ;export KERNEL
98  PROG_DIR=`grep prog_dir $CONFIG|cut -d : -f2`        ;export PROG_DIR
99  CPIO_IN=`grep cpio_in $CONFIG|cut -d : -f2`          ;export CPIO_IN
100 CPIO_OUT=`grep cpio_out $CONFIG|cut -d : -f2`        ;export CPIO_OUT
101 REVERSE=`grep bsf $CONFIG|cut -d : -f2`              ;export REVERSE
102 REWIND=`grep rewind $CONFIG|cut -d : -f2`            ;export REWIND
103 SHELL=`grep shell $CONFIG|cut -d : -f2`              ;export SHELL
104 TAPE_CTRL=`grep tapecntrl $CONFIG|cut -d : -f2`      ;export TAPE_CTRL
105 TAPE_DRIVE=`grep tapedevr $CONFIG|cut -d : -f2`      ;export TAPE_DRIVE
106 TAPE_DRIVEN=`grep tapedevn $CONFIG|cut -d : -f2`     ;export TAPE_DRIVEN
107 WORKING_DIR=`grep working_dir $CONFIG|cut -d : -f2`  ;export WORKING_DIR
108
109 ########################################################################
110 # Initialize files
111 ########################################################################
112 cd /
113 cat /dev/null>$WORKING_DIR/tape.out
114 cat /dev/null>$WORKING_DIR/tape.BLOCKS
115 cat /dev/null>$WORKING_DIR/tape.report
116
117 echo "\n"
118 echo "Start time:  `date`">$WORKING_DIR/tape.time
119 date +%d%t%H%t%M > $WORKING_DIR/tape.dur
120
121 ########################################################################
122 # Preprocess commands before backup begins
123 ########################################################################
124 if [ -f $PROG_DIR/preprocess.bu ] ;then
125    for i in `cat $PROG_DIR/preprocess.bu`
126    do
127       echo "Running $i"
128       $SHELL "$i"
129    done
130 fi
131
132 ########################################################################
133 # First, write to tape the backup directory
134 ########################################################################
135 cp $BACKUP_LIST $WORKING_DIR/tape.directory
136 cd $WORKING_DIR
137 ls tape.directory|$CPIO_OUT>$TAPE_DRIVEN 2>$WORKING_DIR/tape.out
138 $DELAY
139 cd /  # backup is relative to root
140
141 ########################################################################
142 # Do the backup.....
143 # Check to see if the backup is being run by a user and if so display progress.
144 # We do this by executing tty and checking the exit status.
145 # If exit status returns 0 the user is running in the foreground.
146 ########################################################################
147 tty 1>/dev/null 2>/dev/null
148 if [ $? -eq 0 ]; then
149    for i in `cat $BACKUP_LIST`
150    do
151       # Check to see how many files will be backed up.
152       echo $CLEAR
153       echo "Preparing resources for $i."
154       HOW_MANY=`find $i -type f -print|wc -l`
155       echo $CLEAR
156       # Get the start time for this TFS
157       TFS_START=`date +%d%t%H%t%M`
158       date +%d%t%H%t%M >$WORKING_DIR/tfs_tape.start
159       # Put the backup (cpio) in the background
160       (find $i -type f -depth -print|$CPIO_OUT>$TAPE_DRIVEN 2>$WORKING_DIR/tape.out)&
161       while true
162       do
163          # Check to see if the backup of $i is still running
164          CPIO_PID=`ps|grep cpio|grep -v grep|awk '{ print $1 }'`
165          if [ x$CPIO_PID = "x" ] ;then
166            break
167          fi
168
169          # Calculate percentage complete
170          HOW_MUCH=`cat $WORKING_DIR/tape.out|grep -v blocks|wc -l`
171          # Since we may be waiting for the tape to complete its first backup we
172          # need to make sure that HOW_MUCH = at least 1 so awk doesn't fail.
173          if [ $HOW_MUCH -lt 1 ] ;then
174             HOW_MUCH=1
175          fi
176          PERCENT=` echo " " |awk '
177            {
178            }

179            END {  # no division by 0
180            printf("%d", (numer/denom) * 100)
181            } ' numer=$HOW_MUCH denom=$HOW_MANY`
182          TFS_NOW=`date +%d%t%H%t%M`
183
184          # Calculate the time so far
185          TIME_SO_FAR=`echo " "| awk '
186          {
187            {
188            split(arg1, tarr1)
189            split(arg2, tarr2)
190            time1 = (tarr1["1"] * 1440) + (tarr1["2"] * 60) + tarr1["3"];
191            time2 = (tarr2["1"] * 1440) + (tarr2["2"] * 60) + tarr2["3"];
192            sum = (time2 - time1) ;
193            }
194          }
195          END {printf("%d ",sum)
196          }' arg1="$TFS_START" arg2="$TFS_NOW"`
197
198          # Now estimate the time to completion.
199          ETTC=` echo " " |awk '
200             {
201             }
202             END {
203             printf("%d", (time/done) * (todo-done))
204             } ' time=$TIME_SO_FAR done=$HOW_MUCH todo=$HOW_MANY`
205
206          # Print to screen status information (Cursor will jump around a bit)
207          $CURSOR 0 0
208          echo "Currently backing up $i                                      \n"
209          echo "$HI Percent complete      Number files done           Number of files to backup    $LO"
210          $CURSOR 3 7;echo "$PERCENT%";$CURSOR 3 30;echo
"$HOW_MUCH";$CURSOR 3 60;echo "$HOW_MANY"
211          echo "$HI             Total time so far      Estimated time left to completion           $LO"
212          $CURSOR 5 20;echo "$TIME_SO_FAR min.  ";$CURSOR 5 50;echo "  $ETTC min.
"
213          $CURSOR 0 78
214       done  # end while loop
215       # Wait until done and then update statistics
216       $DELAY
217       NUMWROTE=`grep blocks $WORKING_DIR/tape.out`
218       echo "FOR $i I WROTE TO TAPE: $NUMWROTE" >>
$WORKING_DIR/tape.BLOCKS
219   done # end for loop
220
221   echo $CLEAR
222   echo "Finish time: `date`">>$WORKING_DIR/tape.time
223   date +%d%t%H%t%M >>$WORKING_DIR/tape.dur
224
225 # Or run the backup in the background....
226 else
227    for i in `cat $BACKUP_LIST`
228    do
229       find $i -type f -depth -print|$CPIO_OUT>$TAPE_DRIVEN 2>$WORKING_DIR/tape.out
230       $DELAY
231       NUMWROTE=`grep blocks $WORKING_DIR/tape.out`
232       echo "FOR $i I WROTE TO TAPE: $NUMWROTE" >>
$WORKING_DIR/tape.BLOCKS
233    done
234
235     echo "Finish time: `date`">>$WORKING_DIR/tape.time
236     date +%d%t%H%t%M >>$WORKING_DIR/tape.dur
237 fi
238
239 ########################################################################
240 # The reporting section.
241 ########################################################################
242 cat $WORKING_DIR/tape.time
243 echo "\n\n"
244
245 cat $WORKING_DIR/tape.BLOCKS | awk '
246    {
247       {
248       dd  = dd  + 1;
249       sum = sum + ($7 * .000512) + 1;
250       printf("%18s %12d\n", $2, ($7 * .000512) + 1);
251       }
252    }
253 END {printf("%28s \n","                   ------------");
254 printf("%d%9s %10d %s\n",dd, " Tape Sections    ", sum, "Total Megabytes
writen in this backup.")
255 }'>>$WORKING_DIR/tape.report
256
257 cat $WORKING_DIR/tape.dur | awk '
258   {
259      {
260      time1 = ($1 * 1440) + ($2 * 60) + $3;
261      getline;
262      time2 = ($1 * 1440) + ($2 * 60) + $3;
263      sum = (time2 - time1) / 60;
264      }
265   }
266   END {printf("%17s %13f %s\n"," ", sum, "Total hours for this backup.")
267  }'>>$WORKING_DIR/tape.report
268
269 grep Total $WORKING_DIR/tape.report > $WORKING_DIR/tape.rate
270
271 cat $WORKING_DIR/tape.rate | awk '
272    {
273       {
274       megs = $4;
275       getline;
276       time = $1;
277       rate = megs / time;
278       }
279    }
280    END {printf("%17s %13f %s\n"," ", rate, "Average MEG/hour for this
backup.")
281    }'>>$WORKING_DIR/tape.report
282 cat $WORKING_DIR/tape.report
283
284 #######################################################################
285 # Kernel backup
286 #######################################################################
287 #Backup the kernel and then rewind
288 if [ x$KERNEL = "x" ] ;then
289    $TAPE_CTRL $TAPE_DRIVE $REWIND 2>/dev/null
290 else
291    /bin/ls $KERNEL|$CPIO_OUT>$TAPE_DRIVE 2>$WORKING_DIR/tape.out
292 fi
293
294 ########################################################################
295 # Postprocess commands after backup ends
296 ########################################################################
297 if [ -f $PROG_DIR ] ;then
298    for i in `cat $PROG_DIR/postprocess.bu`
299    do
300       echo "Running $i"
301       $SHELL "$i"
302    done
303 fi
304
305 echo "\n\nThe backup is finished. Tape has been rewound."