about summary refs log tree commit diff
path: root/nixos/modules/system/activation/switch-to-configuration.pl
diff options
context:
space:
mode:
authorOliver Charles <ollie@ocharles.org.uk>2014-04-20 19:17:05 +0100
committerOliver Charles <ollie@ocharles.org.uk>2014-04-20 19:17:05 +0100
commit42ae633445a72c4673b4abc3e214a2ddc8227724 (patch)
tree0b19dfa036d81786f15348a60d31dbdefbacf986 /nixos/modules/system/activation/switch-to-configuration.pl
parent41775167ac69a001f40c11e2ee9576887e17b8b4 (diff)
parent31a94915d2532273e3630206a9e13f2e49ce0775 (diff)
downloadnixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.tar
nixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.tar.gz
nixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.tar.bz2
nixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.tar.lz
nixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.tar.xz
nixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.tar.zst
nixlib-42ae633445a72c4673b4abc3e214a2ddc8227724.zip
Merge branch 'master' into dbus-switch-to-configuration
Conflicts:
	nixos/modules/system/activation/switch-to-configuration.pl
Diffstat (limited to 'nixos/modules/system/activation/switch-to-configuration.pl')
-rw-r--r--nixos/modules/system/activation/switch-to-configuration.pl34
1 files changed, 27 insertions, 7 deletions
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index 91beed1130eb..25b5afe99da4 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -27,7 +27,10 @@ EOF
     exit 1;
 }
 
-die "This is not a NixOS installation (/etc/NIXOS is missing)!\n" unless -f "/etc/NIXOS";
+# This is a NixOS installation if it has /etc/NIXOS or a proper
+# /etc/os-release.
+die "This is not a NixOS installation!\n" unless
+    -f "/etc/NIXOS" || (read_file("/etc/os-release", err_mode => 'quiet') // "") =~ /ID=nixos/s;
 
 openlog("nixos", "", LOG_USER);
 
@@ -96,12 +99,18 @@ sub parseFstab {
 sub parseUnit {
     my ($filename) = @_;
     my $info = {};
-    foreach my $line (read_file($filename)) {
+    parseKeyValues($info, read_file($filename));
+    parseKeyValues($info, read_file("${filename}.d/overrides.conf")) if -f "${filename}.d/overrides.conf";
+    return $info;
+}
+
+sub parseKeyValues {
+    my $info = shift;
+    foreach my $line (@_) {
         # FIXME: not quite correct.
         $line =~ /^([^=]+)=(.*)$/ or next;
         $info->{$1} = $2;
     }
-    return $info;
 }
 
 sub boolIsTrue {
@@ -109,6 +118,14 @@ sub boolIsTrue {
     return $s eq "yes" || $s eq "true";
 }
 
+# As a fingerprint for determining whether a unit has changed, we use
+# its absolute path. If it has an override file, we append *its*
+# absolute path as well.
+sub fingerprintUnit {
+    my ($s) = @_;
+    return abs_path($s) . (-f "${s}.d/overrides.conf" ? " " . abs_path "${s}.d/overrides.conf" : "");
+}
+
 # Stop all services that no longer exist or have changed in the new
 # configuration.
 my (@unitsToStop, @unitsToSkip);
@@ -125,7 +142,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
     $baseName =~ s/\.[a-z]*$//;
 
     if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
-        if (! -e $newUnitFile) {
+        if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
             push @unitsToStop, $unit;
         }
 
@@ -160,7 +177,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
             }
         }
 
-        elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
+        elsif (fingerprintUnit($prevUnitFile) ne fingerprintUnit($newUnitFile)) {
             if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") {
                 # Do nothing.  These cannot be restarted directly.
             } elsif ($unit =~ /\.mount$/) {
@@ -170,7 +187,10 @@ while (my ($unit, $state) = each %{$activePrev}) {
                 # FIXME: do something?
             } else {
                 my $unitInfo = parseUnit($newUnitFile);
-                if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes")) {
+                if (boolIsTrue($unitInfo->{'X-ReloadIfChanged'} // "no")) {
+                    write_file($reloadListFile, { append => 1 }, "$unit\n");
+                }
+                elsif (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes")) {
                     push @unitsToSkip, $unit;
                 } else {
                     # If this unit is socket-activated, then stop the
@@ -319,7 +339,7 @@ if (scalar @restart > 0) {
 # that are symlinks to other units.  We shouldn't start both at the
 # same time because we'll get a "Failed to add path to set" error from
 # systemd.
-my @start = unique("default.target", "timers.target", split('\n', read_file($startListFile, err_mode => 'quiet') // ""));
+my @start = unique("default.target", "timers.target", "sockets.target", split('\n', read_file($startListFile, err_mode => 'quiet') // ""));
 print STDERR "starting the following units: ", join(", ", sort(@start)), "\n";
 $systemdManager->StartUnit($_, "replace") for @start;
 unlink($startListFile);