PERFORCE change 156463 for review
Robert Watson
rwatson at FreeBSD.org
Wed Jan 21 03:58:48 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=156463
Change 156463 by rwatson at rwatson_freebsd_capabilities on 2009/01/21 11:58:03
Teach procstat(1) how to print out, when an optional -C flag is
specified, the capability mask associated with a file descriptor.
Affected files ...
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat.1#6 edit
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat.c#4 edit
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat.h#2 edit
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat_files.c#12 edit
Differences ...
==== //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat.1#6 (text+ko) ====
@@ -33,7 +33,7 @@
.Nd get detailed process information
.Sh SYNOPSIS
.Nm
-.Op Fl h
+.Op Fl hC
.Op Fl w Ar interval
.Op Fl b | c | f | k | s | t | v
.Op Fl a | Ar pid ...
@@ -83,6 +83,11 @@
.Fl w
flag is not specified, the output will not repeat.
.Pp
+The
+.Fl C
+flag requests the printing of additional capability information in the file
+descriptor view.
+.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
@@ -111,7 +116,8 @@
Display detailed information about each file descriptor referenced by a
process, including the process ID, command, file descriptor number, and
per-file descriptor object information, such as object type and file system
-path:
+path.
+By default, the following information will be printed:
.Pp
.Bl -tag -width indent -compact
.It PID
@@ -203,7 +209,17 @@
direct I/O
.It l
lock held
+.It C
+descriptor is a capability
.El
+.Pp
+If the
+.Fl C
+flag is specified, the vnode type, reference count, and offset fields will be
+omitted, and a new capabilities field will be included listing capabilities,
+as described in
+.Xr cap_new 2 ,
+present for each capability descriptor.
.Ss Kernel Thread Stacks
Display kernel thread stacks for a process, allowing further interpretation
of thread wait channels.
@@ -345,6 +361,7 @@
.Xr fstat 1 ,
.Xr ps 1 ,
.Xr sockstat 1 ,
+.Xr cap_new 2 ,
.Xr ddb 4 ,
.Xr stack 9
.Sh AUTHORS
==== //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat.c#4 (text+ko) ====
@@ -39,14 +39,14 @@
#include "procstat.h"
static int aflag, bflag, cflag, fflag, kflag, sflag, tflag, vflag;
-int hflag;
+int hflag, Cflag;
static void
usage(void)
{
- fprintf(stderr, "usage: procstat [-h] [-w interval] [-b | -c | -f | "
- "-k | -s | -t | -v]\n");
+ fprintf(stderr, "usage: procstat [-hC] [-w interval] [-b | -c | -f "
+ " | -k | -s | -t | -v]\n");
fprintf(stderr, " [-a | pid ...]\n");
exit(EX_USAGE);
}
@@ -109,7 +109,7 @@
char *dummy;
interval = 0;
- while ((ch = getopt(argc, argv, "abcfkhstvw:")) != -1) {
+ while ((ch = getopt(argc, argv, "abcfkhstvw:C")) != -1) {
switch (ch) {
case 'a':
aflag++;
@@ -156,6 +156,10 @@
interval = l;
break;
+ case 'C':
+ Cflag++;
+ break;
+
case '?':
default:
usage();
@@ -178,6 +182,10 @@
if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
usage();
+ /* Only allow -C with -f. */
+ if (Cflag && !fflag)
+ usage();
+
do {
if (aflag) {
name[0] = CTL_KERN;
==== //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat.h#2 (text+ko) ====
@@ -29,7 +29,7 @@
#ifndef PROCSTAT_H
#define PROCSTAT_H
-extern int hflag;
+extern int hflag, Cflag;
struct kinfo_proc;
void kinfo_proc_sort(struct kinfo_proc *kipp, int count);
==== //depot/projects/trustedbsd/capabilities/src/usr.bin/procstat/procstat_files.c#12 (text+ko) ====
@@ -132,7 +132,6 @@
printf("%s", addr);
}
-#if notyet
static struct cap_desc {
cap_rights_t cd_right;
const char *cd_desc;
@@ -184,42 +183,96 @@
{ CAP_PDWAIT, "pw" },
{ CAP_PDKILL, "pk" },
};
-static const int cap_desc_count = sizeof(cap_desc) /
+static const u_int cap_desc_count = sizeof(cap_desc) /
sizeof(cap_desc[0]);
+static u_int
+width_capability(cap_rights_t rights)
+{
+ u_int count, i, width;
+
+ count = 0;
+ width = 0;
+ for (i = 0; i < cap_desc_count; i++) {
+ if (rights & cap_desc[i].cd_right) {
+ width += strlen(cap_desc[i].cd_desc);
+ if (count)
+ width++;
+ count++;
+ }
+ }
+ return (width);
+}
+
static void
-print_capability(cap_rights_t rights)
+print_capability(cap_rights_t rights, u_int capwidth)
{
- int count, i;
+ u_int count, i, width;
count = 0;
+ width = 0;
+ for (i = width_capability(rights); i < capwidth; i++) {
+ if (rights || i != (capwidth - 1))
+ printf(" ");
+ else
+ printf("-");
+ }
for (i = 0; i < cap_desc_count; i++) {
if (rights & cap_desc[i].cd_right) {
printf("%s%s", count ? "," : "", cap_desc[i].cd_desc);
+ width += strlen(cap_desc[i].cd_desc);
+ if (count)
+ width++;
count++;
}
}
}
-#endif
void
procstat_files(pid_t pid, struct kinfo_proc *kipp)
{
struct kinfo_file *freep, *kif;
+ u_int capwidth, width;
int i, cnt;
const char *str;
- if (!hflag)
- printf("%5s %-16s %4s %1s %1s %-9s %3s %7s %-3s %-12s\n",
- "PID", "COMM", "FD", "T", "V", "FLAGS", "REF", "OFFSET",
- "PRO", "NAME");
+ /*
+ * To print the header in capability mode, we need to know the width
+ * of the widest capability string. Even if we get no processes
+ * back, we will print the header, so we defer aborting due to a lack
+ * of processes until after the header logic.
+ */
+ capwidth = 0;
+ freep = kinfo_getfile(pid, &cnt);
+ if (freep != NULL && Cflag) {
+ for (i = 0; i < cnt; i++) {
+ kif = &freep[i];
+ width = width_capability(kif->kf_cap_rights);
+ if (width > capwidth)
+ capwidth = width;
+ }
+ if (capwidth < strlen("CAPABILITIES"))
+ capwidth = strlen("CAPABILITIES");
+ }
+ printf("capwidth: %d\n", capwidth);
+
+ if (!hflag) {
+ if (Cflag)
+ printf("%5s %-16s %4s %1s %9s %-*s "
+ "%-3s %-12s\n", "PID", "COMM", "FD", "T",
+ "FLAGS", capwidth, "CAPABILITIES", "PRO",
+ "NAME");
+ else
+ printf("%5s %-16s %4s %1s %1s %-9s %3s %7s %-3s "
+ "%-12s\n", "PID", "COMM", "FD", "T", "V",
+ "FLAGS", "REF", "OFFSET", "PRO", "NAME");
+ }
- freep = kinfo_getfile(pid, &cnt);
if (freep == NULL)
return;
for (i = 0; i < cnt; i++) {
kif = &freep[i];
-
+
printf("%5d ", pid);
printf("%-16s ", kipp->ki_comm);
switch (kif->kf_fd) {
@@ -291,49 +344,51 @@
break;
}
printf("%1s ", str);
- str = "-";
- if (kif->kf_type == KF_TYPE_VNODE) {
- switch (kif->kf_vnode_type) {
- case KF_VTYPE_VREG:
- str = "r";
- break;
+ if (!Cflag) {
+ str = "-";
+ if (kif->kf_type == KF_TYPE_VNODE) {
+ switch (kif->kf_vnode_type) {
+ case KF_VTYPE_VREG:
+ str = "r";
+ break;
- case KF_VTYPE_VDIR:
- str = "d";
- break;
+ case KF_VTYPE_VDIR:
+ str = "d";
+ break;
- case KF_VTYPE_VBLK:
- str = "b";
- break;
+ case KF_VTYPE_VBLK:
+ str = "b";
+ break;
- case KF_VTYPE_VCHR:
- str = "c";
- break;
+ case KF_VTYPE_VCHR:
+ str = "c";
+ break;
- case KF_VTYPE_VLNK:
- str = "l";
- break;
+ case KF_VTYPE_VLNK:
+ str = "l";
+ break;
- case KF_VTYPE_VSOCK:
- str = "s";
- break;
+ case KF_VTYPE_VSOCK:
+ str = "s";
+ break;
- case KF_VTYPE_VFIFO:
- str = "f";
- break;
+ case KF_VTYPE_VFIFO:
+ str = "f";
+ break;
- case KF_VTYPE_VBAD:
- str = "x";
- break;
+ case KF_VTYPE_VBAD:
+ str = "x";
+ break;
- case KF_VTYPE_VNON:
- case KF_VTYPE_UNKNOWN:
- default:
- str = "?";
- break;
+ case KF_VTYPE_VNON:
+ case KF_VTYPE_UNKNOWN:
+ default:
+ str = "?";
+ break;
+ }
}
+ printf("%1s ", str);
}
- printf("%1s ", str);
printf("%s", kif->kf_flags & KF_FLAG_READ ? "r" : "-");
printf("%s", kif->kf_flags & KF_FLAG_WRITE ? "w" : "-");
printf("%s", kif->kf_flags & KF_FLAG_APPEND ? "a" : "-");
@@ -343,27 +398,50 @@
printf("%s", kif->kf_flags & KF_FLAG_DIRECT ? "d" : "-");
printf("%s", kif->kf_flags & KF_FLAG_HASLOCK ? "l" : "-");
printf("%s ", kif->kf_flags & KF_FLAG_CAPABILITY ? "c" : "-");
- if (kif->kf_ref_count > -1)
- printf("%3d ", kif->kf_ref_count);
- else
- printf("%3c ", '-');
- if (kif->kf_offset > -1)
- printf("%7jd ", (intmax_t)kif->kf_offset);
- else
- printf("%7c ", '-');
+ if (!Cflag) {
+ if (kif->kf_ref_count > -1)
+ printf("%3d ", kif->kf_ref_count);
+ else
+ printf("%3c ", '-');
+ if (kif->kf_offset > -1)
+ printf("%7jd ", (intmax_t)kif->kf_offset);
+ else
+ printf("%7c ", '-');
+ }
+
+ if (Cflag) {
+ print_capability(kif->kf_cap_rights, capwidth);
+ printf(" ");
+ }
switch (kif->kf_type) {
case KF_TYPE_VNODE:
case KF_TYPE_FIFO:
case KF_TYPE_PTS:
printf("%-3s ", "-");
- printf("%-18s", kif->kf_path);
break;
case KF_TYPE_SOCKET:
printf("%-3s ",
protocol_to_string(kif->kf_sock_domain,
kif->kf_sock_type, kif->kf_sock_protocol));
+ break;
+
+ case KF_TYPE_PROCDESC:
+ printf("%-3s %d", "-", kif->kf_pid);
+ break;
+
+ default:
+ printf("%-3s ", "-");
+ }
+
+ switch (kif->kf_type) {
+ case KF_TYPE_VNODE:
+ case KF_TYPE_FIFO:
+ case KF_TYPE_PTS:
+ printf("%-18s", kif->kf_path);
+
+ case KF_TYPE_SOCKET:
/*
* While generally we like to print two addresses,
* local and peer, for sockets, it turns out to be
@@ -387,11 +465,10 @@
break;
case KF_TYPE_PROCDESC:
- printf("%-3s %d", "-", kif->kf_pid);
+ printf("%d", kif->kf_pid);
break;
default:
- printf("%-3s ", "-");
printf("%-18s", "-");
}
More information about the p4-projects
mailing list