{ config, lib, pkgs, ... }: let inherit (lib) optionalString mkOption types; cfg = config.idiosyn.btrfs; btrfs-scrub = pkgs.writeShellApplication { name = "btrfs-scrub"; runtimeInputs = with pkgs; [ util-linux btrfs-progs ]; text = '' findmnt --noheadings --output "SOURCE" --types btrfs --nofsroot | sort -u \ | xargs -n 1 -P "$(nproc)" -r btrfs scrub start -B ''; }; btrfs-balance = pkgs.writeShellApplication { name = "btrfs-balance"; runtimeInputs = with pkgs; [ util-linux btrfs-progs ]; text = '' findmnt --types btrfs --output "SOURCE" --nofsroot --noheading | sort -u \ | xargs -n 1 -r findmnt --first-only --noheadings --output "TARGET" --types btrfs --source \ | xargs -n 1 -P "$(nproc)" -r btrfs balance start${optionalString (cfg.balance.dataUsage != null) " -dusage=${toString cfg.balance.dataUsage}"}${optionalString (cfg.balance.metadataUsage != null) " -musage=${toString cfg.balance.metadataUsage}"} ''; }; in { options = { idiosyn.btrfs = { scrub.timer = mkOption { type = with types; nullOr nonEmptyStr; default = null; example = "weekly"; description = '' Realtime (wallclock) timer for regular scrubs See {manpage}systemd.time(7). ''; }; balance = { timer = mkOption { type = with types; nullOr nonEmptyStr; default = null; example = "weekly"; description = '' Realtime (wallclock) timer for regular balances. See {manpage}systemd.time(7). ''; }; dataUsage = mkOption { type = with types; nullOr (ints.between 0 100); default = 10; description = '' Balance only data block groups with usage below the given percentage. ''; }; metadataUsage = mkOption { type = with types; nullOr (ints.between 0 100); default = 5; description = '' Balance only metadata block groups with usage below the given percentage. ''; }; }; }; }; config = { systemd.services.btrfs-scrub = lib.mkIf (cfg.scrub.timer != null) { startAt = cfg.scrub.timer; unitConfig.ConditionACPower = true; serviceConfig = { Type = "exec"; ExecStart = "${btrfs-scrub}/bin/btrfs-scrub"; }; }; systemd.services.btrfs-balance = lib.mkIf (cfg.balance.timer != null) { startAt = cfg.balance.timer; unitConfig.ConditionACPower = true; serviceConfig = { Type = "exec"; ExecStart = "${btrfs-balance}/bin/btrfs-balance"; }; }; }; }