diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index 672291541d03..8eee52bfa332 100755 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -95,7 +95,7 @@ if (!-f "/etc/NIXOS" && (read_file("/etc/os-release", err_mode => "quiet") // "" make_path("/run/nixos", { mode => oct(755) }); open(my $stc_lock, '>>', '/run/nixos/switch-to-configuration.lock') or die "Could not open lock - $!"; -flock($stc_lock, LOCK_EX) or die "Could not acquire lock - $!"; +flock($stc_lock, LOCK_EX|LOCK_NB) or die "Could not acquire lock - $!"; openlog("nixos", "", LOG_USER); # run pre-switch checks diff --git a/nixos/tests/switch-test.nix b/nixos/tests/switch-test.nix index 4ad08b726bf5..ba1a6f329cd3 100644 --- a/nixos/tests/switch-test.nix +++ b/nixos/tests/switch-test.nix @@ -732,6 +732,23 @@ in { out = switch_to_specialisation("${machine}", "modifiedSystemConf") assert_contains(out, "starting the following units: ${dbusService}\n") + with subtest("aborts on already locked lock file"): + (exitcode, _) = machine.execute( + 'flock -x --nb /run/nixos/switch-to-configuration.lock -c "${otherSystem}/bin/switch-to-configuration test"', + timeout=5 + ) + # See man timeout, exit codes above 124 come from the timeout command + # We want to make sure that stc actually exited with an error code, + # if instead we hit the timeout, then it means that stc hangs, which is + # what we don't want + # TODO: We cannot match on the exact exit code since it's not consistent between + # stc and stc-ng, since errno/last_os_error is not a very stable interface, + # we should probably get rid of that in stc-ng once we got rid of the + # perl implementation + assert exitcode < 124, \ + "switch-to-configuration did not abort as expected, " + \ + f"probably it timed out instead (exit code: {exitcode}), 124 means timeout" + with subtest("fstab mounts"): switch_to_specialisation("${machine}", "") # add a mountpoint diff --git a/pkgs/by-name/sw/switch-to-configuration-ng/src/src/main.rs b/pkgs/by-name/sw/switch-to-configuration-ng/src/src/main.rs index a64d8566225b..64fc71e85aed 100644 --- a/pkgs/by-name/sw/switch-to-configuration-ng/src/src/main.rs +++ b/pkgs/by-name/sw/switch-to-configuration-ng/src/src/main.rs @@ -1037,7 +1037,7 @@ fn do_system_switch(action: Action) -> anyhow::Result<()> { die(); }; - let Ok(_lock) = Flock::lock(lock, FlockArg::LockExclusive) else { + let Ok(_lock) = Flock::lock(lock, FlockArg::LockExclusiveNonblock) else { eprintln!("Could not acquire lock"); die(); };