[PATCH] Reimplementation of Metze's "lib/tdb: if we know pwrite and pread are thread/fork safe tdb_reopen_all() should be a noop".
Rusty Russell
rusty at rustcorp.com.au
Wed Jul 29 20:22:08 MDT 2009
This version just wraps the reopen code, so we still re-grab the lock and do
the normal sanity checks.
The reason we do this at all is to avoid global fd limits, see:
http://forums.fedoraforum.org/showthread.php?t=210393
Note also that this whole reopen concept is fundamentally racy: if the parent
goes away before the child calls tdb_reopen_all, the database can be left
without an active lock and another TDB_CLEAR_IF_FIRST opener will clear it.
A fork_with_tdbs() wrapper could use a pipe to solve this, but it's hardly
elegant (what if there are other independent things which have similar needs?).
Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
---
lib/tdb/common/open.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c
index b19e4ce..eda4afd 100644
--- a/lib/tdb/common/open.c
+++ b/lib/tdb/common/open.c
@@ -425,6 +425,9 @@ int tdb_reopen(struct tdb_context *tdb)
goto fail;
}
+/* If we have real pread & pwrite, we can skip reopen. */
+#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
+ !defined(LIBREPLACE_PWRITE_NOT_REPLACED)
if (tdb_munmap(tdb) != 0) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
goto fail;
@@ -436,11 +439,6 @@ int tdb_reopen(struct tdb_context *tdb)
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
goto fail;
}
- if ((tdb->flags & TDB_CLEAR_IF_FIRST) &&
- (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) {
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
- goto fail;
- }
if (fstat(tdb->fd, &st) != 0) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
goto fail;
@@ -450,6 +448,13 @@ int tdb_reopen(struct tdb_context *tdb)
goto fail;
}
tdb_mmap(tdb);
+#endif /* fake pread or pwrite */
+
+ if ((tdb->flags & TDB_CLEAR_IF_FIRST) &&
+ (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) {
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
+ goto fail;
+ }
return 0;
--
1.6.0.4
More information about the samba-technical
mailing list