allow setting the recmode even when not completely frozen.
[sahlberg/ctdb.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 static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn)
860 {
861         struct ctdb_all_public_ips *ips;
862         struct ctdb_public_ip ip;
863         int i, ret;
864         uint32_t *nodes;
865         uint32_t disable_time;
866         TDB_DATA data;
867         struct ctdb_node_map *nodemap=NULL;
868         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
869
870         disable_time = 30;
871         data.dptr  = (uint8_t*)&disable_time;
872         data.dsize = sizeof(disable_time);
873         ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
874         if (ret != 0) {
875                 DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
876                 return -1;
877         }
878
879
880
881         /* read the public ip list from the node */
882         ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
883         if (ret != 0) {
884                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
885                 talloc_free(tmp_ctx);
886                 return -1;
887         }
888
889         for (i=0;i<ips->num;i++) {
890                 if (ctdb_same_ip(addr, &ips->ips[i].addr)) {
891                         break;
892                 }
893         }
894         if (i==ips->num) {
895                 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
896                         pnn, ctdb_addr_to_str(addr)));
897                 talloc_free(tmp_ctx);
898                 return -1;
899         }
900
901         ip.pnn  = pnn;
902         ip.addr = *addr;
903
904         data.dptr  = (uint8_t *)&ip;
905         data.dsize = sizeof(ip);
906
907         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &nodemap);
908         if (ret != 0) {
909                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
910                 talloc_free(tmp_ctx);
911                 return ret;
912         }
913
914         nodes = list_of_active_nodes_except_pnn(ctdb, nodemap, tmp_ctx, pnn);
915         ret = ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
916                                         nodes, 0,
917                                         TIMELIMIT(),
918                                         false, data,
919                                         NULL, NULL,
920                                         NULL);
921         if (ret != 0) {
922                 DEBUG(DEBUG_ERR,("Failed to release IP on nodes\n"));
923                 talloc_free(tmp_ctx);
924                 return -1;
925         }
926
927         ret = ctdb_ctrl_takeover_ip(ctdb, TIMELIMIT(), pnn, &ip);
928         if (ret != 0) {
929                 DEBUG(DEBUG_ERR,("Failed to take over IP on node %d\n", pnn));
930                 talloc_free(tmp_ctx);
931                 return -1;
932         }
933
934         talloc_free(tmp_ctx);
935         return 0;
936 }
937
938 /*
939   move/failover an ip address to a specific node
940  */
941 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
942 {
943         uint32_t pnn;
944         ctdb_sock_addr addr;
945
946         if (argc < 2) {
947                 usage();
948                 return -1;
949         }
950
951         if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
952                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
953                 return -1;
954         }
955
956
957         if (sscanf(argv[1], "%u", &pnn) != 1) {
958                 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
959                 return -1;
960         }
961
962         if (move_ip(ctdb, &addr, pnn) != 0) {
963                 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
964                 return -1;
965         }
966
967         return 0;
968 }
969
970 void getips_store_callback(void *param, void *data)
971 {
972         struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
973         struct ctdb_all_public_ips *ips = param;
974         int i;
975
976         i = ips->num++;
977         ips->ips[i].pnn  = node_ip->pnn;
978         ips->ips[i].addr = node_ip->addr;
979 }
980
981 void getips_count_callback(void *param, void *data)
982 {
983         uint32_t *count = param;
984
985         (*count)++;
986 }
987
988 #define IP_KEYLEN       4
989 static uint32_t *ip_key(ctdb_sock_addr *ip)
990 {
991         static uint32_t key[IP_KEYLEN];
992
993         bzero(key, sizeof(key));
994
995         switch (ip->sa.sa_family) {
996         case AF_INET:
997                 key[0]  = ip->ip.sin_addr.s_addr;
998                 break;
999         case AF_INET6:
1000                 key[0]  = ip->ip6.sin6_addr.s6_addr32[3];
1001                 key[1]  = ip->ip6.sin6_addr.s6_addr32[2];
1002                 key[2]  = ip->ip6.sin6_addr.s6_addr32[1];
1003                 key[3]  = ip->ip6.sin6_addr.s6_addr32[0];
1004                 break;
1005         default:
1006                 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
1007                 return key;
1008         }
1009
1010         return key;
1011 }
1012
1013 static void *add_ip_callback(void *parm, void *data)
1014 {
1015         return parm;
1016 }
1017
1018 static int
1019 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
1020 {
1021         struct ctdb_all_public_ips *tmp_ips;
1022         struct ctdb_node_map *nodemap=NULL;
1023         trbt_tree_t *ip_tree;
1024         int i, j, len, ret;
1025         uint32_t count;
1026
1027         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1028         if (ret != 0) {
1029                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1030                 return ret;
1031         }
1032
1033         ip_tree = trbt_create(tmp_ctx, 0);
1034
1035         for(i=0;i<nodemap->num;i++){
1036                 if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
1037                         continue;
1038                 }
1039                 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1040                         continue;
1041                 }
1042
1043                 /* read the public ip list from this node */
1044                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
1045                 if (ret != 0) {
1046                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1047                         return -1;
1048                 }
1049         
1050                 for (j=0; j<tmp_ips->num;j++) {
1051                         struct ctdb_public_ip *node_ip;
1052
1053                         node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
1054                         node_ip->pnn  = tmp_ips->ips[j].pnn;
1055                         node_ip->addr = tmp_ips->ips[j].addr;
1056
1057                         trbt_insertarray32_callback(ip_tree,
1058                                 IP_KEYLEN, ip_key(&tmp_ips->ips[j].addr),
1059                                 add_ip_callback,
1060                                 node_ip);
1061                 }
1062                 talloc_free(tmp_ips);
1063         }
1064
1065         /* traverse */
1066         count = 0;
1067         trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &count);
1068
1069         len = offsetof(struct ctdb_all_public_ips, ips) + 
1070                 count*sizeof(struct ctdb_public_ip);
1071         tmp_ips = talloc_zero_size(tmp_ctx, len);
1072         trbt_traversearray32(ip_tree, IP_KEYLEN, getips_store_callback, tmp_ips);
1073
1074         *ips = tmp_ips;
1075
1076         return 0;
1077 }
1078
1079
1080 /* 
1081  * scans all other nodes and returns a pnn for another node that can host this 
1082  * ip address or -1
1083  */
1084 static int
1085 find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
1086 {
1087         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1088         struct ctdb_all_public_ips *ips;
1089         struct ctdb_node_map *nodemap=NULL;
1090         int i, j, ret;
1091
1092         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1093         if (ret != 0) {
1094                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1095                 talloc_free(tmp_ctx);
1096                 return ret;
1097         }
1098
1099         for(i=0;i<nodemap->num;i++){
1100                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1101                         continue;
1102                 }
1103                 if (nodemap->nodes[i].pnn == options.pnn) {
1104                         continue;
1105                 }
1106
1107                 /* read the public ip list from this node */
1108                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
1109                 if (ret != 0) {
1110                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
1111                         return -1;
1112                 }
1113
1114                 for (j=0;j<ips->num;j++) {
1115                         if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1116                                 talloc_free(tmp_ctx);
1117                                 return nodemap->nodes[i].pnn;
1118                         }
1119                 }
1120                 talloc_free(ips);
1121         }
1122
1123         talloc_free(tmp_ctx);
1124         return -1;
1125 }
1126
1127 /*
1128   add a public ip address to a node
1129  */
1130 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
1131 {
1132         int i, ret;
1133         int len;
1134         uint32_t pnn;
1135         unsigned mask;
1136         ctdb_sock_addr addr;
1137         struct ctdb_control_ip_iface *pub;
1138         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1139         struct ctdb_all_public_ips *ips;
1140
1141
1142         if (argc != 2) {
1143                 talloc_free(tmp_ctx);
1144                 usage();
1145         }
1146
1147         if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
1148                 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
1149                 talloc_free(tmp_ctx);
1150                 return -1;
1151         }
1152
1153         ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1154         if (ret != 0) {
1155                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1156                 talloc_free(tmp_ctx);
1157                 return ret;
1158         }
1159
1160
1161         /* check if some other node is already serving this ip, if not,
1162          * we will claim it
1163          */
1164         for (i=0;i<ips->num;i++) {
1165                 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1166                         break;
1167                 }
1168         }
1169
1170         len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
1171         pub = talloc_size(tmp_ctx, len); 
1172         CTDB_NO_MEMORY(ctdb, pub);
1173
1174         pub->addr  = addr;
1175         pub->mask  = mask;
1176         pub->len   = strlen(argv[1])+1;
1177         memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
1178
1179         ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
1180         if (ret != 0) {
1181                 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
1182                 talloc_free(tmp_ctx);
1183                 return ret;
1184         }
1185
1186         if (i == ips->num) {
1187                 /* no one has this ip so we claim it */
1188                 pnn  = options.pnn;
1189         } else {
1190                 pnn  = ips->ips[i].pnn;
1191         }
1192
1193         if (move_ip(ctdb, &addr, pnn) != 0) {
1194                 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
1195                 return -1;
1196         }
1197
1198         talloc_free(tmp_ctx);
1199         return 0;
1200 }
1201
1202 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
1203
1204 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
1205 {
1206         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1207         struct ctdb_node_map *nodemap=NULL;
1208         struct ctdb_all_public_ips *ips;
1209         int ret, i, j;
1210
1211         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
1212         if (ret != 0) {
1213                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from current node\n"));
1214                 return ret;
1215         }
1216
1217         /* remove it from the nodes that are not hosting the ip currently */
1218         for(i=0;i<nodemap->num;i++){
1219                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1220                         continue;
1221                 }
1222                 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1223                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1224                         continue;
1225                 }
1226
1227                 for (j=0;j<ips->num;j++) {
1228                         if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1229                                 break;
1230                         }
1231                 }
1232                 if (j==ips->num) {
1233                         continue;
1234                 }
1235
1236                 if (ips->ips[j].pnn == nodemap->nodes[i].pnn) {
1237                         continue;
1238                 }
1239
1240                 options.pnn = nodemap->nodes[i].pnn;
1241                 control_delip(ctdb, argc, argv);
1242         }
1243
1244
1245         /* remove it from every node (also the one hosting it) */
1246         for(i=0;i<nodemap->num;i++){
1247                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1248                         continue;
1249                 }
1250                 if (ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips) != 0) {
1251                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %d\n", nodemap->nodes[i].pnn));
1252                         continue;
1253                 }
1254
1255                 for (j=0;j<ips->num;j++) {
1256                         if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
1257                                 break;
1258                         }
1259                 }
1260                 if (j==ips->num) {
1261                         continue;
1262                 }
1263
1264                 options.pnn = nodemap->nodes[i].pnn;
1265                 control_delip(ctdb, argc, argv);
1266         }
1267
1268         talloc_free(tmp_ctx);
1269         return 0;
1270 }
1271         
1272 /*
1273   delete a public ip address from a node
1274  */
1275 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
1276 {
1277         int i, ret;
1278         ctdb_sock_addr addr;
1279         struct ctdb_control_ip_iface pub;
1280         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1281         struct ctdb_all_public_ips *ips;
1282
1283         if (argc != 1) {
1284                 talloc_free(tmp_ctx);
1285                 usage();
1286         }
1287
1288         if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
1289                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
1290                 return -1;
1291         }
1292
1293         if (options.pnn == CTDB_BROADCAST_ALL) {
1294                 return control_delip_all(ctdb, argc, argv, &addr);
1295         }
1296
1297         pub.addr  = addr;
1298         pub.mask  = 0;
1299         pub.len   = 0;
1300
1301         ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1302         if (ret != 0) {
1303                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
1304                 talloc_free(tmp_ctx);
1305                 return ret;
1306         }
1307         
1308         for (i=0;i<ips->num;i++) {
1309                 if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
1310                         break;
1311                 }
1312         }
1313
1314         if (i==ips->num) {
1315                 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
1316                         ctdb_addr_to_str(&addr)));
1317                 talloc_free(tmp_ctx);
1318                 return -1;
1319         }
1320
1321         if (ips->ips[i].pnn == options.pnn) {
1322                 ret = find_other_host_for_public_ip(ctdb, &addr);
1323                 if (ret != -1) {
1324                         if (move_ip(ctdb, &addr, ret) != 0) {
1325                                 DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
1326                                 return -1;
1327                         }
1328                 }
1329         }
1330
1331         ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
1332         if (ret != 0) {
1333                 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
1334                 talloc_free(tmp_ctx);
1335                 return ret;
1336         }
1337
1338         talloc_free(tmp_ctx);
1339         return 0;
1340 }
1341
1342 /*
1343   kill a tcp connection
1344  */
1345 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1346 {
1347         int ret;
1348         struct ctdb_control_killtcp killtcp;
1349
1350         if (argc < 2) {
1351                 usage();
1352         }
1353
1354         if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
1355                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1356                 return -1;
1357         }
1358
1359         if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
1360                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1361                 return -1;
1362         }
1363
1364         ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
1365         if (ret != 0) {
1366                 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
1367                 return ret;
1368         }
1369
1370         return 0;
1371 }
1372
1373
1374 /*
1375   send a gratious arp
1376  */
1377 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
1378 {
1379         int ret;
1380         ctdb_sock_addr addr;
1381
1382         if (argc < 2) {
1383                 usage();
1384         }
1385
1386         if (!parse_ip(argv[0], NULL, 0, &addr)) {
1387                 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
1388                 return -1;
1389         }
1390
1391         ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
1392         if (ret != 0) {
1393                 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
1394                 return ret;
1395         }
1396
1397         return 0;
1398 }
1399
1400 /*
1401   register a server id
1402  */
1403 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1404 {
1405         int ret;
1406         struct ctdb_server_id server_id;
1407
1408         if (argc < 3) {
1409                 usage();
1410         }
1411
1412         server_id.pnn       = strtoul(argv[0], NULL, 0);
1413         server_id.type      = strtoul(argv[1], NULL, 0);
1414         server_id.server_id = strtoul(argv[2], NULL, 0);
1415
1416         ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
1417         if (ret != 0) {
1418                 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
1419                 return ret;
1420         }
1421         return -1;
1422 }
1423
1424 /*
1425   unregister a server id
1426  */
1427 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1428 {
1429         int ret;
1430         struct ctdb_server_id server_id;
1431
1432         if (argc < 3) {
1433                 usage();
1434         }
1435
1436         server_id.pnn       = strtoul(argv[0], NULL, 0);
1437         server_id.type      = strtoul(argv[1], NULL, 0);
1438         server_id.server_id = strtoul(argv[2], NULL, 0);
1439
1440         ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
1441         if (ret != 0) {
1442                 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
1443                 return ret;
1444         }
1445         return -1;
1446 }
1447
1448 /*
1449   check if a server id exists
1450  */
1451 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
1452 {
1453         uint32_t status;
1454         int ret;
1455         struct ctdb_server_id server_id;
1456
1457         if (argc < 3) {
1458                 usage();
1459         }
1460
1461         server_id.pnn       = strtoul(argv[0], NULL, 0);
1462         server_id.type      = strtoul(argv[1], NULL, 0);
1463         server_id.server_id = strtoul(argv[2], NULL, 0);
1464
1465         ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
1466         if (ret != 0) {
1467                 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
1468                 return ret;
1469         }
1470
1471         if (status) {
1472                 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
1473         } else {
1474                 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
1475         }
1476         return 0;
1477 }
1478
1479 /*
1480   get a list of all server ids that are registered on a node
1481  */
1482 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
1483 {
1484         int i, ret;
1485         struct ctdb_server_id_list *server_ids;
1486
1487         ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
1488         if (ret != 0) {
1489                 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
1490                 return ret;
1491         }
1492
1493         for (i=0; i<server_ids->num; i++) {
1494                 printf("Server id %d:%d:%d\n", 
1495                         server_ids->server_ids[i].pnn, 
1496                         server_ids->server_ids[i].type, 
1497                         server_ids->server_ids[i].server_id); 
1498         }
1499
1500         return -1;
1501 }
1502
1503 /*
1504   send a tcp tickle ack
1505  */
1506 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
1507 {
1508         int ret;
1509         ctdb_sock_addr  src, dst;
1510
1511         if (argc < 2) {
1512                 usage();
1513         }
1514
1515         if (!parse_ip_port(argv[0], &src)) {
1516                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1517                 return -1;
1518         }
1519
1520         if (!parse_ip_port(argv[1], &dst)) {
1521                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1522                 return -1;
1523         }
1524
1525         ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1526         if (ret==0) {
1527                 return 0;
1528         }
1529         DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1530
1531         return -1;
1532 }
1533
1534
1535 /*
1536   display public ip status
1537  */
1538 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1539 {
1540         int i, ret;
1541         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1542         struct ctdb_all_public_ips *ips;
1543
1544         if (options.pnn == CTDB_BROADCAST_ALL) {
1545                 /* read the list of public ips from all nodes */
1546                 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1547         } else {
1548                 /* read the public ip list from this node */
1549                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1550         }
1551         if (ret != 0) {
1552                 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1553                 talloc_free(tmp_ctx);
1554                 return ret;
1555         }
1556
1557         if (options.machinereadable){
1558                 printf(":Public IP:Node:\n");
1559         } else {
1560                 if (options.pnn == CTDB_BROADCAST_ALL) {
1561                         printf("Public IPs on ALL nodes\n");
1562                 } else {
1563                         printf("Public IPs on node %u\n", options.pnn);
1564                 }
1565         }
1566
1567         for (i=1;i<=ips->num;i++) {
1568                 if (options.machinereadable){
1569                         printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1570                 } else {
1571                         printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
1572                 }
1573         }
1574
1575         talloc_free(tmp_ctx);
1576         return 0;
1577 }
1578
1579 /*
1580   display pid of a ctdb daemon
1581  */
1582 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1583 {
1584         uint32_t pid;
1585         int ret;
1586
1587         ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1588         if (ret != 0) {
1589                 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1590                 return ret;
1591         }
1592         printf("Pid:%d\n", pid);
1593
1594         return 0;
1595 }
1596
1597 /*
1598   handler for receiving the response to ipreallocate
1599 */
1600 static void ip_reallocate_handler(struct ctdb_context *ctdb, uint64_t srvid, 
1601                              TDB_DATA data, void *private_data)
1602 {
1603         exit(0);
1604 }
1605
1606 static void ctdb_every_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
1607 {
1608         struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
1609
1610         event_add_timed(ctdb->ev, ctdb, 
1611                                 timeval_current_ofs(1, 0),
1612                                 ctdb_every_second, ctdb);
1613 }
1614
1615 /*
1616   ask the recovery daemon on the recovery master to perform a ip reallocation
1617  */
1618 static int control_ipreallocate(struct ctdb_context *ctdb, int argc, const char **argv)
1619 {
1620         int i, ret;
1621         TDB_DATA data;
1622         struct rd_memdump_reply rd;
1623         uint32_t recmaster;
1624         struct ctdb_node_map *nodemap=NULL;
1625         int retries=0;
1626         struct timeval tv = timeval_current();
1627
1628         /* we need some events to trigger so we can timeout and restart
1629            the loop
1630         */
1631         event_add_timed(ctdb->ev, ctdb, 
1632                                 timeval_current_ofs(1, 0),
1633                                 ctdb_every_second, ctdb);
1634
1635         rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
1636         if (rd.pnn == -1) {
1637                 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
1638                 return -1;
1639         }
1640         rd.srvid = getpid();
1641
1642         /* register a message port for receiveing the reply so that we
1643            can receive the reply
1644         */
1645         ctdb_set_message_handler(ctdb, rd.srvid, ip_reallocate_handler, NULL);
1646
1647         data.dptr = (uint8_t *)&rd;
1648         data.dsize = sizeof(rd);
1649
1650 again:
1651         if (retries>5) {
1652                 DEBUG(DEBUG_ERR,("Failed waiting for cluster convergense\n"));
1653                 exit(10);
1654         }
1655
1656         /* check that there are valid nodes available */
1657         if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap) != 0) {
1658                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1659                 exit(10);
1660         }
1661         for (i=0; i<nodemap->num;i++) {
1662                 if ((nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) == 0) {
1663                         break;
1664                 }
1665         }
1666         if (i==nodemap->num) {
1667                 DEBUG(DEBUG_ERR,("No recmaster available, no need to wait for cluster convergence\n"));
1668                 return 0;
1669         }
1670
1671
1672         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1673         if (ret != 0) {
1674                 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1675                 return ret;
1676         }
1677
1678         /* verify the node exists */
1679         if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), recmaster, ctdb, &nodemap) != 0) {
1680                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1681                 exit(10);
1682         }
1683
1684
1685         /* check tha there are nodes available that can act as a recmaster */
1686         for (i=0; i<nodemap->num; i++) {
1687                 if (nodemap->nodes[i].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1688                         continue;
1689                 }
1690         }
1691         if (i == nodemap->num) {
1692                 return 0;
1693         }
1694
1695         /* verify the recovery master is not STOPPED, nor BANNED */
1696         if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1697                 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1698                 retries++;
1699                 sleep(1);
1700                 goto again;
1701         } 
1702
1703         
1704         /* verify the recovery master is not STOPPED, nor BANNED */
1705         if (nodemap->nodes[recmaster].flags & (NODE_FLAGS_DELETED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
1706                 DEBUG(DEBUG_ERR,("No suitable recmaster found. Try again\n"));
1707                 retries++;
1708                 sleep(1);
1709                 goto again;
1710         } 
1711
1712         ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_TAKEOVER_RUN, data);
1713         if (ret != 0) {
1714                 DEBUG(DEBUG_ERR,("Failed to send ip takeover run request message to %u\n", options.pnn));
1715                 return -1;
1716         }
1717
1718         tv = timeval_current();
1719         /* this loop will terminate when we have received the reply */
1720         while (timeval_elapsed(&tv) < 3.0) {    
1721                 event_loop_once(ctdb->ev);
1722         }
1723
1724         DEBUG(DEBUG_INFO,("Timed out waiting for recmaster ipreallocate. Trying again\n"));
1725         retries++;
1726         sleep(1);
1727         goto again;
1728
1729         return 0;
1730 }
1731
1732
1733 /*
1734   disable a remote node
1735  */
1736 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1737 {
1738         int ret;
1739         struct ctdb_node_map *nodemap=NULL;
1740
1741         do {
1742                 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1743                 if (ret != 0) {
1744                         DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1745                         return ret;
1746                 }
1747
1748                 sleep(1);
1749
1750                 /* read the nodemap and verify the change took effect */
1751                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1752                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1753                         exit(10);
1754                 }
1755
1756         } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED));
1757         ret = control_ipreallocate(ctdb, argc, argv);
1758         if (ret != 0) {
1759                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1760                 return ret;
1761         }
1762
1763         return 0;
1764 }
1765
1766 /*
1767   enable a disabled remote node
1768  */
1769 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1770 {
1771         int ret;
1772
1773         struct ctdb_node_map *nodemap=NULL;
1774
1775         do {
1776                 ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1777                 if (ret != 0) {
1778                         DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1779                         return ret;
1780                 }
1781
1782                 sleep(1);
1783
1784                 /* read the nodemap and verify the change took effect */
1785                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1786                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1787                         exit(10);
1788                 }
1789
1790         } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_PERMANENTLY_DISABLED);
1791         ret = control_ipreallocate(ctdb, argc, argv);
1792         if (ret != 0) {
1793                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1794                 return ret;
1795         }
1796
1797         return 0;
1798 }
1799
1800 /*
1801   stop a remote node
1802  */
1803 static int control_stop(struct ctdb_context *ctdb, int argc, const char **argv)
1804 {
1805         int ret;
1806         struct ctdb_node_map *nodemap=NULL;
1807
1808         do {
1809                 ret = ctdb_ctrl_stop_node(ctdb, TIMELIMIT(), options.pnn);
1810                 if (ret != 0) {
1811                         DEBUG(DEBUG_ERR, ("Unable to stop node %u   try again\n", options.pnn));
1812                 }
1813         
1814                 sleep(1);
1815
1816                 /* read the nodemap and verify the change took effect */
1817                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1818                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1819                         exit(10);
1820                 }
1821
1822         } while (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED));
1823         ret = control_ipreallocate(ctdb, argc, argv);
1824         if (ret != 0) {
1825                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1826                 return ret;
1827         }
1828
1829         return 0;
1830 }
1831
1832 /*
1833   restart a stopped remote node
1834  */
1835 static int control_continue(struct ctdb_context *ctdb, int argc, const char **argv)
1836 {
1837         int ret;
1838
1839         struct ctdb_node_map *nodemap=NULL;
1840
1841         do {
1842                 ret = ctdb_ctrl_continue_node(ctdb, TIMELIMIT(), options.pnn);
1843                 if (ret != 0) {
1844                         DEBUG(DEBUG_ERR, ("Unable to continue node %u\n", options.pnn));
1845                         return ret;
1846                 }
1847         
1848                 sleep(1);
1849
1850                 /* read the nodemap and verify the change took effect */
1851                 if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
1852                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1853                         exit(10);
1854                 }
1855
1856         } while (nodemap->nodes[options.pnn].flags & NODE_FLAGS_STOPPED);
1857         ret = control_ipreallocate(ctdb, argc, argv);
1858         if (ret != 0) {
1859                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1860                 return ret;
1861         }
1862
1863         return 0;
1864 }
1865
1866 static uint32_t get_generation(struct ctdb_context *ctdb)
1867 {
1868         struct ctdb_vnn_map *vnnmap=NULL;
1869         int ret;
1870
1871         /* wait until the recmaster is not in recovery mode */
1872         while (1) {
1873                 uint32_t recmode, recmaster;
1874                 
1875                 if (vnnmap != NULL) {
1876                         talloc_free(vnnmap);
1877                         vnnmap = NULL;
1878                 }
1879
1880                 /* get the recmaster */
1881                 ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
1882                 if (ret != 0) {
1883                         DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
1884                         exit(10);
1885                 }
1886
1887                 /* get recovery mode */
1888                 ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
1889                 if (ret != 0) {
1890                         DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
1891                         exit(10);
1892                 }
1893
1894                 /* get the current generation number */
1895                 ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
1896                 if (ret != 0) {
1897                         DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
1898                         exit(10);
1899                 }
1900
1901                 if ((recmode == CTDB_RECOVERY_NORMAL)
1902                 &&  (vnnmap->generation != 1)){
1903                         return vnnmap->generation;
1904                 }
1905                 sleep(1);
1906         }
1907 }
1908
1909 /*
1910   ban a node from the cluster
1911  */
1912 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
1913 {
1914         int ret;
1915         struct ctdb_node_map *nodemap=NULL;
1916         struct ctdb_ban_time bantime;
1917
1918         if (argc < 1) {
1919                 usage();
1920         }
1921         
1922         /* verify the node exists */
1923         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1924         if (ret != 0) {
1925                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1926                 return ret;
1927         }
1928
1929         if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
1930                 DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
1931                 return -1;
1932         }
1933
1934         bantime.pnn  = options.pnn;
1935         bantime.time = strtoul(argv[0], NULL, 0);
1936
1937         ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1938         if (ret != 0) {
1939                 DEBUG(DEBUG_ERR,("Banning node %d for %d seconds failed.\n", bantime.pnn, bantime.time));
1940                 return -1;
1941         }       
1942
1943         ret = control_ipreallocate(ctdb, argc, argv);
1944         if (ret != 0) {
1945                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1946                 return ret;
1947         }
1948
1949         return 0;
1950 }
1951
1952
1953 /*
1954   unban a node from the cluster
1955  */
1956 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
1957 {
1958         int ret;
1959         struct ctdb_node_map *nodemap=NULL;
1960         struct ctdb_ban_time bantime;
1961
1962         /* verify the node exists */
1963         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
1964         if (ret != 0) {
1965                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
1966                 return ret;
1967         }
1968
1969         if (!(nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED)) {
1970                 DEBUG(DEBUG_ERR,("Node %u is not banned.\n", options.pnn));
1971                 return -1;
1972         }
1973
1974         bantime.pnn  = options.pnn;
1975         bantime.time = 0;
1976
1977         ret = ctdb_ctrl_set_ban(ctdb, TIMELIMIT(), options.pnn, &bantime);
1978         if (ret != 0) {
1979                 DEBUG(DEBUG_ERR,("Unbanning node %d failed.\n", bantime.pnn));
1980                 return -1;
1981         }       
1982
1983         ret = control_ipreallocate(ctdb, argc, argv);
1984         if (ret != 0) {
1985                 DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
1986                 return ret;
1987         }
1988
1989         return 0;
1990 }
1991
1992
1993 /*
1994   show ban information for a node
1995  */
1996 static int control_showban(struct ctdb_context *ctdb, int argc, const char **argv)
1997 {
1998         int ret;
1999         struct ctdb_node_map *nodemap=NULL;
2000         struct ctdb_ban_time *bantime;
2001
2002         /* verify the node exists */
2003         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2004         if (ret != 0) {
2005                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2006                 return ret;
2007         }
2008
2009         ret = ctdb_ctrl_get_ban(ctdb, TIMELIMIT(), options.pnn, ctdb, &bantime);
2010         if (ret != 0) {
2011                 DEBUG(DEBUG_ERR,("Showing ban info for node %d failed.\n", options.pnn));
2012                 return -1;
2013         }       
2014
2015         if (bantime->time == 0) {
2016                 printf("Node %u is not banned\n", bantime->pnn);
2017         } else {
2018                 printf("Node %u is banned banned for %d seconds\n", bantime->pnn, bantime->time);
2019         }
2020
2021         return 0;
2022 }
2023
2024 /*
2025   shutdown a daemon
2026  */
2027 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
2028 {
2029         int ret;
2030
2031         ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
2032         if (ret != 0) {
2033                 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
2034                 return ret;
2035         }
2036
2037         return 0;
2038 }
2039
2040 /*
2041   trigger a recovery
2042  */
2043 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
2044 {
2045         int ret;
2046         uint32_t generation, next_generation;
2047
2048         /* record the current generation number */
2049         generation = get_generation(ctdb);
2050
2051         ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, 1);
2052         if (ret != 0) {
2053                 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
2054                 return ret;
2055         }
2056
2057         ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2058         if (ret != 0) {
2059                 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
2060                 return ret;
2061         }
2062
2063         /* wait until we are in a new generation */
2064         while (1) {
2065                 next_generation = get_generation(ctdb);
2066                 if (next_generation != generation) {
2067                         return 0;
2068                 }
2069                 sleep(1);
2070         }
2071
2072         return 0;
2073 }
2074
2075
2076 /*
2077   display monitoring mode of a remote node
2078  */
2079 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
2080 {
2081         uint32_t monmode;
2082         int ret;
2083
2084         ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
2085         if (ret != 0) {
2086                 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
2087                 return ret;
2088         }
2089         if (!options.machinereadable){
2090                 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
2091         } else {
2092                 printf(":mode:\n");
2093                 printf(":%d:\n",monmode);
2094         }
2095         return 0;
2096 }
2097
2098
2099 /*
2100   display capabilities of a remote node
2101  */
2102 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
2103 {
2104         uint32_t capabilities;
2105         int ret;
2106
2107         ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
2108         if (ret != 0) {
2109                 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
2110                 return ret;
2111         }
2112         
2113         if (!options.machinereadable){
2114                 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
2115                 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
2116                 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
2117                 printf("NATGW: %s\n", (capabilities&CTDB_CAP_NATGW)?"YES":"NO");
2118         } else {
2119                 printf(":RECMASTER:LMASTER:LVS:NATGW:\n");
2120                 printf(":%d:%d:%d:%d:\n",
2121                         !!(capabilities&CTDB_CAP_RECMASTER),
2122                         !!(capabilities&CTDB_CAP_LMASTER),
2123                         !!(capabilities&CTDB_CAP_LVS),
2124                         !!(capabilities&CTDB_CAP_NATGW));
2125         }
2126         return 0;
2127 }
2128
2129 /*
2130   display lvs configuration
2131  */
2132 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
2133 {
2134         uint32_t *capabilities;
2135         struct ctdb_node_map *nodemap=NULL;
2136         int i, ret;
2137         int healthy_count = 0;
2138
2139         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2140         if (ret != 0) {
2141                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2142                 return ret;
2143         }
2144
2145         capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2146         CTDB_NO_MEMORY(ctdb, capabilities);
2147         
2148         /* collect capabilities for all connected nodes */
2149         for (i=0; i<nodemap->num; i++) {
2150                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2151                         continue;
2152                 }
2153                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2154                         continue;
2155                 }
2156         
2157                 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2158                 if (ret != 0) {
2159                         DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2160                         return ret;
2161                 }
2162
2163                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2164                         continue;
2165                 }
2166
2167                 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2168                         healthy_count++;
2169                 }
2170         }
2171
2172         /* Print all LVS nodes */
2173         for (i=0; i<nodemap->num; i++) {
2174                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2175                         continue;
2176                 }
2177                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2178                         continue;
2179                 }
2180                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2181                         continue;
2182                 }
2183
2184                 if (healthy_count != 0) {
2185                         if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2186                                 continue;
2187                         }
2188                 }
2189
2190                 printf("%d:%s\n", i, 
2191                         ctdb_addr_to_str(&nodemap->nodes[i].addr));
2192         }
2193
2194         return 0;
2195 }
2196
2197 /*
2198   display who is the lvs master
2199  */
2200 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2201 {
2202         uint32_t *capabilities;
2203         struct ctdb_node_map *nodemap=NULL;
2204         int i, ret;
2205         int healthy_count = 0;
2206
2207         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2208         if (ret != 0) {
2209                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2210                 return ret;
2211         }
2212
2213         capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
2214         CTDB_NO_MEMORY(ctdb, capabilities);
2215         
2216         /* collect capabilities for all connected nodes */
2217         for (i=0; i<nodemap->num; i++) {
2218                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2219                         continue;
2220                 }
2221                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2222                         continue;
2223                 }
2224         
2225                 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
2226                 if (ret != 0) {
2227                         DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
2228                         return ret;
2229                 }
2230
2231                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2232                         continue;
2233                 }
2234
2235                 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
2236                         healthy_count++;
2237                 }
2238         }
2239
2240         /* find and show the lvsmaster */
2241         for (i=0; i<nodemap->num; i++) {
2242                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2243                         continue;
2244                 }
2245                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
2246                         continue;
2247                 }
2248                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
2249                         continue;
2250                 }
2251
2252                 if (healthy_count != 0) {
2253                         if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
2254                                 continue;
2255                         }
2256                 }
2257
2258                 if (options.machinereadable){
2259                         printf("%d\n", i);
2260                 } else {
2261                         printf("Node %d is LVS master\n", i);
2262                 }
2263                 return 0;
2264         }
2265
2266         printf("There is no LVS master\n");
2267         return -1;
2268 }
2269
2270 /*
2271   disable monitoring on a  node
2272  */
2273 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2274 {
2275         
2276         int ret;
2277
2278         ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
2279         if (ret != 0) {
2280                 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
2281                 return ret;
2282         }
2283         printf("Monitoring mode:%s\n","DISABLED");
2284
2285         return 0;
2286 }
2287
2288 /*
2289   enable monitoring on a  node
2290  */
2291 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
2292 {
2293         
2294         int ret;
2295
2296         ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
2297         if (ret != 0) {
2298                 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
2299                 return ret;
2300         }
2301         printf("Monitoring mode:%s\n","ACTIVE");
2302
2303         return 0;
2304 }
2305
2306 /*
2307   display remote list of keys/data for a db
2308  */
2309 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
2310 {
2311         const char *db_name;
2312         struct ctdb_db_context *ctdb_db;
2313         int ret;
2314
2315         if (argc < 1) {
2316                 usage();
2317         }
2318
2319         db_name = argv[0];
2320
2321
2322         if (db_exists(ctdb, db_name)) {
2323                 DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
2324                 return -1;
2325         }
2326
2327         ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2328
2329         if (ctdb_db == NULL) {
2330                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2331                 return -1;
2332         }
2333
2334         /* traverse and dump the cluster tdb */
2335         ret = ctdb_dump_db(ctdb_db, stdout);
2336         if (ret == -1) {
2337                 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
2338                 return -1;
2339         }
2340         talloc_free(ctdb_db);
2341
2342         printf("Dumped %d records\n", ret);
2343         return 0;
2344 }
2345
2346
2347 /*
2348   display a list of the databases on a remote ctdb
2349  */
2350 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
2351 {
2352         int i, ret;
2353         struct ctdb_dbid_map *dbmap=NULL;
2354
2355         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
2356         if (ret != 0) {
2357                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2358                 return ret;
2359         }
2360
2361         printf("Number of databases:%d\n", dbmap->num);
2362         for(i=0;i<dbmap->num;i++){
2363                 const char *path;
2364                 const char *name;
2365                 bool persistent;
2366
2367                 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
2368                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
2369                 persistent = dbmap->dbs[i].persistent;
2370                 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name, 
2371                        path, persistent?"PERSISTENT":"");
2372         }
2373
2374         return 0;
2375 }
2376
2377 /*
2378   check if the local node is recmaster or not
2379   it will return 1 if this node is the recmaster and 0 if it is not
2380   or if the local ctdb daemon could not be contacted
2381  */
2382 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
2383 {
2384         uint32_t mypnn, recmaster;
2385         int ret;
2386
2387         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
2388         if (mypnn == -1) {
2389                 printf("Failed to get pnn of node\n");
2390                 return 1;
2391         }
2392
2393         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
2394         if (ret != 0) {
2395                 printf("Failed to get the recmaster\n");
2396                 return 1;
2397         }
2398
2399         if (recmaster != mypnn) {
2400                 printf("this node is not the recmaster\n");
2401                 return 1;
2402         }
2403
2404         printf("this node is the recmaster\n");
2405         return 0;
2406 }
2407
2408 /*
2409   ping a node
2410  */
2411 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
2412 {
2413         int ret;
2414         struct timeval tv = timeval_current();
2415         ret = ctdb_ctrl_ping(ctdb, options.pnn);
2416         if (ret == -1) {
2417                 printf("Unable to get ping response from node %u\n", options.pnn);
2418                 return -1;
2419         } else {
2420                 printf("response from %u time=%.6f sec  (%d clients)\n", 
2421                        options.pnn, timeval_elapsed(&tv), ret);
2422         }
2423         return 0;
2424 }
2425
2426
2427 /*
2428   get a tunable
2429  */
2430 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
2431 {
2432         const char *name;
2433         uint32_t value;
2434         int ret;
2435
2436         if (argc < 1) {
2437                 usage();
2438         }
2439
2440         name = argv[0];
2441         ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
2442         if (ret == -1) {
2443                 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
2444                 return -1;
2445         }
2446
2447         printf("%-19s = %u\n", name, value);
2448         return 0;
2449 }
2450
2451 /*
2452   set a tunable
2453  */
2454 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
2455 {
2456         const char *name;
2457         uint32_t value;
2458         int ret;
2459
2460         if (argc < 2) {
2461                 usage();
2462         }
2463
2464         name = argv[0];
2465         value = strtoul(argv[1], NULL, 0);
2466
2467         ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
2468         if (ret == -1) {
2469                 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
2470                 return -1;
2471         }
2472         return 0;
2473 }
2474
2475 /*
2476   list all tunables
2477  */
2478 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
2479 {
2480         uint32_t count;
2481         const char **list;
2482         int ret, i;
2483
2484         ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
2485         if (ret == -1) {
2486                 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
2487                 return -1;
2488         }
2489
2490         for (i=0;i<count;i++) {
2491                 control_getvar(ctdb, 1, &list[i]);
2492         }
2493
2494         talloc_free(list);
2495         
2496         return 0;
2497 }
2498
2499 /*
2500   display debug level on a node
2501  */
2502 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2503 {
2504         int ret;
2505         int32_t level;
2506
2507         ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
2508         if (ret != 0) {
2509                 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
2510                 return ret;
2511         } else {
2512                 if (options.machinereadable){
2513                         printf(":Name:Level:\n");
2514                         printf(":%s:%d:\n",get_debug_by_level(level),level);
2515                 } else {
2516                         printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
2517                 }
2518         }
2519         return 0;
2520 }
2521
2522 /*
2523   display reclock file of a node
2524  */
2525 static int control_getreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2526 {
2527         int ret;
2528         const char *reclock;
2529
2530         ret = ctdb_ctrl_getreclock(ctdb, TIMELIMIT(), options.pnn, ctdb, &reclock);
2531         if (ret != 0) {
2532                 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2533                 return ret;
2534         } else {
2535                 if (options.machinereadable){
2536                         if (reclock != NULL) {
2537                                 printf("%s", reclock);
2538                         }
2539                 } else {
2540                         if (reclock == NULL) {
2541                                 printf("No reclock file used.\n");
2542                         } else {
2543                                 printf("Reclock file:%s\n", reclock);
2544                         }
2545                 }
2546         }
2547         return 0;
2548 }
2549
2550 /*
2551   set the reclock file of a node
2552  */
2553 static int control_setreclock(struct ctdb_context *ctdb, int argc, const char **argv)
2554 {
2555         int ret;
2556         const char *reclock;
2557
2558         if (argc == 0) {
2559                 reclock = NULL;
2560         } else if (argc == 1) {
2561                 reclock = argv[0];
2562         } else {
2563                 usage();
2564         }
2565
2566         ret = ctdb_ctrl_setreclock(ctdb, TIMELIMIT(), options.pnn, reclock);
2567         if (ret != 0) {
2568                 DEBUG(DEBUG_ERR, ("Unable to get reclock file from node %u\n", options.pnn));
2569                 return ret;
2570         }
2571         return 0;
2572 }
2573
2574 /*
2575   set the natgw state on/off
2576  */
2577 static int control_setnatgwstate(struct ctdb_context *ctdb, int argc, const char **argv)
2578 {
2579         int ret;
2580         uint32_t natgwstate;
2581
2582         if (argc == 0) {
2583                 usage();
2584         }
2585
2586         if (!strcmp(argv[0], "on")) {
2587                 natgwstate = 1;
2588         } else if (!strcmp(argv[0], "off")) {
2589                 natgwstate = 0;
2590         } else {
2591                 usage();
2592         }
2593
2594         ret = ctdb_ctrl_setnatgwstate(ctdb, TIMELIMIT(), options.pnn, natgwstate);
2595         if (ret != 0) {
2596                 DEBUG(DEBUG_ERR, ("Unable to set the natgw state for node %u\n", options.pnn));
2597                 return ret;
2598         }
2599
2600         return 0;
2601 }
2602
2603 /*
2604   set the lmaster role on/off
2605  */
2606 static int control_setlmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2607 {
2608         int ret;
2609         uint32_t lmasterrole;
2610
2611         if (argc == 0) {
2612                 usage();
2613         }
2614
2615         if (!strcmp(argv[0], "on")) {
2616                 lmasterrole = 1;
2617         } else if (!strcmp(argv[0], "off")) {
2618                 lmasterrole = 0;
2619         } else {
2620                 usage();
2621         }
2622
2623         ret = ctdb_ctrl_setlmasterrole(ctdb, TIMELIMIT(), options.pnn, lmasterrole);
2624         if (ret != 0) {
2625                 DEBUG(DEBUG_ERR, ("Unable to set the lmaster role for node %u\n", options.pnn));
2626                 return ret;
2627         }
2628
2629         return 0;
2630 }
2631
2632 /*
2633   set the recmaster role on/off
2634  */
2635 static int control_setrecmasterrole(struct ctdb_context *ctdb, int argc, const char **argv)
2636 {
2637         int ret;
2638         uint32_t recmasterrole;
2639
2640         if (argc == 0) {
2641                 usage();
2642         }
2643
2644         if (!strcmp(argv[0], "on")) {
2645                 recmasterrole = 1;
2646         } else if (!strcmp(argv[0], "off")) {
2647                 recmasterrole = 0;
2648         } else {
2649                 usage();
2650         }
2651
2652         ret = ctdb_ctrl_setrecmasterrole(ctdb, TIMELIMIT(), options.pnn, recmasterrole);
2653         if (ret != 0) {
2654                 DEBUG(DEBUG_ERR, ("Unable to set the recmaster role for node %u\n", options.pnn));
2655                 return ret;
2656         }
2657
2658         return 0;
2659 }
2660
2661 /*
2662   set debug level on a node or all nodes
2663  */
2664 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
2665 {
2666         int i, ret;
2667         int32_t level;
2668
2669         if (argc == 0) {
2670                 printf("You must specify the debug level. Valid levels are:\n");
2671                 for (i=0; debug_levels[i].description != NULL; i++) {
2672                         printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2673                 }
2674
2675                 return 0;
2676         }
2677
2678         if (isalpha(argv[0][0]) || argv[0][0] == '-') { 
2679                 level = get_debug_by_desc(argv[0]);
2680         } else {
2681                 level = strtol(argv[0], NULL, 0);
2682         }
2683
2684         for (i=0; debug_levels[i].description != NULL; i++) {
2685                 if (level == debug_levels[i].level) {
2686                         break;
2687                 }
2688         }
2689         if (debug_levels[i].description == NULL) {
2690                 printf("Invalid debug level, must be one of\n");
2691                 for (i=0; debug_levels[i].description != NULL; i++) {
2692                         printf("%s (%d)\n", debug_levels[i].description, debug_levels[i].level);
2693                 }
2694                 return -1;
2695         }
2696
2697         ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
2698         if (ret != 0) {
2699                 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
2700         }
2701         return 0;
2702 }
2703
2704
2705 /*
2706   freeze a node
2707  */
2708 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
2709 {
2710         int ret;
2711         uint32_t priority;
2712         
2713         if (argc == 1) {
2714                 priority = strtol(argv[0], NULL, 0);
2715         } else {
2716                 priority = 0;
2717         }
2718         DEBUG(DEBUG_ERR,("Freeze by priority %u\n", priority));
2719
2720         ret = ctdb_ctrl_freeze_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2721         if (ret != 0) {
2722                 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
2723         }               
2724         return 0;
2725 }
2726
2727 /*
2728   thaw a node
2729  */
2730 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
2731 {
2732         int ret;
2733         uint32_t priority;
2734         
2735         if (argc == 1) {
2736                 priority = strtol(argv[0], NULL, 0);
2737         } else {
2738                 priority = 0;
2739         }
2740         DEBUG(DEBUG_ERR,("Thaw by priority %u\n", priority));
2741
2742         ret = ctdb_ctrl_thaw_priority(ctdb, TIMELIMIT(), options.pnn, priority);
2743         if (ret != 0) {
2744                 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
2745         }               
2746         return 0;
2747 }
2748
2749
2750 /*
2751   attach to a database
2752  */
2753 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
2754 {
2755         const char *db_name;
2756         struct ctdb_db_context *ctdb_db;
2757
2758         if (argc < 1) {
2759                 usage();
2760         }
2761         db_name = argv[0];
2762
2763         ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
2764         if (ctdb_db == NULL) {
2765                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
2766                 return -1;
2767         }
2768
2769         return 0;
2770 }
2771
2772 /*
2773   set db priority
2774  */
2775 static int control_setdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2776 {
2777         struct ctdb_db_priority db_prio;
2778         int ret;
2779
2780         if (argc < 2) {
2781                 usage();
2782         }
2783
2784         db_prio.db_id    = strtoul(argv[0], NULL, 0);
2785         db_prio.priority = strtoul(argv[1], NULL, 0);
2786
2787         ret = ctdb_ctrl_set_db_priority(ctdb, TIMELIMIT(), options.pnn, &db_prio);
2788         if (ret != 0) {
2789                 DEBUG(DEBUG_ERR,("Unable to set db prio\n"));
2790                 return -1;
2791         }
2792
2793         return 0;
2794 }
2795
2796 /*
2797   get db priority
2798  */
2799 static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **argv)
2800 {
2801         uint32_t db_id, priority;
2802         int ret;
2803
2804         if (argc < 1) {
2805                 usage();
2806         }
2807
2808         db_id = strtoul(argv[0], NULL, 0);
2809
2810         ret = ctdb_ctrl_get_db_priority(ctdb, TIMELIMIT(), options.pnn, db_id, &priority);
2811         if (ret != 0) {
2812                 DEBUG(DEBUG_ERR,("Unable to get db prio\n"));
2813                 return -1;
2814         }
2815
2816         DEBUG(DEBUG_ERR,("Priority:%u\n", priority));
2817
2818         return 0;
2819 }
2820
2821 /*
2822   run an eventscript on a node
2823  */
2824 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
2825 {
2826         TDB_DATA data;
2827         int ret;
2828         int32_t res;
2829         char *errmsg;
2830         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2831
2832         if (argc != 1) {
2833                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2834                 return -1;
2835         }
2836
2837         data.dptr = (unsigned char *)discard_const(argv[0]);
2838         data.dsize = strlen((char *)data.dptr) + 1;
2839
2840         DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
2841
2842         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
2843                            0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
2844         if (ret != 0 || res != 0) {
2845                 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
2846                 talloc_free(tmp_ctx);
2847                 return -1;
2848         }
2849         talloc_free(tmp_ctx);
2850         return 0;
2851 }
2852
2853 #define DB_VERSION 1
2854 #define MAX_DB_NAME 64
2855 struct db_file_header {
2856         unsigned long version;
2857         time_t timestamp;
2858         unsigned long persistent;
2859         unsigned long size;
2860         const char name[MAX_DB_NAME];
2861 };
2862
2863 struct backup_data {
2864         struct ctdb_marshall_buffer *records;
2865         uint32_t len;
2866         uint32_t total;
2867         bool traverse_error;
2868 };
2869
2870 static int backup_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private)
2871 {
2872         struct backup_data *bd = talloc_get_type(private, struct backup_data);
2873         struct ctdb_rec_data *rec;
2874
2875         /* add the record */
2876         rec = ctdb_marshall_record(bd->records, 0, key, NULL, data);
2877         if (rec == NULL) {
2878                 bd->traverse_error = true;
2879                 DEBUG(DEBUG_ERR,("Failed to marshall record\n"));
2880                 return -1;
2881         }
2882         bd->records = talloc_realloc_size(NULL, bd->records, rec->length + bd->len);
2883         if (bd->records == NULL) {
2884                 DEBUG(DEBUG_ERR,("Failed to expand marshalling buffer\n"));
2885                 bd->traverse_error = true;
2886                 return -1;
2887         }
2888         bd->records->count++;
2889         memcpy(bd->len+(uint8_t *)bd->records, rec, rec->length);
2890         bd->len += rec->length;
2891         talloc_free(rec);
2892
2893         bd->total++;
2894         return 0;
2895 }
2896
2897 /*
2898  * backup a database to a file 
2899  */
2900 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
2901 {
2902         int i, ret;
2903         struct ctdb_dbid_map *dbmap=NULL;
2904         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2905         struct db_file_header dbhdr;
2906         struct ctdb_db_context *ctdb_db;
2907         struct backup_data *bd;
2908         int fh = -1;
2909         int status = -1;
2910
2911         if (argc != 2) {
2912                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
2913                 return -1;
2914         }
2915
2916         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
2917         if (ret != 0) {
2918                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
2919                 return ret;
2920         }
2921
2922         for(i=0;i<dbmap->num;i++){
2923                 const char *name;
2924
2925                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
2926                 if(!strcmp(argv[0], name)){
2927                         talloc_free(discard_const(name));
2928                         break;
2929                 }
2930                 talloc_free(discard_const(name));
2931         }
2932         if (i == dbmap->num) {
2933                 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
2934                 talloc_free(tmp_ctx);
2935                 return -1;
2936         }
2937
2938
2939         ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
2940         if (ctdb_db == NULL) {
2941                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
2942                 talloc_free(tmp_ctx);
2943                 return -1;
2944         }
2945
2946
2947         ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
2948         if (ret == -1) {
2949                 DEBUG(DEBUG_ERR,("Failed to start transaction\n"));
2950                 talloc_free(tmp_ctx);
2951                 return -1;
2952         }
2953
2954
2955         bd = talloc_zero(tmp_ctx, struct backup_data);
2956         if (bd == NULL) {
2957                 DEBUG(DEBUG_ERR,("Failed to allocate backup_data\n"));
2958                 talloc_free(tmp_ctx);
2959                 return -1;
2960         }
2961
2962         bd->records = talloc_zero(bd, struct ctdb_marshall_buffer);
2963         if (bd->records == NULL) {
2964                 DEBUG(DEBUG_ERR,("Failed to allocate ctdb_marshall_buffer\n"));
2965                 talloc_free(tmp_ctx);
2966                 return -1;
2967         }
2968
2969         bd->len = offsetof(struct ctdb_marshall_buffer, data);
2970         bd->records->db_id = ctdb_db->db_id;
2971         /* traverse the database collecting all records */
2972         if (tdb_traverse_read(ctdb_db->ltdb->tdb, backup_traverse, bd) == -1 ||
2973             bd->traverse_error) {
2974                 DEBUG(DEBUG_ERR,("Traverse error\n"));
2975                 talloc_free(tmp_ctx);
2976                 return -1;              
2977         }
2978
2979         tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2980
2981
2982         fh = open(argv[1], O_RDWR|O_CREAT, 0600);
2983         if (fh == -1) {
2984                 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
2985                 talloc_free(tmp_ctx);
2986                 return -1;
2987         }
2988
2989         dbhdr.version = DB_VERSION;
2990         dbhdr.timestamp = time(NULL);
2991         dbhdr.persistent = dbmap->dbs[i].persistent;
2992         dbhdr.size = bd->len;
2993         if (strlen(argv[0]) >= MAX_DB_NAME) {
2994                 DEBUG(DEBUG_ERR,("Too long dbname\n"));
2995                 goto done;
2996         }
2997         strncpy(discard_const(dbhdr.name), argv[0], MAX_DB_NAME);
2998         ret = write(fh, &dbhdr, sizeof(dbhdr));
2999         if (ret == -1) {
3000                 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3001                 goto done;
3002         }
3003         ret = write(fh, bd->records, bd->len);
3004         if (ret == -1) {
3005                 DEBUG(DEBUG_ERR,("write failed: %s\n", strerror(errno)));
3006                 goto done;
3007         }
3008
3009         status = 0;
3010 done:
3011         if (fh != -1) {
3012                 ret = close(fh);
3013                 if (ret == -1) {
3014                         DEBUG(DEBUG_ERR,("close failed: %s\n", strerror(errno)));
3015                 }
3016         }
3017         talloc_free(tmp_ctx);
3018         return status;
3019 }
3020
3021 /*
3022  * restore a database from a file 
3023  */
3024 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
3025 {
3026         int ret;
3027         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3028         TDB_DATA outdata;
3029         TDB_DATA data;
3030         struct db_file_header dbhdr;
3031         struct ctdb_db_context *ctdb_db;
3032         struct ctdb_node_map *nodemap=NULL;
3033         struct ctdb_vnn_map *vnnmap=NULL;
3034         int i, fh;
3035         struct ctdb_control_wipe_database w;
3036         uint32_t *nodes;
3037         uint32_t generation;
3038         struct tm *tm;
3039         char tbuf[100];
3040
3041         if (argc != 1) {
3042                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
3043                 return -1;
3044         }
3045
3046         fh = open(argv[0], O_RDONLY);
3047         if (fh == -1) {
3048                 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[0]));
3049                 talloc_free(tmp_ctx);
3050                 return -1;
3051         }
3052
3053         read(fh, &dbhdr, sizeof(dbhdr));
3054         if (dbhdr.version != DB_VERSION) {
3055                 DEBUG(DEBUG_ERR,("Invalid version of database dump. File is version %lu but expected version was %u\n", dbhdr.version, DB_VERSION));
3056                 talloc_free(tmp_ctx);
3057                 return -1;
3058         }
3059
3060         outdata.dsize = dbhdr.size;
3061         outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
3062         if (outdata.dptr == NULL) {
3063                 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
3064                 close(fh);
3065                 talloc_free(tmp_ctx);
3066                 return -1;
3067         }               
3068         read(fh, outdata.dptr, outdata.dsize);
3069         close(fh);
3070
3071         tm = localtime(&dbhdr.timestamp);
3072         strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
3073         printf("Restoring database '%s' from backup @ %s\n",
3074                 dbhdr.name, tbuf);
3075
3076
3077         ctdb_db = ctdb_attach(ctdb, dbhdr.name, dbhdr.persistent, 0);
3078         if (ctdb_db == NULL) {
3079                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", dbhdr.name));
3080                 talloc_free(tmp_ctx);
3081                 return -1;
3082         }
3083
3084         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3085         if (ret != 0) {
3086                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3087                 talloc_free(tmp_ctx);
3088                 return ret;
3089         }
3090
3091
3092         ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
3093         if (ret != 0) {
3094                 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
3095                 talloc_free(tmp_ctx);
3096                 return ret;
3097         }
3098
3099         /* freeze all nodes */
3100         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3101         for (i=1; i<=NUM_DB_PRIORITIES; i++) {
3102                 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
3103                                         nodes, i,
3104                                         TIMELIMIT(),
3105                                         false, tdb_null,
3106                                         NULL, NULL,
3107                                         NULL) != 0) {
3108                         DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
3109                         ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3110                         talloc_free(tmp_ctx);
3111                         return -1;
3112                 }
3113         }
3114
3115         generation = vnnmap->generation;
3116         data.dptr = (void *)&generation;
3117         data.dsize = sizeof(generation);
3118
3119         /* start a cluster wide transaction */
3120         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3121         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
3122                                         nodes, 0,
3123                                         TIMELIMIT(), false, data,
3124                                         NULL, NULL,
3125                                         NULL) != 0) {
3126                 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
3127                 return -1;
3128         }
3129
3130
3131         w.db_id = ctdb_db->db_id;
3132         w.transaction_id = generation;
3133
3134         data.dptr = (void *)&w;
3135         data.dsize = sizeof(w);
3136
3137         /* wipe all the remote databases. */
3138         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3139         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
3140                                         nodes, 0,
3141                                         TIMELIMIT(), false, data,
3142                                         NULL, NULL,
3143                                         NULL) != 0) {
3144                 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
3145                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3146                 talloc_free(tmp_ctx);
3147                 return -1;
3148         }
3149         
3150         /* push the database */
3151         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3152         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
3153                                         nodes, 0,
3154                                         TIMELIMIT(), false, outdata,
3155                                         NULL, NULL,
3156                                         NULL) != 0) {
3157                 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
3158                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3159                 talloc_free(tmp_ctx);
3160                 return -1;
3161         }
3162
3163         data.dptr = (void *)&generation;
3164         data.dsize = sizeof(generation);
3165
3166         /* commit all the changes */
3167         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
3168                                         nodes, 0,
3169                                         TIMELIMIT(), false, data,
3170                                         NULL, NULL,
3171                                         NULL) != 0) {
3172                 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
3173                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3174                 talloc_free(tmp_ctx);
3175                 return -1;
3176         }
3177
3178
3179         /* thaw all nodes */
3180         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
3181         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
3182                                         nodes, 0,
3183                                         TIMELIMIT(),
3184                                         false, tdb_null,
3185                                         NULL, NULL,
3186                                         NULL) != 0) {
3187                 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
3188                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
3189                 talloc_free(tmp_ctx);
3190                 return -1;
3191         }
3192
3193
3194         talloc_free(tmp_ctx);
3195         return 0;
3196 }
3197
3198 /*
3199  * set flags of a node in the nodemap
3200  */
3201 static int control_setflags(struct ctdb_context *ctdb, int argc, const char **argv)
3202 {
3203         int ret;
3204         int32_t status;
3205         int node;
3206         int flags;
3207         TDB_DATA data;
3208         struct ctdb_node_flag_change c;
3209
3210         if (argc != 2) {
3211                 usage();
3212                 return -1;
3213         }
3214
3215         if (sscanf(argv[0], "%d", &node) != 1) {
3216                 DEBUG(DEBUG_ERR, ("Badly formed node\n"));
3217                 usage();
3218                 return -1;
3219         }
3220         if (sscanf(argv[1], "0x%x", &flags) != 1) {
3221                 DEBUG(DEBUG_ERR, ("Badly formed flags\n"));
3222                 usage();
3223                 return -1;
3224         }
3225
3226         c.pnn       = node;
3227         c.old_flags = 0;
3228         c.new_flags = flags;
3229
3230         data.dsize = sizeof(c);
3231         data.dptr = (unsigned char *)&c;
3232
3233         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_MODIFY_FLAGS, 0, 
3234                            data, NULL, NULL, &status, NULL, NULL);
3235         if (ret != 0 || status != 0) {
3236                 DEBUG(DEBUG_ERR,("Failed to modify flags\n"));
3237                 return -1;
3238         }
3239         return 0;
3240 }
3241
3242 /*
3243   dump memory usage
3244  */
3245 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3246 {
3247         TDB_DATA data;
3248         int ret;
3249         int32_t res;
3250         char *errmsg;
3251         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3252         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
3253                            0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
3254         if (ret != 0 || res != 0) {
3255                 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
3256                 talloc_free(tmp_ctx);
3257                 return -1;
3258         }
3259         write(1, data.dptr, data.dsize);
3260         talloc_free(tmp_ctx);
3261         return 0;
3262 }
3263
3264 /*
3265   handler for memory dumps
3266 */
3267 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid, 
3268                              TDB_DATA data, void *private_data)
3269 {
3270         write(1, data.dptr, data.dsize);
3271         exit(0);
3272 }
3273
3274 /*
3275   dump memory usage on the recovery daemon
3276  */
3277 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
3278 {
3279         int ret;
3280         TDB_DATA data;
3281         struct rd_memdump_reply rd;
3282
3283         rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3284         if (rd.pnn == -1) {
3285                 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
3286                 return -1;
3287         }
3288         rd.srvid = getpid();
3289
3290         /* register a message port for receiveing the reply so that we
3291            can receive the reply
3292         */
3293         ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
3294
3295
3296         data.dptr = (uint8_t *)&rd;
3297         data.dsize = sizeof(rd);
3298
3299         ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
3300         if (ret != 0) {
3301                 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
3302                 return -1;
3303         }
3304
3305         /* this loop will terminate when we have received the reply */
3306         while (1) {     
3307                 event_loop_once(ctdb->ev);
3308         }
3309
3310         return 0;
3311 }
3312
3313 /*
3314   list all nodes in the cluster
3315   if the daemon is running, we read the data from the daemon.
3316   if the daemon is not running we parse the nodes file directly
3317  */
3318 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
3319 {
3320         int i, ret;
3321         struct ctdb_node_map *nodemap=NULL;
3322
3323         if (ctdb != NULL) {
3324                 ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
3325                 if (ret != 0) {
3326                         DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
3327                         return ret;
3328                 }
3329
3330                 for(i=0;i<nodemap->num;i++){
3331                         if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
3332                                 continue;
3333                         }
3334                         if (options.machinereadable){
3335                                 printf(":%d:%s:\n", nodemap->nodes[i].pnn, ctdb_addr_to_str(&nodemap->nodes[i].addr));
3336                         } else {
3337                                 printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
3338                         }
3339                 }
3340         } else {
3341                 TALLOC_CTX *mem_ctx = talloc_new(NULL);
3342                 struct pnn_node *pnn_nodes;
3343                 struct pnn_node *pnn_node;
3344         
3345                 pnn_nodes = read_nodes_file(mem_ctx);
3346                 if (pnn_nodes == NULL) {
3347                         DEBUG(DEBUG_ERR,("Failed to read nodes file\n"));
3348                         talloc_free(mem_ctx);
3349                         return -1;
3350                 }
3351
3352                 for(pnn_node=pnn_nodes;pnn_node;pnn_node=pnn_node->next) {
3353                         ctdb_sock_addr addr;
3354
3355                         if (parse_ip(pnn_node->addr, NULL, 63999, &addr) == 0) {
3356                                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s' in nodes file\n", pnn_node->addr));
3357                                 talloc_free(mem_ctx);
3358                                 return -1;
3359                         }
3360
3361                         if (options.machinereadable){
3362                                 printf(":%d:%s:\n", pnn_node->pnn, pnn_node->addr);
3363                         } else {
3364                                 printf("%s\n", pnn_node->addr);
3365                         }
3366                 }
3367                 talloc_free(mem_ctx);
3368         }
3369
3370         return 0;
3371 }
3372
3373 /*
3374   reload the nodes file on the local node
3375  */
3376 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
3377 {
3378         int i, ret;
3379         int mypnn;
3380         struct ctdb_node_map *nodemap=NULL;
3381
3382         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
3383         if (mypnn == -1) {
3384                 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
3385                 return -1;
3386         }
3387
3388         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
3389         if (ret != 0) {
3390                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
3391                 return ret;
3392         }
3393
3394         /* reload the nodes file on all remote nodes */
3395         for (i=0;i<nodemap->num;i++) {
3396                 if (nodemap->nodes[i].pnn == mypnn) {
3397                         continue;
3398                 }
3399                 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
3400                 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
3401                         nodemap->nodes[i].pnn);
3402                 if (ret != 0) {
3403                         DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
3404                 }
3405         }
3406
3407         /* reload the nodes file on the local node */
3408         DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
3409         ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
3410         if (ret != 0) {
3411                 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
3412         }
3413
3414         /* initiate a recovery */
3415         control_recover(ctdb, argc, argv);
3416
3417         return 0;
3418 }
3419
3420
3421 static const struct {
3422         const char *name;
3423         int (*fn)(struct ctdb_context *, int, const char **);
3424         bool auto_all;
3425         bool without_daemon; /* can be run without daemon running ? */
3426         const char *msg;
3427         const char *args;
3428 } ctdb_commands[] = {
3429 #ifdef CTDB_VERS
3430         { "version",         control_version,           true,   false,  "show version of ctdb" },
3431 #endif
3432         { "status",          control_status,            true,   false,  "show node status" },
3433         { "uptime",          control_uptime,            true,   false,  "show node uptime" },
3434         { "ping",            control_ping,              true,   false,  "ping all nodes" },
3435         { "getvar",          control_getvar,            true,   false,  "get a tunable variable",               "<name>"},
3436         { "setvar",          control_setvar,            true,   false,  "set a tunable variable",               "<name> <value>"},
3437         { "listvars",        control_listvars,          true,   false,  "list tunable variables"},
3438         { "statistics",      control_statistics,        false,  false, "show statistics" },
3439         { "statisticsreset", control_statistics_reset,  true,   false,  "reset statistics"},
3440         { "ip",              control_ip,                false,  false,  "show which public ip's that ctdb manages" },
3441         { "process-exists",  control_process_exists,    true,   false,  "check if a process exists on a node",  "<pid>"},
3442         { "getdbmap",        control_getdbmap,          true,   false,  "show the database map" },
3443         { "catdb",           control_catdb,             true,   false,  "dump a database" ,                     "<dbname>"},
3444         { "getmonmode",      control_getmonmode,        true,   false,  "show monitoring mode" },
3445         { "getcapabilities", control_getcapabilities,   true,   false,  "show node capabilities" },
3446         { "pnn",             control_pnn,               true,   false,  "show the pnn of the currnet node" },
3447         { "lvs",             control_lvs,               true,   false,  "show lvs configuration" },
3448         { "lvsmaster",       control_lvsmaster,         true,   false,  "show which node is the lvs master" },
3449         { "disablemonitor",      control_disable_monmode,true,  false,  "set monitoring mode to DISABLE" },
3450         { "enablemonitor",      control_enable_monmode, true,   false,  "set monitoring mode to ACTIVE" },
3451         { "setdebug",        control_setdebug,          true,   false,  "set debug level",                      "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
3452         { "getdebug",        control_getdebug,          true,   false,  "get debug level" },
3453         { "attach",          control_attach,            true,   false,  "attach to a database",                 "<dbname>" },
3454         { "dumpmemory",      control_dumpmemory,        true,   false,  "dump memory map to stdout" },
3455         { "rddumpmemory",    control_rddumpmemory,      true,   false,  "dump memory map from the recovery daemon to stdout" },
3456         { "getpid",          control_getpid,            true,   false,  "get ctdbd process ID" },
3457         { "disable",         control_disable,           true,   false,  "disable a nodes public IP" },
3458         { "enable",          control_enable,            true,   false,  "enable a nodes public IP" },
3459         { "stop",            control_stop,              true,   false,  "stop a node" },
3460         { "continue",        control_continue,          true,   false,  "re-start a stopped node" },
3461         { "ban",             control_ban,               true,   false,  "ban a node from the cluster",          "<bantime|0>"},
3462         { "unban",           control_unban,             true,   false,  "unban a node" },
3463         { "showban",         control_showban,           true,   false,  "show ban information"},
3464         { "shutdown",        control_shutdown,          true,   false,  "shutdown ctdbd" },
3465         { "recover",         control_recover,           true,   false,  "force recovery" },
3466         { "ipreallocate",    control_ipreallocate,      true,   false,  "force the recovery daemon to perform a ip reallocation procedure" },
3467         { "freeze",          control_freeze,            true,   false,  "freeze databases", "[priority:1-3]" },
3468         { "thaw",            control_thaw,              true,   false,  "thaw databases", "[priority:1-3]" },
3469         { "isnotrecmaster",  control_isnotrecmaster,    false,  false,  "check if the local node is recmaster or not" },
3470         { "killtcp",         kill_tcp,                  false,  false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
3471         { "gratiousarp",     control_gratious_arp,      false,  false, "send a gratious arp", "<ip> <interface>" },
3472         { "tickle",          tickle_tcp,                false,  false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
3473         { "gettickles",      control_get_tickles,       false,  false, "get the list of tickles registered for this ip", "<ip>" },
3474
3475         { "regsrvid",        regsrvid,                  false,  false, "register a server id", "<pnn> <type> <id>" },
3476         { "unregsrvid",      unregsrvid,                false,  false, "unregister a server id", "<pnn> <type> <id>" },
3477         { "chksrvid",        chksrvid,                  false,  false, "check if a server id exists", "<pnn> <type> <id>" },
3478         { "getsrvids",       getsrvids,                 false,  false, "get a list of all server ids"},
3479         { "vacuum",          ctdb_vacuum,               false,  false, "vacuum the databases of empty records", "[max_records]"},
3480         { "repack",          ctdb_repack,               false,  false, "repack all databases", "[max_freelist]"},
3481         { "listnodes",       control_listnodes,         false,  true, "list all nodes in the cluster"},
3482         { "reloadnodes",     control_reload_nodes_file, false,  false, "reload the nodes file and restart the transport on all nodes"},
3483         { "moveip",          control_moveip,            false,  false, "move/failover an ip address to another node", "<ip> <node>"},
3484         { "addip",           control_addip,             true,   false, "add a ip address to a node", "<ip/mask> <iface>"},
3485         { "delip",           control_delip,             false,  false, "delete an ip address from a node", "<ip>"},
3486         { "eventscript",     control_eventscript,       true,   false, "run the eventscript with the given parameters on a node", "<arguments>"},
3487         { "backupdb",        control_backupdb,          false,  false, "backup the database into a file.", "<database> <file>"},
3488         { "restoredb",        control_restoredb,        false,  false, "restore the database from a file.", "<file>"},
3489         { "recmaster",        control_recmaster,        false,  false, "show the pnn for the recovery master."},
3490         { "setflags",        control_setflags,          false,  false, "set flags for a node in the nodemap.", "<node> <flags>"},
3491         { "scriptstatus",    control_scriptstatus,  false,      false, "show the status of the monitoring scripts"},
3492         { "enablescript",     control_enablescript,  false,     false, "enable an eventscript", "<script>"},
3493         { "disablescript",    control_disablescript,  false,    false, "disable an eventscript", "<script>"},
3494         { "natgwlist",        control_natgwlist,        false,  false, "show the nodes belonging to this natgw configuration"},
3495         { "xpnn",             control_xpnn,             true,   true,  "find the pnn of the local node without talking to the daemon (unreliable)" },
3496         { "getreclock",       control_getreclock,       false,  false, "Show the reclock file of a node"},
3497         { "setreclock",       control_setreclock,       false,  false, "Set/clear the reclock file of a node", "[filename]"},
3498         { "setnatgwstate",    control_setnatgwstate,    false,  false, "Set NATGW state to on/off", "{on|off}"},
3499         { "setlmasterrole",   control_setlmasterrole,   false,  false, "Set LMASTER role to on/off", "{on|off}"},
3500         { "setrecmasterrole", control_setrecmasterrole, false,  false, "Set RECMASTER role to on/off", "{on|off}"},
3501         { "setdbprio",        control_setdbprio,        false,  false, "Set DB priority", "<dbid> <prio:1-3>"},
3502         { "getdbprio",        control_getdbprio,        false,  false, "Get DB priority", "<dbid>"},
3503 };
3504
3505 /*
3506   show usage message
3507  */
3508 static void usage(void)
3509 {
3510         int i;
3511         printf(
3512 "Usage: ctdb [options] <control>\n" \
3513 "Options:\n" \
3514 "   -n <node>          choose node number, or 'all' (defaults to local node)\n"
3515 "   -Y                 generate machinereadable output\n"
3516 "   -t <timelimit>     set timelimit for control in seconds (default %u)\n", options.timelimit);
3517         printf("Controls:\n");
3518         for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3519                 printf("  %-15s %-27s  %s\n", 
3520                        ctdb_commands[i].name, 
3521                        ctdb_commands[i].args?ctdb_commands[i].args:"",
3522                        ctdb_commands[i].msg);
3523         }
3524         exit(1);
3525 }
3526
3527
3528 static void ctdb_alarm(int sig)
3529 {
3530         printf("Maximum runtime exceeded - exiting\n");
3531         _exit(ERR_TIMEOUT);
3532 }
3533
3534 /*
3535   main program
3536 */
3537 int main(int argc, const char *argv[])
3538 {
3539         struct ctdb_context *ctdb;
3540         char *nodestring = NULL;
3541         struct poptOption popt_options[] = {
3542                 POPT_AUTOHELP
3543                 POPT_CTDB_CMDLINE
3544                 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
3545                 { "node",      'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
3546                 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
3547                 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
3548                 POPT_TABLEEND
3549         };
3550         int opt;
3551         const char **extra_argv;
3552         int extra_argc = 0;
3553         int ret=-1, i;
3554         poptContext pc;
3555         struct event_context *ev;
3556         const char *control;
3557
3558         setlinebuf(stdout);
3559         
3560         /* set some defaults */
3561         options.maxruntime = 0;
3562         options.timelimit = 3;
3563         options.pnn = CTDB_CURRENT_NODE;
3564
3565         pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
3566
3567         while ((opt = poptGetNextOpt(pc)) != -1) {
3568                 switch (opt) {
3569                 default:
3570                         DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n", 
3571                                 poptBadOption(pc, 0), poptStrerror(opt)));
3572                         exit(1);
3573                 }
3574         }
3575
3576         /* setup the remaining options for the main program to use */
3577         extra_argv = poptGetArgs(pc);
3578         if (extra_argv) {
3579                 extra_argv++;
3580                 while (extra_argv[extra_argc]) extra_argc++;
3581         }
3582
3583         if (extra_argc < 1) {
3584                 usage();
3585         }
3586
3587         if (options.maxruntime == 0) {
3588                 const char *ctdb_timeout;
3589                 ctdb_timeout = getenv("CTDB_TIMEOUT");
3590                 if (ctdb_timeout != NULL) {
3591                         options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
3592                 } else {
3593                         /* default timeout is 120 seconds */
3594                         options.maxruntime = 120;
3595                 }
3596         }
3597
3598         signal(SIGALRM, ctdb_alarm);
3599         alarm(options.maxruntime);
3600
3601         /* setup the node number to contact */
3602         if (nodestring != NULL) {
3603                 if (strcmp(nodestring, "all") == 0) {
3604                         options.pnn = CTDB_BROADCAST_ALL;
3605                 } else {
3606                         options.pnn = strtoul(nodestring, NULL, 0);
3607                 }
3608         }
3609
3610         control = extra_argv[0];
3611
3612         ev = event_context_init(NULL);
3613
3614         for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
3615                 if (strcmp(control, ctdb_commands[i].name) == 0) {
3616                         int j;
3617
3618                         if (ctdb_commands[i].without_daemon == true) {
3619                                 close(2);
3620                         }
3621
3622                         /* initialise ctdb */
3623                         ctdb = ctdb_cmdline_client(ev);
3624
3625                         if (ctdb_commands[i].without_daemon == false) {
3626                                 if (ctdb == NULL) {
3627                                         DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
3628                                         exit(1);
3629                                 }
3630
3631                                 /* verify the node exists */
3632                                 verify_node(ctdb);
3633
3634                                 if (options.pnn == CTDB_CURRENT_NODE) {
3635                                         int pnn;
3636                                         pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);         
3637                                         if (pnn == -1) {
3638                                                 return -1;
3639                                         }
3640                                         options.pnn = pnn;
3641                                 }
3642                         }
3643
3644                         if (ctdb_commands[i].auto_all && 
3645                             options.pnn == CTDB_BROADCAST_ALL) {
3646                                 uint32_t *nodes;
3647                                 uint32_t num_nodes;
3648                                 ret = 0;
3649
3650                                 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
3651                                 CTDB_NO_MEMORY(ctdb, nodes);
3652         
3653                                 for (j=0;j<num_nodes;j++) {
3654                                         options.pnn = nodes[j];
3655                                         ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3656                                 }
3657                                 talloc_free(nodes);
3658                         } else {
3659                                 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
3660                         }
3661                         break;
3662                 }
3663         }
3664
3665         if (i == ARRAY_SIZE(ctdb_commands)) {
3666                 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));
3667                 exit(1);
3668         }
3669
3670         return ret;
3671 }