diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-12-02 22:07:55 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-12-03 10:03:39 +0100 |
commit | 9a33e064a16c2d281d1946c8efa89599624e7a70 (patch) | |
tree | 97d46809546945eac7a7421e7904bdc2aeed87e4 | |
parent | 9c5fe954cca8b4bcb8f552645e1f52a5d9824134 (diff) | |
download | podman-9a33e064a16c2d281d1946c8efa89599624e7a70.tar.gz podman-9a33e064a16c2d281d1946c8efa89599624e7a70.tar.bz2 podman-9a33e064a16c2d281d1946c8efa89599624e7a70.zip |
podman, exec: move conmon to the correct cgroup
move the conmon process to the conmon cgroup also on exec.
The previous implementation would fail to move the conmon process as
the systemd unit already exists so its creation would fail.
When the unit cannot be created, attempt to directly join the cgroup
instead.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r-- | utils/utils_supported.go | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/utils/utils_supported.go b/utils/utils_supported.go index bcaa2c61a..e6978ca6f 100644 --- a/utils/utils_supported.go +++ b/utils/utils_supported.go @@ -43,6 +43,15 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error { ch := make(chan string) _, err = conn.StartTransientUnit(unitName, "replace", properties, ch) if err != nil { + // On errors check if the cgroup already exists, if it does move the process there + if props, err := conn.GetUnitTypeProperties(unitName, "Scope"); err == nil { + if cgroup, ok := props["ControlGroup"].(string); ok && cgroup != "" { + if err := moveUnderCgroup(cgroup, "", []uint32{uint32(pid)}); err != nil { + return err + } + return nil + } + } return err } defer conn.Close() @@ -101,6 +110,13 @@ func GetCgroupProcess(pid int) (string, error) { // MoveUnderCgroupSubtree moves the PID under a cgroup subtree. func MoveUnderCgroupSubtree(subtree string) error { + return moveUnderCgroup("", subtree, nil) +} + +// moveUnderCgroup moves a group of processes to a new cgroup. +// If cgroup is the empty string, then the current calling process cgroup is used. +// If processes is empty, then the processes from the current cgroup are moved. +func moveUnderCgroup(cgroup, subtree string, processes []uint32) error { procFile := "/proc/self/cgroup" f, err := os.Open(procFile) if err != nil { @@ -140,13 +156,12 @@ func MoveUnderCgroupSubtree(subtree string) error { cgroupRoot = filepath.Join(cgroupRoot, controller) } - processes, err := ioutil.ReadFile(filepath.Join(cgroupRoot, parts[2], "cgroup.procs")) - if err != nil { - return err + parentCgroup := cgroup + if parentCgroup == "" { + parentCgroup = parts[2] } - - newCgroup := filepath.Join(cgroupRoot, parts[2], subtree) - if err := os.Mkdir(newCgroup, 0755); err != nil { + newCgroup := filepath.Join(cgroupRoot, parentCgroup, subtree) + if err := os.Mkdir(newCgroup, 0755); err != nil && !os.IsExist(err) { return err } @@ -156,9 +171,21 @@ func MoveUnderCgroupSubtree(subtree string) error { } defer f.Close() - for _, pid := range bytes.Split(processes, []byte("\n")) { - if _, err := f.Write(pid); err != nil { - logrus.Warnf("Cannot move process %s to cgroup %q", pid, newCgroup) + if len(processes) > 0 { + for _, pid := range processes { + if _, err := f.Write([]byte(fmt.Sprintf("%d\n", pid))); err != nil { + logrus.Warnf("Cannot move process %d to cgroup %q", pid, newCgroup) + } + } + } else { + processesData, err := ioutil.ReadFile(filepath.Join(cgroupRoot, parts[2], "cgroup.procs")) + if err != nil { + return err + } + for _, pid := range bytes.Split(processesData, []byte("\n")) { + if _, err := f.Write(pid); err != nil { + logrus.Warnf("Cannot move process %d to cgroup %q", pid, newCgroup) + } } } } |