field noteLinux · rsync · Permissions

Merging files back from under a mountpoint

Files written while a disk was missing end up hidden underneath it. Getting them back is easy; doing it as root without breaking ownership takes the right rsync flags.

After the empty mountpoint trap, about 1,800 files had been written to the system disk while the shared drive was missing. Most were already on the drive. Several hundred were not, and the drive had carefully set-up group ownership and ACLs that scheduled jobs depended on.

See what's underneath

Stop everything that writes to the share first. Then the folder underneath the mount can be reached without unmounting, through a bind mount of the root filesystem:

v=$(sudo mktemp -d /mnt/rootview.XXXX)
sudo mount --bind / "$v"
ls "$v/srv/share"            # what is hidden under the mount
sudo umount "$v" && sudo rmdir "$v"

Move it aside, then merge

I renamed the stray copy instead of deleting it, mounted the drive on a fresh empty folder, and ran a dry run first. The real run only added files that didn't exist yet: about 700 files copied, none in conflict.

rsync -rltH --omit-dir-times --ignore-existing --itemize-changes \
  /srv/share.stray/ /srv/share/
--ignore-existing never overwrites what's on the drive; --itemize-changes logs every file it touches.

Why not rsync -a

-a includes owner, group and permissions, and applies them to folders that already exist on the destination too. Run as root, it would have rewritten the drive's folders to match the stray copy, root-owned with the wrong mode, and broken the jobs that write there. -rlt copies the files and their times and leaves existing folders alone.

The copied files still came out root-owned, so I fixed only those: owner and group copied from each file's parent folder, then group write added so the ACL mask matched the files around them.

What I took from it

  • -a means preserve everything, including things you don't want on the destination.
  • Move the old copy aside, dry-run, then merge with --ignore-existing. Delete the leftovers only once you're happy.