Compare commits

...

20 Commits
v4.8 ... v4.10

Author SHA1 Message Date
Antynea
8142691be1 Adds missing newline
* Adds missing newline:
  "\n" was missing.
2021-09-24 15:54:04 +02:00
Antynea
bab78d4ed8 Write-protect user data
* Write-protect user data
  * The script does not need write access to the data.
  Adds "ro" flags to provide protection against accidental writing.
2021-09-24 12:24:15 +02:00
Antynea
544d2e84ac Adds security if a false positive is detected
* Adds security if a false positive is detected:
  * if the command "grep -qs "$gbgmp" /proc/mounts;" returns a false positive.
  "rm -d" will return an error if the directory is not empty.
2021-09-24 12:12:43 +02:00
Antynea
b346727219 Deletes unused code
* Deletes unused code:
  * Limit generation of menuentries if exceeds 250 has never been used.
  Uses "GRUB_BTRFS_LIMIT" (default 50) instead
2021-09-23 15:28:28 +02:00
Antynea
f1ca0db36d Update header installation section
* Update header installation section:
  * Remove instructions
  (Refet to the project website, installation section)
2021-09-23 14:54:59 +02:00
Antynea
c4d0df3a97 Rework the creation of the "grub-btrfs.cfg" file.
* Rework the creation of the "grub-btrfs.cfg" file:
  * Before, the "grub-btrfs.cfg" file was deleted and then the new configuration was written.
  No backup was made.
  * Now, the new configuration will be written in a temporary file "grub-btrfs.new" and then analysed with the "grub_script_check" command before being finally written in the "grub-btrfs.cfg" file.
  If an error is detected, the "grub-btrfs.new" file will coexist with the old "grub-btrfs.cfg" file, if it exists.
2021-09-23 14:49:56 +02:00
Antynea
c1cadccd1f Adds trap command on EXIT signal
* Adds trap command on EXIT signal:
  * Now umount command will launch on EXIT signal. 
  * Adds a function called by the trap on EXIT signal to unmount and delete the temporary folder. 
  (That should be the end of multiple tmp.xxxxxxxxxx in /tmp)
    - If the command fails, retry every 2 seconds. After 10 attempts, it will stop and display a warning.
    - If the command is successful, "Succes" will be displayed.
  * Adds "grub-btrfs" as a prefix to the temporarie mount folder.
  (before = tmp.xxxxxxxxx , now = grub-btrfs.xxxxxxxxxx)
2021-09-23 11:49:21 +02:00
Antynea
8cc214fd0e Corrects printf format string
* Corrects printf format string:
  * printf interprets escape sequences and format specifiers in the format string. If variables are included, any escape sequences or format specifiers in the data will be interpreted too, when you most likely wanted to treat it as data.
2021-09-22 19:08:55 +02:00
Antynea
81bde02b03 Update "Installation section"
* Update "Installation section":
  * Adds required dependencies
  * Indicates that the command "update-grub", is an alias to "grub-mkconfig" on Debian-like distributions.
2021-09-22 17:07:44 +02:00
Antynea
14bf041ba6 Deactivate the script as soon as possible
* With these changes, the script will be disabled as soon as possible, if :
  * "GRUB_BTRFS_DISABLE" If this variable is set to "true"
  * "btrfs-progs isn't installed" This package is required to retrieve information from the btrfs filesystem.
  * "grub-mkconfig_lib couldn't be found" This library is required because the script depends on it.
  * "Root filesystem isn't btrfs" grub-btrfs currently checks only the btrfs snapshots present on the root partition.
2021-09-22 15:49:02 +02:00
Antynea
863107588c Remove redundant check
Running a command and then checking its exit status $? against 0 is redundant.
Instead of just checking the exit code of a command, it checks the exit code of a command that checks the exit code of a command.
2021-09-22 15:40:05 +02:00
Antynea
2851ecd72b Removes double negation in file test operators
* Removes double negation in file test operators:
  * Replaces the "! -z" operator with "-n".
2021-09-22 15:31:03 +02:00
Antynea
679d000446 Add possibility to boot without init (#164)
* Add possibility to boot without init(rd,ramfs):
  - For a snapshot to be valid, it must contain a boot folder and a kernel from the official list (or have been added to the custom kernel list)
  - if a snapshot doesn't contain an init(rd,ramfs), it will be detected as valid.
  - Suppress script stop when an init is not found
  - If init isn't found, add the letter "x" to the init list. (hoping this doesn't break the support for custom init names)
  - The microcode support is still present, despite the absence of init(rd,ramfs), is it really relevant ?
2021-09-17 15:39:23 +02:00
Antynea
981777d745 Add filter snapper's snapshot (#158)
- Add filter to ignore snapper's snapshot "type or description" during run "grub-mkconfig"

- Two new variables available in the config file:
# Ignore specific type of snapper's snapshot during run "grub-mkconfig".
# Type = single, pre or post.
# Default: ("")
GRUB_BTRFS_IGNORE_SNAPPER_TYPE=("")

# Ignore specific description of snapper's snapshot during run "grub-mkconfig".
# Default: ("")
GRUB_BTRFS_IGNORE_SNAPPER_DESCRIPTION=("")
2021-07-14 12:48:20 +02:00
Björn Daase
3433754c69 Makefile: Make sure make is invoked with appropriate permissions (#146) 2021-03-01 13:35:44 +01:00
Antynea
db753a9ac8 41_snapshots: update header
* 41_snapshots: update header
  * Update "Automatically update Grub" section.
  * Update "Purpose" section.
  * Update "What this script does" section
2021-02-21 15:37:43 +01:00
Antynea
83bf1da01e Improves systemd.path unit (#139)
* grub-btrfs.path : improves unit

#### Remember to modify your configuration accordingly.  
Allows the unit to start and stop automatically when the mount point is detected.  
If the mount point is already mounted when the unit is activated `systemctl enable grub-btrfs.path`,  
it will be necessary to start the unit for monitoring to begin `systemctl start grub-btrfs.path`.

- `DefaultDependencies=no`
Prevents systemd from automatically generating `Wants= or Requires= or After=`.
- `Requires=\x2esnapshots.mount`
Ensures unit is started if mount point exists.
- `After=\x2esnapshots.mount`
Unit start after the mounting point exists.
- `BindsTo=\x2esnapshots.mount`
If the mount point is removed, the unit will stop.
- `PathModified=\x2esnapshots.mount`
The monitored folder containing the snapshots.
- `WantedBy=\x2esnapshots.mount`
If the mount point exists, unit start automatically. (only if unit is activated before the mount point is mounted)

* Readme: Update "Automatically update grub" section

Update section following the recent change in the `grub-btrfs.path` unit.  
Add information to be able to update the `grub-btrfs` menu every time the system is restart/shutdown.
2021-02-21 05:26:39 +01:00
Kriss
2f22fd8630 [make help] mention INITCPIO switch (#137)
This commit is an expansion to :
87b816345b

Since a new `make` parameter has been introduced, it should be mentioned
in the output of the `help` target.

Also, the table is being expanded by a new column describing the type of
data that each parameter may be assigned, like paths or boolean values.
2021-01-23 20:46:14 +01:00
Antynea
88a0320d62 [Makefile] remove mkinitcpio dependency (#136)
Errata commit:
This commit has no substantive code change.
This commit is provided only to document a correction to a previous commit message.
This pertains to commit object 87b816345b

Due to improper handling, the aforementioned commit message is incorrect.
Correct message is :

[Makefile] remove `mkinitcpio` dependency

The mkinitcpio binary is not available even on Arch,  when building in a
clean environment (e.g. building distro packages in a clean chroot).

This causes the mkinitcpio hook  to not be present in the final package,
which is resolved by this commit, by adding a `make` switch. This switch
allows users to explicitely turn on inclusion of the hook.

[uninstall:] don't remove non-existent folders

This prevents some warnings being output when on a non-Archlinux system,
without a previously installed initcpio hook, a `make uninstall` is per-
formed.

These three folders should _only_ be deleted if they had been mistakenly
created during `make install`.

Co-authored-by: Kriss <kr1ss.x@yandex.com>
2021-01-23 12:02:11 +01:00
Kriss
87b816345b [Makefile] remove mkinitcpio dependency (#136)
[Makefile] remove `mkinitcpio` dependency
2021-01-17 22:25:10 +01:00
5 changed files with 241 additions and 134 deletions

View File

@@ -1,38 +1,33 @@
#! /usr/bin/env bash #! /usr/bin/env bash
# #
#
# Written by: Antynea # Written by: Antynea
# BTC donation address: 1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt # BTC donation address: 1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt
# Github: https://github.com/Antynea/grub-btrfs # Github: https://github.com/Antynea/grub-btrfs
# #
# Purpose: # Purpose:
# Improves Grub by adding "btrfs snapshots" to the Grub menu. # Improves Grub by adding "btrfs snapshots" to the Grub menu.
# You can start your system on a "snapshot" from the Grub menu. # You can boot your system on a "snapshot" from the Grub menu.
# Supports manual snapshots, snapper ... # Supports manual snapshots, snapper, timeshift ...
# Warning : booting on read-only snapshots can be tricky # Warning : booting on read-only snapshots can be tricky.
# (Read about it, https://github.com/Antynea/grub-btrfs#warning-booting-on-read-only-snapshots-can-be-tricky) # (Read about it, https://github.com/Antynea/grub-btrfs#warning-booting-on-read-only-snapshots-can-be-tricky)
# #
# What this script does: # What this script does:
# - Automatically List snapshots existing on root partition (btrfs). # - Automatically List snapshots existing on root partition (btrfs).
# - Automatically Detect if "/boot" is in separate partition. # - Automatically Detect if "/boot" is in separate partition.
# - Automatically Detect kernel, initramfs and intel microcode in "/boot" directory on snapshots. # - Automatically Detect kernel, initramfs and intel/amd microcode in "/boot" directory on snapshots.
# - Automatically Create corresponding "menuentry" in grub.cfg # - Automatically Create corresponding "menuentry" in grub.cfg.
# - Automatically detect snapper and use snapper's snapshot description if available. # - Automatically detect snapper and use snapper's snapshot description if available.
# - Automatically generate grub.cfg if you use the provided systemd service. # - Automatically generate grub.cfg if you use the provided systemd service.
# #
# Installation: # Installation:
# - Run `make install` or look into Makefile for instructions on where to put each file. # - Refer to https://github.com/Antynea/grub-btrfs#installation-
# #
# Customization: # Customization:
# Refer to config for the list of available options and their default values. # You have the possibility to modify many parameters in /etc/default/grub-btrfs/config.
# Place your configurations to /etc/default/grub-btrfs/config.
# #
# Automatically update Grub # Automatically update Grub
# If you would like Grub to automatically update when a snapshots is made or deleted: # If you would like grub-btrfs menu to automatically update when a snapshot is created or deleted:
# - Use systemctl start/enable grub-btrfs.path # - Refer to https://github.com/Antynea/grub-btrfs#automatically-update-grub.
# - grub-btrfs.path automatically (re)generates grub.cfg when a modification appears in /.snapshots folder (by default).
# - If your snapshots aren't mounted in /.snapshots, you must modify the watch folder using systemctl edit grub-btrfs.path
# - See 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,25 +36,34 @@
set -e set -e
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share" datarootdir="/usr/share"
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"
. "$datarootdir/grub/grub-mkconfig_lib" [[ -f "${sysconfdir}/default/grub" ]] && . "${sysconfdir}/default/grub"
. "${sysconfdir}/default/grub"
## Exit the script, if:
disable_script() {
# Disable Grub-btrfs is set to true (default=false)
[[ "${GRUB_BTRFS_DISABLE:-"false"}" == "true" ]] && return 1
# btrfs-progs isn't installed
if ! type btrfs >/dev/null 2>&1; then return 1; fi
# grub-mkconfig_lib couldn't be found
[[ -f "$datarootdir/grub/grub-mkconfig_lib" ]] && . "$datarootdir/grub/grub-mkconfig_lib" || return 1
# Root filesystem isn't btrfs
root_fs=$(${grub_probe} --target="fs" / 2>/dev/null)
[[ "$root_fs" != "btrfs" ]] && return 1
return 0
}
disable_script
### Variables in /etc/default/grub-btrfs/config
## Disable Grub-btrfs (default=active)
[[ "${GRUB_BTRFS_DISABLE:-"false"}" == "true" ]] && exit 0
## Submenu name ## Submenu name
distro=$(awk -F "=" '/^NAME=/ {gsub(/"/, "", $2); print $2}' /etc/os-release) 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"}
## Prefix entry ## Prefix entry
prefixentry=${GRUB_BTRFS_PREFIXENTRY:-"Snapshot:"} prefixentry=${GRUB_BTRFS_PREFIXENTRY:-"Snapshot:"}
## Limit snapshots to show in the Grub menu ## Limit snapshots to show in the Grub menu (default=50)
limit_snap_show="${GRUB_BTRFS_LIMIT:-50}" limit_snap_show="${GRUB_BTRFS_LIMIT:-50}"
## How to sort snapshots list ## How to sort snapshots list
btrfssubvolsort=(--sort="${GRUB_BTRFS_SUBVOLUME_SORT:-"-rootid"}") btrfssubvolsort=(--sort="${GRUB_BTRFS_SUBVOLUME_SORT:-"-rootid"}")
@@ -76,31 +80,24 @@ case "${GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU:-"false"}" in
*) unrestricted_access_submenu="" *) unrestricted_access_submenu=""
esac esac
# Authorized users (--users foo,bar) # Authorized users (--users foo,bar)
if [ ! -z "${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
### variables script ## Probe informations of Root and Boot devices
## Probe info "Boot partition" # Probe info "Root partition"
# Boot device root_device=$(${grub_probe} --target=device /) # Root device
boot_device=$(${grub_probe} --target=device ${boot_directory}) root_uuid=$(${grub_probe} --device ${root_device} --target="fs_uuid" 2>/dev/null) # UUID of the root device
# hints string # Probe info "Boot partition"
boot_hs=$(${grub_probe} --device ${boot_device} --target="hints_string" 2>/dev/null) boot_device=$(${grub_probe} --target=device ${boot_directory}) # Boot device
# UUID of the boot partition boot_uuid=$(${grub_probe} --device ${boot_device} --target="fs_uuid" 2>/dev/null) # UUID of the boot device
boot_uuid=$(${grub_probe} --device ${boot_device} --target="fs_uuid" 2>/dev/null) boot_hs=$(${grub_probe} --device ${boot_device} --target="hints_string" 2>/dev/null) # hints string
# Type filesystem of boot partition boot_fs=$(${grub_probe} --device ${boot_device} --target="fs" 2>/dev/null) # Type filesystem of boot device
boot_fs=$(${grub_probe} --device ${boot_device} --target="fs" 2>/dev/null)
## Probe info "Root partition"
# Type filesystem of root partition
root_fs=$(${grub_probe} --target="fs" / 2>/dev/null)
# Root device
root_device=$(${grub_probe} --target=device /)
# UUID of the root partition
root_uuid=$(${grub_probe} --device ${root_device} --target="fs_uuid" 2>/dev/null)
## Parameters passed to the kernel ## Parameters passed to the kernel
kernel_parameters="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT" kernel_parameters="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
## Mount point location ## Mount point location
gbgmp=$(mktemp -d) gbgmp=$(mktemp -dt grub-btrfs.XXXXXXXXXX)
## Class for theme ## Class for theme
CLASS="--class snapshots --class gnu-linux --class gnu --class os" CLASS="--class snapshots --class gnu-linux --class gnu --class os"
## save IFS ## save IFS
@@ -122,32 +119,54 @@ detect_rootflags()
| sed -E 's/^.*[[:space:]]([[:graph:]]+)$/\1/;s/,?subvol(id)?=[^,$]+//g;s/^,//') | sed -E 's/^.*[[:space:]]([[:graph:]]+)$/\1/;s/,?subvol(id)?=[^,$]+//g;s/^,//')
rootflags="rootflags=${fstabflags:+$fstabflags,}${GRUB_BTRFS_ROOTFLAGS:+$GRUB_BTRFS_ROOTFLAGS,}" rootflags="rootflags=${fstabflags:+$fstabflags,}${GRUB_BTRFS_ROOTFLAGS:+$GRUB_BTRFS_ROOTFLAGS,}"
} }
## Path to grub-script-check
grub_script_check="${bindir}/grub-script-check"
### Error Handling ## Error Handling
print_error() print_error()
{ {
local arg="$@" local err_msg="$*"
local nothing_to_do="If you think an error has occurred , please file a bug report at \" https://github.com/Antynea/grub-btrfs \"\nNothing to do. Abort.\n" local bug_report="If you think an error has occurred , please file a bug report at \" https://github.com/Antynea/grub-btrfs \""
printf "${arg}\n${nothing_to_do}" >&2 ; printf "%s\n" "${err_msg}" "${bug_report}" >&2 ;
exit 0 exit 0
} }
test_btrfs() unmount_gbgmp()
{ {
[[ "$root_fs" != "btrfs" ]] && print_error "Root partition isn't a btrfs filesystem.\nThis script only supports snapshots of the btrfs filesystem." if [[ -d "$gbgmp" ]]; then
set +e local wait=true
type btrfs >/dev/null 2>&1 local wait_max=0
if [[ $? -ne 0 ]]; then printf "Unmount %s .." "$gbgmp" >&2;
print_error "Unable to retrieve info from btrfs filesystem, make sure you have btrfs-progs on your system." while $wait; do
if grep -qs "$gbgmp" /proc/mounts; then
wait_max=$((1+$wait_max))
if umount "$gbgmp" >/dev/null 2>&1; then
wait=false # umount successful
printf " Success\n" >&2;
elif [[ $wait_max = 10 ]]; then
printf "\nWarning: Unable to unmount %s in %s\n" "$root_device" "$gbgmp" >&2;
break;
else
printf "." >&2 ; # output to show that the script is alive
sleep 2 # wait 2 seconds before retry
fi
else
wait=false # not mounted
printf " Success\n" >&2;
fi
done
if [[ "$wait" != true ]]; then
if ! rm -d "$gbgmp" >/dev/null 2>&1; then
printf "Unable to delete %s: Device or ressource is busy\n" "$gbgmp" >&2;
fi
fi fi
set -e fi
} }
### Script
## Create entry ## Create entry
entry() entry()
{ {
echo "$@" >> "$grub_directory/grub-btrfs.cfg" echo "$@" >> "$grub_directory/grub-btrfs.new"
} }
## menu entries ## menu entries
@@ -160,24 +179,24 @@ make_menu_entries()
[[ ! -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
prefix_i=${i%%"-"*} if [[ "${name_initramfs}" != "x" ]] ; then
suffix_i=${i#*"-"} prefix_i=${i%%"-"*}
alt_suffix_i=${i##*"-"} suffix_i=${i#*"-"}
if [ "${kversion}" = "${suffix_i}" ]; then i="${i}"; alt_suffix_i=${i##*"-"}
elif [ "${kversion}.img" = "${suffix_i}" ]; then i="${i}"; if [ "${kversion}" = "${suffix_i}" ]; then i="${i}";
elif [ "${kversion}-fallback.img" = "${suffix_i}" ]; then i="${i}"; elif [ "${kversion}.img" = "${suffix_i}" ]; then i="${i}";
elif [ "${kversion}.gz" = "${suffix_i}" ]; then i="${i}"; elif [ "${kversion}-fallback.img" = "${suffix_i}" ]; then i="${i}";
else continue ; elif [ "${kversion}.gz" = "${suffix_i}" ]; then i="${i}";
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
entry " entry "
menuentry '"${k}" & "${i}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {" menuentry '"${k}" & "${i}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {"
fi fi
entry "\ entry "\
if [ x\$feature_all_video_module = xy ]; then if [ x\$feature_all_video_module = xy ]; then
insmod all_video insmod all_video
fi fi
@@ -191,18 +210,50 @@ make_menu_entries()
echo 'Loading Snapshot: "${snap_date_time}" "${snap_dir_name}"' echo 'Loading Snapshot: "${snap_date_time}" "${snap_dir_name}"'
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}"\"" linux \"${boot_dir_root_grub}/"${k}"\" root="${LINUX_ROOT_DEVICE}" ${kernel_parameters} ${rootflags}subvol=\""${snap_dir_name}"\""
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}"\""
else else
entry "\ entry "\
echo 'Loading Initramfs: "${i}" ...' echo 'Loading Initramfs: "${i}" ...'
initrd \"${boot_dir_root_grub}/"${i}"\"" initrd \"${boot_dir_root_grub}/"${i}"\""
fi fi
entry " }" entry " }"
count_warning_menuentries=$((1+$count_warning_menuentries)) count_warning_menuentries=$((1+$count_warning_menuentries))
done done
else
for u in "${name_microcode[@]}"; do
if [[ "${name_microcode}" != "x" ]] ; then
entry "
menuentry '"${k}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {"
else
entry "
menuentry '"${k}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid' {"
fi
entry "\
if [ x\$feature_all_video_module = xy ]; then
insmod all_video
fi
set gfxpayload=keep
insmod ${boot_fs}
if [ x\$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root ${boot_hs} ${boot_uuid}
else
search --no-floppy --fs-uuid --set=root ${boot_uuid}
fi
echo 'Loading Snapshot: "${snap_date_time}" "${snap_dir_name}"'
echo 'Loading Kernel: "${k}" ...'
linux \"${boot_dir_root_grub}/"${k}"\" root="${LINUX_ROOT_DEVICE}" ${kernel_parameters} ${rootflags}subvol=\""${snap_dir_name}"\""
if [[ "${name_microcode}" != "x" ]] ; then
entry "\
echo 'Loading Microcode: "${u}" ...'
initrd \"${boot_dir_root_grub}/"${u}"\""
fi
entry " }"
count_warning_menuentries=$((1+$count_warning_menuentries))
done
fi
done done
done done
entry "}" entry "}"
@@ -220,17 +271,16 @@ trim() {
snapshot_list() snapshot_list()
{ {
# Query info from snapper if it is installed # Query info from snapper if it is installed
type snapper >/dev/null 2>&1 if type snapper >/dev/null 2>&1; then
if [ $? -eq 0 ]; then
if [ -s "/etc/snapper/configs/$snapper_config" ]; then if [ -s "/etc/snapper/configs/$snapper_config" ]; then
printf "Info: snapper detected, using config '$snapper_config'\n" >&2 printf "Info: snapper detected, using config: %s\n" "$snapper_config" >&2
local snapper_ids=($(snapper --no-dbus -t 0 -c "$snapper_config" list --disable-used-space | tail -n +3 | cut -d'|' -f 1)) local snapper_ids=($(snapper --no-dbus -t 0 -c "$snapper_config" list --disable-used-space | tail -n +3 | cut -d'|' -f 1))
local snapper_types=($(snapper --no-dbus -t 0 -c "$snapper_config" list --disable-used-space | tail -n +3 | cut -d'|' -f 2)) local snapper_types=($(snapper --no-dbus -t 0 -c "$snapper_config" list --disable-used-space | tail -n +3 | cut -d'|' -f 2))
IFS=$'\n' IFS=$'\n'
local snapper_descriptions=($(snapper --no-dbus -t 0 -c "$snapper_config" list --disable-used-space | tail -n +3 | rev | cut -d'|' -f 2 | rev)) local snapper_descriptions=($(snapper --no-dbus -t 0 -c "$snapper_config" list --disable-used-space | tail -n +3 | rev | cut -d'|' -f 2 | rev))
else else
printf "Warning: snapper detected but config '$snapper_config' does not exist\n" >&2 printf "Warning: snapper detected but config: %s does not exist\n" "$snapper_config" >&2
fi fi
fi fi
@@ -250,12 +300,12 @@ snapshot_list()
[[ ${snap_path_name%%"/"*} == "<FS_TREE>" ]] && snap_path_name=${snap_path_name#*"/"} [[ ${snap_path_name%%"/"*} == "<FS_TREE>" ]] && snap_path_name=${snap_path_name#*"/"}
# ignore specific path during run "grub-mkconfig" # ignore specific path during run "grub-mkconfig"
if [ ! -z "${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
[[ "${snap_path_name}" == "${isp}" ]] && continue 2; [[ "${snap_path_name}" == "${isp}" ]] && continue 2;
done done
fi fi
if [ ! -z "${GRUB_BTRFS_IGNORE_PREFIX_PATH}" ] ; then if [ -n "${GRUB_BTRFS_IGNORE_PREFIX_PATH}" ] ; then
for isp in ${GRUB_BTRFS_IGNORE_PREFIX_PATH[@]} ; do for isp in ${GRUB_BTRFS_IGNORE_PREFIX_PATH[@]} ; do
[[ "${snap_path_name}" == "${isp}"/* ]] && continue 2; [[ "${snap_path_name}" == "${isp}"/* ]] && continue 2;
done done
@@ -300,6 +350,18 @@ snapshot_list()
if [[ "$snapper_id" == "$id" ]]; then if [[ "$snapper_id" == "$id" ]]; then
local snapper_type=$(trim "${snapper_types[$j]}") local snapper_type=$(trim "${snapper_types[$j]}")
local snapper_description=$(trim "${snapper_descriptions[$j]}") local snapper_description=$(trim "${snapper_descriptions[$j]}")
# ignore snapper_type or snapper_description during run "grub-mkconfig"
if [ -n "${GRUB_BTRFS_IGNORE_SNAPPER_TYPE}" ] ; then
for ist in ${GRUB_BTRFS_IGNORE_SNAPPER_TYPE[@]} ; do
[[ "${snapper_type}" == "${ist}" ]] && continue 3;
done
fi
if [ -n "${GRUB_BTRFS_IGNORE_SNAPPER_DESCRIPTION}" ] ; then
for isd in ${GRUB_BTRFS_IGNORE_SNAPPER_DESCRIPTION[@]} ; do
[[ "${snapper_description}" == "${isd}" ]] && continue 3;
done
fi
printf -v entry "%-${max_entry_length}s | %-${max_type_length}s | %s" "$entry" "$snapper_type" "$snapper_description" printf -v entry "%-${max_entry_length}s | %-${max_type_length}s | %s" "$entry" "$snapper_type" "$snapper_description"
break break
fi fi
@@ -323,7 +385,7 @@ detect_kernel()
done done
# Custom name kernel in GRUB_BTRFS_NKERNEL # Custom name kernel in GRUB_BTRFS_NKERNEL
if [ ! -z "${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")
@@ -346,12 +408,13 @@ detect_initramfs()
done done
# Custom name initramfs in GRUB_BTRFS_NINIT # Custom name initramfs in GRUB_BTRFS_NINIT
if [ ! -z "${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
if [ -z "${list_initramfs}" ]; then list_initramfs=(x); fi
} }
## Detect microcode in "/boot" ## Detect microcode in "/boot"
@@ -371,7 +434,7 @@ detect_microcode()
done done
# Custom name microcode in GRUB_BTRFS_CUSTOM_MICROCODE # Custom name microcode in GRUB_BTRFS_CUSTOM_MICROCODE
if [ ! -z "${GRUB_BTRFS_CUSTOM_MICROCODE}" ] ; then if [ -n "${GRUB_BTRFS_CUSTOM_MICROCODE}" ] ; then
for cucode in "${boot_dir}/${GRUB_BTRFS_CUSTOM_MICROCODE[@]}" ; do for cucode in "${boot_dir}/${GRUB_BTRFS_CUSTOM_MICROCODE[@]}" ; do
[[ ! -f "${cucode}" ]] && continue [[ ! -f "${cucode}" ]] && continue
list_ucode+=("$cucode") list_ucode+=("$cucode")
@@ -428,7 +491,6 @@ boot_bounded()
detect_rootflags detect_rootflags
# Initramfs (Original + custom initramfs) # Initramfs (Original + custom initramfs)
detect_initramfs detect_initramfs
if [ -z "${list_initramfs}" ]; then continue; fi
name_initramfs=("${list_initramfs[@]##*"/"}") name_initramfs=("${list_initramfs[@]##*"/"}")
# microcode (auto-detect + custom microcode) # microcode (auto-detect + custom microcode)
detect_microcode detect_microcode
@@ -448,11 +510,10 @@ boot_bounded()
### 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;
# Limit generation of menuentries if exceeds 250
# [[ $count_warning_menuentries -ge 250 ]] && break;
done done
IFS=$oldIFS IFS=$oldIFS
} }
boot_separate() boot_separate()
{ {
boot_dir="${boot_directory}" boot_dir="${boot_directory}"
@@ -465,7 +526,6 @@ boot_separate()
name_kernel=("${list_kernel[@]##*"/"}") name_kernel=("${list_kernel[@]##*"/"}")
# Initramfs (Original + custom initramfs) # Initramfs (Original + custom initramfs)
detect_initramfs detect_initramfs
if [ -z "${list_initramfs}" ]; then print_error "Initramfs not found."; fi
name_initramfs=("${list_initramfs[@]##*"/"}") name_initramfs=("${list_initramfs[@]##*"/"}")
# microcode (auto-detect + custom microcode) # microcode (auto-detect + custom microcode)
detect_microcode detect_microcode
@@ -496,22 +556,17 @@ boot_separate()
# 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;
# Limit generation of menuentries if exceeds 250
# [[ $count_warning_menuentries -ge 250 ]] && break;
done done
IFS=$oldIFS IFS=$oldIFS
} }
### Start
printf "Detecting snapshots ...\n" >&2 ; printf "Detecting snapshots ...\n" >&2 ;
# Only support btrfs snapshots rm -f "$grub_directory/grub-btrfs.new"
test_btrfs > "$grub_directory/grub-btrfs.new"
# Delete existing config
#rm -f --preserve-root "$grub_directory/grub-btrfs.cfg"
> "$grub_directory/grub-btrfs.cfg"
# Create mount point then mounting # Create mount point then mounting
[[ ! -d $gbgmp ]] && mkdir -p $gbgmp [[ ! -d $gbgmp ]] && mkdir -p "$gbgmp"
mount -o subvolid=5 /dev/disk/by-uuid/$root_uuid $gbgmp/ mount -o ro,subvolid=5 /dev/disk/by-uuid/"$root_uuid" "$gbgmp/"
trap "unmount_gbgmp" EXIT # unmounting mount point on EXIT signal
# Count menuentries # Count menuentries
count_warning_menuentries=0 count_warning_menuentries=0
# Count snapshots # Count snapshots
@@ -531,23 +586,25 @@ else
boot_bounded boot_bounded
fi fi
fi fi
# unmounting mount point
umount $gbgmp
# Show warn, menuentries exceeds 250 entries # Show warn, menuentries exceeds 250 entries
[[ $count_warning_menuentries -ge 250 ]] && printf "Generated ${count_warning_menuentries} total GRUB entries. You might experience issues loading snapshots menu in GRUB.\n" >&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 ;
# printf "menuentries = $count_warning_menuentries \n" >&2 ;
# Show total found snapshots # Show total found snapshots
if [[ "${GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND:-"true"}" = "true" && ! -z "${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 ${count_limit_snap} snapshot(s)\n" >&2 ; printf "Found %s snapshot(s)\n" "${count_limit_snap}" >&2 ;
fi fi
# if no snapshot found, 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
print_error "No snapshots found." print_error "No snapshots found."
fi fi
# Make a submenu in GRUB (grub.cfg) # Make a submenu in GRUB (grub.cfg) and move "grub-btrfs.new" to "grub-btrfs.cfg"
cat << EOF if ${grub_script_check} "$grub_directory/grub-btrfs.new"; then
cat "$grub_directory/grub-btrfs.new" > "$grub_directory/grub-btrfs.cfg"
rm -f "$grub_directory/grub-btrfs.new"
cat << EOF
submenu '${submenuname}' ${protection_authorized_users}${unrestricted_access_submenu}{ submenu '${submenuname}' ${protection_authorized_users}${unrestricted_access_submenu}{
configfile "\${prefix}/grub-btrfs.cfg" configfile "\${prefix}/grub-btrfs.cfg"
} }
EOF EOF
### End else
print_error "Syntax errors are detected in generated grub-btrfs.cfg file."
fi

View File

@@ -1,19 +1,25 @@
PKGNAME ?= grub-btrfs PKGNAME ?= grub-btrfs
PREFIX ?= /usr PREFIX ?= /usr
INITCPIO ?= false
SHARE_DIR = $(DESTDIR)$(PREFIX)/share SHARE_DIR = $(DESTDIR)$(PREFIX)/share
LIB_DIR = $(DESTDIR)$(PREFIX)/lib LIB_DIR = $(DESTDIR)$(PREFIX)/lib
.PHONY: install uninstall help .PHONY: install uninstall help
install: install:
@if test "$(shell id -u)" != 0; then \
echo "You are not root, run this target as root please."; \
exit 1; \
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 -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfs.service @install -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfs.service
@install -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfs.path @install -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfs.path
@install -Dm644 -t "$(SHARE_DIR)/licenses/$(PKGNAME)/" LICENSE @install -Dm644 -t "$(SHARE_DIR)/licenses/$(PKGNAME)/" LICENSE
@# Arch Linux like distros only : @# Arch Linux like distros only :
@if command -V mkinitcpio >/dev/null 2>&1; then \ @if test "$(INITCPIO)" = true; then \
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
@@ -21,6 +27,10 @@ install:
@install -Dm644 "initramfs/readme.md" "$(SHARE_DIR)/doc/$(PKGNAME)/initramfs-overlayfs.md" @install -Dm644 "initramfs/readme.md" "$(SHARE_DIR)/doc/$(PKGNAME)/initramfs-overlayfs.md"
uninstall: uninstall:
@if test "$(shell id -u)" != 0; then \
echo "You are not root, run this target as root please."; \
exit 1; \
fi
@grub_dirname="$$(grep -oP '^[[:space:]]*GRUB_BTRFS_GRUB_DIRNAME=\K.*' "$(DESTDIR)/etc/default/grub-btrfs/config" | sed "s|\s*#.*||;s|(\s*\(.\+\)\s*)|\1|;s|['\"]||g")"; \ @grub_dirname="$$(grep -oP '^[[:space:]]*GRUB_BTRFS_GRUB_DIRNAME=\K.*' "$(DESTDIR)/etc/default/grub-btrfs/config" | sed "s|\s*#.*||;s|(\s*\(.\+\)\s*)|\1|;s|['\"]||g")"; \
rm -f "$${grub_dirname:-/boot/grub}/grub-btrfs.cfg" rm -f "$${grub_dirname:-/boot/grub}/grub-btrfs.cfg"
@rm -f "$(DESTDIR)/etc/default/grub-btrfs/config" @rm -f "$(DESTDIR)/etc/default/grub-btrfs/config"
@@ -29,8 +39,8 @@ uninstall:
@rm -f "$(LIB_DIR)/systemd/system/grub-btrfs.path" @rm -f "$(LIB_DIR)/systemd/system/grub-btrfs.path"
@rm -f "$(LIB_DIR)/initcpio/install/grub-btrfs-overlayfs" @rm -f "$(LIB_DIR)/initcpio/install/grub-btrfs-overlayfs"
@rm -f "$(LIB_DIR)/initcpio/hooks/grub-btrfs-overlayfs" @rm -f "$(LIB_DIR)/initcpio/hooks/grub-btrfs-overlayfs"
@# Arch Linux unlike distros only : @# Arch Linux UNlike distros only :
@if ! command -V mkinitcpio >/dev/null 2>&1; then \ @if test "$(INITCPIO)" != true && test -d "$(LIB_DIR)/initcpio"; then \
rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio/install" || :; \ rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio/install" || :; \
rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio/hooks" || :; \ rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio/hooks" || :; \
rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio" || :; \ rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio" || :; \
@@ -50,11 +60,12 @@ help:
@echo " uninstall" @echo " uninstall"
@echo " help" @echo " help"
@echo @echo
@echo " parameters | description | defaults" @echo " parameter | type | description | defaults"
@echo " -----------+--------------------------------+----------------------------" @echo " ----------+------+--------------------------------+----------------------------"
@echo " DESTDIR | install destination | <unset>" @echo " DESTDIR | path | install destination | <unset>"
@echo " PREFIX | system tree prefix | '/usr'" @echo " PREFIX | path | system tree prefix | '/usr'"
@echo " SHARE_DIR | shared data location | '\$$(DESTDIR)\$$(PREFIX)/share'" @echo " SHARE_DIR | path | shared data location | '\$$(DESTDIR)\$$(PREFIX)/share'"
@echo " LIB_DIR | system libraries location | '\$$(DESTDIR)\$$(PREFIX)/lib'" @echo " LIB_DIR | path | system libraries location | '\$$(DESTDIR)\$$(PREFIX)/lib'"
@echo " PKGNAME | name of the ditributed package | 'grub-btrfs'" @echo " PKGNAME | name | name of the ditributed package | 'grub-btrfs'"
@echo " INITCPIO | bool | include mkinitcpio hook | false"
@echo @echo

View File

@@ -6,10 +6,10 @@
This is a version 4.xx of grub-btrfs This is a version 4.xx of grub-btrfs
##### BTC donation address: `1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt` ##### BTC donation address: `1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt`
## ##
### Description ### Description :
Improves Grub by adding "btrfs snapshots" to the Grub menu. Improves Grub by adding "btrfs snapshots" to the Grub menu.
You can start your system on a "snapshot" from the Grub menu. You can boot your system on a "snapshot" from the Grub menu.
Supports manual snapshots, snapper, timeshift ... Supports manual snapshots, snapper, timeshift ...
##### Warning: booting on read-only snapshots can be tricky ##### Warning: booting on read-only snapshots can be tricky
@@ -33,7 +33,7 @@ Refer to the [documentation](https://github.com/Antynea/grub-btrfs/blob/master/i
## ##
### Installation : ### Installation :
#### Arch Linux #### Arch Linux
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
``` ```
@@ -41,34 +41,60 @@ pacman -S grub-btrfs
#### Manual #### Manual
* Run `make install` or look into Makefile for instructions on where to put each file. * Run `make install` or look into Makefile for instructions on where to put each file.
* Dependencies:
* [btrfs-progs](https://archlinux.org/packages/core/x86_64/btrfs-progs/)
* [grub](https://archlinux.org/packages/core/x86_64/grub/)
NOTE: Generate your Grub menu after installation for the changes to take effect. NOTE: Generate your Grub menu after installation for the changes to take effect.
On Arch Linux use `grub-mkconfig -o /boot/grub/grub.cfg`. On Arch Linux use `grub-mkconfig -o /boot/grub/grub.cfg`.
On Debian-like distribution `update-grub` is an alias to `grub-mkconfig ...`
## ##
### 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`.
See [config file](https://github.com/Antynea/grub-btrfs/blob/master/config) for more information. See [config file](https://github.com/Antynea/grub-btrfs/blob/master/config) for more information.
## ##
### Automatically update grub ### Automatically update grub
If you would like Grub to automatically update when a snapshot is made or deleted: 1- If you would like grub-btrfs menu to automatically update when a snapshot is created or deleted:
* Use `systemctl start/enable grub-btrfs.path`. * Use `systemctl enable grub-btrfs.path`.
* `grub-btrfs.path` automatically (re)generates `grub.cfg` when a modification appears in `/.snapshots` folder (by default). * `grub-btrfs.path` automatically (re)generates `grub-btrfs.cfg` when a modification appears in `/.snapshots` mount point (by default).
* If your snapshots aren't mounted in `/.snapshots`, you must modify the watch folder using `systemctl edit grub-btrfs.path`. * If the `/.snapshots` mount point is already mounted, then use `systemctl start grub-btrfs.path` to start monitoring.
* For example: Timeshift mount its snapshots in `/run/timeshift/backup/timeshift-btrfs/snapshots` folder. Otherwise, the unit will automatically start monitoring when the mount point will be available.
* If your snapshots location aren't mounted in `/.snapshots`, you must modify `grub-btrfs.path` unit using
`systemctl edit --full grub-btrfs.path` and run `systemctl reenable grub-btrfs.path` for changes take effect.
To find out the name of the `.mount` unit
use `systemctl list-units -t mount`.
* For example: Timeshift mounts its snapshot folder in `/run/timeshift/backup/timeshift-btrfs/snapshots`.
Use `systemctl edit grub-btrfs.path`. Use `systemctl edit --full grub-btrfs.path`.
Then wrote: Then replace the whole block by:
``` ```
[Unit]
Description=Monitors for new snapshots
DefaultDependencies=no
Requires=run-timeshift-backup.mount
After=run-timeshift-backup.mount
BindsTo=run-timeshift-backup.mount
[Path] [Path]
PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots
[Install]
WantedBy=run-timeshift-backup.mount
``` ```
and finally save. Then save and finally run `systemctl reenable grub-btrfs.path` for changes take effect.
Optional:
If the `/run/timeshift/backup/timeshift-btrfs/snapshots` mount point is already mounted,
then use `systemctl start grub-btrfs.path` to start monitoring.
Otherwise, the unit will automatically start monitoring when the mount point will be available.
* You can view your change to `systemctl cat grub-btrfs.path`. * You can view your change to `systemctl cat grub-btrfs.path`.
* To revert change use `systemctl revert grub-btrfs.path`. * To revert change use `systemctl revert grub-btrfs.path`.
##### Warning:
2- If you would like grub-btrfs menu to automatically update on system restart/shutdown:
[Look at this comment](https://github.com/Antynea/grub-btrfs/issues/138#issuecomment-766918328)
Currently not implemented
##### Warning :
by default, `grub-mkconfig` command is used. by default, `grub-mkconfig` command is used.
Might be `grub2-mkconfig` on some systems (Fedora ...). Might be `grub2-mkconfig` on some systems (Fedora ...).
Edit `GRUB_BTRFS_MKCONFIG` variable in `/etc/default/grub-btrfs/config` file to reflect this. Edit `GRUB_BTRFS_MKCONFIG` variable in `/etc/default/grub-btrfs/config` file to reflect this.

9
config
View File

@@ -74,6 +74,15 @@ GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("@")
# 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") GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/docker")
# Ignore specific type of snapper's snapshot during run "grub-mkconfig".
# Type = single, pre, post.
# Default: ("")
GRUB_BTRFS_IGNORE_SNAPPER_TYPE=("")
# Ignore specific description of snapper's snapshot during run "grub-mkconfig".
# Default: ("")
GRUB_BTRFS_IGNORE_SNAPPER_DESCRIPTION=("")
# By default "grub-btrfs" automatically detects your boot partition, # By default "grub-btrfs" automatically detects your boot partition,
# either located at the system root or on a separate partition, # either located at the system root or on a separate partition,
# but cannot detect if it is in a subvolume. # but cannot detect if it is in a subvolume.

View File

@@ -1,8 +1,12 @@
[Unit] [Unit]
Description=Monitors for new snapshots Description=Monitors for new snapshots
DefaultDependencies=no
Requires=\x2esnapshots.mount
After=\x2esnapshots.mount
BindsTo=\x2esnapshots.mount
[Path] [Path]
PathModified=/.snapshots PathModified=/.snapshots
[Install] [Install]
WantedBy=multi-user.target WantedBy=\x2esnapshots.mount