mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
116 lines
2.2 KiB
Go
116 lines
2.2 KiB
Go
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
|
|
// Licensed under the GNU Affero General Public License (AGPL).
|
|
// See License-AGPL.txt in the project root for license information.
|
|
|
|
package cgroups
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
const DefaultCGroupMount = "/sys/fs/cgroup"
|
|
|
|
type CgroupSetup int
|
|
|
|
const (
|
|
Unknown CgroupSetup = iota
|
|
Legacy
|
|
Unified
|
|
)
|
|
|
|
func (s CgroupSetup) String() string {
|
|
return [...]string{"Legacy", "Unified"}[s]
|
|
}
|
|
|
|
func GetCgroupSetup() (CgroupSetup, error) {
|
|
controllers := filepath.Join(DefaultCGroupMount, "cgroup.controllers")
|
|
_, err := os.Stat(controllers)
|
|
|
|
if os.IsNotExist(err) {
|
|
return Legacy, nil
|
|
}
|
|
|
|
if err == nil {
|
|
return Unified, nil
|
|
}
|
|
|
|
return Unknown, err
|
|
}
|
|
|
|
func IsUnifiedCgroupSetup() (bool, error) {
|
|
setup, err := GetCgroupSetup()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return setup == Unified, nil
|
|
}
|
|
|
|
func IsLegacyCgroupSetup() (bool, error) {
|
|
setup, err := GetCgroupSetup()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return setup == Legacy, nil
|
|
}
|
|
|
|
func EnsureCpuControllerEnabled(basePath, cgroupPath string) error {
|
|
targetPath := filepath.Join(basePath, cgroupPath)
|
|
if enabled, err := isCpuControllerEnabled(targetPath); err != nil || enabled {
|
|
return err
|
|
}
|
|
|
|
err := writeCpuController(basePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
levelPath := basePath
|
|
cgroupPath = strings.TrimPrefix(cgroupPath, "/")
|
|
levels := strings.Split(cgroupPath, string(os.PathSeparator))
|
|
for _, l := range levels[:len(levels)-1] {
|
|
levelPath = filepath.Join(levelPath, l)
|
|
err = writeCpuController(levelPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func isCpuControllerEnabled(path string) (bool, error) {
|
|
controllerFile := filepath.Join(path, "cgroup.controllers")
|
|
controllers, err := os.ReadFile(controllerFile)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, ctrl := range strings.Fields(string(controllers)) {
|
|
if ctrl == "cpu" {
|
|
// controller is already activated
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func writeCpuController(path string) error {
|
|
f, err := os.OpenFile(filepath.Join(path, "cgroup.subtree_control"), os.O_WRONLY, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
_, err = f.Write([]byte("+cpu"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|