Linux: Remove unnecessary crhold on incomplete kernel credentials
[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 struct thread *afs_global_owner;
62 #endif
63
64 #if defined(AFS_DARWIN_ENV)
65 thread_t afs_global_owner;
66 #endif /* AFS_DARWIN_ENV */
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 = crdup(osi_curcred());
90 #else
91         memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
92 #if defined(AFS_LINUX26_ENV)
93         afs_set_cr_group_info(&afs_osi_cred, groups_alloc(0));
94 #endif
95 #if defined(AFS_DARWIN80_ENV)
96         afs_osi_cred.cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */
97 #else
98 # if !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_HAS_CRED))
99         crhold(&afs_osi_cred);  /* don't let it evaporate */
100 # endif
101 #endif
102
103         afs_osi_credp = &afs_osi_cred;
104 #endif
105         afs_osicred_initialized = 1;
106     }
107 #ifdef AFS_SGI64_ENV
108     osi_flid.fl_pid = osi_flid.fl_sysid = 0;
109 #endif
110
111     init_et_to_sys_error();
112 }
113
114 /* mask signals in afsds */
115 void
116 afs_osi_MaskSignals(void)
117 {
118 #ifdef AFS_LINUX22_ENV
119     osi_linux_mask();
120 #endif
121 }
122
123 /* unmask signals in rxk listener */
124 void
125 afs_osi_UnmaskRxkSignals(void)
126 {
127 }
128
129 /* Two hacks to try and fix afsdb */
130 void 
131 afs_osi_MaskUserLoop(void)
132 {
133 #ifdef AFS_DARWIN_ENV
134     afs_osi_Invisible();
135     afs_osi_fullSigMask();
136 #else
137     afs_osi_MaskSignals();
138 #endif
139 }
140
141 void 
142 afs_osi_UnmaskUserLoop(void)
143 {
144 #ifdef AFS_DARWIN_ENV
145     afs_osi_fullSigRestore();
146 #endif
147 }
148
149 /* register rxk listener proc info */
150 void
151 afs_osi_RxkRegister(void)
152 {
153 }
154
155 /* procedure for making our processes as invisible as we can */
156 void
157 afs_osi_Invisible(void)
158 {
159 #ifdef AFS_LINUX22_ENV
160     afs_osi_MaskSignals();
161 #elif defined(AFS_SUN5_ENV)
162     curproc->p_flag |= SSYS;
163 #elif defined(AFS_HPUX101_ENV) && !defined(AFS_HPUX1123_ENV)
164     set_system_proc(u.u_procp);
165 #elif defined(AFS_DARWIN80_ENV)
166 #elif defined(AFS_DARWIN_ENV)
167     /* maybe call init_process instead? */
168     current_proc()->p_flag |= P_SYSTEM;
169 #elif defined(AFS_XBSD_ENV)
170     curproc->p_flag |= P_SYSTEM;
171 #elif defined(AFS_SGI_ENV)
172     vrelvm();
173 #endif
174
175     AFS_STATCNT(osi_Invisible);
176 }
177
178 void
179 afs_osi_Visible(void)
180 {
181 #if defined(AFS_SUN5_ENV)
182     curproc->p_flag &= ~SSYS;
183 #elif defined(AFS_DARWIN80_ENV)
184 #elif defined(AFS_DARWIN_ENV)
185     /* maybe call init_process instead? */
186     current_proc()->p_flag &= ~P_SYSTEM;
187 #elif defined(AFS_XBSD_ENV)
188     curproc->p_flag &= ~P_SYSTEM;
189 #endif
190 }
191
192 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV)
193 /* set the real time */
194 void
195 afs_osi_SetTime(osi_timeval_t * atv)
196 {
197 #if defined(AFS_AIX32_ENV)
198     struct timestruc_t t;
199
200     t.tv_sec = atv->tv_sec;
201     t.tv_nsec = atv->tv_usec * 1000;
202     ksettimer(&t);              /*  Was -> settimer(TIMEOFDAY, &t); */
203 #elif defined(AFS_SUN55_ENV)
204     stime(atv->tv_sec);
205 #elif defined(AFS_SUN5_ENV)
206     /*
207      * To get more than second resolution we can use adjtime. The problem
208      * is that the usecs from the server are wrong (by now) so it isn't
209      * worth complicating the following code.
210      */
211     struct stimea {
212         time_t time;
213     } sta;
214
215     sta.time = atv->tv_sec;
216
217     stime(&sta, NULL);
218 #elif defined(AFS_SGI_ENV)
219     struct stimea {
220         sysarg_t time;
221     } sta;
222
223     AFS_GUNLOCK();
224     sta.time = atv->tv_sec;
225     stime(&sta);
226     AFS_GLOCK();
227 #elif defined(AFS_DARWIN_ENV)
228 #ifndef AFS_DARWIN80_ENV
229     AFS_GUNLOCK();
230     setthetime(atv);
231     AFS_GLOCK();
232 #endif
233 #else
234     /* stolen from kern_time.c */
235 #ifndef AFS_AUX_ENV
236     boottime.tv_sec += atv->tv_sec - time.tv_sec;
237 #endif
238 #ifdef AFS_HPUX_ENV
239     {
240 #if !defined(AFS_HPUX1122_ENV)
241         /* drop the setting of the clock for now. spl7 is not
242          * known on hpux11.22
243          */
244         register ulong_t s;
245         struct timeval t;
246         t.tv_sec = atv->tv_sec;
247         t.tv_usec = atv->tv_usec;
248         s = spl7();
249         time = t;
250         (void)splx(s);
251         resettodr(atv);
252 #endif
253     }
254 #else
255     {
256         register int s;
257         s = splclock();
258         time = *atv;
259         (void)splx(s);
260     }
261     resettodr();
262 #endif
263 #ifdef  AFS_AUX_ENV
264     logtchg(atv->tv_sec);
265 #endif
266 #endif /* AFS_DARWIN_ENV */
267     AFS_STATCNT(osi_SetTime);
268 }
269 #endif /* AFS_LINUX20_ENV */
270
271
272 void
273 shutdown_osi(void)
274 {
275     AFS_STATCNT(shutdown_osi);
276 #ifdef AFS_DARWIN80_ENV
277     if (afs_osi_ctxtp_initialized && afs_osi_ctxtp) {
278        vfs_context_rele(afs_osi_ctxtp);
279        afs_osi_ctxtp = NULL;
280        afs_osi_ctxtp_initialized = 0;
281     }
282     shutdown_osisleep();
283 #endif
284     if (afs_cold_shutdown) {
285         LOCK_INIT(&afs_ftf, "afs_ftf");
286     }
287 }
288
289 #ifndef AFS_OBSD_ENV
290 int
291 afs_osi_suser(void *cr)
292 {
293 #if defined(AFS_SUN510_ENV)
294     return (priv_policy(cr, PRIV_SYS_SUSER_COMPAT, B_FALSE, EPERM, NULL) == 0);
295 #elif defined(AFS_SUN5_ENV)
296     return afs_suser(cr);
297 #else
298     return afs_suser(NULL);
299 #endif
300 }
301 #endif