Compare commits

..

1 Commits

Author SHA1 Message Date
Pascal J
3fd87c86da Merge branch 'master' into make-prefix-configurable 2022-11-26 17:34:19 +01:00
17 changed files with 517 additions and 1123 deletions

View File

@@ -1,6 +0,0 @@
[codespell]
skip = .git,*.pdf,*.svg,go.sum,.codespellrc
check-hidden = true
# ignore-regex =
# ist -- unfortunate variable
ignore-words-list = ist

View File

@@ -1,22 +0,0 @@
---
name: Codespell
on:
push:
branches: [master]
pull_request:
branches: [master]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Codespell
uses: codespell-project/actions-codespell@v2

View File

@@ -20,16 +20,14 @@
# - Automatically generate grub.cfg if you use the provided systemd service. # - Automatically generate grub.cfg if you use the provided systemd service.
# #
# Installation: # Installation:
# - Refer to https://github.com/Antynea/grub-btrfs#%EF%B8%8F-installation # - Refer to https://github.com/Antynea/grub-btrfs#installation-
# #
# Customization: # Customization:
# You have the possibility to modify many parameters in /etc/default/grub-btrfs/config. # You have the possibility to modify many parameters in /etc/default/grub-btrfs/config.
# Read more here https://github.com/Antynea/grub-btrfs#installation- an in the manpage
# 'man grub-btrfs'
# #
# Automatically update Grub # Automatically update Grub
# If you would like grub-btrfs menu to automatically update when a snapshot is created or deleted: # If you would like grub-btrfs menu to automatically update when a snapshot is created or deleted:
# - Refer to https://github.com/Antynea/grub-btrfs#-automatically-update-grub-upon-snapshot. # - Refer to https://github.com/Antynea/grub-btrfs#automatically-update-grub.
# #
# Special thanks for assistance and contributions: # Special thanks for assistance and contributions:
# - My friends # - My friends
@@ -41,8 +39,8 @@ set -e
sysconfdir="/etc" sysconfdir="/etc"
grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config" grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config"
[ -f "$grub_btrfs_config" ] && . "$grub_btrfs_config" [[ -f "$grub_btrfs_config" ]] && . "$grub_btrfs_config"
[ -f "${sysconfdir}/default/grub" ] && . "${sysconfdir}/default/grub" [[ -f "${sysconfdir}/default/grub" ]] && . "${sysconfdir}/default/grub"
## Error Handling ## Error Handling
print_error() print_error()
@@ -75,15 +73,15 @@ while getopts :V-: opt; do
done done
## Exit the script, if: ## Exit the script, if:
[ "$(echo "$GRUB_BTRFS_DISABLE" | tr '[:upper:]' '[:lower:]')" = 'true' ] && print_error "GRUB_BTRFS_DISABLE is set to true (default=false)" [[ "${GRUB_BTRFS_DISABLE,,}" == "true" ]] && print_error "GRUB_BTRFS_DISABLE is set to true (default=false)"
if ! type btrfs >/dev/null 2>&1; then print_error "btrfs-progs isn't installed"; fi if ! type btrfs >/dev/null 2>&1; then print_error "btrfs-progs isn't installed"; fi
[ -f "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" ] && . "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" || print_error "grub-mkconfig_lib couldn't be found" [[ -f "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" ]] && . "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" || print_error "grub-mkconfig_lib couldn't be found"
[[ "$(btrfs filesystem df / 2>&1)" == *"not a btrfs filesystem"* ]] && print_error "Root filesystem isn't btrfs" [[ "$(${grub_probe} --target="fs" / 2>/dev/null)" != "btrfs" ]] && print_error "Root filesystem isn't btrfs"
printf "Detecting snapshots ...\n" >&2 ; printf "Detecting snapshots ...\n" >&2 ;
## Submenu name ## Submenu name
distro=$(awk -F "=" '/^NAME=/ {gsub(/"/, "", $2); print $2}' /etc/os-release) # escape ' distro=$(awk -F "=" '/^NAME=/ {gsub(/"/, "", $2); print $2}' /etc/os-release)
submenuname=${GRUB_BTRFS_SUBMENUNAME:-"${distro:-Linux} snapshots"} submenuname=${GRUB_BTRFS_SUBMENUNAME:-"${distro:-Linux} snapshots"}
## Limit snapshots to show in the Grub menu (default=50) ## Limit snapshots to show in the Grub menu (default=50)
limit_snap_show="${GRUB_BTRFS_LIMIT:-50}" limit_snap_show="${GRUB_BTRFS_LIMIT:-50}"
@@ -94,12 +92,12 @@ grub_directory=${GRUB_BTRFS_GRUB_DIRNAME:-"/boot/grub"}
## Customize BOOT directory, where kernels/initrams/microcode is saved. ## Customize BOOT directory, where kernels/initrams/microcode is saved.
boot_directory=${GRUB_BTRFS_BOOT_DIRNAME:-"/boot"} boot_directory=${GRUB_BTRFS_BOOT_DIRNAME:-"/boot"}
## Customize GRUB-BTRFS.cfg directory, where "grub-btrfs.cfg" file is saved ## Customize GRUB-BTRFS.cfg directory, where "grub-btrfs.cfg" file is saved
grub_btrfs_directory=${GRUB_BTRFS_GBTRFS_DIRNAME:-${grub_directory}} grub_btrfs_directory=${GRUB_BTRFS_GBTRFS_DIRNAME:-"/boot/grub"}
## Customize directory where "grub-btrfs.cfg" file is searched for by grub ## Customize directory where "grub-btrfs.cfg" file is searched for by grub
grub_btrfs_search_directory=${GRUB_BTRFS_GBTRFS_SEARCH_DIRNAME:-"\${prefix}"} grub_btrfs_search_directory=${GRUB_BTRFS_GBTRFS_SEARCH_DIRNAME:-"\${prefix}"}
## Password protection management for submenu ## Password protection management for submenu
# Protection support for submenu (--unrestricted) # Protection support for submenu (--unrestricted)
case "$(echo "$GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU" | tr '[:upper:]' '[:lower:]')" in case "${GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU,,}" in
true) unrestricted_access_submenu="--unrestricted ";; true) unrestricted_access_submenu="--unrestricted ";;
*) unrestricted_access_submenu="" *) unrestricted_access_submenu=""
esac esac
@@ -107,88 +105,23 @@ esac
if [ -n "${GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS}" ] ; then if [ -n "${GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS}" ] ; then
protection_authorized_users="--users ${GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS} " protection_authorized_users="--users ${GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS} "
fi fi
## Probe information of Root and Boot devices
# -----------------------------------------------------------
# ---------- Root partition ---------- ## Probe informations of Root and Boot devices
root_device="$(${grub_probe} --target=device /)" # e.g. /dev/mapper/enc # Probe info "Root partition"
root_uuid="$(${grub_probe} --device "${root_device}" --target=fs_uuid 2>/dev/null)" || true root_device=$(${grub_probe} --target=device /) # Root device
root_uuid=$(${grub_probe} --device ${root_device} --target="fs_uuid" 2>/dev/null) # UUID of the root device
# Fallback when grub-probe fails (encrypted container, detached header…) root_uuid_subvolume=$(btrfs subvolume show / 2>/dev/null) || print_error "UUID of the root subvolume is not available"; # If UUID of root subvolume is not available, then exit
if [ -z "$root_uuid" ]; then root_uuid_subvolume=$(awk -F":" 'match($1, /(^[ \t]+UUID)/) {sub(/^[ \t]+/, "", $2); print $2}' <<< "$root_uuid_subvolume") # UUID of the root subvolume
root_uuid="$(blkid -s UUID -o value "${root_device}" 2>/dev/null)" # Probe info "Boot partition"
fi boot_device=$(${grub_probe} --target=device ${boot_directory}) # Boot device
[ -z "$root_uuid" ] && print_error "Cannot determine UUID of ${root_device}" boot_uuid=$(${grub_probe} --device ${boot_device} --target="fs_uuid" 2>/dev/null) # UUID of the boot device
boot_uuid_subvolume=$(btrfs subvolume show "$boot_directory" 2>/dev/null) || boot_uuid_subvolume=" UUID: $root_uuid_subvolume"; # If boot folder isn't a subvolume, then UUID=root_uuid_subvolume
# Root subvolume UUID boot_uuid_subvolume=$(awk -F":" 'match($1, /(^[ \t]+UUID)/) {sub(/^[ \t]+/, "", $2); print $2}' <<< "$boot_uuid_subvolume") # UUID of the boot subvolume
root_uuid_subvolume="$(btrfs subvolume show / 2>/dev/null | \ boot_hs=$(${grub_probe} --device ${boot_device} --target="hints_string" 2>/dev/null) # hints string
awk -F':' '/^\s*UUID/ {gsub(/^[ \t]+/, "", $2); print $2}')" boot_fs=$(${grub_probe} --device ${boot_device} --target="fs" 2>/dev/null) # Type filesystem of boot device
[ -z "$root_uuid_subvolume" ] && print_error "UUID of the root subvolume is not available"
# ---------- Boot partition ----------
boot_device="$(${grub_probe} --target=device "${boot_directory}")" # e.g. /dev/sdb1
boot_uuid="$(${grub_probe} --device "${boot_device}" --target=fs_uuid 2>/dev/null)" || true
# Fallback for boot UUID
if [ -z "$boot_uuid" ]; then
boot_uuid="$(blkid -s UUID -o value "${boot_device}" 2>/dev/null)"
fi
[ -z "$boot_uuid" ] && print_error "Cannot determine UUID of ${boot_device}"
# If /boot is not a Btrfs subvolume, reuse root subvol UUID
boot_uuid_subvolume="$(
btrfs subvolume show "${boot_directory}" 2>/dev/null | \
awk -F':' '/^\s*UUID/ {gsub(/^[ \t]+/, "", $2); print $2; exit}'
)"
[ -z "$boot_uuid_subvolume" ] && boot_uuid_subvolume="$root_uuid_subvolume"
# Extra data for GRUB commands
boot_hs="$(${grub_probe} --device "${boot_device}" --target=hints_string 2>/dev/null)"
boot_fs="$(${grub_probe} --device "${boot_device}" --target=fs 2>/dev/null)"
# -----------------------------------------------------------
## Enable LUKS encrypted devices support
case "$(echo "$GRUB_BTRFS_ENABLE_CRYPTODISK" | tr '[:upper:]' '[:lower:]')" in
true)
list_insmods=(
"insmod gzio"
"insmod part_gpt"
"insmod cryptodisk"
"insmod luks"
"insmod gcry_rijndael"
"insmod gcry_rijndael"
"insmod gcry_sha256"
"insmod ${boot_fs}"
)
# Extract the <source> field of cryptdevice=<source>:<name>[:header]
crypt_source="$(printf '%s %s\n' "$GRUB_CMDLINE_LINUX_DEFAULT" "$GRUB_CMDLINE_LINUX" \
| grep -o -P 'cryptdevice=\K[^:]+' || true)"
# Turn the source into a UUID that cryptomount -u understands
crypt_uuid=""
if [[ "$crypt_source" =~ ^UUID=.* ]]; then # already UUID=…
crypt_uuid="${crypt_source#UUID=}"
elif [[ "$crypt_source" == /dev/* ]]; then # path → resolve → blkid
real_dev=$(readlink -f "$crypt_source" 2>/dev/null || true)
[ -b "$real_dev" ] && crypt_uuid=$(blkid -s UUID -o value "$real_dev" 2>/dev/null || true)
fi
# Emit the proper cryptomount command
if [[ "$crypt_uuid" =~ ^[0-9a-fA-F-]{36}$ ]]; then
list_insmods+=("cryptomount -u ${crypt_uuid}")
else
# last-resort: scan all crypto containers (works but a bit slower)
list_insmods+=("cryptomount -a")
fi
;;
*)
list_insmods=("insmod ${boot_fs}")
;;
esac
## Parameters passed to the kernel ## Parameters passed to the kernel
kernel_parameters="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT $GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS" kernel_parameters="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
## Mount point location ## Mount point location
grub_btrfs_mount_point=$(mktemp -dt grub-btrfs.XXXXXXXXXX) grub_btrfs_mount_point=$(mktemp -dt grub-btrfs.XXXXXXXXXX)
## Class for theme ## Class for theme
@@ -197,7 +130,7 @@ CLASS="--class snapshots --class gnu-linux --class gnu --class os"
oldIFS=$IFS oldIFS=$IFS
## Detect uuid requirement (lvm,btrfs...) ## Detect uuid requirement (lvm,btrfs...)
check_uuid_required() { check_uuid_required() {
if [ "${root_uuid}" = "" ] || [ "${GRUB_DISABLE_LINUX_UUID}" = "true" ] \ if [ "x${root_uuid}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${root_uuid}" \ || ! test -e "/dev/disk/by-uuid/${root_uuid}" \
|| ( test -e "${root_device}" && uses_abstraction "${root_device}" lvm ); then || ( test -e "${root_device}" && uses_abstraction "${root_device}" lvm ); then
LINUX_ROOT_DEVICE=${root_device} LINUX_ROOT_DEVICE=${root_device}
@@ -215,7 +148,7 @@ detect_rootflags()
unmount_grub_btrfs_mount_point() unmount_grub_btrfs_mount_point()
{ {
if [ -d "$grub_btrfs_mount_point" ]; then if [[ -d "$grub_btrfs_mount_point" ]]; then
local wait=true local wait=true
local wait_max=0 local wait_max=0
printf "Unmount %s .." "$grub_btrfs_mount_point" >&2; printf "Unmount %s .." "$grub_btrfs_mount_point" >&2;
@@ -225,7 +158,7 @@ if [ -d "$grub_btrfs_mount_point" ]; then
if umount "$grub_btrfs_mount_point" >/dev/null 2>&1; then if umount "$grub_btrfs_mount_point" >/dev/null 2>&1; then
wait=false # umount successful wait=false # umount successful
printf " Success\n" >&2; printf " Success\n" >&2;
elif [ $wait_max -eq 10 ]; then elif [[ $wait_max = 10 ]]; then
printf "\nWarning: Unable to unmount %s in %s\n" "$root_device" "$grub_btrfs_mount_point" >&2; printf "\nWarning: Unable to unmount %s in %s\n" "$root_device" "$grub_btrfs_mount_point" >&2;
break; break;
else else
@@ -237,9 +170,9 @@ if [ -d "$grub_btrfs_mount_point" ]; then
printf " Success\n" >&2; printf " Success\n" >&2;
fi fi
done done
if [ "$wait" != true ]; then if [[ "$wait" != true ]]; then
if ! rm -d "$grub_btrfs_mount_point" >/dev/null 2>&1; then if ! rm -d "$grub_btrfs_mount_point" >/dev/null 2>&1; then
printf "Unable to delete %s: Device or resource is busy\n" "$grub_btrfs_mount_point" >&2; printf "Unable to delete %s: Device or ressource is busy\n" "$grub_btrfs_mount_point" >&2;
fi fi
fi fi
fi fi
@@ -258,10 +191,10 @@ make_menu_entries()
entry "submenu '${title_menu}' { entry "submenu '${title_menu}' {
submenu '${title_submenu}' { echo }" submenu '${title_submenu}' { echo }"
for k in "${name_kernel[@]}"; do for k in "${name_kernel[@]}"; do
[ ! -f "${boot_dir}"/"${k}" ] && continue; [[ ! -f "${boot_dir}"/"${k}" ]] && continue;
kversion=${k#*"-"} kversion=${k#*"-"}
for i in "${name_initramfs[@]}"; do for i in "${name_initramfs[@]}"; do
if [ "${name_initramfs}" != "x" ] ; then if [[ "${name_initramfs}" != "x" ]] ; then
# prefix_i=${i%%"-"*} # prefix_i=${i%%"-"*}
suffix_i=${i#*"-"} suffix_i=${i#*"-"}
# alt_suffix_i=${i##*"-"} # alt_suffix_i=${i##*"-"}
@@ -272,7 +205,7 @@ make_menu_entries()
else continue; else continue;
fi fi
for u in "${name_microcode[@]}"; do for u in "${name_microcode[@]}"; do
if [ "${name_microcode}" != "x" ] ; then if [[ "${name_microcode}" != "x" ]] ; then
entry " entry "
menuentry ' "${k}" & "${i}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {" menuentry ' "${k}" & "${i}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {"
else else
@@ -283,26 +216,17 @@ make_menu_entries()
if [ x\$feature_all_video_module = xy ]; then if [ x\$feature_all_video_module = xy ]; then
insmod all_video insmod all_video
fi fi
set gfxpayload=keep" set gfxpayload=keep
for j in "${insmods[@]}"; do insmod ${boot_fs}
entry "\
${j}"
done
entry "\
if [ x\$feature_platform_search_hint = xy ]; then if [ x\$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root ${boot_hs} ${boot_uuid} search --no-floppy --fs-uuid --set=root ${boot_hs} ${boot_uuid}
else else
search --no-floppy --fs-uuid --set=root ${boot_uuid} search --no-floppy --fs-uuid --set=root ${boot_uuid}
fi"
if [ "${SUSE_BTRFS_SNAPSHOT_BOOTING:-"false"}" = "true" ]; then
entry "\
set btrfs_subvolid=5"
fi fi
entry "\
echo 'Loading Snapshot: "${snap_date_trim}" "${snap_dir_name_trim}"' echo 'Loading Snapshot: "${snap_date_trim}" "${snap_dir_name_trim}"'
echo 'Loading Kernel: "${k}" ...' echo 'Loading Kernel: "${k}" ...'
linux \"${boot_dir_root_grub}/"${k}"\" root="${LINUX_ROOT_DEVICE}" ${kernel_parameters} ${rootflags}subvol=\""${snap_dir_name_trim}"\"" linux \"${boot_dir_root_grub}/"${k}"\" root="${LINUX_ROOT_DEVICE}" ${kernel_parameters} ${rootflags}subvol=\""${snap_dir_name_trim}"\""
if [ "${name_microcode}" != "x" ] ; then if [[ "${name_microcode}" != "x" ]] ; then
entry "\ entry "\
echo 'Loading Microcode & Initramfs: "${u}" "${i}" ...' echo 'Loading Microcode & Initramfs: "${u}" "${i}" ...'
initrd \"${boot_dir_root_grub}/"${u}"\" \"${boot_dir_root_grub}/"${i}"\"" initrd \"${boot_dir_root_grub}/"${u}"\" \"${boot_dir_root_grub}/"${i}"\""
@@ -316,7 +240,7 @@ make_menu_entries()
done done
else else
for u in "${name_microcode[@]}"; do for u in "${name_microcode[@]}"; do
if [ "${name_microcode}" != "x" ] ; then if [[ "${name_microcode}" != "x" ]] ; then
entry " entry "
menuentry ' "${k}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {" menuentry ' "${k}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {"
else else
@@ -333,16 +257,11 @@ make_menu_entries()
search --no-floppy --fs-uuid --set=root ${boot_hs} ${boot_uuid} search --no-floppy --fs-uuid --set=root ${boot_hs} ${boot_uuid}
else else
search --no-floppy --fs-uuid --set=root ${boot_uuid} search --no-floppy --fs-uuid --set=root ${boot_uuid}
fi"
if [ "${SUSE_BTRFS_SNAPSHOT_BOOTING:-"false"}" = "true" ]; then
entry "\
set btrfs_subvolid=5"
fi fi
entry "\
echo 'Loading Snapshot: "${snap_date_trim}" "${snap_dir_name_trim}"' echo 'Loading Snapshot: "${snap_date_trim}" "${snap_dir_name_trim}"'
echo 'Loading Kernel: "${k}" ...' echo 'Loading Kernel: "${k}" ...'
linux \"${boot_dir_root_grub}/"${k}"\" root="${LINUX_ROOT_DEVICE}" ${kernel_parameters} ${rootflags}subvol=\""${snap_dir_name_trim}"\"" linux \"${boot_dir_root_grub}/"${k}"\" root="${LINUX_ROOT_DEVICE}" ${kernel_parameters} ${rootflags}subvol=\""${snap_dir_name_trim}"\""
if [ "${name_microcode}" != "x" ] ; then if [[ "${name_microcode}" != "x" ]] ; then
entry "\ entry "\
echo 'Loading Microcode: "${u}" ...' echo 'Loading Microcode: "${u}" ...'
initrd \"${boot_dir_root_grub}/"${u}"\"" initrd \"${boot_dir_root_grub}/"${u}"\""
@@ -376,7 +295,7 @@ snapshot_list()
IFS=$'\n' IFS=$'\n'
for snap in $(btrfs subvolume list -sa "${btrfs_subvolume_sort}" /); do # Parse btrfs snapshots for snap in $(btrfs subvolume list -sa "${btrfs_subvolume_sort}" /); do # Parse btrfs snapshots
IFS=$oldIFS IFS=$oldIFS
snap=(${snap}) snap=($snap)
local path_snapshot=${snap[@]:13:${#snap[@]}} local path_snapshot=${snap[@]:13:${#snap[@]}}
if [ "$path_snapshot" = "DELETED" ]; then continue; fi # Discard deleted snapshots if [ "$path_snapshot" = "DELETED" ]; then continue; fi # Discard deleted snapshots
[[ ${path_snapshot%%"/"*} == "<FS_TREE>" ]] && path_snapshot=${path_snapshot#*"/"} # Remove the "<FS_TREE>" string at the beginning of the path [[ ${path_snapshot%%"/"*} == "<FS_TREE>" ]] && path_snapshot=${path_snapshot#*"/"} # Remove the "<FS_TREE>" string at the beginning of the path
@@ -384,7 +303,7 @@ snapshot_list()
# ignore specific path during run "grub-mkconfig" # ignore specific path during run "grub-mkconfig"
if [ -n "${GRUB_BTRFS_IGNORE_SPECIFIC_PATH}" ] ; then if [ -n "${GRUB_BTRFS_IGNORE_SPECIFIC_PATH}" ] ; then
for isp in "${GRUB_BTRFS_IGNORE_SPECIFIC_PATH[@]}" ; do for isp in "${GRUB_BTRFS_IGNORE_SPECIFIC_PATH[@]}" ; do
[ "${path_snapshot}" = "${isp}" ] && continue 2; [[ "${path_snapshot}" == "${isp}" ]] && continue 2;
done done
fi fi
if [ -n "${GRUB_BTRFS_IGNORE_PREFIX_PATH}" ] ; then if [ -n "${GRUB_BTRFS_IGNORE_PREFIX_PATH}" ] ; then
@@ -392,38 +311,30 @@ snapshot_list()
[[ "${path_snapshot}" == "${isp}"/* ]] && continue 2; [[ "${path_snapshot}" == "${isp}"/* ]] && continue 2;
done done
fi fi
[ ! -d "$grub_btrfs_mount_point/$path_snapshot/boot" ] && continue; # Discard snapshots without /boot folder [[ ! -d "$grub_btrfs_mount_point/$path_snapshot/boot" ]] && continue; # Discard snapshots without /boot folder
# Parse Snapper & timeshift & yabsnap information # Parse Snapper & timeshift informations
local type_snapshot="N/A" local type_snapshot="N/A"
local description_snapshot="N/A" local description_snapshot="N/A"
# path to yabsnap snapshot meta data
local yabsnap_info="$grub_btrfs_mount_point/${path_snapshot%"/"*}/$(echo "${snap[13]}" | awk -F'/' '{print $3 "-meta.json"}')"
if [[ -s "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info" ]] ; then if [[ -s "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info" ]] ; then
type_snapshot=$(awk -F"<|>" 'match($2, /^type/) {print $3}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info") # search matching string beginning "type" type_snapshot=$(awk -F"<|>" 'match($2, /^type/) {print $3}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info") # search matching string beginning "type"
description_snapshot=$(awk -F"<|>" 'match($2, /^description/) {print $3}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info") # search matching string beginning "description" description_snapshot=$(awk -F"<|>" 'match($2, /^description/) {print $3}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info") # search matching string beginning "description"
elif [[ -s "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$timeshift_info" ]] ; then elif [[ -s "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$timeshift_info" ]] ; then
type_snapshot=$(awk -F" : " 'match($1, /^[ \t]+"tags"/) {gsub(/"|,/,"");print $2}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$timeshift_info") # search matching string beginning "tags" type_snapshot=$(awk -F" : " 'match($1, /^[ \t]+"tags"/) {gsub(/"|,/,"");print $2}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$timeshift_info") # search matching string beginning "tags"
description_snapshot=$(awk -F" : " 'match($1, /^[ \t]+"comments"/) {gsub(/"|,/,"");print $2}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$timeshift_info") # search matching string beginning "comments" fix ' description_snapshot=$(awk -F" : " 'match($1, /^[ \t]+"comments"/) {gsub(/"|,/,"");print $2}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$timeshift_info") # search matching string beginning "comments"
elif [[ -s $yabsnap_info ]] ; then
type_snapshot=$(grep -P '^\s*"trigger"' $yabsnap_info | awk -F'"' '{print $4}') # search matching string beginning "trigger"
description_snapshot=$(grep -P '^\s*"comment"' $yabsnap_info | awk -F'"' '{print $4}') # search matching string beginning "comment"
fi fi
[[ -z "$type_snapshot" ]] && type_snapshot=("N/A")
[ -z "$type_snapshot" ] && type_snapshot=("N/A") [[ -z "$description_snapshot" ]] && description_snapshot=("N/A")
[ -z "$description_snapshot" ] && description_snapshot=("N/A")
# ignore specific {type,tag,description} of snapshot during run "grub-mkconfig" # ignore specific {type,tag,description} of snapshot during run "grub-mkconfig"
if [ -n "${GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE}" ] ; then if [ -n "${GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE}" ] ; then
for ist in "${GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE[@]}" ; do for ist in "${GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE[@]}" ; do
[ "${type_snapshot}" = "${ist}" ] && continue 2; [[ "${type_snapshot}" == "${ist}" ]] && continue 2;
done done
fi fi
if [ -n "${GRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION}" ] ; then if [ -n "${GRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION}" ] ; then
for isd in "${GRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION[@]}" ; do for isd in "${GRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION[@]}" ; do
[ "${description_snapshot}" = "${isd}" ] && continue 2; [[ "${description_snapshot}" == "${isd}" ]] && continue 2;
done done
fi fi
@@ -438,21 +349,21 @@ snapshot_list()
local max_date_length=0 local max_date_length=0
for i in "${date_snapshots[@]}"; do for i in "${date_snapshots[@]}"; do
local length="${#i}" local length="${#i}"
[ "$length" -gt "$max_date_length" ] && max_date_length=$length [[ "$length" -gt "$max_date_length" ]] && max_date_length=$length
done done
# Find max length of a snapshot name, needed for pretty formatting # Find max length of a snapshot name, needed for pretty formatting
local max_path_length=0 local max_path_length=0
for i in "${path_snapshots[@]}"; do for i in "${path_snapshots[@]}"; do
local length="${#i}" local length="${#i}"
[ "$length" -gt "$max_path_length" ] && max_path_length=$length [[ "$length" -gt "$max_path_length" ]] && max_path_length=$length
done done
# Find max length of a snapshot type, needed for pretty formatting # Find max length of a snapshot type, needed for pretty formatting
local max_type_length=0 local max_type_length=0
for i in "${type_snapshots[@]}"; do for i in "${type_snapshots[@]}"; do
local length="${#i}" local length="${#i}"
[ "$length" -gt "$max_type_length" ] && max_type_length=$length [[ "$length" -gt "$max_type_length" ]] && max_type_length=$length
done done
# Find max length of a snapshot description, needed for pretty formatting # Find max length of a snapshot description, needed for pretty formatting
@@ -493,14 +404,14 @@ detect_kernel()
for okernel in "${boot_dir}"/vmlinuz-* \ for okernel in "${boot_dir}"/vmlinuz-* \
"${boot_dir}"/vmlinux-* \ "${boot_dir}"/vmlinux-* \
"${boot_dir}"/kernel-* ; do "${boot_dir}"/kernel-* ; do
[ ! -f "${okernel}" ] && continue; [[ ! -f "${okernel}" ]] && continue;
list_kernel+=("$okernel") list_kernel+=("$okernel")
done done
# Custom name kernel in "GRUB_BTRFS_NKERNEL" # Custom name kernel in "GRUB_BTRFS_NKERNEL"
if [ -n "${GRUB_BTRFS_NKERNEL}" ] ; then if [ -n "${GRUB_BTRFS_NKERNEL}" ] ; then
for ckernel in "${boot_dir}/${GRUB_BTRFS_NKERNEL[@]}" ; do for ckernel in "${boot_dir}/${GRUB_BTRFS_NKERNEL[@]}" ; do
[ ! -f "${ckernel}" ] && continue; [[ ! -f "${ckernel}" ]] && continue;
list_kernel+=("$ckernel") list_kernel+=("$ckernel")
done done
fi fi
@@ -514,14 +425,14 @@ detect_initramfs()
for oinitramfs in "${boot_dir}"/initrd.img-* \ for oinitramfs in "${boot_dir}"/initrd.img-* \
"${boot_dir}"/initramfs-* \ "${boot_dir}"/initramfs-* \
"${boot_dir}"/initrd-* ; do "${boot_dir}"/initrd-* ; do
[ ! -f "${oinitramfs}" ] && continue; [[ ! -f "${oinitramfs}" ]] && continue;
list_initramfs+=("$oinitramfs") list_initramfs+=("$oinitramfs")
done done
# Custom name initramfs in "GRUB_BTRFS_NINIT" # Custom name initramfs in "GRUB_BTRFS_NINIT"
if [ -n "${GRUB_BTRFS_NINIT}" ] ; then if [ -n "${GRUB_BTRFS_NINIT}" ] ; then
for cinitramfs in "${boot_dir}/${GRUB_BTRFS_NINIT[@]}" ; do for cinitramfs in "${boot_dir}/${GRUB_BTRFS_NINIT[@]}" ; do
[ ! -f "${cinitramfs}" ] && continue; [[ ! -f "${cinitramfs}" ]] && continue;
list_initramfs+=("$cinitramfs") list_initramfs+=("$cinitramfs")
done done
fi fi
@@ -534,9 +445,13 @@ detect_microcode()
list_ucode=() list_ucode=()
# Original intel/amd microcode (auto-detect) # Original intel/amd microcode (auto-detect)
# See "https://www.gnu.org/software/grub/manual/grub/html_node/Simple-configuration.html" # See "https://www.gnu.org/software/grub/manual/grub/html_node/Simple-configuration.html"
for oiucode in ${GRUB_EARLY_INITRD_LINUX_STOCK} ; do for oiucode in "${boot_dir}"/intel-uc.img \
oiucode="${boot_dir}/${oiucode}" "${boot_dir}"/intel-ucode.img \
[ ! -f "${oiucode}" ] && continue; "${boot_dir}"/amd-uc.img \
"${boot_dir}"/amd-ucode.img \
"${boot_dir}"/early_ucode.cpio \
"${boot_dir}"/microcode.cpio; do
[[ ! -f "${oiucode}" ]] && continue;
list_ucode+=("$oiucode") list_ucode+=("$oiucode")
done done
@@ -592,7 +507,7 @@ boot_bounded()
# Initialize menu entries # Initialize menu entries
IFS=$'\n' IFS=$'\n'
for item in $(snapshot_list); do for item in $(snapshot_list); do
[ "${limit_snap_show}" -le 0 ] && break; # fix: limit_snap_show=0 [[ ${limit_snap_show} -le 0 ]] && break; # fix: limit_snap_show=0
IFS=$oldIFS IFS=$oldIFS
parse_snapshot_list parse_snapshot_list
boot_dir="$grub_btrfs_mount_point/$snap_dir_name_trim$boot_directory" boot_dir="$grub_btrfs_mount_point/$snap_dir_name_trim$boot_directory"
@@ -606,15 +521,14 @@ boot_bounded()
detect_rootflags detect_rootflags
title_format title_format
boot_dir_root_grub="$(make_system_path_relative_to_its_root "${boot_dir}")" # convert "boot_directory" to root of GRUB (e.g /boot become /) boot_dir_root_grub="$(make_system_path_relative_to_its_root "${boot_dir}")" # convert "boot_directory" to root of GRUB (e.g /boot become /)
insmods=("${list_insmods[@]##*"/"}")
make_menu_entries make_menu_entries
# show snapshot found during run "grub-mkconfig" # show snapshot found during run "grub-mkconfig"
if [ "${GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND:-"true"}" = "true" ]; then if [[ "${GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND:-"true"}" = "true" ]]; then
printf "Found snapshot: %s\n" "$item" >&2 ; printf "Found snapshot: %s\n" "$item" >&2 ;
fi fi
# Limit snapshots found during run "grub-mkconfig" # Limit snapshots found during run "grub-mkconfig"
count_limit_snap=$((1+count_limit_snap)) count_limit_snap=$((1+count_limit_snap))
[ "$count_limit_snap" -ge "$limit_snap_show" ] && break; [[ $count_limit_snap -ge $limit_snap_show ]] && break;
done done
IFS=$oldIFS IFS=$oldIFS
} }
@@ -634,72 +548,59 @@ boot_separate()
# Initialize menu entries # Initialize menu entries
IFS=$'\n' IFS=$'\n'
for item in $(snapshot_list); do for item in $(snapshot_list); do
[ "${limit_snap_show}" -le 0 ] && break; # fix: limit_snap_show=0 [[ ${limit_snap_show} -le 0 ]] && break; # fix: limit_snap_show=0
IFS=$oldIFS IFS=$oldIFS
parse_snapshot_list parse_snapshot_list
detect_rootflags detect_rootflags
title_format title_format
make_menu_entries make_menu_entries
# show snapshot found during run "grub-mkconfig" # show snapshot found during run "grub-mkconfig"
if [ "${GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND:-"true"}" = "true" ]; then if [[ "${GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND:-"true"}" = "true" ]]; then
printf "Found snapshot: %s\n" "$item" >&2 ; printf "Found snapshot: %s\n" "$item" >&2 ;
fi fi
# Limit snapshots found during run "grub-mkconfig" # Limit snapshots found during run "grub-mkconfig"
count_limit_snap=$((1+count_limit_snap)) count_limit_snap=$((1+count_limit_snap))
[ "$count_limit_snap" -ge "$limit_snap_show" ] && break; [[ $count_limit_snap -ge $limit_snap_show ]] && break;
done done
IFS=$oldIFS IFS=$oldIFS
} }
rm -f "$grub_btrfs_directory/grub-btrfs.new" rm -f "$grub_btrfs_directory/grub-btrfs.new"
true > "$grub_btrfs_directory/grub-btrfs.new" # Create a "grub-btrfs.new" file in "grub_btrfs_directory" > "$grub_btrfs_directory/grub-btrfs.new" # Create a "grub-btrfs.new" file in "grub_btrfs_directory"
# Create a backup of the "$grub_btrfs_directory/grub-btrfs.cfg" file if exist
if [ -e "$grub_btrfs_directory/grub-btrfs.cfg" ]; then
mv -f "$grub_btrfs_directory/grub-btrfs.cfg" "$grub_btrfs_directory/grub-btrfs.cfg.bkp"
fi
# Create mount point then mounting # Create mount point then mounting
[ ! -d "$grub_btrfs_mount_point" ] && mkdir -p "$grub_btrfs_mount_point" [[ ! -d $grub_btrfs_mount_point ]] && mkdir -p "$grub_btrfs_mount_point"
mount -o ro,subvolid=5 /dev/disk/by-uuid/"$root_uuid" "$grub_btrfs_mount_point/" > /dev/null mount -o ro,subvolid=5 /dev/disk/by-uuid/"$root_uuid" "$grub_btrfs_mount_point/"
trap "unmount_grub_btrfs_mount_point" EXIT # unmounting mount point on EXIT signal trap "unmount_grub_btrfs_mount_point" EXIT # unmounting mount point on EXIT signal
count_warning_menuentries=0 # Count menuentries count_warning_menuentries=0 # Count menuentries
count_limit_snap=0 # Count snapshots count_limit_snap=0 # Count snapshots
check_uuid_required check_uuid_required
# Detects if /boot is a separate partition # Detects if /boot is a separate partition
[ "$(echo "$GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION}" | tr '[:upper:]' '[:lower:]')" = "true" ] && printf "Override boot partition detection : enable \n" >&2 && boot_separate; [[ "${GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION,,}" == "true" ]] && printf "Override boot partition detection : enable \n" >&2 && boot_separate;
if [ "$root_uuid" != "$boot_uuid" ] || [ "$root_uuid_subvolume" != "$boot_uuid_subvolume" ]; then boot_separate ; else boot_bounded ; fi if [[ "$root_uuid" != "$boot_uuid" ]] || [[ "$root_uuid_subvolume" != "$boot_uuid_subvolume" ]]; then boot_separate ; else boot_bounded ; fi
# Make a submenu in GRUB (grub.cfg)
cat << EOF
if [ ! -e "${grub_btrfs_search_directory}/grub-btrfs.cfg" ]; then
echo ""
else
submenu '${submenuname}' ${protection_authorized_users}${unrestricted_access_submenu}{
configfile "${grub_btrfs_search_directory}/grub-btrfs.cfg"
}
fi
EOF
# Show warn, menuentries exceeds 250 entries # Show warn, menuentries exceeds 250 entries
[ $count_warning_menuentries -ge 250 ] && printf "Generated %s total GRUB entries. You might experience issues loading snapshots menu in GRUB.\n" "${count_warning_menuentries}" >&2 ; [[ $count_warning_menuentries -ge 250 ]] && printf "Generated %s total GRUB entries. You might experience issues loading snapshots menu in GRUB.\n" "${count_warning_menuentries}" >&2 ;
# Show total found snapshots # Show total found snapshots
if [ "${GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND:-"true"}" = "true" ] && [ -n "${count_limit_snap}" ] && [ "${count_limit_snap}" != "0" ]; then if [[ "${GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND:-"true"}" = "true" && -n "${count_limit_snap}" && "${count_limit_snap}" != "0" ]]; then
printf "Found %s snapshot(s)\n" "${count_limit_snap}" >&2 ; printf "Found %s snapshot(s)\n" "${count_limit_snap}" >&2 ;
fi fi
# if no snapshot found, delete the "$grub_btrfs_directory/grub-btrfs.new" file and the "$grub_btrfs_directory/grub-btrfs.cfg.bkp" file and exit # if no snapshot found, exit
if [ "${count_limit_snap}" = "0" ] || [ -z "${count_limit_snap}" ]; then if [[ "${count_limit_snap}" = "0" || -z "${count_limit_snap}" ]]; then
rm -f "$grub_btrfs_directory/grub-btrfs.new" "$grub_btrfs_directory/grub-btrfs.cfg.bkp"
print_error "No snapshots found." print_error "No snapshots found."
fi fi
# Move "grub-btrfs.new" to "grub-btrfs.cfg" # Make a submenu in GRUB (grub.cfg) and move "grub-btrfs.new" to "grub-btrfs.cfg"
header_menu header_menu
if "${bindir}/${GRUB_BTRFS_SCRIPT_CHECK:-grub-script-check}" "$grub_btrfs_directory/grub-btrfs.new"; then if "${bindir}/${GRUB_BTRFS_SCRIPT_CHECK:-grub-script-check}" "$grub_btrfs_directory/grub-btrfs.new"; then
cat "$grub_btrfs_directory/grub-btrfs.new" > "$grub_btrfs_directory/grub-btrfs.cfg" cat "$grub_btrfs_directory/grub-btrfs.new" > "$grub_btrfs_directory/grub-btrfs.cfg"
rm -f "$grub_btrfs_directory/grub-btrfs.new" "$grub_btrfs_directory/grub-btrfs.cfg.bkp" rm -f "$grub_btrfs_directory/grub-btrfs.new"
cat << EOF
submenu '${submenuname}' ${protection_authorized_users}${unrestricted_access_submenu}{
configfile "${grub_btrfs_search_directory}/grub-btrfs.cfg"
}
EOF
else else
if [ -e "$grub_btrfs_directory/grub-btrfs.cfg.bkp" ]; then print_error "Syntax errors were detected in generated ${grub_btrfs_directory}/grub-btrfs.new file. Old grub-btrfs.cfg (if present) was not replaced."
mv -f "$grub_btrfs_directory/grub-btrfs.cfg.bkp" "$grub_btrfs_directory/grub-btrfs.cfg"
fi
print_error "Syntax errors were detected in generated ${grub_btrfs_directory}/grub-btrfs.new file. The old grub-btrfs.cfg file (if present) have been restored."
fi fi
# warn when this script is run but there is no entry in grub.cfg # warn when this script is run but there is no entry in grub.cfg
grep "snapshots-btrfs" "${grub_directory}/grub.cfg" >/dev/null 2>&1 || printf "\nWARNING: '%s' needs to run at least once to generate the snapshots (sub)menu entry in grub the main menu. \ grep "snapshots-btrfs" "${grub_directory}/grub.cfg" || printf "\nWARNING: '%s' needs to run at least once to generate the snapshots (sub)menu entry in grub the main menu. \
After that this script can run alone to generate the snapshot entries.\n\n" "${GRUB_BTRFS_MKCONFIG:-grub-mkconfig}" >&2 ; After that this script can run alone to generate the snapshot entries.\n\n" "${GRUB_BTRFS_MKCONFIG:-grub-mkconfig}" >&2 ;

View File

@@ -5,12 +5,6 @@ INITCPIO ?= false
SYSTEMD ?= true SYSTEMD ?= true
OPENRC ?= false OPENRC ?= false
BOOT_DIR_DEBIAN ?= /boot/grub
BOOT_DIR_FEDORA ?= /boot/grub2
GRUB_UPDATE_EXCLUDE ?= false
INSTALL_DOCS ?= true
SHARE_DIR = $(DESTDIR)$(PREFIX)/share SHARE_DIR = $(DESTDIR)$(PREFIX)/share
LIB_DIR = $(DESTDIR)$(PREFIX)/lib LIB_DIR = $(DESTDIR)$(PREFIX)/lib
BIN_DIR = $(DESTDIR)$(PREFIX)/bin BIN_DIR = $(DESTDIR)$(PREFIX)/bin
@@ -18,7 +12,6 @@ MAN_DIR = $(SHARE_DIR)/man
TEMP_DIR = ./temp TEMP_DIR = ./temp
.PHONY: install uninstall clean help .PHONY: install uninstall clean help
install: install:
@@ -38,18 +31,14 @@ install:
@echo @echo
@echo " For further information visit https://github.com/Antynea/grub-btrfs or read the man page: 'man grub-btrfs'" @echo " For further information visit https://github.com/Antynea/grub-btrfs or read the man page: 'man grub-btrfs'"
@echo @echo
@rm -rf "${TEMP_DIR}"
@mkdir "${TEMP_DIR}" @mkdir "${TEMP_DIR}"
@chmod 777 ${TEMP_DIR} @chmod 777 ${TEMP_DIR}
@cp manpages/grub-btrfs.8.man ${TEMP_DIR}/grub-btrfs.8 @cp manpages/grub-btrfs.8.man ${TEMP_DIR}/grub-btrfs.8
@if test "$(INSTALL_DOCS)" = true; then \ @bzip2 ${TEMP_DIR}/grub-btrfs.8
echo "Installing manpages..."; \ @install -Dm644 -t "${MAN_DIR}/man8" "${TEMP_DIR}/grub-btrfs.8.bz2"
install -Dm644 -t "${MAN_DIR}/man8" "${TEMP_DIR}/grub-btrfs.8"; \
fi
@cp manpages/grub-btrfsd.8.man ${TEMP_DIR}/grub-btrfsd.8 @cp manpages/grub-btrfsd.8.man ${TEMP_DIR}/grub-btrfsd.8
@if test "$(INSTALL_DOCS)" = true; then \ @bzip2 ${TEMP_DIR}/grub-btrfsd.8
install -Dm644 -t "${MAN_DIR}/man8" "${TEMP_DIR}/grub-btrfsd.8"; \ @install -Dm644 -t "${MAN_DIR}/man8" "${TEMP_DIR}/grub-btrfsd.8.bz2";
fi
@install -Dm755 -t "$(DESTDIR)/etc/grub.d/" 41_snapshots-btrfs @install -Dm755 -t "$(DESTDIR)/etc/grub.d/" 41_snapshots-btrfs
@install -Dm644 -t "$(DESTDIR)/etc/default/grub-btrfs/" config @install -Dm644 -t "$(DESTDIR)/etc/default/grub-btrfs/" config
@install -Dm744 -t "$(BIN_DIR)/" grub-btrfsd; @install -Dm744 -t "$(BIN_DIR)/" grub-btrfsd;
@@ -70,20 +59,10 @@ install:
install -Dm644 "initramfs/Arch Linux/overlay_snap_ro-install" "$(LIB_DIR)/initcpio/install/grub-btrfs-overlayfs"; \ install -Dm644 "initramfs/Arch Linux/overlay_snap_ro-install" "$(LIB_DIR)/initcpio/install/grub-btrfs-overlayfs"; \
install -Dm644 "initramfs/Arch Linux/overlay_snap_ro-hook" "$(LIB_DIR)/initcpio/hooks/grub-btrfs-overlayfs"; \ install -Dm644 "initramfs/Arch Linux/overlay_snap_ro-hook" "$(LIB_DIR)/initcpio/hooks/grub-btrfs-overlayfs"; \
fi fi
@if test "$(INSTALL_DOCS)" = true; then \ @install -Dm644 -t "$(SHARE_DIR)/licenses/$(PKGNAME)/" LICENSE
echo "Installing docs..."; \ @install -Dm644 -t "$(SHARE_DIR)/doc/$(PKGNAME)/" README.md
install -Dm644 -t "$(SHARE_DIR)/licenses/$(PKGNAME)/" LICENSE; \ @install -Dm644 "initramfs/readme.md" "$(SHARE_DIR)/doc/$(PKGNAME)/initramfs-overlayfs.md"
install -Dm644 -t "$(SHARE_DIR)/doc/$(PKGNAME)/" README.md; \ @rm -rf "${TEMP_DIR}"
install -Dm644 "initramfs/readme.md" "$(SHARE_DIR)/doc/$(PKGNAME)/initramfs-overlayfs.md"; \
fi
@if command -v grub-mkconfig > /dev/null && [ -e "$(BOOT_DIR_DEBIAN)/grub.cfg" ] && test "$(GRUB_UPDATE_EXCLUDE)" = false; then \
echo "Updating the GRUB menu..."; \
grub-mkconfig -o "$(BOOT_DIR_DEBIAN)/grub.cfg"; \
fi
@if command -v grub2-mkconfig > /dev/null && [ -e "$(BOOT_DIR_FEDORA)/grub.cfg" ] && test "$(GRUB_UPDATE_EXCLUDE)" = false; then \
echo "Updating the GRUB menu..."; \
grub2-mkconfig -o "$(BOOT_DIR_FEDORA)/grub.cfg"; \
fi
uninstall: uninstall:
@echo "Uninstalling grub-btrfs" @echo "Uninstalling grub-btrfs"
@@ -115,14 +94,6 @@ uninstall:
@rmdir --ignore-fail-on-non-empty "$(SHARE_DIR)/doc/$(PKGNAME)/" || : @rmdir --ignore-fail-on-non-empty "$(SHARE_DIR)/doc/$(PKGNAME)/" || :
@rmdir --ignore-fail-on-non-empty "$(SHARE_DIR)/licenses/$(PKGNAME)/" || : @rmdir --ignore-fail-on-non-empty "$(SHARE_DIR)/licenses/$(PKGNAME)/" || :
@rmdir --ignore-fail-on-non-empty "$(DESTDIR)/etc/default/grub-btrfs" || : @rmdir --ignore-fail-on-non-empty "$(DESTDIR)/etc/default/grub-btrfs" || :
@if command -v grub-mkconfig > /dev/null && [ -e "$(BOOT_DIR_DEBIAN)/grub.cfg" ] && test "$(GRUB_UPDATE_EXCLUDE)" = false; then \
echo "Updating the GRUB menu..."; \
grub-mkconfig -o "$(BOOT_DIR_DEBIAN)/grub.cfg"; \
fi
@if command -v grub2-mkconfig > /dev/null && [ -e "$(BOOT_DIR_FEDORA)/grub.cfg" ] && test "$(GRUB_UPDATE_EXCLUDE)" = false; then \
echo "Updating the GRUB menu..."; \
grub2-mkconfig -o "$(BOOT_DIR_FEDORA)/grub.cfg"; \
fi
clean: clean:
@echo "Deleting ./temp" @echo "Deleting ./temp"
@@ -137,17 +108,14 @@ help:
@echo " uninstall" @echo " uninstall"
@echo " help" @echo " help"
@echo @echo
@echo " parameter | type | description | defaults" @echo " parameter | type | description | defaults"
@echo " --------------------+------+-------------------------------------------------------+----------------------------" @echo " ----------+------+--------------------------------+----------------------------"
@echo " DESTDIR | path | install destination | <unset>" @echo " DESTDIR | path | install destination | <unset>"
@echo " PREFIX | path | system tree prefix | '/usr'" @echo " PREFIX | path | system tree prefix | '/usr'"
@echo " BOOT_DIR_DEBIAN | path | boot data location (Debian, Ubuntu, Gentoo, Arch...) | '/boot/grub'" @echo " SHARE_DIR | path | shared data location | '\$$(DESTDIR)\$$(PREFIX)/share'"
@echo " BOOT_DIR_FEDORA | path | boot data location (Fedora, RHEL, CentOS, Rocky...) | '/boot/grub2'" @echo " LIB_DIR | path | system libraries location | '\$$(DESTDIR)\$$(PREFIX)/lib'"
@echo " SHARE_DIR | path | shared data location | '\$$(DESTDIR)\$$(PREFIX)/share'" @echo " PKGNAME | name | name of the ditributed package | 'grub-btrfs'"
@echo " LIB_DIR | path | system libraries location | '\$$(DESTDIR)\$$(PREFIX)/lib'" @echo " INITCPIO | bool | include mkinitcpio hook | false"
@echo " PKGNAME | name | name of the distributed package | 'grub-btrfs'" @echo " SYSTEMD | bool | include unit files | true"
@echo " INITCPIO | bool | include mkinitcpio hook | false" @echo " OPENRC | bool | include OpenRc daemon | false"
@echo " SYSTEMD | bool | include unit files | true"
@echo " OPENRC | bool | include OpenRc daemon | false"
@echo " GRUB_UPDATE_EXCLUDE | bool | Do not update grub after installation | false"
@echo @echo

281
README.md
View File

@@ -6,32 +6,33 @@
##### BTC donation address: `1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt` ##### BTC donation address: `1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt`
- - - - - -
### 🔎 Description: ### 🔎 Description:
grub-btrfs improves the grub bootloader by adding a btrfs snapshots sub-menu, allowing the user to boot into snapshots. Improves grub by adding "btrfs snapshots" to the grub menu.
grub-btrfs supports manual snapshots as well as snapper, timeshift, and yabsnap created snapshots. You can boot your system on a "snapshot" from the grub menu.
Supports manual snapshots, snapper, timeshift ...
##### Warning: booting read-only snapshots can be tricky ##### Warning: booting on read-only snapshots can be tricky
If you wish to use read-only snapshots, `/var/log` or even `/var` must be on a separate subvolume. If you choose to do it, `/var/log` or even `/var` must be on a separate subvolume.
Otherwise, make sure your snapshots are writable. Otherwise, make sure your snapshots are writable.
See [this ticket](https://github.com/Antynea/grub-btrfs/issues/92) for more info. See [this ticket](https://github.com/Antynea/grub-btrfs/issues/92) for more info.
This project includes its own solution. This project includes its own solution.
Refer to the [documentation](https://github.com/Antynea/grub-btrfs/blob/master/initramfs/readme.md). Refer to the [documentation](https://github.com/Antynea/grub-btrfs/blob/master/initramfs/readme.md).
- - - - - -
### ✨ What features does grub-btrfs have? ### ✨ What features does grub-btrfs have?
* Automatically lists snapshots existing on the btrfs root partition. * Automatically list snapshots existing on root partition (btrfs).
* Automatically detect if `/boot` is in a separate partition. * Automatically detect if `/boot` is in separate partition.
* Automatically detect kernel, initramfs and Intel/AMD microcode in `/boot` directory within snapshots. * Automatically detect kernel, initramfs and Intel/AMD microcode in `/boot` directory on snapshots.
* Automatically create corresponding menu entries in `grub.cfg` * Automatically create corresponding "menuentry" in `grub.cfg`
* Automatically detect the type/tags/triggers and descriptions/comments of Snapper/Timeshift/Yabsnap snapshots. * Automatically detect the type/tags and descriptions/comments of Snapper/Timeshift snapshots.
* Automatically generate `grub.cfg` if you use the provided Systemd/ OpenRC service. * Automatically generate `grub.cfg` if you use the provided Systemd/ OpenRC service.
- - - - - -
### 🛠️ Installation: ### 🛠️ Installation:
#### Arch Linux #### Arch Linux
The package is available in the extra repository [grub-btrfs](https://archlinux.org/packages/extra/any/grub-btrfs/) The package is available in the community repository [grub-btrfs](https://archlinux.org/packages/community/any/grub-btrfs/)
``` ```
pacman -S grub-btrfs pacman -S grub-btrfs
``` ```
@@ -55,89 +56,118 @@ Emerge grub-btrfs via
``` ```
apt install grub-btrfs apt install grub-btrfs
``` ```
Booting into read-only snapshots is fully supported when choosing btrfs as the file system during a standard Kali Linux installation following [this walk-through](https://www.kali.org/docs/installation/btrfs/). Booting into read-only snapshots is fully supported when choosing "btrfs" as file system during a standard Kali Linux installation following [this walk-through](https://www.kali.org/docs/installation/btrfs/).
#### Manual installation #### Manual
* Run `make install` * Run `make install` or look into Makefile for instructions on where to put each file.
* Run `make help` to check what options are available. * Run `make help` to check what options are available.
* Dependencies: * Dependencies:
* [btrfs-progs](https://archlinux.org/packages/core/x86_64/btrfs-progs/) * [btrfs-progs](https://archlinux.org/packages/core/x86_64/btrfs-progs/)
* [grub](https://archlinux.org/packages/core/x86_64/grub/) * [grub](https://archlinux.org/packages/core/x86_64/grub/)
* [bash >4](https://archlinux.org/packages/core/x86_64/bash/) * [bash >4](https://archlinux.org/packages/core/x86_64/bash/)
* [gawk](https://archlinux.org/packages/core/x86_64/gawk/) * [gawk](https://archlinux.org/packages/core/x86_64/gawk/)
* (only when using the grub-btrfsd daemon)[inotify-tools](https://archlinux.org/packages/extra/x86_64/inotify-tools/) * (only when using the daemon)[inotify-tools](https://archlinux.org/packages/community/x86_64/inotify-tools/)
- - - - - -
### 📚 Manual usage of grub-btrfs ### 📚 Usage
To manually generate grub snapshot entries you can run `sudo /etc/grub.d/41_snapshots-btrfs` which updates `grub-btrfs.cfg`. You then need to regenerate the GRUB configuration by running one of the following commands: After installation the grub main menu needs to be generated to make a menuentry for the snapshots sub menu. Depending on the Linux distribution the commands for that are different:
* On **Arch Linux** or **Gentoo** use `grub-mkconfig -o /boot/grub/grub.cfg`. * On **Arch Linux** or **Gentoo** use `grub-mkconfig -o /boot/grub/grub.cfg`.
* On **Fedora** use `grub2-mkconfig -o /boot/grub2/grub.cfg` * On **Fedora** use `grub2-mkconfig -o /boot/grub2/grub.cfg`
* On **Debian and Ubuntu based** distributions `update-grub` is a script that runs `grub-mkconfig ...` * On **Debian-like** distribution `update-grub` is an alias to `grub-mkconfig ...`
This process can be automated to occur whenever you create or delete snapshots but this process is slightly different depending upon your distributions choice on init system. See the relevant instructions for your init system below. Once the entry for the sub menu was generated grub-btrfs puts the actual sub menu into the file grub-btrfs.cfg. So to generate snapshot entries in the sub menu it is usually enough to run only the script with `sudo /etc/grub.d/41_snapshots-btrfs`.
Read further below on how to automate this process.
### ⚙️ Customization: ### ⚙️ Customization:
You have the possibility to modify many parameters in `/etc/default/grub-btrfs/config`. You have the possibility to modify many parameters in `/etc/default/grub-btrfs/config`.
For further information see [config file](https://github.com/Antynea/grub-btrfs/blob/master/config) or `man grub-btrfs` For further information see [config file](https://github.com/Antynea/grub-btrfs/blob/master/config) or `man grub-btrfs`
#### Warning: #### Warning:
Some file locations and command names differ from distribution to distribution. Initially the configuration is set up to work with Arch and Gentoo (and many other distributions) out of the box, which are using the `grub-mkconfig` command. Some file locations and command names differ from distribution to distribution. Initially the configuration is set up to work with Arch and Gentoo (and many other distributions) out of the box, which are using the `grub-mkconfig` command.
However Fedora, for example, uses a different command, `grub2-mkconfig`. However, Fedora for example uses a different command, `grub2-mkconfig`.
Edit the `GRUB_BTRFS_MKCONFIG` variable in `/etc/default/grub-btrfs/config` file to reflect this. (e.g. `GRUB_BTRFS_MKCONFIG=/sbin/grub2-mkconfig` for Fedora) Edit `GRUB_BTRFS_MKCONFIG` variable in `/etc/default/grub-btrfs/config` file to reflect this. (e.g. `GRUB_BTRFS_MKCONFIG=/sbin/grub2-mkconfig` for Fedora)
On most distributions, the grub installation resides in `/boot/grub`. If grub is installed in a different place, change the variable `GRUB_BTRFS_MKCONFIG` in the config file accordingly. For Fedora this is `GRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"`. The command to check the grub scripts is different on some system, for Fedora it is `GRUB_BTRFS_SCRIPT_CHECK=grub2-script-check` On most distributions and installs, the grub installation resides in `/boot/grub`. If grub is installed in a different place, change the variable `GRUB_BTRFS_MKCONFIG` in the config file accordingly. For Fedora this is `GRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"`. Also the command to check the grub scripts is different on some system, for Fedora it is `GRUB_BTRFS_SCRIPT_CHECK=grub2-script-check`
#### Customization of the grub-btrfsd daemon #### Customization of the grub-btrfsd daemon
Grub-btrfs comes with a daemon script that automatically updates the grub menu when it sees a snapshot being created or deleted in a directory it is given via command line. You must install `inotify-tools` before you can use grub-btrfsd. Grub-btrfs comes with a daemon script that automatically updates the grub menu when it sees a snapshot being created or deleted in a directory it is given via command line.
The daemon can be configured by passing different command line arguments to it. The daemon can be configured by passing different command line arguments to it.
The available arguments are: The arguments are:
* `SNAPSHOTS_DIRS` * `SNAPSHOTS_DIR`
This argument specifies the (space separated) paths where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots. This argument specifies the path where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots.
E.g. for Snapper or Yabsnap this would be `/.snapshots`. It is possible to define more than one directory here, all directories will inherit the same settings (recursive etc.). E.g. for Snapper this would be `/.snapshots`
This argument is not necessary to provide if `--timeshift-auto` is set.
* `-c / --no-color` * `-c / --no-color`
Disable colors in output. Disable colors in output.
* `-l / --log-file` * `-l / --log-file`
This arguments specifies a file where grub-btrfsd should write log messages. This arguments specifies a file where grub-btrfsd should write log messages.
* `-r / --recursive`
Watch the snapshots directory recursively
* `-s / --syslog` * `-s / --syslog`
* `-o / --timeshift-old`
Look for snapshots in `/run/timeshift/backup/timeshift-btrfs` instead of `/run/timeshift/$PID/backup/timeshift-btrfs.` This is to be used for Timeshift versions <22.06. You must also use `--timeshift-auto` if using this option.
* `-t / --timeshift-auto` * `-t / --timeshift-auto`
This is a flag to activate the auto-detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to `/run/timeshift/$PID/backup/timeshift-btrfs`. Where `$PID` is the process ID of the currently running Timeshift session. The PID changes every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument `SNAPSHOTS_DIRS` has no effect. This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to `/run/timeshift/$PID/backup/timeshift-btrfs`. Where `$PID` is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument `SNAPSHOTS_DIR` has no effect.
* `-v / --verbose` * `-v / --verbose`
Let the log of the daemon be more verbose Let the log of the daemon be more verbose
* `-h / --help` * `-h / --help`
Displays a short help message. Displays a short help message.
- - - - - -
### 🪀 Automatically update grub upon snapshot creation or deletion ##### Systemd instructions
Grub-btrfsd is a daemon that watches the snapshot directory for you and updates the grub menu automatically every time a snapshot is created or deleted. To edit the arguments that are passed to the daemon, use
By default this daemon watches the directory `/.snapshots` for changes (creation or deletion of snapshots) and triggers the grub menu creation and re-installation of grub if any changes are noticed. ```bash
Therefore, if Snapper or Yabsnap is used with its default directory, the daemon can just be started and nothing needs to be configured. See the instructions below to configure grub-btrfsd for use with Timeshift or when using an alternative snapshots directory with Snapper/Yabsnap. sudo systemctl edit --full grub-btrfsd
```
after that the Daemon must be restarted with
```bash
sudo systemctl restart grub-btrfsd
```
It is also possible to start the daemon without using systemd for troubleshooting purposes for example. If you want to do this, a running daemon should be stopped with
```bash
sudo systemctl stop grub-btrfsd
```
Then the daemon can be manually run and played around with using the command `/usr/bin/grub-btrfsd`.
For additional information on the daemon script and its arguments, run `grub-btrfsd -h` and see `man grub-btrfsd`
- - -
##### OpenRC instructions
To edit the arguments that are passed to the daemon edit the file `/etc/conf.d/grub-btrfsd`.
After that restart the daemon with
```
sudo rc-service grub-btrfsd restart
```
It is also possible to start the daemon without using OpenRC for troubleshooting purposes for example. If you want to do this, a running daemon should be stopped with
```bash
sudo rc-service grub-btrfsd stop
```
Then the daemon can be manually run and played around with using the command `grub-btrfsd`.
For additional information on daemon script and its arguments, run `grub-btrfsd -h` and see `man grub-btrfsd`
- - - - - -
#### grub-btrfsd systemd instructions ### 🪀 Automatically update grub upon snapshot
To start the daemon run: Grub-btrfsd is a daemon daemon that watches the snapshot directory for you and updates the grub menu automatically every time a snapshot is created or deleted.
By default this daemon watches the directory `/.snapshots` for changes (creation or deletion of snapshots) and triggers the grub menu creation if a snapshot is found.
Therefore, if Snapper is used with its default directory, the daemon can just be started and nothing needs to be configured. For other configurations like Timeshift, or Snapper with a different directory, see further below.
- - -
#### SystemD instructions
To start the daemon run
```bash ```bash
sudo systemctl start grub-btrfsd sudo systemctl start grub-btrfsd
``` ```
To activate it during system startup, run: To activate it during system startup, run
```bash ```bash
sudo systemctl enable grub-btrfsd sudo systemctl enable grub-btrfsd
``` ```
##### 💼 Snapshots not in `/.snapshots` when using systemd ##### 💼 Snapshots not in `/.snapshots`
By default the daemon is watching the directory `/.snapshots`. If the daemon should watch a different directory, it can be edited with: NOTE: This works also for Timeshift versions < 22.06, the path to watch would be `/run/timeshift/backup/timeshift-btrfs/snapshots`.
By default the daemon is watching the directory `/.snapshots`. If the daemon should watch a different directory, it can be edited with
```bash ```bash
sudo systemctl edit --full grub-btrfsd sudo systemctl edit --full grub-btrfsd
``` ```
You need to edit the `/.snapshots` part in the line that says `ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots`. What should be edited is the `/.snapshots`-part in the line that says `ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots`.
This is what the file should look like afterwards: So this is what the file should look afterwards:
``` bash ``` bash
[Unit] [Unit]
Description=Regenerate grub-btrfs.cfg Description=Regenerate grub-btrfs.cfg
@@ -150,47 +180,46 @@ Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin"
# Load environment variables from the configuration # Load environment variables from the configuration
EnvironmentFile=/etc/default/grub-btrfs/config EnvironmentFile=/etc/default/grub-btrfs/config
# Start the daemon, usage of it is: # Start the daemon, usage of it is:
# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIRS # grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR
# SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto # SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto
# Optional arguments: # Optional arguments:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory
# -o, --timeshift-old Activate for timeshift versions <22.06
# -l, --log-file Specify a logfile to write to # -l, --log-file Specify a logfile to write to
# -v, --verbose Let the log of the daemon be more verbose # -v, --verbose Let the log of the daemon be more verbose
# -s, --syslog Write to syslog # -s, --syslog Write to syslog
ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots ExecStart=/usr/bin/grub-btrfsd --syslog /path/to/your/snapshot/directory
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
When done, the service should be restarted with: When done, the service should be restarted with
``` bash ``` bash
sudo systemctl restart grub-btrfsd sudo systemctl restart grub-btrfsd
``` ```
##### 🌟 Using Timeshift with systemd ##### 🌟 Timeshift >= version 22.06
Newer Timeshift versions (>= 22.06) create a new directory named after their process ID in `/run/timeshift` every time they are started. The PID will be different every time. Newer Timeshift versions create a new directory named after their process ID in `/run/timeshift` every time they are started. The PID is going to be different every time.
Therefore the daemon cannot simply watch a directory. It monitors `/run/timeshift` and if a directory is created it gets Timeshifts current PID then watches a directory in that newly created directory from Timeshift. Therefore the daemon can not simply watch a directory, it watches `/run/timeshift` first, if a directory is created it gets Timeshifts current PID, then watches a directory in that newly created directory from Timeshift.
To activate this mode of the daemon, `--timeshift-auto` must be passed to the daemon as a command line argument. Anyhow, to activate this mode of the daemon, `--timeshift-auto` must be passed to the daemon as a command line argument.
To pass `--timeshift-auto` to grub-btrfsd, the .service file of grub-btrfsd can be edited with To pass `--timeshift-auto` to grub-btrfsd, the .service-file of grub-btrfsd can be edited with
```bash ```bash
sudo systemctl edit --full grub-btrfsd sudo systemctl edit --full grub-btrfsd
``` ```
The line that contains: The line that says
```bash ```bash
ExecStart=/usr/bin/grub-btrfsd /.snapshots --syslog ExecStart=/usr/bin/grub-btrfsd /.snapshots --syslog
``` ```
Should be modified to read: should be edited into
``` bash ``` bash
ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto
``` ```
The modified file should look like this: So the file looks like this, afterwards:
``` bash ``` bash
[Unit] [Unit]
Description=Regenerate grub-btrfs.cfg Description=Regenerate grub-btrfs.cfg
@@ -203,8 +232,8 @@ Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin"
# Load environment variables from the configuration # Load environment variables from the configuration
EnvironmentFile=/etc/default/grub-btrfs/config EnvironmentFile=/etc/default/grub-btrfs/config
# Start the daemon, usage of it is: # Start the daemon, usage of it is:
# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIRS # grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR
# SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto # SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto
# Optional arguments: # Optional arguments:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory
# -l, --log-file Specify a logfile to write to # -l, --log-file Specify a logfile to write to
@@ -216,13 +245,7 @@ ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
If you are using an older release of Timeshift (before 22.06), you also need to add `--timeshift-old` so that your ExecStart line would look like: When done, the service must be restarted with
```
ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto --timeshift-old
```
When done, the service must be restarted with:
``` bash ``` bash
sudo systemctl restart grub-btrfsd sudo systemctl restart grub-btrfsd
``` ```
@@ -231,59 +254,116 @@ Note:
You can view your change with `systemctl cat grub-btrfsd`. You can view your change with `systemctl cat grub-btrfsd`.
To revert all the changes use `systemctl revert grub-btrfsd`. To revert all the changes use `systemctl revert grub-btrfsd`.
##### ❇️ Automatically update grub upon restart/boot:
[Look at this comment](https://github.com/Antynea/grub-btrfs/issues/138#issuecomment-766918328)
Currently not implemented
- - - - - -
#### grub-btrfsd OpenRC instructions #### OpenRC instructions
To start the daemon run: To start the daemon run
```bash ```bash
sudo rc-service grub-btrfsd start sudo rc-service grub-btrfsd start
``` ```
To activate it during system startup, run: To activate it during system startup, run
```bash ```bash
sudo rc-config add grub-btrfsd default sudo rc-config add grub-btrfsd default
``` ```
##### 💼 Snapshots not in `/.snapshots` for OpenRC ##### 💼 Snapshots not in `/.snapshots`
NOTE: This works also for Timeshift versions < 22.06, the path to watch would be `/run/timeshift/backup/timeshift-btrfs/snapshots`.
By default the daemon is watching the directory `/.snapshots`. If the daemon should watch a different directory, it can be edited by passing different arguments to it. By default the daemon is watching the directory `/.snapshots`. If the daemon should watch a different directory, it can be edited by passing different arguments to it.
Arguments are passed to grub-btrfsd via the file `/etc/conf.d/grub-btrfsd`. Arguments are passed to grub-btrfsd via the file `/etc/conf.d/grub-btrfsd`.
The variable `snapshots` defines the path the daemon will monitor for snapshots. The variable `snapshots` defines, where the daemon will watch for snapshots.
After editing, the file should look like this: After editing, the file should look like this:
``` bash ``` bash
# Copyright 2022 Pascal Jaeger # Copyright 2022 Pascal Jaeger
# Distributed under the terms of the GNU General Public License v3 # Distributed under the terms of the GNU General Public License v3
## Where to locate the root snapshots
#snapshots="/.snapshots" # Snapper in the root directory
#snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06
snapshots="/path/to/your/snapshot/directory"
## Optional arguments to run with the daemon
# Possible options are:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06
# -l, --log-file Specify a logfile to write to
# -v, --verbose Let the log of the daemon be more verbose
# -s, --syslog Write to syslog
# Uncomment the line to activate the option
optional_args+="--syslog " # write to syslog by default
#optional_args+="--timeshift-auto "
#optional_args+="--log-file /var/log/grub-btrfsd.log "
#optional_args+="--verbose "
```
After that, the daemon should be restarted with
``` bash
sudo rc-service grub-btrfsd restart
```
##### 🌟 Timeshift >= version 22.06
Arguments are passed to grub-btrfsd via the file `/etc/conf.d/grub-btrfsd`.
The variable `optional_args` defines, which optional arguments get passed to the daemon.
Uncomment `#optional_args+="--timeshift-auto "` to pass the command line option `--timeshift-auto` to it.
After the change, the file should look like this:
(Note that there is no need to comment out the `snapshots` variable. It is ignored when `--timeshift-auto` is active.)
``` bash
# Copyright 2022 Pascal Jaeger
# Distributed under the terms of the GNU General Public License v3
## Where to locate the root snapshots ## Where to locate the root snapshots
snapshots="/.snapshots" # Snapper in the root directory snapshots="/.snapshots" # Snapper in the root directory
#snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06 #snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06
## Optional arguments to run with the daemon ## Optional arguments to run with the daemon
# Append options to this like this:
# optional_args="--syslog --timeshift-auto --verbose"
# Possible options are: # Possible options are:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06 # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06
# -o, --timeshift-old Look for snapshots in directory of Timeshift <v22.06 (requires --timeshift-auto)
# -l, --log-file Specify a logfile to write to # -l, --log-file Specify a logfile to write to
# -v, --verbose Let the log of the daemon be more verbose # -v, --verbose Let the log of the daemon be more verbose
# -s, --syslog Write to syslog # -s, --syslog Write to syslog
optional_args="--syslog" # Uncomment the line to activate the option
optional_args+="--syslog " # write to syslog by default
optional_args+="--timeshift-auto "
#optional_args+="--log-file /var/log/grub-btrfsd.log "
#optional_args+="--verbose "
``` ```
After that, the daemon should be restarted with: After that, the daemon should be restarted with
``` bash ``` bash
sudo rc-service grub-btrfsd restart sudo rc-service grub-btrfsd restart
``` ```
##### 🔒 Snapshots on LUKS encrypted devices ##### ❇️ Automatically update grub upon restart/boot:
By default, grub-btrfs generates entries that does not load modules for dealing with encrypted devices. If you would like the grub-btrfs menu to automatically update on system restart/ shutdown, just add the following script as `/etc/local.d/grub-btrfs-update.stop`:
Enable the `GRUB_BTRFS_ENABLE_CRYPTODISK` variable in `/etc/default/grub-btrfs/config` to load said modules and then execute the steps to mount encrypted root after selecting the snapshot. ```bash
#!/usr/bin/env bash
description="Update the grub btrfs snapshots menu"
name="grub-btrfs-update"
depend()
{
use localmount
}
bash -c 'if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then /etc/grub.d/41_snapshots-btrfs; else {GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o {GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; fi'
```
Make your script executable with `sudo chmod a+x /etc/local.d/grub-btrfs-update.stop`.
* The extension `.stop` at the end of the filename indicates to the locald-daemon that this script should be run at shutdown.
If you want to run the menu update on system startup instead, rename the file to `grub-btrfs-update.start`
* Works for Snapper and Timeshift
- - - - - -
### Troubleshooting ### Troubleshooting
If you experience problems with grub-btrfs don't hesitate [to file an issue](https://github.com/Antynea/grub-btrfs/issues/new/choose). If there are problems don't hesitate [to file an issue](https://github.com/Antynea/grub-btrfs/issues/new/choose).
#### What version of grub-btrfs am I running? #### Version
When requesting help or reporting bugs in grub-btrfs, please run: To help the best we would like to know the version of grub-btrfs used. Please run
``` bash ``` bash
sudo /etc/grub.d/41_snapshots-btrfs --version sudo /etc/grub.d/41_snapshots-btrfs --version
``` ```
@@ -291,37 +371,18 @@ or
``` bash ``` bash
sudo /usr/bin/grub-btrfsd --help sudo /usr/bin/grub-btrfsd --help
``` ```
to get the currently running version of grub-btrfs and include this information in your ticket. to get the currently running version of grub-btrfs.
#### Running grub-btrfsd in verbose mode #### Verbose mode of the daemon
If you have problems with the daemon, you can run it with the `--verbose`-flag. To do so you can run: If you have problems with the daemon, you can run it with the `--verbose`-flag. To do so you can run
``` bash ``` bash
sudo /usr/bin/grub-btrfsd --verbose --timeshift-auto` (for timeshift) sudo /usr/bin/grub-btrfsd --verbose --timeshift-auto` (for timeshift)
# or # or
sudo /usr/bin/grub-btrfsd /.snapshots --verbose` (for snapper/yabsnap) sudo /usr/bin/grub-btrfsd /.snapshots --verbose` (for snapper)
``` ```
Or pass `--verbose` to the daemon using the Systemd .service file or the OpenRC conf.d file respectively. Or pass `--verbose` to the daemon using the Systemd .service-file or the OpenRC conf.d file respectively. (see Daemon installation instructions how to do that)
For additional information on the daemon and its arguments, run `grub-btrfsd -h` or `man grub-btrfsd`
- - - - - -
### Development
Grub-btrfs uses a rudimentary system of automatic versioning to tell apart different commits. This is helpful when users report problems and it is not immediately clear what version they are using.
We therefore have the following script in `.git/hooks/pre-commit`:
``` bash
#!/bin/sh
echo "Doing pre commit hook with version bump"
version="$(git describe --tags --abbrev=0)-$(git rev-parse --abbrev-ref HEAD)-$(date -u -Iseconds)"
echo "New version is ${version}"
sed -i "s/GRUB_BTRFS_VERSION=.*/GRUB_BTRFS_VERSION=${version}/" config
git add config
```
This automatically sets the version in the `config`-file to `[lasttag]-[branch-name]-[current-date-in-UTC]`.
In order to create a Tag we don't want to have this long version. In this case we set the version manually in `config` and commit with `git commit --no-verify`. This avoids running the hook.
### Special thanks for assistance and contributions ### Special thanks for assistance and contributions
* [Maxim Baz](https://github.com/maximbaz) * [Maxim Baz](https://github.com/maximbaz)
* [Schievel1](https://github.com/Antynea/grub-btrfs/discussions/173#discussioncomment-1438790) * [Schievel1](https://github.com/Antynea/grub-btrfs/discussions/173#discussioncomment-1438790)

30
config
View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
GRUB_BTRFS_VERSION=4.12-make-prefix-configurable-2022-11-26T14:14:00+00:00
GRUB_BTRFS_VERSION=4.13-yabsnap_info_support-2024-03-06T13:43:57+00:00
# Disable grub-btrfs. # Disable grub-btrfs.
# Default: "false" # Default: "false"
@@ -49,14 +48,7 @@ GRUB_BTRFS_VERSION=4.13-yabsnap_info_support-2024-03-06T13:43:57+00:00
# Default: ("") # Default: ("")
#GRUB_BTRFS_CUSTOM_MICROCODE=("custom-ucode.img" "custom-uc.img "custom_ucode.cpio") #GRUB_BTRFS_CUSTOM_MICROCODE=("custom-ucode.img" "custom-uc.img "custom_ucode.cpio")
# Additional kernel command line parameters that should be passed to the kernel # Comma seperated mount options to be used when booting a snapshot.
# when booting a snapshot.
# For dracut based distros this could be useful to pass "rd.live.overlay.overlayfs=1"
# or "rd.live.overlay.readonly=1" to the Kernel for booting snapshots read only.
# Default: ""
#GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="rd.live.overlay.overlayfs=1"
# Comma separated mount options to be used when booting a snapshot.
# They can be defined here as well as in the "/" line inside the respective snapshots' # They can be defined here as well as in the "/" line inside the respective snapshots'
# "/etc/fstab" files. Mount options found in both places are combined, and this variable # "/etc/fstab" files. Mount options found in both places are combined, and this variable
# takes priority over `fstab` entries. # takes priority over `fstab` entries.
@@ -74,15 +66,13 @@ GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("@")
# Any path starting with the specified string will be ignored. # Any path starting with the specified string will be ignored.
# e.g : if `prefix path` = @, all snapshots beginning with "@/..." will be ignored. # e.g : if `prefix path` = @, all snapshots beginning with "@/..." will be ignored.
# Default: ("var/lib/docker" "@var/lib/docker" "@/var/lib/docker") # Default: ("var/lib/docker" "@var/lib/docker" "@/var/lib/docker")
GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/docker" "var/lib/containers" "@var/lib/containers" "@/var/lib/containers") GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/docker")
# Ignore specific type/tag of snapshot during run "grub-mkconfig". # Ignore specific type/tag of snapshot during run "grub-mkconfig".
# For snapper: # For snapper:
# Type = single, pre, post. # Type = single, pre, post.
# For Timeshift: # For Timeshift:
# Tag = boot, ondemand, hourly, daily, weekly, monthly. # Tag = boot, ondemand, hourly, daily, weekly, monthly.
# For yabsnap:
# Trigger = S, I, U.
# Default: ("") # Default: ("")
#GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE=("") #GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE=("")
@@ -98,7 +88,9 @@ GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/doc
#GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true" #GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"
# Location of the folder containing the "grub.cfg" file. # Location of the folder containing the "grub.cfg" file.
# Use by grub-btrfs to save the file "grub-btrfs.cfg".
# Might be grub2 on some systems. # Might be grub2 on some systems.
# For example, on Fedora with EFI : "/boot/efi/EFI/fedora"
# Default: "/boot/grub" # Default: "/boot/grub"
#GRUB_BTRFS_GRUB_DIRNAME="/boot/grub2" #GRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"
@@ -108,15 +100,15 @@ GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/doc
#GRUB_BTRFS_BOOT_DIRNAME="/boot" #GRUB_BTRFS_BOOT_DIRNAME="/boot"
# Location where grub-btrfs.cfg should be saved. # Location where grub-btrfs.cfg should be saved.
# Some distributions (like OpenSuSE) store those files at the snapshot directory # Some distributions (like OpenSuSE) store those file at the snapshot directory
# instead of boot. Be aware that this directory must be available for grub during # instead of boot. Be aware that this direcory must be available for grub during
# startup of the system. # startup of the system.
# Default: $GRUB_BTRFS_GRUB_DIRNAME # Default: "/boot/grub"
#GRUB_BTRFS_GBTRFS_DIRNAME="/boot/grub" #GRUB_BTRFS_GBTRFS_DIRNAME="/boot/grub"
# Location of the directory where Grub searches for the grub-btrfs.cfg file. # Location of the directory where Grub searches for the grub-btrfs.cfg file.
# Some distributions (like OpenSuSE) store those file at the snapshot directory # Some distributions (like OpenSuSE) store those file at the snapshot directory
# instead of boot. Be aware that this directory must be available for grub during # instead of boot. Be aware that this direcory must be available for grub during
# startup of the system. # startup of the system.
# Default: "\${prefix}" # This is a grub variable that resolves to where grub is # Default: "\${prefix}" # This is a grub variable that resolves to where grub is
# installed. (like /boot/grub, /boot/efi/grub) # installed. (like /boot/grub, /boot/efi/grub)
@@ -158,7 +150,3 @@ GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/doc
# doesn't work if GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS isn't empty # doesn't work if GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS isn't empty
# Default: "false" # Default: "false"
#GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU="true" #GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU="true"
# Enable booting from snapshots stored on LUKS encrypted devices
# Default: "false"
#GRUB_BTRFS_ENABLE_CRYPTODISK="true"

View File

@@ -1,15 +1,16 @@
#!/usr/bin/env bash #!/bin/sh
# Copyright 2023 Pascal Jaeger # Copyright 2022 Pascal Jaeger
# Distributed under the terms of the GNU General Public License v3 # Distributed under the terms of the GNU General Public License v3
# Update GRUB when new BTRFS snapshots are created. # Update GRUB when new BTRFS snapshots are created.
sighandler() { # init
trap '""' SIGINT SIGTERM timeshift_pid=-1
vlog "Parent $$: Received signal SIGINT/ SIGTERM" watchtime=0
kill 0 logfile=0
wait snapshots=-1
exit 0 timeshift_auto=false
} verbose=false
syslog=false
setcolors() { setcolors() {
if [ "${1}" = true ]; then if [ "${1}" = true ]; then
@@ -19,322 +20,239 @@ setcolors() {
RESET=$'\033[0m' RESET=$'\033[0m'
fi fi
if [ "${1}" = false ]; then if [ "${1}" = false ]; then
GREEN=$'\033[0;0m' GREEN=$'\033[0;0m'
RED=$'\033[0;0m' RED=$'\033[0;0m'
CYAN=$'\033[;0m' CYAN=$'\033[;0m'
RESET=$'\033[0m' RESET=$'\033[0m'
fi fi
} }
setcolors true # normally we want colors
sysconfdir="/etc"
grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config"
# source config file
[[ -f "$grub_btrfs_config" ]] && . "$grub_btrfs_config"
[[ -f "${sysconfdir}/default/grub" ]] && . "${sysconfdir}/default/grub"
print_help() { print_help() {
echo "${CYAN}[?] Usage:" echo "${CYAN}[?] Usage:"
echo "${0##*/} [-h, --help] [-c, --no-color] [-l, --log-file LOG_FILE] [-r, --recursive] [-s, --syslog] [-t, --timeshift-auto] [-v, --verbose] SNAPSHOTS_DIRS" echo "${0##*/} [-h, --help] [-c, --no-color] [-l, --log-file LOG_FILE] [-s, --syslog] [-t, --timeshift-auto] [-v, --verbose] SNAPSHOTS_DIR"
echo echo
echo "SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto" echo "SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto"
echo echo
echo "Optional arguments:" echo "Optional arguments:"
echo "-c, --no-color Disable colors in output" echo "-c, --no-color Disable colors in output"
echo "-l, --log-file Specify a logfile to write to" echo "-l, --log-file Specify a logfile to write to"
echo "-r, --recursive Watch snapshots directory recursively" echo "-s, --syslog Write to syslog"
echo "-s, --syslog Write to syslog" echo "-t, --timeshift-auto Automatically detect Timeshifts snapshot directory"
echo "-o, --timeshift-old Look for snapshots in directory of Timeshift <v22.06 (requires --timeshift-auto)" echo "-v, --verbose Let the log of the daemon be more verbose"
echo "-t, --timeshift-auto Automatically detect Timeshifts snapshot directory" echo "-h, --help Display this message"
echo "-v, --verbose Let the log of the daemon be more verbose" echo
echo "-h, --help Display this message" echo "Version ${GRUB_BTRFS_VERSION}${RESET}"
echo
echo "Version ${GRUB_BTRFS_VERSION}${RESET}"
} }
log() { log() {
echo "${2}"$1"${RESET}" echo "${2}"$1"${RESET}"
if [ ${syslog} = true ]; then if [ ${syslog} = true ]; then
logger -p user.notice -t ${0##*/}"["$$"]" "$1" logger -p user.notice -t ${0##*/}"["$$"]" "$1"
fi fi
if [ ${#logfile} -gt 1 ]; then if [ ${#logfile} -gt 1 ]; then
echo "$(date) ${1}" >> "${logfile}" echo "$(date) ${1}" >> ${logfile}
fi fi
} }
vlog() { vlog() {
if [ ${verbose} = true ]; then if [ ${verbose} = true ]; then
echo "${2}"$1"${RESET}" echo "${2}"$1"${RESET}"
if [ ${syslog} = true ]; then if [ ${syslog} = true ]; then
logger -p user.notice -t ${0##*/} "$1" logger -p user.notice -t ${0##*/} "$1"
fi fi
if [ ${#logfile} -gt 1 ]; then if [ ${#logfile} -gt 1 ]; then
echo "$(date) ${1}" >> "${logfile}" echo "$(date) ${1}" >> ${logfile}
fi fi
fi fi
} }
err() { err() {
echo "${2}"${1}"${RESET}" >&2 echo "${2}"${1}"${RESET}" >&2
if [ ${syslog} = true ]; then if [ ${syslog} = true ]; then
logger -p user.error -t ${0##*/} "$1" logger -p user.error -t ${0##*/} "$1"
fi fi
if [ ${#logfile} -gt 1 ]; then if [ ${#logfile} -gt 1 ]; then
echo "$(date) error: ${1}" >> "${logfile}" echo "$(date) error: ${1}" >> ${logfile}
fi fi
} }
parse_arguments() { # parse arguments
while getopts :l:ctvrsh-: opt; do while getopts :l:ctvsh-: opt; do
case "$opt" in case "$opt" in
-) -)
case "${OPTARG}" in case "${OPTARG}" in
no-color) no-color)
setcolors false
;;
log-file)
logfile="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
;;
timeshift-auto)
timeshift_auto=true
;;
timeshift-old)
timeshift_old=true
;;
verbose)
verbose=true
;;
recursive)
recursive=true
;;
syslog)
syslog=true
;;
help)
print_help
exit 0
;;
*)
if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then
err "[!] Unknown option --${OPTARG}" "${RED}" >&2
echo
fi
print_help
exit 1
;;
esac;;
c)
setcolors false setcolors false
;; ;;
l) log-file)
logfile="${OPTARG}" logfile="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 ))
;; ;;
t) timeshift-auto)
timeshift_auto=true timeshift_auto=true
;; ;;
o) verbose)
timeshift_old=true
;;
v)
verbose=true verbose=true
;; ;;
r) syslog)
recursive=true
;;
s)
syslog=true syslog=true
;; ;;
h) help)
print_help print_help
exit 0 exit 0
;; ;;
*) *)
if [ "$OPTERR" = 1 ] || [ "${optspec:0:1}" = ":" ]; then if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then
err "[!] Non-option argument: '-${OPTARG}'" "${RED}" >&2 err "[!] Unknown option --${OPTARG}" "${RED}" >&2
echo echo
fi fi
print_help print_help
exit 1 exit 1
;; ;;
esac esac;;
done c)
} setcolors false
;;
l)
logfile="${OPTARG}"
;;
t)
timeshift_auto=true
;;
v)
verbose=true
;;
s)
syslog=true
;;
h)
print_help
exit 0
;;
*)
if [ "$OPTERR" = 1 ] || [ "${optspec:0:1}" = ":" ]; then
err "[!] Non-option argument: '-${OPTARG}'" "${RED}" >&2
echo
fi
print_help
exit 1
;;
esac
done
shift $(( OPTIND - 1 ))
checks() { snapshots="${1}"
# check if inotify exists, see issue #227
if ! command -v inotifywait >/dev/null 2>&1; then
err "[!] inotifywait was not found, exiting. Is inotify-tools installed?" "${RED}" >&2
exit 1
fi
if [ ${timeshift_auto} = false ] && [ ${timeshift_old} = true ]; then # check if inotify exists, see issue #227
err "[!] Flag --timeshift-old requires flag --timeshift-auto" "${RED}" >&2 if ! command -v inotifywait &> /dev/null; then
exit 1 err "[!] inotifywait was not found, exiting. Is inotify-tools installed?" "${RED}" >&2
fi exit 1
fi
if ! [ ${timeshift_auto} = true ]; then if [ ${#logfile} -gt 1 ]; then
for snapdir in "${snapdirs[@]}" touch "${logfile}"
do echo "GRUB-BTRFSD log $(date)" >> "${logfile}"
if ! [ -d ${snapdir} ]; then fi
err "[!] No directory found at ${snapdir}" "${RED}" >&2
err "[!] Please specify a valid snapshot directory" "${RED}" >&2
exit 1
fi
done
fi
}
setup() { log "grub-btrfsd starting up..." "${GREEN}"
if [ ${#logfile} -gt 1 ]; then
touch "${logfile}"
echo "GRUB-BTRFSD log $(date)" >> "${logfile}"
fi
if [ ${verbose} = true ]; then if [ ${verbose} = true ]; then
inotify_qiet_flag="" inotify_qiet_flag=""
else else
inotify_qiet_flag=" -q -q " inotify_qiet_flag=" -q -q "
fi fi
if [ ${recursive} = true ]; then vlog "Arguments:"
inotify_recursive_flag=" -r " vlog "Snapshot directory: $snapshots"
else vlog "Timestift autodetection: $timeshift_auto"
inotify_recursive_flag="" vlog "Logfile: $logfile"
fi
if [ ${timeshift_auto} = true ]; then if ! [ -d "$snapshots" ] && ! [ ${timeshift_auto} = true ]; then
watchtime=15 err "[!] No directory found at ${snapshots}" "${RED}" >&2
[ -d /run/timeshift ] || mkdir /run/timeshift err "[!] Please specify a valid snapshot directory" "${RED}" >&2
else exit 1
watchtime=0 fi
fi
} if [ ${timeshift_auto} = true ]; then
watchtime=15
[ -d /run/timeshift ] || mkdir /run/timeshift
else
watchtime=0
fi
create_grub_menu() { create_grub_menu() {
# create the grub submenu of the whole grub menu, depending on whether the submenu already exists # create the grub submenu of the whole grub menu, depending on wether the submenu already exists
# and gives feedback if it worked # and gives feedback if it worked
if grep "snapshots-btrfs" "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}"/grub.cfg; then if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then
if /etc/grub.d/41_snapshots-btrfs; then if /etc/grub.d/41_snapshots-btrfs; then
log "Grub submenu recreated" "${GREEN}" log "Grub submenu recreated" "${GREEN}"
else else
err "[!] Error during grub submenu creation (grub-btrfs error)" "${RED}" err "[!] Error during grub submenu creation (grub-btrfs error)" "${RED}"
fi fi
else else
if ${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}"/grub.cfg; then if ${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o ${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; then
log "Grub menu recreated" "${GREEN}" log "Grub menu recreated" "${GREEN}"
else else
err "[!] Error during grub menu creation (grub/ grub-btrfs error)" "${RED}" err "[!] Error during grub menu creation (grub/ grub-btrfs error)" "${RED}"
fi fi
fi fi
} }
set_snapshot_dir() { # start the actual daemon
# old timeshift has it's snapshot dir in a different location vlog "Snapshot dir watchtimeout: $watchtime"
if [ "${timeshift_old}" = true ]; then vlog "Entering infinite while" "${GREEN}"
snapdir="/run/timeshift/backup/timeshift-btrfs/snapshots" while true; do
runs=false
if [ ${timeshift_auto} = true ] && ! [ "${timeshift_pid}" -gt 0 ] ; then
# watch the timeshift folder for a folder that is created when timeshift starts up
sleep 1 # for safety so the outer while is not going crazy
if [ "${timeshift_pid}" -eq -2 ]; then
log "detected timeshift shutdown"
fi
timeshift_pid=$(ps ax | awk '{sub(/.*\//, "", $5)} $5 ~ /timeshift/ {print $1}')
if [ "${#timeshift_pid}" -gt 0 ]; then
snapshots="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots"
log "detected running Timeshift at daemon startup, PID is: $timeshift_pid"
vlog "new snapshots directory is $snapshots"
else
log "Watching /run/timeshift for timeshift to start"
inotifywait ${inotify_qiet_flag} -e create -e delete /run/timeshift && {
sleep 1
timeshift_pid=$(ps ax | awk '{sub(/.*\//, "", $5)} $5 ~ /timeshift/ {print $1}')
snapshots="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots"
log "detected Timeshift startup, PID is: $timeshift_pid" "${CYAN}"
vlog "new snapshots directory is $snapshots" "${CYAN}"
(create_grub_menu) # create the grub menu once immidiatly in a forking process. Snapshots from commandline using timeshift --create need this
}
fi
runs=false
else else
snapdir="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots" while [ -d "$snapshots" ]; do
fi # watch the actual snapshots folder for a new snapshot or a deletion of a snapshot
} if [ ${runs} = false ] && [ ${verbose} = false ]; then
log "Watching $snapshots for new snapshots..." "${CYAN}"
daemon_function() {
trap 'vlog "$BASHPID: Received SIGINT/ SIGTERM"; exit 0' SIGINT SIGTERM
# start the actual daemon
snapdir=$1
vlog "Subdaemon function started, PID: $BASHPID" "${GREEN}"
vlog "${BASHPID}: Entering infinite while for $snapdir" "${GREEN}"
vlog "${BASHPID}: Snapshot dir watchtimeout: $watchtime"
while true; do
runs=false
if [ ${timeshift_auto} = true ] && ! [ "${timeshift_pid}" -gt 0 ] ; then
# watch the timeshift folder for a folder that is created when timeshift starts up
sleep 1 # for safety so the outer while is not going crazy
if [ "${timeshift_pid}" -eq -2 ]; then
log "${BASHPID}: detected timeshift shutdown"
fi
timeshift_pid=$(ps ax | awk '{sub(/.*\//, "", $5)} $5 ~ /timeshift/ {print $1}')
if [ "${#timeshift_pid}" -gt 0 ]; then
set_snapshot_dir
log "${BASHPID}: detected running Timeshift at daemon startup, PID is: $timeshift_pid"
vlog "${BASHPID}: new snapshots directory is $snapdir"
else
log "Watching /run/timeshift for timeshift to start"
inotifywait ${inotify_qiet_flag} -e create -e delete /run/timeshift && {
sleep 1
timeshift_pid=$(ps ax | awk '{sub(/.*\//, "", $5)} $5 ~ /timeshift/ {print $1}')
set_snapshot_dir
log "${BASHPID}: detected Timeshift startup, PID is: $timeshift_pid" "${CYAN}"
vlog "${BASHPID}: new snapshots directory is $snapdir" "${CYAN}"
(create_grub_menu) # create the grub menu once immediately in a forking process. Snapshots from commandline using timeshift --create need this
}
fi
runs=false
else else
while [ -d "$snapdir" ]; do vlog "Watching $snapshots for new snapshots..." "${CYAN}"
# watch the actual snapshots folder for a new snapshot or a deletion of a snapshot
if [ ${runs} = false ] && [ ${verbose} = false ]; then
log "${BASHPID}: Watching $snapdir for new snapshots..." "${CYAN}"
else
vlog "${BASHPID}: Watching $snapdir for new snapshots..." "${CYAN}"
fi
runs=true
inotifywait ${inotify_qiet_flag} ${inotify_recursive_flag} -e create -e delete -e unmount -t "$watchtime" "$snapdir" && {
log "${BASHPID}: Detected snapshot creation/ deletion, recreating Grub menu" "${CYAN}"
sleep 5
create_grub_menu
}
sleep 1
done
timeshift_pid=-2
fi fi
if ! [ ${timeshift_auto} = true ] && ! [ -d "${snapdir}" ] ; then # in case someone deletes the snapshots folder (in snapper mode) to prevent the while loop from going wild runs=true
break inotifywait ${inotify_qiet_flag} -e create -e delete -e unmount -t "$watchtime" "$snapshots" && {
fi log "Detected snapshot creation/ deletion, recreating Grub menu" "${CYAN}"
done sleep 5
} create_grub_menu
}
main() { sleep 1
# init
timeshift_pid=-1
watchtime=0
logfile=0
snapshots=-1
timeshift_auto=false
timeshift_old=false
verbose=false
syslog=false
recursive=false
trap sighandler SIGINT SIGTERM
setcolors true # normally we want colors
sysconfdir="/etc"
grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config"
# source config file
[ -f "$grub_btrfs_config" ] && . "$grub_btrfs_config"
[ -f "${sysconfdir}/default/grub" ] && . "${sysconfdir}/default/grub"
parse_arguments "${@}"
shift $(( OPTIND - 1 ))
snapdirs=( "${@}" )
vlog "Arguments:"
vlog "Snapshot directories: ${snapdirs[*]}"
vlog "Timestift autodetection: $timeshift_auto"
vlog "Timeshift old: $timeshift_old"
vlog "Logfile: $logfile"
vlog "Recursive: $recursive"
checks
setup
log "grub-btrfsd starting up..." "${GREEN}"
if [ ${timeshift_auto} = true ] ; then
daemon_function "timeshift" &
else
# for all dirs that got passed to the script, start a new fork with that dir
for snapdir in "${snapdirs[@]}"
do
vlog "starting daemon watching $snapdir..."
daemon_function "${snapdir}" &
done done
timeshift_pid=-2
fi fi
wait # wait for forks to finish, kill child forks if SIGTERM is sent if ! [ ${timeshift_auto} = true ] && ! [ -d "${snapshots}" ] ; then # in case someone deletes the snapshots folder (in snapper mode) to prevent the while loop from going wild
exit 0 break
} fi
done
main "${@}" exit 0 # tradition is tradition

View File

@@ -1,4 +1,4 @@
# Copyright 2023 Pascal Jaeger # Copyright 2022 Pascal Jaeger
# Distributed under the terms of the GNU General Public License v3 # Distributed under the terms of the GNU General Public License v3
## Where to locate the root snapshots ## Where to locate the root snapshots
@@ -6,12 +6,13 @@ snapshots="/.snapshots" # Snapper in the root directory
#snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06 #snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06
## Optional arguments to run with the daemon ## Optional arguments to run with the daemon
# Append options to this like this:
# optional_args="--syslog --timeshift-auto --verbose"
# Possible options are: # Possible options are:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06 # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06
# -o, --timeshift-old Look for snapshots in directory of Timeshift <v22.06 (requires --timeshift-auto)
# -l, --log-file Specify a logfile to write to # -l, --log-file Specify a logfile to write to
# -v, --verbose Let the log of the daemon be more verbose # -v, --verbose Let the log of the daemon be more verbose
# -s, --syslog Write to syslog # -s, --syslog Write to syslog
optional_args="--syslog" # Uncomment the line to activate the option
optional_args+="--syslog " # write to syslog by default
#optional_args+="--timeshift-auto "
#optional_args+="--log-file /var/log/grub-btrfsd.log "
#optional_args+="--verbose "

View File

@@ -1,5 +1,5 @@
#!/sbin/openrc-run #!/sbin/openrc-run
# Copyright 2023 Pascal Jaeger # Copyright 2021 Pascal Jaeger
# Distributed under the terms of the GNU General Public License v3 # Distributed under the terms of the GNU General Public License v3
name="grub-btrfs daemon" name="grub-btrfs daemon"

View File

@@ -9,11 +9,10 @@ Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin"
# Load environment variables from the configuration # Load environment variables from the configuration
EnvironmentFile=/etc/default/grub-btrfs/config EnvironmentFile=/etc/default/grub-btrfs/config
# Start the daemon, usage of it is: # Start the daemon, usage of it is:
# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIRS # grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR
# SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto # SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto
# Optional arguments: # Optional arguments:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory
# -o, --timeshift-old Activate for timeshift versions <22.06
# -l, --log-file Specify a logfile to write to # -l, --log-file Specify a logfile to write to
# -v, --verbose Let the log of the daemon be more verbose # -v, --verbose Let the log of the daemon be more verbose
# -s, --syslog Write to syslog # -s, --syslog Write to syslog

View File

@@ -39,11 +39,7 @@ You notice that the name of the `hook` must match the name of the 2 installed fi
Re-generate your initramfs Re-generate your initramfs
`mkinitcpio -P` (option -P means, all preset present in `/etc/mkinitcpio.d`) `mkinitcpio -P` (option -P means, all preset present in `/etc/mkinitcpio.d`)
#### Dracut based distros
Distributions that use Dracut to make their initramfs (many of the Fedora based Distros) simply have to pass either `rd.live.overlay.readonly=1` (to boot into the snapshot read only) or `rd.live.overlay.overlayfs=1` (to act like a livedisk, that is files can be changed but changes will be lost on the next boot) to their kernel command line in grub.
Grub-btrfs provides the variable `GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS` to add any command to the kernel command line. Set it to `GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="rd.live.overlay.overlayfs=1"` to make snapshots immutable when booted into.
After changing this run `sudo /etc/grub.d/41_snapshots-btrfs` to generate a new snapshot-submenu with the parameter added.
#### Other distribution #### Other distribution
Refer to your distribution's documentation or contribute to this project to add a paragraph. Refer to your distribution's documentation
or contribute to this project to add a paragraph.
# #

View File

@@ -1,4 +1,4 @@
.TH "grub-btrfs" "8" .TH "grub-btrfs" "8"
.SH "NAME" .SH "NAME"
.PP .PP
@@ -82,7 +82,7 @@ Example: \fCGRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="false"\fP
.SS "\fCGRUB_BTRFS_ROOTFLAGS\fP" .SS "\fCGRUB_BTRFS_ROOTFLAGS\fP"
.PP .PP
Comma separated mount options to be used when booting a snapshot. Comma seperated mount options to be used when booting a snapshot.
They can be defined here as well as in the “/” line inside the respective snapshots They can be defined here as well as in the “/” line inside the respective snapshots
“/etc/fstab” files. Mount options found in both places are combined, and this variable “/etc/fstab” files. Mount options found in both places are combined, and this variable
takes priority over `fstab` entries. takes priority over `fstab` entries.
@@ -102,14 +102,6 @@ Default: “false”
.IP \(em 4 .IP \(em 4
Example: \fCGRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"\fP Example: \fCGRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"\fP
.SS "\GRUB_BTRFS_ENABLE_CRYPTODISK\fP"
.PP
Enable booting from snapshots stored on LUKS encrypted devices
.IP \(em 4
Default: “false”
.IP \(em 4
Example: \GRUB_BTRFS_ENABLE_CRYPTODISK="true"\fP
.SS "CUSTOM KERNELS" .SS "CUSTOM KERNELS"
.SS "\fCGRUB_BTRFS_NKERNEL\fP / \fCGRUB_BTRFS_NINIT\fP / \fCGRUB_BTRFS_CUSTOM_MICROCODE\fP" .SS "\fCGRUB_BTRFS_NKERNEL\fP / \fCGRUB_BTRFS_NINIT\fP / \fCGRUB_BTRFS_CUSTOM_MICROCODE\fP"
.PP .PP
@@ -122,17 +114,6 @@ Example: \fCGRUB_BTRFS_NKERNEL=("kernel\-5.19.4\-custom" "vmlinux\-5.19.4\-custo
\fCGRUB_BTRFS_NINIT=("initramfs\-5.19.4\-custom.img" "initrd\-5.19.4\-custom.img" "otherinit\-5.19.4\-custom.gz")\fP \fCGRUB_BTRFS_NINIT=("initramfs\-5.19.4\-custom.img" "initrd\-5.19.4\-custom.img" "otherinit\-5.19.4\-custom.gz")\fP
\fCGRUB_BTRFS_CUSTOM_MICROCODE=("custom\-ucode.img" "custom\-uc.img "custom_ucode.cpio")\fP \fCGRUB_BTRFS_CUSTOM_MICROCODE=("custom\-ucode.img" "custom\-uc.img "custom_ucode.cpio")\fP
.SS "\fCGRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS\fP"
.PP
Additional kernel command line parameters that should be passed to the kernelwhen
booting a snapshot.
For dracut based distros this could be useful to pass “rd.live.overlay.overlayfs=1”
or “rd.live.overlay.readonly=1” to the Kernel for booting read only snapshots.
.IP \(em 4
Default: “”
.IP \(em 4
Example: \fCGRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="rd.live.overlay.overlayfs=1"\fP
.SS "SNAPSHOT FILTERING" .SS "SNAPSHOT FILTERING"
.SS "\fCGRUB_BTRFS_IGNORE_SPECIFIC_PATH\fP" .SS "\fCGRUB_BTRFS_IGNORE_SPECIFIC_PATH\fP"
.PP .PP
@@ -187,6 +168,7 @@ Example: \fCGRUB_BTRFS_BOOT_DIRNAME="/"\fP
.SS "\fCGRUB_BTRFS_GRUB_DIRNAME\fP" .SS "\fCGRUB_BTRFS_GRUB_DIRNAME\fP"
.PP .PP
Location of the folder containing the “grub.cfg” file. Location of the folder containing the “grub.cfg” file.
Used by grub-btrfs to save the file “grub-btrfs.cfg”.
Might be grub2 on some systems. Might be grub2 on some systems.
For example, on Fedora with EFI : “/boot/efi/EFI/fedora” For example, on Fedora with EFI : “/boot/efi/EFI/fedora”
.IP \(em 4 .IP \(em 4
@@ -198,18 +180,18 @@ Example: \fCGRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"\fP
.PP .PP
Location where grub-btrfs.cfg should be saved. Location where grub-btrfs.cfg should be saved.
Some distributions (like OpenSuSE) store those file at the snapshot directory Some distributions (like OpenSuSE) store those file at the snapshot directory
instead of boot. Be aware that this directory must be available for grub during instead of boot. Be aware that this direcory must be available for grub during
startup of the system. startup of the system.
.IP \(em 4 .IP \(em 4
Default: \fC$GRUB_BTRFS_GRUB_DIRNAME\fP Default: “/boot/grub”
.IP \(em 4 .IP \(em 4
Example: \fCGRUB_BTRFS_GBTRFS_DIRNAME="/.snapshots"\fP Example GRUB\d\s-2BTRFS\s+2\u\d\s-2GBTRFS\s+2\u\d\s-2DIRNAME\s+2\u=“/boot/grub”
.SS "\fCGRUB_BTRFS_GBTRFS_SEARCH_DIRNAME\fP" .SS "\fCGRUB_BTRFS_GBTRFS_SEARCH_DIRNAME\fP"
.PP .PP
Location of the directory where Grub searches for the grub-btrfs.cfg file. Location of the directory where Grub searches for the grub-btrfs.cfg file.
Some distributions (like OpenSuSE) store those file at the snapshot directory Some distributions (like OpenSuSE) store those file at the snapshot directory
instead of boot. Be aware that this directory must be available for grub during instead of boot. Be aware that this direcory must be available for grub during
startup of the system. startup of the system.
.IP \(em 4 .IP \(em 4
Default: “\${prefix}” (This is a grub variable that resolves to where grub is Default: “\${prefix}” (This is a grub variable that resolves to where grub is
@@ -220,7 +202,8 @@ NOTE: If variables of grub are used here like ${prefix}, they need to be escaped
.PP .PP
with `$\` before the `$` with `$\` before the `$`
.IP \(em 4 .IP \(em 4
Example: \fCGRUB_BTRFS_GBTRFS_SEARCH_DIRNAME="\${prefix}"\fP Example: GRUB\d\s-2BTRFS\s+2\u\d\s-2GBTRFS\s+2\u\d\s-2SEARCH\s+2\u\d\s-2DIRNAME\s+2\u=“\${prefix}
.SS "\fCGRUB_BTRFS_MKCONFIG\fP" .SS "\fCGRUB_BTRFS_MKCONFIG\fP"
.PP .PP
@@ -260,9 +243,7 @@ and this comment \fIhttps://github.com/Antynea/grub-btrfs/issues/95#issuecomment
Add authorized usernames separate by comma (userfoo,userbar). Add authorized usernames separate by comma (userfoo,userbar).
When Grubs password protection is enabled, the superuser is authorized by default, it is not necessary to add it When Grubs password protection is enabled, the superuser is authorized by default, it is not necessary to add it
.IP \(em 4 .IP \(em 4
Default: “ Default: “- Example: \fCGRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"\fP
.IP \(em 4
Example: \fCGRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"\fP
.SS "\fCGRUB_BTRFS_DISABLE_PROTECTION_SUBMENU\fP" .SS "\fCGRUB_BTRFS_DISABLE_PROTECTION_SUBMENU\fP"
.PP .PP

View File

@@ -1,6 +1,6 @@
#+title: grub-btrfs #+title: grub-btrfs
#+author: Pascal Jaeger #+author: Pascal Jaeger
#+MAN_CLASS_OPTIONS: :section-id "8" #+man_class_option: :sectionid 8
* NAME * NAME
grub-btrfs - Automatically add btrfs-Snapshots as a Grub submenu grub-btrfs - Automatically add btrfs-Snapshots as a Grub submenu
@@ -58,7 +58,7 @@ Show snapshots found during run "grub-mkconfig"
- Example: ~GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="false"~ - Example: ~GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="false"~
*** ~GRUB_BTRFS_ROOTFLAGS~ *** ~GRUB_BTRFS_ROOTFLAGS~
Comma separated mount options to be used when booting a snapshot. Comma seperated mount options to be used when booting a snapshot.
They can be defined here as well as in the "/" line inside the respective snapshots' They can be defined here as well as in the "/" line inside the respective snapshots'
"/etc/fstab" files. Mount options found in both places are combined, and this variable "/etc/fstab" files. Mount options found in both places are combined, and this variable
takes priority over `fstab` entries. takes priority over `fstab` entries.
@@ -73,11 +73,6 @@ Change to "true" if your boot partition is not detected as separate.
- Default: "false" - Default: "false"
- Example: ~GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"~ - Example: ~GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"~
*** ~GRUB_BTRFS_ENABLE_CRYPTODISK~
Enable booting from snapshots stored on LUKS encrypted devices
- Default: "false"
- Example: ~GRUB_BTRFS_ENABLE_CRYPTODISK="true"~
** CUSTOM KERNELS ** CUSTOM KERNELS
*** ~GRUB_BTRFS_NKERNEL~ / ~GRUB_BTRFS_NINIT~ / ~GRUB_BTRFS_CUSTOM_MICROCODE~ *** ~GRUB_BTRFS_NKERNEL~ / ~GRUB_BTRFS_NINIT~ / ~GRUB_BTRFS_CUSTOM_MICROCODE~
@@ -88,14 +83,6 @@ Customs kernel, initramfs and microcodes that are not detected can be added in t
~GRUB_BTRFS_NINIT=("initramfs-5.19.4-custom.img" "initrd-5.19.4-custom.img" "otherinit-5.19.4-custom.gz")~ ~GRUB_BTRFS_NINIT=("initramfs-5.19.4-custom.img" "initrd-5.19.4-custom.img" "otherinit-5.19.4-custom.gz")~
~GRUB_BTRFS_CUSTOM_MICROCODE=("custom-ucode.img" "custom-uc.img "custom_ucode.cpio")~ ~GRUB_BTRFS_CUSTOM_MICROCODE=("custom-ucode.img" "custom-uc.img "custom_ucode.cpio")~
*** ~GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS~
Additional kernel command line parameters that should be passed to the kernelwhen
booting a snapshot.
For dracut based distros this could be useful to pass "rd.live.overlay.overlayfs=1"
or "rd.live.overlay.readonly=1" to the Kernel for booting read only snapshots.
- Default: ""
- Example: ~GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="rd.live.overlay.overlayfs=1"~
** SNAPSHOT FILTERING ** SNAPSHOT FILTERING
*** ~GRUB_BTRFS_IGNORE_SPECIFIC_PATH~ *** ~GRUB_BTRFS_IGNORE_SPECIFIC_PATH~
@@ -136,6 +123,7 @@ Used by "grub-btrfs" to detect the boot partition and the location of kernels, i
*** ~GRUB_BTRFS_GRUB_DIRNAME~ *** ~GRUB_BTRFS_GRUB_DIRNAME~
Location of the folder containing the "grub.cfg" file. Location of the folder containing the "grub.cfg" file.
Used by grub-btrfs to save the file "grub-btrfs.cfg".
Might be grub2 on some systems. Might be grub2 on some systems.
For example, on Fedora with EFI : "/boot/efi/EFI/fedora" For example, on Fedora with EFI : "/boot/efi/EFI/fedora"
- Default: "/boot/grub" - Default: "/boot/grub"
@@ -144,27 +132,25 @@ For example, on Fedora with EFI : "/boot/efi/EFI/fedora"
*** ~GRUB_BTRFS_GBTRFS_DIRNAME~ *** ~GRUB_BTRFS_GBTRFS_DIRNAME~
Location where grub-btrfs.cfg should be saved. Location where grub-btrfs.cfg should be saved.
Some distributions (like OpenSuSE) store those file at the snapshot directory Some distributions (like OpenSuSE) store those file at the snapshot directory
instead of boot. Be aware that this directory must be available for grub during instead of boot. Be aware that this direcory must be available for grub during
startup of the system. startup of the system.
- Default: ~$GRUB_BTRFS_GRUB_DIRNAME~ - Default: "/boot/grub"
- Example: ~GRUB_BTRFS_GBTRFS_DIRNAME="/.snapshots"~ - Example GRUB_BTRFS_GBTRFS_DIRNAME="/boot/grub"
*** ~GRUB_BTRFS_GBTRFS_SEARCH_DIRNAME~ *** ~GRUB_BTRFS_GBTRFS_SEARCH_DIRNAME~
Location of the directory where Grub searches for the grub-btrfs.cfg file. Location of the directory where Grub searches for the grub-btrfs.cfg file.
Some distributions (like OpenSuSE) store those file at the snapshot directory Some distributions (like OpenSuSE) store those file at the snapshot directory
instead of boot. Be aware that this directory must be available for grub during instead of boot. Be aware that this direcory must be available for grub during
startup of the system. startup of the system.
- Default: "\${prefix}" (This is a grub variable that resolves to where grub is - Default: "\${prefix}" (This is a grub variable that resolves to where grub is
installed. (like /boot/grub, /boot/efi/grub)) installed. (like /boot/grub, /boot/efi/grub))
- NOTE: If variables of grub are used here like ${prefix}, they need to be escaped - NOTE: If variables of grub are used here like ${prefix}, they need to be escaped
with `\` before the `$` with `\` before the `$`
- Example: ~GRUB_BTRFS_GBTRFS_SEARCH_DIRNAME="\${prefix}"~ - Example: GRUB_BTRFS_GBTRFS_SEARCH_DIRNAME="\${prefix}"
*** ~GRUB_BTRFS_MKCONFIG~ *** ~GRUB_BTRFS_MKCONFIG~
Name/path of the command to generate the grub menu, used by Name/path of the command to generate the grub menu, used by "grub-btrfs.service"
#+BEGIN_MAN
.BR grub-btrfsd (8)
#+END_MAN
Might be 'grub2-mkconfig' on some systems (e.g. Fedora) Might be 'grub2-mkconfig' on some systems (e.g. Fedora)
Default paths are /sbin:/bin:/usr/sbin:/usr/bin, if your path is missing, report it on the upstream project. Default paths are /sbin:/bin:/usr/sbin:/usr/bin, if your path is missing, report it on the upstream project.
You can use the name of the command only or full the path. You can use the name of the command only or full the path.
@@ -191,8 +177,7 @@ Refer to the Grub documentation https://www.gnu.org/software/grub/manual/grub/gr
and this comment https://github.com/Antynea/grub-btrfs/issues/95#issuecomment-682295660 and this comment https://github.com/Antynea/grub-btrfs/issues/95#issuecomment-682295660
Add authorized usernames separate by comma (userfoo,userbar). Add authorized usernames separate by comma (userfoo,userbar).
When Grub's password protection is enabled, the superuser is authorized by default, it is not necessary to add it When Grub's password protection is enabled, the superuser is authorized by default, it is not necessary to add it
- Default: "" - Default: "- Example: ~GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"~
- Example: ~GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"~
*** ~GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU~ *** ~GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU~
Disable authentication support for submenu of Grub-btrfs only (--unrestricted) Disable authentication support for submenu of Grub-btrfs only (--unrestricted)

View File

@@ -1,4 +1,4 @@
.TH "grub-btrfsd" "8" .TH "grub-btrfsd" "8"
.SH "NAME" .SH "NAME"
.PP .PP
@@ -9,7 +9,7 @@ when a new btrfs snapshot is created.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.PP .PP
\fCgrub\-btrfsd [\-h, \-\-help] [\-c, \-\-no\-color] [\-l, \-\-log\-file LOG_FILE] [\-r, \-\-recursive] [\-s, \-\-syslog] [\-t, \-\-timeshift\-auto] [\-o, \-\-timeshift\-old] [\-v, \-\-verbose] SNAPSHOTS_DIRS\fP \fCgrub\-btrfsd [\-h, \-\-help] [\-c, \-\-no\-color] [\-l, \-\-log\-file LOG_FILE] [\-s, \-\-syslog] [\-t, \-\-timeshift\-auto] [\-v, \-\-verbose] SNAPSHOTS_DIR\fP
.SH "DESCRIPTION" .SH "DESCRIPTION"
.PP .PP
@@ -17,11 +17,10 @@ Grub-btrfsd is a shell script which is meant to be run as a daemon.
Grub-btrfsd watches a directory where btrfs-snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or \fC/etc/grub.d/41_snapshots\-btrfs\fP (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes. Grub-btrfsd watches a directory where btrfs-snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or \fC/etc/grub.d/41_snapshots\-btrfs\fP (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes.
.SH "OPTIONS" .SH "OPTIONS"
.SS "\fCSNAPSHOTS_DIRS\fP" .SS "\fCSNAPSHOTS_DIR\fP"
.PP .PP
This argument specifies the (space separated) paths where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots. This argument specifies the path where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots.
E.g. for Snapper this would be \fC/.snapshots\fP. It is possible to define more than one directory here, all directories will inherit the same settings (recursive etc.). E.g. for Snapper this would be \fC/.snapshots\fP
This argument is not necessary to provide if \fC\-\-timeshift\-auto\fP is set.
.SS "\fC\-c / \-\-no\-color\fP" .SS "\fC\-c / \-\-no\-color\fP"
.PP .PP
@@ -31,21 +30,13 @@ Disable colors in output.
.PP .PP
This arguments specifies a file where grub-btrfsd should write log messages. This arguments specifies a file where grub-btrfsd should write log messages.
.SS "\fC\-r / \-\-recursive\fP"
.PP
Watch snapshot directory recursively
.SS "\fC\-s / \-\-syslog\fP" .SS "\fC\-s / \-\-syslog\fP"
.PP .PP
Write to syslog Write to syslog
.SS "\fC\-t / \-\-timeshift\-auto\fP" .SS "\fC\-t / \-\-timeshift\-auto\fP"
.PP .PP
This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to \fC/run/timeshift/$PID/backup/timeshift\-btrfs\fP. Where \fC$PID\fP is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument \fCSNAPSHOTS_DIRS\fP has no effect. This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to \fC/run/timeshift/$PID/backup/timeshift\-btrfs\fP. Where \fC$PID\fP is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument \fCSNAPSHOTS_DIR\fP has no effect.
.SS "\fC\-o / \-\-timeshift\-old\fP"
.PP
Look for snapshots in \fC/run/timeshift/backup/timeshift\-btrfs\fP instead of \fC/run/timeshift/$PID/backup/timeshift\-btrfs\fP. This is to be used for Timeshift versions <22.06.
.SS "\fC\-v / \-\-verbose\fP" .SS "\fC\-v / \-\-verbose\fP"
.PP .PP
@@ -55,6 +46,8 @@ Let the log of the daemon be more verbose
.PP .PP
Displays a short help message. Displays a short help message.
.SH "CONFIGURATION" .SH "CONFIGURATION"
.PP .PP
The daemon is usually configured via the file \fC/etc/conf.d/grub\-btrfsd\fP on openrc-init systems and \fCsudo systemctl edit \-\-full grub\-btrfsd\fP on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured. The daemon is usually configured via the file \fC/etc/conf.d/grub\-btrfsd\fP on openrc-init systems and \fCsudo systemctl edit \-\-full grub\-btrfsd\fP on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured.

View File

@@ -1,6 +1,6 @@
#+title: grub-btrfsd #+title: grub-btrfsd
#+author: Pascal Jaeger #+author: Pascal Jaeger
#+MAN_CLASS_OPTIONS: :section-id "8" #+man_class_option: :sectionid 8
* NAME * NAME
grub-btrfsd - An OpenRC daemon to automatically update the grub menu with grub-btrfsd - An OpenRC daemon to automatically update the grub menu with
@@ -10,17 +10,16 @@ grub-btrfsd - An OpenRC daemon to automatically update the grub menu with
when a new btrfs snapshot is created. when a new btrfs snapshot is created.
* SYNOPSIS * SYNOPSIS
~grub-btrfsd [-h, --help] [-c, --no-color] [-l, --log-file LOG_FILE] [-r, --recursive] [-s, --syslog] [-t, --timeshift-auto] [-o, --timeshift-old] [-v, --verbose] SNAPSHOTS_DIRS~ ~grub-btrfsd [-h, --help] [-c, --no-color] [-l, --log-file LOG_FILE] [-s, --syslog] [-t, --timeshift-auto] [-v, --verbose] SNAPSHOTS_DIR~
* DESCRIPTION * DESCRIPTION
Grub-btrfsd is a shell script which is meant to be run as a daemon. Grub-btrfsd is a shell script which is meant to be run as a daemon.
Grub-btrfsd watches a directory where btrfs-snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or ~/etc/grub.d/41_snapshots-btrfs~ (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes. Grub-btrfsd watches a directory where btrfs-snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or ~/etc/grub.d/41_snapshots-btrfs~ (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes.
* OPTIONS * OPTIONS
** ~SNAPSHOTS_DIRS~ ** ~SNAPSHOTS_DIR~
This argument specifies the (space separated) paths where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots. This argument specifies the path where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots.
E.g. for Snapper this would be ~/.snapshots~. It is possible to define more than one directory here, all directories will inherit the same settings (recursive etc.). E.g. for Snapper this would be ~/.snapshots~
This argument is not necessary to provide if ~--timeshift-auto~ is set.
** ~-c / --no-color~ ** ~-c / --no-color~
Disable colors in output. Disable colors in output.
@@ -28,17 +27,11 @@ Disable colors in output.
** ~-l / --log-file~ ** ~-l / --log-file~
This arguments specifies a file where grub-btrfsd should write log messages. This arguments specifies a file where grub-btrfsd should write log messages.
** ~-r / --recursive~
Watch snapshot directory recursively
** ~-s / --syslog~ ** ~-s / --syslog~
Write to syslog Write to syslog
** ~-t / --timeshift-auto~ ** ~-t / --timeshift-auto~
This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to ~/run/timeshift/$PID/backup/timeshift-btrfs~. Where ~$PID~ is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument ~SNAPSHOTS_DIRS~ has no effect. This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to ~/run/timeshift/$PID/backup/timeshift-btrfs~. Where ~$PID~ is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument ~SNAPSHOTS_DIR~ has no effect.
** ~-o / --timeshift-old~
Look for snapshots in ~/run/timeshift/backup/timeshift-btrfs~ instead of ~/run/timeshift/$PID/backup/timeshift-btrfs~. This is to be used for Timeshift versions <22.06.
** ~-v / --verbose~ ** ~-v / --verbose~
Let the log of the daemon be more verbose Let the log of the daemon be more verbose
@@ -46,6 +39,8 @@ Let the log of the daemon be more verbose
** ~-h / --help~ ** ~-h / --help~
Displays a short help message. Displays a short help message.
* CONFIGURATION * CONFIGURATION
The daemon is usually configured via the file ~/etc/conf.d/grub-btrfsd~ on openrc-init systems and ~sudo systemctl edit --full grub-btrfsd~ on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured. The daemon is usually configured via the file ~/etc/conf.d/grub-btrfsd~ on openrc-init systems and ~sudo systemctl edit --full grub-btrfsd~ on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured.

View File

@@ -1,280 +0,0 @@
.TH "grub-btrfs" "8"
.SH "NAME"
.PP
grub-btrfs - Automatically add btrfs-Snapshots as a Grub submenu
.SH "SYNOPSIS"
.PP
\fC/etc/grub.d/41_snapshots\-btrfs [\-V, \-\-version]\fP
.SH "DESCRIPTION"
.PP
Improves grub by adding “btrfs snapshots” to the grub menu.
.PP
You can boot your system on a “snapshot” from the grub menu.
Supports manual snapshots, snapper and timeshift.
Features of grub-btrfs:
.IP \(em 4
Automatically list snapshots existing on root partition (btrfs).
.IP \(em 4
Automatically detect if /boot is in separate partition.
.IP \(em 4
Automatically detect kernel, initramfs and intel/amd microcode in /boot directory on snapshots.
.IP \(em 4
Automatically create corresponding “menuentry” in grub.cfg
.IP \(em 4
Automatically detect the type/tags and descriptions/comments of snapper/timeshift snapshots.
.IP \(em 4
Automatically generate grub.cfg if you use the provided systemd service.
.SH "CONFIGURATION"
.PP
grub-btrfs is configured via the file \fC/etc/default/grub\-btrfs/config\fP.
Possible options are:
.SS "GENERAL"
.SS "\fCGRUB_BTRFS_DISABLE\fP"
.PP
Disable grub-btrfs if true.
.IP \(em 4
Default: “false”
.IP \(em 4
Example: \fCGRUB_BTRFS_DISABLE="true"\fP
.SS "\fCGRUB_BTRFS_TITLE_FORMAT\fP"
.PP
The snapshot entries submenu in Grub are added according to this line. It is possible to change to order of the fields.
.IP \(em 4
Default: (“date” “snapshot” “type” “description”)
.IP \(em 4
Example: \fCGRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description")\fP
.SS "\fCGRUB_BTRFS_LIMIT\fP"
.PP
Maximum number of snapshots in the GRUB snapshots sub menu.
.IP \(em 4
Default: “50”
.IP \(em 4
Example: \fCGRUB_BTRFS_LIMIT="50"\fP
.SS "\fCGRUB_BTRFS_SUBVOLUME_SORT\fP"
.PP
Sort the found subvolumes by “ogeneration” or “generation” or “path” or “rootid”.
.IP \(em 4
See Sorting section in
.BR btrfs-subvolume (8)
.PP
“-rootid” means list snapshot by new ones first.
.IP \(em 4
Default: “-rootid”
.IP \(em 4
Example: \fCGRUB_BTRFS_SUBVOLUME_SORT="+ogen,\-gen,path,rootid"\fP
.SS "\fCGRUB_BTRFS_SHOW_SNAPSHOTS_FOUND\fP"
.PP
Show snapshots found during run “grub-mkconfig”
.IP \(em 4
Default: “true”
.IP \(em 4
Example: \fCGRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="false"\fP
.SS "\fCGRUB_BTRFS_ROOTFLAGS\fP"
.PP
Comma separated mount options to be used when booting a snapshot.
They can be defined here as well as in the “/” line inside the respective snapshots
“/etc/fstab” files. Mount options found in both places are combined, and this variable
takes priority over `fstab` entries.
NB: Do NOT include “subvol=...” or “subvolid=...” here.
.IP \(em 4
Default: “”
.IP \(em 4
Example: \fCGRUB_BTRFS_ROOTFLAGS="space_cache,commit=10,norecovery"\fP
.SS "\fCGRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION\fP"
.PP
By default “grub-btrfs” automatically detects your boot partition,
either located at the system root or on a separate partition or in a subvolume,
Change to “true” if your boot partition is not detected as separate.
.IP \(em 4
Default: “false”
.IP \(em 4
Example: \fCGRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"\fP
.SS "CUSTOM KERNELS"
.SS "\fCGRUB_BTRFS_NKERNEL\fP / \fCGRUB_BTRFS_NINIT\fP / \fCGRUB_BTRFS_CUSTOM_MICROCODE\fP"
.PP
By default, “grub-btrfs” automatically detects most existing kernels, initramfs and microcode.
Customs kernel, initramfs and microcodes that are not detected can be added in these variables.
.IP \(em 4
Default: (“”)
.IP \(em 4
Example: \fCGRUB_BTRFS_NKERNEL=("kernel\-5.19.4\-custom" "vmlinux\-5.19.4\-custom")\fP
\fCGRUB_BTRFS_NINIT=("initramfs\-5.19.4\-custom.img" "initrd\-5.19.4\-custom.img" "otherinit\-5.19.4\-custom.gz")\fP
\fCGRUB_BTRFS_CUSTOM_MICROCODE=("custom\-ucode.img" "custom\-uc.img "custom_ucode.cpio")\fP
.SS "\fCGRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS\fP"
.PP
Additional kernel command line parameters that should be passed to the kernelwhen
booting a snapshot.
For dracut based distros this could be useful to pass “rd.live.overlay.overlayfs=1”
or “rd.live.overlay.readonly=1” to the Kernel for booting read only snapshots.
.IP \(em 4
Default: “”
.IP \(em 4
Example: \fCGRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="rd.live.overlay.overlayfs=1"\fP
.SS "SNAPSHOT FILTERING"
.SS "\fCGRUB_BTRFS_IGNORE_SPECIFIC_PATH\fP"
.PP
Ignore specific path during run “grub-mkconfig”.
Only exact paths are ignored.
e.g : if `specific path` = @, only `@` snapshot will be ignored.
.IP \(em 4
Default: (“@”)
.IP \(em 4
Example: \fCGRUB_BTRFS_IGNORE_SPECIFIC_PATH=("@home")\fP
.SS "\fCGRUB_BTRFS_IGNORE_PREFIX_PATH\fP"
.PP
Ignore prefix path during run “grub-mkconfig”.
Any path starting with the specified string will be ignored.
e.g : if `prefix path` = @, all snapshots beginning with “@/...” will be ignored.
.IP \(em 4
Default: (“var/lib/docker” “@var/lib/docker” “@/var/lib/docker”)
.IP \(em 4
Example: \fCGRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/docker")\fP
.SS "\fCGRUB_BTRFS_IGNORE_SNAPSHOT_TYPE\fP"
.PP
Ignore specific type/tag of snapshot during run “grub-mkconfig”.
For snapper:
Type = single, pre, post.
For Timeshift:
Tag = boot, ondemand, hourly, daily, weekly, monthly.
.IP \(em 4
Default: (“”)
.IP \(em 4
Example: \fCGRUB_BTRFS_IGNORE_SNAPSHOT_TYPE=("ondemand")\fP
.SS "\fCGRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION\fP"
.PP
Ignore specific description of snapshot during run “grub-mkconfig”.
.IP \(em 4
Default: (“”)
.IP \(em 4
Example: \fCGRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION=("timeline")\fP
.SS "DISTRIBUTION DEPENDENT SETTINGS"
.SS "\fCGRUB_BTRFS_BOOT_DIRNAME\fP"
.PP
Location of kernels/initramfs/microcode.
Used by “grub-btrfs” to detect the boot partition and the location of kernels, initramfs and microcodes.
.IP \(em 4
Default: “/boot”
.IP \(em 4
Example: \fCGRUB_BTRFS_BOOT_DIRNAME="/"\fP
.SS "\fCGRUB_BTRFS_GRUB_DIRNAME\fP"
.PP
Location of the folder containing the “grub.cfg” file.
Might be grub2 on some systems.
For example, on Fedora with EFI : “/boot/efi/EFI/fedora”
.IP \(em 4
Default: “/boot/grub”
.IP \(em 4
Example: \fCGRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"\fP
.SS "\fCGRUB_BTRFS_GBTRFS_DIRNAME\fP"
.PP
Location where grub-btrfs.cfg should be saved.
Some distributions (like OpenSuSE) store those file at the snapshot directory
instead of boot. Be aware that this directory must be available for grub during
startup of the system.
.IP \(em 4
Default: \fC$GRUB_BTRFS_GRUB_DIRNAME\fP
.IP \(em 4
Example: \fCGRUB_BTRFS_GBTRFS_DIRNAME="/.snapshots"\fP
.SS "\fCGRUB_BTRFS_GBTRFS_SEARCH_DIRNAME\fP"
.PP
Location of the directory where Grub searches for the grub-btrfs.cfg file.
Some distributions (like OpenSuSE) store those file at the snapshot directory
instead of boot. Be aware that this directory must be available for grub during
startup of the system.
.IP \(em 4
Default: “\${prefix}” (This is a grub variable that resolves to where grub is
.PP
installed. (like /boot/grub, /boot/efi/grub))
.IP \(em 4
NOTE: If variables of grub are used here like ${prefix}, they need to be escaped
.PP
with `$\` before the `$`
.IP \(em 4
Example: \fCGRUB_BTRFS_GBTRFS_SEARCH_DIRNAME="\${prefix}"\fP
.SS "\fCGRUB_BTRFS_MKCONFIG\fP"
.PP
Name/path of the command to generate the grub menu, used by “grub-btrfs.service”
Might be grub2-mkconfig on some systems (e.g. Fedora)
Default paths are /sbin:/bin:/usr/sbin:/usr/bin, if your path is missing, report it on the upstream project.
You can use the name of the command only or full the path.
.IP \(em 4
Default: grub-mkconfig
.IP \(em 4
Example: \fCGRUB_BTRFS_MKCONFIG=/sbin/grub2\-mkconfig\fP
.SS "\fCGRUB_BTRFS_SCRIPT_CHECK\fP"
.PP
Name of grub-script-check command, used by “grub-btrfs”
Might be grub2-script-check on some systems (e.g. Fedora)
.IP \(em 4
Default: grub-script-check
.IP \(em 4
Example: \fCGRUB_BTRFS_SCRIPT_CHECK=grub2\-script\-check\fP
.SS "\fCGRUB_BTRFS_MKCONFIG_LIB\fP"
.PP
Path of grub-mkconfig\d\s-2lib\s+2\u file, used by “grub-btrfs”
Might be /usr/share/grub2/grub-mkconfig\d\s-2lib\s+2\u on some systems (e.g. Opensuse)
.IP \(em 4
Default: /usr/share/grub/grub-mkconfig\d\s-2lib\s+2\u
.IP \(em 4
Example: \fCGRUB_BTRFS_MKCONFIG_LIB=/usr/share/grub2/grub\-mkconfig_lib\fP
.SS "SECURITY"
.SS "\fCGRUB_BTRFS_PROTECTION_AUTHORIZED_USERS\fP"
.PP
Password protection management for submenu, snapshots
Refer to the Grub documentation \fIhttps://www.gnu.org/software/grub/manual/grub/grub.html#Authentication-and-authorisation\fP
and this comment \fIhttps://github.com/Antynea/grub-btrfs/issues/95#issuecomment-682295660\fP
Add authorized usernames separate by comma (userfoo,userbar).
When Grubs password protection is enabled, the superuser is authorized by default, it is not necessary to add it
.IP \(em 4
Default: “”
.IP \(em 4
Example: \fCGRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"\fP
.SS "\fCGRUB_BTRFS_DISABLE_PROTECTION_SUBMENU\fP"
.PP
Disable authentication support for submenu of Grub-btrfs only (--unrestricted)
does not work if GRUB\d\s-2BTRFS\s+2\u\d\s-2PROTECTION\s+2\u\d\s-2AUTHORIZED\s+2\u\d\s-2USERS\s+2\u is not empty
.IP \(em 4
Default: “false”
.IP \(em 4
Example: \fCGRUB_BTRFS_DISABLE_PROTECTION_SUBMENU="true"\fP
.SH "FILES"
.PP
/etc/default/grub-btrfs/config
.SH "SEE ALSO"
.IR btrfs (8)
.IR btrfs-subvolume (8)
.IR grub-btrfsd (8)
.IR grub-mkconfig (8)
.SH "COPYRIGHT"
.PP
Copyright (c) 2022 Pascal Jäger

View File

@@ -1,84 +0,0 @@
.TH "grub-btrfsd" "8"
.SH "NAME"
.PP
grub-btrfsd - An OpenRC daemon to automatically update the grub menu with
.BR grub-btrfs (8)
.PP
when a new btrfs snapshot is created.
.SH "SYNOPSIS"
.PP
\fCgrub\-btrfsd [\-h, \-\-help] [\-c, \-\-no\-color] [\-l, \-\-log\-file LOG_FILE] [\-r, \-\-recursive] [\-s, \-\-syslog] [\-t, \-\-timeshift\-auto] [\-o, \-\-timeshift\-old] [\-v, \-\-verbose] SNAPSHOTS_DIRS\fP
.SH "DESCRIPTION"
.PP
Grub-btrfsd is a shell script which is meant to be run as a daemon.
Grub-btrfsd watches a directory where btrfs-snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or \fC/etc/grub.d/41_snapshots\-btrfs\fP (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes.
.SH "OPTIONS"
.SS "\fCSNAPSHOTS_DIRS\fP"
.PP
This argument specifies the (space separated) paths where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots.
E.g. for Snapper this would be \fC/.snapshots\fP. It is possible to define more than one directory here, all directories will inherit the same settings (recursive etc.).
This argument is not necessary to provide if \fC\-\-timeshift\-auto\fP is set.
.SS "\fC\-c / \-\-no\-color\fP"
.PP
Disable colors in output.
.SS "\fC\-l / \-\-log\-file\fP"
.PP
This arguments specifies a file where grub-btrfsd should write log messages.
.SS "\fC\-r / \-\-recursive\fP"
.PP
Watch snapshot directory recursively
.SS "\fC\-s / \-\-syslog\fP"
.PP
Write to syslog
.SS "\fC\-t / \-\-timeshift\-auto\fP"
.PP
This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to \fC/run/timeshift/$PID/backup/timeshift\-btrfs\fP. Where \fC$PID\fP is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument \fCSNAPSHOTS_DIRS\fP has no effect.
.SS "\fC\-o / \-\-timeshift\-old\fP"
.PP
Look for snapshots in \fC/run/timeshift/backup/timeshift\-btrfs\fP instead of \fC/run/timeshift/$PID/backup/timeshift\-btrfs\fP. This is to be used for Timeshift versions <22.06.
.SS "\fC\-v / \-\-verbose\fP"
.PP
Let the log of the daemon be more verbose
.SS "\fC\-h / \-\-help\fP"
.PP
Displays a short help message.
.SH "CONFIGURATION"
.PP
The daemon is usually configured via the file \fC/etc/conf.d/grub\-btrfsd\fP on openrc-init systems and \fCsudo systemctl edit \-\-full grub\-btrfsd\fP on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured.
.SS "NOTES"
.PP
A common configuration for Snapper would be to set \fCSNAPSHOTS_DIR\fP to \fC/.snapshots\fP and not to set \fC\-\-timeshift\-auto\fP.
For Timeshift \fC\-\-timeshift\-auto\fP is set to true and \fCSNAPSHOTS_DIR\fP can be left as is.
.SH "FILES"
.PP
\fC/etc/conf.d/grub\-btrfsd\fP
\fC/usr/lib/systemd/system/grub\-btrfsd.service\fP
.SH "SEE ALSO"
.IR btrfs (8)
.IR btrfs-subvolume (8)
.IR grub-btrfsd (8)
.IR grub-mkconfig (8)
.IR inotifywait (1)
.IR openrc (8)
.IR rc-service (8)
.IR timeshift (1)
.SH "COPYRIGHT"
.PP
Copyright (c) 2022 Pascal Jäger