diff options
Diffstat (limited to 'usr/src/cmd')
41 files changed, 749 insertions, 193 deletions
diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c index a5031e9950..c1995611e9 100644 --- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018 Joyent, Inc. * Copyright 2016 Argo Technologie SA. * Copyright (c) 2016-2017, Chris Fraire <cfraire@me.com>. */ @@ -457,6 +458,7 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op) (void) pthread_attr_init(&attr); (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + (void) pthread_attr_setname_np(&attr, "db_restore"); err = pthread_create(&tid, &attr, ipmgmt_db_restore_thread, NULL); (void) pthread_attr_destroy(&attr); @@ -1124,7 +1126,7 @@ ipmgmt_aobjmap_init(void *arg, nvlist_t *db_nvl, char *buf, size_t buflen, { nvpair_t *nvp = NULL; char *name, *strval = NULL; - ipmgmt_aobjmap_t node; + ipmgmt_aobjmap_t node; struct sockaddr_in6 *in6; *errp = 0; diff --git a/usr/src/cmd/dtrace/test/tst/common/Makefile b/usr/src/cmd/dtrace/test/tst/common/Makefile index 808d0e4e8e..a29d774069 100644 --- a/usr/src/cmd/dtrace/test/tst/common/Makefile +++ b/usr/src/cmd/dtrace/test/tst/common/Makefile @@ -26,8 +26,8 @@ # # Copyright (c) 2012 by Delphix. All rights reserved. -# Copyright (c) 2013, Joyent, Inc. All rights reserved. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # # @@ -57,6 +57,8 @@ sysevent/tst.post_chan.exe := LDLIBS += -lsysevent ustack/tst.bigstack.exe := COPTFLAG += -xO1 +CSTD = $(CSTD_GNU99) + nfs/%.o: $(SNOOPDIR)/%.c $(COMPILE.c) -o $@ $< -I$(SNOOPDIR) $(POST_PROCESS_O) diff --git a/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c new file mode 100644 index 0000000000..49d9f2155c --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c @@ -0,0 +1,99 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * All we're doing is constantly modifying a thread name while DTrace is + * watching us, making sure we don't break. + */ + +#include <sys/fcntl.h> +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> + +#define NR_THREADS (100) +#define RUNTIME (30) /* seconds */ + +static void +random_ascii(char *buf, size_t bufsize) +{ + char table[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.-#'?!"; + size_t len = rand() % bufsize; + + bzero(buf, bufsize); + + for (size_t i = 0; i < len; i++) { + buf[i] = table[rand() % (sizeof (table) - 1)]; + } +} + +static void +busy() +{ + struct timeval tv1; + struct timeval tv2; + + if (gettimeofday(&tv1, NULL) != 0) + abort(); + + for (;;) { + static volatile int i; + for (i = 0; i < 2000000; i++) + ; + + if (gettimeofday(&tv2, NULL) != 0) + abort(); + + /* janky, but we don't care */ + if (tv2.tv_sec != tv1.tv_sec) + return; + } +} + +static void * +thread(void *arg) +{ + char name[PTHREAD_MAX_NAMELEN_NP]; + + for (size_t i = 0; ; i++) { + random_ascii(name, sizeof (name)); + + if ((i % 100) == 0) { + if (pthread_setname_np(pthread_self(), NULL) != 0) + abort(); + } else { + (void) pthread_setname_np(pthread_self(), name); + } + + busy(); + } + + return (NULL); +} + +int +main(int argc, char **argv) +{ + pthread_t tids[NR_THREADS]; + + for (size_t i = 0; i < NR_THREADS; i++) { + if (pthread_create(&tids[i], NULL, thread, NULL) != 0) + exit(EXIT_FAILURE); + } + + sleep(RUNTIME); + exit(EXIT_SUCCESS); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d new file mode 100644 index 0000000000..289f6c5bbc --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d @@ -0,0 +1,26 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#pragma D option quiet + +profile-10ms /pid == $1 && threadname == "unlikely"/ +{ + surprising++; +} + +syscall::rexit:entry /pid == $1/ +{ + exit(arg0); +} diff --git a/usr/src/cmd/halt/Makefile b/usr/src/cmd/halt/Makefile index 98d8eccee4..a515a0a1ef 100644 --- a/usr/src/cmd/halt/Makefile +++ b/usr/src/cmd/halt/Makefile @@ -21,6 +21,7 @@ # Copyright 2016 Toomas Soome <tsoome@me.com> # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018 Joyent, Inc. # PROG = halt @@ -60,10 +61,10 @@ install := TARGET = install clean := TARGET = clean clobber := TARGET = clobber lint := TARGET = lint -lint := LINTFLAGS = -u +lint := LINTFLAGS += -u -all: $(PROG) +all: $(PROG) install: all $(ROOTUSRSBINPROG) $(ROOTLINKS) $(ROOTSYMLINKS) $(SUBDIRS) diff --git a/usr/src/cmd/ldapcachemgr/cachemgr_change.c b/usr/src/cmd/ldapcachemgr/cachemgr_change.c index 85a15a1054..727851ffbc 100644 --- a/usr/src/cmd/ldapcachemgr/cachemgr_change.c +++ b/usr/src/cmd/ldapcachemgr/cachemgr_change.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #include <strings.h> @@ -33,6 +35,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <procfs.h> +#include <pthread.h> #include "cachemgr.h" extern admin_t current_admin; @@ -535,6 +538,8 @@ chg_cleanup_waiting_threads(void *arg) pid_t pid; int always = 1, waiting; + (void) pthread_setname_np(pthread_self(), "chg_cleanup_thr"); + if (op == NULL) { waiting = 1; type = CLEANUP_ALL; diff --git a/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c b/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c index bb352ae7c4..6650c9c221 100644 --- a/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c +++ b/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #ifdef SLP @@ -539,9 +541,12 @@ done: * parameter 'r' should be a pointer to an unsigned int containing * the requested interval at which the network should be queried. */ -void discover(void *r) { +void +discover(void *r) { unsigned short reqrefresh = *((unsigned int *)r); + (void) pthread_setname_np(pthread_self(), "discover"); + for (;;) { find_all_contexts("ldap", __cache_get_cfghandle, diff --git a/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c b/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c index 298e61fcb0..b9bc3f77b6 100644 --- a/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c +++ b/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c @@ -20,6 +20,8 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Copyright 2018 Joyent, Inc. */ #include <assert.h> @@ -1631,6 +1633,8 @@ getldap_serverInfo_op(info_op_t op, char *input, char **output) static time_t prev_refresh = 0, next_refresh = 0; ns_server_status_t changed = 0; + (void) pthread_setname_np(pthread_self(), "getldap_serverinfo"); + if (current_admin.debug_level >= DBG_ALL) { logit("getldap_serverInfo_op()...\n"); } @@ -2542,6 +2546,8 @@ getldap_refresh() int sig_done = 0; int dbg_level; + (void) pthread_setname_np(pthread_self(), "getldap_refresh"); + if (current_admin.debug_level >= DBG_ALL) { logit("getldap_refresh()...\n"); } @@ -2892,6 +2898,8 @@ remove_server_thread(void *arg) int up; rm_svr_t rms; + (void) pthread_setname_np(pthread_self(), "remove_server"); + up = contact_server(addr); rms.addr = addr; diff --git a/usr/src/cmd/mdb/common/mdb/mdb_proc.c b/usr/src/cmd/mdb/common/mdb/mdb_proc.c index 6c9f0aa5f4..33994c11e6 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_proc.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_proc.c @@ -1303,6 +1303,23 @@ pt_regstatus(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (pt_regs(addr, flags, argc, argv)); } +static void +pt_thread_name(mdb_tgt_t *t, mdb_tgt_tid_t tid, char *buf, size_t bufsize) +{ + char name[THREAD_NAME_MAX]; + + buf[0] = '\0'; + + if (t->t_pshandle == NULL || + Plwp_getname(t->t_pshandle, tid, name, sizeof (name)) != 0 || + name[0] == '\0') { + (void) mdb_snprintf(buf, bufsize, "%lu", tid); + return; + } + + (void) mdb_snprintf(buf, bufsize, "%lu [%s]", tid, name); +} + static int pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) { @@ -1311,6 +1328,7 @@ pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) int showargs = 0; int count; uintptr_t pc, sp; + char name[128]; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); @@ -1334,7 +1352,10 @@ pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) #else sp = gregs.gregs[R_SP]; #endif - mdb_printf("stack pointer for thread %p: %p\n", tid, sp); + + pt_thread_name(t, tid, name, sizeof (name)); + + mdb_printf("stack pointer for thread %s: %p\n", name, sp); if (pc != 0) mdb_printf("[ %0?lr %a() ]\n", sp, pc); diff --git a/usr/src/cmd/mdb/common/modules/genunix/findstack.c b/usr/src/cmd/mdb/common/modules/genunix/findstack.c index 12b90b8f7d..fc8a4f874b 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/findstack.c +++ b/usr/src/cmd/mdb/common/modules/genunix/findstack.c @@ -22,6 +22,7 @@ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright 2018 Joyent, Inc. */ #include <mdb/mdb_modapi.h> @@ -38,6 +39,12 @@ #include "thread.h" #include "sobj.h" +/* + * Parts of this file are shared between targets, but this section is only + * used for KVM and KMDB. + */ +#ifdef _KERNEL + int findstack_debug_on = 0; /* @@ -48,6 +55,7 @@ print_stack(uintptr_t sp, uintptr_t pc, uintptr_t addr, int argc, const mdb_arg_t *argv, int free_state) { int showargs = 0, count, err; + char tdesc[128] = ""; count = mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &showargs, NULL); @@ -57,8 +65,10 @@ print_stack(uintptr_t sp, uintptr_t pc, uintptr_t addr, if (argc > 1 || (argc == 1 && argv->a_type != MDB_TYPE_STRING)) return (DCMD_USAGE); - mdb_printf("stack pointer for thread %p%s: %p\n", - addr, (free_state ? " (TS_FREE)" : ""), sp); + (void) thread_getdesc(addr, B_TRUE, tdesc, sizeof (tdesc)); + + mdb_printf("stack pointer for thread %p%s (%s): %p\n", + addr, (free_state ? " (TS_FREE)" : ""), tdesc, sp); if (pc != 0) mdb_printf("[ %0?lr %a() ]\n", sp, pc); @@ -108,6 +118,8 @@ findstack_debug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *av) return (DCMD_OK); } +#endif /* _KERNEL */ + static void uppercase(char *p) { @@ -197,7 +209,7 @@ static stacks_entry_t **stacks_hash; static stacks_entry_t **stacks_array; static size_t stacks_array_size; -size_t +static size_t stacks_hash_entry(stacks_entry_t *sep) { size_t depth = sep->se_depth; @@ -224,7 +236,7 @@ stacks_hash_entry(stacks_entry_t *sep) * relative ordering, so we don't do the extra work of looking up symbols * for the stack addresses. */ -int +static int stacks_entry_comp_impl(stacks_entry_t *l, stacks_entry_t *r, uint_t forsort) { @@ -298,7 +310,7 @@ stacks_entry_comp_impl(stacks_entry_t *l, stacks_entry_t *r, return (0); } -int +static int stacks_entry_comp(const void *l_arg, const void *r_arg) { stacks_entry_t * const *lp = l_arg; @@ -368,7 +380,7 @@ stacks_cleanup(int force) } /*ARGSUSED*/ -int +static int stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg) { stacks_info_t *sip = cbarg; @@ -421,7 +433,7 @@ stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg) return (WALK_NEXT); } -int +static int stacks_run_tlist(mdb_pipe_t *tlist, stacks_info_t *si) { size_t idx; @@ -445,7 +457,7 @@ stacks_run_tlist(mdb_pipe_t *tlist, stacks_info_t *si) return (-1); } -int +static int stacks_run(int verbose, mdb_pipe_t *tlist) { stacks_info_t si; diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c index 425911d112..719206065b 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c +++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c @@ -21,7 +21,7 @@ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2017 Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. * Copyright (c) 2013 by Delphix. All rights reserved. */ @@ -164,14 +164,19 @@ ps_threadprint(uintptr_t addr, const void *data, void *private) if (prt_flags & PS_PRTTHREADS) mdb_printf("\tT %?a <%b>\n", addr, t->t_state, t_state_bits); - if (prt_flags & PS_PRTLWPS) - mdb_printf("\tL %?a ID: %u\n", t->t_lwp, t->t_tid); + if (prt_flags & PS_PRTLWPS) { + char desc[128] = ""; + + (void) thread_getdesc(addr, B_FALSE, desc, sizeof (desc)); + + mdb_printf("\tL %?a ID: %s\n", t->t_lwp, desc); + } return (WALK_NEXT); } typedef struct mdb_pflags_proc { - struct pid *p_pidp; + struct pid *p_pidp; ushort_t p_pidflag; uint_t p_proc_flag; uint_t p_flag; @@ -261,8 +266,8 @@ pflags(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) typedef struct mdb_ps_proc { char p_stat; - struct pid *p_pidp; - struct pid *p_pgidp; + struct pid *p_pidp; + struct pid *p_pgidp; struct cred *p_cred; struct sess *p_sessp; struct task *p_task; diff --git a/usr/src/cmd/mdb/common/modules/genunix/thread.c b/usr/src/cmd/mdb/common/modules/genunix/thread.c index 652e5af2d6..410f9973d8 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/thread.c +++ b/usr/src/cmd/mdb/common/modules/genunix/thread.c @@ -24,11 +24,13 @@ */ /* * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ #include <mdb/mdb_modapi.h> #include <mdb/mdb_ks.h> +#include <mdb/mdb_ctf.h> #include <sys/types.h> #include <sys/thread.h> #include <sys/lwp.h> @@ -38,6 +40,7 @@ #include <sys/disp.h> #include <sys/taskq_impl.h> #include <sys/stack.h> +#include "thread.h" #ifndef STACK_BIAS #define STACK_BIAS 0 @@ -561,6 +564,89 @@ thread_help(void) } /* + * Return a string description of the thread, including the ID and the thread + * name. + * + * If ->t_name is NULL, and we're a system thread, we'll do a little more + * spelunking to find a useful string to return. + */ +int +thread_getdesc(uintptr_t addr, boolean_t include_comm, + char *buf, size_t bufsize) +{ + char name[THREAD_NAME_MAX] = ""; + kthread_t t; + proc_t p; + + bzero(buf, bufsize); + + if (mdb_vread(&t, sizeof (kthread_t), addr) == -1) { + mdb_warn("failed to read kthread_t at %p", addr); + return (-1); + } + + if (t.t_tid == 0) { + taskq_t tq; + + if (mdb_vread(&tq, sizeof (taskq_t), + (uintptr_t)t.t_taskq) == -1) + tq.tq_name[0] = '\0'; + + if (t.t_name != NULL) { + if (mdb_readstr(buf, bufsize, + (uintptr_t)t.t_name) == -1) { + mdb_warn("error reading thread name"); + } + } else if (tq.tq_name[0] != '\0') { + (void) mdb_snprintf(buf, bufsize, "tq:%s", tq.tq_name); + } else { + mdb_snprintf(buf, bufsize, "%a()", t.t_startpc); + } + + return (buf[0] == '\0' ? -1 : 0); + } + + if (include_comm && mdb_vread(&p, sizeof (proc_t), + (uintptr_t)t.t_procp) == -1) { + mdb_warn("failed to read proc at %p", t.t_procp); + return (-1); + } + + if (t.t_name != NULL) { + if (mdb_readstr(name, sizeof (name), (uintptr_t)t.t_name) == -1) + mdb_warn("error reading thread name"); + + /* + * Just to be safe -- if mdb_readstr() succeeds, it always NUL + * terminates the output, but is unclear what it does on + * failure. In that case we attempt to show any partial content + * w/ the warning in case it's useful, but explicitly + * NUL-terminate to be safe. + */ + buf[bufsize - 1] = '\0'; + } + + if (name[0] != '\0') { + if (include_comm) { + (void) mdb_snprintf(buf, bufsize, "%s/%u [%s]", + p.p_user.u_comm, t.t_tid, name); + } else { + (void) mdb_snprintf(buf, bufsize, "%u [%s]", + t.t_tid, name); + } + } else { + if (include_comm) { + (void) mdb_snprintf(buf, bufsize, "%s/%u", + p.p_user.u_comm, t.t_tid); + } else { + (void) mdb_snprintf(buf, bufsize, "%u", t.t_tid); + } + } + + return (buf[0] == '\0' ? -1 : 0); +} + +/* * List a combination of kthread_t and proc_t. Add stack traces in verbose mode. */ int @@ -571,8 +657,6 @@ threadlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) uint_t verbose = FALSE; uint_t notaskq = FALSE; kthread_t t; - taskq_t tq; - proc_t p; char cmd[80]; mdb_arg_t cmdarg; @@ -618,50 +702,32 @@ threadlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if (t.t_state == TS_FREE) return (DCMD_OK); - if (mdb_vread(&p, sizeof (proc_t), (uintptr_t)t.t_procp) == -1) { - mdb_warn("failed to read proc at %p", t.t_procp); - return (DCMD_ERR); - } + if (!verbose) { + char desc[128]; + + if (thread_getdesc(addr, B_TRUE, desc, sizeof (desc)) == -1) + return (DCMD_ERR); - if (mdb_vread(&tq, sizeof (taskq_t), (uintptr_t)t.t_taskq) == -1) - tq.tq_name[0] = '\0'; + mdb_printf("%0?p %?p %?p %s\n", addr, t.t_procp, t.t_lwp, desc); + return (DCMD_OK); + } - if (verbose) { - mdb_printf("%0?p %?p %?p %3u %3d %?p\n", - addr, t.t_procp, t.t_lwp, t.t_cid, t.t_pri, t.t_wchan); + mdb_printf("%0?p %?p %?p %3u %3d %?p\n", + addr, t.t_procp, t.t_lwp, t.t_cid, t.t_pri, t.t_wchan); - mdb_inc_indent(2); + mdb_inc_indent(2); - mdb_printf("PC: %a", t.t_pc); - if (t.t_tid == 0) { - if (tq.tq_name[0] != '\0') - mdb_printf(" TASKQ: %s\n", tq.tq_name); - else - mdb_printf(" THREAD: %a()\n", t.t_startpc); - } else { - mdb_printf(" CMD: %s\n", p.p_user.u_psargs); - } + mdb_printf("PC: %a\n", t.t_pc); - mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", count); - cmdarg.a_type = MDB_TYPE_STRING; - cmdarg.a_un.a_str = cmd; + mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", count); + cmdarg.a_type = MDB_TYPE_STRING; + cmdarg.a_un.a_str = cmd; - (void) mdb_call_dcmd("findstack", addr, flags, 1, &cmdarg); + (void) mdb_call_dcmd("findstack", addr, flags, 1, &cmdarg); - mdb_dec_indent(2); + mdb_dec_indent(2); - mdb_printf("\n"); - } else { - mdb_printf("%0?p %?p %?p", addr, t.t_procp, t.t_lwp); - if (t.t_tid == 0) { - if (tq.tq_name[0] != '\0') - mdb_printf(" tq:%s\n", tq.tq_name); - else - mdb_printf(" %a()\n", t.t_startpc); - } else { - mdb_printf(" %s/%u\n", p.p_user.u_comm, t.t_tid); - } - } + mdb_printf("\n"); return (DCMD_OK); } @@ -716,7 +782,6 @@ int stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { kthread_t t; - proc_t p; uint64_t *ptr; /* pattern pointer */ caddr_t start; /* kernel stack start */ caddr_t end; /* kernel stack end */ @@ -730,6 +795,7 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) int i = 0; unsigned int ukmem_stackinfo; uintptr_t allthreads; + char tdesc[128] = ""; /* handle options */ if (mdb_getopts(argc, argv, @@ -775,7 +841,7 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) mdb_printf("%<u>%?s%</u>", "THREAD"); mdb_printf(" %<u>%?s%</u>", "STACK"); - mdb_printf("%<u>%s%</u>", " SIZE MAX CMD/LWPID or STARTPC"); + mdb_printf("%<u>%s%</u>", " SIZE MAX LWP"); mdb_printf("\n"); usize = KMEM_STKINFO_LOG_SIZE * sizeof (kmem_stkinfo_t); log = (kmem_stkinfo_t *)mdb_alloc(usize, UM_SLEEP); @@ -798,18 +864,15 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if (log[i].kthread == NULL) { continue; } - mdb_printf("%0?p %0?p %6x %3d%%", + + (void) thread_getdesc((uintptr_t)log[i].kthread, + B_TRUE, tdesc, sizeof (tdesc)); + + mdb_printf("%0?p %0?p %6x %3d%% %s\n", log[i].kthread, log[i].start, (uint_t)log[i].stksz, - (int)log[i].percent); - if (log[i].t_tid != 0) { - mdb_printf(" %s/%u\n", - log[i].cmd, log[i].t_tid); - } else { - mdb_printf(" %p (%a)\n", log[i].t_startpc, - log[i].t_startpc); - } + (int)log[i].percent, tdesc); } mdb_free((void *)log, usize); return (DCMD_OK); @@ -824,7 +887,7 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } mdb_printf("%<u>%?s%</u>", "THREAD"); mdb_printf(" %<u>%?s%</u>", "STACK"); - mdb_printf("%<u>%s%</u>", " SIZE CUR MAX CMD/LWPID"); + mdb_printf("%<u>%s%</u>", " SIZE CUR MAX LWP"); mdb_printf("\n"); } @@ -838,12 +901,6 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } - /* read proc */ - if (mdb_vread(&p, sizeof (proc_t), (uintptr_t)t.t_procp) == -1) { - mdb_warn("failed to read proc at %p\n", t.t_procp); - return (DCMD_ERR); - } - /* * Stack grows up or down, see thread_create(), * compute stack memory aera start and end (start < end). @@ -878,14 +935,10 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) mdb_printf(" %3d%%", percent); percent = 0; + (void) thread_getdesc(addr, B_TRUE, tdesc, sizeof (tdesc)); + if (ukmem_stackinfo == 0) { - mdb_printf(" n/a"); - if (t.t_tid == 0) { - mdb_printf(" %a()", t.t_startpc); - } else { - mdb_printf(" %s/%u", p.p_user.u_comm, t.t_tid); - } - mdb_printf("\n"); + mdb_printf(" n/a %s\n", tdesc); return (DCMD_OK); } @@ -958,12 +1011,9 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } else { mdb_printf(" n/a"); } - if (t.t_tid == 0) { - mdb_printf(" %a()", t.t_startpc); - } else { - mdb_printf(" %s/%u", p.p_user.u_comm, t.t_tid); - } - mdb_printf("\n"); + + mdb_printf(" %s\n", tdesc); + mdb_free((void *)ustack, usize + 8); return (DCMD_OK); } @@ -978,7 +1028,7 @@ stackinfo_help(void) "(an unsigned integer) is non zero at kthread creation time. "); mdb_printf("For example:\n"); mdb_printf( - " THREAD STACK SIZE CUR MAX CMD/LWPID\n"); + " THREAD STACK SIZE CUR MAX LWP\n"); mdb_printf( "ffffff014f5f2c20 ffffff0004153000 4f00 4%% 43%% init/1\n"); mdb_printf( @@ -1002,6 +1052,6 @@ stackinfo_help(void) "-h shows history, dead kthreads that used their " "kernel stack the most\n"); mdb_printf( - "\nSee Solaris Modular Debugger Guide for detailed usage.\n"); + "\nSee illumos Modular Debugger Guide for detailed usage.\n"); mdb_flush(); } diff --git a/usr/src/cmd/mdb/common/modules/genunix/thread.h b/usr/src/cmd/mdb/common/modules/genunix/thread.h index 18952fdc0a..901d962be8 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/thread.h +++ b/usr/src/cmd/mdb/common/modules/genunix/thread.h @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _THREAD_H @@ -58,6 +60,8 @@ void thread_state_to_text(uint_t, char *, size_t); int thread_text_to_state(const char *, uint_t *); void thread_walk_states(void (*)(uint_t, const char *, void *), void *); +int thread_getdesc(uintptr_t, boolean_t, char *, size_t); + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/nscd/cache.c b/usr/src/cmd/nscd/cache.c index 2ffb95c30d..288c6e767e 100644 --- a/usr/src/cmd/nscd/cache.c +++ b/usr/src/cmd/nscd/cache.c @@ -22,6 +22,7 @@ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright 2018 Joyent, Inc. */ /* @@ -1817,8 +1818,10 @@ init_cache_ctx(int i) { static void revalidate(nsc_ctx_t *ctx) { + (void) thr_setname(thr_self(), "revalidate"); + for (;;) { - int i, slp, interval, count; + int i, slp, interval, count; (void) rw_rdlock(&ctx->cfg_rwlp); slp = ctx->cfg.pos_ttl; @@ -1961,6 +1964,8 @@ static void do_update(nsc_lookup_args_t *in) { nss_pheader_t *phdr = (nss_pheader_t *)in->buffer; + (void) thr_setname(thr_self(), "do_update"); + /* update the length of the data buffer */ phdr->data_len = phdr->pbufsiz - phdr->data_off; @@ -2017,7 +2022,7 @@ nsc_invalidate(nsc_ctx_t *ctx, char *dbname, nsc_ctx_t **ctxs) static void ctx_invalidate(nsc_ctx_t *ctx) { - int i; + int i; nsc_entry_t *entry; char *me = "ctx_invalidate"; @@ -2190,6 +2195,8 @@ reaper(nsc_ctx_t *ctx) ulong_t nsc_entries; char *me = "reaper"; + (void) thr_setname(thr_self(), me); + for (;;) { (void) mutex_lock(&ctx->stats_mutex); nsc_entries = ctx->stats.entries; diff --git a/usr/src/cmd/nscd/nscd_frontend.c b/usr/src/cmd/nscd/nscd_frontend.c index 7ed5e71bca..134da3f280 100644 --- a/usr/src/cmd/nscd/nscd_frontend.c +++ b/usr/src/cmd/nscd/nscd_frontend.c @@ -22,6 +22,7 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2012 Milan Jurik. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #include <stdlib.h> @@ -89,6 +90,8 @@ server_tsd_bind(void *arg) { static void *value = 0; + (void) thr_setname(thr_self(), "server_tsd_bind"); + /* disable cancellation to avoid hangs if server threads disappear */ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); (void) thr_setspecific(server_key, value); @@ -132,7 +135,8 @@ server_destroy(void *arg) * get clearance */ int -_nscd_get_clearance(sema_t *sema) { +_nscd_get_clearance(sema_t *sema) +{ if (sema_trywait(&common_sema) == 0) { (void) thr_setspecific(lookup_state_key, NULL); return (0); @@ -151,7 +155,8 @@ _nscd_get_clearance(sema_t *sema) { * release clearance */ int -_nscd_release_clearance(sema_t *sema) { +_nscd_release_clearance(sema_t *sema) +{ int which; (void) thr_getspecific(lookup_state_key, (void**)&which); @@ -197,7 +202,7 @@ _nscd_restart_if_cfgfile_changed() static timestruc_t last_nsswitch_modified = { 0 }; static timestruc_t last_resolv_modified = { -1, 0 }; static mutex_t restarting_lock = DEFAULTMUTEX; - static int restarting = 0; + static int restarting = 0; int restart = 0; time_t now = time(NULL); char *me = "_nscd_restart_if_cfgfile_changed"; @@ -1477,6 +1482,8 @@ rts_mon(void) struct ifa_msghdr *ifam = &mbuf.ifam; char *me = "rts_mon"; + (void) thr_setname(thr_self(), me); + rt_sock = socket(PF_ROUTE, SOCK_RAW, 0); if (rt_sock < 0) { _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR) diff --git a/usr/src/cmd/nscd/nscd_getentctx.c b/usr/src/cmd/nscd/nscd_getentctx.c index 2fed9a5c82..f4e6b89fbc 100644 --- a/usr/src/cmd/nscd/nscd_getentctx.c +++ b/usr/src/cmd/nscd/nscd_getentctx.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #include <sys/ccompile.h> @@ -658,6 +660,8 @@ reclaim_getent_ctx(void *arg) nss_getent_t nssctx = { 0 }; char *me = "reclaim_getent_ctx"; + (void) thr_setname(thr_self(), me); + /*CONSTCOND*/ while (1) { @@ -744,7 +748,8 @@ reclaim_getent_ctx(void *arg) } static nscd_rc_t -_nscd_init_getent_ctx_monitor() { +_nscd_init_getent_ctx_monitor() +{ int errnum; char *me = "_nscd_init_getent_ctx_monitor"; @@ -763,7 +768,7 @@ _nscd_init_getent_ctx_monitor() { * start a thread to reclaim unused getent contexts */ if (thr_create(NULL, NULL, reclaim_getent_ctx, - NULL, THR_DETACHED, NULL) != 0) { + NULL, THR_DETACHED, NULL) != 0) { errnum = errno; _NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_ERROR) (me, "thr_create: %s\n", strerror(errnum)); diff --git a/usr/src/cmd/nscd/nscd_selfcred.c b/usr/src/cmd/nscd/nscd_selfcred.c index df4d2a2c5b..b6cdba8c7a 100644 --- a/usr/src/cmd/nscd/nscd_selfcred.c +++ b/usr/src/cmd/nscd/nscd_selfcred.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. + * Copyright 2018 Joyent Inc. */ #include <stdio.h> @@ -425,6 +426,8 @@ forker_monitor( char *fmri; char *me = "forker_monitor"; + (void) thr_setname(thr_self(), me); + /* wait until forker exits */ fpid = forker_pid; (void) selfcred_pulse(forking_door); @@ -1416,7 +1419,7 @@ check_uid(char *pid_name) static uid_t uid = 0; static uid_t euid = 0; int pfd; /* file descriptor for /proc/<pid>/psinfo */ - psinfo_t info; /* process information from /proc */ + psinfo_t info; /* process information from /proc */ if (uid == 0) { pid = getpid(); @@ -1466,6 +1469,8 @@ check_user_process(void *arg) int found; char *me = "check_user_process"; + (void) thr_setname(thr_self(), me); + for (;;) { (void) sleep(60); diff --git a/usr/src/cmd/nscd/nscd_smfmonitor.c b/usr/src/cmd/nscd/nscd_smfmonitor.c index bd2ff958ba..c5d5731ecd 100644 --- a/usr/src/cmd/nscd/nscd_smfmonitor.c +++ b/usr/src/cmd/nscd/nscd_smfmonitor.c @@ -21,6 +21,8 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #include <stdlib.h> @@ -107,6 +109,8 @@ set_smf_state(void *arg) int i; int st; + (void) thr_setname(thr_self(), "set_smf_state"); + /* * the forker nscd needs not monitor the state * of the client services diff --git a/usr/src/cmd/prstat/Makefile.com b/usr/src/cmd/prstat/Makefile.com index e317483142..96c1450b26 100644 --- a/usr/src/cmd/prstat/Makefile.com +++ b/usr/src/cmd/prstat/Makefile.com @@ -21,6 +21,7 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018, Joyent, Inc. # # cmd/prstat/Makefile.com # @@ -31,6 +32,7 @@ SRCS = $(OBJS:%.o=../%.c) include ../../Makefile.cmd +CSTD = $(CSTD_GNU99) CFLAGS += $(CCVERBOSE) CERRWARN += -_gcc=-Wno-parentheses LDLIBS += -lcurses -lproject diff --git a/usr/src/cmd/prstat/prstat.c b/usr/src/cmd/prstat/prstat.c index fc16e435f6..0ff4f51bcd 100644 --- a/usr/src/cmd/prstat/prstat.c +++ b/usr/src/cmd/prstat/prstat.c @@ -26,6 +26,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier + * Copyright 2018 Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -86,13 +87,13 @@ #define PSINFO_HEADER_PROC_LGRP \ " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/NLWP " #define PSINFO_HEADER_LWP \ -" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID " +" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWP " #define PSINFO_HEADER_LWP_LGRP \ -" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWPID " +" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWP " #define USAGE_HEADER_PROC \ " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP " #define USAGE_HEADER_LWP \ -" PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID " +" PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWP " #define USER_HEADER_PROC \ " NPROC USERNAME SWAP RSS MEMORY TIME CPU " #define USER_HEADER_LWP \ @@ -110,12 +111,12 @@ #define ZONE_HEADER_LWP \ "ZONEID NLWP SWAP RSS MEMORY TIME CPU ZONE " #define PSINFO_LINE \ -"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %-.16s/%d" +"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %s" #define PSINFO_LINE_LGRP \ -"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %-.16s/%d" +"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %s" #define USAGE_LINE \ "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\ -"%3.3s %3.3s %-.12s/%d" +"%3.3s %3.3s %s" #define USER_LINE \ "%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%" #define TASK_LINE \ @@ -149,8 +150,8 @@ static table_t prj_tbl = {0, 0, NULL}; /* selected projects */ static table_t tsk_tbl = {0, 0, NULL}; /* selected tasks */ static table_t lgr_tbl = {0, 0, NULL}; /* selected lgroups */ static zonetbl_t zone_tbl = {0, 0, NULL}; /* selected zones */ -static uidtbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */ -static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */ +static uidtbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */ +static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */ static uint_t total_procs; /* total number of procs */ static uint_t total_lwps; /* total number of lwps */ @@ -172,7 +173,7 @@ static long pagesize; /* default settings */ -static optdesc_t opts = { +optdesc_t opts = { 5, /* interval between updates, seconds */ 15, /* number of lines in top part */ 5, /* number of lines in bottom part */ @@ -361,11 +362,12 @@ list_print(list_t *list) char psize[6], prssize[6], pmem[6], pcpu[6], ptime[12]; char pstate[7], pnice[4], ppri[4]; char pname[LOGNAME_MAX+1]; + char name[PRFNSZ + THREAD_NAME_MAX + 2]; char projname[PROJNAME_MAX+1]; char zonename[ZONENAME_MAX+1]; float cpu, mem; double loadavg[3] = {0, 0, 0}; - int i, lwpid; + int i, n; if (list->l_size == 0) return; @@ -385,54 +387,59 @@ list_print(list_t *list) (void) putchar('\r'); (void) putp(t_ulon); + n = opts.o_cols; switch (list->l_type) { case LT_PROJECTS: if (opts.o_outpmode & OPT_LWPS) - (void) printf(PROJECT_HEADER_LWP); + n = printf(PROJECT_HEADER_LWP); else - (void) printf(PROJECT_HEADER_PROC); + n = printf(PROJECT_HEADER_PROC); break; case LT_TASKS: if (opts.o_outpmode & OPT_LWPS) - (void) printf(TASK_HEADER_LWP); + n = printf(TASK_HEADER_LWP); else - (void) printf(TASK_HEADER_PROC); + n = printf(TASK_HEADER_PROC); break; case LT_ZONES: if (opts.o_outpmode & OPT_LWPS) - (void) printf(ZONE_HEADER_LWP); + n = printf(ZONE_HEADER_LWP); else - (void) printf(ZONE_HEADER_PROC); + n = printf(ZONE_HEADER_PROC); break; case LT_USERS: if (opts.o_outpmode & OPT_LWPS) - (void) printf(USER_HEADER_LWP); + n = printf(USER_HEADER_LWP); else - (void) printf(USER_HEADER_PROC); + n = printf(USER_HEADER_PROC); break; case LT_LWPS: if (opts.o_outpmode & OPT_LWPS) { if (opts.o_outpmode & OPT_PSINFO) { if (opts.o_outpmode & OPT_LGRP) - (void) printf(PSINFO_HEADER_LWP_LGRP); + n = printf(PSINFO_HEADER_LWP_LGRP); else - (void) printf(PSINFO_HEADER_LWP); + n = printf(PSINFO_HEADER_LWP); } if (opts.o_outpmode & OPT_MSACCT) - (void) printf(USAGE_HEADER_LWP); + n = printf(USAGE_HEADER_LWP); } else { if (opts.o_outpmode & OPT_PSINFO) { if (opts.o_outpmode & OPT_LGRP) - (void) printf(PSINFO_HEADER_PROC_LGRP); + n = printf(PSINFO_HEADER_PROC_LGRP); else - (void) printf(PSINFO_HEADER_PROC); + n = printf(PSINFO_HEADER_PROC); } if (opts.o_outpmode & OPT_MSACCT) - (void) printf(USAGE_HEADER_PROC); + n = printf(USAGE_HEADER_PROC); } break; } + /* Pad out the header line so the underline spans the whole width */ + if ((opts.o_outpmode & OPT_TERMCAP) && n < opts.o_cols) + (void) printf("%*s", (int)(opts.o_cols - n), ""); + (void) putp(t_uloff); (void) putp(t_eol); (void) putchar('\n'); @@ -499,15 +506,14 @@ list_print(list_t *list) break; case LT_LWPS: lwp = list->l_ptrs[i]; - if (opts.o_outpmode & OPT_LWPS) - lwpid = lwp->li_info.pr_lwp.pr_lwpid; - else - lwpid = lwp->li_info.pr_nlwp + - lwp->li_info.pr_nzomb; + + format_name(lwp, name, sizeof (name)); + pwd_getname(lwp->li_info.pr_uid, pname, sizeof (pname), opts.o_outpmode & OPT_NORESOLVE, opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC), LOGIN_WIDTH); + if (opts.o_outpmode & OPT_PSINFO) { Format_size(psize, lwp->li_info.pr_size, 6); Format_size(prssize, lwp->li_info.pr_rssize, 6); @@ -536,21 +542,17 @@ list_print(list_t *list) lwp->li_info.pr_time.tv_sec, 10); if (opts.o_outpmode & OPT_TTY) (void) putchar('\r'); - stripfname(lwp->li_info.pr_fname); if (opts.o_outpmode & OPT_LGRP) { (void) printf(PSINFO_LINE_LGRP, (int)lwp->li_info.pr_pid, pname, psize, prssize, pstate, ppri, pnice, ptime, pcpu, - (int)lwp->li_info.pr_lwp.pr_lgrp, - lwp->li_info.pr_fname, lwpid); + lwp->li_info.pr_lwp.pr_lgrp, name); } else { (void) printf(PSINFO_LINE, (int)lwp->li_info.pr_pid, pname, - psize, prssize, - pstate, ppri, pnice, - ptime, pcpu, - lwp->li_info.pr_fname, lwpid); + psize, prssize, pstate, ppri, pnice, + ptime, pcpu, name); } (void) putp(t_eol); (void) putchar('\n'); @@ -570,12 +572,11 @@ list_print(list_t *list) Format_pct(lat, lwp->li_lat, 4); if (opts.o_outpmode & OPT_TTY) (void) putchar('\r'); - stripfname(lwp->li_info.pr_fname); (void) printf(USAGE_LINE, (int)lwp->li_info.pr_pid, pname, usr, sys, trp, tfl, dfl, lck, slp, lat, vcx, icx, scl, sig, - lwp->li_info.pr_fname, lwpid); + name); (void) putp(t_eol); (void) putchar('\n'); } @@ -877,6 +878,27 @@ add_proc(psinfo_t *psinfo) } static void +get_lwpname(pid_t pid, id_t lwpid, char *buf, size_t bufsize) +{ + char *path = NULL; + int fd; + + buf[0] = '\0'; + + if (asprintf(&path, "/proc/%d/lwp/%d/lwpname", + (int)pid, (int)lwpid) == -1) + return; + + if ((fd = open(path, O_RDONLY)) != -1) { + (void) read(fd, buf, bufsize); + buf[bufsize - 1] = '\0'; + (void) close(fd); + } + + free(path); +} + +static void add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags) { lwp_info_t *lwp; @@ -891,6 +913,7 @@ add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags) (void) memcpy(&lwp->li_info, psinfo, sizeof (psinfo_t) - sizeof (lwpsinfo_t)); (void) memcpy(&lwp->li_info.pr_lwp, lwpsinfo, sizeof (lwpsinfo_t)); + get_lwpname(pid, lwpid, lwp->li_lwpname, sizeof (lwp->li_lwpname)); } static void @@ -1113,7 +1136,7 @@ list_refresh(list_t *list) } static void -curses_on() +curses_on(void) { if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) { (void) initscr(); @@ -1124,7 +1147,7 @@ curses_on() } static void -curses_off() +curses_off(void) { if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) { (void) putp(t_rmcup); @@ -1135,26 +1158,40 @@ curses_off() } static int -nlines() +nlines(int *linesp, int *colsp) { struct winsize ws; char *envp; int n; + + *linesp = -1; + *colsp = -1; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) { if (ws.ws_row > 0) - return (ws.ws_row); + *linesp = ws.ws_row; + if (ws.ws_col > 0) + *colsp = ws.ws_col; + if (ws.ws_row > 0 && ws.ws_col > 0) + return (0); } - if (envp = getenv("LINES")) { + + if ((envp = getenv("LINES")) != NULL) { if ((n = Atoi(envp)) > 0) { opts.o_outpmode &= ~OPT_USEHOME; - return (n); + *linesp = n; + } + } + if ((envp = getenv("COLUMNS")) != NULL) { + if ((n = Atoi(envp)) > 0) { + *colsp = n; } } - return (-1); + + return ((*linesp > 0 && *colsp > 0) ? 0 : -1); } static void -setmovecur() +setmovecur(void) { int i, n; if ((opts.o_outpmode & OPT_FULLSCREEN) && @@ -1184,17 +1221,19 @@ setmovecur() } static int -setsize() +setsize(void) { static int oldn = 0; - int n; + int cols, n, ret; if (opts.o_outpmode & OPT_FULLSCREEN) { - n = nlines(); + ret = nlines(&n, &cols); + if (ret != -1) + opts.o_cols = cols; if (n == oldn) return (0); oldn = n; - if (n == -1) { + if (ret == -1) { opts.o_outpmode &= ~OPT_USEHOME; setmovecur(); /* set default window size */ return (1); diff --git a/usr/src/cmd/prstat/prstat.h b/usr/src/cmd/prstat/prstat.h index 293123c5b9..e205a98bd2 100644 --- a/usr/src/cmd/prstat/prstat.h +++ b/usr/src/cmd/prstat/prstat.h @@ -26,6 +26,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier + * Copyright 2018 Joyent, Inc. All rights reserved. */ #ifndef _PRSTAT_H @@ -113,6 +114,7 @@ typedef struct lwp_info { ulong_t li_icx; /* involuntary context switches */ ulong_t li_scl; /* system calls */ ulong_t li_sig; /* received signals */ + char li_lwpname[THREAD_NAME_MAX]; struct lwp_info *li_next; /* pointer to next lwp */ struct lwp_info *li_prev; /* pointer to previous lwp */ } lwp_info_t; @@ -167,8 +169,11 @@ typedef struct optdesc { int o_count; /* number of iterations */ int o_outpmode; /* selected output mode */ int o_sortorder; /* +1 ascending, -1 descending */ + int o_cols; /* number of columns */ } optdesc_t; +extern optdesc_t opts; + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/prstat/prutil.c b/usr/src/cmd/prstat/prutil.c index 0f9cbd6c4d..551c72cc8a 100644 --- a/usr/src/cmd/prstat/prutil.c +++ b/usr/src/cmd/prstat/prutil.c @@ -25,6 +25,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier + * Copyright 2018 Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -324,14 +325,16 @@ getzonename(zoneid_t zoneid, char *str, size_t len, int trunc, size_t width) /* * Remove all unprintable characters from process name */ -void -stripfname(char *buf) +static void +stripfname(char *buf, size_t bufsize, const char *pname) { int bytesleft = PRFNSZ; wchar_t wchar; int length; char *cp; + (void) strlcpy(buf, pname, bufsize); + buf[bytesleft - 1] = '\0'; for (cp = buf; *cp != '\0'; cp += length) { @@ -351,3 +354,71 @@ stripfname(char *buf) bytesleft -= length; } } + + +/* + * prstat has always implicitly wanted a terminal width of at least 80 columns + * (when a TTY is present). If run in a terminal narrower than 80 columns, + * prstat output may wrap. For wider terminals, we allow the last column to use + * the additional space. + * + * We never truncate if using -c, or not outputting to a TTY. + */ +static int +format_namewidth(void) +{ + int prefixlen = 0; + + if (opts.o_cols == 0 || !(opts.o_outpmode & (OPT_TERMCAP | OPT_TRUNC))) + return (0); + + if (opts.o_outpmode & OPT_PSINFO) { + if (opts.o_outpmode & OPT_LGRP) + prefixlen = 64; + else + prefixlen = 59; + } else if (opts.o_outpmode & OPT_MSACCT) { + prefixlen = 64; + } + + return (opts.o_cols - prefixlen); +} + +void +format_name(lwp_info_t *lwp, char *buf, size_t buflen) +{ + int pname_width = PRFNSZ; + char nr_suffix[20]; + char pname[PRFNSZ]; + int width; + int n; + + stripfname(pname, sizeof (pname), lwp->li_info.pr_fname); + + if (opts.o_outpmode & OPT_LWPS) { + n = snprintf(nr_suffix, sizeof (nr_suffix), "%d", + lwp->li_info.pr_lwp.pr_lwpid); + } else { + n = snprintf(nr_suffix, sizeof (nr_suffix), "%d", + lwp->li_info.pr_nlwp + lwp->li_info.pr_nzomb); + } + + width = format_namewidth(); + + /* If we're over budget, truncate the process name not the LWP part. */ + if (strlen(pname) > (width - n - 1)) { + pname_width = width - n - 1; + pname[pname_width - 1] = '*'; + } + + if ((opts.o_outpmode & OPT_LWPS) && lwp->li_lwpname[0] != '\0') { + n = snprintf(buf, buflen, "%.*s/%s [%s]", pname_width, + pname, nr_suffix, lwp->li_lwpname); + } else { + n = snprintf(buf, buflen, "%.*s/%s", pname_width, + pname, nr_suffix); + } + + if (width > 0 && strlen(buf) > width) + buf[width] = '\0'; +} diff --git a/usr/src/cmd/prstat/prutil.h b/usr/src/cmd/prstat/prutil.h index cfa2133714..ae2dbe5a93 100644 --- a/usr/src/cmd/prstat/prutil.h +++ b/usr/src/cmd/prstat/prutil.h @@ -25,6 +25,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier + * Copyright 2018, Joyent, Inc. */ #ifndef _PRUTIL_H @@ -54,7 +55,7 @@ extern int Setrlimit(); extern void Priocntl(char *); extern void getprojname(projid_t, char *, size_t, int, int, size_t); extern void getzonename(projid_t, char *, size_t, int, size_t); -extern void stripfname(char *); +extern void format_name(lwp_info_t *, char *, size_t); #ifdef __cplusplus } diff --git a/usr/src/cmd/ps/ps.c b/usr/src/cmd/ps/ps.c index 78dabbccfe..1a3e91689a 100644 --- a/usr/src/cmd/ps/ps.c +++ b/usr/src/cmd/ps/ps.c @@ -27,11 +27,11 @@ */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * ps -- print things about processes. @@ -108,6 +108,7 @@ enum fname { /* enumeration of field names */ F_SID, /* session id */ F_PSR, /* bound processor */ F_LWP, /* lwp-id */ + F_LWPNAME, /* lwp name */ F_NLWP, /* number of lwps */ F_OPRI, /* old priority (obsolete) */ F_PRI, /* new priority */ @@ -177,6 +178,7 @@ static struct def_field fname[] = { { "sid", "SID", 5, 5 }, { "psr", "PSR", 3, 2 }, { "lwp", "LWP", 6, 2 }, + { "lwpname", "LWPNAME", 32, 8 }, { "nlwp", "NLWP", 4, 2 }, { "opri", "PRI", 3, 2 }, { "pri", "PRI", 3, 2 }, @@ -211,8 +213,8 @@ static struct def_field fname[] = { { "zone", "ZONE", 8, 8 }, { "zoneid", "ZONEID", 5, 5 }, { "ctid", "CTID", 5, 5 }, - { "lgrp", "LGRP", 4, 2 }, - { "dmodel", "DMODEL", 6, 6 }, + { "lgrp", "LGRP", 4, 2 }, + { "dmodel", "DMODEL", 6, 6 }, }; #define NFIELDS (sizeof (fname) / sizeof (fname[0])) @@ -803,6 +805,7 @@ stdmain(int argc, char **argv) (void) printf("%-*s", f->width, f->header); break; + case F_LWPNAME: case F_FNAME: case F_COMM: case F_ARGS: @@ -1178,7 +1181,8 @@ parse_format(char *arg) } for (df = &fname[0]; df < &fname[NFIELDS]; df++) if (strcmp(name, df->fname) == 0) { - if (strcmp(name, "lwp") == 0) + if (strcmp(name, "lwp") == 0 || + strcmp(name, "lwpname") == 0) Lflg++; break; } @@ -1754,6 +1758,27 @@ print_field(psinfo_t *psinfo, struct field *f, const char *ttyp) case F_LWP: (void) printf("%*d", width, (int)psinfo->pr_lwp.pr_lwpid); break; + case F_LWPNAME: { + char lwpname[THREAD_NAME_MAX] = ""; + char *path = NULL; + int fd; + + if (asprintf(&path, "%s/%d/lwp/%d/lwpname", procdir, + (int)psinfo->pr_pid, (int)psinfo->pr_lwp.pr_lwpid) != -1 && + (fd = open(path, O_RDONLY)) != -1) { + (void) read(fd, lwpname, sizeof (lwpname)); + lwpname[THREAD_NAME_MAX - 1] = '\0'; + (void) close(fd); + } + + free(path); + + if (f->next != NULL) + (void) printf("%-*s", width, lwpname); + else + (void) printf("%s", lwpname); + break; + } case F_NLWP: (void) printf("%*d", width, psinfo->pr_nlwp + psinfo->pr_nzomb); break; @@ -2077,7 +2102,7 @@ print_zombie_field(psinfo_t *psinfo, struct field *f, const char *ttyp) static void pr_fields(psinfo_t *psinfo, const char *ttyp, - void (*print_fld)(psinfo_t *, struct field *, const char *)) + void (*print_fld)(psinfo_t *, struct field *, const char *)) { struct field *f; @@ -2367,7 +2392,7 @@ przom(psinfo_t *psinfo) } if (fflg) { int width = fname[F_STIME].width; - (void) printf(" %*.*s", width, width, "-"); /* STIME */ + (void) printf(" %*.*s", width, width, "-"); /* STIME */ } (void) printf(" %-8.14s", "?"); /* TTY */ @@ -2447,9 +2472,9 @@ delta_secs(const timestruc_t *start) /* * Returns the following: * - * 0 No error - * EINVAL Invalid number - * ERANGE Value exceeds (min, max) range + * 0 No error + * EINVAL Invalid number + * ERANGE Value exceeds (min, max) range */ static int str2id(const char *p, pid_t *val, long min, long max) @@ -2484,9 +2509,9 @@ str2id(const char *p, pid_t *val, long min, long max) /* * Returns the following: * - * 0 No error - * EINVAL Invalid number - * ERANGE Value exceeds (min, max) range + * 0 No error + * EINVAL Invalid number + * ERANGE Value exceeds (min, max) range */ static int str2uid(const char *p, uid_t *val, unsigned long min, unsigned long max) diff --git a/usr/src/cmd/ptools/pstack/pstack.c b/usr/src/cmd/ptools/pstack/pstack.c index 0515ff62d0..d1d55d2280 100644 --- a/usr/src/cmd/ptools/pstack/pstack.c +++ b/usr/src/cmd/ptools/pstack/pstack.c @@ -21,6 +21,8 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #include <sys/isa_defs.h> @@ -137,7 +139,7 @@ static int thr_stack(const td_thrhandle_t *, void *); static void free_threadinfo(void); static struct threadinfo *find_thread(id_t); static int all_call_stacks(pstack_handle_t *, int); -static void tlhead(id_t, id_t); +static void tlhead(id_t, id_t, const char *); static int print_frame(void *, prgregset_t, uint_t, const long *); static void print_zombie(struct ps_prochandle *, struct threadinfo *); static void print_syscall(const lwpstatus_t *, prgregset_t); @@ -380,6 +382,7 @@ static int thread_call_stack(void *data, const lwpstatus_t *psp, const lwpsinfo_t *pip) { + char lwpname[THREAD_NAME_MAX] = ""; pstack_handle_t *h = data; lwpstatus_t lwpstatus; struct threadinfo *tip; @@ -391,7 +394,10 @@ thread_call_stack(void *data, const lwpstatus_t *psp, if ((tip = find_thread(pip->pr_lwpid)) == NULL) return (0); - tlhead(tip->threadid, pip->pr_lwpid); + (void) Plwp_getname(h->proc, pip->pr_lwpid, + lwpname, sizeof (lwpname)); + + tlhead(tip->threadid, pip->pr_lwpid, lwpname); tip->threadid = 0; /* finish eliminating tid */ if (psp) call_stack(h, psp); @@ -410,15 +416,19 @@ thread_call_stack(void *data, const lwpstatus_t *psp, static int lwp_call_stack(void *data, - const lwpstatus_t *psp, const lwpsinfo_t *pip) + const lwpstatus_t *psp, const lwpsinfo_t *pip) { + char lwpname[THREAD_NAME_MAX] = ""; pstack_handle_t *h = data; if (!proc_lwp_in_set(h->lwps, pip->pr_lwpid)) return (0); h->count++; - tlhead(0, pip->pr_lwpid); + (void) Plwp_getname(h->proc, pip->pr_lwpid, + lwpname, sizeof (lwpname)); + + tlhead(0, pip->pr_lwpid, lwpname); if (psp) call_stack(h, psp); else @@ -462,7 +472,7 @@ all_call_stacks(pstack_handle_t *h, int dothreads) if ((tid = tip->threadid) != 0) { (void) memcpy(lwpstatus.pr_reg, tip->regs, sizeof (prgregset_t)); - tlhead(tid, tip->lwpid); + tlhead(tid, tip->lwpid, NULL); if (tip->state == TD_THR_ZOMBIE) print_zombie(Pr, tip); else @@ -475,23 +485,49 @@ all_call_stacks(pstack_handle_t *h, int dothreads) return (0); } +/* The width of the header */ +#define HEAD_WIDTH (62) static void -tlhead(id_t threadid, id_t lwpid) +tlhead(id_t threadid, id_t lwpid, const char *name) { + char buf[128] = { 0 }; + char num[16]; + ssize_t amt = 0; + int i; + if (threadid == 0 && lwpid == 0) return; - (void) printf("-----------------"); + if (lwpid > 0) { + (void) snprintf(num, sizeof (num), "%d", (int)lwpid); + (void) strlcat(buf, "thread# ", sizeof (buf)); + (void) strlcat(buf, num, sizeof (buf)); + } + + if (threadid > 0) { + (void) snprintf(num, sizeof (num), "%d", (int)threadid); + if (lwpid > 0) + (void) strlcat(buf, " / ", sizeof (buf)); + (void) strlcat(buf, "lwp# ", sizeof (buf)); + (void) strlcat(buf, num, sizeof (buf)); + } + + if (name != NULL && strlen(name) > 0) { + (void) strlcat(buf, " [", sizeof (buf)); + (void) strlcat(buf, name, sizeof (buf)); + (void) strlcat(buf, "]", sizeof (buf)); + } - if (threadid && lwpid) - (void) printf(" lwp# %d / thread# %d ", - (int)lwpid, (int)threadid); - else if (threadid) - (void) printf("--------- thread# %d ", (int)threadid); - else if (lwpid) - (void) printf(" lwp# %d ------------", (int)lwpid); + amt = (HEAD_WIDTH - strlen(buf) - 2); + if (amt < 4) + amt = 4; - (void) printf("--------------------\n"); + for (i = 0; i < amt / 2; i++) + (void) putc('-', stdout); + (void) printf(" %s ", buf); + for (i = 0; i < (amt / 2) + (amt % 2); i++) + (void) putc('-', stdout); + (void) putc('\n', stdout); } /*ARGSUSED*/ diff --git a/usr/src/cmd/sgs/elfdump/common/corenote.c b/usr/src/cmd/sgs/elfdump/common/corenote.c index 0777025523..a5ba4e31b8 100644 --- a/usr/src/cmd/sgs/elfdump/common/corenote.c +++ b/usr/src/cmd/sgs/elfdump/common/corenote.c @@ -1256,6 +1256,20 @@ dump_prstatus(note_state_t *state, const char *title) } +static void +dump_lwpname(note_state_t *state, const char *title) +{ + const sl_prlwpname_layout_t *layout = state->ns_arch->prlwpname; + + indent_enter(state, title, &layout->pr_lwpid); + + PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid); + PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_LWPNAME), pr_lwpname); + + indent_exit(state); +} + + /* * Print percent from 16-bit binary fraction [0 .. 1] * Round up .01 to .1 to indicate some small percentage (the 0x7000 below). @@ -1909,6 +1923,11 @@ corenote(Half mach, int do_swap, Word type, state.ns_v2col = 54; dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_T)); return (CORENOTE_R_OK); + + case NT_LWPNAME: + state.ns_vcol = 20; + dump_lwpname(&state, MSG_ORIG(MSG_CNOTE_DESC_PRLWPNAME_T)); + return (CORENOTE_R_OK); } return (CORENOTE_R_BADTYPE); diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg index e7488d5373..253ea4a788 100644 --- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg @@ -22,6 +22,7 @@ # # Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2012 DEY Storage Systems, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # @ _START_ @@ -469,6 +470,7 @@ @ MSG_CNOTE_DESC_STRUCT_UTSNAME "desc: (struct utsname)" @ MSG_CNOTE_DESC_PRFDINFO_T "desc: (prfdinfo_t)" @ MSG_CNOTE_DESC_PRSECFLAGS_T "desc: (prsecflags_t)" +@ MSG_CNOTE_DESC_PRLWPNAME_T "desc: (prlwpname_t)" @ MSG_CNOTE_FMT_LINE "%*s%-*s%s" @ MSG_CNOTE_FMT_LINE_2UP "%*s%-*s%-*s%-*s%s" @@ -535,6 +537,7 @@ @ MSG_CNOTE_T_PR_LWP "pr_lwp:" @ MSG_CNOTE_T_PR_LWPHOLD "pr_lwphold:" @ MSG_CNOTE_T_PR_LWPID "pr_lwpid:" +@ MSG_CNOTE_T_PR_LWPNAME "pr_lwpname:" @ MSG_CNOTE_T_PR_LWPPEND "pr_lwppend:" @ MSG_CNOTE_T_PR_NAME "pr_name:" @ MSG_CNOTE_T_PR_NGROUPS "pr_ngroups:" diff --git a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c index f7af1c1543..674972dc22 100644 --- a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c +++ b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c @@ -11,6 +11,7 @@ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ /* @@ -58,3 +59,4 @@ timestruc_t ts; struct utsname uts; prfdinfo_t ptfd; prsecflags_t psf; +prlwpname_t psn; diff --git a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c index d90363c5de..522c974fbd 100644 --- a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c +++ b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c @@ -24,11 +24,12 @@ * Use is subject to license terms. * * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ /* * This program is used to generate the contents of the - * struct_layout_XXX.c files that contain per-archtecture + * struct_layout_XXX.c files that contain per-architecture * structure layout information. * * Although not part of elfdump, it is built by the makefile @@ -599,6 +600,15 @@ gen_prsecflags(void) END; } +static void +gen_prlwpname(void) +{ + START(prlwpname, prlwpname_t); + SCALAR_FIELD(prlwpname_t, pr_lwpid, 0); + ARRAY_FIELD(prlwpname_t, pr_lwpname, 0); + END; +} + /*ARGSUSED*/ int main(int argc, char *argv[]) @@ -640,6 +650,7 @@ main(int argc, char *argv[]) gen_utsname(); gen_prfdinfo(); gen_prsecflags(); + gen_prlwpname(); /* * Generate the full arch_layout description @@ -668,6 +679,7 @@ main(int argc, char *argv[]) (void) printf(fmt, "utsname"); (void) printf(fmt, "prfdinfo"); (void) printf(fmt, "prsecflags"); + (void) printf(fmt, "prlwpname"); (void) printf("};\n"); /* diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout.h b/usr/src/cmd/sgs/elfdump/common/struct_layout.h index b0592d6909..022640e906 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout.h +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout.h @@ -26,6 +26,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #ifndef _STRUCT_LAYOUT_H @@ -98,7 +99,7 @@ typedef struct { */ typedef union { char sld_i8; - uchar_t sld_ui8; + uchar_t sld_ui8; short sld_i16; ushort_t sld_ui16; int32_t sld_i32; @@ -535,6 +536,12 @@ typedef struct { sl_field_t pr_upper; } sl_prsecflags_layout_t; +typedef struct { + sl_field_t sizeof_struct; + sl_field_t pr_lwpid; + sl_field_t pr_lwpname; +} sl_prlwpname_layout_t; + /* * This type collects all of the layout definitions for * a given architecture. @@ -561,6 +568,7 @@ typedef struct { const sl_utsname_layout_t *utsname; /* struct utsname */ const sl_prfdinfo_layout_t *prfdinfo; /* prdinfo_t */ const sl_prsecflags_layout_t *prsecflags; /* prsecflags_t */ + const sl_prlwpname_layout_t *prlwpname; /* prlwpname_t */ } sl_arch_layout_t; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c index 2b9469a022..42260b1e43 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c @@ -25,6 +25,7 @@ */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #include <struct_layout.h> @@ -387,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = { }; +static const sl_prlwpname_layout_t prlwpname_layout = { + { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */ + { 0, 8, 0, 0 }, /* pr_lwpid */ + { 8, 1, 32, 0 }, /* pr_lwpname[] */ +}; + + static const sl_arch_layout_t layout_amd64 = { @@ -411,6 +419,7 @@ static const sl_arch_layout_t layout_amd64 = { &utsname_layout, &prfdinfo_layout, &prsecflags_layout, + &prlwpname_layout, }; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c index 6a516bc225..de104e90ec 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c @@ -25,6 +25,7 @@ */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #include <struct_layout.h> @@ -387,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = { }; +static const sl_prlwpname_layout_t prlwpname_layout = { + { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */ + { 0, 8, 0, 0 }, /* pr_lwpid */ + { 8, 1, 32, 0 }, /* pr_lwpname[] */ +}; + + static const sl_arch_layout_t layout_i386 = { @@ -411,6 +419,7 @@ static const sl_arch_layout_t layout_i386 = { &utsname_layout, &prfdinfo_layout, &prsecflags_layout, + &prlwpname_layout, }; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c index 94760c3d82..ead0ae6b7b 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c @@ -25,7 +25,9 @@ */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ + #include <struct_layout.h> @@ -386,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = { }; +static const sl_prlwpname_layout_t prlwpname_layout = { + { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */ + { 0, 8, 0, 0 }, /* pr_lwpid */ + { 8, 1, 32, 0 }, /* pr_lwpname[] */ +}; + + static const sl_arch_layout_t layout_sparc = { @@ -410,6 +419,7 @@ static const sl_arch_layout_t layout_sparc = { &utsname_layout, &prfdinfo_layout, &prsecflags_layout, + &prlwpname_layout, }; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c index a194d8136a..00eaae9146 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c @@ -25,6 +25,7 @@ */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #include <struct_layout.h> @@ -387,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = { }; +static const sl_prlwpname_layout_t prlwpname_layout = { + { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */ + { 0, 8, 0, 0 }, /* pr_lwpid */ + { 8, 1, 32, 0 }, /* pr_lwpname[] */ +}; + + static const sl_arch_layout_t layout_sparcv9 = { @@ -411,6 +419,7 @@ static const sl_arch_layout_t layout_sparcv9 = { &utsname_layout, &prfdinfo_layout, &prsecflags_layout, + &prlwpname_layout, }; diff --git a/usr/src/cmd/sgs/libconv/Makefile.com b/usr/src/cmd/sgs/libconv/Makefile.com index c6287c433c..1bb482f706 100644 --- a/usr/src/cmd/sgs/libconv/Makefile.com +++ b/usr/src/cmd/sgs/libconv/Makefile.com @@ -21,7 +21,7 @@ # # Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2018, Joyent, Inc. +# Copyright 2018 Joyent, Inc. # LIBRARY = libconv.a @@ -124,8 +124,8 @@ $(LINTOUT64) := LDLIBS += -ldemangle-sys SGSMSGTARG= $(BLTOBJS:%_msg.o=../common/%.msg) -LINTFLAGS += -u -LINTFLAGS64 += -u +LINTFLAGS += -u -erroff=E_NAME_DECL_NOT_USED_DEF2 +LINTFLAGS64 += -u -erroff=E_NAME_DECL_NOT_USED_DEF2 CLEANFILES += $(BLTDATA) $(LINTOUTS) bld_vernote vernote.s CLOBBERFILES += $(LINTLIBS) diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c index 02b3e5d59b..dc9b8022f3 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.c +++ b/usr/src/cmd/sgs/libconv/common/corenote.c @@ -58,9 +58,10 @@ conv_cnote_type(Word type, Conv_fmt_flags_t fmt_flags, MSG_NT_LWPSINFO, MSG_NT_PRPRIV, MSG_NT_PRPRIVINFO, MSG_NT_CONTENT, MSG_NT_ZONENAME, MSG_NT_FDINFO, - MSG_NT_SPYMASTER, MSG_NT_SECFLAGS + MSG_NT_SPYMASTER, MSG_NT_SECFLAGS, + MSG_NT_LWPNAME, }; -#if NT_NUM != NT_SECFLAGS +#if NT_NUM != NT_LWPNAME #error "NT_NUM has grown. Update core note types[]" #endif static const conv_ds_msg_t ds_types = { diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg index b55e67ec07..a36f2bddf7 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.msg +++ b/usr/src/cmd/sgs/libconv/common/corenote.msg @@ -49,6 +49,7 @@ @ MSG_NT_FDINFO "[ NT_FDINFO ]" @ MSG_NT_SPYMASTER "[ NT_SPYMASTER ]" @ MSG_NT_SECFLAGS "[ NT_SECFLAGS ]" +@ MSG_NT_LWPNAME "[ NT_LWPNAME ]" @ MSG_AUXV_AF_SUN_SETUGID "AF_SUN_SETUGID" diff --git a/usr/src/cmd/svc/startd/graph.c b/usr/src/cmd/svc/startd/graph.c index 62fbbf1514..0e5253a281 100644 --- a/usr/src/cmd/svc/startd/graph.c +++ b/usr/src/cmd/svc/startd/graph.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018 Joyent, Inc. * Copyright (c) 2015, Syneto S.R.L. All rights reserved. * Copyright 2016 Toomas Soome <tsoome@me.com> * Copyright 2016 RackTop Systems. @@ -576,7 +577,7 @@ typedef enum { typedef int (*graph_walk_cb_t)(graph_vertex_t *, void *); typedef struct graph_walk_info { - graph_walk_dir_t gi_dir; + graph_walk_dir_t gi_dir; uchar_t *gi_visited; /* vertex bitmap */ int (*gi_pre)(graph_vertex_t *, void *); void (*gi_post)(graph_vertex_t *, void *); @@ -3849,6 +3850,8 @@ run_sulogin(const char *msg) static void * sulogin_thread(void *unused) { + (void) pthread_setname_np(pthread_self(), "sulogin"); + MUTEX_LOCK(&dgraph_lock); assert(sulogin_thread_running); @@ -3876,6 +3879,8 @@ single_user_thread(void *unused) char *buf; int r; + (void) pthread_setname_np(pthread_self(), "single_user"); + MUTEX_LOCK(&single_user_thread_lock); single_user_thread_count++; @@ -5779,6 +5784,8 @@ graph_event_thread(void *unused) scf_handle_t *h; int err; + (void) pthread_setname_np(pthread_self(), "graph_event"); + h = libscf_handle_create_bound_loop(); /*CONSTCOND*/ @@ -6138,6 +6145,8 @@ graph_thread(void *arg) scf_handle_t *h; int err; + (void) pthread_setname_np(pthread_self(), "graph"); + h = libscf_handle_create_bound_loop(); if (st->st_initial) @@ -6794,6 +6803,8 @@ repository_event_thread(void *unused) char *pg_name = startd_alloc(max_scf_value_size); int r; + (void) pthread_setname_np(pthread_self(), "repository_event"); + h = libscf_handle_create_bound_loop(); pg = safe_scf_pg_create(h); diff --git a/usr/src/cmd/svc/startd/method.c b/usr/src/cmd/svc/startd/method.c index cc9ce6768c..bddae9b027 100644 --- a/usr/src/cmd/svc/startd/method.c +++ b/usr/src/cmd/svc/startd/method.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Joyent Inc. + * Copyright 2018 Joyent, Inc. */ /* @@ -1115,6 +1115,8 @@ method_thread(void *arg) boolean_t retryable; restarter_str_t reason; + (void) pthread_setname_np(pthread_self(), "method"); + assert(0 <= info->sf_method_type && info->sf_method_type <= 2); /* Get (and lock) the restarter_inst_t. */ diff --git a/usr/src/cmd/svc/startd/restarter.c b/usr/src/cmd/svc/startd/restarter.c index 676cded1c8..a98c863fb5 100644 --- a/usr/src/cmd/svc/startd/restarter.c +++ b/usr/src/cmd/svc/startd/restarter.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ /* @@ -994,6 +994,8 @@ restarter_post_fsminimal_thread(void *unused) scf_handle_t *h; int r; + (void) pthread_setname_np(pthread_self(), "restarter_post_fsmin"); + h = libscf_handle_create_bound_loop(); for (;;) { @@ -1771,6 +1773,8 @@ restarter_process_events(void *arg) char *fmri = (char *)arg; struct timespec to; + (void) pthread_setname_np(pthread_self(), "restarter_process_events"); + assert(fmri != NULL); h = libscf_handle_create_bound_loop(); @@ -1939,8 +1943,8 @@ out: } static int -is_admin_event(restarter_event_type_t t) { - +is_admin_event(restarter_event_type_t t) +{ switch (t) { case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON: case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE: @@ -1985,6 +1989,8 @@ restarter_event_thread(void *unused) { scf_handle_t *h; + (void) pthread_setname_np(pthread_self(), "restarter_event"); + /* * This is a new thread, and thus, gets its own handle * to the repository. @@ -2196,6 +2202,8 @@ restarter_contracts_event_thread(void *unused) int fd, err; scf_handle_t *local_handle; + (void) pthread_setname_np(pthread_self(), "restarter_contracts_event"); + /* * Await graph load completion. That is, stop here, until we've scanned * the repository for contract - instance associations. @@ -2545,6 +2553,8 @@ restarter_timeouts_event_thread(void *unused) * is not empty. */ + (void) pthread_setname_np(pthread_self(), "restarter_timeouts_event"); + /*CONSTCOND*/ while (1) { /* diff --git a/usr/src/cmd/svc/startd/wait.c b/usr/src/cmd/svc/startd/wait.c index ebd83be10e..12856ff639 100644 --- a/usr/src/cmd/svc/startd/wait.c +++ b/usr/src/cmd/svc/startd/wait.c @@ -21,7 +21,8 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2012, Joyent, Inc. All rights reserved. + * + * Copyright 2018 Joyent, Inc. */ /* @@ -252,6 +253,8 @@ wait_register(pid_t pid, const char *inst_fmri, int am_parent, int direct) void * wait_thread(void *args) { + (void) pthread_setname_np(pthread_self(), "wait"); + for (;;) { port_event_t pe; int fd; |