From f70a2648621ab1463299eabecda8e8c7584831c3 Mon Sep 17 00:00:00 2001 From: jingrui Date: Thu, 3 Jan 2019 16:01:36 +0800 Subject: [PATCH 043/111] docker: Make sure the pid exist in pidfile is docker reason: cherry-pick commits to docker-18.09. cherry-pick from b4714e3321 | * Make sure the pid exist in pidfile is docker Because of the recycling of used PIDs policy in kernel, it could be possible that the process died with pidfile existing and when the process boot next time, the pid in pidfile has been assigned to another process, this would make the process can't be boot again without removing the pidfile manually. Change-Id: I237566682716733174900cd4dc76ce74ff9f4195 Signed-off-by: Lei Jitang Signed-off-by: jingrui --- components/engine/pkg/pidfile/pidfile.go | 30 +++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/components/engine/pkg/pidfile/pidfile.go b/components/engine/pkg/pidfile/pidfile.go index 0617a89e5f..485c00138b 100644 --- a/components/engine/pkg/pidfile/pidfile.go +++ b/components/engine/pkg/pidfile/pidfile.go @@ -4,6 +4,7 @@ package pidfile // import "github.com/docker/docker/pkg/pidfile" import ( + "bufio" "fmt" "io/ioutil" "os" @@ -19,12 +20,39 @@ type PIDFile struct { path string } +// isSameApplication check whether the pid exist in pidfile +// is the the same application we are going to run. +func isSameApplication(pid int) (bool, error) { + path := filepath.Join("/proc", strconv.Itoa(pid), "status") + file, err := os.Open(path) + if err != nil { + return false, err + } + defer file.Close() + sc := bufio.NewScanner(file) + for sc.Scan() { + lens := strings.Split(sc.Text(), ":") + if len(lens) == 2 && strings.TrimSpace(lens[0]) == "Name" { + if strings.TrimSpace(lens[1]) == os.Args[0] { + return true, nil + } + return false, nil + } + } + if err := sc.Err(); err != nil { + return false, err + } + return false, nil +} + func checkPIDFileAlreadyExists(path string) error { if pidByte, err := ioutil.ReadFile(path); err == nil { pidString := strings.TrimSpace(string(pidByte)) if pid, err := strconv.Atoi(pidString); err == nil { if processExists(pid) { - return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path) + if same, err := isSameApplication(pid); same || (err != nil && !os.IsNotExist(err)) { + return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path) + } } } } -- 2.17.1