diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 6f770757edba..08c316a123c4 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -28,6 +28,10 @@ - `util-linux` is now supported on Darwin and is no longer an alias to `unixtools`. Use the `unixtools.util-linux` package for access to the Apple variants of the utilities. +- `fileSystems..autoFormat` now uses `systemd-makefs`, which does not accept formatting options. Therefore, `fileSystems..formatOptions` has been removed. + +- `fileSystems..autoResize` now uses `systemd-growfs` to resize the file system online in stage 2. This means that `f2fs` and `ext2` can no longer be auto resized, while `xfs` and `btrfs` now can be. + ## Other Notable Changes {#sec-release-23.11-notable-changes} - The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration. diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index f72342429a6d..bad045ec101f 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -374,22 +374,6 @@ mountFS() { checkFS "$device" "$fsType" - # Optionally resize the filesystem. - case $options in - *x-nixos.autoresize*) - if [ "$fsType" = ext2 -o "$fsType" = ext3 -o "$fsType" = ext4 ]; then - modprobe "$fsType" - echo "resizing $device..." - e2fsck -fp "$device" - resize2fs "$device" - elif [ "$fsType" = f2fs ]; then - echo "resizing $device..." - fsck.f2fs -fp "$device" - resize.f2fs "$device" - fi - ;; - esac - # Create backing directories for overlayfs if [ "$fsType" = overlay ]; then for i in upper work; do diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 1229f6357523..dcb15cf7d42b 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -150,12 +150,6 @@ let copy_bin_and_libs ${pkgs.kmod}/bin/kmod ln -sf kmod $out/bin/modprobe - # Copy resize2fs if any ext* filesystems are to be resized - ${optionalString (any (fs: fs.autoResize && (lib.hasPrefix "ext" fs.fsType)) fileSystems) '' - # We need mke2fs in the initrd. - copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs - ''} - # Copy multipath. ${optionalString config.services.multipath.enable '' copy_bin_and_libs ${config.services.multipath.package}/bin/multipath diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 5ff99b14dee6..d2af86fef57c 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -588,6 +588,15 @@ in systemd.services."systemd-backlight@".restartIfChanged = false; systemd.services."systemd-fsck@".restartIfChanged = false; systemd.services."systemd-fsck@".path = [ config.system.path ]; + systemd.services."systemd-makefs@" = { + restartIfChanged = false; + path = [ pkgs.util-linux ] ++ config.system.fsPackages; + # Since there is no /etc/systemd/system/systemd-makefs@.service + # file, the units generated in /run/systemd/generator would + # override anything we put here. But by forcing the use of a + # drop-in in /etc, it does apply. + overrideStrategy = "asDropin"; + }; systemd.services.systemd-random-seed.restartIfChanged = false; systemd.services.systemd-remount-fs.restartIfChanged = false; systemd.services.systemd-update-utmp.restartIfChanged = false; diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index c9c219d0a0a5..3f40a5b2dfa0 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -56,7 +56,6 @@ let "systemd-ask-password-console.path" "systemd-ask-password-console.service" "systemd-fsck@.service" - "systemd-growfs@.service" "systemd-halt.service" "systemd-hibernate-resume@.service" "systemd-journald-audit.socket" @@ -93,7 +92,6 @@ let fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems; needMakefs = lib.any (fs: fs.autoFormat) fileSystems; - needGrowfs = lib.any (fs: fs.autoResize) fileSystems; kernel-name = config.boot.kernelPackages.kernel.name or "kernel"; modulesTree = config.system.modulesTree.override { name = kernel-name + "-modules"; }; @@ -400,7 +398,6 @@ in { storePaths = [ # systemd tooling "${cfg.package}/lib/systemd/systemd-fsck" - (lib.mkIf needGrowfs "${cfg.package}/lib/systemd/systemd-growfs") "${cfg.package}/lib/systemd/systemd-hibernate-resume" "${cfg.package}/lib/systemd/systemd-journald" (lib.mkIf needMakefs "${cfg.package}/lib/systemd/systemd-makefs") diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix index 2f032c3faf5c..7cb2ca23fa41 100644 --- a/nixos/modules/tasks/filesystems.nix +++ b/nixos/modules/tasks/filesystems.nix @@ -112,12 +112,9 @@ let }; formatOptions = mkOption { - default = ""; - type = types.str; - description = lib.mdDoc '' - If {option}`autoFormat` option is set specifies - extra options passed to mkfs. - ''; + visible = false; + type = types.unspecified; + default = null; }; autoResize = mkOption { @@ -139,22 +136,11 @@ let }; - config = let - defaultFormatOptions = - # -F needed to allow bare block device without partitions - if (builtins.substring 0 3 config.fsType) == "ext" then "-F" - # -q needed for non-interactive operations - else if config.fsType == "jfs" then "-q" - # (same here) - else if config.fsType == "reiserfs" then "-q" - else null; - in { - options = mkMerge [ - (mkIf config.autoResize [ "x-nixos.autoresize" ]) - (mkIf (utils.fsNeededForBoot config) [ "x-initrd.mount" ]) - ]; - formatOptions = mkIf (defaultFormatOptions != null) (mkDefault defaultFormatOptions); - }; + config.options = mkMerge [ + (mkIf config.autoResize [ "x-systemd.growfs" ]) + (mkIf config.autoFormat [ "x-systemd.makefs" ]) + (mkIf (utils.fsNeededForBoot config) [ "x-initrd.mount" ]) + ]; }; @@ -201,23 +187,20 @@ let skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck || isBindMount fs; # https://wiki.archlinux.org/index.php/fstab#Filepath_spaces escape = string: builtins.replaceStrings [ " " "\t" ] [ "\\040" "\\011" ] string; - in fstabFileSystems: { rootPrefix ? "", extraOpts ? (fs: []) }: concatMapStrings (fs: + in fstabFileSystems: { rootPrefix ? "" }: concatMapStrings (fs: (optionalString (isBindMount fs) (escape rootPrefix)) + (if fs.device != null then escape fs.device else if fs.label != null then "/dev/disk/by-label/${escape fs.label}" else throw "No device specified for mount point ‘${fs.mountPoint}’.") + " " + escape fs.mountPoint + " " + fs.fsType - + " " + escape (builtins.concatStringsSep "," (fs.options ++ (extraOpts fs))) + + " " + escape (builtins.concatStringsSep "," fs.options) + " 0 " + (if skipCheck fs then "0" else if fs.mountPoint == "/" then "1" else "2") + "\n" ) fstabFileSystems; initrdFstab = pkgs.writeText "initrd-fstab" (makeFstabEntries (filter utils.fsNeededForBoot fileSystems) { rootPrefix = "/sysroot"; - extraOpts = fs: - (optional fs.autoResize "x-systemd.growfs") - ++ (optional fs.autoFormat "x-systemd.makefs"); }); in @@ -319,7 +302,13 @@ in assertions = let ls = sep: concatMapStringsSep sep (x: x.mountPoint); - notAutoResizable = fs: fs.autoResize && !(hasPrefix "ext" fs.fsType || fs.fsType == "f2fs"); + resizableFSes = [ + "ext3" + "ext4" + "btrfs" + "xfs" + ]; + notAutoResizable = fs: fs.autoResize && !(builtins.elem fs.fsType resizableFSes); in [ { assertion = ! (fileSystems' ? cycle); message = "The ‘fileSystems’ option can't be topologically sorted: mountpoint dependency path ${ls " -> " fileSystems'.cycle} loops to ${ls ", " fileSystems'.loops}"; @@ -327,8 +316,21 @@ in { assertion = ! (any notAutoResizable fileSystems); message = let fs = head (filter notAutoResizable fileSystems); - in - "Mountpoint '${fs.mountPoint}': 'autoResize = true' is not supported for 'fsType = \"${fs.fsType}\"':${optionalString (fs.fsType == "auto") " fsType has to be explicitly set and"} only the ext filesystems and f2fs support it."; + in '' + Mountpoint '${fs.mountPoint}': 'autoResize = true' is not supported for 'fsType = "${fs.fsType}"' + ${optionalString (fs.fsType == "auto") "fsType has to be explicitly set and"} + only the following support it: ${lib.concatStringsSep ", " resizableFSes}. + ''; + } + { + assertion = ! (any (fs: fs.formatOptions != null) fileSystems); + message = let + fs = head (filter (fs: fs.formatOptions != null) fileSystems); + in '' + 'fileSystems..formatOptions' has been removed, since + systemd-makefs does not support any way to provide formatting + options. + ''; } ]; @@ -377,37 +379,7 @@ in wants = [ "local-fs.target" "remote-fs.target" ]; }; - systemd.services = - - # Emit systemd services to format requested filesystems. - let - formatDevice = fs: - let - mountPoint' = "${escapeSystemdPath fs.mountPoint}.mount"; - device' = escapeSystemdPath fs.device; - device'' = "${device'}.device"; - in nameValuePair "mkfs-${device'}" - { description = "Initialisation of Filesystem ${fs.device}"; - wantedBy = [ mountPoint' ]; - before = [ mountPoint' "systemd-fsck@${device'}.service" ]; - requires = [ device'' ]; - after = [ device'' ]; - path = [ pkgs.util-linux ] ++ config.system.fsPackages; - script = - '' - if ! [ -e "${fs.device}" ]; then exit 1; fi - # FIXME: this is scary. The test could be more robust. - type=$(blkid -p -s TYPE -o value "${fs.device}" || true) - if [ -z "$type" ]; then - echo "creating ${fs.fsType} filesystem on ${fs.device}..." - mkfs.${fs.fsType} ${fs.formatOptions} "${fs.device}" - fi - ''; - unitConfig.RequiresMountsFor = [ "${dirOf fs.device}" ]; - unitConfig.DefaultDependencies = false; # needed to prevent a cycle - serviceConfig.Type = "oneshot"; - }; - in listToAttrs (map formatDevice (filter (fs: fs.autoFormat && !(utils.fsNeededForBoot fs)) fileSystems)) // { + systemd.services = { # 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/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix index 1d52861aa39d..035784f43df8 100644 --- a/nixos/modules/tasks/filesystems/f2fs.nix +++ b/nixos/modules/tasks/filesystems/f2fs.nix @@ -15,11 +15,6 @@ in boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs - ${optionalString (any (fs: fs.autoResize) fileSystems) '' - # We need f2fs-tools' tools to resize filesystems - copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/resize.f2fs - ''} - ''; }; } diff --git a/nixos/tests/fsck.nix b/nixos/tests/fsck.nix index ccb664be080c..ec6bfa69ae84 100644 --- a/nixos/tests/fsck.nix +++ b/nixos/tests/fsck.nix @@ -30,7 +30,7 @@ import ./make-test-python.nix { else "fsck.ext4.*/dev/vda"}'") with subtest("mnt fs is fsckd"): - machine.succeed("journalctl -b | grep 'fsck.*/dev/vdb.*clean'") + machine.succeed("journalctl -b | grep 'fsck.*vdb.*clean'") machine.succeed( "grep 'Requires=systemd-fsck@dev-vdb.service' /run/systemd/generator/mnt.mount" )