4 Copyright (C) Andrew Tridgell 2007
5 Copyright (C) Ronnie Sahlberg 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "lib/events/events.h"
23 #include "system/time.h"
24 #include "system/filesys.h"
25 #include "system/network.h"
26 #include "system/locale.h"
29 #include "../include/ctdb.h"
30 #include "../include/ctdb_private.h"
31 #include "../common/rb_tree.h"
35 #define ERR_TIMEOUT 20 /* timed out trying to reach node */
36 #define ERR_NONODE 21 /* node does not exist */
37 #define ERR_DISNODE 22 /* node is disconnected */
39 static void usage(void);
48 #define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
51 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
54 #define XSTR(x) STR(x)
55 printf("CTDB version: %s\n", XSTR(CTDB_VERS));
62 verify that a node exists and is reachable
64 static void verify_node(struct ctdb_context *ctdb)
67 struct ctdb_node_map *nodemap=NULL;
69 if (options.pnn == CTDB_CURRENT_NODE) {
72 if (options.pnn == CTDB_BROADCAST_ALL) {
76 /* verify the node exists */
77 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
78 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
81 if (options.pnn >= nodemap->num) {
82 DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
85 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DELETED) {
86 DEBUG(DEBUG_ERR, ("Node %u is DELETED\n", options.pnn));
89 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
90 DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
94 /* verify we can access the node */
95 ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
97 DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
103 check if a database exists
105 static int db_exists(struct ctdb_context *ctdb, const char *db_name)
108 struct ctdb_dbid_map *dbmap=NULL;
110 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
112 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
116 for(i=0;i<dbmap->num;i++){
119 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
120 if (!strcmp(name, db_name)) {
129 see if a process exists
131 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
139 if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
140 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
144 ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
146 printf("%u:%u exists\n", pnn, pid);
148 printf("%u:%u does not exist\n", pnn, pid);
154 display statistics structure
156 static void show_statistics(struct ctdb_statistics *s)
158 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
160 const char *prefix=NULL;
166 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
167 STATISTICS_FIELD(num_clients),
168 STATISTICS_FIELD(frozen),
169 STATISTICS_FIELD(recovering),
170 STATISTICS_FIELD(client_packets_sent),
171 STATISTICS_FIELD(client_packets_recv),
172 STATISTICS_FIELD(node_packets_sent),
173 STATISTICS_FIELD(node_packets_recv),
174 STATISTICS_FIELD(keepalive_packets_sent),
175 STATISTICS_FIELD(keepalive_packets_recv),
176 STATISTICS_FIELD(node.req_call),
177 STATISTICS_FIELD(node.reply_call),
178 STATISTICS_FIELD(node.req_dmaster),
179 STATISTICS_FIELD(node.reply_dmaster),
180 STATISTICS_FIELD(node.reply_error),
181 STATISTICS_FIELD(node.req_message),
182 STATISTICS_FIELD(node.req_control),
183 STATISTICS_FIELD(node.reply_control),
184 STATISTICS_FIELD(client.req_call),
185 STATISTICS_FIELD(client.req_message),
186 STATISTICS_FIELD(client.req_control),
187 STATISTICS_FIELD(timeouts.call),
188 STATISTICS_FIELD(timeouts.control),
189 STATISTICS_FIELD(timeouts.traverse),
190 STATISTICS_FIELD(total_calls),
191 STATISTICS_FIELD(pending_calls),
192 STATISTICS_FIELD(lockwait_calls),
193 STATISTICS_FIELD(pending_lockwait_calls),
194 STATISTICS_FIELD(childwrite_calls),
195 STATISTICS_FIELD(pending_childwrite_calls),
196 STATISTICS_FIELD(memory_used),
197 STATISTICS_FIELD(max_hop_count),
199 printf("CTDB version %u\n", CTDB_VERSION);
200 for (i=0;i<ARRAY_SIZE(fields);i++) {
201 if (strchr(fields[i].name, '.')) {
202 preflen = strcspn(fields[i].name, ".")+1;
203 if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
204 prefix = fields[i].name;
205 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
210 printf(" %*s%-22s%*s%10u\n",
212 fields[i].name+preflen,
214 *(uint32_t *)(fields[i].offset+(uint8_t *)s));
216 printf(" %-30s %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
217 printf(" %-30s %.6f sec\n", "max_reclock_recd", s->reclock.recd);
219 printf(" %-30s %.6f sec\n", "max_call_latency", s->max_call_latency);
220 printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
221 printf(" %-30s %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
222 talloc_free(tmp_ctx);
226 display remote ctdb statistics combined from all nodes
228 static int control_statistics_all(struct ctdb_context *ctdb)
231 struct ctdb_statistics statistics;
235 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
236 CTDB_NO_MEMORY(ctdb, nodes);
238 ZERO_STRUCT(statistics);
240 for (i=0;i<num_nodes;i++) {
241 struct ctdb_statistics s1;
243 uint32_t *v1 = (uint32_t *)&s1;
244 uint32_t *v2 = (uint32_t *)&statistics;
246 offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
247 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
249 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
252 for (j=0;j<num_ints;j++) {
255 statistics.max_hop_count =
256 MAX(statistics.max_hop_count, s1.max_hop_count);
257 statistics.max_call_latency =
258 MAX(statistics.max_call_latency, s1.max_call_latency);
259 statistics.max_lockwait_latency =
260 MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
263 printf("Gathered statistics for %u nodes\n", num_nodes);
264 show_statistics(&statistics);
269 display remote ctdb statistics
271 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
274 struct ctdb_statistics statistics;
276 if (options.pnn == CTDB_BROADCAST_ALL) {
277 return control_statistics_all(ctdb);
280 ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
282 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
285 show_statistics(&statistics);
291 reset remote ctdb statistics
293 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
297 ret = ctdb_statistics_reset(ctdb, options.pnn);
299 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
307 display uptime of remote node
309 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
312 struct ctdb_uptime *uptime = NULL;
313 int tmp, days, hours, minutes, seconds;
315 ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
317 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
321 if (options.machinereadable){
322 printf(":Current Node Time:Ctdb Start Time:Last Recovery Time:Last Recovery Duration:\n");
323 printf(":%u:%u:%u:%lf\n",
324 (unsigned int)uptime->current_time.tv_sec,
325 (unsigned int)uptime->ctdbd_start_time.tv_sec,
326 (unsigned int)uptime->last_recovery_finished.tv_sec,
327 timeval_delta(&uptime->last_recovery_finished,
328 &uptime->last_recovery_started)
333 printf("Current time of node : %s", ctime(&uptime->current_time.tv_sec));
335 tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
343 printf("Ctdbd start time : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
345 tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
353 printf("Time of last recovery : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
355 printf("Duration of last recovery : %lf seconds\n",
356 timeval_delta(&uptime->last_recovery_finished,
357 &uptime->last_recovery_started));
363 show the PNN of the current node
365 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
369 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
371 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
375 printf("PNN:%d\n", mypnn);
381 struct pnn_node *next;
386 static struct pnn_node *read_nodes_file(TALLOC_CTX *mem_ctx)
388 const char *nodes_list;
392 struct pnn_node *pnn_nodes = NULL;
393 struct pnn_node *pnn_node;
394 struct pnn_node *tmp_node;
396 /* read the nodes file */
397 nodes_list = getenv("CTDB_NODES");
398 if (nodes_list == NULL) {
399 nodes_list = "/etc/ctdb/nodes";
401 lines = file_lines_load(nodes_list, &nlines, mem_ctx);
405 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
408 for (i=0, pnn=0; i<nlines; i++) {
412 /* strip leading spaces */
413 while((*node == ' ') || (*node == '\t')) {
420 if (strcmp(node, "") == 0) {
423 pnn_node = talloc(mem_ctx, struct pnn_node);
424 pnn_node->pnn = pnn++;
425 pnn_node->addr = talloc_strdup(pnn_node, node);
426 pnn_node->next = pnn_nodes;
427 pnn_nodes = pnn_node;
430 /* swap them around so we return them in incrementing order */
431 pnn_node = pnn_nodes;
435 pnn_node = pnn_node->next;
437 tmp_node->next = pnn_nodes;
438 pnn_nodes = tmp_node;
445 show the PNN of the current node
446 discover the pnn by loading the nodes file and try to bind to all
447 addresses one at a time until the ip address is found.
449 static int control_xpnn(struct ctdb_context *ctdb, int argc, const char **argv)
451 TALLOC_CTX *mem_ctx = talloc_new(NULL);
452 struct pnn_node *pnn_nodes;
453 struct pnn_node *pnn_node;
455 pnn_nodes = read_nodes_file(mem_ctx);
456 if (pnn_nodes == NULL) {
457 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
458 talloc_free(mem_ctx);
462 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
465 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
466 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
467 talloc_free(mem_ctx);
471 if (ctdb_sys_have_ip(&addr)) {
472 printf("PNN:%d\n", pnn_node->pnn);
473 talloc_free(mem_ctx);
478 printf("Failed to detect which PNN this node is\n");
479 talloc_free(mem_ctx);
484 display remote ctdb status
486 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
489 struct ctdb_vnn_map *vnnmap=NULL;
490 struct ctdb_node_map *nodemap=NULL;
491 uint32_t recmode, recmaster;
494 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
499 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
501 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
505 if(options.machinereadable){
506 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:\n");
507 for(i=0;i<nodemap->num;i++){
508 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
511 printf(":%d:%s:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
512 ctdb_addr_to_str(&nodemap->nodes[i].addr),
513 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
514 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
515 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
516 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY));
521 printf("Number of nodes:%d\n", nodemap->num);
522 for(i=0;i<nodemap->num;i++){
523 static const struct {
527 { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" },
528 { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" },
529 { NODE_FLAGS_BANNED, "BANNED" },
530 { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" },
531 { NODE_FLAGS_DELETED, "DELETED" },
533 char *flags_str = NULL;
536 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
539 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
540 if (nodemap->nodes[i].flags & flag_names[j].flag) {
541 if (flags_str == NULL) {
542 flags_str = talloc_strdup(ctdb, flag_names[j].name);
544 flags_str = talloc_asprintf_append(flags_str, "|%s",
547 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
550 if (flags_str == NULL) {
551 flags_str = talloc_strdup(ctdb, "OK");
552 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
554 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
555 ctdb_addr_to_str(&nodemap->nodes[i].addr),
557 nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
558 talloc_free(flags_str);
561 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
563 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
566 if (vnnmap->generation == INVALID_GENERATION) {
567 printf("Generation:INVALID\n");
569 printf("Generation:%d\n",vnnmap->generation);
571 printf("Size:%d\n",vnnmap->size);
572 for(i=0;i<vnnmap->size;i++){
573 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
576 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
578 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
581 printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
583 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
585 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
588 printf("Recovery master:%d\n",recmaster);
595 struct natgw_node *next;
600 display the list of nodes belonging to this natgw configuration
602 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
605 const char *natgw_list;
608 struct natgw_node *natgw_nodes = NULL;
609 struct natgw_node *natgw_node;
610 struct ctdb_node_map *nodemap=NULL;
613 /* read the natgw nodes file into a linked list */
614 natgw_list = getenv("NATGW_NODES");
615 if (natgw_list == NULL) {
616 natgw_list = "/etc/ctdb/natgw_nodes";
618 lines = file_lines_load(natgw_list, &nlines, ctdb);
620 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
623 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
626 for (i=0;i<nlines;i++) {
630 /* strip leading spaces */
631 while((*node == ' ') || (*node == '\t')) {
637 if (strcmp(node, "") == 0) {
640 natgw_node = talloc(ctdb, struct natgw_node);
641 natgw_node->addr = talloc_strdup(natgw_node, node);
642 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
643 natgw_node->next = natgw_nodes;
644 natgw_nodes = natgw_node;
647 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
649 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
654 while(i<nodemap->num) {
655 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
656 if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
661 /* this node was not in the natgw so we just remove it from
664 if ((natgw_node == NULL)
665 || (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
668 for (j=i+1; j<nodemap->num; j++) {
669 nodemap->nodes[j-1] = nodemap->nodes[j];
678 /* print the natgw master */
679 for(i=0;i<nodemap->num;i++){
680 if (!(nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
681 printf("%d\n", nodemap->nodes[i].pnn);
686 /* print the pruned list of nodes belonging to this natgw list */
687 for(i=0;i<nodemap->num;i++){
688 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
691 printf(":%d:%s:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
692 ctdb_addr_to_str(&nodemap->nodes[i].addr),
693 !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
694 !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
695 !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
696 !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY));
704 display the status of the monitoring scripts
706 static int control_scriptstatus(struct ctdb_context *ctdb, int argc, const char **argv)
709 struct ctdb_monitoring_wire *script_status;
711 ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, &script_status);
713 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
717 printf("%d scripts were executed last monitoring cycle\n", script_status->num_scripts);
718 for (i=0; i<script_status->num_scripts; i++) {
719 printf("%-20s Status:%s ",
720 script_status->scripts[i].name,
721 script_status->scripts[i].timedout?"TIMEDOUT":script_status->scripts[i].status==0?"OK":"ERROR");
722 if (script_status->scripts[i].timedout == 0) {
723 printf("Duration:%.3lf ",
724 timeval_delta(&script_status->scripts[i].finished,
725 &script_status->scripts[i].start));
728 ctime(&script_status->scripts[i].start.tv_sec));
729 if ((script_status->scripts[i].timedout != 0)
730 || (script_status->scripts[i].status != 0) ) {
731 printf(" OUTPUT:%s\n",
732 script_status->scripts[i].output);
741 display the pnn of the recovery master
743 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
748 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
750 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
753 printf("%d\n",recmaster);
759 get a list of all tickles for this pnn
761 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
763 struct ctdb_control_tcp_tickle_list *list;
771 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
772 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
776 ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
778 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
782 printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
783 printf("Num tickles:%u\n", list->tickles.num);
784 for (i=0;i<list->tickles.num;i++) {
785 printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
786 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));
796 move/failover an ip address to a specific node
798 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
802 struct ctdb_all_public_ips *ips;
803 struct ctdb_public_ip ip;
807 struct ctdb_node_map *nodemap=NULL;
808 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
812 talloc_free(tmp_ctx);
816 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
817 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
818 talloc_free(tmp_ctx);
823 if (sscanf(argv[1], "%u", &pnn) != 1) {
824 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
825 talloc_free(tmp_ctx);
830 /* read the public ip list from the node */
831 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
833 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
834 talloc_free(tmp_ctx);
838 for (i=0;i<ips->num;i++) {
839 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
844 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
845 pnn, ctdb_addr_to_str(&addr)));
846 talloc_free(tmp_ctx);
849 if (ips->ips[i].pnn == pnn) {
850 DEBUG(DEBUG_ERR, ("Host %u is already hosting '%s'\n",
851 pnn, ctdb_addr_to_str(&ips->ips[i].addr)));
852 talloc_free(tmp_ctx);
859 data.dptr = (uint8_t *)&ip;
860 data.dsize = sizeof(ip);
862 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
864 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
865 talloc_free(tmp_ctx);
869 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
870 ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
876 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
877 talloc_free(tmp_ctx);
881 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
883 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
884 talloc_free(tmp_ctx);
888 talloc_free(tmp_ctx);
892 void getips_store_callback(void *param, void *data)
894 struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
895 struct ctdb_all_public_ips *ips = param;
899 ips->ips[i].pnn = node_ip->pnn;
900 ips->ips[i].addr = node_ip->addr;
903 void getips_count_callback(void *param, void *data)
905 uint32_t *count = param;
911 static uint32_t *ip_key(ctdb_sock_addr *ip)
913 static uint32_t key[IP_KEYLEN];
915 bzero(key, sizeof(key));
917 switch (ip->sa.sa_family) {
919 key[0] = ip->ip.sin_addr.s_addr;
922 key[0] = ip->ip6.sin6_addr.s6_addr32[3];
923 key[1] = ip->ip6.sin6_addr.s6_addr32[2];
924 key[2] = ip->ip6.sin6_addr.s6_addr32[1];
925 key[3] = ip->ip6.sin6_addr.s6_addr32[0];
928 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
935 static void *add_ip_callback(void *parm, void *data)
941 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
943 struct ctdb_all_public_ips *tmp_ips;
944 struct ctdb_node_map *nodemap=NULL;
945 trbt_tree_t *ip_tree;
949 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
951 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
955 ip_tree = trbt_create(tmp_ctx, 0);
957 for(i=0;i<nodemap->num;i++){
958 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
961 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
965 /* read the public ip list from this node */
966 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
968 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
972 for (j=0; j<tmp_ips->num;j++) {
973 struct ctdb_public_ip *node_ip;
975 node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
976 node_ip->pnn = tmp_ips->ips[j].pnn;
977 node_ip->addr = tmp_ips->ips[j].addr;
979 trbt_insertarray32_callback(ip_tree,
980 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
984 talloc_free(tmp_ips);
989 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
991 len = offsetof(struct ctdb_all_public_ips, ips) +
992 count*sizeof(struct ctdb_public_ip);
993 tmp_ips = talloc_zero_size(tmp_ctx, len);
994 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1003 * scans all other nodes and returns a pnn for another node that can host this
1007 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1009 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1010 struct ctdb_all_public_ips *ips;
1011 struct ctdb_node_map *nodemap=NULL;
1014 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1016 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1017 talloc_free(tmp_ctx);
1021 for(i=0;i<nodemap->num;i++){
1022 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1025 if (nodemap->nodes[i].pnn == options.pnn) {
1029 /* read the public ip list from this node */
1030 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1032 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1036 for (j=0;j<ips->num;j++) {
1037 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1038 talloc_free(tmp_ctx);
1039 return nodemap->nodes[i].pnn;
1045 talloc_free(tmp_ctx);
1050 add a public ip address to a node
1052 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1057 ctdb_sock_addr addr;
1058 struct ctdb_control_ip_iface *pub;
1059 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1060 struct ctdb_all_public_ips *ips;
1063 talloc_free(tmp_ctx);
1067 if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1068 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1069 talloc_free(tmp_ctx);
1073 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1075 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1076 talloc_free(tmp_ctx);
1081 /* check if some other node is already serving this ip, if not,
1084 for (i=0;i<ips->num;i++) {
1085 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1090 len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1091 pub = talloc_size(tmp_ctx, len);
1092 CTDB_NO_MEMORY(ctdb, pub);
1096 pub->len = strlen(argv[1])+1;
1097 memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1099 ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1101 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1102 talloc_free(tmp_ctx);
1106 /* no one has this ip so we claim it */
1107 if (i == ips->num) {
1108 struct ctdb_public_ip ip;
1110 ip.pnn = options.pnn;
1113 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), options.pnn, &ip);
1115 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", options.pnn));
1122 DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));
1126 talloc_free(tmp_ctx);
1130 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1132 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1134 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1135 struct ctdb_node_map *nodemap=NULL;
1136 struct ctdb_all_public_ips *ips;
1139 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1141 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1145 /* remove it from the nodes that are not hosting the ip currently */
1146 for(i=0;i<nodemap->num;i++){
1147 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1150 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1151 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1155 for (j=0;j<ips->num;j++) {
1156 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1164 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1168 options.pnn = nodemap->nodes[i].pnn;
1169 control_delip(ctdb, argc, argv);
1173 /* remove it from every node (also the one hosting it) */
1174 for(i=0;i<nodemap->num;i++){
1175 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1178 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1179 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1183 for (j=0;j<ips->num;j++) {
1184 if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1192 options.pnn = nodemap->nodes[i].pnn;
1193 control_delip(ctdb, argc, argv);
1196 talloc_free(tmp_ctx);
1201 delete a public ip address from a node
1203 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1206 ctdb_sock_addr addr;
1207 struct ctdb_control_ip_iface pub;
1208 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1209 struct ctdb_all_public_ips *ips;
1212 talloc_free(tmp_ctx);
1216 if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1217 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1221 if (options.pnn == CTDB_BROADCAST_ALL) {
1222 return control_delip_all(ctdb, argc, argv, &addr);
1229 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1231 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1232 talloc_free(tmp_ctx);
1236 for (i=0;i<ips->num;i++) {
1237 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1243 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1244 ctdb_addr_to_str(&addr)));
1245 talloc_free(tmp_ctx);
1249 if (ips->ips[i].pnn == options.pnn) {
1250 ret = find_other_host_for_public_ip(ctdb, &addr);
1252 struct ctdb_public_ip ip;
1257 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), ret, &ip);
1259 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", options.pnn));
1265 ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1267 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1268 talloc_free(tmp_ctx);
1272 talloc_free(tmp_ctx);
1277 kill a tcp connection
1279 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1282 struct ctdb_control_killtcp killtcp;
1288 if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1289 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1293 if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1294 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1298 ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1300 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1311 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1314 ctdb_sock_addr addr;
1320 if (!parse_ip(argv[0], NULL, 0, &addr)) {
1321 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1325 ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1327 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1335 register a server id
1337 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1340 struct ctdb_server_id server_id;
1346 server_id.pnn = strtoul(argv[0], NULL, 0);
1347 server_id.type = strtoul(argv[1], NULL, 0);
1348 server_id.server_id = strtoul(argv[2], NULL, 0);
1350 ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1352 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1359 unregister a server id
1361 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1364 struct ctdb_server_id server_id;
1370 server_id.pnn = strtoul(argv[0], NULL, 0);
1371 server_id.type = strtoul(argv[1], NULL, 0);
1372 server_id.server_id = strtoul(argv[2], NULL, 0);
1374 ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1376 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1383 check if a server id exists
1385 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1389 struct ctdb_server_id server_id;
1395 server_id.pnn = strtoul(argv[0], NULL, 0);
1396 server_id.type = strtoul(argv[1], NULL, 0);
1397 server_id.server_id = strtoul(argv[2], NULL, 0);
1399 ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1401 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1406 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1408 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1414 get a list of all server ids that are registered on a node
1416 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1419 struct ctdb_server_id_list *server_ids;
1421 ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1423 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1427 for (i=0; i<server_ids->num; i++) {
1428 printf("Server id %d:%d:%d\n",
1429 server_ids->server_ids[i].pnn,
1430 server_ids->server_ids[i].type,
1431 server_ids->server_ids[i].server_id);
1438 send a tcp tickle ack
1440 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1443 ctdb_sock_addr src, dst;
1449 if (!parse_ip_port(argv[0], &src)) {
1450 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1454 if (!parse_ip_port(argv[1], &dst)) {
1455 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1459 ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1463 DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1470 display public ip status
1472 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1475 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1476 struct ctdb_all_public_ips *ips;
1478 if (options.pnn == CTDB_BROADCAST_ALL) {
1479 /* read the list of public ips from all nodes */
1480 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1482 /* read the public ip list from this node */
1483 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1486 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1487 talloc_free(tmp_ctx);
1491 if (options.machinereadable){
1492 printf(":Public IP:Node:\n");
1494 if (options.pnn == CTDB_BROADCAST_ALL) {
1495 printf("Public IPs on ALL nodes\n");
1497 printf("Public IPs on node %u\n", options.pnn);
1501 for (i=1;i<=ips->num;i++) {
1502 if (options.machinereadable){
1503 printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1505 printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1509 talloc_free(tmp_ctx);
1514 display pid of a ctdb daemon
1516 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1521 ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1523 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1526 printf("Pid:%d\n", pid);
1532 disable a remote node
1534 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1538 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1540 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1548 enable a disabled remote node
1550 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1554 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1556 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1563 static uint32_t get_generation(struct ctdb_context *ctdb)
1565 struct ctdb_vnn_map *vnnmap=NULL;
1568 /* wait until the recmaster is not in recovery mode */
1570 uint32_t recmode, recmaster;
1572 if (vnnmap != NULL) {
1573 talloc_free(vnnmap);
1577 /* get the recmaster */
1578 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1580 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1584 /* get recovery mode */
1585 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1587 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1591 /* get the current generation number */
1592 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
1594 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
1598 if ((recmode == CTDB_RECOVERY_NORMAL)
1599 && (vnnmap->generation != 1)){
1600 return vnnmap->generation;
1607 ban a node from the cluster
1609 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
1612 struct ctdb_ban_info b;
1615 struct ctdb_node_map *nodemap=NULL;
1616 uint32_t generation, next_generation;
1622 /* record the current generation number */
1623 generation = get_generation(ctdb);
1626 /* verify the node exists */
1627 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1629 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1633 if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
1634 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
1638 ban_time = strtoul(argv[0], NULL, 0);
1640 b.pnn = options.pnn;
1641 b.ban_time = ban_time;
1643 data.dptr = (uint8_t *)&b;
1644 data.dsize = sizeof(b);
1646 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_BAN_NODE, data);
1648 DEBUG(DEBUG_ERR,("Failed to ban node %u\n", options.pnn));
1652 /* wait until we are in a new generation */
1654 next_generation = get_generation(ctdb);
1655 if (next_generation != generation) {
1666 unban a node from the cluster
1668 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
1672 uint32_t generation, next_generation;
1673 struct ctdb_node_map *nodemap=NULL;
1675 /* record the current generation number */
1676 generation = get_generation(ctdb);
1678 data.dptr = (uint8_t *)&options.pnn;
1679 data.dsize = sizeof(uint32_t);
1681 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1683 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1687 if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
1688 DEBUG(DEBUG_ERR, ("Node %d is not banned. Can not unban\n", options.pnn));
1692 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_UNBAN_NODE, data);
1694 DEBUG(DEBUG_ERR,("Failed to to unban node %u\n", options.pnn));
1698 /* wait until we are in a new generation */
1700 next_generation = get_generation(ctdb);
1701 if (next_generation != generation) {
1714 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
1718 ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
1720 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
1730 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
1733 uint32_t generation, next_generation;
1735 /* record the current generation number */
1736 generation = get_generation(ctdb);
1738 ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
1740 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
1744 ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
1746 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
1750 /* wait until we are in a new generation */
1752 next_generation = get_generation(ctdb);
1753 if (next_generation != generation) {
1764 display monitoring mode of a remote node
1766 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
1771 ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
1773 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
1776 if (!options.machinereadable){
1777 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
1780 printf(":%d:\n",monmode);
1787 display capabilities of a remote node
1789 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
1791 uint32_t capabilities;
1794 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
1796 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
1800 if (!options.machinereadable){
1801 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
1802 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
1803 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
1805 printf(":RECMASTER:LMASTER:LVS:\n");
1806 printf(":%d:%d:%d:\n",
1807 !!(capabilities&CTDB_CAP_RECMASTER),
1808 !!(capabilities&CTDB_CAP_LMASTER),
1809 !!(capabilities&CTDB_CAP_LVS));
1815 display lvs configuration
1817 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
1819 uint32_t *capabilities;
1820 struct ctdb_node_map *nodemap=NULL;
1822 int healthy_count = 0;
1824 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
1826 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1830 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
1831 CTDB_NO_MEMORY(ctdb, capabilities);
1833 /* collect capabilities for all connected nodes */
1834 for (i=0; i<nodemap->num; i++) {
1835 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1838 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1842 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
1844 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
1848 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1852 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
1857 /* Print all LVS nodes */
1858 for (i=0; i<nodemap->num; i++) {
1859 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1862 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1865 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1869 if (healthy_count != 0) {
1870 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
1875 printf("%d:%s\n", i,
1876 ctdb_addr_to_str(&nodemap->nodes[i].addr));
1883 display who is the lvs master
1885 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
1887 uint32_t *capabilities;
1888 struct ctdb_node_map *nodemap=NULL;
1890 int healthy_count = 0;
1892 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
1894 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1898 capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
1899 CTDB_NO_MEMORY(ctdb, capabilities);
1901 /* collect capabilities for all connected nodes */
1902 for (i=0; i<nodemap->num; i++) {
1903 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1906 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1910 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
1912 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
1916 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1920 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
1925 /* find and show the lvsmaster */
1926 for (i=0; i<nodemap->num; i++) {
1927 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1930 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1933 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1937 if (healthy_count != 0) {
1938 if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
1943 if (options.machinereadable){
1946 printf("Node %d is LVS master\n", i);
1951 printf("There is no LVS master\n");
1956 disable monitoring on a node
1958 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
1963 ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
1965 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
1968 printf("Monitoring mode:%s\n","DISABLED");
1974 enable monitoring on a node
1976 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
1981 ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
1983 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
1986 printf("Monitoring mode:%s\n","ACTIVE");
1992 display remote list of keys/data for a db
1994 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
1996 const char *db_name;
1997 struct ctdb_db_context *ctdb_db;
2007 if (db_exists(ctdb, db_name)) {
2008 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2012 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2014 if (ctdb_db == NULL) {
2015 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2019 /* traverse and dump the cluster tdb */
2020 ret = ctdb_dump_db(ctdb_db, stdout);
2022 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2025 talloc_free(ctdb_db);
2027 printf("Dumped %d records\n", ret);
2033 display a list of the databases on a remote ctdb
2035 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2038 struct ctdb_dbid_map *dbmap=NULL;
2040 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2042 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2046 printf("Number of databases:%d\n", dbmap->num);
2047 for(i=0;i<dbmap->num;i++){
2052 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2053 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2054 persistent = dbmap->dbs[i].persistent;
2055 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name,
2056 path, persistent?"PERSISTENT":"");
2063 check if the local node is recmaster or not
2064 it will return 1 if this node is the recmaster and 0 if it is not
2065 or if the local ctdb daemon could not be contacted
2067 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2069 uint32_t mypnn, recmaster;
2072 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2074 printf("Failed to get pnn of node\n");
2078 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2080 printf("Failed to get the recmaster\n");
2084 if (recmaster != mypnn) {
2085 printf("this node is not the recmaster\n");
2089 printf("this node is the recmaster\n");
2096 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2099 struct timeval tv = timeval_current();
2100 ret = ctdb_ctrl_ping(ctdb, options.pnn);
2102 printf("Unable to get ping response from node %u\n", options.pnn);
2105 printf("response from %u time=%.6f sec (%d clients)\n",
2106 options.pnn, timeval_elapsed(&tv), ret);
2115 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2126 ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2128 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2132 printf("%-19s = %u\n", name, value);
2139 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2150 value = strtoul(argv[1], NULL, 0);
2152 ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2154 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2163 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2169 ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2171 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2175 for (i=0;i<count;i++) {
2176 control_getvar(ctdb, 1, &list[i]);
2186 const char *description;
2187 } debug_levels[] = {
2188 {DEBUG_EMERG, "EMERG"},
2189 {DEBUG_ALERT, "ALERT"},
2190 {DEBUG_CRIT, "CRIT"},
2192 {DEBUG_WARNING, "WARNING"},
2193 {DEBUG_NOTICE, "NOTICE"},
2194 {DEBUG_INFO, "INFO"},
2195 {DEBUG_DEBUG, "DEBUG"}
2198 static const char *get_debug_by_level(int32_t level)
2202 for (i=0;i<ARRAY_SIZE(debug_levels);i++) {
2203 if (debug_levels[i].level == level) {
2204 return debug_levels[i].description;
2210 static int32_t get_debug_by_desc(const char *desc)
2214 for (i=0;i<ARRAY_SIZE(debug_levels);i++) {
2215 if (!strcmp(debug_levels[i].description, desc)) {
2216 return debug_levels[i].level;
2220 fprintf(stderr, "Invalid debug level '%s'\nMust be one of\n", desc);
2221 for (i=0;i<ARRAY_SIZE(debug_levels);i++) {
2222 fprintf(stderr, " %s\n", debug_levels[i].description);
2229 display debug level on a node
2231 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2236 ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2238 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2241 if (options.machinereadable){
2242 printf(":Name:Level:\n");
2243 printf(":%s:%d:\n",get_debug_by_level(level),level);
2245 printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2253 set debug level on a node or all nodes
2255 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2264 if (isalpha(argv[0][0])) {
2265 level = get_debug_by_desc(argv[0]);
2267 level = strtol(argv[0], NULL, 0);
2270 ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2272 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2281 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2285 ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
2287 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2295 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2299 ret = ctdb_ctrl_thaw(ctdb, TIMELIMIT(), options.pnn);
2301 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2308 attach to a database
2310 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2312 const char *db_name;
2313 struct ctdb_db_context *ctdb_db;
2320 ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2321 if (ctdb_db == NULL) {
2322 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2330 run an eventscript on a node
2332 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
2338 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2341 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2345 data.dptr = (unsigned char *)discard_const(argv[0]);
2346 data.dsize = strlen((char *)data.dptr) + 1;
2348 DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
2350 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
2351 0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2352 if (ret != 0 || res != 0) {
2353 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
2354 talloc_free(tmp_ctx);
2357 talloc_free(tmp_ctx);
2361 #define DB_VERSION 1
2362 #define MAX_DB_NAME 64
2363 struct db_file_header {
2364 unsigned long version;
2366 unsigned long persistent;
2368 const char name[MAX_DB_NAME];
2371 struct backup_data {
2372 struct ctdb_marshall_buffer *records;
2375 bool traverse_error;
2378 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
2380 struct backup_data *bd = talloc_get_type(private, struct backup_data);
2381 struct ctdb_rec_data *rec;
2383 /* add the record */
2384 rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
2386 bd->traverse_error = true;
2387 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
2390 bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
2391 if (bd->records == NULL) {
2392 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
2393 bd->traverse_error = true;
2396 bd->records->count++;
2397 memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
2398 bd->len += rec->length;
2406 * backup a database to a file
2408 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
2411 struct ctdb_dbid_map *dbmap=NULL;
2412 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2413 struct db_file_header dbhdr;
2414 struct ctdb_db_context *ctdb_db;
2415 struct backup_data *bd;
2420 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2424 ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
2426 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2430 for(i=0;i<dbmap->num;i++){
2433 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
2434 if(!strcmp(argv[0], name)){
2435 talloc_free(discard_const(name));
2438 talloc_free(discard_const(name));
2440 if (i == dbmap->num) {
2441 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
2442 talloc_free(tmp_ctx);
2447 ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
2448 if (ctdb_db == NULL) {
2449 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
2450 talloc_free(tmp_ctx);
2455 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
2457 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
2458 talloc_free(tmp_ctx);
2463 bd = talloc_zero(tmp_ctx, struct backup_data);
2465 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
2466 talloc_free(tmp_ctx);
2470 bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
2471 if (bd->records == NULL) {
2472 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
2473 talloc_free(tmp_ctx);
2477 bd->len = offsetof(struct ctdb_marshall_buffer, data);
2478 bd->records->db_id = ctdb_db->db_id;
2479 /* traverse the database collecting all records */
2480 if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
2481 bd->traverse_error) {
2482 DEBUG(DEBUG_ERR,("Traverse error\n"));
2483 talloc_free(tmp_ctx);
2487 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2490 fh = open(argv[1], O_RDWR|O_CREAT, 0600);
2492 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
2493 talloc_free(tmp_ctx);
2497 dbhdr.version = DB_VERSION;
2498 dbhdr.timestamp = time(NULL);
2499 dbhdr.persistent = dbmap->dbs[i].persistent;
2500 dbhdr.size = bd->len;
2501 if (strlen(argv[0]) >= MAX_DB_NAME) {
2502 DEBUG(DEBUG_ERR,("Too long dbname\n"));
2505 strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
2506 ret = write(fh, &dbhdr, sizeof(dbhdr));
2508 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
2511 ret = write(fh, bd->records, bd->len);
2513 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
2522 DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
2525 talloc_free(tmp_ctx);
2530 * restore a database from a file
2532 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
2535 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2538 struct db_file_header dbhdr;
2539 struct ctdb_db_context *ctdb_db;
2540 struct ctdb_node_map *nodemap=NULL;
2541 struct ctdb_vnn_map *vnnmap=NULL;
2543 struct ctdb_control_wipe_database w;
2545 uint32_t generation;
2550 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2554 fh = open(argv[0], O_RDONLY);
2556 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
2557 talloc_free(tmp_ctx);
2561 read(fh, &dbhdr, sizeof(dbhdr));
2562 if (dbhdr.version != DB_VERSION) {
2563 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
2564 talloc_free(tmp_ctx);
2568 outdata.dsize = dbhdr.size;
2569 outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
2570 if (outdata.dptr == NULL) {
2571 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
2573 talloc_free(tmp_ctx);
2576 read(fh, outdata.dptr, outdata.dsize);
2579 tm = localtime(&dbhdr.timestamp);
2580 strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
2581 printf("Restoring database '%s' from backup @ %s\n",
2585 ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
2586 if (ctdb_db == NULL) {
2587 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
2588 talloc_free(tmp_ctx);
2592 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2594 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2595 talloc_free(tmp_ctx);
2600 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
2602 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
2603 talloc_free(tmp_ctx);
2607 /* freeze all nodes */
2608 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2609 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
2614 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
2615 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2616 talloc_free(tmp_ctx);
2620 generation = vnnmap->generation;
2621 data.dptr = (void *)&generation;
2622 data.dsize = sizeof(generation);
2624 /* start a cluster wide transaction */
2625 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2626 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
2628 TIMELIMIT(), false, data,
2631 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
2636 w.db_id = ctdb_db->db_id;
2637 w.transaction_id = generation;
2639 data.dptr = (void *)&w;
2640 data.dsize = sizeof(w);
2642 /* wipe all the remote databases. */
2643 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2644 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
2646 TIMELIMIT(), false, data,
2649 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
2650 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2651 talloc_free(tmp_ctx);
2655 /* push the database */
2656 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2657 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
2659 TIMELIMIT(), false, outdata,
2662 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
2663 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2664 talloc_free(tmp_ctx);
2668 data.dptr = (void *)&generation;
2669 data.dsize = sizeof(generation);
2671 /* commit all the changes */
2672 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
2674 TIMELIMIT(), false, data,
2677 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
2678 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2679 talloc_free(tmp_ctx);
2684 /* thaw all nodes */
2685 nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2686 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
2691 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
2692 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2693 talloc_free(tmp_ctx);
2698 talloc_free(tmp_ctx);
2703 * set flags of a node in the nodemap
2705 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
2712 struct ctdb_node_flag_change c;
2719 if (sscanf(argv[0], "%d", &node) != 1) {
2720 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
2724 if (sscanf(argv[1], "0x%x", &flags) != 1) {
2725 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
2732 c.new_flags = flags;
2734 data.dsize = sizeof(c);
2735 data.dptr = (unsigned char *)&c;
2737 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0,
2738 data, NULL, NULL, &status, NULL, NULL);
2739 if (ret != 0 || status != 0) {
2740 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
2749 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
2755 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2756 ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
2757 0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
2758 if (ret != 0 || res != 0) {
2759 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
2760 talloc_free(tmp_ctx);
2763 write(1, data.dptr, data.dsize);
2764 talloc_free(tmp_ctx);
2769 handler for memory dumps
2771 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid,
2772 TDB_DATA data, void *private_data)
2774 write(1, data.dptr, data.dsize);
2779 dump memory usage on the recovery daemon
2781 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
2785 struct rd_memdump_reply rd;
2787 rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2789 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
2792 rd.srvid = getpid();
2794 /* register a message port for receiveing the reply so that we
2795 can receive the reply
2797 ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
2800 data.dptr = (uint8_t *)&rd;
2801 data.dsize = sizeof(rd);
2803 ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
2805 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
2809 /* this loop will terminate when we have received the reply */
2811 event_loop_once(ctdb->ev);
2818 list all nodes in the cluster
2819 if the daemon is running, we read the data from the daemon.
2820 if the daemon is not running we parse the nodes file directly
2822 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
2825 struct ctdb_node_map *nodemap=NULL;
2828 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2830 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2834 for(i=0;i<nodemap->num;i++){
2835 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
2838 if (options.machinereadable){
2839 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
2841 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
2845 TALLOC_CTX *mem_ctx = talloc_new(NULL);
2846 struct pnn_node *pnn_nodes;
2847 struct pnn_node *pnn_node;
2849 pnn_nodes = read_nodes_file(mem_ctx);
2850 if (pnn_nodes == NULL) {
2851 DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
2852 talloc_free(mem_ctx);
2856 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
2857 ctdb_sock_addr addr;
2859 if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
2860 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
2861 talloc_free(mem_ctx);
2865 if (options.machinereadable){
2866 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
2868 printf("%s\n", pnn_node->addr);
2871 talloc_free(mem_ctx);
2878 reload the nodes file on the local node
2880 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
2884 struct ctdb_node_map *nodemap=NULL;
2886 mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2888 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
2892 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2894 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2898 /* reload the nodes file on all remote nodes */
2899 for (i=0;i<nodemap->num;i++) {
2900 if (nodemap->nodes[i].pnn == mypnn) {
2903 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
2904 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
2905 nodemap->nodes[i].pnn);
2907 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
2911 /* reload the nodes file on the local node */
2912 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
2913 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
2915 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
2918 /* initiate a recovery */
2919 control_recover(ctdb, argc, argv);
2925 static const struct {
2927 int (*fn)(struct ctdb_context *, int, const char **);
2929 bool without_daemon; /* can be run without daemon running ? */
2932 } ctdb_commands[] = {
2934 { "version", control_version, true, false, "show version of ctdb" },
2936 { "status", control_status, true, false, "show node status" },
2937 { "uptime", control_uptime, true, false, "show node uptime" },
2938 { "ping", control_ping, true, false, "ping all nodes" },
2939 { "getvar", control_getvar, true, false, "get a tunable variable", "<name>"},
2940 { "setvar", control_setvar, true, false, "set a tunable variable", "<name> <value>"},
2941 { "listvars", control_listvars, true, false, "list tunable variables"},
2942 { "statistics", control_statistics, false, false, "show statistics" },
2943 { "statisticsreset", control_statistics_reset, true, false, "reset statistics"},
2944 { "ip", control_ip, false, false, "show which public ip's that ctdb manages" },
2945 { "process-exists", control_process_exists, true, false, "check if a process exists on a node", "<pid>"},
2946 { "getdbmap", control_getdbmap, true, false, "show the database map" },
2947 { "catdb", control_catdb, true, false, "dump a database" , "<dbname>"},
2948 { "getmonmode", control_getmonmode, true, false, "show monitoring mode" },
2949 { "getcapabilities", control_getcapabilities, true, false, "show node capabilities" },
2950 { "pnn", control_pnn, true, false, "show the pnn of the currnet node" },
2951 { "lvs", control_lvs, true, false, "show lvs configuration" },
2952 { "lvsmaster", control_lvsmaster, true, false, "show which node is the lvs master" },
2953 { "disablemonitor", control_disable_monmode,true, false, "set monitoring mode to DISABLE" },
2954 { "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
2955 { "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
2956 { "getdebug", control_getdebug, true, false, "get debug level" },
2957 { "attach", control_attach, true, false, "attach to a database", "<dbname>" },
2958 { "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },
2959 { "rddumpmemory", control_rddumpmemory, true, false, "dump memory map from the recovery daemon to stdout" },
2960 { "getpid", control_getpid, true, false, "get ctdbd process ID" },
2961 { "disable", control_disable, true, false, "disable a nodes public IP" },
2962 { "enable", control_enable, true, false, "enable a nodes public IP" },
2963 { "ban", control_ban, true, false, "ban a node from the cluster", "<bantime|0>"},
2964 { "unban", control_unban, true, false, "unban a node from the cluster" },
2965 { "shutdown", control_shutdown, true, false, "shutdown ctdbd" },
2966 { "recover", control_recover, true, false, "force recovery" },
2967 { "freeze", control_freeze, true, false, "freeze all databases" },
2968 { "thaw", control_thaw, true, false, "thaw all databases" },
2969 { "isnotrecmaster", control_isnotrecmaster, false, false, "check if the local node is recmaster or not" },
2970 { "killtcp", kill_tcp, false, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
2971 { "gratiousarp", control_gratious_arp, false, false, "send a gratious arp", "<ip> <interface>" },
2972 { "tickle", tickle_tcp, false, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
2973 { "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
2975 { "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
2976 { "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
2977 { "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },
2978 { "getsrvids", getsrvids, false, false, "get a list of all server ids"},
2979 { "vacuum", ctdb_vacuum, false, false, "vacuum the databases of empty records", "[max_records]"},
2980 { "repack", ctdb_repack, false, false, "repack all databases", "[max_freelist]"},
2981 { "listnodes", control_listnodes, false, true, "list all nodes in the cluster"},
2982 { "reloadnodes", control_reload_nodes_file, false, false, "reload the nodes file and restart the transport on all nodes"},
2983 { "moveip", control_moveip, false, false, "move/failover an ip address to another node", "<ip> <node>"},
2984 { "addip", control_addip, true, false, "add a ip address to a node", "<ip/mask> <iface>"},
2985 { "delip", control_delip, false, false, "delete an ip address from a node", "<ip>"},
2986 { "eventscript", control_eventscript, true, false, "run the eventscript with the given parameters on a node", "<arguments>"},
2987 { "backupdb", control_backupdb, false, false, "backup the database into a file.", "<database> <file>"},
2988 { "restoredb", control_restoredb, false, false, "restore the database from a file.", "<file>"},
2989 { "recmaster", control_recmaster, false, false, "show the pnn for the recovery master."},
2990 { "setflags", control_setflags, false, false, "set flags for a node in the nodemap.", "<node> <flags>"},
2991 { "scriptstatus", control_scriptstatus, false, false, "show the status of the monitoring scripts"},
2992 { "natgwlist", control_natgwlist, false, false, "show the nodes belonging to this natgw configuration"},
2993 { "xpnn", control_xpnn, true, true, "find the pnn of the local node without talking to the daemon (unreliable)" },
2999 static void usage(void)
3003 "Usage: ctdb [options] <control>\n" \
3005 " -n <node> choose node number, or 'all' (defaults to local node)\n"
3006 " -Y generate machinereadable output\n"
3007 " -t <timelimit> set timelimit for control in seconds (default %u)\n", options.timelimit);
3008 printf("Controls:\n");
3009 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3010 printf(" %-15s %-27s %s\n",
3011 ctdb_commands[i].name,
3012 ctdb_commands[i].args?ctdb_commands[i].args:"",
3013 ctdb_commands[i].msg);
3019 static void ctdb_alarm(int sig)
3021 printf("Maximum runtime exceeded - exiting\n");
3028 int main(int argc, const char *argv[])
3030 struct ctdb_context *ctdb;
3031 char *nodestring = NULL;
3032 struct poptOption popt_options[] = {
3035 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3036 { "node", 'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3037 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3038 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3042 const char **extra_argv;
3046 struct event_context *ev;
3047 const char *control;
3051 /* set some defaults */
3052 options.maxruntime = 0;
3053 options.timelimit = 3;
3054 options.pnn = CTDB_CURRENT_NODE;
3056 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3058 while ((opt = poptGetNextOpt(pc)) != -1) {
3061 DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n",
3062 poptBadOption(pc, 0), poptStrerror(opt)));
3067 /* setup the remaining options for the main program to use */
3068 extra_argv = poptGetArgs(pc);
3071 while (extra_argv[extra_argc]) extra_argc++;
3074 if (extra_argc < 1) {
3078 if (options.maxruntime == 0) {
3079 const char *ctdb_timeout;
3080 ctdb_timeout = getenv("CTDB_TIMEOUT");
3081 if (ctdb_timeout != NULL) {
3082 options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3085 if (options.maxruntime != 0) {
3086 signal(SIGALRM, ctdb_alarm);
3087 alarm(options.maxruntime);
3090 /* setup the node number to contact */
3091 if (nodestring != NULL) {
3092 if (strcmp(nodestring, "all") == 0) {
3093 options.pnn = CTDB_BROADCAST_ALL;
3095 options.pnn = strtoul(nodestring, NULL, 0);
3099 control = extra_argv[0];
3101 ev = event_context_init(NULL);
3103 for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3104 if (strcmp(control, ctdb_commands[i].name) == 0) {
3107 if (ctdb_commands[i].without_daemon == true) {
3111 /* initialise ctdb */
3112 ctdb = ctdb_cmdline_client(ev);
3114 if (ctdb_commands[i].without_daemon == false) {
3116 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3120 /* verify the node exists */
3123 if (options.pnn == CTDB_CURRENT_NODE) {
3125 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
3133 if (ctdb_commands[i].auto_all &&
3134 options.pnn == CTDB_BROADCAST_ALL) {
3139 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
3140 CTDB_NO_MEMORY(ctdb, nodes);
3142 for (j=0;j<num_nodes;j++) {
3143 options.pnn = nodes[j];
3144 ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3148 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3154 if (i == ARRAY_SIZE(ctdb_commands)) {
3155 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));