예제 #1
0
파일: ntdbdump.c 프로젝트: AIdrifter/samba
static int dump_ntdb(const char *fname, const char *keyname)
{
	struct ntdb_context *ntdb;
	NTDB_DATA key, value;

	ntdb = ntdb_open(fname, 0, O_RDONLY, 0, NULL);
	if (!ntdb) {
		printf("Failed to open %s\n", fname);
		return 1;
	}

	if (!keyname) {
		ntdb_traverse(ntdb, traverse_fn, NULL);
	} else {
		key = ntdb_mkdata(keyname, strlen(keyname));
		if (ntdb_fetch(ntdb, key, &value) != 0) {
			return 1;
		} else {
			print_data(value);
			free(value.dptr);
		}
	}

	return 0;
}
예제 #2
0
static void first_record(struct ntdb_context *the_ntdb, NTDB_DATA *pkey)
{
	NTDB_DATA dbuf;
	enum NTDB_ERROR ecode;
	ecode = ntdb_firstkey(the_ntdb, pkey);
	if (!ecode)
		ecode = ntdb_fetch(the_ntdb, *pkey, &dbuf);
	if (ecode) terror(ecode, "fetch failed");
	else {
		print_rec(the_ntdb, *pkey, dbuf, NULL);
	}
}
예제 #3
0
int main(int argc, char *argv[])
{
	unsigned int i, j;
	union ntdb_attribute alloc_attr;
	struct ntdb_context *ntdb;
	int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
			NTDB_NOMMAP|NTDB_CONVERT };
	NTDB_DATA key = { (unsigned char *)&j, sizeof(j) };
	NTDB_DATA data = { (unsigned char *)&j, sizeof(j) };

	alloc_attr.base.next = &tap_log_attr;
	alloc_attr.base.attr = NTDB_ATTRIBUTE_ALLOCATOR;

	alloc_attr.alloc.alloc = test_alloc;
	alloc_attr.alloc.expand = test_expand;
	alloc_attr.alloc.free = test_free;
	alloc_attr.alloc.priv_data = &owner_weird_count;

	plan_tests(sizeof(flags) / sizeof(flags[0]) * (1 + 700 * 3 + 4) + 1);

	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		curr_ntdb = NULL;
		curr_file = NULL;
		ntdb = ntdb_open("run-12-store.ntdb", flags[i]|MAYBE_NOSYNC,
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &alloc_attr);
		ok1(ntdb);
		if (!ntdb)
			continue;

		for (j = 0; j < 700; j++) {
			NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */
			ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
			ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
			ok1(ntdb_deq(d, data));
			test_free(d.dptr, &owner_weird_count);
		}
		ntdb_close(ntdb);

		ok1(owner_null_count == 2+i*2);
		ok1(owner_weird_count == 0);
		ok1(alloc_count == free_count);
		ok1(expand_count != 0);
	}

	ok1(tap_log_messages == 0);
	return exit_status();
}
예제 #4
0
static void move_rec(char *keyname, size_t keylen, char* tdbname)
{
	NTDB_DATA key, dbuf;
	struct ntdb_context *dst_ntdb;
	enum NTDB_ERROR ecode;

	if ((keyname == NULL) || (keylen == 0)) {
		terror(NTDB_SUCCESS, "need key");
		return;
	}

	if ( !tdbname ) {
		terror(NTDB_SUCCESS, "need destination ntdb name");
		return;
	}

	key.dptr = (unsigned char *)keyname;
	key.dsize = keylen;

	ecode = ntdb_fetch(ntdb, key, &dbuf);
	if (ecode) {
		terror(ecode, "fetch failed");
		return;
	}

	print_rec(ntdb, key, dbuf, NULL);

	dst_ntdb = ntdb_open(tdbname, 0, O_RDWR, 0600, NULL);
	if ( !dst_ntdb ) {
		terror(NTDB_SUCCESS, "unable to open destination ntdb");
		return;
	}

	ecode = ntdb_store( dst_ntdb, key, dbuf, NTDB_REPLACE);
	if (ecode)
		terror(ecode, "failed to move record");
	else
		printf("record moved\n");

	ntdb_close( dst_ntdb );
}
예제 #5
0
static void show_ntdb(char *keyname, size_t keylen)
{
	NTDB_DATA key, dbuf;
	enum NTDB_ERROR ecode;

	if ((keyname == NULL) || (keylen == 0)) {
		terror(NTDB_SUCCESS, "need key");
		return;
	}

	key.dptr = (unsigned char *)keyname;
	key.dsize = keylen;

	ecode = ntdb_fetch(ntdb, key, &dbuf);
	if (ecode) {
		terror(ecode, "fetch failed");
		return;
	}

	print_rec(ntdb, key, dbuf, NULL);

	free( dbuf.dptr );
}
static enum NTDB_ERROR fork_in_parse(NTDB_DATA key, NTDB_DATA data,
				    struct ntdb_context *ntdb)
{
	int status;

	if (fork() == 0) {
		am_child = true;

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

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

		if (tap_log_messages != 2)
			exit(2);

		return NTDB_SUCCESS;
	}
	wait(&status);
	ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0);
	return NTDB_SUCCESS;
}
예제 #7
0
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), d;
	union ntdb_attribute seed_attr;
	unsigned int msgs = 0;

	failtest_init(argc, argv);
	failtest_hook = block_repeat_failures;
	failtest_exit_check = exit_check_log;

	seed_attr.base.attr = NTDB_ATTRIBUTE_SEED;
	seed_attr.base.next = &tap_log_attr;
	seed_attr.seed.seed = 0;

	failtest_suppress = true;
	plan_tests(sizeof(flags) / sizeof(flags[0]) * 11);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("run-05-readonly-open.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600,
				 &seed_attr);
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
		ntdb_close(ntdb);

		failtest_suppress = false;
		ntdb = ntdb_open("run-05-readonly-open.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDONLY, 0600, &tap_log_attr);
		if (!ok1(ntdb))
			break;
		ok1(tap_log_messages == msgs);
		/* Fetch should succeed, stores should fail. */
		if (!ok1(ntdb_fetch(ntdb, key, &d) == 0))
			goto fail;
		ok1(ntdb_deq(d, data));
		free(d.dptr);
		if (!ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY)
			 == NTDB_ERR_RDONLY))
			goto fail;
		ok1(tap_log_messages == ++msgs);
		if (!ok1(ntdb_store(ntdb, key, data, NTDB_INSERT)
			 == NTDB_ERR_RDONLY))
			goto fail;
		ok1(tap_log_messages == ++msgs);
		failtest_suppress = true;
		ok1(ntdb_check(ntdb, NULL, NULL) == 0);
		ntdb_close(ntdb);
		ok1(tap_log_messages == msgs);
		/* SIGH: failtest bug, it doesn't save the ntdb file because
		 * we have it read-only.  If we go around again, it gets
		 * changed underneath us and things get screwy. */
		if (failtest_has_failed())
			break;
	}
	failtest_exit(exit_status());

fail:
	failtest_suppress = true;
	ntdb_close(ntdb);
	failtest_exit(exit_status());
}
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();
}
예제 #9
0
파일: speed.c 프로젝트: AIdrifter/samba
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;
}
예제 #10
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;
}
예제 #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();
}