From 3052d3aa50674f2cfeee7c7ddf42c36d84013e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Sun, 6 Mar 2022 19:38:51 +0100 Subject: [PATCH] nixos/switch-to-configuration: Fix restarting by activation script This bug is so obscure and unlikely that I was honestly not able to properly write a test for it. What happens is that we are calling handleModifiedUnit() with $unitsToStart=\%unitsToRestart. We do this to make sure that the unit is stopped before it's started again which is not possible by regular means because the stop phase is already done when calling the activation script. recordUnit() still gets $startListFile, however which is the wrong file. The bug would be triggered if an activation script requests a service restart for a service that has `stopIfChanged = true` and switch-to-configuration is killed before the restart phase was run. If the script is run again, but the activation script is not requesting more restarts, the unit would be started instead of restarted. --- .../system/activation/switch-to-configuration.pl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index ca45fc9c286..a67a9b05778 100644 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -392,7 +392,11 @@ sub handleModifiedUnit { # exist in new configuration: if (-e "$out/etc/systemd/system/$socket") { $unitsToStart->{$socket} = 1; - recordUnit($startListFile, $socket); + if ($unitsToStart eq $unitsToRestart) { + recordUnit($restartListFile, $socket); + } else { + recordUnit($startListFile, $socket); + } $socket_activated = 1; } # Remove from units to reload so we don't restart and reload @@ -410,7 +414,11 @@ sub handleModifiedUnit { # service gets restarted if we're interrupted. if (!$socket_activated) { $unitsToStart->{$unit} = 1; - recordUnit($startListFile, $unit); + if ($unitsToStart eq $unitsToRestart) { + recordUnit($restartListFile, $unit); + } else { + recordUnit($startListFile, $unit); + } } $unitsToStop->{$unit} = 1;