diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/tdb2/tdb1.h | 3 | ||||
-rw-r--r-- | lib/tdb2/tdb1_hash.c | 2 | ||||
-rw-r--r-- | lib/tdb2/tdb1_open.c | 47 | ||||
-rw-r--r-- | lib/tdb2/test/run-tdb1-incompatible.c | 38 | ||||
-rw-r--r-- | lib/tdb2/test/run-tdb1-oldhash.c | 4 | ||||
-rw-r--r-- | lib/tdb2/test/run-tdb1-wronghash-fail.c | 26 |
6 files changed, 72 insertions, 48 deletions
diff --git a/lib/tdb2/tdb1.h b/lib/tdb2/tdb1.h index b2435ba53e..3869373fbe 100644 --- a/lib/tdb2/tdb1.h +++ b/lib/tdb2/tdb1.h @@ -49,7 +49,6 @@ #define TDB1_VOLATILE 256 /** Activate the per-hashchain freelist, default 5 */ #define TDB1_ALLOW_NESTING 512 /** Allow transactions to nest */ #define TDB1_DISALLOW_NESTING 1024 /** Disallow transactions to nest */ -#define TDB1_INCOMPATIBLE_HASH 2048 /** Better hashing: can't be opened by tdb < 1.2.6. */ /** This is the context structure that is returned from a db open. */ typedef struct tdb1_context TDB1_CONTEXT; @@ -121,7 +120,7 @@ int tdb1_hash_size(struct tdb1_context *tdb); void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb); -unsigned int tdb1_jenkins_hash(TDB_DATA *key); +unsigned int tdb1_incompatible_hash(TDB_DATA *key); int tdb1_check(struct tdb1_context *tdb, int (*check) (TDB_DATA key, TDB_DATA data, void *private_data), diff --git a/lib/tdb2/tdb1_hash.c b/lib/tdb2/tdb1_hash.c index 50e49505ca..886577da70 100644 --- a/lib/tdb2/tdb1_hash.c +++ b/lib/tdb2/tdb1_hash.c @@ -339,7 +339,7 @@ static uint32_t hashlittle( const void *key, size_t length ) return c; } -unsigned int tdb1_jenkins_hash(TDB_DATA *key) +unsigned int tdb1_incompatible_hash(TDB_DATA *key) { return hashlittle(key->dptr, key->dsize); } diff --git a/lib/tdb2/tdb1_open.c b/lib/tdb2/tdb1_open.c index 30c11956ac..f53a32b5be 100644 --- a/lib/tdb2/tdb1_open.c +++ b/lib/tdb2/tdb1_open.c @@ -72,7 +72,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) /* Make sure older tdbs (which don't check the magic hash fields) * will refuse to open this TDB. */ - if (tdb->flags & TDB1_INCOMPATIBLE_HASH) + if (tdb->hash_fn == tdb1_incompatible_hash) newdb->rwlocks = TDB1_HASH_RWLOCK_MAGIC; if (tdb->flags & TDB1_INTERNAL) { @@ -135,25 +135,28 @@ struct tdb1_context *tdb1_open(const char *name, int hash_size, int tdb1_flags, return tdb1_open_ex(name, hash_size, tdb1_flags, open_flags, mode, NULL, NULL); } -static bool check_header_hash(struct tdb1_context *tdb, - bool default_hash, uint32_t *m1, uint32_t *m2) +static bool hash_correct(struct tdb1_context *tdb, + uint32_t *m1, uint32_t *m2) { tdb1_header_hash(tdb, m1, m2); - if (tdb->header.magic1_hash == *m1 && - tdb->header.magic2_hash == *m2) { - return true; - } + return (tdb->header.magic1_hash == *m1 && + tdb->header.magic2_hash == *m2); +} - /* If they explicitly set a hash, always respect it. */ - if (!default_hash) - return false; +static bool check_header_hash(struct tdb1_context *tdb, + uint32_t *m1, uint32_t *m2) +{ + if (hash_correct(tdb, m1, m2)) + return true; - /* Otherwise, try the other inbuilt hash. */ + /* If they use one inbuilt, try the other inbuilt hash. */ if (tdb->hash_fn == tdb1_old_hash) - tdb->hash_fn = tdb1_jenkins_hash; - else + tdb->hash_fn = tdb1_incompatible_hash; + else if (tdb->hash_fn == tdb1_incompatible_hash) tdb->hash_fn = tdb1_old_hash; - return check_header_hash(tdb, false, m1, m2); + else + return false; + return hash_correct(tdb, m1, m2); } struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flags, @@ -216,15 +219,13 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag if (hash_fn) { tdb->hash_fn = hash_fn; - hash_alg = "the user defined"; + if (hash_fn == tdb1_incompatible_hash) + hash_alg = "tdb1_incompatible_hash"; + else + hash_alg = "the user defined"; } else { - /* This controls what we use when creating a tdb. */ - if (tdb->flags & TDB1_INCOMPATIBLE_HASH) { - tdb->hash_fn = tdb1_jenkins_hash; - } else { - tdb->hash_fn = tdb1_old_hash; - } - hash_alg = "either default"; + tdb->hash_fn = tdb1_old_hash; + hash_alg = "default"; } /* cache the page size */ @@ -353,7 +354,7 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag if ((tdb->header.magic1_hash == 0) && (tdb->header.magic2_hash == 0)) { /* older TDB without magic hash references */ tdb->hash_fn = tdb1_old_hash; - } else if (!check_header_hash(tdb, !hash_fn, &magic1, &magic2)) { + } else if (!check_header_hash(tdb, &magic1, &magic2)) { tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_USE_ERROR, "tdb1_open_ex: " "%s was not created with %s hash function we are using\n" diff --git a/lib/tdb2/test/run-tdb1-incompatible.c b/lib/tdb2/test/run-tdb1-incompatible.c index 51aa52d4b7..6f3aee0336 100644 --- a/lib/tdb2/test/run-tdb1-incompatible.c +++ b/lib/tdb2/test/run-tdb1-incompatible.c @@ -31,6 +31,16 @@ static unsigned int hdr_rwlocks(const char *fname) return hdr.rwlocks; } +static unsigned int jenkins_hashfn(TDB_DATA *key) +{ + return hashlittle(key->dptr, key->dsize); +} + +static unsigned int old_hash(TDB_DATA *key) +{ + return tdb1_old_hash(key); +} + int main(int argc, char *argv[]) { struct tdb1_context *tdb; @@ -61,11 +71,12 @@ int main(int argc, char *argv[]) /* Should not have marked rwlocks field. */ ok1(hdr_rwlocks("run-incompatible.tdb") == 0); - /* We can still open any old-style with incompat flag. */ + /* We can still open any old-style with incompat hash. */ log_count = 0; tdb = tdb1_open_ex("run-incompatible.tdb", 0, - TDB1_INCOMPATIBLE_HASH, - O_RDWR, 0600, &log_ctx, NULL); + TDB_DEFAULT, + O_RDWR, 0600, &log_ctx, + tdb1_incompatible_hash); ok1(tdb); ok1(log_count == 0); d = tdb1_fetch(tdb, d); @@ -76,7 +87,7 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb1_open_ex("test/jenkins-le-hash.tdb1", 0, 0, O_RDONLY, - 0, &log_ctx, tdb1_jenkins_hash); + 0, &log_ctx, jenkins_hashfn); ok1(tdb); ok1(log_count == 0); ok1(tdb1_check(tdb, NULL, NULL) == 0); @@ -84,18 +95,18 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb1_open_ex("test/jenkins-be-hash.tdb1", 0, 0, O_RDONLY, - 0, &log_ctx, tdb1_jenkins_hash); + 0, &log_ctx, jenkins_hashfn); ok1(tdb); ok1(log_count == 0); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); - /* OK, now create with incompatible flag, default hash. */ + /* OK, now create with incompatible hash. */ log_count = 0; tdb = tdb1_open_ex("run-incompatible.tdb", 0, - flags|TDB1_INCOMPATIBLE_HASH, + flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, - NULL); + tdb1_incompatible_hash); ok1(tdb); ok1(log_count == 0); d.dptr = (void *)"Hello"; @@ -109,14 +120,14 @@ int main(int argc, char *argv[]) /* Cannot open with old hash. */ log_count = 0; tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0, - O_RDWR, 0600, &log_ctx, tdb1_old_hash); + O_RDWR, 0600, &log_ctx, old_hash); ok1(!tdb); ok1(log_count == 1); /* Can open with jenkins hash. */ log_count = 0; tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0, - O_RDWR, 0600, &log_ctx, tdb1_jenkins_hash); + O_RDWR, 0600, &log_ctx, jenkins_hashfn); ok1(tdb); ok1(log_count == 0); d = tdb1_fetch(tdb, d); @@ -139,10 +150,11 @@ int main(int argc, char *argv[]) ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); + /* FIXME: Not possible with TDB2 :( */ /* We can also use incompatible hash with other hashes. */ log_count = 0; tdb = tdb1_open_ex("run-incompatible.tdb", 0, - flags|TDB1_INCOMPATIBLE_HASH, + flags, O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, tdb1_dumb_hash); ok1(tdb); @@ -152,8 +164,8 @@ int main(int argc, char *argv[]) ok1(tdb1_store(tdb, d, d, TDB_INSERT) == 0); tdb1_close(tdb); - /* Should have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); + /* FIXME: Should have marked rwlocks field. */ + ok1(hdr_rwlocks("run-incompatible.tdb") != rwmagic); /* It should not open if we don't specify. */ log_count = 0; diff --git a/lib/tdb2/test/run-tdb1-oldhash.c b/lib/tdb2/test/run-tdb1-oldhash.c index 32b4200d54..4f74dbb95b 100644 --- a/lib/tdb2/test/run-tdb1-oldhash.c +++ b/lib/tdb2/test/run-tdb1-oldhash.c @@ -25,13 +25,13 @@ int main(int argc, char *argv[]) tdb1_close(tdb); tdb = tdb1_open_ex("test/old-nohash-le.tdb1", 0, 0, O_RDWR, 0, - &taplogctx, tdb1_jenkins_hash); + &taplogctx, tdb1_incompatible_hash); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); tdb = tdb1_open_ex("test/old-nohash-be.tdb1", 0, 0, O_RDWR, 0, - &taplogctx, tdb1_jenkins_hash); + &taplogctx, tdb1_incompatible_hash); ok1(tdb); ok1(tdb1_check(tdb, NULL, NULL) == 0); tdb1_close(tdb); diff --git a/lib/tdb2/test/run-tdb1-wronghash-fail.c b/lib/tdb2/test/run-tdb1-wronghash-fail.c index 368835ed7f..97a8293e7d 100644 --- a/lib/tdb2/test/run-tdb1-wronghash-fail.c +++ b/lib/tdb2/test/run-tdb1-wronghash-fail.c @@ -11,6 +11,18 @@ static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level, (*count)++; } +static unsigned int jenkins_hashfn(TDB_DATA *key) +{ + return hashlittle(key->dptr, key->dsize); +} + +/* the tdb1_old_hash function is "magic" as it automatically makes us test the + * tdb1_incompatible_hash as well, so use this wrapper. */ +static unsigned int old_hash(TDB_DATA *key) +{ + return tdb1_old_hash(key); +} + int main(int argc, char *argv[]) { struct tdb1_context *tdb; @@ -33,7 +45,7 @@ int main(int argc, char *argv[]) /* Fail to open with different hash. */ tdb = tdb1_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb1_jenkins_hash); + &log_ctx, jenkins_hashfn); ok1(!tdb); ok1(log_count == 1); @@ -41,7 +53,7 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb1_open_ex("run-wronghash-fail.tdb", 0, 0, O_CREAT|O_RDWR|O_TRUNC, - 0600, &log_ctx, tdb1_jenkins_hash); + 0600, &log_ctx, jenkins_hashfn); ok1(tdb); ok1(log_count == 0); tdb1_close(tdb); @@ -49,26 +61,26 @@ int main(int argc, char *argv[]) /* Endian should be no problem. */ log_count = 0; tdb = tdb1_open_ex("test/jenkins-le-hash.tdb1", 0, 0, O_RDWR, 0, - &log_ctx, tdb1_old_hash); + &log_ctx, old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb1_open_ex("test/jenkins-be-hash.tdb1", 0, 0, O_RDWR, 0, - &log_ctx, tdb1_old_hash); + &log_ctx, old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; /* Fail to open with old default hash. */ tdb = tdb1_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb1_old_hash); + &log_ctx, old_hash); ok1(!tdb); ok1(log_count == 1); log_count = 0; tdb = tdb1_open_ex("test/jenkins-le-hash.tdb1", 0, 0, O_RDONLY, - 0, &log_ctx, tdb1_jenkins_hash); + 0, &log_ctx, tdb1_incompatible_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb1_check(tdb, NULL, NULL) == 0); @@ -76,7 +88,7 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb1_open_ex("test/jenkins-be-hash.tdb1", 0, 0, O_RDONLY, - 0, &log_ctx, tdb1_jenkins_hash); + 0, &log_ctx, tdb1_incompatible_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb1_check(tdb, NULL, NULL) == 0); |