diff options
author | Martin Schwenke <martin@meltin.net> | 2015-02-20 11:47:23 +1100 |
---|---|---|
committer | Amitay Isaacs <amitay@samba.org> | 2015-03-23 12:23:12 +0100 |
commit | a5be2c245d5634695bd23387913c7e2e2481879b (patch) | |
tree | 3d891e1e738045b5fd52a1dbd3b8a93315f6228c /ctdb/tcp | |
parent | 3cbeb17d0f9f1e4b6a3faa9aba2982793cf8494b (diff) | |
download | samba-a5be2c245d5634695bd23387913c7e2e2481879b.tar.gz |
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>
Diffstat (limited to 'ctdb/tcp')
-rw-r--r-- | ctdb/tcp/tcp_connect.c | 99 | ||||
-rw-r--r-- | ctdb/tcp/tcp_init.c | 2 |
2 files changed, 23 insertions, 78 deletions
diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c index 51aa21fc944..6950ac85522 100644 --- a/ctdb/tcp/tcp_connect.c +++ b/ctdb/tcp/tcp_connect.c @@ -111,16 +111,6 @@ static void ctdb_node_connect_write(struct event_context *ev, struct fd_event *f } -static int ctdb_tcp_get_address(struct ctdb_context *ctdb, - const char *address, ctdb_sock_addr *addr) -{ - if (parse_ip(address, NULL, 0, addr) == 0) { - DEBUG(DEBUG_CRIT, (__location__ " Unparsable address : %s.\n", address)); - return -1; - } - return 0; -} - /* called when we should try and establish a tcp connection to a node */ @@ -139,25 +129,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te, ctdb_tcp_stop_connection(node); - ZERO_STRUCT(sock_out); -#ifdef HAVE_SOCK_SIN_LEN - sock_out.ip.sin_len = sizeof(sock_out); -#endif - if (ctdb_tcp_get_address(ctdb, node->address.address, &sock_out) != 0) { - return; - } - switch (sock_out.sa.sa_family) { - case AF_INET: - sock_out.ip.sin_port = htons(node->address.port); - break; - case AF_INET6: - sock_out.ip6.sin6_port = htons(node->address.port); - break; - default: - DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n", - sock_out.sa.sa_family)); - return; - } + sock_out = node->address; tnode->fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if (tnode->fd == -1) { @@ -175,12 +147,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te, * the remote side is actually routable in case CTDB traffic will run on * a dedicated non-routeable network. */ - ZERO_STRUCT(sock_in); - if (ctdb_tcp_get_address(ctdb, ctdb->address.address, &sock_in) != 0) { - DEBUG(DEBUG_ERR, (__location__ " Failed to find our address. Failing bind.\n")); - close(tnode->fd); - return; - } + sock_in = *ctdb->address; /* AIX libs check to see if the socket address and length arguments are consistent with each other on calls like @@ -189,10 +156,12 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te, */ switch (sock_in.sa.sa_family) { case AF_INET: + sock_in.ip.sin_port = 0 /* Any port */; sockin_size = sizeof(sock_in.ip); sockout_size = sizeof(sock_out.ip); break; case AF_INET6: + sock_in.ip6.sin6_port = 0 /* Any port */; sockin_size = sizeof(sock_in.ip6); sockout_size = sizeof(sock_out.ip6); break; @@ -202,10 +171,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te, close(tnode->fd); return; } -#ifdef HAVE_SOCK_SIN_LEN - sock_in.ip.sin_len = sockin_size; - sock_out.ip.sin_len = sockout_size; -#endif + if (bind(tnode->fd, (struct sockaddr *)&sock_in, sockin_size) == -1) { DEBUG(DEBUG_ERR, (__location__ "Failed to bind socket %s(%d)\n", strerror(errno), errno)); @@ -249,18 +215,16 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde, 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); + nodeid = ctdb_ip_to_nodeid(ctdb, &addr); if (nodeid == -1) { - DEBUG(DEBUG_ERR, ("Refused connection from unknown node %s\n", incoming_node)); + DEBUG(DEBUG_ERR, ("Refused connection from unknown node %s\n", ctdb_addr_to_str(&addr))); close(fd); return; } @@ -279,8 +243,8 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde, strerror(errno))); } - in->queue = ctdb_queue_setup(ctdb, in, in->fd, CTDB_TCP_ALIGNMENT, - ctdb_tcp_read_cb, in, "ctdbd-%s", incoming_node); + in->queue = ctdb_queue_setup(ctdb, in, in->fd, CTDB_TCP_ALIGNMENT, + ctdb_tcp_read_cb, in, "ctdbd-%s", ctdb_addr_to_str(&addr)); } @@ -334,20 +298,13 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb) if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) { continue; } - ZERO_STRUCT(sock); - if (ctdb_tcp_get_address(ctdb, - ctdb->nodes[i]->address.address, - &sock) != 0) { - continue; - } - + sock = ctdb->nodes[i]->address; + switch (sock.sa.sa_family) { case AF_INET: - sock.ip.sin_port = htons(ctdb->nodes[i]->address.port); sock_size = sizeof(sock.ip); break; case AF_INET6: - sock.ip6.sin6_port = htons(ctdb->nodes[i]->address.port); sock_size = sizeof(sock.ip6); break; default: @@ -355,9 +312,6 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb) sock.sa.sa_family)); continue; } -#ifdef HAVE_SOCK_SIN_LEN - sock.ip.sin_len = sock_size; -#endif ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if (ctcp->listen_fd == -1) { @@ -390,14 +344,14 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb) DEBUG(DEBUG_CRIT,("Unable to bind to any of the node addresses - giving up\n")); goto failed; } - ctdb->address.address = talloc_strdup(ctdb, ctdb->nodes[i]->address.address); - ctdb->address.port = ctdb->nodes[i]->address.port; + ctdb->address = talloc_memdup(ctdb, + &ctdb->nodes[i]->address, + sizeof(ctdb_sock_addr)); + CTDB_NO_MEMORY(ctdb, ctdb->address); ctdb->name = talloc_asprintf(ctdb, "%s:%u", - ctdb->address.address, - ctdb->address.port); - DEBUG(DEBUG_INFO,("ctdb chose network address %s:%u\n", - ctdb->address.address, - ctdb->address.port)); + ctdb_addr_to_str(ctdb->address), + ctdb_addr_to_port(ctdb->address)); + DEBUG(DEBUG_INFO,("ctdb chose network address %s\n", ctdb->name)); if (listen(ctcp->listen_fd, 10) == -1) { goto failed; @@ -410,7 +364,7 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb) close(lock_fd); return 0; - + failed: close(lock_fd); if (ctcp->listen_fd != -1) { @@ -435,23 +389,17 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb) /* we can either auto-bind to the first available address, or we can use a specified address */ - if (!ctdb->address.address) { + if (!ctdb->address) { return ctdb_tcp_listen_automatic(ctdb); } - ZERO_STRUCT(sock); - if (ctdb_tcp_get_address(ctdb, ctdb->address.address, - &sock) != 0) { - goto failed; - } - + sock = *ctdb->address; + switch (sock.sa.sa_family) { case AF_INET: - sock.ip.sin_port = htons(ctdb->address.port); sock_size = sizeof(sock.ip); break; case AF_INET6: - sock.ip6.sin6_port = htons(ctdb->address.port); sock_size = sizeof(sock.ip6); break; default: @@ -459,9 +407,6 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb) sock.sa.sa_family)); goto failed; } -#ifdef HAVE_SOCK_SIN_LEN - sock.ip.sin_len = sock_size; -#endif ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if (ctcp->listen_fd == -1) { diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c index a65e7320f5e..dba3be33947 100644 --- a/ctdb/tcp/tcp_init.c +++ b/ctdb/tcp/tcp_init.c @@ -92,7 +92,7 @@ static int ctdb_tcp_connect_node(struct ctdb_node *node) /* startup connection to the other server - will happen on next event loop */ - if (!ctdb_same_address(&ctdb->address, &node->address)) { + if (!ctdb_same_address(ctdb->address, &node->address)) { tnode->connect_te = event_add_timed(ctdb->ev, tnode, timeval_zero(), ctdb_tcp_node_connect, node); |