Merge pull request #7774
ade464a
ITS#9385 fix using MDB_NOSUBDIR with nonexistent file (Kris Zyp)033a32a
Remove check is_directory check on lmdb path (Howard Chu)b096e16
Revert 'db_lmdb: test for mmap support at init time' (Howard Chu)493577a
Silence spurious fallthru warning (Howard Chu)b46a60e
Fix rawpart flag collision (Howard Chu)4e7586c
More RAWPART support (Howard Chu)747f5d3
Preliminary raw partition support (Howard Chu)
This commit is contained in:
commit
30a9183091
58
external/db_drivers/liblmdb/mdb.c
vendored
58
external/db_drivers/liblmdb/mdb.c
vendored
@ -1467,6 +1467,8 @@ struct MDB_env {
|
||||
#endif
|
||||
/** Failed to update the meta page. Probably an I/O error. */
|
||||
#define MDB_FATAL_ERROR 0x80000000U
|
||||
/** using a raw block device */
|
||||
#define MDB_RAWPART 0x40000000U
|
||||
/** Some fields are initialized. */
|
||||
#define MDB_ENV_ACTIVE 0x20000000U
|
||||
/** me_txkey is set */
|
||||
@ -4038,6 +4040,8 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ESECT mdb_env_map(MDB_env *env, void *addr);
|
||||
|
||||
/** Read the environment parameters of a DB environment before
|
||||
* mapping it into memory.
|
||||
* @param[in] env the environment handle
|
||||
@ -4054,6 +4058,31 @@ mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta)
|
||||
int i, rc, off;
|
||||
enum { Size = sizeof(pbuf) };
|
||||
|
||||
if (env->me_flags & MDB_RAWPART) {
|
||||
#define VM_ALIGN 0x200000
|
||||
env->me_mapsize += VM_ALIGN-1;
|
||||
env->me_mapsize &= ~(VM_ALIGN-1);
|
||||
env->me_psize = env->me_os_psize;
|
||||
rc = mdb_env_map(env, NULL);
|
||||
if (rc) {
|
||||
DPRINTF(("mdb_env_map: %s", mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
p = (MDB_page *)env->me_map;
|
||||
for (i=0; i<NUM_METAS; i++) {
|
||||
if (!F_ISSET(p->mp_flags, P_META))
|
||||
return ENOENT;
|
||||
if (env->me_metas[i]->mm_magic != MDB_MAGIC)
|
||||
return MDB_INVALID;
|
||||
if (env->me_metas[i]->mm_version != MDB_DATA_VERSION)
|
||||
return MDB_VERSION_MISMATCH;
|
||||
if (i == 0 || env->me_metas[i]->mm_txnid > meta->mm_txnid)
|
||||
*meta = *env->me_metas[i];
|
||||
p = (MDB_page *)((char *)p + env->me_psize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We don't know the page size yet, so use a minimum value.
|
||||
* Read both meta pages so we can use the latest one.
|
||||
*/
|
||||
@ -4081,6 +4110,8 @@ mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta)
|
||||
p = (MDB_page *)&pbuf;
|
||||
|
||||
if (!F_ISSET(p->mp_flags, P_META)) {
|
||||
if (env->me_flags & MDB_RAWPART)
|
||||
return ENOENT;
|
||||
DPRINTF(("page %"Yu" not a meta page", p->mp_pgno));
|
||||
return MDB_INVALID;
|
||||
}
|
||||
@ -4148,6 +4179,18 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
|
||||
|
||||
psize = env->me_psize;
|
||||
|
||||
if ((env->me_flags & (MDB_RAWPART|MDB_WRITEMAP)) == (MDB_RAWPART|MDB_WRITEMAP)) {
|
||||
p = (MDB_page *)env->me_map;
|
||||
p->mp_pgno = 0;
|
||||
p->mp_flags = P_META;
|
||||
*(MDB_meta *)METADATA(p) = *meta;
|
||||
q = (MDB_page *)((char *)p + psize);
|
||||
q->mp_pgno = 1;
|
||||
q->mp_flags = P_META;
|
||||
*(MDB_meta *)METADATA(q) = *meta;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = calloc(NUM_METAS, psize);
|
||||
if (!p)
|
||||
return ENOMEM;
|
||||
@ -4410,7 +4453,7 @@ mdb_env_map(MDB_env *env, void *addr)
|
||||
int prot = PROT_READ;
|
||||
if (flags & MDB_WRITEMAP) {
|
||||
prot |= PROT_WRITE;
|
||||
if (ftruncate(env->me_fd, env->me_mapsize) < 0)
|
||||
if (!(flags & MDB_RAWPART) && ftruncate(env->me_fd, env->me_mapsize) < 0)
|
||||
return ErrCode();
|
||||
}
|
||||
env->me_map = mmap(addr, env->me_mapsize, prot, MAP_SHARED,
|
||||
@ -5448,6 +5491,17 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
|
||||
if (rc)
|
||||
goto leave;
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
{
|
||||
struct stat st;
|
||||
flags &= ~MDB_RAWPART;
|
||||
if (!stat(path, &st) && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))) {
|
||||
flags |= MDB_RAWPART | MDB_NOSUBDIR;
|
||||
if (!env->me_mapsize)
|
||||
env->me_mapsize = DEFAULT_MAPSIZE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
flags |= MDB_ENV_ACTIVE; /* tell mdb_env_close0() to clean up */
|
||||
|
||||
@ -7668,7 +7722,7 @@ more:
|
||||
offset *= 4; /* space for 4 more */
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU: Big enough MDB_DUPFIXED sub-page */
|
||||
/* FALLTHRU *//* Big enough MDB_DUPFIXED sub-page */
|
||||
case MDB_CURRENT:
|
||||
fp->mp_flags |= P_DIRTY;
|
||||
COPY_PGNO(fp->mp_pgno, mp->mp_pgno);
|
||||
|
@ -25,13 +25,6 @@
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "db_lmdb.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
@ -1303,26 +1296,6 @@ BlockchainLMDB::BlockchainLMDB(bool batch_transactions): BlockchainDB()
|
||||
m_hardfork = nullptr;
|
||||
}
|
||||
|
||||
void BlockchainLMDB::check_mmap_support()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
const boost::filesystem::path mmap_test_file = m_folder / boost::filesystem::unique_path();
|
||||
int mmap_test_fd = ::open(mmap_test_file.string().c_str(), O_RDWR | O_CREAT, 0600);
|
||||
if (mmap_test_fd < 0)
|
||||
throw0(DB_ERROR((std::string("Failed to check for mmap support: open failed: ") + strerror(errno)).c_str()));
|
||||
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([mmap_test_fd, &mmap_test_file]() {
|
||||
::close(mmap_test_fd);
|
||||
boost::filesystem::remove(mmap_test_file.string());
|
||||
});
|
||||
if (write(mmap_test_fd, "mmaptest", 8) != 8)
|
||||
throw0(DB_ERROR((std::string("Failed to check for mmap support: write failed: ") + strerror(errno)).c_str()));
|
||||
void *mmap_res = mmap(NULL, 8, PROT_READ, MAP_SHARED, mmap_test_fd, 0);
|
||||
if (mmap_res == MAP_FAILED)
|
||||
throw0(DB_ERROR("This filesystem does not support mmap: use --data-dir to place the blockchain on a filesystem which does"));
|
||||
munmap(mmap_res, 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
||||
{
|
||||
int result;
|
||||
@ -1334,14 +1307,8 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
||||
throw0(DB_OPEN_FAILURE("Attempted to open db, but it's already open"));
|
||||
|
||||
boost::filesystem::path direc(filename);
|
||||
if (boost::filesystem::exists(direc))
|
||||
{
|
||||
if (!boost::filesystem::is_directory(direc))
|
||||
throw0(DB_OPEN_FAILURE("LMDB needs a directory path, but a file was passed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!boost::filesystem::create_directories(direc))
|
||||
if (!boost::filesystem::exists(direc) &&
|
||||
!boost::filesystem::create_directories(direc)) {
|
||||
throw0(DB_OPEN_FAILURE(std::string("Failed to create directory ").append(filename).c_str()));
|
||||
}
|
||||
|
||||
@ -1364,9 +1331,6 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
|
||||
|
||||
m_folder = filename;
|
||||
|
||||
try { check_mmap_support(); }
|
||||
catch(...) { MERROR("Failed to check for mmap support, proceeding"); }
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
if ((mdb_flags & MDB_WRITEMAP) == 0) {
|
||||
MCLOG_RED(el::Level::Info, "global", "Running on OpenBSD: forcing WRITEMAP");
|
||||
|
@ -359,7 +359,6 @@ public:
|
||||
static int compare_string(const MDB_val *a, const MDB_val *b);
|
||||
|
||||
private:
|
||||
void check_mmap_support();
|
||||
void do_resize(uint64_t size_increase=0);
|
||||
|
||||
bool need_resize(uint64_t threshold_size=0) const;
|
||||
|
Loading…
Reference in New Issue
Block a user