Exemple #1
0
int main(int argc, char *argv[])
{
	unsigned int i;
	struct tdb_context *tdb;
	int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
			TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
			TDB_NOMMAP|TDB_CONVERT,
			TDB_INTERNAL|TDB_VERSION1, TDB_VERSION1,
			TDB_NOMMAP|TDB_VERSION1,
			TDB_INTERNAL|TDB_CONVERT|TDB_VERSION1,
			TDB_CONVERT|TDB_VERSION1,
			TDB_NOMMAP|TDB_CONVERT|TDB_VERSION1 };
	struct tdb_data key = tdb_mkdata("key", 3);
	struct tdb_data data = tdb_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]) * 8 + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		tdb = tdb_open("run-11-simple-fetch.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (tdb) {
			struct tdb_data d = { NULL, 0 }; /* Bogus GCC warning */

			/* fetch should fail. */
			failtest_suppress = false;
			if (!ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_NOEXIST))
				goto fail;
			failtest_suppress = true;
			ok1(tdb_check(tdb, NULL, NULL) == 0);
			/* Insert should succeed. */
			ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
			ok1(tdb_check(tdb, NULL, NULL) == 0);
			/* Fetch should now work. */
			failtest_suppress = false;
			if (!ok1(tdb_fetch(tdb, key, &d) == TDB_SUCCESS))
				goto fail;
			failtest_suppress = true;
			ok1(tdb_deq(d, data));
			free(d.dptr);
			ok1(tdb_check(tdb, NULL, NULL) == 0);
			tdb_close(tdb);
		}
	}
	ok1(tap_log_messages == 0);
	failtest_exit(exit_status());

fail:
	failtest_suppress = true;
	tdb_close(tdb);
	failtest_exit(exit_status());
}
Exemple #2
0
static bool store_records(struct tdb_context *tdb)
{
	int i;
	struct tdb_data key = { (unsigned char *)&i, sizeof(i) };
	struct tdb_data d, data = { (unsigned char *)&i, sizeof(i) };

	for (i = 0; i < 1000; i++) {
		if (tdb_store(tdb, key, data, TDB_REPLACE) != 0)
			return false;
		tdb_fetch(tdb, key, &d);
		if (!tdb_deq(d, data))
			return false;
		free(d.dptr);
	}
	return true;
}
Exemple #3
0
static enum TDB_ERROR parse(TDB_DATA key, TDB_DATA data, TDB_DATA *expected)
{
	if (!tdb_deq(data, *expected))
		return TDB_ERR_EINVAL;
	return TDB_SUCCESS;
}
Exemple #4
0
static enum agent_return do_operation(enum operation op, const char *name)
{
	TDB_DATA k;
	enum agent_return ret;
	TDB_DATA data;
	enum TDB_ERROR ecode;
	union tdb_attribute cif;

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

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

	k = tdb_mkdata(name, strlen(name));

	locking_would_block = 0;
	switch (op) {
	case OPEN:
		if (tdb) {
			diag("Already have tdb %s open", tdb_name(tdb));
			return OTHER_FAILURE;
		}
		tdb = tdb_open(name, TDB_DEFAULT, O_RDWR, 0, &tap_log_attr);
		if (!tdb) {
			if (!locking_would_block)
				diag("Opening tdb gave %s", strerror(errno));
			forget_locking();
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case OPEN_WITH_HOOK:
		if (tdb) {
			diag("Already have tdb %s open", tdb_name(tdb));
			return OTHER_FAILURE;
		}
		cif.openhook.base.attr = TDB_ATTRIBUTE_OPENHOOK;
		cif.openhook.base.next = &tap_log_attr;
		cif.openhook.fn = clear_if_first;
		tdb = tdb_open(name, TDB_DEFAULT, O_RDWR, 0, &cif);
		if (!tdb) {
			if (!locking_would_block)
				diag("Opening tdb gave %s", strerror(errno));
			forget_locking();
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case FETCH:
		ecode = tdb_fetch(tdb, k, &data);
		if (ecode == TDB_ERR_NOEXIST) {
			ret = FAILED;
		} else if (ecode < 0) {
			ret = OTHER_FAILURE;
		} else if (!tdb_deq(data, k)) {
			ret = OTHER_FAILURE;
			external_agent_free(data.dptr);
		} else {
			ret = SUCCESS;
			external_agent_free(data.dptr);
		}
		break;
	case STORE:
		ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_START:
		ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_COMMIT:
		ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE;
		break;
	case NEEDS_RECOVERY:
		ret = external_agent_needs_rec(tdb);
		break;
	case CHECK:
		ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case CLOSE:
		ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
		tdb = 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;
}
int main(int argc, char *argv[])
{
	unsigned int i, extra_messages;
	struct tdb_context *tdb, *tdb2;
	struct tdb_data key = { (unsigned char *)&i, sizeof(i) };
	struct tdb_data data = { (unsigned char *)&i, sizeof(i) };
	struct tdb_data d = { NULL, 0 }; /* Bogus GCC warning */
	int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
			TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT,
			TDB_VERSION1, TDB_NOMMAP|TDB_VERSION1,
			TDB_CONVERT|TDB_VERSION1,
			TDB_NOMMAP|TDB_CONVERT|TDB_VERSION1 };

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 28);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		tdb = tdb_open("run-open-multiple-times.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (!tdb)
			continue;

		if (flags[i] & TDB_VERSION1) {
			extra_messages = 1;
		} else {
			extra_messages = 0;
		}
		tdb2 = tdb_open("run-open-multiple-times.tdb", flags[i],
				O_RDWR|O_CREAT, 0600, &tap_log_attr);
		ok1(tdb_check(tdb, NULL, NULL) == 0);
		ok1(tdb_check(tdb2, NULL, NULL) == 0);

		/* Store in one, fetch in the other. */
		ok1(tdb_store(tdb, key, data, TDB_REPLACE) == 0);
		ok1(tdb_fetch(tdb2, key, &d) == TDB_SUCCESS);
		ok1(tdb_deq(d, data));
		free(d.dptr);

		/* Vice versa, with delete. */
		ok1(tdb_delete(tdb2, key) == 0);
		ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_NOEXIST);

		/* OK, now close first one, check second still good. */
		ok1(tdb_close(tdb) == 0);

		ok1(tdb_store(tdb2, key, data, TDB_REPLACE) == 0);
		ok1(tdb_fetch(tdb2, key, &d) == TDB_SUCCESS);
		ok1(tdb_deq(d, data));
		free(d.dptr);

		/* Reopen */
		tdb = tdb_open("run-open-multiple-times.tdb", flags[i],
			       O_RDWR|O_CREAT, 0600, &tap_log_attr);
		ok1(tdb);

		ok1(tdb_transaction_start(tdb2) == 0);

		/* Anything in the other one should fail. */
		ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
		tap_log_messages -= extra_messages;
		ok1(tap_log_messages == 1);
		ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
		tap_log_messages -= extra_messages;
		ok1(tap_log_messages == 2);
		ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
		ok1(tap_log_messages == 3);
		ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
		tap_log_messages -= extra_messages;
		ok1(tap_log_messages == 4);

		/* Transaciton should work as normal. */
		ok1(tdb_store(tdb2, key, data, TDB_REPLACE) == TDB_SUCCESS);

		/* Now... try closing with locks held. */
		ok1(tdb_close(tdb2) == 0);

		ok1(tdb_fetch(tdb, key, &d) == TDB_SUCCESS);
		ok1(tdb_deq(d, data));
		free(d.dptr);
		ok1(tdb_close(tdb) == 0);
		ok1(tap_log_messages == 4);
		tap_log_messages = 0;
	}

	return exit_status();
}