Fix stale sandbox from store problem
At times, when checkpointed sandbox from store cannot be cleaned up properly we still retain the sandbox in both the store and in memory. But this sandbox store may not contain important configuration information from docker. So when docker requests a new sandbox, instead of using it as is, reconcile the sandbox state from store with the the configuration information provided by docker. To do this mark the sandbox from store as stub and never reveal it to external searches. When docker requests a new sandbox, update the stub sandbox and clear the stub flag. Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
parent
e557f4a67d
commit
670302e66b
3 changed files with 58 additions and 12 deletions
|
@ -100,6 +100,9 @@ type NetworkController interface {
|
|||
// SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
|
||||
SandboxByID(id string) (Sandbox, error)
|
||||
|
||||
// SandboxDestroy destroys a sandbox given a container ID
|
||||
SandboxDestroy(id string) error
|
||||
|
||||
// Stop network controller
|
||||
Stop()
|
||||
}
|
||||
|
@ -478,21 +481,37 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
|
|||
return nil, types.BadRequestErrorf("invalid container ID")
|
||||
}
|
||||
|
||||
var existing Sandbox
|
||||
look := SandboxContainerWalker(&existing, containerID)
|
||||
c.WalkSandboxes(look)
|
||||
if existing != nil {
|
||||
return nil, types.BadRequestErrorf("container %s is already present: %v", containerID, existing)
|
||||
var sb *sandbox
|
||||
c.Lock()
|
||||
for _, s := range c.sandboxes {
|
||||
if s.containerID == containerID {
|
||||
// If not a stub, then we already have a complete sandbox.
|
||||
if !s.isStub {
|
||||
c.Unlock()
|
||||
return nil, types.BadRequestErrorf("container %s is already present: %v", containerID, s)
|
||||
}
|
||||
|
||||
// We already have a stub sandbox from the
|
||||
// store. Make use of it so that we don't lose
|
||||
// the endpoints from store but reset the
|
||||
// isStub flag.
|
||||
sb = s
|
||||
sb.isStub = false
|
||||
break
|
||||
}
|
||||
}
|
||||
c.Unlock()
|
||||
|
||||
// Create sandbox and process options first. Key generation depends on an option
|
||||
sb := &sandbox{
|
||||
id: stringid.GenerateRandomID(),
|
||||
containerID: containerID,
|
||||
endpoints: epHeap{},
|
||||
epPriority: map[string]int{},
|
||||
config: containerConfig{},
|
||||
controller: c,
|
||||
if sb == nil {
|
||||
sb = &sandbox{
|
||||
id: stringid.GenerateRandomID(),
|
||||
containerID: containerID,
|
||||
endpoints: epHeap{},
|
||||
epPriority: map[string]int{},
|
||||
config: containerConfig{},
|
||||
controller: c,
|
||||
}
|
||||
}
|
||||
|
||||
heap.Init(&sb.endpoints)
|
||||
|
@ -547,6 +566,11 @@ func (c *controller) Sandboxes() []Sandbox {
|
|||
|
||||
list := make([]Sandbox, 0, len(c.sandboxes))
|
||||
for _, s := range c.sandboxes {
|
||||
// Hide stub sandboxes from libnetwork users
|
||||
if s.isStub {
|
||||
continue
|
||||
}
|
||||
|
||||
list = append(list, s)
|
||||
}
|
||||
|
||||
|
@ -574,6 +598,26 @@ func (c *controller) SandboxByID(id string) (Sandbox, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
// SandboxDestroy destroys a sandbox given a container ID
|
||||
func (c *controller) SandboxDestroy(id string) error {
|
||||
var sb *sandbox
|
||||
c.Lock()
|
||||
for _, s := range c.sandboxes {
|
||||
if s.containerID == id {
|
||||
sb = s
|
||||
break
|
||||
}
|
||||
}
|
||||
c.Unlock()
|
||||
|
||||
// It is not an error if sandbox is not available
|
||||
if sb == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return sb.Delete()
|
||||
}
|
||||
|
||||
// SandboxContainerWalker returns a Sandbox Walker function which looks for an existing Sandbox with the passed containerID
|
||||
func SandboxContainerWalker(out *Sandbox, containerID string) SandboxWalker {
|
||||
return func(sb Sandbox) bool {
|
||||
|
|
|
@ -68,6 +68,7 @@ type sandbox struct {
|
|||
joinLeaveDone chan struct{}
|
||||
dbIndex uint64
|
||||
dbExists bool
|
||||
isStub bool
|
||||
inDelete bool
|
||||
sync.Mutex
|
||||
}
|
||||
|
|
|
@ -188,6 +188,7 @@ func (c *controller) sandboxCleanup() {
|
|||
endpoints: epHeap{},
|
||||
epPriority: map[string]int{},
|
||||
dbIndex: sbs.dbIndex,
|
||||
isStub: true,
|
||||
dbExists: true,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue