fix: btrfs scrub timer while suspended

This commit is contained in:
Daniel Langbein 2025-02-01 21:40:51 +01:00
parent 98bd1b5f8b
commit 0102b7f2d7
Signed by: langfingaz
GPG Key ID: 6C47C753F0823002

View File

@ -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);
};
}