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:Inactive:\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:%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),
517 !!(nodemap->nodes[i].flags&NODE_FLAGS_INACTIVE));
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" },
534 { NODE_FLAGS_INACTIVE, "INACTIVE" },
536 char *flags_str = NULL;
539 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
542 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
543 if (nodemap->nodes[i].flags & flag_names[j].flag) {
544 if (flags_str == NULL) {
545 flags_str = talloc_strdup(ctdb, flag_names[j].name);
547 flags_str = talloc_asprintf_append(flags_str, "|%s",
550 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
553 if (flags_str == NULL) {
554 flags_str = talloc_strdup(ctdb, "OK");
555 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
557 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
558 ctdb_addr_to_str(&nodemap->nodes[i].addr),
560 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
561 talloc_free(flags_str);
564 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
566 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
569 if (vnnmap->generation == INVALID_GENERATION) {
570 printf("Generation:INVALID\n");
572 printf("Generation:%d\n",vnnmap->generation);
574 printf("Size:%d\n",vnnmap->size);
575 for(i=0;i<vnnmap->size;i++){
576 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
579 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
581 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
584 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
586 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
588 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
591 printf("Recovery master:%d\n",recmaster);
598 struct natgw_node *next;
603 display the list of nodes belonging to this natgw configuration
605 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
608 const char *natgw_list;
611 struct natgw_node *natgw_nodes = NULL;
612 struct natgw_node *natgw_node;
613 struct ctdb_node_map *nodemap=NULL;
616 /* read the natgw nodes file into a linked list */
617 natgw_list = getenv("NATGW_NODES");
618 if (natgw_list == NULL) {
619 natgw_list = "/etc/ctdb/natgw_nodes";
621 lines = file_lines_load(natgw_list, &nlines, ctdb);
623 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
626 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
629 for (i=0;i<nlines;i++) {
633 /* strip leading spaces */
634 while((*node == ' ') || (*node == '\t')) {
640 if (strcmp(node, "") == 0) {
643 natgw_node = talloc(ctdb, struct natgw_node);
644 natgw_node->addr = talloc_strdup(natgw_node, node);
645 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
646 natgw_node->next = natgw_nodes;
647 natgw_nodes = natgw_node;
650 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
652 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
657 while(i<nodemap->num) {
658 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
659 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
664 /* this node was not in the natgw so we just remove it from
667 if ((natgw_node == NULL)
668 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
671 for (j=i+1; j<nodemap->num; j++) {
672 nodemap->nodes[j-1] = nodemap->nodes[j];
681 /* pick a node to be natgwmaster
682 * we dont allow STOPPED, DELETED, BANNED or UNHEALTHY nodes to become the natgwmaster
684 for(i=0;i<nodemap->num;i++){
685 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_UNHEALTHY))) {
686 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
690 /* we couldnt find any healthy node, try unhealthy ones */
691 if (i == nodemap->num) {
692 for(i=0;i<nodemap->num;i++){
693 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
694 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
699 /* unless all nodes are STOPPED, when we pick one anyway */
700 if (i == nodemap->num) {
701 for(i=0;i<nodemap->num;i++){
702 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
703 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
707 /* or if we still can not find any */
708 if (i == nodemap->num) {
709 printf("-1 0.0.0.0\n");
713 /* print the pruned list of nodes belonging to this natgw list */
714 for(i=0;i<nodemap->num;i++){
715 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
718 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
719 ctdb_addr_to_str(&nodemap->nodes[i].addr),
720 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
721 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
722 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
723 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
724 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
731 display the status of the scripts for monitoring (or other events)
733 static int control_one_scriptstatus(struct ctdb_context *ctdb,
734 enum ctdb_eventscript_call type)
736 struct ctdb_scripts_wire *script_status;
739 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, type, &script_status);
741 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
745 if (script_status == NULL) {
746 if (!options.machinereadable) {
747 printf("%s cycle never run\n",
748 ctdb_eventscript_call_names[type]);
753 if (!options.machinereadable) {
754 printf("%d scripts were executed last %s cycle\n",
755 script_status->num_scripts,
756 ctdb_eventscript_call_names[type]);
758 for (i=0; i<script_status->num_scripts; i++) {
759 const char *status = NULL;
761 switch (script_status->scripts[i].status) {
772 if (script_status->scripts[i].status > 0)
776 if (options.machinereadable) {
777 printf("%s:%s:%i:%s:%lu.%06lu:%lu.%06lu:%s:\n",
778 ctdb_eventscript_call_names[type],
779 script_status->scripts[i].name,
780 script_status->scripts[i].status,
782 (long)script_status->scripts[i].start.tv_sec,
783 (long)script_status->scripts[i].start.tv_usec,
784 (long)script_status->scripts[i].finished.tv_sec,
785 (long)script_status->scripts[i].finished.tv_usec,
786 script_status->scripts[i].output);
790 printf("%-20s Status:%s ",
791 script_status->scripts[i].name, status);
793 /* Some other error, eg from stat. */
794 printf("%-20s Status:CANNOT RUN (%s)",
795 script_status->scripts[i].name,
796 strerror(-script_status->scripts[i].status));
798 if (script_status->scripts[i].status >= 0) {
799 printf("Duration:%.3lf ",
800 timeval_delta(&script_status->scripts[i].finished,
801 &script_status->scripts[i].start));
803 if (script_status->scripts[i].status != -ENOEXEC) {
805 ctime(&script_status->scripts[i].start.tv_sec));
806 if (script_status->scripts[i].status != 0) {
807 printf(" OUTPUT:%s\n",
808 script_status->scripts[i].output);
818 static int control_scriptstatus(struct ctdb_context *ctdb,
819 int argc, const char **argv)
822 enum ctdb_eventscript_call type, min, max;
826 DEBUG(DEBUG_ERR, ("Unknown arguments to scriptstatus\n"));
831 arg = ctdb_eventscript_call_names[CTDB_EVENT_MONITOR];
835 for (type = 0; type < CTDB_EVENT_MAX; type++) {
836 if (strcmp(arg, ctdb_eventscript_call_names[type]) == 0) {
842 if (type == CTDB_EVENT_MAX) {
843 if (strcmp(arg, "all") == 0) {
845 max = CTDB_EVENT_MAX;
847 DEBUG(DEBUG_ERR, ("Unknown event type %s\n", argv[0]));
852 if (options.machinereadable) {
853 printf(":Type:Name:Code:Status:Start:End:Error Output...:\n");
856 for (type = min; type < max; type++) {
857 ret = control_one_scriptstatus(ctdb, type);
867 enable an eventscript
869 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
877 ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
879 DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
887 disable an eventscript
889 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
897 ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
899 DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
907 display the pnn of the recovery master
909 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
914 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
916 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
919 printf("%d\n",recmaster);
925 get a list of all tickles for this pnn
927 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
929 struct ctdb_control_tcp_tickle_list *list;
937 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
938 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
942 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
944 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
948 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
949 printf("Num tickles:%u\n", list->tickles.num);
950 for (i=0;i<list->tickles.num;i++) {
951 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
952 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));
962 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
964 struct ctdb_all_public_ips *ips;
965 struct ctdb_public_ip ip;
968 uint32_t disable_time;
970 struct ctdb_node_map *nodemap=NULL;
971 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
974 data.dptr = (uint8_t*)&disable_time;
975 data.dsize = sizeof(disable_time);
976 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
978 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
984 /* read the public ip list from the node */
985 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
987 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
988 talloc_free(tmp_ctx);
992 for (i=0;i<ips->num;i++) {
993 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
998 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
999 pnn, ctdb_addr_to_str(addr)));
1000 talloc_free(tmp_ctx);
1007 data.dptr = (uint8_t *)&ip;
1008 data.dsize = sizeof(ip);
1010 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
1012 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1013 talloc_free(tmp_ctx);
1017 nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
1018 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
1025 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
1026 talloc_free(tmp_ctx);
1030 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
1032 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
1033 talloc_free(tmp_ctx);
1037 talloc_free(tmp_ctx);
1042 move/failover an ip address to a specific node
1044 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
1047 ctdb_sock_addr addr;
1054 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1055 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1060 if (sscanf(argv[1], "%u", &pnn) != 1) {
1061 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
1065 if (move_ip(ctdb, &addr, pnn) != 0) {
1066 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1073 void getips_store_callback(void *param, void *data)
1075 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
1076 struct ctdb_all_public_ips *ips = param;
1080 ips->ips[i].pnn = node_ip->pnn;
1081 ips->ips[i].addr = node_ip->addr;
1084 void getips_count_callback(void *param, void *data)
1086 uint32_t *count = param;
1092 static uint32_t *ip_key(ctdb_sock_addr *ip)
1094 static uint32_t key[IP_KEYLEN];
1096 bzero(key, sizeof(key));
1098 switch (ip->sa.sa_family) {
1100 key[0] = ip->ip.sin_addr.s_addr;
1103 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
1104 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
1105 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
1106 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
1109 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1116 static void *add_ip_callback(void *parm, void *data)
1122 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1124 struct ctdb_all_public_ips *tmp_ips;
1125 struct ctdb_node_map *nodemap=NULL;
1126 trbt_tree_t *ip_tree;
1130 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1132 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1136 ip_tree = trbt_create(tmp_ctx, 0);
1138 for(i=0;i<nodemap->num;i++){
1139 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1142 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1146 /* read the public ip list from this node */
1147 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1149 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1153 for (j=0; j<tmp_ips->num;j++) {
1154 struct ctdb_public_ip *node_ip;
1156 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1157 node_ip->pnn = tmp_ips->ips[j].pnn;
1158 node_ip->addr = tmp_ips->ips[j].addr;
1160 trbt_insertarray32_callback(ip_tree,
1161 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1165 talloc_free(tmp_ips);
1170 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1172 len = offsetof(struct ctdb_all_public_ips, ips) +
1173 count*sizeof(struct ctdb_public_ip);
1174 tmp_ips = talloc_zero_size(tmp_ctx, len);
1175 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1184 * scans all other nodes and returns a pnn for another node that can host this
1188 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1190 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1191 struct ctdb_all_public_ips *ips;
1192 struct ctdb_node_map *nodemap=NULL;
1195 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1197 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1198 talloc_free(tmp_ctx);
1202 for(i=0;i<nodemap->num;i++){
1203 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1206 if (nodemap->nodes[i].pnn == options.pnn) {
1210 /* read the public ip list from this node */
1211 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1213 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1217 for (j=0;j<ips->num;j++) {
1218 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1219 talloc_free(tmp_ctx);
1220 return nodemap->nodes[i].pnn;
1226 talloc_free(tmp_ctx);
1231 add a public ip address to a node
1233 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1239 ctdb_sock_addr addr;
1240 struct ctdb_control_ip_iface *pub;
1241 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1242 struct ctdb_all_public_ips *ips;
1246 talloc_free(tmp_ctx);
1250 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1251 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1252 talloc_free(tmp_ctx);
1256 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1258 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1259 talloc_free(tmp_ctx);
1264 /* check if some other node is already serving this ip, if not,
1267 for (i=0;i<ips->num;i++) {
1268 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1273 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1274 pub = talloc_size(tmp_ctx, len);
1275 CTDB_NO_MEMORY(ctdb, pub);
1279 pub->len = strlen(argv[1])+1;
1280 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1282 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1284 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1285 talloc_free(tmp_ctx);
1289 if (i == ips->num) {
1290 /* no one has this ip so we claim it */
1293 pnn = ips->ips[i].pnn;
1296 if (move_ip(ctdb, &addr, pnn) != 0) {
1297 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1301 talloc_free(tmp_ctx);
1305 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1307 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1309 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1310 struct ctdb_node_map *nodemap=NULL;
1311 struct ctdb_all_public_ips *ips;
1314 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1316 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1320 /* remove it from the nodes that are not hosting the ip currently */
1321 for(i=0;i<nodemap->num;i++){
1322 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1325 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1326 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1330 for (j=0;j<ips->num;j++) {
1331 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1339 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1343 options.pnn = nodemap->nodes[i].pnn;
1344 control_delip(ctdb, argc, argv);
1348 /* remove it from every node (also the one hosting it) */
1349 for(i=0;i<nodemap->num;i++){
1350 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1353 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1354 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1358 for (j=0;j<ips->num;j++) {
1359 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1367 options.pnn = nodemap->nodes[i].pnn;
1368 control_delip(ctdb, argc, argv);
1371 talloc_free(tmp_ctx);
1376 delete a public ip address from a node
1378 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1381 ctdb_sock_addr addr;
1382 struct ctdb_control_ip_iface pub;
1383 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1384 struct ctdb_all_public_ips *ips;
1387 talloc_free(tmp_ctx);
1391 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1392 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1396 if (options.pnn == CTDB_BROADCAST_ALL) {
1397 return control_delip_all(ctdb, argc, argv, &addr);
1404 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1406 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1407 talloc_free(tmp_ctx);
1411 for (i=0;i<ips->num;i++) {
1412 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1418 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1419 ctdb_addr_to_str(&addr)));
1420 talloc_free(tmp_ctx);
1424 if (ips->ips[i].pnn == options.pnn) {
1425 ret = find_other_host_for_public_ip(ctdb, &addr);
1427 if (move_ip(ctdb, &addr, ret) != 0) {
1428 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1434 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1436 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1437 talloc_free(tmp_ctx);
1441 talloc_free(tmp_ctx);
1446 kill a tcp connection
1448 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1451 struct ctdb_control_killtcp killtcp;
1457 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1458 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1462 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1463 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1467 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1469 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1480 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1483 ctdb_sock_addr addr;
1489 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1490 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1494 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1496 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1504 register a server id
1506 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1509 struct ctdb_server_id server_id;
1515 server_id.pnn = strtoul(argv[0], NULL, 0);
1516 server_id.type = strtoul(argv[1], NULL, 0);
1517 server_id.server_id = strtoul(argv[2], NULL, 0);
1519 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1521 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1528 unregister a server id
1530 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1533 struct ctdb_server_id server_id;
1539 server_id.pnn = strtoul(argv[0], NULL, 0);
1540 server_id.type = strtoul(argv[1], NULL, 0);
1541 server_id.server_id = strtoul(argv[2], NULL, 0);
1543 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1545 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1552 check if a server id exists
1554 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1558 struct ctdb_server_id server_id;
1564 server_id.pnn = strtoul(argv[0], NULL, 0);
1565 server_id.type = strtoul(argv[1], NULL, 0);
1566 server_id.server_id = strtoul(argv[2], NULL, 0);
1568 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1570 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1575 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1577 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1583 get a list of all server ids that are registered on a node
1585 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1588 struct ctdb_server_id_list *server_ids;
1590 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1592 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1596 for (i=0; i<server_ids->num; i++) {
1597 printf("Server id %d:%d:%d\n",
1598 server_ids->server_ids[i].pnn,
1599 server_ids->server_ids[i].type,
1600 server_ids->server_ids[i].server_id);
1607 send a tcp tickle ack
1609 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1612 ctdb_sock_addr src, dst;
1618 if (!parse_ip_port(argv[0], &src)) {
1619 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1623 if (!parse_ip_port(argv[1], &dst)) {
1624 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1628 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1632 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1639 display public ip status
1641 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1644 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1645 struct ctdb_all_public_ips *ips;
1647 if (options.pnn == CTDB_BROADCAST_ALL) {
1648 /* read the list of public ips from all nodes */
1649 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1651 /* read the public ip list from this node */
1652 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1655 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1656 talloc_free(tmp_ctx);
1660 if (options.machinereadable){
1661 printf(":Public IP:Node:\n");
1663 if (options.pnn == CTDB_BROADCAST_ALL) {
1664 printf("Public IPs on ALL nodes\n");
1666 printf("Public IPs on node %u\n", options.pnn);
1670 for (i=1;i<=ips->num;i++) {
1671 if (options.machinereadable){
1672 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1674 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1678 talloc_free(tmp_ctx);
1683 display pid of a ctdb daemon
1685 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1690 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1692 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1695 printf("Pid:%d\n", pid);
1701 handler for receiving the response to ipreallocate
1703 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1704 TDB_DATA data, void *private_data)
1709 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1711 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1713 event_add_timed(ctdb->ev, ctdb,
1714 timeval_current_ofs(1, 0),
1715 ctdb_every_second, ctdb);
1719 ask the recovery daemon on the recovery master to perform a ip reallocation
1721 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1725 struct takeover_run_reply rd;
1727 struct ctdb_node_map *nodemap=NULL;
1729 struct timeval tv = timeval_current();
1731 /* we need some events to trigger so we can timeout and restart
1734 event_add_timed(ctdb->ev, ctdb,
1735 timeval_current_ofs(1, 0),
1736 ctdb_every_second, ctdb);
1738 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1740 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1743 rd.srvid = getpid();
1745 /* register a message port for receiveing the reply so that we
1746 can receive the reply
1748 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1750 data.dptr = (uint8_t *)&rd;
1751 data.dsize = sizeof(rd);
1755 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1759 /* check that there are valid nodes available */
1760 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1761 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1764 for (i=0; i<nodemap->num;i++) {
1765 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1769 if (i==nodemap->num) {
1770 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1775 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1777 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1781 /* verify the node exists */
1782 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1783 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1788 /* check tha there are nodes available that can act as a recmaster */
1789 for (i=0; i<nodemap->num; i++) {
1790 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1795 if (i == nodemap->num) {
1796 DEBUG(DEBUG_ERR,("No possible nodes to host addresses.\n"));
1800 /* verify the recovery master is not STOPPED, nor BANNED */
1801 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1802 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1809 /* verify the recovery master is not STOPPED, nor BANNED */
1810 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1811 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1817 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1819 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1823 tv = timeval_current();
1824 /* this loop will terminate when we have received the reply */
1825 while (timeval_elapsed(&tv) < 3.0) {
1826 event_loop_once(ctdb->ev);
1829 DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1839 disable a remote node
1841 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1844 struct ctdb_node_map *nodemap=NULL;
1847 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1849 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1855 /* read the nodemap and verify the change took effect */
1856 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1857 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1861 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1862 ret = control_ipreallocate(ctdb, argc, argv);
1864 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1872 enable a disabled remote node
1874 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1878 struct ctdb_node_map *nodemap=NULL;
1881 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1883 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1889 /* read the nodemap and verify the change took effect */
1890 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1891 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1895 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1896 ret = control_ipreallocate(ctdb, argc, argv);
1898 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1908 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1911 struct ctdb_node_map *nodemap=NULL;
1914 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1916 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
1921 /* read the nodemap and verify the change took effect */
1922 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1923 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1927 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1928 ret = control_ipreallocate(ctdb, argc, argv);
1930 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1938 restart a stopped remote node
1940 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1944 struct ctdb_node_map *nodemap=NULL;
1947 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1949 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1955 /* read the nodemap and verify the change took effect */
1956 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1957 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1961 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1962 ret = control_ipreallocate(ctdb, argc, argv);
1964 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1971 static uint32_t get_generation(struct ctdb_context *ctdb)
1973 struct ctdb_vnn_map *vnnmap=NULL;
1976 /* wait until the recmaster is not in recovery mode */
1978 uint32_t recmode, recmaster;
1980 if (vnnmap != NULL) {
1981 talloc_free(vnnmap);
1985 /* get the recmaster */
1986 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1988 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1992 /* get recovery mode */
1993 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1995 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1999 /* get the current generation number */
2000 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
2002 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
2006 if ((recmode == CTDB_RECOVERY_NORMAL)
2007 && (vnnmap->generation != 1)){
2008 return vnnmap->generation;
2015 ban a node from the cluster
2017 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
2020 struct ctdb_node_map *nodemap=NULL;
2021 struct ctdb_ban_time bantime;
2027 /* verify the node exists */
2028 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2030 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2034 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
2035 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
2039 bantime.pnn = options.pnn;
2040 bantime.time = strtoul(argv[0], NULL, 0);
2042 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2044 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
2048 ret = control_ipreallocate(ctdb, argc, argv);
2050 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2059 unban a node from the cluster
2061 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
2064 struct ctdb_node_map *nodemap=NULL;
2065 struct ctdb_ban_time bantime;
2067 /* verify the node exists */
2068 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2070 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2074 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
2075 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
2079 bantime.pnn = options.pnn;
2082 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2084 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
2088 ret = control_ipreallocate(ctdb, argc, argv);
2090 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2099 show ban information for a node
2101 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
2104 struct ctdb_node_map *nodemap=NULL;
2105 struct ctdb_ban_time *bantime;
2107 /* verify the node exists */
2108 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2110 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2114 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2116 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2120 if (bantime->time == 0) {
2121 printf("Node %u is not banned\n", bantime->pnn);
2123 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2132 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2136 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2138 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2148 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2151 uint32_t generation, next_generation;
2153 /* record the current generation number */
2154 generation = get_generation(ctdb);
2156 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2158 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2162 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2164 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2168 /* wait until we are in a new generation */
2170 next_generation = get_generation(ctdb);
2171 if (next_generation != generation) {
2182 display monitoring mode of a remote node
2184 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2189 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2191 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2194 if (!options.machinereadable){
2195 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2198 printf(":%d:\n",monmode);
2205 display capabilities of a remote node
2207 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2209 uint32_t capabilities;
2212 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2214 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2218 if (!options.machinereadable){
2219 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2220 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2221 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2222 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2224 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2225 printf(":%d:%d:%d:%d:\n",
2226 !!(capabilities&CTDB_CAP_RECMASTER),
2227 !!(capabilities&CTDB_CAP_LMASTER),
2228 !!(capabilities&CTDB_CAP_LVS),
2229 !!(capabilities&CTDB_CAP_NATGW));
2235 display lvs configuration
2237 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2239 uint32_t *capabilities;
2240 struct ctdb_node_map *nodemap=NULL;
2242 int healthy_count = 0;
2244 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2246 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2250 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2251 CTDB_NO_MEMORY(ctdb, capabilities);
2253 /* collect capabilities for all connected nodes */
2254 for (i=0; i<nodemap->num; i++) {
2255 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2258 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2262 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2264 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2268 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2272 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2277 /* Print all LVS nodes */
2278 for (i=0; i<nodemap->num; i++) {
2279 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2282 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2285 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2289 if (healthy_count != 0) {
2290 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2295 printf("%d:%s\n", i,
2296 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2303 display who is the lvs master
2305 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2307 uint32_t *capabilities;
2308 struct ctdb_node_map *nodemap=NULL;
2310 int healthy_count = 0;
2312 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2314 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2318 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2319 CTDB_NO_MEMORY(ctdb, capabilities);
2321 /* collect capabilities for all connected nodes */
2322 for (i=0; i<nodemap->num; i++) {
2323 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2326 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2330 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2332 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2336 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2340 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2345 /* find and show the lvsmaster */
2346 for (i=0; i<nodemap->num; i++) {
2347 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2350 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2353 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2357 if (healthy_count != 0) {
2358 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2363 if (options.machinereadable){
2366 printf("Node %d is LVS master\n", i);
2371 printf("There is no LVS master\n");
2376 disable monitoring on a node
2378 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2383 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2385 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2388 printf("Monitoring mode:%s\n","DISABLED");
2394 enable monitoring on a node
2396 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2401 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2403 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2406 printf("Monitoring mode:%s\n","ACTIVE");
2412 display remote list of keys/data for a db
2414 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2416 const char *db_name;
2417 struct ctdb_db_context *ctdb_db;
2427 if (db_exists(ctdb, db_name)) {
2428 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2432 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2434 if (ctdb_db == NULL) {
2435 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2439 /* traverse and dump the cluster tdb */
2440 ret = ctdb_dump_db(ctdb_db, stdout);
2442 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2443 DEBUG(DEBUG_ERR, ("Maybe try 'ctdb getdbstatus %s'"
2444 " and 'ctdb getvar AllowUnhealthyDBRead'\n",
2448 talloc_free(ctdb_db);
2450 printf("Dumped %d records\n", ret);
2455 static void log_handler(struct ctdb_context *ctdb, uint64_t srvid,
2456 TDB_DATA data, void *private_data)
2458 DEBUG(DEBUG_ERR,("Log data received\n"));
2459 if (data.dsize > 0) {
2460 printf("%s", data.dptr);
2467 display a list of log messages from the in memory ringbuffer
2469 static int control_getlog(struct ctdb_context *ctdb, int argc, const char **argv)
2473 struct ctdb_get_log_addr log_addr;
2475 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2480 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2481 talloc_free(tmp_ctx);
2485 log_addr.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2486 log_addr.srvid = getpid();
2487 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2488 log_addr.level = get_debug_by_desc(argv[0]);
2490 log_addr.level = strtol(argv[0], NULL, 0);
2494 data.dptr = (unsigned char *)&log_addr;
2495 data.dsize = sizeof(log_addr);
2497 DEBUG(DEBUG_ERR, ("Pulling logs from node %u\n", options.pnn));
2499 ctdb_set_message_handler(ctdb, log_addr.srvid, log_handler, NULL);
2502 DEBUG(DEBUG_ERR,("Listen for response on %d\n", (int)log_addr.srvid));
2504 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_GET_LOG,
2505 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2506 if (ret != 0 || res != 0) {
2507 DEBUG(DEBUG_ERR,("Failed to get logs - %s\n", errmsg));
2508 talloc_free(tmp_ctx);
2513 tv = timeval_current();
2514 /* this loop will terminate when we have received the reply */
2515 while (timeval_elapsed(&tv) < 3.0) {
2516 event_loop_once(ctdb->ev);
2519 DEBUG(DEBUG_INFO,("Timed out waiting for log data.\n"));
2521 talloc_free(tmp_ctx);
2526 clear the in memory log area
2528 static int control_clearlog(struct ctdb_context *ctdb, int argc, const char **argv)
2533 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2535 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_CLEAR_LOG,
2536 0, tdb_null, tmp_ctx, NULL, &res, NULL, &errmsg);
2537 if (ret != 0 || res != 0) {
2538 DEBUG(DEBUG_ERR,("Failed to clear logs\n"));
2539 talloc_free(tmp_ctx);
2543 talloc_free(tmp_ctx);
2550 display a list of the databases on a remote ctdb
2552 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2555 struct ctdb_dbid_map *dbmap=NULL;
2557 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2559 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2563 if(options.machinereadable){
2564 printf(":ID:Name:Path:Persistent:Unhealthy:\n");
2565 for(i=0;i<dbmap->num;i++){
2571 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn,
2572 dbmap->dbs[i].dbid, ctdb, &path);
2573 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
2574 dbmap->dbs[i].dbid, ctdb, &name);
2575 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
2576 dbmap->dbs[i].dbid, ctdb, &health);
2577 persistent = dbmap->dbs[i].persistent;
2578 printf(":0x%08X:%s:%s:%d:%d:\n",
2579 dbmap->dbs[i].dbid, name, path,
2580 !!(persistent), !!(health));
2585 printf("Number of databases:%d\n", dbmap->num);
2586 for(i=0;i<dbmap->num;i++){
2592 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2593 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2594 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
2595 persistent = dbmap->dbs[i].persistent;
2596 printf("dbid:0x%08x name:%s path:%s%s%s\n",
2597 dbmap->dbs[i].dbid, name, path,
2598 persistent?" PERSISTENT":"",
2599 health?" UNHEALTHY":"");
2606 display the status of a database on a remote ctdb
2608 static int control_getdbstatus(struct ctdb_context *ctdb, int argc, const char **argv)
2611 struct ctdb_dbid_map *dbmap=NULL;
2612 const char *db_name;
2620 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2622 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2626 for(i=0;i<dbmap->num;i++){
2632 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2633 if (strcmp(name, db_name) != 0) {
2637 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2638 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
2639 persistent = dbmap->dbs[i].persistent;
2640 printf("dbid: 0x%08x\nname: %s\npath: %s\nPERSISTENT: %s\nHEALTH: %s\n",
2641 dbmap->dbs[i].dbid, name, path,
2642 persistent?"yes":"no",
2643 health?health:"OK");
2647 DEBUG(DEBUG_ERR, ("db %s doesn't exist on node %u\n", db_name, options.pnn));
2652 check if the local node is recmaster or not
2653 it will return 1 if this node is the recmaster and 0 if it is not
2654 or if the local ctdb daemon could not be contacted
2656 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2658 uint32_t mypnn, recmaster;
2661 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2663 printf("Failed to get pnn of node\n");
2667 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2669 printf("Failed to get the recmaster\n");
2673 if (recmaster != mypnn) {
2674 printf("this node is not the recmaster\n");
2678 printf("this node is the recmaster\n");
2685 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2688 struct timeval tv = timeval_current();
2689 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2691 printf("Unable to get ping response from node %u\n", options.pnn);
2694 printf("response from %u time=%.6f sec (%d clients)\n",
2695 options.pnn, timeval_elapsed(&tv), ret);
2704 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2715 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2717 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2721 printf("%-19s = %u\n", name, value);
2728 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2739 value = strtoul(argv[1], NULL, 0);
2741 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2743 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2752 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2758 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2760 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2764 for (i=0;i<count;i++) {
2765 control_getvar(ctdb, 1, &list[i]);
2774 display debug level on a node
2776 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2781 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2783 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2786 if (options.machinereadable){
2787 printf(":Name:Level:\n");
2788 printf(":%s:%d:\n",get_debug_by_level(level),level);
2790 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2797 display reclock file of a node
2799 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2802 const char *reclock;
2804 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2806 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2809 if (options.machinereadable){
2810 if (reclock != NULL) {
2811 printf("%s", reclock);
2814 if (reclock == NULL) {
2815 printf("No reclock file used.\n");
2817 printf("Reclock file:%s\n", reclock);
2825 set the reclock file of a node
2827 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2830 const char *reclock;
2834 } else if (argc == 1) {
2840 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2842 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2849 set the natgw state on/off
2851 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2854 uint32_t natgwstate;
2860 if (!strcmp(argv[0], "on")) {
2862 } else if (!strcmp(argv[0], "off")) {
2868 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2870 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2878 set the lmaster role on/off
2880 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2883 uint32_t lmasterrole;
2889 if (!strcmp(argv[0], "on")) {
2891 } else if (!strcmp(argv[0], "off")) {
2897 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2899 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2907 set the recmaster role on/off
2909 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2912 uint32_t recmasterrole;
2918 if (!strcmp(argv[0], "on")) {
2920 } else if (!strcmp(argv[0], "off")) {
2926 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2928 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2936 set debug level on a node or all nodes
2938 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2944 printf("You must specify the debug level. Valid levels are:\n");
2945 for (i=0; debug_levels[i].description != NULL; i++) {
2946 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2952 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2953 level = get_debug_by_desc(argv[0]);
2955 level = strtol(argv[0], NULL, 0);
2958 for (i=0; debug_levels[i].description != NULL; i++) {
2959 if (level == debug_levels[i].level) {
2963 if (debug_levels[i].description == NULL) {
2964 printf("Invalid debug level, must be one of\n");
2965 for (i=0; debug_levels[i].description != NULL; i++) {
2966 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2971 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2973 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2982 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2988 priority = strtol(argv[0], NULL, 0);
2992 DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
2994 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2996 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
3004 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
3010 priority = strtol(argv[0], NULL, 0);
3014 DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
3016 ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
3018 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
3025 attach to a database
3027 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
3029 const char *db_name;
3030 struct ctdb_db_context *ctdb_db;
3037 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
3038 if (ctdb_db == NULL) {
3039 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
3049 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
3051 struct ctdb_db_priority db_prio;
3058 db_prio.db_id = strtoul(argv[0], NULL, 0);
3059 db_prio.priority = strtoul(argv[1], NULL, 0);
3061 ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
3063 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
3073 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
3075 uint32_t db_id, priority;
3082 db_id = strtoul(argv[0], NULL, 0);
3084 ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
3086 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
3090 DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
3096 run an eventscript on a node
3098 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
3104 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3107 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3111 data.dptr = (unsigned char *)discard_const(argv[0]);
3112 data.dsize = strlen((char *)data.dptr) + 1;
3114 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
3116 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
3117 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
3118 if (ret != 0 || res != 0) {
3119 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
3120 talloc_free(tmp_ctx);
3123 talloc_free(tmp_ctx);
3127 #define DB_VERSION 1
3128 #define MAX_DB_NAME 64
3129 struct db_file_header {
3130 unsigned long version;
3132 unsigned long persistent;
3134 const char name[MAX_DB_NAME];
3137 struct backup_data {
3138 struct ctdb_marshall_buffer *records;
3141 bool traverse_error;
3144 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
3146 struct backup_data *bd = talloc_get_type(private, struct backup_data);
3147 struct ctdb_rec_data *rec;
3149 /* add the record */
3150 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
3152 bd->traverse_error = true;
3153 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
3156 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
3157 if (bd->records == NULL) {
3158 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
3159 bd->traverse_error = true;
3162 bd->records->count++;
3163 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
3164 bd->len += rec->length;
3172 * backup a database to a file
3174 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
3177 struct ctdb_dbid_map *dbmap=NULL;
3178 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3179 struct db_file_header dbhdr;
3180 struct ctdb_db_context *ctdb_db;
3181 struct backup_data *bd;
3184 const char *reason = NULL;
3187 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3191 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
3193 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
3197 for(i=0;i<dbmap->num;i++){
3200 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
3201 if(!strcmp(argv[0], name)){
3202 talloc_free(discard_const(name));
3205 talloc_free(discard_const(name));
3207 if (i == dbmap->num) {
3208 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
3209 talloc_free(tmp_ctx);
3213 ret = ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
3214 dbmap->dbs[i].dbid, tmp_ctx, &reason);
3216 DEBUG(DEBUG_ERR,("Unable to get dbhealth for database '%s'\n",
3218 talloc_free(tmp_ctx);
3222 uint32_t allow_unhealthy = 0;
3224 ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn,
3225 "AllowUnhealthyDBRead",
3228 if (allow_unhealthy != 1) {
3229 DEBUG(DEBUG_ERR,("database '%s' is unhealthy: %s\n",
3232 DEBUG(DEBUG_ERR,("disallow backup : tunnable AllowUnhealthyDBRead = %u\n",
3234 talloc_free(tmp_ctx);
3238 DEBUG(DEBUG_WARNING,("WARNING database '%s' is unhealthy - see 'ctdb getdbstatus %s'\n",
3240 DEBUG(DEBUG_WARNING,("WARNING! allow backup of unhealthy database: "
3241 "tunnable AllowUnhealthyDBRead = %u\n",
3245 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3246 if (ctdb_db == NULL) {
3247 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
3248 talloc_free(tmp_ctx);
3253 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3255 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
3256 talloc_free(tmp_ctx);
3261 bd = talloc_zero(tmp_ctx, struct backup_data);
3263 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
3264 talloc_free(tmp_ctx);
3268 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
3269 if (bd->records == NULL) {
3270 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
3271 talloc_free(tmp_ctx);
3275 bd->len = offsetof(struct ctdb_marshall_buffer, data);
3276 bd->records->db_id = ctdb_db->db_id;
3277 /* traverse the database collecting all records */
3278 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
3279 bd->traverse_error) {
3280 DEBUG(DEBUG_ERR,("Traverse error\n"));
3281 talloc_free(tmp_ctx);
3285 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3288 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
3290 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
3291 talloc_free(tmp_ctx);
3295 dbhdr.version = DB_VERSION;
3296 dbhdr.timestamp = time(NULL);
3297 dbhdr.persistent = dbmap->dbs[i].persistent;
3298 dbhdr.size = bd->len;
3299 if (strlen(argv[0]) >= MAX_DB_NAME) {
3300 DEBUG(DEBUG_ERR,("Too long dbname\n"));
3303 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
3304 ret = write(fh, &dbhdr, sizeof(dbhdr));
3306 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3309 ret = write(fh, bd->records, bd->len);
3311 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3320 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3323 talloc_free(tmp_ctx);
3328 * restore a database from a file
3330 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3333 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3336 struct db_file_header dbhdr;
3337 struct ctdb_db_context *ctdb_db;
3338 struct ctdb_node_map *nodemap=NULL;
3339 struct ctdb_vnn_map *vnnmap=NULL;
3341 struct ctdb_control_wipe_database w;
3343 uint32_t generation;
3348 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3352 fh = open(argv[0], O_RDONLY);
3354 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3355 talloc_free(tmp_ctx);
3359 read(fh, &dbhdr, sizeof(dbhdr));
3360 if (dbhdr.version != DB_VERSION) {
3361 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3362 talloc_free(tmp_ctx);
3366 outdata.dsize = dbhdr.size;
3367 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3368 if (outdata.dptr == NULL) {
3369 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3371 talloc_free(tmp_ctx);
3374 read(fh, outdata.dptr, outdata.dsize);
3377 tm = localtime(&dbhdr.timestamp);
3378 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3379 printf("Restoring database '%s' from backup @ %s\n",
3383 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3384 if (ctdb_db == NULL) {
3385 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3386 talloc_free(tmp_ctx);
3390 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3392 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3393 talloc_free(tmp_ctx);
3398 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3400 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3401 talloc_free(tmp_ctx);
3405 /* freeze all nodes */
3406 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3407 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3408 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3414 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3415 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3416 talloc_free(tmp_ctx);
3421 generation = vnnmap->generation;
3422 data.dptr = (void *)&generation;
3423 data.dsize = sizeof(generation);
3425 /* start a cluster wide transaction */
3426 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3427 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3429 TIMELIMIT(), false, data,
3432 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3437 w.db_id = ctdb_db->db_id;
3438 w.transaction_id = generation;
3440 data.dptr = (void *)&w;
3441 data.dsize = sizeof(w);
3443 /* wipe all the remote databases. */
3444 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3445 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3447 TIMELIMIT(), false, data,
3450 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3451 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3452 talloc_free(tmp_ctx);
3456 /* push the database */
3457 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3458 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3460 TIMELIMIT(), false, outdata,
3463 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3464 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3465 talloc_free(tmp_ctx);
3469 data.dptr = (void *)&ctdb_db->db_id;
3470 data.dsize = sizeof(ctdb_db->db_id);
3472 /* mark the database as healthy */
3473 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3474 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_DB_SET_HEALTHY,
3476 TIMELIMIT(), false, data,
3479 DEBUG(DEBUG_ERR, ("Failed to mark database as healthy.\n"));
3480 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3481 talloc_free(tmp_ctx);
3485 data.dptr = (void *)&generation;
3486 data.dsize = sizeof(generation);
3488 /* commit all the changes */
3489 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3491 TIMELIMIT(), false, data,
3494 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3495 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3496 talloc_free(tmp_ctx);
3501 /* thaw all nodes */
3502 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3503 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3509 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3510 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3511 talloc_free(tmp_ctx);
3516 talloc_free(tmp_ctx);
3521 * dump a database backup from a file
3523 static int control_dumpdbbackup(struct ctdb_context *ctdb, int argc, const char **argv)
3525 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3527 struct db_file_header dbhdr;
3531 struct ctdb_rec_data *rec = NULL;
3532 struct ctdb_marshall_buffer *m;
3535 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3539 fh = open(argv[0], O_RDONLY);
3541 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3542 talloc_free(tmp_ctx);
3546 read(fh, &dbhdr, sizeof(dbhdr));
3547 if (dbhdr.version != DB_VERSION) {
3548 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3549 talloc_free(tmp_ctx);
3553 outdata.dsize = dbhdr.size;
3554 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3555 if (outdata.dptr == NULL) {
3556 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3558 talloc_free(tmp_ctx);
3561 read(fh, outdata.dptr, outdata.dsize);
3563 m = (struct ctdb_marshall_buffer *)outdata.dptr;
3565 tm = localtime(&dbhdr.timestamp);
3566 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3567 printf("Backup of database name:'%s' dbid:0x%x08x from @ %s\n",
3568 dbhdr.name, m->db_id, tbuf);
3570 for (i=0; i < m->count; i++) {
3574 /* we do not want the header splitted, so we pass NULL*/
3575 rec = ctdb_marshall_loop_next(m, rec, &reqid,
3578 ctdb_dumpdb_record(ctdb, key, data, stdout);
3581 printf("Dumped %d records\n", i);
3582 talloc_free(tmp_ctx);
3587 * wipe a database from a file
3589 static int control_wipedb(struct ctdb_context *ctdb, int argc,
3593 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3595 struct ctdb_db_context *ctdb_db;
3596 struct ctdb_node_map *nodemap = NULL;
3597 struct ctdb_vnn_map *vnnmap = NULL;
3599 struct ctdb_control_wipe_database w;
3601 uint32_t generation;
3602 struct ctdb_dbid_map *dbmap = NULL;
3605 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3609 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3612 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n",
3617 for(i=0;i<dbmap->num;i++){
3620 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
3621 dbmap->dbs[i].dbid, tmp_ctx, &name);
3622 if(!strcmp(argv[0], name)){
3623 talloc_free(discard_const(name));
3626 talloc_free(discard_const(name));
3628 if (i == dbmap->num) {
3629 DEBUG(DEBUG_ERR, ("No database with name '%s' found\n",
3631 talloc_free(tmp_ctx);
3635 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3636 if (ctdb_db == NULL) {
3637 DEBUG(DEBUG_ERR, ("Unable to attach to database '%s'\n",
3639 talloc_free(tmp_ctx);
3643 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb,
3646 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n",
3648 talloc_free(tmp_ctx);
3652 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3655 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n",
3657 talloc_free(tmp_ctx);
3661 /* freeze all nodes */
3662 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3663 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3664 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3671 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3672 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn,
3673 CTDB_RECOVERY_ACTIVE);
3674 talloc_free(tmp_ctx);
3679 generation = vnnmap->generation;
3680 data.dptr = (void *)&generation;
3681 data.dsize = sizeof(generation);
3683 /* start a cluster wide transaction */
3684 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3685 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3687 TIMELIMIT(), false, data,
3691 DEBUG(DEBUG_ERR, ("Unable to start cluster wide "
3692 "transactions.\n"));
3696 w.db_id = ctdb_db->db_id;
3697 w.transaction_id = generation;
3699 data.dptr = (void *)&w;
3700 data.dsize = sizeof(w);
3702 /* wipe all the remote databases. */
3703 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3704 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3706 TIMELIMIT(), false, data,
3709 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3710 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3711 talloc_free(tmp_ctx);
3715 data.dptr = (void *)&ctdb_db->db_id;
3716 data.dsize = sizeof(ctdb_db->db_id);
3718 /* mark the database as healthy */
3719 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3720 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_DB_SET_HEALTHY,
3722 TIMELIMIT(), false, data,
3725 DEBUG(DEBUG_ERR, ("Failed to mark database as healthy.\n"));
3726 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3727 talloc_free(tmp_ctx);
3731 data.dptr = (void *)&generation;
3732 data.dsize = sizeof(generation);
3734 /* commit all the changes */
3735 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3737 TIMELIMIT(), false, data,
3740 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3741 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3742 talloc_free(tmp_ctx);
3746 /* thaw all nodes */
3747 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3748 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3754 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3755 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3756 talloc_free(tmp_ctx);
3760 talloc_free(tmp_ctx);
3765 * set flags of a node in the nodemap
3767 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3774 struct ctdb_node_flag_change c;
3781 if (sscanf(argv[0], "%d", &node) != 1) {
3782 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3786 if (sscanf(argv[1], "0x%x", &flags) != 1) {
3787 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3794 c.new_flags = flags;
3796 data.dsize = sizeof(c);
3797 data.dptr = (unsigned char *)&c;
3799 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
3800 data, NULL, NULL, &status, NULL, NULL);
3801 if (ret != 0 || status != 0) {
3802 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3811 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3817 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3818 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3819 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3820 if (ret != 0 || res != 0) {
3821 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3822 talloc_free(tmp_ctx);
3825 write(1, data.dptr, data.dsize);
3826 talloc_free(tmp_ctx);
3831 handler for memory dumps
3833 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
3834 TDB_DATA data, void *private_data)
3836 write(1, data.dptr, data.dsize);
3841 dump memory usage on the recovery daemon
3843 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3847 struct rd_memdump_reply rd;
3849 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3851 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3854 rd.srvid = getpid();
3856 /* register a message port for receiveing the reply so that we
3857 can receive the reply
3859 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3862 data.dptr = (uint8_t *)&rd;
3863 data.dsize = sizeof(rd);
3865 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3867 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3871 /* this loop will terminate when we have received the reply */
3873 event_loop_once(ctdb->ev);
3880 list all nodes in the cluster
3881 if the daemon is running, we read the data from the daemon.
3882 if the daemon is not running we parse the nodes file directly
3884 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3887 struct ctdb_node_map *nodemap=NULL;
3890 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3892 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3896 for(i=0;i<nodemap->num;i++){
3897 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3900 if (options.machinereadable){
3901 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3903 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3907 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3908 struct pnn_node *pnn_nodes;
3909 struct pnn_node *pnn_node;
3911 pnn_nodes = read_nodes_file(mem_ctx);
3912 if (pnn_nodes == NULL) {
3913 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3914 talloc_free(mem_ctx);
3918 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3919 ctdb_sock_addr addr;
3921 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3922 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3923 talloc_free(mem_ctx);
3927 if (options.machinereadable){
3928 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3930 printf("%s\n", pnn_node->addr);
3933 talloc_free(mem_ctx);
3940 reload the nodes file on the local node
3942 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3946 struct ctdb_node_map *nodemap=NULL;
3948 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3950 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3954 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3956 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3960 /* reload the nodes file on all remote nodes */
3961 for (i=0;i<nodemap->num;i++) {
3962 if (nodemap->nodes[i].pnn == mypnn) {
3965 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3966 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3967 nodemap->nodes[i].pnn);
3969 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3973 /* reload the nodes file on the local node */
3974 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3975 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3977 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3980 /* initiate a recovery */
3981 control_recover(ctdb, argc, argv);
3987 static const struct {
3989 int (*fn)(struct ctdb_context *, int, const char **);
3991 bool without_daemon; /* can be run without daemon running ? */
3994 } ctdb_commands[] = {
3996 { "version", control_version, true, false, "show version of ctdb" },
3998 { "status", control_status, true, false, "show node status" },
3999 { "uptime", control_uptime, true, false, "show node uptime" },
4000 { "ping", control_ping, true, false, "ping all nodes" },
4001 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
4002 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
4003 { "listvars", control_listvars, true, false, "list tunable variables"},
4004 { "statistics", control_statistics, false, false, "show statistics" },
4005 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
4006 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
4007 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
4008 { "getdbmap", control_getdbmap, true, false, "show the database map" },
4009 { "getdbstatus", control_getdbstatus, true, false, "show the status of a database", "<dbname>" },
4010 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
4011 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
4012 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
4013 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
4014 { "lvs", control_lvs, true, false, "show lvs configuration" },
4015 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
4016 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
4017 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
4018 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
4019 { "getdebug", control_getdebug, true, false, "get debug level" },
4020 { "getlog", control_getlog, true, false, "get the log data from the in memory ringbuffer", "<level>" },
4021 { "clearlog", control_clearlog, true, false, "clear the log data from the in memory ringbuffer" },
4022 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
4023 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
4024 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
4025 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
4026 { "disable", control_disable, true, false, "disable a nodes public IP" },
4027 { "enable", control_enable, true, false, "enable a nodes public IP" },
4028 { "stop", control_stop, true, false, "stop a node" },
4029 { "continue", control_continue, true, false, "re-start a stopped node" },
4030 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
4031 { "unban", control_unban, true, false, "unban a node" },
4032 { "showban", control_showban, true, false, "show ban information"},
4033 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
4034 { "recover", control_recover, true, false, "force recovery" },
4035 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
4036 { "freeze", control_freeze, true, false, "freeze databases", "[priority:1-3]" },
4037 { "thaw", control_thaw, true, false, "thaw databases", "[priority:1-3]" },
4038 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
4039 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
4040 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
4041 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
4042 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
4044 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
4045 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
4046 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
4047 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
4048 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
4049 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
4050 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
4051 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
4052 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
4053 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
4054 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
4055 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
4056 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
4057 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
4058 { "dumpdbbackup", control_dumpdbbackup, false, true, "dump database backup from a file.", "<file>"},
4059 { "wipedb", control_wipedb, false, false, "wipe the contents of a database.", "<dbname>"},
4060 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
4061 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
4062 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts (or all scripts)", "[all]"},
4063 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
4064 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
4065 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
4066 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
4067 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
4068 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
4069 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
4070 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
4071 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
4072 { "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
4073 { "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
4079 static void usage(void)
4083 "Usage: ctdb [options] <control>\n" \
4085 " -n <node> choose node number, or 'all' (defaults to local node)\n"
4086 " -Y generate machinereadable output\n"
4087 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
4088 printf("Controls:\n");
4089 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
4090 printf(" %-15s %-27s %s\n",
4091 ctdb_commands[i].name,
4092 ctdb_commands[i].args?ctdb_commands[i].args:"",
4093 ctdb_commands[i].msg);
4099 static void ctdb_alarm(int sig)
4101 printf("Maximum runtime exceeded - exiting\n");
4108 int main(int argc, const char *argv[])
4110 struct ctdb_context *ctdb;
4111 char *nodestring = NULL;
4112 struct poptOption popt_options[] = {
4115 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
4116 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
4117 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
4118 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
4122 const char **extra_argv;
4126 struct event_context *ev;
4127 const char *control;
4131 /* set some defaults */
4132 options.maxruntime = 0;
4133 options.timelimit = 3;
4134 options.pnn = CTDB_CURRENT_NODE;
4136 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
4138 while ((opt = poptGetNextOpt(pc)) != -1) {
4141 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
4142 poptBadOption(pc, 0), poptStrerror(opt)));
4147 /* setup the remaining options for the main program to use */
4148 extra_argv = poptGetArgs(pc);
4151 while (extra_argv[extra_argc]) extra_argc++;
4154 if (extra_argc < 1) {
4158 if (options.maxruntime == 0) {
4159 const char *ctdb_timeout;
4160 ctdb_timeout = getenv("CTDB_TIMEOUT");
4161 if (ctdb_timeout != NULL) {
4162 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
4164 /* default timeout is 120 seconds */
4165 options.maxruntime = 120;
4169 signal(SIGALRM, ctdb_alarm);
4170 alarm(options.maxruntime);
4172 /* setup the node number to contact */
4173 if (nodestring != NULL) {
4174 if (strcmp(nodestring, "all") == 0) {
4175 options.pnn = CTDB_BROADCAST_ALL;
4177 options.pnn = strtoul(nodestring, NULL, 0);
4181 control = extra_argv[0];
4183 ev = event_context_init(NULL);
4185 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
4186 if (strcmp(control, ctdb_commands[i].name) == 0) {
4189 if (ctdb_commands[i].without_daemon == true) {
4193 /* initialise ctdb */
4194 ctdb = ctdb_cmdline_client(ev);
4196 if (ctdb_commands[i].without_daemon == false) {
4198 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
4202 /* verify the node exists */
4205 if (options.pnn == CTDB_CURRENT_NODE) {
4207 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
4215 if (ctdb_commands[i].auto_all &&
4216 options.pnn == CTDB_BROADCAST_ALL) {
4221 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
4222 CTDB_NO_MEMORY(ctdb, nodes);
4224 for (j=0;j<num_nodes;j++) {
4225 options.pnn = nodes[j];
4226 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4230 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4236 if (i == ARRAY_SIZE(ctdb_commands)) {
4237 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));