merge from tridge
[samba.git] / ctdb / common / cmdline.c
1 /* 
2    common commandline code to ctdb test tools
3
4    Copyright (C) Andrew Tridgell  2007
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10
11    This library 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 GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "includes.h"
22 #include "lib/events/events.h"
23 #include "system/filesys.h"
24 #include "popt.h"
25 #include "../include/ctdb.h"
26 #include "../include/ctdb_private.h"
27
28 /* Handle common command line options for ctdb test progs
29  */
30
31 static struct {
32         const char *nlist;
33         const char *transport;
34         const char *myaddress;
35         const char *socketname;
36         int self_connect;
37         const char *db_dir;
38         int torture;
39 } ctdb_cmdline = {
40         .nlist = NULL,
41         .transport = "tcp",
42         .myaddress = NULL,
43         .socketname = CTDB_PATH,
44         .self_connect = 0,
45         .db_dir = NULL,
46         .torture = 0
47 };
48
49
50 struct poptOption popt_ctdb_cmdline[] = {
51         { "nlist", 0, POPT_ARG_STRING, &ctdb_cmdline.nlist, 0, "node list file", "filename" },
52         { "listen", 0, POPT_ARG_STRING, &ctdb_cmdline.myaddress, 0, "address to listen on", "address" },
53         { "socket", 0, POPT_ARG_STRING, &ctdb_cmdline.socketname, 0, "local socket name", "filename" },
54         { "transport", 0, POPT_ARG_STRING, &ctdb_cmdline.transport, 0, "protocol transport", NULL },
55         { "self-connect", 0, POPT_ARG_NONE, &ctdb_cmdline.self_connect, 0, "enable self connect", "boolean" },
56         { "debug", 'd', POPT_ARG_INT, &LogLevel, 0, "debug level"},
57         { "dbdir", 0, POPT_ARG_STRING, &ctdb_cmdline.db_dir, 0, "directory for the tdb files", NULL },
58         { "torture", 0, POPT_ARG_NONE, &ctdb_cmdline.torture, 0, "enable nastiness in library", NULL },
59         { NULL }
60 };
61
62
63 /*
64   startup daemon side of ctdb according to command line options
65  */
66 struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
67 {
68         struct ctdb_context *ctdb;
69         int i, ret;
70
71         if (ctdb_cmdline.nlist == NULL || ctdb_cmdline.myaddress == NULL) {
72                 printf("You must provide a node list with --nlist and an address with --listen\n");
73                 exit(1);
74         }
75
76         /* initialise ctdb */
77         ctdb = ctdb_init(ev);
78         if (ctdb == NULL) {
79                 printf("Failed to init ctdb\n");
80                 exit(1);
81         }
82
83         if (ctdb_cmdline.self_connect) {
84                 ctdb_set_flags(ctdb, CTDB_FLAG_SELF_CONNECT);
85         }
86         if (ctdb_cmdline.torture) {
87                 ctdb_set_flags(ctdb, CTDB_FLAG_TORTURE);
88         }
89
90         ret = ctdb_set_transport(ctdb, ctdb_cmdline.transport);
91         if (ret == -1) {
92                 printf("ctdb_set_transport failed - %s\n", ctdb_errstr(ctdb));
93                 exit(1);
94         }
95
96         /* tell ctdb what address to listen on */
97         ret = ctdb_set_address(ctdb, ctdb_cmdline.myaddress);
98         if (ret == -1) {
99                 printf("ctdb_set_address failed - %s\n", ctdb_errstr(ctdb));
100                 exit(1);
101         }
102
103         /* tell ctdb the socket address */
104         ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname);
105         if (ret == -1) {
106                 printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb));
107                 exit(1);
108         }
109
110         /* tell ctdb what nodes are available */
111         ret = ctdb_set_nlist(ctdb, ctdb_cmdline.nlist);
112         if (ret == -1) {
113                 printf("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb));
114                 exit(1);
115         }
116
117         ret = ctdb_set_tdb_dir(ctdb, ctdb_cmdline.db_dir);
118         if (ret == -1) {
119                 printf("ctdb_set_tdb_dir failed - %s\n", ctdb_errstr(ctdb));
120                 exit(1);
121         }
122
123         /* initialize the vnn mapping table */
124 /*
125 XXX we currently initialize it to the maximum number of nodes to 
126 XXX make it behave the same way as previously.  
127 XXX Once we have recovery working we should initialize this always to 
128 XXX generation==0 (==invalid) and let the recovery tool populate this 
129 XXX table for the daemons. 
130 */
131         ctdb->vnn_map = talloc_zero(ctdb, struct ctdb_vnn_map);
132         if (ctdb->vnn_map == NULL) {
133                 DEBUG(0,(__location__ " Unable to allocate vnn_map structure\n"));
134                 exit(1);
135         }
136         ctdb->vnn_map->generation = 1;
137         ctdb->vnn_map->size = ctdb->num_nodes;
138         ctdb->vnn_map->map = talloc_array(ctdb->vnn_map, uint32_t, ctdb->vnn_map->size);
139         if (ctdb->vnn_map->map == NULL) {
140                 DEBUG(0,(__location__ " Unable to allocate vnn_map->map structure\n"));
141                 exit(1);
142         }
143         for(i=0;i<ctdb->vnn_map->size;i++){
144                 ctdb->vnn_map->map[i] = i%ctdb->num_nodes;
145         }
146
147
148         return ctdb;
149 }
150
151
152 /*
153   startup a client only ctdb context
154  */
155 struct ctdb_context *ctdb_cmdline_client(struct event_context *ev)
156 {
157         struct ctdb_context *ctdb;
158         int ret;
159
160         /* initialise ctdb */
161         ctdb = ctdb_init(ev);
162         if (ctdb == NULL) {
163                 printf("Failed to init ctdb\n");
164                 exit(1);
165         }
166
167         /* tell ctdb the socket address */
168         ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname);
169         if (ret == -1) {
170                 printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb));
171                 exit(1);
172         }
173
174         ret = ctdb_socket_connect(ctdb);
175         if (ret != 0) {
176                 DEBUG(0,(__location__ " Failed to connect to daemon\n"));
177                 talloc_free(ctdb);
178                 return NULL;
179         }
180
181         /* get our config */
182         ret = ctdb_get_config(ctdb);
183         if (ret != 0) {
184                 DEBUG(0,(__location__ " Failed to get ctdb config\n"));
185                 talloc_free(ctdb);
186                 return NULL;
187         }
188
189         return ctdb;
190 }