diff options
author | Chris Wilson <chris+github@qwirx.com> | 2007-09-19 21:58:24 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2007-09-19 21:58:24 +0000 |
commit | 867fbf737760a7764f6095a1b9b7554047c47eb3 (patch) | |
tree | 1bc17e74cfef9352857f62b3ee842fa95a8547a4 /lib/backupclient | |
parent | 41f3230a75e965254ab47e3609f68c8634266d37 (diff) | |
parent | 2ff87143551e6882c90ceaba940a34779b922882 (diff) |
Replace trunk with chris/merge.
Diffstat (limited to 'lib/backupclient')
-rw-r--r-- | lib/backupclient/BackupClientFileAttributes.cpp | 23 | ||||
-rw-r--r-- | lib/backupclient/BackupClientFileAttributes.h | 3 | ||||
-rw-r--r-- | lib/backupclient/BackupClientRestore.cpp | 350 | ||||
-rw-r--r-- | lib/backupclient/BackupClientRestore.h | 4 | ||||
-rw-r--r-- | lib/backupclient/BackupDaemonConfigVerify.cpp | 4 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreDirectory.cpp | 5 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreFile.cpp | 27 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreFile.h | 9 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreFileDiff.cpp | 69 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreFileEncodeStream.cpp | 19 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreFileEncodeStream.h | 2 | ||||
-rw-r--r-- | lib/backupclient/BackupStoreFilenameClear.cpp | 7 |
12 files changed, 404 insertions, 118 deletions
diff --git a/lib/backupclient/BackupClientFileAttributes.cpp b/lib/backupclient/BackupClientFileAttributes.cpp index ba65d57a..925d1620 100644 --- a/lib/backupclient/BackupClientFileAttributes.cpp +++ b/lib/backupclient/BackupClientFileAttributes.cpp @@ -344,8 +344,8 @@ void BackupClientFileAttributes::ReadAttributes(const char *Filename, bool ZeroM // to be true (still aborts), but it can at least hold 2^32. if (winTime >= 0x100000000LL || _gmtime64(&winTime) == 0) { - ::syslog(LOG_ERR, "Invalid Modification Time " - "caught for file: %s", Filename); + BOX_ERROR("Invalid Modification Time caught for " + "file: '" << Filename << "'"); pattr->ModificationTime = 0; } @@ -355,8 +355,8 @@ void BackupClientFileAttributes::ReadAttributes(const char *Filename, bool ZeroM if (winTime > 0x100000000LL || _gmtime64(&winTime) == 0) { - ::syslog(LOG_ERR, "Invalid Attribute Modification " - "Time caught for file: %s", Filename); + BOX_ERROR("Invalid Attribute Modification Time " + "caught for file: '" << Filename << "'"); pattr->AttrModificationTime = 0; } #endif @@ -578,7 +578,8 @@ void BackupClientFileAttributes::FillExtendedAttr(StreamableMemBlock &outputBloc // Created: 2003/10/07 // // -------------------------------------------------------------------------- -void BackupClientFileAttributes::WriteAttributes(const char *Filename) const +void BackupClientFileAttributes::WriteAttributes(const char *Filename, + bool MakeUserWritable) const { // Got something loaded if(GetSize() <= 0) @@ -626,9 +627,8 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename) const } #ifdef WIN32 - ::syslog(LOG_WARNING, - "Cannot create symbolic links on Windows: %s", - Filename); + BOX_WARNING("Cannot create symbolic links on Windows: '" << + Filename << "'"); #else // Make a symlink, first deleting anything in the way ::unlink(Filename); @@ -704,7 +704,12 @@ void BackupClientFileAttributes::WriteAttributes(const char *Filename) const THROW_EXCEPTION(CommonException, OSFileError) } } - + + if (MakeUserWritable) + { + mode |= S_IRWXU; + } + // Apply everything else... (allowable mode flags only) if(::chmod(Filename, mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX)) != 0) // mode must be done last (think setuid) { diff --git a/lib/backupclient/BackupClientFileAttributes.h b/lib/backupclient/BackupClientFileAttributes.h index 62ba2184..fa56ff65 100644 --- a/lib/backupclient/BackupClientFileAttributes.h +++ b/lib/backupclient/BackupClientFileAttributes.h @@ -45,7 +45,8 @@ public: void ReadAttributes(const char *Filename, bool ZeroModificationTimes = false, box_time_t *pModTime = 0, box_time_t *pAttrModTime = 0, int64_t *pFileSize = 0, InodeRefType *pInodeNumber = 0, bool *pHasMultipleLinks = 0); - void WriteAttributes(const char *Filename) const; + void WriteAttributes(const char *Filename, + bool MakeUserWritable = false) const; bool IsSymLink() const; diff --git a/lib/backupclient/BackupClientRestore.cpp b/lib/backupclient/BackupClientRestore.cpp index fbb4ee47..3c03c87c 100644 --- a/lib/backupclient/BackupClientRestore.cpp +++ b/lib/backupclient/BackupClientRestore.cpp @@ -19,6 +19,7 @@ #include <set> #include <limits.h> #include <stdio.h> +#include <errno.h> #include "BackupClientRestore.h" #include "autogen_BackupProtocolClient.h" @@ -206,7 +207,7 @@ typedef struct // Created: 23/11/03 // // -------------------------------------------------------------------------- -static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t DirectoryID, std::string &rLocalDirectoryName, +static int BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t DirectoryID, std::string &rLocalDirectoryName, RestoreParams &Params, RestoreResumeInfo &rLevel) { // If we're resuming... check that we haven't got a next level to look at @@ -223,11 +224,35 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di rLevel.RemoveLevel(); } - // Save the resumption information - Params.mResumeInfo.Save(Params.mRestoreResumeInfoFilename); + // Create the local directory, if not already done. + // Path and owner set later, just use restrictive owner mode. - // Create the local directory (if not already done) -- path and owner set later, just use restrictive owner mode - switch(ObjectExists(rLocalDirectoryName.c_str())) + int exists; + + try + { + exists = ObjectExists(rLocalDirectoryName.c_str()); + } + catch (BoxException &e) + { + BOX_ERROR("Failed to check existence for " << + rLocalDirectoryName << ": " << e.what()); + return Restore_UnknownError; + } + catch(std::exception &e) + { + BOX_ERROR("Failed to check existence for " << + rLocalDirectoryName << ": " << e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to check existence for " << + rLocalDirectoryName << ": unknown error"); + return Restore_UnknownError; + } + + switch(exists) { case ObjectExists_Dir: // Do nothing @@ -235,26 +260,152 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di case ObjectExists_File: { // File exists with this name, which is fun. Get rid of it. - ::printf("WARNING: File present with name '%s', removing out of the way of restored directory. Use specific restore with ID to restore this object.", rLocalDirectoryName.c_str()); + BOX_WARNING("File present with name '" << + rLocalDirectoryName << "', removing " << + "out of the way of restored directory. " + "Use specific restore with ID to " + "restore this object."); if(::unlink(rLocalDirectoryName.c_str()) != 0) { - THROW_EXCEPTION(CommonException, OSFileError); + BOX_ERROR("Failed to delete file " << + rLocalDirectoryName << ": " << + strerror(errno)); + return Restore_UnknownError; } - TRACE1("In restore, directory name collision with file %s", rLocalDirectoryName.c_str()); + BOX_TRACE("In restore, directory name " + "collision with file " << + rLocalDirectoryName); } - // follow through to... (no break) + break; case ObjectExists_NoObject: - if(::mkdir(rLocalDirectoryName.c_str(), S_IRWXU) != 0) - { - THROW_EXCEPTION(CommonException, OSFileError); - } + // we'll create it in a second, after checking + // whether the parent directory exists break; default: ASSERT(false); break; } - - // Fetch the directory listing from the server -- getting a list of files which is approparite to the restore type + + std::string parentDirectoryName(rLocalDirectoryName); + if(parentDirectoryName[parentDirectoryName.size() - 1] == + DIRECTORY_SEPARATOR_ASCHAR) + { + parentDirectoryName.resize(parentDirectoryName.size() - 1); + } + + size_t lastSlash = parentDirectoryName.rfind(DIRECTORY_SEPARATOR_ASCHAR); + + if(lastSlash == std::string::npos) + { + // might be a forward slash separator, + // especially in the unit tests! + lastSlash = parentDirectoryName.rfind('/'); + } + + if(lastSlash != std::string::npos) + { + // the target directory is a deep path, remove the last + // directory name and check that the resulting parent + // exists, otherwise the restore should fail. + parentDirectoryName.resize(lastSlash); + + #ifdef WIN32 + // if the path is a drive letter, then we need to + // add a a backslash to query the root directory. + if (lastSlash == 2 && parentDirectoryName[1] == ':') + { + parentDirectoryName += '\\'; + } + else if (lastSlash == 0) + { + parentDirectoryName += '\\'; + } + #endif + + int parentExists; + + try + { + parentExists = ObjectExists(parentDirectoryName.c_str()); + } + catch (BoxException &e) + { + BOX_ERROR("Failed to check existence for " << + parentDirectoryName << ": " << e.what()); + return Restore_UnknownError; + } + catch(std::exception &e) + { + BOX_ERROR("Failed to check existence for " << + parentDirectoryName << ": " << e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to check existence for " << + parentDirectoryName << ": unknown error"); + return Restore_UnknownError; + } + + switch(parentExists) + { + case ObjectExists_Dir: + // this is fine, do nothing + break; + + case ObjectExists_File: + BOX_ERROR("Failed to restore: '" << + parentDirectoryName << "' " + "is a file, but should be a " + "directory."); + return Restore_TargetPathNotFound; + + case ObjectExists_NoObject: + BOX_ERROR("Failed to restore: parent '" << + parentDirectoryName << "' of target " + "directory does not exist."); + return Restore_TargetPathNotFound; + + default: + BOX_ERROR("Failed to restore: unknown " + "result from ObjectExists('" << + parentDirectoryName << "')"); + return Restore_UnknownError; + } + } + + if((exists == ObjectExists_NoObject || + exists == ObjectExists_File) && + ::mkdir(rLocalDirectoryName.c_str(), S_IRWXU) != 0) + { + BOX_ERROR("Failed to create directory '" << + rLocalDirectoryName << "': " << + strerror(errno)); + return Restore_UnknownError; + } + + // Save the restore info, in case it's needed later + try + { + Params.mResumeInfo.Save(Params.mRestoreResumeInfoFilename); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to save resume info file '" << + Params.mRestoreResumeInfoFilename << "': " << + e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to save resume info file '" << + Params.mRestoreResumeInfoFilename << + "': unknown error"); + return Restore_UnknownError; + } + + // Fetch the directory listing from the server -- getting a + // list of files which is appropriate to the restore type rConnection.QueryListDirectory( DirectoryID, Params.RestoreDeleted?(BackupProtocolClientListDirectory::Flags_Deleted):(BackupProtocolClientListDirectory::Flags_INCLUDE_EVERYTHING), @@ -269,7 +420,23 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di // Apply attributes to the directory const StreamableMemBlock &dirAttrBlock(dir.GetAttributes()); BackupClientFileAttributes dirAttr(dirAttrBlock); - dirAttr.WriteAttributes(rLocalDirectoryName.c_str()); + + try + { + dirAttr.WriteAttributes(rLocalDirectoryName.c_str(), true); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to restore attributes for '" << + rLocalDirectoryName << "': " << e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to restore attributes for '" << + rLocalDirectoryName << "': unknown error"); + return Restore_UnknownError; + } int64_t bytesWrittenSinceLastRestoreInfoSave = 0; @@ -287,7 +454,13 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di std::string localFilename(rLocalDirectoryName + DIRECTORY_SEPARATOR_ASCHAR + nm.GetClearFilename()); // Unlink anything which already exists -- for resuming restores, we can't overwrite files already there. - ::unlink(localFilename.c_str()); + if(::unlink(localFilename.c_str()) == 0) + { + BOX_ERROR("Failed to delete file '" << + localFilename << "': " << + strerror(errno)); + return Restore_UnknownError; + } // Request it from the store rConnection.QueryGetFile(DirectoryID, en->GetObjectID()); @@ -297,17 +470,34 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di // Decode the file -- need to do different things depending on whether // the directory entry has additional attributes - if(en->HasAttributes()) + try { - // Use these attributes - const StreamableMemBlock &storeAttr(en->GetAttributes()); - BackupClientFileAttributes attr(storeAttr); - BackupStoreFile::DecodeFile(*objectStream, localFilename.c_str(), rConnection.GetTimeout(), &attr); + if(en->HasAttributes()) + { + // Use these attributes + const StreamableMemBlock &storeAttr(en->GetAttributes()); + BackupClientFileAttributes attr(storeAttr); + BackupStoreFile::DecodeFile(*objectStream, localFilename.c_str(), rConnection.GetTimeout(), &attr); + } + else + { + // Use attributes stored in file + BackupStoreFile::DecodeFile(*objectStream, localFilename.c_str(), rConnection.GetTimeout()); + } } - else + catch(std::exception &e) { - // Use attributes stored in file - BackupStoreFile::DecodeFile(*objectStream, localFilename.c_str(), rConnection.GetTimeout()); + BOX_ERROR("Failed to restore file '" << + localFilename << "': " << + e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to restore file '" << + localFilename << + "': unknown error"); + return Restore_UnknownError; } // Progress display? @@ -322,7 +512,34 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di // Save restore info? int64_t fileSize; - if(FileExists(localFilename.c_str(), &fileSize, true /* treat links as not existing */)) + int exists; + + try + { + exists = FileExists( + localFilename.c_str(), + &fileSize, + true /* treat links as not + existing */); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to determine " + "whether file exists: '" << + localFilename << "': " << + e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to determine " + "whether file exists: '" << + localFilename << "': " + "unknown error"); + return Restore_UnknownError; + } + + if(exists) { // File exists... bytesWrittenSinceLastRestoreInfoSave += fileSize; @@ -330,7 +547,25 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di if(bytesWrittenSinceLastRestoreInfoSave > MAX_BYTES_WRITTEN_BETWEEN_RESTORE_INFO_SAVES) { // Save the restore info, in case it's needed later - Params.mResumeInfo.Save(Params.mRestoreResumeInfoFilename); + try + { + Params.mResumeInfo.Save(Params.mRestoreResumeInfoFilename); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to save resume info file '" << + Params.mRestoreResumeInfoFilename << + "': " << e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to save resume info file '" << + Params.mRestoreResumeInfoFilename << + "': unknown error"); + return Restore_UnknownError; + } + bytesWrittenSinceLastRestoreInfoSave = 0; } } @@ -342,12 +577,31 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di if(bytesWrittenSinceLastRestoreInfoSave != 0) { // Save the restore info, in case it's needed later - Params.mResumeInfo.Save(Params.mRestoreResumeInfoFilename); + try + { + Params.mResumeInfo.Save( + Params.mRestoreResumeInfoFilename); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to save resume info file '" << + Params.mRestoreResumeInfoFilename << "': " << + e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to save resume info file '" << + Params.mRestoreResumeInfoFilename << + "': unknown error"); + return Restore_UnknownError; + } + bytesWrittenSinceLastRestoreInfoSave = 0; } - // Recuse to directories + // Recurse to directories { BackupStoreDirectory::Iterator i(dir); BackupStoreDirectory::Entry *en = 0; @@ -364,7 +618,14 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di RestoreResumeInfo &rnextLevel(rLevel.AddLevel(en->GetObjectID(), nm.GetClearFilename())); // Recurse - BackupClientRestoreDir(rConnection, en->GetObjectID(), localDirname, Params, rnextLevel); + int result = BackupClientRestoreDir( + rConnection, en->GetObjectID(), + localDirname, Params, rnextLevel); + + if (result != Restore_Complete) + { + return result; + } // Remove the level for the above call rLevel.RemoveLevel(); @@ -373,7 +634,27 @@ static void BackupClientRestoreDir(BackupProtocolClient &rConnection, int64_t Di rLevel.mRestoredObjects.insert(en->GetObjectID()); } } - } + } + + // now remove the user writable flag, if we added it earlier + try + { + dirAttr.WriteAttributes(rLocalDirectoryName.c_str(), false); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to restore attributes for '" << + rLocalDirectoryName << "': " << e.what()); + return Restore_UnknownError; + } + catch(...) + { + BOX_ERROR("Failed to restore attributes for '" << + rLocalDirectoryName << "': unknown error"); + return Restore_UnknownError; + } + + return Restore_Complete; } @@ -444,7 +725,12 @@ int BackupClientRestore(BackupProtocolClient &rConnection, int64_t DirectoryID, // Restore the directory std::string localName(LocalDirectoryName); - BackupClientRestoreDir(rConnection, DirectoryID, localName, params, params.mResumeInfo); + int result = BackupClientRestoreDir(rConnection, DirectoryID, + localName, params, params.mResumeInfo); + if (result != Restore_Complete) + { + return result; + } // Undelete the directory on the server? if(RestoreDeleted && UndeleteAfterRestoreDeleted) diff --git a/lib/backupclient/BackupClientRestore.h b/lib/backupclient/BackupClientRestore.h index 4b382771..f7724030 100644 --- a/lib/backupclient/BackupClientRestore.h +++ b/lib/backupclient/BackupClientRestore.h @@ -16,7 +16,9 @@ enum { Restore_Complete = 0, Restore_ResumePossible = 1, - Restore_TargetExists = 2 + Restore_TargetExists = 2, + Restore_TargetPathNotFound = 3, + Restore_UnknownError = 4, }; int BackupClientRestore(BackupProtocolClient &rConnection, int64_t DirectoryID, const char *LocalDirectoryName, diff --git a/lib/backupclient/BackupDaemonConfigVerify.cpp b/lib/backupclient/BackupDaemonConfigVerify.cpp index 89ad4d54..9000ec6d 100644 --- a/lib/backupclient/BackupDaemonConfigVerify.cpp +++ b/lib/backupclient/BackupDaemonConfigVerify.cpp @@ -81,7 +81,9 @@ static const ConfigurationVerifyKey verifyrootkeys[] = {"FileTrackingSizeThreshold", 0, ConfigTest_Exists | ConfigTest_IsInt, 0}, {"DiffingUploadSizeThreshold", 0, ConfigTest_Exists | ConfigTest_IsInt, 0}, {"StoreHostname", 0, ConfigTest_Exists, 0}, - {"ExtendedLogging", "no", ConfigTest_IsBool, 0}, // make value "yes" to enable in config file + {"ExtendedLogging", "no", ConfigTest_IsBool, 0}, // extended log to syslog + {"ExtendedLogFile", NULL, 0, 0}, // extended log to a file + {"LogAllFileAccess", "no", ConfigTest_IsBool, 0}, {"CommandSocket", 0, 0, 0}, // not compulsory to have this {"KeepAliveTime", 0, ConfigTest_IsInt, 0}, // optional diff --git a/lib/backupclient/BackupStoreDirectory.cpp b/lib/backupclient/BackupStoreDirectory.cpp index 61e6461d..0d06da34 100644 --- a/lib/backupclient/BackupStoreDirectory.cpp +++ b/lib/backupclient/BackupStoreDirectory.cpp @@ -149,6 +149,11 @@ void BackupStoreDirectory::ReadFromStream(IOStream &rStream, int Timeout) int count = ntohl(hdr.mNumEntries); // Clear existing list + for(std::vector<Entry*>::iterator i = mEntries.begin(); + i != mEntries.end(); i++) + { + delete (*i); + } mEntries.clear(); // Read them in! diff --git a/lib/backupclient/BackupStoreFile.cpp b/lib/backupclient/BackupStoreFile.cpp index 278bf50a..7e93d59d 100644 --- a/lib/backupclient/BackupStoreFile.cpp +++ b/lib/backupclient/BackupStoreFile.cpp @@ -17,10 +17,8 @@ #include <string.h> #include <new> #include <string.h> + #ifndef BOX_DISABLE_BACKWARDS_COMPATIBILITY_BACKUPSTOREFILE - #ifndef WIN32 - #include <syslog.h> - #endif #include <stdio.h> #endif @@ -46,6 +44,7 @@ #include "ReadGatherStream.h" #include "Random.h" #include "BackupStoreFileEncodeStream.h" +#include "Logging.h" #include "MemLeakFindOn.h" @@ -291,6 +290,20 @@ void BackupStoreFile::DecodeFile(IOStream &rEncodedFile, const char *DecodedFile } out.Close(); + + // The stream might have uncertain size, in which case + // we need to drain it to get the + // Protocol::ProtocolStreamHeader_EndOfStream byte + // out of our connection stream. + char buffer[1]; + int drained = rEncodedFile.Read(buffer, 1); + + // The Read will return 0 if we are actually at the end + // of the stream, but some tests decode files directly, + // in which case we are actually positioned at the start + // of the block index. I hope that reading an extra byte + // doesn't hurt! + // ASSERT(drained == 0); // Write the attributes stream->GetAttributes().WriteAttributes(DecodedFilename); @@ -743,8 +756,7 @@ int BackupStoreFile::DecodedStream::Read(void *pBuffer, int NBytes, int Timeout) // Warn and log this issue if(!sWarnedAboutBackwardsCompatiblity) { - ::printf("WARNING: Decoded one or more files using backwards compatibility mode for block index.\n"); - ::syslog(LOG_ERR, "WARNING: Decoded one or more files using backwards compatibility mode for block index.\n"); + BOX_WARNING("WARNING: Decoded one or more files using backwards compatibility mode for block index."); sWarnedAboutBackwardsCompatiblity = true; } } @@ -1485,9 +1497,8 @@ void BackupStoreFile::EncodingBuffer::Allocate(int Size) // -------------------------------------------------------------------------- void BackupStoreFile::EncodingBuffer::Reallocate(int NewSize) { -#ifndef WIN32 - TRACE2("Reallocating EncodingBuffer from %d to %d\n", mBufferSize, NewSize); -#endif + BOX_TRACE("Reallocating EncodingBuffer from " << mBufferSize << + " to " << NewSize); ASSERT(mpBuffer != 0); uint8_t *buffer = (uint8_t*)BackupStoreFile::CodingChunkAlloc(NewSize); if(buffer == 0) diff --git a/lib/backupclient/BackupStoreFile.h b/lib/backupclient/BackupStoreFile.h index 437b4232..3ee5ddb0 100644 --- a/lib/backupclient/BackupStoreFile.h +++ b/lib/backupclient/BackupStoreFile.h @@ -50,17 +50,16 @@ public: DiffTimer(); virtual ~DiffTimer(); public: - virtual void DoKeepAlive() = 0; - virtual time_t GetTimeMgmtEpoch() = 0; - virtual int GetMaximumDiffingTime() = 0; - virtual int GetKeepaliveTime() = 0; + virtual void DoKeepAlive() = 0; + virtual int GetMaximumDiffingTime() = 0; + virtual bool IsManaged() = 0; }; // -------------------------------------------------------------------------- // // Class // Name: BackupStoreFile -// Purpose: Class to hold together utils for maniplating files. +// Purpose: Class to hold together utils for manipulating files. // Created: 2003/08/28 // // -------------------------------------------------------------------------- diff --git a/lib/backupclient/BackupStoreFileDiff.cpp b/lib/backupclient/BackupStoreFileDiff.cpp index ee09f1c8..3a3f1a5e 100644 --- a/lib/backupclient/BackupStoreFileDiff.cpp +++ b/lib/backupclient/BackupStoreFileDiff.cpp @@ -29,6 +29,7 @@ #include "RollingChecksum.h" #include "MD5Digest.h" #include "CommonException.h" +#include "Timer.h" #include "MemLeakFindOn.h" @@ -52,31 +53,6 @@ static bool SecondStageMatch(BlocksAvailableEntry *pFirstInHashList, RollingChec BlocksAvailableEntry *pIndex, std::map<int64_t, int64_t> &rFoundBlocks); static void GenerateRecipe(BackupStoreFileEncodeStream::Recipe &rRecipe, BlocksAvailableEntry *pIndex, int64_t NumBlocks, std::map<int64_t, int64_t> &rFoundBlocks, int64_t SizeOfInputFile); -// sDiffTimerExpired flags when the diff timer has expired. When true, the -// diff routine should check the wall clock as soon as possible, to determine -// whether it's time for a keepalive to be sent, or whether the diff has been -// running for too long and should be terminated. -static bool sDiffTimerExpired = false; - - -// -------------------------------------------------------------------------- -// -// Function -// Name: BackupStoreFile::DiffTimerExpired() -// Purpose: Notifies BackupStoreFile object that the diff operation -// timer has expired, which may mean that a keepalive should -// be sent, or the diff should be terminated. Called from an -// external timer, so it should not do more than set a flag. -// -// Created: 19/1/06 -// -// -------------------------------------------------------------------------- -void BackupStoreFile::DiffTimerExpired() -{ - sDiffTimerExpired = true; -} - - // -------------------------------------------------------------------------- // // Function @@ -483,15 +459,11 @@ static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t> BlocksAvailableEntry *pIndex, int64_t NumBlocks, int32_t Sizes[BACKUP_FILE_DIFF_MAX_BLOCK_SIZES], DiffTimer *pDiffTimer) { - time_t TimeMgmtEpoch = 0; - int MaximumDiffingTime = 0; - int KeepAliveTime = 0; + Timer maximumDiffingTime(0); - if (pDiffTimer) + if(pDiffTimer && pDiffTimer->IsManaged()) { - TimeMgmtEpoch = pDiffTimer->GetTimeMgmtEpoch(); - MaximumDiffingTime = pDiffTimer->GetMaximumDiffingTime(); - KeepAliveTime = pDiffTimer->GetKeepaliveTime(); + maximumDiffingTime = Timer(pDiffTimer->GetMaximumDiffingTime()); } std::map<int64_t, int32_t> goodnessOfFit; @@ -577,31 +549,20 @@ static void SearchForMatchingBlocks(IOStream &rFile, std::map<int64_t, int64_t> int rollOverInitialBytes = 0; while(true) { - if(sDiffTimerExpired) + if(maximumDiffingTime.HasExpired()) { - ASSERT(TimeMgmtEpoch > 0); ASSERT(pDiffTimer != NULL); - - time_t tTotalRunIntvl = time(NULL) - TimeMgmtEpoch; - - if(MaximumDiffingTime > 0 && - tTotalRunIntvl >= MaximumDiffingTime) - { - TRACE0("MaximumDiffingTime reached - " - "suspending file diff\n"); - abortSearch = true; - break; - } - else if(KeepAliveTime > 0) - { - TRACE0("KeepAliveTime reached - " - "initiating keep-alive\n"); - pDiffTimer->DoKeepAlive(); - } - - sDiffTimerExpired = false; + TRACE0("MaximumDiffingTime reached - " + "suspending file diff\n"); + abortSearch = true; + break; } - + + if(pDiffTimer) + { + pDiffTimer->DoKeepAlive(); + } + // Load in another block of data, and record how big it is int bytesInEndings = rFile.Read(endings, Sizes[s]); int tmp; diff --git a/lib/backupclient/BackupStoreFileEncodeStream.cpp b/lib/backupclient/BackupStoreFileEncodeStream.cpp index c692f18e..423c11a3 100644 --- a/lib/backupclient/BackupStoreFileEncodeStream.cpp +++ b/lib/backupclient/BackupStoreFileEncodeStream.cpp @@ -38,6 +38,7 @@ using namespace BackupStoreFileCryptVar; BackupStoreFileEncodeStream::BackupStoreFileEncodeStream() : mpRecipe(0), mpFile(0), + mpLogging(0), mStatus(Status_Header), mSendData(true), mTotalBlocks(0), @@ -79,6 +80,13 @@ BackupStoreFileEncodeStream::~BackupStoreFileEncodeStream() mpFile = 0; } + // Clear up logging stream + if(mpLogging) + { + delete mpLogging; + mpLogging = 0; + } + // Free the recipe if(mpRecipe != 0) { @@ -199,6 +207,9 @@ void BackupStoreFileEncodeStream::Setup(const char *Filename, BackupStoreFileEnc { // Open the file mpFile = new FileStream(Filename); + + // Create logging stream + mpLogging = new ReadLoggingStream(*mpFile); // Work out the largest possible block required for the encoded data mAllocatedBufferSize = BackupStoreFile::MaxBlockSizeForChunkSize(maxBlockClearSize); @@ -267,7 +278,7 @@ void BackupStoreFileEncodeStream::CalculateBlockSizes(int64_t DataSize, int64_t rNumBlocksOut = (DataSize + rBlockSizeOut - 1) / rBlockSizeOut; - } while(rBlockSizeOut <= BACKUP_FILE_MAX_BLOCK_SIZE && rNumBlocksOut > BACKUP_FILE_INCREASE_BLOCK_SIZE_AFTER); + } while(rBlockSizeOut < BACKUP_FILE_MAX_BLOCK_SIZE && rNumBlocksOut > BACKUP_FILE_INCREASE_BLOCK_SIZE_AFTER); // Last block size rLastBlockSizeOut = DataSize - ((rNumBlocksOut - 1) * rBlockSizeOut); @@ -474,7 +485,7 @@ void BackupStoreFileEncodeStream::SkipPreviousBlocksInInstruction() } // Move forward in the stream - mpFile->Seek(sizeToSkip, IOStream::SeekType_Relative); + mpLogging->Seek(sizeToSkip, IOStream::SeekType_Relative); } @@ -518,14 +529,14 @@ void BackupStoreFileEncodeStream::EncodeCurrentBlock() ASSERT(blockRawSize < mAllocatedBufferSize); // Check file open - if(mpFile == 0) + if(mpFile == 0 || mpLogging == 0) { // File should be open, but isn't. So logical error. THROW_EXCEPTION(BackupStoreException, Internal) } // Read the data in - if(!mpFile->ReadFullBuffer(mpRawBuffer, blockRawSize, 0 /* not interested in size if failure */)) + if(!mpLogging->ReadFullBuffer(mpRawBuffer, blockRawSize, 0 /* not interested in size if failure */)) { // TODO: Do something more intelligent, and abort this upload because the file // has changed diff --git a/lib/backupclient/BackupStoreFileEncodeStream.h b/lib/backupclient/BackupStoreFileEncodeStream.h index 1c748798..fb5d0851 100644 --- a/lib/backupclient/BackupStoreFileEncodeStream.h +++ b/lib/backupclient/BackupStoreFileEncodeStream.h @@ -17,6 +17,7 @@ #include "CollectInBufferStream.h" #include "MD5Digest.h" #include "BackupStoreFile.h" +#include "ReadLoggingStream.h" namespace BackupStoreFileCreation { @@ -100,6 +101,7 @@ private: Recipe *mpRecipe; IOStream *mpFile; // source file CollectInBufferStream mData; // buffer for header and index entries + ReadLoggingStream *mpLogging; int mStatus; bool mSendData; // true if there's file data to send (ie not a symlink) int64_t mTotalBlocks; // Total number of blocks in the file diff --git a/lib/backupclient/BackupStoreFilenameClear.cpp b/lib/backupclient/BackupStoreFilenameClear.cpp index c415b9bb..9114fdd1 100644 --- a/lib/backupclient/BackupStoreFilenameClear.cpp +++ b/lib/backupclient/BackupStoreFilenameClear.cpp @@ -13,6 +13,7 @@ #include "CipherContext.h" #include "CipherBlowfish.h" #include "Guards.h" +#include "Logging.h" #include "MemLeakFindOn.h" @@ -203,9 +204,9 @@ static void EnsureEncDecBufferSize(int BufSize) { if(sEncDecBufferSize < BufSize) { -#ifndef WIN32 - TRACE2("Reallocating filename encoding/decoding buffer from %d to %d\n", sEncDecBufferSize, BufSize); -#endif + BOX_TRACE("Reallocating filename encoding/decoding " + "buffer from " << sEncDecBufferSize << + " to " << BufSize); spEncDecBuffer->Resize(BufSize); sEncDecBufferSize = BufSize; MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer); |