I’ve been working with CrashPlan Pro recently, seeding backups from my Macs to a 750 GB hard disk that will eventually live at a friend’s house and serve as our offsite backup. It all went well for a while, but all of a sudden, CrashPlan Pro on each of the Macs started complaining that the destination Mac was out of disk space. That made no sense, given that my 750 GB disk had over 580 GB of free space, and everything was still set correctly in the CrashPlan interface. Late in the day, I sent email to the CrashPlan folks asking what might be going on.
Before I heard back the next morning, however, Mac OS X warned me that my startup disk was almost out of space, so I fired up GrandPerspective to see where my disk space had gone. Mac OS X’s virtual memory can hog disk space, but there should have been at least 5 or 6 GB of free space. A few minutes with GrandPerspective, and I found my culprit, a folder in /Volumes.
Background and Explanation — The Volumes directory, which is normally hidden in Mac OS X, is the mount point for external disks. That means that when you attach a hard disk to a Mac, that hard disk appears as a disk alias in /Volumes, and the Finder shows it to you on the Desktop and/or in the sidebar, depending on your preferences.
My external 750 GB hard disk is called “Adam’s CrashPad” and when I looked in /Volumes, there was a normal folder with that name, to which CrashPlan had been happily backing up gigabytes of data. Although the disk appeared as “Adam’s CrashPad” in the Finder, in /Volumes it was called “Adam’s CrashPad 1”.
As I dug into the situation more, things became muddier. It turns out that the main way this kind of replacement can happen is if a disk is unmounted in such a way that applications using it aren’t made aware that it is no longer present, usually by powering it down, or removing a FireWire or USB cable without ejecting properly first. Certain applications then continue to write to the path where the disk had been, and the end result is a folder (and its embedded file structure) that matches what would have been on the disk, had it been present. (I never ejected my external disk improperly, so I still don’t know exactly what happened.)
Needless to say, applications should notice the disappearance of a disk, and Matthew Dornquast of Code42 Software said that they had spent nearly 100 hours trying to prevent CrashPlan from writing to a folder in /Volumes if the disk disappeared. However, I received reports of a wide variety of applications suffering from this problem, including the BitTorrent client Azureus, the Perforce version control system, Apple’s Xcode development environment, and Mac OS X itself. (This is speculation, but Unix applications and Java-based applications may suffer more than Cocoa-based applications because cross-platform developers are more likely to use generic code that happily creates subdirectories if the parent directory in /Volumes doesn’t exist; that way, the same code can work across different operating systems.)
Mac OS X can fall prey to this problem if you set your user’s home folder to live on an external disk (which might be your laptop in FireWire Target Disk Mode, a technique that lets you use the same data on a desktop Mac at work and on the laptop at home, for instance). If that external drive is unmounted improperly, which is easy to do if you’re leaving work in a hurry and grab your laptop without unmounting it from the desktop Mac, Mac OS X on the desktop Mac blithely recreates your home folder in /Volumes.
You might wonder why /Volumes is writable to user-level applications at all, and the answer seems to be that such permissions are necessary to allow anyone, even a restricted account, to insert removable media, which of course needs to be mounted in /Volumes. If /Volumes weren’t world-writable, user-level applications wouldn’t be able to create new folders there.
Delete and Reboot, For Now — Solving my particular problem was easy. I simply viewed /Volumes in the Finder by choosing Go to Folder from the Finder’s Go menu (Command-Shift-G), and then typing “/Volumes” in the dialog that appeared. Once I could see /Volumes, I trashed the “Adam’s CrashPad” folder, emptied the Trash to reclaim the necessary space, and rebooted quickly, before CrashPlan could recreate the folder in /Volumes. A similar process should work in other situations.
More generally, this is an architectural problem in Mac OS X that Apple needs to fix. Although applications bear some responsibility for creating folders in /Volumes when they shouldn’t, the operating system should protect itself from such an obvious misuse. Unfortunately, a vast amount of code, both from Apple and other developers, assumes that /Volumes is writable, which means that fixing the problem would require lots of other changes, and Apple hasn’t had the fortitude to force such an unpalatable solution on developers.
Until such time as Apple re-architects this aspect of Mac OS X, it will remain up to developers to work around the problem by avoiding coding techniques that happily create entire hierarchies of files and folders even if the parent volume is no longer present.