about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/system/boot/systemd/shutdown.nix
blob: b4b750fa9aafe487ddb8e5d90b2fefcc906000d6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{ config, lib, utils, pkgs, ... }: let

  cfg = config.systemd.shutdownRamfs;

  ramfsContents = let
    storePaths = map (p: "${p}\n") cfg.storePaths;
    contents = lib.mapAttrsToList (_: v: "${v.source}\n${v.target}") (lib.filterAttrs (_: v: v.enable) cfg.contents);
  in pkgs.writeText "shutdown-ramfs-contents" (lib.concatStringsSep "\n" (storePaths ++ contents));

in {
  options.systemd.shutdownRamfs = {
    enable = lib.mkEnableOption (lib.mdDoc "pivoting back to an initramfs for shutdown") // { default = true; };
    contents = lib.mkOption {
      description = lib.mdDoc "Set of files that have to be linked into the shutdown ramfs";
      example = lib.literalExpression ''
        {
          "/lib/systemd/system-shutdown/zpool-sync-shutdown".source = writeShellScript "zpool" "exec ''${zfs}/bin/zpool sync"
        }
      '';
      type = utils.systemdUtils.types.initrdContents;
    };

    storePaths = lib.mkOption {
      description = lib.mdDoc ''
        Store paths to copy into the shutdown ramfs as well.
      '';
      type = lib.types.listOf lib.types.singleLineStr;
      default = [];
    };
  };

  config = lib.mkIf cfg.enable {
    systemd.shutdownRamfs.contents."/shutdown".source = "${config.systemd.package}/lib/systemd/systemd-shutdown";
    systemd.shutdownRamfs.storePaths = [pkgs.runtimeShell "${pkgs.coreutils}/bin"];

    systemd.mounts = [{
      what = "tmpfs";
      where = "/run/initramfs";
      type = "tmpfs";
    }];

    systemd.services.generate-shutdown-ramfs = {
      description = "Generate shutdown ramfs";
      wantedBy = [ "shutdown.target" ];
      before = [ "shutdown.target" ];
      unitConfig = {
        DefaultDependencies = false;
        RequiresMountsFor = "/run/initramfs";
        ConditionFileIsExecutable = [
          "!/run/initramfs/shutdown"
        ];
      };

      serviceConfig = {
        Type = "oneshot";
        ProtectSystem = "strict";
        ReadWritePaths = "/run/initramfs";
        ExecStart = "${pkgs.makeInitrdNGTool}/bin/make-initrd-ng ${ramfsContents} /run/initramfs";
      };
    };
  };
}