summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2011-06-28 06:55:31 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2011-06-28 06:55:31 +0000
commitc0d08b24b0c62214665701f658806e788c7830d5 (patch)
tree88bdac9c6fadf614c47367fd01ae9b526b142eae /usr.sbin
parent1427060e974d41019de36be78aadb4e4cf180f90 (diff)
Use kvm_getfile2() instead of sysctl(KERN_FILE) for the -f option
Make -T behave as documented: only report totals Only open the kvm files when necessary prompted by a comment from matthew@ ok and corrections millert@, ok tedu@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/pstat/pstat.c115
1 files changed, 44 insertions, 71 deletions
diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c
index 6f92e801753..e4ee7d2751b 100644
--- a/usr.sbin/pstat/pstat.c
+++ b/usr.sbin/pstat/pstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pstat.c,v 1.77 2009/10/27 23:59:53 deraadt Exp $ */
+/* $OpenBSD: pstat.c,v 1.78 2011/06/28 06:55:30 guenther Exp $ */
/* $NetBSD: pstat.c,v 1.27 1996/10/23 22:50:06 cgd Exp $ */
/*-
@@ -53,6 +53,7 @@
#include <sys/sysctl.h>
+#include <stdint.h>
#include <err.h>
#include <kvm.h>
#include <limits.h>
@@ -103,7 +104,6 @@ kvm_t *kd = NULL;
}
void filemode(void);
-int getfiles(char **, size_t *);
struct mount *
getmnt(struct mount *);
struct e_vnode *
@@ -134,7 +134,7 @@ main(int argc, char *argv[])
extern char *optarg;
extern int optind;
gid_t gid;
- int i;
+ int i, need_nlist;
while ((ch = getopt(argc, argv, "d:TM:N:fiknstv")) != -1)
switch (ch) {
@@ -181,17 +181,23 @@ main(int argc, char *argv[])
if ((dformat == 0 && argc > 0) || (dformat && argc == 0))
usage();
+ need_nlist = vnodeflag || dformat;
+
/*
* Discard setgid privileges if not the running kernel so that bad
* guys can't print interesting stuff from kernel memory.
*/
gid = getgid();
- if (nlistf != NULL || memf != NULL)
+ if (nlistf != NULL || memf != NULL) {
if (setresgid(gid, gid, gid) == -1)
err(1, "setresgid");
+ if (fileflag || totalflag)
+ need_nlist = 1;
+ }
- if (vnodeflag || dformat)
- if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0)
+ if (vnodeflag || fileflag || dformat || need_nlist)
+ if ((kd = kvm_openfiles(nlistf, memf, NULL,
+ O_RDONLY | (need_nlist ? 0 : KVM_NO_FILES), buf)) == 0)
errx(1, "kvm_openfiles: %s", buf);
if (nlistf == NULL && memf == NULL)
@@ -295,7 +301,7 @@ main(int argc, char *argv[])
exit(error);
}
- if (vnodeflag)
+ if (need_nlist)
if (kvm_nlist(kd, vnodenl) == -1)
errx(1, "kvm_nlist: %s", kvm_geterr(kd));
@@ -975,15 +981,15 @@ ttyprt(struct itty *tp)
void
filemode(void)
{
- struct file fp, *ffp, *addr;
- char *buf, flagbuf[16], *fbp;
+ struct kinfo_file2 *kf;
+ char flagbuf[16], *fbp;
static char *dtypes[] = { "???", "inode", "socket" };
int mib[2], maxfile, nfile;
size_t len;
globalnl = vnodenl;
- if (kd == 0) {
+ if (nlistf == NULL && memf == NULL) {
mib[0] = CTL_KERN;
mib[1] = KERN_MAXFILES;
len = sizeof(maxfile);
@@ -1005,83 +1011,50 @@ filemode(void)
}
}
- if (getfiles(&buf, &len) == -1)
- return;
- /*
- * Getfiles returns in malloc'd memory a pointer to the first file
- * structure, and then an array of file structs (whose addresses are
- * derivable from the previous entry).
- */
- addr = LIST_FIRST((struct filelist *)buf);
- ffp = (struct file *)(buf + sizeof(struct filelist));
- nfile = (len - sizeof(struct filelist)) / sizeof(struct file);
+ if (!totalflag) {
+ kf = kvm_getfile2(kd, KERN_FILE_BYFILE, 0, sizeof *kf, &nfile);
+ if (kf == NULL) {
+ warnx("kvm_getfile2: %s", kvm_geterr(kd));
+ return;
+ }
+ }
(void)printf("%d/%d open files\n", nfile, maxfile);
+ if (totalflag)
+ return;
(void)printf("%*s TYPE FLG CNT MSG %*s OFFSET\n",
2 * (int)sizeof(long), "LOC", 2 * (int)sizeof(long), "DATA");
- for (; (char *)ffp < buf + len; addr = LIST_NEXT(ffp, f_list), ffp++) {
- memmove(&fp, ffp, sizeof fp);
- if ((unsigned)fp.f_type > DTYPE_SOCKET)
+ for (; nfile-- > 0; kf++) {
+ if (kf->f_type > DTYPE_SOCKET)
continue;
- (void)printf("%0*lx ", 2 * (int)sizeof(long), (long)addr);
- (void)printf("%-8.8s", dtypes[fp.f_type]);
+ (void)printf("%0*llx ", 2 * (int)sizeof(long), kf->f_fileaddr);
+ (void)printf("%-8.8s", dtypes[kf->f_type]);
fbp = flagbuf;
- if (fp.f_flag & FREAD)
+ if (kf->f_flag & FREAD)
*fbp++ = 'R';
- if (fp.f_flag & FWRITE)
+ if (kf->f_flag & FWRITE)
*fbp++ = 'W';
- if (fp.f_flag & FAPPEND)
+ if (kf->f_flag & FAPPEND)
*fbp++ = 'A';
- if (fp.f_flag & FHASLOCK)
+ if (kf->f_flag & FHASLOCK)
*fbp++ = 'L';
- if (fp.f_flag & FASYNC)
+ if (kf->f_flag & FASYNC)
*fbp++ = 'I';
*fbp = '\0';
- (void)printf("%6s %3ld", flagbuf, fp.f_count);
- (void)printf(" %3ld", fp.f_msgcount);
- (void)printf(" %0*lx", 2 * (int)sizeof(long), (long)fp.f_data);
+ (void)printf("%6s %3ld", flagbuf, kf->f_count);
+ (void)printf(" %3ld", kf->f_msgcount);
+ (void)printf(" %0*lx", 2 * (int)sizeof(long),
+ (long)kf->f_data);
- if (fp.f_offset == (off_t)-1)
+ if (kf->f_offset == (uint64_t)-1)
(void)printf(" *\n");
- else if (fp.f_offset < 0)
- (void)printf(" %llx\n", (long long)fp.f_offset);
- else
- (void)printf(" %lld\n", (long long)fp.f_offset);
- }
- free(buf);
-}
-
-int
-getfiles(char **abuf, size_t *alen)
-{
- size_t len;
- int mib[2];
- char *buf;
-
- /*
- * XXX
- * Add emulation of KINFO_FILE here.
- */
- if (memf != NULL)
- errx(1, "files on dead kernel, not implemented");
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_FILE;
- if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1) {
- warn("sysctl: KERN_FILE");
- return (-1);
- }
- if ((buf = malloc(len)) == NULL)
- err(1, "malloc: KERN_FILE");
- if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
- warn("sysctl: KERN_FILE");
- free(buf);
- return (-1);
+ else if (kf->f_offset > INT64_MAX) {
+ /* would have been negative */
+ (void)printf(" %llx\n", (long long)kf->f_offset);
+ } else
+ (void)printf(" %lld\n", (long long)kf->f_offset);
}
- *abuf = buf;
- *alen = len;
- return (0);
}
/*