diff options
author | Jason King <jason.brian.king@gmail.com> | 2017-05-05 22:58:26 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2018-09-26 08:38:04 +0000 |
commit | c113f3b5211bf6ae3ff1ee916a9f9ad0c28b7125 (patch) | |
tree | ed3893fad0f78462adf85cf08feb76669ab9abab /usr/src/cmd/prstat | |
parent | dee777b5a3880de62b42997fe61524f95dcc16db (diff) | |
download | illumos-joyent-OS-7200.tar.gz |
OS-7200 would like thread name APIOS-7200
OS-7205 bhyve makefile uses wrong linker flags
Diffstat (limited to 'usr/src/cmd/prstat')
-rw-r--r-- | usr/src/cmd/prstat/Makefile.com | 2 | ||||
-rw-r--r-- | usr/src/cmd/prstat/prstat.c | 140 | ||||
-rw-r--r-- | usr/src/cmd/prstat/prstat.h | 6 | ||||
-rw-r--r-- | usr/src/cmd/prstat/prutil.c | 76 | ||||
-rw-r--r-- | usr/src/cmd/prstat/prutil.h | 3 |
5 files changed, 171 insertions, 56 deletions
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 99fc9ecb28..f40219d75a 100644 --- a/usr/src/cmd/prstat/prstat.c +++ b/usr/src/cmd/prstat/prstat.c @@ -26,7 +26,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier - * Copyright 2017 Joyent, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -87,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 \ @@ -111,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 \ @@ -150,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 */ @@ -173,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 */ @@ -389,11 +389,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; @@ -413,54 +414,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'); @@ -527,15 +533,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); @@ -564,21 +569,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'); @@ -598,12 +599,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'); } @@ -905,6 +905,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; @@ -919,6 +940,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 @@ -1141,7 +1163,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(); @@ -1152,7 +1174,7 @@ curses_on() } static void -curses_off() +curses_off(void) { if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) { (void) putp(t_rmcup); @@ -1163,26 +1185,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) && @@ -1212,17 +1248,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 ddb7416213..7d3913f731 100644 --- a/usr/src/cmd/prstat/prstat.h +++ b/usr/src/cmd/prstat/prstat.h @@ -26,7 +26,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier - * Copyright 2017 Joyent, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. All rights reserved. */ #ifndef _PRSTAT_H @@ -115,6 +115,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; @@ -169,8 +170,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 8c90cb2e15..551c72cc8a 100644 --- a/usr/src/cmd/prstat/prutil.c +++ b/usr/src/cmd/prstat/prutil.c @@ -25,7 +25,7 @@ * Use is subject to license terms. * * Portions Copyright 2009 Chad Mynhier - * Copyright 2017 Joyent, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -325,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) { @@ -352,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 } |