/* * Class: jmdb_DatabaseWrapper * Method: envGetMaxReaders * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jmdb_DatabaseWrapper_envGetMaxReaders(JNIEnv *vm, jclass clazz, jlong envL) { MDB_env *envC = (MDB_env*) envL; unsigned int max_readers; int code = mdb_env_get_maxreaders(envC, &max_readers); if (code) { throwDatabaseException(vm, code); } return max_readers; }
DBPriv *DBPrivOpenDB(const char *dbpath, dbid id) { DBPriv *db = xcalloc(1, sizeof(DBPriv)); MDB_txn *txn = NULL; int rc; rc = pthread_key_create(&db->txn_key, &DestroyTransaction); if (rc) { Log(LOG_LEVEL_ERR, "Could not create transaction key. (pthread_key_create: '%s')", GetErrorStrFromCode(rc)); free(db); return NULL; } rc = mdb_env_create(&db->env); if (rc) { Log(LOG_LEVEL_ERR, "Could not create handle for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } rc = mdb_env_set_mapsize(db->env, LMDB_MAXSIZE); if (rc) { Log(LOG_LEVEL_ERR, "Could not set mapsize for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } if (DB_MAX_READERS > 0) { rc = mdb_env_set_maxreaders(db->env, DB_MAX_READERS); if (rc) { Log(LOG_LEVEL_ERR, "Could not set maxreaders for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } } unsigned int open_flags = MDB_NOSUBDIR; if (id == dbid_locks || (GetAmPolicyHub() && id == dbid_lastseen)) { open_flags |= MDB_NOSYNC; } #ifdef __hpux /* * On HP-UX, a unified file cache was not introduced until version 11.31. * This means that on 11.23 there are separate file caches for mmap()'ed * files and open()'ed files. When these two are mixed, changes made using * one mode won't be immediately seen by the other mode, which is an * assumption LMDB is relying on. The MDB_WRITEMAP flag causes LMDB to use * mmap() only, so that we stay within one file cache. */ open_flags |= MDB_WRITEMAP; #endif rc = mdb_env_open(db->env, dbpath, open_flags, 0644); if (rc) { Log(LOG_LEVEL_ERR, "Could not open database %s: %s", dbpath, mdb_strerror(rc)); goto err; } if (DB_MAX_READERS > 0) { int max_readers; rc = mdb_env_get_maxreaders(db->env, &max_readers); if (rc) { Log(LOG_LEVEL_ERR, "Could not get maxreaders for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } if (max_readers < DB_MAX_READERS) { // LMDB will only reinitialize maxreaders if no database handles are // open, including in other processes, which is how we might end up // here. Log(LOG_LEVEL_VERBOSE, "Failed to set LMDB max reader limit on database '%s', " "consider restarting CFEngine", dbpath); } } rc = mdb_txn_begin(db->env, NULL, MDB_RDONLY, &txn); if (rc) { Log(LOG_LEVEL_ERR, "Could not open database txn %s: %s", dbpath, mdb_strerror(rc)); goto err; } rc = mdb_open(txn, NULL, 0, &db->dbi); if (rc) { Log(LOG_LEVEL_ERR, "Could not open database dbi %s: %s", dbpath, mdb_strerror(rc)); mdb_txn_abort(txn); goto err; } rc = mdb_txn_commit(txn); if (rc) { Log(LOG_LEVEL_ERR, "Could not commit database dbi %s: %s", dbpath, mdb_strerror(rc)); goto err; } return db; err: if (db->env) { mdb_env_close(db->env); } pthread_key_delete(db->txn_key); free(db); if (rc == MDB_INVALID) { return DB_PRIV_DATABASE_BROKEN; } return NULL; }