SUMMARY: Dumping to 5GB 8mm tapes

From: Earl Zmijewski (
Date: Sat Dec 12 1992 - 03:37:18 CST

Original Question:

>We just purchased a 5GB 8mm tape drive from Sun and I (a novice)
>am trying to do dumps to it from various machines over the network.
>I should be able to dump every partition of every disk here to a
>single tape, but am having a problem. Here is what I am doing:
> For each disk partition on every machine do
> (from machine with disk partition to back up, I type)
> /usr/etc/rdump 0dsbfu 54000 13000 126 sun-with-tape:/dev/nrst8 /dev/sdxx
> (then from the machine with the tape, I type)
> mt eof
> end
>I thought that this would create consecutive dump files on the tape with
>eof marks in between. That way, I could use mt to move to the appropriate
>dump file and restore. However, the tape seems to only end up with the
>last two partitions that I've dumped (as if the tape had been rewound after
>the first n-2 dumps.) I am not rewinding the tape and the "n" in front of
>the "nrst8" should prevent dump from rewinding it.

>Can some kind soul tell me what I'm doing wrong? I'm assuming I can dump
>multiple partitions to the same tape. Do I need the eof marks? If not,
>how can I do the restore from the appropriate place? Is there anyway to
>automate the above procedure? Remember that I need to do this from several
>different machines (which of course must done consecutively).

As most of you noted, I didn't need to write an eof using mt, dump does this
for you. In fact, you don't need mt at all, since the -s option on restore
will allow you to skip over earlier dumps.

Another point is that "mt eof" will rewind the tape when it completes, if you
write to /dev/rst8, instead of /dev/nrst8. This is how I managed to overwrite
earlier dumps.

Thanks to all who wrote in and especially to those who included scripts to
automate all of this. I've included two of these, the first is a simple one
that is adequate for my purposes. The second is more elaborate.

Thanks again,

First, some suggestions for commericial products:

lemke@MITL.COM (Kennedy Lemke) writes:

Second, I'd *strongly* recommend you get the "mdump" software
from APUNIX ((800) 8-APUNIX). This software is really great
for doing network dumps--exactly what you're trying to do. You
get the software for free if you buy a tape drive from them;
it's probably several hundred dollars if you just want the software.

-------------------------------------------------------------- (Frank Allan (Network Mgr)) writes:

a better blocking factor for Exabytes is 2000 rather than 126.

For automating your backups have a look at FlashBack II (details
of supplier below) We use it to automatically backup multiple
small disks on assorted machines to the one tapedrive on our
server and it works a treat. It also has no trouble putting
multiple dumps on the one tape, and will prompt for a second tape
if required. It will also handle multiple tape devices and
multiple tapehosts, and it is all driven from a point and click
windowing interface, with automatic logging to a file and/or
email to selected persons. Also once it is installed, you don't
need root privileges to use it to modify backup schedules.

Supplier details:

Susan Butts - Technical Support
Rick Huhnke - Sales

email is

Pinnacle Micro
19 Technology
Irvine CA 92718

Ph: 714 727 330
Fax: 714 727 1913

Pricing is US$495 for 1-9 hosts
or US$1995 for unlimited hosts

And now for the scripts:
From: (Bill Morrow)
#!/bin/sh -f
# this script dumps the cns network.
# WMM 91-09-10
# for restarts.
# to restart at a failed dump set $StartFileNumber to the EOF count AFTER the failed
# for a complete dump, start at StartFileNumber=1


# $1 is the file number for this dump. It's used with $FileNumber to skip over
# successful dumps doing restarts
# $2 is the partition to dump
DoDump() {
        if [ $1 -ne $FileNumber ]
           echo "Not dumping file "$1
           echo "Dumping "$DUMPHOST$2
           /etc/dump $PARAMS $LENGTH $DRIVE $DENSITY $BLOCK_SIZE $2
           echo "Wrote EOF marker "$FileNumber
           FileNumber=`expr $FileNumber + 1`
           echo "----------------------------------------------------------"
           sleep 120

# $1 is as in DoDump
# $2 is the host being dumped
# $3 is as $2 in DoDump
DoRdump() {
        if [ $1 -ne $FileNumber ]
           echo "Not dumping file "$1
           echo "Dumping "$2":"$3" on "$DUMPHOST$DRIVE
           rsh $2 /etc/rdump $PARAMS $LENGTH $DUMPHOST$DRIVE $DENSITY $BLOCK_SIZE $3
           echo "Wrote EOF marker "$FileNumber
           FileNumber=`expr $FileNumber + 1`
           echo "----------------------------------------------------------"
           sleep 120

echo "Starting at "`date`
echo Rewinding...
/bin/mt -f $DRIVE rew
sleep 120
if [ "$StartFileNumber" -gt 1 ]
   echo "Restarting after EOF "$StartFileNumber
   mt fsf `expr $StartFileNumber - 1`
   sleep 120

# do all partitions on cns8 - file server
DoDump 1 /dev/sd2c
DoDump 2 /dev/sd1c
DoDump 3 /dev/sd0a
DoDump 4 /dev/sd0g

# do all partitions of cns16 - home file server
DoRdump 5 cns16 /dev/sd0a
DoRdump 6 cns16 /dev/sd0g
DoRdump 7 cns16 /dev/sd0h
DoRdump 8 cns16 /dev/sd1a

# do all partitions of cns1 - 386i master
DoRdump 9 cns1 /dev/roota
DoRdump 10 cns1 /dev/rootg
DoRdump 11 cns1 /dev/rooth

# only back up the root and files partitions of cns2 and cns3 since the
# usr partitions on these machines are copies of cns1's usr partition
DoRdump 12 cns2 /dev/roota
DoRdump 13 cns2 /dev/rooth
DoRdump 14 cns3 /dev/roota
DoRdump 15 cns3 /dev/rooth
# cns19 is mostly generic except that it has a larger files partition,
# which may be used to store application software or user files
# it holds the Windhorst group home files
DoRdump 16 cns19 /dev/sd0h

/bin/mt -f $DRIVE off

echo "Completed at "`date`

From: (Tim Hoogasian)

PATH=/bin:/etc:/usr/bin:/usr/ucb:/usr/etc ; export PATH
# PROGRAM: FlexDump (Bourne script - distributed under terms of GNU 'copyleft')
# AUTHOR : Tim Hoogasian (, or {...,uunet}!netcom!alc!hoogs )
# DATE : 25 NOV 92
# PURPOSE: FlexDump relieves the harried Sys/Network Admin of having to interact
# with the (painful) syntax of rdump. FlexDump automates the backup of
# a local Unix network (NIS or otherwise) automagically to any remote
# tapeserver, from any trusted host, by any trusted user (needn't be
# uid 0, but must be in dump group; dump group must be in root group).
# With no user-options specified, FlexDump will first determine network
# hosts, ensuring they're up and are rdump-capable Unix hosts. It will
# execute rdump for these hosts' local disk partition(s), dumping each
# host's data to a (presumed) DAT drive. FlexDump automatically screens
# out /, /usr, /tmp, /var partitions, and mounted cdroms or floppies.
# Using a "sliding window" technique, each dump-night a segment of the
# total number of local hosts is backed up with a level 0 dump; other
# hosts are dumped at level 5. The number of hosts to be level-0 dumped
# is specified by n = (<total # hosts> / <# dump nights>); the window
# moves along each night to the next n hosts in the list. A logfile of
# the progressing dumps is kept during dumping; after the final dump
# completes, this file is tarred to EOT (for purposes of tape self-
# documentation). FlexDump's many options allow for specification of
# (a) nodes to be dumped that are not normally done (e.g. fileservers),
# (b) alternate filesystems to be dumped, by name rather than device,
# (c) inclusion/exclusion lists of hostnames/hosttypes (e.g. hp, etc.),
# (d) alternate tapehosts, tape drives, dump options, etc.
# Backup hosts on local internet. Logic as follows:
# (1) Test to see if host is on net and up, via ping.
# (2) If ping succeeds, get remote machine's OS type (sun, hp, etc) via uname,
# to compare against a predetermined list of rdump-capable host OS-types.
# (3) Get dump partition list with df. (HPs seem only configured w/root part'n)
# (4) Using host/partition list, rdump each machine to (remote) tape drive.

USE="USAGE: `basename $0` "
USE=$USE"-h | -(n){ G | [bcdDHlLNoprRStTuxX] } (norew) <get tarfile> <blkfctr> "
USE=$USE"<rdump loc'n> <density> <day-of-week> <host(s)> <tapelen> <dumplvl> "
USE=$USE"<# dump nights> <dump opts> <part'n list> <add'l rdump-hosts> "
USE=$USE"<alt. rdump-hosts> <log-stamp> <tapedrive> <tapehost> <user> "
USE=$USE"<host(s)> <hosttype(s)>"

log=/tmp/dumplog.`date '+%a%h%d'` # daily dumplog
t_user=dumper # dumper != root ( ~ operator )
t_host=dumphost2 # DAT drive host alias
t_drive=/dev/nrst5 # rst8: 5 Gb; rst5: 2.3 Gb
week_lvl=0 # weekly backup level
day_lvl=5 # daily backup level
dflt_opts=undsbf # default rdump option flags
dens=54000 # tape density
t_len=6000 # tape length (2.3 Gb DAT)
blockfct=126 # block factor
server_hosts="prez lester alc" # default: not for fileservers
exclude_hostnames="localhost $server_hosts"
rdump_hosts="aix hp sun ultrix" # rdump-capable (predetermined)
dump_nights=5 # default: weeknights only
day_of_week=`date '+%w'` # 0=Sun, 1=Mon, ...
rdump_cmd=/etc/rdump # default rdump cmd
rew=on # dflt: rewind when dump done
# Process user flags. User may specify alternates for just about any preset
# variable in FlexDump, though of course combining certain flags may not make
# sense (e.g., -H 'some HP hostname' -X 'hp', etc). Note that since getopts
# processes flags left-to-right, later flags may override previously- specified
# command-line flag values. Also, no sanity-checks are done on user-flag
# values since, for instance, there is no way of knowing in advance the
# specific capabilities of any particular host, hosttype, tape drive, etc.
# More to the point, since the tool is designed to aid the sysadmin, presumably
# s/he isn't going to *try* to force it to break, e.g., by entering negative
# or zero values for the number of dump nights, tape length, density, etc. It
# checks for some degree of sanity while processing, but is not "bulletproof".

while getopts \?b:c:d:D:GhH:l:L:nN:o:p:r:R:S:t:T:u:x:X: flag ; do # user flags
   case $flag in
      b) blockfct=$OPTARG ;; # alt. block factor
      c) rdump_cmd=$OPTARG ;; # alt. rdump cmd location
      d) dens=$OPTARG ;; # alt. tape density
      D) day_of_week=$OPTARG ;; # alt. dump 'day-of-week'
      G) get_dump_tar_list=1 ;;
   \?|h) echo $USE
         echo ""
         echo "Dump Logfile : $log"
         echo "Tape User : $t_user"
         echo "Tape Host : $t_host"
         echo "Tape Drive : $t_drive"
         echo "Rdump Options : $dflt_opts"
         echo "Tape Density : $dens"
         echo "Tape Length : $t_len"
         echo "Block Factor : $blockfct"
         echo "Tape Rewind : $rew"
         echo "Day Of Week : $day_of_week"
         echo "Dump Nights (#) : $dump_nights"
         if [ "$exclude_hostnames" ]; then
            echo "Exclude Hosts : $exclude_hostnames"
         if [ "$exclude_hosttypes" ]; then
            echo "Exclude Types : $exclude_hosttypes"
         if [ "$full_machine_list" ]; then
            echo "Host Backup List: $full_machine_list"
         exit 1 ;;
      H) full_machine_list="$OPTARG" ;; # alt. host list for dump
      l) t_len=$OPTARG ;; # alt. tape length
      L) level=$OPTARG # alt. dump level
         alt_level_spec=1 ;;
      N) dump_nights=$OPTARG ;; # alt. # of nights-to-dump
      n) rew=off ;; # useful for appending
      o) dflt_opts=$OPTARG ;; # alt. dump options
      p) alt_part_list="$alt_part_list $OPTARG";;# alt. disk partition list
      r) rdump_hosts="$rdump_hosts $OPTARG" ;; # add'l rdump-hosts
      R) rdump_hosts="$OPTARG" ;; # substitute rdump-hosts list
      S) log=/tmp/`basename $OPTARG` ;; # alt. logfile stamp
      t) t_drive=$OPTARG ;; # alt. tape device
      T) t_host=$OPTARG ;; # alt. tape host
      u) t_user=$OPTARG ;; # alt. tape user
      x) exclude_hostnames="$exclude_hostnames $OPTARG" ;;
      X) exclude_hosttypes="$exclude_hosttypes $OPTARG" ;;

shift `expr $OPTIND - 1`
# If logfile doesn't yet exist (implying start of a brand new dump run) or user
# has requested retrieval of the tape-documenting tarfile, rewind tape drive.
# If new tape run, create logfile and continue; else, retrieve tarfile [if no-
# rewind set, leave tape positioned at the tarfile (EOM -1)] and exit.

if [ ! -f $log -o $get_dump_tar_list -eq 1 ]; then
   msg=`rsh $t_host -l $t_user /bin/mt -f $t_drive rew 2>&1`

   if [ "$msg" ]; then # tape command failed
      echo "Malfunction with $t_drive on $t_host"
      echo "(Err msg: $msg)"
      exit 2

   if [ $get_dump_tar_list -eq 1 ]; then # previously created dumptape
      echo "Seeking to EOM... Please be patient (this could take a while)."
      rsh $t_host -l $t_user /bin/mt -f $t_drive eom
      rsh $t_host -l $t_user /bin/mt -f $t_drive nbsf 1
      rsh $t_host -l $t_user /bin/dd if=$t_drive bs=20b | tar xvBfbp - 20

      if [ $rew = "off" ]; then # append more dumps @ EOT?
         rsh $t_host -l $t_user /bin/mt -f $t_drive eom
         rsh $t_host -l $t_user /bin/mt -f $t_drive nbsf 1
         rsh $t_host -l $t_user /bin/mt -f $t_drive rew
      exit 0 # no further processing
      echo "Dump logfile: $log" | tee $log # prepare for new dump(s)
      echo "Dump run begun: `date`" | tee -a $log
      echo "" | tee -a $log

# Ensure egrep "or" argument lists are separated by single `|' (pipe) chars.
# (Maybe overkill, but should fix pathological garbage separator cases.)
# (Look carefully - these are mostly identical, but not quite!)

rdump_hosts=`echo $rdump_hosts | \
   sed 's/^[^a-zA-Z0-9_\-]*//

exclude_hosttypes=`echo $exclude_hosttypes | \
   sed 's/^[^a-zA-Z0-9_\-]*//

exclude_hostnames=`echo $exclude_hostnames | \
   sed 's/^[^a-zA-Z0-9_\-]*//

alt_part_list=`echo $alt_part_list | \
   sed 's/^[^a-zA-Z0-9/_\-]*//
        s/[^a-zA-Z0-9/_\-][^a-zA-Z0-9_\-/]*/|/g'` # note: / is valid here

full_machine_list=`echo $full_machine_list | \
   sed 's/^[^a-zA-Z0-9_\-]*//
        s/[^a-zA-Z0-9_\-][^a-zA-Z0-9_\-]*/ /g'` # note: separated by spaces
if [ ! "$exclude_hosttypes" ]; then # non-null needed for checking
   exclude_hosttypes=" "

if [ ! "$full_machine_list" ]; then # if hosts not user-specified
   full_machine_list=`ypcat hosts | awk '{ print $2 }' \
                               | sort | uniq | egrep -vi $exclude_hostnames`

# Test each machine in $full_machine_list, to build host_dump_list. Find which
# machines are (1) up and on the net, and (2) respond as unix machines (i.e.,
# not PCs or Macs). Then ensure those machines are in the (predefined) rdump-
# capable hosttypes list, and are not in the hosttype-exclusion list.

for machine in $full_machine_list ; do
   ping $machine >/dev/null 2>&1 # is $machine up?

   if [ $status -eq 0 ]; then
      mach_os=`rsh $machine -l $t_user /bin/uname -s 2>/dev/null`
      status=$? # if it's a unix box, success

      if [ $status -eq 0 ]; then # is $machine rdump-capable?
         `echo $mach_os | egrep -i "^$rdump_hosts" | \
                          egrep -vi "^$exclude_hosttypes" >/dev/null 2>&1`

         if [ $status -eq 0 ]; then # valid rdump host
            host_dump_list="$host_dump_list $machine"
            host_count=`expr $host_count + 1`
            : # echo "$machine has $mach_os architecture"
         : # echo "Rsh failed for $machine"
      : # echo "Ping failed for $machine"

if [ $host_count -eq 0 ]; then # no need to continue
   echo "No hosts to dump"
   rm -f $log
   exit 3

daily_count=`expr $host_count / $dump_nights` # level 0 dump count (cf. cron)
count=`expr $daily_count \* $dump_nights`

if [ $count -lt $host_count ]; then
   daily_count=`expr $daily_count + 1` # expr uses DIV (rounds down)

end=`expr $day_of_week \* $daily_count` # use host position count,
start=`expr $end - $daily_count + 1` # rather than machine name

for machine in $host_dump_list; do # do the individual dumps
   count=`expr $count + 1`
   mach_os=`rsh $machine -l $t_user /bin/uname -s | tr "[A-Z]" "[a-z]"`

   if [ $alt_level_spec -eq 0 ]; then # alt. dump level not specified
      if [ $count -lt $start -o $count -gt $end ]; then
         level=$day_lvl # level 5 dump
         level=$week_lvl # level 0 dump

   # What local (non-NFS) partitions reside on $machine? (Not all nodes have
   # same setup.) Since /, /usr, /var, & /tmp likely don't hold information
   # requiring nightly backup, they're excluded from default list. Note exclu-
   # sion for /cd & /pcfs (cd's, floppies). SysV -> HP case; BSD -> default.
   # (Caveat: since HPs only have root part'n, / isn't excluded in their case.)

   if [ ! "$alt_part_list" ]; then # automagically determine
      case $mach_os in # local partitions for backup
         hp-ux) part_list=`rsh $machine -l $t_user /bin/df 2>/dev/null \
                 | grep '/dev/' | awk '{ print $2, $1 }' | tr -d '()' \
                 | egrep -v '/(cd.*|pcfs|usr|var|tmp)$' |awk '{ print $1 }'` ;;
            * ) part_list=`rsh $machine -l $t_user /bin/df 2>/dev/null \
                 | grep '/dev/' | awk '{ print $1, $NF }' \
                 | egrep -v '/(cd.*|pcfs|usr|var|tmp)?$' |awk '{ print $1 }'` ;;
   else # using user-specified part'n
      case $mach_os in # name(s), get device handle
         hp-ux) part_list=`rsh $machine -l $t_user /bin/df 2>/dev/null \
                 | grep '/dev/' | awk '{print $2, $1}' | tr -d '()' \
                 | egrep "($alt_part_list)$" | awk '{ print $1 }'` ;;
            * ) part_list=`rsh $machine -l $t_user /bin/df 2>/dev/null \
                 | grep '/dev/' | awk '{ print $1, $NF }' \
                 | egrep "($alt_part_list)$" | awk '{ print $1 }'` ;;

   if [ "$part_list" ]; then
      echo -n "[** $machine **] Level $level dump; partition(s): " | tee -a $log
      echo $part_list | tee -a $log ; echo "" | tee -a $log

      case $mach_os in # slight differences
         sunos ) opts=$dflt_opts ;;
         hp-ux ) opts=$dflt_opts ;;
         ultrix) opts=oundsBf ;; # non-DEC compatibility
         aix ) opts=udsbf ;; # doesn't understand 'n' flag
             * ) opts=$dflt_opts ;; # <shrug> try it anyway...
      for f_sys in $part_list; do # finally: do partition dumps
         rsh $machine -l $t_user $rdump_cmd $level$opts $dens \
             $t_len $blockfct $t_host:$t_drive $f_sys 2>&1 | tee -a $log
      echo "" | tee -a $log
if [ $rew = "on" ]; then # norewind not set; finish up
   echo "Dump run completed: `date`" | tee -a $log
   echo "" | tee -a $log
   chmod a+rwx $log
   tar -cfb - 20 $log | rsh $t_host -l $t_user /bin/dd of=$t_drive obs=20b 2>&1
   rm -f $log
   rsh $t_host -l $t_user /bin/mt -f $t_drive rewoffl 2>&1
exit 0

And finally, the credits ....
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ (Michael G. Harrington) (Bill Morrow)
Boyd Fletcher IV <> (Jeff Pack) (Ian MacPhedran) (Brent Chivers)
hammond@solarz.Colorado.EDU (Anne Hammond) (Greg Kastanek)
lemke@MITL.COM (Kennedy Lemke)
"arossite" <>
Tom Conroy <trc@NSD.3Com.COM>
Jack Stewart <> (Russ Poffenberger) (Tim Hoogasian) (Brett Lymn) (Kee Koon Chua) (Dave Probert) (Frank Allan (Network Mgr))
Dave Mitchell <>
Wolfg. Koppenhoefer <> (Andreas Erzmann)
Steve Elliott <> (Ercument Canver)
Donald Ballance <>
ups!upstage!glenn@fourx.Aus.Sun.COM (Glenn Satchell) (David N. Edwards)
Mr T Crummey (DIJ) <>
"Paul O'Donnell" <>
Paul Bournival <> (Pascal F. J. Janssens)
Gregory A. Parmer <>
"Paul O'Donnell" <>
"Patrick M. Landry" <> (Ralph Tietje) (Scott Babb)
Ted Rodriguez-Bell <ted@ssl.Berkeley.EDU>

This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:06:54 CDT