Sfoglia il codice sorgente

Merge pull request #11525 from cpuguy83/10969-cleanup-unix-sockets

cleanup unix sockets
Jessie Frazelle 10 anni fa
parent
commit
41f2b010c6
4 ha cambiato i file con 57 aggiunte e 19 eliminazioni
  1. 9 1
      api/server/server.go
  2. 3 2
      docker/daemon.go
  3. 17 16
      engine/engine.go
  4. 28 0
      integration-cli/docker_cli_daemon_test.go

+ 9 - 1
api/server/server.go

@@ -1578,7 +1578,15 @@ func ServeApi(job *engine.Job) engine.Status {
 				chErrors <- err
 				return
 			}
-			chErrors <- srv.Serve()
+			job.Eng.OnShutdown(func() {
+				if err := srv.Close(); err != nil {
+					log.Error(err)
+				}
+			})
+			if err = srv.Serve(); err != nil && strings.Contains(err.Error(), "use of closed network connection") {
+				err = nil
+			}
+			chErrors <- err
 		}()
 	}
 

+ 3 - 2
docker/daemon.go

@@ -186,8 +186,9 @@ func mainDaemon() {
 	errAPI := <-serveAPIWait
 	// If we have an error here it is unique to API (as daemonErr would have
 	// exited the daemon process above)
+	eng.Shutdown()
 	if errAPI != nil {
-		log.Errorf("Shutting down due to ServeAPI error: %v", errAPI)
+		log.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)
 	}
-	eng.Shutdown()
+
 }

+ 17 - 16
engine/engine.go

@@ -46,18 +46,19 @@ func unregister(name string) {
 // It acts as a store for *containers*, and allows manipulation of these
 // containers by executing *jobs*.
 type Engine struct {
-	handlers   map[string]Handler
-	catchall   Handler
-	hack       Hack // data for temporary hackery (see hack.go)
-	id         string
-	Stdout     io.Writer
-	Stderr     io.Writer
-	Stdin      io.Reader
-	Logging    bool
-	tasks      sync.WaitGroup
-	l          sync.RWMutex // lock for shutdown
-	shutdown   bool
-	onShutdown []func() // shutdown handlers
+	handlers     map[string]Handler
+	catchall     Handler
+	hack         Hack // data for temporary hackery (see hack.go)
+	id           string
+	Stdout       io.Writer
+	Stderr       io.Writer
+	Stdin        io.Reader
+	Logging      bool
+	tasks        sync.WaitGroup
+	l            sync.RWMutex // lock for shutdown
+	shutdownWait sync.WaitGroup
+	shutdown     bool
+	onShutdown   []func() // shutdown handlers
 }
 
 func (eng *Engine) Register(name string, handler Handler) error {
@@ -143,6 +144,7 @@ func (eng *Engine) Job(name string, args ...string) *Job {
 func (eng *Engine) OnShutdown(h func()) {
 	eng.l.Lock()
 	eng.onShutdown = append(eng.onShutdown, h)
+	eng.shutdownWait.Add(1)
 	eng.l.Unlock()
 }
 
@@ -156,6 +158,7 @@ func (eng *Engine) Shutdown() {
 	eng.l.Lock()
 	if eng.shutdown {
 		eng.l.Unlock()
+		eng.shutdownWait.Wait()
 		return
 	}
 	eng.shutdown = true
@@ -180,17 +183,15 @@ func (eng *Engine) Shutdown() {
 
 	// Call shutdown handlers, if any.
 	// Timeout after 10 seconds.
-	var wg sync.WaitGroup
 	for _, h := range eng.onShutdown {
-		wg.Add(1)
 		go func(h func()) {
-			defer wg.Done()
 			h()
+			eng.shutdownWait.Done()
 		}(h)
 	}
 	done := make(chan struct{})
 	go func() {
-		wg.Wait()
+		eng.shutdownWait.Wait()
 		close(done)
 	}()
 	select {

+ 28 - 0
integration-cli/docker_cli_daemon_test.go

@@ -800,3 +800,31 @@ func TestDaemonDots(t *testing.T) {
 
 	logDone("daemon - test dots on INFO")
 }
+
+func TestDaemonUnixSockCleanedUp(t *testing.T) {
+	d := NewDaemon(t)
+	dir, err := ioutil.TempDir("", "socket-cleanup-test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	sockPath := filepath.Join(dir, "docker.sock")
+	if err := d.Start("--host", "unix://"+sockPath); err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := os.Stat(sockPath); err != nil {
+		t.Fatal("socket does not exist")
+	}
+
+	if err := d.Stop(); err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) {
+		t.Fatal("unix socket is not cleaned up")
+	}
+
+	logDone("daemon - unix socket is cleaned up")
+}