merge from Samba4
authorAndrew Tridgell <tridge@samba.org>
Sat, 5 Jan 2008 06:41:41 +0000 (17:41 +1100)
committerAndrew Tridgell <tridge@samba.org>
Sat, 5 Jan 2008 06:41:41 +0000 (17:41 +1100)
16 files changed:
lib/tdb/Makefile.in
lib/tdb/autogen.sh
lib/tdb/common/io.c
lib/tdb/common/lock.c
lib/tdb/common/open.c
lib/tdb/common/tdb.c
lib/tdb/common/tdb_private.h
lib/tdb/common/traverse.c
lib/tdb/config.mk
lib/tdb/configure.ac
lib/tdb/include/tdb.h
lib/tdb/libtdb.m4
lib/tdb/tools/tdbbackup.c
lib/tdb/tools/tdbdump.c
lib/tdb/tools/tdbtool.c
lib/tdb/tools/tdbtorture.c

index ba98564506be7a75e4510fcf77c1c8e3f3d6a2b5..a60b9a67bf5b11475a14838a044ac1e61659f495 100644 (file)
@@ -16,6 +16,12 @@ CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude
 CFLAGS = $(CPPFLAGS) @CFLAGS@
 LDFLAGS = @LDFLAGS@
 EXEEXT = @EXEEXT@
+SHLD = @SHLD@
+SHLD_FLAGS = @SHLD_FLAGS@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PICFLAG = @PICFLAG@
+SHLIBEXT = @SHLIBEXT@
+SWIG = swig
 
 .PHONY: test
 
@@ -27,7 +33,10 @@ TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@
 
 DIRS = bin common tools
 
-all: showflags dirs $(PROGS)
+SONAME = libtdb.$(SHLIBEXT).1
+SOLIB = libtdb.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+all: showflags dirs $(PROGS) $(SOLIB) libtdb.a
 
 showflags:
        @echo 'tdb will be compiled with flags:'
@@ -36,10 +45,12 @@ showflags:
        @echo '  LDFLAGS = $(LDFLAGS)'
        @echo '  LIBS = $(LIBS)'
 
+.SUFFIXES: .c .o
+
 .c.o:
        @echo Compiling $*.c
        @mkdir -p `dirname $@`
-       @$(CC) $(CFLAGS) -c $< -o $@
+       @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@
 
 dirs:
        @mkdir -p $(DIRS)
@@ -52,23 +63,35 @@ install: all
        cp $(PROGS) $(DESTDIR)$(bindir)
        cp $(srcdir)/include/tdb.h $(DESTDIR)$(includedir)
        cp tdb.pc $(DESTDIR)$(libdir)/pkgconfig
+       cp libtdb.a $(SOLIB) $(DESTDIR)$(libdir)
 
 libtdb.a: $(TDB_OBJ)
        ar -rv libtdb.a $(TDB_OBJ)
 
-bin/tdbtest$(EXEEXT): tools/tdbtest.o libtdb.a
+libtdb.$(SHLIBEXT): $(SOLIB)
+       ln -fs $< $@
+
+$(SONAME): $(SOLIB)
+       ln -fs $< $@
+
+$(SOLIB): $(TDB_OBJ)
+       $(SHLD) $(SHLD_FLAGS) -o $@ $(TDB_OBJ) @SONAMEFLAG@$(SONAME)
+
+TDB_LIB = libtdb.a
+
+bin/tdbtest$(EXEEXT): tools/tdbtest.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtest tools/tdbtest.o -L. -ltdb -lgdbm
 
-bin/tdbtool$(EXEEXT): tools/tdbtool.o libtdb.a
+bin/tdbtool$(EXEEXT): tools/tdbtool.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtool tools/tdbtool.o -L. -ltdb
 
-bin/tdbtorture$(EXEEXT): tools/tdbtorture.o libtdb.a
+bin/tdbtorture$(EXEEXT): tools/tdbtorture.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtorture tools/tdbtorture.o -L. -ltdb
 
-bin/tdbdump$(EXEEXT): tools/tdbdump.o libtdb.a
+bin/tdbdump$(EXEEXT): tools/tdbdump.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbdump tools/tdbdump.o -L. -ltdb
 
-bin/tdbbackup$(EXEEXT): tools/tdbbackup.o libtdb.a
+bin/tdbbackup$(EXEEXT): tools/tdbbackup.o $(TDB_LIB)
        $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbbackup tools/tdbbackup.o -L. -ltdb
 
 test: bin/tdbtorture$(EXEEXT)
@@ -79,6 +102,7 @@ installcheck: test install
 clean:
        rm -f $(ALL_PROGS) *.o *.a common/*.o tools/*.o tdb.pc
        rm -f test.db test.tdb torture.tdb test.gdbm
+       rm -f $(SONAME) $(SOLIB) libtdb.a libtdb.$(SHLIBEXT)
 
 distclean: clean
        rm -f *~ */*~
@@ -87,3 +111,23 @@ distclean: clean
 
 realdistclean: distclean
        rm -f configure include/config.h.in
+
+tdb_wrap.c tdb.py: tdb.i
+       $(SWIG) -O -Wall -python -keyword tdb.i
+
+build-python: libtdb.$(SHLIBEXT) tdb_wrap.c tdb.py
+       ./setup.py build
+
+install-python:
+       ./setup.py install --prefix=$(prefix)
+
+check-python: build-python
+       # FIXME: Should be more portable:
+       LD_LIBRARY_PATH=. PYTHONPATH=.:build/lib.linux-i686-2.4 trial python/tests/simple.py
+
+install-swig:
+       mkdir -p $(DESTDIR)`$(SWIG) -swiglib`
+       cp tdb.i $(DESTDIR)`$(SWIG) -swiglib`
+
+clean-python:
+       ./setup.py clean
index bf84eeee19a9116f3dc79177449a91321b3e8c31..88ac4cfcf73fb364825f2661b340456dc6ccc5fb 100755 (executable)
@@ -9,6 +9,8 @@ autoheader $IPATHS || exit 1
 
 rm -rf autom4te.cache
 
+swig -O -Wall -python -keyword tdb.i # Ignore errors for now
+
 echo "Now run ./configure and then make."
 exit 0
 
index 1da9ac37c2fe8c4025ef96f009a507fd5f27b90f..172ab69d8c9e69ae7f160071567c4d885ac7848c 100644 (file)
@@ -88,13 +88,32 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off,
 
        if (tdb->map_ptr) {
                memcpy(off + (char *)tdb->map_ptr, buf, len);
-       } else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) {
+       } else {
+               ssize_t written = pwrite(tdb->fd, buf, len, off);
+               if ((written != (ssize_t)len) && (written != -1)) {
+                       /* try once more */
+                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only "
+                                "%d of %d bytes at %d, trying once more\n",
+                                (int)written, len, off));
+                       errno = ENOSPC;
+                       written = pwrite(tdb->fd, (const void *)((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)));
+                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d "
+                                "len=%d (%s)\n", off, len, strerror(errno)));
+                       return TDB_ERRCODE(TDB_ERR_IO, -1);
+               } else if (written != (ssize_t)len) {
+                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to "
+                                "write %d bytes at %d in two attempts\n",
+                                len, off));
+                       errno = ENOSPC;
                return TDB_ERRCODE(TDB_ERR_IO, -1);
        }
+       }
        return 0;
 }
 
@@ -220,7 +239,16 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
 
        if (ftruncate(tdb->fd, size+addition) == -1) {
                char b = 0;
-               if (pwrite(tdb->fd,  &b, 1, (size+addition) - 1) != 1) {
+               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;
@@ -232,15 +260,30 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
           disk. This must be done with write, not via mmap */
        memset(buf, TDB_PAD_BYTE, sizeof(buf));
        while (addition) {
-               int n = addition>sizeof(buf)?sizeof(buf):addition;
-               int ret = pwrite(tdb->fd, buf, n, size);
-               if (ret != n) {
-                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of %d failed (%s)\n", 
-                                  n, strerror(errno)));
+               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 -= n;
-               size += n;
+               addition -= written;
+               size += written;
        }
        return 0;
 }
index 33afe74336f02d19b023a35f5d40bbb69be58021..f156c0fa7b2e548640d47db23df71c9427ec73ce 100644 (file)
 
 #define TDB_MARK_LOCK 0x80000000
 
+void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
+{
+       tdb->interrupt_sig_ptr = ptr;
+}
+
 /* a byte range locking function - return 0 on success
    this functions locks/unlocks 1 byte at the specified offset.
 
@@ -60,6 +65,13 @@ int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset,
 
        do {
                ret = fcntl(tdb->fd,lck_type,&fl);
+
+               /* 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) {
index e2353d6e6002378ab9a78d5c2832b52840a98f85..6bd8fda2bf1a4a5212578bfcc60edcf74bd76f93 100644 (file)
@@ -49,7 +49,9 @@ static unsigned int default_tdb_hash(TDB_DATA *key)
 static int tdb_new_database(struct tdb_context *tdb, int hash_size)
 {
        struct tdb_header *newdb;
-       int size, ret = -1;
+       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);
@@ -78,10 +80,22 @@ static int tdb_new_database(struct tdb_context *tdb, int hash_size)
        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);
-       if (write(tdb->fd, newdb, size) != size) {
-               ret = -1;
-       } else {
+       /* 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:
@@ -165,6 +179,10 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
                tdb->page_size = 0x2000;
        }
 
+       if (open_flags & TDB_VOLATILE) {
+               tdb->max_dead_records = 5;
+       }
+
        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));
@@ -221,13 +239,16 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
                }
        }
 
+       errno = 0;
        if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
            || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
            || (tdb->header.version != TDB_VERSION
                && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
                /* its not a valid database - possibly initialise it */
                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);
index 3edd10fff0dd8266f887bde9dd0737778519e57f..79c15475191c2f6693f2a8cd1c0530412182626b 100644 (file)
@@ -579,8 +579,12 @@ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
        if (dbuf.dptr == NULL) {
                dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize);
        } else {
-               dbuf.dptr = (unsigned char *)realloc(dbuf.dptr,
+               unsigned char *new_dptr = (unsigned char *)realloc(dbuf.dptr,
                                                     dbuf.dsize + new_dbuf.dsize);
+               if (new_dptr == NULL) {
+                       free(dbuf.dptr);
+               }
+               dbuf.dptr = new_dptr;
        }
 
        if (dbuf.dptr == NULL) {
index b157ec8af5362f38b1580713db6e10a400247f89..86cb762fd52b086880cb3c21519d5ded4a82c2c3 100644 (file)
@@ -28,6 +28,7 @@
 #include "system/time.h"
 #include "system/shmem.h"
 #include "system/select.h"
+#include "system/wait.h"
 #include "tdb.h"
 
 #ifndef HAVE_GETPAGESIZE
@@ -61,7 +62,7 @@ typedef uint32_t 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_UINT32_T  0x42424242
+#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
@@ -167,6 +168,7 @@ struct tdb_context {
        int page_size;
        int max_dead_records;
        bool have_transaction_lock;
+       volatile sig_atomic_t *interrupt_sig_ptr;
 };
 
 
index c244ea848da7b1054aa4db4118c76778fd53a39f..2bde1270a078f2df05ddf235fb14cd6fd5218df0 100644 (file)
@@ -260,12 +260,15 @@ TDB_DATA tdb_firstkey(struct tdb_context *tdb)
        tdb->travlocks.off = tdb->travlocks.hash = 0;
        tdb->travlocks.lock_rw = F_RDLCK;
 
+       /* Grab first record: locks chain and returned record. */
        if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0)
                return tdb_null;
        /* now read the key */
        key.dsize = rec.key_len;
        key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
-       if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0)
+
+       /* Unlock the hash chain of the record we just read. */
+       if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
                TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n"));
        return key;
 }
@@ -280,7 +283,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
 
        /* Is locked key the old key?  If so, traverse will be reliable. */
        if (tdb->travlocks.off) {
-               if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK))
+               if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw))
                        return tdb_null;
                if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1
                    || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
@@ -291,7 +294,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
                                SAFE_FREE(k);
                                return tdb_null;
                        }
-                       if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) {
+                       if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) {
                                SAFE_FREE(k);
                                return tdb_null;
                        }
@@ -303,7 +306,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
 
        if (!tdb->travlocks.off) {
                /* No previous element: do normal find, and lock record */
-               tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec);
+               tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec);
                if (!tdb->travlocks.off)
                        return tdb_null;
                tdb->travlocks.hash = BUCKET(rec.full_hash);
@@ -321,11 +324,11 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
                key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec),
                                          key.dsize);
                /* Unlock the chain of this new record */
-               if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0)
+               if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
                        TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
        }
        /* Unlock the chain of old record */
-       if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0)
+       if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0)
                TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
        return key;
 }
index ab90ed728d57afc3caa391ca8eacd82d8e2cb90e..c9e5a67d7bae11e58b65ade038537eaae3cfa05c 100644 (file)
@@ -57,12 +57,3 @@ PRIVATE_DEPENDENCIES = \
                LIBTDB
 # End BINARY tdbbackup
 ################################################
-
-#######################
-# Start LIBRARY swig_tdb
-[LIBRARY::swig_tdb]
-LIBRARY_REALNAME = swig/_tdb.$(SHLIBEXT)
-OBJ_FILES = swig/tdb_wrap.o
-PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG
-# End LIBRARY swig_tdb
-#######################
index 8bfff589cc58e1d81dedeab9b9e60ff4b6eb5ee6..3237d29fb04e1c45a59057562c9f552dcdf43a48 100644 (file)
@@ -2,9 +2,14 @@ AC_PREREQ(2.50)
 AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
 AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
 AC_DEFUN([SMB_ENABLE], [echo -n ""])
-AC_INIT(tdb, 1.1.0)
+AC_INIT(tdb, 1.1.1)
 AC_CONFIG_SRCDIR([common/tdb.c])
 AC_CONFIG_HEADER(include/config.h)
 AC_LIBREPLACE_ALL_CHECKS
+AC_LD_SONAMEFLAG
+AC_LD_PICFLAG
+AC_LD_SHLIBEXT
+AC_LIBREPLACE_SHLD
+AC_LIBREPLACE_SHLD_FLAGS
 m4_include(libtdb.m4)
 AC_OUTPUT(Makefile tdb.pc)
index fb59911ebe533ea6299947391e75c9023fa6bffe..7de4c419a81ea0c67b6faadfc22b0208c44a0c6b 100644 (file)
@@ -46,6 +46,7 @@ extern "C" {
 #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_ERRCODE(code, ret) ((tdb->ecode = (code)), ret)
 
@@ -146,6 +147,8 @@ 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);
+
 /* Debug functions. Not used in production. */
 void tdb_dump_all(struct tdb_context *tdb);
 int tdb_printfreelist(struct tdb_context *tdb);
index 7682edada9312d9c6c204ba56dc2db005de78d3d..1e17a7a4f23c74ea30eaf3914c5346b1915776df 100644 (file)
@@ -28,35 +28,3 @@ AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h)
 
 AC_HAVE_DECL(pread, [#include <unistd.h>])
 AC_HAVE_DECL(pwrite, [#include <unistd.h>])
-
-AC_MSG_CHECKING([for Python])
-
-PYTHON=
-AC_ARG_WITH(python,
-[  --with-python=PYTHONNAME  build Python libraries],
-[ case "${withval-python}" in
-  yes)
-        PYTHON=python
-        ;;
-  no)
-        PYTHON=
-        ;;
-  *)
-        PYTHON=${withval-python}
-        ;;
-  esac ])
-
-if test x"$PYTHON" != "x"; then
-       incdir=`python -c 'import sys; print "%s/include/python%d.%d" % (sys.prefix, sys.version_info[[0]], sys.version_info[[1]])'`
-       CPPFLAGS="$CPPFLAGS -I $incdir"
-fi
-
-if test x"$PYTHON" != "x"; then
-       AC_MSG_RESULT([${withval-python}])
-else
-       SMB_ENABLE(swig_tdb, NO)
-       AC_MSG_RESULT(no)
-fi
-
-AC_SUBST(PYTHON)
index 2a75c44b1d4f5e7a42c501e5cff8deea20f19be6..6f3ca48314f0ccbb0b48bcecf1637e0e3f628290 100644 (file)
@@ -44,6 +44,7 @@
 #include "system/locale.h"
 #include "system/time.h"
 #include "system/filesys.h"
+#include "system/wait.h"
 #include "tdb.h"
 
 #ifdef HAVE_GETOPT_H
@@ -70,7 +71,7 @@ static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
        TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
 
        if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
-               fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb));
+               fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new));
                failed = 1;
                return 1;
        }
@@ -163,7 +164,7 @@ static int backup_tdb(const char *old_name, const char *new_name, int hash_size)
        }
        
        /* traverse the new tdb to confirm */
-       count2 = tdb_traverse(tdb_new, test_fn, 0);
+       count2 = tdb_traverse(tdb_new, test_fn, NULL);
        if (count2 != count1) {
                fprintf(stderr,"failed to copy %s\n", old_name);
                tdb_close(tdb_new);
@@ -177,7 +178,6 @@ static int backup_tdb(const char *old_name, const char *new_name, int hash_size)
 
        /* close the new tdb and rename it to .bak */
        tdb_close(tdb_new);
-       unlink(new_name);
        if (rename(tmp_name, new_name) != 0) {
                perror(new_name);
                free(tmp_name);
index a654c0fb31682061188fe6cb40339a9deac3d771..8d930383b0918cc94ff2602f0685c95073273699 100644 (file)
@@ -21,6 +21,7 @@
 #include "system/locale.h"
 #include "system/time.h"
 #include "system/filesys.h"
+#include "system/wait.h"
 #include "tdb.h"
 
 static void print_data(TDB_DATA d)
index 580dd9d02ae17ec6059e7c2c8424bde97fca267c..79435a3571cf61f02233d088e7ce3f01354b19af 100644 (file)
@@ -24,6 +24,7 @@
 #include "system/locale.h"
 #include "system/time.h"
 #include "system/filesys.h"
+#include "system/wait.h"
 #include "tdb.h"
 
 static int do_command(void);
@@ -34,6 +35,7 @@ int bIterate = 0;
 char *line;
 TDB_DATA iterate_kbuf;
 char cmdline[1024];
+static int disable_mmap;
 
 enum commands {
        CMD_CREATE_TDB,
@@ -50,6 +52,8 @@ enum commands {
        CMD_LIST_HASH_FREE,
        CMD_LIST_FREE,
        CMD_INFO,
+       CMD_MMAP,
+       CMD_SPEED,
        CMD_FIRST,
        CMD_NEXT,
        CMD_SYSTEM,
@@ -77,6 +81,8 @@ COMMAND_TABLE cmd_table[] = {
        {"list",        CMD_LIST_HASH_FREE},
        {"free",        CMD_LIST_FREE},
        {"info",        CMD_INFO},
+       {"speed",       CMD_SPEED},
+       {"mmap",        CMD_MMAP},
        {"first",       CMD_FIRST},
        {"1",           CMD_FIRST},
        {"next",        CMD_NEXT},
@@ -87,6 +93,20 @@ COMMAND_TABLE cmd_table[] = {
        {NULL,          CMD_HELP}
 };
 
+struct timeval tp1,tp2;
+
+static void _start_timer(void)
+{
+       gettimeofday(&tp1,NULL);
+}
+
+static double _end_timer(void)
+{
+       gettimeofday(&tp2,NULL);
+       return((tp2.tv_sec - tp1.tv_sec) + 
+              (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+}
+
 /* a tdb tool for manipulating a tdb database */
 
 static TDB_CONTEXT *tdb;
@@ -175,7 +195,7 @@ static void terror(const char *why)
 static void create_tdb(const char *tdbname)
 {
        if (tdb) tdb_close(tdb);
-       tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST,
+       tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0),
                       O_RDWR | O_CREAT | O_TRUNC, 0600);
        if (!tdb) {
                printf("Could not create %s: %s\n", tdbname, strerror(errno));
@@ -185,7 +205,7 @@ static void create_tdb(const char *tdbname)
 static void open_tdb(const char *tdbname)
 {
        if (tdb) tdb_close(tdb);
-       tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600);
+       tdb = tdb_open(tdbname, 0, disable_mmap?TDB_NOMMAP:0, O_RDWR, 0600);
        if (!tdb) {
                printf("Could not open %s: %s\n", tdbname, strerror(errno));
        }
@@ -365,6 +385,31 @@ static void info_tdb(void)
                printf("%d records totalling %d bytes\n", count, total_bytes);
 }
 
+static void speed_tdb(const char *tlimit)
+{
+       unsigned timelimit = tlimit?atoi(tlimit):0;
+       double t;
+       int ops=0;
+       if (timelimit == 0) timelimit = 10;
+       printf("Testing traverse speed for %u seconds\n", timelimit);
+       _start_timer();
+       while ((t=_end_timer()) < timelimit) {
+               tdb_traverse(tdb, traverse_fn, NULL);
+               printf("%10.3f ops/sec\r", (++ops)/t);
+       }
+       printf("\n");
+}
+
+static void toggle_mmap(void)
+{
+       disable_mmap = !disable_mmap;
+       if (disable_mmap) {
+               printf("mmap is disabled\n");
+       } else {
+               printf("mmap is enabled\n");
+       }
+}
+
 static char *tdb_getline(const char *prompt)
 {
        static char thisline[1024];
@@ -493,6 +538,12 @@ static int do_command(void)
            case CMD_INFO:
                info_tdb();
                return 0;
+           case CMD_SPEED:
+               speed_tdb(arg1);
+               return 0;
+           case CMD_MMAP:
+               toggle_mmap();
+               return 0;
            case CMD_FIRST:
                bIterate = 1;
                first_record(tdb, &iterate_kbuf);
index 14a2b48cdc78d4bf5e4d215b1f2cd354e08312cc..9265cf07aa27976f36c54801758e2f6862e2b613 100644 (file)
@@ -3,10 +3,10 @@
 */
 
 #include "replace.h"
-#include "tdb.h"
 #include "system/time.h"
 #include "system/wait.h"
 #include "system/filesys.h"
+#include "tdb.h"
 
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
@@ -238,7 +238,7 @@ static void usage(void)
 
        unlink("torture.tdb");
 
-       pids = calloc(sizeof(pid_t), num_procs);
+       pids = (pid_t *)calloc(sizeof(pid_t), num_procs);
        pids[0] = getpid();
 
        for (i=0;i<num_procs-1;i++) {