Skip to content

Don't truncate the archive at a mount point in tar --one-file-system - #458

Open
folbricht wants to merge 2 commits into
masterfrom
fix-tar-one-file-system-truncation
Open

folbricht wants to merge 2 commits into
masterfrom
fix-tar-one-file-system-truncation

Conversation

@folbricht

@folbricht folbricht commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

desync tar --one-file-system produces an incomplete archive when the tree contains a mount point with anything in it. Everything that sorts after the mount point is left out, and the command exits successfully.

With a tmpfs holding one file mounted on mnt:

tree/keep/a
tree/mnt/other-fs-file
tree/zfile
tree/zzz/b

the archive contains only keep/a. zfile and zzz/b are on the same filesystem as the root and are missing.

The walk function returned nil for a directory on another filesystem. That leaves the directory itself out, but filepath.Walk still descends into it. The files found there are passed on without their parent directory, and tar reads an entry that doesn't belong to the directory it is encoding, or any above it, as the end of the tree. It stops there with the rest of the walk unread. An empty mount point did not trigger this, as there was nothing below it to pass on.

The walk function now returns filepath.SkipDir, so nothing below the mount point is visited. The mount point directory itself stays out of the archive, as it did for an empty one.

The device lookup becomes a field of LocalFS, which the test replaces to simulate a tree across two filesystems, since mounting one needs privileges. The test reports the mount point and everything below it as being on another device and checks the entries the walk returns. The same result was confirmed with a real tmpfs mounted in a user namespace.

A directory on another filesystem was left out of the walk, but the walk
still descended into it. The entries it found there have no parent in
the stream of entries, which tar takes as the end of the tree. Anything
that came after the mount point was silently left out of the archive.

Skip the directory in the walk instead.
The lookup used to simulate another filesystem in the test is now a field
of the LocalFS being read rather than a package-level variable. The test
marks the mount point and everything below it as being on another device,
and checks the entries returned by Next().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant