diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-05-08 13:49:07 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-05-17 20:48:24 +0200 |
commit | 791d53a21421fba249156ea3a503e9e04a4912e4 (patch) | |
tree | d56e5f5ec94837075fb006b79891c9eabbe3b651 /cmd/podman/main_local.go | |
parent | 2e0fef51b3928337ef46629b4627ff1700a918d1 (diff) | |
download | podman-791d53a21421fba249156ea3a503e9e04a4912e4.tar.gz podman-791d53a21421fba249156ea3a503e9e04a4912e4.tar.bz2 podman-791d53a21421fba249156ea3a503e9e04a4912e4.zip |
rootless: use a pause process
use a pause process to keep the user and mount namespace alive.
The pause process is created immediately on reload, and all successive
Podman processes will refer to it for joining the user&mount
namespace.
This solves all the race conditions we had on joining the correct
namespaces using the conmon processes.
As a fallback if the join fails for any reason (e.g. the pause process
was killed), then we try to join the running containers as we were
doing before.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'cmd/podman/main_local.go')
-rw-r--r-- | cmd/podman/main_local.go | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index 7452965a2..2024d4b31 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -16,6 +16,7 @@ import ( "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/tracing" + "github.com/containers/libpod/pkg/util" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -113,6 +114,34 @@ func setupRootless(cmd *cobra.Command, args []string) error { MainGlobalOpts, remoteclient, } + + pausePidPath, err := util.GetRootlessPauseProcessPidPath() + if err != nil { + return errors.Wrapf(err, "could not get pause process pid file path") + } + + data, err := ioutil.ReadFile(pausePidPath) + if err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "cannot read pause process pid file %s", pausePidPath) + } + if err == nil { + pausePid, err := strconv.Atoi(string(data)) + if err != nil { + return errors.Wrapf(err, "cannot parse pause pid file %s", pausePidPath) + } + became, ret, err := rootless.JoinUserAndMountNS(uint(pausePid), "") + if err != nil { + logrus.Errorf("cannot join pause process pid %d. You may need to remove %s and stop all containers", pausePid, pausePidPath) + logrus.Errorf(err.Error()) + os.Exit(1) + } + if became { + os.Exit(ret) + } + } + + // if there is no pid file, try to join existing containers, and create a pause process. + runtime, err := libpodruntime.GetRuntime(getContext(), &podmanCmd) if err != nil { return errors.Wrapf(err, "could not get runtime") @@ -127,20 +156,20 @@ func setupRootless(cmd *cobra.Command, args []string) error { var became bool var ret int if len(ctrs) == 0 { - became, ret, err = rootless.BecomeRootInUserNS() + became, ret, err = rootless.BecomeRootInUserNS(pausePidPath) } else { for _, ctr := range ctrs { data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile) if err != nil { logrus.Errorf(err.Error()) - os.Exit(1) + continue } conmonPid, err := strconv.Atoi(string(data)) if err != nil { logrus.Errorf(err.Error()) - os.Exit(1) + continue } - became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid)) + became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid), pausePidPath) if err == nil { break } |