logo
vision scalability social networking revelation source

Arch with rollback install

abstract:

The huge advantage of btrfs is that it makes rollback possible. When you are ricing your system, you are going to break it irreversibly, and lose all your ricing work.

This happens even on windows, and it happens a lot more on linux desktop, and even more on bleeding edge distros such as Arch and the Arch derived distros. If you are on a distro that has pacman, yay and the AUR, you are apt to be reinstalling rather too often.

I was planning to install arch on the Nuc 15 Pro+, but was disturbed to discover that the intel repo is only directly available though Asus for Ubuntu Desktop 25.04 and 24.04 “For Ubuntu 25.04 and 24.04, we offer the intel-graphics Personal Package Archive (PPA). This PPA provides early access to the latest packages”: Not necessarily a deal killer, but clearly a risk.

1 initial install

Assuming efi. All machines are efi these days. Assuming SSD. Why would anyone install an OS on anything other than an SSD? EFI is in practice buggy, because hardware developers only care if windows runs, so anything off the windows path will not frequently not work, or will not work according to spec. So we have to work refind around the UEFI bugs

Rod’s books on refind

We are going to implement rollbacks with snapper. Grub overrules snapper rollback, so we will use refind as our boot manager, and edit its /boot/refind_linux.conf file and its /refind/refind.conf file to support snapper rollback. Which is nowhere documented except here.

snapper rollback is confusing, because in the default environment it does not rollback anything, merely creates the rollback subvolume, unless you have the correct bootmanager, correctly configured. Snapper relies on btrfs subvolume set-default, and every boot manager overrules the default. But you can turn this off in refind.

Rollback is not backup, but snapper also provides useful support for an incremental backup system, that backs up your snapshots.

Most utilities for managing subvolumes and snapshots expect your file system to follow the subvolume layout prescribed by arch wiki for snapper setup, so this layout is based on that layout, except it excludes a few more directories from snapshotting than it does.

/tmp is almost always on tmpfs, not your root subvolume, /run is similarly always on a special file system. /var/run is usually a symlink to run or contains only a symlink to run and is normally mounted on tmpfs

You probably need to make /home /opt, /var/tmp, /var/cache, /var/spools, and /var/lib/docker into subvolumes

1.1 partitioning for btrfs

A swap file on a btrfs volume is difficult and complicated to setup. Easier to use a standard swap partition.

So, your partition scheme should be 256 megabyte efi, a few gigabytes swap, and the rest one btrfs partition.

Almost all distros support btrfs in manual partitioning. Since you will be using snapper, you need at least thirty gigabytes.

A btrfs file system can go over many partitions on many devices, but this is a bad idea for your root file system, and is apt to get scary complicated and require much ricing.

On your OS subvolume you want rollback, but not necessarily backup. On your home partition you do not want rollback but you do want incremental backup, and using btrfs for incremental backup gives you manual rollback for free.

2 partitioning for btrfs

A swap file on a btrfs volume is difficult and complicated to setup. Easier to use a standard swap partition. Should be slightly bigger than all of memory. This also allows hibernation on laptops.

So, your partition scheme should be 256 megabyte efi, a few gigabytes swap, and the rest one btrfs partition. Since you will be using snapper, you need at least thirty gigabytes.

A btrfs file system can go over many partitions on many devices, but this is a bad idea for your root file system, and is apt to get scary complicated and require much ricing.

Since partitions with btrfs files on them are resizable, another solution is to have one partition for the OS, and another for home and opt. This allows you to reinstall linux, while keeping your possibly large data. But if you have OS rollback, you are not going to care about re-installing linux, so, all one big partition with separate subvolumes.

2.1 Staging

This describes what becomes a refind-btrfs system. Grub does not play nice with snapper, with the result that the command snapper rollback does not have the desired and expected effect

If one uses refind, rather than grub, as one’s boot manager, then snapper works as one would expect, avoiding the complicated and dangerous methods one must use to rollback a grub-btrfs system.

Staging is setting up the working partitions, subvolumes, and files on the target system. After staging we will then arch-chroot into an almost working system to do the final setup from within the system, the most important step being to create the bootloader, which can only be done chrooted.

Boot archinstall live disk. Which instead of coming up with a user friendly gui, drops you immediately into root.

Which is what we want, because the user friendly archinstall will set up the /boot directory on the efi drive, which does not play nice with rollback.

I am going to setup a whole lot of subvolumes, and mount them, in order to play nice with rollback. One wants rollback to rollback the operating system, and only the operating system. For everything else, one wants backup, not rollback. Or as with the logs, the cache, and thing like that, one does not care because trivially replaceable

passwd
systemctl start sshd

OK, now we ssh in from another computer, so that we can cut and paste (Avahi is running on the livecd, so if you have avahi or bonjour running on your local system you can ssh in by name.)

scp ~/.ssh/~/«local».pub root@archiso:/root/.ssh/authorized_keys
ssh root@archiso

And now, in our ssh window we create a 256M partition for efi, and a swap file big enough for all of memory, in our case +5120M

This is easer to do if we boot into a livecd graphical environment and use gparted, and then reboot into the livecd command line, rather than doing it all from the command line but here I depict doing it from the command line, in part because with classic user hostility, the arch install cd does not have a graphical environment:

lsblk #the unmounted device should be /dev/sda
fdisk /dev/sda
g
n
1

+256M
n
2

+5120M
n
3


w
lsblk
gdisk /dev/sda
t
1
EF00
t
2
8200
t
w
mkfs.fat -F32  /dev/sda1
mkswap -L "swap" /dev/sda2
mkfs.btrfs -fL "Arch Linux" /dev/sda3
mount  /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvolid=5 /mnt

Most utilities for managing subvolumes and snapshots expect your file system to follow the subvolume layout prescribed by arch wiki for snapper setup, so this layout is based on that layout, except it excludes a few more directories from snapshotting than the arch layout does.

Because we don’t want snapshots of the root file system to snapshot some directories, we create a bunch of subvolumes for those directories, either because they contain frequently changing stuff that we do not care about, and would just waste snapshot space, for example /var/cache, or because, like /home, /var/log, and /.snapshots itself, we don’t want to lose their contents when we rollback the root file system to an earlier state.

btrfs subvolume create /mnt/@rootfs
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@opt
btrfs subvolume create /mnt/@var_tmp
btrfs subvolume create /mnt/@var_cache
btrfs subvolume create /mnt/@var_spools
btrfs subvolume create /mnt/@var_log
btrfs subvolume create /mnt/@var_lib_docker
btrfs subvolume create /mnt/@var_lib_nerdctl
umount /mnt
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@rootfs /mnt
mkdir -p /mnt/boot/efi
mkdir -p /mnt/.snapshots
mkdir -p /mnt/home
mkdir -p /mnt/opt
mkdir -p /mnt/btrfsroot
mkdir -p /mnt/var/cache
mkdir -p /mnt/var/tmp
mkdir -p /mnt/var/spools
mkdir -p /mnt/var/log
mkdir -p /mnt/var/lib/docker
mkdir -p /mnt/var/lib/nerdctl
mount /dev/sda1 -o umask=0077 /mnt/boot/efi
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@snapshots        /mnt/.snapshots
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@home             /mnt/home
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@opt              /mnt/opt
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvolid=5               /mnt/btrfsroot
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@var_tmp          /mnt/var/tmp
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@var_cache        /mnt/var/cache
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@var_spools       /mnt/var/spools
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@var_log          /mnt/var/log
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@var_lib_docker   /mnt/var/lib/docker
mount /dev/sda3 -o rw,relatime,discard,ssd,autodefrag,compress=zstd,commit=300,space_cache=v2,subvol=@var_lib_nerdctl  /mnt/var/lib/nerdctl
reflector --country 'United States' --latest 10 --sort rate --save /etc/pacman.d/mirrorlist
#this takes a while, but without it, mirror will run excruciatingly slowly and might die on you.
pacstrap /mnt base base-devel linux linux-firmware intel-ucode
genfstab -U /mnt > /mnt/etc/fstab
blkid
#substitute the actual uuid revealed by blkid
echo $(blkid |grep swap |cut -d ' ' -f 3 | sed 's/["]//g') none  swap sw 0 0 >>/mnt/etc/fstab
nano /mnt/etc/fstab #sanity check and add swapfile.  Highly likely that genfstab has done bad stuff.
#edit out the subvol=entry for the root subvolume.  We intend to rely on set-default to define the root.
cp -r ~/.ssh /mnt/root
arch-chroot /mnt

/etc/fstab should look something like this

# /dev/sda1  efi
UUID=81C6-5568                                  /boot/efi        vfat    rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro   0 2

# /dev/sda2 LABEL=swap
UUID=613bbb43-062a-4248-98dd-ba3d6b2e6a93       none             swap    sw                                                                                                      0 0

# /dev/sda3 LABEL=Arch\134x20Linux
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /                btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300                            0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /.snapshots      btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@snapshots         0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /home            btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@home              0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /opt             btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@opt               0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /var/tmp         btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@var_tmp           0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /var/cache       btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@var_cache         0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /var/spools      btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@var_spools        0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /var/log         btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@var_log           0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /var/lib/docker  btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@var_lib_docker    0 0
UUID=385a6b3a-2240-4b22-86a5-d29979e1d150       /var/lib/nerdctl btrfs   rw,relatime,compress=zstd:3,ssd,discard,space_cache=v2,autodefrag,commit=300,subvol=/@var_lib_nerdctl   0 0

You may later want to mount additional devices, such as usb drives but we can worry about that later. At the moment all we care about is getting a system that boots and that works as we intend it to, and the less we do on the path to that goal, the less we can get wrong. So we are only mounting what we need mounted so that our first snapper snapshot will be sane.

And now we are chrooted inside the real system, but still using the CDROM linux

2.2 chroot arch-chroot /mnt

If you are rebooting the cdrom after mounting all the volumes you created, you are going to have remount them before you arch-chroot.

Not installing iwd and crda because not installing NetworkManager Installing dhcpcd and openresolv instead. But if using a laptop, going to need NetworkManager, iwd, and crda, which are more complicated to setup and slow down booting. You will need them because a laptop is always moving from one wifi to another.

dhcpcd-uiAUR is a GTK frontend for the dhcpcd daemon, and optionally wpa_supplicant. It features a configuration dialogue and the ability to enter a pass phrase for wireless networks.

passwd
hostnamectl hostname «hostname» # not set by pacstrap>
pacman -Syu
pacman -S refind efibootmgr os-prober mtools linux linux-firmware intel-ucode linux-headers base base-devel dhcpcd openresolv btrfs-progs reflector nano openssh git rsync man-db man-pages openssh avahi fcron
refind-install

This will attempt to find and mount your ESP, copy rEFInd files to esp/EFI/refind/, use efibootmgr to make rEFInd the default EFI boot application and will generate /boot/refind_linux.conf, a configuration that overrules the btrfs default that enabled refind to find the files to boot. edit out the subvolume directive root=subvol=@rootfs

The /boot/refind_linux.conf file it generates will be completely broken, using the wrong UUID, and setting the subvolume explicitly to @rootfs, which we do not, because we want that controlled by btrfs subvolume set-default, so that we are able to use snapper to rollback our file system.

lsblk -o name,type,size,fstype,mountpoint,UUID
nano /boot/refind_linux.conf

The correct /boot/refind_linux.conf will look like this, except with with correct UUID which lsblk showed you

"Boot with standard options"  "root=UUID=385a6b3a-2240-4b22-86a5-d29979e1d150 rw loglevel=3"
"Boot to single-user mode"    "root=UUID=385a6b3a-2240-4b22-86a5-d29979e1d150 rw loglevel=3"
"Boot with minimal options"   "ro root=UUID=385a6b3a-2240-4b22-86a5-d29979e1d150"

You need the correct UUID, and you want to edit out the subvol=@rootfs, so that the boot will respect the btrfs subvolume set-default set by snapper.

These the first option shows up in the top level refind boot menu. Subsequent options show up when you press f2 for submenu. You can also add some of them as options to the top level refind menu with stanzas in /boot/efi/EFI/refind/refind.conf

This gives you an escape hatch should you break your snapper root subvolume so totally it does not boot.

If when you reboot, you are in refind, and see no option to boot into refind, then your boot manager is EFI/refind/refind_x64.efi and you edit its conf file.

If when you reboot, refind gives you an option to boot into refind, then your boot manager is BOOT/bootx64.efi and you will edit its conf file

`btrfs subvolume set-default /` #so that refind will be able to find /boot when it boots.
cd /boot/efi/EFI
cp -r refind BOOT
cd BOOT
mv refind_x64.efi bootx64.efi

if UEFI forgets, as it always does on Oracle VMs, it will then run EFI/BOOT/bootx64.efi

ip a
systemctl enable dhcpcd@enp0s3.service
systemctl enable sshd
systemctl enable avahi-daemon
useradd -m «user» -G wheel,audio,video  #not created by pacstrap
passwd «user»
EDITOR=nano visudo
## Uncomment to allow members of group wheel to execute any command
# %wheel ALL=(ALL:ALL) ALL

## Same thing without a password
«user»  ALL=(ALL:ALL) NOPASSWD: ALL
wheel ALL=(ALL:ALL) NOPASSWD: ALL

Initialise resolvconf

resolvconf -u

Because otherwise will not be able to do name resolution, now that the livecd’s name resolution has gone away.

dhcpcd is a dhcp client, which requires a systemd service dhcpcd@enp0s3.service

The confusingly similarly named dhcpd is a dhcp server, which similarly requires a dhcpd4.service and dhcpd6.service,

Howver the dhcpcd server should not provide the client with is local IP6, which should be done locally by slaac, merely its dns and stuff. If the DHCP server insists on doing its own thing (like Starlink DHCPv6), this confuses the hell out of no end of local devices, with the result that IP6 communications fail to go over the internet. SLAAC compatible dhcp service, such as dhcpcd, has more compatibility and considerably easier configuration. Allowing slaac to work is called stateless mode.

dhcpcd does not necessarily correctly guess your ip6 router environment. Sometimes, often, it requires an interface stanza to successfuly handle ip6

Which if your local router is using SLAAC for network addresses might be

ip a
nano /etc/dhcpcd.conf
interface «enp0s3»
ipv6rs

or if your network uses the evil anti privacy centralised DHCPv6 rather than SLAAC

interface «enp0s3»
ipv6rs
ia_na 1

Usually using the right standard for the local network provided by your router will work.

DHCPV6 is the anti privacy option. If your router is not using SLAAC, you should get a router that does. SLAAC routers deliberately make it hard to match IP6 addresses to physical addresses, physical addresses that might have valuable secrets whose owners can be robbed or shaken down, such as a Bitcoin wallet, or a site sharing politically incorrect information.

But, if nothing you do results in success, tell dhcpcd to avoid using ip6 addresses when it has a choice.

interface «enp0s3»
ipv6rs
nooption DNS6

As always «foobar» means mutas mutandis. You should see the interface that has access to the outside world in ip a

After you reboot into a running system, you will probably find you have made the wrong choice, and will have to come back to this.

From another terminal session:

scp ~/.ssh/~/«local».pub root@archiso:/mnt/root/.ssh/authorized_keys

2.3 after booting into running system

After rebooting into the target system (no longer in chroot) ssh in, so that you can use cut and paste.

In this situation and configuration, refind will immediately launch whatever efi boot file you last selected.

2.4 .bashrc

Arch install does not supply a .bashrc and .bashrc_profile. This is an option you have to explicitly invoke in adduser with adduser -m

modify the .bashrc file created for a user so that it looks something like

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

alias ll="ls --color=auto -hal --time-style=iso"
mkcd() { mkdir -p "$1" && cd "$1"; }
alias ls='ls --color=auto'
alias grep='grep --color=auto'
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

And if no .bash_profile file

#
# ~/.bash_profile
#

[[ -f ~/.bashrc ]] && . ~/.bashrc

2.5 limit systemd journals

If using systemd, edit the systemd journal limit to SystemMaxUse=300M, as the default is enormous, and anything much bigger than 200M-300M is unusable. Searching 300 Megabytes of compressed text for what you care about is slow, and apt to break tools that were never designed for such a use case. Systemd search tools, however can handle big journals well.

nano /etc/systemd/journald.conf
[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
SystemMaxUse=300M
#SystemKeepFree=
#SystemMaxFileSize=

If old information that you might care about keeps dropping off, that is because some daemons are dumping far too much info. Put them in a separate namespace with a separate volume limit.

3 install yay

As an unprivileged user:

sudo pacman -Syu
sudo pacman -S --needed base-devel git
mkdir -p ~/.cache/yay
cd ~/.cache/yay
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

After all, the whole point of arch is total freedom and total control – including the freedom to install completely unvetted software. If you want to play it safe, use pacman, rather than yay, but if you wanted to play it safe, why aren’t you using debian?

4 creating snapshots

Snapper rollback does not work by default because grub renders btrfs subvolume set-default / to have no effect, and all bootloaders do this by default, and have to be configured to allow it to have effect.

I assume that you are using refind, and that you have removed the references to @rootfs from /boot/refind-linux.conf and /etc/stab

snapper --ambit classic rollback «n» will create writeable copy of snapshot «n», and, if you are root or sudo, execute btrfs subvolume set-default / so that next time you boot, your file system is that bootable snapshot.

Subsequent changes will change that snapshot, and not change @rootfs, which I keep around in case I bork my current root file system, and need to be able to boot into a working root file system – so you need to have some way of booting into @rootfs, you can do by leaving grub around, which shows up in the refind menu, but if you do not have grub on your system at all, which I should not, put it into the refind submenu generated by /boot/refind_linux.conf, which you can access from refind with F2.

As root user

pacman -Syu
packman -S snapper
This installs the snapper service, three disabled services, and a three timer services to run them at intervals -- which should be setup automatically, but check that they are
Created symlink '/etc/systemd/system/timers.target.wants/snapper-boot.timer' → '/usr/lib/systemd/system/snapper-boot.timer'.
Created symlink '/etc/systemd/system/timers.target.wants/snapper-cleanup.timer' → '/usr/lib/systemd/system/snapper-cleanup.timer'.
Created symlink '/etc/systemd/system/timers.target.wants/snapper-timeline.timer' → '/usr/lib/systemd/system/snapper-timeline.timer'.
Created symlink '/etc/systemd/system/sysinit.target.wants/snapperd.service' → '/usr/lib/systemd/system/snapperd.service'.
systemctl status snapper-boot
systemctl status snapper-cleanup
systemctl status snapperd

snapper likes to assume that config root exists, that being the default config, and any other config should be specified with snapper -c «config» but install does not automatically creates it.

Futher, the command to create a config is broken. When you snapper -c root create-config /, it will insist on creating a new snapper subvolume. Which lives inside your root subvolume. And when you take a snapshot, it is not included, and so, when you rollback your system to a previous writeable snapshot it is not there any more. It is just an ordinary directory. And suddenly snapper does not work, and in consequence rollback no longer works either. Suddenly you are in deep doodoo.

So, before you create the root config, or any other, unmount your /.snapshots volume

I assume you have already setup top level subvolumes and /etc/fstab in staging](#staging) in accordance with the instructions for setting up snapper in the arch wiki for snapper setup.

umount /.snapshots
rm -r /.snapshots
snapper -c root create-config /
btrfs subvolume show /.snapshots  # should show the wrong snapshots volume
ls -hal /.snapshots  # should be empty
btrfs subvolume delete /.snapshots
mkdir /.snapshots
mount -a
btrfs subvolume show /.snapshots  # should show the right snapshots volume
# snapper will not care that you switched subvolumes underneath it.

snapper -c home create-config /home
# If you ever expect to switch to a snapshot of
# home, set its /home/.snapper subvolume up as for root
# in /btfrsroot/home/@snapper but you probably
# never intend to switch, you intend to restore selected parts of
# /home when needed from /home/.snapper with cp -a
snapper list-configs
snapper create -d"first snapshot of root, without most software, among them without grub-btrfs"
snapper -c home create -d"first snapshot of empty home"
snapper list
snapper -c home list
nano /etc/snapper/configs/root  #allow wheel
pacman -S snap-pac # pre and post install snapshots.

Edit the root config to turn off the timeline feature.

I am assuming you have already modified /etc/fstab to explicitly mount .snapshots and all your subvolumes as decribed in staging, and as described in the arch wiki for snapper setup. so that they will survive in a different snapshot. If not, do it now.

snapper -c home rollback is not allowed, and if you do want to roll home back to an earlier snapshot, you roll it back by modifying fstab andor an explicit mount command. But you never should want to rollback home. The home config is useful for btrfs incremental backup utilities, and useful for restoring files and directories with If you ever rollback /home, you must first make sure all its subvolumes including /home/.snapper somewhere else and are explicitly mounted by /etc/fstab, or when you rollback, you lose them.

You care about restore points for your operating system, because you often make changes and find you want to reverse them.

You do not care much about backup for your operating system, because you can always re-install.

You don’t really care that much about restore points for home. What you care very much about is backups for home.

And btrfs insists on sending only read only snapshots, such as those created by snapper. Which is what you want for incremental backup.

There are multitude of bash scripts available for synchronising snapshots over ssh to a backup device, typically a btrfs formatted usb drive, snap-sync is, like most things, in the pacman repository. Though the use case that writers of btrfs had in mind was backing up over the home network over ssh to one of your other computers.

It might be a good idea, if backing up to thumbdrives, to create a special subvolume with all the stuff that you care about, and only the stuff that you care about, to create a snapper config for this special subvolume, and to create encrypted btrfs thumbdrives with a long, hard to guess passphrase. This use case for snap-sync is documented by jwillickers

When creating an encrypted thumbdrive, use Veracrypt. Luks has no hardening against being plugged into a hostile computer.

A Veracrypt thumbdrive is indistinguishable from a wiped thumbdrive. On the other hand, a bootable thumbdrive containing a veracrypt partition is very obviously a veracrypt thumbdrive. So you should keep an uninteresting bootable backup in the clear, that boots an os that can read another thumbdrive, one that is end to end a single veracrypt partition, and can do an ssh btrfs send of it.

Veracrypt also supports hidden volumes, unlike Luks.

There is a bootable memory only linux, which you can boot from a thumbdrive, then pull out that thumbdrive, and insert your all veracrypt thumbdrive, which is indistinguishable from a drive that has been wiped.

So if travelling past your enemies with valuable data, bring some veracrypt thumbdrives indistingishable from wiped thumdrives unlless you know the secret key, some thumbdrives that have actually been wiped, and a perfectly normal bootable thumbdrive that contains the software you need to decrypt the veracrypt thumbdrives.

The primary use case for Luks is booting from a hard drive that is mostly encrypted.

5 Optional preparation for emergency boot

Suppose your linux kernel gets corrupted, or btrfs subvolume get-default \ somehow got sent to a stupid value. Then boot does not work.

This is far more likely to happen on Arch than on any other linux, because of frequent replacements and rebuilds of the linux kernel.

This is not the end of the world. Suppose you know that snapshot «11» is a working system, You can boot off a live thumbdrive,

mount  /dev/sda3 -o subvolid=5 /mnt
cd /mnt
btrfs subvolume snapshot @snapshots/«11»/snapshot @rootfs2
btrfs subvolume set-default @rootfs2

and then you can boot normally and things will be rolled back to what they were in snapshot «11».

But, as an entirely optional step, if you want to setup a safe boot to an older version, create a snapshot somewhere of that older version, perhaps @recovery, create a subdirectory /boot/efi/EFI/recovery, move the boot files to @recovery/boot to /boot/efi/EFI/recovery edit the /boot/efi/EFI/recovery/refind_linux.conf so that rootflags=subvol=@recovery loglevel=3.

In your emergency backup boot, you want the btrfs default ignored and overriden, because your default root file system is probably broken. So you are ignoring it for the boot files, and instead using old boot files on your efi disk, and ignoring it for the root file system, because you have told the boot file to load your recovery subvolume

Assuming the current directory is subvolid=5, and you have created the @recovery snapshot =@rootfin the current directory:

mkdir -p /boot/efi/EFI/recovery
mv @recovery/boot/initramfs-linux.img /boot/efi/EFI/recovery
mv @recovery/boot/intel-ucode.img     /boot/efi/EFI/recovery
mv @recovery/boot/refind_linux.conf   /boot/efi/EFI/recovery
mv @recovery/boot/vmlinuz-linux       /boot/efi/EFI/recovery
nano /boot/refind_linux.conf

The correct /boot/efi/EFI/recovery/refind_linux.conf will look like this, ony with your correct UUID and editing in subvol=@recovery where you previously edited out subvol=@rootfs becase in your recovery, you don’t want to boot into the broken volume, but rather intend to use snapper –ambit classic rollback to set the default to the most recent good snapshot.

"Recovery Boot with standard options"         "root=UUID=385a6b3a-2240-4b22-86a5-d29979e1d150 rw rootflags=subvol=@recovery loglevel=3"
"Recovery Boot to single-user mode"           "root=UUID=385a6b3a-2240-4b22-86a5-d29979e1d150 rw rootflags=subvol=@recovery loglevel=3"
"Recovery Boot @rootfs with standard options" "root=UUID=385a6b3a-2240-4b22-86a5-d29979e1d150 rw rootflags=subvol=@recovery loglevel=3"

and the next time you boot, refind will have a new toplevel menu option

6 installing XFCE

pacman -S xfce4 xfce4-goodies lightdm lightdm-gtk-greeter
systemctl enable lightdm

6.1 enable autologin

groupadd -r autologin
gpasswd -a cherry autologin
nano /etc/lightdm/lightdm.conf

In the [Seat:*] section of the configuration file (there is another section of this configuration file where these changes have no apparent effect) edit

#autologin-guest=false
#autologin-user=user
#autologin-user-timeout=0

to

autologin-guest=false
autologin-user=«username»
autologin-user-timeout=0

Reboot. Should be in your user

Select from the menu:

Applications/settings/Power manager and configure as appropriate for your use case.

7 X2go

Arch Wiki:x2Go

7.1 install

As root user:

pacman -Syu
pacman -S x2goserver xorg-xauth fuse3
nano /etc/ssh/sshd_config

set X11Forwarding to yes verify that AllowTcpForwarding and X11UseLocalhost options are set to yes, and that X11DisplayOffset is set to 10 (those are the default values if nothing has been changed).

#AllowAgentForwarding yes
#AllowTcpForwarding yes
GatewayPorts yes
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes

If you needed to change anything:

sudo systemctl restart sshd

Fuse is used to mount the client file system in the host file system, so the client’s home directory becomes a subdirectory of server’s home directory

Initialise the x2go database

sudo x2godbadmin --createdb

7.2 additional applications

Publish applications, if you have any that the remote user might want to run locally without running the whole desktop remotely.

But usually you just want to run the desktop remotely, so you can skip this step.

mkdir /etc/x2go/applications

Populate it with hard links to the relevant application’s .desktop file. If there are any

7.3 start

systemctl enable x2goserver.service
systemctl start x2goserver.service
systemctl status x2goserver.service

Creative Commons License reaction.la gpg key 154588427F2709CD9D7146B01C99BB982002C39F
This work is licensed under the Creative Commons Attribution 4.0 International License.