Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/proc/prvnops.c
          +++ new/usr/src/uts/common/fs/proc/prvnops.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright (c) 2017, Joyent, Inc.
       24 + * Copyright (c) 2018, Joyent, Inc.
  25   25   * Copyright (c) 2017 by Delphix. All rights reserved.
  26   26   */
  27   27  
  28   28  /*      Copyright (c) 1984,      1986, 1987, 1988, 1989 AT&T    */
  29      -/*        All Rights Reserved   */
       29 +/*        All Rights Reserved   */
  30   30  
  31   31  #include <sys/types.h>
  32   32  #include <sys/param.h>
  33   33  #include <sys/time.h>
  34   34  #include <sys/cred.h>
  35   35  #include <sys/policy.h>
  36   36  #include <sys/debug.h>
  37   37  #include <sys/dirent.h>
  38   38  #include <sys/errno.h>
  39   39  #include <sys/file.h>
↓ open down ↓ 17 lines elided ↑ open up ↑
  57   57  #include <sys/gfs.h>
  58   58  #include <sys/vnode.h>
  59   59  #include <sys/fault.h>
  60   60  #include <sys/syscall.h>
  61   61  #include <sys/procfs.h>
  62   62  #include <sys/atomic.h>
  63   63  #include <sys/cmn_err.h>
  64   64  #include <sys/contract_impl.h>
  65   65  #include <sys/ctfs.h>
  66   66  #include <sys/avl.h>
       67 +#include <sys/ctype.h>
  67   68  #include <fs/fs_subr.h>
  68   69  #include <vm/rm.h>
  69   70  #include <vm/as.h>
  70   71  #include <vm/seg.h>
  71   72  #include <vm/seg_vn.h>
  72   73  #include <vm/hat.h>
  73   74  #include <fs/proc/prdata.h>
  74   75  #if defined(__sparc)
  75   76  #include <sys/regset.h>
  76   77  #endif
↓ open down ↓ 99 lines elided ↑ open up ↑
 176  177  /*
 177  178   * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 178  179   */
 179  180  static prdirent_t lwpiddir[] = {
 180  181          { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 181  182                  "." },
 182  183          { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 183  184                  ".." },
 184  185          { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 185  186                  "lwpctl" },
 186      -        { PR_LWPSTATUS,  4 * sizeof (prdirent_t), sizeof (prdirent_t),
      187 +        { PR_LWPNAME,    4 * sizeof (prdirent_t), sizeof (prdirent_t),
      188 +                "lwpname" },
      189 +        { PR_LWPSTATUS,  5 * sizeof (prdirent_t), sizeof (prdirent_t),
 187  190                  "lwpstatus" },
 188      -        { PR_LWPSINFO,   5 * sizeof (prdirent_t), sizeof (prdirent_t),
      191 +        { PR_LWPSINFO,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 189  192                  "lwpsinfo" },
 190      -        { PR_LWPUSAGE,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
      193 +        { PR_LWPUSAGE,   7 * sizeof (prdirent_t), sizeof (prdirent_t),
 191  194                  "lwpusage" },
 192      -        { PR_XREGS,      7 * sizeof (prdirent_t), sizeof (prdirent_t),
      195 +        { PR_XREGS,      8 * sizeof (prdirent_t), sizeof (prdirent_t),
 193  196                  "xregs" },
 194      -        { PR_TMPLDIR,    8 * sizeof (prdirent_t), sizeof (prdirent_t),
      197 +        { PR_TMPLDIR,    9 * sizeof (prdirent_t), sizeof (prdirent_t),
 195  198                  "templates" },
 196      -        { PR_SPYMASTER,  9 * sizeof (prdirent_t), sizeof (prdirent_t),
      199 +        { PR_SPYMASTER,  10 * sizeof (prdirent_t), sizeof (prdirent_t),
 197  200                  "spymaster" },
 198  201  #if defined(__sparc)
 199      -        { PR_GWINDOWS,  10 * sizeof (prdirent_t), sizeof (prdirent_t),
      202 +        { PR_GWINDOWS,  11 * sizeof (prdirent_t), sizeof (prdirent_t),
 200  203                  "gwindows" },
 201      -        { PR_ASRS,      11 * sizeof (prdirent_t), sizeof (prdirent_t),
      204 +        { PR_ASRS,      12 * sizeof (prdirent_t), sizeof (prdirent_t),
 202  205                  "asrs" },
 203  206  #endif
 204  207  };
 205  208  
 206  209  #define NLWPIDDIRFILES  (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
 207  210  
 208  211  /*
 209  212   * Span of entries in the array files (lstatus, lpsinfo, lusage).
 210  213   * We make the span larger than the size of the structure on purpose,
 211  214   * to make sure that programs cannot use the structure size by mistake.
↓ open down ↓ 368 lines elided ↑ open up ↑
 580  583   */
 581  584  static int pr_read_inval(), pr_read_as(), pr_read_status(),
 582  585          pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 583  586          pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 584  587          pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 585  588  #if defined(__x86)
 586  589          pr_read_ldt(),
 587  590  #endif
 588  591          pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 589  592          pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 590      -        pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
      593 +        pr_read_lwpusage(), pr_read_lwpname(),
      594 +        pr_read_xregs(), pr_read_priv(),
 591  595          pr_read_spymaster(), pr_read_secflags(),
 592  596  #if defined(__sparc)
 593  597          pr_read_gwindows(), pr_read_asrs(),
 594  598  #endif
 595  599          pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 596  600  
 597  601  static int (*pr_read_function[PR_NFILES])() = {
 598  602          pr_read_inval,          /* /proc                                */
 599  603          pr_read_inval,          /* /proc/self                           */
 600  604          pr_read_piddir,         /* /proc/<pid> (old /proc read())       */
↓ open down ↓ 18 lines elided ↑ open up ↑
 619  623          pr_read_watch,          /* /proc/<pid>/watch                    */
 620  624          pr_read_inval,          /* /proc/<pid>/cwd                      */
 621  625          pr_read_inval,          /* /proc/<pid>/root                     */
 622  626          pr_read_inval,          /* /proc/<pid>/fd                       */
 623  627          pr_read_inval,          /* /proc/<pid>/fd/nn                    */
 624  628          pr_read_inval,          /* /proc/<pid>/object                   */
 625  629          pr_read_inval,          /* /proc/<pid>/object/xxx               */
 626  630          pr_read_inval,          /* /proc/<pid>/lwp                      */
 627  631          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>              */
 628  632          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
      633 +        pr_read_lwpname,        /* /proc/<pid>/lwp/<lwpid>/lwpname      */
 629  634          pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
 630  635          pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
 631  636          pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
 632  637          pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs        */
 633  638          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates    */
 634  639          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 635  640          pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster    */
 636  641  #if defined(__sparc)
 637  642          pr_read_gwindows,       /* /proc/<pid>/lwp/<lwpid>/gwindows     */
 638  643          pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs         */
↓ open down ↓ 427 lines elided ↑ open up ↑
1066 1071          return (pr_uioread(auxv, sizeof (auxv), uiop));
1067 1072  }
1068 1073  
1069 1074  #if defined(__x86)
1070 1075  /*
1071 1076   * XX64
1072 1077   *      This is almost certainly broken for the amd64 kernel, because
1073 1078   *      we have two kinds of LDT structures to export -- one for compatibility
1074 1079   *      mode, and one for long mode, sigh.
1075 1080   *
1076      - *      For now lets just have a ldt of size 0 for 64-bit processes.
     1081 + *      For now let's just have a ldt of size 0 for 64-bit processes.
1077 1082   */
1078 1083  static int
1079 1084  pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1080 1085  {
1081 1086          proc_t *p;
1082 1087          struct ssd *ssd;
1083 1088          size_t size;
1084 1089          int error;
1085 1090  
1086 1091          ASSERT(pnp->pr_type == PR_LDT);
↓ open down ↓ 444 lines elided ↑ open up ↑
1531 1536  
1532 1537          prcvtusage(pup, upup);
1533 1538  
1534 1539          error = pr_uioread(upup, sizeof (prusage_t), uiop);
1535 1540  out:
1536 1541          kmem_free(pup, sizeof (*pup));
1537 1542          kmem_free(upup, sizeof (*upup));
1538 1543          return (error);
1539 1544  }
1540 1545  
     1546 +static int
     1547 +pr_read_lwpname(prnode_t *pnp, uio_t *uiop)
     1548 +{
     1549 +        char lwpname[THREAD_NAME_MAX];
     1550 +        kthread_t *t;
     1551 +        int error;
     1552 +
     1553 +        ASSERT(pnp->pr_type == PR_LWPNAME);
     1554 +
     1555 +        if (uiop->uio_offset >= THREAD_NAME_MAX)
     1556 +                return (0);
     1557 +
     1558 +        if ((error = prlock(pnp, ZNO)) != 0)
     1559 +                return (error);
     1560 +
     1561 +        bzero(lwpname, sizeof (lwpname));
     1562 +
     1563 +        t = pnp->pr_common->prc_thread;
     1564 +
     1565 +        if (t->t_name != NULL)
     1566 +                (void) strlcpy(lwpname, t->t_name, sizeof (lwpname));
     1567 +
     1568 +        prunlock(pnp);
     1569 +
     1570 +        return (pr_uioread(lwpname, sizeof (lwpname), uiop));
     1571 +}
     1572 +
1541 1573  /* ARGSUSED */
1542 1574  static int
1543 1575  pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1544 1576  {
1545 1577  #if defined(__sparc)
1546 1578          proc_t *p;
1547 1579          kthread_t *t;
1548 1580          int error;
1549 1581          char *xreg;
1550 1582          size_t size;
↓ open down ↓ 250 lines elided ↑ open up ↑
1801 1833          pr_read_watch_32,       /* /proc/<pid>/watch                    */
1802 1834          pr_read_inval,          /* /proc/<pid>/cwd                      */
1803 1835          pr_read_inval,          /* /proc/<pid>/root                     */
1804 1836          pr_read_inval,          /* /proc/<pid>/fd                       */
1805 1837          pr_read_inval,          /* /proc/<pid>/fd/nn                    */
1806 1838          pr_read_inval,          /* /proc/<pid>/object                   */
1807 1839          pr_read_inval,          /* /proc/<pid>/object/xxx               */
1808 1840          pr_read_inval,          /* /proc/<pid>/lwp                      */
1809 1841          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>              */
1810 1842          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
     1843 +        pr_read_lwpname,        /* /proc/<pid>/lwp/<lwpid>/lwpname      */
1811 1844          pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
1812 1845          pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
1813 1846          pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
1814 1847          pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs        */
1815 1848          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates    */
1816 1849          pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1817 1850          pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster    */
1818 1851  #if defined(__sparc)
1819 1852          pr_read_gwindows_32,    /* /proc/<pid>/lwp/<lwpid>/gwindows     */
1820 1853          pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs         */
↓ open down ↓ 892 lines elided ↑ open up ↑
2713 2746           */
2714 2747          if (curproc->p_model == DATAMODEL_LP64)
2715 2748                  return (pr_read_function[pnp->pr_type](pnp, uiop));
2716 2749          else
2717 2750                  return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2718 2751  #else
2719 2752          return (pr_read_function[pnp->pr_type](pnp, uiop));
2720 2753  #endif
2721 2754  }
2722 2755  
     2756 +/* Note we intentionally don't handle partial writes/updates. */
     2757 +static int
     2758 +pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
     2759 +{
     2760 +        kthread_t *t = NULL;
     2761 +        char *lwpname;
     2762 +        int error;
     2763 +
     2764 +        lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
     2765 +
     2766 +        if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) {
     2767 +                kmem_free(lwpname, THREAD_NAME_MAX);
     2768 +                return (error);
     2769 +        }
     2770 +
     2771 +        /* Somebody tried to write too long a thread name... */
     2772 +        if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) {
     2773 +                kmem_free(lwpname, THREAD_NAME_MAX);
     2774 +                return (EIO);
     2775 +        }
     2776 +
     2777 +        VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0');
     2778 +
     2779 +        for (size_t i = 0; lwpname[i] != '\0'; i++) {
     2780 +                if (!ISPRINT(lwpname[i])) {
     2781 +                        kmem_free(lwpname, THREAD_NAME_MAX);
     2782 +                        return (EINVAL);
     2783 +                }
     2784 +        }
     2785 +
     2786 +        /* Equivalent of thread_setname(), but with the ZNO magic. */
     2787 +        if ((error = prlock(pnp, ZNO)) != 0) {
     2788 +                kmem_free(lwpname, THREAD_NAME_MAX);
     2789 +                return (error);
     2790 +        }
     2791 +
     2792 +        t = pnp->pr_common->prc_thread;
     2793 +        if (t->t_name == NULL) {
     2794 +                t->t_name = lwpname;
     2795 +        } else {
     2796 +                (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX);
     2797 +                kmem_free(lwpname, THREAD_NAME_MAX);
     2798 +        }
     2799 +
     2800 +        prunlock(pnp);
     2801 +        return (0);
     2802 +}
     2803 +
2723 2804  /* ARGSUSED */
2724 2805  static int
2725 2806  prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2726 2807  {
2727 2808          prnode_t *pnp = VTOP(vp);
2728 2809          int old = 0;
2729 2810          int error;
2730 2811          ssize_t resid;
2731 2812  
2732 2813          ASSERT(pnp->pr_type < PR_NFILES);
↓ open down ↓ 58 lines elided ↑ open up ↑
2791 2872                  error = prwritectl(vp, uiop, CRED());
2792 2873  #endif
2793 2874                  /*
2794 2875                   * This hack makes sure that the EINTR is passed
2795 2876                   * all the way back to the caller's write() call.
2796 2877                   */
2797 2878                  if (error == EINTR)
2798 2879                          uiop->uio_resid = resid;
2799 2880                  return (error);
2800 2881  
     2882 +        case PR_LWPNAME:
     2883 +                return (pr_write_lwpname(pnp, uiop));
     2884 +
2801 2885          default:
2802 2886                  return ((vp->v_type == VDIR)? EISDIR : EBADF);
2803 2887          }
2804 2888          /* NOTREACHED */
2805 2889  }
2806 2890  
2807 2891  static int
2808 2892  prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2809 2893      caller_context_t *ct)
2810 2894  {
↓ open down ↓ 540 lines elided ↑ open up ↑
3351 3435          pr_lookup_notdir,       /* /proc/<pid>/watch                    */
3352 3436          pr_lookup_notdir,       /* /proc/<pid>/cwd                      */
3353 3437          pr_lookup_notdir,       /* /proc/<pid>/root                     */
3354 3438          pr_lookup_fddir,        /* /proc/<pid>/fd                       */
3355 3439          pr_lookup_notdir,       /* /proc/<pid>/fd/nn                    */
3356 3440          pr_lookup_objectdir,    /* /proc/<pid>/object                   */
3357 3441          pr_lookup_notdir,       /* /proc/<pid>/object/xxx               */
3358 3442          pr_lookup_lwpdir,       /* /proc/<pid>/lwp                      */
3359 3443          pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>              */
3360 3444          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
     3445 +        pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpname      */
3361 3446          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
3362 3447          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
3363 3448          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
3364 3449          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs        */
3365 3450          pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates    */
3366 3451          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3367 3452          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster    */
3368 3453  #if defined(__sparc)
3369 3454          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/gwindows     */
3370 3455          pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/asrs         */
↓ open down ↓ 1243 lines elided ↑ open up ↑
4614 4699          case PR_CTL:
4615 4700          case PR_LWPCTL:
4616 4701                  pnp->pr_mode = 0200;    /* write-only by owner only */
4617 4702                  break;
4618 4703  
4619 4704          case PR_PIDFILE:
4620 4705          case PR_LWPIDFILE:
4621 4706                  pnp->pr_mode = 0600;    /* read-write by owner only */
4622 4707                  break;
4623 4708  
     4709 +        case PR_LWPNAME:
     4710 +                pnp->pr_mode = 0644;    /* readable by all + owner can write */
     4711 +                break;
     4712 +
4624 4713          case PR_PSINFO:
4625 4714          case PR_LPSINFO:
4626 4715          case PR_LWPSINFO:
4627 4716          case PR_USAGE:
4628 4717          case PR_LUSAGE:
4629 4718          case PR_LWPUSAGE:
4630 4719                  pnp->pr_mode = 0444;    /* read-only by all */
4631 4720                  break;
4632 4721  
4633 4722          default:
↓ open down ↓ 104 lines elided ↑ open up ↑
4738 4827          pr_readdir_notdir,      /* /proc/<pid>/watch                    */
4739 4828          pr_readdir_notdir,      /* /proc/<pid>/cwd                      */
4740 4829          pr_readdir_notdir,      /* /proc/<pid>/root                     */
4741 4830          pr_readdir_fddir,       /* /proc/<pid>/fd                       */
4742 4831          pr_readdir_notdir,      /* /proc/<pid>/fd/nn                    */
4743 4832          pr_readdir_objectdir,   /* /proc/<pid>/object                   */
4744 4833          pr_readdir_notdir,      /* /proc/<pid>/object/xxx               */
4745 4834          pr_readdir_lwpdir,      /* /proc/<pid>/lwp                      */
4746 4835          pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>              */
4747 4836          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl       */
     4837 +        pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpname      */
4748 4838          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus    */
4749 4839          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo     */
4750 4840          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage     */
4751 4841          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs        */
4752 4842          pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates    */
4753 4843          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4754 4844          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster    */
4755 4845  #if defined(__sparc)
4756 4846          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/gwindows     */
4757 4847          pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/asrs         */
↓ open down ↓ 1379 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX