Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 2d8f21c

Browse files
authored
Merge pull request #717 from teawater/snap
Use snap to handle the lock issue in XPod.updatePodInfo
2 parents 8828033 + 82f7b6c commit 2d8f21c

File tree

5 files changed

+66
-26
lines changed

5 files changed

+66
-26
lines changed

daemon/pod/container.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,7 @@ func (c *Container) CreatedAt() time.Time {
135135
return ct
136136
}
137137

138-
func (c *Container) Info() *apitypes.Container {
139-
c.status.RLock()
140-
defer c.status.RUnlock()
138+
func (c *Container) InfoLocked() *apitypes.Container {
141139
cinfo := &apitypes.Container{
142140
Name: c.RuntimeName(),
143141
ContainerID: c.Id(),
@@ -188,9 +186,13 @@ func (c *Container) Info() *apitypes.Container {
188186
return cinfo
189187
}
190188

191-
func (c *Container) InfoStatus() *apitypes.ContainerStatus {
189+
func (c *Container) Info() *apitypes.Container {
192190
c.status.RLock()
193191
defer c.status.RUnlock()
192+
return c.InfoLocked()
193+
}
194+
195+
func (c *Container) InfoStatusLocked() *apitypes.ContainerStatus {
194196
s := &apitypes.ContainerStatus{
195197
Name: c.SpecName(),
196198
ContainerID: c.Id(),
@@ -226,6 +228,12 @@ func (c *Container) InfoStatus() *apitypes.ContainerStatus {
226228
return s
227229
}
228230

231+
func (c *Container) InfoStatus() *apitypes.ContainerStatus {
232+
c.status.RLock()
233+
defer c.status.RUnlock()
234+
return c.InfoStatusLocked()
235+
}
236+
229237
// Container life cycle operations:
230238
func (c *Container) Add() error {
231239
return nil

daemon/pod/decommission.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ func (p *XPod) RemoveContainer(id string) error {
276276
}
277277
p.factory.registry.ReleaseContainer(id, c.SpecName())
278278
delete(p.containers, id)
279+
p.statusLock.Lock()
280+
delete(p.snapContainers, id)
281+
p.statusLock.Unlock()
279282

280283
//remove volumes from daemondb
281284
for _, vName := range removedVols {

daemon/pod/persist.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ func LoadXPod(factory *PodFactory, layout *types.PersistPodLayout) (*XPod, error
128128
for _, v := range p.volumes {
129129
v.status = S_VOLUME_INSERTED
130130
}
131+
p.statusLock.Lock()
132+
for index := range p.snapVolumes {
133+
p.snapVolumes[index] = p.volumes[index].Info()
134+
}
135+
p.statusLock.Unlock()
131136
}
132137

133138
err = p.loadPodMeta()
@@ -376,6 +381,9 @@ func (p *XPod) loadContainer(id string) error {
376381
return err
377382
}
378383
p.containers[c.Id()] = c
384+
p.statusLock.Lock()
385+
p.snapContainers[c.Id()] = c
386+
p.statusLock.Unlock()
379387
return nil
380388
}
381389

@@ -403,6 +411,9 @@ func (p *XPod) loadVolume(id string) error {
403411
v.descript = vx.Descript
404412
v.status = S_VOLUME_CREATED
405413
p.volumes[v.spec.Name] = v
414+
p.statusLock.Lock()
415+
p.snapVolumes[v.spec.Name] = p.volumes[v.spec.Name].Info()
416+
p.statusLock.Unlock()
406417
return nil
407418
}
408419

daemon/pod/pod.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ type XPod struct {
7878
// on it too.
7979
stoppedChan chan bool
8080
initCond *sync.Cond
81+
82+
//Protected by statusLock
83+
snapVolumes map[string]*apitypes.PodVolume
84+
snapContainers map[string]*Container
8185
}
8286

8387
// The Log infrastructure, to add pod name as prefix of the log message.
@@ -338,22 +342,22 @@ func (p *XPod) updatePodInfo() error {
338342
defer p.statusLock.Unlock()
339343

340344
var (
341-
containers = make([]*apitypes.Container, 0, len(p.containers))
342-
volumes = make([]*apitypes.PodVolume, 0, len(p.volumes))
343-
containerStatus = make([]*apitypes.ContainerStatus, 0, len(p.containers))
345+
containers = make([]*apitypes.Container, 0, len(p.snapContainers))
346+
volumes = make([]*apitypes.PodVolume, 0, len(p.snapVolumes))
347+
containerStatus = make([]*apitypes.ContainerStatus, 0, len(p.snapContainers))
344348
)
345349

346350
p.info.Spec.Labels = p.labels
347351

348-
for _, v := range p.volumes {
349-
volumes = append(volumes, v.Info())
352+
for _, v := range p.snapVolumes {
353+
volumes = append(volumes, v)
350354
}
351355
p.info.Spec.Volumes = volumes
352356

353357
succeeeded := "Succeeded"
354-
for _, c := range p.containers {
355-
ci := c.Info()
356-
cs := c.InfoStatus()
358+
for _, c := range p.snapContainers {
359+
ci := c.InfoLocked()
360+
cs := c.InfoStatusLocked()
357361
containers = append(containers, ci)
358362
containerStatus = append(containerStatus, cs)
359363
if cs.Phase == "failed" {

daemon/pod/provision.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,22 @@ func newXPod(factory *PodFactory, spec *apitypes.UserPod) (*XPod, error) {
8787
factory.hosts = HostsCreator(spec.Id)
8888
factory.logCreator = initLogCreator(factory, spec)
8989
p := &XPod{
90-
name: spec.Id,
91-
logPrefix: fmt.Sprintf("Pod[%s] ", spec.Id),
92-
globalSpec: spec.CloneGlobalPart(),
93-
containers: make(map[string]*Container),
94-
volumes: make(map[string]*Volume),
95-
interfaces: make(map[string]*Interface),
96-
portMappings: spec.Portmappings,
97-
labels: spec.Labels,
98-
prestartExecs: [][]string{},
99-
execs: make(map[string]*Exec),
100-
resourceLock: &sync.Mutex{},
101-
statusLock: &sync.RWMutex{},
102-
stoppedChan: make(chan bool, 1),
103-
factory: factory,
90+
name: spec.Id,
91+
logPrefix: fmt.Sprintf("Pod[%s] ", spec.Id),
92+
globalSpec: spec.CloneGlobalPart(),
93+
containers: make(map[string]*Container),
94+
volumes: make(map[string]*Volume),
95+
interfaces: make(map[string]*Interface),
96+
portMappings: spec.Portmappings,
97+
labels: spec.Labels,
98+
prestartExecs: [][]string{},
99+
execs: make(map[string]*Exec),
100+
resourceLock: &sync.Mutex{},
101+
statusLock: &sync.RWMutex{},
102+
stoppedChan: make(chan bool, 1),
103+
factory: factory,
104+
snapVolumes: make(map[string]*apitypes.PodVolume),
105+
snapContainers: make(map[string]*Container),
104106
}
105107
p.initCond = sync.NewCond(p.statusLock.RLocker())
106108
return p, nil
@@ -143,6 +145,9 @@ func (p *XPod) doContainerCreate(c *apitypes.UserContainer) (string, error) {
143145
}
144146

145147
p.containers[pc.Id()] = pc
148+
p.statusLock.Lock()
149+
p.snapContainers[pc.Id()] = pc
150+
p.statusLock.Unlock()
146151

147152
vols := pc.volumes()
148153
nvs := make([]string, 0, len(vols))
@@ -152,6 +157,9 @@ func (p *XPod) doContainerCreate(c *apitypes.UserContainer) (string, error) {
152157
continue
153158
}
154159
p.volumes[vol.Name] = newVolume(p, vol)
160+
p.statusLock.Lock()
161+
p.snapVolumes[vol.Name] = p.volumes[vol.Name].Info()
162+
p.statusLock.Unlock()
155163
nvs = append(nvs, vol.Name)
156164
}
157165
pc.Log(TRACE, "volumes to be added: %v", nvs)
@@ -366,13 +374,19 @@ func (p *XPod) initResources(spec *apitypes.UserPod, allowCreate bool) error {
366374
return err
367375
}
368376
p.containers[c.Id()] = c
377+
p.statusLock.Lock()
378+
p.snapContainers[c.Id()] = c
379+
p.statusLock.Unlock()
369380

370381
vols := c.volumes()
371382
for _, vol := range vols {
372383
if _, ok := p.volumes[vol.Name]; ok {
373384
continue
374385
}
375386
p.volumes[vol.Name] = newVolume(p, vol)
387+
p.statusLock.Lock()
388+
p.snapVolumes[vol.Name] = p.volumes[vol.Name].Info()
389+
p.statusLock.Unlock()
376390
}
377391
}
378392

0 commit comments

Comments
 (0)