[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