4 Copyright (C) Andrew Tridgell 2007
5 Copyright (C) Ronnie Sahlberg 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "lib/events/events.h"
23 #include "system/time.h"
24 #include "system/filesys.h"
25 #include "system/network.h"
26 #include "system/locale.h"
29 #include "../include/ctdb.h"
30 #include "../include/ctdb_private.h"
31 #include "../common/rb_tree.h"
34 #define ERR_TIMEOUT 20 /* timed out trying to reach node */
35 #define ERR_NONODE 21 /* node does not exist */
36 #define ERR_DISNODE 22 /* node is disconnected */
38 static void usage(void);
47 #define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
50 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
53 #define XSTR(x) STR(x)
54 printf("CTDB version: %s\n", XSTR(CTDB_VERS));
61 verify that a node exists and is reachable
63 static void verify_node(struct ctdb_context *ctdb)
66 struct ctdb_node_map *nodemap=NULL;
68 if (options.pnn == CTDB_CURRENT_NODE) {
71 if (options.pnn == CTDB_BROADCAST_ALL) {
75 /* verify the node exists */
76 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
77 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
80 if (options.pnn >= nodemap->num) {
81 DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
84 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DELETED) {
85 DEBUG(DEBUG_ERR, ("Node %u is DELETED\n", options.pnn));
88 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
89 DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
93 /* verify we can access the node */
94 ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
96 DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
102 check if a database exists
104 static int db_exists(struct ctdb_context *ctdb, const char *db_name)
107 struct ctdb_dbid_map *dbmap=NULL;
109 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
111 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
115 for(i=0;i<dbmap->num;i++){
118 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
119 if (!strcmp(name, db_name)) {
128 see if a process exists
130 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
138 if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
139 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
143 ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
145 printf("%u:%u exists\n", pnn, pid);
147 printf("%u:%u does not exist\n", pnn, pid);
153 display statistics structure
155 static void show_statistics(struct ctdb_statistics *s)
157 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
159 const char *prefix=NULL;
165 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
166 STATISTICS_FIELD(num_clients),
167 STATISTICS_FIELD(frozen),
168 STATISTICS_FIELD(recovering),
169 STATISTICS_FIELD(client_packets_sent),
170 STATISTICS_FIELD(client_packets_recv),
171 STATISTICS_FIELD(node_packets_sent),
172 STATISTICS_FIELD(node_packets_recv),
173 STATISTICS_FIELD(keepalive_packets_sent),
174 STATISTICS_FIELD(keepalive_packets_recv),
175 STATISTICS_FIELD(node.req_call),
176 STATISTICS_FIELD(node.reply_call),
177 STATISTICS_FIELD(node.req_dmaster),
178 STATISTICS_FIELD(node.reply_dmaster),
179 STATISTICS_FIELD(node.reply_error),
180 STATISTICS_FIELD(node.req_message),
181 STATISTICS_FIELD(node.req_control),
182 STATISTICS_FIELD(node.reply_control),
183 STATISTICS_FIELD(client.req_call),
184 STATISTICS_FIELD(client.req_message),
185 STATISTICS_FIELD(client.req_control),
186 STATISTICS_FIELD(timeouts.call),
187 STATISTICS_FIELD(timeouts.control),
188 STATISTICS_FIELD(timeouts.traverse),
189 STATISTICS_FIELD(total_calls),
190 STATISTICS_FIELD(pending_calls),
191 STATISTICS_FIELD(lockwait_calls),
192 STATISTICS_FIELD(pending_lockwait_calls),
193 STATISTICS_FIELD(childwrite_calls),
194 STATISTICS_FIELD(pending_childwrite_calls),
195 STATISTICS_FIELD(memory_used),
196 STATISTICS_FIELD(max_hop_count),
198 printf("CTDB version %u\n", CTDB_VERSION);
199 for (i=0;i<ARRAY_SIZE(fields);i++) {
200 if (strchr(fields[i].name, '.')) {
201 preflen = strcspn(fields[i].name, ".")+1;
202 if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
203 prefix = fields[i].name;
204 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
209 printf(" %*s%-22s%*s%10u\n",
211 fields[i].name+preflen,
213 *(uint32_t *)(fields[i].offset+(uint8_t *)s));
215 printf(" %-30s %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
216 printf(" %-30s %.6f sec\n", "max_reclock_recd", s->reclock.recd);
218 printf(" %-30s %.6f sec\n", "max_call_latency", s->max_call_latency);
219 printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
220 printf(" %-30s %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
221 talloc_free(tmp_ctx);
225 display remote ctdb statistics combined from all nodes
227 static int control_statistics_all(struct ctdb_context *ctdb)
230 struct ctdb_statistics statistics;
234 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
235 CTDB_NO_MEMORY(ctdb, nodes);
237 ZERO_STRUCT(statistics);
239 for (i=0;i<num_nodes;i++) {
240 struct ctdb_statistics s1;
242 uint32_t *v1 = (uint32_t *)&s1;
243 uint32_t *v2 = (uint32_t *)&statistics;
245 offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
246 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
248 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
251 for (j=0;j<num_ints;j++) {
254 statistics.max_hop_count =
255 MAX(statistics.max_hop_count, s1.max_hop_count);
256 statistics.max_call_latency =
257 MAX(statistics.max_call_latency, s1.max_call_latency);
258 statistics.max_lockwait_latency =
259 MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
262 printf("Gathered statistics for %u nodes\n", num_nodes);
263 show_statistics(&statistics);
268 display remote ctdb statistics
270 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
273 struct ctdb_statistics statistics;
275 if (options.pnn == CTDB_BROADCAST_ALL) {
276 return control_statistics_all(ctdb);
279 ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
281 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
284 show_statistics(&statistics);
290 reset remote ctdb statistics
292 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
296 ret = ctdb_statistics_reset(ctdb, options.pnn);
298 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
306 display uptime of remote node
308 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
311 struct ctdb_uptime *uptime = NULL;
312 int tmp, days, hours, minutes, seconds;
314 ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
316 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
320 if (options.machinereadable){
321 printf(":Current Node Time:Ctdb Start Time:Last Recovery/Failover Time:Last Recovery/IPFailover Duration:\n");
322 printf(":%u:%u:%u:%lf\n",
323 (unsigned int)uptime->current_time.tv_sec,
324 (unsigned int)uptime->ctdbd_start_time.tv_sec,
325 (unsigned int)uptime->last_recovery_finished.tv_sec,
326 timeval_delta(&uptime->last_recovery_finished,
327 &uptime->last_recovery_started)
332 printf("Current time of node : %s", ctime(&uptime->current_time.tv_sec));
334 tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
342 printf("Ctdbd start time : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
344 tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
352 printf("Time of last recovery/failover: (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
354 printf("Duration of last recovery/failover: %lf seconds\n",
355 timeval_delta(&uptime->last_recovery_finished,
356 &uptime->last_recovery_started));
362 show the PNN of the current node
364 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
368 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
370 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
374 printf("PNN:%d\n", mypnn);
380 struct pnn_node *next;
385 static struct pnn_node *read_nodes_file(TALLOC_CTX *mem_ctx)
387 const char *nodes_list;
391 struct pnn_node *pnn_nodes = NULL;
392 struct pnn_node *pnn_node;
393 struct pnn_node *tmp_node;
395 /* read the nodes file */
396 nodes_list = getenv("CTDB_NODES");
397 if (nodes_list == NULL) {
398 nodes_list = "/etc/ctdb/nodes";
400 lines = file_lines_load(nodes_list, &nlines, mem_ctx);
404 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
407 for (i=0, pnn=0; i<nlines; i++) {
411 /* strip leading spaces */
412 while((*node == ' ') || (*node == '\t')) {
419 if (strcmp(node, "") == 0) {
422 pnn_node = talloc(mem_ctx, struct pnn_node);
423 pnn_node->pnn = pnn++;
424 pnn_node->addr = talloc_strdup(pnn_node, node);
425 pnn_node->next = pnn_nodes;
426 pnn_nodes = pnn_node;
429 /* swap them around so we return them in incrementing order */
430 pnn_node = pnn_nodes;
434 pnn_node = pnn_node->next;
436 tmp_node->next = pnn_nodes;
437 pnn_nodes = tmp_node;
444 show the PNN of the current node
445 discover the pnn by loading the nodes file and try to bind to all
446 addresses one at a time until the ip address is found.
448 static int control_xpnn(struct ctdb_context *ctdb, int argc, const char **argv)
450 TALLOC_CTX *mem_ctx = talloc_new(NULL);
451 struct pnn_node *pnn_nodes;
452 struct pnn_node *pnn_node;
454 pnn_nodes = read_nodes_file(mem_ctx);
455 if (pnn_nodes == NULL) {
456 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
457 talloc_free(mem_ctx);
461 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
464 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
465 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
466 talloc_free(mem_ctx);
470 if (ctdb_sys_have_ip(&addr)) {
471 printf("PNN:%d\n", pnn_node->pnn);
472 talloc_free(mem_ctx);
477 printf("Failed to detect which PNN this node is\n");
478 talloc_free(mem_ctx);
483 display remote ctdb status
485 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
488 struct ctdb_vnn_map *vnnmap=NULL;
489 struct ctdb_node_map *nodemap=NULL;
490 uint32_t recmode, recmaster;
493 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
498 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
500 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
504 if(options.machinereadable){
505 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:Stopped:\n");
506 for(i=0;i<nodemap->num;i++){
507 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
510 printf(":%d:%s:%d:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
511 ctdb_addr_to_str(&nodemap->nodes[i].addr),
512 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
513 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
514 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
515 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
516 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
521 printf("Number of nodes:%d\n", nodemap->num);
522 for(i=0;i<nodemap->num;i++){
523 static const struct {
527 { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" },
528 { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" },
529 { NODE_FLAGS_BANNED, "BANNED" },
530 { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" },
531 { NODE_FLAGS_DELETED, "DELETED" },
532 { NODE_FLAGS_STOPPED, "STOPPED" },
534 char *flags_str = NULL;
537 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
540 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
541 if (nodemap->nodes[i].flags & flag_names[j].flag) {
542 if (flags_str == NULL) {
543 flags_str = talloc_strdup(ctdb, flag_names[j].name);
545 flags_str = talloc_asprintf_append(flags_str, "|%s",
548 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
551 if (flags_str == NULL) {
552 flags_str = talloc_strdup(ctdb, "OK");
553 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
555 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
556 ctdb_addr_to_str(&nodemap->nodes[i].addr),
558 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
559 talloc_free(flags_str);
562 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
564 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
567 if (vnnmap->generation == INVALID_GENERATION) {
568 printf("Generation:INVALID\n");
570 printf("Generation:%d\n",vnnmap->generation);
572 printf("Size:%d\n",vnnmap->size);
573 for(i=0;i<vnnmap->size;i++){
574 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
577 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
579 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
582 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
584 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
586 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
589 printf("Recovery master:%d\n",recmaster);
596 struct natgw_node *next;
601 display the list of nodes belonging to this natgw configuration
603 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
606 const char *natgw_list;
609 struct natgw_node *natgw_nodes = NULL;
610 struct natgw_node *natgw_node;
611 struct ctdb_node_map *nodemap=NULL;
614 /* read the natgw nodes file into a linked list */
615 natgw_list = getenv("NATGW_NODES");
616 if (natgw_list == NULL) {
617 natgw_list = "/etc/ctdb/natgw_nodes";
619 lines = file_lines_load(natgw_list, &nlines, ctdb);
621 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
624 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
627 for (i=0;i<nlines;i++) {
631 /* strip leading spaces */
632 while((*node == ' ') || (*node == '\t')) {
638 if (strcmp(node, "") == 0) {
641 natgw_node = talloc(ctdb, struct natgw_node);
642 natgw_node->addr = talloc_strdup(natgw_node, node);
643 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
644 natgw_node->next = natgw_nodes;
645 natgw_nodes = natgw_node;
648 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
650 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
655 while(i<nodemap->num) {
656 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
657 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
662 /* this node was not in the natgw so we just remove it from
665 if ((natgw_node == NULL)
666 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
669 for (j=i+1; j<nodemap->num; j++) {
670 nodemap->nodes[j-1] = nodemap->nodes[j];
679 /* pick a node to be natgwmaster
680 * we dont allow STOPPED, DELETED, BANNED or UNHEALTHY nodes to become the natgwmaster
682 for(i=0;i<nodemap->num;i++){
683 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_UNHEALTHY))) {
684 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
688 /* we couldnt find any healthy node, try unhealthy ones */
689 if (i == nodemap->num) {
690 for(i=0;i<nodemap->num;i++){
691 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
692 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
697 /* unless all nodes are STOPPED, when we pick one anyway */
698 if (i == nodemap->num) {
699 for(i=0;i<nodemap->num;i++){
700 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
701 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
705 /* or if we still can not find any */
706 if (i == nodemap->num) {
707 printf("-1 0.0.0.0\n");
711 /* print the pruned list of nodes belonging to this natgw list */
712 for(i=0;i<nodemap->num;i++){
713 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
716 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
717 ctdb_addr_to_str(&nodemap->nodes[i].addr),
718 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
719 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
720 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
721 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
722 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
729 display the status of the scripts for monitoring (or other events)
731 static int control_one_scriptstatus(struct ctdb_context *ctdb,
732 enum ctdb_eventscript_call type)
734 struct ctdb_scripts_wire *script_status;
737 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, type, &script_status);
739 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
743 if (script_status == NULL) {
744 if (!options.machinereadable) {
745 printf("%s cycle never run\n",
746 ctdb_eventscript_call_names[type]);
751 if (!options.machinereadable) {
752 printf("%d scripts were executed last %s cycle\n",
753 script_status->num_scripts,
754 ctdb_eventscript_call_names[type]);
756 for (i=0; i<script_status->num_scripts; i++) {
757 const char *status = NULL;
759 switch (script_status->scripts[i].status) {
770 if (script_status->scripts[i].status > 0)
774 if (options.machinereadable) {
775 printf("%s:%s:%i:%s:%lu.%06lu:%lu.%06lu:%s:\n",
776 ctdb_eventscript_call_names[type],
777 script_status->scripts[i].name,
778 script_status->scripts[i].status,
780 (long)script_status->scripts[i].start.tv_sec,
781 (long)script_status->scripts[i].start.tv_usec,
782 (long)script_status->scripts[i].finished.tv_sec,
783 (long)script_status->scripts[i].finished.tv_usec,
784 script_status->scripts[i].output);
788 printf("%-20s Status:%s ",
789 script_status->scripts[i].name, status);
791 /* Some other error, eg from stat. */
792 printf("%-20s Status:CANNOT RUN (%s)",
793 script_status->scripts[i].name,
794 strerror(-script_status->scripts[i].status));
796 if (script_status->scripts[i].status >= 0) {
797 printf("Duration:%.3lf ",
798 timeval_delta(&script_status->scripts[i].finished,
799 &script_status->scripts[i].start));
801 if (script_status->scripts[i].status != -ENOEXEC) {
803 ctime(&script_status->scripts[i].start.tv_sec));
804 if (script_status->scripts[i].status != 0) {
805 printf(" OUTPUT:%s\n",
806 script_status->scripts[i].output);
816 static int control_scriptstatus(struct ctdb_context *ctdb,
817 int argc, const char **argv)
820 enum ctdb_eventscript_call type, min, max;
824 DEBUG(DEBUG_ERR, ("Unknown arguments to scriptstatus\n"));
829 arg = ctdb_eventscript_call_names[CTDB_EVENT_MONITOR];
833 for (type = 0; type < CTDB_EVENT_MAX; type++) {
834 if (strcmp(arg, ctdb_eventscript_call_names[type]) == 0) {
840 if (type == CTDB_EVENT_MAX) {
841 if (strcmp(arg, "all") == 0) {
843 max = CTDB_EVENT_MAX;
845 DEBUG(DEBUG_ERR, ("Unknown event type %s\n", argv[0]));
850 if (options.machinereadable) {
851 printf(":Type:Name:Code:Status:Start:End:Error Output...:\n");
854 for (type = min; type < max; type++) {
855 ret = control_one_scriptstatus(ctdb, type);
865 enable an eventscript
867 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
875 ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
877 DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
885 disable an eventscript
887 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
895 ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
897 DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
905 display the pnn of the recovery master
907 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
912 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
914 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
917 printf("%d\n",recmaster);
923 get a list of all tickles for this pnn
925 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
927 struct ctdb_control_tcp_tickle_list *list;
935 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
936 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
940 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
942 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
946 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
947 printf("Num tickles:%u\n", list->tickles.num);
948 for (i=0;i<list->tickles.num;i++) {
949 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
950 printf("DST: %s:%u\n", ctdb_addr_to_str(&list->tickles.connections[i].dst_addr), ntohs(list->tickles.connections[i].dst_addr.ip.sin_port));
960 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
962 struct ctdb_all_public_ips *ips;
963 struct ctdb_public_ip ip;
966 uint32_t disable_time;
968 struct ctdb_node_map *nodemap=NULL;
969 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
972 data.dptr = (uint8_t*)&disable_time;
973 data.dsize = sizeof(disable_time);
974 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
976 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
982 /* read the public ip list from the node */
983 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
985 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
986 talloc_free(tmp_ctx);
990 for (i=0;i<ips->num;i++) {
991 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
996 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
997 pnn, ctdb_addr_to_str(addr)));
998 talloc_free(tmp_ctx);
1005 data.dptr = (uint8_t *)&ip;
1006 data.dsize = sizeof(ip);
1008 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
1010 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1011 talloc_free(tmp_ctx);
1015 nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
1016 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
1023 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
1024 talloc_free(tmp_ctx);
1028 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
1030 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
1031 talloc_free(tmp_ctx);
1035 talloc_free(tmp_ctx);
1040 move/failover an ip address to a specific node
1042 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
1045 ctdb_sock_addr addr;
1052 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1053 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1058 if (sscanf(argv[1], "%u", &pnn) != 1) {
1059 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
1063 if (move_ip(ctdb, &addr, pnn) != 0) {
1064 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1071 void getips_store_callback(void *param, void *data)
1073 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
1074 struct ctdb_all_public_ips *ips = param;
1078 ips->ips[i].pnn = node_ip->pnn;
1079 ips->ips[i].addr = node_ip->addr;
1082 void getips_count_callback(void *param, void *data)
1084 uint32_t *count = param;
1090 static uint32_t *ip_key(ctdb_sock_addr *ip)
1092 static uint32_t key[IP_KEYLEN];
1094 bzero(key, sizeof(key));
1096 switch (ip->sa.sa_family) {
1098 key[0] = ip->ip.sin_addr.s_addr;
1101 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
1102 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
1103 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
1104 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
1107 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1114 static void *add_ip_callback(void *parm, void *data)
1120 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1122 struct ctdb_all_public_ips *tmp_ips;
1123 struct ctdb_node_map *nodemap=NULL;
1124 trbt_tree_t *ip_tree;
1128 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1130 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1134 ip_tree = trbt_create(tmp_ctx, 0);
1136 for(i=0;i<nodemap->num;i++){
1137 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1140 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1144 /* read the public ip list from this node */
1145 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1147 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1151 for (j=0; j<tmp_ips->num;j++) {
1152 struct ctdb_public_ip *node_ip;
1154 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1155 node_ip->pnn = tmp_ips->ips[j].pnn;
1156 node_ip->addr = tmp_ips->ips[j].addr;
1158 trbt_insertarray32_callback(ip_tree,
1159 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1163 talloc_free(tmp_ips);
1168 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1170 len = offsetof(struct ctdb_all_public_ips, ips) +
1171 count*sizeof(struct ctdb_public_ip);
1172 tmp_ips = talloc_zero_size(tmp_ctx, len);
1173 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1182 * scans all other nodes and returns a pnn for another node that can host this
1186 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1188 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1189 struct ctdb_all_public_ips *ips;
1190 struct ctdb_node_map *nodemap=NULL;
1193 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1195 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1196 talloc_free(tmp_ctx);
1200 for(i=0;i<nodemap->num;i++){
1201 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1204 if (nodemap->nodes[i].pnn == options.pnn) {
1208 /* read the public ip list from this node */
1209 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1211 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1215 for (j=0;j<ips->num;j++) {
1216 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1217 talloc_free(tmp_ctx);
1218 return nodemap->nodes[i].pnn;
1224 talloc_free(tmp_ctx);
1229 add a public ip address to a node
1231 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1237 ctdb_sock_addr addr;
1238 struct ctdb_control_ip_iface *pub;
1239 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1240 struct ctdb_all_public_ips *ips;
1244 talloc_free(tmp_ctx);
1248 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1249 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1250 talloc_free(tmp_ctx);
1254 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1256 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1257 talloc_free(tmp_ctx);
1262 /* check if some other node is already serving this ip, if not,
1265 for (i=0;i<ips->num;i++) {
1266 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1271 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1272 pub = talloc_size(tmp_ctx, len);
1273 CTDB_NO_MEMORY(ctdb, pub);
1277 pub->len = strlen(argv[1])+1;
1278 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1280 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1282 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1283 talloc_free(tmp_ctx);
1287 if (i == ips->num) {
1288 /* no one has this ip so we claim it */
1291 pnn = ips->ips[i].pnn;
1294 if (move_ip(ctdb, &addr, pnn) != 0) {
1295 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1299 talloc_free(tmp_ctx);
1303 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1305 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1307 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1308 struct ctdb_node_map *nodemap=NULL;
1309 struct ctdb_all_public_ips *ips;
1312 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1314 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1318 /* remove it from the nodes that are not hosting the ip currently */
1319 for(i=0;i<nodemap->num;i++){
1320 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1323 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1324 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1328 for (j=0;j<ips->num;j++) {
1329 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1337 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1341 options.pnn = nodemap->nodes[i].pnn;
1342 control_delip(ctdb, argc, argv);
1346 /* remove it from every node (also the one hosting it) */
1347 for(i=0;i<nodemap->num;i++){
1348 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1351 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1352 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1356 for (j=0;j<ips->num;j++) {
1357 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1365 options.pnn = nodemap->nodes[i].pnn;
1366 control_delip(ctdb, argc, argv);
1369 talloc_free(tmp_ctx);
1374 delete a public ip address from a node
1376 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1379 ctdb_sock_addr addr;
1380 struct ctdb_control_ip_iface pub;
1381 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1382 struct ctdb_all_public_ips *ips;
1385 talloc_free(tmp_ctx);
1389 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1390 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1394 if (options.pnn == CTDB_BROADCAST_ALL) {
1395 return control_delip_all(ctdb, argc, argv, &addr);
1402 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1404 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1405 talloc_free(tmp_ctx);
1409 for (i=0;i<ips->num;i++) {
1410 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1416 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1417 ctdb_addr_to_str(&addr)));
1418 talloc_free(tmp_ctx);
1422 if (ips->ips[i].pnn == options.pnn) {
1423 ret = find_other_host_for_public_ip(ctdb, &addr);
1425 if (move_ip(ctdb, &addr, ret) != 0) {
1426 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1432 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1434 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1435 talloc_free(tmp_ctx);
1439 talloc_free(tmp_ctx);
1444 kill a tcp connection
1446 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1449 struct ctdb_control_killtcp killtcp;
1455 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1456 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1460 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1461 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1465 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1467 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1478 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1481 ctdb_sock_addr addr;
1487 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1488 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1492 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1494 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1502 register a server id
1504 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1507 struct ctdb_server_id server_id;
1513 server_id.pnn = strtoul(argv[0], NULL, 0);
1514 server_id.type = strtoul(argv[1], NULL, 0);
1515 server_id.server_id = strtoul(argv[2], NULL, 0);
1517 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1519 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1526 unregister a server id
1528 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1531 struct ctdb_server_id server_id;
1537 server_id.pnn = strtoul(argv[0], NULL, 0);
1538 server_id.type = strtoul(argv[1], NULL, 0);
1539 server_id.server_id = strtoul(argv[2], NULL, 0);
1541 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1543 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1550 check if a server id exists
1552 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1556 struct ctdb_server_id server_id;
1562 server_id.pnn = strtoul(argv[0], NULL, 0);
1563 server_id.type = strtoul(argv[1], NULL, 0);
1564 server_id.server_id = strtoul(argv[2], NULL, 0);
1566 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1568 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1573 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1575 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1581 get a list of all server ids that are registered on a node
1583 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1586 struct ctdb_server_id_list *server_ids;
1588 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1590 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1594 for (i=0; i<server_ids->num; i++) {
1595 printf("Server id %d:%d:%d\n",
1596 server_ids->server_ids[i].pnn,
1597 server_ids->server_ids[i].type,
1598 server_ids->server_ids[i].server_id);
1605 send a tcp tickle ack
1607 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1610 ctdb_sock_addr src, dst;
1616 if (!parse_ip_port(argv[0], &src)) {
1617 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1621 if (!parse_ip_port(argv[1], &dst)) {
1622 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1626 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1630 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1637 display public ip status
1639 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1642 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1643 struct ctdb_all_public_ips *ips;
1645 if (options.pnn == CTDB_BROADCAST_ALL) {
1646 /* read the list of public ips from all nodes */
1647 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1649 /* read the public ip list from this node */
1650 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1653 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1654 talloc_free(tmp_ctx);
1658 if (options.machinereadable){
1659 printf(":Public IP:Node:\n");
1661 if (options.pnn == CTDB_BROADCAST_ALL) {
1662 printf("Public IPs on ALL nodes\n");
1664 printf("Public IPs on node %u\n", options.pnn);
1668 for (i=1;i<=ips->num;i++) {
1669 if (options.machinereadable){
1670 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1672 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1676 talloc_free(tmp_ctx);
1681 display pid of a ctdb daemon
1683 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1688 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1690 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1693 printf("Pid:%d\n", pid);
1699 handler for receiving the response to ipreallocate
1701 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1702 TDB_DATA data, void *private_data)
1707 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1709 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1711 event_add_timed(ctdb->ev, ctdb,
1712 timeval_current_ofs(1, 0),
1713 ctdb_every_second, ctdb);
1717 ask the recovery daemon on the recovery master to perform a ip reallocation
1719 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1723 struct takeover_run_reply rd;
1725 struct ctdb_node_map *nodemap=NULL;
1727 struct timeval tv = timeval_current();
1729 /* we need some events to trigger so we can timeout and restart
1732 event_add_timed(ctdb->ev, ctdb,
1733 timeval_current_ofs(1, 0),
1734 ctdb_every_second, ctdb);
1736 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1738 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1741 rd.srvid = getpid();
1743 /* register a message port for receiveing the reply so that we
1744 can receive the reply
1746 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1748 data.dptr = (uint8_t *)&rd;
1749 data.dsize = sizeof(rd);
1753 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1757 /* check that there are valid nodes available */
1758 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1759 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1762 for (i=0; i<nodemap->num;i++) {
1763 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1767 if (i==nodemap->num) {
1768 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1773 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1775 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1779 /* verify the node exists */
1780 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1781 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1786 /* check tha there are nodes available that can act as a recmaster */
1787 for (i=0; i<nodemap->num; i++) {
1788 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1793 if (i == nodemap->num) {
1794 DEBUG(DEBUG_ERR,("No possible nodes to host addresses.\n"));
1798 /* verify the recovery master is not STOPPED, nor BANNED */
1799 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1800 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1807 /* verify the recovery master is not STOPPED, nor BANNED */
1808 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1809 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1815 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1817 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1821 tv = timeval_current();
1822 /* this loop will terminate when we have received the reply */
1823 while (timeval_elapsed(&tv) < 3.0) {
1824 event_loop_once(ctdb->ev);
1827 DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1837 disable a remote node
1839 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1842 struct ctdb_node_map *nodemap=NULL;
1845 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1847 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1853 /* read the nodemap and verify the change took effect */
1854 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1855 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1859 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1860 ret = control_ipreallocate(ctdb, argc, argv);
1862 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1870 enable a disabled remote node
1872 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1876 struct ctdb_node_map *nodemap=NULL;
1879 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1881 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1887 /* read the nodemap and verify the change took effect */
1888 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1889 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1893 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1894 ret = control_ipreallocate(ctdb, argc, argv);
1896 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1906 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1909 struct ctdb_node_map *nodemap=NULL;
1912 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1914 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
1919 /* read the nodemap and verify the change took effect */
1920 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1921 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1925 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1926 ret = control_ipreallocate(ctdb, argc, argv);
1928 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1936 restart a stopped remote node
1938 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1942 struct ctdb_node_map *nodemap=NULL;
1945 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1947 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1953 /* read the nodemap and verify the change took effect */
1954 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1955 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1959 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1960 ret = control_ipreallocate(ctdb, argc, argv);
1962 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1969 static uint32_t get_generation(struct ctdb_context *ctdb)
1971 struct ctdb_vnn_map *vnnmap=NULL;
1974 /* wait until the recmaster is not in recovery mode */
1976 uint32_t recmode, recmaster;
1978 if (vnnmap != NULL) {
1979 talloc_free(vnnmap);
1983 /* get the recmaster */
1984 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1986 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1990 /* get recovery mode */
1991 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1993 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1997 /* get the current generation number */
1998 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
2000 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
2004 if ((recmode == CTDB_RECOVERY_NORMAL)
2005 && (vnnmap->generation != 1)){
2006 return vnnmap->generation;
2013 ban a node from the cluster
2015 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
2018 struct ctdb_node_map *nodemap=NULL;
2019 struct ctdb_ban_time bantime;
2025 /* verify the node exists */
2026 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2028 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2032 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
2033 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
2037 bantime.pnn = options.pnn;
2038 bantime.time = strtoul(argv[0], NULL, 0);
2040 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2042 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
2046 ret = control_ipreallocate(ctdb, argc, argv);
2048 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2057 unban a node from the cluster
2059 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
2062 struct ctdb_node_map *nodemap=NULL;
2063 struct ctdb_ban_time bantime;
2065 /* verify the node exists */
2066 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2068 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2072 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
2073 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
2077 bantime.pnn = options.pnn;
2080 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2082 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
2086 ret = control_ipreallocate(ctdb, argc, argv);
2088 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2097 show ban information for a node
2099 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
2102 struct ctdb_node_map *nodemap=NULL;
2103 struct ctdb_ban_time *bantime;
2105 /* verify the node exists */
2106 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2108 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2112 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2114 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2118 if (bantime->time == 0) {
2119 printf("Node %u is not banned\n", bantime->pnn);
2121 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2130 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2134 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2136 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2146 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2149 uint32_t generation, next_generation;
2151 /* record the current generation number */
2152 generation = get_generation(ctdb);
2154 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2156 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2160 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2162 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2166 /* wait until we are in a new generation */
2168 next_generation = get_generation(ctdb);
2169 if (next_generation != generation) {
2180 display monitoring mode of a remote node
2182 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2187 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2189 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2192 if (!options.machinereadable){
2193 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2196 printf(":%d:\n",monmode);
2203 display capabilities of a remote node
2205 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2207 uint32_t capabilities;
2210 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2212 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2216 if (!options.machinereadable){
2217 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2218 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2219 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2220 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2222 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2223 printf(":%d:%d:%d:%d:\n",
2224 !!(capabilities&CTDB_CAP_RECMASTER),
2225 !!(capabilities&CTDB_CAP_LMASTER),
2226 !!(capabilities&CTDB_CAP_LVS),
2227 !!(capabilities&CTDB_CAP_NATGW));
2233 display lvs configuration
2235 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2237 uint32_t *capabilities;
2238 struct ctdb_node_map *nodemap=NULL;
2240 int healthy_count = 0;
2242 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2244 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2248 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2249 CTDB_NO_MEMORY(ctdb, capabilities);
2251 /* collect capabilities for all connected nodes */
2252 for (i=0; i<nodemap->num; i++) {
2253 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2256 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2260 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2262 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2266 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2270 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2275 /* Print all LVS nodes */
2276 for (i=0; i<nodemap->num; i++) {
2277 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2280 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2283 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2287 if (healthy_count != 0) {
2288 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2293 printf("%d:%s\n", i,
2294 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2301 display who is the lvs master
2303 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2305 uint32_t *capabilities;
2306 struct ctdb_node_map *nodemap=NULL;
2308 int healthy_count = 0;
2310 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2312 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2316 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2317 CTDB_NO_MEMORY(ctdb, capabilities);
2319 /* collect capabilities for all connected nodes */
2320 for (i=0; i<nodemap->num; i++) {
2321 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2324 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2328 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2330 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2334 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2338 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2343 /* find and show the lvsmaster */
2344 for (i=0; i<nodemap->num; i++) {
2345 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2348 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2351 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2355 if (healthy_count != 0) {
2356 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2361 if (options.machinereadable){
2364 printf("Node %d is LVS master\n", i);
2369 printf("There is no LVS master\n");
2374 disable monitoring on a node
2376 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2381 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2383 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2386 printf("Monitoring mode:%s\n","DISABLED");
2392 enable monitoring on a node
2394 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2399 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2401 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2404 printf("Monitoring mode:%s\n","ACTIVE");
2410 display remote list of keys/data for a db
2412 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2414 const char *db_name;
2415 struct ctdb_db_context *ctdb_db;
2425 if (db_exists(ctdb, db_name)) {
2426 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2430 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2432 if (ctdb_db == NULL) {
2433 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2437 /* traverse and dump the cluster tdb */
2438 ret = ctdb_dump_db(ctdb_db, stdout);
2440 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2443 talloc_free(ctdb_db);
2445 printf("Dumped %d records\n", ret);
2450 static void log_handler(struct ctdb_context *ctdb, uint64_t srvid,
2451 TDB_DATA data, void *private_data)
2453 DEBUG(DEBUG_ERR,("Log data received\n"));
2454 if (data.dsize > 0) {
2455 printf("%s", data.dptr);
2462 display a list of log messages from the in memory ringbuffer
2464 static int control_getlog(struct ctdb_context *ctdb, int argc, const char **argv)
2468 struct ctdb_get_log_addr log_addr;
2470 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2475 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2476 talloc_free(tmp_ctx);
2480 log_addr.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2481 log_addr.srvid = getpid();
2482 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2483 log_addr.level = get_debug_by_desc(argv[0]);
2485 log_addr.level = strtol(argv[0], NULL, 0);
2489 data.dptr = (unsigned char *)&log_addr;
2490 data.dsize = sizeof(log_addr);
2492 DEBUG(DEBUG_ERR, ("Pulling logs from node %u\n", options.pnn));
2494 ctdb_set_message_handler(ctdb, log_addr.srvid, log_handler, NULL);
2497 DEBUG(DEBUG_ERR,("Listen for response on %d\n", (int)log_addr.srvid));
2499 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_GET_LOG,
2500 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2501 if (ret != 0 || res != 0) {
2502 DEBUG(DEBUG_ERR,("Failed to get logs - %s\n", errmsg));
2503 talloc_free(tmp_ctx);
2508 tv = timeval_current();
2509 /* this loop will terminate when we have received the reply */
2510 while (timeval_elapsed(&tv) < 3.0) {
2511 event_loop_once(ctdb->ev);
2514 DEBUG(DEBUG_INFO,("Timed out waiting for log data.\n"));
2516 talloc_free(tmp_ctx);
2521 clear the in memory log area
2523 static int control_clearlog(struct ctdb_context *ctdb, int argc, const char **argv)
2528 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2530 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_CLEAR_LOG,
2531 0, tdb_null, tmp_ctx, NULL, &res, NULL, &errmsg);
2532 if (ret != 0 || res != 0) {
2533 DEBUG(DEBUG_ERR,("Failed to clear logs\n"));
2534 talloc_free(tmp_ctx);
2538 talloc_free(tmp_ctx);
2545 display a list of the databases on a remote ctdb
2547 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2550 struct ctdb_dbid_map *dbmap=NULL;
2552 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2554 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2558 printf("Number of databases:%d\n", dbmap->num);
2559 for(i=0;i<dbmap->num;i++){
2564 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2565 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2566 persistent = dbmap->dbs[i].persistent;
2567 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name,
2568 path, persistent?"PERSISTENT":"");
2575 check if the local node is recmaster or not
2576 it will return 1 if this node is the recmaster and 0 if it is not
2577 or if the local ctdb daemon could not be contacted
2579 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2581 uint32_t mypnn, recmaster;
2584 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2586 printf("Failed to get pnn of node\n");
2590 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2592 printf("Failed to get the recmaster\n");
2596 if (recmaster != mypnn) {
2597 printf("this node is not the recmaster\n");
2601 printf("this node is the recmaster\n");
2608 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2611 struct timeval tv = timeval_current();
2612 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2614 printf("Unable to get ping response from node %u\n", options.pnn);
2617 printf("response from %u time=%.6f sec (%d clients)\n",
2618 options.pnn, timeval_elapsed(&tv), ret);
2627 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2638 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2640 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2644 printf("%-19s = %u\n", name, value);
2651 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2662 value = strtoul(argv[1], NULL, 0);
2664 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2666 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2675 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2681 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2683 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2687 for (i=0;i<count;i++) {
2688 control_getvar(ctdb, 1, &list[i]);
2697 display debug level on a node
2699 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2704 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2706 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2709 if (options.machinereadable){
2710 printf(":Name:Level:\n");
2711 printf(":%s:%d:\n",get_debug_by_level(level),level);
2713 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2720 display reclock file of a node
2722 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2725 const char *reclock;
2727 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2729 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2732 if (options.machinereadable){
2733 if (reclock != NULL) {
2734 printf("%s", reclock);
2737 if (reclock == NULL) {
2738 printf("No reclock file used.\n");
2740 printf("Reclock file:%s\n", reclock);
2748 set the reclock file of a node
2750 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2753 const char *reclock;
2757 } else if (argc == 1) {
2763 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2765 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2772 set the natgw state on/off
2774 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2777 uint32_t natgwstate;
2783 if (!strcmp(argv[0], "on")) {
2785 } else if (!strcmp(argv[0], "off")) {
2791 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2793 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2801 set the lmaster role on/off
2803 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2806 uint32_t lmasterrole;
2812 if (!strcmp(argv[0], "on")) {
2814 } else if (!strcmp(argv[0], "off")) {
2820 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2822 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2830 set the recmaster role on/off
2832 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2835 uint32_t recmasterrole;
2841 if (!strcmp(argv[0], "on")) {
2843 } else if (!strcmp(argv[0], "off")) {
2849 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2851 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2859 set debug level on a node or all nodes
2861 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2867 printf("You must specify the debug level. Valid levels are:\n");
2868 for (i=0; debug_levels[i].description != NULL; i++) {
2869 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2875 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2876 level = get_debug_by_desc(argv[0]);
2878 level = strtol(argv[0], NULL, 0);
2881 for (i=0; debug_levels[i].description != NULL; i++) {
2882 if (level == debug_levels[i].level) {
2886 if (debug_levels[i].description == NULL) {
2887 printf("Invalid debug level, must be one of\n");
2888 for (i=0; debug_levels[i].description != NULL; i++) {
2889 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2894 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2896 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2905 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2911 priority = strtol(argv[0], NULL, 0);
2915 DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
2917 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2919 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2927 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2933 priority = strtol(argv[0], NULL, 0);
2937 DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
2939 ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2941 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2948 attach to a database
2950 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2952 const char *db_name;
2953 struct ctdb_db_context *ctdb_db;
2960 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2961 if (ctdb_db == NULL) {
2962 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2972 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2974 struct ctdb_db_priority db_prio;
2981 db_prio.db_id = strtoul(argv[0], NULL, 0);
2982 db_prio.priority = strtoul(argv[1], NULL, 0);
2984 ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
2986 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
2996 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2998 uint32_t db_id, priority;
3005 db_id = strtoul(argv[0], NULL, 0);
3007 ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
3009 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
3013 DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
3019 run an eventscript on a node
3021 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
3027 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3030 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3034 data.dptr = (unsigned char *)discard_const(argv[0]);
3035 data.dsize = strlen((char *)data.dptr) + 1;
3037 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
3039 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
3040 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
3041 if (ret != 0 || res != 0) {
3042 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
3043 talloc_free(tmp_ctx);
3046 talloc_free(tmp_ctx);
3050 #define DB_VERSION 1
3051 #define MAX_DB_NAME 64
3052 struct db_file_header {
3053 unsigned long version;
3055 unsigned long persistent;
3057 const char name[MAX_DB_NAME];
3060 struct backup_data {
3061 struct ctdb_marshall_buffer *records;
3064 bool traverse_error;
3067 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
3069 struct backup_data *bd = talloc_get_type(private, struct backup_data);
3070 struct ctdb_rec_data *rec;
3072 /* add the record */
3073 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
3075 bd->traverse_error = true;
3076 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
3079 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
3080 if (bd->records == NULL) {
3081 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
3082 bd->traverse_error = true;
3085 bd->records->count++;
3086 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
3087 bd->len += rec->length;
3095 * backup a database to a file
3097 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
3100 struct ctdb_dbid_map *dbmap=NULL;
3101 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3102 struct db_file_header dbhdr;
3103 struct ctdb_db_context *ctdb_db;
3104 struct backup_data *bd;
3109 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3113 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
3115 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
3119 for(i=0;i<dbmap->num;i++){
3122 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
3123 if(!strcmp(argv[0], name)){
3124 talloc_free(discard_const(name));
3127 talloc_free(discard_const(name));
3129 if (i == dbmap->num) {
3130 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
3131 talloc_free(tmp_ctx);
3136 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3137 if (ctdb_db == NULL) {
3138 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
3139 talloc_free(tmp_ctx);
3144 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3146 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
3147 talloc_free(tmp_ctx);
3152 bd = talloc_zero(tmp_ctx, struct backup_data);
3154 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
3155 talloc_free(tmp_ctx);
3159 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
3160 if (bd->records == NULL) {
3161 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
3162 talloc_free(tmp_ctx);
3166 bd->len = offsetof(struct ctdb_marshall_buffer, data);
3167 bd->records->db_id = ctdb_db->db_id;
3168 /* traverse the database collecting all records */
3169 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
3170 bd->traverse_error) {
3171 DEBUG(DEBUG_ERR,("Traverse error\n"));
3172 talloc_free(tmp_ctx);
3176 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3179 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
3181 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
3182 talloc_free(tmp_ctx);
3186 dbhdr.version = DB_VERSION;
3187 dbhdr.timestamp = time(NULL);
3188 dbhdr.persistent = dbmap->dbs[i].persistent;
3189 dbhdr.size = bd->len;
3190 if (strlen(argv[0]) >= MAX_DB_NAME) {
3191 DEBUG(DEBUG_ERR,("Too long dbname\n"));
3194 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
3195 ret = write(fh, &dbhdr, sizeof(dbhdr));
3197 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3200 ret = write(fh, bd->records, bd->len);
3202 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3211 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3214 talloc_free(tmp_ctx);
3219 * restore a database from a file
3221 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3224 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3227 struct db_file_header dbhdr;
3228 struct ctdb_db_context *ctdb_db;
3229 struct ctdb_node_map *nodemap=NULL;
3230 struct ctdb_vnn_map *vnnmap=NULL;
3232 struct ctdb_control_wipe_database w;
3234 uint32_t generation;
3239 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3243 fh = open(argv[0], O_RDONLY);
3245 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3246 talloc_free(tmp_ctx);
3250 read(fh, &dbhdr, sizeof(dbhdr));
3251 if (dbhdr.version != DB_VERSION) {
3252 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3253 talloc_free(tmp_ctx);
3257 outdata.dsize = dbhdr.size;
3258 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3259 if (outdata.dptr == NULL) {
3260 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3262 talloc_free(tmp_ctx);
3265 read(fh, outdata.dptr, outdata.dsize);
3268 tm = localtime(&dbhdr.timestamp);
3269 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3270 printf("Restoring database '%s' from backup @ %s\n",
3274 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3275 if (ctdb_db == NULL) {
3276 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3277 talloc_free(tmp_ctx);
3281 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3283 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3284 talloc_free(tmp_ctx);
3289 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3291 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3292 talloc_free(tmp_ctx);
3296 /* freeze all nodes */
3297 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3298 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3299 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3305 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3306 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3307 talloc_free(tmp_ctx);
3312 generation = vnnmap->generation;
3313 data.dptr = (void *)&generation;
3314 data.dsize = sizeof(generation);
3316 /* start a cluster wide transaction */
3317 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3318 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3320 TIMELIMIT(), false, data,
3323 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3328 w.db_id = ctdb_db->db_id;
3329 w.transaction_id = generation;
3331 data.dptr = (void *)&w;
3332 data.dsize = sizeof(w);
3334 /* wipe all the remote databases. */
3335 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3336 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3338 TIMELIMIT(), false, data,
3341 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3342 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3343 talloc_free(tmp_ctx);
3347 /* push the database */
3348 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3349 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3351 TIMELIMIT(), false, outdata,
3354 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3355 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3356 talloc_free(tmp_ctx);
3360 data.dptr = (void *)&generation;
3361 data.dsize = sizeof(generation);
3363 /* commit all the changes */
3364 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3366 TIMELIMIT(), false, data,
3369 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3370 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3371 talloc_free(tmp_ctx);
3376 /* thaw all nodes */
3377 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3378 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3384 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3385 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3386 talloc_free(tmp_ctx);
3391 talloc_free(tmp_ctx);
3396 * wipe a database from a file
3398 static int control_wipedb(struct ctdb_context *ctdb, int argc,
3402 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3404 struct ctdb_db_context *ctdb_db;
3405 struct ctdb_node_map *nodemap = NULL;
3406 struct ctdb_vnn_map *vnnmap = NULL;
3408 struct ctdb_control_wipe_database w;
3410 uint32_t generation;
3411 struct ctdb_dbid_map *dbmap = NULL;
3414 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3418 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3421 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n",
3426 for(i=0;i<dbmap->num;i++){
3429 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
3430 dbmap->dbs[i].dbid, tmp_ctx, &name);
3431 if(!strcmp(argv[0], name)){
3432 talloc_free(discard_const(name));
3435 talloc_free(discard_const(name));
3437 if (i == dbmap->num) {
3438 DEBUG(DEBUG_ERR, ("No database with name '%s' found\n",
3440 talloc_free(tmp_ctx);
3444 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3445 if (ctdb_db == NULL) {
3446 DEBUG(DEBUG_ERR, ("Unable to attach to database '%s'\n",
3448 talloc_free(tmp_ctx);
3452 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb,
3455 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n",
3457 talloc_free(tmp_ctx);
3461 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3464 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n",
3466 talloc_free(tmp_ctx);
3470 /* freeze all nodes */
3471 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3472 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3473 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3480 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3481 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn,
3482 CTDB_RECOVERY_ACTIVE);
3483 talloc_free(tmp_ctx);
3488 generation = vnnmap->generation;
3489 data.dptr = (void *)&generation;
3490 data.dsize = sizeof(generation);
3492 /* start a cluster wide transaction */
3493 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3494 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3496 TIMELIMIT(), false, data,
3500 DEBUG(DEBUG_ERR, ("Unable to start cluster wide "
3501 "transactions.\n"));
3505 w.db_id = ctdb_db->db_id;
3506 w.transaction_id = generation;
3508 data.dptr = (void *)&w;
3509 data.dsize = sizeof(w);
3511 /* wipe all the remote databases. */
3512 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3513 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3515 TIMELIMIT(), false, data,
3518 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3519 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3520 talloc_free(tmp_ctx);
3524 data.dptr = (void *)&generation;
3525 data.dsize = sizeof(generation);
3527 /* commit all the changes */
3528 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3530 TIMELIMIT(), false, data,
3533 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3534 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3535 talloc_free(tmp_ctx);
3539 /* thaw all nodes */
3540 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3541 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3547 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3548 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3549 talloc_free(tmp_ctx);
3553 talloc_free(tmp_ctx);
3558 * set flags of a node in the nodemap
3560 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3567 struct ctdb_node_flag_change c;
3574 if (sscanf(argv[0], "%d", &node) != 1) {
3575 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3579 if (sscanf(argv[1], "0x%x", &flags) != 1) {
3580 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3587 c.new_flags = flags;
3589 data.dsize = sizeof(c);
3590 data.dptr = (unsigned char *)&c;
3592 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
3593 data, NULL, NULL, &status, NULL, NULL);
3594 if (ret != 0 || status != 0) {
3595 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3604 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3610 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3611 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3612 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3613 if (ret != 0 || res != 0) {
3614 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3615 talloc_free(tmp_ctx);
3618 write(1, data.dptr, data.dsize);
3619 talloc_free(tmp_ctx);
3624 handler for memory dumps
3626 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
3627 TDB_DATA data, void *private_data)
3629 write(1, data.dptr, data.dsize);
3634 dump memory usage on the recovery daemon
3636 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3640 struct rd_memdump_reply rd;
3642 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3644 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3647 rd.srvid = getpid();
3649 /* register a message port for receiveing the reply so that we
3650 can receive the reply
3652 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3655 data.dptr = (uint8_t *)&rd;
3656 data.dsize = sizeof(rd);
3658 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3660 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3664 /* this loop will terminate when we have received the reply */
3666 event_loop_once(ctdb->ev);
3673 list all nodes in the cluster
3674 if the daemon is running, we read the data from the daemon.
3675 if the daemon is not running we parse the nodes file directly
3677 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3680 struct ctdb_node_map *nodemap=NULL;
3683 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3685 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3689 for(i=0;i<nodemap->num;i++){
3690 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3693 if (options.machinereadable){
3694 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3696 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3700 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3701 struct pnn_node *pnn_nodes;
3702 struct pnn_node *pnn_node;
3704 pnn_nodes = read_nodes_file(mem_ctx);
3705 if (pnn_nodes == NULL) {
3706 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3707 talloc_free(mem_ctx);
3711 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3712 ctdb_sock_addr addr;
3714 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3715 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3716 talloc_free(mem_ctx);
3720 if (options.machinereadable){
3721 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3723 printf("%s\n", pnn_node->addr);
3726 talloc_free(mem_ctx);
3733 reload the nodes file on the local node
3735 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3739 struct ctdb_node_map *nodemap=NULL;
3741 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3743 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3747 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3749 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3753 /* reload the nodes file on all remote nodes */
3754 for (i=0;i<nodemap->num;i++) {
3755 if (nodemap->nodes[i].pnn == mypnn) {
3758 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3759 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3760 nodemap->nodes[i].pnn);
3762 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3766 /* reload the nodes file on the local node */
3767 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3768 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3770 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3773 /* initiate a recovery */
3774 control_recover(ctdb, argc, argv);
3780 static const struct {
3782 int (*fn)(struct ctdb_context *, int, const char **);
3784 bool without_daemon; /* can be run without daemon running ? */
3787 } ctdb_commands[] = {
3789 { "version", control_version, true, false, "show version of ctdb" },
3791 { "status", control_status, true, false, "show node status" },
3792 { "uptime", control_uptime, true, false, "show node uptime" },
3793 { "ping", control_ping, true, false, "ping all nodes" },
3794 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
3795 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
3796 { "listvars", control_listvars, true, false, "list tunable variables"},
3797 { "statistics", control_statistics, false, false, "show statistics" },
3798 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
3799 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
3800 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
3801 { "getdbmap", control_getdbmap, true, false, "show the database map" },
3802 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
3803 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
3804 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
3805 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
3806 { "lvs", control_lvs, true, false, "show lvs configuration" },
3807 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
3808 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
3809 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
3810 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
3811 { "getdebug", control_getdebug, true, false, "get debug level" },
3812 { "getlog", control_getlog, true, false, "get the log data from the in memory ringbuffer", "<level>" },
3813 { "clearlog", control_clearlog, true, false, "clear the log data from the in memory ringbuffer" },
3814 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
3815 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
3816 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
3817 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
3818 { "disable", control_disable, true, false, "disable a nodes public IP" },
3819 { "enable", control_enable, true, false, "enable a nodes public IP" },
3820 { "stop", control_stop, true, false, "stop a node" },
3821 { "continue", control_continue, true, false, "re-start a stopped node" },
3822 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
3823 { "unban", control_unban, true, false, "unban a node" },
3824 { "showban", control_showban, true, false, "show ban information"},
3825 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
3826 { "recover", control_recover, true, false, "force recovery" },
3827 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
3828 { "freeze", control_freeze, true, false, "freeze databases", "[priority:1-3]" },
3829 { "thaw", control_thaw, true, false, "thaw databases", "[priority:1-3]" },
3830 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
3831 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
3832 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
3833 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
3834 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
3836 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
3837 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
3838 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
3839 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
3840 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
3841 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
3842 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
3843 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
3844 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
3845 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
3846 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
3847 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
3848 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
3849 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
3850 { "wipedb", control_wipedb, false, false, "wipe the contents of a database.", "<dbname>"},
3851 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
3852 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
3853 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts (or all scripts)", "[all]"},
3854 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
3855 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
3856 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
3857 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
3858 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
3859 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
3860 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
3861 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
3862 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
3863 { "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
3864 { "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
3870 static void usage(void)
3874 "Usage: ctdb [options] <control>\n" \
3876 " -n <node> choose node number, or 'all' (defaults to local node)\n"
3877 " -Y generate machinereadable output\n"
3878 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
3879 printf("Controls:\n");
3880 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3881 printf(" %-15s %-27s %s\n",
3882 ctdb_commands[i].name,
3883 ctdb_commands[i].args?ctdb_commands[i].args:"",
3884 ctdb_commands[i].msg);
3890 static void ctdb_alarm(int sig)
3892 printf("Maximum runtime exceeded - exiting\n");
3899 int main(int argc, const char *argv[])
3901 struct ctdb_context *ctdb;
3902 char *nodestring = NULL;
3903 struct poptOption popt_options[] = {
3906 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3907 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3908 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3909 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3913 const char **extra_argv;
3917 struct event_context *ev;
3918 const char *control;
3922 /* set some defaults */
3923 options.maxruntime = 0;
3924 options.timelimit = 3;
3925 options.pnn = CTDB_CURRENT_NODE;
3927 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3929 while ((opt = poptGetNextOpt(pc)) != -1) {
3932 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
3933 poptBadOption(pc, 0), poptStrerror(opt)));
3938 /* setup the remaining options for the main program to use */
3939 extra_argv = poptGetArgs(pc);
3942 while (extra_argv[extra_argc]) extra_argc++;
3945 if (extra_argc < 1) {
3949 if (options.maxruntime == 0) {
3950 const char *ctdb_timeout;
3951 ctdb_timeout = getenv("CTDB_TIMEOUT");
3952 if (ctdb_timeout != NULL) {
3953 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3955 /* default timeout is 120 seconds */
3956 options.maxruntime = 120;
3960 signal(SIGALRM, ctdb_alarm);
3961 alarm(options.maxruntime);
3963 /* setup the node number to contact */
3964 if (nodestring != NULL) {
3965 if (strcmp(nodestring, "all") == 0) {
3966 options.pnn = CTDB_BROADCAST_ALL;
3968 options.pnn = strtoul(nodestring, NULL, 0);
3972 control = extra_argv[0];
3974 ev = event_context_init(NULL);
3976 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3977 if (strcmp(control, ctdb_commands[i].name) == 0) {
3980 if (ctdb_commands[i].without_daemon == true) {
3984 /* initialise ctdb */
3985 ctdb = ctdb_cmdline_client(ev);
3987 if (ctdb_commands[i].without_daemon == false) {
3989 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3993 /* verify the node exists */
3996 if (options.pnn == CTDB_CURRENT_NODE) {
3998 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
4006 if (ctdb_commands[i].auto_all &&
4007 options.pnn == CTDB_BROADCAST_ALL) {
4012 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
4013 CTDB_NO_MEMORY(ctdb, nodes);
4015 for (j=0;j<num_nodes;j++) {
4016 options.pnn = nodes[j];
4017 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4021 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4027 if (i == ARRAY_SIZE(ctdb_commands)) {
4028 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));