lvsnackup: Backup using LVM Snapshots

Posted on Mon 10 August 2015

Another piece of Bash forgery that automates a common administrative task: creating image-style (i.e. full) backups of logical volumes. The name is a combination of LVM, Snapshot and Backup.

The advantage compared to plain dd is that image contents are consistent (at least as consistent as a power fault would leave disks), no matter how long the actual imaging process takes. By default it uses LZO compression in order to benefit from zeroed blocks.

Configuration

lvsnackup is configurable using the following environment variables:

  • CMD_COMPR: compression command (default: lzop -c)
  • COMPR_EXT: image file suffix (default: .lzo)
  • SNAP_SIZE: size of temporary change buffer (default: 1 GB)

Requirements

  • lvm (obviously)
  • lzop as default compressor
  • (optional) Pipe Viewer for visual progress information

(Arch packages: lvm, lzop, pv)

Usage

$ lvsnackup /dev/vg0/root /mnt/backup/vg0-lvroot.img

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/bin/bash

# lvsnackup: Create LV Backups using LVM Snapshots
#   2015 Alexander Koch

# defaults
CMD_COMPR="${CMD_COMPR:-"lzop -c"}"
SNAP_SIZE="${SNAP_SIZE:-"1G"}"
COMPR_EXT="${COMPR_EXT:-".lzo"}"


if ! [ $# -eq 2 ]; then
    echo "error: invalid arguments."
    echo "usage: $0 VOLUME IMAGE"
    echo "  VOLUME:  path to logical volume to backup"
    echo "  IMAGE:   path to image, excl. compression suffix"
    exit 1
fi

SRC="$1"
DST="${2}${COMPR_EXT}"
SNAP="$(basename "$SRC")-snap"
SNAP_FULL="$(dirname "$SRC")/$SNAP"

if ! [ -e "$SRC" ]; then
    echo "error: invalid volume: '$SRC'."
    exit 1
fi

if ! [ -w "$DST" ] && ! [ -w "$(dirname "$DST")" ]; then
    echo "error: unable to write to '$DST'."
    exit 1
fi

ERR=0

# create snapshot volume
lvcreate -n "$SNAP" -L $SNAP_SIZE -s "$SRC" || exit 1

# compress contents to image
if tty -s && which pv &>/dev/null; then
    pv "$SNAP_FULL" | $CMD_COMPR > "$DST" || ERR=1
else
    $CMD_COMPR < "$SNAP_FULL" > "$DST" || ERR=1
fi

# destroy snapshot volume
lvremove -f "$SNAP_FULL" || ERR=1

exit $ERR

(Update 2015-09-03: Fixed lvremove call)

tags: lvm, backup, snapshot, bash | category: projects