Skip to content

Commit cbdb157

Browse files
committed
Handle incompatible BDB environments
Before, opening a -datadir that was created with a new version of Berkeley DB would result in an un-caught DB_RUNRECOVERY exception. After these changes, the error is caught and the user is told that there is a problem and is told how to try to recover from it. Reference: bitcoin/bitcoin#1917
1 parent 32be82e commit cbdb157

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

src/db.cpp

+8-12
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,15 @@ void CDBEnv::EnvShutdown()
3737
return;
3838

3939
fDbEnvInit = false;
40-
try
41-
{
42-
dbenv.close(0);
43-
}
44-
catch (const DbException& e)
45-
{
46-
printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno());
47-
}
40+
int ret = dbenv.close(0);
41+
if (ret != 0)
42+
printf("EnvShutdown exception: %s (%d)\n", DbEnv::strerror(ret), ret);
43+
4844
if (!fMockDb)
4945
DbEnv(0).remove(GetDataDir().string().c_str(), 0);
5046
}
5147

52-
CDBEnv::CDBEnv() : dbenv(0)
48+
CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS)
5349
{
5450
}
5551

@@ -96,8 +92,8 @@ bool CDBEnv::Open(const boost::filesystem::path& path)
9692
DB_THREAD |
9793
DB_RECOVER,
9894
S_IRUSR | S_IWUSR);
99-
if (ret > 0)
100-
return error("CDB() : error %d opening database environment", ret);
95+
if (ret != 0)
96+
return error("CDB() : error %s (%d) opening database environment", DbEnv::strerror(ret), ret);
10197

10298
fDbEnvInit = true;
10399
fMockDb = false;
@@ -186,7 +182,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) :
186182
nFlags, // Flags
187183
0);
188184

189-
if (ret > 0)
185+
if (ret != 0)
190186
{
191187
delete pdb;
192188
pdb = NULL;

src/init.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,11 @@ bool AppInit2()
428428
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
429429
if (file) fclose(file);
430430
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
431+
/* Set a cstring to hold the datadir path cause we use it several times
432+
* throughout init. */
433+
const char* pszDataDir = GetDataDir().string().c_str();
431434
if (!lock.try_lock())
432-
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Paycoin is probably already running."), GetDataDir().string().c_str()));
435+
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Paycoin is probably already running."), pszDataDir));
433436

434437
#if !defined(WIN32) && !defined(QT_GUI)
435438
if (fDaemon)
@@ -459,7 +462,7 @@ bool AppInit2()
459462
printf("Paycoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
460463
printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
461464
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
462-
printf("Used data directory %s\n", GetDataDir().string().c_str());
465+
printf("Used data directory %s\n", pszDataDir);
463466

464467
// Check and update minium version protocol after a given time.
465468
if (time(NULL) >= MICROPRIMES_STAGGER_DOWN)
@@ -471,6 +474,15 @@ bool AppInit2()
471474
//
472475
if (fDaemon)
473476
fprintf(stdout, "Paycoin server starting\n");
477+
478+
if (!bitdb.Open(GetDataDir()))
479+
{
480+
string msg = strprintf(_("Error initializing database environment %s!"
481+
" To recover, BACKUP THAT DIRECTORY, then remove"
482+
" everything from it except for wallet.dat."), pszDataDir);
483+
return InitError(msg);
484+
}
485+
474486
int64 nStart;
475487

476488
// ********************************************************* Step 5: network initialization
@@ -582,7 +594,7 @@ bool AppInit2()
582594
printf("Loading block index...\n");
583595
nStart = GetTimeMillis();
584596
if (!LoadBlockIndex())
585-
strErrors << _("Error loading blkindex.dat") << "\n";
597+
return InitError(_("Error loading blkindex.dat"));
586598

587599
// as LoadBlockIndex can take several minutes, it's possible the user
588600
// requested to kill bitcoin-qt during the last operation. If so, exit.

0 commit comments

Comments
 (0)