Merge pull request #84032 from teto/fix_kernel_merge

Fix kernel configuration merge

Changed files
+68 -45
lib
nixos
modules
system
pkgs
os-specific
test
+4 -4
lib/kernel.nix
···
option = x:
x // { optional = true; };
-
yes = { tristate = "y"; };
-
no = { tristate = "n"; };
-
module = { tristate = "m"; };
-
freeform = x: { freeform = x; };
+
yes = { tristate = "y"; optional = false; };
+
no = { tristate = "n"; optional = false; };
+
module = { tristate = "m"; optional = false; };
+
freeform = x: { freeform = x; optional = false; };
/*
Common patterns/legacy used in common-config/hardened/config.nix
+3 -2
nixos/modules/system/boot/kernel_config.nix
···
mergeFalseByDefault = locs: defs:
if defs == [] then abort "This case should never happen."
-
else if any (x: x == false) defs then false
+
else if any (x: x == false) (getValues defs) then false
else true;
kernelItem = types.submodule {
···
default = false;
description = ''
Wether option should generate a failure when unused.
+
Upon merging values, mandatory wins over optional.
'';
};
};
···
type = types.attrsOf kernelItem;
example = literalExample '' with lib.kernel; {
"9P_NET" = yes;
-
USB = optional yes;
+
USB = option yes;
MMC_BLOCK_MINORS = freeform "32";
}'';
description = ''
+4 -5
pkgs/os-specific/linux/kernel/common-config.nix
···
TIMER_STATS = whenOlder "4.11" yes;
DEBUG_NX_TEST = whenOlder "4.11" no;
DEBUG_STACK_USAGE = no;
-
DEBUG_STACKOVERFLOW = mkIf (!features.grsecurity) no;
+
DEBUG_STACKOVERFLOW = mkIf (!features.grsecurity) (option no);
RCU_TORTURE_TEST = no;
SCHEDSTATS = no;
DETECT_HUNG_TASK = yes;
···
# needed for ss
INET_DIAG = yes;
-
INET_TCP_DIAG = module;
INET_UDP_DIAG = module;
INET_RAW_DIAG = whenAtLeast "4.14" module;
INET_DIAG_DESTROY = whenAtLeast "4.9" yes;
···
CIFS_STATS = whenOlder "4.19" yes;
CIFS_WEAK_PW_HASH = yes;
CIFS_UPCALL = yes;
-
CIFS_ACL = yes;
+
CIFS_ACL = option yes;
CIFS_DFS_UPCALL = yes;
CIFS_SMB2 = whenOlder "4.13" yes;
···
DEBUG_SET_MODULE_RONX = { optional = true; tristate = whenOlder "4.11" "y"; };
RANDOMIZE_BASE = option yes;
STRICT_DEVMEM = option yes; # Filter access to /dev/mem
-
SECURITY_SELINUX_BOOTPARAM_VALUE = freeform "0"; # Disable SELinux by default
+
SECURITY_SELINUX_BOOTPARAM_VALUE = option (freeform "0"); # Disable SELinux by default
# Prevent processes from ptracing non-children processes
SECURITY_YAMA = option yes;
DEVKMEM = mkIf (!features.grsecurity) no; # Disable /dev/kmem
···
KEXEC_JUMP = option yes;
# Windows Logical Disk Manager (Dynamic Disk) support
-
LDM_PARTITION = yes;
+
LDM_PARTITION = option yes;
LOGIRUMBLEPAD2_FF = yes; # Logitech Rumblepad 2 force feedback
LOGO = no; # not needed
MEDIA_ATTACH = yes;
-3
pkgs/os-specific/linux/kernel/generic.nix
···
;
}).config;
-
#
structuredConfig = moduleStructuredConfig.settings;
};
-
-
}; # end of configfile derivation
kernel = (callPackage ./manual-config.nix {}) {
+57 -31
pkgs/test/kernel.nix
···
+
# to run these tests:
+
# nix-instantiate --eval --strict . -A tests.kernel-config
+
#
+
# make sure to use NON EXISTING kernel settings else they may conflict with
+
# common-config.nix
{ lib, pkgs }:
-
with lib.kernel;
-
with lib.asserts;
-
with lib.modules;
+
with lib;
+
with kernel;
-
# To test nixos/modules/system/boot/kernel_config.nix;
let
-
# copied from release-lib.nix
-
assertTrue = bool:
-
if bool
-
then pkgs.runCommand "evaluated-to-true" {} "touch $out"
-
else pkgs.runCommand "evaluated-to-false" {} "false";
-
lts_kernel = pkgs.linuxPackages.kernel;
-
kernelTestConfig = structuredConfig: (lts_kernel.override {
-
structuredExtraConfig = structuredConfig;
-
}).configfile.structuredConfig;
+
# to see the result once the module transformed the lose structured config
+
getConfig = structuredConfig:
+
(lts_kernel.override {
+
structuredExtraConfig = structuredConfig;
+
}).configfile.structuredConfig;
mandatoryVsOptionalConfig = mkMerge [
-
{ USB_DEBUG = option yes;}
-
{ USB_DEBUG = yes;}
+
{ NIXOS_FAKE_USB_DEBUG = yes;}
+
{ NIXOS_FAKE_USB_DEBUG = option yes; }
];
freeformConfig = mkMerge [
-
{ MMC_BLOCK_MINORS = freeform "32"; } # same as default, won't trigger any error
-
{ MMC_BLOCK_MINORS = freeform "64"; } # will trigger an error but the message is not great:
+
{ NIXOS_FAKE_MMC_BLOCK_MINORS = freeform "32"; } # same as default, won't trigger any error
+
{ NIXOS_FAKE_MMC_BLOCK_MINORS = freeform "64"; } # will trigger an error but the message is not great:
];
yesWinsOverNoConfig = mkMerge [
-
# default for "8139TOO_PIO" is no
-
{ "8139TOO_PIO" = yes; } # yes wins over no by default
-
{ "8139TOO_PIO" = no; }
+
# default for "NIXOS_TEST_BOOLEAN" is no
+
{ "NIXOS_TEST_BOOLEAN" = yes; } # yes wins over no by default
+
{ "NIXOS_TEST_BOOLEAN" = no; }
+
];
+
+
optionalNoWins = mkMerge [
+
{ NIXOS_FAKE_USB_DEBUG = option yes;}
+
{ NIXOS_FAKE_USB_DEBUG = yes;}
];
+
+
allOptionalRemainOptional = mkMerge [
+
{ NIXOS_FAKE_USB_DEBUG = option yes;}
+
{ NIXOS_FAKE_USB_DEBUG = option yes;}
+
];
+
in
-
{
+
runTests {
+
testEasy = {
+
expr = (getConfig { NIXOS_FAKE_USB_DEBUG = yes;}).NIXOS_FAKE_USB_DEBUG;
+
expected = { tristate = "y"; optional = false; freeform = null; };
+
};
+
# mandatory flag should win over optional
-
mandatoryCheck = (kernelTestConfig mandatoryVsOptionalConfig);
+
testMandatoryCheck = {
+
expr = (getConfig mandatoryVsOptionalConfig).NIXOS_FAKE_USB_DEBUG.optional;
+
expected = false;
+
};
+
+
testYesWinsOverNo = {
+
expr = (getConfig yesWinsOverNoConfig)."NIXOS_TEST_BOOLEAN".tristate;
+
expected = "y";
+
};
+
+
testAllOptionalRemainOptional = {
+
expr = (getConfig allOptionalRemainOptional)."NIXOS_FAKE_USB_DEBUG".optional;
+
expected = true;
+
};
# check that freeform options are unique
# Should trigger
-
# > The option `settings.MMC_BLOCK_MINORS.freeform' has conflicting definitions, in `<unknown-file>' and `<unknown-file>'
-
freeformCheck = let
-
res = builtins.tryEval ( (kernelTestConfig freeformConfig).MMC_BLOCK_MINORS.freeform);
-
in
-
assertTrue (res.success == false);
+
# > The option `settings.NIXOS_FAKE_MMC_BLOCK_MINORS.freeform' has conflicting definitions, in `<unknown-file>' and `<unknown-file>'
+
testTreeform = let
+
res = builtins.tryEval ( (getConfig freeformConfig).NIXOS_FAKE_MMC_BLOCK_MINORS.freeform);
+
in {
+
expr = res.success;
+
expected = false;
+
};
-
yesVsNoCheck = let
-
res = kernelTestConfig yesWinsOverNoConfig;
-
in
-
assertTrue (res."8139TOO_PIO".tristate == "y");
}