BlockFuse to the Rescue: rdiff-backup of LVM Snapshots and Block Devices

Over the years I have used rdiff-backup as an incremental backup solution. It works really well on many platforms, supports files >4GB, ACLs, and much much more.

Unfortunately, rdiff-backup does not support backing up block device content; instead, it will replicate the block device inode’s major/minor numbers on the destination system (doesn’t backup the internal content). If you are backing up all of your root filesystem (/), this is probably what you want. But, what if you’re backing up large virtual machine LVM snapshots?

Not finding a solution on the web, I wrote my own using the Linux FUSE filesystem.

BlockFuse takes two arguments:

	# ./block-fuse
	usage: ./block-fuse /dev/directory /mnt/point

For example:

	# # Take an LVM snapshot:
	# lvm -s /dev/vgBoot/asterisk -n _snap-asterisk -L 1G
	   ...
	# # Mount /dev/mapper as /mnt/block-devices:
	# ./block-fuse /dev/mapper /mnt/block-devices
	# ls -l /mnt/block-devices
	-r-------- 1 root root  10G 2010-12-21 16:07 vgBoot-_snap--asterisk
	-r-------- 1 root root 1.0G 2010-12-21 16:07 vgBoot-_snap--asterisk-cow
	   ...
	# # Perform your backup:
	# rdiff-backup --include '/mnt/block-devices/*_snap*' --exclude '*' \
		/mnt/block-devices \
		/mnt/backup/lvm-snapshots
	# #
	# ls -l /mnt/backup/lvm-snapshots/
	drwx------ 3 root root         4096 2010-12-21 16:19 rdiff-backup-data
	-r-------- 1 root root  10737418240 1969-12-31 16:00 vgBoot-_snap--asterisk
	-r-------- 1 root root   1073741824 1969-12-31 16:00 vgBoot-_snap--asterisk-cow

Thus, rdiff-backup is able to backup block-device content, including LVM snapshots using BlockFuse. BlockFuse is quite simple: it enumerates the content of the mount-source directory, and exports all block devices with non-zero size as a file with 0400 permissions, owned by your fuse user (probably root for this).

Notes:

  • BlockFuse does not support writing, so your data is read-only-safe. In a catastrophic recovery where you cannot restore a snapshot and must recover from rdiff- backup, just use rdiff-backup’s –restore-as-of argument, and ‘dd’ the recovered “file” back onto the original block device.
  • BlockFuse uses the mount-time as the modification time (st_mtime) for the mounted filesystem. This will force rdiff-backup to scan the block devices for changes. Therefore you must unmount and re-mount your BlockFuse filesystem after updating your snapshots. If you do not, rdiff-backup will skip the “files” because their modification timestamp had not changed since the last backup. (It would be easy to write a SIGHUP handler for this, so send me a patch if you do!)

Incidentally, I have this working in production, backing up snapshots as large as 350GB, so this is well tested. Still, this software is TO BE USED AT YOUR OWN RISK! Patches are welcome if you have a novell idea or change to add to BlockFuse.

Wed Dec 22 15:19:06 PST 2010: BlockFuse v0.01 initial release
Tue Dec 21 16:39:41 PST 2010: BlockFuse v0.02 now uses mmap’ed IO!
Tue Jan 14 10:53:54 PST 2014: BlockFuse v0.03 now follows symlinks and supports i386 architectures.

Download BlockFuse v0.03.

2014-01-14: Thank you for your patience waiting for the current version to be uploaded.  If someone would like to maintain BlockFuse and open a public git repo to maintain the package I would greatly appreciate it.

Cheers,

-Eric

10 thoughts on “BlockFuse to the Rescue: rdiff-backup of LVM Snapshots and Block Devices

  1. after mounting volume with blockfuse I get

    ls -la
    ls: reading directory .: Software caused connection abort

    How to fix that ?

    • Sounds like blockfuse died for some reason. Try compiling it with debug enabled and run it in the foreground.

      I have a newer version that isn’t uploaded yet. Email me and I’ll send you a copy if you want to give it a try.

      -Eric

  2. Hello
    I tried your blockfuse to be able to do a backup ov my lv; block fuse compiles without errors but when i go mounting with ./block-fuse /dev/mapper /mnt/block
    I simply get:
    root@proxmox:/usr/src/block-fuse# ./block-fuse /dev/mapper /mnt/block
    RLIMIT_NOFILE = 1024
    3
    [0] ./block-fuse
    [1] /dev/mapper
    [2] /mnt/block
    root@proxmox:/usr/src/block-fuse# ls -l /mnt/block
    total 0
    root@proxmox:/usr/src/block-fuse# mount | grep block
    block-fuse on /mnt/block type fuse.block-fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0)

    Any ideas?
    Regards

  3. ah, of course mapper is not empty ^^
    root@proxmox:~# ls -l /dev/mapper
    total 0
    crw——- 1 root root 10, 61 Oct 15 15:39 control
    lrwxrwxrwx 1 root root 7 Oct 15 15:39 drbdvg-vm–100–disk–1 -> ../dm-1
    lrwxrwxrwx 1 root root 7 Oct 15 15:39 pve1-root -> ../dm-0
    lrwxrwxrwx 1 root root 7 Oct 15 15:39 pve1-swap -> ../dm-2

Leave a Comment