MakeIndex: a tape utility
by Arthur Haigh

I'm fond of my backup tapes. They have saved the day more than just once. The problem I have, however, is not in making the backup tapes, but in keeping track of what's on them and when they were made. I'm sure I'm not the only systems administrator that has a pile of mystery tapes lying around. To help me keep that pile manageable, I wrote the MakeIndex script.
 

What's an index?

My backup scripts are similar to those presented in "Practical backups for the small Solaris system," and "No-brainer backup,"  issues. The scripts create one ufsdump file per file system and sequentially put them onto tape. In this article, I'll present a short Bourne shell script, called MakeIndex, that will take a tape that has been created with multiple ufsdump files and create an index of those files. The script doesn't create what the Solaris ufsrestore man page refers to as a table of contents. A table of contents is a list of every file and directory that's backed up within a ufsdump file. The MakeIndex script creates a list, including the name of each file system mount point, the date the dump was created, and the level of the dump.

The script is a hands-off program. One simply inserts a tape and executes the script. The index is written to standard output. The tape is automatically rewound and ejected when finished.

Creating the tape index

Execution of the MakeIndex script produces the output shown in Listing A. The script shows that the host europa had its root (/), /usr and /export/home filesystems dumped (with level 0 dump) on Thursday, February 18th at about 7:00 P.M. In addition, europa had the /var file system dumped at a level 2 dump on Thursday, February 18th. The line reading
Dumped from: Wed Feb 17 04:07:04 1999
indicates the date of the last lower level dump of /var. For a plethora of information on dump levels, refer to the man pages on ufsdump. You may have noticed that the file systems that had been dumped at level 0 produced the line:
Dumped from: the epoch
This indicates that there's no previous lower-level dump for this file system.

Listing A: Standard output from the execution of the MakeIndex shell script

# ./MakeIndex

File: 0
Dump   date: Thu Feb 18 19:07:03 1999
Dumped from: the epoch
Level 0 dump of / on europa:/dev/dsk/c0t3d0s0

File: 1
Dump   date: Thu Feb 18 19:18:00 1999
Dumped from: the epoch
Level 0 dump of /usr on europa:/dev/dsk/c0t3d0s5

File: 2
Dump   date: Thu Feb 18 19:31:23 1999
Dumped from: the epoch
Level 0 dump of /export/home on europa:/dev/dsk/c0t3d0s6

File: 3
Dump   date: Thu Feb 18 19:51:53 1999
Dumped from: Wed Feb 17 04:07:04 1999
Level 2 dump of /var on europa:/dev/dsk/c0t3d0s7

File: 4
EOM

Picking it apart

The shell is shown in Listing B. Line 1 defines the shell as a Bourne shell. The variable TAPE is defined on line 7, and line 8 initializes the variable ERROR.

Listing B: The MakeIndex shell script

1       #!/bin/sh
2       #-------------------------------------------------------------
3       #
4       #  MakeIndex:  Creates an index for a tape in ufsdump format
5       #
6       #-------------------------------------------------------------
7       TAPE=/dev/rmt/0n
8       ERROR=0
9       
10      while [ $ERROR -eq 0 ]
11      do
12        FILENUM='mt -f $TAPE status | grep file | awk '{print $3 }' '
13        echo "\nFile: $FILENUM" 
14        echo "quit\c"|ufsrestore -ivf $TAPE 2>/dev/null|grep "ump"
15      #  echo "quit\c"|ufsrestore -ivf $TAPE 2>/dev/null|grep "ump "
16        ERROR=$?
17      done
18      echo "EOM"
19      mt $TAPE rewoffl &
20      exit
Typically, the backup consists of a series of dump files. The while loop will loop over the number of files. For the sake of simplicity, performance, and flexibility, the script doesn't determine the number of files to loop over before looping. Rather, the while loop continues as long as the value of the variable ERROR is zero. You can see in line 12 of Listing B that the file number of the first record is determined by pruning the file number from the output of the mt status command. The standard output from the mt command is piped to grep file and then further reduced by piping to the awk command. The result, a number indicating the current file position on the tape is assigned to the variable FILENUM. Line 13 echoes the file number to standard output.

The heart of the shell

Line 14 is the heart of the shell and, like line 12, jams many commands into this one line. At the heart of this line is the command:
ufsrestore -ivf $TAPE
You can see that the -ivf parameters are used. The -iv invokes the verbose and interactive modes. The f parameter indicates that we wish to read from the file represented by the variable TAPE. Remember, in UNIX, devices are files. We aren't really interested in using the interactive mode of ufsrestore, though. We use the interactive mode because, when it's invoked, the command generates a description of the dump file, which includes the filesystem that was dumped, the date of the dump, and the dump level. Unfortunately, the command gives us more information than we need, including a prompt for interactive use. Here's what it gives us:
# /usr/sbin/ufsrestore -ivf $TAPE
Verify volume and initialize maps
Media block size is 126
Dump   date: Thur Feb 18 19:18:00 1999
Dumped from: the epoch
Level 0 dump of /usr on europa:/dev/
=>dsk/c0t3d0s5
Label: none
Extract directories from tape
Initialize symbol table.
ufsrestore>
The ufsrestore command directs the prompt to standard error, which is, by default, represented by file number 2. You can see, in line 14 of Listing B, that the standard error is redirected to suppress the prompt.
ufsrestore -ivf $TAPE 2>/dev/null
To rid our index of unwanted information produced from the ufsrestore command, we can redirect the standard output to the grep command to pick out only the information of interest. We're interested only in lines that have the string dump in them. These include Dump, Dumped, and dump. We pipe the output to grep and search for these strings. We need to restrict our search string to pick out the string ump:
ufsrestore -ivf $TAPE 2>/dev/
=>null | grep "ump"
Since we invoked the interactive mode, we need to enter the quit command to ufsrestore's standard input. We can again use a pipe to redirect the output of the echo to the input of ufsrestore:
echo "quit\c"|ufsrestore -ivf $TAPE 2>/
=>dev/null|grep "ump"

Finishing up the loop

Immediately following the ufsrestore command is the assignment of the variable ERROR. Line 16 assigns the return code from the previous command issued using the built-in shell variable $?. If the ufsrestore command was successful, then a zero is returned and the while loop continues. If zero isn't returned, indicating an error, the while loop finishes. The error we foresee is when there are no more dump files to restore. When the ufsrestore command fails, we're finished with the loop. In line 18, I have the script echo EOM (for End of Media) to indicate that there are no more dump files on this tape. The mt command is then issued to run in detached mode (line 19). The tape is rewound and then ejected by the rewoffl option, which means rewind and take offline. Since the mt command is detached, the shell is free to exit without waiting for the rewind to finish.

Since I almost always perform level 0 dumps, I got tired of seeing the line

Dumped from: the epoch
If you're not interested in the dump level, or if you just don't like seeing the facetious reference to the epoch, you can comment out line 14 in Listing B and uncomment line 15. The difference between these lines is simply a space at the end of the string ump. The space eliminates the occurrence of the string containing Dumped in the MakeIndex output.

Conclusion

The MakeIndex script is simple, flexible, and versatile. Used as printed in Listing B, the script provides a hands-off utility for identifying and verifying the contents of your tapes. The commands can be incorporated at the end of a ufsdump backup script to verify the backup. You can be sure that the backup was successful because the MakeIndex program is reading the tape. Finally, you can redirect the standard output of the MakeIndex command to a file to create written records that can be filed or printed and attached to the tape. The ufsdump command is an excellent resource for creating backups. Coupled with this handy script, you'll be able to simplify and automate the creation, verification, and organization of your valuable tapes.

<<  Back to Tech Corner