1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/param.h>
28 #include <sys/sysmacros.h>
29 #include <sys/bitmap.h>
30 #include <sys/var.h>
31 #include <sys/thread.h>
32 #include <sys/proc.h>
33 #include <sys/brand.h>
34 #include <sys/zone.h>
35 #include <sys/lx_brand.h>
36 #include <sys/lx_pid.h>
37
38 #define LINUX_PROC_FACTOR 8 /* factor down the hash table by this */
39 static int hash_len = 4; /* desired average hash chain length */
40 static int hash_size; /* no of buckets in the hash table */
41
42 static struct lx_pid **stol_pid_hash;
43 static struct lx_pid **ltos_pid_hash;
44
45 #define LTOS_HASH(pid) ((pid) & (hash_size - 1))
46 #define STOL_HASH(pid, tid) (((pid) + (tid)) & (hash_size - 1))
47
48 static kmutex_t hash_lock;
49
50 static void
51 lx_pid_insert_hash(struct lx_pid *lpidp)
52 {
53 int shash = STOL_HASH(lpidp->s_pid, lpidp->s_tid);
54 int lhash = LTOS_HASH(lpidp->l_pid);
55
56 ASSERT(MUTEX_HELD(&hash_lock));
57
58 lpidp->stol_next = stol_pid_hash[shash];
59 stol_pid_hash[shash] = lpidp;
60
61 lpidp->ltos_next = ltos_pid_hash[lhash];
62 ltos_pid_hash[lhash] = lpidp;
63 }
64
65 static struct lx_pid *
66 lx_pid_remove_hash(pid_t pid, id_t tid)
67 {
68 struct lx_pid **hpp;
69 struct lx_pid *lpidp = NULL;
70
71 ASSERT(MUTEX_HELD(&hash_lock));
72
73 hpp = &stol_pid_hash[STOL_HASH(pid, tid)];
74 while (*hpp) {
75 if ((*hpp)->s_pid == pid && (*hpp)->s_tid == tid) {
76 lpidp = *hpp;
77 *hpp = (*hpp)->stol_next;
78 break;
79 }
80 hpp = &(*hpp)->stol_next;
81 }
82
83 /*
84 * when called during error recovery the pid may already
85 * be released
86 */
87 if (lpidp == NULL)
88 return (NULL);
89
90 hpp = <os_pid_hash[LTOS_HASH(lpidp->l_pid)];
91 while (*hpp) {
92 if (*hpp == lpidp) {
93 *hpp = lpidp->ltos_next;
94 break;
95 }
96 hpp = &(*hpp)->ltos_next;
97 }
98
99 return (lpidp);
100 }
101
102 struct pid * pid_find(pid_t pid);
103
104 /*
105 * given a solaris pid/tid pair, create a linux pid
106 */
107 int
108 lx_pid_assign(kthread_t *t)
109 {
110 proc_t *p = ttoproc(t);
111 pid_t s_pid = p->p_pid;
112 id_t s_tid = t->t_tid;
113 struct pid *pidp;
114 struct lx_pid *lpidp;
115 lx_lwp_data_t *lwpd = ttolxlwp(t);
116 pid_t newpid;
117
118 if (p->p_lwpcnt > 0) {
119 /*
120 * Allocate a pid for any thread other than the first
121 */
122 if ((newpid = pid_allocate(p, 0, 0)) < 0)
123 return (-1);
124
125 pidp = pid_find(newpid);
126 } else {
127 pidp = NULL;
128 newpid = s_pid;
129 }
130
131 lpidp = kmem_alloc(sizeof (struct lx_pid), KM_SLEEP);
132 lpidp->l_pid = newpid;
133 lpidp->s_pid = s_pid;
134 lpidp->s_tid = s_tid;
135 lpidp->l_pidp = pidp;
136 lpidp->l_start = t->t_start;
137
138 /*
139 * now put the pid into the linux-solaris and solaris-linux
140 * conversion hash tables
141 */
142 mutex_enter(&hash_lock);
143 lx_pid_insert_hash(lpidp);
144 mutex_exit(&hash_lock);
145
146 lwpd->br_pid = newpid;
147
148 return (0);
149 }
150
151 /*
152 * If we are exec()ing the process, this thread's tid is about to be reset
153 * to 1. Make sure the Linux PID bookkeeping reflects that change.
154 */
155 void
156 lx_pid_reassign(kthread_t *t)
157 {
158 proc_t *p = ttoproc(t);
159 struct pid *old_pidp;
160 struct lx_pid *lpidp;
161
162 ASSERT(p->p_lwpcnt == 1);
163
164 mutex_enter(&hash_lock);
165
166 /*
167 * Clean up all the traces of this thread's 'fake' Linux PID.
168 */
169 lpidp = lx_pid_remove_hash(p->p_pid, t->t_tid);
170 ASSERT(lpidp != NULL);
171 old_pidp = lpidp->l_pidp;
172 lpidp->l_pidp = NULL;
173
174 /*
175 * Now register this thread as (pid, 1).
176 */
177 lpidp->l_pid = p->p_pid;
178 lpidp->s_pid = p->p_pid;
179 lpidp->s_tid = 1;
180 lx_pid_insert_hash(lpidp);
181
182 mutex_exit(&hash_lock);
183
184 if (old_pidp)
185 (void) pid_rele(old_pidp);
186 }
187
188 /*
189 * release a solaris pid/tid pair
190 */
191 void
192 lx_pid_rele(pid_t pid, id_t tid)
193 {
194 struct lx_pid *lpidp;
195
196 mutex_enter(&hash_lock);
197 lpidp = lx_pid_remove_hash(pid, tid);
198 mutex_exit(&hash_lock);
199
200 if (lpidp) {
201 if (lpidp->l_pidp)
202 (void) pid_rele(lpidp->l_pidp);
203
204 kmem_free(lpidp, sizeof (*lpidp));
205 }
206 }
207
208 /*
209 * given a linux pid, return the solaris pid/tid pair
210 */
211 int
212 lx_lpid_to_spair(pid_t l_pid, pid_t *s_pid, id_t *s_tid)
213 {
214 struct lx_pid *hp;
215
216 mutex_enter(&hash_lock);
217 for (hp = ltos_pid_hash[LTOS_HASH(l_pid)]; hp; hp = hp->ltos_next) {
218 if (l_pid == hp->l_pid) {
219 if (s_pid)
220 *s_pid = hp->s_pid;
221 if (s_tid)
222 *s_tid = hp->s_tid;
223 break;
224 }
225 }
226 mutex_exit(&hash_lock);
227 if (hp != NULL)
228 return (0);
229
230 /*
231 * We didn't find this pid in our translation table.
232 * But this still could be the pid of a native process
233 * running in the current zone so check for that here.
234 *
235 * Note that prfind() only searches for processes in the current zone.
236 */
237 mutex_enter(&pidlock);
238 if (prfind(l_pid) != NULL) {
239 mutex_exit(&pidlock);
240 if (s_pid)
241 *s_pid = l_pid;
242 if (s_tid)
243 *s_tid = 0;
244 return (0);
245 }
246 mutex_exit(&pidlock);
247
248 return (-1);
249 }
250
251 /*
252 * Given an lwp, return the Linux pid of its parent. If the caller
253 * wants them, we return the Solaris (pid, tid) as well.
254 */
255 pid_t
256 lx_lwp_ppid(klwp_t *lwp, pid_t *ppidp, id_t *ptidp)
257 {
258 lx_lwp_data_t *lwpd = lwptolxlwp(lwp);
259 proc_t *p = lwptoproc(lwp);
260 struct lx_pid *hp;
261 pid_t zoneinit = curproc->p_zone->zone_proc_initpid;
262 pid_t lppid, ppid;
263
264 /*
265 * Be sure not to return a parent pid that should be invisible
266 * within this zone.
267 */
268 ppid = ((p->p_flag & SZONETOP)
269 ? curproc->p_zone->zone_zsched->p_pid : p->p_ppid);
270
271 /*
272 * If the parent process's pid is the zone's init process, force it
273 * to the Linux init pid value of 1.
274 */
275 if (ppid == zoneinit)
276 ppid = 1;
277
278 /*
279 * There are two cases in which the Linux definition of a 'parent'
280 * matches that of Solaris:
281 *
282 * - if our tgid is the same as our PID, then we are either the
283 * first thread in the process or a CLONE_THREAD thread.
284 *
285 * - if the brand lwp value for ppid is 0, then we are either the
286 * child of a differently-branded process or a CLONE_PARENT thread.
287 */
288 if (p->p_pid == lwpd->br_tgid || lwpd->br_ppid == 0) {
289 if (ppidp != NULL)
290 *ppidp = ppid;
291 if (ptidp != NULL)
292 *ptidp = -1;
293 return (ppid);
294 }
295
296 /*
297 * Set the default Linux parent pid to be the pid of the zone's init
298 * process; this will get converted back to the Linux default of 1
299 * later.
300 */
301 lppid = zoneinit;
302
303 /*
304 * If the process's parent isn't init, try and look up the Linux "pid"
305 * corresponding to the process's parent.
306 */
307 if (ppid != 1) {
308 /*
309 * In all other cases, we are looking for the parent of this
310 * specific thread, which in Linux refers to the thread that
311 * clone()d it. We stashed that thread's PID away when this
312 * thread was created.
313 */
314 mutex_enter(&hash_lock);
315 for (hp = ltos_pid_hash[LTOS_HASH(lwpd->br_ppid)]; hp;
316 hp = hp->ltos_next) {
317 if (lwpd->br_ppid == hp->l_pid) {
318 /*
319 * We found the PID we were looking for, but
320 * since we cached its value in this LWP's brand
321 * structure, it has exited and been reused by
322 * another process.
323 */
324 if (hp->l_start > lwptot(lwp)->t_start)
325 break;
326
327 lppid = lwpd->br_ppid;
328 if (ppidp != NULL)
329 *ppidp = hp->s_pid;
330 if (ptidp != NULL)
331 *ptidp = hp->s_tid;
332
333 break;
334 }
335 }
336 mutex_exit(&hash_lock);
337 }
338
339 if (lppid == zoneinit) {
340 lppid = 1;
341
342 if (ppidp != NULL)
343 *ppidp = lppid;
344 if (ptidp != NULL)
345 *ptidp = -1;
346 }
347
348 return (lppid);
349 }
350
351 void
352 lx_pid_init(void)
353 {
354 hash_size = 1 << highbit(v.v_proc / (hash_len * LINUX_PROC_FACTOR));
355
356 stol_pid_hash = kmem_zalloc(sizeof (struct lx_pid *) * hash_size,
357 KM_SLEEP);
358 ltos_pid_hash = kmem_zalloc(sizeof (struct lx_pid *) * hash_size,
359 KM_SLEEP);
360
361 mutex_init(&hash_lock, NULL, MUTEX_DEFAULT, NULL);
362 }
363
364 void
365 lx_pid_fini(void)
366 {
367 kmem_free(stol_pid_hash, sizeof (struct lx_pid *) * hash_size);
368 kmem_free(ltos_pid_hash, sizeof (struct lx_pid *) * hash_size);
369 }