(afsrights2nnpfsrights): export
[arla.git] / arlad / arla.c
blob2f5833616ca1518bb76639c6543c8b08b27eb024
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 nnpfs_trace = 0;
237 int num_workers = 16;
238 #ifdef KERBEROS
239 const char *rxkad_level_string = "crypt";
240 #endif
242 static struct conf_param conf_params[] = {
243 {"dynroot", CONF_PARAM_BOOL, &dynrootlevel},
244 {"fake_stat", CONF_PARAM_BOOL, &fake_stat},
245 {"fake_mp", CONF_PARAM_BOOL, &fake_mp},
246 {"fetch_block", CONF_PARAM_INT64, &fetch_block_size},
247 {"blocksize", CONF_PARAM_INT64, &blocksize},
248 {"low_vnodes", CONF_PARAM_INT, &low_vnodes},
249 {"high_vnodes", CONF_PARAM_INT, &high_vnodes},
250 {"low_bytes", CONF_PARAM_INT64, &low_bytes},
251 {"high_bytes", CONF_PARAM_INT64, &high_bytes},
252 {"numcreds", CONF_PARAM_INT, &numcreds},
253 {"numconns", CONF_PARAM_INT, &numconns},
254 {"numvols", CONF_PARAM_INT, &numvols},
255 {"sysname", CONF_PARAM_STR, &conf_sysname},
256 {"workers", CONF_PARAM_INT, &num_workers},
257 {"nnpfs_trace", CONF_PARAM_BOOL, &nnpfs_trace},
258 {"nnpfs_trace_file", CONF_PARAM_STR, &trace_file},
259 #ifdef KERBEROS
260 {"rxkad-level", CONF_PARAM_STR, &rxkad_level_string},
261 #endif
262 { NULL }
265 const char *conf_file = ARLACONFFILE;
266 char *log_file = NULL;
267 char *debug_levels = NULL;
268 char *connected_mode_string = NULL;
269 char *root_volume;
270 int cpu_usage;
271 int version_flag;
272 int help_flag;
273 int recover = 0;
274 int dynroot_enable = 0;
275 int cm_consistency = 0;
276 int fake_stat = 0;
279 * These are exported to other modules
282 char *cache_dir;
283 int fake_mp;
284 int fork_flag = 1;
285 int use_o_largefile = 1;
286 char *trace_file = "arla.trace";
289 * Global AFS variables, se arla_local.h for comment
292 int afs_BusyWaitPeriod = 15;
298 static int
299 parse_string_list (const char *s, const char **units)
301 const char **p;
302 int partial_val = 0;
303 int partial_match = 0;
305 for (p = units; *p; ++p) {
306 if (strcmp (s, *p) == 0)
307 return p - units;
308 if (strncmp (s, *p, strlen(s)) == 0) {
309 partial_match++;
310 partial_val = p - units;
313 if (partial_match == 1)
314 return partial_val;
315 else
316 return -1;
319 #ifdef KERBEROS
320 static const char *rxkad_level_units[] = {
321 "clear", /* 0 */
322 "auth", /* 1 */
323 "crypt", /* 2 */
324 NULL
327 static int
328 parse_rxkad_level (const char *s)
330 return parse_string_list (s, rxkad_level_units);
332 #endif
334 static const char *connected_levels[] = {
335 "connected", /* CONNECTED = 0 */
336 "fetch-only", /* FETCH_ONLY = 1 */
337 "disconnected", /* DISCONNCTED = 2 */
338 NULL
341 static int
342 set_connected_mode (const char *s)
344 return parse_string_list (s, connected_levels);
352 arla_init (void)
354 log_flags log_flags;
355 char fpriofile[MAXPATHLEN];
356 const char *temp_sysname;
358 if (log_file == NULL)
359 log_file = default_log_file;
361 if (strcmp(log_file, "syslog") == 0)
362 log_file = "syslog:no-delay";
364 log_flags = 0;
365 if (cpu_usage)
366 log_flags |= LOG_CPU_USAGE;
367 arla_loginit(log_file, log_flags);
369 if (debug_levels != NULL) {
370 if (arla_log_set_level (debug_levels) < 0) {
371 warnx ("bad debug levels: `%s'", debug_levels);
372 arla_log_print_levels (stderr);
373 exit (1);
377 if (connected_mode_string != NULL) {
378 int tmp = set_connected_mode (connected_mode_string);
380 if (tmp < 0)
381 errx (1, "bad connected mode: `%s'", connected_mode_string);
382 connected_mode = tmp;
383 if (connected_mode != CONNECTED)
384 disco_openlog();
387 read_conffile(conf_file, conf_params);
389 if (low_vnodes > high_vnodes)
390 arla_errx (1, ADEBERROR, "low vnode is larger then high vnodes, "
391 "cowardly refusing to start (%d > %d) "
392 "(check BUGS section in arla.conf manual page)",
393 low_vnodes, high_vnodes);
394 if (low_bytes > high_bytes)
395 arla_errx (1, ADEBERROR, "low bytes is larger then high bytes, "
396 "cowardly refusing to start "
397 "(check BUGS section in arla.conf manual page)");
400 #ifdef KERBEROS
401 conn_rxkad_level = parse_rxkad_level (rxkad_level_string);
402 if (conn_rxkad_level < 0)
403 errx (1, "bad rxkad level `%s'", rxkad_level_string);
404 #endif
406 if (cache_dir == NULL)
407 cache_dir = get_default_cache_dir();
409 if (mkdir (cache_dir, 0777) < 0 && errno != EEXIST)
410 arla_err (1, ADEBERROR, errno, "mkdir %s", cache_dir);
411 if (chdir (cache_dir) < 0)
412 arla_err (1, ADEBERROR, errno, "chdir %s", cache_dir);
415 if (argv_sysname)
416 temp_sysname = argv_sysname;
417 else if (conf_sysname)
418 temp_sysname = conf_sysname;
419 else
420 temp_sysname = arla_getsysname ();
422 if (temp_sysname != NULL)
423 fcache_setdefsysname(temp_sysname);
425 if (dynrootlevel || dynroot_enable)
426 dynroot_setenable (TRUE);
428 if (!nnpfs_trace)
429 trace_file = NULL;
432 snprintf(fpriofile, sizeof(fpriofile), "%s/%s", cache_dir, "fprio");
435 * Init
438 arla_warnx (ADEBINIT,"Arlad booting sequence:");
439 arla_warnx (ADEBINIT, "connected mode: %s",
440 connected_levels[connected_mode]);
441 arla_warnx (ADEBINIT, "ports_init");
442 ports_init ();
443 arla_warnx (ADEBINIT, "uae_init");
444 uae_init ();
445 arla_warnx (ADEBINIT, "rx");
446 initrx (client_port);
447 arla_warnx (ADEBINIT, "conn_init numconns = %u", numconns);
448 conn_init (numconns);
449 arla_warnx (ADEBINIT, "cellcache");
450 cell_init (0, arla_log_method);
451 arla_warnx (ADEBINIT, "poller");
452 poller_init();
453 arla_warnx (ADEBINIT, "fprio");
454 fprio_init(fpriofile);
455 arla_warnx (ADEBINIT, "volcache numvols = %u", numvols);
456 volcache_init (numvols, recover);
457 if (root_volume != NULL)
458 volcache_set_rootvolume (root_volume);
459 #ifdef KERBEROS
460 arla_warnx (ADEBINIT, "using rxkad level %s",
461 rxkad_level_units[conn_rxkad_level]);
462 #endif
465 * Credential cache
467 arla_warnx (ADEBINIT, "credcache numcreds = %u", numcreds);
468 cred_init (numcreds);
470 arla_warnx (ADEBINIT,
471 "fcache low_vnodes = %u, high_vnodes = %u "
472 "low_bytes = %lld, high_bytes = %lld",
473 low_vnodes, high_vnodes,
474 (long long)low_bytes, (long long)high_bytes);
475 fcache_init (low_vnodes, high_vnodes,
476 low_bytes, high_bytes, blocksize, recover);
478 arla_warnx (ADEBINIT, "cmcb");
479 cmcb_init ();
481 arla_warnx(ADEBINIT, "cm");
482 cm_init ();
484 if (cm_consistency) {
485 arla_warnx(ADEBINIT, "turning on consistency test");
486 cm_turn_on_consistency_check();
489 arla_warnx(ADEBINIT, "arla init done.");
491 return 0;