summaryrefslogtreecommitdiff
path: root/lib/backupstore/BackupStoreInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/backupstore/BackupStoreInfo.cpp')
-rw-r--r--lib/backupstore/BackupStoreInfo.cpp268
1 files changed, 155 insertions, 113 deletions
diff --git a/lib/backupstore/BackupStoreInfo.cpp b/lib/backupstore/BackupStoreInfo.cpp
index b6714709..efe3f7bb 100644
--- a/lib/backupstore/BackupStoreInfo.cpp
+++ b/lib/backupstore/BackupStoreInfo.cpp
@@ -34,22 +34,24 @@
//
// --------------------------------------------------------------------------
BackupStoreInfo::BackupStoreInfo()
- : mAccountID(-1),
- mDiscSet(-1),
- mReadOnly(true),
- mIsModified(false),
- mClientStoreMarker(0),
- mLastObjectIDUsed(-1),
- mBlocksUsed(0),
- mBlocksInCurrentFiles(0),
- mBlocksInOldFiles(0),
- mBlocksInDeletedFiles(0),
- mBlocksInDirectories(0),
- mNumFiles(0),
- mNumOldFiles(0),
- mNumDeletedFiles(0),
- mNumDirectories(0),
- mAccountEnabled(true)
+: mAccountID(-1),
+ mDiscSet(-1),
+ mReadOnly(true),
+ mIsModified(false),
+ mClientStoreMarker(0),
+ mLastObjectIDUsed(-1),
+ mBlocksUsed(0),
+ mBlocksInCurrentFiles(0),
+ mBlocksInOldFiles(0),
+ mBlocksInDeletedFiles(0),
+ mBlocksInDirectories(0),
+ mBlocksSoftLimit(0),
+ mBlocksHardLimit(0),
+ mNumCurrentFiles(0),
+ mNumOldFiles(0),
+ mNumDeletedFiles(0),
+ mNumDirectories(0),
+ mAccountEnabled(true)
{
}
@@ -92,6 +94,31 @@ void BackupStoreInfo::CreateNew(int32_t AccountID, const std::string &rRootDir,
info.Save(false);
}
+BackupStoreInfo::BackupStoreInfo(int32_t AccountID, const std::string &FileName,
+ int64_t BlockSoftLimit, int64_t BlockHardLimit)
+: mAccountID(AccountID),
+ mDiscSet(-1),
+ mFilename(FileName),
+ mReadOnly(false),
+ mIsModified(false),
+ mClientStoreMarker(0),
+ mLastObjectIDUsed(0),
+ mBlocksUsed(0),
+ mBlocksInCurrentFiles(0),
+ mBlocksInOldFiles(0),
+ mBlocksInDeletedFiles(0),
+ mBlocksInDirectories(0),
+ mBlocksSoftLimit(BlockSoftLimit),
+ mBlocksHardLimit(BlockHardLimit),
+ mNumCurrentFiles(0),
+ mNumOldFiles(0),
+ mNumDeletedFiles(0),
+ mNumDirectories(0),
+ mAccountEnabled(true)
+{
+ mExtraData.SetForReading(); // extra data is empty in this case
+}
+
// --------------------------------------------------------------------------
//
// Function
@@ -108,16 +135,31 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID,
{
// 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));
+ std::auto_ptr<BackupStoreInfo> info = Load(*rf, fn, ReadOnly);
+
+ // Check it
+ if(info->GetAccountID() != AccountID)
+ {
+ THROW_FILE_ERROR("Found wrong account ID in store info",
+ fn, BackupStoreException, BadStoreInfoOnLoad);
+ }
+
+ info->mDiscSet = DiscSet;
+ return info;
+}
+std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(IOStream& rStream,
+ const std::string FileName, bool ReadOnly)
+{
// Read in format and version
int32_t magic;
- if(!rf->ReadFullBuffer(&magic, sizeof(magic), 0))
+ if(!rStream.ReadFullBuffer(&magic, sizeof(magic), 0))
{
THROW_FILE_ERROR("Failed to read store info file: "
- "short read of magic number", fn,
+ "short read of magic number", FileName,
BackupStoreException, CouldNotLoadStoreInfo);
}
@@ -135,16 +177,14 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID,
{
THROW_FILE_ERROR("Failed to read store info file: "
"unknown magic " << BOX_FORMAT_HEX32(ntohl(magic)),
- fn, BackupStoreException, BadStoreInfoOnLoad);
+ FileName, BackupStoreException, BadStoreInfoOnLoad);
}
// Make new object
std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo);
-
+
// Put in basic location info
- info->mAccountID = AccountID;
- info->mDiscSet = DiscSet;
- info->mFilename = fn;
+ info->mFilename = FileName;
info->mReadOnly = ReadOnly;
int64_t numDelObj = 0;
@@ -152,23 +192,17 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID,
{
// Read in a header
info_StreamFormat_1 hdr;
- rf->Seek(0, IOStream::SeekType_Absolute);
+ rStream.Seek(0, IOStream::SeekType_Absolute);
- if(!rf->ReadFullBuffer(&hdr, sizeof(hdr),
+ if(!rStream.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);
+ FileName, BackupStoreException, CouldNotLoadStoreInfo);
}
-
+
// Insert info from file
+ info->mAccountID = ntohl(hdr.mAccountID);
info->mClientStoreMarker = box_ntoh64(hdr.mClientStoreMarker);
info->mLastObjectIDUsed = box_ntoh64(hdr.mLastObjectIDUsed);
info->mBlocksUsed = box_ntoh64(hdr.mBlocksUsed);
@@ -177,24 +211,16 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID,
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);
+ Archive archive(rStream, 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->mAccountID);
archive.Read(info->mAccountName);
archive.Read(info->mClientStoreMarker);
archive.Read(info->mLastObjectIDUsed);
@@ -205,35 +231,35 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID,
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);
+ archive.Read(info->mNumCurrentFiles);
+ archive.Read(info->mNumOldFiles);
+ archive.Read(info->mNumDeletedFiles);
+ archive.Read(info->mNumDirectories);
+ archive.Read(numDelObj);
}
// Then load the list of deleted directories
if(numDelObj > 0)
{
int64_t objs[NUM_DELETED_DIRS_BLOCK];
-
+
int64_t toload = numDelObj;
while(toload > 0)
{
// How many in this one?
int b = (toload > NUM_DELETED_DIRS_BLOCK)?NUM_DELETED_DIRS_BLOCK:((int)(toload));
-
- if(!rf->ReadFullBuffer(objs, b * sizeof(int64_t), 0 /* not interested in bytes read if this fails */))
+
+ if(!rStream.ReadFullBuffer(objs, b * sizeof(int64_t), 0 /* not interested in bytes read if this fails */))
{
THROW_EXCEPTION(BackupStoreException, CouldNotLoadStoreInfo)
}
-
+
// Add them
for(int t = 0; t < b; ++t)
{
info->mDeletedDirectories.push_back(box_ntoh64(objs[t]));
}
-
+
// Number loaded
toload -= b;
}
@@ -247,24 +273,24 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::Load(int32_t AccountID,
if(v2)
{
- Archive archive(*rf, IOStream::TimeOutInfinite);
+ Archive archive(rStream, 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();
+ IOStream::pos_type bytesLeft = rStream.BytesLeftToRead();
if (bytesLeft > 0)
{
- rf->CopyStreamTo(info->mExtraData);
+ rStream.CopyStreamTo(info->mExtraData);
}
info->mExtraData.SetForReading();
-
+
// return it to caller
return info;
}
@@ -289,10 +315,10 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration(
{
// Generate the filename
std::string fn(rRootDir + INFO_FILENAME);
-
+
// Make new object
std::auto_ptr<BackupStoreInfo> info(new BackupStoreInfo);
-
+
// Put in basic info
info->mAccountID = AccountID;
info->mAccountName = rAccountName;
@@ -311,7 +337,7 @@ std::auto_ptr<BackupStoreInfo> BackupStoreInfo::CreateForRegeneration(
info->mBlocksSoftLimit = BlockSoftLimit;
info->mBlocksHardLimit = BlockHardLimit;
info->mAccountEnabled = AccountEnabled;
-
+
ExtraData.CopyStreamTo(info->mExtraData);
info->mExtraData.SetForReading();
@@ -341,15 +367,22 @@ void BackupStoreInfo::Save(bool allowOverwrite)
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
-
+
// Then... open a write file
RaidFileWrite rf(mDiscSet, mFilename);
rf.Open(allowOverwrite);
-
+ Save(rf);
+
+ // Commit it to disc, converting it to RAID now
+ rf.Commit(true);
+}
+
+void BackupStoreInfo::Save(IOStream& rOutStream)
+{
// Make header
int32_t magic = htonl(INFO_MAGIC_VALUE_2);
- rf.Write(&magic, sizeof(magic));
- Archive archive(rf, IOStream::TimeOutInfinite);
+ rOutStream.Write(&magic, sizeof(magic));
+ Archive archive(rOutStream, IOStream::TimeOutInfinite);
archive.Write(mAccountID);
archive.Write(mAccountName);
@@ -362,7 +395,7 @@ void BackupStoreInfo::Save(bool allowOverwrite)
archive.Write(mBlocksInDirectories);
archive.Write(mBlocksSoftLimit);
archive.Write(mBlocksHardLimit);
- archive.Write(mNumFiles);
+ archive.Write(mNumCurrentFiles);
archive.Write(mNumOldFiles);
archive.Write(mNumDeletedFiles);
archive.Write(mNumDirectories);
@@ -374,14 +407,14 @@ void BackupStoreInfo::Save(bool allowOverwrite)
if(mDeletedDirectories.size() > 0)
{
int64_t objs[NUM_DELETED_DIRS_BLOCK];
-
+
int tosave = mDeletedDirectories.size();
std::vector<int64_t>::iterator i(mDeletedDirectories.begin());
while(tosave > 0)
{
// How many in this one?
int b = (tosave > NUM_DELETED_DIRS_BLOCK)?NUM_DELETED_DIRS_BLOCK:((int)(tosave));
-
+
// Add them
for(int t = 0; t < b; ++t)
{
@@ -390,23 +423,20 @@ void BackupStoreInfo::Save(bool allowOverwrite)
i++;
}
- // Write
- rf.Write(objs, b * sizeof(int64_t));
-
+ // Write
+ rOutStream.Write(objs, b * sizeof(int64_t));
+
// Number saved
tosave -= b;
}
}
-
+
archive.Write(mAccountEnabled);
-
+
mExtraData.Seek(0, IOStream::SeekType_Absolute);
- mExtraData.CopyStreamTo(rf);
+ mExtraData.CopyStreamTo(rOutStream);
mExtraData.Seek(0, IOStream::SeekType_Absolute);
- // Commit it to disc, converting it to RAID now
- rf.Commit(true);
-
// Mark is as not modified
mIsModified = false;
}
@@ -426,7 +456,6 @@ int BackupStoreInfo::ReportChangesTo(BackupStoreInfo& rOldInfo)
COMPARE(AccountID);
COMPARE(AccountName);
- COMPARE(LastObjectIDUsed);
COMPARE(BlocksUsed);
COMPARE(BlocksInCurrentFiles);
COMPARE(BlocksInOldFiles);
@@ -434,32 +463,47 @@ int BackupStoreInfo::ReportChangesTo(BackupStoreInfo& rOldInfo)
COMPARE(BlocksInDirectories);
COMPARE(BlocksSoftLimit);
COMPARE(BlocksHardLimit);
- COMPARE(NumFiles);
+ COMPARE(NumCurrentFiles);
COMPARE(NumOldFiles);
COMPARE(NumDeletedFiles);
COMPARE(NumDirectories);
#undef COMPARE
+ if (rOldInfo.GetLastObjectIDUsed() != GetLastObjectIDUsed())
+ {
+ BOX_NOTICE("LastObjectIDUsed changed from " <<
+ rOldInfo.GetLastObjectIDUsed() << " to " <<
+ GetLastObjectIDUsed());
+ // Not important enough to be an error
+ // numChanges++;
+ }
+
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; \
+void BackupStoreInfo::ApplyDelta(int64_t& field, const std::string& field_name,
+ const int64_t delta)
+{
+ if(mReadOnly)
+ {
+ THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly);
+ }
+
+ if((field + delta) < 0)
+ {
+ THROW_EXCEPTION_MESSAGE(BackupStoreException,
+ StoreInfoBlockDeltaMakesValueNegative,
+ "Failed to reduce " << field_name << " from " <<
+ field << " by " << delta);
+ }
+
+ field += delta;
mIsModified = true;
+}
+
+#define APPLY_DELTA(field, delta) \
+ ApplyDelta(field, #field, delta)
// --------------------------------------------------------------------------
//
@@ -527,9 +571,9 @@ void BackupStoreInfo::ChangeBlocksInDirectories(int64_t Delta)
APPLY_DELTA(mBlocksInDirectories, Delta);
}
-void BackupStoreInfo::AdjustNumFiles(int64_t increase)
+void BackupStoreInfo::AdjustNumCurrentFiles(int64_t increase)
{
- APPLY_DELTA(mNumFiles, increase);
+ APPLY_DELTA(mNumCurrentFiles, increase);
}
void BackupStoreInfo::AdjustNumOldFiles(int64_t increase)
@@ -563,13 +607,13 @@ void BackupStoreInfo::CorrectAllUsedValues(int64_t Used, int64_t InOldFiles, int
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
-
+
// Set the values
mBlocksUsed = Used;
mBlocksInOldFiles = InOldFiles;
mBlocksInDeletedFiles = InDeletedFiles;
mBlocksInDirectories = InDirectories;
-
+
mIsModified = true;
}
@@ -588,9 +632,8 @@ void BackupStoreInfo::AddDeletedDirectory(int64_t DirID)
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
-
+
mDeletedDirectories.push_back(DirID);
-
mIsModified = true;
}
@@ -608,14 +651,14 @@ void BackupStoreInfo::RemovedDeletedDirectory(int64_t DirID)
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
-
+
std::vector<int64_t>::iterator i(std::find(mDeletedDirectories.begin(), mDeletedDirectories.end(), DirID));
if(i == mDeletedDirectories.end())
{
THROW_EXCEPTION(BackupStoreException, StoreInfoDirNotInList)
}
+
mDeletedDirectories.erase(i);
-
mIsModified = true;
}
@@ -636,7 +679,7 @@ void BackupStoreInfo::ChangeLimits(int64_t BlockSoftLimit, int64_t BlockHardLimi
mBlocksSoftLimit = BlockSoftLimit;
mBlocksHardLimit = BlockHardLimit;
-
+
mIsModified = true;
}
@@ -655,15 +698,16 @@ int64_t BackupStoreInfo::AllocateObjectID()
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
+
if(mLastObjectIDUsed < 0)
{
THROW_EXCEPTION(BackupStoreException, StoreInfoNotInitialised)
}
-
+
+ mIsModified = true;
+
// Return the next object ID
return ++mLastObjectIDUsed;
-
- mIsModified = true;
}
@@ -682,9 +726,8 @@ void BackupStoreInfo::SetClientStoreMarker(int64_t ClientStoreMarker)
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
-
+
mClientStoreMarker = ClientStoreMarker;
-
mIsModified = true;
}
@@ -703,9 +746,8 @@ void BackupStoreInfo::SetAccountName(const std::string& rName)
{
THROW_EXCEPTION(BackupStoreException, StoreInfoIsReadOnly)
}
-
+
mAccountName = rName;
-
mIsModified = true;
}