Browse code

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 authored on 2016/06/24 05:34:38
Showing 4 changed files
... ...
@@ -197,6 +197,8 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
197 197
 	defer PutDriver(t)
198 198
 	base := stringid.GenerateRandomID()
199 199
 	upper := stringid.GenerateRandomID()
200
+	deleteFile := "file-remove.txt"
201
+	deleteFileContent := []byte("This file should get removed in upper!")
200 202
 
201 203
 	if err := driver.Create(base, "", "", nil); err != nil {
202 204
 		t.Fatal(err)
... ...
@@ -206,6 +208,10 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
206 206
 		t.Fatal(err)
207 207
 	}
208 208
 
209
+	if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil {
210
+		t.Fatal(err)
211
+	}
212
+
209 213
 	if err := driver.Create(upper, base, "", nil); err != nil {
210 214
 		t.Fatal(err)
211 215
 	}
... ...
@@ -213,6 +219,11 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
213 213
 	if err := addManyFiles(driver, upper, fileCount, 6); err != nil {
214 214
 		t.Fatal(err)
215 215
 	}
216
+
217
+	if err := removeFile(driver, upper, deleteFile); err != nil {
218
+		t.Fatal(err)
219
+	}
220
+
216 221
 	diffSize, err := driver.DiffSize(upper, "")
217 222
 	if err != nil {
218 223
 		t.Fatal(err)
... ...
@@ -227,6 +238,10 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
227 227
 		t.Fatal(err)
228 228
 	}
229 229
 
230
+	if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil {
231
+		t.Fatal(err)
232
+	}
233
+
230 234
 	arch, err := driver.Diff(upper, base)
231 235
 	if err != nil {
232 236
 		t.Fatal(err)
... ...
@@ -248,9 +263,14 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
248 248
 	if applyDiffSize != diffSize {
249 249
 		t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize)
250 250
 	}
251
+
251 252
 	if err := checkManyFiles(driver, diff, fileCount, 6); err != nil {
252 253
 		t.Fatal(err)
253 254
 	}
255
+
256
+	if err := checkFileRemoved(driver, diff, deleteFile); err != nil {
257
+		t.Fatal(err)
258
+	}
254 259
 }
255 260
 
256 261
 // DriverTestChanges tests computed changes on a layer matches changes made
... ...
@@ -78,6 +78,32 @@ func addFile(drv graphdriver.Driver, layer, filename string, content []byte) err
78 78
 	return ioutil.WriteFile(path.Join(root, filename), content, 0755)
79 79
 }
80 80
 
81
+func removeFile(drv graphdriver.Driver, layer, filename string) error {
82
+	root, err := drv.Get(layer, "")
83
+	if err != nil {
84
+		return err
85
+	}
86
+	defer drv.Put(layer)
87
+
88
+	return os.Remove(path.Join(root, filename))
89
+}
90
+
91
+func checkFileRemoved(drv graphdriver.Driver, layer, filename string) error {
92
+	root, err := drv.Get(layer, "")
93
+	if err != nil {
94
+		return err
95
+	}
96
+	defer drv.Put(layer)
97
+
98
+	if _, err := os.Stat(path.Join(root, filename)); err == nil {
99
+		return fmt.Errorf("file still exists: %s", path.Join(root, filename))
100
+	} else if !os.IsNotExist(err) {
101
+		return err
102
+	}
103
+
104
+	return nil
105
+}
106
+
81 107
 func addManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) error {
82 108
 	root, err := drv.Get(layer, "")
83 109
 	if err != nil {
... ...
@@ -359,7 +359,7 @@ func (ta *tarAppender) addTarFile(path, name string) error {
359 359
 		return err
360 360
 	}
361 361
 
362
-	if hdr.Typeflag == tar.TypeReg {
362
+	if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {
363 363
 		file, err := os.Open(path)
364 364
 		if err != nil {
365 365
 			return err
... ...
@@ -26,6 +26,7 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
26 26
 		hdr.Name = WhiteoutPrefix + hdr.Name
27 27
 		hdr.Mode = 0600
28 28
 		hdr.Typeflag = tar.TypeReg
29
+		hdr.Size = 0
29 30
 	}
30 31
 
31 32
 	if fi.Mode()&os.ModeDir != 0 {