Add two new ctdb commands :
[samba.git] / ctdb / 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
33 static void usage(void);
34
35 static struct {
36         int timelimit;
37         uint32_t pnn;
38         int machinereadable;
39         int maxruntime;
40 } options;
41
42 #define TIMELIMIT() timeval_current_ofs(options.timelimit, 0)
43
44 #ifdef CTDB_VERS
45 static int control_version(struct ctdb_context *ctdb, int argc, const char **argv)
46 {
47 #define STR(x) #x
48 #define XSTR(x) STR(x)
49         printf("CTDB version: %s\n", XSTR(CTDB_VERS));
50         return 0;
51 }
52 #endif
53
54 /*
55   see if a process exists
56  */
57 static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
58 {
59         uint32_t pnn, pid;
60         int ret;
61         if (argc < 1) {
62                 usage();
63         }
64
65         if (sscanf(argv[0], "%u:%u", &pnn, &pid) != 2) {
66                 DEBUG(DEBUG_ERR, ("Badly formed pnn:pid\n"));
67                 return -1;
68         }
69
70         ret = ctdb_ctrl_process_exists(ctdb, pnn, pid);
71         if (ret == 0) {
72                 printf("%u:%u exists\n", pnn, pid);
73         } else {
74                 printf("%u:%u does not exist\n", pnn, pid);
75         }
76         return ret;
77 }
78
79 /*
80   display statistics structure
81  */
82 static void show_statistics(struct ctdb_statistics *s)
83 {
84         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
85         int i;
86         const char *prefix=NULL;
87         int preflen=0;
88         const struct {
89                 const char *name;
90                 uint32_t offset;
91         } fields[] = {
92 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
93                 STATISTICS_FIELD(num_clients),
94                 STATISTICS_FIELD(frozen),
95                 STATISTICS_FIELD(recovering),
96                 STATISTICS_FIELD(client_packets_sent),
97                 STATISTICS_FIELD(client_packets_recv),
98                 STATISTICS_FIELD(node_packets_sent),
99                 STATISTICS_FIELD(node_packets_recv),
100                 STATISTICS_FIELD(keepalive_packets_sent),
101                 STATISTICS_FIELD(keepalive_packets_recv),
102                 STATISTICS_FIELD(node.req_call),
103                 STATISTICS_FIELD(node.reply_call),
104                 STATISTICS_FIELD(node.req_dmaster),
105                 STATISTICS_FIELD(node.reply_dmaster),
106                 STATISTICS_FIELD(node.reply_error),
107                 STATISTICS_FIELD(node.req_message),
108                 STATISTICS_FIELD(node.req_control),
109                 STATISTICS_FIELD(node.reply_control),
110                 STATISTICS_FIELD(client.req_call),
111                 STATISTICS_FIELD(client.req_message),
112                 STATISTICS_FIELD(client.req_control),
113                 STATISTICS_FIELD(timeouts.call),
114                 STATISTICS_FIELD(timeouts.control),
115                 STATISTICS_FIELD(timeouts.traverse),
116                 STATISTICS_FIELD(total_calls),
117                 STATISTICS_FIELD(pending_calls),
118                 STATISTICS_FIELD(lockwait_calls),
119                 STATISTICS_FIELD(pending_lockwait_calls),
120                 STATISTICS_FIELD(childwrite_calls),
121                 STATISTICS_FIELD(pending_childwrite_calls),
122                 STATISTICS_FIELD(memory_used),
123                 STATISTICS_FIELD(max_hop_count),
124         };
125         printf("CTDB version %u\n", CTDB_VERSION);
126         for (i=0;i<ARRAY_SIZE(fields);i++) {
127                 if (strchr(fields[i].name, '.')) {
128                         preflen = strcspn(fields[i].name, ".")+1;
129                         if (!prefix || strncmp(prefix, fields[i].name, preflen) != 0) {
130                                 prefix = fields[i].name;
131                                 printf(" %*.*s\n", preflen-1, preflen-1, fields[i].name);
132                         }
133                 } else {
134                         preflen = 0;
135                 }
136                 printf(" %*s%-22s%*s%10u\n", 
137                        preflen?4:0, "",
138                        fields[i].name+preflen, 
139                        preflen?0:4, "",
140                        *(uint32_t *)(fields[i].offset+(uint8_t *)s));
141         }
142         printf(" %-30s     %.6f sec\n", "max_call_latency", s->max_call_latency);
143         printf(" %-30s     %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency);
144         printf(" %-30s     %.6f sec\n", "max_childwrite_latency", s->max_childwrite_latency);
145         talloc_free(tmp_ctx);
146 }
147
148 /*
149   display remote ctdb statistics combined from all nodes
150  */
151 static int control_statistics_all(struct ctdb_context *ctdb)
152 {
153         int ret, i;
154         struct ctdb_statistics statistics;
155         uint32_t *nodes;
156         uint32_t num_nodes;
157
158         nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
159         CTDB_NO_MEMORY(ctdb, nodes);
160         
161         ZERO_STRUCT(statistics);
162
163         for (i=0;i<num_nodes;i++) {
164                 struct ctdb_statistics s1;
165                 int j;
166                 uint32_t *v1 = (uint32_t *)&s1;
167                 uint32_t *v2 = (uint32_t *)&statistics;
168                 uint32_t num_ints = 
169                         offsetof(struct ctdb_statistics, __last_counter) / sizeof(uint32_t);
170                 ret = ctdb_ctrl_statistics(ctdb, nodes[i], &s1);
171                 if (ret != 0) {
172                         DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", nodes[i]));
173                         return ret;
174                 }
175                 for (j=0;j<num_ints;j++) {
176                         v2[j] += v1[j];
177                 }
178                 statistics.max_hop_count = 
179                         MAX(statistics.max_hop_count, s1.max_hop_count);
180                 statistics.max_call_latency = 
181                         MAX(statistics.max_call_latency, s1.max_call_latency);
182                 statistics.max_lockwait_latency = 
183                         MAX(statistics.max_lockwait_latency, s1.max_lockwait_latency);
184         }
185         talloc_free(nodes);
186         printf("Gathered statistics for %u nodes\n", num_nodes);
187         show_statistics(&statistics);
188         return 0;
189 }
190
191 /*
192   display remote ctdb statistics
193  */
194 static int control_statistics(struct ctdb_context *ctdb, int argc, const char **argv)
195 {
196         int ret;
197         struct ctdb_statistics statistics;
198
199         if (options.pnn == CTDB_BROADCAST_ALL) {
200                 return control_statistics_all(ctdb);
201         }
202
203         ret = ctdb_ctrl_statistics(ctdb, options.pnn, &statistics);
204         if (ret != 0) {
205                 DEBUG(DEBUG_ERR, ("Unable to get statistics from node %u\n", options.pnn));
206                 return ret;
207         }
208         show_statistics(&statistics);
209         return 0;
210 }
211
212
213 /*
214   reset remote ctdb statistics
215  */
216 static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const char **argv)
217 {
218         int ret;
219
220         ret = ctdb_statistics_reset(ctdb, options.pnn);
221         if (ret != 0) {
222                 DEBUG(DEBUG_ERR, ("Unable to reset statistics on node %u\n", options.pnn));
223                 return ret;
224         }
225         return 0;
226 }
227
228
229 /*
230   display uptime of remote node
231  */
232 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
233 {
234         int ret;
235         int mypnn;
236         struct ctdb_uptime *uptime = NULL;
237         int tmp, days, hours, minutes, seconds;
238
239         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
240         if (mypnn == -1) {
241                 return -1;
242         }
243
244         ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
245         if (ret != 0) {
246                 DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
247                 return ret;
248         }
249
250         if (options.machinereadable){
251                 printf(":Current Node Time:Ctdb Start Time:Last Recovery Time:Last Recovery Duration:\n");
252                 printf(":%u:%u:%u:%lf\n",
253                         (unsigned int)uptime->current_time.tv_sec,
254                         (unsigned int)uptime->ctdbd_start_time.tv_sec,
255                         (unsigned int)uptime->last_recovery_finished.tv_sec,
256                         timeval_delta(&uptime->last_recovery_finished,
257                                       &uptime->last_recovery_started)
258                 );
259                 return 0;
260         }
261
262         printf("Current time of node  : %s", ctime(&uptime->current_time.tv_sec));
263
264         tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
265         seconds = tmp%60;
266         tmp    /= 60;
267         minutes = tmp%60;
268         tmp    /= 60;
269         hours   = tmp%24;
270         tmp    /= 24;
271         days    = tmp;
272         printf("Ctdbd start time      : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
273
274         tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
275         seconds = tmp%60;
276         tmp    /= 60;
277         minutes = tmp%60;
278         tmp    /= 60;
279         hours   = tmp%24;
280         tmp    /= 24;
281         days    = tmp;
282         printf("Time of last recovery : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_finished.tv_sec));
283         
284         printf("Duration of last recovery : %lf seconds\n",
285                 timeval_delta(&uptime->last_recovery_finished,
286                               &uptime->last_recovery_started));
287
288         return 0;
289 }
290
291 /*
292   show the PNN of the current node
293  */
294 static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
295 {
296         int mypnn;
297
298         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
299         if (mypnn == -1) {
300                 DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
301                 return -1;
302         }
303
304         printf("PNN:%d\n", mypnn);
305         return 0;
306 }
307
308 /*
309   display remote ctdb status
310  */
311 static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
312 {
313         int i, ret;
314         struct ctdb_vnn_map *vnnmap=NULL;
315         struct ctdb_node_map *nodemap=NULL;
316         uint32_t recmode, recmaster;
317         int mypnn;
318
319         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
320         if (mypnn == -1) {
321                 return -1;
322         }
323
324         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
325         if (ret != 0) {
326                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
327                 return ret;
328         }
329
330         if(options.machinereadable){
331                 printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:\n");
332                 for(i=0;i<nodemap->num;i++){
333                         printf(":%d:%s:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
334                                 inet_ntoa(nodemap->nodes[i].sin.sin_addr),
335                                !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
336                                !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
337                                !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
338                                !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY));
339                 }
340                 return 0;
341         }
342
343         printf("Number of nodes:%d\n", nodemap->num);
344         for(i=0;i<nodemap->num;i++){
345                 static const struct {
346                         uint32_t flag;
347                         const char *name;
348                 } flag_names[] = {
349                         { NODE_FLAGS_DISCONNECTED,          "DISCONNECTED" },
350                         { NODE_FLAGS_PERMANENTLY_DISABLED,  "DISABLED" },
351                         { NODE_FLAGS_BANNED,                "BANNED" },
352                         { NODE_FLAGS_UNHEALTHY,             "UNHEALTHY" },
353                 };
354                 char *flags_str = NULL;
355                 int j;
356                 for (j=0;j<ARRAY_SIZE(flag_names);j++) {
357                         if (nodemap->nodes[i].flags & flag_names[j].flag) {
358                                 if (flags_str == NULL) {
359                                         flags_str = talloc_strdup(ctdb, flag_names[j].name);
360                                 } else {
361                                         flags_str = talloc_asprintf_append(flags_str, "|%s",
362                                                                            flag_names[j].name);
363                                 }
364                                 CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
365                         }
366                 }
367                 if (flags_str == NULL) {
368                         flags_str = talloc_strdup(ctdb, "OK");
369                         CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
370                 }
371                 printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
372                        inet_ntoa(nodemap->nodes[i].sin.sin_addr),
373                        flags_str,
374                        nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
375                 talloc_free(flags_str);
376         }
377
378         ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &vnnmap);
379         if (ret != 0) {
380                 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
381                 return ret;
382         }
383         if (vnnmap->generation == INVALID_GENERATION) {
384                 printf("Generation:INVALID\n");
385         } else {
386                 printf("Generation:%d\n",vnnmap->generation);
387         }
388         printf("Size:%d\n",vnnmap->size);
389         for(i=0;i<vnnmap->size;i++){
390                 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
391         }
392
393         ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmode);
394         if (ret != 0) {
395                 DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
396                 return ret;
397         }
398         printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
399
400         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
401         if (ret != 0) {
402                 DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
403                 return ret;
404         }
405         printf("Recovery master:%d\n",recmaster);
406
407         return 0;
408 }
409
410 /*
411   get a list of all tickles for this pnn
412  */
413 static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
414 {
415         struct ctdb_control_tcp_tickle_list *list;
416         struct sockaddr_in ip;
417         int i, ret;
418
419         if (argc < 1) {
420                 usage();
421         }
422
423         ip.sin_family = AF_INET;
424         if (inet_aton(argv[0], &ip.sin_addr) == 0) {
425                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
426                 return -1;
427         }
428
429         ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &ip, &list);
430         if (ret == -1) {
431                 DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
432                 return -1;
433         }
434
435         printf("Tickles for ip:%s\n", inet_ntoa(list->ip.sin_addr));
436         printf("Num tickles:%u\n", list->tickles.num);
437         for (i=0;i<list->tickles.num;i++) {
438                 printf("SRC: %s:%u   ", inet_ntoa(list->tickles.connections[i].saddr.sin_addr), ntohs(list->tickles.connections[i].saddr.sin_port));
439                 printf("DST: %s:%u\n", inet_ntoa(list->tickles.connections[i].daddr.sin_addr), ntohs(list->tickles.connections[i].daddr.sin_port));
440         }
441
442         talloc_free(list);
443         
444         return 0;
445 }
446
447 /* send a release ip to all nodes */
448 static int control_send_release(struct ctdb_context *ctdb, uint32_t pnn,
449 struct sockaddr_in *sin)
450 {
451         int ret;
452         struct ctdb_public_ip pip;
453         TDB_DATA data;
454         struct ctdb_node_map *nodemap=NULL;
455
456         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
457         if (ret != 0) {
458                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
459                 return ret;
460         }
461
462         /* send a moveip message to the recovery master */
463         pip.pnn = pnn;
464         pip.sin.sin_family = AF_INET;
465         pip.sin.sin_addr   = sin->sin_addr;
466         data.dsize = sizeof(pip);
467         data.dptr = (unsigned char *)&pip;
468
469
470         /* send release ip to all nodes */
471         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
472                         list_of_active_nodes(ctdb, nodemap, ctdb, true),
473                         TIMELIMIT(), false, data,
474                         NULL, NULL, NULL) != 0) {
475                 DEBUG(DEBUG_ERR, (__location__ " Unable to send 'ReleaseIP' to all nodes.\n"));
476                 return -1;
477         }
478
479         return 0;
480 }
481
482 /*
483   move/failover an ip address to a specific node
484  */
485 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
486 {
487         uint32_t pnn;
488         struct sockaddr_in ip;
489         uint32_t value;
490         struct ctdb_all_public_ips *ips;
491         int i, ret;
492
493         if (argc < 2) {
494                 usage();
495         }
496
497         ip.sin_family = AF_INET;
498         if (inet_aton(argv[0], &ip.sin_addr) == 0) {
499                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
500                 return -1;
501         }
502
503
504         if (sscanf(argv[1], "%u", &pnn) != 1) {
505                 DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
506                 return -1;
507         }
508
509         ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, "DeterministicIPs", &value);
510         if (ret == -1) {
511                 DEBUG(DEBUG_ERR, ("Unable to get tunable variable 'DeterministicIPs' from local node\n"));
512                 return -1;
513         }
514         if (value != 0) {
515                 DEBUG(DEBUG_ERR, ("The tunable 'DeterministicIPs' is set. You can only move ip addresses when this feature is disabled\n"));
516                 return -1;
517         }
518
519         ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, "NoIPFailback", &value);
520         if (ret == -1) {
521                 DEBUG(DEBUG_ERR, ("Unable to get tunable variable 'NoIPFailback' from local node\n"));
522                 return -1;
523         }
524         if (value == 0) {
525                 DEBUG(DEBUG_ERR, ("The tunable 'NoIPFailback' is NOT set. You can only move ip addresses when this feature is enabled\n"));
526                 return -1;
527         }
528
529         /* read the public ip list from the node */
530         ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
531         if (ret != 0) {
532                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", pnn));
533                 return -1;
534         }
535
536         for (i=0;i<ips->num;i++) {
537                 if (ctdb_same_ipv4(&ip, &ips->ips[i].sin)) {
538                         break;
539                 }
540         }
541         if (i==ips->num) {
542                 DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
543                         pnn, inet_ntoa(ip.sin_addr)));
544                 return -1;
545         }
546         if (ips->ips[i].pnn == pnn) {
547                 DEBUG(DEBUG_ERR, ("Host %u is already hosting '%s'\n",
548                         pnn, inet_ntoa(ips->ips[i].sin.sin_addr)));
549                 return -1;
550         }
551
552         ret = control_send_release(ctdb, pnn, &ips->ips[i].sin);
553         if (ret != 0) {
554                 DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));;
555                 return -1;
556         }
557
558         return 0;
559 }
560
561 struct node_ip {
562         uint32_t pnn;
563         struct sockaddr_in sin;
564 };
565
566 void getips_store_callback(void *param, void *data)
567 {
568         struct node_ip *node_ip = (struct node_ip *)data;
569         struct ctdb_all_public_ips *ips = param;
570         int i;
571
572         i = ips->num++;
573         ips->ips[i].pnn = node_ip->pnn;
574         ips->ips[i].sin = node_ip->sin;
575 }
576
577 void getips_count_callback(void *param, void *data)
578 {
579         uint32_t *count = param;
580
581         (*count)++;
582 }
583
584 static int
585 control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
586 {
587         struct ctdb_all_public_ips *tmp_ips;
588         struct ctdb_node_map *nodemap=NULL;
589         trbt_tree_t *tree;
590         int i, j, len, ret;
591         uint32_t count;
592
593         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
594         if (ret != 0) {
595                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
596                 return ret;
597         }
598
599         tree = trbt_create(tmp_ctx, 0);
600
601         for(i=0;i<nodemap->num;i++){
602                 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
603                         continue;
604                 }
605
606                 /* read the public ip list from this node */
607                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
608                 if (ret != 0) {
609                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
610                         return -1;
611                 }
612         
613                 for (j=0; j<tmp_ips->num;j++) {
614                         struct node_ip *node_ip;
615
616                         node_ip = talloc(tmp_ctx, struct node_ip);
617                         node_ip->pnn = tmp_ips->ips[j].pnn;
618                         node_ip->sin = tmp_ips->ips[j].sin;
619
620                         trbt_insert32(tree, tmp_ips->ips[j].sin.sin_addr.s_addr, node_ip);
621                 }
622                 talloc_free(tmp_ips);
623         }
624
625         /* traverse */
626         count = 0;
627         trbt_traversearray32(tree, 1, getips_count_callback, &count);
628
629         len = offsetof(struct ctdb_all_public_ips, ips) + 
630                 count*sizeof(struct ctdb_public_ip);
631         tmp_ips = talloc_zero_size(tmp_ctx, len);
632         trbt_traversearray32(tree, 1, getips_store_callback, tmp_ips);
633
634         *ips = tmp_ips;
635
636         return 0;
637 }
638
639
640 /* 
641  * scans all other nodes and returns a pnn for another node that can host this 
642  * ip address or -1
643  */
644 static int
645 find_other_host_for_public_ip(struct ctdb_context *ctdb, struct sockaddr_in *addr)
646 {
647         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
648         struct ctdb_all_public_ips *ips;
649         struct ctdb_node_map *nodemap=NULL;
650         int i, j, ret;
651
652         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
653         if (ret != 0) {
654                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
655                 talloc_free(tmp_ctx);
656                 return ret;
657         }
658
659         for(i=0;i<nodemap->num;i++){
660                 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
661                         continue;
662                 }
663                 if (nodemap->nodes[i].pnn == options.pnn) {
664                         continue;
665                 }
666
667                 /* read the public ip list from this node */
668                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips);
669                 if (ret != 0) {
670                         DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
671                         return -1;
672                 }
673
674                 for (j=0;j<ips->num;j++) {
675                         if (ctdb_same_ipv4(addr, &ips->ips[j].sin)) {
676                                 talloc_free(tmp_ctx);
677                                 return nodemap->nodes[i].pnn;
678                         }
679                 }
680                 talloc_free(ips);
681         }
682
683         talloc_free(tmp_ctx);
684         return -1;
685 }
686
687 /*
688   add a public ip address to a node
689  */
690 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
691 {
692         int i, ret;
693         int len;
694         unsigned mask;
695         struct sockaddr_in addr;
696         struct ctdb_control_ip_iface *pub;
697         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
698         struct ctdb_all_public_ips *ips;
699
700         if (argc != 2) {
701                 talloc_free(tmp_ctx);
702                 usage();
703         }
704
705         if (!parse_ip_mask(argv[0], &addr, &mask)) {
706                 DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
707                 talloc_free(tmp_ctx);
708                 return -1;
709         }
710
711         ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
712         if (ret != 0) {
713                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
714                 talloc_free(tmp_ctx);
715                 return ret;
716         }
717
718
719         len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
720         pub = talloc_size(tmp_ctx, len); 
721         CTDB_NO_MEMORY(ctdb, pub);
722
723         pub->sin   = addr;
724         pub->mask  = mask;
725         pub->len   = strlen(argv[1])+1;
726         memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
727
728         ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
729         if (ret != 0) {
730                 DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
731                 talloc_free(tmp_ctx);
732                 return ret;
733         }
734
735
736         /* check if some other node is already serving this ip, if not,
737          * we will claim it
738          */
739         for (i=0;i<ips->num;i++) {
740                 if (ctdb_same_ipv4(&addr, &ips->ips[i].sin)) {
741                         break;
742                 }
743         }
744         /* no one has this ip so we claim it */
745         if (i == ips->num) {
746                 ret = control_send_release(ctdb, options.pnn, &addr);
747         } else {
748                 ret = control_send_release(ctdb, ips->ips[i].pnn, &addr);
749         }
750
751         if (ret != 0) {
752                 DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));
753                 return -1;
754         }
755
756         talloc_free(tmp_ctx);
757         return 0;
758 }
759
760 /*
761   delete a public ip address from a node
762  */
763 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
764 {
765         int i, ret;
766         struct sockaddr_in addr;
767         struct ctdb_control_ip_iface pub;
768         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
769         struct ctdb_all_public_ips *ips;
770
771         if (argc != 1) {
772                 talloc_free(tmp_ctx);
773                 usage();
774         }
775
776         addr.sin_family = AF_INET;
777         if (inet_aton(argv[0], &addr.sin_addr) == 0) {
778                 DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
779                 return -1;
780         }
781
782         pub.sin   = addr;
783         pub.mask  = 0;
784         pub.len   = 0;
785
786         ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
787         if (ret != 0) {
788                 DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
789                 talloc_free(tmp_ctx);
790                 return ret;
791         }
792         
793         for (i=0;i<ips->num;i++) {
794                 if (ctdb_same_ipv4(&addr, &ips->ips[i].sin)) {
795                         break;
796                 }
797         }
798
799         if (i==ips->num) {
800                 DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
801                         inet_ntoa(addr.sin_addr)));
802                 talloc_free(tmp_ctx);
803                 return -1;
804         }
805
806         if (ips->ips[i].pnn == options.pnn) {
807                 ret = find_other_host_for_public_ip(ctdb, &addr);
808                 if (ret != -1) {
809                         ret = control_send_release(ctdb, ret, &addr);
810                         if (ret != 0) {
811                                 DEBUG(DEBUG_ERR, ("Failed to migrate this ip to another node. Use moveip of recover to reassign this address to a node\n"));
812                         }
813                 }
814         }
815
816         ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub);
817         if (ret != 0) {
818                 DEBUG(DEBUG_ERR, ("Unable to del public ip from node %u\n", options.pnn));
819                 talloc_free(tmp_ctx);
820                 return ret;
821         }
822
823         talloc_free(tmp_ctx);
824         return 0;
825 }
826
827 /*
828   kill a tcp connection
829  */
830 static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
831 {
832         int ret;
833         struct ctdb_control_killtcp killtcp;
834
835         if (argc < 2) {
836                 usage();
837         }
838
839         if (!parse_ip_port(argv[0], (ctdb_sock_addr *)&killtcp.src)) {
840                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
841                 return -1;
842         }
843
844         if (!parse_ip_port(argv[1], (ctdb_sock_addr *)&killtcp.dst)) {
845                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
846                 return -1;
847         }
848
849         ret = ctdb_ctrl_killtcp(ctdb, TIMELIMIT(), options.pnn, &killtcp);
850         if (ret != 0) {
851                 DEBUG(DEBUG_ERR, ("Unable to killtcp from node %u\n", options.pnn));
852                 return ret;
853         }
854
855         return 0;
856 }
857
858
859 /*
860   send a gratious arp
861  */
862 static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char **argv)
863 {
864         int ret;
865         ctdb_sock_addr addr;
866
867         if (argc < 2) {
868                 usage();
869         }
870
871         if (!parse_ip(argv[0], &addr)) {
872                 DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
873                 return -1;
874         }
875
876         ret = ctdb_ctrl_gratious_arp(ctdb, TIMELIMIT(), options.pnn, &addr, argv[1]);
877         if (ret != 0) {
878                 DEBUG(DEBUG_ERR, ("Unable to send gratious_arp from node %u\n", options.pnn));
879                 return ret;
880         }
881
882         return 0;
883 }
884
885 /*
886   register a server id
887  */
888 static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
889 {
890         int ret;
891         struct ctdb_server_id server_id;
892
893         if (argc < 3) {
894                 usage();
895         }
896
897         server_id.pnn       = strtoul(argv[0], NULL, 0);
898         server_id.type      = strtoul(argv[1], NULL, 0);
899         server_id.server_id = strtoul(argv[2], NULL, 0);
900
901         ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
902         if (ret != 0) {
903                 DEBUG(DEBUG_ERR, ("Unable to register server_id from node %u\n", options.pnn));
904                 return ret;
905         }
906         return -1;
907 }
908
909 /*
910   unregister a server id
911  */
912 static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
913 {
914         int ret;
915         struct ctdb_server_id server_id;
916
917         if (argc < 3) {
918                 usage();
919         }
920
921         server_id.pnn       = strtoul(argv[0], NULL, 0);
922         server_id.type      = strtoul(argv[1], NULL, 0);
923         server_id.server_id = strtoul(argv[2], NULL, 0);
924
925         ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
926         if (ret != 0) {
927                 DEBUG(DEBUG_ERR, ("Unable to unregister server_id from node %u\n", options.pnn));
928                 return ret;
929         }
930         return -1;
931 }
932
933 /*
934   check if a server id exists
935  */
936 static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
937 {
938         uint32_t status;
939         int ret;
940         struct ctdb_server_id server_id;
941
942         if (argc < 3) {
943                 usage();
944         }
945
946         server_id.pnn       = strtoul(argv[0], NULL, 0);
947         server_id.type      = strtoul(argv[1], NULL, 0);
948         server_id.server_id = strtoul(argv[2], NULL, 0);
949
950         ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.pnn, &server_id, &status);
951         if (ret != 0) {
952                 DEBUG(DEBUG_ERR, ("Unable to check server_id from node %u\n", options.pnn));
953                 return ret;
954         }
955
956         if (status) {
957                 printf("Server id %d:%d:%d EXISTS\n", server_id.pnn, server_id.type, server_id.server_id);
958         } else {
959                 printf("Server id %d:%d:%d does NOT exist\n", server_id.pnn, server_id.type, server_id.server_id);
960         }
961         return 0;
962 }
963
964 /*
965   get a list of all server ids that are registered on a node
966  */
967 static int getsrvids(struct ctdb_context *ctdb, int argc, const char **argv)
968 {
969         int i, ret;
970         struct ctdb_server_id_list *server_ids;
971
972         ret = ctdb_ctrl_get_server_id_list(ctdb, ctdb, TIMELIMIT(), options.pnn, &server_ids);
973         if (ret != 0) {
974                 DEBUG(DEBUG_ERR, ("Unable to get server_id list from node %u\n", options.pnn));
975                 return ret;
976         }
977
978         for (i=0; i<server_ids->num; i++) {
979                 printf("Server id %d:%d:%d\n", 
980                         server_ids->server_ids[i].pnn, 
981                         server_ids->server_ids[i].type, 
982                         server_ids->server_ids[i].server_id); 
983         }
984
985         return -1;
986 }
987
988 /*
989   send a tcp tickle ack
990  */
991 static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
992 {
993         int ret;
994         ctdb_sock_addr  src, dst;
995
996         if (argc < 2) {
997                 usage();
998         }
999
1000         if (!parse_ip_port(argv[0], &src)) {
1001                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
1002                 return -1;
1003         }
1004
1005         if (!parse_ip_port(argv[1], &dst)) {
1006                 DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
1007                 return -1;
1008         }
1009
1010         ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
1011         if (ret==0) {
1012                 return 0;
1013         }
1014         DEBUG(DEBUG_ERR, ("Error while sending tickle ack\n"));
1015
1016         return -1;
1017 }
1018
1019
1020 /*
1021   display public ip status
1022  */
1023 static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
1024 {
1025         int i, ret;
1026         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1027         struct ctdb_all_public_ips *ips;
1028
1029         if (options.pnn == CTDB_BROADCAST_ALL) {
1030                 /* read the list of public ips from all nodes */
1031                 ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
1032         } else {
1033                 /* read the public ip list from this node */
1034                 ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
1035         }
1036         if (ret != 0) {
1037                 DEBUG(DEBUG_ERR, ("Unable to get public ips from node %u\n", options.pnn));
1038                 talloc_free(tmp_ctx);
1039                 return ret;
1040         }
1041
1042         if (options.machinereadable){
1043                 printf(":Public IP:Node:\n");
1044         } else {
1045                 if (options.pnn == CTDB_BROADCAST_ALL) {
1046                         printf("Public IPs on ALL nodes\n");
1047                 } else {
1048                         printf("Public IPs on node %u\n", options.pnn);
1049                 }
1050         }
1051
1052         for (i=1;i<=ips->num;i++) {
1053                 if (options.machinereadable){
1054                         printf(":%s:%d:\n", inet_ntoa(ips->ips[ips->num-i].sin.sin_addr), ips->ips[ips->num-i].pnn);
1055                 } else {
1056                         printf("%s %d\n", inet_ntoa(ips->ips[ips->num-i].sin.sin_addr), ips->ips[ips->num-i].pnn);
1057                 }
1058         }
1059
1060         talloc_free(tmp_ctx);
1061         return 0;
1062 }
1063
1064 /*
1065   display pid of a ctdb daemon
1066  */
1067 static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv)
1068 {
1069         uint32_t pid;
1070         int ret;
1071
1072         ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.pnn, &pid);
1073         if (ret != 0) {
1074                 DEBUG(DEBUG_ERR, ("Unable to get daemon pid from node %u\n", options.pnn));
1075                 return ret;
1076         }
1077         printf("Pid:%d\n", pid);
1078
1079         return 0;
1080 }
1081
1082 /*
1083   disable a remote node
1084  */
1085 static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
1086 {
1087         int ret;
1088
1089         ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0);
1090         if (ret != 0) {
1091                 DEBUG(DEBUG_ERR, ("Unable to disable node %u\n", options.pnn));
1092                 return ret;
1093         }
1094
1095         return 0;
1096 }
1097
1098 /*
1099   enable a disabled remote node
1100  */
1101 static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
1102 {
1103         int ret;
1104
1105         ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.pnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED);
1106         if (ret != 0) {
1107                 DEBUG(DEBUG_ERR, ("Unable to enable node %u\n", options.pnn));
1108                 return ret;
1109         }
1110
1111         return 0;
1112 }
1113
1114 /*
1115   ban a node from the cluster
1116  */
1117 static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
1118 {
1119         int ret;
1120         struct ctdb_ban_info b;
1121         TDB_DATA data;
1122         uint32_t ban_time;
1123
1124         if (argc < 1) {
1125                 usage();
1126         }
1127
1128         ban_time = strtoul(argv[0], NULL, 0);
1129
1130         b.pnn = options.pnn;
1131         b.ban_time = ban_time;
1132
1133         data.dptr = (uint8_t *)&b;
1134         data.dsize = sizeof(b);
1135
1136         ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_BAN_NODE, data);
1137         if (ret != 0) {
1138                 DEBUG(DEBUG_ERR,("Failed to ban node %u\n", options.pnn));
1139                 return -1;
1140         }
1141         
1142         return 0;
1143 }
1144
1145
1146 /*
1147   unban a node from the cluster
1148  */
1149 static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
1150 {
1151         int ret;
1152         TDB_DATA data;
1153
1154         data.dptr = (uint8_t *)&options.pnn;
1155         data.dsize = sizeof(uint32_t);
1156
1157         ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_UNBAN_NODE, data);
1158         if (ret != 0) {
1159                 DEBUG(DEBUG_ERR,("Failed to to unban node %u\n", options.pnn));
1160                 return -1;
1161         }
1162         
1163         return 0;
1164 }
1165
1166
1167 /*
1168   shutdown a daemon
1169  */
1170 static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv)
1171 {
1172         int ret;
1173
1174         ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.pnn);
1175         if (ret != 0) {
1176                 DEBUG(DEBUG_ERR, ("Unable to shutdown node %u\n", options.pnn));
1177                 return ret;
1178         }
1179
1180         return 0;
1181 }
1182
1183 /*
1184   trigger a recovery
1185  */
1186 static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv)
1187 {
1188         int ret;
1189
1190         ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
1191         if (ret != 0) {
1192                 DEBUG(DEBUG_ERR, ("Unable to freeze node\n"));
1193                 return ret;
1194         }
1195
1196         ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
1197         if (ret != 0) {
1198                 DEBUG(DEBUG_ERR, ("Unable to set recovery mode\n"));
1199                 return ret;
1200         }
1201
1202         return 0;
1203 }
1204
1205
1206 /*
1207   display monitoring mode of a remote node
1208  */
1209 static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv)
1210 {
1211         uint32_t monmode;
1212         int ret;
1213
1214         ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.pnn, &monmode);
1215         if (ret != 0) {
1216                 DEBUG(DEBUG_ERR, ("Unable to get monmode from node %u\n", options.pnn));
1217                 return ret;
1218         }
1219         if (!options.machinereadable){
1220                 printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode);
1221         } else {
1222                 printf(":mode:\n");
1223                 printf(":%d:\n",monmode);
1224         }
1225         return 0;
1226 }
1227
1228
1229 /*
1230   display capabilities of a remote node
1231  */
1232 static int control_getcapabilities(struct ctdb_context *ctdb, int argc, const char **argv)
1233 {
1234         uint32_t capabilities;
1235         int ret;
1236
1237         ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), options.pnn, &capabilities);
1238         if (ret != 0) {
1239                 DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", options.pnn));
1240                 return ret;
1241         }
1242         
1243         if (!options.machinereadable){
1244                 printf("RECMASTER: %s\n", (capabilities&CTDB_CAP_RECMASTER)?"YES":"NO");
1245                 printf("LMASTER: %s\n", (capabilities&CTDB_CAP_LMASTER)?"YES":"NO");
1246                 printf("LVS: %s\n", (capabilities&CTDB_CAP_LVS)?"YES":"NO");
1247         } else {
1248                 printf(":RECMASTER:LMASTER:LVS:\n");
1249                 printf(":%d:%d:%d:\n",
1250                         !!(capabilities&CTDB_CAP_RECMASTER),
1251                         !!(capabilities&CTDB_CAP_LMASTER),
1252                         !!(capabilities&CTDB_CAP_LVS));
1253         }
1254         return 0;
1255 }
1256
1257 /*
1258   display lvs configuration
1259  */
1260 static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
1261 {
1262         uint32_t *capabilities;
1263         struct ctdb_node_map *nodemap=NULL;
1264         int i, ret;
1265         int healthy_count = 0;
1266
1267         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
1268         if (ret != 0) {
1269                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1270                 return ret;
1271         }
1272
1273         capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
1274         CTDB_NO_MEMORY(ctdb, capabilities);
1275         
1276         /* collect capabilities for all connected nodes */
1277         for (i=0; i<nodemap->num; i++) {
1278                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1279                         continue;
1280                 }
1281                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1282                         continue;
1283                 }
1284         
1285                 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
1286                 if (ret != 0) {
1287                         DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
1288                         return ret;
1289                 }
1290
1291                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1292                         continue;
1293                 }
1294
1295                 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
1296                         healthy_count++;
1297                 }
1298         }
1299
1300         /* Print all LVS nodes */
1301         for (i=0; i<nodemap->num; i++) {
1302                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1303                         continue;
1304                 }
1305                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1306                         continue;
1307                 }
1308                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1309                         continue;
1310                 }
1311
1312                 if (healthy_count != 0) {
1313                         if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
1314                                 continue;
1315                         }
1316                 }
1317
1318                 printf("%d:%s\n", i, inet_ntoa(nodemap->nodes[i].sin.sin_addr));
1319         }
1320
1321         return 0;
1322 }
1323
1324 /*
1325   display who is the lvs master
1326  */
1327 static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv)
1328 {
1329         uint32_t *capabilities;
1330         struct ctdb_node_map *nodemap=NULL;
1331         int i, ret;
1332         int healthy_count = 0;
1333
1334         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
1335         if (ret != 0) {
1336                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1337                 return ret;
1338         }
1339
1340         capabilities = talloc_array(ctdb, uint32_t, nodemap->num);
1341         CTDB_NO_MEMORY(ctdb, capabilities);
1342         
1343         /* collect capabilities for all connected nodes */
1344         for (i=0; i<nodemap->num; i++) {
1345                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1346                         continue;
1347                 }
1348                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1349                         continue;
1350                 }
1351         
1352                 ret = ctdb_ctrl_getcapabilities(ctdb, TIMELIMIT(), i, &capabilities[i]);
1353                 if (ret != 0) {
1354                         DEBUG(DEBUG_ERR, ("Unable to get capabilities from node %u\n", i));
1355                         return ret;
1356                 }
1357
1358                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1359                         continue;
1360                 }
1361
1362                 if (!(nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY)) {
1363                         healthy_count++;
1364                 }
1365         }
1366
1367         /* find and show the lvsmaster */
1368         for (i=0; i<nodemap->num; i++) {
1369                 if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
1370                         continue;
1371                 }
1372                 if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
1373                         continue;
1374                 }
1375                 if (!(capabilities[i] & CTDB_CAP_LVS)) {
1376                         continue;
1377                 }
1378
1379                 if (healthy_count != 0) {
1380                         if (nodemap->nodes[i].flags & NODE_FLAGS_UNHEALTHY) {
1381                                 continue;
1382                         }
1383                 }
1384
1385                 printf("Node %d is LVS master\n", i);
1386                 return 0;
1387         }
1388
1389         printf("There is no LVS master\n");
1390         return 0;
1391 }
1392
1393 /*
1394   disable monitoring on a  node
1395  */
1396 static int control_disable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
1397 {
1398         
1399         int ret;
1400
1401         ret = ctdb_ctrl_disable_monmode(ctdb, TIMELIMIT(), options.pnn);
1402         if (ret != 0) {
1403                 DEBUG(DEBUG_ERR, ("Unable to disable monmode on node %u\n", options.pnn));
1404                 return ret;
1405         }
1406         printf("Monitoring mode:%s\n","DISABLED");
1407
1408         return 0;
1409 }
1410
1411 /*
1412   enable monitoring on a  node
1413  */
1414 static int control_enable_monmode(struct ctdb_context *ctdb, int argc, const char **argv)
1415 {
1416         
1417         int ret;
1418
1419         ret = ctdb_ctrl_enable_monmode(ctdb, TIMELIMIT(), options.pnn);
1420         if (ret != 0) {
1421                 DEBUG(DEBUG_ERR, ("Unable to enable monmode on node %u\n", options.pnn));
1422                 return ret;
1423         }
1424         printf("Monitoring mode:%s\n","ACTIVE");
1425
1426         return 0;
1427 }
1428
1429 /*
1430   display remote list of keys/data for a db
1431  */
1432 static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
1433 {
1434         const char *db_name;
1435         struct ctdb_db_context *ctdb_db;
1436         int ret;
1437
1438         if (argc < 1) {
1439                 usage();
1440         }
1441
1442         db_name = argv[0];
1443         ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
1444
1445         if (ctdb_db == NULL) {
1446                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
1447                 return -1;
1448         }
1449
1450         /* traverse and dump the cluster tdb */
1451         ret = ctdb_dump_db(ctdb_db, stdout);
1452         if (ret == -1) {
1453                 DEBUG(DEBUG_ERR, ("Unable to dump database\n"));
1454                 return -1;
1455         }
1456         talloc_free(ctdb_db);
1457
1458         printf("Dumped %d records\n", ret);
1459         return 0;
1460 }
1461
1462
1463 /*
1464   display a list of the databases on a remote ctdb
1465  */
1466 static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv)
1467 {
1468         int i, ret;
1469         struct ctdb_dbid_map *dbmap=NULL;
1470
1471         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
1472         if (ret != 0) {
1473                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
1474                 return ret;
1475         }
1476
1477         printf("Number of databases:%d\n", dbmap->num);
1478         for(i=0;i<dbmap->num;i++){
1479                 const char *path;
1480                 const char *name;
1481                 bool persistent;
1482
1483                 ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
1484                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
1485                 persistent = dbmap->dbs[i].persistent;
1486                 printf("dbid:0x%08x name:%s path:%s %s\n", dbmap->dbs[i].dbid, name, 
1487                        path, persistent?"PERSISTENT":"");
1488         }
1489
1490         return 0;
1491 }
1492
1493 /*
1494   check if the local node is recmaster or not
1495   it will return 1 if this node is the recmaster and 0 if it is not
1496   or if the local ctdb daemon could not be contacted
1497  */
1498 static int control_isnotrecmaster(struct ctdb_context *ctdb, int argc, const char **argv)
1499 {
1500         uint32_t mypnn, recmaster;
1501         int ret;
1502
1503         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
1504         if (mypnn == -1) {
1505                 printf("Failed to get pnn of node\n");
1506                 return 1;
1507         }
1508
1509         ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), options.pnn, &recmaster);
1510         if (ret != 0) {
1511                 printf("Failed to get the recmaster\n");
1512                 return 1;
1513         }
1514
1515         if (recmaster != mypnn) {
1516                 printf("this node is not the recmaster\n");
1517                 return 1;
1518         }
1519
1520         printf("this node is the recmaster\n");
1521         return 0;
1522 }
1523
1524 /*
1525   ping a node
1526  */
1527 static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
1528 {
1529         int ret;
1530         struct timeval tv = timeval_current();
1531         ret = ctdb_ctrl_ping(ctdb, options.pnn);
1532         if (ret == -1) {
1533                 printf("Unable to get ping response from node %u\n", options.pnn);
1534         } else {
1535                 printf("response from %u time=%.6f sec  (%d clients)\n", 
1536                        options.pnn, timeval_elapsed(&tv), ret);
1537         }
1538         return 0;
1539 }
1540
1541
1542 /*
1543   get a tunable
1544  */
1545 static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv)
1546 {
1547         const char *name;
1548         uint32_t value;
1549         int ret;
1550
1551         if (argc < 1) {
1552                 usage();
1553         }
1554
1555         name = argv[0];
1556         ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.pnn, name, &value);
1557         if (ret == -1) {
1558                 DEBUG(DEBUG_ERR, ("Unable to get tunable variable '%s'\n", name));
1559                 return -1;
1560         }
1561
1562         printf("%-19s = %u\n", name, value);
1563         return 0;
1564 }
1565
1566 /*
1567   set a tunable
1568  */
1569 static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv)
1570 {
1571         const char *name;
1572         uint32_t value;
1573         int ret;
1574
1575         if (argc < 2) {
1576                 usage();
1577         }
1578
1579         name = argv[0];
1580         value = strtoul(argv[1], NULL, 0);
1581
1582         ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.pnn, name, value);
1583         if (ret == -1) {
1584                 DEBUG(DEBUG_ERR, ("Unable to set tunable variable '%s'\n", name));
1585                 return -1;
1586         }
1587         return 0;
1588 }
1589
1590 /*
1591   list all tunables
1592  */
1593 static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv)
1594 {
1595         uint32_t count;
1596         const char **list;
1597         int ret, i;
1598
1599         ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.pnn, ctdb, &list, &count);
1600         if (ret == -1) {
1601                 DEBUG(DEBUG_ERR, ("Unable to list tunable variables\n"));
1602                 return -1;
1603         }
1604
1605         for (i=0;i<count;i++) {
1606                 control_getvar(ctdb, 1, &list[i]);
1607         }
1608
1609         talloc_free(list);
1610         
1611         return 0;
1612 }
1613
1614 static struct {
1615         int32_t level;
1616         const char *description;
1617 } debug_levels[] = {
1618         {DEBUG_EMERG,   "EMERG"},
1619         {DEBUG_ALERT,   "ALERT"},
1620         {DEBUG_CRIT,    "CRIT"},
1621         {DEBUG_ERR,     "ERR"},
1622         {DEBUG_WARNING, "WARNING"},
1623         {DEBUG_NOTICE,  "NOTICE"},
1624         {DEBUG_INFO,    "INFO"},
1625         {DEBUG_DEBUG,   "DEBUG"}
1626 };
1627
1628 static const char *get_debug_by_level(int32_t level)
1629 {
1630         int i;
1631
1632         for (i=0;i<ARRAY_SIZE(debug_levels);i++) {
1633                 if (debug_levels[i].level == level) {
1634                         return debug_levels[i].description;
1635                 }
1636         }
1637         return "Unknown";
1638 }
1639
1640 static int32_t get_debug_by_desc(const char *desc)
1641 {
1642         int i;
1643
1644         for (i=0;i<ARRAY_SIZE(debug_levels);i++) {
1645                 if (!strcmp(debug_levels[i].description, desc)) {
1646                         return debug_levels[i].level;
1647                 }
1648         }
1649         return DEBUG_ERR;
1650 }
1651
1652 /*
1653   display debug level on a node
1654  */
1655 static int control_getdebug(struct ctdb_context *ctdb, int argc, const char **argv)
1656 {
1657         int ret;
1658         int32_t level;
1659
1660         ret = ctdb_ctrl_get_debuglevel(ctdb, options.pnn, &level);
1661         if (ret != 0) {
1662                 DEBUG(DEBUG_ERR, ("Unable to get debuglevel response from node %u\n", options.pnn));
1663                 return ret;
1664         } else {
1665                 if (options.machinereadable){
1666                         printf(":Name:Level:\n");
1667                         printf(":%s:%d:\n",get_debug_by_level(level),level);
1668                 } else {
1669                         printf("Node %u is at debug level %s (%d)\n", options.pnn, get_debug_by_level(level), level);
1670                 }
1671         }
1672         return 0;
1673 }
1674
1675
1676 /*
1677   set debug level on a node or all nodes
1678  */
1679 static int control_setdebug(struct ctdb_context *ctdb, int argc, const char **argv)
1680 {
1681         int ret;
1682         uint32_t level;
1683
1684         if (argc < 1) {
1685                 usage();
1686         }
1687
1688         if (isalpha(argv[0][0])) { 
1689                 level = get_debug_by_desc(argv[0]);
1690         } else {
1691                 level = strtoul(argv[0], NULL, 0);
1692         }
1693
1694         ret = ctdb_ctrl_set_debuglevel(ctdb, options.pnn, level);
1695         if (ret != 0) {
1696                 DEBUG(DEBUG_ERR, ("Unable to set debug level on node %u\n", options.pnn));
1697         }
1698         return 0;
1699 }
1700
1701
1702 /*
1703   freeze a node
1704  */
1705 static int control_freeze(struct ctdb_context *ctdb, int argc, const char **argv)
1706 {
1707         int ret;
1708
1709         ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.pnn);
1710         if (ret != 0) {
1711                 DEBUG(DEBUG_ERR, ("Unable to freeze node %u\n", options.pnn));
1712         }               
1713         return 0;
1714 }
1715
1716 /*
1717   thaw a node
1718  */
1719 static int control_thaw(struct ctdb_context *ctdb, int argc, const char **argv)
1720 {
1721         int ret;
1722
1723         ret = ctdb_ctrl_thaw(ctdb, TIMELIMIT(), options.pnn);
1724         if (ret != 0) {
1725                 DEBUG(DEBUG_ERR, ("Unable to thaw node %u\n", options.pnn));
1726         }               
1727         return 0;
1728 }
1729
1730
1731 /*
1732   attach to a database
1733  */
1734 static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv)
1735 {
1736         const char *db_name;
1737         struct ctdb_db_context *ctdb_db;
1738
1739         if (argc < 1) {
1740                 usage();
1741         }
1742         db_name = argv[0];
1743
1744         ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
1745         if (ctdb_db == NULL) {
1746                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
1747                 return -1;
1748         }
1749
1750         return 0;
1751 }
1752
1753 /*
1754   run an eventscript on a node
1755  */
1756 static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
1757 {
1758         TDB_DATA data;
1759         int ret;
1760         int32_t res;
1761         char *errmsg;
1762         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1763
1764         if (argc != 1) {
1765                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
1766                 return -1;
1767         }
1768
1769         data.dptr = (unsigned char *)discard_const(argv[0]);
1770         data.dsize = strlen((char *)data.dptr) + 1;
1771
1772         DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
1773
1774         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
1775                            0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
1776         if (ret != 0 || res != 0) {
1777                 DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
1778                 talloc_free(tmp_ctx);
1779                 return -1;
1780         }
1781         talloc_free(tmp_ctx);
1782         return 0;
1783 }
1784
1785 struct db_file_header {
1786         unsigned long persistent;
1787         unsigned long size;
1788 };
1789
1790 /*
1791  * backup a database to a file 
1792  */
1793 static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **argv)
1794 {
1795         int i, ret;
1796         struct ctdb_dbid_map *dbmap=NULL;
1797         struct ctdb_node_map *nodemap=NULL;
1798         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1799         TDB_DATA outdata;
1800         struct db_file_header dbhdr;
1801         int fh;
1802         uint32_t *nodes;
1803
1804         if (argc != 2) {
1805                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
1806                 return -1;
1807         }
1808
1809         ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
1810         if (ret != 0) {
1811                 DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
1812                 return ret;
1813         }
1814
1815         for(i=0;i<dbmap->num;i++){
1816                 const char *name;
1817
1818                 ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
1819                 if(!strcmp(argv[0], name)){
1820                         talloc_free(discard_const(name));
1821                         break;
1822                 }
1823                 talloc_free(discard_const(name));
1824         }
1825         if (i == dbmap->num) {
1826                 DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
1827                 talloc_free(tmp_ctx);
1828                 return -1;
1829         }
1830
1831         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
1832         if (ret != 0) {
1833                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1834                 talloc_free(tmp_ctx);
1835                 return ret;
1836         }
1837
1838         /* freeze all nodes */
1839         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
1840         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
1841                                         nodes, TIMELIMIT(),
1842                                         false, tdb_null,
1843                                         NULL, NULL,
1844                                         NULL) != 0) {
1845                 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
1846                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
1847                 talloc_free(tmp_ctx);
1848                 return -1;
1849         }
1850
1851         ret = ctdb_ctrl_pulldb(ctdb, options.pnn, dbmap->dbs[i].dbid,
1852                         CTDB_LMASTER_ANY, tmp_ctx,
1853                         TIMELIMIT(), &outdata);
1854         if (ret != 0) {
1855                 DEBUG(DEBUG_ERR,(__location__ " Unable to copy db from node %u\n", options.pnn));
1856                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
1857                 talloc_free(tmp_ctx);
1858                 return -1;
1859         }
1860
1861         /* thaw all nodes */
1862         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
1863         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
1864                                         nodes, TIMELIMIT(),
1865                                         false, tdb_null,
1866                                         NULL, NULL,
1867                                         NULL) != 0) {
1868                 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
1869                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
1870                 talloc_free(tmp_ctx);
1871                 return -1;
1872         }
1873
1874         fh = open(argv[1], O_RDWR|O_CREAT, 0600);
1875         if (fh == -1) {
1876                 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
1877                 talloc_free(tmp_ctx);
1878                 return -1;
1879         }
1880
1881         dbhdr.persistent = dbmap->dbs[i].persistent;
1882         dbhdr.size = outdata.dsize;
1883         write(fh, &dbhdr, sizeof(dbhdr));
1884         write(fh, outdata.dptr, outdata.dsize);
1885
1886         close(fh);
1887         talloc_free(tmp_ctx);
1888         return 0;
1889 }
1890
1891 /*
1892  * restore a database from a file 
1893  */
1894 static int control_restoredb(struct ctdb_context *ctdb, int argc, const char **argv)
1895 {
1896         int ret;
1897         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1898         TDB_DATA outdata;
1899         TDB_DATA data;
1900         struct db_file_header dbhdr;
1901         struct ctdb_db_context *ctdb_db;
1902         struct ctdb_node_map *nodemap=NULL;
1903         struct ctdb_vnn_map *vnnmap=NULL;
1904         int fh;
1905         struct ctdb_control_wipe_database w;
1906         uint32_t *nodes;
1907         uint32_t generation;
1908
1909         if (argc != 2) {
1910                 DEBUG(DEBUG_ERR,("Invalid arguments\n"));
1911                 return -1;
1912         }
1913
1914         fh = open(argv[1], O_RDONLY);
1915         if (fh == -1) {
1916                 DEBUG(DEBUG_ERR,("Failed to open file '%s'\n", argv[1]));
1917                 talloc_free(tmp_ctx);
1918                 return -1;
1919         }
1920
1921         read(fh, &dbhdr, sizeof(dbhdr));
1922         outdata.dsize = dbhdr.size;
1923         outdata.dptr = talloc_size(tmp_ctx, outdata.dsize);
1924         if (outdata.dptr == NULL) {
1925                 DEBUG(DEBUG_ERR,("Failed to allocate data of size '%lu'\n", dbhdr.size));
1926                 close(fh);
1927                 talloc_free(tmp_ctx);
1928                 return -1;
1929         }               
1930         read(fh, outdata.dptr, outdata.dsize);
1931         close(fh);
1932
1933
1934         ctdb_db = ctdb_attach(ctdb, argv[0], dbhdr.persistent, 0);
1935         if (ctdb_db == NULL) {
1936                 DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
1937                 talloc_free(tmp_ctx);
1938                 return -1;
1939         }
1940
1941         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
1942         if (ret != 0) {
1943                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
1944                 talloc_free(tmp_ctx);
1945                 return ret;
1946         }
1947
1948
1949         ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &vnnmap);
1950         if (ret != 0) {
1951                 DEBUG(DEBUG_ERR, ("Unable to get vnnmap from node %u\n", options.pnn));
1952                 talloc_free(tmp_ctx);
1953                 return ret;
1954         }
1955
1956         /* freeze all nodes */
1957         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
1958         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_FREEZE,
1959                                         nodes, TIMELIMIT(),
1960                                         false, tdb_null,
1961                                         NULL, NULL,
1962                                         NULL) != 0) {
1963                 DEBUG(DEBUG_ERR, ("Unable to freeze nodes.\n"));
1964                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
1965                 talloc_free(tmp_ctx);
1966                 return -1;
1967         }
1968
1969         generation = vnnmap->generation;
1970         data.dptr = (void *)&generation;
1971         data.dsize = sizeof(generation);
1972
1973         /* start a cluster wide transaction */
1974         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
1975         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_START,
1976                                         nodes,
1977                                         TIMELIMIT(), false, data,
1978                                         NULL, NULL,
1979                                         NULL) != 0) {
1980                 DEBUG(DEBUG_ERR, ("Unable to start cluster wide transactions.\n"));
1981                 return -1;
1982         }
1983
1984
1985         w.db_id = ctdb_db->db_id;
1986         w.transaction_id = generation;
1987
1988         data.dptr = (void *)&w;
1989         data.dsize = sizeof(w);
1990
1991         /* wipe all the remote databases. */
1992         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
1993         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_WIPE_DATABASE,
1994                                         nodes,
1995                                         TIMELIMIT(), false, data,
1996                                         NULL, NULL,
1997                                         NULL) != 0) {
1998                 DEBUG(DEBUG_ERR, ("Unable to wipe database.\n"));
1999                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2000                 talloc_free(tmp_ctx);
2001                 return -1;
2002         }
2003         
2004         /* push the database */
2005         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2006         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_PUSH_DB,
2007                                         nodes,
2008                                         TIMELIMIT(), false, outdata,
2009                                         NULL, NULL,
2010                                         NULL) != 0) {
2011                 DEBUG(DEBUG_ERR, ("Failed to push database.\n"));
2012                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2013                 talloc_free(tmp_ctx);
2014                 return -1;
2015         }
2016
2017         data.dptr = (void *)&generation;
2018         data.dsize = sizeof(generation);
2019
2020         /* commit all the changes */
2021         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_TRANSACTION_COMMIT,
2022                                         nodes,
2023                                         TIMELIMIT(), false, data,
2024                                         NULL, NULL,
2025                                         NULL) != 0) {
2026                 DEBUG(DEBUG_ERR, ("Unable to commit databases.\n"));
2027                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2028                 talloc_free(tmp_ctx);
2029                 return -1;
2030         }
2031
2032
2033         /* thaw all nodes */
2034         nodes = list_of_active_nodes(ctdb, nodemap, tmp_ctx, true);
2035         if (ctdb_client_async_control(ctdb, CTDB_CONTROL_THAW,
2036                                         nodes, TIMELIMIT(),
2037                                         false, tdb_null,
2038                                         NULL, NULL,
2039                                         NULL) != 0) {
2040                 DEBUG(DEBUG_ERR, ("Unable to thaw nodes.\n"));
2041                 ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.pnn, CTDB_RECOVERY_ACTIVE);
2042                 talloc_free(tmp_ctx);
2043                 return -1;
2044         }
2045
2046
2047         talloc_free(tmp_ctx);
2048         return 0;
2049 }
2050
2051 /*
2052   dump memory usage
2053  */
2054 static int control_dumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
2055 {
2056         TDB_DATA data;
2057         int ret;
2058         int32_t res;
2059         char *errmsg;
2060         TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2061         ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_DUMP_MEMORY,
2062                            0, tdb_null, tmp_ctx, &data, &res, NULL, &errmsg);
2063         if (ret != 0 || res != 0) {
2064                 DEBUG(DEBUG_ERR,("Failed to dump memory - %s\n", errmsg));
2065                 talloc_free(tmp_ctx);
2066                 return -1;
2067         }
2068         write(1, data.dptr, data.dsize);
2069         talloc_free(tmp_ctx);
2070         return 0;
2071 }
2072
2073 /*
2074   handler for memory dumps
2075 */
2076 static void mem_dump_handler(struct ctdb_context *ctdb, uint64_t srvid, 
2077                              TDB_DATA data, void *private_data)
2078 {
2079         write(1, data.dptr, data.dsize);
2080         exit(0);
2081 }
2082
2083 /*
2084   dump memory usage on the recovery daemon
2085  */
2086 static int control_rddumpmemory(struct ctdb_context *ctdb, int argc, const char **argv)
2087 {
2088         int ret;
2089         TDB_DATA data;
2090         struct rd_memdump_reply rd;
2091
2092         rd.pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2093         if (rd.pnn == -1) {
2094                 DEBUG(DEBUG_ERR, ("Failed to get pnn of local node\n"));
2095                 return -1;
2096         }
2097         rd.srvid = getpid();
2098
2099         /* register a message port for receiveing the reply so that we
2100            can receive the reply
2101         */
2102         ctdb_set_message_handler(ctdb, rd.srvid, mem_dump_handler, NULL);
2103
2104
2105         data.dptr = (uint8_t *)&rd;
2106         data.dsize = sizeof(rd);
2107
2108         ret = ctdb_send_message(ctdb, options.pnn, CTDB_SRVID_MEM_DUMP, data);
2109         if (ret != 0) {
2110                 DEBUG(DEBUG_ERR,("Failed to send memdump request message to %u\n", options.pnn));
2111                 return -1;
2112         }
2113
2114         /* this loop will terminate when we have received the reply */
2115         while (1) {     
2116                 event_loop_once(ctdb->ev);
2117         }
2118
2119         return 0;
2120 }
2121
2122 /*
2123   list all nodes in the cluster
2124  */
2125 static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **argv)
2126 {
2127         int i, ret;
2128         struct ctdb_node_map *nodemap=NULL;
2129
2130         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, ctdb, &nodemap);
2131         if (ret != 0) {
2132                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
2133                 return ret;
2134         }
2135
2136         for(i=0;i<nodemap->num;i++){
2137                 printf("%s\n", inet_ntoa(nodemap->nodes[i].sin.sin_addr));
2138         }
2139
2140         return 0;
2141 }
2142
2143 /*
2144   reload the nodes file on the local node
2145  */
2146 static int control_reload_nodes_file(struct ctdb_context *ctdb, int argc, const char **argv)
2147 {
2148         int i, ret;
2149         int mypnn;
2150         struct ctdb_node_map *nodemap=NULL;
2151
2152         mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
2153         if (mypnn == -1) {
2154                 DEBUG(DEBUG_ERR, ("Failed to read pnn of local node\n"));
2155                 return -1;
2156         }
2157
2158         ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
2159         if (ret != 0) {
2160                 DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
2161                 return ret;
2162         }
2163
2164         /* reload the nodes file on all remote nodes */
2165         for (i=0;i<nodemap->num;i++) {
2166                 if (nodemap->nodes[i].pnn == mypnn) {
2167                         continue;
2168                 }
2169                 DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", nodemap->nodes[i].pnn));
2170                 ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(),
2171                         nodemap->nodes[i].pnn);
2172                 if (ret != 0) {
2173                         DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", nodemap->nodes[i].pnn));
2174                 }
2175         }
2176
2177         /* reload the nodes file on the local node */
2178         DEBUG(DEBUG_NOTICE, ("Reloading nodes file on node %u\n", mypnn));
2179         ret = ctdb_ctrl_reload_nodes_file(ctdb, TIMELIMIT(), mypnn);
2180         if (ret != 0) {
2181                 DEBUG(DEBUG_ERR, ("ERROR: Failed to reload nodes file on node %u. You MUST fix that node manually!\n", mypnn));
2182         }
2183
2184         return 0;
2185 }
2186
2187
2188 static const struct {
2189         const char *name;
2190         int (*fn)(struct ctdb_context *, int, const char **);
2191         bool auto_all;
2192         const char *msg;
2193         const char *args;
2194 } ctdb_commands[] = {
2195 #ifdef CTDB_VERS
2196         { "version",         control_version,           true,  "show version of ctdb" },
2197 #endif
2198         { "status",          control_status,            true,  "show node status" },
2199         { "uptime",          control_uptime,            true,  "show node uptime" },
2200         { "ping",            control_ping,              true,  "ping all nodes" },
2201         { "getvar",          control_getvar,            true,  "get a tunable variable",               "<name>"},
2202         { "setvar",          control_setvar,            true,  "set a tunable variable",               "<name> <value>"},
2203         { "listvars",        control_listvars,          true,  "list tunable variables"},
2204         { "statistics",      control_statistics,        false, "show statistics" },
2205         { "statisticsreset", control_statistics_reset,  true,  "reset statistics"},
2206         { "ip",              control_ip,                false,  "show which public ip's that ctdb manages" },
2207         { "process-exists",  control_process_exists,    true,  "check if a process exists on a node",  "<pid>"},
2208         { "getdbmap",        control_getdbmap,          true,  "show the database map" },
2209         { "catdb",           control_catdb,             true,  "dump a database" ,                     "<dbname>"},
2210         { "getmonmode",      control_getmonmode,        true,  "show monitoring mode" },
2211         { "getcapabilities", control_getcapabilities,   true,  "show node capabilities" },
2212         { "pnn",             control_pnn,               true,  "show the pnn of the currnet node" },
2213         { "lvs",             control_lvs,               true,  "show lvs configuration" },
2214         { "lvsmaster",       control_lvsmaster,         true,  "show which node is the lvs master" },
2215         { "disablemonitor",      control_disable_monmode,        true,  "set monitoring mode to DISABLE" },
2216         { "enablemonitor",      control_enable_monmode,        true,  "set monitoring mode to ACTIVE" },
2217         { "setdebug",        control_setdebug,          true,  "set debug level",                      "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
2218         { "getdebug",        control_getdebug,          true,  "get debug level" },
2219         { "attach",          control_attach,            true,  "attach to a database",                 "<dbname>" },
2220         { "dumpmemory",      control_dumpmemory,        true,  "dump memory map to stdout" },
2221         { "rddumpmemory",    control_rddumpmemory,      true,  "dump memory map from the recovery daemon to stdout" },
2222         { "getpid",          control_getpid,            true,  "get ctdbd process ID" },
2223         { "disable",         control_disable,           true,  "disable a nodes public IP" },
2224         { "enable",          control_enable,            true,  "enable a nodes public IP" },
2225         { "ban",             control_ban,               true,  "ban a node from the cluster",          "<bantime|0>"},
2226         { "unban",           control_unban,             true,  "unban a node from the cluster" },
2227         { "shutdown",        control_shutdown,          true,  "shutdown ctdbd" },
2228         { "recover",         control_recover,           true,  "force recovery" },
2229         { "freeze",          control_freeze,            true,  "freeze all databases" },
2230         { "thaw",            control_thaw,              true,  "thaw all databases" },
2231         { "isnotrecmaster",  control_isnotrecmaster,    false,  "check if the local node is recmaster or not" },
2232         { "killtcp",         kill_tcp,                  false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
2233         { "gratiousarp",     control_gratious_arp,      false, "send a gratious arp", "<ip> <interface>" },
2234         { "tickle",          tickle_tcp,                false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
2235         { "gettickles",      control_get_tickles,       false, "get the list of tickles registered for this ip", "<ip>" },
2236
2237         { "regsrvid",        regsrvid,                  false, "register a server id", "<pnn> <type> <id>" },
2238         { "unregsrvid",      unregsrvid,                false, "unregister a server id", "<pnn> <type> <id>" },
2239         { "chksrvid",        chksrvid,                  false, "check if a server id exists", "<pnn> <type> <id>" },
2240         { "getsrvids",       getsrvids,                 false, "get a list of all server ids"},
2241         { "vacuum",          ctdb_vacuum,               false, "vacuum the databases of empty records", "[max_records]"},
2242         { "repack",          ctdb_repack,               false, "repack all databases", "[max_freelist]"},
2243         { "listnodes",       control_listnodes,         false, "list all nodes in the cluster"},
2244         { "reloadnodes",     control_reload_nodes_file,         false, "reload the nodes file and restart the transport on all nodes"},
2245         { "moveip",          control_moveip,            false, "move/failover an ip address to another node", "<ip> <node>"},
2246         { "addip",           control_addip,             true, "add a ip address to a node", "<ip/mask> <iface>"},
2247         { "delip",           control_delip,             false, "delete an ip address from a node", "<ip>"},
2248         { "eventscript",     control_eventscript,       true, "run the eventscript with the given parameters on a node", "<arguments>"},
2249         { "backupdb",        control_backupdb,          false, "backup the database into a file.", "<database> <file>"},
2250         { "restoredb",        control_restoredb,          false, "restore the database from a file.", "<database> <file>"},
2251 };
2252
2253 /*
2254   show usage message
2255  */
2256 static void usage(void)
2257 {
2258         int i;
2259         printf(
2260 "Usage: ctdb [options] <control>\n" \
2261 "Options:\n" \
2262 "   -n <node>          choose node number, or 'all' (defaults to local node)\n"
2263 "   -Y                 generate machinereadable output\n"
2264 "   -t <timelimit>     set timelimit for control in seconds (default %u)\n", options.timelimit);
2265         printf("Controls:\n");
2266         for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
2267                 printf("  %-15s %-27s  %s\n", 
2268                        ctdb_commands[i].name, 
2269                        ctdb_commands[i].args?ctdb_commands[i].args:"",
2270                        ctdb_commands[i].msg);
2271         }
2272         exit(1);
2273 }
2274
2275
2276 static void ctdb_alarm(int sig)
2277 {
2278         printf("Maximum runtime exceeded - exiting\n");
2279         _exit(0);
2280 }
2281
2282 /*
2283   main program
2284 */
2285 int main(int argc, const char *argv[])
2286 {
2287         struct ctdb_context *ctdb;
2288         char *nodestring = NULL;
2289         struct poptOption popt_options[] = {
2290                 POPT_AUTOHELP
2291                 POPT_CTDB_CMDLINE
2292                 { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
2293                 { "node",      'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
2294                 { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
2295                 { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
2296                 POPT_TABLEEND
2297         };
2298         int opt;
2299         const char **extra_argv;
2300         int extra_argc = 0;
2301         int ret=-1, i;
2302         poptContext pc;
2303         struct event_context *ev;
2304         const char *control;
2305
2306         setlinebuf(stdout);
2307         
2308         /* set some defaults */
2309         options.maxruntime = 0;
2310         options.timelimit = 3;
2311         options.pnn = CTDB_CURRENT_NODE;
2312
2313         pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
2314
2315         while ((opt = poptGetNextOpt(pc)) != -1) {
2316                 switch (opt) {
2317                 default:
2318                         DEBUG(DEBUG_ERR, ("Invalid option %s: %s\n", 
2319                                 poptBadOption(pc, 0), poptStrerror(opt)));
2320                         exit(1);
2321                 }
2322         }
2323
2324         /* setup the remaining options for the main program to use */
2325         extra_argv = poptGetArgs(pc);
2326         if (extra_argv) {
2327                 extra_argv++;
2328                 while (extra_argv[extra_argc]) extra_argc++;
2329         }
2330
2331         if (extra_argc < 1) {
2332                 usage();
2333         }
2334
2335         if (options.maxruntime != 0) {
2336                 signal(SIGALRM, ctdb_alarm);
2337                 alarm(options.maxruntime);
2338         }
2339
2340         /* setup the node number to contact */
2341         if (nodestring != NULL) {
2342                 if (strcmp(nodestring, "all") == 0) {
2343                         options.pnn = CTDB_BROADCAST_ALL;
2344                 } else {
2345                         options.pnn = strtoul(nodestring, NULL, 0);
2346                 }
2347         }
2348
2349         control = extra_argv[0];
2350
2351         ev = event_context_init(NULL);
2352
2353         /* initialise ctdb */
2354         ctdb = ctdb_cmdline_client(ev);
2355         if (ctdb == NULL) {
2356                 DEBUG(DEBUG_ERR, ("Failed to init ctdb\n"));
2357                 exit(1);
2358         }
2359
2360         for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
2361                 if (strcmp(control, ctdb_commands[i].name) == 0) {
2362                         int j;
2363
2364                         if (options.pnn == CTDB_CURRENT_NODE) {
2365                                 int pnn;
2366                                 pnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);         
2367                                 if (pnn == -1) {
2368                                         return -1;
2369                                 }
2370                                 options.pnn = pnn;
2371                         }
2372
2373                         if (ctdb_commands[i].auto_all && 
2374                             options.pnn == CTDB_BROADCAST_ALL) {
2375                                 uint32_t *nodes;
2376                                 uint32_t num_nodes;
2377                                 ret = 0;
2378
2379                                 nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes);
2380                                 CTDB_NO_MEMORY(ctdb, nodes);
2381         
2382                                 for (j=0;j<num_nodes;j++) {
2383                                         options.pnn = nodes[j];
2384                                         ret |= ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
2385                                 }
2386                                 talloc_free(nodes);
2387                         } else {
2388                                 ret = ctdb_commands[i].fn(ctdb, extra_argc-1, extra_argv+1);
2389                         }
2390                         break;
2391                 }
2392         }
2393
2394         if (i == ARRAY_SIZE(ctdb_commands)) {
2395                 DEBUG(DEBUG_ERR, ("Unknown control '%s'\n", control));
2396                 exit(1);
2397         }
2398
2399         return ret;
2400 }