Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | #include <afsconfig.h> | |
11 | #include <afs/param.h> | |
12 | #include <afs/stds.h> | |
13 | ||
14 | #include <roken.h> | |
15 | #ifdef AFS_PTHREAD_ENV | |
16 | # include <opr/softsig.h> | |
17 | # include <afs/procmgmt_softsig.h> /* must come after softsig.h */ | |
18 | #endif | |
19 | ||
20 | #ifdef AFS_NT40_ENV | |
21 | #include <WINNT/afsevent.h> | |
22 | #endif | |
23 | ||
24 | #ifdef HAVE_SYS_FILE_H | |
25 | #include <sys/file.h> | |
26 | #endif | |
27 | ||
28 | #include <rx/xdr.h> | |
29 | #include <rx/rx.h> | |
30 | #include <rx/rx_globals.h> | |
31 | #include <rx/rxstat.h> | |
32 | #include <afs/cmd.h> | |
33 | #include <afs/cellconfig.h> | |
34 | #include <afs/keys.h> | |
35 | #include <afs/auth.h> | |
36 | #include <afs/audit.h> | |
37 | #include <afs/com_err.h> | |
38 | #include <lock.h> | |
39 | #include <ubik.h> | |
40 | #include <afs/afsutil.h> | |
41 | ||
42 | #include "vlserver.h" | |
43 | #include "vlserver_internal.h" | |
44 | ||
45 | #define MAXLWP 64 | |
46 | struct afsconf_dir *vldb_confdir = 0; /* vldb configuration dir */ | |
47 | int lwps = 9; | |
48 | ||
49 | struct vldstats dynamic_statistics; | |
50 | struct ubik_dbase *VL_dbase; | |
51 | afs_uint32 rd_HostAddress[MAXSERVERID + 1]; | |
52 | afs_uint32 wr_HostAddress[MAXSERVERID + 1]; | |
53 | ||
54 | static void *CheckSignal(void*); | |
55 | int smallMem = 0; | |
56 | int restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER; | |
57 | int rxJumbograms = 0; /* default is to not send and receive jumbo grams */ | |
58 | int rxMaxMTU = -1; | |
59 | afs_int32 rxBind = 0; | |
60 | int rxkadDisableDotCheck = 0; | |
61 | ||
62 | #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */ | |
63 | afs_uint32 SHostAddrs[ADDRSPERSITE]; | |
64 | ||
65 | static void | |
66 | CheckSignal_Signal(int unused) | |
67 | { | |
68 | #if defined(AFS_PTHREAD_ENV) | |
69 | CheckSignal(0); | |
70 | #else | |
71 | IOMGR_SoftSig(CheckSignal, 0); | |
72 | #endif | |
73 | } | |
74 | ||
75 | static void * | |
76 | CheckSignal(void *unused) | |
77 | { | |
78 | int i, errorcode; | |
79 | struct vl_ctx ctx; | |
80 | ||
81 | if ((errorcode = | |
82 | Init_VLdbase(&ctx, LOCKREAD, VLGETSTATS - VL_LOWEST_OPCODE))) | |
83 | return (void *)(intptr_t)errorcode; | |
84 | VLog(0, ("Dump name hash table out\n")); | |
85 | for (i = 0; i < HASHSIZE; i++) { | |
86 | HashNDump(&ctx, i); | |
87 | } | |
88 | VLog(0, ("Dump id hash table out\n")); | |
89 | for (i = 0; i < HASHSIZE; i++) { | |
90 | HashIdDump(&ctx, i); | |
91 | } | |
92 | return ((void *)(intptr_t)ubik_EndTrans(ctx.trans)); | |
93 | } /*CheckSignal */ | |
94 | ||
95 | ||
96 | /* Initialize the stats for the opcodes */ | |
97 | void | |
98 | initialize_dstats(void) | |
99 | { | |
100 | int i; | |
101 | ||
102 | dynamic_statistics.start_time = (afs_uint32) time(0); | |
103 | for (i = 0; i < MAX_NUMBER_OPCODES; i++) { | |
104 | dynamic_statistics.requests[i] = 0; | |
105 | dynamic_statistics.aborts[i] = 0; | |
106 | } | |
107 | } | |
108 | ||
109 | /* check whether caller is authorized to manage RX statistics */ | |
110 | int | |
111 | vldb_rxstat_userok(struct rx_call *call) | |
112 | { | |
113 | return afsconf_SuperUser(vldb_confdir, call, NULL); | |
114 | } | |
115 | ||
116 | /** | |
117 | * Return true if this name is a member of the local realm. | |
118 | */ | |
119 | int | |
120 | vldb_IsLocalRealmMatch(void *rock, char *name, char *inst, char *cell) | |
121 | { | |
122 | struct afsconf_dir *dir = (struct afsconf_dir *)rock; | |
123 | afs_int32 islocal = 0; /* default to no */ | |
124 | int code; | |
125 | ||
126 | code = afsconf_IsLocalRealmMatch(dir, &islocal, name, inst, cell); | |
127 | if (code) { | |
128 | VLog(0, | |
129 | ("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n", | |
130 | code, name, inst, cell)); | |
131 | } | |
132 | return islocal; | |
133 | } | |
134 | ||
135 | /* Main server module */ | |
136 | ||
137 | #include "AFS_component_version_number.c" | |
138 | ||
139 | enum optionsList { | |
140 | OPT_noauth, | |
141 | OPT_smallmem, | |
142 | OPT_auditlog, | |
143 | OPT_auditiface, | |
144 | OPT_config, | |
145 | OPT_debug, | |
146 | OPT_database, | |
147 | OPT_logfile, | |
148 | OPT_threads, | |
149 | #ifdef HAVE_SYSLOG | |
150 | OPT_syslog, | |
151 | #endif | |
152 | OPT_peer, | |
153 | OPT_process, | |
154 | OPT_nojumbo, | |
155 | OPT_jumbo, | |
156 | OPT_rxbind, | |
157 | OPT_rxmaxmtu, | |
158 | OPT_trace, | |
159 | OPT_dotted, | |
160 | OPT_restricted_query, | |
161 | OPT_transarc_logs | |
162 | }; | |
163 | ||
164 | int | |
165 | main(int argc, char **argv) | |
166 | { | |
167 | afs_int32 code; | |
168 | afs_uint32 myHost; | |
169 | struct rx_service *tservice; | |
170 | struct rx_securityClass **securityClasses; | |
171 | afs_int32 numClasses; | |
172 | struct afsconf_dir *tdir; | |
173 | struct ktc_encryptionKey tkey; | |
174 | struct afsconf_cell info; | |
175 | struct hostent *th; | |
176 | char hostname[VL_MAXNAMELEN]; | |
177 | int noAuth = 0; | |
178 | char clones[MAXHOSTSPERCELL]; | |
179 | afs_uint32 host = ntohl(INADDR_ANY); | |
180 | struct cmd_syndesc *opts; | |
181 | struct logOptions logopts; | |
182 | ||
183 | char *vl_dbaseName; | |
184 | char *configDir; | |
185 | ||
186 | char *auditFileName = NULL; | |
187 | char *interface = NULL; | |
188 | char *optstring = NULL; | |
189 | ||
190 | char *restricted_query_parameter = NULL; | |
191 | ||
192 | #ifdef AFS_AIX32_ENV | |
193 | /* | |
194 | * The following signal action for AIX is necessary so that in case of a | |
195 | * crash (i.e. core is generated) we can include the user's data section | |
196 | * in the core dump. Unfortunately, by default, only a partial core is | |
197 | * generated which, in many cases, isn't too useful. | |
198 | */ | |
199 | struct sigaction nsa; | |
200 | ||
201 | rx_extraPackets = 100; /* should be a switch, I guess... */ | |
202 | sigemptyset(&nsa.sa_mask); | |
203 | nsa.sa_handler = SIG_DFL; | |
204 | nsa.sa_flags = SA_FULLDUMP; | |
205 | sigaction(SIGABRT, &nsa, NULL); | |
206 | sigaction(SIGSEGV, &nsa, NULL); | |
207 | #endif | |
208 | osi_audit_init(); | |
209 | ||
210 | memset(&logopts, 0, sizeof(logopts)); | |
211 | ||
212 | /* Initialize dirpaths */ | |
213 | if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { | |
214 | #ifdef AFS_NT40_ENV | |
215 | ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); | |
216 | #endif | |
217 | fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", | |
218 | argv[0]); | |
219 | exit(2); | |
220 | } | |
221 | ||
222 | vl_dbaseName = strdup(AFSDIR_SERVER_VLDB_FILEPATH); | |
223 | configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH); | |
224 | ||
225 | cmd_DisableAbbreviations(); | |
226 | cmd_DisablePositionalCommands(); | |
227 | opts = cmd_CreateSyntax(NULL, NULL, NULL, 0, NULL); | |
228 | ||
229 | /* vlserver specific options */ | |
230 | cmd_AddParmAtOffset(opts, OPT_noauth, "-noauth", CMD_FLAG, | |
231 | CMD_OPTIONAL, "disable authentication"); | |
232 | cmd_AddParmAtOffset(opts, OPT_smallmem, "-smallmem", CMD_FLAG, | |
233 | CMD_OPTIONAL, "optimise for small memory systems"); | |
234 | ||
235 | /* general server options */ | |
236 | cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE, | |
237 | CMD_OPTIONAL, "location of audit log"); | |
238 | cmd_AddParmAtOffset(opts, OPT_auditiface, "-audit-interface", CMD_SINGLE, | |
239 | CMD_OPTIONAL, "interface to use for audit logging"); | |
240 | cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE, | |
241 | CMD_OPTIONAL, "configuration location"); | |
242 | cmd_AddParmAtOffset(opts, OPT_debug, "-d", CMD_SINGLE, | |
243 | CMD_OPTIONAL, "debug level"); | |
244 | cmd_AddParmAtOffset(opts, OPT_database, "-database", CMD_SINGLE, | |
245 | CMD_OPTIONAL, "database file"); | |
246 | cmd_AddParmAlias(opts, OPT_database, "-db"); | |
247 | cmd_AddParmAtOffset(opts, OPT_logfile, "-logfile", CMD_SINGLE, | |
248 | CMD_OPTIONAL, "location of logfile"); | |
249 | cmd_AddParmAtOffset(opts, OPT_threads, "-p", CMD_SINGLE, CMD_OPTIONAL, | |
250 | "number of threads"); | |
251 | #ifdef HAVE_SYSLOG | |
252 | cmd_AddParmAtOffset(opts, OPT_syslog, "-syslog", CMD_SINGLE_OR_FLAG, | |
253 | CMD_OPTIONAL, "log to syslog"); | |
254 | #endif | |
255 | cmd_AddParmAtOffset(opts, OPT_transarc_logs, "-transarc-logs", CMD_FLAG, | |
256 | CMD_OPTIONAL, "enable Transarc style logging"); | |
257 | ||
258 | /* rx options */ | |
259 | cmd_AddParmAtOffset(opts, OPT_peer, "-enable_peer_stats", CMD_FLAG, | |
260 | CMD_OPTIONAL, "enable RX transport statistics"); | |
261 | cmd_AddParmAtOffset(opts, OPT_process, "-enable_process_stats", CMD_FLAG, | |
262 | CMD_OPTIONAL, "enable RX RPC statistics"); | |
263 | cmd_AddParmAtOffset(opts, OPT_nojumbo, "-nojumbo", CMD_FLAG, | |
264 | CMD_OPTIONAL, "disable jumbograms"); | |
265 | cmd_AddParmAtOffset(opts, OPT_jumbo, "-jumbo", CMD_FLAG, | |
266 | CMD_OPTIONAL, "enable jumbograms"); | |
267 | cmd_AddParmAtOffset(opts, OPT_rxbind, "-rxbind", CMD_FLAG, | |
268 | CMD_OPTIONAL, "bind only to the primary interface"); | |
269 | cmd_AddParmAtOffset(opts, OPT_rxmaxmtu, "-rxmaxmtu", CMD_SINGLE, | |
270 | CMD_OPTIONAL, "maximum MTU for RX"); | |
271 | cmd_AddParmAtOffset(opts, OPT_trace, "-trace", CMD_SINGLE, | |
272 | CMD_OPTIONAL, "rx trace file"); | |
273 | cmd_AddParmAtOffset(opts, OPT_restricted_query, "-restricted_query", | |
274 | CMD_SINGLE, CMD_OPTIONAL, "anyuser | admin"); | |
275 | ||
276 | ||
277 | /* rxkad options */ | |
278 | cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals", | |
279 | CMD_FLAG, CMD_OPTIONAL, | |
280 | "permit Kerberos 5 principals with dots"); | |
281 | ||
282 | code = cmd_Parse(argc, argv, &opts); | |
283 | if (code == CMD_HELP) { | |
284 | exit(0); | |
285 | } | |
286 | if (code) | |
287 | return -1; | |
288 | ||
289 | cmd_OptionAsString(opts, OPT_config, &configDir); | |
290 | ||
291 | cmd_OpenConfigFile(AFSDIR_SERVER_CONFIG_FILE_FILEPATH); | |
292 | cmd_SetCommandName("vlserver"); | |
293 | ||
294 | /* vlserver options */ | |
295 | cmd_OptionAsFlag(opts, OPT_noauth, &noAuth); | |
296 | cmd_OptionAsFlag(opts, OPT_smallmem, &smallMem); | |
297 | if (cmd_OptionAsString(opts, OPT_trace, &optstring) == 0) { | |
298 | extern char rxi_tracename[80]; | |
299 | strcpy(rxi_tracename, optstring); | |
300 | free(optstring); | |
301 | optstring = NULL; | |
302 | } | |
303 | ||
304 | /* general server options */ | |
305 | ||
306 | cmd_OptionAsString(opts, OPT_auditlog, &auditFileName); | |
307 | ||
308 | if (cmd_OptionAsString(opts, OPT_auditiface, &interface) == 0) { | |
309 | if (osi_audit_interface(interface)) { | |
310 | printf("Invalid audit interface '%s'\n", interface); | |
311 | return -1; | |
312 | } | |
313 | free(interface); | |
314 | } | |
315 | ||
316 | cmd_OptionAsString(opts, OPT_database, &vl_dbaseName); | |
317 | ||
318 | if (cmd_OptionAsInt(opts, OPT_threads, &lwps) == 0) { | |
319 | if (lwps > MAXLWP) { | |
320 | printf("Warning: '-p %d' is too big; using %d instead\n", | |
321 | lwps, MAXLWP); | |
322 | lwps = MAXLWP; | |
323 | } | |
324 | } | |
325 | ||
326 | cmd_OptionAsInt(opts, OPT_debug, &logopts.lopt_logLevel); | |
327 | #ifdef HAVE_SYSLOG | |
328 | if (cmd_OptionPresent(opts, OPT_syslog)) { | |
329 | if (cmd_OptionPresent(opts, OPT_logfile)) { | |
330 | fprintf(stderr, "Invalid options: -syslog and -logfile are exclusive.\n"); | |
331 | return -1; | |
332 | } | |
333 | if (cmd_OptionPresent(opts, OPT_transarc_logs)) { | |
334 | fprintf(stderr, "Invalid options: -syslog and -transarc-logs are exclusive.\n"); | |
335 | return -1; | |
336 | } | |
337 | ||
338 | logopts.lopt_dest = logDest_syslog; | |
339 | logopts.lopt_facility = LOG_DAEMON; /* default value */ | |
340 | logopts.lopt_tag = "vlserver"; | |
341 | cmd_OptionAsInt(opts, OPT_syslog, &logopts.lopt_facility); | |
342 | } else | |
343 | #endif | |
344 | { | |
345 | logopts.lopt_dest = logDest_file; | |
346 | if (cmd_OptionPresent(opts, OPT_transarc_logs)) { | |
347 | logopts.lopt_rotateOnOpen = 1; | |
348 | logopts.lopt_rotateStyle = logRotate_old; | |
349 | } | |
350 | if (cmd_OptionPresent(opts, OPT_logfile)) | |
351 | cmd_OptionAsString(opts, OPT_logfile, (char**)&logopts.lopt_filename); | |
352 | else | |
353 | logopts.lopt_filename = AFSDIR_SERVER_VLOG_FILEPATH; | |
354 | } | |
355 | ||
356 | ||
357 | /* rx options */ | |
358 | if (cmd_OptionPresent(opts, OPT_peer)) | |
359 | rx_enablePeerRPCStats(); | |
360 | if (cmd_OptionPresent(opts, OPT_process)) | |
361 | rx_enableProcessRPCStats(); | |
362 | if (cmd_OptionPresent(opts, OPT_nojumbo)) | |
363 | rxJumbograms = 0; | |
364 | if (cmd_OptionPresent(opts, OPT_jumbo)) | |
365 | rxJumbograms = 1; | |
366 | ||
367 | cmd_OptionAsFlag(opts, OPT_rxbind, &rxBind); | |
368 | ||
369 | cmd_OptionAsInt(opts, OPT_rxmaxmtu, &rxMaxMTU); | |
370 | ||
371 | /* rxkad options */ | |
372 | cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck); | |
373 | ||
374 | /* restricted query */ | |
375 | if (cmd_OptionAsString(opts, OPT_restricted_query, | |
376 | &restricted_query_parameter) == 0) { | |
377 | if (strcmp(restricted_query_parameter, "anyuser") == 0) | |
378 | restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER; | |
379 | else if (strcmp(restricted_query_parameter, "admin") == 0) | |
380 | restrictedQueryLevel = RESTRICTED_QUERY_ADMIN; | |
381 | else { | |
382 | printf("invalid argument for -restricted_query: %s\n", | |
383 | restricted_query_parameter); | |
384 | return -1; | |
385 | } | |
386 | free(restricted_query_parameter); | |
387 | } | |
388 | ||
389 | if (auditFileName) { | |
390 | osi_audit_file(auditFileName); | |
391 | } | |
392 | ||
393 | OpenLog(&logopts); | |
394 | #ifdef AFS_PTHREAD_ENV | |
395 | opr_softsig_Init(); | |
396 | SetupLogSoftSignals(); | |
397 | #else | |
398 | SetupLogSignals(); | |
399 | #endif | |
400 | ||
401 | tdir = afsconf_Open(configDir); | |
402 | if (!tdir) { | |
403 | VLog(0, | |
404 | ("vlserver: can't open configuration files in dir %s, giving up.\n", | |
405 | configDir)); | |
406 | exit(1); | |
407 | } | |
408 | ||
409 | /* initialize audit user check */ | |
410 | osi_audit_set_user_check(tdir, vldb_IsLocalRealmMatch); | |
411 | ||
412 | #ifdef AFS_NT40_ENV | |
413 | /* initialize winsock */ | |
414 | if (afs_winsockInit() < 0) { | |
415 | ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); | |
416 | VLog(0, ("vlserver: couldn't initialize winsock. \n")); | |
417 | exit(1); | |
418 | } | |
419 | #endif | |
420 | /* get this host */ | |
421 | gethostname(hostname, sizeof(hostname)); | |
422 | th = gethostbyname(hostname); | |
423 | if (!th) { | |
424 | VLog(0, ("vlserver: couldn't get address of this host (%s).\n", | |
425 | hostname)); | |
426 | exit(1); | |
427 | } | |
428 | memcpy(&myHost, th->h_addr, sizeof(afs_uint32)); | |
429 | ||
430 | #if !defined(AFS_HPUX_ENV) && !defined(AFS_NT40_ENV) | |
431 | signal(SIGXCPU, CheckSignal_Signal); | |
432 | #endif | |
433 | /* get list of servers */ | |
434 | code = | |
435 | afsconf_GetExtendedCellInfo(tdir, NULL, AFSCONF_VLDBSERVICE, &info, | |
436 | clones); | |
437 | if (code) { | |
438 | printf("vlserver: Couldn't get cell server list for 'afsvldb'.\n"); | |
439 | exit(2); | |
440 | } | |
441 | ||
442 | vldb_confdir = tdir; /* Preserve our configuration dir */ | |
443 | /* rxvab no longer supported */ | |
444 | memset(&tkey, 0, sizeof(tkey)); | |
445 | ||
446 | if (noAuth) | |
447 | afsconf_SetNoAuthFlag(tdir, 1); | |
448 | ||
449 | if (rxBind) { | |
450 | afs_int32 ccode; | |
451 | #ifndef AFS_NT40_ENV | |
452 | if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || | |
453 | AFSDIR_SERVER_NETINFO_FILEPATH) { | |
454 | char reason[1024]; | |
455 | ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, | |
456 | ADDRSPERSITE, reason, | |
457 | AFSDIR_SERVER_NETINFO_FILEPATH, | |
458 | AFSDIR_SERVER_NETRESTRICT_FILEPATH); | |
459 | } else | |
460 | #endif | |
461 | { | |
462 | ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); | |
463 | } | |
464 | if (ccode == 1) { | |
465 | host = SHostAddrs[0]; | |
466 | rx_InitHost(host, htons(AFSCONF_VLDBPORT)); | |
467 | } | |
468 | } | |
469 | ||
470 | if (!rxJumbograms) { | |
471 | rx_SetNoJumbo(); | |
472 | } | |
473 | if (rxMaxMTU != -1) { | |
474 | if (rx_SetMaxMTU(rxMaxMTU) != 0) { | |
475 | VLog(0, ("rxMaxMTU %d invalid\n", rxMaxMTU)); | |
476 | return -1; | |
477 | } | |
478 | } | |
479 | ||
480 | code = rx_Init(htons(AFSCONF_VLDBPORT)); | |
481 | if (code < 0) { | |
482 | VLog(0, ("vlserver: Rx init failed: %d\n", code)); | |
483 | exit(1); | |
484 | } | |
485 | rx_SetRxDeadTime(50); | |
486 | ||
487 | ubik_nBuffers = 512; | |
488 | ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, tdir); | |
489 | ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects, | |
490 | afsconf_CheckAuth, tdir); | |
491 | ||
492 | ubik_SyncWriterCacheProc = vlsynccache; | |
493 | code = | |
494 | ubik_ServerInitByInfo(myHost, htons(AFSCONF_VLDBPORT), &info, clones, | |
495 | vl_dbaseName, &VL_dbase); | |
496 | if (code) { | |
497 | VLog(0, ("vlserver: Ubik init failed: %s\n", afs_error_message(code))); | |
498 | exit(2); | |
499 | } | |
500 | ||
501 | memset(rd_HostAddress, 0, sizeof(rd_HostAddress)); | |
502 | memset(wr_HostAddress, 0, sizeof(wr_HostAddress)); | |
503 | initialize_dstats(); | |
504 | ||
505 | afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses); | |
506 | ||
507 | tservice = | |
508 | rx_NewServiceHost(host, 0, USER_SERVICE_ID, "Vldb server", | |
509 | securityClasses, numClasses, | |
510 | VL_ExecuteRequest); | |
511 | if (tservice == (struct rx_service *)0) { | |
512 | VLog(0, ("vlserver: Could not create VLDB_SERVICE rx service\n")); | |
513 | exit(3); | |
514 | } | |
515 | rx_SetMinProcs(tservice, 2); | |
516 | if (lwps < 4) | |
517 | lwps = 4; | |
518 | rx_SetMaxProcs(tservice, lwps); | |
519 | ||
520 | if (rxkadDisableDotCheck) { | |
521 | rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, | |
522 | (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); | |
523 | } | |
524 | ||
525 | tservice = | |
526 | rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", | |
527 | securityClasses, numClasses, | |
528 | RXSTATS_ExecuteRequest); | |
529 | if (tservice == (struct rx_service *)0) { | |
530 | VLog(0, ("vlserver: Could not create rpc stats rx service\n")); | |
531 | exit(3); | |
532 | } | |
533 | rx_SetMinProcs(tservice, 2); | |
534 | rx_SetMaxProcs(tservice, 4); | |
535 | ||
536 | LogCommandLine(argc, argv, "vlserver", VldbVersion, "Starting AFS", FSLog); | |
537 | if (afsconf_GetLatestKey(tdir, NULL, NULL) == 0) { | |
538 | LogDesWarning(); | |
539 | } | |
540 | VLog(0, ("%s\n", cml_version_number)); | |
541 | ||
542 | /* allow super users to manage RX statistics */ | |
543 | rx_SetRxStatUserOk(vldb_rxstat_userok); | |
544 | ||
545 | rx_StartServer(1); /* Why waste this idle process?? */ | |
546 | ||
547 | return 0; /* not reachable */ | |
548 | } |