diff options
Diffstat (limited to 'lib/backupstore/BackupStoreInfo.cpp')
-rw-r--r-- | lib/backupstore/BackupStoreInfo.cpp | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/lib/backupstore/BackupStoreInfo.cpp b/lib/backupstore/BackupStoreInfo.cpp index 1d55fdf0..c58ae99a 100644 --- a/lib/backupstore/BackupStoreInfo.cpp +++ b/lib/backupstore/BackupStoreInfo.cpp @@ -11,6 +11,10 @@ #include <algorithm> +<<<<<<< HEAD +======= +#include "Archive.h" +>>>>>>> 0.12 #include "BackupStoreInfo.h" #include "BackupStoreException.h" #include "RaidFileWrite.h" @@ -18,6 +22,7 @@ #include "MemLeakFindOn.h" +<<<<<<< HEAD // set packing to one byte #ifdef STRUCTURE_PACKING_FOR_WIRE_USE_HEADERS #include "BeginStructPackForWire.h" @@ -55,14 +60,19 @@ typedef struct END_STRUCTURE_PACKING_FOR_WIRE #endif +======= +>>>>>>> 0.12 #ifdef BOX_RELEASE_BUILD #define NUM_DELETED_DIRS_BLOCK 256 #else #define NUM_DELETED_DIRS_BLOCK 2 #endif +<<<<<<< HEAD #define INFO_FILENAME "info" +======= +>>>>>>> 0.12 // -------------------------------------------------------------------------- // // Function @@ -79,8 +89,20 @@ BackupStoreInfo::BackupStoreInfo() mClientStoreMarker(0), mLastObjectIDUsed(-1), mBlocksUsed(0), +<<<<<<< HEAD mBlocksInOldFiles(0), mBlocksInDeletedFiles(0) +======= + mBlocksInCurrentFiles(0), + mBlocksInOldFiles(0), + mBlocksInDeletedFiles(0), + mBlocksInDirectories(0), + mNumFiles(0), + mNumOldFiles(0), + mNumDeletedFiles(0), + mNumDirectories(0), + mAccountEnabled(true) +>>>>>>> 0.12 { } @@ -106,6 +128,7 @@ BackupStoreInfo::~BackupStoreInfo() // -------------------------------------------------------------------------- void BackupStoreInfo::CreateNew(int32_t AccountID, const std::string &rRootDir, int DiscSet, int64_t BlockSoftLimit, int64_t BlockHardLimit) { +<<<<<<< HEAD // Initial header (is entire file) info_StreamFormat hdr = { htonl(INFO_MAGIC_VALUE), // mMagicValue @@ -139,11 +162,29 @@ void BackupStoreInfo::CreateNew(int32_t AccountID, const std::string &rRootDir, rf.Commit(true); // Done. +======= + BackupStoreInfo info; + info.mAccountID = AccountID; + info.mDiscSet = DiscSet; + info.mReadOnly = false; + info.mLastObjectIDUsed = 1; + info.mBlocksSoftLimit = BlockSoftLimit; + info.mBlocksHardLimit = BlockHardLimit; + + // Generate the filename + ASSERT(rRootDir[rRootDir.size() - 1] == '/' || + rRootDir[rRootDir.size() - 1] == DIRECTORY_SEPARATOR_ASCHAR); + info.mFilename = rRootDir + INFO_FILENAME; + info.mExtraData.SetForReading(); // extra data is empty in this case + + info.Save(false); +>>>>>>> 0.12 } // -------------------------------------------------------------------------- // // Function +<<<<<<< HEAD // Name: BackupStoreInfo::Load(int32_t, const std::string &, int, bool) // Purpose: Loads the info from disc, given the root information. Can be marked as read only. // Created: 2003/08/28 @@ -170,6 +211,51 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, const st THROW_EXCEPTION(BackupStoreException, BadStoreInfoOnLoad) } +======= +// Name: BackupStoreInfo::Load(int32_t, const std::string &, +// int, bool) +// Purpose: Loads the info from disc, given the root +// information. Can be marked as read only. +// Created: 2003/08/28 +// +// -------------------------------------------------------------------------- +std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, + const std::string &rRootDir, int DiscSet, bool ReadOnly, + int64_t *pRevisionID) +{ + // Generate the filename + std::string fn(rRootDir + INFO_FILENAME); + + // Open the file for reading (passing on optional request for revision ID) + std::auto_ptr<RaidFileRead> rf(RaidFileRead::Open(DiscSet, fn, pRevisionID)); + + // Read in format and version + int32_t magic; + if(!rf->ReadFullBuffer(&magic, sizeof(magic), 0)) + { + THROW_FILE_ERROR("Failed to read store info file: " + "short read of magic number", fn, + BackupStoreException, CouldNotLoadStoreInfo); + } + + bool v1 = false, v2 = false; + + if(ntohl(magic) == INFO_MAGIC_VALUE_1) + { + v1 = true; + } + else if(ntohl(magic) == INFO_MAGIC_VALUE_2) + { + v2 = true; + } + else + { + THROW_FILE_ERROR("Failed to read store info file: " + "unknown magic " << BOX_FORMAT_HEX32(ntohl(magic)), + fn, BackupStoreException, BadStoreInfoOnLoad); + } + +>>>>>>> 0.12 // Make new object std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo); @@ -178,6 +264,7 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, const st info->mDiscSet = DiscSet; info->mFilename = fn; info->mReadOnly = ReadOnly; +<<<<<<< HEAD // Insert info from file info->mClientStoreMarker = box_ntoh64(hdr.mClientStoreMarker); @@ -193,6 +280,75 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, const st int64_t numDelObj = box_ntoh64(hdr.mNumberDeletedDirectories); // Then load them in +======= + int64_t numDelObj = 0; + + if (v1) + { + // Read in a header + info_StreamFormat_1 hdr; + rf->Seek(0, IOStream::SeekType_Absolute); + + if(!rf->ReadFullBuffer(&hdr, sizeof(hdr), + 0 /* not interested in bytes read if this fails */)) + { + THROW_FILE_ERROR("Failed to read store info header", + fn, BackupStoreException, CouldNotLoadStoreInfo); + } + + // Check it + if((int32_t)ntohl(hdr.mAccountID) != AccountID) + { + THROW_FILE_ERROR("Found wrong account ID in store info", + fn, BackupStoreException, BadStoreInfoOnLoad); + } + + // Insert info from file + info->mClientStoreMarker = box_ntoh64(hdr.mClientStoreMarker); + info->mLastObjectIDUsed = box_ntoh64(hdr.mLastObjectIDUsed); + info->mBlocksUsed = box_ntoh64(hdr.mBlocksUsed); + info->mBlocksInOldFiles = box_ntoh64(hdr.mBlocksInOldFiles); + info->mBlocksInDeletedFiles = box_ntoh64(hdr.mBlocksInDeletedFiles); + info->mBlocksInDirectories = box_ntoh64(hdr.mBlocksInDirectories); + info->mBlocksSoftLimit = box_ntoh64(hdr.mBlocksSoftLimit); + info->mBlocksHardLimit = box_ntoh64(hdr.mBlocksHardLimit); + + // Load up array of deleted objects + numDelObj = box_ntoh64(hdr.mNumberDeletedDirectories); + } + else if(v2) + { + Archive archive(*rf, IOStream::TimeOutInfinite); + + // Check it + int32_t FileAccountID; + archive.Read(FileAccountID); + if (FileAccountID != AccountID) + { + THROW_FILE_ERROR("Found wrong account ID in store " + "info: " << BOX_FORMAT_HEX32(FileAccountID), + fn, BackupStoreException, BadStoreInfoOnLoad); + } + + archive.Read(info->mAccountName); + archive.Read(info->mClientStoreMarker); + archive.Read(info->mLastObjectIDUsed); + archive.Read(info->mBlocksUsed); + archive.Read(info->mBlocksInCurrentFiles); + archive.Read(info->mBlocksInOldFiles); + archive.Read(info->mBlocksInDeletedFiles); + archive.Read(info->mBlocksInDirectories); + archive.Read(info->mBlocksSoftLimit); + archive.Read(info->mBlocksHardLimit); + archive.Read(info->mNumFiles); + archive.Read(info->mNumOldFiles); + archive.Read(info->mNumDeletedFiles); + archive.Read(info->mNumDirectories); + archive.Read(numDelObj); + } + + // Then load the list of deleted directories +>>>>>>> 0.12 if(numDelObj > 0) { int64_t objs[NUM_DELETED_DIRS_BLOCK]; @@ -224,6 +380,29 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, const st { THROW_EXCEPTION(BackupStoreException, BadStoreInfoOnLoad) } +<<<<<<< HEAD +======= + + if(v2) + { + Archive archive(*rf, IOStream::TimeOutInfinite); + archive.ReadIfPresent(info->mAccountEnabled, true); + } + else + { + info->mAccountEnabled = true; + } + + // If there's any data left in the info file, from future additions to + // the file format, then we need to load it so that it won't be lost when + // we resave the file. + IOStream::pos_type bytesLeft = rf->BytesLeftToRead(); + if (bytesLeft > 0) + { + rf->CopyStreamTo(info->mExtraData); + } + info->mExtraData.SetForReading(); +>>>>>>> 0.12 // return it to caller return info; @@ -238,18 +417,33 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID, const st // Created: 23/4/04 // // -------------------------------------------------------------------------- +<<<<<<< HEAD std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration(int32_t AccountID, const std::string &rRootDir, int DiscSet, int64_t LastObjectID, int64_t BlocksUsed, int64_t BlocksInOldFiles, int64_t BlocksInDeletedFiles, int64_t BlocksInDirectories, int64_t BlockSoftLimit, int64_t BlockHardLimit) { // Generate the filename std::string fn(rRootDir + DIRECTORY_SEPARATOR INFO_FILENAME); +======= +std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration( + int32_t AccountID, const std::string& rAccountName, + const std::string &rRootDir, int DiscSet, + int64_t LastObjectID, int64_t BlocksUsed, + int64_t BlocksInCurrentFiles, int64_t BlocksInOldFiles, + int64_t BlocksInDeletedFiles, int64_t BlocksInDirectories, + int64_t BlockSoftLimit, int64_t BlockHardLimit, + bool AccountEnabled, IOStream& ExtraData) +{ + // Generate the filename + std::string fn(rRootDir + INFO_FILENAME); +>>>>>>> 0.12 // Make new object std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo); // Put in basic info info->mAccountID = AccountID; +<<<<<<< HEAD info->mDiscSet = DiscSet; info->mFilename = fn; info->mReadOnly = false; @@ -258,12 +452,32 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration(int32_t Ac info->mClientStoreMarker = 0; info->mLastObjectIDUsed = LastObjectID; info->mBlocksUsed = BlocksUsed; +======= + info->mAccountName = rAccountName; + info->mDiscSet = DiscSet; + info->mFilename = fn; + info->mReadOnly = false; + + // Insert info starting info + info->mClientStoreMarker = 0; + info->mLastObjectIDUsed = LastObjectID; + info->mBlocksUsed = BlocksUsed; + info->mBlocksInCurrentFiles = BlocksInCurrentFiles; +>>>>>>> 0.12 info->mBlocksInOldFiles = BlocksInOldFiles; info->mBlocksInDeletedFiles = BlocksInDeletedFiles; info->mBlocksInDirectories = BlocksInDirectories; info->mBlocksSoftLimit = BlockSoftLimit; info->mBlocksHardLimit = BlockHardLimit; +<<<<<<< HEAD + +======= + info->mAccountEnabled = AccountEnabled; + ExtraData.CopyStreamTo(info->mExtraData); + info->mExtraData.SetForReading(); + +>>>>>>> 0.12 // return it to caller return info; } @@ -272,12 +486,20 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration(int32_t Ac // -------------------------------------------------------------------------- // // Function +<<<<<<< HEAD // Name: BackupStoreInfo::Save() +======= +// Name: BackupStoreInfo::Save(bool allowOverwrite) +>>>>>>> 0.12 // Purpose: Save modified info back to disc // Created: 2003/08/28 // // -------------------------------------------------------------------------- +<<<<<<< HEAD void BackupStoreInfo::Save() +======= +void BackupStoreInfo::Save(bool allowOverwrite) +>>>>>>> 0.12 { // Make sure we're initialised (although should never come to this) if(mFilename.empty() || mAccountID == -1 || mDiscSet == -1) @@ -293,6 +515,7 @@ void BackupStoreInfo::Save() // Then... open a write file RaidFileWrite rf(mDiscSet, mFilename); +<<<<<<< HEAD rf.Open(true); // allow overwriting // Make header @@ -314,6 +537,34 @@ void BackupStoreInfo::Save() // Write header rf.Write(&hdr, sizeof(hdr)); +======= + rf.Open(allowOverwrite); + + // Make header + int32_t magic = htonl(INFO_MAGIC_VALUE_2); + rf.Write(&magic, sizeof(magic)); + Archive archive(rf, IOStream::TimeOutInfinite); + + archive.Write(mAccountID); + archive.Write(mAccountName); + archive.Write(mClientStoreMarker); + archive.Write(mLastObjectIDUsed); + archive.Write(mBlocksUsed); + archive.Write(mBlocksInCurrentFiles); + archive.Write(mBlocksInOldFiles); + archive.Write(mBlocksInDeletedFiles); + archive.Write(mBlocksInDirectories); + archive.Write(mBlocksSoftLimit); + archive.Write(mBlocksHardLimit); + archive.Write(mNumFiles); + archive.Write(mNumOldFiles); + archive.Write(mNumDeletedFiles); + archive.Write(mNumDirectories); + + int64_t numDelObj = mDeletedDirectories.size(); + archive.Write(numDelObj); + +>>>>>>> 0.12 // Write the deleted object list if(mDeletedDirectories.size() > 0) { @@ -341,6 +592,15 @@ void BackupStoreInfo::Save() tosave -= b; } } +<<<<<<< HEAD +======= + + archive.Write(mAccountEnabled); + + mExtraData.Seek(0, IOStream::SeekType_Absolute); + mExtraData.CopyStreamTo(rf); + mExtraData.Seek(0, IOStream::SeekType_Absolute); +>>>>>>> 0.12 // Commit it to disc, converting it to RAID now rf.Commit(true); @@ -349,7 +609,59 @@ void BackupStoreInfo::Save() mIsModified = false; } +<<<<<<< HEAD +======= +int BackupStoreInfo::ReportChangesTo(BackupStoreInfo& rOldInfo) +{ + int numChanges = 0; + + #define COMPARE(attribute) \ + if (rOldInfo.Get ## attribute () != Get ## attribute ()) \ + { \ + BOX_ERROR(#attribute " changed from " << \ + rOldInfo.Get ## attribute () << " to " << \ + Get ## attribute ()); \ + numChanges++; \ + } + + COMPARE(AccountID); + COMPARE(AccountName); + COMPARE(LastObjectIDUsed); + COMPARE(BlocksUsed); + COMPARE(BlocksInCurrentFiles); + COMPARE(BlocksInOldFiles); + COMPARE(BlocksInDeletedFiles); + COMPARE(BlocksInDirectories); + COMPARE(BlocksSoftLimit); + COMPARE(BlocksHardLimit); + COMPARE(NumFiles); + COMPARE(NumOldFiles); + COMPARE(NumDeletedFiles); + COMPARE(NumDirectories); + + #undef COMPARE + + return numChanges; +} + +#define APPLY_DELTA(field, delta) \ + if(mReadOnly) \ + { \ + THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) \ + } \ + \ + if((field + delta) < 0) \ + { \ + THROW_EXCEPTION_MESSAGE(BackupStoreException, \ + StoreInfoBlockDeltaMakesValueNegative, \ + "Failed to reduce " << #field << " from " << \ + field << " by " << delta); \ + } \ + \ + field += delta; \ + mIsModified = true; +>>>>>>> 0.12 // -------------------------------------------------------------------------- // @@ -361,6 +673,7 @@ void BackupStoreInfo::Save() // -------------------------------------------------------------------------- void BackupStoreInfo::ChangeBlocksUsed(int64_t Delta) { +<<<<<<< HEAD if(mReadOnly) { THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) @@ -373,6 +686,23 @@ void BackupStoreInfo::ChangeBlocksUsed(int64_t Delta) mBlocksUsed += Delta; mIsModified = true; +======= + APPLY_DELTA(mBlocksUsed, Delta); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupStoreInfo::ChangeBlocksInCurrentFiles(int32_t) +// Purpose: Change number of blocks in current files, by a delta +// amount +// Created: 2010/08/26 +// +// -------------------------------------------------------------------------- +void BackupStoreInfo::ChangeBlocksInCurrentFiles(int64_t Delta) +{ + APPLY_DELTA(mBlocksInCurrentFiles, Delta); +>>>>>>> 0.12 } // -------------------------------------------------------------------------- @@ -385,6 +715,7 @@ void BackupStoreInfo::ChangeBlocksUsed(int64_t Delta) // -------------------------------------------------------------------------- void BackupStoreInfo::ChangeBlocksInOldFiles(int64_t Delta) { +<<<<<<< HEAD if(mReadOnly) { THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) @@ -397,6 +728,9 @@ void BackupStoreInfo::ChangeBlocksInOldFiles(int64_t Delta) mBlocksInOldFiles += Delta; mIsModified = true; +======= + APPLY_DELTA(mBlocksInOldFiles, Delta); +>>>>>>> 0.12 } // -------------------------------------------------------------------------- @@ -409,6 +743,7 @@ void BackupStoreInfo::ChangeBlocksInOldFiles(int64_t Delta) // -------------------------------------------------------------------------- void BackupStoreInfo::ChangeBlocksInDeletedFiles(int64_t Delta) { +<<<<<<< HEAD if(mReadOnly) { THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) @@ -421,6 +756,9 @@ void BackupStoreInfo::ChangeBlocksInDeletedFiles(int64_t Delta) mBlocksInDeletedFiles += Delta; mIsModified = true; +======= + APPLY_DELTA(mBlocksInDeletedFiles, Delta); +>>>>>>> 0.12 } // -------------------------------------------------------------------------- @@ -433,6 +771,7 @@ void BackupStoreInfo::ChangeBlocksInDeletedFiles(int64_t Delta) // -------------------------------------------------------------------------- void BackupStoreInfo::ChangeBlocksInDirectories(int64_t Delta) { +<<<<<<< HEAD if(mReadOnly) { THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) @@ -447,6 +786,30 @@ void BackupStoreInfo::ChangeBlocksInDirectories(int64_t Delta) mIsModified = true; } +======= + APPLY_DELTA(mBlocksInDirectories, Delta); +} + +void BackupStoreInfo::AdjustNumFiles(int64_t increase) +{ + APPLY_DELTA(mNumFiles, increase); +} + +void BackupStoreInfo::AdjustNumOldFiles(int64_t increase) +{ + APPLY_DELTA(mNumOldFiles, increase); +} + +void BackupStoreInfo::AdjustNumDeletedFiles(int64_t increase) +{ + APPLY_DELTA(mNumDeletedFiles, increase); +} + +void BackupStoreInfo::AdjustNumDirectories(int64_t increase) +{ + APPLY_DELTA(mNumDirectories, increase); +} +>>>>>>> 0.12 // -------------------------------------------------------------------------- // @@ -590,4 +953,26 @@ void BackupStoreInfo::SetClientStoreMarker(int64_t ClientStoreMarker) } +<<<<<<< HEAD +======= +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupStoreInfo::SetAccountName(const std::string&) +// Purpose: Sets the account name +// Created: 2008/08/22 +// +// -------------------------------------------------------------------------- +void BackupStoreInfo::SetAccountName(const std::string& rName) +{ + if(mReadOnly) + { + THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly) + } + + mAccountName = rName; + + mIsModified = true; +} +>>>>>>> 0.12 |