diff options
| author | Gavin Andresen <[email protected]> | 2012-10-09 12:14:26 -0400 |
|---|---|---|
| committer | Gavin Andresen <[email protected]> | 2012-10-09 12:14:26 -0400 |
| commit | 673021410f48db3ad664d5c0dbf3a480ec0a0106 (patch) | |
| tree | f722eb6bed24919b9170b7862dea27911fd5e137 /src/db.cpp | |
| parent | Merge branch 'crash_at_exit' of github.com:gavinandresen/bitcoin-git (diff) | |
| parent | Don't try to verify a non-existent wallet.dat (diff) | |
| download | discoin-673021410f48db3ad664d5c0dbf3a480ec0a0106.tar.xz discoin-673021410f48db3ad664d5c0dbf3a480ec0a0106.zip | |
Merge branch 'wallet_exceptions' of github.com:gavinandresen/bitcoin-git
Diffstat (limited to 'src/db.cpp')
| -rw-r--r-- | src/db.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/db.cpp b/src/db.cpp index 7ca9e3495..9ad67892f 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -136,6 +136,69 @@ void CDBEnv::MakeMock() fMockDb = true; } +CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)) +{ + LOCK(cs_db); + assert(mapFileUseCount.count(strFile) == 0); + + Db db(&dbenv, 0); + int result = db.verify(strFile.c_str(), NULL, NULL, 0); + if (result == 0) + return VERIFY_OK; + else if (recoverFunc == NULL) + return RECOVER_FAIL; + + // Try to recover: + bool fRecovered = (*recoverFunc)(*this, strFile); + return (fRecovered ? RECOVER_OK : RECOVER_FAIL); +} + +bool CDBEnv::Salvage(std::string strFile, bool fAggressive, + std::vector<CDBEnv::KeyValPair >& vResult) +{ + LOCK(cs_db); + assert(mapFileUseCount.count(strFile) == 0); + + u_int32_t flags = DB_SALVAGE; + if (fAggressive) flags |= DB_AGGRESSIVE; + + stringstream strDump; + + Db db(&dbenv, 0); + int result = db.verify(strFile.c_str(), NULL, &strDump, flags); + if (result != 0) + { + printf("ERROR: db salvage failed\n"); + return false; + } + + // Format of bdb dump is ascii lines: + // header lines... + // HEADER=END + // hexadecimal key + // hexadecimal value + // ... repeated + // DATA=END + + string strLine; + while (!strDump.eof() && strLine != "HEADER=END") + getline(strDump, strLine); // Skip past header + + std::string keyHex, valueHex; + while (!strDump.eof() && keyHex != "DATA=END") + { + getline(strDump, keyHex); + if (keyHex != "DATA_END") + { + getline(strDump, valueHex); + vResult.push_back(make_pair(ParseHex(keyHex),ParseHex(valueHex))); + } + } + + return (result == 0); +} + + void CDBEnv::CheckpointLSN(std::string strFile) { dbenv.txn_checkpoint(0, 0, 0); @@ -257,6 +320,15 @@ void CDBEnv::CloseDb(const string& strFile) } } +bool CDBEnv::RemoveDb(const string& strFile) +{ + this->CloseDb(strFile); + + LOCK(cs_db); + int rc = dbenv.dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT); + return (rc == 0); +} + bool CDB::Rewrite(const string& strFile, const char* pszSkip) { while (!fShutdown) |