diff options
-rw-r--r-- | source3/nsswitch/winbindd_dual.c | 2 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 | ||||
-rw-r--r-- | source3/tdb/tdb.c | 18 | ||||
-rw-r--r-- | source3/tdb/tdb.h | 2 | ||||
-rw-r--r-- | source3/tdb/tdbtorture.c | 4 |
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); |