We're using rsync to update the tables on our email relays, and very occasionally we get an error in the logs saying that a table has the wrong permissions. This is because of race conditions in finish_transfer() which mean that it does not update files atomically. This makes rsync not entirely safe to use in our situation, where the files being synced are frequently opened for short periods :-( The specific problems are: (1) The permissions on the file are fixed as the last operation. They should be fixed before the file is atomically renamed into place. I believe this is the one we are hitting, which occurs about once every few thousand runs. (2) If the rename fails because it is cross-device, it is copied into place before the permissions are fixed. This should only occur if the user has specified a temporary directory. It is probably worth noting in the documentation that atomic updates are not possible in this situation. Fixing rsync to update the file atomically may cause problems if the target filesystem is short on space, which is probably the reason for using the --temp-dir option in the first place. Tony. -- f.a.n.finch <dot@dotat.at> http://dotat.at/ BERWICK ON TWEED TO WHITBY: WEST OR SOUTHWEST 2 OR 3 INCREASING 3 OR 4. FAIR. GOOD. SLIGHT OR SMOOTH.
On Mon, Aug 09, 2004 at 12:12:16PM +0100, Tony Finch wrote:> This is because of race conditions in finish_transfer() which mean > that it does not update files atomically.There is a diff in the "patches" dir named early-chmod.diff that changes this behavior. It sets the permissions prior to the robust_rename() call, and the copy-when-rename-fails logic is extended to ensure that these final permissions on the temp file don't interfere with rsync's reading of the file for the copy. The only reason this patch hasn't already been applied is that I'm not 100% sure of the reasons that rsync was written to do the chmod() after the rename(). For instance, do we need to worry about some strange system that drops the setuid bits on rename()? Is there a (relevant) system that prevents the rename() if the file is read-only? (I seem to recall that MS DOS has this behavior, but cygwin probably hides it if it does.) Any comments on how portable it would be to apply the final permissions before calling rename()? ..wayne..