Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix docker --init with /dev bind mount #37665

Merged
merged 1 commit into from
Sep 6, 2018
Merged

Conversation

kolyshkin
Copy link
Contributor

@kolyshkin kolyshkin commented Aug 17, 2018

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.

Fixes #37645

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall SGTM; perhaps we need a test for this, and we should also look into the alternative approach (change the destination to (e.g.) /sbin/docker-init)

@@ -474,7 +474,7 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c
// filter out mount overridden by a user supplied mount
continue
}
if mountDev && strings.HasPrefix(m.Destination, "/dev/") {
if mountDev && strings.HasPrefix(m.Destination, "/dev/") && m.Destination != "/dev/init" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitty; wondering if it would be clearer to make this a separate if (also if we should put /dev/init in a constant)

Copy link
Contributor

@anusha-ragunathan anusha-ragunathan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kolyshkin
Copy link
Contributor Author

yes, it is better to move it to e.g. /sbin (I guess not too many people bind-mount /sbin, and even if they do, there are no special cases in the code so we'll be fine).

Copy link
Member

@boaz0 boaz0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codecov
Copy link

codecov bot commented Aug 22, 2018

Codecov Report

❗ No coverage uploaded for pull request base (master@0c5f8d2). Click here to learn what that means.
The diff coverage is 0%.

@@            Coverage Diff            @@
##             master   #37665   +/-   ##
=========================================
  Coverage          ?   36.04%           
=========================================
  Files             ?      609           
  Lines             ?    45061           
  Branches          ?        0           
=========================================
  Hits              ?    16240           
  Misses            ?    26589           
  Partials          ?     2232

@kolyshkin
Copy link
Contributor Author

I have changed the commit to use /sbin/docker-init as a bind-mount destination for in-container init. It still won't work with bind-mounted /sbin but I guess this case is much less common.

There is still one open question: what to do if a user-supplied mount overshadows a mount from spec. Opened #37702 to address it.

@kolyshkin
Copy link
Contributor Author

note all the LGTMs above are now invalid as the code is different (I should have probably close the PR and create a different one).

@kolyshkin
Copy link
Contributor Author

rebased; should help CI

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>
@kolyshkin
Copy link
Contributor Author

rebased; should help CI (hmm, I start to sound like a broken record)

@kolyshkin
Copy link
Contributor Author

ppc ci failure is #33041

02:08:40.182 FAIL: docker_cli_swarm_test.go:1376: DockerSwarmSuite.TestSwarmClusterRotateUnlockKey

z ci failure is most probably just slow/overloaded hw, also see #36907

00:22:15.137 === RUN TestCreateServiceConfigFileMode
00:22:29.326 --- FAIL: TestCreateServiceConfigFileMode (14.19s)
00:22:29.326 daemon.go:290: [defd2263b4179] waiting for daemon to start
00:22:29.326 daemon.go:322: [defd2263b4179] daemon started
00:22:29.326 create_test.go:306: timeout hit after 10s: task count at 1 waiting for 0
00:22:29.326 daemon.go:280: [defd2263b4179] exiting daemon

@kolyshkin
Copy link
Contributor Author

Note this commit just changes in-container init path from /dev/init to /sbin/init, which should greatly reduce the chance to break things (as not too many users, I assume, bind-mount /sbin inside container).

The ultimate fix is #37704 which rearranges the mount in proper way so even if /sbin is bind-mounted from the host, /sbin/init will still be visible.

I think that both fixes make sense and should be merged.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@atline
Copy link

atline commented Jun 18, 2019

I wonder which version of docker ce already used this patch?

@thaJeztah
Copy link
Member

Looks like this will be in the upcoming 19.03 release; https://github.com/docker/engine/blob/19.03/daemon/oci_linux.go#L36

(It's not in the 18.09 codebase)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Could not mount /dev with --init flag
9 participants