From 0102b7f2d7ff1b0b3fecf128a846ee2f5b4ccf9d Mon Sep 17 00:00:00 2001 From: Daniel Langbein Date: Sat, 1 Feb 2025 21:40:51 +0100 Subject: [PATCH] fix: btrfs scrub timer while suspended --- modules/btrfsScrub.nix | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/modules/btrfsScrub.nix b/modules/btrfsScrub.nix index 765f526..c0514e5 100644 --- a/modules/btrfsScrub.nix +++ b/modules/btrfsScrub.nix @@ -14,7 +14,11 @@ # sudo btrfs scrub start / # sudo btrfs scrub status / -{ lib, config, options, pkgs, modulesPath, ... }: +# Print generated systemd unit file +# cat "$(systemctl show -P FragmentPath btrfs-scrub-mnt-backup.timer)" +# cat "$(systemctl show -P FragmentPath btrfs-scrub--.timer)" + +{ lib, config, options, pkgs, modulesPath, utils, ... }: with lib; let cfg = config.yoda.btrfsScrub; @@ -33,10 +37,43 @@ in }; config = mkIf (length cfg > 0) { + # Note: + # The systemd timers generated by `config.btrfs.autoScrub` do not wake the system and have accuracy of `1d`. + # As our system wakes up daily at ~12:05, we want the timers to start at the same time and also wake up the system. + # If they do not wake up the system, the will fail and not be executed for the current time period. + services.btrfs.autoScrub = { enable = true; - interval = "monthly"; + # Important: Wake up at ~ same time as daily-backup-and-suspend.service to avoid system being powered on longer than necessary. + # Value: Each month on the 1st day at 12:00 - 5 minutes before daily-backup-and-suspend + # TODO: Let's see next month if this works. Maybe it doesn't if "resume from suspend" is still not finished when the scrub service is already being started. The latter conflicts with suspend. The idea is that it stops scrubbing when suspend is started. But maybe this prohibits us from "waking up to start scrub service"? We'll find out! + # https://www.freedesktop.org/software/systemd/man/latest/systemd.time.html#Calendar%20Events + interval = "*-*-01 12:00:00"; fileSystems = cfg; }; + + # Copied from the definition of the scrub systemd timer. If the source changes, we have to adapt here as well! + # https://github.com/NixOS/nixpkgs/blob/7ad7702fa8b0d409aaf83eba8be1479b97823cdc/nixos/modules/tasks/filesystems/btrfs.nix#L140-L158 + # TODO: Watch and get notified on changes + systemd.timers = + let + scrubTimer = + fs: + let + fs' = utils.escapeSystemdPath fs; + in + nameValuePair "btrfs-scrub-${fs'}" { + timerConfig = { + # Important: + # Overwrite `1d` with default value `1min`. + AccuracySec = lib.mkForce "1min"; + # Important: + # host-specific.nix -> daily-backup-and-suspend.service + # -> System might be suspended. Without setting this to `true`, the timer would fail. + WakeSystem = true; + }; + }; + in + listToAttrs (map scrubTimer cfg); }; }