diff --git a/nixos/tests/switch-test.nix b/nixos/tests/switch-test.nix index 63dc78e2e6dc..b81d84086f2e 100644 --- a/nixos/tests/switch-test.nix +++ b/nixos/tests/switch-test.nix @@ -541,6 +541,12 @@ in systemd.services."accept-socket@".serviceConfig.X-Test = "test"; }; + socket-activated-without-socket.configuration = { + imports = [ simple-socket.configuration ]; + systemd.sockets.socket-activated.enable = false; + systemd.services.socket-activated.wantedBy = [ "multi-user.target" ]; + }; + mount.configuration = { systemd.mounts = [ { @@ -1620,6 +1626,18 @@ in if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": raise Exception("Socket was not properly activated after the service was restarted") + # A service transitioning to socket activation is not started directly, + # it's left for the newly started socket to activate on demand + switch_to_specialisation("${machine}", "socket-activated-without-socket") + machine.succeed("systemctl is-active socket-activated.service") + out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed") + assert_contains(out, "stopping the following units: socket-activated.service\n") + assert_lacks(out, "\nstarting the following units:") + assert_contains(out, "the following new units were started: socket-activated.socket\n") + machine.succeed("[ -S /run/test.sock ]") + if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": + raise Exception("Socket was not properly activated after the transition") + with subtest("socket-activated services with Accept=yes"): # Socket-activated services don't get started, just the socket machine.fail("[ -S /run/accept-test.sock ]") diff --git a/pkgs/by-name/sw/switch-to-configuration-ng/src/main.rs b/pkgs/by-name/sw/switch-to-configuration-ng/src/main.rs index 6dd05161628f..db6009945e9c 100644 --- a/pkgs/by-name/sw/switch-to-configuration-ng/src/main.rs +++ b/pkgs/by-name/sw/switch-to-configuration-ng/src/main.rs @@ -743,11 +743,6 @@ fn handle_modified_unit( // This unit should be restarted instead of stopped and started. units_to_restart.insert(unit.to_string(), ()); record_unit(&restart_list, unit); - // Remove from units to reload so we don't restart and reload - if units_to_reload.contains_key(unit) { - units_to_reload.remove(unit); - unrecord_unit(&reload_list, unit); - } } else { // If this unit is socket-activated, then stop the socket unit(s) as well, and // restart the socket(s) instead of the service. @@ -777,6 +772,9 @@ fn handle_modified_unit( } for socket in &sockets { + let socket_in_new_config = + toplevel.join(scope.etc_dir()).join(socket).exists(); + if active_cur.contains_key(socket) { // We can now be sure this is a socket-activated unit @@ -787,7 +785,7 @@ fn handle_modified_unit( } // Only restart sockets that actually exist in new configuration: - if toplevel.join(scope.etc_dir()).join(socket).exists() { + if socket_in_new_config { if use_restart_as_stop_and_start { units_to_restart.insert(socket.to_string(), ()); record_unit(&restart_list, socket); @@ -798,12 +796,9 @@ fn handle_modified_unit( socket_activated = true; } - - // Remove from units to reload so we don't restart and reload - if units_to_reload.contains_key(unit) { - units_to_reload.remove(unit); - unrecord_unit(&reload_list, unit); - } + } else if socket_in_new_config { + // Transitioning to socket activation; let the socket start it. + socket_activated = true; } } } @@ -832,11 +827,11 @@ fn handle_modified_unit( } else { units_to_stop.insert(unit.to_string(), ()); } - // Remove from units to reload so we don't restart and reload - if units_to_reload.contains_key(unit) { - units_to_reload.remove(unit); - unrecord_unit(&reload_list, unit); - } + } + + // Remove from units to reload so we don't restart and reload + if units_to_reload.remove(unit).is_some() { + unrecord_unit(&reload_list, unit); } } }