Merge pull request #86967 from jakobrs/more-general-fsbefore
nixos/lib/utils: Add `fileSystems.<name>.depends` option and generalise fsBefore (fixes #86955)
This commit is contained in:
commit
26706834a5
4 changed files with 54 additions and 4 deletions
|
@ -14,8 +14,30 @@ rec {
|
||||||
fsNeededForBoot = fs: fs.neededForBoot || elem fs.mountPoint pathsNeededForBoot;
|
fsNeededForBoot = fs: fs.neededForBoot || elem fs.mountPoint pathsNeededForBoot;
|
||||||
|
|
||||||
# Check whenever `b` depends on `a` as a fileSystem
|
# Check whenever `b` depends on `a` as a fileSystem
|
||||||
fsBefore = a: b: a.mountPoint == b.device
|
fsBefore = a: b:
|
||||||
|| hasPrefix "${a.mountPoint}${optionalString (!(hasSuffix "/" a.mountPoint)) "/"}" b.mountPoint;
|
let
|
||||||
|
# normalisePath adds a slash at the end of the path if it didn't already
|
||||||
|
# have one.
|
||||||
|
#
|
||||||
|
# The reason slashes are added at the end of each path is to prevent `b`
|
||||||
|
# from accidentally depending on `a` in cases like
|
||||||
|
# a = { mountPoint = "/aaa"; ... }
|
||||||
|
# b = { device = "/aaaa"; ... }
|
||||||
|
# Here a.mountPoint *is* a prefix of b.device even though a.mountPoint is
|
||||||
|
# *not* a parent of b.device. If we add a slash at the end of each string,
|
||||||
|
# though, this is not a problem: "/aaa/" is not a prefix of "/aaaa/".
|
||||||
|
normalisePath = path: "${path}${optionalString (!(hasSuffix "/" path)) "/"}";
|
||||||
|
normalise = mount: mount // { device = normalisePath mount.device;
|
||||||
|
mountPoint = normalisePath mount.mountPoint;
|
||||||
|
depends = map normalisePath mount.depends;
|
||||||
|
};
|
||||||
|
|
||||||
|
a' = normalise a;
|
||||||
|
b' = normalise b;
|
||||||
|
|
||||||
|
in hasPrefix a'.mountPoint b'.device
|
||||||
|
|| hasPrefix a'.mountPoint b'.mountPoint
|
||||||
|
|| any (hasPrefix a'.mountPoint) b'.depends;
|
||||||
|
|
||||||
# Escape a path according to the systemd rules, e.g. /dev/xyzzy
|
# Escape a path according to the systemd rules, e.g. /dev/xyzzy
|
||||||
# becomes dev-xyzzy. FIXME: slow.
|
# becomes dev-xyzzy. FIXME: slow.
|
||||||
|
|
|
@ -680,6 +680,12 @@ in
|
||||||
"upperdir=/nix/.rw-store/store"
|
"upperdir=/nix/.rw-store/store"
|
||||||
"workdir=/nix/.rw-store/work"
|
"workdir=/nix/.rw-store/work"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
depends = [
|
||||||
|
"/nix/.ro-store"
|
||||||
|
"/nix/.rw-store/store"
|
||||||
|
"/nix/.rw-store/work"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ];
|
boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ];
|
||||||
|
|
|
@ -57,6 +57,12 @@ with lib;
|
||||||
"upperdir=/nix/.rw-store/store"
|
"upperdir=/nix/.rw-store/store"
|
||||||
"workdir=/nix/.rw-store/work"
|
"workdir=/nix/.rw-store/work"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
depends = [
|
||||||
|
"/nix/.ro-store"
|
||||||
|
"/nix/.rw-store/store"
|
||||||
|
"/nix/.rw-store/work"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "squashfs" "overlay" ];
|
boot.initrd.availableKernelModules = [ "squashfs" "overlay" ];
|
||||||
|
|
|
@ -24,13 +24,15 @@ let
|
||||||
|
|
||||||
specialFSTypes = [ "proc" "sysfs" "tmpfs" "ramfs" "devtmpfs" "devpts" ];
|
specialFSTypes = [ "proc" "sysfs" "tmpfs" "ramfs" "devtmpfs" "devpts" ];
|
||||||
|
|
||||||
|
nonEmptyWithoutTrailingSlash = addCheckDesc "non-empty without trailing slash" types.str
|
||||||
|
(s: isNonEmpty s && (builtins.match ".+/" s) == null);
|
||||||
|
|
||||||
coreFileSystemOpts = { name, config, ... }: {
|
coreFileSystemOpts = { name, config, ... }: {
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
mountPoint = mkOption {
|
mountPoint = mkOption {
|
||||||
example = "/mnt/usb";
|
example = "/mnt/usb";
|
||||||
type = addCheckDesc "non-empty without trailing slash" types.str
|
type = nonEmptyWithoutTrailingSlash;
|
||||||
(s: isNonEmpty s && (builtins.match ".+/" s) == null);
|
|
||||||
description = "Location of the mounted the file system.";
|
description = "Location of the mounted the file system.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,6 +57,20 @@ let
|
||||||
type = types.listOf nonEmptyStr;
|
type = types.listOf nonEmptyStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
depends = mkOption {
|
||||||
|
default = [ ];
|
||||||
|
example = [ "/persist" ];
|
||||||
|
type = types.listOf nonEmptyWithoutTrailingSlash;
|
||||||
|
description = ''
|
||||||
|
List of paths that should be mounted before this one. This filesystem's
|
||||||
|
<option>device</option> and <option>mountPoint</option> are always
|
||||||
|
checked and do not need to be included explicitly. If a path is added
|
||||||
|
to this list, any other filesystem whose mount point is a parent of
|
||||||
|
the path will be mounted before this filesystem. The paths do not need
|
||||||
|
to actually be the <option>mountPoint</option> of some other filesystem.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
Loading…
Reference in a new issue