Changeset 2181 for box/trunk/bin/bbackupd/BackupClientDirectoryRecord.cpp
- Timestamp:
- 28/05/2008 16:24:05 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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),
Note: See TracChangeset
for help on using the changeset viewer.
