X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb%2Fopen.c;h=9a3457bc47555960ec0dce4b8665e3b242dfa446;hp=ed32cf327f0dd8a21fe86a39ae380c5d5f0a6c99;hb=05f69a4723f3a48502a699805c90c16489bf0525;hpb=c92d0d635e1dcbb1d7b6f3356d4ac01e6f1d2535 diff --git a/ccan/tdb/open.c b/ccan/tdb/open.c index ed32cf32..9a3457bc 100644 --- a/ccan/tdb/open.c +++ b/ccan/tdb/open.c @@ -161,7 +161,6 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, errno = ENOMEM; goto fail; } - tdb_io_init(tdb); tdb->fd = -1; #ifdef TDB_TRACE @@ -241,8 +240,8 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, 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 */ } @@ -341,7 +340,8 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, { 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); @@ -355,8 +355,8 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, 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; @@ -453,9 +453,7 @@ void *tdb_get_logging_private(struct tdb_context *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; @@ -484,11 +482,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->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; @@ -499,6 +492,12 @@ int tdb_reopen(struct tdb_context *tdb) } 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: @@ -506,12 +505,21 @@ 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 @@ -525,10 +533,10 @@ int tdb_reopen_all(int parent_longlived) */ 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; }