Btrfs Best Practice

When using btrfs, you can simply do everything as before, but to take advantage of its benefits, you’ll need to do some things differently.

UEFI and GPT

Use GPT as the partition table and create a single EFI partition marked as bootable.

why ?

GPT: The GPT partitioning scheme is the successor to the MSDOS/MBR partitioning scheme. GPT is newer, more robust, and more future-proof than MBR. Multiboot can be implemented robustly with GPT.
EFI Partition: The location where the bootloaders of GRUB, Windows, or others are stored. Bootloaders rarely change. The file system is FAT so that it can be read and booted by UEFI. The partition is marked as “bootable.”

single large btrfs partition

Use a single large btrfs partition and create subvolumes instead of using multiple partitions.

why ?

Previously, separate partitions were used for /boot, /, and /home (sometimes even more) for good reasons.
btrfs has a built-in volume manager. This makes it easier to keep the different parts of an installation together in a single partition (a btrfs volume). Instead of different partitions, subvolumes are used within the btrfs volume.

  • The space within a volume is dynamically shared by all subvolumes and snapshots.
  • The space is easily expandable using the volume manager.
  • A volume can span multiple disks.
  • A volume can be converted to RAID.
  • A volume backup captures all subvolumes and snapshots.

swap

Use a real swap partition instead of a swap file

why?

A swap file in btrfs is a workaround that should only be used when all other options have been exhausted. According to the developers of btrfs, a swap file in btrfs must be specially marked. This marking impedes various features of btrfs.
Contrary to popular belief, a swap partition is not harmful to an SSD. In particular, a swap file is no more gentle on an SSD than a swap partition.

btrfs layout

Use a btrfs layout that is supported by as many tools as possible

@ → /

Use the btrfs name @ for the subvolume mounted in the Linux filesystem at the / location

@home → /home

Use the btrfs name @home for the subvolume mounted in the Linux filesystem at the /home location

why?

This way, you can use various tools that are configured for this “Ubuntu layout.” Of course, btrfs also offers other options.
The layout plays an important role in creating snapshots of individual subvolumes and rolling back to such a snapshot.
No matter which layout you choose, it must either be supported by the tools you use, or you must be able to keep track of your snapshots even after a rollback. If you lose track and an “old” snapshot is left behind, you’ll quickly run into space problems.
You can find more information about the btrfs layout in the btrfs documentation.

/boot

Do not make /boot a separate partition or subvolume

why?

All kernels and the initram disk are located in /boot. Both are necessary for booting, and both are closely linked to the entire system. When taking snapshots of the entire system (@), the appropriate kernels and initram disk should always be included. This will automatically be the case if /boot is not independent, but part of @

Automatic snapshots of @

Install the necessary tools to automatically create and delete snapshots

  • Before and after an update
  • After a successful boot
  • According to a schedule (hourly, daily, weekly, monthly)
why?

This allows for easy rollbacks if something goes wrong.

  • State before the update
  • State at which the system last successfully booted
  • State before you corrupted your configuration
  • State before you deleted important system files
  • State one hour, one day, one week, or three months ago
    It also allows you to view individual files in their “previous state”
  • A deleted configuration file
  • A file in which you accidentally made a syntax error
    You can simply copy and restore the file from the snapshot
    Or you can compare it with the version from three weeks ago

Automatic snapshots of @home

Configure to automatically create and delete extra snapshots of @home

  • According to a schedule (hourly, daily, weekly, monthly)
why?

If @home is a separate subvolume, the snapshots of @ and @home are performed separately. When the system is rolled back to its previous state four weeks ago, the data under /home remains unchanged; instead, all changes made in /home/* are retained. The system is restored to its previous state four weeks ago, but user data remains untouched. This is because Linux is traditionally a multi-user system, where system and data are kept relatively strictly separate.

Independently, you can restore individual files from @home snapshots for individual users.

  • Files deleted one hour, one day, one week, or three months ago.
  • A single accidentally deleted LibreOffice file.
  • A deleted configuration file.
    You can simply copy the file from the snapshot and restore it.
    Or you can compare it with the same file from three weeks ago.

noatime

Ensure all btrfs volumes are mounted with noatime as option.

why?

This makes btrfs faster and avoids generating unnecessary metadata when files are only read. Details are linked at:
make btrfs faster

compression

Be sure to use the compression built into btrfs.

why?

This saves space on the volume and, in most cases, also leads to faster data reading and writing. Especially if you have sufficient RAM and a fast processor. The selected compression level is a matter of taste. (My tip: 9)

:footprints:
Btrfs in the wiki
btrfs best practice :de:

7 Likes

Linking your nice article on brtfs send | receive [HowTo] use btrfs send / receive

2 Likes

I agree with that, but is it possible to do it when installing Manjaro with Calamares ? You can create de btrfs partition, but you cannot create subvolumes as @home, or even @var, @logs and so on ?

Is it possible to make snapshots only of the hidden files of /home/$USER?

calamares already does that automatically, or at least, if you go with automatic partitioning. It will create four subvolumes in addition to the top-level subvolume (which cannot be deleted)… :point_down:

  • @, which will be mounted as /
  • @home, which will be mounted as /home
  • @cache, which will be mounted as /var/cache
  • @log, which will be mounted as /var/log

calamares will however not create any additional subvolumes, nor will it set the default subvolume when the partition is mounted without explicitly specifying a subvolume in the mount options. So the default subvolume will remain the top-level subvolume, in which the four above-listed subvolumes are visible and accessible as directories.

It isn’t really necessary to set the default subvolume, but it might make maintenance and/or system repair via a chroot a little easier if you set the default subvolume to @.


Edit: My own subvolume layout is… a little more elaborate… :face_with_hand_over_mouth:

:point_down:

Notes:

  1. In order to have /usr on a separate subvolume or — in the event of using ext4 or another traditional filesystem — on another partition, you need to either have the “usr” hook in /etc/mkinitcpio.conf, or use the “systemd” hook instead of the “udev” hook. See mkinitcpio - ArchWiki.

  2. I also have a separate subvolume for/etc, but this is a nested subvolume, i.e. it is a subvolume (and thus a directory) inside the @ subvolume. This is because I am mounting / read-only, while /etc is best kept writable, and you need it to be readable when the root subvolume is mounted, because otherwise init won’t find /etc/fstab. As such, when / is mounted, /etc/fstab is readable — but mounted read-only, just like / — and then /etc/fstab itself specifies that /etc should be (re)mounted read/write.

    /etc is my only nested subvolume. All others are in a flat list.

    It is possible to make /etc not be a nested subvolume, but this would require adding /etc/fstab to the "FILES=’ line in /etc/mkinitcpio.conf so that it gets loaded into the initramfs — it works; I’ve tried it! — and then every change to /etc/fstsab would require rebuilding the initramfs.

1 Like

My godness, what a fstab !! :grimacing:

I only have @, @log (/var/log) and @cache (/var/cache). And I keep using an ext4 /home partition. Maybe there is a benefit of have a @home subvolume in the btrfs same partition as @.

In addition, i use grub-btrfs in order to have all my @ snapshots at boot, so i cannot use a separate /boot partition.

But is there any reason to have all those subvolumes ? Do you do specific tasks with them ?

What is the advantage of your BACKUPS partition mounted on the top-level subvolume over a standard ext4 one ?

Thanks

1 Like

Well, the benefit would be that all free space on the filesystem is shared among all subvolumes.

How important that is will of course depend on your personal needs and preferences.

Well, I already had that partition from before my conversion to a setup with subvolumes, and it was originally an ext4 partition. So technically, I needn’t have made it into a separate partition, but it was already there, so… :wink:

Of course there is. Many of them are mounted read-only during normal system operation. It’s also more robust, because every subvolume has its own inode tree.

That partition actually also has subvolumes on it, but I am not mounting them explicitly — even though I could. It’s more a matter of robustness.

As for why it’s btrfs and not ext4, the answers are “copy-on-write” and “inline compression”. :wink:

2 Likes

So true ! :grin:
So you disable CoW on @home ? Or at least on some folders as ~/.cache, ~/.thunderbird ?

What for ? I mean, is it for security purpose ?
I understand that read-only is more robust, sure, but i do no see in which specific cases I would need those read-only subvolumes.
Is it to have a nearly immutable partition ?

No, why would I do that? :thinking:

(I don’t use thunderbird, by the way. I use kmail.)

Security is an additional benefit, but it’s also for robustness.

Just ponder the following. In every UNIX system, there are processes running with root privileges. So it’s not just the root user, but you’ve also got system processes — for instance systemd, just to name one — running under UID 0.

Every process running under UID 0 has write access to anything that’s mounted read/write, even if the permissions say otherwise. This was defined in the kernel, because the root account has to be able to update the software, restore broken permissions, restore backups, and so on. Therefore, the root account bypasses all write restrictions, except those that root can undo, such as an ACL or a read-only mounted filesystem/subvolume.

Now, imagine that one of the processes running as root goes haywire and starts writing gibberish to the filesystem, or starts overwriting files. Or even simpler than that, on a read/write-mounted filesystem, files will be held open by the kernel, and their contents will only be (reliably) synchronized with the physical storage medium upon system shutdown.

All of this leaves the door open to file and/or filesystem corruption. File hierarchies like /usr are supposed to be read-only — not necessarily meaning that they must be mounted read-only, but that nothing may expect to be able to write to /usr. But if a root-owned process goes rogue — or it is a malicious process, such as from a compromised program — then that may still happen. Mounting the filesystem (or subvolume) read-only prevents that scenario.

And not only that, but the UNIX philosophy also distinguishes between four different types of data, whereby there is some overlap. :point_down:

  • Static data
  • Variable data
  • Shareable data
  • Non-shareable data

/usr for instance is static and shareable. It can be exported over the network — when mounted read-only, of course — to diskless workstations.

/etc is semi-static and non-shareable. Its contents are specific to the local machine.

/var for instance is variable and non-shareable. Its contents are specific to the local machine.

/home is variable and shareable. It can be exported over the network to diskless clients.

So, keeping the above in mind, there is method to my madness. :stuck_out_tongue:

That is one way of looking at it, yes, but immutable systems are normally intended for protecting people from themselves. :stuck_out_tongue:

That’s what I have physical backups for, on the spinning HDD. They are made with timeshift using the rsync method. In addition to that, I also separately make manual backups of /home at least once every day.

I don’t use btrfs snapshots.

/boot is included in the rsync backups. :wink: It’s an almost complete backup of the whole system, minus /var/cache, /var/log, /var/spool and /var/tmp.

It even includes the home directories, but as I said, I do make separate backups of those as well, so I can always restore my most recent backup of /home, which will never be older than a day.

1 Like

For folders with files that change very often (databases or mailboxes), COW causes performance drops and fragmentation.
But if you do not use btrfs snapshots, it’s pointless :slight_smile:

1 Like

Fragmentation is not an issue on SSDs. :wink: On a spinning disk, yes, but the btrfsmaintenance package includes a systemd timer for defragmenting a btrfs filesystem.

I don’t use it, though, because I have autodefrag as a mount option for the partition on the HDD. So it’ll defragment itself.


Sorry for the belated reply — I missed it, but then again, you were asking @andreas85. :stuck_out_tongue:

The answer is “no”. A btrfs snapshot is always a copy of an entire subvolume at a given point in time, starting off as merely a reflinked copy — meaning that it’s more like a hard-link of every single file — but which then remains static as the main subvolume gets updated via the copy-on-write principle.

In other words, initially the snapshot and the subvolume it is the snapshot of will be occupying the same blocks on the drive — and thus, the snapshot will not be taking up any space yet — but as the main subvolume gets updated, the blocks on disk that its files originally occupied will not be freed and will remain in use by the snapshot.

One caveat is that if you make a snapshot of a subvolume that contains one or multiple nested subvolumes, then those nested subvolumes will not be included in the snapshot. Instead, the snapshot will only contain an empty directory of the same name as the nested subvolume, which upon restoring the snapshot will become the mountpoint for the nested subvolume again.

4 Likes

Having these subvolumes as read-only volumes doesn’t cause any problem for booting, right? And then, if you want to install an app or update your system, you have a hook that remounts your subvolumes as read-write, something like that?

Nope, none, because nothing should be expected to write to them.

/etc is however a grey zone. In a default installation, /etc/resolv.conf will be a regular file that gets written to by NetworkManager or systemd-resolved, but this can be circumvented by making it a symlink to /run/NetworkManager/resolv.conf — do read the documentation, though.

No, no hook. I do it manually. I always update from the command line anyway. :wink:

I suppose I could write a shell function that does the whole thing in one go, but I don’t really have a need for that, as I’m already so accustomed to doing the routine by hand.

For instance, for a full system update, I would do the following in a tty, while logged out of the GUI environment, and having elevated my privileges to root with “su -”… :point_down:

systemctl stop sddm
for fs in /boot/efi /boot /usr /opt ; do mount -o remount,rw $fs ; done
pacman-mirrors -f && pacman -Syu

And then there are a few more steps, like updating my AUR packages — for which I need to log into my own account — and checking for .pacnews, checking for orphans (and removing them), and emptying the package cache.

And when all of that is done, I run a manual fstrim on all partitions — I also check whether a btrfs balance is warranted — and then I reboot. :wink:

:wink:

1 Like