From 8105a2edf7074e664b0d114d93f22ac617e5c663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Sun, 26 Mar 2023 20:56:07 +0200 Subject: [PATCH] grub-btrfsd: watch more than one snapshot dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #262 Signed-off-by: Pascal Jäger --- README.md | 17 +++--- config | 2 +- grub-btrfsd | 120 +++++++++++++++++++++---------------- grub-btrfsd.confd | 2 +- grub-btrfsd.initd | 2 +- grub-btrfsd.service | 4 +- manpages/grub-btrfsd.8.man | 11 ++-- manpages/grub-btrfsd.8.org | 11 ++-- 8 files changed, 93 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index c4b6cf9..4a265bb 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,10 @@ Grub-btrfs comes with a daemon script that automatically updates the grub menu w The daemon can be configured by passing different command line arguments to it. The arguments are: -* `SNAPSHOTS_DIR` -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` +* `SNAPSHOTS_DIRS` +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 `/.snapshots`. 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 `--timeshift-auto` is set. * `-c / --no-color` Disable colors in output. * `-l / --log-file` @@ -109,7 +110,7 @@ Watch the snapshots directory recursively * `-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. * `-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_DIR` 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_DIRS` has no effect. * `-v / --verbose` Let the log of the daemon be more verbose * `-h / --help` @@ -182,8 +183,8 @@ Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" # Load environment variables from the configuration EnvironmentFile=/etc/default/grub-btrfs/config # Start the daemon, usage of it is: -# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR -# SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto +# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIRS +# SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto # Optional arguments: # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory # -o, --timeshift-old Activate for timeshift versions <22.06 @@ -235,8 +236,8 @@ Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" # Load environment variables from the configuration EnvironmentFile=/etc/default/grub-btrfs/config # Start the daemon, usage of it is: -# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR -# SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto +# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIRS +# SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto # Optional arguments: # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory # -l, --log-file Specify a logfile to write to diff --git a/config b/config index 21ff0d6..720a5d4 100644 --- a/config +++ b/config @@ -1,7 +1,7 @@ #!/usr/bin/env bash -GRUB_BTRFS_VERSION=4.12-master-2023-03-26T18:44:50+00:00 +GRUB_BTRFS_VERSION=4.12-master-2023-03-26T19:08:16+00:00 # Disable grub-btrfs. # Default: "false" diff --git a/grub-btrfsd b/grub-btrfsd index 934c1ac..b71fb93 100755 --- a/grub-btrfsd +++ b/grub-btrfsd @@ -38,9 +38,9 @@ grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config" print_help() { 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_DIR" + echo "${0##*/} [-h, --help] [-c, --no-color] [-l, --log-file LOG_FILE] [-r, --recursive] [-s, --syslog] [-t, --timeshift-auto] [-v, --verbose] SNAPSHOTS_DIRS" echo - echo "SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto" + echo "SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto" echo echo "Optional arguments:" echo "-c, --no-color Disable colors in output" @@ -196,7 +196,7 @@ if [ ${timeshift_auto} = false ] && [ ${timeshift_old} = true ]; then fi vlog "Arguments:" -vlog "Snapshot directory: $snapshots" +vlog "Snapshot directories: $snapshots" vlog "Timestift autodetection: $timeshift_auto" vlog "Timeshift old: $timeshift_old" vlog "Logfile: $logfile" @@ -236,61 +236,75 @@ create_grub_menu() { set_snapshot_dir() { # old timeshift has it's snapshot dir in a different location if [ "${timeshift_old}" = true ]; then - snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" + snapdir="/run/timeshift/backup/timeshift-btrfs/snapshots" else - snapshots="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots" + snapdir="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots" fi } -# start the actual daemon -vlog "Snapshot dir watchtimeout: $watchtime" -vlog "Entering infinite while" "${GREEN}" -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 - set_snapshot_dir - 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 +daemon_function() { + # start the actual daemon + snapdir=$1 + vlog "Snapshot dir watchtimeout: $watchtime" + vlog "Entering infinite while for $snapdir" "${GREEN}" + 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}') - set_snapshot_dir - 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 - while [ -d "$snapshots" ]; do - # 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}" - else - vlog "Watching $snapshots for new snapshots..." "${CYAN}" - fi - runs=true - inotifywait ${inotify_qiet_flag} ${inotify_recursive_flag} -e create -e delete -e unmount -t "$watchtime" "$snapshots" && { - log "Detected snapshot creation/ deletion, recreating Grub menu" "${CYAN}" - sleep 5 - create_grub_menu - } - sleep 1 - done - timeshift_pid=-2 - fi - 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 - break - fi + if [ "${#timeshift_pid}" -gt 0 ]; then + set_snapshot_dir + log "detected running Timeshift at daemon startup, PID is: $timeshift_pid" + vlog "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 "detected Timeshift startup, PID is: $timeshift_pid" "${CYAN}" + vlog "new snapshots directory is $snapdir" "${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 + while [ -d "$snapdir" ]; do + # watch the actual snapshots folder for a new snapshot or a deletion of a snapshot + if [ ${runs} = false ] && [ ${verbose} = false ]; then + log "Watching $snapdir for new snapshots..." "${CYAN}" + else + vlog "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 "Detected snapshot creation/ deletion, recreating Grub menu" "${CYAN}" + sleep 5 + create_grub_menu + } + sleep 1 + done + timeshift_pid=-2 + 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 + break + fi + done +} + +# for all dirs that got passed to the script, start a new fork with that dir +snapdirs=( "${@}" ) +for snapdir in "${snapdirs[@]}" + do + vlog "starting daemon with watching $snapdir..." + daemon_function "${snapdir}" & done +wait # wait for forks to finish, kill child forks if SIGTERM is sent + + exit 0 # tradition is tradition diff --git a/grub-btrfsd.confd b/grub-btrfsd.confd index 926b0c7..8084bc2 100644 --- a/grub-btrfsd.confd +++ b/grub-btrfsd.confd @@ -1,4 +1,4 @@ -# Copyright 2022 Pascal Jaeger +# Copyright 2023 Pascal Jaeger # Distributed under the terms of the GNU General Public License v3 ## Where to locate the root snapshots diff --git a/grub-btrfsd.initd b/grub-btrfsd.initd index 2ffb8b1..29ac034 100755 --- a/grub-btrfsd.initd +++ b/grub-btrfsd.initd @@ -1,5 +1,5 @@ #!/sbin/openrc-run -# Copyright 2021 Pascal Jaeger +# Copyright 2023 Pascal Jaeger # Distributed under the terms of the GNU General Public License v3 name="grub-btrfs daemon" diff --git a/grub-btrfsd.service b/grub-btrfsd.service index 9fe8f7a..d2f8dd8 100644 --- a/grub-btrfsd.service +++ b/grub-btrfsd.service @@ -9,8 +9,8 @@ Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" # Load environment variables from the configuration EnvironmentFile=/etc/default/grub-btrfs/config # Start the daemon, usage of it is: -# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR -# SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto +# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIRS +# SNAPSHOTS_DIRS Snapshot directories to watch, without effect when --timeshift-auto # Optional arguments: # -t, --timeshift-auto Automatically detect Timeshifts snapshot directory # -o, --timeshift-old Activate for timeshift versions <22.06 diff --git a/manpages/grub-btrfsd.8.man b/manpages/grub-btrfsd.8.man index 0dd1331..5a2c016 100644 --- a/manpages/grub-btrfsd.8.man +++ b/manpages/grub-btrfsd.8.man @@ -9,7 +9,7 @@ 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_DIR\fP +\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 @@ -17,10 +17,11 @@ 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_DIR\fP" +.SS "\fCSNAPSHOTS_DIRS\fP" .PP -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 +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 @@ -40,7 +41,7 @@ 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_DIR\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_DIRS\fP has no effect. .SS "\fC\-o / \-\-timeshift\-old\fP" .PP diff --git a/manpages/grub-btrfsd.8.org b/manpages/grub-btrfsd.8.org index 2c78880..93b50e5 100644 --- a/manpages/grub-btrfsd.8.org +++ b/manpages/grub-btrfsd.8.org @@ -10,16 +10,17 @@ grub-btrfsd - An OpenRC daemon to automatically update the grub menu with when a new btrfs snapshot is created. * 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_DIR~ +~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~ * DESCRIPTION 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. * OPTIONS -** ~SNAPSHOTS_DIR~ -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~ +** ~SNAPSHOTS_DIRS~ +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 ~/.snapshots~. 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 ~--timeshift-auto~ is set. ** ~-c / --no-color~ Disable colors in output. @@ -34,7 +35,7 @@ Watch snapshot directory recursively Write to syslog ** ~-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_DIR~ 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_DIRS~ 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.