log_method.c 6.84 KB
Newer Older
1 2 3
/*-
 * See the file LICENSE for redistribution information.
 *
jimw@mysql.com's avatar
jimw@mysql.com committed
4
 * Copyright (c) 1999-2005
5
 *	Sleepycat Software.  All rights reserved.
jimw@mysql.com's avatar
jimw@mysql.com committed
6
 *
jimw@mysql.com's avatar
jimw@mysql.com committed
7
 * $Id: log_method.c,v 12.4 2005/07/21 18:21:25 bostic Exp $
8 9
 */

jimw@mysql.com's avatar
jimw@mysql.com committed
10
#include "db_config.h"
11 12 13 14 15 16

#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>

#include <stdlib.h>
#include <string.h>
jimw@mysql.com's avatar
jimw@mysql.com committed
17 18
#endif

19
#include "db_int.h"
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
20
#include "dbinc/log.h"
21 22 23 24 25 26 27 28 29 30 31

/*
 * __log_dbenv_create --
 *	Log specific initialization of the DB_ENV structure.
 *
 * PUBLIC: void __log_dbenv_create __P((DB_ENV *));
 */
void
__log_dbenv_create(dbenv)
	DB_ENV *dbenv;
{
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
32 33 34 35 36 37
	/*
	 * !!!
	 * Our caller has not yet had the opportunity to reset the panic
	 * state or turn off mutex locking, and so we can neither check
	 * the panic state or acquire a mutex in the DB_ENV create path.
	 */
jimw@mysql.com's avatar
jimw@mysql.com committed
38
	dbenv->lg_bsize = 0;
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
39
	dbenv->lg_regionmax = LG_BASE_REGION_SIZE;
40 41
}

jimw@mysql.com's avatar
jimw@mysql.com committed
42 43 44 45
/*
 * PUBLIC: int __log_get_lg_bsize __P((DB_ENV *, u_int32_t *));
 */
int
jimw@mysql.com's avatar
jimw@mysql.com committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
__log_get_lg_bsize(dbenv, lg_bsizep)
	DB_ENV *dbenv;
	u_int32_t *lg_bsizep;
{
	ENV_NOT_CONFIGURED(dbenv,
	    dbenv->lg_handle, "DB_ENV->get_lg_bsize", DB_INIT_LOG);

	if (LOGGING_ON(dbenv)) {
		/* Cannot be set after open, no lock required to read. */
		*lg_bsizep = ((LOG *)
		    ((DB_LOG *)dbenv->lg_handle)->reginfo.primary)->buffer_size;
	} else
		*lg_bsizep = dbenv->lg_bsize;
	return (0);
}

62 63
/*
 * __log_set_lg_bsize --
jimw@mysql.com's avatar
jimw@mysql.com committed
64 65 66
 *	DB_ENV->set_lg_bsize.
 *
 * PUBLIC: int __log_set_lg_bsize __P((DB_ENV *, u_int32_t));
67
 */
jimw@mysql.com's avatar
jimw@mysql.com committed
68
int
69 70 71 72
__log_set_lg_bsize(dbenv, lg_bsize)
	DB_ENV *dbenv;
	u_int32_t lg_bsize;
{
jimw@mysql.com's avatar
jimw@mysql.com committed
73
	ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lg_bsize");
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
74

jimw@mysql.com's avatar
jimw@mysql.com committed
75 76 77
	dbenv->lg_bsize = lg_bsize;
	return (0);
}
78

jimw@mysql.com's avatar
jimw@mysql.com committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
/*
 * PUBLIC: int __log_get_lg_filemode __P((DB_ENV *, int *));
 */
int
__log_get_lg_filemode(dbenv, lg_modep)
	DB_ENV *dbenv;
	int *lg_modep;
{
	DB_LOG *dblp;

	ENV_NOT_CONFIGURED(dbenv,
	    dbenv->lg_handle, "DB_ENV->get_lg_filemode", DB_INIT_LOG);

	if (LOGGING_ON(dbenv)) {
		dblp = dbenv->lg_handle;
		LOG_SYSTEM_LOCK(dbenv);
		*lg_modep = ((LOG *)dblp->reginfo.primary)->filemode;
		LOG_SYSTEM_UNLOCK(dbenv);
	} else
		*lg_modep = dbenv->lg_filemode;

	return (0);
}

/*
 * __log_set_lg_filemode --
 *	DB_ENV->set_lg_filemode.
 *
 * PUBLIC: int __log_set_lg_filemode __P((DB_ENV *, int));
 */
int
__log_set_lg_filemode(dbenv, lg_mode)
	DB_ENV *dbenv;
	int lg_mode;
{
	DB_LOG *dblp;
	LOG *lp;

	ENV_NOT_CONFIGURED(dbenv,
	    dbenv->lg_handle, "DB_ENV->set_lg_filemode", DB_INIT_LOG);

	if (LOGGING_ON(dbenv)) {
		dblp = dbenv->lg_handle;
		lp = dblp->reginfo.primary;
		LOG_SYSTEM_LOCK(dbenv);
		lp->filemode = lg_mode;
		LOG_SYSTEM_UNLOCK(dbenv);
	} else
		dbenv->lg_filemode = lg_mode;

	return (0);
}

/*
 * PUBLIC: int __log_get_lg_max __P((DB_ENV *, u_int32_t *));
 */
int
jimw@mysql.com's avatar
jimw@mysql.com committed
136 137 138 139 140
__log_get_lg_max(dbenv, lg_maxp)
	DB_ENV *dbenv;
	u_int32_t *lg_maxp;
{
	DB_LOG *dblp;
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
141

jimw@mysql.com's avatar
jimw@mysql.com committed
142 143 144 145 146
	ENV_NOT_CONFIGURED(dbenv,
	    dbenv->lg_handle, "DB_ENV->get_lg_max", DB_INIT_LOG);

	if (LOGGING_ON(dbenv)) {
		dblp = dbenv->lg_handle;
jimw@mysql.com's avatar
jimw@mysql.com committed
147
		LOG_SYSTEM_LOCK(dbenv);
jimw@mysql.com's avatar
jimw@mysql.com committed
148
		*lg_maxp = ((LOG *)dblp->reginfo.primary)->log_nsize;
jimw@mysql.com's avatar
jimw@mysql.com committed
149
		LOG_SYSTEM_UNLOCK(dbenv);
jimw@mysql.com's avatar
jimw@mysql.com committed
150 151
	} else
		*lg_maxp = dbenv->lg_size;
152 153 154 155 156 157

	return (0);
}

/*
 * __log_set_lg_max --
jimw@mysql.com's avatar
jimw@mysql.com committed
158 159 160
 *	DB_ENV->set_lg_max.
 *
 * PUBLIC: int __log_set_lg_max __P((DB_ENV *, u_int32_t));
161
 */
jimw@mysql.com's avatar
jimw@mysql.com committed
162
int
163 164 165 166
__log_set_lg_max(dbenv, lg_max)
	DB_ENV *dbenv;
	u_int32_t lg_max;
{
jimw@mysql.com's avatar
jimw@mysql.com committed
167 168 169
	DB_LOG *dblp;
	LOG *lp;
	int ret;
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
170

jimw@mysql.com's avatar
jimw@mysql.com committed
171 172
	ENV_NOT_CONFIGURED(dbenv,
	    dbenv->lg_handle, "DB_ENV->set_lg_max", DB_INIT_LOG);
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
173

jimw@mysql.com's avatar
jimw@mysql.com committed
174 175 176 177 178
	if (LOGGING_ON(dbenv)) {
		if ((ret = __log_check_sizes(dbenv, lg_max, 0)) != 0)
			return (ret);
		dblp = dbenv->lg_handle;
		lp = dblp->reginfo.primary;
jimw@mysql.com's avatar
jimw@mysql.com committed
179
		LOG_SYSTEM_LOCK(dbenv);
jimw@mysql.com's avatar
jimw@mysql.com committed
180
		lp->log_nsize = lg_max;
jimw@mysql.com's avatar
jimw@mysql.com committed
181
		LOG_SYSTEM_UNLOCK(dbenv);
jimw@mysql.com's avatar
jimw@mysql.com committed
182
	} else
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
183 184 185
		dbenv->lg_size = lg_max;

	return (0);
jimw@mysql.com's avatar
jimw@mysql.com committed
186
}
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
187

jimw@mysql.com's avatar
jimw@mysql.com committed
188 189 190 191
/*
 * PUBLIC: int __log_get_lg_regionmax __P((DB_ENV *, u_int32_t *));
 */
int
jimw@mysql.com's avatar
jimw@mysql.com committed
192 193 194 195 196 197 198 199 200 201 202 203 204 205
__log_get_lg_regionmax(dbenv, lg_regionmaxp)
	DB_ENV *dbenv;
	u_int32_t *lg_regionmaxp;
{
	ENV_NOT_CONFIGURED(dbenv,
	    dbenv->lg_handle, "DB_ENV->get_lg_regionmax", DB_INIT_LOG);

	if (LOGGING_ON(dbenv)) {
		/* Cannot be set after open, no lock required to read. */
		*lg_regionmaxp = ((LOG *)
		    ((DB_LOG *)dbenv->lg_handle)->reginfo.primary)->regionmax;
	} else
		*lg_regionmaxp = dbenv->lg_regionmax;
	return (0);
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
206 207 208 209
}

/*
 * __log_set_lg_regionmax --
jimw@mysql.com's avatar
jimw@mysql.com committed
210 211 212
 *	DB_ENV->set_lg_regionmax.
 *
 * PUBLIC: int __log_set_lg_regionmax __P((DB_ENV *, u_int32_t));
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
213
 */
jimw@mysql.com's avatar
jimw@mysql.com committed
214
int
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
215 216 217 218
__log_set_lg_regionmax(dbenv, lg_regionmax)
	DB_ENV *dbenv;
	u_int32_t lg_regionmax;
{
jimw@mysql.com's avatar
jimw@mysql.com committed
219
	ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lg_regionmax");
220 221

					/* Let's not be silly. */
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
222 223 224
	if (lg_regionmax != 0 && lg_regionmax < LG_BASE_REGION_SIZE) {
		__db_err(dbenv,
		    "log file size must be >= %d", LG_BASE_REGION_SIZE);
225 226 227
		return (EINVAL);
	}

ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
228
	dbenv->lg_regionmax = lg_regionmax;
229 230 231
	return (0);
}

jimw@mysql.com's avatar
jimw@mysql.com committed
232 233 234 235
/*
 * PUBLIC: int __log_get_lg_dir __P((DB_ENV *, const char **));
 */
int
jimw@mysql.com's avatar
jimw@mysql.com committed
236 237 238 239 240 241 242 243
__log_get_lg_dir(dbenv, dirp)
	DB_ENV *dbenv;
	const char **dirp;
{
	*dirp = dbenv->db_log_dir;
	return (0);
}

244 245
/*
 * __log_set_lg_dir --
jimw@mysql.com's avatar
jimw@mysql.com committed
246 247 248
 *	DB_ENV->set_lg_dir.
 *
 * PUBLIC: int __log_set_lg_dir __P((DB_ENV *, const char *));
249
 */
jimw@mysql.com's avatar
jimw@mysql.com committed
250
int
251 252 253 254 255
__log_set_lg_dir(dbenv, dir)
	DB_ENV *dbenv;
	const char *dir;
{
	if (dbenv->db_log_dir != NULL)
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
256
		__os_free(dbenv, dbenv->db_log_dir);
257 258
	return (__os_strdup(dbenv, dir, &dbenv->db_log_dir));
}
jimw@mysql.com's avatar
jimw@mysql.com committed
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354

/*
 * __log_get_flags --
 *	DB_ENV->get_flags.
 *
 * PUBLIC: void __log_get_flags __P((DB_ENV *, u_int32_t *));
 */
void
__log_get_flags(dbenv, flagsp)
	DB_ENV *dbenv;
	u_int32_t *flagsp;
{
	DB_LOG *dblp;
	LOG *lp;
	u_int32_t flags;

	if ((dblp = dbenv->lg_handle) == NULL)
		return;

	lp = dblp->reginfo.primary;

	flags = *flagsp;
	if (lp->db_log_autoremove)
		LF_SET(DB_LOG_AUTOREMOVE);
	else
		LF_CLR(DB_LOG_AUTOREMOVE);
	if (lp->db_log_inmemory)
		LF_SET(DB_LOG_INMEMORY);
	else
		LF_CLR(DB_LOG_INMEMORY);
	*flagsp = flags;
}

/*
 * __log_set_flags --
 *	DB_ENV->set_flags.
 *
 * PUBLIC: void __log_set_flags __P((DB_ENV *, u_int32_t, int));
 */
void
__log_set_flags(dbenv, flags, on)
	DB_ENV *dbenv;
	u_int32_t flags;
	int on;
{
	DB_LOG *dblp;
	LOG *lp;

	if ((dblp = dbenv->lg_handle) == NULL)
		return;

	lp = dblp->reginfo.primary;

	if (LF_ISSET(DB_LOG_AUTOREMOVE))
		lp->db_log_autoremove = on ? 1 : 0;
	if (LF_ISSET(DB_LOG_INMEMORY))
		lp->db_log_inmemory = on ? 1 : 0;
}

/*
 * __log_check_sizes --
 *	Makes sure that the log file size and log buffer size are compatible.
 *
 * PUBLIC: int __log_check_sizes __P((DB_ENV *, u_int32_t, u_int32_t));
 */
int
__log_check_sizes(dbenv, lg_max, lg_bsize)
	DB_ENV *dbenv;
	u_int32_t lg_max;
	u_int32_t lg_bsize;
{
	LOG *lp;
	int inmem;

	if (LOGGING_ON(dbenv)) {
		lp = ((DB_LOG *)dbenv->lg_handle)->reginfo.primary;
		inmem = lp->db_log_inmemory;
		lg_bsize = lp->buffer_size;
	} else
		inmem = (F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) != 0);

	if (inmem) {
		if (lg_bsize == 0)
			lg_bsize = LG_BSIZE_INMEM;
		if (lg_max == 0)
			lg_max = LG_MAX_INMEM;

		if (lg_bsize <= lg_max) {
			__db_err(dbenv,
		  "in-memory log buffer must be larger than the log file size");
			return (EINVAL);
		}
	}

	return (0);
}