Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Chandler <wchandler@gitlab.com>2023-11-09 22:50:50 +0300
committerWill Chandler <wchandler@gitlab.com>2023-11-10 19:07:39 +0300
commit722547075ed32ca72a26fa197c958cb2838cfaee (patch)
tree774fe120f5f504762610e1a1921c65a106465e53
parentbaa2aeb2a7d69635a79dc7395b62acffd29339ef (diff)
cgroups: Add genericHandler
Create a new `genericHandler` to unify most of the logic for cgroups-v1 and v2. This is made generic over two parameters: T: The cgroup type, `cgroup1.Cgroup` or `*cgroup2.Manager`. H: The hierarchy or mountpoint passed when creating a cgroup. For `cgroup1.New` this is a `cgroup1.Hierarchy`, for `cgroup2.New` this is a `string` with the path to the cgroup's mountpoint. Four generic functions are added for the operations that are easily abstracted over. Metrics and stats collection are not included as they involve significant version-specific logic.
-rw-r--r--internal/cgroups/handler_linux.go106
1 files changed, 106 insertions, 0 deletions
diff --git a/internal/cgroups/handler_linux.go b/internal/cgroups/handler_linux.go
new file mode 100644
index 000000000..eaf23b2df
--- /dev/null
+++ b/internal/cgroups/handler_linux.go
@@ -0,0 +1,106 @@
+//go:build linux
+
+package cgroups
+
+import (
+ "github.com/containerd/cgroups/v3/cgroup1"
+ "github.com/containerd/cgroups/v3/cgroup2"
+ "github.com/opencontainers/runtime-spec/specs-go"
+ cgroupscfg "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config/cgroups"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/log"
+)
+
+type (
+ // createCgroupFunc is a function that creates a new cgroup.
+ createCgroupFunc[T any, H any] func(hierarchy H, resources *specs.LinuxResources, path string) (T, error)
+ // loadCgroupFunc is a function that loads an existing cgroup.
+ loadCgroupFunc[T any, H any] func(hierarchy H, path string) (T, error)
+ // addToCgroupFunc is a function that adds a process to an existing cgroup.
+ addToCgroupFunc[T any] func(control T, pid int) error
+ // deleteCgroupFunc is a function that deletes a cgroup.
+ deleteCgroupFunc[T any] func(control T) error
+)
+
+// genericHandler is a cgroup handler that can be instantiated for either cgroups-v1
+// or cgroups-v2.
+type genericHandler[T any, H any] struct {
+ cfg cgroupscfg.Config
+ logger log.Logger
+ pid int
+ supportsClone bool
+
+ // hierarchy is either a cgroup1.Hierarchy or the cgroup2 Mountpoint path.
+ hierarchy H
+ createFunc createCgroupFunc[T, H]
+ loadFunc loadCgroupFunc[T, H]
+ addFunc addToCgroupFunc[T]
+ deleteFunc deleteCgroupFunc[T]
+
+ metrics *cgroupsMetrics
+}
+
+func newV1GenericHandler(
+ cfg cgroupscfg.Config,
+ logger log.Logger,
+ pid int,
+) *genericHandler[cgroup1.Cgroup, cgroup1.Hierarchy] {
+ return &genericHandler[cgroup1.Cgroup, cgroup1.Hierarchy]{
+ cfg: cfg,
+ logger: logger,
+ pid: pid,
+ supportsClone: false,
+ hierarchy: func() ([]cgroup1.Subsystem, error) {
+ return defaultSubsystems(cfg.Mountpoint)
+ },
+ metrics: newV1CgroupsMetrics(),
+ createFunc: func(hierarchy cgroup1.Hierarchy, resources *specs.LinuxResources, cgroupPath string) (cgroup1.Cgroup, error) {
+ return cgroup1.New(
+ cgroup1.StaticPath(cgroupPath),
+ resources,
+ cgroup1.WithHiearchy(hierarchy))
+ },
+ loadFunc: func(hierarchy cgroup1.Hierarchy, cgroupPath string) (cgroup1.Cgroup, error) {
+ return cgroup1.Load(
+ cgroup1.StaticPath(cgroupPath),
+ cgroup1.WithHiearchy(hierarchy),
+ )
+ },
+ addFunc: func(control cgroup1.Cgroup, pid int) error {
+ return control.Add(cgroup1.Process{Pid: pid})
+ },
+ deleteFunc: func(control cgroup1.Cgroup) error {
+ return control.Delete()
+ },
+ }
+}
+
+func newV2GenericHandler(
+ cfg cgroupscfg.Config,
+ logger log.Logger,
+ pid int,
+) *genericHandler[*cgroup2.Manager, string] {
+ return &genericHandler[*cgroup2.Manager, string]{
+ cfg: cfg,
+ logger: logger,
+ pid: pid,
+ supportsClone: true,
+ hierarchy: cfg.Mountpoint,
+ metrics: newV2CgroupsMetrics(),
+ createFunc: func(mountpoint string, resources *specs.LinuxResources, cgroupPath string) (*cgroup2.Manager, error) {
+ return cgroup2.NewManager(
+ mountpoint,
+ "/"+cgroupPath,
+ cgroup2.ToResources(resources),
+ )
+ },
+ loadFunc: func(mountpoint string, cgroupPath string) (*cgroup2.Manager, error) {
+ return cgroup2.Load("/"+cgroupPath, cgroup2.WithMountpoint(mountpoint))
+ },
+ addFunc: func(control *cgroup2.Manager, pid int) error {
+ return control.AddProc(uint64(pid))
+ },
+ deleteFunc: func(control *cgroup2.Manager) error {
+ return control.Delete()
+ },
+ }
+}