about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-09-16 16:51:19 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-09-16 16:51:19 +0200
commitb20a0e49c8c0d5c84b917bfbbe3f2ead31886a67 (patch)
treed0dfa0624afb1c1f567001547fe4e558c08a0f8b /nixos
parentb9ed9c7fed0d1aeae42ac382d6fefff65563e81d (diff)
Revert systemd interface version to 2
The new systemd in 19.09 gives an "Access Denied" error when doing
"systemctl daemon-reexec" on an 19.03 system. The fix is to use the
previous systemctl to signal the daemon to re-exec itself. This
ensures that users don't have to reboot when upgrading from NixOS
19.03 to 19.09.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl19
1 files changed, 13 insertions, 6 deletions
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index 8ff00fa11dc75..641cf9faadc97 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -10,6 +10,9 @@ use Cwd 'abs_path';
 
 my $out = "@out@";
 
+# FIXME: maybe we should use /proc/1/exe to get the current systemd.
+my $curSystemd = abs_path("/run/current-system/sw/bin");
+
 # To be robust against interruption, record what units need to be started etc.
 my $startListFile = "/run/systemd/start-list";
 my $restartListFile = "/run/systemd/restart-list";
@@ -267,7 +270,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
 sub pathToUnitName {
     my ($path) = @_;
     # Use current version of systemctl binary before daemon is reexeced.
-    open my $cmd, "-|", "/run/current-system/sw/bin/systemd-escape", "--suffix=mount", "-p", $path
+    open my $cmd, "-|", "$curSystemd/systemd-escape", "--suffix=mount", "-p", $path
         or die "Unable to escape $path!\n";
     my $escaped = join "", <$cmd>;
     chomp $escaped;
@@ -370,7 +373,7 @@ if (scalar (keys %unitsToStop) > 0) {
     print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
         if scalar @unitsToStopFiltered;
     # Use current version of systemctl binary before daemon is reexeced.
-    system("/run/current-system/sw/bin/systemctl", "stop", "--", sort(keys %unitsToStop)); # FIXME: ignore errors?
+    system("$curSystemd/systemctl", "stop", "--", sort(keys %unitsToStop)); # FIXME: ignore errors?
 }
 
 print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
@@ -382,10 +385,12 @@ my $res = 0;
 print STDERR "activating the configuration...\n";
 system("$out/activate", "$out") == 0 or $res = 2;
 
-# Restart systemd if necessary.
+# Restart systemd if necessary. Note that this is done using the
+# current version of systemd, just in case the new one has trouble
+# communicating with the running pid 1.
 if ($restartSystemd) {
     print STDERR "restarting systemd...\n";
-    system("@systemd@/bin/systemctl", "daemon-reexec") == 0 or $res = 2;
+    system("$curSystemd/systemctl", "daemon-reexec") == 0 or $res = 2;
 }
 
 # Forget about previously failed services.
@@ -401,8 +406,10 @@ while (my $f = <$listActiveUsers>) {
     my ($uid, $name) = ($+{uid}, $+{user});
     print STDERR "reloading user units for $name...\n";
 
-    system("@su@", "-s", "@shell@", "-l", $name, "-c", "XDG_RUNTIME_DIR=/run/user/$uid @systemd@/bin/systemctl --user daemon-reload");
-    system("@su@", "-s", "@shell@", "-l", $name, "-c", "XDG_RUNTIME_DIR=/run/user/$uid @systemd@/bin/systemctl --user start nixos-activation.service");
+    system("@su@", "-s", "@shell@", "-l", $name, "-c",
+           "export XDG_RUNTIME_DIR=/run/user/$uid; " .
+           "$curSystemd/systemctl --user daemon-reexec; " .
+           "@systemd@/bin/systemctl --user start nixos-activation.service");
 }
 
 close $listActiveUsers;