Linux Commands

Btrfs Subvolume Layout for VMs and Databases

“Btrfs is great for snapshotting and rolling back data. By planning your subvolume layout, you can fine tune your snapshot, protecting virtual machines and databases from system-wide rollbacks. Subvolumes are a great way to manage important data.”

Flat Layout

When you perform a standard Ubuntu installation using btrfs on one partition, the installer creates and mounts two subvolumes: @ (located at /) and @home (located at /home). These are mounted at boot via /etc/fstab. This is called a flat layout and makes snapshots easy to manage.

Snapshots and Rollbacks

Assuming the Ubuntu standard btrfs setup, mount your system partition at /mnt:

$ sudo mount /dev/sdX /mnt.

You’ll see your two subvolumes there:

The entire root filesystem is contained within @. To take a snapshot of @ called @.snapshot, we do:

To rollback a subvolume, simply move/rename the old subvolume, then move/rename the snapshot you wish to use onto the old subvolume’s location:

$ sudo mv /mnt/@ /mnt/@.broken
$ sudo mv /mnt/@.snapshot /mnt/@

After a reboot, you will be using the snapshot you took.

Note before reboot: /etc/fstab has entries for @ and @home like so:


UUID=XXXXX  /   btrfs   mount_options,subvol=@  0 0
UUID=XXXXX  /home   btrfs   mount_options,subvol=@home  0 0

If your /etc/fstab entries have subvolid in the mount options like this, that option must be removed.


UUID=XXXXX  /   btrfs   mount_options,subvol=@,subvolid=XXXX    0 0

A subvolume id is a unique identifier for a subvolume. When you replace a subvolume, the subvolume listed in that mount point may have the same name, but it will have a different id. If the id is different from the one in /etc/fstab, it will not mount. It is safe to use only names when mounting subvolumes in /etc/fstab so long as your subvolumes are uniquely named.

Mariadb

When using Mariadb, your database files will live in “/var/lib/mariadb.” By creating a new subvolume for this data, you protect your database from being touched in a system rollback when reverting @ to a previous state.

First, mount your top-level btrfs:

$ sudo mount /dev/sdX /mnt

Create the new subvolume:

$ sudo btrfs subvolume create /mnt/@mariadb

Then mount it:

$ sudo mount -o  subvol=@mariadb /dev/sdX /var/lib/mariadb

Add this entry to your fstab, and install the database:

$ sudo vim /etc/fstab


UUID=XXXXX  /var/lib/mariadb    btrfs   mount_options,subvol=@mariadb   0 0

$ sudo apt install mariadb-server

KVM

Similarly, isolate all KVM machines into one subvolume at “/var/lib/libvirt/machines:”

$ sudo btrfs subvolume create /mnt/@kvm
$ sudo mount -o subvol=@kvm /dev/sdX /var/lib/libvirt/machines
$ sudo vim /etc/fstab

UUID=XXXX       /var/lib/libvirt/machines   btrfs   mount_options,subvol=@kvm   0 0

If you already have data in your virtual machine and database directories, you can back it up, replace the original directory with the subvolume you made, and then restore the data from the backup. Don’t forget to fix permissions where necessary as all newly created subvolumes are owned by root:

$ sudo chown -R mysql:mysql /var/lib/mariadb

Conclusion

Now, when you need to rollback @ to a previous state, your database and virtual machines will be preserved in separate subvolumes. The possibilities for subvolume layouts are endless, and what I’ve demonstrated here is just one way to use btrfs to protect and preserve your data. Whatever your use case, the flexibility of btrfs subvolumes can enhance the features of your server or workstation.

About the author

Joseph M Gant

Joseph M Gant is a professional poet, fiction writer, and cyber-activist. His creative work has appeared widely in small and academic press, and his technical writing has appeared in various cybersecurity blogs. He is an Arch linux enthusiast of 10 years, EFF supporter, and self-confessed datahoarder.
Find him on Twitter or on Github