summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdrian Pistol <vifino@posteo.net>2023-10-06 14:11:51 +0200
committerAustin Seipp <aseipp@pobox.com>2023-11-15 15:09:22 -0600
commit7a1d45811ea4420dea5b2818c9790a86c18c1170 (patch)
treee4ec066dde38bf1b8d2d600506a34a0f135548e3
parentf356750f6284781cf7a750d2fd39501e161239f1 (diff)
downloadnixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.tar
nixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.tar.gz
nixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.tar.bz2
nixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.tar.lz
nixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.tar.xz
nixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.tar.zst
nixpkgs-7a1d45811ea4420dea5b2818c9790a86c18c1170.zip
nixos/chrony: Let Chrony control/track RTC drift
-rw-r--r--nixos/doc/manual/release-notes/rl-2311.section.md2
-rw-r--r--nixos/modules/services/networking/ntp/chrony.nix39
2 files changed, 40 insertions, 1 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md
index 93abf760b0d..08fd671e2a7 100644
--- a/nixos/doc/manual/release-notes/rl-2311.section.md
+++ b/nixos/doc/manual/release-notes/rl-2311.section.md
@@ -373,6 +373,8 @@
 
 - The `prayer` package as well as `services.prayer` have been removed because it's been unmaintained for several years and the author's website has vanished.
 
+- The `chrony` NixOS module now tracks the Real-Time Clock drift from the System Clock with `rtcfile` and automatically adjusts it with `rtcautotrim` when it exceeds the maximum error specified in `services.chrony.autotrimThreshold` (default 30 seconds). If you enabled `rtcsync` in `extraConfig`, you should remove RTC related options from `extraConfig`. If you do not want chrony configured to keep the RTC in check, you can set `services.chrony.enableRTCTrimming = false;`
+
 ## Other Notable Changes {#sec-release-23.11-notable-changes}
 
 - A new option `system.switch.enable` was added. By default, this is option is
diff --git a/nixos/modules/services/networking/ntp/chrony.nix b/nixos/modules/services/networking/ntp/chrony.nix
index afd721e34da..d370e6946d7 100644
--- a/nixos/modules/services/networking/ntp/chrony.nix
+++ b/nixos/modules/services/networking/ntp/chrony.nix
@@ -9,6 +9,7 @@ let
   stateDir = cfg.directory;
   driftFile = "${stateDir}/chrony.drift";
   keyFile = "${stateDir}/chrony.keys";
+  rtcFile = "${stateDir}/chrony.rtc";
 
   configFile = pkgs.writeText "chrony.conf" ''
     ${concatMapStringsSep "\n" (server: "server " + server + " " + cfg.serverOption + optionalString (cfg.enableNTS) " nts") cfg.servers}
@@ -20,8 +21,10 @@ let
 
     driftfile ${driftFile}
     keyfile ${keyFile}
+    ${optionalString (cfg.enableRTCTrimming) "rtcfile ${rtcFile}"}
     ${optionalString (cfg.enableNTS) "ntsdumpdir ${stateDir}"}
 
+    ${optionalString (cfg.enableRTCTrimming) "rtcautotrim ${builtins.toString cfg.autotrimThreshold}"}
     ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"}
 
     ${cfg.extraConfig}
@@ -85,6 +88,33 @@ in
         '';
       };
 
+      enableRTCTrimming = mkOption {
+        type = types.bool;
+        default = true;
+        description = lib.mdDoc ''
+          Enable tracking of the RTC offset to the system clock and automatic trimming.
+          See also [](#opt-services.chrony.autotrimThreshold)
+
+          ::: {.note}
+          This is not compatible with the `rtcsync` directive, which naively syncs the RTC time every 11 minutes.
+
+          Tracking the RTC drift will allow more precise timekeeping,
+          especially on intermittently running devices, where the RTC is very relevant.
+          :::
+        '';
+      };
+
+      autotrimThreshold = mkOption {
+        type = types.ints.positive;
+        default = 30;
+        example = 10;
+        description = ''
+          Maximum estimated error threshold for the `rtcautotrim` command.
+          When reached, the RTC will be trimmed.
+          Only used when [](#opt-services.chrony.enableRTCTrimming) is enabled.
+        '';
+      };
+
       enableNTS = mkOption {
         type = types.bool;
         default = false;
@@ -141,7 +171,7 @@ in
   };
 
   config = mkIf cfg.enable {
-    meta.maintainers = with lib.maintainers; [ thoughtpolice ];
+    meta.maintainers = with lib.maintainers; [ thoughtpolice vifino ];
 
     environment.systemPackages = [ chronyPkg ];
 
@@ -156,12 +186,19 @@ in
 
     services.timesyncd.enable = mkForce false;
 
+    # If chrony controls and tracks the RTC, writing it externally causes clock error.
+    systemd.services.save-hwclock = lib.mkIf cfg.enableRTCTrimming {
+      enable = lib.mkForce false;
+    };
+
     systemd.services.systemd-timedated.environment = { SYSTEMD_TIMEDATED_NTP_SERVICES = "chronyd.service"; };
 
     systemd.tmpfiles.rules = [
       "d ${stateDir} 0750 chrony chrony - -"
       "f ${driftFile} 0640 chrony chrony - -"
       "f ${keyFile} 0640 chrony chrony - -"
+    ] ++ lib.optionals cfg.enableRTCTrimming [
+      "f ${rtcFile} 0640 chrony chrony - -"
     ];
 
     systemd.services.chronyd =