summaryrefslogtreecommitdiff
path: root/lib/tdb2
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tdb2')
-rw-r--r--lib/tdb2/tdb1.h3
-rw-r--r--lib/tdb2/tdb1_hash.c2
-rw-r--r--lib/tdb2/tdb1_open.c47
-rw-r--r--lib/tdb2/test/run-tdb1-incompatible.c38
-rw-r--r--lib/tdb2/test/run-tdb1-oldhash.c4
-rw-r--r--lib/tdb2/test/run-tdb1-wronghash-fail.c26
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);