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