diff --git a/lib/kernel.nix b/lib/kernel.nix index 8045a228d05..ffcbc268b76 100644 --- a/lib/kernel.nix +++ b/lib/kernel.nix @@ -8,10 +8,10 @@ with lib; 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 diff --git a/nixos/modules/system/boot/kernel_config.nix b/nixos/modules/system/boot/kernel_config.nix index a316782dfc5..85bd420e304 100644 --- a/nixos/modules/system/boot/kernel_config.nix +++ b/nixos/modules/system/boot/kernel_config.nix @@ -22,7 +22,7 @@ let 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 { @@ -55,6 +55,7 @@ let default = false; description = '' Wether option should generate a failure when unused. + Upon merging values, mandatory wins over optional. ''; }; }; @@ -121,7 +122,7 @@ in type = types.attrsOf kernelItem; example = literalExample '' with lib.kernel; { "9P_NET" = yes; - USB = optional yes; + USB = option yes; MMC_BLOCK_MINORS = freeform "32"; }''; description = '' diff --git a/pkgs/os-specific/linux/kernel/common-config.nix b/pkgs/os-specific/linux/kernel/common-config.nix index c715c7baf78..d239455ad34 100644 --- a/pkgs/os-specific/linux/kernel/common-config.nix +++ b/pkgs/os-specific/linux/kernel/common-config.nix @@ -42,7 +42,7 @@ let 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; @@ -184,7 +184,6 @@ let # 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; @@ -365,7 +364,7 @@ let 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; @@ -396,7 +395,7 @@ let 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 @@ -709,7 +708,7 @@ let 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; diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix index e6e1bd84236..a9d0cf45168 100644 --- a/pkgs/os-specific/linux/kernel/generic.nix +++ b/pkgs/os-specific/linux/kernel/generic.nix @@ -158,11 +158,8 @@ let ; }).config; - # structuredConfig = moduleStructuredConfig.settings; }; - - }; # end of configfile derivation kernel = (callPackage ./manual-config.nix {}) { diff --git a/pkgs/test/kernel.nix b/pkgs/test/kernel.nix index 86f1b8d8e9a..a4da1003033 100644 --- a/pkgs/test/kernel.nix +++ b/pkgs/test/kernel.nix @@ -1,53 +1,79 @@ +# 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 `' and `' - 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 `' and `' + 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"); }