Linux Tape Backup and Firewire

I recently got a new tape drive for backing up a group of Linux servers on a budget. The SCSI DDS 3 drive that I had quit and so I started researching new drives.

The Linux Tape Certification Program has a lot of information including what drives are "certified". The Tape Cert program is run by the TOLIS group, these are the folks that purchased BRU a while back.

After checking the certified drives I decided I wanted VXA or Mammoth this time. So I searched for prices and decided I could afford neither. Then I decided to check eBay for the heck of it. I found many many drives available and considered it worth the risk for the cost savings. I ended up with an Exabyte VXA-1 external FireWire connected drive. I got it for about half the price of new drives and it came with all supplies including three tapes (which are themselves not cheap).

The "backup" server is an older ASUS motherboard without any firewire support. Doing some quick research I discovered that Linux has a lot of support for the UHCI firewire standard and so I bought a cheap firewire PCI card.

From there I went to linux1394.org for help with modules and configuration. The 2.6 kernel has most of the support needed, even for hotplug, already there, but for 2.4 you will need to load a few modules (different depending on kernel rev) as detailed here.
With 2.4.24 following the instructions I had support for the drive ready to go in just a few minutes (using Red Hat 7.3).

From there the firewire device is then accessible on the SCSI but just like any other SCSI device. For tapes I generally use the "mt" program. (Scsi devices for tape drives are stx where x is the device number, st0 for example, they also have a non rewinding alias of nstx.)

  • mt -f /dev/st0 status
  • mt -f /dev/st0 rewind
  • and so on, see man mt

Once the drive was responding properly I went back to using my "tar" based backup script that I wrote some years back. Using tar is "ultra" simple, once on the tape you search and restore and such simply using tar. Its not nearly as fancy as other programs that are available such as amanda or commercial products such as BRU but it has always worked great and been ultra easy for others to understand.

My backup script uses separate "include" and "exclude" files to tell tar what to get and what to skip. Then later these files can be modified as needed without touching the actual script.
The script, in case it might help anyone is basically thus (no warranty implied, yadda yadda, use at your own risk, and I am no shell scripting expert so improvements and criticism welcome):

#!/bin/bash
#
# ultra simple solid backup - ussb
#

# tar uses a block size of Nx512 bytes, with a default N=20

# vars
CWD=`pwd`
DATE=`date -I`
LABEL="Cron - backup: $DATE"
ARCHIVE_DEVICE=/dev/nst0
INCLUDE_FILE=/opt/backup/backup.include
EXCLUDE_FILE=/opt/backup/backup.exclude
BACKUP_DIR=/opt/backup
LOG_FILE=/var/log/backup.log

# start process and open log
echo "" > $LOG_FILE
echo "$LABEL" >> $LOG_FILE
START_TIME=`date +%s`
echo "Start timestamp = $START_TIME" >> $LOG_FILE
echo "" >> $LOG_FILE

# tar it up baby
echo "Beginning backup to tape using include and exclude." >> $LOG_FILE
echo "" >> $LOG_FILE
mt -f $ARCHIVE_DEVICE rewind >> $LOG_FILE               
tar -cvpf $ARCHIVE_DEVICE \
--exclude-from $EXCLUDE_FILE \
`cat $INCLUDE_FILE` \ 
--totals >> $LOG_FILE 2>&1
 
# rewind again (leave in rewound state)
echo "Rewinding tape." >> $LOG_FILE
echo "" >> $LOG_FILE
mt -f $ARCHIVE_DEVICE rewind >> $LOG_FILE
 
# done
END_TIME=`date +%s`
echo "End timestamp = $END_TIME" >> $LOG_FILE
let TOTAL_SECONDS=$END_TIME-$START_TIME 
let TOTAL_MINUTES=$TOTAL_SECONDS/60 
let TOTAL_HOURS=$TOTAL_MINUTES/60 
echo "" >> $LOG_FILE 
echo "Total TIME" >> $LOG_FILE 
echo "      seconds = $TOTAL_SECONDS" >> $LOG_FILE 
echo "      minutes = $TOTAL_MINUTES" >> $LOG_FILE 
echo "      hours = $TOTAL_HOURS" >> $LOG_FILE  
echo "" >> $LOG_FILE 
echo "All done boss." >> $LOG_FILE 
echo "" >> $LOG_FILE
 

# mail root
# create file to mail to root
MAIL_FILE=mail.root 
echo "$LABEL" > $MAIL_FILE 
echo "(See \"$LOG_FILE\" for more detailed info.)" >> $MAIL_FILE  
echo "" >> $MAIL_FILE 
tail -16 $LOG_FILE  >> $MAIL_FILE 
echo "" >> $MAIL_FILE 
echo "All done boss." >> $MAIL_FILE 
echo "" >> $MAIL_FILE 
mail root -s "$LABEL" < $MAIL_FILE