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