summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-11-10 10:42:50 +0000
committerrwatson <rwatson@FreeBSD.org>2005-11-10 10:42:50 +0000
commit20a1214886ea883bdcce327b9722855ed3637aab (patch)
treeda99e78a9aec8b7b52662bf7c4596435c9868fdc /sys
parent439f89ac76f92a161885034fabf60ff2b5ee49f4 (diff)
downloadFreeBSD-src-20a1214886ea883bdcce327b9722855ed3637aab.zip
FreeBSD-src-20a1214886ea883bdcce327b9722855ed3637aab.tar.gz
Add a DDB "show files" command to list the current open file list, some
state about each open file, and identify the first process in the process table that references the file. This is helpful in debugging leaks of file descriptors. MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_descrip.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index f0c5650..9274f9b 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -38,6 +38,7 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -69,6 +70,8 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
+#include <ddb/ddb.h>
+
static MALLOC_DEFINE(M_FILEDESC, "filedesc", "Open file descriptor table");
static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "filedesc_to_leader",
"file desc to leader structures");
@@ -2466,6 +2469,76 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
0, 0, sysctl_kern_file, "S,xfile", "Entire file table");
+#ifdef DDB
+/*
+ * For the purposes of debugging, generate a human-readable string for the
+ * file type.
+ */
+static const char *
+file_type_to_name(short type)
+{
+
+ switch (type) {
+ case 0:
+ return ("zero");
+ case DTYPE_VNODE:
+ return ("vnod");
+ case DTYPE_SOCKET:
+ return ("sock");
+ case DTYPE_PIPE:
+ return ("pipe");
+ case DTYPE_FIFO:
+ return ("fifo");
+ case DTYPE_CRYPTO:
+ return ("crpt");
+ default:
+ return ("unkn");
+ }
+}
+
+/*
+ * For the purposes of debugging, identify a process (if any, perhaps one of
+ * many) that references the passed file in its file descriptor array. Return
+ * NULL if none.
+ */
+static struct proc *
+file_to_first_proc(struct file *fp)
+{
+ struct filedesc *fdp;
+ struct proc *p;
+ int n;
+
+ LIST_FOREACH(p, &allproc, p_list) {
+ if (p->p_state == PRS_NEW)
+ continue;
+ fdp = p->p_fd;
+ if (fdp == NULL)
+ continue;
+ for (n = 0; n < fdp->fd_nfiles; n++) {
+ if (fp == fdp->fd_ofiles[n])
+ return (p);
+ }
+ }
+ return (NULL);
+}
+
+DB_SHOW_COMMAND(files, db_show_files)
+{
+ struct file *fp;
+ struct proc *p;
+
+ db_printf("%9s %4s %9s %9s %6s %9s %6s %12s\n", "File", "Type",
+ "Data", "Flag", "Count", "Vnode", "FPid", "FCmd");
+ LIST_FOREACH(fp, &filehead, f_list) {
+ p = file_to_first_proc(fp);
+ db_printf("%9p %4s %9p 0x%09x %6d %9p %6d %12s\n", fp,
+ file_type_to_name(fp->f_type), fp->f_data, fp->f_flag,
+ fp->f_count, fp->f_vnode, p != NULL ? p->p_pid : -1,
+ p != NULL ? p->p_comm : "-");
+ }
+}
+#endif
+
SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
&maxfilesperproc, 0, "Maximum files allowed open per process");
OpenPOWER on IntegriCloud