Arch Linux Upgrades Deserve a Safety Net: Automating Btrfs Snapshots with Pacman Hooks
Rolling-release upgrades can leave Arch Linux unbootable. A pacman hook that snapshots your Btrfs root before every transaction gives you a rollback point—if you plan for disk space and bootloader integration.
05 Dec 2025, 18:50 UTC

The upgrade gamble
Arch Linux is a rolling release. There is no "Arch 2.0" to wait for; you run pacman -Syu and pull whatever the maintainers have pushed. Most of the time this is uneventful. Occasionally a kernel module fails to build, a shared library changes ABI, or a graphics driver conflicts with your hardware. The result is a system that will not boot.
Recovering usually means booting an Arch live USB, mounting your root partition, arch-chrooting in, and downgrading or rebuilding the broken package. It works, but it costs time and assumes you have installation media handy. If your root filesystem is Btrfs, you can shortcut that recovery by snapshotting the filesystem moments before pacman touches anything.
Hooking into pacman
Pacman supports transaction hooks: small INI-style files in /etc/pacman.d/hooks/ with a .hook extension. A hook defines a trigger (for example, any package upgrade) and an action to run at a specific point in the transaction. The When = PreTransaction option runs your script before pacman downloads or installs anything.
Because pacman executes as root, the hook inherits root privileges. That is necessary for Btrfs subvolume operations, but it also means a buggy script can interfere with the upgrade. Test any hook manually before letting pacman call it.
A minimal snapshot hook
The following pattern is illustrative, not a drop-in replacement for a tested backup strategy. It assumes / is a Btrfs subvolume (not merely a directory on a Btrfs partition) and that you have btrfs-progs installed.
First, create the action script. Run this as root or with sudo:
sudo tee /usr/local/bin/pacman-btrfs-snapshot > /dev/null <<'EOF' #!/bin/bash set -euo pipefail SNAPSHOT_DIR=/.snapshots TIMESTAMP=$(date +%Y%m%d-%H%M%S) SNAPSHOT_NAME="pre-upgrade-$TIMESTAMP" mkdir -p "$SNAPSHOT_DIR" btrfs subvolume snapshot -r / "$SNAPSHOT_DIR/$SNAPSHOT_NAME" EOF sudo chmod 755 /usr/local/bin/pacman-btrfs-snapshot
Then create the hook file:
sudo tee /etc/pacman.d/hooks/90-btrfs-snapshot.hook > /dev/null <<'EOF' [Trigger] Operation = Upgrade Type = Package Target = * [Action] Description = Create Btrfs snapshot before system upgrade When = PreTransaction Exec = /usr/local/bin/pacman-btrfs-snapshot EOF
Before your next upgrade, run the script manually to confirm it succeeds. After an upgrade, verify the snapshot exists:
sudo btrfs subvolume list /
Look for a path containing pre-upgrade and the date of the transaction. If the script exits non-zero, pacman may abort the upgrade depending on your version and hook configuration, so keep the script simple and idempotent.
Getting back—and paying the bill
A snapshot is only useful if you can boot it. Unlike ext4, Btrfs snapshots are full subvolumes; the snapshot contains its own /boot, kernel, and initramfs. To boot from the snapshot you need a bootloader entry that points to the snapshot's kernel and passes the correct rootflags=subvol=... argument. Tools such as grub-btrfs can generate these entries automatically, but they are not part of a default Arch install. If you use a separate /boot partition, the snapshot may not contain the bootloader files you expect, and manual GRUB configuration becomes fragile.
The other cost is disk space. Btrfs snapshots start as metadata-only clones, but as pacman replaces files, the old blocks remain allocated in the snapshot. A month of daily upgrades with unpruned snapshots can consume gigabytes. You must delete old snapshots yourself:
sudo btrfs subvolume delete /.snapshots/pre-upgrade-20260101-120000
There is no automatic retention in the minimal hook above.
| Approach | Setup | Rollback path | Space management |
|---|---|---|---|
Manual snapshot before -Syu | Run one command | Manual GRUB or live USB | Manual |
| Pacman hook (shown above) | One script + one hook file | Same, but automated creation | Manual or scripted |
Snapper + grub-btrfs | Package install + config | GRUB menu entries | Timeline retention |
Actionable checklist
- Confirm your root is a Btrfs subvolume:
sudo btrfs subvolume show /. If it fails, this pattern does not apply. - Install
btrfs-progsif it is missing. - Deploy the script and hook above, then run the script by hand.
- Perform a small upgrade and verify the snapshot with
btrfs subvolume list /. - Decide how you will boot the snapshot—manual GRUB entry,
grub-btrfs, or live USB—before you actually need it. - Set a cron job or systemd timer to delete snapshots older than your retention window.
This approach is not a substitute for off-machine backups. A snapshot protects you from a bad upgrade on the same disk; it does not protect you from disk failure. But for a rolling-release system, it turns a panicked recovery session into a routine menu choice.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.