Strategies to deal with `renameat(3)` on persisted files
Suppose you have a configuration like this:
{
environment.persistence = {
"/impermanence/safe" = {
directories = [
"/etc/wpa_supplicant.conf"
];
};
}
Now, wpa_supplicant appears to do a rename when writing changes to the config which is state I'd like to keep.
A similar issue also exists for ~/.local/share/recently-used.xbel or .gdbinit.
This doesn't work if only the file is persisted (i.e. bind-mounted) since a rename fails with EBUSY in that case.
There are two kinds of workarounds:
- use symlinks (with #146): works for a few applications, e.g.
gdb. But GTK (forrecently-used.xbel) and wpa_supplicant replace the symlink with a file then. - patch around in the NixOS module to use another config file. For
wpa_supplicantthat was my fix (https://github.com/Ma27/nixpkgs/commit/d90b3eb6f49104b02b02c8296230f6f9d8c11761, note: I useallowAuxiliaryImperativeNetworks). Now I can persist/etc/wpa_supplicant[1] and the move inside works fine. This however is not feasible forrecently-used.xbelwhich seems to be backed into GTK and would cause an excessive amount of rebuilds for me (and I don't really want to use libredirect for ~everything on my desktop).
What I'm wondering is, is there any feasible, generic way that doesn't require us to find solutions per-application? If so, we may want to consider adding those as another alternative into impermanence.
[1] https://docs.gtk.org/gtk4/property.Settings.gtk-recent-files-enabled.html
This isn't optimal, but I think it would work in this situation. If using btrfs subvolumes, on boot (or at least before a lot of services start), you could copy the file into your /persist location, and then copy that over to the actual location.
For example, if this is your persist:
/persist/recently-used.xbel (mtime 4/02)
Then on boot:
/last_boot/home/.../recently-used.xbel (mtime 4/03) -> /persist/recently-used.xbel
/persist/recently-used.xbel (mtime 4/03) -> /home/.../recently-used.xbel
This has the downside of not being persisted until after boot happens again, but on btrfs this copy could be essentially free with --reflink.