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