svn commit: r195664 - projects/libprocstat/usr.bin/fstat

Stanislav Sedov stas at FreeBSD.org
Mon Jul 13 21:18:55 UTC 2009


Author: stas
Date: Mon Jul 13 21:18:54 2009
New Revision: 195664
URL: http://svn.freebsd.org/changeset/base/195664

Log:
  - Work-in-progress work on separating access-independent fstat code from
    data access routines and attempt to create a generic transparent interface
    to kernel structures supporting both KVM and sysctl interfaces.  This is
    still very dirty and current fstat is broken in a number of ways (and only
    ordinary vnodes are supported now).

Added:
  projects/libprocstat/usr.bin/fstat/libprocstat.c
  projects/libprocstat/usr.bin/fstat/libprocstat.h
Modified:
  projects/libprocstat/usr.bin/fstat/Makefile
  projects/libprocstat/usr.bin/fstat/common.h
  projects/libprocstat/usr.bin/fstat/fstat.c
  projects/libprocstat/usr.bin/fstat/fuser.c

Modified: projects/libprocstat/usr.bin/fstat/Makefile
==============================================================================
--- projects/libprocstat/usr.bin/fstat/Makefile	Mon Jul 13 20:19:29 2009	(r195663)
+++ projects/libprocstat/usr.bin/fstat/Makefile	Mon Jul 13 21:18:54 2009	(r195664)
@@ -4,12 +4,10 @@
 .include <bsd.own.mk>
 
 PROG=	fstat
-SRCS=	cd9660.c common.c fstat.c main.c msdosfs.c fuser.c
+SRCS=	cd9660.c common.c fstat.c main.c msdosfs.c fuser.c libprocstat.c
 LINKS=	${BINDIR}/fstat ${BINDIR}/fuser
 DPADD=	${LIBKVM}
 LDADD=	-lkvm -lutil
-BINGRP=	kmem
-BINMODE=2555
 WARNS?=	6
 
 MAN1=	fuser.1 fstat.1

Modified: projects/libprocstat/usr.bin/fstat/common.h
==============================================================================
--- projects/libprocstat/usr.bin/fstat/common.h	Mon Jul 13 20:19:29 2009	(r195663)
+++ projects/libprocstat/usr.bin/fstat/common.h	Mon Jul 13 21:18:54 2009	(r195664)
@@ -42,6 +42,12 @@ struct  filestat {
 	mode_t	mode;
 	u_long	size;
 	dev_t	rdev;
+	int	vtype;
+	int	type;
+	char	*mntdir;
+	int	flags;
+	int	fflags;
+	int	fd;
 };
 
 extern int vflg;

Modified: projects/libprocstat/usr.bin/fstat/fstat.c
==============================================================================
--- projects/libprocstat/usr.bin/fstat/fstat.c	Mon Jul 13 20:19:29 2009	(r195663)
+++ projects/libprocstat/usr.bin/fstat/fstat.c	Mon Jul 13 21:18:54 2009	(r195664)
@@ -87,6 +87,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip.h>
 #include <netinet/in_pcb.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <err.h>
 #include <fcntl.h>
@@ -104,13 +105,7 @@ __FBSDID("$FreeBSD$");
 
 #include "common.h"
 #include "functions.h"
-
-#define	TEXT	-1
-#define	CDIR	-2
-#define	RDIR	-3
-#define	TRACE	-4
-#define	MMAP	-5
-#define	JDIR	-6
+#include "libprocstat.h"
 
 int 	fsflg,	/* show files on same filesystem as file(s) argument */
 	pflg,	/* show files open by a particular pid */
@@ -128,27 +123,30 @@ typedef struct devs {
 
 DEVS *devs;
 char *memf, *nlistf;
-kvm_t *kd;
 
-static void fstat_kvm(int, int);
-static void fstat_sysctl(int, int);
-void dofiles(struct kinfo_proc *kp);
+static void fstat1(int what, int arg);
+static void dofiles(struct procstat *procstat, struct kinfo_proc *p);
 void dofiles_kinfo(struct kinfo_proc *kp);
 void dommap(struct kinfo_proc *kp);
-void vtrans(struct vnode *vp, int i, int flag);
+void vtrans(struct vnode *vp, int i, int flag, const char *uname, const char *cmd, int pid);
 char *getmnton(struct mount *m);
-void pipetrans(struct pipe *pi, int i, int flag);
-void socktrans(struct socket *sock, int i);
-void ptstrans(struct tty *tp, int i, int flag);
+void pipetrans(struct pipe *pi, int i, int flag, const char *uname, const char *cmd, int pid);
+void socktrans(struct socket *sock, int i, const char *uname, const char *cmd, int pid);
+void ptstrans(struct tty *tp, int i, int flag, const char *uname, const char *cmd, int pid);
 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);
+void vtrans_kinfo(struct kinfo_file *, int i, int flag, const char *uname, const char *cmd, int pid);
+static void print_file_info(struct procstat *procstat, struct filestat *fst, const char *uname, const char *cmd, int pid);
 
-/* XXX: sys/mount.h */
-int	statfs(const char *, struct statfs *);
+static void
+print_socket_info(struct procstat *procstat, struct filestat *fst);
+static void
+print_pipe_info(struct procstat *procstat, struct filestat *fst);
+static void
+print_pts_info(struct procstat *procstat, struct filestat *fst);
+static void
+print_vnode_info(struct procstat *procstat, struct filestat *fst);
 
 int
 do_fstat(int argc, char **argv)
@@ -218,17 +216,28 @@ do_fstat(int argc, char **argv)
 		checkfile = 1;
 	}
 
-	if (memf != NULL)
-		fstat_kvm(what, arg);
-	else
-		fstat_sysctl(what, arg);
+		fstat1(what, arg);
 	exit(0);
 }
 
 static void
-print_header(void)
+fstat1(int what, int arg)
 {
+	struct kinfo_proc *p;
+	struct procstat *procstat;
+	int cnt;
+	int i;
+
+	procstat = procstat_open(nlistf, memf);
+	if (procstat == NULL)
+		errx(1, "procstat_open()");
+	p = procstat_getprocs(procstat, what, arg, &cnt);
+	if (p == NULL)
+		errx(1, "procstat_getprocs()");
 
+	/*
+	 * Print header.
+	 */
 	if (nflg)
 		printf("%s",
 "USER     CMD          PID   FD  DEV    INUM       MODE SZ|DV R/W");
@@ -239,854 +248,206 @@ print_header(void)
 		printf(" NAME\n");
 	else
 		putchar('\n');
-}
-
-static void
-fstat_kvm(int what, int arg)
-{
-	struct kinfo_proc *p, *plast;
-	char buf[_POSIX2_LINE_MAX];
-	int cnt;
 
 	/*
-	 * Discard setgid privileges if not the running kernel so that bad
-	 * guys can't print interesting stuff from kernel memory.
+	 * Go through the process list.
 	 */
-	if (nlistf != NULL || memf != NULL)
-		setgid(getgid());
-
-	if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == NULL)
-		errx(1, "%s", buf);
-	setgid(getgid());
-	if ((p = kvm_getprocs(kd, what, arg, &cnt)) == NULL)
-		errx(1, "%s", kvm_geterr(kd));
-	print_header();
-	for (plast = &p[cnt]; p < plast; ++p) {
-		if (p->ki_stat == SZOMB)
+	for (i = 0; i < cnt; i++) {
+		if (p[i].ki_stat == SZOMB)
 			continue;
-		dofiles(p);
+		dofiles(procstat, &p[i]);
+/*
 		if (mflg)
-			dommap(p);
+			dommap(procstat, &p[i]);
+*/
 	}
-}
-
-/*
- * 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
-kinfo_proc_sort(struct kinfo_proc *kipp, int count)
-{
-
-	qsort(kipp, count, sizeof(*kipp), kinfo_proc_compare);
+	free(p);
+	procstat_close(procstat);
 }
 
 static void
-fstat_sysctl(int what, int arg)
+dofiles(struct procstat *procstat, struct kinfo_proc *kp)
 {
-	struct kinfo_proc *kipp;
-	int name[4];
-	size_t len;
+	struct filestat *fst;
+	unsigned int count;
+	const char *cmd, *uname;
+	int pid;
 	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;
-int	Pid;
-
-#define PREFIX(i) printf("%-8.8s %-10s %5d", Uname, Comm, Pid); \
-	switch(i) { \
-	case TEXT: \
-		printf(" text"); \
-		break; \
-	case CDIR: \
-		printf("   wd"); \
-		break; \
-	case RDIR: \
-		printf(" root"); \
-		break; \
-	case TRACE: \
-		printf("   tr"); \
-		break; \
-	case MMAP: \
-		printf(" mmap"); \
-		break; \
-	case JDIR: \
-		printf(" jail"); \
-		break; \
-	default: \
-		printf(" %4d", i); \
-		break; \
-	}
-
-/*
- * print open files attributed to this process
- */
-void
-dofiles(struct kinfo_proc *kp)
-{
-	int i;
-	struct file file;
-	struct filedesc filed;
-	unsigned int nfiles;
-	struct file **ofiles;
-
-	Uname = user_from_uid(kp->ki_uid, 0);
-	Pid = kp->ki_pid;
-	Comm = kp->ki_comm;
-
-	if (kp->ki_fd == NULL)
-		return;
-	if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &filed,
-	    sizeof(filed))) {
-		dprintf(stderr, "can't read filedesc at %p for pid %d\n",
-		    (void *)kp->ki_fd, Pid);
-		return;
-	}
-	/*
-	 * root directory vnode, if one
-	 */
-	if (filed.fd_rdir)
-		vtrans(filed.fd_rdir, RDIR, FREAD);
-	/*
-	 * current working directory vnode
-	 */
-	if (filed.fd_cdir)
-		vtrans(filed.fd_cdir, CDIR, FREAD);
-	/*
-	 * jail root, if any.
-	 */
-	if (filed.fd_jdir)
-		vtrans(filed.fd_jdir, JDIR, FREAD);
-	/*
-	 * ktrace vnode, if one
-	 */
-	if (kp->ki_tracep)
-		vtrans(kp->ki_tracep, TRACE, FREAD|FWRITE);
-	/*
-	 * text vnode, if one
-	 */
-	if (kp->ki_textvp)
-		vtrans(kp->ki_textvp, TEXT, FREAD);
-	/*
-	 * open files
-	 */
-#define FPSIZE	(sizeof (struct file *))
-#define MAX_LASTFILE	(0x1000000)
+	uname = user_from_uid(kp->ki_uid, 0);
+	pid = kp->ki_pid;
+	cmd = kp->ki_comm;
 
-	/* Sanity check on filed.fd_lastfile */
-	if (filed.fd_lastfile <= -1 || filed.fd_lastfile > MAX_LASTFILE)
+	fst = procstat_getfiles(procstat, kp, &count);
+	if (fst == NULL)
 		return;
 
-	nfiles = filed.fd_lastfile + 1;
-	ofiles = malloc(nfiles * sizeof(struct file *));
-	if (ofiles == NULL) {
-		warn("malloc(%zd)", nfiles * sizeof(struct file *));
-		return;
-	}
-	if (!kvm_read_all(kd, (unsigned long)filed.fd_ofiles, ofiles,
-	    (filed.fd_lastfile+1) * FPSIZE)) {
-		dprintf(stderr,
-		    "can't read file structures at %p for pid %d\n",
-		    (void *)filed.fd_ofiles, Pid);
-		free(ofiles);
-		return;
-	}
-	for (i = 0; i <= filed.fd_lastfile; i++) {
-		if (ofiles[i] == NULL)
-			continue;
-		if (!kvm_read_all(kd, (unsigned long)ofiles[i], &file,
-		    sizeof(struct file))) {
-			dprintf(stderr, "can't read file %d at %p for pid %d\n",
-			    i, (void *)ofiles[i], Pid);
-			continue;
-		}
-		if (file.f_type == DTYPE_VNODE)
-			vtrans(file.f_vnode, i, file.f_flag);
-		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);
-		}
-	}
-	free(ofiles);
+	for (i = 0; i < count; i++)
+		print_file_info(procstat, &fst[i], uname, cmd, pid);
 }
 
-/*
- * 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)
+static void
+print_file_info(struct procstat *procstat, struct filestat *fst,
+    const char *uname, const char *cmd, int pid)
 {
-	vm_map_t map;
-	struct vmspace vmspace;
-	struct vm_map_entry entry;
-	vm_map_entry_t entryp;
-	struct vm_object object;
-	vm_object_t objp;
-	int prot, fflags;
-
-	if (!kvm_read_all(kd, (unsigned long)kp->ki_vmspace, &vmspace,
-	    sizeof(vmspace))) {
-		dprintf(stderr,
-		    "can't read vmspace at %p for pid %d\n",
-		    (void *)kp->ki_vmspace, Pid);
-		return;
-	}
-	map = &vmspace.vm_map;
-
-	for (entryp = map->header.next;
-	    entryp != &kp->ki_vmspace->vm_map.header; entryp = entry.next) {
-		if (!kvm_read_all(kd, (unsigned long)entryp, &entry,
-		    sizeof(entry))) {
-			dprintf(stderr,
-			    "can't read vm_map_entry at %p for pid %d\n",
-			    (void *)entryp, Pid);
-			return;
-		}
-
-		if (entry.eflags & MAP_ENTRY_IS_SUB_MAP)
-			continue;
+	const char *badtype, *filename;
 
-		if ((objp = entry.object.vm_object) == NULL)
-			continue;
+	badtype = NULL;
+	filename = NULL;
+	if (fst->type == PS_FST_TYPE_VNODE || fst->type == PS_FST_TYPE_FIFO) {
+		if (fst->flags & PS_FST_FLAG_ERROR)
+			badtype = "error";
+		else if (fst->flags == PS_FST_FLAG_UNKNOWNFS)
+			badtype = "unknown";
+		else if (fst->vtype == PS_FST_VTYPE_VNON)
+			badtype = "none";
+		else if (fst->vtype == PS_FST_VTYPE_VBAD)
+			badtype = "bad";
+
+		if (checkfile) {
+			int fsmatch = 0;
+			DEVS *d;
 
-		for (; objp; objp = object.backing_object) {
-			if (!kvm_read_all(kd, (unsigned long)objp, &object,
-			    sizeof(object))) {
-				dprintf(stderr,
-				    "can't read vm_object at %p for pid %d\n",
-				    (void *)objp, Pid);
+			if (badtype)
 				return;
-			}
-		}
-
-		prot = entry.protection;
-		fflags = (prot & VM_PROT_READ ? FREAD : 0) |
-		    (prot & VM_PROT_WRITE ? FWRITE : 0);
-
-		switch (object.type) {
-		case OBJT_VNODE:
-			vtrans((struct vnode *)object.handle, MMAP, fflags);
-			break;
-		default:
-			break;
-		}
-	}
-}
-
-void
-vtrans(struct vnode *vp, int i, int flag)
-{
-	struct vnode vn;
-	struct filestat fst;
-	char rw[3], mode[15], tagstr[12], *tagptr;
-	const char *badtype, *filename;
-
-	filename = badtype = NULL;
-	if (!kvm_read_all(kd, (unsigned long)vp, &vn, sizeof(struct vnode))) {
-		dprintf(stderr, "can't read vnode at %p for pid %d\n",
-		    (void *)vp, Pid);
-		return;
-	}
-	if (!kvm_read_all(kd, (unsigned long)&vp->v_tag, &tagptr,
-	    sizeof(tagptr)) || !kvm_read_all(kd, (unsigned long)tagptr, tagstr,
-	    sizeof(tagstr))) {
-		dprintf(stderr, "can't read v_tag at %p for pid %d\n",
-		    (void *)vp, Pid);
-		return;
-	}
-	tagstr[sizeof(tagstr) - 1] = '\0';
-	if (vn.v_type == VNON)
-		badtype = "none";
-	else if (vn.v_type == VBAD)
-		badtype = "bad";
-	else {
-		if (!strcmp("ufs", tagstr)) {
-			if (!ufs_filestat(kd, &vn, &fst))
-				badtype = "error";
-		} else if (!strcmp("devfs", tagstr)) {
-			if (!devfs_filestat(kd, &vn, &fst))
-				badtype = "error";
-		} else if (!strcmp("nfs", tagstr)) {
-			if (!nfs_filestat(kd, &vn, &fst))
-				badtype = "error";
-		} else if (!strcmp("msdosfs", tagstr)) {
-			if (!msdosfs_filestat(kd, &vn, &fst))
-				badtype = "error";
-		} else if (!strcmp("isofs", tagstr)) {
-			if (!isofs_filestat(kd, &vn, &fst))
-				badtype = "error";
-#ifdef ZFS
-		} else if (!strcmp("zfs", tagstr)) {
-			if (!zfs_filestat(kd, &vn, &fst))
-				badtype = "error";
-#endif
-		} else {
-			static char unknown[32];
-			snprintf(unknown, sizeof unknown, "?(%s)", tagstr);
-			badtype = unknown;
-		}
-	}
-	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;
+			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);
+			if (fsmatch == 0 || (filename == NULL && fsflg == 0))
+				return;
+		}
+	} else if (checkfile != 0)
 		return;
-	}
-	if (nflg)
-		(void)printf(" %2d,%-2d", major(fst.fsid), minor(fst.fsid));
-	else
-		(void)printf(" %-8s", getmnton(vn.v_mount));
-	if (nflg)
-		(void)sprintf(mode, "%o", fst.mode);
-	else
-		strmode(fst.mode, mode);
-	(void)printf(" %6ld %10s", fst.fileid, mode);
-	switch (vn.v_type) {
-	case VBLK:
-	case VCHR: {
-		char *name;
 
-		name = kdevtoname(kd, vn.v_rdev);
-		if (nflg || !name)
-			printf("  %2d,%-2d", major(fst.rdev), minor(fst.rdev));
-		else {
-			printf(" %6s", name);
-			free(name);
-		}
+	/*
+	 * Print entry prefix.
+	 */
+	printf("%-8.8s %-10s %5d", uname, cmd, pid);
+	switch(fst->fd) {
+	case PS_FST_FD_TEXT:
+		printf(" text");
 		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');
-}
-
-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";
+	case PS_FST_FD_CDIR:
+		printf("   wd");
+		break;
+	case PS_FST_FD_RDIR:
+		printf(" root");
+		break;
+	case PS_FST_FD_TRACE:
+		printf("   tr");
+		break;
+	case PS_FST_FD_MMAP:
+		printf(" mmap");
 		break;
-	case VBAD:
-		badtype = "bad";
+	case PS_FST_FD_JAIL:
+		printf(" jail");
 		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;
+		printf(" %4d", fst->fd);
 		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);
-		}
+
+	/*
+	 * Print type-specific data.
+	 */
+	switch (fst->type) {
+	case PS_FST_TYPE_FIFO:
+	case PS_FST_TYPE_VNODE:
+		print_vnode_info(procstat, fst);
 		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);
-		}
+	case PS_FST_TYPE_SOCKET:
+		print_socket_info(procstat, fst);
 		break;
+	case PS_FST_TYPE_PIPE:
+		print_pipe_info(procstat, fst);
+		break;
+	case PS_FST_TYPE_PTS:
+		print_pts_info(procstat, fst);
+		break;
+	default:	
+		dprintf(stderr,
+		    "unknown file type %d for file %d of pid %d\n",
+		    fst->type, fst->fd, pid);
 	}
-	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 void
+print_socket_info(struct procstat *procstat __unused, struct filestat *fst __unused)
 {
-	static struct mount mnt;
-	static struct mtab {
-		struct mtab *next;
-		struct mount *m;
-		char mntonname[MNAMELEN];
-	} *mhead = NULL;
-	struct mtab *mt;
-
-	for (mt = mhead; mt != NULL; mt = mt->next)
-		if (m == mt->m)
-			return (mt->mntonname);
-	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(&mnt.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN);
-	mt->next = mhead;
-	mhead = mt;
-	return (mt->mntonname);
+
+	printf(" not implemented\n");
 }
 
-void
-pipetrans(struct pipe *pi, int i, int flag)
+static void
+print_pipe_info(struct procstat *procstat __unused, struct filestat *fst __unused)
 {
-	struct pipe pip;
-	char rw[3];
-
-	PREFIX(i);
 
-	/* fill in socket */
-	if (!kvm_read_all(kd, (unsigned long)pi, &pip, sizeof(struct pipe))) {
-		dprintf(stderr, "can't read pipe at %p\n", (void *)pi);
-		goto bad;
-	}
-
-	printf("* pipe %8lx <-> %8lx", (u_long)pi, (u_long)pip.pipe_peer);
-	printf(" %6d", (int)pip.pipe_buffer.cnt);
-	rw[0] = '\0';
-	if (flag & FREAD)
-		strcat(rw, "r");
-	if (flag & FWRITE)
-		strcat(rw, "w");
-	printf(" %2s", rw);
-	putchar('\n');
-	return;
-
-bad:
-	printf("* error\n");
+	printf(" not implemented\n");
 }
 
-void
-socktrans(struct socket *sock, int i)
+static void
+print_pts_info(struct procstat *procstat __unused, struct filestat *fst __unused)
 {
-	static const char *stypename[] = {
-		"unused",	/* 0 */
-		"stream", 	/* 1 */
-		"dgram",	/* 2 */
-		"raw",		/* 3 */
-		"rdm",		/* 4 */
-		"seqpak"	/* 5 */
-	};
-#define	STYPEMAX 5
-	struct socket	so;
-	struct protosw	proto;
-	struct domain	dom;
-	struct inpcb	inpcb;
-	struct unpcb	unpcb;
-	int len;
-	char dname[32];
-
-	PREFIX(i);
-
-	/* fill in socket */
-	if (!kvm_read_all(kd, (unsigned long)sock, &so,
-	    sizeof(struct socket))) {
-		dprintf(stderr, "can't read sock at %p\n", (void *)sock);
-		goto bad;
-	}
-
-	/* fill in protosw entry */
-	if (!kvm_read_all(kd, (unsigned long)so.so_proto, &proto,
-	    sizeof(struct protosw))) {
-		dprintf(stderr, "can't read protosw at %p",
-		    (void *)so.so_proto);
-		goto bad;
-	}
-
-	/* fill in domain */
-	if (!kvm_read_all(kd, (unsigned long)proto.pr_domain, &dom,
-	    sizeof(struct domain))) {
-		dprintf(stderr, "can't read domain at %p\n",
-		    (void *)proto.pr_domain);
-		goto bad;
-	}
-
-	if ((len = kvm_read(kd, (unsigned long)dom.dom_name, dname,
-	    sizeof(dname) - 1)) < 0) {
-		dprintf(stderr, "can't read domain name at %p\n",
-		    (void *)dom.dom_name);
-		dname[0] = '\0';
-	}
-	else
-		dname[len] = '\0';
 
-	if ((u_short)so.so_type > STYPEMAX)
-		printf("* %s ?%d", dname, so.so_type);
-	else
-		printf("* %s %s", dname, stypename[so.so_type]);
-
-	/*
-	 * protocol specific formatting
-	 *
-	 * Try to find interesting things to print.  For tcp, the interesting
-	 * thing is the address of the tcpcb, for udp and others, just the
-	 * inpcb (socket pcb).  For unix domain, its the address of the socket
-	 * pcb and the address of the connected pcb (if connected).  Otherwise
-	 * just print the protocol number and address of the socket itself.
-	 * The idea is not to duplicate netstat, but to make available enough
-	 * information for further analysis.
-	 */
-	switch(dom.dom_family) {
-	case AF_INET:
-	case AF_INET6:
-		getinetproto(proto.pr_protocol);
-		if (proto.pr_protocol == IPPROTO_TCP ) {
-			if (so.so_pcb) {
-				if (kvm_read(kd, (u_long)so.so_pcb,
-				    (char *)&inpcb, sizeof(struct inpcb))
-				    != sizeof(struct inpcb)) {
-					dprintf(stderr,
-					    "can't read inpcb at %p\n",
-					    (void *)so.so_pcb);
-					goto bad;
-				}
-				printf(" %lx", (u_long)inpcb.inp_ppcb);
-			}
-		}
-		else if (so.so_pcb)
-			printf(" %lx", (u_long)so.so_pcb);
-		break;
-	case AF_UNIX:
-		/* print address of pcb and connected pcb */
-		if (so.so_pcb) {
-			printf(" %lx", (u_long)so.so_pcb);
-			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&unpcb,
-			    sizeof(struct unpcb)) != sizeof(struct unpcb)){
-				dprintf(stderr, "can't read unpcb at %p\n",
-				    (void *)so.so_pcb);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list