The Turnstone's Bill

Fixing the Ghost File Problem

During my last round of beta testing with DropSync I got a bug report where error messages were being returned by rsync about non existent files. An example error (with filenames anonymised) was as follows;

Error: mkstemp "/Volumes/Folder/..afilename.mBhoxf" failed: No such file or directory (2)

After a bit of googling I came across this discussion thread in which the essence of the problem was laid bare. Basically, it was not a bug in rsync at all, but a bug from Apple. Under certain circumstances (drives mounted via a Time Capsule, or some other afp network shares) any attempt to create a file with two leading dots (ie “..”) would fail, eventually leading to the creation of a Ghost file. In addition to the fact that this would prevent rsync from working, these Ghost files are particularly annoying because they are tricky to delete.

Even though this was not an rsync bug, rsync is one of the few programs that will actually create files with a leading “..”. This is because it creates temporary files by prepending a dot to the name of its original file, and appending a hash. This means that any hidden files (with a single dot) will end up producing a double dot file at the destination by rsync.

I’ve filed a bug with apple rdar://9262177 but until the issue gets fixed, there is a fairly good workaround.

The workaround is to modify the way rsync creates temporary files so that is only prepends a dot if there isn’t already one. I’ve included an rsync binary with this fix in DropSync, but you’ll need to select it in the Advanced configuration tab.

To compile your own rsync with the workaround type the following commands in terminal; Download and unpack the rsync sources

1
2
    curl http://rsync.samba.org/ftp/rsync/src/rsync-3.0.8.tar.gz > rsync-3.0.8.tar.gz
    tar zxvf rsync-3.0.8.tar.gz

apply the patch

1
2
3
    curl http://www.mudflatsoftware.com/rsync/nodotdot.diff > nodotdot.diff
    cd rsync-3.0.8
    patch -p1 < ../nodotdot.diff

Build rsync

1
2
    ./configure
    make