|
MongoDB
2.0.3
|
00001 // @file paths.h 00002 // file paths and directory handling 00003 00004 /* Copyright 2010 10gen Inc. 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 00019 #pragma once 00020 00021 #include "mongoutils/str.h" 00022 #include <sys/types.h> 00023 #include <sys/stat.h> 00024 #include <fcntl.h> 00025 00026 namespace mongo { 00027 00028 using namespace mongoutils; 00029 00030 extern string dbpath; 00031 00035 struct RelativePath { 00036 string _p; 00037 00038 bool empty() const { return _p.empty(); } 00039 00040 static RelativePath fromRelativePath(string f) { 00041 RelativePath rp; 00042 rp._p = f; 00043 return rp; 00044 } 00045 00047 static RelativePath fromFullPath(path f) { 00048 path dbp(dbpath); // normalizes / and backslash 00049 string fullpath = f.string(); 00050 string relative = str::after(fullpath, dbp.string()); 00051 if( relative.empty() ) { 00052 log() << "warning file is not under db path? " << fullpath << ' ' << dbp.string() << endl; 00053 RelativePath rp; 00054 rp._p = fullpath; 00055 return rp; 00056 } 00057 /*uassert(13600, 00058 str::stream() << "file path is not under the db path? " << fullpath << ' ' << dbpath, 00059 relative != fullpath);*/ 00060 if( str::startsWith(relative, "/") || str::startsWith(relative, "\\") ) { 00061 relative.erase(0, 1); 00062 } 00063 RelativePath rp; 00064 rp._p = relative; 00065 return rp; 00066 } 00067 00068 string toString() const { return _p; } 00069 00070 bool operator!=(const RelativePath& r) const { return _p != r._p; } 00071 bool operator==(const RelativePath& r) const { return _p == r._p; } 00072 bool operator<(const RelativePath& r) const { return _p < r._p; } 00073 00074 string asFullPath() const { 00075 path x(dbpath); 00076 x /= _p; 00077 return x.string(); 00078 } 00079 00080 }; 00081 00082 inline dev_t getPartition(const string& path){ 00083 struct stat stats; 00084 00085 if (stat(path.c_str(), &stats) != 0){ 00086 uasserted(13646, str::stream() << "stat() failed for file: " << path << " " << errnoWithDescription()); 00087 } 00088 00089 return stats.st_dev; 00090 } 00091 00092 inline bool onSamePartition(const string& path1, const string& path2){ 00093 dev_t dev1 = getPartition(path1); 00094 dev_t dev2 = getPartition(path2); 00095 00096 return dev1 == dev2; 00097 } 00098 00099 inline void flushMyDirectory(const boost::filesystem::path& file){ 00100 #ifdef __linux__ // this isn't needed elsewhere 00101 massert(13652, str::stream() << "Couldn't find parent dir for file: " << file.string(), file.has_branch_path()); 00102 boost::filesystem::path dir = file.branch_path(); // parent_path in new boosts 00103 00104 log(1) << "flushing directory " << dir.string() << endl; 00105 00106 int fd = ::open(dir.string().c_str(), O_RDONLY); // DO NOT THROW OR ASSERT BEFORE CLOSING 00107 massert(13650, str::stream() << "Couldn't open directory '" << dir.string() << "' for flushing: " << errnoWithDescription(), fd >= 0); 00108 if (fsync(fd) != 0){ 00109 int e = errno; 00110 close(fd); 00111 massert(13651, str::stream() << "Couldn't fsync directory '" << dir.string() << "': " << errnoWithDescription(e), false); 00112 } 00113 close(fd); 00114 #endif 00115 } 00116 00117 }
1.8.0