idiosyn/modules/btrfs.nix
2024-07-22 09:19:05 +02:00

94 lines
2.7 KiB
Nix

{ 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";
};
};
};
}