From bcacbf523b35b6cf22bd84ac33e4425784c5a0a2 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Wed, 22 Aug 2018 13:05:12 -0700 Subject: [PATCH] Fix docker --init with /dev bind mount In case a user wants to have a child reaper inside a container (i.e. run "docker --init") AND a bind-mounted /dev, the following error occurs: > docker run -d -v /dev:/dev --init busybox top > 088c96808c683077f04c4cc2711fddefe1f5970afc085d59e0baae779745a7cf > docker: Error response from daemon: OCI runtime create failed: container_linux.go:296: starting container process caused "exec: "/dev/init": stat /dev/init: no such file or directory": unknown. This happens because if a user-suppled /dev is provided, all the built-in /dev/xxx mounts are filtered out. To solve, let's move in-container init to /sbin, as the chance that /sbin will be bind-mounted to a container is smaller than that for /dev. While at it, let's give it more unique name (docker-init). NOTE it still won't work for the case of bind-mounted /sbin. Signed-off-by: Kir Kolyshkin --- daemon/oci_linux.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 7611fc054d..00ace320df 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -27,6 +27,10 @@ import ( "golang.org/x/sys/unix" ) +const ( + inContainerInitPath = "/sbin/" + daemonconfig.DefaultInitBinary +) + func setResources(s *specs.Spec, r containertypes.Resources) error { weightDevices, err := getBlkioWeightDevices(r) if err != nil { @@ -657,19 +661,16 @@ func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container) if c.HostConfig.PidMode.IsPrivate() { if (c.HostConfig.Init != nil && *c.HostConfig.Init) || (c.HostConfig.Init == nil && daemon.configStore.Init) { - s.Process.Args = append([]string{"/dev/init", "--", c.Path}, c.Args...) - var path string - if daemon.configStore.InitPath == "" { + s.Process.Args = append([]string{inContainerInitPath, "--", c.Path}, c.Args...) + path := daemon.configStore.InitPath + if path == "" { path, err = exec.LookPath(daemonconfig.DefaultInitBinary) if err != nil { return err } } - if daemon.configStore.InitPath != "" { - path = daemon.configStore.InitPath - } s.Mounts = append(s.Mounts, specs.Mount{ - Destination: "/dev/init", + Destination: inContainerInitPath, Type: "bind", Source: path, Options: []string{"bind", "ro"},