Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / afs_osi.c
CommitLineData
805e021f
CE
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
29extern void init_hckernel_mutex(void);
30#endif
31
32afs_lock_t afs_ftf; /* flush text lock */
33
34#ifdef AFS_SGI53_ENV
35lock_t afs_event_lock;
36#endif
37
38#ifdef AFS_SGI64_ENV
39flid_t osi_flid;
40#endif
41
42afs_ucred_t *afs_osi_credp;
43
44#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
45kmutex_t afs_global_lock;
46#endif
47
48#if defined(AFS_SGI_ENV) && !defined(AFS_SGI64_ENV)
49long afs_global_owner;
50#endif
51
52#if defined(AFS_DARWIN_ENV)
53thread_t afs_global_owner;
54#ifdef AFS_DARWIN80_ENV
55lck_mtx_t *afs_global_lock;
56#else
57struct 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)
63kmutex_t afs_global_mtx;
64# else
65struct lock afs_global_lock;
66afs_proc_t *afs_global_owner;
67# endif
68#elif defined(AFS_FBSD_ENV)
69struct mtx afs_global_mtx;
70struct thread *afs_global_owner;
71#endif
72
73#if defined(AFS_AIX41_ENV)
74simple_lock_data afs_global_lock;
75#endif
76
77void
78osi_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 */
129void
130afs_osi_MaskSignals(void)
131{
132#ifdef AFS_LINUX22_ENV
133 osi_linux_mask();
134#endif
135}
136
137/* unmask signals in rxk listener */
138void
139afs_osi_UnmaskRxkSignals(void)
140{
141#ifdef AFS_LINUX22_ENV
142 osi_linux_unmaskrxk();
143#endif
144}
145
146/* Two hacks to try and fix afsdb */
147void
148afs_osi_MaskUserLoop(void)
149{
150#ifdef AFS_DARWIN_ENV
151 afs_osi_Invisible();
152 afs_osi_fullSigMask();
153#else
154 afs_osi_MaskSignals();
155#endif
156}
157
158void
159afs_osi_UnmaskUserLoop(void)
160{
161#ifdef AFS_DARWIN_ENV
162 afs_osi_fullSigRestore();
163#endif
164}
165
166/* register rxk listener proc info */
167void
168afs_osi_RxkRegister(void)
169{
170}
171
172/* procedure for making our processes as invisible as we can */
173void
174afs_osi_Invisible(void)
175{
176#ifdef AFS_LINUX22_ENV
177 afs_osi_MaskSignals();
178#elif defined(AFS_SUN5_ENV)
179 curproc->p_flag |= SSYS;
180#elif defined(AFS_HPUX101_ENV) && !defined(AFS_HPUX1123_ENV)
181 set_system_proc(u.u_procp);
182#elif defined(AFS_DARWIN80_ENV)
183#elif defined(AFS_DARWIN_ENV)
184 /* maybe call init_process instead? */
185 current_proc()->p_flag |= P_SYSTEM;
186#elif defined(AFS_NBSD50_ENV)
187 /* XXX in netbsd a system thread is more than invisible */
188#elif defined(AFS_XBSD_ENV)
189 curproc->p_flag |= P_SYSTEM;
190#elif defined(AFS_SGI_ENV)
191 vrelvm();
192#endif
193
194 AFS_STATCNT(osi_Invisible);
195}
196
197void
198afs_osi_Visible(void)
199{
200#if defined(AFS_SUN5_ENV)
201 curproc->p_flag &= ~SSYS;
202#elif defined(AFS_DARWIN80_ENV)
203#elif defined(AFS_DARWIN_ENV)
204 /* maybe call init_process instead? */
205 current_proc()->p_flag &= ~P_SYSTEM;
206#elif defined(AFS_NBSD50_ENV)
207 /* XXX in netbsd a system thread is more than invisible */
208#elif defined(AFS_XBSD_ENV)
209 curproc->p_flag &= ~P_SYSTEM;
210#endif
211}
212
213void
214shutdown_osi(void)
215{
216 AFS_STATCNT(shutdown_osi);
217#ifdef AFS_DARWIN80_ENV
218 if (afs_osi_ctxtp_initialized && afs_osi_ctxtp) {
219 vfs_context_rele(afs_osi_ctxtp);
220 afs_osi_ctxtp = NULL;
221 afs_osi_ctxtp_initialized = 0;
222 }
223#endif
224#if !defined(AFS_HPUX_ENV) && !defined(UKERNEL) && !defined(AFS_DFBSD_ENV) && !defined(AFS_LINUX26_ENV)
225 /* LINUX calls this from afs_cleanup() which hooks into module_exit */
226 shutdown_osisleep();
227#endif
228 if (afs_cold_shutdown) {
229 LOCK_INIT(&afs_ftf, "afs_ftf");
230 }
231}
232
233#if !defined(AFS_HPUX_ENV) && !defined(UKERNEL) && !defined(AFS_DFBSD_ENV) && !defined(AFS_DARWIN_ENV)
234/* DARWIN uses locking, and so must provide its own */
235void
236shutdown_osisleep(void)
237{
238 afs_event_t *tmp;
239 int i;
240
241 for (i=0;i<AFS_EVHASHSIZE;i++) {
242 while ((tmp = afs_evhasht[i]) != NULL) {
243 afs_evhasht[i] = tmp->next;
244 if (tmp->refcount > 0) {
245 afs_warn("nonzero refcount in shutdown_osisleep()\n");
246 } else {
247#if defined(AFS_AIX_ENV)
248 xmfree(tmp);
249#elif defined(AFS_FBSD_ENV)
250 afs_osi_Free(tmp, sizeof(*tmp));
251#elif defined(AFS_SGI_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_SUN5_ENV)
252 osi_FreeSmallSpace(tmp);
253#elif defined(AFS_LINUX26_ENV)
254 kfree(tmp);
255#elif defined(AFS_LINUX20_ENV)
256 osi_linux_free(tmp);
257#endif
258 }
259 }
260 }
261}
262#endif
263
264#if !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD40_ENV)
265int
266afs_osi_suser(void *cr)
267{
268#if defined(AFS_SUN510_ENV)
269 return (priv_policy(cr, PRIV_SYS_SUSER_COMPAT, B_FALSE, EPERM, NULL) == 0);
270#elif defined(AFS_SUN5_ENV)
271 return afs_suser(cr);
272#else
273 return afs_suser(NULL);
274#endif
275}
276#endif