From owner-svn-src-all@FreeBSD.ORG Fri Jun 27 20:34:23 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 8DED93C1; Fri, 27 Jun 2014 20:34:23 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6EFB629D2; Fri, 27 Jun 2014 20:34:23 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s5RKYN9q093116; Fri, 27 Jun 2014 20:34:23 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s5RKYMca093108; Fri, 27 Jun 2014 20:34:22 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201406272034.s5RKYMca093108@svn.freebsd.org> From: John Baldwin Date: Fri, 27 Jun 2014 20:34:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r267979 - in stable: 10/usr.bin/procstat 9/usr.bin/procstat X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Jun 2014 20:34:23 -0000 Author: jhb Date: Fri Jun 27 20:34:22 2014 New Revision: 267979 URL: http://svnweb.freebsd.org/changeset/base/267979 Log: MFC 266293: - Add support for dumping current resource usage for processes via a new -r flag to procstat. - Add an -H flag to request information about threads rather than processes when dumping statistics. Currently it is only used for -r to display resource usage for individual threads instead of the entire process. Added: stable/10/usr.bin/procstat/procstat_rusage.c - copied unchanged from r266293, head/usr.bin/procstat/procstat_rusage.c Modified: stable/10/usr.bin/procstat/Makefile stable/10/usr.bin/procstat/procstat.1 stable/10/usr.bin/procstat/procstat.c stable/10/usr.bin/procstat/procstat.h Directory Properties: stable/10/ (props changed) Changes in other areas also in this revision: Added: stable/9/usr.bin/procstat/procstat_rusage.c - copied unchanged from r266293, head/usr.bin/procstat/procstat_rusage.c Modified: stable/9/usr.bin/procstat/Makefile stable/9/usr.bin/procstat/procstat.1 stable/9/usr.bin/procstat/procstat.c stable/9/usr.bin/procstat/procstat.h Directory Properties: stable/9/usr.bin/procstat/ (props changed) Modified: stable/10/usr.bin/procstat/Makefile ============================================================================== --- stable/10/usr.bin/procstat/Makefile Fri Jun 27 19:57:57 2014 (r267978) +++ stable/10/usr.bin/procstat/Makefile Fri Jun 27 20:34:22 2014 (r267979) @@ -11,6 +11,7 @@ SRCS= procstat.c \ procstat_files.c \ procstat_kstack.c \ procstat_rlimit.c \ + procstat_rusage.c \ procstat_sigs.c \ procstat_threads.c \ procstat_vm.c Modified: stable/10/usr.bin/procstat/procstat.1 ============================================================================== --- stable/10/usr.bin/procstat/procstat.1 Fri Jun 27 19:57:57 2014 (r267978) +++ stable/10/usr.bin/procstat/procstat.1 Fri Jun 27 20:34:22 2014 (r267979) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 11, 2014 +.Dd May 16, 2014 .Dt PROCSTAT 1 .Os .Sh NAME @@ -33,11 +33,9 @@ .Nd get detailed process information .Sh SYNOPSIS .Nm -.Op Fl h -.Op Fl n -.Op Fl C +.Op Fl CHhn .Op Fl w Ar interval -.Op Fl b | c | e | f | i | j | k | l | s | t | v | x +.Op Fl b | c | e | f | i | j | k | l | r | s | t | v | x .Op Fl a | Ar pid | Ar core ... .Sh DESCRIPTION The @@ -73,6 +71,8 @@ If the flag is repeated, function offset printed. .It Fl l Display resource limits for the process. +.It Fl r +Display resource usage information for the process. .It Fl s Display security credential information for the process. .It Fl t @@ -102,6 +102,13 @@ The flag requests the printing of additional capability information in the file descriptor view. .Pp +The +.Fl H +flag may be used to request per-thread statistics rather than per-process +statistics for some options. +For those options, the second field in the table will list the thread ID +to which the row of information corresponds. +.Pp Some information, such as VM and file descriptor information, is available only to the owner of a process or the superuser. .Ss Binary Information Modified: stable/10/usr.bin/procstat/procstat.c ============================================================================== --- stable/10/usr.bin/procstat/procstat.c Fri Jun 27 19:57:57 2014 (r267978) +++ stable/10/usr.bin/procstat/procstat.c Fri Jun 27 20:34:22 2014 (r267979) @@ -39,18 +39,19 @@ #include "procstat.h" -static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, sflag; -static int tflag, vflag, xflag; -int hflag, nflag, Cflag; +static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, rflag; +static int sflag, tflag, vflag, xflag; +int hflag, nflag, Cflag, Hflag; static void usage(void) { - fprintf(stderr, "usage: procstat [-h] [-C] [-M core] [-N system] " + fprintf(stderr, "usage: procstat [-CHhn] [-M core] [-N system] " "[-w interval] \n"); fprintf(stderr, " [-b | -c | -e | -f | -i | -j | -k | " - "-l | -s | -t | -v | -x] [-a | pid | core ...]\n"); + "-l | -r | -s | -t | -v | -x]\n"); + fprintf(stderr, " [-a | pid | core ...]\n"); exit(EX_USAGE); } @@ -74,6 +75,8 @@ procstat(struct procstat *prstat, struct procstat_kstack(prstat, kipp, kflag); else if (lflag) procstat_rlimit(prstat, kipp); + else if (rflag) + procstat_rusage(prstat, kipp); else if (sflag) procstat_cred(prstat, kipp); else if (tflag) @@ -125,12 +128,16 @@ main(int argc, char *argv[]) interval = 0; memf = nlistf = NULL; - while ((ch = getopt(argc, argv, "CN:M:abcefijklhstvw:x")) != -1) { + while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrstvw:x")) != -1) { switch (ch) { case 'C': Cflag++; break; + case 'H': + Hflag++; + break; + case 'M': memf = optarg; break; @@ -181,6 +188,10 @@ main(int argc, char *argv[]) hflag++; break; + case 'r': + rflag++; + break; + case 's': sflag++; break; @@ -217,7 +228,7 @@ main(int argc, char *argv[]) /* We require that either 0 or 1 mode flags be set. */ tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) + - lflag + sflag + tflag + vflag + xflag; + lflag + rflag + sflag + tflag + vflag + xflag; if (!(tmp == 0 || tmp == 1)) usage(); Modified: stable/10/usr.bin/procstat/procstat.h ============================================================================== --- stable/10/usr.bin/procstat/procstat.h Fri Jun 27 19:57:57 2014 (r267978) +++ stable/10/usr.bin/procstat/procstat.h Fri Jun 27 20:34:22 2014 (r267979) @@ -29,7 +29,7 @@ #ifndef PROCSTAT_H #define PROCSTAT_H -extern int hflag, nflag, Cflag; +extern int hflag, nflag, Cflag, Hflag; struct kinfo_proc; void kinfo_proc_sort(struct kinfo_proc *kipp, int count); @@ -44,6 +44,7 @@ void procstat_files(struct procstat *prs void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp, int kflag); void procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp); +void procstat_rusage(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_threads(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_threads_sigs(struct procstat *prstat, struct kinfo_proc *kipp); Copied: stable/10/usr.bin/procstat/procstat_rusage.c (from r266293, head/usr.bin/procstat/procstat_rusage.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/usr.bin/procstat/procstat_rusage.c Fri Jun 27 20:34:22 2014 (r267979, copy of r266293, head/usr.bin/procstat/procstat_rusage.c) @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2012 Advanced Computing Technologies LLC + * Written by: John H. Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include +#include + +#include "procstat.h" + +static struct { + const char *ri_name; + bool ri_humanize; + int ri_scale; +} rusage_info[] = { + { "maximum RSS", true, 1 }, + { "integral shared memory", true, 1 }, + { "integral unshared data", true, 1 }, + { "integral unshared stack", true, 1 }, + { "page reclaims", false, 0 }, + { "page faults", false, 0 }, + { "swaps", false, 0 }, + { "block reads", false, 0 }, + { "block writes", false, 0 }, + { "messages sent", false, 0 }, + { "messages received", false, 0 }, + { "signals received", false, 0 }, + { "voluntary context switches", false, 0 }, + { "involuntary context switches", false, 0 } +}; + +/* xxx days hh:mm:ss.uuuuuu */ +static const char * +format_time(struct timeval *tv) +{ + static char buffer[32]; + int days, hours, minutes, seconds, used; + + minutes = tv->tv_sec / 60; + seconds = tv->tv_sec % 60; + hours = minutes / 60; + minutes %= 60; + days = hours / 24; + hours %= 24; + used = 0; + if (days == 1) + used += snprintf(buffer, sizeof(buffer), "1 day "); + else if (days > 0) + used += snprintf(buffer, sizeof(buffer), "%u days ", days); + + snprintf(buffer + used, sizeof(buffer) - used, "%02u:%02u:%02u.%06u ", + hours, minutes, seconds, (unsigned int)tv->tv_usec); + return (buffer); +} + +static const char * +format_value(long value, bool humanize, int scale) +{ + static char buffer[14]; + + if (scale != 0) + value <<= scale * 10; + if (humanize) + humanize_number(buffer, sizeof(buffer), value, "B", + scale, HN_DECIMAL); + else + snprintf(buffer, sizeof(buffer), "%ld ", value); + return (buffer); +} + +static void +print_prefix(struct kinfo_proc *kipp) +{ + + printf("%5d ", kipp->ki_pid); + if (Hflag) + printf("%6d ", kipp->ki_tid); + printf("%-16s ", kipp->ki_comm); +} + +static void +print_rusage(struct kinfo_proc *kipp) +{ + long *lp; + unsigned int i; + + print_prefix(kipp); + printf("%-14s %32s\n", "user time", + format_time(&kipp->ki_rusage.ru_utime)); + print_prefix(kipp); + printf("%-14s %32s\n", "system time", + format_time(&kipp->ki_rusage.ru_stime)); + lp = &kipp->ki_rusage.ru_maxrss; + for (i = 0; i < nitems(rusage_info); i++) { + print_prefix(kipp); + printf("%-32s %14s\n", rusage_info[i].ri_name, + format_value(*lp, rusage_info[i].ri_humanize, + rusage_info[i].ri_scale)); + lp++; + } +} + +void +procstat_rusage(struct procstat *procstat, struct kinfo_proc *kipp) +{ + struct kinfo_proc *kip; + unsigned int count, i; + + if (!hflag) { + printf("%5s ", "PID"); + if (Hflag) + printf("%6s ", "TID"); + printf("%-16s %-32s %14s\n", "COMM", "TYPE", "VALUE "); + } + + if (!Hflag) { + print_rusage(kipp); + return; + } + + kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD, + kipp->ki_pid, &count); + if (kip == NULL) + return; + kinfo_proc_sort(kip, count); + for (i = 0; i < count; i++) + print_rusage(&kip[i]); + procstat_freeprocs(procstat, kip); +}