github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/integration/container/daemon_linux_test.go (about) 1 package container // import "github.com/docker/docker/integration/container" 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "strconv" 8 "strings" 9 "testing" 10 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/integration/internal/container" 13 "github.com/docker/docker/internal/test/daemon" 14 "golang.org/x/sys/unix" 15 "gotest.tools/assert" 16 is "gotest.tools/assert/cmp" 17 "gotest.tools/skip" 18 ) 19 20 // This is a regression test for #36145 21 // It ensures that a container can be started when the daemon was improperly 22 // shutdown when the daemon is brought back up. 23 // 24 // The regression is due to improper error handling preventing a container from 25 // being restored and as such have the resources cleaned up. 26 // 27 // To test this, we need to kill dockerd, then kill both the containerd-shim and 28 // the container process, then start dockerd back up and attempt to start the 29 // container again. 30 func TestContainerStartOnDaemonRestart(t *testing.T) { 31 skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run") 32 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 33 t.Parallel() 34 35 d := daemon.New(t) 36 d.StartWithBusybox(t, "--iptables=false") 37 defer d.Stop(t) 38 39 c := d.NewClientT(t) 40 41 ctx := context.Background() 42 43 cID := container.Create(t, ctx, c) 44 defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) 45 46 err := c.ContainerStart(ctx, cID, types.ContainerStartOptions{}) 47 assert.Check(t, err, "error starting test container") 48 49 inspect, err := c.ContainerInspect(ctx, cID) 50 assert.Check(t, err, "error getting inspect data") 51 52 ppid := getContainerdShimPid(t, inspect) 53 54 err = d.Kill() 55 assert.Check(t, err, "failed to kill test daemon") 56 57 err = unix.Kill(inspect.State.Pid, unix.SIGKILL) 58 assert.Check(t, err, "failed to kill container process") 59 60 err = unix.Kill(ppid, unix.SIGKILL) 61 assert.Check(t, err, "failed to kill containerd-shim") 62 63 d.Start(t, "--iptables=false") 64 65 err = c.ContainerStart(ctx, cID, types.ContainerStartOptions{}) 66 assert.Check(t, err, "failed to start test container") 67 } 68 69 func getContainerdShimPid(t *testing.T, c types.ContainerJSON) int { 70 statB, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", c.State.Pid)) 71 assert.Check(t, err, "error looking up containerd-shim pid") 72 73 // ppid is the 4th entry in `/proc/pid/stat` 74 ppid, err := strconv.Atoi(strings.Fields(string(statB))[3]) 75 assert.Check(t, err, "error converting ppid field to int") 76 77 assert.Check(t, ppid != 1, "got unexpected ppid") 78 return ppid 79 } 80 81 // TestDaemonRestartIpcMode makes sure a container keeps its ipc mode 82 // (derived from daemon default) even after the daemon is restarted 83 // with a different default ipc mode. 84 func TestDaemonRestartIpcMode(t *testing.T) { 85 skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run") 86 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 87 t.Parallel() 88 89 d := daemon.New(t) 90 d.StartWithBusybox(t, "--iptables=false", "--default-ipc-mode=private") 91 defer d.Stop(t) 92 93 c := d.NewClientT(t) 94 ctx := context.Background() 95 96 // check the container is created with private ipc mode as per daemon default 97 cID := container.Run(t, ctx, c, 98 container.WithCmd("top"), 99 container.WithRestartPolicy("always"), 100 ) 101 defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) 102 103 inspect, err := c.ContainerInspect(ctx, cID) 104 assert.NilError(t, err) 105 assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "private")) 106 107 // restart the daemon with shareable default ipc mode 108 d.Restart(t, "--iptables=false", "--default-ipc-mode=shareable") 109 110 // check the container is still having private ipc mode 111 inspect, err = c.ContainerInspect(ctx, cID) 112 assert.NilError(t, err) 113 assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "private")) 114 115 // check a new container is created with shareable ipc mode as per new daemon default 116 cID = container.Run(t, ctx, c) 117 defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) 118 119 inspect, err = c.ContainerInspect(ctx, cID) 120 assert.NilError(t, err) 121 assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "shareable")) 122 }