Fix race in os sandbox sharing

There is a race in os sandbox sharing code where two containers which
are sharing the os sandbox try to recreate the os sandbox again which
might result in destroying the os sandbox and recreating it. Since the
os sandbox sharing is happening only for default sandbox, refactored the
code to create os sandbox only once inside a `sync.Once` api so that it
happens exactly once and gets reused by other containers. Also disabled
deleting this os sandbox.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
Jana Radhakrishnan 2015-10-31 23:15:15 -07:00
parent 6c23d4073f
commit 967917c8b4
2 changed files with 17 additions and 9 deletions

View File

@ -144,6 +144,8 @@ type controller struct {
unWatchCh chan *endpoint
svcDb map[string]svcMap
nmap map[string]*netWatch
defOsSbox osl.Sandbox
sboxOnce sync.Once
sync.Mutex
}
@ -492,12 +494,6 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
config: containerConfig{},
controller: c,
}
// This sandbox may be using an existing osl sandbox, sharing it with another sandbox
var peerSb Sandbox
c.WalkSandboxes(SandboxKeyWalker(&peerSb, sb.Key()))
if peerSb != nil {
sb.osSbox = peerSb.(*sandbox).osSbox
}
heap.Init(&sb.endpoints)
@ -507,14 +503,26 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
return nil, err
}
c.Lock()
if sb.config.useDefaultSandBox {
c.sboxOnce.Do(func() {
c.defOsSbox, err = osl.NewSandbox(sb.Key(), false)
})
if err != nil {
c.sboxOnce = sync.Once{}
return nil, fmt.Errorf("failed to create default sandbox: %v", err)
}
sb.osSbox = c.defOsSbox
}
if sb.osSbox == nil && !sb.config.useExternalKey {
if sb.osSbox, err = osl.NewSandbox(sb.Key(), !sb.config.useDefaultSandBox); err != nil {
c.Unlock()
return nil, fmt.Errorf("failed to create new osl sandbox: %v", err)
}
}
c.Lock()
c.sandboxes[sb.id] = sb
c.Unlock()
defer func() {

View File

@ -197,7 +197,7 @@ func (sb *sandbox) Delete() error {
// likely not required any more. Drop it.
etchosts.Drop(sb.config.hostsPath)
if sb.osSbox != nil {
if sb.osSbox != nil && !sb.config.useDefaultSandBox {
sb.osSbox.Destroy()
}