You are not logged in.
I've been messing around with some mkinitcpio hooks and managed to get several different things working:
Works for me on btrfs with the root subvolume as /@:
- run system in tmpfs (and after manually umounting /boot or /efi, you could remove the disk/USB)
- boot into snapshot
- boot into snapshot + overlay (to allow non-persistent changes to the system)
- boot from squashfs* image with overlay
- create squashfs image
- boot into overlay
Hibernation works for all of the above if you have a separate swap partition and it's set up properly. Just hibernate and boot back in using regular options. This also works with my USB installed arch, too.
* squashfs running using lz4hc compression (make sure lz4 is installed!)
WARNING: do NOT run this if you don't know what mkinitcpio is! Do NOT run on a production system!
/etc/mkinitcpio.conf:
...
HOOKS=(base udev keyboard kms autodetect modconf sd-vconsole block filesystems liveroot resume)
...
What my /etc/fstab looks like:
#/dev/sda3 LABEL=ROOT
UUID=1bbccece-789a-4a05-b114-abff3ba8b7c0 / btrfs rw,noatime,compress-force=zstd:1,ssd,discard=async,space_cache=v2,subvol=/@ 0 0
#/dev/sda2 LABEL=SWAP
UUID=e5451d4d-f7d7-44f2-a0b1-ffdcd139d4a0 none swap defaults 0 0
# /dev/sda1 LABEL=EFI
UUID=7C78-8FB5 /efi vfat ro,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2
/usr/lib/initcpio/hooks/liveroot:
#!/usr/bin/bash
create_archive() {
echo -e "Creating archive file...\n"
cd $real_root/@/
mksquashfs . $real_root/@/root.squashfs -noappend -no-recovery -mem-percent 50 -e root.squashfs -e boot/* -e efi/* -e dev/* -e proc/* -e sys/* -e tmp/* -e run/* -e mnt/ -e .snapshots/ -e var/tmp/* -e var/cache/* -e var/log/* -e etc/pacman.d/gnupg/* -e var/lib/systemd/random-seed
ls -la $real_root/@/root.squashfs
}
create_overlay() {
local lower_dir=$(mktemp -d -p /)
local ram_dir=$(mktemp -d -p /)
mount --move ${new_root} ${lower_dir}
mount -t tmpfs cowspace ${ram_dir}
mkdir -p ${ram_dir}/upper ${ram_dir}/work
mount -t overlay -o lowerdir=${lower_dir},upperdir=${ram_dir}/upper,workdir=${ram_dir}/work rootfs ${new_root}
}
run_latehook() {
echo -e "\nPress any key for extra boot options.\n"
if read -t 4 -s -n 1; then
echo -e "\nPlease choose an option:\n\n\
<s> run snapshot\n\
<w> run snapshot + overlay\n\
<o> run in overlay mode\n\
<e> run squashfs + overlay\n\
<n> create & run squashfs + overlay\n\
<c> copy / to tmpfs\n\
<d> emergency shell\n\n\
<enter> continue boot\n"
read -n 1 -s key
new_root=/new_root
mkdir -p $new_root
if [[ "$key" = "s" ]] || [[ "$key" = "w" ]]; then
mount --mkdir -o subvolid=256 ${root} $new_root
btrfs subvolume list -ts $new_root | less
read -n 3 -p "Choose a snapshot (256 is current system): " subvol
echo -e "\nPlease enter extra mount options (ex., ro ):"
read options
[ ! "$options" = "" ] && options=","$options
echo -e "\nWill proceed with the following mount:\n\nmount -o subvolid=$subvol$options ${root} /\n"
sleep 4
umount $new_root
mount --mkdir -o subvolid=$subvol$options ${root} $new_root
if [ "$?" -ne 0 ]; then
echo "Could not mount subvol ($subvol). Chosing default (256)."
sleep 2
mount --mkdir -o subvolid=256 ${root} $new_root
fi
[[ "$key" = "w" ]] && create_overlay
elif [[ "$key" = "o" ]]; then
create_overlay
elif [[ "$key" = "e" ]] || [[ "$key" = "n" ]] || [[ "$key" = "c" ]]; then
real_root=/real_root
mkdir $real_root
mount ${root} $real_root
if [[ "$key" = "e" ]] || [[ "$key" = "n" ]]; then
[[ ! -f "$real_root/@/root.squashfs" ]] || [[ "$key" = "n" ]] && create_archive
echo "Extracting archive to RAM..."
#unsquashfs -d @new_root -f $real_root/@/root.squashfs
mount "$real_root/@/root.squashfs" $new_root -t squashfs -o loop
create_overlay
umount -l $real_root
elif [[ "$key" = "c" ]]; then
mount -t tmpfs -o size=80% none $new_root
echo "Copying root filesystem to RAM. Please be patient..."
rsync -a --exclude=root.squashfs --exclude=/dev/ --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ --exclude=/run/ --exclude=/mnt/ --exclude=/.snapshots/* --exclude=/var/tmp/ --exclude=/var/cache/ --exclude=/var/log/ --exclude=/mnt/ $real_root/@/ $new_root
fi
elif [[ "$key" = "d" ]]; then
echo "Entering emergency shell."
bash
else
echo "Continuing boot..."
fi
fi
}
/usr/lib/initcpio/install/liveroot :
#!/bin/sh
build() {
add_binary rsync
add_binary bash
add_binary btrfs
add_binary unsquashfs
add_binary mksquashfs
add_binary unionfs
add_module overlay
add_module loop
add_module squashfs
add_module lz4hc
add_runscript
}
help() {
cat << HELPEOF
Run Arch in tmpfs, overlay, squashfs, or snapshot.
HELPEOF
}
update:
mkinitcpio -P
Note: the code has nigh zero error capture, so you MUST read and understand it before running. The script is not meant to handle any deviations other than my setup posted above. It's just a barebones thing.
I made this script because I wasn't able to find much out there that was able to run btrfs in tmpfs, overlay, and squashfs, and I thought I'd share. These hooks should work in grub and rEFInd. It might not work if you have other special hooks enabled, such as booster. The ability to run snapshots is a bonus.
I'm looking for input and critiques.
Offline