diff --git a/virtcontainers/pod.go b/virtcontainers/pod.go index f65d2f8d60..6055d7a7c9 100644 --- a/virtcontainers/pod.go +++ b/virtcontainers/pod.go @@ -642,23 +642,37 @@ func newPod(podConfig PodConfig) (*Pod, error) { wg: &sync.WaitGroup{}, } - if err := p.storage.createAllResources(*p); err != nil { + if err = globalPodList.addPod(p); err != nil { return nil, err } - if err := p.hypervisor.init(p); err != nil { - p.storage.deletePodResources(p.id, nil) + defer func() { + if err != nil { + p.Logger().WithError(err).WithField("podid", p.id).Error("Create new pod failed") + globalPodList.removePod(p.id) + } + }() + + if err = p.storage.createAllResources(*p); err != nil { return nil, err } - if err := p.hypervisor.createPod(podConfig); err != nil { - p.storage.deletePodResources(p.id, nil) + defer func() { + if err != nil { + p.storage.deletePodResources(p.id, nil) + } + }() + + if err = p.hypervisor.init(p); err != nil { + return nil, err + } + + if err = p.hypervisor.createPod(podConfig); err != nil { return nil, err } agentConfig := newAgentConfig(podConfig) - if err := p.agent.init(p, agentConfig); err != nil { - p.storage.deletePodResources(p.id, nil) + if err = p.agent.init(p, agentConfig); err != nil { return nil, err } @@ -688,6 +702,11 @@ func fetchPod(podID string) (pod *Pod, err error) { return nil, errNeedPodID } + pod, err = globalPodList.lookupPod(podID) + if pod != nil && err == nil { + return pod, err + } + fs := filesystem{} config, err := fs.fetchPodConfig(podID) if err != nil { @@ -766,6 +785,8 @@ func (p *Pod) delete() error { } } + globalPodList.removePod(p.id) + return p.storage.deletePodResources(p.id, nil) } diff --git a/virtcontainers/podlist.go b/virtcontainers/podlist.go new file mode 100644 index 0000000000..14e8eb4368 --- /dev/null +++ b/virtcontainers/podlist.go @@ -0,0 +1,60 @@ +// +// Copyright (c) 2018 HyperHQ Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package virtcontainers + +import ( + "fmt" + "sync" +) + +type podList struct { + lock sync.RWMutex + pods map[string]*Pod +} + +// globalPodList tracks pods globally +var globalPodList = &podList{pods: make(map[string]*Pod)} + +func (p *podList) addPod(pod *Pod) (err error) { + if pod == nil { + return nil + } + + p.lock.Lock() + defer p.lock.Unlock() + if p.pods[pod.id] == nil { + p.pods[pod.id] = pod + } else { + err = fmt.Errorf("pod %s exists", pod.id) + } + return err +} + +func (p *podList) removePod(id string) { + p.lock.Lock() + defer p.lock.Unlock() + delete(p.pods, id) +} + +func (p *podList) lookupPod(id string) (*Pod, error) { + p.lock.RLock() + defer p.lock.RUnlock() + if p.pods[id] != nil { + return p.pods[id], nil + } + return nil, fmt.Errorf("pod %s does not exist", id) +}