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)
48 #define LONGTIMELIMIT() timeval_current_ofs(options.timelimit*10, 0)
51 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
54 #define XSTR(x) STR(x)
55 printf("CTDB version: %s\n", XSTR(CTDB_VERS));
62 verify that a node exists and is reachable
64 static void verify_node(struct ctdb_context *ctdb)
67 struct ctdb_node_map *nodemap=NULL;
69 if (options.pnn == CTDB_CURRENT_NODE) {
72 if (options.pnn == CTDB_BROADCAST_ALL) {
76 /* verify the node exists */
77 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
78 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
81 if (options.pnn >= nodemap->num) {
82 DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
85 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DELETED) {
86 DEBUG(DEBUG_ERR, ("Node %u is DELETED\n", options.pnn));
89 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
90 DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
94 /* verify we can access the node */
95 ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
97 DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
103 check if a database exists
105 static int db_exists(struct ctdb_context *ctdb, const char *db_name)
108 struct ctdb_dbid_map *dbmap=NULL;
110 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
112 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
116 for(i=0;i<dbmap->num;i++){
119 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
120 if (!strcmp(name, db_name)) {
129 see if a process exists
131 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
139 if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
140 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
144 ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
146 printf("%u:%u exists\n", pnn, pid);
148 printf("%u:%u does not exist\n", pnn, pid);
154 display statistics structure
156 static void show_statistics(struct ctdb_statistics *s)
158 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
160 const char *prefix=NULL;
166 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
167 STATISTICS_FIELD(num_clients),
168 STATISTICS_FIELD(frozen),
169 STATISTICS_FIELD(recovering),
170 STATISTICS_FIELD(client_packets_sent),
171 STATISTICS_FIELD(client_packets_recv),
172 STATISTICS_FIELD(node_packets_sent),
173 STATISTICS_FIELD(node_packets_recv),
174 STATISTICS_FIELD(keepalive_packets_sent),
175 STATISTICS_FIELD(keepalive_packets_recv),
176 STATISTICS_FIELD(node.req_call),
177 STATISTICS_FIELD(node.reply_call),
178 STATISTICS_FIELD(node.req_dmaster),
179 STATISTICS_FIELD(node.reply_dmaster),
180 STATISTICS_FIELD(node.reply_error),
181 STATISTICS_FIELD(node.req_message),
182 STATISTICS_FIELD(node.req_control),
183 STATISTICS_FIELD(node.reply_control),
184 STATISTICS_FIELD(client.req_call),
185 STATISTICS_FIELD(client.req_message),
186 STATISTICS_FIELD(client.req_control),
187 STATISTICS_FIELD(timeouts.call),
188 STATISTICS_FIELD(timeouts.control),
189 STATISTICS_FIELD(timeouts.traverse),
190 STATISTICS_FIELD(total_calls),
191 STATISTICS_FIELD(pending_calls),
192 STATISTICS_FIELD(lockwait_calls),
193 STATISTICS_FIELD(pending_lockwait_calls),
194 STATISTICS_FIELD(childwrite_calls),
195 STATISTICS_FIELD(pending_childwrite_calls),
196 STATISTICS_FIELD(memory_used),
197 STATISTICS_FIELD(max_hop_count),
199 printf("CTDB version %u\n", CTDB_VERSION);
200 for (i=0;i<ARRAY_SIZE(fields);i++) {
201 if (strchr(fields[i].name, '.')) {
202 preflen = strcspn(fields[i].name, ".")+1;
203 if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
204 prefix = fields[i].name;
205 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
210 printf(" %*s%-22s%*s%10u\n",
212 fields[i].name+preflen,
214 *(uint32_t *)(fields[i].offset+(uint8_t *)s));
216 printf(" %-30s %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
217 printf(" %-30s %.6f sec\n", "max_reclock_recd", s->reclock.recd);
219 printf(" %-30s %.6f sec\n", "max_call_latency", s->max_call_latency);
220 printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
221 printf(" %-30s %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
222 talloc_free(tmp_ctx);
226 display remote ctdb statistics combined from all nodes
228 static int control_statistics_all(struct ctdb_context *ctdb)
231 struct ctdb_statistics statistics;
235 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
236 CTDB_NO_MEMORY(ctdb, nodes);
238 ZERO_STRUCT(statistics);
240 for (i=0;i<num_nodes;i++) {
241 struct ctdb_statistics s1;
243 uint32_t *v1 = (uint32_t *)&s1;
244 uint32_t *v2 = (uint32_t *)&statistics;
246 offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
247 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
249 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
252 for (j=0;j<num_ints;j++) {
255 statistics.max_hop_count =
256 MAX(statistics.max_hop_count, s1.max_hop_count);
257 statistics.max_call_latency =
258 MAX(statistics.max_call_latency, s1.max_call_latency);
259 statistics.max_lockwait_latency =
260 MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
263 printf("Gathered statistics for %u nodes\n", num_nodes);
264 show_statistics(&statistics);
269 display remote ctdb statistics
271 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
274 struct ctdb_statistics statistics;
276 if (options.pnn == CTDB_BROADCAST_ALL) {
277 return control_statistics_all(ctdb);
280 ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
282 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
285 show_statistics(&statistics);
291 reset remote ctdb statistics
293 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
297 ret = ctdb_statistics_reset(ctdb, options.pnn);
299 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
307 display uptime of remote node
309 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
312 struct ctdb_uptime *uptime = NULL;
313 int tmp, days, hours, minutes, seconds;
315 ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
317 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
321 if (options.machinereadable){
322 printf(":Current Node Time:Ctdb Start Time:Last Recovery/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:Inactive:PartiallyOnline:\n");
507 for(i=0;i<nodemap->num;i++){
508 int partially_online = 0;
511 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
514 if (nodemap->nodes[i].flags == 0) {
515 struct ctdb_control_get_ifaces *ifaces;
517 ret = ctdb_ctrl_get_ifaces(ctdb, TIMELIMIT(),
518 nodemap->nodes[i].pnn,
521 for (j=0; j < ifaces->num; j++) {
522 if (ifaces->ifaces[j].link_state != 0) {
525 partially_online = 1;
531 printf(":%d:%s:%d:%d:%d:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
532 ctdb_addr_to_str(&nodemap->nodes[i].addr),
533 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
534 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
535 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
536 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
537 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED),
538 !!(nodemap->nodes[i].flags&NODE_FLAGS_INACTIVE),
544 printf("Number of nodes:%d\n", nodemap->num);
545 for(i=0;i<nodemap->num;i++){
546 static const struct {
550 { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" },
551 { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" },
552 { NODE_FLAGS_BANNED, "BANNED" },
553 { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" },
554 { NODE_FLAGS_DELETED, "DELETED" },
555 { NODE_FLAGS_STOPPED, "STOPPED" },
556 { NODE_FLAGS_INACTIVE, "INACTIVE" },
558 char *flags_str = NULL;
561 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
564 if (nodemap->nodes[i].flags == 0) {
565 struct ctdb_control_get_ifaces *ifaces;
567 ret = ctdb_ctrl_get_ifaces(ctdb, TIMELIMIT(),
568 nodemap->nodes[i].pnn,
571 for (j=0; j < ifaces->num; j++) {
572 if (ifaces->ifaces[j].link_state != 0) {
575 flags_str = talloc_strdup(ctdb, "PARTIALLYONLINE");
581 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
582 if (nodemap->nodes[i].flags & flag_names[j].flag) {
583 if (flags_str == NULL) {
584 flags_str = talloc_strdup(ctdb, flag_names[j].name);
586 flags_str = talloc_asprintf_append(flags_str, "|%s",
589 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
592 if (flags_str == NULL) {
593 flags_str = talloc_strdup(ctdb, "OK");
594 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
596 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
597 ctdb_addr_to_str(&nodemap->nodes[i].addr),
599 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
600 talloc_free(flags_str);
603 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
605 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
608 if (vnnmap->generation == INVALID_GENERATION) {
609 printf("Generation:INVALID\n");
611 printf("Generation:%d\n",vnnmap->generation);
613 printf("Size:%d\n",vnnmap->size);
614 for(i=0;i<vnnmap->size;i++){
615 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
618 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
620 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
623 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
625 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
627 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
630 printf("Recovery master:%d\n",recmaster);
637 struct natgw_node *next;
642 display the list of nodes belonging to this natgw configuration
644 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
647 const char *natgw_list;
650 struct natgw_node *natgw_nodes = NULL;
651 struct natgw_node *natgw_node;
652 struct ctdb_node_map *nodemap=NULL;
655 /* read the natgw nodes file into a linked list */
656 natgw_list = getenv("NATGW_NODES");
657 if (natgw_list == NULL) {
658 natgw_list = "/etc/ctdb/natgw_nodes";
660 lines = file_lines_load(natgw_list, &nlines, ctdb);
662 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
665 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
668 for (i=0;i<nlines;i++) {
672 /* strip leading spaces */
673 while((*node == ' ') || (*node == '\t')) {
679 if (strcmp(node, "") == 0) {
682 natgw_node = talloc(ctdb, struct natgw_node);
683 natgw_node->addr = talloc_strdup(natgw_node, node);
684 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
685 natgw_node->next = natgw_nodes;
686 natgw_nodes = natgw_node;
689 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
691 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
696 while(i<nodemap->num) {
697 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
698 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
703 /* this node was not in the natgw so we just remove it from
706 if ((natgw_node == NULL)
707 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
710 for (j=i+1; j<nodemap->num; j++) {
711 nodemap->nodes[j-1] = nodemap->nodes[j];
720 /* pick a node to be natgwmaster
721 * we dont allow STOPPED, DELETED, BANNED or UNHEALTHY nodes to become the natgwmaster
723 for(i=0;i<nodemap->num;i++){
724 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_UNHEALTHY))) {
725 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
729 /* we couldnt find any healthy node, try unhealthy ones */
730 if (i == nodemap->num) {
731 for(i=0;i<nodemap->num;i++){
732 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
733 printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
738 /* unless all nodes are STOPPED, when we pick one anyway */
739 if (i == nodemap->num) {
740 for(i=0;i<nodemap->num;i++){
741 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
742 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
746 /* or if we still can not find any */
747 if (i == nodemap->num) {
748 printf("-1 0.0.0.0\n");
752 /* print the pruned list of nodes belonging to this natgw list */
753 for(i=0;i<nodemap->num;i++){
754 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
757 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
758 ctdb_addr_to_str(&nodemap->nodes[i].addr),
759 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
760 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
761 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
762 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
763 !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
770 display the status of the scripts for monitoring (or other events)
772 static int control_one_scriptstatus(struct ctdb_context *ctdb,
773 enum ctdb_eventscript_call type)
775 struct ctdb_scripts_wire *script_status;
778 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, type, &script_status);
780 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
784 if (script_status == NULL) {
785 if (!options.machinereadable) {
786 printf("%s cycle never run\n",
787 ctdb_eventscript_call_names[type]);
792 if (!options.machinereadable) {
793 printf("%d scripts were executed last %s cycle\n",
794 script_status->num_scripts,
795 ctdb_eventscript_call_names[type]);
797 for (i=0; i<script_status->num_scripts; i++) {
798 const char *status = NULL;
800 switch (script_status->scripts[i].status) {
811 if (script_status->scripts[i].status > 0)
815 if (options.machinereadable) {
816 printf("%s:%s:%i:%s:%lu.%06lu:%lu.%06lu:%s:\n",
817 ctdb_eventscript_call_names[type],
818 script_status->scripts[i].name,
819 script_status->scripts[i].status,
821 (long)script_status->scripts[i].start.tv_sec,
822 (long)script_status->scripts[i].start.tv_usec,
823 (long)script_status->scripts[i].finished.tv_sec,
824 (long)script_status->scripts[i].finished.tv_usec,
825 script_status->scripts[i].output);
829 printf("%-20s Status:%s ",
830 script_status->scripts[i].name, status);
832 /* Some other error, eg from stat. */
833 printf("%-20s Status:CANNOT RUN (%s)",
834 script_status->scripts[i].name,
835 strerror(-script_status->scripts[i].status));
837 if (script_status->scripts[i].status >= 0) {
838 printf("Duration:%.3lf ",
839 timeval_delta(&script_status->scripts[i].finished,
840 &script_status->scripts[i].start));
842 if (script_status->scripts[i].status != -ENOEXEC) {
844 ctime(&script_status->scripts[i].start.tv_sec));
845 if (script_status->scripts[i].status != 0) {
846 printf(" OUTPUT:%s\n",
847 script_status->scripts[i].output);
857 static int control_scriptstatus(struct ctdb_context *ctdb,
858 int argc, const char **argv)
861 enum ctdb_eventscript_call type, min, max;
865 DEBUG(DEBUG_ERR, ("Unknown arguments to scriptstatus\n"));
870 arg = ctdb_eventscript_call_names[CTDB_EVENT_MONITOR];
874 for (type = 0; type < CTDB_EVENT_MAX; type++) {
875 if (strcmp(arg, ctdb_eventscript_call_names[type]) == 0) {
881 if (type == CTDB_EVENT_MAX) {
882 if (strcmp(arg, "all") == 0) {
884 max = CTDB_EVENT_MAX;
886 DEBUG(DEBUG_ERR, ("Unknown event type %s\n", argv[0]));
891 if (options.machinereadable) {
892 printf(":Type:Name:Code:Status:Start:End:Error Output...:\n");
895 for (type = min; type < max; type++) {
896 ret = control_one_scriptstatus(ctdb, type);
906 enable an eventscript
908 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
916 ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
918 DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
926 disable an eventscript
928 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
936 ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
938 DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
946 display the pnn of the recovery master
948 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
953 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
955 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
958 printf("%d\n",recmaster);
964 get a list of all tickles for this pnn
966 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
968 struct ctdb_control_tcp_tickle_list *list;
976 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
977 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
981 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
983 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
987 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
988 printf("Num tickles:%u\n", list->tickles.num);
989 for (i=0;i<list->tickles.num;i++) {
990 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
991 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));
1000 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
1002 struct ctdb_all_public_ips *ips;
1003 struct ctdb_public_ip ip;
1006 uint32_t disable_time;
1008 struct ctdb_node_map *nodemap=NULL;
1009 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1012 data.dptr = (uint8_t*)&disable_time;
1013 data.dsize = sizeof(disable_time);
1014 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
1016 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
1022 /* read the public ip list from the node */
1023 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
1025 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
1026 talloc_free(tmp_ctx);
1030 for (i=0;i<ips->num;i++) {
1031 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
1036 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
1037 pnn, ctdb_addr_to_str(addr)));
1038 talloc_free(tmp_ctx);
1045 data.dptr = (uint8_t *)&ip;
1046 data.dsize = sizeof(ip);
1048 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
1050 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1051 talloc_free(tmp_ctx);
1055 nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
1056 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
1063 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
1064 talloc_free(tmp_ctx);
1068 ret = ctdb_ctrl_takeover_ip(ctdb, LONGTIMELIMIT(), pnn, &ip);
1070 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
1071 talloc_free(tmp_ctx);
1075 /* update the recovery daemon so it now knows to expect the new
1076 node assignment for this ip.
1078 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_RECD_UPDATE_IP, data);
1080 DEBUG(DEBUG_ERR,("Failed to send message to update the ip on the recovery master.\n"));
1084 talloc_free(tmp_ctx);
1089 move/failover an ip address to a specific node
1091 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
1094 ctdb_sock_addr addr;
1101 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1102 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1107 if (sscanf(argv[1], "%u", &pnn) != 1) {
1108 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
1112 if (move_ip(ctdb, &addr, pnn) != 0) {
1113 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1120 void getips_store_callback(void *param, void *data)
1122 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
1123 struct ctdb_all_public_ips *ips = param;
1127 ips->ips[i].pnn = node_ip->pnn;
1128 ips->ips[i].addr = node_ip->addr;
1131 void getips_count_callback(void *param, void *data)
1133 uint32_t *count = param;
1139 static uint32_t *ip_key(ctdb_sock_addr *ip)
1141 static uint32_t key[IP_KEYLEN];
1143 bzero(key, sizeof(key));
1145 switch (ip->sa.sa_family) {
1147 key[0] = ip->ip.sin_addr.s_addr;
1150 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
1151 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
1152 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
1153 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
1156 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1163 static void *add_ip_callback(void *parm, void *data)
1169 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1171 struct ctdb_all_public_ips *tmp_ips;
1172 struct ctdb_node_map *nodemap=NULL;
1173 trbt_tree_t *ip_tree;
1177 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1179 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1183 ip_tree = trbt_create(tmp_ctx, 0);
1185 for(i=0;i<nodemap->num;i++){
1186 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1189 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1193 /* read the public ip list from this node */
1194 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1196 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1200 for (j=0; j<tmp_ips->num;j++) {
1201 struct ctdb_public_ip *node_ip;
1203 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1204 node_ip->pnn = tmp_ips->ips[j].pnn;
1205 node_ip->addr = tmp_ips->ips[j].addr;
1207 trbt_insertarray32_callback(ip_tree,
1208 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1212 talloc_free(tmp_ips);
1217 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1219 len = offsetof(struct ctdb_all_public_ips, ips) +
1220 count*sizeof(struct ctdb_public_ip);
1221 tmp_ips = talloc_zero_size(tmp_ctx, len);
1222 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1231 * scans all other nodes and returns a pnn for another node that can host this
1235 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1237 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1238 struct ctdb_all_public_ips *ips;
1239 struct ctdb_node_map *nodemap=NULL;
1242 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1244 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1245 talloc_free(tmp_ctx);
1249 for(i=0;i<nodemap->num;i++){
1250 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1253 if (nodemap->nodes[i].pnn == options.pnn) {
1257 /* read the public ip list from this node */
1258 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1260 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1264 for (j=0;j<ips->num;j++) {
1265 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1266 talloc_free(tmp_ctx);
1267 return nodemap->nodes[i].pnn;
1273 talloc_free(tmp_ctx);
1278 add a public ip address to a node
1280 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1286 ctdb_sock_addr addr;
1287 struct ctdb_control_ip_iface *pub;
1288 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1289 struct ctdb_all_public_ips *ips;
1293 talloc_free(tmp_ctx);
1297 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1298 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1299 talloc_free(tmp_ctx);
1303 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1305 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1306 talloc_free(tmp_ctx);
1311 /* check if some other node is already serving this ip, if not,
1314 for (i=0;i<ips->num;i++) {
1315 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1320 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1321 pub = talloc_size(tmp_ctx, len);
1322 CTDB_NO_MEMORY(ctdb, pub);
1326 pub->len = strlen(argv[1])+1;
1327 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1329 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1331 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1332 talloc_free(tmp_ctx);
1336 if (i == ips->num) {
1337 /* no one has this ip so we claim it */
1340 pnn = ips->ips[i].pnn;
1343 if (move_ip(ctdb, &addr, pnn) != 0) {
1344 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1348 talloc_free(tmp_ctx);
1352 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1354 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1356 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1357 struct ctdb_node_map *nodemap=NULL;
1358 struct ctdb_all_public_ips *ips;
1361 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1363 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1367 /* remove it from the nodes that are not hosting the ip currently */
1368 for(i=0;i<nodemap->num;i++){
1369 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1372 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1373 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1377 for (j=0;j<ips->num;j++) {
1378 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1386 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1390 options.pnn = nodemap->nodes[i].pnn;
1391 control_delip(ctdb, argc, argv);
1395 /* remove it from every node (also the one hosting it) */
1396 for(i=0;i<nodemap->num;i++){
1397 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1400 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1401 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1405 for (j=0;j<ips->num;j++) {
1406 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1414 options.pnn = nodemap->nodes[i].pnn;
1415 control_delip(ctdb, argc, argv);
1418 talloc_free(tmp_ctx);
1423 delete a public ip address from a node
1425 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1428 ctdb_sock_addr addr;
1429 struct ctdb_control_ip_iface pub;
1430 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1431 struct ctdb_all_public_ips *ips;
1434 talloc_free(tmp_ctx);
1438 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1439 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1443 if (options.pnn == CTDB_BROADCAST_ALL) {
1444 return control_delip_all(ctdb, argc, argv, &addr);
1451 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1453 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1454 talloc_free(tmp_ctx);
1458 for (i=0;i<ips->num;i++) {
1459 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1465 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1466 ctdb_addr_to_str(&addr)));
1467 talloc_free(tmp_ctx);
1471 if (ips->ips[i].pnn == options.pnn) {
1472 ret = find_other_host_for_public_ip(ctdb, &addr);
1474 if (move_ip(ctdb, &addr, ret) != 0) {
1475 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1481 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1483 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1484 talloc_free(tmp_ctx);
1488 talloc_free(tmp_ctx);
1493 kill a tcp connection
1495 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1498 struct ctdb_control_killtcp killtcp;
1504 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1505 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1509 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1510 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1514 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1516 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1527 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1530 ctdb_sock_addr addr;
1536 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1537 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1541 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1543 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1551 register a server id
1553 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1556 struct ctdb_server_id server_id;
1562 server_id.pnn = strtoul(argv[0], NULL, 0);
1563 server_id.type = strtoul(argv[1], NULL, 0);
1564 server_id.server_id = strtoul(argv[2], NULL, 0);
1566 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1568 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1571 DEBUG(DEBUG_ERR,("Srvid registered. Sleeping for 999 seconds\n"));
1577 unregister a server id
1579 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1582 struct ctdb_server_id server_id;
1588 server_id.pnn = strtoul(argv[0], NULL, 0);
1589 server_id.type = strtoul(argv[1], NULL, 0);
1590 server_id.server_id = strtoul(argv[2], NULL, 0);
1592 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1594 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1601 check if a server id exists
1603 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1607 struct ctdb_server_id server_id;
1613 server_id.pnn = strtoul(argv[0], NULL, 0);
1614 server_id.type = strtoul(argv[1], NULL, 0);
1615 server_id.server_id = strtoul(argv[2], NULL, 0);
1617 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1619 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1624 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1626 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1632 get a list of all server ids that are registered on a node
1634 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1637 struct ctdb_server_id_list *server_ids;
1639 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1641 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1645 for (i=0; i<server_ids->num; i++) {
1646 printf("Server id %d:%d:%d\n",
1647 server_ids->server_ids[i].pnn,
1648 server_ids->server_ids[i].type,
1649 server_ids->server_ids[i].server_id);
1656 send a tcp tickle ack
1658 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1661 ctdb_sock_addr src, dst;
1667 if (!parse_ip_port(argv[0], &src)) {
1668 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1672 if (!parse_ip_port(argv[1], &dst)) {
1673 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1677 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1681 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1688 display public ip status
1690 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1693 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1694 struct ctdb_all_public_ips *ips;
1696 if (options.pnn == CTDB_BROADCAST_ALL) {
1697 /* read the list of public ips from all nodes */
1698 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1700 /* read the public ip list from this node */
1701 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1704 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1705 talloc_free(tmp_ctx);
1709 if (options.machinereadable){
1710 printf(":Public IP:Node:ActiveInterface:AvailableInterfaces:ConfiguredInterfaces:\n");
1712 if (options.pnn == CTDB_BROADCAST_ALL) {
1713 printf("Public IPs on ALL nodes\n");
1715 printf("Public IPs on node %u\n", options.pnn);
1719 for (i=1;i<=ips->num;i++) {
1720 struct ctdb_control_public_ip_info *info = NULL;
1722 char *aciface = NULL;
1723 char *avifaces = NULL;
1724 char *cifaces = NULL;
1726 if (options.pnn == CTDB_BROADCAST_ALL) {
1727 pnn = ips->ips[ips->num-i].pnn;
1733 ret = ctdb_ctrl_get_public_ip_info(ctdb, TIMELIMIT(), pnn, ctdb,
1734 &ips->ips[ips->num-i].addr, &info);
1741 for (j=0; j < info->num; j++) {
1742 if (cifaces == NULL) {
1743 cifaces = talloc_strdup(info,
1744 info->ifaces[j].name);
1746 cifaces = talloc_asprintf_append(cifaces,
1748 info->ifaces[j].name);
1751 if (info->active_idx == j) {
1752 aciface = info->ifaces[j].name;
1755 if (info->ifaces[j].link_state == 0) {
1759 if (avifaces == NULL) {
1760 avifaces = talloc_strdup(info, info->ifaces[j].name);
1762 avifaces = talloc_asprintf_append(avifaces,
1764 info->ifaces[j].name);
1769 if (options.machinereadable){
1770 printf(":%s:%d:%s:%s:%s:\n",
1771 ctdb_addr_to_str(&ips->ips[ips->num-i].addr),
1772 ips->ips[ips->num-i].pnn,
1774 avifaces?avifaces:"",
1775 cifaces?cifaces:"");
1777 printf("%s node[%d] active[%s] available[%s] configured[%s]\n",
1778 ctdb_addr_to_str(&ips->ips[ips->num-i].addr),
1779 ips->ips[ips->num-i].pnn,
1781 avifaces?avifaces:"",
1782 cifaces?cifaces:"");
1787 talloc_free(tmp_ctx);
1794 static int control_ipinfo(struct ctdb_context *ctdb, int argc, const char **argv)
1797 ctdb_sock_addr addr;
1798 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1799 struct ctdb_control_public_ip_info *info;
1802 talloc_free(tmp_ctx);
1806 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1807 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1811 /* read the public ip info from this node */
1812 ret = ctdb_ctrl_get_public_ip_info(ctdb, TIMELIMIT(), options.pnn,
1813 tmp_ctx, &addr, &info);
1815 DEBUG(DEBUG_ERR, ("Unable to get public ip[%s]info from node %u\n",
1816 argv[0], options.pnn));
1817 talloc_free(tmp_ctx);
1821 printf("Public IP[%s] info on node %u\n",
1822 ctdb_addr_to_str(&info->ip.addr),
1825 printf("IP:%s\nCurrentNode:%d\nNumInterfaces:%u\n",
1826 ctdb_addr_to_str(&info->ip.addr),
1827 info->ip.pnn, info->num);
1829 for (i=0; i<info->num; i++) {
1830 info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
1832 printf("Interface[%u]: Name:%s Link:%s References:%u%s\n",
1833 i+1, info->ifaces[i].name,
1834 info->ifaces[i].link_state?"up":"down",
1835 (unsigned int)info->ifaces[i].references,
1836 (i==info->active_idx)?" (active)":"");
1839 talloc_free(tmp_ctx);
1844 display interfaces status
1846 static int control_ifaces(struct ctdb_context *ctdb, int argc, const char **argv)
1849 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1850 struct ctdb_control_get_ifaces *ifaces;
1852 /* read the public ip list from this node */
1853 ret = ctdb_ctrl_get_ifaces(ctdb, TIMELIMIT(), options.pnn,
1856 DEBUG(DEBUG_ERR, ("Unable to get interfaces from node %u\n",
1858 talloc_free(tmp_ctx);
1862 if (options.machinereadable){
1863 printf(":Name:LinkStatus:References:\n");
1865 printf("Interfaces on node %u\n", options.pnn);
1868 for (i=0; i<ifaces->num; i++) {
1869 if (options.machinereadable){
1870 printf(":%s:%s:%u\n",
1871 ifaces->ifaces[i].name,
1872 ifaces->ifaces[i].link_state?"1":"0",
1873 (unsigned int)ifaces->ifaces[i].references);
1875 printf("name:%s link:%s references:%u\n",
1876 ifaces->ifaces[i].name,
1877 ifaces->ifaces[i].link_state?"up":"down",
1878 (unsigned int)ifaces->ifaces[i].references);
1882 talloc_free(tmp_ctx);
1888 set link status of an interface
1890 static int control_setifacelink(struct ctdb_context *ctdb, int argc, const char **argv)
1893 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1894 struct ctdb_control_iface_info info;
1902 if (strlen(argv[0]) > CTDB_IFACE_SIZE) {
1903 DEBUG(DEBUG_ERR, ("interfaces name '%s' too long\n",
1905 talloc_free(tmp_ctx);
1908 strcpy(info.name, argv[0]);
1910 if (strcmp(argv[1], "up") == 0) {
1911 info.link_state = 1;
1912 } else if (strcmp(argv[1], "down") == 0) {
1913 info.link_state = 0;
1915 DEBUG(DEBUG_ERR, ("link state invalid '%s' should be 'up' or 'down'\n",
1917 talloc_free(tmp_ctx);
1921 /* read the public ip list from this node */
1922 ret = ctdb_ctrl_set_iface_link(ctdb, TIMELIMIT(), options.pnn,
1925 DEBUG(DEBUG_ERR, ("Unable to set link state for interfaces %s node %u\n",
1926 argv[0], options.pnn));
1927 talloc_free(tmp_ctx);
1931 talloc_free(tmp_ctx);
1936 display pid of a ctdb daemon
1938 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1943 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1945 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1948 printf("Pid:%d\n", pid);
1953 static uint32_t ipreallocate_finished;
1956 handler for receiving the response to ipreallocate
1958 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid,
1959 TDB_DATA data, void *private_data)
1961 ipreallocate_finished = 1;
1964 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1966 struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1968 event_add_timed(ctdb->ev, ctdb,
1969 timeval_current_ofs(1, 0),
1970 ctdb_every_second, ctdb);
1974 ask the recovery daemon on the recovery master to perform a ip reallocation
1976 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1980 struct takeover_run_reply rd;
1982 struct ctdb_node_map *nodemap=NULL;
1984 struct timeval tv = timeval_current();
1986 /* we need some events to trigger so we can timeout and restart
1989 event_add_timed(ctdb->ev, ctdb,
1990 timeval_current_ofs(1, 0),
1991 ctdb_every_second, ctdb);
1993 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1995 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1998 rd.srvid = getpid();
2000 /* register a message port for receiveing the reply so that we
2001 can receive the reply
2003 ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
2005 data.dptr = (uint8_t *)&rd;
2006 data.dsize = sizeof(rd);
2010 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
2014 /* check that there are valid nodes available */
2015 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
2016 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2019 for (i=0; i<nodemap->num;i++) {
2020 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
2024 if (i==nodemap->num) {
2025 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
2030 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2032 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
2036 /* verify the node exists */
2037 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
2038 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2043 /* check tha there are nodes available that can act as a recmaster */
2044 for (i=0; i<nodemap->num; i++) {
2045 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
2050 if (i == nodemap->num) {
2051 DEBUG(DEBUG_ERR,("No possible nodes to host addresses.\n"));
2055 /* verify the recovery master is not STOPPED, nor BANNED */
2056 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
2057 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
2064 /* verify the recovery master is not STOPPED, nor BANNED */
2065 if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
2066 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
2072 ipreallocate_finished = 0;
2073 ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
2075 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
2079 tv = timeval_current();
2080 /* this loop will terminate when we have received the reply */
2081 while (timeval_elapsed(&tv) < 3.0) {
2082 event_loop_once(ctdb->ev);
2084 if (ipreallocate_finished == 1) {
2088 DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
2098 disable a remote node
2100 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
2103 struct ctdb_node_map *nodemap=NULL;
2105 /* check if the node is already disabled */
2106 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
2107 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2110 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2111 DEBUG(DEBUG_ERR,("Node %d is already disabled.\n", options.pnn));
2116 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
2118 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
2124 /* read the nodemap and verify the change took effect */
2125 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
2126 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2130 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
2131 ret = control_ipreallocate(ctdb, argc, argv);
2133 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2141 enable a disabled remote node
2143 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
2147 struct ctdb_node_map *nodemap=NULL;
2150 /* check if the node is already enabled */
2151 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
2152 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2155 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED)) {
2156 DEBUG(DEBUG_ERR,("Node %d is already enabled.\n", options.pnn));
2161 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
2163 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
2169 /* read the nodemap and verify the change took effect */
2170 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
2171 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2175 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
2177 ret = control_ipreallocate(ctdb, argc, argv);
2179 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2189 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
2192 struct ctdb_node_map *nodemap=NULL;
2195 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
2197 DEBUG(DEBUG_ERR, ("Unable to stop node %u try again\n", options.pnn));
2202 /* read the nodemap and verify the change took effect */
2203 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
2204 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2208 } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
2209 ret = control_ipreallocate(ctdb, argc, argv);
2211 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2219 restart a stopped remote node
2221 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
2225 struct ctdb_node_map *nodemap=NULL;
2228 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
2230 DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
2236 /* read the nodemap and verify the change took effect */
2237 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
2238 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2242 } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
2243 ret = control_ipreallocate(ctdb, argc, argv);
2245 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2252 static uint32_t get_generation(struct ctdb_context *ctdb)
2254 struct ctdb_vnn_map *vnnmap=NULL;
2257 /* wait until the recmaster is not in recovery mode */
2259 uint32_t recmode, recmaster;
2261 if (vnnmap != NULL) {
2262 talloc_free(vnnmap);
2266 /* get the recmaster */
2267 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
2269 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
2273 /* get recovery mode */
2274 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
2276 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
2280 /* get the current generation number */
2281 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
2283 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
2287 if ((recmode == CTDB_RECOVERY_NORMAL)
2288 && (vnnmap->generation != 1)){
2289 return vnnmap->generation;
2296 ban a node from the cluster
2298 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
2301 struct ctdb_node_map *nodemap=NULL;
2302 struct ctdb_ban_time bantime;
2308 /* verify the node exists */
2309 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2311 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2315 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
2316 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
2320 bantime.pnn = options.pnn;
2321 bantime.time = strtoul(argv[0], NULL, 0);
2323 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2325 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
2329 ret = control_ipreallocate(ctdb, argc, argv);
2331 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2340 unban a node from the cluster
2342 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
2345 struct ctdb_node_map *nodemap=NULL;
2346 struct ctdb_ban_time bantime;
2348 /* verify the node exists */
2349 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2351 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2355 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
2356 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
2360 bantime.pnn = options.pnn;
2363 ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
2365 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
2369 ret = control_ipreallocate(ctdb, argc, argv);
2371 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
2380 show ban information for a node
2382 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
2385 struct ctdb_node_map *nodemap=NULL;
2386 struct ctdb_ban_time *bantime;
2388 /* verify the node exists */
2389 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2391 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2395 ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2397 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2401 if (bantime->time == 0) {
2402 printf("Node %u is not banned\n", bantime->pnn);
2404 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2413 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2417 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2419 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2429 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2432 uint32_t generation, next_generation;
2434 /* record the current generation number */
2435 generation = get_generation(ctdb);
2437 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2439 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2443 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2445 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2449 /* wait until we are in a new generation */
2451 next_generation = get_generation(ctdb);
2452 if (next_generation != generation) {
2463 display monitoring mode of a remote node
2465 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2470 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2472 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2475 if (!options.machinereadable){
2476 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2479 printf(":%d:\n",monmode);
2486 display capabilities of a remote node
2488 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2490 uint32_t capabilities;
2493 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2495 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2499 if (!options.machinereadable){
2500 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2501 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2502 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2503 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2505 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2506 printf(":%d:%d:%d:%d:\n",
2507 !!(capabilities&CTDB_CAP_RECMASTER),
2508 !!(capabilities&CTDB_CAP_LMASTER),
2509 !!(capabilities&CTDB_CAP_LVS),
2510 !!(capabilities&CTDB_CAP_NATGW));
2516 display lvs configuration
2518 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2520 uint32_t *capabilities;
2521 struct ctdb_node_map *nodemap=NULL;
2523 int healthy_count = 0;
2525 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2527 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2531 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2532 CTDB_NO_MEMORY(ctdb, capabilities);
2534 /* collect capabilities for all connected nodes */
2535 for (i=0; i<nodemap->num; i++) {
2536 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2539 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2543 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2545 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2549 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2553 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2558 /* Print all LVS nodes */
2559 for (i=0; i<nodemap->num; i++) {
2560 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2563 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2566 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2570 if (healthy_count != 0) {
2571 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2576 printf("%d:%s\n", i,
2577 ctdb_addr_to_str(&nodemap->nodes[i].addr));
2584 display who is the lvs master
2586 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2588 uint32_t *capabilities;
2589 struct ctdb_node_map *nodemap=NULL;
2591 int healthy_count = 0;
2593 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2595 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2599 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2600 CTDB_NO_MEMORY(ctdb, capabilities);
2602 /* collect capabilities for all connected nodes */
2603 for (i=0; i<nodemap->num; i++) {
2604 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2607 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2611 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2613 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2617 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2621 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2626 /* find and show the lvsmaster */
2627 for (i=0; i<nodemap->num; i++) {
2628 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2631 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2634 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2638 if (healthy_count != 0) {
2639 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2644 if (options.machinereadable){
2647 printf("Node %d is LVS master\n", i);
2652 printf("There is no LVS master\n");
2657 disable monitoring on a node
2659 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2664 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2666 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2669 printf("Monitoring mode:%s\n","DISABLED");
2675 enable monitoring on a node
2677 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2682 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2684 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2687 printf("Monitoring mode:%s\n","ACTIVE");
2693 display remote list of keys/data for a db
2695 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2697 const char *db_name;
2698 struct ctdb_db_context *ctdb_db;
2708 if (db_exists(ctdb, db_name)) {
2709 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2713 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2715 if (ctdb_db == NULL) {
2716 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2720 /* traverse and dump the cluster tdb */
2721 ret = ctdb_dump_db(ctdb_db, stdout);
2723 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2724 DEBUG(DEBUG_ERR, ("Maybe try 'ctdb getdbstatus %s'"
2725 " and 'ctdb getvar AllowUnhealthyDBRead'\n",
2729 talloc_free(ctdb_db);
2731 printf("Dumped %d records\n", ret);
2736 static void log_handler(struct ctdb_context *ctdb, uint64_t srvid,
2737 TDB_DATA data, void *private_data)
2739 DEBUG(DEBUG_ERR,("Log data received\n"));
2740 if (data.dsize > 0) {
2741 printf("%s", data.dptr);
2748 display a list of log messages from the in memory ringbuffer
2750 static int control_getlog(struct ctdb_context *ctdb, int argc, const char **argv)
2754 struct ctdb_get_log_addr log_addr;
2756 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2761 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2762 talloc_free(tmp_ctx);
2766 log_addr.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2767 log_addr.srvid = getpid();
2768 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
2769 log_addr.level = get_debug_by_desc(argv[0]);
2771 log_addr.level = strtol(argv[0], NULL, 0);
2775 data.dptr = (unsigned char *)&log_addr;
2776 data.dsize = sizeof(log_addr);
2778 DEBUG(DEBUG_ERR, ("Pulling logs from node %u\n", options.pnn));
2780 ctdb_set_message_handler(ctdb, log_addr.srvid, log_handler, NULL);
2783 DEBUG(DEBUG_ERR,("Listen for response on %d\n", (int)log_addr.srvid));
2785 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_GET_LOG,
2786 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2787 if (ret != 0 || res != 0) {
2788 DEBUG(DEBUG_ERR,("Failed to get logs - %s\n", errmsg));
2789 talloc_free(tmp_ctx);
2794 tv = timeval_current();
2795 /* this loop will terminate when we have received the reply */
2796 while (timeval_elapsed(&tv) < 3.0) {
2797 event_loop_once(ctdb->ev);
2800 DEBUG(DEBUG_INFO,("Timed out waiting for log data.\n"));
2802 talloc_free(tmp_ctx);
2807 clear the in memory log area
2809 static int control_clearlog(struct ctdb_context *ctdb, int argc, const char **argv)
2814 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2816 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_CLEAR_LOG,
2817 0, tdb_null, tmp_ctx, NULL, &res, NULL, &errmsg);
2818 if (ret != 0 || res != 0) {
2819 DEBUG(DEBUG_ERR,("Failed to clear logs\n"));
2820 talloc_free(tmp_ctx);
2824 talloc_free(tmp_ctx);
2831 display a list of the databases on a remote ctdb
2833 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2836 struct ctdb_dbid_map *dbmap=NULL;
2838 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2840 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2844 if(options.machinereadable){
2845 printf(":ID:Name:Path:Persistent:Unhealthy:\n");
2846 for(i=0;i<dbmap->num;i++){
2852 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn,
2853 dbmap->dbs[i].dbid, ctdb, &path);
2854 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
2855 dbmap->dbs[i].dbid, ctdb, &name);
2856 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
2857 dbmap->dbs[i].dbid, ctdb, &health);
2858 persistent = dbmap->dbs[i].persistent;
2859 printf(":0x%08X:%s:%s:%d:%d:\n",
2860 dbmap->dbs[i].dbid, name, path,
2861 !!(persistent), !!(health));
2866 printf("Number of databases:%d\n", dbmap->num);
2867 for(i=0;i<dbmap->num;i++){
2873 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2874 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2875 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
2876 persistent = dbmap->dbs[i].persistent;
2877 printf("dbid:0x%08x name:%s path:%s%s%s\n",
2878 dbmap->dbs[i].dbid, name, path,
2879 persistent?" PERSISTENT":"",
2880 health?" UNHEALTHY":"");
2887 display the status of a database on a remote ctdb
2889 static int control_getdbstatus(struct ctdb_context *ctdb, int argc, const char **argv)
2892 struct ctdb_dbid_map *dbmap=NULL;
2893 const char *db_name;
2901 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2903 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2907 for(i=0;i<dbmap->num;i++){
2913 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2914 if (strcmp(name, db_name) != 0) {
2918 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2919 ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
2920 persistent = dbmap->dbs[i].persistent;
2921 printf("dbid: 0x%08x\nname: %s\npath: %s\nPERSISTENT: %s\nHEALTH: %s\n",
2922 dbmap->dbs[i].dbid, name, path,
2923 persistent?"yes":"no",
2924 health?health:"OK");
2928 DEBUG(DEBUG_ERR, ("db %s doesn't exist on node %u\n", db_name, options.pnn));
2933 check if the local node is recmaster or not
2934 it will return 1 if this node is the recmaster and 0 if it is not
2935 or if the local ctdb daemon could not be contacted
2937 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2939 uint32_t mypnn, recmaster;
2942 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2944 printf("Failed to get pnn of node\n");
2948 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2950 printf("Failed to get the recmaster\n");
2954 if (recmaster != mypnn) {
2955 printf("this node is not the recmaster\n");
2959 printf("this node is the recmaster\n");
2966 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2969 struct timeval tv = timeval_current();
2970 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2972 printf("Unable to get ping response from node %u\n", options.pnn);
2975 printf("response from %u time=%.6f sec (%d clients)\n",
2976 options.pnn, timeval_elapsed(&tv), ret);
2985 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2996 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2998 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
3002 printf("%-19s = %u\n", name, value);
3009 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
3020 value = strtoul(argv[1], NULL, 0);
3022 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
3024 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
3033 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
3039 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
3041 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
3045 for (i=0;i<count;i++) {
3046 control_getvar(ctdb, 1, &list[i]);
3055 display debug level on a node
3057 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
3062 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
3064 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
3067 if (options.machinereadable){
3068 printf(":Name:Level:\n");
3069 printf(":%s:%d:\n",get_debug_by_level(level),level);
3071 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
3078 display reclock file of a node
3080 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
3083 const char *reclock;
3085 ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
3087 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
3090 if (options.machinereadable){
3091 if (reclock != NULL) {
3092 printf("%s", reclock);
3095 if (reclock == NULL) {
3096 printf("No reclock file used.\n");
3098 printf("Reclock file:%s\n", reclock);
3106 set the reclock file of a node
3108 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
3111 const char *reclock;
3115 } else if (argc == 1) {
3121 ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
3123 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
3130 set the natgw state on/off
3132 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
3135 uint32_t natgwstate;
3141 if (!strcmp(argv[0], "on")) {
3143 } else if (!strcmp(argv[0], "off")) {
3149 ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
3151 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
3159 set the lmaster role on/off
3161 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
3164 uint32_t lmasterrole;
3170 if (!strcmp(argv[0], "on")) {
3172 } else if (!strcmp(argv[0], "off")) {
3178 ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
3180 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
3188 set the recmaster role on/off
3190 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
3193 uint32_t recmasterrole;
3199 if (!strcmp(argv[0], "on")) {
3201 } else if (!strcmp(argv[0], "off")) {
3207 ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
3209 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
3217 set debug level on a node or all nodes
3219 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
3225 printf("You must specify the debug level. Valid levels are:\n");
3226 for (i=0; debug_levels[i].description != NULL; i++) {
3227 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
3233 if (isalpha(argv[0][0]) || argv[0][0] == '-') {
3234 level = get_debug_by_desc(argv[0]);
3236 level = strtol(argv[0], NULL, 0);
3239 for (i=0; debug_levels[i].description != NULL; i++) {
3240 if (level == debug_levels[i].level) {
3244 if (debug_levels[i].description == NULL) {
3245 printf("Invalid debug level, must be one of\n");
3246 for (i=0; debug_levels[i].description != NULL; i++) {
3247 printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
3252 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
3254 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
3263 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
3269 priority = strtol(argv[0], NULL, 0);
3273 DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
3275 ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
3277 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
3285 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
3291 priority = strtol(argv[0], NULL, 0);
3295 DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
3297 ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
3299 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
3306 attach to a database
3308 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
3310 const char *db_name;
3311 struct ctdb_db_context *ctdb_db;
3318 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
3319 if (ctdb_db == NULL) {
3320 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
3330 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
3332 struct ctdb_db_priority db_prio;
3339 db_prio.db_id = strtoul(argv[0], NULL, 0);
3340 db_prio.priority = strtoul(argv[1], NULL, 0);
3342 ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
3344 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
3354 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
3356 uint32_t db_id, priority;
3363 db_id = strtoul(argv[0], NULL, 0);
3365 ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
3367 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
3371 DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
3377 run an eventscript on a node
3379 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
3385 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3388 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3392 data.dptr = (unsigned char *)discard_const(argv[0]);
3393 data.dsize = strlen((char *)data.dptr) + 1;
3395 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
3397 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
3398 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
3399 if (ret != 0 || res != 0) {
3400 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
3401 talloc_free(tmp_ctx);
3404 talloc_free(tmp_ctx);
3408 #define DB_VERSION 1
3409 #define MAX_DB_NAME 64
3410 struct db_file_header {
3411 unsigned long version;
3413 unsigned long persistent;
3415 const char name[MAX_DB_NAME];
3418 struct backup_data {
3419 struct ctdb_marshall_buffer *records;
3422 bool traverse_error;
3425 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
3427 struct backup_data *bd = talloc_get_type(private, struct backup_data);
3428 struct ctdb_rec_data *rec;
3430 /* add the record */
3431 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
3433 bd->traverse_error = true;
3434 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
3437 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
3438 if (bd->records == NULL) {
3439 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
3440 bd->traverse_error = true;
3443 bd->records->count++;
3444 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
3445 bd->len += rec->length;
3453 * backup a database to a file
3455 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
3458 struct ctdb_dbid_map *dbmap=NULL;
3459 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3460 struct db_file_header dbhdr;
3461 struct ctdb_db_context *ctdb_db;
3462 struct backup_data *bd;
3465 const char *reason = NULL;
3468 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3472 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
3474 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
3478 for(i=0;i<dbmap->num;i++){
3481 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
3482 if(!strcmp(argv[0], name)){
3483 talloc_free(discard_const(name));
3486 talloc_free(discard_const(name));
3488 if (i == dbmap->num) {
3489 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
3490 talloc_free(tmp_ctx);
3494 ret = ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
3495 dbmap->dbs[i].dbid, tmp_ctx, &reason);
3497 DEBUG(DEBUG_ERR,("Unable to get dbhealth for database '%s'\n",
3499 talloc_free(tmp_ctx);
3503 uint32_t allow_unhealthy = 0;
3505 ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn,
3506 "AllowUnhealthyDBRead",
3509 if (allow_unhealthy != 1) {
3510 DEBUG(DEBUG_ERR,("database '%s' is unhealthy: %s\n",
3513 DEBUG(DEBUG_ERR,("disallow backup : tunnable AllowUnhealthyDBRead = %u\n",
3515 talloc_free(tmp_ctx);
3519 DEBUG(DEBUG_WARNING,("WARNING database '%s' is unhealthy - see 'ctdb getdbstatus %s'\n",
3521 DEBUG(DEBUG_WARNING,("WARNING! allow backup of unhealthy database: "
3522 "tunnable AllowUnhealthyDBRead = %u\n",
3526 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3527 if (ctdb_db == NULL) {
3528 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
3529 talloc_free(tmp_ctx);
3534 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3536 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
3537 talloc_free(tmp_ctx);
3542 bd = talloc_zero(tmp_ctx, struct backup_data);
3544 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
3545 talloc_free(tmp_ctx);
3549 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
3550 if (bd->records == NULL) {
3551 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
3552 talloc_free(tmp_ctx);
3556 bd->len = offsetof(struct ctdb_marshall_buffer, data);
3557 bd->records->db_id = ctdb_db->db_id;
3558 /* traverse the database collecting all records */
3559 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
3560 bd->traverse_error) {
3561 DEBUG(DEBUG_ERR,("Traverse error\n"));
3562 talloc_free(tmp_ctx);
3566 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3569 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
3571 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
3572 talloc_free(tmp_ctx);
3576 dbhdr.version = DB_VERSION;
3577 dbhdr.timestamp = time(NULL);
3578 dbhdr.persistent = dbmap->dbs[i].persistent;
3579 dbhdr.size = bd->len;
3580 if (strlen(argv[0]) >= MAX_DB_NAME) {
3581 DEBUG(DEBUG_ERR,("Too long dbname\n"));
3584 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
3585 ret = write(fh, &dbhdr, sizeof(dbhdr));
3587 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3590 ret = write(fh, bd->records, bd->len);
3592 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3601 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3604 talloc_free(tmp_ctx);
3609 * restore a database from a file
3611 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3614 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3617 struct db_file_header dbhdr;
3618 struct ctdb_db_context *ctdb_db;
3619 struct ctdb_node_map *nodemap=NULL;
3620 struct ctdb_vnn_map *vnnmap=NULL;
3622 struct ctdb_control_wipe_database w;
3624 uint32_t generation;
3629 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3633 fh = open(argv[0], O_RDONLY);
3635 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3636 talloc_free(tmp_ctx);
3640 read(fh, &dbhdr, sizeof(dbhdr));
3641 if (dbhdr.version != DB_VERSION) {
3642 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3643 talloc_free(tmp_ctx);
3647 outdata.dsize = dbhdr.size;
3648 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3649 if (outdata.dptr == NULL) {
3650 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3652 talloc_free(tmp_ctx);
3655 read(fh, outdata.dptr, outdata.dsize);
3658 tm = localtime(&dbhdr.timestamp);
3659 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3660 printf("Restoring database '%s' from backup @ %s\n",
3664 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3665 if (ctdb_db == NULL) {
3666 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3667 talloc_free(tmp_ctx);
3671 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3673 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3674 talloc_free(tmp_ctx);
3679 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3681 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3682 talloc_free(tmp_ctx);
3686 /* freeze all nodes */
3687 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3688 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3689 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3695 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3696 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3697 talloc_free(tmp_ctx);
3702 generation = vnnmap->generation;
3703 data.dptr = (void *)&generation;
3704 data.dsize = sizeof(generation);
3706 /* start a cluster wide transaction */
3707 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3708 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3710 TIMELIMIT(), false, data,
3713 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3718 w.db_id = ctdb_db->db_id;
3719 w.transaction_id = generation;
3721 data.dptr = (void *)&w;
3722 data.dsize = sizeof(w);
3724 /* wipe all the remote databases. */
3725 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3726 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3728 TIMELIMIT(), false, data,
3731 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3732 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3733 talloc_free(tmp_ctx);
3737 /* push the database */
3738 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3739 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3741 TIMELIMIT(), false, outdata,
3744 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3745 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3746 talloc_free(tmp_ctx);
3750 data.dptr = (void *)&ctdb_db->db_id;
3751 data.dsize = sizeof(ctdb_db->db_id);
3753 /* mark the database as healthy */
3754 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3755 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_DB_SET_HEALTHY,
3757 TIMELIMIT(), false, data,
3760 DEBUG(DEBUG_ERR, ("Failed to mark database as healthy.\n"));
3761 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3762 talloc_free(tmp_ctx);
3766 data.dptr = (void *)&generation;
3767 data.dsize = sizeof(generation);
3769 /* commit all the changes */
3770 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3772 TIMELIMIT(), false, data,
3775 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3776 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3777 talloc_free(tmp_ctx);
3782 /* thaw all nodes */
3783 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3784 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3790 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3791 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3792 talloc_free(tmp_ctx);
3797 talloc_free(tmp_ctx);
3802 * dump a database backup from a file
3804 static int control_dumpdbbackup(struct ctdb_context *ctdb, int argc, const char **argv)
3806 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3808 struct db_file_header dbhdr;
3812 struct ctdb_rec_data *rec = NULL;
3813 struct ctdb_marshall_buffer *m;
3816 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3820 fh = open(argv[0], O_RDONLY);
3822 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3823 talloc_free(tmp_ctx);
3827 read(fh, &dbhdr, sizeof(dbhdr));
3828 if (dbhdr.version != DB_VERSION) {
3829 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3830 talloc_free(tmp_ctx);
3834 outdata.dsize = dbhdr.size;
3835 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3836 if (outdata.dptr == NULL) {
3837 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3839 talloc_free(tmp_ctx);
3842 read(fh, outdata.dptr, outdata.dsize);
3844 m = (struct ctdb_marshall_buffer *)outdata.dptr;
3846 tm = localtime(&dbhdr.timestamp);
3847 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3848 printf("Backup of database name:'%s' dbid:0x%x08x from @ %s\n",
3849 dbhdr.name, m->db_id, tbuf);
3851 for (i=0; i < m->count; i++) {
3855 /* we do not want the header splitted, so we pass NULL*/
3856 rec = ctdb_marshall_loop_next(m, rec, &reqid,
3859 ctdb_dumpdb_record(ctdb, key, data, stdout);
3862 printf("Dumped %d records\n", i);
3863 talloc_free(tmp_ctx);
3868 * wipe a database from a file
3870 static int control_wipedb(struct ctdb_context *ctdb, int argc,
3874 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3876 struct ctdb_db_context *ctdb_db;
3877 struct ctdb_node_map *nodemap = NULL;
3878 struct ctdb_vnn_map *vnnmap = NULL;
3880 struct ctdb_control_wipe_database w;
3882 uint32_t generation;
3883 struct ctdb_dbid_map *dbmap = NULL;
3886 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3890 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3893 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n",
3898 for(i=0;i<dbmap->num;i++){
3901 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn,
3902 dbmap->dbs[i].dbid, tmp_ctx, &name);
3903 if(!strcmp(argv[0], name)){
3904 talloc_free(discard_const(name));
3907 talloc_free(discard_const(name));
3909 if (i == dbmap->num) {
3910 DEBUG(DEBUG_ERR, ("No database with name '%s' found\n",
3912 talloc_free(tmp_ctx);
3916 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
3917 if (ctdb_db == NULL) {
3918 DEBUG(DEBUG_ERR, ("Unable to attach to database '%s'\n",
3920 talloc_free(tmp_ctx);
3924 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb,
3927 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n",
3929 talloc_free(tmp_ctx);
3933 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
3936 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n",
3938 talloc_free(tmp_ctx);
3942 /* freeze all nodes */
3943 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3944 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3945 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3952 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3953 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn,
3954 CTDB_RECOVERY_ACTIVE);
3955 talloc_free(tmp_ctx);
3960 generation = vnnmap->generation;
3961 data.dptr = (void *)&generation;
3962 data.dsize = sizeof(generation);
3964 /* start a cluster wide transaction */
3965 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3966 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3968 TIMELIMIT(), false, data,
3972 DEBUG(DEBUG_ERR, ("Unable to start cluster wide "
3973 "transactions.\n"));
3977 w.db_id = ctdb_db->db_id;
3978 w.transaction_id = generation;
3980 data.dptr = (void *)&w;
3981 data.dsize = sizeof(w);
3983 /* wipe all the remote databases. */
3984 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3985 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3987 TIMELIMIT(), false, data,
3990 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3991 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3992 talloc_free(tmp_ctx);
3996 data.dptr = (void *)&ctdb_db->db_id;
3997 data.dsize = sizeof(ctdb_db->db_id);
3999 /* mark the database as healthy */
4000 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
4001 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_DB_SET_HEALTHY,
4003 TIMELIMIT(), false, data,
4006 DEBUG(DEBUG_ERR, ("Failed to mark database as healthy.\n"));
4007 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
4008 talloc_free(tmp_ctx);
4012 data.dptr = (void *)&generation;
4013 data.dsize = sizeof(generation);
4015 /* commit all the changes */
4016 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
4018 TIMELIMIT(), false, data,
4021 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
4022 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
4023 talloc_free(tmp_ctx);
4027 /* thaw all nodes */
4028 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
4029 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
4035 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
4036 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
4037 talloc_free(tmp_ctx);
4041 talloc_free(tmp_ctx);
4046 * set flags of a node in the nodemap
4048 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
4055 struct ctdb_node_flag_change c;
4062 if (sscanf(argv[0], "%d", &node) != 1) {
4063 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
4067 if (sscanf(argv[1], "0x%x", &flags) != 1) {
4068 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
4075 c.new_flags = flags;
4077 data.dsize = sizeof(c);
4078 data.dptr = (unsigned char *)&c;
4080 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
4081 data, NULL, NULL, &status, NULL, NULL);
4082 if (ret != 0 || status != 0) {
4083 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
4092 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
4098 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
4099 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
4100 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
4101 if (ret != 0 || res != 0) {
4102 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
4103 talloc_free(tmp_ctx);
4106 write(1, data.dptr, data.dsize);
4107 talloc_free(tmp_ctx);
4112 handler for memory dumps
4114 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
4115 TDB_DATA data, void *private_data)
4117 write(1, data.dptr, data.dsize);
4122 dump memory usage on the recovery daemon
4124 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
4128 struct rd_memdump_reply rd;
4130 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
4132 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
4135 rd.srvid = getpid();
4137 /* register a message port for receiveing the reply so that we
4138 can receive the reply
4140 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
4143 data.dptr = (uint8_t *)&rd;
4144 data.dsize = sizeof(rd);
4146 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
4148 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
4152 /* this loop will terminate when we have received the reply */
4154 event_loop_once(ctdb->ev);
4161 send a message to a srvid
4163 static int control_msgsend(struct ctdb_context *ctdb, int argc, const char **argv)
4165 unsigned long srvid;
4173 srvid = strtoul(argv[0], NULL, 0);
4175 data.dptr = (uint8_t *)discard_const(argv[1]);
4176 data.dsize= strlen(argv[1]);
4178 ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, srvid, data);
4180 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
4188 handler for msglisten
4190 static void msglisten_handler(struct ctdb_context *ctdb, uint64_t srvid,
4191 TDB_DATA data, void *private_data)
4195 printf("Message received: ");
4196 for (i=0;i<data.dsize;i++) {
4197 printf("%c", data.dptr[i]);
4203 listen for messages on a messageport
4205 static int control_msglisten(struct ctdb_context *ctdb, int argc, const char **argv)
4211 /* register a message port and listen for messages
4213 ctdb_set_message_handler(ctdb, srvid, msglisten_handler, NULL);
4214 printf("Listening for messages on srvid:%d\n", (int)srvid);
4217 event_loop_once(ctdb->ev);
4224 list all nodes in the cluster
4225 if the daemon is running, we read the data from the daemon.
4226 if the daemon is not running we parse the nodes file directly
4228 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
4231 struct ctdb_node_map *nodemap=NULL;
4234 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
4236 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
4240 for(i=0;i<nodemap->num;i++){
4241 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
4244 if (options.machinereadable){
4245 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
4247 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
4251 TALLOC_CTX *mem_ctx = talloc_new(NULL);
4252 struct pnn_node *pnn_nodes;
4253 struct pnn_node *pnn_node;
4255 pnn_nodes = read_nodes_file(mem_ctx);
4256 if (pnn_nodes == NULL) {
4257 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
4258 talloc_free(mem_ctx);
4262 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
4263 ctdb_sock_addr addr;
4265 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
4266 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
4267 talloc_free(mem_ctx);
4271 if (options.machinereadable){
4272 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
4274 printf("%s\n", pnn_node->addr);
4277 talloc_free(mem_ctx);
4284 reload the nodes file on the local node
4286 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
4290 struct ctdb_node_map *nodemap=NULL;
4292 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
4294 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
4298 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
4300 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
4304 /* reload the nodes file on all remote nodes */
4305 for (i=0;i<nodemap->num;i++) {
4306 if (nodemap->nodes[i].pnn == mypnn) {
4309 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
4310 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
4311 nodemap->nodes[i].pnn);
4313 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
4317 /* reload the nodes file on the local node */
4318 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
4319 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
4321 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
4324 /* initiate a recovery */
4325 control_recover(ctdb, argc, argv);
4331 static const struct {
4333 int (*fn)(struct ctdb_context *, int, const char **);
4335 bool without_daemon; /* can be run without daemon running ? */
4338 } ctdb_commands[] = {
4340 { "version", control_version, true, false, "show version of ctdb" },
4342 { "status", control_status, true, false, "show node status" },
4343 { "uptime", control_uptime, true, false, "show node uptime" },
4344 { "ping", control_ping, true, false, "ping all nodes" },
4345 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
4346 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
4347 { "listvars", control_listvars, true, false, "list tunable variables"},
4348 { "statistics", control_statistics, false, false, "show statistics" },
4349 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
4350 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
4351 { "ipinfo", control_ipinfo, true, false, "show details about a public ip that ctdb manages", "<ip>" },
4352 { "ifaces", control_ifaces, true, false, "show which interfaces that ctdb manages" },
4353 { "setifacelink", control_setifacelink, true, false, "set interface link status", "<iface> <status>" },
4354 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
4355 { "getdbmap", control_getdbmap, true, false, "show the database map" },
4356 { "getdbstatus", control_getdbstatus, true, false, "show the status of a database", "<dbname>" },
4357 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
4358 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
4359 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
4360 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
4361 { "lvs", control_lvs, true, false, "show lvs configuration" },
4362 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
4363 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
4364 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
4365 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
4366 { "getdebug", control_getdebug, true, false, "get debug level" },
4367 { "getlog", control_getlog, true, false, "get the log data from the in memory ringbuffer", "<level>" },
4368 { "clearlog", control_clearlog, true, false, "clear the log data from the in memory ringbuffer" },
4369 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
4370 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
4371 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
4372 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
4373 { "disable", control_disable, true, false, "disable a nodes public IP" },
4374 { "enable", control_enable, true, false, "enable a nodes public IP" },
4375 { "stop", control_stop, true, false, "stop a node" },
4376 { "continue", control_continue, true, false, "re-start a stopped node" },
4377 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
4378 { "unban", control_unban, true, false, "unban a node" },
4379 { "showban", control_showban, true, false, "show ban information"},
4380 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
4381 { "recover", control_recover, true, false, "force recovery" },
4382 { "ipreallocate", control_ipreallocate, true, false, "force the recovery daemon to perform a ip reallocation procedure" },
4383 { "freeze", control_freeze, true, false, "freeze databases", "[priority:1-3]" },
4384 { "thaw", control_thaw, true, false, "thaw databases", "[priority:1-3]" },
4385 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
4386 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
4387 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
4388 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
4389 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
4391 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
4392 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
4393 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
4394 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
4395 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
4396 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
4397 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
4398 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
4399 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
4400 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
4401 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
4402 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
4403 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
4404 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
4405 { "dumpdbbackup", control_dumpdbbackup, false, true, "dump database backup from a file.", "<file>"},
4406 { "wipedb", control_wipedb, false, false, "wipe the contents of a database.", "<dbname>"},
4407 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
4408 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
4409 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts (or all scripts)", "[all]"},
4410 { "enablescript", control_enablescript, false, false, "enable an eventscript", "<script>"},
4411 { "disablescript", control_disablescript, false, false, "disable an eventscript", "<script>"},
4412 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
4413 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
4414 { "getreclock", control_getreclock, false, false, "Show the reclock file of a node"},
4415 { "setreclock", control_setreclock, false, false, "Set/clear the reclock file of a node", "[filename]"},
4416 { "setnatgwstate", control_setnatgwstate, false, false, "Set NATGW state to on/off", "{on|off}"},
4417 { "setlmasterrole", control_setlmasterrole, false, false, "Set LMASTER role to on/off", "{on|off}"},
4418 { "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
4419 { "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
4420 { "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
4421 { "msglisten", control_msglisten, false, false, "Listen on a srvid port for messages", "<msg srvid>"},
4422 { "msgsend", control_msgsend, false, false, "Send a message to srvid", "<srvid> <message>"},
4428 static void usage(void)
4432 "Usage: ctdb [options] <control>\n" \
4434 " -n <node> choose node number, or 'all' (defaults to local node)\n"
4435 " -Y generate machinereadable output\n"
4436 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
4437 printf("Controls:\n");
4438 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
4439 printf(" %-15s %-27s %s\n",
4440 ctdb_commands[i].name,
4441 ctdb_commands[i].args?ctdb_commands[i].args:"",
4442 ctdb_commands[i].msg);
4448 static void ctdb_alarm(int sig)
4450 printf("Maximum runtime exceeded - exiting\n");
4457 int main(int argc, const char *argv[])
4459 struct ctdb_context *ctdb;
4460 char *nodestring = NULL;
4461 struct poptOption popt_options[] = {
4464 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
4465 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
4466 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
4467 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
4471 const char **extra_argv;
4475 struct event_context *ev;
4476 const char *control;
4480 /* set some defaults */
4481 options.maxruntime = 0;
4482 options.timelimit = 3;
4483 options.pnn = CTDB_CURRENT_NODE;
4485 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
4487 while ((opt = poptGetNextOpt(pc)) != -1) {
4490 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
4491 poptBadOption(pc, 0), poptStrerror(opt)));
4496 /* setup the remaining options for the main program to use */
4497 extra_argv = poptGetArgs(pc);
4500 while (extra_argv[extra_argc]) extra_argc++;
4503 if (extra_argc < 1) {
4507 if (options.maxruntime == 0) {
4508 const char *ctdb_timeout;
4509 ctdb_timeout = getenv("CTDB_TIMEOUT");
4510 if (ctdb_timeout != NULL) {
4511 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
4513 /* default timeout is 120 seconds */
4514 options.maxruntime = 120;
4518 signal(SIGALRM, ctdb_alarm);
4519 alarm(options.maxruntime);
4521 /* setup the node number to contact */
4522 if (nodestring != NULL) {
4523 if (strcmp(nodestring, "all") == 0) {
4524 options.pnn = CTDB_BROADCAST_ALL;
4526 options.pnn = strtoul(nodestring, NULL, 0);
4530 control = extra_argv[0];
4532 ev = event_context_init(NULL);
4534 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
4535 if (strcmp(control, ctdb_commands[i].name) == 0) {
4538 if (ctdb_commands[i].without_daemon == true) {
4542 /* initialise ctdb */
4543 ctdb = ctdb_cmdline_client(ev);
4545 if (ctdb_commands[i].without_daemon == false) {
4547 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
4551 /* verify the node exists */
4554 if (options.pnn == CTDB_CURRENT_NODE) {
4556 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
4564 if (ctdb_commands[i].auto_all &&
4565 options.pnn == CTDB_BROADCAST_ALL) {
4570 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
4571 CTDB_NO_MEMORY(ctdb, nodes);
4573 for (j=0;j<num_nodes;j++) {
4574 options.pnn = nodes[j];
4575 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4579 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
4585 if (i == ARRAY_SIZE(ctdb_commands)) {
4586 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));