Btrfs system snapshots and rollbacks with Timeshift

Introduction

The snapshot feature of the Btrfs filesystem can be used to perform system snapshots and rollbacks. With Timeshift there is also an easy to use a graphical application for that.
Unfortunately, the current RebornOS installer only allows installation on the bare Btrfs filesystem, and not on the @ subvolume, which would be needed to perform system snapshots and rollbacks with Timeshift.

In this guide I will explain the steps to move RebornOS from the bare Btrfs filesystem to an Ubuntu-style subvolume layout, as expected by Timeshift.

Before you start

I would advise against using a boot partition (mount point /boot) with Btrfs system subvolumes, as that would exclude the /boot directory from system snapshots. A quick way to remove your boot partition is explained here: https://osdn.net/projects/rebornos/wiki/Remove+the+boot+partition to remove your systems boot partition.

Check if your system partition uses Btrfs. If not, you can use Btrfs-convert to convert your system partition to Btrfs if it uses the ext2/3/4 or ReiserFS filesystem. The process is explained here: https://osdn.net/projects/rebornos/wiki/Convert+ext2%2F3%2F4+and+ReiserFS+file+systems+to+Btrfs+without+data+loss

Move RebornOS to Btrfs subvolumes

1. First, create a snapshot of your system partition to /@:
sudo btrfs subvolume snapshot / /@
A snapshot is a normal subvolume, but it won't consume extra space as long as the content stays the same, because it can share all data blocks with the source subvolume. All files on yor system partition are now present a second time on that subvolume.

2. Unless you want to use a separate home partition, run
sudo btrfs subvolume create /@home
to create a home subvolume so the home directory /home can be excluded from Btrfs system snapshots.

3. Next I recommend creating additional subvolumes for all directories that should be excluded from Btrfs system snapshots and thereby preserved during system rollbacks:
/var contains variable data like system logs (/var/log), temporary files (/var/cache, /var/tmp), and program data from various applications, including default locations for virtual machine images and databases, and should be excluded from system snapshots to avoid data loss, keep system logs accessible and keep snapshots small:
sudo btrfs subvolume create /@var
The following subvolumes don't provide much benefit for the average user, consider skipping them if you are in a hurry:
/root, the root users home directory, should be preserved on rollbacks:
sudo btrfs subvolume create /@root
/opt is the default location for third-party programs and should be excluded so the programs don't get removed on rollbacks:
sudo btrfs subvolume create /@opt
/usr/local is used when manually installing software and should be excluded to avoid uninstalling these installations on rollbacks:
sudo btrfs subvolume create /@local
/srv might contain important data if you use your system as a web or file server and should be excluded from system snapshots to avoid data loss on system rollbacks:
sudo btrfs subvolume create /@srv

4. You'll also have to move all the relevant data to the subvolumes you created in step 2 and 3. You can do that by running the following commands, just skip the irrelevant ones:
/home: sudo find /@/home -mindepth 1 -prune -exec mv '{}' /@home \;
/var: sudo find /@/var -mindepth 1 -prune -exec mv '{}' /@var \;
/root: sudo find /@/root -mindepth 1 -prune -exec mv '{}' /@root \;
/opt: sudo find /@/opt -mindepth 1 -prune -exec mv '{}' /@opt \;
/usr/local: sudo find /@/usr/local -mindepth 1 -prune -exec mv '{}' /@local \;
/srv: sudo find /@/srv -mindepth 1 -prune -exec mv '{}' /@srv \;

Edit the new systems file systems table (fstab)

To account for the changes, you have to edit /etc/fstab for the new RebornOS system on the new root subvolume, /@/etc/fstab.
You can use nano for that:
sudo nano /@/etc/fstab

Every subvolume that should be mounted during boot needs its own entry in fstab, a minimum entry would look like this:

UUID=<UUID of filesystem the subvolume resides in>  btrfs  subvol=<path of subvolume relative to root directory of filesystem>  0  0

This is an example of how fstab could look like after editing:

UUID=11111111-1111-1111-1111-111111111111 /                     btrfs subvol=@,defaults,compress=zstd 0 0
UUID=11111111-1111-1111-1111-111111111111 /home                 btrfs subvol=@home                    0 0
UUID=11111111-1111-1111-1111-111111111111 /var                  btrfs subvol=@var,nodatacow           0 0
UUID=11111111-1111-1111-1111-111111111111 /root                 btrfs subvol=@root                    0 0
UUID=11111111-1111-1111-1111-111111111111 /opt                  btrfs subvol=@opt                     0 0
UUID=11111111-1111-1111-1111-111111111111 /usr/local            btrfs subvol=@local                   0 0
UUID=11111111-1111-1111-1111-111111111111 /srv                  btrfs subvol=@srv                     0 0
UUID=0000-0000                            /boot/efi             vfat  defaults                        0 2
tmpfs                                     /tmp                  tmpfs defaults,mode=1777              0 0
UUID=22222222-2222-2222-2222-222222222222 swap                  swap  defaults                        0 0
Btrfs mount options propagate down through mount points when the mounted subvolumes are on the same filesystem, unless the mount options are contradictory. That's why mount options defaults and compress are only specified once for the root subvolume.

Mount your new RebornOS system to a temporary mountpoint

After editing /@/etc/fstab, the only thing left to do to make the new RebornOS system on the new root subvolume bootable is to reinstall the bootloader for the new RebornOS system, so it will actually boot the new RebornOS system. To do this, you have to mount the new RebornOS system so you can chroot into it.

If you chose to use a separate home partition which is also used by your current system you'll have to perform the following commands from a live ISO.

1. Find out the device name of the system partition (mount point */*) and, if present, the EFI system partition (mount point */boot/efi*). lsblk, fdisk -l or a graphical partition manager are good ways to do that.

2. Mount the new root subvolume to /mnt: sudo mount -o subvol=@ /dev/<device name of system partition> /mnt

To completely mount the new system to /mnt you also have to run an additional command for every other entry in the new fstab with a mount point.
For the fstab example above it would be the following commands:
/home: sudo mount -o subvol=@home /dev/<device name of system partition> /mnt/home
/var: sudo mount -o subvol=@var /dev/<device name of system partition> /mnt/var
/root: sudo mount -o subvol=@root /dev/<device name of system partition> /mnt/root
/opt: sudo mount -o subvol=@opt /dev/<device name of system partition> /mnt/opt
/usr/local: sudo mount -o subvol=@local /dev/<device name of system partition> /mnt/usr/local
/srv: sudo mount -o subvol=@srv /dev/<device name of system partition> /mnt/srv
/boot/efi: sudo mount /dev/<device name of EFI system partition> /mnt/boot/efi
/tmp: sudo mount -t tmpfs tmpfs /mnt/tmp

Now your new RebornOS system should be completely mounted.

Chroot into the new system and reinstall GRUB

1. Chroot into the new RebornOS system:
sudo arch-chroot /mnt

2. If you are on an UEFI system with EFI system partition, run grub-install --target=x86_64-efi --efi-directory=/boot/efi.
If you are on a Legacy BIOS system, run grub-install /dev/<device name of system disk> instead.

3. After (re)installing the bootloader you also have to update the GRUB configuration file:
grub-mkconfig -o /boot/grub/grub.cfg

4. Run exit to leave the chroot jail. You can now reboot and should end up in the new RebornOS system on the @ subvolume. The system is now ready for Btrfs snapshots with Timeshift.

You might have to manually activate *cronie.service* by running systemctl enable cronie.service and systemctl start cronie.service for Timeshift scheduled snapshots to work.

Remove the old RebornOS system

1. Mount the root Btrfs filesystem to /mnt:
sudo mount /dev/<device name of system partition> /mnt

2. Remove everything except system subvolumes and their content from the system partition:
sudo find /mnt -mindepth 1 -prune \! -name @* -exec rm -rf '{}' +

Boot into Timeshift Btrfs snapshots from GRUB with grub-btrfs

This feature allows you to easily boot into Timshift Btrfs system snapshots and perform system rollbacks from there.

After installing grub-btrfs (sudo pamac install grub-btrfs), GRUB boot entries for existing Timeshift Btrfs snapshots get created every time the GRUB configuration file gets updated (sudo grub-mkconfig -o /boot/grub/grub.cfg).

Grub-btrfs can perform the GRUB update automatically each time a new Timeshift Btrfs snapshot is created. For this to work the Timeshift Btrfs snapshot folder on the system partition's root directory has to be replaced with a Btrfs subvolume and mounted inside the system's directory structure, so changes in that directory can be monitored. To do this, run the following commands:

1. sudo mount /dev/<device name of system partition> /mnt

2. systemctl stop cronie.service

3. sudo rm -rvf /mnt/timeshift-btrfs (Warning: This will remove all existing Timeshift Btrfs snapshots)

4. sudo btrfs subvolume create /mnt/timeshift-btrfs

5. systemctl start cronie.service

6. sudo mkdir /.snapshots

7. sudo mount -o subvol=timeshift-btrfs /dev/<device name of system partition> /.snapshots

8. To be automatically mounted at boot you have to add a line in /etc/fstab. It could look like this:

UUID=11111111-1111-1111-1111-111111111111 /.snapshots           btrfs subvol=timeshift-btrfs          0 0

7. Finally, run sudo systemctl enable grub-btrfs.path and sudo systemctl start grub-btrfs.path to activate the automatic update of the GRUB configuration file.

Grub-btrfs can be configured by editing /etc/default/grub-btrfs/config.

Automatic Timeshift Btrfs system snapshot before package upgrades with timeshift-autosnap

You might also want to install timeshift-autosnap, which creates Timeshift snapshots before package upgrades using a pacman hook.
Change the line updateGrub=true in /etc/timeshift-autosnap.conf to updateGrub=false, so Grub doesn't get updated twice when timeshift-autosnap creates a snapshot.


I hope this guide helped you to successfully set up Btrfs system snapshots with Timeshift.

-damian101