[Box Backup-commit] COMMIT r3157 - in box/trunk: bin/bbstoreaccounts lib/backupstore

subversion at boxbackup.org subversion at boxbackup.org
Sun Nov 18 16:29:41 GMT 2012


Author: chris
Date: 2012-11-18 16:29:41 +0000 (Sun, 18 Nov 2012)
New Revision: 3157

Modified:
   box/trunk/bin/bbstoreaccounts/bbstoreaccounts.cpp
   box/trunk/lib/backupstore/BackupStoreAccounts.cpp
   box/trunk/lib/backupstore/BackupStoreAccounts.h
   box/trunk/lib/backupstore/BackupStoreCheck.cpp
Log:
Add a helper in BackupStoreAccounts to get a write lock on an account.
Use it in two places to simplify code (not in BackupStoreContext yet,
because that wants to communicate with HK process as well).


Modified: box/trunk/bin/bbstoreaccounts/bbstoreaccounts.cpp
===================================================================
--- box/trunk/bin/bbstoreaccounts/bbstoreaccounts.cpp	2012-11-18 16:26:43 UTC (rev 3156)
+++ box/trunk/bin/bbstoreaccounts/bbstoreaccounts.cpp	2012-11-18 16:29:41 UTC (rev 3157)
@@ -128,37 +128,8 @@
 	}
 }
 
-bool GetWriteLockOnAccount(NamedLock &rLock, const std::string rRootDir,
-	int discSetNum)
-{
-	std::string writeLockFilename;
-	StoreStructure::MakeWriteLockFilename(rRootDir, discSetNum, writeLockFilename);
-
-	bool gotLock = false;
-	int triesLeft = 8;
-	do
-	{
-		gotLock = rLock.TryAndGetLock(writeLockFilename.c_str(), 0600 /* restrictive file permissions */);
-		
-		if(!gotLock)
-		{
-			--triesLeft;
-			::sleep(1);
-		}
-	} while(!gotLock && triesLeft > 0);
-
-	if(!gotLock)
-	{
-		// Couldn't lock the account -- just stop now
-		BOX_ERROR("Failed to lock the account, did not change limits. "
-			"Try again later.");
-	}
-
-	return gotLock;
-}
-
 bool OpenAccount(Configuration &rConfig, int32_t ID, std::string &rRootDirOut,
-	int &rDiscSetOut, std::auto_ptr<UnixUser> apUser);
+	int &rDiscSetOut, std::auto_ptr<UnixUser> apUser, NamedLock* pLock);
 
 int SetLimit(Configuration &rConfig, int32_t ID, const char *SoftLimitStr,
 	const char *HardLimitStr)
@@ -166,22 +137,15 @@
 	std::string rootDir;
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
+	NamedLock writeLock;
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " to change limits.");
 		return 1;
 	}
 	
-	// Attempt to lock
-	NamedLock writeLock;
-	if(!GetWriteLockOnAccount(writeLock, rootDir, discSetNum))
-	{
-		// Failed to get lock
-		return 1;
-	}
-
 	// Load the info
 	std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID, rootDir,
 		discSetNum, false /* Read/Write */));
@@ -208,22 +172,15 @@
 	std::string rootDir;
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
+	NamedLock writeLock;
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " to change name.");
 		return 1;
 	}
 
-	// Attempt to lock
-	NamedLock writeLock;
-	if(!GetWriteLockOnAccount(writeLock, rootDir, discSetNum))
-	{
-		// Failed to get lock
-		return 1;
-	}
-
 	// Load the info
 	std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(ID,
 		rootDir, discSetNum, false /* Read/Write */));
@@ -245,7 +202,8 @@
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user,
+		NULL /* no write lock needed for this read-only operation */))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " to display info.");
@@ -306,8 +264,9 @@
 	std::string rootDir;
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
+	NamedLock writeLock;
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " to change enabled flag.");
@@ -327,8 +286,10 @@
 	std::string rootDir;
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
+	NamedLock writeLock;
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	// Obtain a write lock, as the daemon user
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " for deletion.");
@@ -348,19 +309,8 @@
 		}
 	}
 	
-	// Obtain a write lock, as the daemon user
-	NamedLock writeLock;
-	{
-		// Get a write lock
-		if(!GetWriteLockOnAccount(writeLock, rootDir, discSetNum))
-		{
-			// Failed to get lock
-			return 1;
-		}
-		
-		// Back to original user, but write lock is maintained
-		user.reset();
-	}
+	// Back to original user, but write lock is maintained
+	user.reset();
 
 	std::auto_ptr<BackupStoreAccountDatabase> db(BackupStoreAccountDatabase::Read(rConfig.GetKeyValue("AccountDatabase").c_str()));
 
@@ -431,7 +381,7 @@
 }
 
 bool OpenAccount(Configuration &rConfig, int32_t ID, std::string &rRootDirOut,
-	int &rDiscSetOut, std::auto_ptr<UnixUser> apUser)
+	int &rDiscSetOut, std::auto_ptr<UnixUser> apUser, NamedLock* pLock)
 {
 	// Load in the account database 
 	std::auto_ptr<BackupStoreAccountDatabase> db(BackupStoreAccountDatabase::Read(rConfig.GetKeyValue("AccountDatabase").c_str()));
@@ -468,6 +418,11 @@
 		// in the caller.
 	}
 
+	if(pLock)
+	{
+		acc.LockAccount(ID, *pLock);
+	}
+
 	return true;
 }
 
@@ -476,8 +431,9 @@
 	std::string rootDir;
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
+	NamedLock writeLock;
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user, &writeLock))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " for checking.");
@@ -530,7 +486,8 @@
 	int discSetNum;
 	std::auto_ptr<UnixUser> user; // used to reset uid when we return
 
-	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user))
+	if(!OpenAccount(rConfig, ID, rootDir, discSetNum, user,
+		NULL /* housekeeping locks the account itself */))
 	{
 		BOX_ERROR("Failed to open account " << BOX_FORMAT_ACCOUNT(ID)
 			<< " for housekeeping.");

Modified: box/trunk/lib/backupstore/BackupStoreAccounts.cpp
===================================================================
--- box/trunk/lib/backupstore/BackupStoreAccounts.cpp	2012-11-18 16:26:43 UTC (rev 3156)
+++ box/trunk/lib/backupstore/BackupStoreAccounts.cpp	2012-11-18 16:29:41 UTC (rev 3157)
@@ -11,14 +11,16 @@
 
 #include <stdio.h>
 
-#include "BoxPortsAndFiles.h"
 #include "BackupStoreAccounts.h"
 #include "BackupStoreAccountDatabase.h"
+#include "BackupStoreConstants.h"
+#include "BackupStoreDirectory.h"
+#include "BackupStoreException.h"
+#include "BackupStoreInfo.h"
 #include "BackupStoreRefCountDatabase.h"
+#include "BoxPortsAndFiles.h"
 #include "RaidFileWrite.h"
-#include "BackupStoreInfo.h"
-#include "BackupStoreDirectory.h"
-#include "BackupStoreConstants.h"
+#include "StoreStructure.h"
 #include "UnixUser.h"
 
 #include "MemLeakFindOn.h"
@@ -168,4 +170,34 @@
 	return mrDatabase.EntryExists(ID);
 }
 
+void BackupStoreAccounts::LockAccount(int32_t ID, NamedLock& rNamedLock)
+{
+	const BackupStoreAccountDatabase::Entry &en(mrDatabase.GetEntry(ID));
+	std::string rootDir = MakeAccountRootDir(ID, en.GetDiscSet());
+	int discSet = en.GetDiscSet();
 
+	std::string writeLockFilename;
+	StoreStructure::MakeWriteLockFilename(rootDir, discSet, writeLockFilename);
+
+	bool gotLock = false;
+	int triesLeft = 8;
+	do
+	{
+		gotLock = rNamedLock.TryAndGetLock(writeLockFilename,
+			0600 /* restrictive file permissions */);
+		
+		if(!gotLock)
+		{
+			--triesLeft;
+			::sleep(1);
+		}
+	}
+	while (!gotLock && triesLeft > 0);
+
+	if (!gotLock)
+	{
+		THROW_EXCEPTION_MESSAGE(BackupStoreException,
+			CouldNotLockStoreAccount, "Failed to get exclusive "
+			"lock on account " << ID);
+	}
+}

Modified: box/trunk/lib/backupstore/BackupStoreAccounts.h
===================================================================
--- box/trunk/lib/backupstore/BackupStoreAccounts.h	2012-11-18 16:26:43 UTC (rev 3156)
+++ box/trunk/lib/backupstore/BackupStoreAccounts.h	2012-11-18 16:29:41 UTC (rev 3157)
@@ -13,6 +13,7 @@
 #include <string>
 
 #include "BackupStoreAccountDatabase.h"
+#include "NamedLock.h"
 
 // --------------------------------------------------------------------------
 //
@@ -41,6 +42,7 @@
 	{
 		return MakeAccountRootDir(rEntry.GetID(), rEntry.GetDiscSet());
 	}
+	void LockAccount(int32_t ID, NamedLock& rNamedLock);
 
 private:
 	static std::string MakeAccountRootDir(int32_t ID, int DiscSet);

Modified: box/trunk/lib/backupstore/BackupStoreCheck.cpp
===================================================================
--- box/trunk/lib/backupstore/BackupStoreCheck.cpp	2012-11-18 16:26:43 UTC (rev 3156)
+++ box/trunk/lib/backupstore/BackupStoreCheck.cpp	2012-11-18 16:29:41 UTC (rev 3157)
@@ -81,41 +81,17 @@
 //
 // Function
 //		Name:    BackupStoreCheck::Check()
-//		Purpose: Perform the check on the given account
+//		Purpose: Perform the check on the given account. You need to
+//			 hold a lock on the account before calling this!
 //		Created: 21/4/04
 //
 // --------------------------------------------------------------------------
 void BackupStoreCheck::Check()
 {
-	// Lock the account
-	{
-		std::string writeLockFilename;
-		StoreStructure::MakeWriteLockFilename(mStoreRoot, mDiscSetNumber, writeLockFilename);
+	std::string writeLockFilename;
+	StoreStructure::MakeWriteLockFilename(mStoreRoot, mDiscSetNumber, writeLockFilename);
+	ASSERT(FileExists(writeLockFilename));
 
-		bool gotLock = false;
-		int triesLeft = 8;
-		do
-		{
-			gotLock = mAccountLock.TryAndGetLock(writeLockFilename.c_str(), 0600 /* restrictive file permissions */);
-			
-			if(!gotLock)
-			{
-				--triesLeft;
-				::sleep(1);
-			}
-		} while(!gotLock && triesLeft > 0);
-	
-		if(!gotLock)
-		{
-			// Couldn't lock the account -- just stop now
-			if(!mQuiet)
-			{
-				BOX_ERROR("Failed to lock the account -- did not check.\nTry again later after the client has disconnected.\nAlternatively, forcibly kill the server.");
-			}
-			THROW_EXCEPTION(BackupStoreException, CouldNotLockStoreAccount)
-		}
-	}
-
 	if(!mQuiet && mFixErrors)
 	{
 		BOX_NOTICE("Will fix errors encountered during checking.");




More information about the Boxbackup-commit mailing list