*** empty log message ***
[arla.git] / arlad / arla.c
blob394f06e9f03951db431345210e5f477af57296b9
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.
35 * Test to talk with FS
38 #include "arla_local.h"
39 #include <parse_units.h>
40 #include <getarg.h>
42 RCSID("$Id$") ;
44 enum connected_mode connected_mode = CONNECTED;
46 static void
47 initrx (int userport)
49 int port = userport;
50 int error;
52 if (port == 0)
53 port = afscallbackport;
55 error = rx_Init (htons(port));
56 if (error == RX_ADDRINUSE && userport == 0)
57 error = rx_Init(0);
58 if (error)
59 arla_err (1, ADEBERROR, error, "rx_init");
63 void
64 store_state (void)
66 arla_warnx (ADEBMISC, "storing state");
67 fcache_store_state ();
68 volcache_store_state ();
69 cm_store_state ();
72 typedef enum { CONF_PARAM_INT,
73 CONF_PARAM_STR,
74 CONF_PARAM_BOOL,
75 CONF_PARAM_INT64
76 } conf_type;
78 struct conf_param {
79 const char *name;
80 conf_type type;
81 void *val;
85 * Reads in a configuration file, and sets some defaults.
88 static struct units size_units[] = {
89 { "G", 1024 * 1024 * 1024 },
90 { "M", 1024 * 1024 },
91 { "k", 1024 },
92 { NULL, 0 }
95 static void
96 read_conffile(const char *fname,
97 struct conf_param *params)
99 FILE *fp;
100 char buf[256];
101 int lineno;
102 struct conf_param *p;
104 arla_warnx (ADEBINIT, "read_conffile: %s", fname);
106 fp = fopen(fname, "r");
107 if (fp == NULL) {
108 arla_warn (ADEBINIT, errno, "open %s", fname);
109 return;
112 lineno = 0;
114 while (fgets (buf, sizeof(buf), fp) != NULL) {
115 struct conf_param *partial_param = NULL;
116 int partial_match = 0;
117 char *save = NULL;
118 char *n;
119 char *v;
120 int64_t val;
121 char *endptr;
123 ++lineno;
124 buf[strcspn(buf, "\n")] = '\0';
125 if (buf[0] == '\0' || buf[0] == '#')
126 continue;
128 n = strtok_r (buf, " \t", &save);
129 if (n == NULL) {
130 fprintf (stderr, "%s:%d: no parameter?\n", fname, lineno);
131 continue;
134 v = strtok_r (NULL, " \t", &save);
135 if (v == NULL) {
136 fprintf (stderr, "%s:%d: no value?\n", fname, lineno);
137 continue;
141 for (p = params; p->name; ++p) {
142 if (strcmp(n, p->name) == 0) {
143 partial_match = 1;
144 partial_param = p;
145 break;
146 } else if(strncmp(n, p->name, strlen(n)) == 0) {
147 ++partial_match;
148 partial_param = p;
151 if (partial_match == 0) {
152 fprintf (stderr, "%s:%d: unknown parameter `%s'\n",
153 fname, lineno, n);
154 continue;
155 } else if (partial_match != 1) {
156 fprintf (stderr, "%s:%d: ambiguous parameter `%s'\n",
157 fname, lineno, n);
158 continue;
161 p = partial_param;
163 switch (p->type) {
164 case CONF_PARAM_INT:
165 case CONF_PARAM_INT64:
167 /* parse_units is currently broken, so we roll our own for now */
169 #ifdef HAVE_STRTOLL
170 val = strtoll(v, &endptr, 0);
171 #else
172 val = strtol(v, &endptr, 0);
173 #endif
175 if (*endptr != '\0') {
176 struct units *u = size_units;
178 while (u->name != NULL) {
179 if (!strcmp(endptr, u->name)) {
180 val *= u->mult;
181 break;
183 u++;
186 if (u->name == NULL)
187 fprintf (stderr, "%s:%d: bad value `%s'\n",
188 fname, lineno, v);
191 if (p->type == CONF_PARAM_INT)
192 *((unsigned *)partial_param->val) = val;
193 else if (p->type == CONF_PARAM_INT64)
194 *((int64_t *)partial_param->val) = val;
195 else
196 abort();
197 break;
199 case CONF_PARAM_STR:
201 *((char **)partial_param->val) = strdup(v);
203 break;
205 case CONF_PARAM_BOOL:
207 if (strcasecmp(v, "yes") == 0 || strcasecmp(v, "true") == 0)
208 *((unsigned *)partial_param->val) = 1;
209 else if (strcasecmp(v, "no") == 0 || strcasecmp(v, "false") == 0)
210 *((unsigned *)partial_param->val) = 0;
211 else
212 fprintf (stderr, "%s:%d: bad boolean value `%s'\n",
213 fname, lineno, v);
214 break;
215 default:
216 abort();
222 fclose(fp);
225 static unsigned low_vnodes = ARLA_LOW_VNODES;
226 static unsigned high_vnodes = ARLA_HIGH_VNODES;
227 static int64_t low_bytes = ARLA_LOW_BYTES;
228 static int64_t high_bytes = ARLA_HIGH_BYTES;
229 static uint64_t blocksize = ARLA_BLOCKSIZE;
230 static unsigned numcreds = ARLA_NUMCREDS;
231 static unsigned numconns = ARLA_NUMCONNS;
232 static unsigned numvols = ARLA_NUMVOLS;
233 static unsigned dynrootlevel = DYNROOT_DEFAULT;
234 static char *conf_sysname = NULL; /* sysname from conf file */
235 const char *argv_sysname = NULL; /* sysname from argv */
236 int num_workers = 16;
237 #ifdef KERBEROS
238 const char *rxkad_level_string = "crypt";
239 #endif
241 static struct conf_param conf_params[] = {
242 {"dynroot", CONF_PARAM_BOOL, &dynrootlevel},
243 {"fake_stat", CONF_PARAM_BOOL, &fake_stat},
244 {"fake_mp", CONF_PARAM_BOOL, &fake_mp},
245 {"fetch_block", CONF_PARAM_INT64, &fetch_block_size},
246 {"blocksize", CONF_PARAM_INT64, &blocksize},
247 {"low_vnodes", CONF_PARAM_INT, &low_vnodes},
248 {"high_vnodes", CONF_PARAM_INT, &high_vnodes},
249 {"low_bytes", CONF_PARAM_INT64, &low_bytes},
250 {"high_bytes", CONF_PARAM_INT64, &high_bytes},
251 {"numcreds", CONF_PARAM_INT, &numcreds},
252 {"numconns", CONF_PARAM_INT, &numconns},
253 {"numvols", CONF_PARAM_INT, &numvols},
254 {"sysname", CONF_PARAM_STR, &conf_sysname},
255 {"workers", CONF_PARAM_INT, &num_workers},
256 #ifdef KERBEROS
257 {"rxkad-level", CONF_PARAM_STR, &rxkad_level_string},
258 #endif
259 { NULL }
262 const char *conf_file = ARLACONFFILE;
263 char *log_file = NULL;
264 char *debug_levels = NULL;
265 char *connected_mode_string = NULL;
266 char *root_volume;
267 int cpu_usage;
268 int version_flag;
269 int help_flag;
270 int recover = 0;
271 int dynroot_enable = 0;
272 int cm_consistency = 0;
273 int fake_stat = 0;
276 * These are exported to other modules
279 char *cache_dir;
280 int fake_mp;
281 int fork_flag = 1;
282 int use_o_largefile = 1;
283 char *trace_file = NULL;
286 * Global AFS variables, se arla_local.h for comment
289 int afs_BusyWaitPeriod = 15;
295 static int
296 parse_string_list (const char *s, const char **units)
298 const char **p;
299 int partial_val = 0;
300 int partial_match = 0;
302 for (p = units; *p; ++p) {
303 if (strcmp (s, *p) == 0)
304 return p - units;
305 if (strncmp (s, *p, strlen(s)) == 0) {
306 partial_match++;
307 partial_val = p - units;
310 if (partial_match == 1)
311 return partial_val;
312 else
313 return -1;
316 #ifdef KERBEROS
317 static const char *rxkad_level_units[] = {
318 "clear", /* 0 */
319 "auth", /* 1 */
320 "crypt", /* 2 */
321 NULL
324 static int
325 parse_rxkad_level (const char *s)
327 return parse_string_list (s, rxkad_level_units);
329 #endif
331 static const char *connected_levels[] = {
332 "connected", /* CONNECTED = 0 */
333 "fetch-only", /* FETCH_ONLY = 1 */
334 "disconnected", /* DISCONNCTED = 2 */
335 NULL
338 static int
339 set_connected_mode (const char *s)
341 return parse_string_list (s, connected_levels);
349 arla_init (void)
351 log_flags log_flags;
352 char fpriofile[MAXPATHLEN];
353 const char *temp_sysname;
355 if (log_file == NULL)
356 log_file = default_log_file;
358 if (strcmp(log_file, "syslog") == 0)
359 log_file = "syslog:no-delay";
361 log_flags = 0;
362 if (cpu_usage)
363 log_flags |= LOG_CPU_USAGE;
364 arla_loginit(log_file, log_flags);
366 if (debug_levels != NULL) {
367 if (arla_log_set_level (debug_levels) < 0) {
368 warnx ("bad debug levels: `%s'", debug_levels);
369 arla_log_print_levels (stderr);
370 exit (1);
374 if (connected_mode_string != NULL) {
375 int tmp = set_connected_mode (connected_mode_string);
377 if (tmp < 0)
378 errx (1, "bad connected mode: `%s'", connected_mode_string);
379 connected_mode = tmp;
380 if (connected_mode != CONNECTED)
381 disco_openlog();
384 read_conffile(conf_file, conf_params);
386 if (low_vnodes > high_vnodes)
387 arla_errx (1, ADEBERROR, "low vnode is larger then high vnodes, "
388 "cowardly refusing to start (%d > %d) "
389 "(check BUGS section in arla.conf manual page)",
390 low_vnodes, high_vnodes);
391 if (low_bytes > high_bytes)
392 arla_errx (1, ADEBERROR, "low bytes is larger then high bytes, "
393 "cowardly refusing to start "
394 "(check BUGS section in arla.conf manual page)");
397 #ifdef KERBEROS
398 conn_rxkad_level = parse_rxkad_level (rxkad_level_string);
399 if (conn_rxkad_level < 0)
400 errx (1, "bad rxkad level `%s'", rxkad_level_string);
401 #endif
403 if (cache_dir == NULL)
404 cache_dir = get_default_cache_dir();
406 if (mkdir (cache_dir, 0777) < 0 && errno != EEXIST)
407 arla_err (1, ADEBERROR, errno, "mkdir %s", cache_dir);
408 if (chdir (cache_dir) < 0)
409 arla_err (1, ADEBERROR, errno, "chdir %s", cache_dir);
412 if (argv_sysname)
413 temp_sysname = argv_sysname;
414 else if (conf_sysname)
415 temp_sysname = conf_sysname;
416 else
417 temp_sysname = arla_getsysname ();
419 if (temp_sysname != NULL)
420 fcache_setdefsysname(temp_sysname);
422 if (dynrootlevel || dynroot_enable)
423 dynroot_setenable (TRUE);
425 snprintf(fpriofile, sizeof(fpriofile), "%s/%s", cache_dir, "fprio");
428 * Init
431 arla_warnx (ADEBINIT,"Arlad booting sequence:");
432 arla_warnx (ADEBINIT, "connected mode: %s",
433 connected_levels[connected_mode]);
434 arla_warnx (ADEBINIT, "ports_init");
435 ports_init ();
436 arla_warnx (ADEBINIT, "uae_init");
437 uae_init ();
438 arla_warnx (ADEBINIT, "rx");
439 initrx (client_port);
440 arla_warnx (ADEBINIT, "conn_init numconns = %u", numconns);
441 conn_init (numconns);
442 arla_warnx (ADEBINIT, "cellcache");
443 cell_init (0, arla_log_method);
444 arla_warnx (ADEBINIT, "poller");
445 poller_init();
446 arla_warnx (ADEBINIT, "fprio");
447 fprio_init(fpriofile);
448 arla_warnx (ADEBINIT, "volcache numvols = %u", numvols);
449 volcache_init (numvols, recover);
450 if (root_volume != NULL)
451 volcache_set_rootvolume (root_volume);
452 #ifdef KERBEROS
453 arla_warnx (ADEBINIT, "using rxkad level %s",
454 rxkad_level_units[conn_rxkad_level]);
455 #endif
458 * Credential cache
460 arla_warnx (ADEBINIT, "credcache numcreds = %u", numcreds);
461 cred_init (numcreds);
463 arla_warnx (ADEBINIT,
464 "fcache low_vnodes = %u, high_vnodes = %u "
465 "low_bytes = %lld, high_bytes = %lld",
466 low_vnodes, high_vnodes,
467 (long long)low_bytes, (long long)high_bytes);
468 fcache_init (low_vnodes, high_vnodes,
469 low_bytes, high_bytes, blocksize, recover);
471 arla_warnx (ADEBINIT, "cmcb");
472 cmcb_init ();
474 arla_warnx(ADEBINIT, "cm");
475 cm_init ();
477 if (cm_consistency) {
478 arla_warnx(ADEBINIT, "turning on consistency test");
479 cm_turn_on_consistency_check();
482 arla_warnx(ADEBINIT, "arla init done.");
484 return 0;