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