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