diff options
author | Amitay Isaacs <amitay@gmail.com> | 2012-05-09 15:09:51 +1000 |
---|---|---|
committer | Amitay Isaacs <amitay@gmail.com> | 2012-10-20 02:48:44 +1100 |
commit | 23f83d58a5b546a8c14c9b4986a244227e4e7684 (patch) | |
tree | 83cd1ca440984c209516408fe4d0da4d157fd094 | |
parent | cbf16856f819fc0604dc66d54cc67c9df068ccff (diff) | |
download | samba-23f83d58a5b546a8c14c9b4986a244227e4e7684.tar.gz samba-23f83d58a5b546a8c14c9b4986a244227e4e7684.tar.xz samba-23f83d58a5b546a8c14c9b4986a244227e4e7684.zip |
ctdb_freeze: Replace locking functions with locking API
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
(This used to be ctdb commit 01ee86d2aafbcda658ef6acc2bba6d6781ae4047)
-rw-r--r-- | ctdb/server/ctdb_freeze.c | 158 |
1 files changed, 18 insertions, 140 deletions
diff --git a/ctdb/server/ctdb_freeze.c b/ctdb/server/ctdb_freeze.c index 7d17899fbe..88384f90a9 100644 --- a/ctdb/server/ctdb_freeze.c +++ b/ctdb/server/ctdb_freeze.c @@ -26,52 +26,6 @@ #include "db_wrap.h" #include "../common/rb_tree.h" -static bool later_db(const char *name) -{ - return (strstr(name, "notify") || strstr(name, "serverid")); -} - -/* - lock all databases - */ -static int ctdb_lock_all_databases(struct ctdb_context *ctdb, uint32_t priority) -{ - struct ctdb_db_context *ctdb_db; - /* REMOVE later */ - /* This double loop is for backward compatibility and deadlock - avoidance for old samba versions that not yet support - the set prio call. - This code shall be removed later - */ - for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) { - if (ctdb_db->priority != priority) { - continue; - } - if (later_db(ctdb_db->db_name)) { - continue; - } - DEBUG(DEBUG_INFO,("locking database 0x%08x priority:%u %s\n", ctdb_db->db_id, ctdb_db->priority, ctdb_db->db_name)); - if (tdb_lockall(ctdb_db->ltdb->tdb) != 0) { - DEBUG(DEBUG_ERR,(__location__ " Failed to lock database %s\n", ctdb_db->db_name)); - return -1; - } - } - for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) { - if (ctdb_db->priority != priority) { - continue; - } - if (!later_db(ctdb_db->db_name)) { - continue; - } - DEBUG(DEBUG_INFO,("locking database 0x%08x priority:%u %s\n", ctdb_db->db_id, ctdb_db->priority, ctdb_db->db_name)); - if (tdb_lockall(ctdb_db->ltdb->tdb) != 0) { - DEBUG(DEBUG_ERR,(__location__ " Failed to lock database %s\n", ctdb_db->db_name)); - return -1; - } - } - return 0; -} - /* a list of control requests waiting for a freeze lock child to get the database locks @@ -88,8 +42,7 @@ struct ctdb_freeze_waiter { struct ctdb_freeze_handle { struct ctdb_context *ctdb; uint32_t priority; - pid_t child; - int fd; + struct lock_request *lreq; struct ctdb_freeze_waiter *waiters; }; @@ -122,18 +75,17 @@ static int ctdb_freeze_handle_destructor(struct ctdb_freeze_handle *h) ctdb->freeze_mode[h->priority] = CTDB_FREEZE_NONE; ctdb->freeze_handles[h->priority] = NULL; - ctdb_kill(h->ctdb, h->child, SIGKILL); + ctdb_lock_free_request_context(h->lreq); return 0; } /* called when the child writes its status to us */ -static void ctdb_freeze_lock_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private_data) +static void ctdb_freeze_lock_handler(void *private_data, bool locked) { - struct ctdb_freeze_handle *h = talloc_get_type(private_data, struct ctdb_freeze_handle); - int32_t status; + struct ctdb_freeze_handle *h = talloc_get_type_abort(private_data, + struct ctdb_freeze_handle); struct ctdb_freeze_waiter *w; if (h->ctdb->freeze_mode[h->priority] == CTDB_FREEZE_FROZEN) { @@ -142,12 +94,7 @@ static void ctdb_freeze_lock_handler(struct event_context *ev, struct fd_event * return; } - if (read(h->fd, &status, sizeof(status)) != sizeof(status)) { - DEBUG(DEBUG_ERR,("read error from freeze lock child\n")); - status = -1; - } - - if (status == -1) { + if (!locked) { DEBUG(DEBUG_ERR,("Failed to get locks in ctdb_freeze_child\n")); /* we didn't get the locks - destroy the handle */ talloc_free(h); @@ -161,91 +108,13 @@ static void ctdb_freeze_lock_handler(struct event_context *ev, struct fd_event * DEBUG(DEBUG_ERR,("lockwait finished but h is not linked\n")); } while ((w = h->waiters)) { - w->status = status; + w->status = 0; DLIST_REMOVE(h->waiters, w); talloc_free(w); } } /* - create a child which gets locks on all the open databases, then calls the callback telling the parent - that it is done - */ -static struct ctdb_freeze_handle *ctdb_freeze_lock(struct ctdb_context *ctdb, uint32_t priority) -{ - struct ctdb_freeze_handle *h; - int fd[2]; - struct fd_event *fde; - - h = talloc_zero(ctdb, struct ctdb_freeze_handle); - CTDB_NO_MEMORY_NULL(ctdb, h); - - h->ctdb = ctdb; - h->priority = priority; - - if (pipe(fd) == -1) { - DEBUG(DEBUG_ERR,("Failed to create pipe for ctdb_freeze_lock\n")); - talloc_free(h); - return NULL; - } - - h->child = ctdb_fork(ctdb); - if (h->child == -1) { - DEBUG(DEBUG_ERR,("Failed to fork child for ctdb_freeze_lock\n")); - talloc_free(h); - return NULL; - } - - if (h->child == 0) { - int ret; - - /* in the child */ - close(fd[0]); - - debug_extra = talloc_asprintf(NULL, "freeze_lock-%u:", priority); - ret = ctdb_lock_all_databases(ctdb, priority); - if (ret != 0) { - _exit(0); - } - - ret = write(fd[1], &ret, sizeof(ret)); - if (ret != sizeof(ret)) { - DEBUG(DEBUG_ERR, (__location__ " Failed to write to socket from freeze child. ret:%d errno:%u\n", ret, errno)); - _exit(1); - } - - while (1) { - sleep(1); - if (ctdb_kill(ctdb, ctdb->ctdbd_pid, 0) != 0) { - DEBUG(DEBUG_ERR,("Parent died. Exiting lock wait child\n")); - - _exit(0); - } - } - } - - talloc_set_destructor(h, ctdb_freeze_handle_destructor); - - close(fd[1]); - set_close_on_exec(fd[0]); - - h->fd = fd[0]; - - - fde = event_add_fd(ctdb->ev, h, h->fd, EVENT_FD_READ, - ctdb_freeze_lock_handler, h); - if (fde == NULL) { - DEBUG(DEBUG_ERR,("Failed to setup fd event for ctdb_freeze_lock\n")); - close(fd[0]); - talloc_free(h); - return NULL; - } - tevent_fd_set_auto_close(fde); - - return h; -} - -/* destroy a waiter for a freeze mode change */ static int ctdb_freeze_waiter_destructor(struct ctdb_freeze_waiter *w) @@ -259,6 +128,8 @@ static int ctdb_freeze_waiter_destructor(struct ctdb_freeze_waiter *w) */ int ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority) { + struct ctdb_freeze_handle *h; + if (priority == 0) { DEBUG(DEBUG_ERR,("Freeze priority 0 requested, remapping to priority 1\n")); priority = 1; @@ -279,8 +150,15 @@ int ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority) /* if there isn't a freeze lock child then create one */ if (ctdb->freeze_handles[priority] == NULL) { - ctdb->freeze_handles[priority] = ctdb_freeze_lock(ctdb, priority); - CTDB_NO_MEMORY(ctdb, ctdb->freeze_handles[priority]); + h = talloc_zero(ctdb, struct ctdb_freeze_handle); + CTDB_NO_MEMORY(ctdb, h); + h->ctdb = ctdb; + h->priority = priority; + talloc_set_destructor(h, ctdb_freeze_handle_destructor); + + h->lreq = ctdb_lock_alldb_prio(ctdb, priority, false, ctdb_freeze_lock_handler, h); + CTDB_NO_MEMORY(ctdb, h->lreq); + ctdb->freeze_handles[priority] = h; ctdb->freeze_mode[priority] = CTDB_FREEZE_PENDING; } |