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