058120a84a92aa30fd0bd9a2ba34cb24f5974017
[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
14 #include "afs/sysincludes.h"    /* Standard vendor system headers */
15 #include "afsincludes.h"        /* Afs-based standard headers */
16 #include "afs/afs_stats.h"
17 #include "rx/rx_globals.h"
18 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
19 #include "net/if.h"
20 #ifdef AFS_SGI62_ENV
21 #include "h/hashing.h"
22 #endif
23 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
24 #include "netinet/in_var.h"
25 #endif
26 #endif /* !defined(UKERNEL) */
27 #ifdef AFS_LINUX22_ENV
28 #include "h/smp_lock.h"
29 #endif
30 #ifdef AFS_SUN510_ENV
31 #include "h/ksynch.h"
32 #include "h/sunddi.h"
33 #endif
34
35 #if defined(AFS_SUN5_ENV) || defined(AFS_AIX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV)
36 #define AFS_MINBUFFERS  100
37 #else
38 #define AFS_MINBUFFERS  50
39 #endif
40
41 struct afsop_cell {
42     afs_int32 hosts[MAXCELLHOSTS];
43     char cellName[100];
44 };
45
46 char afs_zeros[AFS_ZEROS];
47 char afs_rootVolumeName[64] = "";
48 afs_uint32 rx_bindhost;
49
50 #ifdef AFS_SUN510_ENV
51 ddi_taskq_t *afs_taskq;
52 krwlock_t afsifinfo_lock;
53 #endif
54
55 afs_int32 afs_initState = 0;
56 afs_int32 afs_termState = 0;
57 afs_int32 afs_setTime = 0;
58 int afs_cold_shutdown = 0;
59 char afs_SynchronousCloses = '\0';
60 static int afs_CB_Running = 0;
61 static int AFS_Running = 0;
62 static int afs_CacheInit_Done = 0;
63 static int afs_Go_Done = 0;
64 extern struct interfaceAddr afs_cb_interface;
65 static int afs_RX_Running = 0;
66 static int afs_InitSetup_done = 0;
67 afs_int32 afs_numcachefiles = -1;
68 afs_int32 afs_numfilesperdir = -1;
69 char afs_cachebasedir[1024];
70
71 afs_int32 afs_rx_deadtime = AFS_RXDEADTIME;
72 afs_int32 afs_rx_harddead = AFS_HARDDEADTIME;
73 afs_int32 afs_rx_idledead = AFS_IDLEDEADTIME;
74
75 static int afscall_set_rxpck_received = 0;
76
77 #if defined(AFS_HPUX_ENV)
78 extern int afs_vfs_mount();
79 #endif /* defined(AFS_HPUX_ENV) */
80
81 /* This is code which needs to be called once when the first daemon enters
82  * the client. A non-zero return means an error and AFS should not start.
83  */
84 static int
85 afs_InitSetup(int preallocs)
86 {
87     int code;
88
89     if (afs_InitSetup_done)
90         return EAGAIN;
91
92 #ifdef AFS_SUN510_ENV
93     /* Initialize a RW lock for the ifinfo global array */
94     rw_init(&afsifinfo_lock, NULL, RW_DRIVER, NULL);
95
96     /* Create a taskq */
97     afs_taskq = ddi_taskq_create(NULL, "afs_taskq", 2, TASKQ_DEFAULTPRI, 0);
98
99     osi_StartNetIfPoller();
100 #endif
101
102 #ifndef AFS_NOSTATS
103     /*
104      * Set up all the AFS statistics variables.  This should be done
105      * exactly once, and it should be done here, the first resource-setting
106      * routine to be called by the CM/RX.
107      */
108     afs_InitStats();
109 #endif /* AFS_NOSTATS */
110
111     memset(afs_zeros, 0, AFS_ZEROS);
112
113     /* start RX */
114     if(!afscall_set_rxpck_received)
115     rx_extraPackets = AFS_NRXPACKETS;   /* smaller # of packets */
116     code = rx_InitHost(rx_bindhost, htons(7001));
117     if (code) {
118         printf("AFS: RX failed to initialize %d).\n", code);
119         return code;
120     }
121     rx_SetRxDeadTime(afs_rx_deadtime);
122     /* resource init creates the services */
123     afs_ResourceInit(preallocs);
124
125     afs_InitSetup_done = 1;
126     afs_osi_Wakeup(&afs_InitSetup_done);
127
128     return code;
129 }
130 #if defined(AFS_DARWIN80_ENV)
131 struct afsd_thread_info {
132     unsigned long parm;
133 };
134 static int
135 afsd_thread(int *rock)
136 {
137     struct afsd_thread_info *arg = (struct afsd_thread_info *)rock;
138     unsigned long parm = arg->parm;
139
140     switch (parm) {
141     case AFSOP_START_RXCALLBACK:
142         AFS_GLOCK();
143         wakeup(arg);
144         afs_CB_Running = 1;
145         while (afs_RX_Running != 2)
146             afs_osi_Sleep(&afs_RX_Running);
147         afs_RXCallBackServer();
148         AFS_GUNLOCK();
149         thread_terminate(current_thread());
150         break;
151     case AFSOP_START_AFS:
152         AFS_GLOCK();
153         wakeup(arg);
154         AFS_Running = 1;
155         while (afs_initState < AFSOP_START_AFS)
156             afs_osi_Sleep(&afs_initState);
157         afs_initState = AFSOP_START_BKG;
158         afs_osi_Wakeup(&afs_initState);
159         afs_Daemon();
160         AFS_GUNLOCK();
161         thread_terminate(current_thread());
162         break;
163     case AFSOP_START_BKG:
164         AFS_GLOCK();
165         wakeup(arg);
166         while (afs_initState < AFSOP_START_BKG)
167             afs_osi_Sleep(&afs_initState);
168         if (afs_initState < AFSOP_GO) {
169             afs_initState = AFSOP_GO;
170             afs_osi_Wakeup(&afs_initState);
171         }
172         afs_BackgroundDaemon();
173         AFS_GUNLOCK();
174         thread_terminate(current_thread());
175         break;
176     case AFSOP_START_TRUNCDAEMON:
177         AFS_GLOCK();
178         wakeup(arg);
179         while (afs_initState < AFSOP_GO)
180             afs_osi_Sleep(&afs_initState);
181         afs_CacheTruncateDaemon();
182         AFS_GUNLOCK();
183         thread_terminate(current_thread());
184         break;
185     case AFSOP_START_CS:
186         AFS_GLOCK();
187         wakeup(arg);
188         afs_CheckServerDaemon();
189         AFS_GUNLOCK();
190         thread_terminate(current_thread());
191         break;
192     case AFSOP_RXEVENT_DAEMON:
193         AFS_GLOCK();
194         wakeup(arg);
195         while (afs_initState < AFSOP_START_BKG)
196             afs_osi_Sleep(&afs_initState);
197         afs_rxevent_daemon();
198         AFS_GUNLOCK();
199         thread_terminate(current_thread());
200         break;
201     case AFSOP_RXLISTENER_DAEMON:
202         AFS_GLOCK();
203         wakeup(arg);
204         afs_initState = AFSOP_START_AFS;
205         afs_osi_Wakeup(&afs_initState);
206         afs_RX_Running = 2;
207         afs_osi_Wakeup(&afs_RX_Running);
208         afs_osi_RxkRegister();
209         rxk_Listener();
210         AFS_GUNLOCK();
211         thread_terminate(current_thread());
212         break;
213     default:
214         printf("Unknown op %ld in StartDaemon()\n", (long)parm);
215         break;
216     }
217 }
218
219 void
220 afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5,
221              long parm6)
222 {
223     int code;
224     struct afsd_thread_info info;
225     thread_t thread;
226
227     if (parm == AFSOP_START_RXCALLBACK) {
228         if (afs_CB_Running)
229             return;
230     } else if (parm == AFSOP_RXLISTENER_DAEMON) {
231         if (afs_RX_Running)
232             return;
233         afs_RX_Running = 1;
234         code = afs_InitSetup(parm2);
235         if (parm3) {
236             rx_enablePeerRPCStats();
237         }
238         if (parm4) {
239             rx_enableProcessRPCStats();
240         }
241         if (code)
242             return;
243     } else if (parm == AFSOP_START_AFS) {
244         if (AFS_Running)
245             return;
246     }                           /* other functions don't need setup in the parent */
247     info.parm = parm;
248     kernel_thread_start((thread_continue_t)afsd_thread, &info, &thread);
249     AFS_GUNLOCK();
250     /* we need to wait cause we passed stack pointers around.... */
251     msleep(&info, NULL, PVFS, "afs_DaemonOp", NULL);
252     AFS_GLOCK();
253     thread_deallocate(thread);
254 }
255 #endif
256
257
258 #if defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS)
259 struct afsd_thread_info {
260 #if defined(AFS_LINUX26_ENV) && !defined(INIT_WORK_HAS_DATA)
261     struct work_struct tq;
262 #endif
263     unsigned long parm;
264     struct completion *complete;
265 };
266
267 static int
268 afsd_thread(void *rock)
269 {
270     struct afsd_thread_info *arg = rock;
271     unsigned long parm = arg->parm;
272 #ifdef SYS_SETPRIORITY_EXPORTED
273     int (*sys_setpriority) (int, int, int) = sys_call_table[__NR_setpriority];
274 #endif
275 #if defined(AFS_LINUX26_ENV)
276     daemonize("afsd");
277 #else
278     daemonize();
279 #endif
280                                 /* doesn't do much, since we were forked from keventd, but
281                                  * does call mm_release, which wakes up our parent (since it
282                                  * used CLONE_VFORK) */
283 #if !defined(AFS_LINUX26_ENV)
284     reparent_to_init();
285 #endif
286     afs_osi_MaskSignals();
287     switch (parm) {
288     case AFSOP_START_RXCALLBACK:
289         sprintf(current->comm, "afs_cbstart");
290         AFS_GLOCK();
291         complete(arg->complete);
292         afs_CB_Running = 1;
293         while (afs_RX_Running != 2)
294             afs_osi_Sleep(&afs_RX_Running);
295         sprintf(current->comm, "afs_callback");
296         afs_RXCallBackServer();
297         AFS_GUNLOCK();
298         complete_and_exit(0, 0);
299         break;
300     case AFSOP_START_AFS:
301         sprintf(current->comm, "afs_afsstart");
302         AFS_GLOCK();
303         complete(arg->complete);
304         AFS_Running = 1;
305         while (afs_initState < AFSOP_START_AFS)
306             afs_osi_Sleep(&afs_initState);
307         afs_initState = AFSOP_START_BKG;
308         afs_osi_Wakeup(&afs_initState);
309         sprintf(current->comm, "afsd");
310         afs_Daemon();
311         AFS_GUNLOCK();
312         complete_and_exit(0, 0);
313         break;
314     case AFSOP_START_BKG:
315         sprintf(current->comm, "afs_bkgstart");
316         AFS_GLOCK();
317         complete(arg->complete);
318         while (afs_initState < AFSOP_START_BKG)
319             afs_osi_Sleep(&afs_initState);
320         if (afs_initState < AFSOP_GO) {
321             afs_initState = AFSOP_GO;
322             afs_osi_Wakeup(&afs_initState);
323         }
324         sprintf(current->comm, "afs_background");
325         afs_BackgroundDaemon();
326         AFS_GUNLOCK();
327         complete_and_exit(0, 0);
328         break;
329     case AFSOP_START_TRUNCDAEMON:
330         sprintf(current->comm, "afs_trimstart");
331         AFS_GLOCK();
332         complete(arg->complete);
333         while (afs_initState < AFSOP_GO)
334             afs_osi_Sleep(&afs_initState);
335         sprintf(current->comm, "afs_cachetrim");
336         afs_CacheTruncateDaemon();
337         AFS_GUNLOCK();
338         complete_and_exit(0, 0);
339         break;
340     case AFSOP_START_CS:
341         sprintf(current->comm, "afs_checkserver");
342         AFS_GLOCK();
343         complete(arg->complete);
344         afs_CheckServerDaemon();
345         AFS_GUNLOCK();
346         complete_and_exit(0, 0);
347         break;
348     case AFSOP_RXEVENT_DAEMON:
349         sprintf(current->comm, "afs_evtstart");
350 #ifdef SYS_SETPRIORITY_EXPORTED
351         sys_setpriority(PRIO_PROCESS, 0, -10);
352 #else
353 #ifdef CURRENT_INCLUDES_NICE
354         current->nice = -10;
355 #endif
356 #endif
357         AFS_GLOCK();
358         complete(arg->complete);
359         while (afs_initState < AFSOP_START_BKG)
360             afs_osi_Sleep(&afs_initState);
361         sprintf(current->comm, "afs_rxevent");
362         afs_rxevent_daemon();
363         AFS_GUNLOCK();
364         complete_and_exit(0, 0);
365         break;
366     case AFSOP_RXLISTENER_DAEMON:
367         sprintf(current->comm, "afs_lsnstart");
368 #ifdef SYS_SETPRIORITY_EXPORTED
369         sys_setpriority(PRIO_PROCESS, 0, -10);
370 #else
371 #ifdef CURRENT_INCLUDES_NICE
372         current->nice = -10;
373 #endif
374 #endif
375         AFS_GLOCK();
376         complete(arg->complete);
377         afs_initState = AFSOP_START_AFS;
378         afs_osi_Wakeup(&afs_initState);
379         afs_RX_Running = 2;
380         afs_osi_Wakeup(&afs_RX_Running);
381         afs_osi_RxkRegister();
382         sprintf(current->comm, "afs_rxlistener");
383         rxk_Listener();
384         AFS_GUNLOCK();
385         complete_and_exit(0, 0);
386         break;
387     default:
388         printf("Unknown op %ld in StartDaemon()\n", (long)parm);
389         break;
390     }
391     return 0;
392 }
393
394 void
395 #if defined(AFS_LINUX26_ENV) && !defined(INIT_WORK_HAS_DATA)
396 afsd_launcher(struct work_struct *work)
397 #else
398 afsd_launcher(void *rock)
399 #endif
400 {
401 #if defined(AFS_LINUX26_ENV) && !defined(INIT_WORK_HAS_DATA)
402     struct afsd_thread_info *rock = container_of(work, struct afsd_thread_info, tq);
403 #endif
404
405     if (!kernel_thread(afsd_thread, (void *)rock, CLONE_VFORK | SIGCHLD))
406         printf("kernel_thread failed. afs startup will not complete\n");
407 }
408
409 void
410 afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5,
411              long parm6)
412 {
413     int code;
414     DECLARE_COMPLETION(c);
415 #if defined(AFS_LINUX26_ENV) 
416 #if defined(INIT_WORK_HAS_DATA)
417     struct work_struct tq;
418 #endif
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                           cparms.dynamic_vcaches);
797
798     } else if (parm == AFSOP_CACHEINODE) {
799         ino_t ainode = parm2;
800         /* wait for basic init */
801         while (afs_initState < AFSOP_START_BKG)
802             afs_osi_Sleep(&afs_initState);
803
804 #ifdef AFS_DARWIN80_ENV
805         get_vfs_context();
806 #endif
807         /* do it by inode */
808 #ifdef AFS_SGI62_ENV
809         ainode = (ainode << 32) | (parm3 & 0xffffffff);
810 #endif
811         code = afs_InitCacheFile(NULL, ainode);
812 #ifdef AFS_DARWIN80_ENV
813         put_vfs_context();
814 #endif
815     } else if (parm == AFSOP_CACHEDIRS) {
816         afs_numfilesperdir = parm2;
817         afs_osi_Wakeup(&afs_initState);
818     } else if (parm == AFSOP_CACHEFILES) {
819         afs_numcachefiles = parm2;
820         afs_osi_Wakeup(&afs_initState);
821     } else if (parm == AFSOP_ROOTVOLUME) {
822         /* wait for basic init */
823         while (afs_initState < AFSOP_START_BKG)
824             afs_osi_Sleep(&afs_initState);
825
826         if (parm2) {
827             AFS_COPYINSTR((char *)parm2, afs_rootVolumeName,
828                           sizeof(afs_rootVolumeName), &bufferSize, code);
829             afs_rootVolumeName[sizeof(afs_rootVolumeName) - 1] = 0;
830         } else
831             code = 0;
832     } else if (parm == AFSOP_CACHEFILE || parm == AFSOP_CACHEINFO
833                || parm == AFSOP_VOLUMEINFO || parm == AFSOP_AFSLOG
834                || parm == AFSOP_CELLINFO || parm == AFSOP_CACHEBASEDIR) {
835         char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
836
837         code = 0;
838         AFS_COPYINSTR((char *)parm2, tbuffer, AFS_SMALLOCSIZ, &bufferSize,
839                       code);
840         if (code) {
841             osi_FreeSmallSpace(tbuffer);
842             goto out;
843         }
844         if (!code) {
845             tbuffer[AFS_SMALLOCSIZ - 1] = '\0'; /* null-terminate the name */
846             /* We have the cache dir copied in.  Call the cache init routine */
847 #ifdef AFS_DARWIN80_ENV
848     get_vfs_context();
849 #endif
850             if (parm == AFSOP_CACHEBASEDIR) {
851                 strncpy(afs_cachebasedir, tbuffer, 1024);
852                 afs_cachebasedir[1023] = '\0';
853                 afs_osi_Wakeup(&afs_initState);
854             } else if (parm == AFSOP_CACHEFILE) {
855                 wait_for_cachedefs();
856                 code = afs_InitCacheFile(tbuffer, 0);
857             } else if (parm == AFSOP_CACHEINFO) {
858                 wait_for_cachedefs();
859                 code = afs_InitCacheInfo(tbuffer);
860             } else if (parm == AFSOP_VOLUMEINFO) {
861                 wait_for_cachedefs();
862                 code = afs_InitVolumeInfo(tbuffer);
863             } else if (parm == AFSOP_CELLINFO) {
864                 wait_for_cachedefs();
865                 code = afs_InitCellInfo(tbuffer);
866             }
867 #ifdef AFS_DARWIN80_ENV
868             put_vfs_context();
869 #endif
870         }
871         osi_FreeSmallSpace(tbuffer);
872     } else if (parm == AFSOP_GO) {
873 #ifdef AFS_CACHE_VNODE_PATH
874         if (cacheDiskType != AFS_FCACHE_TYPE_MEM) {
875             afs_int32 dummy;
876             
877             wait_for_cachedefs();
878             
879 #ifdef AFS_DARWIN80_ENV
880             get_vfs_context();
881 #endif
882             if ((afs_numcachefiles > 0) && (afs_numfilesperdir > 0) && 
883                 (afs_cachebasedir[0] == '/')) {
884                 for (dummy = 0; dummy < afs_numcachefiles; dummy++) {
885                     code = afs_InitCacheFile(NULL, dummy);
886                 }
887             }
888 #ifdef AFS_DARWIN80_ENV
889             put_vfs_context();
890 #endif
891         }
892 #endif
893         /* the generic initialization calls come here.  One parameter: should we do the
894          * set-time operation on this workstation */
895         if (afs_Go_Done)
896             goto out;
897         afs_Go_Done = 1;
898         while (afs_initState < AFSOP_GO)
899             afs_osi_Sleep(&afs_initState);
900         afs_initState = 101;
901         afs_setTime = parm2;
902         if (afs_tpct1 + afs_tpct2 != 100) {
903             afs_tpct1 = 0;
904             afs_tpct2 = 0;
905             splitdcache = 0;
906         } else {        
907             splitdcache = 1;
908         }
909         afs_osi_Wakeup(&afs_initState);
910 #if     (!defined(AFS_NONFSTRANS)) || defined(AFS_AIX_IAUTH_ENV)
911         afs_nfsclient_init();
912 #endif
913         afs_uuid_create(&afs_cb_interface.uuid);
914         printf("found %d non-empty cache files (%d%%).\n",
915                afs_stats_cmperf.cacheFilesReused,
916                (100 * afs_stats_cmperf.cacheFilesReused) /
917                (afs_stats_cmperf.cacheNumEntries ? afs_stats_cmperf.
918                 cacheNumEntries : 1));
919     } else if (parm == AFSOP_ADVISEADDR) {
920         /* pass in the host address to the rx package */
921         int rxbind = 0;
922         int refresh = 0;
923
924         afs_int32 count = parm2;
925         afs_int32 *buffer =
926             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
927         afs_int32 *maskbuffer =
928             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
929         afs_int32 *mtubuffer =
930             afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
931         int i;
932
933         /* This is a refresh */
934         if (count & 0x40000000) {
935             count &= ~0x40000000;
936             /* Can't bind after we start. Fix? */
937             count &= ~0x80000000;
938             refresh = 1;
939         }
940
941         /* Bind, but only if there's only one address configured */ 
942         if ( count & 0x80000000) {
943             count &= ~0x80000000;
944             if (count == 1)
945                 rxbind=1;
946         }
947
948         if (count > AFS_MAX_INTERFACE_ADDR) {
949             code = ENOMEM;
950             count = AFS_MAX_INTERFACE_ADDR;
951         }
952
953         AFS_COPYIN((char *)parm3, (char *)buffer, count * sizeof(afs_int32),
954                    code);
955         if (parm4)
956             AFS_COPYIN((char *)parm4, (char *)maskbuffer,
957                        count * sizeof(afs_int32), code);
958         if (parm5)
959             AFS_COPYIN((char *)parm5, (char *)mtubuffer,
960                        count * sizeof(afs_int32), code);
961
962         afs_cb_interface.numberOfInterfaces = count;
963         for (i = 0; i < count; i++) {
964             afs_cb_interface.addr_in[i] = buffer[i];
965 #ifdef AFS_USERSPACE_IP_ADDR
966             /* AFS_USERSPACE_IP_ADDR means we have no way of finding the
967              * machines IP addresses when in the kernel (the in_ifaddr
968              * struct is not available), so we pass the info in at
969              * startup. We also pass in the subnetmask and mtu size. The
970              * subnetmask is used when setting the rank:
971              * afsi_SetServerIPRank(); and the mtu size is used when
972              * finding the best mtu size. rxi_FindIfnet() is replaced
973              * with rxi_Findcbi().
974              */
975             afs_cb_interface.subnetmask[i] =
976                 (parm4 ? maskbuffer[i] : 0xffffffff);
977             afs_cb_interface.mtu[i] = (parm5 ? mtubuffer[i] : htonl(1500));
978 #endif
979         }
980         rxi_setaddr(buffer[0]);
981         if (!refresh) {
982             if (rxbind)
983                 rx_bindhost = buffer[0];
984             else
985                 rx_bindhost = htonl(INADDR_ANY);
986         }
987
988         afs_osi_Free(buffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
989         afs_osi_Free(maskbuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
990         afs_osi_Free(mtubuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
991
992         if (refresh) {
993             afs_CheckServers(1, NULL);     /* check down servers */
994             afs_CheckServers(0, NULL);     /* check down servers */
995         }
996     }
997 #ifdef  AFS_SGI53_ENV
998     else if (parm == AFSOP_NFSSTATICADDR) {
999         extern int (*nfs_rfsdisptab_v2) ();
1000         nfs_rfsdisptab_v2 = (int (*)())parm2;
1001     } else if (parm == AFSOP_NFSSTATICADDR2) {
1002         extern int (*nfs_rfsdisptab_v2) ();
1003 #ifdef _K64U64
1004         nfs_rfsdisptab_v2 = (int (*)())((parm2 << 32) | (parm3 & 0xffffffff));
1005 #else /* _K64U64 */
1006         nfs_rfsdisptab_v2 = (int (*)())(parm3 & 0xffffffff);
1007 #endif /* _K64U64 */
1008     }
1009 #if defined(AFS_SGI62_ENV) && !defined(AFS_SGI65_ENV)
1010     else if (parm == AFSOP_SBLOCKSTATICADDR2) {
1011         extern int (*afs_sblockp) ();
1012         extern void (*afs_sbunlockp) ();
1013 #ifdef _K64U64
1014         afs_sblockp = (int (*)())((parm2 << 32) | (parm3 & 0xffffffff));
1015         afs_sbunlockp = (void (*)())((parm4 << 32) | (parm5 & 0xffffffff));
1016 #else
1017         afs_sblockp = (int (*)())(parm3 & 0xffffffff);
1018         afs_sbunlockp = (void (*)())(parm5 & 0xffffffff);
1019 #endif /* _K64U64 */
1020     }
1021 #endif /* AFS_SGI62_ENV && !AFS_SGI65_ENV */
1022 #endif /* AFS_SGI53_ENV */
1023     else if (parm == AFSOP_SHUTDOWN) {
1024         afs_cold_shutdown = 0;
1025         if (parm2 == 1)
1026             afs_cold_shutdown = 1;
1027 #ifndef AFS_DARWIN_ENV
1028         if (afs_globalVFS != 0) {
1029             afs_warn("AFS isn't unmounted yet! Call aborted\n");
1030             code = EACCES;
1031         } else
1032 #endif
1033             afs_shutdown();
1034     } else if (parm == AFSOP_AFS_VFSMOUNT) {
1035 #ifdef  AFS_HPUX_ENV
1036         vfsmount(parm2, parm3, parm4, parm5);
1037 #else /* defined(AFS_HPUX_ENV) */
1038 #if defined(KERNEL_HAVE_UERROR)
1039         setuerror(EINVAL);
1040 #else
1041         code = EINVAL;
1042 #endif
1043 #endif /* defined(AFS_HPUX_ENV) */
1044     } else if (parm == AFSOP_CLOSEWAIT) {
1045         afs_SynchronousCloses = 'S';
1046     } else if (parm == AFSOP_GETMTU) {
1047         afs_uint32 mtu = 0;
1048 #if     !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV)
1049 #ifdef AFS_USERSPACE_IP_ADDR
1050         afs_int32 i;
1051         i = rxi_Findcbi(parm2);
1052         mtu = ((i == -1) ? htonl(1500) : afs_cb_interface.mtu[i]);
1053 #else /* AFS_USERSPACE_IP_ADDR */
1054         AFS_IFNET_T tifnp;
1055
1056         tifnp = rxi_FindIfnet(parm2, NULL);     /*  make iterative */
1057         mtu = (tifnp ? ifnet_mtu(tifnp) : htonl(1500));
1058 #endif /* else AFS_USERSPACE_IP_ADDR */
1059 #endif /* !AFS_SUN5_ENV */
1060         if (!code)
1061             AFS_COPYOUT((caddr_t) & mtu, (caddr_t) parm3, sizeof(afs_int32),
1062                         code);
1063 #ifdef AFS_AIX32_ENV
1064 /* this is disabled for now because I can't figure out how to get access
1065  * to these kernel variables.  It's only for supporting user-mode rx
1066  * programs -- it makes a huge difference on the 220's in my testbed,
1067  * though I don't know why. The bosserver does this with /etc/no, so it's
1068  * being handled a different way for the servers right now.  */
1069 /*      {
1070         static adjusted = 0;
1071         extern u_long sb_max_dflt;
1072         if (!adjusted) {
1073           adjusted = 1;
1074           if (sb_max_dflt < 131072) sb_max_dflt = 131072; 
1075           if (sb_max < 131072) sb_max = 131072; 
1076         }
1077       } */
1078 #endif /* AFS_AIX32_ENV */
1079     } else if (parm == AFSOP_GETMASK) { /* parm2 == addr in net order */
1080         afs_uint32 mask = 0;
1081 #if     !defined(AFS_SUN5_ENV)
1082 #ifdef AFS_USERSPACE_IP_ADDR
1083         afs_int32 i;
1084         i = rxi_Findcbi(parm2);
1085         if (i != -1) {
1086             mask = afs_cb_interface.subnetmask[i];
1087         } else {
1088             code = -1;
1089         }
1090 #else /* AFS_USERSPACE_IP_ADDR */
1091         AFS_IFNET_T tifnp;
1092
1093         tifnp = rxi_FindIfnet(parm2, &mask);    /* make iterative */
1094         if (!tifnp)
1095             code = -1;
1096 #endif /* else AFS_USERSPACE_IP_ADDR */
1097 #endif /* !AFS_SUN5_ENV */
1098         if (!code)
1099             AFS_COPYOUT((caddr_t) & mask, (caddr_t) parm3, sizeof(afs_int32),
1100                         code);
1101     }
1102 #ifdef AFS_AFSDB_ENV
1103     else if (parm == AFSOP_AFSDB_HANDLER) {
1104         int sizeArg = (int)parm4;
1105         int kmsgLen = sizeArg & 0xffff;
1106         int cellLen = (sizeArg & 0xffff0000) >> 16;
1107         afs_int32 *kmsg = afs_osi_Alloc(kmsgLen);
1108         char *cellname = afs_osi_Alloc(cellLen);
1109
1110 #ifndef UKERNEL
1111         afs_osi_MaskUserLoop();
1112 #endif
1113         AFS_COPYIN((afs_int32 *) parm2, cellname, cellLen, code);
1114         AFS_COPYIN((afs_int32 *) parm3, kmsg, kmsgLen, code);
1115         if (!code) {
1116             code = afs_AFSDBHandler(cellname, cellLen, kmsg);
1117             if (*cellname == 1)
1118                 *cellname = 0;
1119             if (code == -2) {   /* Shutting down? */
1120                 *cellname = 1;
1121                 code = 0;
1122             }
1123         }
1124         if (!code)
1125             AFS_COPYOUT(cellname, (char *)parm2, cellLen, code);
1126         afs_osi_Free(kmsg, kmsgLen);
1127         afs_osi_Free(cellname, cellLen);
1128     }
1129 #endif
1130     else if (parm == AFSOP_SET_DYNROOT) {
1131         code = afs_SetDynrootEnable(parm2);
1132     } else if (parm == AFSOP_SET_FAKESTAT) {
1133         afs_fakestat_enable = parm2;
1134         code = 0;
1135     } else if (parm == AFSOP_SET_BACKUPTREE) {
1136         afs_bkvolpref = parm2;
1137     } else if (parm == AFSOP_SET_RXPCK) {
1138         rx_extraPackets = parm2;
1139         afscall_set_rxpck_received = 1;
1140     } else if (parm == AFSOP_SET_RXMAXMTU) {
1141     rx_MyMaxSendSize = rx_maxReceiveSizeUser = rx_maxReceiveSize = parm2;
1142     } else
1143         code = EINVAL;
1144
1145   out:
1146     AFS_GUNLOCK();
1147 #ifdef AFS_LINUX20_ENV
1148     return -code;
1149 #else
1150     return code;
1151 #endif
1152 }
1153
1154 /*
1155  * Initstate in the range 0 < x < 100 are early initialization states.
1156  * Initstate of 100 means a AFSOP_START operation has been done.  After this,
1157  *  the cache may be initialized.
1158  * Initstate of 101 means a AFSOP_GO operation has been done.  This operation
1159  *  is done after all the cache initialization has been done.
1160  * Initstate of 200 means that the volume has been looked up once, possibly
1161  *  incorrectly.
1162  * Initstate of 300 means that the volume has been *successfully* looked up.
1163  */
1164 int
1165 afs_CheckInit(void)
1166 {
1167     register int code = 0;
1168
1169     AFS_STATCNT(afs_CheckInit);
1170     if (afs_initState <= 100)
1171         code = ENXIO;           /* never finished init phase */
1172     else if (afs_initState == 101) {    /* init done, wait for afs_daemon */
1173         while (afs_initState < 200)
1174             afs_osi_Sleep(&afs_initState);
1175     } else if (afs_initState == 200)
1176         code = ETIMEDOUT;       /* didn't find root volume */
1177     return code;
1178 }
1179
1180 int afs_shuttingdown = 0;
1181 void
1182 afs_shutdown(void)
1183 {
1184     extern short afs_brsDaemons;
1185     extern afs_int32 afs_CheckServerDaemonStarted;
1186     extern struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
1187     extern struct osi_file *afs_cacheInodep;
1188
1189     AFS_STATCNT(afs_shutdown);
1190     if (afs_initState == 0) {
1191         afs_warn("AFS not initialized - not shutting down\n");
1192       return;
1193     }
1194
1195     if (afs_shuttingdown)
1196         return;
1197     afs_shuttingdown = 1;
1198     if (afs_cold_shutdown)
1199         afs_warn("COLD ");
1200     else
1201         afs_warn("WARM ");
1202     afs_warn("shutting down of: CB... ");
1203
1204     afs_termState = AFSOP_STOP_RXCALLBACK;
1205     rx_WakeupServerProcs();
1206 #ifdef AFS_AIX51_ENV
1207     shutdown_rxkernel();
1208 #endif
1209     /* shutdown_rxkernel(); */
1210     while (afs_termState == AFSOP_STOP_RXCALLBACK)
1211         afs_osi_Sleep(&afs_termState);
1212
1213     afs_warn("afs... ");
1214     while (afs_termState == AFSOP_STOP_AFS) {
1215         afs_osi_CancelWait(&AFS_WaitHandler);
1216         afs_osi_Sleep(&afs_termState);
1217     }
1218     if (afs_CheckServerDaemonStarted) {
1219         while (afs_termState == AFSOP_STOP_CS) {
1220             afs_osi_CancelWait(&AFS_CSWaitHandler);
1221             afs_osi_Sleep(&afs_termState);
1222         }
1223     }
1224     afs_warn("BkG... ");
1225     /* Wake-up afs_brsDaemons so that we don't have to wait for a bkg job! */
1226     while (afs_termState == AFSOP_STOP_BKG) {
1227         afs_osi_Wakeup(&afs_brsDaemons);
1228         afs_osi_Sleep(&afs_termState);
1229     }
1230     afs_warn("CTrunc... ");
1231     /* Cancel cache truncate daemon. */
1232     while (afs_termState == AFSOP_STOP_TRUNCDAEMON) {
1233         afs_osi_Wakeup((char *)&afs_CacheTruncateDaemon);
1234         afs_osi_Sleep(&afs_termState);
1235     }
1236 #ifdef AFS_AFSDB_ENV
1237     afs_warn("AFSDB... ");
1238     afs_StopAFSDB();
1239     while (afs_termState == AFSOP_STOP_AFSDB)
1240         afs_osi_Sleep(&afs_termState);
1241 #endif
1242 #if     defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
1243     afs_warn("RxEvent... ");
1244     /* cancel rx event daemon */
1245     while (afs_termState == AFSOP_STOP_RXEVENT)
1246         afs_osi_Sleep(&afs_termState);
1247 #if defined(RXK_LISTENER_ENV)
1248 #ifndef UKERNEL
1249     afs_warn("UnmaskRxkSignals... ");
1250     afs_osi_UnmaskRxkSignals();
1251 #endif
1252     /* cancel rx listener */
1253     afs_warn("RxListener... ");
1254     osi_StopListener();         /* This closes rx_socket. */
1255     while (afs_termState == AFSOP_STOP_RXK_LISTENER) {
1256         afs_warn("Sleep... ");
1257         afs_osi_Sleep(&afs_termState);
1258     }
1259 #endif
1260 #else
1261     afs_termState = AFSOP_STOP_COMPLETE;
1262 #endif
1263     afs_warn("\n");
1264
1265 #ifdef AFS_AIX51_ENV
1266     shutdown_daemons();
1267 #endif
1268
1269 #ifdef notdef
1270     shutdown_CB();
1271     shutdown_AFS();
1272     shutdown_rxkernel();
1273     shutdown_rxevent();
1274     shutdown_rx();
1275     afs_shutdown_BKG();
1276 #endif
1277     shutdown_bufferpackage();
1278     shutdown_cache();
1279     shutdown_osi();
1280     shutdown_osinet();
1281     shutdown_osifile();
1282     shutdown_vnodeops();
1283     shutdown_memcache();
1284 #if (!defined(AFS_NONFSTRANS) || defined(AFS_AIX_IAUTH_ENV)) && !defined(AFS_OSF_ENV)
1285     shutdown_exporter();
1286     shutdown_nfsclnt();
1287 #endif
1288     shutdown_afstest();
1289     /* The following hold the cm stats */
1290 /*
1291     memset(&afs_cmstats, 0, sizeof(struct afs_CMStats));
1292     memset(&afs_stats_cmperf, 0, sizeof(struct afs_stats_CMPerf));
1293     memset(&afs_stats_cmfullperf, 0, sizeof(struct afs_stats_CMFullPerf));
1294 */
1295     afs_warn(" ALL allocated tables\n");
1296
1297     /* Close file only after daemons which can write to it are stopped. */
1298     if (afs_cacheInodep) {      /* memcache won't set this */
1299         osi_UFSClose(afs_cacheInodep);  /* Since we always leave it open */
1300         afs_cacheInodep = 0;
1301     }
1302
1303     afs_shuttingdown = 0;
1304
1305     return;                     /* Just kill daemons for now */
1306 }
1307
1308 void
1309 shutdown_afstest(void)
1310 {
1311     AFS_STATCNT(shutdown_afstest);
1312     afs_initState = afs_termState = afs_setTime = 0;
1313     AFS_Running = afs_CB_Running = 0;
1314     afs_CacheInit_Done = afs_Go_Done = 0;
1315     if (afs_cold_shutdown) {
1316         *afs_rootVolumeName = 0;
1317     }
1318 }
1319
1320
1321 /* In case there is a bunch of dynamically build bkg daemons to free */
1322 void
1323 afs_shutdown_BKG(void)
1324 {
1325     AFS_STATCNT(shutdown_BKG);
1326 }