summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-07-31 12:26:52 +0000
committerdes <des@FreeBSD.org>2002-07-31 12:26:52 +0000
commit5e9bc3c12a5ff59cda5edb46ea46bc9a43a902c6 (patch)
tree7b803d139b23e463d56100f5979954b93b6cd3f9 /sys/kern/kern_descrip.c
parent2ca172b7258cc03a502ae5ba4fcc74b22ec663fa (diff)
downloadFreeBSD-src-5e9bc3c12a5ff59cda5edb46ea46bc9a43a902c6.zip
FreeBSD-src-5e9bc3c12a5ff59cda5edb46ea46bc9a43a902c6.tar.gz
Have the kern.file sysctl export xfiles rather than files. The truth is
out there! Sponsored by: DARPA, NAI Labs
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 06aca87..30df164 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2040,43 +2040,70 @@ dupfdopen(td, fdp, indx, dfd, mode, error)
static int
sysctl_kern_file(SYSCTL_HANDLER_ARGS)
{
- int error;
+ struct proc *p;
+ struct filedesc *fdp;
struct file *fp;
+ struct xfile xf;
+ int error, n;
sysctl_wire_old_buffer(req, 0);
- sx_slock(&filelist_lock);
if (!req->oldptr) {
- /*
- * overestimate by 10 files
- */
- error = SYSCTL_OUT(req, 0, sizeof(filehead) +
- (nfiles + 10) * sizeof(struct file));
- sx_sunlock(&filelist_lock);
- return (error);
- }
-
- error = SYSCTL_OUT(req, &filehead, sizeof(filehead));
- if (error) {
+ n = 16; /* slight overestimate */
+ sx_slock(&filelist_lock);
+ LIST_FOREACH(fp, &filehead, f_list) {
+ /*
+ * We should grab the lock, but this is an
+ * estimate, so does it really matter?
+ */
+ /* mtx_lock(fp->f_mtxp); */
+ n += fp->f_count;
+ /* mtx_unlock(f->f_mtxp); */
+ }
sx_sunlock(&filelist_lock);
- return (error);
+ return (SYSCTL_OUT(req, 0, n * sizeof xf));
}
- /*
- * followed by an array of file structures
- */
- LIST_FOREACH(fp, &filehead, f_list) {
- error = SYSCTL_OUT(req, fp, sizeof (struct file));
- if (error) {
- sx_sunlock(&filelist_lock);
- return (error);
+ error = 0;
+ bzero(&xf, sizeof xf);
+ xf.xf_size = sizeof xf;
+ sx_slock(&allproc_lock);
+ LIST_FOREACH(p, &allproc, p_list) {
+ PROC_LOCK(p);
+ xf.xf_pid = p->p_pid;
+ xf.xf_uid = p->p_ucred->cr_uid;
+ if ((fdp = p->p_fd) == NULL) {
+ PROC_UNLOCK(p);
+ continue;
+ }
+ FILEDESC_LOCK(fdp);
+ for (n = 0; n < fdp->fd_nfiles; ++n) {
+ if ((fp = fdp->fd_ofiles[n]) == NULL)
+ continue;
+ xf.xf_fd = n;
+ xf.xf_file = fp;
+#define XF_COPY(field) xf.xf_##field = fp->f_##field
+ XF_COPY(type);
+ XF_COPY(count);
+ XF_COPY(msgcount);
+ XF_COPY(offset);
+ XF_COPY(data);
+ XF_COPY(flag);
+#undef XF_COPY
+ error = SYSCTL_OUT(req, &xf, sizeof xf);
+ if (error)
+ break;
}
+ FILEDESC_UNLOCK(fdp);
+ PROC_UNLOCK(p);
+ if (error)
+ break;
}
- sx_sunlock(&filelist_lock);
- return (0);
+ sx_sunlock(&allproc_lock);
+ return (error);
}
SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
- 0, 0, sysctl_kern_file, "S,file", "Entire file table");
+ 0, 0, sysctl_kern_file, "S,xfile", "Entire file table");
SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
&maxfilesperproc, 0, "Maximum files allowed open per process");
OpenPOWER on IntegriCloud