summary refs log tree commit diff
diff options
context:
space:
mode:
authorJanne Heß <janne@hess.ooo>2022-03-06 19:38:51 +0100
committerJanne Heß <janne@hess.ooo>2022-03-11 13:30:03 +0100
commit3052d3aa50674f2cfeee7c7ddf42c36d84013e48 (patch)
tree51da9c4afed7903e4ade35bf568fd64e68a53f66
parentc96180c53fcd4f36a7163c3e59a2e6bcd9233f06 (diff)
downloadnixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.tar
nixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.tar.gz
nixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.tar.bz2
nixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.tar.lz
nixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.tar.xz
nixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.tar.zst
nixpkgs-3052d3aa50674f2cfeee7c7ddf42c36d84013e48.zip
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.
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl12
1 files 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;