switch-to-configuration-ng: don't block when the lockfile is already locked (#382797)

This commit is contained in:
Ramses
2025-02-19 11:07:33 +01:00
committed by GitHub
3 changed files with 19 additions and 2 deletions
@@ -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
+17
View File
@@ -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
@@ -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();
};