bccb764c26a7cca88b93e804679ad2759374d62f
[openafs.git] / src / afs / afs_call.c
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 RCSID
14     ("$Header$");
15
16 #include "afs/sysincludes.h"    /* Standard vendor system headers */
17 #include "afsincludes.h"        /* Afs-based standard headers */
18 #include "afs/afs_stats.h"
19 #include "rx/rx_globals.h"
20 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
21 #include "net/if.h"
22 #ifdef AFS_SGI62_ENV
23 #include "h/hashing.h"
24 #endif
25 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
26 #include "netinet/in_var.h"
27 #endif
28 #endif /* !defined(UKERNEL) */
29 #ifdef AFS_LINUX22_ENV
30 #include "h/smp_lock.h"
31 #endif
32 #ifdef AFS_SUN510_ENV
33 #include "h/ksynch.h"
34 #include "h/sunddi.h"
35 #endif
36
37 #if defined(AFS_SUN5_ENV) || defined(AFS_AIX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV)
38 #define AFS_MINBUFFERS  100
39 #else
40 #define AFS_MINBUFFERS  50
41 #endif
42
43 struct afsop_cell {
44     afs_int32 hosts[MAXCELLHOSTS];
45     char cellName[100];
46 };
47
48 char afs_zeros[AFS_ZEROS];
49 char afs_rootVolumeName[64] = "";
50 afs_uint32 rx_bindhost;
51
52 #ifdef AFS_SUN510_ENV
53 ddi_taskq_t *afs_taskq;
54 krwlock_t afsifinfo_lock;
55 #endif
56
57 afs_int32 afs_initState = 0;
58 afs_int32 afs_termState = 0;
59 afs_int32 afs_setTime = 0;
60 int afs_cold_shutdown = 0;
61 char afs_SynchronousCloses = '\0';
62 static int afs_CB_Running = 0;
63 static int AFS_Running = 0;
64 static int afs_CacheInit_Done = 0;
65 static int afs_Go_Done = 0;
66 extern struct interfaceAddr afs_cb_interface;
67 static int afs_RX_Running = 0;
68 static int afs_InitSetup_done = 0;
69 afs_int32 afs_numcachefiles = -1;
70 afs_int32 afs_numfilesperdir = -1;
71 char afs_cachebasedir[1024];
72
73 afs_int32 afs_rx_deadtime = AFS_RXDEADTIME;
74 afs_int32 afs_rx_harddead = AFS_HARDDEADTIME;
75 afs_int32 afs_rx_idledead = AFS_IDLEDEADTIME;
76
77 static int afscall_set_rxpck_received = 0;
78
79 #if defined(AFS_HPUX_ENV)
80 extern int afs_vfs_mount();
81 #endif /* defined(AFS_HPUX_ENV) */
82
83 /* This is code which needs to be called once when the first daemon enters
84  * the client. A non-zero return means an error and AFS should not start.
85  */
86 static int
87 afs_InitSetup(int preallocs)
88 {
89     int code;
90
91     if (afs_InitSetup_done)
92         return EAGAIN;
93
94 #ifdef AFS_SUN510_ENV
95     /* Initialize a RW lock for the ifinfo global array */
96     rw_init(&afsifinfo_lock, NULL, RW_DRIVER, NULL);
97
98     /* Create a taskq */
99     afs_taskq = ddi_taskq_create(NULL, "afs_taskq", 2, TASKQ_DEFAULTPRI, 0);
100
101     osi_StartNetIfPoller();
102 #endif
103
104 #ifndef AFS_NOSTATS
105     /*
106      * Set up all the AFS statistics variables.  This should be done
107      * exactly once, and it should be done here, the first resource-setting
108      * routine to be called by the CM/RX.
109      */
110     afs_InitStats();
111 #endif /* AFS_NOSTATS */
112
113     memset(afs_zeros, 0, AFS_ZEROS);
114
115     /* start RX */
116     if(!afscall_set_rxpck_received)
117     rx_extraPackets = AFS_NRXPACKETS;   /* smaller # of packets */
118     code = rx_InitHost(rx_bindhost, htons(7001));
119     if (code) {
120         printf("AFS: RX failed to initialize %d).\n", code);
121         return code;
122     }
123     rx_SetRxDeadTime(afs_rx_deadtime);
124     /* resource init creates the services */
125     afs_ResourceInit(preallocs);
126
127     afs_InitSetup_done = 1;
128     afs_osi_Wakeup(&afs_InitSetup_done);
129
130     return code;
131 }
132 #if defined(AFS_DARWIN80_ENV)
133 struct afsd_thread_info {
134     unsigned long parm;
135 };
136 static int
137 afsd_thread(int *rock)
138 {
139     struct afsd_thread_info *arg = (struct afsd_thread_info *)rock;
140     unsigned long parm = arg->parm;
141
142     switch (parm) {
143     case AFSOP_START_RXCALLBACK:
144         AFS_GLOCK();
145         wakeup(arg);
146         afs_CB_Running = 1;
147         while (afs_RX_Running != 2)
148             afs_osi_Sleep(&afs_RX_Running);
149         afs_RXCallBackServer();
150         AFS_GUNLOCK();
151         thread_terminate(current_thread());
152         break;
153     case AFSOP_START_AFS:
154         AFS_GLOCK();
155         wakeup(arg);
156         AFS_Running = 1;
157         while (afs_initState < AFSOP_START_AFS)
158             afs_osi_Sleep(&afs_initState);
159         afs_initState = AFSOP_START_BKG;
160         afs_osi_Wakeup(&afs_initState);
161         afs_Daemon();
162         AFS_GUNLOCK();
163         thread_terminate(current_thread());
164         break;
165     case AFSOP_START_BKG:
166         AFS_GLOCK();
167         wakeup(arg);
168         while (afs_initState < AFSOP_START_BKG)
169             afs_osi_Sleep(&afs_initState);
170         if (afs_initState < AFSOP_GO) {
171             afs_initState = AFSOP_GO;
172             afs_osi_Wakeup(&afs_initState);
173         }
174         afs_BackgroundDaemon();
175         AFS_GUNLOCK();
176         thread_terminate(current_thread());
177         break;
178     case AFSOP_START_TRUNCDAEMON:
179         AFS_GLOCK();
180         wakeup(arg);
181         while (afs_initState < AFSOP_GO)
182             afs_osi_Sleep(&afs_initState);
183         afs_CacheTruncateDaemon();
184         AFS_GUNLOCK();
185         thread_terminate(current_thread());
186         break;
187     case AFSOP_START_CS:
188         AFS_GLOCK();
189         wakeup(arg);
190         afs_CheckServerDaemon();
191         AFS_GUNLOCK();
192         thread_terminate(current_thread());
193         break;
194     case AFSOP_RXEVENT_DAEMON:
195         AFS_GLOCK();
196         wakeup(arg);
197         while (afs_initState < AFSOP_START_BKG)
198             afs_osi_Sleep(&afs_initState);
199         afs_rxevent_daemon();
200         AFS_GUNLOCK();
201         thread_terminate(current_thread());
202         break;
203     case AFSOP_RXLISTENER_DAEMON:
204         AFS_GLOCK();
205         wakeup(arg);
206         afs_initState = AFSOP_START_AFS;
207         afs_osi_Wakeup(&afs_initState);
208         afs_RX_Running = 2;
209         afs_osi_Wakeup(&afs_RX_Running);
210         afs_osi_RxkRegister();
211         rxk_Listener();
212         AFS_GUNLOCK();
213         thread_terminate(current_thread());
214         break;
215     default:
216         printf("Unknown op %ld in StartDaemon()\n", (long)parm);
217         break;
218     }
219 }
220
221 void
222 afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5,
223              long parm6)
224 {
225     int code;
226     struct afsd_thread_info info;
227     thread_t thread;
228
229     if (parm == AFSOP_START_RXCALLBACK) {
230         if (afs_CB_Running)
231             return;
232     } else if (parm == AFSOP_RXLISTENER_DAEMON) {
233         if (afs_RX_Running)
234             return;
235         afs_RX_Running = 1;
236         code = afs_InitSetup(parm2);
237         if (parm3) {
238             rx_enablePeerRPCStats();
239         }
240         if (parm4) {
241             rx_enableProcessRPCStats();
242         }
243         if (code)
244             return;
245     } else if (parm == AFSOP_START_AFS) {
246         if (AFS_Running)
247             return;
248     }                           /* other functions don't need setup in the parent */
249     info.parm = parm;
250     kernel_thread_start((thread_continue_t)afsd_thread, &info, &thread);
251     AFS_GUNLOCK();
252     /* we need to wait cause we passed stack pointers around.... */
253     msleep(&info, NULL, PVFS, "afs_DaemonOp", NULL);
254     AFS_GLOCK();
255     thread_deallocate(thread);
256 }
257 #endif
258
259
260 #if defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS)
261 struct afsd_thread_info {
262 #if defined(AFS_LINUX26_ENV) && !defined(INIT_WORK_HAS_DATA)
263     struct work_struct tq;
264 #endif
265     unsigned long parm;
266     struct completion *complete;
267 };
268
269 static int
270 afsd_thread(void *rock)
271 {
272     struct afsd_thread_info *arg = rock;
273     unsigned long parm = arg->parm;
274 #ifdef SYS_SETPRIORITY_EXPORTED
275     int (*sys_setpriority) (int, int, int) = sys_call_table[__NR_setpriority];
276 #endif
277 #if defined(AFS_LINUX26_ENV)
278     daemonize("afsd");
279 #else
280     daemonize();
281 #endif
282                                 /* doesn't do much, since we were forked from keventd, but
283                                  * does call mm_release, which wakes up our parent (since it
284                                  * used CLONE_VFORK) */
285 #if !defined(AFS_LINUX26_ENV)
286     reparent_to_init();
287 #endif
288     afs_osi_MaskSignals();
289     switch (parm) {
290     case AFSOP_START_RXCALLBACK:
291         sprintf(current->comm, "afs_cbstart");
292         AFS_GLOCK();
293         complete(arg->complete);
294         afs_CB_Running = 1;
295         while (afs_RX_Running != 2)
296             afs_osi_Sleep(&afs_RX_Running);
297         sprintf(current->comm, "afs_callback");
298         afs_RXCallBackServer();
299         AFS_GUNLOCK();
300         complete_and_exit(0, 0);
301         break;
302     case AFSOP_START_AFS:
303         sprintf(current->comm, "afs_afsstart");
304         AFS_GLOCK();
305         complete(arg->complete);
306         AFS_Running = 1;
307         while (afs_initState < AFSOP_START_AFS)
308             afs_osi_Sleep(&afs_initState);
309         afs_initState = AFSOP_START_BKG;
310         afs_osi_Wakeup(&afs_initState);
311         sprintf(current->comm, "afsd");
312         afs_Daemon();
313         AFS_GUNLOCK();
314         complete_and_exit(0, 0);
315         break;
316     case AFSOP_START_BKG:
317         sprintf(current->comm, "afs_bkgstart");
318         AFS_GLOCK();
319         complete(arg->complete);
320         while (afs_initState < AFSOP_START_BKG)
321             afs_osi_Sleep(&afs_initState);
322         if (afs_initState < AFSOP_GO) {
323             afs_initState = AFSOP_GO;
324             afs_osi_Wakeup(&afs_initState);
325         }
326         sprintf(current->comm, "afs_background");
327         afs_BackgroundDaemon();
328         AFS_GUNLOCK();
329         complete_and_exit(0, 0);
330         break;
331     case AFSOP_START_TRUNCDAEMON:
332         sprintf(current->comm, "afs_trimstart");
333         AFS_GLOCK();
334         complete(arg->complete);
335         while (afs_initState < AFSOP_GO)
336             afs_osi_Sleep(&afs_initState);
337         sprintf(current->comm, "afs_cachetrim");
338         afs_CacheTruncateDaemon();
339         AFS_GUNLOCK();
340         complete_and_exit(0, 0);
341         break;
342     case AFSOP_START_CS:
343         sprintf(current->comm, "afs_checkserver");
344         AFS_GLOCK();
345         complete(arg->complete);
346         afs_CheckServerDaemon();
347         AFS_GUNLOCK();
348         complete_and_exit(0, 0);
349         break;
350     case AFSOP_RXEVENT_DAEMON:
351         sprintf(current->comm, "afs_evtstart");
352 #ifdef SYS_SETPRIORITY_EXPORTED
353         sys_setpriority(PRIO_PROCESS, 0, -10);
354 #else
355 #ifdef CURRENT_INCLUDES_NICE
356         current->nice = -10;
357 #endif
358 #endif
359         AFS_GLOCK();
360         complete(arg->complete);
361         while (afs_initState < AFSOP_START_BKG)
362             afs_osi_Sleep(&afs_initState);
363         sprintf(current->comm, "afs_rxevent");
364         afs_rxevent_daemon();
365         AFS_GUNLOCK();
366         complete_and_exit(0, 0);
367         break;
368     case AFSOP_RXLISTENER_DAEMON:
369         sprintf(current->comm, "afs_lsnstart");
370 #ifdef SYS_SETPRIORITY_EXPORTED
371         sys_setpriority(PRIO_PROCESS, 0, -10);
372 #else
373 #ifdef CURRENT_INCLUDES_NICE
374         current->nice = -10;
375 #endif
376 #endif
377         AFS_GLOCK();
378         complete(arg->complete);
379         afs_initState = AFSOP_START_AFS;
380         afs_osi_Wakeup(&afs_initState);
381         afs_RX_Running = 2;
382         afs_osi_Wakeup(&afs_RX_Running);
383         afs_osi_RxkRegister();
384         sprintf(current->comm, "afs_rxlistener");
385         rxk_Listener();
386         AFS_GUNLOCK();
387         complete_and_exit(0, 0);
388         break;
389     default:
390         printf("Unknown op %ld in StartDaemon()\n", (long)parm);
391         break;
392     }
393     return 0;
394 }
395
396 void
397 #if defined(AFS_LINUX26_ENV) && !defined(INIT_WORK_HAS_DATA)
398 afsd_launcher(struct work_struct *work)
399 #else
400 afsd_launcher(void *rock)
401 #endif
402 {
403 #if defined(AFS_LINUX26_ENV) && !defined(INIT_WORK_HAS_DATA)
404     struct afsd_thread_info *rock = container_of(work, struct afsd_thread_info, tq);
405 #endif
406
407     if (!kernel_thread(afsd_thread, (void *)rock, CLONE_VFORK | SIGCHLD))
408         printf("kernel_thread failed. afs startup will not complete\n");
409 }
410
411 void
412 afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5,
413              long parm6)
414 {
415     int code;
416     DECLARE_COMPLETION(c);
417 #if defined(AFS_LINUX26_ENV) 
418 #if defined(INIT_WORK_HAS_DATA)
419     struct work_struct tq;
420 #endif
421 #else
422     struct tq_struct tq;
423 #endif
424     struct afsd_thread_info info;
425     if (parm == AFSOP_START_RXCALLBACK) {
426         if (afs_CB_Running)
427             return;
428     } else if (parm == AFSOP_RXLISTENER_DAEMON) {
429         if (afs_RX_Running)
430             return;
431         afs_RX_Running = 1;
432         code = afs_InitSetup(parm2);
433         if (parm3) {
434             rx_enablePeerRPCStats();
435         }
436         if (parm4) {
437             rx_enableProcessRPCStats();
438         }
439         if (code)
440             return;
441     } else if (parm == AFSOP_START_AFS) {
442         if (AFS_Running)
443             return;
444     }                           /* other functions don't need setup in the parent */
445     info.complete = &c;
446     info.parm = parm;
447 #if defined(AFS_LINUX26_ENV)
448 #if !defined(INIT_WORK_HAS_DATA)
449     INIT_WORK(&info.tq, afsd_launcher);
450     schedule_work(&info.tq);
451 #else
452     INIT_WORK(&tq, afsd_launcher, &info);
453     schedule_work(&tq);
454 #endif
455 #else
456     tq.sync = 0;
457     INIT_LIST_HEAD(&tq.list);
458     tq.routine = afsd_launcher;
459     tq.data = &info;
460     schedule_task(&tq);
461 #endif
462     AFS_GUNLOCK();
463     /* we need to wait cause we passed stack pointers around.... */
464     wait_for_completion(&c);
465     AFS_GLOCK();
466 }
467 #endif
468
469 static void
470 wait_for_cachedefs(void) {
471 #ifdef AFS_CACHE_VNODE_PATH
472     if (cacheDiskType != AFS_FCACHE_TYPE_MEM) 
473         while ((afs_numcachefiles < 1) || (afs_numfilesperdir < 1) ||
474                (afs_cachebasedir[0] != '/')) {
475             printf("afs: waiting for cache parameter definitions\n");
476             afs_osi_Sleep(&afs_initState);
477         }
478 #endif
479 }
480
481 int
482 afs_syscall_call(long parm, long parm2, long parm3, long parm4, long parm5, long parm6)
483 {
484     afs_int32 code = 0;
485 #if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
486     size_t bufferSize;
487 #else /* AFS_SGI61_ENV */
488     u_int bufferSize;
489 #endif /* AFS_SGI61_ENV */
490
491     AFS_STATCNT(afs_syscall_call);
492     if (
493 #ifdef  AFS_SUN5_ENV
494         !afs_suser(CRED())
495 #else
496         !afs_suser(NULL)
497 #endif
498                     && (parm != AFSOP_GETMTU) && (parm != AFSOP_GETMASK)) {
499         /* only root can run this code */
500 #if defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(KERNEL_HAVE_UERROR)
501 #if defined(KERNEL_HAVE_UERROR)
502         setuerror(EACCES);
503 #endif
504         code = EACCES;
505 #else
506         code = EPERM;
507 #endif
508         AFS_GLOCK();
509 #ifdef AFS_DARWIN80_ENV
510         put_vfs_context();
511 #endif
512         goto out;
513     }
514     AFS_GLOCK();
515 #ifdef AFS_DARWIN80_ENV
516     put_vfs_context();
517 #endif
518 #if ((defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS)) || defined(AFS_DARWIN80_ENV)) && !defined(UKERNEL)
519     if (parm < AFSOP_ADDCELL || parm == AFSOP_RXEVENT_DAEMON
520         || parm == AFSOP_RXLISTENER_DAEMON) {
521         afs_DaemonOp(parm, parm2, parm3, parm4, parm5, parm6);
522     }
523 #else /* !(AFS_LINUX24_ENV && !UKERNEL) */
524     if (parm == AFSOP_START_RXCALLBACK) {
525         if (afs_CB_Running)
526             goto out;
527         afs_CB_Running = 1;
528 #ifndef RXK_LISTENER_ENV
529         code = afs_InitSetup(parm2);
530         if (!code)
531 #endif /* !RXK_LISTENER_ENV */
532         {
533 #ifdef RXK_LISTENER_ENV
534             while (afs_RX_Running != 2)
535                 afs_osi_Sleep(&afs_RX_Running);
536 #else /* !RXK_LISTENER_ENV */
537             afs_initState = AFSOP_START_AFS;
538             afs_osi_Wakeup(&afs_initState);
539 #endif /* RXK_LISTENER_ENV */
540             afs_osi_Invisible();
541             afs_RXCallBackServer();
542             afs_osi_Visible();
543         }
544 #ifdef AFS_SGI_ENV
545         AFS_GUNLOCK();
546         exit(CLD_EXITED, code);
547 #endif /* AFS_SGI_ENV */
548     }
549 #ifdef RXK_LISTENER_ENV
550     else if (parm == AFSOP_RXLISTENER_DAEMON) {
551         if (afs_RX_Running)
552             goto out;
553         afs_RX_Running = 1;
554         code = afs_InitSetup(parm2);
555         if (parm3) {
556             rx_enablePeerRPCStats();
557         }
558         if (parm4) {
559             rx_enableProcessRPCStats();
560         }
561         if (!code) {
562             afs_initState = AFSOP_START_AFS;
563             afs_osi_Wakeup(&afs_initState);
564             afs_osi_Invisible();
565             afs_RX_Running = 2;
566             afs_osi_Wakeup(&afs_RX_Running);
567 #ifndef UKERNEL
568             afs_osi_RxkRegister();
569 #endif /* !UKERNEL */
570             rxk_Listener();
571             afs_osi_Visible();
572         }
573 #ifdef  AFS_SGI_ENV
574         AFS_GUNLOCK();
575         exit(CLD_EXITED, code);
576 #endif /* AFS_SGI_ENV */
577     }
578 #endif /* RXK_LISTENER_ENV */
579     else if (parm == AFSOP_START_AFS) {
580         /* afs daemon */
581         if (AFS_Running)
582             goto out;
583         AFS_Running = 1;
584         while (afs_initState < AFSOP_START_AFS)
585             afs_osi_Sleep(&afs_initState);
586
587         afs_initState = AFSOP_START_BKG;
588         afs_osi_Wakeup(&afs_initState);
589         afs_osi_Invisible();
590         afs_Daemon();
591         afs_osi_Visible();
592 #ifdef AFS_SGI_ENV
593         AFS_GUNLOCK();
594         exit(CLD_EXITED, 0);
595 #endif /* AFS_SGI_ENV */
596     } else if (parm == AFSOP_START_CS) {
597         afs_osi_Invisible();
598         afs_CheckServerDaemon();
599         afs_osi_Visible();
600 #ifdef AFS_SGI_ENV
601         AFS_GUNLOCK();
602         exit(CLD_EXITED, 0);
603 #endif /* AFS_SGI_ENV */
604     } else if (parm == AFSOP_START_BKG) {
605         while (afs_initState < AFSOP_START_BKG)
606             afs_osi_Sleep(&afs_initState);
607         if (afs_initState < AFSOP_GO) {
608             afs_initState = AFSOP_GO;
609             afs_osi_Wakeup(&afs_initState);
610         }
611         /* start the bkg daemon */
612         afs_osi_Invisible();
613 #ifdef AFS_AIX32_ENV
614         if (parm2)
615             afs_BioDaemon(parm2);
616         else
617 #endif /* AFS_AIX32_ENV */
618             afs_BackgroundDaemon();
619         afs_osi_Visible();
620 #ifdef AFS_SGI_ENV
621         AFS_GUNLOCK();
622         exit(CLD_EXITED, 0);
623 #endif /* AFS_SGI_ENV */
624     } else if (parm == AFSOP_START_TRUNCDAEMON) {
625         while (afs_initState < AFSOP_GO)
626             afs_osi_Sleep(&afs_initState);
627         /* start the bkg daemon */
628         afs_osi_Invisible();
629         afs_CacheTruncateDaemon();
630         afs_osi_Visible();
631 #ifdef  AFS_SGI_ENV
632         AFS_GUNLOCK();
633         exit(CLD_EXITED, 0);
634 #endif /* AFS_SGI_ENV */
635     }
636 #if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
637     else if (parm == AFSOP_RXEVENT_DAEMON) {
638         while (afs_initState < AFSOP_START_BKG)
639             afs_osi_Sleep(&afs_initState);
640         afs_osi_Invisible();
641         afs_rxevent_daemon();
642         afs_osi_Visible();
643 #ifdef AFS_SGI_ENV
644         AFS_GUNLOCK();
645         exit(CLD_EXITED, 0);
646 #endif /* AFS_SGI_ENV */
647     }
648 #endif /* AFS_SUN5_ENV || RXK_LISTENER_ENV */
649 #endif /* AFS_LINUX24_ENV && !UKERNEL */
650     else if (parm == AFSOP_BASIC_INIT) {
651         afs_int32 temp;
652
653         while (!afs_InitSetup_done)
654             afs_osi_Sleep(&afs_InitSetup_done);
655
656 #if defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_SUN5_ENV)
657         temp = AFS_MINBUFFERS;  /* Should fix this soon */
658 #else
659         /* number of 2k buffers we could get from all of the buffer space */
660         temp = ((afs_bufferpages * NBPG) >> 11);
661         temp = temp >> 2;       /* don't take more than 25% (our magic parameter) */
662         if (temp < AFS_MINBUFFERS)
663             temp = AFS_MINBUFFERS;      /* though we really should have this many */
664 #endif
665         DInit(temp);
666         afs_rootFid.Fid.Volume = 0;
667         code = 0;
668     } else if (parm == AFSOP_BUCKETPCT) {
669         /* need to enable this now, will disable again before GO
670            if we don't have 100% */
671         splitdcache = 1;
672         switch (parm2) {
673         case 1:
674             afs_tpct1 = parm3;
675             break;
676         case 2:
677             afs_tpct2 = parm3;
678             break;
679         }           
680     } else if (parm == AFSOP_ADDCELL) {
681         /* add a cell.  Parameter 2 is 8 hosts (in net order),  parm 3 is the null-terminated
682          * name.  Parameter 4 is the length of the name, including the null.  Parm 5 is the
683          * home cell flag (0x1 bit) and the nosuid flag (0x2 bit) */
684         struct afsop_cell *tcell = afs_osi_Alloc(sizeof(struct afsop_cell));
685
686         code = afs_InitDynroot();
687         if (!code) {
688             AFS_COPYIN((char *)parm2, (char *)tcell->hosts, sizeof(tcell->hosts),
689                        code);
690         }
691         if (!code) {
692             if (parm4 > sizeof(tcell->cellName))
693                 code = EFAULT;
694             else {
695                 AFS_COPYIN((char *)parm3, tcell->cellName, parm4, code);
696                 if (!code)
697                     afs_NewCell(tcell->cellName, tcell->hosts, parm5, NULL, 0,
698                                 0, 0);
699             }
700         }
701         afs_osi_Free(tcell, sizeof(struct afsop_cell));
702     } else if (parm == AFSOP_ADDCELL2) {
703         struct afsop_cell *tcell = afs_osi_Alloc(sizeof(struct afsop_cell));
704         char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ), *lcnamep = 0;
705         char *tbuffer1 = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
706         int cflags = parm4;
707
708         code = afs_InitDynroot();
709         if (!code) {
710 #if 0
711             /* wait for basic init - XXX can't find any reason we need this? */
712             while (afs_initState < AFSOP_START_BKG)
713                 afs_osi_Sleep(&afs_initState);
714 #endif
715
716             AFS_COPYIN((char *)parm2, (char *)tcell->hosts, sizeof(tcell->hosts),
717                        code);
718         }
719         if (!code) {
720             AFS_COPYINSTR((char *)parm3, tbuffer1, AFS_SMALLOCSIZ,
721                           &bufferSize, code);
722             if (!code) {
723                 if (parm4 & 4) {
724                     AFS_COPYINSTR((char *)parm5, tbuffer, AFS_SMALLOCSIZ,
725                                   &bufferSize, code);
726                     if (!code) {
727                         lcnamep = tbuffer;
728                         cflags |= CLinkedCell;
729                     }
730                 }
731                 if (!code)
732                     code =
733                         afs_NewCell(tbuffer1, tcell->hosts, cflags, lcnamep,
734                                     0, 0, 0);
735             }
736         }
737         afs_osi_Free(tcell, sizeof(struct afsop_cell));
738         osi_FreeSmallSpace(tbuffer);
739         osi_FreeSmallSpace(tbuffer1);
740     } else if (parm == AFSOP_ADDCELLALIAS) {
741         /*
742          * Call arguments:
743          * parm2 is the alias name
744          * parm3 is the real cell name
745          */
746         char *aliasName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
747         char *cellName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
748
749         code = afs_InitDynroot();
750         if (!code) {
751             AFS_COPYINSTR((char *)parm2, aliasName, AFS_SMALLOCSIZ, &bufferSize,
752                           code);
753         }
754         if (!code)
755             AFS_COPYINSTR((char *)parm3, cellName, AFS_SMALLOCSIZ,
756                           &bufferSize, code);
757         if (!code)
758             afs_NewCellAlias(aliasName, cellName);
759         osi_FreeSmallSpace(aliasName);
760         osi_FreeSmallSpace(cellName);
761     } else if (parm == AFSOP_SET_THISCELL) {
762         /*
763          * Call arguments:
764          * parm2 is the primary cell name
765          */
766         char *cell = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
767
768         code = afs_InitDynroot();
769         if (!code) {
770             AFS_COPYINSTR((char *)parm2, cell, AFS_SMALLOCSIZ, &bufferSize, code);
771         }
772         if (!code)
773             afs_SetPrimaryCell(cell);
774         osi_FreeSmallSpace(cell);
775     } else if (parm == AFSOP_CACHEINIT) {
776         struct afs_cacheParams cparms;
777
778         if (afs_CacheInit_Done)
779             goto out;
780
781         AFS_COPYIN((char *)parm2, (caddr_t) & cparms, sizeof(cparms), code);
782         if (code) {
783 #if defined(KERNEL_HAVE_UERROR)
784             setuerror(code);
785             code = -1;
786 #endif
787             goto out;
788         }
789         afs_CacheInit_Done = 1;
790         code = afs_icl_InitLogs();
791         afs_setTime = cparms.setTimeFlag;
792
793         code =
794             afs_CacheInit(cparms.cacheScaches, cparms.cacheFiles,
795                           cparms.cacheBlocks, cparms.cacheDcaches,
796                           cparms.cacheVolumes, cparms.chunkSize,
797                           cparms.memCacheFlag, cparms.inodes, cparms.users);
798
799     } else if (parm == AFSOP_CACHEINODE) {
800         ino_t ainode = parm2;
801         /* wait for basic init */
802         while (afs_initState < AFSOP_START_BKG)
803             afs_osi_Sleep(&afs_initState);
804
805 #ifdef AFS_DARWIN80_ENV
806         get_vfs_context();
807 #endif
808         /* do it by inode */
809 #ifdef AFS_SGI62_ENV
810         ainode = (ainode << 32) | (parm3 & 0xffffffff);
811 #endif
812         code = afs_InitCacheFile(NULL, ainode);
813 #ifdef AFS_DARWIN80_ENV
814         put_vfs_context();
815 #endif
816     } else if (parm == AFSOP_CACHEDIRS) {
817         afs_numfilesperdir = parm2;
818         afs_osi_Wakeup(&afs_initState);
819     } else if (parm == AFSOP_CACHEFILES) {
820         afs_numcachefiles = parm2;
821         afs_osi_Wakeup(&afs_initState);
822     } else if (parm == AFSOP_ROOTVOLUME) {
823         /* wait for basic init */
824         while (afs_initState < AFSOP_START_BKG)
825             afs_osi_Sleep(&afs_initState);
826
827         if (parm2) {
828             AFS_COPYINSTR((char *)parm2, afs_rootVolumeName,
829                           sizeof(afs_rootVolumeName), &bufferSize, code);
830             afs_rootVolumeName[sizeof(afs_rootVolumeName) - 1] = 0;
831         } else
832             code = 0;
833     } else if (parm == AFSOP_CACHEFILE || parm == AFSOP_CACHEINFO
834                || parm == AFSOP_VOLUMEINFO || parm == AFSOP_AFSLOG
835                || parm == AFSOP_CELLINFO || parm == AFSOP_CACHEBASEDIR) {
836         char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
837
838         code = 0;
839         AFS_COPYINSTR((char *)parm2, tbuffer, AFS_SMALLOCSIZ, &bufferSize,
840                       code);
841         if (code) {
842             osi_FreeSmallSpace(tbuffer);
843             goto out;
844         }
845         if (!code) {
846             tbuffer[AFS_SMALLOCSIZ - 1] = '\0'; /* null-terminate the name */
847             /* We have the cache dir copied in.  Call the cache init routine */
848 #ifdef AFS_DARWIN80_ENV
849     get_vfs_context();
850 #endif
851             if (parm == AFSOP_CACHEBASEDIR) {
852                 strncpy(afs_cachebasedir, tbuffer, 1024);
853                 afs_cachebasedir[1023] = '\0';
854                 afs_osi_Wakeup(&afs_initState);
855             } else if (parm == AFSOP_CACHEFILE) {
856                 wait_for_cachedefs();
857                 code = afs_InitCacheFile(tbuffer, 0);
858             } else if (parm == AFSOP_CACHEINFO) {
859                 wait_for_cachedefs();
860                 code = afs_InitCacheInfo(tbuffer);
861             } else if (parm == AFSOP_VOLUMEINFO) {
862                 wait_for_cachedefs();
863                 code = afs_InitVolumeInfo(tbuffer);
864             } else if (parm == AFSOP_CELLINFO) {
865                 wait_for_cachedefs();
866                 code = afs_InitCellInfo(tbuffer);
867             }
868 #ifdef AFS_DARWIN80_ENV
869             put_vfs_context();
870 #endif
871         }
872         osi_FreeSmallSpace(tbuffer);
873     } else if (parm == AFSOP_GO) {
874 #ifdef AFS_CACHE_VNODE_PATH
875         if (cacheDiskType != AFS_FCACHE_TYPE_MEM) {
876             afs_int32 dummy;
877             
878             wait_for_cachedefs();
879             
880 #ifdef AFS_DARWIN80_ENV
881             get_vfs_context();
882 #endif
883             if ((afs_numcachefiles > 0) && (afs_numfilesperdir > 0) && 
884                 (afs_cachebasedir[0] == '/')) {
885                 for (dummy = 0; dummy < afs_numcachefiles; dummy++) {
886                     code = afs_InitCacheFile(NULL, dummy);
887                 }
888             }
889 #ifdef AFS_DARWIN80_ENV
890             put_vfs_context();
891 #endif
892         }
893 #endif
894         /* the generic initialization calls come here.  One parameter: should we do the
895          * set-time operation on this workstation */
896         if (afs_Go_Done)
897             goto out;
898         afs_Go_Done = 1;
899         while (afs_initState < AFSOP_GO)
900             afs_osi_Sleep(&afs_initState);
901         afs_initState = 101;
902         afs_setTime = parm2;
903         if (afs_tpct1 + afs_tpct2 != 100) {
904             afs_tpct1 = 0;
905             afs_tpct2 = 0;
906             splitdcache = 0;
907         } else {        
908             splitdcache = 1;
909         }
910         afs_osi_Wakeup(&afs_initState);
911 #if     (!defined(AFS_NONFSTRANS)) || defined(AFS_AIX_IAUTH_ENV)
912         afs_nfsclient_init();
913 #endif
914         afs_uuid_create(&afs_cb_interface.uuid);
915         printf("found %d non-empty cache files (%d%%).\n",
916                afs_stats_cmperf.cacheFilesReused,
917                (100 * afs_stats_cmperf.cacheFilesReused) /
918                (afs_stats_cmperf.cacheNumEntries ? afs_stats_cmperf.
919                 cacheNumEntries : 1));
920     } else if (parm == AFSOP_ADVISEADDR) {
921         /* pass in the host address to the rx package */
922         int rxbind = 0;
923         int refresh = 0;
924
925         afs_int32 count = parm2;
926         afs_int32 *buffer =
927             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
928         afs_int32 *maskbuffer =
929             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
930         afs_int32 *mtubuffer =
931             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
932         int i;
933
934         /* This is a refresh */
935         if (count & 0x40000000) {
936             count &= ~0x40000000;
937             /* Can't bind after we start. Fix? */
938             count &= ~0x80000000;
939             refresh = 1;
940         }
941
942         /* Bind, but only if there's only one address configured */ 
943         if ( count & 0x80000000) {
944             count &= ~0x80000000;
945             if (count == 1)
946                 rxbind=1;
947         }
948
949         if (count > AFS_MAX_INTERFACE_ADDR) {
950             code = ENOMEM;
951             count = AFS_MAX_INTERFACE_ADDR;
952         }
953
954         AFS_COPYIN((char *)parm3, (char *)buffer, count * sizeof(afs_int32),
955                    code);
956         if (parm4)
957             AFS_COPYIN((char *)parm4, (char *)maskbuffer,
958                        count * sizeof(afs_int32), code);
959         if (parm5)
960             AFS_COPYIN((char *)parm5, (char *)mtubuffer,
961                        count * sizeof(afs_int32), code);
962
963         afs_cb_interface.numberOfInterfaces = count;
964         for (i = 0; i < count; i++) {
965             afs_cb_interface.addr_in[i] = buffer[i];
966 #ifdef AFS_USERSPACE_IP_ADDR
967             /* AFS_USERSPACE_IP_ADDR means we have no way of finding the
968              * machines IP addresses when in the kernel (the in_ifaddr
969              * struct is not available), so we pass the info in at
970              * startup. We also pass in the subnetmask and mtu size. The
971              * subnetmask is used when setting the rank:
972              * afsi_SetServerIPRank(); and the mtu size is used when
973              * finding the best mtu size. rxi_FindIfnet() is replaced
974              * with rxi_Findcbi().
975              */
976             afs_cb_interface.subnetmask[i] =
977                 (parm4 ? maskbuffer[i] : 0xffffffff);
978             afs_cb_interface.mtu[i] = (parm5 ? mtubuffer[i] : htonl(1500));
979 #endif
980         }
981         rxi_setaddr(buffer[0]);
982         if (!refresh) {
983             if (rxbind)
984                 rx_bindhost = buffer[0];
985             else
986                 rx_bindhost = htonl(INADDR_ANY);
987         }
988
989         afs_osi_Free(buffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
990         afs_osi_Free(maskbuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
991         afs_osi_Free(mtubuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
992
993         if (refresh) {
994             afs_CheckServers(1, NULL);     /* check down servers */
995             afs_CheckServers(0, NULL);     /* check down servers */
996         }
997     }
998 #ifdef  AFS_SGI53_ENV
999     else if (parm == AFSOP_NFSSTATICADDR) {
1000         extern int (*nfs_rfsdisptab_v2) ();
1001         nfs_rfsdisptab_v2 = (int (*)())parm2;
1002     } else if (parm == AFSOP_NFSSTATICADDR2) {
1003         extern int (*nfs_rfsdisptab_v2) ();
1004 #ifdef _K64U64
1005         nfs_rfsdisptab_v2 = (int (*)())((parm2 << 32) | (parm3 & 0xffffffff));
1006 #else /* _K64U64 */
1007         nfs_rfsdisptab_v2 = (int (*)())(parm3 & 0xffffffff);
1008 #endif /* _K64U64 */
1009     }
1010 #if defined(AFS_SGI62_ENV) && !defined(AFS_SGI65_ENV)
1011     else if (parm == AFSOP_SBLOCKSTATICADDR2) {
1012         extern int (*afs_sblockp) ();
1013         extern void (*afs_sbunlockp) ();
1014 #ifdef _K64U64
1015         afs_sblockp = (int (*)())((parm2 << 32) | (parm3 & 0xffffffff));
1016         afs_sbunlockp = (void (*)())((parm4 << 32) | (parm5 & 0xffffffff));
1017 #else
1018         afs_sblockp = (int (*)())(parm3 & 0xffffffff);
1019         afs_sbunlockp = (void (*)())(parm5 & 0xffffffff);
1020 #endif /* _K64U64 */
1021     }
1022 #endif /* AFS_SGI62_ENV && !AFS_SGI65_ENV */
1023 #endif /* AFS_SGI53_ENV */
1024     else if (parm == AFSOP_SHUTDOWN) {
1025         afs_cold_shutdown = 0;
1026         if (parm2 == 1)
1027             afs_cold_shutdown = 1;
1028 #ifndef AFS_DARWIN_ENV
1029         if (afs_globalVFS != 0) {
1030             afs_warn("AFS isn't unmounted yet! Call aborted\n");
1031             code = EACCES;
1032         } else
1033 #endif
1034             afs_shutdown();
1035     } else if (parm == AFSOP_AFS_VFSMOUNT) {
1036 #ifdef  AFS_HPUX_ENV
1037         vfsmount(parm2, parm3, parm4, parm5);
1038 #else /* defined(AFS_HPUX_ENV) */
1039 #if defined(KERNEL_HAVE_UERROR)
1040         setuerror(EINVAL);
1041 #else
1042         code = EINVAL;
1043 #endif
1044 #endif /* defined(AFS_HPUX_ENV) */
1045     } else if (parm == AFSOP_CLOSEWAIT) {
1046         afs_SynchronousCloses = 'S';
1047     } else if (parm == AFSOP_GETMTU) {
1048         afs_uint32 mtu = 0;
1049 #if     !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV)
1050 #ifdef AFS_USERSPACE_IP_ADDR
1051         afs_int32 i;
1052         i = rxi_Findcbi(parm2);
1053         mtu = ((i == -1) ? htonl(1500) : afs_cb_interface.mtu[i]);
1054 #else /* AFS_USERSPACE_IP_ADDR */
1055         AFS_IFNET_T tifnp;
1056
1057         tifnp = rxi_FindIfnet(parm2, NULL);     /*  make iterative */
1058         mtu = (tifnp ? ifnet_mtu(tifnp) : htonl(1500));
1059 #endif /* else AFS_USERSPACE_IP_ADDR */
1060 #endif /* !AFS_SUN5_ENV */
1061         if (!code)
1062             AFS_COPYOUT((caddr_t) & mtu, (caddr_t) parm3, sizeof(afs_int32),
1063                         code);
1064 #ifdef AFS_AIX32_ENV
1065 /* this is disabled for now because I can't figure out how to get access
1066  * to these kernel variables.  It's only for supporting user-mode rx
1067  * programs -- it makes a huge difference on the 220's in my testbed,
1068  * though I don't know why. The bosserver does this with /etc/no, so it's
1069  * being handled a different way for the servers right now.  */
1070 /*      {
1071         static adjusted = 0;
1072         extern u_long sb_max_dflt;
1073         if (!adjusted) {
1074           adjusted = 1;
1075           if (sb_max_dflt < 131072) sb_max_dflt = 131072; 
1076           if (sb_max < 131072) sb_max = 131072; 
1077         }
1078       } */
1079 #endif /* AFS_AIX32_ENV */
1080     } else if (parm == AFSOP_GETMASK) { /* parm2 == addr in net order */
1081         afs_uint32 mask = 0;
1082 #if     !defined(AFS_SUN5_ENV)
1083 #ifdef AFS_USERSPACE_IP_ADDR
1084         afs_int32 i;
1085         i = rxi_Findcbi(parm2);
1086         if (i != -1) {
1087             mask = afs_cb_interface.subnetmask[i];
1088         } else {
1089             code = -1;
1090         }
1091 #else /* AFS_USERSPACE_IP_ADDR */
1092         AFS_IFNET_T tifnp;
1093
1094         tifnp = rxi_FindIfnet(parm2, &mask);    /* make iterative */
1095         if (!tifnp)
1096             code = -1;
1097 #endif /* else AFS_USERSPACE_IP_ADDR */
1098 #endif /* !AFS_SUN5_ENV */
1099         if (!code)
1100             AFS_COPYOUT((caddr_t) & mask, (caddr_t) parm3, sizeof(afs_int32),
1101                         code);
1102     }
1103 #ifdef AFS_AFSDB_ENV
1104     else if (parm == AFSOP_AFSDB_HANDLER) {
1105         int sizeArg = (int)parm4;
1106         int kmsgLen = sizeArg & 0xffff;
1107         int cellLen = (sizeArg & 0xffff0000) >> 16;
1108         afs_int32 *kmsg = afs_osi_Alloc(kmsgLen);
1109         char *cellname = afs_osi_Alloc(cellLen);
1110
1111 #ifndef UKERNEL
1112         afs_osi_MaskUserLoop();
1113 #endif
1114         AFS_COPYIN((afs_int32 *) parm2, cellname, cellLen, code);
1115         AFS_COPYIN((afs_int32 *) parm3, kmsg, kmsgLen, code);
1116         if (!code) {
1117             code = afs_AFSDBHandler(cellname, cellLen, kmsg);
1118             if (*cellname == 1)
1119                 *cellname = 0;
1120             if (code == -2) {   /* Shutting down? */
1121                 *cellname = 1;
1122                 code = 0;
1123             }
1124         }
1125         if (!code)
1126             AFS_COPYOUT(cellname, (char *)parm2, cellLen, code);
1127         afs_osi_Free(kmsg, kmsgLen);
1128         afs_osi_Free(cellname, cellLen);
1129     }
1130 #endif
1131     else if (parm == AFSOP_SET_DYNROOT) {
1132         code = afs_SetDynrootEnable(parm2);
1133     } else if (parm == AFSOP_SET_FAKESTAT) {
1134         afs_fakestat_enable = parm2;
1135         code = 0;
1136     } else if (parm == AFSOP_SET_BACKUPTREE) {
1137         afs_bkvolpref = parm2;
1138     } else if (parm == AFSOP_SET_RXPCK) {
1139         rx_extraPackets = parm2;
1140         afscall_set_rxpck_received = 1;
1141     } else
1142         code = EINVAL;
1143
1144   out:
1145     AFS_GUNLOCK();
1146 #ifdef AFS_LINUX20_ENV
1147     return -code;
1148 #else
1149     return code;
1150 #endif
1151 }
1152
1153 /*
1154  * Initstate in the range 0 < x < 100 are early initialization states.
1155  * Initstate of 100 means a AFSOP_START operation has been done.  After this,
1156  *  the cache may be initialized.
1157  * Initstate of 101 means a AFSOP_GO operation has been done.  This operation
1158  *  is done after all the cache initialization has been done.
1159  * Initstate of 200 means that the volume has been looked up once, possibly
1160  *  incorrectly.
1161  * Initstate of 300 means that the volume has been *successfully* looked up.
1162  */
1163 int
1164 afs_CheckInit(void)
1165 {
1166     register int code = 0;
1167
1168     AFS_STATCNT(afs_CheckInit);
1169     if (afs_initState <= 100)
1170         code = ENXIO;           /* never finished init phase */
1171     else if (afs_initState == 101) {    /* init done, wait for afs_daemon */
1172         while (afs_initState < 200)
1173             afs_osi_Sleep(&afs_initState);
1174     } else if (afs_initState == 200)
1175         code = ETIMEDOUT;       /* didn't find root volume */
1176     return code;
1177 }
1178
1179 int afs_shuttingdown = 0;
1180 void
1181 afs_shutdown(void)
1182 {
1183     extern short afs_brsDaemons;
1184     extern afs_int32 afs_CheckServerDaemonStarted;
1185     extern struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
1186     extern struct osi_file *afs_cacheInodep;
1187
1188     AFS_STATCNT(afs_shutdown);
1189     if (afs_initState == 0) {
1190         afs_warn("AFS not initialized - not shutting down\n");
1191       return;
1192     }
1193
1194     if (afs_shuttingdown)
1195         return;
1196     afs_shuttingdown = 1;
1197     if (afs_cold_shutdown)
1198         afs_warn("COLD ");
1199     else
1200         afs_warn("WARM ");
1201     afs_warn("shutting down of: CB... ");
1202
1203     afs_termState = AFSOP_STOP_RXCALLBACK;
1204     rx_WakeupServerProcs();
1205 #ifdef AFS_AIX51_ENV
1206     shutdown_rxkernel();
1207 #endif
1208     /* shutdown_rxkernel(); */
1209     while (afs_termState == AFSOP_STOP_RXCALLBACK)
1210         afs_osi_Sleep(&afs_termState);
1211
1212     afs_warn("afs... ");
1213     while (afs_termState == AFSOP_STOP_AFS) {
1214         afs_osi_CancelWait(&AFS_WaitHandler);
1215         afs_osi_Sleep(&afs_termState);
1216     }
1217     if (afs_CheckServerDaemonStarted) {
1218         while (afs_termState == AFSOP_STOP_CS) {
1219             afs_osi_CancelWait(&AFS_CSWaitHandler);
1220             afs_osi_Sleep(&afs_termState);
1221         }
1222     }
1223     afs_warn("BkG... ");
1224     /* Wake-up afs_brsDaemons so that we don't have to wait for a bkg job! */
1225     while (afs_termState == AFSOP_STOP_BKG) {
1226         afs_osi_Wakeup(&afs_brsDaemons);
1227         afs_osi_Sleep(&afs_termState);
1228     }
1229     afs_warn("CTrunc... ");
1230     /* Cancel cache truncate daemon. */
1231     while (afs_termState == AFSOP_STOP_TRUNCDAEMON) {
1232         afs_osi_Wakeup((char *)&afs_CacheTruncateDaemon);
1233         afs_osi_Sleep(&afs_termState);
1234     }
1235 #ifdef AFS_AFSDB_ENV
1236     afs_warn("AFSDB... ");
1237     afs_StopAFSDB();
1238     while (afs_termState == AFSOP_STOP_AFSDB)
1239         afs_osi_Sleep(&afs_termState);
1240 #endif
1241 #if     defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
1242     afs_warn("RxEvent... ");
1243     /* cancel rx event daemon */
1244     while (afs_termState == AFSOP_STOP_RXEVENT)
1245         afs_osi_Sleep(&afs_termState);
1246 #if defined(RXK_LISTENER_ENV)
1247 #ifndef UKERNEL
1248     afs_warn("UnmaskRxkSignals... ");
1249     afs_osi_UnmaskRxkSignals();
1250 #endif
1251     /* cancel rx listener */
1252     afs_warn("RxListener... ");
1253     osi_StopListener();         /* This closes rx_socket. */
1254     while (afs_termState == AFSOP_STOP_RXK_LISTENER) {
1255         afs_warn("Sleep... ");
1256         afs_osi_Sleep(&afs_termState);
1257     }
1258 #endif
1259 #else
1260     afs_termState = AFSOP_STOP_COMPLETE;
1261 #endif
1262     afs_warn("\n");
1263
1264 #ifdef AFS_AIX51_ENV
1265     shutdown_daemons();
1266 #endif
1267
1268 #ifdef notdef
1269     shutdown_CB();
1270     shutdown_AFS();
1271     shutdown_rxkernel();
1272     shutdown_rxevent();
1273     shutdown_rx();
1274     afs_shutdown_BKG();
1275 #endif
1276     shutdown_bufferpackage();
1277     shutdown_cache();
1278     shutdown_osi();
1279     shutdown_osinet();
1280     shutdown_osifile();
1281     shutdown_vnodeops();
1282     shutdown_memcache();
1283 #if (!defined(AFS_NONFSTRANS) || defined(AFS_AIX_IAUTH_ENV)) && !defined(AFS_OSF_ENV)
1284     shutdown_exporter();
1285     shutdown_nfsclnt();
1286 #endif
1287     shutdown_afstest();
1288     /* The following hold the cm stats */
1289 /*
1290     memset(&afs_cmstats, 0, sizeof(struct afs_CMStats));
1291     memset(&afs_stats_cmperf, 0, sizeof(struct afs_stats_CMPerf));
1292     memset(&afs_stats_cmfullperf, 0, sizeof(struct afs_stats_CMFullPerf));
1293 */
1294     afs_warn(" ALL allocated tables\n");
1295
1296     /* Close file only after daemons which can write to it are stopped. */
1297     if (afs_cacheInodep) {      /* memcache won't set this */
1298         osi_UFSClose(afs_cacheInodep);  /* Since we always leave it open */
1299         afs_cacheInodep = 0;
1300     }
1301
1302     afs_shuttingdown = 0;
1303
1304     return;                     /* Just kill daemons for now */
1305 }
1306
1307 void
1308 shutdown_afstest(void)
1309 {
1310     AFS_STATCNT(shutdown_afstest);
1311     afs_initState = afs_termState = afs_setTime = 0;
1312     AFS_Running = afs_CB_Running = 0;
1313     afs_CacheInit_Done = afs_Go_Done = 0;
1314     if (afs_cold_shutdown) {
1315         *afs_rootVolumeName = 0;
1316     }
1317 }
1318
1319
1320 /* In case there is a bunch of dynamically build bkg daemons to free */
1321 void
1322 afs_shutdown_BKG(void)
1323 {
1324     AFS_STATCNT(shutdown_BKG);
1325 }