From cef5a146e600a27064f0ea2aa25fc5f8663cb9b7 Mon Sep 17 00:00:00 2001 From: guenther Date: Sat, 7 Jan 2023 05:24:58 +0000 Subject: [PATCH] Add {get,set}thrname(2) for putting thread names in the kernel and exposed in a new field returned by sysctl(KERN_PROC). Update pthread_{get,set}_name_np(3) to use the syscalls. Show them, when set, in ps -H and top -H output. libc and libpthread minor bumps ok mpi@, mvs@, deraadt@ --- bin/ps/print.c | 19 ++++++++++--- include/unistd.h | 4 ++- lib/libc/Symbols.list | 4 +++ lib/libc/shlib_version | 2 +- lib/libc/sys/Makefile.inc | 7 ++--- lib/librthread/rthread_np.c | 16 ++++++++--- lib/librthread/shlib_version | 2 +- sys/kern/kern_exec.c | 4 ++- sys/kern/kern_fork.c | 3 ++- sys/kern/kern_pledge.c | 4 ++- sys/kern/kern_prot.c | 52 +++++++++++++++++++++++++++++++++++- sys/kern/syscalls.master | 6 ++--- sys/sys/proc.h | 3 ++- sys/sys/sysctl.h | 8 +++--- usr.bin/top/machine.c | 35 +++++++++++++----------- 15 files changed, 130 insertions(+), 39 deletions(-) diff --git a/bin/ps/print.c b/bin/ps/print.c index 56a78da0cbf..21709700847 100644 --- a/bin/ps/print.c +++ b/bin/ps/print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print.c,v 1.84 2022/09/20 10:01:51 job Exp $ */ +/* $OpenBSD: print.c,v 1.85 2023/01/07 05:24:59 guenther Exp $ */ /* $NetBSD: print.c,v 1.27 1995/09/29 21:58:12 cgd Exp $ */ /*- @@ -95,6 +95,18 @@ printheader(void) (void)putchar('\n'); } +static int +print_comm_name(const struct kinfo_proc *kp, int left, int trail) +{ + left -= mbswprint(kp->p_comm, left, trail); + if (left > 1 && kp->p_name[0] != '\0') { + putchar('/'); + left--; + left -= mbswprint(kp->p_name, left, trail); + } + return left; +} + void command(const struct pinfo *pi, VARENT *ve) { @@ -161,6 +173,7 @@ command(const struct pinfo *pi, VARENT *ve) } } if (argv == NULL || argv[0] == NULL || + kp->p_name[0] != '\0' || strcmp(cmdpart(argv[0]), kp->p_comm)) { if (wantspace) { putchar(' '); @@ -169,7 +182,7 @@ command(const struct pinfo *pi, VARENT *ve) } putchar('('); left--; - left -= mbswprint(kp->p_comm, left, 0); + left -= print_comm_name(kp, left, 0); if (left == 0) return; putchar(')'); @@ -180,7 +193,7 @@ command(const struct pinfo *pi, VARENT *ve) putchar(' '); left--; } - left -= mbswprint(kp->p_comm, left, 0); + left -= print_comm_name(kp, left, 0); } } if (ve->next != NULL) diff --git a/include/unistd.h b/include/unistd.h index c9432eadb23..771347031e9 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.106 2018/07/13 09:25:22 beck Exp $ */ +/* $OpenBSD: unistd.h,v 1.107 2023/01/07 05:24:58 guenther Exp $ */ /* $NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $ */ /*- @@ -488,6 +488,7 @@ mode_t getmode(const void *, mode_t); int getresgid(gid_t *, gid_t *, gid_t *); int getresuid(uid_t *, uid_t *, uid_t *); pid_t getthrid(void); +int getthrname(pid_t, char *, size_t); char *getusershell(void); int initgroups(const char *, gid_t); int issetugid(void); @@ -517,6 +518,7 @@ void *setmode(const char *); int setpgrp(pid_t _pid, pid_t _pgrp); /* BSD compat version */ int setresgid(gid_t, gid_t, gid_t); int setresuid(uid_t, uid_t, uid_t); +int setthrname(pid_t, const char *); void setusershell(void); int strtofflags(char **, u_int32_t *, u_int32_t *); int swapctl(int cmd, const void *arg, int misc); diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index 833cdf655e9..c5b8794362e 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -115,6 +115,7 @@ _thread_sys_getsid _thread_sys_getsockname _thread_sys_getsockopt _thread_sys_getthrid +_thread_sys_getthrname _thread_sys_gettimeofday _thread_sys_getuid _thread_sys_ioctl @@ -206,6 +207,7 @@ _thread_sys_setrlimit _thread_sys_setrtable _thread_sys_setsid _thread_sys_setsockopt +_thread_sys_setthrname _thread_sys_settimeofday _thread_sys_setuid _thread_sys_shmat @@ -314,6 +316,7 @@ getsid getsockname getsockopt getthrid +getthrname gettimeofday getuid ioctl @@ -408,6 +411,7 @@ setrlimit setrtable setsid setsockopt +setthrname settimeofday setuid shmat diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 9da1fafdd94..807e5659848 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ major=96 -minor=4 +minor=5 # note: If changes were made to include/thread_private.h or if system calls # were added/changed then librthread/shlib_version must also be updated. diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 6579bc1e58f..2f70b2b9463 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.167 2022/12/19 18:13:50 guenther Exp $ +# $OpenBSD: Makefile.inc,v 1.168 2023/01/07 05:24:58 guenther Exp $ # $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $ # @(#)Makefile.inc 8.1 (Berkeley) 6/17/93 @@ -91,9 +91,10 @@ DASM= ${ASM:.o=.do} # they just never want to set errno. ASM_NOERR=__get_tcb.o __set_tcb.o __threxit.o __thrsleep.o __thrwakeup.o \ getdtablecount.o getegid.o geteuid.o getgid.o getlogin_r.o \ - getpgrp.o getpid.o getppid.o getrtable.o getthrid.o getuid.o \ + getpgrp.o getpid.o getppid.o getrtable.o getthrid.o \ + getthrname.o getuid.o \ issetugid.o \ - sched_yield.o sync.o \ + sched_yield.o setthrname.o sync.o \ umask.o PASM_NOERR= ${ASM_NOERR:.o=.po} SASM_NOERR= ${ASM_NOERR:.o=.so} diff --git a/lib/librthread/rthread_np.c b/lib/librthread/rthread_np.c index 8570f3141ca..b2d10e1ce2a 100644 --- a/lib/librthread/rthread_np.c +++ b/lib/librthread/rthread_np.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_np.c,v 1.23 2021/09/17 15:20:21 deraadt Exp $ */ +/* $OpenBSD: rthread_np.c,v 1.24 2023/01/07 05:24:58 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst * Copyright (c) 2005 Otto Moerbeek @@ -36,17 +36,27 @@ #include "rthread.h" REDIRECT_SYSCALL(sysctl); +REDIRECT_SYSCALL(getthrname); +REDIRECT_SYSCALL(setthrname); void pthread_set_name_np(pthread_t thread, const char *name) { - strlcpy(thread->name, name, sizeof(thread->name)); + pid_t tid = 0; + + if (thread != pthread_self()) + tid = thread->tib->tib_tid; + setthrname(tid, name); } void pthread_get_name_np(pthread_t thread, char *name, size_t len) { - strlcpy(name, thread->name, len); + pid_t tid = 0; + + if (thread != pthread_self()) + tid = thread->tib->tib_tid; + getthrname(tid, name, len); } int diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version index 68cb9e8a964..6168a5fce7f 100644 --- a/lib/librthread/shlib_version +++ b/lib/librthread/shlib_version @@ -1,2 +1,2 @@ major=26 -minor=3 +minor=4 diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 84185dc75c8..0d470bf9292 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.241 2023/01/05 21:39:57 deraadt Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.242 2023/01/07 05:24:58 guenther Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -663,6 +663,8 @@ sys_execve(struct proc *p, void *v, register_t *retval) timespecclear(&p->p_tu.tu_runtime); p->p_tu.tu_uticks = p->p_tu.tu_sticks = p->p_tu.tu_iticks = 0; + memset(p->p_name, 0, sizeof p->p_name); + km_free(argp, NCARGS, &kv_exec, &kp_pageable); pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 31fb7d61877..ccdd34aafb8 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.244 2022/11/11 18:09:58 cheloha Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.245 2023/01/07 05:24:58 guenther Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -535,6 +535,7 @@ thread_fork(struct proc *curp, void *stack, void *tcb, pid_t *tidptr, p = thread_new(curp, uaddr); atomic_setbits_int(&p->p_flag, P_THREAD); sigstkinit(&p->p_sigstk); + memset(p->p_name, 0, sizeof p->p_name); /* other links */ p->p_p = pr; diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 0c3a697d21e..09d600f47ba 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.301 2022/12/23 05:35:08 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.302 2023/01/07 05:24:58 guenther Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -280,6 +280,8 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = { [SYS___thrwakeup] = PLEDGE_STDIO, [SYS___threxit] = PLEDGE_STDIO, [SYS___thrsigdivert] = PLEDGE_STDIO, + [SYS_getthrname] = PLEDGE_STDIO, + [SYS_setthrname] = PLEDGE_STDIO, [SYS_fork] = PLEDGE_PROC, [SYS_vfork] = PLEDGE_PROC, diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index d593a43a29e..54e169debbb 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_prot.c,v 1.80 2022/08/14 01:58:27 jsg Exp $ */ +/* $OpenBSD: kern_prot.c,v 1.81 2023/01/07 05:24:58 guenther Exp $ */ /* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */ /* @@ -1111,6 +1111,56 @@ sys___get_tcb(struct proc *p, void *v, register_t *retval) return (0); } +int +sys_getthrname(struct proc *curp, void *v, register_t *retval) +{ + struct sys_getthrname_args /* { + syscallarg(pid_t) tid; + syscallarg(char *) name; + syscallarg(size_t) len; + } */ *uap = v; + struct proc *p; + size_t len; + int tid = SCARG(uap, tid); + int error; + + p = tid ? tfind_user(tid, curp->p_p) : curp; + if (p == NULL) + return ESRCH; + + len = SCARG(uap, len); + if (len > sizeof(p->p_name)) + len = sizeof(p->p_name); + error = copyoutstr(p->p_name, SCARG(uap, name), len, NULL); + if (error == ENAMETOOLONG) + error = ERANGE; + *retval = error; + return 0; +} + +int +sys_setthrname(struct proc *curp, void *v, register_t *retval) +{ + struct sys_setthrname_args /* { + syscallarg(pid_t) tid; + syscallarg(const char *) name; + } */ *uap = v; + struct proc *p; + char buf[sizeof p->p_name]; + int tid = SCARG(uap, tid); + int error; + + p = tid ? tfind_user(tid, curp->p_p) : curp; + if (p == NULL) + return ESRCH; + + error = copyinstr(SCARG(uap, name), buf, sizeof buf, NULL); + if (error == 0) + strlcpy(p->p_name, buf, sizeof(p->p_name)); + *retval = error; + return 0; +} + /* * Refresh the thread's reference to the process's credentials */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 85bae7ec8ab..029d06a2b3b 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.238 2022/12/17 13:42:59 kn Exp $ +; $OpenBSD: syscalls.master,v 1.239 2023/01/07 05:24:58 guenther Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -280,8 +280,8 @@ 140 STD NOLOCK { int sys_adjtime(const struct timeval *delta, \ struct timeval *olddelta); } 141 STD { int sys_getlogin_r(char *namebuf, u_int namelen); } -142 OBSOL ogethostid -143 OBSOL osethostid +142 STD { int sys_getthrname(pid_t tid, char *name, size_t len); } +143 STD { int sys_setthrname(pid_t tid, const char *name); } 144 OBSOL ogetrlimit 145 OBSOL osetrlimit 146 OBSOL okillpg diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 545f20027da..15844fa4d34 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.337 2023/01/02 23:09:48 guenther Exp $ */ +/* $OpenBSD: proc.h,v 1.338 2023/01/07 05:24:58 guenther Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -367,6 +367,7 @@ struct proc { #define p_startcopy p_sigmask sigset_t p_sigmask; /* [a] Current signal mask */ + char p_name[_MAXCOMLEN]; /* thread name, incl NUL */ u_char p_slppri; /* [S] Sleeping priority */ u_char p_usrpri; /* [S] Priority based on p_estcpu & ps_nice */ u_int p_estcpu; /* [S] Time averaged val of p_cpticks */ diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 4fa5afdf6c8..ee7938765d1 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.231 2022/11/07 14:25:44 robert Exp $ */ +/* $OpenBSD: sysctl.h,v 1.232 2023/01/07 05:24:58 guenther Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -490,6 +490,7 @@ struct kinfo_proc { u_int32_t p_rtableid; /* U_INT: Routing table identifier. */ u_int64_t p_pledge; /* U_INT64_T: Pledge flags. */ + char p_name[KI_MAXCOMLEN]; /* thread name */ }; /* @@ -617,7 +618,7 @@ do { \ (kp)->p_svgid = (uc)->cr_svgid; \ \ memcpy((kp)->p_groups, (uc)->cr_groups, \ - _FILL_KPROC_MIN(sizeof((kp)->p_groups), sizeof((uc)->cr_groups))); \ + _FILL_KPROC_MIN(sizeof((kp)->p_groups), sizeof((uc)->cr_groups))); \ (kp)->p_ngroups = (uc)->cr_ngroups; \ \ (kp)->p_jobc = (pg)->pg_jobc; \ @@ -630,6 +631,7 @@ do { \ (kp)->p_uticks = (p)->p_tu.tu_uticks; \ (kp)->p_sticks = (p)->p_tu.tu_sticks; \ (kp)->p_iticks = (p)->p_tu.tu_iticks; \ + strlcpy((kp)->p_name, (p)->p_name, sizeof((kp)->p_name)); \ } else { \ (kp)->p_rtime_sec = (pr)->ps_tu.tu_runtime.tv_sec; \ (kp)->p_rtime_usec = (pr)->ps_tu.tu_runtime.tv_nsec/1000; \ @@ -666,7 +668,7 @@ do { \ strlcpy((kp)->p_emul, "native", sizeof((kp)->p_emul)); \ strlcpy((kp)->p_comm, (pr)->ps_comm, sizeof((kp)->p_comm)); \ strlcpy((kp)->p_login, (sess)->s_login, \ - _FILL_KPROC_MIN(sizeof((kp)->p_login), sizeof((sess)->s_login))); \ + _FILL_KPROC_MIN(sizeof((kp)->p_login), sizeof((sess)->s_login))); \ \ if ((sess)->s_ttyvp) \ (kp)->p_eflag |= EPROC_CTTY; \ diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index fbddbc172d3..8991f53bf99 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machine.c,v 1.112 2022/09/10 16:58:51 cheloha Exp $ */ +/* $OpenBSD: machine.c,v 1.113 2023/01/07 05:24:59 guenther Exp $ */ /*- * Copyright (c) 1994 Thorsten Lockert @@ -390,6 +390,9 @@ cmd_matches(struct kinfo_proc *proc, char *term) /* Filter set, process name needs to contain term */ if (strstr(proc->p_comm, term)) return 1; + /* If thread name set, search that too */ + if (strstr(proc->p_name, term)) + return 1; /* If showing arguments, search those as well */ if (show_args) { args = get_proc_args(proc); @@ -518,22 +521,22 @@ format_comm(struct kinfo_proc *kp) char **p, **s; extern int show_args; - if (!show_args) - return (kp->p_comm); - - s = get_proc_args(kp); - if (s == NULL) - return kp->p_comm; - - buf[0] = '\0'; - for (p = s; *p != NULL; p++) { - if (p != s) - strlcat(buf, " ", sizeof(buf)); - strlcat(buf, *p, sizeof(buf)); + if (show_args && (s = get_proc_args(kp)) != NULL) { + buf[0] = '\0'; + for (p = s; *p != NULL; p++) { + if (p != s) + strlcat(buf, " ", sizeof(buf)); + strlcat(buf, *p, sizeof(buf)); + } + if (buf[0] != '\0') + return buf; + } + if (kp->p_name[0] != '\0') { + snprintf(buf, sizeof buf, "%s/%s", kp->p_comm, + kp->p_name); + return buf; } - if (buf[0] == '\0') - return (kp->p_comm); - return (buf); + return kp->p_comm; } void -- 2.20.1