Example #1
0
DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok)
{
	DB_ENV *env = NULL;    
	int     err;
	u_int32_t	envFlags;

	err = db_env_create( &env, 0 );

	if ( err ) {
#ifdef LDAP_SYSLOG
		syslog( LOG_INFO, "ldbm_initialize_env(): "
			"FATAL error in db_env_create() : %s (%d)\n",
			db_strerror( err ), err );
#endif
		return NULL;
	}

#if DB_VERSION_X >= 0x030300
	/* This interface appeared in 3.3 */
	env->set_alloc( env, ldbm_malloc, NULL, NULL );
#endif

	env->set_errcall( env, ldbm_db_errcall );
	env->set_errpfx( env, "==>" );
	if (dbcachesize) {
		env->set_cachesize( env, 0, dbcachesize, 0 );
	}

	envFlags = DB_CREATE | DB_INIT_MPOOL | DB_USE_ENVIRON;
#ifdef DB_PRIVATE
	envFlags |= DB_PRIVATE;
#endif
#ifdef DB_MPOOL_PRIVATE
	envFlags |= DB_MPOOL_PRIVATE;
#endif
#ifdef HAVE_BERKELEY_DB_THREAD
	envFlags |= DB_THREAD;
#endif

#if DB_VERSION_X >= 0x030100
	err = env->open( env, home, envFlags, 0 );
#else
	/* 3.0.x requires an extra argument */
	err = env->open( env, home, NULL, envFlags, 0 );
#endif

	if ( err != 0 ) {
#ifdef LDAP_SYSLOG
		syslog(	LOG_INFO, "ldbm_initialize_env(): "
			"FATAL error in dbEnv->open() : %s (%d)\n",
			db_strerror( err ), err );
#endif
		env->close( env, 0 );
		return NULL;
	}

	*envdirok = 1;
	return env;
}
Example #2
0
File: db3.c Project: crossbuild/rpm
static int db_init(rpmdb rdb, const char * dbhome)
{
    DB_ENV *dbenv = NULL;
    int rc, xx;
    int retry_open = 2;
    int lockfd = -1;
    struct dbConfig_s * cfg = &rdb->cfg;
    /* This is our setup, thou shall not have other setups before us */
    uint32_t eflags = (DB_CREATE|DB_INIT_MPOOL|DB_INIT_CDB);

    if (rdb->db_dbenv != NULL) {
	rdb->db_opens++;
	return 0;
    } else {
	/* On first call, set backend description to something... */
	free(rdb->db_descr);
	rasprintf(&rdb->db_descr, "db%u", DB_VERSION_MAJOR);
    }

    /*
     * Both verify and rebuild are rather special, if for different reasons:
     * On rebuild we dont want to be affected by eg paniced environment, and
     * CDB only slows things down there. Verify is a quirky beast unlike
     * anything else in BDB, and does not like shared env or CDB.
     */
    if (rdb->db_flags & (RPMDB_FLAG_VERIFYONLY|RPMDB_FLAG_REBUILD)) {
	eflags |= DB_PRIVATE;
	eflags &= ~DB_INIT_CDB;
    }

    rc = db_env_create(&dbenv, 0);
    rc = dbapi_err(rdb, "db_env_create", rc, _debug);
    if (dbenv == NULL || rc)
	goto errxit;

    dbenv->set_alloc(dbenv, rmalloc, rrealloc, NULL);
    dbenv->set_errcall(dbenv, NULL);
    dbenv->set_errpfx(dbenv, _errpfx);
    dbenv->set_msgcall(dbenv, warnlog);

    /* 
     * These enable automatic stale lock removal. 
     * thread_count 8 is some kind of "magic minimum" value...
     */
    dbenv->set_thread_count(dbenv, 8);
    dbenv->set_isalive(dbenv, isalive);

    dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK,
	    (cfg->db_verbose & DB_VERB_DEADLOCK));
    dbenv->set_verbose(dbenv, DB_VERB_RECOVERY,
	    (cfg->db_verbose & DB_VERB_RECOVERY));
    dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR,
	    (cfg->db_verbose & DB_VERB_WAITSFOR));

    if (cfg->db_mmapsize) {
	xx = dbenv->set_mp_mmapsize(dbenv, cfg->db_mmapsize);
	xx = dbapi_err(rdb, "dbenv->set_mp_mmapsize", xx, _debug);
    }

    if (cfg->db_cachesize) {
	xx = dbenv->set_cachesize(dbenv, 0, cfg->db_cachesize, 0);
	xx = dbapi_err(rdb, "dbenv->set_cachesize", xx, _debug);
    }

    /*
     * Serialize shared environment open (and clock) via fcntl() lock.
     * Otherwise we can end up calling dbenv->failchk() while another
     * process is joining the environment, leading to transient
     * DB_RUNRECOVER errors. Also prevents races wrt removing the
     * environment (eg chrooted operation). Silently fall back to
     * private environment on failure to allow non-privileged queries
     * to "work", broken as it might be.
     */
    if (!(eflags & DB_PRIVATE)) {
	lockfd = serialize_env(dbhome);
	if (lockfd < 0) {
	    eflags |= DB_PRIVATE;
	    retry_open--;
	    rpmlog(RPMLOG_DEBUG, "serialize failed, using private dbenv\n");
	}
    }

    /*
     * Actually open the environment. Fall back to private environment
     * if we dont have permission to join/create shared environment or
     * system doesn't support it..
     */
    while (retry_open) {
	char *fstr = prDbiOpenFlags(eflags, 1);
	rpmlog(RPMLOG_DEBUG, "opening  db environment %s %s\n", dbhome, fstr);
	free(fstr);

	rc = (dbenv->open)(dbenv, dbhome, eflags, rdb->db_perms);
	if ((rc == EACCES || rc == EROFS) || (rc == EINVAL && errno == rc)) {
	    eflags |= DB_PRIVATE;
	    retry_open--;
	} else {
	    retry_open = 0;
	}
    }
    rc = dbapi_err(rdb, "dbenv->open", rc, _debug);
    if (rc)
	goto errxit;

    dbenv->set_errcall(dbenv, errlog);

    /* stale lock removal */
    rc = dbenv->failchk(dbenv, 0);
    rc = dbapi_err(rdb, "dbenv->failchk", rc, _debug);
    if (rc)
	goto errxit;

    rdb->db_dbenv = dbenv;
    rdb->db_opens = 1;

    if (lockfd >= 0)
	close(lockfd);
    return 0;

errxit:
    if (dbenv) {
	int xx;
	xx = dbenv->close(dbenv, 0);
	xx = dbapi_err(rdb, "dbenv->close", xx, _debug);
    }
    if (lockfd >= 0)
	close(lockfd);
    return rc;
}