diff --git a/hosts/common/fs.nix b/hosts/common/fs.nix index b1603e8f7..38e26d1fb 100644 --- a/hosts/common/fs.nix +++ b/hosts/common/fs.nix @@ -153,32 +153,63 @@ let systemd.mounts = let fsEntry = config.fileSystems."${localPath}"; in [{ - bindsTo = [ "${systemdName}.service" ]; where = localPath; what = fsEntry.device; type = fsEntry.fsType; options = lib.concatStringsSep "," fsEntry.options; + + # bindsTo X: when X is stopped, or exits, causes this unit to also be stopped. also, causes X to be started when this unit is started. + # bindsTo = [ "${systemdName}.service" ]; + # startLimitBurst = 2; + # startLimitIntervalSec = 120; + onSuccess = [ "${systemdName}-trigger.service" ]; }]; + systemd.services."${systemdName}-trigger" = { + description = "re-establish the mount to ${localPath}"; + conflicts = [ "${systemdName}.service" ]; + before = [ "${systemdName}.service" ]; #< XXX: "that to ensure that the conflicting unit is stopped before the other unit is started, an After= or Before= dependency must be declared. It doesn't matter which of the two ordering dependencies is used, because stop jobs are always ordered before start jobs" (man systemd.unit) + onSuccess = [ "${systemdName}.service" ]; + serviceConfig.Type = "oneshot"; + serviceConfig.ExecStart = lib.getExe' pkgs.coreutils "true"; + }; systemd.services."${systemdName}" = { - description = "re-mount ${localPath} when it fails"; - after = [ "network-online.target" ]; - requires = [ "network-online.target" ]; - wantedBy = [ "default.target" ]; - - partOf = [ "${systemdName}.mount" ]; - upholds = [ "${systemdName}.mount" ]; - requiredBy = [ "${systemdName}.mount" ]; - - serviceConfig.Type = "simple"; - # serviceConfig.ExecStartPre = "${lib.getExe' pkgs.systemd "systemctl"} start ${systemdName}.mount"; - # serviceConfig.ExecStop = "${lib.getExe' pkgs.systemd "systemctl"} stop ${systemdName}.mount"; - serviceConfig.ExecStart = "${lib.getExe' pkgs.coreutils "sleep"} infinity"; - - serviceConfig.Restart = "always"; + # TODO: remove the trigger, and use `bindsTo = ${systemdName}.mount` here. + # unitConfig.RequiresMountsFor = [ localPath ]; + serviceConfig.Restart = "on-failure"; serviceConfig.RestartSec = "10s"; serviceConfig.RestartMaxDelaySec = "120s"; serviceConfig.RestartSteps = "5"; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + serviceConfig.ExecStart = "${lib.getExe' pkgs.systemd "systemctl"} start ${systemdName}.mount"; + # serviceConfig.Type = "simple"; + # serviceConfig.ExecStart = "${lib.getExe' pkgs.coreutils "sleep"} infinity"; }; + # systemd.services."${systemdName}" = { + # description = "re-mount ${localPath} when it fails"; + # after = [ "network-online.target" ]; + # requires = [ "network-online.target" ]; + # wantedBy = [ "default.target" ]; + + # # partOf X: when X is *explicitly* stopped or restarted, this unit is also stopped/restarted. + # # partOf = [ "${systemdName}.mount" ]; + # # upholds X: as long as this unit is active, X will be started any time it's found to be inactive or failed (immediately). + # upholds = [ "${systemdName}.mount" ]; + # # requiredBy X: when X is started, this unit is caused to be started, and when this unit is *explicitly* stopped, then X will be stopped. + # # requiredBy = [ "${systemdName}.mount" ]; + # # bindsTo X: when X is stopped, or exits, causes this unit to also be stopped. also, causes X to be started when this unit is started. + # # bindsTo = [ "${systemdName}.mount" ]; + + # serviceConfig.Type = "simple"; + # # serviceConfig.ExecStartPre = "${lib.getExe' pkgs.systemd "systemctl"} start ${systemdName}.mount"; + # # serviceConfig.ExecStop = "${lib.getExe' pkgs.systemd "systemctl"} stop ${systemdName}.mount"; + # serviceConfig.ExecStart = "${lib.getExe' pkgs.coreutils "sleep"} infinity"; + + # serviceConfig.Restart = "always"; + # serviceConfig.RestartSec = "10s"; + # serviceConfig.RestartMaxDelaySec = "120s"; + # serviceConfig.RestartSteps = "5"; + # }; # systemd.services."automount-servo-${utils.escapeSystemdPath subdir}" = let # fs = config.fileSystems."/mnt/servo/${subdir}"; # in {