diff options
author | Will Chandler <wchandler@gitlab.com> | 2023-10-26 23:50:25 +0300 |
---|---|---|
committer | Will Chandler <wchandler@gitlab.com> | 2023-11-08 06:53:57 +0300 |
commit | 2fd5c1d2bd5062257576d25448ac1cd9a97b7f13 (patch) | |
tree | 7ad61da74349b6aedecc3d22e20d003332eae7c8 /internal/cgroups | |
parent | 02a39ec23e6f768d3a57d6c4ca119faf9ccb757d (diff) |
cgroups: Check if cgroup exists in CloneIntoCgroup
Update the `CloneIntoCgroup` method to check if the target cgroup is
present and create it if not.
This also updates the method to be clear that the file handle we open is
for the target cgroup directory, not a file. From clone(2):
This file descriptor can be obtained by opening a cgroup v2
directory using either the O_RDONLY or the O_PATH flag.
Diffstat (limited to 'internal/cgroups')
-rw-r--r-- | internal/cgroups/manager_linux.go | 13 | ||||
-rw-r--r-- | internal/cgroups/manager_linux_test.go | 5 |
2 files changed, 12 insertions, 6 deletions
diff --git a/internal/cgroups/manager_linux.go b/internal/cgroups/manager_linux.go index 7dc5cae42..871174b55 100644 --- a/internal/cgroups/manager_linux.go +++ b/internal/cgroups/manager_linux.go @@ -167,9 +167,14 @@ func (cgm *CGroupManager) maybeCreateCgroup(cgroupPath string) error { // to start the command directly in the correct cgroup. On success, the function returns an io.Closer // that must be closed after the command has been started to close the cgroup's file descriptor. func (cgm *CGroupManager) CloneIntoCgroup(cmd *exec.Cmd, opts ...AddCommandOption) (string, io.Closer, error) { - cgroupPath := filepath.Join(cgm.cfg.Mountpoint, cgm.cgroupPathForCommand(cmd, opts)) + cgroupPath := cgm.cgroupPathForCommand(cmd, opts) + + if err := cgm.maybeCreateCgroup(cgroupPath); err != nil { + return "", nil, fmt.Errorf("setup cgroup: %w", err) + } - file, err := os.Open(cgroupPath) + cgroupDirPath := filepath.Join(cgm.cfg.Mountpoint, cgroupPath) + dir, err := os.Open(cgroupDirPath) if err != nil { return "", nil, fmt.Errorf("open file: %w", err) } @@ -179,9 +184,9 @@ func (cgm *CGroupManager) CloneIntoCgroup(cmd *exec.Cmd, opts ...AddCommandOptio } cmd.SysProcAttr.UseCgroupFD = true - cmd.SysProcAttr.CgroupFD = int(file.Fd()) + cmd.SysProcAttr.CgroupFD = int(dir.Fd()) - return cgroupPath, file, nil + return cgroupDirPath, dir, nil } // cgroupPathForCommand returns the path of the cgroup a given command should go in. diff --git a/internal/cgroups/manager_linux_test.go b/internal/cgroups/manager_linux_test.go index cfc7e5903..3c9878169 100644 --- a/internal/cgroups/manager_linux_test.go +++ b/internal/cgroups/manager_linux_test.go @@ -20,8 +20,9 @@ func TestCloneIntoCgroup(t *testing.T) { // Create the files we expect the manager to open. require.NoError(t, os.MkdirAll(filepath.Join(hierarchyRoot, "gitaly-1"), fs.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(hierarchyRoot, "gitaly-1", "repos-3"), nil, fs.ModePerm)) - require.NoError(t, os.WriteFile(filepath.Join(hierarchyRoot, "gitaly-1", "repos-5"), nil, fs.ModePerm)) + require.NoError(t, os.MkdirAll(filepath.Join(hierarchyRoot, "gitaly-1", "repos-3"), fs.ModePerm)) + require.NoError(t, os.MkdirAll(filepath.Join(hierarchyRoot, "gitaly-1", "repos-5"), fs.ModePerm)) + require.NoError(t, os.WriteFile(filepath.Join(hierarchyRoot, "gitaly-1", "cgroup.subtree_control"), nil, fs.ModePerm)) mgr := NewManager(cgroups.Config{ Mountpoint: mountPoint, |