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 }