Skip to content

Commit 94d16c9

Browse files
committed
libct: move exec sub-cgroup handling down the line
Remove cgroupPaths field from struct setnsProcess, because: - we can get base cgroup paths from p.manager.GetPaths(); - we can get sub-cgroup paths from p.process.SubCgroupPaths. But mostly because we are going to need separate cgroup paths when adopting cgroups.AddPid. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent d47ad24 commit 94d16c9

File tree

2 files changed

+32
-39
lines changed

2 files changed

+32
-39
lines changed

libcontainer/container_linux.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"io"
88
"os"
99
"os/exec"
10-
"path"
1110
"path/filepath"
1211
"reflect"
1312
"strconv"
@@ -651,40 +650,10 @@ func (c *Container) newSetnsProcess(p *Process, cmd *exec.Cmd, comm *processComm
651650
bootstrapData: data,
652651
container: c,
653652
},
654-
cgroupPaths: state.CgroupPaths,
655653
rootlessCgroups: c.config.RootlessCgroups,
656654
intelRdtPath: state.IntelRdtPath,
657655
initProcessPid: state.InitProcessPid,
658656
}
659-
if len(p.SubCgroupPaths) > 0 {
660-
if add, ok := p.SubCgroupPaths[""]; ok {
661-
// cgroup v1: using the same path for all controllers.
662-
// cgroup v2: the only possible way.
663-
for k := range proc.cgroupPaths {
664-
subPath := path.Join(proc.cgroupPaths[k], add)
665-
if !strings.HasPrefix(subPath, proc.cgroupPaths[k]) {
666-
return nil, fmt.Errorf("%s is not a sub cgroup path", add)
667-
}
668-
proc.cgroupPaths[k] = subPath
669-
}
670-
// cgroup v2: do not try to join init process's cgroup
671-
// as a fallback (see (*setnsProcess).start).
672-
proc.initProcessPid = 0
673-
} else {
674-
// Per-controller paths.
675-
for ctrl, add := range p.SubCgroupPaths {
676-
if val, ok := proc.cgroupPaths[ctrl]; ok {
677-
subPath := path.Join(val, add)
678-
if !strings.HasPrefix(subPath, val) {
679-
return nil, fmt.Errorf("%s is not a sub cgroup path", add)
680-
}
681-
proc.cgroupPaths[ctrl] = subPath
682-
} else {
683-
return nil, fmt.Errorf("unknown controller %s in SubCgroupPaths", ctrl)
684-
}
685-
}
686-
}
687-
}
688657
return proc, nil
689658
}
690659

libcontainer/process_linux.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ import (
66
"errors"
77
"fmt"
88
"io"
9+
"maps"
910
"net"
1011
"os"
1112
"os/exec"
13+
"path"
1214
"path/filepath"
1315
"runtime"
1416
"strconv"
17+
"strings"
1518
"sync"
1619
"time"
1720

@@ -153,7 +156,6 @@ func (p *containerProcess) wait() (*os.ProcessState, error) { //nolint:unparam
153156

154157
type setnsProcess struct {
155158
containerProcess
156-
cgroupPaths map[string]string
157159
rootlessCgroups bool
158160
intelRdtPath string
159161
initProcessPid int
@@ -199,7 +201,20 @@ func (p *setnsProcess) setFinalCPUAffinity() error {
199201
}
200202

201203
func (p *setnsProcess) addIntoCgroupV1() error {
202-
for _, path := range p.cgroupPaths {
204+
paths := maps.Clone(p.manager.GetPaths())
205+
for ctrl, sub := range p.process.SubCgroupPaths {
206+
base, ok := paths[ctrl]
207+
if !ok {
208+
return fmt.Errorf("unknown controller %s in SubCgroupPaths", ctrl)
209+
}
210+
cgPath := path.Join(base, sub)
211+
if !strings.HasPrefix(cgPath, base) {
212+
return fmt.Errorf("%s is not a sub cgroup path", sub)
213+
}
214+
paths[ctrl] = cgPath
215+
}
216+
217+
for _, path := range paths {
203218
if err := cgroups.WriteCgroupProc(path, p.pid()); err != nil && !p.rootlessCgroups {
204219
return fmt.Errorf("error adding pid %d to cgroups: %w", p.pid(), err)
205220
}
@@ -209,19 +224,28 @@ func (p *setnsProcess) addIntoCgroupV1() error {
209224
}
210225

211226
func (p *setnsProcess) addIntoCgroupV2() error {
212-
path := p.cgroupPaths[""]
213-
if err := cgroups.WriteCgroupProc(path, p.pid()); err != nil && !p.rootlessCgroups {
227+
base := p.manager.Path("")
228+
sub := ""
229+
if p.process.SubCgroupPaths != nil {
230+
sub = p.process.SubCgroupPaths[""]
231+
}
232+
cgPath := path.Join(base, sub)
233+
if !strings.HasPrefix(cgPath, base) {
234+
return fmt.Errorf("%s is not a sub cgroup path", sub)
235+
}
236+
237+
if err := cgroups.WriteCgroupProc(cgPath, p.pid()); err != nil && !p.rootlessCgroups {
214238
// On cgroup v2 + nesting + domain controllers, WriteCgroupProc may fail with EBUSY.
215239
// https://github.com/opencontainers/runc/issues/2356#issuecomment-621277643
216-
// Try to join the cgroup of InitProcessPid.
217-
if p.initProcessPid != 0 {
240+
// Try to join the cgroup of InitProcessPid, unless sub-cgroup is explicitly set.
241+
if p.initProcessPid != 0 && sub == "" {
218242
initProcCgroupFile := fmt.Sprintf("/proc/%d/cgroup", p.initProcessPid)
219243
initCg, initCgErr := cgroups.ParseCgroupFile(initProcCgroupFile)
220244
if initCgErr == nil {
221245
if initCgPath, ok := initCg[""]; ok {
222246
initCgDirpath := filepath.Join(fs2.UnifiedMountpoint, initCgPath)
223-
logrus.Debugf("adding pid %d to cgroups %v failed (%v), attempting to join %q (obtained from %s)",
224-
p.pid(), p.cgroupPaths, err, initCg, initCgDirpath)
247+
logrus.Debugf("adding pid %d to cgroup %s failed (%v), attempting to join %s",
248+
p.pid(), cgPath, err, initCgDirpath)
225249
// NOTE: initCgDirPath is not guaranteed to exist because we didn't pause the container.
226250
err = cgroups.WriteCgroupProc(initCgDirpath, p.pid())
227251
}

0 commit comments

Comments
 (0)