nixos/systemd/initrd: Check MODULES accurately
`config.system.build.kernel.config` is not actually accurate. When a kconfig is specified in the `config` argument to `kernel/build.nix` (a.k.a. `manualConfig` or `linuxManualConfig`), then `isSet` will return `true` and other queries like `isYes` will be accurate. But if a kconfig is not specified in that `config` argument, then `isSet` will return `false` and other queries will be inaccurate, e.g. `isYes` "MODULES"` can return `false` even though your `configfile` has it enabled. Note the difference between the `config` argument and the `configfile` argument. The `configfile` is how the kernel will be actually built, while `config` is merely passed through as a source of eval-time information. Importantly, neither is derived from the other *in any way*, unless `builtins.isPath configfile || allowImportFromDerivation` in which case the default value for `config` is derived from reading `configfile`. The more generic `kernel/generic.nix` (a.k.a. `buildLinux`) creates its `configfile` in a derivation, so it cannot be read at eval time by default. It calls into `kernel/build.nix`, and only passes a `config` with `CONFIG_MODULES`, `CONFIG_FW_LOADER`, and `CONFIG_RUST` set. So almost nothing in `kernel.config` is accurate in the typical case. `MODULES` happens to be one of the three that *is* accurate typically, but regardless we obviously can't rely on that since a user of `kernel/build.nix` is likely to mess it up. Even worse, `structuredExtraConfig` is not incorporated into `kernel.config` at all, which leads to the incredibly confusing scenario where a kconfig is specified in `structuredExtraConfig` but still is not represented accurately by these queries. All of this is why, in most cases, the implementation of `requiredKernelConfig` deliberately does absolutely nothing and creates an empty list of assertions, and it's all extremely confusing. With all that in mind: TODO: - The structured config used to generate the `configfile` should be reflected in the `config` argument to `kernel/build.nix`, and consequently `kernel.config`. - The three kconfigs represented by `config` in `kernel/generic.nix` now, `CONFIG_MODULES`, `CONFIG_FW_LOADER`, and `CONFIG_RUST`, should be set in the structured config. - Queries for kconfigs that we don't actually know the value of at eval time should fail to evaluate, rather than evaluating inaccurately. - Most of the ways we use these eval-time queries should instead be done at build time, so they can use the complete `configfile` rather than the incomplete eval-time `config` value. - The ones that we still want to happen at eval-time should be more prepared for the possibility that we can't know the value of arbitrary kconfigs at eval time. --- Anyway, all that is to say: I'd like for this all to be better, but am not willing to work on the kernel expressions myself at the moment, so I thought I'd write down the reasons why this change was necessary, and the extent of the problem. We had already successfully considered this issue in one place in `systemd/initrd.nix`, but it seems there are two more places where we should have taken the same care.
This commit is contained in:
@@ -47,6 +47,12 @@ let
|
||||
|
||||
cfg = config.boot.initrd.systemd;
|
||||
|
||||
withKmod =
|
||||
let
|
||||
kconfig = config.system.build.kernel.config;
|
||||
in
|
||||
kconfig.isSet "MODULES" -> kconfig.isYes "MODULES";
|
||||
|
||||
upstreamUnits = [
|
||||
"basic.target"
|
||||
"breakpoint-pre-udev.service"
|
||||
@@ -525,7 +531,7 @@ in
|
||||
pkgs.coreutils
|
||||
cfg.package
|
||||
]
|
||||
++ lib.optional (config.system.build.kernel.config.isYes "MODULES") cfg.package.kmod
|
||||
++ lib.optional withKmod cfg.package.kmod
|
||||
++ lib.optionals cfg.shell.enable [
|
||||
# bashInteractive is easier to use and also required by debug-shell.service
|
||||
pkgs.bashInteractive
|
||||
@@ -575,7 +581,7 @@ in
|
||||
// optionalAttrs (config.environment.etc ? "modprobe.d/nixos.conf") {
|
||||
"/etc/modprobe.d/nixos.conf".source = config.environment.etc."modprobe.d/nixos.conf".source;
|
||||
}
|
||||
// optionalAttrs (with config.system.build.kernel.config; isSet "MODULES" -> isYes "MODULES") {
|
||||
// optionalAttrs withKmod {
|
||||
"/lib".source = "${config.system.build.modulesClosure}/lib";
|
||||
|
||||
"/etc/modules-load.d/nixos.conf".text = concatStringsSep "\n" config.boot.initrd.kernelModules;
|
||||
@@ -660,7 +666,7 @@ in
|
||||
) cfg.automounts
|
||||
);
|
||||
|
||||
services."modprobe@" = lib.mkIf (config.system.build.kernel.config.isYes "MODULES") {
|
||||
services."modprobe@" = lib.mkIf withKmod {
|
||||
serviceConfig.ExecSearchPath = lib.makeBinPath [ cfg.package.kmod ];
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user