Add ctdb_fork(0 which will fork a child process and drop the real-time
[sahlberg/ctdb.git] / server / ctdb_traverse.c
index d66036f9a1c4de81a36b8c932cde89af0af82961..5ad374f098da6a8a498c7bfe3ec0640ebe2c7f45 100644 (file)
@@ -18,7 +18,7 @@
 */
 
 #include "includes.h"
-#include "lib/events/events.h"
+#include "lib/tevent/tevent.h"
 #include "system/filesys.h"
 #include "system/wait.h"
 #include "db_wrap.h"
@@ -153,7 +153,7 @@ static struct ctdb_traverse_local_handle *ctdb_traverse_local(struct ctdb_db_con
                return NULL;
        }
 
-       h->child = fork();
+       h->child = ctdb_fork(ctdb_db->ctdb);
 
        if (h->child == (pid_t)-1) {
                close(h->fd[0]);
@@ -171,6 +171,8 @@ static struct ctdb_traverse_local_handle *ctdb_traverse_local(struct ctdb_db_con
        if (h->child == 0) {
                /* start the traverse in the child */
                close(h->fd[0]);
+               debug_extra = talloc_asprintf(NULL, "traverse_local-%s:",
+                                             ctdb_db->db_name);
                tdb_traverse_read(ctdb_db->ltdb->tdb, ctdb_traverse_local_fn, h);
                _exit(0);
        }
@@ -186,9 +188,10 @@ static struct ctdb_traverse_local_handle *ctdb_traverse_local(struct ctdb_db_con
          setup a packet queue between the child and the parent. This
          copes with all the async and packet boundary issues
         */
-       DEBUG(DEBUG_NOTICE, (__location__ " Created PIPE FD:%d to child traverse\n", h->fd[0]));
+       DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child traverse\n", h->fd[0]));
 
-       h->queue = ctdb_queue_setup(ctdb_db->ctdb, h, h->fd[0], 0, ctdb_traverse_local_handler, h);
+       h->queue = ctdb_queue_setup(ctdb_db->ctdb, h, h->fd[0], 0, ctdb_traverse_local_handler, h,
+                                   "to-ctdbd");
        if (h->queue == NULL) {
                talloc_free(h);
                return NULL;
@@ -233,7 +236,7 @@ static void ctdb_traverse_all_timeout(struct event_context *ev, struct timed_eve
        struct ctdb_traverse_all_handle *state = talloc_get_type(private_data, struct ctdb_traverse_all_handle);
 
        DEBUG(DEBUG_ERR,(__location__ " Traverse all timeout on database:%s\n", state->ctdb_db->db_name));
-       state->ctdb->statistics.timeouts.traverse++;
+       CTDB_INCREMENT_STAT(state->ctdb, timeouts.traverse);
 
        state->callback(state->private_data, tdb_null, tdb_null);
 }
@@ -388,6 +391,16 @@ int32_t ctdb_control_traverse_all(struct ctdb_context *ctdb, TDB_DATA data, TDB_
                return -1;
        }
 
+       if (ctdb_db->unhealthy_reason) {
+               if (ctdb->tunable.allow_unhealthy_db_read == 0) {
+                       DEBUG(DEBUG_ERR,("db(%s) unhealty in ctdb_control_traverse_all: %s\n",
+                                       ctdb_db->db_name, ctdb_db->unhealthy_reason));
+                       return -1;
+               }
+               DEBUG(DEBUG_WARNING,("warn: db(%s) unhealty in ctdb_control_traverse_all: %s\n",
+                                    ctdb_db->db_name, ctdb_db->unhealthy_reason));
+       }
+
        state = talloc(ctdb_db, struct traverse_all_state);
        if (state == NULL) {
                return -1;
@@ -561,6 +574,16 @@ int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb, TDB_DATA data,
                return -1;
        }
 
+       if (ctdb_db->unhealthy_reason) {
+               if (ctdb->tunable.allow_unhealthy_db_read == 0) {
+                       DEBUG(DEBUG_ERR,("db(%s) unhealty in ctdb_control_traverse_start: %s\n",
+                                       ctdb_db->db_name, ctdb_db->unhealthy_reason));
+                       return -1;
+               }
+               DEBUG(DEBUG_WARNING,("warn: db(%s) unhealty in ctdb_control_traverse_start: %s\n",
+                                    ctdb_db->db_name, ctdb_db->unhealthy_reason));
+       }
+
        state = talloc(client, struct traverse_start_state);
        if (state == NULL) {
                return -1;