Skip to content

Instantly share code, notes, and snippets.

@abg
Created May 7, 2014 16:01
Show Gist options
  • Save abg/b4a8b5ab77e526128e7e to your computer and use it in GitHub Desktop.
Save abg/b4a8b5ab77e526128e7e to your computer and use it in GitHub Desktop.
Snapshot an encrypted luks volume backed by LVM
#!/bin/bash
set -x
LUKS_PASSPHRASE="foo"
SNAPSHOT_MOUNTPOINT="/mnt/backup"
MOUNT_OPTIONS="barrier=0" # nouuid for xfs, etc.
# 1) Discover a MySQL datadir
datadir=$(mysql -sse 'select @@datadir')
# 2) Discover the volume the MySQL datadir resides on
volume=$(df -P ${datadir} | awk '/^[/]/ { print $1; }')
# Assumption: step (2) discovered a luks device
# 3) Discover the underlying logical volume used by luks
lvdev=$(cryptsetup status ${volume} | awk '/device:/{print $2;}')
# 4) Lookup some attributes about the logical volume
# 4a) Lookup the canonical logical volume device path (lv_path)
lv_path=$(lvs --noheadings -o lv_path ${lvdev} | awk '{ print $1; }')
# 4b) Lookup the base name of the logical volume
lv_name=$(lvs --noheadings -o lv_name ${lvdev} | awk '{ print $1; }')
# 5) Find the base luks name (i.e. /dev/mapper/crypt00 -> crypt00)
cryptname=${volume##*/}
# 6) Create a snapshot of the underlying logical volume
lvcreate --snapshot --extents 100%FREE --name ${lv_name}_snapshot ${lv_path}
# 7) Decrypt the luks snapshot volume using the configured passphrase
cryptsetup luksOpen ${lv_path}_snapshot ${cryptname}_snapshot <<< "${LUKS_PASSPHRASE}"
# 8) Mount the luks volume
mount -o "${MOUNT_OPTIONS}" /dev/mapper/${cryptname}_snapshot "${SNAPSHOT_MOUNTPOINT}"
# 9) Archival of ${SNAPSHOT_MOUNTPOINT} would happen here
# tar zcf backup.tar.gz -C "${SNAPSHOT_MOUNTPOINT}" .
# 10) Unmount the snapshot
umount /dev/mapper/${cryptname}_snapshot
# 11) close the luks volume
cryptsetup luksClose ${cryptname}_snapshot
# 12) Remove the snapshot volume
lvremove --force ${lv_path}_snapshot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment