Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/db.cpp
Show First 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | |||||
CDBEnv::~CDBEnv() { | CDBEnv::~CDBEnv() { | ||||
EnvShutdown(); | EnvShutdown(); | ||||
} | } | ||||
void CDBEnv::Close() { | void CDBEnv::Close() { | ||||
EnvShutdown(); | EnvShutdown(); | ||||
} | } | ||||
bool CDBEnv::Open(const fs::path &pathIn) { | bool CDBEnv::Open(const fs::path &pathIn, bool retry) { | ||||
if (fDbEnvInit) { | if (fDbEnvInit) { | ||||
return true; | return true; | ||||
} | } | ||||
boost::this_thread::interruption_point(); | boost::this_thread::interruption_point(); | ||||
strPath = pathIn.string(); | strPath = pathIn.string(); | ||||
if (!LockDirectory(pathIn, ".walletlock")) { | |||||
LogPrintf("Cannot obtain a lock on wallet directory %s. Another " | |||||
"instance of bitcoin may be using it.\n", | |||||
strPath); | |||||
return false; | |||||
} | |||||
fs::path pathLogDir = pathIn / "database"; | fs::path pathLogDir = pathIn / "database"; | ||||
TryCreateDirectories(pathLogDir); | TryCreateDirectories(pathLogDir); | ||||
fs::path pathErrorFile = pathIn / "db.log"; | fs::path pathErrorFile = pathIn / "db.log"; | ||||
LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), | LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), | ||||
pathErrorFile.string()); | pathErrorFile.string()); | ||||
unsigned int nEnvFlags = 0; | unsigned int nEnvFlags = 0; | ||||
if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) { | if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) { | ||||
Show All 14 Lines | bool CDBEnv::Open(const fs::path &pathIn, bool retry) { | ||||
dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1); | dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1); | ||||
int ret = | int ret = | ||||
dbenv->open(strPath.c_str(), | dbenv->open(strPath.c_str(), | ||||
DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | | DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | | ||||
DB_INIT_TXN | DB_THREAD | DB_RECOVER | nEnvFlags, | DB_INIT_TXN | DB_THREAD | DB_RECOVER | nEnvFlags, | ||||
S_IRUSR | S_IWUSR); | S_IRUSR | S_IWUSR); | ||||
if (ret != 0) { | if (ret != 0) { | ||||
dbenv->close(0); | dbenv->close(0); | ||||
return error( | LogPrintf("CDBEnv::Open: Error %d opening database environment: %s\n", | ||||
"CDBEnv::Open: Error %d opening database environment: %s\n", ret, | ret, DbEnv::strerror(ret)); | ||||
DbEnv::strerror(ret)); | if (retry) { | ||||
// try moving the database env out of the way | |||||
fs::path pathDatabaseBak = | |||||
pathIn / strprintf("database.%d.bak", GetTime()); | |||||
try { | |||||
fs::rename(pathLogDir, pathDatabaseBak); | |||||
LogPrintf("Moved old %s to %s. Retrying.\n", | |||||
pathLogDir.string(), pathDatabaseBak.string()); | |||||
} catch (const fs::filesystem_error &) { | |||||
// failure is ok (well, not really, but it's not worse than what | |||||
// we started with) | |||||
} | |||||
// try opening it again one more time | |||||
if (!Open(pathIn, false)) { | |||||
// if it still fails, it probably means we can't even create the | |||||
// database env | |||||
return false; | |||||
} | |||||
} else { | |||||
return false; | |||||
} | |||||
} | } | ||||
fDbEnvInit = true; | fDbEnvInit = true; | ||||
fMockDb = false; | fMockDb = false; | ||||
return true; | return true; | ||||
} | } | ||||
void CDBEnv::MakeMock() { | void CDBEnv::MakeMock() { | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | bool CDB::VerifyEnvironment(const std::string &walletFile, | ||||
// Wallet file must be a plain filename without a directory | // Wallet file must be a plain filename without a directory | ||||
if (walletFile != fs::basename(walletFile) + fs::extension(walletFile)) { | if (walletFile != fs::basename(walletFile) + fs::extension(walletFile)) { | ||||
errorStr = strprintf(_("Wallet %s resides outside wallet directory %s"), | errorStr = strprintf(_("Wallet %s resides outside wallet directory %s"), | ||||
walletFile, walletDir.string()); | walletFile, walletDir.string()); | ||||
return false; | return false; | ||||
} | } | ||||
if (!bitdb.Open(walletDir)) { | if (!bitdb.Open(walletDir, true)) { | ||||
// try moving the database env out of the way | |||||
fs::path pathDatabase = walletDir / "database"; | |||||
fs::path pathDatabaseBak = | |||||
walletDir / strprintf("database.%d.bak", GetTime()); | |||||
try { | |||||
fs::rename(pathDatabase, pathDatabaseBak); | |||||
LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), | |||||
pathDatabaseBak.string()); | |||||
} catch (const fs::filesystem_error &) { | |||||
// failure is ok (well, not really, but it's not worse than what we | |||||
// started with) | |||||
} | |||||
// try again | |||||
if (!bitdb.Open(walletDir)) { | |||||
// if it still fails, it probably means we can't even create the | |||||
// database env | |||||
errorStr = strprintf( | errorStr = strprintf( | ||||
_("Error initializing wallet database environment %s!"), | _("Error initializing wallet database environment %s!"), walletDir); | ||||
walletDir); | |||||
return false; | return false; | ||||
} | } | ||||
} | |||||
return true; | return true; | ||||
} | } | ||||
bool CDB::VerifyDatabaseFile(const std::string &walletFile, | bool CDB::VerifyDatabaseFile(const std::string &walletFile, | ||||
const fs::path &walletDir, std::string &warningStr, | const fs::path &walletDir, std::string &warningStr, | ||||
std::string &errorStr, | std::string &errorStr, | ||||
CDBEnv::recoverFunc_type recoverFunc) { | CDBEnv::recoverFunc_type recoverFunc) { | ||||
if (fs::exists(walletDir / walletFile)) { | if (fs::exists(walletDir / walletFile)) { | ||||
▲ Show 20 Lines • Show All 472 Lines • Show Last 20 Lines |