A simple Btrfs Snapshot system installation and setup guide for Arch Linux along with Snapper, GRUB and Fish Shell.
This system allows you to:
- Take snapshots with a few commands via Fish Shell (
arch snapshot) - Automatically create snapshots before and after system updates with
pacman. - Select Boot to past snapshots directly from the GNU GRUB page.
- Arch Linux operating system uses Btrfs as the Root File System (
/) - Use GRUB as Bootloader.
- Use Fish Shell as the main shell.
Warning
Warning
-
Don't use
snapper rollbackdirectly from the base OS:-
On Arch Linux using the Btrfs subvolume (
@and/@snapshots) layout, running thesnapper rollbackcommand directly while booting normally will result in the main subvolume crashing or a Kernel Panic on the next boot! -
How to Rollback Correctly:
-
Reboot the machine and select Boot into the desired Snapshot via GRUB Menu (
Arch Linux snapshots). -
Once temporarily logged in via Snapshot, open Terminal and run the command:
sudo snapper rollback
- Then reboot the machine again to return to the main system that has already rolled back.
-
-
-
Rollback returns only Root (
/):-
All Root Partition data (including Package, Configuration in
/etc) will revert to the Snapshot date. -
If
/homeis not separated into a separate subvolume (for example,/homeis included with/): all your personal files, documents, or desktop files will be sent back in time! -
Tip: Always backup important data in
/homeexternally or separate Subvolume@homebefore running this script.
-
-
Deleting large files Doesn't help free up space immediately:
-
On Btrfs if you delete large files in the system But the file is still saved in the old Snapshot. Disk space will not be regained.
-
If the disk is so full that Btrfs becomes Read-Only, delete the old Snapshot with the command:
arch snapshot -d <ID_to be deleted>
-
-
After a major system update (e.g.
pacman -Syuwith a Linux Kernel update), thegrub-btrfsdservice will automatically sync the Snapshots menu in GRUB. -
If you opened GRUB and couldn't find the latest snapshot, you can manually create a new GRUB menu:
sudo grub-mkconfig -o /boot/grub/grub.cfg
-
If you type
arch snapshotand Shell sayscommand not found: -
Check if the current user has Fish Shell enabled.
-
Run the command to load the new config:
source ~/.config/fish/config.fishsource ~/.config/fish/config.fish
- Check permissions of function file:
ls -l ~/.config/fish/functions/arch.fish(must be Owner of that user)
- Check permissions of function file:
Important to know
Important:
install.fishchanges system configuration files, initramfs, GRUB, Snapper configuration, mounts, and Btrfs snapshot storage. Read this section before running it.This installer is intended for an already-installed Arch Linux system using Btrfs for
/and GRUB as the bootloader. It is not an Arch Linux installation script and should not be run from the Arch ISO/chroot unless you specifically know that the target system is correctly mounted and bootable.
Step 1: Requirements
Before starting, make sure:
- You are booted into the normal installed Arch Linux system.
/is on Btrfs.- The system uses GRUB.
fishis installed.sudoworks for your user.- You have enough free Btrfs space for snapshots.
- You have a working internet connection if the installer needs to install missing packages.
- You have a way to recover the machine if a boot configuration change fails (for example, an Arch ISO/USB).
Check the most important conditions:
findmnt -no FSTYPE /findmnt /bootctl statussudo grub-install --versionfish --versionThe first command findmnt -no FSTYPE / should report:
btrfs
If / is not Btrfs, do not continue.
Step 2: Get the repository
Clone the repository:
git clone https://github.com/KaiJu144/Snapper-Setup-Arch-Linux.gitcd Snapper-Setup-Arch-LinuxIf you already cloned it:
cd Snapper-Setup-Arch-Linux
git pullCheck that the installer exists:
ls -l ./install.fishMake it executable if necessary:
chmod +x ./install.fishStep 3: Check the installer before running it
The installer is written for Fish.
First perform a syntax-only check:
fish -n ./install.fishIf there is no output, Fish accepted the syntax.
You can also verify the exit status:
echo $statusExpected result:
0
Do not continue if the syntax check reports an error.
Step 4: Choose the installation mode
Run:
sudo ./install.fishThe installer provides two modes.
Choose this when you want to keep your existing Snapper snapshots.
This mode is the recommended choice for an existing installation because it does not intentionally delete the existing snapshot history just to make the numbering start at #1 again.
It installs/configures the Snapper + GRUB-Btrfs integration and includes the fixes needed for booting snapshots through the GRUB-Btrfs OverlayFS mechanism.
Use this mode when:
- you already have useful snapshots;
- you want to preserve snapshot history;
- you do not care that the next snapshot number is greater than
#1; - you are upgrading/fixing an existing Snapper setup.
Recommended for most existing systems: Option 1.
Choose this only if you explicitly want to start the Snapper snapshot storage over so that the new snapshot history can begin again from a low number.
This mode is destructive to the old snapshot history after the reset has been successfully committed.
Before selecting it:
- Make sure you do not need the old snapshots.
- If you may need them later, copy/export them first.
- Make sure you have a recovery USB available.
- Do not interrupt the machine while the reset is being performed.
The reset mode is designed to avoid deleting the old snapshot tree before the new setup is ready. It also keeps temporary recovery information while the operation is in progress.
Do not choose Option 2 simply because the snapshot number is large. Snapshot numbers are identifiers; a high number does not mean the system is broken.
Step 5: What the installer configures
Depending on the selected mode, the installer configures the Snapper root setup and the GRUB-Btrfs integration.
The important boot-related pieces include:
- the Snapper root configuration;
- the
@snapshotsBtrfs snapshot storage; - the
/.snapshotsmount; grub-btrfs-overlayfsin the activemkinitcpioHOOKS=...line;- the GRUB-Btrfs snapshot kernel parameter;
- the OverlayFS remount condition used when booting a snapshot;
grub-btrfsd;- regenerated initramfs images;
- regenerated
/boot/grub/grub.cfg; - Snapper timeline/cleanup services where applicable.
The OverlayFS remount condition is intentionally:
[Unit]
ConditionKernelCommandLine=!snapper_snapshot_boot=1This prevents systemd-remount-fs.service from incorrectly remounting the snapshot boot environment when snapper_snapshot_boot=1 is present.
Do not reboot while the installer is still running.
The installer may perform operations such as:
mkinitcpio
grub-mkconfig
systemctl daemon-reload
systemctl enable/start grub-btrfsd
Wait until the installer reports that installation/verification completed successfully.
If the installer stops with an error, do not immediately rerun it repeatedly. Read the error first and check the state of the system.
Step 7: Verify the installation after it finishes
Check the active root filesystem:
findmnt /Check that the snapshot mount exists:
findmnt /.snapshotsCheck Snapper:
sudo snapper -c root listCheck the GRUB-Btrfs daemon:
systemctl status grub-btrfsd --no-pagerCheck for failed systemd units:
systemctl --failedA healthy result is:
0 loaded units listed.
Step 8: Verify the initramfs hook
Check the active HOOKS= line:
grep '^HOOKS=' /etc/mkinitcpio.confIt must contain:
grub-btrfs-overlayfs
Then rebuild the initramfs manually if you want an additional verification:
sudo mkinitcpio -PA successful build should reach:
Initcpio image generation successful
A warning such as:
consolefont: no font found in configuration
is not by itself a Snapper/GRUB-Btrfs failure if the initramfs build completes successfully.
Step 9: Verify GRUB snapshot entries
Regenerate GRUB:
sudo grub-mkconfig -o /boot/grub/grub.cfgDuring generation, GRUB-Btrfs should detect the available snapshots.
You should see output similar to:
Detecting snapshots ...
Found snapshot: ...
The exact snapshot numbers and descriptions will depend on your system.
Test creating a snapshot
Create a manual snapshot using the project's helper if it is installed:
arch snapshotThen list snapshots:
arch snapshot -lAlternatively, use Snapper directly:
sudo snapper -c root create --description "Installation test"sudo snapper -c root listConfirm that the new snapshot appears.
Test booting a snapshot
Before testing, make sure you have saved your work.
Reboot:
sudo rebootAt the GRUB menu, look for the GRUB-Btrfs snapshot submenu.
Select a known-good snapshot.
The snapshot boot should use the OverlayFS mechanism configured by the installer. The booted snapshot should be usable for testing without modifying the read-only snapshot itself.
After booting, check:
cat /proc/cmdlineWhen booted through the snapshot entry, the command line should contain:
snapper_snapshot_boot=1
Also check:
findmnt /A snapshot boot using the OverlayFS setup can show / as an overlay filesystem. This is expected for the snapshot-boot path.
If the system boots normally but systemctl --failed is clean
That is a good sign.
For example:
systemctl --failedreturning:
0 loaded units listed.
means systemd currently has no failed units.
It is still recommended to test an actual snapshot boot before considering the GRUB-Btrfs setup fully tested.
If you choose the reset mode
After a successful reset:
sudo snapper -c root listshould show the new snapshot history.
Do not manually delete random Btrfs subvolumes to force the numbering lower.
If reset mode fails before its cleanup/commit phase, the installer is designed to keep the old snapshot storage available for recovery where possible.
If reset mode has already reached its final cleanup phase, automatic rollback is intentionally not attempted because the old snapshot tree may already be partially removed.
Important safety notes
The project uses a dedicated Btrfs snapshot storage layout. Do not run commands such as:
sudo btrfs subvolume delete /...unless you know exactly which subvolume is being removed.
/.snapshots is a mount point used by Snapper. It is not necessarily the actual snapshot-storage subvolume.
Always inspect first:
findmnt /.snapshots
sudo btrfs subvolume list /A high snapshot number is normal. Use Option 2 only when you intentionally want to discard the old snapshot history.
Any script that changes initramfs and bootloader configuration has an inherent boot-recovery risk. Keep an Arch ISO/USB available.
Quick post-install checklist
Run:
findmnt -no FSTYPE /findmnt /.snapshotssudo snapper -c root listsystemctl --failedsystemctl is-active grub-btrfsdgrep '^HOOKS=' /etc/mkinitcpio.confgrep -n 'snapper_snapshot_boot' /etc/default/grub-btrfs/configExpected:
/→btrfs/.snapshots→ mounted- Snapper → lists snapshots
systemctl --failed→ no failed unitsgrub-btrfsd→activeHOOKS=→ containsgrub-btrfs-overlayfs- GRUB-Btrfs configuration → contains
snapper_snapshot_boot=1
Troubleshooting
If the syntax check fails:
fish -n ./install.fishFix the reported Fish syntax error before executing the installer.
If mkinitcpio fails:
sudo mkinitcpio -PRead the first actual ERROR: message. Do not treat an unrelated warning as the failure.
If GRUB does not show snapshots:
sudo grub-mkconfig -o /boot/grub/grub.cfgsystemctl status grub-btrfsd --no-pagersudo snapper -c root listIf snapshot boot reaches the system but produces systemd remount-related failures, verify:
sudo cat /etc/systemd/system/systemd-remount-fs.service.d/snapshot-overlay.confIt should contain exactly:
[Unit]
ConditionKernelCommandLine=!snapper_snapshot_boot=1Then:
sudo systemctl daemon-reloadand rebuild the initramfs/GRUB configuration if required.
Recommended workflow
For a normal existing system:
Clone/update repository
↓
fish -n ./install.fish
↓
./install.fish
↓
Choose Option 1
↓
Wait for verification to finish
↓
Check systemctl --failed
↓
Check Snapper
↓
Check GRUB snapshot entries
↓
Reboot
↓
Test a known-good snapshot
For intentionally starting snapshot history over:
Backup anything important
↓
Clone/update repository
↓
fish -n ./install.fish
↓
./install.fish
↓
Choose Option 2
↓
Confirm that old snapshots may be removed
↓
Wait for reset + verification
↓
Check Snapper
↓
Check GRUB
↓
Reboot
↓
Create/test a new snapshot
Final recommendation: If you are unsure which option to choose, use Option 1. Preserving existing snapshots is safer than resetting the snapshot history.
Important to know
This section describes how to install the same Snapper + GRUB-Btrfs + OverlayFS setup used by this project without running install.fish.
[!IMPORTANT] This guide is for an already-installed Arch Linux system whose
/is on Btrfs and whose bootloader is GRUB. It is not an Arch Linux installation/chroot guide.
[!WARNING] This procedure changes
/etc/fstab, Snapper configuration,mkinitcpio, GRUB-Btrfs configuration, initramfs, and the GRUB menu. Keep an Arch ISO/USB recovery medium available and back up important data first.
Step 1: Verify prerequisites
Boot into the normal installed Arch Linux system, not a snapshot.
Check /:
findmnt -no FSTYPE /Expected:
btrfs
Check the root mount:
findmnt /Check GRUB:
grub-install --versionCheck Fish:
fish --versionIf / is not Btrfs or GRUB is not your bootloader, stop here.
Step 2: Install required packages
sudo pacman -S snapper snap-pac grub-btrfs btrfs-progsIf Fish is not installed:
sudo pacman -S fishStep 3: Create a top-level @snapshots subvolume
This project expects @snapshots to be a top-level Btrfs subvolume, alongside the root subvolume.
Do not blindly run:
sudo btrfs subvolume create /@snapshotswhen / itself is a subvolume such as @; that can create a subvolume nested inside the root.
Find the device containing /:
findmnt -no SOURCE /Example:
/dev/nvme0n1p2[/@]
The underlying device is /dev/nvme0n1p2.
Create a temporary top-level mount:
sudo mkdir -p /mnt/btrfs-topMount Btrfs top level:
sudo mount -o subvolid=5 "$(findmnt -no SOURCE / | sed 's/\[.*\]//')" /mnt/btrfs-topInspect the layout:
sudo btrfs subvolume list /mnt/btrfs-topIf @snapshots does not already exist, create it:
sudo btrfs subvolume create /mnt/btrfs-top/@snapshotsIf it already exists, do not create another one.
Unmount:
sudo umount /mnt/btrfs-topsudo rmdir /mnt/btrfs-top[!IMPORTANT]
@snapshotsshould be a sibling of the root subvolume in the Btrfs top-level tree, not a child of the root subvolume.
Step 4: Mount @snapshots at /.snapshots and make it persistent
Create the mount point:
sudo mkdir -p /.snapshotsMount it:
sudo mount -o subvol=/@snapshots "$(findmnt -no SOURCE / | sed 's/\[.*\]//')" /.snapshotsVerify:
findmnt /.snapshotsGet the Btrfs filesystem UUID:
findmnt -no UUID /Edit /etc/fstab:
sudo nano /etc/fstabor:
sudo nvim /etc/fstabAdd one /.snapshots entry:
UUID=YOUR_ROOT_BTRFS_UUID /.snapshots btrfs rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@snapshots 0 0
Replace YOUR_ROOT_BTRFS_UUID with the UUID from findmnt -no UUID /.
[!IMPORTANT] Do not leave duplicate
/.snapshotsentries in/etc/fstab.
Reload and test:
sudo systemctl daemon-reloadsudo mount -aThen:
findmnt /.snapshotsIf mount -a reports an error, stop and fix /etc/fstab before continuing.
Set permissions:
sudo chmod 750 /.snapshotsStep 5: Create the Snapper root configuration
Create the configuration directory:
sudo mkdir -p /etc/snapper/configsCreate:
sudo nano /etc/snapper/configs/rootUse:
SUBVOLUME="/"
FSTYPE="btrfs"
SPACE_LIMIT="0.5"
FREE_LIMIT="0.2"
ALLOW_USERS=""
ALLOW_GROUPS=""
SYNC_ACL="no"
GENERATE_CLEANUP="yes"
NUMBER_CLEANUP="yes"
NUMBER_MIN_AGE="1800"
NUMBER_LIMIT="50"
NUMBER_LIMIT_IMPORTANT="10"
TIMELINE_CLEANUP="yes"
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="10"
TIMELINE_LIMIT_DAILY="10"
TIMELINE_LIMIT_WEEKLY="0"
TIMELINE_LIMIT_MONTHLY="0"
TIMELINE_LIMIT_YEARLY="0"
EMPTY_PRE_POST_CLEANUP="yes"
EMPTY_PRE_POST_MIN_AGE="1800"Register the configuration:
echo 'SNAPPER_CONFIGS="root"' | sudo tee /etc/snapper/snapper-configsVerify:
sudo snapper -c root listAn empty list is acceptable if no snapshots exist yet; configuration/mount errors are not.
Step 6: Enable Snapper timers and Snap-Pac
sudo systemctl enable --now snapper-timeline.timersudo systemctl enable --now snapper-cleanup.timerCheck:
systemctl status snapper-timeline.timer --no-pagersystemctl status snapper-cleanup.timer --no-pagersnap-pac integrates with Pacman so package transactions can create pre/post snapshots.
Step 7: Enable GRUB-Btrfs
sudo systemctl enable --now grub-btrfsdVerify:
systemctl is-active grub-btrfsdExpected:
active
Step 8: Add the GRUB-Btrfs OverlayFS initramfs hook
Edit:
sudo nano /etc/mkinitcpio.confFind the active HOOKS=(...) line and add grub-btrfs-overlayfs at the end.
Example:
HOOKS=(base udev autodetect microcode modprobed-db kms keyboard keymap consolefont block filesystems fsck grub-btrfs-overlayfs)[!IMPORTANT] Modify the existing active
HOOKS=assignment. Do not create a secondHOOKS=line.
Verify:
grep '^HOOKS=' /etc/mkinitcpio.confIt must contain:
grub-btrfs-overlayfs
Rebuild:
sudo mkinitcpio -PIf there is an actual ERROR:, stop and fix it before continuing.
Step 9: Configure GRUB-Btrfs snapshot kernel parameters
Edit:
sudo nano /etc/default/grub-btrfs/configSet:
GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="rd.live.overlay.overlayfs=1 snapper_snapshot_boot=1"Verify:
grep '^GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS=' /etc/default/grub-btrfs/configExpected to contain:
rd.live.overlay.overlayfs=1 snapper_snapshot_boot=1
[!IMPORTANT] Keep
snapper_snapshot_boot=1. The systemd fix in the next step uses it to distinguish snapshot boots from normal boots.
Step 10: fix systemd-remount-fs.service for snapshot OverlayFS boots
This is an important part of this project's setup. During a snapshot boot, / becomes OverlayFS. Without the condition below, systemd-remount-fs.service can try to remount / using the normal Btrfs root entry and fail with an error similar to:
mount: /: fsconfig() failed: overlay: No changes allowed in reconfigure.
[!IMPORTANT] Perform this while booted into the normal/main Arch Linux system, not a snapshot.
Create the drop-in directory:
sudo mkdir -p /etc/systemd/system/systemd-remount-fs.service.dCreate the drop-in:
sudo sh -c 'printf "%s\n" "[Unit]" "ConditionKernelCommandLine=!snapper_snapshot_boot=1" > /etc/systemd/system/systemd-remount-fs.service.d/snapshot-overlay.conf'Verify:
cat /etc/systemd/system/systemd-remount-fs.service.d/snapshot-overlay.confIt must contain exactly:
[Unit]
ConditionKernelCommandLine=!snapper_snapshot_boot=1Reload:
sudo systemctl daemon-reloadOn a normal boot, snapper_snapshot_boot=1 is absent, so the service remains able to run normally.
Step 11: Rebuild initramfs and GRUB
sudo mkinitcpio -PThen:
sudo grub-mkconfig -o /boot/grub/grub.cfgIf snapshots already exist, GRUB-Btrfs should detect them during generation.
Step 12: Install the Fish arch snapshot helper
Create the Fish function directory:
mkdir -p ~/.config/fish/functionsCreate:
nano ~/.config/fish/functions/arch.fishAdd:
function arch --description "Arch Linux Snapshot Utility"
set -l sub_command $argv[1]
switch "$sub_command"
case snapshot
set -l flag $argv[2]
set -l args $argv[3..-1]
switch "$flag"
case -l --list
echo " Listing all system snapshots..."
sudo snapper -c root list
case -d --delete
if test (count $args) -eq 0
echo " Error: Please specify at least one snapshot ID to delete."
echo " Usage: arch snapshot -d <id1> [id2 id3 ...]"
return 1
end
echo " Deleting snapshot ID(s): $args..."
for id in $args
echo " - Deleting ID: $id"
if not sudo snapper -c root delete $id
echo " Error: Failed to delete snapshot ID: $id"
return 1
end
end
echo " Updating GRUB menu..."
if not sudo grub-mkconfig -o /boot/grub/grub.cfg
echo " Error: GRUB update failed."
return 1
end
case -h --help -help
echo " Arch Snapshot Utility"
echo "-------------------------------------"
echo "Usage:"
echo " arch snapshot : Create a manual snapshot"
echo " arch snapshot -l : List all snapshots"
echo " arch snapshot -d <ID1> <ID2>: Delete multiple snapshots by ID"
echo " arch snapshot -d (seq 1 15) : Delete snapshots from ID 1 to 15"
echo " arch snapshot -h | -help : Show this help message"
case ""
set -l desc "Manual snapshot taken on "(date "+%Y-%m-%d %H:%M:%S")
echo " Creating manual snapshot..."
if sudo snapper -c root create --description "$desc"
echo " Snapshot created successfully!"
else
echo " Error: Snapshot creation failed."
return 1
end
case "*"
echo " Unknown flag: $flag"
echo "Use 'arch snapshot -h' for help."
return 1
end
case "*"
echo " Unknown command: $sub_command"
echo "Use 'arch snapshot -h' for help."
return 1
end
endLoad it:
source ~/.config/fish/functions/arch.fishTest:
arch snapshot -hThen:
arch snapshot -lStep 13: Create a NEW test snapshot
Create a new snapshot after the systemd drop-in was installed:
sudo snapper -c root create --description "Manual installation test"List it:
sudo snapper -c root list[!WARNING] Snapshots created before the
systemd-remount-fsdrop-in was added do not contain the new file. Use a snapshot created after the fix for the first boot test.
Regenerate GRUB:
sudo grub-mkconfig -o /boot/grub/grub.cfgStep 14: Verify the normal boot before rebooting
Check:
findmnt /The normal root should be Btrfs, not OverlayFS.
findmnt /.snapshotssudo snapper -c root listsystemctl is-active grub-btrfsdExpected:
active
systemctl --failedExpected:
0 loaded units listed.
Check the hook:
grep '^HOOKS=' /etc/mkinitcpio.confIt must contain grub-btrfs-overlayfs.
Check the GRUB-Btrfs parameter:
grep '^GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS=' /etc/default/grub-btrfs/configIt must contain:
rd.live.overlay.overlayfs=1 snapper_snapshot_boot=1
Check the systemd drop-in:
cat /etc/systemd/system/systemd-remount-fs.service.d/snapshot-overlay.confExpected:
[Unit]
ConditionKernelCommandLine=!snapper_snapshot_boot=1Check:
cat /proc/cmdlineA normal boot should not contain:
snapper_snapshot_boot=1
Test booting a snapshot
sudo rebootAt GRUB, select:
Arch Linux snapshots
Select the new snapshot created after the fix.
After logging in:
cat /proc/cmdlineIt should contain:
rd.live.overlay.overlayfs=1
snapper_snapshot_boot=1
Check:
findmnt /An overlay root is expected during a snapshot boot.
Finally:
systemctl --failedExpected:
0 loaded units listed.
systemd-remount-fs.service should not be listed as failed.
Return to the normal system
Reboot:
sudo rebootSelect the normal:
Arch Linux
entry, not the snapshot.
Verify:
findmnt /The normal root should be Btrfs.
Then:
systemctl --failedIt should remain clean.
And:
cat /proc/cmdlineshould not contain:
snapper_snapshot_boot=1
Final verification checklist
Run:
findmnt -no FSTYPE /→ btrfs
findmnt /.snapshots→ /.snapshots is mounted from @snapshots
sudo snapper -c root list→ Snapper lists snapshots without configuration errors
systemctl is-active grub-btrfsd→ active
systemctl --failed→ 0 loaded units listed.
grep '^HOOKS=' /etc/mkinitcpio.conf→ contains grub-btrfs-overlayfs
grep '^GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS=' /etc/default/grub-btrfs/config→ contains rd.live.overlay.overlayfs=1 snapper_snapshot_boot=1
cat /etc/systemd/system/systemd-remount-fs.service.d/snapshot-overlay.conf→ contains:
[Unit]
ConditionKernelCommandLine=!snapper_snapshot_boot=1A successful snapshot boot should additionally show snapper_snapshot_boot=1, an overlay root, and no failed systemd-remount-fs.service.
Important safety notes
For this project's Btrfs layout, do not blindly run:
sudo snapper rollbackwhile booted into the normal base system.
If you intend to roll back, first boot the desired snapshot through the GRUB-Btrfs snapshot menu and then follow the project's rollback procedure.
Do not use:
rm -rf /.snapshots/*or arbitrary:
sudo btrfs subvolume delete ...to force Snapper numbering back to #1.
A high snapshot number is not a failure. If you intentionally want to reset the history, use the project's automated installer Option 2 rather than manually deleting snapshot storage.
/.snapshots is a mount point and is not necessarily the actual Btrfs snapshot-storage subvolume.
Inspect first:
findmnt /.snapshotssudo btrfs subvolume list /Because this setup changes initramfs and GRUB, keep an Arch ISO/USB available.
Recommended workflow
Verify Btrfs + GRUB
↓
Install packages
↓
Create top-level @snapshots
↓
Mount @snapshots at /.snapshots
↓
Add /etc/fstab entry
↓
Configure Snapper root
↓
Enable Snapper timers + grub-btrfsd
↓
Add grub-btrfs-overlayfs
↓
Configure snapshot kernel parameters
↓
Add systemd-remount-fs condition
↓
Rebuild initramfs
↓
Regenerate GRUB
↓
Create a NEW test snapshot
↓
Verify normal boot
↓
Boot the NEW snapshot
↓
Check OverlayFS + systemctl --failed
↓
Return to normal Arch Linux
Recommendation: If you do not specifically need a manual installation, use the project's
install.fish. The automated installer performs the same configuration while adding validation, backups, and the two snapshot-history modes.
| command | Description |
|---|---|
arch snapshot |
Instantly create a manual Snapshot (with time/date stamp) |
arch snapshot -l |
List all snapshots in the system. |
arch snapshot -d <ID1> <ID2> |
Delete multiple snapshots by ID (e.g. arch snapshot -d 5 6 7) |
arch snapshot -d (seq <ID1> <ID15>) |
Delete snapshots from ID (e.g. arch snapshot -d (seq 1 15)) |
arch snapshot -h |
Show the [Help menu] (arch snapshot -help, arch snapshot --help can be used as well) |
With snap-pac installed, every time you run the command:
sudo pacman -SyuThe system will automatically take Pre (before installation) and Post (after installation) snapshots.
-
Reboot the machine and select the menu
Arch Linux snapshotson the GNU GRUB page. -
Select the Snapshot of the desired date and time.
-
When logging in (The system will temporarily be in a Read-Only state.) If you are sure you want to roll back the system, open a Terminal and run:
sudo snapper rollback- Order to reboot the machine again. The system will turn back time perfectly!
This script sets up automatic snapshot retention to prevent the disk from filling up:
-
Number Cleanup: Keep up to 50 numbers (10 important numbers)
-
Timeline Cleanup:
- Hourly: Collect 10 characters.
- Daily: Collect 10 characters.
- Weekly / Monthly / Yearly: 0 (
turn it off to save space)
How to clean and reset Snapper to #1
- There are three main factors that prevent Snapper from resetting to
#1after we delete files:
-
info.xmlwithin Subvolume (/.snapshots/<number>/info.xml): Snapper doesn't just check if the folder in/.snapshots/ exists, every time a snapshot is created, it creates aninfo.xmlfile to store metadata. If these files are stuck or the numbers in the XML conflict, the system will skip to the next number. -
Snapper Internal DB / Metadata Counter: The Snapper Engine stores the Next Snapshot ID in Memory/State. If you delete a folder using
rm -rfwithout using thesnapper deletecommand, the Snapper counter will not update backward. -
Btrfs Subvolume Tree Inconsistency: At the Btrfs File System level, each subvolume has its own subvolume ID in the kernel. Even if the folder is deleted on the OS, if the actual subvolume hasn't been
btrfs subvolume delete, the snapper will consider that area to still have a conflict and will run the next ID to prevent data overlap (Data Corruption Protection).
[!WARNING]
- To completely reset the Snapper system to a clean 100% reset, returning the snapshot count to
#1you can use the command/script below:
- Stop the service and unmount all old files.
sudo systemctl stop grub-btrfsdsudo umount -l /.snapshots 2>/dev/nullsudo rm -rf /.snapshotssudo rm -rf /etc/snapper/configs/*- Unlock the configuration to allow Snapper to create a new configuration.
echo 'SNAPPER_CONFIGS=""' | sudo tee /etc/conf.d/snapper >/dev/nullecho 'SNAPPER_CONFIGS=""' | sudo tee /etc/sysconfig/snapper >/dev/null- Let Snapper create the actual configuration file first (it will secretly create its own
/.snapshotsfile).
sudo snapper -c root create-config /- Swap the
/.snapshotsthat Snapper creates with our actual@snapshots.
sudo umount /.snapshots 2>/dev/nullsudo rm -rf /.snapshotssudo mkdir -p /.snapshotssudo mount -o subvol=@snapshots (df -P / | tail -n1 | awk '{print $1}') /.snapshots- Register the configuration and set permissions.
echo 'SNAPPER_CONFIGS="root"' | sudo tee /etc/conf.d/snapper >/dev/nullecho 'SNAPPER_CONFIGS="root"' | sudo tee /etc/sysconfig/snapper >/dev/nullsudo chmod 750 /.snapshots- Restart Service.
sudo systemctl daemon-reloadsudo systemctl restart grub-btrfsd[!NOTE] To prevent snapshots from disappearing after a system reboot, ensure your
/@snapshotssubvolume is registered in/etc/fstab.
- Open the
/etc/fstabfile.
sudo nvim /etc/fstabor
sudo nano /etc/fstab- Add this line to the bottom of the file.
[!NOTE] If you find multiple duplicate
/.snapshotslines, delete them all so that only one remains, in this correct format.
UUID=YOUR_ROOT_UUID /.snapshots btrfs rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@snapshots 0 0[!NOTE] (Replace
YOUR_ROOT_UUIDwith the actual UUID of your primary drive.)
[!TIP] (The complete
/etc/fstabfile after adding this will look like this.)# Static information about the filesystems. # See fstab(5) for details. # <file system> <dir> <type> <options> <dump> <pass> # /dev/nvme0n1p2 UUID=235749cf-3398-4291-b33f-96ccec82bb84 / btrfs rw,relatime,ssd,discard=async,space_cache=v2,subvol=/ 0 0 # /dev/nvme0n1p1 UUID=533C-B30F /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2 # /dev/nvme0n1p2 - /.snapshots UUID=235749cf-3398-4291-b33f-96ccec82bb84 /.snapshots btrfs rw,relatime,ssd,discard=async,space_cache=v2,subvol=/@snapshots 0 0
- Perform a mount test and reload Systemd.
- Run this command in the Terminal to mount the system immediately without restarting
sudo systemctl daemon-reloadsudo mount -a