Changeset 2181
- Timestamp:
- 28/05/2008 15:24:05 (2 years ago)
- Location:
- box/trunk/bin/bbackupd
- Files:
-
- 8 modified
-
BackupClientContext.cpp (modified) (2 diffs)
-
BackupClientContext.h (modified) (5 diffs)
-
BackupClientDeleteList.cpp (modified) (8 diffs)
-
BackupClientDeleteList.h (modified) (1 diff)
-
BackupClientDirectoryRecord.cpp (modified) (63 diffs)
-
BackupClientDirectoryRecord.h (modified) (5 diffs)
-
BackupDaemon.cpp (modified) (24 diffs)
-
BackupDaemon.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/bin/bbackupd/BackupClientContext.cpp
r2127 r2181 49 49 bool ExtendedLogging, 50 50 bool ExtendedLogToFile, 51 std::string ExtendedLogFile 51 std::string ExtendedLogFile, 52 ProgressNotifier& rProgressNotifier 52 53 ) 53 54 : mrDaemon(rDaemon), … … 70 71 mpExcludeDirs(0), 71 72 mKeepAliveTimer(0), 72 mbIsManaged(false) 73 mbIsManaged(false), 74 mrProgressNotifier(rProgressNotifier) 73 75 { 74 76 } -
box/trunk/bin/bbackupd/BackupClientContext.h
r2127 r2181 13 13 #include "BoxTime.h" 14 14 #include "BackupClientDeleteList.h" 15 #include "BackupClientDirectoryRecord.h" 15 16 #include "BackupStoreFile.h" 16 17 #include "ExcludeList.h" … … 46 47 bool ExtendedLogging, 47 48 bool ExtendedLogToFile, 48 std::string ExtendedLogFile 49 std::string ExtendedLogFile, 50 ProgressNotifier &rProgressNotifier 49 51 ); 50 52 virtual ~BackupClientContext(); … … 71 73 72 74 bool StorageLimitExceeded() {return mStorageLimitExceeded;} 75 void SetStorageLimitExceeded() {mStorageLimitExceeded = true;} 73 76 74 77 // -------------------------------------------------------------------------- … … 199 202 virtual bool IsManaged() { return mbIsManaged; } 200 203 204 ProgressNotifier& GetProgressNotifier() const 205 { 206 return mrProgressNotifier; 207 } 208 201 209 private: 202 210 BackupDaemon &mrDaemon; … … 222 230 int mKeepAliveTime; 223 231 int mMaximumDiffingTime; 232 ProgressNotifier &mrProgressNotifier; 224 233 }; 225 234 -
box/trunk/bin/bbackupd/BackupClientDeleteList.cpp
r217 r2181 43 43 } 44 44 45 // -------------------------------------------------------------------------- 46 // 47 // Function 48 // Name: BackupClientDeleteList::AddDirectoryDelete(int64_t) 45 BackupClientDeleteList::FileToDelete::FileToDelete(int64_t DirectoryID, 46 const BackupStoreFilename& rFilename, 47 const std::string& rLocalPath) 48 : mDirectoryID(DirectoryID), 49 mFilename(rFilename), 50 mLocalPath(rLocalPath) 51 { } 52 53 BackupClientDeleteList::DirToDelete::DirToDelete(int64_t ObjectID, 54 const std::string& rLocalPath) 55 : mObjectID(ObjectID), 56 mLocalPath(rLocalPath) 57 { } 58 59 // -------------------------------------------------------------------------- 60 // 61 // Function 62 // Name: BackupClientDeleteList::AddDirectoryDelete(int64_t, 63 // const BackupStoreFilename&) 49 64 // Purpose: Add a directory to the list of directories to be deleted. 50 65 // Created: 10/11/03 51 66 // 52 67 // -------------------------------------------------------------------------- 53 void BackupClientDeleteList::AddDirectoryDelete(int64_t ObjectID) 68 void BackupClientDeleteList::AddDirectoryDelete(int64_t ObjectID, 69 const std::string& rLocalPath) 54 70 { 55 71 // Only add the delete to the list if it's not in the "no delete" set 56 if(mDirectoryNoDeleteList.find(ObjectID) == mDirectoryNoDeleteList.end()) 72 if(mDirectoryNoDeleteList.find(ObjectID) == 73 mDirectoryNoDeleteList.end()) 57 74 { 58 75 // Not in the list, so should delete it 59 mDirectoryList.push_back(ObjectID); 60 } 61 } 62 63 64 // -------------------------------------------------------------------------- 65 // 66 // Function 67 // Name: BackupClientDeleteList::AddFileDelete(int64_t, BackupStoreFilenameClear &) 76 mDirectoryList.push_back(DirToDelete(ObjectID, rLocalPath)); 77 } 78 } 79 80 81 // -------------------------------------------------------------------------- 82 // 83 // Function 84 // Name: BackupClientDeleteList::AddFileDelete(int64_t, 85 // const BackupStoreFilename &) 68 86 // Purpose: 69 87 // Created: 10/11/03 70 88 // 71 89 // -------------------------------------------------------------------------- 72 void BackupClientDeleteList::AddFileDelete(int64_t DirectoryID, const BackupStoreFilename &rFilename) 90 void BackupClientDeleteList::AddFileDelete(int64_t DirectoryID, 91 const BackupStoreFilename &rFilename, const std::string& rLocalPath) 73 92 { 74 93 // Try to find it in the no delete list 75 std::vector<std::pair<int64_t, BackupStoreFilename> >::iterator delEntry(mFileNoDeleteList.begin()); 94 std::vector<std::pair<int64_t, BackupStoreFilename> >::iterator 95 delEntry(mFileNoDeleteList.begin()); 76 96 while(delEntry != mFileNoDeleteList.end()) 77 97 { 78 if((delEntry)->first == DirectoryID && (delEntry)->second == rFilename) 98 if((delEntry)->first == DirectoryID 99 && (delEntry)->second == rFilename) 79 100 { 80 101 // Found! … … 87 108 if(delEntry == mFileNoDeleteList.end()) 88 109 { 89 mFileList.push_back(std::pair<int64_t, BackupStoreFilename>(DirectoryID, rFilename)); 110 mFileList.push_back(FileToDelete(DirectoryID, rFilename, 111 rLocalPath)); 90 112 } 91 113 } … … 114 136 115 137 // Do the deletes 116 for(std::vector<int64_t>::iterator i(mDirectoryList.begin()); i != mDirectoryList.end(); ++i) 117 { 118 connection.QueryDeleteDirectory(*i); 138 for(std::vector<DirToDelete>::iterator i(mDirectoryList.begin()); 139 i != mDirectoryList.end(); ++i) 140 { 141 connection.QueryDeleteDirectory(i->mObjectID); 142 rContext.GetProgressNotifier().NotifyDirectoryDeleted( 143 i->mObjectID, i->mLocalPath); 119 144 } 120 145 … … 123 148 124 149 // Delete the files 125 for(std::vector<std::pair<int64_t, BackupStoreFilename> >::iterator i(mFileList.begin()); i != mFileList.end(); ++i) 126 { 127 connection.QueryDeleteFile(i->first, i->second); 150 for(std::vector<FileToDelete>::iterator i(mFileList.begin()); 151 i != mFileList.end(); ++i) 152 { 153 connection.QueryDeleteFile(i->mDirectoryID, i->mFilename); 154 rContext.GetProgressNotifier().NotifyFileDeleted( 155 i->mDirectoryID, i->mLocalPath); 128 156 } 129 157 } … … 141 169 { 142 170 // First of all, is it in the delete vector? 143 std::vector<int64_t>::iterator delEntry(std::find(mDirectoryList.begin(), mDirectoryList.end(), ObjectID)); 171 std::vector<DirToDelete>::iterator delEntry(mDirectoryList.begin()); 172 for(; delEntry != mDirectoryList.end(); delEntry++) 173 { 174 if(delEntry->mObjectID == ObjectID) 175 { 176 // Found! 177 break; 178 } 179 } 144 180 if(delEntry != mDirectoryList.end()) 145 181 { … … 149 185 else 150 186 { 151 // Haven't been asked to delete it yet, put it in the no delete list 187 // Haven't been asked to delete it yet, put it in the 188 // no delete list 152 189 mDirectoryNoDeleteList.insert(ObjectID); 153 190 } … … 163 200 // 164 201 // -------------------------------------------------------------------------- 165 void BackupClientDeleteList::StopFileDeletion(int64_t DirectoryID, const BackupStoreFilename &rFilename) 202 void BackupClientDeleteList::StopFileDeletion(int64_t DirectoryID, 203 const BackupStoreFilename &rFilename) 166 204 { 167 205 // Find this in the delete list 168 std::vector< std::pair<int64_t, BackupStoreFilename>>::iterator delEntry(mFileList.begin());206 std::vector<FileToDelete>::iterator delEntry(mFileList.begin()); 169 207 while(delEntry != mFileList.end()) 170 208 { 171 if((delEntry)->first == DirectoryID && (delEntry)->second == rFilename) 209 if(delEntry->mDirectoryID == DirectoryID 210 && delEntry->mFilename == rFilename) 172 211 { 173 212 // Found! … … 187 226 mFileNoDeleteList.push_back(std::pair<int64_t, BackupStoreFilename>(DirectoryID, rFilename)); 188 227 } 189 190 } 191 192 193 194 195 228 } 229 -
box/trunk/bin/bbackupd/BackupClientDeleteList.h
r217 r2181 29 29 class BackupClientDeleteList 30 30 { 31 private: 32 class FileToDelete 33 { 34 public: 35 int64_t mDirectoryID; 36 BackupStoreFilename mFilename; 37 std::string mLocalPath; 38 FileToDelete(int64_t DirectoryID, 39 const BackupStoreFilename& rFilename, 40 const std::string& rLocalPath); 41 }; 42 43 class DirToDelete 44 { 45 public: 46 int64_t mObjectID; 47 std::string mLocalPath; 48 DirToDelete(int64_t ObjectID, const std::string& rLocalPath); 49 }; 50 31 51 public: 32 52 BackupClientDeleteList(); 33 53 ~BackupClientDeleteList(); 34 54 35 void AddDirectoryDelete(int64_t ObjectID); 36 void AddFileDelete(int64_t DirectoryID, const BackupStoreFilename &rFilename); 55 void AddDirectoryDelete(int64_t ObjectID, 56 const std::string& rLocalPath); 57 void AddFileDelete(int64_t DirectoryID, 58 const BackupStoreFilename &rFilename, 59 const std::string& rLocalPath); 37 60 38 61 void StopDirectoryDeletion(int64_t ObjectID); 39 void StopFileDeletion(int64_t DirectoryID, const BackupStoreFilename &rFilename); 62 void StopFileDeletion(int64_t DirectoryID, 63 const BackupStoreFilename &rFilename); 40 64 41 65 void PerformDeletions(BackupClientContext &rContext); 42 66 43 67 private: 44 std::vector< int64_t> mDirectoryList;68 std::vector<DirToDelete> mDirectoryList; 45 69 std::set<int64_t> mDirectoryNoDeleteList; // note: things only get in this list if they're not present in mDirectoryList when they are 'added' 46 std::vector< std::pair<int64_t, BackupStoreFilename>> mFileList;70 std::vector<FileToDelete> mFileList; 47 71 std::vector<std::pair<int64_t, BackupStoreFilename> > mFileNoDeleteList; 48 72 }; -
box/trunk/bin/bbackupd/BackupClientDirectoryRecord.cpp
r2143 r2181 3 3 // File 4 4 // Name: BackupClientDirectoryRecord.cpp 5 // Purpose: Implementation of record about directory for backup client 5 // Purpose: Implementation of record about directory for 6 // backup client 6 7 // Created: 2003/10/08 7 8 // … … 101 102 // 102 103 // Function 103 // Name: BackupClientDirectoryRecord::SyncDirectory(BackupClientDirectoryRecord::SyncParams &, int64_t, const std::string &, bool) 104 // Purpose: Syncronise, recusively, a local directory with the server. 104 // Name: BackupClientDirectoryRecord::SyncDirectory(i 105 // BackupClientDirectoryRecord::SyncParams &, 106 // int64_t, const std::string &, 107 // const std::string &, bool) 108 // Purpose: Recursively synchronise a local directory 109 // with the server. 105 110 // Created: 2003/10/08 106 111 // 107 112 // -------------------------------------------------------------------------- 108 void BackupClientDirectoryRecord::SyncDirectory(BackupClientDirectoryRecord::SyncParams &rParams, int64_t ContainingDirectoryID, 109 const std::string &rLocalPath, bool ThisDirHasJustBeenCreated) 113 void BackupClientDirectoryRecord::SyncDirectory( 114 BackupClientDirectoryRecord::SyncParams &rParams, 115 int64_t ContainingDirectoryID, 116 const std::string &rLocalPath, 117 const std::string &rRemotePath, 118 bool ThisDirHasJustBeenCreated) 110 119 { 120 BackupClientContext& rContext(rParams.mrContext); 121 ProgressNotifier& rNotifier(rContext.GetProgressNotifier()); 122 111 123 // Signal received by daemon? 112 124 if(rParams.mrDaemon.StopRun()) … … 119 131 // and on the immediate sub directories. 120 132 mSyncDone = false; 121 for(std::map<std::string, BackupClientDirectoryRecord *>::iterator i = mSubDirectories.begin(); 133 for(std::map<std::string, BackupClientDirectoryRecord *>::iterator 134 i = mSubDirectories.begin(); 122 135 i != mSubDirectories.end(); ++i) 123 136 { … … 125 138 } 126 139 127 // Work out the time in the future after which the file should be uploaded regardless. 128 // This is a simple way to avoid having too many problems with file servers when they have 129 // clients with badly out of sync clocks. 130 rParams.mUploadAfterThisTimeInTheFuture = GetCurrentBoxTime() + rParams.mMaxFileTimeInFuture; 131 132 // Build the current state checksum to compare against while getting info from dirs 133 // Note checksum is used locally only, so byte order isn't considered. 140 // Work out the time in the future after which the file should 141 // be uploaded regardless. This is a simple way to avoid having 142 // too many problems with file servers when they have clients 143 // with badly out of sync clocks. 144 rParams.mUploadAfterThisTimeInTheFuture = GetCurrentBoxTime() + 145 rParams.mMaxFileTimeInFuture; 146 147 // Build the current state checksum to compare against while 148 // getting info from dirs. Note checksum is used locally only, 149 // so byte order isn't considered. 134 150 MD5Digest currentStateChecksum; 135 151 152 struct stat dest_st; 136 153 // Stat the directory, to get attribute info 137 { 138 struct stat st; 139 if(::stat(rLocalPath.c_str(), &st) != 0) 140 { 141 // The directory has probably been deleted, so just ignore this error. 142 // In a future scan, this deletion will be noticed, deleted from server, and this object deleted. 143 rParams.GetProgressNotifier().NotifyDirStatFailed( 144 this, rLocalPath, strerror(errno)); 154 // If it's a symbolic link, we want the link target here 155 // (as we're about to back up the contents of the directory) 156 { 157 if(::stat(rLocalPath.c_str(), &dest_st) != 0) 158 { 159 // The directory has probably been deleted, so 160 // just ignore this error. In a future scan, this 161 // deletion will be noticed, deleted from server, 162 // and this object deleted. 163 rNotifier.NotifyDirStatFailed(this, rLocalPath, 164 strerror(errno)); 145 165 return; 146 166 } 147 // Store inode number in map so directories are tracked in case they're renamed 148 { 149 BackupClientInodeToIDMap &idMap(rParams.mrContext.GetNewIDMap()); 150 idMap.AddToMap(st.st_ino, mObjectID, ContainingDirectoryID); 167 // Store inode number in map so directories are tracked 168 // in case they're renamed 169 { 170 BackupClientInodeToIDMap &idMap( 171 rParams.mrContext.GetNewIDMap()); 172 idMap.AddToMap(dest_st.st_ino, mObjectID, 173 ContainingDirectoryID); 151 174 } 152 175 // Add attributes to checksum 153 currentStateChecksum.Add(&st.st_mode, sizeof(st.st_mode)); 154 currentStateChecksum.Add(&st.st_uid, sizeof(st.st_uid)); 155 currentStateChecksum.Add(&st.st_gid, sizeof(st.st_gid)); 176 currentStateChecksum.Add(&dest_st.st_mode, 177 sizeof(dest_st.st_mode)); 178 currentStateChecksum.Add(&dest_st.st_uid, 179 sizeof(dest_st.st_uid)); 180 currentStateChecksum.Add(&dest_st.st_gid, 181 sizeof(dest_st.st_gid)); 156 182 // Inode to be paranoid about things moving around 157 currentStateChecksum.Add(&st.st_ino, sizeof(st.st_ino)); 183 currentStateChecksum.Add(&dest_st.st_ino, 184 sizeof(dest_st.st_ino)); 158 185 #ifdef HAVE_STRUCT_STAT_ST_FLAGS 159 currentStateChecksum.Add(&st.st_flags, sizeof(st.st_flags)); 186 currentStateChecksum.Add(&dest_st.st_flags, 187 sizeof(dest_st.st_flags)); 160 188 #endif 161 189 162 190 StreamableMemBlock xattr; 163 BackupClientFileAttributes::FillExtendedAttr(xattr, rLocalPath.c_str()); 191 BackupClientFileAttributes::FillExtendedAttr(xattr, 192 rLocalPath.c_str()); 164 193 currentStateChecksum.Add(xattr.GetBuffer(), xattr.GetSize()); 165 194 } … … 171 200 bool downloadDirectoryRecordBecauseOfFutureFiles = false; 172 201 173 struct stat dir_st;174 if(::lstat(rLocalPath.c_str(), & dir_st) != 0)202 struct stat link_st; 203 if(::lstat(rLocalPath.c_str(), &link_st) != 0) 175 204 { 176 205 // Report the error (logs and 177 206 // eventual email to administrator) 178 r Params.GetProgressNotifier().NotifyFileStatFailed(this,179 rLocalPath,strerror(errno));207 rNotifier.NotifyFileStatFailed(this, rLocalPath, 208 strerror(errno)); 180 209 181 210 // FIXME move to NotifyFileStatFailed() … … 193 222 try 194 223 { 195 rParams.GetProgressNotifier().NotifyScanDirectory( 196 this, rLocalPath); 224 rNotifier.NotifyScanDirectory(this, rLocalPath); 197 225 198 226 dirHandle = ::opendir(rLocalPath.c_str()); … … 203 231 if (errno == EACCES) 204 232 { 205 r Params.GetProgressNotifier().NotifyDirListFailed(206 this,rLocalPath, "Access denied");233 rNotifier.NotifyDirListFailed(this, 234 rLocalPath, "Access denied"); 207 235 } 208 236 else 209 237 { 210 r Params.GetProgressNotifier().NotifyDirListFailed(this,238 rNotifier.NotifyDirListFailed(this, 211 239 rLocalPath, strerror(errno)); 212 240 } 213 241 214 // Report the error (logs and eventual email to administrator) 215 SetErrorWhenReadingFilesystemObject(rParams, rLocalPath.c_str()); 242 // Report the error (logs and eventual email 243 // to administrator) 244 SetErrorWhenReadingFilesystemObject(rParams, 245 rLocalPath.c_str()); 216 246 // Ignore this directory for now. 217 247 return; … … 229 259 230 260 struct dirent *en = 0; 231 struct stat st;261 struct stat file_st; 232 262 std::string filename; 233 263 while((en = ::readdir(dirHandle)) != 0) … … 235 265 rParams.mrContext.DoKeepAlive(); 236 266 237 // Don't need to use LinuxWorkaround_FinishDirentStruct(en, rLocalPath.c_str()); 238 // on Linux, as a stat is performed to get all this info 267 // Don't need to use 268 // LinuxWorkaround_FinishDirentStruct(en, 269 // rLocalPath.c_str()); 270 // on Linux, as a stat is performed to 271 // get all this info 239 272 240 273 if(en->d_name[0] == '.' && … … 260 293 int type = en->d_type; 261 294 #else 262 if(::lstat(filename.c_str(), & st) != 0)295 if(::lstat(filename.c_str(), &file_st) != 0) 263 296 { 264 297 // Report the error (logs and 265 298 // eventual email to administrator) 266 r Params.GetProgressNotifier().NotifyFileStatFailed(this,299 rNotifier.NotifyFileStatFailed(this, 267 300 filename, strerror(errno)); 268 301 … … 275 308 } 276 309 277 if( st.st_dev != dir_st.st_dev)310 if(file_st.st_dev != dest_st.st_dev) 278 311 { 279 312 if(!(rParams.mrContext.ExcludeDir( 280 313 filename))) 281 314 { 282 rParams.GetProgressNotifier() 283 .NotifyMountPointSkipped( 284 this, filename); 315 rNotifier.NotifyMountPointSkipped( 316 this, filename); 285 317 } 286 318 continue; 287 319 } 288 320 289 int type = st.st_mode & S_IFMT;321 int type = file_st.st_mode & S_IFMT; 290 322 #endif 291 323 … … 297 329 if(rParams.mrContext.ExcludeFile(filename)) 298 330 { 299 rParams.GetProgressNotifier() 300 .NotifyFileExcluded( 331 rNotifier.NotifyFileExcluded( 301 332 this, 302 333 filename); … … 316 347 if(rParams.mrContext.ExcludeDir(filename)) 317 348 { 318 rParams.GetProgressNotifier() 319 .NotifyDirExcluded( 349 rNotifier.NotifyDirExcluded( 320 350 this, 321 351 filename); … … 332 362 if(rParams.mrContext.ExcludeFile(filename)) 333 363 { 334 rParams.GetProgressNotifier() 335 .NotifyFileExcluded( 364 rNotifier.NotifyFileExcluded( 336 365 this, 337 366 filename); … … 339 368 else 340 369 { 341 rParams.GetProgressNotifier() 342 .NotifyUnsupportedFileType( 370 rNotifier.NotifyUnsupportedFileType( 343 371 this, filename); 344 372 SetErrorWhenReadingFilesystemObject( … … 355 383 // We didn't stat the file before, 356 384 // but now we need the information. 357 if(::lstat(filename.c_str(), &st) != 0) 358 { 359 rParams.GetProgressNotifier() 360 .NotifyFileStatFailed(this, 385 if(::lstat(filename.c_str(), &file_st) != 0) 386 { 387 rNotifier.NotifyFileStatFailed(this, 361 388 filename, 362 389 strerror(errno)); … … 371 398 } 372 399 373 if(st.st_dev != dir_st.st_dev) 374 { 375 rParams.GetProgressNotifier() 376 .NotifyMountPointSkipped(this, 400 if(file_st.st_dev != link_st.st_dev) 401 { 402 rNotifier.NotifyMountPointSkipped(this, 377 403 filename); 378 404 continue; … … 380 406 #endif 381 407 382 checksum_info.mModificationTime = FileModificationTime( st);383 checksum_info.mAttributeModificationTime = FileAttrModificationTime( st);384 checksum_info.mSize = st.st_size;408 checksum_info.mModificationTime = FileModificationTime(file_st); 409 checksum_info.mAttributeModificationTime = FileAttrModificationTime(file_st); 410 checksum_info.mSize = file_st.st_size; 385 411 currentStateChecksum.Add(&checksum_info, sizeof(checksum_info)); 386 412 currentStateChecksum.Add(en->d_name, strlen(en->d_name)); … … 395 421 if(!rParams.mHaveLoggedWarningAboutFutureFileTimes) 396 422 { 397 r Params.GetProgressNotifier().NotifyFileModifiedInFuture(423 rNotifier.NotifyFileModifiedInFuture( 398 424 this, filename); 399 425 rParams.mHaveLoggedWarningAboutFutureFileTimes = true; … … 469 495 470 496 // Do the directory reading 471 bool updateCompleteSuccess = UpdateItems(rParams, rLocalPath, pdirOnStore, entriesLeftOver, files, dirs); 497 bool updateCompleteSuccess = UpdateItems(rParams, rLocalPath, 498 rRemotePath, pdirOnStore, entriesLeftOver, files, dirs); 472 499 473 500 // LAST THING! (think exception safety) … … 605 632 // 606 633 // -------------------------------------------------------------------------- 607 bool BackupClientDirectoryRecord::UpdateItems(BackupClientDirectoryRecord::SyncParams &rParams, 608 const std::string &rLocalPath, BackupStoreDirectory *pDirOnStore, 634 bool BackupClientDirectoryRecord::UpdateItems( 635 BackupClientDirectoryRecord::SyncParams &rParams, 636 const std::string &rLocalPath, 637 const std::string &rRemotePath, 638 BackupStoreDirectory *pDirOnStore, 609 639 std::vector<BackupStoreDirectory::Entry *> &rEntriesLeftOver, 610 std::vector<std::string> &rFiles, const std::vector<std::string> &rDirs) 640 std::vector<std::string> &rFiles, 641 const std::vector<std::string> &rDirs) 611 642 { 643 BackupClientContext& rContext(rParams.mrContext); 644 ProgressNotifier& rNotifier(rContext.GetProgressNotifier()); 645 612 646 bool allUpdatedSuccessfully = true; 613 647 … … 635 669 { 636 670 // Send keep-alive message if needed 637 r Params.mrContext.DoKeepAlive();671 rContext.DoKeepAlive(); 638 672 639 673 // Filename of this file … … 652 686 if(::lstat(filename.c_str(), &st) != 0) 653 687 { 654 r Params.GetProgressNotifier().NotifyFileStatFailed(this,688 rNotifier.NotifyFileStatFailed(this, 655 689 filename, strerror(errno)); 656 690 … … 690 724 { 691 725 // Directory exists in the place of this file -- sort it out 692 RemoveDirectoryInPlaceOfFile(rParams, pDirOnStore, en->GetObjectID(), *f); 726 RemoveDirectoryInPlaceOfFile(rParams, pDirOnStore, 727 en, *f); 693 728 en = 0; 694 729 } … … 702 737 703 738 // Do we know about the inode number? 704 const BackupClientInodeToIDMap &idMap(r Params.mrContext.GetCurrentIDMap());739 const BackupClientInodeToIDMap &idMap(rContext.GetCurrentIDMap()); 705 740 int64_t renameObjectID = 0, renameInDirectory = 0; 706 741 if(idMap.Lookup(inodeNum, renameObjectID, renameInDirectory)) … … 712 747 box_time_t srvModTime = 0, srvAttributesHash = 0; 713 748 BackupStoreFilenameClear oldLeafname; 714 if(r Params.mrContext.FindFilename(renameObjectID, renameInDirectory, localPotentialOldName, isDir, isCurrentVersion, &srvModTime, &srvAttributesHash, &oldLeafname))749 if(rContext.FindFilename(renameObjectID, renameInDirectory, localPotentialOldName, isDir, isCurrentVersion, &srvModTime, &srvAttributesHash, &oldLeafname)) 715 750 { 716 751 // Only interested if it's a file and the latest version … … 725 760 726 761 // Get the connection to the server 727 BackupProtocolClient &connection(r Params.mrContext.GetConnection());762 BackupProtocolClient &connection(rContext.GetConnection()); 728 763 729 764 // Only do this step if there is room on the server. 730 765 // This step will be repeated later when there is space available 731 if(!r Params.mrContext.StorageLimitExceeded())766 if(!rContext.StorageLimitExceeded()) 732 767 { 733 768 // Rename the existing files (ie include old versions) on the server … … 737 772 738 773 // Stop the attempt to delete the file in the original location 739 BackupClientDeleteList &rdelList(r Params.mrContext.GetDeleteList());774 BackupClientDeleteList &rdelList(rContext.GetDeleteList()); 740 775 rdelList.StopFileDeletion(renameInDirectory, oldLeafname); 741 776 … … 872 907 } 873 908 909 bool fileSynced = true; 910 874 911 if (doUpload) 875 912 { 913 // Upload needed, don't mark sync success until 914 // we've actually done it 915 fileSynced = false; 916 876 917 // Make sure we're connected -- must connect here so we know whether 877 918 // the storage limit has been exceeded, and hence whether or not 878 919 // to actually upload the file. 879 r Params.mrContext.GetConnection();920 rContext.GetConnection(); 880 921 881 922 // Only do this step if there is room on the server. 882 923 // This step will be repeated later when there is space available 883 if(!r Params.mrContext.StorageLimitExceeded())924 if(!rContext.StorageLimitExceeded()) 884 925 { 885 926 // Upload the file to the server, recording the object ID it returns … … 891 932 { 892 933 latestObjectID = UploadFile(rParams, filename, storeFilename, fileSize, modTime, attributesHash, noPreviousVersionOnServer); 893 uploadSuccess = true; 934 if (latestObjectID == 0) 935 { 936 // storage limit exceeded 937 rParams.mrContext.SetStorageLimitExceeded(); 938 uploadSuccess = false; 939 allUpdatedSuccessfully = false; 940 } 941 else 942 { 943 uploadSuccess = true; 944 } 894 945 } 895 946 catch(ConnectionException &e) … … 897 948 // Connection errors should just be passed on to the main handler, retries 898 949 // would probably just cause more problems. 899 rParams.GetProgressNotifier() 900 .NotifyFileUploadException( 901 this, filename, e); 950 // StorageLimitExceeded never gets here. 951 952 rParams.mrDaemon.NotifySysadmin(BackupDaemon::NotifyEvent_StoreFull); 953 rNotifier.NotifyFileUploadException( 954 this, filename, e); 902 955 throw; 903 956 } … … 908 961 // Log it. 909 962 SetErrorWhenReadingFilesystemObject(rParams, filename.c_str()); 910 rParams.GetProgressNotifier() 911 .NotifyFileUploadException( 912 this, filename, e); 963 rNotifier.NotifyFileUploadException( 964 this, filename, e); 913 965 } 914 966 … … 916 968 if(uploadSuccess) 917 969 { 970 fileSynced = true; 971 918 972 // delete from pending entries 919 973 if(pendingFirstSeenTime != 0 && mpPendingEntries != 0) … … 925 979 else 926 980 { 927 r Params.GetProgressNotifier().NotifyFileSkippedServerFull(this,981 rNotifier.NotifyFileSkippedServerFull(this, 928 982 filename); 929 983 } … … 932 986 { 933 987 // Attributes have probably changed, upload them again. 934 // If the attributes have changed enough, the directory hash will have changed too, 935 // and so the dir will have been downloaded, and the entry will be available. 988 // If the attributes have changed enough, the directory 989 // hash will have changed too, and so the dir will have 990 // been downloaded, and the entry will be available. 936 991 937 992 // Get connection 938 BackupProtocolClient &connection(r Params.mrContext.GetConnection());993 BackupProtocolClient &connection(rContext.GetConnection()); 939 994 940 995 // Only do this step if there is room on the server. 941 // This step will be repeated later when there is space available 942 if(!rParams.mrContext.StorageLimitExceeded()) 996 // This step will be repeated later when there is 997 // space available 998 if(!rContext.StorageLimitExceeded()) 943 999 { 944 1000 // Update store … … 947 1003 MemBlockStream attrStream(attr); 948 1004 connection.QuerySetReplacementFileAttributes(mObjectID, attributesHash, storeFilename, attrStream); 1005 fileSynced = true; 949 1006 } 950 1007 } … … 982 1039 { 983 1040 // Get the map 984 BackupClientInodeToIDMap &idMap(r Params.mrContext.GetNewIDMap());1041 BackupClientInodeToIDMap &idMap(rContext.GetNewIDMap()); 985 1042 986 1043 // Need to get an ID from somewhere... … … 994 1051 // Don't know it -- haven't sent anything to the store, and didn't get a listing. 995 1052 // Look it up in the current map, and if it's there, use that. 996 const BackupClientInodeToIDMap ¤tIDMap(r Params.mrContext.GetCurrentIDMap());1053 const BackupClientInodeToIDMap ¤tIDMap(rContext.GetCurrentIDMap()); 997 1054 int64_t objid = 0, dirid = 0; 998 1055 if(currentIDMap.Lookup(inodeNum, objid, dirid)) … … 1003 1060 // or there is a problem somewhere. If this happened on a short test run, look 1004 1061 // into it. However, in a long running process this may happen occasionally and 1005 // not indic iate anything wrong.1062 // not indicate anything wrong. 1006 1063 // Run the release version for real life use, where this check is not made. 1007 1064 idMap.AddToMap(inodeNum, objid, mObjectID /* containing directory */); … … 1010 1067 } 1011 1068 1012 rParams.GetProgressNotifier().NotifyFileSynchronised(this, 1013 filename, fileSize); 1069 if (fileSynced) 1070 { 1071 rNotifier.NotifyFileSynchronised(this, filename, 1072 fileSize); 1073 } 1014 1074 } 1015 1075 … … 1031 1091 { 1032 1092 // Send keep-alive message if needed 1033 r Params.mrContext.DoKeepAlive();1093 rContext.DoKeepAlive(); 1034 1094 1035 1095 // Get the local filename … … 1051 1111 if((en != 0) && ((en->GetFlags() & BackupStoreDirectory::Entry::Flags_Dir) == 0)) 1052 1112 { 1053 // Entry exists, but is not a directory. Bad. Get rid of it. 1054 BackupProtocolClient &connection(rParams.mrContext.GetConnection()); 1113 // Entry exists, but is not a directory. Bad. 1114 // Get rid of it. 1115 BackupProtocolClient &connection(rContext.GetConnection()); 1055 1116 connection.QueryDeleteFile(mObjectID /* in directory */, storeFilename); 1117 rNotifier.NotifyFileDeleted(en->GetObjectID(), 1118 storeFilename.GetClearFilename()); 1056 1119 1057 1120 // Nothing found … … 1059 1122 } 1060 1123 1061 // Flag for having created directory, so can optimise the recusive call not to 1062 // read it again, because we know it's empty. 1124 // Flag for having created directory, so can optimise the 1125 // recusive call not to read it again, because we know 1126 // it's empty. 1063 1127 bool haveJustCreatedDirOnServer = false; 1064 1128 … … 1087 1151 subDirObjectID = en->GetObjectID(); 1088 1152 } 1089 else if(r Params.mrContext.StorageLimitExceeded())1153 else if(rContext.StorageLimitExceeded()) 1090 1154 // know we've got a connection if we get this far, 1091 1155 // as dir will have been modified. … … 1113 1177 int64_t renameObjectID = 0, renameInDirectory = 0; 1114 1178 bool renameDir = false; 1115 const BackupClientInodeToIDMap &idMap(rParams.mrContext.GetCurrentIDMap()); 1179 const BackupClientInodeToIDMap &idMap( 1180 rContext.GetCurrentIDMap()); 1116 1181 if(idMap.Lookup(inodeNum, renameObjectID, renameInDirectory)) 1117 1182 { … … 1120 1185 bool isDir = false; 1121 1186 bool isCurrentVersion = false; 1122 if(r Params.mrContext.FindFilename(renameObjectID, renameInDirectory, localPotentialOldName, isDir, isCurrentVersion))1187 if(rContext.FindFilename(renameObjectID, renameInDirectory, localPotentialOldName, isDir, isCurrentVersion)) 1123 1188 { 1124 1189 // Only interested if it's a directory … … 1138 1203 1139 1204 // Get connection 1140 BackupProtocolClient &connection(r Params.mrContext.GetConnection());1205 BackupProtocolClient &connection(rContext.GetConnection()); 1141 1206 1142 1207 // Don't do a check for storage limit exceeded here, because if we get to this … … 1158 1223 1159 1224 // Stop it being deleted later 1160 BackupClientDeleteList &rdelList(rParams.mrContext.GetDeleteList()); 1225 BackupClientDeleteList &rdelList( 1226 rContext.GetDeleteList()); 1161 1227 rdelList.StopDirectoryDeletion(renameObjectID); 1162 1228 … … 1195 1261 } 1196 1262 1197 ASSERT(psubDirRecord != 0 || r Params.mrContext.StorageLimitExceeded());1263 ASSERT(psubDirRecord != 0 || rContext.StorageLimitExceeded()); 1198 1264 1199 1265 if(psubDirRecord) 1200 1266 { 1201 1267 // Sync this sub directory too 1202 psubDirRecord->SyncDirectory(rParams, mObjectID, dirname, haveJustCreatedDirOnServer); 1268 psubDirRecord->SyncDirectory(rParams, mObjectID, 1269 dirname, rRemotePath + "/" + *d, 1270 haveJustCreatedDirOnServer); 1203 1271 } 1204 1272 … … 1229 1297 // If there's an error during the process, it doesn't matter if things 1230 1298 // aren't actually deleted, as the whole state will be reset anyway. 1231 BackupClientDeleteList &rdel(rParams.mrContext.GetDeleteList()); 1299 BackupClientDeleteList &rdel(rContext.GetDeleteList()); 1300 1301 std::string localName = MakeFullPath(rLocalPath, 1302 en->GetName()); 1232 1303 1233 1304 // Delete this entry -- file or directory? … … 1235 1306 { 1236 1307 // Set a pending deletion for the file 1237 rdel.AddFileDelete(mObjectID, en->GetName()); 1308 rdel.AddFileDelete(mObjectID, en->GetName(), 1309 localName); 1238 1310 } 1239 1311 else if((en->GetFlags() & BackupStoreDirectory::Entry::Flags_Dir) != 0) 1240 1312 { 1241 1313 // Set as a pending deletion for the directory 1242 rdel.AddDirectoryDelete(en->GetObjectID()); 1314 rdel.AddDirectoryDelete(en->GetObjectID(), 1315 localName); 1243 1316 1244 // If there's a directory record for it in the sub directory map, delete it now 1317 // If there's a directory record for it in 1318 // the sub directory map, delete it now 1245 1319 BackupStoreFilenameClear dirname(en->GetName()); 1246 1320 std::map<std::string, BackupClientDirectoryRecord *>::iterator e(mSubDirectories.find(dirname.GetClearFilename())); … … 1277 1351 // 1278 1352 // -------------------------------------------------------------------------- 1279 void BackupClientDirectoryRecord::RemoveDirectoryInPlaceOfFile(SyncParams &rParams, BackupStoreDirectory *pDirOnStore, int64_t ObjectID, const std::string &rFilename) 1353 void BackupClientDirectoryRecord::RemoveDirectoryInPlaceOfFile( 1354 SyncParams &rParams, 1355 BackupStoreDirectory* pDirOnStore, 1356 BackupStoreDirectory::Entry* pEntry, 1357 const std::string &rFilename) 1280 1358 { 1281 1359 // First, delete the directory 1282 1360 BackupProtocolClient &connection(rParams.mrContext.GetConnection()); 1283 connection.QueryDeleteDirectory(ObjectID); 1361 connection.QueryDeleteDirectory(pEntry->GetObjectID()); 1362 1363 BackupStoreFilenameClear clear(pEntry->GetName()); 1364 rParams.mrContext.GetProgressNotifier().NotifyDirectoryDeleted( 1365 pEntry->GetObjectID(), clear.GetClearFilename()); 1284 1366 1285 1367 // Then, delete any directory record 1286 std::map<std::string, BackupClientDirectoryRecord *>::iterator e(mSubDirectories.find(rFilename)); 1368 std::map<std::string, BackupClientDirectoryRecord *>::iterator 1369 e(mSubDirectories.find(rFilename)); 1370 1287 1371 if(e != mSubDirectories.end()) 1288 1372 { … … 1301 1385 // 1302 1386 // Function 1303 // Name: BackupClientDirectoryRecord::UploadFile(BackupClientDirectoryRecord::SyncParams &, const std::string &, const BackupStoreFilename &, int64_t, box_time_t, box_time_t, bool) 1304 // Purpose: Private. Upload a file to the server -- may send a patch instead of the whole thing 1387 // Name: BackupClientDirectoryRecord::UploadFile( 1388 // BackupClientDirectoryRecord::SyncParams &, 1389 // const std::string &, 1390 // const BackupStoreFilename &, 1391 // int64_t, box_time_t, box_time_t, bool) 1392 // Purpose: Private. Upload a file to the server. May send 1393 // a patch instead of the whole thing 1305 1394 // Created: 20/1/04 1306 1395 // 1307 1396 // -------------------------------------------------------------------------- 1308 int64_t BackupClientDirectoryRecord::UploadFile(BackupClientDirectoryRecord::SyncParams &rParams, const std::string &rFilename, const BackupStoreFilename &rStoreFilename, 1309 int64_t FileSize, box_time_t ModificationTime, box_time_t AttributesHash, bool NoPreviousVersionOnServer) 1397 int64_t BackupClientDirectoryRecord::UploadFile( 1398 BackupClientDirectoryRecord::SyncParams &rParams, 1399 const std::string &rFilename, 1400 const BackupStoreFilename &rStoreFilename, 1401 int64_t FileSize, 1402 box_time_t ModificationTime, 1403 box_time_t AttributesHash, 1404 bool NoPreviousVersionOnServer) 1310 1405 { 1406 BackupClientContext& rContext(rParams.mrContext); 1407 ProgressNotifier& rNotifier(rContext.GetProgressNotifier()); 1408 1311 1409 // Get the connection 1312 BackupProtocolClient &connection(r Params.mrContext.GetConnection());1410 BackupProtocolClient &connection(rContext.GetConnection()); 1313 1411 1314 1412 // Info … … 1319 1417 try 1320 1418 { 1321 // Might an old version be on the server, and is the file size over the diffing threshold? 1322 if(!NoPreviousVersionOnServer && FileSize >= rParams.mDiffingUploadSizeThreshold) 1419 // Might an old version be on the server, and is the file 1420 // size over the diffing threshold? 1421 if(!NoPreviousVersionOnServer && 1422 FileSize >= rParams.mDiffingUploadSizeThreshold) 1323 1423 { 1324 1424 // YES -- try to do diff, if possible … … 1330 1430 { 1331 1431 // Found an old version 1332 r Params.GetProgressNotifier().NotifyFileUploadingPatch(this,1432 rNotifier.NotifyFileUploadingPatch(this, 1333 1433 rFilename); 1334 1434 … … 1340 1440 // 1341 1441 1342 r Params.mrContext.ManageDiffProcess();1442 rContext.ManageDiffProcess(); 1343 1443 1344 1444 bool isCompletelyDifferent = false; … … 1349 1449 rStoreFilename, diffFromID, *blockIndexStream, 1350 1450 connection.GetTimeout(), 1351 &r Params.mrContext, // DiffTimer implementation1451 &rContext, // DiffTimer implementation 1352 1452 0 /* not interested in the modification time */, 1353 1453 &isCompletelyDifferent)); 1354 1454 1355 r Params.mrContext.UnManageDiffProcess();1455 rContext.UnManageDiffProcess(); 1356 1456 1357 1457 // … … 1361 1461 AttributesHash, isCompletelyDifferent?(0):(diffFromID), rStoreFilename, *patchStream)); 1362 1462 1463 // Get object ID from the result 1464 objID = stored->GetObjectID(); 1465 1363 1466 // Don't attempt to upload it again! 1364 1467 doNormalUpload = false; … … 1369 1472 { 1370 1473 // below threshold or nothing to diff from, so upload whole 1371 rParams.GetProgressNotifier().NotifyFileUploading(this, 1372 rFilename); 1474 rNotifier.NotifyFileUploading(this, rFilename); 1373 1475 1374 1476 // Prepare to upload, getting a stream which will encode the file as we go along … … 1391 1493 catch(BoxException &e) 1392 1494 { 1393 r Params.mrContext.UnManageDiffProcess();1495 rContext.UnManageDiffProcess(); 1394 1496 1395 1497 if(e.GetType() == ConnectionException::ExceptionType && e.GetSubType() == ConnectionException::Protocol_UnexpectedReply) … … 1405 1507 // The hard limit was exceeded on the server, notify! 1406 1508 rParams.mrDaemon.NotifySysadmin(BackupDaemon::NotifyEvent_StoreFull); 1407 } 1408 rParams.GetProgressNotifier() 1409 .NotifyFileUploadServerError( 1410 this, rFilename, type, subtype); 1509 // return an error code instead of 1510 // throwing an exception that we 1511 // can't debug. 1512 return 0; 1513 } 1514 rNotifier.NotifyFileUploadServerError(this, 1515 rFilename, type, subtype); 1411 1516 } 1412 1517 } … … 1416 1521 } 1417 1522 1418 r Params.GetProgressNotifier().NotifyFileUploaded(this, rFilename, FileSize);1523 rNotifier.NotifyFileUploaded(this, rFilename, FileSize); 1419 1524 1420 1525 // Return the new object ID of this file … … 1458 1563 // -------------------------------------------------------------------------- 1459 1564 BackupClientDirectoryRecord::SyncParams::SyncParams(BackupDaemon &rDaemon, 1460 ProgressNotifier &rProgressNotifier, BackupClientContext &rContext) 1461 : mrProgressNotifier(rProgressNotifier), 1462 mSyncPeriodStart(0), 1565 BackupClientContext &rContext) 1566 : mSyncPeriodStart(0), 1463 1567 mSyncPeriodEnd(0), 1464 1568 mMaxUploadWait(0), -
box/trunk/bin/bbackupd/BackupClientDirectoryRecord.h
r1801 r2181 97 97 const std::string& rLocalPath, 98 98 int64_t FileSize) = 0; 99 virtual void NotifyDirectoryDeleted( 100 int64_t ObjectID, 101 const std::string& rRemotePath) = 0; 102 virtual void NotifyFileDeleted( 103 int64_t ObjectID, 104 const std::string& rRemotePath) = 0; 99 105 }; 100 106 … … 138 144 SyncParams( 139 145 BackupDaemon &rDaemon, 140 ProgressNotifier &rProgressNotifier,141 146 BackupClientContext &rContext); 142 147 ~SyncParams(); … … 145 150 SyncParams(const SyncParams&); 146 151 SyncParams &operator=(const SyncParams&); 147 ProgressNotifier &mrProgressNotifier;148 152 149 153 public: … … 162 166 box_time_t mUploadAfterThisTimeInTheFuture; 163 167 bool mHaveLoggedWarningAboutFutureFileTimes; 164 165 ProgressNotifier& GetProgressNotifier() const166 {167 return mrProgressNotifier;168 }169 168 }; 170 169 171 void SyncDirectory(SyncParams &rParams, int64_t ContainingDirectoryID, const std::string &rLocalPath, 170 void SyncDirectory(SyncParams &rParams, 171 int64_t ContainingDirectoryID, 172 const std::string &rLocalPath, 173 const std::string &rRemotePath, 172 174 bool ThisDirHasJustBeenCreated = false); 173 175 … … 175 177 void DeleteSubDirectories(); 176 178 BackupStoreDirectory *FetchDirectoryListing(SyncParams &rParams); 177 void UpdateAttributes(SyncParams &rParams, BackupStoreDirectory *pDirOnStore, const std::string &rLocalPath); 178 bool UpdateItems(SyncParams &rParams, const std::string &rLocalPath, BackupStoreDirectory *pDirOnStore, 179 void UpdateAttributes(SyncParams &rParams, 180 BackupStoreDirectory *pDirOnStore, 181 const std::string &rLocalPath); 182 bool UpdateItems(SyncParams &rParams, const std::string &rLocalPath, 183 const std::string &rRemotePath, 184 BackupStoreDirectory *pDirOnStore, 179 185 std::vector<BackupStoreDirectory::Entry *> &rEntriesLeftOver, 180 std::vector<std::string> &rFiles, const std::vector<std::string> &rDirs); 181 int64_t UploadFile(SyncParams &rParams, const std::string &rFilename, const BackupStoreFilename &rStoreFilename, 182 int64_t FileSize, box_time_t ModificationTime, box_time_t AttributesHash, bool NoPreviousVersionOnServer); 183 void SetErrorWhenReadingFilesystemObject(SyncParams &rParams, const char *Filename); 184 void RemoveDirectoryInPlaceOfFile(SyncParams &rParams, BackupStoreDirectory *pDirOnStore, int64_t ObjectID, const std::string &rFilename); 186 std::vector<std::string> &rFiles, 187 const std::vector<std::string> &rDirs); 188 int64_t UploadFile(SyncParams &rParams, 189 const std::string &rFilename, 190 const BackupStoreFilename &rStoreFilename, 191 int64_t FileSize, box_time_t ModificationTime, 192 box_time_t AttributesHash, bool NoPreviousVersionOnServer); 193 void SetErrorWhenReadingFilesystemObject(SyncParams &rParams, 194 const char *Filename); 195 void RemoveDirectoryInPlaceOfFile(SyncParams &rParams, 196 BackupStoreDirectory* pDirOnStore, 197 BackupStoreDirectory::Entry* pEntry, 198 const std::string &rFilename); 185 199 186 200 private: 187 int64_t mObjectID;201 int64_t mObjectID; 188 202 std::string mSubDirName; 189 bool mInitialSyncDone;190 bool mSyncDone;203 bool mInitialSyncDone; 204 bool mSyncDone; 191 205 192 206 // Checksum of directory contents and attributes, used to detect changes 193 207 uint8_t mStateChecksum[MD5Digest::DigestLength]; 194 208 195 std::map<std::string, box_time_t> *mpPendingEntries;196 std::map<std::string, BackupClientDirectoryRecord *> mSubDirectories;209 std::map<std::string, box_time_t> *mpPendingEntries; 210 std::map<std::string, BackupClientDirectoryRecord *> mSubDirectories; 197 211 // mpPendingEntries is a pointer rather than simple a member 198 // variable s, because most of the time it'll be empty. This would waste a lot199 // of memory because of STL allocation policies.212 // variable, because most of the time it'll be empty. This would 213 // waste a lot of memory because of STL allocation policies. 200 214 }; 201 215 -
box/trunk/bin/bbackupd/BackupDaemon.cpp
r2148 r2181 48 48 49 49 #include "SSLLib.h" 50 #include "TLSContext.h"51 50 52 51 #include "BackupDaemon.h" … … 125 124 mpCommandSocketInfo(0), 126 125 mDeleteUnusedRootDirEntriesAfter(0), 126 mClientStoreMarker(BackupClientContext::ClientStoreMarker_NotKnown), 127 mStorageLimitExceeded(false), 128 mReadErrorsOnFilesystemObjects(false), 129 mLastSyncTime(0), 127 130 mLogAllFileAccess(false) 128 131 #ifdef WIN32 … … 295 298 mLocations.clear(); 296 299 297 // And delete everything from the asso icated mount vector300 // And delete everything from the associated mount vector 298 301 mIDMapMounts.clear(); 299 302 } … … 686 689 } 687 690 688 // -------------------------------------------------------------------------- 689 // 690 // Function 691 // Name: BackupDaemon::Run2() 692 // Purpose: Run function for daemon (second stage) 693 // Created: 2003/10/08 694 // 695 // -------------------------------------------------------------------------- 696 void BackupDaemon::Run2() 691 void BackupDaemon::InitCrypto() 697 692 { 698 693 // Read in the certificates creating a TLS context 699 TLSContext tlsContext;700 694 const Configuration &conf(GetConfiguration()); 701 695 std::string certFile(conf.GetKeyValue("CertificateFile")); 702 696 std::string keyFile(conf.GetKeyValue("PrivateKeyFile")); 703 697 std::string caFile(conf.GetKeyValue("TrustedCAsFile")); 704 tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(), caFile.c_str()); 698 mTlsContext.Initialise(false /* as client */, certFile.c_str(), 699 keyFile.c_str(), caFile.c_str()); 705 700 706 701 // Set up the keys for various things 707 702 BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str()); 708 709 // Setup various timings 710 int maximumDiffingTime = 600; 711 int keepAliveTime = 60; 712 713 // max diffing time, keep-alive time 714 if(conf.KeyExists("MaximumDiffingTime")) 715 { 716 maximumDiffingTime = conf.GetKeyValueInt("MaximumDiffingTime"); 717 } 718 if(conf.KeyExists("KeepAliveTime")) 719 { 720 keepAliveTime = conf.GetKeyValueInt("KeepAliveTime"); 721 } 703 } 704 705 // -------------------------------------------------------------------------- 706 // 707 // Function 708 // Name: BackupDaemon::Run2() 709 // Purpose: Run function for daemon (second stage) 710 // Created: 2003/10/08 711 // 712 // -------------------------------------------------------------------------- 713 void BackupDaemon::Run2() 714 { 715 InitCrypto(); 716 717 const Configuration &conf(GetConfiguration()); 722 718 723 719 // How often to connect to the store (approximate) 724 box_time_t updateStoreInterval = SecondsToBoxTime(conf.GetKeyValueInt("UpdateStoreInterval")); 720 box_time_t updateStoreInterval = SecondsToBoxTime( 721 conf.GetKeyValueInt("UpdateStoreInterval")); 725 722 726 723 // But are we connecting automatically? 727 724 bool automaticBackup = conf.GetKeyValueBool("AutomaticBackup"); 728 725 729 // The minimum age a file needs to be before it will be considered for uploading730 box_time_t minimumFileAge = SecondsToBoxTime(conf.GetKeyValueInt("MinimumFileAge"));731 732 // The maximum time we'll wait to upload a file, regardless of how often it's modified733 box_time_t maxUploadWait = SecondsToBoxTime(conf.GetKeyValueInt("MaxUploadWait"));734 // Adjust by subtracting the minimum file age, so is relative to sync period end in comparisons735 maxUploadWait = (maxUploadWait > minimumFileAge)?(maxUploadWait - minimumFileAge):(0);736 737 726 // When the next sync should take place -- which is ASAP 738 727 box_time_t nextSyncTime = 0; 739 728 740 729 // When the last sync started (only updated if the store was not full when the sync ended) 741 box_time_t lastSyncTime = 0;730 mLastSyncTime = 0; 742 731 743 732 // -------------------------------------------------------------------------------------------- 744 733 745 // And what's the current client store marker?746 int64_t clientStoreMarker =747 BackupClientContext::ClientStoreMarker_NotKnown;748 // haven't contacted the store yet749 750 734 bool deleteStoreObjectInfoFile = DeserializeStoreObjectInfo( 751 clientStoreMarker, lastSyncTime, nextSyncTime);735 mLastSyncTime, nextSyncTime); 752 736 753 737 // -------------------------------------------------------------------------------------------- … … 756 740 // Set state 757 741 SetState(State_Idle); 742 743 bool doSyncForcedByPreviousSyncError = false; 758 744 759 745 // Loop around doing backups … … 766 752 767 753 // Is a delay necessary? 768 { 769 box_time_t currentTime; 770 do 771 { 772 // Check whether we should be stopping, 773 // and don't run a sync if so. 774 if(StopRun()) break; 775 776 currentTime = GetCurrentBoxTime(); 777 778 // Pause a while, but no more than 779 // MAX_SLEEP_TIME seconds (use the conditional 780 // because times are unsigned) 781 box_time_t requiredDelay = 782 (nextSyncTime < currentTime) 783 ? (0) 784 : (nextSyncTime - currentTime); 785 786 // If there isn't automatic backup happening, 787 // set a long delay. And limit delays at the 788 // same time. 789 if(!automaticBackup || requiredDelay > 790 SecondsToBoxTime(MAX_SLEEP_TIME)) 791 { 792 requiredDelay = SecondsToBoxTime( 793 MAX_SLEEP_TIME); 794 } 795 796 // Only delay if necessary 797 if(requiredDelay > 0) 798 { 799 // Sleep somehow. There are choices 800 // on how this should be done, 801 // depending on the state of the 802 // control connection 803 if(mpCommandSocketInfo != 0) 804 { 805 // A command socket exists, 806 // so sleep by waiting on it 807 WaitOnCommandSocket( 808 requiredDelay, doSync, 809 doSyncForcedByCommand); 810 } 811 else 812 { 813 // No command socket or 814 // connection, just do a 815 // normal sleep 816 time_t sleepSeconds = 817 BoxTimeToSeconds( 818 requiredDelay); 819 ::sleep((sleepSeconds <= 0) 820 ? 1 821 : sleepSeconds); 822 } 823 } 824 825 } while((!automaticBackup || (currentTime < nextSyncTime)) && !doSync && !StopRun()); 826 } 754 box_time_t currentTime; 755 756 do 757 { 758 // Check whether we should be stopping, 759 // and don't run a sync if so. 760 if(StopRun()) break; 761 762 currentTime = GetCurrentBoxTime(); 763 764 // Pause a while, but no more than 765 // MAX_SLEEP_TIME seconds (use the conditional 766 // because times are unsigned) 767 box_time_t requiredDelay = 768 (nextSyncTime < currentTime) 769 ? (0) 770 : (nextSyncTime - currentTime); 771 772 // If there isn't automatic backup happening, 773 // set a long delay. And limit delays at the 774 // same time. 775 if(!automaticBackup && !doSyncForcedByPreviousSyncError) 776 { 777 requiredDelay = SecondsToBoxTime(MAX_SLEEP_TIME); 778 } 779 else if(requiredDelay > SecondsToBoxTime(MAX_SLEEP_TIME)) 780 { 781 requiredDelay = SecondsToBoxTime(MAX_SLEEP_TIME); 782 } 783 784 // Only delay if necessary 785 if(requiredDelay > 0) 786 { 787 // Sleep somehow. There are choices 788 // on how this should be done, 789 // depending on the state of the 790 // control connection 791 if(mpCommandSocketInfo != 0) 792 { 793 // A command socket exists, 794 // so sleep by waiting on it 795 WaitOnCommandSocket(requiredDelay, 796 doSync, doSyncForcedByCommand); 797 } 798 else 799 { 800 // No command socket or 801 // connection, just do a 802 // normal sleep 803 time_t sleepSeconds = 804 BoxTimeToSeconds(requiredDelay); 805 ::sleep((sleepSeconds <= 0) 806 ? 1 : sleepSeconds); 807 } 808 } 809 810 if ((automaticBackup || doSyncForcedByPreviousSyncError) 811 && currentTime >= nextSyncTime) 812 { 813 doSync = true; 814 } 815 } 816 while(!doSync && !StopRun()); 827 817 828 818 // Time of sync start, and if it's time for another sync 829 819 // (and we're doing automatic syncs), set the flag 830 820 box_time_t currentSyncStartTime = GetCurrentBoxTime(); 831 if(automaticBackup && currentSyncStartTime >= nextSyncTime) 821 if((automaticBackup || doSyncForcedByPreviousSyncError) && 822 currentSyncStartTime >= nextSyncTime) 832 823 { 833 824 doSync = true; … … 860 851 BackupStoreFile::ResetStats(); 861 852 862 // Calculate the sync period of files to examine863 box_time_t syncPeriodStart = lastSyncTime;864 box_time_t syncPeriodEnd = currentSyncStartTime -865 minimumFileAge;866 867 if(syncPeriodStart >= syncPeriodEnd &&868 syncPeriodStart - syncPeriodEnd < minimumFileAge)869 {870 // This can happen if we receive a force-sync871 // command less than minimumFileAge after872 // the last sync. Deal with it by moving back873 // syncPeriodStart, which should not do any874 // damage.875 syncPeriodStart = syncPeriodEnd -876 SecondsToBoxTime(1);877 }878 879 if(syncPeriodStart >= syncPeriodEnd)880 {881 BOX_ERROR("Invalid (negative) sync period: "882 "perhaps your clock is going "883 "backwards (" << syncPeriodStart <<884 " to " << syncPeriodEnd << ")");885 THROW_EXCEPTION(ClientException,886 ClockWentBackwards);887 }888 889 // Check logic890 ASSERT(syncPeriodEnd > syncPeriodStart);891 // Paranoid check on sync times892 if(syncPeriodStart >= syncPeriodEnd) continue;893 894 // Adjust syncPeriodEnd to emulate snapshot895 // behaviour properly896 box_time_t syncPeriodEndExtended = syncPeriodEnd;897 // Using zero min file age?898 if(minimumFileAge == 0)899 {900 // Add a year on to the end of the end time,901 // to make sure we sync files which are902 // modified after the scan run started.903 // Of course, they may be eligible to be904 // synced again the next time round,905 // but this should be OK, because the changes906 // only upload should upload no data.907 syncPeriodEndExtended += SecondsToBoxTime(908 (time_t)(356*24*3600));909 }910 911 853 // Delete the serialised store object file, 912 854 // so that we don't try to reload it after a … … 934 876 try 935 877 { 936 // Set state and log start937 SetState(State_Connected);938 BOX_NOTICE("Beginning scan of local files");939 940 std::string extendedLogFile;941 if (conf.KeyExists("ExtendedLogFile"))942 {943 extendedLogFile = conf.GetKeyValue(944 "ExtendedLogFile");945 }946 947 if (conf.KeyExists("LogAllFileAccess"))948 {949 mLogAllFileAccess =950 conf.GetKeyValueBool(951 "LogAllFileAccess");952 }953 954 // Then create a client context object (don't955 // just connect, as this may be unnecessary)956 BackupClientContext clientContext957 (958 *this,959 tlsContext,960 conf.GetKeyValue("StoreHostname"),961 conf.GetKeyValueInt("StorePort"),962 conf.GetKeyValueInt("AccountNumber"),963 conf.GetKeyValueBool("ExtendedLogging"),964 conf.KeyExists("ExtendedLogFile"),965 extendedLogFile966 );967 968 // Set up the sync parameters969 BackupClientDirectoryRecord::SyncParams params(970 *this, *this, clientContext);971 params.mSyncPeriodStart = syncPeriodStart;972 params.mSyncPeriodEnd = syncPeriodEndExtended;973 // use potentially extended end time974 params.mMaxUploadWait = maxUploadWait;975 params.mFileTrackingSizeThreshold =976 conf.GetKeyValueInt(977 "FileTrackingSizeThreshold");978 params.mDiffingUploadSizeThreshold =979 conf.GetKeyValueInt(980 "DiffingUploadSizeThreshold");981 params.mMaxFileTimeInFuture =982 SecondsToBoxTime(983 conf.GetKeyValueInt(984 "MaxFileTimeInFuture"));985 mDeleteRedundantLocationsAfter =986 conf.GetKeyValueInt(987 "DeleteRedundantLocationsAfter");988 989 clientContext.SetMaximumDiffingTime(maximumDiffingTime);990 clientContext.SetKeepAliveTime(keepAliveTime);991 992 // Set store marker993 clientContext.SetClientStoreMarker(clientStoreMarker);994 995 // Set up the locations, if necessary --996 // need to do it here so we have a997 // (potential) connection to use998 if(mLocations.empty())999 {1000 const Configuration &locations(1001 conf.GetSubConfiguration(1002 "BackupLocations"));1003 1004 // Make sure all the directory records1005 // are set up1006 SetupLocations(clientContext, locations);1007 }1008 1009 // Get some ID maps going1010 SetupIDMapsForSync();1011 1012 // Delete any unused directories?1013 DeleteUnusedRootDirEntries(clientContext);1014 1015 878 // Notify administrator 1016 879 NotifySysadmin(NotifyEvent_BackupStart); 1017 880 1018 // Go through the records, syncing them 1019 for(std::vector<Location *>::const_iterator 1020 i(mLocations.begin()); 1021 i != mLocations.end(); ++i) 1022 { 1023 // Set current and new ID map pointers 1024 // in the context 1025 clientContext.SetIDMaps(mCurrentIDMaps[(*i)->mIDMapIndex], mNewIDMaps[(*i)->mIDMapIndex]); 1026 1027 // Set exclude lists (context doesn't 1028 // take ownership) 1029 clientContext.SetExcludeLists( 1030 (*i)->mpExcludeFiles, 1031 (*i)->mpExcludeDirs); 1032 1033 // Sync the directory 1034 (*i)->mpDirectoryRecord->SyncDirectory( 1035 params, 1036 BackupProtocolClientListDirectory::RootDirectory, 1037 (*i)->mPath); 1038 1039 // Unset exclude lists (just in case) 1040 clientContext.SetExcludeLists(0, 0); 1041 } 1042 881 RunSyncNow(); 882 1043 883 // Errors reading any files? 1044 if( params.mReadErrorsOnFilesystemObjects)884 if(mReadErrorsOnFilesystemObjects) 1045 885 { 1046 886 // Notify administrator … … 1054 894 } 1055 895 1056 // Perform any deletions required -- these are1057 // delayed until the end to allow renaming to1058 // happen neatly.1059 clientContext.PerformDeletions();1060 1061 // Close any open connection1062 clientContext.CloseAnyOpenConnection();1063 1064 // Get the new store marker1065 clientStoreMarker = clientContext.GetClientStoreMarker();1066 1067 896 // Check the storage limit 1068 if( clientContext.StorageLimitExceeded())897 if(mStorageLimitExceeded) 1069 898 { 1070 899 // Tell the sysadmin about this … … 1073 902 else 1074 903 { 1075 // The start time of the next run is1076 // the end time of this run.1077 // This is only done if the storage1078 // limit wasn't exceeded (as things1079 // won't have been done properly if1080 // it was)1081 lastSyncTime = syncPeriodEnd;1082 1083 904 // unflag the storage full notify flag 1084 905 // so that next time the store is full, … … 1093 914 SYNC_PERIOD_RANDOM_EXTRA_TIME_SHIFT_BY); 1094 915 1095 // Commit the ID Maps1096 CommitIDMapsAfterSync();1097 1098 // Log1099 BOX_NOTICE("Finished scan of local files");1100 1101 916 // Notify administrator 1102 917 NotifySysadmin(NotifyEvent_BackupFinish); … … 1109 924 1110 925 deleteStoreObjectInfoFile = 1111 SerializeStoreObjectInfo( 1112 clientStoreMarker, 1113 lastSyncTime, nextSyncTime); 926 SerializeStoreObjectInfo(mLastSyncTime, 927 nextSyncTime); 1114 928 1115 929 // -------------------------------------------------------------------------------------------- 930 931 // If we were retrying after an error, 932 // now would be a good time to stop :-) 933 doSyncForcedByPreviousSyncError = false; 1116 934 } 1117 935 catch(BoxException &e) … … 1154 972 1155 973 // Clear state data 1156 syncPeriodStart = 0;1157 // go back to beginning of time1158 clientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown; // no store marker, so download everything974 // Go back to beginning of time 975 mLastSyncTime = 0; 976 mClientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown; // no store marker, so download everything 1159 977 DeleteAllLocations(); 1160 978 DeleteAllIDMaps(); … … 1169 987 } 1170 988 1171 // If the Berkely db files get corrupted, delete them and try again immediately 989 // If the Berkely db files get corrupted, 990 // delete them and try again immediately. 1172 991 if(isBerkelyDbFailure) 1173 992 { … … 1189 1008 ::sleep(10); 1190 1009 nextSyncTime = currentSyncStartTime + 1191 SecondsToBoxTime( 90) +1010 SecondsToBoxTime(100) + 1192 1011 Random::RandomInt( 1193 1012 updateStoreInterval >> 1194 1013 SYNC_PERIOD_RANDOM_EXTRA_TIME_SHIFT_BY); 1014 doSyncForcedByPreviousSyncError = true; 1195 1015 } 1196 1016 } … … 1222 1042 } 1223 1043 1044 void BackupDaemon::RunSyncNow() 1045 { 1046 // Set state and log start 1047 SetState(State_Connected); 1048 BOX_NOTICE("Beginning scan of local files"); 1049 1050 const Configuration &conf(GetConfiguration()); 1051 1052 std::string extendedLogFile; 1053 if (conf.KeyExists("ExtendedLogFile")) 1054 { 1055 extendedLogFile = conf.GetKeyValue("ExtendedLogFile"); 1056 } 1057 1058 if (conf.KeyExists("LogAllFileAccess")) 1059 { 1060 mLogAllFileAccess = conf.GetKeyValueBool("LogAllFileAccess"); 1061 } 1062 1063 // Then create a client context object (don't 1064 // just connect, as this may be unnecessary) 1065 BackupClientContext clientContext 1066 ( 1067 *this, 1068 mTlsContext, 1069 conf.GetKeyValue("StoreHostname"), 1070 conf.GetKeyValueInt("StorePort"), 1071 conf.GetKeyValueInt("AccountNumber"), 1072 conf.GetKeyValueBool("ExtendedLogging"), 1073 conf.KeyExists("ExtendedLogFile"), 1074 extendedLogFile, *this 1075 ); 1076 1077 // The minimum age a file needs to be before it will be 1078 // considered for uploading 1079 box_time_t minimumFileAge = SecondsToBoxTime( 1080 conf.GetKeyValueInt("MinimumFileAge")); 1081 1082 // The maximum time we'll wait to upload a file, regardless 1083 // of how often it's modified 1084 box_time_t maxUploadWait = SecondsToBoxTime( 1085 conf.GetKeyValueInt("MaxUploadWait")); 1086 // Adjust by subtracting the minimum file age, so is relative 1087 // to sync period end in comparisons 1088 if (maxUploadWait > minimumFileAge) 1089 { 1090 maxUploadWait -= minimumFileAge; 1091 } 1092 else 1093 { 1094 maxUploadWait = 0; 1095 } 1096 1097 // Calculate the sync period of files to examine 1098 box_time_t syncPeriodStart = mLastSyncTime; 1099 box_time_t syncPeriodEnd = GetCurrentBoxTime() - minimumFileAge; 1100 1101 if(syncPeriodStart >= syncPeriodEnd && 1102 syncPeriodStart - syncPeriodEnd < minimumFileAge) 1103 { 1104 // This can happen if we receive a force-sync 1105 // command less than minimumFileAge after 1106 // the last sync. Deal with it by moving back 1107 // syncPeriodStart, which should not do any 1108 // damage. 1109 syncPeriodStart = syncPeriodEnd - 1110 SecondsToBoxTime(1); 1111 } 1112 1113 if(syncPeriodStart >= syncPeriodEnd) 1114 { 1115 BOX_ERROR("Invalid (negative) sync period: " 1116 "perhaps your clock is going " 1117 "backwards (" << syncPeriodStart << 1118 " to " << syncPeriodEnd << ")"); 1119 THROW_EXCEPTION(ClientException, 1120 ClockWentBackwards); 1121 } 1122 1123 // Check logic 1124 ASSERT(syncPeriodEnd > syncPeriodStart); 1125 // Paranoid check on sync times 1126 if(syncPeriodStart >= syncPeriodEnd) return; 1127 1128 // Adjust syncPeriodEnd to emulate snapshot 1129 // behaviour properly 1130 box_time_t syncPeriodEndExtended = syncPeriodEnd; 1131 1132 // Using zero min file age? 1133 if(minimumFileAge == 0) 1134 { 1135 // Add a year on to the end of the end time, 1136 // to make sure we sync files which are 1137 // modified after the scan run started. 1138 // Of course, they may be eligible to be 1139 // synced again the next time round, 1140 // but this should be OK, because the changes 1141 // only upload should upload no data. 1142 syncPeriodEndExtended += SecondsToBoxTime( 1143 (time_t)(356*24*3600)); 1144 } 1145 1146 // Set up the sync parameters 1147 BackupClientDirectoryRecord::SyncParams params( 1148 *this, clientContext); 1149 params.mSyncPeriodStart = syncPeriodStart; 1150 params.mSyncPeriodEnd = syncPeriodEndExtended; 1151 // use potentially extended end time 1152 params.mMaxUploadWait = maxUploadWait; 1153 params.mFileTrackingSizeThreshold = 1154 conf.GetKeyValueInt( 1155 "FileTrackingSizeThreshold"); 1156 params.mDiffingUploadSizeThreshold = 1157 conf.GetKeyValueInt( 1158 "DiffingUploadSizeThreshold"); 1159 params.mMaxFileTimeInFuture = 1160 SecondsToBoxTime( 1161 conf.GetKeyValueInt( 1162 "MaxFileTimeInFuture")); 1163 mDeleteRedundantLocationsAfter = 1164 conf.GetKeyValueInt( 1165 "DeleteRedundantLocationsAfter"); 1166 mStorageLimitExceeded = false; 1167 mReadErrorsOnFilesystemObjects = false; 1168 1169 // Setup various timings 1170 int maximumDiffingTime = 600; 1171 int keepAliveTime = 60; 1172 1173 // max diffing time, keep-alive time 1174 if(conf.KeyExists("MaximumDiffingTime")) 1175 { 1176 maximumDiffingTime = conf.GetKeyValueInt("MaximumDiffingTime"); 1177 } 1178 if(conf.KeyExists("KeepAliveTime")) 1179 { 1180 keepAliveTime = conf.GetKeyValueInt("KeepAliveTime"); 1181 } 1182 1183 clientContext.SetMaximumDiffingTime(maximumDiffingTime); 1184 clientContext.SetKeepAliveTime(keepAliveTime); 1185 1186 // Set store marker 1187 clientContext.SetClientStoreMarker(mClientStoreMarker); 1188 1189 // Set up the locations, if necessary -- 1190 // need to do it here so we have a 1191 // (potential) connection to use 1192 if(mLocations.empty()) 1193 { 1194 const Configuration &locations( 1195 conf.GetSubConfiguration( 1196 "BackupLocations")); 1197 1198 // Make sure all the directory records 1199 // are set up 1200 SetupLocations(clientContext, locations); 1201 } 1202 1203 // Get some ID maps going 1204 SetupIDMapsForSync(); 1205 1206 // Delete any unused directories? 1207 DeleteUnusedRootDirEntries(clientContext); 1208 1209 // Go through the records, syncing them 1210 for(std::vector<Location *>::const_iterator 1211 i(mLocations.begin()); 1212 i != mLocations.end(); ++i) 1213 { 1214 // Set current and new ID map pointers 1215 // in the context 1216 clientContext.SetIDMaps(mCurrentIDMaps[(*i)->mIDMapIndex], 1217 mNewIDMaps[(*i)->mIDMapIndex]); 1218 1219 // Set exclude lists (context doesn't 1220 // take ownership) 1221 clientContext.SetExcludeLists( 1222 (*i)->mpExcludeFiles, 1223 (*i)->mpExcludeDirs); 1224 1225 // Sync the directory 1226 (*i)->mpDirectoryRecord->SyncDirectory( 1227 params, 1228 BackupProtocolClientListDirectory::RootDirectory, 1229 (*i)->mPath, std::string("/") + (*i)->mName); 1230 1231 // Unset exclude lists (just in case) 1232 clientContext.SetExcludeLists(0, 0); 1233 } 1234 1235 // Errors reading any files? 1236 if(params.mReadErrorsOnFilesystemObjects) 1237 { 1238 // Notify administrator 1239 NotifySysadmin(NotifyEvent_ReadError); 1240 } 1241 else 1242 { 1243 // Unset the read error flag, so the // error is reported again if it 1244 // happens again 1245 mNotificationsSent[NotifyEvent_ReadError] = false; 1246 } 1247 1248 // Perform any deletions required -- these are 1249 // delayed until the end to allow renaming to 1250 // happen neatly. 1251 clientContext.PerformDeletions(); 1252 1253 // Close any open connection 1254 clientContext.CloseAnyOpenConnection(); 1255 1256 // Get the new store marker 1257 mClientStoreMarker = clientContext.GetClientStoreMarker(); 1258 mStorageLimitExceeded = clientContext.StorageLimitExceeded(); 1259 mReadErrorsOnFilesystemObjects = 1260 params.mReadErrorsOnFilesystemObjects; 1261 1262 if(!mStorageLimitExceeded) 1263 { 1264 // The start time of the next run is the end time of this 1265 // run. This is only done if the storage limit wasn't 1266 // exceeded (as things won't have been done properly if 1267 // it was) 1268 mLastSyncTime = syncPeriodEnd; 1269 } 1270 1271 // Commit the ID Maps 1272 CommitIDMapsAfterSync(); 1273 1274 // Log 1275 BOX_NOTICE("Finished scan of local files"); 1276 } 1224 1277 1225 1278 // -------------------------------------------------------------------------- … … 2461 2514 BOX_NOTICE("Deleting unused locations from store root..."); 2462 2515 BackupProtocolClient &connection(rContext.GetConnection()); 2463 for(std::vector<std::pair<int64_t,std::string> >::iterator i(mUnusedRootDirEntries.begin()); i != mUnusedRootDirEntries.end(); ++i) 2516 for(std::vector<std::pair<int64_t,std::string> >::iterator 2517 i(mUnusedRootDirEntries.begin()); 2518 i != mUnusedRootDirEntries.end(); ++i) 2464 2519 { 2465 2520 connection.QueryDeleteDirectory(i->first); 2466 2467 // Log this 2468 BOX_NOTICE("Deleted " << i->second << " (ID " << i->first 2469 << ") from store root"); 2521 rContext.GetProgressNotifier().NotifyFileDeleted( 2522 i->first, i->second); 2470 2523 } 2471 2524 … … 2738 2791 // 2739 2792 // Function 2740 // Name: BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) 2741 // Purpose: Serializes remote directory and file information into a stream of bytes, using an Archive abstraction. 2742 // 2793 // Name: BackupDaemon::SerializeStoreObjectInfo( 2794 // box_time_t theLastSyncTime, 2795 // box_time_t theNextSyncTime) 2796 // Purpose: Serializes remote directory and file information 2797 // into a stream of bytes, using an Archive 2798 // abstraction. 2743 2799 // Created: 2005/04/11 2744 2800 // … … 2749 2805 static const int STOREOBJECTINFO_VERSION = 2; 2750 2806 2751 bool BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const 2807 bool BackupDaemon::SerializeStoreObjectInfo(box_time_t theLastSyncTime, 2808 box_time_t theNextSyncTime) const 2752 2809 { 2753 2810 if(!GetConfiguration().KeyExists("StoreObjectInfoFile")) … … 2778 2835 anArchive.Write(STOREOBJECTINFO_VERSION); 2779 2836 anArchive.Write(GetLoadedConfigModifiedTime()); 2780 anArchive.Write( aClientStoreMarker);2837 anArchive.Write(mClientStoreMarker); 2781 2838 anArchive.Write(theLastSyncTime); 2782 2839 anArchive.Write(theNextSyncTime); … … 2830 2887 catch(std::exception &e) 2831 2888 { 2832 BOX_ERROR("Internal error writing store object " 2833 "info file (" << StoreObjectInfoFile << "): " 2834 << e.what()); 2889 BOX_ERROR("Failed to write StoreObjectInfoFile: " << 2890 StoreObjectInfoFile << ": " << e.what()); 2835 2891 } 2836 2892 catch(...) 2837 2893 { 2838 BOX_ERROR("Internal error writing store object " 2839 "info file (" << StoreObjectInfoFile << "): " 2840 "unknown error"); 2894 BOX_ERROR("Failed to write StoreObjectInfoFile: " << 2895 StoreObjectInfoFile << ": unknown error"); 2841 2896 } 2842 2897 … … 2847 2902 // 2848 2903 // Function 2849 // Name: BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime) 2850 // Purpose: Deserializes remote directory and file information from a stream of bytes, using an Archive abstraction. 2851 // 2904 // Name: BackupDaemon::DeserializeStoreObjectInfo( 2905 // box_time_t & theLastSyncTime, 2906 // box_time_t & theNextSyncTime) 2907 // Purpose: Deserializes remote directory and file information 2908 // from a stream of bytes, using an Archive 2909 // abstraction. 2852 2910 // Created: 2005/04/11 2853 2911 // 2854 2912 // -------------------------------------------------------------------------- 2855 bool BackupDaemon::DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime) 2913 bool BackupDaemon::DeserializeStoreObjectInfo(box_time_t & theLastSyncTime, 2914 box_time_t & theNextSyncTime) 2856 2915 { 2857 2916 // … … 2945 3004 // this is it, go at it 2946 3005 // 2947 anArchive.Read( aClientStoreMarker);3006 anArchive.Read(mClientStoreMarker); 2948 3007 anArchive.Read(theLastSyncTime); 2949 3008 anArchive.Read(theNextSyncTime); … … 3023 3082 DeleteAllLocations(); 3024 3083 3025 aClientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown;3084 mClientStoreMarker = BackupClientContext::ClientStoreMarker_NotKnown; 3026 3085 theLastSyncTime = 0; 3027 3086 theNextSyncTime = 0; -
box/trunk/bin/bbackupd/BackupDaemon.h
r2099 r2181 15 15 #include <memory> 16 16 17 #include "BackupClientDirectoryRecord.h" 17 18 #include "BoxTime.h" 18 19 #include "Daemon.h" 19 #include " BackupClientDirectoryRecord.h"20 #include "Logging.h" 20 21 #include "Socket.h" 21 22 #include "SocketListen.h" 22 23 #include "SocketStream.h" 23 #include "Logging.h" 24 #include "TLSContext.h" 25 24 26 #include "autogen_BackupProtocolClient.h" 25 27 … … 53 55 // methods below do partial (specialized) serialization of 54 56 // client state only 55 bool SerializeStoreObjectInfo( int64_t aClientStoreMarker,56 box_time_t the LastSyncTime, box_time_t theNextSyncTime) const;57 bool DeserializeStoreObjectInfo( int64_t & aClientStoreMarker,58 box_time_t & the LastSyncTime, box_time_t & theNextSyncTime);57 bool SerializeStoreObjectInfo(box_time_t theLastSyncTime, 58 box_time_t theNextSyncTime) const; 59 bool DeserializeStoreObjectInfo(box_time_t & theLastSyncTime, 60 box_time_t & theNextSyncTime); 59 61 bool DeleteStoreObjectInfo() const; 60 62 BackupDaemon(const BackupDaemon &); … … 112 114 void Run2(); 113 115 116 public: 117 void InitCrypto(); 118 void RunSyncNow(); 119 120 private: 114 121 void DeleteAllLocations(); 115 122 void SetupLocations(BackupClientContext &rClientContext, const Configuration &rLocationsConf); … … 206 213 std::vector<std::pair<int64_t,std::string> > mUnusedRootDirEntries; 207 214 215 int64_t mClientStoreMarker; 216 bool mStorageLimitExceeded; 217 bool mReadErrorsOnFilesystemObjects; 218 box_time_t mLastSyncTime; 219 TLSContext mTlsContext; 220 208 221 public: 209 222 bool StopRun() { return this->Daemon::StopRun(); } 223 bool StorageLimitExceeded() { return mStorageLimitExceeded; } 210 224 211 225 private: … … 428 442 } 429 443 } 444 virtual void NotifyDirectoryDeleted( 445 int64_t ObjectID, 446 const std::string& rRemotePath) 447 { 448 if (mLogAllFileAccess) 449 { 450 BOX_NOTICE("Deleted directory: " << rRemotePath << 451 " (ID " << BOX_FORMAT_OBJECTID(ObjectID) << 452 ")"); 453 } 454 } 455 virtual void NotifyFileDeleted( 456 int64_t ObjectID, 457 const std::string& rRemotePath) 458 { 459 if (mLogAllFileAccess) 460 { 461 BOX_NOTICE("Deleted file: " << rRemotePath << 462 " (ID " << BOX_FORMAT_OBJECTID(ObjectID) << 463 ")"); 464 } 465 } 430 466 431 467 #ifdef WIN32
