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