clean up headers, obsd socket.h needs types.h
[arla.git] / arlad / arlad.c
blob0c4afd060ac6fa3cf1a6a0de1f4c5d5b61e24abf
1 /*
2 * Copyright (c) 1995 - 2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include <arla_local.h>
35 #include <getarg.h>
36 #include <vers.h>
37 RCSID("$Id$");
39 char *default_log_file = "syslog";
40 int client_port = 0;
42 static char *pid_filename;
44 #define _PATH_VAR_RUN "/var/run"
45 #define _PATH_DEV_NNPFS0 "/dev/nnpfs0"
46 #define _PATH_DEV_STDERR "/dev/stderr"
53 static void
54 write_pid_file (const char *progname)
56 FILE *fp;
58 asprintf (&pid_filename, _PATH_VAR_RUN "/%s.pid", progname);
59 if (pid_filename == NULL)
60 return;
61 fp = fopen (pid_filename, "w");
62 if (fp == NULL)
63 return;
64 fprintf (fp, "%u", (unsigned)getpid());
65 fclose (fp);
68 static void
69 delete_pid_file (void)
71 if (pid_filename != NULL) {
72 unlink (pid_filename);
73 free (pid_filename);
74 pid_filename = NULL;
79 * signal handlers...
82 static void
83 sigint (int foo)
85 arla_warnx (ADEBMISC, "fatal signal received");
86 store_state ();
87 delete_pid_file ();
88 exit (0);
91 static void
92 sighup (int foo)
94 store_state ();
95 delete_pid_file ();
98 static void
99 sigusr1 (int foo)
101 exit(0);
104 static void
105 sigchild (int foo)
107 exit(1);
110 static void
111 daemonify (void)
113 pid_t pid;
114 int fd;
116 pid = fork ();
117 if (pid < 0)
118 arla_err (1, ADEBERROR, errno, "fork");
119 else if (pid > 0) {
120 signal(SIGUSR1, sigusr1);
121 signal(SIGCHLD, sigchild);
122 while (1) pause();
123 exit(0);
125 if (setsid() == -1)
126 arla_err (1, ADEBERROR, errno, "setsid");
127 fd = open(_PATH_DEVNULL, O_RDWR, 0);
128 if (fd < 0)
129 arla_err (1, ADEBERROR, errno, "open " _PATH_DEVNULL);
130 dup2 (fd, STDIN_FILENO);
131 dup2 (fd, STDOUT_FILENO);
132 dup2 (fd, STDERR_FILENO);
133 if (fd > 2)
134 close (fd);
138 static void
139 arla_start (char *device_file, const char *cache_dir)
141 struct kernel_args kernel_args;
143 signal (SIGINT, sigint);
144 signal (SIGTERM, sigint);
145 signal (SIGHUP, sighup);
146 umask (S_IRWXG|S_IRWXO); /* 077 */
148 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
149 prctl(PR_SET_DUMPABLE, 1);
150 #endif
152 nnpfs_message_init ();
153 kernel_opendevice (device_file);
155 kernel_args.num_workers = num_workers;
156 kernel_args.num_bufs = num_workers * 2; /* XXX */
158 write_pid_file ("arlad");
160 if (chroot (cache_dir) < 0)
161 arla_err (1, ADEBERROR, errno, "chroot %s", cache_dir);
163 if (chdir("/") < 0)
164 arla_err (1, ADEBERROR, errno, "chdir /");
166 if (fork_flag)
167 kill(getppid(), SIGUSR1);
169 kernel_interface(&kernel_args);
170 abort ();
173 char *
174 get_default_cache_dir (void)
176 return ARLACACHEDIR;
179 char *device_file = _PATH_DEV_NNPFS0;
181 static struct getargs args[] = {
182 {"cache-dir", 0, arg_string, &cache_dir,
183 "cache directory", "directory"},
184 {"check-consistency", 'C', arg_flag, &cm_consistency,
185 "if we want extra paranoid consistency checks", NULL },
186 {"cpu-usage", 0, arg_flag, &cpu_usage,
187 NULL, NULL},
188 {"conffile", 'c', arg_string, &conf_file,
189 "path to configuration file", "file"},
190 {"connected-mode", 0, arg_string, &connected_mode_string,
191 "initial connected mode [conncted|fetch-only|disconnected]", NULL},
192 {"debug", 0, arg_string, &debug_levels,
193 "what to write in the log", NULL},
194 {"device", 'd', arg_string, &device_file,
195 "the NNPFS device to use [/dev/nnpfs0]", "path"},
196 {"dynroot", 'D', arg_flag, &dynroot_enable,
197 "if dynroot is enabled", NULL},
198 {"largefile", 0, arg_negative_flag, &use_o_largefile,
199 "stop using O_LARGEFILE flag when opening cache files", NULL},
200 {"log", 'l', arg_string, &log_file,
201 "where to write log (stderr (default), syslog, or path to file)", NULL},
202 {"fake-mp", 0, arg_flag, &fake_mp,
203 "enable fake mountpoints", NULL},
204 {"fake-stat", 0, arg_flag, &fake_stat,
205 "build stat info from afs rights", NULL},
206 {"fork", 'n', arg_negative_flag, &fork_flag,
207 "don't fork and demonize", NULL},
208 {"port", 0, arg_integer, &client_port,
209 "port number to use", "number"},
210 {"recover", 'z', arg_negative_flag, &recover,
211 "don't recover state", NULL},
212 {"root-volume",0, arg_string, &root_volume},
213 #ifdef KERBEROS
214 {"rxkad-level", 'r', arg_string, &rxkad_level_string,
215 "the rxkad level to use (clear, auth or crypt)", NULL},
216 #endif
217 {"sysname", 's', arg_string, &argv_sysname,
218 "set the sysname of this system", NULL},
219 {"tracefile", 0, arg_string, &trace_file,
220 "record nnpfs traffic in file", NULL},
221 {"workers", 0, arg_integer, &num_workers,
222 "number of worker threads", NULL},
223 {"version", 0, arg_flag, &version_flag,
224 NULL, NULL},
225 {"help", 0, arg_flag, &help_flag,
226 NULL, NULL}
229 static void
230 usage (int ret)
232 arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "[device]");
233 exit (ret);
237 main (int argc, char **argv)
239 int optind = 0;
240 int ret;
242 setprogname (argv[0]);
243 tzset();
244 srand(time(NULL));
246 if (getarg (args, sizeof(args)/sizeof(*args), argc, argv, &optind))
247 usage (1);
249 argc -= optind;
250 argv += optind;
252 if (help_flag)
253 usage (0);
255 if (version_flag) {
256 print_version (NULL);
257 exit (0);
260 if (argc > 0) {
261 device_file = *argv;
262 argc--;
263 argv++;
266 if (argc != 0)
267 usage (1);
269 if (!fork_flag)
270 default_log_file = _PATH_DEV_STDERR;
272 if (fork_flag)
273 daemonify ();
275 ret = arla_init();
276 if (ret)
277 return ret;
279 arla_start (device_file, cache_dir);
281 return 0;