Date: Thu, 16 Jul 2009 17:31:23 +0000 (UTC) From: Stanislav Sedov <stas@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195723 - projects/libprocstat/usr.bin/fstat Message-ID: <200907161731.n6GHVNfU035509@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: stas Date: Thu Jul 16 17:31:23 2009 New Revision: 195723 URL: http://svn.freebsd.org/changeset/base/195723 Log: - Add mmapped files display support. - Cleanup. Modified: projects/libprocstat/usr.bin/fstat/fstat.c projects/libprocstat/usr.bin/fstat/libprocstat.c projects/libprocstat/usr.bin/fstat/libprocstat.h Modified: projects/libprocstat/usr.bin/fstat/fstat.c ============================================================================== --- projects/libprocstat/usr.bin/fstat/fstat.c Thu Jul 16 16:55:08 2009 (r195722) +++ projects/libprocstat/usr.bin/fstat/fstat.c Thu Jul 16 17:31:23 2009 (r195723) @@ -43,10 +43,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/queue.h> -#include <vm/vm.h> -#include <vm/vm_map.h> -#include <vm/vm_object.h> - #include <netinet/in.h> #include <assert.h> @@ -85,7 +81,6 @@ char *memf, *nlistf; static int getfname(const char *filename); static void dofiles(struct procstat *procstat, struct kinfo_proc *p); -static void dommap(struct procstat *procstat, struct kinfo_proc *p); static void print_access_flags(int flags); static void print_file_info(struct procstat *procstat, struct filestat *fst, const char *uname, const char *cmd, int pid); @@ -198,8 +193,6 @@ do_fstat(int argc, char **argv) if (p[i].ki_stat == SZOMB) continue; dofiles(procstat, &p[i]); - if (mflg) - dommap(procstat, &p[i]); } free(p); procstat_close(procstat); @@ -207,13 +200,6 @@ do_fstat(int argc, char **argv) } static void -dommap(struct procstat *procstat __unused, struct kinfo_proc *kp __unused) -{ - - fprintf(stderr, "Not implemented\n"); -} - -static void dofiles(struct procstat *procstat, struct kinfo_proc *kp) { struct filestat_list *head; @@ -226,10 +212,9 @@ dofiles(struct procstat *procstat, struc pid = kp->ki_pid; cmd = kp->ki_comm; - head = procstat_getfiles(procstat, kp); + head = procstat_getfiles(procstat, kp, mflg); if (head == NULL) return; - STAILQ_FOREACH(fst, head, next) print_file_info(procstat, fst, uname, cmd, pid); } Modified: projects/libprocstat/usr.bin/fstat/libprocstat.c ============================================================================== --- projects/libprocstat/usr.bin/fstat/libprocstat.c Thu Jul 16 16:55:08 2009 (r195722) +++ projects/libprocstat/usr.bin/fstat/libprocstat.c Thu Jul 16 17:31:23 2009 (r195723) @@ -167,9 +167,9 @@ struct { static char *getmnton(kvm_t *kd, struct mount *m); static struct filestat_list *procstat_getfiles_kvm(kvm_t *kd, - struct kinfo_proc *kp); + struct kinfo_proc *kp, int mmapped); static struct filestat_list *procstat_getfiles_sysctl( - struct kinfo_proc *kp); + struct kinfo_proc *kp, int mmapped); static int procstat_get_pipe_info_sysctl(struct filestat *fst, struct pipestat *pipe, char *errbuf); static int procstat_get_pipe_info_kvm(kvm_t *kd, struct filestat *fst, @@ -292,13 +292,13 @@ fail: } struct filestat_list * -procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp) +procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) { if (procstat->type == PROCSTAT_SYSCTL) - return (procstat_getfiles_sysctl(kp)); + return (procstat_getfiles_sysctl(kp, mmapped)); else if (procstat->type == PROCSTAT_KVM) - return (procstat_getfiles_kvm(procstat->kd, kp)); + return (procstat_getfiles_kvm(procstat->kd, kp, mmapped)); else return (NULL); } @@ -321,7 +321,7 @@ filestat_new_entry(struct vnode *vp, int } static struct filestat_list * -procstat_getfiles_kvm(kvm_t *kd, struct kinfo_proc *kp) +procstat_getfiles_kvm(kvm_t *kd, struct kinfo_proc *kp, int mmapped) { int i; struct file file; @@ -332,6 +332,13 @@ procstat_getfiles_kvm(kvm_t *kd, struct struct filestat_list *head; int type; void *data; + vm_map_t map; + struct vmspace vmspace; + struct vm_map_entry vmentry; + vm_map_entry_t entryp; + struct vm_object object; + vm_object_t objp; + int prot, fflags; assert(kd); @@ -339,7 +346,7 @@ procstat_getfiles_kvm(kvm_t *kd, struct return (NULL); if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &filed, sizeof(filed))) { - warnx("can't read filedesc at %p\n", (void *)kp->ki_fd); + warnx("can't read filedesc at %p", (void *)kp->ki_fd); return (NULL); } @@ -391,21 +398,21 @@ procstat_getfiles_kvm(kvm_t *kd, struct ofiles = malloc(nfiles * sizeof(struct file *)); if (ofiles == NULL) { warn("malloc(%zd)", nfiles * sizeof(struct file *)); - goto exit; + goto do_mmapped; } if (!kvm_read_all(kd, (unsigned long)filed.fd_ofiles, ofiles, nfiles * sizeof(struct file *))) { - warn("cannot read file structures at %p\n", + warnx("cannot read file structures at %p", (void *)filed.fd_ofiles); free(ofiles); - goto exit; + goto do_mmapped; } 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))) { - warn("can't read file %d at %p\n", i, + warnx("can't read file %d at %p", i, (void *)ofiles[i]); continue; } @@ -433,7 +440,7 @@ procstat_getfiles_kvm(kvm_t *kd, struct break; #endif default: - warnx("unknown file type %d for file %d\n", + warnx("unknown file type %d for file %d", file.f_type, i); continue; } @@ -443,12 +450,69 @@ procstat_getfiles_kvm(kvm_t *kd, struct STAILQ_INSERT_TAIL(head, entry, next); } free(ofiles); + +do_mmapped: + + /* + * Process mmapped files if requested. + */ + if (mmapped) { + if (!kvm_read_all(kd, (unsigned long)kp->ki_vmspace, &vmspace, + sizeof(vmspace))) { + warnx("can't read vmspace at %p", + (void *)kp->ki_vmspace); + goto exit; + } + map = &vmspace.vm_map; + + for (entryp = map->header.next; + entryp != &kp->ki_vmspace->vm_map.header; + entryp = vmentry.next) { + if (!kvm_read_all(kd, (unsigned long)entryp, &vmentry, + sizeof(vmentry))) { + warnx("can't read vm_map_entry at %p", + (void *)entryp); + continue; + } + if (vmentry.eflags & MAP_ENTRY_IS_SUB_MAP) + continue; + if ((objp = vmentry.object.vm_object) == NULL) + continue; + for (; objp; objp = object.backing_object) { + if (!kvm_read_all(kd, (unsigned long)objp, + &object, sizeof(object))) { + warnx("can't read vm_object at %p", + (void *)objp); + break; + } + } + + /* We want only vnode objects. */ + if (object.type != OBJT_VNODE) + continue; + + prot = vmentry.protection; + fflags = 0; + if (prot & VM_PROT_READ) + fflags = PS_FST_FFLAG_READ; + if (prot & VM_PROT_WRITE) + fflags |= PS_FST_FFLAG_WRITE; + + /* + * Create filestat entry. + */ + entry = filestat_new_entry(object.handle, + PS_FST_TYPE_VNODE, PS_FST_FD_MMAP, fflags); + if (entry != NULL) + STAILQ_INSERT_TAIL(head, entry, next); + } + } exit: return (head); } static struct filestat_list * -procstat_getfiles_sysctl(struct kinfo_proc *kp __unused) +procstat_getfiles_sysctl(struct kinfo_proc *kp __unused, int mmapped) { return (NULL); } @@ -601,7 +665,7 @@ procstat_get_vnode_info_kvm(kvm_t *kd, s goto fail; error = kvm_read_all(kd, (unsigned long)vp, &vnode, sizeof(vnode)); if (error == 0) { - warnx("can't read vnode at %p\n", (void *)vp); + warnx("can't read vnode at %p", (void *)vp); goto fail; } bzero(vn, sizeof(*vn)); @@ -610,7 +674,7 @@ procstat_get_vnode_info_kvm(kvm_t *kd, s return (0); error = kvm_read_all(kd, (unsigned long)vnode.v_tag, tagstr, sizeof(tagstr)); if (error == 0) { - warnx("can't read v_tag at %p\n", (void *)vp); + warnx("can't read v_tag at %p", (void *)vp); goto fail; } tagstr[sizeof(tagstr) - 1] = '\0'; @@ -738,7 +802,7 @@ procstat_get_socket_info_kvm(kvm_t *kd, if (kvm_read(kd, (u_long)s.so_pcb, (char *)&inpcb, sizeof(struct inpcb)) != sizeof(struct inpcb)) { - warnx("can't read inpcb at %p\n", + warnx("can't read inpcb at %p", (void *)s.so_pcb); } else sock->inp_ppcb = @@ -750,7 +814,7 @@ procstat_get_socket_info_kvm(kvm_t *kd, if (s.so_pcb) { if (kvm_read(kd, (u_long)s.so_pcb, (char *)&unpcb, sizeof(struct unpcb)) != sizeof(struct unpcb)){ - warnx("can't read unpcb at %p\n", + warnx("can't read unpcb at %p", (void *)s.so_pcb); } else if (unpcb.unp_conn) { sock->so_rcv_sb_state = s.so_rcv.sb_state; Modified: projects/libprocstat/usr.bin/fstat/libprocstat.h ============================================================================== --- projects/libprocstat/usr.bin/fstat/libprocstat.h Thu Jul 16 16:55:08 2009 (r195722) +++ projects/libprocstat/usr.bin/fstat/libprocstat.h Thu Jul 16 17:31:23 2009 (r195723) @@ -126,7 +126,7 @@ STAILQ_HEAD(filestat_list, filestat); void procstat_close(struct procstat *procstat); struct filestat_list *procstat_getfiles(struct procstat *procstat, - struct kinfo_proc *kp); + struct kinfo_proc *kp, int mmapped); struct kinfo_proc *procstat_getprocs(struct procstat *procstat, int what, int arg, unsigned int *count); int procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907161731.n6GHVNfU035509>