示例#1
0
int main(int argc, char *argv[])
{
	unsigned int i;
	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 = ntdb_mkdata("key", 3);
	NTDB_DATA data = ntdb_mkdata("data", 4);

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 7 + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("run-simple-delete.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);
		if (ntdb) {
			/* Delete should fail. */
			ok1(ntdb_delete(ntdb, key) == NTDB_ERR_NOEXIST);
			ok1(ntdb_check(ntdb, NULL, NULL) == 0);
			/* Insert should succeed. */
			ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
			ok1(ntdb_check(ntdb, NULL, NULL) == 0);
			/* Delete should now work. */
			ok1(ntdb_delete(ntdb, key) == 0);
			ok1(ntdb_check(ntdb, NULL, NULL) == 0);
			ntdb_close(ntdb);
		}
	}
	ok1(tap_log_messages == 0);
	return exit_status();
}
int main(int argc, char *argv[])
{
	unsigned int i;
	struct agent *agent;
	struct ntdb_context *ntdb;
	NTDB_DATA d = ntdb_mkdata("hello", 5);
	const char filename[] = "run-remap-in-read_traverse.ntdb";

	plan_tests(4);

	agent = prepare_external_agent();

	ntdb = ntdb_open(filename, MAYBE_NOSYNC,
		       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);

	ok1(external_agent_operation(agent, OPEN, filename) == SUCCESS);
	i = add_records_to_grow(agent, ntdb->file->fd, ntdb->file->map_size);

	/* Do a traverse. */
	ok1(ntdb_traverse(ntdb, NULL, NULL) == i);

	/* Now store something! */
	ok1(ntdb_store(ntdb, d, d, NTDB_INSERT) == 0);
	ok1(tap_log_messages == 0);
	ntdb_close(ntdb);
	free_external_agent(agent);
	return exit_status();
}
示例#3
0
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;
}
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;
}
示例#5
0
int main(int argc, char *argv[])
{
	unsigned int i;
	struct ntdb_context *ntdb;
	struct agent *agent;
	union ntdb_attribute cif;
	NTDB_DATA key = ntdb_mkdata(KEY_STR, strlen(KEY_STR));
	int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
			NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };

	cif.openhook.base.attr = NTDB_ATTRIBUTE_OPENHOOK;
	cif.openhook.base.next = &tap_log_attr;
	cif.openhook.fn = clear_if_first;
	cif.openhook.data = clear_if_first;

	agent = prepare_external_agent();
	plan_tests(sizeof(flags) / sizeof(flags[0]) * 13);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		/* Create it */
		ntdb = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, NULL);
		ok1(ntdb);
		ok1(ntdb_store(ntdb, key, key, NTDB_REPLACE) == 0);
		ntdb_close(ntdb);

		/* Now, open with CIF, should clear it. */
		ntdb = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC,
				 O_RDWR, 0, &cif);
		ok1(ntdb);
		ok1(!ntdb_exists(ntdb, key));
		ok1(ntdb_store(ntdb, key, key, NTDB_REPLACE) == 0);

		/* Agent should not clear it, since it's still open. */
		ok1(external_agent_operation(agent, OPEN_WITH_HOOK,
					     "run-83-openhook.ntdb") == SUCCESS);
		ok1(external_agent_operation(agent, FETCH, KEY_STR "=" KEY_STR)
		    == SUCCESS);
		ok1(external_agent_operation(agent, CLOSE, "") == SUCCESS);

		/* Still exists for us too. */
		ok1(ntdb_exists(ntdb, key));

		/* Close it, now agent should clear it. */
		ntdb_close(ntdb);

		ok1(external_agent_operation(agent, OPEN_WITH_HOOK,
					     "run-83-openhook.ntdb") == SUCCESS);
		ok1(external_agent_operation(agent, FETCH, KEY_STR "=" KEY_STR)
		    == FAILED);
		ok1(external_agent_operation(agent, CLOSE, "") == SUCCESS);

		ok1(tap_log_messages == 0);
	}

	free_external_agent(agent);
	return exit_status();
}
int main(int argc, char *argv[])
{
	unsigned int i;
	int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT };
	NTDB_DATA key = ntdb_mkdata("hello", 5), data = ntdb_mkdata("world", 5);

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 2 + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("api-95-read-only-during-parse.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_SUCCESS);
		ok1(ntdb_parse_record(ntdb, key, parse, &data) == NTDB_SUCCESS);
		ntdb_close(ntdb);
	}

	ok1(tap_log_messages == 0);
	return exit_status();
}
示例#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 };

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

	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		union ntdb_attribute *attr;
		NTDB_DATA key = ntdb_mkdata("key", 3), data;

		ntdb = ntdb_open("run-91-get-stats.ntdb", flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);
		/* Force an expansion */
		data.dsize = 65536;
		data.dptr = calloc(data.dsize, 1);
		ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
		free(data.dptr);

		/* Use malloc so valgrind will catch overruns. */
		attr = malloc(sizeof *attr);
		attr->stats.base.attr = NTDB_ATTRIBUTE_STATS;
		attr->stats.size = sizeof(*attr);

		ok1(ntdb_get_attribute(ntdb, attr) == 0);
		ok1(attr->stats.size == sizeof(*attr));
		ok1(attr->stats.allocs > 0);
		ok1(attr->stats.expands > 0);
		ok1(attr->stats.locks > 0);
		free(attr);

		/* Try short one. */
		attr = malloc(offsetof(struct ntdb_attribute_stats, allocs)
			      + sizeof(attr->stats.allocs));
		attr->stats.base.attr = NTDB_ATTRIBUTE_STATS;
		attr->stats.size = offsetof(struct ntdb_attribute_stats, allocs)
			+ sizeof(attr->stats.allocs);
		ok1(ntdb_get_attribute(ntdb, attr) == 0);
		ok1(attr->stats.size == sizeof(*attr));
		ok1(attr->stats.allocs > 0);
		free(attr);
		ok1(tap_log_messages == 0);

		ntdb_close(ntdb);

	}
	return exit_status();
}
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();
}
示例#9
0
int main(int argc, char *argv[])
{
	unsigned int i;
	struct ntdb_context *ntdb;
	int flags[] = { NTDB_INTERNAL,
			NTDB_INTERNAL|NTDB_CONVERT,
			NTDB_CONVERT };
	NTDB_DATA key = ntdb_mkdata("key", 3);
	NTDB_DATA data = ntdb_mkdata("data", 4);

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

	failtest_suppress = true;
	plan_tests(sizeof(flags) / sizeof(flags[0]) * 3 + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("run-12-check.ntdb", flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);

		/* This is what we really want to test: ntdb_check(). */
		failtest_suppress = false;
		if (!ok1(ntdb_check(ntdb, NULL, NULL) == 0))
			goto fail;
		failtest_suppress = true;

		ntdb_close(ntdb);
	}
	ok1(tap_log_messages == 0);
	failtest_exit(exit_status());

fail:
	failtest_suppress = true;
	ntdb_close(ntdb);
	failtest_exit(exit_status());
}
示例#10
0
文件: ntdb.c 项目: AIdrifter/samba
_PUBLIC_ enum NTDB_ERROR ntdb_parse_record_(struct ntdb_context *ntdb,
				 NTDB_DATA key,
				 enum NTDB_ERROR (*parse)(NTDB_DATA k,
							 NTDB_DATA d,
							 void *data),
				 void *data)
{
	ntdb_off_t off;
	struct ntdb_used_record rec;
	struct hash_info h;
	enum NTDB_ERROR ecode;
	const char *keyp;

	off = find_and_lock(ntdb, key, F_RDLCK, &h, &rec, &keyp);
	if (NTDB_OFF_IS_ERR(off)) {
		return NTDB_OFF_TO_ERR(off);
	}

	if (!off) {
		ecode = NTDB_ERR_NOEXIST;
	} else {
		unsigned int old_flags;
		NTDB_DATA d = ntdb_mkdata(keyp + key.dsize,
					  rec_data_length(&rec));

		/*
		 * Make sure they don't try to write db, since they
		 * have read lock!  They can if they've done
		 * ntdb_lockall(): if it was ntdb_lockall_read, that'll
		 * stop them doing a write operation anyway.
		 */
		old_flags = ntdb->flags;
		if (!ntdb->file->allrecord_lock.count &&
		    !(ntdb->flags & NTDB_NOLOCK)) {
			ntdb->flags |= NTDB_RDONLY;
		}
		ecode = parse(key, d, data);
		ntdb->flags = old_flags;
		ntdb_access_release(ntdb, keyp);
	}

	ntdb_unlock_hash(ntdb, h.h, F_RDLCK);
	return ecode;
}
int main(int argc, char *argv[])
{
	unsigned int i;
	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 = ntdb_mkdata("key", 3);
	NTDB_DATA data;

	data.dptr = malloc(MAX_SIZE);
	memset(data.dptr, 0x24, MAX_SIZE);

	plan_tests(sizeof(flags) / sizeof(flags[0])
		   * (3 + (1 + (MAX_SIZE/SIZE_STEP)) * 2) + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		ntdb = ntdb_open("run-record-expand.ntdb",
				 flags[i]|MAYBE_NOSYNC,
				 O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(ntdb);
		if (!ntdb)
			continue;

		data.dsize = 0;
		ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0);
		ok1(ntdb_check(ntdb, NULL, NULL) == 0);
		for (data.dsize = 0;
		     data.dsize < MAX_SIZE;
		     data.dsize += SIZE_STEP) {
			memset(data.dptr, data.dsize, data.dsize);
			ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == 0);
			ok1(ntdb_check(ntdb, NULL, NULL) == 0);
		}
		ntdb_close(ntdb);
	}
	ok1(tap_log_messages == 0);
	free(data.dptr);

	return exit_status();
}
示例#12
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();
}
示例#13
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();
}
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();
}
示例#16
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();
}
示例#17
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);
}
示例#18
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;
}