increase the listen queue. Now that the eventscripts may become clients and connect...
[sahlberg/ctdb.git] / server / ctdb_daemon.c
index 83fcc0aa53779eba88fb8dd66262a90c6fbd684a..e730d76f55f9a65a5db6bee226dc6c191a8129c2 100644 (file)
 
 static void daemon_incoming_packet(void *, struct ctdb_req_header *);
 
-/*
-  handler for when a node changes its flags
-*/
-static void flag_change_handler(struct ctdb_context *ctdb, uint64_t srvid, 
-                               TDB_DATA data, void *private_data)
-{
-       struct ctdb_node_flag_change *c = (struct ctdb_node_flag_change *)data.dptr;
-
-       if (data.dsize != sizeof(*c) || !ctdb_validate_pnn(ctdb, c->pnn)) {
-               DEBUG(DEBUG_CRIT,(__location__ "Invalid data in ctdb_node_flag_change\n"));
-               return;
-       }
-
-       if (!ctdb_validate_pnn(ctdb, c->pnn)) {
-               DEBUG(DEBUG_CRIT,("Bad pnn %u in flag_change_handler\n", c->pnn));
-               return;
-       }
-
-       /* don't get the disconnected flag from the other node */
-       ctdb->nodes[c->pnn]->flags = 
-               (ctdb->nodes[c->pnn]->flags&NODE_FLAGS_DISCONNECTED) 
-               | (c->new_flags & ~NODE_FLAGS_DISCONNECTED);    
-       DEBUG(DEBUG_INFO,("Node flags for node %u are now 0x%x\n", c->pnn, ctdb->nodes[c->pnn]->flags));
-
-       /* make sure we don't hold any IPs when we shouldn't */
-       if (c->pnn == ctdb->pnn &&
-           (ctdb->nodes[c->pnn]->flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_BANNED))) {
-               ctdb_release_all_ips(ctdb);
-       }
-}
 
 static void print_exit_message(void)
 {
@@ -91,10 +61,6 @@ static void ctdb_start_transport(struct ctdb_context *ctdb)
        /* Make sure we log something when the daemon terminates */
        atexit(print_exit_message);
 
-       /* a handler for when nodes are disabled/enabled */
-       ctdb_register_message_handler(ctdb, ctdb, CTDB_SRVID_NODE_FLAGS_CHANGED, 
-                                     flag_change_handler, NULL);
-
        /* start monitoring for connected/disconnected nodes */
        ctdb_start_keepalive(ctdb);
 
@@ -103,6 +69,9 @@ static void ctdb_start_transport(struct ctdb_context *ctdb)
 
        /* start periodic update of tcp tickle lists */
                ctdb_start_tcp_tickle_update(ctdb);
+
+       /* start listening for recovery daemon pings */
+       ctdb_control_recd_ping(ctdb);
 }
 
 static void block_signal(int signum)
@@ -210,6 +179,12 @@ static int ctdb_client_destructor(struct ctdb_client *client)
        ctdb_takeover_client_destructor_hook(client);
        ctdb_reqid_remove(client->ctdb, client->client_id);
        client->ctdb->statistics.num_clients--;
+
+       if (client->num_persistent_updates != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " Client disconnecting with %u persistent updates in flight. Starting recovery\n", client->num_persistent_updates));
+               client->ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
+       }
+
        return 0;
 }
 
@@ -260,6 +235,7 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
        int res;
        uint32_t length;
        struct ctdb_client *client = dstate->client;
+       struct ctdb_db_context *ctdb_db = state->ctdb_db;
 
        talloc_steal(client, dstate);
        talloc_steal(dstate, dstate->call);
@@ -268,7 +244,7 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
        if (res != 0) {
                DEBUG(DEBUG_ERR, (__location__ " ctdbd_call_recv() returned error\n"));
                client->ctdb->statistics.pending_calls--;
-               ctdb_latency(&client->ctdb->statistics.max_call_latency, dstate->start_time);
+               ctdb_latency(ctdb_db, "call_from_client_cb 1", &client->ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
 
@@ -278,7 +254,7 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
        if (r == NULL) {
                DEBUG(DEBUG_ERR, (__location__ " Failed to allocate reply_call in ctdb daemon\n"));
                client->ctdb->statistics.pending_calls--;
-               ctdb_latency(&client->ctdb->statistics.max_call_latency, dstate->start_time);
+               ctdb_latency(ctdb_db, "call_from_client_cb 2", &client->ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
        r->hdr.reqid        = dstate->reqid;
@@ -289,7 +265,7 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
        if (res != 0) {
                DEBUG(DEBUG_ERR, (__location__ " Failed to queue packet from daemon to client\n"));
        }
-       ctdb_latency(&client->ctdb->statistics.max_call_latency, dstate->start_time);
+       ctdb_latency(ctdb_db, "call_from_client_cb 3", &client->ctdb->statistics.max_call_latency, dstate->start_time);
        talloc_free(dstate);
        client->ctdb->statistics.pending_calls--;
 }
@@ -397,7 +373,7 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
                ctdb_ltdb_unlock(ctdb_db, key);
                DEBUG(DEBUG_ERR,(__location__ " Unable to allocate call\n"));
                ctdb->statistics.pending_calls--;
-               ctdb_latency(&ctdb->statistics.max_call_latency, dstate->start_time);
+               ctdb_latency(ctdb_db, "call_from_client 1", &ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
 
@@ -418,7 +394,7 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        if (state == NULL) {
                DEBUG(DEBUG_ERR,(__location__ " Unable to setup call send\n"));
                ctdb->statistics.pending_calls--;
-               ctdb_latency(&ctdb->statistics.max_call_latency, dstate->start_time);
+               ctdb_latency(ctdb_db, "call_from_client 2", &ctdb->statistics.max_call_latency, dstate->start_time);
                return;
        }
        talloc_steal(state, dstate);
@@ -529,7 +505,7 @@ static void ctdb_daemon_read_cb(uint8_t *data, size_t cnt, void *args)
 static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde, 
                         uint16_t flags, void *private_data)
 {
-       struct sockaddr_in addr;
+       struct sockaddr_un addr;
        socklen_t len;
        int fd;
        struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
@@ -606,7 +582,7 @@ static int ux_socket_bind(struct ctdb_context *ctdb)
        } 
 
 
-       if (listen(ctdb->daemon.sd, 10) != 0) {
+       if (listen(ctdb->daemon.sd, 100) != 0) {
                DEBUG(DEBUG_CRIT,("Unable to listen on ctdb socket '%s'\n", ctdb->daemon.name));
                goto failed;
        }
@@ -628,6 +604,27 @@ static int unlink_destructor(const char *name)
        return 0;
 }
 
+static void sig_child_handler(struct event_context *ev,
+       struct signal_event *se, int signum, int count,
+       void *dont_care, 
+       void *private_data)
+{
+//     struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
+       int status;
+       pid_t pid = -1;
+
+       while (pid != 0) {
+               pid = waitpid(-1, &status, WNOHANG);
+               if (pid == -1) {
+                       DEBUG(DEBUG_ERR, (__location__ " waitpid() returned error. errno:%d\n", errno));
+                       return;
+               }
+               if (pid > 0) {
+                       DEBUG(DEBUG_DEBUG, ("SIGCHLD from %d\n", (int)pid));
+               }
+       }
+}
+
 /*
   start the protocol going as a daemon
 */
@@ -636,6 +633,7 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork)
        int res, ret = -1;
        struct fd_event *fde;
        const char *domain_socket_name;
+       struct signal_event *se;
 
        /* get rid of any old sockets */
        unlink(ctdb->daemon.name);
@@ -731,9 +729,16 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork)
        /* start the transport going */
        ctdb_start_transport(ctdb);
 
-       /* we dont want any SIGCHLD */
-       signal(SIGCHLD, SIG_IGN);
-
+       /* set up a handler to pick up sigchld */
+       se = event_add_signal(ctdb->ev, ctdb,
+                                    SIGCHLD, 0,
+                                    sig_child_handler,
+                                    ctdb);
+       if (se == NULL) {
+               DEBUG(DEBUG_CRIT,("Failed to set up signal handler for SIGCHLD\n"));
+               exit(1);
+       }
+         
        /* go into a wait loop to allow other nodes to complete */
        event_loop_wait(ctdb->ev);