Skip to content

Commit c16260a

Browse files
committed
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>
1 parent 172d095 commit c16260a

2 files changed

Lines changed: 17 additions & 9 deletions

File tree

controller.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ type controller struct {
144144
unWatchCh chan *endpoint
145145
svcDb map[string]svcMap
146146
nmap map[string]*netWatch
147+
defOsSbox osl.Sandbox
148+
sboxOnce sync.Once
147149
sync.Mutex
148150
}
149151

@@ -492,12 +494,6 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
492494
config: containerConfig{},
493495
controller: c,
494496
}
495-
// This sandbox may be using an existing osl sandbox, sharing it with another sandbox
496-
var peerSb Sandbox
497-
c.WalkSandboxes(SandboxKeyWalker(&peerSb, sb.Key()))
498-
if peerSb != nil {
499-
sb.osSbox = peerSb.(*sandbox).osSbox
500-
}
501497

502498
heap.Init(&sb.endpoints)
503499

@@ -507,14 +503,26 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
507503
return nil, err
508504
}
509505

510-
c.Lock()
506+
if sb.config.useDefaultSandBox {
507+
c.sboxOnce.Do(func() {
508+
c.defOsSbox, err = osl.NewSandbox(sb.Key(), false)
509+
})
510+
511+
if err != nil {
512+
c.sboxOnce = sync.Once{}
513+
return nil, fmt.Errorf("failed to create default sandbox: %v", err)
514+
}
515+
516+
sb.osSbox = c.defOsSbox
517+
}
518+
511519
if sb.osSbox == nil && !sb.config.useExternalKey {
512520
if sb.osSbox, err = osl.NewSandbox(sb.Key(), !sb.config.useDefaultSandBox); err != nil {
513-
c.Unlock()
514521
return nil, fmt.Errorf("failed to create new osl sandbox: %v", err)
515522
}
516523
}
517524

525+
c.Lock()
518526
c.sandboxes[sb.id] = sb
519527
c.Unlock()
520528
defer func() {

sandbox.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func (sb *sandbox) Delete() error {
197197
// likely not required any more. Drop it.
198198
etchosts.Drop(sb.config.hostsPath)
199199

200-
if sb.osSbox != nil {
200+
if sb.osSbox != nil && !sb.config.useDefaultSandBox {
201201
sb.osSbox.Destroy()
202202
}
203203

0 commit comments

Comments
 (0)