eb38d5e
From 5fb0f19ec8c52ed0c9bbb3551deb0016992ecc52 Mon Sep 17 00:00:00 2001
eb38d5e
From: Giuseppe Scrivano <gscrivan@redhat.com>
eb38d5e
Date: Thu, 3 Oct 2019 15:58:39 +0200
eb38d5e
Subject: [PATCH] cgroups: raise an error on cgroups v2
eb38d5e
eb38d5e
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
eb38d5e
---
eb38d5e
 create.go      |  8 ++++++++
eb38d5e
 run.go         |  8 ++++++++
eb38d5e
 utils_linux.go | 14 ++++++++++++++
eb38d5e
 3 files changed, 30 insertions(+)
eb38d5e
eb38d5e
diff --git a/create.go b/create.go
eb38d5e
index 5f3ac609..91d17d07 100644
eb38d5e
--- a/create.go
eb38d5e
+++ b/create.go
eb38d5e
@@ -1,6 +1,7 @@
eb38d5e
 package main
eb38d5e
 
eb38d5e
 import (
eb38d5e
+	"fmt"
eb38d5e
 	"os"
eb38d5e
 
eb38d5e
 	"github.com/urfave/cli"
eb38d5e
@@ -52,6 +53,13 @@ command(s) that get executed on start, edit the args parameter of the spec. See
eb38d5e
 		},
eb38d5e
 	},
eb38d5e
 	Action: func(context *cli.Context) error {
eb38d5e
+		unified, err := IsCgroup2UnifiedMode()
eb38d5e
+		if  err != nil {
eb38d5e
+			return err
eb38d5e
+		}
eb38d5e
+		if unified {
eb38d5e
+			return fmt.Errorf("this version of runc doesn't work on cgroups v2")
eb38d5e
+		}
eb38d5e
 		if err := checkArgs(context, 1, exactArgs); err != nil {
eb38d5e
 			return err
eb38d5e
 		}
eb38d5e
diff --git a/run.go b/run.go
eb38d5e
index f8d63178..3f29737b 100644
eb38d5e
--- a/run.go
eb38d5e
+++ b/run.go
eb38d5e
@@ -3,6 +3,7 @@
eb38d5e
 package main
eb38d5e
 
eb38d5e
 import (
eb38d5e
+	"fmt"
eb38d5e
 	"os"
eb38d5e
 
eb38d5e
 	"github.com/urfave/cli"
eb38d5e
@@ -63,6 +64,13 @@ command(s) that get executed on start, edit the args parameter of the spec. See
eb38d5e
 		},
eb38d5e
 	},
eb38d5e
 	Action: func(context *cli.Context) error {
eb38d5e
+		unified, err := IsCgroup2UnifiedMode()
eb38d5e
+		if  err != nil {
eb38d5e
+			return err
eb38d5e
+		}
eb38d5e
+		if unified {
eb38d5e
+			return fmt.Errorf("this version of runc doesn't work on cgroups v2")
eb38d5e
+		}
eb38d5e
 		if err := checkArgs(context, 1, exactArgs); err != nil {
eb38d5e
 			return err
eb38d5e
 		}
eb38d5e
diff --git a/utils_linux.go b/utils_linux.go
eb38d5e
index 984e6b0f..a5a03de9 100644
eb38d5e
--- a/utils_linux.go
eb38d5e
+++ b/utils_linux.go
eb38d5e
@@ -9,6 +9,7 @@ import (
eb38d5e
 	"os/exec"
eb38d5e
 	"path/filepath"
eb38d5e
 	"strconv"
eb38d5e
+	"syscall"
eb38d5e
 
eb38d5e
 	"github.com/opencontainers/runc/libcontainer"
eb38d5e
 	"github.com/opencontainers/runc/libcontainer/cgroups/systemd"
eb38d5e
@@ -26,6 +27,10 @@ import (
eb38d5e
 	"golang.org/x/sys/unix"
eb38d5e
 )
eb38d5e
 
eb38d5e
+const (
eb38d5e
+	_cgroup2SuperMagic = 0x63677270
eb38d5e
+)
eb38d5e
+
eb38d5e
 var errEmptyID = errors.New("container id cannot be empty")
eb38d5e
 
eb38d5e
 // loadFactory returns the configured factory instance for execing containers.
eb38d5e
@@ -451,3 +456,12 @@ func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOp
eb38d5e
 	}
eb38d5e
 	return r.run(spec.Process)
eb38d5e
 }
eb38d5e
+
eb38d5e
+// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
eb38d5e
+func IsCgroup2UnifiedMode() (bool, error) {
eb38d5e
+	var st syscall.Statfs_t
eb38d5e
+	if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
eb38d5e
+		return false, err
eb38d5e
+	}
eb38d5e
+	return st.Type == _cgroup2SuperMagic, nil
eb38d5e
+}
eb38d5e
-- 
eb38d5e
2.21.0
eb38d5e