diff options
author | Janne Heß <janne@hess.ooo> | 2022-04-03 15:53:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-03 15:53:02 +0200 |
commit | 7cdc4dd5d1a2869d6e3c089f960ed6feae06ae77 (patch) | |
tree | 75022465e14ef14779c364a0c1578837ed9b29f1 /nixos/modules | |
parent | 803c1abb38afa5037f9576796a32248d2a7ecbcf (diff) | |
parent | 7ebb4ebe404a7ecf6ee9761aab7d02cd4e2a4abc (diff) |
Merge pull request #164943 from ElvishJerricco/systemd-initrd-reuse-systemd-module
initrd: Opt-in bare bones systemd-based initrd
Diffstat (limited to 'nixos/modules')
-rw-r--r-- | nixos/modules/misc/version.nix | 40 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/system/boot/stage-1.nix | 8 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd.nix | 43 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/initrd.nix | 417 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/nspawn.nix | 8 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/user.nix | 31 | ||||
-rw-r--r-- | nixos/modules/tasks/filesystems.nix | 2 | ||||
-rw-r--r-- | nixos/modules/virtualisation/qemu-vm.nix | 24 |
9 files changed, 513 insertions, 61 deletions
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix index d825f4beb301c..931201ade2935 100644 --- a/nixos/modules/misc/version.nix +++ b/nixos/modules/misc/version.nix @@ -15,6 +15,26 @@ let mapAttrsToList (n: v: ''${n}=${escapeIfNeccessary (toString v)}'') attrs ); + osReleaseContents = { + NAME = "NixOS"; + ID = "nixos"; + VERSION = "${cfg.release} (${cfg.codeName})"; + VERSION_CODENAME = toLower cfg.codeName; + VERSION_ID = cfg.release; + BUILD_ID = cfg.version; + PRETTY_NAME = "NixOS ${cfg.release} (${cfg.codeName})"; + LOGO = "nix-snowflake"; + HOME_URL = "https://nixos.org/"; + DOCUMENTATION_URL = "https://nixos.org/learn.html"; + SUPPORT_URL = "https://nixos.org/community.html"; + BUG_REPORT_URL = "https://github.com/NixOS/nixpkgs/issues"; + }; + + initrdReleaseContents = osReleaseContents // { + PRETTY_NAME = "${osReleaseContents.PRETTY_NAME} (Initrd)"; + }; + initrdRelease = pkgs.writeText "initrd-release" (attrsToText initrdReleaseContents); + in { imports = [ @@ -119,20 +139,12 @@ in DISTRIB_DESCRIPTION = "NixOS ${cfg.release} (${cfg.codeName})"; }; - "os-release".text = attrsToText { - NAME = "NixOS"; - ID = "nixos"; - VERSION = "${cfg.release} (${cfg.codeName})"; - VERSION_CODENAME = toLower cfg.codeName; - VERSION_ID = cfg.release; - BUILD_ID = cfg.version; - PRETTY_NAME = "NixOS ${cfg.release} (${cfg.codeName})"; - LOGO = "nix-snowflake"; - HOME_URL = "https://nixos.org/"; - DOCUMENTATION_URL = "https://nixos.org/learn.html"; - SUPPORT_URL = "https://nixos.org/community.html"; - BUG_REPORT_URL = "https://github.com/NixOS/nixpkgs/issues"; - }; + "os-release".text = attrsToText osReleaseContents; + }; + + boot.initrd.systemd.contents = { + "/etc/os-release".source = initrdRelease; + "/etc/initrd-release".source = initrdRelease; }; }; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index c4958c36ea004..789faea91977c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1181,6 +1181,7 @@ ./system/boot/systemd/nspawn.nix ./system/boot/systemd/tmpfiles.nix ./system/boot/systemd/user.nix + ./system/boot/systemd/initrd.nix ./system/boot/timesyncd.nix ./system/boot/tmp.nix ./system/etc/etc-activation.nix diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 8b011d91563f0..1bafec30b53d4 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -703,8 +703,12 @@ in } ]; - system.build = - { inherit bootStage1 initialRamdisk initialRamdiskSecretAppender extraUtils; }; + system.build = mkMerge [ + { inherit bootStage1 initialRamdiskSecretAppender extraUtils; } + + # generated in nixos/modules/system/boot/systemd/initrd.nix + (mkIf (!config.boot.initrd.systemd.enable) { inherit initialRamdisk; }) + ]; system.requiredKernelConfig = with config.lib.kernelConfig; [ (isYes "TMPFS") diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index f69c5d3d5a641..844a6793c1540 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -11,14 +11,7 @@ let systemd = cfg.package; inherit (systemdUtils.lib) - makeUnit generateUnits - makeJobScript - unitConfig - serviceConfig - mountConfig - automountConfig - commonUnitText targetToUnit serviceToUnit socketToUnit @@ -185,13 +178,7 @@ in systemd.units = mkOption { description = "Definition of systemd units."; default = {}; - type = with types; attrsOf (submodule ( - { name, config, ... }: - { options = concreteUnitOptions; - config = { - unit = mkDefault (makeUnit name config); - }; - })); + type = systemdUtils.types.units; }; systemd.packages = mkOption { @@ -203,37 +190,37 @@ in systemd.targets = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] ); + type = systemdUtils.types.targets; description = "Definition of systemd target units."; }; systemd.services = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ]); + type = systemdUtils.types.services; description = "Definition of systemd service units."; }; systemd.sockets = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ]); + type = systemdUtils.types.sockets; description = "Definition of systemd socket units."; }; systemd.timers = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ]); + type = systemdUtils.types.timers; description = "Definition of systemd timer units."; }; systemd.paths = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]); + type = systemdUtils.types.paths; description = "Definition of systemd path units."; }; systemd.mounts = mkOption { default = []; - type = with types; listOf (submodule [ { options = mountOptions; } unitConfig mountConfig ]); + type = systemdUtils.types.mounts; description = '' Definition of systemd mount units. This is a list instead of an attrSet, because systemd mandates the names to be derived from @@ -243,7 +230,7 @@ in systemd.automounts = mkOption { default = []; - type = with types; listOf (submodule [ { options = automountOptions; } unitConfig automountConfig ]); + type = systemdUtils.types.automounts; description = '' Definition of systemd automount units. This is a list instead of an attrSet, because systemd mandates the names to be derived from @@ -253,7 +240,7 @@ in systemd.slices = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = sliceOptions; } unitConfig] ); + type = systemdUtils.types.slices; description = "Definition of slice configurations."; }; @@ -362,10 +349,11 @@ in type = types.listOf types.str; example = [ "systemd-backlight@.service" ]; description = '' - A list of units to suppress when generating system systemd configuration directory. This has + A list of units to skip when generating system systemd configuration directory. This has priority over upstream units, <option>systemd.units</option>, and <option>systemd.additionalUpstreamSystemUnits</option>. The main purpose of this is to - suppress a upstream systemd unit with any modifications made to it by other NixOS modules. + prevent a upstream systemd unit from being added to the initrd with any modifications made to it + by other NixOS modules. ''; }; @@ -482,7 +470,12 @@ in enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedSystemUnits) cfg.units; in ({ - "systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants; + "systemd/system".source = generateUnits { + type = "system"; + units = enabledUnits; + upstreamUnits = enabledUpstreamSystemUnits; + upstreamWants = upstreamSystemWants; + }; "systemd/system.conf".text = '' [Manager] diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix new file mode 100644 index 0000000000000..30bdc9a3422c7 --- /dev/null +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -0,0 +1,417 @@ +{ lib, config, utils, pkgs, ... }: + +with lib; + +let + inherit (utils) systemdUtils escapeSystemdPath; + inherit (systemdUtils.lib) + generateUnits + pathToUnit + serviceToUnit + sliceToUnit + socketToUnit + targetToUnit + timerToUnit + mountToUnit + automountToUnit; + + + cfg = config.boot.initrd.systemd; + + # Copied from fedora + upstreamUnits = [ + "basic.target" + "ctrl-alt-del.target" + "emergency.service" + "emergency.target" + "final.target" + "halt.target" + "initrd-cleanup.service" + "initrd-fs.target" + "initrd-parse-etc.service" + "initrd-root-device.target" + "initrd-root-fs.target" + "initrd-switch-root.service" + "initrd-switch-root.target" + "initrd.target" + "initrd-udevadm-cleanup-db.service" + "kexec.target" + "kmod-static-nodes.service" + "local-fs-pre.target" + "local-fs.target" + "multi-user.target" + "paths.target" + "poweroff.target" + "reboot.target" + "rescue.service" + "rescue.target" + "rpcbind.target" + "shutdown.target" + "sigpwr.target" + "slices.target" + "sockets.target" + "swap.target" + "sysinit.target" + "sys-kernel-config.mount" + "syslog.socket" + "systemd-ask-password-console.path" + "systemd-ask-password-console.service" + "systemd-fsck@.service" + "systemd-halt.service" + "systemd-hibernate-resume@.service" + "systemd-journald-audit.socket" + "systemd-journald-dev-log.socket" + "systemd-journald.service" + "systemd-journald.socket" + "systemd-kexec.service" + "systemd-modules-load.service" + "systemd-poweroff.service" + "systemd-random-seed.service" + "systemd-reboot.service" + "systemd-sysctl.service" + "systemd-tmpfiles-setup-dev.service" + "systemd-tmpfiles-setup.service" + "systemd-udevd-control.socket" + "systemd-udevd-kernel.socket" + "systemd-udevd.service" + "systemd-udev-settle.service" + "systemd-udev-trigger.service" + "systemd-vconsole-setup.service" + "timers.target" + "umount.target" + + # TODO: Networking + # "network-online.target" + # "network-pre.target" + # "network.target" + # "nss-lookup.target" + # "nss-user-lookup.target" + # "remote-fs-pre.target" + # "remote-fs.target" + ] ++ cfg.additionalUpstreamUnits; + + upstreamWants = [ + "sysinit.target.wants" + ]; + + enabledUpstreamUnits = filter (n: ! elem n cfg.suppressedUnits) upstreamUnits; + enabledUnits = filterAttrs (n: v: ! elem n cfg.suppressedUnits) cfg.units; + + stage1Units = generateUnits { + type = "initrd"; + units = enabledUnits; + upstreamUnits = enabledUpstreamUnits; + inherit upstreamWants; + inherit (cfg) packages package; + }; + + fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems; + + fstab = pkgs.writeText "fstab" (lib.concatMapStringsSep "\n" + ({ fsType, mountPoint, device, options, autoFormat, autoResize, ... }@fs: let + opts = options ++ optional autoFormat "x-systemd.makefs" ++ optional autoResize "x-systemd.growfs"; + in "${device} /sysroot${mountPoint} ${fsType} ${lib.concatStringsSep "," opts}") fileSystems); + + kernel-name = config.boot.kernelPackages.kernel.name or "kernel"; + modulesTree = config.system.modulesTree.override { name = kernel-name + "-modules"; }; + firmware = config.hardware.firmware; + # Determine the set of modules that we need to mount the root FS. + modulesClosure = pkgs.makeModulesClosure { + rootModules = config.boot.initrd.availableKernelModules ++ config.boot.initrd.kernelModules; + kernel = modulesTree; + firmware = firmware; + allowMissing = false; + }; + + initrdBinEnv = pkgs.buildEnv { + name = "initrd-emergency-env"; + paths = map getBin cfg.initrdBin; + pathsToLink = ["/bin" "/sbin"]; + # Make recovery easier + postBuild = '' + ln -s ${cfg.package.util-linux}/bin/mount $out/bin/ + ln -s ${cfg.package.util-linux}/bin/umount $out/bin/ + ''; + }; + + initialRamdisk = pkgs.makeInitrdNG { + contents = map (path: { object = path; symlink = ""; }) (subtractLists cfg.suppressedStorePaths cfg.storePaths) + ++ mapAttrsToList (_: v: { object = v.source; symlink = v.target; }) (filterAttrs (_: v: v.enable) cfg.contents); + }; + +in { + options.boot.initrd.systemd = { + enable = mkEnableOption ''systemd in initrd. + + Note: This is in very early development and is highly + experimental. Most of the features NixOS supports in initrd are + not yet supported by the intrd generated with this option. + ''; + + package = (mkPackageOption pkgs "systemd" { + default = "systemdMinimal"; + }) // { + visible = false; + }; + + contents = mkOption { + description = "Set of files that have to be linked into the initrd"; + example = literalExpression '' + { + "/etc/hostname".text = "mymachine"; + } + ''; + visible = false; + default = {}; + type = types.attrsOf (types.submodule ({ config, options, name, ... }: { + options = { + enable = mkEnableOption "copying of this file to initrd and symlinking it" // { default = true; }; + + target = mkOption { + type = types.path; + description = '' + Path of the symlink. + ''; + default = name; + }; + + text = mkOption { + default = null; + type = types.nullOr types.lines; + description = "Text of the file."; + }; + + source = mkOption { + type = types.path; + description = "Path of the source file."; + }; + }; + + config = { + source = mkIf (config.text != null) ( + let name' = "initrd-" + baseNameOf name; + in mkDerivedConfig options.text (pkgs.writeText name') + ); + }; + })); + }; + + storePaths = mkOption { + description = '' + Store paths to copy into the initrd as well. + ''; + type = types.listOf types.singleLineStr; + default = []; + }; + + suppressedStorePaths = mkOption { + description = '' + Store paths specified in the storePaths option that + should not be copied. + ''; + type = types.listOf types.singleLineStr; + default = []; + }; + + emergencyAccess = mkOption { + type = with types; oneOf [ bool singleLineStr ]; + visible = false; + description = '' + Set to true for unauthenticated emergency access, and false for + no emergency access. + + Can also be set to a hashed super user password to allow + authenticated access to the emergency mode. + ''; + default = false; + }; + + initrdBin = mkOption { + type = types.listOf types.package; + default = []; + visible = false; + description = '' + Packages to include in /bin for the stage 1 emergency shell. + ''; + }; + + additionalUpstreamUnits = mkOption { + default = [ ]; + type = types.listOf types.str; + visible = false; + example = [ "debug-shell.service" "systemd-quotacheck.service" ]; + description = '' + Additional units shipped with systemd that shall be enabled. + ''; + }; + + suppressedUnits = mkOption { + default = [ ]; + type = types.listOf types.str; + example = [ "systemd-backlight@.service" ]; + visible = false; + description = '' + A list of units to skip when generating system systemd configuration directory. This has + priority over upstream units, <option>boot.initrd.systemd.units</option>, and + <option>boot.initrd.systemd.additionalUpstreamUnits</option>. The main purpose of this is to + prevent a upstream systemd unit from being added to the initrd with any modifications made to it + by other NixOS modules. + ''; + }; + + units = mkOption { + description = "Definition of systemd units."; + default = {}; + visible = false; + type = systemdUtils.types.units; + }; + + packages = mkOption { + default = []; + visible = false; + type = types.listOf types.package; + example = literalExpression "[ pkgs.systemd-cryptsetup-generator ]"; + description = "Packages providing systemd units and hooks."; + }; + + targets = mkOption { + default = {}; + visible = false; + type = systemdUtils.types.initrdTargets; + description = "Definition of systemd target units."; + }; + + services = mkOption { + default = {}; + type = systemdUtils.types.initrdServices; + visible = false; + description = "Definition of systemd service units."; + }; + + sockets = mkOption { + default = {}; + type = systemdUtils.types.initrdSockets; + visible = false; + description = "Definition of systemd socket units."; + }; + + timers = mkOption { + default = {}; + type = systemdUtils.types.initrdTimers; + visible = false; + description = "Definition of systemd timer units."; + }; + + paths = mkOption { + default = {}; + type = systemdUtils.types.initrdPaths; + visible = false; + description = "Definition of systemd path units."; + }; + + mounts = mkOption { + default = []; + type = systemdUtils.types.initrdMounts; + visible = false; + description = '' + Definition of systemd mount units. + This is a list instead of an attrSet, because systemd mandates the names to be derived from + the 'where' attribute. + ''; + }; + + automounts = mkOption { + default = []; + type = systemdUtils.types.automounts; + visible = false; + description = '' + Definition of systemd automount units. + This is a list instead of an attrSet, because systemd mandates the names to be derived from + the 'where' attribute. + ''; + }; + + slices = mkOption { + default = {}; + type = systemdUtils.types.slices; + visible = false; + description = "Definition of slice configurations."; + }; + }; + + config = mkIf (config.boot.initrd.enable && cfg.enable) { + system.build = { inherit initialRamdisk; }; + boot.initrd.systemd = { + initrdBin = [pkgs.bash pkgs.coreutils pkgs.kmod cfg.package] ++ config.system.fsPackages; + + contents = { + "/init".source = "${cfg.package}/lib/systemd/systemd"; + "/etc/systemd/system".source = stage1Units; + + "/etc/systemd/system.conf".text = '' + [Manager] + DefaultEnvironment=PATH=/bin:/sbin + ''; + + "/etc/fstab".source = fstab; + + "/lib/modules".source = "${modulesClosure}/lib/modules"; + + "/etc/modules-load.d/nixos.conf".text = concatStringsSep "\n" config.boot.initrd.kernelModules; + + "/etc/passwd".source = "${pkgs.fakeNss}/etc/passwd"; + "/etc/shadow".text = "root:${if isBool cfg.emergencyAccess then "!" else cfg.emergencyAccess}:::::::"; + + "/bin".source = "${initrdBinEnv}/bin"; + "/sbin".source = "${initrdBinEnv}/sbin"; + + "/etc/sysctl.d/nixos.conf".text = "kernel.modprobe = /sbin/modprobe"; + }; + + storePaths = [ + # TODO: Limit this to the bare necessities + "${cfg.package}/lib" + + "${cfg.package.util-linux}/bin/mount" + "${cfg.package.util-linux}/bin/umount" + "${cfg.package.util-linux}/bin/sulogin" + + # so NSS can look up usernames + "${pkgs.glibc}/lib/libnss_files.so" + ]; + + targets.initrd.aliases = ["default.target"]; + units = + mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services + // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets + // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets + // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers + // listToAttrs (map + (v: let n = escapeSystemdPath v.where; + in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) + // listToAttrs (map + (v: let n = escapeSystemdPath v.where; + in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); + + services.emergency = mkIf (isBool cfg.emergencyAccess && cfg.emergencyAccess) { + environment.SYSTEMD_SULOGIN_FORCE = "1"; + }; + # The unit in /run/systemd/generator shadows the unit in + # /etc/systemd/system, but will still apply drop-ins from + # /etc/systemd/system/foo.service.d/ + # + # We need IgnoreOnIsolate, otherwise the Requires dependency of + # a mount unit on its makefs unit causes it to be unmounted when + # we isolate for switch-root. Use a dummy package so that + # generateUnits will generate drop-ins instead of unit files. + packages = [(pkgs.runCommand "dummy" {} '' + mkdir -p $out/etc/systemd/system + touch $out/etc/systemd/system/systemd-{makefs,growfs}@.service + '')]; + services."systemd-makefs@".unitConfig.IgnoreOnIsolate = true; + services."systemd-growfs@".unitConfig.IgnoreOnIsolate = true; + }; + }; +} diff --git a/nixos/modules/system/boot/systemd/nspawn.nix b/nixos/modules/system/boot/systemd/nspawn.nix index 0c6822319a5b0..bf9995d03cc18 100644 --- a/nixos/modules/system/boot/systemd/nspawn.nix +++ b/nixos/modules/system/boot/systemd/nspawn.nix @@ -116,7 +116,13 @@ in { in mkMerge [ (mkIf (cfg != {}) { - environment.etc."systemd/nspawn".source = mkIf (cfg != {}) (generateUnits' false "nspawn" units [] []); + environment.etc."systemd/nspawn".source = mkIf (cfg != {}) (generateUnits { + allowCollisions = false; + type = "nspawn"; + inherit units; + upstreamUnits = []; + upstreamWants = []; + }); }) { systemd.targets.multi-user.wants = [ "machines.target" ]; diff --git a/nixos/modules/system/boot/systemd/user.nix b/nixos/modules/system/boot/systemd/user.nix index e30f83f3457f8..4951aef95584b 100644 --- a/nixos/modules/system/boot/systemd/user.nix +++ b/nixos/modules/system/boot/systemd/user.nix @@ -12,10 +12,6 @@ let (systemdUtils.lib) makeUnit generateUnits - makeJobScript - unitConfig - serviceConfig - commonUnitText targetToUnit serviceToUnit socketToUnit @@ -57,48 +53,42 @@ in { systemd.user.units = mkOption { description = "Definition of systemd per-user units."; default = {}; - type = with types; attrsOf (submodule ( - { name, config, ... }: - { options = concreteUnitOptions; - config = { - unit = mkDefault (makeUnit name config); - }; - })); + type = systemdUtils.types.units; }; systemd.user.paths = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]); + type = systemdUtils.types.paths; description = "Definition of systemd per-user path units."; }; systemd.user.services = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ] ); + type = systemdUtils.types.services; description = "Definition of systemd per-user service units."; }; systemd.user.slices = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = sliceOptions; } unitConfig ] ); + type = systemdUtils.types.slices; description = "Definition of systemd per-user slice units."; }; systemd.user.sockets = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ] ); + type = systemdUtils.types.sockets; description = "Definition of systemd per-user socket units."; }; systemd.user.targets = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] ); + type = systemdUtils.types.targets; description = "Definition of systemd per-user target units."; }; systemd.user.timers = mkOption { default = {}; - type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ] ); + type = systemdUtils.types.timers; description = "Definition of systemd per-user timer units."; }; @@ -119,7 +109,12 @@ in { ]; environment.etc = { - "systemd/user".source = generateUnits "user" cfg.units upstreamUserUnits []; + "systemd/user".source = generateUnits { + type = "user"; + inherit (cfg) units; + upstreamUnits = upstreamUserUnits; + upstreamWants = []; + }; "systemd/user.conf".text = '' [Manager] diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index d68edd8d7d394..b8afe231dd2e1 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -352,7 +352,7 @@ in unitConfig.DefaultDependencies = false; # needed to prevent a cycle serviceConfig.Type = "oneshot"; }; - in listToAttrs (map formatDevice (filter (fs: fs.autoFormat) fileSystems)) // { + in listToAttrs (map formatDevice (filter (fs: fs.autoFormat && !(utils.fsNeededForBoot fs)) fileSystems)) // { # Mount /sys/fs/pstore for evacuating panic logs and crashdumps from persistent storage onto the disk using systemd-pstore. # This cannot be done with the other special filesystems because the pstore module (which creates the mount point) is not loaded then. "mount-pstore" = { diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 760f69121612b..74f6521462b85 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -923,6 +923,8 @@ in mkVMOverride (cfg.fileSystems // { "/".device = cfg.bootDevice; + "/".fsType = "ext4"; + "/".autoFormat = true; "/tmp" = mkIf config.boot.tmpOnTmpfs { device = "tmpfs"; @@ -953,6 +955,28 @@ in }; } // lib.mapAttrs' mkSharedDir cfg.sharedDirectories); + boot.initrd.systemd = lib.mkIf (config.boot.initrd.systemd.enable && cfg.writableStore) { + mounts = [{ + where = "/sysroot/nix/store"; + what = "overlay"; + type = "overlay"; + options = "lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/store,workdir=/sysroot/nix/.rw-store/work"; + wantedBy = ["local-fs.target"]; + before = ["local-fs.target"]; + requires = ["sysroot-nix-.ro\\x2dstore.mount" "sysroot-nix-.rw\\x2dstore.mount" "rw-store.service"]; + after = ["sysroot-nix-.ro\\x2dstore.mount" "sysroot-nix-.rw\\x2dstore.mount" "rw-store.service"]; + unitConfig.IgnoreOnIsolate = true; + }]; + services.rw-store = { + after = ["sysroot-nix-.rw\\x2dstore.mount"]; + unitConfig.DefaultDependencies = false; + serviceConfig = { + Type = "oneshot"; + ExecStart = "/bin/mkdir -p 0755 /sysroot/nix/.rw-store/store /sysroot/nix/.rw-store/work /sysroot/nix/store"; + }; + }; + }; + swapDevices = mkVMOverride [ ]; boot.initrd.luks.devices = mkVMOverride {}; |