Commit | Line | Data |
---|---|---|
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 | |
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 | #ifdef AFS_LINUX22_ENV | |
142 | osi_linux_unmaskrxk(); | |
143 | #endif | |
144 | } | |
145 | ||
146 | /* Two hacks to try and fix afsdb */ | |
147 | void | |
148 | afs_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 | ||
158 | void | |
159 | afs_osi_UnmaskUserLoop(void) | |
160 | { | |
161 | #ifdef AFS_DARWIN_ENV | |
162 | afs_osi_fullSigRestore(); | |
163 | #endif | |
164 | } | |
165 | ||
166 | /* register rxk listener proc info */ | |
167 | void | |
168 | afs_osi_RxkRegister(void) | |
169 | { | |
170 | } | |
171 | ||
172 | /* procedure for making our processes as invisible as we can */ | |
173 | void | |
174 | afs_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 | ||
197 | void | |
198 | afs_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 | ||
213 | void | |
214 | shutdown_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 */ | |
235 | void | |
236 | shutdown_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) | |
265 | int | |
266 | afs_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 |