How to determine why nixos-rebuild restarted systemd services

Is there a way to figure out why nixos-rebuild switch sometimes restarts the world (i.e. almost all systemd services)? I’m fine with waiting for the nightly update to restart things when I am not using them, in the general case. But especially while testing changes to nixos modules I somewhat frequently encounter restart the world events, while the second try (improving on the first) then skips over the restarts. Is it possible to get some kind of debug output that shows me the dependency chain that triggered the restarts?

Some services seem to depend on config.system.path which will change if you install/update packages. Quick remedy for the issue would be to set systemd.services.<name>.restartIfChanged to false but the proper way should be to stop using config.system.path in servies where it isn’t actually necessary.

So after quite a while of staring at outputs, I see that whenever this happens stdenv-linux, patchelf and gnumake turn up:

these paths will be fetched (0.34 MiB download, 1.61 MiB unpacked):
  /nix/store/9l508y7cvrqjd1n50jbr3fm2q9smmp92-gnumake-4.3
  /nix/store/ajib0wv150ah6nqbkn5b5kwmqldk368y-patchelf-0.12
  /nix/store/av0pavd6vn698g82ml66gd2hnjd01nzb-stdenv-linux

This is on stable. Is there a way to figure out why it thinks stdenv-linux has updated? Sadly I hadn’t actually copy’n’pasted more samples. But it feels like whenever I do the first nixos-rebuild switch of the day it refetches these and restarts the world.

Using nix-diff is a good way to find out what has changed between two derivations.

If you want to see what systemd services would be restarted on switch without actually doing the restart you can use nixos-rebuild dry-activate instead of nixos-rebuild switch

Thank you, @griff! nix-diff was very helpful and I finally found the root cause: The daily nixos-upgrade unit and nixos-rebuild switch used different channels for nixpkgs. This was made worse by the latter’s channels seemingly not being updated at all. What would fetch new channel data automatically beyond hardcoding an URL? Somehow I couldn’t find an option for this.

To recap for others: I used nix show-derivation /run/current-system to get the right .drv name, basically before and after (although there was only one from before, because that was the one that was continuously updated; but a lot of the latter, because that was from the stuck nixos version). The give-away was also the downgrade in the version number. From nix-diff it was then clear that it’s actually a downgrade.

In nix-channel I used nixos-20.09-small and in system.autoUpgrade.channel I hardcoded https://nixos.org/channels/nixos-20.09. I noticed that -small had timely security updates and that the regular channel did not, hence the change at some point. However this also meant that the global system upgrade task did a new download on every upgrade as far as I can see.

nixos-rebuild dry-activate itself was extremely terse: it told me about the global restart but not about the derivations involved (not even with -v).

1 Like