summaryrefslogtreecommitdiffstats
path: root/ctdb
diff options
context:
space:
mode:
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/client/ctdb_client.c21
-rw-r--r--ctdb/include/ctdb.h3
-rw-r--r--ctdb/include/ctdb_private.h5
-rw-r--r--ctdb/server/ctdb_control.c4
-rw-r--r--ctdb/server/ctdb_recover.c36
-rw-r--r--ctdb/server/ctdb_server.c4
-rw-r--r--ctdb/server/ctdbd.c15
-rw-r--r--ctdb/tcp/ctdb_tcp.h1
-rw-r--r--ctdb/tcp/tcp_init.c20
-rw-r--r--ctdb/tools/ctdb.c42
10 files changed, 145 insertions, 6 deletions
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index 1cdfee56e0..df328c078e 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/client/ctdb_client.c
@@ -1242,6 +1242,27 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
}
/*
+ drop the transport, reload the nodes file and restart the transport
+ */
+int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
+ struct timeval timeout, uint32_t destnode)
+{
+ int ret;
+ int32_t res;
+
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
+ NULL, NULL, &res, &timeout, NULL);
+ if (ret != 0 || res != 0) {
+ DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
set vnn map on a node
*/
int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h
index d9bf992b4a..d7f754f77a 100644
--- a/ctdb/include/ctdb.h
+++ b/ctdb/include/ctdb.h
@@ -295,6 +295,9 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
struct timeval timeout, uint32_t destnode,
TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap);
+int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
+ struct timeval timeout, uint32_t destnode);
+
struct ctdb_key_list {
uint32_t dbid;
uint32_t num;
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index ab875924fa..c34a9d994e 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -490,6 +490,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0,
CTDB_CONTROL_UPTIME = 69,
CTDB_CONTROL_START_RECOVERY = 70,
CTDB_CONTROL_END_RECOVERY = 71,
+ CTDB_CONTROL_RELOAD_NODES_FILE = 72,
};
/*
@@ -1244,5 +1245,9 @@ int ctdb_client_async_control(struct ctdb_context *ctdb,
bool dont_log_errors,
TDB_DATA data);
+void ctdb_load_nodes_file(struct ctdb_context *ctdb);
+
+int ctdb_control_reload_nodes_file(struct ctdb_context *ctdb, uint32_t opcode);
+
#endif
diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c
index 3ea8f161db..dc890cfb17 100644
--- a/ctdb/server/ctdb_control.c
+++ b/ctdb/server/ctdb_control.c
@@ -134,6 +134,10 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
case CTDB_CONTROL_GET_NODEMAP:
return ctdb_control_getnodemap(ctdb, opcode, indata, outdata);
+ case CTDB_CONTROL_RELOAD_NODES_FILE:
+ CHECK_CONTROL_DATA_SIZE(0);
+ return ctdb_control_reload_nodes_file(ctdb, opcode);
+
case CTDB_CONTROL_SETVNNMAP:
return ctdb_control_setvnnmap(ctdb, opcode, indata, outdata);
diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c
index c3a0caf0a7..96882db944 100644
--- a/ctdb/server/ctdb_recover.c
+++ b/ctdb/server/ctdb_recover.c
@@ -171,6 +171,42 @@ ctdb_control_getnodemap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA ind
return 0;
}
+static void
+ctdb_reload_nodes_event(struct event_context *ev, struct timed_event *te,
+ struct timeval t, void *private_data)
+{
+ int ret;
+ struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
+ int ctdb_tcp_init(struct ctdb_context *);
+
+ /* shut down the transport */
+ ctdb->methods->shutdown(ctdb);
+
+ /* start the transport again */
+ ctdb_load_nodes_file(ctdb);
+ ret = ctdb_tcp_init(ctdb);
+ if (ret != 0) {
+ DEBUG(DEBUG_CRIT, (__location__ " Failed to init TCP\n"));
+ exit(1);
+ }
+ ctdb->methods->initialise(ctdb);
+ ctdb->methods->start(ctdb);
+
+ return;
+}
+
+/*
+ reload the nodes file after a short delay (so that we can send the response
+ back first
+*/
+int
+ctdb_control_reload_nodes_file(struct ctdb_context *ctdb, uint32_t opcode)
+{
+ event_add_timed(ctdb->ev, ctdb, timeval_current_ofs(1,0), ctdb_reload_nodes_event, ctdb);
+
+ return 0;
+}
+
/*
a traverse function for pulling all relevent records from pulldb
*/
diff --git a/ctdb/server/ctdb_server.c b/ctdb/server/ctdb_server.c
index d97e3cbc4f..47a65c93ab 100644
--- a/ctdb/server/ctdb_server.c
+++ b/ctdb/server/ctdb_server.c
@@ -134,6 +134,10 @@ int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist)
int nlines;
int i;
+ talloc_free(ctdb->nodes);
+ ctdb->nodes = NULL;
+ ctdb->num_nodes = 0;
+
talloc_free(ctdb->node_list_file);
ctdb->node_list_file = talloc_strdup(ctdb, nlist);
diff --git a/ctdb/server/ctdbd.c b/ctdb/server/ctdbd.c
index a40c4efb75..ca366fc209 100644
--- a/ctdb/server/ctdbd.c
+++ b/ctdb/server/ctdbd.c
@@ -73,7 +73,16 @@ static void ctdb_recv_pkt(struct ctdb_context *ctdb, uint8_t *data, uint32_t len
ctdb_input_pkt(ctdb, hdr);
}
+void ctdb_load_nodes_file(struct ctdb_context *ctdb)
+{
+ int ret;
+ ret = ctdb_set_nlist(ctdb, options.nlist);
+ if (ret == -1) {
+ DEBUG(DEBUG_ALERT,("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb)));
+ exit(1);
+ }
+}
static const struct ctdb_upcalls ctdb_upcalls = {
.recv_pkt = ctdb_recv_pkt,
@@ -188,11 +197,7 @@ int main(int argc, const char *argv[])
}
/* tell ctdb what nodes are available */
- ret = ctdb_set_nlist(ctdb, options.nlist);
- if (ret == -1) {
- DEBUG(DEBUG_ALERT,("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb)));
- exit(1);
- }
+ ctdb_load_nodes_file(ctdb);
/* if a node-ip was specified, verify that it exists in the
nodes file
diff --git a/ctdb/tcp/ctdb_tcp.h b/ctdb/tcp/ctdb_tcp.h
index 7d47cbcfe1..9a17bd6b59 100644
--- a/ctdb/tcp/ctdb_tcp.h
+++ b/ctdb/tcp/ctdb_tcp.h
@@ -20,6 +20,7 @@
/* ctdb_tcp main state */
struct ctdb_tcp {
+ struct ctdb_context *ctdb;
int listen_fd;
};
diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c
index 624f6507ef..527373cb08 100644
--- a/ctdb/tcp/tcp_init.c
+++ b/ctdb/tcp/tcp_init.c
@@ -54,7 +54,10 @@ static int ctdb_tcp_initialise(struct ctdb_context *ctdb)
int i;
/* listen on our own address */
- if (ctdb_tcp_listen(ctdb) != 0) return -1;
+ 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_tcp_add_node(ctdb->nodes[i]) != 0) {
@@ -142,6 +145,18 @@ static const struct ctdb_methods ctdb_tcp_methods = {
.restart = ctdb_tcp_restart,
};
+static int tcp_ctcp_destructor(struct ctdb_tcp *ctcp)
+{
+ if (ctcp->listen_fd) {
+ close(ctcp->listen_fd);
+ }
+ ctcp->ctdb->private_data = NULL;
+ ctcp->ctdb->methods = NULL;
+
+ return 0;
+}
+
+
/*
initialise tcp portion of ctdb
*/
@@ -152,8 +167,11 @@ int ctdb_tcp_init(struct ctdb_context *ctdb)
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;
}
diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index a82d625ad8..72e4ceb043 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/tools/ctdb.c
@@ -1130,6 +1130,46 @@ static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **
return 0;
}
+/*
+ list all nodes in the cluster
+ */
+static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int i, ret;
+ struct ctdb_node_map *nodemap=NULL;
+
+ ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
+ return ret;
+ }
+
+ for(i=0;i<nodemap->num;i++){
+ printf("%s\n", inet_ntoa(nodemap->nodes[i].sin.sin_addr));
+ }
+
+ return 0;
+}
+
+/*
+ reload the nodes file on the local node
+ */
+static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+
+
+ ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
+ CTDB_CURRENT_NODE);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on local node You MUST fix that node manually!\n"));
+ }
+
+
+ return 0;
+}
+
+
static const struct {
const char *name;
int (*fn)(struct ctdb_context *, int, const char **);
@@ -1175,6 +1215,8 @@ static const struct {
{ "getsrvids", getsrvids, false, "get a list of all server ids"},
{ "vacuum", ctdb_vacuum, false, "vacuum the databases of empty records", "[max_records]"},
{ "repack", ctdb_repack, false, "repack all databases", "[max_freelist]"},
+ { "listnodes", control_listnodes, false, "list all nodes in the cluster"},
+ { "reloadnodes", control_reload_nodes_file, false, "update the nodes file and restart the transport on the local node"},
};
/*