| 70 | } |
| 71 | |
| 72 | bool CDBEnv::Open(const boost::filesystem::path& pathIn, bool retry) |
| 73 | { |
| 74 | if (fDbEnvInit) |
| 75 | return true; |
| 76 | |
| 77 | boost::this_thread::interruption_point(); |
| 78 | |
| 79 | strPath = pathIn.string(); |
| 80 | boost::filesystem::path pathLogDir = pathIn / "database"; |
| 81 | TryCreateDirectory(pathLogDir); |
| 82 | boost::filesystem::path pathErrorFile = pathIn / "db.log"; |
| 83 | LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); |
| 84 | |
| 85 | unsigned int nEnvFlags = 0; |
| 86 | if (GetBoolArg("-privdb", true)) |
| 87 | nEnvFlags |= DB_PRIVATE; |
| 88 | |
| 89 | dbenv->set_lg_dir(pathLogDir.string().c_str()); |
| 90 | dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet |
| 91 | dbenv->set_lg_bsize(0x10000); |
| 92 | dbenv->set_lg_max(1048576); |
| 93 | dbenv->set_lk_max_locks(40000); |
| 94 | dbenv->set_lk_max_objects(40000); |
| 95 | dbenv->set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug |
| 96 | dbenv->set_flags(DB_AUTO_COMMIT, 1); |
| 97 | dbenv->set_flags(DB_TXN_WRITE_NOSYNC, 1); |
| 98 | dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1); |
| 99 | int ret = dbenv->open(strPath.c_str(), |
| 100 | DB_CREATE | |
| 101 | DB_INIT_LOCK | |
| 102 | DB_INIT_LOG | |
| 103 | DB_INIT_MPOOL | |
| 104 | DB_INIT_TXN | |
| 105 | DB_THREAD | |
| 106 | DB_RECOVER | |
| 107 | nEnvFlags, |
| 108 | S_IRUSR | S_IWUSR); |
| 109 | if (ret != 0) |
| 110 | { |
| 111 | LogPrintf("CDBEnv::Open : Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); |
| 112 | |
| 113 | // According to Berkeley DB specification, we must call dbenv.close() method on failure |
| 114 | dbenv->close(0); |
| 115 | if (retry) |
| 116 | { |
| 117 | // try moving the database env out of the way |
| 118 | boost::filesystem::path pathDatabaseBak = pathIn / strprintf("database.%d.bak", GetTime()); |
| 119 | try |
| 120 | { |
| 121 | boost::filesystem::rename(pathLogDir, pathDatabaseBak); |
| 122 | LogPrintf("Moved old %s to %s. Retrying.\n", pathLogDir.string(), pathDatabaseBak.string()); |
| 123 | } |
| 124 | catch (const boost::filesystem::filesystem_error&) |
| 125 | { |
| 126 | // failure is ok (well, not really, but it's not worse than what we started with) |
| 127 | } |
| 128 | // try opening it again one more time |
| 129 | if (!Open(pathIn, false)) |
no test coverage detected