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