diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile index 1744fe083214..211ce1a1431b 100644 --- a/usr.bin/procstat/Makefile +++ b/usr.bin/procstat/Makefile @@ -8,6 +8,7 @@ SRCS= procstat.c \ procstat_basic.c \ procstat_bin.c \ procstat_cred.c \ + procstat_cs.c \ procstat_files.c \ procstat_kstack.c \ procstat_rlimit.c \ diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index f33c746bc736..5cc7cc8785cc 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -35,7 +35,7 @@ .Nm .Op Fl CHhn .Op Fl w Ar interval -.Op Fl b | c | e | f | i | j | k | l | r | s | t | v | x +.Op Fl b | c | e | f | i | j | k | l | r | s | S | t | v | x .Op Fl a | Ar pid | Ar core ... .Sh DESCRIPTION The @@ -75,6 +75,8 @@ Display resource limits for the process. Display resource usage information for the process. .It Fl s Display security credential information for the process. +.It Fl S +Display the cpuset information for the thread. .It Fl t Display thread information for the process. .It Fl v @@ -108,9 +110,16 @@ 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. +The +.Fl H +flag is implied for the +.Fl S +mode. .Pp -Some information, such as VM and file descriptor information, is available +Information for VM, file descriptor, and cpuset options is available only to the owner of a process or the superuser. +A cpuset value displayed as -1 means that the information is either invalid +or not available. .Ss Binary Information Display the process ID, command, and path to the process binary: .Pp diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c index de0237f387ce..0be90c334066 100644 --- a/usr.bin/procstat/procstat.c +++ b/usr.bin/procstat/procstat.c @@ -40,7 +40,7 @@ #include "procstat.h" static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, rflag; -static int sflag, tflag, vflag, xflag; +static int sflag, tflag, vflag, xflag, Sflag;; int hflag, nflag, Cflag, Hflag; static void @@ -50,7 +50,7 @@ usage(void) fprintf(stderr, "usage: procstat [-CHhn] [-M core] [-N system] " "[-w interval] \n"); fprintf(stderr, " [-b | -c | -e | -f | -i | -j | -k | " - "-l | -r | -s | -t | -v | -x]\n"); + "-l | -r | -s | -S | -t | -v | -x]\n"); fprintf(stderr, " [-a | pid | core ...]\n"); exit(EX_USAGE); } @@ -85,6 +85,8 @@ procstat(struct procstat *prstat, struct kinfo_proc *kipp) procstat_vm(prstat, kipp); else if (xflag) procstat_auxv(prstat, kipp); + else if (Sflag) + procstat_cs(prstat, kipp); else procstat_basic(kipp); } @@ -128,7 +130,7 @@ main(int argc, char *argv[]) interval = 0; memf = nlistf = NULL; - while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrstvw:x")) != -1) { + while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrsStvw:x")) != -1) { switch (ch) { case 'C': Cflag++; @@ -144,6 +146,9 @@ main(int argc, char *argv[]) case 'N': nlistf = optarg; break; + case 'S': + Sflag++; + break; case 'a': aflag++; break; @@ -228,7 +233,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 + rflag + sflag + tflag + vflag + xflag; + lflag + rflag + sflag + tflag + vflag + xflag + Sflag; if (!(tmp == 0 || tmp == 1)) usage(); diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h index 98282b3ac1e0..50795219111f 100644 --- a/usr.bin/procstat/procstat.h +++ b/usr.bin/procstat/procstat.h @@ -39,6 +39,7 @@ void procstat_auxv(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_basic(struct kinfo_proc *kipp); void procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_cred(struct procstat *prstat, struct kinfo_proc *kipp); +void procstat_cs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_env(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_files(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp, diff --git a/usr.bin/procstat/procstat_cs.c b/usr.bin/procstat/procstat_cs.c new file mode 100644 index 000000000000..8ccf1ea82227 --- /dev/null +++ b/usr.bin/procstat/procstat_cs.c @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2007 Robert N. M. Watson + * 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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "procstat.h" + +void +procstat_cs(struct procstat *procstat, struct kinfo_proc *kipp) +{ + cpusetid_t cs; + cpuset_t mask; + struct kinfo_proc *kip; + unsigned int count, i; + int once, twice, lastcpu, cpu; + + if (!hflag) + printf("%5s %6s %-16s %-16s %2s %4s %-7s\n", "PID", + "TID", "COMM", "TDNAME", "CPU", "CSID", "CPU MASK"); + + 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++) { + kipp = &kip[i]; + printf("%5d ", kipp->ki_pid); + printf("%6d ", kipp->ki_tid); + printf("%-16s ", strlen(kipp->ki_comm) ? + kipp->ki_comm : "-"); + printf("%-16s ", (strlen(kipp->ki_tdname) && + (strcmp(kipp->ki_comm, kipp->ki_tdname) != 0)) ? + kipp->ki_tdname : "-"); + if (kipp->ki_oncpu != 255) + printf("%3d ", kipp->ki_oncpu); + else if (kipp->ki_lastcpu != 255) + printf("%3d ", kipp->ki_lastcpu); + else + printf("%3s ", "-"); + if (cpuset_getid(CPU_LEVEL_CPUSET, CPU_WHICH_TID, + kipp->ki_tid, &cs) != 0) { + cs = CPUSET_INVALID; + } + printf("%4d ", cs); + if ((cs != CPUSET_INVALID) && + (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, + kipp->ki_tid, sizeof(mask), &mask) == 0)) { + lastcpu = -1; + once = 0; + twice = 0; + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (CPU_ISSET(cpu, &mask)) { + if (once == 0) { + printf("%d", cpu); + once = 1; + } else if (cpu == lastcpu + 1) { + twice = 1; + } else if (twice == 1) { + printf("-%d,%d", lastcpu, cpu); + twice = 0; + } else + printf(",%d", cpu); + lastcpu = cpu; + } + } + if (once && twice) + printf("-%d", lastcpu); + } + printf("\n"); + } + procstat_freeprocs(procstat, kip); +}