Let’s say you want to move a (relatively large) filesystem, with an application’s data files (including a lot of subdirectories, many of them with specific ACLs), to a faster disk (for instance). The old FS is mounted as /PROD, while the new disk is mounted as /NEW; the idea is to stop the application, rsync the data, and switch mount points. Easy, you think:
[pastacode lang=”bash” manual=”rsync%20-av%20%2FPROD%2F%20%2FNEW%2F” message=”” highlight=”” provider=”manual”/]
So, the application guys stop the app, you enter the command above, then switch mount points so the old /NEW is now /PROD, and the old /PROD is now /OLD . Everything looks fine, the application guys start their thing again…
… and then complain about access problems. Oops, the rsync didn’t copy the ACLs — you needed the -A argument to include them (e.g. rsync -aAv).
But they took a while to notice it, so that there’s a lot of new data in the new filesystem, so simply doing a new rsync from /OLD to /PROD is unacceptable. You’d simply like to copy directory ACLs (for simplification’s sake, let’s assume there are no file ACLs here — but see below). But there are a couple thousand directories, and of course you don’t want to do it manually…
The solution I came up with was:
[pastacode lang=”bash” manual=”cd%20%2FOLD%0Afind%20.%20-type%20d%20%7C%20cut%20-d%20′.’%20-f%202-%20%3E%20%2Ftmp%2Fdirectories.txt%0AIFS%3D%24’%5Cn’%20%3B%20for%20i%20in%20%60cat%20%2Ftmp%2Fdirectories.txt%60%3B%20do%20getfacl%20%22%2FOLD%24i%22%20%7C%20setfacl%20–set-file%3D-%20%22%2FPROD%24i%22%20%3B%20done” message=”” highlight=”” provider=”manual”/]
Basically, it stores a list of directories in /OLD , then, for each of them, it copies the ACL from /OLD/<directory> to /PROD/<directory> . setfacl’s “–set-file=-” means use the standard input as a “file”, which comes from getfacl‘s output. The “IFS=$’\n’” bit means that the for loop cycles through entire lines, not “words” — otherwise, it would try to split paths with spaces in them.
A limitation of this is that any newly created directories in the new /PROD filesystem won’t be affected, but hopefully they won’t be too many.
What if you wanted to include files as well? Just remove the “-type d” in the find command. Note that, in this case, it’s much more likely that there are new files in the new /PROD FS that won’t have their ACLs corrected.