mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-10 21:53:57 +08:00
libct: use manager.AddPid to add exec to cgroup
The main benefit here is when we are using a systemd cgroup driver, we actually ask systemd to add a PID, rather than doing it ourselves. This way, we can add rootless exec PID to a cgroup. This requires newer opencontainers/cgroups and coreos/go-systemd. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
+5
@@ -29,6 +29,11 @@ type Manager interface {
|
||||
// can be used to merely create a cgroup.
|
||||
Apply(pid int) error
|
||||
|
||||
// AddPid adds a process with a given pid to an existing cgroup.
|
||||
// The subcgroup argument is either empty, or a path relative to
|
||||
// a cgroup under under the manager's cgroup.
|
||||
AddPid(subcgroup string, pid int) error
|
||||
|
||||
// GetPids returns the PIDs of all processes inside the cgroup.
|
||||
GetPids() ([]int, error)
|
||||
|
||||
|
||||
+29
@@ -4,6 +4,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -139,6 +141,33 @@ func (m *Manager) Apply(pid int) (retErr error) {
|
||||
return retErr
|
||||
}
|
||||
|
||||
// AddPid adds a process with a given pid to an existing cgroup.
|
||||
// The subcgroup argument is either empty, or a path relative to
|
||||
// a cgroup under under the manager's cgroup.
|
||||
func (m *Manager) AddPid(subcgroup string, pid int) (retErr error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
c := m.cgroups
|
||||
|
||||
for _, dir := range m.paths {
|
||||
path := path.Join(dir, subcgroup)
|
||||
if !strings.HasPrefix(path, dir) {
|
||||
return fmt.Errorf("bad sub cgroup path: %s", subcgroup)
|
||||
}
|
||||
|
||||
if err := cgroups.WriteCgroupProc(path, pid); err != nil {
|
||||
if isIgnorableError(c.Rootless, err) && c.Path == "" {
|
||||
retErr = cgroups.ErrRootless
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return retErr
|
||||
}
|
||||
|
||||
func (m *Manager) Destroy() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
+13
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/cgroups"
|
||||
@@ -83,6 +84,18 @@ func (m *Manager) Apply(pid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddPid adds a process with a given pid to an existing cgroup.
|
||||
// The subcgroup argument is either empty, or a path relative to
|
||||
// a cgroup under under the manager's cgroup.
|
||||
func (m *Manager) AddPid(subcgroup string, pid int) error {
|
||||
path := filepath.Join(m.dirPath, subcgroup)
|
||||
if !strings.HasPrefix(path, m.dirPath) {
|
||||
return fmt.Errorf("bad sub cgroup path: %s", subcgroup)
|
||||
}
|
||||
|
||||
return cgroups.WriteCgroupProc(path, pid)
|
||||
}
|
||||
|
||||
func (m *Manager) GetPids() ([]int, error) {
|
||||
return cgroups.GetPids(m.dirPath)
|
||||
}
|
||||
|
||||
+15
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -208,6 +209,20 @@ func stopUnit(cm *dbusConnManager, unitName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func addPid(cm *dbusConnManager, unitName, subcgroup string, pid int) error {
|
||||
absSubcgroup := subcgroup
|
||||
if !path.IsAbs(absSubcgroup) {
|
||||
absSubcgroup = "/" + subcgroup
|
||||
}
|
||||
if absSubcgroup != path.Clean(absSubcgroup) {
|
||||
return fmt.Errorf("bad sub cgroup path: %s", subcgroup)
|
||||
}
|
||||
|
||||
return cm.retryOnDisconnect(func(c *systemdDbus.Conn) error {
|
||||
return c.AttachProcessesToUnit(context.TODO(), unitName, absSubcgroup, []uint32{uint32(pid)})
|
||||
})
|
||||
}
|
||||
|
||||
func resetFailedUnit(cm *dbusConnManager, name string) error {
|
||||
return cm.retryOnDisconnect(func(c *systemdDbus.Conn) error {
|
||||
return c.ResetFailedUnitContext(context.TODO(), name)
|
||||
|
||||
+19
@@ -215,6 +215,25 @@ func (m *LegacyManager) Apply(pid int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddPid adds a process with a given pid to an existing cgroup.
|
||||
// The subcgroup argument is either empty, or a path relative to
|
||||
// a cgroup under under the manager's cgroup.
|
||||
func (m *LegacyManager) AddPid(subcgroup string, pid int) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if err := addPid(m.dbus, getUnitName(m.cgroups), subcgroup, pid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Since systemd only joins controllers it knows, use cgroupfs for the rest.
|
||||
fsMgr, err := fs.NewManager(m.cgroups, m.paths)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fsMgr.AddPid(subcgroup, pid)
|
||||
}
|
||||
|
||||
func (m *LegacyManager) Destroy() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
+10
@@ -383,6 +383,16 @@ func cgroupFilesToChown() ([]string, error) {
|
||||
return filesToChown, nil
|
||||
}
|
||||
|
||||
// AddPid adds a process with a given pid to an existing cgroup.
|
||||
// The subcgroup argument is either empty, or a path relative to
|
||||
// a cgroup under under the manager's cgroup.
|
||||
func (m *UnifiedManager) AddPid(subcgroup string, pid int) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
return addPid(m.dbus, getUnitName(m.cgroups), subcgroup, pid)
|
||||
}
|
||||
|
||||
func (m *UnifiedManager) Destroy() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user