merge from ridge and vl
[vlendec/samba-autobuild/.git] / ctdb / direct / ctdbd.c
1 /* 
2    standalone ctdb daemon
3
4    Copyright (C) Andrew Tridgell  2006
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 "system/wait.h"
26
27 static void block_signal(int signum)
28 {
29         struct sigaction act;
30
31         memset(&act, 0, sizeof(act));
32
33         act.sa_handler = SIG_IGN;
34         sigemptyset(&act.sa_mask);
35         sigaddset(&act.sa_mask, signum);
36         sigaction(signum, &act, NULL);
37 }
38
39
40 /*
41   main program
42 */
43 int main(int argc, const char *argv[])
44 {
45         struct ctdb_context *ctdb;
46         const char *nlist = NULL;
47         const char *transport = "tcp";
48         const char *myaddress = NULL;
49         int self_connect=0;
50         int daemon_mode=0;
51
52         struct poptOption popt_options[] = {
53                 POPT_AUTOHELP
54                 { "nlist", 0, POPT_ARG_STRING, &nlist, 0, "node list file", "filename" },
55                 { "listen", 0, POPT_ARG_STRING, &myaddress, 0, "address to listen on", "address" },
56                 { "transport", 0, POPT_ARG_STRING, &transport, 0, "protocol transport", NULL },
57                 { "self-connect", 0, POPT_ARG_NONE, &self_connect, 0, "enable self connect", "boolean" },
58                 { "daemon", 0, POPT_ARG_NONE, &daemon_mode, 0, "spawn a ctdb daemon", "boolean" },
59                 POPT_TABLEEND
60         };
61         int opt;
62         const char **extra_argv;
63         int extra_argc = 0;
64         int ret;
65         poptContext pc;
66         struct event_context *ev;
67
68         pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
69
70         while ((opt = poptGetNextOpt(pc)) != -1) {
71                 switch (opt) {
72                 default:
73                         fprintf(stderr, "Invalid option %s: %s\n", 
74                                 poptBadOption(pc, 0), poptStrerror(opt));
75                         exit(1);
76                 }
77         }
78
79         /* setup the remaining options for the main program to use */
80         extra_argv = poptGetArgs(pc);
81         if (extra_argv) {
82                 extra_argv++;
83                 while (extra_argv[extra_argc]) extra_argc++;
84         }
85
86         if (nlist == NULL || myaddress == NULL) {
87                 printf("You must provide a node list with --nlist and an address with --listen\n");
88                 exit(1);
89         }
90
91         block_signal(SIGPIPE);
92
93         ev = event_context_init(NULL);
94
95         /* initialise ctdb */
96         ctdb = ctdb_init(ev);
97         if (ctdb == NULL) {
98                 printf("Failed to init ctdb\n");
99                 exit(1);
100         }
101
102         if (self_connect) {
103                 ctdb_set_flags(ctdb, CTDB_FLAG_SELF_CONNECT);
104         }
105         if (daemon_mode) {
106                 ctdb_set_flags(ctdb, CTDB_FLAG_DAEMON_MODE);
107         }
108
109         ret = ctdb_set_transport(ctdb, transport);
110         if (ret == -1) {
111                 printf("ctdb_set_transport failed - %s\n", ctdb_errstr(ctdb));
112                 exit(1);
113         }
114
115         /* tell ctdb what address to listen on */
116         ret = ctdb_set_address(ctdb, myaddress);
117         if (ret == -1) {
118                 printf("ctdb_set_address failed - %s\n", ctdb_errstr(ctdb));
119                 exit(1);
120         }
121
122         /* tell ctdb what nodes are available */
123         ret = ctdb_set_nlist(ctdb, nlist);
124         if (ret == -1) {
125                 printf("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb));
126                 exit(1);
127         }
128
129         /* start the protocol running */
130         ret = ctdb_start(ctdb);
131
132         event_loop_wait(ev);
133        
134         /* shut it down */
135         talloc_free(ev);
136         return 0;
137 }