Skip to content

Commit 05139c1

Browse files
authored
Merge pull request #26 from kolyshkin/add-pid
Implement AddPid for cgroup managers
2 parents 11f71ec + 304da79 commit 05139c1

File tree

8 files changed

+94
-4
lines changed

8 files changed

+94
-4
lines changed

cgroups.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ type Manager interface {
2929
// can be used to merely create a cgroup.
3030
Apply(pid int) error
3131

32+
// AddPid adds a process with a given pid to an existing cgroup.
33+
// The subcgroup argument is either empty, or a path relative to
34+
// a cgroup under under the manager's cgroup.
35+
AddPid(subcgroup string, pid int) error
36+
3237
// GetPids returns the PIDs of all processes inside the cgroup.
3338
GetPids() ([]int, error)
3439

fs/fs.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"path"
8+
"strings"
79
"sync"
810

911
"golang.org/x/sys/unix"
@@ -139,6 +141,33 @@ func (m *Manager) Apply(pid int) (retErr error) {
139141
return retErr
140142
}
141143

144+
// AddPid adds a process with a given pid to an existing cgroup.
145+
// The subcgroup argument is either empty, or a path relative to
146+
// a cgroup under under the manager's cgroup.
147+
func (m *Manager) AddPid(subcgroup string, pid int) (retErr error) {
148+
m.mu.Lock()
149+
defer m.mu.Unlock()
150+
151+
c := m.cgroups
152+
153+
for _, dir := range m.paths {
154+
path := path.Join(dir, subcgroup)
155+
if !strings.HasPrefix(path, dir) {
156+
return fmt.Errorf("bad sub cgroup path: %s", subcgroup)
157+
}
158+
159+
if err := cgroups.WriteCgroupProc(path, pid); err != nil {
160+
if isIgnorableError(c.Rootless, err) && c.Path == "" {
161+
retErr = cgroups.ErrRootless
162+
continue
163+
}
164+
return err
165+
}
166+
}
167+
168+
return retErr
169+
}
170+
142171
func (m *Manager) Destroy() error {
143172
m.mu.Lock()
144173
defer m.mu.Unlock()

fs2/fs2.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"path/filepath"
78
"strings"
89

910
"github.com/opencontainers/cgroups"
@@ -83,6 +84,18 @@ func (m *Manager) Apply(pid int) error {
8384
return nil
8485
}
8586

87+
// AddPid adds a process with a given pid to an existing cgroup.
88+
// The subcgroup argument is either empty, or a path relative to
89+
// a cgroup under under the manager's cgroup.
90+
func (m *Manager) AddPid(subcgroup string, pid int) error {
91+
path := filepath.Join(m.dirPath, subcgroup)
92+
if !strings.HasPrefix(path, m.dirPath) {
93+
return fmt.Errorf("bad sub cgroup path: %s", subcgroup)
94+
}
95+
96+
return cgroups.WriteCgroupProc(path, pid)
97+
}
98+
8699
func (m *Manager) GetPids() ([]int, error) {
87100
return cgroups.GetPids(m.dirPath)
88101
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.23.0
44

55
require (
66
github.com/cilium/ebpf v0.17.3
7-
github.com/coreos/go-systemd/v22 v22.5.0
7+
github.com/coreos/go-systemd/v22 v22.6.0
88
github.com/cyphar/filepath-securejoin v0.4.1
99
github.com/godbus/dbus/v5 v5.1.0
1010
github.com/moby/sys/mountinfo v0.7.2

go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
github.com/cilium/ebpf v0.17.3 h1:FnP4r16PWYSE4ux6zN+//jMcW4nMVRvuTLVTvCjyyjg=
22
github.com/cilium/ebpf v0.17.3/go.mod h1:G5EDHij8yiLzaqn0WjyfJHvRa+3aDlReIaLVRMvOyJk=
3-
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
4-
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
3+
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
4+
github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
55
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
66
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
77
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
88
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
99
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1010
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
1111
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
12-
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
1312
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
1413
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
1514
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=

systemd/common.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"math"
88
"os"
9+
"path"
910
"strconv"
1011
"strings"
1112
"sync"
@@ -208,6 +209,20 @@ func stopUnit(cm *dbusConnManager, unitName string) error {
208209
return nil
209210
}
210211

212+
func addPid(cm *dbusConnManager, unitName, subcgroup string, pid int) error {
213+
absSubcgroup := subcgroup
214+
if !path.IsAbs(absSubcgroup) {
215+
absSubcgroup = "/" + subcgroup
216+
}
217+
if absSubcgroup != path.Clean(absSubcgroup) {
218+
return fmt.Errorf("bad sub cgroup path: %s", subcgroup)
219+
}
220+
221+
return cm.retryOnDisconnect(func(c *systemdDbus.Conn) error {
222+
return c.AttachProcessesToUnit(context.TODO(), unitName, absSubcgroup, []uint32{uint32(pid)})
223+
})
224+
}
225+
211226
func resetFailedUnit(cm *dbusConnManager, name string) error {
212227
return cm.retryOnDisconnect(func(c *systemdDbus.Conn) error {
213228
return c.ResetFailedUnitContext(context.TODO(), name)

systemd/v1.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,25 @@ func (m *LegacyManager) Apply(pid int) error {
215215
return nil
216216
}
217217

218+
// AddPid adds a process with a given pid to an existing cgroup.
219+
// The subcgroup argument is either empty, or a path relative to
220+
// a cgroup under under the manager's cgroup.
221+
func (m *LegacyManager) AddPid(subcgroup string, pid int) error {
222+
m.mu.Lock()
223+
defer m.mu.Unlock()
224+
225+
if err := addPid(m.dbus, getUnitName(m.cgroups), subcgroup, pid); err != nil {
226+
return err
227+
}
228+
229+
// Since systemd only joins controllers it knows, use cgroupfs for the rest.
230+
fsMgr, err := fs.NewManager(m.cgroups, m.paths)
231+
if err != nil {
232+
return err
233+
}
234+
return fsMgr.AddPid(subcgroup, pid)
235+
}
236+
218237
func (m *LegacyManager) Destroy() error {
219238
m.mu.Lock()
220239
defer m.mu.Unlock()

systemd/v2.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,16 @@ func cgroupFilesToChown() ([]string, error) {
383383
return filesToChown, nil
384384
}
385385

386+
// AddPid adds a process with a given pid to an existing cgroup.
387+
// The subcgroup argument is either empty, or a path relative to
388+
// a cgroup under under the manager's cgroup.
389+
func (m *UnifiedManager) AddPid(subcgroup string, pid int) error {
390+
m.mu.Lock()
391+
defer m.mu.Unlock()
392+
393+
return addPid(m.dbus, getUnitName(m.cgroups), subcgroup, pid)
394+
}
395+
386396
func (m *UnifiedManager) Destroy() error {
387397
m.mu.Lock()
388398
defer m.mu.Unlock()

0 commit comments

Comments
 (0)