소스 검색

Fix --volumes-from mount failure

As explained in https://github.com/dotcloud/docker/issues/4979
--volumes-from fails with ENOFILE errors.

This is because the code tries to look at the "from" volume without
ensuring that it is mounted yet. We fix this by mounting the containers
before stating in it.

Also includes a regression test.

Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
Alexander Larsson 11 년 전
부모
커밋
bd94f84ded
2개의 변경된 파일24개의 추가작업 그리고 1개의 파일을 삭제
  1. 18 0
      integration-cli/docker_cli_run_test.go
  2. 6 1
      runtime/volumes.go

+ 18 - 0
integration-cli/docker_cli_run_test.go

@@ -272,6 +272,24 @@ func TestDockerRunWithVolumesAsFiles(t *testing.T) {
 	logDone("run - regression test for #4741 - volumes from as files")
 }
 
+// Regression test for #4979
+func TestDockerRunWithVolumesFromExited(t *testing.T) {
+	runCmd := exec.Command(dockerBinary, "run", "--name", "test-data", "--volume", "/some/dir", "busybox", "touch", "/some/dir/file")
+	out, stderr, exitCode, err := runCommandWithStdoutStderr(runCmd)
+	if err != nil && exitCode != 0 {
+		t.Fatal("1", out, stderr, err)
+	}
+
+	runCmd = exec.Command(dockerBinary, "run", "--volumes-from", "test-data", "busybox", "cat", "/some/dir/file")
+	out, stderr, exitCode, err = runCommandWithStdoutStderr(runCmd)
+	if err != nil && exitCode != 0 {
+		t.Fatal("2", out, stderr, err)
+	}
+	deleteAllContainers()
+
+	logDone("run - regression test for #4979 - volumes-from on exited container")
+}
+
 // Regression test for #4830
 func TestDockerRunWithRelativePath(t *testing.T) {
 	runCmd := exec.Command(dockerBinary, "run", "-v", "tmp:/other-tmp", "busybox", "true")

+ 6 - 1
runtime/volumes.go

@@ -81,9 +81,14 @@ func applyVolumesFrom(container *Container) error {
 
 			c := container.runtime.Get(specParts[0])
 			if c == nil {
-				return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.ID)
+				return fmt.Errorf("Container %s not found. Impossible to mount its volumes", specParts[0])
 			}
 
+			if err := c.Mount(); err != nil {
+				return fmt.Errorf("Container %s failed to mount. Impossible to mount its volumes", specParts[0])
+			}
+			defer c.Unmount()
+
 			for volPath, id := range c.Volumes {
 				if _, exists := container.Volumes[volPath]; exists {
 					continue