diff options
Diffstat (limited to 'source4/lib/ldb/ldb_tdb')
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 30 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.h | 4 | ||||
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c | 115 |
3 files changed, 127 insertions, 22 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 0c8d2cea3e..40cfe97c29 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -819,16 +819,6 @@ static const struct ldb_module_ops ltdb_ops = { /* - destroy the ltdb context -*/ -static int ltdb_destructor(void *p) -{ - struct ltdb_private *ltdb = p; - tdb_close(ltdb->tdb); - return 0; -} - -/* connect to the database */ int ltdb_connect(struct ldb_context *ldb, const char *url, @@ -837,7 +827,6 @@ int ltdb_connect(struct ldb_context *ldb, const char *url, const char *path; int tdb_flags, open_flags; struct ltdb_private *ltdb; - TDB_CONTEXT *tdb; /* parse the url */ if (strchr(url, ':')) { @@ -858,24 +847,21 @@ int ltdb_connect(struct ldb_context *ldb, const char *url, open_flags = O_CREAT | O_RDWR; } - /* note that we use quite a large default hash size */ - tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666); - if (!tdb) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); - return -1; - } - ltdb = talloc_zero(ldb, struct ltdb_private); if (!ltdb) { - tdb_close(tdb); ldb_oom(ldb); return -1; } - ltdb->tdb = tdb; - ltdb->sequence_number = 0; + /* note that we use quite a large default hash size */ + ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, tdb_flags, open_flags, 0666); + if (!ltdb->tdb) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); + talloc_free(ltdb); + return -1; + } - talloc_set_destructor(ltdb, ltdb_destructor); + ltdb->sequence_number = 0; ldb->modules = talloc(ldb, struct ldb_module); if (!ldb->modules) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 46c5843d60..9ee3bfb70f 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -105,3 +105,7 @@ int ltdb_unlock_read(struct ldb_module *module); int ltdb_index_del_value(struct ldb_module *module, const char *dn, struct ldb_message_element *el, int v_idx); +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, int tdb_flags, + int open_flags, mode_t mode); + diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c new file mode 100644 index 0000000000..f58ec7f7ff --- /dev/null +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c @@ -0,0 +1,115 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "includes.h" +#include "ldb/include/ldb.h" +#include "ldb/include/ldb_private.h" +#include "ldb/ldb_tdb/ldb_tdb.h" + +/* + the purpose of this code is to work around the braindead posix locking + rules, to allow us to have a ldb open more than once while allowing + locking to work +*/ + +struct ltdb_wrap { + struct ltdb_wrap *next, *prev; + struct tdb_context *tdb; + dev_t device; + ino_t inode; +}; + +static struct ltdb_wrap *tdb_list; + +/* destroy the last connection to a tdb */ +static int ltdb_wrap_destructor(void *ctx) +{ + struct ltdb_wrap *w = talloc_get_type(ctx, struct ltdb_wrap); + tdb_close(w->tdb); + if (w->next) { + w->next->prev = w->prev; + } + if (w->prev) { + w->prev->next = w->next; + } + if (w == tdb_list) { + tdb_list = w->next; + } + return 0; +} + +/* + wrapped connection to a tdb database. The caller should _not_ free + this as it is not a talloc structure (as tdb does not use talloc + yet). It will auto-close when the caller frees the mem_ctx that is + passed to this call + */ +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + struct ltdb_wrap *w; + struct stat st; + + if (stat(path, &st) == 0) { + for (w=tdb_list;w;w=w->next) { + if (st.st_dev == w->device && st.st_ino == w->inode) { + talloc_reference(mem_ctx, w); + return w->tdb; + } + } + } + + w = talloc(mem_ctx, struct ltdb_wrap); + if (w == NULL) { + return NULL; + } + + w->tdb = tdb_open(path, hash_size, tdb_flags, open_flags, mode); + if (w->tdb == NULL) { + talloc_free(w); + return NULL; + } + + if (fstat(w->tdb->fd, &st) != 0) { + tdb_close(w->tdb); + talloc_free(w); + return NULL; + } + + w->device = st.st_dev; + w->inode = st.st_ino; + + talloc_set_destructor(w, ltdb_wrap_destructor); + + w->next = tdb_list; + w->prev = NULL; + if (tdb_list) { + tdb_list->prev = w; + } + tdb_list = w; + + return w->tdb; +} + |