diff -ur mongodb-src-r2.4.5.orig/src/mongo/db/pdfile.cpp mongodb-src-r2.4.5/src/mongo/db/pdfile.cpp --- mongodb-src-r2.4.5.orig/src/mongo/db/pdfile.cpp 2013-07-02 12:27:08.000000000 -0700 +++ mongodb-src-r2.4.5/src/mongo/db/pdfile.cpp 2013-08-06 18:03:24.000000000 -0700 @@ -216,10 +216,49 @@ void _applyOpToDataFiles( const char *database, FileOp &fo, bool afterAllocator = false, const string& path = dbpath ); + // dereferences the given symlink + // if it's a directory, removes all of the target directory's contents + void _deleteSymlinkDirectoryContents(boost::filesystem::path symlink) { + boost::filesystem::path targetDirectory = boost::filesystem::read_symlink( symlink ); + + if ( boost::filesystem::exists(targetDirectory) && + boost::filesystem::is_directory(targetDirectory) ) { + + typedef std::vector vec; + vec v; + + copy( + boost::filesystem::directory_iterator(targetDirectory), + boost::filesystem::directory_iterator(), + std::back_inserter(v) + ); + + for (vec::const_iterator it (v.begin()); it != v.end(); ++it) { + boost::filesystem::remove_all(*it); + } + } + } + void _deleteDataFiles(const char *database) { if ( directoryperdb ) { FileAllocator::get()->waitUntilFinished(); - MONGO_ASSERT_ON_EXCEPTION_WITH_MSG( boost::filesystem::remove_all( boost::filesystem::path( dbpath ) / database ), "delete data files with a directoryperdb" ); + + // target directory path + boost::filesystem::path targetDirectory = boost::filesystem::path( dbpath ) / database; + + // if the database "directory" is actually a symlink that points to a directory + // then remove the contents of the target directory without breaking the symlink + if ( boost::filesystem::exists(targetDirectory) && + boost::filesystem::is_symlink(targetDirectory) && + boost::filesystem::is_directory(targetDirectory) ) { + + MONGO_ASSERT_ON_EXCEPTION_WITH_MSG( _deleteSymlinkDirectoryContents( targetDirectory ),"delete data files with a directoryperdb symlink" ); + + // otherwise, delete the directory (or whatever it actually is) + } else { + MONGO_ASSERT_ON_EXCEPTION_WITH_MSG( boost::filesystem::remove_all( targetDirectory ), "delete data files with a directoryperdb" ); + } + return; } class : public FileOp {