Skip to content

nixos/kernel: Module inclusion improvements #375975

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: staging-next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,13 @@ rec {
nestedTypes.finalType = finalType;
};

# A list of attrnames is coerced into an attrset of bools by
# setting the values to true.
Comment on lines +1183 to +1184
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to tempt contributors into improving this duplicate doc.

Suggested change
# A list of attrnames is coerced into an attrset of bools by
# setting the values to true.
/** See https://nixos.org/manual/nixos/unstable/#sec-option-types-basic */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any other types in this file linking to the manual like that?

attrNamesToTrue = coercedTo
(types.listOf types.str)
(enabledList: lib.genAttrs enabledList (_attrName: true))
(types.attrsOf types.bool);

# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };

Expand Down
23 changes: 23 additions & 0 deletions nixos/doc/manual/development/option-types.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,29 @@ merging is handled.
problems.
:::

`types.attrNamesToTrue`

: Either a list of attribute names, or an attribute set of
booleans. A list will be coerced into an attribute set with those
names, whose values are set to `true`. This is useful when it is
convenient to be able to write definitions as a simple list, but
still need to be able to override and disable individual values.

::: {#ex-types-attrNamesToTrue .example}
### `types.attrNamesToTrue`
```
{
foo = [ "bar" ];
}
```

```
{
foo.bar = true;
}
```
:::

`types.pkgs`

: A type for the top level Nixpkgs package set.
Expand Down
51 changes: 44 additions & 7 deletions nixos/modules/system/boot/kernel.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ let
inherit (config.boot.kernel) features randstructSeed;
inherit (config.boot.kernelPackages) kernel;

modulesTypeDesc = ''
This can either be a list of modules, or an attrset. In an
attrset, names that are set to `true` represent modules that will
be included. Note that setting these names to `false` does not
prevent the module from being loaded. For that, use
{option}`boot.blacklistedKernelModules`.
'';
Comment on lines +11 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be coercedTo (... true) (attrsOf (enum [ true false "auto" ])) then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. That isn't what these options do.


kernelModulesConf = pkgs.writeText "nixos.conf"
''
${concatStringsSep "\n" config.boot.kernelModules}
Expand Down Expand Up @@ -175,20 +183,23 @@ in
};

boot.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
type = types.attrNamesToTrue;
default = { };
description = ''
The set of kernel modules to be loaded in the second stage of
the boot process. Note that modules that are needed to
mount the root file system should be added to
{option}`boot.initrd.availableKernelModules` or
{option}`boot.initrd.kernelModules`.

${modulesTypeDesc}
'';
apply = mods: lib.attrNames (lib.filterAttrs (_: v: v) mods);
};

boot.initrd.availableKernelModules = mkOption {
type = types.listOf types.str;
default = [];
type = types.attrNamesToTrue;
default = { };
example = [ "sata_nv" "ext3" ];
description = ''
The set of kernel modules in the initial ramdisk used during the
Expand All @@ -204,13 +215,21 @@ in
modules for PCI devices are loaded when they match the PCI ID
of a device in your system). To force a module to be loaded,
include it in {option}`boot.initrd.kernelModules`.

${modulesTypeDesc}
'';
apply = mods: lib.attrNames (lib.filterAttrs (_: v: v) mods);
};

boot.initrd.kernelModules = mkOption {
type = types.listOf types.str;
default = [];
description = "List of modules that are always loaded by the initrd.";
type = types.attrNamesToTrue;
default = { };
description = ''
Set of modules that are always loaded by the initrd.

${modulesTypeDesc}
'';
apply = mods: lib.attrNames (lib.filterAttrs (_: v: v) mods);
};

boot.initrd.includeDefaultModules = mkOption {
Expand All @@ -223,6 +242,24 @@ in
'';
};

boot.initrd.allowMissingModules = mkOption {
type = types.bool;
default = false;
description = ''
Whether the initrd can be built even though modules listed in
{option}`boot.initrd.kernelModules` or
{option}`boot.initrd.availableKernelModules` are missing from
the kernel. This is useful when combining configurations that
include a lot of modules, such as
{option}`hardware.enableAllHardware`, with kernels that don't
provide as many modules as typical NixOS kernels.

Note that enabling this is discouraged. Instead, try disabling
individual modules by setting e.g.
`boot.initrd.availableKernelModules.foo = lib.mkForce false;`
'';
};

system.modulesTree = mkOption {
type = types.listOf types.path;
internal = true;
Expand Down
11 changes: 7 additions & 4 deletions nixos/modules/system/boot/modprobe.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ with lib;
};

boot.blacklistedKernelModules = mkOption {
type = types.listOf types.str;
default = [ ];
type = types.attrNamesToTrue;
default = { };
example = [
"cirrusfb"
"i2c_piix4"
];
description = ''
List of names of kernel modules that should not be loaded
automatically by the hardware probing code.
Set of names of kernel modules that should not be loaded
automatically by the hardware probing code. This can either be
a list of modules or an attrset. In an attrset, names that are
set to `true` represent modules that will be blacklisted.
'';
apply = mods: lib.attrNames (lib.filterAttrs (_: v: v) mods);
};

boot.extraModprobeConfig = mkOption {
Expand Down
4 changes: 2 additions & 2 deletions nixos/modules/system/boot/stage-1.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ let
rootModules = config.boot.initrd.availableKernelModules ++ config.boot.initrd.kernelModules;
kernel = config.system.modulesTree;
firmware = config.hardware.firmware;
allowMissing = false;
allowMissing = config.boot.initrd.allowMissingModules;
inherit (config.boot.initrd) extraFirmwarePaths;
};

Expand Down Expand Up @@ -716,7 +716,7 @@ in
];

system.build = mkMerge [
{ inherit bootStage1 initialRamdiskSecretAppender extraUtils; }
{ inherit bootStage1 initialRamdiskSecretAppender extraUtils modulesClosure; }

# generated in nixos/modules/system/boot/systemd/initrd.nix
(mkIf (!config.boot.initrd.systemd.enable) { inherit initialRamdisk; })
Expand Down
10 changes: 1 addition & 9 deletions nixos/modules/system/boot/systemd/initrd.nix
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,6 @@ let
};

kernel-name = config.boot.kernelPackages.kernel.name or "kernel";
# 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 = config.system.modulesTree;
firmware = config.hardware.firmware;
allowMissing = false;
inherit (config.boot.initrd) extraFirmwarePaths;
};

initrdBinEnv = pkgs.buildEnv {
name = "initrd-bin-env";
Expand Down Expand Up @@ -477,7 +469,7 @@ in
}
'';

"/lib".source = "${modulesClosure}/lib";
"/lib".source = "${config.system.build.modulesClosure}/lib";

"/etc/modules-load.d/nixos.conf".text = concatStringsSep "\n" config.boot.initrd.kernelModules;

Expand Down
5 changes: 1 addition & 4 deletions nixos/modules/tasks/filesystems.nix
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,7 @@ in
zfs = lib.mkForce false;
}
'';
type = types.coercedTo
(types.listOf types.str)
(enabled: lib.listToAttrs (map (fs: lib.nameValuePair fs true) enabled))
(types.attrsOf types.bool);
type = types.attrNamesToTrue;
description = ''
Names of supported filesystem types, or an attribute set of file system types
and their state. The set form may be used together with `lib.mkForce` to
Expand Down