97c96550d72c1008d2825b4d12bb97fec2fc4d1b
[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     struct work_struct tq;
419 #else
420     struct tq_struct tq;
421 #endif
422     struct afsd_thread_info info;
423     if (parm == AFSOP_START_RXCALLBACK) {
424         if (afs_CB_Running)
425             return;
426     } else if (parm == AFSOP_RXLISTENER_DAEMON) {
427         if (afs_RX_Running)
428             return;
429         afs_RX_Running = 1;
430         code = afs_InitSetup(parm2);
431         if (parm3) {
432             rx_enablePeerRPCStats();
433         }
434         if (parm4) {
435             rx_enableProcessRPCStats();
436         }
437         if (code)
438             return;
439     } else if (parm == AFSOP_START_AFS) {
440         if (AFS_Running)
441             return;
442     }                           /* other functions don't need setup in the parent */
443     info.complete = &c;
444     info.parm = parm;
445 #if defined(AFS_LINUX26_ENV)
446 #if !defined(INIT_WORK_HAS_DATA)
447     INIT_WORK(&info.tq, afsd_launcher);
448     schedule_work(&info.tq);
449 #else
450     INIT_WORK(&tq, afsd_launcher, &info);
451     schedule_work(&tq);
452 #endif
453 #else
454     tq.sync = 0;
455     INIT_LIST_HEAD(&tq.list);
456     tq.routine = afsd_launcher;
457     tq.data = &info;
458     schedule_task(&tq);
459 #endif
460     AFS_GUNLOCK();
461     /* we need to wait cause we passed stack pointers around.... */
462     wait_for_completion(&c);
463     AFS_GLOCK();
464 }
465 #endif
466
467 static void
468 wait_for_cachedefs(void) {
469 #ifdef AFS_CACHE_VNODE_PATH
470     if (cacheDiskType != AFS_FCACHE_TYPE_MEM) 
471         while ((afs_numcachefiles < 1) || (afs_numfilesperdir < 1) ||
472                (afs_cachebasedir[0] != '/')) {
473             printf("afs: waiting for cache parameter definitions\n");
474             afs_osi_Sleep(&afs_initState);
475         }
476 #endif
477 }
478
479 int
480 afs_syscall_call(long parm, long parm2, long parm3, long parm4, long parm5, long parm6)
481 {
482     afs_int32 code = 0;
483 #if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
484     size_t bufferSize;
485 #else /* AFS_SGI61_ENV */
486     u_int bufferSize;
487 #endif /* AFS_SGI61_ENV */
488
489     AFS_STATCNT(afs_syscall_call);
490     if (
491 #ifdef  AFS_SUN5_ENV
492         !afs_suser(CRED())
493 #else
494         !afs_suser(NULL)
495 #endif
496                     && (parm != AFSOP_GETMTU) && (parm != AFSOP_GETMASK)) {
497         /* only root can run this code */
498 #if defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(KERNEL_HAVE_UERROR)
499 #if defined(KERNEL_HAVE_UERROR)
500         setuerror(EACCES);
501 #endif
502         code = EACCES;
503 #else
504         code = EPERM;
505 #endif
506         AFS_GLOCK();
507 #ifdef AFS_DARWIN80_ENV
508         put_vfs_context();
509 #endif
510         goto out;
511     }
512     AFS_GLOCK();
513 #ifdef AFS_DARWIN80_ENV
514     put_vfs_context();
515 #endif
516 #if ((defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS)) || defined(AFS_DARWIN80_ENV)) && !defined(UKERNEL)
517     if (parm < AFSOP_ADDCELL || parm == AFSOP_RXEVENT_DAEMON
518         || parm == AFSOP_RXLISTENER_DAEMON) {
519         afs_DaemonOp(parm, parm2, parm3, parm4, parm5, parm6);
520     }
521 #else /* !(AFS_LINUX24_ENV && !UKERNEL) */
522     if (parm == AFSOP_START_RXCALLBACK) {
523         if (afs_CB_Running)
524             goto out;
525         afs_CB_Running = 1;
526 #ifndef RXK_LISTENER_ENV
527         code = afs_InitSetup(parm2);
528         if (!code)
529 #endif /* !RXK_LISTENER_ENV */
530         {
531 #ifdef RXK_LISTENER_ENV
532             while (afs_RX_Running != 2)
533                 afs_osi_Sleep(&afs_RX_Running);
534 #else /* !RXK_LISTENER_ENV */
535             afs_initState = AFSOP_START_AFS;
536             afs_osi_Wakeup(&afs_initState);
537 #endif /* RXK_LISTENER_ENV */
538             afs_osi_Invisible();
539             afs_RXCallBackServer();
540             afs_osi_Visible();
541         }
542 #ifdef AFS_SGI_ENV
543         AFS_GUNLOCK();
544         exit(CLD_EXITED, code);
545 #endif /* AFS_SGI_ENV */
546     }
547 #ifdef RXK_LISTENER_ENV
548     else if (parm == AFSOP_RXLISTENER_DAEMON) {
549         if (afs_RX_Running)
550             goto out;
551         afs_RX_Running = 1;
552         code = afs_InitSetup(parm2);
553         if (parm3) {
554             rx_enablePeerRPCStats();
555         }
556         if (parm4) {
557             rx_enableProcessRPCStats();
558         }
559         if (!code) {
560             afs_initState = AFSOP_START_AFS;
561             afs_osi_Wakeup(&afs_initState);
562             afs_osi_Invisible();
563             afs_RX_Running = 2;
564             afs_osi_Wakeup(&afs_RX_Running);
565 #ifndef UKERNEL
566             afs_osi_RxkRegister();
567 #endif /* !UKERNEL */
568             rxk_Listener();
569             afs_osi_Visible();
570         }
571 #ifdef  AFS_SGI_ENV
572         AFS_GUNLOCK();
573         exit(CLD_EXITED, code);
574 #endif /* AFS_SGI_ENV */
575     }
576 #endif /* RXK_LISTENER_ENV */
577     else if (parm == AFSOP_START_AFS) {
578         /* afs daemon */
579         if (AFS_Running)
580             goto out;
581         AFS_Running = 1;
582         while (afs_initState < AFSOP_START_AFS)
583             afs_osi_Sleep(&afs_initState);
584
585         afs_initState = AFSOP_START_BKG;
586         afs_osi_Wakeup(&afs_initState);
587         afs_osi_Invisible();
588         afs_Daemon();
589         afs_osi_Visible();
590 #ifdef AFS_SGI_ENV
591         AFS_GUNLOCK();
592         exit(CLD_EXITED, 0);
593 #endif /* AFS_SGI_ENV */
594     } else if (parm == AFSOP_START_CS) {
595         afs_osi_Invisible();
596         afs_CheckServerDaemon();
597         afs_osi_Visible();
598 #ifdef AFS_SGI_ENV
599         AFS_GUNLOCK();
600         exit(CLD_EXITED, 0);
601 #endif /* AFS_SGI_ENV */
602     } else if (parm == AFSOP_START_BKG) {
603         while (afs_initState < AFSOP_START_BKG)
604             afs_osi_Sleep(&afs_initState);
605         if (afs_initState < AFSOP_GO) {
606             afs_initState = AFSOP_GO;
607             afs_osi_Wakeup(&afs_initState);
608         }
609         /* start the bkg daemon */
610         afs_osi_Invisible();
611 #ifdef AFS_AIX32_ENV
612         if (parm2)
613             afs_BioDaemon(parm2);
614         else
615 #endif /* AFS_AIX32_ENV */
616             afs_BackgroundDaemon();
617         afs_osi_Visible();
618 #ifdef AFS_SGI_ENV
619         AFS_GUNLOCK();
620         exit(CLD_EXITED, 0);
621 #endif /* AFS_SGI_ENV */
622     } else if (parm == AFSOP_START_TRUNCDAEMON) {
623         while (afs_initState < AFSOP_GO)
624             afs_osi_Sleep(&afs_initState);
625         /* start the bkg daemon */
626         afs_osi_Invisible();
627         afs_CacheTruncateDaemon();
628         afs_osi_Visible();
629 #ifdef  AFS_SGI_ENV
630         AFS_GUNLOCK();
631         exit(CLD_EXITED, 0);
632 #endif /* AFS_SGI_ENV */
633     }
634 #if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
635     else if (parm == AFSOP_RXEVENT_DAEMON) {
636         while (afs_initState < AFSOP_START_BKG)
637             afs_osi_Sleep(&afs_initState);
638         afs_osi_Invisible();
639         afs_rxevent_daemon();
640         afs_osi_Visible();
641 #ifdef AFS_SGI_ENV
642         AFS_GUNLOCK();
643         exit(CLD_EXITED, 0);
644 #endif /* AFS_SGI_ENV */
645     }
646 #endif /* AFS_SUN5_ENV || RXK_LISTENER_ENV */
647 #endif /* AFS_LINUX24_ENV && !UKERNEL */
648     else if (parm == AFSOP_BASIC_INIT) {
649         afs_int32 temp;
650
651         while (!afs_InitSetup_done)
652             afs_osi_Sleep(&afs_InitSetup_done);
653
654 #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)
655         temp = AFS_MINBUFFERS;  /* Should fix this soon */
656 #else
657         /* number of 2k buffers we could get from all of the buffer space */
658         temp = ((afs_bufferpages * NBPG) >> 11);
659         temp = temp >> 2;       /* don't take more than 25% (our magic parameter) */
660         if (temp < AFS_MINBUFFERS)
661             temp = AFS_MINBUFFERS;      /* though we really should have this many */
662 #endif
663         DInit(temp);
664         afs_rootFid.Fid.Volume = 0;
665         code = 0;
666     } else if (parm == AFSOP_BUCKETPCT) {
667         /* need to enable this now, will disable again before GO
668            if we don't have 100% */
669         splitdcache = 1;
670         switch (parm2) {
671         case 1:
672             afs_tpct1 = parm3;
673             break;
674         case 2:
675             afs_tpct2 = parm3;
676             break;
677         }           
678     } else if (parm == AFSOP_ADDCELL) {
679         /* add a cell.  Parameter 2 is 8 hosts (in net order),  parm 3 is the null-terminated
680          * name.  Parameter 4 is the length of the name, including the null.  Parm 5 is the
681          * home cell flag (0x1 bit) and the nosuid flag (0x2 bit) */
682         struct afsop_cell *tcell = afs_osi_Alloc(sizeof(struct afsop_cell));
683
684         code = afs_InitDynroot();
685         if (!code) {
686             AFS_COPYIN((char *)parm2, (char *)tcell->hosts, sizeof(tcell->hosts),
687                        code);
688         }
689         if (!code) {
690             if (parm4 > sizeof(tcell->cellName))
691                 code = EFAULT;
692             else {
693                 AFS_COPYIN((char *)parm3, tcell->cellName, parm4, code);
694                 if (!code)
695                     afs_NewCell(tcell->cellName, tcell->hosts, parm5, NULL, 0,
696                                 0, 0);
697             }
698         }
699         afs_osi_Free(tcell, sizeof(struct afsop_cell));
700     } else if (parm == AFSOP_ADDCELL2) {
701         struct afsop_cell *tcell = afs_osi_Alloc(sizeof(struct afsop_cell));
702         char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ), *lcnamep = 0;
703         char *tbuffer1 = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
704         int cflags = parm4;
705
706         code = afs_InitDynroot();
707         if (!code) {
708 #if 0
709             /* wait for basic init - XXX can't find any reason we need this? */
710             while (afs_initState < AFSOP_START_BKG)
711                 afs_osi_Sleep(&afs_initState);
712 #endif
713
714             AFS_COPYIN((char *)parm2, (char *)tcell->hosts, sizeof(tcell->hosts),
715                        code);
716         }
717         if (!code) {
718             AFS_COPYINSTR((char *)parm3, tbuffer1, AFS_SMALLOCSIZ,
719                           &bufferSize, code);
720             if (!code) {
721                 if (parm4 & 4) {
722                     AFS_COPYINSTR((char *)parm5, tbuffer, AFS_SMALLOCSIZ,
723                                   &bufferSize, code);
724                     if (!code) {
725                         lcnamep = tbuffer;
726                         cflags |= CLinkedCell;
727                     }
728                 }
729                 if (!code)
730                     code =
731                         afs_NewCell(tbuffer1, tcell->hosts, cflags, lcnamep,
732                                     0, 0, 0);
733             }
734         }
735         afs_osi_Free(tcell, sizeof(struct afsop_cell));
736         osi_FreeSmallSpace(tbuffer);
737         osi_FreeSmallSpace(tbuffer1);
738     } else if (parm == AFSOP_ADDCELLALIAS) {
739         /*
740          * Call arguments:
741          * parm2 is the alias name
742          * parm3 is the real cell name
743          */
744         char *aliasName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
745         char *cellName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
746
747         code = afs_InitDynroot();
748         if (!code) {
749             AFS_COPYINSTR((char *)parm2, aliasName, AFS_SMALLOCSIZ, &bufferSize,
750                           code);
751         }
752         if (!code)
753             AFS_COPYINSTR((char *)parm3, cellName, AFS_SMALLOCSIZ,
754                           &bufferSize, code);
755         if (!code)
756             afs_NewCellAlias(aliasName, cellName);
757         osi_FreeSmallSpace(aliasName);
758         osi_FreeSmallSpace(cellName);
759     } else if (parm == AFSOP_SET_THISCELL) {
760         /*
761          * Call arguments:
762          * parm2 is the primary cell name
763          */
764         char *cell = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
765
766         code = afs_InitDynroot();
767         if (!code) {
768             AFS_COPYINSTR((char *)parm2, cell, AFS_SMALLOCSIZ, &bufferSize, code);
769         }
770         if (!code)
771             afs_SetPrimaryCell(cell);
772         osi_FreeSmallSpace(cell);
773     } else if (parm == AFSOP_CACHEINIT) {
774         struct afs_cacheParams cparms;
775
776         if (afs_CacheInit_Done)
777             goto out;
778
779         AFS_COPYIN((char *)parm2, (caddr_t) & cparms, sizeof(cparms), code);
780         if (code) {
781 #if defined(KERNEL_HAVE_UERROR)
782             setuerror(code);
783             code = -1;
784 #endif
785             goto out;
786         }
787         afs_CacheInit_Done = 1;
788         code = afs_icl_InitLogs();
789         afs_setTime = cparms.setTimeFlag;
790
791         code =
792             afs_CacheInit(cparms.cacheScaches, cparms.cacheFiles,
793                           cparms.cacheBlocks, cparms.cacheDcaches,
794                           cparms.cacheVolumes, cparms.chunkSize,
795                           cparms.memCacheFlag, cparms.inodes, cparms.users);
796
797     } else if (parm == AFSOP_CACHEINODE) {
798         ino_t ainode = parm2;
799         /* wait for basic init */
800         while (afs_initState < AFSOP_START_BKG)
801             afs_osi_Sleep(&afs_initState);
802
803 #ifdef AFS_DARWIN80_ENV
804         get_vfs_context();
805 #endif
806         /* do it by inode */
807 #ifdef AFS_SGI62_ENV
808         ainode = (ainode << 32) | (parm3 & 0xffffffff);
809 #endif
810         code = afs_InitCacheFile(NULL, ainode);
811 #ifdef AFS_DARWIN80_ENV
812         put_vfs_context();
813 #endif
814     } else if (parm == AFSOP_CACHEDIRS) {
815         afs_numfilesperdir = parm2;
816         afs_osi_Wakeup(&afs_initState);
817     } else if (parm == AFSOP_CACHEFILES) {
818         afs_numcachefiles = parm2;
819         afs_osi_Wakeup(&afs_initState);
820     } else if (parm == AFSOP_ROOTVOLUME) {
821         /* wait for basic init */
822         while (afs_initState < AFSOP_START_BKG)
823             afs_osi_Sleep(&afs_initState);
824
825         if (parm2) {
826             AFS_COPYINSTR((char *)parm2, afs_rootVolumeName,
827                           sizeof(afs_rootVolumeName), &bufferSize, code);
828             afs_rootVolumeName[sizeof(afs_rootVolumeName) - 1] = 0;
829         } else
830             code = 0;
831     } else if (parm == AFSOP_CACHEFILE || parm == AFSOP_CACHEINFO
832                || parm == AFSOP_VOLUMEINFO || parm == AFSOP_AFSLOG
833                || parm == AFSOP_CELLINFO || parm == AFSOP_CACHEBASEDIR) {
834         char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
835
836         code = 0;
837         AFS_COPYINSTR((char *)parm2, tbuffer, AFS_SMALLOCSIZ, &bufferSize,
838                       code);
839         if (code) {
840             osi_FreeSmallSpace(tbuffer);
841             goto out;
842         }
843         if (!code) {
844             tbuffer[AFS_SMALLOCSIZ - 1] = '\0'; /* null-terminate the name */
845             /* We have the cache dir copied in.  Call the cache init routine */
846 #ifdef AFS_DARWIN80_ENV
847     get_vfs_context();
848 #endif
849             if (parm == AFSOP_CACHEBASEDIR) {
850                 strncpy(afs_cachebasedir, tbuffer, 1024);
851                 afs_cachebasedir[1023] = '\0';
852                 afs_osi_Wakeup(&afs_initState);
853             } else if (parm == AFSOP_CACHEFILE) {
854                 wait_for_cachedefs();
855                 code = afs_InitCacheFile(tbuffer, 0);
856             } else if (parm == AFSOP_CACHEINFO) {
857                 wait_for_cachedefs();
858                 code = afs_InitCacheInfo(tbuffer);
859             } else if (parm == AFSOP_VOLUMEINFO) {
860                 wait_for_cachedefs();
861                 code = afs_InitVolumeInfo(tbuffer);
862             } else if (parm == AFSOP_CELLINFO) {
863                 wait_for_cachedefs();
864                 code = afs_InitCellInfo(tbuffer);
865             }
866 #ifdef AFS_DARWIN80_ENV
867             put_vfs_context();
868 #endif
869         }
870         osi_FreeSmallSpace(tbuffer);
871     } else if (parm == AFSOP_GO) {
872 #ifdef AFS_CACHE_VNODE_PATH
873         if (cacheDiskType != AFS_FCACHE_TYPE_MEM) {
874             afs_int32 dummy;
875             
876             wait_for_cachedefs();
877             
878 #ifdef AFS_DARWIN80_ENV
879             get_vfs_context();
880 #endif
881             if ((afs_numcachefiles > 0) && (afs_numfilesperdir > 0) && 
882                 (afs_cachebasedir[0] == '/')) {
883                 for (dummy = 0; dummy < afs_numcachefiles; dummy++) {
884                     code = afs_InitCacheFile(NULL, dummy);
885                 }
886             }
887 #ifdef AFS_DARWIN80_ENV
888             put_vfs_context();
889 #endif
890         }
891 #endif
892         /* the generic initialization calls come here.  One parameter: should we do the
893          * set-time operation on this workstation */
894         if (afs_Go_Done)
895             goto out;
896         afs_Go_Done = 1;
897         while (afs_initState < AFSOP_GO)
898             afs_osi_Sleep(&afs_initState);
899         afs_initState = 101;
900         afs_setTime = parm2;
901         if (afs_tpct1 + afs_tpct2 != 100) {
902             afs_tpct1 = 0;
903             afs_tpct2 = 0;
904             splitdcache = 0;
905         } else {        
906             splitdcache = 1;
907         }
908         afs_osi_Wakeup(&afs_initState);
909 #if     (!defined(AFS_NONFSTRANS)) || defined(AFS_AIX_IAUTH_ENV)
910         afs_nfsclient_init();
911 #endif
912         afs_uuid_create(&afs_cb_interface.uuid);
913         printf("found %d non-empty cache files (%d%%).\n",
914                afs_stats_cmperf.cacheFilesReused,
915                (100 * afs_stats_cmperf.cacheFilesReused) /
916                (afs_stats_cmperf.cacheNumEntries ? afs_stats_cmperf.
917                 cacheNumEntries : 1));
918     } else if (parm == AFSOP_ADVISEADDR) {
919         /* pass in the host address to the rx package */
920         int rxbind = 0;
921         int refresh = 0;
922
923         afs_int32 count = parm2;
924         afs_int32 *buffer =
925             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
926         afs_int32 *maskbuffer =
927             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
928         afs_int32 *mtubuffer =
929             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
930         int i;
931
932         /* This is a refresh */
933         if (count & 0x40000000) {
934             count &= ~0x40000000;
935             /* Can't bind after we start. Fix? */
936             count &= ~0x80000000;
937             refresh = 1;
938         }
939
940         /* Bind, but only if there's only one address configured */ 
941         if ( count & 0x80000000) {
942             count &= ~0x80000000;
943             if (count == 1)
944                 rxbind=1;
945         }
946
947         if (count > AFS_MAX_INTERFACE_ADDR) {
948             code = ENOMEM;
949             count = AFS_MAX_INTERFACE_ADDR;
950         }
951
952         AFS_COPYIN((char *)parm3, (char *)buffer, count * sizeof(afs_int32),
953                    code);
954         if (parm4)
955             AFS_COPYIN((char *)parm4, (char *)maskbuffer,
956                        count * sizeof(afs_int32), code);
957         if (parm5)
958             AFS_COPYIN((char *)parm5, (char *)mtubuffer,
959                        count * sizeof(afs_int32), code);
960
961         afs_cb_interface.numberOfInterfaces = count;
962         for (i = 0; i < count; i++) {
963             afs_cb_interface.addr_in[i] = buffer[i];
964 #ifdef AFS_USERSPACE_IP_ADDR
965             /* AFS_USERSPACE_IP_ADDR means we have no way of finding the
966              * machines IP addresses when in the kernel (the in_ifaddr
967              * struct is not available), so we pass the info in at
968              * startup. We also pass in the subnetmask and mtu size. The
969              * subnetmask is used when setting the rank:
970              * afsi_SetServerIPRank(); and the mtu size is used when
971              * finding the best mtu size. rxi_FindIfnet() is replaced
972              * with rxi_Findcbi().
973              */
974             afs_cb_interface.subnetmask[i] =
975                 (parm4 ? maskbuffer[i] : 0xffffffff);
976             afs_cb_interface.mtu[i] = (parm5 ? mtubuffer[i] : htonl(1500));
977 #endif
978         }
979         rxi_setaddr(buffer[0]);
980         if (!refresh) {
981             if (rxbind)
982                 rx_bindhost = buffer[0];
983             else
984                 rx_bindhost = htonl(INADDR_ANY);
985         }
986
987         afs_osi_Free(buffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
988         afs_osi_Free(maskbuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
989         afs_osi_Free(mtubuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
990
991         if (refresh) {
992             afs_CheckServers(1, NULL);     /* check down servers */
993             afs_CheckServers(0, NULL);     /* check down servers */
994         }
995     }
996 #ifdef  AFS_SGI53_ENV
997     else if (parm == AFSOP_NFSSTATICADDR) {
998         extern int (*nfs_rfsdisptab_v2) ();
999         nfs_rfsdisptab_v2 = (int (*)())parm2;
1000     } else if (parm == AFSOP_NFSSTATICADDR2) {
1001         extern int (*nfs_rfsdisptab_v2) ();
1002 #ifdef _K64U64
1003         nfs_rfsdisptab_v2 = (int (*)())((parm2 << 32) | (parm3 & 0xffffffff));
1004 #else /* _K64U64 */
1005         nfs_rfsdisptab_v2 = (int (*)())(parm3 & 0xffffffff);
1006 #endif /* _K64U64 */
1007     }
1008 #if defined(AFS_SGI62_ENV) && !defined(AFS_SGI65_ENV)
1009     else if (parm == AFSOP_SBLOCKSTATICADDR2) {
1010         extern int (*afs_sblockp) ();
1011         extern void (*afs_sbunlockp) ();
1012 #ifdef _K64U64
1013         afs_sblockp = (int (*)())((parm2 << 32) | (parm3 & 0xffffffff));
1014         afs_sbunlockp = (void (*)())((parm4 << 32) | (parm5 & 0xffffffff));
1015 #else
1016         afs_sblockp = (int (*)())(parm3 & 0xffffffff);
1017         afs_sbunlockp = (void (*)())(parm5 & 0xffffffff);
1018 #endif /* _K64U64 */
1019     }
1020 #endif /* AFS_SGI62_ENV && !AFS_SGI65_ENV */
1021 #endif /* AFS_SGI53_ENV */
1022     else if (parm == AFSOP_SHUTDOWN) {
1023         afs_cold_shutdown = 0;
1024         if (parm2 == 1)
1025             afs_cold_shutdown = 1;
1026 #ifndef AFS_DARWIN_ENV
1027         if (afs_globalVFS != 0) {
1028             afs_warn("AFS isn't unmounted yet! Call aborted\n");
1029             code = EACCES;
1030         } else
1031 #endif
1032             afs_shutdown();
1033     } else if (parm == AFSOP_AFS_VFSMOUNT) {
1034 #ifdef  AFS_HPUX_ENV
1035         vfsmount(parm2, parm3, parm4, parm5);
1036 #else /* defined(AFS_HPUX_ENV) */
1037 #if defined(KERNEL_HAVE_UERROR)
1038         setuerror(EINVAL);
1039 #else
1040         code = EINVAL;
1041 #endif
1042 #endif /* defined(AFS_HPUX_ENV) */
1043     } else if (parm == AFSOP_CLOSEWAIT) {
1044         afs_SynchronousCloses = 'S';
1045     } else if (parm == AFSOP_GETMTU) {
1046         afs_uint32 mtu = 0;
1047 #if     !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV)
1048 #ifdef AFS_USERSPACE_IP_ADDR
1049         afs_int32 i;
1050         i = rxi_Findcbi(parm2);
1051         mtu = ((i == -1) ? htonl(1500) : afs_cb_interface.mtu[i]);
1052 #else /* AFS_USERSPACE_IP_ADDR */
1053         AFS_IFNET_T tifnp;
1054
1055         tifnp = rxi_FindIfnet(parm2, NULL);     /*  make iterative */
1056         mtu = (tifnp ? ifnet_mtu(tifnp) : htonl(1500));
1057 #endif /* else AFS_USERSPACE_IP_ADDR */
1058 #endif /* !AFS_SUN5_ENV */
1059         if (!code)
1060             AFS_COPYOUT((caddr_t) & mtu, (caddr_t) parm3, sizeof(afs_int32),
1061                         code);
1062 #ifdef AFS_AIX32_ENV
1063 /* this is disabled for now because I can't figure out how to get access
1064  * to these kernel variables.  It's only for supporting user-mode rx
1065  * programs -- it makes a huge difference on the 220's in my testbed,
1066  * though I don't know why. The bosserver does this with /etc/no, so it's
1067  * being handled a different way for the servers right now.  */
1068 /*      {
1069         static adjusted = 0;
1070         extern u_long sb_max_dflt;
1071         if (!adjusted) {
1072           adjusted = 1;
1073           if (sb_max_dflt < 131072) sb_max_dflt = 131072; 
1074           if (sb_max < 131072) sb_max = 131072; 
1075         }
1076       } */
1077 #endif /* AFS_AIX32_ENV */
1078     } else if (parm == AFSOP_GETMASK) { /* parm2 == addr in net order */
1079         afs_uint32 mask = 0;
1080 #if     !defined(AFS_SUN5_ENV)
1081 #ifdef AFS_USERSPACE_IP_ADDR
1082         afs_int32 i;
1083         i = rxi_Findcbi(parm2);
1084         if (i != -1) {
1085             mask = afs_cb_interface.subnetmask[i];
1086         } else {
1087             code = -1;
1088         }
1089 #else /* AFS_USERSPACE_IP_ADDR */
1090         AFS_IFNET_T tifnp;
1091
1092         tifnp = rxi_FindIfnet(parm2, &mask);    /* make iterative */
1093         if (!tifnp)
1094             code = -1;
1095 #endif /* else AFS_USERSPACE_IP_ADDR */
1096 #endif /* !AFS_SUN5_ENV */
1097         if (!code)
1098             AFS_COPYOUT((caddr_t) & mask, (caddr_t) parm3, sizeof(afs_int32),
1099                         code);
1100     }
1101 #ifdef AFS_AFSDB_ENV
1102     else if (parm == AFSOP_AFSDB_HANDLER) {
1103         int sizeArg = (int)parm4;
1104         int kmsgLen = sizeArg & 0xffff;
1105         int cellLen = (sizeArg & 0xffff0000) >> 16;
1106         afs_int32 *kmsg = afs_osi_Alloc(kmsgLen);
1107         char *cellname = afs_osi_Alloc(cellLen);
1108
1109 #ifndef UKERNEL
1110         afs_osi_MaskUserLoop();
1111 #endif
1112         AFS_COPYIN((afs_int32 *) parm2, cellname, cellLen, code);
1113         AFS_COPYIN((afs_int32 *) parm3, kmsg, kmsgLen, code);
1114         if (!code) {
1115             code = afs_AFSDBHandler(cellname, cellLen, kmsg);
1116             if (*cellname == 1)
1117                 *cellname = 0;
1118             if (code == -2) {   /* Shutting down? */
1119                 *cellname = 1;
1120                 code = 0;
1121             }
1122         }
1123         if (!code)
1124             AFS_COPYOUT(cellname, (char *)parm2, cellLen, code);
1125         afs_osi_Free(kmsg, kmsgLen);
1126         afs_osi_Free(cellname, cellLen);
1127     }
1128 #endif
1129     else if (parm == AFSOP_SET_DYNROOT) {
1130         code = afs_SetDynrootEnable(parm2);
1131     } else if (parm == AFSOP_SET_FAKESTAT) {
1132         afs_fakestat_enable = parm2;
1133         code = 0;
1134     } else if (parm == AFSOP_SET_BACKUPTREE) {
1135         afs_bkvolpref = parm2;
1136     } else if (parm == AFSOP_SET_RXPCK) {
1137         rx_extraPackets = parm2;
1138         afscall_set_rxpck_received = 1;
1139     } else
1140         code = EINVAL;
1141
1142   out:
1143     AFS_GUNLOCK();
1144 #ifdef AFS_LINUX20_ENV
1145     return -code;
1146 #else
1147     return code;
1148 #endif
1149 }
1150
1151 /*
1152  * Initstate in the range 0 < x < 100 are early initialization states.
1153  * Initstate of 100 means a AFSOP_START operation has been done.  After this,
1154  *  the cache may be initialized.
1155  * Initstate of 101 means a AFSOP_GO operation has been done.  This operation
1156  *  is done after all the cache initialization has been done.
1157  * Initstate of 200 means that the volume has been looked up once, possibly
1158  *  incorrectly.
1159  * Initstate of 300 means that the volume has been *successfully* looked up.
1160  */
1161 int
1162 afs_CheckInit(void)
1163 {
1164     register int code = 0;
1165
1166     AFS_STATCNT(afs_CheckInit);
1167     if (afs_initState <= 100)
1168         code = ENXIO;           /* never finished init phase */
1169     else if (afs_initState == 101) {    /* init done, wait for afs_daemon */
1170         while (afs_initState < 200)
1171             afs_osi_Sleep(&afs_initState);
1172     } else if (afs_initState == 200)
1173         code = ETIMEDOUT;       /* didn't find root volume */
1174     return code;
1175 }
1176
1177 int afs_shuttingdown = 0;
1178 void
1179 afs_shutdown(void)
1180 {
1181     extern short afs_brsDaemons;
1182     extern afs_int32 afs_CheckServerDaemonStarted;
1183     extern struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
1184     extern struct osi_file *afs_cacheInodep;
1185
1186     AFS_STATCNT(afs_shutdown);
1187     if (afs_initState == 0) {
1188         afs_warn("AFS not initialized - not shutting down\n");
1189       return;
1190     }
1191
1192     if (afs_shuttingdown)
1193         return;
1194     afs_shuttingdown = 1;
1195     if (afs_cold_shutdown)
1196         afs_warn("COLD ");
1197     else
1198         afs_warn("WARM ");
1199     afs_warn("shutting down of: CB... ");
1200
1201     afs_termState = AFSOP_STOP_RXCALLBACK;
1202     rx_WakeupServerProcs();
1203 #ifdef AFS_AIX51_ENV
1204     shutdown_rxkernel();
1205 #endif
1206     /* shutdown_rxkernel(); */
1207     while (afs_termState == AFSOP_STOP_RXCALLBACK)
1208         afs_osi_Sleep(&afs_termState);
1209
1210     afs_warn("afs... ");
1211     while (afs_termState == AFSOP_STOP_AFS) {
1212         afs_osi_CancelWait(&AFS_WaitHandler);
1213         afs_osi_Sleep(&afs_termState);
1214     }
1215     if (afs_CheckServerDaemonStarted) {
1216         while (afs_termState == AFSOP_STOP_CS) {
1217             afs_osi_CancelWait(&AFS_CSWaitHandler);
1218             afs_osi_Sleep(&afs_termState);
1219         }
1220     }
1221     afs_warn("BkG... ");
1222     /* Wake-up afs_brsDaemons so that we don't have to wait for a bkg job! */
1223     while (afs_termState == AFSOP_STOP_BKG) {
1224         afs_osi_Wakeup(&afs_brsDaemons);
1225         afs_osi_Sleep(&afs_termState);
1226     }
1227     afs_warn("CTrunc... ");
1228     /* Cancel cache truncate daemon. */
1229     while (afs_termState == AFSOP_STOP_TRUNCDAEMON) {
1230         afs_osi_Wakeup((char *)&afs_CacheTruncateDaemon);
1231         afs_osi_Sleep(&afs_termState);
1232     }
1233 #ifdef AFS_AFSDB_ENV
1234     afs_warn("AFSDB... ");
1235     afs_StopAFSDB();
1236     while (afs_termState == AFSOP_STOP_AFSDB)
1237         afs_osi_Sleep(&afs_termState);
1238 #endif
1239 #if     defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
1240     afs_warn("RxEvent... ");
1241     /* cancel rx event daemon */
1242     while (afs_termState == AFSOP_STOP_RXEVENT)
1243         afs_osi_Sleep(&afs_termState);
1244 #if defined(RXK_LISTENER_ENV)
1245 #ifndef UKERNEL
1246     afs_warn("UnmaskRxkSignals... ");
1247     afs_osi_UnmaskRxkSignals();
1248 #endif
1249     /* cancel rx listener */
1250     afs_warn("RxListener... ");
1251     osi_StopListener();         /* This closes rx_socket. */
1252     while (afs_termState == AFSOP_STOP_RXK_LISTENER) {
1253         afs_warn("Sleep... ");
1254         afs_osi_Sleep(&afs_termState);
1255     }
1256 #endif
1257 #else
1258     afs_termState = AFSOP_STOP_COMPLETE;
1259 #endif
1260     afs_warn("\n");
1261
1262 #ifdef AFS_AIX51_ENV
1263     shutdown_daemons();
1264 #endif
1265
1266 #ifdef notdef
1267     shutdown_CB();
1268     shutdown_AFS();
1269     shutdown_rxkernel();
1270     shutdown_rxevent();
1271     shutdown_rx();
1272     afs_shutdown_BKG();
1273 #endif
1274     shutdown_bufferpackage();
1275     shutdown_cache();
1276     shutdown_osi();
1277     shutdown_osinet();
1278     shutdown_osifile();
1279     shutdown_vnodeops();
1280     shutdown_memcache();
1281 #if (!defined(AFS_NONFSTRANS) || defined(AFS_AIX_IAUTH_ENV)) && !defined(AFS_OSF_ENV)
1282     shutdown_exporter();
1283     shutdown_nfsclnt();
1284 #endif
1285     shutdown_afstest();
1286     /* The following hold the cm stats */
1287 /*
1288     memset(&afs_cmstats, 0, sizeof(struct afs_CMStats));
1289     memset(&afs_stats_cmperf, 0, sizeof(struct afs_stats_CMPerf));
1290     memset(&afs_stats_cmfullperf, 0, sizeof(struct afs_stats_CMFullPerf));
1291 */
1292     afs_warn(" ALL allocated tables\n");
1293
1294     /* Close file only after daemons which can write to it are stopped. */
1295     if (afs_cacheInodep) {      /* memcache won't set this */
1296         osi_UFSClose(afs_cacheInodep);  /* Since we always leave it open */
1297         afs_cacheInodep = 0;
1298     }
1299
1300     afs_shuttingdown = 0;
1301
1302     return;                     /* Just kill daemons for now */
1303 }
1304
1305 void
1306 shutdown_afstest(void)
1307 {
1308     AFS_STATCNT(shutdown_afstest);
1309     afs_initState = afs_termState = afs_setTime = 0;
1310     AFS_Running = afs_CB_Running = 0;
1311     afs_CacheInit_Done = afs_Go_Done = 0;
1312     if (afs_cold_shutdown) {
1313         *afs_rootVolumeName = 0;
1314     }
1315 }
1316
1317
1318 /* In case there is a bunch of dynamically build bkg daemons to free */
1319 void
1320 afs_shutdown_BKG(void)
1321 {
1322     AFS_STATCNT(shutdown_BKG);
1323 }