3eb176b8e401318266327df47d95dc8d7d81ce65
[openafs.git] / src / afs / afs_osi.c
1 /*
2  * Copyrigh 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"      /* afs statistics */
17 #ifdef AFS_AIX_ENV
18 #include <sys/adspace.h>        /* for vm_att(), vm_det() */
19 #endif
20
21 /* osi_Init -- do once per kernel installation initialization.
22  *     -- On Solaris this is called from modload initialization.
23  *     -- On AIX called from afs_config.
24  *     -- On HP called from afsc_link.
25  *     -- On SGI called from afs_init. */
26
27 afs_lock_t afs_ftf;             /* flush text lock */
28
29 #ifdef AFS_SGI53_ENV
30 lock_t afs_event_lock;
31 #endif
32
33 #ifdef AFS_SGI64_ENV
34 flid_t osi_flid;
35 #endif
36
37 afs_ucred_t *afs_osi_credp;
38
39 #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
40 kmutex_t afs_global_lock;
41 #endif
42
43 #if defined(AFS_SGI_ENV) && !defined(AFS_SGI64_ENV)
44 long afs_global_owner;
45 #endif
46
47 #if defined(AFS_DARWIN_ENV)
48 thread_t afs_global_owner;
49 #ifdef AFS_DARWIN80_ENV
50 lck_mtx_t  *afs_global_lock;
51 #else
52 struct lock__bsd__ afs_global_lock;
53 #endif
54 #endif
55
56 #if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD_ENV)
57 # if defined(AFS_NBSD50_ENV)
58 kmutex_t afs_global_mtx;
59 # else
60 struct lock afs_global_lock;
61 afs_proc_t *afs_global_owner;
62 # endif
63 #elif defined(AFS_FBSD_ENV)
64 struct mtx afs_global_mtx;
65 struct thread *afs_global_owner;
66 #endif
67
68 #if defined(AFS_AIX41_ENV)
69 simple_lock_data afs_global_lock;
70 #endif
71
72 void
73 osi_Init(void)
74 {
75     static int once = 0;
76     if (once++ > 0)             /* just in case */
77         return;
78
79     osi_InitGlock();
80
81     if (!afs_osicred_initialized) {
82 #if defined(AFS_DARWIN80_ENV)
83         afs_osi_ctxtp_initialized = 0;
84         afs_osi_ctxtp = NULL; /* initialized in afs_Daemon since it has
85                                   a proc reference that cannot be changed */
86 #endif
87 #if defined(AFS_XBSD_ENV)
88         /* Can't just invent one, must use crget() because of mutex */
89         afs_osi_credp =
90           crdup(osi_curcred());
91 #elif defined(AFS_SUN5_ENV)
92         afs_osi_credp = kcred;
93 #else
94         memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
95 #if defined(AFS_LINUX26_ENV)
96         afs_set_cr_group_info(&afs_osi_cred, groups_alloc(0));
97 #endif
98 #if defined(AFS_DARWIN80_ENV)
99         afs_osi_cred.cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */
100 #else
101 # if !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
102         crhold(&afs_osi_cred);  /* don't let it evaporate */
103 # endif
104 #endif
105
106         afs_osi_credp = &afs_osi_cred;
107 #endif
108         afs_osicred_initialized = 1;
109     }
110 #ifdef AFS_SGI64_ENV
111     osi_flid.fl_pid = osi_flid.fl_sysid = 0;
112 #endif
113
114     init_et_to_sys_error();
115 }
116
117 /* mask signals in afsds */
118 void
119 afs_osi_MaskSignals(void)
120 {
121 #ifdef AFS_LINUX22_ENV
122     osi_linux_mask();
123 #endif
124 }
125
126 /* unmask signals in rxk listener */
127 void
128 afs_osi_UnmaskRxkSignals(void)
129 {
130 }
131
132 /* Two hacks to try and fix afsdb */
133 void
134 afs_osi_MaskUserLoop(void)
135 {
136 #ifdef AFS_DARWIN_ENV
137     afs_osi_Invisible();
138     afs_osi_fullSigMask();
139 #else
140     afs_osi_MaskSignals();
141 #endif
142 }
143
144 void
145 afs_osi_UnmaskUserLoop(void)
146 {
147 #ifdef AFS_DARWIN_ENV
148     afs_osi_fullSigRestore();
149 #endif
150 }
151
152 /* register rxk listener proc info */
153 void
154 afs_osi_RxkRegister(void)
155 {
156 }
157
158 /* procedure for making our processes as invisible as we can */
159 void
160 afs_osi_Invisible(void)
161 {
162 #ifdef AFS_LINUX22_ENV
163     afs_osi_MaskSignals();
164 #elif defined(AFS_SUN5_ENV)
165     curproc->p_flag |= SSYS;
166 #elif defined(AFS_HPUX101_ENV) && !defined(AFS_HPUX1123_ENV)
167     set_system_proc(u.u_procp);
168 #elif defined(AFS_DARWIN80_ENV)
169 #elif defined(AFS_DARWIN_ENV)
170     /* maybe call init_process instead? */
171     current_proc()->p_flag |= P_SYSTEM;
172 #elif defined(AFS_NBSD50_ENV)
173     /* XXX in netbsd a system thread is more than invisible */
174 #elif defined(AFS_XBSD_ENV)
175     curproc->p_flag |= P_SYSTEM;
176 #elif defined(AFS_SGI_ENV)
177     vrelvm();
178 #endif
179
180     AFS_STATCNT(osi_Invisible);
181 }
182
183 void
184 afs_osi_Visible(void)
185 {
186 #if defined(AFS_SUN5_ENV)
187     curproc->p_flag &= ~SSYS;
188 #elif defined(AFS_DARWIN80_ENV)
189 #elif defined(AFS_DARWIN_ENV)
190     /* maybe call init_process instead? */
191     current_proc()->p_flag &= ~P_SYSTEM;
192 #elif defined(AFS_NBSD50_ENV)
193     /* XXX in netbsd a system thread is more than invisible */
194 #elif defined(AFS_XBSD_ENV)
195     curproc->p_flag &= ~P_SYSTEM;
196 #endif
197 }
198
199 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV)
200 /* set the real time */
201 void
202 afs_osi_SetTime(osi_timeval_t * atv)
203 {
204 #if defined(AFS_AIX32_ENV)
205     struct timestruc_t t;
206
207     t.tv_sec = atv->tv_sec;
208     t.tv_nsec = atv->tv_usec * 1000;
209     ksettimer(&t);              /*  Was -> settimer(TIMEOFDAY, &t); */
210 #elif defined(AFS_SUN5_ENV)
211     stime(atv->tv_sec);
212 #elif defined(AFS_SGI_ENV)
213     struct stimea {
214         sysarg_t time;
215     } sta;
216
217     AFS_GUNLOCK();
218     sta.time = atv->tv_sec;
219     stime(&sta);
220     AFS_GLOCK();
221 #elif defined(AFS_DARWIN_ENV)
222 #ifndef AFS_DARWIN80_ENV
223     AFS_GUNLOCK();
224     setthetime(atv);
225     AFS_GLOCK();
226 #endif
227 #else
228     /* stolen from kern_time.c */
229 #ifndef AFS_AUX_ENV
230     boottime.tv_sec += atv->tv_sec - time.tv_sec;
231 #endif
232 #ifdef AFS_HPUX_ENV
233     {
234 #if !defined(AFS_HPUX1122_ENV)
235         /* drop the setting of the clock for now. spl7 is not
236          * known on hpux11.22
237          */
238         ulong_t s;
239         struct timeval t;
240         t.tv_sec = atv->tv_sec;
241         t.tv_usec = atv->tv_usec;
242         s = spl7();
243         time = t;
244         (void)splx(s);
245         resettodr(atv);
246 #endif
247     }
248 #else
249     {
250         int s;
251         s = splclock();
252         time = *atv;
253         (void)splx(s);
254     }
255     resettodr();
256 #endif
257 #ifdef  AFS_AUX_ENV
258     logtchg(atv->tv_sec);
259 #endif
260 #endif /* AFS_DARWIN_ENV */
261     AFS_STATCNT(osi_SetTime);
262 }
263 #endif /* AFS_LINUX20_ENV */
264
265
266 void
267 shutdown_osi(void)
268 {
269     AFS_STATCNT(shutdown_osi);
270 #ifdef AFS_DARWIN80_ENV
271     if (afs_osi_ctxtp_initialized && afs_osi_ctxtp) {
272        vfs_context_rele(afs_osi_ctxtp);
273        afs_osi_ctxtp = NULL;
274        afs_osi_ctxtp_initialized = 0;
275     }
276 #endif
277 #if !defined(AFS_HPUX_ENV) && !defined(UKERNEL) && !defined(AFS_DFBSD_ENV) && !defined(AFS_LINUX26_ENV)
278     /* LINUX calls this from afs_cleanup() which hooks into module_exit */
279     shutdown_osisleep();
280 #endif
281     if (afs_cold_shutdown) {
282         LOCK_INIT(&afs_ftf, "afs_ftf");
283     }
284 }
285
286 #if !defined(AFS_HPUX_ENV) && !defined(UKERNEL) && !defined(AFS_DFBSD_ENV) && !defined(AFS_DARWIN_ENV)
287 /* DARWIN uses locking, and so must provide its own */
288 void
289 shutdown_osisleep(void)
290 {
291     afs_event_t *tmp;
292     int i;
293
294     for (i=0;i<AFS_EVHASHSIZE;i++) {
295         while ((tmp = afs_evhasht[i]) != NULL) {
296             afs_evhasht[i] = tmp->next;
297             if (tmp->refcount > 0) {
298                 afs_warn("nonzero refcount in shutdown_osisleep()\n");
299             } else {
300 #if defined(AFS_AIX_ENV)
301                 xmfree(tmp);
302 #elif defined(AFS_FBSD_ENV)
303                 afs_osi_Free(tmp, sizeof(*tmp));
304 #elif defined(AFS_SGI_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_SUN5_ENV)
305                 osi_FreeSmallSpace(tmp);
306 #elif defined(AFS_LINUX26_ENV)
307                 kfree(tmp);
308 #elif defined(AFS_LINUX20_ENV)
309                 osi_linux_free(tmp);
310 #endif
311             }
312         }
313     }
314 }
315 #endif
316
317 #if !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD40_ENV)
318 int
319 afs_osi_suser(void *cr)
320 {
321 #if defined(AFS_SUN510_ENV)
322     return (priv_policy(cr, PRIV_SYS_SUSER_COMPAT, B_FALSE, EPERM, NULL) == 0);
323 #elif defined(AFS_SUN5_ENV)
324     return afs_suser(cr);
325 #else
326     return afs_suser(NULL);
327 #endif
328 }
329 #endif