Skip to content

Commit

Permalink
libpod: improve heuristic to detect cgroup
Browse files Browse the repository at this point in the history
improve the heuristic to detect the scope that was created for the container.
This is necessary with systemd running as PID 1, since it moves itself
to a different sub-cgroup, thus stats would not account for other
processes in the same container.

Closes: #12400

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Nov 24, 2021
1 parent a66f40b commit e648122
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
25 changes: 25 additions & 0 deletions libpod/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import (
"io/ioutil"
"net"
"os"
"strings"
"time"

types040 "github.com/containernetworking/cni/pkg/types/040"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/secrets"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v3/libpod/define"
Expand Down Expand Up @@ -963,6 +965,29 @@ func (c *Container) cGroupPath() (string, error) {
return "", errors.Errorf("could not find any cgroup in %q", procPath)
}

cgroupManager := c.CgroupManager()
switch {
case c.config.CgroupsMode == cgroupSplit:
name := fmt.Sprintf("/libpod-payload-%s/", c.ID())
if index := strings.LastIndex(cgroupPath, name); index >= 0 {
return cgroupPath[:index+len(name)-1], nil
}
case cgroupManager == config.CgroupfsCgroupsManager:
name := fmt.Sprintf("/libpod-%s/", c.ID())
if index := strings.LastIndex(cgroupPath, name); index >= 0 {
return cgroupPath[:index+len(name)-1], nil
}
case cgroupManager == config.SystemdCgroupsManager:
// When running under systemd, try to detect the scope that was requested
// to be created. It improves the heuristic since we report the first
// cgroup that was created instead of the cgroup where PID 1 might have
// moved to.
name := fmt.Sprintf("/libpod-%s.scope/", c.ID())
if index := strings.LastIndex(cgroupPath, name); index >= 0 {
return cgroupPath[:index+len(name)-1], nil
}
}

return cgroupPath, nil
}

Expand Down
2 changes: 1 addition & 1 deletion libpod/container_internal_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2618,7 +2618,7 @@ func (c *Container) getOCICgroupPath() (string, error) {
if err != nil {
return "", err
}
return filepath.Join(selfCgroup, "container"), nil
return filepath.Join(selfCgroup, fmt.Sprintf("libpod-payload-%s", c.ID())), nil
case cgroupManager == config.SystemdCgroupsManager:
// When the OCI runtime is set to use Systemd as a cgroup manager, it
// expects cgroups to be passed as follows:
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/systemd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ WantedBy=multi-user.target
stats := podmanTest.Podman([]string{"stats", "--no-stream", ctrName})
stats.WaitWithDefaultTimeout()
Expect(stats).Should(Exit(0))

cgroupPath := podmanTest.Podman([]string{"inspect", "--format='{{.State.CgroupPath}}'", ctrName})
cgroupPath.WaitWithDefaultTimeout()
Expect(cgroupPath).Should(Exit(0))
Expect(result.OutputToString()).To(Not(ContainSubstring("init.scope")))
})

It("podman create container with systemd entrypoint triggers systemd mode", func() {
Expand Down

0 comments on commit e648122

Please sign in to comment.