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 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
861 struct ctdb_all_public_ips *ips;
862 struct ctdb_public_ip ip;
865 uint32_t disable_time;
867 struct ctdb_node_map *nodemap=NULL;
868 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
871 data.dptr = (uint8_t*)&disable_time;
872 data.dsize = sizeof(disable_time);
873 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
875 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
881 /* read the public ip list from the node */
882 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
884 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
885 talloc_free(tmp_ctx);
889 for (i=0;i<ips->num;i++) {
890 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
895 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
896 pnn, ctdb_addr_to_str(addr)));
897 talloc_free(tmp_ctx);
904 data.dptr = (uint8_t *)&ip;
905 data.dsize = sizeof(ip);
907 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
909 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
910 talloc_free(tmp_ctx);
914 nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
915 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
922 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
923 talloc_free(tmp_ctx);
927 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
929 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
930 talloc_free(tmp_ctx);
934 talloc_free(tmp_ctx);
939 move/failover an ip address to a specific node
941 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
951 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
952 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
957 if (sscanf(argv[1], "%u", &pnn) != 1) {
958 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
962 if (move_ip(ctdb, &addr, pnn) != 0) {
963 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
970 void getips_store_callback(void *param, void *data)
972 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
973 struct ctdb_all_public_ips *ips = param;
977 ips->ips[i].pnn = node_ip->pnn;
978 ips->ips[i].addr = node_ip->addr;
981 void getips_count_callback(void *param, void *data)
983 uint32_t *count = param;
989 static uint32_t *ip_key(ctdb_sock_addr *ip)
991 static uint32_t key[IP_KEYLEN];
993 bzero(key, sizeof(key));
995 switch (ip->sa.sa_family) {
997 key[0] = ip->ip.sin_addr.s_addr;
1000 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
1001 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
1002 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
1003 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
1006 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1013 static void *add_ip_callback(void *parm, void *data)
1019 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1021 struct ctdb_all_public_ips *tmp_ips;
1022 struct ctdb_node_map *nodemap=NULL;
1023 trbt_tree_t *ip_tree;
1027 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1029 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1033 ip_tree = trbt_create(tmp_ctx, 0);
1035 for(i=0;i<nodemap->num;i++){
1036 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1039 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1043 /* read the public ip list from this node */
1044 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1046 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1050 for (j=0; j<tmp_ips->num;j++) {
1051 struct ctdb_public_ip *node_ip;
1053 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1054 node_ip->pnn = tmp_ips->ips[j].pnn;
1055 node_ip->addr = tmp_ips->ips[j].addr;
1057 trbt_insertarray32_callback(ip_tree,
1058 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1062 talloc_free(tmp_ips);
1067 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1069 len = offsetof(struct ctdb_all_public_ips, ips) +
1070 count*sizeof(struct ctdb_public_ip);
1071 tmp_ips = talloc_zero_size(tmp_ctx, len);
1072 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1081 * scans all other nodes and returns a pnn for another node that can host this
1085 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1087 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1088 struct ctdb_all_public_ips *ips;
1089 struct ctdb_node_map *nodemap=NULL;
1092 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1094 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1095 talloc_free(tmp_ctx);
1099 for(i=0;i<nodemap->num;i++){
1100 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1103 if (nodemap->nodes[i].pnn == options.pnn) {
1107 /* read the public ip list from this node */
1108 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1110 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1114 for (j=0;j<ips->num;j++) {
1115 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1116 talloc_free(tmp_ctx);
1117 return nodemap->nodes[i].pnn;
1123 talloc_free(tmp_ctx);
1128 add a public ip address to a node
1130 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1136 ctdb_sock_addr addr;
1137 struct ctdb_control_ip_iface *pub;
1138 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1139 struct ctdb_all_public_ips *ips;
1143 talloc_free(tmp_ctx);
1147 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1148 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1149 talloc_free(tmp_ctx);
1153 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1155 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1156 talloc_free(tmp_ctx);
1161 /* check if some other node is already serving this ip, if not,
1164 for (i=0;i<ips->num;i++) {
1165 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1170 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1171 pub = talloc_size(tmp_ctx, len);
1172 CTDB_NO_MEMORY(ctdb, pub);
1176 pub->len = strlen(argv[1])+1;
1177 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1179 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1181 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1182 talloc_free(tmp_ctx);
1186 if (i == ips->num) {
1187 /* no one has this ip so we claim it */
1190 pnn = ips->ips[i].pnn;
1193 if (move_ip(ctdb, &addr, pnn) != 0) {
1194 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1198 talloc_free(tmp_ctx);
1202 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1204 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1206 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1207 struct ctdb_node_map *nodemap=NULL;
1208 struct ctdb_all_public_ips *ips;
1211 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1213 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1217 /* remove it from the nodes that are not hosting the ip currently */
1218 for(i=0;i<nodemap->num;i++){
1219 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1222 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1223 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1227 for (j=0;j<ips->num;j++) {
1228 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1236 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1240 options.pnn = nodemap->nodes[i].pnn;
1241 control_delip(ctdb, argc, argv);
1245 /* remove it from every node (also the one hosting it) */
1246 for(i=0;i<nodemap->num;i++){
1247 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1250 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1251 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1255 for (j=0;j<ips->num;j++) {
1256 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1264 options.pnn = nodemap->nodes[i].pnn;
1265 control_delip(ctdb, argc, argv);
1268 talloc_free(tmp_ctx);
1273 delete a public ip address from a node
1275 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1278 ctdb_sock_addr addr;
1279 struct ctdb_control_ip_iface pub;
1280 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1281 struct ctdb_all_public_ips *ips;
1284 talloc_free(tmp_ctx);
1288 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1289 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1293 if (options.pnn == CTDB_BROADCAST_ALL) {
1294 return control_delip_all(ctdb, argc, argv, &addr);
1301 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1303 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1304 talloc_free(tmp_ctx);
1308 for (i=0;i<ips->num;i++) {
1309 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1315 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1316 ctdb_addr_to_str(&addr)));
1317 talloc_free(tmp_ctx);
1321 if (ips->ips[i].pnn == options.pnn) {
1322 ret = find_other_host_for_public_ip(ctdb, &addr);
1324 if (move_ip(ctdb, &addr, ret) != 0) {
1325 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1331 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1333 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1334 talloc_free(tmp_ctx);
1338 talloc_free(tmp_ctx);
1343 kill a tcp connection
1345 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1348 struct ctdb_control_killtcp killtcp;
1354 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1355 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1359 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1360 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1364 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1366 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1377 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1380 ctdb_sock_addr addr;
1386 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1387 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1391 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1393 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1401 register a server id
1403 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1406 struct ctdb_server_id server_id;
1412 server_id.pnn = strtoul(argv[0], NULL, 0);
1413 server_id.type = strtoul(argv[1], NULL, 0);
1414 server_id.server_id = strtoul(argv[2], NULL, 0);
1416 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1418 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1425 unregister a server id
1427 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1430 struct ctdb_server_id server_id;
1436 server_id.pnn = strtoul(argv[0], NULL, 0);
1437 server_id.type = strtoul(argv[1], NULL, 0);
1438 server_id.server_id = strtoul(argv[2], NULL, 0);
1440 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1442 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1449 check if a server id exists
1451 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1455 struct ctdb_server_id server_id;
1461 server_id.pnn = strtoul(argv[0], NULL, 0);
1462 server_id.type = strtoul(argv[1], NULL, 0);
1463 server_id.server_id = strtoul(argv[2], NULL, 0);
1465 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1467 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1472 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1474 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1480 get a list of all server ids that are registered on a node
1482 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1485 struct ctdb_server_id_list *server_ids;
1487 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1489 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1493 for (i=0; i<server_ids->num; i++) {
1494 printf("Server id %d:%d:%d\n",
1495 server_ids->server_ids[i].pnn,
1496 server_ids->server_ids[i].type,
1497 server_ids->server_ids[i].server_id);
1504 send a tcp tickle ack
1506 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1509 ctdb_sock_addr src, dst;
1515 if (!parse_ip_port(argv[0], &src)) {
1516 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1520 if (!parse_ip_port(argv[1], &dst)) {
1521 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1525 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1529 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1536 display public ip status
1538 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1541 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1542 struct ctdb_all_public_ips *ips;
1544 if (options.pnn == CTDB_BROADCAST_ALL) {
1545 /* read the list of public ips from all nodes */
1546 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1548 /* read the public ip list from this node */
1549 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1552 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1553 talloc_free(tmp_ctx);
1557 if (options.machinereadable){
1558 printf(":Public IP:Node:\n");
1560 if (options.pnn == CTDB_BROADCAST_ALL) {
1561 printf("Public IPs on ALL nodes\n");
1563 printf("Public IPs on node %u\n", options.pnn);
1567 for (i=1;i<=ips->num;i++) {
1568 if (options.machinereadable){
1569 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1571 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1575 talloc_free(tmp_ctx);
1580 display pid of a ctdb daemon
1582 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1587 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1589 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1592 printf("Pid:%d\n", pid);
1598 handler for receiving the response to ipreallocate
1600 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1601 TDB_DATA data, void *private_data)
1606 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1608 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1610 event_add_timed(ctdb->ev, ctdb,
1611 timeval_current_ofs(1, 0),
1612 ctdb_every_second, ctdb);
1616 ask the recovery daemon on the recovery master to perform a ip reallocation
1618 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1622 struct rd_memdump_reply rd;
1624 struct ctdb_node_map *nodemap=NULL;
1626 struct timeval tv = timeval_current();
1628 /* we need some events to trigger so we can timeout and restart
1631 event_add_timed(ctdb->ev, ctdb,
1632 timeval_current_ofs(1, 0),
1633 ctdb_every_second, ctdb);
1635 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1637 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1640 rd.srvid = getpid();
1642 /* register a message port for receiveing the reply so that we
1643 can receive the reply
1645 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1647 data.dptr = (uint8_t *)&rd;
1648 data.dsize = sizeof(rd);
1652 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1656 /* check that there are valid nodes available */
1657 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1658 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1661 for (i=0; i<nodemap->num;i++) {
1662 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1666 if (i==nodemap->num) {
1667 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1672 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1674 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1678 /* verify the node exists */
1679 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1680 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1685 /* check tha there are nodes available that can act as a recmaster */
1686 for (i=0; i<nodemap->num; i++) {
1687 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1691 if (i == nodemap->num) {
1695 /* verify the recovery master is not STOPPED, nor BANNED */
1696 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1697 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1704 /* verify the recovery master is not STOPPED, nor BANNED */
1705 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1706 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1712 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1714 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1718 tv = timeval_current();
1719 /* this loop will terminate when we have received the reply */
1720 while (timeval_elapsed(&tv) < 3.0) {
1721 event_loop_once(ctdb->ev);
1724 DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1734 disable a remote node
1736 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1739 struct ctdb_node_map *nodemap=NULL;
1742 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1744 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1750 /* read the nodemap and verify the change took effect */
1751 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1752 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1756 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1757 ret = control_ipreallocate(ctdb, argc, argv);
1759 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1767 enable a disabled remote node
1769 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1773 struct ctdb_node_map *nodemap=NULL;
1776 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1778 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1784 /* read the nodemap and verify the change took effect */
1785 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1786 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1790 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1791 ret = control_ipreallocate(ctdb, argc, argv);
1793 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1803 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1806 struct ctdb_node_map *nodemap=NULL;
1809 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1811 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
1816 /* read the nodemap and verify the change took effect */
1817 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1818 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1822 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1823 ret = control_ipreallocate(ctdb, argc, argv);
1825 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1833 restart a stopped remote node
1835 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1839 struct ctdb_node_map *nodemap=NULL;
1842 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1844 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1850 /* read the nodemap and verify the change took effect */
1851 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1852 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1856 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1857 ret = control_ipreallocate(ctdb, argc, argv);
1859 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1866 static uint32_t get_generation(struct ctdb_context *ctdb)
1868 struct ctdb_vnn_map *vnnmap=NULL;
1871 /* wait until the recmaster is not in recovery mode */
1873 uint32_t recmode, recmaster;
1875 if (vnnmap != NULL) {
1876 talloc_free(vnnmap);
1880 /* get the recmaster */
1881 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1883 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1887 /* get recovery mode */
1888 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1890 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1894 /* get the current generation number */
1895 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
1897 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
1901 if ((recmode == CTDB_RECOVERY_NORMAL)
1902 && (vnnmap->generation != 1)){
1903 return vnnmap->generation;
1910 ban a node from the cluster
1912 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
1915 struct ctdb_node_map *nodemap=NULL;
1916 struct ctdb_ban_time bantime;
1922 /* verify the node exists */
1923 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1925 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1929 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
1930 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
1934 bantime.pnn = options.pnn;
1935 bantime.time = strtoul(argv[0], NULL, 0);
1937 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1939 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
1943 ret = control_ipreallocate(ctdb, argc, argv);
1945 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1954 unban a node from the cluster
1956 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
1959 struct ctdb_node_map *nodemap=NULL;
1960 struct ctdb_ban_time bantime;
1962 /* verify the node exists */
1963 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1965 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1969 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
1970 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
1974 bantime.pnn = options.pnn;
1977 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1979 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
1983 ret = control_ipreallocate(ctdb, argc, argv);
1985 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1994 show ban information for a node
1996 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
1999 struct ctdb_node_map *nodemap=NULL;
2000 struct ctdb_ban_time *bantime;
2002 /* verify the node exists */
2003 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2005 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2009 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2011 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2015 if (bantime->time == 0) {
2016 printf("Node %u is not banned\n", bantime->pnn);
2018 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2027 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2031 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2033 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2043 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2046 uint32_t generation, next_generation;
2048 /* record the current generation number */
2049 generation = get_generation(ctdb);
2051 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2053 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2057 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2059 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2063 /* wait until we are in a new generation */
2065 next_generation = get_generation(ctdb);
2066 if (next_generation != generation) {
2077 display monitoring mode of a remote node
2079 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2084 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2086 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2089 if (!options.machinereadable){
2090 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2093 printf(":%d:\n",monmode);
2100 display capabilities of a remote node
2102 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2104 uint32_t capabilities;
2107 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2109 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2113 if (!options.machinereadable){
2114 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2115 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2116 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2117 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2119 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2120 printf(":%d:%d:%d:%d:\n",
2121 !!(capabilities&CTDB_CAP_RECMASTER),
2122 !!(capabilities&CTDB_CAP_LMASTER),
2123 !!(capabilities&CTDB_CAP_LVS),
2124 !!(capabilities&CTDB_CAP_NATGW));
2130 display lvs configuration
2132 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2134 uint32_t *capabilities;
2135 struct ctdb_node_map *nodemap=NULL;
2137 int healthy_count = 0;
2139 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2141 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2145 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2146 CTDB_NO_MEMORY(ctdb, capabilities);
2148 /* collect capabilities for all connected nodes */
2149 for (i=0; i<nodemap->num; i++) {
2150 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2153 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2157 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2159 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2163 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2167 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2172 /* Print all LVS nodes */
2173 for (i=0; i<nodemap->num; i++) {
2174 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2177 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2180 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2184 if (healthy_count != 0) {
2185 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2190 printf("%d:%s\n", i,
2191 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2198 display who is the lvs master
2200 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2202 uint32_t *capabilities;
2203 struct ctdb_node_map *nodemap=NULL;
2205 int healthy_count = 0;
2207 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2209 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2213 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2214 CTDB_NO_MEMORY(ctdb, capabilities);
2216 /* collect capabilities for all connected nodes */
2217 for (i=0; i<nodemap->num; i++) {
2218 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2221 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2225 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2227 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2231 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2235 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2240 /* find and show the lvsmaster */
2241 for (i=0; i<nodemap->num; i++) {
2242 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2245 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2248 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2252 if (healthy_count != 0) {
2253 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2258 if (options.machinereadable){
2261 printf("Node %d is LVS master\n", i);
2266 printf("There is no LVS master\n");
2271 disable monitoring on a node
2273 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2278 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2280 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2283 printf("Monitoring mode:%s\n","DISABLED");
2289 enable monitoring on a node
2291 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2296 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2298 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2301 printf("Monitoring mode:%s\n","ACTIVE");
2307 display remote list of keys/data for a db
2309 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2311 const char *db_name;
2312 struct ctdb_db_context *ctdb_db;
2322 if (db_exists(ctdb, db_name)) {
2323 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2327 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2329 if (ctdb_db == NULL) {
2330 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2334 /* traverse and dump the cluster tdb */
2335 ret = ctdb_dump_db(ctdb_db, stdout);
2337 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2340 talloc_free(ctdb_db);
2342 printf("Dumped %d records\n", ret);
2348 display a list of the databases on a remote ctdb
2350 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2353 struct ctdb_dbid_map *dbmap=NULL;
2355 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2357 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2361 printf("Number of databases:%d\n", dbmap->num);
2362 for(i=0;i<dbmap->num;i++){
2367 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2368 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2369 persistent = dbmap->dbs[i].persistent;
2370 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name,
2371 path, persistent?"PERSISTENT":"");
2378 check if the local node is recmaster or not
2379 it will return 1 if this node is the recmaster and 0 if it is not
2380 or if the local ctdb daemon could not be contacted
2382 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2384 uint32_t mypnn, recmaster;
2387 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2389 printf("Failed to get pnn of node\n");
2393 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2395 printf("Failed to get the recmaster\n");
2399 if (recmaster != mypnn) {
2400 printf("this node is not the recmaster\n");
2404 printf("this node is the recmaster\n");
2411 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2414 struct timeval tv = timeval_current();
2415 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2417 printf("Unable to get ping response from node %u\n", options.pnn);
2420 printf("response from %u time=%.6f sec (%d clients)\n",
2421 options.pnn, timeval_elapsed(&tv), ret);
2430 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2441 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2443 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2447 printf("%-19s = %u\n", name, value);
2454 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2465 value = strtoul(argv[1], NULL, 0);
2467 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2469 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2478 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2484 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2486 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2490 for (i=0;i<count;i++) {
2491 control_getvar(ctdb, 1, &list[i]);
2500 display debug level on a node
2502 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2507 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2509 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2512 if (options.machinereadable){
2513 printf(":Name:Level:\n");
2514 printf(":%s:%d:\n",get_debug_by_level(level),level);
2516 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2523 display reclock file of a node
2525 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2528 const char *reclock;
2530 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2532 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2535 if (options.machinereadable){
2536 if (reclock != NULL) {
2537 printf("%s", reclock);
2540 if (reclock == NULL) {
2541 printf("No reclock file used.\n");
2543 printf("Reclock file:%s\n", reclock);
2551 set the reclock file of a node
2553 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2556 const char *reclock;
2560 } else if (argc == 1) {
2566 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2568 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2575 set the natgw state on/off
2577 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2580 uint32_t natgwstate;
2586 if (!strcmp(argv[0], "on")) {
2588 } else if (!strcmp(argv[0], "off")) {
2594 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2596 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2604 set the lmaster role on/off
2606 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2609 uint32_t lmasterrole;
2615 if (!strcmp(argv[0], "on")) {
2617 } else if (!strcmp(argv[0], "off")) {
2623 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2625 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2633 set the recmaster role on/off
2635 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2638 uint32_t recmasterrole;
2644 if (!strcmp(argv[0], "on")) {
2646 } else if (!strcmp(argv[0], "off")) {
2652 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2654 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2662 set debug level on a node or all nodes
2664 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2670 printf("You must specify the debug level. Valid levels are:\n");
2671 for (i=0; debug_levels[i].description != NULL; i++) {
2672 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2678 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2679 level = get_debug_by_desc(argv[0]);
2681 level = strtol(argv[0], NULL, 0);
2684 for (i=0; debug_levels[i].description != NULL; i++) {
2685 if (level == debug_levels[i].level) {
2689 if (debug_levels[i].description == NULL) {
2690 printf("Invalid debug level, must be one of\n");
2691 for (i=0; debug_levels[i].description != NULL; i++) {
2692 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2697 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2699 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2708 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2714 priority = strtol(argv[0], NULL, 0);
2718 DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
2720 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2722 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2730 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2736 priority = strtol(argv[0], NULL, 0);
2740 DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
2742 ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2744 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2751 attach to a database
2753 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2755 const char *db_name;
2756 struct ctdb_db_context *ctdb_db;
2763 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2764 if (ctdb_db == NULL) {
2765 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2775 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2777 struct ctdb_db_priority db_prio;
2784 db_prio.db_id = strtoul(argv[0], NULL, 0);
2785 db_prio.priority = strtoul(argv[1], NULL, 0);
2787 ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
2789 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
2799 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2801 uint32_t db_id, priority;
2808 db_id = strtoul(argv[0], NULL, 0);
2810 ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
2812 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
2816 DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
2822 run an eventscript on a node
2824 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
2830 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2833 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2837 data.dptr = (unsigned char *)discard_const(argv[0]);
2838 data.dsize = strlen((char *)data.dptr) + 1;
2840 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
2842 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
2843 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2844 if (ret != 0 || res != 0) {
2845 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
2846 talloc_free(tmp_ctx);
2849 talloc_free(tmp_ctx);
2853 #define DB_VERSION 1
2854 #define MAX_DB_NAME 64
2855 struct db_file_header {
2856 unsigned long version;
2858 unsigned long persistent;
2860 const char name[MAX_DB_NAME];
2863 struct backup_data {
2864 struct ctdb_marshall_buffer *records;
2867 bool traverse_error;
2870 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
2872 struct backup_data *bd = talloc_get_type(private, struct backup_data);
2873 struct ctdb_rec_data *rec;
2875 /* add the record */
2876 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
2878 bd->traverse_error = true;
2879 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
2882 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
2883 if (bd->records == NULL) {
2884 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
2885 bd->traverse_error = true;
2888 bd->records->count++;
2889 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
2890 bd->len += rec->length;
2898 * backup a database to a file
2900 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
2903 struct ctdb_dbid_map *dbmap=NULL;
2904 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2905 struct db_file_header dbhdr;
2906 struct ctdb_db_context *ctdb_db;
2907 struct backup_data *bd;
2912 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2916 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
2918 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2922 for(i=0;i<dbmap->num;i++){
2925 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
2926 if(!strcmp(argv[0], name)){
2927 talloc_free(discard_const(name));
2930 talloc_free(discard_const(name));
2932 if (i == dbmap->num) {
2933 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
2934 talloc_free(tmp_ctx);
2939 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
2940 if (ctdb_db == NULL) {
2941 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
2942 talloc_free(tmp_ctx);
2947 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
2949 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
2950 talloc_free(tmp_ctx);
2955 bd = talloc_zero(tmp_ctx, struct backup_data);
2957 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
2958 talloc_free(tmp_ctx);
2962 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
2963 if (bd->records == NULL) {
2964 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
2965 talloc_free(tmp_ctx);
2969 bd->len = offsetof(struct ctdb_marshall_buffer, data);
2970 bd->records->db_id = ctdb_db->db_id;
2971 /* traverse the database collecting all records */
2972 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
2973 bd->traverse_error) {
2974 DEBUG(DEBUG_ERR,("Traverse error\n"));
2975 talloc_free(tmp_ctx);
2979 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2982 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
2984 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
2985 talloc_free(tmp_ctx);
2989 dbhdr.version = DB_VERSION;
2990 dbhdr.timestamp = time(NULL);
2991 dbhdr.persistent = dbmap->dbs[i].persistent;
2992 dbhdr.size = bd->len;
2993 if (strlen(argv[0]) >= MAX_DB_NAME) {
2994 DEBUG(DEBUG_ERR,("Too long dbname\n"));
2997 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
2998 ret = write(fh, &dbhdr, sizeof(dbhdr));
3000 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3003 ret = write(fh, bd->records, bd->len);
3005 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3014 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3017 talloc_free(tmp_ctx);
3022 * restore a database from a file
3024 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3027 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3030 struct db_file_header dbhdr;
3031 struct ctdb_db_context *ctdb_db;
3032 struct ctdb_node_map *nodemap=NULL;
3033 struct ctdb_vnn_map *vnnmap=NULL;
3035 struct ctdb_control_wipe_database w;
3037 uint32_t generation;
3042 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3046 fh = open(argv[0], O_RDONLY);
3048 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3049 talloc_free(tmp_ctx);
3053 read(fh, &dbhdr, sizeof(dbhdr));
3054 if (dbhdr.version != DB_VERSION) {
3055 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3056 talloc_free(tmp_ctx);
3060 outdata.dsize = dbhdr.size;
3061 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3062 if (outdata.dptr == NULL) {
3063 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3065 talloc_free(tmp_ctx);
3068 read(fh, outdata.dptr, outdata.dsize);
3071 tm = localtime(&dbhdr.timestamp);
3072 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3073 printf("Restoring database '%s' from backup @ %s\n",
3077 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3078 if (ctdb_db == NULL) {
3079 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3080 talloc_free(tmp_ctx);
3084 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3086 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3087 talloc_free(tmp_ctx);
3092 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3094 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3095 talloc_free(tmp_ctx);
3099 /* freeze all nodes */
3100 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3101 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3102 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3108 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3109 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3110 talloc_free(tmp_ctx);
3115 generation = vnnmap->generation;
3116 data.dptr = (void *)&generation;
3117 data.dsize = sizeof(generation);
3119 /* start a cluster wide transaction */
3120 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3121 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3123 TIMELIMIT(), false, data,
3126 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3131 w.db_id = ctdb_db->db_id;
3132 w.transaction_id = generation;
3134 data.dptr = (void *)&w;
3135 data.dsize = sizeof(w);
3137 /* wipe all the remote databases. */
3138 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3139 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3141 TIMELIMIT(), false, data,
3144 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3145 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3146 talloc_free(tmp_ctx);
3150 /* push the database */
3151 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3152 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3154 TIMELIMIT(), false, outdata,
3157 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3158 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3159 talloc_free(tmp_ctx);
3163 data.dptr = (void *)&generation;
3164 data.dsize = sizeof(generation);
3166 /* commit all the changes */
3167 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3169 TIMELIMIT(), false, data,
3172 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3173 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3174 talloc_free(tmp_ctx);
3179 /* thaw all nodes */
3180 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3181 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3187 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3188 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3189 talloc_free(tmp_ctx);
3194 talloc_free(tmp_ctx);
3199 * set flags of a node in the nodemap
3201 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3208 struct ctdb_node_flag_change c;
3215 if (sscanf(argv[0], "%d", &node) != 1) {
3216 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3220 if (sscanf(argv[1], "0x%x", &flags) != 1) {
3221 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3228 c.new_flags = flags;
3230 data.dsize = sizeof(c);
3231 data.dptr = (unsigned char *)&c;
3233 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
3234 data, NULL, NULL, &status, NULL, NULL);
3235 if (ret != 0 || status != 0) {
3236 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3245 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3251 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3252 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3253 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3254 if (ret != 0 || res != 0) {
3255 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3256 talloc_free(tmp_ctx);
3259 write(1, data.dptr, data.dsize);
3260 talloc_free(tmp_ctx);
3265 handler for memory dumps
3267 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
3268 TDB_DATA data, void *private_data)
3270 write(1, data.dptr, data.dsize);
3275 dump memory usage on the recovery daemon
3277 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3281 struct rd_memdump_reply rd;
3283 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3285 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3288 rd.srvid = getpid();
3290 /* register a message port for receiveing the reply so that we
3291 can receive the reply
3293 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3296 data.dptr = (uint8_t *)&rd;
3297 data.dsize = sizeof(rd);
3299 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3301 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3305 /* this loop will terminate when we have received the reply */
3307 event_loop_once(ctdb->ev);
3314 list all nodes in the cluster
3315 if the daemon is running, we read the data from the daemon.
3316 if the daemon is not running we parse the nodes file directly
3318 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3321 struct ctdb_node_map *nodemap=NULL;
3324 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3326 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3330 for(i=0;i<nodemap->num;i++){
3331 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3334 if (options.machinereadable){
3335 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3337 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3341 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3342 struct pnn_node *pnn_nodes;
3343 struct pnn_node *pnn_node;
3345 pnn_nodes = read_nodes_file(mem_ctx);
3346 if (pnn_nodes == NULL) {
3347 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3348 talloc_free(mem_ctx);
3352 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3353 ctdb_sock_addr addr;
3355 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3356 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3357 talloc_free(mem_ctx);
3361 if (options.machinereadable){
3362 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3364 printf("%s\n", pnn_node->addr);
3367 talloc_free(mem_ctx);
3374 reload the nodes file on the local node
3376 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3380 struct ctdb_node_map *nodemap=NULL;
3382 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3384 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3388 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3390 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3394 /* reload the nodes file on all remote nodes */
3395 for (i=0;i<nodemap->num;i++) {
3396 if (nodemap->nodes[i].pnn == mypnn) {
3399 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3400 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3401 nodemap->nodes[i].pnn);
3403 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3407 /* reload the nodes file on the local node */
3408 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3409 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3411 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3414 /* initiate a recovery */
3415 control_recover(ctdb, argc, argv);
3421 static const struct {
3423 int (*fn)(struct ctdb_context *, int, const char **);
3425 bool without_daemon; /* can be run without daemon running ? */
3428 } ctdb_commands[] = {
3430 { "version", control_version, true, false, "show version of ctdb" },
3432 { "status", control_status, true, false, "show node status" },
3433 { "uptime", control_uptime, true, false, "show node uptime" },
3434 { "ping", control_ping, true, false, "ping all nodes" },
3435 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
3436 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
3437 { "listvars", control_listvars, true, false, "list tunable variables"},
3438 { "statistics", control_statistics, false, false, "show statistics" },
3439 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
3440 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
3441 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
3442 { "getdbmap", control_getdbmap, true, false, "show the database map" },
3443 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
3444 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
3445 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
3446 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
3447 { "lvs", control_lvs, true, false, "show lvs configuration" },
3448 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
3449 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
3450 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
3451 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
3452 { "getdebug", control_getdebug, true, false, "get debug level" },
3453 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
3454 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
3455 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
3456 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
3457 { "disable", control_disable, true, false, "disable a nodes public IP" },
3458 { "enable", control_enable, true, false, "enable a nodes public IP" },
3459 { "stop", control_stop, true, false, "stop a node" },
3460 { "continue", control_continue, true, false, "re-start a stopped node" },
3461 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
3462 { "unban", control_unban, true, false, "unban a node" },
3463 { "showban", control_showban, true, false, "show ban information"},
3464 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
3465 { "recover", control_recover, true, false, "force recovery" },
3466 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
3467 { "freeze", control_freeze, true, false, "freeze databases", "[priority:1-3]" },
3468 { "thaw", control_thaw, true, false, "thaw databases", "[priority:1-3]" },
3469 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
3470 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
3471 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
3472 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
3473 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
3475 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
3476 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
3477 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
3478 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
3479 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
3480 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
3481 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
3482 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
3483 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
3484 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
3485 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
3486 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
3487 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
3488 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
3489 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
3490 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
3491 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts"},
3492 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
3493 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
3494 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
3495 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
3496 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
3497 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
3498 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
3499 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
3500 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
3501 { "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
3502 { "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
3508 static void usage(void)
3512 "Usage: ctdb [options] <control>\n" \
3514 " -n <node> choose node number, or 'all' (defaults to local node)\n"
3515 " -Y generate machinereadable output\n"
3516 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
3517 printf("Controls:\n");
3518 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3519 printf(" %-15s %-27s %s\n",
3520 ctdb_commands[i].name,
3521 ctdb_commands[i].args?ctdb_commands[i].args:"",
3522 ctdb_commands[i].msg);
3528 static void ctdb_alarm(int sig)
3530 printf("Maximum runtime exceeded - exiting\n");
3537 int main(int argc, const char *argv[])
3539 struct ctdb_context *ctdb;
3540 char *nodestring = NULL;
3541 struct poptOption popt_options[] = {
3544 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3545 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3546 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3547 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3551 const char **extra_argv;
3555 struct event_context *ev;
3556 const char *control;
3560 /* set some defaults */
3561 options.maxruntime = 0;
3562 options.timelimit = 3;
3563 options.pnn = CTDB_CURRENT_NODE;
3565 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3567 while ((opt = poptGetNextOpt(pc)) != -1) {
3570 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
3571 poptBadOption(pc, 0), poptStrerror(opt)));
3576 /* setup the remaining options for the main program to use */
3577 extra_argv = poptGetArgs(pc);
3580 while (extra_argv[extra_argc]) extra_argc++;
3583 if (extra_argc < 1) {
3587 if (options.maxruntime == 0) {
3588 const char *ctdb_timeout;
3589 ctdb_timeout = getenv("CTDB_TIMEOUT");
3590 if (ctdb_timeout != NULL) {
3591 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3593 /* default timeout is 120 seconds */
3594 options.maxruntime = 120;
3598 signal(SIGALRM, ctdb_alarm);
3599 alarm(options.maxruntime);
3601 /* setup the node number to contact */
3602 if (nodestring != NULL) {
3603 if (strcmp(nodestring, "all") == 0) {
3604 options.pnn = CTDB_BROADCAST_ALL;
3606 options.pnn = strtoul(nodestring, NULL, 0);
3610 control = extra_argv[0];
3612 ev = event_context_init(NULL);
3614 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3615 if (strcmp(control, ctdb_commands[i].name) == 0) {
3618 if (ctdb_commands[i].without_daemon == true) {
3622 /* initialise ctdb */
3623 ctdb = ctdb_cmdline_client(ev);
3625 if (ctdb_commands[i].without_daemon == false) {
3627 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3631 /* verify the node exists */
3634 if (options.pnn == CTDB_CURRENT_NODE) {
3636 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
3644 if (ctdb_commands[i].auto_all &&
3645 options.pnn == CTDB_BROADCAST_ALL) {
3650 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
3651 CTDB_NO_MEMORY(ctdb, nodes);
3653 for (j=0;j<num_nodes;j++) {
3654 options.pnn = nodes[j];
3655 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3659 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3665 if (i == ARRAY_SIZE(ctdb_commands)) {
3666 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));