diff --git a/validators/cgroup_validator_other.go b/validators/cgroup_validator_other.go index 9d74a7b..1486756 100644 --- a/validators/cgroup_validator_other.go +++ b/validators/cgroup_validator_other.go @@ -23,6 +23,8 @@ package system var _ Validator = &CgroupsValidator{} +const mountsFilePath = "" + // CgroupsValidator validates cgroup configuration. type CgroupsValidator struct { Reporter Reporter @@ -37,3 +39,8 @@ func (c *CgroupsValidator) Validate(spec SysSpec) (warns, errs []error) { func (c *CgroupsValidator) Name() string { return "cgroups" } + +// getUnifiedMountpoint is a no-op for non-Linux OSes. +func getUnifiedMountpoint(path string) (string, bool, error) { + return "", false, nil +} diff --git a/validators/kernel_validator.go b/validators/kernel_validator.go index ffad149..0b37396 100644 --- a/validators/kernel_validator.go +++ b/validators/kernel_validator.go @@ -70,7 +70,8 @@ func (k *KernelValidator) Validate(spec SysSpec) ([]error, []error) { warns = append(warns, warn) } // only validate kernel config when necessary (currently no kernel config for windows) - if len(spec.KernelSpec.Required) > 0 || len(spec.KernelSpec.Forbidden) > 0 || len(spec.KernelSpec.Optional) > 0 { + if len(spec.KernelSpec.Required) > 0 || len(spec.KernelSpec.Forbidden) > 0 || len(spec.KernelSpec.Optional) > 0 || + len(spec.KernelSpec.RequiredCgroupsV1) > 0 || len(spec.KernelSpec.RequiredCgroupsV2) > 0 { if err = k.validateKernelConfig(spec.KernelSpec); err != nil { errs = append(errs, err) } @@ -158,6 +159,20 @@ func (k *KernelValidator) validateCachedKernelConfig(allConfig map[string]kConfi for _, config := range kSpec.Required { validateOpt(config, required) } + _, isCgroupsV2, err := getUnifiedMountpoint(mountsFilePath) + if err != nil { + return fmt.Errorf("failed to get unified mountpoint: %w", err) + } + if isCgroupsV2 { + for _, config := range kSpec.RequiredCgroupsV2 { + validateOpt(config, required) + } + } else { + for _, config := range kSpec.RequiredCgroupsV1 { + validateOpt(config, required) + } + } + for _, config := range kSpec.Optional { validateOpt(config, optional) } diff --git a/validators/types.go b/validators/types.go index eee7e81..10e38d6 100644 --- a/validators/types.go +++ b/validators/types.go @@ -46,7 +46,12 @@ type KernelSpec struct { VersionsNote string `json:"versionsNote,omitempty"` // Required contains all kernel configurations required to be enabled // (built in or as module). + // RequiredCgroupsV1 and RequiredCgroupsV2 are mutually exclusive. Required []KernelConfig `json:"required,omitempty"` + // RequiredCgroupsV1 contains all kernel configurations required to be enabled for cgroups v1. + RequiredCgroupsV1 []KernelConfig `json:"requiredCgroupsV1,omitempty"` + // RequiredCgroupsV2 contains all kernel configurations required to be enabled for cgroups v2. + RequiredCgroupsV2 []KernelConfig `json:"requiredCgroupsV2,omitempty"` // Optional contains all kernel configurations are required for optional // features. Optional []KernelConfig `json:"optional,omitempty"` diff --git a/validators/types_unix.go b/validators/types_unix.go index e2fc25f..b100dc2 100644 --- a/validators/types_unix.go +++ b/validators/types_unix.go @@ -41,7 +41,6 @@ var DefaultSysSpec = SysSpec{ {Name: "PID_NS"}, {Name: "IPC_NS"}, {Name: "UTS_NS"}, - {Name: "CGROUPS"}, {Name: "CPUSETS"}, {Name: "MEMCG"}, {Name: "INET"}, @@ -51,6 +50,20 @@ var DefaultSysSpec = SysSpec{ {Name: "NETFILTER_XT_MATCH_COMMENT"}, {Name: "FAIR_GROUP_SCHED"}, }, + RequiredCgroupsV1: []KernelConfig{ + {Name: "CGROUPS", Description: "Required for cgroups."}, + {Name: "CGROUP_CPUACCT", Description: "Required for cpuacct controller, used in simple CPU accounting controller."}, + {Name: "CGROUP_DEVICE", Description: "Required for device controller."}, + {Name: "CGROUP_FREEZER", Description: "Required for freezer controller."}, + {Name: "CGROUP_PIDS", Description: "Required for PIDs controller."}, + {Name: "CGROUP_SCHED", Description: "Required for CPU controller."}, + }, + RequiredCgroupsV2: []KernelConfig{ + {Name: "CGROUPS", Description: "Required for cgroups."}, + {Name: "CGROUP_BPF", Description: "Required for eBPF programs attached to cgroups, used in device controller."}, + {Name: "CGROUP_PIDS", Description: "Required for PIDs controller."}, + {Name: "CGROUP_SCHED", Description: "Required for CPU controller."}, + }, Optional: []KernelConfig{ {Name: "OVERLAY_FS", Aliases: []string{"OVERLAYFS_FS"}, Description: "Required for overlayfs."}, {Name: "AUFS_FS", Description: "Required for aufs."},