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 | ||
13 | #include <roken.h> | |
14 | #include <afs/opr.h> | |
15 | #ifdef AFS_PTHREAD_ENV | |
16 | # include <opr/lock.h> | |
17 | # include <opr/softsig.h> | |
18 | # include <afs/procmgmt_softsig.h> /* must come after softsig */ | |
19 | #endif | |
20 | ||
21 | #ifdef AFS_NT40_ENV | |
22 | #include <windows.h> | |
23 | #include <WINNT/afsevent.h> | |
24 | #endif | |
25 | ||
26 | #include <rx/rx_queue.h> | |
27 | #include <afs/afsint.h> | |
28 | #include <afs/prs_fs.h> | |
29 | #include <afs/nfs.h> | |
30 | #include <lwp.h> | |
31 | #include <lock.h> | |
32 | #include <afs/afssyscalls.h> | |
33 | #include <afs/ihandle.h> | |
34 | #ifdef AFS_NT40_ENV | |
35 | #include <afs/ntops.h> | |
36 | #endif | |
37 | #include <afs/vnode.h> | |
38 | #include <afs/volume.h> | |
39 | #include <afs/partition.h> | |
40 | #include <rx/rx.h> | |
41 | #include <rx/rxstat.h> | |
42 | #include <rx/rx_globals.h> | |
43 | #include <afs/auth.h> | |
44 | #include <afs/cellconfig.h> | |
45 | #include <afs/keys.h> | |
46 | #include <afs/dir.h> | |
47 | #include <ubik.h> | |
48 | #include <afs/audit.h> | |
49 | #include <afs/afsutil.h> | |
50 | #include <afs/cmd.h> | |
51 | #include <lwp.h> | |
52 | ||
53 | #include "volser.h" | |
54 | #include "volint.h" | |
55 | #include "volser_internal.h" | |
56 | ||
57 | #define VolserVersion "2.0" | |
58 | #define N_SECURITY_OBJECTS 3 | |
59 | ||
60 | extern struct Lock localLock; | |
61 | char *GlobalNameHack = NULL; | |
62 | int hackIsIn = 0; | |
63 | afs_int32 GlobalVolCloneId, GlobalVolParentId; | |
64 | int GlobalVolType; | |
65 | int VolumeChanged; /* XXXX */ | |
66 | static char busyFlags[MAXHELPERS]; | |
67 | struct volser_trans *QI_GlobalWriteTrans = 0; | |
68 | struct afsconf_dir *tdir; | |
69 | static afs_int32 runningCalls = 0; | |
70 | int DoLogging = 0; | |
71 | int debuglevel = 0; | |
72 | #define MAXLWP 128 | |
73 | int lwps = 9; | |
74 | int udpBufSize = 0; /* UDP buffer size for receive */ | |
75 | int restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER; | |
76 | ||
77 | int rxBind = 0; | |
78 | int rxkadDisableDotCheck = 0; | |
79 | int DoPreserveVolumeStats = 1; | |
80 | int rxJumbograms = 0; /* default is to not send and receive jumbograms. */ | |
81 | int rxMaxMTU = -1; | |
82 | char *auditFileName = NULL; | |
83 | static struct logOptions logopts; | |
84 | char *configDir = NULL; | |
85 | ||
86 | enum vol_s2s_crypt doCrypt = VS2SC_NEVER; | |
87 | ||
88 | #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */ | |
89 | afs_uint32 SHostAddrs[ADDRSPERSITE]; | |
90 | ||
91 | #define VS_EXIT(code) { \ | |
92 | osi_audit(VS_ExitEvent, code, AUD_END); \ | |
93 | exit(code); \ | |
94 | } | |
95 | ||
96 | static void | |
97 | MyBeforeProc(struct rx_call *acall) | |
98 | { | |
99 | VTRANS_LOCK; | |
100 | runningCalls++; | |
101 | VTRANS_UNLOCK; | |
102 | return; | |
103 | } | |
104 | ||
105 | static void | |
106 | MyAfterProc(struct rx_call *acall, afs_int32 code) | |
107 | { | |
108 | VTRANS_LOCK; | |
109 | runningCalls--; | |
110 | VTRANS_UNLOCK; | |
111 | return; | |
112 | } | |
113 | ||
114 | /* Called every GCWAKEUP seconds to try to unlock all our partitions, | |
115 | * if we're idle and there are no active transactions | |
116 | */ | |
117 | static void | |
118 | TryUnlock(void) | |
119 | { | |
120 | /* if there are no running calls, and there are no active transactions, then | |
121 | * it should be safe to release any partition locks we've accumulated */ | |
122 | VTRANS_LOCK; | |
123 | if (runningCalls == 0 && TransList() == (struct volser_trans *)0) { | |
124 | VTRANS_UNLOCK; | |
125 | VPFullUnlock(); /* in volprocs.c */ | |
126 | } else | |
127 | VTRANS_UNLOCK; | |
128 | } | |
129 | ||
130 | /* background daemon for timing out transactions */ | |
131 | static void* | |
132 | BKGLoop(void *unused) | |
133 | { | |
134 | struct timeval tv; | |
135 | int loop = 0; | |
136 | ||
137 | afs_pthread_setname_self("vol bkg"); | |
138 | while (1) { | |
139 | tv.tv_sec = GCWAKEUP; | |
140 | tv.tv_usec = 0; | |
141 | #ifdef AFS_PTHREAD_ENV | |
142 | #ifdef AFS_NT40_ENV | |
143 | Sleep(GCWAKEUP * 1000); | |
144 | #else | |
145 | select(0, 0, 0, 0, &tv); | |
146 | #endif | |
147 | #else | |
148 | (void)IOMGR_Select(0, 0, 0, 0, &tv); | |
149 | #endif | |
150 | GCTrans(); | |
151 | TryUnlock(); | |
152 | loop++; | |
153 | if (loop == 10) { /* reopen log every 5 minutes */ | |
154 | loop = 0; | |
155 | ReOpenLog(); | |
156 | } | |
157 | } | |
158 | ||
159 | AFS_UNREACHED(return(NULL)); | |
160 | } | |
161 | ||
162 | #if defined(AFS_NT40_ENV) || defined(AFS_DARWIN160_ENV) | |
163 | /* no volser_syscall */ | |
164 | #elif defined(AFS_SUN511_ENV) | |
165 | int | |
166 | volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5) | |
167 | { | |
168 | int err, code; | |
169 | code = ioctl_sun_afs_syscall(28 /* AFSCALL_CALL */, a3, a4, a5, 0, 0, 0, | |
170 | &err); | |
171 | if (code) { | |
172 | err = code; | |
173 | } | |
174 | return err; | |
175 | } | |
176 | #elif !defined(AFS_SYSCALL) | |
177 | int | |
178 | volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5) | |
179 | { | |
180 | errno = ENOSYS; | |
181 | return -1; | |
182 | } | |
183 | #else | |
184 | int | |
185 | volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5) | |
186 | { | |
187 | afs_uint32 rcode; | |
188 | #ifndef AFS_LINUX20_ENV | |
189 | void (*old) (int); | |
190 | ||
191 | old = signal(SIGSYS, SIG_IGN); | |
192 | #endif | |
193 | rcode = | |
194 | syscall(AFS_SYSCALL /* AFS_SYSCALL */ , 28 /* AFSCALL_CALL */ , a3, | |
195 | a4, a5); | |
196 | #ifndef AFS_LINUX20_ENV | |
197 | signal(SIGSYS, old); | |
198 | #endif | |
199 | ||
200 | return rcode; | |
201 | } | |
202 | #endif | |
203 | ||
204 | ||
205 | /* check whether caller is authorized to manage RX statistics */ | |
206 | int | |
207 | vol_rxstat_userok(struct rx_call *call) | |
208 | { | |
209 | return afsconf_SuperUser(tdir, call, NULL); | |
210 | } | |
211 | ||
212 | /** | |
213 | * Return true if this name is a member of the local realm. | |
214 | */ | |
215 | static int | |
216 | vol_IsLocalRealmMatch(void *rock, char *name, char *inst, char *cell) | |
217 | { | |
218 | struct afsconf_dir *dir = (struct afsconf_dir *)rock; | |
219 | afs_int32 islocal = 0; /* default to no */ | |
220 | int code; | |
221 | ||
222 | code = afsconf_IsLocalRealmMatch(dir, &islocal, name, inst, cell); | |
223 | if (code) { | |
224 | ViceLog(0, | |
225 | ("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n", | |
226 | code, name, inst, cell)); | |
227 | } | |
228 | return islocal; | |
229 | } | |
230 | ||
231 | enum optionsList { | |
232 | OPT_log, | |
233 | OPT_rxbind, | |
234 | OPT_dotted, | |
235 | OPT_debug, | |
236 | OPT_threads, | |
237 | OPT_auditlog, | |
238 | OPT_audit_interface, | |
239 | OPT_nojumbo, | |
240 | OPT_jumbo, | |
241 | OPT_rxmaxmtu, | |
242 | OPT_sleep, | |
243 | OPT_udpsize, | |
244 | OPT_peer, | |
245 | OPT_process, | |
246 | OPT_preserve_vol_stats, | |
247 | OPT_clear_vol_stats, | |
248 | OPT_sync, | |
249 | #ifdef HAVE_SYSLOG | |
250 | OPT_syslog, | |
251 | #endif | |
252 | OPT_logfile, | |
253 | OPT_config, | |
254 | OPT_restricted_query, | |
255 | OPT_transarc_logs, | |
256 | OPT_s2s_crypt | |
257 | }; | |
258 | ||
259 | static int | |
260 | ParseArgs(int argc, char **argv) { | |
261 | int code; | |
262 | int optval; | |
263 | char *optstring = NULL; | |
264 | struct cmd_syndesc *opts; | |
265 | char *sleepSpec = NULL; | |
266 | char *sync_behavior = NULL; | |
267 | char *restricted_query_parameter = NULL; | |
268 | char *s2s_crypt_behavior = NULL; | |
269 | ||
270 | opts = cmd_CreateSyntax(NULL, NULL, NULL, 0, NULL); | |
271 | cmd_AddParmAtOffset(opts, OPT_log, "-log", CMD_FLAG, CMD_OPTIONAL, | |
272 | "log vos users"); | |
273 | cmd_AddParmAtOffset(opts, OPT_rxbind, "-rxbind", CMD_FLAG, CMD_OPTIONAL, | |
274 | "bind only to the primary interface"); | |
275 | cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals", CMD_FLAG, CMD_OPTIONAL, | |
276 | "permit Kerberos 5 principals with dots"); | |
277 | cmd_AddParmAtOffset(opts, OPT_debug, "-d", CMD_SINGLE, CMD_OPTIONAL, | |
278 | "debug level"); | |
279 | cmd_AddParmAtOffset(opts, OPT_threads, "-p", CMD_SINGLE, CMD_OPTIONAL, | |
280 | "number of threads"); | |
281 | cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE, | |
282 | CMD_OPTIONAL, "location of audit log"); | |
283 | cmd_AddParmAtOffset(opts, OPT_audit_interface, "-audit-interface", | |
284 | CMD_SINGLE, CMD_OPTIONAL, "interface to use for audit logging"); | |
285 | cmd_AddParmAtOffset(opts, OPT_nojumbo, "-nojumbo", CMD_FLAG, CMD_OPTIONAL, | |
286 | "disable jumbograms"); | |
287 | cmd_AddParmAtOffset(opts, OPT_jumbo, "-jumbo", CMD_FLAG, CMD_OPTIONAL, | |
288 | "enable jumbograms"); | |
289 | cmd_AddParmAtOffset(opts, OPT_rxmaxmtu, "-rxmaxmtu", CMD_SINGLE, | |
290 | CMD_OPTIONAL, "maximum MTU for RX"); | |
291 | cmd_AddParmAtOffset(opts, OPT_udpsize, "-udpsize", CMD_SINGLE, | |
292 | CMD_OPTIONAL, "size of socket buffer in bytes"); | |
293 | cmd_AddParmAtOffset(opts, OPT_sleep, "-sleep", CMD_SINGLE, | |
294 | CMD_OPTIONAL, "make background daemon sleep (LWP only)"); | |
295 | cmd_AddParmAtOffset(opts, OPT_peer, "-enable_peer_stats", CMD_FLAG, | |
296 | CMD_OPTIONAL, "enable RX transport statistics"); | |
297 | cmd_AddParmAtOffset(opts, OPT_process, "-enable_process_stats", CMD_FLAG, | |
298 | CMD_OPTIONAL, "enable RX RPC statistics"); | |
299 | /* -preserve-vol-stats on by default now. */ | |
300 | cmd_AddParmAtOffset(opts, OPT_preserve_vol_stats, "-preserve-vol-stats", CMD_FLAG, | |
301 | CMD_OPTIONAL|CMD_HIDDEN, | |
302 | "preserve volume statistics when restoring/recloning"); | |
303 | cmd_AddParmAtOffset(opts, OPT_clear_vol_stats, "-clear-vol-stats", CMD_FLAG, | |
304 | CMD_OPTIONAL, "clear volume statistics when restoring/recloning"); | |
305 | #ifdef HAVE_SYSLOG | |
306 | cmd_AddParmAtOffset(opts, OPT_syslog, "-syslog", CMD_SINGLE_OR_FLAG, | |
307 | CMD_OPTIONAL, "log to syslog"); | |
308 | #endif | |
309 | cmd_AddParmAtOffset(opts, OPT_transarc_logs, "-transarc-logs", CMD_FLAG, | |
310 | CMD_OPTIONAL, "enable Transarc style logging"); | |
311 | cmd_AddParmAtOffset(opts, OPT_sync, "-sync", | |
312 | CMD_SINGLE, CMD_OPTIONAL, "always | onclose | never"); | |
313 | cmd_AddParmAtOffset(opts, OPT_logfile, "-logfile", CMD_SINGLE, | |
314 | CMD_OPTIONAL, "location of log file"); | |
315 | cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE, | |
316 | CMD_OPTIONAL, "configuration location"); | |
317 | cmd_AddParmAtOffset(opts, OPT_restricted_query, "-restricted_query", | |
318 | CMD_SINGLE, CMD_OPTIONAL, "anyuser | admin"); | |
319 | cmd_AddParmAtOffset(opts, OPT_s2s_crypt, "-s2scrypt", | |
320 | CMD_SINGLE, CMD_OPTIONAL, "always | inherit | never"); | |
321 | ||
322 | code = cmd_Parse(argc, argv, &opts); | |
323 | if (code == CMD_HELP) { | |
324 | exit(0); | |
325 | } | |
326 | if (code) | |
327 | return 1; | |
328 | ||
329 | cmd_OptionAsFlag(opts, OPT_log, &DoLogging); | |
330 | cmd_OptionAsFlag(opts, OPT_rxbind, &rxBind); | |
331 | cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck); | |
332 | if (cmd_OptionPresent(opts, OPT_clear_vol_stats)) | |
333 | DoPreserveVolumeStats = 0; | |
334 | if (cmd_OptionPresent(opts, OPT_peer)) | |
335 | rx_enablePeerRPCStats(); | |
336 | if (cmd_OptionPresent(opts, OPT_process)) | |
337 | rx_enableProcessRPCStats(); | |
338 | if (cmd_OptionPresent(opts, OPT_nojumbo)) | |
339 | rxJumbograms = 0; | |
340 | if (cmd_OptionPresent(opts, OPT_jumbo)) | |
341 | rxJumbograms = 1; | |
342 | ||
343 | #ifdef HAVE_SYSLOG | |
344 | if (cmd_OptionPresent(opts, OPT_syslog)) { | |
345 | if (cmd_OptionPresent(opts, OPT_logfile)) { | |
346 | fprintf(stderr, "Invalid options: -syslog and -logfile are exclusive.\n"); | |
347 | return -1; | |
348 | } | |
349 | if (cmd_OptionPresent(opts, OPT_transarc_logs)) { | |
350 | fprintf(stderr, "Invalid options: -syslog and -transarc-logs are exclusive.\n"); | |
351 | return -1; | |
352 | } | |
353 | logopts.lopt_dest = logDest_syslog; | |
354 | logopts.lopt_facility = LOG_DAEMON; | |
355 | logopts.lopt_tag = "volserver"; | |
356 | cmd_OptionAsInt(opts, OPT_syslog, &logopts.lopt_facility); | |
357 | } else | |
358 | #endif | |
359 | { | |
360 | logopts.lopt_dest = logDest_file; | |
361 | if (cmd_OptionPresent(opts, OPT_transarc_logs)) { | |
362 | logopts.lopt_rotateOnOpen = 1; | |
363 | logopts.lopt_rotateStyle = logRotate_old; | |
364 | } | |
365 | if (cmd_OptionPresent(opts, OPT_logfile)) | |
366 | cmd_OptionAsString(opts, OPT_logfile, (char**)&logopts.lopt_filename); | |
367 | else | |
368 | logopts.lopt_filename = AFSDIR_SERVER_VOLSERLOG_FILEPATH; | |
369 | } | |
370 | cmd_OptionAsInt(opts, OPT_debug, &logopts.lopt_logLevel); | |
371 | ||
372 | cmd_OptionAsInt(opts, OPT_rxmaxmtu, &rxMaxMTU); | |
373 | if (cmd_OptionAsInt(opts, OPT_udpsize, &optval) == 0) { | |
374 | if (optval < rx_GetMinUdpBufSize()) { | |
375 | printf("Warning:udpsize %d is less than minimum %d; ignoring\n", | |
376 | optval, rx_GetMinUdpBufSize()); | |
377 | } else | |
378 | udpBufSize = optval; | |
379 | } | |
380 | cmd_OptionAsString(opts, OPT_auditlog, &auditFileName); | |
381 | ||
382 | if (cmd_OptionAsString(opts, OPT_audit_interface, &optstring) == 0) { | |
383 | if (osi_audit_interface(optstring)) { | |
384 | printf("Invalid audit interface '%s'\n", optstring); | |
385 | return -1; | |
386 | } | |
387 | free(optstring); | |
388 | optstring = NULL; | |
389 | } | |
390 | if (cmd_OptionAsInt(opts, OPT_threads, &lwps) == 0) { | |
391 | if (lwps > MAXLWP) { | |
392 | printf("Warning: '-p %d' is too big; using %d instead\n", lwps, MAXLWP); | |
393 | lwps = MAXLWP; | |
394 | } | |
395 | } | |
396 | if (cmd_OptionAsString(opts, OPT_sleep, &sleepSpec) == 0) { | |
397 | printf("Warning: -sleep option ignored; this option is obsolete\n"); | |
398 | } | |
399 | if (cmd_OptionAsString(opts, OPT_sync, &sync_behavior) == 0) { | |
400 | if (ih_SetSyncBehavior(sync_behavior)) { | |
401 | printf("Invalid -sync value %s\n", sync_behavior); | |
402 | return -1; | |
403 | } | |
404 | } | |
405 | cmd_OptionAsString(opts, OPT_config, &configDir); | |
406 | if (cmd_OptionAsString(opts, OPT_restricted_query, | |
407 | &restricted_query_parameter) == 0) { | |
408 | if (strcmp(restricted_query_parameter, "anyuser") == 0) | |
409 | restrictedQueryLevel = RESTRICTED_QUERY_ANYUSER; | |
410 | else if (strcmp(restricted_query_parameter, "admin") == 0) | |
411 | restrictedQueryLevel = RESTRICTED_QUERY_ADMIN; | |
412 | else { | |
413 | printf("invalid argument for -restricted_query: %s\n", | |
414 | restricted_query_parameter); | |
415 | return -1; | |
416 | } | |
417 | free(restricted_query_parameter); | |
418 | } | |
419 | if (cmd_OptionAsString(opts, OPT_s2s_crypt, &s2s_crypt_behavior) == 0) { | |
420 | if (strcmp(s2s_crypt_behavior, "always") == 0) | |
421 | doCrypt = VS2SC_ALWAYS; | |
422 | else if (strcmp(s2s_crypt_behavior, "never") == 0) | |
423 | doCrypt = VS2SC_NEVER; | |
424 | else if (strcmp(s2s_crypt_behavior, "inherit") == 0) | |
425 | doCrypt = VS2SC_INHERIT; | |
426 | else { | |
427 | printf("invalid argument for -s2scrypt: %s\n", s2s_crypt_behavior); | |
428 | return -1; | |
429 | } | |
430 | free(s2s_crypt_behavior); | |
431 | } | |
432 | ||
433 | return 0; | |
434 | } | |
435 | ||
436 | #include "AFS_component_version_number.c" | |
437 | int | |
438 | main(int argc, char **argv) | |
439 | { | |
440 | afs_int32 code; | |
441 | struct rx_securityClass **securityClasses; | |
442 | afs_int32 numClasses; | |
443 | struct rx_service *service; | |
444 | int rxpackets = 100; | |
445 | afs_uint32 host = ntohl(INADDR_ANY); | |
446 | VolumePackageOptions opts; | |
447 | ||
448 | #ifdef AFS_AIX32_ENV | |
449 | /* | |
450 | * The following signal action for AIX is necessary so that in case of a | |
451 | * crash (i.e. core is generated) we can include the user's data section | |
452 | * in the core dump. Unfortunately, by default, only a partial core is | |
453 | * generated which, in many cases, isn't too useful. | |
454 | */ | |
455 | struct sigaction nsa; | |
456 | ||
457 | sigemptyset(&nsa.sa_mask); | |
458 | nsa.sa_handler = SIG_DFL; | |
459 | nsa.sa_flags = SA_FULLDUMP; | |
460 | sigaction(SIGABRT, &nsa, NULL); | |
461 | sigaction(SIGSEGV, &nsa, NULL); | |
462 | #endif | |
463 | osi_audit_init(); | |
464 | osi_audit(VS_StartEvent, 0, AUD_END); | |
465 | ||
466 | /* Initialize dirpaths */ | |
467 | if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { | |
468 | #ifdef AFS_NT40_ENV | |
469 | ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); | |
470 | #endif | |
471 | fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", | |
472 | argv[0]); | |
473 | exit(2); | |
474 | } | |
475 | ||
476 | configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH); | |
477 | ||
478 | if (ParseArgs(argc, argv)) { | |
479 | exit(1); | |
480 | } | |
481 | ||
482 | if (auditFileName) { | |
483 | osi_audit_file(auditFileName); | |
484 | osi_audit(VS_StartEvent, 0, AUD_END); | |
485 | } | |
486 | #ifdef AFS_SGI_VNODE_GLUE | |
487 | if (afs_init_kernel_config(-1) < 0) { | |
488 | printf | |
489 | ("Can't determine NUMA configuration, not starting volserver.\n"); | |
490 | exit(1); | |
491 | } | |
492 | #endif | |
493 | InitErrTabs(); | |
494 | ||
495 | #ifdef AFS_PTHREAD_ENV | |
496 | SetLogThreadNumProgram( rx_GetThreadNum ); | |
497 | #endif | |
498 | ||
499 | #ifdef AFS_NT40_ENV | |
500 | if (afs_winsockInit() < 0) { | |
501 | ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); | |
502 | printf("Volume server unable to start winsock, exiting.\n"); | |
503 | exit(1); | |
504 | } | |
505 | #endif | |
506 | ||
507 | OpenLog(&logopts); | |
508 | ||
509 | VOptDefaults(volumeServer, &opts); | |
510 | if (VInitVolumePackage2(volumeServer, &opts)) { | |
511 | Log("Shutting down: errors encountered initializing volume package\n"); | |
512 | exit(1); | |
513 | } | |
514 | /* For nuke() */ | |
515 | Lock_Init(&localLock); | |
516 | DInit(40); | |
517 | #ifndef AFS_PTHREAD_ENV | |
518 | vol_PollProc = IOMGR_Poll; /* tell vol pkg to poll io system periodically */ | |
519 | #endif | |
520 | #if !defined( AFS_NT40_ENV ) && !defined(AFS_DARWIN160_ENV) | |
521 | rxi_syscallp = volser_syscall; | |
522 | #endif | |
523 | rx_nPackets = rxpackets; /* set the max number of packets */ | |
524 | if (udpBufSize) | |
525 | rx_SetUdpBufSize(udpBufSize); /* set the UDP buffer size for receive */ | |
526 | if (rxBind) { | |
527 | afs_int32 ccode; | |
528 | if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || | |
529 | AFSDIR_SERVER_NETINFO_FILEPATH) { | |
530 | char reason[1024]; | |
531 | ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, | |
532 | ADDRSPERSITE, reason, | |
533 | AFSDIR_SERVER_NETINFO_FILEPATH, | |
534 | AFSDIR_SERVER_NETRESTRICT_FILEPATH); | |
535 | } else | |
536 | { | |
537 | ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); | |
538 | } | |
539 | if (ccode == 1) | |
540 | host = SHostAddrs[0]; | |
541 | } | |
542 | ||
543 | code = rx_InitHost(host, (int)htons(AFSCONF_VOLUMEPORT)); | |
544 | if (code) { | |
545 | fprintf(stderr, "rx init failed on socket AFSCONF_VOLUMEPORT %u\n", | |
546 | AFSCONF_VOLUMEPORT); | |
547 | VS_EXIT(1); | |
548 | } | |
549 | if (!rxJumbograms) { | |
550 | /* Don't allow 3.4 vos clients to send jumbograms and we don't send. */ | |
551 | rx_SetNoJumbo(); | |
552 | } | |
553 | if (rxMaxMTU != -1) { | |
554 | if (rx_SetMaxMTU(rxMaxMTU) != 0) { | |
555 | fprintf(stderr, "rxMaxMTU %d is invalid\n", rxMaxMTU); | |
556 | VS_EXIT(1); | |
557 | } | |
558 | } | |
559 | rx_GetIFInfo(); | |
560 | rx_SetRxDeadTime(420); | |
561 | memset(busyFlags, 0, sizeof(busyFlags)); | |
562 | ||
563 | #ifdef AFS_PTHREAD_ENV | |
564 | opr_softsig_Init(); | |
565 | SetupLogSoftSignals(); | |
566 | #else | |
567 | SetupLogSignals(); | |
568 | #endif | |
569 | ||
570 | { | |
571 | #ifdef AFS_PTHREAD_ENV | |
572 | pthread_t tid; | |
573 | pthread_attr_t tattr; | |
574 | opr_Verify(pthread_attr_init(&tattr) == 0); | |
575 | opr_Verify(pthread_attr_setdetachstate(&tattr, | |
576 | PTHREAD_CREATE_DETACHED) == 0); | |
577 | opr_Verify(pthread_create(&tid, &tattr, BKGLoop, NULL) == 0); | |
578 | #else | |
579 | PROCESS pid; | |
580 | LWP_CreateProcess(BKGLoop, 16*1024, 3, 0, "vol bkg daemon", &pid); | |
581 | #endif | |
582 | } | |
583 | ||
584 | /* Create a single security object, in this case the null security object, for unauthenticated connections, which will be used to control security on connections made to this server */ | |
585 | ||
586 | tdir = afsconf_Open(configDir); | |
587 | if (!tdir) { | |
588 | Abort("volser: could not open conf files in %s\n", | |
589 | configDir); | |
590 | VS_EXIT(1); | |
591 | } | |
592 | ||
593 | /* initialize audit user check */ | |
594 | osi_audit_set_user_check(tdir, vol_IsLocalRealmMatch); | |
595 | ||
596 | afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses); | |
597 | if (securityClasses[0] == NULL) | |
598 | Abort("rxnull_NewServerSecurityObject"); | |
599 | service = | |
600 | rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityClasses, | |
601 | numClasses, AFSVolExecuteRequest); | |
602 | if (service == (struct rx_service *)0) | |
603 | Abort("rx_NewService"); | |
604 | rx_SetBeforeProc(service, MyBeforeProc); | |
605 | rx_SetAfterProc(service, MyAfterProc); | |
606 | rx_SetIdleDeadTime(service, 0); /* never timeout */ | |
607 | if (lwps < 4) | |
608 | lwps = 4; | |
609 | rx_SetMaxProcs(service, lwps); | |
610 | #if defined(AFS_XBSD_ENV) | |
611 | rx_SetStackSize(service, (128 * 1024)); | |
612 | #elif defined(AFS_SGI_ENV) | |
613 | rx_SetStackSize(service, (48 * 1024)); | |
614 | #else | |
615 | rx_SetStackSize(service, (32 * 1024)); | |
616 | #endif | |
617 | ||
618 | if (rxkadDisableDotCheck) { | |
619 | rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS, | |
620 | (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); | |
621 | } | |
622 | ||
623 | service = | |
624 | rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, | |
625 | numClasses, RXSTATS_ExecuteRequest); | |
626 | if (service == (struct rx_service *)0) | |
627 | Abort("rx_NewService"); | |
628 | rx_SetMinProcs(service, 2); | |
629 | rx_SetMaxProcs(service, 4); | |
630 | ||
631 | LogCommandLine(argc, argv, "Volserver", VolserVersion, "Starting AFS", | |
632 | Log); | |
633 | if (afsconf_GetLatestKey(tdir, NULL, NULL) == 0) { | |
634 | LogDesWarning(); | |
635 | } | |
636 | ||
637 | /* allow super users to manage RX statistics */ | |
638 | rx_SetRxStatUserOk(vol_rxstat_userok); | |
639 | ||
640 | rx_StartServer(1); /* Donate this process to the server process pool */ | |
641 | ||
642 | osi_audit(VS_FinishEvent, (-1), AUD_END); | |
643 | Abort("StartServer returned?"); | |
644 | return 0; /* not reached */ | |
645 | } |