[Box Backup-commit] COMMIT r1433 - in box/chris/general: bin/bbackupd lib/common lib/server

boxbackup-dev@fluffy.co.uk boxbackup-dev@fluffy.co.uk
Thu, 22 Mar 2007 23:45:24 +0000


Author: chris
Date: 2007-03-22 23:45:24 +0000 (Thu, 22 Mar 2007)
New Revision: 1433

Added:
   box/chris/general/lib/common/ServerControl.h
Modified:
   box/chris/general/bin/bbackupd/BackupClientDirectoryRecord.cpp
   box/chris/general/bin/bbackupd/BackupDaemon.cpp
   box/chris/general/bin/bbackupd/BackupDaemon.h
   box/chris/general/lib/server/Daemon.cpp
Log:
Merge changes from chris/merge tree:

Trace reasons for uploading (or not) each file.

Log at trace level by default in debug builds.

Add a new notification constant, NotifyEvent_BackupError, for use when
an exception occurs during the backup.

Make bbackupd notify sysadmin when an exception occurs during the backup,
using this error code, and the notification string "backup-error".

Change NotifyEvent__MAX to be one greater than the highest notification
constant, makes code more maintainable.


Modified: box/chris/general/bin/bbackupd/BackupClientDirectoryRecord.cpp
===================================================================
--- box/chris/general/bin/bbackupd/BackupClientDirectoryRecord.cpp	2007-03-22 23:38:47 UTC (rev 1432)
+++ box/chris/general/bin/bbackupd/BackupClientDirectoryRecord.cpp	2007-03-22 23:45:24 UTC (rev 1433)
@@ -30,6 +30,7 @@
 #include "BackupStoreException.h"
 #include "Archive.h"
 #include "PathUtils.h"
+#include "Logging.h"
 
 #include "MemLeakFindOn.h"
 
@@ -793,10 +794,14 @@
 				if (pDirOnStore != 0 && en == 0)
 				{
 					doUpload = true;
+					BOX_TRACE(filename << ": will upload "
+						"(not on server)");
 				}
 				else if (modTime >= rParams.mSyncPeriodStart)
 				{
 					doUpload = true;
+					BOX_TRACE(filename << ": will upload "
+						"(modified since last sync)");
 				}
 			}
 
@@ -813,6 +818,8 @@
 				> rParams.mMaxUploadWait)
 			{
 				doUpload = true;
+				BOX_TRACE(filename << ": will upload "
+					"(continually modified)");
 			}
 
 			// Then make sure that if files are added with a 
@@ -828,6 +835,8 @@
 				en->GetModificationTime() != modTime)
 			{
 				doUpload = true;
+				BOX_TRACE(filename << ": will upload "
+					"(mod time changed)");
 			}
 
 			// And just to catch really badly off clocks in 
@@ -838,9 +847,20 @@
 				rParams.mUploadAfterThisTimeInTheFuture)
 			{
 				doUpload = true;
+				BOX_TRACE(filename << ": will upload "
+					"(mod time in the future)");
 			}
 		}
 
+		if (!doUpload)
+		{
+			BOX_TRACE(filename << ": will not upload "
+				"(no reason to upload, mod time is "
+				<< modTime << " versus sync period "
+				<< rParams.mSyncPeriodStart << " to "
+				<< rParams.mSyncPeriodEnd << ")");
+		}
+
 		if (doUpload)
 		{
 			// Make sure we're connected -- must connect here so we know whether

Modified: box/chris/general/bin/bbackupd/BackupDaemon.cpp
===================================================================
--- box/chris/general/bin/bbackupd/BackupDaemon.cpp	2007-03-22 23:38:47 UTC (rev 1432)
+++ box/chris/general/bin/bbackupd/BackupDaemon.cpp	2007-03-22 23:45:24 UTC (rev 1433)
@@ -119,8 +119,8 @@
 	// Only ever one instance of a daemon
 	SSLLib::Initialise();
 	
-	// Initialise notifcation sent status
-	for(int l = 0; l <= NotifyEvent__MAX; ++l)
+	// Initialise notification sent status
+	for(int l = 0; l < NotifyEvent__MAX; ++l)
 	{
 		mNotificationsSent[l] = false;
 	}
@@ -963,6 +963,8 @@
 				else
 				{
 					// Not restart/terminate, pause and retry
+					// Notify administrator
+					NotifySysadmin(NotifyEvent_BackupError);
 					SetState(State_Error);
 					BOX_ERROR("Exception caught ("
 						<< errorString
@@ -2092,11 +2094,17 @@
 // --------------------------------------------------------------------------
 void BackupDaemon::NotifySysadmin(int Event)
 {
-	static const char *sEventNames[] = {"store-full", "read-error", 0};
+	static const char *sEventNames[] = 
+	{
+		"store-full",
+		"read-error", 
+		"backup-error",
+		0
+	};
 
 	BOX_TRACE("BackupDaemon::NotifySysadmin() called, event = " << Event);
 
-	if(Event < 0 || Event > NotifyEvent__MAX)
+	if(Event < 0 || Event >= NotifyEvent__MAX)
 	{
 		THROW_EXCEPTION(BackupStoreException, BadNotifySysadminEventCode);
 	}

Modified: box/chris/general/bin/bbackupd/BackupDaemon.h
===================================================================
--- box/chris/general/bin/bbackupd/BackupDaemon.h	2007-03-22 23:38:47 UTC (rev 1432)
+++ box/chris/general/bin/bbackupd/BackupDaemon.h	2007-03-22 23:45:24 UTC (rev 1433)
@@ -82,8 +82,9 @@
 	enum
 	{
 		NotifyEvent_StoreFull = 0,
-		NotifyEvent_ReadError = 1,
-		NotifyEvent__MAX = 1
+		NotifyEvent_ReadError,
+		NotifyEvent_BackupError,
+		NotifyEvent__MAX
 		// When adding notifications, remember to add strings to NotifySysadmin()
 	};
 	void NotifySysadmin(int Event);
@@ -177,7 +178,7 @@
 	CommandSocketInfo *mpCommandSocketInfo;
 	
 	// Stop notifications being repeated.
-	bool mNotificationsSent[NotifyEvent__MAX + 1];
+	bool mNotificationsSent[NotifyEvent__MAX];
 
 	// Unused entries in the root directory wait a while before being deleted
 	box_time_t mDeleteUnusedRootDirEntriesAfter;	// time to delete them

Copied: box/chris/general/lib/common/ServerControl.h (from rev 1430, box/chris/merge/lib/common/ServerControl.h)
===================================================================
--- box/chris/general/lib/common/ServerControl.h	                        (rev 0)
+++ box/chris/general/lib/common/ServerControl.h	2007-03-22 23:45:24 UTC (rev 1433)
@@ -0,0 +1,177 @@
+#ifndef SERVER_CONTROL_H
+#define SERVER_CONTROL_H
+
+#ifdef WIN32
+
+#include "WinNamedPipeStream.h"
+#include "IOStreamGetLine.h"
+#include "BoxPortsAndFiles.h"
+#include "Test.h"
+
+static bool SendCommands(const std::string& rCmd)
+{
+	WinNamedPipeStream connection;
+
+	try
+	{
+		connection.Connect(BOX_NAMED_PIPE_NAME);
+	}
+	catch(...)
+	{
+		printf("Failed to connect to daemon control socket.\n");
+		return false;
+	}
+
+	// For receiving data
+	IOStreamGetLine getLine(connection);
+	
+	// Wait for the configuration summary
+	std::string configSummary;
+	if(!getLine.GetLine(configSummary))
+	{
+		printf("Failed to receive configuration summary from daemon\n");
+		return false;
+	}
+
+	// Was the connection rejected by the server?
+	if(getLine.IsEOF())
+	{
+		printf("Server rejected the connection.\n");
+		return false;
+	}
+
+	// Decode it
+	int autoBackup, updateStoreInterval, minimumFileAge, maxUploadWait;
+	if(::sscanf(configSummary.c_str(), "bbackupd: %d %d %d %d", 
+			&autoBackup, &updateStoreInterval, 
+			&minimumFileAge, &maxUploadWait) != 4)
+	{
+		printf("Config summary didn't decode\n");
+		return false;
+	}
+
+	std::string cmds;
+	bool expectResponse;
+
+	if (rCmd != "")
+	{
+		cmds = rCmd;
+		cmds += "\nquit\n";
+		expectResponse = true;
+	}
+	else
+	{
+		cmds = "quit\n";
+		expectResponse = false;
+	}
+	
+	connection.Write(cmds.c_str(), cmds.size());
+	
+	// Read the response
+	std::string line;
+	bool statusOk = !expectResponse;
+
+	while (expectResponse && !getLine.IsEOF() && getLine.GetLine(line))
+	{
+		// Is this an OK or error line?
+		if (line == "ok")
+		{
+			statusOk = true;
+		}
+		else if (line == "error")
+		{
+			printf("ERROR (%s)\n", rCmd.c_str());
+			break;
+		}
+		else
+		{
+			printf("WARNING: Unexpected response to command '%s': "
+				"%s", rCmd.c_str(), line.c_str());
+		}
+	}
+	
+	return statusOk;
+}
+
+inline bool HUPServer(int pid)
+{
+	return SendCommands("reload");
+}
+
+inline bool KillServerInternal(int pid)
+{
+	HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, false, pid);
+	if (hProcess == NULL)
+	{
+		printf("Failed to open process %d: error %d\n",
+			pid, (int)GetLastError());
+		return false;
+	}
+
+	if (!TerminateProcess(hProcess, 1))
+	{
+		printf("Failed to terminate process %d: error %d\n",
+			pid, (int)GetLastError());
+		CloseHandle(hProcess);
+		return false;
+	}
+
+	CloseHandle(hProcess);
+	return true;
+}
+
+#else // !WIN32
+
+inline bool HUPServer(int pid)
+{
+	if(pid == 0) return false;
+	return ::kill(pid, SIGHUP) == 0;
+}
+
+inline bool KillServerInternal(int pid)
+{
+	if(pid == 0 || pid == -1) return false;
+	bool killed = (::kill(pid, SIGTERM) == 0);
+	TEST_THAT(killed);
+	return killed;
+}
+
+#endif // WIN32
+
+inline bool KillServer(int pid)
+{
+	if (!KillServerInternal(pid))
+	{
+		return false;
+	}
+
+	for (int i = 0; i < 30; i++)
+	{
+		if (!ServerIsAlive(pid)) break;
+		::sleep(1);
+		if (!ServerIsAlive(pid)) break;
+
+		if (i == 0) 
+		{
+			printf("waiting for server to die");
+		}
+
+		printf(".");
+		fflush(stdout);
+	}
+
+	if (!ServerIsAlive(pid))
+	{
+		printf("done.\n");
+	}
+	else
+	{
+		printf("failed!\n");
+	}
+
+	fflush(stdout);
+
+	return !ServerIsAlive(pid);
+}
+
+#endif // SERVER_CONTROL_H

Modified: box/chris/general/lib/server/Daemon.cpp
===================================================================
--- box/chris/general/lib/server/Daemon.cpp	2007-03-22 23:38:47 UTC (rev 1432)
+++ box/chris/general/lib/server/Daemon.cpp	2007-03-22 23:45:24 UTC (rev 1433)
@@ -101,7 +101,13 @@
 	mConfigFileName = DefaultConfigFile;
 	bool haveConfigFile = false;
 	bool singleProcess  = false;
+
+	#ifdef NDEBUG
 	int masterLevel = Log::NOTICE; // need an int to do math with
+	#else
+	int masterLevel = Log::TRACE; // need an int to do math with
+	#endif
+
 	char c;
 
 	while((c = getopt(argc, (char * const *)argv, "c:Dqv")) != -1)