#include "db_config.h"
#include "db_int.h"
#include "dbinc/mp.h"
#include "dbinc/lock.h"
#include "dbinc/log.h"
#include "dbinc/txn.h"
static int __env_des_get __P((ENV *, REGINFO *, REGINFO *, REGION **));
static int __env_faultmem __P((ENV *, void *, size_t, int));
static int __env_sys_attach __P((ENV *, REGINFO *, REGION *));
static int __env_sys_detach __P((ENV *, REGINFO *, int));
static void __env_des_destroy __P((ENV *, REGION *));
static void __env_remove_file __P((ENV *));
int
__env_attach(env, init_flagsp, create_ok, retry_ok)
ENV *env;
u_int32_t *init_flagsp;
int create_ok, retry_ok;
{
DB_ENV *dbenv;
REGENV rbuf, *renv;
REGENV_REF ref;
REGINFO *infop;
REGION *rp, tregion;
size_t max, nrw, size;
long segid;
u_int32_t bytes, i, mbytes, nregions, signature;
u_int retry_cnt;
int majver, minver, patchver, ret;
char buf[sizeof(DB_REGION_FMT) + 20];
dbenv = env->dbenv;
retry_cnt = 0;
signature = __env_struct_sig();
loop: renv = NULL;
rp = NULL;
if ((ret = __os_calloc(env, 1, sizeof(REGINFO), &infop)) != 0)
return (ret);
infop->env = env;
infop->type = REGION_TYPE_ENV;
infop->id = REGION_ID_ENV;
infop->flags = REGION_JOIN_OK;
if (create_ok)
F_SET(infop, REGION_CREATE_OK);
if (F_ISSET(env, ENV_PRIVATE))
ret = __os_strdup(env, "process-private", &infop->name);
else {
(void)snprintf(buf, sizeof(buf), "%s", DB_REGION_ENV);
ret = __db_appname(env, DB_APP_NONE, buf, NULL, &infop->name);
}
if (ret != 0)
goto err;
if (F_ISSET(env, ENV_PRIVATE) || DB_GLOBAL(j_region_map) != NULL)
goto creation;
if (create_ok) {
if ((ret = __os_open(env, infop->name, 0,
DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_REGION,
env->db_mode, &env->lockfhp)) == 0)
goto creation;
if (ret != EEXIST) {
__db_err(env, ret, "%s", infop->name);
goto err;
}
}
F_CLR(infop, REGION_CREATE_OK);
if ((ret = __os_open(
env, infop->name, 0, DB_OSO_REGION, 0, &env->lockfhp)) != 0)
goto err;
if ((ret = __os_ioinfo(env, infop->name,
env->lockfhp, &mbytes, &bytes, NULL)) != 0) {
__db_err(env, ret, "%s", infop->name);
goto err;
}
size = mbytes * MEGABYTE + bytes;
if (size < sizeof(ref))
goto retry;
else {
if (size == sizeof(ref))
F_SET(env, ENV_SYSTEM_MEM);
else if (F_ISSET(env, ENV_SYSTEM_MEM)) {
ret = EINVAL;
__db_err(env, ret, DB_STR_A("1535",
"%s: existing environment not created in system memory",
"%s"), infop->name);
goto err;
} else {
if ((ret = __os_read(env, env->lockfhp, &rbuf,
sizeof(rbuf), &nrw)) != 0 ||
nrw < (size_t)sizeof(rbuf) ||
(ret = __os_seek(env,
env->lockfhp, 0, 0, rbuf.region_off)) != 0) {
__db_err(env, ret, DB_STR_A("1536",
"%s: unable to read region info", "%s"),
infop->name);
goto err;
}
}
if ((ret = __os_read(env, env->lockfhp, &ref,
sizeof(ref), &nrw)) != 0 || nrw < (size_t)sizeof(ref)) {
if (ret == 0)
ret = EIO;
__db_err(env, ret, DB_STR_A("1537",
"%s: unable to read system-memory information",
"%s"), infop->name);
goto err;
}
size = ref.size;
max = ref.max;
segid = ref.segid;
}
#ifndef HAVE_MUTEX_FCNTL
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
#endif
memset(&tregion, 0, sizeof(tregion));
tregion.size = (roff_t)size;
tregion.max = (roff_t)max;
tregion.segid = segid;
if ((ret = __env_sys_attach(env, infop, &tregion)) != 0)
goto err;
user_map_functions:
infop->primary = infop->addr;
infop->head = (u_int8_t *)infop->addr + sizeof(REGENV);
renv = infop->primary;
if (renv->majver != DB_VERSION_MAJOR ||
renv->minver != DB_VERSION_MINOR) {
if (renv->majver != 0 || renv->minver != 0) {
__db_errx(env, DB_STR_A("1538",
"Program version %d.%d doesn't match environment version %d.%d",
"%d %d %d %d"), DB_VERSION_MAJOR, DB_VERSION_MINOR,
renv->majver, renv->minver);
ret = DB_VERSION_MISMATCH;
} else
ret = EINVAL;
goto err;
}
if (renv->signature != signature) {
__db_errx(env, DB_STR("1539",
"Build signature doesn't match environment"));
ret = DB_VERSION_MISMATCH;
goto err;
}
if (renv->panic && !F_ISSET(dbenv, DB_ENV_NOPANIC)) {
ret = __env_panic_msg(env);
goto err;
}
if (renv->magic != DB_REGION_MAGIC)
goto retry;
if ((ret = __env_des_get(env, infop, infop, &rp)) != 0 || rp == NULL)
goto find_err;
infop->rp = rp;
if (DB_GLOBAL(j_region_map) == NULL && rp->size != size)
goto retry;
if (init_flagsp != NULL) {
FLD_CLR(*init_flagsp, renv->init_flags);
if (*init_flagsp != 0) {
__db_errx(env, DB_STR("1540",
"configured environment flags incompatible with existing environment"));
ret = EINVAL;
goto err;
}
*init_flagsp = renv->init_flags;
}
(void)__env_faultmem(env, infop->primary, rp->size, 0);
env->reginfo = infop;
return (0);
creation:
F_SET(infop, REGION_CREATE);
memset(&tregion, 0, sizeof(tregion));
nregions = __memp_max_regions(env) + 5;
size = nregions * sizeof(REGION);
size += dbenv->passwd_len;
size += (dbenv->thr_max + dbenv->thr_max / 4) *
__env_alloc_size(sizeof(DB_THREAD_INFO));
if (init_flagsp != NULL && FLD_ISSET(*init_flagsp, DB_INITENV_REP))
size += MEGABYTE;
size += __txn_region_size(env);
size += __log_region_size(env);
size += __env_thread_size(env, size);
size += __lock_region_size(env, size);
tregion.size = (roff_t)size;
tregion.segid = INVALID_REGION_SEGID;
if ((tregion.max = dbenv->memory_max) == 0) {
size += 16 * 1024;
tregion.max = (roff_t)size;
tregion.max += (roff_t)__lock_region_max(env);
tregion.max += (roff_t)__txn_region_max(env);
tregion.max += (roff_t)__log_region_max(env);
tregion.max += (roff_t)__env_thread_max(env);
} else if (tregion.size > tregion.max) {
__db_errx(env, DB_STR_A("1542",
"Minimum environment memory size %ld is bigger than spcified max %ld.",
"%ld %ld"), (u_long)tregion.size, (u_long)tregion.max);
ret = EINVAL;
goto err;
} else if (F_ISSET(env, ENV_PRIVATE))
infop->max_alloc = dbenv->memory_max;
if ((ret = __env_sys_attach(env, infop, &tregion)) != 0)
goto err;
if (!F_ISSET(infop, REGION_CREATE))
goto user_map_functions;
(void)__env_faultmem(env, infop->addr, tregion.size, 1);
infop->primary = infop->addr;
infop->head = (u_int8_t *)infop->addr + sizeof(REGENV);
__env_alloc_init(infop, tregion.size - sizeof(REGENV));
renv = infop->primary;
renv->magic = 0;
renv->panic = 0;
(void)db_version(&majver, &minver, &patchver);
renv->majver = (u_int32_t)majver;
renv->minver = (u_int32_t)minver;
renv->patchver = (u_int32_t)patchver;
renv->signature = signature;
(void)time(&renv->timestamp);
__os_unique_id(env, &renv->envid);
renv->init_flags = (init_flagsp == NULL) ? 0 : *init_flagsp;
renv->region_cnt = nregions;
if ((ret = __env_alloc(infop, nregions * sizeof(REGION), &rp)) != 0) {
__db_err(env, ret, DB_STR("1543",
"unable to create new master region array"));
goto err;
}
renv->region_off = R_OFFSET(infop, rp);
for (i = 0; i < nregions; ++i, ++rp)
rp->id = INVALID_REGION_ID;
renv->cipher_off = renv->thread_off = renv->rep_off = INVALID_ROFF;
renv->flags = 0;
renv->op_timestamp = renv->rep_timestamp = 0;
renv->mtx_regenv = MUTEX_INVALID;
renv->reg_panic = 0;
if ((ret = __env_des_get(env, infop, infop, &rp)) != 0) {
find_err: __db_errx(env, DB_STR_A("1544",
"%s: unable to find environment", "%s"), infop->name);
if (ret == 0)
ret = EINVAL;
goto err;
}
infop->rp = rp;
rp->alloc = rp->size = tregion.size;
rp->max = tregion.max;
rp->segid = tregion.segid;
if (tregion.segid != INVALID_REGION_SEGID) {
ref.size = tregion.size;
ref.segid = tregion.segid;
ref.max = tregion.max;
if ((ret = __os_write(
env, env->lockfhp, &ref, sizeof(ref), &nrw)) != 0) {
__db_err(env, ret, DB_STR_A("1545",
"%s: unable to write out public environment ID",
"%s"), infop->name);
goto err;
}
}
#ifndef HAVE_MUTEX_FCNTL
if (env->lockfhp != NULL) {
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
}
#endif
env->reginfo = infop;
return (0);
err:
retry:
if (env->lockfhp != NULL) {
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
}
if (infop->addr != NULL) {
if (infop->rp == NULL)
infop->rp = &tregion;
(void)__env_sys_detach(env,
infop, F_ISSET(infop, REGION_CREATE));
if (rp != NULL && F_ISSET(env, DB_PRIVATE))
__env_alloc_free(infop, rp);
}
if (infop->name != NULL)
__os_free(env, infop->name);
__os_free(env, infop);
if (ret == 0) {
if (!retry_ok || ++retry_cnt > 3) {
__db_errx(env, DB_STR("1546",
"unable to join the environment"));
ret = EAGAIN;
} else {
__os_yield(env, retry_cnt * 3, 0);
goto loop;
}
}
return (ret);
}
int
__env_turn_on(env)
ENV *env;
{
REGENV *renv;
REGINFO *infop;
infop = env->reginfo;
renv = infop->primary;
if (!F_ISSET(infop, REGION_CREATE))
return (0);
renv->magic = DB_REGION_MAGIC;
return (0);
}
int
__env_turn_off(env, flags)
ENV *env;
u_int32_t flags;
{
REGENV *renv;
REGINFO *infop;
int ret, t_ret;
ret = 0;
if (__env_attach(env, NULL, 0, 1) != 0)
return (0);
infop = env->reginfo;
renv = infop->primary;
MUTEX_LOCK(env, renv->mtx_regenv);
if (renv->refcnt > 0 && !LF_ISSET(DB_FORCE) && !renv->panic)
ret = EBUSY;
else
renv->panic = 1;
MUTEX_UNLOCK(env, renv->mtx_regenv);
if ((t_ret = __env_detach(env, 0)) != 0 && ret == 0)
ret = t_ret;
return (ret);
}
void
__env_panic_set(env, on)
ENV *env;
int on;
{
if (env != NULL && env->reginfo != NULL)
((REGENV *)env->reginfo->primary)->panic = on ? 1 : 0;
}
int
__env_ref_increment(env)
ENV *env;
{
REGENV *renv;
REGINFO *infop;
int ret;
infop = env->reginfo;
renv = infop->primary;
if (F_ISSET(infop, REGION_CREATE)) {
if ((ret = __mutex_alloc(
env, MTX_ENV_REGION, 0, &renv->mtx_regenv)) != 0)
return (ret);
renv->refcnt = 1;
} else {
MUTEX_LOCK(env, renv->mtx_regenv);
++renv->refcnt;
MUTEX_UNLOCK(env, renv->mtx_regenv);
}
F_SET(env, ENV_REF_COUNTED);
return (0);
}
int
__env_ref_decrement(env)
ENV *env;
{
REGENV *renv;
REGINFO *infop;
if ((infop = env->reginfo) == NULL)
return (0);
renv = infop->primary;
if (F_ISSET(env, ENV_REF_COUNTED)) {
MUTEX_LOCK(env, renv->mtx_regenv);
if (renv->refcnt == 0)
__db_errx(env, DB_STR("1547",
"environment reference count went negative"));
else
--renv->refcnt;
MUTEX_UNLOCK(env, renv->mtx_regenv);
F_CLR(env, ENV_REF_COUNTED);
}
return (F_ISSET(env, ENV_PRIVATE) ?
__mutex_free(env, &renv->mtx_regenv) : 0);
}
int
__env_ref_get(dbenv, countp)
DB_ENV *dbenv;
u_int32_t *countp;
{
ENV *env;
REGENV *renv;
REGINFO *infop;
env = dbenv->env;
infop = env->reginfo;
renv = infop->primary;
*countp = renv->refcnt;
return (0);
}
int
__env_detach(env, destroy)
ENV *env;
int destroy;
{
REGENV *renv;
REGINFO *infop;
REGION rp;
int ret, t_ret;
infop = env->reginfo;
renv = infop->primary;
ret = 0;
if (env->lockfhp != NULL) {
if ((t_ret =
__os_closehandle(env, env->lockfhp)) != 0 && ret == 0)
ret = t_ret;
env->lockfhp = NULL;
}
if (destroy) {
rp = *infop->rp;
infop->rp = &rp;
if (renv->region_off != INVALID_ROFF)
__env_alloc_free(
infop, R_ADDR(infop, renv->region_off));
}
env->reginfo = NULL;
env->thr_hashtab = NULL;
if ((t_ret = __env_sys_detach(env, infop, destroy)) != 0 && ret == 0)
ret = t_ret;
if (infop->name != NULL)
__os_free(env, infop->name);
__os_free(env, infop);
return (ret);
}
int
__env_remove_env(env)
ENV *env;
{
DB_ENV *dbenv;
REGENV *renv;
REGINFO *infop, reginfo;
REGION *rp;
u_int32_t flags_orig, i;
dbenv = env->dbenv;
flags_orig = F_ISSET(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC);
F_SET(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC);
if (__env_attach(env, NULL, 0, 0) != 0)
goto remfiles;
infop = env->reginfo;
renv = infop->primary;
renv->panic = 1;
for (rp = R_ADDR(infop, renv->region_off),
i = 0; i < renv->region_cnt; ++i, ++rp) {
if (rp->id == INVALID_REGION_ID || rp->type == REGION_TYPE_ENV)
continue;
memset(®info, 0, sizeof(reginfo));
reginfo.id = rp->id;
reginfo.flags = REGION_CREATE_OK;
if (__env_region_attach(env, ®info, 0, 0) != 0)
continue;
#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
if (reginfo.type == REGION_TYPE_MUTEX)
__mutex_resource_return(env, ®info);
#endif
(void)__env_region_detach(env, ®info, 1);
}
(void)__env_detach(env, 1);
remfiles:
__env_remove_file(env);
F_CLR(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC);
F_SET(dbenv, flags_orig);
return (0);
}
static void
__env_remove_file(env)
ENV *env;
{
int cnt, fcnt, lastrm, ret;
const char *dir;
char saved_char, *p, **names, *path, buf[sizeof(DB_REGION_FMT) + 20];
(void)snprintf(buf, sizeof(buf), "%s", DB_REGION_ENV);
if ((ret = __db_appname(env,
DB_APP_NONE, buf, NULL, &path)) != 0)
return;
if ((p = __db_rpath(path)) == NULL) {
p = path;
saved_char = *p;
dir = PATH_DOT;
} else {
saved_char = *p;
*p = '\0';
dir = path;
}
if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0)
__db_err(env, ret, "%s", dir);
*p = saved_char;
__os_free(env, path);
if (ret != 0)
return;
for (lastrm = -1, cnt = fcnt; --cnt >= 0;) {
if (!IS_DB_FILE(names[cnt]))
continue;
if (strncmp(names[cnt], "__dbq.", 6) == 0)
continue;
if (strncmp(names[cnt], "__dbp.", 6) == 0)
continue;
if (strncmp(names[cnt], "__db.register", 13) == 0)
continue;
if (strncmp(names[cnt], "__db.rep", 8) == 0)
continue;
if (strcmp(names[cnt], DB_REGION_ENV) == 0) {
lastrm = cnt;
continue;
}
if (__db_appname(env,
DB_APP_NONE, names[cnt], NULL, &path) == 0) {
(void)__os_unlink(env, path, 1);
__os_free(env, path);
}
}
if (lastrm != -1)
if (__db_appname(env,
DB_APP_NONE, names[lastrm], NULL, &path) == 0) {
(void)__os_unlink(env, path, 1);
__os_free(env, path);
}
__os_dirfree(env, names, fcnt);
}
int
__env_region_attach(env, infop, init, max)
ENV *env;
REGINFO *infop;
size_t init, max;
{
REGION *rp;
int ret;
char buf[sizeof(DB_REGION_FMT) + 20];
F_CLR(infop, REGION_CREATE);
if ((ret = __env_des_get(env, env->reginfo, infop, &rp)) != 0)
return (ret);
infop->env = env;
infop->rp = rp;
infop->type = rp->type;
infop->id = rp->id;
if (F_ISSET(infop, REGION_CREATE)) {
rp->alloc = rp->size = (roff_t)init;
rp->max = (roff_t)max;
}
(void)snprintf(buf, sizeof(buf), DB_REGION_FMT, infop->id);
if ((ret = __db_appname(env,
DB_APP_NONE, buf, NULL, &infop->name)) != 0)
goto err;
if ((ret = __env_sys_attach(env, infop, rp)) != 0)
goto err;
(void)__env_faultmem(env,
infop->addr, rp->size, F_ISSET(infop, REGION_CREATE));
if (F_ISSET(infop, REGION_CREATE))
__env_alloc_init(infop, rp->size);
return (0);
err:
if (infop->addr != NULL)
(void)__env_sys_detach(env,
infop, F_ISSET(infop, REGION_CREATE));
else if (infop->name != NULL) {
__os_free(env, infop->name);
infop->name = NULL;
}
infop->rp = NULL;
infop->id = INVALID_REGION_ID;
if (F_ISSET(infop, REGION_CREATE)) {
__env_des_destroy(env, rp);
F_CLR(infop, REGION_CREATE);
}
return (ret);
}
int
__env_region_share(env, infop)
ENV *env;
REGINFO *infop;
{
REGINFO *envinfo;
REGION *rp;
envinfo = env->reginfo;
rp = envinfo->rp;
F_SET(infop, F_ISSET(envinfo, REGION_CREATE) | REGION_SHARED);
infop->addr = envinfo->addr;
infop->head = envinfo->head;
infop->env = env;
infop->rp = rp;
infop->name = envinfo->name;
infop->fhp = envinfo->fhp;
infop->type = rp->type;
infop->id = rp->id;
return (0);
}
int
__env_region_detach(env, infop, destroy)
ENV *env;
REGINFO *infop;
int destroy;
{
REGION *rp;
REGION_MEM *mem, *next;
int ret;
if (F_ISSET(env, ENV_PRIVATE))
destroy = 1;
else if (F_ISSET(infop, REGION_SHARED))
return (0);
rp = infop->rp;
if (F_ISSET(env, ENV_PRIVATE) && infop->primary != NULL) {
for (mem = infop->mem; mem != NULL; mem = next) {
next = mem->next;
__env_alloc_free(infop, mem);
}
__env_alloc_free(infop, infop->primary);
}
if (F_ISSET(infop, REGION_SHARED))
return (0);
ret = __env_sys_detach(env, infop, destroy);
if (destroy)
__env_des_destroy(env, rp);
if (infop->name != NULL)
__os_free(env, infop->name);
return (ret);
}
static int
__env_sys_attach(env, infop, rp)
ENV *env;
REGINFO *infop;
REGION *rp;
{
int ret;
#define OS_VMPAGESIZE (8 * 1024)
#define OS_VMROUNDOFF(i) { \
if ((i) + OS_VMPAGESIZE - 1 > (i)) \
(i) += OS_VMPAGESIZE - 1; \
(i) -= (i) % OS_VMPAGESIZE; \
}
if (F_ISSET(infop, REGION_CREATE)) {
OS_VMROUNDOFF(rp->size);
OS_VMROUNDOFF(rp->max);
}
#ifdef DB_REGIONSIZE_MAX
if (rp->size > DB_REGIONSIZE_MAX) {
__db_errx(env, DB_STR_A("1548",
"region size %lu is too large; maximum is %lu", "%lu %lu"),
(u_long)rp->size, (u_long)DB_REGIONSIZE_MAX);
return (EINVAL);
}
if (rp->max > DB_REGIONSIZE_MAX) {
__db_errx(env, DB_STR_A("1549",
"region max %lu is too large; maximum is %lu", "%lu %lu"),
(u_long)rp->max, (u_long)DB_REGIONSIZE_MAX);
return (EINVAL);
}
#endif
if (F_ISSET(env, ENV_PRIVATE)) {
#if defined(HAVE_MUTEX_HPPA_MSEM_INIT)
if (F_ISSET(env, ENV_THREAD)) {
__db_errx(env, DB_STR("1550",
"architecture does not support locks inside process-local (malloc) memory"));
__db_errx(env, DB_STR("1551",
"application may not specify both DB_PRIVATE and DB_THREAD"));
return (EINVAL);
}
#endif
if ((ret = __os_malloc(
env, sizeof(REGENV), &infop->addr)) != 0)
return (ret);
} else {
#if !defined(HAVE_MMAP_EXTEND)
rp->size = rp->max;
#endif
if ((ret = __os_attach(env, infop, rp)) != 0)
return (ret);
}
infop->head = infop->addr;
if (infop->addr != ALIGNP_INC(infop->addr, sizeof(uintmax_t))) {
__db_errx(env, DB_STR("1552",
"region memory was not correctly aligned"));
(void)__env_sys_detach(env, infop,
F_ISSET(infop, REGION_CREATE));
return (EINVAL);
}
return (0);
}
static int
__env_sys_detach(env, infop, destroy)
ENV *env;
REGINFO *infop;
int destroy;
{
if (F_ISSET(env, ENV_PRIVATE)) {
__os_free(env, infop->addr);
return (0);
}
return (__os_detach(env, infop, destroy));
}
static int
__env_des_get(env, env_infop, infop, rpp)
ENV *env;
REGINFO *env_infop, *infop;
REGION **rpp;
{
REGENV *renv;
REGION *rp, *empty_slot, *first_type;
u_int32_t i, maxid;
*rpp = NULL;
renv = env_infop->primary;
maxid = REGION_ID_ENV;
empty_slot = first_type = NULL;
for (rp = R_ADDR(env_infop, renv->region_off),
i = 0; i < renv->region_cnt; ++i, ++rp) {
if (rp->id == INVALID_REGION_ID) {
if (empty_slot == NULL)
empty_slot = rp;
continue;
}
if (infop->id != INVALID_REGION_ID) {
if (infop->id == rp->id)
break;
continue;
}
if (infop->type == rp->type &&
F_ISSET(infop, REGION_JOIN_OK) &&
(first_type == NULL || first_type->id > rp->id))
first_type = rp;
if (rp->id > maxid)
maxid = rp->id;
}
if (i >= renv->region_cnt)
rp = first_type;
if (rp != NULL) {
*rpp = rp;
return (0);
}
if (!F_ISSET(infop, REGION_CREATE_OK))
return (ENOENT);
if (empty_slot == NULL) {
__db_errx(env, DB_STR("1553",
"no room remaining for additional REGIONs"));
return (ENOENT);
}
memset(empty_slot, 0, sizeof(REGION));
empty_slot->segid = INVALID_REGION_SEGID;
empty_slot->type = infop->type;
empty_slot->id = infop->id == INVALID_REGION_ID ? maxid + 1 : infop->id;
F_SET(infop, REGION_CREATE);
*rpp = empty_slot;
return (0);
}
static void
__env_des_destroy(env, rp)
ENV *env;
REGION *rp;
{
COMPQUIET(env, NULL);
rp->id = INVALID_REGION_ID;
}
static int
__env_faultmem(env, addr, size, created)
ENV *env;
void *addr;
size_t size;
int created;
{
int ret;
u_int8_t *p, *t;
if (F_ISSET(env, ENV_PRIVATE))
return (0);
ret = 0;
if (F_ISSET(env->dbenv, DB_ENV_REGION_INIT)) {
if (created)
for (p = addr,
t = (u_int8_t *)addr + size; p < t; p += 512)
p[0] = 0xdb;
else
for (p = addr,
t = (u_int8_t *)addr + size; p < t; p += 512)
ret |= p[0];
}
return (ret);
}