Changeset 2176
- Timestamp:
- 28/05/2008 15:27:21 (4 years ago)
- Location:
- box/trunk/bin/bbstored
- Files:
-
- 2 edited
-
HousekeepStoreAccount.cpp (modified) (17 diffs)
-
HousekeepStoreAccount.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/trunk/bin/bbstored/HousekeepStoreAccount.cpp
r1783 r2176 86 86 // Attempt to lock the account 87 87 std::string writeLockFilename; 88 StoreStructure::MakeWriteLockFilename(mStoreRoot, mStoreDiscSet, writeLockFilename); 88 StoreStructure::MakeWriteLockFilename(mStoreRoot, mStoreDiscSet, 89 writeLockFilename); 89 90 NamedLock writeLock; 90 if(!writeLock.TryAndGetLock(writeLockFilename.c_str(), 0600 /* restrictive file permissions */)) 91 if(!writeLock.TryAndGetLock(writeLockFilename.c_str(), 92 0600 /* restrictive file permissions */)) 91 93 { 92 94 // Couldn't lock the account -- just stop now … … 95 97 96 98 // Load the store info to find necessary info for the housekeeping 97 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(mAccountID, mStoreRoot, mStoreDiscSet, false /* Read/Write */)); 99 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(mAccountID, 100 mStoreRoot, mStoreDiscSet, false /* Read/Write */)); 98 101 99 102 // Calculate how much should be deleted … … 105 108 106 109 // Scan the directory for potential things to delete 107 // This will also remove el egiable items marked with RemoveASAP110 // This will also remove eligible items marked with RemoveASAP 108 111 bool continueHousekeeping = ScanDirectory(BACKUPSTORE_ROOT_DIRECTORY_ID); 109 112 110 // If scan directory stopped for some reason, probably parent instructed to teminate, stop now. 113 // If scan directory stopped for some reason, probably parent 114 // instructed to terminate, stop now. 111 115 if(!continueHousekeeping) 112 116 { 113 // If any files were marked "delete now", then update the size of the store. 114 if(mBlocksUsedDelta != 0 || mBlocksInOldFilesDelta != 0 || mBlocksInDeletedFilesDelta != 0) 117 // If any files were marked "delete now", then update 118 // the size of the store. 119 if(mBlocksUsedDelta != 0 || 120 mBlocksInOldFilesDelta != 0 || 121 mBlocksInDeletedFilesDelta != 0) 115 122 { 116 123 info->ChangeBlocksUsed(mBlocksUsedDelta); … … 125 132 } 126 133 127 // Log any difference in opinion between the values recorded in the store info, and128 // the values just calculated for space usage.134 // Log any difference in opinion between the values recorded in 135 // the store info, and the values just calculated for space usage. 129 136 // BLOCK 130 137 { … … 134 141 int64_t usedDirectories = info->GetBlocksInDirectories(); 135 142 136 // If the counts were wrong, taking into account RemoveASAP items deleted, log a message 137 if((used + mBlocksUsedDelta) != mBlocksUsed || (usedOld + mBlocksInOldFilesDelta) != mBlocksInOldFiles 138 || (usedDeleted + mBlocksInDeletedFilesDelta) != mBlocksInDeletedFiles || usedDirectories != mBlocksInDirectories) 143 // If the counts were wrong, taking into account RemoveASAP 144 // items deleted, log a message 145 if((used + mBlocksUsedDelta) != mBlocksUsed 146 || (usedOld + mBlocksInOldFilesDelta) != mBlocksInOldFiles 147 || (usedDeleted + mBlocksInDeletedFilesDelta) != mBlocksInDeletedFiles 148 || usedDirectories != mBlocksInDirectories) 139 149 { 140 150 // Log this … … 154 164 155 165 // If the current values don't match, store them 156 if(used != mBlocksUsed || usedOld != mBlocksInOldFiles 157 || usedDeleted != mBlocksInDeletedFiles || usedDirectories != (mBlocksInDirectories + mBlocksInDirectoriesDelta)) 166 if(used != mBlocksUsed 167 || usedOld != mBlocksInOldFiles 168 || usedDeleted != mBlocksInDeletedFiles 169 || usedDirectories != (mBlocksInDirectories + mBlocksInDirectoriesDelta)) 158 170 { 159 171 // Set corrected values in store info 160 info->CorrectAllUsedValues(mBlocksUsed, mBlocksInOldFiles, mBlocksInDeletedFiles, mBlocksInDirectories + mBlocksInDirectoriesDelta); 172 info->CorrectAllUsedValues(mBlocksUsed, 173 mBlocksInOldFiles, mBlocksInDeletedFiles, 174 mBlocksInDirectories + mBlocksInDirectoriesDelta); 161 175 info->Save(); 162 176 } 163 177 } 164 178 165 // Reset the delta counts for files, as they will include RemoveASAP flagged files deleted 166 // during the initial scan. 167 int64_t removeASAPBlocksUsedDelta = mBlocksUsedDelta; // keep for reporting 179 // Reset the delta counts for files, as they will include 180 // RemoveASAP flagged files deleted during the initial scan. 181 182 // keep for reporting 183 int64_t removeASAPBlocksUsedDelta = mBlocksUsedDelta; 184 168 185 mBlocksUsedDelta = 0; 169 186 mBlocksInOldFilesDelta = 0; … … 173 190 bool deleteInterrupted = DeleteFiles(); 174 191 175 // If that wasn't interrupted, remove any empty directories which are also marked as deleted in their containing directory 192 // If that wasn't interrupted, remove any empty directories which 193 // are also marked as deleted in their containing directory 176 194 if(!deleteInterrupted) 177 195 { … … 191 209 } 192 210 193 // Make sure the delta's won't cause problems if the counts are really wrong, and 194 // it wasn't fixed because the store was updated during the scan. 211 // Make sure the delta's won't cause problems if the counts are 212 // really wrong, and it wasn't fixed because the store was 213 // updated during the scan. 195 214 if(mBlocksUsedDelta < (0 - info->GetBlocksUsed())) 196 215 { … … 219 238 info->Save(); 220 239 221 // Explicity release the lock (would happen automatically on going out of scope, included for code clarity) 240 // Explicity release the lock (would happen automatically on 241 // going out of scope, included for code clarity) 222 242 writeLock.ReleaseLock(); 223 243 } … … 244 264 // Function 245 265 // Name: HousekeepStoreAccount::ScanDirectory(int64_t) 246 // Purpose: Private. Scan a directory for potenitally deleteable items, and 247 // add them to the list. Returns true if the scan should continue. 266 // Purpose: Private. Scan a directory for potentially deleteable 267 // items, and add them to the list. Returns true if the 268 // scan should continue. 248 269 // Created: 11/12/03 249 270 // … … 254 275 if((--mCountUntilNextInterprocessMsgCheck) <= 0) 255 276 { 256 mCountUntilNextInterprocessMsgCheck = POLL_INTERPROCESS_MSG_CHECK_FREQUENCY; 277 mCountUntilNextInterprocessMsgCheck = 278 POLL_INTERPROCESS_MSG_CHECK_FREQUENCY; 279 257 280 // Check for having to stop 258 if(mrDaemon.CheckForInterProcessMsg(mAccountID)) // include account ID here as the specified account is locked 281 // Include account ID here as the specified account is locked 282 if(mrDaemon.CheckForInterProcessMsg(mAccountID)) 259 283 { 260 284 // Need to abort now … … 269 293 270 294 // Open it. 271 std::auto_ptr<RaidFileRead> dirStream(RaidFileRead::Open(mStoreDiscSet, objectFilename)); 295 std::auto_ptr<RaidFileRead> dirStream(RaidFileRead::Open(mStoreDiscSet, 296 objectFilename)); 272 297 273 298 // Add the size of the directory on disc to the size being calculated … … 291 316 // BLOCK 292 317 { 293 // Remove any files which are marked for removal as soon as they become old294 // or deleted.318 // Remove any files which are marked for removal as soon 319 // as they become old or deleted. 295 320 bool deletedSomething = false; 296 321 do … … 365 390 d.mMarkNumber = en->GetMarkNumber(); 366 391 d.mVersionAgeWithinMark = enVersionAge; 392 d.mIsFlagDeleted = (enFlags & 393 BackupStoreDirectory::Entry::Flags_Deleted) 394 ? true : false; 367 395 368 396 // Add it to the list … … 542 570 // Delete the file 543 571 DeleteFile(i->mInDirectory, i->mObjectID, dir, dirFilename, dirSizeInBlocksOrig); 572 BOX_INFO("Housekeeping removed " << 573 (i->mIsFlagDeleted ? "deleted" : "old") << 574 " file " << BOX_FORMAT_OBJECTID(i->mObjectID) << 575 " from dir " << BOX_FORMAT_OBJECTID(i->mInDirectory)); 544 576 545 577 // Stop if the deletion target has been matched or exceeded … … 787 819 } 788 820 789 // Load up the directory to potentially delete 790 std::string dirFilename; 791 BackupStoreDirectory dir; 792 int64_t dirSizeInBlocks = 0; 793 { 794 MakeObjectFilename(*i, dirFilename); 795 // Check it actually exists (just in case it gets added twice to the list) 796 if(!RaidFileRead::FileExists(mStoreDiscSet, dirFilename)) 797 { 798 // doesn't exist, next! 799 continue; 800 } 801 // load 802 std::auto_ptr<RaidFileRead> dirStream(RaidFileRead::Open(mStoreDiscSet, dirFilename)); 803 dirSizeInBlocks = dirStream->GetDiscUsageInBlocks(); 804 dir.ReadFromStream(*dirStream, IOStream::TimeOutInfinite); 805 } 806 807 // Make sure this directory is actually empty 808 if(dir.GetNumberOfEntries() != 0) 809 { 810 // Not actually empty, try next one 811 continue; 812 } 813 814 // Candiate for deletion... open containing directory 815 std::string containingDirFilename; 816 BackupStoreDirectory containingDir; 817 int64_t containingDirSizeInBlocksOrig = 0; 818 { 819 MakeObjectFilename(dir.GetContainerID(), containingDirFilename); 820 std::auto_ptr<RaidFileRead> containingDirStream(RaidFileRead::Open(mStoreDiscSet, containingDirFilename)); 821 containingDirSizeInBlocksOrig = containingDirStream->GetDiscUsageInBlocks(); 822 containingDir.ReadFromStream(*containingDirStream, IOStream::TimeOutInfinite); 823 } 824 825 // Find the entry 826 BackupStoreDirectory::Entry *pdirentry = containingDir.FindEntryByID(dir.GetObjectID()); 827 if((pdirentry != 0) && ((pdirentry->GetFlags() & BackupStoreDirectory::Entry::Flags_Deleted) != 0)) 828 { 829 // Should be deleted 830 containingDir.DeleteEntry(dir.GetObjectID()); 831 832 // Is the containing dir now a candidate for deletion? 833 if(containingDir.GetNumberOfEntries() == 0) 834 { 835 toExamine.push_back(containingDir.GetObjectID()); 836 } 837 838 // Write revised parent directory 839 RaidFileWrite writeDir(mStoreDiscSet, containingDirFilename); 840 writeDir.Open(true /* allow overwriting */); 841 containingDir.WriteToStream(writeDir); 842 843 // get the disc usage (must do this before commiting it) 844 int64_t dirSize = writeDir.GetDiscUsageInBlocks(); 845 846 // Commit directory 847 writeDir.Commit(BACKUP_STORE_CONVERT_TO_RAID_IMMEDIATELY); 848 849 // adjust usage counts for this directory 850 if(dirSize > 0) 851 { 852 int64_t adjust = dirSize - containingDirSizeInBlocksOrig; 853 mBlocksUsedDelta += adjust; 854 mBlocksInDirectoriesDelta += adjust; 855 } 856 857 // Delete the directory itself 858 { 859 RaidFileWrite del(mStoreDiscSet, dirFilename); 860 del.Delete(); 861 } 862 863 // And adjust usage counts for the directory that's just been deleted 864 mBlocksUsedDelta -= dirSizeInBlocks; 865 mBlocksInDirectoriesDelta -= dirSizeInBlocks; 866 867 // Update count 868 ++mEmptyDirectoriesDeleted; 869 } 821 DeleteEmptyDirectory(*i, toExamine); 870 822 } 871 823 … … 880 832 } 881 833 882 883 884 834 void HousekeepStoreAccount::DeleteEmptyDirectory(int64_t dirId, 835 std::vector<int64_t>& rToExamine) 836 { 837 // Load up the directory to potentially delete 838 std::string dirFilename; 839 BackupStoreDirectory dir; 840 int64_t dirSizeInBlocks = 0; 841 842 // BLOCK 843 { 844 MakeObjectFilename(dirId, dirFilename); 845 // Check it actually exists (just in case it gets 846 // added twice to the list) 847 if(!RaidFileRead::FileExists(mStoreDiscSet, dirFilename)) 848 { 849 // doesn't exist, next! 850 return; 851 } 852 // load 853 std::auto_ptr<RaidFileRead> dirStream( 854 RaidFileRead::Open(mStoreDiscSet, dirFilename)); 855 dirSizeInBlocks = dirStream->GetDiscUsageInBlocks(); 856 dir.ReadFromStream(*dirStream, IOStream::TimeOutInfinite); 857 } 858 859 // Make sure this directory is actually empty 860 if(dir.GetNumberOfEntries() != 0) 861 { 862 // Not actually empty, try next one 863 return; 864 } 865 866 // Candidate for deletion... open containing directory 867 std::string containingDirFilename; 868 BackupStoreDirectory containingDir; 869 int64_t containingDirSizeInBlocksOrig = 0; 870 { 871 MakeObjectFilename(dir.GetContainerID(), containingDirFilename); 872 std::auto_ptr<RaidFileRead> containingDirStream( 873 RaidFileRead::Open(mStoreDiscSet, 874 containingDirFilename)); 875 containingDirSizeInBlocksOrig = 876 containingDirStream->GetDiscUsageInBlocks(); 877 containingDir.ReadFromStream(*containingDirStream, 878 IOStream::TimeOutInfinite); 879 } 880 881 // Find the entry 882 BackupStoreDirectory::Entry *pdirentry = 883 containingDir.FindEntryByID(dir.GetObjectID()); 884 if((pdirentry != 0) && ((pdirentry->GetFlags() & BackupStoreDirectory::Entry::Flags_Deleted) != 0)) 885 { 886 // Should be deleted 887 containingDir.DeleteEntry(dir.GetObjectID()); 888 889 // Is the containing dir now a candidate for deletion? 890 if(containingDir.GetNumberOfEntries() == 0) 891 { 892 rToExamine.push_back(containingDir.GetObjectID()); 893 } 894 895 // Write revised parent directory 896 RaidFileWrite writeDir(mStoreDiscSet, containingDirFilename); 897 writeDir.Open(true /* allow overwriting */); 898 containingDir.WriteToStream(writeDir); 899 900 // get the disc usage (must do this before commiting it) 901 int64_t dirSize = writeDir.GetDiscUsageInBlocks(); 902 903 // Commit directory 904 writeDir.Commit(BACKUP_STORE_CONVERT_TO_RAID_IMMEDIATELY); 905 906 // adjust usage counts for this directory 907 if(dirSize > 0) 908 { 909 int64_t adjust = dirSize - containingDirSizeInBlocksOrig; 910 mBlocksUsedDelta += adjust; 911 mBlocksInDirectoriesDelta += adjust; 912 } 913 914 // Delete the directory itself 915 { 916 RaidFileWrite del(mStoreDiscSet, dirFilename); 917 del.Delete(); 918 } 919 920 BOX_INFO("Housekeeping removed empty deleted dir " << 921 BOX_FORMAT_OBJECTID(dirId)); 922 923 // And adjust usage counts for the directory that's 924 // just been deleted 925 mBlocksUsedDelta -= dirSizeInBlocks; 926 mBlocksInDirectoriesDelta -= dirSizeInBlocks; 927 928 // Update count 929 ++mEmptyDirectoriesDeleted; 930 } 931 } 932 -
box/trunk/bin/bbstored/HousekeepStoreAccount.h
r217 r2176 43 43 bool DeleteFiles(); 44 44 bool DeleteEmptyDirectories(); 45 void DeleteEmptyDirectory(int64_t dirId, 46 std::vector<int64_t>& rToExamine); 45 47 void DeleteFile(int64_t InDirectory, int64_t ObjectID, BackupStoreDirectory &rDirectory, const std::string &rDirectoryFilename, int64_t OriginalDirSizeInBlocks); 46 48 … … 53 55 int32_t mMarkNumber; 54 56 int32_t mVersionAgeWithinMark; // 0 == current, 1 latest old version, etc 57 bool mIsFlagDeleted; // false for files flagged "Old" 55 58 } DelEn; 56 59
Note: See TracChangeset
for help on using the changeset viewer.
