Merge pull request #20 from runcom/locks
server: locking around server components
This commit is contained in:
commit
0d7b500cee
2 changed files with 63 additions and 17 deletions
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -63,37 +65,71 @@ type serverState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type sandbox struct {
|
type sandbox struct {
|
||||||
name string
|
name string
|
||||||
logDir string
|
logDir string
|
||||||
labels map[string]string
|
labels map[string]string
|
||||||
containers map[string]*oci.Container
|
containersLock sync.Mutex
|
||||||
}
|
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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue