Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grub-btrfs.path is started but does not generate grub-btrfs.cfg #138

Closed
HanM23 opened this issue Jan 24, 2021 · 39 comments · Fixed by #139
Closed

grub-btrfs.path is started but does not generate grub-btrfs.cfg #138

HanM23 opened this issue Jan 24, 2021 · 39 comments · Fixed by #139

Comments

@HanM23
Copy link

HanM23 commented Jan 24, 2021

Hello,
I have a strange behavior with grub-btrfs.path service.
Right after starting my computer, i do :
systemctl status grub-btrfs.path ....it tells me that the service is enabled and active, everything is ok.

But when i create a snapshot within Timeshift, grub-btrfs.cfg is not regenerated.
Then, i do : systemctl start grub-btrfs.path, just to make sure.....nothing happens either when i create a snapshot in Timeshit.

To make it works i have to do "restart (or stop/start) on grub-btrfs.path service, and then, everything is ok, once i create a snapshot, grub-btrfs.cfg is regenerated.

I really don't know what happens, i uninstalled and reinstalled grub-btrfs several times.
I see absolutely nothing wrong in journalctl (journalctl -u grub-btrfs.path or grub-btrfs.

I have the latest Manjaro, with everything up to date.
My snapshots path has been modified as you advised us, with systemctl edit .....
I did no modification within /etc/default/grub/grub-btrfs/config.

Could you help me please?
Thanks a lot

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

Hello,

grub-btrfs.path starts grub-btrfs.service when a change is detected in the PathModified= variable.
To check the functioning of the service, when it is booted, use journalctl -ru grub-btrfs.service.

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

Okay,

/run/timeshift/backup/timeshift-btrfs/snapshots doesn't exist at boot time.
A workaround must be found ...

@HanM23
Copy link
Author

HanM23 commented Jan 24, 2021

Thanks for your reply, i was out today, i could not reply to you before.
I am happy you identified this issue as well.

By the way, could you please tell me how (and where) you discovered there is no /run/timeshift/backup/timeshift-btrfs/snapshots at boot time ?

Because when i do systemctl show grub-btrfs.path, i get :

Unit=grub-btrfs.service
Paths=/run/timeshift/backup/timeshift-btrfs/snapshots (PathModified)
Paths=/.snapshots (PathModified)
MakeDirectory=no
DirectoryMode=0755
Result=success
Id=grub-btrfs.path
Names=grub-btrfs.path
Requires=sysinit.target -.mount
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=multi-user.target grub-btrfs.service paths.target shutdown.target
After=sysinit.target -.mount
Triggers=grub-btrfs.service
RequiresMountsFor=/.snapshots /run/timeshift/backup/timeshift-btrfs/snapshots
Description=Monitors for new snapshots
LoadState=loaded
ActiveState=active
FreezerState=running
SubState=waiting
FragmentPath=/usr/lib/systemd/system/grub-btrfs.path
DropInPaths=/etc/systemd/system/grub-btrfs.path.d/override.conf
...

So, it seems to be ok :(

Thanks again

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

I installed "manjaro" in a virtual machine with a btrfs filesystem.
By default, manjaro creates 2 subvolumes on the fs @ and @home.
timeshift is also installed by default.

findmnt -S /dev/sda1
The command gives no result for timeshift.

Run the timeshift application, and now, findmnt -S /dev/sda1 return
/run/timeshift/backup /dev/sda1 .....

So I deduce that the mounting point doesn't exist at startup.

@HanM23
Copy link
Author

HanM23 commented Jan 24, 2021

Oh, i got it.

I have a Manjaro with @ subvol, my home is in another partition in xfs, it's a minimal Manjaro with xfce.

At boot time, i get :

$ findmnt -S /dev/sda6 (sda6 in my root partition)
/ /dev/sda6[/@] btrfs rw,noatime,compress=zstd:3,ssd,space_cache,commit=12

And yes, after creating a snapshot within Timeshift, i get

$ findmnt -S /dev/sda6
/ /dev/sda6[/@] btrfs rw,noatime,compress=zstd:3,ssd,space_cache,commit=120,subvolid=256,subvol=/
/run/timeshift/backup /dev/sda6 btrfs rw,relatime,compress=zstd:3,ssd,space_cache,commit=120,subvolid=5,subvol=/

If it can help, below is my fstab entry corresponding to this partition, i did not modify it, it's like that by default:

UUID=ca4f8997-1a78-417c-acff-a6b18e496711 / btrfs subvol=@,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 0 1

m2c
Thanks again

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

While waiting to find an elegant solution,
you could create the directory /.snapshots via mkdir /.snapshots command.

Then write in your fstab, this :
UUUID=ca4f8997-1a78-417c-acff-a6b18e496711 /.snapshots btrfs subvolid=5,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 0 1

This will allow grub-btrfs.path to work.

Edit: no, sorry don't do that, this doesn't work properly

@HanM23
Copy link
Author

HanM23 commented Jan 24, 2021

Yeah :)
I could not boot, but no worry, i have a clean snapshot, i am on it right now :)

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

Sorry about that, I realized that some steps were missing in my message.

@HanM23
Copy link
Author

HanM23 commented Jan 24, 2021

No worries, it was funny....i was like: WTF@!???

Anyway, i made the correction now in emergency mode in fstab

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

So,
Stopping the grub-btrfs.path
systemctl stop grub-btrfs.path
then
systemctl edit grub-btrfs.path
Replace

[Path]
PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots

by

[Path]
PathModified=
PathModified=/.snapshots/timeshift-btrfs/snapshots

don't run service at this stage.

Create a /.snapshots folder. (if you have delete it previously)
mkdir /.snapshots

Now, let's try to make it work.
Mounted your root's filesystem in /.snapshots

mount -o subvolid=5,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 /dev/sda6 /.snapshots

if no error has occurred at this stage,
run the grub-btrfs.path
systemctl start grub-btrfs.path

then take a snapshot with timeshift
and see if grub-btrfs.service works
journalctl -ru grub-btrfs.service

@HanM23
Copy link
Author

HanM23 commented Jan 24, 2021

This is working

But also, as i said in my first message, a simple restart of grub-btrfs.path service at boot time, before to run Timeshift application, makes it work too (with PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots)
So, i boot my computer, i restart grub-btrfs.path with systemctl, and then i go in Timeshift, create a snapshot --> grub-btrfs.cfg is regenerated.
I don't know if you noticed it

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

it's time to cook dinner, I'll be back later.

I don't know if you noticed it

it's very strange

@Antynea
Copy link
Owner

Antynea commented Jan 24, 2021

So, i boot my computer, i restart grub-btrfs.path with systemctl, and then i go in Timeshift, create a snapshot --> grub-btrfs.cfg is regenerated.

i performed the same test. i don't have the same result.
grub-btrfs.service isn't executed...

@HanM23
Copy link
Author

HanM23 commented Jan 25, 2021

I made some additional tests.
Indeed, you are right, i get the same result as you, but, now, what i have is :

  1. I boot on my computer
  2. I launch Timeshift but i do NOT create any snapshot, and i let it open
  3. I restart grub-btrfs.path with systemctl
  4. I create a snapshot in Timeshift
  5. grub-btrfs.cfg is regenerated and put the rights entries in it

I precise that i do not have timeshift-autosnap installed

@Antynea
Copy link
Owner

Antynea commented Jan 25, 2021

That's what I get.

Systemd.path uses inotify, and therefore the limitations that go with it...
In this case, it's impossible to monitor an mount point before its creation.

If you absolutely want the monitoring to work, you have to mount the timeshift folder that includes the snapshots yourself at boot time.

if you aren't interested in this feature, I can offer you an alternative solution, which consists in executing the grub update during a shutdown or a reboot of your system.
To do so, use the following customized service:

[Unit]
Description=Update grub-btrfs.cfg before reboot/shutdown
Before=poweroff.target

[Service]
Type=oneshot
# 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
RemainAfterExit=true
ExecStart=/bin/true
# Regenerate just '/boot/grub/grub-btrfs.cfg' if it exists and is not empty, else regenerate the whole grub menu
ExecStop=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' 

[Install]
WantedBy=multi-user.target

@HanM23
Copy link
Author

HanM23 commented Jan 25, 2021

Thanks a lot for both solutions, i will pick one of them.

But, do you think, this happens with every distro or only with Manjaro ?
Will it be the same if i use snapper instead of Timeshift ?

Thanks

@Antynea
Copy link
Owner

Antynea commented Jan 25, 2021

But, do you think, this happens with every distro or only with Manjaro ?

This is part of the design of the timeshift application, so it should be reproducible on another distribution.
Don't blame Manjaro for this disapointment.

Will it be the same if i use snapper instead of Timeshift ?

I don't use any of these applications.
Each of these applications has its advantages and limitations.
Ask around, experiment and make your own opinion.

Understand that using snapshots, requires you to explicitly mount your either root filesystem (subvolid=5) or another dedicated subvolume or another folder/device in a folder (permanent or temporary).
Whether it's you or an app doing it for you, it has to be done.

I use a manual method to create snapshots (without third-party tools), i like that my device containing snapshots is mounted on system startup in a permanent folder.
In this case, grub-btrfs.path works as expected.

@HanM23
Copy link
Author

HanM23 commented Jan 26, 2021

Thanks for your help.
I will mount my folder' snapshot at startup too

@Antynea
Copy link
Owner

Antynea commented Jan 26, 2021

okay
You confirm that 'grub-btrfs.path' is working now?
Leave your issue open, if i find a satisfactory solution i will post here.

@HanM23
Copy link
Author

HanM23 commented Jan 26, 2021

How do you mount your snapshots at startup ?
I mean, mine are located in /run/timeshift/backup/timeshift-btrfs/snapshots
So i guess i have to mount them but i don't how exactly. I know how to mount a samba share of ntfs, or even another partition (ntfs for instance), but for subvolumes, it's a bit tricky.

In addition, in /run/timeshift/backup, i have a '@' folder, i guess it's related to timeshift, but i really do not know what is it.

What we need to know is, once snapshot are properly mounted at startup, if grub-btrfs.path is working.

Because if i start my computer, then i run timeshift (only to mount the snapshots), i still have to restart grub-btrfs.path with systemctl to make it working.

@Antynea
Copy link
Owner

Antynea commented Jan 26, 2021

Short answer :
Write an entry in your fstab file to mount the root of your filesystem.
Modify grub-btrfs.path accordingly.

Long answer : ( hope this will be understandable )

How do you mount your snapshots at startup ?

At the root of my filesystem,
i created a @ subvolume that contains my entire OS, home folder included.
I also created a @snapshots subvolume which hosts my snapshots.
As well as other subvolume dedicated to something else ....
With this configuration, I just have to mount my @snapshots subvolume in a persistent folder that places at the root of my OS. (/.snapshots)

Your setup is somewhat different.
You told me you have a @ subvolume (which contains your OS) at the root of the filesystem.
When you start your system, its this subvolume that is mounted automatically, so you don't have access to the root of your filesystem at this point.

I mean, mine are located in /run/timeshift/backup/timeshift-btrfs/snapshots

/run/timeshift/backup is a trap.
It is a mount point, which is used to access the root of your filesystem, because timeshift stores your snapshots in a folder timeshift-btrfs at the root of your filesystem, unfortunately, it is a folder and not a subvolume.
This forces us to mount the root of your filesystem.
(It would have been easier, if timeshift used a subvolume).

So i guess i have to mount them but i don't how exactly.

Remember this message
To manually mount your root filesystem, I have shown you the procedure :
mkdir /.snapshots
mount -o subvolid=5,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 /dev/sda6 /.snapshots

You can replace /.snapshots with the location and name you like.
Mount command will mount the root of your filesystem in /.snapshots, but it's not persistent after a reboot.
To do that, you need to write an entry in your fstab file.

The following was written using the information you provided here

UUID=ca4f8997-1a78-417c-acff-a6b18e496711 /.snapshots btrfs subvolid=5,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 0 1
  • Make sure the uuid matches your /
  • Make sure /.snapshots exists (or the one you have chosen)
  • For rootflags option, subvolid=5 is the root of your filesystem, another must be the same as your /

In addition, in /run/timeshift/backup, i have a '@' folder, i guess it's related to timeshift, but i really do not know what is it.

@ is a subvolume hosts your OS.

Because if i start my computer, then i run timeshift (only to mount the snapshots), i still have to restart grub-btrfs.path with systemctl to make it working.

Yes, you have to restart the service, because timeshift creates the mount point, only when launching its applicationn not at boot time.

@Antynea
Copy link
Owner

Antynea commented Jan 26, 2021

I deduced that the grub-btrfs.path service was disabled.
I didn't tell you how to configure it in my previous post, I am waiting to see that everything is understandable to you.

@HanM23
Copy link
Author

HanM23 commented Jan 27, 2021

I think i get it working.
I followed your instructions and grub-btrfs.cgs is regenerated when i create a snapshot manually with CLI. I uninstalled Timeshift because.

Just to be sure of what we are doing here:

By modifying the fstab with:
UUID=ca4f8997-1a78-417c-acff-a6b18e496711 /.snapshots btrfs subvolid=5,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 0 1

--> We are mounting the root filesystem

What is confusing for me is the subvolid=5.

I mean, when i installed Manjaro, in my vanilla fstab i have this line
UUID=ca4f8997-1a78-417c-acff-a6b18e496711 / btrfs subvol=@,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 0 1

I thought this subvolume was the root one, but it does not have ID=5, it has ID=274:

sudo btrfs subvolume list -a -p /
ID 274 gen 1812 parent 5 top level 5 path <FS_TREE>/@
ID 279 gen 1801 parent 5 top level 5 path <FS_TREE>/snap_test

Do you know what's happening here exactly ? I did not find any accurate information on the internet.

Anyway, grub-btrfs.path is working now, it's enabled, activated and the grub file is regenerated when i create a snapshot
Thanks

@Antynea
Copy link
Owner

Antynea commented Jan 27, 2021

What is confusing for me is the subvolid=5.
Do you know what's happening here exactly ? I did not find any accurate information on the internet.

actually from the official BTRFS wiki, it's written that the toplevel subvolid is 5. The quote :

The top-level subvolume (ID5) (which one can think of as the root of the filesystem) can be mounted, and the full filesystem structure will be seen at the mount point; alternatively any other subvolume can be mounted (with the mount options subvol or subvolid, for example subvol=subvol_a) and only anything below that subvolume (in the above example the subvolume subvol_b, it's contents, and file file_4) will be visible at the mount point

Read the documentation quietly, a lot of answers can be found there.

@Antynea
Copy link
Owner

Antynea commented Jan 27, 2021

I uninstalled Timeshift

Now that you have the root of your filesystem mounted at boot time, it is very easy to get systemd.path to work with timeshift.

As I mentioned in a previous post, the snapshots created with timeshift are located at the root of your filesystem in a timeshift-btrfs/snapshots folder.

So for this to work, you need to tell grub-btrfs.path to watch this folder.
This way (in accordance with the informations you provided previously)
systemctl edit grub-btrfs.path

[Path]
PathModified=
PathModified=/.snapshots/timeshift-btrfs/snapshots

@HanM23
Copy link
Author

HanM23 commented Jan 27, 2021

Yes, you are right now what to do with Timeshift.
I think i will keep using CLI to do some different operations on subvolumes and snapshots, it's much more useful like that i think.
Because, we could also say that in this story, Timeshift brought me also some confusion :)

Thanks again for all !

@Kr1ss-XD
Copy link
Contributor

Kr1ss-XD commented Jan 27, 2021

@HanM23

What is confusing for me is the subvolid=5.

I mean, when i installed Manjaro, in my vanilla fstab i have this line
UUID=ca4f8997-1a78-417c-acff-a6b18e496711 / btrfs subvol=@,defaults,noatime,space_cache,ssd,compress=zstd,commit=120 0 1

I thought this subvolume was the root one, but it does not have ID=5, it has ID=274

I think you are confusing the Btrfs root and the "root subvolume" ("@" in the default installation), which is to be mounted at /.

The actual Btrfs root has subvol=/,subvolid=5, all subvolumes are (direct or indirect) children of it. As per @Antynea sugggestion, this actual root is mounted at /.snapshots, while the "root subvolume" is mounted at /, the root of the directory tree.

It's not easy to wrap the head around that, but in a nutshell there are

  1. the actual Btrfs root (on filesystem level), and
  2. the subvolume which is mounted at the / (root) directory.

@HanM23
Copy link
Author

HanM23 commented Jan 27, 2021

That's exactly what i had difficulties with. That is not logical at first, for me at least :)

@Antynea
Copy link
Owner

Antynea commented Jan 29, 2021

Okay,

I think I have found an acceptable solution.
grub-btrfs.path unit isn't written correctly,
it starts during system boot, and doesn't wait for the mount point to be ready.
So you have to rewrite it, that way:

[Unit]
Description=Monitors for new snapshots
DefaultDependencies=no
Requires=run-timeshift-backup.mount
After=run-timeshift-backup.mount
BindsTo=run-timeshift-backup.mount

[Path]
PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots

[Install]
WantedBy=run-timeshift-backup.mount

I used the timeshift mount point in my example.

Some explanations:

  • DefaultDependencies=no
    Prevents systemd from automatically generating Wants= or Requires= or After=.
  • Requires=run-timeshift-backup.mount
    Ensures unit is started if mount point exists.
  • After=run-timeshift-backup.mount
    Here we want the unit to be started after the mount point is existing.
  • BindsTo=run-timeshift-backup.mount
    If the mount point is removed, the unit will stopped and restart automatically when the mount point will be mounted again
  • PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots
    The watched folder containing the snapshots.
  • WantedBy=run-timeshift-backup.mount
    systemd enable will create a symbolic link in /etc/systemd/system/run-timeshift-backup.mount.wants

To be able to modify the default unit provided by grub-btrfs,
make sure that the grub-btrfs.path unit is stopped and disable at boot.

systemctl stop grub-btrfs.path
systemctl disable grub-btrfs.path
then
systemctl edit --full grub-btrfs.path
and
replace the whole block with the block provided in this message.

Now enable and start grub-btrfs.path unit.
Everything should work as expected.

I will create a pull request later.

Edit: to know .mount unit, used systemctl list-units -t mount
Edit2: Adds BindsTo= directive in [Unit] section

@debnath-d
Copy link

* `Requires=run-timeshift-backup.mount`
  Ensures unit is started if mount point exists.
* `BindsTo=run-timeshift-backup.mount`
  If the mount point is removed, the unit will stopped and restart automatically when the mount point will be mounted again

@Antynea, do we need both Requires= and BindsTo=? According to https://man.archlinux.org/man/systemd.unit.5.en#%5BUNIT%5D_SECTION_OPTIONS:

BindsTo=
Configures requirement dependencies, very similar in style to Requires=. However, this dependency type is stronger: in addition to the effect of Requires= it declares that if the unit bound to is stopped, this unit will be stopped too. This means a unit bound to another unit that suddenly enters inactive state will be stopped too. Units can suddenly, unexpectedly enter inactive state for different reasons: the main process of a service unit might terminate on its own choice, the backing device of a device unit might be unplugged or the mount point of a mount unit might be unmounted without involvement of the system and service manager.

@Antynea
Copy link
Owner

Antynea commented Nov 12, 2021

@keyb0ardninja

do we need both Requires= and BindsTo=?

It seems that the Requires= parameter overloads the configuration, and is not needed when the bindsTo parameter is set.
It would be wise to remove the Requires= parameter,
thanks for reporting this.

@danboid
Copy link
Contributor

danboid commented Aug 28, 2022

I'm hoping @Antynea hasn't abandonned this very useful program and that they're otherwise OK?

After reading this thread and a few others, it seems that grub-btrfs.path is no longer a viable option and so the only workable option is to have GRUB be updated on every reboot. The README needs to be updated to reflect this state of affairs.

I tried @Antynea's one-shot service and it didn't work for me. I had to simplify it down to this to get a working grub update on reboot:

[Unit]
Description=Update grub-btrfs.cfg before reboot/shutdown
Before=poweroff.target

[Service]
Type=oneshot
# 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
RemainAfterExit=true
ExecStart=/bin/true
# Update GRUB menu
ExecStop=bash -c 'grub-mkconfig -o /boot/grub/grub.cfg' 

[Install]
WantedBy=multi-user.target

I'd be interested to hear from anyone who has got grub-btrfs.path working with a recent version of timeshift, if it is still possible to use that kind of on demand method still.

@Schievel1
Copy link
Collaborator

Well it’s not the only viable option, you can still do this https://www.lorenzobettini.it/2022/07/timeshift-and-grub-btrfs-in-linux-arch/

@danboid
Copy link
Contributor

danboid commented Aug 29, 2022

Mr Bettini manually runs grub update in that guide, which is what I'm going to do after creating any snapshots because I don't like updating grub on every reboot. Feels wrong to me.

@Schievel1
Copy link
Collaborator

Schievel1 commented Aug 29, 2022

Maybe I don’t understand his blog post that well, I’m tired, but he doesn’t change the grub-btrfs.service file, only the grub-btrfs.path, does he?

the .path is the one that watches the mount point, the .service is the one that actually does fire up the update of the snapshots.
This is the line in the .service file, that checks if a snapshot menu already exists and if so, execs only the grub-btrfs script, if not execs grub-mkconfig:

ExecStart=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'

So as Long as that’s still there it shouldn’t update the whole grub every time

@danboid
Copy link
Contributor

danboid commented Aug 29, 2022

I have followed his instructions exactly as written except for installing timshift-autosnap but they do not work for me, I still have to manually run a grub update for my snapshots to get listed. Debian doesn't package timeshift-autosnap so maybe his guide depends on that being installed too? I am running Debian testing with subvols for / (@) and /home (@home).

As for:

ExecStart=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'

Why are the three variables in that command suffixed with :-? I don't claim to be a scripting expert but I've never seen that before.

@Schievel1
Copy link
Collaborator

Schievel1 commented Aug 29, 2022

That is just a fallback in case the variable does not exist.
In fact you can run this command yourself in a shell to see if it works
${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
Sorry mate, I don't have a systemd install to test things out. But I am pretty sure his guide does not depend on timeshift-autosnap.

@danboid
Copy link
Contributor

danboid commented Aug 29, 2022

@Schievel1

Thanks for your help.

I don't suppose you have write access to the grub-btrfs repo do you? Is this a dead project now, at least is this repo effectively dead now?

It would be good to see the README get updated to give some better guidance around auto updating GRUB on modern distros.

@danboid
Copy link
Contributor

danboid commented Aug 30, 2022

I have got it working now - systemd now auto updates GRUB when I create or delete timeshift snapshots so I have created a guide to getting this configured correctly.

Configuring systemd to update grub after modifying timeshift snapshots

Neither timeshift nor grub-btrfs will update your grub menu after you create or delete any snapshots so we have to manually configure systemd to do this for us, if we want the ability to boot directly into snapshots from GRUB.

First, we must check the base path used to store your timeshift snapshots. Create at least one snapshot with timeshift and then run timeshift --list

# timeshift --list
Mounted '/dev/sda5' at '/run/timeshift/6724/backup'
Device : /dev/sda5
UUID   : fac5f415-21f5-44e9-93a8-c4b6b5687c72
Path   : /run/timeshift/6724/backup
Mode   : BTRFS
Status : OK
1 snapshots, 387.5 GB free

Num     Name                 Tags  Description  
------------------------------------------------------------------------------
0    >  2022-08-30_21-56-43  O

We can see here that the path of the snapshot is /run/timeshift/6724/backup. If you create more snapshots you will notice a similar path used but with a different 4 digit number so from this we can see it is actually /run/timeshift that we want to monitor for new directories / snapshots.

systemd has a function called PathModified that we'll use to monitor /run/timeshift for changes to update grub but we can only use it with dynamically created dirs such as this by creating a new mount point for it. Edit /etc/fstab and add a line like:

UUID=<UUID> /run/timeshift/       btrfs   defaults,noatime  0 0

You must replace <UUID> with the UUID of your btrfs disk that you are snapshotting. After adding the new fstab entry, reboot and run:

# systemctl list-units -t mount
  UNIT                                              LOAD   ACTIVE SUB     DESCRIPTION                              
  ...
  run-timeshift.mount                               loaded active mounted /run/timeshift

To check systemd has registered the new mount point.

Create /etc/systemd/system/update-grub.service with the following contents, after checking grub-mkconfig -o /boot/grub/grub.cfg is the correct command to update GRUB on your OS. If not, adjust it as required:

[Unit]
Description=Regenerate grub menu

[Service]
Type=oneshot
# Regenerate the grub menu
ExecStart=bash -c 'grub-mkconfig -o /boot/grub/grub.cfg' 

Create /etc/systemd/system/grub-btrfs.path with the following contents. Replace every instance of run-timeshift.mount with the name of the systemd mount unit name used for the snapshots if the path / unit name differs on your system:

[Unit]
Description="Monitor /run/timeshift for new snapshots"
DefaultDependencies=no
Requires=run-timeshift.mount
After=run-timeshift.mount
BindsTo=run-timeshift.mount

[Path]
PathModified=/run/timeshift
Unit=update-grub.service

[Install]
WantedBy=run-timeshift.mount

Now by enabling / starting grub-btrfs.path, systemd will update GRUB when snapshots are created or deleted.

systemctl enable grub-btrfs.path
systemctl start grub-btrfs.path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants