4 Copyright (C) Andrew Tridgell 2007
5 Copyright (C) Ronnie Sahlberg 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "lib/events/events.h"
23 #include "system/time.h"
24 #include "system/filesys.h"
25 #include "system/network.h"
26 #include "system/locale.h"
29 #include "../include/ctdb.h"
30 #include "../include/ctdb_private.h"
31 #include "../common/rb_tree.h"
34 #define ERR_TIMEOUT 20 /* timed out trying to reach node */
35 #define ERR_NONODE 21 /* node does not exist */
36 #define ERR_DISNODE 22 /* node is disconnected */
38 static void usage(void);
47 #define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
50 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
53 #define XSTR(x) STR(x)
54 printf("CTDB version: %s\n", XSTR(CTDB_VERS));
61 verify that a node exists and is reachable
63 static void verify_node(struct ctdb_context *ctdb)
66 struct ctdb_node_map *nodemap=NULL;
68 if (options.pnn == CTDB_CURRENT_NODE) {
71 if (options.pnn == CTDB_BROADCAST_ALL) {
75 /* verify the node exists */
76 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
77 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
80 if (options.pnn >= nodemap->num) {
81 DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
84 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DELETED) {
85 DEBUG(DEBUG_ERR, ("Node %u is DELETED\n", options.pnn));
88 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
89 DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
93 /* verify we can access the node */
94 ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
96 DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
102 check if a database exists
104 static int db_exists(struct ctdb_context *ctdb, const char *db_name)
107 struct ctdb_dbid_map *dbmap=NULL;
109 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
111 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
115 for(i=0;i<dbmap->num;i++){
118 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
119 if (!strcmp(name, db_name)) {
128 see if a process exists
130 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
138 if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
139 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
143 ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
145 printf("%u:%u exists\n", pnn, pid);
147 printf("%u:%u does not exist\n", pnn, pid);
153 display statistics structure
155 static void show_statistics(struct ctdb_statistics *s)
157 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
159 const char *prefix=NULL;
165 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
166 STATISTICS_FIELD(num_clients),
167 STATISTICS_FIELD(frozen),
168 STATISTICS_FIELD(recovering),
169 STATISTICS_FIELD(client_packets_sent),
170 STATISTICS_FIELD(client_packets_recv),
171 STATISTICS_FIELD(node_packets_sent),
172 STATISTICS_FIELD(node_packets_recv),
173 STATISTICS_FIELD(keepalive_packets_sent),
174 STATISTICS_FIELD(keepalive_packets_recv),
175 STATISTICS_FIELD(node.req_call),
176 STATISTICS_FIELD(node.reply_call),
177 STATISTICS_FIELD(node.req_dmaster),
178 STATISTICS_FIELD(node.reply_dmaster),
179 STATISTICS_FIELD(node.reply_error),
180 STATISTICS_FIELD(node.req_message),
181 STATISTICS_FIELD(node.req_control),
182 STATISTICS_FIELD(node.reply_control),
183 STATISTICS_FIELD(client.req_call),
184 STATISTICS_FIELD(client.req_message),
185 STATISTICS_FIELD(client.req_control),
186 STATISTICS_FIELD(timeouts.call),
187 STATISTICS_FIELD(timeouts.control),
188 STATISTICS_FIELD(timeouts.traverse),
189 STATISTICS_FIELD(total_calls),
190 STATISTICS_FIELD(pending_calls),
191 STATISTICS_FIELD(lockwait_calls),
192 STATISTICS_FIELD(pending_lockwait_calls),
193 STATISTICS_FIELD(childwrite_calls),
194 STATISTICS_FIELD(pending_childwrite_calls),
195 STATISTICS_FIELD(memory_used),
196 STATISTICS_FIELD(max_hop_count),
198 printf("CTDB version %u\n", CTDB_VERSION);
199 for (i=0;i<ARRAY_SIZE(fields);i++) {
200 if (strchr(fields[i].name, '.')) {
201 preflen = strcspn(fields[i].name, ".")+1;
202 if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
203 prefix = fields[i].name;
204 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
209 printf(" %*s%-22s%*s%10u\n",
211 fields[i].name+preflen,
213 *(uint32_t *)(fields[i].offset+(uint8_t *)s));
215 printf(" %-30s %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
216 printf(" %-30s %.6f sec\n", "max_reclock_recd", s->reclock.recd);
218 printf(" %-30s %.6f sec\n", "max_call_latency", s->max_call_latency);
219 printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
220 printf(" %-30s %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
221 talloc_free(tmp_ctx);
225 display remote ctdb statistics combined from all nodes
227 static int control_statistics_all(struct ctdb_context *ctdb)
230 struct ctdb_statistics statistics;
234 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
235 CTDB_NO_MEMORY(ctdb, nodes);
237 ZERO_STRUCT(statistics);
239 for (i=0;i<num_nodes;i++) {
240 struct ctdb_statistics s1;
242 uint32_t *v1 = (uint32_t *)&s1;
243 uint32_t *v2 = (uint32_t *)&statistics;
245 offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
246 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
248 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
251 for (j=0;j<num_ints;j++) {
254 statistics.max_hop_count =
255 MAX(statistics.max_hop_count, s1.max_hop_count);
256 statistics.max_call_latency =
257 MAX(statistics.max_call_latency, s1.max_call_latency);
258 statistics.max_lockwait_latency =
259 MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
262 printf("Gathered statistics for %u nodes\n", num_nodes);
263 show_statistics(&statistics);
268 display remote ctdb statistics
270 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
273 struct ctdb_statistics statistics;
275 if (options.pnn == CTDB_BROADCAST_ALL) {
276 return control_statistics_all(ctdb);
279 ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
281 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
284 show_statistics(&statistics);
290 reset remote ctdb statistics
292 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
296 ret = ctdb_statistics_reset(ctdb, options.pnn);
298 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
306 display uptime of remote node
308 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
311 struct ctdb_uptime *uptime = NULL;
312 int tmp, days, hours, minutes, seconds;
314 ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
316 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
320 if (options.machinereadable){
321 printf(":Current Node Time:Ctdb Start Time:Last Recovery/Failover Time:Last Recovery/IPFailover Duration:\n");
322 printf(":%u:%u:%u:%lf\n",
323 (unsigned int)uptime->current_time.tv_sec,
324 (unsigned int)uptime->ctdbd_start_time.tv_sec,
325 (unsigned int)uptime->last_recovery_finished.tv_sec,
326 timeval_delta(&uptime->last_recovery_finished,
327 &uptime->last_recovery_started)
332 printf("Current time of node : %s", ctime(&uptime->current_time.tv_sec));
334 tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
342 printf("Ctdbd start time : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
344 tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
352 printf("Time of last recovery/failover: (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
354 printf("Duration of last recovery/failover: %lf seconds\n",
355 timeval_delta(&uptime->last_recovery_finished,
356 &uptime->last_recovery_started));
362 show the PNN of the current node
364 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
368 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
370 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
374 printf("PNN:%d\n", mypnn);
380 struct pnn_node *next;
385 static struct pnn_node *read_nodes_file(TALLOC_CTX *mem_ctx)
387 const char *nodes_list;
391 struct pnn_node *pnn_nodes = NULL;
392 struct pnn_node *pnn_node;
393 struct pnn_node *tmp_node;
395 /* read the nodes file */
396 nodes_list = getenv("CTDB_NODES");
397 if (nodes_list == NULL) {
398 nodes_list = "/etc/ctdb/nodes";
400 lines = file_lines_load(nodes_list, &nlines, mem_ctx);
404 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
407 for (i=0, pnn=0; i<nlines; i++) {
411 /* strip leading spaces */
412 while((*node == ' ') || (*node == '\t')) {
419 if (strcmp(node, "") == 0) {
422 pnn_node = talloc(mem_ctx, struct pnn_node);
423 pnn_node->pnn = pnn++;
424 pnn_node->addr = talloc_strdup(pnn_node, node);
425 pnn_node->next = pnn_nodes;
426 pnn_nodes = pnn_node;
429 /* swap them around so we return them in incrementing order */
430 pnn_node = pnn_nodes;
434 pnn_node = pnn_node->next;
436 tmp_node->next = pnn_nodes;
437 pnn_nodes = tmp_node;
444 show the PNN of the current node
445 discover the pnn by loading the nodes file and try to bind to all
446 addresses one at a time until the ip address is found.
448 static int control_xpnn(struct ctdb_context *ctdb, int argc, const char **argv)
450 TALLOC_CTX *mem_ctx = talloc_new(NULL);
451 struct pnn_node *pnn_nodes;
452 struct pnn_node *pnn_node;
454 pnn_nodes = read_nodes_file(mem_ctx);
455 if (pnn_nodes == NULL) {
456 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
457 talloc_free(mem_ctx);
461 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
464 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
465 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
466 talloc_free(mem_ctx);
470 if (ctdb_sys_have_ip(&addr)) {
471 printf("PNN:%d\n", pnn_node->pnn);
472 talloc_free(mem_ctx);
477 printf("Failed to detect which PNN this node is\n");
478 talloc_free(mem_ctx);
483 display remote ctdb status
485 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
488 struct ctdb_vnn_map *vnnmap=NULL;
489 struct ctdb_node_map *nodemap=NULL;
490 uint32_t recmode, recmaster;
493 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
498 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
500 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
504 if(options.machinereadable){
505 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:Stopped:\n");
506 for(i=0;i<nodemap->num;i++){
507 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
510 printf(":%d:%s:%d:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
511 ctdb_addr_to_str(&nodemap->nodes[i].addr),
512 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
513 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
514 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
515 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
516 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
521 printf("Number of nodes:%d\n", nodemap->num);
522 for(i=0;i<nodemap->num;i++){
523 static const struct {
527 { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" },
528 { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" },
529 { NODE_FLAGS_BANNED, "BANNED" },
530 { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" },
531 { NODE_FLAGS_DELETED, "DELETED" },
532 { NODE_FLAGS_STOPPED, "STOPPED" },
534 char *flags_str = NULL;
537 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
540 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
541 if (nodemap->nodes[i].flags & flag_names[j].flag) {
542 if (flags_str == NULL) {
543 flags_str = talloc_strdup(ctdb, flag_names[j].name);
545 flags_str = talloc_asprintf_append(flags_str, "|%s",
548 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
551 if (flags_str == NULL) {
552 flags_str = talloc_strdup(ctdb, "OK");
553 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
555 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
556 ctdb_addr_to_str(&nodemap->nodes[i].addr),
558 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
559 talloc_free(flags_str);
562 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
564 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
567 if (vnnmap->generation == INVALID_GENERATION) {
568 printf("Generation:INVALID\n");
570 printf("Generation:%d\n",vnnmap->generation);
572 printf("Size:%d\n",vnnmap->size);
573 for(i=0;i<vnnmap->size;i++){
574 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
577 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
579 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
582 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
584 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
586 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
589 printf("Recovery master:%d\n",recmaster);
596 struct natgw_node *next;
601 display the list of nodes belonging to this natgw configuration
603 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
606 const char *natgw_list;
609 struct natgw_node *natgw_nodes = NULL;
610 struct natgw_node *natgw_node;
611 struct ctdb_node_map *nodemap=NULL;
614 /* read the natgw nodes file into a linked list */
615 natgw_list = getenv("NATGW_NODES");
616 if (natgw_list == NULL) {
617 natgw_list = "/etc/ctdb/natgw_nodes";
619 lines = file_lines_load(natgw_list, &nlines, ctdb);
621 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
624 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
627 for (i=0;i<nlines;i++) {
631 /* strip leading spaces */
632 while((*node == ' ') || (*node == '\t')) {
638 if (strcmp(node, "") == 0) {
641 natgw_node = talloc(ctdb, struct natgw_node);
642 natgw_node->addr = talloc_strdup(natgw_node, node);
643 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
644 natgw_node->next = natgw_nodes;
645 natgw_nodes = natgw_node;
648 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
650 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
655 while(i<nodemap->num) {
656 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
657 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
662 /* this node was not in the natgw so we just remove it from
665 if ((natgw_node == NULL)
666 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
669 for (j=i+1; j<nodemap->num; j++) {
670 nodemap->nodes[j-1] = nodemap->nodes[j];
679 /* pick a node to be natgwmaster
680 * we dont allow STOPPED, DELETED, BANNED or UNHEALTHY nodes to become the natgwmaster
682 for(i=0;i<nodemap->num;i++){
683 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_UNHEALTHY))) {
684 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
688 /* we couldnt find any healthy node, try unhealthy ones */
689 if (i == nodemap->num) {
690 for(i=0;i<nodemap->num;i++){
691 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
692 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
697 /* unless all nodes are STOPPED, when we pick one anyway */
698 if (i == nodemap->num) {
699 for(i=0;i<nodemap->num;i++){
700 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
701 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
705 /* or if we still can not find any */
706 if (i == nodemap->num) {
707 printf("-1 0.0.0.0\n");
711 /* print the pruned list of nodes belonging to this natgw list */
712 for(i=0;i<nodemap->num;i++){
713 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
716 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
717 ctdb_addr_to_str(&nodemap->nodes[i].addr),
718 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
719 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
720 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
721 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
722 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
729 display the status of the scripts for monitoring (or other events)
731 static int control_one_scriptstatus(struct ctdb_context *ctdb,
732 enum ctdb_eventscript_call type)
734 struct ctdb_scripts_wire *script_status;
737 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, type, &script_status);
739 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
743 if (script_status == NULL) {
744 if (!options.machinereadable) {
745 printf("%s cycle never run\n",
746 ctdb_eventscript_call_names[type]);
751 if (!options.machinereadable) {
752 printf("%d scripts were executed last %s cycle\n",
753 script_status->num_scripts,
754 ctdb_eventscript_call_names[type]);
756 for (i=0; i<script_status->num_scripts; i++) {
757 const char *status = NULL;
759 switch (script_status->scripts[i].status) {
770 if (script_status->scripts[i].status > 0)
774 if (options.machinereadable) {
775 printf("%s:%s:%i:%s:%lu.%06lu:%lu.%06lu:%s:\n",
776 ctdb_eventscript_call_names[type],
777 script_status->scripts[i].name,
778 script_status->scripts[i].status,
780 (long)script_status->scripts[i].start.tv_sec,
781 (long)script_status->scripts[i].start.tv_usec,
782 (long)script_status->scripts[i].finished.tv_sec,
783 (long)script_status->scripts[i].finished.tv_usec,
784 script_status->scripts[i].output);
788 printf("%-20s Status:%s ",
789 script_status->scripts[i].name, status);
791 /* Some other error, eg from stat. */
792 printf("%-20s Status:CANNOT RUN (%s)",
793 script_status->scripts[i].name,
794 strerror(-script_status->scripts[i].status));
796 if (script_status->scripts[i].status >= 0) {
797 printf("Duration:%.3lf ",
798 timeval_delta(&script_status->scripts[i].finished,
799 &script_status->scripts[i].start));
801 if (script_status->scripts[i].status != -ENOEXEC) {
803 ctime(&script_status->scripts[i].start.tv_sec));
805 if (script_status->scripts[i].status != 0) {
806 printf(" OUTPUT:%s\n",
807 script_status->scripts[i].output);
814 static int control_scriptstatus(struct ctdb_context *ctdb,
815 int argc, const char **argv)
818 enum ctdb_eventscript_call type, min, max;
822 DEBUG(DEBUG_ERR, ("Unknown arguments to scriptstatus\n"));
827 arg = ctdb_eventscript_call_names[CTDB_EVENT_MONITOR];
831 for (type = 0; type < CTDB_EVENT_MAX; type++) {
832 if (strcmp(arg, ctdb_eventscript_call_names[type]) == 0) {
838 if (type == CTDB_EVENT_MAX) {
839 if (strcmp(arg, "all") == 0) {
841 max = CTDB_EVENT_MAX;
843 DEBUG(DEBUG_ERR, ("Unknown event type %s\n", argv[0]));
848 if (options.machinereadable) {
849 printf(":Type:Name:Code:Status:Start:End:Error Output...:\n");
852 for (type = min; type < max; type++) {
853 ret = control_one_scriptstatus(ctdb, type);
863 enable an eventscript
865 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
873 ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
875 DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
883 disable an eventscript
885 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
893 ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
895 DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
903 display the pnn of the recovery master
905 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
910 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
912 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
915 printf("%d\n",recmaster);
921 get a list of all tickles for this pnn
923 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
925 struct ctdb_control_tcp_tickle_list *list;
933 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
934 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
938 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
940 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
944 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
945 printf("Num tickles:%u\n", list->tickles.num);
946 for (i=0;i<list->tickles.num;i++) {
947 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
948 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));
958 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
960 struct ctdb_all_public_ips *ips;
961 struct ctdb_public_ip ip;
964 uint32_t disable_time;
966 struct ctdb_node_map *nodemap=NULL;
967 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
970 data.dptr = (uint8_t*)&disable_time;
971 data.dsize = sizeof(disable_time);
972 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
974 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
980 /* read the public ip list from the node */
981 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
983 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
984 talloc_free(tmp_ctx);
988 for (i=0;i<ips->num;i++) {
989 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
994 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
995 pnn, ctdb_addr_to_str(addr)));
996 talloc_free(tmp_ctx);
1003 data.dptr = (uint8_t *)&ip;
1004 data.dsize = sizeof(ip);
1006 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
1008 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1009 talloc_free(tmp_ctx);
1013 nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
1014 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
1021 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
1022 talloc_free(tmp_ctx);
1026 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
1028 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
1029 talloc_free(tmp_ctx);
1033 talloc_free(tmp_ctx);
1038 move/failover an ip address to a specific node
1040 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
1043 ctdb_sock_addr addr;
1050 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1051 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1056 if (sscanf(argv[1], "%u", &pnn) != 1) {
1057 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
1061 if (move_ip(ctdb, &addr, pnn) != 0) {
1062 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1069 void getips_store_callback(void *param, void *data)
1071 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
1072 struct ctdb_all_public_ips *ips = param;
1076 ips->ips[i].pnn = node_ip->pnn;
1077 ips->ips[i].addr = node_ip->addr;
1080 void getips_count_callback(void *param, void *data)
1082 uint32_t *count = param;
1088 static uint32_t *ip_key(ctdb_sock_addr *ip)
1090 static uint32_t key[IP_KEYLEN];
1092 bzero(key, sizeof(key));
1094 switch (ip->sa.sa_family) {
1096 key[0] = ip->ip.sin_addr.s_addr;
1099 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
1100 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
1101 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
1102 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
1105 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1112 static void *add_ip_callback(void *parm, void *data)
1118 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1120 struct ctdb_all_public_ips *tmp_ips;
1121 struct ctdb_node_map *nodemap=NULL;
1122 trbt_tree_t *ip_tree;
1126 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1128 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1132 ip_tree = trbt_create(tmp_ctx, 0);
1134 for(i=0;i<nodemap->num;i++){
1135 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1138 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1142 /* read the public ip list from this node */
1143 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1145 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1149 for (j=0; j<tmp_ips->num;j++) {
1150 struct ctdb_public_ip *node_ip;
1152 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1153 node_ip->pnn = tmp_ips->ips[j].pnn;
1154 node_ip->addr = tmp_ips->ips[j].addr;
1156 trbt_insertarray32_callback(ip_tree,
1157 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1161 talloc_free(tmp_ips);
1166 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1168 len = offsetof(struct ctdb_all_public_ips, ips) +
1169 count*sizeof(struct ctdb_public_ip);
1170 tmp_ips = talloc_zero_size(tmp_ctx, len);
1171 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1180 * scans all other nodes and returns a pnn for another node that can host this
1184 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1186 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1187 struct ctdb_all_public_ips *ips;
1188 struct ctdb_node_map *nodemap=NULL;
1191 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1193 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1194 talloc_free(tmp_ctx);
1198 for(i=0;i<nodemap->num;i++){
1199 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1202 if (nodemap->nodes[i].pnn == options.pnn) {
1206 /* read the public ip list from this node */
1207 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1209 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1213 for (j=0;j<ips->num;j++) {
1214 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1215 talloc_free(tmp_ctx);
1216 return nodemap->nodes[i].pnn;
1222 talloc_free(tmp_ctx);
1227 add a public ip address to a node
1229 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1235 ctdb_sock_addr addr;
1236 struct ctdb_control_ip_iface *pub;
1237 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1238 struct ctdb_all_public_ips *ips;
1242 talloc_free(tmp_ctx);
1246 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1247 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1248 talloc_free(tmp_ctx);
1252 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1254 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1255 talloc_free(tmp_ctx);
1260 /* check if some other node is already serving this ip, if not,
1263 for (i=0;i<ips->num;i++) {
1264 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1269 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1270 pub = talloc_size(tmp_ctx, len);
1271 CTDB_NO_MEMORY(ctdb, pub);
1275 pub->len = strlen(argv[1])+1;
1276 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1278 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1280 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1281 talloc_free(tmp_ctx);
1285 if (i == ips->num) {
1286 /* no one has this ip so we claim it */
1289 pnn = ips->ips[i].pnn;
1292 if (move_ip(ctdb, &addr, pnn) != 0) {
1293 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1297 talloc_free(tmp_ctx);
1301 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1303 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1305 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1306 struct ctdb_node_map *nodemap=NULL;
1307 struct ctdb_all_public_ips *ips;
1310 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1312 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1316 /* remove it from the nodes that are not hosting the ip currently */
1317 for(i=0;i<nodemap->num;i++){
1318 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1321 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1322 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1326 for (j=0;j<ips->num;j++) {
1327 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1335 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1339 options.pnn = nodemap->nodes[i].pnn;
1340 control_delip(ctdb, argc, argv);
1344 /* remove it from every node (also the one hosting it) */
1345 for(i=0;i<nodemap->num;i++){
1346 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1349 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1350 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1354 for (j=0;j<ips->num;j++) {
1355 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1363 options.pnn = nodemap->nodes[i].pnn;
1364 control_delip(ctdb, argc, argv);
1367 talloc_free(tmp_ctx);
1372 delete a public ip address from a node
1374 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1377 ctdb_sock_addr addr;
1378 struct ctdb_control_ip_iface pub;
1379 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1380 struct ctdb_all_public_ips *ips;
1383 talloc_free(tmp_ctx);
1387 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1388 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1392 if (options.pnn == CTDB_BROADCAST_ALL) {
1393 return control_delip_all(ctdb, argc, argv, &addr);
1400 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1402 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1403 talloc_free(tmp_ctx);
1407 for (i=0;i<ips->num;i++) {
1408 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1414 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1415 ctdb_addr_to_str(&addr)));
1416 talloc_free(tmp_ctx);
1420 if (ips->ips[i].pnn == options.pnn) {
1421 ret = find_other_host_for_public_ip(ctdb, &addr);
1423 if (move_ip(ctdb, &addr, ret) != 0) {
1424 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1430 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1432 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1433 talloc_free(tmp_ctx);
1437 talloc_free(tmp_ctx);
1442 kill a tcp connection
1444 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1447 struct ctdb_control_killtcp killtcp;
1453 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1454 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1458 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1459 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1463 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1465 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1476 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1479 ctdb_sock_addr addr;
1485 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1486 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1490 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1492 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1500 register a server id
1502 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1505 struct ctdb_server_id server_id;
1511 server_id.pnn = strtoul(argv[0], NULL, 0);
1512 server_id.type = strtoul(argv[1], NULL, 0);
1513 server_id.server_id = strtoul(argv[2], NULL, 0);
1515 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1517 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1524 unregister a server id
1526 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1529 struct ctdb_server_id server_id;
1535 server_id.pnn = strtoul(argv[0], NULL, 0);
1536 server_id.type = strtoul(argv[1], NULL, 0);
1537 server_id.server_id = strtoul(argv[2], NULL, 0);
1539 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1541 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1548 check if a server id exists
1550 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1554 struct ctdb_server_id server_id;
1560 server_id.pnn = strtoul(argv[0], NULL, 0);
1561 server_id.type = strtoul(argv[1], NULL, 0);
1562 server_id.server_id = strtoul(argv[2], NULL, 0);
1564 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1566 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1571 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1573 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1579 get a list of all server ids that are registered on a node
1581 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1584 struct ctdb_server_id_list *server_ids;
1586 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1588 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1592 for (i=0; i<server_ids->num; i++) {
1593 printf("Server id %d:%d:%d\n",
1594 server_ids->server_ids[i].pnn,
1595 server_ids->server_ids[i].type,
1596 server_ids->server_ids[i].server_id);
1603 send a tcp tickle ack
1605 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1608 ctdb_sock_addr src, dst;
1614 if (!parse_ip_port(argv[0], &src)) {
1615 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1619 if (!parse_ip_port(argv[1], &dst)) {
1620 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1624 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1628 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1635 display public ip status
1637 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1640 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1641 struct ctdb_all_public_ips *ips;
1643 if (options.pnn == CTDB_BROADCAST_ALL) {
1644 /* read the list of public ips from all nodes */
1645 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1647 /* read the public ip list from this node */
1648 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1651 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1652 talloc_free(tmp_ctx);
1656 if (options.machinereadable){
1657 printf(":Public IP:Node:\n");
1659 if (options.pnn == CTDB_BROADCAST_ALL) {
1660 printf("Public IPs on ALL nodes\n");
1662 printf("Public IPs on node %u\n", options.pnn);
1666 for (i=1;i<=ips->num;i++) {
1667 if (options.machinereadable){
1668 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1670 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1674 talloc_free(tmp_ctx);
1679 display pid of a ctdb daemon
1681 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1686 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1688 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1691 printf("Pid:%d\n", pid);
1697 handler for receiving the response to ipreallocate
1699 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1700 TDB_DATA data, void *private_data)
1705 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1707 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1709 event_add_timed(ctdb->ev, ctdb,
1710 timeval_current_ofs(1, 0),
1711 ctdb_every_second, ctdb);
1715 ask the recovery daemon on the recovery master to perform a ip reallocation
1717 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1721 struct takeover_run_reply rd;
1723 struct ctdb_node_map *nodemap=NULL;
1725 struct timeval tv = timeval_current();
1727 /* we need some events to trigger so we can timeout and restart
1730 event_add_timed(ctdb->ev, ctdb,
1731 timeval_current_ofs(1, 0),
1732 ctdb_every_second, ctdb);
1734 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1736 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1739 rd.srvid = getpid();
1741 /* register a message port for receiveing the reply so that we
1742 can receive the reply
1744 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1746 data.dptr = (uint8_t *)&rd;
1747 data.dsize = sizeof(rd);
1751 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1755 /* check that there are valid nodes available */
1756 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1757 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1760 for (i=0; i<nodemap->num;i++) {
1761 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1765 if (i==nodemap->num) {
1766 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1771 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1773 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1777 /* verify the node exists */
1778 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1779 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1784 /* check tha there are nodes available that can act as a recmaster */
1785 for (i=0; i<nodemap->num; i++) {
1786 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1791 if (i == nodemap->num) {
1792 DEBUG(DEBUG_ERR,("No possible nodes to host addresses.\n"));
1796 /* verify the recovery master is not STOPPED, nor BANNED */
1797 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1798 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1805 /* verify the recovery master is not STOPPED, nor BANNED */
1806 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1807 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1813 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1815 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1819 tv = timeval_current();
1820 /* this loop will terminate when we have received the reply */
1821 while (timeval_elapsed(&tv) < 3.0) {
1822 event_loop_once(ctdb->ev);
1825 DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1835 disable a remote node
1837 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1840 struct ctdb_node_map *nodemap=NULL;
1843 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1845 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1851 /* read the nodemap and verify the change took effect */
1852 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1853 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1857 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1858 ret = control_ipreallocate(ctdb, argc, argv);
1860 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1868 enable a disabled remote node
1870 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1874 struct ctdb_node_map *nodemap=NULL;
1877 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1879 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1885 /* read the nodemap and verify the change took effect */
1886 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1887 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1891 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1892 ret = control_ipreallocate(ctdb, argc, argv);
1894 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1904 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1907 struct ctdb_node_map *nodemap=NULL;
1910 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1912 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
1917 /* read the nodemap and verify the change took effect */
1918 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1919 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1923 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1924 ret = control_ipreallocate(ctdb, argc, argv);
1926 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1934 restart a stopped remote node
1936 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1940 struct ctdb_node_map *nodemap=NULL;
1943 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1945 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1951 /* read the nodemap and verify the change took effect */
1952 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1953 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1957 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1958 ret = control_ipreallocate(ctdb, argc, argv);
1960 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1967 static uint32_t get_generation(struct ctdb_context *ctdb)
1969 struct ctdb_vnn_map *vnnmap=NULL;
1972 /* wait until the recmaster is not in recovery mode */
1974 uint32_t recmode, recmaster;
1976 if (vnnmap != NULL) {
1977 talloc_free(vnnmap);
1981 /* get the recmaster */
1982 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1984 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1988 /* get recovery mode */
1989 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1991 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1995 /* get the current generation number */
1996 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
1998 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
2002 if ((recmode == CTDB_RECOVERY_NORMAL)
2003 && (vnnmap->generation != 1)){
2004 return vnnmap->generation;
2011 ban a node from the cluster
2013 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
2016 struct ctdb_node_map *nodemap=NULL;
2017 struct ctdb_ban_time bantime;
2023 /* verify the node exists */
2024 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2026 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2030 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
2031 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
2035 bantime.pnn = options.pnn;
2036 bantime.time = strtoul(argv[0], NULL, 0);
2038 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2040 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
2044 ret = control_ipreallocate(ctdb, argc, argv);
2046 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2055 unban a node from the cluster
2057 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
2060 struct ctdb_node_map *nodemap=NULL;
2061 struct ctdb_ban_time bantime;
2063 /* verify the node exists */
2064 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2066 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2070 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
2071 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
2075 bantime.pnn = options.pnn;
2078 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2080 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
2084 ret = control_ipreallocate(ctdb, argc, argv);
2086 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2095 show ban information for a node
2097 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
2100 struct ctdb_node_map *nodemap=NULL;
2101 struct ctdb_ban_time *bantime;
2103 /* verify the node exists */
2104 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2106 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2110 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2112 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2116 if (bantime->time == 0) {
2117 printf("Node %u is not banned\n", bantime->pnn);
2119 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2128 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2132 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2134 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2144 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2147 uint32_t generation, next_generation;
2149 /* record the current generation number */
2150 generation = get_generation(ctdb);
2152 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2154 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2158 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2160 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2164 /* wait until we are in a new generation */
2166 next_generation = get_generation(ctdb);
2167 if (next_generation != generation) {
2178 display monitoring mode of a remote node
2180 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2185 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2187 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2190 if (!options.machinereadable){
2191 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2194 printf(":%d:\n",monmode);
2201 display capabilities of a remote node
2203 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2205 uint32_t capabilities;
2208 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2210 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2214 if (!options.machinereadable){
2215 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2216 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2217 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2218 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2220 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2221 printf(":%d:%d:%d:%d:\n",
2222 !!(capabilities&CTDB_CAP_RECMASTER),
2223 !!(capabilities&CTDB_CAP_LMASTER),
2224 !!(capabilities&CTDB_CAP_LVS),
2225 !!(capabilities&CTDB_CAP_NATGW));
2231 display lvs configuration
2233 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2235 uint32_t *capabilities;
2236 struct ctdb_node_map *nodemap=NULL;
2238 int healthy_count = 0;
2240 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2242 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2246 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2247 CTDB_NO_MEMORY(ctdb, capabilities);
2249 /* collect capabilities for all connected nodes */
2250 for (i=0; i<nodemap->num; i++) {
2251 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2254 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2258 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2260 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2264 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2268 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2273 /* Print all LVS nodes */
2274 for (i=0; i<nodemap->num; i++) {
2275 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2278 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2281 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2285 if (healthy_count != 0) {
2286 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2291 printf("%d:%s\n", i,
2292 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2299 display who is the lvs master
2301 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2303 uint32_t *capabilities;
2304 struct ctdb_node_map *nodemap=NULL;
2306 int healthy_count = 0;
2308 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2310 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2314 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2315 CTDB_NO_MEMORY(ctdb, capabilities);
2317 /* collect capabilities for all connected nodes */
2318 for (i=0; i<nodemap->num; i++) {
2319 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2322 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2326 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2328 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2332 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2336 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2341 /* find and show the lvsmaster */
2342 for (i=0; i<nodemap->num; i++) {
2343 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2346 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2349 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2353 if (healthy_count != 0) {
2354 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2359 if (options.machinereadable){
2362 printf("Node %d is LVS master\n", i);
2367 printf("There is no LVS master\n");
2372 disable monitoring on a node
2374 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2379 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2381 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2384 printf("Monitoring mode:%s\n","DISABLED");
2390 enable monitoring on a node
2392 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2397 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2399 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2402 printf("Monitoring mode:%s\n","ACTIVE");
2408 display remote list of keys/data for a db
2410 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2412 const char *db_name;
2413 struct ctdb_db_context *ctdb_db;
2423 if (db_exists(ctdb, db_name)) {
2424 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2428 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2430 if (ctdb_db == NULL) {
2431 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2435 /* traverse and dump the cluster tdb */
2436 ret = ctdb_dump_db(ctdb_db, stdout);
2438 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2441 talloc_free(ctdb_db);
2443 printf("Dumped %d records\n", ret);
2448 static void log_handler(struct ctdb_context *ctdb, uint64_t srvid,
2449 TDB_DATA data, void *private_data)
2451 DEBUG(DEBUG_ERR,("Log data received\n"));
2452 if (data.dsize > 0) {
2453 printf("%s", data.dptr);
2460 display a list of log messages from the in memory ringbuffer
2462 static int control_getlog(struct ctdb_context *ctdb, int argc, const char **argv)
2466 struct ctdb_get_log_addr log_addr;
2468 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2473 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2474 talloc_free(tmp_ctx);
2478 log_addr.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2479 log_addr.srvid = getpid();
2480 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2481 log_addr.level = get_debug_by_desc(argv[0]);
2483 log_addr.level = strtol(argv[0], NULL, 0);
2487 data.dptr = (unsigned char *)&log_addr;
2488 data.dsize = sizeof(log_addr);
2490 DEBUG(DEBUG_ERR, ("Pulling logs from node %u\n", options.pnn));
2492 ctdb_set_message_handler(ctdb, log_addr.srvid, log_handler, NULL);
2495 DEBUG(DEBUG_ERR,("Listen for response on %d\n", (int)log_addr.srvid));
2497 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_GET_LOG,
2498 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2499 if (ret != 0 || res != 0) {
2500 DEBUG(DEBUG_ERR,("Failed to get logs - %s\n", errmsg));
2501 talloc_free(tmp_ctx);
2506 tv = timeval_current();
2507 /* this loop will terminate when we have received the reply */
2508 while (timeval_elapsed(&tv) < 3.0) {
2509 event_loop_once(ctdb->ev);
2512 DEBUG(DEBUG_INFO,("Timed out waiting for log data.\n"));
2514 talloc_free(tmp_ctx);
2519 clear the in memory log area
2521 static int control_clearlog(struct ctdb_context *ctdb, int argc, const char **argv)
2526 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2528 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_CLEAR_LOG,
2529 0, tdb_null, tmp_ctx, NULL, &res, NULL, &errmsg);
2530 if (ret != 0 || res != 0) {
2531 DEBUG(DEBUG_ERR,("Failed to clear logs\n"));
2532 talloc_free(tmp_ctx);
2536 talloc_free(tmp_ctx);
2543 display a list of the databases on a remote ctdb
2545 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2548 struct ctdb_dbid_map *dbmap=NULL;
2550 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2552 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2556 printf("Number of databases:%d\n", dbmap->num);
2557 for(i=0;i<dbmap->num;i++){
2562 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2563 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2564 persistent = dbmap->dbs[i].persistent;
2565 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name,
2566 path, persistent?"PERSISTENT":"");
2573 check if the local node is recmaster or not
2574 it will return 1 if this node is the recmaster and 0 if it is not
2575 or if the local ctdb daemon could not be contacted
2577 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2579 uint32_t mypnn, recmaster;
2582 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2584 printf("Failed to get pnn of node\n");
2588 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2590 printf("Failed to get the recmaster\n");
2594 if (recmaster != mypnn) {
2595 printf("this node is not the recmaster\n");
2599 printf("this node is the recmaster\n");
2606 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2609 struct timeval tv = timeval_current();
2610 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2612 printf("Unable to get ping response from node %u\n", options.pnn);
2615 printf("response from %u time=%.6f sec (%d clients)\n",
2616 options.pnn, timeval_elapsed(&tv), ret);
2625 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2636 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2638 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2642 printf("%-19s = %u\n", name, value);
2649 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2660 value = strtoul(argv[1], NULL, 0);
2662 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2664 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2673 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2679 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2681 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2685 for (i=0;i<count;i++) {
2686 control_getvar(ctdb, 1, &list[i]);
2695 display debug level on a node
2697 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2702 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2704 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2707 if (options.machinereadable){
2708 printf(":Name:Level:\n");
2709 printf(":%s:%d:\n",get_debug_by_level(level),level);
2711 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2718 display reclock file of a node
2720 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2723 const char *reclock;
2725 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2727 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2730 if (options.machinereadable){
2731 if (reclock != NULL) {
2732 printf("%s", reclock);
2735 if (reclock == NULL) {
2736 printf("No reclock file used.\n");
2738 printf("Reclock file:%s\n", reclock);
2746 set the reclock file of a node
2748 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2751 const char *reclock;
2755 } else if (argc == 1) {
2761 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2763 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2770 set the natgw state on/off
2772 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2775 uint32_t natgwstate;
2781 if (!strcmp(argv[0], "on")) {
2783 } else if (!strcmp(argv[0], "off")) {
2789 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2791 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2799 set the lmaster role on/off
2801 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2804 uint32_t lmasterrole;
2810 if (!strcmp(argv[0], "on")) {
2812 } else if (!strcmp(argv[0], "off")) {
2818 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2820 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2828 set the recmaster role on/off
2830 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2833 uint32_t recmasterrole;
2839 if (!strcmp(argv[0], "on")) {
2841 } else if (!strcmp(argv[0], "off")) {
2847 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2849 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2857 set debug level on a node or all nodes
2859 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2865 printf("You must specify the debug level. Valid levels are:\n");
2866 for (i=0; debug_levels[i].description != NULL; i++) {
2867 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2873 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2874 level = get_debug_by_desc(argv[0]);
2876 level = strtol(argv[0], NULL, 0);
2879 for (i=0; debug_levels[i].description != NULL; i++) {
2880 if (level == debug_levels[i].level) {
2884 if (debug_levels[i].description == NULL) {
2885 printf("Invalid debug level, must be one of\n");
2886 for (i=0; debug_levels[i].description != NULL; i++) {
2887 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2892 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2894 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2903 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2909 priority = strtol(argv[0], NULL, 0);
2913 DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
2915 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2917 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2925 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2931 priority = strtol(argv[0], NULL, 0);
2935 DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
2937 ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2939 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2946 attach to a database
2948 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2950 const char *db_name;
2951 struct ctdb_db_context *ctdb_db;
2958 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2959 if (ctdb_db == NULL) {
2960 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2970 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2972 struct ctdb_db_priority db_prio;
2979 db_prio.db_id = strtoul(argv[0], NULL, 0);
2980 db_prio.priority = strtoul(argv[1], NULL, 0);
2982 ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
2984 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
2994 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2996 uint32_t db_id, priority;
3003 db_id = strtoul(argv[0], NULL, 0);
3005 ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
3007 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
3011 DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
3017 run an eventscript on a node
3019 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
3025 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3028 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3032 data.dptr = (unsigned char *)discard_const(argv[0]);
3033 data.dsize = strlen((char *)data.dptr) + 1;
3035 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
3037 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
3038 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
3039 if (ret != 0 || res != 0) {
3040 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
3041 talloc_free(tmp_ctx);
3044 talloc_free(tmp_ctx);
3048 #define DB_VERSION 1
3049 #define MAX_DB_NAME 64
3050 struct db_file_header {
3051 unsigned long version;
3053 unsigned long persistent;
3055 const char name[MAX_DB_NAME];
3058 struct backup_data {
3059 struct ctdb_marshall_buffer *records;
3062 bool traverse_error;
3065 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
3067 struct backup_data *bd = talloc_get_type(private, struct backup_data);
3068 struct ctdb_rec_data *rec;
3070 /* add the record */
3071 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
3073 bd->traverse_error = true;
3074 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
3077 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
3078 if (bd->records == NULL) {
3079 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
3080 bd->traverse_error = true;
3083 bd->records->count++;
3084 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
3085 bd->len += rec->length;
3093 * backup a database to a file
3095 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
3098 struct ctdb_dbid_map *dbmap=NULL;
3099 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3100 struct db_file_header dbhdr;
3101 struct ctdb_db_context *ctdb_db;
3102 struct backup_data *bd;
3107 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3111 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
3113 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
3117 for(i=0;i<dbmap->num;i++){
3120 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
3121 if(!strcmp(argv[0], name)){
3122 talloc_free(discard_const(name));
3125 talloc_free(discard_const(name));
3127 if (i == dbmap->num) {
3128 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
3129 talloc_free(tmp_ctx);
3134 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3135 if (ctdb_db == NULL) {
3136 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
3137 talloc_free(tmp_ctx);
3142 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3144 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
3145 talloc_free(tmp_ctx);
3150 bd = talloc_zero(tmp_ctx, struct backup_data);
3152 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
3153 talloc_free(tmp_ctx);
3157 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
3158 if (bd->records == NULL) {
3159 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
3160 talloc_free(tmp_ctx);
3164 bd->len = offsetof(struct ctdb_marshall_buffer, data);
3165 bd->records->db_id = ctdb_db->db_id;
3166 /* traverse the database collecting all records */
3167 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
3168 bd->traverse_error) {
3169 DEBUG(DEBUG_ERR,("Traverse error\n"));
3170 talloc_free(tmp_ctx);
3174 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3177 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
3179 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
3180 talloc_free(tmp_ctx);
3184 dbhdr.version = DB_VERSION;
3185 dbhdr.timestamp = time(NULL);
3186 dbhdr.persistent = dbmap->dbs[i].persistent;
3187 dbhdr.size = bd->len;
3188 if (strlen(argv[0]) >= MAX_DB_NAME) {
3189 DEBUG(DEBUG_ERR,("Too long dbname\n"));
3192 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
3193 ret = write(fh, &dbhdr, sizeof(dbhdr));
3195 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3198 ret = write(fh, bd->records, bd->len);
3200 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3209 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3212 talloc_free(tmp_ctx);
3217 * restore a database from a file
3219 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3222 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3225 struct db_file_header dbhdr;
3226 struct ctdb_db_context *ctdb_db;
3227 struct ctdb_node_map *nodemap=NULL;
3228 struct ctdb_vnn_map *vnnmap=NULL;
3230 struct ctdb_control_wipe_database w;
3232 uint32_t generation;
3237 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3241 fh = open(argv[0], O_RDONLY);
3243 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3244 talloc_free(tmp_ctx);
3248 read(fh, &dbhdr, sizeof(dbhdr));
3249 if (dbhdr.version != DB_VERSION) {
3250 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3251 talloc_free(tmp_ctx);
3255 outdata.dsize = dbhdr.size;
3256 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3257 if (outdata.dptr == NULL) {
3258 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3260 talloc_free(tmp_ctx);
3263 read(fh, outdata.dptr, outdata.dsize);
3266 tm = localtime(&dbhdr.timestamp);
3267 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3268 printf("Restoring database '%s' from backup @ %s\n",
3272 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3273 if (ctdb_db == NULL) {
3274 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3275 talloc_free(tmp_ctx);
3279 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3281 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3282 talloc_free(tmp_ctx);
3287 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3289 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3290 talloc_free(tmp_ctx);
3294 /* freeze all nodes */
3295 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3296 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3297 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3303 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3304 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3305 talloc_free(tmp_ctx);
3310 generation = vnnmap->generation;
3311 data.dptr = (void *)&generation;
3312 data.dsize = sizeof(generation);
3314 /* start a cluster wide transaction */
3315 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3316 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3318 TIMELIMIT(), false, data,
3321 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3326 w.db_id = ctdb_db->db_id;
3327 w.transaction_id = generation;
3329 data.dptr = (void *)&w;
3330 data.dsize = sizeof(w);
3332 /* wipe all the remote databases. */
3333 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3334 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3336 TIMELIMIT(), false, data,
3339 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3340 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3341 talloc_free(tmp_ctx);
3345 /* push the database */
3346 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3347 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3349 TIMELIMIT(), false, outdata,
3352 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3353 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3354 talloc_free(tmp_ctx);
3358 data.dptr = (void *)&generation;
3359 data.dsize = sizeof(generation);
3361 /* commit all the changes */
3362 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3364 TIMELIMIT(), false, data,
3367 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3368 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3369 talloc_free(tmp_ctx);
3374 /* thaw all nodes */
3375 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3376 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3382 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3383 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3384 talloc_free(tmp_ctx);
3389 talloc_free(tmp_ctx);
3394 * wipe a database from a file
3396 static int control_wipedb(struct ctdb_context *ctdb, int argc,
3400 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3402 struct ctdb_db_context *ctdb_db;
3403 struct ctdb_node_map *nodemap = NULL;
3404 struct ctdb_vnn_map *vnnmap = NULL;
3406 struct ctdb_control_wipe_database w;
3408 uint32_t generation;
3409 struct ctdb_dbid_map *dbmap = NULL;
3412 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3416 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3419 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n",
3424 for(i=0;i<dbmap->num;i++){
3427 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
3428 dbmap->dbs[i].dbid, tmp_ctx, &name);
3429 if(!strcmp(argv[0], name)){
3430 talloc_free(discard_const(name));
3433 talloc_free(discard_const(name));
3435 if (i == dbmap->num) {
3436 DEBUG(DEBUG_ERR, ("No database with name '%s' found\n",
3438 talloc_free(tmp_ctx);
3442 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3443 if (ctdb_db == NULL) {
3444 DEBUG(DEBUG_ERR, ("Unable to attach to database '%s'\n",
3446 talloc_free(tmp_ctx);
3450 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb,
3453 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n",
3455 talloc_free(tmp_ctx);
3459 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3462 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n",
3464 talloc_free(tmp_ctx);
3468 /* freeze all nodes */
3469 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3470 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3471 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3478 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3479 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn,
3480 CTDB_RECOVERY_ACTIVE);
3481 talloc_free(tmp_ctx);
3486 generation = vnnmap->generation;
3487 data.dptr = (void *)&generation;
3488 data.dsize = sizeof(generation);
3490 /* start a cluster wide transaction */
3491 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3492 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3494 TIMELIMIT(), false, data,
3498 DEBUG(DEBUG_ERR, ("Unable to start cluster wide "
3499 "transactions.\n"));
3503 w.db_id = ctdb_db->db_id;
3504 w.transaction_id = generation;
3506 data.dptr = (void *)&w;
3507 data.dsize = sizeof(w);
3509 /* wipe all the remote databases. */
3510 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3511 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3513 TIMELIMIT(), false, data,
3516 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3517 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3518 talloc_free(tmp_ctx);
3522 data.dptr = (void *)&generation;
3523 data.dsize = sizeof(generation);
3525 /* commit all the changes */
3526 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3528 TIMELIMIT(), false, data,
3531 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3532 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3533 talloc_free(tmp_ctx);
3537 /* thaw all nodes */
3538 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3539 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3545 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3546 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3547 talloc_free(tmp_ctx);
3551 talloc_free(tmp_ctx);
3556 * set flags of a node in the nodemap
3558 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3565 struct ctdb_node_flag_change c;
3572 if (sscanf(argv[0], "%d", &node) != 1) {
3573 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3577 if (sscanf(argv[1], "0x%x", &flags) != 1) {
3578 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3585 c.new_flags = flags;
3587 data.dsize = sizeof(c);
3588 data.dptr = (unsigned char *)&c;
3590 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
3591 data, NULL, NULL, &status, NULL, NULL);
3592 if (ret != 0 || status != 0) {
3593 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3602 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3608 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3609 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3610 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3611 if (ret != 0 || res != 0) {
3612 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3613 talloc_free(tmp_ctx);
3616 write(1, data.dptr, data.dsize);
3617 talloc_free(tmp_ctx);
3622 handler for memory dumps
3624 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
3625 TDB_DATA data, void *private_data)
3627 write(1, data.dptr, data.dsize);
3632 dump memory usage on the recovery daemon
3634 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3638 struct rd_memdump_reply rd;
3640 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3642 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3645 rd.srvid = getpid();
3647 /* register a message port for receiveing the reply so that we
3648 can receive the reply
3650 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3653 data.dptr = (uint8_t *)&rd;
3654 data.dsize = sizeof(rd);
3656 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3658 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3662 /* this loop will terminate when we have received the reply */
3664 event_loop_once(ctdb->ev);
3671 list all nodes in the cluster
3672 if the daemon is running, we read the data from the daemon.
3673 if the daemon is not running we parse the nodes file directly
3675 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3678 struct ctdb_node_map *nodemap=NULL;
3681 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3683 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3687 for(i=0;i<nodemap->num;i++){
3688 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3691 if (options.machinereadable){
3692 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3694 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3698 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3699 struct pnn_node *pnn_nodes;
3700 struct pnn_node *pnn_node;
3702 pnn_nodes = read_nodes_file(mem_ctx);
3703 if (pnn_nodes == NULL) {
3704 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3705 talloc_free(mem_ctx);
3709 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3710 ctdb_sock_addr addr;
3712 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3713 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3714 talloc_free(mem_ctx);
3718 if (options.machinereadable){
3719 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3721 printf("%s\n", pnn_node->addr);
3724 talloc_free(mem_ctx);
3731 reload the nodes file on the local node
3733 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3737 struct ctdb_node_map *nodemap=NULL;
3739 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3741 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3745 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3747 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3751 /* reload the nodes file on all remote nodes */
3752 for (i=0;i<nodemap->num;i++) {
3753 if (nodemap->nodes[i].pnn == mypnn) {
3756 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3757 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3758 nodemap->nodes[i].pnn);
3760 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3764 /* reload the nodes file on the local node */
3765 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3766 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3768 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3771 /* initiate a recovery */
3772 control_recover(ctdb, argc, argv);
3778 static const struct {
3780 int (*fn)(struct ctdb_context *, int, const char **);
3782 bool without_daemon; /* can be run without daemon running ? */
3785 } ctdb_commands[] = {
3787 { "version", control_version, true, false, "show version of ctdb" },
3789 { "status", control_status, true, false, "show node status" },
3790 { "uptime", control_uptime, true, false, "show node uptime" },
3791 { "ping", control_ping, true, false, "ping all nodes" },
3792 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
3793 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
3794 { "listvars", control_listvars, true, false, "list tunable variables"},
3795 { "statistics", control_statistics, false, false, "show statistics" },
3796 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
3797 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
3798 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
3799 { "getdbmap", control_getdbmap, true, false, "show the database map" },
3800 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
3801 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
3802 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
3803 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
3804 { "lvs", control_lvs, true, false, "show lvs configuration" },
3805 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
3806 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
3807 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
3808 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
3809 { "getdebug", control_getdebug, true, false, "get debug level" },
3810 { "getlog", control_getlog, true, false, "get the log data from the in memory ringbuffer", "<level>" },
3811 { "clearlog", control_clearlog, true, false, "clear the log data from the in memory ringbuffer" },
3812 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
3813 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
3814 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
3815 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
3816 { "disable", control_disable, true, false, "disable a nodes public IP" },
3817 { "enable", control_enable, true, false, "enable a nodes public IP" },
3818 { "stop", control_stop, true, false, "stop a node" },
3819 { "continue", control_continue, true, false, "re-start a stopped node" },
3820 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
3821 { "unban", control_unban, true, false, "unban a node" },
3822 { "showban", control_showban, true, false, "show ban information"},
3823 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
3824 { "recover", control_recover, true, false, "force recovery" },
3825 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
3826 { "freeze", control_freeze, true, false, "freeze databases", "[priority:1-3]" },
3827 { "thaw", control_thaw, true, false, "thaw databases", "[priority:1-3]" },
3828 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
3829 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
3830 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
3831 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
3832 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
3834 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
3835 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
3836 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
3837 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
3838 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
3839 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
3840 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
3841 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
3842 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
3843 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
3844 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
3845 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
3846 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
3847 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
3848 { "wipedb", control_wipedb, false, false, "wipe the contents of a database.", "<dbname>"},
3849 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
3850 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
3851 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts (or all scripts)", "[all]"},
3852 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
3853 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
3854 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
3855 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
3856 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
3857 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
3858 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
3859 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
3860 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
3861 { "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
3862 { "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
3868 static void usage(void)
3872 "Usage: ctdb [options] <control>\n" \
3874 " -n <node> choose node number, or 'all' (defaults to local node)\n"
3875 " -Y generate machinereadable output\n"
3876 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
3877 printf("Controls:\n");
3878 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3879 printf(" %-15s %-27s %s\n",
3880 ctdb_commands[i].name,
3881 ctdb_commands[i].args?ctdb_commands[i].args:"",
3882 ctdb_commands[i].msg);
3888 static void ctdb_alarm(int sig)
3890 printf("Maximum runtime exceeded - exiting\n");
3897 int main(int argc, const char *argv[])
3899 struct ctdb_context *ctdb;
3900 char *nodestring = NULL;
3901 struct poptOption popt_options[] = {
3904 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3905 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3906 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3907 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3911 const char **extra_argv;
3915 struct event_context *ev;
3916 const char *control;
3920 /* set some defaults */
3921 options.maxruntime = 0;
3922 options.timelimit = 3;
3923 options.pnn = CTDB_CURRENT_NODE;
3925 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3927 while ((opt = poptGetNextOpt(pc)) != -1) {
3930 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
3931 poptBadOption(pc, 0), poptStrerror(opt)));
3936 /* setup the remaining options for the main program to use */
3937 extra_argv = poptGetArgs(pc);
3940 while (extra_argv[extra_argc]) extra_argc++;
3943 if (extra_argc < 1) {
3947 if (options.maxruntime == 0) {
3948 const char *ctdb_timeout;
3949 ctdb_timeout = getenv("CTDB_TIMEOUT");
3950 if (ctdb_timeout != NULL) {
3951 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3953 /* default timeout is 120 seconds */
3954 options.maxruntime = 120;
3958 signal(SIGALRM, ctdb_alarm);
3959 alarm(options.maxruntime);
3961 /* setup the node number to contact */
3962 if (nodestring != NULL) {
3963 if (strcmp(nodestring, "all") == 0) {
3964 options.pnn = CTDB_BROADCAST_ALL;
3966 options.pnn = strtoul(nodestring, NULL, 0);
3970 control = extra_argv[0];
3972 ev = event_context_init(NULL);
3974 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3975 if (strcmp(control, ctdb_commands[i].name) == 0) {
3978 if (ctdb_commands[i].without_daemon == true) {
3982 /* initialise ctdb */
3983 ctdb = ctdb_cmdline_client(ev);
3985 if (ctdb_commands[i].without_daemon == false) {
3987 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3991 /* verify the node exists */
3994 if (options.pnn == CTDB_CURRENT_NODE) {
3996 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
4004 if (ctdb_commands[i].auto_all &&
4005 options.pnn == CTDB_BROADCAST_ALL) {
4010 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
4011 CTDB_NO_MEMORY(ctdb, nodes);
4013 for (j=0;j<num_nodes;j++) {
4014 options.pnn = nodes[j];
4015 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4019 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4025 if (i == ARRAY_SIZE(ctdb_commands)) {
4026 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));