Merge pull request #20 from runcom/locks

server: locking around server components
This commit is contained in:
Mrunal Patel 2016-09-17 08:04:02 -07:00 committed by GitHub
commit 0d7b500cee
2 changed files with 63 additions and 17 deletions

View file

@ -191,27 +191,32 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque
if *sbName == "" { if *sbName == "" {
return nil, fmt.Errorf("PodSandboxId should not be empty") return nil, fmt.Errorf("PodSandboxId should not be empty")
} }
sb := s.state.sandboxes[*sbName] sb := s.getSandbox(*sbName)
if sb == nil { if sb == nil {
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName) return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
} }
podInfraContainer := *sbName + "-infra" podInfraContainer := *sbName + "-infra"
sb.containersLock.Lock()
for _, c := range sb.containers { for _, c := range sb.containers {
if podInfraContainer == c.Name() { if podInfraContainer == c.Name() {
podNamespace := "" podNamespace := ""
netnsPath, err := c.NetNsPath() netnsPath, err := c.NetNsPath()
if err != nil { if err != nil {
sb.containersLock.Unlock()
return nil, err return nil, err
} }
if err := s.netPlugin.TearDownPod(netnsPath, podNamespace, *sbName, podInfraContainer); err != nil { if err := s.netPlugin.TearDownPod(netnsPath, podNamespace, *sbName, podInfraContainer); err != nil {
sb.containersLock.Unlock()
return nil, fmt.Errorf("failed to destroy network for container %s in sandbox %s: %v", c.Name(), *sbName, err) return nil, fmt.Errorf("failed to destroy network for container %s in sandbox %s: %v", c.Name(), *sbName, err)
} }
} }
if err := s.runtime.StopContainer(c); err != nil { if err := s.runtime.StopContainer(c); err != nil {
sb.containersLock.Unlock()
return nil, fmt.Errorf("failed to stop container %s in sandbox %s: %v", c.Name(), *sbName, err) return nil, fmt.Errorf("failed to stop container %s in sandbox %s: %v", c.Name(), *sbName, err)
} }
} }
sb.containersLock.Unlock()
return &pb.StopPodSandboxResponse{}, nil return &pb.StopPodSandboxResponse{}, nil
} }
@ -223,7 +228,7 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR
if *sbName == "" { if *sbName == "" {
return nil, fmt.Errorf("PodSandboxId should not be empty") return nil, fmt.Errorf("PodSandboxId should not be empty")
} }
sb := s.state.sandboxes[*sbName] sb := s.getSandbox(*sbName)
if sb == nil { if sb == nil {
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName) return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
} }
@ -231,18 +236,23 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR
podInfraContainer := *sbName + "-infra" podInfraContainer := *sbName + "-infra"
// Delete all the containers in the sandbox // Delete all the containers in the sandbox
sb.containersLock.Lock()
for _, c := range sb.containers { for _, c := range sb.containers {
if err := s.runtime.DeleteContainer(c); err != nil { if err := s.runtime.DeleteContainer(c); err != nil {
sb.containersLock.Unlock()
return nil, fmt.Errorf("failed to delete container %s in sandbox %s: %v", c.Name(), *sbName, err) return nil, fmt.Errorf("failed to delete container %s in sandbox %s: %v", c.Name(), *sbName, err)
} }
if podInfraContainer == c.Name() { if podInfraContainer == c.Name() {
sb.containersLock.Unlock()
continue continue
} }
containerDir := filepath.Join(s.runtime.ContainerDir(), c.Name()) containerDir := filepath.Join(s.runtime.ContainerDir(), c.Name())
if err := os.RemoveAll(containerDir); err != nil { if err := os.RemoveAll(containerDir); err != nil {
sb.containersLock.Unlock()
return nil, fmt.Errorf("failed to remove container %s directory: %v", c.Name(), err) return nil, fmt.Errorf("failed to remove container %s directory: %v", c.Name(), err)
} }
} }
sb.containersLock.Unlock()
// Remove the files related to the sandbox // Remove the files related to the sandbox
podSandboxDir := filepath.Join(s.sandboxDir, *sbName) podSandboxDir := filepath.Join(s.sandboxDir, *sbName)
@ -271,13 +281,13 @@ func (s *Server) PodSandboxStatus(ctx context.Context, req *pb.PodSandboxStatusR
if *sbName == "" { if *sbName == "" {
return nil, fmt.Errorf("PodSandboxId should not be empty") return nil, fmt.Errorf("PodSandboxId should not be empty")
} }
sb := s.state.sandboxes[*sbName] sb := s.getSandbox(*sbName)
if sb == nil { if sb == nil {
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName) return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
} }
podInfraContainerName := *sbName + "-infra" podInfraContainerName := *sbName + "-infra"
podInfraContainer := sb.containers[podInfraContainerName] podInfraContainer := sb.getContainer(podInfraContainerName)
cState := s.runtime.ContainerStatus(podInfraContainer) cState := s.runtime.ContainerStatus(podInfraContainer)
created := cState.Created.Unix() created := cState.Created.Unix()

View file

@ -3,6 +3,7 @@ package server
import ( import (
"fmt" "fmt"
"os" "os"
"sync"
"github.com/kubernetes-incubator/ocid/oci" "github.com/kubernetes-incubator/ocid/oci"
"github.com/kubernetes-incubator/ocid/utils" "github.com/kubernetes-incubator/ocid/utils"
@ -18,6 +19,7 @@ const (
type Server struct { type Server struct {
runtime *oci.Runtime runtime *oci.Runtime
sandboxDir string sandboxDir string
stateLock sync.Mutex
state *serverState state *serverState
netPlugin ocicni.CNIPlugin netPlugin ocicni.CNIPlugin
} }
@ -66,34 +68,68 @@ type sandbox struct {
name string name string
logDir string logDir string
labels map[string]string labels map[string]string
containersLock sync.Mutex
containers map[string]*oci.Container containers map[string]*oci.Container
} }
func (s *Server) addSandbox(sb *sandbox) {
s.state.sandboxes[sb.name] = sb
}
func (s *Server) hasSandbox(name string) bool {
_, ok := s.state.sandboxes[name]
return ok
}
func (s *sandbox) addContainer(c *oci.Container) { func (s *sandbox) addContainer(c *oci.Container) {
s.containersLock.Lock()
s.containers[c.Name()] = c s.containers[c.Name()] = c
s.containersLock.Unlock()
}
func (s *sandbox) getContainer(name string) *oci.Container {
s.containersLock.Lock()
c := s.containers[name]
s.containersLock.Unlock()
return c
} }
func (s *sandbox) removeContainer(c *oci.Container) { func (s *sandbox) removeContainer(c *oci.Container) {
s.containersLock.Lock()
delete(s.containers, c.Name()) delete(s.containers, c.Name())
s.containersLock.Unlock()
}
func (s *Server) addSandbox(sb *sandbox) {
s.stateLock.Lock()
s.state.sandboxes[sb.name] = sb
s.stateLock.Unlock()
}
func (s *Server) getSandbox(name string) *sandbox {
s.stateLock.Lock()
sb := s.state.sandboxes[name]
s.stateLock.Unlock()
return sb
}
func (s *Server) hasSandbox(name string) bool {
s.stateLock.Lock()
_, ok := s.state.sandboxes[name]
s.stateLock.Unlock()
return ok
} }
func (s *Server) addContainer(c *oci.Container) { func (s *Server) addContainer(c *oci.Container) {
s.stateLock.Lock()
sandbox := s.state.sandboxes[c.Sandbox()] sandbox := s.state.sandboxes[c.Sandbox()]
sandbox.addContainer(c) sandbox.addContainer(c)
s.state.containers[c.Name()] = c s.state.containers[c.Name()] = c
s.stateLock.Unlock()
}
func (s *Server) getContainer(name string) *oci.Container {
s.stateLock.Lock()
c := s.state.containers[name]
s.stateLock.Unlock()
return c
} }
func (s *Server) removeContainer(c *oci.Container) { func (s *Server) removeContainer(c *oci.Container) {
s.stateLock.Lock()
sandbox := s.state.sandboxes[c.Sandbox()] sandbox := s.state.sandboxes[c.Sandbox()]
sandbox.removeContainer(c) sandbox.removeContainer(c)
delete(s.state.containers, c.Name()) delete(s.state.containers, c.Name())
s.stateLock.Unlock()
} }