static enum NTDB_ERROR parse(NTDB_DATA key, NTDB_DATA data,
			     NTDB_DATA *expected)
{
	NTDB_DATA add = ntdb_mkdata("another", strlen("another"));

	if (!ntdb_deq(data, *expected)) {
		return NTDB_ERR_EINVAL;
	}

	/* These should all fail.*/
	if (!xfail(ntdb_store(ntdb, add, add, NTDB_INSERT))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_append(ntdb, key, add))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_delete(ntdb, key))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_transaction_start(ntdb))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_chainlock(ntdb, key))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_lockall(ntdb))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_wipe_all(ntdb))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	if (!xfail(ntdb_repack(ntdb))) {
		return NTDB_ERR_EINVAL;
	}
	tap_log_messages--;

	/* Access the record one more time. */
	if (!ntdb_deq(data, *expected)) {
		return NTDB_ERR_EINVAL;
	}

	return NTDB_SUCCESS;
}
Пример #2
0
static NTSTATUS db_ntdb_transaction_start_nonblock(struct db_context *db)
{
	union ntdb_attribute orig;
	enum NTDB_ERROR ecode;
	struct db_ntdb_ctx *db_ctx =
		talloc_get_type_abort(db->private_data, struct db_ntdb_ctx);

	ecode = enable_nonblock(db_ctx->ntdb, &orig);
	if (!ecode) {
		ecode = ntdb_transaction_start(db_ctx->ntdb);
		disable_nonblock(db_ctx->ntdb);
	}
	return map_nt_error_from_ntdb(ecode);
}
Пример #3
0
_PUBLIC_ enum NTDB_ERROR ntdb_repack(struct ntdb_context *ntdb)
{
	struct ntdb_context *tmp_db;
	struct traverse_state state;

	state.error = ntdb_transaction_start(ntdb);
	if (state.error != NTDB_SUCCESS) {
		return state.error;
	}

	tmp_db = ntdb_open("tmpdb", NTDB_INTERNAL, O_RDWR|O_CREAT, 0, NULL);
	if (tmp_db == NULL) {
		state.error = ntdb_logerr(ntdb, NTDB_ERR_OOM, NTDB_LOG_ERROR,
					 __location__
					 " Failed to create tmp_db");
		ntdb_transaction_cancel(ntdb);
		return state.error;
	}

	state.dest_db = tmp_db;
	if (ntdb_traverse(ntdb, repack_traverse, &state) < 0) {
		goto fail;
	}

	state.error = ntdb_wipe_all(ntdb);
	if (state.error != NTDB_SUCCESS) {
		goto fail;
	}

	state.dest_db = ntdb;
	if (ntdb_traverse(tmp_db, repack_traverse, &state) < 0) {
		goto fail;
	}

	ntdb_close(tmp_db);
	return ntdb_transaction_commit(ntdb);

fail:
	ntdb_transaction_cancel(ntdb);
	ntdb_close(tmp_db);
	return state.error;
}
int main(int argc, char *argv[])
{
	const int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
	int i;
	struct ntdb_context *ntdb;
	NTDB_DATA key, data;

	plan_tests(sizeof(flags)/sizeof(flags[0]) * 5);
	agent = prepare_external_agent();
	if (!agent)
		err(1, "preparing agent");

	unlock_callback = after_unlock;
	for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) {
		diag("Test with %s and %s\n",
		     (flags[i] & NTDB_CONVERT) ? "CONVERT" : "DEFAULT",
		     (flags[i] & NTDB_NOMMAP) ? "no mmap" : "mmap");
		unlink(TEST_DBNAME);
		ntdb = ntdb_open(TEST_DBNAME, flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);

		opened = true;
		ok1(ntdb_transaction_start(ntdb) == 0);
		key = ntdb_mkdata("hi", strlen("hi"));
		data = ntdb_mkdata("world", strlen("world"));

		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
		ok1(ntdb_transaction_commit(ntdb) == 0);
		ok(!errors, "We had %u open errors", errors);

		opened = false;
		ntdb_close(ntdb);
	}

	return exit_status();
}
Пример #5
0
static int db_ntdb_transaction_start(struct db_context *db)
{
	struct db_ntdb_ctx *db_ctx =
		talloc_get_type_abort(db->private_data, struct db_ntdb_ctx);
	return ntdb_transaction_start(db_ctx->ntdb) == NTDB_SUCCESS ? 0 : -1;
}
int main(int argc, char *argv[])
{
	unsigned int i;
	struct ntdb_context *ntdb;
	int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
	NTDB_DATA key = ntdb_mkdata("key", 3);
	NTDB_DATA data = ntdb_mkdata("data", 4);

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 14);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		int status;

		tap_log_messages = 0;

		ntdb = ntdb_open("run-fork-test.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		if (!ok1(ntdb))
			continue;

		/* Put a record in here. */
		ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_SUCCESS);

		ok1(ntdb_chainlock(ntdb, key) == NTDB_SUCCESS);
		if (fork() == 0) {
			/* We expect this to fail. */
			if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK)
				return 1;

			if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK)
				return 1;

			if (tap_log_messages != 2)
				return 2;

			/* Child can do this without any complaints. */
			ntdb_chainunlock(ntdb, key);
			if (tap_log_messages != 2)
				return 3;
			ntdb_close(ntdb);
			if (tap_log_messages != 2)
				return 4;
			return 0;
		}
		wait(&status);
		ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0);
		ntdb_chainunlock(ntdb, key);

		ok1(ntdb_lockall(ntdb) == NTDB_SUCCESS);
		if (fork() == 0) {
			/* We expect this to fail. */
			if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK)
				return 1;

			if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK)
				return 1;

			if (tap_log_messages != 2)
				return 2;

			/* Child can do this without any complaints. */
			ntdb_unlockall(ntdb);
			if (tap_log_messages != 2)
				return 3;
			ntdb_close(ntdb);
			if (tap_log_messages != 2)
				return 4;
			return 0;
		}
		wait(&status);
		ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0);
		ntdb_unlockall(ntdb);

		ok1(ntdb_lockall_read(ntdb) == NTDB_SUCCESS);
		if (fork() == 0) {
			/* We expect this to fail. */
			/* This would always fail anyway... */
			if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK)
				return 1;

			if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK)
				return 1;

			if (tap_log_messages != 2)
				return 2;

			/* Child can do this without any complaints. */
			ntdb_unlockall_read(ntdb);
			if (tap_log_messages != 2)
				return 3;
			ntdb_close(ntdb);
			if (tap_log_messages != 2)
				return 4;
			return 0;
		}
		wait(&status);
		ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0);
		ntdb_unlockall_read(ntdb);

		ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS);
		/* If transactions is empty, noop "commit" succeeds. */
		ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS);
		if (fork() == 0) {
			int last_log_messages;

			/* We expect this to fail. */
			if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK)
				return 1;

			if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK)
				return 1;

			if (tap_log_messages != 2)
				return 2;

			if (ntdb_transaction_prepare_commit(ntdb)
			    != NTDB_ERR_LOCK)
				return 3;
			if (tap_log_messages == 2)
				return 4;

			last_log_messages = tap_log_messages;
			/* Child can do this without any complaints. */
			ntdb_transaction_cancel(ntdb);
			if (tap_log_messages != last_log_messages)
				return 4;
			ntdb_close(ntdb);
			if (tap_log_messages != last_log_messages)
				return 4;
			return 0;
		}
		wait(&status);
		ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0);
		ntdb_transaction_cancel(ntdb);

		ok1(ntdb_parse_record(ntdb, key, fork_in_parse, ntdb)
		    == NTDB_SUCCESS);
		ntdb_close(ntdb);
		if (am_child) {
			/* Child can return from parse without complaints. */
			if (tap_log_messages != 2)
				exit(3);
			exit(0);
		}
		ok1(tap_log_messages == 0);
	}
	return exit_status();
}
int main(int argc, char *argv[])
{
	unsigned int i;
	struct ntdb_context *ntdb;
	NTDB_DATA key = ntdb_mkdata("key", 3);
	NTDB_DATA data = ntdb_mkdata("data", 4);
	int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 48);

	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		/* RW -> R0 */
		ntdb = ntdb_open("run-92-get-set-readonly.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);
		ok1(!(ntdb_get_flags(ntdb) & NTDB_RDONLY));

		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_SUCCESS);

		ntdb_add_flag(ntdb, NTDB_RDONLY);
		ok1(ntdb_get_flags(ntdb) & NTDB_RDONLY);

		/* Can't store, append, delete. */
		ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 1);
		ok1(ntdb_append(ntdb, key, data) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 2);
		ok1(ntdb_delete(ntdb, key) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 3);

		/* Can't start a transaction, or any write lock. */
		ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 4);
		ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 5);
		ok1(ntdb_lockall(ntdb) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 6);
		ok1(ntdb_wipe_all(ntdb) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 7);

		/* Back to RW. */
		ntdb_remove_flag(ntdb, NTDB_RDONLY);
		ok1(!(ntdb_get_flags(ntdb) & NTDB_RDONLY));

		ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == NTDB_SUCCESS);
		ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS);
		ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS);

		ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS);
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_SUCCESS);
		ok1(ntdb_transaction_commit(ntdb) == NTDB_SUCCESS);

		ok1(ntdb_chainlock(ntdb, key) == NTDB_SUCCESS);
		ntdb_chainunlock(ntdb, key);
		ok1(ntdb_lockall(ntdb) == NTDB_SUCCESS);
		ntdb_unlockall(ntdb);
		ok1(ntdb_wipe_all(ntdb) == NTDB_SUCCESS);
		ok1(tap_log_messages == 7);

		ntdb_close(ntdb);

		/* R0 -> RW */
		ntdb = ntdb_open("run-92-get-set-readonly.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDONLY, 0600, &tap_log_attr);
		ok1(ntdb);
		ok1(ntdb_get_flags(ntdb) & NTDB_RDONLY);

		/* Can't store, append, delete. */
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 8);
		ok1(ntdb_append(ntdb, key, data) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 9);
		ok1(ntdb_delete(ntdb, key) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 10);

		/* Can't start a transaction, or any write lock. */
		ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 11);
		ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 12);
		ok1(ntdb_lockall(ntdb) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 13);
		ok1(ntdb_wipe_all(ntdb) == NTDB_ERR_RDONLY);
		ok1(tap_log_messages == 14);

		/* Can't remove NTDB_RDONLY since we opened with O_RDONLY */
		ntdb_remove_flag(ntdb, NTDB_RDONLY);
		ok1(tap_log_messages == 15);
		ok1(ntdb_get_flags(ntdb) & NTDB_RDONLY);
		ntdb_close(ntdb);

		ok1(tap_log_messages == 15);
		tap_log_messages = 0;
	}
	return exit_status();
}
Пример #8
0
int main(int argc, char *argv[])
{
	unsigned int i, j, num = 1000, stage = 0, stopat = -1;
	int flags = NTDB_DEFAULT;
	bool transaction = false, summary = false;
	NTDB_DATA key, data;
	struct ntdb_context *ntdb;
	struct timeval start, stop;
	union ntdb_attribute seed, log;
	bool do_stats = false;
	enum NTDB_ERROR ecode;

	/* Try to keep benchmarks even. */
	seed.base.attr = NTDB_ATTRIBUTE_SEED;
	seed.base.next = NULL;
	seed.seed.seed = 0;

	log.base.attr = NTDB_ATTRIBUTE_LOG;
	log.base.next = &seed;
	log.log.fn = ntdb_log;

	if (argv[1] && strcmp(argv[1], "--internal") == 0) {
		flags = NTDB_INTERNAL;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--transaction") == 0) {
		transaction = true;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--no-sync") == 0) {
		flags |= NTDB_NOSYNC;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--summary") == 0) {
		summary = true;
		argc--;
		argv++;
	}
	if (argv[1] && strcmp(argv[1], "--stats") == 0) {
		do_stats = true;
		argc--;
		argv++;
	}

	ntdb = ntdb_open("/tmp/speed.ntdb", flags, O_RDWR|O_CREAT|O_TRUNC,
		       0600, &log);
	if (!ntdb)
		err(1, "Opening /tmp/speed.ntdb");

	key.dptr = (void *)&i;
	key.dsize = sizeof(i);
	data = key;

	if (argv[1]) {
		num = atoi(argv[1]);
		argv++;
		argc--;
	}

	if (argv[1]) {
		stopat = atoi(argv[1]);
		argv++;
		argc--;
	}

	/* Add 1000 records. */
	printf("Adding %u records: ", num); fflush(stdout);
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++)
		if ((ecode = ntdb_store(ntdb, key, data, NTDB_INSERT)) != 0)
			errx(1, "Inserting key %u in ntdb: %s",
			     i, ntdb_errorstr(ecode));
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());

	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);

	if (++stage == stopat)
		exit(0);

	/* Finding 1000 records. */
	printf("Finding %u records: ", num); fflush(stdout);
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++) {
		NTDB_DATA dbuf;
		if ((ecode = ntdb_fetch(ntdb, key, &dbuf)) != NTDB_SUCCESS
		    || *(int *)dbuf.dptr != i) {
			errx(1, "Fetching key %u in ntdb gave %u",
			     i, ecode ? ecode : *(int *)dbuf.dptr);
		}
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Missing 1000 records. */
	printf("Missing %u records: ", num); fflush(stdout);
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (i = num; i < num*2; i++) {
		NTDB_DATA dbuf;
		ecode = ntdb_fetch(ntdb, key, &dbuf);
		if (ecode != NTDB_ERR_NOEXIST)
			errx(1, "Fetching key %u in ntdb gave %s",
			     i, ntdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Traverse 1000 records. */
	printf("Traversing %u records: ", num); fflush(stdout);
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	i = 0;
	gettimeofday(&start, NULL);
	if (ntdb_traverse(ntdb, count_record, &i) != num)
		errx(1, "Traverse returned wrong number of records");
	if (i != (num - 1) * (num / 2))
		errx(1, "Traverse tallied to %u", i);
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Delete 1000 records (not in order). */
	printf("Deleting %u records: ", num); fflush(stdout);
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 100003) % num;
		if ((ecode = ntdb_delete(ntdb, key)) != NTDB_SUCCESS)
			errx(1, "Deleting key %u in ntdb: %s",
			     i, ntdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Re-add 1000 records (not in order). */
	printf("Re-adding %u records: ", num); fflush(stdout);
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 100003) % num;
		if ((ecode = ntdb_store(ntdb, key, data, NTDB_INSERT)) != 0)
			errx(1, "Inserting key %u in ntdb: %s",
			     i, ntdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	/* Append 1000 records. */
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	printf("Appending %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (i = 0; i < num; i++)
		if ((ecode = ntdb_append(ntdb, key, data)) != NTDB_SUCCESS)
			errx(1, "Appending key %u in ntdb: %s",
			     i, ntdb_errorstr(ecode));
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());
	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (++stage == stopat)
		exit(0);

	/* Churn 1000 records: not in order! */
	if (transaction && (ecode = ntdb_transaction_start(ntdb)))
		errx(1, "starting transaction: %s", ntdb_errorstr(ecode));
	printf("Churning %u records: ", num); fflush(stdout);
	gettimeofday(&start, NULL);
	for (j = 0; j < num; j++) {
		i = (j + 1000019) % num;
		if ((ecode = ntdb_delete(ntdb, key)) != NTDB_SUCCESS)
			errx(1, "Deleting key %u in ntdb: %s",
			     i, ntdb_errorstr(ecode));
		i += num;
		if ((ecode = ntdb_store(ntdb, key, data, NTDB_INSERT)) != 0)
			errx(1, "Inserting key %u in ntdb: %s",
			     i, ntdb_errorstr(ecode));
	}
	gettimeofday(&stop, NULL);
	if (transaction && (ecode = ntdb_transaction_commit(ntdb)))
		errx(1, "committing transaction: %s", ntdb_errorstr(ecode));
	printf(" %zu ns (%zu bytes)\n",
	       normalize(&start, &stop, num), file_size());

	if (ntdb_check(ntdb, NULL, NULL))
		errx(1, "ntdb_check failed!");
	if (summary) {
		char *sumstr = NULL;
		ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr);
		printf("%s\n", sumstr);
		free(sumstr);
	}
	if (do_stats)
		dump_and_clear_stats(&ntdb, flags, &log);
	if (++stage == stopat)
		exit(0);

	return 0;
}
Пример #9
0
static enum agent_return do_operation(enum operation op, const char *name)
{
	NTDB_DATA k, d;
	enum agent_return ret;
	NTDB_DATA data;
	enum NTDB_ERROR ecode;
	union ntdb_attribute cif;
	const char *eq;

	if (op != OPEN && op != OPEN_WITH_HOOK && !ntdb) {
		diag("external: No ntdb open!");
		return OTHER_FAILURE;
	}

	diag("external: %s", operation_name(op));

	eq = strchr(name, '=');
	if (eq) {
		k = ntdb_mkdata(name, eq - name);
		d = ntdb_mkdata(eq + 1, strlen(eq+1));
	} else {
		k = ntdb_mkdata(name, strlen(name));
		d.dsize = 0;
		d.dptr = NULL;
	}

	locking_would_block = 0;
	switch (op) {
	case OPEN:
		if (ntdb) {
			diag("Already have ntdb %s open", ntdb_name(ntdb));
			return OTHER_FAILURE;
		}
		ntdb = ntdb_open(name, MAYBE_NOSYNC, O_RDWR, 0, &tap_log_attr);
		if (!ntdb) {
			if (!locking_would_block)
				diag("Opening ntdb gave %s", strerror(errno));
			forget_locking();
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case OPEN_WITH_HOOK:
		if (ntdb) {
			diag("Already have ntdb %s open", ntdb_name(ntdb));
			return OTHER_FAILURE;
		}
		cif.openhook.base.attr = NTDB_ATTRIBUTE_OPENHOOK;
		cif.openhook.base.next = &tap_log_attr;
		cif.openhook.fn = clear_if_first;
		ntdb = ntdb_open(name, MAYBE_NOSYNC, O_RDWR, 0, &cif);
		if (!ntdb) {
			if (!locking_would_block)
				diag("Opening ntdb gave %s", strerror(errno));
			forget_locking();
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case FETCH:
		ecode = ntdb_fetch(ntdb, k, &data);
		if (ecode == NTDB_ERR_NOEXIST) {
			ret = FAILED;
		} else if (ecode < 0) {
			ret = OTHER_FAILURE;
		} else if (!ntdb_deq(data, d)) {
			ret = OTHER_FAILURE;
			external_agent_free(data.dptr);
		} else {
			ret = SUCCESS;
			external_agent_free(data.dptr);
		}
		break;
	case STORE:
		ret = ntdb_store(ntdb, k, d, 0) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_START:
		ret = ntdb_transaction_start(ntdb) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_COMMIT:
		ret = ntdb_transaction_commit(ntdb)==0 ? SUCCESS : OTHER_FAILURE;
		break;
	case NEEDS_RECOVERY:
		ret = external_agent_needs_rec(ntdb);
		break;
	case CHECK:
		ret = ntdb_check(ntdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case CLOSE:
		ret = ntdb_close(ntdb) == 0 ? SUCCESS : OTHER_FAILURE;
		ntdb = NULL;
		break;
	case SEND_SIGNAL:
		/* We do this async */
		ret = SUCCESS;
		break;
	default:
		ret = OTHER_FAILURE;
	}

	if (locking_would_block)
		ret = WOULD_HAVE_BLOCKED;

	return ret;
}
Пример #10
0
static int do_command(void)
{
	COMMAND_TABLE *ctp = cmd_table;
	enum commands mycmd = CMD_HELP;
	int cmd_len;

	if (cmdname && strlen(cmdname) == 0) {
		mycmd = CMD_NEXT;
	} else {
		while (ctp->name) {
			cmd_len = strlen(ctp->name);
			if (strncmp(ctp->name,cmdname,cmd_len) == 0) {
				mycmd = ctp->cmd;
				break;
			}
			ctp++;
		}
	}

	switch (mycmd) {
	case CMD_CREATE_NTDB:
		bIterate = 0;
		create_ntdb(arg1);
		return 0;
	case CMD_OPEN_NTDB:
		bIterate = 0;
		open_ntdb(arg1);
		return 0;
	case CMD_SYSTEM:
		/* Shell command */
		if (system(arg1) == -1) {
			terror(NTDB_SUCCESS, "system() call failed\n");
		}
		return 0;
	case CMD_QUIT:
		return 1;
	default:
		/* all the rest require a open database */
		if (!ntdb) {
			bIterate = 0;
			terror(NTDB_SUCCESS, "database not open");
			help();
			return 0;
		}
		switch (mycmd) {
		case CMD_TRANSACTION_START:
			bIterate = 0;
			ntdb_transaction_start(ntdb);
			return 0;
		case CMD_TRANSACTION_COMMIT:
			bIterate = 0;
			ntdb_transaction_commit(ntdb);
			return 0;
		case CMD_TRANSACTION_CANCEL:
			bIterate = 0;
			ntdb_transaction_cancel(ntdb);
			return 0;
		case CMD_ERASE:
			bIterate = 0;
			ntdb_traverse(ntdb, do_delete_fn, NULL);
			return 0;
		case CMD_DUMP:
			bIterate = 0;
			ntdb_traverse(ntdb, print_rec, NULL);
			return 0;
		case CMD_INSERT:
			bIterate = 0;
			insert_ntdb(arg1, arg1len,arg2,arg2len);
			return 0;
		case CMD_MOVE:
			bIterate = 0;
			move_rec(arg1,arg1len,arg2);
			return 0;
		case CMD_STORE:
			bIterate = 0;
			store_ntdb(arg1,arg1len,arg2,arg2len);
			return 0;
		case CMD_SHOW:
			bIterate = 0;
			show_ntdb(arg1, arg1len);
			return 0;
		case CMD_KEYS:
			ntdb_traverse(ntdb, print_key, NULL);
			return 0;
		case CMD_HEXKEYS:
			ntdb_traverse(ntdb, print_hexkey, NULL);
			return 0;
		case CMD_DELETE:
			bIterate = 0;
			delete_ntdb(arg1,arg1len);
			return 0;
#if 0
		case CMD_LIST_HASH_FREE:
			ntdb_dump_all(ntdb);
			return 0;
		case CMD_LIST_FREE:
			ntdb_printfreelist(ntdb);
			return 0;
#endif
		case CMD_INFO:
			info_ntdb();
			return 0;
		case CMD_SPEED:
			speed_ntdb(arg1);
			return 0;
		case CMD_MMAP:
			toggle_mmap();
			return 0;
		case CMD_FIRST:
			bIterate = 1;
			first_record(ntdb, &iterate_kbuf);
			return 0;
		case CMD_NEXT:
			if (bIterate)
				next_record(ntdb, &iterate_kbuf);
			return 0;
		case CMD_CHECK:
			check_db(ntdb);
			return 0;
		case CMD_HELP:
			help();
			return 0;
		case CMD_CREATE_NTDB:
		case CMD_OPEN_NTDB:
		case CMD_SYSTEM:
		case CMD_QUIT:
			/*
			 * unhandled commands.  cases included here to avoid compiler
			 * warnings.
			 */
			return 0;
		}
	}

	return 0;
}
Пример #11
0
static void speed_ntdb(const char *tlimit)
{
	unsigned timelimit = tlimit?atoi(tlimit):0;
	double t;
	int ops;
	if (timelimit == 0) timelimit = 5;

	ops = 0;
	printf("Testing store speed for %u seconds\n", timelimit);
	_start_timer();
	do {
		long int r = random();
		NTDB_DATA key, dbuf;
		key = ntdb_mkdata("store test", strlen("store test"));
		dbuf.dptr = (unsigned char *)&r;
		dbuf.dsize = sizeof(r);
		ntdb_store(ntdb, key, dbuf, NTDB_REPLACE);
		t = _end_timer();
		ops++;
	} while (t < timelimit);
	printf("%10.3f ops/sec\n", ops/t);

	ops = 0;
	printf("Testing fetch speed for %u seconds\n", timelimit);
	_start_timer();
	do {
		long int r = random();
		NTDB_DATA key, dbuf;
		key = ntdb_mkdata("store test", strlen("store test"));
		dbuf.dptr = (unsigned char *)&r;
		dbuf.dsize = sizeof(r);
		ntdb_fetch(ntdb, key, &dbuf);
		t = _end_timer();
		ops++;
	} while (t < timelimit);
	printf("%10.3f ops/sec\n", ops/t);

	ops = 0;
	printf("Testing transaction speed for %u seconds\n", timelimit);
	_start_timer();
	do {
		long int r = random();
		NTDB_DATA key, dbuf;
		key = ntdb_mkdata("transaction test", strlen("transaction test"));
		dbuf.dptr = (unsigned char *)&r;
		dbuf.dsize = sizeof(r);
		ntdb_transaction_start(ntdb);
		ntdb_store(ntdb, key, dbuf, NTDB_REPLACE);
		ntdb_transaction_commit(ntdb);
		t = _end_timer();
		ops++;
	} while (t < timelimit);
	printf("%10.3f ops/sec\n", ops/t);

	ops = 0;
	printf("Testing traverse speed for %u seconds\n", timelimit);
	_start_timer();
	do {
		ntdb_traverse(ntdb, traverse_fn, NULL);
		t = _end_timer();
		ops++;
	} while (t < timelimit);
	printf("%10.3f ops/sec\n", ops/t);
}
Пример #12
0
int main(int argc, char *argv[])
{
	unsigned int i;
	struct ntdb_context *ntdb;
	unsigned char *buffer;
	int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
	NTDB_DATA key = ntdb_mkdata("key", 3);
	NTDB_DATA data;

	buffer = malloc(1000);
	for (i = 0; i < 1000; i++)
		buffer[i] = i;

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 20 + 1);

	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("run-55-transaction.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);
		if (!ntdb)
			continue;

		ok1(ntdb_transaction_start(ntdb) == 0);
		data.dptr = buffer;
		data.dsize = 1000;
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
		ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS);
		ok1(data.dsize == 1000);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);

		/* Cancelling a transaction means no store */
		ntdb_transaction_cancel(ntdb);
		ok1(ntdb->file->allrecord_lock.count == 0
		    && ntdb->file->num_lockrecs == 0);
		ok1(ntdb_check(ntdb, NULL, NULL) == 0);
		ok1(ntdb_fetch(ntdb, key, &data) == NTDB_ERR_NOEXIST);

		/* Commit the transaction. */
		ok1(ntdb_transaction_start(ntdb) == 0);
		data.dptr = buffer;
		data.dsize = 1000;
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
		ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS);
		ok1(data.dsize == 1000);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);
		ok1(ntdb_transaction_commit(ntdb) == 0);
		ok1(ntdb->file->allrecord_lock.count == 0
		    && ntdb->file->num_lockrecs == 0);
		ok1(ntdb_check(ntdb, NULL, NULL) == 0);
		ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS);
		ok1(data.dsize == 1000);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);

		ntdb_close(ntdb);
	}

	ok1(tap_log_messages == 0);
	free(buffer);
	return exit_status();
}
Пример #13
0
int main(int argc, char *argv[])
{
	unsigned int i, seq;
	struct ntdb_context *ntdb;
	NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */
	NTDB_DATA key = ntdb_mkdata("key", 3);
	NTDB_DATA data = ntdb_mkdata("data", 4);
	int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
			NTDB_NOMMAP|NTDB_CONVERT };

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 15 + 4 * 13);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("api-81-seqnum.ntdb",
				 flags[i]|NTDB_SEQNUM|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		if (!ok1(ntdb))
			continue;

		seq = 0;
		ok1(ntdb_get_seqnum(ntdb) == seq);
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
		ok1(ntdb_get_seqnum(ntdb) == ++seq);
		/* Fetch doesn't change seqnum */
		if (ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS))
			free(d.dptr);
		ok1(ntdb_get_seqnum(ntdb) == seq);
		ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS);
		ok1(ntdb_get_seqnum(ntdb) == ++seq);

		ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS);
		ok1(ntdb_get_seqnum(ntdb) == ++seq);
		/* Empty append works */
		ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS);
		ok1(ntdb_get_seqnum(ntdb) == ++seq);

		ok1(ntdb_wipe_all(ntdb) == NTDB_SUCCESS);
		ok1(ntdb_get_seqnum(ntdb) == ++seq);

		if (!(flags[i] & NTDB_INTERNAL)) {
			ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS);
			ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
			ok1(ntdb_get_seqnum(ntdb) == ++seq);
			ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS);
			ok1(ntdb_get_seqnum(ntdb) == ++seq);
			ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS);
			ok1(ntdb_get_seqnum(ntdb) == ++seq);
			ok1(ntdb_transaction_commit(ntdb) == NTDB_SUCCESS);
			ok1(ntdb_get_seqnum(ntdb) == seq);

			ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS);
			ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
			ok1(ntdb_get_seqnum(ntdb) == seq + 1);
			ntdb_transaction_cancel(ntdb);
			ok1(ntdb_get_seqnum(ntdb) == seq);
		}
		ntdb_close(ntdb);
		ok1(tap_log_messages == 0);
	}
	return exit_status();
}