diff options
Diffstat (limited to 'ctdb/lib/util/db_wrap.c')
-rw-r--r-- | ctdb/lib/util/db_wrap.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/ctdb/lib/util/db_wrap.c b/ctdb/lib/util/db_wrap.c new file mode 100644 index 0000000000..1b2bf7e228 --- /dev/null +++ b/ctdb/lib/util/db_wrap.c @@ -0,0 +1,103 @@ +/* + Unix SMB/CIFS implementation. + + database wrap functions + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +/* + the stupidity of the unix fcntl locking design forces us to never + allow a database file to be opened twice in the same process. These + wrappers provide convenient access to a tdb or ldb, taking advantage + of talloc destructors to ensure that only a single open is done +*/ + +#include "includes.h" +#include "lib/util/dlinklist.h" +#include "tdb.h" +#include "db_wrap.h" + +static struct tdb_wrap *tdb_list; + + + +/* destroy the last connection to a tdb */ +static int tdb_wrap_destructor(struct tdb_wrap *w) +{ + tdb_close(w->tdb); + DLIST_REMOVE(tdb_list, w); + return 0; +} + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + if (level <= TDB_DEBUG_ERROR) { + va_list ap; + this_log_level = level; + char newfmt[strlen(tdb_name(tdb)) + 1 + strlen(fmt) + 1]; + sprintf(newfmt, "%s:%s", tdb_name(tdb), fmt); + va_start(ap, fmt); + do_debug_v(newfmt, ap); + va_end(ap); + } +} + + +/* + wrapped connection to a tdb database + to close just talloc_free() the tdb_wrap pointer + */ +struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + struct tdb_wrap *w; + struct tdb_logging_context log_ctx; + + log_ctx.log_fn = log_fn; + log_ctx.log_private = NULL; + + for (w=tdb_list;w;w=w->next) { + if (strcmp(name, w->name) == 0) { + return talloc_reference(mem_ctx, w); + } + } + + w = talloc(mem_ctx, struct tdb_wrap); + if (w == NULL) { + return NULL; + } + + w->name = talloc_strdup(w, name); + if (w->name == NULL) { + talloc_free(w); + return NULL; + } + + w->tdb = tdb_open_ex(name, hash_size, tdb_flags, + open_flags, mode, &log_ctx, NULL); + if (w->tdb == NULL) { + talloc_free(w); + return NULL; + } + + talloc_set_destructor(w, tdb_wrap_destructor); + + DLIST_ADD(tdb_list, w); + + return w; +} |