Understanding Whiteout Files in Dive's Container Image Analysis
Whiteout files in Dive's analysis are overlay filesystem markers that indicate when files or directories have been deleted in upper Docker image layers, enabling the tool to accurately reconstruct layer state and calculate storage efficiency.
When analyzing Docker and OCI images, the open-source tool Dive must interpret special filesystem entries called whiteout files to properly visualize layer changes. These markers, implemented in the wagoodman/dive repository, allow Dive to distinguish between files that persist from lower layers versus those explicitly removed in subsequent layers.
What Are Whiteout Files in Container Images?
Docker and OCI images use overlay-whiteout files to record deletions within layered filesystems. When a file or directory present in a lower layer is deleted in an upper layer, the overlay filesystem creates a special marker file rather than actually removing the underlying data.
There are two primary types of whiteout markers:
- Regular whiteouts – Files prefixed with
.wh.indicate that a specific file or directory has been deleted. For example,.wh.config.yamlsignals the removal ofconfig.yaml. - Opaque whiteouts – The special marker
.wh..wh..opqindicates that an entire directory has been replaced or deleted, instructing the overlay driver to ignore all contents from lower layers.
How Dive Detects and Filters Whiteout Markers
Dive implements whiteout detection in the dive/filetree package, distinguishing between these marker types to build accurate file trees for each image layer.
Whiteout Prefix Constants in file_tree.go
The recognition patterns for whiteout files are defined in dive/filetree/file_tree.go at lines 18-20:
const (
whiteoutPrefix = ".wh."
doubleWhiteoutPrefix = ".wh..wh.."
)
These constants enable the file tree parser to identify deletion markers during tree construction.
Node Creation Logic in file_node.go
The core filtering logic resides in dive/filetree/file_node.go. When adding paths to the tree via the AddPath method, Dive checks for opaque whiteouts at lines 91-94:
if strings.HasPrefix(name, doubleWhiteoutPrefix) {
return nil
}
For regular whiteout files, the IsWhiteout() method at lines 264-267 provides detection:
func (node *FileNode) IsWhiteout() bool {
return strings.HasPrefix(node.Name, whiteoutPrefix)
}
When displaying paths, Dive strips the whiteout prefix using strings.TrimPrefix at lines 285-289 to show the original filename that was deleted.
Impact on Efficiency Calculations
Whiteout files directly affect Dive's storage efficiency scoring. When a whiteout file indicates directory removal, Dive must account for the total size of all hidden children to accurately reflect the deletion's impact.
In dive/filetree/efficiency.go (lines 57-86), the efficiency calculation logic walks the previous stacked tree to sum the sizes of files hidden by whiteout markers. This ensures that removing a directory via whiteout correctly reduces the efficiency score by the cumulative size of all deleted contents, not just the marker file itself.
Practical Implementation Examples
Detecting Regular Whiteout Files
When processing a standard whiteout marker, Dive creates a node to track the deletion but handles it differently than regular files:
tree := filetree.NewFileTree()
// Regular file – a node is created
node, _, _ := tree.AddPath("/etc/config.yaml", dive.FileInfo{})
fmt.Println(node.Name) // "/etc/config.yaml"
// Whiteout file – node is marked as deletion
// The IsWhiteout() method returns true for ".wh.config.yaml"
Filtering Opaque Whiteout Markers
Opaque whiteouts are completely discarded during tree construction:
node, _, err := tree.AddPath("/var/lib/.wh..wh..opq", dive.FileInfo{})
// node == nil and err == nil – the opaque marker is discarded entirely
This behavior is verified in dive/filetree/file_tree_test.go at lines 327-343, confirming that opaque whiteouts create no tree nodes.
Calculating Efficiency with Directory Whiteouts
When scoring layer efficiency, Dive accounts for removed directory contents:
score, inefficient := filetree.Efficiency([]*filetree.FileTree{lower, upper})
// score reflects the total size of files removed via whiteout markers
// inefficient contains paths with significant size reduction from deletions
The implementation in efficiency.go specifically handles cases where .wh. prefixed entries represent directories, walking the lower layer tree to accumulate the total bytes freed by the deletion.
Summary
- Whiteout files are overlay filesystem markers indicating deleted files or directories in Docker image layers.
- Dive filters opaque whiteouts (
.wh..wh..opq) entirely, while tracking regular whiteouts (.wh.) to represent deletions in the file tree. - Detection constants are defined in
dive/filetree/file_tree.go, with filtering logic indive/filetree/file_node.go. - Efficiency calculations in
dive/filetree/efficiency.gosum the sizes of hidden children when directories are removed via whiteout markers. - Unit tests in
dive/filetree/file_tree_test.goverify that whiteout files are handled correctly during tree construction.
Frequently Asked Questions
What do whiteout files represent in Docker image layers?
Whiteout files represent deletion operations in overlay filesystems. When a file is deleted in an upper layer but exists in a lower layer, Docker creates a .wh. prefixed marker to hide the underlying file without modifying the read-only lower layer. This allows the union filesystem to present a coherent view where the file appears deleted while preserving the original image data.
How does Dive distinguish between regular and opaque whiteout files?
Dive distinguishes these markers using prefix detection constants defined in dive/filetree/file_tree.go. Regular whiteouts use the .wh. prefix, while opaque whiteouts use .wh..wh... The AddPath method in dive/filetree/file_node.go checks for the double prefix first and returns nil to skip opaque markers entirely, whereas regular whiteouts are processed as deletion indicators.
Why does Dive ignore opaque whiteout files when building the file tree?
Opaque whiteouts (.wh..wh..opq) indicate that an entire directory has been replaced in the upper layer, meaning all contents from lower layers should be disregarded. Dive ignores these markers because the directory replacement is implicitly handled by the presence of the new directory contents; creating a node for the opaque marker itself would add unnecessary clutter to the tree visualization.
How do whiteout files affect Dive's efficiency scoring?
When calculating storage efficiency, Dive treats whiteout files as indicators of data removal. If a whiteout file represents a directory, the efficiency algorithm in dive/filetree/efficiency.go walks the previous layer's tree to sum the total size of all hidden children. This ensures the efficiency score accurately reflects the bytes freed by deletions, preventing removed data from being counted as wasted space in the final image analysis.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →