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)
{
/* 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);
/* 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)
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;
}
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);
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;
}
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;
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--;
}
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;
}
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);
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);
}
- 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;
}
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
*/
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);
/* 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);