Files
podman/libpod/container_linux.go
Matthew Heon 8c52aa15f0 Fix handling of Linux network namespaces
The CNI plugins upstream removed their network namespace creation
code, making it a test package only. Copy it into our repository
and slightly modify it for our use (most notably, use MNT_DETACH
when unmounting namespaces).

This new CNI code splits closing and unmounting network
namespaces, which allows us to greatly reduce the number of
occasions on which we call teardownNetwork() and make more errors
in that function fatal instead of warnings. Instead, we can call
Close() and just close the open file descriptor in cases where
the namespace has already been cleaned up.

Signed-off-by: Matthew Heon <matthew.heon@gmail.com>

Closes: #1165
Approved by: baude
2018-07-27 02:48:15 +00:00

56 lines
1.4 KiB
Go

// +build linux
package libpod
import (
"github.com/containernetworking/plugins/pkg/ns"
"github.com/sirupsen/logrus"
)
type containerPlatformState struct {
// NetNSPath is the path of the container's network namespace
// Will only be set if config.CreateNetNS is true, or the container was
// told to join another container's network namespace
NetNS ns.NetNS `json:"-"`
}
func (ctr *Container) setNamespace(netNSPath string, newState *containerState) error {
if netNSPath != "" {
// Check if the container's old state has a good netns
if ctr.state.NetNS != nil && netNSPath == ctr.state.NetNS.Path() {
newState.NetNS = ctr.state.NetNS
} else {
// Close the existing namespace.
// Whoever removed it from the database already tore it down.
if err := ctr.runtime.closeNetNS(ctr); err != nil {
return err
}
// Open the new network namespace
ns, err := joinNetNS(netNSPath)
if err == nil {
newState.NetNS = ns
} else {
logrus.Errorf("error joining network namespace for container %s", ctr.ID())
ctr.valid = false
}
}
} else {
// The container no longer has a network namespace
// Close the old one, whoever removed it from the DB should have
// cleaned it up already.
if err := ctr.runtime.closeNetNS(ctr); err != nil {
return err
}
}
return nil
}
func (ctr *Container) setNamespaceStatePath() string {
if ctr.state.NetNS != nil {
return ctr.state.NetNS.Path()
}
return ""
}