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