浏览代码

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 <kolyshkin@gmail.com>
Kir Kolyshkin 6 年之前
父节点
当前提交
bcacbf523b
共有 1 个文件被更改,包括 8 次插入7 次删除
  1. 8 7
      daemon/oci_linux.go

+ 8 - 7
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"},