mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
e6170b5389
This is used to mark nodes as being DELETED internally in ctdb so that nodes are not renumbered if / when they are removed from the nodes file. This is used to be able to do "ctdb reloadnodes" at runtime without causing nodes to be renumbered. To do this, instead of deleting a node from the nodes file, just comment it out like 1.0.0.1 #1.0.0.2 1.0.0.3 After removing 1.0.0.2 from the cluster, the remaining nodes retain their pnn's from prior to the deletion, namely 0 and 2 Any line in the nodes file that is commented out represents a DELETED pnn (This used to be ctdb commit 6a5e4fd7fa391206b463bb4e976502f3ac5bd343)
203 lines
4.7 KiB
C
203 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 "lib/tdb/include/tdb.h"
|
|
#include "lib/events/events.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);
|
|
|
|
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;
|
|
}
|
|
|