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