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(num_recoveries),
170 STATISTICS_FIELD(client_packets_sent),
171 STATISTICS_FIELD(client_packets_recv),
172 STATISTICS_FIELD(node_packets_sent),
173 STATISTICS_FIELD(node_packets_recv),
174 STATISTICS_FIELD(keepalive_packets_sent),
175 STATISTICS_FIELD(keepalive_packets_recv),
176 STATISTICS_FIELD(node.req_call),
177 STATISTICS_FIELD(node.reply_call),
178 STATISTICS_FIELD(node.req_dmaster),
179 STATISTICS_FIELD(node.reply_dmaster),
180 STATISTICS_FIELD(node.reply_error),
181 STATISTICS_FIELD(node.req_message),
182 STATISTICS_FIELD(node.req_control),
183 STATISTICS_FIELD(node.reply_control),
184 STATISTICS_FIELD(client.req_call),
185 STATISTICS_FIELD(client.req_message),
186 STATISTICS_FIELD(client.req_control),
187 STATISTICS_FIELD(timeouts.call),
188 STATISTICS_FIELD(timeouts.control),
189 STATISTICS_FIELD(timeouts.traverse),
190 STATISTICS_FIELD(total_calls),
191 STATISTICS_FIELD(pending_calls),
192 STATISTICS_FIELD(lockwait_calls),
193 STATISTICS_FIELD(pending_lockwait_calls),
194 STATISTICS_FIELD(childwrite_calls),
195 STATISTICS_FIELD(pending_childwrite_calls),
196 STATISTICS_FIELD(memory_used),
197 STATISTICS_FIELD(max_hop_count),
199 printf("CTDB version %u\n", CTDB_VERSION);
200 for (i=0;i<ARRAY_SIZE(fields);i++) {
201 if (strchr(fields[i].name, '.')) {
202 preflen = strcspn(fields[i].name, ".")+1;
203 if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
204 prefix = fields[i].name;
205 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
210 printf(" %*s%-22s%*s%10u\n",
212 fields[i].name+preflen,
214 *(uint32_t *)(fields[i].offset+(uint8_t *)s));
216 printf(" %-30s %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
217 printf(" %-30s %.6f sec\n", "max_reclock_recd", s->reclock.recd);
219 printf(" %-30s %.6f sec\n", "max_call_latency", s->max_call_latency);
220 printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
221 printf(" %-30s %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
222 talloc_free(tmp_ctx);
226 display remote ctdb statistics combined from all nodes
228 static int control_statistics_all(struct ctdb_context *ctdb)
231 struct ctdb_statistics statistics;
235 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
236 CTDB_NO_MEMORY(ctdb, nodes);
238 ZERO_STRUCT(statistics);
240 for (i=0;i<num_nodes;i++) {
241 struct ctdb_statistics s1;
243 uint32_t *v1 = (uint32_t *)&s1;
244 uint32_t *v2 = (uint32_t *)&statistics;
246 offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
247 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
249 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
252 for (j=0;j<num_ints;j++) {
255 statistics.max_hop_count =
256 MAX(statistics.max_hop_count, s1.max_hop_count);
257 statistics.max_call_latency =
258 MAX(statistics.max_call_latency, s1.max_call_latency);
259 statistics.max_lockwait_latency =
260 MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
263 printf("Gathered statistics for %u nodes\n", num_nodes);
264 show_statistics(&statistics);
269 display remote ctdb statistics
271 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
274 struct ctdb_statistics statistics;
276 if (options.pnn == CTDB_BROADCAST_ALL) {
277 return control_statistics_all(ctdb);
280 ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
282 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
285 show_statistics(&statistics);
291 reset remote ctdb statistics
293 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
297 ret = ctdb_statistics_reset(ctdb, options.pnn);
299 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
307 display uptime of remote node
309 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
312 struct ctdb_uptime *uptime = NULL;
313 int tmp, days, hours, minutes, seconds;
315 ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
317 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
321 if (options.machinereadable){
322 printf(":Current Node Time:Ctdb Start Time:Last Recovery/Failover Time:Last Recovery/IPFailover Duration:\n");
323 printf(":%u:%u:%u:%lf\n",
324 (unsigned int)uptime->current_time.tv_sec,
325 (unsigned int)uptime->ctdbd_start_time.tv_sec,
326 (unsigned int)uptime->last_recovery_finished.tv_sec,
327 timeval_delta(&uptime->last_recovery_finished,
328 &uptime->last_recovery_started)
333 printf("Current time of node : %s", ctime(&uptime->current_time.tv_sec));
335 tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
343 printf("Ctdbd start time : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
345 tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
353 printf("Time of last recovery/failover: (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
355 printf("Duration of last recovery/failover: %lf seconds\n",
356 timeval_delta(&uptime->last_recovery_finished,
357 &uptime->last_recovery_started));
363 show the PNN of the current node
365 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
369 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
371 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
375 printf("PNN:%d\n", mypnn);
381 struct pnn_node *next;
386 static struct pnn_node *read_nodes_file(TALLOC_CTX *mem_ctx)
388 const char *nodes_list;
392 struct pnn_node *pnn_nodes = NULL;
393 struct pnn_node *pnn_node;
394 struct pnn_node *tmp_node;
396 /* read the nodes file */
397 nodes_list = getenv("CTDB_NODES");
398 if (nodes_list == NULL) {
399 nodes_list = "/etc/ctdb/nodes";
401 lines = file_lines_load(nodes_list, &nlines, mem_ctx);
405 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
408 for (i=0, pnn=0; i<nlines; i++) {
412 /* strip leading spaces */
413 while((*node == ' ') || (*node == '\t')) {
420 if (strcmp(node, "") == 0) {
423 pnn_node = talloc(mem_ctx, struct pnn_node);
424 pnn_node->pnn = pnn++;
425 pnn_node->addr = talloc_strdup(pnn_node, node);
426 pnn_node->next = pnn_nodes;
427 pnn_nodes = pnn_node;
430 /* swap them around so we return them in incrementing order */
431 pnn_node = pnn_nodes;
435 pnn_node = pnn_node->next;
437 tmp_node->next = pnn_nodes;
438 pnn_nodes = tmp_node;
445 show the PNN of the current node
446 discover the pnn by loading the nodes file and try to bind to all
447 addresses one at a time until the ip address is found.
449 static int control_xpnn(struct ctdb_context *ctdb, int argc, const char **argv)
451 TALLOC_CTX *mem_ctx = talloc_new(NULL);
452 struct pnn_node *pnn_nodes;
453 struct pnn_node *pnn_node;
455 pnn_nodes = read_nodes_file(mem_ctx);
456 if (pnn_nodes == NULL) {
457 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
458 talloc_free(mem_ctx);
462 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
465 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
466 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
467 talloc_free(mem_ctx);
471 if (ctdb_sys_have_ip(&addr)) {
472 printf("PNN:%d\n", pnn_node->pnn);
473 talloc_free(mem_ctx);
478 printf("Failed to detect which PNN this node is\n");
479 talloc_free(mem_ctx);
484 display remote ctdb status
486 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
489 struct ctdb_vnn_map *vnnmap=NULL;
490 struct ctdb_node_map *nodemap=NULL;
491 uint32_t recmode, recmaster;
494 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
499 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
501 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
505 if(options.machinereadable){
506 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:Stopped:\n");
507 for(i=0;i<nodemap->num;i++){
508 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
511 printf(":%d:%s:%d:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
512 ctdb_addr_to_str(&nodemap->nodes[i].addr),
513 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
514 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
515 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
516 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
517 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
522 printf("Number of nodes:%d\n", nodemap->num);
523 for(i=0;i<nodemap->num;i++){
524 static const struct {
528 { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" },
529 { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" },
530 { NODE_FLAGS_BANNED, "BANNED" },
531 { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" },
532 { NODE_FLAGS_DELETED, "DELETED" },
533 { NODE_FLAGS_STOPPED, "STOPPED" },
535 char *flags_str = NULL;
538 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
541 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
542 if (nodemap->nodes[i].flags & flag_names[j].flag) {
543 if (flags_str == NULL) {
544 flags_str = talloc_strdup(ctdb, flag_names[j].name);
546 flags_str = talloc_asprintf_append(flags_str, "|%s",
549 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
552 if (flags_str == NULL) {
553 flags_str = talloc_strdup(ctdb, "OK");
554 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
556 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
557 ctdb_addr_to_str(&nodemap->nodes[i].addr),
559 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
560 talloc_free(flags_str);
563 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
565 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
568 if (vnnmap->generation == INVALID_GENERATION) {
569 printf("Generation:INVALID\n");
571 printf("Generation:%d\n",vnnmap->generation);
573 printf("Size:%d\n",vnnmap->size);
574 for(i=0;i<vnnmap->size;i++){
575 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
578 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
580 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
583 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
585 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
587 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
590 printf("Recovery master:%d\n",recmaster);
597 struct natgw_node *next;
602 display the list of nodes belonging to this natgw configuration
604 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
607 const char *natgw_list;
610 struct natgw_node *natgw_nodes = NULL;
611 struct natgw_node *natgw_node;
612 struct ctdb_node_map *nodemap=NULL;
615 /* read the natgw nodes file into a linked list */
616 natgw_list = getenv("NATGW_NODES");
617 if (natgw_list == NULL) {
618 natgw_list = "/etc/ctdb/natgw_nodes";
620 lines = file_lines_load(natgw_list, &nlines, ctdb);
622 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
625 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
628 for (i=0;i<nlines;i++) {
632 /* strip leading spaces */
633 while((*node == ' ') || (*node == '\t')) {
639 if (strcmp(node, "") == 0) {
642 natgw_node = talloc(ctdb, struct natgw_node);
643 natgw_node->addr = talloc_strdup(natgw_node, node);
644 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
645 natgw_node->next = natgw_nodes;
646 natgw_nodes = natgw_node;
649 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
651 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
656 while(i<nodemap->num) {
657 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
658 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
663 /* this node was not in the natgw so we just remove it from
666 if ((natgw_node == NULL)
667 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
670 for (j=i+1; j<nodemap->num; j++) {
671 nodemap->nodes[j-1] = nodemap->nodes[j];
680 /* pick a node to be natgwmaster
681 * we dont allow STOPPED, DELETED, BANNED or UNHEALTHY nodes to become the natgwmaster
683 for(i=0;i<nodemap->num;i++){
684 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_UNHEALTHY))) {
685 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
689 /* we couldnt find any healthy node, try unhealthy ones */
690 if (i == nodemap->num) {
691 for(i=0;i<nodemap->num;i++){
692 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
693 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
698 /* unless all nodes are STOPPED, when we pick one anyway */
699 if (i == nodemap->num) {
700 for(i=0;i<nodemap->num;i++){
701 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
702 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
706 /* or if we still can not find any */
707 if (i == nodemap->num) {
708 printf("-1 0.0.0.0\n");
712 /* print the pruned list of nodes belonging to this natgw list */
713 for(i=0;i<nodemap->num;i++){
714 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
717 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
718 ctdb_addr_to_str(&nodemap->nodes[i].addr),
719 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
720 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
721 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
722 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
723 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
730 display the status of the scripts for monitoring (or other events)
732 static int control_one_scriptstatus(struct ctdb_context *ctdb,
733 enum ctdb_eventscript_call type)
735 struct ctdb_scripts_wire *script_status;
738 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, type, &script_status);
740 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
744 if (script_status == NULL) {
745 if (!options.machinereadable) {
746 printf("%s cycle never run\n",
747 ctdb_eventscript_call_names[type]);
752 if (!options.machinereadable) {
753 printf("%d scripts were executed last %s cycle\n",
754 script_status->num_scripts,
755 ctdb_eventscript_call_names[type]);
757 for (i=0; i<script_status->num_scripts; i++) {
758 const char *status = NULL;
760 switch (script_status->scripts[i].status) {
771 if (script_status->scripts[i].status > 0)
775 if (options.machinereadable) {
776 printf("%s:%s:%i:%s:%lu.%06lu:%lu.%06lu:%s:\n",
777 ctdb_eventscript_call_names[type],
778 script_status->scripts[i].name,
779 script_status->scripts[i].status,
781 (long)script_status->scripts[i].start.tv_sec,
782 (long)script_status->scripts[i].start.tv_usec,
783 (long)script_status->scripts[i].finished.tv_sec,
784 (long)script_status->scripts[i].finished.tv_usec,
785 script_status->scripts[i].output);
789 printf("%-20s Status:%s ",
790 script_status->scripts[i].name, status);
792 /* Some other error, eg from stat. */
793 printf("%-20s Status:CANNOT RUN (%s)",
794 script_status->scripts[i].name,
795 strerror(-script_status->scripts[i].status));
797 if (script_status->scripts[i].status >= 0) {
798 printf("Duration:%.3lf ",
799 timeval_delta(&script_status->scripts[i].finished,
800 &script_status->scripts[i].start));
802 if (script_status->scripts[i].status != -ENOEXEC) {
804 ctime(&script_status->scripts[i].start.tv_sec));
805 if (script_status->scripts[i].status != 0) {
806 printf(" OUTPUT:%s\n",
807 script_status->scripts[i].output);
817 static int control_scriptstatus(struct ctdb_context *ctdb,
818 int argc, const char **argv)
821 enum ctdb_eventscript_call type, min, max;
825 DEBUG(DEBUG_ERR, ("Unknown arguments to scriptstatus\n"));
830 arg = ctdb_eventscript_call_names[CTDB_EVENT_MONITOR];
834 for (type = 0; type < CTDB_EVENT_MAX; type++) {
835 if (strcmp(arg, ctdb_eventscript_call_names[type]) == 0) {
841 if (type == CTDB_EVENT_MAX) {
842 if (strcmp(arg, "all") == 0) {
844 max = CTDB_EVENT_MAX;
846 DEBUG(DEBUG_ERR, ("Unknown event type %s\n", argv[0]));
851 if (options.machinereadable) {
852 printf(":Type:Name:Code:Status:Start:End:Error Output...:\n");
855 for (type = min; type < max; type++) {
856 ret = control_one_scriptstatus(ctdb, type);
866 enable an eventscript
868 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
876 ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
878 DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
886 disable an eventscript
888 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
896 ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
898 DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
906 display the pnn of the recovery master
908 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
913 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
915 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
918 printf("%d\n",recmaster);
924 get a list of all tickles for this pnn
926 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
928 struct ctdb_control_tcp_tickle_list *list;
936 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
937 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
941 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
943 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
947 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
948 printf("Num tickles:%u\n", list->tickles.num);
949 for (i=0;i<list->tickles.num;i++) {
950 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
951 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));
961 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
963 struct ctdb_all_public_ips *ips;
964 struct ctdb_public_ip ip;
967 uint32_t disable_time;
969 struct ctdb_node_map *nodemap=NULL;
970 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
973 data.dptr = (uint8_t*)&disable_time;
974 data.dsize = sizeof(disable_time);
975 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
977 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
983 /* read the public ip list from the node */
984 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
986 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
987 talloc_free(tmp_ctx);
991 for (i=0;i<ips->num;i++) {
992 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
997 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
998 pnn, ctdb_addr_to_str(addr)));
999 talloc_free(tmp_ctx);
1006 data.dptr = (uint8_t *)&ip;
1007 data.dsize = sizeof(ip);
1009 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
1011 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1012 talloc_free(tmp_ctx);
1016 nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
1017 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
1024 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
1025 talloc_free(tmp_ctx);
1029 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
1031 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
1032 talloc_free(tmp_ctx);
1036 /* update the recovery daemon so it now knows to expect the new
1037 node assignment for this ip.
1039 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_RECD_UPDATE_IP, data);
1041 DEBUG(DEBUG_ERR,("Failed to send message to update the ip on the recovery master.\n"));
1045 talloc_free(tmp_ctx);
1050 move/failover an ip address to a specific node
1052 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
1055 ctdb_sock_addr addr;
1062 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1063 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1068 if (sscanf(argv[1], "%u", &pnn) != 1) {
1069 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
1073 if (move_ip(ctdb, &addr, pnn) != 0) {
1074 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1081 void getips_store_callback(void *param, void *data)
1083 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
1084 struct ctdb_all_public_ips *ips = param;
1088 ips->ips[i].pnn = node_ip->pnn;
1089 ips->ips[i].addr = node_ip->addr;
1092 void getips_count_callback(void *param, void *data)
1094 uint32_t *count = param;
1100 static uint32_t *ip_key(ctdb_sock_addr *ip)
1102 static uint32_t key[IP_KEYLEN];
1104 bzero(key, sizeof(key));
1106 switch (ip->sa.sa_family) {
1108 key[0] = ip->ip.sin_addr.s_addr;
1111 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
1112 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
1113 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
1114 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
1117 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1124 static void *add_ip_callback(void *parm, void *data)
1130 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1132 struct ctdb_all_public_ips *tmp_ips;
1133 struct ctdb_node_map *nodemap=NULL;
1134 trbt_tree_t *ip_tree;
1138 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1140 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1144 ip_tree = trbt_create(tmp_ctx, 0);
1146 for(i=0;i<nodemap->num;i++){
1147 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1150 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1154 /* read the public ip list from this node */
1155 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1157 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1161 for (j=0; j<tmp_ips->num;j++) {
1162 struct ctdb_public_ip *node_ip;
1164 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1165 node_ip->pnn = tmp_ips->ips[j].pnn;
1166 node_ip->addr = tmp_ips->ips[j].addr;
1168 trbt_insertarray32_callback(ip_tree,
1169 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1173 talloc_free(tmp_ips);
1178 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1180 len = offsetof(struct ctdb_all_public_ips, ips) +
1181 count*sizeof(struct ctdb_public_ip);
1182 tmp_ips = talloc_zero_size(tmp_ctx, len);
1183 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1192 * scans all other nodes and returns a pnn for another node that can host this
1196 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1198 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1199 struct ctdb_all_public_ips *ips;
1200 struct ctdb_node_map *nodemap=NULL;
1203 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1205 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1206 talloc_free(tmp_ctx);
1210 for(i=0;i<nodemap->num;i++){
1211 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1214 if (nodemap->nodes[i].pnn == options.pnn) {
1218 /* read the public ip list from this node */
1219 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1221 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1225 for (j=0;j<ips->num;j++) {
1226 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1227 talloc_free(tmp_ctx);
1228 return nodemap->nodes[i].pnn;
1234 talloc_free(tmp_ctx);
1239 add a public ip address to a node
1241 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1247 ctdb_sock_addr addr;
1248 struct ctdb_control_ip_iface *pub;
1249 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1250 struct ctdb_all_public_ips *ips;
1254 talloc_free(tmp_ctx);
1258 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1259 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1260 talloc_free(tmp_ctx);
1264 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1266 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1267 talloc_free(tmp_ctx);
1272 /* check if some other node is already serving this ip, if not,
1275 for (i=0;i<ips->num;i++) {
1276 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1281 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1282 pub = talloc_size(tmp_ctx, len);
1283 CTDB_NO_MEMORY(ctdb, pub);
1287 pub->len = strlen(argv[1])+1;
1288 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1290 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1292 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1293 talloc_free(tmp_ctx);
1297 if (i == ips->num) {
1298 /* no one has this ip so we claim it */
1301 pnn = ips->ips[i].pnn;
1304 if (move_ip(ctdb, &addr, pnn) != 0) {
1305 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1309 talloc_free(tmp_ctx);
1313 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1315 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1317 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1318 struct ctdb_node_map *nodemap=NULL;
1319 struct ctdb_all_public_ips *ips;
1322 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1324 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1328 /* remove it from the nodes that are not hosting the ip currently */
1329 for(i=0;i<nodemap->num;i++){
1330 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1333 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1334 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1338 for (j=0;j<ips->num;j++) {
1339 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1347 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1351 options.pnn = nodemap->nodes[i].pnn;
1352 control_delip(ctdb, argc, argv);
1356 /* remove it from every node (also the one hosting it) */
1357 for(i=0;i<nodemap->num;i++){
1358 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1361 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1362 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1366 for (j=0;j<ips->num;j++) {
1367 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1375 options.pnn = nodemap->nodes[i].pnn;
1376 control_delip(ctdb, argc, argv);
1379 talloc_free(tmp_ctx);
1384 delete a public ip address from a node
1386 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1389 ctdb_sock_addr addr;
1390 struct ctdb_control_ip_iface pub;
1391 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1392 struct ctdb_all_public_ips *ips;
1395 talloc_free(tmp_ctx);
1399 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1400 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1404 if (options.pnn == CTDB_BROADCAST_ALL) {
1405 return control_delip_all(ctdb, argc, argv, &addr);
1412 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1414 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1415 talloc_free(tmp_ctx);
1419 for (i=0;i<ips->num;i++) {
1420 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1426 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1427 ctdb_addr_to_str(&addr)));
1428 talloc_free(tmp_ctx);
1432 if (ips->ips[i].pnn == options.pnn) {
1433 ret = find_other_host_for_public_ip(ctdb, &addr);
1435 if (move_ip(ctdb, &addr, ret) != 0) {
1436 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1442 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1444 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1445 talloc_free(tmp_ctx);
1449 talloc_free(tmp_ctx);
1454 kill a tcp connection
1456 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1459 struct ctdb_control_killtcp killtcp;
1465 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1466 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1470 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1471 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1475 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1477 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1488 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1491 ctdb_sock_addr addr;
1497 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1498 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1502 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1504 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1512 register a server id
1514 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1517 struct ctdb_server_id server_id;
1523 server_id.pnn = strtoul(argv[0], NULL, 0);
1524 server_id.type = strtoul(argv[1], NULL, 0);
1525 server_id.server_id = strtoul(argv[2], NULL, 0);
1527 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1529 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1536 unregister a server id
1538 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1541 struct ctdb_server_id server_id;
1547 server_id.pnn = strtoul(argv[0], NULL, 0);
1548 server_id.type = strtoul(argv[1], NULL, 0);
1549 server_id.server_id = strtoul(argv[2], NULL, 0);
1551 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1553 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1560 check if a server id exists
1562 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1566 struct ctdb_server_id server_id;
1572 server_id.pnn = strtoul(argv[0], NULL, 0);
1573 server_id.type = strtoul(argv[1], NULL, 0);
1574 server_id.server_id = strtoul(argv[2], NULL, 0);
1576 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1578 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1583 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1585 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1591 get a list of all server ids that are registered on a node
1593 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1596 struct ctdb_server_id_list *server_ids;
1598 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1600 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1604 for (i=0; i<server_ids->num; i++) {
1605 printf("Server id %d:%d:%d\n",
1606 server_ids->server_ids[i].pnn,
1607 server_ids->server_ids[i].type,
1608 server_ids->server_ids[i].server_id);
1615 send a tcp tickle ack
1617 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1620 ctdb_sock_addr src, dst;
1626 if (!parse_ip_port(argv[0], &src)) {
1627 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1631 if (!parse_ip_port(argv[1], &dst)) {
1632 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1636 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1640 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1647 display public ip status
1649 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1652 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1653 struct ctdb_all_public_ips *ips;
1655 if (options.pnn == CTDB_BROADCAST_ALL) {
1656 /* read the list of public ips from all nodes */
1657 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1659 /* read the public ip list from this node */
1660 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1663 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1664 talloc_free(tmp_ctx);
1668 if (options.machinereadable){
1669 printf(":Public IP:Node:\n");
1671 if (options.pnn == CTDB_BROADCAST_ALL) {
1672 printf("Public IPs on ALL nodes\n");
1674 printf("Public IPs on node %u\n", options.pnn);
1678 for (i=1;i<=ips->num;i++) {
1679 if (options.machinereadable){
1680 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1682 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1686 talloc_free(tmp_ctx);
1691 display pid of a ctdb daemon
1693 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1698 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1700 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1703 printf("Pid:%d\n", pid);
1709 handler for receiving the response to ipreallocate
1711 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1712 TDB_DATA data, void *private_data)
1717 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1719 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1721 event_add_timed(ctdb->ev, ctdb,
1722 timeval_current_ofs(1, 0),
1723 ctdb_every_second, ctdb);
1727 ask the recovery daemon on the recovery master to perform a ip reallocation
1729 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1733 struct takeover_run_reply rd;
1735 struct ctdb_node_map *nodemap=NULL;
1737 struct timeval tv = timeval_current();
1739 /* we need some events to trigger so we can timeout and restart
1742 event_add_timed(ctdb->ev, ctdb,
1743 timeval_current_ofs(1, 0),
1744 ctdb_every_second, ctdb);
1746 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1748 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1751 rd.srvid = getpid();
1753 /* register a message port for receiveing the reply so that we
1754 can receive the reply
1756 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1758 data.dptr = (uint8_t *)&rd;
1759 data.dsize = sizeof(rd);
1762 /* check that there are valid nodes available */
1763 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1764 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1767 for (i=0; i<nodemap->num;i++) {
1768 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1772 if (i==nodemap->num) {
1773 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1778 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1780 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1784 /* verify the node exists */
1785 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1786 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1791 /* check tha there are nodes available that can act as a recmaster */
1792 for (i=0; i<nodemap->num; i++) {
1793 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1798 if (i == nodemap->num) {
1799 DEBUG(DEBUG_ERR,("No possible nodes to host addresses.\n"));
1803 /* verify the recovery master is not STOPPED, nor BANNED */
1804 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1805 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1812 /* verify the recovery master is not STOPPED, nor BANNED */
1813 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1814 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1820 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1822 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1826 tv = timeval_current();
1827 /* this loop will terminate when we have received the reply */
1828 while (timeval_elapsed(&tv) < 3.0) {
1829 event_loop_once(ctdb->ev);
1832 DEBUG(DEBUG_ERR,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1842 disable a remote node
1844 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1847 struct ctdb_node_map *nodemap=NULL;
1850 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1852 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1858 /* read the nodemap and verify the change took effect */
1859 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1860 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1864 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1865 ret = control_ipreallocate(ctdb, argc, argv);
1867 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1875 enable a disabled remote node
1877 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1881 struct ctdb_node_map *nodemap=NULL;
1884 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1886 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1892 /* read the nodemap and verify the change took effect */
1893 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1894 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1898 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1899 ret = control_ipreallocate(ctdb, argc, argv);
1901 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1911 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1914 struct ctdb_node_map *nodemap=NULL;
1917 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1919 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
1924 /* read the nodemap and verify the change took effect */
1925 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1926 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1930 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1931 ret = control_ipreallocate(ctdb, argc, argv);
1933 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1941 restart a stopped remote node
1943 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1947 struct ctdb_node_map *nodemap=NULL;
1950 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1952 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1958 /* read the nodemap and verify the change took effect */
1959 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1960 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1964 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1965 ret = control_ipreallocate(ctdb, argc, argv);
1967 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1974 static uint32_t get_generation(struct ctdb_context *ctdb)
1976 struct ctdb_vnn_map *vnnmap=NULL;
1979 /* wait until the recmaster is not in recovery mode */
1981 uint32_t recmode, recmaster;
1983 if (vnnmap != NULL) {
1984 talloc_free(vnnmap);
1988 /* get the recmaster */
1989 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1991 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1995 /* get recovery mode */
1996 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1998 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
2002 /* get the current generation number */
2003 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
2005 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
2009 if ((recmode == CTDB_RECOVERY_NORMAL)
2010 && (vnnmap->generation != 1)){
2011 return vnnmap->generation;
2018 ban a node from the cluster
2020 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
2023 struct ctdb_node_map *nodemap=NULL;
2024 struct ctdb_ban_time bantime;
2030 /* verify the node exists */
2031 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2033 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2037 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
2038 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
2042 bantime.pnn = options.pnn;
2043 bantime.time = strtoul(argv[0], NULL, 0);
2045 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2047 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
2051 ret = control_ipreallocate(ctdb, argc, argv);
2053 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2062 unban a node from the cluster
2064 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
2067 struct ctdb_node_map *nodemap=NULL;
2068 struct ctdb_ban_time bantime;
2070 /* verify the node exists */
2071 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2073 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2077 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
2078 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
2082 bantime.pnn = options.pnn;
2085 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2087 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
2091 ret = control_ipreallocate(ctdb, argc, argv);
2093 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2102 show ban information for a node
2104 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
2107 struct ctdb_node_map *nodemap=NULL;
2108 struct ctdb_ban_time *bantime;
2110 /* verify the node exists */
2111 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2113 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2117 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2119 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2123 if (bantime->time == 0) {
2124 printf("Node %u is not banned\n", bantime->pnn);
2126 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2135 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2139 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2141 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2151 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2154 uint32_t generation, next_generation;
2156 /* record the current generation number */
2157 generation = get_generation(ctdb);
2159 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2161 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2165 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2167 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2171 /* wait until we are in a new generation */
2173 next_generation = get_generation(ctdb);
2174 if (next_generation != generation) {
2185 display monitoring mode of a remote node
2187 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2192 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2194 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2197 if (!options.machinereadable){
2198 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2201 printf(":%d:\n",monmode);
2208 display capabilities of a remote node
2210 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2212 uint32_t capabilities;
2215 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2217 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2221 if (!options.machinereadable){
2222 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2223 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2224 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2225 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2227 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2228 printf(":%d:%d:%d:%d:\n",
2229 !!(capabilities&CTDB_CAP_RECMASTER),
2230 !!(capabilities&CTDB_CAP_LMASTER),
2231 !!(capabilities&CTDB_CAP_LVS),
2232 !!(capabilities&CTDB_CAP_NATGW));
2238 display lvs configuration
2240 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2242 uint32_t *capabilities;
2243 struct ctdb_node_map *nodemap=NULL;
2245 int healthy_count = 0;
2247 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2249 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2253 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2254 CTDB_NO_MEMORY(ctdb, capabilities);
2256 /* collect capabilities for all connected nodes */
2257 for (i=0; i<nodemap->num; i++) {
2258 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2261 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2265 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2267 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2271 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2275 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2280 /* Print all LVS nodes */
2281 for (i=0; i<nodemap->num; i++) {
2282 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2285 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2288 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2292 if (healthy_count != 0) {
2293 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2298 printf("%d:%s\n", i,
2299 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2306 display who is the lvs master
2308 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2310 uint32_t *capabilities;
2311 struct ctdb_node_map *nodemap=NULL;
2313 int healthy_count = 0;
2315 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2317 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2321 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2322 CTDB_NO_MEMORY(ctdb, capabilities);
2324 /* collect capabilities for all connected nodes */
2325 for (i=0; i<nodemap->num; i++) {
2326 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2329 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2333 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2335 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2339 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2343 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2348 /* find and show the lvsmaster */
2349 for (i=0; i<nodemap->num; i++) {
2350 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2353 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2356 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2360 if (healthy_count != 0) {
2361 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2366 if (options.machinereadable){
2369 printf("Node %d is LVS master\n", i);
2374 printf("There is no LVS master\n");
2379 disable monitoring on a node
2381 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2386 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2388 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2391 printf("Monitoring mode:%s\n","DISABLED");
2397 enable monitoring on a node
2399 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2404 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2406 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2409 printf("Monitoring mode:%s\n","ACTIVE");
2415 display remote list of keys/data for a db
2417 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2419 const char *db_name;
2420 struct ctdb_db_context *ctdb_db;
2430 if (db_exists(ctdb, db_name)) {
2431 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2435 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2437 if (ctdb_db == NULL) {
2438 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2442 /* traverse and dump the cluster tdb */
2443 ret = ctdb_dump_db(ctdb_db, stdout);
2445 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2446 DEBUG(DEBUG_ERR, ("Maybe try 'ctdb getdbstatus %s'"
2447 " and 'ctdb getvar AllowUnhealthyDBRead'\n",
2451 talloc_free(ctdb_db);
2453 printf("Dumped %d records\n", ret);
2458 static void log_handler(struct ctdb_context *ctdb, uint64_t srvid,
2459 TDB_DATA data, void *private_data)
2461 DEBUG(DEBUG_ERR,("Log data received\n"));
2462 if (data.dsize > 0) {
2463 printf("%s", data.dptr);
2470 display a list of log messages from the in memory ringbuffer
2472 static int control_getlog(struct ctdb_context *ctdb, int argc, const char **argv)
2476 struct ctdb_get_log_addr log_addr;
2478 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2483 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2484 talloc_free(tmp_ctx);
2488 log_addr.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2489 log_addr.srvid = getpid();
2490 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2491 log_addr.level = get_debug_by_desc(argv[0]);
2493 log_addr.level = strtol(argv[0], NULL, 0);
2497 data.dptr = (unsigned char *)&log_addr;
2498 data.dsize = sizeof(log_addr);
2500 DEBUG(DEBUG_ERR, ("Pulling logs from node %u\n", options.pnn));
2502 ctdb_set_message_handler(ctdb, log_addr.srvid, log_handler, NULL);
2505 DEBUG(DEBUG_ERR,("Listen for response on %d\n", (int)log_addr.srvid));
2507 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_GET_LOG,
2508 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2509 if (ret != 0 || res != 0) {
2510 DEBUG(DEBUG_ERR,("Failed to get logs - %s\n", errmsg));
2511 talloc_free(tmp_ctx);
2516 tv = timeval_current();
2517 /* this loop will terminate when we have received the reply */
2518 while (timeval_elapsed(&tv) < 3.0) {
2519 event_loop_once(ctdb->ev);
2522 DEBUG(DEBUG_INFO,("Timed out waiting for log data.\n"));
2524 talloc_free(tmp_ctx);
2529 clear the in memory log area
2531 static int control_clearlog(struct ctdb_context *ctdb, int argc, const char **argv)
2536 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2538 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_CLEAR_LOG,
2539 0, tdb_null, tmp_ctx, NULL, &res, NULL, &errmsg);
2540 if (ret != 0 || res != 0) {
2541 DEBUG(DEBUG_ERR,("Failed to clear logs\n"));
2542 talloc_free(tmp_ctx);
2546 talloc_free(tmp_ctx);
2553 display a list of the databases on a remote ctdb
2555 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2558 struct ctdb_dbid_map *dbmap=NULL;
2560 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2562 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2566 if(options.machinereadable){
2567 printf(":ID:Name:Path:Persistent:Unhealthy:\n");
2568 for(i=0;i<dbmap->num;i++){
2574 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn,
2575 dbmap->dbs[i].dbid, ctdb, &path);
2576 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
2577 dbmap->dbs[i].dbid, ctdb, &name);
2578 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
2579 dbmap->dbs[i].dbid, ctdb, &health);
2580 persistent = dbmap->dbs[i].persistent;
2581 printf(":0x%08X:%s:%s:%d:%d:\n",
2582 dbmap->dbs[i].dbid, name, path,
2583 !!(persistent), !!(health));
2588 printf("Number of databases:%d\n", dbmap->num);
2589 for(i=0;i<dbmap->num;i++){
2595 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2596 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2597 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
2598 persistent = dbmap->dbs[i].persistent;
2599 printf("dbid:0x%08x name:%s path:%s%s%s\n",
2600 dbmap->dbs[i].dbid, name, path,
2601 persistent?" PERSISTENT":"",
2602 health?" UNHEALTHY":"");
2609 display the status of a database on a remote ctdb
2611 static int control_getdbstatus(struct ctdb_context *ctdb, int argc, const char **argv)
2614 struct ctdb_dbid_map *dbmap=NULL;
2615 const char *db_name;
2623 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2625 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2629 for(i=0;i<dbmap->num;i++){
2635 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2636 if (strcmp(name, db_name) != 0) {
2640 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2641 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
2642 persistent = dbmap->dbs[i].persistent;
2643 printf("dbid: 0x%08x\nname: %s\npath: %s\nPERSISTENT: %s\nHEALTH: %s\n",
2644 dbmap->dbs[i].dbid, name, path,
2645 persistent?"yes":"no",
2646 health?health:"OK");
2650 DEBUG(DEBUG_ERR, ("db %s doesn't exist on node %u\n", db_name, options.pnn));
2655 check if the local node is recmaster or not
2656 it will return 1 if this node is the recmaster and 0 if it is not
2657 or if the local ctdb daemon could not be contacted
2659 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2661 uint32_t mypnn, recmaster;
2664 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2666 printf("Failed to get pnn of node\n");
2670 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2672 printf("Failed to get the recmaster\n");
2676 if (recmaster != mypnn) {
2677 printf("this node is not the recmaster\n");
2681 printf("this node is the recmaster\n");
2688 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2691 struct timeval tv = timeval_current();
2692 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2694 printf("Unable to get ping response from node %u\n", options.pnn);
2697 printf("response from %u time=%.6f sec (%d clients)\n",
2698 options.pnn, timeval_elapsed(&tv), ret);
2707 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2718 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2720 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2724 printf("%-19s = %u\n", name, value);
2731 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2742 value = strtoul(argv[1], NULL, 0);
2744 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2746 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2755 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2761 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2763 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2767 for (i=0;i<count;i++) {
2768 control_getvar(ctdb, 1, &list[i]);
2777 display debug level on a node
2779 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2784 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2786 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2789 if (options.machinereadable){
2790 printf(":Name:Level:\n");
2791 printf(":%s:%d:\n",get_debug_by_level(level),level);
2793 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2800 display reclock file of a node
2802 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2805 const char *reclock;
2807 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2809 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2812 if (options.machinereadable){
2813 if (reclock != NULL) {
2814 printf("%s", reclock);
2817 if (reclock == NULL) {
2818 printf("No reclock file used.\n");
2820 printf("Reclock file:%s\n", reclock);
2828 set the reclock file of a node
2830 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2833 const char *reclock;
2837 } else if (argc == 1) {
2843 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2845 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2852 set the natgw state on/off
2854 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2857 uint32_t natgwstate;
2863 if (!strcmp(argv[0], "on")) {
2865 } else if (!strcmp(argv[0], "off")) {
2871 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2873 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2881 set the lmaster role on/off
2883 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2886 uint32_t lmasterrole;
2892 if (!strcmp(argv[0], "on")) {
2894 } else if (!strcmp(argv[0], "off")) {
2900 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2902 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2910 set the recmaster role on/off
2912 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2915 uint32_t recmasterrole;
2921 if (!strcmp(argv[0], "on")) {
2923 } else if (!strcmp(argv[0], "off")) {
2929 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2931 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2939 set debug level on a node or all nodes
2941 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2947 printf("You must specify the debug level. Valid levels are:\n");
2948 for (i=0; debug_levels[i].description != NULL; i++) {
2949 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2955 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2956 level = get_debug_by_desc(argv[0]);
2958 level = strtol(argv[0], NULL, 0);
2961 for (i=0; debug_levels[i].description != NULL; i++) {
2962 if (level == debug_levels[i].level) {
2966 if (debug_levels[i].description == NULL) {
2967 printf("Invalid debug level, must be one of\n");
2968 for (i=0; debug_levels[i].description != NULL; i++) {
2969 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2974 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2976 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2985 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2991 priority = strtol(argv[0], NULL, 0);
2995 DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
2997 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2999 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
3007 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
3013 priority = strtol(argv[0], NULL, 0);
3017 DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
3019 ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
3021 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
3028 attach to a database
3030 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
3032 const char *db_name;
3033 struct ctdb_db_context *ctdb_db;
3040 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
3041 if (ctdb_db == NULL) {
3042 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
3052 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
3054 struct ctdb_db_priority db_prio;
3061 db_prio.db_id = strtoul(argv[0], NULL, 0);
3062 db_prio.priority = strtoul(argv[1], NULL, 0);
3064 ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
3066 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
3076 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
3078 uint32_t db_id, priority;
3085 db_id = strtoul(argv[0], NULL, 0);
3087 ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
3089 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
3093 DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
3099 run an eventscript on a node
3101 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
3107 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3110 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3114 data.dptr = (unsigned char *)discard_const(argv[0]);
3115 data.dsize = strlen((char *)data.dptr) + 1;
3117 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
3119 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
3120 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
3121 if (ret != 0 || res != 0) {
3122 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
3123 talloc_free(tmp_ctx);
3126 talloc_free(tmp_ctx);
3130 #define DB_VERSION 1
3131 #define MAX_DB_NAME 64
3132 struct db_file_header {
3133 unsigned long version;
3135 unsigned long persistent;
3137 const char name[MAX_DB_NAME];
3140 struct backup_data {
3141 struct ctdb_marshall_buffer *records;
3144 bool traverse_error;
3147 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
3149 struct backup_data *bd = talloc_get_type(private, struct backup_data);
3150 struct ctdb_rec_data *rec;
3152 /* add the record */
3153 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
3155 bd->traverse_error = true;
3156 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
3159 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
3160 if (bd->records == NULL) {
3161 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
3162 bd->traverse_error = true;
3165 bd->records->count++;
3166 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
3167 bd->len += rec->length;
3175 * backup a database to a file
3177 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
3180 struct ctdb_dbid_map *dbmap=NULL;
3181 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3182 struct db_file_header dbhdr;
3183 struct ctdb_db_context *ctdb_db;
3184 struct backup_data *bd;
3187 const char *reason = NULL;
3190 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3194 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
3196 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
3200 for(i=0;i<dbmap->num;i++){
3203 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
3204 if(!strcmp(argv[0], name)){
3205 talloc_free(discard_const(name));
3208 talloc_free(discard_const(name));
3210 if (i == dbmap->num) {
3211 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
3212 talloc_free(tmp_ctx);
3216 ret = ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
3217 dbmap->dbs[i].dbid, tmp_ctx, &reason);
3219 DEBUG(DEBUG_ERR,("Unable to get dbhealth for database '%s'\n",
3221 talloc_free(tmp_ctx);
3225 uint32_t allow_unhealthy = 0;
3227 ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn,
3228 "AllowUnhealthyDBRead",
3231 if (allow_unhealthy != 1) {
3232 DEBUG(DEBUG_ERR,("database '%s' is unhealthy: %s\n",
3235 DEBUG(DEBUG_ERR,("disallow backup : tunnable AllowUnhealthyDBRead = %u\n",
3237 talloc_free(tmp_ctx);
3241 DEBUG(DEBUG_WARNING,("WARNING database '%s' is unhealthy - see 'ctdb getdbstatus %s'\n",
3243 DEBUG(DEBUG_WARNING,("WARNING! allow backup of unhealthy database: "
3244 "tunnable AllowUnhealthyDBRead = %u\n",
3248 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3249 if (ctdb_db == NULL) {
3250 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
3251 talloc_free(tmp_ctx);
3256 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3258 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
3259 talloc_free(tmp_ctx);
3264 bd = talloc_zero(tmp_ctx, struct backup_data);
3266 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
3267 talloc_free(tmp_ctx);
3271 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
3272 if (bd->records == NULL) {
3273 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
3274 talloc_free(tmp_ctx);
3278 bd->len = offsetof(struct ctdb_marshall_buffer, data);
3279 bd->records->db_id = ctdb_db->db_id;
3280 /* traverse the database collecting all records */
3281 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
3282 bd->traverse_error) {
3283 DEBUG(DEBUG_ERR,("Traverse error\n"));
3284 talloc_free(tmp_ctx);
3288 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3291 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
3293 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
3294 talloc_free(tmp_ctx);
3298 dbhdr.version = DB_VERSION;
3299 dbhdr.timestamp = time(NULL);
3300 dbhdr.persistent = dbmap->dbs[i].persistent;
3301 dbhdr.size = bd->len;
3302 if (strlen(argv[0]) >= MAX_DB_NAME) {
3303 DEBUG(DEBUG_ERR,("Too long dbname\n"));
3306 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
3307 ret = write(fh, &dbhdr, sizeof(dbhdr));
3309 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3312 ret = write(fh, bd->records, bd->len);
3314 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3323 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3326 talloc_free(tmp_ctx);
3331 * restore a database from a file
3333 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3336 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3339 struct db_file_header dbhdr;
3340 struct ctdb_db_context *ctdb_db;
3341 struct ctdb_node_map *nodemap=NULL;
3342 struct ctdb_vnn_map *vnnmap=NULL;
3344 struct ctdb_control_wipe_database w;
3346 uint32_t generation;
3351 if (argc < 1 || argc > 2) {
3352 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3356 fh = open(argv[0], O_RDONLY);
3358 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3359 talloc_free(tmp_ctx);
3363 read(fh, &dbhdr, sizeof(dbhdr));
3364 if (dbhdr.version != DB_VERSION) {
3365 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3366 talloc_free(tmp_ctx);
3370 dbname = dbhdr.name;
3375 outdata.dsize = dbhdr.size;
3376 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3377 if (outdata.dptr == NULL) {
3378 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3380 talloc_free(tmp_ctx);
3383 read(fh, outdata.dptr, outdata.dsize);
3386 tm = localtime(&dbhdr.timestamp);
3387 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3388 printf("Restoring database '%s' from backup @ %s\n",
3392 ctdb_db = ctdb_attach(ctdb, dbname, dbhdr.persistent, 0);
3393 if (ctdb_db == NULL) {
3394 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbname));
3395 talloc_free(tmp_ctx);
3399 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3401 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3402 talloc_free(tmp_ctx);
3407 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3409 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3410 talloc_free(tmp_ctx);
3414 /* freeze all nodes */
3415 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3416 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3417 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3423 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3424 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3425 talloc_free(tmp_ctx);
3430 generation = vnnmap->generation;
3431 data.dptr = (void *)&generation;
3432 data.dsize = sizeof(generation);
3434 /* start a cluster wide transaction */
3435 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3436 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3438 TIMELIMIT(), false, data,
3441 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3446 w.db_id = ctdb_db->db_id;
3447 w.transaction_id = generation;
3449 data.dptr = (void *)&w;
3450 data.dsize = sizeof(w);
3452 /* wipe all the remote databases. */
3453 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3454 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3456 TIMELIMIT(), false, data,
3459 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3460 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3461 talloc_free(tmp_ctx);
3465 /* push the database */
3466 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3467 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3469 TIMELIMIT(), false, outdata,
3472 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3473 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3474 talloc_free(tmp_ctx);
3478 data.dptr = (void *)&ctdb_db->db_id;
3479 data.dsize = sizeof(ctdb_db->db_id);
3481 /* mark the database as healthy */
3482 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3483 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_DB_SET_HEALTHY,
3485 TIMELIMIT(), false, data,
3488 DEBUG(DEBUG_ERR, ("Failed to mark database as healthy.\n"));
3489 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3490 talloc_free(tmp_ctx);
3494 data.dptr = (void *)&generation;
3495 data.dsize = sizeof(generation);
3497 /* commit all the changes */
3498 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3500 TIMELIMIT(), false, data,
3503 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3504 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3505 talloc_free(tmp_ctx);
3510 /* thaw all nodes */
3511 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3512 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3518 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3519 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3520 talloc_free(tmp_ctx);
3525 talloc_free(tmp_ctx);
3530 * dump a database backup from a file
3532 static int control_dumpdbbackup(struct ctdb_context *ctdb, int argc, const char **argv)
3534 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3536 struct db_file_header dbhdr;
3540 struct ctdb_rec_data *rec = NULL;
3541 struct ctdb_marshall_buffer *m;
3544 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3548 fh = open(argv[0], O_RDONLY);
3550 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3551 talloc_free(tmp_ctx);
3555 read(fh, &dbhdr, sizeof(dbhdr));
3556 if (dbhdr.version != DB_VERSION) {
3557 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3558 talloc_free(tmp_ctx);
3562 outdata.dsize = dbhdr.size;
3563 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3564 if (outdata.dptr == NULL) {
3565 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3567 talloc_free(tmp_ctx);
3570 read(fh, outdata.dptr, outdata.dsize);
3572 m = (struct ctdb_marshall_buffer *)outdata.dptr;
3574 tm = localtime(&dbhdr.timestamp);
3575 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3576 printf("Backup of database name:'%s' dbid:0x%x08x from @ %s\n",
3577 dbhdr.name, m->db_id, tbuf);
3579 for (i=0; i < m->count; i++) {
3583 /* we do not want the header splitted, so we pass NULL*/
3584 rec = ctdb_marshall_loop_next(m, rec, &reqid,
3587 ctdb_dumpdb_record(ctdb, key, data, stdout);
3590 printf("Dumped %d records\n", i);
3591 talloc_free(tmp_ctx);
3596 * wipe a database from a file
3598 static int control_wipedb(struct ctdb_context *ctdb, int argc,
3602 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3604 struct ctdb_db_context *ctdb_db;
3605 struct ctdb_node_map *nodemap = NULL;
3606 struct ctdb_vnn_map *vnnmap = NULL;
3608 struct ctdb_control_wipe_database w;
3610 uint32_t generation;
3611 struct ctdb_dbid_map *dbmap = NULL;
3614 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3618 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3621 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n",
3626 for(i=0;i<dbmap->num;i++){
3629 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
3630 dbmap->dbs[i].dbid, tmp_ctx, &name);
3631 if(!strcmp(argv[0], name)){
3632 talloc_free(discard_const(name));
3635 talloc_free(discard_const(name));
3637 if (i == dbmap->num) {
3638 DEBUG(DEBUG_ERR, ("No database with name '%s' found\n",
3640 talloc_free(tmp_ctx);
3644 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3645 if (ctdb_db == NULL) {
3646 DEBUG(DEBUG_ERR, ("Unable to attach to database '%s'\n",
3648 talloc_free(tmp_ctx);
3652 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb,
3655 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n",
3657 talloc_free(tmp_ctx);
3661 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3664 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n",
3666 talloc_free(tmp_ctx);
3670 /* freeze all nodes */
3671 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3672 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3673 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3680 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3681 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn,
3682 CTDB_RECOVERY_ACTIVE);
3683 talloc_free(tmp_ctx);
3688 generation = vnnmap->generation;
3689 data.dptr = (void *)&generation;
3690 data.dsize = sizeof(generation);
3692 /* start a cluster wide transaction */
3693 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3694 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3696 TIMELIMIT(), false, data,
3700 DEBUG(DEBUG_ERR, ("Unable to start cluster wide "
3701 "transactions.\n"));
3705 w.db_id = ctdb_db->db_id;
3706 w.transaction_id = generation;
3708 data.dptr = (void *)&w;
3709 data.dsize = sizeof(w);
3711 /* wipe all the remote databases. */
3712 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3713 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3715 TIMELIMIT(), false, data,
3718 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3719 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3720 talloc_free(tmp_ctx);
3724 data.dptr = (void *)&ctdb_db->db_id;
3725 data.dsize = sizeof(ctdb_db->db_id);
3727 /* mark the database as healthy */
3728 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3729 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_DB_SET_HEALTHY,
3731 TIMELIMIT(), false, data,
3734 DEBUG(DEBUG_ERR, ("Failed to mark database as healthy.\n"));
3735 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3736 talloc_free(tmp_ctx);
3740 data.dptr = (void *)&generation;
3741 data.dsize = sizeof(generation);
3743 /* commit all the changes */
3744 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3746 TIMELIMIT(), false, data,
3749 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3750 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3751 talloc_free(tmp_ctx);
3755 /* thaw all nodes */
3756 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3757 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3763 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3764 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3765 talloc_free(tmp_ctx);
3769 talloc_free(tmp_ctx);
3774 * set flags of a node in the nodemap
3776 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3783 struct ctdb_node_flag_change c;
3790 if (sscanf(argv[0], "%d", &node) != 1) {
3791 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3795 if (sscanf(argv[1], "0x%x", &flags) != 1) {
3796 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3803 c.new_flags = flags;
3805 data.dsize = sizeof(c);
3806 data.dptr = (unsigned char *)&c;
3808 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
3809 data, NULL, NULL, &status, NULL, NULL);
3810 if (ret != 0 || status != 0) {
3811 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3820 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3826 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3827 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3828 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3829 if (ret != 0 || res != 0) {
3830 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3831 talloc_free(tmp_ctx);
3834 write(1, data.dptr, data.dsize);
3835 talloc_free(tmp_ctx);
3840 handler for memory dumps
3842 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
3843 TDB_DATA data, void *private_data)
3845 write(1, data.dptr, data.dsize);
3850 dump memory usage on the recovery daemon
3852 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3856 struct rd_memdump_reply rd;
3858 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3860 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3863 rd.srvid = getpid();
3865 /* register a message port for receiveing the reply so that we
3866 can receive the reply
3868 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3871 data.dptr = (uint8_t *)&rd;
3872 data.dsize = sizeof(rd);
3874 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3876 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3880 /* this loop will terminate when we have received the reply */
3882 event_loop_once(ctdb->ev);
3889 list all nodes in the cluster
3890 if the daemon is running, we read the data from the daemon.
3891 if the daemon is not running we parse the nodes file directly
3893 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3896 struct ctdb_node_map *nodemap=NULL;
3899 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3901 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3905 for(i=0;i<nodemap->num;i++){
3906 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3909 if (options.machinereadable){
3910 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3912 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3916 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3917 struct pnn_node *pnn_nodes;
3918 struct pnn_node *pnn_node;
3920 pnn_nodes = read_nodes_file(mem_ctx);
3921 if (pnn_nodes == NULL) {
3922 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3923 talloc_free(mem_ctx);
3927 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3928 ctdb_sock_addr addr;
3930 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3931 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3932 talloc_free(mem_ctx);
3936 if (options.machinereadable){
3937 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3939 printf("%s\n", pnn_node->addr);
3942 talloc_free(mem_ctx);
3949 reload the nodes file on the local node
3951 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3955 struct ctdb_node_map *nodemap=NULL;
3957 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3959 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3963 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3965 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3969 /* reload the nodes file on all remote nodes */
3970 for (i=0;i<nodemap->num;i++) {
3971 if (nodemap->nodes[i].pnn == mypnn) {
3974 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3975 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3976 nodemap->nodes[i].pnn);
3978 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3982 /* reload the nodes file on the local node */
3983 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3984 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3986 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3989 /* initiate a recovery */
3990 control_recover(ctdb, argc, argv);
3996 static const struct {
3998 int (*fn)(struct ctdb_context *, int, const char **);
4000 bool without_daemon; /* can be run without daemon running ? */
4003 } ctdb_commands[] = {
4005 { "version", control_version, true, false, "show version of ctdb" },
4007 { "status", control_status, true, false, "show node status" },
4008 { "uptime", control_uptime, true, false, "show node uptime" },
4009 { "ping", control_ping, true, false, "ping all nodes" },
4010 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
4011 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
4012 { "listvars", control_listvars, true, false, "list tunable variables"},
4013 { "statistics", control_statistics, false, false, "show statistics" },
4014 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
4015 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
4016 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
4017 { "getdbmap", control_getdbmap, true, false, "show the database map" },
4018 { "getdbstatus", control_getdbstatus, true, false, "show the status of a database", "<dbname>" },
4019 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
4020 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
4021 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
4022 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
4023 { "lvs", control_lvs, true, false, "show lvs configuration" },
4024 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
4025 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
4026 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
4027 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
4028 { "getdebug", control_getdebug, true, false, "get debug level" },
4029 { "getlog", control_getlog, true, false, "get the log data from the in memory ringbuffer", "<level>" },
4030 { "clearlog", control_clearlog, true, false, "clear the log data from the in memory ringbuffer" },
4031 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
4032 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
4033 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
4034 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
4035 { "disable", control_disable, true, false, "disable a nodes public IP" },
4036 { "enable", control_enable, true, false, "enable a nodes public IP" },
4037 { "stop", control_stop, true, false, "stop a node" },
4038 { "continue", control_continue, true, false, "re-start a stopped node" },
4039 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
4040 { "unban", control_unban, true, false, "unban a node" },
4041 { "showban", control_showban, true, false, "show ban information"},
4042 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
4043 { "recover", control_recover, true, false, "force recovery" },
4044 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
4045 { "freeze", control_freeze, true, false, "freeze databases", "[priority:1-3]" },
4046 { "thaw", control_thaw, true, false, "thaw databases", "[priority:1-3]" },
4047 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
4048 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
4049 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
4050 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
4051 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
4053 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
4054 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
4055 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
4056 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
4057 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
4058 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
4059 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
4060 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
4061 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
4062 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
4063 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
4064 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
4065 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
4066 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file> [dbname]"},
4067 { "dumpdbbackup", control_dumpdbbackup, false, true, "dump database backup from a file.", "<file>"},
4068 { "wipedb", control_wipedb, false, false, "wipe the contents of a database.", "<dbname>"},
4069 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
4070 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
4071 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts (or all scripts)", "[all]"},
4072 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
4073 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
4074 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
4075 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
4076 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
4077 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
4078 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
4079 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
4080 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
4081 { "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
4082 { "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
4088 static void usage(void)
4092 "Usage: ctdb [options] <control>\n" \
4094 " -n <node> choose node number, or 'all' (defaults to local node)\n"
4095 " -Y generate machinereadable output\n"
4096 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
4097 printf("Controls:\n");
4098 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
4099 printf(" %-15s %-27s %s\n",
4100 ctdb_commands[i].name,
4101 ctdb_commands[i].args?ctdb_commands[i].args:"",
4102 ctdb_commands[i].msg);
4108 static void ctdb_alarm(int sig)
4110 printf("Maximum runtime exceeded - exiting\n");
4117 int main(int argc, const char *argv[])
4119 struct ctdb_context *ctdb;
4120 char *nodestring = NULL;
4121 struct poptOption popt_options[] = {
4124 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
4125 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
4126 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
4127 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
4131 const char **extra_argv;
4135 struct event_context *ev;
4136 const char *control;
4140 /* set some defaults */
4141 options.maxruntime = 0;
4142 options.timelimit = 3;
4143 options.pnn = CTDB_CURRENT_NODE;
4145 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
4147 while ((opt = poptGetNextOpt(pc)) != -1) {
4150 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
4151 poptBadOption(pc, 0), poptStrerror(opt)));
4156 /* setup the remaining options for the main program to use */
4157 extra_argv = poptGetArgs(pc);
4160 while (extra_argv[extra_argc]) extra_argc++;
4163 if (extra_argc < 1) {
4167 if (options.maxruntime == 0) {
4168 const char *ctdb_timeout;
4169 ctdb_timeout = getenv("CTDB_TIMEOUT");
4170 if (ctdb_timeout != NULL) {
4171 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
4173 /* default timeout is 120 seconds */
4174 options.maxruntime = 120;
4178 signal(SIGALRM, ctdb_alarm);
4179 alarm(options.maxruntime);
4181 /* setup the node number to contact */
4182 if (nodestring != NULL) {
4183 if (strcmp(nodestring, "all") == 0) {
4184 options.pnn = CTDB_BROADCAST_ALL;
4186 options.pnn = strtoul(nodestring, NULL, 0);
4190 control = extra_argv[0];
4192 ev = event_context_init(NULL);
4194 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
4195 if (strcmp(control, ctdb_commands[i].name) == 0) {
4198 if (ctdb_commands[i].without_daemon == true) {
4202 /* initialise ctdb */
4203 ctdb = ctdb_cmdline_client(ev);
4205 if (ctdb_commands[i].without_daemon == false) {
4207 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
4211 /* verify the node exists */
4214 if (options.pnn == CTDB_CURRENT_NODE) {
4216 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
4224 if (ctdb_commands[i].auto_all &&
4225 options.pnn == CTDB_BROADCAST_ALL) {
4230 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
4231 CTDB_NO_MEMORY(ctdb, nodes);
4233 for (j=0;j<num_nodes;j++) {
4234 options.pnn = nodes[j];
4235 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4239 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4245 if (i == ARRAY_SIZE(ctdb_commands)) {
4246 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));