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