summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal.go8
-rw-r--r--libpod/oci_linux.go53
-rw-r--r--libpod/runtime.go14
-rw-r--r--libpod/runtime_ctr.go7
4 files changed, 75 insertions, 7 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 3c7319963..36b5e01df 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -350,7 +350,7 @@ func (c *Container) teardownStorage() error {
artifacts := filepath.Join(c.config.StaticDir, artifactsDir)
if err := os.RemoveAll(artifacts); err != nil {
- return errors.Wrapf(err, "error removing artifacts %q", artifacts)
+ return errors.Wrapf(err, "error removing container %s artifacts %q", c.ID(), artifacts)
}
if err := c.cleanupStorage(); err != nil {
@@ -1113,13 +1113,13 @@ func (c *Container) cleanup(ctx context.Context) error {
// Remove healthcheck unit/timer file if it execs
if c.config.HealthCheckConfig != nil {
if err := c.removeTimer(); err != nil {
- logrus.Error(err)
+ logrus.Errorf("Error removing timer for container %s healthcheck: %v", c.ID(), err)
}
}
// Clean up network namespace, if present
if err := c.cleanupNetwork(); err != nil {
- lastError = err
+ lastError = errors.Wrapf(err, "error removing container %s network", c.ID())
}
// Unmount storage
@@ -1127,7 +1127,7 @@ func (c *Container) cleanup(ctx context.Context) error {
if lastError != nil {
logrus.Errorf("Error unmounting container %s storage: %v", c.ID(), err)
} else {
- lastError = err
+ lastError = errors.Wrapf(err, "error unmounting container %s storage", c.ID())
}
}
diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go
index 8c0abad80..01f7c3649 100644
--- a/libpod/oci_linux.go
+++ b/libpod/oci_linux.go
@@ -3,15 +3,20 @@
package libpod
import (
+ "fmt"
"os"
"os/exec"
"path/filepath"
+ "runtime"
"strings"
"syscall"
"github.com/containerd/cgroups"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/utils"
+ pmount "github.com/containers/storage/pkg/mount"
spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@@ -91,6 +96,54 @@ func (r *OCIRuntime) createContainer(ctr *Container, cgroupParent string, restor
return err
}
}
+
+ // if we are running a non privileged container, be sure to umount some kernel paths so they are not
+ // bind mounted inside the container at all.
+ if !ctr.config.Privileged && !rootless.IsRootless() {
+ ch := make(chan error)
+ go func() {
+ runtime.LockOSThread()
+ err := func() error {
+ fd, err := os.Open(fmt.Sprintf("/proc/%d/task/%d/ns/mnt", os.Getpid(), unix.Gettid()))
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+
+ // create a new mountns on the current thread
+ if err = unix.Unshare(unix.CLONE_NEWNS); err != nil {
+ return err
+ }
+ defer unix.Setns(int(fd.Fd()), unix.CLONE_NEWNS)
+
+ // don't spread our mounts around. We are setting only /sys to be slave
+ // so that the cleanup process is still able to umount the storage and the
+ // changes are propagated to the host.
+ err = unix.Mount("/sys", "/sys", "none", unix.MS_REC|unix.MS_SLAVE, "")
+ if err != nil {
+ return errors.Wrapf(err, "cannot make /sys slave")
+ }
+
+ mounts, err := pmount.GetMounts()
+ if err != nil {
+ return err
+ }
+ for _, m := range mounts {
+ if !strings.HasPrefix(m.Mountpoint, "/sys/kernel") {
+ continue
+ }
+ err = unix.Unmount(m.Mountpoint, 0)
+ if err != nil {
+ return errors.Wrapf(err, "cannot unmount %s", m.Mountpoint)
+ }
+ }
+ return r.createOCIContainer(ctr, cgroupParent, restoreOptions)
+ }()
+ ch <- err
+ }()
+ err := <-ch
+ return err
+ }
}
return r.createOCIContainer(ctr, cgroupParent, restoreOptions)
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 4dd2707e8..3b1c2be98 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -870,6 +870,20 @@ func makeRuntime(runtime *Runtime) (err error) {
_, err = os.Stat(runtimeAliveFile)
if err != nil {
+ // If we need to refresh, then it is safe to assume there are
+ // no containers running. Create immediately a namespace, as
+ // we will need to access the storage.
+ if os.Geteuid() != 0 {
+ aliveLock.Unlock()
+ became, ret, err := rootless.BecomeRootInUserNS()
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
+ }
+
+ }
// If the file doesn't exist, we need to refresh the state
// This will trigger on first use as well, but refreshing an
// empty state only creates a single file
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 800b42851..85b860268 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -372,7 +372,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool,
// Clean up network namespace, cgroups, mounts
if err := c.cleanup(ctx); err != nil {
if cleanupErr == nil {
- cleanupErr = err
+ cleanupErr = errors.Wrapf(err, "error cleaning up container %s", c.ID())
} else {
logrus.Errorf("cleanup network, cgroups, mounts: %v", err)
}
@@ -404,12 +404,14 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool,
// Deallocate the container's lock
if err := c.lock.Free(); err != nil {
if cleanupErr == nil {
- cleanupErr = err
+ cleanupErr = errors.Wrapf(err, "error freeing lock for container %s", c.ID())
} else {
logrus.Errorf("free container lock: %v", err)
}
}
+ c.newContainerEvent(events.Remove)
+
if !removeVolume {
return cleanupErr
}
@@ -425,7 +427,6 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool,
}
}
- c.newContainerEvent(events.Remove)
return cleanupErr
}