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