Thursday, September 10, 2009

Multi-DVD or (multi-CD) spanning backups with tar in Linux

Download

You can download all three source files below with one click if you want to save some cut&paste.

Just extract this file into your home dir, edit .multibak.conf as outlined below and launch multibak:
$ cd
$ tar zxvf multibak-2009-09-10.tar.gz
$ vi .multibak.conf
$ multibak

Setting up the config file

Create a hidden file named .multibak.conf in your home directory and edit the list of directories to back up as it suits you (default is your entire home):
# .multibak.conf

# in kbytes (1 kbyte = 1024 bytes)
# 4508876 is a safe size for ~4.7 GB DVD (single-sided, single-layer)
DISK_SIZE=4508876

# list of files/directories to backup
BAK_DIRS=($HOME)

# tar options:
# -P does not strip leading '/'s from file names
# -h dereferences symlinks - dumps the files they point to
TAR_OPT="-hP"

# cdrecord options:
# -v increment verbosity level
# -dao disk at once mode
# -overburn test it with your drive before enabling (adjust DISK_SIZE also)
# speed=X (X is in 1385 kB/s units): 0 lowest, omit for max
DVD_OPT="-v -dao"

# drive device name
# /dev/dvdwriter is a good general choise; e.g. if you attach an external
# USB drive, udev changes this link to that of the newly connected drive
DEV="/dev/dvdwriter"

# location of tar new volume script
TAR_SCRIPT="~/bin/multibak-tar-script"

# method to gain root privileges needed to record media;
# choose one of: none, su, sudo
SU=sudo
You should also review the other options too. If your system does not come with sudo installed and properly configured make sure to change SU to su.

Install the script

Put this script in your private command directory ~/bin/ and ensure this is on your $PATH environment variable and its executable permission bit is set. I called it multibak:
#!/bin/bash
# multibak: Multi-DVD or (multi-CD) spanning backups with tar

# source the config file
readonly CONFIG=~/.multibak.conf
readonly PROG=$(basename $0)
. "$CONFIG" || { echo "$PROG: config file $CONFIG missing" >&2; exit 1; }

# make temporary archive file name (unique)
readonly export TMP_TAR_FILE=$(mktemp -t $PROG.XXXXXXXXXX) || exit 1
trap "rm -f $TMP_TAR_FILE" HUP INT QUIT TERM EXIT

# make config variables read only and export
# those we need to transmit to the tar script
readonly DISK_SIZE BAK_DIRS TAR_OPT DVD_OPT DEV TAR_SCRIPT
export DEV DVD_OPT TMP_TAR_FILE SU

# archive and burn
tar $TAR_OPT -L $DISK_SIZE -F "$TAR_SCRIPT" -cf $TMP_TAR_FILE "${BAK_DIRS[@]}"
"$TAR_SCRIPT" -last
Another piece is needed, that's the "new volume script", run by tar at end of each media. Name it ~/bin/multibak-tar-script:
#!/bin/bash
# multibak-tar-script: new volume script used by multibak
# See: http://www.gnu.org/software/automake/manual/tar/Multi_002dVolume-Archives.html

[ "$DEV" ] || { echo "This script should not be run directly"; exit 1; }

# close the tray, if left open
eject -t $DEV

# format media, if it's a DVD+-RW
echo dvd+rw-format $DEV

# burn this piece
CMD="cdrecord $DVD_OPT dev=$DEV $TMP_TAR_FILE"
case $SU in
  none) echo $CMD ;;
  su) echo su -c "$CMD" ;;
  sudo) echo sudo $CMD ;;
esac

eject $DEV

[ "$1" != "-last" ] && read -p "Prepare volume #$TAR_VOLUME for backup and hit return: "
Be sure this is executable too otherwise tar will refuse to run it.

Dependencies are obvious. Here they are for CentOS or Arch Linux: cdrecord, dvd+rw-tools.

Start a backup

To make a consistent backup your applications must have been shut down first. Note tar(1) is smart enough and will warn you if a file gets modified meanwhile it gets archived. If you see such warnings it means there is some process mangling with the file.
$ multibak
If you want to do this on a Mac read here.

No comments: