Changeset 2631
- Timestamp:
- 22/02/2010 22:10:04 (2 years ago)
- Location:
- box/trunk/bin/bbackupd
- Files:
-
- 3 edited
-
BackupClientInodeToIDMap.cpp (modified) (12 diffs)
-
BackupClientInodeToIDMap.h (modified) (3 diffs)
-
BackupDaemon.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/bin/bbackupd/BackupClientInodeToIDMap.cpp
r2314 r2631 10 10 #include "Box.h" 11 11 12 #ifdef HAVE_DB 13 // Include db headers and other OS files if they're needed for the disc implementation 14 #include <sys/types.h> 15 #include <fcntl.h> 16 #include <limits.h> 17 #include <db.h> 18 #include <sys/stat.h> 19 #endif 12 #include <stdlib.h> 13 #include <depot.h> 20 14 21 15 #define BACKIPCLIENTINODETOIDMAP_IMPLEMENTATION 22 16 #include "BackupClientInodeToIDMap.h" 17 #undef BACKIPCLIENTINODETOIDMAP_IMPLEMENTATION 23 18 24 19 #include "BackupStoreException.h" 25 20 26 27 21 #include "MemLeakFindOn.h" 28 29 // What type of Berkeley DB shall we use?30 #define TABLE_DATABASE_TYPE DB_HASH31 22 32 23 typedef struct … … 36 27 } IDBRecord; 37 28 29 #define BOX_DBM_MESSAGE(stuff) stuff << " (qdbm): " << dperrmsg(dpecode) 30 31 #define BOX_LOG_DBM_ERROR(stuff) \ 32 BOX_ERROR(BOX_DBM_MESSAGE(stuff)) 33 34 #define THROW_DBM_ERROR(message, filename, exception, subtype) \ 35 BOX_LOG_DBM_ERROR(message << ": " << filename); \ 36 THROW_EXCEPTION_MESSAGE(exception, subtype, \ 37 BOX_DBM_MESSAGE(message << ": " << filename)); 38 39 #define ASSERT_DBM_OK(operation, message, filename, exception, subtype) \ 40 if(!(operation)) \ 41 { \ 42 THROW_DBM_ERROR(message, filename, exception, subtype); \ 43 } 44 45 #define ASSERT_DBM_OPEN() \ 46 if(mpDepot == 0) \ 47 { \ 48 THROW_EXCEPTION_MESSAGE(BackupStoreException, InodeMapNotOpen, \ 49 "Inode database not open"); \ 50 } 51 52 #define ASSERT_DBM_CLOSED() \ 53 if(mpDepot != 0) \ 54 { \ 55 THROW_EXCEPTION_MESSAGE(CommonException, Internal, \ 56 "Inode database already open: " << mFilename); \ 57 } 58 38 59 // -------------------------------------------------------------------------- 39 60 // … … 45 66 // -------------------------------------------------------------------------- 46 67 BackupClientInodeToIDMap::BackupClientInodeToIDMap() 47 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION48 68 : mReadOnly(true), 49 69 mEmpty(false), 50 dbp(0) 51 #endif 70 mpDepot(0) 52 71 { 53 72 } … … 63 82 BackupClientInodeToIDMap::~BackupClientInodeToIDMap() 64 83 { 65 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION 66 if(dbp != 0) 67 { 68 #if BDB_VERSION_MAJOR >= 3 69 dbp->close(0); 70 #else 71 dbp->close(dbp); 72 #endif 73 } 74 #endif 75 } 76 84 if(mpDepot != 0) 85 { 86 Close(); 87 } 88 } 77 89 78 90 // -------------------------------------------------------------------------- … … 84 96 // 85 97 // -------------------------------------------------------------------------- 86 void BackupClientInodeToIDMap::Open(const char *Filename, bool ReadOnly, bool CreateNew) 87 { 88 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION 98 void BackupClientInodeToIDMap::Open(const char *Filename, bool ReadOnly, 99 bool CreateNew) 100 { 101 mFilename = Filename; 102 89 103 // Correct arguments? 90 104 ASSERT(!(CreateNew && ReadOnly)); 91 105 92 106 // Correct usage? 93 ASSERT (dbp == 0);107 ASSERT_DBM_CLOSED(); 94 108 ASSERT(!mEmpty); 95 109 96 110 // Open the database file 97 #if BDB_VERSION_MAJOR >= 3 98 dbp = new Db(0,0); 99 dbp->set_pagesize(1024); /* Page size: 1K. */ 100 dbp->set_cachesize(0, 32 * 1024, 0); 101 dbp->open(NULL, Filename, NULL, DB_HASH, DB_CREATE, 0664); 102 #else 103 dbp = dbopen(Filename, (CreateNew?O_CREAT:0) | (ReadOnly?O_RDONLY:O_RDWR), S_IRUSR | S_IWUSR | S_IRGRP, TABLE_DATABASE_TYPE, NULL); 104 #endif 105 if(dbp == NULL) 106 { 107 THROW_EXCEPTION(BackupStoreException, BerkelyDBFailure); 108 } 111 int mode = ReadOnly ? DP_OREADER : DP_OWRITER; 112 if(CreateNew) 113 { 114 mode |= DP_OCREAT; 115 } 116 117 mpDepot = dpopen(Filename, mode, 0); 118 119 ASSERT_DBM_OK(mpDepot, "Failed to open inode database", mFilename, 120 BackupStoreException, BerkelyDBFailure); 109 121 110 122 // Read only flag 111 123 mReadOnly = ReadOnly; 112 #endif113 124 } 114 125 … … 117 128 // Function 118 129 // Name: BackupClientInodeToIDMap::OpenEmpty() 119 // Purpose: 'Open' this map. Not associated with a disc file. Useful for when a map 120 // is required, but is against an empty file on disc which shouldn't be created. 121 // Implies read only. 130 // Purpose: 'Open' this map. Not associated with a disc file. 131 // Useful for when a map is required, but is against 132 // an empty file on disc which shouldn't be created. 133 // Implies read only. 122 134 // Created: 20/11/03 123 135 // … … 125 137 void BackupClientInodeToIDMap::OpenEmpty() 126 138 { 127 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION 128 ASSERT( dbp== 0);139 ASSERT_DBM_CLOSED(); 140 ASSERT(mpDepot == 0); 129 141 mEmpty = true; 130 142 mReadOnly = true; 131 #endif 132 } 133 134 143 } 135 144 136 145 // -------------------------------------------------------------------------- … … 144 153 void BackupClientInodeToIDMap::Close() 145 154 { 146 #ifndef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION 147 if(dbp != 0) 148 { 149 #if BDB_VERSION_MAJOR >= 3 150 if(dbp->close(0) != 0) 151 #else 152 if(dbp->close(dbp) != 0) 153 #endif 154 { 155 THROW_EXCEPTION(BackupStoreException, BerkelyDBFailure); 156 } 157 dbp = 0; 158 } 159 #endif 160 } 161 162 163 // -------------------------------------------------------------------------- 164 // 165 // Function 166 // Name: BackupClientInodeToIDMap::AddToMap(InodeRefType, int64_t, int64_t) 167 // Purpose: Adds an entry to the map. Overwrites any existing entry. 168 // Created: 11/11/03 169 // 170 // -------------------------------------------------------------------------- 171 void BackupClientInodeToIDMap::AddToMap(InodeRefType InodeRef, int64_t ObjectID, int64_t InDirectory) 172 { 173 #ifdef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION 174 mMap[InodeRef] = std::pair<int64_t, int64_t>(ObjectID, InDirectory); 175 #else 155 ASSERT_DBM_OPEN(); 156 ASSERT_DBM_OK(dpclose(mpDepot), "Failed to close inode database", 157 mFilename, BackupStoreException, BerkelyDBFailure); 158 mpDepot = 0; 159 } 160 161 // -------------------------------------------------------------------------- 162 // 163 // Function 164 // Name: BackupClientInodeToIDMap::AddToMap(InodeRefType, 165 // int64_t, int64_t) 166 // Purpose: Adds an entry to the map. Overwrites any existing 167 // entry. 168 // Created: 11/11/03 169 // 170 // -------------------------------------------------------------------------- 171 void BackupClientInodeToIDMap::AddToMap(InodeRefType InodeRef, int64_t ObjectID, 172 int64_t InDirectory) 173 { 176 174 if(mReadOnly) 177 175 { … … 179 177 } 180 178 181 if( dbp== 0)179 if(mpDepot == 0) 182 180 { 183 181 THROW_EXCEPTION(BackupStoreException, InodeMapNotOpen); 184 182 } 183 184 ASSERT_DBM_OPEN(); 185 185 186 186 // Setup structures … … 189 189 rec.mInDirectory = InDirectory; 190 190 191 #if BDB_VERSION_MAJOR >= 3 192 Dbt key(&InodeRef, sizeof(InodeRef)); 193 Dbt data(&rec, sizeof(rec)); 194 195 if (dbp->put(0, &key, &data, 0) != 0) { 196 THROW_EXCEPTION(BackupStoreException, BerkelyDBFailure); 197 } 198 #else 199 200 DBT key; 201 key.data = &InodeRef; 202 key.size = sizeof(InodeRef); 203 204 DBT data; 205 data.data = &rec; 206 data.size = sizeof(rec); 207 208 // Add to map (or replace existing entry) 209 if(dbp->put(dbp, &key, &data, 0) != 0) 210 { 211 THROW_EXCEPTION(BackupStoreException, BerkelyDBFailure); 212 } 213 #endif 214 #endif 191 ASSERT_DBM_OK(dpput(mpDepot, (const char *)&InodeRef, sizeof(InodeRef), 192 (const char *)&rec, sizeof(rec), DP_DOVER), 193 "Failed to add record to inode database", mFilename, 194 BackupStoreException, BerkelyDBFailure); 215 195 } 216 196 … … 229 209 int64_t &rObjectIDOut, int64_t &rInDirectoryOut) const 230 210 { 231 #ifdef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION232 std::map<InodeRefType, std::pair<int64_t, int64_t> >::const_iterator i(mMap.find(InodeRef));233 234 // Found?235 if(i == mMap.end())236 {237 return false;238 }239 240 // Yes. Return the details241 rObjectIDOut = i->second.first;242 rInDirectoryOut = i->second.second;243 return true;244 #else245 211 if(mEmpty) 246 212 { … … 249 215 } 250 216 251 if( dbp== 0)217 if(mpDepot == 0) 252 218 { 253 219 THROW_EXCEPTION(BackupStoreException, InodeMapNotOpen); 254 220 } 255 256 #if BDB_VERSION_MAJOR >= 3 257 Dbt key(&InodeRef, sizeof(InodeRef)); 258 Dbt data(0, 0); 259 switch(dbp->get(NULL, &key, &data, 0)) 260 #else 261 DBT key; 262 key.data = &InodeRef; 263 key.size = sizeof(InodeRef); 264 265 DBT data; 266 data.data = 0; 267 data.size = 0; 268 269 switch(dbp->get(dbp, &key, &data, 0)) 270 #endif 271 272 { 273 case 1: // key not in file 221 222 ASSERT_DBM_OPEN(); 223 224 IDBRecord rec; 225 226 if(dpgetwb(mpDepot, (const char *)&InodeRef, sizeof(InodeRef), 227 0, sizeof(IDBRecord), (char *)&rec) == -1) 228 { 229 // key not in file 274 230 return false; 275 276 case -1: // error 277 default: // not specified in docs 278 THROW_EXCEPTION(BackupStoreException, BerkelyDBFailure); 279 return false; 280 281 case 0: // success, found it 282 break; 283 } 284 285 // Check for sensible return 286 #if BDB_VERSION_MAJOR >= 3 287 if(key.get_data() == 0 || data.get_size() != sizeof(IDBRecord)) 288 { 289 // Assert in debug version 290 ASSERT(key.get_data() == 0 || data.get_size() != sizeof(IDBRecord)); 231 } 291 232 292 // Invalid entries mean it wasn't found293 return false;294 }295 296 // Data alignment isn't guaranteed to be on a suitable boundary297 IDBRecord rec;298 299 ::memcpy(&rec, data.get_data(), sizeof(rec));300 #else301 if(key.data == 0 || data.size != sizeof(IDBRecord))302 {303 // Assert in debug version304 ASSERT(key.data == 0 || data.size != sizeof(IDBRecord));305 306 // Invalid entries mean it wasn't found307 return false;308 }309 310 // Data alignment isn't guaranteed to be on a suitable boundary311 IDBRecord rec;312 313 ::memcpy(&rec, data.data, sizeof(rec));314 #endif315 316 233 // Return data 317 234 rObjectIDOut = rec.mObjectID; 318 235 rInDirectoryOut = rec.mInDirectory; 319 236 320 // Don't have to worry about freeing the returned data321 322 237 // Found 323 238 return true; 324 #endif 325 } 326 327 239 } -
box/trunk/bin/bbackupd/BackupClientInodeToIDMap.h
r217 r2631 9 9 10 10 #ifndef BACKUPCLIENTINODETOIDMAP_H 11 #define BACKUPCLIENTINODETOIDMAP_ _H11 #define BACKUPCLIENTINODETOIDMAP_H 12 12 13 13 #include <sys/types.h> … … 16 16 #include <utility> 17 17 18 // Use in memory implementation if there isn't access to the Berkely DB on this platform19 #ifndef HAVE_DB20 #define BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION21 #endif22 23 18 // avoid having to include the DB files when not necessary 24 19 #ifndef BACKIPCLIENTINODETOIDMAP_IMPLEMENTATION 25 #ifdef BERKELY_V4 26 class Db; 27 #else 28 class DB; 29 #endif 20 class DEPOT; 30 21 #endif 31 22 … … 56 47 57 48 private: 58 #ifdef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION59 std::map<InodeRefType, std::pair<int64_t, int64_t> > mMap;60 #else61 49 bool mReadOnly; 62 50 bool mEmpty; 63 #ifdef BERKELY_V4 64 Db *dbp; // c++ style implimentation 65 #else 66 DB *dbp; // C style interface, use notation from documentation 67 #endif // BERKELY_V4 68 #endif // BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION 51 std::string mFilename; 52 DEPOT *mpDepot; 69 53 }; 70 54 71 #endif // BACKUPCLIENTINODETOIDMAP_ _H55 #endif // BACKUPCLIENTINODETOIDMAP_H 72 56 73 57 -
box/trunk/bin/bbackupd/BackupDaemon.cpp
r2597 r2631 1785 1785 void BackupDaemon::SetupIDMapsForSync() 1786 1786 { 1787 // Need to do different things depending on whether it's an1788 // in memory implementation, or whether it's all stored on disc.1789 1790 #ifdef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION1791 1792 // Make sure we have some blank, empty ID maps1793 DeleteIDMapVector(mNewIDMaps);1794 FillIDMapVector(mNewIDMaps, true /* new maps */);1795 1796 // Then make sure that the current maps have objects,1797 // even if they are empty (for the very first run)1798 if(mCurrentIDMaps.empty())1799 {1800 FillIDMapVector(mCurrentIDMaps, false /* current maps */);1801 }1802 1803 #else1804 1805 1787 // Make sure we have some blank, empty ID maps 1806 1788 DeleteIDMapVector(mNewIDMaps); … … 1808 1790 DeleteIDMapVector(mCurrentIDMaps); 1809 1791 FillIDMapVector(mCurrentIDMaps, false /* new maps */); 1810 1811 #endif1812 1792 } 1813 1793 … … 1936 1916 void BackupDaemon::CommitIDMapsAfterSync() 1937 1917 { 1938 // Need to do different things depending on whether it's an in memory implementation,1939 // or whether it's all stored on disc.1940 1941 #ifdef BACKIPCLIENTINODETOIDMAP_IN_MEMORY_IMPLEMENTATION1942 // Remove the current ID maps1943 DeleteIDMapVector(mCurrentIDMaps);1944 1945 // Copy the (pointers to) "new" maps over to be the new "current" maps1946 mCurrentIDMaps = mNewIDMaps;1947 1948 // Clear the new ID maps vector (not delete them!)1949 mNewIDMaps.clear();1950 1951 #else1952 1953 1918 // Get rid of the maps in memory (leaving them on disc of course) 1954 1919 DeleteIDMapVector(mCurrentIDMaps); … … 1974 1939 } 1975 1940 } 1976 1977 #endif1978 1941 } 1979 1942 … … 1997 1960 1998 1961 // Close and delete 1999 toDel->Close(); 2000 delete toDel; 1962 win32 rename delete toDel; 2001 1963 } 2002 1964 ASSERT(rVector.size() == 0);
Note: See TracChangeset
for help on using the changeset viewer.
