Bug Summary

File:volser/volmain.c
Location:line 525, column 5
Description:Access to field 'minProcs' results in a dereference of a null pointer (loaded from variable 'service')

Annotated Source Code

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
15#ifdef AFS_NT40_ENV
16#include <windows.h>
17#include <WINNT/afsevent.h>
18#endif
19
20#include <rx/xdr.h>
21#include <afs/afsint.h>
22#include <afs/afs_assert.h>
23#include <afs/prs_fs.h>
24#include <afs/nfs.h>
25#include <lwp.h>
26#include <lock.h>
27#include <afs/afssyscalls.h>
28#include <afs/ihandle.h>
29#ifdef AFS_NT40_ENV
30#include <afs/ntops.h>
31#endif
32#include <afs/vnode.h>
33#include <afs/volume.h>
34#include <afs/partition.h>
35#include <rx/rx.h>
36#include <rx/rxstat.h>
37#include <rx/rx_globals.h>
38#include <afs/auth.h>
39#include <afs/cellconfig.h>
40#include <afs/keys.h>
41#include <afs/dir.h>
42#include <ubik.h>
43#include <afs/audit.h>
44#include <afs/afsutil.h>
45#include <lwp.h>
46
47#include "volser.h"
48#include "volint.h"
49#include "volser_internal.h"
50
51/*@printflike@*/ extern void Log(const char *format, ...);
52/*@printflike@*/ extern void Abort(const char *format, ...);
53
54#define VolserVersion"2.0" "2.0"
55#define N_SECURITY_OBJECTS3 3
56
57extern struct Lock localLock;
58char *GlobalNameHack = NULL((void *)0);
59int hackIsIn = 0;
60afs_int32 GlobalVolCloneId, GlobalVolParentId;
61int GlobalVolType;
62int VolumeChanged; /* XXXX */
63static char busyFlags[MAXHELPERS10];
64struct volser_trans *QI_GlobalWriteTrans = 0;
65struct afsconf_dir *tdir;
66static afs_int32 runningCalls = 0;
67int DoLogging = 0;
68int debuglevel = 0;
69#define MAXLWP128 128
70int lwps = 9;
71int udpBufSize = 0; /* UDP buffer size for receive */
72
73int rxBind = 0;
74int rxkadDisableDotCheck = 0;
75
76#define ADDRSPERSITE16 16 /* Same global is in rx/rx_user.c */
77afs_uint32 SHostAddrs[ADDRSPERSITE16];
78
79#define VS_EXIT(code){ osi_audit("AFS_VS_Exit", code, 0); exit(code); } { \
80 osi_audit(VS_ExitEvent"AFS_VS_Exit", code, AUD_END0); \
81 exit(code); \
82 }
83
84static void
85MyBeforeProc(struct rx_call *acall)
86{
87 VTRANS_LOCK;
88 runningCalls++;
89 VTRANS_UNLOCK;
90 return;
91}
92
93static void
94MyAfterProc(struct rx_call *acall, afs_int32 code)
95{
96 VTRANS_LOCK;
97 runningCalls--;
98 VTRANS_UNLOCK;
99 return;
100}
101
102/* Called every GCWAKEUP seconds to try to unlock all our partitions,
103 * if we're idle and there are no active transactions
104 */
105static void
106TryUnlock(void)
107{
108 /* if there are no running calls, and there are no active transactions, then
109 * it should be safe to release any partition locks we've accumulated */
110 VTRANS_LOCK;
111 if (runningCalls == 0 && TransList() == (struct volser_trans *)0) {
112 VTRANS_UNLOCK;
113 VPFullUnlock(); /* in volprocs.c */
114 } else
115 VTRANS_UNLOCK;
116}
117
118/* background daemon for timing out transactions */
119static void*
120BKGLoop(void *unused)
121{
122 struct timeval tv;
123 int loop = 0;
124
125 afs_pthread_setname_self("vol bkg")(void)0;
126 while (1) {
127 tv.tv_sec = GCWAKEUP30;
128 tv.tv_usec = 0;
129#ifdef AFS_PTHREAD_ENV
130#ifdef AFS_NT40_ENV
131 Sleep(GCWAKEUP30 * 1000);
132#else
133 select(0, 0, 0, 0, &tv);
134#endif
135#else
136 (void)IOMGR_Select(0, 0, 0, 0, &tv);
137#endif
138 GCTrans();
139 TryUnlock();
140 loop++;
141 if (loop == 10) { /* reopen log every 5 minutes */
142 loop = 0;
143 ReOpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATHgetDirPath(AFSDIR_SERVER_VOLSERLOG_FILEPATH_ID));
144 }
145 }
146
147 return NULL((void *)0);
148}
149
150/* Background daemon for sleeping so the volserver does not become I/O bound */
151afs_int32 TTsleep, TTrun;
152#ifndef AFS_PTHREAD_ENV
153static void *
154BKGSleep(void *unused)
155{
156 struct volser_trans *tt;
157
158 if (TTsleep) {
159 while (1) {
160#ifdef AFS_PTHREAD_ENV
161 sleep(TTrun);
162#else /* AFS_PTHREAD_ENV */
163 IOMGR_Sleep(TTrun);
164#endif
165 VTRANS_LOCK;
166 for (tt = TransList(); tt; tt = tt->next) {
167 VTRANS_OBJ_LOCK(tt);
168 if ((strcmp(tt->lastProcName, "DeleteVolume") == 0)
169 || (strcmp(tt->lastProcName, "Clone") == 0)
170 || (strcmp(tt->lastProcName, "ReClone") == 0)
171 || (strcmp(tt->lastProcName, "Forward") == 0)
172 || (strcmp(tt->lastProcName, "Restore") == 0)
173 || (strcmp(tt->lastProcName, "ForwardMulti") == 0)) {
174 VTRANS_OBJ_UNLOCK(tt);
175 break;
176 }
177 VTRANS_OBJ_UNLOCK(tt);
178 }
179 if (tt) {
180 VTRANS_UNLOCK;
181 sleep(TTsleep);
182 } else
183 VTRANS_UNLOCK;
184 }
185 }
186 return NULL((void *)0);
187}
188#endif
189
190#ifdef AFS_NT40_ENV
191/* no volser_syscall */
192#elif defined(AFS_SUN511_ENV)
193int
194volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
195{
196 int err, code;
197 code = ioctl_sun_afs_syscall(28 /* AFSCALL_CALL */, a3, a4, a5, 0, 0, 0,
198 &err);
199 if (code) {
200 err = code;
201 }
202 return err;
203}
204#else
205int
206volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
207{
208 afs_uint32 rcode;
209#ifndef AFS_LINUX20_ENV
210 void (*old) (int);
211
212 old = signal(SIGSYS12, SIG_IGN((__sighandler_t *)1));
213#endif
214 rcode =
215 syscall(AFS_SYSCALL339 /* AFS_SYSCALL */ , 28 /* AFSCALL_CALL */ , a3,
216 a4, a5);
217#ifndef AFS_LINUX20_ENV
218 signal(SIGSYS12, old);
219#endif
220
221 return rcode;
222}
223#endif
224
225
226/* check whether caller is authorized to manage RX statistics */
227int
228vol_rxstat_userok(struct rx_call *call)
229{
230 return afsconf_SuperUser(tdir, call, NULL((void *)0));
231}
232
233#include "AFS_component_version_number.c"
234int
235main(int argc, char **argv)
236{
237 afs_int32 code;
238 struct rx_securityClass **securityClasses;
239 afs_int32 numClasses;
240 struct rx_service *service;
241 struct ktc_encryptionKey tkey;
242 int rxpackets = 100;
243 int rxJumbograms = 0; /* default is to send and receive jumbograms. */
244 int rxMaxMTU = -1;
245 int bufSize = 0; /* temp variable to read in udp socket buf size */
246 afs_uint32 host = ntohl(INADDR_ANY)(__builtin_constant_p((u_int32_t)0x00000000) ? ((((__uint32_t
)((u_int32_t)0x00000000)) >> 24) | ((((__uint32_t)((u_int32_t
)0x00000000)) & (0xff << 16)) >> 8) | ((((__uint32_t
)((u_int32_t)0x00000000)) & (0xff << 8)) << 8
) | (((__uint32_t)((u_int32_t)0x00000000)) << 24)) : __bswap32_var
((u_int32_t)0x00000000))
;
247 char *auditFileName = NULL((void *)0);
248 VolumePackageOptions opts;
249
250#ifdef AFS_AIX32_ENV
251 /*
252 * The following signal action for AIX is necessary so that in case of a
253 * crash (i.e. core is generated) we can include the user's data section
254 * in the core dump. Unfortunately, by default, only a partial core is
255 * generated which, in many cases, isn't too useful.
256 */
257 struct sigaction nsa;
258
259 sigemptyset(&nsa.sa_mask);
260 nsa.sa_handler__sigaction_u.__sa_handler = SIG_DFL((__sighandler_t *)0);
261 nsa.sa_flags = SA_FULLDUMP;
262 sigaction(SIGABRT6, &nsa, NULL((void *)0));
263 sigaction(SIGSEGV11, &nsa, NULL((void *)0));
264#endif
265 osi_audit_init();
266 osi_audit(VS_StartEvent"AFS_VS_Start", 0, AUD_END0);
267
268 /* Initialize dirpaths */
269 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK0x2)) {
1
Taking false branch
270#ifdef AFS_NT40_ENV
271 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
272#endif
273 fprintf(stderr__stderrp, "%s: Unable to obtain AFS server directory.\n",
274 argv[0]);
275 exit(2);
276 }
277
278 TTsleep = TTrun = 0;
279
280 /* parse cmd line */
281 for (code = 1; code < argc; code++) {
2
Loop condition is false. Execution continues on line 388
282 if (strcmp(argv[code], "-log") == 0) {
283 /* set extra logging flag */
284 DoLogging = 1;
285 } else if (strcmp(argv[code], "-help") == 0) {
286 goto usage;
287 } else if (strcmp(argv[code], "-rxbind") == 0) {
288 rxBind = 1;
289 } else if (strcmp(argv[code], "-allow-dotted-principals") == 0) {
290 rxkadDisableDotCheck = 1;
291 } else if (strcmp(argv[code], "-d") == 0) {
292 if ((code + 1) >= argc) {
293 fprintf(stderr__stderrp, "missing argument for -d\n");
294 return -1;
295 }
296 debuglevel = atoi(argv[++code]);
297 LogLevel = debuglevel;
298 } else if (strcmp(argv[code], "-p") == 0) {
299 lwps = atoi(argv[++code]);
300 if (lwps > MAXLWP128) {
301 printf("Warning: '-p %d' is too big; using %d instead\n",
302 lwps, MAXLWP128);
303 lwps = MAXLWP128;
304 }
305 } else if (strcmp(argv[code], "-auditlog") == 0) {
306 auditFileName = argv[++code];
307
308 } else if (strcmp(argv[code], "-audit-interface") == 0) {
309 char *interface = argv[++code];
310
311 if (osi_audit_interface(interface)) {
312 printf("Invalid audit interface '%s'\n", interface);
313 return -1;
314 }
315 } else if (strcmp(argv[code], "-nojumbo") == 0) {
316 rxJumbograms = 0;
317 } else if (strcmp(argv[code], "-jumbo") == 0) {
318 rxJumbograms = 1;
319 } else if (!strcmp(argv[code], "-rxmaxmtu")) {
320 if ((code + 1) >= argc) {
321 fprintf(stderr__stderrp, "missing argument for -rxmaxmtu\n");
322 exit(1);
323 }
324 rxMaxMTU = atoi(argv[++code]);
325 if ((rxMaxMTU < RX_MIN_PACKET_SIZE(576 - RX_IPUDP_SIZE)) ||
326 (rxMaxMTU > RX_MAX_PACKET_DATA_SIZE(16384 - sizeof (struct rx_header)))) {
327 printf("rxMaxMTU %d invalid; must be between %d-%" AFS_SIZET_FMT"zu" "\n",
328 rxMaxMTU, RX_MIN_PACKET_SIZE(576 - RX_IPUDP_SIZE),
329 RX_MAX_PACKET_DATA_SIZE(16384 - sizeof (struct rx_header)));
330 exit(1);
331 }
332 } else if (strcmp(argv[code], "-sleep") == 0) {
333 sscanf(argv[++code], "%d/%d", &TTsleep, &TTrun);
334 if ((TTsleep < 0) || (TTrun <= 0)) {
335 printf("Warning: '-sleep %d/%d' is incorrect; ignoring\n",
336 TTsleep, TTrun);
337 TTsleep = TTrun = 0;
338 }
339 } else if (strcmp(argv[code], "-udpsize") == 0) {
340 if ((code + 1) >= argc) {
341 printf("You have to specify -udpsize <integer value>\n");
342 exit(1);
343 }
344 sscanf(argv[++code], "%d", &bufSize);
345 if (bufSize < rx_GetMinUdpBufSize()(64*1024))
346 printf
347 ("Warning:udpsize %d is less than minimum %d; ignoring\n",
348 bufSize, rx_GetMinUdpBufSize()(64*1024));
349 else
350 udpBufSize = bufSize;
351 } else if (strcmp(argv[code], "-enable_peer_stats") == 0) {
352 rx_enablePeerRPCStats();
353 } else if (strcmp(argv[code], "-enable_process_stats") == 0) {
354 rx_enableProcessRPCStats();
355 }
356#ifndef AFS_NT40_ENV
357 else if (strcmp(argv[code], "-syslog") == 0) {
358 /* set syslog logging flag */
359 serverLogSyslog = 1;
360 } else if (strncmp(argv[code], "-syslog=", 8) == 0) {
361 serverLogSyslog = 1;
362 serverLogSyslogFacility = atoi(argv[code] + 8);
363 }
364#endif
365 else {
366 printf("volserver: unrecognized flag '%s'\n", argv[code]);
367 usage:
368#ifndef AFS_NT40_ENV
369 printf("Usage: volserver [-log] [-p <number of processes>] "
370 "[-auditlog <log path>] [-d <debug level>] "
371 "[-nojumbo] [-jumbo] [-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
372 "[-udpsize <size of socket buffer in bytes>] "
373 "[-syslog[=FACILITY]] "
374 "[-enable_peer_stats] [-enable_process_stats] "
375 "[-help]\n");
376#else
377 printf("Usage: volserver [-log] [-p <number of processes>] "
378 "[-auditlog <log path>] [-d <debug level>] "
379 "[-nojumbo] [-jumbo] [-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
380 "[-udpsize <size of socket buffer in bytes>] "
381 "[-enable_peer_stats] [-enable_process_stats] "
382 "[-help]\n");
383#endif
384 VS_EXIT(1){ osi_audit("AFS_VS_Exit", 1, 0); exit(1); };
385 }
386 }
387
388 if (auditFileName) {
3
Taking false branch
389 osi_audit_file(auditFileName);
390 osi_audit(VS_StartEvent"AFS_VS_Start", 0, AUD_END0);
391 }
392#ifdef AFS_SGI_VNODE_GLUE
393 if (afs_init_kernel_config(-1) < 0) {
394 printf
395 ("Can't determine NUMA configuration, not starting volserver.\n");
396 exit(1);
397 }
398#endif
399 InitErrTabs();
400
401#ifdef AFS_PTHREAD_ENV
402 SetLogThreadNumProgram( rx_GetThreadNum );
403#endif
404
405#ifdef AFS_NT40_ENV
406 if (afs_winsockInit() < 0) {
407 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
408 printf("Volume server unable to start winsock, exiting.\n");
409 exit(1);
410 }
411#endif
412 /* Open VolserLog and map stdout, stderr into it; VInitVolumePackage2 can
413 log, so we need to do this here */
414 OpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATHgetDirPath(AFSDIR_SERVER_VOLSERLOG_FILEPATH_ID));
415
416 VOptDefaults(volumeServer, &opts);
417 if (VInitVolumePackage2(volumeServer, &opts)) {
4
Taking false branch
418 Log("Shutting down: errors encountered initializing volume package\n");
419 exit(1);
420 }
421 /* For nuke() */
422 Lock_Init(&localLock);
423 DInit(40);
424#ifndef AFS_PTHREAD_ENV
425 vol_PollProc = IOMGR_Poll; /* tell vol pkg to poll io system periodically */
426#endif
427#ifndef AFS_NT40_ENV
428 rxi_syscallp = volser_syscall;
429#endif
430 rx_nPackets = rxpackets; /* set the max number of packets */
431 if (udpBufSize)
5
Taking false branch
432 rx_SetUdpBufSize(udpBufSize)(((udpBufSize)>(64*1024)) ? (rx_UdpBufSize = (udpBufSize))
:0)
; /* set the UDP buffer size for receive */
433 if (rxBind) {
6
Taking false branch
434 afs_int32 ccode;
435 if (AFSDIR_SERVER_NETRESTRICT_FILEPATHgetDirPath(AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID) ||
436 AFSDIR_SERVER_NETINFO_FILEPATHgetDirPath(AFSDIR_SERVER_NETINFO_FILEPATH_ID)) {
437 char reason[1024];
438 ccode = parseNetFiles(SHostAddrs, NULL((void *)0), NULL((void *)0),
439 ADDRSPERSITE16, reason,
440 AFSDIR_SERVER_NETINFO_FILEPATHgetDirPath(AFSDIR_SERVER_NETINFO_FILEPATH_ID),
441 AFSDIR_SERVER_NETRESTRICT_FILEPATHgetDirPath(AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID));
442 } else
443 {
444 ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE16);
445 }
446 if (ccode == 1)
447 host = SHostAddrs[0];
448 }
449
450 code = rx_InitHost(host, (int)htons(AFSCONF_VOLUMEPORT)(__builtin_constant_p(7005) ? (__uint16_t)(((__uint16_t)(7005
)) << 8 | ((__uint16_t)(7005)) >> 8) : __bswap16_var
(7005))
);
451 if (code) {
7
Taking false branch
452 fprintf(stderr__stderrp, "rx init failed on socket AFSCONF_VOLUMEPORT %u\n",
453 AFSCONF_VOLUMEPORT7005);
454 VS_EXIT(1){ osi_audit("AFS_VS_Exit", 1, 0); exit(1); };
455 }
456 if (!rxJumbograms) {
8
Taking true branch
457 /* Don't allow 3.4 vos clients to send jumbograms and we don't send. */
458 rx_SetNoJumbo();
459 }
460 if (rxMaxMTU != -1) {
9
Taking false branch
461 rx_SetMaxMTU(rxMaxMTU);
462 }
463 rx_GetIFInfo();
464 rx_SetRxDeadTime(420)(rx_connDeadTime = (420));
465 memset(busyFlags, 0, sizeof(busyFlags));
466
467 SetupLogSignals();
468
469 {
470#ifdef AFS_PTHREAD_ENV
471 pthread_t tid;
472 pthread_attr_t tattr;
473 osi_Assert(pthread_attr_init(&tattr) == 0)(void)((pthread_attr_init(&tattr) == 0) || (osi_AssertFailU
("pthread_attr_init(&tattr) == 0", "volmain.c", 473), 0))
;
474 osi_Assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0)(void)((pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED
) == 0) || (osi_AssertFailU("pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0"
, "volmain.c", 474), 0))
;
475
476 osi_Assert(pthread_create(&tid, &tattr, BKGLoop, NULL) == 0)(void)((pthread_create(&tid, &tattr, BKGLoop, ((void *
)0)) == 0) || (osi_AssertFailU("pthread_create(&tid, &tattr, BKGLoop, NULL) == 0"
, "volmain.c", 476), 0))
;
477#else
478 PROCESS pid;
479 LWP_CreateProcess(BKGLoop, 16*1024, 3, 0, "vol bkg daemon", &pid);
480 LWP_CreateProcess(BKGSleep,16*1024, 3, 0, "vol slp daemon", &pid);
481#endif
482 }
483
484 /* 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 */
485
486 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATHgetDirPath(AFSDIR_SERVER_ETC_DIRPATH_ID));
487 if (!tdir) {
10
Taking false branch
488 Abort("volser: could not open conf files in %s\n",
489 AFSDIR_SERVER_ETC_DIRPATHgetDirPath(AFSDIR_SERVER_ETC_DIRPATH_ID));
490 VS_EXIT(1){ osi_audit("AFS_VS_Exit", 1, 0); exit(1); };
491 }
492 afsconf_GetKey(tdir, 999, &tkey);
493 afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses);
494 if (securityClasses[0] == NULL((void *)0))
11
Taking false branch
495 Abort("rxnull_NewServerSecurityObject");
496 service =
497 rx_NewServiceHost(host, 0, VOLSERVICE_ID4, "VOLSER", securityClasses,
498 numClasses, AFSVolExecuteRequest);
499 if (service == (struct rx_service *)0)
12
Taking false branch
500 Abort("rx_NewService");
501 rx_SetBeforeProc(service, MyBeforeProc)((service)->beforeProc = (MyBeforeProc));
502 rx_SetAfterProc(service, MyAfterProc)((service)->afterProc = (MyAfterProc));
503 rx_SetIdleDeadTime(service, 0)((service)->idleDeadTime = (0)); /* never timeout */
504 if (lwps < 4)
13
Taking false branch
505 lwps = 4;
506 rx_SetMaxProcs(service, lwps)((service)->maxProcs = (lwps));
507#if defined(AFS_XBSD_ENV1)
508 rx_SetStackSize(service, (128 * 1024))rx_stackSize = ((((128 * 1024)) > rx_stackSize)? (128 * 1024
): rx_stackSize)
;
509#elif defined(AFS_SGI_ENV)
510 rx_SetStackSize(service, (48 * 1024))rx_stackSize = ((((48 * 1024)) > rx_stackSize)? (48 * 1024
): rx_stackSize)
;
511#else
512 rx_SetStackSize(service, (32 * 1024))rx_stackSize = ((((32 * 1024)) > rx_stackSize)? (32 * 1024
): rx_stackSize)
;
513#endif
514
515 if (rxkadDisableDotCheck) {
14
Taking false branch
516 rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS,
517 (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK0x01);
518 }
519
520 service =
521 rx_NewService(0, RX_STATS_SERVICE_ID409, "rpcstats", securityClasses,
522 numClasses, RXSTATS_ExecuteRequest);
523 if (service == (struct rx_service *)0)
15
Taking true branch
524 Abort("rx_NewService");
525 rx_SetMinProcs(service, 2)((service)->minProcs = (2));
16
Within the expansion of the macro 'rx_SetMinProcs':
a
Access to field 'minProcs' results in a dereference of a null pointer (loaded from variable 'service')
526 rx_SetMaxProcs(service, 4)((service)->maxProcs = (4));
527
528 LogCommandLine(argc, argv, "Volserver", VolserVersion"2.0", "Starting AFS",
529 Log);
530 if (TTsleep) {
531 Log("Will sleep %d second%s every %d second%s\n", TTsleep,
532 (TTsleep > 1) ? "s" : "", TTrun + TTsleep,
533 (TTrun + TTsleep > 1) ? "s" : "");
534 }
535
536 /* allow super users to manage RX statistics */
537 rx_SetRxStatUserOk(vol_rxstat_userok);
538
539 rx_StartServer(1); /* Donate this process to the server process pool */
540
541 osi_audit(VS_FinishEvent"AFS_VS_Finish", (-1), AUD_END0);
542 Abort("StartServer returned?");
543 return 0; /* not reached */
544}