diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-07-30 09:42:35 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-07-31 14:19:50 +0000 |
commit | 1db70cce344724e091635bc8c6fa6c207450df68 (patch) | |
tree | ed48df83141568bb949a8bdd5611cd20b3fa42c2 /libpod/boltdb_state_linux.go | |
parent | cfcd92847684fc65949350b7cdc4769ad1099d46 (diff) | |
download | podman-1db70cce344724e091635bc8c6fa6c207450df68.tar.gz podman-1db70cce344724e091635bc8c6fa6c207450df68.tar.bz2 podman-1db70cce344724e091635bc8c6fa6c207450df68.zip |
Do not fetch pod and ctr State on retrieval in Bolt
It's not necessary to fill in state immediately, as we'll be
overwriting it on any API call accessing it thanks to
syncContainer(). It is also causing races when we fetch it
without holding the container lock (which syncContainer() does).
As such, just don't retrieve the state on initial pull from the
database with Bolt.
Also, refactor some Linux-specific netns handling functions out
of container_internal_linux.go into boltdb_linux.go.
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Closes: #1186
Approved by: rhatdan
Diffstat (limited to 'libpod/boltdb_state_linux.go')
-rw-r--r-- | libpod/boltdb_state_linux.go | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/libpod/boltdb_state_linux.go b/libpod/boltdb_state_linux.go index 9238d22fe..fce3a1b1e 100644 --- a/libpod/boltdb_state_linux.go +++ b/libpod/boltdb_state_linux.go @@ -6,20 +6,44 @@ import ( "github.com/sirupsen/logrus" ) -// parseNetNSBoltData sets ctr.state.NetNS, if any, from netNSBytes. -// Returns true if the data is valid. -func parseNetNSBoltData(ctr *Container, netNSBytes []byte) bool { - // The container may not have a network namespace, so it's OK if this is - // nil - if netNSBytes != nil { - nsPath := string(netNSBytes) - netNS, err := joinNetNS(nsPath) - if err == nil { - ctr.state.NetNS = netNS +// replaceNetNS handle network namespace transitions after updating a +// container's state. +func replaceNetNS(netNSPath string, ctr *Container, 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 { - logrus.Errorf("error joining network namespace for container %s", ctr.ID()) - return false + // 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 true + return nil +} + +// getNetNSPath retrieves the netns path to be stored in the database +func getNetNSPath(ctr *Container) string { + if ctr.state.NetNS != nil { + return ctr.state.NetNS.Path() + } + return "" } |