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/
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.