Add sysctl kern.proc.cwd

It returns only current working directory of given process which saves a lot of
overhead over kern.proc.filedesc if given proc has a lot of open fds.

Submitted by:	Tiwei Bie <btw mail.ustc.edu.cn> (slightly modified)
X-Additional:	JuniorJobs project
This commit is contained in:
Mateusz Guzik 2014-11-06 08:12:34 +00:00
parent 3ae366de58
commit bfda9935bd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=274167
3 changed files with 69 additions and 0 deletions

View File

@ -3406,6 +3406,73 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc,
CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_filedesc,
"Process filedesc entries");
/*
* Store a process current working directory information to sbuf.
*
* Takes a locked proc as argument, and returns with the proc unlocked.
*/
int
kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
{
struct filedesc *fdp;
struct export_fd_buf *efbuf;
int error;
PROC_LOCK_ASSERT(p, MA_OWNED);
fdp = fdhold(p);
PROC_UNLOCK(p);
if (fdp == NULL)
return (EINVAL);
efbuf = malloc(sizeof(*efbuf), M_TEMP, M_WAITOK);
efbuf->fdp = fdp;
efbuf->sb = sb;
efbuf->remainder = maxlen;
FILEDESC_SLOCK(fdp);
if (fdp->fd_cdir == NULL)
error = EINVAL;
else {
vref(fdp->fd_cdir);
error = export_vnode_to_sb(fdp->fd_cdir, KF_FD_TYPE_CWD,
FREAD, efbuf);
}
FILEDESC_SUNLOCK(fdp);
fddrop(fdp);
free(efbuf, M_TEMP);
return (error);
}
/*
* Get per-process current working directory.
*/
static int
sysctl_kern_proc_cwd(SYSCTL_HANDLER_ARGS)
{
struct sbuf sb;
struct proc *p;
ssize_t maxlen;
int error, error2, *name;
name = (int *)arg1;
sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_file), req);
error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
if (error != 0) {
sbuf_delete(&sb);
return (error);
}
maxlen = req->oldptr != NULL ? req->oldlen : -1;
error = kern_proc_cwd_out(p, &sb, maxlen);
error2 = sbuf_finish(&sb);
sbuf_delete(&sb);
return (error != 0 ? error : error2);
}
static SYSCTL_NODE(_kern_proc, KERN_PROC_CWD, cwd, CTLFLAG_RD|CTLFLAG_MPSAFE,
sysctl_kern_proc_cwd, "Process current working directory");
#ifdef DDB
/*
* For the purposes of debugging, generate a human-readable string for the

View File

@ -657,6 +657,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define KERN_PROC_UMASK 39 /* process umask */
#define KERN_PROC_OSREL 40 /* osreldate for process binary */
#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */
#define KERN_PROC_CWD 42 /* process current working directory */
/*
* KERN_IPC identifiers

View File

@ -530,6 +530,7 @@ struct sbuf;
*/
int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen);
int kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen);
int kern_proc_out(struct proc *p, struct sbuf *sb, int flags);
int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb);