[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