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:
parent
3ae366de58
commit
bfda9935bd
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user