Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
*** 19,29 ****
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2017, Joyent, Inc.
* Copyright (c) 2017 by Delphix. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 2018, Joyent, Inc.
* Copyright (c) 2017 by Delphix. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
*** 62,71 ****
--- 62,72 ----
#include <sys/atomic.h>
#include <sys/cmn_err.h>
#include <sys/contract_impl.h>
#include <sys/ctfs.h>
#include <sys/avl.h>
+ #include <sys/ctype.h>
#include <fs/fs_subr.h>
#include <vm/rm.h>
#include <vm/as.h>
#include <vm/seg.h>
#include <vm/seg_vn.h>
*** 181,206 ****
"." },
{ PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
".." },
{ PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpctl" },
! { PR_LWPSTATUS, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpstatus" },
! { PR_LWPSINFO, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpsinfo" },
! { PR_LWPUSAGE, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpusage" },
! { PR_XREGS, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
"xregs" },
! { PR_TMPLDIR, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
"templates" },
! { PR_SPYMASTER, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
"spymaster" },
#if defined(__sparc)
! { PR_GWINDOWS, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
"gwindows" },
! { PR_ASRS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
"asrs" },
#endif
};
#define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
--- 182,209 ----
"." },
{ PR_LWPDIR, 2 * sizeof (prdirent_t), sizeof (prdirent_t),
".." },
{ PR_LWPCTL, 3 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpctl" },
! { PR_LWPNAME, 4 * sizeof (prdirent_t), sizeof (prdirent_t),
! "lwpname" },
! { PR_LWPSTATUS, 5 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpstatus" },
! { PR_LWPSINFO, 6 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpsinfo" },
! { PR_LWPUSAGE, 7 * sizeof (prdirent_t), sizeof (prdirent_t),
"lwpusage" },
! { PR_XREGS, 8 * sizeof (prdirent_t), sizeof (prdirent_t),
"xregs" },
! { PR_TMPLDIR, 9 * sizeof (prdirent_t), sizeof (prdirent_t),
"templates" },
! { PR_SPYMASTER, 10 * sizeof (prdirent_t), sizeof (prdirent_t),
"spymaster" },
#if defined(__sparc)
! { PR_GWINDOWS, 11 * sizeof (prdirent_t), sizeof (prdirent_t),
"gwindows" },
! { PR_ASRS, 12 * sizeof (prdirent_t), sizeof (prdirent_t),
"asrs" },
#endif
};
#define NLWPIDDIRFILES (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
*** 585,595 ****
#if defined(__x86)
pr_read_ldt(),
#endif
pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
! pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
pr_read_spymaster(), pr_read_secflags(),
#if defined(__sparc)
pr_read_gwindows(), pr_read_asrs(),
#endif
pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
--- 588,599 ----
#if defined(__x86)
pr_read_ldt(),
#endif
pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
! pr_read_lwpusage(), pr_read_lwpname(),
! pr_read_xregs(), pr_read_priv(),
pr_read_spymaster(), pr_read_secflags(),
#if defined(__sparc)
pr_read_gwindows(), pr_read_asrs(),
#endif
pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
*** 624,633 ****
--- 628,638 ----
pr_read_inval, /* /proc/<pid>/object */
pr_read_inval, /* /proc/<pid>/object/xxx */
pr_read_inval, /* /proc/<pid>/lwp */
pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
+ pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
pr_read_lwpstatus, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
pr_read_lwpsinfo, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
pr_read_lwpusage, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
*** 1071,1081 ****
* XX64
* This is almost certainly broken for the amd64 kernel, because
* we have two kinds of LDT structures to export -- one for compatibility
* mode, and one for long mode, sigh.
*
! * For now lets just have a ldt of size 0 for 64-bit processes.
*/
static int
pr_read_ldt(prnode_t *pnp, uio_t *uiop)
{
proc_t *p;
--- 1076,1086 ----
* XX64
* This is almost certainly broken for the amd64 kernel, because
* we have two kinds of LDT structures to export -- one for compatibility
* mode, and one for long mode, sigh.
*
! * For now let's just have a ldt of size 0 for 64-bit processes.
*/
static int
pr_read_ldt(prnode_t *pnp, uio_t *uiop)
{
proc_t *p;
*** 1536,1545 ****
--- 1541,1577 ----
kmem_free(pup, sizeof (*pup));
kmem_free(upup, sizeof (*upup));
return (error);
}
+ static int
+ pr_read_lwpname(prnode_t *pnp, uio_t *uiop)
+ {
+ char lwpname[THREAD_NAME_MAX];
+ kthread_t *t;
+ int error;
+
+ ASSERT(pnp->pr_type == PR_LWPNAME);
+
+ if (uiop->uio_offset >= THREAD_NAME_MAX)
+ return (0);
+
+ if ((error = prlock(pnp, ZNO)) != 0)
+ return (error);
+
+ bzero(lwpname, sizeof (lwpname));
+
+ t = pnp->pr_common->prc_thread;
+
+ if (t->t_name != NULL)
+ (void) strlcpy(lwpname, t->t_name, sizeof (lwpname));
+
+ prunlock(pnp);
+
+ return (pr_uioread(lwpname, sizeof (lwpname), uiop));
+ }
+
/* ARGSUSED */
static int
pr_read_xregs(prnode_t *pnp, uio_t *uiop)
{
#if defined(__sparc)
*** 1806,1815 ****
--- 1838,1848 ----
pr_read_inval, /* /proc/<pid>/object */
pr_read_inval, /* /proc/<pid>/object/xxx */
pr_read_inval, /* /proc/<pid>/lwp */
pr_read_inval, /* /proc/<pid>/lwp/<lwpid> */
pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
+ pr_read_lwpname, /* /proc/<pid>/lwp/<lwpid>/lwpname */
pr_read_lwpstatus_32, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
pr_read_lwpsinfo_32, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
pr_read_lwpusage_32, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
pr_read_xregs, /* /proc/<pid>/lwp/<lwpid>/xregs */
pr_read_inval, /* /proc/<pid>/lwp/<lwpid>/templates */
*** 2718,2727 ****
--- 2751,2808 ----
#else
return (pr_read_function[pnp->pr_type](pnp, uiop));
#endif
}
+ /* Note we intentionally don't handle partial writes/updates. */
+ static int
+ pr_write_lwpname(prnode_t *pnp, uio_t *uiop)
+ {
+ kthread_t *t = NULL;
+ char *lwpname;
+ int error;
+
+ lwpname = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
+
+ if ((error = uiomove(lwpname, THREAD_NAME_MAX, UIO_WRITE, uiop)) != 0) {
+ kmem_free(lwpname, THREAD_NAME_MAX);
+ return (error);
+ }
+
+ /* Somebody tried to write too long a thread name... */
+ if (lwpname[THREAD_NAME_MAX - 1] != '\0' || uiop->uio_resid > 0) {
+ kmem_free(lwpname, THREAD_NAME_MAX);
+ return (EIO);
+ }
+
+ VERIFY3U(lwpname[THREAD_NAME_MAX - 1], ==, '\0');
+
+ for (size_t i = 0; lwpname[i] != '\0'; i++) {
+ if (!ISPRINT(lwpname[i])) {
+ kmem_free(lwpname, THREAD_NAME_MAX);
+ return (EINVAL);
+ }
+ }
+
+ /* Equivalent of thread_setname(), but with the ZNO magic. */
+ if ((error = prlock(pnp, ZNO)) != 0) {
+ kmem_free(lwpname, THREAD_NAME_MAX);
+ return (error);
+ }
+
+ t = pnp->pr_common->prc_thread;
+ if (t->t_name == NULL) {
+ t->t_name = lwpname;
+ } else {
+ (void) strlcpy(t->t_name, lwpname, THREAD_NAME_MAX);
+ kmem_free(lwpname, THREAD_NAME_MAX);
+ }
+
+ prunlock(pnp);
+ return (0);
+ }
+
/* ARGSUSED */
static int
prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
{
prnode_t *pnp = VTOP(vp);
*** 2796,2805 ****
--- 2877,2889 ----
*/
if (error == EINTR)
uiop->uio_resid = resid;
return (error);
+ case PR_LWPNAME:
+ return (pr_write_lwpname(pnp, uiop));
+
default:
return ((vp->v_type == VDIR)? EISDIR : EBADF);
}
/* NOTREACHED */
}
*** 3356,3365 ****
--- 3440,3450 ----
pr_lookup_objectdir, /* /proc/<pid>/object */
pr_lookup_notdir, /* /proc/<pid>/object/xxx */
pr_lookup_lwpdir, /* /proc/<pid>/lwp */
pr_lookup_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
+ pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
pr_lookup_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
pr_lookup_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */
*** 4619,4628 ****
--- 4704,4717 ----
case PR_PIDFILE:
case PR_LWPIDFILE:
pnp->pr_mode = 0600; /* read-write by owner only */
break;
+ case PR_LWPNAME:
+ pnp->pr_mode = 0644; /* readable by all + owner can write */
+ break;
+
case PR_PSINFO:
case PR_LPSINFO:
case PR_LWPSINFO:
case PR_USAGE:
case PR_LUSAGE:
*** 4743,4752 ****
--- 4832,4842 ----
pr_readdir_objectdir, /* /proc/<pid>/object */
pr_readdir_notdir, /* /proc/<pid>/object/xxx */
pr_readdir_lwpdir, /* /proc/<pid>/lwp */
pr_readdir_lwpiddir, /* /proc/<pid>/lwp/<lwpid> */
pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
+ pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpname */
pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
pr_readdir_notdir, /* /proc/<pid>/lwp/<lwpid>/xregs */
pr_readdir_tmpldir, /* /proc/<pid>/lwp/<lwpid>/templates */