summaryrefslogtreecommitdiff
path: root/pkg/cgroups/cgroups_supported.go
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2019-09-06 15:30:30 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2019-09-12 08:35:26 +0200
commitafd0818326aa37f03a3bc74f0269a06a403db16d (patch)
tree8ebc91774297027f2c244b22a4428222d42fa3ad /pkg/cgroups/cgroups_supported.go
parentb94a5e241095a55a6838970148d296e109b2afd1 (diff)
downloadpodman-afd0818326aa37f03a3bc74f0269a06a403db16d.tar.gz
podman-afd0818326aa37f03a3bc74f0269a06a403db16d.tar.bz2
podman-afd0818326aa37f03a3bc74f0269a06a403db16d.zip
rootless: automatically create a systemd scope
when running in rootless mode and using systemd as cgroup manager create automatically a systemd scope when the user doesn't own the current cgroup. This solves a couple of issues: on cgroup v2 it is necessary that a process before it can moved to a different cgroup tree must be in a directory owned by the unprivileged user. This is not always true, e.g. when creating a session with su -l. Closes: https://github.com/containers/libpod/issues/3937 Also, for running systemd in a container it was before necessary to specify "systemd-run --scope --user podman ...", now this is done automatically as part of this PR. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/cgroups/cgroups_supported.go')
-rw-r--r--pkg/cgroups/cgroups_supported.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/pkg/cgroups/cgroups_supported.go b/pkg/cgroups/cgroups_supported.go
index fcd44dfc8..2a36777d4 100644
--- a/pkg/cgroups/cgroups_supported.go
+++ b/pkg/cgroups/cgroups_supported.go
@@ -3,8 +3,15 @@
package cgroups
import (
+ "bufio"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
"sync"
"syscall"
+
+ "github.com/pkg/errors"
)
var (
@@ -25,3 +32,58 @@ func IsCgroup2UnifiedMode() (bool, error) {
})
return isUnified, isUnifiedErr
}
+
+// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
+// current cgroup.
+func UserOwnsCurrentSystemdCgroup() (bool, error) {
+ uid := os.Geteuid()
+
+ cgroup2, err := IsCgroup2UnifiedMode()
+ if err != nil {
+ return false, err
+ }
+
+ f, err := os.Open("/proc/self/cgroup")
+ if err != nil {
+ return false, errors.Wrapf(err, "open file /proc/self/cgroup")
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ parts := strings.SplitN(line, ":", 3)
+
+ if len(parts) < 3 {
+ continue
+ }
+
+ var cgroupPath string
+
+ if cgroup2 {
+ cgroupPath = filepath.Join(cgroupRoot, parts[2])
+ } else {
+ if parts[1] != "name=systemd" {
+ continue
+ }
+ cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2])
+ }
+
+ st, err := os.Stat(cgroupPath)
+ if err != nil {
+ return false, err
+ }
+ s := st.Sys()
+ if s == nil {
+ return false, fmt.Errorf("error stat cgroup path %s", cgroupPath)
+ }
+
+ if int(s.(*syscall.Stat_t).Uid) != uid {
+ return false, nil
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ return false, errors.Wrapf(err, "parsing file /proc/self/cgroup")
+ }
+ return true, nil
+}