From c3602075ec6ee535e2fbf3e4fcf2ecbd27fa22c9 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 21 Jun 2018 11:09:17 -0400 Subject: Make CGroups cleanup optional on whether they exist Signed-off-by: Matthew Heon Closes: #981 Approved by: baude --- libpod/container.go | 3 +++ libpod/container_api.go | 2 ++ libpod/container_internal.go | 29 +++++++++++++++++++++++++---- libpod/pod.go | 3 --- libpod/runtime.go | 6 ++++++ 5 files changed, 36 insertions(+), 7 deletions(-) (limited to 'libpod') diff --git a/libpod/container.go b/libpod/container.go index a30a9e006..37dabd80d 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -167,6 +167,9 @@ type containerState struct { // the path of the file on disk outside the container BindMounts map[string]string `json:"bindMounts,omitempty"` + // CgroupCreated indicates that the container has created a cgroup + CgroupCreated bool `json:"cgroupCreated,omitempty"` + // UserNSRoot is the directory used as root for the container when using // user namespaces. UserNSRoot string `json:"userNSRoot,omitempty"` diff --git a/libpod/container_api.go b/libpod/container_api.go index d181af2a8..f4613534c 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -805,6 +805,8 @@ func (c *Container) Refresh(ctx context.Context) error { return err } + logrus.Debugf("Resetting state of container %s", c.ID()) + // We've finished unwinding the container back to its initial state // Now safe to refresh container state if err := resetState(c.state); err != nil { diff --git a/libpod/container_internal.go b/libpod/container_internal.go index fee13953c..1985bb141 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -329,15 +329,13 @@ func resetState(state *containerState) error { state.Interfaces = nil state.Routes = nil state.BindMounts = make(map[string]string) + state.CgroupCreated = false return nil } // Refresh refreshes the container's state after a restart func (c *Container) refresh() error { - c.lock.Lock() - defer c.lock.Unlock() - if !c.valid { return errors.Wrapf(ErrCtrRemoved, "container %s is not valid - may have been removed", c.ID()) } @@ -567,6 +565,7 @@ func (c *Container) init(ctx context.Context) error { logrus.Debugf("Created container %s in OCI runtime", c.ID()) c.state.State = ContainerStateCreated + c.state.CgroupCreated = true if err := c.save(); err != nil { return err @@ -812,6 +811,11 @@ func (c *Container) prepare() (err error) { // cleanupCgroup cleans up residual CGroups after container execution // This is a no-op for the systemd cgroup driver func (c *Container) cleanupCgroups() error { + if !c.state.CgroupCreated { + logrus.Debugf("Cgroups are not present, ignoring...") + return nil + } + if c.runtime.config.CgroupManager == SystemdCgroupsManager { return nil } @@ -836,11 +840,22 @@ func (c *Container) cleanupCgroups() error { return err } + c.state.CgroupCreated = false + + if c.valid { + return c.save() + } + return nil } // cleanupNetwork unmounts and cleans up the container's network func (c *Container) cleanupNetwork() error { + if c.state.NetNS == nil { + logrus.Debugf("Network is already cleaned up, skipping...") + return nil + } + // Stop the container's network namespace (if it has one) if err := c.runtime.teardownNetNS(c); err != nil { logrus.Errorf("unable to cleanup network for container %s: %q", c.ID(), err) @@ -850,13 +865,19 @@ func (c *Container) cleanupNetwork() error { c.state.IPs = nil c.state.Interfaces = nil c.state.Routes = nil - return c.save() + + if c.valid { + return c.save() + } + + return nil } // cleanupStorage unmounts and cleans up the container's root filesystem func (c *Container) cleanupStorage() error { if !c.state.Mounted { // Already unmounted, do nothing + logrus.Debugf("Storage is already unmounted, skipping...") return nil } diff --git a/libpod/pod.go b/libpod/pod.go index 1fde4285d..a96628853 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -127,9 +127,6 @@ func (p *Pod) save() error { // Refresh a pod's state after restart func (p *Pod) refresh() error { - p.lock.Lock() - defer p.lock.Unlock() - if !p.valid { return ErrPodRemoved } diff --git a/libpod/runtime.go b/libpod/runtime.go index 46d5a95ee..21dd9d024 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -570,14 +570,20 @@ func (r *Runtime) refresh(alivePath string) error { return errors.Wrapf(err, "error retrieving all pods from state") } for _, ctr := range ctrs { + ctr.lock.Lock() if err := ctr.refresh(); err != nil { + ctr.lock.Unlock() return err } + ctr.lock.Unlock() } for _, pod := range pods { + pod.lock.Lock() if err := pod.refresh(); err != nil { + pod.lock.Unlock() return err } + pod.lock.Unlock() } // Create a file indicating the runtime is alive and ready -- cgit v1.2.3-54-g00ecf