summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-09-22 21:04:54 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-09-22 21:39:05 +0200
commitf19065c283f69e44caeddb20fab9051ac52a31ec (patch)
treec86942fcc422b1b5670ac75d7ab671c118721cbe /modules
parentf5c4874b05680237d14aaf4a35b87a9aec74d9e3 (diff)
downloadnixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.tar
nixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.tar.gz
nixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.tar.bz2
nixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.tar.lz
nixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.tar.xz
nixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.tar.zst
nixlib-f19065c283f69e44caeddb20fab9051ac52a31ec.zip
Fix broken systemd shutdown services
The services systemd-random-seed-save.service and
systemd-update-utmp-shutdown.service from systemd 203 don't work,
because they have a RequiresMountFor dependency on /var/lib and
/var/log.  Such a dependency produces a cycle, causing systemd to drop
those services:

  Fixing conflicting jobs by deleting job poweroff.target/stop
  Deleting job systemd-poweroff.service/stop as dependency of job poweroff.target/stop
  Deleting job umount.target/stop as dependency of job systemd-poweroff.service/stop
  Deleting job -.mount/start as dependency of job umount.target/stop
  Deleting job systemd-random-seed-save.service/start as dependency of job -.mount/start
  Deleting job systemd-update-utmp-shutdown.service/start as dependency of job -.mount/start

Dropping the RequiresMountFor doesn't work either, because then
/var/... may have meen unmounted or remounted read-only.

Upstream systemd fixes this by doing the actual work from an ExecStop
action in an already-running service than conflicts with
shutdown.target.  So I backported that here.  The main consequence is
that wtmp shutdown records now get written properly.

The main lesson: shutdown.target is useless for pulling in services
during shutdown if they need to write anywhere.
Diffstat (limited to 'modules')
-rw-r--r--modules/system/boot/systemd-unit-options.nix9
-rw-r--r--modules/system/boot/systemd.nix49
2 files changed, 45 insertions, 13 deletions
diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix
index e3542ce9225a..be3fbd556741 100644
--- a/modules/system/boot/systemd-unit-options.nix
+++ b/modules/system/boot/systemd-unit-options.nix
@@ -76,6 +76,15 @@ rec {
       '';
     };
 
+    conflicts = mkOption {
+      default = [];
+      types = types.listOf types.string;
+      description = ''
+        If the specified units are started, then this unit is stopped
+        and vice versa.
+      '';
+    };
+
     requiredBy = mkOption {
       default = [];
       types = types.listOf types.string;
diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix
index da34d435a3f2..21b3e5e80a03 100644
--- a/modules/system/boot/systemd.nix
+++ b/modules/system/boot/systemd.nix
@@ -73,13 +73,6 @@ let
       "systemd-initctl.socket"
       "systemd-initctl.service"
 
-      # Random seed.
-      "systemd-random-seed-load.service"
-      "systemd-random-seed-save.service"
-
-      # Utmp maintenance.
-      "systemd-update-utmp-shutdown.service"
-
       # Kernel module loading.
       #"systemd-modules-load.service"
 
@@ -158,6 +151,7 @@ let
           Before = concatStringsSep " " config.before;
           BindsTo = concatStringsSep " " config.bindsTo;
           PartOf = concatStringsSep " " config.partOf;
+          Conflicts = concatStringsSep " " config.conflicts;
           "X-Restart-Triggers" = toString config.restartTriggers;
         } // optionalAttrs (config.description != "") {
           Description = config.description;
@@ -600,13 +594,42 @@ in
 
     users.extraGroups.systemd-journal.gid = config.ids.gids.systemd-journal;
 
-    # FIXME: This should no longer be needed with systemd >= 204.
-    systemd.services."systemd-update-utmp-reboot.service" =
-      { description = "Update UTMP about System Reboot";
+    # FIXME: These are borrowed from upstream systemd.
+    systemd.services."systemd-update-utmp" =
+      { description = "Update UTMP about System Reboot/Shutdown";
         wantedBy = [ "sysinit.target" ];
-        unitConfig.DefaultDependencies = false;
-        serviceConfig.Type = "oneshot";
-        serviceConfig.ExecStart = "${systemd}/lib/systemd/systemd-update-utmp reboot";
+        after = [ "systemd-remount-fs.service" ];
+        before = [ "sysinit.target" "shutdown.target" ];
+        conflicts = [ "shutdown.target" ];
+        unitConfig = {
+          DefaultDependencies = false;
+          RequiresMountsFor = "/var/log";
+        };
+        serviceConfig = {
+          Type = "oneshot";
+          RemainAfterExit = true;
+          ExecStart = "${systemd}/lib/systemd/systemd-update-utmp reboot";
+          ExecStop = "${systemd}/lib/systemd/systemd-update-utmp shutdown";
+        };
+        restartIfChanged = false;
+      };
+
+    systemd.services."systemd-random-seed" =
+      { description = "Load/Save Random Seed";
+        wantedBy = [ "sysinit.target" "multi-user.target" ];
+        after = [ "systemd-remount-fs.service" ];
+        before = [ "sysinit.target" "shutdown.target" ];
+        conflicts = [ "shutdown.target" ];
+        unitConfig = {
+          DefaultDependencies = false;
+          RequiresMountsFor = "/var/lib";
+        };
+        serviceConfig = {
+          Type = "oneshot";
+          RemainAfterExit = true;
+          ExecStart = "${systemd}/lib/systemd/systemd-random-seed load";
+          ExecStop = "${systemd}/lib/systemd/systemd-random-seed save";
+        };
       };
 
   };