svn commit: r195489 - projects/libprocstat/usr.bin/fstat
Stanislav Sedov
stas at FreeBSD.org
Thu Jul 9 11:48:48 UTC 2009
Author: stas
Date: Thu Jul 9 11:48:48 2009
New Revision: 195489
URL: http://svn.freebsd.org/changeset/base/195489
Log:
- Merge sysctl-bases access routines from fstat_vnode.c into fstat.c.
- Link fstat against libutil.
Deleted:
projects/libprocstat/usr.bin/fstat/fstat_vnode.c
Modified:
projects/libprocstat/usr.bin/fstat/Makefile
projects/libprocstat/usr.bin/fstat/fstat.c
Modified: projects/libprocstat/usr.bin/fstat/Makefile
==============================================================================
--- projects/libprocstat/usr.bin/fstat/Makefile Thu Jul 9 09:46:34 2009 (r195488)
+++ projects/libprocstat/usr.bin/fstat/Makefile Thu Jul 9 11:48:48 2009 (r195489)
@@ -7,7 +7,7 @@ PROG= fstat
SRCS= cd9660.c common.c fstat.c main.c msdosfs.c fuser.c
LINKS= ${BINDIR}/fstat ${BINDIR}/fuser
DPADD= ${LIBKVM}
-LDADD= -lkvm
+LDADD= -lkvm -lutil
BINGRP= kmem
BINMODE=2555
WARNS?= 6
Modified: projects/libprocstat/usr.bin/fstat/fstat.c
==============================================================================
--- projects/libprocstat/usr.bin/fstat/fstat.c Thu Jul 9 09:46:34 2009 (r195488)
+++ projects/libprocstat/usr.bin/fstat/fstat.c Thu Jul 9 11:48:48 2009 (r195489)
@@ -65,8 +65,8 @@ __FBSDID("$FreeBSD$");
#include <sys/file.h>
#include <sys/conf.h>
#define _KERNEL
-#include <sys/pipe.h>
#include <sys/mount.h>
+#include <sys/pipe.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <fs/devfs/devfs.h>
@@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <fcntl.h>
#include <kvm.h>
+#include <libutil.h>
#include <limits.h>
#include <nlist.h>
#include <paths.h>
@@ -152,6 +153,7 @@ kvm_t *kd;
static void fstat_kvm(int, int);
static void fstat_sysctl(int, int);
void dofiles(struct kinfo_proc *kp);
+void dofiles_kinfo(struct kinfo_proc *kp);
void dommap(struct kinfo_proc *kp);
void vtrans(struct vnode *vp, int i, int flag);
char *getmnton(struct mount *m);
@@ -161,6 +163,12 @@ void ptstrans(struct tty *tp, int i, int
void getinetproto(int number);
int getfname(const char *filename);
void usage(void);
+static int kinfo_proc_compare(const void *, const void *);
+static void kinfo_proc_sort(struct kinfo_proc *, int);
+void vtrans_kinfo(struct kinfo_file *, int i, int flag);
+
+/* XXX: sys/mount.h */
+int statfs(const char *, struct statfs *);
int
do_fstat(int argc, char **argv)
@@ -288,12 +296,66 @@ fstat_kvm(int what, int arg)
}
}
+/*
+ * Sort processes first by pid and then tid.
+ */
+static int
+kinfo_proc_compare(const void *a, const void *b)
+{
+ int i;
+
+ i = ((const struct kinfo_proc *)b)->ki_pid -
+ ((const struct kinfo_proc *)a)->ki_pid;
+ if (i != 0)
+ return (i);
+ i = ((const struct kinfo_proc *)b)->ki_tid -
+ ((const struct kinfo_proc *)a)->ki_tid;
+ return (i);
+}
+
static void
-fstat_sysctl(int what, int arg)
+kinfo_proc_sort(struct kinfo_proc *kipp, int count)
{
- /* not yet implemented */
- fstat_kvm(what, arg);
+ qsort(kipp, count, sizeof(*kipp), kinfo_proc_compare);
+}
+
+static void
+fstat_sysctl(int what, int arg)
+{
+ struct kinfo_proc *kipp;
+ int name[4];
+ size_t len;
+ unsigned int i;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = what;
+ name[3] = arg;
+
+ len = 0;
+ if (sysctl(name, 4, NULL, &len, NULL, 0) < 0)
+ err(-1, "sysctl: kern.proc");
+ kipp = malloc(len);
+ if (kipp == NULL)
+ err(-1, "malloc");
+
+ if (sysctl(name, 4, kipp, &len, NULL, 0) < 0) {
+ free(kipp);
+ err(-1, "sysctl: kern.proc");
+ }
+ if (len % sizeof(*kipp) != 0)
+ err(-1, "kinfo_proc mismatch");
+ if (kipp->ki_structsize != sizeof(*kipp))
+ err(-1, "kinfo_proc structure mismatch");
+ kinfo_proc_sort(kipp, len / sizeof(*kipp));
+ print_header();
+ for (i = 0; i < len / sizeof(*kipp); i++) {
+ dofiles_kinfo(&kipp[i]);
+ if (mflg)
+ dommap(&kipp[i]);
+ }
+ free(kipp);
}
const char *Uname, *Comm;
@@ -430,6 +492,108 @@ dofiles(struct kinfo_proc *kp)
}
}
+/*
+ * print open files attributed to this process using kinfo
+ */
+void
+dofiles_kinfo(struct kinfo_proc *kp)
+{
+ struct kinfo_file *kif, *freep;
+#if 0
+ struct kinfo_file kifb;
+#endif
+ int i, cnt, fd_type, flags;
+
+ Uname = user_from_uid(kp->ki_uid, 0);
+ Pid = kp->ki_pid;
+ Comm = kp->ki_comm;
+
+ if (kp->ki_fd == NULL)
+ return;
+
+#if 0
+ /*
+ * ktrace vnode, if one
+ */
+ if (kp->ki_tracep)
+ vtrans_kin(kp->ki_tracep, TRACE, FREAD|FWRITE);
+ /*
+ * text vnode, if one
+ */
+ vtrans(kp->ki_textvp, TEXT, FREAD);
+ /* Text vnode. */
+ if (kp->ki_textvp) {
+ if (gettextvp(kp, &kifb) == 0)
+ vtrans_kinfo(&kifb, TEXT, FREAD);
+ }
+#endif
+
+ /*
+ * open files
+ */
+ freep = kinfo_getfile(kp->ki_pid, &cnt);
+ if (freep == NULL)
+ err(1, "kinfo_getfile");
+
+ for (i = 0; i < cnt; i++) {
+ kif = &freep[i];
+ switch (kif->kf_type) {
+ case KF_TYPE_VNODE:
+ if (kif->kf_fd == KF_FD_TYPE_CWD) {
+ fd_type = CDIR;
+ flags = FREAD;
+ } else if (kif->kf_fd == KF_FD_TYPE_ROOT) {
+ fd_type = RDIR;
+ flags = FREAD;
+ } else if (kif->kf_fd == KF_FD_TYPE_JAIL) {
+ fd_type = JDIR;
+ flags = FREAD;
+ } else {
+ fd_type = i;
+ flags = kif->kf_flags;
+ }
+ /* Only do this if the attributes are valid. */
+ if (kif->kf_status & KF_ATTR_VALID)
+ vtrans_kinfo(kif, fd_type, flags);
+ break;
+#if 0
+ case KF_TYPE_PIPE:
+ if (checkfile == 0)
+ pipetrans_kinfo(kif, i, kif->kf_flags);
+ break;
+ else if (file.f_type == DTYPE_SOCKET) {
+ if (checkfile == 0)
+ socktrans(file.f_data, i);
+ }
+#ifdef DTYPE_PIPE
+ else if (file.f_type == DTYPE_PIPE) {
+ if (checkfile == 0)
+ pipetrans(file.f_data, i, file.f_flag);
+ }
+#endif
+#ifdef DTYPE_FIFO
+ else if (file.f_type == DTYPE_FIFO) {
+ if (checkfile == 0)
+ vtrans(file.f_vnode, i, file.f_flag);
+ }
+#endif
+#ifdef DTYPE_PTS
+ else if (file.f_type == DTYPE_PTS) {
+ if (checkfile == 0)
+ ptstrans(file.f_data, i, file.f_flag);
+ }
+#endif
+ else {
+ dprintf(stderr,
+ "unknown file type %d for file %d of pid %d\n",
+ file.f_type, i, Pid);
+ }
+#endif
+ }
+ }
+ free(freep);
+}
+
void
dommap(struct kinfo_proc *kp)
{
@@ -602,10 +766,106 @@ vtrans(struct vnode *vp, int i, int flag
putchar('\n');
}
+void
+vtrans_kinfo(struct kinfo_file *kif, int i, int flag)
+{
+ struct filestat fst;
+ char rw[3], mode[15];
+ const char *badtype, *filename;
+ struct statfs stbuf;
+
+ filename = badtype = NULL;
+ fst.fsid = fst.fileid = fst.mode = fst.size = fst.rdev = 0;
+ bzero(&stbuf, sizeof(struct statfs));
+ switch (kif->kf_vnode_type) {
+ case VNON:
+ badtype = "none";
+ break;
+ case VBAD:
+ badtype = "bad";
+ break;
+ default:
+ fst.fsid = kif->kf_file_fsid;
+ fst.fileid = kif->kf_file_fileid;
+ fst.mode = kif->kf_file_mode;
+ fst.size = kif->kf_file_size;
+ fst.rdev = kif->kf_file_rdev;
+ break;
+ }
+ if (checkfile) {
+ int fsmatch = 0;
+ DEVS *d;
+
+ if (badtype)
+ return;
+ for (d = devs; d != NULL; d = d->next)
+ if (d->fsid == fst.fsid) {
+ fsmatch = 1;
+ if (d->ino == fst.fileid) {
+ filename = d->name;
+ break;
+ }
+ }
+ if (fsmatch == 0 || (filename == NULL && fsflg == 0))
+ return;
+ }
+ PREFIX(i);
+ if (badtype) {
+ (void)printf(" - - %10s -\n", badtype);
+ return;
+ }
+ if (nflg)
+ (void)printf(" %2d,%-2d", major(fst.fsid), minor(fst.fsid));
+ else {
+ if (strlen(kif->kf_path) > 0)
+ statfs(kif->kf_path, &stbuf);
+ (void)printf(" %-8s", stbuf.f_mntonname);
+ }
+ if (nflg)
+ (void)sprintf(mode, "%o", fst.mode);
+ else {
+ strmode(fst.mode, mode);
+ }
+ (void)printf(" %6ld %10s", fst.fileid, mode);
+ switch (kif->kf_vnode_type) {
+ case KF_VTYPE_VBLK: {
+ char *name;
+ name = devname(fst.rdev, S_IFBLK);
+ if (nflg || !name)
+ printf(" %2d,%-2d", major(fst.rdev), minor(fst.rdev));
+ else {
+ printf(" %6s", name);
+ }
+ break;
+ }
+ case KF_VTYPE_VCHR: {
+ char *name;
+ name = devname(fst.rdev, S_IFCHR);
+ if (nflg || !name)
+ printf(" %2d,%-2d", major(fst.rdev), minor(fst.rdev));
+ else {
+ printf(" %6s", name);
+ }
+ break;
+ }
+ default:
+ printf(" %6lu", fst.size);
+ }
+ rw[0] = '\0';
+ if (flag & FREAD)
+ strcat(rw, "r");
+ if (flag & FWRITE)
+ strcat(rw, "w");
+ printf(" %2s", rw);
+ if (filename && !fsflg)
+ printf(" %s", filename);
+ putchar('\n');
+}
+
char *
getmnton(struct mount *m)
{
- static struct mount mount;
+ static struct mount mnt;
static struct mtab {
struct mtab *next;
struct mount *m;
@@ -616,14 +876,14 @@ getmnton(struct mount *m)
for (mt = mhead; mt != NULL; mt = mt->next)
if (m == mt->m)
return (mt->mntonname);
- if (!kvm_read_all(kd, (unsigned long)m, &mount, sizeof(struct mount))) {
+ if (!kvm_read_all(kd, (unsigned long)m, &mnt, sizeof(struct mount))) {
warnx("can't read mount table at %p", (void *)m);
return (NULL);
}
if ((mt = malloc(sizeof (struct mtab))) == NULL)
err(1, NULL);
mt->m = m;
- bcopy(&mount.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN);
+ bcopy(&mnt.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN);
mt->next = mhead;
mhead = mt;
return (mt->mntonname);
More information about the svn-src-projects
mailing list