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