Virtualbox VM backup using LVM
Thu, Jan 10, 2019 · 5 minute readlinuxvirtualbox
There really is no simple and quick way to backup running Virtualbox VM’s, unless you use a filesystem manager that supports snapshots.
We are using LVM and XFS but you could equally use ZFS or BTRFS.
Please test with disposable VM before relying on this technique for vital data.
Some general backup advice:
- Make sure you can restore from your backups - test restores regularly.
- Log your backups and check the logs to avoid silent backup failures ruining your day.
- Do not rely on an external USB for backup - maintain multiple backup copies.
We have 530GiB free in a single volume group vg-data which we are going to use for our VM.
root@bits1:~# vgs
VG #PV #LV #SN Attr VSize VFree
vg-data 1 1 0 wz--n- <931.51g <531.51g
vg-root 1 2 0 wz--n- <118.74g 0
Create a logical volume big enough for our VM.
Our VM disk will be thin provisioned so we can size the disk larger than the space allocated.
Using LVM makes it easy to expand the filesystem later should the need arise.
root@bits1:~# lvcreate -L 20G -n lv-vm3 vg-data
Logical volume "lv-vm3" created.
Create a filesystem, we are using XFS for this VM, other VM’s could use a different filesystem which may be convenient for testing.
root@bits1:~# mkfs -t xfs /dev/vg-data/lv-vm3
meta-data=/dev/vg-data/lv-vm3 isize=512 agcount=4, agsize=1310720 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=0, rmapbt=0, reflink=0
data = bsize=4096 blocks=5242880, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
Create a mountpoint, mount the filesystem, add the mount to /etc/fstab if the mount needs to persist over a reboot.
Depending on your environment you may been to change the owner and permissions of the mountpoint to allow other non-root users to create the VM.
root@bits1:~# mkdir /vm/vm3
root@bits1:~# mount /dev/vg-data/lv-vm3 /vm/vm3
Create the VM, or restore it from a previous cold (VM shutdown) copy.
Then start the VM.
alan@bits1:~$ VBoxManage startvm vm3 --type headless
Waiting for VM "vm3" to power on...
VM "vm3" has been successfully started.
VM is up, now we can use LVM to take a snapshot.
Use lvcreate
for this, the logical volume size is 1G, needs to be large enough to record all changes made to source disk for duration of snapshot.
Our VM’s are typically low activity and snapshot taken overnight so 1G is OK.
Be warned though - if the snapshot space gets exhausted it may be difficult to recover.
The snapshot mount options are required when using XFS filesystems, if not specified then you will see an error similar to this:
#root@bits1:~# mount /dev/vg-data/lvVMsnapshot /vm/VM-snapshot
#mount: /vm/VM-snapshot: wrong fs type, bad option, bad superblock on /dev/mapper/vg--data-lvVMsnapshot, missing codepage or helper program, or other error.
Create and mount the snapshot.
VM=vm3
lvcreate -L 1G -s -n lvVMsnapshot /dev/vg-data/lv-${VM}
mkdir /vm/VM-snapshot
# mount options req'd for XFS
mount /dev/vg-data/lvVMsnapshot /vm/VM-snapshot -o nouuid,ro
Use rsync to make a copy of the VM - remember the VM is still running and useable at this point.
We send our copy to an external USB drive.
rsync -av /vm/VM-snapshot/ /media/USB-Backup/vm/vm3
...
Can use ls to confirm the file copy.
At this point VM files can be seen in 3 places;
1. The original VM directory
2. The snapshot
3. The USB backup
All files will be the same.
root@bits1:~# ls -l /media/USB-Backup/vm/vm3
total 15318592
-rwxrwxrwx 1 itadmin itadmin 11455692800 Dec 1 14:30 vm3-00.vdi
-rwxrwxrwx 1 itadmin itadmin 4234149888 Dec 1 14:30 vm3-01.vdi
-rwxrwxrwx 1 itadmin itadmin 3169 Dec 1 14:30 vm3.vbox
-rwxrwxrwx 1 itadmin itadmin 3169 Jul 23 13:20 vm3.vbox-prev
drwxrwxrwx 1 itadmin itadmin 0 Nov 24 11:16 Logs
root@bits1:~# ls -l /vm/VM-snapshot/
total 15314896
-rwxrwxrwx 1 itadmin itadmin 11465129984 Dec 3 10:30 vm3-00.vdi
-rwxrwxrwx 1 itadmin itadmin 4234149888 Dec 1 14:30 vm3-01.vdia
-rwxrwxrwx 1 itadmin itadmin 3169 Dec 1 14:30 vm3.vbox
-rwxrwxrwx 1 itadmin itadmin 3169 Jul 23 13:20 vm3.vbox-prev
drwxrwxrwx 2 itadmin itadmin 76 Dec 1 17:04 Logs
root@bits1:~# ls -l /vm/vm3
total 15314896
-rwxrwxrwx 1 itadmin itadmin 11465129984 Dec 3 11:03 vm3-00.vdi
-rwxrwxrwx 1 itadmin itadmin 4234149888 Dec 1 14:30 vm3-01.vdi
-rwxrwxrwx 1 itadmin itadmin 3169 Dec 1 14:30 vm3.vbox
-rwxrwxrwx 1 itadmin itadmin 3169 Jul 23 13:20 vm3.vbox-prev
drwxrwxrwx 2 itadmin itadmin 76 Dec 1 17:04 Logs
The snapshot has served it’s purpose - unmount and destroy the snapshot.
umount /vm/VM-snapshot
lvremove --yes vg-data/lvVMsnapshot
It is easy to generalise this into a script that can be called for any VM.
You will need sudo as the script has to run as root
#!/bin/bash
# backup-vm-usb.sh
# Use LVM snapshot to backup running Virtualbox VM to external USB.
# (c) Alan jeskins-Powell (Bespoke IT Solutions) 2019
# Reproduced here for anyone to use - at your own risk!
# *****
# Script provided As Is.
# No warranty, either express or implied.
# In no event shall the author be responsible for any claim, damages or other liability
# arising from, out of or in connection with this script.
# *****
usb=/media/USB-Backup/vm
snapdir=/vm/VM-snapshot
snaplv=lvVMsnapshot
[ $# -ne 1 ] && { echo "Usage: $0 vm"; exit 1; }
VM=$1
[ ! -d /vm/${VM} ] && { echo "VM does not exist"; exit 1; }
echo "Backing up VM ${VM} ..."
echo "Creating LVM snapshot ..."
# 5GB - needs to be large enough to hold all changes for duration of backup
lvcreate -L 5G -s -n ${snaplv} /dev/vg-data/lv-${VM}
[ $? -ne 0 ] && { echo "Failed to create snapshot"; exit 1; }
[ ! -d ${snapdir} ] && { echo "Creating snapshot mount point ..."; mkdir ${snapdir}; }
echo "Mounting snapshot ..."
# mount options req'd for XFS
# -t required (at least for some VMs to prevent this error):
# mount: /vm/VM-snapshot: more filesystems detected on /dev/mapper/vg--data-lvVMsnapshot; use -t <type> or wipefs(8).
mount /dev/vg-data/${snaplv} ${snapdir} -o nouuid,ro -t xfs
[ $? -ne 0 ] && { echo "Mount snapshot failed"; exit 1; }
df -h ${snapdir}
echo "rsync snapshot backup to ${usb}/${VM} ..."
[ ! -d ${usb}/${VM} ] && { mkdir ${usb}/${VM}; }
rsync -av --progress ${snapdir}/ ${usb}/${VM}
echo "Tidying up ..."
umount ${snapdir}
lvremove --yes vg-data/${snaplv}