From 34e2cda9ad6a20861844776abfbb45052d20c3fa Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Mon, 22 Feb 2021 15:54:58 -0800 Subject: Return nicer error message when cgroups v1 isn't available Updates #3481 Closes #5430 PiperOrigin-RevId: 358923208 --- runsc/cgroup/BUILD | 1 + runsc/cgroup/cgroup.go | 11 +++++++++++ runsc/container/container.go | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/runsc/cgroup/BUILD b/runsc/cgroup/BUILD index 37f4253ba..f7e892584 100644 --- a/runsc/cgroup/BUILD +++ b/runsc/cgroup/BUILD @@ -11,6 +11,7 @@ go_library( "//pkg/log", "@com_github_cenkalti_backoff//:go_default_library", "@com_github_opencontainers_runtime_spec//specs-go:go_default_library", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index 797c1c2bc..ac9e4e3a8 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -32,6 +32,7 @@ import ( "github.com/cenkalti/backoff" specs "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/cleanup" "gvisor.dev/gvisor/pkg/log" ) @@ -59,6 +60,16 @@ var controllers = map[string]config{ "systemd": {ctrlr: &noop{}}, } +// IsOnlyV2 checks whether cgroups V2 is enabled and V1 is not. +func IsOnlyV2() bool { + var stat unix.Statfs_t + if err := unix.Statfs(cgroupRoot, &stat); err != nil { + // It's not used for anything important, assume not V2 on failure. + return false + } + return stat.Type == unix.CGROUP2_SUPER_MAGIC +} + func setOptionalValueInt(path, name string, val *int64) error { if val == nil || *val == 0 { return nil diff --git a/runsc/container/container.go b/runsc/container/container.go index aae64ae1c..40812efb8 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -230,7 +230,6 @@ func New(conf *config.Config, args Args) (*Container, error) { if args.Spec.Linux.CgroupsPath == "" && !conf.TestOnlyAllowRunAsCurrentUserWithoutChroot { args.Spec.Linux.CgroupsPath = "/" + args.ID } - // Create and join cgroup before processes are created to ensure they are // part of the cgroup from the start (and all their children processes). cg, err := cgroup.New(args.Spec) @@ -238,6 +237,10 @@ func New(conf *config.Config, args Args) (*Container, error) { return nil, err } if cg != nil { + // TODO(gvisor.dev/issue/3481): Remove when cgroups v2 is supported. + if !conf.Rootless && cgroup.IsOnlyV2() { + return nil, fmt.Errorf("cgroups V2 is not yet supported. Enable cgroups V1 and retry") + } // If there is cgroup config, install it before creating sandbox process. if err := cg.Install(args.Spec.Linux.Resources); err != nil { switch { -- cgit v1.2.3