Move sandbox resources when container restarts
Currently when container has a restart policy and gets restarted, docker does not release networking and allocate it back. But it presents libnetwork with a new sandbox while all the network resources are locked in the old sandbox. This commit attempts to move all the network resources from the old sandbox to the new sandbox when libnetwork is presented with the new sandbox. Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
parent
242ffc0b8b
commit
1ffe6fef02
1 changed files with 51 additions and 24 deletions
|
@ -307,15 +307,21 @@ func (sb *sandbox) SetKey(basePath string) error {
|
|||
}
|
||||
|
||||
sb.Lock()
|
||||
if sb.osSbox != nil {
|
||||
sb.Unlock()
|
||||
return types.ForbiddenErrorf("failed to set sandbox key : already assigned")
|
||||
}
|
||||
osSbox := sb.osSbox
|
||||
sb.Unlock()
|
||||
osSbox, err := osl.GetSandboxForExternalKey(basePath, sb.Key())
|
||||
|
||||
if osSbox != nil {
|
||||
// If we already have an OS sandbox, release the network resources from that
|
||||
// and destroy the OS snab. We are moving into a new home further down. Note that none
|
||||
// of the network resources gets destroyed during the move.
|
||||
sb.releaseOSSbox()
|
||||
}
|
||||
|
||||
osSbox, err = osl.GetSandboxForExternalKey(basePath, sb.Key())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sb.Lock()
|
||||
sb.osSbox = osSbox
|
||||
sb.Unlock()
|
||||
|
@ -335,6 +341,45 @@ func (sb *sandbox) SetKey(basePath string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
|
||||
for _, i := range osSbox.Info().Interfaces() {
|
||||
// Only remove the interfaces owned by this endpoint from the sandbox.
|
||||
if ep.hasInterface(i.SrcName()) {
|
||||
if err := i.Remove(); err != nil {
|
||||
log.Debugf("Remove interface failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ep.Lock()
|
||||
joinInfo := ep.joinInfo
|
||||
ep.Unlock()
|
||||
|
||||
// Remove non-interface routes.
|
||||
for _, r := range joinInfo.StaticRoutes {
|
||||
if err := osSbox.RemoveStaticRoute(r); err != nil {
|
||||
log.Debugf("Remove route failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sb *sandbox) releaseOSSbox() {
|
||||
sb.Lock()
|
||||
osSbox := sb.osSbox
|
||||
sb.osSbox = nil
|
||||
sb.Unlock()
|
||||
|
||||
if osSbox == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, ep := range sb.getConnectedEndpoints() {
|
||||
releaseOSSboxResources(osSbox, ep)
|
||||
}
|
||||
|
||||
osSbox.Destroy()
|
||||
}
|
||||
|
||||
func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
|
||||
sb.Lock()
|
||||
if sb.osSbox == nil {
|
||||
|
@ -394,25 +439,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
|
|||
osSbox := sb.osSbox
|
||||
sb.Unlock()
|
||||
if osSbox != nil {
|
||||
for _, i := range osSbox.Info().Interfaces() {
|
||||
// Only remove the interfaces owned by this endpoint from the sandbox.
|
||||
if ep.hasInterface(i.SrcName()) {
|
||||
if err := i.Remove(); err != nil {
|
||||
log.Debugf("Remove interface failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ep.Lock()
|
||||
joinInfo := ep.joinInfo
|
||||
ep.Unlock()
|
||||
|
||||
// Remove non-interface routes.
|
||||
for _, r := range joinInfo.StaticRoutes {
|
||||
if err := osSbox.RemoveStaticRoute(r); err != nil {
|
||||
log.Debugf("Remove route failed: %v", err)
|
||||
}
|
||||
}
|
||||
releaseOSSboxResources(osSbox, ep)
|
||||
}
|
||||
|
||||
sb.Lock()
|
||||
|
|
Loading…
Reference in a new issue