예제 #1
0
파일: file.c 프로젝트: DINKIN/mongo
void
obj_create_unique(int force)
{
	WT_SESSION *session;
	int ret;
	char new_uri[64];

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "conn.session");

	/* Generate a unique object name. */
	if ((ret = pthread_rwlock_wrlock(&single)) != 0)
		testutil_die(ret, "pthread_rwlock_wrlock single");
	testutil_check(__wt_snprintf(
	    new_uri, sizeof(new_uri), "%s.%u", uri, ++uid));
	if ((ret = pthread_rwlock_unlock(&single)) != 0)
		testutil_die(ret, "pthread_rwlock_unlock single");

	if ((ret = session->create(session, new_uri, config)) != 0)
		testutil_die(ret, "session.create");

	__wt_yield();
	while ((ret = session->drop(
	    session, new_uri, force ? "force" : NULL)) != 0)
		if (ret != EBUSY)
			testutil_die(ret, "session.drop: %s", new_uri);

	if ((ret = session->close(session, NULL)) != 0)
		testutil_die(ret, "session.close");
}
예제 #2
0
파일: thread.c 프로젝트: ajdavis/mongo
/*
 * Create a guaranteed unique table and open and close a bulk cursor on it.
 */
void
op_bulk_unique(void *arg)
{
	TEST_OPTS *opts;
	TEST_PER_THREAD_OPTS *args;
	WT_CURSOR *c;
	WT_RAND_STATE rnd;
	WT_SESSION *session;
	int ret;
	char new_uri[64];

	args = (TEST_PER_THREAD_OPTS *)arg;
	opts = args->testopts;
	__wt_random_init_seed(NULL, &rnd);

	testutil_check(
	    opts->conn->open_session(opts->conn, NULL, NULL, &session));

	/* Generate a unique object name. */
	testutil_check(__wt_snprintf(
	    new_uri, sizeof(new_uri), "%s.%" PRIu64,
	    opts->uri, __wt_atomic_add64(&opts->unique_id, 1)));
	testutil_check(session->create(session, new_uri, DEFAULT_TABLE_SCHEMA));

	__wt_yield();

	/*
	 * Opening a bulk cursor may have raced with a forced checkpoint
	 * which created a checkpoint of the empty file, and triggers an EINVAL.
	 */
	if ((ret = session->open_cursor(
	    session, new_uri, NULL, "bulk,checkpoint_wait=false", &c)) == 0) {
		testutil_check(c->close(c));
	} else if (ret != EINVAL && ret != EBUSY)
		testutil_die(ret,
		    "session.open_cursor bulk unique: %s", new_uri);

	while ((ret = session->drop(session, new_uri, __wt_random(&rnd) & 1 ?
	    "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0)
		if (ret != EBUSY)
			testutil_die(ret, "session.drop: %s", new_uri);
		else
			/*
			 * The EBUSY is expected when we run with
			 * checkpoint_wait set to false, so we increment the
			 * counter while in this loop to avoid false positives.
			 */
			args->thread_counter++;

	testutil_check(session->close(session, NULL));
	args->thread_counter++;
}
예제 #3
0
파일: main.c 프로젝트: ksuarz/mongo
int
main(int argc, char *argv[])
{
	int ret;
	WT_CONNECTION *conn;
	WT_SESSION *session;

	(void)argc;
	(void)argv;
	fprintf(stderr, SEPARATOR "wiredtiger_open\n");
	if ((ret = wiredtiger_open(".", NULL, "create", &conn)) != 0)
		fail(ret);

	usleep(100);
	fflush(stderr);
	fprintf(stderr, SEPARATOR "open_session\n");
	fflush(stderr);

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		fail(ret);

	usleep(100);
	fflush(stderr);
	fprintf(stderr, SEPARATOR "create\n");
	fflush(stderr);

	if ((ret = session->create(
	    session, "table:hello", "key_format=S,value_format=S")) != 0)
		fail(ret);

	usleep(100);
	fprintf(stderr, SEPARATOR "rename\n");

	if ((ret = session->rename(
	    session, "table:hello", "table:world", NULL)) != 0)
		fail(ret);

	fflush(stdout);
	fprintf(stderr, SEPARATOR "drop\n");
	fflush(stdout);

	if ((ret = session->drop(session, "table:world", NULL)) != 0)
		fail(ret);

	fprintf(stderr, SEPARATOR "WT_CONNECTION::close\n");

	if ((ret = conn->close(conn, NULL)) != 0)
		fail(ret);

	return (0);
}
예제 #4
0
파일: file.c 프로젝트: qixin/wiredtiger
void
obj_drop(void)
{
	WT_SESSION *session;
	int ret;

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		die("conn.session", ret);

	if ((ret = session->drop(session, uri, NULL)) != 0)
		if (ret != ENOENT && ret != EBUSY)
			die("session.drop", ret);

	if ((ret = session->close(session, NULL)) != 0)
		die("session.close", ret);
}
예제 #5
0
파일: file.c 프로젝트: DINKIN/mongo
void
obj_drop(int force)
{
	WT_SESSION *session;
	int ret;

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "conn.session");

	if ((ret = session->drop(session, uri, force ? "force" : NULL)) != 0)
		if (ret != ENOENT && ret != EBUSY)
			testutil_die(ret, "session.drop");

	if ((ret = session->close(session, NULL)) != 0)
		testutil_die(ret, "session.close");
}
예제 #6
0
파일: file.c 프로젝트: DINKIN/mongo
void
obj_bulk_unique(int force)
{
	WT_CURSOR *c;
	WT_SESSION *session;
	int ret;
	char new_uri[64];

	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		testutil_die(ret, "conn.session");

	/* Generate a unique object name. */
	if ((ret = pthread_rwlock_wrlock(&single)) != 0)
		testutil_die(ret, "pthread_rwlock_wrlock single");
	testutil_check(__wt_snprintf(
	    new_uri, sizeof(new_uri), "%s.%u", uri, ++uid));
	if ((ret = pthread_rwlock_unlock(&single)) != 0)
		testutil_die(ret, "pthread_rwlock_unlock single");

	if ((ret = session->create(session, new_uri, config)) != 0)
		testutil_die(ret, "session.create: %s", new_uri);

	__wt_yield();
	/*
	 * Opening a bulk cursor may have raced with a forced checkpoint
	 * which created a checkpoint of the empty file, and triggers an EINVAL
	 */
	if ((ret = session->open_cursor(
	    session, new_uri, NULL, "bulk", &c)) == 0) {
		if ((ret = c->close(c)) != 0)
			testutil_die(ret, "cursor.close");
	} else if (ret != EINVAL)
		testutil_die(ret,
		    "session.open_cursor bulk unique: %s, new_uri");

	while ((ret = session->drop(
	    session, new_uri, force ? "force" : NULL)) != 0)
		if (ret != EBUSY)
			testutil_die(ret, "session.drop: %s", new_uri);

	if ((ret = session->close(session, NULL)) != 0)
		testutil_die(ret, "session.close");
}
예제 #7
0
int setup(char *name, const char *kf, const char *vf, const char *cconfig, WT_CURSOR **cursor){
  WT_SESSION *session;
  int creating, ret;
  char tconfig[64];

  creating = (kf != NULL);

  if((ret = wiredtiger_open(NULL, NULL, "create", &conn) != 0) ||
    (ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
    return ret;

  /* If we get a configuration, create the table. */
  if(creating) {
    (void)session->drop(session, name, "force");
    snprintf(tconfig, sizeof(tconfig), "key_format=%s,value_format=%s", kf, vf);
    if ((ret = session->create(session, name, tconfig)) != 0)
      return ret;
  }

  return session->open_cursor(session, name, NULL, cconfig, cursor);
}
예제 #8
0
파일: thread.c 프로젝트: ajdavis/mongo
/*
 * Create and drop a unique guaranteed table.
 */
void
op_create_unique(void *arg)
{
	TEST_OPTS *opts;
	TEST_PER_THREAD_OPTS *args;
	WT_RAND_STATE rnd;
	WT_SESSION *session;
	int ret;
	char new_uri[64];

	args = (TEST_PER_THREAD_OPTS *)arg;
	opts = args->testopts;
	__wt_random_init_seed(NULL, &rnd);

	testutil_check(
	    opts->conn->open_session(opts->conn, NULL, NULL, &session));

	/* Generate a unique object name. */
	testutil_check(__wt_snprintf(
	    new_uri, sizeof(new_uri), "%s.%" PRIu64,
	    opts->uri, __wt_atomic_add64(&opts->unique_id, 1)));
	testutil_check(session->create(session, new_uri, DEFAULT_TABLE_SCHEMA));

	__wt_yield();
	while ((ret = session->drop(session, new_uri, __wt_random(&rnd) & 1 ?
	    "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0)
		if (ret != EBUSY)
			testutil_die(ret, "session.drop: %s", new_uri);
		else
			/*
			 * The EBUSY is expected when we run with
			 * checkpoint_wait set to false, so we increment the
			 * counter while in this loop to avoid false positives.
			 */
			args->thread_counter++;

	testutil_check(session->close(session, NULL));
	args->thread_counter++;
}
예제 #9
0
파일: thread.c 프로젝트: ajdavis/mongo
/*
 * Drop a table.
 */
void
op_drop(void *arg)
{
	TEST_OPTS *opts;
	TEST_PER_THREAD_OPTS *args;
	WT_RAND_STATE rnd;
	WT_SESSION *session;
	int ret;

	args = (TEST_PER_THREAD_OPTS *)arg;
	opts = args->testopts;
	__wt_random_init_seed(NULL, &rnd);

	testutil_check(
	    opts->conn->open_session(opts->conn, NULL, NULL, &session));

	if ((ret = session->drop(session, opts->uri, __wt_random(&rnd) & 1 ?
	    "force,checkpoint_wait=false" : "checkpoint_wait=false")) != 0)
		if (ret != ENOENT && ret != EBUSY)
			testutil_die(ret, "session.drop");

	testutil_check(session->close(session, NULL));
	args->thread_counter++;
}
예제 #10
0
파일: wts_ops.c 프로젝트: qixin/wiredtiger
static void *
ops(void *arg)
{
	TINFO *tinfo;
	WT_CONNECTION *conn;
	WT_CURSOR *cursor, *cursor_insert;
	WT_SESSION *session;
	WT_ITEM key, value;
	uint64_t cnt, keyno, sync_op, thread_ops;
	uint32_t op;
	uint8_t *keybuf, *valbuf;
	u_int np;
	int dir, insert, notfound, ret, sync_drop;
	char sync_name[64];

	conn = g.wts_conn;

	tinfo = arg;

	/* Set up the default key and value buffers. */
	memset(&key, 0, sizeof(key));
	key_gen_setup(&keybuf);
	memset(&value, 0, sizeof(value));
	val_gen_setup(&valbuf);

	/* Open a session. */
	if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
		die(ret, "connection.open_session");

	/*
	 * Open two cursors: one configured for overwriting and one configured
	 * for append if we're dealing with a column-store.
	 *
	 * The reason is when testing with existing records, we don't track if
	 * a record was deleted or not, which means we must use cursor->insert
	 * with overwriting configured.  But, in column-store files where we're
	 * testing with new, appended records, we don't want to have to specify
	 * the record number, which requires an append configuration.
	 */
	cursor = cursor_insert = NULL;
	if ((ret = session->open_cursor(session,
	    WT_TABLENAME, NULL, "overwrite", &cursor)) != 0)
		die(ret, "session.open_cursor");
	if ((g.c_file_type == FIX || g.c_file_type == VAR) &&
	    (ret = session->open_cursor(session,
	    WT_TABLENAME, NULL, "append", &cursor_insert)) != 0)
		die(ret, "session.open_cursor");

	/* Each thread does its share of the total operations. */
	thread_ops = g.c_ops / g.c_threads;

	/* Pick an operation where we'll do a sync and create the name. */
	sync_drop = 0;
	sync_op = MMRAND(1, thread_ops);
	snprintf(sync_name, sizeof(sync_name), "snapshot=thread-%d", tinfo->id);

	for (cnt = 0; cnt < thread_ops; ++cnt) {
		if (SINGLETHREADED && cnt % 100 == 0)
			track("read/write ops", 0ULL, tinfo);

		if (cnt == sync_op) {
			if (sync_drop && (int)MMRAND(1, 4) == 1) {
				if ((ret = session->drop(
				    session, WT_TABLENAME, sync_name)) != 0)
					die(ret, "session.drop: %s: %s",
					    WT_TABLENAME, sync_name);
				sync_drop = 0;
			} else {
				if ((ret = session->checkpoint(
				    session, sync_name)) != 0)
					die(ret, "session.checkpoint: %s",
					    sync_name);
				sync_drop = 1;
			}

			/*
			 * Pick the next sync operation, try for roughly five
			 * snapshot operations per thread run.
			 */
			sync_op += MMRAND(1, thread_ops) / 5;
		}

		insert = notfound = 0;

		keyno = MMRAND(1, g.rows);
		key.data = keybuf;
		value.data = valbuf;

		/*
		 * Perform some number of operations: the percentage of deletes,
		 * inserts and writes are specified, reads are the rest.  The
		 * percentages don't have to add up to 100, a high percentage
		 * of deletes will mean fewer inserts and writes.  A read
		 * operation always follows a modification to confirm it worked.
		 */
		op = (uint32_t)(wts_rand() % 100);
		if (op < g.c_delete_pct) {
			++tinfo->remove;
			switch (g.c_file_type) {
			case ROW:
				/*
				 * If deleting a non-existent record, the cursor
				 * won't be positioned, and so can't do a next.
				 */
				row_remove(cursor, &key, keyno, &notfound);
				break;
			case FIX:
			case VAR:
				col_remove(cursor, &key, keyno, &notfound);
				break;
			}
		} else if (op < g.c_delete_pct + g.c_insert_pct) {
			++tinfo->insert;
			switch (g.c_file_type) {
			case ROW:
				row_update(cursor, &key, &value, keyno, 1);
				break;
			case FIX:
			case VAR:
				/*
				 * Reset the standard cursor so it doesn't keep
				 * pages pinned.
				 */
				if ((ret = cursor->reset(cursor)) != 0)
					die(ret, "cursor.reset");
				col_insert(cursor_insert, &key, &value, &keyno);
				insert = 1;
				break;
			}
		} else if (
		    op < g.c_delete_pct + g.c_insert_pct + g.c_write_pct) {
			++tinfo->update;
			switch (g.c_file_type) {
			case ROW:
				row_update(cursor, &key, &value, keyno, 0);
				break;
			case FIX:
			case VAR:
				col_update(cursor, &key, &value, keyno);
				break;
			}
		} else {
			++tinfo->search;
			read_row(cursor, &key, keyno);
			continue;
		}

		/*
		 * If we did any operation, we've set the cursor, do a small
		 * number of next/prev cursor operations in a random direction.
		 */
		dir = (int)MMRAND(0, 1);
		for (np = 0; np < MMRAND(1, 8); ++np) {
			if (notfound)
				break;
			nextprev(
			    insert ? cursor_insert : cursor, dir, &notfound);
		}

		if (insert && (ret = cursor_insert->reset(cursor_insert)) != 0)
			die(ret, "cursor.reset");

		/* Read the value we modified to confirm the operation. */
		read_row(cursor, &key, keyno);
	}

	if ((ret = session->close(session, NULL)) != 0)
		die(ret, "session.close");

	free(keybuf);
	free(valbuf);

	tinfo->state = TINFO_COMPLETE;
	return (NULL);
}
예제 #11
0
파일: salvage.c 프로젝트: Machyne/mongo
/*
 * build --
 *	Build a row- or column-store page in a file.
 */
void
build(int ikey, int ivalue, int cnt)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM key, value;
	WT_SESSION *session;
	char config[256], kbuf[64], vbuf[64];
	int new_slvg;

	/*
	 * Disable logging: we're modifying files directly, we don't want to
	 * run recovery.
	 */
	CHECK(wiredtiger_open(
	    NULL, NULL, "create,log=(enabled=false)", &conn) == 0);
	CHECK(conn->open_session(conn, NULL, NULL, &session) == 0);
	CHECK(session->drop(session, "file:" LOAD, "force") == 0);

	switch (page_type) {
	case WT_PAGE_COL_FIX:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,value_format=7t,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_COL_VAR:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_ROW_LEAF:
		(void)snprintf(config, sizeof(config),
		    "key_format=u,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	default:
		assert(0);
	}
	CHECK(session->create(session, "file:" LOAD, config) == 0);
	CHECK(session->open_cursor(
	    session, "file:" LOAD, NULL, "bulk,append", &cursor) == 0);
	for (; cnt > 0; --cnt, ++ikey, ++ivalue) {
		switch (page_type) {			/* Build the key. */
		case WT_PAGE_COL_FIX:
		case WT_PAGE_COL_VAR:
			break;
		case WT_PAGE_ROW_LEAF:
			snprintf(kbuf, sizeof(kbuf), "%010d KEY------", ikey);
			key.data = kbuf;
			key.size = 20;
			cursor->set_key(cursor, &key);
			break;
		}

		switch (page_type) {			/* Build the value. */
		case WT_PAGE_COL_FIX:
			cursor->set_value(cursor, ivalue & 0x7f);
			break;
		case WT_PAGE_COL_VAR:
		case WT_PAGE_ROW_LEAF:
			snprintf(vbuf, sizeof(vbuf),
			    "%010d VALUE----", value_unique ? ivalue : 37);
			value.data = vbuf;
			value.size = 20;
			cursor->set_value(cursor, &value);
		}
		CHECK(cursor->insert(cursor) == 0);
	}

	/*
	 * The first time through this routine we create the salvage file and
	 * then remove it (all we want is the appropriate schema entry, we're
	 * creating the salvage file itself by hand).
	 */
	new_slvg = !file_exists(SLVG);
	if (new_slvg) {
		CHECK(session->drop(session, "file:" SLVG, "force") == 0);
		CHECK(session->create(session, "file:" SLVG, config) == 0);
	}
	CHECK(conn->close(conn, 0) == 0);
	if (new_slvg)
		(void)remove(SLVG);
}
예제 #12
0
파일: salvage.c 프로젝트: qixin/wiredtiger
/*
 * build --
 *	Build a row- or column-store page in a file.
 */
void
build(int ikey, int ivalue, int cnt)
{
	WT_CONNECTION *conn;
	WT_CURSOR *cursor;
	WT_ITEM key, value;
	WT_SESSION *session;
	char config[256], kbuf[64], vbuf[64];
	int new_slvg;

	assert(wiredtiger_open(NULL, NULL, "create", &conn) == 0);
	assert(conn->open_session(conn, NULL, NULL, &session) == 0);
	assert(session->drop(session, "file:" LOAD, "force") == 0);

	switch (page_type) {
	case WT_PAGE_COL_FIX:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,value_format=7t,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_COL_VAR:
		(void)snprintf(config, sizeof(config),
		    "key_format=r,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	case WT_PAGE_ROW_LEAF:
		(void)snprintf(config, sizeof(config),
		    "key_format=u,"
		    "allocation_size=%d,"
		    "internal_page_max=%d,internal_item_max=%d,"
		    "leaf_page_max=%d,leaf_item_max=%d",
		    PSIZE, PSIZE, OSIZE, PSIZE, OSIZE);
		break;
	default:
		assert(0);
	}
	assert(session->create(session, "file:" LOAD, config) == 0);
	assert(session->open_cursor(
	    session, "file:" LOAD, NULL, "bulk", &cursor) == 0);
	for (; cnt > 0; --cnt, ++ikey, ++ivalue) {
		switch (page_type) {			/* Build the key. */
		case WT_PAGE_COL_FIX:
		case WT_PAGE_COL_VAR:
			break;
		case WT_PAGE_ROW_LEAF:
			snprintf(kbuf, sizeof(kbuf), "%010d KEY------", ikey);
			key.data = kbuf;
			key.size = 20;
			cursor->set_key(cursor, &key);
			break;
		}

		switch (page_type) {			/* Build the value. */
		case WT_PAGE_COL_FIX:
			cursor->set_value(cursor, ivalue & 0x7f);
			break;
		case WT_PAGE_COL_VAR:
		case WT_PAGE_ROW_LEAF:
			snprintf(vbuf, sizeof(vbuf),
			    "%010d VALUE----", value_unique ? ivalue : 37);
			value.data = vbuf;
			value.size = 20;
			cursor->set_value(cursor, &value);
		}
		assert(cursor->insert(cursor) == 0);
	}

	/*
	 * The first time through this routine we put a matching configuration
	 * in for the salvage file.
	 */
	new_slvg = (access(SLVG, F_OK) != 0);
	if (new_slvg) {
		assert(session->drop(session, "file:" SLVG, "force") == 0);
		assert(session->create(session, "file:" SLVG, config) == 0);
	}

	assert(conn->close(conn, 0) == 0);

	/*
	 * We created the salvage file above, but all we want is the schema,
	 * we're creating the salvage file by hand.
	 */
	if (new_slvg)
		(void)remove(SLVG);
}
예제 #13
0
/*
 * Regularly create, open a cursor and drop a table.
 * Measure how long each step takes, and flag an error if it exceeds the
 * configured maximum.
 */
static void *
cycle_idle_tables(void *arg)
{
	struct timespec start, stop;
	CONFIG *cfg;
	WT_SESSION *session;
	WT_CURSOR *cursor;
	int cycle_count, ret;
	char uri[512];

	cfg = (CONFIG *)arg;
	cycle_count = 0;

	if ((ret = cfg->conn->open_session(
	    cfg->conn, NULL, cfg->sess_config, &session)) != 0) {
		lprintf(cfg, ret, 0,
		    "Error opening a session on %s", cfg->home);
		return (NULL);
	}

	for (cycle_count = 0; cfg->idle_cycle_run; ++cycle_count) {
		snprintf(uri, 512, "%s_cycle%07d", cfg->uris[0], cycle_count);
		/* Don't busy cycle in this loop. */
		__wt_sleep(1, 0);

		/* Setup a start timer. */
		if ((ret = __wt_epoch(NULL, &start)) != 0) {
			lprintf(cfg, ret, 0,
			     "Get time failed in cycle_idle_tables.");
			cfg->error = ret;
			return (NULL);
		}

		/* Create a table. */
		if ((ret = session->create(
		    session, uri, cfg->table_config)) != 0) {
			if (ret == EBUSY)
				continue;
			lprintf(cfg, ret, 0,
			     "Table create failed in cycle_idle_tables.");
			cfg->error = ret;
			return (NULL);
		}
		if (check_timing(cfg, "create", start, &stop) != 0)
			return (NULL);
		start = stop;

		/* Open and close cursor. */
		if ((ret = session->open_cursor(
		    session, uri, NULL, NULL, &cursor)) != 0) {
			lprintf(cfg, ret, 0,
			     "Cursor open failed in cycle_idle_tables.");
			cfg->error = ret;
			return (NULL);
		}
		if ((ret = cursor->close(cursor)) != 0) {
			lprintf(cfg, ret, 0,
			     "Cursor close failed in cycle_idle_tables.");
			cfg->error = ret;
			return (NULL);
		}
		if (check_timing(cfg, "cursor", start, &stop) != 0)
			return (NULL);
		start = stop;

		/*
		 * Drop the table. Keep retrying on EBUSY failure - it is an
		 * expected return when checkpoints are happening.
		 */
		while ((ret = session->drop(
		    session, uri, "force,checkpoint_wait=false")) == EBUSY)
			__wt_sleep(1, 0);

		if (ret != 0 && ret != EBUSY) {
			lprintf(cfg, ret, 0,
			     "Table drop failed in cycle_idle_tables.");
			cfg->error = ret;
			return (NULL);
		}
		if (check_timing(cfg, "drop", start, &stop) != 0)
			return (NULL);
	}

	return (NULL);
}