From 3809490dd0ceb902c002bfeff09e6c04946e1a0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Nov 2007 22:57:35 -0800 Subject: Keep the tdb code in sync with Samba4. Mainly this is the svn changes : ------------------------------------------------------------------------ r23238 | tridge | 2007-05-30 01:15:49 -0700 (Wed, 30 May 2007) | 6 lines merged transaction lock changes from ctdb this ensures that having the global lock also implies the transaction lock ------------------------------------------------------------------------ r22832 | tridge | 2007-05-13 18:00:06 -0700 (Sun, 13 May 2007) | 3 lines merged the latest tdb changes from ctdb to Samba4 Jeremy. (This used to be commit ab11c0055761e97ba32a8c3ec4fa6f8763a262cd) --- source3/lib/tdb/Makefile.in | 55 +++++++++---- source3/lib/tdb/common/lock.c | 147 ++++++++++++++++++++++++++++++++--- source3/lib/tdb/common/tdb.c | 33 ++++++-- source3/lib/tdb/common/tdb_private.h | 3 + source3/lib/tdb/common/transaction.c | 9 +-- source3/lib/tdb/common/traverse.c | 14 ++-- source3/lib/tdb/configure.ac | 4 + source3/lib/tdb/include/tdb.h | 9 +++ source3/lib/tdb/libtdb.m4 | 12 ++- source3/lib/tdb/tdb.pc.in | 2 +- source3/lib/tdb/tools/tdbtest.c | 2 +- source3/lib/tdb/tools/tdbtorture.c | 2 +- 12 files changed, 238 insertions(+), 54 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/Makefile.in b/source3/lib/tdb/Makefile.in index b2f42ea70f..e1ecbb30ec 100644 --- a/source3/lib/tdb/Makefile.in +++ b/source3/lib/tdb/Makefile.in @@ -12,10 +12,15 @@ libdir = @libdir@ VPATH = @srcdir@:@libreplacedir@ srcdir = @srcdir@ builddir = @builddir@ -CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I@libreplacedir@ +CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude CFLAGS = $(CPPFLAGS) @CFLAGS@ LDFLAGS = @LDFLAGS@ EXEEXT = @EXEEXT@ +SHLD_FLAGS = @SHLD_FLAGS@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PICFLAG = @PICFLAG@ +SONAMEFLAG = @SONAMEFLAG@ +SHLIBEXT = @SHLIBEXT@ .PHONY: test @@ -23,11 +28,14 @@ PROGS = bin/tdbtool$(EXEEXT) bin/tdbdump$(EXEEXT) bin/tdbbackup$(EXEEXT) PROGS_NOINSTALL = bin/tdbtest$(EXEEXT) bin/tdbtorture$(EXEEXT) ALL_PROGS = $(PROGS) $(PROGS_NOINSTALL) -TDB_OBJ = @TDBOBJ@ @LIBREPLACEOBJ@ +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,39 +44,53 @@ 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) install: all - mkdir -p $(bindir) - mkdir -p $(includedir) - mkdir -p $(libdir) - mkdir -p $(libdir)/pkgconfig - cp $(PROGS) $(bindir) - cp $(srcdir)/include/tdb.h $(includedir) - cp tdb.pc $(libdir)/pkgconfig + mkdir -p $(DESTDIR)$(bindir) + mkdir -p $(DESTDIR)$(includedir) + mkdir -p $(DESTDIR)$(libdir) + mkdir -p $(DESTDIR)$(libdir)/pkgconfig + 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 -s $< $@ + +$(SONAME): $(SOLIB) + ln -s $< $@ + +$(SOLIB): $(TDB_OBJ) + $(CC) $(SHLD_FLAGS) $(SONAMEFLAG)$(SONAME) -o $@ $^ + +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 +101,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 distclean: clean rm -f *~ */*~ diff --git a/source3/lib/tdb/common/lock.c b/source3/lib/tdb/common/lock.c index 43be5d20e1..e3fe888c46 100644 --- a/source3/lib/tdb/common/lock.c +++ b/source3/lib/tdb/common/lock.c @@ -27,6 +27,8 @@ #include "tdb_private.h" +#define TDB_MARK_LOCK 0x80000000 + void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) { tdb->interrupt_sig_ptr = ptr; @@ -116,10 +118,13 @@ int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len) /* lock a list in the database. list -1 is the alloc list */ -int tdb_lock(struct tdb_context *tdb, int list, int ltype) +static int _tdb_lock(struct tdb_context *tdb, int list, int ltype, int op) { struct tdb_lock_type *new_lck; int i; + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; /* a global lock allows us to avoid per chain locks */ if (tdb->global_lock.count && @@ -169,10 +174,9 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype) /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ - if (tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, + if (!mark_lock && + tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op, 0, 1)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " - "ltype=%d (%s)\n", list, ltype, strerror(errno))); return -1; } @@ -186,6 +190,25 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype) return 0; } +/* 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(tdb, list, ltype, F_SETLKW); + 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(tdb, list, ltype, F_SETLK); +} + + /* unlock the database: returns void because it's too late for errors. */ /* changed to return int it may be interesting to know there has been an error --simo */ @@ -194,6 +217,9 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) int ret = -1; int i; struct tdb_lock_type *lck = NULL; + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; /* a global lock allows us to avoid per chain locks */ if (tdb->global_lock.count && @@ -238,8 +264,12 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) * anyway. */ - ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, - F_SETLKW, 0, 1); + if (mark_lock) { + ret = 0; + } else { + ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, + F_SETLKW, 0, 1); + } tdb->num_locks--; /* @@ -266,11 +296,50 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) return ret; } +/* + get the transaction lock + */ +int tdb_transaction_lock(struct tdb_context *tdb, int ltype) +{ + if (tdb->have_transaction_lock || tdb->global_lock.count) { + return 0; + } + if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, + F_SETLKW, 0, 1) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + tdb->have_transaction_lock = 1; + return 0; +} + +/* + release the transaction lock + */ +int tdb_transaction_unlock(struct tdb_context *tdb) +{ + int ret; + if (!tdb->have_transaction_lock) { + return 0; + } + ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); + if (ret == 0) { + tdb->have_transaction_lock = 0; + } + return ret; +} + + /* lock/unlock entire database */ -static int _tdb_lockall(struct tdb_context *tdb, int ltype) +static int _tdb_lockall(struct tdb_context *tdb, int ltype, int op) { + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; + /* There are no locks on read-only dbs */ if (tdb->read_only || tdb->traverse_read) return TDB_ERRCODE(TDB_ERR_LOCK, -1); @@ -290,9 +359,12 @@ static int _tdb_lockall(struct tdb_context *tdb, int ltype) return TDB_ERRCODE(TDB_ERR_LOCK, -1); } - if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, F_SETLKW, + if (!mark_lock && + tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, op, 0, 4*tdb->header.hash_size)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno))); + if (op == F_SETLKW) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno))); + } return -1; } @@ -302,9 +374,15 @@ static int _tdb_lockall(struct tdb_context *tdb, int ltype) return 0; } + + /* unlock entire db */ static int _tdb_unlockall(struct tdb_context *tdb, int ltype) { + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; + /* There are no locks on read-only dbs */ if (tdb->read_only || tdb->traverse_read) { return TDB_ERRCODE(TDB_ERR_LOCK, -1); @@ -319,7 +397,8 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype) return 0; } - if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, + if (!mark_lock && + tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 4*tdb->header.hash_size)) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno))); return -1; @@ -334,7 +413,25 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype) /* lock entire database with write lock */ int tdb_lockall(struct tdb_context *tdb) { - return _tdb_lockall(tdb, F_WRLCK); + return _tdb_lockall(tdb, F_WRLCK, F_SETLKW); +} + +/* lock entire database with write lock - mark only */ +int tdb_lockall_mark(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW); +} + +/* unlock entire database with write lock - unmark only */ +int tdb_lockall_unmark(struct tdb_context *tdb) +{ + return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK); +} + +/* lock entire database with write lock - nonblocking varient */ +int tdb_lockall_nonblock(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_WRLCK, F_SETLK); } /* unlock entire database with write lock */ @@ -346,7 +443,13 @@ int tdb_unlockall(struct tdb_context *tdb) /* lock entire database with read lock */ int tdb_lockall_read(struct tdb_context *tdb) { - return _tdb_lockall(tdb, F_RDLCK); + return _tdb_lockall(tdb, F_RDLCK, F_SETLKW); +} + +/* lock entire database with read lock - nonblock varient */ +int tdb_lockall_read_nonblock(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_RDLCK, F_SETLK); } /* unlock entire database with read lock */ @@ -362,6 +465,26 @@ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } +/* 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) +{ + return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +/* 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) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); +} + +/* 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) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); +} + int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) { return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); diff --git a/source3/lib/tdb/common/tdb.c b/source3/lib/tdb/common/tdb.c index 8f3c146843..0e9d1dbd74 100644 --- a/source3/lib/tdb/common/tdb.c +++ b/source3/lib/tdb/common/tdb.c @@ -30,10 +30,10 @@ TDB_DATA tdb_null; /* - increment the tdb sequence number if the tdb has been opened using + non-blocking increment of the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag */ -static void tdb_increment_seqnum(struct tdb_context *tdb) +void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) { tdb_off_t seqnum=0; @@ -41,16 +41,29 @@ static void tdb_increment_seqnum(struct tdb_context *tdb) return; } - if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) { - 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_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) { + return; + } + + tdb_increment_seqnum_nonblock(tdb); tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1); } @@ -653,3 +666,11 @@ int tdb_get_flags(struct tdb_context *tdb) return tdb->flags; } + +/* + enable sequence number handling on an open tdb +*/ +void tdb_enable_seqnum(struct tdb_context *tdb) +{ + tdb->flags |= TDB_SEQNUM; +} diff --git a/source3/lib/tdb/common/tdb_private.h b/source3/lib/tdb/common/tdb_private.h index daef07aff1..00bd0eb537 100644 --- a/source3/lib/tdb/common/tdb_private.h +++ b/source3/lib/tdb/common/tdb_private.h @@ -162,6 +162,7 @@ struct tdb_context { struct tdb_transaction *transaction; int page_size; int max_dead_records; + bool have_transaction_lock; volatile sig_atomic_t *interrupt_sig_ptr; }; @@ -174,6 +175,8 @@ void tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); int tdb_unlock(struct tdb_context *tdb, int list, int ltype); int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); +int tdb_transaction_lock(struct tdb_context *tdb, int ltype); +int tdb_transaction_unlock(struct tdb_context *tdb); int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len); 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); diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index 8263bd7f38..7eaacf7a16 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -422,9 +422,7 @@ int tdb_transaction_start(struct tdb_context *tdb) /* get the transaction write lock. This is a blocking lock. As discussed with Volker, there are a number of ways we could make this async, which we will probably do in the future */ - if (tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; + if (tdb_transaction_lock(tdb, F_WRLCK) == -1) { SAFE_FREE(tdb->transaction); return -1; } @@ -468,6 +466,7 @@ int tdb_transaction_start(struct tdb_context *tdb) TDB_HASHTABLE_SIZE(tdb)) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n")); tdb->ecode = TDB_ERR_IO; + tdb->methods = tdb->transaction->io_methods; goto fail; } @@ -475,7 +474,7 @@ int tdb_transaction_start(struct tdb_context *tdb) fail: tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); - tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); + tdb_transaction_unlock(tdb); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return -1; @@ -530,7 +529,7 @@ int tdb_transaction_cancel(struct tdb_context *tdb) tdb->methods = tdb->transaction->io_methods; tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); - tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); + tdb_transaction_unlock(tdb); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); diff --git a/source3/lib/tdb/common/traverse.c b/source3/lib/tdb/common/traverse.c index 86fa4fd48e..6fc576a55a 100644 --- a/source3/lib/tdb/common/traverse.c +++ b/source3/lib/tdb/common/traverse.c @@ -204,12 +204,10 @@ int tdb_traverse_read(struct tdb_context *tdb, { struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; int ret; - + /* we need to get a read lock on the transaction lock here to cope with the lock ordering semantics of solaris10 */ - if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; + if (tdb_transaction_lock(tdb, F_RDLCK)) { return -1; } @@ -217,7 +215,7 @@ int tdb_traverse_read(struct tdb_context *tdb, ret = tdb_traverse_internal(tdb, fn, private_data, &tl); tdb->traverse_read--; - tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); + tdb_transaction_unlock(tdb); return ret; } @@ -236,15 +234,13 @@ int tdb_traverse(struct tdb_context *tdb, return tdb_traverse_read(tdb, fn, private_data); } - if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; + if (tdb_transaction_lock(tdb, F_WRLCK)) { return -1; } ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); + tdb_transaction_unlock(tdb); return ret; } diff --git a/source3/lib/tdb/configure.ac b/source3/lib/tdb/configure.ac index 8bfff589cc..de8fc9c2b5 100644 --- a/source3/lib/tdb/configure.ac +++ b/source3/lib/tdb/configure.ac @@ -6,5 +6,9 @@ AC_INIT(tdb, 1.1.0) AC_CONFIG_SRCDIR([common/tdb.c]) AC_CONFIG_HEADER(include/config.h) AC_LIBREPLACE_ALL_CHECKS +AC_LD_SONAMEFLAG +AC_LD_PICFLAG +AC_LD_SHLDFLAGS +AC_LD_SHLIBEXT m4_include(libtdb.m4) AC_OUTPUT(Makefile tdb.pc) diff --git a/source3/lib/tdb/include/tdb.h b/source3/lib/tdb/include/tdb.h index 21410e840b..7de4c419a8 100644 --- a/source3/lib/tdb/include/tdb.h +++ b/source3/lib/tdb/include/tdb.h @@ -116,9 +116,13 @@ 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); @@ -131,12 +135,17 @@ 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_enable_seqnum(struct tdb_context *tdb); +void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); /* 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); diff --git a/source3/lib/tdb/libtdb.m4 b/source3/lib/tdb/libtdb.m4 index fefa5912c2..7682edada9 100644 --- a/source3/lib/tdb/libtdb.m4 +++ b/source3/lib/tdb/libtdb.m4 @@ -12,11 +12,17 @@ done if test x"$tdbdir" = "x"; then AC_MSG_ERROR([cannot find tdb source in $tdbpaths]) fi -TDBOBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" -TDBOBJ="$TDBOBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o" -AC_SUBST(TDBOBJ) +TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" +TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o" +AC_SUBST(TDB_OBJ) AC_SUBST(LIBREPLACEOBJ) +TDB_LIBS="" +AC_SUBST(TDB_LIBS) + +TDB_CFLAGS="-I$tdbdir/include" +AC_SUBST(TDB_CFLAGS) + AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime) AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h) diff --git a/source3/lib/tdb/tdb.pc.in b/source3/lib/tdb/tdb.pc.in index 8180d47185..bb440f9cf5 100644 --- a/source3/lib/tdb/tdb.pc.in +++ b/source3/lib/tdb/tdb.pc.in @@ -5,6 +5,6 @@ includedir=@includedir@ Name: tdb Description: A trivial database -Version: 4.0 +Version: @PACKAGE_VERSION@ Libs: -L${libdir} -ltdb Cflags: -I${includedir} diff --git a/source3/lib/tdb/tools/tdbtest.c b/source3/lib/tdb/tools/tdbtest.c index 1564a42bc4..416bc50a5b 100644 --- a/source3/lib/tdb/tools/tdbtest.c +++ b/source3/lib/tdb/tools/tdbtest.c @@ -214,7 +214,7 @@ static void merge_test(void) key.dptr = keys[3]; tdb_delete(db, key); } - + int main(int argc, const char *argv[]) { int i, seed=0; diff --git a/source3/lib/tdb/tools/tdbtorture.c b/source3/lib/tdb/tools/tdbtorture.c index 14a2b48cdc..ca71c736ad 100644 --- a/source3/lib/tdb/tools/tdbtorture.c +++ b/source3/lib/tdb/tools/tdbtorture.c @@ -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