mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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:
parent
6c23d4073f
commit
967917c8b4
2 changed files with 17 additions and 9 deletions
|
@ -144,6 +144,8 @@ type controller struct {
|
||||||
unWatchCh chan *endpoint
|
unWatchCh chan *endpoint
|
||||||
svcDb map[string]svcMap
|
svcDb map[string]svcMap
|
||||||
nmap map[string]*netWatch
|
nmap map[string]*netWatch
|
||||||
|
defOsSbox osl.Sandbox
|
||||||
|
sboxOnce sync.Once
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,12 +494,6 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
|
||||||
config: containerConfig{},
|
config: containerConfig{},
|
||||||
controller: c,
|
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)
|
heap.Init(&sb.endpoints)
|
||||||
|
|
||||||
|
@ -507,14 +503,26 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
|
||||||
return nil, err
|
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 == nil && !sb.config.useExternalKey {
|
||||||
if sb.osSbox, err = osl.NewSandbox(sb.Key(), !sb.config.useDefaultSandBox); err != nil {
|
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)
|
return nil, fmt.Errorf("failed to create new osl sandbox: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
c.sandboxes[sb.id] = sb
|
c.sandboxes[sb.id] = sb
|
||||||
c.Unlock()
|
c.Unlock()
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
|
@ -197,7 +197,7 @@ func (sb *sandbox) Delete() error {
|
||||||
// likely not required any more. Drop it.
|
// likely not required any more. Drop it.
|
||||||
etchosts.Drop(sb.config.hostsPath)
|
etchosts.Drop(sb.config.hostsPath)
|
||||||
|
|
||||||
if sb.osSbox != nil {
|
if sb.osSbox != nil && !sb.config.useDefaultSandBox {
|
||||||
sb.osSbox.Destroy()
|
sb.osSbox.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue