tdb: delete from CCAN.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 14 Feb 2012 09:39:18 +0000 (20:09 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 14 Feb 2012 09:39:18 +0000 (20:09 +1030)
This was an early experiment in putting code into CCAN, but TDB is a public
library distributed as part of the Samba sources; there is no reason to
publish it here (especially now the unit tests are also in Samba).

74 files changed:
ccan/tdb/LICENSE [deleted symlink]
ccan/tdb/_info [deleted file]
ccan/tdb/check.c [deleted file]
ccan/tdb/dump.c [deleted file]
ccan/tdb/error.c [deleted file]
ccan/tdb/freelist.c [deleted file]
ccan/tdb/freelistcheck.c [deleted file]
ccan/tdb/hash.c [deleted file]
ccan/tdb/io.c [deleted file]
ccan/tdb/lock.c [deleted file]
ccan/tdb/open.c [deleted file]
ccan/tdb/summary.c [deleted file]
ccan/tdb/tdb.c [deleted file]
ccan/tdb/tdb.h [deleted file]
ccan/tdb/tdb_private.h [deleted file]
ccan/tdb/test/external-agent.c [deleted file]
ccan/tdb/test/external-agent.h [deleted file]
ccan/tdb/test/jenkins-be-hash.tdb [deleted file]
ccan/tdb/test/jenkins-le-hash.tdb [deleted file]
ccan/tdb/test/lock-tracking.c [deleted file]
ccan/tdb/test/lock-tracking.h [deleted file]
ccan/tdb/test/logging.c [deleted file]
ccan/tdb/test/logging.h [deleted file]
ccan/tdb/test/old-nohash-be.tdb [deleted file]
ccan/tdb/test/old-nohash-le.tdb [deleted file]
ccan/tdb/test/run-3G-file.c [deleted file]
ccan/tdb/test/run-bad-tdb-header.c [deleted file]
ccan/tdb/test/run-check.c [deleted file]
ccan/tdb/test/run-corrupt.c [deleted file]
ccan/tdb/test/run-die-during-transaction.c [deleted file]
ccan/tdb/test/run-endian.c [deleted file]
ccan/tdb/test/run-incompatible.c [deleted file]
ccan/tdb/test/run-nested-transactions.c [deleted file]
ccan/tdb/test/run-nested-traverse.c [deleted file]
ccan/tdb/test/run-no-lock-during-traverse.c [deleted file]
ccan/tdb/test/run-oldhash.c [deleted file]
ccan/tdb/test/run-open-during-transaction.c [deleted file]
ccan/tdb/test/run-readonly-check.c [deleted file]
ccan/tdb/test/run-rwlock-check.c [deleted file]
ccan/tdb/test/run-summary.c [deleted file]
ccan/tdb/test/run-transaction-expand.c [deleted file]
ccan/tdb/test/run-traverse-in-transaction.c [deleted file]
ccan/tdb/test/run-wronghash-fail.c [deleted file]
ccan/tdb/test/run-zero-append.c [deleted file]
ccan/tdb/test/run.c [deleted file]
ccan/tdb/test/rwlock-be.tdb [deleted file]
ccan/tdb/test/rwlock-le.tdb [deleted file]
ccan/tdb/test/tdb.corrupt [deleted file]
ccan/tdb/tools/Makefile [deleted file]
ccan/tdb/tools/benchmarks/configuration.ldb.trace.19774.rz [deleted file]
ccan/tdb/tools/benchmarks/sam.ldb.trace.19774.rz [deleted file]
ccan/tdb/tools/benchmarks/schema.ldb.trace.19774.rz [deleted file]
ccan/tdb/tools/benchmarks/templates.ldb.trace.19774.rz [deleted file]
ccan/tdb/tools/benchmarks/users.ldb.trace.19774.rz [deleted file]
ccan/tdb/tools/keywords.c [deleted file]
ccan/tdb/tools/keywords.gperf [deleted file]
ccan/tdb/tools/mktdb.c [deleted file]
ccan/tdb/tools/replay_trace.c [deleted file]
ccan/tdb/tools/speed.c [deleted file]
ccan/tdb/tools/starvation.c [deleted file]
ccan/tdb/tools/tdbdump.c [deleted file]
ccan/tdb/tools/tdbtool.c [deleted file]
ccan/tdb/tools/tdbtorture.c [deleted file]
ccan/tdb/tools/tests/1-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/2-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/3-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/4-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/5-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/6-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/7-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/8-torture.trace.tar.bz2 [deleted file]
ccan/tdb/tools/tests/9-torture.trace.tar.bz2 [deleted file]
ccan/tdb/transaction.c [deleted file]
ccan/tdb/traverse.c [deleted file]

diff --git a/ccan/tdb/LICENSE b/ccan/tdb/LICENSE
deleted file mode 120000 (symlink)
index 7455044..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../licenses/LGPL-3
\ No newline at end of file
diff --git a/ccan/tdb/_info b/ccan/tdb/_info
deleted file mode 100644 (file)
index ca49e3f..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#include <string.h>
-#include <stdio.h>
-
-/**
- * tdb - The trivial (transactional) database
- *
- * The tdb module provides an efficient keyword data mapping (usually
- * within a file).  It supports transactions, so the contents of the
- * database is reliable even across crashes.
- *
- * Example:
- *     #include <ccan/tdb/tdb.h>
- *     #include <ccan/str/str.h>
- *     #include <err.h>
- *     #include <stdio.h>
- *     
- *     static void usage(const char *argv0)
- *     {
- *             errx(1, "Usage: %s fetch <dbfile> <key>\n"
- *                  "OR %s store <dbfile> <key> <data>", argv0, argv0);
- *     }
- *     
- *     int main(int argc, char *argv[])
- *     {
- *             struct tdb_context *tdb;
- *             TDB_DATA key, value;
- *     
- *             if (argc < 4)
- *                     usage(argv[0]);
- *     
- *             tdb = tdb_open(argv[2], 1024, TDB_DEFAULT, O_CREAT|O_RDWR,
- *                             0600);
- *             if (!tdb)
- *                     err(1, "Opening %s", argv[2]);
- *     
- *             key.dptr = (void *)argv[3];
- *             key.dsize = strlen(argv[3]);
- *     
- *             if (streq(argv[1], "fetch")) {
- *                     if (argc != 4)
- *                             usage(argv[0]);
- *                     value = tdb_fetch(tdb, key);
- *                     if (!value.dptr)
- *                             errx(1, "fetch %s: %s",
- *                                  argv[3], tdb_errorstr(tdb));
- *                     printf("%.*s\n", value.dsize, (char *)value.dptr);
- *                     free(value.dptr);
- *             } else if (streq(argv[1], "store")) {
- *                     if (argc != 5)
- *                             usage(argv[0]);
- *                     value.dptr = (void *)argv[4];
- *                     value.dsize = strlen(argv[4]);
- *                     if (tdb_store(tdb, key, value, 0) != 0)
- *                             errx(1, "store %s: %s",
- *                                  argv[3], tdb_errorstr(tdb));
- *             } else
- *                     usage(argv[0]);
- *     
- *             return 0;
- *     }
- *
- * Maintainer: Rusty Russell <rusty@rustcorp.com.au>
- *
- * Author: Andrew Tridgell, Jeremy Allison, Rusty Russell
- *
- * License: LGPL (v3 or any later version)
- *
- * Ccanlint:
- *     // valgrind breaks fcntl locks.
- *     tests_pass_valgrind test/run-open-during-transaction.c:FAIL
- *     tests_pass_valgrind_noleaks test/run-die-during-transaction.c:FAIL
- */
-int main(int argc, char *argv[])
-{
-       if (argc != 2)
-               return 1;
-
-       if (strcmp(argv[1], "depends") == 0) {
-               printf("ccan/compiler\n");
-               return 0;
-       }
-
-       return 1;
-}
diff --git a/ccan/tdb/check.c b/ccan/tdb/check.c
deleted file mode 100644 (file)
index 4fbbb92..0000000
+++ /dev/null
@@ -1,473 +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 "tdb_private.h"
-#include <limits.h>
-
-/* Since we opened it, these shouldn't fail unless it's recent corruption. */
-static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery)
-{
-       struct tdb_header hdr;
-       uint32_t h1, h2;
-
-       if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1)
-               return false;
-       if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0)
-               goto corrupt;
-
-       CONVERT(hdr);
-       if (hdr.version != TDB_VERSION)
-               goto corrupt;
-
-       if (hdr.rwlocks != 0 && hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC)
-               goto corrupt;
-
-       tdb_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->header.hash_size)
-               goto corrupt;
-
-       if (hdr.recovery_start != 0 &&
-           hdr.recovery_start < TDB_DATA_START(tdb->header.hash_size))
-               goto corrupt;
-
-       *recovery = hdr.recovery_start;
-       return true;
-
-corrupt:
-       tdb->ecode = TDB_ERR_CORRUPT;
-       TDB_LOG((tdb, TDB_DEBUG_ERROR, "Header is corrupt\n"));
-       return false;
-}
-
-/* Generic record header check. */
-static bool tdb_check_record(struct tdb_context *tdb,
-                            tdb_off_t off,
-                            const struct tdb_record *rec)
-{
-       tdb_off_t tailer;
-
-       /* Check rec->next: 0 or points to record offset, aligned. */
-       if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->header.hash_size)){
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "Record offset %d too small next %d\n",
-                        off, rec->next));
-               goto corrupt;
-       }
-       if (rec->next + sizeof(*rec) < rec->next) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "Record offset %d too large next %d\n",
-                        off, rec->next));
-               goto corrupt;
-       }
-       if ((rec->next % TDB_ALIGNMENT) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "Record offset %d misaligned next %d\n",
-                        off, rec->next));
-               goto corrupt;
-       }
-       if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0))
-               goto corrupt;
-
-       /* Check rec_len: similar to rec->next, implies next record. */
-       if ((rec->rec_len % TDB_ALIGNMENT) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "Record offset %d misaligned length %d\n",
-                        off, rec->rec_len));
-               goto corrupt;
-       }
-       /* Must fit tailer. */
-       if (rec->rec_len < sizeof(tailer)) {
-               TDB_LOG((tdb, TDB_DEBUG_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->methods->tdb_oob(tdb, off+sizeof(*rec)+rec->rec_len, 0))
-               goto corrupt;
-
-       /* Check tailer. */
-       if (tdb_ofs_read(tdb, off+sizeof(*rec)+rec->rec_len-sizeof(tailer),
-                        &tailer) == -1)
-               goto corrupt;
-       if (tailer != sizeof(*rec) + rec->rec_len) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "Record offset %d invalid tailer\n", off));
-               goto corrupt;
-       }
-
-       return true;
-
-corrupt:
-       tdb->ecode = 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,
-                         tdb_off_t off, tdb_len_t len)
-{
-       TDB_DATA d;
-
-       d.dsize = len;
-
-       if (tdb->transaction == NULL && tdb->map_ptr != NULL)
-               d.dptr = (unsigned char *)tdb->map_ptr + off;
-       else
-               d.dptr = tdb_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->transaction == NULL && tdb->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 hash(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[], tdb_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++) {
-               hash(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 tdb_check_used_record(struct tdb_context *tdb,
-                                 tdb_off_t off,
-                                 const struct tdb_record *rec,
-                                 unsigned char **hashes,
-                                 int (*check)(TDB_DATA, TDB_DATA, void *),
-                                 void *private_data)
-{
-       TDB_DATA key, data;
-
-       if (!tdb_check_record(tdb, off, rec))
-               return false;
-
-       /* key + data + tailer must fit in record */
-       if (rec->key_len + rec->data_len + sizeof(tdb_off_t) > rec->rec_len) {
-               TDB_LOG((tdb, TDB_DEBUG_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 (tdb->hash_fn(&key) != rec->full_hash) {
-               TDB_LOG((tdb, TDB_DEBUG_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[BUCKET(rec->full_hash)+1], off);
-       /* And similarly if the next pointer is valid. */
-       if (rec->next)
-               record_offset(hashes[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 != TDB_DEAD_MAGIC) {
-               data = get_bytes(tdb, off + sizeof(*rec) + rec->key_len,
-                                rec->data_len);
-               if (!data.dptr)
-                       goto fail_put_key;
-
-               if (check(key, data, private_data) == -1)
-                       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 tdb_check_free_record(struct tdb_context *tdb,
-                                 tdb_off_t off,
-                                 const struct tdb_record *rec,
-                                 unsigned char **hashes)
-{
-       if (!tdb_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 tdb_dead_space(struct tdb_context *tdb, tdb_off_t off)
-{
-       size_t len;
-
-       for (len = 0; off + len < tdb->map_size; len++) {
-               char c;
-               if (tdb->methods->tdb_read(tdb, off, &c, 1, 0))
-                       return 0;
-               if (c != 0 && c != 0x42)
-                       break;
-       }
-       return len;
-}
-
-int tdb_check(struct tdb_context *tdb,
-             int (*check)(TDB_DATA key, TDB_DATA data, void *private_data),
-             void *private_data)
-{
-       unsigned int h;
-       unsigned char **hashes;
-       tdb_off_t off, recovery_start;
-       struct tdb_record rec;
-       bool found_recovery = false;
-       tdb_len_t dead;
-       bool locked;
-
-       /* Read-only databases use no locking at all: it's best-effort.
-        * We may have a write lock already, so skip that case too. */
-       if (tdb->read_only || tdb->allrecord_lock.count != 0) {
-               locked = false;
-       } else {
-               if (tdb_lockall_read(tdb) == -1)
-                       return -1;
-               locked = true;
-       }
-
-       /* Make sure we know true size of the underlying file. */
-       tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1);
-
-       /* Header must be OK: also gets us the recovery ptr, if any. */
-       if (!tdb_check_header(tdb, &recovery_start))
-               goto unlock;
-
-       /* We should have the whole header, too. */
-       if (tdb->map_size < TDB_DATA_START(tdb->header.hash_size)) {
-               tdb->ecode = TDB_ERR_CORRUPT;
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "File too short for hashes\n"));
-               goto unlock;
-       }
-
-       /* One big malloc: pointers then bit arrays. */
-       hashes = (unsigned char **)calloc(
-                       1, sizeof(hashes[0]) * (1+tdb->header.hash_size)
-                       + BITMAP_BITS / CHAR_BIT * (1+tdb->header.hash_size));
-       if (!hashes) {
-               tdb->ecode = TDB_ERR_OOM;
-               goto unlock;
-       }
-
-       /* Initialize pointers */
-       hashes[0] = (unsigned char *)(&hashes[1+tdb->header.hash_size]);
-       for (h = 1; h < 1+tdb->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->header.hash_size; h++) {
-               if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_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 = TDB_DATA_START(tdb->header.hash_size);
-            off < tdb->map_size;
-            off += sizeof(rec) + rec.rec_len) {
-               if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec),
-                                          DOCONV()) == -1)
-                       goto free;
-               switch (rec.magic) {
-               case TDB_MAGIC:
-               case TDB_DEAD_MAGIC:
-                       if (!tdb_check_used_record(tdb, off, &rec, hashes,
-                                                  check, private_data))
-                               goto free;
-                       break;
-               case TDB_FREE_MAGIC:
-                       if (!tdb_check_free_record(tdb, off, &rec, hashes))
-                               goto free;
-                       break;
-               /* If we crash after ftruncate, we can get zeroes or fill. */
-               case TDB_RECOVERY_INVALID_MAGIC:
-               case 0x42424242:
-                       if (recovery_start == off) {
-                               found_recovery = true;
-                               break;
-                       }
-                       dead = tdb_dead_space(tdb, off);
-                       if (dead < sizeof(rec))
-                               goto corrupt;
-
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                                "Dead space at %d-%d (of %u)\n",
-                                off, off + dead, tdb->map_size));
-                       rec.rec_len = dead - sizeof(rec);
-                       break;
-               case TDB_RECOVERY_MAGIC:
-                       if (recovery_start != off) {
-                               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                                        "Unexpected recovery record at offset %d\n",
-                                        off));
-                               goto free;
-                       }
-                       found_recovery = true;
-                       break;
-               default: ;
-               corrupt:
-                       tdb->ecode = TDB_ERR_CORRUPT;
-                       TDB_LOG((tdb, TDB_DEBUG_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->header.hash_size; h++) {
-               unsigned int i;
-               for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) {
-                       if (hashes[h][i] != 0) {
-                               tdb->ecode = TDB_ERR_CORRUPT;
-                               TDB_LOG((tdb, TDB_DEBUG_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_LOG((tdb, TDB_DEBUG_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/ccan/tdb/dump.c b/ccan/tdb/dump.c
deleted file mode 100644 (file)
index bdcbfab..0000000
+++ /dev/null
@@ -1,137 +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 "tdb_private.h"
-
-static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash,
-                                tdb_off_t offset)
-{
-       struct tdb_record rec;
-       tdb_off_t tailer_ofs, tailer;
-
-       if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, 
-                                  sizeof(rec), DOCONV()) == -1) {
-               printf("ERROR: failed to read record at %u\n", offset);
-               return 0;
-       }
-
-       printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%d "
-              "key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n",
-              hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len,
-              rec.full_hash, rec.magic);
-
-       tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t);
-
-       if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) {
-               printf("ERROR: failed to read tailer at %u\n", tailer_ofs);
-               return rec.next;
-       }
-
-       if (tailer != rec.rec_len + sizeof(rec)) {
-               printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n",
-                               (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec)));
-       }
-       return rec.next;
-}
-
-static int tdb_dump_chain(struct tdb_context *tdb, int i)
-{
-       tdb_off_t rec_ptr, top;
-
-       top = TDB_HASH_TOP(i);
-
-       if (tdb_lock(tdb, i, F_WRLCK) != 0)
-               return -1;
-
-       if (tdb_ofs_read(tdb, top, &rec_ptr) == -1)
-               return tdb_unlock(tdb, i, F_WRLCK);
-
-       if (rec_ptr)
-               printf("hash=%d\n", i);
-
-       while (rec_ptr) {
-               rec_ptr = tdb_dump_record(tdb, i, rec_ptr);
-       }
-
-       return tdb_unlock(tdb, i, F_WRLCK);
-}
-
-void tdb_dump_all(struct tdb_context *tdb)
-{
-       int i;
-       for (i=0;i<tdb->header.hash_size;i++) {
-               tdb_dump_chain(tdb, i);
-       }
-       printf("freelist:\n");
-       tdb_dump_chain(tdb, -1);
-}
-
-int tdb_printfreelist(struct tdb_context *tdb)
-{
-       int ret;
-       long total_free = 0;
-       tdb_off_t offset, rec_ptr;
-       struct tdb_record rec;
-
-       if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0)
-               return ret;
-
-       offset = FREELIST_TOP;
-
-       /* read in the freelist top */
-       if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) {
-               tdb_unlock(tdb, -1, F_WRLCK);
-               return 0;
-       }
-
-       printf("freelist top=[0x%08x]\n", rec_ptr );
-       while (rec_ptr) {
-               if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, 
-                                          sizeof(rec), DOCONV()) == -1) {
-                       tdb_unlock(tdb, -1, F_WRLCK);
-                       return -1;
-               }
-
-               if (rec.magic != TDB_FREE_MAGIC) {
-                       printf("bad magic 0x%08x in free list\n", rec.magic);
-                       tdb_unlock(tdb, -1, F_WRLCK);
-                       return -1;
-               }
-
-               printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", 
-                      rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len);
-               total_free += rec.rec_len;
-
-               /* move to the next record */
-               rec_ptr = rec.next;
-       }
-       printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, 
-               (int)total_free);
-
-       return tdb_unlock(tdb, -1, F_WRLCK);
-}
-
diff --git a/ccan/tdb/error.c b/ccan/tdb/error.c
deleted file mode 100644 (file)
index 195ab23..0000000
+++ /dev/null
@@ -1,57 +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 "tdb_private.h"
-
-enum TDB_ERROR tdb_error(struct tdb_context *tdb)
-{
-       return tdb->ecode;
-}
-
-static struct tdb_errname {
-       enum TDB_ERROR ecode; const char *estring;
-} emap[] = { {TDB_SUCCESS, "Success"},
-            {TDB_ERR_CORRUPT, "Corrupt database"},
-            {TDB_ERR_IO, "IO Error"},
-            {TDB_ERR_LOCK, "Locking error"},
-            {TDB_ERR_OOM, "Out of memory"},
-            {TDB_ERR_EXISTS, "Record exists"},
-            {TDB_ERR_NOLOCK, "Lock exists on other keys"},
-            {TDB_ERR_EINVAL, "Invalid parameter"},
-            {TDB_ERR_NOEXIST, "Record does not exist"},
-            {TDB_ERR_RDONLY, "write not permitted"} };
-
-/* Error string for the last tdb error */
-const char *tdb_errorstr(struct tdb_context *tdb)
-{
-       uint32_t i;
-       for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++)
-               if (tdb->ecode == emap[i].ecode)
-                       return emap[i].estring;
-       return "Invalid error code";
-}
-
diff --git a/ccan/tdb/freelist.c b/ccan/tdb/freelist.c
deleted file mode 100644 (file)
index c7d908e..0000000
+++ /dev/null
@@ -1,386 +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 "tdb_private.h"
-
-/* 'right' merges can involve O(n^2) cost when combined with a
-   traverse, so they are disabled until we find a way to do them in 
-   O(1) time
-*/
-#define USE_RIGHT_MERGES 0
-
-/* read a freelist record and check for simple errors */
-int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec)
-{
-       if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1)
-               return -1;
-
-       if (rec->magic == TDB_MAGIC) {
-               /* this happens when a app is showdown while deleting a record - we should
-                  not completely fail when this happens */
-               TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", 
-                        rec->magic, off));
-               rec->magic = TDB_FREE_MAGIC;
-               if (tdb->methods->tdb_write(tdb, off, rec, sizeof(*rec)) == -1)
-                       return -1;
-       }
-
-       if (rec->magic != TDB_FREE_MAGIC) {
-               /* Ensure ecode is set for log fn. */
-               tdb->ecode = TDB_ERR_CORRUPT;
-               TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n", 
-                          rec->magic, off));
-               return -1;
-       }
-       if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0)
-               return -1;
-       return 0;
-}
-
-
-#if USE_RIGHT_MERGES
-/* Remove an element from the freelist.  Must have alloc lock. */
-static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next)
-{
-       tdb_off_t last_ptr, i;
-
-       /* read in the freelist top */
-       last_ptr = FREELIST_TOP;
-       while (tdb_ofs_read(tdb, last_ptr, &i) != -1 && i != 0) {
-               if (i == off) {
-                       /* We've found it! */
-                       return tdb_ofs_write(tdb, last_ptr, &next);
-               }
-               /* Follow chain (next offset is at start of record) */
-               last_ptr = i;
-       }
-       tdb->ecode = TDB_ERR_CORRUPT;
-       TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off));
-       return -1;
-}
-#endif
-
-
-/* update a record tailer (must hold allocation lock) */
-static int update_tailer(struct tdb_context *tdb, tdb_off_t offset,
-                        const struct tdb_record *rec)
-{
-       tdb_off_t totalsize;
-
-       /* Offset of tailer from record header */
-       totalsize = sizeof(*rec) + rec->rec_len;
-       return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t),
-                        &totalsize);
-}
-
-/* Add an element into the freelist. Merge adjacent records if
-   necessary. */
-int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec)
-{
-       /* Allocation and tailer lock */
-       if (tdb_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_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n"));
-               goto fail;
-       }
-
-#if USE_RIGHT_MERGES
-       /* Look right first (I'm an Australian, dammit) */
-       if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) {
-               tdb_off_t right = offset + sizeof(*rec) + rec->rec_len;
-               struct tdb_record r;
-
-               if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right read failed at %u\n", right));
-                       goto left;
-               }
-
-               /* If it's free, expand to include it. */
-               if (r.magic == TDB_FREE_MAGIC) {
-                       if (remove_from_freelist(tdb, right, r.next) == -1) {
-                               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right free failed at %u\n", right));
-                               goto left;
-                       }
-                       rec->rec_len += sizeof(r) + r.rec_len;
-                       if (update_tailer(tdb, offset, rec) == -1) {
-                               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset));
-                               goto fail;
-                       }
-               }
-       }
-left:
-#endif
-
-       /* Look left */
-       if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->header.hash_size)) {
-               tdb_off_t left = offset - sizeof(tdb_off_t);
-               struct tdb_record l;
-               tdb_off_t leftsize;
-               
-               /* Read in tailer and jump back to header */
-               if (tdb_ofs_read(tdb, left, &leftsize) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left));
-                       goto update;
-               }
-
-               /* it could be uninitialised data */
-               if (leftsize == 0 || leftsize == TDB_PAD_U32) {
-                       goto update;
-               }
-
-               left = offset - leftsize;
-
-               if (leftsize > offset ||
-                   left < TDB_DATA_START(tdb->header.hash_size)) {
-                       goto update;
-               }
-
-               /* Now read in the left record */
-               if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize));
-                       goto update;
-               }
-
-               /* If it's free, expand to include it. */
-               if (l.magic == TDB_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 (tdb_rec_write(tdb, left, &l) == -1) {
-                               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left));
-                               goto fail;
-                       }
-                       if (update_tailer(tdb, left, &l) == -1) {
-                               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset));
-                               goto fail;
-                       }
-                       tdb_unlock(tdb, -1, F_WRLCK);
-                       return 0;
-               }
-       }
-
-update:
-
-       /* Now, prepend to free list */
-       rec->magic = TDB_FREE_MAGIC;
-
-       if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 ||
-           tdb_rec_write(tdb, offset, rec) == -1 ||
-           tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%d\n", offset));
-               goto fail;
-       }
-
-       /* And we're done. */
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return 0;
-
- fail:
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return -1;
-}
-
-
-
-/* 
-   the core of tdb_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 tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, 
-                                 tdb_len_t length, tdb_off_t rec_ptr,
-                                 struct tdb_record *rec, tdb_off_t last_ptr)
-{
-#define MIN_REC_SIZE (sizeof(struct tdb_record) + sizeof(tdb_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 (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) {
-                       return 0;
-               }
-
-               /* mark it not free */
-               rec->magic = TDB_MAGIC;
-               if (tdb_rec_write(tdb, rec_ptr, rec) == -1) {
-                       return 0;
-               }
-               return rec_ptr;
-       }
-
-       /* we're going to just shorten the existing record */
-       rec->rec_len -= (length + sizeof(*rec));
-       if (tdb_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 = TDB_MAGIC;
-
-       if (tdb_rec_write(tdb, rec_ptr, rec) == -1) {
-               return 0;
-       }
-
-       if (update_tailer(tdb, rec_ptr, rec) == -1) {
-               return 0;
-       }
-
-       return rec_ptr;
-}
-
-/* allocate some space from the free list. The offset returned points
-   to a unconnected tdb_record within the database with room for at
-   least length bytes of total data
-
-   0 is returned if the space could not be allocated
- */
-tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec)
-{
-       tdb_off_t rec_ptr, last_ptr, newrec_ptr;
-       struct {
-               tdb_off_t rec_ptr, last_ptr;
-               tdb_len_t rec_len;
-       } bestfit;
-       float multiplier = 1.0;
-
-       if (tdb_lock(tdb, -1, F_WRLCK) == -1)
-               return 0;
-
-       /* over-allocate to reduce fragmentation */
-       length *= 1.25;
-
-       /* Extra bytes required for tailer */
-       length += sizeof(tdb_off_t);
-       length = TDB_ALIGN(length, TDB_ALIGNMENT);
-
- again:
-       last_ptr = FREELIST_TOP;
-
-       /* read in the freelist top */
-       if (tdb_ofs_read(tdb, 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 (tdb_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 (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) {
-                       goto fail;
-               }
-
-               newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, 
-                                             rec, bestfit.last_ptr);
-               tdb_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 (tdb_expand(tdb, length + sizeof(*rec)) == 0)
-               goto again;
- fail:
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return 0;
-}
-
-
-
-/* 
-   return the size of the freelist - used to decide if we should repack 
-*/
-int tdb_freelist_size(struct tdb_context *tdb)
-{
-       tdb_off_t ptr;
-       int count=0;
-
-       if (tdb_lock(tdb, -1, F_RDLCK) == -1) {
-               return -1;
-       }
-
-       ptr = FREELIST_TOP;
-       while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) {
-               count++;
-       }
-
-       tdb_unlock(tdb, -1, F_RDLCK);
-       return count;
-}
diff --git a/ccan/tdb/freelistcheck.c b/ccan/tdb/freelistcheck.c
deleted file mode 100644 (file)
index 5afcaa2..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   trivial database library
-
-   Copyright (C) Jeremy Allison                    2006
-
-     ** 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 "tdb_private.h"
-
-/* Check the freelist is good and contains no loops.
-   Very memory intensive - only do this as a consistency
-   checker. Heh heh - uses an in memory tdb as the storage
-   for the "seen" record list. For some reason this strikes
-   me as extremely clever as I don't have to write another tree
-   data structure implementation :-).
- */
-
-static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr)
-{
-       TDB_DATA key, data;
-
-       memset(&data, '\0', sizeof(data));
-       key.dptr = (unsigned char *)&rec_ptr;
-       key.dsize = sizeof(rec_ptr);
-       return tdb_store(mem_tdb, key, data, TDB_INSERT);
-}
-
-int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries)
-{
-       struct tdb_context *mem_tdb = NULL;
-       struct tdb_record rec;
-       tdb_off_t rec_ptr;
-       int ret = -1;
-
-       *pnum_entries = 0;
-
-       mem_tdb = tdb_open("flval", tdb->header.hash_size,
-                               TDB_INTERNAL, O_RDWR, 0600);
-       if (!mem_tdb) {
-               return -1;
-       }
-
-       if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
-               tdb_close(mem_tdb);
-               return 0;
-       }
-
-       /* Store the FREELIST_TOP record. */
-       if (seen_insert(mem_tdb, FREELIST_TOP) == -1) {
-               tdb->ecode = TDB_ERR_CORRUPT;
-               ret = -1;
-               goto fail;
-       }
-
-       /* read in the freelist top */
-       if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) {
-               goto fail;
-       }
-
-       while (rec_ptr) {
-
-               /* If we can't store this record (we've seen it
-                  before) then the free list has a loop and must
-                  be corrupt. */
-
-               if (seen_insert(mem_tdb, rec_ptr)) {
-                       tdb->ecode = TDB_ERR_CORRUPT;
-                       ret = -1;
-                       goto fail;
-               }
-
-               if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) {
-                       goto fail;
-               }
-
-               /* move to the next record */
-               rec_ptr = rec.next;
-               *pnum_entries += 1;
-       }
-
-       ret = 0;
-
-  fail:
-
-       tdb_close(mem_tdb);
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return ret;
-}
diff --git a/ccan/tdb/hash.c b/ccan/tdb/hash.c
deleted file mode 100644 (file)
index 5d920bb..0000000
+++ /dev/null
@@ -1,382 +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 "tdb_private.h"
-
-/* This is based on the hash algorithm from gdbm */
-unsigned int tdb_old_hash(TDB_DATA *key)
-{
-       uint32_t value; /* Used to compute the hash value.  */
-       uint32_t   i;   /* Used to cycle through random values. */
-
-       /* Set the initial value from the key size. */
-       for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++)
-               value = (value + (key->dptr[i] << (i*5 % 24)));
-
-       return (1103515243 * value + 12345);  
-}
-
-#if HAVE_LITTLE_ENDIAN
-# define HASH_LITTLE_ENDIAN 1
-# define HASH_BIG_ENDIAN 0
-#elif HAVE_BIG_ENDIAN
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 1
-#else
-# error Unknown endian
-#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 */
-#ifdef VALGRIND
-    const uint8_t  *k8;
-#endif
-
-    /*------ 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 */
-    /* 
-     * "k[2]&0xffffff" actually reads beyond the end of the string, but
-     * then masks off the part it's not allowed to read.  Because the
-     * string is aligned, the masked-off tail is in the same word as the
-     * rest of the string.  Every machine with memory protection I've seen
-     * does it on word boundaries, so is OK with this.  But VALGRIND will
-     * still catch it and complain.  The masking trick does make the hash
-     * noticably faster for short strings (like English words).
-     */
-#ifndef VALGRIND
-
-    switch(length)
-    {
-    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
-    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
-    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
-    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
-    case 8 : b+=k[1]; a+=k[0]; break;
-    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
-    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
-    case 5 : b+=k[1]&0xff; a+=k[0]; break;
-    case 4 : a+=k[0]; break;
-    case 3 : a+=k[0]&0xffffff; break;
-    case 2 : a+=k[0]&0xffff; break;
-    case 1 : a+=k[0]&0xff; break;
-    case 0 : return c;              /* zero length strings require no mixing */
-    }
-
-#else /* make valgrind happy */
-
-    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;
-    }
-
-#endif /* !valgrind */
-
-  } 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;
-}
-
-unsigned int tdb_jenkins_hash(TDB_DATA *key)
-{
-       return hashlittle(key->dptr, key->dsize);
-}
diff --git a/ccan/tdb/io.c b/ccan/tdb/io.c
deleted file mode 100644 (file)
index 77f26ad..0000000
+++ /dev/null
@@ -1,504 +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 "tdb_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 tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe)
-{
-       struct stat st;
-       if (len <= tdb->map_size)
-               return 0;
-       if (tdb->flags & TDB_INTERNAL) {
-               if (!probe) {
-                       /* Ensure ecode is set for log fn. */
-                       tdb->ecode = TDB_ERR_IO;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond internal malloc size %d\n",
-                                (int)len, (int)tdb->map_size));
-               }
-               return -1;
-       }
-
-       if (fstat(tdb->fd, &st) == -1) {
-               tdb->ecode = TDB_ERR_IO;
-               return -1;
-       }
-
-       if (st.st_size < (size_t)len) {
-               if (!probe) {
-                       /* Ensure ecode is set for log fn. */
-                       tdb->ecode = TDB_ERR_IO;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond eof at %d\n",
-                                (int)len, (int)st.st_size));
-               }
-               return -1;
-       }
-
-       /* Unmap, update size, remap */
-       if (tdb_munmap(tdb) == -1) {
-               tdb->ecode = TDB_ERR_IO;
-               return -1;
-       }
-       tdb->map_size = st.st_size;
-       tdb_mmap(tdb);
-       return 0;
-}
-
-/* write a lump of data at a specified offset */
-static int tdb_write(struct tdb_context *tdb, tdb_off_t off, 
-                    const void *buf, tdb_len_t len)
-{
-       if (len == 0) {
-               return 0;
-       }
-
-       if (tdb->read_only || tdb->traverse_read) {
-               tdb->ecode = TDB_ERR_RDONLY;
-               return -1;
-       }
-
-       if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0)
-               return -1;
-
-       if (tdb->map_ptr) {
-               memcpy(off + (char *)tdb->map_ptr, buf, len);
-       } else {
-               ssize_t written = pwrite(tdb->fd, buf, len, off);
-               if ((written != (ssize_t)len) && (written != -1)) {
-                       /* try once more */
-                       tdb->ecode = TDB_ERR_IO;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only "
-                                "%d of %d bytes at %d, trying once more\n",
-                                (int)written, len, off));
-                       written = pwrite(tdb->fd, (const char *)buf+written,
-                                        len-written,
-                                        off+written);
-               }
-               if (written == -1) {
-                       /* Ensure ecode is set for log fn. */
-                       tdb->ecode = TDB_ERR_IO;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d "
-                                "len=%d (%s)\n", off, len, strerror(errno)));
-                       return -1;
-               } else if (written != (ssize_t)len) {
-                       tdb->ecode = TDB_ERR_IO;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to "
-                                "write %d bytes at %d in two attempts\n",
-                                len, off));
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-/* Endian conversion: we only ever deal with 4 byte quantities */
-void *tdb_convert(void *buf, uint32_t size)
-{
-       uint32_t i;
-       unsigned char *p = buf, tmp;
-
-       for (i = 0; i < size; i += 4) {
-               tmp = p[i];
-               p[i] = p[i+3];
-               p[i+3] = tmp;
-               tmp = p[i+1];
-               p[i+1] = p[i+2];
-               p[i+2] = tmp;
-       }
-       return buf;
-}
-
-
-/* read a lump of data at a specified offset, maybe convert */
-static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, 
-                   tdb_len_t len, int cv)
-{
-       if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) {
-               return -1;
-       }
-
-       if (tdb->map_ptr) {
-               memcpy(buf, off + (char *)tdb->map_ptr, len);
-       } else {
-               ssize_t ret = pread(tdb->fd, buf, len, off);
-               if (ret != (ssize_t)len) {
-                       /* Ensure ecode is set for log fn. */
-                       tdb->ecode = TDB_ERR_IO;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %d "
-                                "len=%d ret=%d (%s) map_size=%d\n",
-                                (int)off, (int)len, (int)ret, strerror(errno),
-                                (int)tdb->map_size));
-                       return -1;
-               }
-       }
-       if (cv) {
-               tdb_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 tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain)
-{
-       uint32_t h = *chain;
-       if (tdb->map_ptr) {
-               for (;h < tdb->header.hash_size;h++) {
-                       if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) {
-                               break;
-                       }
-               }
-       } else {
-               uint32_t off=0;
-               for (;h < tdb->header.hash_size;h++) {
-                       if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) {
-                               break;
-                       }
-               }
-       }
-       (*chain) = h;
-}
-
-
-int tdb_munmap(struct tdb_context *tdb)
-{
-       if (tdb->flags & TDB_INTERNAL)
-               return 0;
-
-#if HAVE_MMAP
-       if (tdb->map_ptr) {
-               int ret;
-
-               ret = munmap(tdb->map_ptr, tdb->map_size);
-               if (ret != 0)
-                       return ret;
-       }
-#endif
-       tdb->map_ptr = NULL;
-       return 0;
-}
-
-void tdb_mmap(struct tdb_context *tdb)
-{
-       if (tdb->flags & TDB_INTERNAL)
-               return;
-
-#if HAVE_MMAP
-       if (!(tdb->flags & TDB_NOMMAP)) {
-               tdb->map_ptr = mmap(NULL, tdb->map_size, 
-                                   PROT_READ|(tdb->read_only? 0:PROT_WRITE), 
-                                   MAP_SHARED, tdb->fd, 0);
-
-               /*
-                * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!!
-                */
-
-               if (tdb->map_ptr == MAP_FAILED) {
-                       tdb->map_ptr = NULL;
-                       TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", 
-                                tdb->map_size, strerror(errno)));
-               }
-       } else {
-               tdb->map_ptr = NULL;
-       }
-#else
-       tdb->map_ptr = NULL;
-#endif
-}
-
-/* expand a file.  we prefer to use ftruncate, as that is what posix
-  says to use for mmap expansion */
-static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition)
-{
-       char buf[8192];
-
-       if (tdb->read_only || tdb->traverse_read) {
-               tdb->ecode = TDB_ERR_RDONLY;
-               return -1;
-       }
-
-       if (ftruncate(tdb->fd, size+addition) == -1) {
-               char b = 0;
-               ssize_t written = pwrite(tdb->fd,  &b, 1, (size+addition) - 1);
-               if (written == 0) {
-                       /* try once more, potentially revealing errno */
-                       written = pwrite(tdb->fd,  &b, 1, (size+addition) - 1);
-               }
-               if (written == 0) {
-                       /* again - give up, guessing errno */
-                       errno = ENOSPC;
-               }
-               if (written != 1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", 
-                                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, TDB_PAD_BYTE, sizeof(buf));
-       while (addition) {
-               size_t n = addition>sizeof(buf)?sizeof(buf):addition;
-               ssize_t written = pwrite(tdb->fd, buf, n, size);
-               if (written == 0) {
-                       /* prevent infinite loops: try _once_ more */
-                       written = pwrite(tdb->fd, buf, n, size);
-               }
-               if (written == 0) {
-                       /* give up, trying to provide a useful errno */
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write "
-                               "returned 0 twice: giving up!\n"));
-                       errno = ENOSPC;
-                       return -1;
-               } else if (written == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of "
-                                "%d bytes failed (%s)\n", (int)n,
-                                strerror(errno)));
-                       return -1;
-               } else if (written != n) {
-                       TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote "
-                                "only %d of %d bytes - retrying\n", (int)written,
-                                (int)n));
-               }
-               addition -= written;
-               size += written;
-       }
-       return 0;
-}
-
-/* You need 'size', this tells you how much you should expand by. */
-tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size)
-{
-       tdb_off_t new_size, top_size;
-
-       /* 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 = map_size + size * 2;
-       } else {
-               top_size = 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 (map_size > 100 * 1024 * 1024) {
-               new_size = map_size * 1.10;
-       } else {
-               new_size = map_size * 1.25;
-       }
-
-       /* Round the database up to a multiple of the page size */
-       new_size = MAX(top_size, new_size);
-       return TDB_ALIGN(new_size, page_size) - map_size;
-}
-
-/* expand the database at least size bytes by expanding the underlying
-   file and doing the mmap again if necessary */
-int tdb_expand(struct tdb_context *tdb, tdb_off_t size)
-{
-       struct tdb_record rec;
-       tdb_off_t offset;
-
-       if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n"));
-               return -1;
-       }
-
-       /* must know about any previous expansions by another process */
-       tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1);
-
-       size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size);
-
-       if (!(tdb->flags & TDB_INTERNAL))
-               tdb_munmap(tdb);
-
-       /*
-        * We must ensure the file is unmapped before doing this
-        * to ensure consistency with systems like OpenBSD where
-        * writes and mmaps are not consistent.
-        */
-
-       /* expand the file itself */
-       if (!(tdb->flags & TDB_INTERNAL)) {
-               if (tdb->methods->tdb_expand_file(tdb, tdb->map_size, size) != 0)
-                       goto fail;
-       }
-
-       tdb->map_size += size;
-
-       if (tdb->flags & TDB_INTERNAL) {
-               char *new_map_ptr = (char *)realloc(tdb->map_ptr,
-                                                   tdb->map_size);
-               if (!new_map_ptr) {
-                       tdb->map_size -= size;
-                       goto fail;
-               }
-               tdb->map_ptr = new_map_ptr;
-       } else {
-               /*
-                * We must ensure the file is remapped before adding the space
-                * to ensure consistency with systems like OpenBSD where
-                * writes and mmaps are not consistent.
-                */
-
-               /* We're ok if the mmap fails as we'll fallback to read/write */
-               tdb_mmap(tdb);
-       }
-
-       /* form a new freelist record */
-       memset(&rec,'\0',sizeof(rec));
-       rec.rec_len = size - sizeof(rec);
-
-       /* link it into the free list */
-       offset = tdb->map_size - size;
-       if (tdb_free(tdb, offset, &rec) == -1)
-               goto fail;
-
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return 0;
- fail:
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return -1;
-}
-
-/* read/write a tdb_off_t */
-int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d)
-{
-       return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV());
-}
-
-int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d)
-{
-       tdb_off_t off = *d;
-       return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d));
-}
-
-
-/* read a lump of data, allocating the space for it */
-unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len)
-{
-       unsigned char *buf;
-
-       /* some systems don't like zero length malloc */
-
-       if (!(buf = (unsigned char *)malloc(len ? len : 1))) {
-               /* Ensure ecode is set for log fn. */
-               tdb->ecode = TDB_ERR_OOM;
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%d (%s)\n",
-                          len, strerror(errno)));
-               return NULL;
-       }
-       if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) {
-               SAFE_FREE(buf);
-               return NULL;
-       }
-       return buf;
-}
-
-/* Give a piece of tdb data to a parser */
-
-int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
-                  tdb_off_t offset, tdb_len_t len,
-                  int (*parser)(TDB_DATA key, TDB_DATA data,
-                                void *private_data),
-                  void *private_data)
-{
-       TDB_DATA data;
-       int result;
-
-       data.dsize = len;
-
-       if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) {
-               /*
-                * Optimize by avoiding the malloc/memcpy/free, point the
-                * parser directly at the mmap area.
-                */
-               if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) {
-                       return -1;
-               }
-               data.dptr = offset + (unsigned char *)tdb->map_ptr;
-               return parser(key, data, private_data);
-       }
-
-       if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) {
-               return -1;
-       }
-
-       result = parser(key, data, private_data);
-       free(data.dptr);
-       return result;
-}
-
-/* read/write a record */
-int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec)
-{
-       if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1)
-               return -1;
-       if (TDB_BAD_MAGIC(rec)) {
-               /* Ensure ecode is set for log fn. */
-               tdb->ecode = TDB_ERR_CORRUPT;
-               TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset));
-               return -1;
-       }
-       return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0);
-}
-
-int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec)
-{
-       struct tdb_record r = *rec;
-       return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r));
-}
-
-static const struct tdb_methods io_methods = {
-       tdb_read,
-       tdb_write,
-       tdb_next_hash_chain,
-       tdb_oob,
-       tdb_expand_file,
-};
-
-/*
-  initialise the default methods table
-*/
-void tdb_io_init(struct tdb_context *tdb)
-{
-       tdb->methods = &io_methods;
-}
diff --git a/ccan/tdb/lock.c b/ccan/tdb/lock.c
deleted file mode 100644 (file)
index dfcac7a..0000000
+++ /dev/null
@@ -1,865 +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 "tdb_private.h"
-
-void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
-{
-       tdb->interrupt_sig_ptr = ptr;
-}
-
-static int fcntl_lock(struct tdb_context *tdb,
-                     int rw, off_t off, off_t len, bool waitflag)
-{
-       struct flock fl;
-
-       fl.l_type = rw;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = off;
-       fl.l_len = len;
-       fl.l_pid = 0;
-
-       if (waitflag)
-               return fcntl(tdb->fd, F_SETLKW, &fl);
-       else
-               return fcntl(tdb->fd, F_SETLK, &fl);
-}
-
-static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len)
-{
-       struct flock fl;
-#if 0 /* Check they matched up locks and unlocks correctly. */
-       char line[80];
-       FILE *locks;
-       bool found = false;
-
-       locks = fopen("/proc/locks", "r");
-
-       while (fgets(line, 80, locks)) {
-               char *p;
-               int type, start, l;
-
-               /* eg. 1: FLOCK  ADVISORY  WRITE 2440 08:01:2180826 0 EOF */
-               p = strchr(line, ':') + 1;
-               if (strncmp(p, " POSIX  ADVISORY  ", strlen(" POSIX  ADVISORY  ")))
-                       continue;
-               p += strlen(" FLOCK  ADVISORY  ");
-               if (strncmp(p, "READ  ", strlen("READ  ")) == 0)
-                       type = F_RDLCK;
-               else if (strncmp(p, "WRITE ", strlen("WRITE ")) == 0)
-                       type = F_WRLCK;
-               else
-                       abort();
-               p += 6;
-               if (atoi(p) != getpid())
-                       continue;
-               p = strchr(strchr(p, ' ') + 1, ' ') + 1;
-               start = atoi(p);
-               p = strchr(p, ' ') + 1;
-               if (strncmp(p, "EOF", 3) == 0)
-                       l = 0;
-               else
-                       l = atoi(p) - start + 1;
-
-               if (off == start) {
-                       if (len != l) {
-                               fprintf(stderr, "Len %u should be %u: %s",
-                                       (int)len, l, line);
-                               abort();
-                       }
-                       if (type != rw) {
-                               fprintf(stderr, "Type %s wrong: %s",
-                                       rw == F_RDLCK ? "READ" : "WRITE", line);
-                               abort();
-                       }
-                       found = true;
-                       break;
-               }
-       }
-
-       if (!found) {
-               fprintf(stderr, "Unlock on %u@%u not found!\n",
-                       (int)off, (int)len);
-               abort();
-       }
-
-       fclose(locks);
-#endif
-
-       fl.l_type = F_UNLCK;
-       fl.l_whence = SEEK_SET;
-       fl.l_start = off;
-       fl.l_len = len;
-       fl.l_pid = 0;
-
-       return fcntl(tdb->fd, F_SETLKW, &fl);
-}
-
-/* list -1 is the alloc list, otherwise a hash chain. */
-static tdb_off_t lock_offset(int list)
-{
-       return 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 tdb_open(). 
-
-   note that a len of zero means lock to end of file
-*/
-int tdb_brlock(struct tdb_context *tdb,
-              int rw_type, tdb_off_t offset, size_t len,
-              enum tdb_lock_flags flags)
-{
-       int ret;
-
-       if (tdb->flags & TDB_NOLOCK) {
-               return 0;
-       }
-
-       if (flags & TDB_LOCK_MARK_ONLY) {
-               return 0;
-       }
-
-       if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) {
-               tdb->ecode = TDB_ERR_RDONLY;
-               return -1;
-       }
-
-       do {
-               ret = fcntl_lock(tdb, rw_type, offset, len,
-                                flags & TDB_LOCK_WAIT);
-               /* Check for a sigalarm break. */
-               if (ret == -1 && errno == EINTR &&
-                               tdb->interrupt_sig_ptr &&
-                               *tdb->interrupt_sig_ptr) {
-                       break;
-               }
-       } while (ret == -1 && errno == EINTR);
-
-       if (ret == -1) {
-               tdb->ecode = TDB_ERR_LOCK;
-               /* Generic lock error. errno set by fcntl.
-                * EAGAIN is an expected return from non-blocking
-                * locks. */
-               if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) {
-                       TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d flags=%d len=%d\n",
-                                tdb->fd, offset, rw_type, flags, (int)len));
-               }
-               return -1;
-       }
-       return 0;
-}
-
-int tdb_brunlock(struct tdb_context *tdb,
-                int rw_type, tdb_off_t offset, size_t len)
-{
-       int ret;
-
-       if (tdb->flags & TDB_NOLOCK) {
-               return 0;
-       }
-
-       do {
-               ret = fcntl_unlock(tdb, rw_type, offset, len);
-       } while (ret == -1 && errno == EINTR);
-
-       if (ret == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %d rw_type=%d len=%d\n",
-                        tdb->fd, offset, rw_type, (int)len));
-       }
-       return ret;
-}
-
-/*
-  upgrade a read lock to a write lock. This needs to be handled in a
-  special way as some OSes (such as solaris) have too conservative
-  deadlock detection and claim a deadlock when progress can be
-  made. For those OSes we may loop for a while.  
-*/
-int tdb_allrecord_upgrade(struct tdb_context *tdb)
-{
-       int count = 1000;
-
-       if (tdb->allrecord_lock.count != 1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "tdb_allrecord_upgrade failed: count %u too high\n",
-                        tdb->allrecord_lock.count));
-               return -1;
-       }
-
-       if (tdb->allrecord_lock.off != 1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                        "tdb_allrecord_upgrade failed: already upgraded?\n"));
-               return -1;
-       }
-
-       while (count--) {
-               struct timeval tv;
-               if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
-                              TDB_LOCK_WAIT|TDB_LOCK_PROBE) == 0) {
-                       tdb->allrecord_lock.ltype = F_WRLCK;
-                       tdb->allrecord_lock.off = 0;
-                       return 0;
-               }
-               if (errno != EDEADLK) {
-                       break;
-               }
-               /* sleep for as short a time as we can - more portable than usleep() */
-               tv.tv_sec = 0;
-               tv.tv_usec = 1;
-               select(0, NULL, NULL, NULL, &tv);
-       }
-       TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_allrecord_upgrade failed\n"));
-       return -1;
-}
-
-static struct tdb_lock_type *find_nestlock(struct tdb_context *tdb,
-                                          tdb_off_t offset)
-{
-       unsigned int i;
-
-       for (i=0; i<tdb->num_lockrecs; i++) {
-               if (tdb->lockrecs[i].off == offset) {
-                       return &tdb->lockrecs[i];
-               }
-       }
-       return NULL;
-}
-
-/* lock an offset in the database. */
-int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype,
-                 enum tdb_lock_flags flags)
-{
-       struct tdb_lock_type *new_lck;
-
-       if (offset >= lock_offset(tdb->header.hash_size)) {
-               tdb->ecode = TDB_ERR_LOCK;
-               TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid offset %u for ltype=%d\n",
-                        offset, ltype));
-               return -1;
-       }
-       if (tdb->flags & TDB_NOLOCK)
-               return 0;
-
-       new_lck = find_nestlock(tdb, offset);
-       if (new_lck) {
-               /*
-                * Just increment the in-memory struct, posix locks
-                * don't stack.
-                */
-               new_lck->count++;
-               return 0;
-       }
-
-       new_lck = (struct tdb_lock_type *)realloc(
-               tdb->lockrecs,
-               sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1));
-       if (new_lck == NULL) {
-               errno = ENOMEM;
-               return -1;
-       }
-       tdb->lockrecs = new_lck;
-
-       /* Since fcntl locks don't nest, we do a lock for the first one,
-          and simply bump the count for future ones */
-       if (tdb_brlock(tdb, ltype, offset, 1, flags)) {
-               return -1;
-       }
-
-       tdb->lockrecs[tdb->num_lockrecs].off = offset;
-       tdb->lockrecs[tdb->num_lockrecs].count = 1;
-       tdb->lockrecs[tdb->num_lockrecs].ltype = ltype;
-       tdb->num_lockrecs++;
-
-       return 0;
-}
-
-static int tdb_lock_and_recover(struct tdb_context *tdb)
-{
-       int ret;
-
-       /* We need to match locking order in transaction commit. */
-       if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT)) {
-               return -1;
-       }
-
-       if (tdb_brlock(tdb, F_WRLCK, OPEN_LOCK, 1, TDB_LOCK_WAIT)) {
-               tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0);
-               return -1;
-       }
-
-       ret = tdb_transaction_recover(tdb);
-
-       tdb_brunlock(tdb, F_WRLCK, OPEN_LOCK, 1);
-       tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0);
-
-       return ret;
-}
-
-static bool have_data_locks(const struct tdb_context *tdb)
-{
-       unsigned int i;
-
-       for (i = 0; i < tdb->num_lockrecs; i++) {
-               if (tdb->lockrecs[i].off >= lock_offset(-1))
-                       return true;
-       }
-       return false;
-}
-
-static int tdb_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->allrecord_lock.count &&
-           (ltype == tdb->allrecord_lock.ltype || ltype == F_RDLCK)) {
-               return 0;
-       }
-
-       if (tdb->allrecord_lock.count) {
-               tdb->ecode = TDB_ERR_LOCK;
-               ret = -1;
-       } else {
-               /* Only check when we grab first data lock. */
-               check = !have_data_locks(tdb);
-               ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag);
-
-               if (ret == 0 && check && tdb_needs_recovery(tdb)) {
-                       tdb_nest_unlock(tdb, lock_offset(list), ltype, false);
-
-                       if (tdb_lock_and_recover(tdb) == -1) {
-                               return -1;
-                       }
-                       return tdb_lock_list(tdb, list, ltype, waitflag);
-               }
-       }
-       return ret;
-}
-
-/* lock a list in the database. list -1 is the alloc list */
-int tdb_lock(struct tdb_context *tdb, int list, int ltype)
-{
-       int ret;
-
-       ret = tdb_lock_list(tdb, list, ltype, TDB_LOCK_WAIT);
-       if (ret) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d "
-                        "ltype=%d (%s)\n",  list, ltype, strerror(errno)));
-       }
-       return ret;
-}
-
-/* lock a list in the database. list -1 is the alloc list. non-blocking lock */
-int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype)
-{
-       return tdb_lock_list(tdb, list, ltype, TDB_LOCK_NOWAIT);
-}
-
-
-int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype,
-                   bool mark_lock)
-{
-       int ret = -1;
-       struct tdb_lock_type *lck;
-
-       if (tdb->flags & TDB_NOLOCK)
-               return 0;
-
-       /* Sanity checks */
-       if (offset >= lock_offset(tdb->header.hash_size)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: offset %u invalid (%d)\n", offset, tdb->header.hash_size));
-               return ret;
-       }
-
-       lck = find_nestlock(tdb, offset);
-       if ((lck == NULL) || (lck->count == 0)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n"));
-               return -1;
-       }
-
-       if (lck->count > 1) {
-               lck->count--;
-               return 0;
-       }
-
-       /*
-        * This lock has count==1 left, so we need to unlock it in the
-        * kernel. We don't bother with decrementing the in-memory array
-        * element, we're about to overwrite it with the last array element
-        * anyway.
-        */
-
-       if (mark_lock) {
-               ret = 0;
-       } else {
-               ret = tdb_brunlock(tdb, ltype, offset, 1);
-       }
-
-       /*
-        * Shrink the array by overwriting the element just unlocked with the
-        * last array element.
-        */
-       *lck = tdb->lockrecs[--tdb->num_lockrecs];
-
-       /*
-        * We don't bother with realloc when the array shrinks, but if we have
-        * a completely idle tdb we should get rid of the locked array.
-        */
-
-       if (tdb->num_lockrecs == 0) {
-               SAFE_FREE(tdb->lockrecs);
-       }
-
-       if (ret)
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); 
-       return ret;
-}
-
-int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
-{
-       /* a global lock allows us to avoid per chain locks */
-       if (tdb->allrecord_lock.count &&
-           (ltype == tdb->allrecord_lock.ltype || ltype == F_RDLCK)) {
-               return 0;
-       }
-
-       if (tdb->allrecord_lock.count) {
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       return tdb_nest_unlock(tdb, lock_offset(list), ltype, false);
-}
-
-/*
-  get the transaction lock
- */
-int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
-{
-       return tdb_nest_lock(tdb, TRANSACTION_LOCK, ltype, TDB_LOCK_WAIT);
-}
-
-/*
-  release the transaction lock
- */
-int tdb_transaction_unlock(struct tdb_context *tdb, int ltype)
-{
-       return tdb_nest_unlock(tdb, TRANSACTION_LOCK, ltype, false);
-}
-
-/* Returns 0 if all done, -1 if error, 1 if ok. */
-static int tdb_allrecord_check(struct tdb_context *tdb, int ltype,
-                              enum tdb_lock_flags flags, bool upgradable)
-{
-       /* There are no locks on read-only dbs */
-       if (tdb->read_only || tdb->traverse_read) {
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       if (tdb->allrecord_lock.count && tdb->allrecord_lock.ltype == ltype) {
-               tdb->allrecord_lock.count++;
-               return 0;
-       }
-
-       if (tdb->allrecord_lock.count) {
-               /* a global lock of a different type exists */
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       if (tdb_have_extra_locks(tdb)) {
-               /* can't combine global and chain locks */
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       if (upgradable && ltype != F_RDLCK) {
-               /* tdb error: you can't upgrade a write lock! */
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-       return 1;
-}
-
-/* We only need to lock individual bytes, but Linux merges consecutive locks
- * so we lock in contiguous ranges. */
-static int tdb_chainlock_gradual(struct tdb_context *tdb,
-                                int ltype, enum tdb_lock_flags flags,
-                                size_t off, size_t len)
-{
-       int ret;
-       enum tdb_lock_flags nb_flags = (flags & ~TDB_LOCK_WAIT);
-
-       if (len <= 4) {
-               /* Single record.  Just do blocking lock. */
-               return tdb_brlock(tdb, ltype, off, len, flags);
-       }
-
-       /* First we try non-blocking. */
-       ret = tdb_brlock(tdb, ltype, off, len, nb_flags);
-       if (ret == 0) {
-               return 0;
-       }
-
-       /* Try locking first half, then second. */
-       ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2);
-       if (ret == -1)
-               return -1;
-
-       ret = tdb_chainlock_gradual(tdb, ltype, flags,
-                                   off + len / 2, len - len / 2);
-       if (ret == -1) {
-               tdb_brunlock(tdb, ltype, off, len / 2);
-               return -1;
-       }
-       return 0;
-}
-
-/* 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 tdb_allrecord_lock(struct tdb_context *tdb, int ltype,
-                      enum tdb_lock_flags flags, bool upgradable)
-{
-       switch (tdb_allrecord_check(tdb, ltype, flags, upgradable)) {
-       case -1:
-               return -1;
-       case 0:
-               return 0;
-       }
-
-       /* 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. */
-       if (tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP,
-                                 tdb->header.hash_size * 4) == -1) {
-               return -1;
-       }
-
-       /* Grab individual record locks. */
-       if (tdb_brlock(tdb, ltype, lock_offset(tdb->header.hash_size), 0,
-                      flags) == -1) {
-               tdb_brunlock(tdb, ltype, FREELIST_TOP,
-                            tdb->header.hash_size * 4);
-               return -1;
-       }
-
-       tdb->allrecord_lock.count = 1;
-       /* If it's upgradable, it's actually exclusive so we can treat
-        * it as a write lock. */
-       tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype;
-       tdb->allrecord_lock.off = upgradable;
-
-       if (tdb_needs_recovery(tdb)) {
-               bool mark = flags & TDB_LOCK_MARK_ONLY;
-               tdb_allrecord_unlock(tdb, ltype, mark);
-               if (mark) {
-                       tdb->ecode = TDB_ERR_LOCK;
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                                "tdb_lockall_mark cannot do recovery\n"));
-                       return -1;
-               }
-               if (tdb_lock_and_recover(tdb) == -1) {
-                       return -1;
-               }
-               return tdb_allrecord_lock(tdb, ltype, flags, upgradable);
-       }
-
-       return 0;
-}
-
-
-
-/* unlock entire db */
-int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock)
-{
-       /* There are no locks on read-only dbs */
-       if (tdb->read_only || tdb->traverse_read) {
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       if (tdb->allrecord_lock.count == 0) {
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       /* Upgradable locks are marked as write locks. */
-       if (tdb->allrecord_lock.ltype != ltype
-           && (!tdb->allrecord_lock.off || ltype != F_RDLCK)) {
-               tdb->ecode = TDB_ERR_LOCK;
-               return -1;
-       }
-
-       if (tdb->allrecord_lock.count > 1) {
-               tdb->allrecord_lock.count--;
-               return 0;
-       }
-
-       if (!mark_lock && tdb_brunlock(tdb, ltype, FREELIST_TOP, 0)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno)));
-               return -1;
-       }
-
-       tdb->allrecord_lock.count = 0;
-       tdb->allrecord_lock.ltype = 0;
-
-       return 0;
-}
-
-/* lock entire database with write lock */
-int tdb_lockall(struct tdb_context *tdb)
-{
-       tdb_trace(tdb, "tdb_lockall");
-       return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false);
-}
-
-/* lock entire database with write lock - mark only */
-int tdb_lockall_mark(struct tdb_context *tdb)
-{
-       tdb_trace(tdb, "tdb_lockall_mark");
-       return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY, false);
-}
-
-/* unlock entire database with write lock - unmark only */
-int tdb_lockall_unmark(struct tdb_context *tdb)
-{
-       tdb_trace(tdb, "tdb_lockall_unmark");
-       return tdb_allrecord_unlock(tdb, F_WRLCK, true);
-}
-
-/* lock entire database with write lock - nonblocking varient */
-int tdb_lockall_nonblock(struct tdb_context *tdb)
-{
-       int ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false);
-       tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret);
-       return ret;
-}
-
-/* unlock entire database with write lock */
-int tdb_unlockall(struct tdb_context *tdb)
-{
-       tdb_trace(tdb, "tdb_unlockall");
-       return tdb_allrecord_unlock(tdb, F_WRLCK, false);
-}
-
-/* lock entire database with read lock */
-int tdb_lockall_read(struct tdb_context *tdb)
-{
-       tdb_trace(tdb, "tdb_lockall_read");
-       return tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false);
-}
-
-/* lock entire database with read lock - nonblock varient */
-int tdb_lockall_read_nonblock(struct tdb_context *tdb)
-{
-       int ret = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_NOWAIT, false);
-       tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret);
-       return ret;
-}
-
-/* unlock entire database with read lock */
-int tdb_unlockall_read(struct tdb_context *tdb)
-{
-       tdb_trace(tdb, "tdb_unlockall_read");
-       return tdb_allrecord_unlock(tdb, F_RDLCK, false);
-}
-
-/* lock/unlock one hash chain. This is meant to be used to reduce
-   contention - it cannot guarantee how many records will be locked */
-int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
-{
-       int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
-       tdb_trace_1rec(tdb, "tdb_chainlock", key);
-       return ret;
-}
-
-/* lock/unlock one hash chain, non-blocking. This is meant to be used
-   to reduce contention - it cannot guarantee how many records will be
-   locked */
-int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
-{
-       int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
-       tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret);
-       return ret;
-}
-
-/* mark a chain as locked without actually locking it. Warning! use with great caution! */
-int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key)
-{
-       int ret = tdb_nest_lock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))),
-                               F_WRLCK, TDB_LOCK_MARK_ONLY);
-       tdb_trace_1rec(tdb, "tdb_chainlock_mark", key);
-       return ret;
-}
-
-/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
-int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key)
-{
-       tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key);
-       return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))),
-                              F_WRLCK, true);
-}
-
-int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
-{
-       tdb_trace_1rec(tdb, "tdb_chainunlock", key);
-       return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
-}
-
-int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key)
-{
-       int ret;
-       ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
-       tdb_trace_1rec(tdb, "tdb_chainlock_read", key);
-       return ret;
-}
-
-int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key)
-{
-       tdb_trace_1rec(tdb, "tdb_chainunlock_read", key);
-       return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
-}
-
-
-
-/* record lock stops delete underneath */
-int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off)
-{
-       if (tdb->allrecord_lock.count) {
-               return 0;
-       }
-       return off ? tdb_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 tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off)
-{
-       struct tdb_traverse_lock *i;
-       for (i = &tdb->travlocks; i; i = i->next)
-               if (i->off == off)
-                       return -1;
-       if (tdb->allrecord_lock.count) {
-               if (tdb->allrecord_lock.ltype == F_WRLCK) {
-                       return 0;
-               }
-               return -1;
-       }
-       return tdb_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE);
-}
-
-int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off)
-{
-       if (tdb->allrecord_lock.count) {
-               return 0;
-       }
-       return tdb_brunlock(tdb, F_WRLCK, off, 1);
-}
-
-/* fcntl locks don't stack: avoid unlocking someone else's */
-int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off)
-{
-       struct tdb_traverse_lock *i;
-       uint32_t count = 0;
-
-       if (tdb->allrecord_lock.count) {
-               return 0;
-       }
-
-       if (off == 0)
-               return 0;
-       for (i = &tdb->travlocks; i; i = i->next)
-               if (i->off == off)
-                       count++;
-       return (count == 1 ? tdb_brunlock(tdb, F_RDLCK, off, 1) : 0);
-}
-
-bool tdb_have_extra_locks(struct tdb_context *tdb)
-{
-       unsigned int extra = tdb->num_lockrecs;
-
-       /* A transaction holds the lock for all records. */
-       if (!tdb->transaction && tdb->allrecord_lock.count) {
-               return true;
-       }
-
-       /* We always hold the active lock if CLEAR_IF_FIRST. */
-       if (find_nestlock(tdb, ACTIVE_LOCK)) {
-               extra--;
-       }
-
-       /* In a transaction, we expect to hold the transaction lock */
-       if (tdb->transaction && find_nestlock(tdb, TRANSACTION_LOCK)) {
-               extra--;
-       }
-
-       return extra;
-}
-
-/* The transaction code uses this to remove all locks.  Note that this
-   may include OPEN_LOCK. */
-void tdb_release_extra_locks(struct tdb_context *tdb)
-{
-       unsigned int i, extra = 0;
-
-       if (tdb->allrecord_lock.count != 0) {
-               tdb_brunlock(tdb, tdb->allrecord_lock.ltype, FREELIST_TOP, 0);
-               tdb->allrecord_lock.count = 0;
-       }
-
-       for (i=0;i<tdb->num_lockrecs;i++) {
-               struct tdb_lock_type *lck = &tdb->lockrecs[i];
-
-               /* Don't release transaction or active locks! */
-               if (tdb->transaction && lck->off == TRANSACTION_LOCK) {
-                       tdb->lockrecs[extra++] = *lck;
-               } else if (lck->off == ACTIVE_LOCK) {
-                       tdb->lockrecs[extra++] = *lck;
-               } else {
-                       tdb_brunlock(tdb, lck->ltype, lck->off, 1);
-               }
-       }
-       tdb->num_lockrecs = extra;
-       if (tdb->num_lockrecs == 0) {
-               SAFE_FREE(tdb->lockrecs);
-       }
-}
diff --git a/ccan/tdb/open.c b/ccan/tdb/open.c
deleted file mode 100644 (file)
index aa97443..0000000
+++ /dev/null
@@ -1,617 +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 "tdb_private.h"
-
-/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
-static struct tdb_context *tdbs = NULL;
-
-/* We use two hashes to double-check they're using the right hash function. */
-void tdb_header_hash(struct tdb_context *tdb,
-                    uint32_t *magic1_hash, uint32_t *magic2_hash)
-{
-       TDB_DATA hash_key;
-       uint32_t tdb_magic = TDB_MAGIC;
-
-       hash_key.dptr = (unsigned char *)TDB_MAGIC_FOOD;
-       hash_key.dsize = sizeof(TDB_MAGIC_FOOD);
-       *magic1_hash = tdb->hash_fn(&hash_key);
-
-       hash_key.dptr = CONVERT(tdb_magic);
-       hash_key.dsize = sizeof(tdb_magic);
-       *magic2_hash = tdb->hash_fn(&hash_key);
-
-       /* Make sure at least one hash is non-zero! */
-       if (*magic1_hash == 0 && *magic2_hash == 0)
-               *magic1_hash = 1;
-}
-
-/* initialise a new database with a specified hash size */
-static int tdb_new_database(struct tdb_context *tdb, int hash_size)
-{
-       struct tdb_header *newdb;
-       size_t size;
-       int ret = -1;
-       ssize_t written;
-
-       /* We make it up in memory, then write it out if not internal */
-       size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
-       if (!(newdb = (struct tdb_header *)calloc(size, 1))) {
-               tdb->ecode = TDB_ERR_OOM;
-               return -1;
-       }
-
-       /* Fill in the header */
-       newdb->version = TDB_VERSION;
-       newdb->hash_size = hash_size;
-
-       tdb_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->flags & TDB_INCOMPATIBLE_HASH)
-               newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC;
-
-       if (tdb->flags & TDB_INTERNAL) {
-               tdb->map_size = size;
-               tdb->map_ptr = (char *)newdb;
-               memcpy(&tdb->header, newdb, sizeof(tdb->header));
-               /* Convert the `ondisk' version if asked. */
-               CONVERT(*newdb);
-               return 0;
-       }
-       if (lseek(tdb->fd, 0, SEEK_SET) == -1)
-               goto fail;
-
-       if (ftruncate(tdb->fd, 0) == -1)
-               goto fail;
-
-       /* This creates an endian-converted header, as if read from disk */
-       CONVERT(*newdb);
-       memcpy(&tdb->header, newdb, sizeof(tdb->header));
-       /* Don't endian-convert the magic food! */
-       memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
-       /* we still have "ret == -1" here */
-       written = write(tdb->fd, newdb, size);
-       if (written == size) {
-               ret = 0;
-       } else if (written != -1) {
-               /* call write once again, this usually should return -1 and
-                * set errno appropriately */
-               size -= written;
-               written = write(tdb->fd, newdb+written, size);
-               if (written == size) {
-               ret = 0;
-               } else if (written >= 0) {
-                       /* a second incomplete write - we give up.
-                        * guessing the errno... */
-                       errno = ENOSPC;
-               }
-       }
-
-  fail:
-       SAFE_FREE(newdb);
-       return ret;
-}
-
-
-
-static int tdb_already_open(dev_t device,
-                           ino_t ino)
-{
-       struct tdb_context *i;
-       
-       for (i = tdbs; i; i = i->next) {
-               if (i->device == device && i->inode == ino) {
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-/* open the database, creating it if necessary 
-
-   The open_flags and mode are passed straight to the open call on the
-   database file. A flags value of O_WRONLY is invalid. The hash size
-   is advisory, use zero for a default value.
-
-   Return is NULL on error, in which case errno is also set.  Don't 
-   try to call tdb_error or tdb_errname, just do strerror(errno).
-
-   @param name may be NULL for internal databases. */
-struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
-                     int open_flags, mode_t mode)
-{
-       return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL);
-}
-
-/* a default logging function */
-static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_FMT(3, 4);
-static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
-{
-}
-
-static bool check_header_hash(struct tdb_context *tdb,
-                             bool default_hash, uint32_t *m1, uint32_t *m2)
-{
-       tdb_header_hash(tdb, m1, m2);
-       if (tdb->header.magic1_hash == *m1 &&
-           tdb->header.magic2_hash == *m2) {
-               return true;
-       }
-
-       /* If they explicitly set a hash, always respect it. */
-       if (!default_hash)
-               return false;
-
-       /* Otherwise, try the other inbuilt hash. */
-       if (tdb->hash_fn == tdb_old_hash)
-               tdb->hash_fn = tdb_jenkins_hash;
-       else
-               tdb->hash_fn = tdb_old_hash;
-       return check_header_hash(tdb, false, m1, m2);
-}
-
-struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
-                               int open_flags, mode_t mode,
-                               const struct tdb_logging_context *log_ctx,
-                               tdb_hash_func hash_fn)
-{
-       struct tdb_context *tdb;
-       struct stat st;
-       int rev = 0, locked = 0;
-       unsigned char *vp;
-       uint32_t vertest;
-       unsigned v;
-       const char *hash_alg;
-       uint32_t magic1, magic2;
-
-       if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
-               /* Can't log this */
-               errno = ENOMEM;
-               goto fail;
-       }
-       tdb_io_init(tdb);
-       tdb->fd = -1;
-#ifdef TDB_TRACE
-       tdb->tracefd = -1;
-#endif
-       tdb->name = NULL;
-       tdb->map_ptr = NULL;
-       tdb->flags = tdb_flags;
-       tdb->open_flags = open_flags;
-       if (log_ctx) {
-               tdb->log = *log_ctx;
-       } else {
-               tdb->log.log_fn = null_log_fn;
-               tdb->log.log_private = NULL;
-       }
-
-       if (hash_fn) {
-               tdb->hash_fn = hash_fn;
-               hash_alg = "the user defined";
-       } else {
-               /* This controls what we use when creating a tdb. */
-               if (tdb->flags & TDB_INCOMPATIBLE_HASH) {
-                       tdb->hash_fn = tdb_jenkins_hash;
-               } else {
-                       tdb->hash_fn = tdb_old_hash;
-               }
-               hash_alg = "either default";
-       }
-
-       /* cache the page size */
-       tdb->page_size = getpagesize();
-       if (tdb->page_size <= 0) {
-               tdb->page_size = 0x2000;
-       }
-
-       tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0;
-
-       if ((open_flags & O_ACCMODE) == O_WRONLY) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
-                        name));
-               errno = EINVAL;
-               goto fail;
-       }
-       
-       if (hash_size == 0)
-               hash_size = DEFAULT_HASH_SIZE;
-       if ((open_flags & O_ACCMODE) == O_RDONLY) {
-               tdb->read_only = 1;
-               /* read only databases don't do locking or clear if first */
-               tdb->flags |= TDB_NOLOCK;
-               tdb->flags &= ~TDB_CLEAR_IF_FIRST;
-       }
-
-       if ((tdb->flags & TDB_ALLOW_NESTING) &&
-           (tdb->flags & TDB_DISALLOW_NESTING)) {
-               tdb->ecode = TDB_ERR_NESTING;
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
-                       "allow_nesting and disallow_nesting are not allowed together!"));
-               errno = EINVAL;
-               goto fail;
-       }
-
-       /*
-        * TDB_DISALLOW_NESTING is the default behavior.
-        */
-       if (!(tdb->flags & TDB_ALLOW_NESTING)) {
-               tdb->flags |= TDB_DISALLOW_NESTING;
-       }
-
-       /* internal databases don't mmap or lock, and start off cleared */
-       if (tdb->flags & TDB_INTERNAL) {
-               tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
-               tdb->flags &= ~TDB_CLEAR_IF_FIRST;
-               if (tdb_new_database(tdb, hash_size) != 0) {
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
-                       goto fail;
-               }
-               goto internal;
-       }
-
-       if ((tdb->fd = open(name, open_flags, mode)) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
-                        name, strerror(errno)));
-               goto fail;      /* errno set by open(2) */
-       }
-
-       /* on exec, don't inherit the fd */
-       v = fcntl(tdb->fd, F_GETFD, 0);
-        fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC);
-
-       /* ensure there is only one process initialising at once */
-       if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n",
-                        name, strerror(errno)));
-               goto fail;      /* errno set by tdb_brlock */
-       }
-
-       /* we need to zero database if we are the only one with it open */
-       if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
-           (!tdb->read_only) &&
-           (locked = (tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE) == 0))) {
-               open_flags |= O_CREAT;
-               if (ftruncate(tdb->fd, 0) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
-                                "failed to truncate %s: %s\n",
-                                name, strerror(errno)));
-                       goto fail; /* errno set by ftruncate */
-               }
-       }
-
-       errno = 0;
-       if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
-           || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) {
-               if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
-                       if (errno == 0) {
-                               errno = EIO; /* ie bad format or something */
-                       }
-                       goto fail;
-               }
-               rev = (tdb->flags & TDB_CONVERT);
-       } else if (tdb->header.version != TDB_VERSION
-                  && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION)))) {
-               /* wrong version */
-               errno = EIO;
-               goto fail;
-       }
-       vp = (unsigned char *)&tdb->header.version;
-       vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) |
-                 (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3];
-       tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
-       if (!rev)
-               tdb->flags &= ~TDB_CONVERT;
-       else {
-               tdb->flags |= TDB_CONVERT;
-               tdb_convert(&tdb->header, sizeof(tdb->header));
-       }
-       if (fstat(tdb->fd, &st) == -1)
-               goto fail;
-
-       if (tdb->header.rwlocks != 0 &&
-           tdb->header.rwlocks != TDB_HASH_RWLOCK_MAGIC) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n"));
-               goto fail;
-       }
-
-       if ((tdb->header.magic1_hash == 0) && (tdb->header.magic2_hash == 0)) {
-               /* older TDB without magic hash references */
-               tdb->hash_fn = tdb_old_hash;
-       } else if (!check_header_hash(tdb, !hash_fn, &magic1, &magic2)) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
-                        "%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]\n",
-                        name, hash_alg,
-                        tdb->header.magic1_hash,
-                        (tdb->header.magic1_hash == magic1) ? "==" : "!=",
-                        magic1,
-                        tdb->header.magic2_hash,
-                        (tdb->header.magic2_hash == magic2) ? "==" : "!=",
-                        magic2));
-               errno = EINVAL;
-               goto fail;
-       }
-
-       /* Is it already in the open list?  If so, fail. */
-       if (tdb_already_open(st.st_dev, st.st_ino)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
-                        "%s (%d,%d) is already open in this process\n",
-                        name, (int)st.st_dev, (int)st.st_ino));
-               errno = EBUSY;
-               goto fail;
-       }
-
-       if (!(tdb->name = (char *)strdup(name))) {
-               errno = ENOMEM;
-               goto fail;
-       }
-
-       tdb->map_size = st.st_size;
-       tdb->device = st.st_dev;
-       tdb->inode = st.st_ino;
-       tdb_mmap(tdb);
-       if (locked) {
-               if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
-                                "failed to take ACTIVE_LOCK on %s: %s\n",
-                                name, strerror(errno)));
-                       goto fail;
-               }
-
-       }
-
-       /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
-          we didn't get the initial exclusive lock as we need to let all other
-          users know we're using it. */
-
-       if (tdb_flags & TDB_CLEAR_IF_FIRST) {
-               /* leave this lock in place to indicate it's in use */
-               if (tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
-                       goto fail;
-               }
-       }
-
-       /* if needed, run recovery */
-       if (tdb_transaction_recover(tdb) == -1) {
-               goto fail;
-       }
-
-#ifdef TDB_TRACE
-       {
-               char tracefile[strlen(name) + 32];
-
-               snprintf(tracefile, sizeof(tracefile),
-                        "%s.trace.%li", name, (long)getpid());
-               tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
-               if (tdb->tracefd >= 0) {
-                       tdb_enable_seqnum(tdb);
-                       tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags,
-                                      open_flags);
-               } else
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile));
-       }
-#endif
-
- internal:
-       /* Internal (memory-only) databases skip all the code above to
-        * do with disk files, and resume here by releasing their
-        * open lock and hooking into the active list. */
-       if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) {
-               goto fail;
-       }
-       tdb->next = tdbs;
-       tdbs = tdb;
-       return tdb;
-
- fail:
-       { int save_errno = errno;
-
-       if (!tdb)
-               return NULL;
-
-#ifdef TDB_TRACE
-       close(tdb->tracefd);
-#endif
-       if (tdb->map_ptr) {
-               if (tdb->flags & TDB_INTERNAL)
-                       SAFE_FREE(tdb->map_ptr);
-               else
-                       tdb_munmap(tdb);
-       }
-       SAFE_FREE(tdb->name);
-       if (tdb->fd != -1)
-               if (close(tdb->fd) != 0)
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
-       SAFE_FREE(tdb->lockrecs);
-       SAFE_FREE(tdb);
-       errno = save_errno;
-       return NULL;
-       }
-}
-
-/*
- * Set the maximum number of dead records per hash chain
- */
-
-void tdb_set_max_dead(struct tdb_context *tdb, int max_dead)
-{
-       tdb->max_dead_records = max_dead;
-}
-
-/**
- * Close a database.
- *
- * @returns -1 for error; 0 for success.
- **/
-int tdb_close(struct tdb_context *tdb)
-{
-       struct tdb_context **i;
-       int ret = 0;
-
-       if (tdb->transaction) {
-               tdb_transaction_cancel(tdb);
-       }
-       tdb_trace(tdb, "tdb_close");
-
-       if (tdb->map_ptr) {
-               if (tdb->flags & TDB_INTERNAL)
-                       SAFE_FREE(tdb->map_ptr);
-               else
-                       tdb_munmap(tdb);
-       }
-       SAFE_FREE(tdb->name);
-       if (tdb->fd != -1) {
-               ret = close(tdb->fd);
-               tdb->fd = -1;
-       }
-       SAFE_FREE(tdb->lockrecs);
-
-       /* Remove from contexts list */
-       for (i = &tdbs; *i; i = &(*i)->next) {
-               if (*i == tdb) {
-                       *i = tdb->next;
-                       break;
-               }
-       }
-
-#ifdef TDB_TRACE
-       close(tdb->tracefd);
-#endif
-       memset(tdb, 0, sizeof(*tdb));
-       SAFE_FREE(tdb);
-
-       return ret;
-}
-
-/* register a loging function */
-void tdb_set_logging_function(struct tdb_context *tdb,
-                              const struct tdb_logging_context *log_ctx)
-{
-        tdb->log = *log_ctx;
-}
-
-void *tdb_get_logging_private(struct tdb_context *tdb)
-{
-       return tdb->log.log_private;
-}
-
-static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock)
-{
-       struct stat st;
-
-       if (tdb->flags & TDB_INTERNAL) {
-               return 0; /* Nothing to do. */
-       }
-
-       if (tdb_have_extra_locks(tdb)) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n"));
-               goto fail;
-       }
-
-       if (tdb->transaction != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n"));
-               goto fail;
-       }
-
-       if (tdb_munmap(tdb) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
-               goto fail;
-       }
-       if (close(tdb->fd) != 0)
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
-       tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
-       if (tdb->fd == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
-               goto fail;
-       }
-       if (fstat(tdb->fd, &st) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
-               goto fail;
-       }
-       if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n"));
-               goto fail;
-       }
-       tdb_mmap(tdb);
-
-       /* We may still think we hold the active lock. */
-       tdb->num_lockrecs = 0;
-       SAFE_FREE(tdb->lockrecs);
-
-       if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-       tdb_close(tdb);
-       return -1;
-}
-
-/* reopen a tdb - this can be used after a fork to ensure that we have an independent
-   seek pointer from our parent and to re-establish locks */
-int tdb_reopen(struct tdb_context *tdb)
-{
-       return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST);
-}
-
-/* reopen all tdb's */
-int tdb_reopen_all(int parent_longlived)
-{
-       struct tdb_context *tdb;
-
-       for (tdb=tdbs; tdb; tdb = tdb->next) {
-               bool active_lock = (tdb->flags & TDB_CLEAR_IF_FIRST);
-
-               /*
-                * If the parent is longlived (ie. a
-                * parent daemon architecture), we know
-                * it will keep it's active lock on a
-                * tdb opened with CLEAR_IF_FIRST. Thus
-                * for child processes we don't have to
-                * add an active lock. This is essential
-                * to improve performance on systems that
-                * keep POSIX locks as a non-scalable data
-                * structure in the kernel.
-                */
-               if (parent_longlived) {
-                       /* Ensure no clear-if-first. */
-                       active_lock = false;
-               }
-
-               if (tdb_reopen_internal(tdb, active_lock) != 0)
-                       return -1;
-       }
-
-       return 0;
-}
diff --git a/ccan/tdb/summary.c b/ccan/tdb/summary.c
deleted file mode 100644 (file)
index 8046a0c..0000000
+++ /dev/null
@@ -1,192 +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 "tdb_private.h"
-
-#define SUMMARY_FORMAT \
-       "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 tally_init(struct tally *tally)
-{
-       tally->total = 0;
-       tally->num = 0;
-       tally->min = tally->max = 0;
-}
-
-static void tally_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 tally_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)
-{
-       tdb_off_t rec_ptr;
-       size_t count = 0;
-
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(i), &rec_ptr) == -1)
-               return 0;
-
-       /* keep looking until we find the right record */
-       while (rec_ptr) {
-               struct tdb_record r;
-               ++count;
-               if (tdb_rec_read(tdb, rec_ptr, &r) == -1)
-                       return 0;
-               rec_ptr = r.next;
-       }
-       return count;
-}
-
-char *tdb_summary(struct tdb_context *tdb)
-{
-       tdb_off_t off;
-       struct tally freet, keys, data, dead, extra, hash, uncoal;
-       struct tdb_record rec;
-       char *ret = NULL;
-       bool locked;
-       size_t len, unc = 0;
-
-       /* Read-only databases use no locking at all: it's best-effort.
-        * We may have a write lock already, so skip that case too. */
-       if (tdb->read_only || tdb->allrecord_lock.count != 0) {
-               locked = false;
-       } else {
-               if (tdb_lockall_read(tdb) == -1)
-                       return NULL;
-               locked = true;
-       }
-
-       tally_init(&freet);
-       tally_init(&keys);
-       tally_init(&data);
-       tally_init(&dead);
-       tally_init(&extra);
-       tally_init(&hash);
-       tally_init(&uncoal);
-
-       for (off = TDB_DATA_START(tdb->header.hash_size);
-            off < tdb->map_size - 1;
-            off += sizeof(rec) + rec.rec_len) {
-               if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec),
-                                          DOCONV()) == -1)
-                       goto unlock;
-               switch (rec.magic) {
-               case TDB_MAGIC:
-                       tally_add(&keys, rec.key_len);
-                       tally_add(&data, rec.data_len);
-                       tally_add(&extra, rec.rec_len - (rec.key_len
-                                                        + rec.data_len));
-                       if (unc > 1)
-                               tally_add(&uncoal, unc - 1);
-                       unc = 0;
-                       break;
-               case TDB_FREE_MAGIC:
-                       tally_add(&freet, rec.rec_len);
-                       unc++;
-                       break;
-               /* If we crash after ftruncate, we can get zeroes or fill. */
-               case TDB_RECOVERY_INVALID_MAGIC:
-               case 0x42424242:
-                       unc++;
-                       rec.rec_len = tdb_dead_space(tdb, off) - sizeof(rec);
-                       /* Fall through */
-               case TDB_DEAD_MAGIC:
-                       tally_add(&dead, rec.rec_len);
-                       break;
-               default:
-                       TDB_LOG((tdb, TDB_DEBUG_ERROR,
-                                "Unexpected record magic 0x%x at offset %d\n",
-                                rec.magic, off));
-                       goto unlock;
-               }
-       }
-       if (unc > 1)
-               tally_add(&uncoal, unc - 1);
-
-       for (off = 0; off < tdb->header.hash_size; off++)
-               tally_add(&hash, get_hash_length(tdb, off));
-
-       /* 20 is max length of a %zu. */
-       len = strlen(SUMMARY_FORMAT) + 35*20 + 1;
-       ret = malloc(len);
-       if (!ret)
-               goto unlock;
-
-       sprintf(ret, SUMMARY_FORMAT,
-               tdb->map_size, keys.total+data.total,
-               keys.num,
-               keys.min, tally_mean(&keys), keys.max,
-               data.min, tally_mean(&data), data.max,
-               extra.min, tally_mean(&extra), extra.max,
-               dead.num,
-               dead.min, tally_mean(&dead), dead.max,
-               freet.num,
-               freet.min, tally_mean(&freet), freet.max,
-               hash.num,
-               hash.min, tally_mean(&hash), hash.max,
-               uncoal.total,
-               uncoal.min, tally_mean(&uncoal), uncoal.max,
-               keys.total * 100.0 / tdb->map_size,
-               data.total * 100.0 / tdb->map_size,
-               extra.total * 100.0 / tdb->map_size,
-               freet.total * 100.0 / tdb->map_size,
-               dead.total * 100.0 / tdb->map_size,
-               (keys.num + freet.num + dead.num)
-               * (sizeof(struct tdb_record) + sizeof(uint32_t))
-               * 100.0 / tdb->map_size,
-               tdb->header.hash_size * sizeof(tdb_off_t)
-               * 100.0 / tdb->map_size);
-
-unlock:
-       if (locked) {
-               tdb_unlockall_read(tdb);
-       }
-       return ret;
-}
diff --git a/ccan/tdb/tdb.c b/ccan/tdb/tdb.c
deleted file mode 100644 (file)
index 7317a3a..0000000
+++ /dev/null
@@ -1,1141 +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 "tdb_private.h"
-
-TDB_DATA tdb_null;
-
-/*
-  non-blocking increment of the tdb sequence number if the tdb has been opened using
-  the TDB_SEQNUM flag
-*/
-void tdb_increment_seqnum_nonblock(struct tdb_context *tdb)
-{
-       tdb_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.
-       */
-       tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
-       seqnum++;
-       tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum);
-}
-
-/*
-  increment the tdb sequence number if the tdb has been opened using
-  the TDB_SEQNUM flag
-*/
-static void tdb_increment_seqnum(struct tdb_context *tdb)
-{
-       if (!(tdb->flags & TDB_SEQNUM)) {
-               return;
-       }
-
-       if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK,
-                         TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) {
-               return;
-       }
-
-       tdb_increment_seqnum_nonblock(tdb);
-
-       tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false);
-}
-
-static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
-{
-       return memcmp(data.dptr, key.dptr, data.dsize);
-}
-
-/* Returns 0 on fail.  On success, return offset of record, and fills
-   in rec */
-static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash,
-                       struct tdb_record *r)
-{
-       tdb_off_t rec_ptr;
-       
-       /* read in the hash top */
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
-               return 0;
-
-       /* keep looking until we find the right record */
-       while (rec_ptr) {
-               if (tdb_rec_read(tdb, rec_ptr, r) == -1)
-                       return 0;
-
-               if (!TDB_DEAD(r) && hash==r->full_hash
-                   && key.dsize==r->key_len
-                   && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r),
-                                     r->key_len, tdb_key_compare,
-                                     NULL) == 0) {
-                       return rec_ptr;
-               }
-               /* detect tight infinite loop */
-               if (rec_ptr == r->next) {
-                       tdb->ecode = TDB_ERR_CORRUPT;
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_find: loop detected.\n"));
-                       return 0;
-               }
-               rec_ptr = r->next;
-       }
-       tdb->ecode = TDB_ERR_NOEXIST;
-       return 0;
-}
-
-/* As tdb_find, but if you succeed, keep the lock */
-tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
-                          struct tdb_record *rec)
-{
-       uint32_t rec_ptr;
-
-       if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
-               return 0;
-       if (!(rec_ptr = tdb_find(tdb, key, hash, rec)))
-               tdb_unlock(tdb, BUCKET(hash), locktype);
-       return rec_ptr;
-}
-
-static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
-
-/* 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 tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf)
-{
-       struct tdb_record rec;
-       tdb_off_t rec_ptr;
-
-       /* find entry */
-       if (!(rec_ptr = tdb_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) {
-               TDB_DATA data = _tdb_fetch(tdb, key);
-               if (data.dsize == dbuf.dsize &&
-                   memcmp(data.dptr, dbuf.dptr, data.dsize) == 0) {
-                       if (data.dptr) {
-                               free(data.dptr);
-                       }
-                       return 0;
-               }
-               if (data.dptr) {
-                       free(data.dptr);
-               }
-       }
-        
-
-       /* must be long enough key, data and tailer */
-       if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) {
-               tdb->ecode = TDB_SUCCESS; /* Not really an error */
-               return -1;
-       }
-
-       if (tdb->methods->tdb_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 tdb_rec_write(tdb, rec_ptr, &rec);
-       }
-       return 0;
-}
-
-/* find an entry in the database given a key */
-/* If an entry doesn't exist tdb_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 _tdb_fetch(struct tdb_context *tdb, TDB_DATA key)
-{
-       tdb_off_t rec_ptr;
-       struct tdb_record rec;
-       TDB_DATA ret;
-       uint32_t hash;
-
-       /* find which hash bucket it is in */
-       hash = tdb->hash_fn(&key);
-       if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
-               return tdb_null;
-
-       ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
-                                 rec.data_len);
-       ret.dsize = rec.data_len;
-       tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
-       return ret;
-}
-
-TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key)
-{
-       TDB_DATA ret = _tdb_fetch(tdb, key);
-
-       tdb_trace_1rec_retrec(tdb, "tdb_fetch", key, ret);
-       return ret;
-}
-
-/*
- * Find an entry in the database and hand the record's data to a parsing
- * function. The parsing function is executed under the chain read lock, so it
- * should be fast and should not block on other syscalls.
- *
- * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS.
- *
- * For mmapped tdb's that do not have a transaction open it points the parsing
- * function directly at the mmap area, it avoids the malloc/memcpy in this
- * case. If a transaction is open or no mmap is available, it has to do
- * malloc/read/parse/free.
- *
- * This is interesting for all readers of potentially large data structures in
- * the tdb records, ldb indexes being one example.
- */
-
-int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
-                    int (*parser)(TDB_DATA key, TDB_DATA data,
-                                  void *private_data),
-                    void *private_data)
-{
-       tdb_off_t rec_ptr;
-       struct tdb_record rec;
-       int ret;
-       uint32_t hash;
-
-       /* find which hash bucket it is in */
-       hash = tdb->hash_fn(&key);
-
-       if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
-               tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1);
-               tdb->ecode = TDB_ERR_NOEXIST;
-               return 0;
-       }
-       tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0);
-
-       ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
-                            rec.data_len, parser, private_data);
-
-       tdb_unlock(tdb, 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 tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
-{
-       struct tdb_record rec;
-       
-       if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0)
-               return 0;
-       tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
-       return 1;
-}
-
-int tdb_exists(struct tdb_context *tdb, TDB_DATA key)
-{
-       uint32_t hash = tdb->hash_fn(&key);
-       int ret;
-
-       ret = tdb_exists_hash(tdb, key, hash);
-       tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret);
-       return ret;
-}
-
-/* actually delete an entry in the database given the offset */
-int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct tdb_record *rec)
-{
-       tdb_off_t last_ptr, i;
-       struct tdb_record lastrec;
-
-       if (tdb->read_only || tdb->traverse_read) return -1;
-
-       if (((tdb->traverse_write != 0) && (!TDB_DEAD(rec))) ||
-           tdb_write_lock_record(tdb, rec_ptr) == -1) {
-               /* Someone traversing here: mark it as dead */
-               rec->magic = TDB_DEAD_MAGIC;
-               return tdb_rec_write(tdb, rec_ptr, rec);
-       }
-       if (tdb_write_unlock_record(tdb, rec_ptr) != 0)
-               return -1;
-
-       /* find previous record in hash chain */
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1)
-               return -1;
-       for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next)
-               if (tdb_rec_read(tdb, i, &lastrec) == -1)
-                       return -1;
-
-       /* unlink it: next ptr is at start of record. */
-       if (last_ptr == 0)
-               last_ptr = TDB_HASH_TOP(rec->full_hash);
-       if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1)
-               return -1;
-
-       /* recover the space */
-       if (tdb_free(tdb, rec_ptr, rec) == -1)
-               return -1;
-       return 0;
-}
-
-static int tdb_count_dead(struct tdb_context *tdb, uint32_t hash)
-{
-       int res = 0;
-       tdb_off_t rec_ptr;
-       struct tdb_record rec;
-       
-       /* read in the hash top */
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
-               return 0;
-
-       while (rec_ptr) {
-               if (tdb_rec_read(tdb, rec_ptr, &rec) == -1)
-                       return 0;
-
-               if (rec.magic == TDB_DEAD_MAGIC) {
-                       res += 1;
-               }
-               rec_ptr = rec.next;
-       }
-       return res;
-}
-
-/*
- * Purge all DEAD records from a hash chain
- */
-static int tdb_purge_dead(struct tdb_context *tdb, uint32_t hash)
-{
-       int res = -1;
-       struct tdb_record rec;
-       tdb_off_t rec_ptr;
-
-       if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
-               return -1;
-       }
-       
-       /* read in the hash top */
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
-               goto fail;
-
-       while (rec_ptr) {
-               tdb_off_t next;
-
-               if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) {
-                       goto fail;
-               }
-
-               next = rec.next;
-
-               if (rec.magic == TDB_DEAD_MAGIC
-                   && tdb_do_delete(tdb, rec_ptr, &rec) == -1) {
-                       goto fail;
-               }
-               rec_ptr = next;
-       }
-       res = 0;
- fail:
-       tdb_unlock(tdb, -1, F_WRLCK);
-       return res;
-}
-
-/* delete an entry in the database given a key */
-static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
-{
-       tdb_off_t rec_ptr;
-       struct tdb_record rec;
-       int ret;
-
-       if (tdb->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 (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
-                       return -1;
-
-               if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) {
-                       /*
-                        * Don't let the per-chain freelist grow too large,
-                        * delete all existing dead records
-                        */
-                       tdb_purge_dead(tdb, hash);
-               }
-
-               if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) {
-                       tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
-                       return -1;
-               }
-
-               /*
-                * Just mark the record as dead.
-                */
-               rec.magic = TDB_DEAD_MAGIC;
-               ret = tdb_rec_write(tdb, rec_ptr, &rec);
-       }
-       else {
-               if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK,
-                                                  &rec)))
-                       return -1;
-
-               ret = tdb_do_delete(tdb, rec_ptr, &rec);
-       }
-
-       if (ret == 0) {
-               tdb_increment_seqnum(tdb);
-       }
-
-       if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
-               TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n"));
-       return ret;
-}
-
-int tdb_delete(struct tdb_context *tdb, TDB_DATA key)
-{
-       uint32_t hash = tdb->hash_fn(&key);
-       int ret;
-
-       ret = tdb_delete_hash(tdb, key, hash);
-       tdb_trace_1rec_ret(tdb, "tdb_delete", key, ret);
-       return ret;
-}
-
-/*
- * See if we have a dead record around with enough space
- */
-static tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash,
-                              struct tdb_record *r, tdb_len_t length)
-{
-       tdb_off_t rec_ptr;
-       
-       /* read in the hash top */
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
-               return 0;
-
-       /* keep looking until we find the right record */
-       while (rec_ptr) {
-               if (tdb_rec_read(tdb, rec_ptr, r) == -1)
-                       return 0;
-
-               if (TDB_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 _tdb_store(struct tdb_context *tdb, TDB_DATA key,
-                      TDB_DATA dbuf, int flag, uint32_t hash)
-{
-       struct tdb_record rec;
-       tdb_off_t rec_ptr;
-       char *p = NULL;
-       int ret = -1;
-
-       /* check for it existing, on insert. */
-       if (flag == TDB_INSERT) {
-               if (tdb_exists_hash(tdb, key, hash)) {
-                       tdb->ecode = TDB_ERR_EXISTS;
-                       goto fail;
-               }
-       } else {
-               /* first try in-place update, on modify or replace. */
-               if (tdb_update_hash(tdb, key, hash, dbuf) == 0) {
-                       goto done;
-               }
-               if (tdb->ecode == TDB_ERR_NOEXIST &&
-                   flag == TDB_MODIFY) {
-                       /* if the record doesn't exist and we are in TDB_MODIFY mode then
-                        we should fail the store */
-                       goto fail;
-               }
-       }
-       /* reset the error code potentially set by the tdb_update() */
-       tdb->ecode = 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)
-               tdb_delete_hash(tdb, key, hash);
-
-       /* Copy key+value *before* allocating free space in case malloc
-          fails and we are left with a dead spot in the tdb. */
-
-       if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) {
-               tdb->ecode = TDB_ERR_OOM;
-               goto fail;
-       }
-
-       memcpy(p, key.dptr, key.dsize);
-       if (dbuf.dsize)
-               memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
-
-       if (tdb->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 = tdb_find_dead(
-                       tdb, hash, &rec,
-                       key.dsize + dbuf.dsize + sizeof(tdb_off_t));
-
-               if (rec_ptr != 0) {
-                       rec.key_len = key.dsize;
-                       rec.data_len = dbuf.dsize;
-                       rec.full_hash = hash;
-                       rec.magic = TDB_MAGIC;
-                       if (tdb_rec_write(tdb, rec_ptr, &rec) == -1
-                           || tdb->methods->tdb_write(
-                                   tdb, rec_ptr + sizeof(rec),
-                                   p, key.dsize + 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 (tdb_lock(tdb, -1, F_WRLCK) == -1) {
-               goto fail;
-       }
-
-       if ((tdb->max_dead_records != 0)
-           && (tdb_purge_dead(tdb, hash) == -1)) {
-               tdb_unlock(tdb, -1, F_WRLCK);
-               goto fail;
-       }
-
-       /* we have to allocate some space */
-       rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec);
-
-       tdb_unlock(tdb, -1, F_WRLCK);
-
-       if (rec_ptr == 0) {
-               goto fail;
-       }
-
-       /* Read hash top into next ptr */
-       if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1)
-               goto fail;
-
-       rec.key_len = key.dsize;
-       rec.data_len = dbuf.dsize;
-       rec.full_hash = hash;
-       rec.magic = TDB_MAGIC;
-
-       /* write out and point the top of the hash chain at it */
-       if (tdb_rec_write(tdb, rec_ptr, &rec) == -1
-           || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
-           || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) {
-               /* Need to tdb_unallocate() here */
-               goto fail;
-       }
-
- done:
-       ret = 0;
- fail:
-       if (ret == 0) {
-               tdb_increment_seqnum(tdb);
-       }
-
-       SAFE_FREE(p); 
-       return ret;
-}
-
-/* store an element in the database, replacing any existing element
-   with the same key
-
-   return 0 on success, -1 on failure
-*/
-int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
-{
-       uint32_t hash;
-       int ret;
-
-       if (tdb->read_only || tdb->traverse_read) {
-               tdb->ecode = TDB_ERR_RDONLY;
-               tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, -1);
-               return -1;
-       }
-
-       /* find which hash bucket it is in */
-       hash = tdb->hash_fn(&key);
-       if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
-               return -1;
-
-       ret = _tdb_store(tdb, key, dbuf, flag, hash);
-       tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, ret);
-       tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
-       return ret;
-}
-
-/* Append to an entry. Create if not exist. */
-int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
-{
-       uint32_t hash;
-       TDB_DATA dbuf;
-       int ret = -1;
-
-       /* find which hash bucket it is in */
-       hash = tdb->hash_fn(&key);
-       if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
-               return -1;
-
-       dbuf = _tdb_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->ecode = TDB_ERR_OOM;
-               goto failed;
-       }
-
-       memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize);
-       dbuf.dsize += new_dbuf.dsize;
-
-       ret = _tdb_store(tdb, key, dbuf, 0, hash);
-       tdb_trace_2rec_retrec(tdb, "tdb_append", key, new_dbuf, dbuf);
-       
-failed:
-       tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
-       SAFE_FREE(dbuf.dptr);
-       return ret;
-}
-
-
-/*
-  return the name of the current tdb file
-  useful for external logging functions
-*/
-const char *tdb_name(struct tdb_context *tdb)
-{
-       return tdb->name;
-}
-
-/*
-  return the underlying file descriptor being used by tdb, or -1
-  useful for external routines that want to check the device/inode
-  of the fd
-*/
-int tdb_fd(struct tdb_context *tdb)
-{
-       return tdb->fd;
-}
-
-/*
-  return the current logging function
-  useful for external tdb routines that wish to log tdb errors
-*/
-tdb_log_func tdb_log_fn(struct tdb_context *tdb)
-{
-       return tdb->log.log_fn;
-}
-
-
-/*
-  get the tdb sequence number. Only makes sense if the writers opened
-  with TDB_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 tdb_get_seqnum(struct tdb_context *tdb)
-{
-       tdb_off_t seqnum=0;
-
-       tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
-       return seqnum;
-}
-
-int tdb_hash_size(struct tdb_context *tdb)
-{
-       return tdb->header.hash_size;
-}
-
-size_t tdb_map_size(struct tdb_context *tdb)
-{
-       return tdb->map_size;
-}
-
-int tdb_get_flags(struct tdb_context *tdb)
-{
-       return tdb->flags;
-}
-
-void tdb_add_flags(struct tdb_context *tdb, unsigned flags)
-{
-       if ((flags & TDB_ALLOW_NESTING) &&
-           (flags & TDB_DISALLOW_NESTING)) {
-               tdb->ecode = TDB_ERR_NESTING;
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: "
-                       "allow_nesting and disallow_nesting are not allowed together!"));
-               return;
-       }
-
-       if (flags & TDB_ALLOW_NESTING) {
-               tdb->flags &= ~TDB_DISALLOW_NESTING;
-       }
-       if (flags & TDB_DISALLOW_NESTING) {
-               tdb->flags &= ~TDB_ALLOW_NESTING;
-       }
-
-       tdb->flags |= flags;
-}
-
-void tdb_remove_flags(struct tdb_context *tdb, unsigned flags)
-{
-       if ((flags & TDB_ALLOW_NESTING) &&
-           (flags & TDB_DISALLOW_NESTING)) {
-               tdb->ecode = TDB_ERR_NESTING;
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: "
-                       "allow_nesting and disallow_nesting are not allowed together!"));
-               return;
-       }
-
-       if (flags & TDB_ALLOW_NESTING) {
-               tdb->flags |= TDB_DISALLOW_NESTING;
-       }
-       if (flags & TDB_DISALLOW_NESTING) {
-               tdb->flags |= TDB_ALLOW_NESTING;
-       }
-
-       tdb->flags &= ~flags;
-}
-
-
-/*
-  enable sequence number handling on an open tdb
-*/
-void tdb_enable_seqnum(struct tdb_context *tdb)
-{
-       tdb->flags |= TDB_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 tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length)
-{
-       struct tdb_record rec;
-       if (length <= sizeof(rec)) {
-               /* the region is not worth adding */
-               return 0;
-       }
-       if (length + offset > tdb->map_size) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n"));
-               return -1;              
-       }
-       memset(&rec,'\0',sizeof(rec));
-       rec.rec_len = length - sizeof(rec);
-       if (tdb_free(tdb, offset, &rec) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n"));
-               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 tdb_wipe_all(struct tdb_context *tdb)
-{
-       int i;
-       tdb_off_t offset = 0;
-       ssize_t data_len;
-       tdb_off_t recovery_head;
-       tdb_len_t recovery_size = 0;
-
-       if (tdb_lockall(tdb) != 0) {
-               return -1;
-       }
-
-       tdb_trace(tdb, "tdb_wipe_all");
-
-       /* see if the tdb has a recovery area, and remember its size
-          if so. We don't want to lose this as otherwise each
-          tdb_wipe_all() in a transaction will increase the size of
-          the tdb by the size of the recovery area */
-       if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n"));
-               goto failed;
-       }
-
-       if (recovery_head != 0) {
-               struct tdb_record rec;
-               if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n"));
-                       return -1;
-               }       
-               recovery_size = rec.rec_len + sizeof(rec);
-       }
-
-       /* wipe the hashes */
-       for (i=0;i<tdb->header.hash_size;i++) {
-               if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i));
-                       goto failed;
-               }
-       }
-
-       /* wipe the freelist */
-       if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n"));
-               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->map_size - TDB_DATA_START(tdb->header.hash_size));
-               if (tdb_free_region(tdb, TDB_DATA_START(tdb->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 - TDB_DATA_START(tdb->header.hash_size));
-               if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) {
-                       goto failed;
-               }
-               /* and the 2nd free list entry after the recovery area - if any */
-               data_len = tdb->map_size - (recovery_head+recovery_size);
-               if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) {
-                       goto failed;
-               }
-       }
-
-       if (tdb_unlockall(tdb) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n"));
-               goto failed;
-       }
-
-       return 0;
-
-failed:
-       tdb_unlockall(tdb);
-       return -1;
-}
-
-struct traverse_state {
-       bool error;
-       struct tdb_context *dest_db;
-};
-
-/*
-  traverse function for repacking
- */
-static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data)
-{
-       struct traverse_state *state = (struct traverse_state *)private_data;
-       if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) {
-               state->error = true;
-               return -1;
-       }
-       return 0;
-}
-
-/*
-  repack a tdb
- */
-int tdb_repack(struct tdb_context *tdb)
-{
-       struct tdb_context *tmp_db;
-       struct traverse_state state;
-
-       tdb_trace(tdb, "tdb_repack");
-
-       if (tdb_transaction_start(tdb) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to start transaction\n"));
-               return -1;
-       }
-
-       tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0);
-       if (tmp_db == NULL) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to create tmp_db\n"));
-               tdb_transaction_cancel(tdb);
-               return -1;
-       }
-
-       state.error = false;
-       state.dest_db = tmp_db;
-
-       if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n"));
-               tdb_transaction_cancel(tdb);
-               tdb_close(tmp_db);
-               return -1;              
-       }
-
-       if (state.error) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during traversal\n"));
-               tdb_transaction_cancel(tdb);
-               tdb_close(tmp_db);
-               return -1;
-       }
-
-       if (tdb_wipe_all(tdb) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to wipe database\n"));
-               tdb_transaction_cancel(tdb);
-               tdb_close(tmp_db);
-               return -1;
-       }
-
-       state.error = false;
-       state.dest_db = tdb;
-
-       if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n"));
-               tdb_transaction_cancel(tdb);
-               tdb_close(tmp_db);
-               return -1;              
-       }
-
-       if (state.error) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during second traversal\n"));
-               tdb_transaction_cancel(tdb);
-               tdb_close(tmp_db);
-               return -1;
-       }
-
-       tdb_close(tmp_db);
-
-       if (tdb_transaction_commit(tdb) != 0) {
-               TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to commit\n"));
-               return -1;
-       }
-
-       return 0;
-}
-
-#ifdef TDB_TRACE
-static void tdb_trace_write(struct tdb_context *tdb, const char *str)
-{
-       if (write(tdb->tracefd, str, strlen(str)) != strlen(str)) {
-               close(tdb->tracefd);
-               tdb->tracefd = -1;
-       }
-}
-
-static void tdb_trace_start(struct tdb_context *tdb)
-{
-       tdb_off_t seqnum=0;
-       char msg[sizeof(tdb_off_t) * 4 + 1];
-
-       tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
-       snprintf(msg, sizeof(msg), "%u ", seqnum);
-       tdb_trace_write(tdb, msg);
-}
-
-static void tdb_trace_end(struct tdb_context *tdb)
-{
-       tdb_trace_write(tdb, "\n");
-}
-
-static void tdb_trace_end_ret(struct tdb_context *tdb, int ret)
-{
-       char msg[sizeof(ret) * 4 + 4];
-       snprintf(msg, sizeof(msg), " = %i\n", ret);
-       tdb_trace_write(tdb, msg);
-}
-
-static void tdb_trace_record(struct tdb_context *tdb, TDB_DATA rec)
-{
-       char msg[20 + rec.dsize*2], *p;
-       unsigned int i;
-
-       /* We differentiate zero-length records from non-existent ones. */
-       if (rec.dptr == NULL) {
-               tdb_trace_write(tdb, " NULL");
-               return;
-       }
-
-       /* snprintf here is purely cargo-cult programming. */
-       p = msg;
-       p += snprintf(p, sizeof(msg), " %zu:", rec.dsize);
-       for (i = 0; i < rec.dsize; i++)
-               p += snprintf(p, 2, "%02x", rec.dptr[i]);
-
-       tdb_trace_write(tdb, msg);
-}
-
-void tdb_trace(struct tdb_context *tdb, const char *op)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_end(tdb);
-}
-
-void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op)
-{
-       char msg[sizeof(tdb_off_t) * 4 + 1];
-
-       snprintf(msg, sizeof(msg), "%u ", seqnum);
-       tdb_trace_write(tdb, msg);
-       tdb_trace_write(tdb, op);
-       tdb_trace_end(tdb);
-}
-
-void tdb_trace_open(struct tdb_context *tdb, const char *op,
-                   unsigned hash_size, unsigned tdb_flags, unsigned open_flags)
-{
-       char msg[128];
-
-       snprintf(msg, sizeof(msg),
-                "%s %u 0x%x 0x%x", op, hash_size, tdb_flags, open_flags);
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, msg);
-       tdb_trace_end(tdb);
-}
-
-void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_end_ret(tdb, ret);
-}
-
-void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_write(tdb, " =");
-       tdb_trace_record(tdb, ret);
-       tdb_trace_end(tdb);
-}
-
-void tdb_trace_1rec(struct tdb_context *tdb, const char *op,
-                   TDB_DATA rec)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_record(tdb, rec);
-       tdb_trace_end(tdb);
-}
-
-void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op,
-                       TDB_DATA rec, int ret)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_record(tdb, rec);
-       tdb_trace_end_ret(tdb, ret);
-}
-
-void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op,
-                          TDB_DATA rec, TDB_DATA ret)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_record(tdb, rec);
-       tdb_trace_write(tdb, " =");
-       tdb_trace_record(tdb, ret);
-       tdb_trace_end(tdb);
-}
-
-void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op,
-                            TDB_DATA rec1, TDB_DATA rec2, unsigned flag,
-                            int ret)
-{
-       char msg[1 + sizeof(ret) * 4];
-
-       snprintf(msg, sizeof(msg), " %#x", flag);
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_record(tdb, rec1);
-       tdb_trace_record(tdb, rec2);
-       tdb_trace_write(tdb, msg);
-       tdb_trace_end_ret(tdb, ret);
-}
-
-void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op,
-                          TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret)
-{
-       tdb_trace_start(tdb);
-       tdb_trace_write(tdb, op);
-       tdb_trace_record(tdb, rec1);
-       tdb_trace_record(tdb, rec2);
-       tdb_trace_write(tdb, " =");
-       tdb_trace_record(tdb, ret);
-       tdb_trace_end(tdb);
-}
-#endif
diff --git a/ccan/tdb/tdb.h b/ccan/tdb/tdb.h
deleted file mode 100644 (file)
index 6fd407a..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-#ifndef __TDB_H__
-#define __TDB_H__
-
-/* 
-   Unix SMB/CIFS implementation.
-
-   trivial database library
-
-   Copyright (C) Andrew Tridgell 1999-2004
-   
-     ** 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/>.
-*/
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-#ifndef _SAMBA_BUILD_
-/* For mode_t */
-#include <sys/types.h>
-/* For O_* flags. */
-#include <sys/stat.h>
-/* For sig_atomic_t. */
-#include <signal.h>
-#endif
-#include <ccan/compiler/compiler.h>
-
-/* flags to tdb_store() */
-#define TDB_REPLACE 1          /* Unused */
-#define TDB_INSERT 2           /* Don't overwrite an existing entry */
-#define TDB_MODIFY 3           /* Don't create an existing entry    */
-
-/* flags for tdb_open() */
-#define TDB_DEFAULT 0 /* just a readability place holder */
-#define TDB_CLEAR_IF_FIRST 1
-#define TDB_INTERNAL 2 /* don't store on disk */
-#define TDB_NOLOCK   4 /* don't do any locking */
-#define TDB_NOMMAP   8 /* don't use mmap */
-#define TDB_CONVERT 16 /* convert endian (internal use) */
-#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */
-#define TDB_NOSYNC   64 /* don't use synchronous transactions */
-#define TDB_SEQNUM   128 /* maintain a sequence number */
-#define TDB_VOLATILE   256 /* Activate the per-hashchain freelist, default 5 */
-#define TDB_ALLOW_NESTING 512 /* Allow transactions to nest */
-#define TDB_DISALLOW_NESTING 1024 /* Disallow transactions to nest */
-#define TDB_INCOMPATIBLE_HASH 2048 /* Better hashing: can't be opened by older tdb versions. */
-
-/* error codes */
-enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, 
-               TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT,
-               TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY,
-               TDB_ERR_NESTING};
-
-/* debugging uses one of the following levels */
-enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, 
-                     TDB_DEBUG_WARNING, TDB_DEBUG_TRACE};
-
-typedef struct TDB_DATA {
-       unsigned char *dptr;
-       size_t dsize;
-} TDB_DATA;
-
-/* this is the context structure that is returned from a db open */
-typedef struct tdb_context TDB_CONTEXT;
-
-typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *);
-typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_FMT(3, 4);
-typedef unsigned int (*tdb_hash_func)(TDB_DATA *key);
-
-struct tdb_logging_context {
-        tdb_log_func log_fn;
-        void *log_private;
-};
-
-struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
-                     int open_flags, mode_t mode);
-struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
-                        int open_flags, mode_t mode,
-                        const struct tdb_logging_context *log_ctx,
-                        tdb_hash_func hash_fn);
-void tdb_set_max_dead(struct tdb_context *tdb, int max_dead);
-
-int tdb_reopen(struct tdb_context *tdb);
-int tdb_reopen_all(int parent_longlived);
-void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx);
-enum TDB_ERROR tdb_error(struct tdb_context *tdb);
-const char *tdb_errorstr(struct tdb_context *tdb);
-TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
-int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
-                    int (*parser)(TDB_DATA key, TDB_DATA data,
-                                  void *private_data),
-                    void *private_data);
-int tdb_delete(struct tdb_context *tdb, TDB_DATA key);
-int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
-int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf);
-int tdb_close(struct tdb_context *tdb);
-TDB_DATA tdb_firstkey(struct tdb_context *tdb);
-TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key);
-int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *);
-int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *);
-int tdb_exists(struct tdb_context *tdb, TDB_DATA key);
-int tdb_lockall(struct tdb_context *tdb);
-int tdb_lockall_nonblock(struct tdb_context *tdb);
-int tdb_unlockall(struct tdb_context *tdb);
-int tdb_lockall_read(struct tdb_context *tdb);
-int tdb_lockall_read_nonblock(struct tdb_context *tdb);
-int tdb_unlockall_read(struct tdb_context *tdb);
-int tdb_lockall_mark(struct tdb_context *tdb);
-int tdb_lockall_unmark(struct tdb_context *tdb);
-const char *tdb_name(struct tdb_context *tdb);
-int tdb_fd(struct tdb_context *tdb);
-tdb_log_func tdb_log_fn(struct tdb_context *tdb);
-void *tdb_get_logging_private(struct tdb_context *tdb);
-int tdb_transaction_start(struct tdb_context *tdb);
-int tdb_transaction_prepare_commit(struct tdb_context *tdb);
-int tdb_transaction_commit(struct tdb_context *tdb);
-int tdb_transaction_cancel(struct tdb_context *tdb);
-int tdb_transaction_recover(struct tdb_context *tdb);
-int tdb_get_seqnum(struct tdb_context *tdb);
-int tdb_hash_size(struct tdb_context *tdb);
-size_t tdb_map_size(struct tdb_context *tdb);
-int tdb_get_flags(struct tdb_context *tdb);
-void tdb_add_flags(struct tdb_context *tdb, unsigned flag);
-void tdb_remove_flags(struct tdb_context *tdb, unsigned flag);
-void tdb_enable_seqnum(struct tdb_context *tdb);
-void tdb_increment_seqnum_nonblock(struct tdb_context *tdb);
-unsigned int tdb_jenkins_hash(TDB_DATA *key);
-int tdb_check(struct tdb_context *tdb,
-             int (*check)(TDB_DATA key, TDB_DATA data, void *private_data),
-             void *private_data);
-
-/* Low level locking functions: use with care */
-int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key);
-int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key);
-int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key);
-int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
-int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
-int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key);
-int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key);
-
-void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr);
-
-/* wipe and repack */
-int tdb_wipe_all(struct tdb_context *tdb);
-int tdb_repack(struct tdb_context *tdb);
-
-/* Debug functions. Not used in production. */
-void tdb_dump_all(struct tdb_context *tdb);
-int tdb_printfreelist(struct tdb_context *tdb);
-int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries);
-int tdb_freelist_size(struct tdb_context *tdb);
-char *tdb_summary(struct tdb_context *tdb);
-
-extern TDB_DATA tdb_null;
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* tdb.h */
diff --git a/ccan/tdb/tdb_private.h b/ccan/tdb/tdb_private.h
deleted file mode 100644 (file)
index f1c841c..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-#ifndef TDB_PRIVATE_H
-#define TDB_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/>.
-*/
-
-#ifdef _SAMBA_BUILD_
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/time.h"
-#include "system/shmem.h"
-#include "system/select.h"
-#include "system/wait.h"
-#else
-#include "config.h"
-#define _FILE_OFFSET_BITS 64
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include <utime.h>
-#endif
-#include "tdb.h"
-
-/* #define TDB_TRACE 1 */
-
-#ifndef __STRING
-#define __STRING(x)    #x
-#endif
-
-#ifndef __STRINGSTRING
-#define __STRINGSTRING(x) __STRING(x)
-#endif
-
-#ifndef __location__
-#define __location__ __FILE__ ":" __STRINGSTRING(__LINE__)
-#endif
-
-#if !HAVE_GETPAGESIZE
-#define getpagesize() 0x2000
-#endif
-
-typedef uint32_t tdb_len_t;
-typedef uint32_t tdb_off_t;
-
-#ifndef offsetof
-#define offsetof(t,f) ((size_t)&((t *)0)->f)
-#endif
-
-#define TDB_MAGIC_FOOD "TDB file\n"
-#define TDB_VERSION (0x26011967 + 6)
-#define TDB_MAGIC (0x26011999U)
-#define TDB_FREE_MAGIC (~TDB_MAGIC)
-#define TDB_DEAD_MAGIC (0xFEE1DEAD)
-#define TDB_RECOVERY_MAGIC (0xf53bc0e7U)
-#define TDB_RECOVERY_INVALID_MAGIC (0x0)
-#define TDB_HASH_RWLOCK_MAGIC (0xbad1a51U)
-#define TDB_ALIGNMENT 4
-#define DEFAULT_HASH_SIZE 131
-#define FREELIST_TOP (sizeof(struct tdb_header))
-#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1))
-#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24))
-#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
-#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
-#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t))
-#define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t))
-#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t))
-#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start)
-#define TDB_SEQNUM_OFS    offsetof(struct tdb_header, sequence_number)
-#define TDB_PAD_BYTE 0x42
-#define TDB_PAD_U32  0x42424242
-
-/* NB assumes there is a local variable called "tdb" that is the
- * current context, also takes doubly-parenthesized print-style
- * argument. */
-#define TDB_LOG(x) tdb->log.log_fn x
-
-#ifdef TDB_TRACE
-void tdb_trace(struct tdb_context *tdb, const char *op);
-void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op);
-void tdb_trace_open(struct tdb_context *tdb, const char *op,
-                   unsigned hash_size, unsigned tdb_flags, unsigned open_flags);
-void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret);
-void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret);
-void tdb_trace_1rec(struct tdb_context *tdb, const char *op,
-                   TDB_DATA rec);
-void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op,
-                       TDB_DATA rec, int ret);
-void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op,
-                          TDB_DATA rec, TDB_DATA ret);
-void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op,
-                            TDB_DATA rec1, TDB_DATA rec2, unsigned flag,
-                            int ret);
-void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op,
-                          TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret);
-#else
-#define tdb_trace(tdb, op)
-#define tdb_trace_seqnum(tdb, seqnum, op)
-#define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags)
-#define tdb_trace_ret(tdb, op, ret)
-#define tdb_trace_retrec(tdb, op, ret)
-#define tdb_trace_1rec(tdb, op, rec)
-#define tdb_trace_1rec_ret(tdb, op, rec, ret)
-#define tdb_trace_1rec_retrec(tdb, op, rec, ret)
-#define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret)
-#define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret)
-#endif /* !TDB_TRACE */
-
-/* lock offsets */
-#define OPEN_LOCK        0
-#define ACTIVE_LOCK      4
-#define 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(x); (x)=NULL;} } while(0)
-#endif
-
-#define BUCKET(hash) ((hash) % tdb->header.hash_size)
-
-#define DOCONV() (tdb->flags & TDB_CONVERT)
-#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x)
-
-
-/* the body of the database is made of one tdb_record for the free space
-   plus a separate data list for each hash value */
-struct tdb_record {
-       tdb_off_t next; /* offset of the next record in the list */
-       tdb_len_t rec_len; /* total byte length of record */
-       tdb_len_t key_len; /* byte length of key */
-       tdb_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)
-               }
-       */
-};
-
-
-/* this is stored at the front of every database */
-struct tdb_header {
-       char magic_food[32]; /* for /etc/magic */
-       uint32_t version; /* version of the code */
-       uint32_t hash_size; /* number of hash entries */
-       tdb_off_t rwlocks; /* obsolete - kept to detect old formats */
-       tdb_off_t recovery_start; /* offset of transaction recovery region */
-       tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */
-       uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */
-       uint32_t magic2_hash; /* hash of TDB_MAGIC. */
-       tdb_off_t reserved[27];
-};
-
-struct tdb_lock_type {
-       uint32_t off;
-       uint32_t count;
-       uint32_t ltype;
-};
-
-struct tdb_traverse_lock {
-       struct tdb_traverse_lock *next;
-       uint32_t off;
-       uint32_t hash;
-       int lock_rw;
-};
-
-enum tdb_lock_flags {
-       /* WAIT == F_SETLKW, NOWAIT == F_SETLK */
-       TDB_LOCK_NOWAIT = 0,
-       TDB_LOCK_WAIT = 1,
-       /* If set, don't log an error on failure. */
-       TDB_LOCK_PROBE = 2,
-       /* If set, don't actually lock at all. */
-       TDB_LOCK_MARK_ONLY = 4,
-};
-
-struct tdb_methods {
-       int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int );
-       int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t);
-       void (*next_hash_chain)(struct tdb_context *, uint32_t *);
-       int (*tdb_oob)(struct tdb_context *, tdb_off_t , int );
-       int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t );
-};
-
-struct tdb_context {
-       char *name; /* the name of the database */
-       void *map_ptr; /* where it is currently mapped */
-       int fd; /* open file descriptor for the database */
-       tdb_len_t map_size; /* how much space has been mapped */
-       int read_only; /* opened read-only */
-       int traverse_read; /* read-only traversal */
-       int traverse_write; /* read-write traversal */
-       struct tdb_lock_type allrecord_lock; /* .offset == upgradable */
-       int num_lockrecs;
-       struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */
-       enum TDB_ERROR ecode; /* error code for last tdb error */
-       struct tdb_header header; /* a cached copy of the header */
-       uint32_t flags; /* the flags passed to tdb_open */
-       struct tdb_traverse_lock travlocks; /* current traversal locks */
-       struct tdb_context *next; /* all tdbs to avoid multiple opens */
-       dev_t device;   /* uniquely identifies this tdb */
-       ino_t inode;    /* uniquely identifies this tdb */
-       struct tdb_logging_context log;
-       unsigned int (*hash_fn)(TDB_DATA *key);
-       int open_flags; /* flags used in the open - needed by reopen */
-       const struct tdb_methods *methods;
-       struct tdb_transaction *transaction;
-       int page_size;
-       int max_dead_records;
-#ifdef TDB_TRACE
-       int tracefd;
-#endif
-       volatile sig_atomic_t *interrupt_sig_ptr;
-};
-
-
-/*
-  internal prototypes
-*/
-int tdb_munmap(struct tdb_context *tdb);
-void tdb_mmap(struct tdb_context *tdb);
-int tdb_lock(struct tdb_context *tdb, int list, int ltype);
-int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype);
-int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype,
-                 enum tdb_lock_flags flags);
-int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype,
-                   bool mark_lock);
-bool tdb_have_locks(struct tdb_context *tdb);
-int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
-int tdb_brlock(struct tdb_context *tdb,
-              int rw_type, tdb_off_t offset, size_t len,
-              enum tdb_lock_flags flags);
-int tdb_brunlock(struct tdb_context *tdb,
-                int rw_type, tdb_off_t offset, size_t len);
-bool tdb_have_extra_locks(struct tdb_context *tdb);
-void tdb_release_extra_locks(struct tdb_context *tdb);
-int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
-int tdb_transaction_unlock(struct tdb_context *tdb, int ltype);
-int tdb_allrecord_lock(struct tdb_context *tdb, int ltype,
-                      enum tdb_lock_flags flags, bool upgradable);
-int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock);
-int tdb_allrecord_upgrade(struct tdb_context *tdb);
-int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
-int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off);
-int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
-int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
-void *tdb_convert(void *buf, uint32_t size);
-int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec);
-tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec);
-int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
-int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
-int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off);
-int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off);
-bool tdb_needs_recovery(struct tdb_context *tdb);
-int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec);
-int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec);
-int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct tdb_record *rec);
-unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len);
-int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
-                  tdb_off_t offset, tdb_len_t len,
-                  int (*parser)(TDB_DATA key, TDB_DATA data,
-                                void *private_data),
-                  void *private_data);
-tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
-                          struct tdb_record *rec);
-void tdb_io_init(struct tdb_context *tdb);
-int tdb_expand(struct tdb_context *tdb, tdb_off_t size);
-tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size);
-int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off,
-                     struct tdb_record *rec);
-void tdb_header_hash(struct tdb_context *tdb,
-                    uint32_t *magic1_hash, uint32_t *magic2_hash);
-unsigned int tdb_old_hash(TDB_DATA *key);
-size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off);
-#endif
diff --git a/ccan/tdb/test/external-agent.c b/ccan/tdb/test/external-agent.c
deleted file mode 100644 (file)
index 503b00d..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#include "external-agent.h"
-#include "lock-tracking.h"
-#include "logging.h"
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <err.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include <errno.h>
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/tdb_private.h>
-#include <ccan/tap/tap.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 && op != OPEN_WITH_CLEAR_IF_FIRST && !tdb) {
-               diag("external: No tdb open!");
-               return OTHER_FAILURE;
-       }
-
-       k.dptr = (void *)name;
-       k.dsize = strlen(name);
-
-       locking_would_block = 0;
-       switch (op) {
-       case OPEN:
-               if (tdb) {
-                       diag("Already have tdb %s open", tdb_name(tdb));
-                       return OTHER_FAILURE;
-               }
-               tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0,
-                                 &taplogctx, NULL);
-               if (!tdb) {
-                       if (!locking_would_block)
-                               diag("Opening tdb gave %s", strerror(errno));
-                       ret = OTHER_FAILURE;
-               } else
-                       ret = SUCCESS;
-               break;
-       case OPEN_WITH_CLEAR_IF_FIRST:
-               if (tdb)
-                       return OTHER_FAILURE;
-               tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0,
-                                 &taplogctx, NULL);
-               ret = tdb ? SUCCESS : OTHER_FAILURE;
-               break;
-       case TRANSACTION_START:
-               ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
-               break;
-       case FETCH:
-               data = tdb_fetch(tdb, k);
-               if (data.dptr == NULL) {
-                       if (tdb_error(tdb) == 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:
-               ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE;
-               break;
-       case TRANSACTION_COMMIT:
-               ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE;
-               break;
-       case CHECK:
-               ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE;
-               break;
-       case NEEDS_RECOVERY:
-               ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED;
-               break;
-       case CLOSE:
-               ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
-               tdb = NULL;
-               break;
-       default:
-               ret = OTHER_FAILURE;
-       }
-
-       if (locking_would_block)
-               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_agent(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_locks = 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_operation(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_name(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_name(enum operation op)
-{
-       switch (op) {
-       case OPEN: return "OPEN";
-       case OPEN_WITH_CLEAR_IF_FIRST: return "OPEN_WITH_CLEAR_IF_FIRST";
-       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/ccan/tdb/test/external-agent.h b/ccan/tdb/test/external-agent.h
deleted file mode 100644 (file)
index ce3755e..0000000
+++ /dev/null
@@ -1,41 +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,
-       OPEN_WITH_CLEAR_IF_FIRST,
-       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_agent(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_operation(struct agent *handle,
-                                          enum operation op,
-                                          const char *name);
-
-/* Mapping enum -> string. */
-const char *agent_return_name(enum agent_return ret);
-const char *operation_name(enum operation op);
-
-#endif /* TDB_TEST_EXTERNAL_AGENT_H */
diff --git a/ccan/tdb/test/jenkins-be-hash.tdb b/ccan/tdb/test/jenkins-be-hash.tdb
deleted file mode 100644 (file)
index b652840..0000000
Binary files a/ccan/tdb/test/jenkins-be-hash.tdb and /dev/null differ
diff --git a/ccan/tdb/test/jenkins-le-hash.tdb b/ccan/tdb/test/jenkins-le-hash.tdb
deleted file mode 100644 (file)
index 007e0a3..0000000
Binary files a/ccan/tdb/test/jenkins-le-hash.tdb and /dev/null differ
diff --git a/ccan/tdb/test/lock-tracking.c b/ccan/tdb/test/lock-tracking.c
deleted file mode 100644 (file)
index 8e8bb99..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* We save the locks so we can reaquire them. */
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ccan/tap/tap.h>
-#include <ccan/tdb/tdb_private.h>
-#include "lock-tracking.h"
-
-struct lock {
-       struct lock *next;
-       unsigned int off;
-       unsigned int len;
-       int type;
-};
-static struct lock *locks;
-int locking_errors = 0;
-bool suppress_lockcheck = false;
-bool nonblocking_locks;
-int locking_would_block = 0;
-void (*unlock_callback)(int fd);
-
-int fcntl_with_lockcheck(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_locks) {
-               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_block++;
-       }
-
-       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_lockcheck) {
-                       diag("Unknown unlock %u@%u - %i",
-                            (int)fl->l_len, (int)fl->l_start, ret);
-                       locking_errors++;
-               }
-       } 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 == FREELIST_TOP
-                           && fl->l_start == 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",
-                                    (int)fl->l_len, (int)fl->l_start,
-                                    i->len, (int)i->off);
-                               locking_errors++;
-                       }
-               }
-
-               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_callback)
-               unlock_callback(fd);
-       return ret;
-}
-
-unsigned int forget_locking(void)
-{
-       unsigned int num = 0;
-       while (locks) {
-               struct lock *next = locks->next;
-               free(locks);
-               locks = next;
-               num++;
-       }
-       return num;
-}
diff --git a/ccan/tdb/test/lock-tracking.h b/ccan/tdb/test/lock-tracking.h
deleted file mode 100644 (file)
index f2c9c44..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef LOCK_TRACKING_H
-#define LOCK_TRACKING_H
-#include <stdbool.h>
-
-/* Set this if you want a callback after fnctl unlock. */
-extern void (*unlock_callback)(int fd);
-
-/* Replacement fcntl. */
-int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ );
-
-/* Discard locking info: returns number of locks outstanding. */
-unsigned int forget_locking(void);
-
-/* Number of errors in locking. */
-extern int locking_errors;
-
-/* Suppress lock checking. */
-extern bool suppress_lockcheck;
-
-/* Make all locks non-blocking. */
-extern bool nonblocking_locks;
-
-/* Number of times we failed a lock because we made it non-blocking. */
-extern int locking_would_block;
-#endif /* LOCK_TRACKING_H */
diff --git a/ccan/tdb/test/logging.c b/ccan/tdb/test/logging.c
deleted file mode 100644 (file)
index ae598a9..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "logging.h"
-#include <ccan/tap/tap.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-bool suppress_logging = false;
-const char *log_prefix = "";
-
-/* Turn log messages into tap diag messages. */
-static void taplog(struct tdb_context *tdb,
-                  enum tdb_debug_level level,
-                  const char *fmt, ...)
-{
-       va_list ap;
-       char line[200];
-
-       if (suppress_logging)
-               return;
-
-       va_start(ap, fmt);
-       vsprintf(line, fmt, ap);
-       va_end(ap);
-
-       /* Strip trailing \n: diag adds it. */
-       if (line[0] && line[strlen(line)-1] == '\n')
-               diag("%s%.*s", log_prefix, (unsigned)strlen(line)-1, line);
-       else
-               diag("%s%s", log_prefix, line);
-}
-
-struct tdb_logging_context taplogctx = { taplog, NULL };
diff --git a/ccan/tdb/test/logging.h b/ccan/tdb/test/logging.h
deleted file mode 100644 (file)
index 6745a32..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef TDB_TEST_LOGGING_H
-#define TDB_TEST_LOGGING_H
-#include <ccan/tdb/tdb.h>
-#include <stdbool.h>
-
-extern bool suppress_logging;
-extern const char *log_prefix;
-extern struct tdb_logging_context taplogctx;
-
-#endif /* TDB_TEST_LOGGING_H */
diff --git a/ccan/tdb/test/old-nohash-be.tdb b/ccan/tdb/test/old-nohash-be.tdb
deleted file mode 100644 (file)
index 1c49116..0000000
Binary files a/ccan/tdb/test/old-nohash-be.tdb and /dev/null differ
diff --git a/ccan/tdb/test/old-nohash-le.tdb b/ccan/tdb/test/old-nohash-le.tdb
deleted file mode 100644 (file)
index 0655072..0000000
Binary files a/ccan/tdb/test/old-nohash-le.tdb and /dev/null differ
diff --git a/ccan/tdb/test/run-3G-file.c b/ccan/tdb/test/run-3G-file.c
deleted file mode 100644 (file)
index d56aed5..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* We need this otherwise fcntl locking fails. */
-#define _FILE_OFFSET_BITS 64
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-static int tdb_expand_file_sparse(struct tdb_context *tdb,
-                                 tdb_off_t size,
-                                 tdb_off_t addition)
-{
-       if (tdb->read_only || tdb->traverse_read) {
-               tdb->ecode = TDB_ERR_RDONLY;
-               return -1;
-       }
-
-       if (ftruncate(tdb->fd, size+addition) == -1) {
-               char b = 0;
-               ssize_t written = pwrite(tdb->fd,  &b, 1, (size+addition) - 1);
-               if (written == 0) {
-                       /* try once more, potentially revealing errno */
-                       written = pwrite(tdb->fd,  &b, 1, (size+addition) - 1);
-               }
-               if (written == 0) {
-                       /* again - give up, guessing errno */
-                       errno = ENOSPC;
-               }
-               if (written != 1) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", 
-                                size+addition, strerror(errno)));
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static const struct tdb_methods large_io_methods = {
-       tdb_read,
-       tdb_write,
-       tdb_next_hash_chain,
-       tdb_oob,
-       tdb_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;
-       tdb_off_t rec_ptr;
-       struct tdb_record rec;
-
-       plan_tests(24);
-       tdb = tdb_open_ex("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       ok1(tdb);
-       tdb->methods = &large_io_methods;
-
-       /* Enlarge the file (internally multiplies by 100). */
-       ok1(tdb_expand(tdb, 30000000) == 0);
-
-       /* Put an entry in, and check it. */
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       orig_data.dsize = strlen("world");
-       orig_data.dptr = (void *)"world";
-
-       ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0);
-
-       data = tdb_fetch(tdb, key);
-       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_fn(&key);
-       rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec);
-       ok1(rec_ptr);
-       ok1(rec_ptr > 2U*1024*1024*1024);
-       tdb_unlock(tdb, 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) == 0);
-
-       ok1(tdb_traverse(tdb, test_traverse, NULL) == 0);
-
-       /* Transactions should work. */
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0);
-
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == strlen("world"));
-       ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
-       free(data.dptr);
-       ok1(tdb_transaction_commit(tdb) == 0);
-
-       ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-bad-tdb-header.c b/ccan/tdb/test/run-bad-tdb-header.c
deleted file mode 100644 (file)
index 330381b..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       struct tdb_header hdr;
-       int fd;
-
-       plan_tests(11);
-       /* Can open fine if complete crap, as long as O_CREAT. */
-       fd = open("run-bad-tdb-header.tdb", O_RDWR|O_CREAT|O_TRUNC, 0600);
-       ok1(fd >= 0);
-       ok1(write(fd, "hello world", 11) == 11);
-       close(fd);
-       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(!tdb);
-       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR,
-                         0600, &taplogctx, NULL);
-       ok1(tdb);
-       tdb_close(tdb);
-
-       /* Now, with wrong version it should *not* overwrite. */
-       fd = open("run-bad-tdb-header.tdb", O_RDWR);
-       ok1(fd >= 0);
-       ok1(read(fd, &hdr, sizeof(hdr)) == sizeof(hdr));
-       ok1(hdr.version == TDB_VERSION);
-       hdr.version++;
-       lseek(fd, 0, SEEK_SET);
-       ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr));
-       close(fd);
-
-       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT,
-                         0600, &taplogctx, NULL);
-       ok1(errno == EIO);
-       ok1(!tdb);
-
-       /* With truncate, will be fine. */
-       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0,
-                         O_RDWR|O_CREAT|O_TRUNC, 0600, &taplogctx, NULL);
-       ok1(tdb);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-check.c b/ccan/tdb/test/run-check.c
deleted file mode 100644 (file)
index f96647b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(13);
-       tdb = tdb_open_ex("run-check.tdb", 1, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dsize = strlen("world");
-       data.dptr = (void *)"world";
-
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("run-check.tdb", 1024, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == -1);
-       ok1(tdb_error(tdb) == TDB_ERR_CORRUPT);
-       tdb_close(tdb);
-
-       /* Big and little endian should work! */
-       tdb = tdb_open_ex("test/old-nohash-le.tdb", 1024, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("test/old-nohash-be.tdb", 1024, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-corrupt.c b/ccan/tdb/test/run-corrupt.c
deleted file mode 100644 (file)
index 6f753ea..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.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 tdb_flip_bit(struct tdb_context *tdb, unsigned int bit)
-{
-       unsigned int off = bit / CHAR_BIT;
-       unsigned char mask = (1 << (bit % CHAR_BIT));
-
-       if (tdb->map_ptr)
-               ((unsigned char *)tdb->map_ptr)[off] ^= mask;
-       else {
-               unsigned char c;
-               if (pread(tdb->fd, &c, 1, off) != 1)
-                       err(1, "pread");
-               c ^= mask;
-               if (pwrite(tdb->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) == 0);
-       
-       key.dptr = (void *)"hello";
-       data.dsize = strlen("world");
-       data.dptr = (void *)"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) != 0)
-                       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(tdb_off_t)
-               + 2 * sizeof(uint32_t);
-       /* From the free list chain and hash chains. */
-       verifiable += 3 * sizeof(tdb_off_t);
-       /* From the record headers & tailer */
-       verifiable += 5 * (sizeof(struct tdb_record) + sizeof(uint32_t));
-       /* The free block: we ignore datalen, keylen, full_hash. */
-       verifiable += sizeof(struct tdb_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->map_size * CHAR_BIT; i++) {
-               tdb_flip_bit(tdb, i);
-               memset(sizes, 0, sizeof(sizes));
-               if (tdb_check(tdb, check, sizes) != 0)
-                       corrupt++;
-               else if (sizes[0] != ksize || sizes[1] != dsize)
-                       corrupt++;
-               tdb_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;
-
-       plan_tests(4);
-       /* This should use mmap. */
-       tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       if (!tdb)
-               abort();
-       check_test(tdb);
-       tdb_close(tdb);
-
-       /* This should not. */
-       tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       if (!tdb)
-               abort();
-       check_test(tdb);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-die-during-transaction.c b/ccan/tdb/test/run-die-during-transaction.c
deleted file mode 100644 (file)
index aa6b40f..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <unistd.h>
-#include "lock-tracking.h"
-static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset);
-static ssize_t write_check(int fd, const void *buf, size_t count);
-static int ftruncate_check(int fd, off_t length);
-
-#define pwrite pwrite_check
-#define write write_check
-#define fcntl fcntl_with_lockcheck
-#define ftruncate ftruncate_check
-
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <err.h>
-#include <setjmp.h>
-#include "external-agent.h"
-#include "logging.h"
-
-#undef write
-#undef pwrite
-#undef fcntl
-#undef ftruncate
-
-static bool in_transaction;
-static int target, current;
-static jmp_buf jmpbuf;
-#define TEST_DBNAME "run-die-during-transaction.tdb"
-#define KEY_STRING "helloworld"
-
-static void maybe_die(int fd)
-{
-       if (in_transaction && current++ == target) {
-               longjmp(jmpbuf, 1);
-       }
-}
-
-static ssize_t pwrite_check(int fd,
-                           const void *buf, size_t count, off_t offset)
-{
-       ssize_t ret;
-
-       maybe_die(fd);
-
-       ret = pwrite(fd, buf, count, offset);
-       if (ret != count)
-               return ret;
-
-       maybe_die(fd);
-       return ret;
-}
-
-static ssize_t write_check(int fd, const void *buf, size_t count)
-{
-       ssize_t ret;
-
-       maybe_die(fd);
-
-       ret = write(fd, buf, count);
-       if (ret != count)
-               return ret;
-
-       maybe_die(fd);
-       return ret;
-}
-
-static int ftruncate_check(int fd, off_t length)
-{
-       int ret;
-
-       maybe_die(fd);
-
-       ret = ftruncate(fd, length);
-
-       maybe_die(fd);
-       return ret;
-}
-
-static bool test_death(enum operation op, struct agent *agent)
-{
-       struct tdb_context *tdb = NULL;
-       TDB_DATA key;
-       enum agent_return ret;
-       int needed_recovery = 0;
-
-       current = target = 0;
-reset:
-       unlink(TEST_DBNAME);
-       tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       if (setjmp(jmpbuf) != 0) {
-               /* We're partway through.  Simulate our death. */
-               close(tdb->fd);
-               forget_locking();
-               in_transaction = false;
-
-               ret = external_agent_operation(agent, NEEDS_RECOVERY, "");
-               if (ret == SUCCESS)
-                       needed_recovery++;
-               else if (ret != FAILED) {
-                       diag("Step %u agent NEEDS_RECOVERY = %s", current,
-                            agent_return_name(ret));
-                       return false;
-               }
-
-               ret = external_agent_operation(agent, op, KEY_STRING);
-               if (ret != SUCCESS) {
-                       diag("Step %u op %s failed = %s", current,
-                            operation_name(op),
-                            agent_return_name(ret));
-                       return false;
-               }
-
-               ret = external_agent_operation(agent, NEEDS_RECOVERY, "");
-               if (ret != FAILED) {
-                       diag("Still needs recovery after step %u = %s",
-                            current, agent_return_name(ret));
-                       return false;
-               }
-
-               ret = external_agent_operation(agent, CHECK, "");
-               if (ret != SUCCESS) {
-                       diag("Step %u check failed = %s", current,
-                            agent_return_name(ret));
-                       return false;
-               }
-
-               ret = external_agent_operation(agent, CLOSE, "");
-               if (ret != SUCCESS) {
-                       diag("Step %u close failed = %s", current,
-                            agent_return_name(ret));
-                       return false;
-               }
-
-               /* Suppress logging as this tries to use closed fd. */
-               suppress_logging = true;
-               suppress_lockcheck = true;
-               tdb_close(tdb);
-               suppress_logging = false;
-               suppress_lockcheck = false;
-               target++;
-               current = 0;
-               goto reset;
-       }
-
-       /* Put key for agent to fetch. */
-       key.dsize = strlen(KEY_STRING);
-       key.dptr = (void *)KEY_STRING;
-       if (tdb_store(tdb, key, key, TDB_INSERT) != 0)
-               return false;
-
-       /* This is the key we insert in transaction. */
-       key.dsize--;
-
-       ret = external_agent_operation(agent, OPEN, TEST_DBNAME);
-       if (ret != SUCCESS)
-               errx(1, "Agent failed to open: %s", agent_return_name(ret));
-
-       ret = external_agent_operation(agent, FETCH, KEY_STRING);
-       if (ret != SUCCESS)
-               errx(1, "Agent failed find key: %s", agent_return_name(ret));
-
-       in_transaction = true;
-       if (tdb_transaction_start(tdb) != 0)
-               return false;
-
-       if (tdb_store(tdb, key, key, TDB_INSERT) != 0)
-               return false;
-
-       if (tdb_transaction_commit(tdb) != 0)
-               return false;
-
-       in_transaction = false;
-
-       /* We made it! */
-       diag("Completed %u runs", current);
-       tdb_close(tdb);
-       ret = external_agent_operation(agent, CLOSE, "");
-       if (ret != SUCCESS) {
-               diag("Step %u close failed = %s", current,
-                    agent_return_name(ret));
-               return false;
-       }
-
-       ok1(needed_recovery);
-       ok1(locking_errors == 0);
-       ok1(forget_locking() == 0);
-       locking_errors = 0;
-       return true;
-}
-
-int main(int argc, char *argv[])
-{
-       enum operation ops[] = { FETCH, STORE, TRANSACTION_START };
-       struct agent *agent;
-       int i;
-
-       plan_tests(12);
-       unlock_callback = maybe_die;
-
-       agent = prepare_external_agent();
-       if (!agent)
-               err(1, "preparing agent");
-
-       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));
-       }
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-endian.c b/ccan/tdb/test/run-endian.c
deleted file mode 100644 (file)
index 0fae162..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(13);
-       tdb = tdb_open_ex("run-endian.tdb", 1024,
-                         TDB_CLEAR_IF_FIRST|TDB_CONVERT,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       ok1(tdb);
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dsize = strlen("world");
-       data.dptr = (void *)"world";
-
-       ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0);
-       ok1(tdb_error(tdb) == TDB_ERR_NOEXIST);
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0);
-       ok1(tdb_error(tdb) == TDB_ERR_EXISTS);
-       ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0);
-
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == strlen("world"));
-       ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
-       free(data.dptr);
-
-       key.dsize++;
-       data = tdb_fetch(tdb, key);
-       ok1(data.dptr == NULL);
-       tdb_close(tdb);
-
-       /* Reopen: should read it */
-       tdb = tdb_open_ex("run-endian.tdb", 1024, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data = tdb_fetch(tdb, key);
-       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/ccan/tdb/test/run-incompatible.c b/ccan/tdb/test/run-incompatible.c
deleted file mode 100644 (file)
index 339d403..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-
-static unsigned int tdb_dumb_hash(TDB_DATA *key)
-{
-       return key->dsize;
-}
-
-static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
-{
-       unsigned int *count = tdb_get_logging_private(tdb);
-       if (strstr(fmt, "hash"))
-               (*count)++;
-}
-
-static unsigned int hdr_rwlocks(const char *fname)
-{
-       struct tdb_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;
-}
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       unsigned int log_count, flags;
-       TDB_DATA d, r;
-       struct tdb_logging_context log_ctx = { log_fn, &log_count };
-
-       plan_tests(38 * 2);
-
-       for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) {
-               unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC;
-
-               if (flags & TDB_CONVERT)
-                       tdb_convert(&rwmagic, sizeof(rwmagic));
-
-               /* Create an old-style hash. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0, flags,
-                                 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
-                                 NULL);
-               ok1(tdb);
-               ok1(log_count == 0);
-               d.dptr = (void *)"Hello";
-               d.dsize = 5;
-               ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
-               tdb_close(tdb);
-
-               /* Should not have marked rwlocks field. */
-               ok1(hdr_rwlocks("run-incompatible.tdb") == 0);
-
-               /* We can still open any old-style with incompat flag. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0,
-                                 TDB_INCOMPATIBLE_HASH,
-                                 O_RDWR, 0600, &log_ctx, NULL);
-               ok1(tdb);
-               ok1(log_count == 0);
-               r = tdb_fetch(tdb, d);
-               ok1(r.dsize == 5);
-               free(r.dptr);
-               ok1(tdb_check(tdb, NULL, NULL) == 0);
-               tdb_close(tdb);
-
-               log_count = 0;
-               tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY,
-                                 0, &log_ctx, tdb_jenkins_hash);
-               ok1(tdb);
-               ok1(log_count == 0);
-               ok1(tdb_check(tdb, NULL, NULL) == 0);
-               tdb_close(tdb);
-
-               log_count = 0;
-               tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY,
-                                 0, &log_ctx, tdb_jenkins_hash);
-               ok1(tdb);
-               ok1(log_count == 0);
-               ok1(tdb_check(tdb, NULL, NULL) == 0);
-               tdb_close(tdb);
-
-               /* OK, now create with incompatible flag, default hash. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0,
-                                 flags|TDB_INCOMPATIBLE_HASH,
-                                 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
-                                 NULL);
-               ok1(tdb);
-               ok1(log_count == 0);
-               d.dptr = (void *)"Hello";
-               d.dsize = 5;
-               ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
-               tdb_close(tdb);
-
-               /* Should have marked rwlocks field. */
-               ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
-
-               /* Cannot open with old hash. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
-                                 O_RDWR, 0600, &log_ctx, tdb_old_hash);
-               ok1(!tdb);
-               ok1(log_count == 1);
-
-               /* Can open with jenkins hash. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
-                                 O_RDWR, 0600, &log_ctx, tdb_jenkins_hash);
-               ok1(tdb);
-               ok1(log_count == 0);
-               r = tdb_fetch(tdb, d);
-               ok1(r.dsize == 5);
-               free(r.dptr);
-               ok1(tdb_check(tdb, NULL, NULL) == 0);
-               tdb_close(tdb);
-
-               /* Can open by letting it figure it out itself. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
-                                 O_RDWR, 0600, &log_ctx, NULL);
-               ok1(tdb);
-               ok1(log_count == 0);
-               r = tdb_fetch(tdb, d);
-               ok1(r.dsize == 5);
-               free(r.dptr);
-               ok1(tdb_check(tdb, NULL, NULL) == 0);
-               tdb_close(tdb);
-
-               /* We can also use incompatible hash with other hashes. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0,
-                                 flags|TDB_INCOMPATIBLE_HASH,
-                                 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
-                                 tdb_dumb_hash);
-               ok1(tdb);
-               ok1(log_count == 0);
-               d.dptr = (void *)"Hello";
-               d.dsize = 5;
-               ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
-               tdb_close(tdb);
-
-               /* Should have marked rwlocks field. */
-               ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
-
-               /* It should not open if we don't specify. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
-                                 &log_ctx, NULL);
-               ok1(!tdb);
-               ok1(log_count == 1);
-
-               /* Should reopen with correct hash. */
-               log_count = 0;
-               tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
-                                 &log_ctx, tdb_dumb_hash);
-               ok1(tdb);
-               ok1(log_count == 0);
-               r = tdb_fetch(tdb, d);
-               ok1(r.dsize == 5);
-               free(r.dptr);
-               ok1(tdb_check(tdb, NULL, NULL) == 0);
-               tdb_close(tdb);
-       }
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-nested-transactions.c b/ccan/tdb/test/run-nested-transactions.c
deleted file mode 100644 (file)
index d13977c..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(27);
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-
-       tdb = tdb_open_ex("run-nested-transactions.tdb",
-                         1024, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-       ok1(tdb);
-
-       /* No nesting by default. */
-       ok1(tdb_transaction_start(tdb) == 0);
-       data.dptr = (void *)"world";
-       data.dsize = strlen("world");
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == strlen("world"));
-       ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
-       free(data.dptr);
-       ok1(tdb_transaction_start(tdb) != 0);
-       ok1(tdb_error(tdb) == TDB_ERR_NESTING);
-
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == strlen("world"));
-       ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
-       free(data.dptr);
-       ok1(tdb_transaction_commit(tdb) == 0);
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == strlen("world"));
-       ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
-       free(data.dptr);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("run-nested-transactions.tdb",
-                         1024, TDB_ALLOW_NESTING, O_RDWR, 0, &taplogctx, NULL);
-       ok1(tdb);
-
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(tdb_delete(tdb, key) == 0);
-       ok1(tdb_transaction_commit(tdb) == 0);
-       ok1(!tdb_exists(tdb, key));
-       ok1(tdb_transaction_cancel(tdb) == 0);
-       /* Surprise! Kills inner "committed" transaction. */
-       ok1(tdb_exists(tdb, key));
-
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(tdb_delete(tdb, key) == 0);
-       ok1(tdb_transaction_commit(tdb) == 0);
-       ok1(!tdb_exists(tdb, key));
-       ok1(tdb_transaction_commit(tdb) == 0);
-       ok1(!tdb_exists(tdb, key));
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-nested-traverse.c b/ccan/tdb/test/run-nested-traverse.c
deleted file mode 100644 (file)
index c58b24c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include "lock-tracking.h"
-#define fcntl fcntl_with_lockcheck
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#undef fcntl
-#include <stdlib.h>
-#include <stdbool.h>
-#include <err.h>
-#include "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_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == WOULD_HAVE_BLOCKED);
-       tdb_traverse(tdb, traverse2, NULL);
-
-       /* That should *not* release the transaction lock! */
-       ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == WOULD_HAVE_BLOCKED);
-       return 0;
-}
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(17);
-       agent = prepare_external_agent();
-       if (!agent)
-               err(1, "preparing agent");
-
-       tdb = tdb_open_ex("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-       ok1(tdb);
-
-       ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS);
-       ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == SUCCESS);
-       ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb))
-           == SUCCESS);
-
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dptr = (void *)"world";
-       data.dsize = strlen("world");
-
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-       tdb_traverse(tdb, traverse1, NULL);
-       tdb_traverse_read(tdb, traverse1, NULL);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-no-lock-during-traverse.c b/ccan/tdb/test/run-no-lock-during-traverse.c
deleted file mode 100644 (file)
index df089f9..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <unistd.h>
-#include "lock-tracking.h"
-
-#define fcntl fcntl_with_lockcheck
-
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.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.dsize = strlen("world");
-               data.dptr = (void *)"world";
-
-               if (tdb_store(tdb, key, data, 0) != 0)
-                       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) == 0);
-       }
-}
-
-/* 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) != 0)
-               (*(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) == 0);
-       return 0;
-}
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       int errors = 0;
-
-       plan_tests(41);
-       tdb = tdb_open_ex("run-no-lock-during-traverse.tdb",
-                         1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR,
-                         0600, &taplogctx, NULL);
-
-       ok1(tdb);
-       ok1(prepare_entries(tdb));
-       ok1(locking_errors == 0);
-       ok1(tdb_lockall(tdb) == 0);
-       ok1(locking_errors == 0);
-       tdb_traverse(tdb, delete_other, &errors);
-       ok1(errors == 0);
-       ok1(locking_errors == 0);
-       ok1(tdb_unlockall(tdb) == 0);
-
-       ok1(prepare_entries(tdb));
-       ok1(locking_errors == 0);
-       ok1(tdb_lockall(tdb) == 0);
-       ok1(locking_errors == 0);
-       tdb_traverse(tdb, delete_self, NULL);
-       ok1(locking_errors == 0);
-       ok1(tdb_unlockall(tdb) == 0);
-
-       ok1(prepare_entries(tdb));
-       ok1(locking_errors == 0);
-       ok1(tdb_lockall(tdb) == 0);
-       ok1(locking_errors == 0);
-       delete_entries(tdb);
-       ok1(locking_errors == 0);
-       ok1(tdb_unlockall(tdb) == 0);
-
-       ok1(tdb_close(tdb) == 0);       
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-oldhash.c b/ccan/tdb/test/run-oldhash.c
deleted file mode 100644 (file)
index a40600f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-
-       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_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0,
-                         &taplogctx, NULL);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0,
-                         &taplogctx, tdb_jenkins_hash);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0,
-                         &taplogctx, tdb_jenkins_hash);
-       ok1(tdb);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-open-during-transaction.c b/ccan/tdb/test/run-open-during-transaction.c
deleted file mode 100644 (file)
index e7feb03..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <unistd.h>
-#include "lock-tracking.h"
-
-static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset);
-static ssize_t write_check(int fd, const void *buf, size_t count);
-static int ftruncate_check(int fd, off_t length);
-
-#define pwrite pwrite_check
-#define write write_check
-#define fcntl fcntl_with_lockcheck
-#define ftruncate ftruncate_check
-
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <err.h>
-#include "external-agent.h"
-#include "logging.h"
-
-static struct agent *agent;
-static bool opened;
-static int errors = 0;
-static bool clear_if_first;
-#define TEST_DBNAME "run-open-during-transaction.tdb"
-
-#undef write
-#undef pwrite
-#undef fcntl
-#undef ftruncate
-
-static bool is_same(const char *snapshot, const char *latest, off_t len)
-{
-       unsigned i;
-
-       for (i = 0; i < len; i++) {
-               if (snapshot[i] != latest[i])
-                       return false;
-       }
-       return true;
-}
-
-static bool compare_file(int fd, const char *snapshot, off_t snapshot_len)
-{
-       char *contents;
-       bool same;
-
-       /* over-length read serves as length check. */
-       contents = malloc(snapshot_len+1);
-       same = pread(fd, contents, snapshot_len+1, 0) == snapshot_len
-               && is_same(snapshot, contents, snapshot_len);
-       free(contents);
-       return same;
-}
-
-static void check_file_intact(int fd)
-{
-       enum agent_return ret;
-       struct stat st;
-       char *contents;
-
-       fstat(fd, &st);
-       contents = malloc(st.st_size);
-       if (pread(fd, contents, st.st_size, 0) != st.st_size) {
-               diag("Read fail");
-               errors++;
-               return;
-       }
-
-       /* Ask agent to open file. */
-       ret = external_agent_operation(agent, clear_if_first ?
-                                      OPEN_WITH_CLEAR_IF_FIRST :
-                                      OPEN,
-                                      TEST_DBNAME);
-
-       /* It's OK to open it, but it must not have changed! */
-       if (!compare_file(fd, contents, st.st_size)) {
-               diag("Agent changed file after opening %s",
-                    agent_return_name(ret));
-               errors++;
-       }
-
-       if (ret == SUCCESS) {
-               ret = external_agent_operation(agent, CLOSE, NULL);
-               if (ret != SUCCESS) {
-                       diag("Agent failed to close tdb: %s",
-                            agent_return_name(ret));
-                       errors++;
-               }
-       } else if (ret != WOULD_HAVE_BLOCKED) {
-               diag("Agent opening file gave %s",
-                    agent_return_name(ret));
-               errors++;
-       }
-
-       free(contents);
-}
-
-static void after_unlock(int fd)
-{
-       if (opened)
-               check_file_intact(fd);
-}
-       
-static ssize_t pwrite_check(int fd,
-                           const void *buf, size_t count, off_t offset)
-{
-       if (opened)
-               check_file_intact(fd);
-
-       return pwrite(fd, buf, count, offset);
-}
-
-static ssize_t write_check(int fd, const void *buf, size_t count)
-{
-       if (opened)
-               check_file_intact(fd);
-
-       return write(fd, buf, count);
-}
-
-static int ftruncate_check(int fd, off_t length)
-{
-       if (opened)
-               check_file_intact(fd);
-
-       return ftruncate(fd, length);
-
-}
-
-int main(int argc, char *argv[])
-{
-       const int flags[] = { TDB_DEFAULT,
-                             TDB_CLEAR_IF_FIRST,
-                             TDB_NOMMAP, 
-                             TDB_CLEAR_IF_FIRST | TDB_NOMMAP };
-       int i;
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(20);
-       agent = prepare_external_agent();
-       if (!agent)
-               err(1, "preparing agent");
-
-       unlock_callback = after_unlock;
-       for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) {
-               clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST);
-               diag("Test with %s and %s\n",
-                    clear_if_first ? "CLEAR" : "DEFAULT",
-                    (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap");
-               unlink(TEST_DBNAME);
-               tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i],
-                                 O_CREAT|O_TRUNC|O_RDWR, 0600,
-                                 &taplogctx, NULL);
-               ok1(tdb);
-
-               opened = true;
-               ok1(tdb_transaction_start(tdb) == 0);
-               key.dsize = strlen("hi");
-               key.dptr = (void *)"hi";
-               data.dptr = (void *)"world";
-               data.dsize = strlen("world");
-
-               ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-               ok1(tdb_transaction_commit(tdb) == 0);
-               ok(!errors, "We had %u open errors", errors);
-
-               opened = false;
-               tdb_close(tdb);
-       }
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-readonly-check.c b/ccan/tdb/test/run-readonly-check.c
deleted file mode 100644 (file)
index 6e92cde..0000000
+++ /dev/null
@@ -1,54 +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!). */
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(11);
-       tdb = tdb_open_ex("run-readonly-check.tdb", 1024,
-                         TDB_DEFAULT,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       ok1(tdb);
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dsize = strlen("world");
-       data.dptr = (void *)"world";
-
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-
-       /* We are also allowed to do a check inside a transaction. */
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       ok1(tdb_close(tdb) == 0);
-
-       tdb = tdb_open_ex("run-readonly-check.tdb", 1024,
-                         TDB_DEFAULT, O_RDONLY, 0, &taplogctx, NULL);
-
-       ok1(tdb);
-       ok1(tdb_store(tdb, key, data, TDB_MODIFY) == -1);
-       ok1(tdb_error(tdb) == TDB_ERR_RDONLY);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       ok1(tdb_close(tdb) == 0);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-rwlock-check.c b/ccan/tdb/test/run-rwlock-check.c
deleted file mode 100644 (file)
index aa8b471..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-
-static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
-{
-       unsigned int *count = tdb_get_logging_private(tdb);
-       if (strstr(fmt, "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;
-       struct tdb_logging_context log_ctx = { log_fn, &log_count };
-
-       plan_tests(4);
-
-       /* We should fail to open rwlock-using tdbs of either endian. */
-       log_count = 0;
-       tdb = tdb_open_ex("test/rwlock-le.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, NULL);
-       ok1(!tdb);
-       ok1(log_count == 1);
-
-       log_count = 0;
-       tdb = tdb_open_ex("test/rwlock-be.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, NULL);
-       ok1(!tdb);
-       ok1(log_count == 1);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-summary.c b/ccan/tdb/test/run-summary.c
deleted file mode 100644 (file)
index 89fbfec..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tdb/summary.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.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.tdb", 131, flags[i],
-                              O_RDWR|O_CREAT|O_TRUNC, 0600);
-               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) != 0)
-                               fail("Storing in tdb");
-               }
-
-               summary = tdb_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/ccan/tdb/test/run-transaction-expand.c b/ccan/tdb/test/run-transaction-expand.c
deleted file mode 100644 (file)
index 26426b2..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* We need this otherwise fcntl locking fails. */
-#define _FILE_OFFSET_BITS 64
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb_private.h>
-
-/* Speed up the tests: setting TDB_NOSYNC removed recovery altogether. */
-static inline int fake_fsync(int fd)
-{
-       return 0;
-}
-#define fsync fake_fsync
-
-#ifdef MS_SYNC
-static inline int fake_msync(void *addr, size_t length, int flags)
-{
-       return 0;
-}
-#define msync fake_msync
-#endif
-
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-static void write_record(struct tdb_context *tdb, size_t extra_len,
-                        TDB_DATA *data)
-{
-       TDB_DATA key;
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-
-       data->dsize += extra_len;
-       tdb_transaction_start(tdb);
-       tdb_store(tdb, key, *data, TDB_REPLACE);
-       tdb_transaction_commit(tdb);
-}
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       size_t i;
-       TDB_DATA data;
-       struct tdb_record rec;
-       tdb_off_t off;
-
-       plan_tests(4);
-       tdb = tdb_open_ex("run-transaction-expand.tdb",
-                         1024, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-       ok1(tdb);
-
-       data.dsize = 0;
-       data.dptr = calloc(1000, getpagesize());
-
-       /* Simulate a slowly growing record. */
-       for (i = 0; i < 1000; i++)
-               write_record(tdb, getpagesize(), &data);
-
-       tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off);
-       tdb_read(tdb, off, &rec, sizeof(rec), DOCONV());
-       diag("TDB size = %zu, recovery = %u-%u",
-            (size_t)tdb->map_size, off, off + sizeof(rec) + rec.rec_len);
-
-       /* We should only be about 5 times larger than largest record. */
-       ok1(tdb->map_size < 6 * i * getpagesize());
-       tdb_close(tdb);
-
-       tdb = tdb_open_ex("run-transaction-expand.tdb",
-                         1024, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-       ok1(tdb);
-
-       data.dsize = 0;
-
-       /* Simulate a slowly growing record, repacking to keep
-        * recovery area at end. */
-       for (i = 0; i < 1000; i++) {
-               write_record(tdb, getpagesize(), &data);
-               if (i % 10 == 0)
-                       tdb_repack(tdb);
-       }
-
-       tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off);
-       tdb_read(tdb, off, &rec, sizeof(rec), DOCONV());
-       diag("TDB size = %zu, recovery = %u-%u",
-            (size_t)tdb->map_size, off, off + sizeof(rec) + rec.rec_len);
-
-       /* We should only be about 4 times larger than largest record. */
-       ok1(tdb->map_size < 5 * i * getpagesize());
-       tdb_close(tdb);
-       free(data.dptr);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-traverse-in-transaction.c b/ccan/tdb/test/run-traverse-in-transaction.c
deleted file mode 100644 (file)
index 61cb131..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include "lock-tracking.h"
-#define fcntl fcntl_with_lockcheck
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#undef fcntl_with_lockcheck
-#include <stdlib.h>
-#include <stdbool.h>
-#include <err.h>
-#include "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;
-
-       plan_tests(13);
-       agent = prepare_external_agent();
-       if (!agent)
-               err(1, "preparing agent");
-
-       tdb = tdb_open_ex("run-traverse-in-transaction.tdb",
-                         1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR,
-                         0600, &taplogctx, NULL);
-       ok1(tdb);
-
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dptr = (void *)"world";
-       data.dsize = strlen("world");
-
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-
-       ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS);
-
-       ok1(tdb_transaction_start(tdb) == 0);
-       ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == WOULD_HAVE_BLOCKED);
-       tdb_traverse(tdb, traverse, NULL);
-
-       /* That should *not* release the transaction lock! */
-       ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == WOULD_HAVE_BLOCKED);
-       tdb_traverse_read(tdb, traverse, NULL);
-
-       /* That should *not* release the transaction lock! */
-       ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == WOULD_HAVE_BLOCKED);
-       ok1(tdb_transaction_commit(tdb) == 0);
-       /* Now we should be fine. */
-       ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
-           == SUCCESS);
-
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-wronghash-fail.c b/ccan/tdb/test/run-wronghash-fail.c
deleted file mode 100644 (file)
index 17fd867..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-
-static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
-{
-       unsigned int *count = tdb_get_logging_private(tdb);
-       if (strstr(fmt, "hash"))
-               (*count)++;
-}
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       unsigned int log_count;
-       TDB_DATA d;
-       struct tdb_logging_context log_ctx = { log_fn, &log_count };
-
-       plan_tests(28);
-
-       /* Create with default hash. */
-       log_count = 0;
-       tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0,
-                         O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL);
-       ok1(tdb);
-       ok1(log_count == 0);
-       d.dptr = (void *)"Hello";
-       d.dsize = 5;
-       ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
-       tdb_close(tdb);
-
-       /* Fail to open with different hash. */
-       tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, tdb_jenkins_hash);
-       ok1(!tdb);
-       ok1(log_count == 1);
-
-       /* Create with different hash. */
-       log_count = 0;
-       tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0,
-                         O_CREAT|O_RDWR|O_TRUNC,
-                         0600, &log_ctx, tdb_jenkins_hash);
-       ok1(tdb);
-       ok1(log_count == 0);
-       tdb_close(tdb);
-
-       /* Endian should be no problem. */
-       log_count = 0;
-       tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, tdb_old_hash);
-       ok1(!tdb);
-       ok1(log_count == 1);
-
-       log_count = 0;
-       tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, tdb_old_hash);
-       ok1(!tdb);
-       ok1(log_count == 1);
-
-       log_count = 0;
-       /* Fail to open with old default hash. */
-       tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, tdb_old_hash);
-       ok1(!tdb);
-       ok1(log_count == 1);
-
-       log_count = 0;
-       tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY,
-                         0, &log_ctx, tdb_jenkins_hash);
-       ok1(tdb);
-       ok1(log_count == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       log_count = 0;
-       tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY,
-                         0, &log_ctx, tdb_jenkins_hash);
-       ok1(tdb);
-       ok1(log_count == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       /* It should open with jenkins hash if we don't specify. */
-       log_count = 0;
-       tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, NULL);
-       ok1(tdb);
-       ok1(log_count == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       log_count = 0;
-       tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0,
-                         &log_ctx, NULL);
-       ok1(tdb);
-       ok1(log_count == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-       log_count = 0;
-       tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDONLY,
-                         0, &log_ctx, NULL);
-       ok1(tdb);
-       ok1(log_count == 0);
-       ok1(tdb_check(tdb, NULL, NULL) == 0);
-       tdb_close(tdb);
-
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run-zero-append.c b/ccan/tdb/test/run-zero-append.c
deleted file mode 100644 (file)
index a869adc..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(4);
-       tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR,
-                         0600, &taplogctx, NULL);
-       ok1(tdb);
-
-       /* Tickle bug on appending zero length buffer to zero length buffer. */
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dptr = (void *)"world";
-       data.dsize = 0;
-
-       ok1(tdb_append(tdb, key, data) == 0);
-       ok1(tdb_append(tdb, key, data) == 0);
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == 0);
-       tdb_close(tdb);
-       free(data.dptr);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/run.c b/ccan/tdb/test/run.c
deleted file mode 100644 (file)
index 6ef3c4d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ccan/tdb/tdb.h>
-#include <ccan/tdb/io.c>
-#include <ccan/tdb/tdb.c>
-#include <ccan/tdb/lock.c>
-#include <ccan/tdb/freelist.c>
-#include <ccan/tdb/traverse.c>
-#include <ccan/tdb/transaction.c>
-#include <ccan/tdb/error.c>
-#include <ccan/tdb/open.c>
-#include <ccan/tdb/check.c>
-#include <ccan/tdb/hash.c>
-#include <ccan/tap/tap.h>
-#include <stdlib.h>
-#include <err.h>
-#include "logging.h"
-
-int main(int argc, char *argv[])
-{
-       struct tdb_context *tdb;
-       TDB_DATA key, data;
-
-       plan_tests(10);
-       tdb = tdb_open_ex("run.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
-
-       ok1(tdb);
-       key.dsize = strlen("hi");
-       key.dptr = (void *)"hi";
-       data.dsize = strlen("world");
-       data.dptr = (void *)"world";
-
-       ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0);
-       ok1(tdb_error(tdb) == TDB_ERR_NOEXIST);
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
-       ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0);
-       ok1(tdb_error(tdb) == TDB_ERR_EXISTS);
-       ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0);
-
-       data = tdb_fetch(tdb, key);
-       ok1(data.dsize == strlen("world"));
-       ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
-       free(data.dptr);
-
-       key.dsize++;
-       data = tdb_fetch(tdb, key);
-       ok1(data.dptr == NULL);
-       tdb_close(tdb);
-
-       return exit_status();
-}
diff --git a/ccan/tdb/test/rwlock-be.tdb b/ccan/tdb/test/rwlock-be.tdb
deleted file mode 100644 (file)
index 45b5f09..0000000
Binary files a/ccan/tdb/test/rwlock-be.tdb and /dev/null differ
diff --git a/ccan/tdb/test/rwlock-le.tdb b/ccan/tdb/test/rwlock-le.tdb
deleted file mode 100644 (file)
index 45b5f09..0000000
Binary files a/ccan/tdb/test/rwlock-le.tdb and /dev/null differ
diff --git a/ccan/tdb/test/tdb.corrupt b/ccan/tdb/test/tdb.corrupt
deleted file mode 100644 (file)
index 83d6677..0000000
Binary files a/ccan/tdb/test/tdb.corrupt and /dev/null differ
diff --git a/ccan/tdb/tools/Makefile b/ccan/tdb/tools/Makefile
deleted file mode 100644 (file)
index 6ba6f99..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-LDLIBS:=../../tdb.o ../../tally.o
-CFLAGS:=-I../../.. -Wall -O3 #-g -pg
-LDFLAGS:=-L../../..
-
-default: replay_trace tdbtorture tdbdump tdbtool starvation mktdb speed
-
-benchmark: replay_trace
-       @trap "rm -f /tmp/trace.$$$$" 0; for f in benchmarks/*.rz; do if runzip -k $$f -o /tmp/trace.$$$$ && echo -n "$$f": && ./replay_trace --quiet -n 5 replay.tdb /tmp/trace.$$$$ && rm /tmp/trace.$$$$; then rm -f /tmp/trace.$$$$; else exit 1; fi; done
-
-REPLAY_LIBS=$(LDLIBS) ../../str_talloc.o ../../grab_file.o  ../../talloc.o ../../noerr.o
-replay_trace: replay_trace.c keywords.c $(REPLAY_LIBS)
-       $(LINK.c) $< $(LOADLIBES) $(REPLAY_LIBS) -o $@
-
-keywords.c: keywords.gperf
-       gperf $< > $@
-
-check: replay_trace
-       @rm -f *.reduced_trace
-       @set -e; for f in tests/*.trace.tar.bz2; do             \
-               tar xvfj $$f;                                   \
-               ./replay_trace replay.tdb *.reduced_trace;      \
-               rm -f *.reduced_trace;                          \
-       done
-
-# Usage: make mytest.trace.tar.bz2 TRACEFILES=*.trace
-%.trace.tar.bz2: $(patsubst %.trace,%.reduced_trace,$(wildcard $(TRACEFILES)))
-       tar cvfj $@ $^
-
-%.reduced_trace: %.trace
-       @sed 's/\(^[0-9]* traverse\) .*/\1fn/' < $^ > $@
-
-clean:
-       rm -f replay_trace tdbtorture tdbdump tdbtool speed *.o
diff --git a/ccan/tdb/tools/benchmarks/configuration.ldb.trace.19774.rz b/ccan/tdb/tools/benchmarks/configuration.ldb.trace.19774.rz
deleted file mode 100644 (file)
index 6225079..0000000
Binary files a/ccan/tdb/tools/benchmarks/configuration.ldb.trace.19774.rz and /dev/null differ
diff --git a/ccan/tdb/tools/benchmarks/sam.ldb.trace.19774.rz b/ccan/tdb/tools/benchmarks/sam.ldb.trace.19774.rz
deleted file mode 100644 (file)
index 24a45d9..0000000
Binary files a/ccan/tdb/tools/benchmarks/sam.ldb.trace.19774.rz and /dev/null differ
diff --git a/ccan/tdb/tools/benchmarks/schema.ldb.trace.19774.rz b/ccan/tdb/tools/benchmarks/schema.ldb.trace.19774.rz
deleted file mode 100644 (file)
index f44bb0a..0000000
Binary files a/ccan/tdb/tools/benchmarks/schema.ldb.trace.19774.rz and /dev/null differ
diff --git a/ccan/tdb/tools/benchmarks/templates.ldb.trace.19774.rz b/ccan/tdb/tools/benchmarks/templates.ldb.trace.19774.rz
deleted file mode 100644 (file)
index bad0796..0000000
Binary files a/ccan/tdb/tools/benchmarks/templates.ldb.trace.19774.rz and /dev/null differ
diff --git a/ccan/tdb/tools/benchmarks/users.ldb.trace.19774.rz b/ccan/tdb/tools/benchmarks/users.ldb.trace.19774.rz
deleted file mode 100644 (file)
index e08ed0d..0000000
Binary files a/ccan/tdb/tools/benchmarks/users.ldb.trace.19774.rz and /dev/null differ
diff --git a/ccan/tdb/tools/keywords.c b/ccan/tdb/tools/keywords.c
deleted file mode 100644 (file)
index a238d5f..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/* ANSI-C code produced by gperf version 3.0.3 */
-/* Command-line: gperf keywords.gperf  */
-/* Computed positions: -k'5,$' */
-
-#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
-      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
-      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
-      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
-      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
-      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
-      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
-      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
-      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
-      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
-      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
-      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
-      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
-      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
-      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
-      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
-      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
-      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
-      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
-      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
-      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
-      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
-      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
-/* The character set is not based on ISO-646.  */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
-#endif
-
-#line 1 "keywords.gperf"
-
-#line 4 "keywords.gperf"
-struct op_table {
-       const char *name;
-       enum op_type type;
-       void (*enhance_op)(char *filename[], struct op op[],
-                          unsigned file, unsigned op_num, char *words[]);
-};
-/* maximum key range = 53, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static unsigned int
-hash_keyword (register const char *str, register unsigned int len)
-{
-  static const unsigned char asso_values[] =
-    {
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 45, 61, 30,
-       5,  0,  0,  5,  5, 61, 61,  0,  0,  0,
-      20, 61, 20, 61, 25,  0,  5,  0, 61,  0,
-      61,  5, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
-      61, 61, 61, 61, 61, 61
-    };
-  return len + asso_values[(unsigned char)str[4]] + asso_values[(unsigned char)str[len - 1]];
-}
-
-#ifdef __GNUC__
-__inline
-#ifdef __GNUC_STDC_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-const struct op_table *
-find_keyword (register const char *str, register unsigned int len)
-{
-  enum
-    {
-      TOTAL_KEYWORDS = 35,
-      MIN_WORD_LENGTH = 8,
-      MAX_WORD_LENGTH = 30,
-      MIN_HASH_VALUE = 8,
-      MAX_HASH_VALUE = 60
-    };
-
-  static const struct op_table wordlist[] =
-    {
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-#line 44 "keywords.gperf"
-      {"traverse", OP_TDB_TRAVERSE, op_add_traverse,},
-#line 33 "keywords.gperf"
-      {"tdb_store", OP_TDB_STORE, op_add_store,},
-#line 32 "keywords.gperf"
-      {"tdb_exists", OP_TDB_EXISTS, op_add_key_ret,},
-#line 16 "keywords.gperf"
-      {"tdb_lockall", OP_TDB_LOCKALL, op_add_nothing,},
-#line 36 "keywords.gperf"
-      {"tdb_wipe_all", OP_TDB_WIPE_ALL, op_add_wipe_all,},
-#line 20 "keywords.gperf"
-      {"tdb_unlockall", OP_TDB_UNLOCKALL, op_add_nothing,},
-#line 48 "keywords.gperf"
-      {"tdb_fetch", OP_TDB_FETCH, op_add_key_data,},
-#line 49 "keywords.gperf"
-      {"tdb_delete", OP_TDB_DELETE, op_add_key_ret,},
-#line 17 "keywords.gperf"
-      {"tdb_lockall_mark", OP_TDB_LOCKALL_MARK, op_add_nothing,},
-#line 46 "keywords.gperf"
-      {"tdb_firstkey", OP_TDB_FIRSTKEY, op_add_key,},
-#line 18 "keywords.gperf"
-      {"tdb_lockall_unmark", OP_TDB_LOCKALL_UNMARK, op_add_nothing,},
-#line 35 "keywords.gperf"
-      {"tdb_get_seqnum", OP_TDB_GET_SEQNUM, op_add_seqnum,},
-#line 19 "keywords.gperf"
-      {"tdb_lockall_nonblock", OP_TDB_LOCKALL_NONBLOCK, op_add_nothing,},
-#line 21 "keywords.gperf"
-      {"tdb_lockall_read", OP_TDB_LOCKALL_READ, op_add_nothing,},
-      {""},
-#line 23 "keywords.gperf"
-      {"tdb_unlockall_read", OP_TDB_UNLOCKALL_READ, op_add_nothing,},
-      {""},
-#line 22 "keywords.gperf"
-      {"tdb_lockall_read_nonblock", OP_TDB_LOCKALL_READ_NONBLOCK, op_add_nothing,},
-#line 43 "keywords.gperf"
-      {"tdb_traverse_end", OP_TDB_TRAVERSE_END, op_analyze_traverse,},
-#line 38 "keywords.gperf"
-      {"tdb_transaction_cancel", OP_TDB_TRANSACTION_CANCEL, op_analyze_transaction,},
-#line 42 "keywords.gperf"
-      {"tdb_traverse_start", OP_TDB_TRAVERSE_START, op_add_traverse_start,},
-      {""},
-#line 45 "keywords.gperf"
-      {"traversefn", OP_TDB_TRAVERSE, op_add_traversefn,},
-#line 37 "keywords.gperf"
-      {"tdb_transaction_start", OP_TDB_TRANSACTION_START, op_add_transaction,},
-#line 39 "keywords.gperf"
-      {"tdb_transaction_commit", OP_TDB_TRANSACTION_COMMIT, op_analyze_transaction,},
-#line 41 "keywords.gperf"
-      {"tdb_traverse_read_start", OP_TDB_TRAVERSE_READ_START, op_add_traverse_start,},
-      {""},
-#line 50 "keywords.gperf"
-      {"tdb_repack", OP_TDB_REPACK, op_add_nothing,},
-#line 47 "keywords.gperf"
-      {"tdb_nextkey", OP_TDB_NEXTKEY, op_add_key_data,},
-      {""}, {""}, {""},
-#line 40 "keywords.gperf"
-      {"tdb_transaction_prepare_commit", OP_TDB_TRANSACTION_PREPARE_COMMIT, op_add_nothing,},
-#line 31 "keywords.gperf"
-      {"tdb_parse_record", OP_TDB_PARSE_RECORD, op_add_key_ret,},
-      {""},
-#line 24 "keywords.gperf"
-      {"tdb_chainlock", OP_TDB_CHAINLOCK, op_add_chainlock,},
-      {""},
-#line 28 "keywords.gperf"
-      {"tdb_chainunlock", OP_TDB_CHAINUNLOCK, op_analyze_chainlock,},
-      {""}, {""},
-#line 26 "keywords.gperf"
-      {"tdb_chainlock_mark", OP_TDB_CHAINLOCK_MARK, op_add_key,},
-      {""},
-#line 27 "keywords.gperf"
-      {"tdb_chainlock_unmark", OP_TDB_CHAINLOCK_UNMARK, op_add_key,},
-      {""},
-#line 25 "keywords.gperf"
-      {"tdb_chainlock_nonblock", OP_TDB_CHAINLOCK_NONBLOCK, op_add_chainlock_ret,},
-#line 29 "keywords.gperf"
-      {"tdb_chainlock_read", OP_TDB_CHAINLOCK_READ, op_add_chainlock,},
-      {""},
-#line 30 "keywords.gperf"
-      {"tdb_chainunlock_read", OP_TDB_CHAINUNLOCK_READ, op_analyze_chainlock,},
-      {""}, {""}, {""}, {""},
-#line 34 "keywords.gperf"
-      {"tdb_append", OP_TDB_APPEND, op_add_append,}
-    };
-
-  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
-    {
-      register int key = hash_keyword (str, len);
-
-      if (key <= MAX_HASH_VALUE && key >= 0)
-        {
-          register const char *s = wordlist[key].name;
-
-          if (*str == *s && !strcmp (str + 1, s + 1))
-            return &wordlist[key];
-        }
-    }
-  return 0;
-}
diff --git a/ccan/tdb/tools/keywords.gperf b/ccan/tdb/tools/keywords.gperf
deleted file mode 100644 (file)
index 4edaf00..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-%{
-%}
-%language=ANSI-C
-struct op_table {
-       const char *name;
-       enum op_type type;
-       void (*enhance_op)(char *filename[], struct op op[],
-                          unsigned file, unsigned op_num, char *words[]);
-};
-%define hash-function-name hash_keyword
-%define lookup-function-name find_keyword
-%readonly-tables
-%struct-type
-%enum
-%%
-tdb_lockall, OP_TDB_LOCKALL, op_add_nothing,
-tdb_lockall_mark, OP_TDB_LOCKALL_MARK, op_add_nothing,
-tdb_lockall_unmark, OP_TDB_LOCKALL_UNMARK, op_add_nothing,
-tdb_lockall_nonblock, OP_TDB_LOCKALL_NONBLOCK, op_add_nothing,
-tdb_unlockall, OP_TDB_UNLOCKALL, op_add_nothing,
-tdb_lockall_read, OP_TDB_LOCKALL_READ, op_add_nothing,
-tdb_lockall_read_nonblock, OP_TDB_LOCKALL_READ_NONBLOCK, op_add_nothing,
-tdb_unlockall_read, OP_TDB_UNLOCKALL_READ, op_add_nothing,
-tdb_chainlock, OP_TDB_CHAINLOCK, op_add_chainlock,
-tdb_chainlock_nonblock, OP_TDB_CHAINLOCK_NONBLOCK, op_add_chainlock_ret,
-tdb_chainlock_mark, OP_TDB_CHAINLOCK_MARK, op_add_key,
-tdb_chainlock_unmark, OP_TDB_CHAINLOCK_UNMARK, op_add_key,
-tdb_chainunlock, OP_TDB_CHAINUNLOCK, op_analyze_chainlock,
-tdb_chainlock_read, OP_TDB_CHAINLOCK_READ, op_add_chainlock,
-tdb_chainunlock_read, OP_TDB_CHAINUNLOCK_READ, op_analyze_chainlock,
-tdb_parse_record, OP_TDB_PARSE_RECORD, op_add_key_ret,
-tdb_exists, OP_TDB_EXISTS, op_add_key_ret,
-tdb_store, OP_TDB_STORE, op_add_store,
-tdb_append, OP_TDB_APPEND, op_add_append,
-tdb_get_seqnum, OP_TDB_GET_SEQNUM, op_add_seqnum,
-tdb_wipe_all, OP_TDB_WIPE_ALL, op_add_wipe_all,
-tdb_transaction_start, OP_TDB_TRANSACTION_START, op_add_transaction,
-tdb_transaction_cancel, OP_TDB_TRANSACTION_CANCEL, op_analyze_transaction,
-tdb_transaction_commit, OP_TDB_TRANSACTION_COMMIT, op_analyze_transaction,
-tdb_transaction_prepare_commit, OP_TDB_TRANSACTION_PREPARE_COMMIT, op_add_nothing,
-tdb_traverse_read_start, OP_TDB_TRAVERSE_READ_START, op_add_traverse_start,
-tdb_traverse_start, OP_TDB_TRAVERSE_START, op_add_traverse_start,
-tdb_traverse_end, OP_TDB_TRAVERSE_END, op_analyze_traverse,
-traverse, OP_TDB_TRAVERSE, op_add_traverse,
-traversefn, OP_TDB_TRAVERSE, op_add_traversefn,
-tdb_firstkey, OP_TDB_FIRSTKEY, op_add_key,
-tdb_nextkey, OP_TDB_NEXTKEY, op_add_key_data,
-tdb_fetch, OP_TDB_FETCH, op_add_key_data,
-tdb_delete, OP_TDB_DELETE, op_add_key_ret,
-tdb_repack, OP_TDB_REPACK, op_add_nothing,
diff --git a/ccan/tdb/tools/mktdb.c b/ccan/tdb/tools/mktdb.c
deleted file mode 100644 (file)
index ed0efcd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <ccan/tdb/tdb.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <err.h>
-
-int main(int argc, char *argv[])
-{
-       unsigned int i, num_recs;
-       struct tdb_context *tdb;
-
-       if (argc != 3 || (num_recs = atoi(argv[2])) == 0)
-               errx(1, "Usage: mktdb <tdbfile> <numrecords>");
-
-       tdb = tdb_open(argv[1], 10007, TDB_DEFAULT, O_CREAT|O_TRUNC|O_RDWR, 0600);
-       if (!tdb)
-               err(1, "Opening %s", argv[1]);
-
-       for (i = 0; i < num_recs; i++) {
-               TDB_DATA d;
-
-               d.dptr = (void *)&i;
-               d.dsize = sizeof(i);
-               if (tdb_store(tdb, d, d, TDB_INSERT) != 0)
-                       err(1, "Failed to store record %i", i);
-       }
-       printf("Done\n");
-       return 0;
-}
diff --git a/ccan/tdb/tools/replay_trace.c b/ccan/tdb/tools/replay_trace.c
deleted file mode 100644 (file)
index 0e799a6..0000000
+++ /dev/null
@@ -1,1955 +0,0 @@
-#include <ccan/tdb/tdb.h>
-#include <ccan/grab_file/grab_file.h>
-#include <ccan/hash/hash.h>
-#include <ccan/talloc/talloc.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/str/str.h>
-#include <ccan/list/list.h>
-#include <err.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-#include <fcntl.h>
-
-#define STRINGIFY2(x) #x
-#define STRINGIFY(x) STRINGIFY2(x)
-
-static bool quiet = false;
-
-/* Avoid mod by zero */
-static unsigned int total_keys = 1;
-
-/* All the wipe_all ops. */
-static struct op_desc *wipe_alls = NULL;
-static unsigned int num_wipe_alls = 0;
-
-/* #define DEBUG_DEPS 1 */
-
-/* Traversals block transactions in the current implementation. */
-#define TRAVERSALS_TAKE_TRANSACTION_LOCK 1
-
-struct pipe {
-       int fd[2];
-};
-static struct pipe *pipes;
-static int backoff_fd = -1;
-
-static void __attribute__((noreturn)) fail(const char *filename,
-                                          unsigned int line,
-                                          const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       fprintf(stderr, "%s:%u: FAIL: ", filename, line);
-       vfprintf(stderr, fmt, ap);
-       fprintf(stderr, "\n");
-       va_end(ap);
-       exit(1);
-}
-       
-/* Try or die. */
-#define try(expr, expect)                                              \
-       do {                                                            \
-               int ret = (expr);                                       \
-               if (ret != (expect))                                    \
-                       fail(filename[file], i+1,                       \
-                            STRINGIFY(expr) "= %i", ret);              \
-       } while (0)
-
-/* Try or imitate results. */
-#define unreliable(expr, expect, force, undo)                          \
-       do {                                                            \
-               int ret = expr;                                         \
-               if (ret != expect) {                                    \
-                       fprintf(stderr, "%s:%u: %s gave %i not %i",     \
-                               filename[file], i+1, STRINGIFY(expr),   \
-                               ret, expect);                           \
-                       if (expect == 0)                                \
-                               force;                                  \
-                       else                                            \
-                               undo;                                   \
-               }                                                       \
-       } while (0)
-
-static bool key_eq(TDB_DATA a, TDB_DATA b)
-{
-       if (a.dsize != b.dsize)
-               return false;
-       return memcmp(a.dptr, b.dptr, a.dsize) == 0;
-}
-
-/* This is based on the hash algorithm from gdbm */
-static unsigned int hash_key(TDB_DATA *key)
-{
-       uint32_t value; /* Used to compute the hash value.  */
-       uint32_t   i;   /* Used to cycle through random values. */
-
-       /* Set the initial value from the key size. */
-       for (value = 0x238F13AF ^ key->dsize, i=0; i < key->dsize; i++)
-