Instructions for installing and configuring a Linux system based on Arch Linux with snapshot functionality.
System uses required BTRFS partitions, Snapper for snapshots and KDE Plasma desktop. This setup is used for testing on a VM machine.
These instructions are based on arch wiki and installanion guide.
All was tested with Qemu
virtual manager and archlinux-2024.11.01
ISO.
The goal is to have a "bleeding edge" system as the main home desktop environment, and to be able to have the latest packages for testing, while being backed up by snapshots and able to quickly restore the system after failed updates, upgrades or critical changes.
This is my discovery attempt to create such a system setup. Please contact me or create an issue
if you have better suggestions or find bugs.
- Create and restore system snapshots using Snapper
- BTRFS system partition - required for system snapshots
- Create automatic snapshots before and after system and software updates with snap-pac
- Restore the system from the boot menu with grub-btrfs
- Desktop Environment - KDE Plasma
- Installation setup
- Partitioning
- System installation
- Chroot
- Snapper configuration
- Post installation steps
If the device and VM are connected to the same Internet, which is usually the case with Virtual Manager installed on the local computer, it is easy to connect via SSH and use the local computer's terminal to install Arch. This is a more convenient option. It is easier to change the font size, scroll through the terminal window to see older commands and output.
First install ssh on the VM Arch installation, enable the ssh service and set the ISO root password for security.
pacman -Sy --needed openssh;
systemctl enable sshd;
passwd
Check IP address on the VM to connect on local machine
ip address
Now connect via ssh on your local machine
ssh root@<your_ip_address>
Use the grep command to find your keyboard layout typing your language code
localectl list-keymaps | grep <your_language_code>
Apply keyboard settings with command
loadkeys <language_code>
This step is not required in the VM, this should just work as machine connected through the Ethernet cable.
To connect to WiFi:
iwctl
And use steps: device list
-> station <device> scan
-> station <device> get-networks
-> station <device> connect <Network_name>
-> exit
.
Clock should be synced automatically. To check the status of the system clock run:
timedatectl
First if you are not sure you can check what type of boot mode is in your system. Run below command. If the file exists you are on UEFI, if not you are on BIOS.
cat /sys/firmware/efi/fw_platform_size
The easiest way to partition the hard disk is to use cfdisk
. VM is probably using BIOS, so here won't be any instructions on how to create a UEFI partition in this guide (for now). Create two partitions, one for BIOS, 100MB is more than enough, and the rest for the Linux filesystem.
cfdisk /dev/<disk>
Format the Linux partition as BTRFS and add a larger node size for metadata (default 16k max 64k). Higher node sizes give better packing and less fragmentation at the cost of more expensive memory operations while updating the metadata blocks.
mkfs.btrfs -f -L <your_label> -n 32k /dev/<linux_partition>
⚠️ - The only way to add new subvolumes later after this installation is to go into recovery mode and repeat the following steps as root. It is necessary to remount partition to the/mnt
like below. Another option is to use the live ISO.
Mount the Linux partition:
mount /dev/<linux_patrition> /mnt
Create BTRFS subvolumes, the su cr
command is an abbreviation of su
bvolume cr
eate. The following subvolumes are required for snapper and the system to work properly. @pacman and @tmp are to reduce snapshot creations slowdowns.
btrfs su cr /mnt/@;
btrfs su cr /mnt/@home;
btrfs su cr /mnt/@snapshots;
btrfs su cr /mnt/@log;
btrfs su cr /mnt/@pacman;
btrfs su cr /mnt/@tmp;
btrfs su cr /mnt/@swap
Now unmount /mnt
and remount the Linux partition with below settings
umount /mnt;
mount -o noatime,compress=lzo,space_cache=v2,subvol=@ /dev/<linux_patrition> /mnt
More about selected options can be found here: link.
Option | desc |
---|---|
noatime | Significantly improves performance because no new access time information needs to be written. Default option here is relatime , but it is not working well with BTRFS! Read more in here |
compress | Control BTRFS file data compression. Type may be specified as zlib, lzo, zstd or no. More in here: link |
space_cache | The free space cache greatly improves performance when reading block group free space into memory. V2 is newer better version. But it is good to make sure to have it is set. |
subvol | Subvolume path |
Create folders for home, snapshots, swap and other subvolumes...
mkdir -p /mnt/{home,var/log,var/tmp,var/cache/pacman/pkg,.snapshots,swap}
...and mount subvolumes
mount -o noatime,compress=lzo,space_cache=v2,subvol=@home /dev/<linux_partition> /mnt/home;
mount -o noatime,compress=lzo,space_cache=v2,subvol=@log /dev/<linux_partition> /mnt/var/log;
mount -o noatime,compress=lzo,space_cache=v2,subvol=@tmp /dev/<linux_partition> /mnt/var/tmp;
mount -o noatime,compress=lzo,space_cache=v2,subvol=@pacman /dev/<linux_partition> /mnt/var/cache/pacman/pkg;
mount -o noatime,compress=lzo,space_cache=v2,subvol=@snapshots /dev/<linux_partition> /mnt/.snapshots
This can speed up download time and help to prevent timeouts. Example below shows command to select the HTTPS mirrors that have been synchronised within the last 12 hours and are located in either Country1
and Country2
, sort them by download speed, and overwrite the /etc/pacman.d/mirrorlist
file with the results.
reflector --country <Country1>,<Country2> --protocol https --age 12 --sort rate --save /etc/pacman.d/mirrorlist
Here we are installing latest linux kernel and other packages for system to work. To install LTS linux change linux
to linux-lts
and linux-lts-headers
or have them both. In this step I am adding also snapper
and grub-btrfs
.
pacstrap -K /mnt base base-devel btrfs-progs git grub grub-btrfs inotify-tools linux linux-firmware linux-headers man neovim networkmanager openssh reflector snapper sudo
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
To find your time zone run:
timedatectl list-timezones | grep <country>
ln -sf /usr/share/zoneinfo/<Region/City> /etc/localtime
Set the hardware clock with command:
hwclock --systohc
Uncomment your locale in /etc/locale.gen
and save the changes.
Generate the locale and add a new line with your locale to /etc/locale.conf
.
locale-gen;
echo LANG=<locale> > /etc/locale.conf
Set up your keymap settings.
echo "KEYMAP=<keymap>" > /etc/vconsole.conf
my_hostname=<hostname>;
echo $my_hostname >> /etc/hostname;
echo "127.0.0.1 localhost"$'\n'"127.0.1.1 $my_hostname.localdomain $my_hostname"$'\n'"::1 localhost" >> /etc/hosts
my_username=<username>;
passwd;
useradd -m -g users -G wheel $my_username;
passwd $my_username
Use the following command and uncomment the line %wheel ALL=(ALL) ALL
line to enable sudo
:
EDITOR=nvim visudo
systemctl enable NetworkManager;
systemctl enable sshd
⚠️ - Swapfile needs to be mounted as subvolume, otherwiseSnapper
won't work. There can be error likeCannot create snapshot
.
Instructions how to enable swap on BTRFS are here: link.
I found it easier to make swap work with snapshots and BTRFS by creating swapfile manually rather than using the above instructions form the Arch wiki.
First, mount the @swap
subvolume, create a swapfile inside the swap folder and give it 600
permissions. Use the chattr
command to disable copy on write
for this file. Set the size of the swap with the dd
command where: if - input file, of - output, bs - block size and count is swap size. After that format swapfile and turn on swap.
⚠️ - Usedd
to allocate swap space instead offallocate
, because it can create file-system holes, more info here.
swap_size=2048;
sudo mount -o subvol=@swap /dev/<linux_partition> /swap;
sudo touch /swap/swapfile;
sudo chmod 600 /swap/swapfile;
sudo chattr +C /swap/swapfile;
sudo dd if=/dev/zero of=/swap/swapfile bs=1024 count=$swap_size;
sudo mkswap /swap/swapfile;
sudo swapon /swap/swapfile
Edit fstab
and add swapfile entries at the end of the file to make changes permanent. First defines that /swap
folder is a separate subvolume and second defines swapfile.
echo 'UUID=<uudi_of_the_btrfs> /swap btrfs subvol=/@swap 0 0' >> /etc/fstab;
echo '/swap/swapfile none swap defaults 0 0' >> /etc/fstab
Verify the /etc/fstab
file after all changes. SWAP should work now with correctly together with snapshots.
⚠️ - Here give the path to your hard disk, not the partition volume where you want to install GRUB, e.g. instead ofvda2
usevda
.
grub-install /dev/<disk>;
grub-mkconfig -o /boot/grub/grub.cfg;
exit
Unmount /mnt
and reboot the system to finish the installation.
umount -R /mnt;
reboot
To list your BTRFS subvolumes use command:
sudo btrfs sub list /
These steps are described on the Arch wiki page here. To run snapper
configuration first unmount snapshots volume and remove snapshots folder created before or make sure it is not there.
sudo umount /.snapshots;
sudo rm -r /.snapshots;
sudo snapper -c root create-config /
Above command creates another subvolume /.snapshots that we do not need. Delete this subvolume, create subvolume folder if not exists and mount subvolume:
sudo btrfs sub del /.snapshots/;
sudo mkdir /.snapshots;
sudo mount -o subvol=@snapshots /dev/<linux_filesystem> /.snapshots
Verify if snapshots subvolume is now in /etc/fstab
. Mount all subvolumes and give 750 permissions to .snapshots
folder
sudo mount -a;
sudo chmod 750 /.snapshots
Configuration files for Snapper are in /etc/snapper/configs/root
file. To use it as a sudo user there is need to add user and group to configuration file.
sudo nvim /etc/snapper/configs/root
Add user and group to be able to use Snapper as user not root:
ALLOW_USERS="my_username"
ALLOW_GROUPS="wheel"
By default Snapper
is creating scheduled hourly snapshots. This is not working until we not install and enable cronie
:
sudo pacman -S --needed cronie;
sudo systemctl enable cronie.service
If you do not want cronie you can use enable below (optional):
sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer
If you do not want to schedule snapshots hourly, this can be disabled by setting below to no
:
TIMELINE_CREATE="no"
If above option is set to yes
, Snapper
is keeping 10 hourly, daily, monthly and yearly snapshots. This can be limited in options e.g. like so:
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="5"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="0"
TIMELINE_LIMIT_MONTHLY="3"
TIMELINE_LIMIT_YEARLY="5"
To manually create snapshots use command with the description use:
snapper create --description "my_snapshot_name"
To enable snapshot restoration from GRUB install grub-btrfs
package (done in previous steps). More info about Snapper configuration here: grub-btrfs.
To manually generate GRUB snapshot entries you can run:
sudo /etc/grub.d/41_snapshots-btrfs
To enable auto refresh list of snapshots in GRUB menu enable grub-btrfsd
service:
sudo systemctl enable grub-btrfsd
Update GRUB to apply all changes.
sudo grub-mkconfig -o /boot/grub/grub.cfg
There can be error about restoring read only snapshots on system boot from GRUB menu. Instructions to fix this for Arch are here: https://github.com/Antynea/grub-btrfs/blob/master/initramfs/readme.md .
git clone https://github.com/Antynea/grub-btrfs.git;
sudo cp grub-btrfs/initramfs/Arch\ Linux/overlay_snap_ro-install /etc/initcpio/install/grub-btrfs-overlayfs;
sudo cp grub-btrfs/initramfs/Arch\ Linux/overlay_snap_ro-hook /etc/initcpio/hooks/grub-btrfs-overlayfs;
rm -rdf grub-btrfs
Next edit /etc/mkinitcpio.conf
file and add grub-btrfs-overlayfs
at the end of the line HOOKS=(... grub-btrfs-overlayfs)
.
sudo nvim /etc/mkinitcpio.conf
Regenerate mkinitcpio
sudo mkinitcpio -P
Bleeding edge system can crash during updates. It is very handy to automatically create snapshot before installing updates. For more details check: snap-pac.
sudo pacman -S snap-pac
Log in to the system using the credentials provided in the installation steps.
If you need to connect to the WiFi, you can use: nmtui
.
Install CPU driver, sound driver, printers, etc
sudo pacman -S cups hplip intel-ucode pipewire pipewire-alsa pipewire-pulse pipewire-jack wireplumber;
sudo systemctl enable cups
Install KDE Plasma and kscreen for screen management.
sudo pacman -S plasma-desktop kscreen
sudo pacman -S firefox kitty
sudo pacman -S xf86-video-intel
Display managers are useful if you have multiple DE's or WM's and want to choose where to boot from in a GUI fashion They also they take care of the launch process.
sudo pacman -S sddm
Enable SDDM service to make it start on boot.
sudo systemctl enable sddm
For KDE install this to control the SDDM configuration from the KDE settings App.
sudo pacman -S --needed sddm-kcm