FreeBSD backups
October 23, 2006 (as amended)

This page details how to make backups with a SCSI tape device using FreeBSD. Two commands are of interest - these are mt and tar. Use mt to prepare the tape, use tar to make the backup.

manpages: mt, tar

Note: in the examples below, the tape device is named sa0. If using these commandlines, ensure to change this name to reflect the name of your tape device.

To check drive status:

mt -f /dev/sa0 status

To rewind the tape:

mt -f /dev/sa0 rewind

To retension the tape:

mt -f /dev/sa0 retension

To erase the tape (ensure to rewind or retension first):

mt -f /dev/sa0 erase

To backup to tape (this overwrites any previous backup):

tar -cv /data/dir
tar -cv data/dir
tar -cv /data/dir /data/test

To list tape contents:

tar -tv
tar -tv > listing.txt

To restore from tape:

tar -xv
tar -xv data/dir
tar -xv data/dir/filename.ext

Note: the name of the file/directory specified must match the name of the file/directory as it is stored by tar. To determine the correct name, get a listing of the tape contents using tar -tv. If the file is stored by tar without a leading slash, do not specify a leading slash when restoring.

Note: if the file is stored by tar without a leading slash, it will be restored to the current directory, not the directory it was backed up from. To restore a file directly into the directory it was backed up from, ensure to change to that directory, before running the restore.

To eject a tape:

mt -f /dev/sa0 offline

Other mt commands (not usually needed):

mt -f $tapedev rewind
mt -f $tapedev density dds-3
mt -f $tapedev comp DCLZ
mt -f $tapedev comp on

If you try an 'mt status' while not logged in as root you get:

mt: /dev/sa0: Permission denied

If you try an 'mt status' while the drive is empty you get:

mt: /dev/sa0: Device not configured

If you try an 'mt status' while the drive is busy you get:

mt: /dev/sa0: Device busy

If you try an 'mt status' when the tape is ready you get something like:

Mode      Density              Blocksize      bpi      Compression
Current:  0x25:DDS-3           variable       97000    DCLZ
---------available modes---------
0:        0x25:DDS-3           variable       97000    DCLZ
1:        0x25:DDS-3           variable       97000    DCLZ
2:        0x25:DDS-3           variable       97000    DCLZ
3:        0x25:DDS-3           variable       97000    DCLZ
---------------------------------
Current Driver State: at rest.
---------------------------------
File Number: 0  Record Number: 0        Residual Count 0

If you try a 'tar -tv' while the tape is unformatted you get:

tar: Unrecognized archive format: Inappropriate file type or format

If you try a 'tar -tv' on an empty tape you get:

tar: Error opening archive: Error reading '/dev/sa0': Input/output error

If you acquire a collection of backup tapes, and you wish to start using them, for each tape, follow this process to ensure it is OK (note: this does a "long erase", which can take hours, and cannot be interrupted):

mt -f /dev/sa0 retension
mt -f /dev/sa0 erase

Here's a sample backup script. It's not fancy, but it works. Note that it doesn't verify, it only lists the contents of tape once the backup is done. I hope to improve on this at some point.

#!/bin/sh

#### backup script 4 - by Stuart Udall 2006-2009 ####

LOGFILE=/var/log/backups.log
MAILFILE=/data/backupreport.txt

# begin
clear
echo "====> backup process started"
date
echo "backup process started:" > ${LOGFILE}
date >> ${LOGFILE}
echo >> ${LOGFILE}

# rewind the tape
echo "rewinding tape.."
mt rewind

# backup user data
echo "starting backup.."
cd /usr
tar -cv --exclude data/dont/backup/thisdir data

# list contents of tape to file
echo "contents of tape:" >> ${LOGFILE}
echo "listing tape contents to file.."
tar -tv >> ${LOGFILE}

# eject the tape
mt offline

# finish up log
echo "backup process completed"
date
echo >> ${LOGFILE}
echo "backup process completed:" >> ${LOGFILE}
date >> ${LOGFILE}

# create report email
echo "To: sysadmin@mailbox.com" > ${MAILFILE}
echo "Cc: boss@customer.com" >> ${MAILFILE}
echo "Subject: backup report" >> ${MAILFILE}
echo >> ${MAILFILE}
grep -v "\-\-r\-\-" ${LOGFILE} >> ${MAILFILE}

# send report email
/usr/sbin/sendmail -f backups@customer.com -i -t < ${MAILFILE}

# clean up
rm ${MAILFILE}

Note that the script changes to the appropriate directory first, then runs the backup with a relative path (in the above example, it backs up a folder called "data"). If an absolute (full) path is used, the backup works but restores can only be done to the source folder, since the path is stored in the backup. That is, the filenames in the backup contain the path they came from, when they are restored they go back to that path. To restore to an alternate directory, ensure to use a path without a leading / character.

Schedule a backup with cron.

If members of the wheel group are permitted to use the backup device, a special 'backups' user can be created, who is a member of the wheel group, who can do backups, but does not need the root password. This user has a call to the backup script in his login script, followed by automatic logout at the end of the login script - this permits manual backups to be run by anyone with the password to the 'backups' account - but nothing else. Use these commands to permit members of the wheel group to use the backup device:

chgrp wheel sa0.0

How to have a script log itself out:

kill -9 -1

How to give the wheel group execute permissions to the script:

chmod 754 backups.sh

How to give the wheel group write permissions to the logfile:

chmod 664 backups.log