Merge root@10.1.1.27:/shared/ctdb/ctdb-git
[metze/ctdb/wip.git] / tools / ctdb.c
1 /* 
2    ctdb control tool
3
4    Copyright (C) Andrew Tridgell  2007
5    Copyright (C) Ronnie Sahlberg  2007
6
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.
11    
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.
16    
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/>.
19 */
20
21 #include "includes.h"
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"
27 #include "popt.h"
28 #include "cmdline.h"
29 #include "../include/ctdb.h"
30 #include "../include/ctdb_private.h"
31 #include "../common/rb_tree.h"
32 #include "db_wrap.h"
33
34
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 */
38
39 static void usage(void);
40
41 static struct {
42         int timelimit;
43         uint32_t pnn;
44         int machinereadable;
45         int maxruntime;
46 } options;
47
48 #define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
49
50 #ifdef CTDB_VERS
51 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
52 {
53 #define STR(x) #x
54 #define XSTR(x) STR(x)
55         printf("CTDB version: %s\n", XSTR(CTDB_VERS));
56         return 0;
57 }
58 #endif
59
60
61 /*
62   verify that a node exists and is reachable
63  */
64 static void verify_node(struct ctdb_context *ctdb)
65 {
66         int ret;
67         struct ctdb_node_map *nodemap=NULL;
68
69         if (options.pnn == CTDB_CURRENT_NODE) {
70                 return;
71         }
72         if (options.pnn == CTDB_BROADCAST_ALL) {
73                 return;
74         }
75
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"));
79                 exit(10);
80         }
81         if (options.pnn >= nodemap->num) {
82                 DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
83                 exit(ERR_NONODE);
84         }
85         if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DELETED) {
86                 DEBUG(DEBUG_ERR, ("Node %u is DELETED\n", options.pnn));
87                 exit(ERR_DISNODE);
88         }
89         if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
90                 DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
91                 exit(ERR_DISNODE);
92         }
93
94         /* verify we can access the node */
95         ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
96         if (ret == -1) {
97                 DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
98                 exit(10);
99         }
100 }
101
102 /*
103  check if a database exists
104 */
105 static int db_exists(struct ctdb_context *ctdb, const char *db_name)
106 {
107         int i, ret;
108         struct ctdb_dbid_map *dbmap=NULL;
109
110         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
111         if (ret != 0) {
112                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
113                 return -1;
114         }
115
116         for(i=0;i<dbmap->num;i++){
117                 const char *name;
118
119                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
120                 if (!strcmp(name, db_name)) {
121                         return 0;
122                 }
123         }
124
125         return -1;
126 }
127
128 /*
129   see if a process exists
130  */
131 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
132 {
133         uint32_t pnn, pid;
134         int ret;
135         if (argc < 1) {
136                 usage();
137         }
138
139         if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
140                 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
141                 return -1;
142         }
143
144         ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
145         if (ret == 0) {
146                 printf("%u:%u exists\n", pnn, pid);
147         } else {
148                 printf("%u:%u does not exist\n", pnn, pid);
149         }
150         return ret;
151 }
152
153 /*
154   display statistics structure
155  */
156 static void show_statistics(struct ctdb_statistics *s)
157 {
158         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
159         int i;
160         const char *prefix=NULL;
161         int preflen=0;
162         const struct {
163                 const char *name;
164                 uint32_t offset;
165         } fields[] = {
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),
198         };
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);
206                         }
207                 } else {
208                         preflen = 0;
209                 }
210                 printf(" %*s%-22s%*s%10u\n", 
211                        preflen?4:0, "",
212                        fields[i].name+preflen, 
213                        preflen?0:4, "",
214                        *(uint32_t *)(fields[i].offset+(uint8_t *)s));
215         }
216         printf(" %-30s     %.6f sec\n", "max_reclock_ctdbd", s->reclock.ctdbd);
217         printf(" %-30s     %.6f sec\n", "max_reclock_recd", s->reclock.recd);
218
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);
223 }
224
225 /*
226   display remote ctdb statistics combined from all nodes
227  */
228 static int control_statistics_all(struct ctdb_context *ctdb)
229 {
230         int ret, i;
231         struct ctdb_statistics statistics;
232         uint32_t *nodes;
233         uint32_t num_nodes;
234
235         nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
236         CTDB_NO_MEMORY(ctdb, nodes);
237         
238         ZERO_STRUCT(statistics);
239
240         for (i=0;i<num_nodes;i++) {
241                 struct ctdb_statistics s1;
242                 int j;
243                 uint32_t *v1 = (uint32_t *)&s1;
244                 uint32_t *v2 = (uint32_t *)&statistics;
245                 uint32_t num_ints = 
246                         offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
247                 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
248                 if (ret != 0) {
249                         DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
250                         return ret;
251                 }
252                 for (j=0;j<num_ints;j++) {
253                         v2[j] += v1[j];
254                 }
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);
261         }
262         talloc_free(nodes);
263         printf("Gathered statistics for %u nodes\n", num_nodes);
264         show_statistics(&statistics);
265         return 0;
266 }
267
268 /*
269   display remote ctdb statistics
270  */
271 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
272 {
273         int ret;
274         struct ctdb_statistics statistics;
275
276         if (options.pnn == CTDB_BROADCAST_ALL) {
277                 return control_statistics_all(ctdb);
278         }
279
280         ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
281         if (ret != 0) {
282                 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
283                 return ret;
284         }
285         show_statistics(&statistics);
286         return 0;
287 }
288
289
290 /*
291   reset remote ctdb statistics
292  */
293 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
294 {
295         int ret;
296
297         ret = ctdb_statistics_reset(ctdb, options.pnn);
298         if (ret != 0) {
299                 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
300                 return ret;
301         }
302         return 0;
303 }
304
305
306 /*
307   display uptime of remote node
308  */
309 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
310 {
311         int ret;
312         struct ctdb_uptime *uptime = NULL;
313         int tmp, days, hours, minutes, seconds;
314
315         ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
316         if (ret != 0) {
317                 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
318                 return ret;
319         }
320
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)
329                 );
330                 return 0;
331         }
332
333         printf("Current time of node  : %s", ctime(&uptime->current_time.tv_sec));
334
335         tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
336         seconds = tmp%60;
337         tmp    /= 60;
338         minutes = tmp%60;
339         tmp    /= 60;
340         hours   = tmp%24;
341         tmp    /= 24;
342         days    = tmp;
343         printf("Ctdbd start time      : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
344
345         tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
346         seconds = tmp%60;
347         tmp    /= 60;
348         minutes = tmp%60;
349         tmp    /= 60;
350         hours   = tmp%24;
351         tmp    /= 24;
352         days    = tmp;
353         printf("Time of last recovery : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
354         
355         printf("Duration of last recovery : %lf seconds\n",
356                 timeval_delta(&uptime->last_recovery_finished,
357                               &uptime->last_recovery_started));
358
359         return 0;
360 }
361
362 /*
363   show the PNN of the current node
364  */
365 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
366 {
367         int mypnn;
368
369         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
370         if (mypnn == -1) {
371                 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
372                 return -1;
373         }
374
375         printf("PNN:%d\n", mypnn);
376         return 0;
377 }
378
379
380 struct pnn_node {
381         struct pnn_node *next;
382         const char *addr;
383         int pnn;
384 };
385
386 static struct pnn_node *read_nodes_file(TALLOC_CTX *mem_ctx)
387 {
388         const char *nodes_list;
389         int nlines;
390         char **lines;
391         int i, pnn;
392         struct pnn_node *pnn_nodes = NULL;
393         struct pnn_node *pnn_node;
394         struct pnn_node *tmp_node;
395
396         /* read the nodes file */
397         nodes_list = getenv("CTDB_NODES");
398         if (nodes_list == NULL) {
399                 nodes_list = "/etc/ctdb/nodes";
400         }
401         lines = file_lines_load(nodes_list, &nlines, mem_ctx);
402         if (lines == NULL) {
403                 return NULL;
404         }
405         while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
406                 nlines--;
407         }
408         for (i=0, pnn=0; i<nlines; i++) {
409                 char *node;
410
411                 node = lines[i];
412                 /* strip leading spaces */
413                 while((*node == ' ') || (*node == '\t')) {
414                         node++;
415                 }
416                 if (*node == '#') {
417                         pnn++;
418                         continue;
419                 }
420                 if (strcmp(node, "") == 0) {
421                         continue;
422                 }
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;
428         }
429
430         /* swap them around so we return them in incrementing order */
431         pnn_node = pnn_nodes;
432         pnn_nodes = NULL;
433         while (pnn_node) {
434                 tmp_node = pnn_node;
435                 pnn_node = pnn_node->next;
436
437                 tmp_node->next = pnn_nodes;
438                 pnn_nodes = tmp_node;
439         }
440
441         return pnn_nodes;
442 }
443
444 /*
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.
448  */
449 static int control_xpnn(struct ctdb_context *ctdb, int argc, const char **argv)
450 {
451         TALLOC_CTX *mem_ctx = talloc_new(NULL);
452         struct pnn_node *pnn_nodes;
453         struct pnn_node *pnn_node;
454
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);
459                 return -1;
460         }
461
462         for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
463                 ctdb_sock_addr addr;
464
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);
468                         return -1;
469                 }
470
471                 if (ctdb_sys_have_ip(&addr)) {
472                         printf("PNN:%d\n", pnn_node->pnn);
473                         talloc_free(mem_ctx);
474                         return 0;
475                 }
476         }
477
478         printf("Failed to detect which PNN this node is\n");
479         talloc_free(mem_ctx);
480         return -1;
481 }
482
483 /*
484   display remote ctdb status
485  */
486 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
487 {
488         int i, ret;
489         struct ctdb_vnn_map *vnnmap=NULL;
490         struct ctdb_node_map *nodemap=NULL;
491         uint32_t recmode, recmaster;
492         int mypnn;
493
494         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
495         if (mypnn == -1) {
496                 return -1;
497         }
498
499         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
500         if (ret != 0) {
501                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
502                 return ret;
503         }
504
505         if(options.machinereadable){
506                 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:Stopped:\n");
507                 for(i=0;i<nodemap->num;i++){
508                         if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
509                                 continue;
510                         }
511                         printf(":%d:%s:%d:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
512                                 ctdb_addr_to_str(&nodemap->nodes[i].addr),
513                                !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
514                                !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
515                                !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
516                                !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
517                                !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
518                 }
519                 return 0;
520         }
521
522         printf("Number of nodes:%d\n", nodemap->num);
523         for(i=0;i<nodemap->num;i++){
524                 static const struct {
525                         uint32_t flag;
526                         const char *name;
527                 } flag_names[] = {
528                         { NODE_FLAGS_DISCONNECTED,          "DISCONNECTED" },
529                         { NODE_FLAGS_PERMANENTLY_DISABLED,  "DISABLED" },
530                         { NODE_FLAGS_BANNED,                "BANNED" },
531                         { NODE_FLAGS_UNHEALTHY,             "UNHEALTHY" },
532                         { NODE_FLAGS_DELETED,               "DELETED" },
533                         { NODE_FLAGS_STOPPED,               "STOPPED" },
534                 };
535                 char *flags_str = NULL;
536                 int j;
537
538                 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
539                         continue;
540                 }
541                 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
542                         if (nodemap->nodes[i].flags & flag_names[j].flag) {
543                                 if (flags_str == NULL) {
544                                         flags_str = talloc_strdup(ctdb, flag_names[j].name);
545                                 } else {
546                                         flags_str = talloc_asprintf_append(flags_str, "|%s",
547                                                                            flag_names[j].name);
548                                 }
549                                 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
550                         }
551                 }
552                 if (flags_str == NULL) {
553                         flags_str = talloc_strdup(ctdb, "OK");
554                         CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
555                 }
556                 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
557                        ctdb_addr_to_str(&nodemap->nodes[i].addr),
558                        flags_str,
559                        nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
560                 talloc_free(flags_str);
561         }
562
563         ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
564         if (ret != 0) {
565                 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
566                 return ret;
567         }
568         if (vnnmap->generation == INVALID_GENERATION) {
569                 printf("Generation:INVALID\n");
570         } else {
571                 printf("Generation:%d\n",vnnmap->generation);
572         }
573         printf("Size:%d\n",vnnmap->size);
574         for(i=0;i<vnnmap->size;i++){
575                 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
576         }
577
578         ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
579         if (ret != 0) {
580                 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
581                 return ret;
582         }
583         printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
584
585         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
586         if (ret != 0) {
587                 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
588                 return ret;
589         }
590         printf("Recovery master:%d\n",recmaster);
591
592         return 0;
593 }
594
595
596 struct natgw_node {
597         struct natgw_node *next;
598         const char *addr;
599 };
600
601 /*
602   display the list of nodes belonging to this natgw configuration
603  */
604 static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
605 {
606         int i, ret;
607         const char *natgw_list;
608         int nlines;
609         char **lines;
610         struct natgw_node *natgw_nodes = NULL;
611         struct natgw_node *natgw_node;
612         struct ctdb_node_map *nodemap=NULL;
613
614
615         /* read the natgw nodes file into a linked list */
616         natgw_list = getenv("NATGW_NODES");
617         if (natgw_list == NULL) {
618                 natgw_list = "/etc/ctdb/natgw_nodes";
619         }
620         lines = file_lines_load(natgw_list, &nlines, ctdb);
621         if (lines == NULL) {
622                 ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
623                 return -1;
624         }
625         while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
626                 nlines--;
627         }
628         for (i=0;i<nlines;i++) {
629                 char *node;
630
631                 node = lines[i];
632                 /* strip leading spaces */
633                 while((*node == ' ') || (*node == '\t')) {
634                         node++;
635                 }
636                 if (*node == '#') {
637                         continue;
638                 }
639                 if (strcmp(node, "") == 0) {
640                         continue;
641                 }
642                 natgw_node = talloc(ctdb, struct natgw_node);
643                 natgw_node->addr = talloc_strdup(natgw_node, node);
644                 CTDB_NO_MEMORY(ctdb, natgw_node->addr);
645                 natgw_node->next = natgw_nodes;
646                 natgw_nodes = natgw_node;
647         }
648
649         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
650         if (ret != 0) {
651                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
652                 return ret;
653         }
654
655         i=0;
656         while(i<nodemap->num) {
657                 for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
658                         if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
659                                 break;
660                         }
661                 }
662
663                 /* this node was not in the natgw so we just remove it from
664                  * the list
665                  */
666                 if ((natgw_node == NULL) 
667                 ||  (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
668                         int j;
669
670                         for (j=i+1; j<nodemap->num; j++) {
671                                 nodemap->nodes[j-1] = nodemap->nodes[j];
672                         }
673                         nodemap->num--;
674                         continue;
675                 }
676
677                 i++;
678         }               
679
680         /* print the natgw master
681          * we dont allow STOPPED or DELETED nodes to become the natgwmaster
682          */
683         for(i=0;i<nodemap->num;i++){
684                 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_STOPPED|NODE_FLAGS_DELETED))) {
685                         printf("%d %s\n", nodemap->nodes[i].pnn,ctdb_addr_to_str(&nodemap->nodes[i].addr));
686                         break;
687                 }
688         }
689         /* unless all nodes are STOPPED, when we pick one anyway */
690         if (i == nodemap->num) {
691                 for(i=0;i<nodemap->num;i++){
692                         if (!(nodemap->nodes[i].flags & (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED))) {
693                                 printf("%d %s\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
694                                 break;
695                         }
696                 }
697                 /* or if we still can not find any */
698                 if (i == nodemap->num) {
699                         printf("-1 0.0.0.0\n");
700                 }
701         }
702
703         /* print the pruned list of nodes belonging to this natgw list */
704         for(i=0;i<nodemap->num;i++){
705                 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
706                         continue;
707                 }
708                 printf(":%d:%s:%d:%d:%d:%d:%d\n", nodemap->nodes[i].pnn,
709                         ctdb_addr_to_str(&nodemap->nodes[i].addr),
710                        !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
711                        !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
712                        !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
713                        !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY),
714                        !!(nodemap->nodes[i].flags&NODE_FLAGS_STOPPED));
715         }
716
717         return 0;
718 }
719
720
721 /*
722   display the status of the monitoring scripts
723  */
724 static int control_scriptstatus(struct ctdb_context *ctdb, int argc, const char **argv)
725 {
726         int i, ret;
727         struct ctdb_monitoring_wire *script_status;
728
729         ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, &script_status);
730         if (ret != 0) {
731                 DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
732                 return ret;
733         }
734
735         printf("%d scripts were executed last monitoring cycle\n", script_status->num_scripts);
736         for (i=0; i<script_status->num_scripts; i++) {
737                 if (script_status->scripts[i].disabled) {
738                         printf("%-20s Status:DISABLED\n",
739                                 script_status->scripts[i].name);
740                         continue;
741                 } 
742                 printf("%-20s Status:%s    ",
743                         script_status->scripts[i].name,
744                         script_status->scripts[i].timedout?"TIMEDOUT":script_status->scripts[i].status==0?"OK":"ERROR");
745                 if (script_status->scripts[i].timedout == 0) {
746                         printf("Duration:%.3lf ",
747                         timeval_delta(&script_status->scripts[i].finished,
748                               &script_status->scripts[i].start));
749                 }
750                 printf("%s",
751                         ctime(&script_status->scripts[i].start.tv_sec));
752                 if ((script_status->scripts[i].timedout != 0)
753                 ||  (script_status->scripts[i].status != 0) ) {
754                         printf("   OUTPUT:%s\n",
755                                 script_status->scripts[i].output);
756                 }
757         }
758
759         return 0;
760 }
761         
762
763 /*
764   enable an eventscript
765  */
766 static int control_enablescript(struct ctdb_context *ctdb, int argc, const char **argv)
767 {
768         int ret;
769
770         if (argc < 1) {
771                 usage();
772         }
773
774         ret = ctdb_ctrl_enablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
775         if (ret != 0) {
776           DEBUG(DEBUG_ERR, ("Unable to enable script %s on node %u\n", argv[0], options.pnn));
777                 return ret;
778         }
779
780         return 0;
781 }
782
783 /*
784   disable an eventscript
785  */
786 static int control_disablescript(struct ctdb_context *ctdb, int argc, const char **argv)
787 {
788         int ret;
789
790         if (argc < 1) {
791                 usage();
792         }
793
794         ret = ctdb_ctrl_disablescript(ctdb, TIMELIMIT(), options.pnn, argv[0]);
795         if (ret != 0) {
796           DEBUG(DEBUG_ERR, ("Unable to disable script %s on node %u\n", argv[0], options.pnn));
797                 return ret;
798         }
799
800         return 0;
801 }
802
803 /*
804   display the pnn of the recovery master
805  */
806 static int control_recmaster(struct ctdb_context *ctdb, int argc, const char **argv)
807 {
808         int ret;
809         uint32_t recmaster;
810
811         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
812         if (ret != 0) {
813                 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
814                 return ret;
815         }
816         printf("%d\n",recmaster);
817
818         return 0;
819 }
820
821 /*
822   get a list of all tickles for this pnn
823  */
824 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
825 {
826         struct ctdb_control_tcp_tickle_list *list;
827         ctdb_sock_addr addr;
828         int i, ret;
829
830         if (argc < 1) {
831                 usage();
832         }
833
834         if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
835                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
836                 return -1;
837         }
838
839         ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
840         if (ret == -1) {
841                 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
842                 return -1;
843         }
844
845         printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
846         printf("Num tickles:%u\n", list->tickles.num);
847         for (i=0;i<list->tickles.num;i++) {
848                 printf("SRC: %s:%u   ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
849                 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));
850         }
851
852         talloc_free(list);
853         
854         return 0;
855 }
856
857
858 /*
859   move/failover an ip address to a specific node
860  */
861 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
862 {
863         uint32_t pnn;
864         ctdb_sock_addr addr;
865         struct ctdb_all_public_ips *ips;
866         struct ctdb_public_ip ip;
867         uint32_t *nodes;
868         int i, ret;
869         TDB_DATA data;
870         struct ctdb_node_map *nodemap=NULL;
871         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
872
873         if (argc < 2) {
874                 usage();
875                 talloc_free(tmp_ctx);
876                 return -1;
877         }
878
879         if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
880                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
881                 talloc_free(tmp_ctx);
882                 return -1;
883         }
884
885
886         if (sscanf(argv[1], "%u", &pnn) != 1) {
887                 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
888                 talloc_free(tmp_ctx);
889                 return -1;
890         }
891
892
893         /* read the public ip list from the node */
894         ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
895         if (ret != 0) {
896                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
897                 talloc_free(tmp_ctx);
898                 return -1;
899         }
900
901         for (i=0;i<ips->num;i++) {
902                 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
903                         break;
904                 }
905         }
906         if (i==ips->num) {
907                 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
908                         pnn, ctdb_addr_to_str(&addr)));
909                 talloc_free(tmp_ctx);
910                 return -1;
911         }
912         if (ips->ips[i].pnn == pnn) {
913                 DEBUG(DEBUG_ERR, ("Host %u is already hosting '%s'\n",
914                         pnn, ctdb_addr_to_str(&ips->ips[i].addr)));
915                 talloc_free(tmp_ctx);
916                 return -1;
917         }
918
919         ip.pnn  = pnn;
920         ip.addr = addr;
921
922         data.dptr  = (uint8_t *)&ip;
923         data.dsize = sizeof(ip);
924
925         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
926         if (ret != 0) {
927                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
928                 talloc_free(tmp_ctx);
929                 return ret;
930         }
931
932         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
933         ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
934                                         nodes, TIMELIMIT(),
935                                         false, data,
936                                         NULL, NULL,
937                                         NULL);
938         if (ret != 0) {
939                 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
940                 talloc_free(tmp_ctx);
941                 return -1;
942         }
943
944         ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
945         if (ret != 0) {
946                 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
947                 talloc_free(tmp_ctx);
948                 return -1;
949         }
950
951         talloc_free(tmp_ctx);
952         return 0;
953 }
954
955 void getips_store_callback(void *param, void *data)
956 {
957         struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
958         struct ctdb_all_public_ips *ips = param;
959         int i;
960
961         i = ips->num++;
962         ips->ips[i].pnn  = node_ip->pnn;
963         ips->ips[i].addr = node_ip->addr;
964 }
965
966 void getips_count_callback(void *param, void *data)
967 {
968         uint32_t *count = param;
969
970         (*count)++;
971 }
972
973 #define IP_KEYLEN       4
974 static uint32_t *ip_key(ctdb_sock_addr *ip)
975 {
976         static uint32_t key[IP_KEYLEN];
977
978         bzero(key, sizeof(key));
979
980         switch (ip->sa.sa_family) {
981         case AF_INET:
982                 key[0]  = ip->ip.sin_addr.s_addr;
983                 break;
984         case AF_INET6:
985                 key[0]  = ip->ip6.sin6_addr.s6_addr32[3];
986                 key[1]  = ip->ip6.sin6_addr.s6_addr32[2];
987                 key[2]  = ip->ip6.sin6_addr.s6_addr32[1];
988                 key[3]  = ip->ip6.sin6_addr.s6_addr32[0];
989                 break;
990         default:
991                 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
992                 return key;
993         }
994
995         return key;
996 }
997
998 static void *add_ip_callback(void *parm, void *data)
999 {
1000         return parm;
1001 }
1002
1003 static int
1004 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1005 {
1006         struct ctdb_all_public_ips *tmp_ips;
1007         struct ctdb_node_map *nodemap=NULL;
1008         trbt_tree_t *ip_tree;
1009         int i, j, len, ret;
1010         uint32_t count;
1011
1012         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1013         if (ret != 0) {
1014                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1015                 return ret;
1016         }
1017
1018         ip_tree = trbt_create(tmp_ctx, 0);
1019
1020         for(i=0;i<nodemap->num;i++){
1021                 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1022                         continue;
1023                 }
1024                 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1025                         continue;
1026                 }
1027
1028                 /* read the public ip list from this node */
1029                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1030                 if (ret != 0) {
1031                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1032                         return -1;
1033                 }
1034         
1035                 for (j=0; j<tmp_ips->num;j++) {
1036                         struct ctdb_public_ip *node_ip;
1037
1038                         node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1039                         node_ip->pnn  = tmp_ips->ips[j].pnn;
1040                         node_ip->addr = tmp_ips->ips[j].addr;
1041
1042                         trbt_insertarray32_callback(ip_tree,
1043                                 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1044                                 add_ip_callback,
1045                                 node_ip);
1046                 }
1047                 talloc_free(tmp_ips);
1048         }
1049
1050         /* traverse */
1051         count = 0;
1052         trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1053
1054         len = offsetof(struct ctdb_all_public_ips, ips) + 
1055                 count*sizeof(struct ctdb_public_ip);
1056         tmp_ips = talloc_zero_size(tmp_ctx, len);
1057         trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1058
1059         *ips = tmp_ips;
1060
1061         return 0;
1062 }
1063
1064
1065 /* 
1066  * scans all other nodes and returns a pnn for another node that can host this 
1067  * ip address or -1
1068  */
1069 static int
1070 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1071 {
1072         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1073         struct ctdb_all_public_ips *ips;
1074         struct ctdb_node_map *nodemap=NULL;
1075         int i, j, ret;
1076
1077         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1078         if (ret != 0) {
1079                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1080                 talloc_free(tmp_ctx);
1081                 return ret;
1082         }
1083
1084         for(i=0;i<nodemap->num;i++){
1085                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1086                         continue;
1087                 }
1088                 if (nodemap->nodes[i].pnn == options.pnn) {
1089                         continue;
1090                 }
1091
1092                 /* read the public ip list from this node */
1093                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1094                 if (ret != 0) {
1095                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1096                         return -1;
1097                 }
1098
1099                 for (j=0;j<ips->num;j++) {
1100                         if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1101                                 talloc_free(tmp_ctx);
1102                                 return nodemap->nodes[i].pnn;
1103                         }
1104                 }
1105                 talloc_free(ips);
1106         }
1107
1108         talloc_free(tmp_ctx);
1109         return -1;
1110 }
1111
1112 /*
1113   add a public ip address to a node
1114  */
1115 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1116 {
1117         int i, ret;
1118         int len;
1119         unsigned mask;
1120         ctdb_sock_addr addr;
1121         struct ctdb_control_ip_iface *pub;
1122         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1123         struct ctdb_all_public_ips *ips;
1124
1125         if (argc != 2) {
1126                 talloc_free(tmp_ctx);
1127                 usage();
1128         }
1129
1130         if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1131                 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1132                 talloc_free(tmp_ctx);
1133                 return -1;
1134         }
1135
1136         ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1137         if (ret != 0) {
1138                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1139                 talloc_free(tmp_ctx);
1140                 return ret;
1141         }
1142
1143
1144         /* check if some other node is already serving this ip, if not,
1145          * we will claim it
1146          */
1147         for (i=0;i<ips->num;i++) {
1148                 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1149                         break;
1150                 }
1151         }
1152
1153         len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1154         pub = talloc_size(tmp_ctx, len); 
1155         CTDB_NO_MEMORY(ctdb, pub);
1156
1157         pub->addr  = addr;
1158         pub->mask  = mask;
1159         pub->len   = strlen(argv[1])+1;
1160         memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1161
1162         ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1163         if (ret != 0) {
1164                 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1165                 talloc_free(tmp_ctx);
1166                 return ret;
1167         }
1168
1169         /* no one has this ip so we claim it */
1170         if (i == ips->num) {
1171                 struct ctdb_public_ip ip;
1172
1173                 ip.pnn  = options.pnn;
1174                 ip.addr = addr;
1175
1176                 ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), options.pnn, &ip);
1177                 if (ret != 0) {
1178                         DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", options.pnn));
1179                         return -1;
1180                 }
1181         }
1182
1183
1184         if (ret != 0) {
1185                 DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));
1186                 return -1;
1187         }
1188
1189         talloc_free(tmp_ctx);
1190         return 0;
1191 }
1192
1193 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1194
1195 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1196 {
1197         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1198         struct ctdb_node_map *nodemap=NULL;
1199         struct ctdb_all_public_ips *ips;
1200         int ret, i, j;
1201
1202         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1203         if (ret != 0) {
1204                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1205                 return ret;
1206         }
1207
1208         /* remove it from the nodes that are not hosting the ip currently */
1209         for(i=0;i<nodemap->num;i++){
1210                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1211                         continue;
1212                 }
1213                 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1214                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1215                         continue;
1216                 }
1217
1218                 for (j=0;j<ips->num;j++) {
1219                         if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1220                                 break;
1221                         }
1222                 }
1223                 if (j==ips->num) {
1224                         continue;
1225                 }
1226
1227                 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1228                         continue;
1229                 }
1230
1231                 options.pnn = nodemap->nodes[i].pnn;
1232                 control_delip(ctdb, argc, argv);
1233         }
1234
1235
1236         /* remove it from every node (also the one hosting it) */
1237         for(i=0;i<nodemap->num;i++){
1238                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1239                         continue;
1240                 }
1241                 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1242                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1243                         continue;
1244                 }
1245
1246                 for (j=0;j<ips->num;j++) {
1247                         if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1248                                 break;
1249                         }
1250                 }
1251                 if (j==ips->num) {
1252                         continue;
1253                 }
1254
1255                 options.pnn = nodemap->nodes[i].pnn;
1256                 control_delip(ctdb, argc, argv);
1257         }
1258
1259         talloc_free(tmp_ctx);
1260         return 0;
1261 }
1262         
1263 /*
1264   delete a public ip address from a node
1265  */
1266 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1267 {
1268         int i, ret;
1269         ctdb_sock_addr addr;
1270         struct ctdb_control_ip_iface pub;
1271         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1272         struct ctdb_all_public_ips *ips;
1273
1274         if (argc != 1) {
1275                 talloc_free(tmp_ctx);
1276                 usage();
1277         }
1278
1279         if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1280                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1281                 return -1;
1282         }
1283
1284         if (options.pnn == CTDB_BROADCAST_ALL) {
1285                 return control_delip_all(ctdb, argc, argv, &addr);
1286         }
1287
1288         pub.addr  = addr;
1289         pub.mask  = 0;
1290         pub.len   = 0;
1291
1292         ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1293         if (ret != 0) {
1294                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1295                 talloc_free(tmp_ctx);
1296                 return ret;
1297         }
1298         
1299         for (i=0;i<ips->num;i++) {
1300                 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1301                         break;
1302                 }
1303         }
1304
1305         if (i==ips->num) {
1306                 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1307                         ctdb_addr_to_str(&addr)));
1308                 talloc_free(tmp_ctx);
1309                 return -1;
1310         }
1311
1312         if (ips->ips[i].pnn == options.pnn) {
1313                 ret = find_other_host_for_public_ip(ctdb, &addr);
1314                 if (ret != -1) {
1315                         struct ctdb_public_ip ip;
1316
1317                         ip.pnn  = ret;
1318                         ip.addr = addr;
1319
1320                         ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), ret, &ip);
1321                         if (ret != 0) {
1322                                 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", options.pnn));
1323                                 return -1;
1324                         }
1325                 }
1326         }
1327
1328         ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1329         if (ret != 0) {
1330                 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1331                 talloc_free(tmp_ctx);
1332                 return ret;
1333         }
1334
1335         talloc_free(tmp_ctx);
1336         return 0;
1337 }
1338
1339 /*
1340   kill a tcp connection
1341  */
1342 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1343 {
1344         int ret;
1345         struct ctdb_control_killtcp killtcp;
1346
1347         if (argc < 2) {
1348                 usage();
1349         }
1350
1351         if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1352                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1353                 return -1;
1354         }
1355
1356         if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1357                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1358                 return -1;
1359         }
1360
1361         ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1362         if (ret != 0) {
1363                 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1364                 return ret;
1365         }
1366
1367         return 0;
1368 }
1369
1370
1371 /*
1372   send a gratious arp
1373  */
1374 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1375 {
1376         int ret;
1377         ctdb_sock_addr addr;
1378
1379         if (argc < 2) {
1380                 usage();
1381         }
1382
1383         if (!parse_ip(argv[0], NULL, 0, &addr)) {
1384                 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1385                 return -1;
1386         }
1387
1388         ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1389         if (ret != 0) {
1390                 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1391                 return ret;
1392         }
1393
1394         return 0;
1395 }
1396
1397 /*
1398   register a server id
1399  */
1400 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1401 {
1402         int ret;
1403         struct ctdb_server_id server_id;
1404
1405         if (argc < 3) {
1406                 usage();
1407         }
1408
1409         server_id.pnn       = strtoul(argv[0], NULL, 0);
1410         server_id.type      = strtoul(argv[1], NULL, 0);
1411         server_id.server_id = strtoul(argv[2], NULL, 0);
1412
1413         ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1414         if (ret != 0) {
1415                 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1416                 return ret;
1417         }
1418         return -1;
1419 }
1420
1421 /*
1422   unregister a server id
1423  */
1424 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1425 {
1426         int ret;
1427         struct ctdb_server_id server_id;
1428
1429         if (argc < 3) {
1430                 usage();
1431         }
1432
1433         server_id.pnn       = strtoul(argv[0], NULL, 0);
1434         server_id.type      = strtoul(argv[1], NULL, 0);
1435         server_id.server_id = strtoul(argv[2], NULL, 0);
1436
1437         ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1438         if (ret != 0) {
1439                 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1440                 return ret;
1441         }
1442         return -1;
1443 }
1444
1445 /*
1446   check if a server id exists
1447  */
1448 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1449 {
1450         uint32_t status;
1451         int ret;
1452         struct ctdb_server_id server_id;
1453
1454         if (argc < 3) {
1455                 usage();
1456         }
1457
1458         server_id.pnn       = strtoul(argv[0], NULL, 0);
1459         server_id.type      = strtoul(argv[1], NULL, 0);
1460         server_id.server_id = strtoul(argv[2], NULL, 0);
1461
1462         ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1463         if (ret != 0) {
1464                 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1465                 return ret;
1466         }
1467
1468         if (status) {
1469                 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1470         } else {
1471                 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1472         }
1473         return 0;
1474 }
1475
1476 /*
1477   get a list of all server ids that are registered on a node
1478  */
1479 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1480 {
1481         int i, ret;
1482         struct ctdb_server_id_list *server_ids;
1483
1484         ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1485         if (ret != 0) {
1486                 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1487                 return ret;
1488         }
1489
1490         for (i=0; i<server_ids->num; i++) {
1491                 printf("Server id %d:%d:%d\n", 
1492                         server_ids->server_ids[i].pnn, 
1493                         server_ids->server_ids[i].type, 
1494                         server_ids->server_ids[i].server_id); 
1495         }
1496
1497         return -1;
1498 }
1499
1500 /*
1501   send a tcp tickle ack
1502  */
1503 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1504 {
1505         int ret;
1506         ctdb_sock_addr  src, dst;
1507
1508         if (argc < 2) {
1509                 usage();
1510         }
1511
1512         if (!parse_ip_port(argv[0], &src)) {
1513                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1514                 return -1;
1515         }
1516
1517         if (!parse_ip_port(argv[1], &dst)) {
1518                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1519                 return -1;
1520         }
1521
1522         ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1523         if (ret==0) {
1524                 return 0;
1525         }
1526         DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1527
1528         return -1;
1529 }
1530
1531
1532 /*
1533   display public ip status
1534  */
1535 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1536 {
1537         int i, ret;
1538         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1539         struct ctdb_all_public_ips *ips;
1540
1541         if (options.pnn == CTDB_BROADCAST_ALL) {
1542                 /* read the list of public ips from all nodes */
1543                 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1544         } else {
1545                 /* read the public ip list from this node */
1546                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1547         }
1548         if (ret != 0) {
1549                 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1550                 talloc_free(tmp_ctx);
1551                 return ret;
1552         }
1553
1554         if (options.machinereadable){
1555                 printf(":Public IP:Node:\n");
1556         } else {
1557                 if (options.pnn == CTDB_BROADCAST_ALL) {
1558                         printf("Public IPs on ALL nodes\n");
1559                 } else {
1560                         printf("Public IPs on node %u\n", options.pnn);
1561                 }
1562         }
1563
1564         for (i=1;i<=ips->num;i++) {
1565                 if (options.machinereadable){
1566                         printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1567                 } else {
1568                         printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1569                 }
1570         }
1571
1572         talloc_free(tmp_ctx);
1573         return 0;
1574 }
1575
1576 /*
1577   display pid of a ctdb daemon
1578  */
1579 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1580 {
1581         uint32_t pid;
1582         int ret;
1583
1584         ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1585         if (ret != 0) {
1586                 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1587                 return ret;
1588         }
1589         printf("Pid:%d\n", pid);
1590
1591         return 0;
1592 }
1593
1594 /*
1595   handler for receiving the response to ipreallocate
1596 */
1597 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid, 
1598                              TDB_DATA data, void *private_data)
1599 {
1600         exit(0);
1601 }
1602
1603 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1604 {
1605         struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1606
1607         event_add_timed(ctdb->ev, ctdb, 
1608                                 timeval_current_ofs(1, 0),
1609                                 ctdb_every_second, ctdb);
1610 }
1611
1612 /*
1613   ask the recovery daemon on the recovery master to perform a ip reallocation
1614  */
1615 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1616 {
1617         int i, ret;
1618         TDB_DATA data;
1619         struct rd_memdump_reply rd;
1620         uint32_t recmaster;
1621         struct ctdb_node_map *nodemap=NULL;
1622         int retries=0;
1623         struct timeval tv = timeval_current();
1624
1625         /* we need some events to trigger so we can timeout and restart
1626            the loop
1627         */
1628         event_add_timed(ctdb->ev, ctdb, 
1629                                 timeval_current_ofs(1, 0),
1630                                 ctdb_every_second, ctdb);
1631
1632         rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1633         if (rd.pnn == -1) {
1634                 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1635                 return -1;
1636         }
1637         rd.srvid = getpid();
1638
1639         /* register a message port for receiveing the reply so that we
1640            can receive the reply
1641         */
1642         ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1643
1644         data.dptr = (uint8_t *)&rd;
1645         data.dsize = sizeof(rd);
1646
1647 again:
1648         if (retries>5) {
1649                 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1650                 exit(10);
1651         }
1652
1653         /* check that there are valid nodes available */
1654         if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1655                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1656                 exit(10);
1657         }
1658         for (i=0; i<nodemap->num;i++) {
1659                 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1660                         break;
1661                 }
1662         }
1663         if (i==nodemap->num) {
1664                 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1665                 return 0;
1666         }
1667
1668
1669         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1670         if (ret != 0) {
1671                 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1672                 return ret;
1673         }
1674
1675         /* verify the node exists */
1676         if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1677                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1678                 exit(10);
1679         }
1680
1681
1682         /* check tha there are nodes available that can act as a recmaster */
1683         for (i=0; i<nodemap->num; i++) {
1684                 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1685                         continue;
1686                 }
1687         }
1688         if (i == nodemap->num) {
1689                 return 0;
1690         }
1691
1692         /* verify the recovery master is not STOPPED, nor BANNED */
1693         if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1694                 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1695                 retries++;
1696                 sleep(1);
1697                 goto again;
1698         } 
1699
1700         
1701         /* verify the recovery master is not STOPPED, nor BANNED */
1702         if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1703                 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1704                 retries++;
1705                 sleep(1);
1706                 goto again;
1707         } 
1708
1709         ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1710         if (ret != 0) {
1711                 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1712                 return -1;
1713         }
1714
1715         tv = timeval_current();
1716         /* this loop will terminate when we have received the reply */
1717         while (timeval_elapsed(&tv) < 3.0) {    
1718                 event_loop_once(ctdb->ev);
1719         }
1720
1721         DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1722         retries++;
1723         sleep(1);
1724         goto again;
1725
1726         return 0;
1727 }
1728
1729
1730 /*
1731   disable a remote node
1732  */
1733 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1734 {
1735         int ret;
1736         struct ctdb_node_map *nodemap=NULL;
1737
1738         do {
1739                 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1740                 if (ret != 0) {
1741                         DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1742                         return ret;
1743                 }
1744
1745                 sleep(1);
1746
1747                 /* read the nodemap and verify the change took effect */
1748                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1749                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1750                         exit(10);
1751                 }
1752
1753         } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1754         ret = control_ipreallocate(ctdb, argc, argv);
1755         if (ret != 0) {
1756                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1757                 return ret;
1758         }
1759
1760         return 0;
1761 }
1762
1763 /*
1764   enable a disabled remote node
1765  */
1766 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1767 {
1768         int ret;
1769
1770         struct ctdb_node_map *nodemap=NULL;
1771
1772         do {
1773                 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1774                 if (ret != 0) {
1775                         DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1776                         return ret;
1777                 }
1778
1779                 sleep(1);
1780
1781                 /* read the nodemap and verify the change took effect */
1782                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1783                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1784                         exit(10);
1785                 }
1786
1787         } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1788         ret = control_ipreallocate(ctdb, argc, argv);
1789         if (ret != 0) {
1790                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1791                 return ret;
1792         }
1793
1794         return 0;
1795 }
1796
1797 /*
1798   stop a remote node
1799  */
1800 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1801 {
1802         int ret;
1803         struct ctdb_node_map *nodemap=NULL;
1804
1805         do {
1806                 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1807                 if (ret != 0) {
1808                         DEBUG(DEBUG_ERR, ("Unable to stop node %u   try again\n", options.pnn));
1809                 }
1810         
1811                 sleep(1);
1812
1813                 /* read the nodemap and verify the change took effect */
1814                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1815                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1816                         exit(10);
1817                 }
1818
1819         } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1820         ret = control_ipreallocate(ctdb, argc, argv);
1821         if (ret != 0) {
1822                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1823                 return ret;
1824         }
1825
1826         return 0;
1827 }
1828
1829 /*
1830   restart a stopped remote node
1831  */
1832 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1833 {
1834         int ret;
1835
1836         struct ctdb_node_map *nodemap=NULL;
1837
1838         do {
1839                 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1840                 if (ret != 0) {
1841                         DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1842                         return ret;
1843                 }
1844         
1845                 sleep(1);
1846
1847                 /* read the nodemap and verify the change took effect */
1848                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1849                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1850                         exit(10);
1851                 }
1852
1853         } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1854         ret = control_ipreallocate(ctdb, argc, argv);
1855         if (ret != 0) {
1856                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1857                 return ret;
1858         }
1859
1860         return 0;
1861 }
1862
1863 static uint32_t get_generation(struct ctdb_context *ctdb)
1864 {
1865         struct ctdb_vnn_map *vnnmap=NULL;
1866         int ret;
1867
1868         /* wait until the recmaster is not in recovery mode */
1869         while (1) {
1870                 uint32_t recmode, recmaster;
1871                 
1872                 if (vnnmap != NULL) {
1873                         talloc_free(vnnmap);
1874                         vnnmap = NULL;
1875                 }
1876
1877                 /* get the recmaster */
1878                 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1879                 if (ret != 0) {
1880                         DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1881                         exit(10);
1882                 }
1883
1884                 /* get recovery mode */
1885                 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1886                 if (ret != 0) {
1887                         DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1888                         exit(10);
1889                 }
1890
1891                 /* get the current generation number */
1892                 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
1893                 if (ret != 0) {
1894                         DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
1895                         exit(10);
1896                 }
1897
1898                 if ((recmode == CTDB_RECOVERY_NORMAL)
1899                 &&  (vnnmap->generation != 1)){
1900                         return vnnmap->generation;
1901                 }
1902                 sleep(1);
1903         }
1904 }
1905
1906 /*
1907   ban a node from the cluster
1908  */
1909 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
1910 {
1911         int ret;
1912         struct ctdb_node_map *nodemap=NULL;
1913         struct ctdb_ban_time bantime;
1914
1915         if (argc < 1) {
1916                 usage();
1917         }
1918         
1919         /* verify the node exists */
1920         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1921         if (ret != 0) {
1922                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1923                 return ret;
1924         }
1925
1926         if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
1927                 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
1928                 return -1;
1929         }
1930
1931         bantime.pnn  = options.pnn;
1932         bantime.time = strtoul(argv[0], NULL, 0);
1933
1934         ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1935         if (ret != 0) {
1936                 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
1937                 return -1;
1938         }       
1939
1940         ret = control_ipreallocate(ctdb, argc, argv);
1941         if (ret != 0) {
1942                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1943                 return ret;
1944         }
1945
1946         return 0;
1947 }
1948
1949
1950 /*
1951   unban a node from the cluster
1952  */
1953 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
1954 {
1955         int ret;
1956         struct ctdb_node_map *nodemap=NULL;
1957         struct ctdb_ban_time bantime;
1958
1959         /* verify the node exists */
1960         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1961         if (ret != 0) {
1962                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1963                 return ret;
1964         }
1965
1966         if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
1967                 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
1968                 return -1;
1969         }
1970
1971         bantime.pnn  = options.pnn;
1972         bantime.time = 0;
1973
1974         ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1975         if (ret != 0) {
1976                 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
1977                 return -1;
1978         }       
1979
1980         ret = control_ipreallocate(ctdb, argc, argv);
1981         if (ret != 0) {
1982                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1983                 return ret;
1984         }
1985
1986         return 0;
1987 }
1988
1989
1990 /*
1991   show ban information for a node
1992  */
1993 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
1994 {
1995         int ret;
1996         struct ctdb_node_map *nodemap=NULL;
1997         struct ctdb_ban_time *bantime;
1998
1999         /* verify the node exists */
2000         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2001         if (ret != 0) {
2002                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2003                 return ret;
2004         }
2005
2006         ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2007         if (ret != 0) {
2008                 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2009                 return -1;
2010         }       
2011
2012         if (bantime->time == 0) {
2013                 printf("Node %u is not banned\n", bantime->pnn);
2014         } else {
2015                 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2016         }
2017
2018         return 0;
2019 }
2020
2021 /*
2022   shutdown a daemon
2023  */
2024 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2025 {
2026         int ret;
2027
2028         ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2029         if (ret != 0) {
2030                 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2031                 return ret;
2032         }
2033
2034         return 0;
2035 }
2036
2037 /*
2038   trigger a recovery
2039  */
2040 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2041 {
2042         int ret;
2043         uint32_t generation, next_generation;
2044
2045         /* record the current generation number */
2046         generation = get_generation(ctdb);
2047
2048         ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
2049         if (ret != 0) {
2050                 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2051                 return ret;
2052         }
2053
2054         ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2055         if (ret != 0) {
2056                 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2057                 return ret;
2058         }
2059
2060         /* wait until we are in a new generation */
2061         while (1) {
2062                 next_generation = get_generation(ctdb);
2063                 if (next_generation != generation) {
2064                         return 0;
2065                 }
2066                 sleep(1);
2067         }
2068
2069         return 0;
2070 }
2071
2072
2073 /*
2074   display monitoring mode of a remote node
2075  */
2076 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2077 {
2078         uint32_t monmode;
2079         int ret;
2080
2081         ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2082         if (ret != 0) {
2083                 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2084                 return ret;
2085         }
2086         if (!options.machinereadable){
2087                 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2088         } else {
2089                 printf(":mode:\n");
2090                 printf(":%d:\n",monmode);
2091         }
2092         return 0;
2093 }
2094
2095
2096 /*
2097   display capabilities of a remote node
2098  */
2099 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2100 {
2101         uint32_t capabilities;
2102         int ret;
2103
2104         ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2105         if (ret != 0) {
2106                 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2107                 return ret;
2108         }
2109         
2110         if (!options.machinereadable){
2111                 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2112                 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2113                 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2114                 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2115         } else {
2116                 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2117                 printf(":%d:%d:%d:%d:\n",
2118                         !!(capabilities&CTDB_CAP_RECMASTER),
2119                         !!(capabilities&CTDB_CAP_LMASTER),
2120                         !!(capabilities&CTDB_CAP_LVS),
2121                         !!(capabilities&CTDB_CAP_NATGW));
2122         }
2123         return 0;
2124 }
2125
2126 /*
2127   display lvs configuration
2128  */
2129 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2130 {
2131         uint32_t *capabilities;
2132         struct ctdb_node_map *nodemap=NULL;
2133         int i, ret;
2134         int healthy_count = 0;
2135
2136         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2137         if (ret != 0) {
2138                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2139                 return ret;
2140         }
2141
2142         capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2143         CTDB_NO_MEMORY(ctdb, capabilities);
2144         
2145         /* collect capabilities for all connected nodes */
2146         for (i=0; i<nodemap->num; i++) {
2147                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2148                         continue;
2149                 }
2150                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2151                         continue;
2152                 }
2153         
2154                 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2155                 if (ret != 0) {
2156                         DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2157                         return ret;
2158                 }
2159
2160                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2161                         continue;
2162                 }
2163
2164                 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2165                         healthy_count++;
2166                 }
2167         }
2168
2169         /* Print all LVS nodes */
2170         for (i=0; i<nodemap->num; i++) {
2171                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2172                         continue;
2173                 }
2174                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2175                         continue;
2176                 }
2177                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2178                         continue;
2179                 }
2180
2181                 if (healthy_count != 0) {
2182                         if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2183                                 continue;
2184                         }
2185                 }
2186
2187                 printf("%d:%s\n", i, 
2188                         ctdb_addr_to_str(&nodemap->nodes[i].addr));
2189         }
2190
2191         return 0;
2192 }
2193
2194 /*
2195   display who is the lvs master
2196  */
2197 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2198 {
2199         uint32_t *capabilities;
2200         struct ctdb_node_map *nodemap=NULL;
2201         int i, ret;
2202         int healthy_count = 0;
2203
2204         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2205         if (ret != 0) {
2206                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2207                 return ret;
2208         }
2209
2210         capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2211         CTDB_NO_MEMORY(ctdb, capabilities);
2212         
2213         /* collect capabilities for all connected nodes */
2214         for (i=0; i<nodemap->num; i++) {
2215                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2216                         continue;
2217                 }
2218                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2219                         continue;
2220                 }
2221         
2222                 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2223                 if (ret != 0) {
2224                         DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2225                         return ret;
2226                 }
2227
2228                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2229                         continue;
2230                 }
2231
2232                 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2233                         healthy_count++;
2234                 }
2235         }
2236
2237         /* find and show the lvsmaster */
2238         for (i=0; i<nodemap->num; i++) {
2239                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2240                         continue;
2241                 }
2242                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2243                         continue;
2244                 }
2245                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2246                         continue;
2247                 }
2248
2249                 if (healthy_count != 0) {
2250                         if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2251                                 continue;
2252                         }
2253                 }
2254
2255                 if (options.machinereadable){
2256                         printf("%d\n", i);
2257                 } else {
2258                         printf("Node %d is LVS master\n", i);
2259                 }
2260                 return 0;
2261         }
2262
2263         printf("There is no LVS master\n");
2264         return -1;
2265 }
2266
2267 /*
2268   disable monitoring on a  node
2269  */
2270 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2271 {
2272         
2273         int ret;
2274
2275         ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2276         if (ret != 0) {
2277                 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2278                 return ret;
2279         }
2280         printf("Monitoring mode:%s\n","DISABLED");
2281
2282         return 0;
2283 }
2284
2285 /*
2286   enable monitoring on a  node
2287  */
2288 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2289 {
2290         
2291         int ret;
2292
2293         ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2294         if (ret != 0) {
2295                 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2296                 return ret;
2297         }
2298         printf("Monitoring mode:%s\n","ACTIVE");
2299
2300         return 0;
2301 }
2302
2303 /*
2304   display remote list of keys/data for a db
2305  */
2306 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2307 {
2308         const char *db_name;
2309         struct ctdb_db_context *ctdb_db;
2310         int ret;
2311
2312         if (argc < 1) {
2313                 usage();
2314         }
2315
2316         db_name = argv[0];
2317
2318
2319         if (db_exists(ctdb, db_name)) {
2320                 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2321                 return -1;
2322         }
2323
2324         ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2325
2326         if (ctdb_db == NULL) {
2327                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2328                 return -1;
2329         }
2330
2331         /* traverse and dump the cluster tdb */
2332         ret = ctdb_dump_db(ctdb_db, stdout);
2333         if (ret == -1) {
2334                 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2335                 return -1;
2336         }
2337         talloc_free(ctdb_db);
2338
2339         printf("Dumped %d records\n", ret);
2340         return 0;
2341 }
2342
2343
2344 /*
2345   display a list of the databases on a remote ctdb
2346  */
2347 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2348 {
2349         int i, ret;
2350         struct ctdb_dbid_map *dbmap=NULL;
2351
2352         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2353         if (ret != 0) {
2354                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2355                 return ret;
2356         }
2357
2358         printf("Number of databases:%d\n", dbmap->num);
2359         for(i=0;i<dbmap->num;i++){
2360                 const char *path;
2361                 const char *name;
2362                 bool persistent;
2363
2364                 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2365                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2366                 persistent = dbmap->dbs[i].persistent;
2367                 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name, 
2368                        path, persistent?"PERSISTENT":"");
2369         }
2370
2371         return 0;
2372 }
2373
2374 /*
2375   check if the local node is recmaster or not
2376   it will return 1 if this node is the recmaster and 0 if it is not
2377   or if the local ctdb daemon could not be contacted
2378  */
2379 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2380 {
2381         uint32_t mypnn, recmaster;
2382         int ret;
2383
2384         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2385         if (mypnn == -1) {
2386                 printf("Failed to get pnn of node\n");
2387                 return 1;
2388         }
2389
2390         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2391         if (ret != 0) {
2392                 printf("Failed to get the recmaster\n");
2393                 return 1;
2394         }
2395
2396         if (recmaster != mypnn) {
2397                 printf("this node is not the recmaster\n");
2398                 return 1;
2399         }
2400
2401         printf("this node is the recmaster\n");
2402         return 0;
2403 }
2404
2405 /*
2406   ping a node
2407  */
2408 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2409 {
2410         int ret;
2411         struct timeval tv = timeval_current();
2412         ret = ctdb_ctrl_ping(ctdb, options.pnn);
2413         if (ret == -1) {
2414                 printf("Unable to get ping response from node %u\n", options.pnn);
2415                 return -1;
2416         } else {
2417                 printf("response from %u time=%.6f sec  (%d clients)\n", 
2418                        options.pnn, timeval_elapsed(&tv), ret);
2419         }
2420         return 0;
2421 }
2422
2423
2424 /*
2425   get a tunable
2426  */
2427 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2428 {
2429         const char *name;
2430         uint32_t value;
2431         int ret;
2432
2433         if (argc < 1) {
2434                 usage();
2435         }
2436
2437         name = argv[0];
2438         ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2439         if (ret == -1) {
2440                 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2441                 return -1;
2442         }
2443
2444         printf("%-19s = %u\n", name, value);
2445         return 0;
2446 }
2447
2448 /*
2449   set a tunable
2450  */
2451 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2452 {
2453         const char *name;
2454         uint32_t value;
2455         int ret;
2456
2457         if (argc < 2) {
2458                 usage();
2459         }
2460
2461         name = argv[0];
2462         value = strtoul(argv[1], NULL, 0);
2463
2464         ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2465         if (ret == -1) {
2466                 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2467                 return -1;
2468         }
2469         return 0;
2470 }
2471
2472 /*
2473   list all tunables
2474  */
2475 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2476 {
2477         uint32_t count;
2478         const char **list;
2479         int ret, i;
2480
2481         ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2482         if (ret == -1) {
2483                 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2484                 return -1;
2485         }
2486
2487         for (i=0;i<count;i++) {
2488                 control_getvar(ctdb, 1, &list[i]);
2489         }
2490
2491         talloc_free(list);
2492         
2493         return 0;
2494 }
2495
2496 /*
2497   display debug level on a node
2498  */
2499 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2500 {
2501         int ret;
2502         int32_t level;
2503
2504         ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2505         if (ret != 0) {
2506                 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2507                 return ret;
2508         } else {
2509                 if (options.machinereadable){
2510                         printf(":Name:Level:\n");
2511                         printf(":%s:%d:\n",get_debug_by_level(level),level);
2512                 } else {
2513                         printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2514                 }
2515         }
2516         return 0;
2517 }
2518
2519 /*
2520   display reclock file of a node
2521  */
2522 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2523 {
2524         int ret;
2525         const char *reclock;
2526
2527         ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2528         if (ret != 0) {
2529                 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2530                 return ret;
2531         } else {
2532                 if (reclock == NULL) {
2533                         printf("No reclock file used.\n");
2534                 } else {
2535                         printf("Reclock file:%s\n", reclock);
2536                 }
2537         }
2538         return 0;
2539 }
2540
2541 /*
2542   set the reclock file of a node
2543  */
2544 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2545 {
2546         int ret;
2547         const char *reclock;
2548
2549         if (argc == 0) {
2550                 reclock = NULL;
2551         } else if (argc == 1) {
2552                 reclock = argv[0];
2553         } else {
2554                 usage();
2555         }
2556
2557         ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2558         if (ret != 0) {
2559                 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2560                 return ret;
2561         }
2562         return 0;
2563 }
2564
2565 /*
2566   set the natgw state on/off
2567  */
2568 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2569 {
2570         int ret;
2571         uint32_t natgwstate;
2572
2573         if (argc == 0) {
2574                 usage();
2575         }
2576
2577         if (!strcmp(argv[0], "on")) {
2578                 natgwstate = 1;
2579         } else if (!strcmp(argv[0], "off")) {
2580                 natgwstate = 0;
2581         } else {
2582                 usage();
2583         }
2584
2585         ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2586         if (ret != 0) {
2587                 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2588                 return ret;
2589         }
2590
2591         return 0;
2592 }
2593
2594 /*
2595   set the lmaster role on/off
2596  */
2597 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2598 {
2599         int ret;
2600         uint32_t lmasterrole;
2601
2602         if (argc == 0) {
2603                 usage();
2604         }
2605
2606         if (!strcmp(argv[0], "on")) {
2607                 lmasterrole = 1;
2608         } else if (!strcmp(argv[0], "off")) {
2609                 lmasterrole = 0;
2610         } else {
2611                 usage();
2612         }
2613
2614         ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2615         if (ret != 0) {
2616                 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2617                 return ret;
2618         }
2619
2620         return 0;
2621 }
2622
2623 /*
2624   set the recmaster role on/off
2625  */
2626 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2627 {
2628         int ret;
2629         uint32_t recmasterrole;
2630
2631         if (argc == 0) {
2632                 usage();
2633         }
2634
2635         if (!strcmp(argv[0], "on")) {
2636                 recmasterrole = 1;
2637         } else if (!strcmp(argv[0], "off")) {
2638                 recmasterrole = 0;
2639         } else {
2640                 usage();
2641         }
2642
2643         ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2644         if (ret != 0) {
2645                 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2646                 return ret;
2647         }
2648
2649         return 0;
2650 }
2651
2652 /*
2653   set debug level on a node or all nodes
2654  */
2655 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2656 {
2657         int i, ret;
2658         int32_t level;
2659
2660         if (argc == 0) {
2661                 printf("You must specify the debug level. Valid levels are:\n");
2662                 for (i=0; debug_levels[i].description != NULL; i++) {
2663                         printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2664                 }
2665
2666                 return 0;
2667         }
2668
2669         if (isalpha(argv[0][0]) || argv[0][0] == '-') { 
2670                 level = get_debug_by_desc(argv[0]);
2671         } else {
2672                 level = strtol(argv[0], NULL, 0);
2673         }
2674
2675         for (i=0; debug_levels[i].description != NULL; i++) {
2676                 if (level == debug_levels[i].level) {
2677                         break;
2678                 }
2679         }
2680         if (debug_levels[i].description == NULL) {
2681                 printf("Invalid debug level, must be one of\n");
2682                 for (i=0; debug_levels[i].description != NULL; i++) {
2683                         printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2684                 }
2685                 return -1;
2686         }
2687
2688         ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2689         if (ret != 0) {
2690                 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2691         }
2692         return 0;
2693 }
2694
2695
2696 /*
2697   freeze a node
2698  */
2699 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2700 {
2701         int ret;
2702
2703         ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
2704         if (ret != 0) {
2705                 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2706         }               
2707         return 0;
2708 }
2709
2710 /*
2711   thaw a node
2712  */
2713 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2714 {
2715         int ret;
2716
2717         ret = ctdb_ctrl_thaw(ctdb, TIMELIMIT(), options.pnn);
2718         if (ret != 0) {
2719                 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2720         }               
2721         return 0;
2722 }
2723
2724
2725 /*
2726   attach to a database
2727  */
2728 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2729 {
2730         const char *db_name;
2731         struct ctdb_db_context *ctdb_db;
2732
2733         if (argc < 1) {
2734                 usage();
2735         }
2736         db_name = argv[0];
2737
2738         ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2739         if (ctdb_db == NULL) {
2740                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2741                 return -1;
2742         }
2743
2744         return 0;
2745 }
2746
2747 /*
2748   run an eventscript on a node
2749  */
2750 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
2751 {
2752         TDB_DATA data;
2753         int ret;
2754         int32_t res;
2755         char *errmsg;
2756         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2757
2758         if (argc != 1) {
2759                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2760                 return -1;
2761         }
2762
2763         data.dptr = (unsigned char *)discard_const(argv[0]);
2764         data.dsize = strlen((char *)data.dptr) + 1;
2765
2766         DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
2767
2768         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
2769                            0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2770         if (ret != 0 || res != 0) {
2771                 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
2772                 talloc_free(tmp_ctx);
2773                 return -1;
2774         }
2775         talloc_free(tmp_ctx);
2776         return 0;
2777 }
2778
2779 #define DB_VERSION 1
2780 #define MAX_DB_NAME 64
2781 struct db_file_header {
2782         unsigned long version;
2783         time_t timestamp;
2784         unsigned long persistent;
2785         unsigned long size;
2786         const char name[MAX_DB_NAME];
2787 };
2788
2789 struct backup_data {
2790         struct ctdb_marshall_buffer *records;
2791         uint32_t len;
2792         uint32_t total;
2793         bool traverse_error;
2794 };
2795
2796 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
2797 {
2798         struct backup_data *bd = talloc_get_type(private, struct backup_data);
2799         struct ctdb_rec_data *rec;
2800
2801         /* add the record */
2802         rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
2803         if (rec == NULL) {
2804                 bd->traverse_error = true;
2805                 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
2806                 return -1;
2807         }
2808         bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
2809         if (bd->records == NULL) {
2810                 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
2811                 bd->traverse_error = true;
2812                 return -1;
2813         }
2814         bd->records->count++;
2815         memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
2816         bd->len += rec->length;
2817         talloc_free(rec);
2818
2819         bd->total++;
2820         return 0;
2821 }
2822
2823 /*
2824  * backup a database to a file 
2825  */
2826 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
2827 {
2828         int i, ret;
2829         struct ctdb_dbid_map *dbmap=NULL;
2830         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2831         struct db_file_header dbhdr;
2832         struct ctdb_db_context *ctdb_db;
2833         struct backup_data *bd;
2834         int fh = -1;
2835         int status = -1;
2836
2837         if (argc != 2) {
2838                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2839                 return -1;
2840         }
2841
2842         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
2843         if (ret != 0) {
2844                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2845                 return ret;
2846         }
2847
2848         for(i=0;i<dbmap->num;i++){
2849                 const char *name;
2850
2851                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
2852                 if(!strcmp(argv[0], name)){
2853                         talloc_free(discard_const(name));
2854                         break;
2855                 }
2856                 talloc_free(discard_const(name));
2857         }
2858         if (i == dbmap->num) {
2859                 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
2860                 talloc_free(tmp_ctx);
2861                 return -1;
2862         }
2863
2864
2865         ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
2866         if (ctdb_db == NULL) {
2867                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
2868                 talloc_free(tmp_ctx);
2869                 return -1;
2870         }
2871
2872
2873         ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
2874         if (ret == -1) {
2875                 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
2876                 talloc_free(tmp_ctx);
2877                 return -1;
2878         }
2879
2880
2881         bd = talloc_zero(tmp_ctx, struct backup_data);
2882         if (bd == NULL) {
2883                 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
2884                 talloc_free(tmp_ctx);
2885                 return -1;
2886         }
2887
2888         bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
2889         if (bd->records == NULL) {
2890                 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
2891                 talloc_free(tmp_ctx);
2892                 return -1;
2893         }
2894
2895         bd->len = offsetof(struct ctdb_marshall_buffer, data);
2896         bd->records->db_id = ctdb_db->db_id;
2897         /* traverse the database collecting all records */
2898         if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
2899             bd->traverse_error) {
2900                 DEBUG(DEBUG_ERR,("Traverse error\n"));
2901                 talloc_free(tmp_ctx);
2902                 return -1;              
2903         }
2904
2905         tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2906
2907
2908         fh = open(argv[1], O_RDWR|O_CREAT, 0600);
2909         if (fh == -1) {
2910                 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
2911                 talloc_free(tmp_ctx);
2912                 return -1;
2913         }
2914
2915         dbhdr.version = DB_VERSION;
2916         dbhdr.timestamp = time(NULL);
2917         dbhdr.persistent = dbmap->dbs[i].persistent;
2918         dbhdr.size = bd->len;
2919         if (strlen(argv[0]) >= MAX_DB_NAME) {
2920                 DEBUG(DEBUG_ERR,("Too long dbname\n"));
2921                 goto done;
2922         }
2923         strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
2924         ret = write(fh, &dbhdr, sizeof(dbhdr));
2925         if (ret == -1) {
2926                 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
2927                 goto done;
2928         }
2929         ret = write(fh, bd->records, bd->len);
2930         if (ret == -1) {
2931                 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
2932                 goto done;
2933         }
2934
2935         status = 0;
2936 done:
2937         if (fh != -1) {
2938                 ret = close(fh);
2939                 if (ret == -1) {
2940                         DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
2941                 }
2942         }
2943         talloc_free(tmp_ctx);
2944         return status;
2945 }
2946
2947 /*
2948  * restore a database from a file 
2949  */
2950 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
2951 {
2952         int ret;
2953         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2954         TDB_DATA outdata;
2955         TDB_DATA data;
2956         struct db_file_header dbhdr;
2957         struct ctdb_db_context *ctdb_db;
2958         struct ctdb_node_map *nodemap=NULL;
2959         struct ctdb_vnn_map *vnnmap=NULL;
2960         int fh;
2961         struct ctdb_control_wipe_database w;
2962         uint32_t *nodes;
2963         uint32_t generation;
2964         struct tm *tm;
2965         char tbuf[100];
2966
2967         if (argc != 1) {
2968                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2969                 return -1;
2970         }
2971
2972         fh = open(argv[0], O_RDONLY);
2973         if (fh == -1) {
2974                 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
2975                 talloc_free(tmp_ctx);
2976                 return -1;
2977         }
2978
2979         read(fh, &dbhdr, sizeof(dbhdr));
2980         if (dbhdr.version != DB_VERSION) {
2981                 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
2982                 talloc_free(tmp_ctx);
2983                 return -1;
2984         }
2985
2986         outdata.dsize = dbhdr.size;
2987         outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
2988         if (outdata.dptr == NULL) {
2989                 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
2990                 close(fh);
2991                 talloc_free(tmp_ctx);
2992                 return -1;
2993         }               
2994         read(fh, outdata.dptr, outdata.dsize);
2995         close(fh);
2996
2997         tm = localtime(&dbhdr.timestamp);
2998         strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
2999         printf("Restoring database '%s' from backup @ %s\n",
3000                 dbhdr.name, tbuf);
3001
3002
3003         ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3004         if (ctdb_db == NULL) {
3005                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3006                 talloc_free(tmp_ctx);
3007                 return -1;
3008         }
3009
3010         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3011         if (ret != 0) {
3012                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3013                 talloc_free(tmp_ctx);
3014                 return ret;
3015         }
3016
3017
3018         ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3019         if (ret != 0) {
3020                 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3021                 talloc_free(tmp_ctx);
3022                 return ret;
3023         }
3024
3025         /* freeze all nodes */
3026         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3027         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3028                                         nodes, TIMELIMIT(),
3029                                         false, tdb_null,
3030                                         NULL, NULL,
3031                                         NULL) != 0) {
3032                 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3033                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3034                 talloc_free(tmp_ctx);
3035                 return -1;
3036         }
3037
3038         generation = vnnmap->generation;
3039         data.dptr = (void *)&generation;
3040         data.dsize = sizeof(generation);
3041
3042         /* start a cluster wide transaction */
3043         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3044         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3045                                         nodes,
3046                                         TIMELIMIT(), false, data,
3047                                         NULL, NULL,
3048                                         NULL) != 0) {
3049                 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3050                 return -1;
3051         }
3052
3053
3054         w.db_id = ctdb_db->db_id;
3055         w.transaction_id = generation;
3056
3057         data.dptr = (void *)&w;
3058         data.dsize = sizeof(w);
3059
3060         /* wipe all the remote databases. */
3061         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3062         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3063                                         nodes,
3064                                         TIMELIMIT(), false, data,
3065                                         NULL, NULL,
3066                                         NULL) != 0) {
3067                 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3068                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3069                 talloc_free(tmp_ctx);
3070                 return -1;
3071         }
3072         
3073         /* push the database */
3074         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3075         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3076                                         nodes,
3077                                         TIMELIMIT(), false, outdata,
3078                                         NULL, NULL,
3079                                         NULL) != 0) {
3080                 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3081                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3082                 talloc_free(tmp_ctx);
3083                 return -1;
3084         }
3085
3086         data.dptr = (void *)&generation;
3087         data.dsize = sizeof(generation);
3088
3089         /* commit all the changes */
3090         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3091                                         nodes,
3092                                         TIMELIMIT(), false, data,
3093                                         NULL, NULL,
3094                                         NULL) != 0) {
3095                 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3096                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3097                 talloc_free(tmp_ctx);
3098                 return -1;
3099         }
3100
3101
3102         /* thaw all nodes */
3103         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3104         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3105                                         nodes, TIMELIMIT(),
3106                                         false, tdb_null,
3107                                         NULL, NULL,
3108                                         NULL) != 0) {
3109                 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3110                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3111                 talloc_free(tmp_ctx);
3112                 return -1;
3113         }
3114
3115
3116         talloc_free(tmp_ctx);
3117         return 0;
3118 }
3119
3120 /*
3121  * set flags of a node in the nodemap
3122  */
3123 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3124 {
3125         int ret;
3126         int32_t status;
3127         int node;
3128         int flags;
3129         TDB_DATA data;
3130         struct ctdb_node_flag_change c;
3131
3132         if (argc != 2) {
3133                 usage();
3134                 return -1;
3135         }
3136
3137         if (sscanf(argv[0], "%d", &node) != 1) {
3138                 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3139                 usage();
3140                 return -1;
3141         }
3142         if (sscanf(argv[1], "0x%x", &flags) != 1) {
3143                 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3144                 usage();
3145                 return -1;
3146         }
3147
3148         c.pnn       = node;
3149         c.old_flags = 0;
3150         c.new_flags = flags;
3151
3152         data.dsize = sizeof(c);
3153         data.dptr = (unsigned char *)&c;
3154
3155         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0, 
3156                            data, NULL, NULL, &status, NULL, NULL);
3157         if (ret != 0 || status != 0) {
3158                 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3159                 return -1;
3160         }
3161         return 0;
3162 }
3163
3164 /*
3165   dump memory usage
3166  */
3167 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3168 {
3169         TDB_DATA data;
3170         int ret;
3171         int32_t res;
3172         char *errmsg;
3173         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3174         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3175                            0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3176         if (ret != 0 || res != 0) {
3177                 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3178                 talloc_free(tmp_ctx);
3179                 return -1;
3180         }
3181         write(1, data.dptr, data.dsize);
3182         talloc_free(tmp_ctx);
3183         return 0;
3184 }
3185
3186 /*
3187   handler for memory dumps
3188 */
3189 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid, 
3190                              TDB_DATA data, void *private_data)
3191 {
3192         write(1, data.dptr, data.dsize);
3193         exit(0);
3194 }
3195
3196 /*
3197   dump memory usage on the recovery daemon
3198  */
3199 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3200 {
3201         int ret;
3202         TDB_DATA data;
3203         struct rd_memdump_reply rd;
3204
3205         rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3206         if (rd.pnn == -1) {
3207                 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3208                 return -1;
3209         }
3210         rd.srvid = getpid();
3211
3212         /* register a message port for receiveing the reply so that we
3213            can receive the reply
3214         */
3215         ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3216
3217
3218         data.dptr = (uint8_t *)&rd;
3219         data.dsize = sizeof(rd);
3220
3221         ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3222         if (ret != 0) {
3223                 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3224                 return -1;
3225         }
3226
3227         /* this loop will terminate when we have received the reply */
3228         while (1) {     
3229                 event_loop_once(ctdb->ev);
3230         }
3231
3232         return 0;
3233 }
3234
3235 /*
3236   list all nodes in the cluster
3237   if the daemon is running, we read the data from the daemon.
3238   if the daemon is not running we parse the nodes file directly
3239  */
3240 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3241 {
3242         int i, ret;
3243         struct ctdb_node_map *nodemap=NULL;
3244
3245         if (ctdb != NULL) {
3246                 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3247                 if (ret != 0) {
3248                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3249                         return ret;
3250                 }
3251
3252                 for(i=0;i<nodemap->num;i++){
3253                         if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3254                                 continue;
3255                         }
3256                         if (options.machinereadable){
3257                                 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3258                         } else {
3259                                 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3260                         }
3261                 }
3262         } else {
3263                 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3264                 struct pnn_node *pnn_nodes;
3265                 struct pnn_node *pnn_node;
3266         
3267                 pnn_nodes = read_nodes_file(mem_ctx);
3268                 if (pnn_nodes == NULL) {
3269                         DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3270                         talloc_free(mem_ctx);
3271                         return -1;
3272                 }
3273
3274                 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3275                         ctdb_sock_addr addr;
3276
3277                         if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3278                                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3279                                 talloc_free(mem_ctx);
3280                                 return -1;
3281                         }
3282
3283                         if (options.machinereadable){
3284                                 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3285                         } else {
3286                                 printf("%s\n", pnn_node->addr);
3287                         }
3288                 }
3289                 talloc_free(mem_ctx);
3290         }
3291
3292         return 0;
3293 }
3294
3295 /*
3296   reload the nodes file on the local node
3297  */
3298 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3299 {
3300         int i, ret;
3301         int mypnn;
3302         struct ctdb_node_map *nodemap=NULL;
3303
3304         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3305         if (mypnn == -1) {
3306                 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3307                 return -1;
3308         }
3309
3310         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3311         if (ret != 0) {
3312                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3313                 return ret;
3314         }
3315
3316         /* reload the nodes file on all remote nodes */
3317         for (i=0;i<nodemap->num;i++) {
3318                 if (nodemap->nodes[i].pnn == mypnn) {
3319                         continue;
3320                 }
3321                 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3322                 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3323                         nodemap->nodes[i].pnn);
3324                 if (ret != 0) {
3325                         DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3326                 }
3327         }
3328
3329         /* reload the nodes file on the local node */
3330         DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3331         ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3332         if (ret != 0) {
3333                 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3334         }
3335
3336         /* initiate a recovery */
3337         control_recover(ctdb, argc, argv);
3338
3339         return 0;
3340 }
3341
3342
3343 static const struct {
3344         const char *name;
3345         int (*fn)(struct ctdb_context *, int, const char **);
3346         bool auto_all;
3347         bool without_daemon; /* can be run without daemon running ? */
3348         const char *msg;
3349         const char *args;
3350 } ctdb_commands[] = {
3351 #ifdef CTDB_VERS
3352         { "version",         control_version,           true,   false,  "show version of ctdb" },
3353 #endif
3354         { "status",          control_status,            true,   false,  "show node status" },
3355         { "uptime",          control_uptime,            true,   false,  "show node uptime" },
3356         { "ping",            control_ping,              true,   false,  "ping all nodes" },
3357         { "getvar",          control_getvar,            true,   false,  "get a tunable variable",               "<name>"},
3358         { "setvar",          control_setvar,            true,   false,  "set a tunable variable",               "<name> <value>"},
3359         { "listvars",        control_listvars,          true,   false,  "list tunable variables"},
3360         { "statistics",      control_statistics,        false,  false, "show statistics" },
3361         { "statisticsreset", control_statistics_reset,  true,   false,  "reset statistics"},
3362         { "ip",              control_ip,                false,  false,  "show which public ip's that ctdb manages" },
3363         { "process-exists",  control_process_exists,    true,   false,  "check if a process exists on a node",  "<pid>"},
3364         { "getdbmap",        control_getdbmap,          true,   false,  "show the database map" },
3365         { "catdb",           control_catdb,             true,   false,  "dump a database" ,                     "<dbname>"},
3366         { "getmonmode",      control_getmonmode,        true,   false,  "show monitoring mode" },
3367         { "getcapabilities", control_getcapabilities,   true,   false,  "show node capabilities" },
3368         { "pnn",             control_pnn,               true,   false,  "show the pnn of the currnet node" },
3369         { "lvs",             control_lvs,               true,   false,  "show lvs configuration" },
3370         { "lvsmaster",       control_lvsmaster,         true,   false,  "show which node is the lvs master" },
3371         { "disablemonitor",      control_disable_monmode,true,  false,  "set monitoring mode to DISABLE" },
3372         { "enablemonitor",      control_enable_monmode, true,   false,  "set monitoring mode to ACTIVE" },
3373         { "setdebug",        control_setdebug,          true,   false,  "set debug level",                      "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
3374         { "getdebug",        control_getdebug,          true,   false,  "get debug level" },
3375         { "attach",          control_attach,            true,   false,  "attach to a database",                 "<dbname>" },
3376         { "dumpmemory",      control_dumpmemory,        true,   false,  "dump memory map to stdout" },
3377         { "rddumpmemory",    control_rddumpmemory,      true,   false,  "dump memory map from the recovery daemon to stdout" },
3378         { "getpid",          control_getpid,            true,   false,  "get ctdbd process ID" },
3379         { "disable",         control_disable,           true,   false,  "disable a nodes public IP" },
3380         { "enable",          control_enable,            true,   false,  "enable a nodes public IP" },
3381         { "stop",            control_stop,              true,   false,  "stop a node" },
3382         { "continue",        control_continue,          true,   false,  "re-start a stopped node" },
3383         { "ban",             control_ban,               true,   false,  "ban a node from the cluster",          "<bantime|0>"},
3384         { "unban",           control_unban,             true,   false,  "unban a node" },
3385         { "showban",         control_showban,           true,   false,  "show ban information"},
3386         { "shutdown",        control_shutdown,          true,   false,  "shutdown ctdbd" },
3387         { "recover",         control_recover,           true,   false,  "force recovery" },
3388         { "ipreallocate",    control_ipreallocate,      true,   false,  "force the recovery daemon to perform a ip reallocation procedure" },
3389         { "freeze",          control_freeze,            true,   false,  "freeze all databases" },
3390         { "thaw",            control_thaw,              true,   false,  "thaw all databases" },
3391         { "isnotrecmaster",  control_isnotrecmaster,    false,  false,  "check if the local node is recmaster or not" },
3392         { "killtcp",         kill_tcp,                  false,  false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
3393         { "gratiousarp",     control_gratious_arp,      false,  false, "send a gratious arp", "<ip> <interface>" },
3394         { "tickle",          tickle_tcp,                false,  false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
3395         { "gettickles",      control_get_tickles,       false,  false, "get the list of tickles registered for this ip", "<ip>" },
3396
3397         { "regsrvid",        regsrvid,                  false,  false, "register a server id", "<pnn> <type> <id>" },
3398         { "unregsrvid",      unregsrvid,                false,  false, "unregister a server id", "<pnn> <type> <id>" },
3399         { "chksrvid",        chksrvid,                  false,  false, "check if a server id exists", "<pnn> <type> <id>" },
3400         { "getsrvids",       getsrvids,                 false,  false, "get a list of all server ids"},
3401         { "vacuum",          ctdb_vacuum,               false,  false, "vacuum the databases of empty records", "[max_records]"},
3402         { "repack",          ctdb_repack,               false,  false, "repack all databases", "[max_freelist]"},
3403         { "listnodes",       control_listnodes,         false,  true, "list all nodes in the cluster"},
3404         { "reloadnodes",     control_reload_nodes_file, false,  false, "reload the nodes file and restart the transport on all nodes"},
3405         { "moveip",          control_moveip,            false,  false, "move/failover an ip address to another node", "<ip> <node>"},
3406         { "addip",           control_addip,             true,   false, "add a ip address to a node", "<ip/mask> <iface>"},
3407         { "delip",           control_delip,             false,  false, "delete an ip address from a node", "<ip>"},
3408         { "eventscript",     control_eventscript,       true,   false, "run the eventscript with the given parameters on a node", "<arguments>"},
3409         { "backupdb",        control_backupdb,          false,  false, "backup the database into a file.", "<database> <file>"},
3410         { "restoredb",        control_restoredb,        false,  false, "restore the database from a file.", "<file>"},
3411         { "recmaster",        control_recmaster,        false,  false, "show the pnn for the recovery master."},
3412         { "setflags",        control_setflags,          false,  false, "set flags for a node in the nodemap.", "<node> <flags>"},
3413         { "scriptstatus",    control_scriptstatus,  false,      false, "show the status of the monitoring scripts"},
3414         { "enablescript",     control_enablescript,  false,     false, "enable an eventscript", "<script>"},
3415         { "disablescript",    control_disablescript,  false,    false, "disable an eventscript", "<script>"},
3416         { "natgwlist",        control_natgwlist,        false,  false, "show the nodes belonging to this natgw configuration"},
3417         { "xpnn",             control_xpnn,             true,   true,  "find the pnn of the local node without talking to the daemon (unreliable)" },
3418         { "getreclock",       control_getreclock,       false,  false, "Show the reclock file of a node"},
3419         { "setreclock",       control_setreclock,       false,  false, "Set/clear the reclock file of a node", "[filename]"},
3420         { "setnatgwstate",    control_setnatgwstate,    false,  false, "Set NATGW state to on/off", "{on|off}"},
3421         { "setlmasterrole",   control_setlmasterrole,   false,  false, "Set LMASTER role to on/off", "{on|off}"},
3422         { "setrecmasterrole", control_setrecmasterrole, false,  false, "Set RECMASTER role to on/off", "{on|off}"},
3423 };
3424
3425 /*
3426   show usage message
3427  */
3428 static void usage(void)
3429 {
3430         int i;
3431         printf(
3432 "Usage: ctdb [options] <control>\n" \
3433 "Options:\n" \
3434 "   -n <node>          choose node number, or 'all' (defaults to local node)\n"
3435 "   -Y                 generate machinereadable output\n"
3436 "   -t <timelimit>     set timelimit for control in seconds (default %u)\n", options.timelimit);
3437         printf("Controls:\n");
3438         for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3439                 printf("  %-15s %-27s  %s\n", 
3440                        ctdb_commands[i].name, 
3441                        ctdb_commands[i].args?ctdb_commands[i].args:"",
3442                        ctdb_commands[i].msg);
3443         }
3444         exit(1);
3445 }
3446
3447
3448 static void ctdb_alarm(int sig)
3449 {
3450         printf("Maximum runtime exceeded - exiting\n");
3451         _exit(ERR_TIMEOUT);
3452 }
3453
3454 /*
3455   main program
3456 */
3457 int main(int argc, const char *argv[])
3458 {
3459         struct ctdb_context *ctdb;
3460         char *nodestring = NULL;
3461         struct poptOption popt_options[] = {
3462                 POPT_AUTOHELP
3463                 POPT_CTDB_CMDLINE
3464                 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3465                 { "node",      'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3466                 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3467                 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3468                 POPT_TABLEEND
3469         };
3470         int opt;
3471         const char **extra_argv;
3472         int extra_argc = 0;
3473         int ret=-1, i;
3474         poptContext pc;
3475         struct event_context *ev;
3476         const char *control;
3477
3478         setlinebuf(stdout);
3479         
3480         /* set some defaults */
3481         options.maxruntime = 0;
3482         options.timelimit = 3;
3483         options.pnn = CTDB_CURRENT_NODE;
3484
3485         pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3486
3487         while ((opt = poptGetNextOpt(pc)) != -1) {
3488                 switch (opt) {
3489                 default:
3490                         DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n", 
3491                                 poptBadOption(pc, 0), poptStrerror(opt)));
3492                         exit(1);
3493                 }
3494         }
3495
3496         /* setup the remaining options for the main program to use */
3497         extra_argv = poptGetArgs(pc);
3498         if (extra_argv) {
3499                 extra_argv++;
3500                 while (extra_argv[extra_argc]) extra_argc++;
3501         }
3502
3503         if (extra_argc < 1) {
3504                 usage();
3505         }
3506
3507         if (options.maxruntime == 0) {
3508                 const char *ctdb_timeout;
3509                 ctdb_timeout = getenv("CTDB_TIMEOUT");
3510                 if (ctdb_timeout != NULL) {
3511                         options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3512                 } else {
3513                         /* default timeout is 120 seconds */
3514                         options.maxruntime = 120;
3515                 }
3516         }
3517
3518         signal(SIGALRM, ctdb_alarm);
3519         alarm(options.maxruntime);
3520
3521         /* setup the node number to contact */
3522         if (nodestring != NULL) {
3523                 if (strcmp(nodestring, "all") == 0) {
3524                         options.pnn = CTDB_BROADCAST_ALL;
3525                 } else {
3526                         options.pnn = strtoul(nodestring, NULL, 0);
3527                 }
3528         }
3529
3530         control = extra_argv[0];
3531
3532         ev = event_context_init(NULL);
3533
3534         for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3535                 if (strcmp(control, ctdb_commands[i].name) == 0) {
3536                         int j;
3537
3538                         if (ctdb_commands[i].without_daemon == true) {
3539                                 close(2);
3540                         }
3541
3542                         /* initialise ctdb */
3543                         ctdb = ctdb_cmdline_client(ev);
3544
3545                         if (ctdb_commands[i].without_daemon == false) {
3546                                 if (ctdb == NULL) {
3547                                         DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3548                                         exit(1);
3549                                 }
3550
3551                                 /* verify the node exists */
3552                                 verify_node(ctdb);
3553
3554                                 if (options.pnn == CTDB_CURRENT_NODE) {
3555                                         int pnn;
3556                                         pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);         
3557                                         if (pnn == -1) {
3558                                                 return -1;
3559                                         }
3560                                         options.pnn = pnn;
3561                                 }
3562                         }
3563
3564                         if (ctdb_commands[i].auto_all && 
3565                             options.pnn == CTDB_BROADCAST_ALL) {
3566                                 uint32_t *nodes;
3567                                 uint32_t num_nodes;
3568                                 ret = 0;
3569
3570                                 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
3571                                 CTDB_NO_MEMORY(ctdb, nodes);
3572         
3573                                 for (j=0;j<num_nodes;j++) {
3574                                         options.pnn = nodes[j];
3575                                         ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3576                                 }
3577                                 talloc_free(nodes);
3578                         } else {
3579                                 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3580                         }
3581                         break;
3582                 }
3583         }
3584
3585         if (i == ARRAY_SIZE(ctdb_commands)) {
3586                 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));
3587                 exit(1);
3588         }
3589
3590         return ret;
3591 }