diff options
author | Chris Wilson <chris+github@qwirx.com> | 2006-07-27 23:18:35 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2006-07-27 23:18:35 +0000 |
commit | c7662795f519d2b6797e4b1ac7fa4a22afa26310 (patch) | |
tree | b1737dfa78d8e7bfb2d5a7e9831bab91869ade97 /bin/bbstored | |
parent | a85b710c46ec79e968da349304f30945cb9b7bc1 (diff) |
* merge
- This is my current patch queue. I think that all of these are safe
to apply. This is just under half of the pending changes in
chris/general (the easy half).
Diffstat (limited to 'bin/bbstored')
-rw-r--r-- | bin/bbstored/BBStoreDHousekeeping.cpp | 174 | ||||
-rw-r--r-- | bin/bbstored/BackupCommands.cpp | 33 | ||||
-rw-r--r-- | bin/bbstored/BackupContext.cpp | 20 | ||||
-rw-r--r-- | bin/bbstored/BackupStoreDaemon.cpp | 19 | ||||
-rw-r--r-- | bin/bbstored/BackupStoreDaemon.h | 13 | ||||
-rw-r--r-- | bin/bbstored/HousekeepStoreAccount.cpp | 7 |
6 files changed, 190 insertions, 76 deletions
diff --git a/bin/bbstored/BBStoreDHousekeeping.cpp b/bin/bbstored/BBStoreDHousekeeping.cpp index d3656630..86b2468b 100644 --- a/bin/bbstored/BBStoreDHousekeeping.cpp +++ b/bin/bbstored/BBStoreDHousekeeping.cpp @@ -10,7 +10,10 @@ #include "Box.h" #include <stdio.h> + +#ifdef HAVE_SYSLOG_H #include <syslog.h> +#endif #include "BackupStoreDaemon.h" #include "BackupStoreAccountDatabase.h" @@ -29,95 +32,128 @@ // Created: 11/12/03 // // -------------------------------------------------------------------------- +void BackupStoreDaemon::HousekeepingInit() +{ + + mLastHousekeepingRun = 0; +} + +#ifndef WIN32 void BackupStoreDaemon::HousekeepingProcess() { + HousekeepingInit(); + // Get the time between housekeeping runs const Configuration &rconfig(GetConfiguration()); int64_t housekeepingInterval = SecondsToBoxTime(rconfig.GetKeyValueInt("TimeBetweenHousekeeping")); - - int64_t lastHousekeepingRun = 0; while(!StopRun()) { - // Time now + RunHousekeepingIfNeeded(); + + // Calculate how long should wait before doing the next housekeeping run int64_t timeNow = GetCurrentBoxTime(); - // Do housekeeping if the time interval has elapsed since the last check - if((timeNow - lastHousekeepingRun) >= housekeepingInterval) - { - // Store the time - lastHousekeepingRun = timeNow; - ::syslog(LOG_INFO, "Starting housekeeping"); + time_t secondsToGo = BoxTimeToSeconds((mLastHousekeepingRun + housekeepingInterval) - timeNow); + if(secondsToGo < 1) secondsToGo = 1; + if(secondsToGo > 60) secondsToGo = 60; + int32_t millisecondsToGo = ((int)secondsToGo) * 1000; + + // Check to see if there's any message pending + CheckForInterProcessMsg(0 /* no account */, millisecondsToGo); + } +} +#endif - // Get the list of accounts - std::vector<int32_t> accounts; - if(mpAccountDatabase) - { - mpAccountDatabase->GetAllAccountIDs(accounts); - } +void BackupStoreDaemon::RunHousekeepingIfNeeded() +{ + // Get the time between housekeeping runs + const Configuration &rconfig(GetConfiguration()); + int64_t housekeepingInterval = SecondsToBoxTime(rconfig.GetKeyValueInt("TimeBetweenHousekeeping")); + + // Time now + int64_t timeNow = GetCurrentBoxTime(); + // Do housekeeping if the time interval has elapsed since the last check + if((timeNow - mLastHousekeepingRun) < housekeepingInterval) + { + return; + } + + // Store the time + mLastHousekeepingRun = timeNow; + ::syslog(LOG_INFO, "Starting housekeeping"); + + // Get the list of accounts + std::vector<int32_t> accounts; + if(mpAccountDatabase) + { + mpAccountDatabase->GetAllAccountIDs(accounts); + } - SetProcessTitle("housekeeping, active"); + SetProcessTitle("housekeeping, active"); - // Check them all - for(std::vector<int32_t>::const_iterator i = accounts.begin(); i != accounts.end(); ++i) + // Check them all + for(std::vector<int32_t>::const_iterator i = accounts.begin(); i != accounts.end(); ++i) + { + try + { + if(mpAccounts) { - try - { - if(mpAccounts) - { - // Get the account root - std::string rootDir; - int discSet = 0; - mpAccounts->GetAccountRoot(*i, rootDir, discSet); - - // Do housekeeping on this account - HousekeepStoreAccount housekeeping(*i, rootDir, discSet, *this); - housekeeping.DoHousekeeping(); - } - } - catch(BoxException &e) - { - ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s (%d/%d) -- aborting housekeeping run for this account", - *i, e.what(), e.GetType(), e.GetSubType()); - } - catch(std::exception &e) - { - ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s -- aborting housekeeping run for this account", - *i, e.what()); - } - catch(...) - { - ::syslog(LOG_ERR, "while housekeeping account %08X, unknown exception -- aborting housekeeping run for this account", - *i); - } + // Get the account root + std::string rootDir; + int discSet = 0; + mpAccounts->GetAccountRoot(*i, rootDir, discSet); - // Check to see if there's any message pending - CheckForInterProcessMsg(0 /* no account */); - - // Stop early? - if(StopRun()) - { - break; - } + // Do housekeeping on this account + HousekeepStoreAccount housekeeping(*i, rootDir, discSet, *this); + housekeeping.DoHousekeeping(); } - - ::syslog(LOG_INFO, "Finished housekeeping"); } - - // Placed here for accuracy, if StopRun() is true, for example. - SetProcessTitle("housekeeping, idle"); - - // Calculate how long should wait before doing the next housekeeping run - timeNow = GetCurrentBoxTime(); - time_t secondsToGo = BoxTimeToSeconds((lastHousekeepingRun + housekeepingInterval) - timeNow); - if(secondsToGo < 1) secondsToGo = 1; - if(secondsToGo > 60) secondsToGo = 60; - int32_t millisecondsToGo = ((int)secondsToGo) * 1000; + catch(BoxException &e) + { + ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s (%d/%d) -- aborting housekeeping run for this account", + *i, e.what(), e.GetType(), e.GetSubType()); + } + catch(std::exception &e) + { + ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s -- aborting housekeeping run for this account", + *i, e.what()); + } + catch(...) + { + ::syslog(LOG_ERR, "while housekeeping account %08X, unknown exception -- aborting housekeeping run for this account", + *i); + } +#ifndef WIN32 // Check to see if there's any message pending - CheckForInterProcessMsg(0 /* no account */, millisecondsToGo); + CheckForInterProcessMsg(0 /* no account */); +#endif + + // Stop early? + if(StopRun()) + { + break; + } } + + ::syslog(LOG_INFO, "Finished housekeeping"); + + // Placed here for accuracy, if StopRun() is true, for example. + SetProcessTitle("housekeeping, idle"); } +#ifdef WIN32 +void BackupStoreDaemon::OnIdle() +{ + if (!mHousekeepingInited) + { + HousekeepingInit(); + mHousekeepingInited = true; + } + + RunHousekeepingIfNeeded(); +} +#endif // -------------------------------------------------------------------------- // @@ -128,6 +164,7 @@ void BackupStoreDaemon::HousekeepingProcess() // Created: 11/12/03 // // -------------------------------------------------------------------------- +#ifndef WIN32 bool BackupStoreDaemon::CheckForInterProcessMsg(int AccountNum, int MaximumWaitTime) { // First, check to see if it's EOF -- this means something has gone wrong, and the housekeeping should terminate. @@ -171,5 +208,6 @@ bool BackupStoreDaemon::CheckForInterProcessMsg(int AccountNum, int MaximumWaitT return false; } +#endif diff --git a/bin/bbstored/BackupCommands.cpp b/bin/bbstored/BackupCommands.cpp index 35bc095d..845903b2 100644 --- a/bin/bbstored/BackupCommands.cpp +++ b/bin/bbstored/BackupCommands.cpp @@ -9,7 +9,12 @@ #include "Box.h" +#ifdef HAVE_SYSLOG_H #include <syslog.h> +#endif + +#include <set> +#include <sstream> #include "autogen_BackupProtocolServer.h" #include "BackupConstants.h" @@ -327,8 +332,15 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProto std::auto_ptr<IOStream> diff2(rContext.OpenObject(patchID)); // Choose a temporary filename for the result of the combination - std::string tempFn(RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), rContext.GetStoreRoot() + ".recombinetemp", - p + 16 /* rotate which disc it's on */)); +#ifdef WIN32 + std::ostringstream fs(rContext.GetStoreRoot()); + fs << ".recombinetemp."; + fs << p; + std::string tempFn(fs.str()); + tempFn = RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), tempFn, p + 16); +#else + std::string tempFn(RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), rContext.GetStoreRoot() + ".recombinetemp", p + 16 /* rotate which disc it's on */)); +#endif // Open the temporary file std::auto_ptr<IOStream> combined; @@ -336,14 +348,23 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProto { { // Write nastily to allow this to work with gcc 2.x +#ifdef WIN32 + combined.reset(new FileStream( + tempFn.c_str(), + O_RDWR | O_CREAT | O_EXCL | + O_BINARY | O_TRUNC)); +#else std::auto_ptr<IOStream> t(new FileStream(tempFn.c_str(), O_RDWR | O_CREAT | O_EXCL)); combined = t; +#endif } +#ifndef WIN32 // Unlink immediately as it's a temporary file if(::unlink(tempFn.c_str()) != 0) { THROW_EXCEPTION(CommonException, OSFileError); } +#endif } catch(...) { @@ -359,6 +380,9 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProto combined->Seek(0, IOStream::SeekType_Absolute); // Then shuffle round for the next go +#ifdef WIN32 + if (from.get()) from->Close(); +#endif from = combined; } @@ -396,8 +420,9 @@ std::auto_ptr<ProtocolObject> BackupProtocolServerGetFile::DoCommand(BackupProto stream = t; } - // Object will be deleted when the stream is deleted, so can release the object auto_ptr here to - // avoid premature deletiong + // Object will be deleted when the stream is deleted, + // so can release the object auto_ptr here to avoid + // premature deletion object.release(); } diff --git a/bin/bbstored/BackupContext.cpp b/bin/bbstored/BackupContext.cpp index c796c13a..cd17812c 100644 --- a/bin/bbstored/BackupContext.cpp +++ b/bin/bbstored/BackupContext.cpp @@ -132,6 +132,7 @@ bool BackupContext::AttemptToGetWriteLock() // Request the lock bool gotLock = mWriteLock.TryAndGetLock(writeLockFile.c_str(), 0600 /* restrictive file permissions */); +#ifndef WIN32 if(!gotLock) { // The housekeeping process might have the thing open -- ask it to stop @@ -150,6 +151,7 @@ bool BackupContext::AttemptToGetWriteLock() } while(!gotLock && tries > 0); } +#endif if(gotLock) { @@ -453,13 +455,21 @@ int64_t BackupContext::AddFile(IOStream &rFile, int64_t InDirectory, int64_t Mod try { // Open it twice +#ifdef WIN32 + FileStream diff(tempFn.c_str(), + O_RDWR | O_CREAT | O_BINARY); + FileStream diff2(tempFn.c_str(), + O_RDWR | O_BINARY); +#else FileStream diff(tempFn.c_str(), O_RDWR | O_CREAT | O_EXCL); FileStream diff2(tempFn.c_str(), O_RDONLY); - // Unlink it immediately, so it definately goes away + + // Unlink it immediately, so it definitely goes away if(::unlink(tempFn.c_str()) != 0) { THROW_EXCEPTION(CommonException, OSFileError); } +#endif // Stream the incoming diff to this temporary file if(!rFile.CopyStreamTo(diff, BACKUP_STORE_TIMEOUT)) @@ -508,6 +518,14 @@ int64_t BackupContext::AddFile(IOStream &rFile, int64_t InDirectory, int64_t Mod ::unlink(tempFn.c_str()); throw; } + +#ifdef WIN32 + // we can't delete the file while it's open, above + if(::unlink(tempFn.c_str()) != 0) + { + THROW_EXCEPTION(CommonException, OSFileError); + } +#endif } // Get the blocks used diff --git a/bin/bbstored/BackupStoreDaemon.cpp b/bin/bbstored/BackupStoreDaemon.cpp index 2752893a..24a81ceb 100644 --- a/bin/bbstored/BackupStoreDaemon.cpp +++ b/bin/bbstored/BackupStoreDaemon.cpp @@ -11,9 +11,12 @@ #include <stdlib.h> #include <stdio.h> -#include <syslog.h> #include <signal.h> +#ifdef HAVE_SYSLOG_H +#include <syslog.h> +#endif + #include "BackupContext.h" #include "BackupStoreDaemon.h" #include "BackupStoreConfigVerify.h" @@ -39,7 +42,11 @@ BackupStoreDaemon::BackupStoreDaemon() mExtendedLogging(false), mHaveForkedHousekeeping(false), mIsHousekeepingProcess(false), +#ifdef WIN32 + mHousekeepingInited(false) +#else mInterProcessComms(mInterProcessCommsSocket) +#endif { } @@ -156,6 +163,7 @@ void BackupStoreDaemon::Run() const Configuration &config(GetConfiguration()); mExtendedLogging = config.GetKeyValueBool("ExtendedLogging"); +#ifndef WIN32 // Fork off housekeeping daemon -- must only do this the first time Run() is called if(!mHaveForkedHousekeeping) { @@ -219,9 +227,11 @@ void BackupStoreDaemon::Run() } else { +#endif // !WIN32 // In server process -- use the base class to do the magic ServerTLS<BOX_PORT_BBSTORED>::Run(); +#ifndef WIN32 // Why did it stop? Tell the housekeeping process to do the same if(IsReloadConfigWanted()) { @@ -232,6 +242,7 @@ void BackupStoreDaemon::Run() mInterProcessCommsSocket.Write("t\n", 2); } } +#endif } @@ -297,6 +308,8 @@ void BackupStoreDaemon::LogConnectionStats(const char *commonName, // Log the amount of data transferred ::syslog(LOG_INFO, "Connection statistics for %s: " "IN=%lld OUT=%lld TOTAL=%lld\n", commonName, - s.GetBytesRead(), s.GetBytesWritten(), - s.GetBytesRead() + s.GetBytesWritten()); + (long long)s.GetBytesRead(), + (long long)s.GetBytesWritten(), + (long long)s.GetBytesRead() + + (long long)s.GetBytesWritten()); } diff --git a/bin/bbstored/BackupStoreDaemon.h b/bin/bbstored/BackupStoreDaemon.h index 2fbe486d..857a9356 100644 --- a/bin/bbstored/BackupStoreDaemon.h +++ b/bin/bbstored/BackupStoreDaemon.h @@ -38,11 +38,13 @@ private: BackupStoreDaemon(const BackupStoreDaemon &rToCopy); public: +#ifndef WIN32 // For BackupContext to comminicate with housekeeping process void SendMessageToHousekeepingProcess(const void *Msg, int MsgLen) { mInterProcessCommsSocket.Write(Msg, MsgLen); } +#endif protected: @@ -57,9 +59,11 @@ protected: const ConfigurationVerify *GetConfigVerify() const; +#ifndef WIN32 // Housekeeping functions void HousekeepingProcess(); bool CheckForInterProcessMsg(int AccountNum = 0, int MaximumWaitTime = 0); +#endif void LogConnectionStats(const char *commonName, const SocketStreamTLS &s); @@ -70,8 +74,17 @@ private: bool mHaveForkedHousekeeping; bool mIsHousekeepingProcess; +#ifdef WIN32 + virtual void OnIdle(); + bool mHousekeepingInited; +#else SocketStream mInterProcessCommsSocket; IOStreamGetLine mInterProcessComms; +#endif + + void HousekeepingInit(); + void RunHousekeepingIfNeeded(); + int64_t mLastHousekeepingRun; }; diff --git a/bin/bbstored/HousekeepStoreAccount.cpp b/bin/bbstored/HousekeepStoreAccount.cpp index 4aa1999e..91945306 100644 --- a/bin/bbstored/HousekeepStoreAccount.cpp +++ b/bin/bbstored/HousekeepStoreAccount.cpp @@ -225,6 +225,7 @@ void HousekeepStoreAccount::MakeObjectFilename(int64_t ObjectID, std::string &rF // -------------------------------------------------------------------------- bool HousekeepStoreAccount::ScanDirectory(int64_t ObjectID) { +#ifndef WIN32 if((--mCountUntilNextInterprocessMsgCheck) <= 0) { mCountUntilNextInterprocessMsgCheck = POLL_INTERPROCESS_MSG_CHECK_FREQUENCY; @@ -235,6 +236,7 @@ bool HousekeepStoreAccount::ScanDirectory(int64_t ObjectID) return false; } } +#endif // Get the filename std::string objectFilename; @@ -251,6 +253,7 @@ bool HousekeepStoreAccount::ScanDirectory(int64_t ObjectID) // Read the directory in BackupStoreDirectory dir; dir.ReadFromStream(*dirStream, IOStream::TimeOutInfinite); + dirStream->Close(); // Is it empty? if(dir.GetNumberOfEntries() == 0) @@ -485,6 +488,7 @@ bool HousekeepStoreAccount::DeleteFiles() // (there is likely to be more in the set than should be actually deleted). for(std::set<DelEn, DelEnCompare>::iterator i(mPotentialDeletions.begin()); i != mPotentialDeletions.end(); ++i) { +#ifndef WIN32 if((--mCountUntilNextInterprocessMsgCheck) <= 0) { mCountUntilNextInterprocessMsgCheck = POLL_INTERPROCESS_MSG_CHECK_FREQUENCY; @@ -495,6 +499,7 @@ bool HousekeepStoreAccount::DeleteFiles() return true; } } +#endif // Load up the directory it's in // Get the filename @@ -729,6 +734,7 @@ bool HousekeepStoreAccount::DeleteEmptyDirectories() // Go through list for(std::vector<int64_t>::const_iterator i(mEmptyDirectories.begin()); i != mEmptyDirectories.end(); ++i) { +#ifndef WIN32 if((--mCountUntilNextInterprocessMsgCheck) <= 0) { mCountUntilNextInterprocessMsgCheck = POLL_INTERPROCESS_MSG_CHECK_FREQUENCY; @@ -739,6 +745,7 @@ bool HousekeepStoreAccount::DeleteEmptyDirectories() return true; } } +#endif // Do not delete the root directory if(*i == BACKUPSTORE_ROOT_DIRECTORY_ID) |