Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136429249
D775.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
42 KB
Referenced Files
None
Subscribers
None
D775.id.diff
View Options
Index: head/sys/fs/devfs/devfs_vnops.c
===================================================================
--- head/sys/fs/devfs/devfs_vnops.c
+++ head/sys/fs/devfs/devfs_vnops.c
@@ -1700,6 +1700,7 @@
.fo_chown = vn_chown,
.fo_sendfile = vn_sendfile,
.fo_seek = vn_seek,
+ .fo_fill_kinfo = vn_fill_kinfo,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
Index: head/sys/kern/kern_descrip.c
===================================================================
--- head/sys/kern/kern_descrip.c
+++ head/sys/kern/kern_descrip.c
@@ -47,27 +47,21 @@
#include <sys/capsicum.h>
#include <sys/conf.h>
-#include <sys/domain.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/filio.h>
#include <sys/jail.h>
#include <sys/kernel.h>
-#include <sys/ksem.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
-#include <sys/mman.h>
#include <sys/mount.h>
-#include <sys/mqueue.h>
#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/selinfo.h>
-#include <sys/pipe.h>
#include <sys/priv.h>
#include <sys/proc.h>
-#include <sys/procdesc.h>
#include <sys/protosw.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
@@ -79,10 +73,7 @@
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysproto.h>
-#include <sys/tty.h>
#include <sys/unistd.h>
-#include <sys/un.h>
-#include <sys/unpcb.h>
#include <sys/user.h>
#include <sys/vnode.h>
#ifdef KTRACE
@@ -91,9 +82,6 @@
#include <net/vnet.h>
-#include <netinet/in.h>
-#include <netinet/in_pcb.h>
-
#include <security/audit/audit.h>
#include <vm/uma.h>
@@ -111,8 +99,6 @@
static uma_zone_t file_zone;
-void (*ksem_info)(struct ksem *ks, char *path, size_t size, uint32_t *value);
-
static int closefp(struct filedesc *fdp, int fd, struct file *fp,
struct thread *td, int holdleaders);
static int fd_first_free(struct filedesc *fdp, int low, int size);
@@ -121,14 +107,6 @@
static void fdgrowtable_exp(struct filedesc *fdp, int nfd);
static void fdunused(struct filedesc *fdp, int fd);
static void fdused(struct filedesc *fdp, int fd);
-static int fill_pipe_info(struct pipe *pi, struct kinfo_file *kif);
-static int fill_procdesc_info(struct procdesc *pdp,
- struct kinfo_file *kif);
-static int fill_pts_info(struct tty *tp, struct kinfo_file *kif);
-static int fill_sem_info(struct file *fp, struct kinfo_file *kif);
-static int fill_shm_info(struct file *fp, struct kinfo_file *kif);
-static int fill_socket_info(struct socket *so, struct kinfo_file *kif);
-static int fill_vnode_info(struct vnode *vp, struct kinfo_file *kif);
static int getmaxfd(struct proc *p);
/*
@@ -2945,280 +2923,14 @@
SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE,
0, 0, sysctl_kern_file, "S,xfile", "Entire file table");
-#ifdef KINFO_OFILE_SIZE
-CTASSERT(sizeof(struct kinfo_ofile) == KINFO_OFILE_SIZE);
-#endif
-
-#ifdef COMPAT_FREEBSD7
-static int
-export_vnode_for_osysctl(struct vnode *vp, int type,
- struct kinfo_ofile *kif, struct filedesc *fdp, struct sysctl_req *req)
-{
- int error;
- char *fullpath, *freepath;
-
- bzero(kif, sizeof(*kif));
- kif->kf_structsize = sizeof(*kif);
-
- vref(vp);
- kif->kf_fd = type;
- kif->kf_type = KF_TYPE_VNODE;
- /* This function only handles directories. */
- if (vp->v_type != VDIR) {
- vrele(vp);
- return (ENOTDIR);
- }
- kif->kf_vnode_type = KF_VTYPE_VDIR;
-
- /*
- * This is not a true file descriptor, so we set a bogus refcount
- * and offset to indicate these fields should be ignored.
- */
- kif->kf_ref_count = -1;
- kif->kf_offset = -1;
-
- freepath = NULL;
- fullpath = "-";
- FILEDESC_SUNLOCK(fdp);
- vn_fullpath(curthread, vp, &fullpath, &freepath);
- vrele(vp);
- strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path));
- if (freepath != NULL)
- free(freepath, M_TEMP);
- error = SYSCTL_OUT(req, kif, sizeof(*kif));
- FILEDESC_SLOCK(fdp);
- return (error);
-}
-
-/*
- * Get per-process file descriptors for use by procstat(1), et al.
- */
-static int
-sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
-{
- char *fullpath, *freepath;
- struct kinfo_ofile *kif;
- struct filedesc *fdp;
- int error, i, *name;
- struct shmfd *shmfd;
- struct socket *so;
- struct vnode *vp;
- struct ksem *ks;
- struct file *fp;
- struct proc *p;
- struct tty *tp;
-
- name = (int *)arg1;
- error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
- if (error != 0)
- return (error);
- fdp = fdhold(p);
- PROC_UNLOCK(p);
- if (fdp == NULL)
- return (ENOENT);
- kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
- FILEDESC_SLOCK(fdp);
- if (fdp->fd_cdir != NULL)
- export_vnode_for_osysctl(fdp->fd_cdir, KF_FD_TYPE_CWD, kif,
- fdp, req);
- if (fdp->fd_rdir != NULL)
- export_vnode_for_osysctl(fdp->fd_rdir, KF_FD_TYPE_ROOT, kif,
- fdp, req);
- if (fdp->fd_jdir != NULL)
- export_vnode_for_osysctl(fdp->fd_jdir, KF_FD_TYPE_JAIL, kif,
- fdp, req);
- for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
- if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
- continue;
- bzero(kif, sizeof(*kif));
- kif->kf_structsize = sizeof(*kif);
- ks = NULL;
- vp = NULL;
- so = NULL;
- tp = NULL;
- shmfd = NULL;
- kif->kf_fd = i;
-
- switch (fp->f_type) {
- case DTYPE_VNODE:
- kif->kf_type = KF_TYPE_VNODE;
- vp = fp->f_vnode;
- break;
-
- case DTYPE_SOCKET:
- kif->kf_type = KF_TYPE_SOCKET;
- so = fp->f_data;
- break;
-
- case DTYPE_PIPE:
- kif->kf_type = KF_TYPE_PIPE;
- break;
-
- case DTYPE_FIFO:
- kif->kf_type = KF_TYPE_FIFO;
- vp = fp->f_vnode;
- break;
-
- case DTYPE_KQUEUE:
- kif->kf_type = KF_TYPE_KQUEUE;
- break;
-
- case DTYPE_CRYPTO:
- kif->kf_type = KF_TYPE_CRYPTO;
- break;
-
- case DTYPE_MQUEUE:
- kif->kf_type = KF_TYPE_MQUEUE;
- break;
-
- case DTYPE_SHM:
- kif->kf_type = KF_TYPE_SHM;
- shmfd = fp->f_data;
- break;
-
- case DTYPE_SEM:
- kif->kf_type = KF_TYPE_SEM;
- ks = fp->f_data;
- break;
-
- case DTYPE_PTS:
- kif->kf_type = KF_TYPE_PTS;
- tp = fp->f_data;
- break;
-
- case DTYPE_PROCDESC:
- kif->kf_type = KF_TYPE_PROCDESC;
- break;
-
- default:
- kif->kf_type = KF_TYPE_UNKNOWN;
- break;
- }
- kif->kf_ref_count = fp->f_count;
- if (fp->f_flag & FREAD)
- kif->kf_flags |= KF_FLAG_READ;
- if (fp->f_flag & FWRITE)
- kif->kf_flags |= KF_FLAG_WRITE;
- if (fp->f_flag & FAPPEND)
- kif->kf_flags |= KF_FLAG_APPEND;
- if (fp->f_flag & FASYNC)
- kif->kf_flags |= KF_FLAG_ASYNC;
- if (fp->f_flag & FFSYNC)
- kif->kf_flags |= KF_FLAG_FSYNC;
- if (fp->f_flag & FNONBLOCK)
- kif->kf_flags |= KF_FLAG_NONBLOCK;
- if (fp->f_flag & O_DIRECT)
- kif->kf_flags |= KF_FLAG_DIRECT;
- if (fp->f_flag & FHASLOCK)
- kif->kf_flags |= KF_FLAG_HASLOCK;
- kif->kf_offset = foffset_get(fp);
- if (vp != NULL) {
- vref(vp);
- switch (vp->v_type) {
- case VNON:
- kif->kf_vnode_type = KF_VTYPE_VNON;
- break;
- case VREG:
- kif->kf_vnode_type = KF_VTYPE_VREG;
- break;
- case VDIR:
- kif->kf_vnode_type = KF_VTYPE_VDIR;
- break;
- case VBLK:
- kif->kf_vnode_type = KF_VTYPE_VBLK;
- break;
- case VCHR:
- kif->kf_vnode_type = KF_VTYPE_VCHR;
- break;
- case VLNK:
- kif->kf_vnode_type = KF_VTYPE_VLNK;
- break;
- case VSOCK:
- kif->kf_vnode_type = KF_VTYPE_VSOCK;
- break;
- case VFIFO:
- kif->kf_vnode_type = KF_VTYPE_VFIFO;
- break;
- case VBAD:
- kif->kf_vnode_type = KF_VTYPE_VBAD;
- break;
- default:
- kif->kf_vnode_type = KF_VTYPE_UNKNOWN;
- break;
- }
- /*
- * It is OK to drop the filedesc lock here as we will
- * re-validate and re-evaluate its properties when
- * the loop continues.
- */
- freepath = NULL;
- fullpath = "-";
- FILEDESC_SUNLOCK(fdp);
- vn_fullpath(curthread, vp, &fullpath, &freepath);
- vrele(vp);
- strlcpy(kif->kf_path, fullpath,
- sizeof(kif->kf_path));
- if (freepath != NULL)
- free(freepath, M_TEMP);
- FILEDESC_SLOCK(fdp);
- }
- if (so != NULL) {
- struct sockaddr *sa;
-
- if (so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa)
- == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
- bcopy(sa, &kif->kf_sa_local, sa->sa_len);
- free(sa, M_SONAME);
- }
- if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa)
- == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
- bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
- free(sa, M_SONAME);
- }
- kif->kf_sock_domain =
- so->so_proto->pr_domain->dom_family;
- kif->kf_sock_type = so->so_type;
- kif->kf_sock_protocol = so->so_proto->pr_protocol;
- }
- if (tp != NULL) {
- strlcpy(kif->kf_path, tty_devname(tp),
- sizeof(kif->kf_path));
- }
- if (shmfd != NULL)
- shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path));
- if (ks != NULL && ksem_info != NULL)
- ksem_info(ks, kif->kf_path, sizeof(kif->kf_path), NULL);
- error = SYSCTL_OUT(req, kif, sizeof(*kif));
- if (error)
- break;
- }
- FILEDESC_SUNLOCK(fdp);
- fddrop(fdp);
- free(kif, M_TEMP);
- return (0);
-}
-
-static SYSCTL_NODE(_kern_proc, KERN_PROC_OFILEDESC, ofiledesc,
- CTLFLAG_RD||CTLFLAG_MPSAFE, sysctl_kern_proc_ofiledesc,
- "Process ofiledesc entries");
-#endif /* COMPAT_FREEBSD7 */
-
#ifdef KINFO_FILE_SIZE
CTASSERT(sizeof(struct kinfo_file) == KINFO_FILE_SIZE);
#endif
-struct export_fd_buf {
- struct filedesc *fdp;
- struct sbuf *sb;
- ssize_t remainder;
- struct kinfo_file kif;
-};
-
static int
-export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt,
- int64_t offset, cap_rights_t *rightsp, struct export_fd_buf *efbuf)
+xlate_fflags(int fflags)
{
- struct {
+ static const struct {
int fflag;
int kf_fflag;
} fflags_table[] = {
@@ -3238,83 +2950,126 @@
{ O_SHLOCK, KF_FLAG_SHLOCK },
{ O_TRUNC, KF_FLAG_TRUNC }
};
-#define NFFLAGS (sizeof(fflags_table) / sizeof(*fflags_table))
- struct kinfo_file *kif;
- struct vnode *vp;
- int error, locked;
unsigned int i;
+ int kflags;
+
+ kflags = 0;
+ for (i = 0; i < nitems(fflags_table); i++)
+ if (fflags & fflags_table[i].fflag)
+ kflags |= fflags_table[i].kf_fflag;
+ return (kflags);
+}
+
+/* Trim unused data from kf_path by truncating the structure size. */
+static void
+pack_kinfo(struct kinfo_file *kif)
+{
+
+ kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
+ strlen(kif->kf_path) + 1;
+ kif->kf_structsize = roundup(kif->kf_structsize, sizeof(uint64_t));
+}
+
+static void
+export_file_to_kinfo(struct file *fp, int fd, cap_rights_t *rightsp,
+ struct kinfo_file *kif, struct filedesc *fdp)
+{
+ int error;
- if (efbuf->remainder == 0)
- return (0);
- kif = &efbuf->kif;
bzero(kif, sizeof(*kif));
- locked = efbuf->fdp != NULL;
- switch (type) {
- case KF_TYPE_FIFO:
- case KF_TYPE_VNODE:
- if (locked) {
- FILEDESC_SUNLOCK(efbuf->fdp);
- locked = 0;
- }
- vp = (struct vnode *)data;
- error = fill_vnode_info(vp, kif);
- vrele(vp);
- break;
- case KF_TYPE_SOCKET:
- error = fill_socket_info((struct socket *)data, kif);
- break;
- case KF_TYPE_PIPE:
- error = fill_pipe_info((struct pipe *)data, kif);
- break;
- case KF_TYPE_PTS:
- error = fill_pts_info((struct tty *)data, kif);
- break;
- case KF_TYPE_PROCDESC:
- error = fill_procdesc_info((struct procdesc *)data, kif);
- break;
- case KF_TYPE_SEM:
- error = fill_sem_info((struct file *)data, kif);
- break;
- case KF_TYPE_SHM:
- error = fill_shm_info((struct file *)data, kif);
- break;
- default:
- error = 0;
- }
- if (error == 0)
- kif->kf_status |= KF_ATTR_VALID;
- /*
- * Translate file access flags.
- */
- for (i = 0; i < NFFLAGS; i++)
- if (fflags & fflags_table[i].fflag)
- kif->kf_flags |= fflags_table[i].kf_fflag;
+ /* Set a default type to allow for empty fill_kinfo() methods. */
+ kif->kf_type = KF_TYPE_UNKNOWN;
+ kif->kf_flags = xlate_fflags(fp->f_flag);
if (rightsp != NULL)
kif->kf_cap_rights = *rightsp;
else
cap_rights_init(&kif->kf_cap_rights);
kif->kf_fd = fd;
- kif->kf_type = type;
- kif->kf_ref_count = refcnt;
- kif->kf_offset = offset;
- /* Pack record size down */
- kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
- strlen(kif->kf_path) + 1;
- kif->kf_structsize = roundup(kif->kf_structsize, sizeof(uint64_t));
+ kif->kf_ref_count = fp->f_count;
+ kif->kf_offset = foffset_get(fp);
+
+ /*
+ * This may drop the filedesc lock, so the 'fp' cannot be
+ * accessed after this call.
+ */
+ error = fo_fill_kinfo(fp, kif, fdp);
+ if (error == 0)
+ kif->kf_status |= KF_ATTR_VALID;
+ pack_kinfo(kif);
+}
+
+static void
+export_vnode_to_kinfo(struct vnode *vp, int fd, int fflags,
+ struct kinfo_file *kif)
+{
+ int error;
+
+ bzero(kif, sizeof(*kif));
+
+ kif->kf_type = KF_TYPE_VNODE;
+ error = vn_fill_kinfo_vnode(vp, kif);
+ if (error == 0)
+ kif->kf_status |= KF_ATTR_VALID;
+ kif->kf_flags = xlate_fflags(fflags);
+ kif->kf_fd = fd;
+ kif->kf_ref_count = -1;
+ kif->kf_offset = -1;
+ pack_kinfo(kif);
+ vrele(vp);
+}
+
+struct export_fd_buf {
+ struct filedesc *fdp;
+ struct sbuf *sb;
+ ssize_t remainder;
+ struct kinfo_file kif;
+};
+
+static int
+export_kinfo_to_sb(struct export_fd_buf *efbuf)
+{
+ struct kinfo_file *kif;
+
+ kif = &efbuf->kif;
if (efbuf->remainder != -1) {
if (efbuf->remainder < kif->kf_structsize) {
/* Terminate export. */
efbuf->remainder = 0;
- if (efbuf->fdp != NULL && !locked)
- FILEDESC_SLOCK(efbuf->fdp);
return (0);
}
efbuf->remainder -= kif->kf_structsize;
}
- if (locked)
+ return (sbuf_bcat(efbuf->sb, kif, kif->kf_structsize));
+}
+
+static int
+export_file_to_sb(struct file *fp, int fd, cap_rights_t *rightsp,
+ struct export_fd_buf *efbuf)
+{
+ int error;
+
+ if (efbuf->remainder == 0)
+ return (0);
+ export_file_to_kinfo(fp, fd, rightsp, &efbuf->kif, efbuf->fdp);
+ FILEDESC_SUNLOCK(efbuf->fdp);
+ error = export_kinfo_to_sb(efbuf);
+ FILEDESC_SLOCK(efbuf->fdp);
+ return (error);
+}
+
+static int
+export_vnode_to_sb(struct vnode *vp, int fd, int fflags,
+ struct export_fd_buf *efbuf)
+{
+ int error;
+
+ if (efbuf->remainder == 0)
+ return (0);
+ if (efbuf->fdp != NULL)
FILEDESC_SUNLOCK(efbuf->fdp);
- error = sbuf_bcat(efbuf->sb, kif, kif->kf_structsize);
+ export_vnode_to_kinfo(vp, fd, fflags, &efbuf->kif);
+ error = export_kinfo_to_sb(efbuf);
if (efbuf->fdp != NULL)
FILEDESC_SLOCK(efbuf->fdp);
return (error);
@@ -3328,16 +3083,15 @@
int
kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
{
+ struct thread *td;
struct file *fp;
struct filedesc *fdp;
struct export_fd_buf *efbuf;
struct vnode *cttyvp, *textvp, *tracevp;
- int64_t offset;
- void *data;
int error, i;
- int type, refcnt, fflags;
cap_rights_t rights;
+ td = curthread;
PROC_LOCK_ASSERT(p, MA_OWNED);
/* ktrace vnode */
@@ -3362,14 +3116,13 @@
efbuf->sb = sb;
efbuf->remainder = maxlen;
if (tracevp != NULL)
- export_fd_to_sb(tracevp, KF_TYPE_VNODE, KF_FD_TYPE_TRACE,
- FREAD | FWRITE, -1, -1, NULL, efbuf);
+ export_vnode_to_sb(tracevp, KF_FD_TYPE_TRACE, FREAD | FWRITE,
+ efbuf);
if (textvp != NULL)
- export_fd_to_sb(textvp, KF_TYPE_VNODE, KF_FD_TYPE_TEXT,
- FREAD, -1, -1, NULL, efbuf);
+ export_vnode_to_sb(textvp, KF_FD_TYPE_TEXT, FREAD, efbuf);
if (cttyvp != NULL)
- export_fd_to_sb(cttyvp, KF_TYPE_VNODE, KF_FD_TYPE_CTTY,
- FREAD | FWRITE, -1, -1, NULL, efbuf);
+ export_vnode_to_sb(cttyvp, KF_FD_TYPE_CTTY, FREAD | FWRITE,
+ efbuf);
error = 0;
if (fdp == NULL)
goto fail;
@@ -3378,105 +3131,34 @@
/* working directory */
if (fdp->fd_cdir != NULL) {
vref(fdp->fd_cdir);
- data = fdp->fd_cdir;
- export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_CWD,
- FREAD, -1, -1, NULL, efbuf);
+ export_vnode_to_sb(fdp->fd_cdir, KF_FD_TYPE_CWD, FREAD, efbuf);
}
/* root directory */
if (fdp->fd_rdir != NULL) {
vref(fdp->fd_rdir);
- data = fdp->fd_rdir;
- export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_ROOT,
- FREAD, -1, -1, NULL, efbuf);
+ export_vnode_to_sb(fdp->fd_rdir, KF_FD_TYPE_ROOT, FREAD, efbuf);
}
/* jail directory */
if (fdp->fd_jdir != NULL) {
vref(fdp->fd_jdir);
- data = fdp->fd_jdir;
- export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_JAIL,
- FREAD, -1, -1, NULL, efbuf);
+ export_vnode_to_sb(fdp->fd_jdir, KF_FD_TYPE_JAIL, FREAD, efbuf);
}
for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
continue;
- data = NULL;
#ifdef CAPABILITIES
rights = *cap_rights(fdp, i);
#else /* !CAPABILITIES */
cap_rights_init(&rights);
#endif
- switch (fp->f_type) {
- case DTYPE_VNODE:
- type = KF_TYPE_VNODE;
- vref(fp->f_vnode);
- data = fp->f_vnode;
- break;
-
- case DTYPE_SOCKET:
- type = KF_TYPE_SOCKET;
- data = fp->f_data;
- break;
-
- case DTYPE_PIPE:
- type = KF_TYPE_PIPE;
- data = fp->f_data;
- break;
-
- case DTYPE_FIFO:
- type = KF_TYPE_FIFO;
- vref(fp->f_vnode);
- data = fp->f_vnode;
- break;
-
- case DTYPE_KQUEUE:
- type = KF_TYPE_KQUEUE;
- break;
-
- case DTYPE_CRYPTO:
- type = KF_TYPE_CRYPTO;
- break;
-
- case DTYPE_MQUEUE:
- type = KF_TYPE_MQUEUE;
- break;
-
- case DTYPE_SHM:
- type = KF_TYPE_SHM;
- data = fp;
- break;
-
- case DTYPE_SEM:
- type = KF_TYPE_SEM;
- data = fp;
- break;
-
- case DTYPE_PTS:
- type = KF_TYPE_PTS;
- data = fp->f_data;
- break;
-
- case DTYPE_PROCDESC:
- type = KF_TYPE_PROCDESC;
- data = fp->f_data;
- break;
-
- default:
- type = KF_TYPE_UNKNOWN;
- break;
- }
- refcnt = fp->f_count;
- fflags = fp->f_flag;
- offset = foffset_get(fp);
-
/*
- * Create sysctl entry.
- * It is OK to drop the filedesc lock here as we will
- * re-validate and re-evaluate its properties when
- * the loop continues.
+ * Create sysctl entry. It is OK to drop the filedesc
+ * lock inside of export_file_to_sb() as we will
+ * re-validate and re-evaluate its properties when the
+ * loop continues.
*/
- error = export_fd_to_sb(data, type, i, fflags, refcnt,
- offset, &rights, efbuf);
- if (error != 0)
+ error = export_file_to_sb(fp, i, &rights, efbuf);
+ if (error != 0 || efbuf->remainder == 0)
break;
}
FILEDESC_SUNLOCK(fdp);
@@ -3514,6 +3196,105 @@
return (error != 0 ? error : error2);
}
+#ifdef KINFO_OFILE_SIZE
+CTASSERT(sizeof(struct kinfo_ofile) == KINFO_OFILE_SIZE);
+#endif
+
+#ifdef COMPAT_FREEBSD7
+static void
+kinfo_to_okinfo(struct kinfo_file *kif, struct kinfo_ofile *okif)
+{
+
+ okif->kf_structsize = sizeof(*okif);
+ okif->kf_type = kif->kf_type;
+ okif->kf_fd = kif->kf_fd;
+ okif->kf_ref_count = kif->kf_ref_count;
+ okif->kf_flags = kif->kf_flags & (KF_FLAG_READ | KF_FLAG_WRITE |
+ KF_FLAG_APPEND | KF_FLAG_ASYNC | KF_FLAG_FSYNC | KF_FLAG_NONBLOCK |
+ KF_FLAG_DIRECT | KF_FLAG_HASLOCK);
+ okif->kf_offset = kif->kf_offset;
+ okif->kf_vnode_type = kif->kf_vnode_type;
+ okif->kf_sock_domain = kif->kf_sock_domain;
+ okif->kf_sock_type = kif->kf_sock_type;
+ okif->kf_sock_protocol = kif->kf_sock_protocol;
+ strlcpy(okif->kf_path, kif->kf_path, sizeof(okif->kf_path));
+ okif->kf_sa_local = kif->kf_sa_local;
+ okif->kf_sa_peer = kif->kf_sa_peer;
+}
+
+static int
+export_vnode_for_osysctl(struct vnode *vp, int type, struct kinfo_file *kif,
+ struct kinfo_ofile *okif, struct filedesc *fdp, struct sysctl_req *req)
+{
+ int error;
+
+ vref(vp);
+ FILEDESC_SUNLOCK(fdp);
+ export_vnode_to_kinfo(vp, type, 0, kif);
+ kinfo_to_okinfo(kif, okif);
+ error = SYSCTL_OUT(req, okif, sizeof(*okif));
+ FILEDESC_SLOCK(fdp);
+ return (error);
+}
+
+/*
+ * Get per-process file descriptors for use by procstat(1), et al.
+ */
+static int
+sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
+{
+ struct kinfo_ofile *okif;
+ struct kinfo_file *kif;
+ struct filedesc *fdp;
+ struct thread *td;
+ int error, i, *name;
+ struct file *fp;
+ struct proc *p;
+
+ td = curthread;
+ name = (int *)arg1;
+ error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
+ if (error != 0)
+ return (error);
+ fdp = fdhold(p);
+ PROC_UNLOCK(p);
+ if (fdp == NULL)
+ return (ENOENT);
+ kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
+ okif = malloc(sizeof(*okif), M_TEMP, M_WAITOK);
+ FILEDESC_SLOCK(fdp);
+ if (fdp->fd_cdir != NULL)
+ export_vnode_for_osysctl(fdp->fd_cdir, KF_FD_TYPE_CWD, kif,
+ okif, fdp, req);
+ if (fdp->fd_rdir != NULL)
+ export_vnode_for_osysctl(fdp->fd_rdir, KF_FD_TYPE_ROOT, kif,
+ okif, fdp, req);
+ if (fdp->fd_jdir != NULL)
+ export_vnode_for_osysctl(fdp->fd_jdir, KF_FD_TYPE_JAIL, kif,
+ okif, fdp, req);
+ for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
+ if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
+ continue;
+ export_file_to_kinfo(fp, i, NULL, kif, fdp);
+ FILEDESC_SUNLOCK(fdp);
+ kinfo_to_okinfo(kif, okif);
+ error = SYSCTL_OUT(req, okif, sizeof(*okif));
+ FILEDESC_SLOCK(fdp);
+ if (error)
+ break;
+ }
+ FILEDESC_SUNLOCK(fdp);
+ fddrop(fdp);
+ free(kif, M_TEMP);
+ free(okif, M_TEMP);
+ return (0);
+}
+
+static SYSCTL_NODE(_kern_proc, KERN_PROC_OFILEDESC, ofiledesc,
+ CTLFLAG_RD||CTLFLAG_MPSAFE, sysctl_kern_proc_ofiledesc,
+ "Process ofiledesc entries");
+#endif /* COMPAT_FREEBSD7 */
+
int
vntype_to_kinfo(int vtype)
{
@@ -3543,170 +3324,6 @@
return (KF_VTYPE_UNKNOWN);
}
-static int
-fill_vnode_info(struct vnode *vp, struct kinfo_file *kif)
-{
- struct vattr va;
- char *fullpath, *freepath;
- int error;
-
- if (vp == NULL)
- return (1);
- kif->kf_vnode_type = vntype_to_kinfo(vp->v_type);
- freepath = NULL;
- fullpath = "-";
- error = vn_fullpath(curthread, vp, &fullpath, &freepath);
- if (error == 0) {
- strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path));
- }
- if (freepath != NULL)
- free(freepath, M_TEMP);
-
- /*
- * Retrieve vnode attributes.
- */
- va.va_fsid = VNOVAL;
- va.va_rdev = NODEV;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &va, curthread->td_ucred);
- VOP_UNLOCK(vp, 0);
- if (error != 0)
- return (error);
- if (va.va_fsid != VNOVAL)
- kif->kf_un.kf_file.kf_file_fsid = va.va_fsid;
- else
- kif->kf_un.kf_file.kf_file_fsid =
- vp->v_mount->mnt_stat.f_fsid.val[0];
- kif->kf_un.kf_file.kf_file_fileid = va.va_fileid;
- kif->kf_un.kf_file.kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
- kif->kf_un.kf_file.kf_file_size = va.va_size;
- kif->kf_un.kf_file.kf_file_rdev = va.va_rdev;
- return (0);
-}
-
-static int
-fill_socket_info(struct socket *so, struct kinfo_file *kif)
-{
- struct sockaddr *sa;
- struct inpcb *inpcb;
- struct unpcb *unpcb;
- int error;
-
- if (so == NULL)
- return (1);
- kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
- kif->kf_sock_type = so->so_type;
- kif->kf_sock_protocol = so->so_proto->pr_protocol;
- kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
- switch(kif->kf_sock_domain) {
- case AF_INET:
- case AF_INET6:
- if (kif->kf_sock_protocol == IPPROTO_TCP) {
- if (so->so_pcb != NULL) {
- inpcb = (struct inpcb *)(so->so_pcb);
- kif->kf_un.kf_sock.kf_sock_inpcb =
- (uintptr_t)inpcb->inp_ppcb;
- }
- }
- break;
- case AF_UNIX:
- if (so->so_pcb != NULL) {
- unpcb = (struct unpcb *)(so->so_pcb);
- if (unpcb->unp_conn) {
- kif->kf_un.kf_sock.kf_sock_unpconn =
- (uintptr_t)unpcb->unp_conn;
- kif->kf_un.kf_sock.kf_sock_rcv_sb_state =
- so->so_rcv.sb_state;
- kif->kf_un.kf_sock.kf_sock_snd_sb_state =
- so->so_snd.sb_state;
- }
- }
- break;
- }
- error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
- if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
- bcopy(sa, &kif->kf_sa_local, sa->sa_len);
- free(sa, M_SONAME);
- }
- error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
- if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
- bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
- free(sa, M_SONAME);
- }
- strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
- sizeof(kif->kf_path));
- return (0);
-}
-
-static int
-fill_pts_info(struct tty *tp, struct kinfo_file *kif)
-{
-
- if (tp == NULL)
- return (1);
- kif->kf_un.kf_pts.kf_pts_dev = tty_udev(tp);
- strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path));
- return (0);
-}
-
-static int
-fill_pipe_info(struct pipe *pi, struct kinfo_file *kif)
-{
-
- if (pi == NULL)
- return (1);
- kif->kf_un.kf_pipe.kf_pipe_addr = (uintptr_t)pi;
- kif->kf_un.kf_pipe.kf_pipe_peer = (uintptr_t)pi->pipe_peer;
- kif->kf_un.kf_pipe.kf_pipe_buffer_cnt = pi->pipe_buffer.cnt;
- return (0);
-}
-
-static int
-fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif)
-{
-
- if (pdp == NULL)
- return (1);
- kif->kf_un.kf_proc.kf_pid = pdp->pd_pid;
- return (0);
-}
-
-static int
-fill_sem_info(struct file *fp, struct kinfo_file *kif)
-{
- struct thread *td;
- struct stat sb;
-
- td = curthread;
- if (fp->f_data == NULL)
- return (1);
- if (fo_stat(fp, &sb, td->td_ucred, td) != 0)
- return (1);
- if (ksem_info == NULL)
- return (1);
- ksem_info(fp->f_data, kif->kf_path, sizeof(kif->kf_path),
- &kif->kf_un.kf_sem.kf_sem_value);
- kif->kf_un.kf_sem.kf_sem_mode = sb.st_mode;
- return (0);
-}
-
-static int
-fill_shm_info(struct file *fp, struct kinfo_file *kif)
-{
- struct thread *td;
- struct stat sb;
-
- td = curthread;
- if (fp->f_data == NULL)
- return (1);
- if (fo_stat(fp, &sb, td->td_ucred, td) != 0)
- return (1);
- shm_path(fp->f_data, kif->kf_path, sizeof(kif->kf_path));
- kif->kf_un.kf_file.kf_file_mode = sb.st_mode;
- kif->kf_un.kf_file.kf_file_size = sb.st_size;
- return (0);
-}
-
static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc,
CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_filedesc,
"Process filedesc entries");
@@ -3926,6 +3543,13 @@
return (EBADF);
}
+static int
+badfo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ return (0);
+}
+
struct fileops badfileops = {
.fo_read = badfo_readwrite,
.fo_write = badfo_readwrite,
@@ -3938,6 +3562,7 @@
.fo_chmod = badfo_chmod,
.fo_chown = badfo_chown,
.fo_sendfile = badfo_sendfile,
+ .fo_fill_kinfo = badfo_fill_kinfo,
};
int
Index: head/sys/kern/kern_event.c
===================================================================
--- head/sys/kern/kern_event.c
+++ head/sys/kern/kern_event.c
@@ -65,6 +65,7 @@
#include <sys/syscallsubr.h>
#include <sys/taskqueue.h>
#include <sys/uio.h>
+#include <sys/user.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@@ -114,6 +115,7 @@
static fo_kqfilter_t kqueue_kqfilter;
static fo_stat_t kqueue_stat;
static fo_close_t kqueue_close;
+static fo_fill_kinfo_t kqueue_fill_kinfo;
static struct fileops kqueueops = {
.fo_read = invfo_rdwr,
@@ -127,6 +129,7 @@
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = kqueue_fill_kinfo,
};
static int knote_attach(struct knote *kn, struct kqueue *kq);
@@ -1802,6 +1805,14 @@
return (0);
}
+static int
+kqueue_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ kif->kf_type = KF_TYPE_KQUEUE;
+ return (0);
+}
+
static void
kqueue_wakeup(struct kqueue *kq)
{
Index: head/sys/kern/sys_pipe.c
===================================================================
--- head/sys/kern/sys_pipe.c
+++ head/sys/kern/sys_pipe.c
@@ -115,6 +115,7 @@
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/uio.h>
+#include <sys/user.h>
#include <sys/event.h>
#include <security/mac/mac_framework.h>
@@ -152,6 +153,7 @@
static fo_close_t pipe_close;
static fo_chmod_t pipe_chmod;
static fo_chown_t pipe_chown;
+static fo_fill_kinfo_t pipe_fill_kinfo;
struct fileops pipeops = {
.fo_read = pipe_read,
@@ -165,6 +167,7 @@
.fo_chmod = pipe_chmod,
.fo_chown = pipe_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = pipe_fill_kinfo,
.fo_flags = DFLAG_PASSABLE
};
@@ -1607,6 +1610,21 @@
return (error);
}
+static int
+pipe_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+ struct pipe *pi;
+
+ if (fp->f_type == DTYPE_FIFO)
+ return (vn_fill_kinfo(fp, kif, fdp));
+ kif->kf_type = KF_TYPE_PIPE;
+ pi = fp->f_data;
+ kif->kf_un.kf_pipe.kf_pipe_addr = (uintptr_t)pi;
+ kif->kf_un.kf_pipe.kf_pipe_peer = (uintptr_t)pi->pipe_peer;
+ kif->kf_un.kf_pipe.kf_pipe_buffer_cnt = pi->pipe_buffer.cnt;
+ return (0);
+}
+
static void
pipe_free_kmem(cpipe)
struct pipe *cpipe;
Index: head/sys/kern/sys_procdesc.c
===================================================================
--- head/sys/kern/sys_procdesc.c
+++ head/sys/kern/sys_procdesc.c
@@ -78,6 +78,7 @@
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/ucred.h>
+#include <sys/user.h>
#include <security/audit/audit.h>
@@ -91,6 +92,7 @@
static fo_kqfilter_t procdesc_kqfilter;
static fo_stat_t procdesc_stat;
static fo_close_t procdesc_close;
+static fo_fill_kinfo_t procdesc_fill_kinfo;
static struct fileops procdesc_ops = {
.fo_read = invfo_rdwr,
@@ -104,6 +106,7 @@
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = procdesc_fill_kinfo,
.fo_flags = DFLAG_PASSABLE,
};
@@ -531,3 +534,14 @@
return (0);
}
+static int
+procdesc_fill_kinfo(struct file *fp, struct kinfo_file *kif,
+ struct filedesc *fdp)
+{
+ struct procdesc *pdp;
+
+ kif->kf_type = KF_TYPE_PROCDESC;
+ pdp = fp->f_data;
+ kif->kf_un.kf_proc.kf_pid = pdp->pd_pid;
+ return (0);
+}
Index: head/sys/kern/sys_socket.c
===================================================================
--- head/sys/kern/sys_socket.c
+++ head/sys/kern/sys_socket.c
@@ -34,8 +34,10 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/domain.h>
#include <sys/file.h>
#include <sys/filedesc.h>
+#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/sigio.h>
@@ -48,12 +50,18 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/ucred.h>
+#include <sys/un.h>
+#include <sys/unpcb.h>
+#include <sys/user.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
#include <net/vnet.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+
#include <security/mac/mac_framework.h>
static fo_rdwr_t soo_read;
@@ -63,6 +71,7 @@
extern fo_kqfilter_t soo_kqfilter;
static fo_stat_t soo_stat;
static fo_close_t soo_close;
+static fo_fill_kinfo_t soo_fill_kinfo;
struct fileops socketops = {
.fo_read = soo_read,
@@ -76,6 +85,7 @@
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = soo_fill_kinfo,
.fo_flags = DFLAG_PASSABLE
};
@@ -293,3 +303,58 @@
error = soclose(so);
return (error);
}
+
+static int
+soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+ struct sockaddr *sa;
+ struct inpcb *inpcb;
+ struct unpcb *unpcb;
+ struct socket *so;
+ int error;
+
+ kif->kf_type = KF_TYPE_SOCKET;
+ so = fp->f_data;
+ kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
+ kif->kf_sock_type = so->so_type;
+ kif->kf_sock_protocol = so->so_proto->pr_protocol;
+ kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
+ switch (kif->kf_sock_domain) {
+ case AF_INET:
+ case AF_INET6:
+ if (kif->kf_sock_protocol == IPPROTO_TCP) {
+ if (so->so_pcb != NULL) {
+ inpcb = (struct inpcb *)(so->so_pcb);
+ kif->kf_un.kf_sock.kf_sock_inpcb =
+ (uintptr_t)inpcb->inp_ppcb;
+ }
+ }
+ break;
+ case AF_UNIX:
+ if (so->so_pcb != NULL) {
+ unpcb = (struct unpcb *)(so->so_pcb);
+ if (unpcb->unp_conn) {
+ kif->kf_un.kf_sock.kf_sock_unpconn =
+ (uintptr_t)unpcb->unp_conn;
+ kif->kf_un.kf_sock.kf_sock_rcv_sb_state =
+ so->so_rcv.sb_state;
+ kif->kf_un.kf_sock.kf_sock_snd_sb_state =
+ so->so_snd.sb_state;
+ }
+ }
+ break;
+ }
+ error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
+ if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
+ bcopy(sa, &kif->kf_sa_local, sa->sa_len);
+ free(sa, M_SONAME);
+ }
+ error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
+ if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
+ bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
+ free(sa, M_SONAME);
+ }
+ strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
+ sizeof(kif->kf_path));
+ return (0);
+}
Index: head/sys/kern/tty_pts.c
===================================================================
--- head/sys/kern/tty_pts.c
+++ head/sys/kern/tty_pts.c
@@ -62,6 +62,7 @@
#include <sys/systm.h>
#include <sys/tty.h>
#include <sys/ttycom.h>
+#include <sys/user.h>
#include <machine/stdarg.h>
@@ -580,6 +581,18 @@
return (0);
}
+static int
+ptsdev_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+ struct tty *tp;
+
+ kif->kf_type = KF_TYPE_PTS;
+ tp = fp->f_data;
+ kif->kf_un.kf_pts.kf_pts_dev = tty_udev(tp);
+ strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path));
+ return (0);
+}
+
static struct fileops ptsdev_ops = {
.fo_read = ptsdev_read,
.fo_write = ptsdev_write,
@@ -592,6 +605,7 @@
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = ptsdev_fill_kinfo,
.fo_flags = DFLAG_PASSABLE,
};
Index: head/sys/kern/uipc_mqueue.c
===================================================================
--- head/sys/kern/uipc_mqueue.c
+++ head/sys/kern/uipc_mqueue.c
@@ -81,6 +81,7 @@
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <sys/unistd.h>
+#include <sys/user.h>
#include <sys/vnode.h>
#include <machine/atomic.h>
@@ -2571,6 +2572,14 @@
return (mq->mq_curmsgs < mq->mq_maxmsg);
}
+static int
+mqf_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ kif->kf_type = KF_TYPE_MQUEUE;
+ return (0);
+}
+
static struct fileops mqueueops = {
.fo_read = invfo_rdwr,
.fo_write = invfo_rdwr,
@@ -2583,6 +2592,7 @@
.fo_chmod = mqf_chmod,
.fo_chown = mqf_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = mqf_fill_kinfo,
};
static struct vop_vector mqfs_vnodeops = {
Index: head/sys/kern/uipc_sem.c
===================================================================
--- head/sys/kern/uipc_sem.c
+++ head/sys/kern/uipc_sem.c
@@ -62,6 +62,7 @@
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/sx.h>
+#include <sys/user.h>
#include <sys/vnode.h>
#include <security/mac/mac_framework.h>
@@ -130,6 +131,7 @@
static fo_close_t ksem_closef;
static fo_chmod_t ksem_chmod;
static fo_chown_t ksem_chown;
+static fo_fill_kinfo_t ksem_fill_kinfo;
/* File descriptor operations. */
static struct fileops ksem_ops = {
@@ -144,6 +146,7 @@
.fo_chmod = ksem_chmod,
.fo_chown = ksem_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = ksem_fill_kinfo,
.fo_flags = DFLAG_PASSABLE
};
@@ -252,6 +255,26 @@
return (0);
}
+static int
+ksem_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+ struct ksem *ks;
+
+ kif->kf_type = KF_TYPE_SEM;
+ ks = fp->f_data;
+ mtx_lock(&sem_lock);
+ kif->kf_un.kf_sem.kf_sem_value = ks->ks_value;
+ kif->kf_un.kf_sem.kf_sem_mode = S_IFREG | ks->ks_mode; /* XXX */
+ mtx_unlock(&sem_lock);
+ if (ks->ks_path != NULL) {
+ sx_slock(&ksem_dict_lock);
+ if (ks->ks_path != NULL)
+ strlcpy(kif->kf_path, ks->ks_path, sizeof(kif->kf_path));
+ sx_sunlock(&ksem_dict_lock);
+ }
+ return (0);
+}
+
/*
* ksem object management including creation and reference counting
* routines.
@@ -388,20 +411,6 @@
return (ENOENT);
}
-static void
-ksem_info_impl(struct ksem *ks, char *path, size_t size, uint32_t *value)
-{
-
- if (ks->ks_path == NULL)
- return;
- sx_slock(&ksem_dict_lock);
- if (ks->ks_path != NULL)
- strlcpy(path, ks->ks_path, size);
- if (value != NULL)
- *value = ks->ks_value;
- sx_sunlock(&ksem_dict_lock);
-}
-
static int
ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd,
int compat32)
@@ -983,7 +992,6 @@
p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 200112L);
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
- ksem_info = ksem_info_impl;
error = syscall_helper_register(ksem_syscalls);
if (error)
@@ -1005,7 +1013,6 @@
#endif
syscall_helper_unregister(ksem_syscalls);
- ksem_info = NULL;
p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 0);
hashdestroy(ksem_dictionary, M_KSEM, ksem_hash);
sx_destroy(&ksem_dict_lock);
Index: head/sys/kern/uipc_shm.c
===================================================================
--- head/sys/kern/uipc_shm.c
+++ head/sys/kern/uipc_shm.c
@@ -75,6 +75,7 @@
#include <sys/time.h>
#include <sys/vnode.h>
#include <sys/unistd.h>
+#include <sys/user.h>
#include <security/mac/mac_framework.h>
@@ -125,6 +126,7 @@
static fo_chmod_t shm_chmod;
static fo_chown_t shm_chown;
static fo_seek_t shm_seek;
+static fo_fill_kinfo_t shm_fill_kinfo;
/* File descriptor operations. */
static struct fileops shm_ops = {
@@ -140,6 +142,7 @@
.fo_chown = shm_chown,
.fo_sendfile = vn_sendfile,
.fo_seek = shm_seek,
+ .fo_fill_kinfo = shm_fill_kinfo,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -1022,14 +1025,24 @@
return (0);
}
-void
-shm_path(struct shmfd *shmfd, char *path, size_t size)
+static int
+shm_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
{
+ struct shmfd *shmfd;
+
+ kif->kf_type = KF_TYPE_SHM;
+ shmfd = fp->f_data;
- if (shmfd->shm_path == NULL)
- return;
- sx_slock(&shm_dict_lock);
- if (shmfd->shm_path != NULL)
- strlcpy(path, shmfd->shm_path, size);
- sx_sunlock(&shm_dict_lock);
+ mtx_lock(&shm_timestamp_lock);
+ kif->kf_un.kf_file.kf_file_mode = S_IFREG | shmfd->shm_mode; /* XXX */
+ mtx_unlock(&shm_timestamp_lock);
+ kif->kf_un.kf_file.kf_file_size = shmfd->shm_size;
+ if (shmfd->shm_path != NULL) {
+ sx_slock(&shm_dict_lock);
+ if (shmfd->shm_path != NULL)
+ strlcpy(kif->kf_path, shmfd->shm_path,
+ sizeof(kif->kf_path));
+ sx_sunlock(&shm_dict_lock);
+ }
+ return (0);
}
Index: head/sys/kern/vfs_vnops.c
===================================================================
--- head/sys/kern/vfs_vnops.c
+++ head/sys/kern/vfs_vnops.c
@@ -69,6 +69,7 @@
#include <sys/conf.h>
#include <sys/syslog.h>
#include <sys/unistd.h>
+#include <sys/user.h>
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -103,6 +104,7 @@
.fo_chown = vn_chown,
.fo_sendfile = vn_sendfile,
.fo_seek = vn_seek,
+ .fo_fill_kinfo = vn_fill_kinfo,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -2249,3 +2251,61 @@
error = VOP_ACCESS(vp, VWRITE, cred, td);
return (error);
}
+
+int
+vn_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+ struct vnode *vp;
+ int error;
+
+ if (fp->f_type == DTYPE_FIFO)
+ kif->kf_type = KF_TYPE_FIFO;
+ else
+ kif->kf_type = KF_TYPE_VNODE;
+ vp = fp->f_vnode;
+ vref(vp);
+ FILEDESC_SUNLOCK(fdp);
+ error = vn_fill_kinfo_vnode(vp, kif);
+ vrele(vp);
+ FILEDESC_SLOCK(fdp);
+ return (error);
+}
+
+int
+vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif)
+{
+ struct vattr va;
+ char *fullpath, *freepath;
+ int error;
+
+ kif->kf_vnode_type = vntype_to_kinfo(vp->v_type);
+ freepath = NULL;
+ fullpath = "-";
+ error = vn_fullpath(curthread, vp, &fullpath, &freepath);
+ if (error == 0) {
+ strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path));
+ }
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
+
+ /*
+ * Retrieve vnode attributes.
+ */
+ va.va_fsid = VNOVAL;
+ va.va_rdev = NODEV;
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(vp, &va, curthread->td_ucred);
+ VOP_UNLOCK(vp, 0);
+ if (error != 0)
+ return (error);
+ if (va.va_fsid != VNOVAL)
+ kif->kf_un.kf_file.kf_file_fsid = va.va_fsid;
+ else
+ kif->kf_un.kf_file.kf_file_fsid =
+ vp->v_mount->mnt_stat.f_fsid.val[0];
+ kif->kf_un.kf_file.kf_file_fileid = va.va_fileid;
+ kif->kf_un.kf_file.kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
+ kif->kf_un.kf_file.kf_file_size = va.va_size;
+ kif->kf_un.kf_file.kf_file_rdev = va.va_rdev;
+ return (0);
+}
Index: head/sys/ofed/include/linux/linux_compat.c
===================================================================
--- head/sys/ofed/include/linux/linux_compat.c
+++ head/sys/ofed/include/linux/linux_compat.c
@@ -576,6 +576,14 @@
return (EOPNOTSUPP);
}
+static int
+linux_file_fill_kinfo(struct file *fp, struct kinfo_file *kif,
+ struct filedesc *fdp)
+{
+
+ return (0);
+}
+
struct fileops linuxfileops = {
.fo_read = linux_file_read,
.fo_write = invfo_rdwr,
@@ -588,6 +596,7 @@
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = linux_file_fill_kinfo,
};
/*
Index: head/sys/opencrypto/cryptodev.c
===================================================================
--- head/sys/opencrypto/cryptodev.c
+++ head/sys/opencrypto/cryptodev.c
@@ -286,6 +286,8 @@
static int cryptof_stat(struct file *, struct stat *,
struct ucred *, struct thread *);
static int cryptof_close(struct file *, struct thread *);
+static int cryptof_fill_kinfo(struct file *, struct kinfo_file *,
+ struct filedesc *);
static struct fileops cryptofops = {
.fo_read = invfo_rdwr,
@@ -299,6 +301,7 @@
.fo_chmod = invfo_chmod,
.fo_chown = invfo_chown,
.fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = cryptof_fill_kinfo,
};
static struct csession *csefind(struct fcrypt *, u_int);
@@ -958,6 +961,14 @@
return 0;
}
+static int
+cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ kif->kf_type = KF_TYPE_CRYPTO;
+ return (0);
+}
+
static struct csession *
csefind(struct fcrypt *fcr, u_int ses)
{
Index: head/sys/sys/file.h
===================================================================
--- head/sys/sys/file.h
+++ head/sys/sys/file.h
@@ -43,6 +43,7 @@
#include <sys/_lock.h>
#include <sys/_mutex.h>
+struct filedesc;
struct stat;
struct thread;
struct uio;
@@ -70,6 +71,7 @@
struct file;
struct filecaps;
+struct kinfo_file;
struct ucred;
#define FOF_OFFSET 0x01 /* Use the offset in uio argument */
@@ -114,6 +116,8 @@
struct sendfile_sync *sfs, struct thread *td);
typedef int fo_seek_t(struct file *fp, off_t offset, int whence,
struct thread *td);
+typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif,
+ struct filedesc *fdp);
typedef int fo_flags_t;
struct fileops {
@@ -129,6 +133,7 @@
fo_chown_t *fo_chown;
fo_sendfile_t *fo_sendfile;
fo_seek_t *fo_seek;
+ fo_fill_kinfo_t *fo_fill_kinfo;
fo_flags_t fo_flags; /* DFLAG_* below */
};
@@ -242,6 +247,8 @@
fo_sendfile_t vn_sendfile;
fo_seek_t vn_seek;
+fo_fill_kinfo_t vn_fill_kinfo;
+int vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif);
void finit(struct file *, u_int, short, void *, struct fileops *);
int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp,
@@ -378,6 +385,13 @@
return ((*fp->f_ops->fo_seek)(fp, offset, whence, td));
}
+static __inline int
+fo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ return ((*fp->f_ops->fo_fill_kinfo)(fp, kif, fdp));
+}
+
#endif /* _KERNEL */
#endif /* !SYS_FILE_H */
Index: head/sys/sys/ksem.h
===================================================================
--- head/sys/sys/ksem.h
+++ head/sys/sys/ksem.h
@@ -63,9 +63,4 @@
#define KS_ANONYMOUS 0x0001 /* Anonymous (unnamed) semaphore. */
#define KS_DEAD 0x0002 /* No new waiters allowed. */
-#ifdef _KERNEL
-extern void (*ksem_info)(struct ksem *ks, char *path, size_t size,
- uint32_t *value);
-#endif
-
#endif /* !_POSIX4_KSEM_H_ */
Index: head/sys/sys/mman.h
===================================================================
--- head/sys/sys/mman.h
+++ head/sys/sys/mman.h
@@ -234,7 +234,6 @@
vm_object_t *obj);
int shm_map(struct file *fp, size_t size, off_t offset, void **memp);
int shm_unmap(struct file *fp, void *mem, size_t size);
-void shm_path(struct shmfd *shmfd, char *path, size_t size);
#else /* !_KERNEL */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 18, 6:30 PM (6 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25534647
Default Alt Text
D775.id.diff (42 KB)
Attached To
Mode
D775: Add a fo_fill_kinfo fileops method.
Attached
Detach File
Event Timeline
Log In to Comment