Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_descrip.c
Show First 20 Lines • Show All 1,057 Lines • ▼ Show 20 Lines | fsetown(pid_t pgid, struct sigio **sigiop) | ||||
ret = 0; | ret = 0; | ||||
/* Allocate and fill in the new sigio out of locks. */ | /* Allocate and fill in the new sigio out of locks. */ | ||||
sigio = malloc(sizeof(struct sigio), M_SIGIO, M_WAITOK); | sigio = malloc(sizeof(struct sigio), M_SIGIO, M_WAITOK); | ||||
sigio->sio_pgid = pgid; | sigio->sio_pgid = pgid; | ||||
sigio->sio_ucred = crhold(curthread->td_ucred); | sigio->sio_ucred = crhold(curthread->td_ucred); | ||||
sigio->sio_myref = sigiop; | sigio->sio_myref = sigiop; | ||||
sx_slock(&proctree_lock); | sx_slock(&V_proctree_lock); | ||||
if (pgid > 0) { | if (pgid > 0) { | ||||
proc = pfind(pgid); | proc = pfind(pgid); | ||||
if (proc == NULL) { | if (proc == NULL) { | ||||
ret = ESRCH; | ret = ESRCH; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | if (pgid > 0) { | ||||
sigio->sio_proc = proc; | sigio->sio_proc = proc; | ||||
PROC_UNLOCK(proc); | PROC_UNLOCK(proc); | ||||
} else { | } else { | ||||
PGRP_LOCK(pgrp); | PGRP_LOCK(pgrp); | ||||
SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio); | SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio); | ||||
sigio->sio_pgrp = pgrp; | sigio->sio_pgrp = pgrp; | ||||
PGRP_UNLOCK(pgrp); | PGRP_UNLOCK(pgrp); | ||||
} | } | ||||
sx_sunlock(&proctree_lock); | sx_sunlock(&V_proctree_lock); | ||||
SIGIO_LOCK(); | SIGIO_LOCK(); | ||||
*sigiop = sigio; | *sigiop = sigio; | ||||
SIGIO_UNLOCK(); | SIGIO_UNLOCK(); | ||||
return (0); | return (0); | ||||
fail: | fail: | ||||
sx_sunlock(&proctree_lock); | sx_sunlock(&V_proctree_lock); | ||||
crfree(sigio->sio_ucred); | crfree(sigio->sio_ucred); | ||||
free(sigio, M_SIGIO); | free(sigio, M_SIGIO); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
/* | /* | ||||
* This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg). | * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg). | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 2,035 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Scan all active processes and prisons to see if any of them have a current | * Scan all active processes and prisons to see if any of them have a current | ||||
* or root directory of `olddp'. If so, replace them with the new mount point. | * or root directory of `olddp'. If so, replace them with the new mount point. | ||||
*/ | */ | ||||
void | void | ||||
mountcheckdirs(struct vnode *olddp, struct vnode *newdp) | mountcheckdirs(struct vnode *olddp, struct vnode *newdp) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct filedesc *fdp; | struct filedesc *fdp; | ||||
struct prison *pr; | struct prison *pr; | ||||
struct proc *p; | struct proc *p; | ||||
int nrele; | int nrele; | ||||
if (vrefcnt(olddp) == 1) | if (vrefcnt(olddp) == 1) | ||||
return; | return; | ||||
nrele = 0; | nrele = 0; | ||||
sx_slock(&allproc_lock); | |||||
VPS_LIST_RLOCK(); | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
sx_slock(&V_allproc_lock); | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
fdp = fdhold(p); | fdp = fdhold(p); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
if (fdp == NULL) | if (fdp == NULL) | ||||
continue; | continue; | ||||
FILEDESC_XLOCK(fdp); | FILEDESC_XLOCK(fdp); | ||||
if (fdp->fd_cdir == olddp) { | if (fdp->fd_cdir == olddp) { | ||||
vrefact(newdp); | vrefact(newdp); | ||||
fdp->fd_cdir = newdp; | fdp->fd_cdir = newdp; | ||||
nrele++; | nrele++; | ||||
} | } | ||||
if (fdp->fd_rdir == olddp) { | if (fdp->fd_rdir == olddp) { | ||||
vrefact(newdp); | vrefact(newdp); | ||||
fdp->fd_rdir = newdp; | fdp->fd_rdir = newdp; | ||||
nrele++; | nrele++; | ||||
} | } | ||||
if (fdp->fd_jdir == olddp) { | if (fdp->fd_jdir == olddp) { | ||||
vrefact(newdp); | vrefact(newdp); | ||||
fdp->fd_jdir = newdp; | fdp->fd_jdir = newdp; | ||||
nrele++; | nrele++; | ||||
} | } | ||||
FILEDESC_XUNLOCK(fdp); | FILEDESC_XUNLOCK(fdp); | ||||
fddrop(fdp); | fddrop(fdp); | ||||
} | } | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
CURVPS_RESTORE(); | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
if (rootvnode == olddp) { | if (rootvnode == olddp) { | ||||
vrefact(newdp); | vrefact(newdp); | ||||
rootvnode = newdp; | rootvnode = newdp; | ||||
nrele++; | nrele++; | ||||
} | } | ||||
mtx_lock(&prison0.pr_mtx); | mtx_lock(&prison0.pr_mtx); | ||||
if (prison0.pr_root == olddp) { | if (prison0.pr_root == olddp) { | ||||
vrefact(newdp); | vrefact(newdp); | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | static SYSCTL_NODE(_kern_proc, KERN_PROC_NFDS, nfds, | ||||
"Number of open file descriptors"); | "Number of open file descriptors"); | ||||
/* | /* | ||||
* Get file structures globally. | * Get file structures globally. | ||||
*/ | */ | ||||
static int | static int | ||||
sysctl_kern_file(SYSCTL_HANDLER_ARGS) | sysctl_kern_file(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct xfile xf; | struct xfile xf; | ||||
struct filedesc *fdp; | struct filedesc *fdp; | ||||
struct file *fp; | struct file *fp; | ||||
struct proc *p; | struct proc *p; | ||||
int error, n; | int error, n; | ||||
error = sysctl_wire_old_buffer(req, 0); | error = sysctl_wire_old_buffer(req, 0); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
if (req->oldptr == NULL) { | if (req->oldptr == NULL) { | ||||
n = 0; | n = 0; | ||||
sx_slock(&allproc_lock); | VPS_LIST_RLOCK(); | ||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
sx_slock(&V_allproc_lock); | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if (p->p_state == PRS_NEW) { | if (p->p_state == PRS_NEW) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
continue; | continue; | ||||
} | } | ||||
fdp = fdhold(p); | fdp = fdhold(p); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
if (fdp == NULL) | if (fdp == NULL) | ||||
continue; | continue; | ||||
/* overestimates sparse tables. */ | /* overestimates sparse tables. */ | ||||
if (fdp->fd_lastfile > 0) | if (fdp->fd_lastfile > 0) | ||||
n += fdp->fd_lastfile; | n += fdp->fd_lastfile; | ||||
fddrop(fdp); | fddrop(fdp); | ||||
} | } | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
CURVPS_RESTORE(); | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
return (SYSCTL_OUT(req, 0, n * sizeof(xf))); | return (SYSCTL_OUT(req, 0, n * sizeof(xf))); | ||||
} | } | ||||
error = 0; | error = 0; | ||||
bzero(&xf, sizeof(xf)); | bzero(&xf, sizeof(xf)); | ||||
xf.xf_size = sizeof(xf); | xf.xf_size = sizeof(xf); | ||||
sx_slock(&allproc_lock); | VPS_LIST_RLOCK(); | ||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
sx_slock(&V_allproc_lock); | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if (p->p_state == PRS_NEW) { | if (p->p_state == PRS_NEW) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
continue; | continue; | ||||
} | } | ||||
if (p_cansee(req->td, p) != 0) { | if (p_cansee(req->td, p) != 0) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
continue; | continue; | ||||
} | } | ||||
xf.xf_pid = p->p_pid; | xf.xf_pid = p->p_pid; | ||||
xf.xf_uid = p->p_ucred->cr_uid; | xf.xf_uid = p->p_ucred->cr_uid; | ||||
fdp = fdhold(p); | fdp = fdhold(p); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
if (fdp == NULL) | if (fdp == NULL) | ||||
continue; | continue; | ||||
FILEDESC_SLOCK(fdp); | FILEDESC_SLOCK(fdp); | ||||
for (n = 0; fdp->fd_refcnt > 0 && n <= fdp->fd_lastfile; ++n) { | for (n = 0; fdp->fd_refcnt > 0 && n <= fdp->fd_lastfile; ++n) { | ||||
if ((fp = fdp->fd_ofiles[n].fde_file) == NULL) | if ((fp = fdp->fd_ofiles[n].fde_file) == NULL) | ||||
continue; | continue; | ||||
xf.xf_fd = n; | xf.xf_fd = n; | ||||
xf.xf_file = (kvaddr_t)(uintptr_t)fp; | xf.xf_file = (kvaddr_t)(uintptr_t)fp; | ||||
xf.xf_data = (kvaddr_t)(uintptr_t)fp->f_data; | xf.xf_data = (kvaddr_t)(uintptr_t)fp->f_data; | ||||
xf.xf_vnode = (kvaddr_t)(uintptr_t)fp->f_vnode; | xf.xf_vnode = (kvaddr_t)(uintptr_t)fp->f_vnode; | ||||
xf.xf_type = (kvaddr_t)(uintptr_t)fp->f_type; | xf.xf_type = (kvaddr_t)(uintptr_t)fp->f_type; | ||||
xf.xf_count = fp->f_count; | xf.xf_count = fp->f_count; | ||||
xf.xf_msgcount = 0; | xf.xf_msgcount = 0; | ||||
xf.xf_offset = foffset_get(fp); | xf.xf_offset = foffset_get(fp); | ||||
xf.xf_flag = fp->f_flag; | xf.xf_flag = fp->f_flag; | ||||
error = SYSCTL_OUT(req, &xf, sizeof(xf)); | error = SYSCTL_OUT(req, &xf, sizeof(xf)); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
} | } | ||||
FILEDESC_SUNLOCK(fdp); | FILEDESC_SUNLOCK(fdp); | ||||
fddrop(fdp); | fddrop(fdp); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
} | } | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
CURVPS_RESTORE(); | |||||
if (error) | |||||
break; | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
return (error); | return (error); | ||||
} | } | ||||
SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, | SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, | ||||
0, 0, sysctl_kern_file, "S,xfile", "Entire file table"); | 0, 0, sysctl_kern_file, "S,xfile", "Entire file table"); | ||||
#ifdef KINFO_FILE_SIZE | #ifdef KINFO_FILE_SIZE | ||||
CTASSERT(sizeof(struct kinfo_file) == KINFO_FILE_SIZE); | CTASSERT(sizeof(struct kinfo_file) == KINFO_FILE_SIZE); | ||||
▲ Show 20 Lines • Show All 534 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* For the purposes of debugging, identify a process (if any, perhaps one of | * 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 | * many) that references the passed file in its file descriptor array. Return | ||||
* NULL if none. | * NULL if none. | ||||
*/ | */ | ||||
static struct proc * | static struct proc * | ||||
file_to_first_proc(struct file *fp) | file_to_first_proc(struct file *fp) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct filedesc *fdp; | struct filedesc *fdp; | ||||
struct proc *p; | struct proc *p; | ||||
int n; | int n; | ||||
/* VPS_LIST_RLOCK(); */ | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
if (p->p_state == PRS_NEW) | if (p->p_state == PRS_NEW) | ||||
continue; | continue; | ||||
fdp = p->p_fd; | fdp = p->p_fd; | ||||
if (fdp == NULL) | if (fdp == NULL) | ||||
continue; | continue; | ||||
for (n = 0; n <= fdp->fd_lastfile; n++) { | for (n = 0; n <= fdp->fd_lastfile; n++) { | ||||
if (fp == fdp->fd_ofiles[n].fde_file) | if (fp == fdp->fd_ofiles[n].fde_file) | ||||
return (p); | return (p); | ||||
} | } | ||||
} | } | ||||
CURVPS_RESTORE(); | |||||
} | |||||
/* VPS_LIST_RUNLOCK(); */ | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
static void | static void | ||||
db_print_file(struct file *fp, int header) | db_print_file(struct file *fp, int header) | ||||
{ | { | ||||
#define XPTRWIDTH ((int)howmany(sizeof(void *) * NBBY, 4)) | #define XPTRWIDTH ((int)howmany(sizeof(void *) * NBBY, 4)) | ||||
struct proc *p; | struct proc *p; | ||||
Show All 21 Lines | if (!have_addr) { | ||||
return; | return; | ||||
} | } | ||||
fp = (struct file *)addr; | fp = (struct file *)addr; | ||||
db_print_file(fp, 1); | db_print_file(fp, 1); | ||||
} | } | ||||
DB_SHOW_COMMAND(files, db_show_files) | DB_SHOW_COMMAND(files, db_show_files) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct filedesc *fdp; | struct filedesc *fdp; | ||||
struct file *fp; | struct file *fp; | ||||
struct proc *p; | struct proc *p; | ||||
int header; | int header; | ||||
int n; | int n; | ||||
header = 1; | header = 1; | ||||
/* VPS_LIST_RLOCK(); */ | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
if (p->p_state == PRS_NEW) | if (p->p_state == PRS_NEW) | ||||
continue; | continue; | ||||
if ((fdp = p->p_fd) == NULL) | if ((fdp = p->p_fd) == NULL) | ||||
continue; | continue; | ||||
for (n = 0; n <= fdp->fd_lastfile; ++n) { | for (n = 0; n <= fdp->fd_lastfile; ++n) { | ||||
if ((fp = fdp->fd_ofiles[n].fde_file) == NULL) | if ((fp = fdp->fd_ofiles[n].fde_file) == NULL) | ||||
continue; | continue; | ||||
db_print_file(fp, header); | db_print_file(fp, header); | ||||
header = 0; | header = 0; | ||||
} | } | ||||
} | } | ||||
CURVPS_RESTORE(); | |||||
} | |||||
/* VPS_LIST_RUNLOCK(); */ | |||||
} | } | ||||
#endif | #endif | ||||
SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, | SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, | ||||
&maxfilesperproc, 0, "Maximum files allowed open per process"); | &maxfilesperproc, 0, "Maximum files allowed open per process"); | ||||
SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, | SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, | ||||
&maxfiles, 0, "Maximum number of files"); | &maxfiles, 0, "Maximum number of files"); | ||||
▲ Show 20 Lines • Show All 237 Lines • Show Last 20 Lines |