From 8f1b7be275e74a7a3f9ecaad105846d603aabb1d Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 14 Jun 2018 16:25:36 -0400 Subject: Fix cleaning up network namespaces on detached ctrs The containernetworking/plugins ns package does not support unmounting and removing namespaces that were opened by another process. Work around this by doing it ourself. Closes: #858 Signed-off-by: Matthew Heon Closes: #949 Approved by: rhatdan --- libpod/container_internal.go | 2 +- libpod/networking.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'libpod') diff --git a/libpod/container_internal.go b/libpod/container_internal.go index f6d8fc32a..e25ffaa03 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -655,7 +655,7 @@ func (c *Container) stop(timeout uint) error { return err } - return c.cleanupStorage() + return c.cleanup() } // mountStorage sets up the container's root filesystem diff --git a/libpod/networking.go b/libpod/networking.go index 54a1c78de..092ce2a3f 100644 --- a/libpod/networking.go +++ b/libpod/networking.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "strings" + "syscall" cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" @@ -184,10 +185,24 @@ func (r *Runtime) teardownNetNS(ctr *Container) error { logrus.Errorf("Failed to tear down network namespace for container %s: %v", ctr.ID(), err) } + nsPath := ctr.state.NetNS.Path() + if err := ctr.state.NetNS.Close(); err != nil { return errors.Wrapf(err, "error closing network namespace for container %s", ctr.ID()) } + // We need to unconditionally try to unmount/remove the namespace + // because we may be in a separate process from the one that created the + // namespace, and Close() will only do that if it is the same process. + if err := unix.Unmount(nsPath, unix.MNT_DETACH); err != nil { + if err != syscall.EINVAL && err != syscall.ENOENT { + return errors.Wrapf(err, "error unmounting network namespace %s for container %s", nsPath, ctr.ID()) + } + } + if err := os.RemoveAll(nsPath); err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "error removing network namespace %s for container %s", nsPath, ctr.ID()) + } + ctr.state.NetNS = nil return nil -- cgit v1.2.3-54-g00ecf