diff options
author | Chris Wilson <chris+github@qwirx.com> | 2006-01-28 00:13:44 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2006-01-28 00:13:44 +0000 |
commit | 9e025fd0ea42782e93363958804c6e2437b44a30 (patch) | |
tree | fd37208fa3f569067e75ea24765c575d9884b339 /bin/bbackupd | |
parent | 41f02c67b06ae838dc9fc8829741ed51abfe5b42 (diff) |
* configure.ac
* bin/bbstored/backupprotocol.txt
* bin/bbstored/BackupCommands.cpp
* bin/bbackupd/BackupClientContext.cpp
* bin/bbackupd/BackupClientContext.h
* bin/bbackupd/BackupClientDirectoryRecord.cpp
* bin/bbackupd/BackupDaemon.cpp
* lib/backupclient/BackupStoreFileDiff.cpp
* lib/backupclient/BackupDaemonConfigVerify.cpp
* lib/backupclient/BackupStoreFile.h
* test/backupstore/testbackupstore.cpp
* test/backupstorepatch/testbackupstorepatch.cpp
- Applied changes from chris/diff-timeout-and-ssl-keepalive
* test/backupdiff/testbackupdiff.cpp
- Fixed test to match new prototype for EncodeFileDiff
Diffstat (limited to 'bin/bbackupd')
-rw-r--r-- | bin/bbackupd/BackupClientContext.cpp | 180 | ||||
-rw-r--r-- | bin/bbackupd/BackupClientContext.h | 69 | ||||
-rw-r--r-- | bin/bbackupd/BackupClientDirectoryRecord.cpp | 23 | ||||
-rw-r--r-- | bin/bbackupd/BackupDaemon.cpp | 10 |
4 files changed, 268 insertions, 14 deletions
diff --git a/bin/bbackupd/BackupClientContext.cpp b/bin/bbackupd/BackupClientContext.cpp index 38d0b98c..ae4e1cad 100644 --- a/bin/bbackupd/BackupClientContext.cpp +++ b/bin/bbackupd/BackupClientContext.cpp @@ -9,8 +9,14 @@ #include "Box.h" -#ifndef WIN32 -#include <syslog.h> +#ifdef HAVE_SYSLOG_H + #include <syslog.h> +#endif +#ifdef HAVE_SIGNAL_H + #include <signal.h> +#endif +#ifdef HAVE_SYS_TIME_H + #include <sys/time.h> #endif #include "BoxPortsAndFiles.h" @@ -22,6 +28,7 @@ #include "BackupStoreException.h" #include "BackupDaemon.h" #include "autogen_BackupProtocolClient.h" +#include "BackupStoreFile.h" #include "MemLeakFindOn.h" @@ -48,7 +55,11 @@ BackupClientContext::BackupClientContext(BackupDaemon &rDaemon, TLSContext &rTLS mpNewIDMap(0), mStorageLimitExceeded(false), mpExcludeFiles(0), - mpExcludeDirs(0) + mpExcludeDirs(0), + mbIsManaged(false), + mTimeMgmtEpoch(0), + mMaximumDiffTime(600), + mKeepAliveTime(0) { } @@ -453,3 +464,166 @@ bool BackupClientContext::FindFilename(int64_t ObjectID, int64_t ContainingDirec } +// maximum time to spend diffing +static int sMaximumDiffTime = 600; +// maximum time of SSL inactivity (keep-alive interval) +static int sKeepAliveTime = 0; + +void BackupClientContext::SetMaximumDiffingTime(int iSeconds) +{ + sMaximumDiffTime = iSeconds < 0 ? 0 : iSeconds; + TRACE1("Set maximum diffing time to %d seconds\n", sMaximumDiffTime); +} + +void BackupClientContext::SetKeepAliveTime(int iSeconds) +{ + sKeepAliveTime = iSeconds < 0 ? 0 : iSeconds; + TRACE1("Set keep-alive time to %d seconds\n", sKeepAliveTime); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: static TimerSigHandler(int) +// Purpose: Signal handler +// Created: 19/3/04 +// +// -------------------------------------------------------------------------- +static void TimerSigHandler(int iUnused) +{ + BackupStoreFile::DiffTimerExpired(); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupClientContext::ManageDiffProcess() +// Purpose: Initiates a file diff control timer +// Created: 04/19/2005 +// +// -------------------------------------------------------------------------- +void BackupClientContext::ManageDiffProcess() +{ + if (mbIsManaged || !mpConnection) + return; + + ASSERT(mTimeMgmtEpoch == 0); + +#ifdef PLATFORM_CYGWIN + ::signal(SIGALRM, TimerSigHandler); +#else + ::signal(SIGVTALRM, TimerSigHandler); +#endif // PLATFORM_CYGWIN + + struct itimerval timeout; + memset(&timeout, 0, sizeof(timeout)); + + // + // + // + if (sMaximumDiffTime <= 0 && sKeepAliveTime <= 0) + { + TRACE0("Diff control not requested - letting things run wild\n"); + return; + } + else if (sMaximumDiffTime > 0 && sKeepAliveTime > 0) + { + timeout.it_value.tv_sec = sKeepAliveTime < sMaximumDiffTime ? sKeepAliveTime : sMaximumDiffTime; + timeout.it_interval.tv_sec = sKeepAliveTime < sMaximumDiffTime ? sKeepAliveTime : sMaximumDiffTime; + } + else + { + timeout.it_value.tv_sec = sKeepAliveTime > 0 ? sKeepAliveTime : sMaximumDiffTime; + timeout.it_interval.tv_sec = sKeepAliveTime > 0 ? sKeepAliveTime : sMaximumDiffTime; + } + + // avoid race + mTimeMgmtEpoch = time(NULL); + +#ifdef PLATFORM_CYGWIN + if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0) +#else + if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0) +#endif // PLATFORM_CYGWIN + { + mTimeMgmtEpoch = 0; + + TRACE0("WARNING: couldn't set file diff control timeout\n"); + THROW_EXCEPTION(BackupStoreException, Internal) + } + + mbIsManaged = true; + TRACE0("Initiated timer for file diff control\n"); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupClientContext::UnManageDiffProcess() +// Purpose: suspends file diff control timer +// Created: 04/19/2005 +// +// -------------------------------------------------------------------------- +void BackupClientContext::UnManageDiffProcess() +{ + if (!mbIsManaged /* don't test for active connection, just do it */) + return; + + struct itimerval timeout; + memset(&timeout, 0, sizeof(timeout)); + +#ifdef PLATFORM_CYGWIN + if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0) +#else + if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0) +#endif // PLATFORM_CYGWIN + { + TRACE0("WARNING: couldn't clear file diff control timeout\n"); + THROW_EXCEPTION(BackupStoreException, Internal) + } + + mbIsManaged = false; + mTimeMgmtEpoch = 0; + + TRACE0("Suspended timer for file diff control\n"); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupClientContext::DoKeepAlive() +// Purpose: Does something inconsequential over the SSL link to keep it up +// Created: 04/19/2005 +// +// -------------------------------------------------------------------------- +void BackupClientContext::DoKeepAlive() +{ + if (!mpConnection) + return; + + mpConnection->QueryGetIsAlive(); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: BackupClientContext::GetTimeMgmtEpoch() +// Purpose: Returns the unix time when the diff was started, or zero +// if the diff process is unmanaged. +// Created: 04/19/2005 +// +// -------------------------------------------------------------------------- +time_t BackupClientContext::GetTimeMgmtEpoch() +{ + return mTimeMgmtEpoch; +} + +int BackupClientContext::GetMaximumDiffingTime() +{ + return mMaximumDiffTime; +} + +int BackupClientContext::GetKeepaliveTime() +{ + return mKeepAliveTime; +} diff --git a/bin/bbackupd/BackupClientContext.h b/bin/bbackupd/BackupClientContext.h index 3933dbed..234868db 100644 --- a/bin/bbackupd/BackupClientContext.h +++ b/bin/bbackupd/BackupClientContext.h @@ -12,6 +12,7 @@ #include "BoxTime.h" #include "BackupClientDeleteList.h" +#include "BackupStoreFile.h" #include "ExcludeList.h" class TLSContext; @@ -31,12 +32,12 @@ class BackupStoreFilenameClear; // Created: 2003/10/08 // // -------------------------------------------------------------------------- -class BackupClientContext +class BackupClientContext : public DiffTimer { public: BackupClientContext(BackupDaemon &rDaemon, TLSContext &rTLSContext, const std::string &rHostname, int32_t AccountNumber, bool ExtendedLogging); - ~BackupClientContext(); + virtual ~BackupClientContext(); private: BackupClientContext(const BackupClientContext &); public: @@ -134,6 +135,60 @@ public: bool &rIsCurrentVersionOut, box_time_t *pModTimeOnServer = 0, box_time_t *pAttributesHashOnServer = 0, BackupStoreFilenameClear *pLeafname = 0); // not const as may connect to server + // -------------------------------------------------------------------------- + // + // Function + // Name: BackupClientContext::SetMaximumDiffingTime() + // Purpose: Sets the maximum time that will be spent diffing a file + // Created: 04/19/2005 + // + // -------------------------------------------------------------------------- + static void SetMaximumDiffingTime(int iSeconds); + + // -------------------------------------------------------------------------- + // + // Function + // Name: BackupClientContext::SetKeepAliveTime() + // Purpose: Sets the time interval for repetitive keep-alive operation + // Created: 04/19/2005 + // + // -------------------------------------------------------------------------- + static void SetKeepAliveTime(int iSeconds); + + // -------------------------------------------------------------------------- + // + // Function + // Name: BackupClientContext::ManageDiffProcess() + // Purpose: Initiates an SSL connection/session keep-alive process + // Created: 04/19/2005 + // + // -------------------------------------------------------------------------- + void ManageDiffProcess(); + + // -------------------------------------------------------------------------- + // + // Function + // Name: BackupClientContext::UnManageDiffProcess() + // Purpose: Suspends an SSL connection/session keep-alive process + // Created: 04/19/2005 + // + // -------------------------------------------------------------------------- + void UnManageDiffProcess(); + + // -------------------------------------------------------------------------- + // + // Function + // Name: BackupClientContext::DoKeepAlive() + // Purpose: Does something inconsequential over the SSL link to + // keep it up, implements DiffTimer interface + // Created: 04/19/2005 + // + // -------------------------------------------------------------------------- + virtual void DoKeepAlive(); + virtual time_t GetTimeMgmtEpoch(); + virtual int GetMaximumDiffingTime(); + virtual int GetKeepaliveTime(); + private: BackupDaemon &mrDaemon; TLSContext &mrTLSContext; @@ -149,8 +204,16 @@ private: bool mStorageLimitExceeded; ExcludeList *mpExcludeFiles; ExcludeList *mpExcludeDirs; + + bool mbIsManaged; + // unix time when diff was started + time_t mTimeMgmtEpoch; + // maximum time to spend diffing, in seconds + int mMaximumDiffTime; + // maximum time of SSL inactivity (keep-alive interval), in seconds + int mKeepAliveTime; + }; #endif // BACKUPCLIENTCONTEXT__H - diff --git a/bin/bbackupd/BackupClientDirectoryRecord.cpp b/bin/bbackupd/BackupClientDirectoryRecord.cpp index 1a124333..3e8ceeb2 100644 --- a/bin/bbackupd/BackupClientDirectoryRecord.cpp +++ b/bin/bbackupd/BackupClientDirectoryRecord.cpp @@ -1093,14 +1093,28 @@ int64_t BackupClientDirectoryRecord::UploadFile(BackupClientDirectoryRecord::Syn // Found an old version -- get the index std::auto_ptr<IOStream> blockIndexStream(connection.ReceiveStream()); + // // Diff the file + // + + rParams.mrContext.ManageDiffProcess(); + bool isCompletelyDifferent = false; - std::auto_ptr<IOStream> patchStream(BackupStoreFile::EncodeFileDiff(rFilename.c_str(), + std::auto_ptr<IOStream> patchStream( + BackupStoreFile::EncodeFileDiff( + rFilename.c_str(), mObjectID, /* containing directory */ rStoreFilename, diffFromID, *blockIndexStream, - connection.GetTimeout(), 0 /* not interested in the modification time */, &isCompletelyDifferent)); + connection.GetTimeout(), + &rParams.mrContext, // DiffTimer implementation + 0 /* not interested in the modification time */, + &isCompletelyDifferent)); + rParams.mrContext.UnManageDiffProcess(); + + // // Upload the patch to the store + // std::auto_ptr<BackupProtocolClientSuccess> stored(connection.QueryStoreFile(mObjectID, ModificationTime, AttributesHash, isCompletelyDifferent?(0):(diffFromID), rStoreFilename, *patchStream)); @@ -1130,6 +1144,8 @@ int64_t BackupClientDirectoryRecord::UploadFile(BackupClientDirectoryRecord::Syn } catch(BoxException &e) { + rParams.mrContext.UnManageDiffProcess(); + if(e.GetType() == ConnectionException::ExceptionType && e.GetSubType() == ConnectionException::Protocol_UnexpectedReply) { // Check and see what error the protocol has -- as it might be an error... @@ -1210,6 +1226,3 @@ BackupClientDirectoryRecord::SyncParams::SyncParams(BackupDaemon &rDaemon, Backu BackupClientDirectoryRecord::SyncParams::~SyncParams() { } - - - diff --git a/bin/bbackupd/BackupDaemon.cpp b/bin/bbackupd/BackupDaemon.cpp index 954504a6..07a8db4d 100644 --- a/bin/bbackupd/BackupDaemon.cpp +++ b/bin/bbackupd/BackupDaemon.cpp @@ -435,10 +435,14 @@ void BackupDaemon::Run2() // Set up the keys for various things BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str()); - // Set maximum diffing time? + // max diffing time, keep-alive time if(conf.KeyExists("MaximumDiffingTime")) { - BackupStoreFile::SetMaximumDiffingTime(conf.GetKeyValueInt("MaximumDiffingTime")); + BackupClientContext::SetMaximumDiffingTime(conf.GetKeyValueInt("MaximumDiffingTime")); + } + if(conf.KeyExists("KeepAliveTime")) + { + BackupClientContext::SetKeepAliveTime(conf.GetKeyValueInt("KeepAliveTime")); } // Setup various timings @@ -885,7 +889,7 @@ void BackupDaemon::WaitOnCommandSocket(box_time_t RequiredDelay, bool &DoSyncFla { #ifdef PLATFORM_CANNOT_FIND_PEER_UID_OF_UNIX_SOCKET bool uidOK = true; - ::syslog(LOG_ERR, "On this platform, no security check can be made on the credientials of peers connecting to the command socket. (bbackupctl)"); + ::syslog(LOG_WARNING, "On this platform, no security check can be made on the credientials of peers connecting to the command socket. (bbackupctl)"); #else // Security check -- does the process connecting to this socket have // the same UID as this process? |