From 32e0ea346b5aa3446af12206ef4525675fb27265 Mon Sep 17 00:00:00 2001 From: Lei Jitang Date: Thu, 1 Dec 2016 02:25:24 -0500 Subject: [PATCH] Fix docker restart panic on machine ungracefully shutdown Machine ungracefully shutdown leaves a lot of container has a Running=true state. ``` $ cat config.v2.json | jq . "Running": true, "Paused": false, "Restarting": false, ``` And the next docker start will fail with panic. ``` time="2016-12-01T01:54:45.086446715-05:00" level=warning msg="libcontainerd: client is out of sync, restore was called on a fully synced container (49f41ad5ca0be860622d9190673b5816d012022fb2c1794560ec4851e7cfec6a)." time="2016-12-01T01:54:45.087046004-05:00" level=warning msg="libcontainerd: failed to retrieve container 49f41ad5ca0be860622d9190673b5816d012022fb2c1794560ec4851e7cfec6a state: rpc error: code = 2 desc = containerd: container not found" panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x5db7f3] goroutine 57 [running]: panic(0x16a8e60, 0xc420010130) /usr/local/go/src/runtime/panic.go:500 +0x1a1 github.com/docker/docker/libcontainerd.(*client).Restore(0xc4202e1a40, 0xc420415000, 0x40, 0xc42015a0b0, 0x0, 0x0, 0x0, 0x0, 0x0) /go/src/github.com/docker/docker/libcontainerd/client_linux.go:457 +0x553 github.com/docker/docker/daemon.(*Daemon).restore.func1(0xc4201c46f0, 0xc4202581e0, 0xc4201c46e8, 0xc42047bfb0, 0xc42047bf80, 0xc42047bf50, 0xc42024ba10, 0xc420512c00) /go/src/github.com/docker/docker/daemon/daemon.go:205 +0x198 created by github.com/docker/docker/daemon.(*Daemon).restore /go/src/github.com/docker/docker/daemon/daemon.go:260 +0x7bb ``` Signed-off-by: Lei Jitang (cherry picked from commit 267422e4d08244e701ce049ab55ca0ad9879ba78) Signed-off-by: Victor Vieux --- libcontainerd/client_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcontainerd/client_linux.go b/libcontainerd/client_linux.go index c20b52cec5..657eda2c0d 100644 --- a/libcontainerd/client_linux.go +++ b/libcontainerd/client_linux.go @@ -454,7 +454,7 @@ func (clnt *client) Restore(containerID string, attachStdio StdioCallback, optio if err != nil { logrus.Warnf("libcontainerd: failed to retrieve container %s state: %v", containerID, err) } - if ev != nil && ev.Pid != InitFriendlyName || ev.Type != StateExit { + if ev != nil && (ev.Pid != InitFriendlyName || ev.Type != StateExit) { // Wait a while for the exit event timeout := time.NewTimer(10 * time.Second) tick := time.NewTicker(100 * time.Millisecond)