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"
35 #define ERR_TIMEOUT 20 /* timed out trying to reach node */
36 #define ERR_NONODE 21 /* node does not exist */
37 #define ERR_DISNODE 22 /* node is disconnected */
39 static void usage(void);
48 #define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
51 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
54 #define XSTR(x) STR(x)
55 printf("CTDB version: %s\n", XSTR(CTDB_VERS));
62 verify that a node exists and is reachable
64 static void verify_node(struct ctdb_context *ctdb)
67 struct ctdb_node_map *nodemap=NULL;
69 if (options.pnn == CTDB_CURRENT_NODE) {
72 if (options.pnn == CTDB_BROADCAST_ALL) {
76 /* verify the node exists */
77 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
78 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
81 if (options.pnn >= nodemap->num) {
82 DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
85 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DELETED) {
86 DEBUG(DEBUG_ERR, ("Node %u is DELETED\n", options.pnn));
89 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
90 DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
94 /* verify we can access the node */
95 ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
97 DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
103 check if a database exists
105 static int db_exists(struct ctdb_context *ctdb, const char *db_name)
108 struct ctdb_dbid_map *dbmap=NULL;
110 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
112 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
116 for(i=0;i<dbmap->num;i++){
119 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
120 if (!strcmp(name, db_name)) {
129 see if a process exists
131 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
139 if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
140 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
144 ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
146 printf("%u:%u exists\n", pnn, pid);
148 printf("%u:%u does not exist\n", pnn, pid);
154 display statistics structure
156 static void show_statistics(struct ctdb_statistics *s)
158 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
160 const char *prefix=NULL;
166 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
167 STATISTICS_FIELD(num_clients),
168 STATISTICS_FIELD(frozen),
169 STATISTICS_FIELD(recovering),
170 STATISTICS_FIELD(client_packets_sent),
171 STATISTICS_FIELD(client_packets_recv),
172 STATISTICS_FIELD(node_packets_sent),
173 STATISTICS_FIELD(node_packets_recv),
174 STATISTICS_FIELD(keepalive_packets_sent),
175 STATISTICS_FIELD(keepalive_packets_recv),
176 STATISTICS_FIELD(node.req_call),
177 STATISTICS_FIELD(node.reply_call),
178 STATISTICS_FIELD(node.req_dmaster),
179 STATISTICS_FIELD(node.reply_dmaster),
180 STATISTICS_FIELD(node.reply_error),
181 STATISTICS_FIELD(node.req_message),
182 STATISTICS_FIELD(node.req_control),
183 STATISTICS_FIELD(node.reply_control),
184 STATISTICS_FIELD(client.req_call),
185 STATISTICS_FIELD(client.req_message),
186 STATISTICS_FIELD(client.req_control),
187 STATISTICS_FIELD(timeouts.call),
188 STATISTICS_FIELD(timeouts.control),
189 STATISTICS_FIELD(timeouts.traverse),
190 STATISTICS_FIELD(total_calls),
191 STATISTICS_FIELD(pending_calls),
192 STATISTICS_FIELD(lockwait_calls),
193 STATISTICS_FIELD(pending_lockwait_calls),
194 STATISTICS_FIELD(childwrite_calls),
195 STATISTICS_FIELD(pending_childwrite_calls),
196 STATISTICS_FIELD(memory_used),
197 STATISTICS_FIELD(max_hop_count),
199 printf("CTDB version %u\n", CTDB_VERSION);
200 for (i=0;i<ARRAY_SIZE(fields);i++) {
201 if (strchr(fields[i].name, '.')) {
202 preflen = strcspn(fields[i].name, ".")+1;
203 if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
204 prefix = fields[i].name;
205 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
210 printf(" %*s%-22s%*s%10u\n",
212 fields[i].name+preflen,
214 *(uint32_t *)(fields[i].offset+(uint8_t *)s));
216 printf(" %-30s %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
217 printf(" %-30s %.6f sec\n", "max_reclock_recd", s->reclock.recd);
219 printf(" %-30s %.6f sec\n", "max_call_latency", s->max_call_latency);
220 printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
221 printf(" %-30s %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
222 talloc_free(tmp_ctx);
226 display remote ctdb statistics combined from all nodes
228 static int control_statistics_all(struct ctdb_context *ctdb)
231 struct ctdb_statistics statistics;
235 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
236 CTDB_NO_MEMORY(ctdb, nodes);
238 ZERO_STRUCT(statistics);
240 for (i=0;i<num_nodes;i++) {
241 struct ctdb_statistics s1;
243 uint32_t *v1 = (uint32_t *)&s1;
244 uint32_t *v2 = (uint32_t *)&statistics;
246 offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
247 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
249 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
252 for (j=0;j<num_ints;j++) {
255 statistics.max_hop_count =
256 MAX(statistics.max_hop_count, s1.max_hop_count);
257 statistics.max_call_latency =
258 MAX(statistics.max_call_latency, s1.max_call_latency);
259 statistics.max_lockwait_latency =
260 MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
263 printf("Gathered statistics for %u nodes\n", num_nodes);
264 show_statistics(&statistics);
269 display remote ctdb statistics
271 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
274 struct ctdb_statistics statistics;
276 if (options.pnn == CTDB_BROADCAST_ALL) {
277 return control_statistics_all(ctdb);
280 ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
282 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
285 show_statistics(&statistics);
291 reset remote ctdb statistics
293 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
297 ret = ctdb_statistics_reset(ctdb, options.pnn);
299 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
307 display uptime of remote node
309 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
312 struct ctdb_uptime *uptime = NULL;
313 int tmp, days, hours, minutes, seconds;
315 ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
317 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
321 if (options.machinereadable){
322 printf(":Current Node Time:Ctdb Start Time:Last Recovery Time:Last Recovery Duration:\n");
323 printf(":%u:%u:%u:%lf\n",
324 (unsigned int)uptime->current_time.tv_sec,
325 (unsigned int)uptime->ctdbd_start_time.tv_sec,
326 (unsigned int)uptime->last_recovery_finished.tv_sec,
327 timeval_delta(&uptime->last_recovery_finished,
328 &uptime->last_recovery_started)
333 printf("Current time of node : %s", ctime(&uptime->current_time.tv_sec));
335 tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
343 printf("Ctdbd start time : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
345 tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
353 printf("Time of last recovery : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
355 printf("Duration of last recovery : %lf seconds\n",
356 timeval_delta(&uptime->last_recovery_finished,
357 &uptime->last_recovery_started));
363 show the PNN of the current node
365 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
369 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
371 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
375 printf("PNN:%d\n", mypnn);
381 struct pnn_node *next;
386 static struct pnn_node *read_nodes_file(TALLOC_CTX *mem_ctx)
388 const char *nodes_list;
392 struct pnn_node *pnn_nodes = NULL;
393 struct pnn_node *pnn_node;
394 struct pnn_node *tmp_node;
396 /* read the nodes file */
397 nodes_list = getenv("CTDB_NODES");
398 if (nodes_list == NULL) {
399 nodes_list = "/etc/ctdb/nodes";
401 lines = file_lines_load(nodes_list, &nlines, mem_ctx);
405 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
408 for (i=0, pnn=0; i<nlines; i++) {
412 /* strip leading spaces */
413 while((*node == ' ') || (*node == '\t')) {
420 if (strcmp(node, "") == 0) {
423 pnn_node = talloc(mem_ctx, struct pnn_node);
424 pnn_node->pnn = pnn++;
425 pnn_node->addr = talloc_strdup(pnn_node, node);
426 pnn_node->next = pnn_nodes;
427 pnn_nodes = pnn_node;
430 /* swap them around so we return them in incrementing order */
431 pnn_node = pnn_nodes;
435 pnn_node = pnn_node->next;
437 tmp_node->next = pnn_nodes;
438 pnn_nodes = tmp_node;
445 show the PNN of the current node
446 discover the pnn by loading the nodes file and try to bind to all
447 addresses one at a time until the ip address is found.
449 static int control_xpnn(struct ctdb_context *ctdb, int argc, const char **argv)
451 TALLOC_CTX *mem_ctx = talloc_new(NULL);
452 struct pnn_node *pnn_nodes;
453 struct pnn_node *pnn_node;
455 pnn_nodes = read_nodes_file(mem_ctx);
456 if (pnn_nodes == NULL) {
457 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
458 talloc_free(mem_ctx);
462 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
465 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
466 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
467 talloc_free(mem_ctx);
471 if (ctdb_sys_have_ip(&addr)) {
472 printf("PNN:%d\n", pnn_node->pnn);
473 talloc_free(mem_ctx);
478 printf("Failed to detect which PNN this node is\n");
479 talloc_free(mem_ctx);
484 display remote ctdb status
486 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
489 struct ctdb_vnn_map *vnnmap=NULL;
490 struct ctdb_node_map *nodemap=NULL;
491 uint32_t recmode, recmaster;
494 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
499 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
501 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
505 if(options.machinereadable){
506 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:Stopped:\n");
507 for(i=0;i<nodemap->num;i++){
508 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
511 printf(":%d:%s:%d:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
512 ctdb_addr_to_str(&nodemap->nodes[i].addr),
513 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
514 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
515 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
516 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
517 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
522 printf("Number of nodes:%d\n", nodemap->num);
523 for(i=0;i<nodemap->num;i++){
524 static const struct {
528 { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" },
529 { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" },
530 { NODE_FLAGS_BANNED, "BANNED" },
531 { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" },
532 { NODE_FLAGS_DELETED, "DELETED" },
533 { NODE_FLAGS_STOPPED, "STOPPED" },
535 char *flags_str = NULL;
538 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
541 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
542 if (nodemap->nodes[i].flags & flag_names[j].flag) {
543 if (flags_str == NULL) {
544 flags_str = talloc_strdup(ctdb, flag_names[j].name);
546 flags_str = talloc_asprintf_append(flags_str, "|%s",
549 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
552 if (flags_str == NULL) {
553 flags_str = talloc_strdup(ctdb, "OK");
554 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
556 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
557 ctdb_addr_to_str(&nodemap->nodes[i].addr),
559 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
560 talloc_free(flags_str);
563 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
565 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
568 if (vnnmap->generation == INVALID_GENERATION) {
569 printf("Generation:INVALID\n");
571 printf("Generation:%d\n",vnnmap->generation);
573 printf("Size:%d\n",vnnmap->size);
574 for(i=0;i<vnnmap->size;i++){
575 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
578 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
580 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
583 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
585 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
587 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
590 printf("Recovery master:%d\n",recmaster);
597 struct natgw_node *next;
602 display the list of nodes belonging to this natgw configuration
604 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
607 const char *natgw_list;
610 struct natgw_node *natgw_nodes = NULL;
611 struct natgw_node *natgw_node;
612 struct ctdb_node_map *nodemap=NULL;
615 /* read the natgw nodes file into a linked list */
616 natgw_list = getenv("NATGW_NODES");
617 if (natgw_list == NULL) {
618 natgw_list = "/etc/ctdb/natgw_nodes";
620 lines = file_lines_load(natgw_list, &nlines, ctdb);
622 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
625 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
628 for (i=0;i<nlines;i++) {
632 /* strip leading spaces */
633 while((*node == ' ') || (*node == '\t')) {
639 if (strcmp(node, "") == 0) {
642 natgw_node = talloc(ctdb, struct natgw_node);
643 natgw_node->addr = talloc_strdup(natgw_node, node);
644 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
645 natgw_node->next = natgw_nodes;
646 natgw_nodes = natgw_node;
649 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
651 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
656 while(i<nodemap->num) {
657 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
658 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
663 /* this node was not in the natgw so we just remove it from
666 if ((natgw_node == NULL)
667 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
670 for (j=i+1; j<nodemap->num; j++) {
671 nodemap->nodes[j-1] = nodemap->nodes[j];
680 /* print the natgw master
681 * we dont allow STOPPED or DELETED nodes to become the natgwmaster
683 for(i=0;i<nodemap->num;i++){
684 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
685 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
689 /* unless all nodes are STOPPED, when we pick one anyway */
690 if (i == nodemap->num) {
691 for(i=0;i<nodemap->num;i++){
692 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
693 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
697 /* or if we still can not find any */
698 if (i == nodemap->num) {
699 printf("-1 0.0.0.0\n");
703 /* print the pruned list of nodes belonging to this natgw list */
704 for(i=0;i<nodemap->num;i++){
705 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
708 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
709 ctdb_addr_to_str(&nodemap->nodes[i].addr),
710 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
711 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
712 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
713 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
714 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
722 display the status of the monitoring scripts
724 static int control_scriptstatus(struct ctdb_context *ctdb, int argc, const char **argv)
727 struct ctdb_monitoring_wire *script_status;
729 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, &script_status);
731 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
735 printf("%d scripts were executed last monitoring cycle\n", script_status->num_scripts);
736 for (i=0; i<script_status->num_scripts; i++) {
737 if (script_status->scripts[i].disabled) {
738 printf("%-20s Status:DISABLED\n",
739 script_status->scripts[i].name);
742 printf("%-20s Status:%s ",
743 script_status->scripts[i].name,
744 script_status->scripts[i].timedout?"TIMEDOUT":script_status->scripts[i].status==0?"OK":"ERROR");
745 if (script_status->scripts[i].timedout == 0) {
746 printf("Duration:%.3lf ",
747 timeval_delta(&script_status->scripts[i].finished,
748 &script_status->scripts[i].start));
751 ctime(&script_status->scripts[i].start.tv_sec));
752 if ((script_status->scripts[i].timedout != 0)
753 || (script_status->scripts[i].status != 0) ) {
754 printf(" OUTPUT:%s\n",
755 script_status->scripts[i].output);
764 enable an eventscript
766 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
774 ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
776 DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
784 disable an eventscript
786 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
794 ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
796 DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
804 display the pnn of the recovery master
806 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
811 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
813 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
816 printf("%d\n",recmaster);
822 get a list of all tickles for this pnn
824 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
826 struct ctdb_control_tcp_tickle_list *list;
834 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
835 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
839 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
841 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
845 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
846 printf("Num tickles:%u\n", list->tickles.num);
847 for (i=0;i<list->tickles.num;i++) {
848 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
849 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));
859 move/failover an ip address to a specific node
861 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
865 struct ctdb_all_public_ips *ips;
866 struct ctdb_public_ip ip;
870 struct ctdb_node_map *nodemap=NULL;
871 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
875 talloc_free(tmp_ctx);
879 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
880 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
881 talloc_free(tmp_ctx);
886 if (sscanf(argv[1], "%u", &pnn) != 1) {
887 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
888 talloc_free(tmp_ctx);
893 /* read the public ip list from the node */
894 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
896 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
897 talloc_free(tmp_ctx);
901 for (i=0;i<ips->num;i++) {
902 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
907 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
908 pnn, ctdb_addr_to_str(&addr)));
909 talloc_free(tmp_ctx);
912 if (ips->ips[i].pnn == pnn) {
913 DEBUG(DEBUG_ERR, ("Host %u is already hosting '%s'\n",
914 pnn, ctdb_addr_to_str(&ips->ips[i].addr)));
915 talloc_free(tmp_ctx);
922 data.dptr = (uint8_t *)&ip;
923 data.dsize = sizeof(ip);
925 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
927 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
928 talloc_free(tmp_ctx);
932 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
933 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
939 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
940 talloc_free(tmp_ctx);
944 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
946 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
947 talloc_free(tmp_ctx);
951 talloc_free(tmp_ctx);
955 void getips_store_callback(void *param, void *data)
957 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
958 struct ctdb_all_public_ips *ips = param;
962 ips->ips[i].pnn = node_ip->pnn;
963 ips->ips[i].addr = node_ip->addr;
966 void getips_count_callback(void *param, void *data)
968 uint32_t *count = param;
974 static uint32_t *ip_key(ctdb_sock_addr *ip)
976 static uint32_t key[IP_KEYLEN];
978 bzero(key, sizeof(key));
980 switch (ip->sa.sa_family) {
982 key[0] = ip->ip.sin_addr.s_addr;
985 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
986 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
987 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
988 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
991 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
998 static void *add_ip_callback(void *parm, void *data)
1004 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1006 struct ctdb_all_public_ips *tmp_ips;
1007 struct ctdb_node_map *nodemap=NULL;
1008 trbt_tree_t *ip_tree;
1012 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1014 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1018 ip_tree = trbt_create(tmp_ctx, 0);
1020 for(i=0;i<nodemap->num;i++){
1021 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1024 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1028 /* read the public ip list from this node */
1029 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1031 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1035 for (j=0; j<tmp_ips->num;j++) {
1036 struct ctdb_public_ip *node_ip;
1038 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1039 node_ip->pnn = tmp_ips->ips[j].pnn;
1040 node_ip->addr = tmp_ips->ips[j].addr;
1042 trbt_insertarray32_callback(ip_tree,
1043 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1047 talloc_free(tmp_ips);
1052 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1054 len = offsetof(struct ctdb_all_public_ips, ips) +
1055 count*sizeof(struct ctdb_public_ip);
1056 tmp_ips = talloc_zero_size(tmp_ctx, len);
1057 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1066 * scans all other nodes and returns a pnn for another node that can host this
1070 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1072 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1073 struct ctdb_all_public_ips *ips;
1074 struct ctdb_node_map *nodemap=NULL;
1077 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1079 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1080 talloc_free(tmp_ctx);
1084 for(i=0;i<nodemap->num;i++){
1085 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1088 if (nodemap->nodes[i].pnn == options.pnn) {
1092 /* read the public ip list from this node */
1093 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1095 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1099 for (j=0;j<ips->num;j++) {
1100 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1101 talloc_free(tmp_ctx);
1102 return nodemap->nodes[i].pnn;
1108 talloc_free(tmp_ctx);
1113 add a public ip address to a node
1115 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1120 ctdb_sock_addr addr;
1121 struct ctdb_control_ip_iface *pub;
1122 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1123 struct ctdb_all_public_ips *ips;
1126 talloc_free(tmp_ctx);
1130 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1131 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1132 talloc_free(tmp_ctx);
1136 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1138 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1139 talloc_free(tmp_ctx);
1144 /* check if some other node is already serving this ip, if not,
1147 for (i=0;i<ips->num;i++) {
1148 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1153 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1154 pub = talloc_size(tmp_ctx, len);
1155 CTDB_NO_MEMORY(ctdb, pub);
1159 pub->len = strlen(argv[1])+1;
1160 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1162 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1164 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1165 talloc_free(tmp_ctx);
1169 /* no one has this ip so we claim it */
1170 if (i == ips->num) {
1171 struct ctdb_public_ip ip;
1173 ip.pnn = options.pnn;
1176 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), options.pnn, &ip);
1178 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", options.pnn));
1185 DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));
1189 talloc_free(tmp_ctx);
1193 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1195 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1197 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1198 struct ctdb_node_map *nodemap=NULL;
1199 struct ctdb_all_public_ips *ips;
1202 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1204 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1208 /* remove it from the nodes that are not hosting the ip currently */
1209 for(i=0;i<nodemap->num;i++){
1210 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1213 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1214 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1218 for (j=0;j<ips->num;j++) {
1219 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1227 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1231 options.pnn = nodemap->nodes[i].pnn;
1232 control_delip(ctdb, argc, argv);
1236 /* remove it from every node (also the one hosting it) */
1237 for(i=0;i<nodemap->num;i++){
1238 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1241 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1242 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1246 for (j=0;j<ips->num;j++) {
1247 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1255 options.pnn = nodemap->nodes[i].pnn;
1256 control_delip(ctdb, argc, argv);
1259 talloc_free(tmp_ctx);
1264 delete a public ip address from a node
1266 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1269 ctdb_sock_addr addr;
1270 struct ctdb_control_ip_iface pub;
1271 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1272 struct ctdb_all_public_ips *ips;
1275 talloc_free(tmp_ctx);
1279 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1280 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1284 if (options.pnn == CTDB_BROADCAST_ALL) {
1285 return control_delip_all(ctdb, argc, argv, &addr);
1292 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1294 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1295 talloc_free(tmp_ctx);
1299 for (i=0;i<ips->num;i++) {
1300 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1306 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1307 ctdb_addr_to_str(&addr)));
1308 talloc_free(tmp_ctx);
1312 if (ips->ips[i].pnn == options.pnn) {
1313 ret = find_other_host_for_public_ip(ctdb, &addr);
1315 struct ctdb_public_ip ip;
1320 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), ret, &ip);
1322 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", options.pnn));
1328 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1330 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1331 talloc_free(tmp_ctx);
1335 talloc_free(tmp_ctx);
1340 kill a tcp connection
1342 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1345 struct ctdb_control_killtcp killtcp;
1351 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1352 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1356 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1357 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1361 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1363 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1374 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1377 ctdb_sock_addr addr;
1383 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1384 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1388 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1390 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1398 register a server id
1400 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1403 struct ctdb_server_id server_id;
1409 server_id.pnn = strtoul(argv[0], NULL, 0);
1410 server_id.type = strtoul(argv[1], NULL, 0);
1411 server_id.server_id = strtoul(argv[2], NULL, 0);
1413 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1415 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1422 unregister a server id
1424 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1427 struct ctdb_server_id server_id;
1433 server_id.pnn = strtoul(argv[0], NULL, 0);
1434 server_id.type = strtoul(argv[1], NULL, 0);
1435 server_id.server_id = strtoul(argv[2], NULL, 0);
1437 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1439 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1446 check if a server id exists
1448 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1452 struct ctdb_server_id server_id;
1458 server_id.pnn = strtoul(argv[0], NULL, 0);
1459 server_id.type = strtoul(argv[1], NULL, 0);
1460 server_id.server_id = strtoul(argv[2], NULL, 0);
1462 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1464 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1469 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1471 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1477 get a list of all server ids that are registered on a node
1479 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1482 struct ctdb_server_id_list *server_ids;
1484 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1486 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1490 for (i=0; i<server_ids->num; i++) {
1491 printf("Server id %d:%d:%d\n",
1492 server_ids->server_ids[i].pnn,
1493 server_ids->server_ids[i].type,
1494 server_ids->server_ids[i].server_id);
1501 send a tcp tickle ack
1503 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1506 ctdb_sock_addr src, dst;
1512 if (!parse_ip_port(argv[0], &src)) {
1513 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1517 if (!parse_ip_port(argv[1], &dst)) {
1518 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1522 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1526 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1533 display public ip status
1535 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1538 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1539 struct ctdb_all_public_ips *ips;
1541 if (options.pnn == CTDB_BROADCAST_ALL) {
1542 /* read the list of public ips from all nodes */
1543 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1545 /* read the public ip list from this node */
1546 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1549 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1550 talloc_free(tmp_ctx);
1554 if (options.machinereadable){
1555 printf(":Public IP:Node:\n");
1557 if (options.pnn == CTDB_BROADCAST_ALL) {
1558 printf("Public IPs on ALL nodes\n");
1560 printf("Public IPs on node %u\n", options.pnn);
1564 for (i=1;i<=ips->num;i++) {
1565 if (options.machinereadable){
1566 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1568 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1572 talloc_free(tmp_ctx);
1577 display pid of a ctdb daemon
1579 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1584 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1586 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1589 printf("Pid:%d\n", pid);
1595 handler for receiving the response to ipreallocate
1597 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1598 TDB_DATA data, void *private_data)
1603 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1605 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1607 event_add_timed(ctdb->ev, ctdb,
1608 timeval_current_ofs(1, 0),
1609 ctdb_every_second, ctdb);
1613 ask the recovery daemon on the recovery master to perform a ip reallocation
1615 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1619 struct rd_memdump_reply rd;
1621 struct ctdb_node_map *nodemap=NULL;
1623 struct timeval tv = timeval_current();
1625 /* we need some events to trigger so we can timeout and restart
1628 event_add_timed(ctdb->ev, ctdb,
1629 timeval_current_ofs(1, 0),
1630 ctdb_every_second, ctdb);
1632 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1634 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1637 rd.srvid = getpid();
1639 /* register a message port for receiveing the reply so that we
1640 can receive the reply
1642 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1644 data.dptr = (uint8_t *)&rd;
1645 data.dsize = sizeof(rd);
1649 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1653 /* check that there are valid nodes available */
1654 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1655 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1658 for (i=0; i<nodemap->num;i++) {
1659 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1663 if (i==nodemap->num) {
1664 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1669 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1671 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1675 /* verify the node exists */
1676 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1677 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1682 /* check tha there are nodes available that can act as a recmaster */
1683 for (i=0; i<nodemap->num; i++) {
1684 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1688 if (i == nodemap->num) {
1692 /* verify the recovery master is not STOPPED, nor BANNED */
1693 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1694 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1701 /* verify the recovery master is not STOPPED, nor BANNED */
1702 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1703 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1709 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1711 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1715 tv = timeval_current();
1716 /* this loop will terminate when we have received the reply */
1717 while (timeval_elapsed(&tv) < 3.0) {
1718 event_loop_once(ctdb->ev);
1721 DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1731 disable a remote node
1733 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1736 struct ctdb_node_map *nodemap=NULL;
1739 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1741 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1747 /* read the nodemap and verify the change took effect */
1748 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1749 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1753 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1754 ret = control_ipreallocate(ctdb, argc, argv);
1756 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1764 enable a disabled remote node
1766 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1770 struct ctdb_node_map *nodemap=NULL;
1773 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1775 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1781 /* read the nodemap and verify the change took effect */
1782 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1783 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1787 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1788 ret = control_ipreallocate(ctdb, argc, argv);
1790 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1800 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1803 struct ctdb_node_map *nodemap=NULL;
1806 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1808 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
1813 /* read the nodemap and verify the change took effect */
1814 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1815 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1819 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1820 ret = control_ipreallocate(ctdb, argc, argv);
1822 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1830 restart a stopped remote node
1832 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1836 struct ctdb_node_map *nodemap=NULL;
1839 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1841 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1847 /* read the nodemap and verify the change took effect */
1848 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1849 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1853 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1854 ret = control_ipreallocate(ctdb, argc, argv);
1856 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1863 static uint32_t get_generation(struct ctdb_context *ctdb)
1865 struct ctdb_vnn_map *vnnmap=NULL;
1868 /* wait until the recmaster is not in recovery mode */
1870 uint32_t recmode, recmaster;
1872 if (vnnmap != NULL) {
1873 talloc_free(vnnmap);
1877 /* get the recmaster */
1878 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1880 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1884 /* get recovery mode */
1885 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1887 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1891 /* get the current generation number */
1892 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
1894 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
1898 if ((recmode == CTDB_RECOVERY_NORMAL)
1899 && (vnnmap->generation != 1)){
1900 return vnnmap->generation;
1907 ban a node from the cluster
1909 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
1912 struct ctdb_node_map *nodemap=NULL;
1913 struct ctdb_ban_time bantime;
1919 /* verify the node exists */
1920 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1922 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1926 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
1927 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
1931 bantime.pnn = options.pnn;
1932 bantime.time = strtoul(argv[0], NULL, 0);
1934 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1936 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
1940 ret = control_ipreallocate(ctdb, argc, argv);
1942 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1951 unban a node from the cluster
1953 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
1956 struct ctdb_node_map *nodemap=NULL;
1957 struct ctdb_ban_time bantime;
1959 /* verify the node exists */
1960 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1962 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1966 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
1967 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
1971 bantime.pnn = options.pnn;
1974 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1976 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
1980 ret = control_ipreallocate(ctdb, argc, argv);
1982 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1991 show ban information for a node
1993 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
1996 struct ctdb_node_map *nodemap=NULL;
1997 struct ctdb_ban_time *bantime;
1999 /* verify the node exists */
2000 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2002 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2006 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2008 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2012 if (bantime->time == 0) {
2013 printf("Node %u is not banned\n", bantime->pnn);
2015 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2024 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2028 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2030 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2040 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2043 uint32_t generation, next_generation;
2045 /* record the current generation number */
2046 generation = get_generation(ctdb);
2048 ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
2050 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2054 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2056 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2060 /* wait until we are in a new generation */
2062 next_generation = get_generation(ctdb);
2063 if (next_generation != generation) {
2074 display monitoring mode of a remote node
2076 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2081 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2083 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2086 if (!options.machinereadable){
2087 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2090 printf(":%d:\n",monmode);
2097 display capabilities of a remote node
2099 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2101 uint32_t capabilities;
2104 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2106 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2110 if (!options.machinereadable){
2111 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2112 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2113 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2114 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2116 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2117 printf(":%d:%d:%d:%d:\n",
2118 !!(capabilities&CTDB_CAP_RECMASTER),
2119 !!(capabilities&CTDB_CAP_LMASTER),
2120 !!(capabilities&CTDB_CAP_LVS),
2121 !!(capabilities&CTDB_CAP_NATGW));
2127 display lvs configuration
2129 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2131 uint32_t *capabilities;
2132 struct ctdb_node_map *nodemap=NULL;
2134 int healthy_count = 0;
2136 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2138 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2142 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2143 CTDB_NO_MEMORY(ctdb, capabilities);
2145 /* collect capabilities for all connected nodes */
2146 for (i=0; i<nodemap->num; i++) {
2147 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2150 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2154 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2156 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2160 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2164 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2169 /* Print all LVS nodes */
2170 for (i=0; i<nodemap->num; i++) {
2171 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2174 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2177 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2181 if (healthy_count != 0) {
2182 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2187 printf("%d:%s\n", i,
2188 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2195 display who is the lvs master
2197 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2199 uint32_t *capabilities;
2200 struct ctdb_node_map *nodemap=NULL;
2202 int healthy_count = 0;
2204 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2206 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2210 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2211 CTDB_NO_MEMORY(ctdb, capabilities);
2213 /* collect capabilities for all connected nodes */
2214 for (i=0; i<nodemap->num; i++) {
2215 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2218 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2222 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2224 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2228 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2232 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2237 /* find and show the lvsmaster */
2238 for (i=0; i<nodemap->num; i++) {
2239 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2242 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2245 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2249 if (healthy_count != 0) {
2250 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2255 if (options.machinereadable){
2258 printf("Node %d is LVS master\n", i);
2263 printf("There is no LVS master\n");
2268 disable monitoring on a node
2270 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2275 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2277 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2280 printf("Monitoring mode:%s\n","DISABLED");
2286 enable monitoring on a node
2288 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2293 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2295 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2298 printf("Monitoring mode:%s\n","ACTIVE");
2304 display remote list of keys/data for a db
2306 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2308 const char *db_name;
2309 struct ctdb_db_context *ctdb_db;
2319 if (db_exists(ctdb, db_name)) {
2320 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2324 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2326 if (ctdb_db == NULL) {
2327 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2331 /* traverse and dump the cluster tdb */
2332 ret = ctdb_dump_db(ctdb_db, stdout);
2334 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2337 talloc_free(ctdb_db);
2339 printf("Dumped %d records\n", ret);
2345 display a list of the databases on a remote ctdb
2347 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2350 struct ctdb_dbid_map *dbmap=NULL;
2352 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2354 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2358 printf("Number of databases:%d\n", dbmap->num);
2359 for(i=0;i<dbmap->num;i++){
2364 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2365 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2366 persistent = dbmap->dbs[i].persistent;
2367 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name,
2368 path, persistent?"PERSISTENT":"");
2375 check if the local node is recmaster or not
2376 it will return 1 if this node is the recmaster and 0 if it is not
2377 or if the local ctdb daemon could not be contacted
2379 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2381 uint32_t mypnn, recmaster;
2384 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2386 printf("Failed to get pnn of node\n");
2390 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2392 printf("Failed to get the recmaster\n");
2396 if (recmaster != mypnn) {
2397 printf("this node is not the recmaster\n");
2401 printf("this node is the recmaster\n");
2408 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2411 struct timeval tv = timeval_current();
2412 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2414 printf("Unable to get ping response from node %u\n", options.pnn);
2417 printf("response from %u time=%.6f sec (%d clients)\n",
2418 options.pnn, timeval_elapsed(&tv), ret);
2427 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2438 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2440 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2444 printf("%-19s = %u\n", name, value);
2451 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2462 value = strtoul(argv[1], NULL, 0);
2464 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2466 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2475 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2481 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2483 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2487 for (i=0;i<count;i++) {
2488 control_getvar(ctdb, 1, &list[i]);
2497 display debug level on a node
2499 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2504 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2506 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2509 if (options.machinereadable){
2510 printf(":Name:Level:\n");
2511 printf(":%s:%d:\n",get_debug_by_level(level),level);
2513 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2520 display reclock file of a node
2522 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2525 const char *reclock;
2527 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2529 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2532 if (reclock == NULL) {
2533 printf("No reclock file used.\n");
2535 printf("Reclock file:%s\n", reclock);
2542 set the reclock file of a node
2544 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2547 const char *reclock;
2551 } else if (argc == 1) {
2557 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2559 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2566 set the natgw state on/off
2568 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2571 uint32_t natgwstate;
2577 if (!strcmp(argv[0], "on")) {
2579 } else if (!strcmp(argv[0], "off")) {
2585 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2587 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2595 set the lmaster role on/off
2597 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2600 uint32_t lmasterrole;
2606 if (!strcmp(argv[0], "on")) {
2608 } else if (!strcmp(argv[0], "off")) {
2614 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2616 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2624 set the recmaster role on/off
2626 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2629 uint32_t recmasterrole;
2635 if (!strcmp(argv[0], "on")) {
2637 } else if (!strcmp(argv[0], "off")) {
2643 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2645 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2653 set debug level on a node or all nodes
2655 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2661 printf("You must specify the debug level. Valid levels are:\n");
2662 for (i=0; debug_levels[i].description != NULL; i++) {
2663 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2669 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2670 level = get_debug_by_desc(argv[0]);
2672 level = strtol(argv[0], NULL, 0);
2675 for (i=0; debug_levels[i].description != NULL; i++) {
2676 if (level == debug_levels[i].level) {
2680 if (debug_levels[i].description == NULL) {
2681 printf("Invalid debug level, must be one of\n");
2682 for (i=0; debug_levels[i].description != NULL; i++) {
2683 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2688 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2690 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2699 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2703 ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
2705 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2713 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2717 ret = ctdb_ctrl_thaw(ctdb, TIMELIMIT(), options.pnn);
2719 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2726 attach to a database
2728 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2730 const char *db_name;
2731 struct ctdb_db_context *ctdb_db;
2738 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2739 if (ctdb_db == NULL) {
2740 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2748 run an eventscript on a node
2750 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
2756 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2759 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2763 data.dptr = (unsigned char *)discard_const(argv[0]);
2764 data.dsize = strlen((char *)data.dptr) + 1;
2766 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
2768 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
2769 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2770 if (ret != 0 || res != 0) {
2771 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
2772 talloc_free(tmp_ctx);
2775 talloc_free(tmp_ctx);
2779 #define DB_VERSION 1
2780 #define MAX_DB_NAME 64
2781 struct db_file_header {
2782 unsigned long version;
2784 unsigned long persistent;
2786 const char name[MAX_DB_NAME];
2789 struct backup_data {
2790 struct ctdb_marshall_buffer *records;
2793 bool traverse_error;
2796 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
2798 struct backup_data *bd = talloc_get_type(private, struct backup_data);
2799 struct ctdb_rec_data *rec;
2801 /* add the record */
2802 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
2804 bd->traverse_error = true;
2805 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
2808 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
2809 if (bd->records == NULL) {
2810 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
2811 bd->traverse_error = true;
2814 bd->records->count++;
2815 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
2816 bd->len += rec->length;
2824 * backup a database to a file
2826 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
2829 struct ctdb_dbid_map *dbmap=NULL;
2830 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2831 struct db_file_header dbhdr;
2832 struct ctdb_db_context *ctdb_db;
2833 struct backup_data *bd;
2838 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2842 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
2844 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2848 for(i=0;i<dbmap->num;i++){
2851 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
2852 if(!strcmp(argv[0], name)){
2853 talloc_free(discard_const(name));
2856 talloc_free(discard_const(name));
2858 if (i == dbmap->num) {
2859 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
2860 talloc_free(tmp_ctx);
2865 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
2866 if (ctdb_db == NULL) {
2867 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
2868 talloc_free(tmp_ctx);
2873 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
2875 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
2876 talloc_free(tmp_ctx);
2881 bd = talloc_zero(tmp_ctx, struct backup_data);
2883 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
2884 talloc_free(tmp_ctx);
2888 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
2889 if (bd->records == NULL) {
2890 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
2891 talloc_free(tmp_ctx);
2895 bd->len = offsetof(struct ctdb_marshall_buffer, data);
2896 bd->records->db_id = ctdb_db->db_id;
2897 /* traverse the database collecting all records */
2898 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
2899 bd->traverse_error) {
2900 DEBUG(DEBUG_ERR,("Traverse error\n"));
2901 talloc_free(tmp_ctx);
2905 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2908 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
2910 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
2911 talloc_free(tmp_ctx);
2915 dbhdr.version = DB_VERSION;
2916 dbhdr.timestamp = time(NULL);
2917 dbhdr.persistent = dbmap->dbs[i].persistent;
2918 dbhdr.size = bd->len;
2919 if (strlen(argv[0]) >= MAX_DB_NAME) {
2920 DEBUG(DEBUG_ERR,("Too long dbname\n"));
2923 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
2924 ret = write(fh, &dbhdr, sizeof(dbhdr));
2926 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
2929 ret = write(fh, bd->records, bd->len);
2931 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
2940 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
2943 talloc_free(tmp_ctx);
2948 * restore a database from a file
2950 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
2953 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2956 struct db_file_header dbhdr;
2957 struct ctdb_db_context *ctdb_db;
2958 struct ctdb_node_map *nodemap=NULL;
2959 struct ctdb_vnn_map *vnnmap=NULL;
2961 struct ctdb_control_wipe_database w;
2963 uint32_t generation;
2968 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2972 fh = open(argv[0], O_RDONLY);
2974 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
2975 talloc_free(tmp_ctx);
2979 read(fh, &dbhdr, sizeof(dbhdr));
2980 if (dbhdr.version != DB_VERSION) {
2981 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
2982 talloc_free(tmp_ctx);
2986 outdata.dsize = dbhdr.size;
2987 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
2988 if (outdata.dptr == NULL) {
2989 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
2991 talloc_free(tmp_ctx);
2994 read(fh, outdata.dptr, outdata.dsize);
2997 tm = localtime(&dbhdr.timestamp);
2998 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
2999 printf("Restoring database '%s' from backup @ %s\n",
3003 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3004 if (ctdb_db == NULL) {
3005 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3006 talloc_free(tmp_ctx);
3010 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3012 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3013 talloc_free(tmp_ctx);
3018 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3020 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3021 talloc_free(tmp_ctx);
3025 /* freeze all nodes */
3026 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3027 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3032 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3033 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3034 talloc_free(tmp_ctx);
3038 generation = vnnmap->generation;
3039 data.dptr = (void *)&generation;
3040 data.dsize = sizeof(generation);
3042 /* start a cluster wide transaction */
3043 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3044 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3046 TIMELIMIT(), false, data,
3049 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3054 w.db_id = ctdb_db->db_id;
3055 w.transaction_id = generation;
3057 data.dptr = (void *)&w;
3058 data.dsize = sizeof(w);
3060 /* wipe all the remote databases. */
3061 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3062 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3064 TIMELIMIT(), false, data,
3067 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3068 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3069 talloc_free(tmp_ctx);
3073 /* push the database */
3074 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3075 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3077 TIMELIMIT(), false, outdata,
3080 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3081 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3082 talloc_free(tmp_ctx);
3086 data.dptr = (void *)&generation;
3087 data.dsize = sizeof(generation);
3089 /* commit all the changes */
3090 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3092 TIMELIMIT(), false, data,
3095 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3096 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3097 talloc_free(tmp_ctx);
3102 /* thaw all nodes */
3103 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3104 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3109 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3110 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3111 talloc_free(tmp_ctx);
3116 talloc_free(tmp_ctx);
3121 * set flags of a node in the nodemap
3123 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3130 struct ctdb_node_flag_change c;
3137 if (sscanf(argv[0], "%d", &node) != 1) {
3138 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3142 if (sscanf(argv[1], "0x%x", &flags) != 1) {
3143 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3150 c.new_flags = flags;
3152 data.dsize = sizeof(c);
3153 data.dptr = (unsigned char *)&c;
3155 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
3156 data, NULL, NULL, &status, NULL, NULL);
3157 if (ret != 0 || status != 0) {
3158 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3167 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3173 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3174 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3175 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3176 if (ret != 0 || res != 0) {
3177 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3178 talloc_free(tmp_ctx);
3181 write(1, data.dptr, data.dsize);
3182 talloc_free(tmp_ctx);
3187 handler for memory dumps
3189 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
3190 TDB_DATA data, void *private_data)
3192 write(1, data.dptr, data.dsize);
3197 dump memory usage on the recovery daemon
3199 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3203 struct rd_memdump_reply rd;
3205 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3207 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3210 rd.srvid = getpid();
3212 /* register a message port for receiveing the reply so that we
3213 can receive the reply
3215 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3218 data.dptr = (uint8_t *)&rd;
3219 data.dsize = sizeof(rd);
3221 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3223 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3227 /* this loop will terminate when we have received the reply */
3229 event_loop_once(ctdb->ev);
3236 list all nodes in the cluster
3237 if the daemon is running, we read the data from the daemon.
3238 if the daemon is not running we parse the nodes file directly
3240 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3243 struct ctdb_node_map *nodemap=NULL;
3246 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3248 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3252 for(i=0;i<nodemap->num;i++){
3253 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3256 if (options.machinereadable){
3257 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3259 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3263 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3264 struct pnn_node *pnn_nodes;
3265 struct pnn_node *pnn_node;
3267 pnn_nodes = read_nodes_file(mem_ctx);
3268 if (pnn_nodes == NULL) {
3269 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3270 talloc_free(mem_ctx);
3274 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3275 ctdb_sock_addr addr;
3277 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3278 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3279 talloc_free(mem_ctx);
3283 if (options.machinereadable){
3284 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3286 printf("%s\n", pnn_node->addr);
3289 talloc_free(mem_ctx);
3296 reload the nodes file on the local node
3298 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3302 struct ctdb_node_map *nodemap=NULL;
3304 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3306 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3310 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3312 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3316 /* reload the nodes file on all remote nodes */
3317 for (i=0;i<nodemap->num;i++) {
3318 if (nodemap->nodes[i].pnn == mypnn) {
3321 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3322 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3323 nodemap->nodes[i].pnn);
3325 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3329 /* reload the nodes file on the local node */
3330 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3331 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3333 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3336 /* initiate a recovery */
3337 control_recover(ctdb, argc, argv);
3343 static const struct {
3345 int (*fn)(struct ctdb_context *, int, const char **);
3347 bool without_daemon; /* can be run without daemon running ? */
3350 } ctdb_commands[] = {
3352 { "version", control_version, true, false, "show version of ctdb" },
3354 { "status", control_status, true, false, "show node status" },
3355 { "uptime", control_uptime, true, false, "show node uptime" },
3356 { "ping", control_ping, true, false, "ping all nodes" },
3357 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
3358 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
3359 { "listvars", control_listvars, true, false, "list tunable variables"},
3360 { "statistics", control_statistics, false, false, "show statistics" },
3361 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
3362 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
3363 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
3364 { "getdbmap", control_getdbmap, true, false, "show the database map" },
3365 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
3366 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
3367 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
3368 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
3369 { "lvs", control_lvs, true, false, "show lvs configuration" },
3370 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
3371 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
3372 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
3373 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
3374 { "getdebug", control_getdebug, true, false, "get debug level" },
3375 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
3376 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
3377 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
3378 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
3379 { "disable", control_disable, true, false, "disable a nodes public IP" },
3380 { "enable", control_enable, true, false, "enable a nodes public IP" },
3381 { "stop", control_stop, true, false, "stop a node" },
3382 { "continue", control_continue, true, false, "re-start a stopped node" },
3383 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
3384 { "unban", control_unban, true, false, "unban a node" },
3385 { "showban", control_showban, true, false, "show ban information"},
3386 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
3387 { "recover", control_recover, true, false, "force recovery" },
3388 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
3389 { "freeze", control_freeze, true, false, "freeze all databases" },
3390 { "thaw", control_thaw, true, false, "thaw all databases" },
3391 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
3392 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
3393 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
3394 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
3395 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
3397 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
3398 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
3399 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
3400 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
3401 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
3402 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
3403 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
3404 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
3405 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
3406 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
3407 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
3408 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
3409 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
3410 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
3411 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
3412 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
3413 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts"},
3414 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
3415 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
3416 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
3417 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
3418 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
3419 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
3420 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
3421 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
3422 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
3428 static void usage(void)
3432 "Usage: ctdb [options] <control>\n" \
3434 " -n <node> choose node number, or 'all' (defaults to local node)\n"
3435 " -Y generate machinereadable output\n"
3436 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
3437 printf("Controls:\n");
3438 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3439 printf(" %-15s %-27s %s\n",
3440 ctdb_commands[i].name,
3441 ctdb_commands[i].args?ctdb_commands[i].args:"",
3442 ctdb_commands[i].msg);
3448 static void ctdb_alarm(int sig)
3450 printf("Maximum runtime exceeded - exiting\n");
3457 int main(int argc, const char *argv[])
3459 struct ctdb_context *ctdb;
3460 char *nodestring = NULL;
3461 struct poptOption popt_options[] = {
3464 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3465 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3466 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3467 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3471 const char **extra_argv;
3475 struct event_context *ev;
3476 const char *control;
3480 /* set some defaults */
3481 options.maxruntime = 0;
3482 options.timelimit = 3;
3483 options.pnn = CTDB_CURRENT_NODE;
3485 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3487 while ((opt = poptGetNextOpt(pc)) != -1) {
3490 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
3491 poptBadOption(pc, 0), poptStrerror(opt)));
3496 /* setup the remaining options for the main program to use */
3497 extra_argv = poptGetArgs(pc);
3500 while (extra_argv[extra_argc]) extra_argc++;
3503 if (extra_argc < 1) {
3507 if (options.maxruntime == 0) {
3508 const char *ctdb_timeout;
3509 ctdb_timeout = getenv("CTDB_TIMEOUT");
3510 if (ctdb_timeout != NULL) {
3511 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3513 /* default timeout is 120 seconds */
3514 options.maxruntime = 120;
3518 signal(SIGALRM, ctdb_alarm);
3519 alarm(options.maxruntime);
3521 /* setup the node number to contact */
3522 if (nodestring != NULL) {
3523 if (strcmp(nodestring, "all") == 0) {
3524 options.pnn = CTDB_BROADCAST_ALL;
3526 options.pnn = strtoul(nodestring, NULL, 0);
3530 control = extra_argv[0];
3532 ev = event_context_init(NULL);
3534 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3535 if (strcmp(control, ctdb_commands[i].name) == 0) {
3538 if (ctdb_commands[i].without_daemon == true) {
3542 /* initialise ctdb */
3543 ctdb = ctdb_cmdline_client(ev);
3545 if (ctdb_commands[i].without_daemon == false) {
3547 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3551 /* verify the node exists */
3554 if (options.pnn == CTDB_CURRENT_NODE) {
3556 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
3564 if (ctdb_commands[i].auto_all &&
3565 options.pnn == CTDB_BROADCAST_ALL) {
3570 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
3571 CTDB_NO_MEMORY(ctdb, nodes);
3573 for (j=0;j<num_nodes;j++) {
3574 options.pnn = nodes[j];
3575 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3579 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3585 if (i == ARRAY_SIZE(ctdb_commands)) {
3586 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));