UPDATED 22/Dec/2022, ChangeLog:
- 22/Dec/2022: added the flag “-czstd” for defragmentation and compression.
- 20/Nov/2022: documented the new version of grub-btrfs and its new grub-btrfsd daemon; the configuration for Timeshift is much simpler, but you have to install another package: inotify-tools.
- 17/Nov/2022: documented that I could also create additional subvolumes and move existing contents from the running system
In this post, I’ll describe the same procedure I described in one of my previous posts but applied to Ubuntu (in particular, Ubuntu Jammy 22.04). I’m not describing an autosnap mechanism when performing package updates in Ubuntu, though you might want to try timeshift-autosnap-apt for that.
If you choose the BTRFS filesystem when you install Ubuntu, you get the two subvolumes “@” for “/” and “@home” for “/home”, which will make Timeshift work since that’s what Timeshift expects to find to take BTRFS snapshots.
However, some adjustments are still worth making to avoid useless data ending in the snapshots and to be able to boot snapshots directly (with the help of grub-btrfs).
Adjust compression
Ubuntu does not mount BTRFS subvolumes with compression. Instead, I prefer to have compression on BTRFS.
To do that, right after the installation, I change /etc/fstab by adding compression and “noatime” to the existing entries for “/” and “/home” (as usual, UUID must be replaced with the UUID of your disk partition):
1 2 |
UUID=... / btrfs defaults,noatime,space_cache=v2,compress=zstd:3,subvol=@ 0 1 UUID=... /home btrfs defaults,noatime,space_cache=v2,compress=zstd:3,subvol=@home 0 2 |
Save the file, reboot, and perform “defragment” so that the existing data gets compressed:
1 |
sudo btrfs fi defragment / -r -czstd |
It’s also best to create /var/lib/portables and /var/lib/machines if not already there
1 2 |
sudo mkdir -p /var/lib/portables sudo mkdir -p /var/lib/machines |
I’m not using these directories, but it looks like systemd creates them automatically as nested subvolumes. Nested subvolumes will force you to do some manual removal after restoring a snapshot and removing old snapshots.
The current situation of subvolumes should be as follows:
1 2 3 |
sudo btrfs su li / ID 256 gen 2342 top level 5 path @ ID 257 gen 2342 top level 5 path @home |
Create additional subvolumes
With the current subvolume layout, things like logs and caches will end up in snapshots, giving you problems when you try to boot a snapshot (which we want to be able to do).
Creating a subvolume for the whole /var directory is not ideal because we lost the contents of essential things like /var/lib in the snapshot, so we could not restore a snapshot correctly. Instead, we create subvolumes to mount /var/log, /var/cache, and /var/tmp.
Since we have to move the existing contents of such directories into the new subvolume, it’s better to operate from a Live ISO.
UPDATE 17/Nov/2022: I also tried to create the new subvolumes and move the existing contents in the running system, following the steps described below. It worked! However, I’d still suggest you do the next steps from a Live ISO because you never know 😉
So, let’s boot a Live ISO (e.g., Ubuntu live installation medium).
Switch to superuser (no password required in the live media):
1 |
sudo su - |
Mount the BTRFS filesystem into /mnt, which should already exist in the live media. We have to mount the partition hosting our existing installation. In my example, it is /dev/sdb10:
1 |
mount /dev/sdb10 /mnt |
You should see the existing subvolumes in the mount directory:
1 2 3 4 |
ls -l /mnt/ total 0 drwxr-xr-x 1 root root 172 Aug 20 12:47 @ drwxr-xr-x 1 root root 14 Oct 18 07:44 @home |
Create the new subvolumes
1 2 3 |
btrfs subvolume create /mnt/@log btrfs subvolume create /mnt/@cache btrfs subvolume create /mnt/@tmp |
Here are the new subvolumes:
1 2 3 4 5 6 7 |
ls -l /mnt/ total 0 drwxr-xr-x 1 root root 172 Aug 20 12:47 @ drwxr-xr-x 1 root root 0 Oct 18 12:16 @cache drwxr-xr-x 1 root root 14 Oct 18 07:44 @home drwxr-xr-x 1 root root 0 Oct 18 12:16 @log drwxr-xr-x 1 root root 0 Oct 18 12:16 @tmp |
Let’s move the contents of /mnt/@/var/log to /mnt/@log and the same for /mnt/@/var/cache into /mnt/@cache
1 2 |
mv /mnt/@/var/cache/* /mnt/@cache/ mv /mnt/@/var/log/* /mnt/@log/ |
The directory /mnt/@/var/tmp/ should be empty, so there’s nothing to move (you may want to check that).
Adjust the fstab of the installed system to point to the renamed subvolumes and mount the new subvolumes as /var/log, /var/cache, and /var/tmp
1 |
nano /mnt/@/etc/fstab |
You will have to use the correct UUID, which is the same as the one for the already mounted volumes (when you copy and paste, make sure you update both the mount point and the subvolume name consistently):
1 2 3 |
UUID=... /var/log btrfs defaults,noatime,space_cache=v2,compress=zstd:3,subvol=@log 0 2 UUID=... /var/cache btrfs defaults,noatime,space_cache=v2,compress=zstd:3,subvol=@cache 0 2 UUID=... /var/tmp btrfs defaults,noatime,space_cache=v2,compress=zstd:3,subvol=@tmp 0 2 |
Remember to double-check everything!
Let’s unmount the partition
1 |
umount /mnt |
and we should be able to reboot the system, hopefully without problems
Install Timeshift
We can install it from the Ubuntu repositories with
1 |
sudo apt install timeshift |
NOTE: since this is not the latest version, Timeshift will always generate snapshots in the same directory, so there’s no need for the additional fixed mount point as in Arch (see my previous post).
Let’s create a new Timeshift snapshot and browse it with the Timeshift toolbar button “Browse”. We can verify that the directories @/var/log, @/var/cache, and @/var/tmp are empty in the snapshot. The same holds for home (but that was already true thanks to the initial subvolume for home).
Configure grub-btrfs
We have to install grub-btrfs from sources because there’s no official package for Ubuntu. However, after installing the dependencies,
1 |
sudo apt install build-essential git |
the installation procedure is straightforward:
1 2 3 4 5 |
mkdir -p ~/git cd ~/git git clone https://github.com/Antynea/grub-btrfs.git cd grub-btrfs sudo make install |
We now need to configure that to monitor the Timeshift snapshot directory instead of the default one (/.snapshots).
Updated version (20 November 2022)
UPDATE 20/Nov/2022: A new version of grub-btrfsd is available only by installing from sources. What follows is based on this new version. At the bottom of the post, there are still the old instructions, but they’re not valid anymore.
If you see an ASCII splash screen installing grub-btrfs from sources, you’re using the latest version.
Now, let’s make sure grub-btrfs can find Timeshift’s snapshots (remember, we’ve just created one). So let’s run update-grub, and we should see in the end something like the following output:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ sudo update-grub Sourcing file `/etc/default/grub' Sourcing file `/etc/default/grub.d/init-select.cfg' Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.19.0-23-generic Found initrd image: /boot/initrd.img-5.19.0-23-generic ... Adding boot menu entry for UEFI Firmware Settings ... Detecting snapshots ... Found snapshot: 2022-11-19 15:08:51 | timeshift-btrfs/snapshots/2022-11-19_15-08-51/@ | ondemand | N/A | Found 1 snapshot(s) Unmount /tmp/grub-btrfs.shzoN5Pcoo .. Success done |
The last lines prove that grub-btrfs can detect snapshots.
Automatically update the grub menu upon snapshot creation or deletion (20 November 2022)
UPDATE 20/Nov/2022: A new version of grub-btrfsd is available only by installing from sources. What follows is based on this new version. At the bottom of the post, there are still the old instructions, but they’re not valid anymore.
Grub-btrfs provides a daemon watching the snapshot directory and updates the grub menu automatically every time a snapshot is created or deleted.
Important: This daemon requires an additional package:
1 |
sudo apt install inotify-tools |
By default, this daemon watches the directory “/.snapshots” (the default directory for Snapper). Since Timeshift uses a different directory, we have to tweak the configuration for the daemon.
Let’s run:
1 |
sudo systemctl edit --full grub-btrfsd |
We must change the line
1 |
ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots |
into
1 |
ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto |
This is required for Timeshift version 22.06 and later because Timeshift creates a new directory named after their process ID in /run/timeshift every time they are started. Since the PID will be different every time, also the directory will be different. Grub-btrfs provides the command line argument –timeshift-auto to correctly detect the current snapshot directory (In previous versions of grub-btrfs, we had to tweak /etc/fstab to deal with that).
Let’s start the daemon:
1 |
sudo systemctl start grub-btrfsd |
In the journalctl log, we should see something like (where the date and time have been stripped off):
1 2 |
grub-btrfsd[9965]: grub-btrfsd starting up... grub-btrfsd[9989]: Watching /run/timeshift for timeshift to start |
Let’s start Timeshift. In the journalctl log, we should see something like this:
1 2 3 4 |
grub-btrfsd[10307]: detected Timeshift startup, PID is: 10232 grub-btrfsd[10611]: Grub submenu recreated systemd[1]: tmp-grub\x2dbtrfs.e6hSsOzTFf.mount: Deactivated successfully. grub-btrfsd[10612]: Watching /run/timeshift/10232/backup/timeshift-btrfs/snapshots for new snapshots... |
Let’s verify that if we create a new snapshot, grub-btrfs automatically updates the GRUB menu: in a terminal window, run “journalctl -f” to look at the log, then create a new snapshot in Timeshift. In the log, you should see something like the following lines:
1 2 3 4 5 6 7 8 9 |
timeshift-gtk.desktop[10232]: Created directory: /run/timeshift/10232/backup/timeshift-btrfs/snapshots/2022-11-20_17-31-59 grub-btrfsd[10667]: Detected snapshot creation/ deletion, recreating Grub menu timeshift-gtk.desktop[10232]: Created subvolume snapshot: /run/timeshift/10232/backup/timeshift-btrfs/snapshots/2022-11-20_17-31-59/@ timeshift-gtk.desktop[10232]: Created control file: /run/timeshift/10232/backup/timeshift-btrfs/snapshots/2022-11-20_17-31-59/info.json timeshift-gtk.desktop[10232]: BTRFS Snapshot saved successfully (0s) timeshift-gtk.desktop[10232]: Tagged snapshot '2022-11-20_17-31-59': ondemand timeshift-gtk.desktop[10232]: ------------------------------------------------------------------------------ grub-btrfsd[11020]: Grub submenu recreated systemd[1]: tmp-grub\x2dbtrfs.OV56bNx3Ax.mount: Deactivated successfully. |
Similarly, if we delete an existing snapshot, we should see something similar in the log.
Remember that it takes a few seconds for grub-btrfs to recreate the grub menu.
Once we’re sure everything works, we can enable the daemon to always start at boot:
1 |
sudo systemctl enable grub-btrfsd |
The next time we boot, our grub menu will also show a submenu to boot snapshots.
Concerning doing some experiments booting a snapshot and restoring it, please look at my other post.
Old version (with old release 4.11)
UPDATE 20/Nov/2022: These are the older instructions for the previous version of grub-btrfs, where there was no “grub-btrfsd.service” and there was another systemd program (“grub-btrfs.path”).
I leave these instructions here just for “historical reasons”.
1 |
sudo systemctl edit --full grub-btrfs.path |
The file contents
1 2 3 4 5 6 7 8 9 10 11 12 |
[Unit] Description=Monitors for new snapshots DefaultDependencies=no Requires=\x2esnapshots.mount After=\x2esnapshots.mount BindsTo=\x2esnapshots.mount [Path] PathModified=.snapshots [Install] WantedBy=\x2esnapshots.mount |
should be replaced with
1 2 3 4 5 6 7 8 9 10 11 12 |
[Unit] Description=Monitors for new snapshots DefaultDependencies=no Requires=run-timeshift-backup.mount After=run-timeshift-backup.mount BindsTo=run-timeshift-backup.mount [Path] PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots [Install] WantedBy=run-timeshift-backup.mount |
Let’s reload and re-enable the monitoring service:
1 2 |
sudo systemctl reenable grub-btrfs.path sudo systemctl start grub-btrfs.path |
If we have already created a few snapshots, we can run update-grub and verify that new grub entries are created for the found snapshots:
1 2 3 4 5 6 7 8 9 10 11 12 |
sudo update-grub Sourcing file `/etc/default/grub' Sourcing file `/etc/default/grub.d/init-select.cfg' Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.15.0-50-generic Found initrd image: /boot/initrd.img-5.15.0-50-generic ... Detecting snapshots ... Found snapshot: 2022-10-18 14:28:23 | timeshift-btrfs/snapshots/2022-10-18_14-28-23/@ | ondemand | N/A | Found 1 snapshot(s) Unmount /tmp/grub-btrfs.wZwQdRnX7x .. Success done |
Let’s verify that if we create (or delete) a snapshot, grub-btrfs automatically updates the GRUB menu: in a terminal window, run “journalctl -f” to look at the log, then create a new snapshot in Timeshift. In the log, you should see something like the following lines (where the date and time have been stripped off):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
timeshift-gtk.desktop[10195]: App config loaded: /etc/timeshift/timeshift.json timeshift-gtk.desktop[10195]: /dev/sdb10 is mounted at: /run/timeshift/backup, options: rw,relatime,compress=zstd:3,ssd,space_cache=v2,subvolid=5,subvol=/ systemd[1826]: Started Application launched by gsd-media-keys. gsd-media-keys[10256]: Sending 'toggle' message to Guake3 timeshift-gtk.desktop[10195]: Creating new backup...(BTRFS) timeshift-gtk.desktop[10195]: Saving to device: /dev/sdb10, mounted at path: /run/timeshift/backup timeshift-gtk.desktop[10195]: Created directory: /run/timeshift/backup/timeshift-btrfs/snapshots/2022-10-18_14-44-00 timeshift-gtk.desktop[10195]: Created subvolume snapshot: /run/timeshift/backup/timeshift-btrfs/snapshots/2022-10-18_14-44-00/@ timeshift-gtk.desktop[10195]: Created control file: /run/timeshift/backup/timeshift-btrfs/snapshots/2022-10-18_14-44-00/info.json timeshift-gtk.desktop[10195]: BTRFS Snapshot saved successfully (0s) systemd[1]: Starting Regenerate grub-btrfs.cfg... timeshift-gtk.desktop[10195]: Tagged snapshot '2022-10-18_14-44-00': ondemand timeshift-gtk.desktop[10195]: ------------------------------------------------------------------------------ bash[10269]: Detecting snapshots ... bash[10269]: Found snapshot: 2022-10-18 14:44:00 | timeshift-btrfs/snapshots/2022-10-18_14-44-00/@ | ondemand | N/A | bash[10269]: Found snapshot: 2022-10-18 14:28:23 | timeshift-btrfs/snapshots/2022-10-18_14-28-23/@ | ondemand | N/A | bash[10269]: Found 2 snapshot(s) bash[10720]: submenu 'Ubuntu snapshots' { bash[10720]: configfile "${prefix}/grub-btrfs.cfg" bash[10720]: } bash[10269]: Unmount /tmp/grub-btrfs.W93IpgdZoU .. Success systemd[1]: tmp-grub\x2dbtrfs.W93IpgdZoU.mount: Deactivated successfully. systemd[1]: grub-btrfs.service: Deactivated successfully. systemd[1]: Finished Regenerate grub-btrfs.cfg. |
This output tells you that the grub-btrfs monitoring service works!
The next time we boot, our grub menu will also show a submenu to boot snapshots.
Concerning doing some experiments booting a snapshot and restoring it, please look at my other post.
Hello Lorenzo,
thanks for this well written tutorial. I maintain the Slint distribution https://slint.fr and intend to provide a simple way for our users, including the newbies, to handle issues like “system not booting after an upgrade”, so this post is valuable food for thinking about that.
Cheers,
Didier
Hello Didier!
Thank you for the kind words!
I wish you all the best with your distribution.
Slackware was my first Linux distro back to… to many years ago O:)
Hello Lorenzo,
instead of relying grub-btrfs I ended up writing my own script (with limited features) : https://slint.fr/testing/snapshots.sh
However I won’t publish it as is as it uses timeshift commands, which I have found to be less reliable for restoring snapshots that the GUI. Instead, I will rewrite it using btrfs commands directly, removing the dependency on timeshift.
Hi Didier,
Have you considered using snapper? I haven’t used it yet, but if one wants to do without timeshift it might be a good alternative.
Hi Lorenzo,
Yes I have considered snapper. It can write boot entries for the snapshots in the GRUB menu so no need for grub-btrfs if you use it.
To investigate further I have installed OpenSUSE Leap 15.4 yesterday. Snapper has indeed more features than timeshift and is not as limited wrt the layout of the subvolumes. However I think that my limited use case do not need it, further the way it writes boot entries would not help blind users of Slint. This notwithstanding I will take inspiration on the way they do that.
Hi Didier,
I agree that Snapper is much more powerful but even more complicated.
For my use case, Timeshift is enough 🙂
Thanks for the post. Very helpful. I installed using this guide on Linux Mint 21.1 and for the defrag and compress I had to use:
sudo btrfs fi defragment / -r -c
Otherwise it didn’t compress.
Thanks for the feedback!
I updated the post with the additional argument “-czstd”.
I’m stuck at this stage. Cannot go further, sorry novice here, can you clearly brief here with example mounting command lines. When I try it says there is no …. on etc/fstab. I already try to add subvolumes into fstab so cannot mount the subvolumes at the beginning. Like a dilemma.
“Adjust the fstab of the installed system to point to the renamed subvolumes and mount the new subvolumes as /var/log, /var/cache, and /var/tmp
nano /mnt/@/etc/fstab
You will have to use the correct UUID, which is the same as the one for the already mounted volumes”
this part a bit for experienced users, please simple it for us too.
Thanks
I’m afraid I can’t think of anything more detailed than this. That’s an advanced topic that assumes you’re familiar with the basics of Linux filesystems and with btrfs in general.
I followed for Tuxedo OS but could not mount as a novice user. Would be nice if you look for it
As I said in the other answer, that’s an advanced topic that assumes you’re familiar with the basics of Linux filesystems and with btrfs in general. Moreover, if you use another distribution, you’ll have to adapt things yourself.
with example scenarios or screenshots?
I don’t understand what you’re saying
Lorenzo
One question came to mind regarding your Guide on BTRFS and grub-btrfs installation & configuration.
I’m currently running Ubuntu 22.04.2 LTS on this particular machine.
When the next LTS (24.04 LTS) is released, would you expect any problem during the automated Ubuntu Upgrade process. For example, the new 24.04LTS would not know anything about grub-btrfs.
Thanks for any thoughts regarding future OS upgrades.
Brian
Hi Brian
since you installed grub-btrfs from the git repository, the Ubuntu update process will not touch it. These programs are shell script so I would expect them to keep on working. Of course, doing an update of the git repository of grub-btrfs or a fresh installation from git will give you the latest version of grub-btrfs, which might or might not work with the new version of Ubuntu. It would be best to check grub-btrfs GitHub repository for possible bug fixes or updates.
Hi Lorenzo,
thanks for this article.
I only think using subvolumes for /var/… is not the preferred way.
btrfs-grud shows another way here: https://github.com/Antynea/grub-btrfs/blob/master/initramfs/readme.md
Regards
Fabian
Not the whole /var, only some of its subdirs that are not meant to be part of a snapshot. That’s the same scheme adopted by endeavouros.
Lorenzo.. I am still running Ubuntu 22.04.3 LTS using grub-btrfs and the system installed/configured to use BTRFS as per your article here.
But with April 2024 approaching faster than I realize, I thought I’d ask if you might see any btrfs-grub or btrfs related issues in an Ubuntu LTS upgrade from 22.04.3 LTS to 24.04 LTS. Such as, would the upgrade overwrite configs for anything already working.
Brian, I’m not using timeshift anymore: I switched to snapper, which, at least in Arch, is automatically configured with grub-btrfs and works like a charm (see https://www.lorenzobettini.it/2023/03/snapper-and-grub-btrfs-in-arch-linux/). Snapper is much more powerful and easier to deal with especially with the program btrfs-assistant. I haven’t been using Ubuntu for a while as well.
Technically, there should be no problem. Of course, the best thing to do is to follow the GitHub repository of the related projects, and, for sure, to do some experiments (e.g., in a VM) with the current development release of Ubuntu to catch possible problems before it’s officially released.
I guess I should look at snapper since I’ve seen quite a few people comment on it in the past 6 months.
Thanks
Yes, I suggest you take a look at snapper, which is much more flexible and easier (especially with btrfs-assistant)
This works for OpenMandriva too, with slight modifications to the instructions.
1) You need to “sudo dnf install make git” instead of “sudo apt install build-essentials git”, because OpenMandriva doesn’t have make installed by default.
2) You need to “sudo systemctl enable crond.service” because OpenMandriva doesn’t have cron enabled by default.
3) You need to “sudo ln -s /boot/grub2 /boot/grub” and “sudo ln -s /usr/bin/grub2-script-check /usr/bin/grub-script-check” because OpenMandriva uses the “grub2” set of filenames for GRUB-related files, and Timeshift won’t find them without symbolic links to the filenames it’s expecting.
Hopefully someone with OpenMandriva will benefit from this info.
Thanks for the updates.
Please note that the 3rd point is not strictly necessary: you can tweak the grub-btrfs configuration file with the paths for grub2 (they are documented in the configuration file for fedora based distros by the way).
I prefer to use symlinks instead of editing the configuration file, because symlinks can’t possibly be overwritten by possible future changes to grub-btrfs’ source code, and simultaneously solve similar problems for any other utilities looking for system files with specific names.
Pingback: A look at Ubuntu 23.10 Mantic Minotaur | Lorenzo Bettini
Thank You very much for this! I made my own Xubuntu Clone. Now i have my encrypted de-snapted adblocking and Auto-Snapshot Grub2 System. Everything is very fine!
Thank you Lorenzo for this, installed and all works good.
Pls could you prepare also a tutorial for ubuntu with btrfs snapper configuration?
Thank you for the kind words, Roberto.
Nowadays, I’m using Arch mainly, so I haven’t been using Ubuntu for some time. For snapper, I’d try to rely on btrfs-assistant, which is what I’m using Arch.
Hey Lorenzo! Thank you so much for all your guides, they have been amazingly helpful!
I have been able to do a full snapper and grub-btrfs setup in Arch thanks to your instructions, but I’m utterly failing at making my snapshots bootable under KDE Neon (Ubuntu derivative).
Do you think creating the subvolume structure you recommend here would solve it?
When I do:
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@cache
btrfs subvolume create /mnt/@tmp
My volumes end up looking like:
@/root/log
Is this as intended?
I feel like I’m missing something super obvious here, like the bloody subvolids in Arch…
Thank you!
Are you talking about snapper in KDE neon? I have no experience with snapper in Ubuntu distros but I’d try to use the same layout as Arch. The “@/root/log” doesn’t sound right to me.
If you’re talking about timeshift, then what’s shown in this article should apply to KDE neon as well.
Yeah, I’m currently using Timeshift but wanted to try and set snapper like I can do with Arch in Ubuntu and it’s derivatives.
I’ll try to use the same layout.
Thanks!
Yeah that’s defo going to be the key factor I think…
Back to the drawing board 😀
@Obsi
Lorenzo’s writeup on Timeshift, BTRFS, etc did state the following on why the need to create those sub-volumes & it involves the issue of booting from snapshots…
> Create additional subvolumes
>
> With the current subvolume layout, things like logs and caches will end up in snapshots, giving you problems when you try to boot a snapshot (which we want to be able to do).