diff --git a/libcontainer/cgroups/systemd/user.go b/libcontainer/cgroups/systemd/user.go index 9698e140f0a..8fe91688477 100644 --- a/libcontainer/cgroups/systemd/user.go +++ b/libcontainer/cgroups/systemd/user.go @@ -57,7 +57,7 @@ func DetectUID() (int, error) { } b, err := exec.Command("busctl", "--user", "--no-pager", "status").CombinedOutput() if err != nil { - return -1, errors.Wrap(err, "could not execute `busctl --user --no-pager status`") + return -1, errors.Wrapf(err, "could not execute `busctl --user --no-pager status`: %q", string(b)) } scanner := bufio.NewScanner(bytes.NewReader(b)) for scanner.Scan() { diff --git a/rootless_linux.go b/rootless_linux.go index 78d840dbab6..348f7c4ffca 100644 --- a/rootless_linux.go +++ b/rootless_linux.go @@ -5,7 +5,9 @@ package main import ( "os" + "github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/system" + "github.com/sirupsen/logrus" "github.com/urfave/cli" ) @@ -28,6 +30,23 @@ func shouldUseRootlessCgroupManager(context *cli.Context) (bool, error) { return false, nil } // euid = 0, in a userns. + // + // [systemd driver] + // We can call DetectUID() to parse the OwnerUID value from `busctl --user --no-pager status` result. + // The value corresponds to sd_bus_creds_get_owner_uid(3). + // If the value is 0, we have rootful systemd inside userns, so we do not need the rootless cgroup manager. + // + // On error, we assume we are root. An error may happen during shelling out to `busctl` CLI, + // mostly when $DBUS_SESSION_BUS_ADDRESS is unset. + if context.GlobalBool("systemd-cgroup") { + ownerUID, err := systemd.DetectUID() + if err != nil { + logrus.WithError(err).Debug("failed to get the OwnerUID value, assuming the value to be 0") + ownerUID = 0 + } + return ownerUID != 0, nil + } + // [cgroupfs driver] // As we are unaware of cgroups path, we can't determine whether we have the full // access to the cgroups path. // Either way, we can safely decide to use the rootless cgroups manager.