errno = ENOMEM;
goto fail;
}
-
tdb_io_init(tdb);
tdb->fd = -1;
#ifdef TDB_TRACE
}
/*
- * TDB_ALLOW_NESTING is the default behavior.
- * Note: this may change in future versions!
+ * TDB_DISALLOW_NESTING is the default behavior.
*/
- if (!(tdb->flags & TDB_DISALLOW_NESTING)) {
- tdb->flags |= TDB_ALLOW_NESTING;
+ if (!(tdb->flags & TDB_ALLOW_NESTING)) {
+ tdb->flags |= TDB_DISALLOW_NESTING;
}
/* internal databases don't mmap or lock, and start off cleared */
fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC);
/* ensure there is only one process initialising at once */
- if (tdb->methods->brlock(tdb, F_WRLCK, GLOBAL_LOCK, 1, TDB_LOCK_WAIT) == -1) {
- TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n",
+ if (tdb->methods->brlock(tdb, F_WRLCK, OPEN_LOCK, 1, TDB_LOCK_WAIT) == -1) {
+ TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n",
name, strerror(errno)));
goto fail; /* errno set by tdb_brlock */
}
{
char tracefile[strlen(name) + 32];
- sprintf(tracefile, "%s.trace.%u", name, getpid());
+ snprintf(tracefile, sizeof(tracefile),
+ "%s.trace.%li", name, (long)getpid());
tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
if (tdb->tracefd >= 0) {
tdb_enable_seqnum(tdb);
internal:
/* Internal (memory-only) databases skip all the code above to
* do with disk files, and resume here by releasing their
- * global lock and hooking into the active list. */
- if (tdb->methods->brunlock(tdb, F_WRLCK, GLOBAL_LOCK, 1) == -1)
+ * open lock and hooking into the active list. */
+ if (tdb->methods->brunlock(tdb, F_WRLCK, OPEN_LOCK, 1) == -1)
goto fail;
tdb->next = tdbs;
tdbs = tdb;
return tdb->log.log_private;
}
-/* reopen a tdb - this can be used after a fork to ensure that we have an independent
- seek pointer from our parent and to re-establish locks */
-int tdb_reopen(struct tdb_context *tdb)
+static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock)
{
struct stat st;
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->brlock(tdb, F_RDLCK, ACTIVE_LOCK, 1, TDB_LOCK_WAIT) == -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;
}
tdb_mmap(tdb);
+ if (active_lock &&
+ (tdb->methods->brlock(tdb, F_RDLCK, ACTIVE_LOCK, 1, TDB_LOCK_WAIT) == -1)) {
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
+ goto fail;
+ }
+
return 0;
fail:
return -1;
}
+/* reopen a tdb - this can be used after a fork to ensure that we have an independent
+ seek pointer from our parent and to re-establish locks */
+int tdb_reopen(struct tdb_context *tdb)
+{
+ return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST);
+}
+
/* reopen all tdb's */
int tdb_reopen_all(int parent_longlived)
{
struct tdb_context *tdb;
for (tdb=tdbs; tdb; tdb = tdb->next) {
+ bool active_lock = (tdb->flags & TDB_CLEAR_IF_FIRST);
+
/*
* If the parent is longlived (ie. a
* parent daemon architecture), we know
*/
if (parent_longlived) {
/* Ensure no clear-if-first. */
- tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+ active_lock = false;
}
- if (tdb_reopen(tdb) != 0)
+ if (tdb_reopen_internal(tdb, active_lock) != 0)
return -1;
}