User:Fg
Good afternoon!
I am a beginner student who likes Gentoo.
BTRFS snapshots allow systems to return to a previous state. One scheme is creating a top level directory of subvolumes that contains snapshots and directories to exclude from snapshots. To access directories, the command mount -o defaults,subvol=@rootlevelsubvolume /dev/sdxn /dir may be used. A partition containing @debian, @debian-var-cache, @gentoo, @gentoo-241103, @gentoo-var-cache, @gentoo-var-tmp, @mnt, @var-lib-flatpak, and a @home is one example. BTRFS allows heavy use of subvolumes rather than other file system alternatives requiring partition editing. Exacting the free space on the system would be tedious otherwise. A shell script may be used to create a snapshot before updates and save large amounts of recovery time.
#!/bin/sh
fssubvolume="@gentoo"
optionsmount="defaults,noatime,compress-force=zstd:1"
partitionbtrfs="/dev/mmcblk0p3"
dirmnt="/mnt/btrfs"
if [ "$(id -u)" -ne 0 ]; then
echo "Snapshots require superuser account. Exiting."
exit 1
fi
# Prepare mount
if [ ! -d "${dirmnt}" ]; then
mkdir "${dirmnt}"
fi
files="$(find "${dirmnt}" -mindepth 1 -maxdepth 1 -xtype d -o -xtype f -o -xtype l | wc -l)"
if grep -qs "$dirmnt " /proc/mounts || [ "$files" -gt 0 ]; then
echo "$dirmnt must be unmounted first. Aborting automated snapshot."
exit 1
fi
# Protect root subvolume with fallback
datefallback="121212"
daterfc=$(date --rfc-3339=date | cut -c3- | sed -e 's/-//g')
if [ "$daterfc" -lt "$datefallback" ]; then
daterfc="$datefallback"
fi
distrodatedir="${dirmnt}"/"${fssubvolume}"-"${daterfc}"
# Snapshot today
mount -o "${optionsmount}" "${partitionbtrfs}" "${dirmnt}"
if [ -d "${distrodatedir}" ]; then
btrfs property set -ts "${distrodatedir}" ro false
btrfs subvolume delete "${distrodatedir}"
fi
btrfs subvolume snapshot -r "${dirmnt}"/"${fssubvolume}" "${distrodatedir}"
umount "${dirmnt}"
exit 0
After execution, it outputs:
root #
./equip.sh
Create readonly snapshot of '/mnt/btrfs/@gentoo' in '/mnt/btrfs/@gentoo-241103'
root #
./equip.sh
Delete subvolume 302 (no-commit): '/mnt/btrfs/@gentoo-241103' Create readonly snapshot of '/mnt/btrfs/@gentoo' in '/mnt/btrfs/@gentoo-241103'
A LiveCD may be used to revert to a snapshot:
#!/bin/bash
OPTIONSMOUNT="defaults,noatime,compress-force=zstd:1"
PARTITIONBTRFS="/dev/sda3"
MNTDIR="/mnt/btrfs"
DISTROSUBVOLUME="@gentoo"
NAMINGSCHEME="${DISTROSUBVOLUME}[-][0-9]{6}"
if [[ ! -d ${MNTDIR} ]]; then
mkdir ${MNTDIR}
fi
if find ${MNTDIR} -mindepth 1 -maxdepth 1 | read; then
echo "$MNTDIR must be unmounted first."
exit 1
fi
mount -o ${OPTIONSMOUNT} ${PARTITIONBTRFS} ${MNTDIR}
MOSTRECENT=""
MOSTRECENT=$(ls -l ${MNTDIR} | awk '{print $NF}' | egrep $NAMINGSCHEME | sort | tail -n 1)
if [ -z "${MOSTRECENT}" ]; then
echo "$MNTDIR snapshot not found."
echo "No files were changed."
echo "Exiting."
umount ${MNTDIR}
exit 1
fi
btrfs subvolume delete ${MNTDIR}/${DISTROSUBVOLUME}
btrfs subvolume snapshot ${MNTDIR}/${MOSTRECENT} ${MNTDIR}/${DISTROSUBVOLUME}
umount ${MNTDIR}
exit 0
This outputs:
root #
chmod +x egress.bash && ./egress.bash && chmod -x egress.bash
Delete subvolume 301 (no-commit): '/mnt/btrfs/@gentoo' Create a snapshot of '/mnt/btrfs/@gentoo-241114' in '/mnt/btrfs/@gentoo'
This is a GRUB2 entry for the system:
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail -n +3 $0' line above.
#
menuentry '@gentoo 6.6.67 realtime' --class gentoo --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-12345678-0123-5678-0123-567890123456' {
# command substitution and date formatting are broken
date
echo -e "\t\t\t\tLoading\tenvironment\t\t\t\t\t...\n\n"
loader_subvol_dist="@gentoo"
export loader_subvol_dist
loader_kvers=6.6.67-gentoo-dist-hardened
export loader_kvers
loader_kernel="vmlinuz-$loader_kvers"
export loader_kernel
loader_disk="initramfs-$loader_kvers.img"
export loader_disk
loader_uuid_grubpart=12345678-0123-5678-0123-567890123456
export loader_uuid_grubpart
loader_rootuuid=12345678-0123-5678-0123-567890123456
export loader_rootuuid
date
echo -e "\t\t\t\tLoading\tmodules\t\t\t\t\t\t...\n\n"
load_video
if [ "x$grub_platform" = xefi ]; then
set gfxpayload=keep
fi
insmod gzio
insmod part_gpt
insmod ext2
date
echo -e "\t\t\t\tLoading GRUB2\t\t\t\t\t\t...\n\n"
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-baremetal=ahci0,gpt2 $loader_uuid_grubpart
else
search --no-floppy --fs-uuid --set=root $loader_uuid_grubpart
fi
date
echo -e "\t\t\t\tLoading\t$loader_kernel\n\t\t\t\tand\tsubvolume $loader_subvol_dist\t\t\t\t...\n\n"
linux /$loader_kernel root=UUID=$loader_rootuuid ro rootflags=subvol=$loader_subvol_dist preempt=full nohz_full=all threadirqs $vt_handoff
date
echo -e "\t\t\t\tLoading\t$loader_uintel\n\t\t\t\tand\t$loader_uamd\n\t\t\t\tand\t$loader_disk\t..."
initrd /$loader_uintel /$loader_uamd /$loader_disk
}
Take care.