소스 검색

Fix overlay2 ignoring whiteout files

Currently when overlay creates a whiteout file then the overlay2 layer is archived,
the correct tar header will be created for the whiteout file, but the tar logic will then attempt to open the file causing a failure.
When tar encounters such failures the file is skipped and excluded for the archive, causing the whiteout to be ignored.
By skipping the copy of empty files, no open attempt will be made on whiteout files.

Fixes #23863

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Derek McGowan 9 년 전
부모
커밋
bd13c53f8d
4개의 변경된 파일48개의 추가작업 그리고 1개의 파일을 삭제
  1. 20 0
      daemon/graphdriver/graphtest/graphtest_unix.go
  2. 26 0
      daemon/graphdriver/graphtest/testutil.go
  3. 1 1
      pkg/archive/archive.go
  4. 1 0
      pkg/archive/archive_linux.go

+ 20 - 0
daemon/graphdriver/graphtest/graphtest_unix.go

@@ -197,6 +197,8 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 	defer PutDriver(t)
 	base := stringid.GenerateRandomID()
 	upper := stringid.GenerateRandomID()
+	deleteFile := "file-remove.txt"
+	deleteFileContent := []byte("This file should get removed in upper!")
 
 	if err := driver.Create(base, "", "", nil); err != nil {
 		t.Fatal(err)
@@ -206,6 +208,10 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 		t.Fatal(err)
 	}
 
+	if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil {
+		t.Fatal(err)
+	}
+
 	if err := driver.Create(upper, base, "", nil); err != nil {
 		t.Fatal(err)
 	}
@@ -213,6 +219,11 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 	if err := addManyFiles(driver, upper, fileCount, 6); err != nil {
 		t.Fatal(err)
 	}
+
+	if err := removeFile(driver, upper, deleteFile); err != nil {
+		t.Fatal(err)
+	}
+
 	diffSize, err := driver.DiffSize(upper, "")
 	if err != nil {
 		t.Fatal(err)
@@ -227,6 +238,10 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 		t.Fatal(err)
 	}
 
+	if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil {
+		t.Fatal(err)
+	}
+
 	arch, err := driver.Diff(upper, base)
 	if err != nil {
 		t.Fatal(err)
@@ -248,9 +263,14 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 	if applyDiffSize != diffSize {
 		t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize)
 	}
+
 	if err := checkManyFiles(driver, diff, fileCount, 6); err != nil {
 		t.Fatal(err)
 	}
+
+	if err := checkFileRemoved(driver, diff, deleteFile); err != nil {
+		t.Fatal(err)
+	}
 }
 
 // DriverTestChanges tests computed changes on a layer matches changes made

+ 26 - 0
daemon/graphdriver/graphtest/testutil.go

@@ -78,6 +78,32 @@ func addFile(drv graphdriver.Driver, layer, filename string, content []byte) err
 	return ioutil.WriteFile(path.Join(root, filename), content, 0755)
 }
 
+func removeFile(drv graphdriver.Driver, layer, filename string) error {
+	root, err := drv.Get(layer, "")
+	if err != nil {
+		return err
+	}
+	defer drv.Put(layer)
+
+	return os.Remove(path.Join(root, filename))
+}
+
+func checkFileRemoved(drv graphdriver.Driver, layer, filename string) error {
+	root, err := drv.Get(layer, "")
+	if err != nil {
+		return err
+	}
+	defer drv.Put(layer)
+
+	if _, err := os.Stat(path.Join(root, filename)); err == nil {
+		return fmt.Errorf("file still exists: %s", path.Join(root, filename))
+	} else if !os.IsNotExist(err) {
+		return err
+	}
+
+	return nil
+}
+
 func addManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) error {
 	root, err := drv.Get(layer, "")
 	if err != nil {

+ 1 - 1
pkg/archive/archive.go

@@ -359,7 +359,7 @@ func (ta *tarAppender) addTarFile(path, name string) error {
 		return err
 	}
 
-	if hdr.Typeflag == tar.TypeReg {
+	if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {
 		file, err := os.Open(path)
 		if err != nil {
 			return err

+ 1 - 0
pkg/archive/archive_linux.go

@@ -26,6 +26,7 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
 		hdr.Name = WhiteoutPrefix + hdr.Name
 		hdr.Mode = 0600
 		hdr.Typeflag = tar.TypeReg
+		hdr.Size = 0
 	}
 
 	if fi.Mode()&os.ModeDir != 0 {