nmdb: Only unlink the pidfile if we were asked to write it
[nmdb.git] / nmdb / main.c
blob7f4596f8f83d77290c0b7561e384bdc873c483e1
2 #include <stdio.h> /* printf() */
3 #include <unistd.h> /* malloc(), fork() and getopt() */
4 #include <stdlib.h> /* atoi() */
5 #include <sys/types.h> /* for pid_t */
6 #include <string.h> /* for strcpy() and strlen() */
7 #include <pthread.h> /* for pthread_t */
9 #include "cache.h"
10 #include "net.h"
11 #include "dbloop.h"
12 #include "common.h"
13 #include "net-const.h"
14 #include "log.h"
15 #include "stats.h"
16 #include "be.h"
18 #define DEFDBNAME "database"
21 /* Define the common structures that are used throughout the whole server. */
22 struct settings settings;
23 struct stats stats;
24 struct cache *cache_table;
25 struct queue *op_queue;
28 static void help(void) {
29 char h[] = \
30 "nmdb [options]\n"
31 "\n"
32 " -b backend backend to use (" DEFAULT_BE_NAME ")\n"
33 " -d dbpath database path ('database' by default)\n"
34 " -l lower TIPC lower port number (10)\n"
35 " -L upper TIPC upper port number (= lower)\n"
36 " -t port TCP listening port (26010)\n"
37 " -T addr TCP listening address (all local addresses)\n"
38 " -u port UDP listening port (26010)\n"
39 " -U addr UDP listening address (all local addresses)\n"
40 " -s port SCTP listening port (26010)\n"
41 " -S addr SCTP listening address (all local addresses)\n"
42 " -c nobj max. number of objects to be cached, in thousands (128)\n"
43 " -o fname log to the given file (stdout).\n"
44 " -i pidfile file to write the PID to (none).\n"
45 " -f don't fork and stay in the foreground\n"
46 " -p enable passive mode, for redundancy purposes (read docs.)\n"
47 " -r read-only mode\n"
48 " -h show this help\n"
49 "\n"
50 "Available backends: " SUPPORTED_BE "\n"
51 "\n"
52 "Please report bugs to Alberto Bertogli (albertito@blitiri.com.ar)\n"
53 "\n";
54 printf("%s", h);
58 static int load_settings(int argc, char **argv)
60 int c;
62 settings.tipc_lower = -1;
63 settings.tipc_upper = -1;
64 settings.tcp_addr = NULL;
65 settings.tcp_port = -1;
66 settings.udp_addr = NULL;
67 settings.udp_port = -1;
68 settings.sctp_addr = NULL;
69 settings.sctp_port = -1;
70 settings.numobjs = -1;
71 settings.foreground = 0;
72 settings.passive = 0;
73 settings.read_only = 0;
74 settings.logfname = NULL;
75 settings.pidfile = NULL;
76 settings.backend = DEFAULT_BE;
78 settings.dbname = strdup(DEFDBNAME);
79 settings.logfname = strdup("-");
81 while ((c = getopt(argc, argv,
82 "b:d:l:L:t:T:u:U:s:S:c:o:i:fprh?")) != -1) {
83 switch(c) {
84 case 'b':
85 settings.backend = be_type_from_str(optarg);
86 break;
87 case 'd':
88 free(settings.dbname);
89 settings.dbname = strdup(optarg);
90 break;
92 case 'l':
93 settings.tipc_lower = atoi(optarg);
94 break;
95 case 'L':
96 settings.tipc_upper = atoi(optarg);
97 break;
99 case 't':
100 settings.tcp_port = atoi(optarg);
101 break;
102 case 'T':
103 settings.tcp_addr = optarg;
104 break;
106 case 'u':
107 settings.udp_port = atoi(optarg);
108 break;
109 case 'U':
110 settings.udp_addr = optarg;
111 break;
113 case 's':
114 settings.sctp_port = atoi(optarg);
115 break;
116 case 'S':
117 settings.sctp_addr = optarg;
118 break;
120 case 'c':
121 settings.numobjs = atoi(optarg) * 1024;
122 break;
124 case 'o':
125 free(settings.logfname);
126 settings.logfname = strdup(optarg);
127 break;
129 case 'i':
130 free(settings.pidfile);
131 settings.pidfile = strdup(optarg);
132 break;
134 case 'f':
135 settings.foreground = 1;
136 break;
137 case 'p':
138 settings.passive = 1;
139 break;
140 case 'r':
141 settings.read_only = 1;
142 break;
144 case 'h':
145 case '?':
146 help();
147 return 0;
148 default:
149 printf("Unknown parameter '%c'\n", c);
150 return 0;
154 if (settings.tipc_lower == -1)
155 settings.tipc_lower = TIPC_SERVER_INST;
156 if (settings.tipc_upper == -1)
157 settings.tipc_upper = settings.tipc_lower;
158 if (settings.tcp_addr == NULL)
159 settings.tcp_addr = TCP_SERVER_ADDR;
160 if (settings.tcp_port == -1)
161 settings.tcp_port = TCP_SERVER_PORT;
162 if (settings.udp_addr == NULL)
163 settings.udp_addr = UDP_SERVER_ADDR;
164 if (settings.udp_port == -1)
165 settings.udp_port = UDP_SERVER_PORT;
166 if (settings.sctp_addr == NULL)
167 settings.sctp_addr = SCTP_SERVER_ADDR;
168 if (settings.sctp_port == -1)
169 settings.sctp_port = SCTP_SERVER_PORT;
170 if (settings.numobjs == -1)
171 settings.numobjs = 128 * 1024;
173 if (settings.backend == BE_UNKNOWN) {
174 printf("Error: unknown backend\n");
175 return 0;
176 } else if (settings.backend == BE_UNSUPPORTED) {
177 printf("Error: unsupported backend\n");
178 return 0;
181 return 1;
185 static void free_settings()
187 free(settings.dbname);
188 free(settings.logfname);
189 free(settings.pidfile);
193 int main(int argc, char **argv)
195 struct cache *cd;
196 struct queue *q;
197 struct db_conn *db;
198 pid_t pid;
199 pthread_t *dbthread;
201 if (!load_settings(argc, argv))
202 return 1;
204 if (!log_init()) {
205 perror("Error opening log file");
206 return 1;
209 stats_init(&stats);
211 cd = cache_create(settings.numobjs, 0);
212 if (cd == NULL) {
213 errlog("Error creating cache");
214 return 1;
216 cache_table = cd;
218 q = queue_create();
219 if (q == NULL) {
220 errlog("Error creating queue");
221 return 1;
223 op_queue = q;
225 db = db_open(settings.backend, settings.dbname, 0);
226 if (db == NULL) {
227 errlog("Error opening DB");
228 return 1;
230 wlog("Opened database \"%s\" with %s backend\n", settings.dbname,
231 be_str_from_type(settings.backend));
233 if (!settings.foreground) {
234 pid = fork();
235 if (pid > 0) {
236 /* parent exits */
237 return 0;
238 } else if (pid < 0) {
239 errlog("Error in fork()");
240 return 1;
243 close(0);
244 setsid();
247 wlog("Starting nmdb\n");
249 write_pid();
251 dbthread = db_loop_start(db);
253 net_loop();
255 db_loop_stop(dbthread);
257 db->close(db);
259 queue_free(q);
261 cache_free(cd);
263 if (settings.pidfile)
264 unlink(settings.pidfile);
266 free_settings();
268 return 0;