/* initialise tcp portion of a ctdb node */ static int ctdb_tcp_add_node(struct ctdb_node *node) { struct ctdb_tcp_node *tnode; tnode = talloc_zero(node, struct ctdb_tcp_node); CTDB_NO_MEMORY(node->ctdb, tnode); tnode->fd = -1; node->private_data = tnode; talloc_set_destructor(tnode, tnode_destructor); tnode->out_queue = ctdb_queue_setup(node->ctdb, node, tnode->fd, CTDB_TCP_ALIGNMENT, ctdb_tcp_tnode_cb, node, "to-node-%s", node->name); return 0; }
/* called when we get contacted by another node currently makes no attempt to check if the connection is really from a ctdb node in our cluster */ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data, struct ctdb_tcp); ctdb_sock_addr addr; socklen_t len; int fd, nodeid; struct ctdb_incoming *in; int one = 1; const char *incoming_node; memset(&addr, 0, sizeof(addr)); len = sizeof(addr); fd = accept(ctcp->listen_fd, (struct sockaddr *)&addr, &len); if (fd == -1) return; incoming_node = ctdb_addr_to_str(&addr); nodeid = ctdb_ip_to_nodeid(ctdb, incoming_node); if (nodeid == -1) { DEBUG(DEBUG_ERR, ("Refused connection from unknown node %s\n", incoming_node)); close(fd); return; } in = talloc_zero(ctcp, struct ctdb_incoming); in->fd = fd; in->ctdb = ctdb; set_nonblocking(in->fd); set_close_on_exec(in->fd); DEBUG(DEBUG_DEBUG, (__location__ " Created SOCKET FD:%d to incoming ctdb connection\n", fd)); if (setsockopt(in->fd,SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(one)) == -1) { DEBUG(DEBUG_WARNING, ("Failed to set KEEPALIVE on fd - %s\n", strerror(errno))); } in->queue = ctdb_queue_setup(ctdb, in, in->fd, CTDB_TCP_ALIGNMENT, ctdb_tcp_read_cb, in, "ctdbd-%s", incoming_node); }
static int pmda_ctdb_daemon_connect(void) { const char *socket_name; int ret; struct sockaddr_un addr; ev = tevent_context_init(NULL); if (ev == NULL) { fprintf(stderr, "Failed to init event ctx\n"); return -1; } ctdb = ctdb_init(ev); if (ctdb == NULL) { fprintf(stderr, "Failed to init ctdb\n"); goto err_ev; } socket_name = getenv("CTDB_SOCKET"); if (socket_name == NULL) { socket_name = CTDB_SOCKET; } ret = ctdb_set_socketname(ctdb, socket_name); if (ret == -1) { fprintf(stderr, "ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb)); goto err_ctdb; } /* * ctdb_socket_connect() sets a default queue callback handler that * calls exit() if ctdbd is unavailable on recv, use our own wrapper to * work around this */ memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path)); ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0); if (ctdb->daemon.sd == -1) { fprintf(stderr, "Failed to open client socket\n"); goto err_ctdb; } set_nonblocking(ctdb->daemon.sd); set_close_on_exec(ctdb->daemon.sd); if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { fprintf(stderr, "Failed to connect to ctdb daemon via %s\n", ctdb->daemon.name); goto err_sd; } ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd, CTDB_DS_ALIGNMENT, pmda_ctdb_q_read_cb, ctdb, "to-ctdbd"); if (ctdb->daemon.queue == NULL) { fprintf(stderr, "Failed to setup queue\n"); goto err_sd; } ctdb->pnn = ctdb_ctrl_getpnn(ctdb, timeval_current_ofs(3, 0), CTDB_CURRENT_NODE); if (ctdb->pnn == (uint32_t)-1) { fprintf(stderr, "Failed to get ctdb pnn\n"); goto err_sd; } return 0; err_sd: close(ctdb->daemon.sd); err_ctdb: talloc_free(ctdb); err_ev: talloc_free(ev); ctdb = NULL; return -1; }