From: Rusty Russell Date: Wed, 31 Aug 2011 06:01:06 +0000 (+0930) Subject: tdb2: add TDB_ATTRIBUTE_TDB1_HASHSIZE X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=49475d68deecd0b31597ed6094229171d2699b11 tdb2: add TDB_ATTRIBUTE_TDB1_HASHSIZE This replaces the tdb1_open "hash_size" argument. It will only be valid when you call tdb_open() with O_CREAT in open_flags, and TDB_VERSION1 in tdb_flags. --- diff --git a/ccan/tdb2/open.c b/ccan/tdb2/open.c index 49804acf..5d5eff13 100644 --- a/ccan/tdb2/open.c +++ b/ccan/tdb2/open.c @@ -209,6 +209,7 @@ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, case TDB_ATTRIBUTE_HASH: case TDB_ATTRIBUTE_SEED: case TDB_ATTRIBUTE_OPENHOOK: + case TDB_ATTRIBUTE_TDB1_HASHSIZE: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, @@ -218,7 +219,9 @@ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, ? "TDB_ATTRIBUTE_HASH" : attr->base.attr == TDB_ATTRIBUTE_SEED ? "TDB_ATTRIBUTE_SEED" - : "TDB_ATTRIBUTE_OPENHOOK"); + : attr->base.attr == TDB_ATTRIBUTE_OPENHOOK + ? "TDB_ATTRIBUTE_OPENHOOK" + : "TDB_ATTRIBUTE_TDB1_HASHSIZE"); case TDB_ATTRIBUTE_STATS: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -276,6 +279,16 @@ enum TDB_ERROR tdb_get_attribute(struct tdb_context *tdb, attr->flock.unlock = tdb->unlock_fn; attr->flock.data = tdb->lock_data; break; + case TDB_ATTRIBUTE_TDB1_HASHSIZE: + if (!(tdb->flags & TDB_VERSION1)) + return tdb->last_error + = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_get_attribute:" + " cannot get TDB_ATTRIBUTE_TDB1_HASHSIZE" + " on TDB2 tdb."); + attr->tdb1_hashsize.hsize = tdb->tdb1.header.hash_size; + break; default: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -300,11 +313,14 @@ void tdb_unset_attribute(struct tdb_context *tdb, break; case TDB_ATTRIBUTE_HASH: case TDB_ATTRIBUTE_SEED: + case TDB_ATTRIBUTE_TDB1_HASHSIZE: tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_unset_attribute: cannot unset %s after opening", type == TDB_ATTRIBUTE_HASH ? "TDB_ATTRIBUTE_HASH" - : "TDB_ATTRIBUTE_SEED"); + : type == TDB_ATTRIBUTE_SEED + ? "TDB_ATTRIBUTE_SEED" + : "TDB_ATTRIBUTE_TDB1_HASHSIZE"); break; case TDB_ATTRIBUTE_STATS: tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -336,6 +352,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, ssize_t rlen; struct tdb_header hdr; struct tdb_attribute_seed *seed = NULL; + struct tdb_attribute_tdb1_hashsize *hsize_attr = NULL; tdb_bool_err berr; enum TDB_ERROR ecode; int openlock; @@ -382,6 +399,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, tdb->openhook = attr->openhook.fn; tdb->openhook_data = attr->openhook.data; break; + case TDB_ATTRIBUTE_TDB1_HASHSIZE: + hsize_attr = &attr->tdb1_hashsize; + break; default: /* These are set as normal. */ ecode = tdb_set_attribute(tdb, attr); @@ -399,6 +419,18 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } + if (hsize_attr) { + if (!(tdb_flags & TDB_VERSION1) || + (!(tdb_flags & TDB_INTERNAL) && !(open_flags & O_CREAT))) { + ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_open: can only use" + " TDB_ATTRIBUTE_TDB1_HASHSIZE when" + " creating a TDB_VERSION1 tdb"); + goto fail; + } + } + if ((open_flags & O_ACCMODE) == O_WRONLY) { ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_open: can't open tdb %s write-only", diff --git a/ccan/tdb2/tdb1.h b/ccan/tdb2/tdb1.h index a2a0afe8..9e280f0b 100644 --- a/ccan/tdb2/tdb1.h +++ b/ccan/tdb2/tdb1.h @@ -38,7 +38,7 @@ typedef int (*tdb1_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); -struct tdb_context *tdb1_open(const char *name, int hash_size, int tdb1_flags, +struct tdb_context *tdb1_open(const char *name, int tdb1_flags, int open_flags, mode_t mode, union tdb_attribute *attributes); @@ -87,8 +87,6 @@ int tdb1_transaction_cancel(struct tdb_context *tdb); int tdb1_get_seqnum(struct tdb_context *tdb); -int tdb1_hash_size(struct tdb_context *tdb); - void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb); uint64_t tdb1_incompatible_hash(const void *key, size_t len, uint64_t seed, void *); diff --git a/ccan/tdb2/tdb1_open.c b/ccan/tdb2/tdb1_open.c index 1f23db01..c1729b57 100644 --- a/ccan/tdb2/tdb1_open.c +++ b/ccan/tdb2/tdb1_open.c @@ -24,7 +24,7 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ - +#include #include "tdb1_private.h" /* We use two hashes to double-check they're using the right hash function. */ @@ -222,8 +222,6 @@ static struct tdb_context *tdb1_open_ex(const char *name, int hash_size, int tdb goto fail; } - if (hash_size == 0) - hash_size = TDB1_DEFAULT_HASH_SIZE; if ((open_flags & O_ACCMODE) == O_RDONLY) { tdb->flags |= TDB_RDONLY; /* read only databases don't do locking */ @@ -359,12 +357,13 @@ static struct tdb_context *tdb1_open_ex(const char *name, int hash_size, int tdb } /* Temporart wrapper for transition. */ -struct tdb_context *tdb1_open(const char *name, int hash_size, int tdb1_flags, +struct tdb_context *tdb1_open(const char *name, int tdb1_flags, int open_flags, mode_t mode, union tdb_attribute *attr) { struct tdb1_logging_context *log_ctx = NULL, log; tdb1_hash_func hash_fn = NULL; + struct tdb_attribute_tdb1_hashsize *hsize = NULL; while (attr) { switch (attr->base.attr) { @@ -376,13 +375,31 @@ struct tdb_context *tdb1_open(const char *name, int hash_size, int tdb1_flags, log.log_private = attr->log.data; log_ctx = &log; break; + case TDB_ATTRIBUTE_TDB1_HASHSIZE: + hsize = &attr->tdb1_hashsize; + break; + break; default: abort(); } attr = attr->base.next; } - return tdb1_open_ex(name, hash_size, tdb1_flags, open_flags, mode, + if (hsize && !(open_flags & O_CREAT)) { + if (log_ctx) { + log_ctx->log_fn(NULL, + TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_open: can only use" + " TDB_ATTRIBUTE_TDB1_HASHSIZE when" + " creating a tdb", + log_ctx->log_private); + } + errno = EINVAL; + return NULL; + } + return tdb1_open_ex(name, hsize ? hsize->hsize : TDB1_DEFAULT_HASH_SIZE, + tdb1_flags, open_flags, mode, log_ctx, hash_fn); } diff --git a/ccan/tdb2/tdb1_tdb.c b/ccan/tdb2/tdb1_tdb.c index e9696000..bb007722 100644 --- a/ccan/tdb2/tdb1_tdb.c +++ b/ccan/tdb2/tdb1_tdb.c @@ -681,11 +681,6 @@ int tdb1_get_seqnum(struct tdb_context *tdb) return seqnum; } -int tdb1_hash_size(struct tdb_context *tdb) -{ - return tdb->tdb1.header.hash_size; -} - /* add a region of the file to the freelist. Length is the size of the region in bytes, @@ -836,6 +831,11 @@ int tdb1_repack(struct tdb_context *tdb) { struct tdb_context *tmp_db; struct traverse_state state; + union tdb_attribute hsize; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = NULL; + hsize.tdb1_hashsize.hsize = tdb->tdb1.header.hash_size; if (tdb1_transaction_start(tdb) != 0) { tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, @@ -843,7 +843,7 @@ int tdb1_repack(struct tdb_context *tdb) return -1; } - tmp_db = tdb1_open("tmpdb", tdb1_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0, NULL); + tmp_db = tdb1_open("tmpdb", TDB_INTERNAL, O_RDWR|O_CREAT, 0, &hsize); if (tmp_db == NULL) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR, __location__ " Failed to create tmp_db"); diff --git a/ccan/tdb2/tdb2.h b/ccan/tdb2/tdb2.h index 4be15e98..c91ca7ca 100644 --- a/ccan/tdb2/tdb2.h +++ b/ccan/tdb2/tdb2.h @@ -607,7 +607,8 @@ enum tdb_attribute_type { TDB_ATTRIBUTE_SEED = 2, TDB_ATTRIBUTE_STATS = 3, TDB_ATTRIBUTE_OPENHOOK = 4, - TDB_ATTRIBUTE_FLOCK = 5 + TDB_ATTRIBUTE_FLOCK = 5, + TDB_ATTRIBUTE_TDB1_HASHSIZE = 128, }; /** @@ -631,8 +632,9 @@ enum TDB_ERROR tdb_get_attribute(struct tdb_context *tdb, * of the same type. It returns TDB_ERR_EINVAL if the attribute is * unknown or invalid. * - * Note that TDB_ATTRIBUTE_HASH, TDB_ATTRIBUTE_SEED and - * TDB_ATTRIBUTE_OPENHOOK cannot currently be set after tdb_open. + * Note that TDB_ATTRIBUTE_HASH, TDB_ATTRIBUTE_SEED, + * TDB_ATTRIBUTE_OPENHOOK and TDB_ATTRIBUTE_TDB1_HASHSIZE cannot + * currently be set after tdb_open. */ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, const union tdb_attribute *attr); @@ -838,6 +840,19 @@ struct tdb_attribute_flock { void *data; }; +/** + * struct tdb_attribute_tdb1_hashsize - tdb1 hashsize + * + * This attribute allows setting the TDB1 hashsize; it only makes sense with + * O_CREAT and TDB_VERSION1. + * + * Hashsize should generally be a prime, such as 10007. + */ +struct tdb_attribute_tdb1_hashsize { + struct tdb_attribute_base base; /* .attr = TDB_ATTRIBUTE_TDB1_HASHSIZE */ + unsigned int hsize; +}; + /** * union tdb_attribute - tdb attributes. * @@ -856,6 +871,7 @@ union tdb_attribute { struct tdb_attribute_stats stats; struct tdb_attribute_openhook openhook; struct tdb_attribute_flock flock; + struct tdb_attribute_tdb1_hashsize tdb1_hashsize; }; #ifdef __cplusplus diff --git a/ccan/tdb2/test/failtest_helper.h b/ccan/tdb2/test/failtest_helper.h index a585dc2b..37acbdd8 100644 --- a/ccan/tdb2/test/failtest_helper.h +++ b/ccan/tdb2/test/failtest_helper.h @@ -4,7 +4,7 @@ #include /* FIXME: Check these! */ -#define INITIAL_TDB_MALLOC "open.c", 343, FAILTEST_MALLOC +#define INITIAL_TDB_MALLOC "open.c", 360, FAILTEST_MALLOC #define URANDOM_OPEN "open.c", 61, FAILTEST_OPEN #define URANDOM_READ "open.c", 41, FAILTEST_READ diff --git a/ccan/tdb2/test/run-tdb1-3G-file.c b/ccan/tdb2/test/run-tdb1-3G-file.c index 1eab4476..4edaa5d4 100644 --- a/ccan/tdb2/test/run-tdb1-3G-file.c +++ b/ccan/tdb2/test/run-tdb1-3G-file.c @@ -64,10 +64,15 @@ int main(int argc, char *argv[]) uint32_t hash; tdb1_off_t rec_ptr; struct tdb1_record rec; + union tdb_attribute hsize; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = &tap_log_attr; + hsize.tdb1_hashsize.hsize = 1024; plan_tests(24); - tdb = tdb1_open("run-36-file.tdb", 1024, TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open("run-36-file.tdb", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); tdb->tdb1.io = &large_io_methods; diff --git a/ccan/tdb2/test/run-tdb1-bad-tdb-header.c b/ccan/tdb2/test/run-tdb1-bad-tdb-header.c index a32b817c..f8bee0b4 100644 --- a/ccan/tdb2/test/run-tdb1-bad-tdb-header.c +++ b/ccan/tdb2/test/run-tdb1-bad-tdb-header.c @@ -9,6 +9,11 @@ int main(int argc, char *argv[]) struct tdb_context *tdb; struct tdb1_header hdr; int fd; + union tdb_attribute hsize; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = &tap_log_attr; + hsize.tdb1_hashsize.hsize = 1024; plan_tests(11); /* Can open fine if complete crap, as long as O_CREAT. */ @@ -16,11 +21,10 @@ int main(int argc, char *argv[]) ok1(fd >= 0); ok1(write(fd, "hello world", 11) == 11); close(fd); - tdb = tdb1_open("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0, - &tap_log_attr); + tdb = tdb1_open("run-bad-tdb-header.tdb", 0, O_RDWR, 0, &tap_log_attr); ok1(!tdb); - tdb = tdb1_open("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR, - 0600, &tap_log_attr); + tdb = tdb1_open("run-bad-tdb-header.tdb", 0, O_CREAT|O_RDWR, + 0600, &hsize); ok1(tdb); tdb1_close(tdb); @@ -34,14 +38,14 @@ int main(int argc, char *argv[]) ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); close(fd); - tdb = tdb1_open("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT, - 0600, &tap_log_attr); + tdb = tdb1_open("run-bad-tdb-header.tdb", 0, O_RDWR|O_CREAT, + 0600, &hsize); ok1(errno == EIO); ok1(!tdb); /* With truncate, will be fine. */ - tdb = tdb1_open("run-bad-tdb-header.tdb", 1024, 0, - O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); + tdb = tdb1_open("run-bad-tdb-header.tdb", 0, + O_RDWR|O_CREAT|O_TRUNC, 0600, &hsize); ok1(tdb); tdb1_close(tdb); diff --git a/ccan/tdb2/test/run-tdb1-check.c b/ccan/tdb2/test/run-tdb1-check.c index 017eb832..f188dc92 100644 --- a/ccan/tdb2/test/run-tdb1-check.c +++ b/ccan/tdb2/test/run-tdb1-check.c @@ -8,10 +8,15 @@ 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 = tdb1_open("run-check.tdb", 1, TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open("run-check.tdb", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); @@ -25,13 +30,13 @@ int main(int argc, char *argv[]) ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - tdb = tdb1_open("run-check.tdb", 1024, 0, O_RDWR, 0, + tdb = tdb1_open("run-check.tdb", 0, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - tdb = tdb1_open("test/tdb1.corrupt", 1024, 0, O_RDWR, 0, + tdb = tdb1_open("test/tdb1.corrupt", 0, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == -1); @@ -39,13 +44,13 @@ int main(int argc, char *argv[]) tdb1_close(tdb); /* Big and little endian should work! */ - tdb = tdb1_open("test/old-nohash-le.tdb1", 1024, 0, O_RDWR, 0, + tdb = tdb1_open("test/old-nohash-le.tdb1", 0, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - tdb = tdb1_open("test/old-nohash-be.tdb1", 1024, 0, O_RDWR, 0, + tdb = tdb1_open("test/old-nohash-be.tdb1", 0, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); diff --git a/ccan/tdb2/test/run-tdb1-corrupt.c b/ccan/tdb2/test/run-tdb1-corrupt.c index 833e9c1e..8647eccc 100644 --- a/ccan/tdb2/test/run-tdb1-corrupt.c +++ b/ccan/tdb2/test/run-tdb1-corrupt.c @@ -94,11 +94,16 @@ static void check_test(struct tdb_context *tdb) int main(int argc, char *argv[]) { struct tdb_context *tdb; + union tdb_attribute hsize; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = &tap_log_attr; + hsize.tdb1_hashsize.hsize = 2; plan_tests(4); /* This should use mmap. */ - tdb = tdb1_open("run-corrupt.tdb", 2, TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open("run-corrupt.tdb", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); if (!tdb) abort(); @@ -106,8 +111,8 @@ int main(int argc, char *argv[]) tdb1_close(tdb); /* This should not. */ - tdb = tdb1_open("run-corrupt.tdb", 2, TDB_NOMMAP, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open("run-corrupt.tdb", TDB_NOMMAP, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); if (!tdb) abort(); diff --git a/ccan/tdb2/test/run-tdb1-die-during-transaction.c b/ccan/tdb2/test/run-tdb1-die-during-transaction.c index 9ff75d10..933d7486 100644 --- a/ccan/tdb2/test/run-tdb1-die-during-transaction.c +++ b/ccan/tdb2/test/run-tdb1-die-during-transaction.c @@ -85,12 +85,17 @@ static bool test_death(enum operation op, struct agent *agent) TDB_DATA key; enum agent_return ret; int needed_recovery = 0; + union tdb_attribute hsize; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = &tap_log_attr; + hsize.tdb1_hashsize.hsize = 1024; current = target = 0; reset: unlink(TEST_DBNAME); - tdb = tdb1_open(TEST_DBNAME, 1024, TDB_NOMMAP, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open(TEST_DBNAME, TDB_NOMMAP, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); if (setjmp(jmpbuf) != 0) { /* We're partway through. Simulate our death. */ diff --git a/ccan/tdb2/test/run-tdb1-endian.c b/ccan/tdb2/test/run-tdb1-endian.c index a06bfb6e..e1b92eea 100644 --- a/ccan/tdb2/test/run-tdb1-endian.c +++ b/ccan/tdb2/test/run-tdb1-endian.c @@ -8,11 +8,16 @@ 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); - tdb = tdb1_open("run-endian.tdb", 1024, + tdb = tdb1_open("run-endian.tdb", TDB_CONVERT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); key.dsize = strlen("hi"); @@ -38,8 +43,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); /* Reopen: should read it */ - tdb = tdb1_open("run-endian.tdb", 1024, 0, O_RDWR, 0, - &tap_log_attr); + tdb = tdb1_open("run-endian.tdb", 0, O_RDWR, 0, NULL); ok1(tdb); key.dsize = strlen("hi"); diff --git a/ccan/tdb2/test/run-tdb1-hashsize.c b/ccan/tdb2/test/run-tdb1-hashsize.c new file mode 100644 index 00000000..fc48c230 --- /dev/null +++ b/ccan/tdb2/test/run-tdb1-hashsize.c @@ -0,0 +1,61 @@ +#include "tdb2-source.h" +#include +#include +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + union tdb_attribute hsize, h2; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = &tap_log_attr; + hsize.tdb1_hashsize.hsize = 1024; + + plan_tests(14); + tdb = tdb1_open("run-tdb1-hashsize.tdb1", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); + ok1(tdb); + h2.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + ok1(tdb_get_attribute(tdb, &h2) == TDB_SUCCESS); + ok1(h2.tdb1_hashsize.hsize == hsize.tdb1_hashsize.hsize); + tdb_close(tdb); + + /* Can't specify TDB_ATTRIBUTE_TDB1_HASHSIZE without O_CREAT */ + tdb = tdb1_open("run-tdb1-hashsize.tdb1", TDB_DEFAULT, + O_RDWR, 0600, &hsize); + ok1(!tdb); + ok1(tap_log_messages == 1); + + /* Can't specify TDB_ATTRIBUTE_TDB1_HASHSIZE for version2. */ + tdb = tdb_open("run-tdb1-hashsize.tdb", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); + ok1(!tdb); + ok1(tap_log_messages == 2); + + /* We can get attribute even if we didn't set it though. */ + tdb = tdb1_open("run-tdb1-hashsize.tdb1", TDB_DEFAULT, + O_RDWR, 0600, &tap_log_attr); + + ok1(tdb); + memset(&h2, 0, sizeof(h2)); + h2.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + ok1(tdb_get_attribute(tdb, &h2) == TDB_SUCCESS); + ok1(h2.tdb1_hashsize.hsize == hsize.tdb1_hashsize.hsize); + tdb_close(tdb); + + /* Check for default hash size. */ + tdb = tdb1_open("run-tdb1-hashsize.tdb1", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + + ok1(tdb); + memset(&h2, 0, sizeof(h2)); + h2.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + ok1(tdb_get_attribute(tdb, &h2) == TDB_SUCCESS); + ok1(h2.tdb1_hashsize.hsize == TDB1_DEFAULT_HASH_SIZE); + tdb_close(tdb); + ok1(tap_log_messages == 2); + + return exit_status(); +} diff --git a/ccan/tdb2/test/run-tdb1-incompatible.c b/ccan/tdb2/test/run-tdb1-incompatible.c index baf40ed4..48f796db 100644 --- a/ccan/tdb2/test/run-tdb1-incompatible.c +++ b/ccan/tdb2/test/run-tdb1-incompatible.c @@ -83,7 +83,7 @@ int main(int argc, char *argv[]) /* Create an old-style hash. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, flags, + tdb = tdb1_open("run-incompatible.tdb", flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_attr); ok1(tdb); ok1(log_count == 0); @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) /* We can still open any old-style with incompat hash. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, + tdb = tdb1_open("run-incompatible.tdb", TDB_DEFAULT, O_RDWR, 0600, &incompat_hash_attr); ok1(tdb); @@ -109,7 +109,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); log_count = 0; - tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, 0, O_RDONLY, + tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, O_RDONLY, 0, &jhash_attr); ok1(tdb); ok1(log_count == 0); @@ -117,7 +117,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); log_count = 0; - tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, 0, O_RDONLY, + tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, O_RDONLY, 0, &jhash_attr); ok1(tdb); ok1(log_count == 0); @@ -126,7 +126,7 @@ int main(int argc, char *argv[]) /* OK, now create with incompatible hash. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, + tdb = tdb1_open("run-incompatible.tdb", flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &incompat_hash_attr); @@ -142,14 +142,14 @@ int main(int argc, char *argv[]) /* Cannot open with old hash. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, 0, + tdb = tdb1_open("run-incompatible.tdb", 0, O_RDWR, 0600, &ohash_attr); ok1(!tdb); ok1(log_count == 1); /* Can open with jenkins hash. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, 0, + tdb = tdb1_open("run-incompatible.tdb", 0, O_RDWR, 0600, &jhash_attr); ok1(tdb); ok1(log_count == 0); @@ -161,7 +161,7 @@ int main(int argc, char *argv[]) /* Can open by letting it figure it out itself. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, 0, + tdb = tdb1_open("run-incompatible.tdb", 0, O_RDWR, 0600, &log_attr); ok1(tdb); ok1(log_count == 0); @@ -176,7 +176,7 @@ int main(int argc, char *argv[]) /* FIXME: Not possible with TDB2 :( */ /* We can also use incompatible hash with other hashes. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, + tdb = tdb1_open("run-incompatible.tdb", flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &dumbhash_attr); ok1(tdb); @@ -191,14 +191,14 @@ int main(int argc, char *argv[]) /* It should not open if we don't specify. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, 0, O_RDWR, 0, + tdb = tdb1_open("run-incompatible.tdb", 0, O_RDWR, 0, &log_attr); ok1(!tdb); ok1(log_count == 1); /* Should reopen with correct hash. */ log_count = 0; - tdb = tdb1_open("run-incompatible.tdb", 0, 0, O_RDWR, 0, + tdb = tdb1_open("run-incompatible.tdb", 0, O_RDWR, 0, &dumbhash_attr); ok1(tdb); ok1(log_count == 0); diff --git a/ccan/tdb2/test/run-tdb1-nested-transactions.c b/ccan/tdb2/test/run-tdb1-nested-transactions.c index d5886123..79b9b568 100644 --- a/ccan/tdb2/test/run-tdb1-nested-transactions.c +++ b/ccan/tdb2/test/run-tdb1-nested-transactions.c @@ -9,14 +9,19 @@ 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(27); key.dsize = strlen("hi"); key.dptr = (void *)"hi"; tdb = tdb1_open("run-nested-transactions.tdb", - 1024, TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); /* No nesting by default. */ @@ -43,7 +48,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); tdb = tdb1_open("run-nested-transactions.tdb", - 1024, TDB_ALLOW_NESTING, O_RDWR, 0, &tap_log_attr); + TDB_ALLOW_NESTING, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_transaction_start(tdb) == 0); diff --git a/ccan/tdb2/test/run-tdb1-nested-traverse.c b/ccan/tdb2/test/run-tdb1-nested-traverse.c index 1fc8d092..0d58a569 100644 --- a/ccan/tdb2/test/run-tdb1-nested-traverse.c +++ b/ccan/tdb2/test/run-tdb1-nested-traverse.c @@ -50,14 +50,19 @@ 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(17); agent = prepare_external_agent1(); if (!agent) err(1, "preparing agent"); - tdb = tdb1_open("run-nested-traverse.tdb", 1024, TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open("run-nested-traverse.tdb", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); ok1(external_agent_operation1(agent, OPEN, tdb->name) == SUCCESS); diff --git a/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c b/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c index cb1c2360..91926cf8 100644 --- a/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c +++ b/ccan/tdb2/test/run-tdb1-no-lock-during-traverse.c @@ -68,11 +68,16 @@ int main(int argc, char *argv[]) { struct tdb_context *tdb; int errors = 0; + union tdb_attribute hsize; + + hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; + hsize.base.next = &tap_log_attr; + hsize.tdb1_hashsize.hsize = 1024; plan_tests(41); tdb = tdb1_open("run-no-lock-during-traverse.tdb", - 1024, TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, - 0600, &tap_log_attr); + TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, + 0600, &hsize); ok1(tdb); ok1(prepare_entries(tdb)); diff --git a/ccan/tdb2/test/run-tdb1-oldhash.c b/ccan/tdb2/test/run-tdb1-oldhash.c index 5219d5c3..4cc973c0 100644 --- a/ccan/tdb2/test/run-tdb1-oldhash.c +++ b/ccan/tdb2/test/run-tdb1-oldhash.c @@ -17,25 +17,25 @@ int main(int argc, char *argv[]) /* Old format (with zeroes in the hash magic fields) should * open with any hash (since we don't know what hash they used). */ - tdb = tdb1_open("test/old-nohash-le.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/old-nohash-le.tdb1", 0, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - tdb = tdb1_open("test/old-nohash-be.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/old-nohash-be.tdb1", 0, O_RDWR, 0, &tap_log_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - tdb = tdb1_open("test/old-nohash-le.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/old-nohash-le.tdb1", 0, O_RDWR, 0, &incompat_hash_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - tdb = tdb1_open("test/old-nohash-be.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/old-nohash-be.tdb1", 0, O_RDWR, 0, &incompat_hash_attr); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); diff --git a/ccan/tdb2/test/run-tdb1-open-during-transaction.c b/ccan/tdb2/test/run-tdb1-open-during-transaction.c index e0b28a53..fbd539a4 100644 --- a/ccan/tdb2/test/run-tdb1-open-during-transaction.c +++ b/ccan/tdb2/test/run-tdb1-open-during-transaction.c @@ -133,6 +133,11 @@ int main(int argc, char *argv[]) int i; 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(10); agent = prepare_external_agent1(); @@ -145,9 +150,9 @@ int main(int argc, char *argv[]) "DEFAULT", (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap"); unlink(TEST_DBNAME); - tdb = tdb1_open(TEST_DBNAME, 1024, flags[i], + tdb = tdb1_open(TEST_DBNAME, flags[i], O_CREAT|O_TRUNC|O_RDWR, 0600, - &tap_log_attr); + &hsize); ok1(tdb); opened = true; diff --git a/ccan/tdb2/test/run-tdb1-readonly-check.c b/ccan/tdb2/test/run-tdb1-readonly-check.c index 762c576f..b712e48a 100644 --- a/ccan/tdb2/test/run-tdb1-readonly-check.c +++ b/ccan/tdb2/test/run-tdb1-readonly-check.c @@ -10,11 +10,16 @@ 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(11); - tdb = tdb1_open("run-readonly-check.tdb", 1024, + tdb = tdb1_open("run-readonly-check.tdb", TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); key.dsize = strlen("hi"); @@ -30,7 +35,7 @@ int main(int argc, char *argv[]) ok1(tdb1_check(tdb, NULL, NULL) == 0); ok1(tdb1_close(tdb) == 0); - tdb = tdb1_open("run-readonly-check.tdb", 1024, + tdb = tdb1_open("run-readonly-check.tdb", TDB_DEFAULT, O_RDONLY, 0, &tap_log_attr); ok1(tdb); diff --git a/ccan/tdb2/test/run-tdb1-rwlock-check.c b/ccan/tdb2/test/run-tdb1-rwlock-check.c index 6f4406c0..76355e84 100644 --- a/ccan/tdb2/test/run-tdb1-rwlock-check.c +++ b/ccan/tdb2/test/run-tdb1-rwlock-check.c @@ -27,13 +27,13 @@ int main(int argc, char *argv[]) /* We should fail to open rwlock-using tdbs of either endian. */ log_count = 0; - tdb = tdb1_open("test/rwlock-le.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/rwlock-le.tdb1", 0, O_RDWR, 0, &log_attr); ok1(!tdb); ok1(log_count == 1); log_count = 0; - tdb = tdb1_open("test/rwlock-be.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/rwlock-be.tdb1", 0, O_RDWR, 0, &log_attr); ok1(!tdb); ok1(log_count == 1); diff --git a/ccan/tdb2/test/run-tdb1-summary.c b/ccan/tdb2/test/run-tdb1-summary.c index 8b9b74ff..85194c8a 100644 --- a/ccan/tdb2/test/run-tdb1-summary.c +++ b/ccan/tdb2/test/run-tdb1-summary.c @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { - tdb = tdb1_open("run-summary.tdb", 131, flags[i], + tdb = tdb1_open("run-summary.tdb", flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600, NULL); ok1(tdb); if (!tdb) diff --git a/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c b/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c index 0395bff7..3865289a 100644 --- a/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c +++ b/ccan/tdb2/test/run-tdb1-traverse-in-transaction.c @@ -36,6 +36,11 @@ 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(); @@ -43,8 +48,8 @@ int main(int argc, char *argv[]) err(1, "preparing agent"); tdb = tdb1_open("run-traverse-in-transaction.tdb", - 1024, TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, - 0600, &tap_log_attr); + TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, + 0600, &hsize); ok1(tdb); key.dsize = strlen("hi"); diff --git a/ccan/tdb2/test/run-tdb1-wronghash-fail.c b/ccan/tdb2/test/run-tdb1-wronghash-fail.c index 54524fc1..f87ebd7c 100644 --- a/ccan/tdb2/test/run-tdb1-wronghash-fail.c +++ b/ccan/tdb2/test/run-tdb1-wronghash-fail.c @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) /* Create with default hash. */ log_count = 0; - tdb = tdb1_open("run-wronghash-fail.tdb", 0, 0, + tdb = tdb1_open("run-wronghash-fail.tdb", 0, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_attr); ok1(tdb); ok1(log_count == 0); @@ -64,14 +64,14 @@ int main(int argc, char *argv[]) tdb1_close(tdb); /* Fail to open with different hash. */ - tdb = tdb1_open("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, + tdb = tdb1_open("run-wronghash-fail.tdb", 0, O_RDWR, 0, &jhash_attr); ok1(!tdb); ok1(log_count == 1); /* Create with different hash. */ log_count = 0; - tdb = tdb1_open("run-wronghash-fail.tdb", 0, 0, + tdb = tdb1_open("run-wronghash-fail.tdb", 0, O_CREAT|O_RDWR|O_TRUNC, 0600, &jhash_attr); ok1(tdb); @@ -80,26 +80,26 @@ int main(int argc, char *argv[]) /* Endian should be no problem. */ log_count = 0; - tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, O_RDWR, 0, &ohash_attr); ok1(!tdb); ok1(log_count == 1); log_count = 0; - tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, O_RDWR, 0, &ohash_attr); ok1(!tdb); ok1(log_count == 1); log_count = 0; /* Fail to open with old default hash. */ - tdb = tdb1_open("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, + tdb = tdb1_open("run-wronghash-fail.tdb", 0, O_RDWR, 0, &ohash_attr); ok1(!tdb); ok1(log_count == 1); log_count = 0; - tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, 0, O_RDONLY, + tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, O_RDONLY, 0, &incompat_hash_attr); ok1(tdb); ok1(log_count == 0); @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); log_count = 0; - tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, 0, O_RDONLY, + tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, O_RDONLY, 0, &incompat_hash_attr); ok1(tdb); ok1(log_count == 0); @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) /* It should open with jenkins hash if we don't specify. */ log_count = 0; - tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/jenkins-le-hash.tdb1", 0, O_RDWR, 0, &log_attr); ok1(tdb); ok1(log_count == 0); @@ -124,7 +124,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); log_count = 0; - tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, 0, O_RDWR, 0, + tdb = tdb1_open("test/jenkins-be-hash.tdb1", 0, O_RDWR, 0, &log_attr); ok1(tdb); ok1(log_count == 0); @@ -132,7 +132,7 @@ int main(int argc, char *argv[]) tdb1_close(tdb); log_count = 0; - tdb = tdb1_open("run-wronghash-fail.tdb", 0, 0, O_RDONLY, + tdb = tdb1_open("run-wronghash-fail.tdb", 0, O_RDONLY, 0, &log_attr); ok1(tdb); ok1(log_count == 0); diff --git a/ccan/tdb2/test/run-tdb1-zero-append.c b/ccan/tdb2/test/run-tdb1-zero-append.c index 3541fe08..9b5c8bc0 100644 --- a/ccan/tdb2/test/run-tdb1-zero-append.c +++ b/ccan/tdb2/test/run-tdb1-zero-append.c @@ -8,10 +8,15 @@ 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(4); - tdb = tdb1_open(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, - 0600, &tap_log_attr); + tdb = tdb1_open(NULL, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, + 0600, &hsize); ok1(tdb); /* Tickle bug on appending zero length buffer to zero length buffer. */ diff --git a/ccan/tdb2/test/run-tdb1.c b/ccan/tdb2/test/run-tdb1.c index d206545c..913b66c1 100644 --- a/ccan/tdb2/test/run-tdb1.c +++ b/ccan/tdb2/test/run-tdb1.c @@ -8,10 +8,15 @@ 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(10); - tdb = tdb1_open("run.tdb", 1024, TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); + tdb = tdb1_open("run.tdb", TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); ok1(tdb); key.dsize = strlen("hi"); diff --git a/ccan/tdb2/test/tdb1-external-agent.c b/ccan/tdb2/test/tdb1-external-agent.c index dcd825dc..44bdecea 100644 --- a/ccan/tdb2/test/tdb1-external-agent.c +++ b/ccan/tdb2/test/tdb1-external-agent.c @@ -39,7 +39,7 @@ static enum agent_return do_operation(enum operation op, const char *name) diag("Already have tdb %s open", tdb->name); return OTHER_FAILURE; } - tdb = tdb1_open(name, 0, TDB_DEFAULT, O_RDWR, 0, + tdb = tdb1_open(name, TDB_DEFAULT, O_RDWR, 0, &tap_log_attr); if (!tdb) { if (!locking_would_block1)