grub-btrfs
grub-btrfs copied to clipboard
Merge openRC and systemd daemon
Improvement with this PR
While systemd's mount services are a charming solution, they are somewhat limited and inflexible. (See #213, #211, #215) With the daemon we wrote for openRC, we had all the flexibility a shell has, so it was easier to solve the newly arising problems with timeshift version 22.06. So this removes the .path mount service of systemd, installs the daemon grub-btrfsd (formerly known as the openrc daemon) by default on all systems and changes the systemd service so that it runs the grub-btrfsd daemon instead.
I also changed the daemon itself. It now does not poll anymore and instead watches completely with inotifywait. It works with timeshift (version 22.06 and newer) and with snapper.
Thanks @Megver83 for contributing to this and also his ideas in #210
Before we merge this, I need to do this:
- [x] test with openrc + timeshift
- [x] test with openrc + snapper
- [x] test with systemd + timeshift
- [x] test with systemd + snapper
If someone is interested in testing this out:
Install the new dependency inotify-tools. (sudo apt-get install inotify-tools
, sudo emerge inotify-tools
, however you install software on your distro. Inotify is a linux kernel utility, so the package inotify-tools should be available on nearly all linux distros)
Clone my repository:
git clone https://github.com/Schievel1/grub-btrfs.git
Go into the directory
cd grub-btrfs
Checkout the branch update-daemon
git checkout update-daemon
Run sudo make install, with the appropriate options:
sudo make install # for systemd, as this is the default option
sudo make SYSTEMD=false OPENRC=true install # for openrc
After installation run
sudo grub-mkconfig -o /boot/grub/grub.cfg
For configuration of the service/ daemon check out the Readme at https://github.com/Schievel1/grub-btrfs/tree/update-daemon
Warning: By default the service is configured to use snapper with the snapshots directory /.snapshots
, look up the readme @ https://github.com/Schievel1/grub-btrfs/tree/update-daemon on how to configure it for timeshift.
Also check out the nice manpages with man grub-btrfs
and man grub-btrfsd
and maybe read a bit and point out mistakes I made. (as english is not my native language)
I noticed on my systemd laptop that the directory /run/timeshift
initially does not exist. Only when timeshift is started this directory is created.
On my openRC PC this directory does exist, though.
This causes the daemon to trying to reestablish the inotify watch every second. Even thougt I don't think this is a performance problem, I changed that time to 3 seconds.
I think one can prevent this from happening by creating that directory.
I think this is almost ready by now. I am just playing around with logging options and such. I am gonna test this out with systemd & snapper tomorrow, then sleep a week over this, then maybe merge it.
I have tried @Schievel1 's repo but it doesn't work for me using timeshift under Debian Testing. I installed the systemd service, started and enabled it, created a new snapshot then rebooted but GRUB doesn't get updated.
Your installation instructions are incomplete and I suspect you are making some presumptions about peoples default or existing timeshift / BTRFS config. I've had a quick look at grub-btrfsd and one command that I can see its using that isn't installed by default under Debian is inotifywait which Debian and Ubuntu users can install by installing inotify-tools.
Do your scripts depend upon any other non standard commands except inotify? grub-btrfsd.service still didn't work after installing inotify-tools and rebooting.
btrfs subvol list /
ID 256 gen 29395 top level 5 path @
ID 257 gen 29400 top level 5 path @home
ID 278 gen 27561 top level 256 path var/lib/portables
ID 279 gen 27562 top level 256 path var/lib/machines
ID 294 gen 29379 top level 5 path timeshift-btrfs/snapshots/2022-09-03_13-10-33/@
ID 295 gen 29381 top level 5 path timeshift-btrfs/snapshots/2022-09-03_13-10-33/@home
# systemctl status grub-btrfsd.service
× grub-btrfsd.service - Regenerate grub-btrfs.cfg
Loaded: loaded (/lib/systemd/system/grub-btrfsd.service; enabled; preset: >
Active: failed (Result: exit-code) since Sat 2022-09-03 13:11:06 BST; 11mi>
Duration: 19ms
Process: 662 ExecStart=/usr/bin/grub-btrfsd /.snapshots --syslog (code=exit>
Main PID: 662 (code=exited, status=1/FAILURE)
CPU: 2ms
What does it expect of /.snapshots? That dir does not exist by default after installing timeshift under Debian.
Thanks for testing that out.
Yes that's correct, you need inotify for grub-btrfsd. Sorry I didn't mention this in this PR, it is listed as a dependency in the readme though.
https://packages.debian.org/bullseye/inotify-tools
The service is configured to use snapper by default, have you edited it with "sudo systemctl edit --full grub-btrfsd" to use timeshift?
Thanks for testing that out.
Yes that's correct, you need inotify for grub-btrfsd. Sorry I didn't mention this in this PR, it is listed as a dependency in the readme though.
https://packages.debian.org/bullseye/inotify-tools
The service is configured to use snapper by default, have you edited it with "sudo systemctl edit --full grub-btrfsd" ?
No. What do I need to change within grub-btrfsd to make it work with timeshift?
EDIT
Oh this is covered in the README...
Well its partly covered but it doesn't tell the user what path timeshift systemd users should be using or how to find out the correct path. I happen to know that it should be /run/timeshift/ but grub-btrfsd still doesn't successfully start for me:
$ sudo systemctl status grub-btrfsd
× grub-btrfsd.service - Regenerate grub-btrfs.cfg
Loaded: loaded (/etc/systemd/system/grub-btrfsd.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Sat 2022-09-03 13:46:59 BST; 2s ago
Duration: 2ms
Process: 1647 ExecStart=/usr/bin/grub-btrfsd /run/timeshift/ --syslog (code=exited, status=1/FAILURE)
Main PID: 1647 (code=exited, status=1/FAILURE)
CPU: 1ms
My grub-btrfsd config:
[Unit]
Description=Regenerate grub-btrfs.cfg
[Service]
Type=simple
LogLevelMax=notice
# Set the possible paths for `grub-mkconfig`
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
# Optional arguments:
# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory
# -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
ExecStart=/usr/bin/grub-btrfsd /run/timeshift/ --syslog
[Install]
WantedBy=multi-user.target
# /usr/bin/grub-btrfsd /run/timeshift/ --syslog
$grub-btrfsd starting up...$
$[!] No directory found at /run/timeshift/$
$[!] Please specify a valid snapshot directory$
Correct! /run/timeshift only appears when I have timeshift running. You say you've tested this as working with systemd and timeshift? Under which OS?
Thanks for posting that service-file here, that you configured. With more information it is always easier to do troubleshooting.
No, the order of arguments is [optional flags] (mendatory arguments) as usual. So you wanna put "ExecStart=/usr/bin/grub-btrfsd --timeshift-auto --syslog (path to snapshots dir) into that line. But since you activated --timeshift-auto you can omit the snapshots dir argument. It just gets ignored.
Thanks for posting that service-file here, that you configured. With more information it is always easier to do troubleshooting.
No, the order of commands is [optional flags] as usual. So you wanna put "ExecStart=/usr/bin/brfsd --timeshift-auto --syslog into that line. But since you activated --timeshift-auto you can omit the argument.
Looks like you made a typo there - /usr/bin/brfsd. You meant /usr/bin/grub-btrfsd ofc.
Thanks for posting that service-file here, that you configured. With more information it is always easier to do troubleshooting.
No, the order of commands is [optional flags] as usual. So you wanna put "ExecStart=/usr/bin/brfsd --timeshift-auto --syslog into that line. But since you activated --timeshift-auto you can omit the argument.
Looks like you made a typo there - /usr/bin/brfsd
waves hands frantically Yes I'm at my cell phone here :D
The line that says ExecStart=/usr/bin/grub-btrfsd /.snapshots should be edited into ExecStart=/usr/bin/grub-btrfsd --timeshift-auto. When done, the service should be restarted with
You're right, I forgot to put the "--syslog" there, will fix that later
It's still not working. I'm using:
ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto /run/timeshift/
The good news is that at least the service is running now but GRUB isn't getting updated when I create or delete snapshots.
systemctl status grub-btrfsd
● grub-btrfsd.service - Regenerate grub-btrfs.cfg
Loaded: loaded (/etc/systemd/system/grub-btrfsd.service; enabled; preset: enabled)
Active: active (running) since Sat 2022-09-03 14:22:41 BST; 1min 42s ago
Main PID: 656 (grub-btrfsd)
Tasks: 2 (limit: 19041)
Memory: 1.3M
CPU: 26ms
CGroup: /system.slice/grub-btrfsd.service
├─656 /bin/sh /usr/bin/grub-btrfsd --syslog --timeshift-auto /run/timeshift/
└─680 inotifywait -q -q -e create -e delete /run/timeshift
You're not expecting the user to edit or uncomment all the required variables within the config file before they install and use grub-btrfs are you?
I ask because I see lines like this in grub-btrfsd
:
${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o ${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg
I can see GRUB_BTRFS_MKCONFIG is defined in config
but its commented out by default, as are all the other variables in that file. The same file mentions defaults but I'm not sure where it would pull them in from if not the config file or the script itself? The users local GRUB config files?
Hm now this is becoming interesting. Maybe a versioning thing. Could you stop the service with systemctl, then go I to that directory you made when doing the git clone and run "sudo ./grub-btrfsd -t -v"
This is like running the service but you get the direct output. -v sets verbose mode for more information. Then fire up timeshift and make a snapshot. Let's see what the scripts outputs then.
You're not expecting the user to edit or uncomment all the required variables within the config file before they install and use grub-btrfs are you?
I ask because I see lines like this in
grub-btrfsd
:${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o ${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg
I can see GRUB_BTRFS_MKCONFIG is defined in
config
but its commented out by default, as are all the other variables in that file. The same file mentions defaults but I'm not sure where it would pull them in from if not the config file or the script itself? The users local GRUB config files?
No, the :- in the variable makes everything behind it the default. So when you don't define anything in the config for GRUB_BTRDS_MKCONFIG, it takes "grub-mkconf"
It seemed to update GRUB when I removed an existing snapshot but it didn't update GRUB when I created a new snapshot
# ./grub-btrfsd -t -v
$grub-btrfsd starting up...$
Arguments:$
Snapshot directory: $
Timestift autodetection: true$
Logfile: 0$
Snapshot dir watchtimeout: 15$
$Entering infinite while$
Watching /run/timeshift for timeshift to start$
Setting up watches.
Watches established.
/run/timeshift/ CREATE,ISDIR 4169
$detected Timeshift startup, PID is: 4169$
$new snapshots directory is /run/timeshift/4169/backup/timeshift-btrfs/snapshots$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
/run/timeshift/4169/backup/timeshift-btrfs/snapshots/ DELETE,ISDIR 2022-09-03_14-25-56
$Detected snapshot creation/ deletion, recreating Grub menu$
Detecting snapshots ...
No snapshots found.
If you think an error has occurred, please file a bug report at "https://github.com/Antynea/grub-btrfs"
Unmount /tmp/grub-btrfs.K4vQtphkVq .. Success
$Grub submenu recreated$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
Strange! It didn't work first time I tried it but then I deleted the snapshot and made a new one and it worked.
# ./grub-btrfsd -t -v
$grub-btrfsd starting up...$
Arguments:$
Snapshot directory: $
Timestift autodetection: true$
Logfile: 0$
Snapshot dir watchtimeout: 15$
$Entering infinite while$
detected running Timeshift at daemon startup, PID is: 4169$
new snapshots directory is /run/timeshift/4169/backup/timeshift-btrfs/snapshots$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
/run/timeshift/4169/backup/timeshift-btrfs/snapshots/ DELETE,ISDIR 2022-09-03_15-12-11
$Detected snapshot creation/ deletion, recreating Grub menu$
Detecting snapshots ...
No snapshots found.
If you think an error has occurred, please file a bug report at "https://github.com/Antynea/grub-btrfs"
Unmount /tmp/grub-btrfs.MROzaRjwjG .. Success
$Grub submenu recreated$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
/run/timeshift/4169/backup/timeshift-btrfs/snapshots/ CREATE,ISDIR 2022-09-03_15-21-21
$Detected snapshot creation/ deletion, recreating Grub menu$
Detecting snapshots ...
Found snapshot: 2022-09-03 15:21:21 | timeshift-btrfs/snapshots/2022-09-03_15-21-21/@ | ondemand | N/A |
Found 1 snapshot(s)
submenu 'Debian GNU/Linux snapshots' {
configfile "${prefix}/grub-btrfs.cfg"
}
Unmount /tmp/grub-btrfs.remebZmqat .. Success
$Grub submenu recreated$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
/run/timeshift/4169/backup/timeshift-btrfs/snapshots/ DELETE,ISDIR 2022-09-03_15-21-21
$Detected snapshot creation/ deletion, recreating Grub menu$
Detecting snapshots ...
No snapshots found.
If you think an error has occurred, please file a bug report at "https://github.com/Antynea/grub-btrfs"
Unmount /tmp/grub-btrfs.4qSgRmeqLt .. Success
$Grub submenu recreated$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
/run/timeshift/4169/backup/timeshift-btrfs/snapshots/ CREATE,ISDIR 2022-09-03_15-22-02
$Detected snapshot creation/ deletion, recreating Grub menu$
Detecting snapshots ...
Found snapshot: 2022-09-03 15:22:02 | timeshift-btrfs/snapshots/2022-09-03_15-22-02/@ | ondemand | N/A |
Found 1 snapshot(s)
submenu 'Debian GNU/Linux snapshots' {
configfile "${prefix}/grub-btrfs.cfg"
}
Unmount /tmp/grub-btrfs.m4S4nPzKVK .. Success
$Grub submenu recreated$
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
$Watching /run/timeshift/4169/backup/timeshift-btrfs/snapshots for new snapshots...$
Setting up watches.
Watches established.
Its still not working. Because I was seeing lines like:
/run/timeshift/4169/backup/timeshift-btrfs/snapshots/ CREATE,ISDIR 2022-09-03_15-22-02
$Detected snapshot creation/ deletion, recreating Grub menu$
Detecting snapshots ...
Found snapshot: 2022-09-03 15:22:02 | timeshift-btrfs/snapshots/2022-09-03_15-22-02/@ | ondemand | N/A |
Found 1 snapshot(s)
submenu 'Debian GNU/Linux snapshots' {
configfile "${prefix}/grub-btrfs.cfg"
}
Unmount /tmp/grub-btrfs.m4S4nPzKVK .. Success
$Grub submenu recreated$
In the log I presumed GRUB was getting updated but its not, after rebooting to check. It looks like $prefix isn't getting set.
The daemon is running fine, the line that says "Detected snapshot creation/ deletion, recreating Grub menu$" indicates that. The output after that, that is saying "detecting snapshots" is from grub-btrfs, not grub-btrfsd.
What's the output when you run grub-btrfs? Command is "sudo /etc/grub.d/41_snapshots-btrfs"
But thanks for posting that and testing it. It didn't occur to me that saying "grub menu recreated" in the log regardless if it really worked isn't a good idea :D
# /etc/grub.d/41_snapshots-btrfs
Detecting snapshots ...
Found snapshot: 2022-09-03 15:25:02 | timeshift-btrfs/snapshots/2022-09-03_15-25-02/@ | ondemand | N/A |
Found 1 snapshot(s)
submenu 'Debian GNU/Linux snapshots' {
configfile "${prefix}/grub-btrfs.cfg"
}
Unmount /tmp/grub-btrfs.quIzKOow1n .. Success
Where is ${prefix} set?
I think right now we are starting to troubleshoot an issue with grub-btrfs, not with the daemon, which this PR is about. The daemon is starting grub-btrfs fine, otherwise it would not say anything about snapshots found or not.
Could you rollback to 4.11 and run /etc/grub.d/41_snapshots-btrfs manually? If the problem is still there, file an issue.
// hm, wait a sec. Maybe this IS a problem with the daemon. maybe we are triggering the grub-btrfs script too fast sometimes? Edit grub-btrfsd, the on in the directory from GitHub, on line 191 it says "sleep 5". Could you change that to "sleep 15" maybe and then run grub-btrfsd with "sudo ./grub-btrfsd -t -v" again, and make a snapshot. (You ran that with sudo before, didn't you?)
Thanks again for testing this out, I really appreciate it. That's always the problem with those timings. "It works on my machine" is just a recipe for desaster
Increasing the sleep to 15 hasn't fixed it.
Increasing the sleep to 15 hasn't fixed it.
But when you make a snapshot and run /etc/grub.d/41_snapshots-btrfs it works every time?
That just plain strange, the daemon does run the script, and it does not run it any different than you would run it manually
/ btw instead of rebooting every time to check if the snaps appear in the grub menu what I do is "cat /boot/grub/ | grep 2022" and the check with the time if the snapshot appears in there
Increasing the sleep to 15 hasn't fixed it.
But when you make a snapshot and run /etc/grub.d/41_snapshots-btrfs it works every time?
That just plain strange, the daemon does run the script, and it does not run it any different than you would run it manually
I didn't say that no. All I said was that the debug output printed when running grub-btrfsd
manually made it look like it was updating grub when in fact it was not.
Increasing the sleep to 15 hasn't fixed it.
But when you make a snapshot and run /etc/grub.d/41_snapshots-btrfs it works every time?
That just plain strange, the daemon does run the script, and it does not run it any different than you would run it manually
I didn't say that no. All I said was that the debug output printed when running
grub-btrfsd
manually made it look like it was updating grub when in fact it was not.
Oh. Alright I got that wrong. So the problem is not the daemon but it's rather the script itself. Have you rolled back to whatever version you were using before and checked if that still works? Because I haven't changed the grub-btrfs script much in this PR (only added some error messages at the beginning) I assume even the older version is not working.
I already have have a proven working (but systemd only) solution based on the existing main grub-btrfs repo so the problem is definitely in your repo.
Ok I just found something, can you do a "cat /boot/grub/grub.cfg" and post the last ~30 lines here?
/and sorry I gotta ask that again even though I saw that your prompt was a # : you are sure you ran all that as root/ with sudo?