From ac15a31b43ee2ee181708f8d484d69cc2a5f1ada Mon Sep 17 00:00:00 2001 From: "Sean T. Allen" Date: Mon, 8 Feb 2021 12:47:08 -0500 Subject: [PATCH] Make directory creation deterministic Prior to this commit, the layout of created ext4 filesystems created using tar2ext4 wasn't deterministic. Recursive directory creation would change from run to run due to the usage of a map as temporary storage for items from the tar stream. This commit changes recursive directory creation to follow the same deterministic pattern as writeDirectory. At this point, the only possible source of non-determinism in a create file system is the UUID in the VHD footer. If no VHD footer is included, then the results are deterministic. --- ext4/internal/compactext4/compact.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ext4/internal/compactext4/compact.go b/ext4/internal/compactext4/compact.go index f2274fd4cf..57b265530d 100644 --- a/ext4/internal/compactext4/compact.go +++ b/ext4/internal/compactext4/compact.go @@ -945,7 +945,18 @@ func (w *Writer) writeDirectoryRecursive(dir, parent *inode) error { if err := w.writeDirectory(dir, parent); err != nil { return err } - for _, child := range dir.Children { + + // Follow e2fsck's convention and sort the children by inode number. + var children []string + for name := range dir.Children { + children = append(children, name) + } + sort.Slice(children, func(i, j int) bool { + return dir.Children[children[i]].Number < dir.Children[children[j]].Number + }) + + for _, name := range children { + child := dir.Children[name] if child.IsDir() { if err := w.writeDirectoryRecursive(child, dir); err != nil { return err