コード例 #1
0
ファイル: schema_plan.c プロジェクト: 7segments/mongo-1
/*
 * __wt_schema_colcheck --
 *	Check that a list of columns matches a (key,value) format pair.
 */
int
__wt_schema_colcheck(WT_SESSION_IMPL *session,
    const char *key_format, const char *value_format, WT_CONFIG_ITEM *colconf,
    u_int *kcolsp, u_int *vcolsp)
{
	WT_CONFIG conf;
	WT_CONFIG_ITEM k, v;
	WT_DECL_PACK_VALUE(pv);
	WT_DECL_RET;
	WT_PACK pack;
	u_int kcols, ncols, vcols;

	WT_RET(__pack_init(session, &pack, key_format));
	for (kcols = 0; (ret = __pack_next(&pack, &pv)) == 0; kcols++)
		;
	WT_RET_TEST(ret != WT_NOTFOUND, ret);

	WT_RET(__pack_init(session, &pack, value_format));
	for (vcols = 0; (ret = __pack_next(&pack, &pv)) == 0; vcols++)
		;
	WT_RET_TEST(ret != WT_NOTFOUND, ret);

	/* Walk through the named columns. */
	WT_RET(__wt_config_subinit(session, &conf, colconf));
	for (ncols = 0; (ret = __wt_config_next(&conf, &k, &v)) == 0; ncols++)
		;
	WT_RET_TEST(ret != WT_NOTFOUND, ret);

	if (ncols != 0 && ncols != kcols + vcols)
		WT_RET_MSG(session, EINVAL, "Number of columns in '%.*s' "
		    "does not match key format '%s' plus value format '%s'",
		    (int)colconf->len, colconf->str, key_format, value_format);

	if (kcolsp != NULL)
		*kcolsp = kcols;
	if (vcolsp != NULL)
		*vcolsp = vcols;

	return (0);
}
コード例 #2
0
ファイル: cur_file.c プロジェクト: niumowm/wiredtiger
/*
 * __wt_curfile_open --
 *	WT_SESSION->open_cursor method for the btree cursor type.
 */
int
__wt_curfile_open(WT_SESSION_IMPL *session, const char *uri,
    WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp)
{
	WT_CONFIG_ITEM cval;
	WT_DECL_RET;
	int bitmap, bulk;
	uint32_t flags;

	flags = 0;

	WT_RET(__wt_config_gets_defno(session, cfg, "bulk", &cval));
	if (cval.type == ITEM_NUM && (cval.val == 0 || cval.val == 1)) {
		bitmap = 0;
		bulk = (cval.val != 0);
	} else if (WT_STRING_MATCH("bitmap", cval.str, cval.len))
		bitmap = bulk = 1;
	else
		WT_RET_MSG(session, EINVAL,
		    "Value for 'bulk' must be a boolean or 'bitmap'");

	/* Bulk handles require exclusive access. */
	if (bulk)
		LF_SET(WT_BTREE_BULK | WT_BTREE_EXCLUSIVE);

	/* TODO: handle projections. */

	/* Get the handle and lock it while the cursor is using it. */
	if (WT_PREFIX_MATCH(uri, "file:"))
		WT_RET(__wt_session_get_btree_ckpt(session, uri, cfg, flags));
	else
		WT_RET(__wt_bad_object_type(session, uri));

	WT_ERR(__wt_curfile_create(session, owner, cfg, bulk, bitmap, cursorp));
	return (0);

err:	/* If the cursor could not be opened, release the handle. */
	WT_TRET(__wt_session_release_btree(session));
	return (ret);
}
コード例 #3
0
ファイル: os_mtx.c プロジェクト: RolfAndreassen/wiredtiger
/*
 * __wt_rwlock_destroy --
 *	Destroy a mutex.
 */
int
__wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp)
{
	WT_DECL_RET;
	WT_RWLOCK *rwlock;

	rwlock = *rwlockp;		/* Clear our caller's reference. */
	if (rwlock == NULL)
		return (0);
	*rwlockp = NULL;

	WT_VERBOSE_RET(session, mutex,
	    "rwlock: destroy %s (%p)", rwlock->name, rwlock);

	if ((ret = pthread_rwlock_destroy(&rwlock->rwlock)) == 0) {
		__wt_free(session, rwlock);
		return (0);
	}

	/* Deliberately leak memory on error. */
	WT_RET_MSG(session, ret, "pthread_rwlock_destroy: %s", rwlock->name);
}
コード例 #4
0
ファイル: lsm_tree.c プロジェクト: umerazad/wiredtiger
/*
 * __lsm_tree_open_check --
 *	Validate the configuration of an LSM tree.
 */
static int
__lsm_tree_open_check(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
{
	WT_CONFIG_ITEM cval;
	uint64_t required;
	uint32_t maxleafpage;
	const char *cfg[] = { WT_CONFIG_BASE(
	    session, session_create), lsm_tree->file_config, NULL };

	WT_RET(__wt_config_gets(session, cfg, "leaf_page_max", &cval));
	maxleafpage = (uint32_t)cval.val;

	/* Three chunks, plus one page for each participant in a merge. */
	required = 3 * lsm_tree->chunk_size +
	    lsm_tree->merge_threads * (lsm_tree->merge_max *  maxleafpage);
	if (S2C(session)->cache_size < required)
		WT_RET_MSG(session, EINVAL,
		    "The LSM configuration requires a cache size of at least %"
		    PRIu64 ". Configured size is %" PRIu64,
		    required, S2C(session)->cache_size);
	return (0);
}
コード例 #5
0
ファイル: os_filesize.c プロジェクト: 3rf/mongo
/*
 * __wt_filesize_name --
 *	Return the size of a file in bytes, given a file name.
 */
int
__wt_filesize_name(
    WT_SESSION_IMPL *session, const char *filename, wt_off_t *sizep)
{
	WT_DECL_RET;
	WIN32_FILE_ATTRIBUTE_DATA data;
	char *path;

	WT_RET(__wt_filename(session, filename, &path));

	ret = GetFileAttributesExA(path, GetFileExInfoStandard, &data);

	__wt_free(session, path);

	if (ret != 0) {
		*sizep =
		    ((int64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow;
		return (0);
	}

	WT_RET_MSG(session, __wt_errno(), "%s: GetFileAttributesEx", filename);
}
コード例 #6
0
ファイル: os_getenv.c プロジェクト: ralic/mongo
/*
 * __wt_getenv --
 * 	Get a non-NULL, greater than zero-length environment variable.
 */
int
__wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp)
{
    WT_DECL_RET;
    DWORD size;

    *envp = NULL;

    size = GetEnvironmentVariableA(variable, NULL, 0);
    if (size <= 1)
        return (WT_NOTFOUND);

    WT_RET(__wt_calloc(session, 1, size, envp));

    ret = GetEnvironmentVariableA(variable, *envp, size);
    /* We expect the number of bytes not including nul terminator. */
    if ((ret + 1) != size)
        WT_RET_MSG(session, __wt_getlasterror(),
                   "GetEnvironmentVariableA failed: %s", variable);

    return (0);
}
コード例 #7
0
ファイル: conn_log.c プロジェクト: GYGit/mongo
/*
 * __wt_log_truncate_files --
 *	Truncate log files via archive once. Requires that the server is not
 *	currently running.
 */
int
__wt_log_truncate_files(
    WT_SESSION_IMPL *session, WT_CURSOR *cursor, const char *cfg[])
{
	WT_CONNECTION_IMPL *conn;
	WT_DECL_RET;
	WT_LOG *log;
	uint32_t backup_file;
	bool locked;

	WT_UNUSED(cfg);
	conn = S2C(session);
	if (!FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED))
		return (0);
	if (F_ISSET(conn, WT_CONN_SERVER_RUN) &&
	    FLD_ISSET(conn->log_flags, WT_CONN_LOG_ARCHIVE))
		WT_RET_MSG(session, EINVAL,
		    "Attempt to archive manually while a server is running");

	log = conn->log;

	backup_file = 0;
	if (cursor != NULL)
		backup_file = WT_CURSOR_BACKUP_ID(cursor);
	WT_ASSERT(session, backup_file <= log->alloc_lsn.l.file);
	WT_RET(__wt_verbose(session, WT_VERB_LOG,
	    "log_truncate_files: Archive once up to %" PRIu32,
	    backup_file));

	WT_RET(__wt_writelock(session, log->log_archive_lock));
	locked = true;
	WT_ERR(__log_archive_once(session, backup_file));
	WT_ERR(__wt_writeunlock(session, log->log_archive_lock));
	locked = false;
err:
	if (locked)
		WT_RET(__wt_writeunlock(session, log->log_archive_lock));
	return (ret);
}
コード例 #8
0
ファイル: schema_plan.c プロジェクト: ajdavis/mongo
/*
 * __wt_table_check --
 *	Make sure all columns appear in a column group.
 */
int
__wt_table_check(WT_SESSION_IMPL *session, WT_TABLE *table)
{
	WT_CONFIG conf;
	WT_CONFIG_ITEM k, v;
	WT_DECL_RET;
	u_int cg, col, i;
	char coltype;

	if (table->is_simple)
		return (0);

	/* Walk through the columns. */
	__wt_config_subinit(session, &conf, &table->colconf);

	/* Skip over the key columns. */
	for (i = 0; i < table->nkey_columns; i++)
		WT_RET(__wt_config_next(&conf, &k, &v));
	cg = col = 0;
	coltype = 0;
	while ((ret = __wt_config_next(&conf, &k, &v)) == 0) {
		if (__find_next_col(
		    session, table, &k, &cg, &col, &coltype) != 0)
			WT_RET_MSG(session, EINVAL,
			    "Column '%.*s' in '%s' does not appear in a "
			    "column group",
			    (int)k.len, k.str, table->iface.name);
		/*
		 * Column groups can't store key columns in their value:
		 * __wt_struct_reformat should have already detected this case.
		 */
		WT_ASSERT(session, coltype == WT_PROJ_VALUE);

	}
	WT_RET_TEST(ret != WT_NOTFOUND, ret);

	return (0);
}
コード例 #9
0
ファイル: conn_api.c プロジェクト: niumowm/wiredtiger
/*
 * __conn_config_env --
 *	Read configuration from an environment variable, if set.
 */
static int
__conn_config_env(WT_SESSION_IMPL *session, const char **cfg)
{
	WT_CONFIG_ITEM cval;
	const char *env_config;

	if ((env_config = getenv("WIREDTIGER_CONFIG")) == NULL ||
	    strlen(env_config) == 0)
		return (0);

	/*
	 * Security stuff:
	 *
	 * If the "use_environment_priv" configuration string is set, use the
	 * environment variable if the process has appropriate privileges.
	 */
	WT_RET(__wt_config_gets(session, cfg, "use_environment_priv", &cval));
	if (cval.val == 0 && __wt_has_priv())
		WT_RET_MSG(session, WT_ERROR, "%s",
		    "WIREDTIGER_CONFIG environment variable set but process "
		    "lacks privileges to use that environment variable");

	/* Check the configuration string. */
	WT_RET(__wt_config_check(
	    session, __wt_confchk_wiredtiger_open, env_config, 0));

	/*
	 * The environment setting comes second-to-last: it overrides the
	 * WiredTiger.config file (if any), but not the config passed by the
	 * application.
	 */
	while (cfg[1] != NULL)
		++cfg;
	cfg[1] = cfg[0];
	cfg[0] = env_config;

	return (0);
}
コード例 #10
0
ファイル: bt_huffman.c プロジェクト: 7segments/mongo-1
/*
 * __huffman_confchk_file --
 *	Check for a Huffman configuration file and return the file name.
 */
static int
__huffman_confchk_file(
    WT_SESSION_IMPL *session, WT_CONFIG_ITEM *v, int *is_utf8p, FILE **fpp)
{
	FILE *fp;
	WT_DECL_RET;
	size_t len;
	char *fname;

	/* Look for a prefix and file name. */
	len = 0;
	if (is_utf8p != NULL)
		*is_utf8p = 0;
	if (WT_PREFIX_MATCH(v->str, "utf8")) {
		if (is_utf8p != NULL)
			*is_utf8p = 1;
		len = strlen("utf8");
	} else if (WT_PREFIX_MATCH(v->str, "utf16"))
		len = strlen("utf16");
	if (len == 0 || len >= v->len)
		WT_RET_MSG(session, EINVAL,
		    "illegal Huffman configuration: %.*s", (int)v->len, v->str);

	/* Check the file exists. */
	WT_RET(__wt_strndup(session, v->str + len, v->len - len, &fname));
	WT_ERR(__wt_fopen(session,
	    fname, WT_FHANDLE_READ, WT_FOPEN_FIXED, &fp));

	/* Optionally return the file handle. */
	if (fpp == NULL)
		(void)__wt_fclose(&fp, WT_FHANDLE_READ);
	else
		*fpp = fp;

err:	__wt_free(session, fname);

	return (ret);
}
コード例 #11
0
ファイル: bt_cursor.c プロジェクト: radik/mongo
/*
 * __wt_btcur_compare --
 *	Return a comparison between two cursors.
 */
int
__wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp)
{
	WT_CURSOR *a, *b;
	WT_SESSION_IMPL *session;

	a = (WT_CURSOR *)a_arg;
	b = (WT_CURSOR *)b_arg;
	session = (WT_SESSION_IMPL *)a->session;

	/* Confirm both cursors reference the same object. */
	if (a_arg->btree != b_arg->btree)
		WT_RET_MSG(
		    session, EINVAL, "Cursors must reference the same object");

	switch (a_arg->btree->type) {
	case BTREE_COL_FIX:
	case BTREE_COL_VAR:
		/*
		 * Compare the interface's cursor record, not the underlying
		 * cursor reference: the interface's cursor reference is the
		 * one being returned to the application.
		 */
		if (a->recno < b->recno)
			*cmpp = -1;
		else if (a->recno == b->recno)
			*cmpp = 0;
		else
			*cmpp = 1;
		break;
	case BTREE_ROW:
		WT_RET(__wt_compare(
		    session, a_arg->btree->collator, &a->key, &b->key, cmpp));
		break;
	WT_ILLEGAL_VALUE(session);
	}
	return (0);
}
コード例 #12
0
ファイル: os_rename.c プロジェクト: 3rf/mongo
/*
 * __wt_rename --
 *	Rename a file.
 */
int
__wt_rename(WT_SESSION_IMPL *session, const char *from, const char *to)
{
	WT_DECL_RET;
	uint32_t lasterror;
	char *from_path, *to_path;

	WT_RET(__wt_verbose(
		session, WT_VERB_FILEOPS, "rename %s to %s", from, to));

	from_path = to_path = NULL;

	WT_RET(__wt_filename(session, from, &from_path));
	WT_TRET(__wt_filename(session, to, &to_path));

	/*
	 * Check if file exists since Windows does not override the file if
	 * it exists.
	 */
	if ((ret = GetFileAttributesA(to_path)) != INVALID_FILE_ATTRIBUTES) {
		if ((ret = DeleteFileA(to_path)) == FALSE) {
			lasterror = GetLastError();
			goto err;
		}
	}

	if ((MoveFileA(from_path, to_path)) == FALSE)
		lasterror = GetLastError();

err:
	__wt_free(session, from_path);
	__wt_free(session, to_path);

	if (ret != FALSE)
		return (0);

	WT_RET_MSG(session, lasterror, "MoveFile %s to %s", from, to);
}
コード例 #13
0
ファイル: schema_open.c プロジェクト: SteveCarrasco/mongo
/*
 * __wt_schema_get_colgroup --
 *	Find a column group by URI.
 */
int
__wt_schema_get_colgroup(WT_SESSION_IMPL *session,
    const char *uri, bool quiet, WT_TABLE **tablep, WT_COLGROUP **colgroupp)
{
	WT_COLGROUP *colgroup;
	WT_TABLE *table;
	const char *tablename, *tend;
	u_int i;

	*colgroupp = NULL;

	tablename = uri;
	if (!WT_PREFIX_SKIP(tablename, "colgroup:"))
		return (__wt_bad_object_type(session, uri));

	if ((tend = strchr(tablename, ':')) == NULL)
		tend = tablename + strlen(tablename);

	WT_RET(__wt_schema_get_table(session,
	    tablename, WT_PTRDIFF(tend, tablename), false, &table));

	for (i = 0; i < WT_COLGROUPS(table); i++) {
		colgroup = table->cgroups[i];
		if (strcmp(colgroup->name, uri) == 0) {
			*colgroupp = colgroup;
			if (tablep != NULL)
				*tablep = table;
			else
				__wt_schema_release_table(session, table);
			return (0);
		}
	}

	__wt_schema_release_table(session, table);
	if (quiet)
		WT_RET(ENOENT);
	WT_RET_MSG(session, ENOENT, "%s not found in table", uri);
}
コード例 #14
0
ファイル: os_fs.c プロジェクト: AshishSanju/mongo
/*
 * __posix_fs_remove --
 *	Remove a file.
 */
static int
__posix_fs_remove(
    WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name)
{
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	WT_UNUSED(file_system);

	session = (WT_SESSION_IMPL *)wt_session;

	/*
	 * ISO C doesn't require remove return -1 on failure or set errno (note
	 * POSIX 1003.1 extends C with those requirements). Regardless, use the
	 * unlink system call, instead of remove, to simplify error handling;
	 * where we're not doing any special checking for standards compliance,
	 * using unlink may be marginally safer.
	 */
	WT_SYSCALL(unlink(name), ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret, "%s: file-remove: unlink", name);
}
コード例 #15
0
ファイル: os_fs.c プロジェクト: GYGit/mongo
/*
 * __posix_fs_exist --
 *	Return if the file exists.
 */
static int
__posix_fs_exist(WT_FILE_SYSTEM *file_system,
    WT_SESSION *wt_session, const char *name, bool *existp)
{
	struct stat sb;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	WT_UNUSED(file_system);

	session = (WT_SESSION_IMPL *)wt_session;

	WT_SYSCALL(stat(name, &sb), ret);
	if (ret == 0) {
		*existp = true;
		return (0);
	}
	if (ret == ENOENT) {
		*existp = false;
		return (0);
	}
	WT_RET_MSG(session, ret, "%s: file-exist: stat", name);
}
コード例 #16
0
ファイル: os_fs.c プロジェクト: AshishSanju/mongo
/*
 * __posix_fs_rename --
 *	Rename a file.
 */
static int
__posix_fs_rename(WT_FILE_SYSTEM *file_system,
    WT_SESSION *wt_session, const char *from, const char *to)
{
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	WT_UNUSED(file_system);

	session = (WT_SESSION_IMPL *)wt_session;

	/*
	 * ISO C doesn't require rename return -1 on failure or set errno (note
	 * POSIX 1003.1 extends C with those requirements). Be cautious, force
	 * any non-zero return to -1 so we'll check errno. We can still end up
	 * with the wrong errno (if errno is garbage), or the generic WT_ERROR
	 * return (if errno is 0), but we've done the best we can.
	 */
	WT_SYSCALL(rename(from, to) != 0 ? -1 : 0, ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret, "%s to %s: file-rename: rename", from, to);
}
コード例 #17
0
ファイル: os_remove.c プロジェクト: BobbWu/wiredtiger
/*
 * __wt_remove --
 *	Remove a file.
 */
int
__wt_remove(WT_SESSION_IMPL *session, const char *name)
{
	WT_DECL_RET;
	char *path;
	uint32_t lasterror;

	WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: remove", name));

	__remove_file_check(session, name);

	WT_RET(__wt_filename(session, name, &path));

	if ((ret = DeleteFileA(path)) == FALSE)
		lasterror = __wt_errno();

	__wt_free(session, path);

	if (ret != FALSE)
		return (0);

	WT_RET_MSG(session, lasterror, "%s: remove", name);
}
コード例 #18
0
ファイル: bt_debug.c プロジェクト: ckoolkarni/wiredtiger
/*
 * __debug_config --
 *	Configure debugging output.
 */
static int
__debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile)
{
	memset(ds, 0, sizeof(WT_DBG));

	ds->session = session;

	WT_RET(__wt_scr_alloc(session, 512, &ds->tmp));

	/*
	 * If we weren't given a file, we use the default event handler, and
	 * we'll have to buffer messages.
	 */
	if (ofile == NULL)
		return (__wt_scr_alloc(session, 512, &ds->msg));

	/* If we're using a file, flush on each line. */
	if ((ds->fp = fopen(ofile, "w")) == NULL)
		WT_RET_MSG(session, __wt_errno(), "%s", ofile);

	(void)setvbuf(ds->fp, NULL, _IOLBF, 0);
	return (0);
}
コード例 #19
0
ファイル: os_map.c プロジェクト: EaseTech/wiredtiger
/*
 * __wt_mmap_preload --
 *	Cause a section of a memory map to be faulted in.
 */
int
__wt_mmap_preload(WT_SESSION_IMPL *session, const void *p, size_t size)
{
#ifdef HAVE_POSIX_MADVISE
	/* Linux requires the address be aligned to a 4KB boundary. */
	WT_BM *bm = S2BT(session)->bm;
	WT_DECL_RET;
	void *blk = (void *)((uintptr_t)p & ~(uintptr_t)(WT_VM_PAGESIZE - 1));
	size += WT_PTRDIFF(p, blk);

	/* XXX proxy for "am I doing a scan?" -- manual read-ahead */
	if (F_ISSET(session, WT_SESSION_NO_CACHE)) {
		/* Read in 2MB blocks every 1MB of data. */
		if (((uintptr_t)((uint8_t *)blk + size) &
		    (uintptr_t)((1<<20) - 1)) < (uintptr_t)blk)
			return (0);
		size = WT_MIN(WT_MAX(20 * size, 2 << 20),
		    WT_PTRDIFF((uint8_t *)bm->map + bm->maplen, blk));
	}

	/*
	 * Manual pages aren't clear on whether alignment is required for the
	 * size, so we will be conservative.
	 */
	size &= ~(size_t)(WT_VM_PAGESIZE - 1);

	if (size > WT_VM_PAGESIZE &&
	    (ret = posix_madvise(blk, size, POSIX_MADV_WILLNEED)) != 0)
		WT_RET_MSG(session, ret, "posix_madvise will need");
#else
	WT_UNUSED(session);
	WT_UNUSED(p);
	WT_UNUSED(size);
#endif

	return (0);
}
コード例 #20
0
ファイル: bt_vrfy.c プロジェクト: ckoolkarni/wiredtiger
/*
 * __verify_config --
 *	Verification supports dumping pages in various formats.
 */
static int
__verify_config(WT_SESSION_IMPL *session, const char *cfg[], WT_VSTUFF *vs)
{
	WT_CONFIG_ITEM cval;
	WT_DECL_RET;

	ret = __wt_config_gets(session, cfg, "dump_address", &cval);
	if (ret != 0 && ret != WT_NOTFOUND)
		WT_RET(ret);
	if (ret == 0 && cval.val != 0)
		vs->dump_address = 1;

	ret = __wt_config_gets(session, cfg, "dump_blocks", &cval);
	if (ret != 0 && ret != WT_NOTFOUND)
		WT_RET(ret);
	if (ret == 0 && cval.val != 0)
		vs->dump_blocks = 1;

	ret = __wt_config_gets(session, cfg, "dump_pages", &cval);
	if (ret != 0 && ret != WT_NOTFOUND)
		WT_RET(ret);
	if (ret == 0 && cval.val != 0)
		vs->dump_pages = 1;

#ifdef HAVE_DIAGNOSTIC
	/*
	 * We use the verification code to do debugging dumps because if we're
	 * dumping in debugging mode, we want to confirm the page is OK before
	 * walking it.
	 */
#else
	if (vs->dump_address || vs->dump_blocks || vs->dump_pages)
		WT_RET_MSG(session, ENOTSUP,
		    "the WiredTiger library was not built in diagnostic mode");
#endif
	return (0);
}
コード例 #21
0
ファイル: block_ckpt.c プロジェクト: zhliu03/wiredtiger
/*
 * __wt_block_ckpt_init --
 *	Initialize a checkpoint structure.
 */
int
__wt_block_ckpt_init(WT_SESSION_IMPL *session,
    WT_BLOCK *block, WT_BLOCK_CKPT *ci, const char *name, int is_live)
{
	WT_DECL_RET;

	/*
	 * If we're loading a new live checkpoint, there shouldn't be one
	 * already loaded.  The btree engine should prevent this from ever
	 * happening, but paranoia is a healthy thing.
	 */
	if (is_live) {
		__wt_spin_lock(session, &block->live_lock);
		if (block->live_load)
			ret = EINVAL;
		else
			block->live_load = 1;
		__wt_spin_unlock(session, &block->live_lock);
		if (ret)
			WT_RET_MSG(
			    session, EINVAL, "checkpoint already loaded");
	}

	memset(ci, 0, sizeof(*ci));

	ci->root_offset = WT_BLOCK_INVALID_OFFSET;

	WT_RET(__wt_block_extlist_init(session, &ci->alloc, name, "alloc"));
	WT_RET(__wt_block_extlist_init(session, &ci->avail, name, "avail"));
	WT_RET(__wt_block_extlist_init(session, &ci->discard, name, "discard"));

	ci->file_size = WT_BLOCK_DESC_SECTOR;
	WT_RET(__wt_block_extlist_init(
	    session, &ci->ckpt_avail, name, "ckpt_avail"));

	return (0);
}
コード例 #22
0
ファイル: os_map.c プロジェクト: EaseTech/wiredtiger
/*
 * __wt_mmap --
 *	Map a file into memory.
 */
int
__wt_mmap(WT_SESSION_IMPL *session, WT_FH *fh, void *mapp, size_t *lenp)
{
	void *map;

	WT_RET(__wt_verbose(session, WT_VERB_FILEOPS,
	    "%s: map %" PRIuMAX " bytes", fh->name, (uintmax_t)fh->size));

	if ((map = mmap(NULL, (size_t)fh->size,
	    PROT_READ,
#ifdef MAP_NOCORE
	    MAP_NOCORE |
#endif
	    MAP_PRIVATE,
	    fh->fd, (off_t)0)) == MAP_FAILED) {
		WT_RET_MSG(session, __wt_errno(),
		    "%s map error: failed to map %" PRIuMAX " bytes",
		    fh->name, (uintmax_t)fh->size);
	}

	*(void **)mapp = map;
	*lenp = (size_t)fh->size;
	return (0);
}
コード例 #23
0
ファイル: meta_table.c プロジェクト: GYGit/mongo
/*
 * __wt_metadata_remove --
 *	Remove a row from the metadata.
 */
int
__wt_metadata_remove(WT_SESSION_IMPL *session, const char *key)
{
	WT_CURSOR *cursor;
	WT_DECL_RET;

	WT_RET(__wt_verbose(session, WT_VERB_METADATA,
	    "Remove: key: %s, tracking: %s, %s" "turtle",
	    key, WT_META_TRACKING(session) ? "true" : "false",
	    __metadata_turtle(key) ? "" : "not "));

	if (__metadata_turtle(key))
		WT_RET_MSG(session, EINVAL,
		    "%s: remove not supported on the turtle file", key);

	WT_RET(__wt_metadata_cursor(session, &cursor));
	cursor->set_key(cursor, key);
	WT_ERR(cursor->search(cursor));
	if (WT_META_TRACKING(session))
		WT_ERR(__wt_meta_track_update(session, key));
	WT_ERR(cursor->remove(cursor));
err:	WT_TRET(__wt_metadata_cursor_release(session, &cursor));
	return (ret);
}
コード例 #24
0
ファイル: bt_bulk.c プロジェクト: RolfAndreassen/wiredtiger
/*
 * __wt_bulk_init --
 *	Start a bulk load.
 */
int
__wt_bulk_init(WT_CURSOR_BULK *cbulk)
{
	WT_BTREE *btree;
	WT_SESSION_IMPL *session;

	session = (WT_SESSION_IMPL *)cbulk->cbt.iface.session;
	btree = S2BT(session);

	/*
	 * Bulk-load is only permitted on newly created files, not any empty
	 * file -- see the checkpoint code for a discussion.
	 */
	if (!btree->bulk_load_ok)
		WT_RET_MSG(session, EINVAL,
		    "bulk-load is only possible for newly created trees");

	/* Set a reference to the empty leaf page. */
	cbulk->leaf = btree->root_page->u.intl.t->page;

	WT_RET(__wt_rec_bulk_init(cbulk));

	return (0);
}
コード例 #25
0
ファイル: os_exist.c プロジェクト: BobbWu/wiredtiger
/*
 * __wt_exist --
 *	Return if the file exists.
 */
int
__wt_exist(WT_SESSION_IMPL *session, const char *filename, bool *existp)
{
	struct stat sb;
	WT_DECL_RET;
	char *path;

	*existp = false;

	WT_RET(__wt_filename(session, filename, &path));

	WT_SYSCALL_RETRY(stat(path, &sb), ret);

	__wt_free(session, path);

	if (ret == 0) {
		*existp = true;
		return (0);
	}
	if (ret == ENOENT)
		return (0);

	WT_RET_MSG(session, ret, "%s: fstat", filename);
}
コード例 #26
0
ファイル: schema_rename.c プロジェクト: rain10154/wiredtiger
int __wt_schema_rename(WT_SESSION_IMPL *session, const char *uri, const char *newuri, const char *cfg[])
{
	WT_DATA_SOURCE *dsrc;
	WT_DECL_RET;
	const char *p, *t;

	/* The target type must match the source type. 匹配前面的关键字,例如file: table:*/
	for (p = uri, t = newuri; *p == *t && *p != ':'; ++p, ++t)
		;
	if (*p != ':' || *t != ':')
		WT_RET_MSG(session, EINVAL, "rename target type must match URI: %s to %s", uri, newuri);

	/*
	 * We track rename operations, if we fail in the middle, we want to
	 * back it all out.
	 */
	WT_RET(__wt_meta_track_on(session));

	if (WT_PREFIX_MATCH(uri, "file:"))
		ret = __rename_file(session, uri, newuri);
	else if (WT_PREFIX_MATCH(uri, "lsm:"))
		ret = __wt_lsm_tree_rename(session, uri, newuri, cfg);
	else if (WT_PREFIX_MATCH(uri, "table:"))
		ret = __rename_table(session, uri, newuri, cfg);
	else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
		ret = dsrc->rename == NULL ? __wt_object_unsupported(session, uri) : dsrc->rename(dsrc, &session->iface, uri, newuri, (WT_CONFIG_ARG *)cfg);
	else
		ret = __wt_bad_object_type(session, uri);

	/* Bump the schema generation so that stale data is ignored. */
	++S2C(session)->schema_gen;

	WT_TRET(__wt_meta_track_off(session, 1, ret != 0));

	return (ret == WT_NOTFOUND ? ENOENT : ret);
}
コード例 #27
0
ファイル: os_rename.c プロジェクト: rain10154/wiredtiger
/*调用rename系统调用*/
int __wt_rename(WT_SESSION_IMPL *session, const char *from, const char *to)
{
	WT_DECL_RET;
	char *from_path, *to_path;

	WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "rename %s to %s", from, to));

	from_path = to_path = NULL;

	/*对路劲进行校验,如果不合法路径,直接返回*/
	WT_RET(__wt_filename(session, from, &from_path));
	WT_TRET(__wt_filename(session, to, &to_path));

	if (ret == 0)
		WT_SYSCALL_RETRY(rename(from_path, to_path), ret);

	__wt_free(session, from_path);
	__wt_free(session, to_path);

	if(ret == 0)
		return 0;

	WT_RET_MSG(session, ret, "rename %s to %s", from, to);
}
コード例 #28
0
ファイル: bt_vrfy.c プロジェクト: BobbWu/wiredtiger
/*
 * __verify_config --
 *	Debugging: verification supports dumping pages in various formats.
 */
static int
__verify_config(WT_SESSION_IMPL *session, const char *cfg[], WT_VSTUFF *vs)
{
	WT_CONFIG_ITEM cval;

	WT_RET(__wt_config_gets(session, cfg, "dump_address", &cval));
	vs->dump_address = cval.val != 0;

	WT_RET(__wt_config_gets(session, cfg, "dump_blocks", &cval));
	vs->dump_blocks = cval.val != 0;

	WT_RET(__wt_config_gets(session, cfg, "dump_pages", &cval));
	vs->dump_pages = cval.val != 0;

	WT_RET(__wt_config_gets(session, cfg, "dump_shape", &cval));
	vs->dump_shape = cval.val != 0;

#if !defined(HAVE_DIAGNOSTIC)
	if (vs->dump_blocks || vs->dump_pages)
		WT_RET_MSG(session, ENOTSUP,
		    "the WiredTiger library was not built in diagnostic mode");
#endif
	return (0);
}
コード例 #29
0
ファイル: os_fs.c プロジェクト: GYGit/mongo
/*
 * __posix_open_file_cloexec --
 *	Prevent child access to file handles.
 */
static inline int
__posix_open_file_cloexec(WT_SESSION_IMPL *session, int fd, const char *name)
{
#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
	int f;

	/*
	 * Security:
	 * The application may spawn a new process, and we don't want another
	 * process to have access to our file handles. There's an obvious race
	 * between the open and this call, prefer the flag to open if available.
	 */
	if ((f = fcntl(fd, F_GETFD)) == -1 ||
	    fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1)
		WT_RET_MSG(session, __wt_errno(),
		    "%s: handle-open: fcntl", name);
	return (0);
#else
	WT_UNUSED(session);
	WT_UNUSED(fd);
	WT_UNUSED(name);
	return (0);
#endif
}
コード例 #30
0
ファイル: txn_recover.c プロジェクト: 3rf/mongo
/*
 * __recovery_setup_file --
 *	Set up the recovery slot for a file.
 */
static int
__recovery_setup_file(WT_RECOVERY *r, const char *uri, const char *config)
{
	WT_CONFIG_ITEM cval;
	WT_LSN lsn;
	uint32_t fileid;

	WT_RET(__wt_config_getones(r->session, config, "id", &cval));
	fileid = (uint32_t)cval.val;

	if (r->nfiles <= fileid) {
		WT_RET(__wt_realloc_def(
		    r->session, &r->file_alloc, fileid + 1, &r->files));
		r->nfiles = fileid + 1;
	}

	WT_RET(__wt_strdup(r->session, uri, &r->files[fileid].uri));
	WT_RET(
	    __wt_config_getones(r->session, config, "checkpoint_lsn", &cval));
	/* If there is checkpoint logged for the file, apply everything. */
	if (cval.type != WT_CONFIG_ITEM_STRUCT)
		INIT_LSN(&lsn);
	else if (sscanf(cval.str, "(%" PRIu32 ",%" PRIdMAX ")",
	    &lsn.file, (intmax_t*)&lsn.offset) != 2)
		WT_RET_MSG(r->session, EINVAL,
		    "Failed to parse checkpoint LSN '%.*s'",
		    (int)cval.len, cval.str);
	r->files[fileid].ckpt_lsn = lsn;

	WT_RET(__wt_verbose(r->session, WT_VERB_RECOVERY,
	    "Recovering %s with id %u @ (%" PRIu32 ", %" PRIu64 ")",
	    uri, fileid, lsn.file, lsn.offset));

	return (0);

}