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 = &ltos_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 }