1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-01 04:58:35 +03:00
samba-mirror/ctdb/tcp/tcp_init.c
Martin Schwenke a5be2c245d ctdb-daemon: Store node addresses as ctdb_sock_addr rather than strings
Every time a nodemap is contructed the node IP addresses all need to
be parsed.  This isn't very productive use of CPU.

Instead, parse each string once when the nodes file is loaded.  This
results in much simpler code.

This code also removes the use of ctdb_address.  Duplicating the port
is pointless without an abstraction layer around ctdb_address.  If
CTDB gets an incompatible transport in the future then add an
abstraction layer.

Note that the infiniband code is not updated.  Compilation of the
infiniband code is already broken.  Fixing it will be a separate,
properly tested effort.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Pair-programmed-with: Amitay Isaacs <amitay@gmail.com>
2015-03-23 12:23:12 +01:00

202 lines
4.7 KiB
C

/*
ctdb over TCP
Copyright (C) Andrew Tridgell 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "tdb.h"
#include "system/network.h"
#include "system/filesys.h"
#include "../include/ctdb_private.h"
#include "ctdb_tcp.h"
static int tnode_destructor(struct ctdb_tcp_node *tnode)
{
// struct ctdb_node *node = talloc_find_parent_bytype(tnode, struct ctdb_node);
if (tnode->fd != -1) {
close(tnode->fd);
tnode->fd = -1;
}
return 0;
}
/*
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;
}
/*
initialise transport structures
*/
static int ctdb_tcp_initialise(struct ctdb_context *ctdb)
{
int i;
/* listen on our own address */
if (ctdb_tcp_listen(ctdb) != 0) {
DEBUG(DEBUG_CRIT, (__location__ " Failed to start listening on the CTDB socket\n"));
exit(1);
}
for (i=0; i < ctdb->num_nodes; i++) {
if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
continue;
}
if (ctdb_tcp_add_node(ctdb->nodes[i]) != 0) {
DEBUG(DEBUG_CRIT, ("methods->add_node failed at %d\n", i));
return -1;
}
}
return 0;
}
/*
start the protocol going
*/
static int ctdb_tcp_connect_node(struct ctdb_node *node)
{
struct ctdb_context *ctdb = node->ctdb;
struct ctdb_tcp_node *tnode = talloc_get_type(
node->private_data, struct ctdb_tcp_node);
/* startup connection to the other server - will happen on
next event loop */
if (!ctdb_same_address(ctdb->address, &node->address)) {
tnode->connect_te = event_add_timed(ctdb->ev, tnode,
timeval_zero(),
ctdb_tcp_node_connect, node);
}
return 0;
}
/*
shutdown and try to restart a connection to a node after it has been
disconnected
*/
static void ctdb_tcp_restart(struct ctdb_node *node)
{
struct ctdb_tcp_node *tnode = talloc_get_type(
node->private_data, struct ctdb_tcp_node);
DEBUG(DEBUG_NOTICE,("Tearing down connection to dead node :%d\n", node->pnn));
ctdb_tcp_stop_connection(node);
tnode->connect_te = event_add_timed(node->ctdb->ev, tnode, timeval_zero(),
ctdb_tcp_node_connect, node);
}
/*
shutdown the transport
*/
static void ctdb_tcp_shutdown(struct ctdb_context *ctdb)
{
struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data,
struct ctdb_tcp);
talloc_free(ctcp);
ctdb->private_data = NULL;
}
/*
start the transport
*/
static int ctdb_tcp_start(struct ctdb_context *ctdb)
{
int i;
for (i=0; i < ctdb->num_nodes; i++) {
if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
continue;
}
ctdb_tcp_connect_node(ctdb->nodes[i]);
}
return 0;
}
/*
transport packet allocator - allows transport to control memory for packets
*/
static void *ctdb_tcp_allocate_pkt(TALLOC_CTX *mem_ctx, size_t size)
{
/* tcp transport needs to round to 8 byte alignment to ensure
that we can use a length header and 64 bit elements in
structures */
size = (size+(CTDB_TCP_ALIGNMENT-1)) & ~(CTDB_TCP_ALIGNMENT-1);
return talloc_size(mem_ctx, size);
}
static const struct ctdb_methods ctdb_tcp_methods = {
.initialise = ctdb_tcp_initialise,
.start = ctdb_tcp_start,
.queue_pkt = ctdb_tcp_queue_pkt,
.add_node = ctdb_tcp_add_node,
.connect_node = ctdb_tcp_connect_node,
.allocate_pkt = ctdb_tcp_allocate_pkt,
.shutdown = ctdb_tcp_shutdown,
.restart = ctdb_tcp_restart,
};
static int tcp_ctcp_destructor(struct ctdb_tcp *ctcp)
{
ctcp->ctdb->private_data = NULL;
ctcp->ctdb->methods = NULL;
return 0;
}
/*
initialise tcp portion of ctdb
*/
int ctdb_tcp_init(struct ctdb_context *ctdb)
{
struct ctdb_tcp *ctcp;
ctcp = talloc_zero(ctdb, struct ctdb_tcp);
CTDB_NO_MEMORY(ctdb, ctcp);
ctcp->listen_fd = -1;
ctcp->ctdb = ctdb;
ctdb->private_data = ctcp;
ctdb->methods = &ctdb_tcp_methods;
talloc_set_destructor(ctcp, tcp_ctcp_destructor);
return 0;
}