コード例 #1
0
ファイル: run-tdb1-zero-append.c プロジェクト: sprymak/samba
int main(int argc, char *argv[])
{
	struct tdb_context *tdb;
	TDB_DATA key, data;
	union tdb_attribute hsize;

	hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE;
	hsize.base.next = &tap_log_attr;
	hsize.tdb1_hashsize.hsize = 1024;

	plan_tests(5);
	tdb = tdb_open(NULL, TDB_INTERNAL|TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR,
		       0600, &hsize);
	ok1(tdb);

	/* Tickle bug on appending zero length buffer to zero length buffer. */
	key = tdb_mkdata("hi", strlen("hi"));
	data = tdb_mkdata("world", 0);

	ok1(tdb_append(tdb, key, data) == TDB_SUCCESS);
	ok1(tdb_append(tdb, key, data) == TDB_SUCCESS);
	ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS);
	ok1(data.dsize == 0);
	free(data.dptr);
	tdb_close(tdb);

	return exit_status();
}
コード例 #2
0
ファイル: run-11-simple-fetch.c プロジェクト: sprymak/samba
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());
}
コード例 #3
0
ファイル: run-tdb1-check.c プロジェクト: sprymak/samba
int main(int argc, char *argv[])
{
	struct tdb_context *tdb;
	TDB_DATA key, data;
	union tdb_attribute hsize;

	hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE;
	hsize.base.next = &tap_log_attr;
	hsize.tdb1_hashsize.hsize = 1;

	plan_tests(13);
	tdb = tdb_open("run-check.tdb1", TDB_VERSION1,
		       O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize);

	ok1(tdb);
	ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);

	key = tdb_mkdata("hi", strlen("hi"));
	data = tdb_mkdata("world", strlen("world"));

	ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);
	ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
	tdb_close(tdb);

	tdb = tdb_open("run-check.tdb1", TDB_VERSION1, O_RDWR, 0, &tap_log_attr);
	ok1(tdb);
	ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
	tdb_close(tdb);

	tdb = tdb_open("test/tdb1.corrupt", TDB_VERSION1, O_RDWR, 0,
			&tap_log_attr);
	ok1(tdb);
	ok1(tdb_check(tdb, NULL, NULL) == TDB_ERR_CORRUPT);
	ok1(tdb_error(tdb) == TDB_ERR_CORRUPT);
	tdb_close(tdb);

	/* Big and little endian should work! */
	tdb = tdb_open("test/old-nohash-le.tdb1", TDB_VERSION1, O_RDWR, 0,
		       &tap_log_attr);
	ok1(tdb);
	ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
	tdb_close(tdb);

	tdb = tdb_open("test/old-nohash-be.tdb1", TDB_VERSION1, O_RDWR, 0,
			&tap_log_attr);
	ok1(tdb);
	ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
	tdb_close(tdb);

	return exit_status();
}
コード例 #4
0
int main(int argc, char *argv[])
{
	struct tdb_context *tdb;
	TDB_DATA key, data;
	union tdb_attribute hsize;

	hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE;
	hsize.base.next = &tap_log_attr;
	hsize.tdb1_hashsize.hsize = 1024;

	plan_tests(13);
	agent = prepare_external_agent1();
	if (!agent)
		err(1, "preparing agent");

	tdb = tdb_open("run-traverse-in-transaction.tdb1",
		       TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR,
		       0600, &hsize);
	ok1(tdb);

	key = tdb_mkdata("hi", strlen("hi"));
	data = tdb_mkdata("world", strlen("world"));

	ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);

	ok1(external_agent_operation1(agent, OPEN, tdb->name) == SUCCESS);

	ok1(tdb_transaction_start(tdb) == TDB_SUCCESS);
	ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
	    == WOULD_HAVE_BLOCKED);
	tdb_traverse(tdb, traverse, NULL);

	/* That should *not* release the transaction lock! */
	ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
	    == WOULD_HAVE_BLOCKED);
	tdb_traverse(tdb, traverse, NULL);

	/* That should *not* release the transaction lock! */
	ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
	    == WOULD_HAVE_BLOCKED);
	ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS);
	/* Now we should be fine. */
	ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name)
	    == SUCCESS);

	tdb_close(tdb);

	return exit_status();
}
コード例 #5
0
ファイル: run-12-check.c プロジェクト: burito/ccan
int main(int argc, char *argv[])
{
	unsigned int i;
	struct tdb_context *tdb;
	int flags[] = { TDB_INTERNAL,
			TDB_INTERNAL|TDB_CONVERT,
			TDB_CONVERT,
			TDB_INTERNAL|TDB_VERSION1,
			TDB_VERSION1,
			TDB_INTERNAL|TDB_CONVERT|TDB_VERSION1,
			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]) * 3 + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		tdb = tdb_open("run-12-check.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);

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

		tdb_close(tdb);
	}
	ok1(tap_log_messages == 0);
	failtest_exit(exit_status());

fail:
	failtest_suppress = true;
	tdb_close(tdb);
	failtest_exit(exit_status());
}
コード例 #6
0
int main(int argc, char *argv[])
{
    unsigned int i;
    struct tdb_context *tdb;
    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
                  };
    struct tdb_data key = tdb_mkdata("key", 3);
    struct tdb_data data = tdb_mkdata("data", 4);

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

    for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
        size_t size;
        tdb = tdb_open("run-expand-in-transaction.tdb", flags[i],
                       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
        ok1(tdb);
        if (!tdb)
            continue;

        size = tdb->file->map_size;
        ok1(tdb_transaction_start(tdb) == 0);
        ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
        ok1(tdb->file->map_size > size);
        ok1(tdb_transaction_commit(tdb) == 0);
        ok1(tdb->file->map_size > size);
        ok1(tdb_check(tdb, NULL, NULL) == 0);
        tdb_close(tdb);
    }

    ok1(tap_log_messages == 0);
    return exit_status();
}
コード例 #7
0
ファイル: api-simple-delete.c プロジェクト: atlant2011/samba
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);

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 7 + 1);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		tdb = tdb_open("run-simple-delete.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (tdb) {
			/* Delete should fail. */
			ok1(tdb_delete(tdb, key) == TDB_ERR_NOEXIST);
			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);
			/* Delete should now work. */
			ok1(tdb_delete(tdb, key) == 0);
			ok1(tdb_check(tdb, NULL, NULL) == 0);
			tdb_close(tdb);
		}
	}
	ok1(tap_log_messages == 0);
	return exit_status();
}
コード例 #8
0
ファイル: tdb.c プロジェクト: atlant2011/samba
enum TDB_ERROR tdb_parse_record_(struct tdb_context *tdb,
				 TDB_DATA key,
				 enum TDB_ERROR (*parse)(TDB_DATA k,
							 TDB_DATA d,
							 void *data),
				 void *data)
{
	tdb_off_t off;
	struct tdb_used_record rec;
	struct hash_info h;
	enum TDB_ERROR ecode;

	if (tdb->flags & TDB_VERSION1) {
		return tdb->last_error = tdb1_parse_record(tdb, key, parse,
							   data);
	}

	off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL);
	if (TDB_OFF_IS_ERR(off)) {
		return tdb->last_error = TDB_OFF_TO_ERR(off);
	}

	if (!off) {
		ecode = TDB_ERR_NOEXIST;
	} else {
		const void *dptr;
		dptr = tdb_access_read(tdb, off + sizeof(rec) + key.dsize,
				       rec_data_length(&rec), false);
		if (TDB_PTR_IS_ERR(dptr)) {
			ecode = TDB_PTR_ERR(dptr);
		} else {
			TDB_DATA d = tdb_mkdata(dptr, rec_data_length(&rec));

			ecode = parse(key, d, data);
			tdb_access_release(tdb, dptr);
		}
	}

	tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK);
	return tdb->last_error = ecode;
}
コード例 #9
0
ファイル: run-64-bit-tdb.c プロジェクト: atlant2011/samba
int main(int argc, char *argv[])
{
	unsigned int i;
	struct tdb_context *tdb;
	int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
			TDB_CONVERT,
			TDB_NOMMAP|TDB_CONVERT };

	if (sizeof(off_t) <= 4) {
		plan_tests(1);
		pass("No 64 bit off_t");
		return exit_status();
	}

	plan_tests(sizeof(flags) / sizeof(flags[0]) * 14);
	for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
		off_t old_size;
		TDB_DATA k, d;
		struct hash_info h;
		struct tdb_used_record rec;
		tdb_off_t off;

		tdb = tdb_open("run-64-bit-tdb.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (!tdb)
			continue;

		old_size = tdb->file->map_size;

		/* This makes a sparse file */
		ok1(ftruncate(tdb->file->fd, 0xFFFFFFF0) == 0);
		ok1(add_free_record(tdb, old_size, 0xFFFFFFF0 - old_size,
				    TDB_LOCK_WAIT, false) == TDB_SUCCESS);

		/* Now add a little record past the 4G barrier. */
		ok1(tdb_expand_file(tdb, 100) == TDB_SUCCESS);
		ok1(add_free_record(tdb, 0xFFFFFFF0, 100, TDB_LOCK_WAIT, false)
		    == TDB_SUCCESS);

		ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);

		/* Test allocation path. */
		k = tdb_mkdata("key", 4);
		d = tdb_mkdata("data", 5);
		ok1(tdb_store(tdb, k, d, TDB_INSERT) == 0);
		ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);

		/* Make sure it put it at end as we expected. */
		off = find_and_lock(tdb, k, F_RDLCK, &h, &rec, NULL);
		ok1(off >= 0xFFFFFFF0);
		tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK);

		ok1(tdb_fetch(tdb, k, &d) == 0);
		ok1(d.dsize == 5);
		ok1(strcmp((char *)d.dptr, "data") == 0);
		free(d.dptr);

		ok1(tdb_delete(tdb, k) == 0);
		ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);

		tdb_close(tdb);
	}

	/* We might get messages about mmap failing, so don't test
	 * tap_log_messages */
	return exit_status();
}
コード例 #10
0
ファイル: run-03-coalesce.c プロジェクト: Arkhont/samba
int main(int argc, char *argv[])
{
	tdb_off_t b_off, test;
	struct tdb_context *tdb;
	struct tdb_layout *layout;
	struct tdb_data data, key;
	tdb_len_t len;

	/* FIXME: Test TDB_CONVERT */
	/* FIXME: Test lock order fail. */

	plan_tests(42);
	data = tdb_mkdata("world", 5);
	key = tdb_mkdata("hello", 5);

	/* No coalescing can be done due to EOF */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	len = 1024;
	tdb_layout_add_free(layout, len, 0);
	tdb = tdb_layout_get(layout);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == len);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(len));
	/* Lock and fail to coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[1].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, len, &test)
	    == 0);
	tdb_unlock_free_bucket(tdb, b_off);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
	ok1(test == layout->elem[1].base.off);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* No coalescing can be done due to used record */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_used(layout, key, data, 6);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and fail to coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[1].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 0);
	tdb_unlock_free_bucket(tdb, b_off);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(test == layout->elem[1].base.off);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* Coalescing can be done due to two free records, then EOF */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_free(layout, 2048, 0);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(free_record_length(tdb, layout->elem[2].base.off) == 2048);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket (first) free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[2].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 1024 + sizeof(struct tdb_used_record) + 2048);
	/* Should tell us it's erased this one... */
	ok1(test == TDB_ERR_NOEXIST);
	ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off)
	    == 1024 + sizeof(struct tdb_used_record) + 2048);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* Coalescing can be done due to two free records, then data */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_free(layout, 512, 0);
	tdb_layout_add_used(layout, key, data, 6);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(free_record_length(tdb, layout->elem[2].base.off) == 512);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[2].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 1024 + sizeof(struct tdb_used_record) + 512);
	ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off)
	    == 1024 + sizeof(struct tdb_used_record) + 512);
	ok1(test == TDB_ERR_NOEXIST);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* Coalescing can be done due to three free records, then EOF */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_free(layout, 512, 0);
	tdb_layout_add_free(layout, 256, 0);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(free_record_length(tdb, layout->elem[2].base.off) == 512);
	ok1(free_record_length(tdb, layout->elem[3].base.off) == 256);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[2].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 1024 + sizeof(struct tdb_used_record) + 512
	    + sizeof(struct tdb_used_record) + 256);
	ok1(tdb->file->allrecord_lock.count == 0
	    && tdb->file->num_lockrecs == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off)
	    == 1024 + sizeof(struct tdb_used_record) + 512
	    + sizeof(struct tdb_used_record) + 256);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	ok1(tap_log_messages == 0);
	return exit_status();
}
コード例 #11
0
ファイル: run-55-transaction.c プロジェクト: Arkhont/samba
int main(int argc, char *argv[])
{
	unsigned int i;
	struct tdb_context *tdb;
	unsigned char *buffer;
	int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
			TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT };
	struct tdb_data key = tdb_mkdata("key", 3);
	struct tdb_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++) {
		tdb = tdb_open("run-55-transaction.tdb", flags[i],
			       O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
		ok1(tdb);
		if (!tdb)
			continue;

		ok1(tdb_transaction_start(tdb) == 0);
		data.dptr = buffer;
		data.dsize = 1000;
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
		ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS);
		ok1(data.dsize == 1000);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);

		/* Cancelling a transaction means no store */
		tdb_transaction_cancel(tdb);
		ok1(tdb->file->allrecord_lock.count == 0
		    && tdb->file->num_lockrecs == 0);
		ok1(tdb_check(tdb, NULL, NULL) == 0);
		ok1(tdb_fetch(tdb, key, &data) == TDB_ERR_NOEXIST);

		/* Commit the transaction. */
		ok1(tdb_transaction_start(tdb) == 0);
		data.dptr = buffer;
		data.dsize = 1000;
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
		ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS);
		ok1(data.dsize == 1000);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);
		ok1(tdb_transaction_commit(tdb) == 0);
		ok1(tdb->file->allrecord_lock.count == 0
		    && tdb->file->num_lockrecs == 0);
		ok1(tdb_check(tdb, NULL, NULL) == 0);
		ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS);
		ok1(data.dsize == 1000);
		ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
		free(data.dptr);

		tdb_close(tdb);
	}

	ok1(tap_log_messages == 0);
	free(buffer);
	return exit_status();
}
コード例 #12
0
int main(int argc, char *argv[])
{
    tdb_off_t off;
    struct tdb_context *tdb;
    struct tdb_layout *layout;
    TDB_DATA key, data;
    union tdb_attribute seed;

    /* This seed value previously tickled a layout.c bug. */
    seed.base.attr = TDB_ATTRIBUTE_SEED;
    seed.seed.seed = 0xb1142bc054d035b4ULL;
    seed.base.next = &tap_log_attr;

    plan_tests(11);
    key = tdb_mkdata("Hello", 5);
    data = tdb_mkdata("world", 5);

    /* Create a TDB with three free tables. */
    layout = new_tdb_layout();
    tdb_layout_add_freetable(layout);
    tdb_layout_add_freetable(layout);
    tdb_layout_add_freetable(layout);
    tdb_layout_add_free(layout, 80, 0);
    /* Used record prevent coalescing. */
    tdb_layout_add_used(layout, key, data, 6);
    tdb_layout_add_free(layout, 160, 1);
    key.dsize--;
    tdb_layout_add_used(layout, key, data, 7);
    tdb_layout_add_free(layout, 320, 2);
    key.dsize--;
    tdb_layout_add_used(layout, key, data, 8);
    tdb_layout_add_free(layout, 40, 0);
    tdb = tdb_layout_get(layout, free, &seed);
    ok1(tdb_check(tdb, NULL, NULL) == 0);

    off = get_free(tdb, 0, 80 - sizeof(struct tdb_used_record), 0,
                   TDB_USED_MAGIC, 0);
    ok1(off == layout->elem[3].base.off);
    ok1(tdb->tdb2.ftable_off == layout->elem[0].base.off);

    off = get_free(tdb, 0, 160 - sizeof(struct tdb_used_record), 0,
                   TDB_USED_MAGIC, 0);
    ok1(off == layout->elem[5].base.off);
    ok1(tdb->tdb2.ftable_off == layout->elem[1].base.off);

    off = get_free(tdb, 0, 320 - sizeof(struct tdb_used_record), 0,
                   TDB_USED_MAGIC, 0);
    ok1(off == layout->elem[7].base.off);
    ok1(tdb->tdb2.ftable_off == layout->elem[2].base.off);

    off = get_free(tdb, 0, 40 - sizeof(struct tdb_used_record), 0,
                   TDB_USED_MAGIC, 0);
    ok1(off == layout->elem[9].base.off);
    ok1(tdb->tdb2.ftable_off == layout->elem[0].base.off);

    /* Now we fail. */
    off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0);
    ok1(off == 0);

    tdb_close(tdb);
    tdb_layout_free(layout);

    ok1(tap_log_messages == 0);
    return exit_status();
}
コード例 #13
0
ファイル: tdb2tool.c プロジェクト: burito/ccan
static void speed_tdb(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();
		TDB_DATA key, dbuf;
		key = tdb_mkdata("store test", strlen("store test"));
		dbuf.dptr = (unsigned char *)&r;
		dbuf.dsize = sizeof(r);
		tdb_store(tdb, key, dbuf, TDB_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();
		TDB_DATA key, dbuf;
		key = tdb_mkdata("store test", strlen("store test"));
		dbuf.dptr = (unsigned char *)&r;
		dbuf.dsize = sizeof(r);
		tdb_fetch(tdb, 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();
		TDB_DATA key, dbuf;
		key = tdb_mkdata("transaction test", strlen("transaction test"));
		dbuf.dptr = (unsigned char *)&r;
		dbuf.dsize = sizeof(r);
		tdb_transaction_start(tdb);
		tdb_store(tdb, key, dbuf, TDB_REPLACE);
		tdb_transaction_commit(tdb);
		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 {
		tdb_traverse(tdb, traverse_fn, NULL);
		t = _end_timer();
		ops++;
	} while (t < timelimit);
	printf("%10.3f ops/sec\n", ops/t);
}
コード例 #14
0
int main(int argc, char *argv[])
{
	unsigned int i, extra_msgs;
	struct tdb_context *tdb;
	struct tdb_data key = tdb_mkdata("key", 3);
	struct tdb_data data = tdb_mkdata("data", 4);
	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]) * 48);

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

		/* TDB1 complains multiple times. */
		if (flags[i] & TDB_VERSION1) {
			extra_msgs = 1;
		} else {
			extra_msgs = 0;
		}

		ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);

		tdb_add_flag(tdb, TDB_RDONLY);
		ok1(tdb_get_flags(tdb) & TDB_RDONLY);

		/* Can't store, append, delete. */
		ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 1);
		ok1(tdb_append(tdb, key, data) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 2);
		ok1(tdb_delete(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 3);

		/* Can't start a transaction, or any write lock. */
		ok1(tdb_transaction_start(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 4);
		ok1(tdb_chainlock(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 5);
		ok1(tdb_lockall(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 6);
		ok1(tdb_wipe_all(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 7);

		/* Back to RW. */
		tdb_remove_flag(tdb, TDB_RDONLY);
		ok1(!(tdb_get_flags(tdb) & TDB_RDONLY));

		ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_SUCCESS);
		ok1(tdb_append(tdb, key, data) == TDB_SUCCESS);
		ok1(tdb_delete(tdb, key) == TDB_SUCCESS);

		ok1(tdb_transaction_start(tdb) == TDB_SUCCESS);
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);
		ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS);

		ok1(tdb_chainlock(tdb, key) == TDB_SUCCESS);
		tdb_chainunlock(tdb, key);
		ok1(tdb_lockall(tdb) == TDB_SUCCESS);
		tdb_unlockall(tdb);
		ok1(tdb_wipe_all(tdb) == TDB_SUCCESS);
		ok1(tap_log_messages == 7);

		tdb_close(tdb);

		/* R0 -> RW */
		tdb = tdb_open("run-92-get-set-readonly.tdb", flags[i],
			       O_RDONLY, 0600, &tap_log_attr);
		ok1(tdb);
		ok1(tdb_get_flags(tdb) & TDB_RDONLY);

		/* Can't store, append, delete. */
		ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 8);
		ok1(tdb_append(tdb, key, data) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 9);
		ok1(tdb_delete(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 10);

		/* Can't start a transaction, or any write lock. */
		ok1(tdb_transaction_start(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 11);
		ok1(tdb_chainlock(tdb, key) == TDB_ERR_RDONLY);
		tap_log_messages -= extra_msgs;
		ok1(tap_log_messages == 12);
		ok1(tdb_lockall(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 13);
		ok1(tdb_wipe_all(tdb) == TDB_ERR_RDONLY);
		ok1(tap_log_messages == 14);

		/* Can't remove TDB_RDONLY since we opened with O_RDONLY */
		tdb_remove_flag(tdb, TDB_RDONLY);
		ok1(tap_log_messages == 15);
		ok1(tdb_get_flags(tdb) & TDB_RDONLY);
		tdb_close(tdb);

		ok1(tap_log_messages == 15);
		tap_log_messages = 0;
	}
	return exit_status();
}
コード例 #15
0
ファイル: external-agent.c プロジェクト: sprymak/samba
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;
}