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; 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 /* 103 * given a solaris pid/tid pair, create a linux pid 104 */ 105 int 106 lx_pid_assign(kthread_t *t) 107 { 108 proc_t *p = ttoproc(t); 109 pid_t s_pid = p->p_pid; 110 id_t s_tid = t->t_tid; 111 struct pid *pidp; 112 struct lx_pid *lpidp; 113 lx_lwp_data_t *lwpd = ttolxlwp(t); 114 pid_t newpid; 115 116 if (p->p_lwpcnt > 0) { 117 /* 118 * Allocate a pid for any thread other than the first 119 */ 120 if ((newpid = pid_allocate(p, 0, 0)) < 0) 121 return (-1); 122 123 pidp = pid_find(newpid); 124 } else { 125 pidp = NULL; 126 newpid = s_pid; 127 } 128 129 lpidp = kmem_alloc(sizeof (struct lx_pid), KM_SLEEP); 130 lpidp->l_pid = newpid; 131 lpidp->s_pid = s_pid; 132 lpidp->s_tid = s_tid; 133 lpidp->l_pidp = pidp; 134 lpidp->l_start = t->t_start; 135 136 /* 137 * now put the pid into the linux-solaris and solaris-linux 138 * conversion hash tables 139 */ 140 mutex_enter(&hash_lock); 141 lx_pid_insert_hash(lpidp); 142 mutex_exit(&hash_lock); 143 144 lwpd->br_pid = newpid; 145 146 return (0); 147 } 148 149 /* 150 * If we are exec()ing the process, this thread's tid is about to be reset 151 * to 1. Make sure the Linux PID bookkeeping reflects that change. 152 */ 153 void 154 lx_pid_reassign(kthread_t *t) 155 { 156 proc_t *p = ttoproc(t); 157 struct pid *old_pidp; 158 struct lx_pid *lpidp; 159 160 ASSERT(p->p_lwpcnt == 1); 161 162 mutex_enter(&hash_lock); 163 164 /* 165 * Clean up all the traces of this thread's 'fake' Linux PID. 166 */ 167 lpidp = lx_pid_remove_hash(p->p_pid, t->t_tid); 168 ASSERT(lpidp != NULL); 169 old_pidp = lpidp->l_pidp; 170 lpidp->l_pidp = NULL; 171 172 /* 173 * Now register this thread as (pid, 1). 174 */ 175 lpidp->l_pid = p->p_pid; 176 lpidp->s_pid = p->p_pid; 177 lpidp->s_tid = 1; 178 lx_pid_insert_hash(lpidp); 179 180 mutex_exit(&hash_lock); 181 182 if (old_pidp) 183 (void) pid_rele(old_pidp); 184 } 185 186 /* 187 * release a solaris pid/tid pair 188 */ 189 void 190 lx_pid_rele(pid_t pid, id_t tid) 191 { 192 struct lx_pid *lpidp; 193 194 mutex_enter(&hash_lock); 195 lpidp = lx_pid_remove_hash(pid, tid); 196 mutex_exit(&hash_lock); 197 198 if (lpidp) { 199 if (lpidp->l_pidp) 200 (void) pid_rele(lpidp->l_pidp); 201 202 kmem_free(lpidp, sizeof (*lpidp)); 203 } 204 } 205 206 /* 207 * given a linux pid, return the solaris pid/tid pair 208 */ 209 int 210 lx_lpid_to_spair(pid_t l_pid, pid_t *s_pid, id_t *s_tid) 211 { 212 struct lx_pid *hp; 213 214 mutex_enter(&hash_lock); 215 for (hp = ltos_pid_hash[LTOS_HASH(l_pid)]; hp; hp = hp->ltos_next) { 216 if (l_pid == hp->l_pid) { 217 if (s_pid) 218 *s_pid = hp->s_pid; 219 if (s_tid) 220 *s_tid = hp->s_tid; 221 break; 222 } 223 } 224 mutex_exit(&hash_lock); 225 if (hp != NULL) 226 return (0); 227 228 /* 229 * We didn't find this pid in our translation table. 230 * But this still could be the pid of a native process 231 * running in the current zone so check for that here. 232 * 233 * Note that prfind() only searches for processes in the current zone. 234 */ 235 mutex_enter(&pidlock); 236 if (prfind(l_pid) != NULL) { 237 mutex_exit(&pidlock); 238 if (s_pid) 239 *s_pid = l_pid; 240 if (s_tid) 241 *s_tid = 0; 242 return (0); 243 } 244 mutex_exit(&pidlock); 245 246 return (-1); 247 } 248 249 /* 250 * Given an lwp, return the Linux pid of its parent. If the caller 251 * wants them, we return the Solaris (pid, tid) as well. 252 */ 253 pid_t 254 lx_lwp_ppid(klwp_t *lwp, pid_t *ppidp, id_t *ptidp) 255 { 256 lx_lwp_data_t *lwpd = lwptolxlwp(lwp); 257 proc_t *p = lwptoproc(lwp); 258 struct lx_pid *hp; 259 pid_t zoneinit = curproc->p_zone->zone_proc_initpid; 260 pid_t lppid, ppid; 261 262 /* 263 * Be sure not to return a parent pid that should be invisible 264 * within this zone. 265 */ 266 ppid = ((p->p_flag & SZONETOP) 267 ? curproc->p_zone->zone_zsched->p_pid : p->p_ppid); 268 269 /* 270 * If the parent process's pid is the zone's init process, force it 271 * to the Linux init pid value of 1. 272 */ 273 if (ppid == zoneinit) 274 ppid = 1; 275 276 /* 277 * There are two cases in which the Linux definition of a 'parent' 278 * matches that of Solaris: 279 * 280 * - if our tgid is the same as our PID, then we are either the 281 * first thread in the process or a CLONE_THREAD thread. 282 * 283 * - if the brand lwp value for ppid is 0, then we are either the 284 * child of a differently-branded process or a CLONE_PARENT thread. 285 */ 286 if (p->p_pid == lwpd->br_tgid || lwpd->br_ppid == 0) { 287 if (ppidp != NULL) 288 *ppidp = ppid; 289 if (ptidp != NULL) 290 *ptidp = -1; 291 return (ppid); 292 } 293 294 /* 295 * Set the default Linux parent pid to be the pid of the zone's init 296 * process; this will get converted back to the Linux default of 1 297 * later. 298 */ 299 lppid = zoneinit; 300 301 /* 302 * If the process's parent isn't init, try and look up the Linux "pid" 303 * corresponding to the process's parent. 304 */ 305 if (ppid != 1) { 306 /* 307 * In all other cases, we are looking for the parent of this 308 * specific thread, which in Linux refers to the thread that 309 * clone()d it. We stashed that thread's PID away when this 310 * thread was created. 311 */ 312 mutex_enter(&hash_lock); 313 for (hp = ltos_pid_hash[LTOS_HASH(lwpd->br_ppid)]; hp; 314 hp = hp->ltos_next) { 315 if (lwpd->br_ppid == hp->l_pid) { 316 /* 317 * We found the PID we were looking for, but 318 * since we cached its value in this LWP's brand 319 * structure, it has exited and been reused by 320 * another process. 321 */ 322 if (hp->l_start > lwptot(lwp)->t_start) 323 break; 324 325 lppid = lwpd->br_ppid; 326 if (ppidp != NULL) 327 *ppidp = hp->s_pid; 328 if (ptidp != NULL) 329 *ptidp = hp->s_tid; 330 331 break; 332 } 333 } 334 mutex_exit(&hash_lock); 335 } 336 337 if (lppid == zoneinit) { 338 lppid = 1; 339 340 if (ppidp != NULL) 341 *ppidp = lppid; 342 if (ptidp != NULL) 343 *ptidp = -1; 344 } 345 346 return (lppid); 347 } 348 349 void 350 lx_pid_init(void) 351 { 352 hash_size = 1 << highbit(v.v_proc / (hash_len * LINUX_PROC_FACTOR)); 353 354 stol_pid_hash = kmem_zalloc(sizeof (struct lx_pid *) * hash_size, 355 KM_SLEEP); 356 ltos_pid_hash = kmem_zalloc(sizeof (struct lx_pid *) * hash_size, 357 KM_SLEEP); 358 359 mutex_init(&hash_lock, NULL, MUTEX_DEFAULT, NULL); 360 } 361 362 void 363 lx_pid_fini(void) 364 { 365 kmem_free(stol_pid_hash, sizeof (struct lx_pid *) * hash_size); 366 kmem_free(ltos_pid_hash, sizeof (struct lx_pid *) * hash_size); 367 }