1# Unit handling {#sec-unit-handling} 2 3To figure out what units need to be started/stopped/restarted/reloaded, the 4script first checks the current state of the system, similar to what `systemctl 5list-units` shows. For each of the units, the script goes through the following 6checks: 7 8- Is the unit file still in the new system? If not, **stop** the service unless 9 it sets `X-StopOnRemoval` in the `[Unit]` section to `false`. 10 11- Is it a `.target` unit? If so, **start** it unless it sets 12 `RefuseManualStart` in the `[Unit]` section to `true` or `X-OnlyManualStart` 13 in the `[Unit]` section to `true`. Also **stop** the unit again unless it 14 sets `X-StopOnReconfiguration` to `false`. 15 16- Are the contents of the unit files different? They are compared by parsing 17 them and comparing their contents. If they are different but only 18 `X-Reload-Triggers` in the `[Unit]` section is changed, **reload** the unit. 19 The NixOS module system allows setting these triggers with the option 20 [systemd.services.\<name\>.reloadTriggers](#opt-systemd.services). There are 21 some additional keys in the `[Unit]` section that are ignored as well. If the 22 unit files differ in any way, the following actions are performed: 23 24 - `.path` and `.slice` units are ignored. There is no need to restart them 25 since changes in their values are applied by systemd when systemd is 26 reloaded. 27 28 - `.mount` units are **reload**ed if only their `Options` changed. If anything 29 else changed (like `What`), they are **restart**ed unless they are the mount 30 unit for `/` or `/nix` in which case they are reloaded to prevent the system 31 from crashing. Note that this is the case for `.mount` units and not for 32 mounts from `/etc/fstab`. These are explained in [](#sec-switching-systems). 33 34 - `.socket` units are currently ignored. This is to be fixed at a later 35 point. 36 37 - The rest of the units (mostly `.service` units) are then **reload**ed if 38 `X-ReloadIfChanged` in the `[Service]` section is set to `true` (exposed 39 via [systemd.services.\<name\>.reloadIfChanged](#opt-systemd.services)). 40 A little exception is done for units that were deactivated in the meantime, 41 for example because they require a unit that got stopped before. These 42 are **start**ed instead of reloaded. 43 44 - If the reload flag is not set, some more flags decide if the unit is 45 skipped. These flags are `X-RestartIfChanged` in the `[Service]` section 46 (exposed via 47 [systemd.services.\<name\>.restartIfChanged](#opt-systemd.services)), 48 `RefuseManualStop` in the `[Unit]` section, and `X-OnlyManualStart` in the 49 `[Unit]` section. 50 51 - Further behavior depends on the unit having `X-StopIfChanged` in the 52 `[Service]` section set to `true` (exposed via 53 [systemd.services.\<name\>.stopIfChanged](#opt-systemd.services)). This is 54 set to `true` by default and must be explicitly turned off if not wanted. 55 If the flag is enabled, the unit is **stop**ped and then **start**ed. If 56 not, the unit is **restart**ed. The goal of the flag is to make sure that 57 the new unit never runs in the old environment which is still in place 58 before the activation script is run. This behavior is different when the 59 service is socket-activated, as outlined in the following steps. 60 61 - The last thing that is taken into account is whether the unit is a 62 service and socket-activated. A correspondence between a 63 `.service` and its `.socket` unit is detected automatically, but 64 services can **opt out** of that detection by setting 65 `X-NotSocketActivated` to `yes` in their `[Service]` 66 section. Otherwise, if `X-StopIfChanged` is **not** set, the 67 service is **restart**ed with the others. If it is set, both the 68 service and the socket are **stop**ped and the socket is 69 **start**ed, leaving socket activation to start the service when 70 it's needed. 71 72## Sysinit reactivation {#sec-sysinit-reactivation} 73 74[`sysinit.target`](https://www.freedesktop.org/software/systemd/man/latest/systemd.special.html#sysinit.target) 75is a systemd target that encodes system initialization (i.e. early startup). A 76few units that need to run very early in the bootup process are ordered to 77finish before this target is reached. Probably the most notable one of these is 78`systemd-tmpfiles-setup.service`. We will refer to these units as "sysinit 79units". 80 81"Normal" systemd units, by default, are ordered AFTER `sysinit.target`. In 82other words, these "normal" units expect all services ordered before 83`sysinit.target` to have finished without explicitly declaring this dependency 84relationship for each dependency. See the [systemd 85bootup](https://www.freedesktop.org/software/systemd/man/latest/bootup.html) 86for more details on the bootup process. 87 88When restarting both a unit ordered before `sysinit.target` as well as one 89after, this presents a problem because they would be started at the same time 90as they do not explicitly declare their dependency relations. 91 92To solve this, NixOS has an artificial `sysinit-reactivation.target` which 93allows you to ensure that services ordered before `sysinit.target` are 94restarted correctly. This applies both to the ordering between these sysinit 95services as well as ensuring that sysinit units are restarted before "normal" 96units. 97 98To make an existing sysinit service restart correctly during system switch, you 99have to declare: 100 101```nix 102{ 103 systemd.services.my-sysinit = { 104 requiredBy = [ "sysinit-reactivation.target" ]; 105 before = [ "sysinit-reactivation.target" ]; 106 restartTriggers = [ config.environment.etc."my-sysinit.d".source ]; 107 }; 108} 109``` 110 111You need to configure appropriate `restartTriggers` specific to your service.