From 92cbe52e19c42ba606b040bee5933dd35b0e8267 Mon Sep 17 00:00:00 2001 From: hyperfekt Date: Tue, 25 May 2021 23:52:46 +0200 Subject: nixos/filesystems: condition mount-pstore.service on pstore module systemd's modprobe@.service does not require success so mount-pstore executed despite a non-present pstore module, leading to an error about the /sys/fs/pstore mountpoint not existing on CONFIG_PSTORE=n systems. --- nixos/modules/tasks/filesystems.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 065d6cc95d1..330facdca63 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -309,6 +309,8 @@ in "mount-pstore" = { serviceConfig = { Type = "oneshot"; + # skip on kernels without the pstore module + ExecCondition = "${pkgs.kmod}/bin/modprobe -b pstore"; ExecStart = "${pkgs.util-linux}/bin/mount -t pstore -o nosuid,noexec,nodev pstore /sys/fs/pstore"; ExecStartPost = pkgs.writeShellScript "wait-for-pstore.sh" '' set -eu @@ -325,8 +327,6 @@ in ConditionVirtualization = "!container"; DefaultDependencies = false; # needed to prevent a cycle }; - after = [ "modprobe@pstore.service" ]; - requires = [ "modprobe@pstore.service" ]; before = [ "systemd-pstore.service" ]; wantedBy = [ "systemd-pstore.service" ]; }; -- cgit 1.4.1 From af871f619ca3ae8c162436e723241e995b088dd6 Mon Sep 17 00:00:00 2001 From: hyperfekt Date: Sun, 30 May 2021 03:29:52 +0200 Subject: nixos/filesystems: await builtin pstore module backend in mount-pstore If the pstore module is builtin, it nonetheless can take considerable time to register a backend despite /sys/fs/pstore already appearing mounted, so the condition is moved into the main script to extend waiting for the backend to this case. --- nixos/modules/tasks/filesystems.nix | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 330facdca63..49c9a37a900 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -305,25 +305,30 @@ in in listToAttrs (map formatDevice (filter (fs: fs.autoFormat) fileSystems)) // { # Mount /sys/fs/pstore for evacuating panic logs and crashdumps from persistent storage onto the disk using systemd-pstore. # This cannot be done with the other special filesystems because the pstore module (which creates the mount point) is not loaded then. - # Since the pstore filesystem is usually empty right after mounting because the backend isn't registered yet, and a path unit cannot detect files inside of it, the same service waits for that to happen. systemd's restart mechanism can't be used here because the first failure also fails all dependent units. "mount-pstore" = { serviceConfig = { Type = "oneshot"; # skip on kernels without the pstore module ExecCondition = "${pkgs.kmod}/bin/modprobe -b pstore"; - ExecStart = "${pkgs.util-linux}/bin/mount -t pstore -o nosuid,noexec,nodev pstore /sys/fs/pstore"; - ExecStartPost = pkgs.writeShellScript "wait-for-pstore.sh" '' + ExecStart = pkgs.writeShellScript "mount-pstore.sh" '' set -eu - TRIES=0 - while [ $TRIES -lt 20 ] && [ "$(cat /sys/module/pstore/parameters/backend)" = "(null)" ]; do - sleep 0.1 - TRIES=$((TRIES+1)) + # if the pstore module is builtin it will have mounted the persistent store automatically. it may also be already mounted for other reasons. + ${pkgs.util-linux}/bin/mountpoint -q /sys/fs/pstore || ${pkgs.util-linux}/bin/mount -t pstore -o nosuid,noexec,nodev pstore /sys/fs/pstore + # wait up to five seconds (arbitrary, happened within one in testing) for the backend to be registered and the files to appear. a systemd path unit cannot detect this happening; and succeeding after a restart would not start dependent units. + TRIES=50 + while [ "$(cat /sys/module/pstore/parameters/backend)" = "(null)" ]; do + if (( $TRIES )); then + sleep 0.1 + TRIES=$((TRIES-1)) + else + echo "Persistent Storage backend was not registered in time." >&2 + exit 1 + fi done ''; RemainAfterExit = true; }; unitConfig = { - ConditionPathIsMountPoint = "!/sys/fs/pstore"; ConditionVirtualization = "!container"; DefaultDependencies = false; # needed to prevent a cycle }; -- cgit 1.4.1