050906c510d4a1906c63c7a7286715adfdf8468d
[nivanova/samba-autobuild/.git] / ctdb / tools / ctdb.c
1 /*
2    CTDB control tool
3
4    Copyright (C) Amitay Isaacs  2015
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21 #include "system/network.h"
22 #include "system/filesys.h"
23 #include "system/time.h"
24 #include "system/wait.h"
25 #include "system/dir.h"
26
27 #include <ctype.h>
28 #include <popt.h>
29 #include <talloc.h>
30 #include <tevent.h>
31 #include <tdb.h>
32
33 #include "ctdb_version.h"
34 #include "lib/util/debug.h"
35 #include "lib/util/samba_util.h"
36 #include "lib/util/sys_rw.h"
37
38 #include "common/db_hash.h"
39 #include "common/logging.h"
40 #include "protocol/protocol.h"
41 #include "protocol/protocol_api.h"
42 #include "common/system.h"
43 #include "client/client.h"
44
45 #define TIMEOUT()       timeval_current_ofs(options.timelimit, 0)
46
47 #define SRVID_CTDB_TOOL    (CTDB_SRVID_TOOL_RANGE | 0x0001000000000000LL)
48 #define SRVID_CTDB_PUSHDB  (CTDB_SRVID_TOOL_RANGE | 0x0002000000000000LL)
49
50 static struct {
51         const char *socket;
52         const char *debuglevelstr;
53         int timelimit;
54         int pnn;
55         int machinereadable;
56         const char *sep;
57         int machineparsable;
58         int verbose;
59         int maxruntime;
60         int printemptyrecords;
61         int printdatasize;
62         int printlmaster;
63         int printhash;
64         int printrecordflags;
65 } options;
66
67 static poptContext pc;
68
69 struct ctdb_context {
70         struct tevent_context *ev;
71         struct ctdb_client_context *client;
72         struct ctdb_node_map *nodemap;
73         uint32_t pnn, cmd_pnn;
74         uint64_t srvid;
75 };
76
77 static void usage(const char *command);
78
79 /*
80  * Utility Functions
81  */
82
83 static double timeval_delta(struct timeval *tv2, struct timeval *tv)
84 {
85         return (tv2->tv_sec - tv->tv_sec) +
86                (tv2->tv_usec - tv->tv_usec) * 1.0e-6;
87 }
88
89 static struct ctdb_node_and_flags *get_node_by_pnn(
90                                         struct ctdb_node_map *nodemap,
91                                         uint32_t pnn)
92 {
93         int i;
94
95         for (i=0; i<nodemap->num; i++) {
96                 if (nodemap->node[i].pnn == pnn) {
97                         return &nodemap->node[i];
98                 }
99         }
100         return NULL;
101 }
102
103 static const char *pretty_print_flags(TALLOC_CTX *mem_ctx, uint32_t flags)
104 {
105         static const struct {
106                 uint32_t flag;
107                 const char *name;
108         } flag_names[] = {
109                 { NODE_FLAGS_DISCONNECTED,          "DISCONNECTED" },
110                 { NODE_FLAGS_PERMANENTLY_DISABLED,  "DISABLED" },
111                 { NODE_FLAGS_BANNED,                "BANNED" },
112                 { NODE_FLAGS_UNHEALTHY,             "UNHEALTHY" },
113                 { NODE_FLAGS_DELETED,               "DELETED" },
114                 { NODE_FLAGS_STOPPED,               "STOPPED" },
115                 { NODE_FLAGS_INACTIVE,              "INACTIVE" },
116         };
117         char *flags_str = NULL;
118         int i;
119
120         for (i=0; i<ARRAY_SIZE(flag_names); i++) {
121                 if (flags & flag_names[i].flag) {
122                         if (flags_str == NULL) {
123                                 flags_str = talloc_asprintf(mem_ctx,
124                                                 "%s", flag_names[i].name);
125                         } else {
126                                 flags_str = talloc_asprintf_append(flags_str,
127                                                 "|%s", flag_names[i].name);
128                         }
129                         if (flags_str == NULL) {
130                                 return "OUT-OF-MEMORY";
131                         }
132                 }
133         }
134         if (flags_str == NULL) {
135                 return "OK";
136         }
137
138         return flags_str;
139 }
140
141 static uint64_t next_srvid(struct ctdb_context *ctdb)
142 {
143         ctdb->srvid += 1;
144         return ctdb->srvid;
145 }
146
147 /*
148  * Get consistent nodemap information.
149  *
150  * If nodemap is already cached, use that. If not get it.
151  * If the current node is BANNED, then get nodemap from "better" node.
152  */
153 static struct ctdb_node_map *get_nodemap(struct ctdb_context *ctdb, bool force)
154 {
155         TALLOC_CTX *tmp_ctx;
156         struct ctdb_node_map *nodemap;
157         struct ctdb_node_and_flags *node;
158         uint32_t current_node;
159         int ret;
160
161         if (force) {
162                 TALLOC_FREE(ctdb->nodemap);
163         }
164
165         if (ctdb->nodemap != NULL) {
166                 return ctdb->nodemap;
167         }
168
169         tmp_ctx = talloc_new(ctdb);
170         if (tmp_ctx == NULL) {
171                 return false;
172         }
173
174         current_node = ctdb->pnn;
175 again:
176         ret = ctdb_ctrl_get_nodemap(tmp_ctx, ctdb->ev, ctdb->client,
177                                     current_node, TIMEOUT(), &nodemap);
178         if (ret != 0) {
179                 fprintf(stderr, "Failed to get nodemap from node %u\n",
180                         current_node);
181                 goto failed;
182         }
183
184         node = get_node_by_pnn(nodemap, current_node);
185         if (node->flags & NODE_FLAGS_BANNED) {
186                 /* Pick next node */
187                 do {
188                         current_node = (current_node + 1) % nodemap->num;
189                         node = get_node_by_pnn(nodemap, current_node);
190                         if (! (node->flags &
191                               (NODE_FLAGS_DELETED|NODE_FLAGS_DISCONNECTED))) {
192                                 break;
193                         }
194                 } while (current_node != ctdb->pnn);
195
196                 if (current_node == ctdb->pnn) {
197                         /* Tried all nodes in the cluster */
198                         fprintf(stderr, "Warning: All nodes are banned.\n");
199                         goto failed;
200                 }
201
202                 goto again;
203         }
204
205         ctdb->nodemap = talloc_steal(ctdb, nodemap);
206         return nodemap;
207
208 failed:
209         talloc_free(tmp_ctx);
210         return NULL;
211 }
212
213 static bool verify_pnn(struct ctdb_context *ctdb, int pnn)
214 {
215         struct ctdb_node_map *nodemap;
216         bool found;
217         int i;
218
219         if (pnn == -1) {
220                 return false;
221         }
222
223         nodemap = get_nodemap(ctdb, false);
224         if (nodemap == NULL) {
225                 return false;
226         }
227
228         found = false;
229         for (i=0; i<nodemap->num; i++) {
230                 if (nodemap->node[i].pnn == pnn) {
231                         found = true;
232                         break;
233                 }
234         }
235         if (! found) {
236                 fprintf(stderr, "Node %u does not exist\n", pnn);
237                 return false;
238         }
239
240         if (nodemap->node[i].flags &
241             (NODE_FLAGS_DISCONNECTED|NODE_FLAGS_DELETED)) {
242                 fprintf(stderr, "Node %u has status %s\n", pnn,
243                         pretty_print_flags(ctdb, nodemap->node[i].flags));
244                 return false;
245         }
246
247         return true;
248 }
249
250 static struct ctdb_node_map *talloc_nodemap(TALLOC_CTX *mem_ctx,
251                                             struct ctdb_node_map *nodemap)
252 {
253         struct ctdb_node_map *nodemap2;
254
255         nodemap2 = talloc_zero(mem_ctx, struct ctdb_node_map);
256         if (nodemap2 == NULL) {
257                 return NULL;
258         }
259
260         nodemap2->node = talloc_array(nodemap2, struct ctdb_node_and_flags,
261                                       nodemap->num);
262         if (nodemap2->node == NULL) {
263                 talloc_free(nodemap2);
264                 return NULL;
265         }
266
267         return nodemap2;
268 }
269
270 /*
271  * Get the number and the list of matching nodes
272  *
273  *   nodestring :=  NULL | all | pnn,[pnn,...]
274  *
275  * If nodestring is NULL, use the current node.
276  */
277 static bool parse_nodestring(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
278                              const char *nodestring,
279                              struct ctdb_node_map **out)
280 {
281         struct ctdb_node_map *nodemap, *nodemap2;
282         struct ctdb_node_and_flags *node;
283         int i;
284
285         nodemap = get_nodemap(ctdb, false);
286         if (nodemap == NULL) {
287                 return false;
288         }
289
290         nodemap2 = talloc_nodemap(mem_ctx, nodemap);
291         if (nodemap2 == NULL) {
292                 return false;
293         }
294
295         if (nodestring == NULL) {
296                 for (i=0; i<nodemap->num; i++) {
297                         if (nodemap->node[i].pnn == ctdb->cmd_pnn) {
298                                 nodemap2->node[0] = nodemap->node[i];
299                                 break;
300                         }
301                 }
302                 nodemap2->num = 1;
303
304                 goto done;
305         }
306
307         if (strcmp(nodestring, "all") == 0) {
308                 for (i=0; i<nodemap->num; i++) {
309                         nodemap2->node[i] = nodemap->node[i];
310                 }
311                 nodemap2->num = nodemap->num;
312
313                 goto done;
314         } else {
315                 char *ns, *tok;
316
317                 ns = talloc_strdup(mem_ctx, nodestring);
318                 if (ns == NULL) {
319                         return false;
320                 }
321
322                 tok = strtok(ns, ",");
323                 while (tok != NULL) {
324                         uint32_t pnn;
325                         char *endptr;
326
327                         pnn = (uint32_t)strtoul(tok, &endptr, 0);
328                         if (pnn == 0 && tok == endptr) {
329                                 fprintf(stderr, "Invalid node %s\n", tok);
330                                         return false;
331                         }
332
333                         node = get_node_by_pnn(nodemap, pnn);
334                         if (node == NULL) {
335                                 fprintf(stderr, "Node %u does not exist\n",
336                                         pnn);
337                                 return false;
338                         }
339
340                         nodemap2->node[nodemap2->num] = *node;
341                         nodemap2->num += 1;
342
343                         tok = strtok(NULL, ",");
344                 }
345         }
346
347 done:
348         *out = nodemap2;
349         return true;
350 }
351
352 /* Compare IP address */
353 static bool ctdb_same_ip(ctdb_sock_addr *ip1, ctdb_sock_addr *ip2)
354 {
355         bool ret = false;
356
357         if (ip1->sa.sa_family != ip2->sa.sa_family) {
358                 return false;
359         }
360
361         switch (ip1->sa.sa_family) {
362         case AF_INET:
363                 ret = (memcmp(&ip1->ip.sin_addr, &ip2->ip.sin_addr,
364                               sizeof(struct in_addr)) == 0);
365                 break;
366
367         case AF_INET6:
368                 ret = (memcmp(&ip1->ip6.sin6_addr, &ip2->ip6.sin6_addr,
369                               sizeof(struct in6_addr)) == 0);
370                 break;
371         }
372
373         return ret;
374 }
375
376 /* Append a node to a node map with given address and flags */
377 static bool node_map_add(struct ctdb_node_map *nodemap,
378                          const char *nstr, uint32_t flags)
379 {
380         ctdb_sock_addr addr;
381         uint32_t num;
382         struct ctdb_node_and_flags *n;
383
384         if (! parse_ip(nstr, NULL, 0, &addr)) {
385                 fprintf(stderr, "Invalid IP address %s\n", nstr);
386                 return false;
387         }
388
389         num = nodemap->num;
390         nodemap->node = talloc_realloc(nodemap, nodemap->node,
391                                        struct ctdb_node_and_flags, num+1);
392         if (nodemap->node == NULL) {
393                 return false;
394         }
395
396         n = &nodemap->node[num];
397         n->addr = addr;
398         n->pnn = num;
399         n->flags = flags;
400
401         nodemap->num = num+1;
402         return true;
403 }
404
405 /* Read a nodes file into a node map */
406 static struct ctdb_node_map *ctdb_read_nodes_file(TALLOC_CTX *mem_ctx,
407                                                   const char *nlist)
408 {
409         char **lines;
410         int nlines;
411         int i;
412         struct ctdb_node_map *nodemap;
413
414         nodemap = talloc_zero(mem_ctx, struct ctdb_node_map);
415         if (nodemap == NULL) {
416                 return NULL;
417         }
418
419         lines = file_lines_load(nlist, &nlines, 0, mem_ctx);
420         if (lines == NULL) {
421                 return NULL;
422         }
423
424         while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
425                 nlines--;
426         }
427
428         for (i=0; i<nlines; i++) {
429                 char *node;
430                 uint32_t flags;
431                 size_t len;
432
433                 node = lines[i];
434                 /* strip leading spaces */
435                 while((*node == ' ') || (*node == '\t')) {
436                         node++;
437                 }
438
439                 len = strlen(node);
440
441                 /* strip trailing spaces */
442                 while ((len > 1) &&
443                        ((node[len-1] == ' ') || (node[len-1] == '\t')))
444                 {
445                         node[len-1] = '\0';
446                         len--;
447                 }
448
449                 if (len == 0) {
450                         continue;
451                 }
452                 if (*node == '#') {
453                         /* A "deleted" node is a node that is
454                            commented out in the nodes file.  This is
455                            used instead of removing a line, which
456                            would cause subsequent nodes to change
457                            their PNN. */
458                         flags = NODE_FLAGS_DELETED;
459                         node = discard_const("0.0.0.0");
460                 } else {
461                         flags = 0;
462                 }
463                 if (! node_map_add(nodemap, node, flags)) {
464                         talloc_free(lines);
465                         TALLOC_FREE(nodemap);
466                         return NULL;
467                 }
468         }
469
470         talloc_free(lines);
471         return nodemap;
472 }
473
474 static struct ctdb_node_map *read_nodes_file(TALLOC_CTX *mem_ctx, uint32_t pnn)
475 {
476         struct ctdb_node_map *nodemap;
477         char *nodepath;
478         const char *nodes_list = NULL;
479
480         if (pnn != CTDB_UNKNOWN_PNN) {
481                 nodepath = talloc_asprintf(mem_ctx, "CTDB_NODES_%u", pnn);
482                 if (nodepath != NULL) {
483                         nodes_list = getenv(nodepath);
484                 }
485         }
486         if (nodes_list == NULL) {
487                 nodes_list = getenv("CTDB_NODES");
488         }
489         if (nodes_list == NULL) {
490                 const char *basedir = getenv("CTDB_BASE");
491                 if (basedir == NULL) {
492                         basedir = CTDB_ETCDIR;
493                 }
494                 nodes_list = talloc_asprintf(mem_ctx, "%s/nodes", basedir);
495                 if (nodes_list == NULL) {
496                         fprintf(stderr, "Memory allocation error\n");
497                         return NULL;
498                 }
499         }
500
501         nodemap = ctdb_read_nodes_file(mem_ctx, nodes_list);
502         if (nodemap == NULL) {
503                 fprintf(stderr, "Failed to read nodes file \"%s\"\n",
504                         nodes_list);
505                 return NULL;
506         }
507
508         return nodemap;
509 }
510
511 static struct ctdb_dbid *db_find(TALLOC_CTX *mem_ctx,
512                                  struct ctdb_context *ctdb,
513                                  struct ctdb_dbid_map *dbmap,
514                                  const char *db_name)
515 {
516         struct ctdb_dbid *db = NULL;
517         const char *name;
518         int ret, i;
519
520         for (i=0; i<dbmap->num; i++) {
521                 ret = ctdb_ctrl_get_dbname(mem_ctx, ctdb->ev, ctdb->client,
522                                            ctdb->pnn, TIMEOUT(),
523                                            dbmap->dbs[i].db_id, &name);
524                 if (ret != 0) {
525                         return false;
526                 }
527
528                 if (strcmp(db_name, name) == 0) {
529                         talloc_free(discard_const(name));
530                         db = &dbmap->dbs[i];
531                         break;
532                 }
533         }
534
535         return db;
536 }
537
538 static bool db_exists(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
539                       const char *db_arg, uint32_t *db_id,
540                       const char **db_name, uint8_t *db_flags)
541 {
542         struct ctdb_dbid_map *dbmap;
543         struct ctdb_dbid *db = NULL;
544         uint32_t id = 0;
545         const char *name = NULL;
546         int ret, i;
547
548         ret = ctdb_ctrl_get_dbmap(mem_ctx, ctdb->ev, ctdb->client,
549                                   ctdb->pnn, TIMEOUT(), &dbmap);
550         if (ret != 0) {
551                 return false;
552         }
553
554         if (strncmp(db_arg, "0x", 2) == 0) {
555                 id = strtoul(db_arg, NULL, 0);
556                 for (i=0; i<dbmap->num; i++) {
557                         if (id == dbmap->dbs[i].db_id) {
558                                 db = &dbmap->dbs[i];
559                                 break;
560                         }
561                 }
562         } else {
563                 name = db_arg;
564                 db = db_find(mem_ctx, ctdb, dbmap, name);
565         }
566
567         if (db == NULL) {
568                 fprintf(stderr, "No database matching '%s' found\n", db_arg);
569                 return false;
570         }
571
572         if (name == NULL) {
573                 ret = ctdb_ctrl_get_dbname(mem_ctx, ctdb->ev, ctdb->client,
574                                            ctdb->pnn, TIMEOUT(), id, &name);
575                 if (ret != 0) {
576                         return false;
577                 }
578         }
579
580         if (db_id != NULL) {
581                 *db_id = db->db_id;
582         }
583         if (db_name != NULL) {
584                 *db_name = talloc_strdup(mem_ctx, name);
585         }
586         if (db_flags != NULL) {
587                 *db_flags = db->flags;
588         }
589         return true;
590 }
591
592 static int h2i(char h)
593 {
594         if (h >= 'a' && h <= 'f') {
595                 return h - 'a' + 10;
596         }
597         if (h >= 'A' && h <= 'F') {
598                 return h - 'f' + 10;
599         }
600         return h - '0';
601 }
602
603 static int hex_to_data(const char *str, size_t len, TALLOC_CTX *mem_ctx,
604                        TDB_DATA *out)
605 {
606         int i;
607         TDB_DATA data;
608
609         if (len & 0x01) {
610                 fprintf(stderr, "Key (%s) contains odd number of hex digits\n",
611                         str);
612                 return EINVAL;
613         }
614
615         data.dsize = len / 2;
616         data.dptr = talloc_size(mem_ctx, data.dsize);
617         if (data.dptr == NULL) {
618                 return ENOMEM;
619         }
620
621         for (i=0; i<data.dsize; i++) {
622                 data.dptr[i] = h2i(str[i*2]) << 4 | h2i(str[i*2+1]);
623         }
624
625         *out = data;
626         return 0;
627 }
628
629 static int str_to_data(const char *str, size_t len, TALLOC_CTX *mem_ctx,
630                        TDB_DATA *out)
631 {
632         TDB_DATA data;
633         int ret = 0;
634
635         if (strncmp(str, "0x", 2) == 0) {
636                 ret = hex_to_data(str+2, len-2, mem_ctx, &data);
637         } else {
638                 data.dptr = talloc_memdup(mem_ctx, str, len);
639                 if (data.dptr == NULL) {
640                         return ENOMEM;
641                 }
642                 data.dsize = len;
643         }
644
645         *out = data;
646         return ret;
647 }
648
649 static int run_helper(TALLOC_CTX *mem_ctx, const char *command,
650                       const char *path, int argc, const char **argv)
651 {
652         pid_t pid;
653         int save_errno, status, ret;
654         const char **new_argv;
655         int i;
656
657         new_argv = talloc_array(mem_ctx, const char *, argc + 2);
658         if (new_argv == NULL) {
659                 return ENOMEM;
660         }
661
662         new_argv[0] = path;
663         for (i=0; i<argc; i++) {
664                 new_argv[i+1] = argv[i];
665         }
666         new_argv[argc+1] = NULL;
667
668         pid = fork();
669         if (pid < 0) {
670                 save_errno = errno;
671                 talloc_free(new_argv);
672                 fprintf(stderr, "Failed to fork %s (%s) - %s\n",
673                         command, path, strerror(save_errno));
674                 return save_errno;
675         }
676
677         if (pid == 0) {
678                 ret = execv(path, discard_const(new_argv));
679                 if (ret == -1) {
680                         _exit(64+errno);
681                 }
682                 /* Should not happen */
683                 _exit(64+ENOEXEC);
684         }
685
686         talloc_free(new_argv);
687
688         ret = waitpid(pid, &status, 0);
689         if (ret == -1) {
690                 save_errno = errno;
691                 fprintf(stderr, "waitpid() failed for %s - %s\n",
692                         command, strerror(save_errno));
693                 return save_errno;
694         }
695
696         if (WIFEXITED(status)) {
697                 int pstatus = WEXITSTATUS(status);
698                 if (WIFSIGNALED(status)) {
699                         fprintf(stderr, "%s terminated with signal %d\n",
700                                 command, WTERMSIG(status));
701                         ret = EINTR;
702                 } else if (pstatus >= 64 && pstatus < 255) {
703                         fprintf(stderr, "%s failed with error %d\n",
704                                 command, pstatus-64);
705                         ret = pstatus - 64;
706                 } else {
707                         ret = pstatus;
708                 }
709                 return ret;
710         } else if (WIFSIGNALED(status)) {
711                 fprintf(stderr, "%s terminated with signal %d\n",
712                         command, WTERMSIG(status));
713                 return EINTR;
714         }
715
716         return 0;
717 }
718
719 /*
720  * Command Functions
721  */
722
723 static int control_version(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
724                            int argc, const char **argv)
725 {
726         printf("%s\n", CTDB_VERSION_STRING);
727         return 0;
728 }
729
730 static bool partially_online(TALLOC_CTX *mem_ctx,
731                              struct ctdb_context *ctdb,
732                              struct ctdb_node_and_flags *node)
733 {
734         struct ctdb_iface_list *iface_list;
735         int ret, i;
736         bool status = false;
737
738         if (node->flags != 0) {
739                 return false;
740         }
741
742         ret = ctdb_ctrl_get_ifaces(mem_ctx, ctdb->ev, ctdb->client,
743                                    node->pnn, TIMEOUT(), &iface_list);
744         if (ret != 0) {
745                 return false;
746         }
747
748         status = false;
749         for (i=0; i < iface_list->num; i++) {
750                 if (iface_list->iface[i].link_state == 0) {
751                         status = true;
752                         break;
753                 }
754         }
755
756         return status;
757 }
758
759 static void print_nodemap_machine(TALLOC_CTX *mem_ctx,
760                                   struct ctdb_context *ctdb,
761                                   struct ctdb_node_map *nodemap,
762                                   uint32_t mypnn)
763 {
764         struct ctdb_node_and_flags *node;
765         int i;
766
767         printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
768                options.sep,
769                "Node", options.sep,
770                "IP", options.sep,
771                "Disconnected", options.sep,
772                "Banned", options.sep,
773                "Disabled", options.sep,
774                "Unhealthy", options.sep,
775                "Stopped", options.sep,
776                "Inactive", options.sep,
777                "PartiallyOnline", options.sep,
778                "ThisNode", options.sep);
779
780         for (i=0; i<nodemap->num; i++) {
781                 node = &nodemap->node[i];
782                 if (node->flags & NODE_FLAGS_DELETED) {
783                         continue;
784                 }
785
786                 printf("%s%u%s%s%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%c%s\n",
787                        options.sep,
788                        node->pnn, options.sep,
789                        ctdb_sock_addr_to_string(mem_ctx, &node->addr),
790                        options.sep,
791                        !! (node->flags & NODE_FLAGS_DISCONNECTED), options.sep,
792                        !! (node->flags & NODE_FLAGS_BANNED), options.sep,
793                        !! (node->flags & NODE_FLAGS_PERMANENTLY_DISABLED),
794                        options.sep,
795                        !! (node->flags & NODE_FLAGS_UNHEALTHY), options.sep,
796                        !! (node->flags & NODE_FLAGS_STOPPED), options.sep,
797                        !! (node->flags & NODE_FLAGS_INACTIVE), options.sep,
798                        partially_online(mem_ctx, ctdb, node), options.sep,
799                        (node->pnn == mypnn)?'Y':'N', options.sep);
800         }
801
802 }
803
804 static void print_nodemap(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
805                           struct ctdb_node_map *nodemap, uint32_t mypnn)
806 {
807         struct ctdb_node_and_flags *node;
808         int num_deleted_nodes = 0;
809         int i;
810
811         for (i=0; i<nodemap->num; i++) {
812                 if (nodemap->node[i].flags & NODE_FLAGS_DELETED) {
813                         num_deleted_nodes++;
814                 }
815         }
816
817         if (num_deleted_nodes == 0) {
818                 printf("Number of nodes:%d\n", nodemap->num);
819         } else {
820                 printf("Number of nodes:%d (including %d deleted nodes)\n",
821                        nodemap->num, num_deleted_nodes);
822         }
823
824         for (i=0; i<nodemap->num; i++) {
825                 node = &nodemap->node[i];
826                 if (node->flags & NODE_FLAGS_DELETED) {
827                         continue;
828                 }
829
830                 printf("pnn:%u %-16s %s%s\n",
831                        node->pnn,
832                        ctdb_sock_addr_to_string(mem_ctx, &node->addr),
833                        partially_online(mem_ctx, ctdb, node) ?
834                                 "PARTIALLYONLINE" :
835                                 pretty_print_flags(mem_ctx, node->flags),
836                        node->pnn == mypnn ? " (THIS NODE)" : "");
837         }
838 }
839
840 static void print_status(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
841                          struct ctdb_node_map *nodemap, uint32_t mypnn,
842                          struct ctdb_vnn_map *vnnmap, int recmode,
843                          uint32_t recmaster)
844 {
845         int i;
846
847         print_nodemap(mem_ctx, ctdb, nodemap, mypnn);
848
849         if (vnnmap->generation == INVALID_GENERATION) {
850                 printf("Generation:INVALID\n");
851         } else {
852                 printf("Generation:%u\n", vnnmap->generation);
853         }
854         printf("Size:%d\n", vnnmap->size);
855         for (i=0; i<vnnmap->size; i++) {
856                 printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]);
857         }
858
859         printf("Recovery mode:%s (%d)\n",
860                recmode == CTDB_RECOVERY_NORMAL ? "NORMAL" : "RECOVERY",
861                recmode);
862         printf("Recovery master:%d\n", recmaster);
863 }
864
865 static int control_status(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
866                           int argc, const char **argv)
867 {
868         struct ctdb_node_map *nodemap;
869         struct ctdb_vnn_map *vnnmap;
870         int recmode;
871         uint32_t recmaster;
872         int ret;
873
874         if (argc != 0) {
875                 usage("status");
876         }
877
878         nodemap = get_nodemap(ctdb, false);
879         if (nodemap == NULL) {
880                 return 1;
881         }
882
883         if (options.machinereadable == 1) {
884                 print_nodemap_machine(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn);
885                 return 0;
886         }
887
888         ret = ctdb_ctrl_getvnnmap(mem_ctx, ctdb->ev, ctdb->client,
889                                   ctdb->cmd_pnn, TIMEOUT(), &vnnmap);
890         if (ret != 0) {
891                 return ret;
892         }
893
894         ret = ctdb_ctrl_get_recmode(mem_ctx, ctdb->ev, ctdb->client,
895                                     ctdb->cmd_pnn, TIMEOUT(), &recmode);
896         if (ret != 0) {
897                 return ret;
898         }
899
900         ret = ctdb_ctrl_get_recmaster(mem_ctx, ctdb->ev, ctdb->client,
901                                       ctdb->cmd_pnn, TIMEOUT(), &recmaster);
902         if (ret != 0) {
903                 return ret;
904         }
905
906         print_status(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn, vnnmap,
907                      recmode, recmaster);
908         return 0;
909 }
910
911 static int control_uptime(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
912                           int argc, const char **argv)
913 {
914         struct ctdb_uptime *uptime;
915         int ret, tmp, days, hours, minutes, seconds;
916
917         ret = ctdb_ctrl_uptime(mem_ctx, ctdb->ev, ctdb->client,
918                                ctdb->cmd_pnn, TIMEOUT(), &uptime);
919         if (ret != 0) {
920                 return ret;
921         }
922
923         printf("Current time of node %-4u     :                %s",
924                ctdb->cmd_pnn, ctime(&uptime->current_time.tv_sec));
925
926         tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
927         seconds = tmp % 60; tmp /= 60;
928         minutes = tmp % 60; tmp /= 60;
929         hours = tmp % 24; tmp /= 24;
930         days = tmp;
931
932         printf("Ctdbd start time              : (%03d %02d:%02d:%02d) %s",
933                days, hours, minutes, seconds,
934                ctime(&uptime->ctdbd_start_time.tv_sec));
935
936         tmp = uptime->current_time.tv_sec - uptime->last_recovery_finished.tv_sec;
937         seconds = tmp % 60; tmp /= 60;
938         minutes = tmp % 60; tmp /= 60;
939         hours = tmp % 24; tmp /= 24;
940         days = tmp;
941
942         printf("Time of last recovery/failover: (%03d %02d:%02d:%02d) %s",
943                days, hours, minutes, seconds,
944                ctime(&uptime->last_recovery_finished.tv_sec));
945
946         printf("Duration of last recovery/failover: %lf seconds\n",
947                timeval_delta(&uptime->last_recovery_finished,
948                              &uptime->last_recovery_started));
949
950         return 0;
951 }
952
953 static int control_ping(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
954                         int argc, const char **argv)
955 {
956         struct timeval tv;
957         int ret, num_clients;
958
959         tv = timeval_current();
960         ret = ctdb_ctrl_ping(mem_ctx, ctdb->ev, ctdb->client,
961                              ctdb->cmd_pnn, TIMEOUT(), &num_clients);
962         if (ret != 0) {
963                 return ret;
964         }
965
966         printf("response from %u time=%.6f sec  (%d clients)\n",
967                ctdb->cmd_pnn, timeval_elapsed(&tv), num_clients);
968         return 0;
969 }
970
971 const char *runstate_to_string(enum ctdb_runstate runstate);
972 enum ctdb_runstate runstate_from_string(const char *runstate_str);
973
974 static int control_runstate(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
975                             int argc, const char **argv)
976 {
977         enum ctdb_runstate runstate;
978         bool found;
979         int ret, i;
980
981         ret = ctdb_ctrl_get_runstate(mem_ctx, ctdb->ev, ctdb->client,
982                                      ctdb->cmd_pnn, TIMEOUT(), &runstate);
983         if (ret != 0) {
984                 return ret;
985         }
986
987         found = true;
988         for (i=0; i<argc; i++) {
989                 enum ctdb_runstate t;
990
991                 found = false;
992                 t = ctdb_runstate_from_string(argv[i]);
993                 if (t == CTDB_RUNSTATE_UNKNOWN) {
994                         printf("Invalid run state (%s)\n", argv[i]);
995                         return 1;
996                 }
997
998                 if (t == runstate) {
999                         found = true;
1000                         break;
1001                 }
1002         }
1003
1004         if (! found) {
1005                 printf("CTDB not in required run state (got %s)\n",
1006                        ctdb_runstate_to_string(runstate));
1007                 return 1;
1008         }
1009
1010         printf("%s\n", ctdb_runstate_to_string(runstate));
1011         return 0;
1012 }
1013
1014 static int control_getvar(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1015                           int argc, const char **argv)
1016 {
1017         struct ctdb_var_list *tun_var_list;
1018         uint32_t value;
1019         int ret, i;
1020         bool found;
1021
1022         if (argc != 1) {
1023                 usage("getvar");
1024         }
1025
1026         ret = ctdb_ctrl_list_tunables(mem_ctx, ctdb->ev, ctdb->client,
1027                                       ctdb->cmd_pnn, TIMEOUT(), &tun_var_list);
1028         if (ret != 0) {
1029                 fprintf(stderr,
1030                         "Failed to get list of variables from node %u\n",
1031                         ctdb->cmd_pnn);
1032                 return ret;
1033         }
1034
1035         found = false;
1036         for (i=0; i<tun_var_list->count; i++) {
1037                 if (strcasecmp(tun_var_list->var[i], argv[0]) == 0) {
1038                         found = true;
1039                         break;
1040                 }
1041         }
1042
1043         if (! found) {
1044                 printf("No such tunable %s\n", argv[0]);
1045                 return 1;
1046         }
1047
1048         ret = ctdb_ctrl_get_tunable(mem_ctx, ctdb->ev, ctdb->client,
1049                                     ctdb->cmd_pnn, TIMEOUT(), argv[0], &value);
1050         if (ret != 0) {
1051                 return ret;
1052         }
1053
1054         printf("%-26s = %u\n", argv[0], value);
1055         return 0;
1056 }
1057
1058 static int control_setvar(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1059                           int argc, const char **argv)
1060 {
1061         struct ctdb_var_list *tun_var_list;
1062         struct ctdb_tunable tunable;
1063         int ret, i;
1064         bool found;
1065
1066         if (argc != 2) {
1067                 usage("setvar");
1068         }
1069
1070         ret = ctdb_ctrl_list_tunables(mem_ctx, ctdb->ev, ctdb->client,
1071                                       ctdb->cmd_pnn, TIMEOUT(), &tun_var_list);
1072         if (ret != 0) {
1073                 fprintf(stderr,
1074                         "Failed to get list of variables from node %u\n",
1075                         ctdb->cmd_pnn);
1076                 return ret;
1077         }
1078
1079         found = false;
1080         for (i=0; i<tun_var_list->count; i++) {
1081                 if (strcasecmp(tun_var_list->var[i], argv[0]) == 0) {
1082                         found = true;
1083                         break;
1084                 }
1085         }
1086
1087         if (! found) {
1088                 printf("No such tunable %s\n", argv[0]);
1089                 return 1;
1090         }
1091
1092         tunable.name = argv[0];
1093         tunable.value = strtoul(argv[1], NULL, 0);
1094
1095         ret = ctdb_ctrl_set_tunable(mem_ctx, ctdb->ev, ctdb->client,
1096                                     ctdb->cmd_pnn, TIMEOUT(), &tunable);
1097         if (ret != 0) {
1098                 if (ret == 1) {
1099                         fprintf(stderr,
1100                                 "Setting obsolete tunable variable '%s'\n",
1101                                tunable.name);
1102                         return 0;
1103                 }
1104         }
1105
1106         return ret;
1107 }
1108
1109 static int control_listvars(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1110                             int argc, const char **argv)
1111 {
1112         struct ctdb_var_list *tun_var_list;
1113         int ret, i;
1114
1115         if (argc != 0) {
1116                 usage("listvars");
1117         }
1118
1119         ret = ctdb_ctrl_list_tunables(mem_ctx, ctdb->ev, ctdb->client,
1120                                       ctdb->cmd_pnn, TIMEOUT(), &tun_var_list);
1121         if (ret != 0) {
1122                 return ret;
1123         }
1124
1125         for (i=0; i<tun_var_list->count; i++) {
1126                 control_getvar(mem_ctx, ctdb, 1, &tun_var_list->var[i]);
1127         }
1128
1129         return 0;
1130 }
1131
1132 const struct {
1133         const char *name;
1134         uint32_t offset;
1135 } stats_fields[] = {
1136 #define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) }
1137         STATISTICS_FIELD(num_clients),
1138         STATISTICS_FIELD(frozen),
1139         STATISTICS_FIELD(recovering),
1140         STATISTICS_FIELD(num_recoveries),
1141         STATISTICS_FIELD(client_packets_sent),
1142         STATISTICS_FIELD(client_packets_recv),
1143         STATISTICS_FIELD(node_packets_sent),
1144         STATISTICS_FIELD(node_packets_recv),
1145         STATISTICS_FIELD(keepalive_packets_sent),
1146         STATISTICS_FIELD(keepalive_packets_recv),
1147         STATISTICS_FIELD(node.req_call),
1148         STATISTICS_FIELD(node.reply_call),
1149         STATISTICS_FIELD(node.req_dmaster),
1150         STATISTICS_FIELD(node.reply_dmaster),
1151         STATISTICS_FIELD(node.reply_error),
1152         STATISTICS_FIELD(node.req_message),
1153         STATISTICS_FIELD(node.req_control),
1154         STATISTICS_FIELD(node.reply_control),
1155         STATISTICS_FIELD(client.req_call),
1156         STATISTICS_FIELD(client.req_message),
1157         STATISTICS_FIELD(client.req_control),
1158         STATISTICS_FIELD(timeouts.call),
1159         STATISTICS_FIELD(timeouts.control),
1160         STATISTICS_FIELD(timeouts.traverse),
1161         STATISTICS_FIELD(locks.num_calls),
1162         STATISTICS_FIELD(locks.num_current),
1163         STATISTICS_FIELD(locks.num_pending),
1164         STATISTICS_FIELD(locks.num_failed),
1165         STATISTICS_FIELD(total_calls),
1166         STATISTICS_FIELD(pending_calls),
1167         STATISTICS_FIELD(childwrite_calls),
1168         STATISTICS_FIELD(pending_childwrite_calls),
1169         STATISTICS_FIELD(memory_used),
1170         STATISTICS_FIELD(max_hop_count),
1171         STATISTICS_FIELD(total_ro_delegations),
1172         STATISTICS_FIELD(total_ro_revokes),
1173 };
1174
1175 #define LATENCY_AVG(v)  ((v).num ? (v).total / (v).num : 0.0 )
1176
1177 static void print_statistics_machine(struct ctdb_statistics *s,
1178                                      bool show_header)
1179 {
1180         int i;
1181
1182         if (show_header) {
1183                 printf("CTDB version%s", options.sep);
1184                 printf("Current time of statistics%s", options.sep);
1185                 printf("Statistics collected since%s", options.sep);
1186                 for (i=0; i<ARRAY_SIZE(stats_fields); i++) {
1187                         printf("%s%s", stats_fields[i].name, options.sep);
1188                 }
1189                 printf("num_reclock_ctdbd_latency%s", options.sep);
1190                 printf("min_reclock_ctdbd_latency%s", options.sep);
1191                 printf("avg_reclock_ctdbd_latency%s", options.sep);
1192                 printf("max_reclock_ctdbd_latency%s", options.sep);
1193
1194                 printf("num_reclock_recd_latency%s", options.sep);
1195                 printf("min_reclock_recd_latency%s", options.sep);
1196                 printf("avg_reclock_recd_latency%s", options.sep);
1197                 printf("max_reclock_recd_latency%s", options.sep);
1198
1199                 printf("num_call_latency%s", options.sep);
1200                 printf("min_call_latency%s", options.sep);
1201                 printf("avg_call_latency%s", options.sep);
1202                 printf("max_call_latency%s", options.sep);
1203
1204                 printf("num_lockwait_latency%s", options.sep);
1205                 printf("min_lockwait_latency%s", options.sep);
1206                 printf("avg_lockwait_latency%s", options.sep);
1207                 printf("max_lockwait_latency%s", options.sep);
1208
1209                 printf("num_childwrite_latency%s", options.sep);
1210                 printf("min_childwrite_latency%s", options.sep);
1211                 printf("avg_childwrite_latency%s", options.sep);
1212                 printf("max_childwrite_latency%s", options.sep);
1213                 printf("\n");
1214         }
1215
1216         printf("%u%s", CTDB_PROTOCOL, options.sep);
1217         printf("%u%s", (uint32_t)s->statistics_current_time.tv_sec, options.sep);
1218         printf("%u%s", (uint32_t)s->statistics_start_time.tv_sec, options.sep);
1219         for (i=0;i<ARRAY_SIZE(stats_fields);i++) {
1220                 printf("%u%s",
1221                        *(uint32_t *)(stats_fields[i].offset+(uint8_t *)s),
1222                        options.sep);
1223         }
1224         printf("%u%s", s->reclock.ctdbd.num, options.sep);
1225         printf("%.6f%s", s->reclock.ctdbd.min, options.sep);
1226         printf("%.6f%s", LATENCY_AVG(s->reclock.ctdbd), options.sep);
1227         printf("%.6f%s", s->reclock.ctdbd.max, options.sep);
1228
1229         printf("%u%s", s->reclock.recd.num, options.sep);
1230         printf("%.6f%s", s->reclock.recd.min, options.sep);
1231         printf("%.6f%s", LATENCY_AVG(s->reclock.recd), options.sep);
1232         printf("%.6f%s", s->reclock.recd.max, options.sep);
1233
1234         printf("%d%s", s->call_latency.num, options.sep);
1235         printf("%.6f%s", s->call_latency.min, options.sep);
1236         printf("%.6f%s", LATENCY_AVG(s->call_latency), options.sep);
1237         printf("%.6f%s", s->call_latency.max, options.sep);
1238
1239         printf("%d%s", s->childwrite_latency.num, options.sep);
1240         printf("%.6f%s", s->childwrite_latency.min, options.sep);
1241         printf("%.6f%s", LATENCY_AVG(s->childwrite_latency), options.sep);
1242         printf("%.6f%s", s->childwrite_latency.max, options.sep);
1243         printf("\n");
1244 }
1245
1246 static void print_statistics(struct ctdb_statistics *s)
1247 {
1248         int tmp, days, hours, minutes, seconds;
1249         int i;
1250         const char *prefix = NULL;
1251         int preflen = 0;
1252
1253         tmp = s->statistics_current_time.tv_sec -
1254               s->statistics_start_time.tv_sec;
1255         seconds = tmp % 60; tmp /= 60;
1256         minutes = tmp % 60; tmp /= 60;
1257         hours   = tmp % 24; tmp /= 24;
1258         days    = tmp;
1259
1260         printf("CTDB version %u\n", CTDB_PROTOCOL);
1261         printf("Current time of statistics  :                %s",
1262                ctime(&s->statistics_current_time.tv_sec));
1263         printf("Statistics collected since  : (%03d %02d:%02d:%02d) %s",
1264                days, hours, minutes, seconds,
1265                ctime(&s->statistics_start_time.tv_sec));
1266
1267         for (i=0; i<ARRAY_SIZE(stats_fields); i++) {
1268                 if (strchr(stats_fields[i].name, '.') != NULL) {
1269                         preflen = strcspn(stats_fields[i].name, ".") + 1;
1270                         if (! prefix ||
1271                             strncmp(prefix, stats_fields[i].name, preflen) != 0) {
1272                                 prefix = stats_fields[i].name;
1273                                 printf(" %*.*s\n", preflen-1, preflen-1,
1274                                        stats_fields[i].name);
1275                         }
1276                 } else {
1277                         preflen = 0;
1278                 }
1279                 printf(" %*s%-22s%*s%10u\n", preflen ? 4 : 0, "",
1280                        stats_fields[i].name+preflen, preflen ? 0 : 4, "",
1281                        *(uint32_t *)(stats_fields[i].offset+(uint8_t *)s));
1282         }
1283
1284         printf(" hop_count_buckets:");
1285         for (i=0; i<MAX_COUNT_BUCKETS; i++) {
1286                 printf(" %d", s->hop_count_bucket[i]);
1287         }
1288         printf("\n");
1289         printf(" lock_buckets:");
1290         for (i=0; i<MAX_COUNT_BUCKETS; i++) {
1291                 printf(" %d", s->locks.buckets[i]);
1292         }
1293         printf("\n");
1294         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
1295                "locks_latency      MIN/AVG/MAX",
1296                s->locks.latency.min, LATENCY_AVG(s->locks.latency),
1297                s->locks.latency.max, s->locks.latency.num);
1298
1299         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
1300                "reclock_ctdbd      MIN/AVG/MAX",
1301                s->reclock.ctdbd.min, LATENCY_AVG(s->reclock.ctdbd),
1302                s->reclock.ctdbd.max, s->reclock.ctdbd.num);
1303
1304         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
1305                "reclock_recd       MIN/AVG/MAX",
1306                s->reclock.recd.min, LATENCY_AVG(s->reclock.recd),
1307                s->reclock.recd.max, s->reclock.recd.num);
1308
1309         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
1310                "call_latency       MIN/AVG/MAX",
1311                s->call_latency.min, LATENCY_AVG(s->call_latency),
1312                s->call_latency.max, s->call_latency.num);
1313
1314         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
1315                "childwrite_latency MIN/AVG/MAX",
1316                s->childwrite_latency.min,
1317                LATENCY_AVG(s->childwrite_latency),
1318                s->childwrite_latency.max, s->childwrite_latency.num);
1319 }
1320
1321 static int control_statistics(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1322                               int argc, const char **argv)
1323 {
1324         struct ctdb_statistics *stats;
1325         int ret;
1326
1327         if (argc != 0) {
1328                 usage("statistics");
1329         }
1330
1331         ret = ctdb_ctrl_statistics(mem_ctx, ctdb->ev, ctdb->client,
1332                                    ctdb->cmd_pnn, TIMEOUT(), &stats);
1333         if (ret != 0) {
1334                 return ret;
1335         }
1336
1337         if (options.machinereadable) {
1338                 print_statistics_machine(stats, true);
1339         } else {
1340                 print_statistics(stats);
1341         }
1342
1343         return 0;
1344 }
1345
1346 static int control_statistics_reset(TALLOC_CTX *mem_ctx,
1347                                     struct ctdb_context *ctdb,
1348                                     int argc, const char **argv)
1349 {
1350         int ret;
1351
1352         if (argc != 0) {
1353                 usage("statisticsreset");
1354         }
1355
1356         ret = ctdb_ctrl_statistics_reset(mem_ctx, ctdb->ev, ctdb->client,
1357                                          ctdb->cmd_pnn, TIMEOUT());
1358         if (ret != 0) {
1359                 return ret;
1360         }
1361
1362         return 0;
1363 }
1364
1365 static int control_stats(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1366                          int argc, const char **argv)
1367 {
1368         struct ctdb_statistics_list *slist;
1369         int ret, count = 0, i;
1370         bool show_header = true;
1371
1372         if (argc > 1) {
1373                 usage("stats");
1374         }
1375
1376         if (argc == 1) {
1377                 count = atoi(argv[0]);
1378         }
1379
1380         ret = ctdb_ctrl_get_stat_history(mem_ctx, ctdb->ev, ctdb->client,
1381                                          ctdb->cmd_pnn, TIMEOUT(), &slist);
1382         if (ret != 0) {
1383                 return ret;
1384         }
1385
1386         for (i=0; i<slist->num; i++) {
1387                 if (slist->stats[i].statistics_start_time.tv_sec == 0) {
1388                         continue;
1389                 }
1390                 if (options.machinereadable == 1) {
1391                         print_statistics_machine(&slist->stats[i],
1392                                                  show_header);
1393                         show_header = false;
1394                 } else {
1395                         print_statistics(&slist->stats[i]);
1396                 }
1397                 if (count > 0 && i == count) {
1398                         break;
1399                 }
1400         }
1401
1402         return 0;
1403 }
1404
1405 static int ctdb_public_ip_cmp(const void *a, const void *b)
1406 {
1407         const struct ctdb_public_ip *ip_a = a;
1408         const struct ctdb_public_ip *ip_b = b;
1409
1410         return ctdb_sock_addr_cmp(&ip_a->addr, &ip_b->addr);
1411 }
1412
1413 static void print_ip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1414                      struct ctdb_public_ip_list *ips,
1415                      struct ctdb_public_ip_info **ipinfo,
1416                      bool all_nodes)
1417 {
1418         int i, j;
1419         char *conf, *avail, *active;
1420
1421         if (options.machinereadable == 1) {
1422                 printf("%s%s%s%s%s", options.sep,
1423                        "Public IP", options.sep,
1424                        "Node", options.sep);
1425                 if (options.verbose == 1) {
1426                         printf("%s%s%s%s%s%s\n",
1427                                "ActiveInterfaces", options.sep,
1428                                "AvailableInterfaces", options.sep,
1429                                "ConfiguredInterfaces", options.sep);
1430                 } else {
1431                         printf("\n");
1432                 }
1433         } else {
1434                 if (all_nodes) {
1435                         printf("Public IPs on ALL nodes\n");
1436                 } else {
1437                         printf("Public IPs on node %u\n", ctdb->cmd_pnn);
1438                 }
1439         }
1440
1441         for (i = 0; i < ips->num; i++) {
1442
1443                 if (options.machinereadable == 1) {
1444                         printf("%s%s%s%d%s", options.sep,
1445                                ctdb_sock_addr_to_string(
1446                                         mem_ctx, &ips->ip[i].addr),
1447                                options.sep,
1448                                (int)ips->ip[i].pnn, options.sep);
1449                 } else {
1450                         printf("%s", ctdb_sock_addr_to_string(
1451                                                 mem_ctx, &ips->ip[i].addr));
1452                 }
1453
1454                 if (options.verbose == 0) {
1455                         if (options.machinereadable == 1) {
1456                                 printf("\n");
1457                         } else {
1458                                 printf(" %d\n", (int)ips->ip[i].pnn);
1459                         }
1460                         continue;
1461                 }
1462
1463                 conf = NULL;
1464                 avail = NULL;
1465                 active = NULL;
1466
1467                 if (ipinfo[i] == NULL) {
1468                         goto skip_ipinfo;
1469                 }
1470
1471                 for (j=0; j<ipinfo[i]->ifaces->num; j++) {
1472                         struct ctdb_iface *iface;
1473
1474                         iface = &ipinfo[i]->ifaces->iface[j];
1475                         if (conf == NULL) {
1476                                 conf = talloc_strdup(mem_ctx, iface->name);
1477                         } else {
1478                                 conf = talloc_asprintf_append(
1479                                                 conf, ",%s", iface->name);
1480                         }
1481
1482                         if (ipinfo[i]->active_idx == j) {
1483                                 active = iface->name;
1484                         }
1485
1486                         if (iface->link_state == 0) {
1487                                 continue;
1488                         }
1489
1490                         if (avail == NULL) {
1491                                 avail = talloc_strdup(mem_ctx, iface->name);
1492                         } else {
1493                                 avail = talloc_asprintf_append(
1494                                                 avail, ",%s", iface->name);
1495                         }
1496                 }
1497
1498         skip_ipinfo:
1499
1500                 if (options.machinereadable == 1) {
1501                         printf("%s%s%s%s%s%s\n",
1502                                active ? active : "", options.sep,
1503                                avail ? avail : "", options.sep,
1504                                conf ? conf : "", options.sep);
1505                 } else {
1506                         printf(" node[%d] active[%s] available[%s]"
1507                                " configured[%s]\n",
1508                                (int)ips->ip[i].pnn, active ? active : "",
1509                                avail ? avail : "", conf ? conf : "");
1510                 }
1511         }
1512 }
1513
1514 static int collect_ips(uint8_t *keybuf, size_t keylen, uint8_t *databuf,
1515                        size_t datalen, void *private_data)
1516 {
1517         struct ctdb_public_ip_list *ips = talloc_get_type_abort(
1518                 private_data, struct ctdb_public_ip_list);
1519         struct ctdb_public_ip *ip;
1520
1521         ip = (struct ctdb_public_ip *)databuf;
1522         ips->ip[ips->num] = *ip;
1523         ips->num += 1;
1524
1525         return 0;
1526 }
1527
1528 static int get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1529                               struct ctdb_public_ip_list **out)
1530 {
1531         struct ctdb_node_map *nodemap;
1532         struct ctdb_public_ip_list *ips;
1533         struct db_hash_context *ipdb;
1534         uint32_t *pnn_list;
1535         int ret, count, i, j;
1536
1537         nodemap = get_nodemap(ctdb, false);
1538         if (nodemap == NULL) {
1539                 return 1;
1540         }
1541
1542         ret = db_hash_init(mem_ctx, "ips", 101, DB_HASH_COMPLEX, &ipdb);
1543         if (ret != 0) {
1544                 goto failed;
1545         }
1546
1547         count = list_of_active_nodes(nodemap, CTDB_UNKNOWN_PNN, mem_ctx,
1548                                      &pnn_list);
1549         if (count <= 0) {
1550                 goto failed;
1551         }
1552
1553         for (i=0; i<count; i++) {
1554                 ret = ctdb_ctrl_get_public_ips(mem_ctx, ctdb->ev, ctdb->client,
1555                                                pnn_list[i], TIMEOUT(),
1556                                                false, &ips);
1557                 if (ret != 0) {
1558                         goto failed;
1559                 }
1560
1561                 for (j=0; j<ips->num; j++) {
1562                         struct ctdb_public_ip ip;
1563
1564                         ip.pnn = ips->ip[j].pnn;
1565                         ip.addr = ips->ip[j].addr;
1566
1567                         if (pnn_list[i] == ip.pnn) {
1568                                 /* Node claims IP is hosted on it, so
1569                                  * save that information
1570                                  */
1571                                 ret = db_hash_add(ipdb, (uint8_t *)&ip.addr,
1572                                                   sizeof(ip.addr),
1573                                                   (uint8_t *)&ip, sizeof(ip));
1574                                 if (ret != 0) {
1575                                         goto failed;
1576                                 }
1577                         } else {
1578                                 /* Node thinks IP is hosted elsewhere,
1579                                  * so overwrite with CTDB_UNKNOWN_PNN
1580                                  * if there's no existing entry
1581                                  */
1582                                 ret = db_hash_exists(ipdb, (uint8_t *)&ip.addr,
1583                                                      sizeof(ip.addr));
1584                                 if (ret == ENOENT) {
1585                                         ip.pnn = CTDB_UNKNOWN_PNN;
1586                                         ret = db_hash_add(ipdb,
1587                                                           (uint8_t *)&ip.addr,
1588                                                           sizeof(ip.addr),
1589                                                           (uint8_t *)&ip,
1590                                                           sizeof(ip));
1591                                         if (ret != 0) {
1592                                                 goto failed;
1593                                         }
1594                                 }
1595                         }
1596                 }
1597
1598                 TALLOC_FREE(ips);
1599         }
1600
1601         talloc_free(pnn_list);
1602
1603         ret = db_hash_traverse(ipdb, NULL, NULL, &count);
1604         if (ret != 0) {
1605                 goto failed;
1606         }
1607
1608         ips = talloc_zero(mem_ctx, struct ctdb_public_ip_list);
1609         if (ips == NULL) {
1610                 goto failed;
1611         }
1612
1613         ips->ip = talloc_array(ips, struct ctdb_public_ip, count);
1614         if (ips->ip == NULL) {
1615                 goto failed;
1616         }
1617
1618         ret = db_hash_traverse(ipdb, collect_ips, ips, &count);
1619         if (ret != 0) {
1620                 goto failed;
1621         }
1622
1623         if (count != ips->num) {
1624                 goto failed;
1625         }
1626
1627         talloc_free(ipdb);
1628
1629         *out = ips;
1630         return 0;
1631
1632 failed:
1633         talloc_free(ipdb);
1634         return 1;
1635 }
1636
1637 static int control_ip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1638                       int argc, const char **argv)
1639 {
1640         struct ctdb_public_ip_list *ips;
1641         struct ctdb_public_ip_info **ipinfo;
1642         int ret, i;
1643         bool do_all = false;
1644
1645         if (argc > 1) {
1646                 usage("ip");
1647         }
1648
1649         if (argc == 1) {
1650                 if (strcmp(argv[0], "all") == 0) {
1651                         do_all = true;
1652                 } else {
1653                         usage("ip");
1654                 }
1655         }
1656
1657         if (do_all) {
1658                 ret = get_all_public_ips(ctdb, mem_ctx, &ips);
1659         } else {
1660                 ret = ctdb_ctrl_get_public_ips(mem_ctx, ctdb->ev, ctdb->client,
1661                                                ctdb->cmd_pnn, TIMEOUT(),
1662                                                false, &ips);
1663         }
1664         if (ret != 0) {
1665                 return ret;
1666         }
1667
1668         qsort(ips->ip, ips->num, sizeof(struct ctdb_public_ip),
1669               ctdb_public_ip_cmp);
1670
1671         ipinfo = talloc_array(mem_ctx, struct ctdb_public_ip_info *, ips->num);
1672         if (ipinfo == NULL) {
1673                 return 1;
1674         }
1675
1676         for (i=0; i<ips->num; i++) {
1677                 uint32_t pnn;
1678                 if (do_all) {
1679                         pnn = ips->ip[i].pnn;
1680                 } else {
1681                         pnn = ctdb->cmd_pnn;
1682                 }
1683                 if (pnn == CTDB_UNKNOWN_PNN) {
1684                         ipinfo[i] = NULL;
1685                         continue;
1686                 }
1687                 ret = ctdb_ctrl_get_public_ip_info(mem_ctx, ctdb->ev,
1688                                                    ctdb->client, pnn,
1689                                                    TIMEOUT(), &ips->ip[i].addr,
1690                                                    &ipinfo[i]);
1691                 if (ret != 0) {
1692                         return ret;
1693                 }
1694         }
1695
1696         print_ip(mem_ctx, ctdb, ips, ipinfo, do_all);
1697         return 0;
1698 }
1699
1700 static int control_ipinfo(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1701                           int argc, const char **argv)
1702 {
1703         struct ctdb_public_ip_info *ipinfo;
1704         ctdb_sock_addr addr;
1705         int ret, i;
1706
1707         if (argc != 1) {
1708                 usage("ipinfo");
1709         }
1710
1711         if (! parse_ip(argv[0], NULL, 0, &addr)) {
1712                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
1713                 return 1;
1714         }
1715
1716         ret = ctdb_ctrl_get_public_ip_info(mem_ctx, ctdb->ev, ctdb->client,
1717                                            ctdb->cmd_pnn, TIMEOUT(), &addr,
1718                                            &ipinfo);
1719         if (ret != 0) {
1720                 if (ret == -1) {
1721                         printf("Node %u does not know about IP %s\n",
1722                                ctdb->cmd_pnn, argv[0]);
1723                 }
1724                 return ret;
1725         }
1726
1727         printf("Public IP[%s] info on node %u\n",
1728                ctdb_sock_addr_to_string(mem_ctx, &ipinfo->ip.addr),
1729                                         ctdb->cmd_pnn);
1730
1731         printf("IP:%s\nCurrentNode:%u\nNumInterfaces:%u\n",
1732                ctdb_sock_addr_to_string(mem_ctx, &ipinfo->ip.addr),
1733                ipinfo->ip.pnn, ipinfo->ifaces->num);
1734
1735         for (i=0; i<ipinfo->ifaces->num; i++) {
1736                 struct ctdb_iface *iface;
1737
1738                 iface = &ipinfo->ifaces->iface[i];
1739                 iface->name[CTDB_IFACE_SIZE] = '\0';
1740                 printf("Interface[%u]: Name:%s Link:%s References:%u%s\n",
1741                        i+1, iface->name,
1742                        iface->link_state == 0 ? "down" : "up",
1743                        iface->references,
1744                        (i == ipinfo->active_idx) ? " (active)" : "");
1745         }
1746
1747         return 0;
1748 }
1749
1750 static int control_ifaces(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1751                           int argc, const char **argv)
1752 {
1753         struct ctdb_iface_list *ifaces;
1754         int ret, i;
1755
1756         if (argc != 0) {
1757                 usage("ifaces");
1758         }
1759
1760         ret = ctdb_ctrl_get_ifaces(mem_ctx, ctdb->ev, ctdb->client,
1761                                    ctdb->cmd_pnn, TIMEOUT(), &ifaces);
1762         if (ret != 0) {
1763                 return ret;
1764         }
1765
1766         if (ifaces->num == 0) {
1767                 printf("No interfaces configured on node %u\n",
1768                        ctdb->cmd_pnn);
1769                 return 0;
1770         }
1771
1772         if (options.machinereadable) {
1773                 printf("%s%s%s%s%s%s%s\n", options.sep,
1774                        "Name", options.sep,
1775                        "LinkStatus", options.sep,
1776                        "References", options.sep);
1777         } else {
1778                 printf("Interfaces on node %u\n", ctdb->cmd_pnn);
1779         }
1780
1781         for (i=0; i<ifaces->num; i++) {
1782                 if (options.machinereadable) {
1783                         printf("%s%s%s%u%s%u%s\n", options.sep,
1784                                ifaces->iface[i].name, options.sep,
1785                                ifaces->iface[i].link_state, options.sep,
1786                                ifaces->iface[i].references, options.sep);
1787                 } else {
1788                         printf("name:%s link:%s references:%u\n",
1789                                ifaces->iface[i].name,
1790                                ifaces->iface[i].link_state ? "up" : "down",
1791                                ifaces->iface[i].references);
1792                 }
1793         }
1794
1795         return 0;
1796 }
1797
1798 static int control_setifacelink(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1799                                 int argc, const char **argv)
1800 {
1801         struct ctdb_iface_list *ifaces;
1802         struct ctdb_iface *iface;
1803         int ret, i;
1804
1805         if (argc != 2) {
1806                 usage("setifacelink");
1807         }
1808
1809         if (strlen(argv[0]) > CTDB_IFACE_SIZE) {
1810                 fprintf(stderr, "Interface name '%s' too long\n", argv[0]);
1811                 return 1;
1812         }
1813
1814         ret = ctdb_ctrl_get_ifaces(mem_ctx, ctdb->ev, ctdb->client,
1815                                    ctdb->cmd_pnn, TIMEOUT(), &ifaces);
1816         if (ret != 0) {
1817                 fprintf(stderr,
1818                         "Failed to get interface information from node %u\n",
1819                         ctdb->cmd_pnn);
1820                 return ret;
1821         }
1822
1823         iface = NULL;
1824         for (i=0; i<ifaces->num; i++) {
1825                 if (strcmp(ifaces->iface[i].name, argv[0]) == 0) {
1826                         iface = &ifaces->iface[i];
1827                         break;
1828                 }
1829         }
1830
1831         if (iface == NULL) {
1832                 printf("Interface %s not configured on node %u\n",
1833                        argv[0], ctdb->cmd_pnn);
1834                 return 1;
1835         }
1836
1837         if (strcmp(argv[1], "up") == 0) {
1838                 iface->link_state = 1;
1839         } else if (strcmp(argv[1], "down") == 0) {
1840                 iface->link_state = 0;
1841         } else {
1842                 usage("setifacelink");
1843                 return 1;
1844         }
1845
1846         iface->references = 0;
1847
1848         ret = ctdb_ctrl_set_iface_link_state(mem_ctx, ctdb->ev, ctdb->client,
1849                                              ctdb->cmd_pnn, TIMEOUT(), iface);
1850         if (ret != 0) {
1851                 return ret;
1852         }
1853
1854         return 0;
1855 }
1856
1857 static int control_process_exists(TALLOC_CTX *mem_ctx,
1858                                   struct ctdb_context *ctdb,
1859                                   int argc, const char **argv)
1860 {
1861         pid_t pid;
1862         int ret, status;
1863
1864         if (argc != 1) {
1865                 usage("process-exists");
1866         }
1867
1868         pid = atoi(argv[0]);
1869         ret = ctdb_ctrl_process_exists(mem_ctx, ctdb->ev, ctdb->client,
1870                                        ctdb->cmd_pnn, TIMEOUT(), pid, &status);
1871         if (ret != 0) {
1872                 return ret;
1873         }
1874
1875         if (status == 0) {
1876                 printf("PID %u exists\n", pid);
1877         } else {
1878                 printf("PID %u does not exist\n", pid);
1879         }
1880         return status;
1881 }
1882
1883 static int control_getdbmap(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1884                             int argc, const char **argv)
1885 {
1886         struct ctdb_dbid_map *dbmap;
1887         int ret, i;
1888
1889         if (argc != 0) {
1890                 usage("getdbmap");
1891         }
1892
1893         ret = ctdb_ctrl_get_dbmap(mem_ctx, ctdb->ev, ctdb->client,
1894                                   ctdb->cmd_pnn, TIMEOUT(), &dbmap);
1895         if (ret != 0) {
1896                 return ret;
1897         }
1898
1899         if (options.machinereadable == 1) {
1900                 printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1901                        options.sep,
1902                        "ID", options.sep,
1903                        "Name", options.sep,
1904                        "Path", options.sep,
1905                        "Persistent", options.sep,
1906                        "Sticky", options.sep,
1907                        "Unhealthy", options.sep,
1908                        "Readonly", options.sep);
1909         } else {
1910                 printf("Number of databases:%d\n", dbmap->num);
1911         }
1912
1913         for (i=0; i<dbmap->num; i++) {
1914                 const char *name;
1915                 const char *path;
1916                 const char *health;
1917                 bool persistent;
1918                 bool readonly;
1919                 bool sticky;
1920                 uint32_t db_id;
1921
1922                 db_id = dbmap->dbs[i].db_id;
1923
1924                 ret = ctdb_ctrl_get_dbname(mem_ctx, ctdb->ev, ctdb->client,
1925                                            ctdb->cmd_pnn, TIMEOUT(), db_id,
1926                                            &name);
1927                 if (ret != 0) {
1928                         return ret;
1929                 }
1930
1931                 ret = ctdb_ctrl_getdbpath(mem_ctx, ctdb->ev, ctdb->client,
1932                                           ctdb->cmd_pnn, TIMEOUT(), db_id,
1933                                           &path);
1934                 if (ret != 0) {
1935                         return ret;
1936                 }
1937
1938                 ret = ctdb_ctrl_db_get_health(mem_ctx, ctdb->ev, ctdb->client,
1939                                               ctdb->cmd_pnn, TIMEOUT(), db_id,
1940                                               &health);
1941                 if (ret != 0) {
1942                         return ret;
1943                 }
1944
1945                 persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
1946                 readonly = dbmap->dbs[i].flags & CTDB_DB_FLAGS_READONLY;
1947                 sticky = dbmap->dbs[i].flags & CTDB_DB_FLAGS_STICKY;
1948
1949                 if (options.machinereadable == 1) {
1950                         printf("%s0x%08X%s%s%s%s%s%d%s%d%s%d%s%d%s\n",
1951                                options.sep,
1952                                db_id, options.sep,
1953                                name, options.sep,
1954                                path, options.sep,
1955                                !! (persistent), options.sep,
1956                                !! (sticky), options.sep,
1957                                !! (health), options.sep,
1958                                !! (readonly), options.sep);
1959                 } else {
1960                         printf("dbid:0x%08x name:%s path:%s%s%s%s%s\n",
1961                                db_id, name, path,
1962                                persistent ? " PERSISTENT" : "",
1963                                sticky ? " STICKY" : "",
1964                                readonly ? " READONLY" : "",
1965                                health ? " UNHEALTHY" : "");
1966                 }
1967
1968                 talloc_free(discard_const(name));
1969                 talloc_free(discard_const(path));
1970                 talloc_free(discard_const(health));
1971         }
1972
1973         return 0;
1974 }
1975
1976 static int control_getdbstatus(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
1977                                int argc, const char **argv)
1978 {
1979         uint32_t db_id;
1980         const char *db_name, *db_path, *db_health;
1981         uint8_t db_flags;
1982         int ret;
1983
1984         if (argc != 1) {
1985                 usage("getdbstatus");
1986         }
1987
1988         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, &db_flags)) {
1989                 return 1;
1990         }
1991
1992         ret = ctdb_ctrl_getdbpath(mem_ctx, ctdb->ev, ctdb->client,
1993                                   ctdb->cmd_pnn, TIMEOUT(), db_id,
1994                                   &db_path);
1995         if (ret != 0) {
1996                 return ret;
1997         }
1998
1999         ret = ctdb_ctrl_db_get_health(mem_ctx, ctdb->ev, ctdb->client,
2000                                       ctdb->cmd_pnn, TIMEOUT(), db_id,
2001                                       &db_health);
2002         if (ret != 0) {
2003                 return ret;
2004         }
2005
2006         printf("dbid: 0x%08x\nname: %s\npath: %s\n", db_id, db_name, db_path);
2007         printf("PERSISTENT: %s\nSTICKY: %s\nREADONLY: %s\nHEALTH: %s\n",
2008                (db_flags & CTDB_DB_FLAGS_PERSISTENT ? "yes" : "no"),
2009                (db_flags & CTDB_DB_FLAGS_STICKY ? "yes" : "no"),
2010                (db_flags & CTDB_DB_FLAGS_READONLY ? "yes" : "no"),
2011                (db_health ? db_health : "OK"));
2012         return 0;
2013 }
2014
2015 struct dump_record_state {
2016         uint32_t count;
2017 };
2018
2019 #define ISASCII(x) (isprint(x) && ! strchr("\"\\", (x)))
2020
2021 static void dump_tdb_data(const char *name, TDB_DATA val)
2022 {
2023         int i;
2024
2025         fprintf(stdout, "%s(%zu) = \"", name, val.dsize);
2026         for (i=0; i<val.dsize; i++) {
2027                 if (ISASCII(val.dptr[i])) {
2028                         fprintf(stdout, "%c", val.dptr[i]);
2029                 } else {
2030                         fprintf(stdout, "\\%02X", val.dptr[i]);
2031                 }
2032         }
2033         fprintf(stdout, "\"\n");
2034 }
2035
2036 static void dump_ltdb_header(struct ctdb_ltdb_header *header)
2037 {
2038         fprintf(stdout, "dmaster: %u\n", header->dmaster);
2039         fprintf(stdout, "rsn: %" PRIu64 "\n", header->rsn);
2040         fprintf(stdout, "flags: 0x%08x", header->flags);
2041         if (header->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) {
2042                 fprintf(stdout, " MIGRATED_WITH_DATA");
2043         }
2044         if (header->flags & CTDB_REC_FLAG_VACUUM_MIGRATED) {
2045                 fprintf(stdout, " VACUUM_MIGRATED");
2046         }
2047         if (header->flags & CTDB_REC_FLAG_AUTOMATIC) {
2048                 fprintf(stdout, " AUTOMATIC");
2049         }
2050         if (header->flags & CTDB_REC_RO_HAVE_DELEGATIONS) {
2051                 fprintf(stdout, " RO_HAVE_DELEGATIONS");
2052         }
2053         if (header->flags & CTDB_REC_RO_HAVE_READONLY) {
2054                 fprintf(stdout, " RO_HAVE_READONLY");
2055         }
2056         if (header->flags & CTDB_REC_RO_REVOKING_READONLY) {
2057                 fprintf(stdout, " RO_REVOKING_READONLY");
2058         }
2059         if (header->flags & CTDB_REC_RO_REVOKE_COMPLETE) {
2060                 fprintf(stdout, " RO_REVOKE_COMPLETE");
2061         }
2062         fprintf(stdout, "\n");
2063
2064 }
2065
2066 static int dump_record(uint32_t reqid, struct ctdb_ltdb_header *header,
2067                        TDB_DATA key, TDB_DATA data, void *private_data)
2068 {
2069         struct dump_record_state *state =
2070                 (struct dump_record_state *)private_data;
2071
2072         state->count += 1;
2073
2074         dump_tdb_data("key", key);
2075         dump_ltdb_header(header);
2076         dump_tdb_data("data", data);
2077         fprintf(stdout, "\n");
2078
2079         return 0;
2080 }
2081
2082 struct traverse_state {
2083         TALLOC_CTX *mem_ctx;
2084         bool done;
2085         ctdb_rec_parser_func_t func;
2086         struct dump_record_state sub_state;
2087 };
2088
2089 static void traverse_handler(uint64_t srvid, TDB_DATA data, void *private_data)
2090 {
2091         struct traverse_state *state = (struct traverse_state *)private_data;
2092         struct ctdb_rec_data *rec;
2093         struct ctdb_ltdb_header header;
2094         int ret;
2095
2096         ret = ctdb_rec_data_pull(data.dptr, data.dsize, state->mem_ctx, &rec);
2097         if (ret != 0) {
2098                 return;
2099         }
2100
2101         if (rec->key.dsize == 0 && rec->data.dsize == 0) {
2102                 talloc_free(rec);
2103                 /* end of traverse */
2104                 state->done = true;
2105                 return;
2106         }
2107
2108         ret = ctdb_ltdb_header_extract(&rec->data, &header);
2109         if (ret != 0) {
2110                 talloc_free(rec);
2111                 return;
2112         }
2113
2114         if (rec->data.dsize == 0) {
2115                 talloc_free(rec);
2116                 return;
2117         }
2118
2119         ret = state->func(rec->reqid, &header, rec->key, rec->data,
2120                           &state->sub_state);
2121         talloc_free(rec);
2122         if (ret != 0) {
2123                 state->done = true;
2124         }
2125 }
2126
2127 static int control_catdb(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2128                          int argc, const char **argv)
2129 {
2130         struct ctdb_db_context *db;
2131         const char *db_name;
2132         uint32_t db_id;
2133         uint8_t db_flags;
2134         struct ctdb_traverse_start_ext traverse;
2135         struct traverse_state state;
2136         int ret;
2137
2138         if (argc != 1) {
2139                 usage("catdb");
2140         }
2141
2142         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, &db_flags)) {
2143                 return 1;
2144         }
2145
2146         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
2147                           db_flags, &db);
2148         if (ret != 0) {
2149                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
2150                 return ret;
2151         }
2152
2153         /* Valgrind fix */
2154         ZERO_STRUCT(traverse);
2155
2156         traverse.db_id = db_id;
2157         traverse.reqid = 0;
2158         traverse.srvid = next_srvid(ctdb);
2159         traverse.withemptyrecords = false;
2160
2161         state.mem_ctx = mem_ctx;
2162         state.done = false;
2163         state.func = dump_record;
2164         state.sub_state.count = 0;
2165
2166         ret = ctdb_client_set_message_handler(ctdb->ev, ctdb->client,
2167                                               traverse.srvid,
2168                                               traverse_handler, &state);
2169         if (ret != 0) {
2170                 return ret;
2171         }
2172
2173         ret = ctdb_ctrl_traverse_start_ext(mem_ctx, ctdb->ev, ctdb->client,
2174                                            ctdb->cmd_pnn, TIMEOUT(),
2175                                            &traverse);
2176         if (ret != 0) {
2177                 return ret;
2178         }
2179
2180         ctdb_client_wait(ctdb->ev, &state.done);
2181
2182         printf("Dumped %u records\n", state.sub_state.count);
2183
2184         ret = ctdb_client_remove_message_handler(ctdb->ev, ctdb->client,
2185                                                  traverse.srvid, &state);
2186         if (ret != 0) {
2187                 return ret;
2188         }
2189
2190         return 0;
2191 }
2192
2193 static int control_cattdb(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2194                           int argc, const char **argv)
2195 {
2196         struct ctdb_db_context *db;
2197         const char *db_name;
2198         uint32_t db_id;
2199         uint8_t db_flags;
2200         struct dump_record_state state;
2201         int ret;
2202
2203         if (argc != 1) {
2204                 usage("catdb");
2205         }
2206
2207         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, &db_flags)) {
2208                 return 1;
2209         }
2210
2211         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
2212                           db_flags, &db);
2213         if (ret != 0) {
2214                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
2215                 return ret;
2216         }
2217
2218         state.count = 0;
2219         ret = ctdb_db_traverse(db, true, true, dump_record, &state);
2220
2221         printf("Dumped %u record(s)\n", state.count);
2222
2223         return ret;
2224 }
2225
2226 static int control_getmonmode(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2227                               int argc, const char **argv)
2228 {
2229         int mode, ret;
2230
2231         if (argc != 0) {
2232                 usage("getmonmode");
2233         }
2234
2235         ret = ctdb_ctrl_get_monmode(mem_ctx, ctdb->ev, ctdb->client,
2236                                     ctdb->cmd_pnn, TIMEOUT(), &mode);
2237         if (ret != 0) {
2238                 return ret;
2239         }
2240
2241         printf("%s\n",
2242                (mode == CTDB_MONITORING_ENABLED) ? "ENABLED" : "DISABLED");
2243         return 0;
2244 }
2245
2246 static int control_getcapabilities(TALLOC_CTX *mem_ctx,
2247                                    struct ctdb_context *ctdb,
2248                                    int argc, const char **argv)
2249 {
2250         uint32_t caps;
2251         int ret;
2252
2253         if (argc != 0) {
2254                 usage("getcapabilities");
2255         }
2256
2257         ret = ctdb_ctrl_get_capabilities(mem_ctx, ctdb->ev, ctdb->client,
2258                                          ctdb->cmd_pnn, TIMEOUT(), &caps);
2259         if (ret != 0) {
2260                 return ret;
2261         }
2262
2263         if (options.machinereadable == 1) {
2264                 printf("%s%s%s%s%s\n",
2265                        options.sep,
2266                        "RECMASTER", options.sep,
2267                        "LMASTER", options.sep);
2268                 printf("%s%d%s%d%s\n", options.sep,
2269                        !! (caps & CTDB_CAP_RECMASTER), options.sep,
2270                        !! (caps & CTDB_CAP_LMASTER), options.sep);
2271         } else {
2272                 printf("RECMASTER: %s\n",
2273                        (caps & CTDB_CAP_RECMASTER) ? "YES" : "NO");
2274                 printf("LMASTER: %s\n",
2275                        (caps & CTDB_CAP_LMASTER) ? "YES" : "NO");
2276         }
2277
2278         return 0;
2279 }
2280
2281 static int control_pnn(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2282                        int argc, const char **argv)
2283 {
2284         printf("%u\n", ctdb_client_pnn(ctdb->client));
2285         return 0;
2286 }
2287
2288 static int control_lvs(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2289                        int argc, const char **argv)
2290 {
2291         char *t, *lvs_helper = NULL;
2292
2293         if (argc != 1) {
2294                 usage("lvs");
2295         }
2296
2297         t = getenv("CTDB_LVS_HELPER");
2298         if (t != NULL) {
2299                 lvs_helper = talloc_strdup(mem_ctx, t);
2300         } else {
2301                 lvs_helper = talloc_asprintf(mem_ctx, "%s/ctdb_lvs",
2302                                              CTDB_HELPER_BINDIR);
2303         }
2304
2305         if (lvs_helper == NULL) {
2306                 fprintf(stderr, "Unable to set LVS helper\n");
2307                 return 1;
2308         }
2309
2310         return run_helper(mem_ctx, "LVS helper", lvs_helper, argc, argv);
2311 }
2312
2313 static int control_disable_monitor(TALLOC_CTX *mem_ctx,
2314                                    struct ctdb_context *ctdb,
2315                                    int argc, const char **argv)
2316 {
2317         int ret;
2318
2319         if (argc != 0) {
2320                 usage("disablemonitor");
2321         }
2322
2323         ret = ctdb_ctrl_disable_monitor(mem_ctx, ctdb->ev, ctdb->client,
2324                                         ctdb->cmd_pnn, TIMEOUT());
2325         if (ret != 0) {
2326                 return ret;
2327         }
2328
2329         return 0;
2330 }
2331
2332 static int control_enable_monitor(TALLOC_CTX *mem_ctx,
2333                                   struct ctdb_context *ctdb,
2334                                   int argc, const char **argv)
2335 {
2336         int ret;
2337
2338         if (argc != 0) {
2339                 usage("enablemonitor");
2340         }
2341
2342         ret = ctdb_ctrl_enable_monitor(mem_ctx, ctdb->ev, ctdb->client,
2343                                        ctdb->cmd_pnn, TIMEOUT());
2344         if (ret != 0) {
2345                 return ret;
2346         }
2347
2348         return 0;
2349 }
2350
2351 static int control_setdebug(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2352                             int argc, const char **argv)
2353 {
2354         int log_level;
2355         int ret;
2356         bool found;
2357
2358         if (argc != 1) {
2359                 usage("setdebug");
2360         }
2361
2362         found = debug_level_parse(argv[0], &log_level);
2363         if (! found) {
2364                 fprintf(stderr,
2365                         "Invalid debug level '%s'. Valid levels are:\n",
2366                         argv[0]);
2367                 fprintf(stderr, "\tERROR | WARNING | NOTICE | INFO | DEBUG\n");
2368                 return 1;
2369         }
2370
2371         ret = ctdb_ctrl_setdebug(mem_ctx, ctdb->ev, ctdb->client,
2372                                  ctdb->cmd_pnn, TIMEOUT(), log_level);
2373         if (ret != 0) {
2374                 return ret;
2375         }
2376
2377         return 0;
2378 }
2379
2380 static int control_getdebug(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2381                             int argc, const char **argv)
2382 {
2383         int loglevel;
2384         const char *log_str;
2385         int ret;
2386
2387         if (argc != 0) {
2388                 usage("getdebug");
2389         }
2390
2391         ret = ctdb_ctrl_getdebug(mem_ctx, ctdb->ev, ctdb->client,
2392                                  ctdb->cmd_pnn, TIMEOUT(), &loglevel);
2393         if (ret != 0) {
2394                 return ret;
2395         }
2396
2397         log_str = debug_level_to_string(loglevel);
2398         printf("%s\n", log_str);
2399
2400         return 0;
2401 }
2402
2403 static int control_attach(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2404                           int argc, const char **argv)
2405 {
2406         const char *db_name;
2407         uint8_t db_flags = 0;
2408         int ret;
2409
2410         if (argc < 1 || argc > 2) {
2411                 usage("attach");
2412         }
2413
2414         db_name = argv[0];
2415         if (argc == 2) {
2416                 if (strcmp(argv[1], "persistent") == 0) {
2417                         db_flags = CTDB_DB_FLAGS_PERSISTENT;
2418                 } else if (strcmp(argv[1], "readonly") == 0) {
2419                         db_flags = CTDB_DB_FLAGS_READONLY;
2420                 } else if (strcmp(argv[1], "sticky") == 0) {
2421                         db_flags = CTDB_DB_FLAGS_STICKY;
2422                 } else {
2423                         usage("attach");
2424                 }
2425         }
2426
2427         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
2428                           db_flags, NULL);
2429         if (ret != 0) {
2430                 return ret;
2431         }
2432
2433         return 0;
2434 }
2435
2436 static int control_detach(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2437                           int argc, const char **argv)
2438 {
2439         const char *db_name;
2440         uint32_t db_id;
2441         uint8_t db_flags;
2442         struct ctdb_node_map *nodemap;
2443         int recmode;
2444         int ret, ret2, i;
2445
2446         if (argc < 1) {
2447                 usage("detach");
2448         }
2449
2450         ret = ctdb_ctrl_get_recmode(mem_ctx, ctdb->ev, ctdb->client,
2451                                     ctdb->cmd_pnn, TIMEOUT(), &recmode);
2452         if (ret != 0) {
2453                 return ret;
2454         }
2455
2456         if (recmode == CTDB_RECOVERY_ACTIVE) {
2457                 fprintf(stderr, "Database cannot be detached"
2458                                 " when recovery is active\n");
2459                 return 1;
2460         }
2461
2462         nodemap = get_nodemap(ctdb, false);
2463         if (nodemap == NULL) {
2464                 return 1;
2465         }
2466
2467         for (i=0; i<nodemap->num; i++) {
2468                 uint32_t value;
2469
2470                 if (nodemap->node[i].flags & NODE_FLAGS_DISCONNECTED) {
2471                         continue;
2472                 }
2473                 if (nodemap->node[i].flags & NODE_FLAGS_DELETED) {
2474                         continue;
2475                 }
2476                 if (nodemap->node[i].flags & NODE_FLAGS_INACTIVE) {
2477                         fprintf(stderr, "Database cannot be detached on"
2478                                 " inactive (stopped or banned) node %u\n",
2479                                 nodemap->node[i].pnn);
2480                         return 1;
2481                 }
2482
2483                 ret = ctdb_ctrl_get_tunable(mem_ctx, ctdb->ev, ctdb->client,
2484                                             nodemap->node[i].pnn, TIMEOUT(),
2485                                             "AllowClientDBAttach", &value);
2486                 if (ret != 0) {
2487                         fprintf(stderr,
2488                                 "Unable to get tunable AllowClientDBAttach"
2489                                 " from node %u\n", nodemap->node[i].pnn);
2490                         return ret;
2491                 }
2492
2493                 if (value == 1) {
2494                         fprintf(stderr,
2495                                 "Database access is still active on node %u."
2496                                 " Set AllowclientDBAttach=0 on all nodes.\n",
2497                                 nodemap->node[i].pnn);
2498                         return 1;
2499                 }
2500         }
2501
2502         ret2 = 0;
2503         for (i=0; i<argc; i++) {
2504                 if (! db_exists(mem_ctx, ctdb, argv[i], &db_id, &db_name,
2505                                 &db_flags)) {
2506                         continue;
2507                 }
2508
2509                 if (db_flags & CTDB_DB_FLAGS_PERSISTENT) {
2510                         fprintf(stderr,
2511                                 "Persistent database %s cannot be detached\n",
2512                                 argv[0]);
2513                         return 1;
2514                 }
2515
2516                 ret = ctdb_detach(mem_ctx, ctdb->ev, ctdb->client,
2517                                   TIMEOUT(), db_id);
2518                 if (ret != 0) {
2519                         fprintf(stderr, "Database %s detach failed\n", db_name);
2520                         ret2 = ret;
2521                 }
2522         }
2523
2524         return ret2;
2525 }
2526
2527 static int control_dumpmemory(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2528                               int argc, const char **argv)
2529 {
2530         const char *mem_str;
2531         ssize_t n;
2532         int ret;
2533
2534         ret = ctdb_ctrl_dump_memory(mem_ctx, ctdb->ev, ctdb->client,
2535                                     ctdb->cmd_pnn, TIMEOUT(), &mem_str);
2536         if (ret != 0) {
2537                 return ret;
2538         }
2539
2540         n = write(1, mem_str, strlen(mem_str)+1);
2541         if (n < 0 || n != strlen(mem_str)+1) {
2542                 fprintf(stderr, "Failed to write talloc summary\n");
2543                 return 1;
2544         }
2545
2546         return 0;
2547 }
2548
2549 static void dump_memory(uint64_t srvid, TDB_DATA data, void *private_data)
2550 {
2551         bool *done = (bool *)private_data;
2552         ssize_t n;
2553
2554         n = write(1, data.dptr, data.dsize);
2555         if (n < 0 || n != data.dsize) {
2556                 fprintf(stderr, "Failed to write talloc summary\n");
2557         }
2558
2559         *done = true;
2560 }
2561
2562 static int control_rddumpmemory(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2563                                 int argc, const char **argv)
2564 {
2565         struct ctdb_srvid_message msg = { 0 };
2566         int ret;
2567         bool done = false;
2568
2569         msg.pnn = ctdb->pnn;
2570         msg.srvid = next_srvid(ctdb);
2571
2572         ret = ctdb_client_set_message_handler(ctdb->ev, ctdb->client,
2573                                               msg.srvid, dump_memory, &done);
2574         if (ret != 0) {
2575                 return ret;
2576         }
2577
2578         ret = ctdb_message_mem_dump(mem_ctx, ctdb->ev, ctdb->client,
2579                                     ctdb->cmd_pnn, &msg);
2580         if (ret != 0) {
2581                 return ret;
2582         }
2583
2584         ctdb_client_wait(ctdb->ev, &done);
2585         return 0;
2586 }
2587
2588 static int control_getpid(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2589                           int argc, const char **argv)
2590 {
2591         pid_t pid;
2592         int ret;
2593
2594         ret = ctdb_ctrl_get_pid(mem_ctx, ctdb->ev, ctdb->client,
2595                                 ctdb->cmd_pnn, TIMEOUT(), &pid);
2596         if (ret != 0) {
2597                 return ret;
2598         }
2599
2600         printf("%u\n", pid);
2601         return 0;
2602 }
2603
2604 static int check_flags(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2605                        const char *desc, uint32_t flag, bool set_flag)
2606 {
2607         struct ctdb_node_map *nodemap;
2608         bool flag_is_set;
2609
2610         nodemap = get_nodemap(ctdb, false);
2611         if (nodemap == NULL) {
2612                 return 1;
2613         }
2614
2615         flag_is_set = nodemap->node[ctdb->cmd_pnn].flags & flag;
2616         if (set_flag == flag_is_set) {
2617                 if (set_flag) {
2618                         fprintf(stderr, "Node %u is already %s\n",
2619                                 ctdb->cmd_pnn, desc);
2620                 } else {
2621                         fprintf(stderr, "Node %u is not %s\n",
2622                                 ctdb->cmd_pnn, desc);
2623                 }
2624                 return 0;
2625         }
2626
2627         return 1;
2628 }
2629
2630 static void wait_for_flags(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2631                            uint32_t flag, bool set_flag)
2632 {
2633         struct ctdb_node_map *nodemap;
2634         bool flag_is_set;
2635
2636         while (1) {
2637                 nodemap = get_nodemap(ctdb, true);
2638                 if (nodemap == NULL) {
2639                         fprintf(stderr,
2640                                 "Failed to get nodemap, trying again\n");
2641                         sleep(1);
2642                         continue;
2643                 }
2644
2645                 flag_is_set = nodemap->node[ctdb->cmd_pnn].flags & flag;
2646                 if (flag_is_set == set_flag) {
2647                         break;
2648                 }
2649
2650                 sleep(1);
2651         }
2652 }
2653
2654 struct ipreallocate_state {
2655         int status;
2656         bool done;
2657 };
2658
2659 static void ipreallocate_handler(uint64_t srvid, TDB_DATA data,
2660                                  void *private_data)
2661 {
2662         struct ipreallocate_state *state =
2663                 (struct ipreallocate_state *)private_data;
2664
2665         if (data.dsize != sizeof(int)) {
2666                 /* Ignore packet */
2667                 return;
2668         }
2669
2670         state->status = *(int *)data.dptr;
2671         state->done = true;
2672 }
2673
2674 static int ipreallocate(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb)
2675 {
2676         struct ctdb_srvid_message msg = { 0 };
2677         struct ipreallocate_state state;
2678         int ret;
2679
2680         msg.pnn = ctdb->pnn;
2681         msg.srvid = next_srvid(ctdb);
2682
2683         state.done = false;
2684         ret = ctdb_client_set_message_handler(ctdb->ev, ctdb->client,
2685                                               msg.srvid,
2686                                               ipreallocate_handler, &state);
2687         if (ret != 0) {
2688                 return ret;
2689         }
2690
2691         while (true) {
2692                 ret = ctdb_message_takeover_run(mem_ctx, ctdb->ev,
2693                                                 ctdb->client,
2694                                                 CTDB_BROADCAST_CONNECTED,
2695                                                 &msg);
2696                 if (ret != 0) {
2697                         goto fail;
2698                 }
2699
2700                 ret = ctdb_client_wait_timeout(ctdb->ev, &state.done,
2701                                                TIMEOUT());
2702                 if (ret != 0) {
2703                         continue;
2704                 }
2705
2706                 if (state.status >= 0) {
2707                         ret = 0;
2708                 } else {
2709                         ret = state.status;
2710                 }
2711                 break;
2712         }
2713
2714 fail:
2715         ctdb_client_remove_message_handler(ctdb->ev, ctdb->client,
2716                                            msg.srvid, &state);
2717         return ret;
2718 }
2719
2720 static int control_disable(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2721                            int argc, const char **argv)
2722 {
2723         int ret;
2724
2725         if (argc != 0) {
2726                 usage("disable");
2727         }
2728
2729         ret = check_flags(mem_ctx, ctdb, "disabled",
2730                           NODE_FLAGS_PERMANENTLY_DISABLED, true);
2731         if (ret == 0) {
2732                 return 0;
2733         }
2734
2735         ret = ctdb_ctrl_modflags(mem_ctx, ctdb->ev, ctdb->client,
2736                                  ctdb->cmd_pnn, TIMEOUT(),
2737                                  NODE_FLAGS_PERMANENTLY_DISABLED, 0);
2738         if (ret != 0) {
2739                 fprintf(stderr,
2740                         "Failed to set DISABLED flag on node %u\n",
2741                         ctdb->cmd_pnn);
2742                 return ret;
2743         }
2744
2745         wait_for_flags(mem_ctx, ctdb, NODE_FLAGS_PERMANENTLY_DISABLED, true);
2746         return ipreallocate(mem_ctx, ctdb);
2747 }
2748
2749 static int control_enable(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2750                           int argc, const char **argv)
2751 {
2752         int ret;
2753
2754         if (argc != 0) {
2755                 usage("enable");
2756         }
2757
2758         ret = check_flags(mem_ctx, ctdb, "disabled",
2759                           NODE_FLAGS_PERMANENTLY_DISABLED, false);
2760         if (ret == 0) {
2761                 return 0;
2762         }
2763
2764         ret = ctdb_ctrl_modflags(mem_ctx, ctdb->ev, ctdb->client,
2765                                  ctdb->cmd_pnn, TIMEOUT(),
2766                                  0, NODE_FLAGS_PERMANENTLY_DISABLED);
2767         if (ret != 0) {
2768                 fprintf(stderr, "Failed to reset DISABLED flag on node %u\n",
2769                         ctdb->cmd_pnn);
2770                 return ret;
2771         }
2772
2773         wait_for_flags(mem_ctx, ctdb, NODE_FLAGS_PERMANENTLY_DISABLED, false);
2774         return ipreallocate(mem_ctx, ctdb);
2775 }
2776
2777 static int control_stop(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2778                         int argc, const char **argv)
2779 {
2780         int ret;
2781
2782         if (argc != 0) {
2783                 usage("stop");
2784         }
2785
2786         ret = check_flags(mem_ctx, ctdb, "stopped",
2787                           NODE_FLAGS_STOPPED, true);
2788         if (ret == 0) {
2789                 return 0;
2790         }
2791
2792         ret = ctdb_ctrl_stop_node(mem_ctx, ctdb->ev, ctdb->client,
2793                                   ctdb->cmd_pnn, TIMEOUT());
2794         if (ret != 0) {
2795                 fprintf(stderr, "Failed to stop node %u\n", ctdb->cmd_pnn);
2796                 return ret;
2797         }
2798
2799         wait_for_flags(mem_ctx, ctdb, NODE_FLAGS_STOPPED, true);
2800         return ipreallocate(mem_ctx, ctdb);
2801 }
2802
2803 static int control_continue(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2804                             int argc, const char **argv)
2805 {
2806         int ret;
2807
2808         if (argc != 0) {
2809                 usage("continue");
2810         }
2811
2812         ret = check_flags(mem_ctx, ctdb, "stopped",
2813                           NODE_FLAGS_STOPPED, false);
2814         if (ret == 0) {
2815                 return 0;
2816         }
2817
2818         ret = ctdb_ctrl_continue_node(mem_ctx, ctdb->ev, ctdb->client,
2819                                       ctdb->cmd_pnn, TIMEOUT());
2820         if (ret != 0) {
2821                 fprintf(stderr, "Failed to continue stopped node %u\n",
2822                         ctdb->cmd_pnn);
2823                 return ret;
2824         }
2825
2826         wait_for_flags(mem_ctx, ctdb, NODE_FLAGS_STOPPED, false);
2827         return ipreallocate(mem_ctx, ctdb);
2828 }
2829
2830 static int control_ban(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2831                        int argc, const char **argv)
2832 {
2833         struct ctdb_ban_state ban_state;
2834         int ret;
2835
2836         if (argc != 1) {
2837                 usage("ban");
2838         }
2839
2840         ret = check_flags(mem_ctx, ctdb, "banned",
2841                           NODE_FLAGS_BANNED, true);
2842         if (ret == 0) {
2843                 return 0;
2844         }
2845
2846         ban_state.pnn = ctdb->cmd_pnn;
2847         ban_state.time = strtoul(argv[0], NULL, 0);
2848
2849         if (ban_state.time == 0) {
2850                 fprintf(stderr, "Ban time cannot be zero\n");
2851                 return EINVAL;
2852         }
2853
2854         ret = ctdb_ctrl_set_ban_state(mem_ctx, ctdb->ev, ctdb->client,
2855                                       ctdb->cmd_pnn, TIMEOUT(), &ban_state);
2856         if (ret != 0) {
2857                 fprintf(stderr, "Failed to ban node %u\n", ctdb->cmd_pnn);
2858                 return ret;
2859         }
2860
2861         wait_for_flags(mem_ctx, ctdb, NODE_FLAGS_BANNED, true);
2862         return ipreallocate(mem_ctx, ctdb);
2863
2864 }
2865
2866 static int control_unban(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2867                          int argc, const char **argv)
2868 {
2869         struct ctdb_ban_state ban_state;
2870         int ret;
2871
2872         if (argc != 0) {
2873                 usage("unban");
2874         }
2875
2876         ret = check_flags(mem_ctx, ctdb, "banned",
2877                           NODE_FLAGS_BANNED, false);
2878         if (ret == 0) {
2879                 return 0;
2880         }
2881
2882         ban_state.pnn = ctdb->cmd_pnn;
2883         ban_state.time = 0;
2884
2885         ret = ctdb_ctrl_set_ban_state(mem_ctx, ctdb->ev, ctdb->client,
2886                                       ctdb->cmd_pnn, TIMEOUT(), &ban_state);
2887         if (ret != 0) {
2888                 fprintf(stderr, "Failed to unban node %u\n", ctdb->cmd_pnn);
2889                 return ret;
2890         }
2891
2892         wait_for_flags(mem_ctx, ctdb, NODE_FLAGS_BANNED, false);
2893         return ipreallocate(mem_ctx, ctdb);
2894
2895 }
2896
2897 static int control_shutdown(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2898                             int argc, const char **argv)
2899 {
2900         int ret;
2901
2902         if (argc != 0) {
2903                 usage("shutdown");
2904         }
2905
2906         ret = ctdb_ctrl_shutdown(mem_ctx, ctdb->ev, ctdb->client,
2907                                  ctdb->cmd_pnn, TIMEOUT());
2908         if (ret != 0) {
2909                 fprintf(stderr, "Unable to shutdown node %u\n", ctdb->cmd_pnn);
2910                 return ret;
2911         }
2912
2913         return 0;
2914 }
2915
2916 static int get_generation(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2917                           uint32_t *generation)
2918 {
2919         uint32_t recmaster;
2920         int recmode;
2921         struct ctdb_vnn_map *vnnmap;
2922         int ret;
2923
2924 again:
2925         ret = ctdb_ctrl_get_recmaster(mem_ctx, ctdb->ev, ctdb->client,
2926                                       ctdb->cmd_pnn, TIMEOUT(), &recmaster);
2927         if (ret != 0) {
2928                 fprintf(stderr, "Failed to find recovery master\n");
2929                 return ret;
2930         }
2931
2932         ret = ctdb_ctrl_get_recmode(mem_ctx, ctdb->ev, ctdb->client,
2933                                     recmaster, TIMEOUT(), &recmode);
2934         if (ret != 0) {
2935                 fprintf(stderr, "Failed to get recovery mode from node %u\n",
2936                         recmaster);
2937                 return ret;
2938         }
2939
2940         if (recmode == CTDB_RECOVERY_ACTIVE) {
2941                 sleep(1);
2942                 goto again;
2943         }
2944
2945         ret = ctdb_ctrl_getvnnmap(mem_ctx, ctdb->ev, ctdb->client,
2946                                   recmaster, TIMEOUT(), &vnnmap);
2947         if (ret != 0) {
2948                 fprintf(stderr, "Failed to get generation from node %u\n",
2949                         recmaster);
2950                 return ret;
2951         }
2952
2953         if (vnnmap->generation == INVALID_GENERATION) {
2954                 talloc_free(vnnmap);
2955                 sleep(1);
2956                 goto again;
2957         }
2958
2959         *generation = vnnmap->generation;
2960         talloc_free(vnnmap);
2961         return 0;
2962 }
2963
2964
2965 static int control_recover(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
2966                            int argc, const char **argv)
2967 {
2968         uint32_t generation, next_generation;
2969         int ret;
2970
2971         if (argc != 0) {
2972                 usage("recover");
2973         }
2974
2975         ret = get_generation(mem_ctx, ctdb, &generation);
2976         if (ret != 0) {
2977                 return ret;
2978         }
2979
2980         ret = ctdb_ctrl_set_recmode(mem_ctx, ctdb->ev, ctdb->client,
2981                                     ctdb->cmd_pnn, TIMEOUT(),
2982                                     CTDB_RECOVERY_ACTIVE);
2983         if (ret != 0) {
2984                 fprintf(stderr, "Failed to set recovery mode active\n");
2985                 return ret;
2986         }
2987
2988         while (1) {
2989                 ret = get_generation(mem_ctx, ctdb, &next_generation);
2990                 if (ret != 0) {
2991                         fprintf(stderr,
2992                                 "Failed to confirm end of recovery\n");
2993                         return ret;
2994                 }
2995
2996                 if (next_generation != generation) {
2997                         break;
2998                 }
2999
3000                 sleep (1);
3001         }
3002
3003         return 0;
3004 }
3005
3006 static int control_ipreallocate(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3007                                 int argc, const char **argv)
3008 {
3009         if (argc != 0) {
3010                 usage("ipreallocate");
3011         }
3012
3013         return ipreallocate(mem_ctx, ctdb);
3014 }
3015
3016 static int control_isnotrecmaster(TALLOC_CTX *mem_ctx,
3017                                   struct ctdb_context *ctdb,
3018                                   int argc, const char **argv)
3019 {
3020         uint32_t recmaster;
3021         int ret;
3022
3023         if (argc != 0) {
3024                 usage("isnotrecmaster");
3025         }
3026
3027         ret = ctdb_ctrl_get_recmaster(mem_ctx, ctdb->ev, ctdb->client,
3028                                       ctdb->pnn, TIMEOUT(), &recmaster);
3029         if (ret != 0) {
3030                 fprintf(stderr, "Failed to get recmaster\n");
3031                 return ret;
3032         }
3033
3034         if (recmaster != ctdb->pnn) {
3035                 printf("this node is not the recmaster\n");
3036                 return 1;
3037         }
3038
3039         printf("this node is the recmaster\n");
3040         return 0;
3041 }
3042
3043 static int control_gratarp(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3044                            int argc, const char **argv)
3045 {
3046         struct ctdb_addr_info addr_info;
3047         int ret;
3048
3049         if (argc != 2) {
3050                 usage("gratarp");
3051         }
3052
3053         if (! parse_ip(argv[0], NULL, 0, &addr_info.addr)) {
3054                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
3055                 return 1;
3056         }
3057         addr_info.iface = argv[1];
3058
3059         ret = ctdb_ctrl_send_gratuitous_arp(mem_ctx, ctdb->ev, ctdb->client,
3060                                             ctdb->cmd_pnn, TIMEOUT(),
3061                                             &addr_info);
3062         if (ret != 0) {
3063                 fprintf(stderr, "Unable to send gratuitous arp from node %u\n",
3064                         ctdb->cmd_pnn);
3065                 return ret;
3066         }
3067
3068         return 0;
3069 }
3070
3071 static int control_tickle(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3072                            int argc, const char **argv)
3073 {
3074         ctdb_sock_addr src, dst;
3075         int ret;
3076
3077         if (argc != 0 && argc != 2) {
3078                 usage("tickle");
3079         }
3080
3081         if (argc == 0) {
3082                 struct ctdb_connection *clist;
3083                 int count;
3084                 int i, num_failed;
3085
3086                 ret = ctdb_parse_connections(stdin, mem_ctx, &count, &clist);
3087                 if (ret != 0) {
3088                         return ret;
3089                 }
3090
3091                 num_failed = 0;
3092                 for (i=0; i<count; i++) {
3093                         ret = ctdb_sys_send_tcp(&clist[i].src,
3094                                                 &clist[i].dst,
3095                                                 0, 0, 0);
3096                         if (ret != 0) {
3097                                 num_failed += 1;
3098                         }
3099                 }
3100
3101                 TALLOC_FREE(clist);
3102
3103                 if (num_failed > 0) {
3104                         fprintf(stderr, "Failed to send %d tickles\n",
3105                                 num_failed);
3106                         return 1;
3107                 }
3108
3109                 return 0;
3110         }
3111
3112
3113         if (! parse_ip_port(argv[0], &src)) {
3114                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
3115                 return 1;
3116         }
3117
3118         if (! parse_ip_port(argv[1], &dst)) {
3119                 fprintf(stderr, "Invalid IP address %s\n", argv[1]);
3120                 return 1;
3121         }
3122
3123         ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0);
3124         if (ret != 0) {
3125                 fprintf(stderr, "Failed to send tickle ack\n");
3126                 return ret;
3127         }
3128
3129         return 0;
3130 }
3131
3132 static int control_gettickles(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3133                               int argc, const char **argv)
3134 {
3135         ctdb_sock_addr addr;
3136         struct ctdb_tickle_list *tickles;
3137         unsigned port = 0;
3138         int ret, i;
3139
3140         if (argc < 1 || argc > 2) {
3141                 usage("gettickles");
3142         }
3143
3144         if (argc == 2) {
3145                 port = strtoul(argv[1], NULL, 10);
3146         }
3147
3148         if (! parse_ip(argv[0], NULL, port, &addr)) {
3149                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
3150                 return 1;
3151         }
3152
3153         ret = ctdb_ctrl_get_tcp_tickle_list(mem_ctx, ctdb->ev, ctdb->client,
3154                                             ctdb->cmd_pnn, TIMEOUT(), &addr,
3155                                             &tickles);
3156         if (ret != 0) {
3157                 fprintf(stderr, "Failed to get list of connections\n");
3158                 return ret;
3159         }
3160
3161         if (options.machinereadable) {
3162                 printf("%s%s%s%s%s%s%s%s%s\n",
3163                        options.sep,
3164                        "Source IP", options.sep,
3165                        "Port", options.sep,
3166                        "Destiation IP", options.sep,
3167                        "Port", options.sep);
3168                 for (i=0; i<tickles->num; i++) {
3169                         printf("%s%s%s%u%s%s%s%u%s\n", options.sep,
3170                                ctdb_sock_addr_to_string(
3171                                        mem_ctx, &tickles->conn[i].src),
3172                                options.sep,
3173                                ntohs(tickles->conn[i].src.ip.sin_port),
3174                                options.sep,
3175                                ctdb_sock_addr_to_string(
3176                                        mem_ctx, &tickles->conn[i].dst),
3177                                options.sep,
3178                                ntohs(tickles->conn[i].dst.ip.sin_port),
3179                                options.sep);
3180                 }
3181         } else {
3182                 printf("Connections for IP: %s\n",
3183                        ctdb_sock_addr_to_string(mem_ctx, &tickles->addr));
3184                 printf("Num connections: %u\n", tickles->num);
3185                 for (i=0; i<tickles->num; i++) {
3186                         printf("SRC: %s:%u   DST: %s:%u\n",
3187                                ctdb_sock_addr_to_string(
3188                                        mem_ctx, &tickles->conn[i].src),
3189                                ntohs(tickles->conn[i].src.ip.sin_port),
3190                                ctdb_sock_addr_to_string(
3191                                        mem_ctx, &tickles->conn[i].dst),
3192                                ntohs(tickles->conn[i].dst.ip.sin_port));
3193                 }
3194         }
3195
3196         talloc_free(tickles);
3197         return 0;
3198 }
3199
3200 typedef void (*clist_request_func)(struct ctdb_req_control *request,
3201                                    struct ctdb_connection *conn);
3202
3203 typedef int (*clist_reply_func)(struct ctdb_reply_control *reply);
3204
3205 struct process_clist_state {
3206         struct ctdb_connection *clist;
3207         int count;
3208         int num_failed, num_total;
3209         clist_reply_func reply_func;
3210 };
3211
3212 static void process_clist_done(struct tevent_req *subreq);
3213
3214 static struct tevent_req *process_clist_send(
3215                                         TALLOC_CTX *mem_ctx,
3216                                         struct ctdb_context *ctdb,
3217                                         struct ctdb_connection *clist,
3218                                         int count,
3219                                         clist_request_func request_func,
3220                                         clist_reply_func reply_func)
3221 {
3222         struct tevent_req *req, *subreq;
3223         struct process_clist_state *state;
3224         struct ctdb_req_control request;
3225         int i;
3226
3227         req = tevent_req_create(mem_ctx, &state, struct process_clist_state);
3228         if (req == NULL) {
3229                 return NULL;
3230         }
3231
3232         state->clist = clist;
3233         state->count = count;
3234         state->reply_func = reply_func;
3235
3236         for (i=0; i<count; i++) {
3237                 request_func(&request, &clist[i]);
3238                 subreq = ctdb_client_control_send(state, ctdb->ev,
3239                                                   ctdb->client, ctdb->cmd_pnn,
3240                                                   TIMEOUT(), &request);
3241                 if (tevent_req_nomem(subreq, req)) {
3242                         return tevent_req_post(req, ctdb->ev);
3243                 }
3244                 tevent_req_set_callback(subreq, process_clist_done, req);
3245         }
3246
3247         return req;
3248 }
3249
3250 static void process_clist_done(struct tevent_req *subreq)
3251 {
3252         struct tevent_req *req = tevent_req_callback_data(
3253                 subreq, struct tevent_req);
3254         struct process_clist_state *state = tevent_req_data(
3255                 req, struct process_clist_state);
3256         struct ctdb_reply_control *reply;
3257         int ret;
3258         bool status;
3259
3260         status = ctdb_client_control_recv(subreq, NULL, state, &reply);
3261         TALLOC_FREE(subreq);
3262         if (! status) {
3263                 state->num_failed += 1;
3264                 goto done;
3265         }
3266
3267         ret = state->reply_func(reply);
3268         if (ret != 0) {
3269                 state->num_failed += 1;
3270                 goto done;
3271         }
3272
3273 done:
3274         state->num_total += 1;
3275         if (state->num_total == state->count) {
3276                 tevent_req_done(req);
3277         }
3278 }
3279
3280 static int process_clist_recv(struct tevent_req *req)
3281 {
3282         struct process_clist_state *state = tevent_req_data(
3283                 req, struct process_clist_state);
3284
3285         return state->num_failed;
3286 }
3287
3288 static int control_addtickle(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3289                              int argc, const char **argv)
3290 {
3291         struct ctdb_connection conn;
3292         int ret;
3293
3294         if (argc != 0 && argc != 2) {
3295                 usage("addtickle");
3296         }
3297
3298         if (argc == 0) {
3299                 struct ctdb_connection *clist;
3300                 struct tevent_req *req;
3301                 int count;
3302
3303                 ret = ctdb_parse_connections(stdin, mem_ctx, &count, &clist);
3304                 if (ret != 0) {
3305                         return ret;
3306                 }
3307                 if (count == 0) {
3308                         return 0;
3309                 }
3310
3311                 req = process_clist_send(mem_ctx, ctdb, clist, count,
3312                                  ctdb_req_control_tcp_add_delayed_update,
3313                                  ctdb_reply_control_tcp_add_delayed_update);
3314                 if (req == NULL) {
3315                         talloc_free(clist);
3316                         return ENOMEM;
3317                 }
3318
3319                 tevent_req_poll(req, ctdb->ev);
3320                 talloc_free(clist);
3321
3322                 ret = process_clist_recv(req);
3323                 if (ret != 0) {
3324                         fprintf(stderr, "Failed to add %d tickles\n", ret);
3325                         return 1;
3326                 }
3327
3328                 return 0;
3329         }
3330
3331         if (! parse_ip_port(argv[0], &conn.src)) {
3332                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
3333                 return 1;
3334         }
3335         if (! parse_ip_port(argv[1], &conn.dst)) {
3336                 fprintf(stderr, "Invalid IP address %s\n", argv[1]);
3337                 return 1;
3338         }
3339
3340         ret = ctdb_ctrl_tcp_add_delayed_update(mem_ctx, ctdb->ev,
3341                                                ctdb->client, ctdb->cmd_pnn,
3342                                                TIMEOUT(), &conn);
3343         if (ret != 0) {
3344                 fprintf(stderr, "Failed to register connection\n");
3345                 return ret;
3346         }
3347
3348         return 0;
3349 }
3350
3351 static int control_deltickle(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3352                              int argc, const char **argv)
3353 {
3354         struct ctdb_connection conn;
3355         int ret;
3356
3357         if (argc != 0 && argc != 2) {
3358                 usage("deltickle");
3359         }
3360
3361         if (argc == 0) {
3362                 struct ctdb_connection *clist;
3363                 struct tevent_req *req;
3364                 int count;
3365
3366                 ret = ctdb_parse_connections(stdin, mem_ctx, &count, &clist);
3367                 if (ret != 0) {
3368                         return ret;
3369                 }
3370                 if (count == 0) {
3371                         return 0;
3372                 }
3373
3374                 req = process_clist_send(mem_ctx, ctdb, clist, count,
3375                                          ctdb_req_control_tcp_remove,
3376                                          ctdb_reply_control_tcp_remove);
3377                 if (req == NULL) {
3378                         talloc_free(clist);
3379                         return ENOMEM;
3380                 }
3381
3382                 tevent_req_poll(req, ctdb->ev);
3383                 talloc_free(clist);
3384
3385                 ret = process_clist_recv(req);
3386                 if (ret != 0) {
3387                         fprintf(stderr, "Failed to remove %d tickles\n", ret);
3388                         return 1;
3389                 }
3390
3391                 return 0;
3392         }
3393
3394         if (! parse_ip_port(argv[0], &conn.src)) {
3395                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
3396                 return 1;
3397         }
3398         if (! parse_ip_port(argv[1], &conn.dst)) {
3399                 fprintf(stderr, "Invalid IP address %s\n", argv[1]);
3400                 return 1;
3401         }
3402
3403         ret = ctdb_ctrl_tcp_remove(mem_ctx, ctdb->ev, ctdb->client,
3404                                    ctdb->cmd_pnn, TIMEOUT(), &conn);
3405         if (ret != 0) {
3406                 fprintf(stderr, "Failed to unregister connection\n");
3407                 return ret;
3408         }
3409
3410         return 0;
3411 }
3412
3413 static int control_check_srvids(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3414                                 int argc, const char **argv)
3415 {
3416         uint64_t *srvid;
3417         uint8_t *result;
3418         int ret, i;
3419
3420         if (argc == 0) {
3421                 usage("check_srvids");
3422         }
3423
3424         srvid = talloc_array(mem_ctx, uint64_t, argc);
3425         if (srvid == NULL) {
3426                 fprintf(stderr, "Memory allocation error\n");
3427                 return 1;
3428         }
3429
3430         for (i=0; i<argc; i++) {
3431                 srvid[i] = strtoull(argv[i], NULL, 0);
3432         }
3433
3434         ret = ctdb_ctrl_check_srvids(mem_ctx, ctdb->ev, ctdb->client,
3435                                      ctdb->cmd_pnn, TIMEOUT(), srvid, argc,
3436                                      &result);
3437         if (ret != 0) {
3438                 fprintf(stderr, "Failed to check srvids on node %u\n",
3439                         ctdb->cmd_pnn);
3440                 return ret;
3441         }
3442
3443         for (i=0; i<argc; i++) {
3444                 printf("SRVID 0x%" PRIx64 " %s\n", srvid[i],
3445                        (result[i] ? "exists" : "does not exist"));
3446         }
3447
3448         return 0;
3449 }
3450
3451 static int control_listnodes(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3452                              int argc, const char **argv)
3453 {
3454         struct ctdb_node_map *nodemap;
3455         int i;
3456
3457         if (argc != 0) {
3458                 usage("listnodes");
3459         }
3460
3461         nodemap = read_nodes_file(mem_ctx, CTDB_UNKNOWN_PNN);
3462         if (nodemap == NULL) {
3463                 return 1;
3464         }
3465
3466         for (i=0; i<nodemap->num; i++) {
3467                 if (nodemap->node[i].flags & NODE_FLAGS_DELETED) {
3468                         continue;
3469                 }
3470
3471                 if (options.machinereadable) {
3472                         printf("%s%u%s%s%s\n", options.sep,
3473                                nodemap->node[i].pnn, options.sep,
3474                                ctdb_sock_addr_to_string(
3475                                         mem_ctx, &nodemap->node[i].addr),
3476                                options.sep);
3477                 } else {
3478                         printf("%s\n",
3479                                ctdb_sock_addr_to_string(
3480                                         mem_ctx, &nodemap->node[i].addr));
3481                 }
3482         }
3483
3484         return 0;
3485 }
3486
3487 static bool nodemap_identical(struct ctdb_node_map *nodemap1,
3488                               struct ctdb_node_map *nodemap2)
3489 {
3490         int i;
3491
3492         if (nodemap1->num != nodemap2->num) {
3493                 return false;
3494         }
3495
3496         for (i=0; i<nodemap1->num; i++) {
3497                 struct ctdb_node_and_flags *n1, *n2;
3498
3499                 n1 = &nodemap1->node[i];
3500                 n2 = &nodemap2->node[i];
3501
3502                 if ((n1->pnn != n2->pnn) ||
3503                     (n1->flags != n2->flags) ||
3504                     ! ctdb_sock_addr_same_ip(&n1->addr, &n2->addr)) {
3505                         return false;
3506                 }
3507         }
3508
3509         return true;
3510 }
3511
3512 static int check_node_file_changes(TALLOC_CTX *mem_ctx,
3513                                    struct ctdb_node_map *nm,
3514                                    struct ctdb_node_map *fnm,
3515                                    bool *reload)
3516 {
3517         int i;
3518         bool check_failed = false;
3519
3520         *reload = false;
3521
3522         for (i=0; i<nm->num; i++) {
3523                 if (i >= fnm->num) {
3524                         fprintf(stderr,
3525                                 "Node %u (%s) missing from nodes file\n",
3526                                 nm->node[i].pnn,
3527                                 ctdb_sock_addr_to_string(
3528                                         mem_ctx, &nm->node[i].addr));
3529                         check_failed = true;
3530                         continue;
3531                 }
3532                 if (nm->node[i].flags & NODE_FLAGS_DELETED &&
3533                     fnm->node[i].flags & NODE_FLAGS_DELETED) {
3534                         /* Node remains deleted */
3535                         continue;
3536                 }
3537
3538                 if (! (nm->node[i].flags & NODE_FLAGS_DELETED) &&
3539                     ! (fnm->node[i].flags & NODE_FLAGS_DELETED)) {
3540                         /* Node not newly nor previously deleted */
3541                         if (! ctdb_same_ip(&nm->node[i].addr,
3542                                            &fnm->node[i].addr)) {
3543                                 fprintf(stderr,
3544                                         "Node %u has changed IP address"
3545                                         " (was %s, now %s)\n",
3546                                         nm->node[i].pnn,
3547                                         ctdb_sock_addr_to_string(
3548                                                 mem_ctx, &nm->node[i].addr),
3549                                         ctdb_sock_addr_to_string(
3550                                                 mem_ctx, &fnm->node[i].addr));
3551                                 check_failed = true;
3552                         } else {
3553                                 if (nm->node[i].flags & NODE_FLAGS_DISCONNECTED) {
3554                                         fprintf(stderr,
3555                                                 "WARNING: Node %u is disconnected."
3556                                                 " You MUST fix this node manually!\n",
3557                                                 nm->node[i].pnn);
3558                                 }
3559                         }
3560                         continue;
3561                 }
3562
3563                 if (fnm->node[i].flags & NODE_FLAGS_DELETED) {
3564                         /* Node is being deleted */
3565                         printf("Node %u is DELETED\n", nm->node[i].pnn);
3566                         *reload = true;
3567                         if (! (nm->node[i].flags & NODE_FLAGS_DISCONNECTED)) {
3568                                 fprintf(stderr,
3569                                         "ERROR: Node %u is still connected\n",
3570                                         nm->node[i].pnn);
3571                                 check_failed = true;
3572                         }
3573                         continue;
3574                 }
3575
3576                 if (nm->node[i].flags & NODE_FLAGS_DELETED) {
3577                         /* Node was previously deleted */
3578                         printf("Node %u is UNDELETED\n", nm->node[i].pnn);
3579                         *reload = true;
3580                 }
3581         }
3582
3583         if (check_failed) {
3584                 fprintf(stderr,
3585                         "ERROR: Nodes will not be reloaded due to previous error\n");
3586                 return 1;
3587         }
3588
3589         /* Leftover nodes in file are NEW */
3590         for (; i < fnm->num; i++) {
3591                 printf("Node %u is NEW\n", fnm->node[i].pnn);
3592                 *reload = true;
3593         }
3594
3595         return 0;
3596 }
3597
3598 struct disable_recoveries_state {
3599         uint32_t *pnn_list;
3600         int node_count;
3601         bool *reply;
3602         int status;
3603         bool done;
3604 };
3605
3606 static void disable_recoveries_handler(uint64_t srvid, TDB_DATA data,
3607                                        void *private_data)
3608 {
3609         struct disable_recoveries_state *state =
3610                 (struct disable_recoveries_state *)private_data;
3611         int ret, i;
3612
3613         if (data.dsize != sizeof(int)) {
3614                 /* Ignore packet */
3615                 return;
3616         }
3617
3618         /* ret will be a PNN (i.e. >=0) on success, or negative on error */
3619         ret = *(int *)data.dptr;
3620         if (ret < 0) {
3621                 state->status = ret;
3622                 state->done = true;
3623                 return;
3624         }
3625         for (i=0; i<state->node_count; i++) {
3626                 if (state->pnn_list[i] == ret) {
3627                         state->reply[i] = true;
3628                         break;
3629                 }
3630         }
3631
3632         state->done = true;
3633         for (i=0; i<state->node_count; i++) {
3634                 if (! state->reply[i]) {
3635                         state->done = false;
3636                         break;
3637                 }
3638         }
3639 }
3640
3641 static int disable_recoveries(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3642                               uint32_t timeout, uint32_t *pnn_list, int count)
3643 {
3644         struct ctdb_disable_message disable = { 0 };
3645         struct disable_recoveries_state state;
3646         int ret, i;
3647
3648         disable.pnn = ctdb->pnn;
3649         disable.srvid = next_srvid(ctdb);
3650         disable.timeout = timeout;
3651
3652         state.pnn_list = pnn_list;
3653         state.node_count = count;
3654         state.done = false;
3655         state.status = 0;
3656         state.reply = talloc_zero_array(mem_ctx, bool, count);
3657         if (state.reply == NULL) {
3658                 return ENOMEM;
3659         }
3660
3661         ret = ctdb_client_set_message_handler(ctdb->ev, ctdb->client,
3662                                               disable.srvid,
3663                                               disable_recoveries_handler,
3664                                               &state);
3665         if (ret != 0) {
3666                 return ret;
3667         }
3668
3669         for (i=0; i<count; i++) {
3670                 ret = ctdb_message_disable_recoveries(mem_ctx, ctdb->ev,
3671                                                       ctdb->client,
3672                                                       pnn_list[i],
3673                                                       &disable);
3674                 if (ret != 0) {
3675                         goto fail;
3676                 }
3677         }
3678
3679         ret = ctdb_client_wait_timeout(ctdb->ev, &state.done, TIMEOUT());
3680         if (ret == ETIME) {
3681                 fprintf(stderr, "Timed out waiting to disable recoveries\n");
3682         } else {
3683                 ret = (state.status >= 0 ? 0 : 1);
3684         }
3685
3686 fail:
3687         ctdb_client_remove_message_handler(ctdb->ev, ctdb->client,
3688                                            disable.srvid, &state);
3689         return ret;
3690 }
3691
3692 static int control_reloadnodes(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3693                                int argc, const char **argv)
3694 {
3695         struct ctdb_node_map *nodemap = NULL;
3696         struct ctdb_node_map *file_nodemap;
3697         struct ctdb_node_map *remote_nodemap;
3698         struct ctdb_req_control request;
3699         struct ctdb_reply_control **reply;
3700         bool reload;
3701         int ret, i;
3702         uint32_t *pnn_list;
3703         int count;
3704
3705         nodemap = get_nodemap(ctdb, false);
3706         if (nodemap == NULL) {
3707                 return 1;
3708         }
3709
3710         file_nodemap = read_nodes_file(mem_ctx, ctdb->pnn);
3711         if (file_nodemap == NULL) {
3712                 return 1;
3713         }
3714
3715         for (i=0; i<nodemap->num; i++) {
3716                 if (nodemap->node[i].flags & NODE_FLAGS_DISCONNECTED) {
3717                         continue;
3718                 }
3719
3720                 ret = ctdb_ctrl_get_nodes_file(mem_ctx, ctdb->ev, ctdb->client,
3721                                                nodemap->node[i].pnn, TIMEOUT(),
3722                                                &remote_nodemap);
3723                 if (ret != 0) {
3724                         fprintf(stderr,
3725                                 "ERROR: Failed to get nodes file from node %u\n",
3726                                 nodemap->node[i].pnn);
3727                         return ret;
3728                 }
3729
3730                 if (! nodemap_identical(file_nodemap, remote_nodemap)) {
3731                         fprintf(stderr,
3732                                 "ERROR: Nodes file on node %u differs"
3733                                  " from current node (%u)\n",
3734                                  nodemap->node[i].pnn, ctdb->pnn);
3735                         return 1;
3736                 }
3737         }
3738
3739         ret = check_node_file_changes(mem_ctx, nodemap, file_nodemap, &reload);
3740         if (ret != 0) {
3741                 return ret;
3742         }
3743
3744         if (! reload) {
3745                 fprintf(stderr, "No change in nodes file,"
3746                                 " skipping unnecessary reload\n");
3747                 return 0;
3748         }
3749
3750         count = list_of_connected_nodes(nodemap, CTDB_UNKNOWN_PNN,
3751                                         mem_ctx, &pnn_list);
3752         if (count <= 0) {
3753                 fprintf(stderr, "Memory allocation error\n");
3754                 return 1;
3755         }
3756
3757         ret = disable_recoveries(mem_ctx, ctdb, 2*options.timelimit,
3758                                  pnn_list, count);
3759         if (ret != 0) {
3760                 fprintf(stderr, "Failed to disable recoveries\n");
3761                 return ret;
3762         }
3763
3764         ctdb_req_control_reload_nodes_file(&request);
3765         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
3766                                         pnn_list, count, TIMEOUT(),
3767                                         &request, NULL, &reply);
3768         if (ret != 0) {
3769                 bool failed = false;
3770
3771                 for (i=0; i<count; i++) {
3772                         ret = ctdb_reply_control_reload_nodes_file(reply[i]);
3773                         if (ret != 0) {
3774                                 fprintf(stderr,
3775                                         "Node %u failed to reload nodes\n",
3776                                         pnn_list[i]);
3777                                 failed = true;
3778                         }
3779                 }
3780                 if (failed) {
3781                         fprintf(stderr,
3782                                 "You MUST fix failed nodes manually!\n");
3783                 }
3784         }
3785
3786         ret = disable_recoveries(mem_ctx, ctdb, 0, pnn_list, count);
3787         if (ret != 0) {
3788                 fprintf(stderr, "Failed to enable recoveries\n");
3789                 return ret;
3790         }
3791
3792         return 0;
3793 }
3794
3795 static int moveip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3796                   ctdb_sock_addr *addr, uint32_t pnn)
3797 {
3798         struct ctdb_public_ip_list *pubip_list;
3799         struct ctdb_public_ip pubip;
3800         struct ctdb_node_map *nodemap;
3801         struct ctdb_req_control request;
3802         uint32_t *pnn_list;
3803         int ret, i, count;
3804
3805         ret = ctdb_message_disable_ip_check(mem_ctx, ctdb->ev, ctdb->client,
3806                                             CTDB_BROADCAST_CONNECTED,
3807                                             2*options.timelimit);
3808         if (ret != 0) {
3809                 fprintf(stderr, "Failed to disable IP check\n");
3810                 return ret;
3811         }
3812
3813         ret = ctdb_ctrl_get_public_ips(mem_ctx, ctdb->ev, ctdb->client,
3814                                        pnn, TIMEOUT(), false, &pubip_list);
3815         if (ret != 0) {
3816                 fprintf(stderr, "Failed to get Public IPs from node %u\n",
3817                         pnn);
3818                 return ret;
3819         }
3820
3821         for (i=0; i<pubip_list->num; i++) {
3822                 if (ctdb_same_ip(addr, &pubip_list->ip[i].addr)) {
3823                         break;
3824                 }
3825         }
3826
3827         if (i == pubip_list->num) {
3828                 fprintf(stderr, "Node %u CANNOT host IP address %s\n",
3829                         pnn, ctdb_sock_addr_to_string(mem_ctx, addr));
3830                 return 1;
3831         }
3832
3833         nodemap = get_nodemap(ctdb, false);
3834         if (nodemap == NULL) {
3835                 return 1;
3836         }
3837
3838         count = list_of_active_nodes(nodemap, pnn, mem_ctx, &pnn_list);
3839         if (count <= 0) {
3840                 fprintf(stderr, "Memory allocation error\n");
3841                 return 1;
3842         }
3843
3844         pubip.pnn = pnn;
3845         pubip.addr = *addr;
3846         ctdb_req_control_release_ip(&request, &pubip);
3847
3848         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
3849                                         pnn_list, count, TIMEOUT(),
3850                                         &request, NULL, NULL);
3851         if (ret != 0) {
3852                 fprintf(stderr, "Failed to release IP on nodes\n");
3853                 return ret;
3854         }
3855
3856         ret = ctdb_ctrl_takeover_ip(mem_ctx, ctdb->ev, ctdb->client,
3857                                     pnn, TIMEOUT(), &pubip);
3858         if (ret != 0) {
3859                 fprintf(stderr, "Failed to takeover IP on node %u\n", pnn);
3860                 return ret;
3861         }
3862
3863         return 0;
3864 }
3865
3866 static int control_moveip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3867                           int argc, const char **argv)
3868 {
3869         ctdb_sock_addr addr;
3870         uint32_t pnn;
3871         int ret, retries = 0;
3872
3873         if (argc != 2) {
3874                 usage("moveip");
3875         }
3876
3877         if (! parse_ip(argv[0], NULL, 0, &addr)) {
3878                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
3879                 return 1;
3880         }
3881
3882         pnn = strtoul(argv[1], NULL, 10);
3883         if (pnn == CTDB_UNKNOWN_PNN) {
3884                 fprintf(stderr, "Invalid PNN %s\n", argv[1]);
3885                 return 1;
3886         }
3887
3888         while (retries < 5) {
3889                 ret = moveip(mem_ctx, ctdb, &addr, pnn);
3890                 if (ret == 0) {
3891                         break;
3892                 }
3893
3894                 sleep(3);
3895                 retries++;
3896         }
3897
3898         if (ret != 0) {
3899                 fprintf(stderr, "Failed to move IP %s to node %u\n",
3900                         argv[0], pnn);
3901                 return ret;
3902         }
3903
3904         return 0;
3905 }
3906
3907 static int rebalancenode(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3908                          uint32_t pnn)
3909 {
3910         int ret;
3911
3912         ret = ctdb_message_rebalance_node(mem_ctx, ctdb->ev, ctdb->client,
3913                                           CTDB_BROADCAST_CONNECTED, pnn);
3914         if (ret != 0) {
3915                 fprintf(stderr,
3916                         "Failed to ask recovery master to distribute IPs\n");
3917                 return ret;
3918         }
3919
3920         return 0;
3921 }
3922
3923 static int control_addip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3924                          int argc, const char **argv)
3925 {
3926         ctdb_sock_addr addr;
3927         struct ctdb_public_ip_list *pubip_list;
3928         struct ctdb_addr_info addr_info;
3929         unsigned int mask;
3930         int ret, i, retries = 0;
3931
3932         if (argc != 2) {
3933                 usage("addip");
3934         }
3935
3936         if (! parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
3937                 fprintf(stderr, "Invalid IP/Mask %s\n", argv[0]);
3938                 return 1;
3939         }
3940
3941         ret = ctdb_ctrl_get_public_ips(mem_ctx, ctdb->ev, ctdb->client,
3942                                        ctdb->cmd_pnn, TIMEOUT(),
3943                                        false, &pubip_list);
3944         if (ret != 0) {
3945                 fprintf(stderr, "Failed to get Public IPs from node %u\n",
3946                         ctdb->cmd_pnn);
3947                 return 1;
3948         }
3949
3950         for (i=0; i<pubip_list->num; i++) {
3951                 if (ctdb_same_ip(&addr, &pubip_list->ip[i].addr)) {
3952                         fprintf(stderr, "Node already knows about IP %s\n",
3953                                 ctdb_sock_addr_to_string(mem_ctx, &addr));
3954                         return 0;
3955                 }
3956         }
3957
3958         addr_info.addr = addr;
3959         addr_info.mask = mask;
3960         addr_info.iface = argv[1];
3961
3962         while (retries < 5) {
3963                 ret = ctdb_ctrl_add_public_ip(mem_ctx, ctdb->ev, ctdb->client,
3964                                               ctdb->cmd_pnn, TIMEOUT(),
3965                                               &addr_info);
3966                 if (ret == 0) {
3967                         break;
3968                 }
3969
3970                 sleep(3);
3971                 retries++;
3972         }
3973
3974         if (ret != 0) {
3975                 fprintf(stderr, "Failed to add public IP to node %u."
3976                                 " Giving up\n", ctdb->cmd_pnn);
3977                 return ret;
3978         }
3979
3980         ret = rebalancenode(mem_ctx, ctdb, ctdb->cmd_pnn);
3981         if (ret != 0) {
3982                 return ret;
3983         }
3984
3985         return 0;
3986 }
3987
3988 static int control_delip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
3989                          int argc, const char **argv)
3990 {
3991         ctdb_sock_addr addr;
3992         struct ctdb_public_ip_list *pubip_list;
3993         struct ctdb_addr_info addr_info;
3994         int ret, i;
3995
3996         if (argc != 1) {
3997                 usage("delip");
3998         }
3999
4000         if (! parse_ip(argv[0], NULL, 0, &addr)) {
4001                 fprintf(stderr, "Invalid IP address %s\n", argv[0]);
4002                 return 1;
4003         }
4004
4005         ret = ctdb_ctrl_get_public_ips(mem_ctx, ctdb->ev, ctdb->client,
4006                                        ctdb->cmd_pnn, TIMEOUT(),
4007                                        false, &pubip_list);
4008         if (ret != 0) {
4009                 fprintf(stderr, "Failed to get Public IPs from node %u\n",
4010                         ctdb->cmd_pnn);
4011                 return 1;
4012         }
4013
4014         for (i=0; i<pubip_list->num; i++) {
4015                 if (ctdb_same_ip(&addr, &pubip_list->ip[i].addr)) {
4016                         break;
4017                 }
4018         }
4019
4020         if (i == pubip_list->num) {
4021                 fprintf(stderr, "Node does not know about IP address %s\n",
4022                         ctdb_sock_addr_to_string(mem_ctx, &addr));
4023                 return 0;
4024         }
4025
4026         addr_info.addr = addr;
4027         addr_info.mask = 0;
4028         addr_info.iface = NULL;
4029
4030         ret = ctdb_ctrl_del_public_ip(mem_ctx, ctdb->ev, ctdb->client,
4031                                       ctdb->cmd_pnn, TIMEOUT(), &addr_info);
4032         if (ret != 0) {
4033                 fprintf(stderr, "Failed to delete public IP from node %u\n",
4034                         ctdb->cmd_pnn);
4035                 return ret;
4036         }
4037
4038         return 0;
4039 }
4040
4041 #define DB_VERSION      3
4042 #define MAX_DB_NAME     64
4043 #define MAX_REC_BUFFER_SIZE     (100*1000)
4044
4045 struct db_header {
4046         unsigned long version;
4047         time_t timestamp;
4048         unsigned long flags;
4049         unsigned long nbuf;
4050         unsigned long nrec;
4051         char name[MAX_DB_NAME];
4052 };
4053
4054 struct backup_state {
4055         TALLOC_CTX *mem_ctx;
4056         struct ctdb_rec_buffer *recbuf;
4057         uint32_t db_id;
4058         int fd;
4059         unsigned int nbuf, nrec;
4060 };
4061
4062 static int backup_handler(uint32_t reqid, struct ctdb_ltdb_header *header,
4063                           TDB_DATA key, TDB_DATA data, void *private_data)
4064 {
4065         struct backup_state *state = (struct backup_state *)private_data;
4066         size_t len;
4067         int ret;
4068
4069         if (state->recbuf == NULL) {
4070                 state->recbuf = ctdb_rec_buffer_init(state->mem_ctx,
4071                                                      state->db_id);
4072                 if (state->recbuf == NULL) {
4073                         return ENOMEM;
4074                 }
4075         }
4076
4077         ret = ctdb_rec_buffer_add(state->recbuf, state->recbuf, reqid,
4078                                   header, key, data);
4079         if (ret != 0) {
4080                 return ret;
4081         }
4082
4083         len = ctdb_rec_buffer_len(state->recbuf);
4084         if (len < MAX_REC_BUFFER_SIZE) {
4085                 return 0;
4086         }
4087
4088         ret = ctdb_rec_buffer_write(state->recbuf, state->fd);
4089         if (ret != 0) {
4090                 fprintf(stderr, "Failed to write records to backup file\n");
4091                 return ret;
4092         }
4093
4094         state->nbuf += 1;
4095         state->nrec += state->recbuf->count;
4096         TALLOC_FREE(state->recbuf);
4097
4098         return 0;
4099 }
4100
4101 static int control_backupdb(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4102                             int argc, const char **argv)
4103 {
4104         const char *db_name;
4105         struct ctdb_db_context *db;
4106         uint32_t db_id;
4107         uint8_t db_flags;
4108         struct backup_state state;
4109         struct db_header db_hdr;
4110         int fd, ret;
4111
4112         if (argc != 2) {
4113                 usage("backupdb");
4114         }
4115
4116         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, &db_flags)) {
4117                 return 1;
4118         }
4119
4120         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
4121                           db_flags, &db);
4122         if (ret != 0) {
4123                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
4124                 return ret;
4125         }
4126
4127         fd = open(argv[1], O_RDWR|O_CREAT, 0600);
4128         if (fd == -1) {
4129                 ret = errno;
4130                 fprintf(stderr, "Failed to open file %s for writing\n",
4131                         argv[1]);
4132                 return ret;
4133         }
4134
4135         /* Write empty header first */
4136         ZERO_STRUCT(db_hdr);
4137         ret = write(fd, &db_hdr, sizeof(struct db_header));
4138         if (ret == -1) {
4139                 ret = errno;
4140                 close(fd);
4141                 fprintf(stderr, "Failed to write header to file %s\n", argv[1]);
4142                 return ret;
4143         }
4144
4145         state.mem_ctx = mem_ctx;
4146         state.recbuf = NULL;
4147         state.fd = fd;
4148         state.nbuf = 0;
4149         state.nrec = 0;
4150
4151         ret = ctdb_db_traverse(db, true, false, backup_handler, &state);
4152         if (ret != 0) {
4153                 fprintf(stderr, "Failed to collect records from DB %s\n",
4154                         db_name);
4155                 close(fd);
4156                 return ret;
4157         }
4158
4159         if (state.recbuf != NULL) {
4160                 ret = ctdb_rec_buffer_write(state.recbuf, state.fd);
4161                 if (ret != 0) {
4162                         fprintf(stderr,
4163                                 "Failed to write records to backup file\n");
4164                         close(fd);
4165                         return ret;
4166                 }
4167
4168                 state.nbuf += 1;
4169                 state.nrec += state.recbuf->count;
4170                 TALLOC_FREE(state.recbuf);
4171         }
4172
4173         db_hdr.version = DB_VERSION;
4174         db_hdr.timestamp = time(NULL);
4175         db_hdr.flags = db_flags;
4176         db_hdr.nbuf = state.nbuf;
4177         db_hdr.nrec = state.nrec;
4178         strncpy(db_hdr.name, db_name, MAX_DB_NAME-1);
4179
4180         lseek(fd, 0, SEEK_SET);
4181         ret = write(fd, &db_hdr, sizeof(struct db_header));
4182         if (ret == -1) {
4183                 ret = errno;
4184                 close(fd);
4185                 fprintf(stderr, "Failed to write header to file %s\n", argv[1]);
4186                 return ret;
4187         }
4188
4189         close(fd);
4190         printf("Database backed up to %s\n", argv[1]);
4191         return 0;
4192 }
4193
4194 static int control_restoredb(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4195                              int argc, const char **argv)
4196 {
4197         const char *db_name = NULL;
4198         struct ctdb_db_context *db;
4199         struct db_header db_hdr;
4200         struct ctdb_node_map *nodemap;
4201         struct ctdb_req_control request;
4202         struct ctdb_reply_control **reply;
4203         struct ctdb_transdb wipedb;
4204         struct ctdb_pulldb_ext pulldb;
4205         struct ctdb_rec_buffer *recbuf;
4206         uint32_t generation;
4207         uint32_t *pnn_list;
4208         char timebuf[128];
4209         int fd, i;
4210         int count, ret;
4211
4212         if (argc < 1 || argc > 2) {
4213                 usage("restoredb");
4214         }
4215
4216         fd = open(argv[0], O_RDONLY, 0600);
4217         if (fd == -1) {
4218                 ret = errno;
4219                 fprintf(stderr, "Failed to open file %s for reading\n",
4220                         argv[0]);
4221                 return ret;
4222         }
4223
4224         if (argc == 2) {
4225                 db_name = argv[1];
4226         }
4227
4228         ret = read(fd, &db_hdr, sizeof(struct db_header));
4229         if (ret == -1) {
4230                 ret = errno;
4231                 close(fd);
4232                 fprintf(stderr, "Failed to read db header from file %s\n",
4233                         argv[0]);
4234                 return ret;
4235         }
4236         db_hdr.name[sizeof(db_hdr.name)-1] = '\0';
4237
4238         if (db_hdr.version != DB_VERSION) {
4239                 fprintf(stderr,
4240                         "Wrong version of backup file, expected %u, got %lu\n",
4241                         DB_VERSION, db_hdr.version);
4242                 close(fd);
4243                 return EINVAL;
4244         }
4245
4246         if (db_name == NULL) {
4247                 db_name = db_hdr.name;
4248         }
4249
4250         strftime(timebuf, sizeof(timebuf)-1, "%Y/%m/%d %H:%M:%S",
4251                  localtime(&db_hdr.timestamp));
4252         printf("Restoring database %s from backup @ %s\n", db_name, timebuf);
4253
4254         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
4255                           db_hdr.flags, &db);
4256         if (ret != 0) {
4257                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
4258                 close(fd);
4259                 return ret;
4260         }
4261
4262         nodemap = get_nodemap(ctdb, false);
4263         if (nodemap == NULL) {
4264                 fprintf(stderr, "Failed to get nodemap\n");
4265                 close(fd);
4266                 return ENOMEM;
4267         }
4268
4269         ret = get_generation(mem_ctx, ctdb, &generation);
4270         if (ret != 0) {
4271                 fprintf(stderr, "Failed to get current generation\n");
4272                 close(fd);
4273                 return ret;
4274         }
4275
4276         count = list_of_active_nodes(nodemap, CTDB_UNKNOWN_PNN, mem_ctx,
4277                                      &pnn_list);
4278         if (count <= 0) {
4279                 close(fd);
4280                 return ENOMEM;
4281         }
4282
4283         wipedb.db_id = ctdb_db_id(db);
4284         wipedb.tid = generation;
4285
4286         ctdb_req_control_db_freeze(&request, wipedb.db_id);
4287         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev,
4288                                         ctdb->client, pnn_list, count,
4289                                         TIMEOUT(), &request, NULL, NULL);
4290         if (ret != 0) {
4291                 goto failed;
4292         }
4293
4294
4295         ctdb_req_control_db_transaction_start(&request, &wipedb);
4296         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4297                                         pnn_list, count, TIMEOUT(),
4298                                         &request, NULL, NULL);
4299         if (ret != 0) {
4300                 goto failed;
4301         }
4302
4303         ctdb_req_control_wipe_database(&request, &wipedb);
4304         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4305                                         pnn_list, count, TIMEOUT(),
4306                                         &request, NULL, NULL);
4307         if (ret != 0) {
4308                 goto failed;
4309         }
4310
4311         pulldb.db_id = ctdb_db_id(db);
4312         pulldb.lmaster = 0;
4313         pulldb.srvid = SRVID_CTDB_PUSHDB;
4314
4315         ctdb_req_control_db_push_start(&request, &pulldb);
4316         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4317                                         pnn_list, count, TIMEOUT(),
4318                                         &request, NULL, NULL);
4319         if (ret != 0) {
4320                 goto failed;
4321         }
4322
4323         for (i=0; i<db_hdr.nbuf; i++) {
4324                 struct ctdb_req_message message;
4325                 TDB_DATA data;
4326
4327                 ret = ctdb_rec_buffer_read(fd, mem_ctx, &recbuf);
4328                 if (ret != 0) {
4329                         goto failed;
4330                 }
4331
4332                 data.dsize = ctdb_rec_buffer_len(recbuf);
4333                 data.dptr = talloc_size(mem_ctx, data.dsize);
4334                 if (data.dptr == NULL) {
4335                         goto failed;
4336                 }
4337
4338                 ctdb_rec_buffer_push(recbuf, data.dptr);
4339
4340                 message.srvid = pulldb.srvid;
4341                 message.data.data = data;
4342
4343                 ret = ctdb_client_message_multi(mem_ctx, ctdb->ev,
4344                                                 ctdb->client,
4345                                                 pnn_list, count,
4346                                                 &message, NULL);
4347                 if (ret != 0) {
4348                         goto failed;
4349                 }
4350
4351                 talloc_free(recbuf);
4352                 talloc_free(data.dptr);
4353         }
4354
4355         ctdb_req_control_db_push_confirm(&request, pulldb.db_id);
4356         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4357                                         pnn_list, count, TIMEOUT(),
4358                                         &request, NULL, &reply);
4359         if (ret != 0) {
4360                 goto failed;
4361         }
4362
4363         for (i=0; i<count; i++) {
4364                 uint32_t num_records;
4365
4366                 ret = ctdb_reply_control_db_push_confirm(reply[i],
4367                                                          &num_records);
4368                 if (ret != 0) {
4369                         fprintf(stderr, "Invalid response from node %u\n",
4370                                 pnn_list[i]);
4371                         goto failed;
4372                 }
4373
4374                 if (num_records != db_hdr.nrec) {
4375                         fprintf(stderr, "Node %u received %u of %lu records\n",
4376                                 pnn_list[i], num_records, db_hdr.nrec);
4377                         goto failed;
4378                 }
4379         }
4380
4381         ctdb_req_control_db_set_healthy(&request, wipedb.db_id);
4382         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4383                                         pnn_list, count, TIMEOUT(),
4384                                         &request, NULL, NULL);
4385         if (ret != 0) {
4386                 goto failed;
4387         }
4388
4389         ctdb_req_control_db_transaction_commit(&request, &wipedb);
4390         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4391                                         pnn_list, count, TIMEOUT(),
4392                                         &request, NULL, NULL);
4393         if (ret != 0) {
4394                 goto failed;
4395         }
4396
4397         ctdb_req_control_db_thaw(&request, wipedb.db_id);
4398         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev,
4399                                         ctdb->client, pnn_list, count,
4400                                         TIMEOUT(), &request, NULL, NULL);
4401         if (ret != 0) {
4402                 goto failed;
4403         }
4404
4405         printf("Database %s restored\n", db_name);
4406         return 0;
4407
4408
4409 failed:
4410         close(fd);
4411         ctdb_ctrl_set_recmode(mem_ctx, ctdb->ev, ctdb->client,
4412                               ctdb->pnn, TIMEOUT(), CTDB_RECOVERY_ACTIVE);
4413         return ret;
4414 }
4415
4416 struct dumpdbbackup_state {
4417         ctdb_rec_parser_func_t parser;
4418         struct dump_record_state sub_state;
4419 };
4420
4421 static int dumpdbbackup_handler(uint32_t reqid,
4422                                 struct ctdb_ltdb_header *header,
4423                                 TDB_DATA key, TDB_DATA data,
4424                                 void *private_data)
4425 {
4426         struct dumpdbbackup_state *state =
4427                 (struct dumpdbbackup_state *)private_data;
4428         struct ctdb_ltdb_header hdr;
4429         int ret;
4430
4431         ret = ctdb_ltdb_header_extract(&data, &hdr);
4432         if (ret != 0) {
4433                 return ret;
4434         }
4435
4436         return state->parser(reqid, &hdr, key, data, &state->sub_state);
4437 }
4438
4439 static int control_dumpdbbackup(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4440                                 int argc, const char **argv)
4441 {
4442         struct db_header db_hdr;
4443         char timebuf[128];
4444         struct dumpdbbackup_state state;
4445         int fd, ret, i;
4446
4447         if (argc != 1) {
4448                 usage("dumpbackup");
4449         }
4450
4451         fd = open(argv[0], O_RDONLY, 0600);
4452         if (fd == -1) {
4453                 ret = errno;
4454                 fprintf(stderr, "Failed to open file %s for reading\n",
4455                         argv[0]);
4456                 return ret;
4457         }
4458
4459         ret = read(fd, &db_hdr, sizeof(struct db_header));
4460         if (ret == -1) {
4461                 ret = errno;
4462                 close(fd);
4463                 fprintf(stderr, "Failed to read db header from file %s\n",
4464                         argv[0]);
4465                 return ret;
4466         }
4467         db_hdr.name[sizeof(db_hdr.name)-1] = '\0';
4468
4469         if (db_hdr.version != DB_VERSION) {
4470                 fprintf(stderr,
4471                         "Wrong version of backup file, expected %u, got %lu\n",
4472                         DB_VERSION, db_hdr.version);
4473                 close(fd);
4474                 return EINVAL;
4475         }
4476
4477         strftime(timebuf, sizeof(timebuf)-1, "%Y/%m/%d %H:%M:%S",
4478                  localtime(&db_hdr.timestamp));
4479         printf("Dumping database %s from backup @ %s\n",
4480                db_hdr.name, timebuf);
4481
4482         state.parser = dump_record;
4483         state.sub_state.count = 0;
4484
4485         for (i=0; i<db_hdr.nbuf; i++) {
4486                 struct ctdb_rec_buffer *recbuf;
4487
4488                 ret = ctdb_rec_buffer_read(fd, mem_ctx, &recbuf);
4489                 if (ret != 0) {
4490                         fprintf(stderr, "Failed to read records\n");
4491                         close(fd);
4492                         return ret;
4493                 }
4494
4495                 ret = ctdb_rec_buffer_traverse(recbuf, dumpdbbackup_handler,
4496                                                &state);
4497                 if (ret != 0) {
4498                         fprintf(stderr, "Failed to dump records\n");
4499                         close(fd);
4500                         return ret;
4501                 }
4502         }
4503
4504         close(fd);
4505         printf("Dumped %u record(s)\n", state.sub_state.count);
4506         return 0;
4507 }
4508
4509 static int control_wipedb(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4510                           int argc, const char **argv)
4511 {
4512         const char *db_name;
4513         struct ctdb_db_context *db;
4514         uint32_t db_id;
4515         uint8_t db_flags;
4516         struct ctdb_node_map *nodemap;
4517         struct ctdb_req_control request;
4518         struct ctdb_transdb wipedb;
4519         uint32_t generation;
4520         uint32_t *pnn_list;
4521         int count, ret;
4522
4523         if (argc != 1) {
4524                 usage("wipedb");
4525         }
4526
4527         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, &db_flags)) {
4528                 return 1;
4529         }
4530
4531         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
4532                           db_flags, &db);
4533         if (ret != 0) {
4534                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
4535                 return ret;
4536         }
4537
4538         nodemap = get_nodemap(ctdb, false);
4539         if (nodemap == NULL) {
4540                 fprintf(stderr, "Failed to get nodemap\n");
4541                 return ENOMEM;
4542         }
4543
4544         ret = get_generation(mem_ctx, ctdb, &generation);
4545         if (ret != 0) {
4546                 fprintf(stderr, "Failed to get current generation\n");
4547                 return ret;
4548         }
4549
4550         count = list_of_active_nodes(nodemap, CTDB_UNKNOWN_PNN, mem_ctx,
4551                                      &pnn_list);
4552         if (count <= 0) {
4553                 return ENOMEM;
4554         }
4555
4556         ctdb_req_control_db_freeze(&request, db_id);
4557         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev,
4558                                         ctdb->client, pnn_list, count,
4559                                         TIMEOUT(), &request, NULL, NULL);
4560         if (ret != 0) {
4561                 goto failed;
4562         }
4563
4564         wipedb.db_id = db_id;
4565         wipedb.tid = generation;
4566
4567         ctdb_req_control_db_transaction_start(&request, &wipedb);
4568         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4569                                         pnn_list, count, TIMEOUT(),
4570                                         &request, NULL, NULL);
4571         if (ret != 0) {
4572                 goto failed;
4573         }
4574
4575         ctdb_req_control_wipe_database(&request, &wipedb);
4576         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4577                                         pnn_list, count, TIMEOUT(),
4578                                         &request, NULL, NULL);
4579         if (ret != 0) {
4580                 goto failed;
4581         }
4582
4583         ctdb_req_control_db_set_healthy(&request, db_id);
4584         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4585                                         pnn_list, count, TIMEOUT(),
4586                                         &request, NULL, NULL);
4587         if (ret != 0) {
4588                 goto failed;
4589         }
4590
4591         ctdb_req_control_db_transaction_commit(&request, &wipedb);
4592         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
4593                                         pnn_list, count, TIMEOUT(),
4594                                         &request, NULL, NULL);
4595         if (ret != 0) {
4596                 goto failed;
4597         }
4598
4599         ctdb_req_control_db_thaw(&request, db_id);
4600         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev,
4601                                         ctdb->client, pnn_list, count,
4602                                         TIMEOUT(), &request, NULL, NULL);
4603         if (ret != 0) {
4604                 goto failed;
4605         }
4606
4607         printf("Database %s wiped\n", db_name);
4608         return 0;
4609
4610
4611 failed:
4612         ctdb_ctrl_set_recmode(mem_ctx, ctdb->ev, ctdb->client,
4613                               ctdb->pnn, TIMEOUT(), CTDB_RECOVERY_ACTIVE);
4614         return ret;
4615 }
4616
4617 static int control_recmaster(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4618                              int argc, const char **argv)
4619 {
4620         uint32_t recmaster;
4621         int ret;
4622
4623         ret = ctdb_ctrl_get_recmaster(mem_ctx, ctdb->ev, ctdb->client,
4624                                       ctdb->cmd_pnn, TIMEOUT(), &recmaster);
4625         if (ret != 0) {
4626                 return ret;
4627         }
4628
4629         printf("%u\n", recmaster);
4630         return 0;
4631 }
4632
4633 static int control_event(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4634                          int argc, const char **argv)
4635 {
4636         char *t, *event_helper = NULL;
4637         char *eventd_socket = NULL;
4638         const char **new_argv;
4639         int i;
4640
4641         t = getenv("CTDB_EVENT_HELPER");
4642         if (t != NULL) {
4643                 event_helper = talloc_strdup(mem_ctx, t);
4644         } else {
4645                 event_helper = talloc_asprintf(mem_ctx, "%s/ctdb_event",
4646                                                CTDB_HELPER_BINDIR);
4647         }
4648
4649         if (event_helper == NULL) {
4650                 fprintf(stderr, "Unable to set event daemon helper\n");
4651                 return 1;
4652         }
4653
4654         t = getenv("CTDB_SOCKET");
4655         if (t != NULL) {
4656                 eventd_socket = talloc_asprintf(mem_ctx, "%s/eventd.sock",
4657                                                 dirname(t));
4658         } else {
4659                 eventd_socket = talloc_asprintf(mem_ctx, "%s/eventd.sock",
4660                                                 CTDB_RUNDIR);
4661         }
4662
4663         if (eventd_socket == NULL) {
4664                 fprintf(stderr, "Unable to set event daemon socket\n");
4665                 return 1;
4666         }
4667
4668         new_argv = talloc_array(mem_ctx, const char *, argc + 1);
4669         if (new_argv == NULL) {
4670                 fprintf(stderr, "Memory allocation error\n");
4671                 return 1;
4672         }
4673
4674         new_argv[0] = eventd_socket;
4675         for (i=0; i<argc; i++) {
4676                 new_argv[i+1] = argv[i];
4677         }
4678
4679         return run_helper(mem_ctx, "event daemon helper", event_helper,
4680                           argc+1, new_argv);
4681 }
4682
4683 static int control_scriptstatus(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4684                                 int argc, const char **argv)
4685 {
4686         const char *new_argv[3];
4687
4688         if (argc > 1) {
4689                 usage("scriptstatus");
4690         }
4691
4692         new_argv[0] = "status";
4693         new_argv[1] = (argc == 0) ? "monitor" : argv[0];
4694         new_argv[2] = NULL;
4695
4696         (void) control_event(mem_ctx, ctdb, 2, new_argv);
4697         return 0;
4698 }
4699
4700 static int control_natgw(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4701                          int argc, const char **argv)
4702 {
4703         char *t, *natgw_helper = NULL;
4704
4705         if (argc != 1) {
4706                 usage("natgw");
4707         }
4708
4709         t = getenv("CTDB_NATGW_HELPER");
4710         if (t != NULL) {
4711                 natgw_helper = talloc_strdup(mem_ctx, t);
4712         } else {
4713                 natgw_helper = talloc_asprintf(mem_ctx, "%s/ctdb_natgw",
4714                                                CTDB_HELPER_BINDIR);
4715         }
4716
4717         if (natgw_helper == NULL) {
4718                 fprintf(stderr, "Unable to set NAT gateway helper\n");
4719                 return 1;
4720         }
4721
4722         return run_helper(mem_ctx, "NAT gateway helper", natgw_helper,
4723                           argc, argv);
4724 }
4725
4726 static int control_natgwlist(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4727                              int argc, const char **argv)
4728 {
4729         char *t, *natgw_helper = NULL;
4730         const char *cmd_argv[] = { "natgwlist", NULL };
4731
4732         if (argc != 0) {
4733                 usage("natgwlist");
4734         }
4735
4736         t = getenv("CTDB_NATGW_HELPER");
4737         if (t != NULL) {
4738                 natgw_helper = talloc_strdup(mem_ctx, t);
4739         } else {
4740                 natgw_helper = talloc_asprintf(mem_ctx, "%s/ctdb_natgw",
4741                                                CTDB_HELPER_BINDIR);
4742         }
4743
4744         if (natgw_helper == NULL) {
4745                 fprintf(stderr, "Unable to set NAT gateway helper\n");
4746                 return 1;
4747         }
4748
4749         return run_helper(mem_ctx, "NAT gateway helper", natgw_helper,
4750                           1, cmd_argv);
4751 }
4752
4753 /*
4754  * Find the PNN of the current node
4755  * discover the pnn by loading the nodes file and try to bind
4756  * to all addresses one at a time until the ip address is found.
4757  */
4758 static bool find_node_xpnn(TALLOC_CTX *mem_ctx, uint32_t *pnn)
4759 {
4760         struct ctdb_node_map *nodemap;
4761         int i;
4762
4763         nodemap = read_nodes_file(mem_ctx, CTDB_UNKNOWN_PNN);
4764         if (nodemap == NULL) {
4765                 return false;
4766         }
4767
4768         for (i=0; i<nodemap->num; i++) {
4769                 if (nodemap->node[i].flags & NODE_FLAGS_DELETED) {
4770                         continue;
4771                 }
4772                 if (ctdb_sys_have_ip(&nodemap->node[i].addr)) {
4773                         if (pnn != NULL) {
4774                                 *pnn = nodemap->node[i].pnn;
4775                         }
4776                         talloc_free(nodemap);
4777                         return true;
4778                 }
4779         }
4780
4781         fprintf(stderr, "Failed to detect PNN of the current node.\n");
4782         talloc_free(nodemap);
4783         return false;
4784 }
4785
4786 static int control_getreclock(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4787                               int argc, const char **argv)
4788 {
4789         const char *reclock;
4790         int ret;
4791
4792         if (argc != 0) {
4793                 usage("getreclock");
4794         }
4795
4796         ret = ctdb_ctrl_get_reclock_file(mem_ctx, ctdb->ev, ctdb->client,
4797                                          ctdb->cmd_pnn, TIMEOUT(), &reclock);
4798         if (ret != 0) {
4799                 return ret;
4800         }
4801
4802         if (reclock != NULL) {
4803                 printf("%s\n", reclock);
4804         }
4805
4806         return 0;
4807 }
4808
4809 static int control_setlmasterrole(TALLOC_CTX *mem_ctx,
4810                                   struct ctdb_context *ctdb,
4811                                   int argc, const char **argv)
4812 {
4813         uint32_t lmasterrole = 0;
4814         int ret;
4815
4816         if (argc != 1) {
4817                 usage("setlmasterrole");
4818         }
4819
4820         if (strcmp(argv[0], "on") == 0) {
4821                 lmasterrole = 1;
4822         } else if (strcmp(argv[0], "off") == 0) {
4823                 lmasterrole = 0;
4824         } else {
4825                 usage("setlmasterrole");
4826         }
4827
4828         ret = ctdb_ctrl_set_lmasterrole(mem_ctx, ctdb->ev, ctdb->client,
4829                                         ctdb->cmd_pnn, TIMEOUT(), lmasterrole);
4830         if (ret != 0) {
4831                 return ret;
4832         }
4833
4834         return 0;
4835 }
4836
4837 static int control_setrecmasterrole(TALLOC_CTX *mem_ctx,
4838                                     struct ctdb_context *ctdb,
4839                                     int argc, const char **argv)
4840 {
4841         uint32_t recmasterrole = 0;
4842         int ret;
4843
4844         if (argc != 1) {
4845                 usage("setrecmasterrole");
4846         }
4847
4848         if (strcmp(argv[0], "on") == 0) {
4849                 recmasterrole = 1;
4850         } else if (strcmp(argv[0], "off") == 0) {
4851                 recmasterrole = 0;
4852         } else {
4853                 usage("setrecmasterrole");
4854         }
4855
4856         ret = ctdb_ctrl_set_recmasterrole(mem_ctx, ctdb->ev, ctdb->client,
4857                                           ctdb->cmd_pnn, TIMEOUT(),
4858                                           recmasterrole);
4859         if (ret != 0) {
4860                 return ret;
4861         }
4862
4863         return 0;
4864 }
4865
4866 static int control_setdbreadonly(TALLOC_CTX *mem_ctx,
4867                                  struct ctdb_context *ctdb,
4868                                  int argc, const char **argv)
4869 {
4870         uint32_t db_id;
4871         uint8_t db_flags;
4872         int ret;
4873
4874         if (argc != 1) {
4875                 usage("setdbreadonly");
4876         }
4877
4878         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, NULL, &db_flags)) {
4879                 return 1;
4880         }
4881
4882         if (db_flags & CTDB_DB_FLAGS_PERSISTENT) {
4883                 fprintf(stderr, "Cannot set READONLY on persistent DB\n");
4884                 return 1;
4885         }
4886
4887         ret = ctdb_ctrl_set_db_readonly(mem_ctx, ctdb->ev, ctdb->client,
4888                                         ctdb->cmd_pnn, TIMEOUT(), db_id);
4889         if (ret != 0) {
4890                 return ret;
4891         }
4892
4893         return 0;
4894 }
4895
4896 static int control_setdbsticky(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4897                                int argc, const char **argv)
4898 {
4899         uint32_t db_id;
4900         uint8_t db_flags;
4901         int ret;
4902
4903         if (argc != 1) {
4904                 usage("setdbsticky");
4905         }
4906
4907         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, NULL, &db_flags)) {
4908                 return 1;
4909         }
4910
4911         if (db_flags & CTDB_DB_FLAGS_PERSISTENT) {
4912                 fprintf(stderr, "Cannot set STICKY on persistent DB\n");
4913                 return 1;
4914         }
4915
4916         ret = ctdb_ctrl_set_db_sticky(mem_ctx, ctdb->ev, ctdb->client,
4917                                       ctdb->cmd_pnn, TIMEOUT(), db_id);
4918         if (ret != 0) {
4919                 return ret;
4920         }
4921
4922         return 0;
4923 }
4924
4925 static int control_pfetch(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4926                           int argc, const char **argv)
4927 {
4928         const char *db_name;
4929         struct ctdb_db_context *db;
4930         struct ctdb_transaction_handle *h;
4931         uint8_t db_flags;
4932         TDB_DATA key, data;
4933         int ret;
4934
4935         if (argc < 2 || argc > 3) {
4936                 usage("pfetch");
4937         }
4938
4939         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
4940                 return 1;
4941         }
4942
4943         if (! (db_flags & CTDB_DB_FLAGS_PERSISTENT)) {
4944                 fprintf(stderr, "DB %s is not a persistent database\n",
4945                         db_name);
4946                 return 1;
4947         }
4948
4949         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
4950                           db_flags, &db);
4951         if (ret != 0) {
4952                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
4953                 return ret;
4954         }
4955
4956         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
4957         if (ret != 0) {
4958                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
4959                 return ret;
4960         }
4961
4962         ret = ctdb_transaction_start(mem_ctx, ctdb->ev, ctdb->client,
4963                                      TIMEOUT(), db, true, &h);
4964         if (ret != 0) {
4965                 fprintf(stderr, "Failed to start transaction on db %s\n",
4966                         db_name);
4967                 return ret;
4968         }
4969
4970         ret = ctdb_transaction_fetch_record(h, key, mem_ctx, &data);
4971         if (ret != 0) {
4972                 fprintf(stderr, "Failed to read record for key %s\n",
4973                         argv[1]);
4974                 ctdb_transaction_cancel(h);
4975                 return ret;
4976         }
4977
4978         printf("%.*s\n", (int)data.dsize, data.dptr);
4979
4980         ctdb_transaction_cancel(h);
4981         return 0;
4982 }
4983
4984 static int control_pstore(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
4985                           int argc, const char **argv)
4986 {
4987         const char *db_name;
4988         struct ctdb_db_context *db;
4989         struct ctdb_transaction_handle *h;
4990         uint8_t db_flags;
4991         TDB_DATA key, data;
4992         int ret;
4993
4994         if (argc != 3) {
4995                 usage("pstore");
4996         }
4997
4998         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
4999                 return 1;
5000         }
5001
5002         if (! (db_flags & CTDB_DB_FLAGS_PERSISTENT)) {
5003                 fprintf(stderr, "DB %s is not a persistent database\n",
5004                         db_name);
5005                 return 1;
5006         }
5007
5008         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
5009                           db_flags, &db);
5010         if (ret != 0) {
5011                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
5012                 return ret;
5013         }
5014
5015         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5016         if (ret != 0) {
5017                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5018                 return ret;
5019         }
5020
5021         ret = str_to_data(argv[2], strlen(argv[2]), mem_ctx, &data);
5022         if (ret != 0) {
5023                 fprintf(stderr, "Failed to parse value %s\n", argv[2]);
5024                 return ret;
5025         }
5026
5027         ret = ctdb_transaction_start(mem_ctx, ctdb->ev, ctdb->client,
5028                                      TIMEOUT(), db, false, &h);
5029         if (ret != 0) {
5030                 fprintf(stderr, "Failed to start transaction on db %s\n",
5031                         db_name);
5032                 return ret;
5033         }
5034
5035         ret = ctdb_transaction_store_record(h, key, data);
5036         if (ret != 0) {
5037                 fprintf(stderr, "Failed to store record for key %s\n",
5038                         argv[1]);
5039                 ctdb_transaction_cancel(h);
5040                 return ret;
5041         }
5042
5043         ret = ctdb_transaction_commit(h);
5044         if (ret != 0) {
5045                 fprintf(stderr, "Failed to commit transaction on db %s\n",
5046                         db_name);
5047                 ctdb_transaction_cancel(h);
5048                 return ret;
5049         }
5050
5051         return 0;
5052 }
5053
5054 static int control_pdelete(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5055                            int argc, const char **argv)
5056 {
5057         const char *db_name;
5058         struct ctdb_db_context *db;
5059         struct ctdb_transaction_handle *h;
5060         uint8_t db_flags;
5061         TDB_DATA key;
5062         int ret;
5063
5064         if (argc != 2) {
5065                 usage("pdelete");
5066         }
5067
5068         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
5069                 return 1;
5070         }
5071
5072         if (! (db_flags & CTDB_DB_FLAGS_PERSISTENT)) {
5073                 fprintf(stderr, "DB %s is not a persistent database\n",
5074                         db_name);
5075                 return 1;
5076         }
5077
5078         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
5079                           db_flags, &db);
5080         if (ret != 0) {
5081                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
5082                 return ret;
5083         }
5084
5085         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5086         if (ret != 0) {
5087                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5088                 return ret;
5089         }
5090
5091         ret = ctdb_transaction_start(mem_ctx, ctdb->ev, ctdb->client,
5092                                      TIMEOUT(), db, false, &h);
5093         if (ret != 0) {
5094                 fprintf(stderr, "Failed to start transaction on db %s\n",
5095                         db_name);
5096                 return ret;
5097         }
5098
5099         ret = ctdb_transaction_delete_record(h, key);
5100         if (ret != 0) {
5101                 fprintf(stderr, "Failed to delete record for key %s\n",
5102                         argv[1]);
5103                 ctdb_transaction_cancel(h);
5104                 return ret;
5105         }
5106
5107         ret = ctdb_transaction_commit(h);
5108         if (ret != 0) {
5109                 fprintf(stderr, "Failed to commit transaction on db %s\n",
5110                         db_name);
5111                 ctdb_transaction_cancel(h);
5112                 return ret;
5113         }
5114
5115         return 0;
5116 }
5117
5118 static int ptrans_parse_string(TALLOC_CTX *mem_ctx, const char **ptr, TDB_DATA *data)
5119 {
5120         const char *t;
5121         size_t n;
5122         int ret;
5123
5124         *data = tdb_null;
5125
5126         /* Skip whitespace */
5127         n = strspn(*ptr, " \t");
5128         t = *ptr + n;
5129
5130         if (t[0] == '"') {
5131                 /* Quoted ASCII string - no wide characters! */
5132                 t++;
5133                 n = strcspn(t, "\"");
5134                 if (t[n] == '"') {
5135                         if (n > 0) {
5136                                 ret = str_to_data(t, n, mem_ctx, data);
5137                                 if (ret != 0) {
5138                                         return ret;
5139                                 }
5140                         }
5141                         *ptr = t + n + 1;
5142                 } else {
5143                         fprintf(stderr, "Unmatched \" in input %s\n", *ptr);
5144                         return 1;
5145                 }
5146         } else {
5147                 fprintf(stderr, "Unsupported input format in %s\n", *ptr);
5148                 return 1;
5149         }
5150
5151         return 0;
5152 }
5153
5154 #define MAX_LINE_SIZE   1024
5155
5156 static bool ptrans_get_key_value(TALLOC_CTX *mem_ctx, FILE *file,
5157                                  TDB_DATA *key, TDB_DATA *value)
5158 {
5159         char line [MAX_LINE_SIZE]; /* FIXME: make this more flexible? */
5160         const char *ptr;
5161         int ret;
5162
5163         ptr = fgets(line, MAX_LINE_SIZE, file);
5164         if (ptr == NULL) {
5165                 return false;
5166         }
5167
5168         /* Get key */
5169         ret = ptrans_parse_string(mem_ctx, &ptr, key);
5170         if (ret != 0 || ptr == NULL || key->dptr == NULL) {
5171                 /* Line Ignored but not EOF */
5172                 *key = tdb_null;
5173                 return true;
5174         }
5175
5176         /* Get value */
5177         ret = ptrans_parse_string(mem_ctx, &ptr, value);
5178         if (ret != 0) {
5179                 /* Line Ignored but not EOF */
5180                 talloc_free(key->dptr);
5181                 *key = tdb_null;
5182                 return true;
5183         }
5184
5185         return true;
5186 }
5187
5188 static int control_ptrans(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5189                           int argc, const char **argv)
5190 {
5191         const char *db_name;
5192         struct ctdb_db_context *db;
5193         struct ctdb_transaction_handle *h;
5194         uint8_t db_flags;
5195         FILE *file;
5196         TDB_DATA key, value;
5197         int ret;
5198
5199         if (argc < 1 || argc > 2) {
5200                 usage("ptrans");
5201         }
5202
5203         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
5204                 return 1;
5205         }
5206
5207         if (! (db_flags & CTDB_DB_FLAGS_PERSISTENT)) {
5208                 fprintf(stderr, "DB %s is not a persistent database\n",
5209                         db_name);
5210                 return 1;
5211         }
5212
5213         if (argc == 2) {
5214                 file = fopen(argv[1], "r");
5215                 if (file == NULL) {
5216                         fprintf(stderr, "Failed to open file %s\n", argv[1]);
5217                         return 1;
5218                 }
5219         } else {
5220                 file = stdin;
5221         }
5222
5223         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
5224                           db_flags, &db);
5225         if (ret != 0) {
5226                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
5227                 goto done;
5228         }
5229
5230         ret = ctdb_transaction_start(mem_ctx, ctdb->ev, ctdb->client,
5231                                      TIMEOUT(), db, false, &h);
5232         if (ret != 0) {
5233                 fprintf(stderr, "Failed to start transaction on db %s\n",
5234                         db_name);
5235                 goto done;
5236         }
5237
5238         while (ptrans_get_key_value(mem_ctx, file, &key, &value)) {
5239                 if (key.dsize != 0) {
5240                         ret = ctdb_transaction_store_record(h, key, value);
5241                         if (ret != 0) {
5242                                 fprintf(stderr, "Failed to store record\n");
5243                                 ctdb_transaction_cancel(h);
5244                                 goto done;
5245                         }
5246                         talloc_free(key.dptr);
5247                         talloc_free(value.dptr);
5248                 }
5249         }
5250
5251         ret = ctdb_transaction_commit(h);
5252         if (ret != 0) {
5253                 fprintf(stderr, "Failed to commit transaction on db %s\n",
5254                         db_name);
5255                 ctdb_transaction_cancel(h);
5256         }
5257
5258 done:
5259         if (file != stdin) {
5260                 fclose(file);
5261         }
5262         return ret;
5263 }
5264
5265 static int control_tfetch(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5266                           int argc, const char **argv)
5267 {
5268         struct tdb_context *tdb;
5269         TDB_DATA key, data;
5270         struct ctdb_ltdb_header header;
5271         int ret;
5272
5273         if (argc < 2 || argc > 3) {
5274                 usage("tfetch");
5275         }
5276
5277         tdb = tdb_open(argv[0], 0, 0, O_RDWR, 0);
5278         if (tdb == NULL) {
5279                 fprintf(stderr, "Failed to open TDB file %s\n", argv[0]);
5280                 return 1;
5281         }
5282
5283         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5284         if (ret != 0) {
5285                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5286                 tdb_close(tdb);
5287                 return ret;
5288         }
5289
5290         data = tdb_fetch(tdb, key);
5291         if (data.dptr == NULL) {
5292                 fprintf(stderr, "No record for key %s\n", argv[1]);
5293                 tdb_close(tdb);
5294                 return 1;
5295         }
5296
5297         if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
5298                 fprintf(stderr, "Invalid record for key %s\n", argv[1]);
5299                 tdb_close(tdb);
5300                 return 1;
5301         }
5302
5303         tdb_close(tdb);
5304
5305         if (argc == 3) {
5306                 int fd;
5307                 ssize_t nwritten;
5308
5309                 fd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0600);
5310                 if (fd == -1) {
5311                         fprintf(stderr, "Failed to open output file %s\n",
5312                                 argv[2]);
5313                         goto fail;
5314                 }
5315
5316                 nwritten = sys_write(fd, data.dptr, data.dsize);
5317                 if (nwritten != data.dsize) {
5318                         fprintf(stderr, "Failed to write record to file\n");
5319                         close(fd);
5320                         goto fail;
5321                 }
5322
5323                 close(fd);
5324         }
5325
5326 fail:
5327         ret = ctdb_ltdb_header_extract(&data, &header);
5328         if (ret != 0) {
5329                 fprintf(stderr, "Failed to parse header from data\n");
5330                 return 1;
5331         }
5332
5333         dump_ltdb_header(&header);
5334         dump_tdb_data("data", data);
5335
5336         return 0;
5337 }
5338
5339 static int control_tstore(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5340                           int argc, const char **argv)
5341 {
5342         struct tdb_context *tdb;
5343         TDB_DATA key, data[2], value;
5344         struct ctdb_ltdb_header header;
5345         uint8_t header_buf[sizeof(struct ctdb_ltdb_header)];
5346         int ret;
5347
5348         if (argc < 3 || argc > 5) {
5349                 usage("tstore");
5350         }
5351
5352         tdb = tdb_open(argv[0], 0, 0, O_RDWR, 0);
5353         if (tdb == NULL) {
5354                 fprintf(stderr, "Failed to open TDB file %s\n", argv[0]);
5355                 return 1;
5356         }
5357
5358         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5359         if (ret != 0) {
5360                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5361                 tdb_close(tdb);
5362                 return ret;
5363         }
5364
5365         ret = str_to_data(argv[2], strlen(argv[2]), mem_ctx, &value);
5366         if (ret != 0) {
5367                 fprintf(stderr, "Failed to parse value %s\n", argv[2]);
5368                 tdb_close(tdb);
5369                 return ret;
5370         }
5371
5372         ZERO_STRUCT(header);
5373
5374         if (argc > 3) {
5375                 header.rsn = (uint64_t)strtoull(argv[3], NULL, 0);
5376         }
5377         if (argc > 4) {
5378                 header.dmaster = (uint32_t)atol(argv[4]);
5379         }
5380         if (argc > 5) {
5381                 header.flags = (uint32_t)atol(argv[5]);
5382         }
5383
5384         ctdb_ltdb_header_push(&header, header_buf);
5385
5386         data[0].dsize = ctdb_ltdb_header_len(&header);
5387         data[0].dptr = header_buf;
5388
5389         data[1].dsize = value.dsize;
5390         data[1].dptr = value.dptr;
5391
5392         ret = tdb_storev(tdb, key, data, 2, TDB_REPLACE);
5393         if (ret != 0) {
5394                 fprintf(stderr, "Failed to write record %s to file %s\n",
5395                         argv[1], argv[0]);
5396         }
5397
5398         tdb_close(tdb);
5399
5400         return ret;
5401 }
5402
5403 static int control_readkey(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5404                            int argc, const char **argv)
5405 {
5406         const char *db_name;
5407         struct ctdb_db_context *db;
5408         struct ctdb_record_handle *h;
5409         uint8_t db_flags;
5410         TDB_DATA key, data;
5411         bool readonly = false;
5412         int ret;
5413
5414         if (argc < 2 || argc > 3) {
5415                 usage("readkey");
5416         }
5417
5418         if (argc == 3) {
5419                 if (strcmp(argv[2], "readonly") == 0) {
5420                         readonly = true;
5421                 } else {
5422                         usage("readkey");
5423                 }
5424         }
5425
5426         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
5427                 return 1;
5428         }
5429
5430         if (db_flags & CTDB_DB_FLAGS_PERSISTENT) {
5431                 fprintf(stderr, "DB %s is not a volatile database\n",
5432                         db_name);
5433                 return 1;
5434         }
5435
5436         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
5437                           db_flags, &db);
5438         if (ret != 0) {
5439                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
5440                 return ret;
5441         }
5442
5443         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5444         if (ret != 0) {
5445                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5446                 return ret;
5447         }
5448
5449         ret = ctdb_fetch_lock(mem_ctx, ctdb->ev, ctdb->client,
5450                               db, key, readonly, &h, NULL, &data);
5451         if (ret != 0) {
5452                 fprintf(stderr, "Failed to read record for key %s\n",
5453                         argv[1]);
5454         } else {
5455                 printf("Data: size:%zu ptr:[%.*s]\n", data.dsize,
5456                        (int)data.dsize, data.dptr);
5457         }
5458
5459         talloc_free(h);
5460         return ret;
5461 }
5462
5463 static int control_writekey(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5464                             int argc, const char **argv)
5465 {
5466         const char *db_name;
5467         struct ctdb_db_context *db;
5468         struct ctdb_record_handle *h;
5469         uint8_t db_flags;
5470         TDB_DATA key, data;
5471         int ret;
5472
5473         if (argc != 3) {
5474                 usage("writekey");
5475         }
5476
5477         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
5478                 return 1;
5479         }
5480
5481         if (db_flags & CTDB_DB_FLAGS_PERSISTENT) {
5482                 fprintf(stderr, "DB %s is not a volatile database\n",
5483                         db_name);
5484                 return 1;
5485         }
5486
5487         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
5488                           db_flags, &db);
5489         if (ret != 0) {
5490                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
5491                 return ret;
5492         }
5493
5494         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5495         if (ret != 0) {
5496                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5497                 return ret;
5498         }
5499
5500         ret = str_to_data(argv[2], strlen(argv[2]), mem_ctx, &data);
5501         if (ret != 0) {
5502                 fprintf(stderr, "Failed to parse value %s\n", argv[2]);
5503                 return ret;
5504         }
5505
5506         ret = ctdb_fetch_lock(mem_ctx, ctdb->ev, ctdb->client,
5507                               db, key, false, &h, NULL, NULL);
5508         if (ret != 0) {
5509                 fprintf(stderr, "Failed to lock record for key %s\n", argv[0]);
5510                 return ret;
5511         }
5512
5513         ret = ctdb_store_record(h, data);
5514         if (ret != 0) {
5515                 fprintf(stderr, "Failed to store record for key %s\n",
5516                         argv[1]);
5517         }
5518
5519         talloc_free(h);
5520         return ret;
5521 }
5522
5523 static int control_deletekey(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5524                              int argc, const char **argv)
5525 {
5526         const char *db_name;
5527         struct ctdb_db_context *db;
5528         struct ctdb_record_handle *h;
5529         uint8_t db_flags;
5530         TDB_DATA key, data;
5531         int ret;
5532
5533         if (argc != 2) {
5534                 usage("deletekey");
5535         }
5536
5537         if (! db_exists(mem_ctx, ctdb, argv[0], NULL, &db_name, &db_flags)) {
5538                 return 1;
5539         }
5540
5541         if (db_flags & CTDB_DB_FLAGS_PERSISTENT) {
5542                 fprintf(stderr, "DB %s is not a volatile database\n",
5543                         db_name);
5544                 return 1;
5545         }
5546
5547         ret = ctdb_attach(ctdb->ev, ctdb->client, TIMEOUT(), db_name,
5548                           db_flags, &db);
5549         if (ret != 0) {
5550                 fprintf(stderr, "Failed to attach to DB %s\n", db_name);
5551                 return ret;
5552         }
5553
5554         ret = str_to_data(argv[1], strlen(argv[1]), mem_ctx, &key);
5555         if (ret != 0) {
5556                 fprintf(stderr, "Failed to parse key %s\n", argv[1]);
5557                 return ret;
5558         }
5559
5560         ret = ctdb_fetch_lock(mem_ctx, ctdb->ev, ctdb->client,
5561                               db, key, false, &h, NULL, &data);
5562         if (ret != 0) {
5563                 fprintf(stderr, "Failed to fetch record for key %s\n",
5564                         argv[1]);
5565                 return ret;
5566         }
5567
5568         ret = ctdb_delete_record(h);
5569         if (ret != 0) {
5570                 fprintf(stderr, "Failed to delete record for key %s\n",
5571                         argv[1]);
5572         }
5573
5574         talloc_free(h);
5575         return ret;
5576 }
5577
5578 static int control_checktcpport(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5579                                 int argc, const char **argv)
5580 {
5581         struct sockaddr_in sin;
5582         unsigned int port;
5583         int s, v;
5584         int ret;
5585
5586         if (argc != 1) {
5587                 usage("chktcpport");
5588         }
5589
5590         port = atoi(argv[0]);
5591
5592         s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
5593         if (s == -1) {
5594                 fprintf(stderr, "Failed to open local socket\n");
5595                 return errno;
5596         }
5597
5598         v = fcntl(s, F_GETFL, 0);
5599         if (v == -1 || fcntl(s, F_SETFL, v | O_NONBLOCK)) {
5600                 fprintf(stderr, "Unable to set socket non-blocking\n");
5601                 close(s);
5602                 return errno;
5603         }
5604
5605         bzero(&sin, sizeof(sin));
5606         sin.sin_family = AF_INET;
5607         sin.sin_port = htons(port);
5608         ret = bind(s, (struct sockaddr *)&sin, sizeof(sin));
5609         close(s);
5610         if (ret == -1) {
5611                 fprintf(stderr, "Failed to bind to TCP port %u\n", port);
5612                 return errno;
5613         }
5614
5615         return 0;
5616 }
5617
5618 static int control_getdbseqnum(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5619                                int argc, const char **argv)
5620 {
5621         uint32_t db_id;
5622         const char *db_name;
5623         uint64_t seqnum;
5624         int ret;
5625
5626         if (argc != 1) {
5627                 usage("getdbseqnum");
5628         }
5629
5630         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, NULL)) {
5631                 return 1;
5632         }
5633
5634         ret = ctdb_ctrl_get_db_seqnum(mem_ctx, ctdb->ev, ctdb->client,
5635                                       ctdb->cmd_pnn, TIMEOUT(), db_id,
5636                                       &seqnum);
5637         if (ret != 0) {
5638                 fprintf(stderr, "Failed to get sequence number for DB %s\n",
5639                         db_name);
5640                 return ret;
5641         }
5642
5643         printf("0x%"PRIx64"\n", seqnum);
5644         return 0;
5645 }
5646
5647 static int control_nodestatus(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5648                               int argc, const char **argv)
5649 {
5650         const char *nodestring = NULL;
5651         struct ctdb_node_map *nodemap;
5652         int ret, i;
5653
5654         if (argc > 1) {
5655                 usage("nodestatus");
5656         }
5657
5658         if (argc == 1) {
5659                 nodestring = argv[0];
5660         }
5661
5662         if (! parse_nodestring(mem_ctx, ctdb, nodestring, &nodemap)) {
5663                 return 1;
5664         }
5665
5666         nodemap = get_nodemap(ctdb, false);
5667         if (nodemap == NULL) {
5668                 return 1;
5669         }
5670
5671         if (options.machinereadable) {
5672                 print_nodemap_machine(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn);
5673         } else {
5674                 print_nodemap(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn);
5675         }
5676
5677         ret = 0;
5678         for (i=0; i<nodemap->num; i++) {
5679                 ret |= nodemap->node[i].flags;
5680         }
5681
5682         return ret;
5683 }
5684
5685 const struct {
5686         const char *name;
5687         uint32_t offset;
5688 } db_stats_fields[] = {
5689 #define DBSTATISTICS_FIELD(n) { #n, offsetof(struct ctdb_db_statistics, n) }
5690         DBSTATISTICS_FIELD(db_ro_delegations),
5691         DBSTATISTICS_FIELD(db_ro_revokes),
5692         DBSTATISTICS_FIELD(locks.num_calls),
5693         DBSTATISTICS_FIELD(locks.num_current),
5694         DBSTATISTICS_FIELD(locks.num_pending),
5695         DBSTATISTICS_FIELD(locks.num_failed),
5696         DBSTATISTICS_FIELD(db_ro_delegations),
5697 };
5698
5699 static void print_dbstatistics(const char *db_name,
5700                                struct ctdb_db_statistics *s)
5701 {
5702         int i;
5703         const char *prefix = NULL;
5704         int preflen = 0;
5705
5706         printf("DB Statistics %s\n", db_name);
5707
5708         for (i=0; i<ARRAY_SIZE(db_stats_fields); i++) {
5709                 if (strchr(db_stats_fields[i].name, '.') != NULL) {
5710                         preflen = strcspn(db_stats_fields[i].name, ".") + 1;
5711                         if (! prefix ||
5712                             strncmp(prefix, db_stats_fields[i].name, preflen) != 0) {
5713                                 prefix = db_stats_fields[i].name;
5714                                 printf(" %*.*s\n", preflen-1, preflen-1,
5715                                        db_stats_fields[i].name);
5716                         }
5717                 } else {
5718                         preflen = 0;
5719                 }
5720                 printf(" %*s%-22s%*s%10u\n", preflen ? 4 : 0, "",
5721                        db_stats_fields[i].name+preflen, preflen ? 0 : 4, "",
5722                        *(uint32_t *)(db_stats_fields[i].offset+(uint8_t *)s));
5723         }
5724
5725         printf(" hop_count_buckets:");
5726         for (i=0; i<MAX_COUNT_BUCKETS; i++) {
5727                 printf(" %d", s->hop_count_bucket[i]);
5728         }
5729         printf("\n");
5730
5731         printf(" lock_buckets:");
5732         for (i=0; i<MAX_COUNT_BUCKETS; i++) {
5733                 printf(" %d", s->locks.buckets[i]);
5734         }
5735         printf("\n");
5736
5737         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
5738                "locks_latency      MIN/AVG/MAX",
5739                s->locks.latency.min, LATENCY_AVG(s->locks.latency),
5740                s->locks.latency.max, s->locks.latency.num);
5741
5742         printf(" %-30s     %.6f/%.6f/%.6f sec out of %d\n",
5743                "vacuum_latency     MIN/AVG/MAX",
5744                s->vacuum.latency.min, LATENCY_AVG(s->vacuum.latency),
5745                s->vacuum.latency.max, s->vacuum.latency.num);
5746
5747         printf(" Num Hot Keys:     %d\n", s->num_hot_keys);
5748         for (i=0; i<s->num_hot_keys; i++) {
5749                 int j;
5750                 printf("     Count:%d Key:", s->hot_keys[i].count);
5751                 for (j=0; j<s->hot_keys[i].key.dsize; j++) {
5752                         printf("%02x", s->hot_keys[i].key.dptr[j] & 0xff);
5753                 }
5754                 printf("\n");
5755         }
5756 }
5757
5758 static int control_dbstatistics(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5759                                 int argc, const char **argv)
5760 {
5761         uint32_t db_id;
5762         const char *db_name;
5763         struct ctdb_db_statistics *dbstats;
5764         int ret;
5765
5766         if (argc != 1) {
5767                 usage("dbstatistics");
5768         }
5769
5770         if (! db_exists(mem_ctx, ctdb, argv[0], &db_id, &db_name, NULL)) {
5771                 return 1;
5772         }
5773
5774         ret = ctdb_ctrl_get_db_statistics(mem_ctx, ctdb->ev, ctdb->client,
5775                                           ctdb->cmd_pnn, TIMEOUT(), db_id,
5776                                           &dbstats);
5777         if (ret != 0) {
5778                 fprintf(stderr, "Failed to get statistics for DB %s\n",
5779                         db_name);
5780                 return ret;
5781         }
5782
5783         print_dbstatistics(db_name, dbstats);
5784         return 0;
5785 }
5786
5787 struct disable_takeover_runs_state {
5788         uint32_t *pnn_list;
5789         int node_count;
5790         bool *reply;
5791         int status;
5792         bool done;
5793 };
5794
5795 static void disable_takeover_run_handler(uint64_t srvid, TDB_DATA data,
5796                                          void *private_data)
5797 {
5798         struct disable_takeover_runs_state *state =
5799                 (struct disable_takeover_runs_state *)private_data;
5800         int ret, i;
5801
5802         if (data.dsize != sizeof(int)) {
5803                 /* Ignore packet */
5804                 return;
5805         }
5806
5807         /* ret will be a PNN (i.e. >=0) on success, or negative on error */
5808         ret = *(int *)data.dptr;
5809         if (ret < 0) {
5810                 state->status = ret;
5811                 state->done = true;
5812                 return;
5813         }
5814         for (i=0; i<state->node_count; i++) {
5815                 if (state->pnn_list[i] == ret) {
5816                         state->reply[i] = true;
5817                         break;
5818                 }
5819         }
5820
5821         state->done = true;
5822         for (i=0; i<state->node_count; i++) {
5823                 if (! state->reply[i]) {
5824                         state->done = false;
5825                         break;
5826                 }
5827         }
5828 }
5829
5830 static int disable_takeover_runs(TALLOC_CTX *mem_ctx,
5831                                  struct ctdb_context *ctdb, uint32_t timeout,
5832                                  uint32_t *pnn_list, int count)
5833 {
5834         struct ctdb_disable_message disable = { 0 };
5835         struct disable_takeover_runs_state state;
5836         int ret, i;
5837
5838         disable.pnn = ctdb->pnn;
5839         disable.srvid = next_srvid(ctdb);
5840         disable.timeout = timeout;
5841
5842         state.pnn_list = pnn_list;
5843         state.node_count = count;
5844         state.done = false;
5845         state.status = 0;
5846         state.reply = talloc_zero_array(mem_ctx, bool, count);
5847         if (state.reply == NULL) {
5848                 return ENOMEM;
5849         }
5850
5851         ret = ctdb_client_set_message_handler(ctdb->ev, ctdb->client,
5852                                               disable.srvid,
5853                                               disable_takeover_run_handler,
5854                                               &state);
5855         if (ret != 0) {
5856                 return ret;
5857         }
5858
5859         for (i=0; i<count; i++) {
5860                 ret = ctdb_message_disable_takeover_runs(mem_ctx, ctdb->ev,
5861                                                          ctdb->client,
5862                                                          pnn_list[i],
5863                                                          &disable);
5864                 if (ret != 0) {
5865                         goto fail;
5866                 }
5867         }
5868
5869         ret = ctdb_client_wait_timeout(ctdb->ev, &state.done, TIMEOUT());
5870         if (ret == ETIME) {
5871                 fprintf(stderr, "Timed out waiting to disable takeover runs\n");
5872         } else {
5873                 ret = (state.status >= 0 ? 0 : 1);
5874         }
5875
5876 fail:
5877         ctdb_client_remove_message_handler(ctdb->ev, ctdb->client,
5878                                            disable.srvid, &state);
5879         return ret;
5880 }
5881
5882 static int control_reloadips(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5883                              int argc, const char **argv)
5884 {
5885         const char *nodestring = NULL;
5886         struct ctdb_node_map *nodemap, *nodemap2;
5887         struct ctdb_req_control request;
5888         uint32_t *pnn_list, *pnn_list2;
5889         int ret, count, count2;
5890
5891         if (argc > 1) {
5892                 usage("reloadips");
5893         }
5894
5895         if (argc == 1) {
5896                 nodestring = argv[0];
5897         }
5898
5899         nodemap = get_nodemap(ctdb, false);
5900         if (nodemap == NULL) {
5901                 return 1;
5902         }
5903
5904         if (! parse_nodestring(mem_ctx, ctdb, nodestring, &nodemap2)) {
5905                 return 1;
5906         }
5907
5908         count = list_of_connected_nodes(nodemap, CTDB_UNKNOWN_PNN,
5909                                         mem_ctx, &pnn_list);
5910         if (count <= 0) {
5911                 fprintf(stderr, "Memory allocation error\n");
5912                 return 1;
5913         }
5914
5915         count2 = list_of_active_nodes(nodemap2, CTDB_UNKNOWN_PNN,
5916                                       mem_ctx, &pnn_list2);
5917         if (count2 <= 0) {
5918                 fprintf(stderr, "Memory allocation error\n");
5919                 return 1;
5920         }
5921
5922         /* Disable takeover runs on all connected nodes.  A reply
5923          * indicating success is needed from each node so all nodes
5924          * will need to be active.
5925          *
5926          * A check could be added to not allow reloading of IPs when
5927          * there are disconnected nodes.  However, this should
5928          * probably be left up to the administrator.
5929          */
5930         ret = disable_takeover_runs(mem_ctx, ctdb, 2*options.timelimit,
5931                                     pnn_list, count);
5932         if (ret != 0) {
5933                 fprintf(stderr, "Failed to disable takeover runs\n");
5934                 return ret;
5935         }
5936
5937         /* Now tell all the desired nodes to reload their public IPs.
5938          * Keep trying this until it succeeds.  This assumes all
5939          * failures are transient, which might not be true...
5940          */
5941         ctdb_req_control_reload_public_ips(&request);
5942         ret = ctdb_client_control_multi(mem_ctx, ctdb->ev, ctdb->client,
5943                                         pnn_list2, count2, TIMEOUT(),
5944                                         &request, NULL, NULL);
5945         if (ret != 0) {
5946                 fprintf(stderr, "Failed to reload IPs on some nodes.\n");
5947         }
5948
5949         /* It isn't strictly necessary to wait until takeover runs are
5950          * re-enabled but doing so can't hurt.
5951          */
5952         ret = disable_takeover_runs(mem_ctx, ctdb, 0, pnn_list, count);
5953         if (ret != 0) {
5954                 fprintf(stderr, "Failed to enable takeover runs\n");
5955                 return ret;
5956         }
5957
5958         return ipreallocate(mem_ctx, ctdb);
5959 }
5960
5961 static int control_ipiface(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
5962                            int argc, const char **argv)
5963 {
5964         ctdb_sock_addr addr;
5965         char *iface;
5966
5967         if (argc != 1) {
5968                 usage("ipiface");
5969         }
5970
5971         if (! parse_ip(argv[0], NULL, 0, &addr)) {
5972                 fprintf(stderr, "Failed to Parse IP %s\n", argv[0]);
5973                 return 1;
5974         }
5975
5976         iface = ctdb_sys_find_ifname(&addr);
5977         if (iface == NULL) {
5978                 fprintf(stderr, "Failed to find interface for IP %s\n",
5979                         argv[0]);
5980                 return 1;
5981         }
5982         free(iface);
5983
5984         return 0;
5985 }
5986
5987
5988 static const struct ctdb_cmd {
5989         const char *name;
5990         int (*fn)(TALLOC_CTX *, struct ctdb_context *, int, const char **);
5991         bool without_daemon; /* can be run without daemon running ? */
5992         bool remote; /* can be run on remote nodes */
5993         const char *msg;
5994         const char *args;
5995 } ctdb_commands[] = {
5996         { "version", control_version, true, false,
5997                 "show version of ctdb", NULL },
5998         { "status", control_status, false, true,
5999                 "show node status", NULL },
6000         { "uptime", control_uptime, false, true,
6001                 "show node uptime", NULL },
6002         { "ping", control_ping, false, true,
6003                 "ping all nodes", NULL },
6004         { "runstate", control_runstate, false, true,
6005                 "get/check runstate of a node",
6006                 "[setup|first_recovery|startup|running]" },
6007         { "getvar", control_getvar, false, true,
6008                 "get a tunable variable", "<name>" },
6009         { "setvar", control_setvar, false, true,
6010                 "set a tunable variable", "<name> <value>" },
6011         { "listvars", control_listvars, false, true,
6012                 "list tunable variables", NULL },
6013         { "statistics", control_statistics, false, true,
6014                 "show ctdb statistics", NULL },
6015         { "statisticsreset", control_statistics_reset, false, true,
6016                 "reset ctdb statistics", NULL },
6017         { "stats", control_stats, false, true,
6018                 "show rolling statistics", "[count]" },
6019         { "ip", control_ip, false, true,
6020                 "show public ips", "[all]" },
6021         { "ipinfo", control_ipinfo, false, true,
6022                 "show public ip details", "<ip>" },
6023         { "ifaces", control_ifaces, false, true,
6024                 "show interfaces", NULL },
6025         { "setifacelink", control_setifacelink, false, true,
6026                 "set interface link status", "<iface> up|down" },
6027         { "process-exists", control_process_exists, false, true,
6028                 "check if a process exists on a node",  "<pid>" },
6029         { "getdbmap", control_getdbmap, false, true,
6030                 "show attached databases", NULL },
6031         { "getdbstatus", control_getdbstatus, false, true,
6032                 "show database status", "<dbname|dbid>" },
6033         { "catdb", control_catdb, false, false,
6034                 "dump cluster-wide ctdb database", "<dbname|dbid>" },
6035         { "cattdb", control_cattdb, false, false,
6036                 "dump local ctdb database", "<dbname|dbid>" },
6037         { "getmonmode", control_getmonmode, false, true,
6038                 "show monitoring mode", NULL },
6039         { "getcapabilities", control_getcapabilities, false, true,
6040                 "show node capabilities", NULL },
6041         { "pnn", control_pnn, false, false,
6042                 "show the pnn of the currnet node", NULL },
6043         { "lvs", control_lvs, false, false,
6044                 "show lvs configuration", "master|list|status" },
6045         { "disablemonitor", control_disable_monitor, false, true,
6046                 "disable monitoring", NULL },
6047         { "enablemonitor", control_enable_monitor, false, true,
6048                 "enable monitoring", NULL },
6049         { "setdebug", control_setdebug, false, true,
6050                 "set debug level", "ERROR|WARNING|NOTICE|INFO|DEBUG" },
6051         { "getdebug", control_getdebug, false, true,
6052                 "get debug level", NULL },
6053         { "attach", control_attach, false, false,
6054                 "attach a database", "<dbname> [persistent]" },
6055         { "detach", control_detach, false, false,
6056                 "detach database(s)", "<dbname|dbid> ..." },
6057         { "dumpmemory", control_dumpmemory, false, true,
6058                 "dump ctdbd memory map", NULL },
6059         { "rddumpmemory", control_rddumpmemory, false, true,
6060                 "dump recoverd memory map", NULL },
6061         { "getpid", control_getpid, false, true,
6062                 "get ctdbd process ID", NULL },
6063         { "disable", control_disable, false, true,
6064                 "disable a node", NULL },
6065         { "enable", control_enable, false, true,
6066                 "enable a node", NULL },
6067         { "stop", control_stop, false, true,
6068                 "stop a node", NULL },
6069         { "continue", control_continue, false, true,
6070                 "continue a stopped node", NULL },
6071         { "ban", control_ban, false, true,
6072                 "ban a node", "<bantime>"},
6073         { "unban", control_unban, false, true,
6074                 "unban a node", NULL },
6075         { "shutdown", control_shutdown, false, true,
6076                 "shutdown ctdb daemon", NULL },
6077         { "recover", control_recover, false, true,
6078                 "force recovery", NULL },
6079         { "sync", control_ipreallocate, false, true,
6080                 "run ip reallocation (deprecated)", NULL },
6081         { "ipreallocate", control_ipreallocate, false, true,
6082                 "run ip reallocation", NULL },
6083         { "isnotrecmaster", control_isnotrecmaster, false, false,
6084                 "check if local node is the recmaster", NULL },
6085         { "gratarp", control_gratarp, false, true,
6086                 "send a gratuitous arp", "<ip> <interface>" },
6087         { "tickle", control_tickle, true, false,
6088                 "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
6089         { "gettickles", control_gettickles, false, true,
6090                 "get the list of tickles", "<ip> [<port>]" },
6091         { "addtickle", control_addtickle, false, true,
6092                 "add a tickle", "<ip>:<port> <ip>:<port>" },
6093         { "deltickle", control_deltickle, false, true,
6094                 "delete a tickle", "<ip>:<port> <ip>:<port>" },
6095         { "check_srvids", control_check_srvids, false, true,
6096                 "check if srvid is registered", "<id> [<id> ...]" },
6097         { "listnodes", control_listnodes, true, true,
6098                 "list nodes in the cluster", NULL },
6099         { "reloadnodes", control_reloadnodes, false, false,
6100                 "reload the nodes file all nodes", NULL },
6101         { "moveip", control_moveip, false, false,
6102                 "move an ip address to another node", "<ip> <node>" },
6103         { "addip", control_addip, false, true,
6104                 "add an ip address to a node", "<ip/mask> <iface>" },
6105         { "delip", control_delip, false, true,
6106                 "delete an ip address from a node", "<ip>" },
6107         { "backupdb", control_backupdb, false, false,
6108                 "backup a database into a file", "<dbname|dbid> <file>" },
6109         { "restoredb", control_restoredb, false, false,
6110                 "restore a database from a file", "<file> [dbname]" },
6111         { "dumpdbbackup", control_dumpdbbackup, true, false,
6112                 "dump database from a backup file", "<file>" },
6113         { "wipedb", control_wipedb, false, false,
6114                 "wipe the contents of a database.", "<dbname|dbid>"},
6115         { "recmaster", control_recmaster, false, true,
6116                 "show the pnn for the recovery master", NULL },
6117         { "event", control_event, true, false,
6118                 "event and event script commands", NULL },
6119         { "scriptstatus", control_scriptstatus, true, false,
6120                 "show event script status",
6121                 "[init|setup|startup|monitor|takeip|releaseip|ipreallocated]" },
6122         { "natgw", control_natgw, false, false,
6123                 "show natgw configuration", "master|list|status" },
6124         { "natgwlist", control_natgwlist, false, false,
6125                 "show the nodes belonging to this natgw configuration", NULL },
6126         { "getreclock", control_getreclock, false, true,
6127                 "get recovery lock file", NULL },
6128         { "setlmasterrole", control_setlmasterrole, false, true,
6129                 "set LMASTER role", "on|off" },
6130         { "setrecmasterrole", control_setrecmasterrole, false, true,
6131                 "set RECMASTER role", "on|off"},
6132         { "setdbreadonly", control_setdbreadonly, false, true,
6133                 "enable readonly records", "<dbname|dbid>" },
6134         { "setdbsticky", control_setdbsticky, false, true,
6135                 "enable sticky records", "<dbname|dbid>"},
6136         { "pfetch", control_pfetch, false, false,
6137                 "fetch record from persistent database", "<dbname|dbid> <key> [<file>]" },
6138         { "pstore", control_pstore, false, false,
6139                 "write record to persistent database", "<dbname|dbid> <key> <value>" },
6140         { "pdelete", control_pdelete, false, false,
6141                 "delete record from persistent database", "<dbname|dbid> <key>" },
6142         { "ptrans", control_ptrans, false, false,
6143                 "update a persistent database (from file or stdin)", "<dbname|dbid> [<file>]" },
6144         { "tfetch", control_tfetch, false, true,
6145                 "fetch a record", "<tdb-file> <key> [<file>]" },
6146         { "tstore", control_tstore, false, true,
6147                 "store a record", "<tdb-file> <key> <data> [<rsn> <dmaster> <flags>]" },
6148         { "readkey", control_readkey, false, false,
6149                 "read value of a database key", "<dbname|dbid> <key> [readonly]" },
6150         { "writekey", control_writekey, false, false,
6151                 "write value for a database key", "<dbname|dbid> <key> <value>" },
6152         { "deletekey", control_deletekey, false, false,
6153                 "delete a database key", "<dbname|dbid> <key>" },
6154         { "checktcpport", control_checktcpport, true, false,
6155                 "check if a service is bound to a specific tcp port or not", "<port>" },
6156         { "getdbseqnum", control_getdbseqnum, false, false,
6157                 "get database sequence number", "<dbname|dbid>" },
6158         { "nodestatus", control_nodestatus, false, true,
6159                 "show and return node status", "[all|<pnn-list>]" },
6160         { "dbstatistics", control_dbstatistics, false, true,
6161                 "show database statistics", "<dbname|dbid>" },
6162         { "reloadips", control_reloadips, false, false,
6163                 "reload the public addresses file", "[all|<pnn-list>]" },
6164         { "ipiface", control_ipiface, true, false,
6165                 "Find the interface an ip address is hosted on", "<ip>" },
6166 };
6167
6168 static const struct ctdb_cmd *match_command(const char *command)
6169 {
6170         const struct ctdb_cmd *cmd;
6171         int i;
6172
6173         for (i=0; i<ARRAY_SIZE(ctdb_commands); i++) {
6174                 cmd = &ctdb_commands[i];
6175                 if (strlen(command) == strlen(cmd->name) &&
6176                     strncmp(command, cmd->name, strlen(command)) == 0) {
6177                         return cmd;
6178                 }
6179         }
6180
6181         return NULL;
6182 }
6183
6184
6185 /**
6186  * Show usage message
6187  */
6188 static void usage_full(void)
6189 {
6190         int i;
6191
6192         poptPrintHelp(pc, stdout, 0);
6193         printf("\nCommands:\n");
6194         for (i=0; i<ARRAY_SIZE(ctdb_commands); i++) {
6195                 printf("  %-15s %-27s  %s\n",
6196                        ctdb_commands[i].name,
6197                        ctdb_commands[i].args ? ctdb_commands[i].args : "",
6198                        ctdb_commands[i].msg);
6199         }
6200 }
6201
6202 static void usage(const char *command)
6203 {
6204         const struct ctdb_cmd *cmd;
6205
6206         if (command == NULL) {
6207                 usage_full();
6208                 exit(1);
6209         }
6210
6211         cmd = match_command(command);
6212         if (cmd == NULL) {
6213                 usage_full();
6214         } else {
6215                 poptPrintUsage(pc, stdout, 0);
6216                 printf("\nCommands:\n");
6217                 printf("  %-15s %-27s  %s\n",
6218                        cmd->name, cmd->args ? cmd->args : "", cmd->msg);
6219         }
6220
6221         exit(1);
6222 }
6223
6224 struct poptOption cmdline_options[] = {
6225         POPT_AUTOHELP
6226         { "socket", 's', POPT_ARG_STRING, &options.socket, 0,
6227                 "CTDB socket path", "filename" },
6228         { "debug", 'd', POPT_ARG_STRING, &options.debuglevelstr, 0,
6229                 "debug level"},
6230         { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0,
6231                 "timelimit (in seconds)" },
6232         { "node", 'n', POPT_ARG_INT, &options.pnn, 0,
6233                 "node specification - integer" },
6234         { NULL, 'Y', POPT_ARG_NONE, &options.machinereadable, 0,
6235                 "enable machine readable output", NULL },
6236         { "separator", 'x', POPT_ARG_STRING, &options.sep, 0,
6237                 "specify separator for machine readable output", "CHAR" },
6238         { NULL, 'X', POPT_ARG_NONE, &options.machineparsable, 0,
6239                 "enable machine parsable output with separator |", NULL },
6240         { "verbose", 'v', POPT_ARG_NONE, &options.verbose, 0,
6241                 "enable verbose output", NULL },
6242         { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0,
6243                 "die if runtime exceeds this limit (in seconds)" },
6244         POPT_TABLEEND
6245 };
6246
6247 static int process_command(const struct ctdb_cmd *cmd, int argc,
6248                            const char **argv)
6249 {
6250         TALLOC_CTX *tmp_ctx;
6251         struct ctdb_context *ctdb;
6252         int ret;
6253         bool status;
6254         uint64_t srvid_offset;
6255
6256         tmp_ctx = talloc_new(NULL);
6257         if (tmp_ctx == NULL) {
6258                 fprintf(stderr, "Memory allocation error\n");
6259                 goto fail;
6260         }
6261
6262         if (cmd->without_daemon) {
6263                 if (options.pnn != -1) {
6264                         fprintf(stderr,
6265                                 "Cannot specify node for command %s\n",
6266                                 cmd->name);
6267                         goto fail;
6268                 }
6269
6270                 ret = cmd->fn(tmp_ctx, NULL, argc-1, argv+1);
6271                 talloc_free(tmp_ctx);
6272                 return ret;
6273         }
6274
6275         ctdb = talloc_zero(tmp_ctx, struct ctdb_context);
6276         if (ctdb == NULL) {
6277                 fprintf(stderr, "Memory allocation error\n");
6278                 goto fail;
6279         }
6280
6281         ctdb->ev = tevent_context_init(ctdb);
6282         if (ctdb->ev == NULL) {
6283                 fprintf(stderr, "Failed to initialize tevent\n");
6284                 goto fail;
6285         }
6286
6287         ret = ctdb_client_init(ctdb, ctdb->ev, options.socket, &ctdb->client);
6288         if (ret != 0) {
6289                 fprintf(stderr, "Failed to connect to CTDB daemon (%s)\n",
6290                         options.socket);
6291
6292                 if (!find_node_xpnn(ctdb, NULL)) {
6293                         fprintf(stderr, "Is this node part of CTDB cluster?\n");
6294                 }
6295                 goto fail;
6296         }
6297
6298         ctdb->pnn = ctdb_client_pnn(ctdb->client);
6299         srvid_offset = getpid() & 0xFFFF;
6300         ctdb->srvid = SRVID_CTDB_TOOL | (srvid_offset << 16);
6301
6302         if (options.pnn != -1) {
6303                 status = verify_pnn(ctdb, options.pnn);
6304                 if (! status) {
6305                         goto fail;
6306                 }
6307
6308                 ctdb->cmd_pnn = options.pnn;
6309         } else {
6310                 ctdb->cmd_pnn = ctdb->pnn;
6311         }
6312
6313         if (! cmd->remote && ctdb->pnn != ctdb->cmd_pnn) {
6314                 fprintf(stderr, "Node cannot be specified for command %s\n",
6315                         cmd->name);
6316                 goto fail;
6317         }
6318
6319         ret = cmd->fn(tmp_ctx, ctdb, argc-1, argv+1);
6320         talloc_free(tmp_ctx);
6321         return ret;
6322
6323 fail:
6324         talloc_free(tmp_ctx);
6325         return 1;
6326 }
6327
6328 static void signal_handler(int sig)
6329 {
6330         fprintf(stderr, "Maximum runtime exceeded - exiting\n");
6331 }
6332
6333 static void alarm_handler(int sig)
6334 {
6335         /* Kill any child processes */
6336         signal(SIGTERM, signal_handler);
6337         kill(0, SIGTERM);
6338
6339         _exit(1);
6340 }
6341
6342 int main(int argc, const char *argv[])
6343 {
6344         int opt;
6345         const char **extra_argv;
6346         int extra_argc;
6347         const struct ctdb_cmd *cmd;
6348         const char *ctdb_socket;
6349         int loglevel;
6350         int ret;
6351
6352         setlinebuf(stdout);
6353
6354         /* Set default options */
6355         options.socket = CTDB_SOCKET;
6356         options.debuglevelstr = NULL;
6357         options.timelimit = 10;
6358         options.sep = "|";
6359         options.maxruntime = 0;
6360         options.pnn = -1;
6361
6362         ctdb_socket = getenv("CTDB_SOCKET");
6363         if (ctdb_socket != NULL) {
6364                 options.socket = ctdb_socket;
6365         }
6366
6367         pc = poptGetContext(argv[0], argc, argv, cmdline_options,
6368                             POPT_CONTEXT_KEEP_FIRST);
6369         while ((opt = poptGetNextOpt(pc)) != -1) {
6370                 fprintf(stderr, "Invalid option %s: %s\n",
6371                         poptBadOption(pc, 0), poptStrerror(opt));
6372                 exit(1);
6373         }
6374
6375         if (options.maxruntime == 0) {
6376                 const char *ctdb_timeout;
6377
6378                 ctdb_timeout = getenv("CTDB_TIMEOUT");
6379                 if (ctdb_timeout != NULL) {
6380                         options.maxruntime = strtoul(ctdb_timeout, NULL, 0);
6381                 } else {
6382                         options.maxruntime = 120;
6383                 }
6384         }
6385         if (options.maxruntime <= 120) {
6386                 /* default timeout is 120 seconds */
6387                 options.maxruntime = 120;
6388         }
6389
6390         if (options.machineparsable) {
6391                 options.machinereadable = 1;
6392         }
6393
6394         /* setup the remaining options for the commands */
6395         extra_argc = 0;
6396         extra_argv = poptGetArgs(pc);
6397         if (extra_argv) {
6398                 extra_argv++;
6399                 while (extra_argv[extra_argc]) extra_argc++;
6400         }
6401
6402         if (extra_argc < 1) {
6403                 usage(NULL);
6404         }
6405
6406         cmd = match_command(extra_argv[0]);
6407         if (cmd == NULL) {
6408                 fprintf(stderr, "Unknown command '%s'\n", extra_argv[0]);
6409                 exit(1);
6410         }
6411
6412         /* Enable logging */
6413         setup_logging("ctdb", DEBUG_STDERR);
6414         if (debug_level_parse(options.debuglevelstr, &loglevel)) {
6415                 DEBUGLEVEL = loglevel;
6416         } else {
6417                 DEBUGLEVEL = DEBUG_ERR;
6418         }
6419
6420         signal(SIGALRM, alarm_handler);
6421         alarm(options.maxruntime);
6422
6423         ret = process_command(cmd, extra_argc, extra_argv);
6424         if (ret == -1) {
6425                 ret = 1;
6426         }
6427
6428         (void)poptFreeContext(pc);
6429
6430         return ret;
6431 }