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