diff options
95 files changed, 160 insertions, 8164 deletions
diff --git a/lib/tdb2/ABI/tdb-2.0.1.sigs b/lib/tdb2/ABI/tdb-2.0.1.sigs new file mode 100644 index 0000000000..f9ee55f84a --- /dev/null +++ b/lib/tdb2/ABI/tdb-2.0.1.sigs @@ -0,0 +1,39 @@ +tdb_add_flag: void (struct tdb_context *, unsigned int) +tdb_append: enum TDB_ERROR (struct tdb_context *, struct tdb_data, struct tdb_data) +tdb_chainlock: enum TDB_ERROR (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: enum TDB_ERROR (struct tdb_context *, TDB_DATA) +tdb_chainunlock: void (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: void (struct tdb_context *, TDB_DATA) +tdb_check_: enum TDB_ERROR (struct tdb_context *, enum TDB_ERROR (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: enum TDB_ERROR (struct tdb_context *, struct tdb_data) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(enum TDB_ERROR) +tdb_exists: bool (struct tdb_context *, TDB_DATA) +tdb_fd: int (const struct tdb_context *) +tdb_fetch: enum TDB_ERROR (struct tdb_context *, struct tdb_data, struct tdb_data *) +tdb_firstkey: enum TDB_ERROR (struct tdb_context *, struct tdb_data *) +tdb_foreach_: void (int (*)(struct tdb_context *, void *), void *) +tdb_get_attribute: enum TDB_ERROR (struct tdb_context *, union tdb_attribute *) +tdb_get_flags: unsigned int (struct tdb_context *) +tdb_get_seqnum: int64_t (struct tdb_context *) +tdb_lockall: enum TDB_ERROR (struct tdb_context *) +tdb_lockall_read: enum TDB_ERROR (struct tdb_context *) +tdb_name: const char *(const struct tdb_context *) +tdb_nextkey: enum TDB_ERROR (struct tdb_context *, struct tdb_data *) +tdb_open: struct tdb_context *(const char *, int, int, mode_t, union tdb_attribute *) +tdb_parse_record_: enum TDB_ERROR (struct tdb_context *, TDB_DATA, enum TDB_ERROR (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_remove_flag: void (struct tdb_context *, unsigned int) +tdb_repack: enum TDB_ERROR (struct tdb_context *) +tdb_set_attribute: enum TDB_ERROR (struct tdb_context *, const union tdb_attribute *) +tdb_store: enum TDB_ERROR (struct tdb_context *, struct tdb_data, struct tdb_data, int) +tdb_summary: enum TDB_ERROR (struct tdb_context *, enum tdb_summary_flags, char **) +tdb_transaction_cancel: void (struct tdb_context *) +tdb_transaction_commit: enum TDB_ERROR (struct tdb_context *) +tdb_transaction_prepare_commit: enum TDB_ERROR (struct tdb_context *) +tdb_transaction_start: enum TDB_ERROR (struct tdb_context *) +tdb_traverse_: int64_t (struct tdb_context *, int (*)(struct tdb_context *, TDB_DATA, TDB_DATA, void *), void *) +tdb_unlockall: void (struct tdb_context *) +tdb_unlockall_read: void (struct tdb_context *) +tdb_unset_attribute: void (struct tdb_context *, enum tdb_attribute_type) +tdb_wipe_all: enum TDB_ERROR (struct tdb_context *) diff --git a/lib/tdb2/check.c b/lib/tdb2/check.c index 9fe60e5409..e6c815815c 100644 --- a/lib/tdb2/check.c +++ b/lib/tdb2/check.c @@ -810,12 +810,6 @@ _PUBLIC_ enum TDB_ERROR tdb_check_(struct tdb_context *tdb, " cannot check."); } - if (tdb->flags & TDB_VERSION1) { - if (tdb1_check(tdb, check, data) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - ecode = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); if (ecode != TDB_SUCCESS) { return tdb->last_error = ecode; diff --git a/lib/tdb2/hash.c b/lib/tdb2/hash.c index 0d4d7805ce..067884a74e 100644 --- a/lib/tdb2/hash.c +++ b/lib/tdb2/hash.c @@ -853,11 +853,6 @@ static enum TDB_ERROR chainlock(struct tdb_context *tdb, const TDB_DATA *key, contention - it cannot guarantee how many records will be locked */ _PUBLIC_ enum TDB_ERROR tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) { - if (tdb->flags & TDB_VERSION1) { - if (tdb1_chainlock(tdb, key) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } return tdb->last_error = chainlock(tdb, &key, F_WRLCK, TDB_LOCK_WAIT, "tdb_chainlock"); } @@ -868,11 +863,6 @@ _PUBLIC_ void tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) tdb_off_t lockstart, locksize; unsigned int group, gbits; - if (tdb->flags & TDB_VERSION1) { - tdb1_chainunlock(tdb, key); - return; - } - gbits = TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS; group = bits_from(h, 64 - gbits, gbits); @@ -884,11 +874,6 @@ _PUBLIC_ void tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) _PUBLIC_ enum TDB_ERROR tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) { - if (tdb->flags & TDB_VERSION1) { - if (tdb1_chainlock_read(tdb, key) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } return tdb->last_error = chainlock(tdb, &key, F_RDLCK, TDB_LOCK_WAIT, "tdb_chainlock_read"); } @@ -899,10 +884,6 @@ _PUBLIC_ void tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) tdb_off_t lockstart, locksize; unsigned int group, gbits; - if (tdb->flags & TDB_VERSION1) { - tdb1_chainunlock_read(tdb, key); - return; - } gbits = TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS; group = bits_from(h, 64 - gbits, gbits); diff --git a/lib/tdb2/io.c b/lib/tdb2/io.c index e27a9fe832..7308d2bf44 100644 --- a/lib/tdb2/io.c +++ b/lib/tdb2/io.c @@ -611,11 +611,6 @@ void tdb_inc_seqnum(struct tdb_context *tdb) { tdb_off_t seq; - if (tdb->flags & TDB_VERSION1) { - tdb1_increment_seqnum_nonblock(tdb); - return; - } - if (likely(!(tdb->flags & TDB_CONVERT))) { int64_t *direct; diff --git a/lib/tdb2/lock.c b/lib/tdb2/lock.c index df0ec0c208..bf6cf7d388 100644 --- a/lib/tdb2/lock.c +++ b/lib/tdb2/lock.c @@ -346,9 +346,8 @@ enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb, struct tdb_lock *new_lck; enum TDB_ERROR ecode; - if (!(tdb->flags & TDB_VERSION1) - && offset > (TDB_HASH_LOCK_START + TDB_HASH_LOCK_RANGE - + tdb->file->map_size / 8)) { + if (offset > (TDB_HASH_LOCK_START + TDB_HASH_LOCK_RANGE + + tdb->file->map_size / 8)) { return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, "tdb_nest_lock: invalid offset %zu ltype=%d", (size_t)offset, ltype); @@ -533,12 +532,6 @@ enum TDB_ERROR tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum TDB_ERROR ecode; tdb_bool_err berr; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_allrecord_lock(tdb, ltype, flags, upgradable) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - if (tdb->flags & TDB_NOLOCK) return TDB_SUCCESS; @@ -653,11 +646,6 @@ void tdb_unlock_expand(struct tdb_context *tdb, int ltype) /* unlock entire db */ void tdb_allrecord_unlock(struct tdb_context *tdb, int ltype) { - if (tdb->flags & TDB_VERSION1) { - tdb1_allrecord_unlock(tdb, ltype); - return; - } - if (tdb->flags & TDB_NOLOCK) return; diff --git a/lib/tdb2/open.c b/lib/tdb2/open.c index b93fa831a0..023dc7fe7d 100644 --- a/lib/tdb2/open.c +++ b/lib/tdb2/open.c @@ -221,7 +221,6 @@ _PUBLIC_ 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, @@ -231,9 +230,7 @@ _PUBLIC_ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, ? "TDB_ATTRIBUTE_HASH" : attr->base.attr == TDB_ATTRIBUTE_SEED ? "TDB_ATTRIBUTE_SEED" - : attr->base.attr == TDB_ATTRIBUTE_OPENHOOK - ? "TDB_ATTRIBUTE_OPENHOOK" - : "TDB_ATTRIBUTE_TDB1_HASHSIZE"); + : "TDB_ATTRIBUTE_OPENHOOK"); case TDB_ATTRIBUTE_STATS: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -271,13 +268,6 @@ _PUBLIC_ enum TDB_ERROR tdb_get_attribute(struct tdb_context *tdb, attr->hash.data = tdb->hash_data; break; case TDB_ATTRIBUTE_SEED: - 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_SEED" - " on TDB1 tdb."); attr->seed.seed = tdb->hash_seed; break; case TDB_ATTRIBUTE_OPENHOOK: @@ -298,16 +288,6 @@ _PUBLIC_ 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, @@ -332,14 +312,11 @@ _PUBLIC_ 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" - : type == TDB_ATTRIBUTE_SEED - ? "TDB_ATTRIBUTE_SEED" - : "TDB_ATTRIBUTE_TDB1_HASHSIZE"); + : "TDB_ATTRIBUTE_SEED"); break; case TDB_ATTRIBUTE_STATS: tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -359,23 +336,6 @@ _PUBLIC_ void tdb_unset_attribute(struct tdb_context *tdb, } } -static bool is_tdb1(struct tdb1_header *hdr, const void *buf, ssize_t rlen) -{ - /* This code assumes we've tried to read entire tdb1 header. */ - BUILD_ASSERT(sizeof(*hdr) <= sizeof(struct tdb_header)); - - if (rlen < (ssize_t)sizeof(*hdr)) { - return false; - } - - memcpy(hdr, buf, sizeof(*hdr)); - if (strcmp(hdr->magic_food, TDB_MAGIC_FOOD) != 0) - return false; - - return hdr->version == TDB1_VERSION - || hdr->version == TDB1_BYTEREV(TDB1_VERSION); -} - /* The top three bits of the capability tell us whether it matters. */ enum TDB_ERROR unknown_capability(struct tdb_context *tdb, const char *caller, tdb_off_t type) @@ -436,8 +396,6 @@ _PUBLIC_ 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; - struct tdb_attribute_tdb1_max_dead *maxsize_attr = NULL; tdb_bool_err berr; enum TDB_ERROR ecode; int openlock; @@ -480,12 +438,6 @@ _PUBLIC_ 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; - case TDB_ATTRIBUTE_TDB1_MAX_DEAD: - maxsize_attr = &attr->tdb1_max_dead; - break; default: /* These are set as normal. */ ecode = tdb_set_attribute(tdb, attr); @@ -497,34 +449,14 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, if (tdb_flags & ~(TDB_INTERNAL | TDB_NOLOCK | TDB_NOMMAP | TDB_CONVERT | TDB_NOSYNC | TDB_SEQNUM | TDB_ALLOW_NESTING - | TDB_RDONLY | TDB_VERSION1)) { + | TDB_RDONLY)) { ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_open: unknown flags %u", 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 (seed) { - if (tdb_flags & TDB_VERSION1) { - ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, - TDB_LOG_USE_ERROR, - "tdb_open:" - " cannot set TDB_ATTRIBUTE_SEED" - " on TDB1 tdb."); - goto fail; - } else if (!(tdb_flags & TDB_INTERNAL) - && !(open_flags & O_CREAT)) { + if (!(tdb_flags & TDB_INTERNAL) && !(open_flags & O_CREAT)) { ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_open:" @@ -563,17 +495,13 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } tdb->file->fd = -1; - if (tdb->flags & TDB_VERSION1) - ecode = tdb1_new_database(tdb, hsize_attr, maxsize_attr); - else { - ecode = tdb_new_database(tdb, seed, &hdr); - if (ecode == TDB_SUCCESS) { - tdb_convert(tdb, &hdr.hash_seed, - sizeof(hdr.hash_seed)); - tdb->hash_seed = hdr.hash_seed; - tdb2_context_init(tdb); - tdb_ftable_init(tdb); - } + ecode = tdb_new_database(tdb, seed, &hdr); + if (ecode == TDB_SUCCESS) { + tdb_convert(tdb, &hdr.hash_seed, + sizeof(hdr.hash_seed)); + tdb->hash_seed = hdr.hash_seed; + tdb2_context_init(tdb); + tdb_ftable_init(tdb); } if (ecode != TDB_SUCCESS) { goto fail; @@ -643,12 +571,6 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, /* If they used O_TRUNC, read will return 0. */ rlen = pread(tdb->file->fd, &hdr, sizeof(hdr), 0); if (rlen == 0 && (open_flags & O_CREAT)) { - if (tdb->flags & TDB_VERSION1) { - ecode = tdb1_new_database(tdb, hsize_attr, maxsize_attr); - if (ecode != TDB_SUCCESS) - goto fail; - goto finished; - } ecode = tdb_new_database(tdb, seed, &hdr); if (ecode != TDB_SUCCESS) { goto fail; @@ -660,14 +582,8 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } else if (rlen < sizeof(hdr) || strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) { - if (is_tdb1(&tdb->tdb1.header, &hdr, rlen)) { - ecode = tdb1_open(tdb, maxsize_attr); - if (!ecode) - goto finished; - goto fail; - } ecode = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb_open: %s is not a tdb file", name); + "tdb_open: %s is not a tdb2 file", name); goto fail; } @@ -675,12 +591,6 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, if (hdr.version == bswap_64(TDB_VERSION)) tdb->flags |= TDB_CONVERT; else { - if (is_tdb1(&tdb->tdb1.header, &hdr, rlen)) { - ecode = tdb1_open(tdb, maxsize_attr); - if (!ecode) - goto finished; - goto fail; - } /* wrong version */ ecode = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, "tdb_open:" @@ -696,11 +606,6 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } - /* This is a version2 tdb. */ - if (tdb->flags & TDB_VERSION1) { - tdb->flags &= ~TDB_VERSION1; - } - tdb2_context_init(tdb); tdb_convert(tdb, &hdr, sizeof(hdr)); @@ -732,46 +637,31 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } -finished: - if (tdb->flags & TDB_VERSION1) { - /* if needed, run recovery */ - if (tdb1_transaction_recover(tdb) == -1) { - ecode = tdb->last_error; - goto fail; - } - } - tdb_unlock_open(tdb, openlock); /* This makes sure we have current map_size and mmap. */ - if (tdb->flags & TDB_VERSION1) { - ecode = tdb1_probe_length(tdb); - } else { - ecode = tdb->tdb2.io->oob(tdb, tdb->file->map_size, 1, true); - } + ecode = tdb->tdb2.io->oob(tdb, tdb->file->map_size, 1, true); if (unlikely(ecode != TDB_SUCCESS)) goto fail; - if (!(tdb->flags & TDB_VERSION1)) { - /* Now it's fully formed, recover if necessary. */ - berr = tdb_needs_recovery(tdb); - if (unlikely(berr != false)) { - if (berr < 0) { - ecode = TDB_OFF_TO_ERR(berr); - goto fail; - } - ecode = tdb_lock_and_recover(tdb); - if (ecode != TDB_SUCCESS) { - goto fail; - } + /* Now it's fully formed, recover if necessary. */ + berr = tdb_needs_recovery(tdb); + if (unlikely(berr != false)) { + if (berr < 0) { + ecode = TDB_OFF_TO_ERR(berr); + goto fail; } - - ecode = tdb_ftable_init(tdb); + ecode = tdb_lock_and_recover(tdb); if (ecode != TDB_SUCCESS) { goto fail; } } + ecode = tdb_ftable_init(tdb); + if (ecode != TDB_SUCCESS) { + goto fail; + } + tdb->next = tdbs; tdbs = tdb; return tdb; @@ -832,14 +722,8 @@ _PUBLIC_ int tdb_close(struct tdb_context *tdb) tdb_trace(tdb, "tdb_close"); - if (tdb->flags & TDB_VERSION1) { - if (tdb->tdb1.transaction) { - tdb1_transaction_cancel(tdb); - } - } else { - if (tdb->tdb2.transaction) { - tdb_transaction_cancel(tdb); - } + if (tdb->tdb2.transaction) { + tdb_transaction_cancel(tdb); } if (tdb->file->map_ptr) { diff --git a/lib/tdb2/private.h b/lib/tdb2/private.h index 0ee8fa4f09..da0454b4de 100644 --- a/lib/tdb2/private.h +++ b/lib/tdb2/private.h @@ -72,7 +72,6 @@ typedef uint64_t tdb_off_t; #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION ((uint64_t)(0x26011967 + 7)) -#define TDB1_VERSION (0x26011967 + 6) #define TDB_USED_MAGIC ((uint64_t)0x1999) #define TDB_HTABLE_MAGIC ((uint64_t)0x1888) #define TDB_CHAIN_MAGIC ((uint64_t)0x1777) @@ -306,9 +305,6 @@ struct traverse_info { tdb_off_t prev; }; -typedef uint32_t tdb1_len_t; -typedef uint32_t tdb1_off_t; - enum tdb_lock_flags { /* WAIT == F_SETLKW, NOWAIT == F_SETLK */ TDB_LOCK_NOWAIT = 0, @@ -578,26 +574,6 @@ int tdb_fcntl_unlock(int fd, int rw, off_t off, off_t len, void *); enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb); tdb_bool_err tdb_needs_recovery(struct tdb_context *tdb); -/* this is stored at the front of every database */ -struct tdb1_header { - char magic_food[32]; /* for /etc/magic */ - uint32_t version; /* version of the code */ - uint32_t hash_size; /* number of hash entries */ - tdb1_off_t rwlocks; /* obsolete - kept to detect old formats */ - tdb1_off_t recovery_start; /* offset of transaction recovery region */ - tdb1_off_t sequence_number; /* used when TDB1_SEQNUM is set */ - uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */ - uint32_t magic2_hash; /* hash of TDB1_MAGIC. */ - tdb1_off_t reserved[27]; -}; - -struct tdb1_traverse_lock { - struct tdb1_traverse_lock *next; - uint32_t off; - uint32_t hash; - int lock_rw; -}; - struct tdb_context { /* Single list of all TDBs, to detect multiple opens. */ struct tdb_context *next; @@ -660,85 +636,8 @@ struct tdb_context { /* Direct access information */ struct tdb_access_hdr *access; } tdb2; - - struct { - int traverse_read; /* read-only traversal */ - int traverse_write; /* read-write traversal */ - - struct tdb1_header header; /* a cached copy of the header */ - struct tdb1_traverse_lock travlocks; /* current traversal locks */ - const struct tdb1_methods *io; - struct tdb1_transaction *transaction; - int page_size; - int max_dead_records; - } tdb1; }; -#define TDB1_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) - -/* tdb1_check.c: */ -int tdb1_check(struct tdb_context *tdb, - enum TDB_ERROR (*check)(TDB_DATA key, TDB_DATA data, void *), - void *private_data); - - -/* tdb1_open.c: */ -enum TDB_ERROR tdb1_new_database(struct tdb_context *tdb, - struct tdb_attribute_tdb1_hashsize *hashsize, - struct tdb_attribute_tdb1_max_dead *max_dead); -enum TDB_ERROR tdb1_open(struct tdb_context *tdb, - struct tdb_attribute_tdb1_max_dead *max_dead); - -/* tdb1_io.c: */ -enum TDB_ERROR tdb1_probe_length(struct tdb_context *tdb); - -/* tdb1_lock.c: */ -int tdb1_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags, bool upgradable); -int tdb1_allrecord_unlock(struct tdb_context *tdb, int ltype); - -int tdb1_chainlock(struct tdb_context *tdb, TDB_DATA key); -int tdb1_chainunlock(struct tdb_context *tdb, TDB_DATA key); -int tdb1_chainlock_read(struct tdb_context *tdb, TDB_DATA key); -int tdb1_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); - -/* tdb1_transaction.c: */ -int tdb1_transaction_recover(struct tdb_context *tdb); -int tdb1_transaction_cancel(struct tdb_context *tdb); - -/* tdb1_traverse.c: */ -int tdb1_traverse(struct tdb_context *tdb, - int (*)(struct tdb_context *, TDB_DATA, TDB_DATA, void *), - void *private_data); - -/* tdb1_summary.c: */ -char *tdb1_summary(struct tdb_context *tdb); - -/* tdb1_tdb.c: */ -int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -enum TDB_ERROR tdb1_fetch(struct tdb_context *tdb, TDB_DATA key, - TDB_DATA *data); -int tdb1_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); -int tdb1_delete(struct tdb_context *tdb, TDB_DATA key); -int tdb1_exists(struct tdb_context *tdb, TDB_DATA key); -enum TDB_ERROR tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key, - enum TDB_ERROR (*parser)(TDB_DATA key, - TDB_DATA data, - void *private_data), - void *private_data); -void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb); -int tdb1_get_seqnum(struct tdb_context *tdb); -int tdb1_wipe_all(struct tdb_context *tdb); - -/* tdb1_transaction.c: */ -int tdb1_transaction_start(struct tdb_context *tdb); -int tdb1_transaction_prepare_commit(struct tdb_context *tdb); -int tdb1_transaction_commit(struct tdb_context *tdb); - -/* tdb1_traverse.c: */ -TDB_DATA tdb1_firstkey(struct tdb_context *tdb); -TDB_DATA tdb1_nextkey(struct tdb_context *tdb, TDB_DATA key); - /* tdb.c: */ enum TDB_ERROR COLD PRINTF_FMT(4, 5) tdb_logerr(struct tdb_context *tdb, diff --git a/lib/tdb2/summary.c b/lib/tdb2/summary.c index 4a1d688727..c7e93284e0 100644 --- a/lib/tdb2/summary.c +++ b/lib/tdb2/summary.c @@ -205,14 +205,6 @@ _PUBLIC_ enum TDB_ERROR tdb_summary(struct tdb_context *tdb, char *hashesg, *freeg, *keysg, *datag, *extrag, *uncoalg; enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) { - /* tdb1 doesn't do graphs. */ - *summary = tdb1_summary(tdb); - if (!*summary) - return tdb->last_error; - return TDB_SUCCESS; - } - hashesg = freeg = keysg = datag = extrag = uncoalg = NULL; ecode = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); diff --git a/lib/tdb2/tdb.c b/lib/tdb2/tdb.c index 4ba6924645..98d1ad6c66 100644 --- a/lib/tdb2/tdb.c +++ b/lib/tdb2/tdb.c @@ -116,12 +116,6 @@ _PUBLIC_ enum TDB_ERROR tdb_store(struct tdb_context *tdb, struct tdb_used_record rec; enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_store(tdb, key, dbuf, flag) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { return tdb->last_error = TDB_OFF_TO_ERR(off); @@ -185,12 +179,6 @@ _PUBLIC_ enum TDB_ERROR tdb_append(struct tdb_context *tdb, struct tdb_data new_dbuf; enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_append(tdb, key, dbuf) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { return tdb->last_error = TDB_OFF_TO_ERR(off); @@ -256,9 +244,6 @@ _PUBLIC_ enum TDB_ERROR tdb_fetch(struct tdb_context *tdb, struct tdb_data key, struct hash_info h; enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) - return tdb1_fetch(tdb, key, 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); @@ -286,10 +271,6 @@ _PUBLIC_ bool tdb_exists(struct tdb_context *tdb, TDB_DATA key) struct tdb_used_record rec; struct hash_info h; - if (tdb->flags & TDB_VERSION1) { - return tdb1_exists(tdb, key); - } - off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { tdb->last_error = TDB_OFF_TO_ERR(off); @@ -308,12 +289,6 @@ _PUBLIC_ enum TDB_ERROR tdb_delete(struct tdb_context *tdb, struct tdb_data key) struct hash_info h; enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_delete(tdb, key) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { return tdb->last_error = TDB_OFF_TO_ERR(off); @@ -353,10 +328,7 @@ _PUBLIC_ unsigned int tdb_get_flags(struct tdb_context *tdb) static bool inside_transaction(const struct tdb_context *tdb) { - if (tdb->flags & TDB_VERSION1) - return tdb->tdb1.transaction != NULL; - else - return tdb->tdb2.transaction != NULL; + return tdb->tdb2.transaction != NULL; } static bool readonly_changable(struct tdb_context *tdb, const char *caller) @@ -523,11 +495,6 @@ _PUBLIC_ enum TDB_ERROR tdb_parse_record_(struct tdb_context *tdb, 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); @@ -562,17 +529,6 @@ _PUBLIC_ int64_t tdb_get_seqnum(struct tdb_context *tdb) { tdb_off_t off; - if (tdb->flags & TDB_VERSION1) { - tdb1_off_t val; - tdb->last_error = TDB_SUCCESS; - val = tdb1_get_seqnum(tdb); - - if (tdb->last_error != TDB_SUCCESS) - return TDB_ERR_TO_OFF(tdb->last_error); - else - return val; - } - off = tdb_read_off(tdb, offsetof(struct tdb_header, seqnum)); if (TDB_OFF_IS_ERR(off)) tdb->last_error = TDB_OFF_TO_ERR(off); diff --git a/lib/tdb2/tdb1_check.c b/lib/tdb2/tdb1_check.c deleted file mode 100644 index 68f8f8183c..0000000000 --- a/lib/tdb2/tdb1_check.c +++ /dev/null @@ -1,479 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Rusty Russell 2009 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#include "tdb1_private.h" - -/* Since we opened it, these shouldn't fail unless it's recent corruption. */ -static bool tdb1_check_header(struct tdb_context *tdb, tdb1_off_t *recovery) -{ - struct tdb1_header hdr; - uint32_t h1, h2; - - if (tdb->tdb1.io->tdb1_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) - return false; - if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) - goto corrupt; - - TDB1_CONV(hdr); - if (hdr.version != TDB1_VERSION) - goto corrupt; - - if (hdr.rwlocks != 0 && hdr.rwlocks != TDB1_HASH_RWLOCK_MAGIC) - goto corrupt; - - tdb1_header_hash(tdb, &h1, &h2); - if (hdr.magic1_hash && hdr.magic2_hash && - (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) - goto corrupt; - - if (hdr.hash_size == 0) - goto corrupt; - - if (hdr.hash_size != tdb->tdb1.header.hash_size) - goto corrupt; - - if (hdr.recovery_start != 0 && - hdr.recovery_start < TDB1_DATA_START(tdb->tdb1.header.hash_size)) - goto corrupt; - - *recovery = hdr.recovery_start; - return true; - -corrupt: - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Header is corrupt\n"); - return false; -} - -/* Generic record header check. */ -static bool tdb1_check_record(struct tdb_context *tdb, - tdb1_off_t off, - const struct tdb1_record *rec) -{ - tdb1_off_t tailer; - - /* Check rec->next: 0 or points to record offset, aligned. */ - if (rec->next > 0 && rec->next < TDB1_DATA_START(tdb->tdb1.header.hash_size)){ - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d too small next %d\n", - off, rec->next); - goto corrupt; - } - if (rec->next + sizeof(*rec) < rec->next) { - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d too large next %d\n", - off, rec->next); - goto corrupt; - } - if ((rec->next % TDB1_ALIGNMENT) != 0) { - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d misaligned next %d\n", - off, rec->next); - goto corrupt; - } - if (tdb->tdb1.io->tdb1_oob(tdb, rec->next+sizeof(*rec), 0)) - goto corrupt; - - /* Check rec_len: similar to rec->next, implies next record. */ - if ((rec->rec_len % TDB1_ALIGNMENT) != 0) { - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d misaligned length %d\n", - off, rec->rec_len); - goto corrupt; - } - /* Must fit tailer. */ - if (rec->rec_len < sizeof(tailer)) { - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d too short length %d\n", - off, rec->rec_len); - goto corrupt; - } - /* OOB allows "right at the end" access, so this works for last rec. */ - if (tdb->tdb1.io->tdb1_oob(tdb, off+sizeof(*rec)+rec->rec_len, 0)) - goto corrupt; - - /* Check tailer. */ - if (tdb1_ofs_read(tdb, off+sizeof(*rec)+rec->rec_len-sizeof(tailer), - &tailer) == -1) - goto corrupt; - if (tailer != sizeof(*rec) + rec->rec_len) { - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d invalid tailer\n", off); - goto corrupt; - } - - return true; - -corrupt: - tdb->last_error = TDB_ERR_CORRUPT; - return false; -} - -/* Grab some bytes: may copy if can't use mmap. - Caller has already done bounds check. */ -static TDB_DATA get_bytes(struct tdb_context *tdb, - tdb1_off_t off, tdb1_len_t len) -{ - TDB_DATA d; - - d.dsize = len; - - if (tdb->tdb1.transaction == NULL && tdb->file->map_ptr != NULL) - d.dptr = (unsigned char *)tdb->file->map_ptr + off; - else - d.dptr = tdb1_alloc_read(tdb, off, d.dsize); - return d; -} - -/* Frees data if we're not able to simply use mmap. */ -static void put_bytes(struct tdb_context *tdb, TDB_DATA d) -{ - if (tdb->tdb1.transaction == NULL && tdb->file->map_ptr != NULL) - return; - free(d.dptr); -} - -/* We use the excellent Jenkins lookup3 hash; this is based on hash_word2. - * See: http://burtleburtle.net/bob/c/lookup3.c - */ -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) -static void jhash(uint32_t key, uint32_t *pc, uint32_t *pb) -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + *pc; - c += *pb; - a += key; - c ^= b; c -= rot(b,14); - a ^= c; a -= rot(c,11); - b ^= a; b -= rot(a,25); - c ^= b; c -= rot(b,16); - a ^= c; a -= rot(c,4); - b ^= a; b -= rot(a,14); - c ^= b; c -= rot(b,24); - *pc=c; *pb=b; -} - -/* - We want to check that all free records are in the free list - (only once), and all free list entries are free records. Similarly - for each hash chain of used records. - - Doing that naively (without walking hash chains, since we want to be - linear) means keeping a list of records which have been seen in each - hash chain, and another of records pointed to (ie. next pointers - from records and the initial hash chain heads). These two lists - should be equal. This will take 8 bytes per record, and require - sorting at the end. - - So instead, we record each offset in a bitmap such a way that - recording it twice will cancel out. Since each offset should appear - exactly twice, the bitmap should be zero at the end. - - The approach was inspired by Bloom Filters (see Wikipedia). For - each value, we flip K bits in a bitmap of size N. The number of - distinct arrangements is: - - N! / (K! * (N-K)!) - - Of course, not all arrangements are actually distinct, but testing - shows this formula to be close enough. - - So, if K == 8 and N == 256, the probability of two things flipping the same - bits is 1 in 409,663,695,276,000. - - Given that ldb uses a hash size of 10000, using 32 bytes per hash chain - (320k) seems reasonable. -*/ -#define NUM_HASHES 8 -#define BITMAP_BITS 256 - -static void bit_flip(unsigned char bits[], unsigned int idx) -{ - bits[idx / CHAR_BIT] ^= (1 << (idx % CHAR_BIT)); -} - -/* We record offsets in a bitmap for the particular chain it should be in. */ -static void record_offset(unsigned char bits[], tdb1_off_t off) -{ - uint32_t h1 = off, h2 = 0; - unsigned int i; - - /* We get two good hash values out of jhash2, so we use both. Then - * we keep going to produce further hash values. */ - for (i = 0; i < NUM_HASHES / 2; i++) { - jhash(off, &h1, &h2); - bit_flip(bits, h1 % BITMAP_BITS); - bit_flip(bits, h2 % BITMAP_BITS); - h2++; - } -} - -/* Check that an in-use record is valid. */ -static bool tdb1_check_used_record(struct tdb_context *tdb, - tdb1_off_t off, - const struct tdb1_record *rec, - unsigned char **hashes, - enum TDB_ERROR (*check)(TDB_DATA, TDB_DATA, - void *), - void *private_data) -{ - TDB_DATA key, data; - - if (!tdb1_check_record(tdb, off, rec)) - return false; - - /* key + data + tailer must fit in record */ - if (rec->key_len + rec->data_len + sizeof(tdb1_off_t) > rec->rec_len) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d too short for contents\n", off); - return false; - } - - key = get_bytes(tdb, off + sizeof(*rec), rec->key_len); - if (!key.dptr) - return false; - - if ((uint32_t)tdb_hash(tdb, key.dptr, key.dsize) != rec->full_hash) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Record offset %d has incorrect hash\n", off); - goto fail_put_key; - } - - /* Mark this offset as a known value for this hash bucket. */ - record_offset(hashes[TDB1_BUCKET(rec->full_hash)+1], off); - /* And similarly if the next pointer is valid. */ - if (rec->next) - record_offset(hashes[TDB1_BUCKET(rec->full_hash)+1], rec->next); - - /* If they supply a check function and this record isn't dead, - get data and feed it. */ - if (check && rec->magic != TDB1_DEAD_MAGIC) { - enum TDB_ERROR ecode; - - data = get_bytes(tdb, off + sizeof(*rec) + rec->key_len, - rec->data_len); - if (!data.dptr) - goto fail_put_key; - - ecode = check(key, data, private_data); - if (ecode != TDB_SUCCESS) { - tdb->last_error = ecode; - goto fail_put_data; - } - put_bytes(tdb, data); - } - - put_bytes(tdb, key); - return true; - -fail_put_data: - put_bytes(tdb, data); -fail_put_key: - put_bytes(tdb, key); - return false; -} - -/* Check that an unused record is valid. */ -static bool tdb1_check_free_record(struct tdb_context *tdb, - tdb1_off_t off, - const struct tdb1_record *rec, - unsigned char **hashes) -{ - if (!tdb1_check_record(tdb, off, rec)) - return false; - - /* Mark this offset as a known value for the free list. */ - record_offset(hashes[0], off); - /* And similarly if the next pointer is valid. */ - if (rec->next) - record_offset(hashes[0], rec->next); - return true; -} - -/* Slow, but should be very rare. */ -size_t tdb1_dead_space(struct tdb_context *tdb, tdb1_off_t off) -{ - size_t len; - - for (len = 0; off + len < tdb->file->map_size; len++) { - char c; - if (tdb->tdb1.io->tdb1_read(tdb, off, &c, 1, 0)) - return 0; - if (c != 0 && c != 0x42) - break; - } - return len; -} - -int tdb1_check(struct tdb_context *tdb, - enum TDB_ERROR (*check)(TDB_DATA key, TDB_DATA data, void *), - void *private_data) -{ - unsigned int h; - unsigned char **hashes; - tdb1_off_t off, recovery_start; - struct tdb1_record rec; - bool found_recovery = false; - tdb1_len_t dead; - bool locked; - size_t alloc_len; - - /* We may have a write lock already, so don't re-lock. */ - if (tdb->file->allrecord_lock.count != 0) { - locked = false; - } else { - if (tdb_lockall_read(tdb) != TDB_SUCCESS) - return -1; - locked = true; - } - - /* Make sure we know true size of the underlying file. */ - tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1); - - /* Header must be OK: also gets us the recovery ptr, if any. */ - if (!tdb1_check_header(tdb, &recovery_start)) - goto unlock; - - /* We should have the whole header, too. */ - if (tdb->file->map_size < TDB1_DATA_START(tdb->tdb1.header.hash_size)) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "File too short for hashes\n"); - goto unlock; - } - - /* One big malloc: pointers then bit arrays. */ - alloc_len = sizeof(hashes[0]) * (1+tdb->tdb1.header.hash_size) - + BITMAP_BITS / CHAR_BIT * (1+tdb->tdb1.header.hash_size); - hashes = (unsigned char **)calloc(1, alloc_len); - if (!hashes) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR, - "tdb_check: could not allocate %zu", - alloc_len); - goto unlock; - } - - /* Initialize pointers */ - hashes[0] = (unsigned char *)(&hashes[1+tdb->tdb1.header.hash_size]); - for (h = 1; h < 1+tdb->tdb1.header.hash_size; h++) - hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT; - - /* Freelist and hash headers are all in a row: read them. */ - for (h = 0; h < 1+tdb->tdb1.header.hash_size; h++) { - if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP + h*sizeof(tdb1_off_t), - &off) == -1) - goto free; - if (off) - record_offset(hashes[h], off); - } - - /* For each record, read it in and check it's ok. */ - for (off = TDB1_DATA_START(tdb->tdb1.header.hash_size); - off < tdb->file->map_size; - off += sizeof(rec) + rec.rec_len) { - if (tdb->tdb1.io->tdb1_read(tdb, off, &rec, sizeof(rec), - TDB1_DOCONV()) == -1) - goto free; - switch (rec.magic) { - case TDB1_MAGIC: - case TDB1_DEAD_MAGIC: - if (!tdb1_check_used_record(tdb, off, &rec, hashes, - check, private_data)) - goto free; - break; - case TDB1_FREE_MAGIC: - if (!tdb1_check_free_record(tdb, off, &rec, hashes)) - goto free; - break; - /* If we crash after ftruncate, we can get zeroes or fill. */ - case TDB1_RECOVERY_INVALID_MAGIC: - case 0x42424242: - if (recovery_start == off) { - found_recovery = true; - break; - } - dead = tdb1_dead_space(tdb, off); - if (dead < sizeof(rec)) - goto corrupt; - - tdb_logerr(tdb, TDB_SUCCESS, TDB_LOG_WARNING, - "Dead space at %d-%d (of %u)\n", - off, off + dead, - (unsigned)tdb->file->map_size); - rec.rec_len = dead - sizeof(rec); - break; - case TDB1_RECOVERY_MAGIC: - if (recovery_start != off) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Unexpected recovery record at offset %d\n", - off); - goto free; - } - found_recovery = true; - break; - default: ; - corrupt: - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Bad magic 0x%x at offset %d\n", - rec.magic, off); - goto free; - } - } - - /* Now, hashes should all be empty: each record exists and is referred - * to by one other. */ - for (h = 0; h < 1+tdb->tdb1.header.hash_size; h++) { - unsigned int i; - for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) { - if (hashes[h][i] != 0) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Hashes do not match records\n"); - goto free; - } - } - } - - /* We must have found recovery area if there was one. */ - if (recovery_start != 0 && !found_recovery) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "Expected a recovery area at %u\n", - recovery_start); - goto free; - } - - free(hashes); - if (locked) { - tdb_unlockall_read(tdb); - } - return 0; - -free: - free(hashes); -unlock: - if (locked) { - tdb_unlockall_read(tdb); - } - return -1; -} diff --git a/lib/tdb2/tdb1_freelist.c b/lib/tdb2/tdb1_freelist.c deleted file mode 100644 index af01293721..0000000000 --- a/lib/tdb2/tdb1_freelist.c +++ /dev/null @@ -1,322 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "tdb1_private.h" - -/* read a freelist record and check for simple errors */ -int tdb1_rec_free_read(struct tdb_context *tdb, tdb1_off_t off, struct tdb1_record *rec) -{ - if (tdb->tdb1.io->tdb1_read(tdb, off, rec, sizeof(*rec),TDB1_DOCONV()) == -1) - return -1; - - if (rec->magic == TDB1_MAGIC) { - /* this happens when a app is showdown while deleting a record - we should - not completely fail when this happens */ - tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_WARNING, - "tdb1_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", - rec->magic, off); - rec->magic = TDB1_FREE_MAGIC; - if (tdb->tdb1.io->tdb1_write(tdb, off, rec, sizeof(*rec)) == -1) - return -1; - } - - if (rec->magic != TDB1_FREE_MAGIC) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "tdb1_rec_free_read bad magic 0x%x at offset=%d\n", - rec->magic, off); - return -1; - } - if (tdb->tdb1.io->tdb1_oob(tdb, rec->next+sizeof(*rec), 0) != 0) - return -1; - return 0; -} - - -/* update a record tailer (must hold allocation lock) */ -static int update_tailer(struct tdb_context *tdb, tdb1_off_t offset, - const struct tdb1_record *rec) -{ - tdb1_off_t totalsize; - - /* Offset of tailer from record header */ - totalsize = sizeof(*rec) + rec->rec_len; - return tdb1_ofs_write(tdb, offset + totalsize - sizeof(tdb1_off_t), - &totalsize); -} - -/* Add an element into the freelist. Merge adjacent records if - necessary. */ -int tdb1_free(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec) -{ - /* Allocation and tailer lock */ - if (tdb1_lock(tdb, -1, F_WRLCK) != 0) - return -1; - - /* set an initial tailer, so if we fail we don't leave a bogus record */ - if (update_tailer(tdb, offset, rec) != 0) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb_free: update_tailer failed!\n"); - goto fail; - } - - tdb->stats.alloc_coalesce_tried++; - /* Look left */ - if (offset - sizeof(tdb1_off_t) > TDB1_DATA_START(tdb->tdb1.header.hash_size)) { - tdb1_off_t left = offset - sizeof(tdb1_off_t); - struct tdb1_record l; - tdb1_off_t leftsize; - - /* Read in tailer and jump back to header */ - if (tdb1_ofs_read(tdb, left, &leftsize) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_free: left offset read failed at %u", left); - goto update; - } - - /* it could be uninitialised data */ - if (leftsize == 0 || leftsize == TDB1_PAD_U32) { - goto update; - } - - left = offset - leftsize; - - if (leftsize > offset || - left < TDB1_DATA_START(tdb->tdb1.header.hash_size)) { - goto update; - } - - /* Now read in the left record */ - if (tdb->tdb1.io->tdb1_read(tdb, left, &l, sizeof(l), TDB1_DOCONV()) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_free: left read failed at %u (%u)", left, leftsize); - goto update; - } - - /* If it's free, expand to include it. */ - if (l.magic == TDB1_FREE_MAGIC) { - /* we now merge the new record into the left record, rather than the other - way around. This makes the operation O(1) instead of O(n). This change - prevents traverse from being O(n^2) after a lot of deletes */ - l.rec_len += sizeof(*rec) + rec->rec_len; - if (tdb1_rec_write(tdb, left, &l) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_free: update_left failed at %u", left); - goto fail; - } - if (update_tailer(tdb, left, &l) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_free: update_tailer failed at %u", offset); - goto fail; - } - tdb->stats.alloc_coalesce_succeeded++; - tdb->stats.alloc_coalesce_num_merged++; - tdb->stats.frees++; - tdb1_unlock(tdb, -1, F_WRLCK); - return 0; - } - } - -update: - - /* Now, prepend to free list */ - rec->magic = TDB1_FREE_MAGIC; - - if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP, &rec->next) == -1 || - tdb1_rec_write(tdb, offset, rec) == -1 || - tdb1_ofs_write(tdb, TDB1_FREELIST_TOP, &offset) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_free record write failed at offset=%d", - offset); - goto fail; - } - - /* And we're done. */ - tdb->stats.frees++; - tdb1_unlock(tdb, -1, F_WRLCK); - return 0; - - fail: - tdb1_unlock(tdb, -1, F_WRLCK); - return -1; -} - - - -/* - the core of tdb1_allocate - called when we have decided which - free list entry to use - - Note that we try to allocate by grabbing data from the end of an existing record, - not the beginning. This is so the left merge in a free is more likely to be - able to free up the record without fragmentation - */ -static tdb1_off_t tdb1_allocate_ofs(struct tdb_context *tdb, - tdb1_len_t length, tdb1_off_t rec_ptr, - struct tdb1_record *rec, tdb1_off_t last_ptr) -{ -#define MIN_REC_SIZE (sizeof(struct tdb1_record) + sizeof(tdb1_off_t) + 8) - - if (rec->rec_len < length + MIN_REC_SIZE) { - /* we have to grab the whole record */ - - /* unlink it from the previous record */ - if (tdb1_ofs_write(tdb, last_ptr, &rec->next) == -1) { - return 0; - } - - /* mark it not free */ - rec->magic = TDB1_MAGIC; - if (tdb1_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - tdb->stats.allocs++; - return rec_ptr; - } - - /* we're going to just shorten the existing record */ - rec->rec_len -= (length + sizeof(*rec)); - if (tdb1_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - /* and setup the new record */ - rec_ptr += sizeof(*rec) + rec->rec_len; - - memset(rec, '\0', sizeof(*rec)); - rec->rec_len = length; - rec->magic = TDB1_MAGIC; - - if (tdb1_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - tdb->stats.allocs++; - tdb->stats.alloc_leftover++; - return rec_ptr; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected tdb1_record within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -tdb1_off_t tdb1_allocate(struct tdb_context *tdb, tdb1_len_t length, struct tdb1_record *rec) -{ - tdb1_off_t rec_ptr, last_ptr, newrec_ptr; - struct { - tdb1_off_t rec_ptr, last_ptr; - tdb1_len_t rec_len; - } bestfit; - float multiplier = 1.0; - - if (tdb1_lock(tdb, -1, F_WRLCK) == -1) - return 0; - - /* over-allocate to reduce fragmentation */ - length *= 1.25; - - /* Extra bytes required for tailer */ - length += sizeof(tdb1_off_t); - length = TDB1_ALIGN(length, TDB1_ALIGNMENT); - - again: - last_ptr = TDB1_FREELIST_TOP; - - /* read in the freelist top */ - if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP, &rec_ptr) == -1) - goto fail; - - bestfit.rec_ptr = 0; - bestfit.last_ptr = 0; - bestfit.rec_len = 0; - - /* - this is a best fit allocation strategy. Originally we used - a first fit strategy, but it suffered from massive fragmentation - issues when faced with a slowly increasing record size. - */ - while (rec_ptr) { - if (tdb1_rec_free_read(tdb, rec_ptr, rec) == -1) { - goto fail; - } - - if (rec->rec_len >= length) { - if (bestfit.rec_ptr == 0 || - rec->rec_len < bestfit.rec_len) { - bestfit.rec_len = rec->rec_len; - bestfit.rec_ptr = rec_ptr; - bestfit.last_ptr = last_ptr; - } - } - - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec->next; - - /* if we've found a record that is big enough, then - stop searching if its also not too big. The - definition of 'too big' changes as we scan - through */ - if (bestfit.rec_len > 0 && - bestfit.rec_len < length * multiplier) { - break; - } - - /* this multiplier means we only extremely rarely - search more than 50 or so records. At 50 records we - accept records up to 11 times larger than what we - want */ - multiplier *= 1.05; - } - - if (bestfit.rec_ptr != 0) { - if (tdb1_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { - goto fail; - } - - newrec_ptr = tdb1_allocate_ofs(tdb, length, bestfit.rec_ptr, - rec, bestfit.last_ptr); - tdb1_unlock(tdb, -1, F_WRLCK); - return newrec_ptr; - } - - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb1_expand(tdb, length + sizeof(*rec)) == 0) - goto again; - fail: - tdb1_unlock(tdb, -1, F_WRLCK); - return 0; -} diff --git a/lib/tdb2/tdb1_hash.c b/lib/tdb2/tdb1_hash.c deleted file mode 100644 index 1d4e4ae3c7..0000000000 --- a/lib/tdb2/tdb1_hash.c +++ /dev/null @@ -1,347 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Rusty Russell 2010 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#include "tdb1_private.h" - -/* This is based on the hash algorithm from gdbm */ -uint64_t tdb1_old_hash(const void *key, size_t len, uint64_t seed, void *unused) -{ - uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ - const unsigned char *dptr = key; - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * len, i=0; i < len; i++) - value = (value + (dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - -#ifndef WORDS_BIGENDIAN -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#endif - -/* -------------------------------------------------------------------------------- -lookup3.c, by Bob Jenkins, May 2006, Public Domain. - -These are functions for producing 32-bit hashes for hash table lookup. -hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() -are externally useful functions. Routines to test the hash are included -if SELF_TEST is defined. You can use this free for any purpose. It's in -the public domain. It has no warranty. - -You probably want to use hashlittle(). hashlittle() and hashbig() -hash byte arrays. hashlittle() is is faster than hashbig() on -little-endian machines. Intel and AMD are little-endian machines. -On second thought, you probably want hashlittle2(), which is identical to -hashlittle() except it returns two 32-bit hashes for the price of one. -You could implement hashbig2() if you wanted but I haven't bothered here. - -If you want to find a hash of, say, exactly 7 integers, do - a = i1; b = i2; c = i3; - mix(a,b,c); - a += i4; b += i5; c += i6; - mix(a,b,c); - a += i7; - final(a,b,c); -then use c as the hash value. If you have a variable length array of -4-byte integers to hash, use hash_word(). If you have a byte array (like -a character string), use hashlittle(). If you have several byte arrays, or -a mix of things, see the comments above hashlittle(). - -Why is this so big? I read 12 bytes at a time into 3 4-byte integers, -then mix those integers. This is fast (you can do a lot more thorough -mixing with 12*3 instructions on 3 integers than you can with 3 instructions -on 1 byte), but shoehorning those bytes into integers efficiently is messy. -*/ - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/* -------------------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. - -This is reversible, so any information in (a,b,c) before mix() is -still in (a,b,c) after mix(). - -If four pairs of (a,b,c) inputs are run through mix(), or through -mix() in reverse, there are at least 32 bits of the output that -are sometimes the same for one pair and different for another pair. -This was tested for: -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that -satisfy this are - 4 6 8 16 19 4 - 9 15 3 18 27 15 - 14 9 3 7 17 3 -Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing -for "differ" defined as + with a one-bit base and a two-bit delta. I -used http://burtleburtle.net/bob/hash/avalanche.html to choose -the operations, constants, and arrangements of the variables. - -This does not achieve avalanche. There are input bits of (a,b,c) -that fail to affect some output bits of (a,b,c), especially of a. The -most thoroughly mixed value is c, but it doesn't really even achieve -avalanche in c. - -This allows some parallelism. Read-after-writes are good at doubling -the number of bits affected, so the goal of mixing pulls in the opposite -direction as the goal of parallelism. I did what I could. Rotates -seem to cost as much as shifts on every machine I could lay my hands -on, and rotates are much kinder to the top and bottom bits, so I used -rotates. -------------------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------------------- -final -- final mixing of 3 32-bit values (a,b,c) into c - -Pairs of (a,b,c) values differing in only a few bits will usually -produce values of c that look totally different. This was tested for -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -These constants passed: - 14 11 25 16 4 14 24 - 12 14 25 16 4 14 24 -and these came close: - 4 8 15 26 3 22 24 - 10 8 15 26 3 22 24 - 11 8 15 26 3 22 24 -------------------------------------------------------------------------------- -*/ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - - -/* -------------------------------------------------------------------------------- -hashlittle() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - length : the length of the key, counting by bytes - val2 : IN: can be any 4-byte value OUT: second 32 bit hash. -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Two keys differing by one or two bits will have -totally different hash values. Note that the return value is better -mixed than val2, so use that first. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (uint8_t **)k, do it like this: - for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h); - -By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this -code any way you wish, private, educational, or commercial. It's free. - -Use for hash table lookup, or anything where one collision in 2^^32 is -acceptable. Do NOT use for cryptographic purposes. -------------------------------------------------------------------------------- -*/ - -static uint32_t hashlittle( const void *key, size_t length ) -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length); - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - -_PUBLIC_ uint64_t tdb1_incompatible_hash(const void *key, size_t len, uint64_t seed, - void *unused) -{ - return hashlittle(key, len); -} diff --git a/lib/tdb2/tdb1_io.c b/lib/tdb2/tdb1_io.c deleted file mode 100644 index 4371c236cc..0000000000 --- a/lib/tdb2/tdb1_io.c +++ /dev/null @@ -1,530 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - - -#include "tdb1_private.h" -#ifndef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary - note that "len" is the minimum length needed for the db -*/ -static int tdb1_oob(struct tdb_context *tdb, tdb1_off_t len, int probe) -{ - struct stat st; - if (len <= tdb->file->map_size) - return 0; - if (tdb->flags & TDB_INTERNAL) { - if (!probe) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_oob len %d beyond internal malloc size %d", - (int)len, (int)tdb->file->map_size); - } - return -1; - } - - if (fstat(tdb->file->fd, &st) == -1) { - tdb->last_error = TDB_ERR_IO; - return -1; - } - - if (st.st_size < (size_t)len) { - if (!probe) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_oob len %d beyond eof at %d", - (int)len, (int)st.st_size); - } - return -1; - } - - /* Unmap, update size, remap */ - if (tdb1_munmap(tdb) == -1) { - tdb->last_error = TDB_ERR_IO; - return -1; - } - tdb->file->map_size = st.st_size; - return tdb1_mmap(tdb); -} - -/* write a lump of data at a specified offset */ -static int tdb1_write(struct tdb_context *tdb, tdb1_off_t off, - const void *buf, tdb1_len_t len) -{ - if (len == 0) { - return 0; - } - - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { - tdb->last_error = TDB_ERR_RDONLY; - return -1; - } - - if (tdb->tdb1.io->tdb1_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->file->map_ptr) { - memcpy(off + (char *)tdb->file->map_ptr, buf, len); - } else { -#ifdef HAVE_INCOHERENT_MMAP - tdb->last_error = TDB_ERR_IO; - return -1; -#else - ssize_t written = pwrite(tdb->file->fd, buf, len, off); - if ((written != (ssize_t)len) && (written != -1)) { - tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_WARNING, - "tdb1_write: wrote only " - "%d of %d bytes at %d, trying once more", - (int)written, len, off); - written = pwrite(tdb->file->fd, - (const char *)buf+written, - len-written, - off+written); - } - if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_write failed at %d " - "len=%d (%s)", - off, len, strerror(errno)); - return -1; - } else if (written != (ssize_t)len) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_write: failed to " - "write %d bytes at %d in two attempts", - len, off); - return -1; - } -#endif - } - return 0; -} - -/* Endian conversion: we only ever deal with 4 byte quantities */ -void *tdb1_convert(void *buf, uint32_t size) -{ - uint32_t i, *p = (uint32_t *)buf; - for (i = 0; i < size / 4; i++) - p[i] = TDB1_BYTEREV(p[i]); - return buf; -} - - -/* read a lump of data at a specified offset, maybe convert */ -static int tdb1_read(struct tdb_context *tdb, tdb1_off_t off, void *buf, - tdb1_len_t len, int cv) -{ - if (tdb->tdb1.io->tdb1_oob(tdb, off + len, 0) != 0) { - return -1; - } - - if (tdb->file->map_ptr) { - memcpy(buf, off + (char *)tdb->file->map_ptr, len); - } else { -#ifdef HAVE_INCOHERENT_MMAP - tdb->last_error = TDB_ERR_IO; - return -1; -#else - ssize_t ret = pread(tdb->file->fd, buf, len, off); - if (ret != (ssize_t)len) { - /* Ensure ecode is set for log fn. */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_read failed at %d " - "len=%d ret=%d (%s) map_size=%d", - (int)off, (int)len, (int)ret, - strerror(errno), - (int)tdb->file->map_size); - return -1; - } -#endif - } - if (cv) { - tdb1_convert(buf, len); - } - return 0; -} - - - -/* - do an unlocked scan of the hash table heads to find the next non-zero head. The value - will then be confirmed with the lock held -*/ -static void tdb1_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - if (tdb->file->map_ptr) { - for (;h < tdb->tdb1.header.hash_size;h++) { - if (0 != *(uint32_t *)(TDB1_HASH_TOP(h) + (unsigned char *)tdb->file->map_ptr)) { - break; - } - } - } else { - uint32_t off=0; - for (;h < tdb->tdb1.header.hash_size;h++) { - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(h), &off) != 0 || off != 0) { - break; - } - } - } - (*chain) = h; -} - - -int tdb1_munmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#if HAVE_MMAP - if (tdb->file->map_ptr) { - int ret; - - ret = munmap(tdb->file->map_ptr, tdb->file->map_size); - if (ret != 0) - return ret; - } -#endif - tdb->file->map_ptr = NULL; - return 0; -} - -/* If mmap isn't coherent, *everyone* must always mmap. */ -static bool should_mmap(const struct tdb_context *tdb) -{ -#ifdef HAVE_INCOHERENT_MMAP - return true; -#else - return !(tdb->flags & TDB_NOMMAP); -#endif -} - -int tdb1_mmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#if HAVE_MMAP - if (should_mmap(tdb)) { - int mmap_flags; - if ((tdb->open_flags & O_ACCMODE) == O_RDONLY) - mmap_flags = PROT_READ; - else - mmap_flags = PROT_READ | PROT_WRITE; - - tdb->file->map_ptr = mmap(NULL, tdb->file->map_size, - mmap_flags, - MAP_SHARED|MAP_FILE, tdb->file->fd, 0); - - /* - * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! - */ - - if (tdb->file->map_ptr == MAP_FAILED) { - tdb->file->map_ptr = NULL; - tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_WARNING, - "tdb1_mmap failed for size %llu (%s)", - (long long)tdb->file->map_size, - strerror(errno)); -#ifdef HAVE_INCOHERENT_MMAP - tdb->last_error = TDB_ERR_IO; - return -1; -#endif - } - } else { - tdb->file->map_ptr = NULL; - } -#else - tdb->file->map_ptr = NULL; -#endif - return 0; -} - -/* expand a file. we prefer to use ftruncate, as that is what posix - says to use for mmap expansion */ -static int tdb1_expand_file(struct tdb_context *tdb, tdb1_off_t size, tdb1_off_t addition) -{ - char buf[8192]; - - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { - tdb->last_error = TDB_ERR_RDONLY; - return -1; - } - - if (ftruncate(tdb->file->fd, size+addition) == -1) { - char b = 0; - ssize_t written = pwrite(tdb->file->fd, &b, 1, - (size+addition) - 1); - if (written == 0) { - /* try once more, potentially revealing errno */ - written = pwrite(tdb->file->fd, &b, 1, - (size+addition) - 1); - } - if (written == 0) { - /* again - give up, guessing errno */ - errno = ENOSPC; - } - if (written != 1) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "expand_file to %d failed (%s)", - size+addition, - strerror(errno)); - return -1; - } - } - - /* now fill the file with something. This ensures that the - file isn't sparse, which would be very bad if we ran out of - disk. This must be done with write, not via mmap */ - memset(buf, TDB1_PAD_BYTE, sizeof(buf)); - while (addition) { - size_t n = addition>sizeof(buf)?sizeof(buf):addition; - ssize_t written = pwrite(tdb->file->fd, buf, n, size); - if (written == 0) { - /* prevent infinite loops: try _once_ more */ - written = pwrite(tdb->file->fd, buf, n, size); - } - if (written == 0) { - /* give up, trying to provide a useful errno */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "expand_file write " - "returned 0 twice: giving up!"); - errno = ENOSPC; - return -1; - } else if (written == -1) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "expand_file write of " - "%d bytes failed (%s)", (int)n, - strerror(errno)); - return -1; - } else if (written != n) { - tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_WARNING, - "expand_file: wrote " - "only %d of %d bytes - retrying", - (int)written, (int)n); - } - addition -= written; - size += written; - } - tdb->stats.expands++; - return 0; -} - - -/* expand the database at least size bytes by expanding the underlying - file and doing the mmap again if necessary */ -int tdb1_expand(struct tdb_context *tdb, tdb1_off_t size) -{ - struct tdb1_record rec; - tdb1_off_t offset, new_size, top_size, map_size; - - if (tdb1_lock(tdb, -1, F_WRLCK) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "lock failed in tdb1_expand"); - return -1; - } - - /* must know about any previous expansions by another process */ - tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1); - - /* limit size in order to avoid using up huge amounts of memory for - * in memory tdbs if an oddball huge record creeps in */ - if (size > 100 * 1024) { - top_size = tdb->file->map_size + size * 2; - } else { - top_size = tdb->file->map_size + size * 100; - } - - /* always make room for at least top_size more records, and at - least 25% more space. if the DB is smaller than 100MiB, - otherwise grow it by 10% only. */ - if (tdb->file->map_size > 100 * 1024 * 1024) { - map_size = tdb->file->map_size * 1.10; - } else { - map_size = tdb->file->map_size * 1.25; - } - - /* Round the database up to a multiple of the page size */ - new_size = MAX(top_size, map_size); - size = TDB1_ALIGN(new_size, tdb->tdb1.page_size) - tdb->file->map_size; - - if (!(tdb->flags & TDB_INTERNAL)) - tdb1_munmap(tdb); - - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - if (tdb->tdb1.io->tdb1_expand_file(tdb, tdb->file->map_size, size) != 0) - goto fail; - } - - tdb->file->map_size += size; - - if (tdb->flags & TDB_INTERNAL) { - char *new_map_ptr = (char *)realloc(tdb->file->map_ptr, - tdb->file->map_size); - if (!new_map_ptr) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, - TDB_LOG_ERROR, - "tdb1_expand: no memory"); - tdb->file->map_size -= size; - goto fail; - } - tdb->file->map_ptr = new_map_ptr; - } else { - if (tdb1_mmap(tdb) != 0) { - goto fail; - } - } - - /* form a new freelist record */ - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - - /* link it into the free list */ - offset = tdb->file->map_size - size; - if (tdb1_free(tdb, offset, &rec) == -1) - goto fail; - - tdb1_unlock(tdb, -1, F_WRLCK); - return 0; - fail: - tdb1_unlock(tdb, -1, F_WRLCK); - return -1; -} - -/* read/write a tdb1_off_t */ -int tdb1_ofs_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d) -{ - return tdb->tdb1.io->tdb1_read(tdb, offset, (char*)d, sizeof(*d), TDB1_DOCONV()); -} - -int tdb1_ofs_write(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d) -{ - tdb1_off_t off = *d; - return tdb->tdb1.io->tdb1_write(tdb, offset, TDB1_CONV(off), sizeof(*d)); -} - - -/* read a lump of data, allocating the space for it */ -unsigned char *tdb1_alloc_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t len) -{ - unsigned char *buf; - - /* some systems don't like zero length malloc */ - - if (!(buf = (unsigned char *)malloc(len ? len : 1))) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR, - "tdb1_alloc_read malloc failed" - " len=%d (%s)", - len, strerror(errno)); - return NULL; - } - if (tdb->tdb1.io->tdb1_read(tdb, offset, buf, len, 0) == -1) { - SAFE_FREE(buf); - return NULL; - } - return buf; -} - -/* Give a piece of tdb data to a parser */ -enum TDB_ERROR tdb1_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb1_off_t offset, tdb1_len_t len, - enum TDB_ERROR (*parser)(TDB_DATA key, - TDB_DATA data, - void *private_data), - void *private_data) -{ - TDB_DATA data; - enum TDB_ERROR result; - - data.dsize = len; - - if ((tdb->tdb1.transaction == NULL) && (tdb->file->map_ptr != NULL)) { - /* - * Optimize by avoiding the malloc/memcpy/free, point the - * parser directly at the mmap area. - */ - if (tdb->tdb1.io->tdb1_oob(tdb, offset+len, 0) != 0) { - return tdb->last_error; - } - data.dptr = offset + (unsigned char *)tdb->file->map_ptr; - return parser(key, data, private_data); - } - - if (!(data.dptr = tdb1_alloc_read(tdb, offset, len))) { - return tdb->last_error; - } - - result = parser(key, data, private_data); - free(data.dptr); - return result; -} - -/* read/write a record */ -int tdb1_rec_read(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec) -{ - if (tdb->tdb1.io->tdb1_read(tdb, offset, rec, sizeof(*rec),TDB1_DOCONV()) == -1) - return -1; - if (TDB1_BAD_MAGIC(rec)) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "tdb1_rec_read bad magic 0x%x at offset=%d", - rec->magic, offset); - return -1; - } - return tdb->tdb1.io->tdb1_oob(tdb, rec->next+sizeof(*rec), 0); -} - -int tdb1_rec_write(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec) -{ - struct tdb1_record r = *rec; - return tdb->tdb1.io->tdb1_write(tdb, offset, TDB1_CONV(r), sizeof(r)); -} - -static const struct tdb1_methods io1_methods = { - tdb1_read, - tdb1_write, - tdb1_next_hash_chain, - tdb1_oob, - tdb1_expand_file, -}; - -/* - initialise the default methods table -*/ -void tdb1_io_init(struct tdb_context *tdb) -{ - tdb->tdb1.io = &io1_methods; -} - -enum TDB_ERROR tdb1_probe_length(struct tdb_context *tdb) -{ - tdb->last_error = TDB_SUCCESS; - tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, true); - return tdb->last_error; -} diff --git a/lib/tdb2/tdb1_lock.c b/lib/tdb2/tdb1_lock.c deleted file mode 100644 index 5cc0ad6567..0000000000 --- a/lib/tdb2/tdb1_lock.c +++ /dev/null @@ -1,560 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "tdb1_private.h" - -/* list -1 is the alloc list, otherwise a hash chain. */ -static tdb1_off_t lock_offset(int list) -{ - return TDB1_FREELIST_TOP + 4*list; -} - -/* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb1_open(). - - note that a len of zero means lock to end of file -*/ -int tdb1_brlock(struct tdb_context *tdb, - int rw_type, tdb1_off_t offset, size_t len, - enum tdb_lock_flags flags) -{ - enum TDB_ERROR ecode = tdb_brlock(tdb, rw_type, offset, len, flags - | TDB_LOCK_NOCHECK); - if (ecode == TDB_SUCCESS) - return 0; - tdb->last_error = ecode; - return -1; -} - -int tdb1_brunlock(struct tdb_context *tdb, - int rw_type, tdb1_off_t offset, size_t len) -{ - enum TDB_ERROR ecode = tdb_brunlock(tdb, rw_type, offset, len); - if (ecode == TDB_SUCCESS) - return 0; - tdb->last_error = ecode; - return -1; -} - -int tdb1_allrecord_upgrade(struct tdb_context *tdb) -{ - enum TDB_ERROR ecode = tdb_allrecord_upgrade(tdb, TDB1_FREELIST_TOP); - if (ecode == TDB_SUCCESS) - return 0; - tdb->last_error = ecode; - return -1; -} - -static struct tdb_lock *tdb1_find_nestlock(struct tdb_context *tdb, - tdb1_off_t offset) -{ - unsigned int i; - - for (i=0; i<tdb->file->num_lockrecs; i++) { - if (tdb->file->lockrecs[i].off == offset) { - return &tdb->file->lockrecs[i]; - } - } - return NULL; -} - -/* lock an offset in the database. */ -int tdb1_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, - enum tdb_lock_flags flags) -{ - enum TDB_ERROR ecode; - - if (offset >= lock_offset(tdb->tdb1.header.hash_size)) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, - "tdb1_lock: invalid offset %u for" - " ltype=%d", - offset, ltype); - return -1; - } - - ecode = tdb_nest_lock(tdb, offset, ltype, flags | TDB_LOCK_NOCHECK); - if (unlikely(ecode != TDB_SUCCESS)) { - tdb->last_error = ecode; - return -1; - } - return 0; -} - -static int tdb1_lock_and_recover(struct tdb_context *tdb) -{ - int ret; - - /* We need to match locking order in transaction commit. */ - if (tdb1_brlock(tdb, F_WRLCK, TDB1_FREELIST_TOP, 0, - TDB_LOCK_WAIT|TDB_LOCK_NOCHECK)) { - return -1; - } - - if (tdb1_brlock(tdb, F_WRLCK, TDB1_OPEN_LOCK, 1, - TDB_LOCK_WAIT|TDB_LOCK_NOCHECK)) { - tdb1_brunlock(tdb, F_WRLCK, TDB1_FREELIST_TOP, 0); - return -1; - } - - ret = tdb1_transaction_recover(tdb); - - tdb1_brunlock(tdb, F_WRLCK, TDB1_OPEN_LOCK, 1); - tdb1_brunlock(tdb, F_WRLCK, TDB1_FREELIST_TOP, 0); - - return ret; -} - -static bool have_data_locks(const struct tdb_context *tdb) -{ - unsigned int i; - - for (i = 0; i < tdb->file->num_lockrecs; i++) { - if (tdb->file->lockrecs[i].off >= lock_offset(-1)) - return true; - } - return false; -} - -static int tdb1_lock_list(struct tdb_context *tdb, int list, int ltype, - enum tdb_lock_flags waitflag) -{ - int ret; - bool check = false; - - /* a allrecord lock allows us to avoid per chain locks */ - if (tdb->file->allrecord_lock.count) { - if (!check_lock_pid(tdb, "tdb1_lock_list", true)) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error = owner_conflict(tdb, "tdb1_lock_list"); - return -1; - } - if (ltype == tdb->file->allrecord_lock.ltype - || ltype == F_RDLCK) { - return 0; - } - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, - TDB_LOG_USE_ERROR, - "tdb1_lock_list:" - " already have read lock"); - return -1; - } - - /* Only check when we grab first data lock. */ - check = !have_data_locks(tdb); - ret = tdb1_nest_lock(tdb, lock_offset(list), ltype, waitflag); - - if (ret == 0 && check) { - tdb_bool_err berr = tdb1_needs_recovery(tdb); - - if (berr < 0) { - return -1; - } - if (berr == true) { - tdb1_nest_unlock(tdb, lock_offset(list), ltype); - - if (tdb1_lock_and_recover(tdb) == -1) { - return -1; - } - return tdb1_lock_list(tdb, list, ltype, waitflag); - } - } - return ret; -} - -/* lock a list in the database. list -1 is the alloc list */ -int tdb1_lock(struct tdb_context *tdb, int list, int ltype) -{ - int ret; - - ret = tdb1_lock_list(tdb, list, ltype, TDB_LOCK_WAIT); - /* Don't log for EAGAIN and EINTR: they could have overridden lock fns */ - if (ret && errno != EAGAIN && errno != EINTR) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_lock failed on list %d " - "ltype=%d (%s)", list, ltype, strerror(errno)); - } - return ret; -} - -int tdb1_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype) -{ - enum TDB_ERROR ecode; - - /* Sanity checks */ - if (offset >= lock_offset(tdb->tdb1.header.hash_size)) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, - "tdb1_unlock: offset %u invalid (%d)", - offset, tdb->tdb1.header.hash_size); - return -1; - } - - ecode = tdb_nest_unlock(tdb, offset, ltype); - if (unlikely(ecode != TDB_SUCCESS)) { - tdb->last_error = ecode; - return -1; - } - return 0; -} - -int tdb1_unlock(struct tdb_context *tdb, int list, int ltype) -{ - /* a global lock allows us to avoid per chain locks */ - if (tdb->file->allrecord_lock.count && - (ltype == tdb->file->allrecord_lock.ltype || ltype == F_RDLCK)) { - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error = owner_conflict(tdb, "tdb1_unlock"); - return -1; - } - return 0; - } - - if (tdb->file->allrecord_lock.count) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - - return tdb1_nest_unlock(tdb, lock_offset(list), ltype); -} - -/* - get the transaction lock - */ -int tdb1_transaction_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags lockflags) -{ - return tdb1_nest_lock(tdb, TDB1_TRANSACTION_LOCK, ltype, lockflags); -} - -/* - release the transaction lock - */ -int tdb1_transaction_unlock(struct tdb_context *tdb, int ltype) -{ - return tdb1_nest_unlock(tdb, TDB1_TRANSACTION_LOCK, ltype); -} - -/* lock/unlock entire database. It can only be upgradable if you have some - * other way of guaranteeing exclusivity (ie. transaction write lock). - * We do the locking gradually to avoid being starved by smaller locks. */ -int tdb1_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags, bool upgradable) -{ - enum TDB_ERROR ecode; - tdb_bool_err berr; - - /* tdb_lock_gradual() doesn't know about tdb->tdb1.traverse_read. */ - if (tdb->tdb1.traverse_read && !(tdb->flags & TDB_NOLOCK)) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, - TDB_LOG_USE_ERROR, - "tdb1_allrecord_lock during" - " tdb1_read_traverse"); - return -1; - } - - if (tdb->file->allrecord_lock.count - && tdb->file->allrecord_lock.ltype == ltype) { - tdb->file->allrecord_lock.count++; - return 0; - } - - if (tdb1_have_extra_locks(tdb)) { - /* can't combine global and chain locks */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, - TDB_LOG_USE_ERROR, - "tdb1_allrecord_lock holding" - " other locks"); - return -1; - } - - if (upgradable && ltype != F_RDLCK) { - /* tdb error: you can't upgrade a write lock! */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, - TDB_LOG_ERROR, - "tdb1_allrecord_lock cannot" - " have upgradable write lock"); - return -1; - } - - /* We cover two kinds of locks: - * 1) Normal chain locks. Taken for almost all operations. - * 3) Individual records locks. Taken after normal or free - * chain locks. - * - * It is (1) which cause the starvation problem, so we're only - * gradual for that. */ - ecode = tdb_lock_gradual(tdb, ltype, flags | TDB_LOCK_NOCHECK, - TDB1_FREELIST_TOP, tdb->tdb1.header.hash_size * 4); - if (ecode != TDB_SUCCESS) { - tdb->last_error = ecode; - return -1; - } - - /* Grab individual record locks. */ - if (tdb1_brlock(tdb, ltype, lock_offset(tdb->tdb1.header.hash_size), 0, - flags) == -1) { - tdb1_brunlock(tdb, ltype, TDB1_FREELIST_TOP, - tdb->tdb1.header.hash_size * 4); - return -1; - } - - tdb->file->allrecord_lock.owner = tdb; - tdb->file->allrecord_lock.count = 1; - tdb->file->locker = getpid(); - /* If it's upgradable, it's actually exclusive so we can treat - * it as a write lock. */ - tdb->file->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; - tdb->file->allrecord_lock.off = upgradable; - - berr = tdb1_needs_recovery(tdb); - if (berr < 0) { - return -1; - } - - if (berr == true) { - tdb1_allrecord_unlock(tdb, ltype); - if (tdb1_lock_and_recover(tdb) == -1) { - return -1; - } - return tdb1_allrecord_lock(tdb, ltype, flags, upgradable); - } - - return 0; -} - - - -/* unlock entire db */ -int tdb1_allrecord_unlock(struct tdb_context *tdb, int ltype) -{ - /* Don't try this during r/o traversal! */ - if (tdb->tdb1.traverse_read) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - - if (tdb->file->allrecord_lock.count == 0) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - - /* Upgradable locks are marked as write locks. */ - if (tdb->file->allrecord_lock.ltype != ltype - && (!tdb->file->allrecord_lock.off || ltype != F_RDLCK)) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - - if (tdb->file->allrecord_lock.count > 1) { - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error - = owner_conflict(tdb, "tdb1_allrecord_unlock"); - return -1; - } - tdb->file->allrecord_lock.count--; - return 0; - } - - tdb->file->allrecord_lock.count = 0; - tdb->file->allrecord_lock.ltype = 0; - - if (tdb1_brunlock(tdb, ltype, TDB1_FREELIST_TOP, 0)) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_unlockall failed (%s)", strerror(errno)); - return -1; - } - - return 0; -} - -/* lock/unlock one hash chain. This is meant to be used to reduce - contention - it cannot guarantee how many records will be locked */ -int tdb1_chainlock(struct tdb_context *tdb, TDB_DATA key) -{ - int ret = tdb1_lock(tdb, - TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), - F_WRLCK); - return ret; -} - -int tdb1_chainunlock(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb1_unlock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), - F_WRLCK); -} - -int tdb1_chainlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - int ret; - ret = tdb1_lock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), - F_RDLCK); - return ret; -} - -int tdb1_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb1_unlock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), - F_RDLCK); -} - -/* record lock stops delete underneath */ -int tdb1_lock_record(struct tdb_context *tdb, tdb1_off_t off) -{ - if (tdb->file->allrecord_lock.count) { - if (!check_lock_pid(tdb, "tdb1_lock_record", true)) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error = owner_conflict(tdb, - "tdb1_lock_record"); - return -1; - } - return 0; - } - return off ? tdb1_brlock(tdb, F_RDLCK, off, 1, TDB_LOCK_WAIT) : 0; -} - -/* - Write locks override our own fcntl readlocks, so check it here. - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ -int tdb1_write_lock_record(struct tdb_context *tdb, tdb1_off_t off) -{ - struct tdb1_traverse_lock *i; - for (i = &tdb->tdb1.travlocks; i; i = i->next) - if (i->off == off) - return -1; - if (tdb->file->allrecord_lock.count) { - if (!check_lock_pid(tdb, "tdb1_write_lock_record", true)) { - tdb->last_error = TDB_ERR_LOCK; - return -1; - } - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error - = owner_conflict(tdb, "tdb1_write_lock_record"); - return -1; - } - if (tdb->file->allrecord_lock.ltype == F_WRLCK) { - return 0; - } - return -1; - } - return tdb1_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); -} - -int tdb1_write_unlock_record(struct tdb_context *tdb, tdb1_off_t off) -{ - if (tdb->file->allrecord_lock.count) { - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error - = owner_conflict(tdb, - "tdb1_write_unlock_record"); - return -1; - } - return 0; - } - return tdb1_brunlock(tdb, F_WRLCK, off, 1); -} - -/* fcntl locks don't stack: avoid unlocking someone else's */ -int tdb1_unlock_record(struct tdb_context *tdb, tdb1_off_t off) -{ - struct tdb1_traverse_lock *i; - uint32_t count = 0; - - if (tdb->file->allrecord_lock.count) { - if (tdb->file->allrecord_lock.owner != tdb) { - tdb->last_error = owner_conflict(tdb, - "tdb1_unlock_record"); - return -1; - } - return 0; - } - - if (off == 0) - return 0; - for (i = &tdb->tdb1.travlocks; i; i = i->next) - if (i->off == off) - count++; - return (count == 1 ? tdb1_brunlock(tdb, F_RDLCK, off, 1) : 0); -} - -bool tdb1_have_extra_locks(struct tdb_context *tdb) -{ - unsigned int extra = tdb->file->num_lockrecs; - - /* A transaction holds the lock for all records. */ - if (!tdb->tdb1.transaction && tdb->file->allrecord_lock.count) { - return true; - } - - /* We always hold the active lock if CLEAR_IF_FIRST. */ - if (tdb1_find_nestlock(tdb, TDB1_ACTIVE_LOCK)) { - extra--; - } - - /* In a transaction, we expect to hold the transaction lock */ - if (tdb->tdb1.transaction - && tdb1_find_nestlock(tdb, TDB1_TRANSACTION_LOCK)) { - extra--; - } - - return extra; -} - -/* The transaction code uses this to remove all locks. */ -void tdb1_release_transaction_locks(struct tdb_context *tdb) -{ - unsigned int i, active = 0; - - if (tdb->file->allrecord_lock.count != 0) { - tdb1_brunlock(tdb, tdb->file->allrecord_lock.ltype, TDB1_FREELIST_TOP, 0); - tdb->file->allrecord_lock.count = 0; - } - - for (i=0;i<tdb->file->num_lockrecs;i++) { - struct tdb_lock *lck = &tdb->file->lockrecs[i]; - - /* Don't release the active lock! Copy it to first entry. */ - if (lck->off == TDB1_ACTIVE_LOCK) { - tdb->file->lockrecs[active++] = *lck; - } else { - tdb1_brunlock(tdb, lck->ltype, lck->off, 1); - } - } - tdb->file->num_lockrecs = active; - if (tdb->file->num_lockrecs == 0) { - SAFE_FREE(tdb->file->lockrecs); - } -} diff --git a/lib/tdb2/tdb1_open.c b/lib/tdb2/tdb1_open.c deleted file mode 100644 index e668616a04..0000000000 --- a/lib/tdb2/tdb1_open.c +++ /dev/null @@ -1,234 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#include <assert.h> -#include "tdb1_private.h" -#include <assert.h> - -/* We use two hashes to double-check they're using the right hash function. */ -void tdb1_header_hash(struct tdb_context *tdb, - uint32_t *magic1_hash, uint32_t *magic2_hash) -{ - uint32_t tdb1_magic = TDB1_MAGIC; - - *magic1_hash = tdb_hash(tdb, TDB_MAGIC_FOOD, sizeof(TDB_MAGIC_FOOD)); - *magic2_hash = tdb_hash(tdb, TDB1_CONV(tdb1_magic), sizeof(tdb1_magic)); - - /* Make sure at least one hash is non-zero! */ - if (*magic1_hash == 0 && *magic2_hash == 0) - *magic1_hash = 1; -} - -static void tdb_context_init(struct tdb_context *tdb, - struct tdb_attribute_tdb1_max_dead *max_dead) -{ - assert(tdb->flags & TDB_VERSION1); - - tdb1_io_init(tdb); - - tdb->tdb1.traverse_read = tdb->tdb1.traverse_write = 0; - memset(&tdb->tdb1.travlocks, 0, sizeof(tdb->tdb1.travlocks)); - tdb->tdb1.transaction = NULL; - - /* cache the page size */ - tdb->tdb1.page_size = getpagesize(); - if (tdb->tdb1.page_size <= 0) { - tdb->tdb1.page_size = 0x2000; - } - - if (max_dead) { - tdb->tdb1.max_dead_records = max_dead->max_dead; - } else { - tdb->tdb1.max_dead_records = 0; - } -} - -/* initialise a new database */ -enum TDB_ERROR tdb1_new_database(struct tdb_context *tdb, - struct tdb_attribute_tdb1_hashsize *hashsize, - struct tdb_attribute_tdb1_max_dead *max_dead) -{ - struct tdb1_header *newdb; - size_t size; - int hash_size = TDB1_DEFAULT_HASH_SIZE; - enum TDB_ERROR ret; - - tdb_context_init(tdb, max_dead); - - /* Default TDB2 hash becomes default TDB1 hash. */ - if (tdb->hash_fn == tdb_jenkins_hash) - tdb->hash_fn = tdb1_old_hash; - - if (hashsize) - hash_size = hashsize->hsize; - - /* We make it up in memory, then write it out if not internal */ - size = sizeof(struct tdb1_header) + (hash_size+1)*sizeof(tdb1_off_t); - if (!(newdb = (struct tdb1_header *)calloc(size, 1))) { - return tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR, - "Could not allocate new database header"); - } - - /* Fill in the header */ - newdb->version = TDB1_VERSION; - newdb->hash_size = hash_size; - - tdb1_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash); - - /* Make sure older tdbs (which don't check the magic hash fields) - * will refuse to open this TDB. */ - if (tdb->hash_fn == tdb1_incompatible_hash) - newdb->rwlocks = TDB1_HASH_RWLOCK_MAGIC; - - memcpy(&tdb->tdb1.header, newdb, sizeof(tdb->tdb1.header)); - /* This creates an endian-converted db. */ - TDB1_CONV(*newdb); - /* Don't endian-convert the magic food! */ - memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - - if (tdb->flags & TDB_INTERNAL) { - tdb->file->map_size = size; - tdb->file->map_ptr = (char *)newdb; - return TDB_SUCCESS; - } - if (lseek(tdb->file->fd, 0, SEEK_SET) == -1) { - ret = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_new_database: lseek failed"); - goto fail; - } - - if (ftruncate(tdb->file->fd, 0) == -1) { - ret = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_new_database: ftruncate failed"); - goto fail; - } - - if (!tdb1_write_all(tdb->file->fd, newdb, size)) { - ret = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_new_database: write failed"); - goto fail; - } - ret = TDB_SUCCESS; - - fail: - SAFE_FREE(newdb); - return ret; -} - -typedef void (*tdb1_log_func)(struct tdb_context *, enum tdb_log_level, enum TDB_ERROR, - const char *, void *); -typedef uint64_t (*tdb1_hash_func)(const void *key, size_t len, uint64_t seed, - void *data); - -struct tdb1_logging_context { - tdb1_log_func log_fn; - void *log_private; -}; - -static bool hash_correct(struct tdb_context *tdb, - uint32_t *m1, uint32_t *m2) -{ - /* older TDB without magic hash references */ - if (tdb->tdb1.header.magic1_hash == 0 - && tdb->tdb1.header.magic2_hash == 0) { - return true; - } - - tdb1_header_hash(tdb, m1, m2); - return (tdb->tdb1.header.magic1_hash == *m1 && - tdb->tdb1.header.magic2_hash == *m2); -} - -static bool check_header_hash(struct tdb_context *tdb, - uint32_t *m1, uint32_t *m2) -{ - if (hash_correct(tdb, m1, m2)) - return true; - - /* If they use one inbuilt, try the other inbuilt hash. */ - if (tdb->hash_fn == tdb1_old_hash) - tdb->hash_fn = tdb1_incompatible_hash; - else if (tdb->hash_fn == tdb1_incompatible_hash) - tdb->hash_fn = tdb1_old_hash; - else - return false; - return hash_correct(tdb, m1, m2); -} - -/* We are hold the TDB open lock on tdb->fd. */ -enum TDB_ERROR tdb1_open(struct tdb_context *tdb, - struct tdb_attribute_tdb1_max_dead *max_dead) -{ - const char *hash_alg; - uint32_t magic1, magic2; - - tdb->flags |= TDB_VERSION1; - - tdb_context_init(tdb, max_dead); - - /* Default TDB2 hash becomes default TDB1 hash. */ - if (tdb->hash_fn == tdb_jenkins_hash) { - tdb->hash_fn = tdb1_old_hash; - hash_alg = "default"; - } else if (tdb->hash_fn == tdb1_incompatible_hash) - hash_alg = "tdb1_incompatible_hash"; - else - hash_alg = "the user defined"; - - if (tdb->tdb1.header.version != TDB1_BYTEREV(TDB1_VERSION)) { - if (tdb->flags & TDB_CONVERT) { - return tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_open:" - " %s does not need TDB_CONVERT", - tdb->name); - } - } else { - tdb->flags |= TDB_CONVERT; - tdb1_convert(&tdb->tdb1.header, sizeof(tdb->tdb1.header)); - } - - if (tdb->tdb1.header.rwlocks != 0 && - tdb->tdb1.header.rwlocks != TDB1_HASH_RWLOCK_MAGIC) { - return tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "tdb1_open: spinlocks no longer supported"); - } - - if (!check_header_hash(tdb, &magic1, &magic2)) { - return tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_USE_ERROR, - "tdb1_open: " - "%s was not created with %s hash function we are using\n" - "magic1_hash[0x%08X %s 0x%08X] " - "magic2_hash[0x%08X %s 0x%08X]", - tdb->name, hash_alg, - tdb->tdb1.header.magic1_hash, - (tdb->tdb1.header.magic1_hash == magic1) ? "==" : "!=", - magic1, - tdb->tdb1.header.magic2_hash, - (tdb->tdb1.header.magic2_hash == magic2) ? "==" : "!=", - magic2); - } - return TDB_SUCCESS; -} diff --git a/lib/tdb2/tdb1_private.h b/lib/tdb2/tdb1_private.h deleted file mode 100644 index 833298b737..0000000000 --- a/lib/tdb2/tdb1_private.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef CCAN_TDB2_TDB1_PRIVATE_H -#define CCAN_TDB2_TDB1_PRIVATE_H - /* - Unix SMB/CIFS implementation. - - trivial database library - private includes - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "private.h" - -#include <limits.h> - -/* #define TDB_TRACE 1 */ -#ifndef HAVE_GETPAGESIZE -#define getpagesize() 0x2000 -#endif - -#ifndef __STRING -#define __STRING(x) #x -#endif - -#ifndef __STRINGSTRING -#define __STRINGSTRING(x) __STRING(x) -#endif - -#ifndef __location__ -#define __location__ __FILE__ ":" __STRINGSTRING(__LINE__) -#endif - -#ifndef offsetof -#define offsetof(t,f) ((unsigned int)&((t *)0)->f) -#endif - -#define TDB1_VERSION (0x26011967 + 6) -#define TDB1_MAGIC (0x26011999U) -#define TDB1_FREE_MAGIC (~TDB1_MAGIC) -#define TDB1_DEAD_MAGIC (0xFEE1DEAD) -#define TDB1_RECOVERY_MAGIC (0xf53bc0e7U) -#define TDB1_RECOVERY_INVALID_MAGIC (0x0) -#define TDB1_HASH_RWLOCK_MAGIC (0xbad1a51U) -#define TDB1_ALIGNMENT 4 -#define TDB1_DEFAULT_HASH_SIZE 131 -#define TDB1_FREELIST_TOP (sizeof(struct tdb1_header)) -#define TDB1_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -#define TDB1_DEAD(r) ((r)->magic == TDB1_DEAD_MAGIC) -#define TDB1_BAD_MAGIC(r) ((r)->magic != TDB1_MAGIC && !TDB1_DEAD(r)) -#define TDB1_HASH_TOP(hash) (TDB1_FREELIST_TOP + (TDB1_BUCKET(hash)+1)*sizeof(tdb1_off_t)) -#define TDB1_HASHTABLE_SIZE(tdb) ((tdb->tdb1.header.hash_size+1)*sizeof(tdb1_off_t)) -#define TDB1_DATA_START(hash_size) (TDB1_HASH_TOP(hash_size-1) + sizeof(tdb1_off_t)) -#define TDB1_RECOVERY_HEAD offsetof(struct tdb1_header, recovery_start) -#define TDB1_SEQNUM_OFS offsetof(struct tdb1_header, sequence_number) -#define TDB1_PAD_BYTE 0x42 -#define TDB1_PAD_U32 0x42424242 - -/* lock offsets */ -#define TDB1_OPEN_LOCK 0 -#define TDB1_ACTIVE_LOCK 4 -#define TDB1_TRANSACTION_LOCK 8 - -/* free memory if the pointer is valid and zero the pointer */ -#ifndef SAFE_FREE -#define SAFE_FREE(x) do { if ((x) != NULL) {free((void *)x); (x)=NULL;} } while(0) -#endif - -#define TDB1_BUCKET(hash) ((hash) % tdb->tdb1.header.hash_size) - -#define TDB1_DOCONV() (tdb->flags & TDB_CONVERT) -#define TDB1_CONV(x) (TDB1_DOCONV() ? tdb1_convert(&x, sizeof(x)) : &x) - -/* the body of the database is made of one tdb1_record for the free space - plus a separate data list for each hash value */ -struct tdb1_record { - tdb1_off_t next; /* offset of the next record in the list */ - tdb1_len_t rec_len; /* total byte length of record */ - tdb1_len_t key_len; /* byte length of key */ - tdb1_len_t data_len; /* byte length of data */ - uint32_t full_hash; /* the full 32 bit hash of the key */ - uint32_t magic; /* try to catch errors */ - /* the following union is implied: - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - uint32_t totalsize; (tailer) - } - */ -}; - - -struct tdb1_methods { - int (*tdb1_read)(struct tdb_context *, tdb1_off_t , void *, tdb1_len_t , int ); - int (*tdb1_write)(struct tdb_context *, tdb1_off_t, const void *, tdb1_len_t); - void (*next_hash_chain)(struct tdb_context *, uint32_t *); - int (*tdb1_oob)(struct tdb_context *, tdb1_off_t , int ); - int (*tdb1_expand_file)(struct tdb_context *, tdb1_off_t , tdb1_off_t ); -}; - - -/* - internal prototypes -*/ -int tdb1_munmap(struct tdb_context *tdb); -int tdb1_mmap(struct tdb_context *tdb); -int tdb1_lock(struct tdb_context *tdb, int list, int ltype); -int tdb1_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, - enum tdb_lock_flags flags); -int tdb1_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype); -int tdb1_unlock(struct tdb_context *tdb, int list, int ltype); -int tdb1_brlock(struct tdb_context *tdb, - int rw_type, tdb1_off_t offset, size_t len, - enum tdb_lock_flags flags); -int tdb1_brunlock(struct tdb_context *tdb, - int rw_type, tdb1_off_t offset, size_t len); -bool tdb1_have_extra_locks(struct tdb_context *tdb); -void tdb1_release_transaction_locks(struct tdb_context *tdb); -int tdb1_transaction_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags lockflags); -int tdb1_transaction_unlock(struct tdb_context *tdb, int ltype); -int tdb1_recovery_area(struct tdb_context *tdb, - const struct tdb1_methods *methods, - tdb1_off_t *recovery_offset, - struct tdb1_record *rec); -int tdb1_allrecord_upgrade(struct tdb_context *tdb); -int tdb1_write_lock_record(struct tdb_context *tdb, tdb1_off_t off); -int tdb1_write_unlock_record(struct tdb_context *tdb, tdb1_off_t off); -int tdb1_ofs_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d); -int tdb1_ofs_write(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d); -void *tdb1_convert(void *buf, uint32_t size); -int tdb1_free(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec); -tdb1_off_t tdb1_allocate(struct tdb_context *tdb, tdb1_len_t length, struct tdb1_record *rec); -int tdb1_ofs_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d); -int tdb1_ofs_write(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d); -int tdb1_lock_record(struct tdb_context *tdb, tdb1_off_t off); -int tdb1_unlock_record(struct tdb_context *tdb, tdb1_off_t off); -tdb_bool_err tdb1_needs_recovery(struct tdb_context *tdb); -int tdb1_rec_read(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec); -int tdb1_rec_write(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec); -int tdb1_do_delete(struct tdb_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec); -unsigned char *tdb1_alloc_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t len); -enum TDB_ERROR tdb1_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb1_off_t offset, tdb1_len_t len, - enum TDB_ERROR (*parser)(TDB_DATA key, - TDB_DATA data, - void *private_data), - void *private_data); -tdb1_off_t tdb1_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct tdb1_record *rec); -void tdb1_io_init(struct tdb_context *tdb); -int tdb1_expand(struct tdb_context *tdb, tdb1_off_t size); -int tdb1_rec_free_read(struct tdb_context *tdb, tdb1_off_t off, - struct tdb1_record *rec); -bool tdb1_write_all(int fd, const void *buf, size_t count); -void tdb1_header_hash(struct tdb_context *tdb, - uint32_t *magic1_hash, uint32_t *magic2_hash); -uint64_t tdb1_old_hash(const void *key, size_t len, uint64_t seed, void *); -size_t tdb1_dead_space(struct tdb_context *tdb, tdb1_off_t off); -#endif /* CCAN_TDB2_TDB1_PRIVATE_H */ diff --git a/lib/tdb2/tdb1_summary.c b/lib/tdb2/tdb1_summary.c deleted file mode 100644 index b74b8f4474..0000000000 --- a/lib/tdb2/tdb1_summary.c +++ /dev/null @@ -1,202 +0,0 @@ - /* - Trivial Database: human-readable summary code - Copyright (C) Rusty Russell 2010 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#include "tdb1_private.h" - -#define SUMMARY_FORMAT1 \ - "Size of file/data: %u/%zu\n" \ - "Number of records: %zu\n" \ - "Smallest/average/largest keys: %zu/%zu/%zu\n" \ - "Smallest/average/largest data: %zu/%zu/%zu\n" \ - "Smallest/average/largest padding: %zu/%zu/%zu\n" \ - "Number of dead records: %zu\n" \ - "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ - "Number of free records: %zu\n" \ - "Smallest/average/largest free records: %zu/%zu/%zu\n" \ - "Number of hash chains: %zu\n" \ - "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ - "Number of uncoalesced records: %zu\n" \ - "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ - "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" - -/* We don't use tally module, to keep upstream happy. */ -struct tally { - size_t min, max, total; - size_t num; -}; - -static void tally1_init(struct tally *tally) -{ - tally->total = 0; - tally->num = 0; - tally->min = tally->max = 0; -} - -static void tally1_add(struct tally *tally, size_t len) -{ - if (tally->num == 0) - tally->max = tally->min = len; - else if (len > tally->max) - tally->max = len; - else if (len < tally->min) - tally->min = len; - tally->num++; - tally->total += len; -} - -static size_t tally1_mean(const struct tally *tally) -{ - if (!tally->num) - return 0; - return tally->total / tally->num; -} - -static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) -{ - tdb1_off_t rec_ptr; - size_t count = 0; - - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(i), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - struct tdb1_record r; - ++count; - if (tdb1_rec_read(tdb, rec_ptr, &r) == -1) - return 0; - rec_ptr = r.next; - } - return count; -} - -char *tdb1_summary(struct tdb_context *tdb) -{ - tdb1_off_t off, rec_off; - struct tally freet, keys, data, dead, extra, hash, uncoal; - struct tdb1_record rec; - char *ret = NULL; - bool locked; - size_t len, unc = 0; - struct tdb1_record recovery; - - /* We may have a write lock already, so don't lock. */ - if (tdb->file->allrecord_lock.count != 0) { - locked = false; - } else { - if (tdb_lockall_read(tdb) != TDB_SUCCESS) - return NULL; - locked = true; - } - - if (tdb1_recovery_area(tdb, tdb->tdb1.io, &rec_off, &recovery) != 0) { - goto unlock; - } - - tally1_init(&freet); - tally1_init(&keys); - tally1_init(&data); - tally1_init(&dead); - tally1_init(&extra); - tally1_init(&hash); - tally1_init(&uncoal); - - for (off = TDB1_DATA_START(tdb->tdb1.header.hash_size); - off < tdb->file->map_size - 1; - off += sizeof(rec) + rec.rec_len) { - if (tdb->tdb1.io->tdb1_read(tdb, off, &rec, sizeof(rec), - TDB1_DOCONV()) == -1) - goto unlock; - switch (rec.magic) { - case TDB1_MAGIC: - tally1_add(&keys, rec.key_len); - tally1_add(&data, rec.data_len); - tally1_add(&extra, rec.rec_len - (rec.key_len - + rec.data_len)); - if (unc > 1) - tally1_add(&uncoal, unc - 1); - unc = 0; - break; - case TDB1_FREE_MAGIC: - tally1_add(&freet, rec.rec_len); - unc++; - break; - /* If we crash after ftruncate, we can get zeroes or fill. */ - case TDB1_RECOVERY_INVALID_MAGIC: - case 0x42424242: - unc++; - /* If it's a valid recovery, we can trust rec_len. */ - if (off != rec_off) { - rec.rec_len = tdb1_dead_space(tdb, off) - - sizeof(rec); - } - /* Fall through */ - case TDB1_DEAD_MAGIC: - tally1_add(&dead, rec.rec_len); - break; - default: - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, - TDB_LOG_ERROR, - "Unexpected record magic 0x%x" - " at offset %d", - rec.magic, off); - goto unlock; - } - } - if (unc > 1) - tally1_add(&uncoal, unc - 1); - - for (off = 0; off < tdb->tdb1.header.hash_size; off++) - tally1_add(&hash, get_hash_length(tdb, off)); - - /* 20 is max length of a %zu. */ - len = strlen(SUMMARY_FORMAT1) + 35*20 + 1; - ret = (char *)malloc(len); - if (!ret) - goto unlock; - - snprintf(ret, len, SUMMARY_FORMAT1, - (tdb1_len_t)tdb->file->map_size, keys.total+data.total, - keys.num, - keys.min, tally1_mean(&keys), keys.max, - data.min, tally1_mean(&data), data.max, - extra.min, tally1_mean(&extra), extra.max, - dead.num, - dead.min, tally1_mean(&dead), dead.max, - freet.num, - freet.min, tally1_mean(&freet), freet.max, - hash.num, - hash.min, tally1_mean(&hash), hash.max, - uncoal.total, - uncoal.min, tally1_mean(&uncoal), uncoal.max, - keys.total * 100.0 / tdb->file->map_size, - data.total * 100.0 / tdb->file->map_size, - extra.total * 100.0 / tdb->file->map_size, - freet.total * 100.0 / tdb->file->map_size, - dead.total * 100.0 / tdb->file->map_size, - (keys.num + freet.num + dead.num) - * (sizeof(struct tdb1_record) + sizeof(uint32_t)) - * 100.0 / tdb->file->map_size, - tdb->tdb1.header.hash_size * sizeof(tdb1_off_t) - * 100.0 / (tdb1_len_t)tdb->file->map_size); - -unlock: - if (locked) { - tdb_unlockall_read(tdb); - } - return ret; -} diff --git a/lib/tdb2/tdb1_tdb.c b/lib/tdb2/tdb1_tdb.c deleted file mode 100644 index ae633ed77b..0000000000 --- a/lib/tdb2/tdb1_tdb.c +++ /dev/null @@ -1,833 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "tdb1_private.h" -#include <assert.h> - -/* - non-blocking increment of the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb) -{ - tdb1_off_t seqnum=0; - - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - /* we ignore errors from this, as we have no sane way of - dealing with them. - */ - tdb1_ofs_read(tdb, TDB1_SEQNUM_OFS, &seqnum); - seqnum++; - tdb1_ofs_write(tdb, TDB1_SEQNUM_OFS, &seqnum); -} - -/* - increment the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -static void tdb1_increment_seqnum(struct tdb_context *tdb) -{ - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - if (tdb1_nest_lock(tdb, TDB1_SEQNUM_OFS, F_WRLCK, - TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) { - return; - } - - tdb1_increment_seqnum_nonblock(tdb); - - tdb1_nest_unlock(tdb, TDB1_SEQNUM_OFS, F_WRLCK); -} - -static enum TDB_ERROR tdb1_key_compare(TDB_DATA key, TDB_DATA data, - void *matches_) -{ - bool *matches = matches_; - *matches = (memcmp(data.dptr, key.dptr, data.dsize) == 0); - return TDB_SUCCESS; -} - -/* Returns 0 on fail; last_error will be TDB_ERR_NOEXIST if it simply - * wasn't there, otherwise a real error. - * On success, return offset of record, and fills in rec */ -static tdb1_off_t tdb1_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, - struct tdb1_record *r) -{ - tdb1_off_t rec_ptr; - - /* read in the hash top */ - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (tdb1_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - tdb->stats.compares++; - if (TDB1_DEAD(r)) { - tdb->stats.compare_wrong_bucket++; - } else if (key.dsize != r->key_len) { - tdb->stats.compare_wrong_keylen++; - } else if (hash != r->full_hash) { - tdb->stats.compare_wrong_rechash++; - } else { - enum TDB_ERROR ecode; - bool matches; - ecode = tdb1_parse_data(tdb, key, rec_ptr + sizeof(*r), - r->key_len, tdb1_key_compare, - &matches); - - if (ecode != TDB_SUCCESS) { - tdb->last_error = ecode; - return 0; - } - - if (!matches) { - tdb->stats.compare_wrong_keycmp++; - } else { - return rec_ptr; - } - } - /* detect tight infinite loop */ - if (rec_ptr == r->next) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, - TDB_LOG_ERROR, - "tdb1_find: loop detected."); - return 0; - } - rec_ptr = r->next; - } - tdb->last_error = TDB_ERR_NOEXIST; - return 0; -} - -/* As tdb1_find, but if you succeed, keep the lock */ -tdb1_off_t tdb1_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct tdb1_record *rec) -{ - uint32_t rec_ptr; - - if (tdb1_lock(tdb, TDB1_BUCKET(hash), locktype) == -1) - return 0; - if (!(rec_ptr = tdb1_find(tdb, key, hash, rec))) - tdb1_unlock(tdb, TDB1_BUCKET(hash), locktype); - return rec_ptr; -} - -static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key); - -static enum TDB_ERROR tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data) -{ - TDB_DATA *dbuf = (TDB_DATA *)private_data; - - if (dbuf->dsize != data.dsize) { - return TDB_ERR_EINVAL; - } - if (memcmp(dbuf->dptr, data.dptr, data.dsize) != 0) { - return TDB_ERR_EINVAL; - } - return TDB_SUCCESS; -} - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. -*/ -static int tdb1_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) -{ - struct tdb1_record rec; - tdb1_off_t rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb1_find(tdb, key, hash, &rec))) - return -1; - - /* it could be an exact duplicate of what is there - this is - * surprisingly common (eg. with a ldb re-index). */ - if (rec.key_len == key.dsize && - rec.data_len == dbuf.dsize && - rec.full_hash == hash && - tdb1_parse_record(tdb, key, tdb_update_hash_cmp, &dbuf) == TDB_SUCCESS) { - return 0; - } - - /* must be long enough key, data and tailer */ - if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb1_off_t)) { - tdb->last_error = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb->tdb1.io->tdb1_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, - dbuf.dptr, dbuf.dsize) == -1) - return -1; - - if (dbuf.dsize != rec.data_len) { - /* update size */ - rec.data_len = dbuf.dsize; - return tdb1_rec_write(tdb, rec_ptr, &rec); - } - - return 0; -} - -/* find an entry in the database given a key */ -/* If an entry doesn't exist tdb1_err will be set to - * TDB_ERR_NOEXIST. If a key has no data attached - * then the TDB_DATA will have zero length but - * a non-zero pointer - */ -static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key) -{ - tdb1_off_t rec_ptr; - struct tdb1_record rec; - TDB_DATA ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb_hash(tdb, key.dptr, key.dsize); - if (!(rec_ptr = tdb1_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { - ret.dptr = NULL; - ret.dsize = 0; - return ret; - } - - ret.dptr = tdb1_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - ret.dsize = rec.data_len; - tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK); - return ret; -} - -enum TDB_ERROR tdb1_fetch(struct tdb_context *tdb, TDB_DATA key, TDB_DATA *data) -{ - *data = _tdb1_fetch(tdb, key); - if (data->dptr == NULL) - return tdb->last_error; - return TDB_SUCCESS; -} - -enum TDB_ERROR tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key, - enum TDB_ERROR (*parser)(TDB_DATA key, - TDB_DATA data, - void *private_data), - void *private_data) -{ - tdb1_off_t rec_ptr; - struct tdb1_record rec; - enum TDB_ERROR ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb_hash(tdb, key.dptr, key.dsize); - - if (!(rec_ptr = tdb1_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { - return tdb->last_error; - } - - ret = tdb1_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len, parser, private_data); - - tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK); - - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -static int tdb1_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - struct tdb1_record rec; - - if (tdb1_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) - return 0; - tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK); - return 1; -} - -int tdb1_exists(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize); - int ret; - - assert(tdb->flags & TDB_VERSION1); - ret = tdb1_exists_hash(tdb, key, hash); - return ret; -} - -/* actually delete an entry in the database given the offset */ -int tdb1_do_delete(struct tdb_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec) -{ - tdb1_off_t last_ptr, i; - struct tdb1_record lastrec; - - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) return -1; - - if (((tdb->tdb1.traverse_write != 0) && (!TDB1_DEAD(rec))) || - tdb1_write_lock_record(tdb, rec_ptr) == -1) { - /* Someone traversing here: mark it as dead */ - rec->magic = TDB1_DEAD_MAGIC; - return tdb1_rec_write(tdb, rec_ptr, rec); - } - if (tdb1_write_unlock_record(tdb, rec_ptr) != 0) - return -1; - - /* find previous record in hash chain */ - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(rec->full_hash), &i) == -1) - return -1; - for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) - if (tdb1_rec_read(tdb, i, &lastrec) == -1) - return -1; - - /* unlink it: next ptr is at start of record. */ - if (last_ptr == 0) - last_ptr = TDB1_HASH_TOP(rec->full_hash); - if (tdb1_ofs_write(tdb, last_ptr, &rec->next) == -1) - return -1; - - /* recover the space */ - if (tdb1_free(tdb, rec_ptr, rec) == -1) - return -1; - return 0; -} - -static int tdb1_count_dead(struct tdb_context *tdb, uint32_t hash) -{ - int res = 0; - tdb1_off_t rec_ptr; - struct tdb1_record rec; - - /* read in the hash top */ - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - while (rec_ptr) { - if (tdb1_rec_read(tdb, rec_ptr, &rec) == -1) - return 0; - - if (rec.magic == TDB1_DEAD_MAGIC) { - res += 1; - } - rec_ptr = rec.next; - } - return res; -} - -/* - * Purge all DEAD records from a hash chain - */ -static int tdb1_purge_dead(struct tdb_context *tdb, uint32_t hash) -{ - int res = -1; - struct tdb1_record rec; - tdb1_off_t rec_ptr; - - if (tdb1_lock(tdb, -1, F_WRLCK) == -1) { - return -1; - } - - /* read in the hash top */ - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) - goto fail; - - while (rec_ptr) { - tdb1_off_t next; - - if (tdb1_rec_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - next = rec.next; - - if (rec.magic == TDB1_DEAD_MAGIC - && tdb1_do_delete(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - rec_ptr = next; - } - res = 0; - fail: - tdb1_unlock(tdb, -1, F_WRLCK); - return res; -} - -/* delete an entry in the database given a key */ -static int tdb1_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - tdb1_off_t rec_ptr; - struct tdb1_record rec; - int ret; - - if (tdb->tdb1.max_dead_records != 0) { - - /* - * Allow for some dead records per hash chain, mainly for - * tdb's with a very high create/delete rate like locking.tdb. - */ - - if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1) - return -1; - - if (tdb1_count_dead(tdb, hash) >= tdb->tdb1.max_dead_records) { - /* - * Don't let the per-chain freelist grow too large, - * delete all existing dead records - */ - tdb1_purge_dead(tdb, hash); - } - - if (!(rec_ptr = tdb1_find(tdb, key, hash, &rec))) { - tdb1_unlock(tdb, TDB1_BUCKET(hash), F_WRLCK); - return -1; - } - - /* - * Just mark the record as dead. - */ - rec.magic = TDB1_DEAD_MAGIC; - ret = tdb1_rec_write(tdb, rec_ptr, &rec); - } - else { - if (!(rec_ptr = tdb1_find_lock_hash(tdb, key, hash, F_WRLCK, - &rec))) - return -1; - - ret = tdb1_do_delete(tdb, rec_ptr, &rec); - } - - if (ret == 0) { - tdb1_increment_seqnum(tdb); - } - - if (tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_WRLCK) != 0) - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_delete: WARNING tdb1_unlock failed!"); - return ret; -} - -int tdb1_delete(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize); - int ret; - - assert(tdb->flags & TDB_VERSION1); - ret = tdb1_delete_hash(tdb, key, hash); - return ret; -} - -/* - * See if we have a dead record around with enough space - */ -static tdb1_off_t tdb1_find_dead(struct tdb_context *tdb, uint32_t hash, - struct tdb1_record *r, tdb1_len_t length) -{ - tdb1_off_t rec_ptr; - - /* read in the hash top */ - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (tdb1_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (TDB1_DEAD(r) && r->rec_len >= length) { - /* - * First fit for simple coding, TODO: change to best - * fit - */ - return rec_ptr; - } - rec_ptr = r->next; - } - return 0; -} - -static int _tdb1_store(struct tdb_context *tdb, TDB_DATA key, - TDB_DATA dbuf, int flag, uint32_t hash) -{ - struct tdb1_record rec; - tdb1_off_t rec_ptr; - int ret = -1; - - /* check for it existing, on insert. */ - if (flag == TDB_INSERT) { - if (tdb1_exists_hash(tdb, key, hash)) { - tdb->last_error = TDB_ERR_EXISTS; - goto fail; - } - if (tdb->last_error != TDB_ERR_NOEXIST) { - goto fail; - } - } else { - /* first try in-place update, on modify or replace. */ - if (tdb1_update_hash(tdb, key, hash, dbuf) == 0) { - goto done; - } - if (tdb->last_error != TDB_SUCCESS) { - if (tdb->last_error != TDB_ERR_NOEXIST) { - goto fail; - } - if (flag == TDB_MODIFY) { - /* if the record doesn't exist and we are in TDB1_MODIFY mode then - we should fail the store */ - goto fail; - } - } - } - /* reset the error code potentially set by the tdb1_update() */ - tdb->last_error = TDB_SUCCESS; - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - if (flag != TDB_INSERT) - tdb1_delete_hash(tdb, key, hash); - - if (tdb->tdb1.max_dead_records != 0) { - /* - * Allow for some dead records per hash chain, look if we can - * find one that can hold the new record. We need enough space - * for key, data and tailer. If we find one, we don't have to - * consult the central freelist. - */ - rec_ptr = tdb1_find_dead( - tdb, hash, &rec, - key.dsize + dbuf.dsize + sizeof(tdb1_off_t)); - - if (rec_ptr != 0) { - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB1_MAGIC; - if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->tdb1.io->tdb1_write( - tdb, rec_ptr + sizeof(rec), - key.dptr, key.dsize) == -1 - || tdb->tdb1.io->tdb1_write( - tdb, rec_ptr + sizeof(rec) + key.dsize, - dbuf.dptr, dbuf.dsize) == -1) { - goto fail; - } - goto done; - } - } - - /* - * We have to allocate some space from the freelist, so this means we - * have to lock it. Use the chance to purge all the DEAD records from - * the hash chain under the freelist lock. - */ - - if (tdb1_lock(tdb, -1, F_WRLCK) == -1) { - goto fail; - } - - if ((tdb->tdb1.max_dead_records != 0) - && (tdb1_purge_dead(tdb, hash) == -1)) { - tdb1_unlock(tdb, -1, F_WRLCK); - goto fail; - } - - /* we have to allocate some space */ - rec_ptr = tdb1_allocate(tdb, key.dsize + dbuf.dsize, &rec); - - tdb1_unlock(tdb, -1, F_WRLCK); - - if (rec_ptr == 0) { - goto fail; - } - - /* Read hash top into next ptr */ - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB1_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->tdb1.io->tdb1_write(tdb, rec_ptr + sizeof(rec), - key.dptr, key.dsize) == -1 - || tdb->tdb1.io->tdb1_write(tdb, rec_ptr + sizeof(rec) + key.dsize, - dbuf.dptr, dbuf.dsize) == -1 - || tdb1_ofs_write(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb1_unallocate() here */ - goto fail; - } - - done: - ret = 0; - fail: - if (ret == 0) { - tdb1_increment_seqnum(tdb); - } - return ret; -} - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - uint32_t hash; - int ret; - - assert(tdb->flags & TDB_VERSION1); - - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_RDONLY, - TDB_LOG_USE_ERROR, - "tdb_store: read-only tdb"); - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(tdb, key.dptr, key.dsize); - if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1) - return -1; - - ret = _tdb1_store(tdb, key, dbuf, flag, hash); - tdb1_unlock(tdb, TDB1_BUCKET(hash), F_WRLCK); - return ret; -} - -/* Append to an entry. Create if not exist. */ -int tdb1_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - uint32_t hash; - TDB_DATA dbuf; - int ret = -1; - - assert(tdb->flags & TDB_VERSION1); - - /* find which hash bucket it is in */ - hash = tdb_hash(tdb, key.dptr, key.dsize); - if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1) - return -1; - - dbuf = _tdb1_fetch(tdb, key); - - if (dbuf.dptr == NULL) { - dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize); - } else { - unsigned int new_len = dbuf.dsize + new_dbuf.dsize; - unsigned char *new_dptr; - - /* realloc '0' is special: don't do that. */ - if (new_len == 0) - new_len = 1; - new_dptr = (unsigned char *)realloc(dbuf.dptr, new_len); - if (new_dptr == NULL) { - free(dbuf.dptr); - } - dbuf.dptr = new_dptr; - } - - if (dbuf.dptr == NULL) { - tdb->last_error = TDB_ERR_OOM; - goto failed; - } - - memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize); - dbuf.dsize += new_dbuf.dsize; - - ret = _tdb1_store(tdb, key, dbuf, 0, hash); - -failed: - tdb1_unlock(tdb, TDB1_BUCKET(hash), F_WRLCK); - SAFE_FREE(dbuf.dptr); - return ret; -} - - -/* - get the tdb sequence number. Only makes sense if the writers opened - with TDB1_SEQNUM set. Note that this sequence number will wrap quite - quickly, so it should only be used for a 'has something changed' - test, not for code that relies on the count of the number of changes - made. If you want a counter then use a tdb record. - - The aim of this sequence number is to allow for a very lightweight - test of a possible tdb change. -*/ -int tdb1_get_seqnum(struct tdb_context *tdb) -{ - tdb1_off_t seqnum=0; - - tdb1_ofs_read(tdb, TDB1_SEQNUM_OFS, &seqnum); - return seqnum; -} - - -/* - add a region of the file to the freelist. Length is the size of the region in bytes, - which includes the free list header that needs to be added - */ -static int tdb1_free_region(struct tdb_context *tdb, tdb1_off_t offset, ssize_t length) -{ - struct tdb1_record rec; - if (length <= sizeof(rec)) { - /* the region is not worth adding */ - return 0; - } - if (length + offset > tdb->file->map_size) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "tdb1_free_region: adding region beyond" - " end of file"); - return -1; - } - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = length - sizeof(rec); - if (tdb1_free(tdb, offset, &rec) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_free_region: failed to add free record"); - return -1; - } - return 0; -} - -/* - wipe the entire database, deleting all records. This can be done - very fast by using a allrecord lock. The entire data portion of the - file becomes a single entry in the freelist. - - This code carefully steps around the recovery area, leaving it alone - */ -int tdb1_wipe_all(struct tdb_context *tdb) -{ - int i; - tdb1_off_t offset = 0; - ssize_t data_len; - tdb1_off_t recovery_head; - tdb1_len_t recovery_size = 0; - - if (tdb_lockall(tdb) != TDB_SUCCESS) { - return -1; - } - - - /* see if the tdb has a recovery area, and remember its size - if so. We don't want to lose this as otherwise each - tdb1_wipe_all() in a transaction will increase the size of - the tdb by the size of the recovery area */ - if (tdb1_ofs_read(tdb, TDB1_RECOVERY_HEAD, &recovery_head) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_wipe_all: failed to read recovery head"); - goto failed; - } - - if (recovery_head != 0) { - struct tdb1_record rec; - if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_wipe_all: failed to read recovery record"); - return -1; - } - recovery_size = rec.rec_len + sizeof(rec); - } - - /* wipe the hashes */ - for (i=0;i<tdb->tdb1.header.hash_size;i++) { - if (tdb1_ofs_write(tdb, TDB1_HASH_TOP(i), &offset) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_wipe_all: failed to write hash %d", i); - goto failed; - } - } - - /* wipe the freelist */ - if (tdb1_ofs_write(tdb, TDB1_FREELIST_TOP, &offset) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_wipe_all: failed to write freelist"); - goto failed; - } - - /* add all the rest of the file to the freelist, possibly leaving a gap - for the recovery area */ - if (recovery_size == 0) { - /* the simple case - the whole file can be used as a freelist */ - data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->tdb1.header.hash_size)); - if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) { - goto failed; - } - } else { - /* we need to add two freelist entries - one on either - side of the recovery area - - Note that we cannot shift the recovery area during - this operation. Only the transaction.c code may - move the recovery area or we risk subtle data - corruption - */ - data_len = (recovery_head - TDB1_DATA_START(tdb->tdb1.header.hash_size)); - if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) { - goto failed; - } - /* and the 2nd free list entry after the recovery area - if any */ - data_len = tdb->file->map_size - (recovery_head+recovery_size); - if (tdb1_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { - goto failed; - } - } - - tdb1_increment_seqnum_nonblock(tdb); - tdb_unlockall(tdb); - return 0; - -failed: - tdb_unlockall(tdb); - return -1; -} - -/* Even on files, we can get partial writes due to signals. */ -bool tdb1_write_all(int fd, const void *buf, size_t count) -{ - while (count) { - ssize_t ret; - ret = write(fd, buf, count); - if (ret < 0) - return false; - buf = (const char *)buf + ret; - count -= ret; - } - return true; -} diff --git a/lib/tdb2/tdb1_transaction.c b/lib/tdb2/tdb1_transaction.c deleted file mode 100644 index 411caef360..0000000000 --- a/lib/tdb2/tdb1_transaction.c +++ /dev/null @@ -1,1336 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "tdb1_private.h" - -/* - transaction design: - - - only allow a single transaction at a time per database. This makes - using the transaction API simpler, as otherwise the caller would - have to cope with temporary failures in transactions that conflict - with other current transactions - - - keep the transaction recovery information in the same file as the - database, using a special 'transaction recovery' record pointed at - by the header. This removes the need for extra journal files as - used by some other databases - - - dynamically allocated the transaction recover record, re-using it - for subsequent transactions. If a larger record is needed then - tdb1_free() the old record to place it on the normal tdb freelist - before allocating the new record - - - during transactions, keep a linked list of writes all that have - been performed by intercepting all tdb1_write() calls. The hooked - transaction versions of tdb1_read() and tdb1_write() check this - linked list and try to use the elements of the list in preference - to the real database. - - - don't allow any locks to be held when a transaction starts, - otherwise we can end up with deadlock (plus lack of lock nesting - in posix locks would mean the lock is lost) - - - if the caller gains a lock during the transaction but doesn't - release it then fail the commit - - - allow for nested calls to tdb1_transaction_start(), re-using the - existing transaction record. If the inner transaction is cancelled - then a subsequent commit will fail - - - keep a mirrored copy of the tdb hash chain heads to allow for the - fast hash heads scan on traverse, updating the mirrored copy in - the transaction version of tdb1_write - - - allow callers to mix transaction and non-transaction use of tdb, - although once a transaction is started then an exclusive lock is - gained until the transaction is committed or cancelled - - - the commit stategy involves first saving away all modified data - into a linearised buffer in the transaction recovery area, then - marking the transaction recovery area with a magic value to - indicate a valid recovery record. In total 4 fsync/msync calls are - needed per commit to prevent race conditions. It might be possible - to reduce this to 3 or even 2 with some more work. - - - check for a valid recovery record on open of the tdb, while the - open lock is held. Automatically recover from the transaction - recovery area if needed, then continue with the open as - usual. This allows for smooth crash recovery with no administrator - intervention. - - - if TDB_NOSYNC is passed to flags in tdb1_open then transactions are - still available, but no transaction recovery area is used and no - fsync/msync calls are made. - - - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using - tdb1_add_flags() transaction nesting is enabled. - The default is that transaction nesting is NOT allowed. - - Beware. when transactions are nested a transaction successfully - completed with tdb1_transaction_commit() can be silently unrolled later. -*/ - - -/* - hold the context of any current transaction -*/ -struct tdb1_transaction { - /* we keep a mirrored copy of the tdb hash heads here so - tdb1_next_hash_chain() can operate efficiently */ - uint32_t *hash_heads; - - /* the original io methods - used to do IOs to the real db */ - const struct tdb1_methods *io_methods; - - /* the list of transaction blocks. When a block is first - written to, it gets created in this list */ - uint8_t **blocks; - uint32_t num_blocks; - uint32_t block_size; /* bytes in each block */ - uint32_t last_block_size; /* number of valid bytes in the last block */ - - /* non-zero when an internal transaction error has - occurred. All write operations will then fail until the - transaction is ended */ - int transaction_error; - - /* when inside a transaction we need to keep track of any - nested tdb1_transaction_start() calls, as these are allowed, - but don't create a new transaction */ - int nesting; - - /* set when a prepare has already occurred */ - bool prepared; - tdb1_off_t magic_offset; - - /* old file size before transaction */ - tdb1_len_t old_map_size; - - /* did we expand in this transaction */ - bool expanded; -}; - - -/* - read while in a transaction. We need to check first if the data is in our list - of transaction elements, then if not do a real read -*/ -static int transaction1_read(struct tdb_context *tdb, tdb1_off_t off, void *buf, - tdb1_len_t len, int cv) -{ - uint32_t blk; - - /* break it down into block sized ops */ - while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->block_size) { - tdb1_len_t len2 = tdb->tdb1.transaction->block_size - (off % tdb->tdb1.transaction->block_size); - if (transaction1_read(tdb, off, buf, len2, cv) != 0) { - return -1; - } - len -= len2; - off += len2; - buf = (void *)(len2 + (char *)buf); - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->tdb1.transaction->block_size; - - /* see if we have it in the block list */ - if (tdb->tdb1.transaction->num_blocks <= blk || - tdb->tdb1.transaction->blocks[blk] == NULL) { - /* nope, do a real read */ - if (tdb->tdb1.transaction->io_methods->tdb1_read(tdb, off, buf, len, cv) != 0) { - goto fail; - } - return 0; - } - - /* it is in the block list. Now check for the last block */ - if (blk == tdb->tdb1.transaction->num_blocks-1) { - if (len > tdb->tdb1.transaction->last_block_size) { - goto fail; - } - } - - /* now copy it out of this block */ - memcpy(buf, tdb->tdb1.transaction->blocks[blk] + (off % tdb->tdb1.transaction->block_size), len); - if (cv) { - tdb1_convert(buf, len); - } - return 0; - -fail: - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "transaction_read: failed at off=%d len=%d", - off, len); - tdb->tdb1.transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction -*/ -static int transaction1_write(struct tdb_context *tdb, tdb1_off_t off, - const void *buf, tdb1_len_t len) -{ - uint32_t blk; - - /* Only a commit is allowed on a prepared transaction */ - if (tdb->tdb1.transaction->prepared) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, - "transaction_write: transaction already" - " prepared, write not allowed"); - tdb->tdb1.transaction->transaction_error = 1; - return -1; - } - - /* if the write is to a hash head, then update the transaction - hash heads */ - if (len == sizeof(tdb1_off_t) && off >= TDB1_FREELIST_TOP && - off < TDB1_FREELIST_TOP+TDB1_HASHTABLE_SIZE(tdb)) { - uint32_t chain = (off-TDB1_FREELIST_TOP) / sizeof(tdb1_off_t); - memcpy(&tdb->tdb1.transaction->hash_heads[chain], buf, len); - } - - /* break it up into block sized chunks */ - while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->block_size) { - tdb1_len_t len2 = tdb->tdb1.transaction->block_size - (off % tdb->tdb1.transaction->block_size); - if (transaction1_write(tdb, off, buf, len2) != 0) { - return -1; - } - len -= len2; - off += len2; - if (buf != NULL) { - buf = (const void *)(len2 + (const char *)buf); - } - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->tdb1.transaction->block_size; - off = off % tdb->tdb1.transaction->block_size; - - if (tdb->tdb1.transaction->num_blocks <= blk) { - uint8_t **new_blocks; - /* expand the blocks array */ - if (tdb->tdb1.transaction->blocks == NULL) { - new_blocks = (uint8_t **)malloc( - (blk+1)*sizeof(uint8_t *)); - } else { - new_blocks = (uint8_t **)realloc( - tdb->tdb1.transaction->blocks, - (blk+1)*sizeof(uint8_t *)); - } - if (new_blocks == NULL) { - tdb->last_error = TDB_ERR_OOM; - goto fail; - } - memset(&new_blocks[tdb->tdb1.transaction->num_blocks], 0, - (1+(blk - tdb->tdb1.transaction->num_blocks))*sizeof(uint8_t *)); - tdb->tdb1.transaction->blocks = new_blocks; - tdb->tdb1.transaction->num_blocks = blk+1; - tdb->tdb1.transaction->last_block_size = 0; - } - - /* allocate and fill a block? */ - if (tdb->tdb1.transaction->blocks[blk] == NULL) { - tdb->tdb1.transaction->blocks[blk] = (uint8_t *)calloc(tdb->tdb1.transaction->block_size, 1); - if (tdb->tdb1.transaction->blocks[blk] == NULL) { - tdb->last_error = TDB_ERR_OOM; - tdb->tdb1.transaction->transaction_error = 1; - return -1; - } - if (tdb->tdb1.transaction->old_map_size > blk * tdb->tdb1.transaction->block_size) { - tdb1_len_t len2 = tdb->tdb1.transaction->block_size; - if (len2 + (blk * tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->old_map_size) { - len2 = tdb->tdb1.transaction->old_map_size - (blk * tdb->tdb1.transaction->block_size); - } - if (tdb->tdb1.transaction->io_methods->tdb1_read(tdb, blk * tdb->tdb1.transaction->block_size, - tdb->tdb1.transaction->blocks[blk], - len2, 0) != 0) { - SAFE_FREE(tdb->tdb1.transaction->blocks[blk]); - tdb->last_error = TDB_ERR_IO; - goto fail; - } - if (blk == tdb->tdb1.transaction->num_blocks-1) { - tdb->tdb1.transaction->last_block_size = len2; - } - } - } - - /* overwrite part of an existing block */ - if (buf == NULL) { - memset(tdb->tdb1.transaction->blocks[blk] + off, 0, len); - } else { - memcpy(tdb->tdb1.transaction->blocks[blk] + off, buf, len); - } - if (blk == tdb->tdb1.transaction->num_blocks-1) { - if (len + off > tdb->tdb1.transaction->last_block_size) { - tdb->tdb1.transaction->last_block_size = len + off; - } - } - - return 0; - -fail: - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "transaction_write: failed at off=%d len=%d", - (blk*tdb->tdb1.transaction->block_size) + off, len); - tdb->tdb1.transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction - this varient never expands the transaction blocks, it only - updates existing blocks. This means it cannot change the recovery size -*/ -static int transaction1_write_existing(struct tdb_context *tdb, tdb1_off_t off, - const void *buf, tdb1_len_t len) -{ - uint32_t blk; - - /* break it up into block sized chunks */ - while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->block_size) { - tdb1_len_t len2 = tdb->tdb1.transaction->block_size - (off % tdb->tdb1.transaction->block_size); - if (transaction1_write_existing(tdb, off, buf, len2) != 0) { - return -1; - } - len -= len2; - off += len2; - if (buf != NULL) { - buf = (const void *)(len2 + (const char *)buf); - } - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->tdb1.transaction->block_size; - off = off % tdb->tdb1.transaction->block_size; - - if (tdb->tdb1.transaction->num_blocks <= blk || - tdb->tdb1.transaction->blocks[blk] == NULL) { - return 0; - } - - if (blk == tdb->tdb1.transaction->num_blocks-1 && - off + len > tdb->tdb1.transaction->last_block_size) { - if (off >= tdb->tdb1.transaction->last_block_size) { - return 0; - } - len = tdb->tdb1.transaction->last_block_size - off; - } - - /* overwrite part of an existing block */ - memcpy(tdb->tdb1.transaction->blocks[blk] + off, buf, len); - - return 0; -} - - -/* - accelerated hash chain head search, using the cached hash heads -*/ -static void transaction1_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - for (;h < tdb->tdb1.header.hash_size;h++) { - /* the +1 takes account of the freelist */ - if (0 != tdb->tdb1.transaction->hash_heads[h+1]) { - break; - } - } - (*chain) = h; -} - -/* - out of bounds check during a transaction -*/ -static int transaction1_oob(struct tdb_context *tdb, tdb1_off_t len, int probe) -{ - if (len <= tdb->file->map_size) { - return 0; - } - tdb->last_error = TDB_ERR_IO; - return -1; -} - -/* - transaction version of tdb1_expand(). -*/ -static int transaction1_expand_file(struct tdb_context *tdb, tdb1_off_t size, - tdb1_off_t addition) -{ - /* add a write to the transaction elements, so subsequent - reads see the zero data */ - if (transaction1_write(tdb, size, NULL, addition) != 0) { - return -1; - } - - tdb->tdb1.transaction->expanded = true; - - return 0; -} - -static const struct tdb1_methods transaction1_methods = { - transaction1_read, - transaction1_write, - transaction1_next_hash_chain, - transaction1_oob, - transaction1_expand_file, -}; - - -/* - start a tdb transaction. No token is returned, as only a single - transaction is allowed to be pending per tdb_context -*/ -static int _tdb1_transaction_start(struct tdb_context *tdb) -{ - /* some sanity checks */ - if (tdb->flags & TDB_INTERNAL) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, - TDB_LOG_USE_ERROR, - "tdb1_transaction_start:" - " cannot start a" - " transaction on an" - " internal tdb"); - return -1; - } - - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_RDONLY, - TDB_LOG_USE_ERROR, - "tdb_transaction_start:" - " cannot start a" - " transaction on a " - " read-only tdb"); - return -1; - } - - /* cope with nested tdb1_transaction_start() calls */ - if (tdb->tdb1.transaction != NULL) { - if (!(tdb->flags & TDB_ALLOW_NESTING)) { - tdb->last_error - = tdb_logerr(tdb, TDB_ERR_EINVAL, - TDB_LOG_USE_ERROR, - "tdb_transaction_start:" - " already inside transaction"); - return -1; - } - tdb->stats.transaction_nest++; - tdb->tdb1.transaction->nesting++; - return 0; - } - - if (tdb1_have_extra_locks(tdb)) { - /* the caller must not have any locks when starting a - transaction as otherwise we'll be screwed by lack - of nested locks in posix */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR, - "tdb1_transaction_start: cannot start a" - " transaction with locks held"); - return -1; - } - - if (tdb->tdb1.travlocks.next != NULL) { - /* you cannot use transactions inside a traverse (although you can use - traverse inside a transaction) as otherwise you can end up with - deadlock */ - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR, - "tdb1_transaction_start: cannot start a" - " transaction within a traverse"); - return -1; - } - - tdb->tdb1.transaction = (struct tdb1_transaction *) - calloc(sizeof(struct tdb1_transaction), 1); - if (tdb->tdb1.transaction == NULL) { - tdb->last_error = TDB_ERR_OOM; - return -1; - } - - /* a page at a time seems like a reasonable compromise between compactness and efficiency */ - tdb->tdb1.transaction->block_size = tdb->tdb1.page_size; - - /* get the transaction write lock. This is a blocking lock. As - discussed with Volker, there are a number of ways we could - make this async, which we will probably do in the future */ - if (tdb1_transaction_lock(tdb, F_WRLCK, TDB_LOCK_WAIT) == -1) { - SAFE_FREE(tdb->tdb1.transaction->blocks); - SAFE_FREE(tdb->tdb1.transaction); - return -1; - } - - /* get a read lock from the freelist to the end of file. This - is upgraded to a write lock during the commit */ - if (tdb1_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) { - if (errno != EAGAIN && errno != EINTR) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_start:" - " failed to get hash locks"); - } - goto fail_allrecord_lock; - } - - /* setup a copy of the hash table heads so the hash scan in - traverse can be fast */ - tdb->tdb1.transaction->hash_heads = (uint32_t *) - calloc(tdb->tdb1.header.hash_size+1, sizeof(uint32_t)); - if (tdb->tdb1.transaction->hash_heads == NULL) { - tdb->last_error = TDB_ERR_OOM; - goto fail; - } - if (tdb->tdb1.io->tdb1_read(tdb, TDB1_FREELIST_TOP, tdb->tdb1.transaction->hash_heads, - TDB1_HASHTABLE_SIZE(tdb), 0) != 0) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_start: failed to read hash heads"); - goto fail; - } - - /* make sure we know about any file expansions already done by - anyone else */ - tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1); - tdb->tdb1.transaction->old_map_size = tdb->file->map_size; - - /* finally hook the io methods, replacing them with - transaction specific methods */ - tdb->tdb1.transaction->io_methods = tdb->tdb1.io; - tdb->tdb1.io = &transaction1_methods; - - tdb->stats.transactions++; - return 0; - -fail: - tdb1_allrecord_unlock(tdb, F_RDLCK); -fail_allrecord_lock: - tdb1_transaction_unlock(tdb, F_WRLCK); - SAFE_FREE(tdb->tdb1.transaction->blocks); - SAFE_FREE(tdb->tdb1.transaction->hash_heads); - SAFE_FREE(tdb->tdb1.transaction); - return -1; -} - -int tdb1_transaction_start(struct tdb_context *tdb) -{ - return _tdb1_transaction_start(tdb); -} - -/* - sync to disk -*/ -static int transaction1_sync(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t length) -{ - if (tdb->flags & TDB_NOSYNC) { - return 0; - } - -#if HAVE_FDATASYNC - if (fdatasync(tdb->file->fd) != 0) { -#else - if (fsync(tdb->file->fd) != 0) { -#endif - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_transaction: fsync failed"); - return -1; - } -#if HAVE_MMAP - if (tdb->file->map_ptr) { - tdb1_off_t moffset = offset & ~(tdb->tdb1.page_size-1); - if (msync(moffset + (char *)tdb->file->map_ptr, - length + (offset - moffset), MS_SYNC) != 0) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_transaction:" - " msync failed - %s", - strerror(errno)); - return -1; - } - } -#endif - return 0; -} - - -static int _tdb1_transaction_cancel(struct tdb_context *tdb) -{ - int i, ret = 0; - - if (tdb->tdb1.transaction == NULL) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, - "tdb1_transaction_cancel:" - " no transaction"); - return -1; - } - - if (tdb->tdb1.transaction->nesting != 0) { - tdb->tdb1.transaction->transaction_error = 1; - tdb->tdb1.transaction->nesting--; - return 0; - } - - tdb->file->map_size = tdb->tdb1.transaction->old_map_size; - - /* free all the transaction blocks */ - for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) { - if (tdb->tdb1.transaction->blocks[i] != NULL) { - free(tdb->tdb1.transaction->blocks[i]); - } - } - SAFE_FREE(tdb->tdb1.transaction->blocks); - - if (tdb->tdb1.transaction->magic_offset) { - const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods; - const uint32_t invalid = TDB1_RECOVERY_INVALID_MAGIC; - - /* remove the recovery marker */ - if (methods->tdb1_write(tdb, tdb->tdb1.transaction->magic_offset, &invalid, 4) == -1 || - transaction1_sync(tdb, tdb->tdb1.transaction->magic_offset, 4) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_cancel: failed to" - " remove recovery magic"); - ret = -1; - } - } - - /* This also removes the OPEN_LOCK, if we have it. */ - tdb1_release_transaction_locks(tdb); - - /* restore the normal io methods */ - tdb->tdb1.io = tdb->tdb1.transaction->io_methods; - - SAFE_FREE(tdb->tdb1.transaction->hash_heads); - SAFE_FREE(tdb->tdb1.transaction); - - return ret; -} - -/* - cancel the current transaction -*/ -int tdb1_transaction_cancel(struct tdb_context *tdb) -{ - tdb->stats.transaction_cancel++; - return _tdb1_transaction_cancel(tdb); -} - -/* - work out how much space the linearised recovery data will consume -*/ -static tdb1_len_t tdb1_recovery_size(struct tdb_context *tdb) -{ - tdb1_len_t recovery_size = 0; - int i; - - recovery_size = sizeof(uint32_t); - for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) { - if (i * tdb->tdb1.transaction->block_size >= tdb->tdb1.transaction->old_map_size) { - break; - } - if (tdb->tdb1.transaction->blocks[i] == NULL) { - continue; - } - recovery_size += 2*sizeof(tdb1_off_t); - if (i == tdb->tdb1.transaction->num_blocks-1) { - recovery_size += tdb->tdb1.transaction->last_block_size; - } else { - recovery_size += tdb->tdb1.transaction->block_size; - } - } - - return recovery_size; -} - -int tdb1_recovery_area(struct tdb_context *tdb, - const struct tdb1_methods *methods, - tdb1_off_t *recovery_offset, - struct tdb1_record *rec) -{ - if (tdb1_ofs_read(tdb, TDB1_RECOVERY_HEAD, recovery_offset) == -1) { - return -1; - } - - if (*recovery_offset == 0) { - rec->rec_len = 0; - return 0; - } - - if (methods->tdb1_read(tdb, *recovery_offset, rec, sizeof(*rec), - TDB1_DOCONV()) == -1) { - return -1; - } - - /* ignore invalid recovery regions: can happen in crash */ - if (rec->magic != TDB1_RECOVERY_MAGIC && - rec->magic != TDB1_RECOVERY_INVALID_MAGIC) { - *recovery_offset = 0; - rec->rec_len = 0; - } - return 0; -} - -/* - allocate the recovery area, or use an existing recovery area if it is - large enough -*/ -static int tdb1_recovery_allocate(struct tdb_context *tdb, - tdb1_len_t *recovery_size, - tdb1_off_t *recovery_offset, - tdb1_len_t *recovery_max_size) -{ - struct tdb1_record rec; - const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods; - tdb1_off_t recovery_head; - - if (tdb1_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_recovery_allocate:" - " failed to read recovery head"); - return -1; - } - - *recovery_size = tdb1_recovery_size(tdb); - - if (recovery_head != 0 && *recovery_size <= rec.rec_len) { - /* it fits in the existing area */ - *recovery_max_size = rec.rec_len; - *recovery_offset = recovery_head; - return 0; - } - - /* we need to free up the old recovery area, then allocate a - new one at the end of the file. Note that we cannot use - tdb1_allocate() to allocate the new one as that might return - us an area that is being currently used (as of the start of - the transaction) */ - if (recovery_head != 0) { - if (tdb1_free(tdb, recovery_head, &rec) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_recovery_allocate: failed to free" - " previous recovery area"); - return -1; - } - } - - /* the tdb1_free() call might have increased the recovery size */ - *recovery_size = tdb1_recovery_size(tdb); - - /* round up to a multiple of page size */ - *recovery_max_size = TDB1_ALIGN(sizeof(rec) + *recovery_size, - tdb->tdb1.page_size) - sizeof(rec); - *recovery_offset = tdb->file->map_size; - recovery_head = *recovery_offset; - - if (methods->tdb1_expand_file(tdb, tdb->tdb1.transaction->old_map_size, - (tdb->file->map_size - tdb->tdb1.transaction->old_map_size) + - sizeof(rec) + *recovery_max_size) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_recovery_allocate:" - " failed to create recovery area"); - return -1; - } - tdb->stats.transaction_expand_file++; - - /* remap the file (if using mmap) */ - methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); - - /* we have to reset the old map size so that we don't try to expand the file - again in the transaction commit, which would destroy the recovery area */ - tdb->tdb1.transaction->old_map_size = tdb->file->map_size; - - /* write the recovery header offset and sync - we can sync without a race here - as the magic ptr in the recovery record has not been set */ - TDB1_CONV(recovery_head); - if (methods->tdb1_write(tdb, TDB1_RECOVERY_HEAD, - &recovery_head, sizeof(tdb1_off_t)) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_recovery_allocate:" - " failed to write recovery head"); - return -1; - } - if (transaction1_write_existing(tdb, TDB1_RECOVERY_HEAD, &recovery_head, sizeof(tdb1_off_t)) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_recovery_allocate:" - " failed to write recovery head"); - return -1; - } - - return 0; -} - - -/* - setup the recovery data that will be used on a crash during commit -*/ -static int transaction1_setup_recovery(struct tdb_context *tdb, - tdb1_off_t *magic_offset) -{ - tdb1_len_t recovery_size; - unsigned char *data, *p; - const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods; - struct tdb1_record *rec; - tdb1_off_t recovery_offset, recovery_max_size; - tdb1_off_t old_map_size = tdb->tdb1.transaction->old_map_size; - uint32_t magic, tailer; - int i; - - /* - check that the recovery area has enough space - */ - if (tdb1_recovery_allocate(tdb, &recovery_size, - &recovery_offset, &recovery_max_size) == -1) { - return -1; - } - - data = (unsigned char *)malloc(recovery_size + sizeof(*rec)); - if (data == NULL) { - tdb->last_error = TDB_ERR_OOM; - return -1; - } - - rec = (struct tdb1_record *)data; - memset(rec, 0, sizeof(*rec)); - - rec->magic = TDB1_RECOVERY_INVALID_MAGIC; - rec->data_len = recovery_size; - rec->rec_len = recovery_max_size; - rec->key_len = old_map_size; - TDB1_CONV(*rec); - - /* build the recovery data into a single blob to allow us to do a single - large write, which should be more efficient */ - p = data + sizeof(*rec); - for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) { - tdb1_off_t offset; - tdb1_len_t length; - - if (tdb->tdb1.transaction->blocks[i] == NULL) { - continue; - } - - offset = i * tdb->tdb1.transaction->block_size; - length = tdb->tdb1.transaction->block_size; - if (i == tdb->tdb1.transaction->num_blocks-1) { - length = tdb->tdb1.transaction->last_block_size; - } - - if (offset >= old_map_size) { - continue; - } - if (offset + length > tdb->tdb1.transaction->old_map_size) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, - TDB_LOG_ERROR, - "tdb1_transaction_setup_recovery: transaction data over new region boundary"); - free(data); - return -1; - } - memcpy(p, &offset, 4); - memcpy(p+4, &length, 4); - if (TDB1_DOCONV()) { - tdb1_convert(p, 8); - } - /* the recovery area contains the old data, not the - new data, so we have to call the original tdb1_read - method to get it */ - if (methods->tdb1_read(tdb, offset, p + 8, length, 0) != 0) { - free(data); - tdb->last_error = TDB_ERR_IO; - return -1; - } - p += 8 + length; - } - - /* and the tailer */ - tailer = sizeof(*rec) + recovery_max_size; - memcpy(p, &tailer, 4); - if (TDB1_DOCONV()) { - tdb1_convert(p, 4); - } - - /* write the recovery data to the recovery area */ - if (methods->tdb1_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_setup_recovery:" - " failed to write recovery data"); - free(data); - return -1; - } - if (transaction1_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_setup_recovery: failed to write" - " secondary recovery data"); - free(data); - return -1; - } - - /* as we don't have ordered writes, we have to sync the recovery - data before we update the magic to indicate that the recovery - data is present */ - if (transaction1_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { - free(data); - return -1; - } - - free(data); - - magic = TDB1_RECOVERY_MAGIC; - TDB1_CONV(magic); - - *magic_offset = recovery_offset + offsetof(struct tdb1_record, magic); - - if (methods->tdb1_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_setup_recovery:" - " failed to write recovery magic"); - return -1; - } - if (transaction1_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_setup_recovery:" - " failed to write secondary recovery magic"); - return -1; - } - - /* ensure the recovery magic marker is on disk */ - if (transaction1_sync(tdb, *magic_offset, sizeof(magic)) == -1) { - return -1; - } - - return 0; -} - -static int _tdb1_transaction_prepare_commit(struct tdb_context *tdb) -{ - const struct tdb1_methods *methods; - - if (tdb->tdb1.transaction == NULL) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, - "tdb1_transaction_prepare_commit:" - " no transaction"); - return -1; - } - - if (tdb->tdb1.transaction->prepared) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, - "tdb1_transaction_prepare_commit:" - " transaction already prepared"); - _tdb1_transaction_cancel(tdb); - return -1; - } - - if (tdb->tdb1.transaction->transaction_error) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_transaction_prepare_commit:" - " transaction error pending"); - _tdb1_transaction_cancel(tdb); - return -1; - } - - - if (tdb->tdb1.transaction->nesting != 0) { - return 0; - } - - /* check for a null transaction */ - if (tdb->tdb1.transaction->blocks == NULL) { - return 0; - } - - methods = tdb->tdb1.transaction->io_methods; - - /* if there are any locks pending then the caller has not - nested their locks properly, so fail the transaction */ - if (tdb1_have_extra_locks(tdb)) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR, - "tdb1_transaction_prepare_commit:" - " locks pending on commit"); - _tdb1_transaction_cancel(tdb); - return -1; - } - - /* upgrade the main transaction lock region to a write lock */ - if (tdb1_allrecord_upgrade(tdb) == -1) { - if (errno != EAGAIN && errno != EINTR) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_prepare_commit:" - " failed to upgrade hash locks"); - } - return -1; - } - - /* get the open lock - this prevents new users attaching to the database - during the commit */ - if (tdb1_nest_lock(tdb, TDB1_OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { - if (errno != EAGAIN && errno != EINTR) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_prepare_commit:" - " failed to get open lock"); - } - return -1; - } - - if (!(tdb->flags & TDB_NOSYNC)) { - /* write the recovery data to the end of the file */ - if (transaction1_setup_recovery(tdb, &tdb->tdb1.transaction->magic_offset) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_prepare_commit:" - " failed to setup recovery data"); - return -1; - } - } - - tdb->tdb1.transaction->prepared = true; - - /* expand the file to the new size if needed */ - if (tdb->file->map_size != tdb->tdb1.transaction->old_map_size) { - if (methods->tdb1_expand_file(tdb, tdb->tdb1.transaction->old_map_size, - tdb->file->map_size - - tdb->tdb1.transaction->old_map_size) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_prepare_commit:" - " expansion failed"); - return -1; - } - tdb->stats.transaction_expand_file++; - tdb->file->map_size = tdb->tdb1.transaction->old_map_size; - methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); - } - - /* Keep the open lock until the actual commit */ - - return 0; -} - -/* - prepare to commit the current transaction -*/ -int tdb1_transaction_prepare_commit(struct tdb_context *tdb) -{ - return _tdb1_transaction_prepare_commit(tdb); -} - -/* A repack is worthwhile if the largest is less than half total free. */ -static bool repack_worthwhile(struct tdb_context *tdb) -{ - tdb1_off_t ptr; - struct tdb1_record rec; - tdb1_len_t total = 0, largest = 0; - - if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP, &ptr) == -1) { - return false; - } - - while (ptr != 0 && tdb1_rec_free_read(tdb, ptr, &rec) == 0) { - total += rec.rec_len; - if (rec.rec_len > largest) { - largest = rec.rec_len; - } - ptr = rec.next; - } - - return total > largest * 2; -} - -/* - commit the current transaction -*/ -int tdb1_transaction_commit(struct tdb_context *tdb) -{ - const struct tdb1_methods *methods; - int i; - bool need_repack = false; - - if (tdb->tdb1.transaction == NULL) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, - "tdb1_transaction_commit:" - " no transaction"); - return -1; - } - - if (tdb->tdb1.transaction->transaction_error) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "tdb1_transaction_commit:" - " transaction error pending"); - _tdb1_transaction_cancel(tdb); - return -1; - } - - - if (tdb->tdb1.transaction->nesting != 0) { - tdb->tdb1.transaction->nesting--; - return 0; - } - - /* check for a null transaction */ - if (tdb->tdb1.transaction->blocks == NULL) { - _tdb1_transaction_cancel(tdb); - return 0; - } - - if (!tdb->tdb1.transaction->prepared) { - int ret = _tdb1_transaction_prepare_commit(tdb); - if (ret) { - _tdb1_transaction_cancel(tdb); - return ret; - } - } - - methods = tdb->tdb1.transaction->io_methods; - - /* perform all the writes */ - for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) { - tdb1_off_t offset; - tdb1_len_t length; - - if (tdb->tdb1.transaction->blocks[i] == NULL) { - continue; - } - - offset = i * tdb->tdb1.transaction->block_size; - length = tdb->tdb1.transaction->block_size; - if (i == tdb->tdb1.transaction->num_blocks-1) { - length = tdb->tdb1.transaction->last_block_size; - } - - if (methods->tdb1_write(tdb, offset, tdb->tdb1.transaction->blocks[i], length) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_commit:" - " write failed during commit"); - - /* we've overwritten part of the data and - possibly expanded the file, so we need to - run the crash recovery code */ - tdb->tdb1.io = methods; - tdb1_transaction_recover(tdb); - - _tdb1_transaction_cancel(tdb); - - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_commit: write failed"); - return -1; - } - SAFE_FREE(tdb->tdb1.transaction->blocks[i]); - } - - /* Do this before we drop lock or blocks. */ - if (tdb->tdb1.transaction->expanded) { - need_repack = repack_worthwhile(tdb); - } - - SAFE_FREE(tdb->tdb1.transaction->blocks); - tdb->tdb1.transaction->num_blocks = 0; - - /* ensure the new data is on disk */ - if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) { - return -1; - } - - /* - TODO: maybe write to some dummy hdr field, or write to magic - offset without mmap, before the last sync, instead of the - utime() call - */ - - /* on some systems (like Linux 2.6.x) changes via mmap/msync - don't change the mtime of the file, this means the file may - not be backed up (as tdb rounding to block sizes means that - file size changes are quite rare too). The following forces - mtime changes when a transaction completes */ -#if HAVE_UTIME - utime(tdb->name, NULL); -#endif - - /* use a transaction cancel to free memory and remove the - transaction locks */ - _tdb1_transaction_cancel(tdb); - - if (need_repack) { - if (tdb_repack(tdb) != 0) - return -1; - } - - return 0; -} - - -/* - recover from an aborted transaction. Must be called with exclusive - database write access already established (including the open - lock to prevent new processes attaching) -*/ -int tdb1_transaction_recover(struct tdb_context *tdb) -{ - tdb1_off_t recovery_head, recovery_eof; - unsigned char *data, *p; - uint32_t zero = 0; - struct tdb1_record rec; - - /* find the recovery area */ - if (tdb1_ofs_read(tdb, TDB1_RECOVERY_HEAD, &recovery_head) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover:" - " failed to read recovery head"); - return -1; - } - - if (recovery_head == 0) { - /* we have never allocated a recovery record */ - return 0; - } - - /* read the recovery record */ - if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, - sizeof(rec), TDB1_DOCONV()) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover:" - " failed to read recovery record"); - return -1; - } - - if (rec.magic != TDB1_RECOVERY_MAGIC) { - /* there is no valid recovery data */ - return 0; - } - - if (tdb->flags & TDB_RDONLY) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, - "tdb1_transaction_recover:" - " attempt to recover read only" - " database"); - return -1; - } - - recovery_eof = rec.key_len; - - data = (unsigned char *)malloc(rec.data_len); - if (data == NULL) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR, - "tdb1_transaction_recover:" - " failed to allocate recovery data"); - return -1; - } - - /* read the full recovery data */ - if (tdb->tdb1.io->tdb1_read(tdb, recovery_head + sizeof(rec), data, - rec.data_len, 0) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover:" - " failed to read recovery data"); - return -1; - } - - /* recover the file data */ - p = data; - while (p+8 < data + rec.data_len) { - uint32_t ofs, len; - if (TDB1_DOCONV()) { - tdb1_convert(p, 8); - } - memcpy(&ofs, p, 4); - memcpy(&len, p+4, 4); - - if (tdb->tdb1.io->tdb1_write(tdb, ofs, p+8, len) == -1) { - free(data); - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover: failed to recover" - " %d bytes at offset %d", len, ofs); - return -1; - } - p += 8 + len; - } - - free(data); - - if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover: failed to sync recovery"); - return -1; - } - - /* if the recovery area is after the recovered eof then remove it */ - if (recovery_eof <= recovery_head) { - if (tdb1_ofs_write(tdb, TDB1_RECOVERY_HEAD, &zero) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover: failed to remove" - " recovery head"); - return -1; - } - } - - /* remove the recovery magic */ - if (tdb1_ofs_write(tdb, recovery_head + offsetof(struct tdb1_record, magic), - &zero) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover: failed to remove" - " recovery magic"); - return -1; - } - - if (transaction1_sync(tdb, 0, recovery_eof) == -1) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_transaction_recover:" - " failed to sync2 recovery"); - return -1; - } - - tdb_logerr(tdb, TDB_SUCCESS, TDB_LOG_WARNING, - "tdb1_transaction_recover: recovered %d byte database", - recovery_eof); - - /* all done */ - return 0; -} - -/* Any I/O failures we say "needs recovery". */ -tdb_bool_err tdb1_needs_recovery(struct tdb_context *tdb) -{ - tdb1_off_t recovery_head; - struct tdb1_record rec; - - /* find the recovery area */ - if (tdb1_ofs_read(tdb, TDB1_RECOVERY_HEAD, &recovery_head) == -1) { - return TDB_ERR_TO_OFF(tdb->last_error); - } - - if (recovery_head == 0) { - /* we have never allocated a recovery record */ - return false; - } - - /* read the recovery record */ - if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, - sizeof(rec), TDB1_DOCONV()) == -1) { - return TDB_ERR_TO_OFF(tdb->last_error); - } - - return (rec.magic == TDB1_RECOVERY_MAGIC); -} diff --git a/lib/tdb2/tdb1_traverse.c b/lib/tdb2/tdb1_traverse.c deleted file mode 100644 index d9d3649fd9..0000000000 --- a/lib/tdb2/tdb1_traverse.c +++ /dev/null @@ -1,373 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include "tdb1_private.h" - -#define TDB1_NEXT_LOCK_ERR ((tdb1_off_t)-1) - -static TDB_DATA tdb1_null; - -/* Uses traverse lock: 0 = finish, TDB1_NEXT_LOCK_ERR = error, - other = record offset */ -static tdb1_off_t tdb1_next_lock(struct tdb_context *tdb, struct tdb1_traverse_lock *tlock, - struct tdb1_record *rec) -{ - int want_next = (tlock->off != 0); - - /* Lock each chain from the start one. */ - for (; tlock->hash < tdb->tdb1.header.hash_size; tlock->hash++) { - if (!tlock->off && tlock->hash != 0) { - /* this is an optimisation for the common case where - the hash chain is empty, which is particularly - common for the use of tdb with ldb, where large - hashes are used. In that case we spend most of our - time in tdb1_brlock(), locking empty hash chains. - - To avoid this, we do an unlocked pre-check to see - if the hash chain is empty before starting to look - inside it. If it is empty then we can avoid that - hash chain. If it isn't empty then we can't believe - the value we get back, as we read it without a - lock, so instead we get the lock and re-fetch the - value below. - - Notice that not doing this optimisation on the - first hash chain is critical. We must guarantee - that we have done at least one fcntl lock at the - start of a search to guarantee that memory is - coherent on SMP systems. If records are added by - others during the search then thats OK, and we - could possibly miss those with this trick, but we - could miss them anyway without this trick, so the - semantics don't change. - - With a non-indexed ldb search this trick gains us a - factor of around 80 in speed on a linux 2.6.x - system (testing using ldbtest). - */ - tdb->tdb1.io->next_hash_chain(tdb, &tlock->hash); - if (tlock->hash == tdb->tdb1.header.hash_size) { - continue; - } - } - - if (tdb1_lock(tdb, tlock->hash, tlock->lock_rw) == -1) - return TDB1_NEXT_LOCK_ERR; - - /* No previous record? Start at top of chain. */ - if (!tlock->off) { - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(tlock->hash), - &tlock->off) == -1) - goto fail; - } else { - /* Otherwise unlock the previous record. */ - if (tdb1_unlock_record(tdb, tlock->off) != 0) - goto fail; - } - - if (want_next) { - /* We have offset of old record: grab next */ - if (tdb1_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - tlock->off = rec->next; - } - - /* Iterate through chain */ - while( tlock->off) { - tdb1_off_t current; - if (tdb1_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - - /* Detect infinite loops. From "Shlomi Yaakobovich" <Shlomi@exanet.com>. */ - if (tlock->off == rec->next) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, - TDB_LOG_ERROR, - "tdb1_next_lock:" - " loop detected."); - goto fail; - } - - if (!TDB1_DEAD(rec)) { - /* Woohoo: we found one! */ - if (tdb1_lock_record(tdb, tlock->off) != 0) - goto fail; - return tlock->off; - } - - /* Try to clean dead ones from old traverses */ - current = tlock->off; - tlock->off = rec->next; - if (!((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) && - tdb1_do_delete(tdb, current, rec) != 0) - goto fail; - } - tdb1_unlock(tdb, tlock->hash, tlock->lock_rw); - want_next = 0; - } - /* We finished iteration without finding anything */ - tdb->last_error = TDB_SUCCESS; - return 0; - - fail: - tlock->off = 0; - if (tdb1_unlock(tdb, tlock->hash, tlock->lock_rw) != 0) - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_next_lock: On error unlock failed!"); - return TDB1_NEXT_LOCK_ERR; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -static int tdb1_traverse_internal(struct tdb_context *tdb, - int (*fn)(struct tdb_context *, - TDB_DATA, TDB_DATA, void *), - void *private_data, - struct tdb1_traverse_lock *tl) -{ - TDB_DATA key, dbuf; - struct tdb1_record rec; - int ret = 0, count = 0; - tdb1_off_t off; - - /* This was in the initializaton, above, but the IRIX compiler - * did not like it. crh - */ - tl->next = tdb->tdb1.travlocks.next; - - /* fcntl locks don't stack: beware traverse inside traverse */ - tdb->tdb1.travlocks.next = tl; - - /* tdb1_next_lock places locks on the record returned, and its chain */ - while ((off = tdb1_next_lock(tdb, tl, &rec)) != 0) { - if (off == TDB1_NEXT_LOCK_ERR) { - ret = -1; - goto out; - } - count++; - /* now read the full record */ - key.dptr = tdb1_alloc_read(tdb, tl->off + sizeof(rec), - rec.key_len + rec.data_len); - if (!key.dptr) { - ret = -1; - if (tdb1_unlock(tdb, tl->hash, tl->lock_rw) != 0) - goto out; - if (tdb1_unlock_record(tdb, tl->off) != 0) - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_traverse: key.dptr == NULL and" - " unlock_record failed!"); - goto out; - } - key.dsize = rec.key_len; - dbuf.dptr = key.dptr + rec.key_len; - dbuf.dsize = rec.data_len; - - /* Drop chain lock, call out */ - if (tdb1_unlock(tdb, tl->hash, tl->lock_rw) != 0) { - ret = -1; - SAFE_FREE(key.dptr); - goto out; - } - if (fn && fn(tdb, key, dbuf, private_data)) { - /* They want us to terminate traversal */ - if (tdb1_unlock_record(tdb, tl->off) != 0) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_traverse:" - " unlock_record failed!"); - ret = -1; - } - SAFE_FREE(key.dptr); - goto out; - } - SAFE_FREE(key.dptr); - } -out: - tdb->tdb1.travlocks.next = tl->next; - if (ret < 0) - return -1; - else - return count; -} - - -/* - a read style traverse - only if db read only -*/ -static int tdb1_traverse_read(struct tdb_context *tdb, - int (*fn)(struct tdb_context *, - TDB_DATA, TDB_DATA, void *), - void *private_data) -{ - struct tdb1_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; - int ret; - - /* we need to get a read lock on the transaction lock here to - cope with the lock ordering semantics of solaris10 */ - if (tdb1_transaction_lock(tdb, F_RDLCK, TDB_LOCK_WAIT)) { - return -1; - } - - tdb->tdb1.traverse_read++; - ret = tdb1_traverse_internal(tdb, fn, private_data, &tl); - tdb->tdb1.traverse_read--; - - tdb1_transaction_unlock(tdb, F_RDLCK); - - return ret; -} - -/* - a write style traverse - needs to get the transaction lock to - prevent deadlocks - - WARNING: The data buffer given to the callback fn does NOT meet the - alignment restrictions malloc gives you. -*/ -int tdb1_traverse(struct tdb_context *tdb, - int (*fn)(struct tdb_context *, TDB_DATA, TDB_DATA, void *), - void *private_data) -{ - struct tdb1_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; - int ret; - - /* If we're read-only, we don't have to write-lock whole db. */ - if (tdb->flags & TDB_RDONLY) { - return tdb1_traverse_read(tdb, fn, private_data); - } - - if (tdb1_transaction_lock(tdb, F_WRLCK, TDB_LOCK_WAIT)) { - return -1; - } - - tdb->tdb1.traverse_write++; - ret = tdb1_traverse_internal(tdb, fn, private_data, &tl); - tdb->tdb1.traverse_write--; - - tdb1_transaction_unlock(tdb, F_WRLCK); - - return ret; -} - - -/* find the first entry in the database and return its key */ -TDB_DATA tdb1_firstkey(struct tdb_context *tdb) -{ - TDB_DATA key; - struct tdb1_record rec; - tdb1_off_t off; - - /* release any old lock */ - if (tdb1_unlock_record(tdb, tdb->tdb1.travlocks.off) != 0) - return tdb1_null; - tdb->tdb1.travlocks.off = tdb->tdb1.travlocks.hash = 0; - tdb->tdb1.travlocks.lock_rw = F_RDLCK; - - /* Grab first record: locks chain and returned record. */ - off = tdb1_next_lock(tdb, &tdb->tdb1.travlocks, &rec); - if (off == 0 || off == TDB1_NEXT_LOCK_ERR) { - return tdb1_null; - } - /* now read the key */ - key.dsize = rec.key_len; - key.dptr =tdb1_alloc_read(tdb,tdb->tdb1.travlocks.off+sizeof(rec),key.dsize); - - /* Unlock the hash chain of the record we just read. */ - if (tdb1_unlock(tdb, tdb->tdb1.travlocks.hash, tdb->tdb1.travlocks.lock_rw) != 0) - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_firstkey:" - " error occurred while tdb1_unlocking!"); - return key; -} - -/* find the next entry in the database, returning its key */ -TDB_DATA tdb1_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) -{ - uint32_t oldhash; - TDB_DATA key = tdb1_null; - struct tdb1_record rec; - unsigned char *k = NULL; - tdb1_off_t off; - - /* Is locked key the old key? If so, traverse will be reliable. */ - if (tdb->tdb1.travlocks.off) { - if (tdb1_lock(tdb,tdb->tdb1.travlocks.hash,tdb->tdb1.travlocks.lock_rw)) - return tdb1_null; - if (tdb1_rec_read(tdb, tdb->tdb1.travlocks.off, &rec) == -1 - || !(k = tdb1_alloc_read(tdb,tdb->tdb1.travlocks.off+sizeof(rec), - rec.key_len)) - || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { - /* No, it wasn't: unlock it and start from scratch */ - if (tdb1_unlock_record(tdb, tdb->tdb1.travlocks.off) != 0) { - SAFE_FREE(k); - return tdb1_null; - } - if (tdb1_unlock(tdb, tdb->tdb1.travlocks.hash, tdb->tdb1.travlocks.lock_rw) != 0) { - SAFE_FREE(k); - return tdb1_null; - } - tdb->tdb1.travlocks.off = 0; - } - - SAFE_FREE(k); - } - - if (!tdb->tdb1.travlocks.off) { - /* No previous element: do normal find, and lock record */ - tdb->tdb1.travlocks.off = tdb1_find_lock_hash(tdb, oldkey, tdb_hash(tdb, oldkey.dptr, oldkey.dsize), tdb->tdb1.travlocks.lock_rw, &rec); - if (!tdb->tdb1.travlocks.off) { - return tdb1_null; - } - tdb->tdb1.travlocks.hash = TDB1_BUCKET(rec.full_hash); - if (tdb1_lock_record(tdb, tdb->tdb1.travlocks.off) != 0) { - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_nextkey: lock_record failed (%s)!", - strerror(errno)); - return tdb1_null; - } - } - oldhash = tdb->tdb1.travlocks.hash; - - /* Grab next record: locks chain and returned record, - unlocks old record */ - off = tdb1_next_lock(tdb, &tdb->tdb1.travlocks, &rec); - if (off != TDB1_NEXT_LOCK_ERR && off != 0) { - key.dsize = rec.key_len; - key.dptr = tdb1_alloc_read(tdb, tdb->tdb1.travlocks.off+sizeof(rec), - key.dsize); - /* Unlock the chain of this new record */ - if (tdb1_unlock(tdb, tdb->tdb1.travlocks.hash, tdb->tdb1.travlocks.lock_rw) != 0) - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_nextkey: WARNING tdb1_unlock failed!"); - } - /* Unlock the chain of old record */ - if (tdb1_unlock(tdb, TDB1_BUCKET(oldhash), tdb->tdb1.travlocks.lock_rw) != 0) - tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, - "tdb1_nextkey: WARNING tdb1_unlock failed!"); - return key; -} diff --git a/lib/tdb2/tdb2.h b/lib/tdb2/tdb2.h index 4782117e97..f7aa0cc310 100644 --- a/lib/tdb2/tdb2.h +++ b/lib/tdb2/tdb2.h @@ -103,22 +103,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, #define TDB_SEQNUM 128 /* maintain a sequence number */ #define TDB_ALLOW_NESTING 256 /* fake nested transactions */ #define TDB_RDONLY 512 /* implied by O_RDONLY */ -#define TDB_VERSION1 1024 /* create/open an old style TDB */ #define TDB_CANT_CHECK 2048 /* has a feature which we don't understand */ /** - * tdb1_incompatible_hash - better (Jenkins) hash for tdb1 - * - * This is better than the default hash for tdb1; but older versions of the - * tdb library (prior to version 1.2.6) won't be able to open them. - * - * It only makes sense to specify this (using tdb_attribute_hash) when - * creating (with O_CREAT) an old tdb version using TDB_VERSION1. It's - * equivalent to the TDB_INCOMPATIBLE_HASH flag for tdb1. - */ -uint64_t tdb1_incompatible_hash(const void *, size_t, uint64_t, void *); - -/** * tdb_close - close and free a tdb. * @tdb: the tdb context returned from tdb_open() * @@ -653,8 +640,6 @@ enum tdb_attribute_type { TDB_ATTRIBUTE_STATS = 3, TDB_ATTRIBUTE_OPENHOOK = 4, TDB_ATTRIBUTE_FLOCK = 5, - TDB_ATTRIBUTE_TDB1_HASHSIZE = 128, - TDB_ATTRIBUTE_TDB1_MAX_DEAD = 129, }; /** @@ -678,9 +663,8 @@ 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, - * TDB_ATTRIBUTE_OPENHOOK and TDB_ATTRIBUTE_TDB1_HASHSIZE cannot - * currently be set after tdb_open. + * Note that TDB_ATTRIBUTE_HASH, TDB_ATTRIBUTE_SEED, and + * TDB_ATTRIBUTE_OPENHOOK cannot currently be set after tdb_open. */ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, const union tdb_attribute *attr); @@ -887,32 +871,6 @@ struct tdb_attribute_flock { }; /** - * 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; -}; - -/** - * struct tdb_attribute_tdb1_max_dead - tdb1 number of maximum dead records. - * - * TDB1 has a method to speed up its slow free list: it lets a certain - * number of "dead" records build up before freeing them. This is - * particularly useful for volatile TDBs; setting it to 5 is - * equivalent to tdb1's TDB_VOLATILE flag. - */ -struct tdb_attribute_tdb1_max_dead { - struct tdb_attribute_base base; /* .attr = TDB_ATTRIBUTE_TDB1_MAX_DEAD */ - unsigned int max_dead; -}; - -/** * union tdb_attribute - tdb attributes. * * This represents all the known attributes. @@ -930,8 +888,6 @@ 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; - struct tdb_attribute_tdb1_max_dead tdb1_max_dead; }; #ifdef __cplusplus diff --git a/lib/tdb2/test/api-13-delete.c b/lib/tdb2/test/api-13-delete.c index c8ed580615..279b38645b 100644 --- a/lib/tdb2/test/api-13-delete.c +++ b/lib/tdb2/test/api-13-delete.c @@ -151,12 +151,7 @@ int main(int argc, char *argv[]) .data = &seed } }; 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 }; + TDB_NOMMAP|TDB_CONVERT }; /* These two values gave trouble before. */ int vals[] = { 755, 837 }; diff --git a/lib/tdb2/test/api-14-exists.c b/lib/tdb2/test/api-14-exists.c index 916e9b46f6..801c295893 100644 --- a/lib/tdb2/test/api-14-exists.c +++ b/lib/tdb2/test/api-14-exists.c @@ -38,12 +38,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 2 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { diff --git a/lib/tdb2/test/api-16-wipe_all.c b/lib/tdb2/test/api-16-wipe_all.c index f97dd0db42..3dfcc7a419 100644 --- a/lib/tdb2/test/api-16-wipe_all.c +++ b/lib/tdb2/test/api-16-wipe_all.c @@ -26,12 +26,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 4 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { diff --git a/lib/tdb2/test/api-21-parse_record.c b/lib/tdb2/test/api-21-parse_record.c index 6ac9543b52..150e1c9dd0 100644 --- a/lib/tdb2/test/api-21-parse_record.c +++ b/lib/tdb2/test/api-21-parse_record.c @@ -51,12 +51,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 2 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { diff --git a/lib/tdb2/test/api-55-transaction.c b/lib/tdb2/test/api-55-transaction.c index ece59d5cb5..c474c6abc3 100644 --- a/lib/tdb2/test/api-55-transaction.c +++ b/lib/tdb2/test/api-55-transaction.c @@ -13,10 +13,7 @@ int main(int argc, char *argv[]) struct tdb_context *tdb; unsigned char *buffer; 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data; diff --git a/lib/tdb2/test/api-80-tdb_fd.c b/lib/tdb2/test/api-80-tdb_fd.c index fea30979b9..63967b8aa6 100644 --- a/lib/tdb2/test/api-80-tdb_fd.c +++ b/lib/tdb2/test/api-80-tdb_fd.c @@ -12,12 +12,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 3); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { diff --git a/lib/tdb2/test/api-81-seqnum.c b/lib/tdb2/test/api-81-seqnum.c index 954b097b0f..8bf261d635 100644 --- a/lib/tdb2/test/api-81-seqnum.c +++ b/lib/tdb2/test/api-81-seqnum.c @@ -16,14 +16,9 @@ int main(int argc, char *argv[]) struct tdb_data data = tdb_mkdata("data", 4); 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 }; + TDB_NOMMAP|TDB_CONVERT }; - plan_tests(sizeof(flags) / sizeof(flags[0]) * 15 + 8 * 13); + plan_tests(sizeof(flags) / sizeof(flags[0]) * 15 + 4 * 13); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("api-81-seqnum.tdb", flags[i]|TDB_SEQNUM, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); @@ -39,9 +34,6 @@ int main(int argc, char *argv[]) free(d.dptr); ok1(tdb_get_seqnum(tdb) == seq); ok1(tdb_append(tdb, key, data) == TDB_SUCCESS); - /* Append in tdb1 (or store over value) bumps twice! */ - if (flags[i] & TDB_VERSION1) - seq++; ok1(tdb_get_seqnum(tdb) == ++seq); ok1(tdb_delete(tdb, key) == TDB_SUCCESS); @@ -57,9 +49,6 @@ int main(int argc, char *argv[]) ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); ok1(tdb_get_seqnum(tdb) == ++seq); - /* Append in tdb1 (or store over value) bumps twice! */ - if (flags[i] & TDB_VERSION1) - seq++; ok1(tdb_append(tdb, key, data) == TDB_SUCCESS); ok1(tdb_get_seqnum(tdb) == ++seq); ok1(tdb_delete(tdb, key) == TDB_SUCCESS); diff --git a/lib/tdb2/test/api-82-lockattr.c b/lib/tdb2/test/api-82-lockattr.c index 8dc4e2fa4e..b229eab83c 100644 --- a/lib/tdb2/test/api-82-lockattr.c +++ b/lib/tdb2/test/api-82-lockattr.c @@ -46,10 +46,7 @@ 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; union tdb_attribute lock_attr; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); @@ -65,14 +62,6 @@ int main(int argc, char *argv[]) for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { struct tdb_data d; - unsigned int num_oom_messages; - - /* TDB1 double logs here. */ - if (flags[i] & TDB_VERSION1) { - num_oom_messages = 2; - } else { - num_oom_messages = 1; - } /* Nonblocking open; expect no error message. */ lock_err = EAGAIN; @@ -114,7 +103,7 @@ int main(int argc, char *argv[]) ok1(tap_log_messages == 0); lock_err = ENOMEM; ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; /* Nonblocking fetch. */ @@ -126,7 +115,7 @@ int main(int argc, char *argv[]) ok1(tap_log_messages == 0); lock_err = ENOMEM; ok1(!tdb_exists(tdb, key)); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; lock_err = EAGAIN; @@ -137,7 +126,7 @@ int main(int argc, char *argv[]) ok1(tap_log_messages == 0); lock_err = ENOMEM; ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; /* Nonblocking delete. */ @@ -149,7 +138,7 @@ int main(int argc, char *argv[]) ok1(tap_log_messages == 0); lock_err = ENOMEM; ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; /* Nonblocking locks. */ @@ -161,7 +150,7 @@ int main(int argc, char *argv[]) ok1(tap_log_messages == 0); lock_err = ENOMEM; ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; lock_err = EAGAIN; @@ -172,7 +161,7 @@ int main(int argc, char *argv[]) ok1(tap_log_messages == 0); lock_err = ENOMEM; ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; lock_err = EAGAIN; @@ -211,7 +200,7 @@ int main(int argc, char *argv[]) trav_err = ENOMEM; lock_err = 0; ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK); - ok1(tap_log_messages == num_oom_messages); + ok1(tap_log_messages == 1); tap_log_messages = 0; /* Nonblocking transactions. */ diff --git a/lib/tdb2/test/api-83-openhook.c b/lib/tdb2/test/api-83-openhook.c index acafca78fa..191cf068c1 100644 --- a/lib/tdb2/test/api-83-openhook.c +++ b/lib/tdb2/test/api-83-openhook.c @@ -47,10 +47,7 @@ int main(int argc, char *argv[]) union tdb_attribute cif; struct tdb_data key = tdb_mkdata("key", 3); 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; cif.openhook.base.attr = TDB_ATTRIBUTE_OPENHOOK; cif.openhook.base.next = &tap_log_attr; diff --git a/lib/tdb2/test/api-91-get-stats.c b/lib/tdb2/test/api-91-get-stats.c index f7bc64524d..395db3fb18 100644 --- a/lib/tdb2/test/api-91-get-stats.c +++ b/lib/tdb2/test/api-91-get-stats.c @@ -13,10 +13,7 @@ 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 11); diff --git a/lib/tdb2/test/api-92-get-set-readonly.c b/lib/tdb2/test/api-92-get-set-readonly.c index eddb0d4fe2..46aea7ae0d 100644 --- a/lib/tdb2/test/api-92-get-set-readonly.c +++ b/lib/tdb2/test/api-92-get-set-readonly.c @@ -8,15 +8,12 @@ int main(int argc, char *argv[]) { - unsigned int i, extra_msgs; + unsigned int i; 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 48); @@ -27,13 +24,6 @@ int main(int argc, char *argv[]) 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); @@ -43,17 +33,14 @@ int main(int argc, char *argv[]) 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); @@ -91,17 +78,14 @@ int main(int argc, char *argv[]) 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); diff --git a/lib/tdb2/test/api-93-repack.c b/lib/tdb2/test/api-93-repack.c index a1b5154524..910eb9b301 100644 --- a/lib/tdb2/test/api-93-repack.c +++ b/lib/tdb2/test/api-93-repack.c @@ -53,10 +53,7 @@ int main(int argc, char *argv[]) bool found[NUM_TESTS]; struct tdb_context *tdb; int flags[] = { TDB_DEFAULT, TDB_NOMMAP, - TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT, - TDB_VERSION1, TDB_VERSION1|TDB_NOMMAP, - TDB_VERSION1|TDB_CONVERT, - TDB_VERSION1|TDB_NOMMAP|TDB_CONVERT + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 6 + 1); diff --git a/lib/tdb2/test/api-add-remove-flags.c b/lib/tdb2/test/api-add-remove-flags.c index 2526bf45b6..a72b609fcb 100644 --- a/lib/tdb2/test/api-add-remove-flags.c +++ b/lib/tdb2/test/api-add-remove-flags.c @@ -12,14 +12,9 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; - plan_tests(173); + plan_tests(87); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("run-add-remove-flags.tdb", flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); diff --git a/lib/tdb2/test/api-check-callback.c b/lib/tdb2/test/api-check-callback.c index e49d00f904..96ef09f3bd 100644 --- a/lib/tdb2/test/api-check-callback.c +++ b/lib/tdb2/test/api-check-callback.c @@ -58,12 +58,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 4 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { diff --git a/lib/tdb2/test/api-firstkey-nextkey.c b/lib/tdb2/test/api-firstkey-nextkey.c index 56b3c25fb0..e5a7c5f8b5 100644 --- a/lib/tdb2/test/api-firstkey-nextkey.c +++ b/lib/tdb2/test/api-firstkey-nextkey.c @@ -56,12 +56,7 @@ int main(int argc, char *argv[]) enum TDB_ERROR ecode; 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 }; + TDB_NOMMAP|TDB_CONVERT }; seed_attr.base.attr = TDB_ATTRIBUTE_SEED; seed_attr.base.next = &tap_log_attr; @@ -72,7 +67,7 @@ int main(int argc, char *argv[]) for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("api-firstkey-nextkey.tdb", flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600, - flags[i] & TDB_VERSION1 ? NULL : &seed_attr); + &seed_attr); ok1(tdb); if (!tdb) continue; diff --git a/lib/tdb2/test/api-fork-test.c b/lib/tdb2/test/api-fork-test.c index 988004e90a..934c71cbe8 100644 --- a/lib/tdb2/test/api-fork-test.c +++ b/lib/tdb2/test/api-fork-test.c @@ -25,24 +25,16 @@ static enum TDB_ERROR fork_in_parse(TDB_DATA key, TDB_DATA data, struct tdb_context *tdb) { - int status, extra_messages; - - if (tdb_get_flags(tdb) & TDB_VERSION1) { - extra_messages = 1; - } else { - extra_messages = 0; - } + int status; if (fork() == 0) { /* We expect this to fail. */ if (tdb_store(tdb, key, data, TDB_REPLACE) != TDB_ERR_LOCK) exit(1); - tap_log_messages -= extra_messages; if (tdb_fetch(tdb, key, &data) != TDB_ERR_LOCK) exit(1); - tap_log_messages -= extra_messages; if (tap_log_messages != 2) exit(2); @@ -61,22 +53,13 @@ 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { - int status, extra_messages; - - if (flags[i] & TDB_VERSION1) { - extra_messages = 1; - } else { - extra_messages = 0; - } + int status; tap_log_messages = 0; @@ -93,11 +76,9 @@ int main(int argc, char *argv[]) /* We expect this to fail. */ if (tdb_store(tdb, key, data, TDB_REPLACE) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tdb_fetch(tdb, key, &data) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tap_log_messages != 2) return 2; @@ -119,11 +100,9 @@ int main(int argc, char *argv[]) /* We expect this to fail. */ if (tdb_store(tdb, key, data, TDB_REPLACE) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tdb_fetch(tdb, key, &data) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tap_log_messages != 2) return 2; @@ -146,11 +125,9 @@ int main(int argc, char *argv[]) /* This would always fail anyway... */ if (tdb_store(tdb, key, data, TDB_REPLACE) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tdb_fetch(tdb, key, &data) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tap_log_messages != 2) return 2; @@ -174,18 +151,15 @@ int main(int argc, char *argv[]) /* We expect this to fail. */ if (tdb_store(tdb, key, data, TDB_REPLACE) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tdb_fetch(tdb, key, &data) != TDB_ERR_LOCK) return 1; - tap_log_messages -= extra_messages; if (tap_log_messages != 2) return 2; if (tdb_transaction_commit(tdb) != TDB_ERR_LOCK) return 3; - tap_log_messages -= extra_messages; tdb_close(tdb); if (tap_log_messages < 3) diff --git a/lib/tdb2/test/api-locktimeout.c b/lib/tdb2/test/api-locktimeout.c index 2466817a13..dabe262f25 100644 --- a/lib/tdb2/test/api-locktimeout.c +++ b/lib/tdb2/test/api-locktimeout.c @@ -133,10 +133,7 @@ int main(int argc, char *argv[]) struct tdb_context *tdb; TDB_DATA key = tdb_mkdata("hello", 5); 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; struct agent *agent; plan_tests(sizeof(flags) / sizeof(flags[0]) * 15); diff --git a/lib/tdb2/test/api-open-multiple-times.c b/lib/tdb2/test/api-open-multiple-times.c index f976c95403..38aea135ac 100644 --- a/lib/tdb2/test/api-open-multiple-times.c +++ b/lib/tdb2/test/api-open-multiple-times.c @@ -9,16 +9,13 @@ int main(int argc, char *argv[]) { - unsigned int i, extra_messages; + unsigned int i; 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 28); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { @@ -28,11 +25,6 @@ int main(int argc, char *argv[]) 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); @@ -65,15 +57,12 @@ int main(int argc, char *argv[]) /* 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. */ diff --git a/lib/tdb2/test/api-record-expand.c b/lib/tdb2/test/api-record-expand.c index 686dcf3267..34799ebe5e 100644 --- a/lib/tdb2/test/api-record-expand.c +++ b/lib/tdb2/test/api-record-expand.c @@ -16,12 +16,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data; diff --git a/lib/tdb2/test/api-simple-delete.c b/lib/tdb2/test/api-simple-delete.c index bd228d654e..48b077a6db 100644 --- a/lib/tdb2/test/api-simple-delete.c +++ b/lib/tdb2/test/api-simple-delete.c @@ -12,12 +12,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); diff --git a/lib/tdb2/test/api-summary.c b/lib/tdb2/test/api-summary.c index babccc7cf4..e9dfd270e9 100644 --- a/lib/tdb2/test/api-summary.c +++ b/lib/tdb2/test/api-summary.c @@ -13,12 +13,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = { (unsigned char *)&j, sizeof(j) }; struct tdb_data data = { (unsigned char *)&j, sizeof(j) }; char *summary; @@ -46,8 +41,7 @@ int main(int argc, char *argv[]) ok1(strstr(summary, "Number of records: 500\n")); ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); - if (!(flags[i] & TDB_VERSION1) - && j == TDB_SUMMARY_HISTOGRAMS) { + if (j == TDB_SUMMARY_HISTOGRAMS) { ok1(strstr(summary, "|") && strstr(summary, "*")); } else { diff --git a/lib/tdb2/test/api-tdb1-flag-removal.c b/lib/tdb2/test/api-tdb1-flag-removal.c deleted file mode 100644 index 59994dfa5c..0000000000 --- a/lib/tdb2/test/api-tdb1-flag-removal.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "config.h" -#include "tdb2.h" -#include "tap-interface.h" -#include <ccan/hash/hash.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "logging.h" - -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 }; - - plan_tests(sizeof(flags) / sizeof(flags[0]) * 3 + 1); - for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { - tdb = tdb_open("run-12-store.tdb", flags[i], - O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); - if (!ok1(tdb)) - continue; - - tdb_close(tdb); - - tdb = tdb_open("run-12-store.tdb", flags[i] | TDB_VERSION1, - O_RDWR, 0600, &tap_log_attr); - if (!ok1(tdb)) - continue; - /* It's not a version1 */ - ok1(!(tdb_get_flags(tdb) & TDB_VERSION1)); - - tdb_close(tdb); - } - - ok1(tap_log_messages == 0); - return exit_status(); -} diff --git a/lib/tdb2/test/failtest_helper.h b/lib/tdb2/test/failtest_helper.h index 4130aff1eb..3c509e7c38 100644 --- a/lib/tdb2/test/failtest_helper.h +++ b/lib/tdb2/test/failtest_helper.h @@ -4,7 +4,7 @@ #include <stdbool.h> /* FIXME: Check these! */ -#define INITIAL_TDB_MALLOC "open.c", 445, FAILTEST_MALLOC +#define INITIAL_TDB_MALLOC "open.c", 403, FAILTEST_MALLOC #define URANDOM_OPEN "open.c", 62, FAILTEST_OPEN #define URANDOM_READ "open.c", 42, FAILTEST_READ diff --git a/lib/tdb2/test/helpapi-external-agent.c b/lib/tdb2/test/helpapi-external-agent.c index 140ffaf116..59e1c6cbee 100644 --- a/lib/tdb2/test/helpapi-external-agent.c +++ b/lib/tdb2/test/helpapi-external-agent.c @@ -1,5 +1,4 @@ #include "external-agent.h" -#include "tdb1_private.h" /* This isn't possible with via the tdb2 API, but this makes it link. */ enum agent_return external_agent_needs_rec(struct tdb_context *tdb) diff --git a/lib/tdb2/test/helprun-external-agent.c b/lib/tdb2/test/helprun-external-agent.c index 469847be75..9f243824fd 100644 --- a/lib/tdb2/test/helprun-external-agent.c +++ b/lib/tdb2/test/helprun-external-agent.c @@ -1,10 +1,7 @@ #include "external-agent.h" -#include "tdb1_private.h" +#include "private.h" enum agent_return external_agent_needs_rec(struct tdb_context *tdb) { - if (tdb->flags & TDB_VERSION1) - return tdb1_needs_recovery(tdb) ? SUCCESS : FAILED; - else - return tdb_needs_recovery(tdb) ? SUCCESS : FAILED; + return tdb_needs_recovery(tdb) ? SUCCESS : FAILED; } diff --git a/lib/tdb2/test/jenkins-be-hash.tdb1 b/lib/tdb2/test/jenkins-be-hash.tdb1 Binary files differdeleted file mode 100644 index b652840414..0000000000 --- a/lib/tdb2/test/jenkins-be-hash.tdb1 +++ /dev/null diff --git a/lib/tdb2/test/jenkins-le-hash.tdb1 b/lib/tdb2/test/jenkins-le-hash.tdb1 Binary files differdeleted file mode 100644 index 007e0a3368..0000000000 --- a/lib/tdb2/test/jenkins-le-hash.tdb1 +++ /dev/null diff --git a/lib/tdb2/test/lock-tracking.c b/lib/tdb2/test/lock-tracking.c index 4a61f9c312..c7387ead99 100644 --- a/lib/tdb2/test/lock-tracking.c +++ b/lib/tdb2/test/lock-tracking.c @@ -1,5 +1,5 @@ /* We save the locks so we can reaquire them. */ -#include "tdb1_private.h" /* For TDB_HASH_LOCK_START, TDB1_FREELIST_TOP, etc. */ +#include "private.h" /* For TDB_HASH_LOCK_START, etc. */ #include <unistd.h> #include <fcntl.h> #include <stdarg.h> @@ -110,17 +110,6 @@ int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ) i->type = F_WRLCK; goto done; } - /* allrecord upgrade for tdb1. */ - if (i->type == F_RDLCK && fl->l_type == F_WRLCK - && i->off == TDB1_FREELIST_TOP - && fl->l_start == TDB1_FREELIST_TOP - && i->len == 0 - && fl->l_len == 0) { - if (ret == 0) - i->type = F_WRLCK; - goto done; - } - if (!suppress_lockcheck) { diag("%s lock %u@%u overlaps %u@%u", fl->l_type == F_WRLCK ? "write" : "read", diff --git a/lib/tdb2/test/old-nohash-be.tdb1 b/lib/tdb2/test/old-nohash-be.tdb1 Binary files differdeleted file mode 100644 index 1c49116c1d..0000000000 --- a/lib/tdb2/test/old-nohash-be.tdb1 +++ /dev/null diff --git a/lib/tdb2/test/old-nohash-le.tdb1 b/lib/tdb2/test/old-nohash-le.tdb1 Binary files differdeleted file mode 100644 index 0655072d88..0000000000 --- a/lib/tdb2/test/old-nohash-le.tdb1 +++ /dev/null diff --git a/lib/tdb2/test/run-01-new_database.c b/lib/tdb2/test/run-01-new_database.c index 2876868842..00c15140df 100644 --- a/lib/tdb2/test/run-01-new_database.c +++ b/lib/tdb2/test/run-01-new_database.c @@ -11,12 +11,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; failtest_init(argc, argv); failtest_hook = block_repeat_failures; diff --git a/lib/tdb2/test/run-05-readonly-open.c b/lib/tdb2/test/run-05-readonly-open.c index 4827b425da..1046a8b47e 100644 --- a/lib/tdb2/test/run-05-readonly-open.c +++ b/lib/tdb2/test/run-05-readonly-open.c @@ -10,10 +10,7 @@ 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4), d; union tdb_attribute seed_attr; @@ -32,8 +29,7 @@ int main(int argc, char *argv[]) for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { tdb = tdb_open("run-05-readonly-open.tdb", flags[i], O_RDWR|O_CREAT|O_TRUNC, 0600, - flags[i] & TDB_VERSION1 - ? &tap_log_attr : &seed_attr); + &seed_attr); ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); tdb_close(tdb); diff --git a/lib/tdb2/test/run-10-simple-store.c b/lib/tdb2/test/run-10-simple-store.c index 3fba81d22d..66bf6a6a51 100644 --- a/lib/tdb2/test/run-10-simple-store.c +++ b/lib/tdb2/test/run-10-simple-store.c @@ -11,12 +11,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); diff --git a/lib/tdb2/test/run-11-simple-fetch.c b/lib/tdb2/test/run-11-simple-fetch.c index 8cd63dedcd..4c41ceec6d 100644 --- a/lib/tdb2/test/run-11-simple-fetch.c +++ b/lib/tdb2/test/run-11-simple-fetch.c @@ -11,12 +11,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); diff --git a/lib/tdb2/test/run-12-check.c b/lib/tdb2/test/run-12-check.c index 4173fb05c8..cc57726f93 100644 --- a/lib/tdb2/test/run-12-check.c +++ b/lib/tdb2/test/run-12-check.c @@ -12,11 +12,7 @@ int main(int argc, char *argv[]) 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 }; + TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); diff --git a/lib/tdb2/test/run-15-append.c b/lib/tdb2/test/run-15-append.c index 8102d3967d..6578b70734 100644 --- a/lib/tdb2/test/run-15-append.c +++ b/lib/tdb2/test/run-15-append.c @@ -12,12 +12,6 @@ static tdb_off_t tdb_offset(struct tdb_context *tdb, struct tdb_data key) struct tdb_used_record urec; struct hash_info h; - if (tdb_get_flags(tdb) & TDB_VERSION1) { - struct tdb1_record rec; - return tdb1_find(tdb, key, tdb_hash(tdb, key.dptr, key.dsize), - &rec); - } - off = find_and_lock(tdb, key, F_RDLCK, &h, &urec, NULL); if (TDB_OFF_IS_ERR(off)) return 0; @@ -33,12 +27,7 @@ int main(int argc, char *argv[]) tdb_off_t oldoff = 0, newoff; 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 }; + TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data; @@ -75,15 +64,9 @@ int main(int argc, char *argv[]) } ok1(!tdb->file || (tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0)); - if (flags[i] & TDB_VERSION1) { - /* TDB1 simply over-size by 25%. */ - ok(moves <= ilog64(j / SIZE_STEP)*4, - "Moved %u times", moves); - } else { - /* We should increase by 50% each time... */ - ok(moves <= ilog64(j / SIZE_STEP)*2, - "Moved %u times", moves); - } + /* We should increase by 50% each time... */ + ok(moves <= ilog64(j / SIZE_STEP)*2, + "Moved %u times", moves); tdb_close(tdb); } @@ -114,15 +97,9 @@ int main(int argc, char *argv[]) } ok1(!tdb->file || (tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0)); - if (flags[i] & TDB_VERSION1) { - /* TDB1 simply over-size by 25%. */ - ok(moves <= ilog64(j / SIZE_STEP)*4, - "Moved %u times", moves); - } else { - /* We should increase by 50% each time... */ - ok(moves <= ilog64(j / SIZE_STEP)*2, - "Moved %u times", moves); - } + /* We should increase by 50% each time... */ + ok(moves <= ilog64(j / SIZE_STEP)*2, + "Moved %u times", moves); tdb_close(tdb); } diff --git a/lib/tdb2/test/run-35-convert.c b/lib/tdb2/test/run-35-convert.c index 0aee0ca625..ac7939591b 100644 --- a/lib/tdb2/test/run-35-convert.c +++ b/lib/tdb2/test/run-35-convert.c @@ -11,10 +11,7 @@ int main(int argc, char *argv[]) unsigned int i, messages = 0; 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; failtest_init(argc, argv); failtest_hook = block_repeat_failures; diff --git a/lib/tdb2/test/run-56-open-during-transaction.c b/lib/tdb2/test/run-56-open-during-transaction.c index f6fd36f6e3..c514caa92b 100644 --- a/lib/tdb2/test/run-56-open-during-transaction.c +++ b/lib/tdb2/test/run-56-open-during-transaction.c @@ -128,10 +128,7 @@ static int ftruncate_check(int fd, off_t length) int main(int argc, char *argv[]) { const 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; int i; struct tdb_context *tdb; TDB_DATA key, data; diff --git a/lib/tdb2/test/run-57-die-during-transaction.c b/lib/tdb2/test/run-57-die-during-transaction.c index 595d6ae23b..ee33a896ff 100644 --- a/lib/tdb2/test/run-57-die-during-transaction.c +++ b/lib/tdb2/test/run-57-die-during-transaction.c @@ -151,7 +151,7 @@ static int ftruncate_check(int fd, off_t length) return ret; } -static bool test_death(enum operation op, struct agent *agent, int flags) +static bool test_death(enum operation op, struct agent *agent) { struct tdb_context *tdb = NULL; TDB_DATA key; @@ -161,7 +161,7 @@ static bool test_death(enum operation op, struct agent *agent, int flags) current = target = 0; reset: unlink(TEST_DBNAME); - tdb = tdb_open(TEST_DBNAME, flags|TDB_NOMMAP, + tdb = tdb_open(TEST_DBNAME, TDB_NOMMAP, O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr); if (!tdb) { diag("Failed opening TDB: %s", strerror(errno)); @@ -273,9 +273,9 @@ int main(int argc, char *argv[]) { enum operation ops[] = { FETCH, STORE, TRANSACTION_START }; struct agent *agent; - int i, flags; + int i; - plan_tests(24); + plan_tests(12); unlock_callback = maybe_die; external_agent_free = free_noleak; @@ -283,11 +283,9 @@ int main(int argc, char *argv[]) if (!agent) err(1, "preparing agent"); - for (flags = TDB_DEFAULT; flags <= TDB_VERSION1; flags += TDB_VERSION1) { - for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { - diag("Testing %s after death", operation_name(ops[i])); - ok1(test_death(ops[i], agent, flags)); - } + for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { + diag("Testing %s after death", operation_name(ops[i])); + ok1(test_death(ops[i], agent)); } free_external_agent(agent); diff --git a/lib/tdb2/test/run-90-get-set-attributes.c b/lib/tdb2/test/run-90-get-set-attributes.c index b6a9075b6d..edf0735013 100644 --- a/lib/tdb2/test/run-90-get-set-attributes.c +++ b/lib/tdb2/test/run-90-get-set-attributes.c @@ -24,10 +24,7 @@ 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; union tdb_attribute seed_attr; union tdb_attribute hash_attr; union tdb_attribute lock_attr; @@ -47,8 +44,7 @@ int main(int argc, char *argv[]) lock_attr.flock.unlock = myunlock; lock_attr.flock.data = &lock_attr; - plan_tests(sizeof(flags) / sizeof(flags[0]) * 49 - + sizeof(flags) / sizeof(flags[0]) / 2); + plan_tests(sizeof(flags) / sizeof(flags[0]) * 50); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { union tdb_attribute attr; @@ -65,26 +61,17 @@ int main(int argc, char *argv[]) attr.base.attr = TDB_ATTRIBUTE_HASH; ok1(tdb_get_attribute(tdb, &attr) == 0); ok1(attr.base.attr == TDB_ATTRIBUTE_HASH); - if (flags[i] & TDB_VERSION1) { - ok1(attr.hash.fn == tdb1_old_hash); - } else { - ok1(attr.hash.fn == tdb_jenkins_hash); - } + ok1(attr.hash.fn == tdb_jenkins_hash); attr.base.attr = TDB_ATTRIBUTE_FLOCK; ok1(tdb_get_attribute(tdb, &attr) == 0); ok1(attr.base.attr == TDB_ATTRIBUTE_FLOCK); ok1(attr.flock.lock == tdb_fcntl_lock); ok1(attr.flock.unlock == tdb_fcntl_unlock); attr.base.attr = TDB_ATTRIBUTE_SEED; - if (flags[i] & TDB_VERSION1) { - ok1(tdb_get_attribute(tdb, &attr) == TDB_ERR_EINVAL); - tap_log_messages = 0; - } else { - ok1(tdb_get_attribute(tdb, &attr) == 0); - ok1(attr.base.attr == TDB_ATTRIBUTE_SEED); - /* This is possible, just astronomically unlikely. */ - ok1(attr.seed.seed != 0); - } + ok1(tdb_get_attribute(tdb, &attr) == 0); + ok1(attr.base.attr == TDB_ATTRIBUTE_SEED); + /* This is possible, just astronomically unlikely. */ + ok1(attr.seed.seed != 0); /* Unset attributes. */ tdb_unset_attribute(tdb, TDB_ATTRIBUTE_LOG); @@ -128,14 +115,6 @@ int main(int argc, char *argv[]) O_RDWR|O_CREAT|O_TRUNC, 0600, &seed_attr); - if (flags[i] & TDB_VERSION1) { - ok1(!tdb); - ok1(tap_log_messages == 1); - tap_log_messages = 0; - tdb = tdb_open("run-90-get-set-attributes.tdb", flags[i], - O_RDWR|O_CREAT|O_TRUNC, 0600, - &hash_attr); - } ok1(tdb); /* Get will succeed */ @@ -159,15 +138,9 @@ int main(int argc, char *argv[]) ok1(attr.flock.data == &lock_attr); attr.base.attr = TDB_ATTRIBUTE_SEED; - if (flags[i] & TDB_VERSION1) { - ok1(tdb_get_attribute(tdb, &attr) == TDB_ERR_EINVAL); - ok1(tap_log_messages == 1); - tap_log_messages = 0; - } else { - ok1(tdb_get_attribute(tdb, &attr) == 0); - ok1(attr.base.attr == TDB_ATTRIBUTE_SEED); - ok1(attr.seed.seed == seed_attr.seed.seed); - } + ok1(tdb_get_attribute(tdb, &attr) == 0); + ok1(attr.base.attr == TDB_ATTRIBUTE_SEED); + ok1(attr.seed.seed == seed_attr.seed.seed); /* Unset attributes. */ tdb_unset_attribute(tdb, TDB_ATTRIBUTE_HASH); diff --git a/lib/tdb2/test/run-expand-in-transaction.c b/lib/tdb2/test/run-expand-in-transaction.c index 2e9919c0f1..6b22d2ef46 100644 --- a/lib/tdb2/test/run-expand-in-transaction.c +++ b/lib/tdb2/test/run-expand-in-transaction.c @@ -7,10 +7,7 @@ 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; struct tdb_data key = tdb_mkdata("key", 3); struct tdb_data data = tdb_mkdata("data", 4); diff --git a/lib/tdb2/test/run-lockall.c b/lib/tdb2/test/run-lockall.c index 23273135bc..3ae0d14f65 100644 --- a/lib/tdb2/test/run-lockall.c +++ b/lib/tdb2/test/run-lockall.c @@ -21,10 +21,7 @@ int main(int argc, char *argv[]) { struct agent *agent; 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 }; + TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; int i; plan_tests(13 * sizeof(flags)/sizeof(flags[0]) + 1); diff --git a/lib/tdb2/test/run-tdb1-3G-file.c b/lib/tdb2/test/run-tdb1-3G-file.c deleted file mode 100644 index a278561c77..0000000000 --- a/lib/tdb2/test/run-tdb1-3G-file.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -static int tdb1_expand_file_sparse(struct tdb_context *tdb, - tdb1_off_t size, - tdb1_off_t addition) -{ - if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) { - tdb->last_error = TDB_ERR_RDONLY; - return -1; - } - - if (ftruncate(tdb->file->fd, size+addition) == -1) { - char b = 0; - ssize_t written = pwrite(tdb->file->fd, &b, 1, (size+addition) - 1); - if (written == 0) { - /* try once more, potentially revealing errno */ - written = pwrite(tdb->file->fd, &b, 1, (size+addition) - 1); - } - if (written == 0) { - /* again - give up, guessing errno */ - errno = ENOSPC; - } - if (written != 1) { - tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, - "expand_file to %d failed (%s)", - size+addition, - strerror(errno)); - return -1; - } - } - - return 0; -} - -static const struct tdb1_methods large_io_methods = { - tdb1_read, - tdb1_write, - tdb1_next_hash_chain, - tdb1_oob, - tdb1_expand_file_sparse -}; - -static int test_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *_data) -{ - TDB_DATA *expect = _data; - ok1(key.dsize == strlen("hi")); - ok1(memcmp(key.dptr, "hi", strlen("hi")) == 0); - ok1(data.dsize == expect->dsize); - ok1(memcmp(data.dptr, expect->dptr, data.dsize) == 0); - return 0; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, orig_data, data; - uint32_t hash; - tdb1_off_t rec_ptr; - struct tdb1_record rec; - union tdb_attribute hsize; - int ret; - - hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; - hsize.base.next = &tap_log_attr; - hsize.tdb1_hashsize.hsize = 1024; - - plan_tests(26); - tdb = tdb_open("run-36-file.tdb1", TDB_VERSION1, - O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); - - ok1(tdb); - tdb->tdb1.io = &large_io_methods; - - key = tdb_mkdata("hi", strlen("hi")); - orig_data = tdb_mkdata("world", strlen("world")); - - /* Enlarge the file (internally multiplies by 2). */ - ret = tdb1_expand(tdb, 1500000000); - -#ifdef HAVE_INCOHERENT_MMAP - /* This can fail due to mmap failure on 32 bit systems. */ - if (ret == -1) { - /* These should now fail. */ - ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == TDB_ERR_IO); - ok1(tdb_fetch(tdb, key, &data) == TDB_ERR_IO); - ok1(tdb_traverse(tdb, test_traverse, &orig_data) == TDB_ERR_IO); - ok1(tdb_delete(tdb, key) == TDB_ERR_IO); - ok1(tdb_traverse(tdb, test_traverse, NULL) == TDB_ERR_IO); - /* Skip the rest... */ - for (ret = 0; ret < 26 - 6; ret++) - ok1(1); - tdb_close(tdb); - return exit_status(); - } -#endif - ok1(ret == 0); - - /* Put an entry in, and check it. */ - ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == TDB_SUCCESS); - - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - - /* That currently fills at the end, make sure that's true. */ - hash = tdb_hash(tdb, key.dptr, key.dsize); - rec_ptr = tdb1_find_lock_hash(tdb, key, hash, F_RDLCK, &rec); - ok1(rec_ptr); - ok1(rec_ptr > 2U*1024*1024*1024); - tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK); - - /* Traverse must work. */ - ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); - - /* Delete should work. */ - ok1(tdb_delete(tdb, key) == TDB_SUCCESS); - - ok1(tdb_traverse(tdb, test_traverse, NULL) == 0); - - /* Transactions should work. */ - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == TDB_SUCCESS); - - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS); - - ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-bad-tdb-header.c b/lib/tdb2/test/run-tdb1-bad-tdb-header.c deleted file mode 100644 index ed1b0085c7..0000000000 --- a/lib/tdb2/test/run-tdb1-bad-tdb-header.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -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); - /* Cannot open fine if complete crap, even with O_CREAT. */ - fd = open("run-bad-tdb-header.tdb1", O_RDWR|O_CREAT|O_TRUNC, 0600); - ok1(fd >= 0); - ok1(write(fd, "hello world", 11) == 11); - close(fd); - tdb = tdb_open("run-bad-tdb-header.tdb1", 0, O_RDWR, 0, &tap_log_attr); - ok1(!tdb); - tdb = tdb_open("run-bad-tdb-header.tdb1", 0, O_CREAT|O_RDWR, - 0600, &hsize); - ok1(!tdb); - - /* With truncate, will be fine. */ - tdb = tdb_open("run-bad-tdb-header.tdb1", TDB_VERSION1, - O_RDWR|O_CREAT|O_TRUNC, 0600, &hsize); - ok1(tdb); - tdb_close(tdb); - - /* Now, with wrong version it should *not* overwrite. */ - fd = open("run-bad-tdb-header.tdb1", O_RDWR); - ok1(fd >= 0); - ok1(read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); - ok1(hdr.version == TDB1_VERSION); - hdr.version++; - lseek(fd, 0, SEEK_SET); - ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); - close(fd); - - tdb = tdb_open("run-bad-tdb-header.tdb1", TDB_VERSION1, O_RDWR|O_CREAT, - 0600, &hsize); - ok1(errno == EIO); - ok1(!tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-check.c b/lib/tdb2/test/run-tdb1-check.c deleted file mode 100644 index 45bcbc4a9d..0000000000 --- a/lib/tdb2/test/run-tdb1-check.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -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(); -} diff --git a/lib/tdb2/test/run-tdb1-corrupt.c b/lib/tdb2/test/run-tdb1-corrupt.c deleted file mode 100644 index 99f5578db7..0000000000 --- a/lib/tdb2/test/run-tdb1-corrupt.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -static int check(TDB_DATA key, TDB_DATA data, void *private) -{ - unsigned int *sizes = private; - - if (key.dsize > strlen("hello")) - return -1; - if (memcmp(key.dptr, "hello", key.dsize) != 0) - return -1; - - if (data.dsize != strlen("world")) - return -1; - if (memcmp(data.dptr, "world", data.dsize) != 0) - return -1; - - sizes[0] += key.dsize; - sizes[1] += data.dsize; - return 0; -} - -static void tdb1_flip_bit(struct tdb_context *tdb, unsigned int bit) -{ - unsigned int off = bit / CHAR_BIT; - unsigned char mask = (1 << (bit % CHAR_BIT)); - - if (tdb->file->map_ptr) - ((unsigned char *)tdb->file->map_ptr)[off] ^= mask; - else { - unsigned char c; - if (pread(tdb->file->fd, &c, 1, off) != 1) - err(1, "pread"); - c ^= mask; - if (pwrite(tdb->file->fd, &c, 1, off) != 1) - err(1, "pwrite"); - } -} - -static void check_test(struct tdb_context *tdb) -{ - TDB_DATA key, data; - unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize; - - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - - key = tdb_mkdata("hello", strlen("hello")); - data = tdb_mkdata("world", strlen("world")); - - /* Key and data size respectively. */ - dsize = ksize = 0; - - /* 5 keys in hash size 2 means we'll have multichains. */ - for (key.dsize = 1; key.dsize <= 5; key.dsize++) { - ksize += key.dsize; - dsize += data.dsize; - if (tdb_store(tdb, key, data, TDB_INSERT) != TDB_SUCCESS) - abort(); - } - - /* This is how many bytes we expect to be verifiable. */ - /* From the file header. */ - verifiable = strlen(TDB_MAGIC_FOOD) + 1 - + 2 * sizeof(uint32_t) + 2 * sizeof(tdb1_off_t) - + 2 * sizeof(uint32_t); - /* From the free list chain and hash chains. */ - verifiable += 3 * sizeof(tdb1_off_t); - /* From the record headers & tailer */ - verifiable += 5 * (sizeof(struct tdb1_record) + sizeof(uint32_t)); - /* The free block: we ignore datalen, keylen, full_hash. */ - verifiable += sizeof(struct tdb1_record) - 3*sizeof(uint32_t) + - sizeof(uint32_t); - /* Our check function verifies the key and data. */ - verifiable += ksize + dsize; - - /* Flip one bit at a time, make sure it detects verifiable bytes. */ - for (i = 0, corrupt = 0; i < tdb->file->map_size * CHAR_BIT; i++) { - tdb1_flip_bit(tdb, i); - memset(sizes, 0, sizeof(sizes)); - if (tdb_check(tdb, check, sizes) == TDB_ERR_CORRUPT) - corrupt++; - else if (sizes[0] != ksize || sizes[1] != dsize) - corrupt++; - tdb1_flip_bit(tdb, i); - } - ok(corrupt == verifiable * CHAR_BIT, "corrupt %u should be %u", - corrupt, verifiable * CHAR_BIT); -} - -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 = tdb_open("run-corrupt.tdb1", TDB_VERSION1, - O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); - - if (!tdb) - abort(); - check_test(tdb); - tdb_close(tdb); - - /* This should not. */ - tdb = tdb_open("run-corrupt.tdb1", TDB_VERSION1|TDB_NOMMAP, - O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); - - if (!tdb) - abort(); - check_test(tdb); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-endian.c b/lib/tdb2/test/run-tdb1-endian.c deleted file mode 100644 index 43f9d5fe5e..0000000000 --- a/lib/tdb2/test/run-tdb1-endian.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -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(14); - tdb = tdb_open("run-endian.tdb1", - TDB_VERSION1|TDB_CONVERT, - 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_MODIFY) == TDB_ERR_NOEXIST); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_ERR_EXISTS); - ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_SUCCESS); - - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - - key.dsize++; - ok1(tdb_fetch(tdb, key, &data) == TDB_ERR_NOEXIST); - ok1(data.dptr == NULL); - tdb_close(tdb); - - /* Reopen: should read it */ - tdb = tdb_open("run-endian.tdb1", 0, O_RDWR, 0, NULL); - ok1(tdb); - - key = tdb_mkdata("hi", strlen("hi")); - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-hashsize.c b/lib/tdb2/test/run-tdb1-hashsize.c deleted file mode 100644 index 4f37b72be6..0000000000 --- a/lib/tdb2/test/run-tdb1-hashsize.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#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 = tdb_open("run-tdb1-hashsize.tdb1", TDB_VERSION1, - 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 = tdb_open("run-tdb1-hashsize.tdb1", TDB_VERSION1, - 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 = tdb_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 = tdb_open("run-tdb1-hashsize.tdb1", TDB_VERSION1, - 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/lib/tdb2/test/run-tdb1-incompatible.c b/lib/tdb2/test/run-tdb1-incompatible.c deleted file mode 100644 index 4a7581609a..0000000000 --- a/lib/tdb2/test/run-tdb1-incompatible.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> - -static uint64_t tdb1_dumb_hash(const void *key, size_t len, uint64_t seed, - void *unused) -{ - return len; -} - -static void log_fn(struct tdb_context *tdb, enum tdb_log_level level, - enum TDB_ERROR ecode, const char *message, void *priv) -{ - unsigned int *count = priv; - if (strstr(message, "hash")) - (*count)++; -} - -static unsigned int hdr_rwlocks(const char *fname) -{ - struct tdb1_header hdr; - - int fd = open(fname, O_RDONLY); - if (fd == -1) - return -1; - - if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) - return -1; - - close(fd); - return hdr.rwlocks; -} - -static uint64_t jenkins_hashfn(const void *key, size_t len, uint64_t seed, - void *unused) -{ - return hashlittle(key, len); -} - -static uint64_t old_hash(const void *key, size_t len, uint64_t seed, - void *unused) -{ - return tdb1_old_hash(key, len, seed, unused); -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count, flags; - TDB_DATA d; - union tdb_attribute log_attr, jhash_attr, ohash_attr, - incompat_hash_attr, dumbhash_attr; - - log_attr.base.attr = TDB_ATTRIBUTE_LOG; - log_attr.base.next = NULL; - log_attr.log.fn = log_fn; - log_attr.log.data = &log_count; - - jhash_attr.base.attr = TDB_ATTRIBUTE_HASH; - jhash_attr.base.next = &log_attr; - jhash_attr.hash.fn = jenkins_hashfn; - - ohash_attr.base.attr = TDB_ATTRIBUTE_HASH; - ohash_attr.base.next = &log_attr; - ohash_attr.hash.fn = old_hash; - - incompat_hash_attr.base.attr = TDB_ATTRIBUTE_HASH; - incompat_hash_attr.base.next = &log_attr; - incompat_hash_attr.hash.fn = tdb1_incompatible_hash; - - dumbhash_attr.base.attr = TDB_ATTRIBUTE_HASH; - dumbhash_attr.base.next = &log_attr; - dumbhash_attr.hash.fn = tdb1_dumb_hash; - - plan_tests(42 * 2); - - for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) { - unsigned int rwmagic = TDB1_HASH_RWLOCK_MAGIC; - - if (flags & TDB_CONVERT) - tdb1_convert(&rwmagic, sizeof(rwmagic)); - - /* Create an old-style hash. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", flags|TDB_VERSION1, - O_CREAT|O_RDWR|O_TRUNC, 0600, &log_attr); - ok1(tdb); - ok1(log_count == 0); - d = tdb_mkdata("Hello", strlen("Hello")); - ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS); - tdb_close(tdb); - - /* Should not have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb1") == 0); - - /* We can still open any old-style with incompat hash. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", - TDB_VERSION1, - O_RDWR, 0600, &incompat_hash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS); - ok1(d.dsize == 5); - free(d.dptr); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open("test/jenkins-le-hash.tdb1", - TDB_VERSION1, O_RDONLY, 0, &jhash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open("test/jenkins-be-hash.tdb1", - TDB_VERSION1, O_RDONLY, 0, &jhash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - /* OK, now create with incompatible hash. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", - flags|TDB_VERSION1, - O_CREAT|O_RDWR|O_TRUNC, 0600, - &incompat_hash_attr); - ok1(tdb); - ok1(log_count == 0); - d = tdb_mkdata("Hello", strlen("Hello")); - ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS); - tdb_close(tdb); - - /* Should have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb1") == rwmagic); - - /* Cannot open with old hash. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, - O_RDWR, 0600, &ohash_attr); - ok1(!tdb); - ok1(log_count == 1); - - /* Can open with jenkins hash. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, - O_RDWR, 0600, &jhash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS); - ok1(d.dsize == 5); - free(d.dptr); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - /* Can open by letting it figure it out itself. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, - O_RDWR, 0600, &log_attr); - ok1(tdb); - ok1(log_count == 0); - d = tdb_mkdata("Hello", strlen("Hello")); - ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS); - ok1(d.dsize == 5); - free(d.dptr); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - /* FIXME: Not possible with TDB2 :( */ - /* We can also use incompatible hash with other hashes. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", - flags|TDB_VERSION1, - O_CREAT|O_RDWR|O_TRUNC, 0600, &dumbhash_attr); - ok1(tdb); - ok1(log_count == 0); - d = tdb_mkdata("Hello", strlen("Hello")); - ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS); - tdb_close(tdb); - - /* FIXME: Should have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb1") != rwmagic); - - /* It should not open if we don't specify. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, O_RDWR, 0, - &log_attr); - ok1(!tdb); - ok1(log_count == 1); - - /* Should reopen with correct hash. */ - log_count = 0; - tdb = tdb_open("run-incompatible.tdb1", TDB_VERSION1, O_RDWR, 0, - &dumbhash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_fetch(tdb, d, &d) == TDB_SUCCESS); - ok1(d.dsize == 5); - free(d.dptr); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - } - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-nested-transactions.c b/lib/tdb2/test/run-tdb1-nested-transactions.c deleted file mode 100644 index 938ab486e7..0000000000 --- a/lib/tdb2/test/run-tdb1-nested-transactions.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include <stdbool.h> -#include "logging.h" - -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(30); - key = tdb_mkdata("hi", strlen("hi")); - - tdb = tdb_open("run-nested-transactions.tdb1", - TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); - ok1(tdb); - - /* No nesting by default. */ - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - data = tdb_mkdata("world", strlen("world")); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS); - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - ok1(tdb_transaction_start(tdb) == TDB_ERR_EINVAL); - ok1(tap_log_messages == 1); - - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS); - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - tdb_close(tdb); - - tdb = tdb_open("run-nested-transactions.tdb1", - TDB_ALLOW_NESTING, O_RDWR, 0, &tap_log_attr); - ok1(tdb); - - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - ok1(tdb_delete(tdb, key) == TDB_SUCCESS); - ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS); - ok1(!tdb_exists(tdb, key)); - tdb_transaction_cancel(tdb); - ok1(tap_log_messages == 1); - /* Surprise! Kills inner "committed" transaction. */ - ok1(tdb_exists(tdb, key)); - - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - ok1(tdb_delete(tdb, key) == TDB_SUCCESS); - ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS); - ok1(!tdb_exists(tdb, key)); - ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS); - ok1(!tdb_exists(tdb, key)); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-nested-traverse.c b/lib/tdb2/test/run-tdb1-nested-traverse.c deleted file mode 100644 index 30f9922f16..0000000000 --- a/lib/tdb2/test/run-tdb1-nested-traverse.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "tdb1-lock-tracking.h" -#define fcntl fcntl_with_lockcheck1 -#include "tdb2-source.h" -#include "tap-interface.h" -#undef fcntl -#include <stdlib.h> -#include <stdbool.h> -#include "tdb1-external-agent.h" -#include "logging.h" - -static struct agent *agent; - -static bool correct_key(TDB_DATA key) -{ - return key.dsize == strlen("hi") - && memcmp(key.dptr, "hi", key.dsize) == 0; -} - -static bool correct_data(TDB_DATA data) -{ - return data.dsize == strlen("world") - && memcmp(data.dptr, "world", data.dsize) == 0; -} - -static int traverse2(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - return 0; -} - -static int traverse1(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) - == WOULD_HAVE_BLOCKED); - tdb_traverse(tdb, traverse2, NULL); - - /* That should *not* release the transaction lock! */ - ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) - == WOULD_HAVE_BLOCKED); - return 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(17); - agent = prepare_external_agent1(); - if (!agent) - err(1, "preparing agent"); - - tdb = tdb_open("run-nested-traverse.tdb1", TDB_VERSION1, - O_CREAT|O_TRUNC|O_RDWR, 0600, &hsize); - ok1(tdb); - - ok1(external_agent_operation1(agent, OPEN, tdb->name) == SUCCESS); - ok1(external_agent_operation1(agent, TRANSACTION_START, tdb->name) - == SUCCESS); - ok1(external_agent_operation1(agent, TRANSACTION_COMMIT, tdb->name) - == SUCCESS); - - key = tdb_mkdata("hi", strlen("hi")); - data = tdb_mkdata("world", strlen("world")); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS); - tdb_traverse(tdb, traverse1, NULL); - tdb_add_flag(tdb, TDB_RDONLY); - tdb_traverse(tdb, traverse1, NULL); - tdb_remove_flag(tdb, TDB_RDONLY); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-no-lock-during-traverse.c b/lib/tdb2/test/run-tdb1-no-lock-during-traverse.c deleted file mode 100644 index 79106c58cb..0000000000 --- a/lib/tdb2/test/run-tdb1-no-lock-during-traverse.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "private.h" -#include <unistd.h> -#include "tdb1-lock-tracking.h" - -#define fcntl fcntl_with_lockcheck1 - -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -#undef fcntl - -#define NUM_ENTRIES 10 - -static bool prepare_entries(struct tdb_context *tdb) -{ - unsigned int i; - TDB_DATA key, data; - - for (i = 0; i < NUM_ENTRIES; i++) { - key.dsize = sizeof(i); - key.dptr = (void *)&i; - data = tdb_mkdata("world", strlen("world")); - - if (tdb_store(tdb, key, data, 0) != TDB_SUCCESS) - return false; - } - return true; -} - -static void delete_entries(struct tdb_context *tdb) -{ - unsigned int i; - TDB_DATA key; - - for (i = 0; i < NUM_ENTRIES; i++) { - key.dsize = sizeof(i); - key.dptr = (void *)&i; - - ok1(tdb_delete(tdb, key) == TDB_SUCCESS); - } -} - -/* We don't know how many times this will run. */ -static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *private_data) -{ - unsigned int i; - memcpy(&i, key.dptr, 4); - i = (i + 1) % NUM_ENTRIES; - key.dptr = (void *)&i; - if (tdb_delete(tdb, key) != TDB_SUCCESS) - (*(int *)private_data)++; - return 0; -} - -static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *private_data) -{ - ok1(tdb_delete(tdb, key) == TDB_SUCCESS); - return 0; -} - -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(40); - tdb = tdb_open("run-no-lock-during-traverse.tdb1", - TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR, - 0600, &hsize); - - ok1(tdb); - ok1(prepare_entries(tdb)); - ok1(locking_errors1 == 0); - ok1(tdb_lockall(tdb) == 0); - ok1(locking_errors1 == 0); - ok1(tdb_traverse(tdb, delete_other, &errors) >= 0); - ok1(errors == 0); - ok1(locking_errors1 == 0); - tdb_unlockall(tdb); - - ok1(prepare_entries(tdb)); - ok1(locking_errors1 == 0); - ok1(tdb_lockall(tdb) == 0); - ok1(locking_errors1 == 0); - ok1(tdb_traverse(tdb, delete_self, NULL) == NUM_ENTRIES); - ok1(locking_errors1 == 0); - tdb_unlockall(tdb); - - ok1(prepare_entries(tdb)); - ok1(locking_errors1 == 0); - ok1(tdb_lockall(tdb) == 0); - ok1(locking_errors1 == 0); - delete_entries(tdb); - ok1(locking_errors1 == 0); - tdb_unlockall(tdb); - - ok1(tdb_close(tdb) == 0); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-oldhash.c b/lib/tdb2/test/run-tdb1-oldhash.c deleted file mode 100644 index 629ff50634..0000000000 --- a/lib/tdb2/test/run-tdb1-oldhash.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - union tdb_attribute incompat_hash_attr; - - incompat_hash_attr.base.attr = TDB_ATTRIBUTE_HASH; - incompat_hash_attr.base.next = &tap_log_attr; - incompat_hash_attr.hash.fn = tdb1_incompatible_hash; - - plan_tests(8); - - /* Old format (with zeroes in the hash magic fields) should - * open with any hash (since we don't know what hash they used). */ - 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); - - tdb = tdb_open("test/old-nohash-le.tdb1", TDB_VERSION1, O_RDWR, 0, - &incompat_hash_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, - &incompat_hash_attr); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-readonly-check.c b/lib/tdb2/test/run-tdb1-readonly-check.c deleted file mode 100644 index 078b9d6148..0000000000 --- a/lib/tdb2/test/run-tdb1-readonly-check.c +++ /dev/null @@ -1,44 +0,0 @@ -/* We should be able to tdb_check a O_RDONLY tdb, and we were previously allowed - * to tdb_check() inside a transaction (though that's paranoia!). */ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -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 = tdb_open("run-readonly-check.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(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - - /* We are also allowed to do a check inside a transaction. */ - ok1(tdb_transaction_start(tdb) == TDB_SUCCESS); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - ok1(tdb_close(tdb) == 0); - - tdb = tdb_open("run-readonly-check.tdb1", - TDB_DEFAULT, O_RDONLY, 0, &tap_log_attr); - - ok1(tdb); - ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_ERR_RDONLY); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - ok1(tdb_close(tdb) == 0); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-rwlock-check.c b/lib/tdb2/test/run-tdb1-rwlock-check.c deleted file mode 100644 index 08a082ff5c..0000000000 --- a/lib/tdb2/test/run-tdb1-rwlock-check.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> - -static void log_fn(struct tdb_context *tdb, enum tdb_log_level level, - enum TDB_ERROR ecode, const char *message, void *priv) -{ - unsigned int *count = priv; - if (strstr(message, "spinlocks")) - (*count)++; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - union tdb_attribute log_attr; - - log_attr.base.attr = TDB_ATTRIBUTE_LOG; - log_attr.base.next = NULL; - log_attr.log.fn = log_fn; - log_attr.log.data = &log_count; - - plan_tests(4); - - /* We should fail to open rwlock-using tdbs of either endian. */ - log_count = 0; - tdb = tdb_open("test/rwlock-le.tdb1", TDB_VERSION1, O_RDWR, 0, - &log_attr); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - tdb = tdb_open("test/rwlock-be.tdb1", TDB_VERSION1, O_RDWR, 0, - &log_attr); - ok1(!tdb); - ok1(log_count == 1); - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-seqnum-wrap.c b/lib/tdb2/test/run-tdb1-seqnum-wrap.c deleted file mode 100644 index 01cfaefb90..0000000000 --- a/lib/tdb2/test/run-tdb1-seqnum-wrap.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int i; - struct tdb1_header hdr; - struct tdb_data key = { (unsigned char *)&hdr, sizeof(hdr) }; - struct tdb_data data = { (unsigned char *)&hdr, sizeof(hdr) }; - int flags[] = { TDB_DEFAULT, TDB_NOMMAP, - TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT }; - - plan_tests(sizeof(flags) / sizeof(flags[0]) * 7); - for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { - tdb = tdb_open("run-tdb1-seqnum-wrap.tdb1", - flags[i]|TDB_VERSION1|TDB_SEQNUM, - O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); - ok1(tdb); - if (!tdb) - break; - ok1(pread(tdb->file->fd, &hdr, sizeof(hdr), 0) == sizeof(hdr)); - hdr.sequence_number = 0xFFFFFFFF; - ok1(pwrite(tdb->file->fd, &hdr, sizeof(hdr), 0) == sizeof(hdr)); - - /* Must not be negative: that would mean an error! */ - ok1(tdb_get_seqnum(tdb) == 0xFFFFFFFF); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS); - ok1(tdb_get_seqnum(tdb) == 0); - tdb_close(tdb); - ok1(tap_log_messages == 0); - } - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-summary.c b/lib/tdb2/test/run-tdb1-summary.c deleted file mode 100644 index a031a10519..0000000000 --- a/lib/tdb2/test/run-tdb1-summary.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> - -int main(int argc, char *argv[]) -{ - unsigned int i, j; - struct tdb_context *tdb; - int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, - TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, - TDB_NOMMAP|TDB_CONVERT }; - TDB_DATA key = { (unsigned char *)&j, sizeof(j) }; - TDB_DATA data = { (unsigned char *)&j, sizeof(j) }; - char *summary; - - plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); - for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { - tdb = tdb_open("run-summary.tdb1", flags[i]|TDB_VERSION1, - O_RDWR|O_CREAT|O_TRUNC, 0600, NULL); - ok1(tdb); - if (!tdb) - continue; - - /* Put some stuff in there. */ - for (j = 0; j < 500; j++) { - /* Make sure padding varies to we get some graphs! */ - data.dsize = j % (sizeof(j) + 1); - if (tdb_store(tdb, key, data, TDB_REPLACE) - != TDB_SUCCESS) { - fail("Storing in tdb"); - } - } - - summary = tdb1_summary(tdb); - diag("%s", summary); - ok1(strstr(summary, "Size of file/data: ")); - ok1(strstr(summary, "Number of records: 500\n")); - ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); - ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); - ok1(strstr(summary, "Smallest/average/largest padding: ")); - ok1(strstr(summary, "Number of dead records: 0\n")); - ok1(strstr(summary, "Number of free records: 1\n")); - ok1(strstr(summary, "Smallest/average/largest free records: ")); - ok1(strstr(summary, "Number of hash chains: 131\n")); - ok1(strstr(summary, "Smallest/average/largest hash chains: ")); - ok1(strstr(summary, "Number of uncoalesced records: 0\n")); - ok1(strstr(summary, "Smallest/average/largest uncoalesced runs: 0/0/0\n")); - ok1(strstr(summary, "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: ")); - - free(summary); - tdb_close(tdb); - } - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-traverse-in-transaction.c b/lib/tdb2/test/run-tdb1-traverse-in-transaction.c deleted file mode 100644 index 6f209d9578..0000000000 --- a/lib/tdb2/test/run-tdb1-traverse-in-transaction.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "config.h" -#include "tdb1-lock-tracking.h" -#define fcntl fcntl_with_lockcheck1 -#include "tdb2-source.h" -#include "tap-interface.h" -#undef fcntl_with_lockcheck -#include <stdlib.h> -#include <stdbool.h> -#include "tdb1-external-agent.h" -#include "logging.h" - -static struct agent *agent; - -static bool correct_key(TDB_DATA key) -{ - return key.dsize == strlen("hi") - && memcmp(key.dptr, "hi", key.dsize) == 0; -} - -static bool correct_data(TDB_DATA data) -{ - return data.dsize == strlen("world") - && memcmp(data.dptr, "world", data.dsize) == 0; -} - -static int traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - return 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(); -} diff --git a/lib/tdb2/test/run-tdb1-wronghash-fail.c b/lib/tdb2/test/run-tdb1-wronghash-fail.c deleted file mode 100644 index 725b4d2d00..0000000000 --- a/lib/tdb2/test/run-tdb1-wronghash-fail.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> - -static void log_fn(struct tdb_context *tdb, enum tdb_log_level level, - enum TDB_ERROR ecode, const char *message, void *priv) -{ - unsigned int *count = priv; - if (strstr(message, "hash")) - (*count)++; -} - -static uint64_t jenkins_hashfn(const void *key, size_t len, uint64_t seed, - void *unused) -{ - return hashlittle(key, len); -} - -/* the tdb1_old_hash function is "magic" as it automatically makes us test the - * tdb1_incompatible_hash as well, so use this wrapper. */ -static uint64_t old_hash(const void *key, size_t len, uint64_t seed, - void *unused) -{ - return tdb1_old_hash(key, len, seed, unused); -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - TDB_DATA d; - union tdb_attribute log_attr, jhash_attr, ohash_attr, - incompat_hash_attr; - - log_attr.base.attr = TDB_ATTRIBUTE_LOG; - log_attr.base.next = NULL; - log_attr.log.fn = log_fn; - log_attr.log.data = &log_count; - - jhash_attr.base.attr = TDB_ATTRIBUTE_HASH; - jhash_attr.base.next = &log_attr; - jhash_attr.hash.fn = jenkins_hashfn; - - ohash_attr.base.attr = TDB_ATTRIBUTE_HASH; - ohash_attr.base.next = &log_attr; - ohash_attr.hash.fn = old_hash; - - incompat_hash_attr.base.attr = TDB_ATTRIBUTE_HASH; - incompat_hash_attr.base.next = &log_attr; - incompat_hash_attr.hash.fn = tdb1_incompatible_hash; - - plan_tests(28); - - /* Create with default hash. */ - log_count = 0; - tdb = tdb_open("run-wronghash-fail.tdb1", TDB_VERSION1, - O_CREAT|O_RDWR|O_TRUNC, 0600, &log_attr); - ok1(tdb); - ok1(log_count == 0); - d = tdb_mkdata("Hello", strlen("Hello")); - ok1(tdb_store(tdb, d, d, TDB_INSERT) == TDB_SUCCESS); - tdb_close(tdb); - - /* Fail to open with different hash. */ - tdb = tdb_open("run-wronghash-fail.tdb1", TDB_VERSION1, O_RDWR, 0, - &jhash_attr); - ok1(!tdb); - ok1(log_count == 1); - - /* Create with different hash. */ - log_count = 0; - tdb = tdb_open("run-wronghash-fail.tdb1", TDB_VERSION1, - O_CREAT|O_RDWR|O_TRUNC, 0600, &jhash_attr); - ok1(tdb); - ok1(log_count == 0); - tdb_close(tdb); - - /* Endian should be no problem. */ - log_count = 0; - tdb = tdb_open("test/jenkins-le-hash.tdb1", TDB_VERSION1, O_RDWR, 0, - &ohash_attr); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - tdb = tdb_open("test/jenkins-be-hash.tdb1", TDB_VERSION1, O_RDWR, 0, - &ohash_attr); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - /* Fail to open with old default hash. */ - tdb = tdb_open("run-wronghash-fail.tdb1", TDB_VERSION1, O_RDWR, 0, - &ohash_attr); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - tdb = tdb_open("test/jenkins-le-hash.tdb1", TDB_VERSION1, O_RDONLY, - 0, &incompat_hash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open("test/jenkins-be-hash.tdb1", TDB_VERSION1, O_RDONLY, - 0, &incompat_hash_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - /* It should open with jenkins hash if we don't specify. */ - log_count = 0; - tdb = tdb_open("test/jenkins-le-hash.tdb1", TDB_VERSION1, O_RDWR, 0, - &log_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open("test/jenkins-be-hash.tdb1", TDB_VERSION1, O_RDWR, 0, - &log_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open("run-wronghash-fail.tdb1", TDB_VERSION1, O_RDONLY, - 0, &log_attr); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS); - tdb_close(tdb); - - - return exit_status(); -} diff --git a/lib/tdb2/test/run-tdb1-zero-append.c b/lib/tdb2/test/run-tdb1-zero-append.c deleted file mode 100644 index 2d8be6123b..0000000000 --- a/lib/tdb2/test/run-tdb1-zero-append.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -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(); -} diff --git a/lib/tdb2/test/run-tdb1.c b/lib/tdb2/test/run-tdb1.c deleted file mode 100644 index d5b05b0bd6..0000000000 --- a/lib/tdb2/test/run-tdb1.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "tdb2-source.h" -#include "tap-interface.h" -#include <stdlib.h> -#include "logging.h" - -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(9); - tdb = tdb_open("run.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_MODIFY) == TDB_ERR_NOEXIST); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_ERR_EXISTS); - ok1(tdb_store(tdb, key, data, TDB_MODIFY) == TDB_SUCCESS); - - ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - - key.dsize++; - ok1(tdb_fetch(tdb, key, &data) == TDB_ERR_NOEXIST); - tdb_close(tdb); - - return exit_status(); -} diff --git a/lib/tdb2/test/rwlock-be.tdb1 b/lib/tdb2/test/rwlock-be.tdb1 Binary files differdeleted file mode 100644 index 45b5f09a1b..0000000000 --- a/lib/tdb2/test/rwlock-be.tdb1 +++ /dev/null diff --git a/lib/tdb2/test/rwlock-le.tdb1 b/lib/tdb2/test/rwlock-le.tdb1 Binary files differdeleted file mode 100644 index 45b5f09a1b..0000000000 --- a/lib/tdb2/test/rwlock-le.tdb1 +++ /dev/null diff --git a/lib/tdb2/test/tdb1-external-agent.c b/lib/tdb2/test/tdb1-external-agent.c deleted file mode 100644 index 7242e22300..0000000000 --- a/lib/tdb2/test/tdb1-external-agent.c +++ /dev/null @@ -1,186 +0,0 @@ -#include "tdb1-external-agent.h" -#include "tdb1-lock-tracking.h" -#include "logging.h" -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <errno.h> -#include "tdb1_private.h" -#include "tap-interface.h" -#include <stdio.h> -#include <stdarg.h> - -static struct tdb_context *tdb; - -static enum agent_return do_operation(enum operation op, const char *name) -{ - TDB_DATA k; - enum agent_return ret; - TDB_DATA data; - - if (op != OPEN && !tdb) { - diag("external: No tdb open!"); - return OTHER_FAILURE; - } - - k = tdb_mkdata(name, strlen(name)); - - locking_would_block1 = 0; - switch (op) { - case OPEN: - if (tdb) { - diag("Already have tdb %s open", tdb->name); - return OTHER_FAILURE; - } - tdb = tdb_open(name, TDB_VERSION1, O_RDWR, 0, &tap_log_attr); - if (!tdb) { - if (!locking_would_block1) - diag("Opening tdb gave %s", strerror(errno)); - ret = OTHER_FAILURE; - } else - ret = SUCCESS; - break; - case TRANSACTION_START: - ret = tdb_transaction_start(tdb) == TDB_SUCCESS ? SUCCESS : OTHER_FAILURE; - break; - case FETCH: - if (tdb_fetch(tdb, k, &data) != TDB_SUCCESS) { - if (tdb->last_error == TDB_ERR_NOEXIST) - ret = FAILED; - else - ret = OTHER_FAILURE; - } else if (data.dsize != k.dsize - || memcmp(data.dptr, k.dptr, k.dsize) != 0) { - ret = OTHER_FAILURE; - } else { - ret = SUCCESS; - } - free(data.dptr); - break; - case STORE: - if (tdb_store(tdb, k, k, 0) == TDB_SUCCESS) - ret = SUCCESS; - else - ret = OTHER_FAILURE; - break; - case TRANSACTION_COMMIT: - ret = tdb_transaction_commit(tdb) == TDB_SUCCESS ? SUCCESS : OTHER_FAILURE; - break; - case CHECK: - ret = tdb_check(tdb, NULL, NULL) == TDB_SUCCESS ? SUCCESS : OTHER_FAILURE; - break; - case NEEDS_RECOVERY: - ret = external_agent_needs_rec(tdb); - break; - case CLOSE: - ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE; - tdb = NULL; - break; - default: - ret = OTHER_FAILURE; - } - - if (locking_would_block1) - ret = WOULD_HAVE_BLOCKED; - - return ret; -} - -struct agent { - int cmdfd, responsefd; -}; - -/* Do this before doing any tdb stuff. Return handle, or NULL. */ -struct agent *prepare_external_agent1(void) -{ - int pid, ret; - int command[2], response[2]; - char name[1+PATH_MAX]; - - if (pipe(command) != 0 || pipe(response) != 0) - return NULL; - - pid = fork(); - if (pid < 0) - return NULL; - - if (pid != 0) { - struct agent *agent = malloc(sizeof(*agent)); - - close(command[0]); - close(response[1]); - agent->cmdfd = command[1]; - agent->responsefd = response[0]; - return agent; - } - - close(command[1]); - close(response[0]); - - /* We want to fail, not block. */ - nonblocking_locks1 = true; - log_prefix = "external: "; - while ((ret = read(command[0], name, sizeof(name))) > 0) { - enum agent_return result; - - result = do_operation(name[0], name+1); - if (write(response[1], &result, sizeof(result)) - != sizeof(result)) - err(1, "Writing response"); - } - exit(0); -} - -/* Ask the external agent to try to do an operation. */ -enum agent_return external_agent_operation1(struct agent *agent, - enum operation op, - const char *name) -{ - enum agent_return res; - unsigned int len; - char *string; - - if (!name) - name = ""; - len = 1 + strlen(name) + 1; - string = malloc(len); - - string[0] = op; - strcpy(string+1, name); - - if (write(agent->cmdfd, string, len) != len - || read(agent->responsefd, &res, sizeof(res)) != sizeof(res)) - res = AGENT_DIED; - - free(string); - return res; -} - -const char *agent_return_name1(enum agent_return ret) -{ - return ret == SUCCESS ? "SUCCESS" - : ret == WOULD_HAVE_BLOCKED ? "WOULD_HAVE_BLOCKED" - : ret == AGENT_DIED ? "AGENT_DIED" - : ret == FAILED ? "FAILED" - : ret == OTHER_FAILURE ? "OTHER_FAILURE" - : "**INVALID**"; -} - -const char *operation_name1(enum operation op) -{ - switch (op) { - case OPEN: return "OPEN"; - case TRANSACTION_START: return "TRANSACTION_START"; - case FETCH: return "FETCH"; - case STORE: return "STORE"; - case TRANSACTION_COMMIT: return "TRANSACTION_COMMIT"; - case CHECK: return "CHECK"; - case NEEDS_RECOVERY: return "NEEDS_RECOVERY"; - case CLOSE: return "CLOSE"; - } - return "**INVALID**"; -} diff --git a/lib/tdb2/test/tdb1-external-agent.h b/lib/tdb2/test/tdb1-external-agent.h deleted file mode 100644 index 19ad8d2c12..0000000000 --- a/lib/tdb2/test/tdb1-external-agent.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef TDB_TEST_EXTERNAL_AGENT_H -#define TDB_TEST_EXTERNAL_AGENT_H - -/* For locking tests, we need a different process to try things at - * various times. */ -enum operation { - OPEN, - TRANSACTION_START, - FETCH, - STORE, - TRANSACTION_COMMIT, - CHECK, - NEEDS_RECOVERY, - CLOSE, -}; - -/* Do this before doing any tdb stuff. Return handle, or -1. */ -struct agent *prepare_external_agent1(void); - -enum agent_return { - SUCCESS, - WOULD_HAVE_BLOCKED, - AGENT_DIED, - FAILED, /* For fetch, or NEEDS_RECOVERY */ - OTHER_FAILURE, -}; - -/* Ask the external agent to try to do an operation. - * name == tdb name for OPEN/OPEN_WITH_CLEAR_IF_FIRST, - * record name for FETCH/STORE (store stores name as data too) - */ -enum agent_return external_agent_operation1(struct agent *handle, - enum operation op, - const char *name); - -/* Mapping enum -> string. */ -const char *agent_return_name1(enum agent_return ret); -const char *operation_name1(enum operation op); - -/* Internal use: */ -struct tdb_context; -enum agent_return external_agent_needs_rec(struct tdb_context *tdb); -#endif /* TDB_TEST_EXTERNAL_AGENT_H */ diff --git a/lib/tdb2/test/tdb1-lock-tracking.c b/lib/tdb2/test/tdb1-lock-tracking.c deleted file mode 100644 index 9701157b81..0000000000 --- a/lib/tdb2/test/tdb1-lock-tracking.c +++ /dev/null @@ -1,146 +0,0 @@ -/* We save the locks so we can reaquire them. */ -#include "tdb1_private.h" -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdlib.h> -#include "tap-interface.h" -#include "tdb1-lock-tracking.h" - -struct lock { - struct lock *next; - unsigned int off; - unsigned int len; - int type; -}; -static struct lock *locks; -int locking_errors1 = 0; -bool suppress_lockcheck1 = false; -bool nonblocking_locks1; -int locking_would_block1 = 0; -void (*unlock_callback1)(int fd); - -int fcntl_with_lockcheck1(int fd, int cmd, ... /* arg */ ) -{ - va_list ap; - int ret, arg3; - struct flock *fl; - bool may_block = false; - - if (cmd != F_SETLK && cmd != F_SETLKW) { - /* This may be totally bogus, but we don't know in general. */ - va_start(ap, cmd); - arg3 = va_arg(ap, int); - va_end(ap); - - return fcntl(fd, cmd, arg3); - } - - va_start(ap, cmd); - fl = va_arg(ap, struct flock *); - va_end(ap); - - if (cmd == F_SETLKW && nonblocking_locks1) { - cmd = F_SETLK; - may_block = true; - } - ret = fcntl(fd, cmd, fl); - - /* Detect when we failed, but might have been OK if we waited. */ - if (may_block && ret == -1 && (errno == EAGAIN || errno == EACCES)) { - locking_would_block1++; - } - - if (fl->l_type == F_UNLCK) { - struct lock **l; - struct lock *old = NULL; - - for (l = &locks; *l; l = &(*l)->next) { - if ((*l)->off == fl->l_start - && (*l)->len == fl->l_len) { - if (ret == 0) { - old = *l; - *l = (*l)->next; - free(old); - } - break; - } - } - if (!old && !suppress_lockcheck1) { - diag("Unknown unlock %u@%u - %i", - (int)fl->l_len, (int)fl->l_start, ret); - locking_errors1++; - } - } else { - struct lock *new, *i; - unsigned int fl_end = fl->l_start + fl->l_len; - if (fl->l_len == 0) - fl_end = (unsigned int)-1; - - /* Check for overlaps: we shouldn't do this. */ - for (i = locks; i; i = i->next) { - unsigned int i_end = i->off + i->len; - if (i->len == 0) - i_end = (unsigned int)-1; - - if (fl->l_start >= i->off && fl->l_start < i_end) - break; - if (fl_end >= i->off && fl_end < i_end) - break; - - /* tdb_allrecord_lock does this, handle adjacent: */ - if (fl->l_start == i_end && fl->l_type == i->type) { - if (ret == 0) { - i->len = fl->l_len - ? i->len + fl->l_len - : 0; - } - goto done; - } - } - if (i) { - /* Special case: upgrade of allrecord lock. */ - if (i->type == F_RDLCK && fl->l_type == F_WRLCK - && i->off == TDB1_FREELIST_TOP - && fl->l_start == TDB1_FREELIST_TOP - && i->len == 0 - && fl->l_len == 0) { - if (ret == 0) - i->type = F_WRLCK; - goto done; - } - if (!suppress_lockcheck1) { - diag("%s lock %u@%u overlaps %u@%u", - fl->l_type == F_WRLCK ? "write" : "read", - (int)fl->l_len, (int)fl->l_start, - i->len, (int)i->off); - locking_errors1++; - } - } - - if (ret == 0) { - new = malloc(sizeof *new); - new->off = fl->l_start; - new->len = fl->l_len; - new->type = fl->l_type; - new->next = locks; - locks = new; - } - } -done: - if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback1) - unlock_callback1(fd); - return ret; -} - -unsigned int forget_locking1(void) -{ - unsigned int num = 0; - while (locks) { - struct lock *next = locks->next; - free(locks); - locks = next; - num++; - } - return num; -} diff --git a/lib/tdb2/test/tdb1-lock-tracking.h b/lib/tdb2/test/tdb1-lock-tracking.h deleted file mode 100644 index b59e7d805d..0000000000 --- a/lib/tdb2/test/tdb1-lock-tracking.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef TDB1_LOCK_TRACKING_H -#define TDB1_LOCK_TRACKING_H -#include "private.h" -#include <stdbool.h> - -/* Set this if you want a callback after fnctl unlock. */ -extern void (*unlock_callback1)(int fd); - -/* Replacement fcntl. */ -int fcntl_with_lockcheck1(int fd, int cmd, ... /* arg */ ); - -/* Discard locking info: returns number of locks outstanding. */ -unsigned int forget_locking1(void); - -/* Number of errors in locking. */ -extern int locking_errors1; - -/* Suppress lock checking. */ -extern bool suppress_lockcheck1; - -/* Make all locks non-blocking. */ -extern bool nonblocking_locks1; - -/* Number of times we failed a lock because we made it non-blocking. */ -extern int locking_would_block1; -#endif /* LOCK_TRACKING_H */ diff --git a/lib/tdb2/test/tdb1.corrupt b/lib/tdb2/test/tdb1.corrupt Binary files differdeleted file mode 100644 index 83d6677454..0000000000 --- a/lib/tdb2/test/tdb1.corrupt +++ /dev/null diff --git a/lib/tdb2/test/tdb2-source.h b/lib/tdb2/test/tdb2-source.h index fabf6ac33d..d13d8b868c 100644 --- a/lib/tdb2/test/tdb2-source.h +++ b/lib/tdb2/test/tdb2-source.h @@ -9,13 +9,3 @@ #include "tdb.c" #include "transaction.c" #include "traverse.c" -#include "tdb1_check.c" -#include "tdb1_freelist.c" -#include "tdb1_hash.c" -#include "tdb1_io.c" -#include "tdb1_lock.c" -#include "tdb1_open.c" -#include "tdb1_summary.c" -#include "tdb1_tdb.c" -#include "tdb1_transaction.c" -#include "tdb1_traverse.c" diff --git a/lib/tdb2/tools/tdb2backup.c b/lib/tdb2/tools/tdb2backup.c index 729ae720b4..37b301c548 100644 --- a/lib/tdb2/tools/tdb2backup.c +++ b/lib/tdb2/tools/tdb2backup.c @@ -44,9 +44,6 @@ #include "tdb2.h" #include "system/filesys.h" -/* Currently we default to creating a tdb1. This will change! */ -#define TDB2_IS_DEFAULT false - #ifdef HAVE_GETOPT_H #include <getopt.h> #endif @@ -101,8 +98,7 @@ static int test_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *s only doing the backup if its OK this function is also used for restore */ -static int backup_tdb(const char *old_name, const char *new_name, - bool tdb2, int hash_size) +static int backup_tdb(const char *old_name, const char *new_name) { struct tdb_context *tdb; struct tdb_context *tdb_new; @@ -110,12 +106,7 @@ static int backup_tdb(const char *old_name, const char *new_name, struct stat st; int count1, count2; enum TDB_ERROR err; - union tdb_attribute log_attr, hsize_attr; - int tdb_flags = TDB_DEFAULT; - - if (!tdb2) { - tdb_flags |= TDB_VERSION1; - } + union tdb_attribute log_attr; tmp_name = add_suffix(new_name, ".tmp"); @@ -138,16 +129,8 @@ static int backup_tdb(const char *old_name, const char *new_name, return 1; } - /* create the new tdb */ - if (!tdb2 && hash_size) { - hsize_attr.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE; - hsize_attr.base.next = NULL; - hsize_attr.tdb1_hashsize.hsize = hash_size; - log_attr.base.next = &hsize_attr; - } - unlink(tmp_name); - tdb_new = tdb_open(tmp_name, tdb_flags, + tdb_new = tdb_open(tmp_name, TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, st.st_mode & 0777, &log_attr); if (!tdb_new) { @@ -270,7 +253,7 @@ static int verify_tdb(const char *fname, const char *bak_name) /* count is < 0 means an error */ if (count < 0) { printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname, TDB2_IS_DEFAULT, 0); + return backup_tdb(bak_name, fname); } printf("%s : %d records\n", fname, count); @@ -295,14 +278,11 @@ static int file_newer(const char *fname1, const char *fname2) static void usage(void) { - printf("Usage: tdbbackup [options] <fname...>\n\n"); + printf("Usage: tdb2backup [options] <fname...>\n\n"); printf(" -h this help message\n"); - printf(" -1 make the backup a TDB1 file\n"); - printf(" -2 make the backup a TDB2 file\n"); printf(" -v verify mode (restore if corrupt)\n"); printf(" -s suffix set the backup suffix\n"); printf(" -v verify mode (restore if corrupt)\n"); - printf(" -n hashsize set the new hash size for the backup\n"); } @@ -312,11 +292,9 @@ static void usage(void) int ret = 0; int c; int verify = 0; - int hashsize = 0; - bool tdb2 = TDB2_IS_DEFAULT; const char *suffix = ".bak"; - while ((c = getopt(argc, argv, "vhs:n:12")) != -1) { + while ((c = getopt(argc, argv, "vhs:")) != -1) { switch (c) { case 'h': usage(); @@ -324,18 +302,9 @@ static void usage(void) case 'v': verify = 1; break; - case '1': - tdb2 = false; - break; - case '2': - tdb2 = true; - break; case 's': suffix = optarg; break; - case 'n': - hashsize = atoi(optarg); - break; } } @@ -359,7 +328,7 @@ static void usage(void) } } else { if (file_newer(fname, bak_name) && - backup_tdb(fname, bak_name, tdb2, hashsize) != 0) { + backup_tdb(fname, bak_name) != 0) { ret = 1; } } diff --git a/lib/tdb2/tools/tdb2torture.c b/lib/tdb2/tools/tdb2torture.c index eb12b59c4e..73e2e29874 100644 --- a/lib/tdb2/tools/tdb2torture.c +++ b/lib/tdb2/tools/tdb2torture.c @@ -21,9 +21,6 @@ #include <sys/wait.h> #endif -/* Currently we default to creating a tdb1. This will change! */ -#define TDB2_IS_DEFAULT false - //#define REOPEN_PROB 30 #define DELETE_PROB 8 #define STORE_PROB 4 @@ -248,7 +245,7 @@ static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, static void usage(void) { - printf("Usage: tdbtorture" + printf("Usage: tdb2torture" #if TRANSACTION_PROB " [-t]" #endif @@ -354,7 +351,6 @@ int main(int argc, char * const *argv) int kill_random = 0; int *done; int tdb_flags = TDB_DEFAULT; - bool tdb2 = TDB2_IS_DEFAULT; char *test_tdb; log_attr.base.attr = TDB_ATTRIBUTE_LOG; @@ -363,7 +359,7 @@ int main(int argc, char * const *argv) seed_attr.base.attr = TDB_ATTRIBUTE_SEED; seed_attr.base.next = NULL; - while ((c = getopt(argc, argv, "n:l:s:thkS12")) != -1) { + while ((c = getopt(argc, argv, "n:l:s:thkS")) != -1) { switch (c) { case 'n': num_procs = strtol(optarg, NULL, 0); @@ -388,24 +384,12 @@ int main(int argc, char * const *argv) case 'k': kill_random = 1; break; - case '1': - tdb2 = false; - break; - case '2': - tdb2 = true; - break; default: usage(); } } - if (!tdb2) { - tdb_flags |= TDB_VERSION1; - /* TDB1 tdbs don't use seed. */ - log_attr.base.next = NULL; - } - - test_tdb = test_path("torture.tdb"); + test_tdb = test_path("torture.tdb2"); unlink(test_tdb); diff --git a/lib/tdb2/transaction.c b/lib/tdb2/transaction.c index f6d75572a0..cd6d42a6ec 100644 --- a/lib/tdb2/transaction.c +++ b/lib/tdb2/transaction.c @@ -521,12 +521,6 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb) { enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_transaction_start(tdb) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - tdb->stats.transactions++; /* some sanity checks */ if (tdb->flags & TDB_INTERNAL) { @@ -623,10 +617,6 @@ fail_allrecord_lock: */ _PUBLIC_ void tdb_transaction_cancel(struct tdb_context *tdb) { - if (tdb->flags & TDB_VERSION1) { - tdb1_transaction_cancel(tdb); - return; - } tdb->stats.transaction_cancel++; _tdb_transaction_cancel(tdb); } @@ -1067,11 +1057,6 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb) */ _PUBLIC_ enum TDB_ERROR tdb_transaction_prepare_commit(struct tdb_context *tdb) { - if (tdb->flags & TDB_VERSION1) { - if (tdb1_transaction_prepare_commit(tdb) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } return tdb->last_error = _tdb_transaction_prepare_commit(tdb); } @@ -1084,12 +1069,6 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb) int i; enum TDB_ERROR ecode; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_transaction_commit(tdb) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - if (tdb->tdb2.transaction == NULL) { return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, diff --git a/lib/tdb2/traverse.c b/lib/tdb2/traverse.c index a93e4d1d68..ed51a9ee72 100644 --- a/lib/tdb2/traverse.c +++ b/lib/tdb2/traverse.c @@ -28,13 +28,6 @@ _PUBLIC_ int64_t tdb_traverse_(struct tdb_context *tdb, struct tdb_data k, d; int64_t count = 0; - if (tdb->flags & TDB_VERSION1) { - count = tdb1_traverse(tdb, fn, p); - if (count == -1) - return TDB_ERR_TO_OFF(tdb->last_error); - return count; - } - k.dptr = NULL; for (ecode = first_in_hash(tdb, &tinfo, &k, &d.dsize); ecode == TDB_SUCCESS; @@ -61,16 +54,6 @@ _PUBLIC_ enum TDB_ERROR tdb_firstkey(struct tdb_context *tdb, struct tdb_data *k { struct traverse_info tinfo; - if (tdb->flags & TDB_VERSION1) { - tdb->last_error = TDB_SUCCESS; - *key = tdb1_firstkey(tdb); - /* TDB1 didn't set error for last key. */ - if (!key->dptr && tdb->last_error == TDB_SUCCESS) { - tdb->last_error = TDB_ERR_NOEXIST; - } - return tdb->last_error; - } - return tdb->last_error = first_in_hash(tdb, &tinfo, key, NULL); } @@ -81,18 +64,6 @@ _PUBLIC_ enum TDB_ERROR tdb_nextkey(struct tdb_context *tdb, struct tdb_data *ke struct hash_info h; struct tdb_used_record rec; - if (tdb->flags & TDB_VERSION1) { - struct tdb_data last_key = *key; - tdb->last_error = TDB_SUCCESS; - *key = tdb1_nextkey(tdb, last_key); - free(last_key.dptr); - /* TDB1 didn't set error for last key. */ - if (!key->dptr && tdb->last_error == TDB_SUCCESS) { - tdb->last_error = TDB_ERR_NOEXIST; - } - return tdb->last_error; - } - tinfo.prev = find_and_lock(tdb, *key, F_RDLCK, &h, &rec, &tinfo); free(key->dptr); if (TDB_OFF_IS_ERR(tinfo.prev)) { @@ -115,12 +86,6 @@ _PUBLIC_ enum TDB_ERROR tdb_wipe_all(struct tdb_context *tdb) enum TDB_ERROR ecode; int64_t count; - if (tdb->flags & TDB_VERSION1) { - if (tdb1_wipe_all(tdb) == -1) - return tdb->last_error; - return TDB_SUCCESS; - } - ecode = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); if (ecode != TDB_SUCCESS) return tdb->last_error = ecode; diff --git a/lib/tdb2/wscript b/lib/tdb2/wscript index b925893cb4..ef30f1b778 100644 --- a/lib/tdb2/wscript +++ b/lib/tdb2/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tdb' -VERSION = '2.0.0' +VERSION = '2.0.1' blddir = 'bin' @@ -71,25 +71,6 @@ def configure(conf): 'test/run-lockall.c', 'test/run-remap-in-read_traverse.c', 'test/run-seed.c', - 'test/run-tdb1-3G-file.c', - 'test/run-tdb1-bad-tdb-header.c', - 'test/run-tdb1.c', - 'test/run-tdb1-check.c', - 'test/run-tdb1-corrupt.c', - 'test/run-tdb1-endian.c', - 'test/run-tdb1-hashsize.c', - 'test/run-tdb1-incompatible.c', - 'test/run-tdb1-nested-transactions.c', - 'test/run-tdb1-nested-traverse.c', - 'test/run-tdb1-no-lock-during-traverse.c', - 'test/run-tdb1-oldhash.c', - 'test/run-tdb1-readonly-check.c', - 'test/run-tdb1-rwlock-check.c', - 'test/run-tdb1-seqnum-wrap.c', - 'test/run-tdb1-summary.c', - 'test/run-tdb1-traverse-in-transaction.c', - 'test/run-tdb1-wronghash-fail.c', - 'test/run-tdb1-zero-append.c', 'test/run-tdb_errorstr.c', 'test/run-tdb_foreach.c', 'test/run-traverse.c'] @@ -115,8 +96,7 @@ def configure(conf): 'test/api-open-multiple-times.c', 'test/api-record-expand.c', 'test/api-simple-delete.c', - 'test/api-summary.c', - 'test/api-tdb1-flag-removal.c'] + 'test/api-summary.c'] conf.env.TEST_API_HELPER_SRC=['test/helpapi-external-agent.c'] conf.env.TEST_RUN_HELPER_SRC=['test/helprun-external-agent.c', 'test/helprun-layout.c'] @@ -124,9 +104,7 @@ def configure(conf): 'test/failtest_helper.c', 'test/lock-tracking.c', 'test/logging.c', - 'test/tap-interface.c', - 'test/tdb1-external-agent.c', - 'test/tdb1-lock-tracking.c'] + 'test/tap-interface.c'] if Options.options.BUILD_TDB2: conf.DEFINE('BUILD_TDB2', 1) @@ -170,11 +148,7 @@ def build(bld): private_library = True SRC = '''check.c free.c hash.c io.c lock.c open.c - summary.c tdb.c transaction.c traverse.c - tdb1_check.c tdb1_freelist.c tdb1_hash.c - tdb1_io.c tdb1_lock.c tdb1_open.c - tdb1_summary.c tdb1_tdb.c tdb1_transaction.c - tdb1_traverse.c''' + summary.c tdb.c transaction.c traverse.c''' if not bld.CONFIG_SET('USING_SYSTEM_TDB2'): bld.SAMBA_LIBRARY('tdb', @@ -182,7 +156,7 @@ def build(bld): deps='replace ccan', includes='.', abi_directory='ABI', - abi_match='tdb_* tdb1_incompatible_hash', + abi_match='tdb_*', hide_symbols=True, vnum=VERSION, public_headers='tdb2.h', |