]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-recovery: Factor out reclock testing into ctdb_cluster_mutex()
authorMartin Schwenke <martin@meltin.net>
Tue, 12 Jan 2016 03:18:27 +0000 (14:18 +1100)
committerAmitay Isaacs <amitay@samba.org>
Thu, 28 Apr 2016 07:39:16 +0000 (09:39 +0200)
This is currently only used to check whether the recovery lock can be
taken.  However, name it more generally in anticipation of using it
for general cluster mutex taking and testing.

No functional changes.  A couple of debug message simplifications and
code rearrangements.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/server/ctdb_recover.c

index 9da9be1c8f55ec22dc2cbd9696aa4e292036d717..c6d01153ccc149ba2476f731f2ad98957fc5d820 100644 (file)
@@ -901,6 +901,92 @@ ctdb_drop_all_ips_event(struct tevent_context *ev, struct tevent_timer *te,
        ctdb_release_all_ips(ctdb);
 }
 
+static struct ctdb_cluster_mutex_handle *
+ctdb_cluster_mutex(struct ctdb_context *ctdb)
+{
+       struct ctdb_cluster_mutex_handle *h;
+       pid_t parent = getpid();
+       int ret;
+
+       h = talloc(ctdb, struct ctdb_cluster_mutex_handle);
+       if (h == NULL) {
+               DEBUG(DEBUG_ERR, (__location__ " out of memory\n"));
+               return NULL;
+       }
+
+       h->start_time = timeval_current();
+       h->fd[0] = -1;
+       h->fd[1] = -1;
+
+       /* For the rest of what needs to be done, we need to do this in
+          a child process since
+          1, the call to ctdb_recovery_lock() can block if the cluster
+             filesystem is in the process of recovery.
+       */
+       ret = pipe(h->fd);
+       if (ret != 0) {
+               talloc_free(h);
+               DEBUG(DEBUG_ERR, (__location__ " Failed to open pipe\n"));
+               return NULL;
+       }
+
+       h->child = ctdb_fork(ctdb);
+       if (h->child == (pid_t)-1) {
+               close(h->fd[0]);
+               close(h->fd[1]);
+               talloc_free(h);
+               return NULL;
+       }
+
+       if (h->child == 0) {
+               char cc = '1';
+               close(h->fd[0]);
+
+               prctl_set_comment("ctdb_cluster_mutex");
+               debug_extra = talloc_asprintf(NULL, "cluster_mutex:");
+               /* Daemon should not be able to get the recover lock,
+                * as it should be held by the recovery master */
+               if (ctdb_recovery_lock(ctdb)) {
+                       DEBUG(DEBUG_ERR,
+                             ("ERROR: Daemon able to take recovery lock on \"%s\" during recovery\n",
+                              ctdb->recovery_lock_file));
+                       ctdb_recovery_unlock(ctdb);
+                       cc = '0';
+               }
+
+               sys_write(h->fd[1], &cc, 1);
+               ctdb_wait_for_process_to_exit(parent);
+               _exit(0);
+       }
+
+       DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d\n", h->fd[0]));
+       set_close_on_exec(h->fd[0]);
+
+       close(h->fd[1]);
+       h->fd[1] = -1;
+
+       talloc_set_destructor(h, cluster_mutex_destructor);
+
+       h->te = tevent_add_timer(ctdb->ev, h, timeval_current_ofs(5, 0),
+                                cluster_mutex_timeout, h);
+
+       h->fde = tevent_add_fd(ctdb->ev, h, h->fd[0], TEVENT_FD_READ,
+                              cluster_mutex_handler, (void *)h);
+
+       if (h->fde == NULL) {
+               talloc_free(h);
+               return NULL;
+       }
+       tevent_fd_set_auto_close(h->fde);
+
+       h->ctdb = ctdb;
+       h->handler = NULL;
+       h->private_data = NULL;
+
+       return h;
+}
+
+
 /*
  * Set up an event to drop all public ips if we remain in recovery for too
  * long
@@ -928,10 +1014,9 @@ int32_t ctdb_control_set_recmode(struct ctdb_context *ctdb,
                                 const char **errormsg)
 {
        uint32_t recmode = *(uint32_t *)indata.dptr;
-       int i, ret;
-       struct ctdb_cluster_mutex_handle *h;
-       pid_t parent = getpid();
+       int i;
        struct ctdb_db_context *ctdb_db;
+       struct ctdb_cluster_mutex_handle *h;
 
        /* if we enter recovery but stay in recovery for too long
           we will eventually drop all our ip addresses
@@ -989,72 +1074,12 @@ int32_t ctdb_control_set_recmode(struct ctdb_context *ctdb,
                return 0;
        }
 
-       h = talloc(ctdb, struct ctdb_cluster_mutex_handle);
-       CTDB_NO_MEMORY(ctdb, h);
-
-       h->start_time = timeval_current();
-       h->fd[0] = -1;
-       h->fd[1] = -1;
-
-       /* For the rest of what needs to be done, we need to do this in
-          a child process since 
-          1, the call to ctdb_recovery_lock() can block if the cluster
-             filesystem is in the process of recovery.
-       */
-       ret = pipe(h->fd);
-       if (ret != 0) {
-               talloc_free(h);
-               DEBUG(DEBUG_CRIT,(__location__ " Failed to open pipe for set_recmode child\n"));
-               return -1;
-       }
-
-       h->child = ctdb_fork(ctdb);
-       if (h->child == (pid_t)-1) {
-               close(h->fd[0]);
-               close(h->fd[1]);
-               talloc_free(h);
+       h = ctdb_cluster_mutex(ctdb);
+       if (h == NULL) {
                return -1;
        }
 
-       if (h->child == 0) {
-               char cc = '1';
-               close(h->fd[0]);
-
-               prctl_set_comment("ctdb_recmode");
-               debug_extra = talloc_asprintf(NULL, "set_recmode:");
-               /* Daemon should not be able to get the recover lock,
-                * as it should be held by the recovery master */
-               if (ctdb_recovery_lock(ctdb)) {
-                       ctdb_recovery_unlock(ctdb);
-                       cc = '0';
-               }
-
-               sys_write(h->fd[1], &cc, 1);
-               ctdb_wait_for_process_to_exit(parent);
-               _exit(0);
-       }
-       close(h->fd[1]);
-       set_close_on_exec(h->fd[0]);
-
-       h->fd[1] = -1;
-
-       talloc_set_destructor(h, cluster_mutex_destructor);
-
-       DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d for setrecmode\n", h->fd[0]));
-
-       h->te = tevent_add_timer(ctdb->ev, h, timeval_current_ofs(5, 0),
-                                cluster_mutex_timeout, h);
-
-       h->fde = tevent_add_fd(ctdb->ev, h, h->fd[0], TEVENT_FD_READ,
-                              cluster_mutex_handler, (void *)h);
-
-       if (h->fde == NULL) {
-               talloc_free(h);
-               return -1;
-       }
-       tevent_fd_set_auto_close(h->fde);
-
-       h->ctdb = ctdb;
+       /* set_recmode_handler() frees h */
        h->handler = set_recmode_handler;
        h->private_data = talloc_steal(h, c);