瀏覽代碼

docker daemon: create file containing PID

Ensure the docker daemon creates a file containing its PID under
/var/run/docker.pid.

The daemon takes care of removing the pid file when it receives either
SIGTERM, SIGINT or SIGKILL.

The daemon also refuses to start when the pidfile is found. An
explanation message is shown to the user when this happens.

This change is required to make docker easier to manage by tools like
checkproc which rely on this information.
Flavio Castelli 12 年之前
父節點
當前提交
fb0b375be7
共有 1 個文件被更改,包括 42 次插入2 次删除
  1. 42 2
      docker/docker.go

+ 42 - 2
docker/docker.go

@@ -2,12 +2,15 @@ package main
 
 
 import (
 import (
 	"flag"
 	"flag"
+	"fmt"
 	"github.com/dotcloud/docker"
 	"github.com/dotcloud/docker"
 	"github.com/dotcloud/docker/rcli"
 	"github.com/dotcloud/docker/rcli"
 	"github.com/dotcloud/docker/term"
 	"github.com/dotcloud/docker/term"
 	"io"
 	"io"
 	"log"
 	"log"
 	"os"
 	"os"
+	"os/signal"
+	"syscall"
 )
 )
 
 
 var GIT_COMMIT string
 var GIT_COMMIT string
@@ -22,6 +25,7 @@ func main() {
 	flDaemon := flag.Bool("d", false, "Daemon mode")
 	flDaemon := flag.Bool("d", false, "Daemon mode")
 	flDebug := flag.Bool("D", false, "Debug mode")
 	flDebug := flag.Bool("D", false, "Debug mode")
 	bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
 	bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge")
+	pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID")
 	flag.Parse()
 	flag.Parse()
 	if *bridgeName != "" {
 	if *bridgeName != "" {
 		docker.NetworkBridgeIface = *bridgeName
 		docker.NetworkBridgeIface = *bridgeName
@@ -37,7 +41,7 @@ func main() {
 			flag.Usage()
 			flag.Usage()
 			return
 			return
 		}
 		}
-		if err := daemon(); err != nil {
+		if err := daemon(*pidfile); err != nil {
 			log.Fatal(err)
 			log.Fatal(err)
 		}
 		}
 	} else {
 	} else {
@@ -47,7 +51,43 @@ func main() {
 	}
 	}
 }
 }
 
 
-func daemon() error {
+func createPidFile(pidfile string) error {
+	if _, err := os.Stat(pidfile); err == nil {
+		return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile)
+	}
+
+	file, err := os.Create(pidfile)
+	if err != nil {
+		return err
+	}
+
+	defer file.Close()
+
+	_, err = fmt.Fprintf(file, "%d", os.Getpid())
+	return err
+}
+
+func removePidFile(pidfile string) {
+	if err := os.Remove(pidfile); err != nil {
+		log.Printf("Error removing %s: %s", pidfile, err)
+	}
+}
+
+func daemon(pidfile string) error {
+		if err := createPidFile(pidfile); err != nil {
+			log.Fatal(err)
+		}
+		defer removePidFile(pidfile)
+
+		c := make(chan os.Signal, 1)
+		signal.Notify(c, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM))
+		go func() {
+			sig := <-c
+			log.Printf("Received signal '%v', exiting\n", sig)
+			removePidFile(pidfile)
+			os.Exit(0)
+		}()
+
 	service, err := docker.NewServer()
 	service, err := docker.NewServer()
 	if err != nil {
 	if err != nil {
 		return err
 		return err