summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/winbindd_dual.c2
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/tdb/tdb.c18
-rw-r--r--source3/tdb/tdb.h2
-rw-r--r--source3/tdb/tdbtorture.c4
5 files changed, 22 insertions, 6 deletions
diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c
index a049bf7b7a..cdfa1e0493 100644
--- a/source3/nsswitch/winbindd_dual.c
+++ b/source3/nsswitch/winbindd_dual.c
@@ -629,7 +629,7 @@ static BOOL fork_domain_child(struct winbindd_child *child)
close(fdpair[1]);
/* tdb needs special fork handling */
- if (tdb_reopen_all() == -1) {
+ if (tdb_reopen_all(1) == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
_exit(0);
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index dfead851e8..ba31827eb3 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -474,7 +474,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
set_need_random_reseed();
/* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
- if (tdb_reopen_all() == -1) {
+ if (tdb_reopen_all(1) == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
smb_panic("tdb_reopen_all failed.");
}
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index 4303976087..ad73a1d9aa 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -2098,11 +2098,27 @@ fail:
}
/* reopen all tdb's */
-int tdb_reopen_all(void)
+int tdb_reopen_all(int parent_longlived)
{
TDB_CONTEXT *tdb;
for (tdb=tdbs; tdb; tdb = tdb->next) {
+ /*
+ * 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. */
+ tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+ }
+
if (tdb_reopen(tdb) != 0)
return -1;
}
diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h
index d1c976cd56..b5b87ee5a5 100644
--- a/source3/tdb/tdb.h
+++ b/source3/tdb/tdb.h
@@ -128,7 +128,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
tdb_hash_func hash_fn);
int tdb_reopen(TDB_CONTEXT *tdb);
-int tdb_reopen_all(void);
+int tdb_reopen_all(int);
void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func);
enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
const char *tdb_errorstr(TDB_CONTEXT *tdb);
diff --git a/source3/tdb/tdbtorture.c b/source3/tdb/tdbtorture.c
index d03cc2a610..2d367b91e1 100644
--- a/source3/tdb/tdbtorture.c
+++ b/source3/tdb/tdbtorture.c
@@ -103,7 +103,7 @@ static void addrec_db(void)
#if REOPEN_PROB
if (random() % REOPEN_PROB == 0) {
- tdb_reopen_all();
+ tdb_reopen_all(1);
goto next;
}
#endif
@@ -192,7 +192,7 @@ int main(int argc, char *argv[])
for (i=0;i<NPROC;i++) {
pids[i] = fork();
if (pids[i] == 0) {
- tdb_reopen_all();
+ tdb_reopen_all(1);
tdb_logging_function(db, tdb_log);