From f7cad7376bd823440df1f2f76c1d13cdfa8d4cbe Mon Sep 17 00:00:00 2001
From: suoxiaocong <suoxiaocong@kylinos.cn>
Date: Mon, 22 Apr 2024 15:52:03 +0800
Subject: [PATCH] support systemd cgroup driver

---
 pkg/common/constant/constant.go   |  7 +++++++
 pkg/config/config.go              | 12 +++++++-----
 pkg/core/typedef/cgroup/common.go | 11 +++++++++++
 pkg/core/typedef/containerinfo.go | 16 +++++++++++++++-
 pkg/core/typedef/rawpod.go        | 30 ++++++++++++++++++++++++++++--
 pkg/rubik/rubik.go                |  3 +++
 6 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/pkg/common/constant/constant.go b/pkg/common/constant/constant.go
index 6a1f69d..cf780b8 100644
--- a/pkg/common/constant/constant.go
+++ b/pkg/common/constant/constant.go
@@ -113,3 +113,10 @@ const (
 	// PSIIOCgroupFileName is name of cgroup file used for detecting io psi
 	PSIIOCgroupFileName = "io.pressure"
 )
+
+const (
+	// CgroupDriverSystemd is global config for cgroupfs driver choice:  systemd driver
+	CgroupDriverSystemd = "systemd"
+	// CgroupDriverCgroupfs is global config for cgroupfs driver choice:  cgroupfs driver
+	CgroupDriverCgroupfs = "cgroupfs"
+)
diff --git a/pkg/config/config.go b/pkg/config/config.go
index e0caef3..b8d31a5 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -44,6 +44,7 @@ type AgentConfig struct {
 	LogDir          string   `json:"logDir,omitempty"`
 	CgroupRoot      string   `json:"cgroupRoot,omitempty"`
 	EnabledFeatures []string `json:"enabledFeatures,omitempty"`
+	CgroupDriver    string   `json:"cgroupDriver,omitempty"`
 }
 
 // NewConfig returns an config object pointer
@@ -51,11 +52,12 @@ func NewConfig(pType parserType) *Config {
 	c := &Config{
 		ConfigParser: defaultParserFactory.getParser(pType),
 		Agent: &AgentConfig{
-			LogDriver:  constant.LogDriverStdio,
-			LogSize:    constant.DefaultLogSize,
-			LogLevel:   constant.DefaultLogLevel,
-			LogDir:     constant.DefaultLogDir,
-			CgroupRoot: constant.DefaultCgroupRoot,
+			LogDriver:    constant.LogDriverStdio,
+			LogSize:      constant.DefaultLogSize,
+			LogLevel:     constant.DefaultLogLevel,
+			LogDir:       constant.DefaultLogDir,
+			CgroupRoot:   constant.DefaultCgroupRoot,
+			CgroupDriver: constant.CgroupDriverCgroupfs,
 		},
 	}
 	return c
diff --git a/pkg/core/typedef/cgroup/common.go b/pkg/core/typedef/cgroup/common.go
index 11002ab..668f951 100644
--- a/pkg/core/typedef/cgroup/common.go
+++ b/pkg/core/typedef/cgroup/common.go
@@ -25,6 +25,17 @@ import (
 )
 
 var rootDir = constant.DefaultCgroupRoot
+var cgroupDriver = constant.CgroupDriverCgroupfs
+
+// SetCgroupDriver is the setter of global cgroup driver
+func SetCgroupDriver(driver string) {
+	cgroupDriver = driver
+}
+
+// GetCgroupDriver is the getter of global cgroup driver
+func GetCgroupDriver() string {
+	return cgroupDriver
+}
 
 // AbsoluteCgroupPath returns the absolute path of the cgroup
 func AbsoluteCgroupPath(elem ...string) string {
diff --git a/pkg/core/typedef/containerinfo.go b/pkg/core/typedef/containerinfo.go
index d810e5b..f751b25 100644
--- a/pkg/core/typedef/containerinfo.go
+++ b/pkg/core/typedef/containerinfo.go
@@ -20,6 +20,7 @@ import (
 	"strings"
 	"sync"
 
+	"isula.org/rubik/pkg/common/constant"
 	"isula.org/rubik/pkg/core/typedef/cgroup"
 )
 
@@ -45,6 +46,11 @@ var (
 	}
 	currentContainerEngines = UNDEFINED
 	setContainerEnginesOnce sync.Once
+	containerEngineScopes   = map[ContainerEngineType]string{
+		DOCKER:     "docker",
+		CONTAINERD: "cri-containerd",
+		ISULAD:     "isulad",
+	}
 )
 
 // Support returns true when the container uses the container engine
@@ -76,10 +82,18 @@ type ContainerInfo struct {
 // NewContainerInfo creates a ContainerInfo instance
 func NewContainerInfo(id, podCgroupPath string, rawContainer *RawContainer) *ContainerInfo {
 	requests, limits := rawContainer.GetResourceMaps()
+	var path string
+	if cgroup.GetCgroupDriver() == constant.CgroupDriverSystemd {
+		scopeName := containerEngineScopes[currentContainerEngines]
+		path = filepath.Join(podCgroupPath, scopeName+"-"+id+".scope")
+	} else {
+		path = filepath.Join(podCgroupPath, id)
+	}
+
 	return &ContainerInfo{
 		Name:             rawContainer.status.Name,
 		ID:               id,
-		Hierarchy:        cgroup.Hierarchy{Path: filepath.Join(podCgroupPath, id)},
+		Hierarchy:        cgroup.Hierarchy{Path: path},
 		RequestResources: requests,
 		LimitResources:   limits,
 	}
diff --git a/pkg/core/typedef/rawpod.go b/pkg/core/typedef/rawpod.go
index 138c580..895e9d4 100644
--- a/pkg/core/typedef/rawpod.go
+++ b/pkg/core/typedef/rawpod.go
@@ -23,6 +23,7 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 
 	"isula.org/rubik/pkg/common/constant"
+	"isula.org/rubik/pkg/core/typedef/cgroup"
 )
 
 const (
@@ -103,7 +104,7 @@ func (pod *RawPod) CgroupPath() string {
 		return ""
 	}
 	/*
-		example:
+		for cgroupfs cgroup driver
 		1. Burstable: pod requests are less than the value of limits and not 0;
 		kubepods/burstable/pod34152897-dbaf-11ea-8cb9-0653660051c3
 		2. BestEffort: pod requests and limits are both 0;
@@ -111,7 +112,32 @@ func (pod *RawPod) CgroupPath() string {
 		3. Guaranteed: pod requests are equal to the value set by limits;
 		kubepods/pod34152897-dbaf-11ea-8cb9-0653660051c3
 	*/
-	return filepath.Join(constant.KubepodsCgroup, qosClassPath, constant.PodCgroupNamePrefix+id)
+	/*
+	   for systemd cgroup driver
+	   1. burstable:
+	   kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podb895995a_e7e5_413e_9bc1_3c3895b3f233.slice
+	   2. besteffort
+	   kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podb895995a_e7e5_413e_9bc1_3c3895b3f233.slice
+	   3. guaranteed
+	   kubepods.slice/kubepods-podb895995a_e7e5_413e_9bc1_3c3895b3f233.slice/
+	*/
+
+	if cgroup.GetCgroupDriver() == constant.CgroupDriverSystemd {
+		if qosClassPath == "" {
+			return filepath.Join(
+				constant.KubepodsCgroup+".slice",
+				constant.KubepodsCgroup+"-"+constant.PodCgroupNamePrefix+strings.Replace(id, "-", "_", -1)+".slice",
+			)
+		}
+		return filepath.Join(
+			constant.KubepodsCgroup+".slice",
+			constant.KubepodsCgroup+"-"+qosClassPath+".slice",
+			constant.KubepodsCgroup+"-"+qosClassPath+"-"+constant.PodCgroupNamePrefix+strings.Replace(id, "-", "_", -1)+".slice",
+		)
+	} else {
+		return filepath.Join(constant.KubepodsCgroup, qosClassPath, constant.PodCgroupNamePrefix+id)
+	}
+
 }
 
 // ListRawContainers returns all RawContainers in the RawPod
diff --git a/pkg/rubik/rubik.go b/pkg/rubik/rubik.go
index f55e834..c4fc583 100644
--- a/pkg/rubik/rubik.go
+++ b/pkg/rubik/rubik.go
@@ -126,6 +126,9 @@ func runAgent(ctx context.Context) error {
 
 	// 3. enable cgroup system
 	cgroup.InitMountDir(c.Agent.CgroupRoot)
+	if c.Agent.CgroupDriver != "" {
+		cgroup.SetCgroupDriver(c.Agent.CgroupDriver)
+	}
 
 	// 4. init service components
 	services.InitServiceComponents(defaultRubikFeature)
-- 
2.25.1

