From 6504900f1f52927adab3489b8d04b6644ceaee7d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 08:06:51 +0000 Subject: r23806: update Samba4 with the latest ctdb code. This doesn't get the ctdb code fully working in Samba4, it just gets it building and not breaking non-clustered use of Samba. It will take a bit longer to update some of the calling ctdb_cluster.c code to make it work correctly in Samba4. Note also that Samba4 now only links to the client portion of ctdb. For the moment I am leaving the ctdbd as a separate daemon, which you install separately from http://ctdb.samba.org/. (This used to be commit b196077cbb55cbecad87065133c2d67198e31066) --- source4/cluster/ctdb/server/ctdb_lockwait.c | 165 ++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 source4/cluster/ctdb/server/ctdb_lockwait.c (limited to 'source4/cluster/ctdb/server/ctdb_lockwait.c') diff --git a/source4/cluster/ctdb/server/ctdb_lockwait.c b/source4/cluster/ctdb/server/ctdb_lockwait.c new file mode 100644 index 0000000000..5b0019836e --- /dev/null +++ b/source4/cluster/ctdb/server/ctdb_lockwait.c @@ -0,0 +1,165 @@ +/* + wait for a tdb chain lock + + Copyright (C) Andrew Tridgell 2006 + + 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 . +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "db_wrap.h" +#include "lib/tdb/include/tdb.h" +#include "../include/ctdb_private.h" + + +struct lockwait_handle { + struct ctdb_context *ctdb; + struct ctdb_db_context *ctdb_db; + struct fd_event *fde; + int fd[2]; + pid_t child; + void *private_data; + void (*callback)(void *); + TDB_DATA key; + struct timeval start_time; +}; + +static void lockwait_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private_data) +{ + struct lockwait_handle *h = talloc_get_type(private_data, + struct lockwait_handle); + void (*callback)(void *) = h->callback; + void *p = h->private_data; + pid_t child = h->child; + TDB_DATA key = h->key; + struct tdb_context *tdb = h->ctdb_db->ltdb->tdb; + TALLOC_CTX *tmp_ctx = talloc_new(ev); + + key.dptr = talloc_memdup(tmp_ctx, key.dptr, key.dsize); + + talloc_set_destructor(h, NULL); + ctdb_latency(&h->ctdb->statistics.max_lockwait_latency, h->start_time); + h->ctdb->statistics.pending_lockwait_calls--; + + /* the handle needs to go away when the context is gone - when + the handle goes away this implicitly closes the pipe, which + kills the child holding the lock */ + talloc_steal(tmp_ctx, h); + + if (h->ctdb->flags & CTDB_FLAG_TORTURE) { + if (tdb_chainlock_nonblock(tdb, key) == 0) { + ctdb_fatal(h->ctdb, "got chain lock while lockwait child active"); + } + } + + tdb_chainlock_mark(tdb, key); + callback(p); + tdb_chainlock_unmark(tdb, key); + + kill(child, SIGKILL); + waitpid(child, NULL, 0); + talloc_free(tmp_ctx); +} + +static int lockwait_destructor(struct lockwait_handle *h) +{ + h->ctdb->statistics.pending_lockwait_calls--; + kill(h->child, SIGKILL); + waitpid(h->child, NULL, 0); + return 0; +} + +/* + setup a non-blocking chainlock on a tdb record. If this function + returns NULL then it could not get the chainlock. Otherwise it + returns a opaque handle, and will call callback() once it has + managed to get the chainlock. You can cancel it by using talloc_free + on the returned handle. + + It is the callers responsibility to unlock the chainlock once + acquired + */ +struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db, + TDB_DATA key, + void (*callback)(void *private_data), + void *private_data) +{ + struct lockwait_handle *result; + int ret; + pid_t parent = getpid(); + + ctdb_db->ctdb->statistics.lockwait_calls++; + ctdb_db->ctdb->statistics.pending_lockwait_calls++; + + if (!(result = talloc_zero(private_data, struct lockwait_handle))) { + ctdb_db->ctdb->statistics.pending_lockwait_calls--; + return NULL; + } + + ret = pipe(result->fd); + + if (ret != 0) { + talloc_free(result); + ctdb_db->ctdb->statistics.pending_lockwait_calls--; + return NULL; + } + + result->child = fork(); + + if (result->child == (pid_t)-1) { + close(result->fd[0]); + close(result->fd[1]); + talloc_free(result); + ctdb_db->ctdb->statistics.pending_lockwait_calls--; + return NULL; + } + + result->callback = callback; + result->private_data = private_data; + result->ctdb = ctdb_db->ctdb; + result->ctdb_db = ctdb_db; + result->key = key; + + if (result->child == 0) { + char c = 0; + close(result->fd[0]); + tdb_chainlock(ctdb_db->ltdb->tdb, key); + write(result->fd[1], &c, 1); + /* make sure we die when our parent dies */ + while (kill(parent, 0) == 0 || errno != ESRCH) { + sleep(5); + } + _exit(0); + } + + close(result->fd[1]); + talloc_set_destructor(result, lockwait_destructor); + + result->fde = event_add_fd(ctdb_db->ctdb->ev, result, result->fd[0], + EVENT_FD_READ|EVENT_FD_AUTOCLOSE, lockwait_handler, + (void *)result); + if (result->fde == NULL) { + talloc_free(result); + ctdb_db->ctdb->statistics.pending_lockwait_calls--; + return NULL; + } + + result->start_time = timeval_current(); + + return result; +} -- cgit From 01bacaecd1c2db5e3810de3734d8cb71021116de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 16:18:02 +0100 Subject: r26101: remove some unused includes (This used to be commit bc615162fc515a8b8ae59af14cb1e80497e9afdd) --- source4/cluster/ctdb/server/ctdb_lockwait.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/cluster/ctdb/server/ctdb_lockwait.c') diff --git a/source4/cluster/ctdb/server/ctdb_lockwait.c b/source4/cluster/ctdb/server/ctdb_lockwait.c index 5b0019836e..2fc3e7a3ed 100644 --- a/source4/cluster/ctdb/server/ctdb_lockwait.c +++ b/source4/cluster/ctdb/server/ctdb_lockwait.c @@ -21,7 +21,6 @@ #include "lib/events/events.h" #include "system/filesys.h" #include "system/wait.h" -#include "db_wrap.h" #include "lib/tdb/include/tdb.h" #include "../include/ctdb_private.h" -- cgit