[Box Backup-dev] COMMIT r324 - in box/chris/diff-timeout-and-ssl-keepalive: . bin/bbackupd bin/bbstored lib/backupclient
boxbackup-dev at fluffy.co.uk
boxbackup-dev at fluffy.co.uk
Wed Jan 18 23:34:10 GMT 2006
Author: chris
Date: 2006-01-18 23:34:07 +0000 (Wed, 18 Jan 2006)
New Revision: 324
Modified:
box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.cpp
box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.h
box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientDirectoryRecord.cpp
box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupDaemon.cpp
box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/BackupCommands.cpp
box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/backupprotocol.txt
box/chris/diff-timeout-and-ssl-keepalive/configure.ac
box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupDaemonConfigVerify.cpp
box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFile.h
box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFileDiff.cpp
Log:
* bb-diff-keepalive
- Merged Gary's diffing timeout and SSL keepalive patches into this copy
of the trunk. The client store marker (de)serialisation patch is NOT
merged. All tests pass on FC2 i386. Additional work is required on the
signal handler to make it truly safe.
Modified: box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.cpp
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.cpp 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.cpp 2006-01-18 23:34:07 UTC (rev 324)
@@ -9,9 +9,15 @@
#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"
#include "BoxTime.h"
@@ -22,6 +28,7 @@
#include "BackupStoreException.h"
#include "BackupDaemon.h"
#include "autogen_BackupProtocolClient.h"
+#include "BackupStoreFile.h"
#include "MemLeakFindOn.h"
@@ -48,7 +55,8 @@
mpNewIDMap(0),
mStorageLimitExceeded(false),
mpExcludeFiles(0),
- mpExcludeDirs(0)
+ mpExcludeDirs(0),
+ mbIsManaged(false)
{
}
@@ -453,3 +461,166 @@
}
+// maximum time to spend diffing
+static int sMaximumDiffTime = 600;
+// maximum time of SSL inactivity (keep-alive interval)
+static int sKeepAliveTime = 0;
+// total time elapsed to keep track of what is going on
+static time_t sTimeMgmtEpoch = 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);
+}
+
+static BackupClientContext* pThisCtxInst = NULL;
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: static TimerSigHandler(int)
+// Purpose: Signal handler
+// Created: 19/3/04
+//
+// --------------------------------------------------------------------------
+void TimerSigHandler(int iUnused)
+{
+ ASSERT(pThisCtxInst);
+ ASSERT(sTimeMgmtEpoch > 0);
+
+ time_t tTotalRunIntvl = time(NULL) - sTimeMgmtEpoch;
+ if (sMaximumDiffTime > 0 && tTotalRunIntvl >= sMaximumDiffTime)
+ {
+ TRACE0("MaximumDiffingTime reached - suspending file diff\n");
+ BackupStoreFile::SuspendFileDiff();
+ }
+ else if (sKeepAliveTime > 0)
+ {
+ // well, we have only two sources of timer events...
+ TRACE0("KeepAliveTime reached - initiating keep-alive\n");
+ pThisCtxInst->DoKeepAlive();
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupClientContext::ManageDiffProcess()
+// Purpose: Initiates a file diff control timer
+// Created: 04/19/2005
+//
+// --------------------------------------------------------------------------
+void BackupClientContext::ManageDiffProcess()
+{
+ if (mbIsManaged || !mpConnection)
+ return;
+
+ ASSERT(pThisCtxInst == NULL);
+ ASSERT(sTimeMgmtEpoch == 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
+ pThisCtxInst = this;
+ sTimeMgmtEpoch = time(NULL);
+
+#ifdef PLATFORM_CYGWIN
+ if(::setitimer(ITIMER_REAL, &timeout, NULL) != 0)
+#else
+ if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0)
+#endif // PLATFORM_CYGWIN
+ {
+ sTimeMgmtEpoch = 0;
+ pThisCtxInst = NULL;
+
+ 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;
+
+ ASSERT(pThisCtxInst != NULL);
+
+ 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;
+ pThisCtxInst = NULL;
+ sTimeMgmtEpoch = 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();
+}
Modified: box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.h
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.h 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientContext.h 2006-01-18 23:34:07 UTC (rev 324)
@@ -134,6 +134,55 @@
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
+ // Created: 04/19/2005
+ //
+ // --------------------------------------------------------------------------
+ void DoKeepAlive();
private:
BackupDaemon &mrDaemon;
TLSContext &mrTLSContext;
@@ -149,6 +198,8 @@
bool mStorageLimitExceeded;
ExcludeList *mpExcludeFiles;
ExcludeList *mpExcludeDirs;
+
+ bool mbIsManaged;
};
Modified: box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientDirectoryRecord.cpp
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientDirectoryRecord.cpp 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupClientDirectoryRecord.cpp 2006-01-18 23:34:07 UTC (rev 324)
@@ -1093,14 +1093,23 @@
// 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(),
mObjectID, /* containing directory */
rStoreFilename, diffFromID, *blockIndexStream,
connection.GetTimeout(), 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 +1139,8 @@
}
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...
Modified: box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupDaemon.cpp 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/bin/bbackupd/BackupDaemon.cpp 2006-01-18 23:34:07 UTC (rev 324)
@@ -435,11 +435,15 @@
// 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 @@
{
#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?
Modified: box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/BackupCommands.cpp
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/BackupCommands.cpp 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/BackupCommands.cpp 2006-01-18 23:34:07 UTC (rev 324)
@@ -859,3 +859,20 @@
));
}
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BackupProtocolServerGetIsAlive::DoCommand(BackupProtocolServer &, BackupContext &)
+// Purpose: Return the amount of disc space used
+// Created: 19/4/04
+//
+// --------------------------------------------------------------------------
+std::auto_ptr<ProtocolObject> BackupProtocolServerGetIsAlive::DoCommand(BackupProtocolServer &rProtocol, BackupContext &rContext)
+{
+ CHECK_PHASE(Phase_Commands)
+
+ //
+ // NOOP
+ //
+ return std::auto_ptr<ProtocolObject>(new BackupProtocolServerIsAlive());
+}
Modified: box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/backupprotocol.txt
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/backupprotocol.txt 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/bin/bbstored/backupprotocol.txt 2006-01-18 23:34:07 UTC (rev 324)
@@ -219,3 +219,10 @@
int64 BlocksSoftLimit
int64 BlocksHardLimit
int32 BlockSize
+
+GetIsAlive 42 Command(IsAlive)
+ # no data members
+
+IsAlive 43 Reply
+ # no data members
+
Modified: box/chris/diff-timeout-and-ssl-keepalive/configure.ac
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/configure.ac 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/configure.ac 2006-01-18 23:34:07 UTC (rev 324)
@@ -75,7 +75,8 @@
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([execinfo.h netinet/in.h regex.h sys/types.h sys/xattr.h])
-AC_CHECK_HEADERS([sys/endian.h asm/byteorder.h])
+AC_CHECK_HEADERS([sys/endian.h asm/byteorder.h syslog.h signal.h sys/time.h])
+AC_CHECK_HEADERS([time.h])
### Checks for typedefs, structures, and compiler characteristics.
Modified: box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupDaemonConfigVerify.cpp
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupDaemonConfigVerify.cpp 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupDaemonConfigVerify.cpp 2006-01-18 23:34:07 UTC (rev 324)
@@ -84,6 +84,7 @@
{"ExtendedLogging", "no", ConfigTest_IsBool, 0}, // make value "yes" to enable in config file
{"CommandSocket", 0, 0, 0}, // not compulsory to have this
+ {"KeepAliveTime", 0, ConfigTest_IsInt, 0}, // optional
{"NotifyScript", 0, 0, 0}, // optional script to run when backup needs attention, eg store full
Modified: box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFile.h
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFile.h 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFile.h 2006-01-18 23:34:07 UTC (rev 324)
@@ -144,8 +144,17 @@
free(a);
}
- // Limits
- static void SetMaximumDiffingTime(int Seconds);
+ // --------------------------------------------------------------------------
+ //
+ // Function
+ // Name: BackupStoreFile::SuspendFileDiff()
+ // Purpose: Notifies BackupStoreFile object that a diff operation should be
+ // terminated ASAP. Usually called from an external timer.
+ //
+ // Created: 12/1/04
+ //
+ // --------------------------------------------------------------------------
+ static void SuspendFileDiff();
// Building blocks
class EncodingBuffer
Modified: box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFileDiff.cpp
===================================================================
--- box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFileDiff.cpp 2006-01-18 22:45:54 UTC (rev 323)
+++ box/chris/diff-timeout-and-ssl-keepalive/lib/backupclient/BackupStoreFileDiff.cpp 2006-01-18 23:34:07 UTC (rev 324)
@@ -11,11 +11,11 @@
#include <new>
#include <map>
-#include <signal.h>
-#ifdef WIN32
-#include <time.h>
-#else
-#include <sys/time.h>
+
+#ifdef HAVE_TIME_H
+ #include <time.h>
+#elif HAVE_SYS_TIME_H
+ #include <sys/time.h>
#endif
#include "BackupStoreFile.h"
@@ -49,27 +49,23 @@
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);
-// Avoid running on too long with diffs
-static int sMaximumDiffTime = 600; // maximum time to spend diffing
+// control whether a currently active diff should be terminated ASAP
static bool sDiffTimedOut = false;
-static bool sSetTimerSignelHandler = false;
-static void TimerSignalHandler(int signal);
-static void StartDiffTimer();
// --------------------------------------------------------------------------
//
// Function
-// Name: BackupStoreFile::SetMaximumDiffingTime(int)
-// Purpose: Sets the maximum time to spend diffing, in seconds. Time is
-// process virutal time.
-// Created: 19/3/04
+// Name: BackupStoreFile::SuspendFileDiff()
+// Purpose: Notifies BackupStoreFile object that a diff operation should be
+// terminated ASAP. Usually called from an external timer.
//
+// Created: 12/1/04
+//
// --------------------------------------------------------------------------
-void BackupStoreFile::SetMaximumDiffingTime(int Seconds)
+void BackupStoreFile::SuspendFileDiff()
{
- sMaximumDiffTime = Seconds;
- TRACE1("Set maximum diffing time to %d seconds\n", Seconds);
+ sDiffTimedOut = true;
}
@@ -180,9 +176,6 @@
// Pointer to recipe we're going to create
BackupStoreFileEncodeStream::Recipe *precipe = 0;
-
- // Start the timeout timer, so that the operation doesn't continue for ever
- StartDiffTimer();
try
{
@@ -1005,55 +998,3 @@
}
#endif
}
-
-
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: static TimerSignalHandler(int)
-// Purpose: Signal handler
-// Created: 19/3/04
-//
-// --------------------------------------------------------------------------
-void TimerSignalHandler(int signal)
-{
- sDiffTimedOut = true;
-}
-
-
-// --------------------------------------------------------------------------
-//
-// Function
-// Name: static StartDiffTimer()
-// Purpose: Starts the diff timeout timer
-// Created: 19/3/04
-//
-// --------------------------------------------------------------------------
-void StartDiffTimer()
-{
- // Set timer signal handler
- if(!sSetTimerSignelHandler)
- {
- ::signal(SIGVTALRM, TimerSignalHandler);
- sSetTimerSignelHandler = true;
- }
-
- struct itimerval timeout;
- // Don't want this to repeat
- timeout.it_interval.tv_sec = 0;
- timeout.it_interval.tv_usec = 0;
- // Single timeout after the specified number of seconds
- timeout.it_value.tv_sec = sMaximumDiffTime;
- timeout.it_value.tv_usec = 0;
- // Set timer
- if(::setitimer(ITIMER_VIRTUAL, &timeout, NULL) != 0)
- {
- TRACE0("WARNING: couldn't set diff timeout\n");
- }
-
- // Unset flag (last thing)
- sDiffTimedOut = false;
-}
-
-
-
More information about the Boxbackup-dev
mailing list